PageRenderTime 79ms CodeModel.GetById 6ms RepoModel.GetById 1ms app.codeStats 0ms

/inc/popoon/classes/structure2xml.php

https://github.com/chregu/fluxcms
PHP | 759 lines | 560 code | 123 blank | 76 comment | 153 complexity | 5c458f2a6b8603015bd823cd192ee7ee MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, Apache-2.0, LGPL-2.1
  1. <?php
  2. class popoon_classes_structure2xml {
  3. private $parent;
  4. private $queries = null;
  5. private $queryCacheOptions = null;
  6. private $db = null;
  7. private $appendcounts = array();
  8. private $structureRootPath = '/structure';
  9. function __construct($parent,$tablePrefix) {
  10. $this->tablePrefix = $tablePrefix;
  11. $this->parent = $parent;
  12. $this->parent->st2xmlCaching = 'false';
  13. $this->api = popoon_helpers_simplecache::getInstance();
  14. if (isset($this->parent->db)) {
  15. $this->db = $this->parent->db;
  16. } elseif (isset($GLOBALS['POOL']->db)) {
  17. $this->db = $GLOBALS['POOL']->db;
  18. }
  19. }
  20. private function getAttrib($value) {
  21. return $this->parent->getAttrib($value);
  22. }
  23. private function getParameter($value) {
  24. return $this->parent->getParameter($value);
  25. }
  26. /**
  27. *
  28. */
  29. function showPage ($configXml,$PageOptions = array(), $returnDb2XmlObject = false) {
  30. // get the queries, either cached from file system or generated
  31. if (is_null($this->queries)) {
  32. $this->queries = $this->getQueries($configXml,$PageOptions);
  33. }
  34. $sql2xml = new XML_db2xml($this->db,"bx","Extended");
  35. if ($this->getParameter("contentIsXml")) {
  36. $sql2xml->setContentIsXml(true);
  37. }
  38. // i should add this for all options .... later maybe
  39. if (!(is_null($this->getAttrib("xml_seperator")) ))
  40. {
  41. $sql2xml->setOptions(array("user_options" => array("xml_seperator"=>$this->getAttrib("xml_seperator"))));
  42. }
  43. $sql2xml->setOptions(array("user_options" => array("print_empty_ids"=>False)));
  44. if (isset($PageOptions["All"]["user_options"])){
  45. $sql2xml->setOptions(array("user_options" => $PageOptions["All"]["user_options"]));
  46. }
  47. if (isset($PageOptions["querystring"])){
  48. $sql2xml->setOptions(array("user_options"=>array("result_root"=>"querystring")));
  49. $pageo = array();
  50. foreach($PageOptions["querystring"] as $key => $value)
  51. {
  52. if (!is_array($value))
  53. {
  54. $pageo[$key] = $value;
  55. }
  56. }
  57. $sql2xml->add($pageo);
  58. }
  59. if ($array2xml = $this->getParameter("array2xml")) {
  60. foreach ($array2xml as $name => $array) {
  61. $sql2xml->setOptions(array("user_options"=>array("result_root"=>$name)));
  62. $sql2xml->add($array);
  63. }
  64. }
  65. if (is_array($this->queries))
  66. {
  67. $_maxLastChangedAll = array(0);
  68. foreach ($this->queries as $structureName => $query) {
  69. if ($structureName == "_queryInfo") {
  70. continue;
  71. }
  72. if (isset($query['noOutput']) && $query['noOutput']) {
  73. continue;
  74. }
  75. //print_r($query);
  76. $query['user_options']['result_root'] = $structureName;
  77. if ($query['type'] == "dbquery"){
  78. //caching the sql2xml part
  79. $query["query"] = $this->replaceVarsInWhere($query["query"]);
  80. //print_r($query);
  81. if ( $this->parent->st2xmlCaching == "true" ) {
  82. if (!(isset($query["maxResults"])) && isset($query['queryMaxResults'])) {
  83. $query['maxResults'] = $this->db->queryOne($query['queryMaxResults']);
  84. //print_r($query['maxResults']);
  85. }
  86. $queryCountNow = $this->db->queryOne($query['queryCountId']);
  87. if (!$queryCountNow) {
  88. $queryCountNow = 1;
  89. }
  90. $_cache = true;
  91. $queryCountOld = $this->api->simpleCacheCheck($query['query'],"st2xml_count",$this->queryCacheOptions,"serialize",3600);
  92. if (MDB2::isError($queryCountOld)) {
  93. throw new PopoonDBException($queryCountOld);
  94. }
  95. if (empty($queryCountOld) || $queryCountNow != $queryCountOld) {
  96. $this->api->simpleCacheWrite($query['query'],"st2xml_count",$this->queryCacheOptions,$queryCountNow);
  97. $_cache = false;
  98. }
  99. if ( !isset($query["maxLastChanged"]) ) {
  100. $query["maxLastChanged"] = $this->db->queryOne($query['queryLastChanged']);
  101. }
  102. if ($_cache && $cachedXML = $this->api->simpleCacheCheck("","st2xml_data",$query['query'],"file", $query["maxLastChanged"])) {
  103. $sql2xml->addWithInput("File",$cachedXML);
  104. }
  105. else {
  106. $sql2xml->setOptions(array("user_tableInfo"=>$query['tableInfo'],"user_options"=>$query['user_options']));
  107. $sql2xml->add($query['query']);
  108. $this->pagerInfos($sql2xml, $query, $structureName);
  109. $this->api->simpleCacheWrite("","st2xml_data",$query['query'],"<?xml version='1.0' ?".">".$sql2xml->Format->xmldoc->saveXML($resultTree->item(0)),"file", $query["maxLastChanged"]);
  110. }
  111. $_maxLastChangedAll[] = $query["maxLastChanged"];
  112. }
  113. else
  114. {
  115. $sql2xml->setOptions(array("user_tableInfo"=>$query['tableInfo'],"user_options"=>$query['user_options']));
  116. $sql2xml->add($query['query']);
  117. $this->pagerInfos($sql2xml, $query, $structureName);
  118. }
  119. }
  120. else if ( $query['type'] == "aggregate" ) {
  121. if ($this->parent->st2xmlCaching == "true" ) {
  122. //http stuff
  123. if (strpos($query['query'],"http") === 0 ) {
  124. //if maxLastChanged is set, we already checked it in the Validity container..
  125. if (! (isset($query["maxLastChanged"]) )) {
  126. //check for Last Modified automatically creates the cached file, if not already there
  127. $query["maxLastChanged"] = $this->api->simpleCacheHttpLastModified($query['query'], time() - $query['expires'],$this->getParameter ("default","proxy") );
  128. }
  129. $_maxLastChangedAll[] = $query["maxLastChanged"];
  130. $sql2xml->addWithInput("File",$this->api->simpleCacheGenerateName("simpleCacheHttp",$query['query']),array("root"=> $structureName));
  131. }
  132. // if not starting with http, it will be a local file... hopefully
  133. else {
  134. $sql2xml->addWithInput("File",$query['query']);
  135. }
  136. }
  137. else {
  138. // with no caching, just get and add it.. (maybe we should allow http caching without db-caching..)
  139. $sql2xml->add($query['query'],array("root"=> $structureName));
  140. }
  141. }
  142. else {
  143. //quite useless right now...
  144. $sql2xml->add($query['query'],array("root"=> $structureName));
  145. }
  146. }
  147. $this->queries["_queryInfo"]["maxLastChanged"] = max($_maxLastChangedAll);
  148. // send http cache headers so the sent page expires immediately
  149. $lastChangedDate = gmdate("r", $this->queries["_queryInfo"]["maxLastChanged"]);
  150. if (isset($this->sitemap)) {
  151. $this->sitemap->setHeader("Last-Modified", $lastChangedDate);
  152. $this->sitemap->setHeader('Expires', $lastChangedDate);
  153. //var_dump(gmdate("r", $this->queries["_queryInfo"]["maxLastChanged"] ));
  154. // FIXME: if there is no bitlib2 code anymore, this if can go away
  155. if (method_exists($this->sitemap,"setLastModified")) {
  156. $this->sitemap->setLastModified($this->queries["_queryInfo"]["maxLastChanged"] );
  157. }
  158. }
  159. }
  160. if ($returnDb2XmlObject) {
  161. return $sql2xml;
  162. } else {
  163. $dom = $sql2xml->getXmlObject();
  164. if (isset($this->queries["_queryInfo"]["maxLastChanged"]) && $this->queries["_queryInfo"]["maxLastChanged"] > 0) {
  165. $dom->documentElement->setAttribute("maxLastChanged", $this->queries["_queryInfo"]["maxLastChanged"]);
  166. }
  167. return $dom;
  168. }
  169. }
  170. function pagerInfos($sql2xml, $query, $structureName) {
  171. if (!(isset($query["maxResults"])) && isset($query['queryMaxResults'])) {
  172. $query['maxResults'] = $this->db->queryOne($query['queryMaxResults']);
  173. //print_r($query['maxResults']);
  174. }
  175. $ctx = new DomXpath($sql2xml->Format->xmldoc);
  176. $resultTree = $ctx->query("$structureName",$sql2xml->Format->xmlroot );
  177. if (isset($query['maxResults']) && $resultTree->item(0)) {
  178. $resultTree->item(0)->setAttribute('maxresults', $query['maxResults'] );
  179. $resultTree->item(0)->setAttribute('maxpages', ceil( $query['maxResults']/$query['limit'] ) -1 );
  180. $page = isset($_GET['p'])? $_GET['p'] : 0 ;
  181. $resultTree->item(0)->setAttribute('page', $page);
  182. }
  183. }
  184. function Structures2Sql ($configFile,$sqlOptions=array(),$rootpath= "/structure")
  185. {
  186. $configClass = bx_helpers_db::getConfigClass($configFile);
  187. $dbMainStructure = $configClass->getValues( $rootpath);
  188. if (@PEAR::isError($dbMainStructure)) {
  189. throw new PopoonPEARException($dbMainStructure);
  190. }
  191. if (is_array($dbMainStructure['children']))
  192. {
  193. foreach ($dbMainStructure['children'] as $structureName) {
  194. $dbStructure = $configClass->getValues( "$rootpath/$structureName");
  195. //print_r($dbStructure);
  196. if (@PEAR::isError($dbStructure)) {
  197. die($dbStructure->getUserinfo() . "\n" . $dbStructure->getMessage());
  198. }
  199. if (isset($dbStructure["pager"])) {
  200. //echo "<h1>$structureName</h1>";
  201. $this->appendcounts[$structureName] = ($dbStructure["pager"]=="true") ? true:false;
  202. }
  203. if (isset($dbStructure["limit"])) {
  204. //echo "<h1>$structureName</h1>";
  205. $allqueries[$structureName]['limit'] = $dbStructure["limit"];
  206. }
  207. if (isset($dbStructure["appendcount"])) {
  208. $this->appendcounts[$structureName] = ($dbStructure["appendcount"]=="true") ? true:false;
  209. }
  210. if (isset($dbStructure["expires"])) {
  211. $allqueries[$structureName]['expires'] = time() - strtotime(preg_replace("#access\s+minus\s+#", "-",$dbStructure["expires"]));
  212. }
  213. else if (isset($this->parent->defaultExpires)) {
  214. $allqueries[$structureName]['expires'] = $this->parent->defaultExpires;
  215. } else {
  216. $allqueries[$structureName]['expires'] = 3600;
  217. }
  218. if (isset($dbStructure["type"]) && $dbStructure["type"] == "aggregate") {
  219. $allqueries[$structureName]['query'] = $dbStructure["src"];
  220. $allqueries[$structureName]['type'] = "aggregate";
  221. }
  222. else {
  223. /* This code looks like unnecessary...
  224. can be removed later, if it's really not needed
  225. $queryfields = $dbStructure['children'][0].".*";
  226. $query = "from ".$dbStructure['children'][0];
  227. $name = $dbStructure['children'][0];;
  228. $dbStructure = $configClass->getValues("$rootpath/$structureName/$name");
  229. */
  230. $tableInfo= array();
  231. if (!isset($sqlOptions[$structureName])) { $sqlOptions[$structureName] = array();} //E_ALL fix
  232. $allqueries[$structureName]['query'] = $this->Structure2Sql($configClass,$tableInfo,$sqlOptions[$structureName],$rootpath."/".$structureName);
  233. $allqueries[$structureName]['tableInfo'] = $tableInfo;
  234. $allqueries[$structureName]['type'] = "dbquery";
  235. }
  236. if (isset($dbStructure['noOutput']) && $dbStructure['noOutput'] = 'true') {
  237. $allqueries[$structureName]['noOutput'] = true;
  238. }
  239. }
  240. }
  241. //print "<pre>";print_r($allqueries);
  242. return $allqueries;
  243. }
  244. function Structure2Sql ( $configFile ,&$tableInfo,$sqlOptions=array(),$rootpath = "/bxconfig/structure")
  245. {
  246. //if it's a string, then it musst be a file, otherwise it's already a config class
  247. $configClass = bx_helpers_db::getConfigClass($configFile);
  248. $dbMasterValues = $configClass->getValues( $rootpath);
  249. // if dont is set, then stop the query building... and return nothing, not used at the moment
  250. if (isset($sqlOptions['dont']) && $sqlOptions['dont'])
  251. {
  252. return Null;
  253. }
  254. $queryfields = $dbMasterValues['children'][0].".*";
  255. $query = " from ".$this->tablePrefix.$dbMasterValues['children'][0] . " as " . $dbMasterValues['children'][0];
  256. $name = $dbMasterValues['children'][0];
  257. $dbStructure = $configClass->getValues("$rootpath/$name");
  258. $queryfields = $this->getQueryFields($name,$dbStructure,"root",$tableInfo);
  259. $queryfields = substr($queryfields,1);
  260. $andcondition = "";
  261. if (isset($dbMasterValues["recursive"]) && $dbMasterValues["recursive"] == "tree") {
  262. include_once("bitlib/SQL/Tree.php");
  263. $t = new sql_tree($this->db);
  264. $t->tablename = $this->tablePrefix.$name;
  265. $data = explode(" , ",$dbStructure['fields']);
  266. $sitemapStartTreeID = $this->getAttrib("treeStartID");
  267. if (isset($sqlOptions['start_id'])) {
  268. } elseif ( $sitemapStartTreeID ) {
  269. $sqlOptions['start_id'] = $sitemapStartTreeID ;
  270. } elseif ( isset($dbMasterValues["start_id"]) ) {
  271. $sqlOptions['start_id'] = $dbMasterValues["start_id"];
  272. } else {
  273. $sqlOptions['start_id'] = 1;
  274. }
  275. $query = $t->children_query_byname(array("ID"=>$sqlOptions['start_id']),$data,True);
  276. }
  277. elseif (isset($dbMasterValues["recursive"]) && $dbMasterValues["recursive"] == "parents") {
  278. include_once("bitlib/SQL/Tree.php");
  279. $t = new sql_tree($this->db);
  280. $t->tablename = $this->tablePrefix.$name;
  281. $data = explode(" , ",$dbStructure['fields']);
  282. $query = $t->supers_query_byname(array("id"=>$sqlOptions[start_id]),$data,False);
  283. }
  284. elseif (isset($dbMasterValues["recursive"]) && $dbMasterValues["recursive"] == "children") {
  285. include_once("bitlib/SQL/Tree.php");
  286. $t = new sql_tree($this->db);
  287. $t->tablename = $this->tablePrefix.$name;
  288. $data = explode(" , ",$dbStructure['fields']);
  289. $query = $t->children_query_byname(array("id"=>$sqlOptions[start_id]),$data);
  290. }
  291. else {
  292. $path = $rootpath;
  293. while (isset($dbStructure["children"]) && is_array($dbStructure["children"]))
  294. {
  295. $path = $path."/".$name;
  296. $parentname = $name;
  297. if (! isset($dbStructure["nofields"]) )
  298. {
  299. $xmlparent = $parentname;
  300. }
  301. $parentdbStructure = $dbStructure;
  302. foreach($dbStructure["children"] as $child) {
  303. $name = $child;
  304. $dbStructure = $configClass->getValues( "$path/$name");
  305. if (isset($dbStructure['tablePrefix']) && !empty($dbStructure['tablePrefix'])) {
  306. $tablePrefix = $dbStructure['tablePrefix'];
  307. } else {
  308. $tablePrefix = $this->tablePrefix;
  309. }
  310. $queryfields = $queryfields. $this->getQueryFields($child,$dbStructure,$xmlparent,$tableInfo);
  311. if (! isset($dbStructure["thatfield"])) { $dbStructure["thatfield"] = "id";}
  312. if (! isset($dbStructure["thisfield"])) { $dbStructure["thisfield"] = "id";}
  313. $query = $query ." left join ".$tablePrefix.$name. " as $name on ($name.".$dbStructure["thisfield"]." = $parentname.".$dbStructure["thatfield"];
  314. if (isset($dbStructure["objectfield"]) )
  315. {
  316. $query = "$query and $parentname.".$dbStructure["objectfield"]." = '$name'";
  317. }
  318. elseif (isset($parentdbStructure["objectfield2"]))
  319. {
  320. $query = "$query and $parentname.".$parentdbStructure["objectfield2"]." = '$name'";
  321. }
  322. $query .= ")";
  323. if (isset($dbStructure["activefield"]))
  324. {
  325. $activequery = "$name.".$dbStructure["activefield"] ."= 1 or isnull($name.".$dbStructure["activefield"] .")";
  326. if (isset($dbStructure["activefromfield"]))
  327. {
  328. $activequery .= " or (( $child.".$dbStructure["activefield"] ." = 2) and (($child.".$dbStructure["activefromfield"] ."< now() or $child.".$dbStructure["activetillfield"] ." = 0) and ($child.".$dbStructure["activetillfield"] ."> now() or $child.".$dbStructure["activetillfield"] ." = 0)))";
  329. }
  330. $andconditions[] = $activequery;
  331. }
  332. }
  333. // if stopattable is set, then stop the query building...
  334. if (isset($sqlOptions["stopattable"]) && $sqlOptions["stopattable"] == $name) {
  335. break;
  336. }
  337. // debug::print_rp($dbStructure);
  338. }
  339. $query = "select $queryfields".$query;
  340. if (!isset($sqlOptions["ShowAll"]) && isset($andconditions) && is_array($andconditions))
  341. {
  342. $andcondition = " and (".implode($andconditions,") and (").")";
  343. }
  344. else
  345. {
  346. $andcondition = "";
  347. }
  348. }
  349. if (isset($sqlOptions["where"]))
  350. {
  351. if (!isset($sqlOptions["where"])) { $sqlOptions["where"] = "";} //E_ALL fix
  352. if (!isset($dbMasterValues["where"])) { $dbMasterValues["where"] = "";} //E_ALL fix
  353. $_append_check = strtoupper(substr($sqlOptions["where"],0,3));
  354. $_append_check_dbMaster = strtoupper(substr($dbMasterValues["where"],0,3));
  355. if ("AND" == $_append_check || "OR " == $_append_check)
  356. {
  357. $query .= " where ((". $dbMasterValues["where"] .") " .$sqlOptions["where"].") $andcondition";
  358. }
  359. elseif ("AND" == $_append_check_dbMaster || "OR " == $_append_check_dbMaster)
  360. {
  361. $query .= " where ((". $sqlOptions["where"] .") " .$dbMasterValues["where"].") $andcondition";
  362. }
  363. else
  364. {
  365. $query .= " where (".$sqlOptions["where"] .") $andcondition";
  366. }
  367. }
  368. elseif (isset($dbMasterValues["where"]))
  369. {
  370. $_where = $this->replaceVarsInWhere($dbMasterValues["where"]);
  371. // if there is already a group by (coming from tree searches...)
  372. if (strpos($query,"group by"))
  373. {
  374. // we assume, there's a "where" already
  375. $query = str_replace ("group by",$_where .$andcondition ." group by",$query);
  376. }
  377. else {
  378. $query .= " where (".$_where .") $andcondition";
  379. }
  380. }
  381. if (isset($sqlOptions["groupby"]))
  382. {
  383. $query .= " group by $sqlOptions[groupby]";
  384. }
  385. elseif (isset($dbMasterValues["groupby"]))
  386. {
  387. $query .= " group by $dbMasterValues[groupby]";
  388. }
  389. if (isset($sqlOptions["orderby"]))
  390. {
  391. $_orderby = $this->replaceVarsInWhere($sqlOptions['orderby']);
  392. if (trim($_orderby)) {
  393. $query .= " order by ". $_orderby ;
  394. }
  395. }
  396. elseif (isset($dbMasterValues["orderby"]))
  397. {
  398. $_orderby = $this->replaceVarsInWhere($dbMasterValues['orderby']);
  399. if (trim($_orderby)) {
  400. $query .= " order by ". $_orderby ;
  401. }
  402. }
  403. if (isset($sqlOptions["limit"]))
  404. {
  405. $query .= " LIMIT $sqlOptions[limit]";
  406. }
  407. elseif (isset($dbMasterValues["limit"]))
  408. {
  409. $limit = $dbMasterValues['limit'];
  410. if(isset($dbMasterValues["pager"])){
  411. $page = ( isset($_GET['p']) ) ? $_GET['p'] :0 ;
  412. $query .= " LIMIT ".($page * $limit).",$limit";
  413. }
  414. else {
  415. $query .= " LIMIT $limit";
  416. }
  417. }
  418. //if we have the simplepermWhere attribute and a table named "Section" add this to the query...
  419. // this is not really safe... there could be something else named Section.
  420. if ($simplepermWhere = $this->getAttrib("simplepermWhere") )
  421. {
  422. $query = str_replace("where", "where $simplepermWhere and ", $query);
  423. }
  424. //echo $query;
  425. return $query;
  426. }
  427. function getQueryFields($tablename,$dbStructure,$xmlparent,&$tableInfo)
  428. {
  429. $queryfields = ""; //E_ALL fix
  430. if (@PEAR::isError($dbStructure)) {
  431. $e = new PopoonPEARException($dbStructure);
  432. if (version_compare(phpversion(),"5.0.2",">") ) {
  433. $e->userInfo = "There seems to be a problem with PHP 5.0.3.
  434. If you are using PHP 5.0.3 and see this message,
  435. try down grading to 5.0.2 or upgrading to a higher version.
  436. ";
  437. }
  438. throw $e;
  439. }
  440. if (! isset($dbStructure["nofields"]) && !(isset($dbStructure["fields"]) && (strlen($dbStructure["fields"]) == 0)))
  441. {
  442. if (isset($dbStructure["fields"]) )
  443. {
  444. $fields = explode(" , ",$dbStructure["fields"]);
  445. foreach ($fields as $fieldname)
  446. {
  447. if (! preg_match ("/\(/",$fieldname))
  448. {
  449. $queryfields = $queryfields . ", $tablename.$fieldname ";
  450. }
  451. else {
  452. $queryfields = $queryfields . ", $fieldname ";
  453. }
  454. }
  455. }
  456. else
  457. {
  458. $queryfields = $queryfields . ", $tablename.*";
  459. }
  460. $tableInfo['parent_table'][$tablename]="$xmlparent";
  461. }
  462. return $queryfields;
  463. }
  464. function getQueries($configXml,$PageOptions) {
  465. //here comes the new cache code
  466. $config = bx_helpers_db::getConfigClass($configXml);
  467. if (!$this->queryCacheOptions) {
  468. $this->queryCacheOptions = $PageOptions;
  469. }
  470. // cache off
  471. //if ( false &&
  472. if (false && $queries = $this->api->simpleCacheCheck($configXml,"st2xml_queries",$this->queryCacheOptions)) {
  473. }
  474. // we don't have the queries cached, generate them..
  475. else {
  476. $queries = $this->Structures2Sql($config,$PageOptions);
  477. // generate the query for lastchanged stuff
  478. // even if we don't do st2xml caching, it's not a big deal
  479. // to do this here anyway, since this is only generated, when
  480. // structure/structure.xml changes, which should not happen very often...
  481. // Hint for PERFORMANCE hungry people :)
  482. // the tree sqls could be made easier here
  483. // this one generates:
  484. // select max(greatest(unix_timestamp(Section.changed), 0)) from Section as Section, Section as b where Section.l between b.l and b.r and Section.l between '2' and '61'
  485. // but
  486. // select max(greatest(Section.changed, 0)) from Section where Section.l between '2' and '61'
  487. // would give back the same result and is faster.
  488. // It doesn't matter if you use Mysql4 with query caching, but it's slightly slower without
  489. // To implement that, we would have to change structure2sql, which then should return an omptimized query
  490. // (to lazy to do that now)
  491. foreach ($queries as $structureName => $query) {
  492. $_changedFields = "";
  493. $_sumIdFields = "";
  494. // get all the tables
  495. // HINT: document2object and section2document are missing here... could maybe lead to wrong
  496. // updates, if you change one of that tables without changing any other table
  497. $appendCount = (isset($this->appendcounts[$structureName]) && $this->appendcounts[$structureName]==true) ? true:false;
  498. $appendCountTable = '';
  499. $sectionStruct = $config->getValues($this->structureRootPath."/".$structureName);
  500. if ($query["type"] == "dbquery" && is_array($query["tableInfo"]["parent_table"] ) )
  501. {
  502. foreach($query["tableInfo"]["parent_table"] as $table => $parent) {
  503. $_changedFields .= 'unix_timestamp('.$table .'.changed), ';
  504. $_sumIdFields .= 'sum(if(isnull('.$table .'.id),0,'.$table .'.id)) + ';
  505. if ($appendCount && $parent=='root') {
  506. $appendCountTable = $table;
  507. }
  508. }
  509. // strip everything away before "from"
  510. $_cleanFrom = substr($query["query"], strrpos($query["query"]," from ")) ." ";
  511. // strip group by away
  512. $_checkGroupBy = strpos($_cleanFrom,"group by") ;
  513. if ( $_checkGroupBy !== false) {
  514. $_cleanFrom = substr($_cleanFrom,0,$_checkGroupBy);
  515. }
  516. // strip order by away
  517. $_checkOrderBy = strpos($_cleanFrom,"order by") ;
  518. if ( $_checkOrderBy !== false) {
  519. $_cleanFrom = substr($_cleanFrom,0,$_checkOrderBy);
  520. }
  521. $_cleanFrom = str_replace("where ()","",$_cleanFrom);
  522. if ($appendCount) {
  523. $_checkLimit = strpos($_cleanFrom,"LIMIT");
  524. if ($_checkLimit !== false) {
  525. $_cleanFrom = substr($_cleanFrom,0,$_checkLimit);
  526. }
  527. if (isset($sectionStruct['idfield']) && !empty($sectionStruct['idfield'])) {
  528. $idfield = $sectionStruct['idfield'];
  529. } else {
  530. $idfield = 'id';
  531. }
  532. $qTmp = 'select count( distinct '.$appendCountTable.'.'.$idfield.') as count '. $_cleanFrom;
  533. $qTmp = preg_replace("#where\s*\(\s*\)#"," where ( 1 = 1 ) ",$qTmp);
  534. $queries[$structureName]["queryMaxResults"] = $qTmp;
  535. //echo "q: ".$queries[$structureName]["queryMaxResults"]."<br/>";
  536. }
  537. $queries[$structureName]["queryLastChanged"] = 'select max(greatest('. $_changedFields.'0)) ' .$_cleanFrom;
  538. $queries[$structureName]["queryCountId"] = 'select ('.$_sumIdFields.'0) as sum ' .$_cleanFrom;
  539. }
  540. }
  541. // $this->api->simpleCacheWrite($configXml,"st2xml_queries",$this->queryCacheOptions,$queries);
  542. }
  543. //that's it for caching the queries..
  544. return $queries;
  545. }
  546. function replaceVarsInWhere($where) {
  547. //this does replace $VAR in structure.xml with the actual variable from requests
  548. // or popooon parameter with type "structure2xml"
  549. // %VAR with an sql_regcase ( hello gets to [Hh][Ee][Ll][Ll][Oo] ) and
  550. // +VAR with +VAR ("hello world" gets to "+hello +world" this is useful for fulltext search in mysql)
  551. $regs = array();
  552. $repl = array();
  553. if (is_array($this->getParameter("structure2xml"))) {
  554. $requests = array_merge($_REQUEST,$this->getParameter("structure2xml"));
  555. } else {
  556. $requests = $_REQUEST;
  557. }
  558. $where = self::replaceVarsInWhereStatic($where,$requests);
  559. return self::replaceVarsInWhereExpr($where, $requests);
  560. }
  561. /* yet very primitive - only single expression with ints possible */
  562. static function replaceVarsInWhereExpr($where, $requests) {
  563. preg_match_all("/e([ifd]):(\d+)([\*\+\/\-])(\d+)/", $where, $exprs);
  564. if (isset($exprs[0])&&sizeof($exprs[0])>0) {
  565. $regs=array();
  566. $exps=array();
  567. foreach($exprs[0] as $i=>$expr) {
  568. $n=null;
  569. switch($exprs[3][$i]) {
  570. case "*":
  571. $n=(int)$exprs[2][$i]*(int)$exprs[4][$i];
  572. break;
  573. case "+":
  574. $n=(int)$exprs[2][$i]+(int)$exprs[4][$i];
  575. break;
  576. case "-":
  577. $n=(int)$exprs[2][$i]-(int)$exprs[4][$i];
  578. break;
  579. case "/":
  580. $n=(int)$exprs[2][$i]/(int)$exprs[4][$i];
  581. break;
  582. }
  583. if ($n!==null) {
  584. $regs[] = $expr;
  585. $exps[] = $n;
  586. }
  587. }
  588. $where = str_replace($regs, $exps, $where);
  589. }
  590. return $where;
  591. }
  592. static function replaceVarsInWhereStatic($where,$requests) {
  593. $regs = array();
  594. $repl = array();
  595. foreach ($requests as $key => $val)
  596. {
  597. /* not so sure about that */
  598. if (empty($val) or is_null($val) or $val === false )
  599. {
  600. continue;
  601. //$val = 0;
  602. }
  603. else if(is_array($val)) {
  604. if (count($val) == 0) {
  605. $val = '0';
  606. } else {
  607. $val = "'".join("','",$val)."'";
  608. }
  609. }
  610. else {
  611. $val = trim($val);
  612. }
  613. $regs[] ="\$$key";
  614. $repl[] = "$val";
  615. $regs[] ="%$key";
  616. $repl[] = sql_regcase($val);
  617. $regs[] ="\$+$key";
  618. $repl[] = "+".join(" +",explode(" ",$val));
  619. $regs[] ="+$key";
  620. $repl[] = "+".join(" +",explode(" ",$val));
  621. if ($val != '') {
  622. $regs[] ="\$:$key";
  623. $repl[] = "$val";
  624. }
  625. }
  626. $where = str_replace($regs,$repl,$where);
  627. $where = preg_replace('#\[\[[^\]]*\$[^\]]+\]\]#',"",$where);
  628. $where = str_replace(array("[[","]]"),"",$where);
  629. //replace where condition, if there's an empty one...
  630. $where = preg_replace("#where\s*\(\s*\)#"," where ( 1 = 1 ) ",$where);
  631. //and delete an eventuall "and" only at the beginning
  632. $where = preg_replace("#where\s*\(\s*and#"," where ( ",$where);
  633. return $where;
  634. }
  635. }