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