AbstractQuery.php
1 <?php
2 /**
3  * wCMF - wemove Content Management Framework
4  * Copyright (C) 2005-2015 wemove digital solutions GmbH
5  *
6  * Licensed under the terms of the MIT License.
7  *
8  * See the LICENSE file distributed with this work for
9  * additional information.
10  */
11 namespace wcmf\lib\model;
12 
21 
22 /**
23  * AbstractQuery is the base class for all query classes.
24  *
25  * @author ingo herwig <ingo@wemove.com>
26  */
27 abstract class AbstractQuery {
28 
29  private $_selectStmt = null;
30 
31  /**
32  * Get the name of the type that should be queried
33  * @return String
34  */
35  protected abstract function getQueryType();
36 
37  /**
38  * Execute the query
39  * @param $buildDepth One of the BUILDDEPTH constants or a number describing the number of generations to load (except BuildDepth::REQUIRED)
40  * or false if only object ids should be returned
41  * @param $orderby An array holding names of attributes to order by, maybe appended with 'ASC', 'DESC' (maybe null) (default: _null_)
42  * @param $pagingInfo A reference paging info instance (optional, default: _null_)
43  * @return A list of objects that match the given conditions or a list of object ids
44  */
45  public function execute($buildDepth, $orderby=null, $pagingInfo=null) {
46  // build the query
47  $this->_selectStmt = $this->buildQuery($orderby, $pagingInfo);
48 
49  return $this->executeInternal($this->_selectStmt, $buildDepth, $pagingInfo);
50  }
51 
52  /**
53  * Get the query serialized to a string. Placeholder are replaced with quoted values.
54  * @param $orderby An array holding names of attributes to order by, maybe appended with 'ASC', 'DESC' (optional, default: _null_)
55  * @return String
56  */
57  public function getQueryString($orderby=null) {
58  $selectStmt = $this->buildQuery($orderby);
59  $str = $selectStmt->__toString();
60  $persistenceFacade = ObjectFactory::getInstance('persistenceFacade');
61  $mapper = $persistenceFacade->getMapper($selectStmt->getType());
62  foreach ($selectStmt->getBind() as $value) {
63  $str = preg_replace('/\?/', $mapper->quoteValue($value), $str, 1);
64  }
65  return $str;
66  }
67 
68  /**
69  * Get the query last executed serialized to a string.
70  * @return String
71  */
72  public function getLastQueryString() {
73  if ($this->_selectStmt != null) {
74  return $this->_selectStmt->__toString();
75  }
76  return "";
77  }
78 
79  /**
80  * Build the query
81  * @param $orderby An array holding names of attributes to order by, maybe appended with 'ASC', 'DESC' (optional, default: _null_)
82  * @param $pagingInfo A reference paging info instance (optional, default: _null_)
83  * @return SelectStatement instance
84  */
85  protected abstract function buildQuery($orderby=null, PagingInfo $pagingInfo=null);
86 
87  /**
88  * Execute the query and return the results.
89  * @param $selectStmt A SelectStatement instance
90  * @param $buildDepth One of the BUILDDEPTH constants or a number describing the number of generations to load (except BuildDepth::REQUIRED)
91  * or false if only object ids should be returned
92  * @param $pagingInfo A reference paging info instance (default: _null_)
93  * @return A list of objects that match the given conditions or a list of object ids
94  */
95  protected function executeInternal(SelectStatement $selectStmt, $buildDepth, PagingInfo $pagingInfo=null) {
96  $type = $this->getQueryType();
97  $loadOidsOnly = ($buildDepth === false);
98 
99  // load only the necessary attributes if only object ids are requested
100  if ($loadOidsOnly) {
101  $buildDepth = BuildDepth::SINGLE;
102  }
103 
104  // execute the query
105  $mapper = self::getMapper($type);
106  $objects = $mapper->loadObjectsFromSQL($selectStmt, $buildDepth, $pagingInfo);
107 
108  // remove objects for which the user is not authorized
109  $permissionManager = ObjectFactory::getInstance('permissionManager');
110  $persistenceFacade = ObjectFactory::getInstance('persistenceFacade');
111  $tx = $persistenceFacade->getTransaction();
112 
113  // remove objects for which the user is not authorized
114  $result = array();
115  for ($i=0, $count=sizeof($objects); $i<$count; $i++) {
116  $object = $objects[$i];
117  if ($permissionManager->authorize($object->getOID(), '', PersistenceAction::READ)) {
118  // call lifecycle callback
119  $object->afterLoad();
120  $result[] = $object;
121  }
122  else {
123  $tx->detach($object->getOID());
124  }
125  // TODO remove attribute values for which the user is not authorized
126  // should use some pre-check if restrictions on the entity type exist
127  }
128 
129  // transform the result
130  if ($loadOidsOnly) {
131  // collect oids
132  $oids = array();
133  foreach ($result as $object) {
134  $oids[] = $object->getOID();
135  }
136  $result = $oids;
137  }
138  return $result;
139  }
140 
141  /**
142  * Get the database connection of the given node type.
143  * @param $type The node type to get the connection from connection
144  * @return The connection
145  */
146  protected static function getConnection($type) {
147  $mapper = self::getMapper($type);
148  $conn = $mapper->getConnection();
149  return $conn;
150  }
151 
152  /**
153  * Get the mapper for a Node and check if it is a supported one.
154  * @param $type The type of Node to get the mapper for
155  * @return RDBMapper instance
156  */
157  protected static function getMapper($type) {
158  $persistenceFacade = ObjectFactory::getInstance('persistenceFacade');
159  $mapper = $persistenceFacade->getMapper($type);
160  self::checkMapper($mapper);
161  return $mapper;
162  }
163 
164  /**
165  * Check if a mapper is a supported one.
166  * @param $mapper PersistenceMapper instance
167  * @throws PersistenceException
168  */
169  protected static function checkMapper(PersistenceMapper $mapper) {
170  if (!($mapper instanceof RDBMapper)) {
171  $message = ObjectFactory::getInstance('message');
172  throw new PersistenceException($message->getText('Only PersistenceMappers of type RDBMapper are supported.'));
173  }
174  }
175 }
176 ?>
Node related interfaces and classes.
Definition: namespaces.php:26
execute($buildDepth, $orderby=null, $pagingInfo=null)
Execute the query.
static checkMapper(PersistenceMapper $mapper)
Check if a mapper is a supported one.
RDBMapper maps objects of one type to a relational database schema.
Definition: RDBMapper.php:49
getQueryString($orderby=null)
Get the query serialized to a string.
PersistenceMapper defines the interface for all mapper classes.
getLastQueryString()
Get the query last executed serialized to a string.
static getInstance($name, $dynamicConfiguration=array())
PagingInfo contains information about a paged list.
Definition: PagingInfo.php:18
getQueryType()
Get the name of the type that should be queried.
static getConnection($type)
Get the database connection of the given node type.
executeInternal(SelectStatement $selectStmt, $buildDepth, PagingInfo $pagingInfo=null)
Execute the query and return the results.
PersistenceException signals an exception in the persistence service.
static getMapper($type)
Get the mapper for a Node and check if it is a supported one.
buildQuery($orderby=null, PagingInfo $pagingInfo=null)
Build the query.
AbstractQuery is the base class for all query classes.