2017-03-31 15 views
0

在我的应用程序中,我有一个记录锁定机制,可以防止两个人同时处于记录的编辑视图中。下面是锁定时,它在编辑观点被称为了记录功能:卸载活动页面时重置数据库字段值

public function lockRecord($id = null) { 
$this->loadModel('User'); 
$this->Model->id = $id; 
$current = $this->Model->read(null, $id); 

//Get the current logged-in user's ID 
$userid = $current['Model']['requester_id']; 

//Get the current lock expiry time 
$lock_time = $this->Model->find('first', array(
    'fields'=>array('Model.lock_expiry_time'), 
    'conditions'=>array('Model.id'=>$id) 
) 
); 

//Get the ID of the user who has the record lock (if any) 
$logged_user = $this->Model->find('first', array(
    'fields'=>array('Model.lock_key'), 
    'conditions'=>array('Model.id'=>$id) 
) 
); 

//Get that same user's full name 
$full_name = $this->User->find('first', array(
    'joins' => array(
    array(
     'table' => 'recordtable', 
     'alias' => 'Model', 
     'type' => 'INNER', 
     'conditions' => array('Model.lock_key = User.id') 
    ) 
    ) 
) 
); 
$this->set('lock_time', $lock_time); 
$this->set(compact($current)); 
$this->set(compact($logged_user)); 
$this->set(compact($full_name)); 
if(AuthComponent::user('id') != $logged_user['Msr']['lock_key'] && date("Y-m-d H:i:s") < $lock_time['Msr']['lock_expiry_time']) { 
    $this->Session->setFlash(__('This MSR is locked for editing by ' . $full_name['User']['full_name'] . '. Please try again in a few minutes or wait for this user to close the document.<br/> 
    (Lock expires at '. $lock_time['Msr']['lock_expiry_time'] . ')')); 
    $this->redirect(array('action' => 'view', $id)); 
} else { 
    //Set a new lock key and expiry time if the record is free for editing 
    $locksession = $this->Msr->query("UPDATE msrs SET lock_key = {$userid}, lock_expiry_time = ADDTIME(NOW(), '00:05:00') WHERE id = {$id}"); 
    $this->set('locksession', $locksession); 
    } 
} 

当用户保存他们的变化,unlockRecord函数被调用,以释放键,复位lock_expiry_time,并将用户重定向到“查看”视图:

public function unlockRecord($id = null) { 
//Get a list of security groups 
$groups = $this->Session->read('groups'); 
$this->Msr->id = $id; 
//Reset the lock_key and the lock_expiry_time 
$locksession = $this->Msr->query("UPDATE msrs SET lock_key = '', lock_expiry_time = '' WHERE id = {$id} "); 
//If the module admin manually releases the lock, display a message 
if(in_array('msr_module_admin', $groups)) { 
    $this->Session->setFlash(__('The MSR has been unlocked and is available for editing.')); 
} 
$this->redirect(array('action'=>'view', $id)); 
} 

存在该锁可以释放其他三个条件:

--An管理员手动解除通过单击链接锁。

- 用户完全退出系统。

- 锁定设置后五分钟过期。

我需要锁释放随时编辑视图中的记录不再有效。例如,如果用户点击另一个网站或点击我自己网站中的不同链接;任何会将它们从“编辑”视图中打开的记录中带走的内容。应将lock_key设置为'',并将lock_expiry_time设置为''。我该如何做到这一点?

+0

'“...... WHERE id = {$ id}”'Aaaand这是一个SQL注入漏洞!请确保在创建原始SQL语句时使用绑定,** _永远不会_ **直接将可能的用户数据插入到查询中! – ndm

回答

2

由于认识到您的网站上的某个页面已被用户放弃,因此无法在网页编程中可靠地执行操作。

如果她关闭她的电脑/设备或断开她的网络,您的网站会发生什么?没有。如果她在编辑页面的过程中点击书签栏中的链接,会发生什么情况?没有。你再也没有听到她的消息。这就是为什么你的锁有到期时间。

因此,要解决您的问题,您需要考虑缩短到期时间和/或减少页面放弃的机会的方法。

一个选择:在您的编辑页面中放入一些Javascript,每隔一段时间使用一次ajax-style请求,以保存请求打开您的网站。你可以把它设置成每分钟打你的网站。每次获取Keepalive请求时,都可以将失效时间延长90秒。

另一种选择:您可能已经注意到,StackOverflow页面会抛出一个浏览器对话框,显示“您想离开本网站吗?”如果在编辑帖子时按下BACK按钮。实际上,抛弃页面时抛出对话框。他们在浏览器中使用onbeforeunload事件。您可以执行相同的操作,在激活编辑页面时启用对话框,并在用户保存时禁用它。

浏览器在页面卸载时不​​允许网页强制执行除对话框之外的任何其他操作。这种功能对于cybercreeps用来传播恶意软件非常容易。

+0

这绝对比没有好,而且非常简单。我会给它一个镜头。 – Chris