/kernel/classes/ezurlaliasquery.php

https://bitbucket.org/ericsagnes/ezpublish-multisite · PHP · 339 lines · 213 code · 24 blank · 102 comment · 40 complexity · c0da37c1233ab3584b0ef21fb0c4021a MD5 · raw file

  1. <?php
  2. /**
  3. * File containing the eZURLAliasFilter class.
  4. *
  5. * @copyright Copyright (C) 1999-2012 eZ Systems AS. All rights reserved.
  6. * @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License v2
  7. * @version 2012.8
  8. * @package kernel
  9. */
  10. /*!
  11. \class eZURLAliasQuery ezurlaliasquery.php
  12. \brief Handles querying of URL aliases with different filters
  13. To use this class instantiate it and then fill in the public
  14. properties with the wanted values. When finished call count()
  15. and/or fetchAll() to perform the wanted operation. Repeated
  16. calls will simply return the cached values.
  17. If you change the properties afterwards call prepare() to reset
  18. internally cached values.
  19. Objects of this class can also be sent to the template system
  20. as a variable and the properties can be accessed directly
  21. including 'count' for the count() function and 'items' for the
  22. 'fetchAll' function.
  23. */
  24. /*!
  25. \todo The hasAttribute, attribute and setAttribute functions can be turned into properties for PHP 5.
  26. */
  27. class eZURLAliasQuery
  28. {
  29. /*!
  30. Array of action values to include, set to null to fetch all kinds.
  31. e.g. eznode:60
  32. */
  33. public $actions;
  34. /*!
  35. Array of action types to include, set to null to fetch all kinds.
  36. e.g. eznode
  37. */
  38. public $actionTypes;
  39. /*!
  40. Array of action types to exclude, set to null to disable.
  41. e.g. eznode
  42. */
  43. public $actionTypesEx;
  44. /*!
  45. If non-null it forces only elements with this parent to be considered.
  46. */
  47. public $paren;
  48. /*!
  49. If non-null it forces only elements with this text to be considered.
  50. */
  51. public $text;
  52. /*!
  53. Type of elements to count, use 'name' for only real names for actions, 'alias' for only aliases to the actions or 'all' for real and aliases.
  54. */
  55. public $type = 'alias';
  56. /*!
  57. If true languages are filtered, otherwise all languages are fetched.
  58. */
  59. public $languages = true;
  60. /*!
  61. The offset to start the fetch.
  62. \note It only applies to fetchAll()
  63. */
  64. public $offset = 0;
  65. /*!
  66. The max limit of the fetch.
  67. \note It only applies to fetchAll()
  68. */
  69. public $limit = 15;
  70. /*!
  71. The order in which elements are fetched, refers the the DB column of the table.
  72. \note It only applies to fetchAll()
  73. */
  74. public $order = 'text';
  75. /*!
  76. \private
  77. Cached value of partial query, used for both count() and fetchAll().
  78. */
  79. public $query;
  80. /*!
  81. \private
  82. Cached value of the total count.
  83. */
  84. public $count;
  85. /*!
  86. \private
  87. Cached value of the fetch items.
  88. */
  89. public $items;
  90. function eZURLAliasQuery()
  91. {
  92. }
  93. function hasAttribute( $name )
  94. {
  95. return in_array( $name,
  96. array_diff( get_object_vars( $this ),
  97. array( 'query' ) ) );
  98. }
  99. function attribute( $name )
  100. {
  101. switch ( $name )
  102. {
  103. case 'count':
  104. {
  105. return $this->count();
  106. } break;
  107. case 'items':
  108. {
  109. return $this->fetchAll();
  110. } break;
  111. default:
  112. {
  113. return $this->$name;
  114. } break;
  115. }
  116. }
  117. function setAttribute( $name, $value )
  118. {
  119. $this->$name = $value;
  120. $this->query = null;
  121. $this->count = null;
  122. $this->items = null;
  123. }
  124. /*!
  125. Resets all internally cached values. This must be called
  126. if the properties have been changed after count() or
  127. fetchAll() has been used.
  128. */
  129. function prepare()
  130. {
  131. $this->query = null;
  132. $this->count = null;
  133. $this->items = null;
  134. }
  135. /*!
  136. Counts the total number of items available using the current
  137. filters as specified with the properties.
  138. \note Can also be fetched from templates by using the 'count' property.
  139. */
  140. function count()
  141. {
  142. if ( $this->count !== null )
  143. return $this->count;
  144. if ( $this->query === null )
  145. {
  146. $this->query = $this->generateSQL();
  147. }
  148. if ( $this->query === false )
  149. return 0;
  150. $query = "SELECT count(*) AS count {$this->query}";
  151. $db = eZDB::instance();
  152. $rows = $db->arrayQuery( $query );
  153. if ( count( $rows ) == 0 )
  154. $this->count = 0;
  155. else
  156. $this->count = $rows[0]['count'];
  157. return $this->count;
  158. }
  159. /*!
  160. Fetches the items in the current range (offset/limit) using the current
  161. filters as specified with the properties.
  162. \note Can also be fetched from templates by using the 'items' property.
  163. */
  164. function fetchAll()
  165. {
  166. if ( $this->items !== null )
  167. return $this->items;
  168. if ( $this->query === null )
  169. {
  170. $this->query = $this->generateSQL();
  171. }
  172. if ( $this->query === false )
  173. return array();
  174. $query = "SELECT * {$this->query} ORDER BY {$this->order}";
  175. $params = array( 'offset' => $this->offset,
  176. 'limit' => $this->limit );
  177. $db = eZDB::instance();
  178. $rows = $db->arrayQuery( $query, $params );
  179. if ( count( $rows ) == 0 )
  180. $this->items = array();
  181. else
  182. $this->items = eZURLAliasQuery::makeList( $rows );
  183. return $this->items;
  184. }
  185. /*!
  186. \private
  187. Generates the common part of the SQL using the properties as filters and returns it.
  188. */
  189. protected function generateSQL()
  190. {
  191. if ( !in_array( $this->type, array( 'name', 'alias', 'all' ) ) )
  192. {
  193. eZDebug::writeError( "Parameter \$type must be one of name, alias or all. The value which was used was '{$this->type}'." );
  194. return null;
  195. }
  196. $db = eZDB::instance();
  197. if ( $this->languages === true )
  198. {
  199. $langMask = trim( eZContentLanguage::languagesSQLFilter( 'ezurlalias_ml', 'lang_mask' ) );
  200. $conds[] = "($langMask)";
  201. }
  202. if ( $this->paren !== null )
  203. {
  204. $conds[] = "parent = {$this->paren}";
  205. }
  206. if ( $this->text !== null )
  207. {
  208. $conds[] = "text_md5 = " . $db->md5( "'" . $db->escapeString( $this->text ) . "'" );
  209. }
  210. if ( $this->actions !== null )
  211. {
  212. // Check for conditions which will return no rows.
  213. if ( count( $this->actions ) == 0 )
  214. return false;
  215. if ( count( $this->actions ) == 1 )
  216. {
  217. $action = $this->actions[0];
  218. $actionStr = $db->escapeString( $action );
  219. $conds[] = "action = '$actionStr'";
  220. }
  221. else
  222. {
  223. $actions = array();
  224. foreach ( $this->actions as $action )
  225. {
  226. $actions[] = "'" . $db->escapeString( $action ) . "'";
  227. }
  228. $conds[] = "action IN (" . join( ", ", $actions ) . ")";
  229. }
  230. }
  231. $actionTypes = null;
  232. if ( $this->actionTypes !== null )
  233. {
  234. $actionTypes = $this->actionTypes;
  235. }
  236. if ( $this->actionTypesEx !== null )
  237. {
  238. if ( $actionTypes == null )
  239. {
  240. $rows = $db->arrayQuery( "SELECT DISTINCT action_type FROM ezurlalias_ml" );
  241. $actionTypes = array();
  242. foreach ( $rows as $row )
  243. {
  244. $actionTypes[] = $row['action_type'];
  245. }
  246. }
  247. $actionTypes = array_values( array_diff( $actionTypes, $this->actionTypesEx ) );
  248. }
  249. if ( $actionTypes !== null )
  250. {
  251. // Check for conditions which will return no rows.
  252. if ( count( $actionTypes ) == 0 )
  253. return false;
  254. if ( count( $actionTypes ) == 1 )
  255. {
  256. $action = $actionTypes[0];
  257. $actionStr = $db->escapeString( $action );
  258. $conds[] = "action_type = '$actionStr'";
  259. }
  260. else
  261. {
  262. $actions = array();
  263. foreach ( $actionTypes as $action )
  264. {
  265. $actions[] = "'" . $db->escapeString( $action ) . "'";
  266. }
  267. $conds[] = "action_type IN (" . join( ", ", $actions ) . ")";
  268. }
  269. }
  270. $conds[] = 'is_original = 1';
  271. if ( $this->type == 'name' )
  272. {
  273. $conds[] = 'is_alias = 0';
  274. }
  275. else if ( $this->type == 'alias' )
  276. {
  277. $conds[] = 'is_alias = 1';
  278. }
  279. else // 'all'
  280. {
  281. }
  282. return "FROM ezurlalias_ml WHERE " . join( " AND ", $conds );
  283. }
  284. /*!
  285. \static
  286. Takes an array with database data in $row and turns them into eZPathElement objects.
  287. Entries which have multiple languages will be turned into multiple objects.
  288. */
  289. static public function makeList( $rows )
  290. {
  291. if ( !is_array( $rows ) || count( $rows ) == 0 )
  292. return array();
  293. $list = array();
  294. foreach ( $rows as $row )
  295. {
  296. $row['always_available'] = $row['lang_mask'] % 2;
  297. $mask = $row['lang_mask'] & ~1;
  298. for ( $i = 1; $i < 30; ++$i )
  299. {
  300. $newMask = (1 << $i);
  301. if ( ($newMask & $mask) > 0 )
  302. {
  303. $row['lang_mask'] = (1 << $i);
  304. $list[] = $row;
  305. }
  306. }
  307. }
  308. $objectList = eZPersistentObject::handleRows( $list, 'eZPathElement', true );
  309. return $objectList;
  310. }
  311. }
  312. ?>