1*8fed17f3SAndreas Gohr<?php 2*8fed17f3SAndreas Gohr 3*8fed17f3SAndreas Gohrnamespace dokuwiki\plugin\struct\test; 4*8fed17f3SAndreas Gohr 5*8fed17f3SAndreas Gohruse dokuwiki\plugin\struct\meta; 6*8fed17f3SAndreas Gohr 7*8fed17f3SAndreas Gohr/** 8*8fed17f3SAndreas Gohr * Tests for the building of SQL-Queries for the struct plugin 9*8fed17f3SAndreas Gohr * 10*8fed17f3SAndreas Gohr * @group plugin_struct 11*8fed17f3SAndreas Gohr * @group plugins 12*8fed17f3SAndreas Gohr * 13*8fed17f3SAndreas Gohr */ 14*8fed17f3SAndreas Gohrclass AccessTableDataReplacementTest extends StructTest 15*8fed17f3SAndreas Gohr{ 16*8fed17f3SAndreas Gohr 17*8fed17f3SAndreas Gohr /** @var array alway enable the needed plugins */ 18*8fed17f3SAndreas Gohr protected $pluginsEnabled = ['struct', 'sqlite']; 19*8fed17f3SAndreas Gohr 20*8fed17f3SAndreas Gohr public function setUp(): void 21*8fed17f3SAndreas Gohr { 22*8fed17f3SAndreas Gohr parent::setUp(); 23*8fed17f3SAndreas Gohr $schemafoo = []; 24*8fed17f3SAndreas Gohr $schemafoo['new']['new1']['label'] = 'pages'; 25*8fed17f3SAndreas Gohr $schemafoo['new']['new1']['ismulti'] = 1; 26*8fed17f3SAndreas Gohr $schemafoo['new']['new1']['class'] = 'Page'; 27*8fed17f3SAndreas Gohr $schemafoo['new']['new1']['isenabled'] = '1'; 28*8fed17f3SAndreas Gohr $schemafoo['new']['new1']['config'] = null; 29*8fed17f3SAndreas Gohr $schemafoo['new']['new1']['sort'] = null; 30*8fed17f3SAndreas Gohr 31*8fed17f3SAndreas Gohr $schemabar['new']['new2']['label'] = 'data'; 32*8fed17f3SAndreas Gohr $schemabar['new']['new2']['ismulti'] = 0; 33*8fed17f3SAndreas Gohr $schemabar['new']['new2']['class'] = 'Text'; 34*8fed17f3SAndreas Gohr $schemabar['new']['new2']['isenabled'] = '1'; 35*8fed17f3SAndreas Gohr $schemabar['new']['new2']['config'] = null; 36*8fed17f3SAndreas Gohr $schemabar['new']['new2']['sort'] = null; 37*8fed17f3SAndreas Gohr 38*8fed17f3SAndreas Gohr $builder_foo = new meta\SchemaBuilder('foo', $schemafoo); 39*8fed17f3SAndreas Gohr $builder_foo->build(); 40*8fed17f3SAndreas Gohr 41*8fed17f3SAndreas Gohr $builder_bar = new meta\SchemaBuilder('bar', $schemabar); 42*8fed17f3SAndreas Gohr $builder_bar->build(); 43*8fed17f3SAndreas Gohr 44*8fed17f3SAndreas Gohr $as = mock\Assignments::getInstance(); 45*8fed17f3SAndreas Gohr $as->assignPageSchema('start', 'foo'); 46*8fed17f3SAndreas Gohr $as->assignPageSchema('no:data', 'foo'); 47*8fed17f3SAndreas Gohr $as->assignPageSchema('page1', 'bar'); 48*8fed17f3SAndreas Gohr $as->assignPageSchema('page2', 'bar'); 49*8fed17f3SAndreas Gohr $as->assignPageSchema('page2', 'bar'); 50*8fed17f3SAndreas Gohr 51*8fed17f3SAndreas Gohr // page data is saved with a rev timestamp 52*8fed17f3SAndreas Gohr $now = time(); 53*8fed17f3SAndreas Gohr $this->saveData( 54*8fed17f3SAndreas Gohr 'start', 55*8fed17f3SAndreas Gohr 'foo', 56*8fed17f3SAndreas Gohr [ 57*8fed17f3SAndreas Gohr 'pages' => ['page1', 'page2'] 58*8fed17f3SAndreas Gohr ], 59*8fed17f3SAndreas Gohr $now 60*8fed17f3SAndreas Gohr ); 61*8fed17f3SAndreas Gohr 62*8fed17f3SAndreas Gohr $this->saveData( 63*8fed17f3SAndreas Gohr 'page1', 64*8fed17f3SAndreas Gohr 'bar', 65*8fed17f3SAndreas Gohr [ 66*8fed17f3SAndreas Gohr 'data' => 'data of page1' 67*8fed17f3SAndreas Gohr ], 68*8fed17f3SAndreas Gohr $now 69*8fed17f3SAndreas Gohr ); 70*8fed17f3SAndreas Gohr 71*8fed17f3SAndreas Gohr $this->saveData( 72*8fed17f3SAndreas Gohr 'page2', 73*8fed17f3SAndreas Gohr 'bar', 74*8fed17f3SAndreas Gohr [ 75*8fed17f3SAndreas Gohr 'data' => 'data of page2' 76*8fed17f3SAndreas Gohr ], 77*8fed17f3SAndreas Gohr $now 78*8fed17f3SAndreas Gohr ); 79*8fed17f3SAndreas Gohr } 80*8fed17f3SAndreas Gohr 81*8fed17f3SAndreas Gohr public function test_simple() 82*8fed17f3SAndreas Gohr { 83*8fed17f3SAndreas Gohr global $INFO; 84*8fed17f3SAndreas Gohr $INFO['id'] = 'start'; 85*8fed17f3SAndreas Gohr $lines = [ 86*8fed17f3SAndreas Gohr "schema : bar", 87*8fed17f3SAndreas Gohr "cols : %pageid%, data", 88*8fed17f3SAndreas Gohr "filter : %pageid% = \$STRUCT.foo.pages$" 89*8fed17f3SAndreas Gohr ]; 90*8fed17f3SAndreas Gohr 91*8fed17f3SAndreas Gohr $configParser = new meta\ConfigParser($lines); 92*8fed17f3SAndreas Gohr $actual_config = $configParser->getConfig(); 93*8fed17f3SAndreas Gohr 94*8fed17f3SAndreas Gohr $search = new meta\SearchConfig($actual_config); 95*8fed17f3SAndreas Gohr list(, $opts) = $search->getSQL(); 96*8fed17f3SAndreas Gohr $result = $search->execute(); 97*8fed17f3SAndreas Gohr 98*8fed17f3SAndreas Gohr $this->assertEquals(['page1', 'page2'], $opts, '$STRUCT.table.col$ should not require table to be selected'); 99*8fed17f3SAndreas Gohr $this->assertEquals('data of page1', $result[0][1]->getValue()); 100*8fed17f3SAndreas Gohr $this->assertEquals('data of page2', $result[1][1]->getValue()); 101*8fed17f3SAndreas Gohr } 102*8fed17f3SAndreas Gohr 103*8fed17f3SAndreas Gohr public function test_emptyfield() 104*8fed17f3SAndreas Gohr { 105*8fed17f3SAndreas Gohr global $ID; 106*8fed17f3SAndreas Gohr $ID = 'no:data'; 107*8fed17f3SAndreas Gohr $lines = [ 108*8fed17f3SAndreas Gohr "schema : bar", 109*8fed17f3SAndreas Gohr "cols : %pageid%, data", 110*8fed17f3SAndreas Gohr "filter : %pageid% = \$STRUCT.foo.pages$" 111*8fed17f3SAndreas Gohr ]; 112*8fed17f3SAndreas Gohr 113*8fed17f3SAndreas Gohr $configParser = new meta\ConfigParser($lines); 114*8fed17f3SAndreas Gohr $actual_config = $configParser->getConfig(); 115*8fed17f3SAndreas Gohr 116*8fed17f3SAndreas Gohr $search = new meta\SearchConfig($actual_config); 117*8fed17f3SAndreas Gohr $result = $search->execute(); 118*8fed17f3SAndreas Gohr 119*8fed17f3SAndreas Gohr $this->assertEquals(0, count($result), 'if no pages a given, then none should be shown'); 120*8fed17f3SAndreas Gohr } 121*8fed17f3SAndreas Gohr 122*8fed17f3SAndreas Gohr public function dataProvider_DataFiltersAsSubQuery() 123*8fed17f3SAndreas Gohr { 124*8fed17f3SAndreas Gohr return [ 125*8fed17f3SAndreas Gohr [ 126*8fed17f3SAndreas Gohr [ 127*8fed17f3SAndreas Gohr "filter : data = foo" 128*8fed17f3SAndreas Gohr ], 129*8fed17f3SAndreas Gohr "AND ((data_bar.col1 != '' AND data_bar.col1 = ?))", 130*8fed17f3SAndreas Gohr "The WHERE-clauses from page-syntax should be wrapped in parentheses" 131*8fed17f3SAndreas Gohr ], 132*8fed17f3SAndreas Gohr [ 133*8fed17f3SAndreas Gohr [ 134*8fed17f3SAndreas Gohr "OR : data = foo" 135*8fed17f3SAndreas Gohr ], 136*8fed17f3SAndreas Gohr "AND ((data_bar.col1 != '' AND data_bar.col1 = ?))", 137*8fed17f3SAndreas Gohr "A single OR clause should be treated as AND clauses" 138*8fed17f3SAndreas Gohr ], 139*8fed17f3SAndreas Gohr [ 140*8fed17f3SAndreas Gohr [ 141*8fed17f3SAndreas Gohr "filter : data = foo", 142*8fed17f3SAndreas Gohr "OR : data = bar" 143*8fed17f3SAndreas Gohr ], 144*8fed17f3SAndreas Gohr "AND ((data_bar.col1 != '' AND data_bar.col1 = ?) OR (data_bar.col1 != '' AND data_bar.col1 = ?))", 145*8fed17f3SAndreas Gohr "The WHERE-clauses from page-syntax should be wrapped in parentheses" 146*8fed17f3SAndreas Gohr ], 147*8fed17f3SAndreas Gohr [ 148*8fed17f3SAndreas Gohr [ 149*8fed17f3SAndreas Gohr "OR : data = bar", 150*8fed17f3SAndreas Gohr "filter : data = foo" 151*8fed17f3SAndreas Gohr ], 152*8fed17f3SAndreas Gohr "AND ((data_bar.col1 != '' AND data_bar.col1 = ?) AND (data_bar.col1 != '' AND data_bar.col1 = ?))", 153*8fed17f3SAndreas Gohr "A single OR clause should be treated as AND clauses" 154*8fed17f3SAndreas Gohr ] 155*8fed17f3SAndreas Gohr ]; 156*8fed17f3SAndreas Gohr } 157*8fed17f3SAndreas Gohr 158*8fed17f3SAndreas Gohr /** 159*8fed17f3SAndreas Gohr * @dataProvider dataProvider_DataFiltersAsSubQuery 160*8fed17f3SAndreas Gohr */ 161*8fed17f3SAndreas Gohr public function test_DataFiltersAsSubQuery($inputFilterLines, $expectedFilterWhere, $msg) 162*8fed17f3SAndreas Gohr { 163*8fed17f3SAndreas Gohr $lines = [ 164*8fed17f3SAndreas Gohr "schema : bar", 165*8fed17f3SAndreas Gohr "cols : %pageid%, data", 166*8fed17f3SAndreas Gohr ]; 167*8fed17f3SAndreas Gohr 168*8fed17f3SAndreas Gohr $lines = array_merge($lines, $inputFilterLines); 169*8fed17f3SAndreas Gohr 170*8fed17f3SAndreas Gohr $configParser = new meta\ConfigParser($lines); 171*8fed17f3SAndreas Gohr $actual_config = $configParser->getConfig(); 172*8fed17f3SAndreas Gohr 173*8fed17f3SAndreas Gohr $search = new meta\SearchConfig($actual_config); 174*8fed17f3SAndreas Gohr list($sql,) = $search->getSQL(); 175*8fed17f3SAndreas Gohr $where = array_filter(explode("\n", $sql), function ($elem) { 176*8fed17f3SAndreas Gohr return strpos($elem, 'WHERE') !== false; 177*8fed17f3SAndreas Gohr }); 178*8fed17f3SAndreas Gohr $where = trim(reset($where)); 179*8fed17f3SAndreas Gohr 180*8fed17f3SAndreas Gohr $baseWhere = "WHERE ( 181*8fed17f3SAndreas Gohr ( 182*8fed17f3SAndreas Gohr data_bar.pid = '' OR ( 183*8fed17f3SAndreas Gohr GETACCESSLEVEL(data_bar.pid) > 0 184*8fed17f3SAndreas Gohr AND PAGEEXISTS(data_bar.pid) = 1 185*8fed17f3SAndreas Gohr AND (ASSIGNED = 1 OR ASSIGNED IS NULL) 186*8fed17f3SAndreas Gohr ) 187*8fed17f3SAndreas Gohr ) 188*8fed17f3SAndreas Gohr AND ( 189*8fed17f3SAndreas Gohr (IS_PUBLISHER(data_bar.pid) AND data_bar.latest = 1) 190*8fed17f3SAndreas Gohr OR (IS_PUBLISHER(data_bar.pid) !=1 AND data_bar.published = 1) 191*8fed17f3SAndreas Gohr )"; 192*8fed17f3SAndreas Gohr 193*8fed17f3SAndreas Gohr $expected_where = $baseWhere . $expectedFilterWhere . " )"; 194*8fed17f3SAndreas Gohr $this->assertEquals($this->cleanWS($expected_where), $this->cleanWS($where), $msg); 195*8fed17f3SAndreas Gohr } 196*8fed17f3SAndreas Gohr 197*8fed17f3SAndreas Gohr} 198