PageRenderTime 52ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/Zikula-1.2.3/system/PageLock/pnuserapi.php

#
PHP | 227 lines | 153 code | 55 blank | 19 comment | 19 complexity | 5fe61fd9b0d3893d66465a7cab1d43d5 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, BSD-3-Clause
  1. <?php
  2. /**
  3. * Zikula Application Framework
  4. * @copyright (c) Zikula Development Team
  5. * @link http://www.zikula.org
  6. * @version $Id: pnuserapi.php 27832 2009-12-09 11:50:03Z drak $
  7. * @license GNU/GPL - http://www.gnu.org/copyleft/gpl.html
  8. * @author Jorn Wildt
  9. * @package Zikula_System_Modules
  10. * @subpackage PageLock
  11. */
  12. /**
  13. * length of time to lock a page
  14. *
  15. */
  16. define('PageLockLifetime', 30);
  17. function PageLock_userapi_pageLock($args)
  18. {
  19. $lockName = $args['lockName'];
  20. $returnUrl = (array_key_exists('returnUrl', $args) ? $args['returnUrl'] : null);
  21. $ignoreEmptyLock = (array_key_exists('ignoreEmptyLock', $args) ? $args['ignoreEmptyLock'] : false);
  22. $uname = pnUserGetVar('uname');
  23. $lockedHtml = '';
  24. if (!empty($lockName) || !$ignoreEmptyLock) {
  25. PageUtil::AddVar('javascript', 'javascript/ajax/prototype.js');
  26. PageUtil::AddVar('javascript', 'javascript/ajax/scriptaculous.js');
  27. PageUtil::AddVar('javascript', 'javascript/ajax/pnajax.js');
  28. PageUtil::AddVar('javascript', 'system/PageLock/pnjavascript/pagelock.js');
  29. PageUtil::AddVar('stylesheet', ThemeUtil::getModuleStylesheet('PageLock'));
  30. $lockInfo = pnModAPIFunc('PageLock', 'user', 'requireLock',
  31. array('lockName' => $lockName,
  32. 'lockedByTitle' => $uname,
  33. 'lockedByIPNo' => $_SERVER['REMOTE_ADDR']));
  34. $hasLock = $lockInfo['hasLock'];
  35. if (!$hasLock) {
  36. $r = & pnRender::getInstance('PageLock');
  37. $r->assign('lockedBy', $lockInfo['lockedBy']);
  38. $lockedHtml = $r->fetch('PageLock_lockedwindow.html');
  39. }
  40. } else {
  41. $hasLock = true;
  42. }
  43. $html = "<script type=\"text/javascript\">\n";
  44. if (!empty($lockName))
  45. {
  46. if ($hasLock) {
  47. $html .= "Event.observe(window, 'load', PageLock.UnlockedPage);\n";
  48. } else {
  49. $html .= "Event.observe(window, 'load', PageLock.LockedPage);\n";
  50. }
  51. }
  52. $lockedHtml = str_replace("\n", "", $lockedHtml);
  53. $lockedHtml = str_replace("\r", "", $lockedHtml);
  54. // Use "PageLockLifetime*2/3" to add a good margin to lock timeout when pinging
  55. $returnUrl = DataUtil::formatForDisplayHTML($returnUrl);
  56. $html .= "
  57. PageLock.LockName = '$lockName';
  58. PageLock.BreakLockWarning = '" . __('Are you sure you want to break this lock?') . "';
  59. PageLock.ReturnUrl = '$returnUrl';
  60. PageLock.PingTime = " . (PageLockLifetime*2/3) . ";
  61. PageLock.LockedHTML = '" . $lockedHtml . "';
  62. </script>";
  63. PageUtil::addVar('rawtext', $html);
  64. return true;
  65. }
  66. function PageLock_userapi_requireLock(&$args)
  67. {
  68. $lockName = $args['lockName'];
  69. $sessionId = (array_key_exists('sessionId', $args) ? $args['sessionId'] : session_id());
  70. $lockedByTitle = $args['lockedByTitle'];
  71. $lockedByIPNo = $args['lockedByIPNo'];
  72. PageLockRequireAccess();
  73. $locks = pnModAPIFunc('PageLock', 'user', 'getLocks',
  74. $args);
  75. if (count($locks) > 0) {
  76. $lockedBy = '';
  77. foreach ($locks as $lock) {
  78. if (strlen($lockedBy) > 0) {
  79. $lockedBy .= ', ';
  80. }
  81. $lockedBy .= $lock['lockedByTitle'] . " ($lock[lockedByIPNo]) " . $lock['createdDate'];
  82. }
  83. return array('hasLock' => false, 'lockedBy' => $lockedBy);
  84. }
  85. $args['lockedBy'] = null;
  86. $pntable = pnDBGetTables();
  87. $pageLockTable = &$pntable['PageLock'];
  88. $pageLockColumn = &$pntable['PageLock_column'];
  89. // Look for existing lock
  90. $sql = "
  91. SELECT COUNT(*)
  92. FROM $pageLockTable
  93. WHERE $pageLockColumn[name] = '" . DataUtil::formatForStore($lockName) . "' AND $pageLockColumn[lockedBySessionId] = '" . DataUtil::formatForStore($sessionId) . "'";
  94. $count = DBUtil::selectScalar($sql);
  95. $now = time();
  96. $expireDate = $now + PageLockLifetime;
  97. if ($count > 0) {
  98. // Update existing lock
  99. $sql = "
  100. UPDATE $pageLockTable
  101. SET $pageLockColumn[expiresDate] = '" . DateUtil::getDatetime($expireDate) . "'
  102. WHERE $pageLockColumn[name] = '" . DataUtil::formatForStore($lockName) . "' AND $pageLockColumn[lockedBySessionId] = '" . DataUtil::formatForStore($sessionId) . "'";
  103. DBUtil::executeSql($sql);
  104. } else {
  105. $data = array('name' => $lockName,
  106. 'createdDate' => DateUtil::getDatetime($now),
  107. 'expiresDate' => DateUtil::getDatetime($expireDate),
  108. 'lockedBySessionId' => $sessionId,
  109. 'lockedByTitle' => $lockedByTitle,
  110. 'lockedByIPNo' => $lockedByIPNo);
  111. DBUtil::insertObject($data, 'PageLock');
  112. }
  113. PageLockReleaseAccess();
  114. return array('hasLock' => true);
  115. }
  116. function PageLock_userapi_getLocks($args)
  117. {
  118. $lockName = $args['lockName'];
  119. $sessionId = (array_key_exists('sessionId', $args) ? $args['sessionId'] : session_id());
  120. PageLockRequireAccess();
  121. $dbconn = DBConnectionStack::getConnection();
  122. $pntable = pnDBGetTables();
  123. $pageLockTable = &$pntable['PageLock'];
  124. $pageLockColumn = &$pntable['PageLock_column'];
  125. $sql = "DELETE FROM $pageLockTable WHERE $pageLockColumn[expiresDate] < " . $dbconn->sysTimeStamp;
  126. DBUtil::executeSql($sql);
  127. $where = "$pageLockColumn[name] = '" . DataUtil::formatForStore($lockName) . "' AND $pageLockColumn[lockedBySessionId] != '" . DataUtil::formatForStore($sessionId) . "'";
  128. $locks = DBUtil::selectObjectArray('PageLock', $where);
  129. PageLockReleaseAccess();
  130. return $locks;
  131. }
  132. function PageLock_userapi_releaseLock($args)
  133. {
  134. $lockName = $args['lockName'];
  135. $sessionId = (array_key_exists('sessionId', $args) ? $args['sessionId'] : session_id());
  136. PageLockRequireAccess();
  137. $pntable = pnDBGetTables();
  138. $pageLockTable = &$pntable['PageLock'];
  139. $pageLockColumn = &$pntable['PageLock_column'];
  140. $sql = "DELETE FROM $pageLockTable WHERE $pageLockColumn[name] = '" . DataUtil::formatForStore($lockName) . "' AND $pageLockColumn[lockedBySessionId] = '" . DataUtil::formatForStore($sessionId) . "'";
  141. DBUtil::executeSql($sql);
  142. PageLockReleaseAccess();
  143. return true;
  144. }
  145. // Internal locking mechanism to avoid concurrency inside the PageLock functions
  146. function PageLockRequireAccess()
  147. {
  148. global $PageLockAccessCount;
  149. if ($PageLockAccessCount == null) {
  150. $PageLockAccessCount = 0;
  151. }
  152. if ($PageLockAccessCount == 0) {
  153. global $PageLockFile;
  154. $ostemp = DataUtil::formatForOS(pnConfigGetVar('temp'), true);
  155. $PageLockFile = fopen($ostemp . '/pagelock.lock', "w+");
  156. flock($PageLockFile, LOCK_EX);
  157. fwrite($PageLockFile, "This is a locking file for synchronizing access to the PageLock module. Please do not delete.");
  158. fflush($PageLockFile);
  159. }
  160. ++$PageLockAccessCount;
  161. }
  162. // Internal locking mechanism to avoid concurrency inside the PageLock functions
  163. function PageLockReleaseAccess()
  164. {
  165. global $PageLockAccessCount;
  166. --$PageLockAccessCount;
  167. if ($PageLockAccessCount == 0) {
  168. global $PageLockFile;
  169. flock($PageLockFile, LOCK_UN);
  170. fclose($PageLockFile);
  171. }
  172. }