[gen] Improved the page lock system.

This commit is contained in:
Gaetan Delannay 2013-01-18 11:26:01 +01:00
parent bdf41adf36
commit d42dffacad
5 changed files with 34 additions and 21 deletions

View file

@ -195,7 +195,7 @@ class BaseMixin:
prevent other users to edit this page at the same time.''' prevent other users to edit this page at the same time.'''
if not hasattr(self.aq_base, 'locks'): if not hasattr(self.aq_base, 'locks'):
# Create the persistent mapping that will store the lock # Create the persistent mapping that will store the lock
# ~{s_page: s_userId}~ # ~{s_page: (s_userId, DateTime_lockDate)}~
from persistent.mapping import PersistentMapping from persistent.mapping import PersistentMapping
self.locks = PersistentMapping() self.locks = PersistentMapping()
# Raise an error is the page is already locked by someone else. If the # Raise an error is the page is already locked by someone else. If the
@ -206,14 +206,15 @@ class BaseMixin:
from AccessControl import Unauthorized from AccessControl import Unauthorized
raise Unauthorized('This page is locked.') raise Unauthorized('This page is locked.')
# Set the lock # Set the lock
self.locks[page] = userId from DateTime import DateTime
self.locks[page] = (userId, DateTime())
def isLocked(self, user, page): def isLocked(self, user, page):
'''Is this page locked? If the page is locked by the same user, we don't '''Is this page locked? If the page is locked by the same user, we don't
mind and consider the page as unlocked. If the page is locked, this mind and consider the page as unlocked. If the page is locked, this
method returns the id of the user that has locked the page.''' method returns the tuple (userId, lockDate).'''
if hasattr(self.aq_base, 'locks') and (page in self.locks): if hasattr(self.aq_base, 'locks') and (page in self.locks):
if (user.getId() != self.locks[page]): return self.locks[page] if (user.getId() != self.locks[page][0]): return self.locks[page]
def removeLock(self, page): def removeLock(self, page):
'''Removes the lock on the current page. This happens after the page has '''Removes the lock on the current page. This happens after the page has
@ -222,7 +223,7 @@ class BaseMixin:
# Raise an error if the user that saves changes is not the one that # Raise an error if the user that saves changes is not the one that
# has locked the page. # has locked the page.
userId = self.getUser().getId() userId = self.getUser().getId()
if self.locks[page] != userId: if self.locks[page][0] != userId:
from AccessControl import Unauthorized from AccessControl import Unauthorized
raise Unauthorized('This page was locked by someone else.') raise Unauthorized('This page was locked by someone else.')
# Remove the lock # Remove the lock
@ -234,7 +235,7 @@ class BaseMixin:
view.pt for this page. In this case, we consider that the user has view.pt for this page. In this case, we consider that the user has
left the edit page in an unexpected way and we remove the lock.''' left the edit page in an unexpected way and we remove the lock.'''
if hasattr(self.aq_base, 'locks') and (page in self.locks) and \ if hasattr(self.aq_base, 'locks') and (page in self.locks) and \
(user.getId() == self.locks[page]): (user.getId() == self.locks[page][0]):
del self.locks[page] del self.locks[page]
def onCreateWithoutForm(self): def onCreateWithoutForm(self):

View file

@ -201,7 +201,7 @@ appyLabels = [
('changes_show', 'Show changes'), ('changes_show', 'Show changes'),
('changes_hide', 'Hide changes'), ('changes_hide', 'Hide changes'),
('anonymous', 'an anonymous user'), ('anonymous', 'an anonymous user'),
('page_locked', 'This page is locked by ${user}.'), ('page_locked', '${date} - This page is locked by ${user}.'),
] ]
# Some default values for labels whose ids are not fixed (so they can't be # Some default values for labels whose ids are not fixed (so they can't be

