Plone:通知用户删除他的帐户
Plone: Notify a user on deleting his account
在 IPrincipalDeletedEvent 上使用订阅者不是解决方案,因为该用户已被删除,我无法获取他的电子邮件地址。
<subscriber
for="* Products.PluggableAuthService.interfaces.events.IPrincipalDeletedEvent"
handler="mycontent.userDeleted" />
https://github.com/plone/Products.PlonePAS/blob/4.2/Products/PlonePAS/pas.py#L78
当调用我的 userDeleted(user_id, event)
时,api.user.get(userid=user_id)
是 None。
似乎为删除的用户添加内容规则是一样的。
知道如何在用户的帐户被标记为删除时获取用户的电子邮件地址吗?我只想给他发一封电子邮件:你的帐户已按你的要求删除。
Monkey 修补以在删除用户之前添加一个事件:
在patches.zcml
中:
<configure xmlns="http://namespaces.zope.org/zope"
xmlns:monkey="http://namespaces.plone.org/monkey"
xmlns:zcml="http://namespaces.zope.org/zcml"
i18n_domain="myapp">
<include package="collective.monkeypatcher" />
<include package="collective.monkeypatcher" file="meta.zcml" />
<monkey:patch description="Add PrincipalBeforeDeleted event"
class="Products.PlonePAS.pas"
original="_doDelUser"
replacement="mycontent.patches._doDelUser"
docstringWarning="true" />
</configure>
在patches.py
中:
from zope.event import notify
from Products.PluggableAuthService.events import PrincipalDeleted
from Products.PlonePAS.interfaces.plugins import IUserManagement
from Products.PluggableAuthService.PluggableAuthService import \
_SWALLOWABLE_PLUGIN_EXCEPTIONS
from Products.PluggableAuthService.PluggableAuthService import \
PluggableAuthService
from Products.PlonePAS.pas import _doDelUser
from Products.PluggableAuthService.interfaces.events import IPASEvent
from zope.interface import implements
from Products.PluggableAuthService.events import PASEvent
class IPrincipalBeforeDeletedEvent(IPASEvent):
"""A user is marked to be removed but still into database.
"""
class PrincipalBeforeDeleted(PASEvent):
implements(IPrincipalBeforeDeletedEvent)
def _doDelUser(self, id):
"""
Given a user id, hand off to a deleter plugin if available.
Fix: Add PrincipalBeforeDeleted notification
"""
plugins = self._getOb('plugins')
userdeleters = plugins.listPlugins(IUserManagement)
if not userdeleters:
raise NotImplementedError(
"There is no plugin that can delete users.")
for userdeleter_id, userdeleter in userdeleters:
# vvv Custom
notify(PrincipalBeforeDeleted(id))
# ^^^ Custom
try:
userdeleter.doDeleteUser(id)
except _SWALLOWABLE_PLUGIN_EXCEPTIONS:
pass
else:
notify(PrincipalDeleted(id))
PluggableAuthService._doDelUser = _doDelUser
然后添加了此事件的订阅者:
在configure.zcml
中:
<subscriber
for="* mycontent.patches.IPrincipalBeforeDeletedEvent"
handler="mycontent.globalhandlers.userBeforeDeleted" />
在globalhandlers.py
中:
from Products.CMFCore.utils import getToolByName
def handleEventFail(func):
def wrapper(*args, **kwargs):
try:
func(*args, **kwargs)
except Exception:
logger.exception('in {0}'.format(func.__name__))
return wrapper
@handleEventFail
def userBeforeDeleted(user_id, event):
""" Notify deleted user about this action. """
membership_tool = getToolByName(api.portal.get(), 'portal_membership')
user = membership_tool.getMemberById(user_id)
email = user.getProperty('email')
mail_text = """
Hi!
Your account ({0}) was deleted.
Best regards,
Our Best Team""".format(user_id)
print mail_text
print email
# TODO send mail
在 IPrincipalDeletedEvent 上使用订阅者不是解决方案,因为该用户已被删除,我无法获取他的电子邮件地址。
<subscriber
for="* Products.PluggableAuthService.interfaces.events.IPrincipalDeletedEvent"
handler="mycontent.userDeleted" />
https://github.com/plone/Products.PlonePAS/blob/4.2/Products/PlonePAS/pas.py#L78
当调用我的userDeleted(user_id, event)
时,api.user.get(userid=user_id)
是 None。
似乎为删除的用户添加内容规则是一样的。
知道如何在用户的帐户被标记为删除时获取用户的电子邮件地址吗?我只想给他发一封电子邮件:你的帐户已按你的要求删除。
Monkey 修补以在删除用户之前添加一个事件:
在patches.zcml
中:
<configure xmlns="http://namespaces.zope.org/zope"
xmlns:monkey="http://namespaces.plone.org/monkey"
xmlns:zcml="http://namespaces.zope.org/zcml"
i18n_domain="myapp">
<include package="collective.monkeypatcher" />
<include package="collective.monkeypatcher" file="meta.zcml" />
<monkey:patch description="Add PrincipalBeforeDeleted event"
class="Products.PlonePAS.pas"
original="_doDelUser"
replacement="mycontent.patches._doDelUser"
docstringWarning="true" />
</configure>
在patches.py
中:
from zope.event import notify
from Products.PluggableAuthService.events import PrincipalDeleted
from Products.PlonePAS.interfaces.plugins import IUserManagement
from Products.PluggableAuthService.PluggableAuthService import \
_SWALLOWABLE_PLUGIN_EXCEPTIONS
from Products.PluggableAuthService.PluggableAuthService import \
PluggableAuthService
from Products.PlonePAS.pas import _doDelUser
from Products.PluggableAuthService.interfaces.events import IPASEvent
from zope.interface import implements
from Products.PluggableAuthService.events import PASEvent
class IPrincipalBeforeDeletedEvent(IPASEvent):
"""A user is marked to be removed but still into database.
"""
class PrincipalBeforeDeleted(PASEvent):
implements(IPrincipalBeforeDeletedEvent)
def _doDelUser(self, id):
"""
Given a user id, hand off to a deleter plugin if available.
Fix: Add PrincipalBeforeDeleted notification
"""
plugins = self._getOb('plugins')
userdeleters = plugins.listPlugins(IUserManagement)
if not userdeleters:
raise NotImplementedError(
"There is no plugin that can delete users.")
for userdeleter_id, userdeleter in userdeleters:
# vvv Custom
notify(PrincipalBeforeDeleted(id))
# ^^^ Custom
try:
userdeleter.doDeleteUser(id)
except _SWALLOWABLE_PLUGIN_EXCEPTIONS:
pass
else:
notify(PrincipalDeleted(id))
PluggableAuthService._doDelUser = _doDelUser
然后添加了此事件的订阅者:
在configure.zcml
中:
<subscriber
for="* mycontent.patches.IPrincipalBeforeDeletedEvent"
handler="mycontent.globalhandlers.userBeforeDeleted" />
在globalhandlers.py
中:
from Products.CMFCore.utils import getToolByName
def handleEventFail(func):
def wrapper(*args, **kwargs):
try:
func(*args, **kwargs)
except Exception:
logger.exception('in {0}'.format(func.__name__))
return wrapper
@handleEventFail
def userBeforeDeleted(user_id, event):
""" Notify deleted user about this action. """
membership_tool = getToolByName(api.portal.get(), 'portal_membership')
user = membership_tool.getMemberById(user_id)
email = user.getProperty('email')
mail_text = """
Hi!
Your account ({0}) was deleted.
Best regards,
Our Best Team""".format(user_id)
print mail_text
print email
# TODO send mail