Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
locking_method_default.inc
1 <?php
17 require_once SQ_CORE_PACKAGE_PATH.'/system/locking/locking_method/locking_method.inc';
18 
19 
39 {
40 
41 
51  public function __construct($assetid=0)
52  {
53  parent::__construct($assetid);
54 
55  }//end __construct()
56 
57 
84  public static function acquireLock($lockid, $source_lockid='', $expires=0)
85  {
86  $current_lock = $GLOBALS['SQ_SYSTEM']->getLockInfo($lockid);
87 
88  // is this asset already locked
89  if (!empty($current_lock)) {
90  // the user is asking to acquire a lock they already had
91  // so just update the lock expiry date
92  if ($current_lock['userid'] == $GLOBALS['SQ_SYSTEM']->currentUserid()) {
93  return self::updateLock($lockid, $expires);
94  } else {
95  $user = $GLOBALS['SQ_SYSTEM']->am->getAsset($current_lock['userid']);
96  throw new Exception('Lock already held by "'.$user->name.'"');
97  }
98  }
99 
100  // if we have no source, we are the asset aquiring the locks
101  if (empty($source_lockid)) $source_lockid = $lockid;
102 
103  if (!is_null($expires)) {
104  $expires = (empty($expires)) ? (time() + SQ_CONF_LOCK_LENGTH) : (int) $expires;
105  $expires = ts_iso8601($expires);
106  }
107 
108  $GLOBALS['SQ_SYSTEM']->changeDatabaseConnection('db3');
109  $GLOBALS['SQ_SYSTEM']->doTransaction('BEGIN');
110 
111  $sql = 'INSERT INTO sq_lock
112  (lockid, source_lockid, userid, expires)
113  VALUES
114  (:lockid, :source_lockid, :userid, :expires)';
115 
116  try {
117  $query = MatrixDAL::preparePdoQuery($sql);
118  MatrixDAL::bindValueToPdo($query, 'lockid', $lockid);
119  MatrixDAL::bindValueToPdo($query, 'source_lockid', $source_lockid);
120  MatrixDAL::bindValueToPdo($query, 'userid', $GLOBALS['SQ_SYSTEM']->currentUserId());
121  MatrixDAL::bindValueToPdo($query, 'expires', $expires);
122  MatrixDAL::execPdoQuery($query);
123  } catch (Exception $e) {
124  // Rather than throwing our own exception, keep the previous format
125  // of returning an error message for now
126  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
127  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
128  throw new Exception('DB error: '.$e->getMessage());
129  }
130 
131  $GLOBALS['SQ_SYSTEM']->doTransaction('COMMIT');
132  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
133  return TRUE;
134 
135  }//end acquireLock()
136 
137 
158  public static function updateLock($lockid, $expires=0)
159  {
160  $current_lock = self::getLockInfo($lockid);
161 
162  // If there is no current lock (it may have expired), or if the lock
163  // is indefinite, do nothing
164  if (empty($current_lock) || empty($current_lock['expires'])) {
165  return TRUE;
166  }
167 
168  if (!is_null($expires)) {
169  $expires = (!$expires) ? (time() + SQ_CONF_LOCK_LENGTH) : (int) $expires;
170  $expires = ts_iso8601($expires);
171  }
172 
173  $GLOBALS['SQ_SYSTEM']->changeDatabaseConnection('db3');
174  $GLOBALS['SQ_SYSTEM']->doTransaction('BEGIN');
175 
176  $sql = 'UPDATE sq_lock
177  SET expires = :expires
178  WHERE source_lockid = :source_lockid';
179 
180  try {
181  $query = MatrixDAL::preparePdoQuery($sql);
182  MatrixDAL::bindValueToPdo($query, 'expires', $expires);
183  MatrixDAL::bindValueToPdo($query, 'source_lockid', $current_lock['source_lockid']);
184  MatrixDAL::execPdoQuery($query);
185  } catch (Exception $e) {
186  // Rollback and then re-throw, let parent call handle the exception
187  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
188  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
189  throw new Exception('DB error: '.$e->getMessage());
190  }
191 
192  $GLOBALS['SQ_SYSTEM']->doTransaction('COMMIT');
193  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
194  return TRUE;
195 
196  }//end acquireLock()
197 
198 
211  public static function releaseLock($lockid)
212  {
213  $current_lock = self::getLockInfo($lockid, FALSE, FALSE);
214  if (empty($current_lock)) return TRUE;
215 
216  $GLOBALS['SQ_SYSTEM']->changeDatabaseConnection('db3');
217  $GLOBALS['SQ_SYSTEM']->doTransaction('BEGIN');
218 
219  $sql = 'DELETE FROM sq_lock
220  WHERE source_lockid = :source_lockid';
221 
222  try {
223  $query = MatrixDAL::preparePdoQuery($sql);
224  MatrixDAL::bindValueToPdo($query, 'source_lockid', $current_lock['source_lockid']);
225  $result = MatrixDAL::execPdoQuery($query);
226  } catch (Exception $e) {
227  // Rather than throwing our own exception, keep the previous format
228  // of returning an error message for now
229  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
230  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
231  throw new Exception('DB error: '.$e->getMessage());
232  }
233 
234  $GLOBALS['SQ_SYSTEM']->doTransaction('COMMIT');
235 
236  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
237  return TRUE;
238 
239  }//end releaseLock()
240 
241 
261  public static function getLockInfo($lockid, $full_chain=FALSE, $check_expires=TRUE, $allow_only_one=TRUE)
262  {
263  // Change to the "locks" connection
264  $GLOBALS['SQ_SYSTEM']->changeDatabaseConnection('db3');
265 
266  // Did I get a string or an array?
267  $where = '';
268  $locks_passed = Array();
269  if (is_array($lockid)) {
270  $where = ' WHERE lockid IN (';
271  foreach ($lockid as $lock_key => $lock_value) {
272  $where .= ':lockid'.$lock_key.',';
273  $locks_passed['lockid'.$lock_key] = $lock_value;
274  }
275  $where = rtrim($where, ',');
276  $where .= ')';
277  } else {
278  $where = ' WHERE lockid = :lockid';
279  $locks_passed['lockid'] = $lockid;
280  }
281 
282  $sql = 'SELECT lockid, source_lockid, userid, expires
283  FROM sq_lock'.$where;
284 
285  try {
286  $query = MatrixDAL::preparePdoQuery($sql);
287  foreach($locks_passed as $bind_var => $bind_val) {
288  MatrixDAL::bindValueToPdo($query, $bind_var, $bind_val);
289  }
290  $results = MatrixDAL::executePdoAssoc($query);
291  } catch (Exception $e) {
292  $lock_error = (is_array($lockid)) ? ('s '.implode(', ', $lockid)) : (' '.$lockid);
293  throw new Exception('Unable to get lock information for lock ID"'.$lock_error.'" due to database error: '.$e->getMessage());
294  }
295 
296  if (!empty($results)) {
297  foreach ($results as $result_key => $result) {
298  $results[$result_key]['expires'] = empty($result['expires']) ? NULL : iso8601_ts($result['expires']);
299  if ($check_expires && !empty($result['expires'])) {
300  if ($results[$result_key]['expires'] < time()) {
301  self::releaseLock($lockid);
302  // this lock has expired
303  if (count($results) > 1) {
304  // More locks to check
305  unset($results[$result_key]);
306  continue;
307  } else {
308  // All done fin
309  $results = Array();
310  break;
311  }//end if
312  }//end if
313  }//end if
314 
315  if ($full_chain) {
316  $results[$result_key]['chained_assets'] = Array();
317  foreach ($locks_passed as $lock_to_test) {
318  $sql = 'SELECT lockid, source_lockid, userid, expires
319  FROM sq_lock
320  WHERE source_lockid = :source_lockid
321  AND lockid <> :lockid';
322 
323  try {
324  $query = MatrixDAL::preparePdoQuery($sql);
325  MatrixDAL::bindValueToPdo($query, 'source_lockid', $result['source_lockid']);
326  MatrixDAL::bindValueToPdo($query, 'lockid', $lock_to_test);
327  $chain = MatrixDAL::executePdoAssoc($query);
328  } catch (Exception $e) {
329  throw new Exception('Unable to get lock chain information for source lock ID "'.$result['source_lockid'].'" due to database error: '.$e->getMessage());
330  }
331 
332  foreach ($chain as $lock_row) {
333  $lock_row['expires'] = (empty($lock_row['expires'])) ? NULL : iso8601_ts($lock_row['expires']);
334  $results[$result_key]['chained_assets'][$lock_row['lockid']] = $lock_row;
335  }
336  }//end foreach
337  }//end if
338  }//end foreach
339  }//end if
340  if (!empty($results) && $allow_only_one) {
341  $results = $results[0];
342  }
343 
344  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
345  return $results;
346 
347  }//end getLockInfo()
348 
349 
362  public static function getActiveLocks($owner_assetid=NULL, $include_expired=FALSE)
363  {
364  try {
365  $bind_vars = Array();
366 
367  if ($include_expired === FALSE) {
368  $bind_vars['expire_time'] = ts_iso8601(time());
369  } else {
370  $bind_vars['expire_time'] = NULL;
371  }
372 
373  if ($owner_assetid !== NULL) {
374  $bind_vars['owner_assetid'] = $owner_assetid;
375  } else {
376  $bind_vars['owner_assetid'] = NULL;
377  }
378 
379  $db_locks = MatrixDAL::executeAll('core', 'getActiveLocks', $bind_vars);
380 
381  } catch (Exception $e) {
382  throw $e;
383 
384  }//end try catch
385 
386  return $db_locks;
387 
388  }//end getActiveLocks()
389 
390 
396  public static function supportsGetActiveLocks()
397  {
398  return TRUE;
399 
400  }//end supportsGetActiveLocks()
401 
402 
417  public static function changeLockOwner($old_assetid, $new_assetid)
418  {
419  $bind_vars = Array(
420  'old_userid' => $old_assetid,
421  'new_userid' => $new_assetid,
422  );
423  MatrixDAL::executeQuery('core', 'changeAllLocksHeldUser', $bind_vars);
424  return TRUE;
425 
426  }//end changeLockOwner()
427 
428 
434  public static function supportsChangeLockOwner()
435  {
436  return TRUE;
437 
438  }//end supportsChangeLockOwner()
439 
440 
446  public static function supportsDeletingExpiredLocks()
447  {
448  return TRUE;
449 
450  }//end supportsDeletingExpiredLocks()
451 
452 
453  public static function deleteExpiredLocks()
454  {
455  $bind_vars['expire_time'] = ts_iso8601(time());
456 
457  MatrixDAL::executeQuery('core', 'deleteExpiredLocks', $bind_vars);
458  return TRUE;
459  }
460 }//end class
461 
462 ?>