BIN
gen/ui/lockedBig.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -253,9 +253,9 @@
</tal:comment> </tal:comment>
<table metal:define-macro="buttons" cellpadding="2" cellspacing="0" style="margin-top: 7px" <table metal:define-macro="buttons" cellpadding="2" cellspacing="0" style="margin-top: 7px"
tal:define="previousPage python: contextObj.getPreviousPage(phaseInfo, page)[0]; tal:define="previousPage python: contextObj.getPreviousPage(phaseInfo, page)[0];
nextPage python: contextObj.getNextPage(phaseInfo, page)[0]; nextPage python: contextObj.getNextPage(phaseInfo, page)[0];
isEdit python: layoutType == 'edit'; isEdit python: layoutType == 'edit';
pageInfo python: phaseInfo['pagesInfo'][page]"> pageInfo python: phaseInfo['pagesInfo'][page]">
<tr> <tr>
<tal:comment replace="nothing">Previous</tal:comment> <tal:comment replace="nothing">Previous</tal:comment>
<td tal:condition="python: previousPage and pageInfo['showPrevious']"> <td tal:condition="python: previousPage and pageInfo['showPrevious']">
@ -287,14 +287,25 @@
title python: _('object_cancel')"/> title python: _('object_cancel')"/>
</td> </td>
<tal:comment replace="nothing">Edit</tal:comment> <tal:edit condition="not: isEdit">
<td tal:condition="python: not isEdit and pageInfo['showOnEdit']"> <td tal:define="locked python: contextObj.isLocked(user, page);
<img style="cursor:pointer" editable python: pageInfo['showOnEdit'] and contextObj.mayEdit()">
tal:attributes="onClick python: 'href: window.location=\'%s\'' % contextObj.getUrl(mode='edit', page=page);
title python: _('object_edit'); <tal:comment replace="nothing">Edit</tal:comment>
src string: $appUrl/ui/editBig.png" <a tal:condition="python: editable and not locked"
tal:condition="contextObj/mayEdit"/> tal:attributes="href python: contextObj.getUrl(mode='edit', page=page)">
</td> <img tal:attributes="src string: $appUrl/ui/editBig.png;
title python: _('object_edit')"/>
</a>
<tal:comment replace="nothing">Locked</tal:comment>
<a tal:condition="python: editable and locked">
<img style="cursor: help"
tal:define="lockDate python: tool.formatDate(locked[1]);
lockMsg python: _('page_locked', mapping={'user':tool.getUserName(locked[0]), 'date': lockDate})"
tal:attributes="src string: $appUrl/ui/lockedBig.png; title lockMsg"/>
</a>
</td>
</tal:edit>
<tal:comment replace="nothing">Refresh</tal:comment> <tal:comment replace="nothing">Refresh</tal:comment>
<td tal:condition="contextObj/isDebug"> <td tal:condition="contextObj/isDebug">

View file

@ -116,7 +116,7 @@
<table metal:define-macro="phases" class="portletContent" <table metal:define-macro="phases" class="portletContent"
tal:define="singlePhase python: phases and (len(phases) == 1); tal:define="singlePhase python: phases and (len(phases) == 1);
page python: req.get('page', 'main'); page python: req.get('page', 'main');
mayEdit python: contextObj.allows('Modify portal content')"> mayEdit contextObj/mayEdit">
<tal:phase repeat="phase phases"> <tal:phase repeat="phase phases">
<tal:comment replace="nothing">The box containing phase-related information</tal:comment> <tal:comment replace="nothing">The box containing phase-related information</tal:comment>
<tr tal:define="singlePage python: len(phase['pages']) == 1"> <tr tal:define="singlePage python: len(phase['pages']) == 1">
@ -142,8 +142,9 @@
</a> </a>
<a tal:condition="python: editable and locked"> <a tal:condition="python: editable and locked">
<img style="cursor: help" <img style="cursor: help"
tal:attributes="src string: $appUrl/ui/locked.png; tal:define="lockDate python: tool.formatDate(locked[1]);
title python: _('page_locked', mapping={'user':tool.getUserName(locked)})"/> lockMsg python: _('page_locked', mapping={'user':tool.getUserName(locked[0]), 'date': lockDate})"
tal:attributes="src string: $appUrl/ui/locked.png; title lockMsg"/>
</a> </a>
</tal:icons> </tal:icons>
</div> </div>