PageRenderTime 37ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/output/include/locking.php

https://gitlab.com/Lidbary/PHPRunner
PHP | 352 lines | 269 code | 51 blank | 32 comment | 23 complexity | 35a54bdc6995bf718678617480ecfd02 MD5 | raw file
  1. <?php
  2. class oLocking
  3. {
  4. var $lockTableName = "";
  5. var $ConfirmTime=250;
  6. var $UnlockTime=300;
  7. var $ConfirmAdmin;
  8. var $ConfirmUser;
  9. var $LockAdmin;
  10. var $LockUser;
  11. var $UserID;
  12. /**
  13. * @type Connection
  14. */
  15. protected $connection;
  16. /**
  17. * @constructor
  18. */
  19. function oLocking()
  20. {
  21. global $cman;
  22. $this->ConfirmAdmin = "Administrator %s aborted your edit session";
  23. $this->ConfirmUser = "Your edit session timed out";
  24. $this->LockAdmin = "Record is edited by %s during %s minutes";
  25. $this->LockUser = "Record is edited by another user";
  26. $this->connection = $cman->getForLocking();
  27. if(isset($_SESSION["UserID"]) && !is_null($_SESSION["UserID"]))
  28. $this->UserID = $_SESSION["UserID"];
  29. else
  30. $this->UserID = "Guest";
  31. }
  32. function LockRecord($strtable,$keys)
  33. {
  34. $skeys = "";
  35. foreach($keys as $ind=>$val)
  36. {
  37. if(strlen($skeys))
  38. $skeys.="&";
  39. $skeys.=rawurlencode($val);
  40. }
  41. $sdate = now();
  42. // add a record - try to lock
  43. $this->insert($strtable, $sdate, $sdate, $skeys, session_id(), $this->UserID, 1);
  44. $arrDelete = array();
  45. // check all locking records
  46. $where = $this->connection->addFieldWrappers("table")."=".$this->connection->prepareString($strtable)
  47. ." AND ".$this->connection->addFieldWrappers("keys")."=".$this->connection->prepareString($skeys)
  48. ." AND ".$this->connection->addFieldWrappers("action")."=1";
  49. $qResult = $this->query( $where, $this->connection->addFieldWrappers("id")." asc" );
  50. while( $data = $qResult->fetchAssoc() )
  51. {
  52. if(secondsPassedFrom($data["confirmdatetime"])>$this->UnlockTime)
  53. {
  54. // locking record is expired
  55. $arrDelete[]=$data["id"];
  56. }
  57. else
  58. {
  59. // delete expired records
  60. foreach($arrDelete as $ind=>$val)
  61. {
  62. $this->delete($this->connection->addFieldWrappers("id"). "=" .$val);
  63. }
  64. if($data["sessionid"]==session_id())
  65. {
  66. // locking was successful
  67. return true;
  68. }
  69. else
  70. {
  71. // record is already locked, delete locking attempt
  72. $where = $this->connection->addFieldWrappers("sessionid"). "=" .$this->connection->prepareString(session_id()) ." AND ".
  73. $this->connection->addFieldWrappers("action"). "=1" ." AND ".
  74. $this->connection->addFieldWrappers("table"). "=" .$this->connection->prepareString($strtable) ." AND ".
  75. $this->connection->addFieldWrappers("keys"). "=" .$this->connection->prepareString($skeys);
  76. $this->delete($where);
  77. return false;
  78. }
  79. }
  80. }
  81. return false;
  82. }
  83. function UnlockRecord($strtable,$keys,$sid)
  84. {
  85. if($sid=="")
  86. $sid=session_id();
  87. $skeys="";
  88. foreach($keys as $ind=>$val)
  89. {
  90. if(strlen($skeys))
  91. $skeys.="&";
  92. $skeys.=rawurlencode($val);
  93. }
  94. $where = $this->connection->addFieldWrappers("sessionid"). "=" .$this->connection->prepareString($sid) ." AND ".
  95. $this->connection->addFieldWrappers("action"). "=1 AND ".
  96. $this->connection->addFieldWrappers("table"). "=" .$this->connection->prepareString($strtable) ." AND ".
  97. $this->connection->addFieldWrappers("keys"). "=" .$this->connection->prepareString($skeys);
  98. $this->delete($where);
  99. }
  100. function ConfirmLock($strtable,$keys,&$message)
  101. {
  102. $skeys="";
  103. foreach($keys as $ind=>$val)
  104. {
  105. if(strlen($skeys))
  106. $skeys.="&";
  107. $skeys.=rawurlencode($val);
  108. }
  109. // add locking attempt
  110. $sdate = now();
  111. $this->insert($strtable, $sdate, $sdate, $skeys, session_id(), $this->UserID, 1);
  112. $where = $this->connection->addFieldWrappers("table")."=".$this->connection->prepareString($strtable)
  113. ." AND ".$this->connection->addFieldWrappers("keys")."=".$this->connection->prepareString($skeys)
  114. ." AND ".$this->connection->addFieldWrappers("action")."=1";
  115. $qResult = $this->query( $where, $this->connection->addFieldWrappers("id")." asc" );
  116. $myfound=0; // total our records found
  117. $newid=0; // last our record - added 5 lines ago
  118. $oldid=0; // next to last our record
  119. $newdate=""; // last our confirm time
  120. $olddate=""; // next to last our confirm time
  121. $otherfound=0; // other's records found between out last and next to last
  122. $tempfound=0;
  123. // check all locking records, count records
  124. while( $data = $qResult->fetchAssoc() )
  125. {
  126. if($data["sessionid"]==session_id())
  127. {
  128. $oldid=$newid;
  129. $newid=$data["id"];
  130. $newdate=$data["confirmdatetime"];
  131. $olddate=$newdate;
  132. $myfound++;
  133. $otherfound=$tempfound;
  134. $tempfound=0;
  135. continue;
  136. }
  137. $tempfound++;
  138. }
  139. if($myfound>1 && !$otherfound)
  140. {
  141. // no other's records, locking is confirmed
  142. $this->update($this->connection->addFieldWrappers("confirmdatetime"). "=" .$this->connection->addDateQuotes(now()),
  143. $this->connection->addFieldWrappers("id"). "=" .$oldid);
  144. $this->delete($this->connection->addFieldWrappers("id"). "=" .$newid);
  145. return true;
  146. }
  147. elseif($myfound>1 && $otherfound)
  148. {
  149. // found some other's records
  150. // check if previous record is not expired
  151. if(secondsPassedFrom($olddate)>$this->UnlockTime-5)
  152. {
  153. // expired - delete locking record, confirm was not successful
  154. $this->UnlockRecord($strtable,$keys,session_id());
  155. $message=$this->ConfirmUser;
  156. return false;
  157. }
  158. else
  159. {
  160. // not expired, locking is confirmed
  161. $this->update($this->connection->addFieldWrappers("confirmdatetime"). "=" .$this->connection->addDateQuotes(now()),
  162. $this->connection->addFieldWrappers("id"). "=" .$oldid);
  163. $this->delete($this->connection->addFieldWrappers("id"). "=" .$newid);
  164. return true;
  165. }
  166. }
  167. else
  168. {
  169. // locking was lost
  170. $this->UnlockRecord($strtable,$keys,session_id());
  171. // check if locking was removed by admin or not
  172. $where = $this->connection->addFieldWrappers("table")."=".$this->connection->prepareString($strtable)
  173. ." AND ".$this->connection->addFieldWrappers("keys")."=".$this->connection->prepareString($skeys)
  174. ." AND ".$this->connection->addFieldWrappers("sessionid")."<>'".session_id()
  175. ."' AND ".$this->connection->addFieldWrappers("action")."=2";
  176. if($data = $this->query( $where, $this->connection->addFieldWrappers("id")." asc" )->fetchAssoc())
  177. $message = mysprintf($this->ConfirmAdmin,array($data["userid"]));
  178. else
  179. $message = $this->ConfirmUser;
  180. $where = $this->connection->addFieldWrappers("action"). "=2 AND ".
  181. $this->connection->addFieldWrappers("table"). "=" .$this->connection->prepareString($strtable) ." AND ".
  182. $this->connection->addFieldWrappers("keys"). "=" .$this->connection->prepareString($skeys);
  183. $this->delete($where);
  184. return false;
  185. }
  186. }
  187. function GetLockInfo($strtable,$keys,$links, $pageid)
  188. {
  189. $page=GetTableLink(GetTableURL($strtable), "edit");
  190. $skeys="";
  191. foreach($keys as $ind=>$val){
  192. if(strlen($skeys))
  193. $skeys.="&";
  194. $skeys.=rawurlencode($val);
  195. }
  196. $where = $this->connection->addFieldWrappers("table")."=".$this->connection->prepareString($strtable)
  197. ." AND ".$this->connection->addFieldWrappers("keys")."=".$this->connection->prepareString($skeys)
  198. ." AND ".$this->connection->addFieldWrappers("sessionid")."<>'".session_id()
  199. ."' AND ".$this->connection->addFieldWrappers("action")."=1";
  200. $qResult = $this->query( $where, $this->connection->addFieldWrappers("id")." asc" );
  201. if( $data = $qResult->fetchAssoc() )
  202. {
  203. $sdate = now();
  204. $arrDateTime = db2time($data["startdatetime"]);
  205. $str = mysprintf($this->LockAdmin,array($data["userid"],round(secondsPassedFrom($data["startdatetime"])/60,2)));
  206. if($links){
  207. $str.='<a class="unlock" href="#" onclick="Runner.pages.PageManager.getAt(\''.runner_htmlspecialchars(jsreplace($strtable)).'\', '.$pageid.').locking.UnlockAdmin(\''
  208. .runner_htmlspecialchars(jsreplace($skeys)).'\',\''.$data["sessionid"].'\',\'no\');return false;">'."Unlock record".'</a>';
  209. $str.='<a class="edit" href="#" onclick="Runner.pages.PageManager.getAt(\''.runner_htmlspecialchars(jsreplace($strtable)).'\', '.$pageid.').locking.UnlockAdmin(\''
  210. .runner_htmlspecialchars(jsreplace($skeys)).'\',\''.$data["sessionid"].'\',\'yes\');return false;">'."Edit record".'</a>';
  211. }
  212. return $str;
  213. }
  214. return "";
  215. }
  216. function UnlockAdmin($strtable, $keys, $startEdit)
  217. {
  218. $skeys = "";
  219. foreach($keys as $ind=>$val)
  220. {
  221. if(strlen($skeys))
  222. $skeys .= "&";
  223. $skeys .= rawurlencode($val);
  224. }
  225. $sdate = now();
  226. if($startEdit)
  227. {
  228. // add a record - lock
  229. $this->insert($strtable, $sdate, $sdate, $skeys, session_id(), $this->UserID, 1);
  230. }
  231. // delete all other locking records
  232. $where = $this->connection->addFieldWrappers("table")."=".$this->connection->prepareString($strtable)
  233. ." AND ".$this->connection->addFieldWrappers("keys")."=".$this->connection->prepareString($skeys)
  234. ." AND ".$this->connection->addFieldWrappers("action")."=1 AND ".$this->connection->addFieldWrappers("sessionid")."<>".$this->connection->prepareString(session_id());
  235. $this->delete( $where );
  236. // inform other users that their locking were removed by locking
  237. $where = $this->connection->addFieldWrappers("startdatetime")."<".$this->connection->addDateQuotes(format_datetime_custom( adddays(db2time(now()), -2), "yyyy-MM-dd HH:mm:ss" ))
  238. ." AND ".$this->connection->addFieldWrappers("action")."=2";
  239. $this->delete( $where );
  240. $this->insert($strtable, $sdate, $sdate, $skeys, session_id(), $this->UserID, 2);
  241. }
  242. /**
  243. * Check if there is any record with particular
  244. * fields' values in the 'locking' table
  245. * @param String table
  246. * @param String keys
  247. * @param String action
  248. * @return Boolean
  249. */
  250. public function isLocked( $table, $keys, $action )
  251. {
  252. $lockSQL = "select count(*) from ". $this->connection->addTableWrappers( $this->lockTableName )
  253. ." where ". $this->connection->addFieldWrappers("keys") ."=". $this->connection->prepareString( $lockWhere )
  254. ." AND ". $this->connection->addFieldWrappers("table") ."=". $this->connection->prepareString( $table )
  255. ." AND ". $this->connection->addFieldWrappers("action") ."=". $action;
  256. $lockSet = $this->connection->query( $lockSQL )->fetchNumeric();
  257. return $lockSet[0] > 0;
  258. }
  259. protected function insert($table, $startdatetime, $confirmdatetime, $keys, $sessionid, $userid, $action)
  260. {
  261. $sql = "INSERT INTO " .$this->connection->addTableWrappers( $this->lockTableName ).
  262. " (" .$this->connection->addFieldWrappers("table").
  263. "," .$this->connection->addFieldWrappers("startdatetime").
  264. "," .$this->connection->addFieldWrappers("confirmdatetime").
  265. "," .$this->connection->addFieldWrappers("keys").
  266. "," .$this->connection->addFieldWrappers("sessionid").
  267. "," .$this->connection->addFieldWrappers("userid").
  268. "," .$this->connection->addFieldWrappers("action").
  269. ") VALUES (" .$this->connection->prepareString($table).
  270. "," .$this->connection->addDateQuotes($startdatetime).
  271. "," .$this->connection->addDateQuotes($confirmdatetime).
  272. "," .$this->connection->prepareString($keys).
  273. "," .$this->connection->prepareString($sessionid).
  274. "," .$this->connection->prepareString($this->UserID).
  275. "," .$action.
  276. ")";
  277. return $this->connection->exec( $sql );
  278. }
  279. protected function query($where, $orderBy)
  280. {
  281. if(!$where)
  282. return;
  283. $sql = "SELECT * FROM " .$this->connection->addTableWrappers( $this->lockTableName ). " WHERE " .$where. " ORDER BY " .$orderBy;
  284. return $this->connection->query( $sql );
  285. }
  286. protected function delete($where)
  287. {
  288. if(!$where)
  289. return;
  290. $sql = "DELETE FROM " .$this->connection->addTableWrappers( $this->lockTableName ). " WHERE " .$where;
  291. $this->connection->exec( $sql );
  292. }
  293. protected function update($values, $where)
  294. {
  295. if(!$where || !$values)
  296. return;
  297. $sql = "UPDATE " .$this->connection->addTableWrappers( $this->lockTableName ). " SET " .$values. " WHERE " .$where;
  298. $this->connection->exec( $sql );
  299. }
  300. }
  301. ?>