wCMF  3.6
 All Classes Namespaces Files Functions Variables Groups Pages
class.PersistenceMapper.php
Go to the documentation of this file.
1 <?php
2 /**
3  * wCMF - wemove Content Management Framework
4  * Copyright (C) 2005-2014 wemove digital solutions GmbH
5  *
6  * Licensed under the terms of any of the following licenses
7  * at your choice:
8  *
9  * - GNU Lesser General Public License (LGPL)
10  * http://www.gnu.org/licenses/lgpl.html
11  * - Eclipse Public License (EPL)
12  * http://www.eclipse.org/org/documents/epl-v10.php
13  *
14  * See the license.txt file distributed with this work for
15  * additional information.
16  *
17  * $Id: class.PersistenceMapper.php 1462 2014-02-04 23:52:27Z iherwig $
18  */
19 require_once(BASE."wcmf/lib/core/class.WCMFException.php");
20 require_once(BASE."wcmf/lib/util/class.Log.php");
21 require_once(BASE."wcmf/lib/util/class.Message.php");
22 require_once(BASE."wcmf/lib/security/class.RightsManager.php");
23 require_once(BASE."wcmf/lib/persistence/class.LockManager.php");
24 require_once(BASE."wcmf/lib/persistence/class.PersistenceFacade.php");
25 
26 /**
27  * @class PersistenceMapper
28  * @ingroup Persistence
29  * @brief PersistenceMapper is the base class for all mapper classes.
30  *
31  * @author ingo herwig <ingo@wemove.com>
32  */
34 {
35  var $_dataConverter = null; // a DataConverter object that converts data before writing and after reading from storage
36  var $_type = ''; // mapper type
37  var $_logging = false;
38  var $_logStrategy = null;
39 
40  /**
41  * Get the mapper type.
42  * @return Mapper type.
43  */
44  function getType()
45  {
46  return $this->_type;
47  }
48  /**
49  * Get the names of the primary key values.
50  * @return An associative array with the value names as keys and the types as values (see PersistentObject::getValue).
51  */
52  function getPkNames()
53  {
54  WCMFException::throwEx("getPkNames() must be implemented by derived class: ".get_class($this), __FILE__, __LINE__);
55  }
56  /**
57  * Set the DataConverter that should be used on load() and save().
58  * @param dataConverter The DataConverter object.
59  */
60  function setDataConverter($dataConverter)
61  {
62  $this->_dataConverter = $dataConverter;
63  }
64  /**
65  * Get the DataConverter that is used on load() and save().
66  * @return The DataConverter object.
67  */
68  function getDataConverter()
69  {
70  return $this->_dataConverter;
71  }
72  /**
73  * Enable logging using a given OutputStrategy to log insert/update/delete actions to a file.
74  * @param logStrategy The OutputStrategy to use.
75  */
76  function enableLogging($logStrategy)
77  {
78  $this->_logStrategy = $logStrategy;
79  $this->_logging = true;
80  }
81  /**
82  * Disable logging.
83  */
84  function disableLogging()
85  {
86  $this->_logging = false;
87  }
88  /**
89  * Check if the PersistenceMapper is logging.
90  * @return True/False whether the PersistenceMapper is logging.
91  */
92  function isLogging()
93  {
94  return $this->_logging;
95  }
96  /**
97  * Log action if logging is enabled.
98  * @note Subclasses must call this method in save/delete method in appropriate place.
99  * @param obj The object on which the action is performed on.
100  */
101  function logAction(&$obj)
102  {
103  if ($this->isLogging())
104  $this->_logStrategy->writeObject($obj);
105  }
106  /**
107  * Load an object from the database.
108  * @param oid OID of the object to construct
109  * @param buildDepth One of the BUILDDEPTH constants or a number describing the number of generations to build (except BUILDDEPTH_REQUIRED)
110  * @param buildAttribs An assoziative array listing the attributes to load (default: null loads all attributes)
111  * (keys: the types, values: an array of attributes of the type to load)
112  * Use this to load only a subset of attributes
113  * @param buildTypes An array listing the (sub-)types to include
114  * @return A reference to the object, null if oid does not exist or a given condition prevents loading.
115  */
116  function &load($oid, $buildDepth, $buildAttribs=null, $buildTypes=null)
117  {
118  if (!$this->checkAuthorization($oid, ACTION_READ))
119  {
121  return;
122  }
123 
124  if (!$this->isValidOID($oid))
125  return null;
126 
127  // load object
128  $object = &$this->loadImpl($oid, $buildDepth, $buildAttribs, $buildTypes);
129  if ($object != null)
130  {
131  // set immutable if not authorized for modification
132  if (!$this->checkAuthorization($oid, ACTION_MODIFY))
133  $object->setImmutable();
134 
135  $this->initialize($object);
136 
137  // call custom initialization
138  $object->afterLoad();
139  }
140  return $object;
141  }
142  /**
143  * Construct the template of an Object of a given type.
144  * @param type The type of object to build
145  * @param buildDepth One of the BUILDDEPTH constants or a number describing the number of generations to build
146  * @param buildAttribs An assoziative array listing the attributes to create (default: null creates all attributes)
147  * (keys: the types, values: an array of attributes of the type to create)
148  * Use this to create only a subset of attributes
149  * @return A reference to the object.
150  */
151  function &create($type, $buildDepth, $buildAttribs=null)
152  {
153  // Don't check rights here, because object creation may be needed
154  // for internal purposes. That newly created objects may not be saved
155  // to the storage is asured by the save method.
156  $object = &$this->createImpl($type, $buildDepth, $buildAttribs);
157 
158  $this->initialize($object);
159 
160  // call custom initialization
161  $object->afterCreate();
162 
163  return $object;
164  }
165  /**
166  * Save an Object to the persistent storage.
167  * @param object A reference to the object to safe
168  * @return True/False depending on success of operation
169  */
170  function save(&$object)
171  {
172  if ( ($object->getState() == STATE_DIRTY) && !$this->checkAuthorization($object->getOID(), ACTION_MODIFY) )
173  {
174  $this->authorizationFailedError($object->getOID(), ACTION_MODIFY);
175  return;
176  }
177  else if ( ($object->getState() == STATE_NEW) && !$this->checkAuthorization($object->getOID(), ACTION_CREATE) )
178  {
179  $this->authorizationFailedError($object->getOID(), ACTION_CREATE);
180  return;
181  }
182 
183  // modify object
184  return $this->saveImpl($object);
185  }
186  /**
187  * Delete an Object from the persistent storage.
188  * @param oid The object id of the Object to delete
189  * @param recursive True/False whether to physically delete it's children too [default: true]
190  * @return True/False depending on success of operation
191  */
192  function delete($oid, $recursive=true)
193  {
194  if (!$this->checkAuthorization($oid, ACTION_DELETE))
195  {
197  return;
198  }
199 
200  if (!$this->isValidOID($oid))
201  return false;
202 
203  // delete oid
204  $result = $this->deleteImpl($oid, $recursive);
205  if ($result === true)
206  {
207  // release any locks on the object
208  $lockManager = &LockManager::getInstance();
209  $lockManager->releaseLocks($oid);
210  }
211  return $result;
212  }
213  /**
214  * Check authorization on an type/OID and a given action.
215  * @param oid The object id of the Object to authorize (its type will be checked too)
216  * @param action Action to authorize
217  * @return True/False depending on success of authorization
218  */
219  function checkAuthorization($oid, $action)
220  {
221  $rightsManager = &RightsManager::getInstance();
222  if (!$rightsManager->authorize($oid, '', $action))
223  return false;
224  else
225  return true;
226  }
227  function authorizationFailedError($oid, $action)
228  {
229  // when reading only log the error to avoid errors on the display
230  $msg = Message::get("Authorization failed for action '%1%' on '%2%'.", array($action, $oid));
231  if ($action == ACTION_READ)
232  Log::error($msg."\n".WCMFException::getStackTrace(), __CLASS__);
233  else
234  WCMFException::throwEx($msg, __FILE__, __LINE__);
235  }
236  /**
237  * Initialize the object after creation/loading and before handing it over to the application.
238  * @note Subclasses may override this to implement special requirements (e.g. install listeners).
239  * Remember to always call parent::initialize().
240  * @param object A reference to the object
241  */
242  function initialize(&$object)
243  {
244  }
245  /**
246  * Validate a given OID.
247  * @note Subclasses must implement this method
248  * @param oid The OID of the object.
249  * @return An True/False whether the OID is valid
250  */
251  function isValidOID($oid)
252  {
253  WCMFException::throwEx("isValidOID() must be implemented by derived class: ".get_class($this), __FILE__, __LINE__);
254  }
255  /**
256  * @see PersistenceFacade::load()
257  * @note Subclasses must implement the loading of an object from the storage in this method
258  * @note Precondition: Object rights have been checked already
259  *
260  */
261  function &loadImpl($oid, $buildDepth, $buildAttribs=null, $buildTypes=null)
262  {
263  WCMFException::throwEx("loadImpl() must be implemented by derived class: ".get_class($this), __FILE__, __LINE__);
264  }
265  /**
266  * @see PersistenceFacade::create()
267  * @note Subclasses must implement the creation of an object in this method
268  * @note Precondition: Object rights have been checked already
269  */
270  function &createImpl($type, $buildDepth, $buildAttribs=null)
271  {
272  WCMFException::throwEx("createImpl() must be implemented by derived class: ".get_class($this), __FILE__, __LINE__);
273  }
274  /**
275  * @see PersistenceFacade::save()
276  * @note Subclasses must implement the modification of an object in the storage in this method
277  * @note Precondition: Object rights have been checked already
278  */
279  function saveImpl(&$object)
280  {
281  WCMFException::throwEx("saveImpl() must be implemented by derived class: ".get_class($this), __FILE__, __LINE__);
282  }
283  /**
284  * @see PersistenceFacade::delete()
285  * @note Subclasses must implement the deletion of an object from the storage in this method
286  * @note Precondition: Object rights have been checked already
287  */
288  function deleteImpl($oid, $recursive=true)
289  {
290  WCMFException::throwEx("deleteImpl() must be implemented by derived class: ".get_class($this), __FILE__, __LINE__);
291  }
292  /**
293  * @see PersistenceFacade::getOIDs()
294  * @note Subclasses must implement the retrieval of object ids from the storage in this method
295  */
296  function getOIDs($type, $criteria=null, $orderby=null, &$pagingInfo)
297  {
298  WCMFException::throwEx("getOIDs() must be implemented by derived class: ".get_class($this), __FILE__, __LINE__);
299  }
300  /**
301  * @see PersistenceFacade::loadObjects()
302  * @note Subclasses must implement the retrieval of objects from the storage in this method
303  */
304  function loadObjects($type, $buildDepth, $criteria=null, $orderby=null, &$pagingInfo, $buildAttribs=null, $buildTypes=null)
305  {
306  WCMFException::throwEx("loadObjects() must be implemented by derived class: ".get_class($this), __FILE__, __LINE__);
307  }
308  /**
309  * Get the names of the attributes to order by, when retrieving the oids.
310  * ASC (ascending), DESC (descending) may be added to defined the order direction for each attribute.
311  * @return An array of attribute names
312  */
313  function getOrderBy()
314  {
315  WCMFException::throwEx("getOrderBy() must be implemented by derived class: ".get_class($this), __FILE__, __LINE__);
316  }
317  /**
318  * @see PersistenceFacade::startTransaction()
319  * @note The default implementation does nothing. Subclasses may override this method if required
320  */
321  function startTransaction()
322  {
323  }
324  /**
325  * @see PersistenceFacade::commitTransaction()
326  * @note The default implementation does nothing. Subclasses may override this method if required
327  */
328  function commitTransaction()
329  {
330  }
331  /**
332  * @see PersistenceFacade::rollbackTransaction()
333  * @note The default implementation does nothing. Subclasses may override this method if required
334  */
336  {
337  }
338 }
339 ?>
const STATE_DIRTY
error($message, $category)
Definition: class.Log.php:69
get($message, $parameters=null, $domain='', $lang='')
& load($oid, $buildDepth, $buildAttribs=null, $buildTypes=null)
const ACTION_DELETE
getOIDs($type, $criteria=null, $orderby=null, &$pagingInfo)
authorizationFailedError($oid, $action)
& create($type, $buildDepth, $buildAttribs=null)
throwEx($message, $file='', $line='')
setDataConverter($dataConverter)
deleteImpl($oid, $recursive=true)
const STATE_NEW
& loadImpl($oid, $buildDepth, $buildAttribs=null, $buildTypes=null)
const ACTION_MODIFY
& createImpl($type, $buildDepth, $buildAttribs=null)
checkAuthorization($oid, $action)
PersistenceMapper is the base class for all mapper classes.
loadObjects($type, $buildDepth, $criteria=null, $orderby=null, &$pagingInfo, $buildAttribs=null, $buildTypes=null)
const ACTION_READ
const ACTION_CREATE