wCMF  3.6
 All Classes Namespaces Files Functions Variables Groups Pages
class.LockManager.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.LockManager.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.Message.php");
21 require_once(BASE."wcmf/lib/util/class.InifileParser.php");
22 require_once(BASE."wcmf/lib/util/class.SessionData.php");
23 require_once(BASE."wcmf/lib/persistence/class.PersistenceFacade.php");
24 require_once(BASE."wcmf/lib/persistence/class.NullLockManager.php");
25 require_once(BASE."wcmf/lib/persistence/class.Lock.php");
26 require_once(BASE."wcmf/lib/security/class.RightsManager.php");
27 require_once(BASE."wcmf/lib/util/class.ObjectFactory.php");
28 
29 /**
30  * @class LockManager
31  * @ingroup Persistence
32  * @brief LockManager is used to handle lock requests on objects.
33  *
34  * This class defines abstract methods that subclasses must implement to support
35  * different lock storages.
36  *
37  * @author ingo herwig <ingo@wemove.com>
38  */
40 {
41  /**
42  * Returns an instance of the class.
43  * @return A reference to the only instance of the Singleton object
44  */
45  function &getInstance()
46  {
47  static $instance = null;
48 
49  $parser = &InifileParser::getInstance();
50  $locking = $parser->getValue('locking', 'cms');
51  if ($locking)
52  {
53  if (!is_object($instance) )
54  {
55  // if the application runs in anonymous mode, locking is not supported
56  $anonymous = $parser->getValue('anonymous', 'cms');
57  if ($anonymous)
58  {
59  require_once(BASE."wcmf/lib/persistence/class.NullLockManager.php");
60  $instance = new NullLockManager();
61  }
62  else
63  {
64  $objectFactory = &ObjectFactory::getInstance();
65  $instance = &$objectFactory->createInstanceFromConfig('implementation', 'LockManager');
66  if ($instance === null)
67  WCMFException::throwEx($objectFactory->getErrorMsg(), __FILE__, __LINE__);
68  }
69  }
70  return $instance;
71  }
72  else
73  {
74  return new NullLockManager();
75  }
76  }
77  /**
78  * Lock a persistent object if it is not locked already and the current user
79  * is allowed to modify it.
80  * @note static method
81  * @param object The object to lock
82  * @param name The display name of the object
83  * @return A message describing the problem if locking is not possible
84  * because another user holds the lock
85  */
86  function handleLocking(&$object, $name)
87  {
88  $lockMsg = "";
89 
90  if (strtolower(get_class($object)) == 'persistentobject' || is_a($object, 'PersistentObject'))
91  {
92  $lockManager = &LockManager::getInstance();
93  $rightsManager = &RightsManager::getInstance();
94  // check if we can edit the object
95  if ($rightsManager->authorize($object->getOID(), '', ACTION_MODIFY))
96  {
97  // if object is locked by another user we retrieve the lock to show a message
98  $lock = $object->getLock();
99  if ($lock != null)
100  $lockMsg .= $lockManager->getLockMessage($lock, $name).'<br />';
101  else
102  {
103  // try to lock object
104  $lockManager->aquireLock($object->getOID());
105  }
106  }
107  }
108  return $lockMsg;
109  }
110  /**
111  * Aquire a lock on an OID for the current user.
112  * @param oid object id of the object to lock.
113  * @return True if successfull/False in case of an invalid oid or a Lock instance in case of an existing lock.
114  */
115  function aquireLock($oid)
116  {
117  if (!PersistenceFacade::isValidOID($oid))
118  return false;
119 
120  $lock = $this->getLock($oid);
121  if ($lock === null)
122  {
123  $session = &SessionData::getInstance();
124  $authUser = $this->getUser();
125  if ($authUser != null)
126  {
127  $lock = new Lock($oid, $authUser->getOID(), $authUser->getLogin(), $session->getID());
128  $this->aquireLockImpl($authUser->getOID(), $session->getID(), $oid, $lock->getCreated());
129  }
130  }
131  return $lock;
132  }
133  /**
134  * Release a lock on an OID for the current user.
135  * @param oid object id of the object to release.
136  */
137  function releaseLock($oid)
138  {
139  if (!PersistenceFacade::isValidOID($oid))
140  return false;
141 
142  $session = &SessionData::getInstance();
143  $authUser = $this->getUser();
144  if ($authUser != null)
145  $this->releaseLockImpl($authUser->getOID(), $session->getID(), $oid);
146  }
147  /**
148  * Release all locks on an OID regardless of the user.
149  * @param oid object id of the object to release.
150  */
151  function releaseLocks($oid)
152  {
153  if (!PersistenceFacade::isValidOID($oid))
154  return false;
155 
156  $this->releaseLockImpl(null, null, $oid);
157  }
158  /**
159  * Release all lock for the current user.
160  */
161  function releaseAllLocks()
162  {
163  $session = &SessionData::getInstance();
164  $authUser = $this->getUser();
165  if ($authUser != null)
166  $this->releaseAllLocksImpl($authUser->getOID(), $session->getID());
167  }
168  /**
169  * Get the default lock message for a lock.
170  * @param lock The Lock instance to construct the message for.
171  * @param objectText The display text for the locked object.
172  * @return The lock message of the form 'objectText is locked by user 'admin' since 12:12:36<br />'.
173  */
174  function getLockMessage($lock, $objectText)
175  {
176  if ($objectText == '')
177  $objectText = $lock->getOID();
178  $msg = Message::get("%1% is locked by user '%2%' since %3%. ", array($objectText, $lock->getLogin(), strftime("%X", strtotime($lock->getCreated()))));
179  //$msg .= '<a href="javascript:submitAction(\'unlock\')">'.Message::get("Click here to unlock the object").'.</a>';
180  return $msg;
181  }
182  /**
183  * Get lock data for an OID. This method may also be used to check for an lock.
184  * @note The method uses the php parameter 'session.gc_maxlifetime' to determine if a lock belongs to an expired session.
185  * A lock with a creation date older than 'session.gc_maxlifetime' seconds is regarded to belong to an expired
186  * session which results in the removal of all locks attached to that session.
187  * @param oid object id of the object to get the lock data for.
188  * @return A Lock instance or null if no lock exists/or in case of an invalid oid.
189  */
190  function getLock($oid)
191  {
192  if (!PersistenceFacade::isValidOID($oid))
193  return null;
194 
195  $lock = $this->getLockImpl($oid);
196 
197  // remove lock if session is expired
198  if ($lock != null)
199  {
200  $lifeTimeInSeconds = (mktime() - strtotime($lock->getCreated()));
201  if ($lifeTimeInSeconds > ini_get("session.gc_maxlifetime"))
202  {
203  $this->releaseLockImpl($lock->getUserOID(), $lock->getSessionID(), null);
204  $lock = null;
205  }
206  }
207  return $lock;
208  }
209  /**
210  * Get the currently logged in user.
211  * @return An instance of AuthUser.
212  */
213  function &getUser()
214  {
215  $rightsManager = &RightsManager::getInstance();
216  return $rightsManager->getAuthUser();
217  }
218  /**
219  * Aquire a lock on an OID for a given user.
220  * @param useroid The oid of the user.
221  * @param sessid The id of the session of the user.
222  * @param oid object id of the object to lock.
223  * @param lockDate date of the lock.
224  */
225  function aquireLockImpl($useroid, $sessid, $oid, $lockDate)
226  {
227  WCMFException::throwEx("aquireLockImpl() must be implemented by derived class: ".get_class($this), __FILE__, __LINE__);
228  }
229  /**
230  * Release a lock on an OID for a given user or all locks for that user or all locks for the OID.
231  * The behaviour depends on the given parameters. A null means that this parameter should be ignored
232  * @param useroid The oid of the user or null to ignore the userid.
233  * @param sessid The id of the session of the user or null to ignore the session id.
234  * @param oid object id of the object to release or null top ignore the oid.
235  */
236  function releaseLockImpl($useroid, $sessid, $oid)
237  {
238  WCMFException::throwEx("releaseLockImpl() must be implemented by derived class: ".get_class($this), __FILE__, __LINE__);
239  }
240  /**
241  * Release all lock for a given user.
242  * @param useroid The oid of the user.
243  * @param sessid The id of the session of the user.
244  */
245  function releaseAllLocksImpl($useroid, $sessid)
246  {
247  WCMFException::throwEx("releaseAllLocks() must be implemented by derived class: ".get_class($this), __FILE__, __LINE__);
248  }
249  /**
250  * Get lock data for an OID. This method may also be used to check for an lock.
251  * @param oid object id of the object to get the lock data for.
252  * @return A Lock instance or null if no lock exists/or in case of an invalid oid.
253  */
254  function getLockImpl($oid)
255  {
256  WCMFException::throwEx("getLockImpl() must be implemented by derived class: ".get_class($this), __FILE__, __LINE__);
257  }
258 }
259 ?>
get($message, $parameters=null, $domain='', $lang='')
LockManager is used to handle lock requests on objects.
throwEx($message, $file='', $line='')
releaseLockImpl($useroid, $sessid, $oid)
const ACTION_MODIFY
aquireLockImpl($useroid, $sessid, $oid, $lockDate)
getLockMessage($lock, $objectText)
handleLocking(&$object, $name)
Lock represents a lock on an object.
Definition: class.Lock.php:27
releaseAllLocksImpl($useroid, $sessid)
NullLockManager acts as if no LockManager was installed. Use this to disable locking.