TYPO3 API  SVNRelease
Query.php
Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
00006 *  All rights reserved
00007 *
00008 *  This class is a backport of the corresponding class of FLOW3.
00009 *  All credits go to the v5 team.
00010 *
00011 *  This script is part of the TYPO3 project. The TYPO3 project is
00012 *  free software; you can redistribute it and/or modify
00013 *  it under the terms of the GNU General Public License as published by
00014 *  the Free Software Foundation; either version 2 of the License, or
00015 *  (at your option) any later version.
00016 *
00017 *  The GNU General Public License can be found at
00018 *  http://www.gnu.org/copyleft/gpl.html.
00019 *
00020 *  This script is distributed in the hope that it will be useful,
00021 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00022 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023 *  GNU General Public License for more details.
00024 *
00025 *  This copyright notice MUST APPEAR in all copies of the script!
00026 ***************************************************************/
00027 
00028 /**
00029  * The Query class used to run queries against the database
00030  *
00031  * @package Extbase
00032  * @subpackage Persistence
00033  * @version $Id$
00034  * @scope prototype
00035  * @api
00036  */
00037 class Tx_Extbase_Persistence_Query implements Tx_Extbase_Persistence_QueryInterface {
00038 
00039     /**
00040      * @var string
00041      */
00042     protected $type;
00043 
00044     /**
00045      * @var Tx_Extbase_Object_ObjectManagerInterface
00046      */
00047     protected $objectManager;
00048 
00049     /**
00050      * @var Tx_Extbase_Persistence_DataMapper
00051      */
00052     protected $dataMapper;
00053 
00054     /**
00055      * @var Tx_Extbase_Persistence_ManagerInterface
00056      */
00057     protected $persistenceManager;
00058 
00059     /**
00060      * @var Tx_Extbase_Persistence_QOM_QueryObjectModelFactory
00061      */
00062     protected $qomFactory;
00063 
00064     /**
00065      * @var Tx_Extbase_Persistence_QOM_SourceInterface
00066      */
00067     protected $source;
00068 
00069     /**
00070      * @var Tx_Extbase_Persistence_QOM_ConstraintInterface
00071      */
00072     protected $constraint;
00073 
00074     /**
00075      * @var Tx_Extbase_Persistence_QOM_Statement
00076      */
00077     protected $statement;
00078 
00079     /**
00080      * @var int
00081      */
00082     protected $orderings = array();
00083 
00084     /**
00085      * @var int
00086      */
00087     protected $limit;
00088 
00089     /**
00090      * @var int
00091      */
00092     protected $offset;
00093 
00094     /**
00095      * The query settings.
00096      *
00097      * @var Tx_Extbase_Persistence_QuerySettingsInterface
00098      */
00099     protected $querySettings;
00100 
00101     /**
00102      * Constructs a query object working on the given class name
00103      *
00104      * @param string $type
00105      */
00106     public function __construct($type) {
00107         $this->type = $type;
00108     }
00109 
00110     /**
00111      * @param Tx_Extbase_Object_ObjectManagerInterface $objectManager
00112      * @return void
00113      */
00114     public function injectObjectManager(Tx_Extbase_Object_ObjectManagerInterface $objectManager) {
00115         $this->objectManager = $objectManager;
00116     }
00117 
00118     /**
00119      * Injects the persistence manager, used to fetch the CR session
00120      *
00121      * @param Tx_Extbase_Persistence_ManagerInterface $persistenceManager
00122      * @return void
00123      */
00124     public function injectPersistenceManager(Tx_Extbase_Persistence_ManagerInterface $persistenceManager) {
00125         $this->persistenceManager = $persistenceManager;
00126     }
00127 
00128     /**
00129      * Injects the DataMapper to map nodes to objects
00130      *
00131      * @param Tx_Extbase_Persistence_Mapper_DataMapper $dataMapper
00132      * @return void
00133      */
00134     public function injectDataMapper(Tx_Extbase_Persistence_Mapper_DataMapper $dataMapper) {
00135         $this->dataMapper = $dataMapper;
00136     }
00137 
00138     /**
00139      * Injects the Query Object Model Factory
00140      *
00141      * @param Tx_Extbase_Persistence_QOM_QueryObjectModelFactory $qomFactory
00142      * @return void
00143      */
00144     public function injectQomFactory(Tx_Extbase_Persistence_QOM_QueryObjectModelFactory $qomFactory) {
00145         $this->qomFactory = $qomFactory;
00146     }
00147 
00148     /**
00149      * Sets the Query Settings. These Query settings must match the settings expected by
00150      * the specific Storage Backend.
00151      *
00152      * @param Tx_Extbase_Persistence_QuerySettingsInterface $querySettings The Query Settings
00153      * @return void
00154      * @api This method is not part of FLOW3 API
00155      */
00156     public function setQuerySettings(Tx_Extbase_Persistence_QuerySettingsInterface $querySettings) {
00157         $this->querySettings = $querySettings;
00158     }
00159 
00160     /**
00161      * Returns the Query Settings.
00162      *
00163      * @return Tx_Extbase_Persistence_QuerySettingsInterface $querySettings The Query Settings
00164      * @api This method is not part of FLOW3 API
00165      */
00166     public function getQuerySettings() {
00167         if (!($this->querySettings instanceof Tx_Extbase_Persistence_QuerySettingsInterface)) throw new Tx_Extbase_Persistence_Exception('Tried to get the query settings without seting them before.', 1248689115);
00168         return $this->querySettings;
00169     }
00170 
00171     /**
00172      * Returns the type this query cares for.
00173      *
00174      * @return string
00175      * @api
00176      */
00177     public function getType() {
00178         return $this->type;
00179     }
00180 
00181     /**
00182      * Sets the source to fetch the result from
00183      *
00184      * @param Tx_Extbase_Persistence_QOM_SourceInterface $source
00185      */
00186     public function setSource(Tx_Extbase_Persistence_QOM_SourceInterface $source) {
00187         $this->source = $source;
00188     }
00189 
00190     /**
00191      * Returns the selectorn name or an empty string, if the source is not a selector
00192      * // TODO This has to be checked at another place
00193      * @return string The selector name
00194      */
00195     protected function getSelectorName() {
00196         if ($this->getSource() instanceof Tx_Extbase_Persistence_QOM_SelectorInterface) {
00197             return $this->source->getSelectorName();
00198         } else {
00199             return '';
00200         }
00201     }
00202 
00203     /**
00204      * Gets the node-tuple source for this query.
00205      *
00206      * @return Tx_Extbase_Persistence_QOM_SourceInterface the node-tuple source; non-null
00207     */
00208     public function getSource() {
00209         if ($this->source === NULL) {
00210             $this->source = $this->qomFactory->selector($this->getType(), $this->dataMapper->convertClassNameToTableName($this->getType()));
00211         }
00212         return $this->source;
00213     }
00214 
00215     /**
00216      * Executes the query against the database and returns the result
00217      *
00218      * @return Tx_Extbase_Persistence_QueryResultInterface|array The query result object or an array if $this->getQuerySettings()->getReturnRawQueryResult() is TRUE
00219      * @api
00220      */
00221     public function execute() {
00222         if ($this->getQuerySettings()->getReturnRawQueryResult() === TRUE) {
00223             return $this->persistenceManager->getObjectDataByQuery($this);
00224         } else {
00225             return $this->objectManager->create('Tx_Extbase_Persistence_QueryResultInterface', $this);
00226         }
00227     }
00228 
00229     /**
00230      * Executes the number of matching objects for the query
00231      *
00232      * @return integer The number of matching objects
00233      * @deprecated since Extbase 1.3.0; was removed in FLOW3; will be removed in Extbase 1.4.0; use Query::execute()::count() instead
00234      * @api
00235      */
00236     public function count() {
00237         t3lib_div::logDeprecatedFunction();
00238         return $this->persistenceManager->getObjectCountByQuery($this);
00239     }
00240 
00241     /**
00242      * Sets the property names to order the result by. Expected like this:
00243      * array(
00244      *  'foo' => Tx_Extbase_Persistence_QueryInterface::ORDER_ASCENDING,
00245      *  'bar' => Tx_Extbase_Persistence_QueryInterface::ORDER_DESCENDING
00246      * )
00247      * where 'foo' and 'bar' are property names.
00248      *
00249      * @param array $orderings The property names to order by
00250      * @return Tx_Extbase_Persistence_QueryInterface
00251      * @api
00252      */
00253     public function setOrderings(array $orderings) {
00254         $this->orderings = $orderings;
00255         return $this;
00256     }
00257 
00258     /**
00259      * Returns the property names to order the result by. Like this:
00260      * array(
00261      *  'foo' => Tx_Extbase_Persistence_QueryInterface::ORDER_ASCENDING,
00262      *  'bar' => Tx_Extbase_Persistence_QueryInterface::ORDER_DESCENDING
00263      * )
00264      *
00265      * @return array
00266      * @api
00267      */
00268     public function getOrderings() {
00269         return $this->orderings;
00270     }
00271 
00272     /**
00273      * Sets the maximum size of the result set to limit. Returns $this to allow
00274      * for chaining (fluid interface)
00275      *
00276      * @param integer $limit
00277      * @return Tx_Extbase_Persistence_QueryInterface
00278      * @api
00279      */
00280     public function setLimit($limit) {
00281         if (!is_int($limit) || $limit < 1) throw new InvalidArgumentException('The limit must be an integer >= 1', 1245071870);
00282         $this->limit = $limit;
00283         return $this;
00284     }
00285 
00286     /**
00287      * Returns the maximum size of the result set to limit.
00288      *
00289      * @param integer
00290      * @api
00291      */
00292     public function getLimit() {
00293         return $this->limit;
00294     }
00295 
00296     /**
00297      * Sets the start offset of the result set to offset. Returns $this to
00298      * allow for chaining (fluid interface)
00299      *
00300      * @param integer $offset
00301      * @return Tx_Extbase_Persistence_QueryInterface
00302      * @api
00303      */
00304     public function setOffset($offset) {
00305         if (!is_int($offset) || $offset < 0) throw new InvalidArgumentException('The offset must be a positive integer', 1245071872);
00306         $this->offset = $offset;
00307         return $this;
00308     }
00309 
00310     /**
00311      * Returns the start offset of the result set.
00312      *
00313      * @return integer
00314      * @api
00315      */
00316     public function getOffset() {
00317         return $this->offset;
00318     }
00319 
00320     /**
00321      * The constraint used to limit the result set. Returns $this to allow
00322      * for chaining (fluid interface)
00323      *
00324      * @param Tx_Extbase_Persistence_QOM_ConstraintInterface $constraint
00325      * @return Tx_Extbase_Persistence_QueryInterface
00326      * @api
00327      */
00328     public function matching($constraint) {
00329         $this->constraint = $constraint;
00330         return $this;
00331     }
00332 
00333     /**
00334      * Sets the statement of this query programmatically. If you use this, you will lose the abstraction from a concrete storage
00335      * backend (database).
00336      *
00337      * @param string $statement The statement
00338      * @param array $paramerters An array of parameters. These will be bound to placeholders '?' in the $statement.
00339      * @return Tx_Extbase_Persistence_QueryInterface
00340      */
00341     public function statement($statement, array $parameters = array()) {
00342         $this->statement = $this->qomFactory->statement($statement, $parameters);
00343         return $this;
00344     }
00345 
00346     /**
00347      * Returns the statement of this query.
00348      *
00349      * @return Tx_Extbase_Persistence_QOM_Statement
00350      */
00351     public function getStatement() {
00352         return $this->statement;
00353     }
00354 
00355     /**
00356      * Gets the constraint for this query.
00357      *
00358      * @return Tx_Extbase_Persistence_QOM_Constraint the constraint, or null if none
00359      * @api
00360     */
00361     public function getConstraint() {
00362         return $this->constraint;
00363     }
00364 
00365     /**
00366      * Performs a logical conjunction of the given constraints. The method takes one or more contraints and concatenates them with a boolean AND.
00367      * It also scepts a single array of constraints to be concatenated.
00368      *
00369      * @param mixed $constraint1 The first of multiple constraints or an array of constraints.
00370      * @return Tx_Extbase_Persistence_QOM_AndInterface
00371      * @api
00372      */
00373     public function logicalAnd($constraint1) {
00374         if (is_array($constraint1)) {
00375             $resultingConstraint = array_shift($constraint1);
00376             $constraints = $constraint1;
00377         } else {
00378             $constraints = func_get_args();
00379             $resultingConstraint = array_shift($constraints);
00380         }
00381         if ($resultingConstraint === NULL) {
00382             throw new Tx_Extbase_Persistence_Exception_InvalidNumberOfConstraints('There must be at least one constraint or a non-empty array of constraints given.', 1268056288);
00383         }
00384         foreach ($constraints as $constraint) {
00385             $resultingConstraint = $this->qomFactory->_and(
00386                 $resultingConstraint,
00387                 $constraint
00388                 );
00389         }
00390         return $resultingConstraint;
00391     }
00392 
00393     /**
00394      * Performs a logical disjunction of the two given constraints
00395      *
00396      * @param mixed $constraint1 The first of multiple constraints or an array of constraints.
00397      * @return Tx_Extbase_Persistence_QOM_OrInterface
00398      * @api
00399      */
00400     public function logicalOr($constraint1) {
00401         if (is_array($constraint1)) {
00402             $resultingConstraint = array_shift($constraint1);
00403             $constraints = $constraint1;
00404         } else {
00405             $constraints = func_get_args();
00406             $resultingConstraint = array_shift($constraints);
00407         }
00408         if ($resultingConstraint === NULL) {
00409             throw new Tx_Extbase_Persistence_Exception_InvalidNumberOfConstraints('There must be at least one constraint or a non-empty array of constraints given.', 1268056288);
00410         }
00411         foreach ($constraints as $constraint) {
00412             $resultingConstraint = $this->qomFactory->_or(
00413                 $resultingConstraint,
00414                 $constraint
00415                 );
00416         }
00417         return $resultingConstraint;
00418     }
00419 
00420     /**
00421      * Performs a logical negation of the given constraint
00422      *
00423      * @param object $constraint Constraint to negate
00424      * @return Tx_Extbase_Persistence_QOM_NotInterface
00425      * @api
00426      */
00427     public function logicalNot($constraint) {
00428         return $this->qomFactory->not($constraint);
00429     }
00430 
00431     /**
00432      * Matches against the (internal) uid.
00433      *
00434      * @param int $uid The uid to match against
00435      * @return Tx_Extbase_Persistence_QOM_ComparisonInterface
00436      * @deprecated since Extbase 1.2.0; was removed in FLOW3; will be removed in Extbase 1.3.0; use equals() instead
00437      */
00438     public function withUid($operand) {
00439         t3lib_div::logDeprecatedFunction();
00440         return $this->qomFactory->comparison(
00441             $this->qomFactory->propertyValue('uid', $this->getSelectorName()),
00442             Tx_Extbase_Persistence_QueryInterface::OPERATOR_EQUAL_TO,
00443             $operand
00444             );
00445     }
00446 
00447     /**
00448      * Returns an equals criterion used for matching objects against a query
00449      *
00450      * @param string $propertyName The name of the property to compare against
00451      * @param mixed $operand The value to compare with
00452      * @param boolean $caseSensitive Whether the equality test should be done case-sensitive
00453      * @return Tx_Extbase_Persistence_QOM_ComparisonInterface
00454      * @api
00455      */
00456     public function equals($propertyName, $operand, $caseSensitive = TRUE) {
00457         if (is_object($operand) || $caseSensitive) {
00458             $comparison = $this->qomFactory->comparison(
00459                 $this->qomFactory->propertyValue($propertyName, $this->getSelectorName()),
00460                 Tx_Extbase_Persistence_QueryInterface::OPERATOR_EQUAL_TO,
00461                 $operand
00462             );
00463         } else {
00464             $comparison = $this->qomFactory->comparison(
00465                 $this->qomFactory->lowerCase(
00466                     $this->qomFactory->propertyValue($propertyName, $this->getSelectorName())
00467                 ),
00468                 Tx_Extbase_Persistence_QueryInterface::OPERATOR_EQUAL_TO,
00469                 strtolower($operand)
00470             );
00471         }
00472 
00473         return $comparison;
00474     }
00475 
00476     /**
00477      * Returns a like criterion used for matching objects against a query
00478      *
00479      * @param string $propertyName The name of the property to compare against
00480      * @param mixed $operand The value to compare with
00481      * @return Tx_Extbase_Persistence_QOM_ComparisonInterface
00482      * @api
00483      */
00484     public function like($propertyName, $operand) {
00485         return $this->qomFactory->comparison(
00486             $this->qomFactory->propertyValue($propertyName, $this->getSelectorName()),
00487             Tx_Extbase_Persistence_QueryInterface::OPERATOR_LIKE,
00488             $operand
00489             );
00490     }
00491 
00492     /**
00493      * Returns a "contains" criterion used for matching objects against a query.
00494      * It matches if the multivalued property contains the given operand.
00495      *
00496      * @param string $propertyName The name of the (multivalued) property to compare against
00497      * @param mixed $operand The value to compare with
00498      * @return Tx_Extbase_Persistence_QOM_ComparisonInterface
00499      * @api
00500      */
00501     public function contains($propertyName, $operand){
00502         return $this->qomFactory->comparison(
00503             $this->qomFactory->propertyValue($propertyName, $this->getSelectorName()),
00504             Tx_Extbase_Persistence_QueryInterface::OPERATOR_CONTAINS,
00505             $operand
00506         );
00507     }
00508 
00509     /**
00510      * Returns an "in" criterion used for matching objects against a query. It
00511      * matches if the property's value is contained in the multivalued operand.
00512      *
00513      * @param string $propertyName The name of the property to compare against
00514      * @param mixed $operand The value to compare with, multivalued
00515      * @return Tx_Extbase_Persistence_QOM_ComparisonInterface
00516      * @api
00517      */
00518     public function in($propertyName, $operand) {
00519         if (!is_array($operand) && (!$operand instanceof ArrayAccess) && (!$operand instanceof Traversable)) {
00520             throw new Tx_Extbase_Persistence_Exception_UnexpectedTypeException('The "in" operator must be given a mutlivalued operand (array, ArrayAccess, Traversable).', 1264678095);
00521         }
00522 
00523         return $this->qomFactory->comparison(
00524             $this->qomFactory->propertyValue($propertyName, $this->getSelectorName()),
00525             Tx_Extbase_Persistence_QueryInterface::OPERATOR_IN,
00526             $operand
00527         );
00528     }
00529 
00530     /**
00531      * Returns a less than criterion used for matching objects against a query
00532      *
00533      * @param string $propertyName The name of the property to compare against
00534      * @param mixed $operand The value to compare with
00535      * @return Tx_Extbase_Persistence_QOM_ComparisonInterface
00536      * @api
00537      */
00538     public function lessThan($propertyName, $operand) {
00539         return $this->qomFactory->comparison(
00540             $this->qomFactory->propertyValue($propertyName, $this->getSelectorName()),
00541             Tx_Extbase_Persistence_QueryInterface::OPERATOR_LESS_THAN,
00542             $operand
00543             );
00544     }
00545 
00546     /**
00547      * Returns a less or equal than criterion used for matching objects against a query
00548      *
00549      * @param string $propertyName The name of the property to compare against
00550      * @param mixed $operand The value to compare with
00551      * @return Tx_Extbase_Persistence_QOM_ComparisonInterface
00552      * @api
00553      */
00554     public function lessThanOrEqual($propertyName, $operand) {
00555         return $this->qomFactory->comparison(
00556             $this->qomFactory->propertyValue($propertyName, $this->getSelectorName()),
00557             Tx_Extbase_Persistence_QueryInterface::OPERATOR_LESS_THAN_OR_EQUAL_TO,
00558             $operand
00559             );
00560     }
00561 
00562     /**
00563      * Returns a greater than criterion used for matching objects against a query
00564      *
00565      * @param string $propertyName The name of the property to compare against
00566      * @param mixed $operand The value to compare with
00567      * @return Tx_Extbase_Persistence_QOM_ComparisonInterface
00568      * @api
00569      */
00570     public function greaterThan($propertyName, $operand) {
00571         return $this->qomFactory->comparison(
00572             $this->qomFactory->propertyValue($propertyName, $this->getSelectorName()),
00573             Tx_Extbase_Persistence_QueryInterface::OPERATOR_GREATER_THAN,
00574             $operand
00575             );
00576     }
00577 
00578     /**
00579      * Returns a greater than or equal criterion used for matching objects against a query
00580      *
00581      * @param string $propertyName The name of the property to compare against
00582      * @param mixed $operand The value to compare with
00583      * @return Tx_Extbase_Persistence_QOM_ComparisonInterface
00584      * @api
00585      */
00586     public function greaterThanOrEqual($propertyName, $operand) {
00587         return $this->qomFactory->comparison(
00588             $this->qomFactory->propertyValue($propertyName, $this->getSelectorName()),
00589             Tx_Extbase_Persistence_QueryInterface::OPERATOR_GREATER_THAN_OR_EQUAL_TO,
00590             $operand
00591             );
00592     }
00593 
00594     /**
00595      * @return void
00596      */
00597     public function __wakeup() {
00598         $this->objectManager = t3lib_div::makeInstance('Tx_Extbase_Object_ObjectManager');
00599         $this->persistenceManager = $this->objectManager->get('Tx_Extbase_Persistence_ManagerInterface');
00600         $this->dataMapper = $this->objectManager->get('Tx_Extbase_Persistence_Mapper_DataMapper');
00601         $this->qomFactory = $this->objectManager->get('Tx_Extbase_Persistence_QOM_QueryObjectModelFactory');
00602     }
00603 
00604     /**
00605      * @return array
00606      */
00607     public function __sleep() {
00608         return array('type', 'source', 'constraint', 'statement', 'orderings', 'limit', 'offset', 'querySettings');
00609     }
00610 
00611 }
00612 ?>