[gen] Improved the page lock system.
This commit is contained in:
parent
bdf41adf36
commit
d42dffacad
|
@ -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):
|
||||||
|
|
|
@ -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
BIN
gen/ui/lockedBig.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
|
@ -287,14 +287,25 @@
|
||||||
title python: _('object_cancel')"/>
|
title python: _('object_cancel')"/>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
|
<tal:edit condition="not: isEdit">
|
||||||
|
<td tal:define="locked python: contextObj.isLocked(user, page);
|
||||||
|
editable python: pageInfo['showOnEdit'] and contextObj.mayEdit()">
|
||||||
|
|
||||||
<tal:comment replace="nothing">Edit</tal:comment>
|
<tal:comment replace="nothing">Edit</tal:comment>
|
||||||
<td tal:condition="python: not isEdit and pageInfo['showOnEdit']">
|
<a tal:condition="python: editable and not locked"
|
||||||
<img style="cursor:pointer"
|
tal:attributes="href python: contextObj.getUrl(mode='edit', page=page)">
|
||||||
tal:attributes="onClick python: 'href: window.location=\'%s\'' % contextObj.getUrl(mode='edit', page=page);
|
<img tal:attributes="src string: $appUrl/ui/editBig.png;
|
||||||
title python: _('object_edit');
|
title python: _('object_edit')"/>
|
||||||
src string: $appUrl/ui/editBig.png"
|
</a>
|
||||||
tal:condition="contextObj/mayEdit"/>
|
<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>
|
</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">
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in a new issue