eZ Publish  [trunk]
ezurlaliasquery.php
Go to the documentation of this file.
00001 <?php
00002 /**
00003  * File containing the eZURLAliasFilter class.
00004  *
00005  * @copyright Copyright (C) 1999-2012 eZ Systems AS. All rights reserved.
00006  * @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License v2
00007  * @version //autogentag//
00008  * @package kernel
00009  */
00010 
00011 /*!
00012   \class eZURLAliasQuery ezurlaliasquery.php
00013   \brief Handles querying of URL aliases with different filters
00014 
00015   To use this class instantiate it and then fill in the public
00016   properties with the wanted values. When finished call count()
00017   and/or fetchAll() to perform the wanted operation. Repeated
00018   calls will simply return the cached values.
00019 
00020   If you change the properties afterwards call prepare() to reset
00021   internally cached values.
00022 
00023   Objects of this class can also be sent to the template system
00024   as a variable and the properties can be accessed directly
00025   including 'count' for the count() function and 'items' for the
00026   'fetchAll' function.
00027 */
00028 
00029 
00030 /*!
00031  \todo The hasAttribute, attribute and setAttribute functions can be turned into properties for PHP 5.
00032  */
00033 class eZURLAliasQuery
00034 {
00035     /*!
00036      Array of action values to include, set to null to fetch all kinds.
00037      e.g. eznode:60
00038      */
00039     public $actions;
00040     /*!
00041      Array of action types to include, set to null to fetch all kinds.
00042      e.g. eznode
00043      */
00044     public $actionTypes;
00045     /*!
00046      Array of action types to exclude, set to null to disable.
00047      e.g. eznode
00048      */
00049     public $actionTypesEx;
00050     /*!
00051      If non-null it forces only elements with this parent to be considered.
00052      */
00053     public $paren;
00054     /*!
00055      If non-null it forces only elements with this text to be considered.
00056      */
00057     public $text;
00058     /*!
00059      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.
00060      */
00061     public $type      = 'alias';
00062     /*!
00063      If true languages are filtered, otherwise all languages are fetched.
00064      */
00065     public $languages = true;
00066     /*!
00067      The offset to start the fetch.
00068      \note It only applies to fetchAll()
00069      */
00070     public $offset    = 0;
00071     /*!
00072      The max limit of the fetch.
00073      \note It only applies to fetchAll()
00074      */
00075     public $limit     = 15;
00076     /*!
00077      The order in which elements are fetched, refers the the DB column of the table.
00078      \note It only applies to fetchAll()
00079      */
00080     public $order     = 'text';
00081 
00082     /*!
00083      \private
00084      Cached value of partial query, used for both count() and fetchAll().
00085      */
00086     public $query;
00087     /*!
00088      \private
00089      Cached value of the total count.
00090      */
00091     public $count;
00092     /*!
00093      \private
00094      Cached value of the fetch items.
00095      */
00096     public $items;
00097 
00098     function eZURLAliasQuery()
00099     {
00100     }
00101 
00102     function hasAttribute( $name )
00103     {
00104         return in_array( $name,
00105                          array_diff( get_object_vars( $this ),
00106                                      array( 'query' ) ) );
00107     }
00108 
00109     function attribute( $name )
00110     {
00111         switch ( $name )
00112         {
00113             case 'count':
00114             {
00115                 return $this->count();
00116             } break;
00117             case 'items':
00118             {
00119                 return $this->fetchAll();
00120             } break;
00121             default:
00122             {
00123                 return $this->$name;
00124             } break;
00125         }
00126     }
00127 
00128     function setAttribute( $name, $value )
00129     {
00130         $this->$name = $value;
00131         $this->query = null;
00132         $this->count = null;
00133         $this->items = null;
00134     }
00135 
00136     /*!
00137      Resets all internally cached values. This must be called
00138      if the properties have been changed after count() or
00139      fetchAll() has been used.
00140      */
00141     function prepare()
00142     {
00143         $this->query = null;
00144         $this->count = null;
00145         $this->items = null;
00146     }
00147 
00148     /*!
00149      Counts the total number of items available using the current
00150      filters as specified with the properties.
00151      \note Can also be fetched from templates by using the 'count' property.
00152      */
00153     function count()
00154     {
00155         if ( $this->count !== null )
00156             return $this->count;
00157 
00158         if ( $this->query === null )
00159         {
00160             $this->query = $this->generateSQL();
00161         }
00162         if ( $this->query === false )
00163             return 0;
00164         $query = "SELECT count(*) AS count {$this->query}";
00165         $db = eZDB::instance();
00166         $rows = $db->arrayQuery( $query );
00167         if ( count( $rows ) == 0 )
00168             $this->count = 0;
00169         else
00170             $this->count = $rows[0]['count'];
00171         return $this->count;
00172     }
00173 
00174     /*!
00175      Fetches the items in the current range (offset/limit) using the current
00176      filters as specified with the properties.
00177      \note Can also be fetched from templates by using the 'items' property.
00178      */
00179     function fetchAll()
00180     {
00181         if ( $this->items !== null )
00182             return $this->items;
00183 
00184         if ( $this->query === null )
00185         {
00186             $this->query = $this->generateSQL();
00187         }
00188         if ( $this->query === false )
00189             return array();
00190         $query = "SELECT * {$this->query} ORDER BY {$this->order}";
00191         $params = array( 'offset' => $this->offset,
00192                          'limit'  => $this->limit );
00193         $db = eZDB::instance();
00194         $rows = $db->arrayQuery( $query, $params );
00195         if ( count( $rows ) == 0 )
00196             $this->items = array();
00197         else
00198             $this->items = eZURLAliasQuery::makeList( $rows );
00199         return $this->items;
00200     }
00201 
00202     /*!
00203      \private
00204      Generates the common part of the SQL using the properties as filters and returns it.
00205      */
00206     protected function generateSQL()
00207     {
00208         if ( !in_array( $this->type, array( 'name', 'alias', 'all' ) ) )
00209         {
00210             eZDebug::writeError( "Parameter \$type must be one of name, alias or all. The value which was used was '{$this->type}'." );
00211             return null;
00212         }
00213 
00214         $db = eZDB::instance();
00215         if ( $this->languages === true )
00216         {
00217             $langMask = trim( eZContentLanguage::languagesSQLFilter( 'ezurlalias_ml', 'lang_mask' ) );
00218             $conds[] = "($langMask)";
00219         }
00220 
00221         if ( $this->paren !== null )
00222         {
00223             $conds[] = "parent = {$this->paren}";
00224         }
00225 
00226         if ( $this->text !== null )
00227         {
00228             $conds[] = "text_md5 = " . $db->md5( "'" . $db->escapeString( $this->text ) . "'" );
00229         }
00230 
00231         if ( $this->actions !== null )
00232         {
00233             // Check for conditions which will return no rows.
00234             if ( count( $this->actions ) == 0 )
00235                 return false;
00236 
00237             if ( count( $this->actions ) == 1 )
00238             {
00239                 $action = $this->actions[0];
00240                 $actionStr = $db->escapeString( $action );
00241                 $conds[] = "action = '$actionStr'";
00242             }
00243             else
00244             {
00245                 $actions = array();
00246                 foreach ( $this->actions as $action )
00247                 {
00248                     $actions[] = "'" . $db->escapeString( $action ) . "'";
00249                 }
00250                 $conds[] = "action IN (" . join( ", ", $actions ) . ")";
00251             }
00252         }
00253         $actionTypes = null;
00254         if ( $this->actionTypes !== null )
00255         {
00256             $actionTypes = $this->actionTypes;
00257         }
00258         if ( $this->actionTypesEx !== null )
00259         {
00260             if ( $actionTypes == null )
00261             {
00262                 $rows = $db->arrayQuery( "SELECT DISTINCT action_type FROM ezurlalias_ml" );
00263                 $actionTypes = array();
00264                 foreach ( $rows as $row )
00265                 {
00266                     $actionTypes[] = $row['action_type'];
00267                 }
00268             }
00269             $actionTypes = array_values( array_diff( $actionTypes, $this->actionTypesEx ) );
00270         }
00271         if ( $actionTypes !== null )
00272         {
00273             // Check for conditions which will return no rows.
00274             if ( count( $actionTypes ) == 0 )
00275                 return false;
00276 
00277             if ( count( $actionTypes ) == 1 )
00278             {
00279                 $action = $actionTypes[0];
00280                 $actionStr = $db->escapeString( $action );
00281                 $conds[] = "action_type = '$actionStr'";
00282             }
00283             else
00284             {
00285                 $actions = array();
00286                 foreach ( $actionTypes as $action )
00287                 {
00288                     $actions[] = "'" . $db->escapeString( $action ) . "'";
00289                 }
00290                 $conds[] = "action_type IN (" . join( ", ", $actions ) . ")";
00291             }
00292         }
00293 
00294         $conds[] = 'is_original = 1';
00295         if ( $this->type == 'name' )
00296         {
00297             $conds[] = 'is_alias = 0';
00298         }
00299         else if ( $this->type == 'alias' )
00300         {
00301             $conds[] = 'is_alias = 1';
00302         }
00303         else // 'all'
00304         {
00305         }
00306 
00307         return "FROM ezurlalias_ml WHERE " . join( " AND ", $conds );
00308     }
00309 
00310     /*!
00311      \static
00312      Takes an array with database data in $row and turns them into eZPathElement objects.
00313      Entries which have multiple languages will be turned into multiple objects.
00314      */
00315     static public function makeList( $rows )
00316     {
00317         if ( !is_array( $rows ) || count( $rows ) == 0 )
00318             return array();
00319         $list = array();
00320         foreach ( $rows as $row )
00321         {
00322             $row['always_available'] = $row['lang_mask'] % 2;
00323             $mask = $row['lang_mask'] & ~1;
00324             for ( $i = 1; $i < 30; ++$i )
00325             {
00326                 $newMask = (1 << $i);
00327                 if ( ($newMask & $mask) > 0 )
00328                 {
00329                     $row['lang_mask'] = (1 << $i);
00330                     $list[] = $row;
00331                 }
00332             }
00333         }
00334         $objectList = eZPersistentObject::handleRows( $list, 'eZPathElement', true );
00335         return $objectList;
00336     }
00337 }
00338 
00339 ?>