[Checkins] SVN: Products.CMFDefault/trunk/Products/CMFDefault/ - added new `Members` and `Member Area` portal types

Yvo Schubbe cvs-admin at zope.org
Mon Jul 29 15:18:40 CEST 2013


Log message for revision 130278:
  - added new `Members` and `Member Area` portal types
  - added `cmf.memberarea` factory
  - updated importVarious setup handler
  - added upgrade steps and adjusted tests

Changed:
  U   Products.CMFDefault/trunk/Products/CMFDefault/CHANGES.txt
  U   Products.CMFDefault/trunk/Products/CMFDefault/MembershipTool.py
  U   Products.CMFDefault/trunk/Products/CMFDefault/browser/membership/TODO.rst
  U   Products.CMFDefault/trunk/Products/CMFDefault/browser/membership/configure.zcml
  U   Products.CMFDefault/trunk/Products/CMFDefault/content.zcml
  U   Products.CMFDefault/trunk/Products/CMFDefault/exportimport.zcml
  A   Products.CMFDefault/trunk/Products/CMFDefault/profiles/default/types/Member_Area.xml
  A   Products.CMFDefault/trunk/Products/CMFDefault/profiles/default/types/Members.xml
  U   Products.CMFDefault/trunk/Products/CMFDefault/profiles/default/types.xml
  U   Products.CMFDefault/trunk/Products/CMFDefault/profiles/default/workflows.xml
  U   Products.CMFDefault/trunk/Products/CMFDefault/setuphandlers.py
  U   Products.CMFDefault/trunk/Products/CMFDefault/tests/test_MembershipTool.py
  U   Products.CMFDefault/trunk/Products/CMFDefault/tests/test_Portal.py
  U   Products.CMFDefault/trunk/Products/CMFDefault/upgrade/configure.zcml
  U   Products.CMFDefault/trunk/Products/CMFDefault/upgrade/to23.py

-=-
Modified: Products.CMFDefault/trunk/Products/CMFDefault/CHANGES.txt
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/CHANGES.txt	2013-07-29 08:23:50 UTC (rev 130277)
+++ Products.CMFDefault/trunk/Products/CMFDefault/CHANGES.txt	2013-07-29 13:18:39 UTC (rev 130278)
@@ -4,6 +4,15 @@
 2.3.0 (unreleased)
 ------------------
 
+- profiles and upgrade: Added new `Members` and `Member Area` portal types.
+  This allows to customize member area creation and behavior by modifying the
+  special portal types. The 'createMemberContent' hook is deprecated. An
+  additional upgrade step helps to convert the portal type of existing members
+  folder and member areas. If you don't run the two upgrade steps and don't
+  add a `Member Area` portal type, you get backwards compatible behavior.
+
+- content: Added `cmf.memberarea` factory for creating member areas.
+
 - browser views: Synced view names with the names used in type Actions.
 
 - profiles and upgrade: Modified Method Aliases used in type Actions.

Modified: Products.CMFDefault/trunk/Products/CMFDefault/MembershipTool.py
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/MembershipTool.py	2013-07-29 08:23:50 UTC (rev 130277)
+++ Products.CMFDefault/trunk/Products/CMFDefault/MembershipTool.py	2013-07-29 13:18:39 UTC (rev 130278)
@@ -151,6 +151,36 @@
 
 
 @implementer(IFactory)
+class _MemberAreaFactory(object):
+
+    """Creates a member area.
+    """
+
+    title = _(u'Member Area')
+    description = _(u'A home folder for portal members.')
+
+    def __call__(self, id, title=None, *args, **kw):
+        if title is None:
+            title = "{0}'s Home".format(id)
+        item = PortalFolder(id, title, *args, **kw)
+        item.manage_setLocalRoles(id, ['Owner'])
+
+        # Create Member's initial content
+        subitem = Document('index_html', "{0}'s Home".format(id),
+                           "{0}'s front page".format(id),
+                           'structured-text', DEFAULT_MEMBER_CONTENT % id)
+        subitem.manage_setLocalRoles(id, ['Owner'])
+        subitem._setPortalTypeName('Document')
+        item._setObject('index_html', subitem, suppress_events=True)
+        return item
+
+    def getInterfaces(self):
+        return implementedBy(PortalFolder)
+
+MemberAreaFactory = _MemberAreaFactory()
+
+
+ at implementer(IFactory)
 class _BBBMemberAreaFactory(object):
 
     """Creates a member area.

Modified: Products.CMFDefault/trunk/Products/CMFDefault/browser/membership/TODO.rst
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/browser/membership/TODO.rst	2013-07-29 08:23:50 UTC (rev 130277)
+++ Products.CMFDefault/trunk/Products/CMFDefault/browser/membership/TODO.rst	2013-07-29 13:18:39 UTC (rev 130278)
@@ -50,8 +50,8 @@
 - [x] members_delete_control.py -> members.Manage
 - [x] members_delete_template.pt -> members_delete.pt
 
-[x] ISiteRoot @@roster.html:
-----------------------------
+[x] IFolderish @@roster:
+------------------------
 - [x] roster.pt -> members.Roster
                    members_list.pt
 

Modified: Products.CMFDefault/trunk/Products/CMFDefault/browser/membership/configure.zcml
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/browser/membership/configure.zcml	2013-07-29 08:23:50 UTC (rev 130277)
+++ Products.CMFDefault/trunk/Products/CMFDefault/browser/membership/configure.zcml	2013-07-29 13:18:39 UTC (rev 130278)
@@ -83,9 +83,9 @@
       />
 
   <browser:page
-      for="Products.CMFCore.interfaces.ISiteRoot"
+      for="Products.CMFCore.interfaces.IFolderish"
       layer="Products.CMFDefault.interfaces.ICMFDefaultSkin"
-      name="roster.html"
+      name="roster"
       class=".members.Roster"
       template="members_list.pt"
       permission="cmf.ListPortalMembers"

Modified: Products.CMFDefault/trunk/Products/CMFDefault/content.zcml
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/content.zcml	2013-07-29 08:23:50 UTC (rev 130277)
+++ Products.CMFDefault/trunk/Products/CMFDefault/content.zcml	2013-07-29 13:18:39 UTC (rev 130278)
@@ -98,6 +98,11 @@
   <!-- MemberArea -->
 
   <utility
+      component=".MembershipTool.MemberAreaFactory"
+      name="cmf.memberarea"
+      />
+
+  <utility
       component=".MembershipTool.BBBMemberAreaFactory"
       name="cmf.memberarea.bbb2"
       />

Modified: Products.CMFDefault/trunk/Products/CMFDefault/exportimport.zcml
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/exportimport.zcml	2013-07-29 08:23:50 UTC (rev 130277)
+++ Products.CMFDefault/trunk/Products/CMFDefault/exportimport.zcml	2013-07-29 13:18:39 UTC (rev 130278)
@@ -8,7 +8,7 @@
       title="Various Settings"
       description="Import various settings from PortalGenerator."
       handler="Products.CMFDefault.setuphandlers.importVarious">
-    <depends name="toolset"/>
+    <depends name="typeinfo"/>
   </genericsetup:importStep>
 
 </configure>

Copied: Products.CMFDefault/trunk/Products/CMFDefault/profiles/default/types/Member_Area.xml (from rev 130271, Products.CMFDefault/trunk/Products/CMFDefault/profiles/default/types/Folder.xml)
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/profiles/default/types/Member_Area.xml	                        (rev 0)
+++ Products.CMFDefault/trunk/Products/CMFDefault/profiles/default/types/Member_Area.xml	2013-07-29 13:18:39 UTC (rev 130278)
@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+<object name="Member Area" meta_type="Factory-based Type Information"
+   i18n:domain="cmf_default" xmlns:i18n="http://xml.zope.org/namespaces/i18n">
+ <property name="title" i18n:translate="">Member Area</property>
+ <property name="description"
+    i18n:translate="">A home folder for portal members.</property>
+ <property name="icon_expr">string:${portal_url}/folder_icon.gif</property>
+ <property name="content_meta_type">Portal Folder</property>
+ <property name="product"></property>
+ <property name="factory">cmf.memberarea</property>
+ <property
+    name="add_view_expr">string:${folder_url}/++add++Member%20Area</property>
+ <property name="link_target"></property>
+ <property name="immediate_view">properties</property>
+ <property name="global_allow">False</property>
+ <property name="filter_content_types">False</property>
+ <property name="allowed_content_types"/>
+ <property name="allow_discussion">False</property>
+ <alias from="(Default)" to="index_html"/>
+ <alias from="folder_contents" to="@@edit"/>
+ <alias from="index.html" to="index_html"/>
+ <alias from="view" to="index_html"/>
+ <action title="View" action_id="view" category="object" condition_expr=""
+    icon_expr="string:${portal_url}/preview_icon.png" link_target=""
+    url_expr="string:${object_url}" visible="True">
+  <permission value="View"/>
+ </action>
+ <action title="Edit" action_id="edit" category="object" condition_expr=""
+    icon_expr="string:${portal_url}/edit_icon.png" link_target=""
+    url_expr="string:${object_url}/properties" visible="True">
+  <permission value="Manage properties"/>
+ </action>
+ <action title="Local Roles" action_id="localroles" category="object"
+    condition_expr="" icon_expr="string:${portal_url}/localroles_icon.png"
+    link_target="" url_expr="string:${object_url}/share" visible="True">
+  <permission value="Change local roles"/>
+ </action>
+ <action title="Folder contents" action_id="folderContents" category="object"
+    condition_expr="" icon_expr="string:${portal_url}/folder_icon.png"
+    link_target="" url_expr="string:${object_url}/folder_contents"
+    visible="True">
+  <permission value="List folder contents"/>
+ </action>
+</object>

Copied: Products.CMFDefault/trunk/Products/CMFDefault/profiles/default/types/Members.xml (from rev 130271, Products.CMFDefault/trunk/Products/CMFDefault/profiles/default/types/Folder.xml)
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/profiles/default/types/Members.xml	                        (rev 0)
+++ Products.CMFDefault/trunk/Products/CMFDefault/profiles/default/types/Members.xml	2013-07-29 13:18:39 UTC (rev 130278)
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<object name="Members" meta_type="Factory-based Type Information"
+   i18n:domain="cmf_default" xmlns:i18n="http://xml.zope.org/namespaces/i18n">
+ <property name="title" i18n:translate="">Members</property>
+ <property name="description"
+    i18n:translate="">A container for member areas.</property>
+ <property name="icon_expr">string:${portal_url}/folder_icon.gif</property>
+ <property name="content_meta_type">Portal Folder</property>
+ <property name="product"></property>
+ <property name="factory">cmf.folder</property>
+ <property name="add_view_expr">string:${folder_url}/++add++Members</property>
+ <property name="link_target"></property>
+ <property name="immediate_view">properties</property>
+ <property name="global_allow">False</property>
+ <property name="filter_content_types">True</property>
+ <property name="allowed_content_types">
+  <element value="Member Area"/>
+ </property>
+ <property name="allow_discussion">False</property>
+ <alias from="(Default)" to="@@roster"/>
+ <alias from="folder_contents" to="@@edit"/>
+ <alias from="index.html" to="@@roster"/>
+ <alias from="view" to="@@roster"/>
+ <action title="View" action_id="view" category="object" condition_expr=""
+    icon_expr="string:${portal_url}/preview_icon.png" link_target=""
+    url_expr="string:${object_url}" visible="True">
+  <permission value="View"/>
+ </action>
+ <action title="Edit" action_id="edit" category="object" condition_expr=""
+    icon_expr="string:${portal_url}/edit_icon.png" link_target=""
+    url_expr="string:${object_url}/properties" visible="True">
+  <permission value="Manage properties"/>
+ </action>
+ <action title="Local Roles" action_id="localroles" category="object"
+    condition_expr="" icon_expr="string:${portal_url}/localroles_icon.png"
+    link_target="" url_expr="string:${object_url}/share" visible="True">
+  <permission value="Change local roles"/>
+ </action>
+ <action title="Folder contents" action_id="folderContents" category="object"
+    condition_expr="" icon_expr="string:${portal_url}/folder_icon.png"
+    link_target="" url_expr="string:${object_url}/folder_contents"
+    visible="True">
+  <permission value="List folder contents"/>
+ </action>
+</object>

Modified: Products.CMFDefault/trunk/Products/CMFDefault/profiles/default/types.xml
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/profiles/default/types.xml	2013-07-29 08:23:50 UTC (rev 130277)
+++ Products.CMFDefault/trunk/Products/CMFDefault/profiles/default/types.xml	2013-07-29 13:18:39 UTC (rev 130278)
@@ -9,5 +9,7 @@
  <object name="Folder" meta_type="Factory-based Type Information"/>
  <object name="Image" meta_type="Factory-based Type Information"/>
  <object name="Link" meta_type="Factory-based Type Information"/>
+ <object name="Member Area" meta_type="Factory-based Type Information"/>
+ <object name="Members" meta_type="Factory-based Type Information"/>
  <object name="News Item" meta_type="Factory-based Type Information"/>
 </object>

Modified: Products.CMFDefault/trunk/Products/CMFDefault/profiles/default/workflows.xml
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/profiles/default/workflows.xml	2013-07-29 08:23:50 UTC (rev 130277)
+++ Products.CMFDefault/trunk/Products/CMFDefault/profiles/default/workflows.xml	2013-07-29 13:18:39 UTC (rev 130278)
@@ -12,5 +12,7 @@
    <bound-workflow workflow_id="singlestate_workflow"/>
   </type>
   <type type_id="Folder"/>
+  <type type_id="Member Area"/>
+  <type type_id="Members"/>
  </bindings>
 </object>

Modified: Products.CMFDefault/trunk/Products/CMFDefault/setuphandlers.py
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/setuphandlers.py	2013-07-29 08:23:50 UTC (rev 130277)
+++ Products.CMFDefault/trunk/Products/CMFDefault/setuphandlers.py	2013-07-29 13:18:39 UTC (rev 130278)
@@ -13,10 +13,12 @@
 """ CMFDefault setup handlers.
 """
 
-from Products.CMFDefault.exceptions import BadRequest
-from OFS.DTMLMethod import addDTMLMethod
+from zope.component import getUtility
+from zope.component.interfaces import IFactory
 
+from Products.CMFCore.interfaces import ITypesTool
 
+
 def importVarious(context):
     """ Import various settings.
 
@@ -32,13 +34,13 @@
 
     site = context.getSite()
 
-    try:
-        site.manage_addPortalFolder('Members')
-        addDTMLMethod(site.Members,
-                      'index_html', 'Member list', '<dtml-return roster>')
-        logger.info('Members folder imported.')
-    except BadRequest:
-        logger.warning('Importing Members folder failed.')
+    ttool = getUtility(ITypesTool)
+    portal_type = ttool.getTypeInfo('Members')
+    factory = getUtility(IFactory, portal_type.factory)
+    obj = factory(id='Members')
+    obj._setPortalTypeName('Members')
+    site._setObject('Members', obj)
+    logger.info('Members folder imported.')
 
     site.acl_users.encrypt_passwords = False
     logger.info('Password encryption disabled.')

Modified: Products.CMFDefault/trunk/Products/CMFDefault/tests/test_MembershipTool.py
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/tests/test_MembershipTool.py	2013-07-29 08:23:50 UTC (rev 130277)
+++ Products.CMFDefault/trunk/Products/CMFDefault/tests/test_MembershipTool.py	2013-07-29 13:18:39 UTC (rev 130278)
@@ -27,17 +27,27 @@
 from zope.interface.verify import verifyClass
 from zope.testing.cleanup import cleanUp
 
+from Products.CMFCore.interfaces import ITypesTool
 from Products.CMFCore.interfaces import IWorkflowTool
 from Products.CMFCore.PortalFolder import PortalFolder
 from Products.CMFCore.testing import EventZCMLLayer
 from Products.CMFCore.tests.base.dummy import DummyFolder
 from Products.CMFCore.tests.base.dummy import DummySite
 from Products.CMFCore.tests.base.dummy import DummyTool
+from Products.CMFCore.tests.base.dummy import DummyType
 from Products.CMFCore.tests.base.dummy import DummyUserFolder
 from Products.CMFCore.tests.base.testcase import SecurityTest
 from Products.CMFCore.tests.base.testcase import TransactionalTest
 
 
+class DummyTool(DummyTool):
+
+    def getTypeInfo(self, contentType):
+        ti = DummyType('Member Area')
+        ti.factory = 'cmf.memberarea'
+        return ti
+
+
 class MembershipToolTests(TransactionalTest):
 
     def _makeOne(self, *args, **kw):
@@ -120,6 +130,62 @@
 
     def test_createMemberArea(self):
         from Products.CMFDefault.interfaces import IMembershipTool
+        from Products.CMFDefault.MembershipTool import MemberAreaFactory
+
+        mtool = self.site.portal_membership
+        members = self.site._setObject('Members', PortalFolder('Members'))
+        acl_users = self.site._setObject('acl_users', DummyUserFolder())
+        ttool = DummyTool()
+        wtool = DummyTool()
+        sm = getSiteManager()
+        sm.registerUtility(mtool, IMembershipTool)
+        sm.registerUtility(ttool, ITypesTool)
+        sm.registerUtility(wtool, IWorkflowTool)
+        sm.registerUtility(MemberAreaFactory, IFactory, 'cmf.memberarea')
+
+        # permission
+        mtool.createMemberArea('user_foo')
+        self.assertFalse(hasattr(members.aq_self, 'user_foo'))
+        newSecurityManager(None, acl_users.user_bar)
+        mtool.createMemberArea('user_foo')
+        self.assertFalse(hasattr(members.aq_self, 'user_foo'))
+        newSecurityManager(None, acl_users.user_foo)
+        mtool.setMemberareaCreationFlag()
+        mtool.createMemberArea('user_foo')
+        self.assertFalse(hasattr(members.aq_self, 'user_foo'))
+        newSecurityManager(None, acl_users.all_powerful_Oz)
+        mtool.setMemberareaCreationFlag()
+        mtool.createMemberArea('user_foo')
+        self.assertTrue(hasattr(members.aq_self, 'user_foo'))
+
+        # default content
+        f = members.user_foo
+        ownership = acl_users.user_foo
+        localroles = (('user_foo', ('Owner',)),)
+        self.assertEqual(f.Title(), "user_foo's Home")
+        self.assertEqual(f.getPortalTypeName(), 'Member Area')
+        self.assertEqual(f.getOwner(), ownership)
+        self.assertEqual(f.get_local_roles(), localroles,
+                         'CMF Collector issue #162 (LocalRoles broken): %s'
+                         % str(f.get_local_roles()))
+        self.assertEqual(f.index_html.getPortalTypeName(), 'Document')
+        self.assertEqual(f.index_html.getOwner(), ownership,
+                         'CMF Collector issue #162 (Ownership broken): %s'
+                         % str(f.index_html.getOwner()))
+        self.assertEqual(f.index_html.get_local_roles(), localroles,
+                         'CMF Collector issue #162 (LocalRoles broken): %s'
+                         % str(f.index_html.get_local_roles()))
+        self.assertEqual(wtool.test_notified, f.index_html)
+
+        # acquisition
+        self.site.user_bar = 'test attribute'
+        newSecurityManager(None, acl_users.user_bar)
+        mtool.createMemberArea('user_bar')
+        self.assertTrue(hasattr(members.aq_self, 'user_bar'),
+                        'CMF Collector issue #102 (acquisition bug)')
+
+    def test_createMemberArea_BBB(self):
+        from Products.CMFDefault.interfaces import IMembershipTool
         from Products.CMFDefault.MembershipTool import BBBMemberAreaFactory
 
         mtool = self.site.portal_membership

Modified: Products.CMFDefault/trunk/Products/CMFDefault/tests/test_Portal.py
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/tests/test_Portal.py	2013-07-29 08:23:50 UTC (rev 130277)
+++ Products.CMFDefault/trunk/Products/CMFDefault/tests/test_Portal.py	2013-07-29 13:18:39 UTC (rev 130278)
@@ -62,11 +62,12 @@
             uidtool = None
 
         portal_types = [ x for x in ttool.listContentTypes()
-                           if x not in ( 'Discussion Item'
-                                       , 'CMF BTree Folder'
-                                       , 'Folder'
-                                       , 'Topic'
-                                       ) ]
+                           if x not in ('Discussion Item',
+                                        'CMF BTree Folder',
+                                        'Folder',
+                                        'Member Area',
+                                        'Members',
+                                        'Topic') ]
 
         self.assertEqual( len( catalog ), 0 )
 

Modified: Products.CMFDefault/trunk/Products/CMFDefault/upgrade/configure.zcml
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/upgrade/configure.zcml	2013-07-29 08:23:50 UTC (rev 130277)
+++ Products.CMFDefault/trunk/Products/CMFDefault/upgrade/configure.zcml	2013-07-29 13:18:39 UTC (rev 130278)
@@ -253,6 +253,20 @@
         checker=".to23.check_type_infos"
         />
 
+    <genericsetup:upgradeStep
+        title="Add new portal types"
+        description="Add 'Members' and 'Member Area' portal types."
+        handler=".to23.upgrade_portal_types"
+        checker=".to23.check_portal_types"
+        />
+
+    <genericsetup:upgradeStep
+        title="Upgrade member areas"
+        description="Convert portal type of members folder and member areas."
+        handler=".to23.upgrade_member_areas"
+        checker=".to23.check_member_areas"
+        />
+
   </genericsetup:upgradeSteps>
 
   <genericsetup:upgradeStep

Modified: Products.CMFDefault/trunk/Products/CMFDefault/upgrade/to23.py
===================================================================
--- Products.CMFDefault/trunk/Products/CMFDefault/upgrade/to23.py	2013-07-29 08:23:50 UTC (rev 130277)
+++ Products.CMFDefault/trunk/Products/CMFDefault/upgrade/to23.py	2013-07-29 13:18:39 UTC (rev 130278)
@@ -23,6 +23,7 @@
 from zope.component.interfaces import ComponentLookupError
 from zope.dottedname.resolve import resolve
 
+from Products.CMFCore.TypesTool import FactoryTypeInformation
 from Products.CMFCore.utils import getToolByName
 from Products.GenericSetup.context import SetupEnviron
 from Products.GenericSetup.interfaces import IBody
@@ -552,3 +553,204 @@
 
         if changed:
             logger.info("TypeInfo '%s' changed." % ti.getId())
+
+def check_portal_types(tool):
+    """2.2.x to 2.3.0 upgrade step checker
+    """
+    ttool = getToolByName(tool, 'portal_types')
+    try:
+        ttool['Member Area']
+    except KeyError:
+        return True
+    try:
+        ttool['Members']
+    except KeyError:
+        return True
+    return False
+
+def upgrade_portal_types(tool):
+    """2.2.x to 2.3.0 upgrade step handler
+    """
+    logger = logging.getLogger('GenericSetup.upgrade')
+    ttool = getToolByName(tool, 'portal_types')
+    wtool = getToolByName(tool, 'portal_workflow')
+    environ = SetupEnviron()
+    environ._should_purge = False
+    try:
+        ttool['Member Area']
+    except KeyError:
+        getMultiAdapter((ttool, environ), IBody).body = _TTOOL_MEMBER_AREA_XML
+        obj = ttool['Member Area']
+        getMultiAdapter((obj, environ), IBody).body = _MEMBER_AREA_XML
+        getMultiAdapter((wtool, environ), IBody).body = _WTOOL_MEMBER_AREA_XML
+        logger.info("'Member Area' type added.")
+    try:
+        ttool['Members']
+    except KeyError:
+        getMultiAdapter((ttool, environ), IBody).body = _TTOOL_MEMBERS_XML
+        obj = ttool['Members']
+        getMultiAdapter((obj, environ), IBody).body = _MEMBERS_XML
+        getMultiAdapter((wtool, environ), IBody).body = _WTOOL_MEMBERS_XML
+        logger.info("'Members' type added.")
+
+_TTOOL_MEMBER_AREA_XML = """\
+<?xml version="1.0"?>
+<object name="portal_types">
+ <object insert-after="Link" name="Member Area"
+    meta_type="Factory-based Type Information"/>
+</object>
+"""
+
+_MEMBER_AREA_XML = """\
+<?xml version="1.0"?>
+<object name="Member Area" meta_type="Factory-based Type Information"
+   i18n:domain="cmf_default" xmlns:i18n="http://xml.zope.org/namespaces/i18n">
+ <property name="title" i18n:translate="">Member Area</property>
+ <property name="description"
+    i18n:translate="">A home folder for portal members.</property>
+ <property name="icon_expr">string:${portal_url}/folder_icon.gif</property>
+ <property name="content_meta_type">Portal Folder</property>
+ <property name="product"></property>
+ <property name="factory">cmf.memberarea</property>
+ <property
+    name="add_view_expr">string:${folder_url}/++add++Member%20Area</property>
+ <property name="link_target"></property>
+ <property name="immediate_view">properties</property>
+ <property name="global_allow">False</property>
+ <property name="filter_content_types">False</property>
+ <property name="allowed_content_types"/>
+ <property name="allow_discussion">False</property>
+ <alias from="(Default)" to="index_html"/>
+ <alias from="folder_contents" to="@@edit"/>
+ <alias from="index.html" to="index_html"/>
+ <alias from="view" to="index_html"/>
+ <action title="View" action_id="view" category="object" condition_expr=""
+    icon_expr="string:${portal_url}/preview_icon.png" link_target=""
+    url_expr="string:${object_url}" visible="True">
+  <permission value="View"/>
+ </action>
+ <action title="Edit" action_id="edit" category="object" condition_expr=""
+    icon_expr="string:${portal_url}/edit_icon.png" link_target=""
+    url_expr="string:${object_url}/properties" visible="True">
+  <permission value="Manage properties"/>
+ </action>
+ <action title="Local Roles" action_id="localroles" category="object"
+    condition_expr="" icon_expr="string:${portal_url}/localroles_icon.png"
+    link_target="" url_expr="string:${object_url}/share" visible="True">
+  <permission value="Change local roles"/>
+ </action>
+ <action title="Folder contents" action_id="folderContents" category="object"
+    condition_expr="" icon_expr="string:${portal_url}/folder_icon.png"
+    link_target="" url_expr="string:${object_url}/folder_contents"
+    visible="True">
+  <permission value="List folder contents"/>
+ </action>
+</object>
+"""
+
+_TTOOL_MEMBERS_XML = """\
+<?xml version="1.0"?>
+<object name="portal_types">
+ <object insert-after="Member Area" name="Members"
+    meta_type="Factory-based Type Information"/>
+</object>
+"""
+
+_MEMBERS_XML = """\
+<?xml version="1.0"?>
+<object name="Members" meta_type="Factory-based Type Information"
+   i18n:domain="cmf_default" xmlns:i18n="http://xml.zope.org/namespaces/i18n">
+ <property name="title" i18n:translate="">Members</property>
+ <property name="description"
+    i18n:translate="">A container for member areas.</property>
+ <property name="icon_expr">string:${portal_url}/folder_icon.gif</property>
+ <property name="content_meta_type">Portal Folder</property>
+ <property name="product"></property>
+ <property name="factory">cmf.folder</property>
+ <property name="add_view_expr">string:${folder_url}/++add++Members</property>
+ <property name="link_target"></property>
+ <property name="immediate_view">properties</property>
+ <property name="global_allow">False</property>
+ <property name="filter_content_types">True</property>
+ <property name="allowed_content_types">
+  <element value="Member Area"/>
+ </property>
+ <property name="allow_discussion">False</property>
+ <alias from="(Default)" to="@@roster"/>
+ <alias from="folder_contents" to="@@edit"/>
+ <alias from="index.html" to="@@roster"/>
+ <alias from="view" to="@@roster"/>
+ <action title="View" action_id="view" category="object" condition_expr=""
+    icon_expr="string:${portal_url}/preview_icon.png" link_target=""
+    url_expr="string:${object_url}" visible="True">
+  <permission value="View"/>
+ </action>
+ <action title="Edit" action_id="edit" category="object" condition_expr=""
+    icon_expr="string:${portal_url}/edit_icon.png" link_target=""
+    url_expr="string:${object_url}/properties" visible="True">
+  <permission value="Manage properties"/>
+ </action>
+ <action title="Local Roles" action_id="localroles" category="object"
+    condition_expr="" icon_expr="string:${portal_url}/localroles_icon.png"
+    link_target="" url_expr="string:${object_url}/share" visible="True">
+  <permission value="Change local roles"/>
+ </action>
+ <action title="Folder contents" action_id="folderContents" category="object"
+    condition_expr="" icon_expr="string:${portal_url}/folder_icon.png"
+    link_target="" url_expr="string:${object_url}/folder_contents"
+    visible="True">
+  <permission value="List folder contents"/>
+ </action>
+</object>
+"""
+
+_WTOOL_MEMBER_AREA_XML = """\
+<?xml version="1.0"?>
+<object name="portal_workflow">
+ <bindings>
+  <type type_id="Member Area"/>
+ </bindings>
+</object>
+"""
+
+_WTOOL_MEMBERS_XML = """\
+<?xml version="1.0"?>
+<object name="portal_workflow">
+ <bindings>
+  <type type_id="Members"/>
+ </bindings>
+</object>
+"""
+
+def check_member_areas(tool):
+    """2.2.x to 2.3.0 upgrade step checker
+    """
+    mtool = getToolByName(tool, 'portal_membership')
+    members = mtool.getMembersFolder()
+    if 'index_html' in members:
+        if members['index_html'].meta_type == 'DTML Method':
+            return True
+    if members.getPortalTypeName() != 'Members':
+        return True
+    for f in members.objectValues('Portal Folder'):
+        if f.getPortalTypeName() != 'Member Area':
+            return True
+    return False
+
+def upgrade_member_areas(tool):
+    """2.2.x to 2.3.0 upgrade step handler
+    """
+    logger = logging.getLogger('GenericSetup.upgrade')
+    mtool = getToolByName(tool, 'portal_membership')
+    members = mtool.getMembersFolder()
+    if 'index_html' in members:
+        if members['index_html'].meta_type == 'DTML Method':
+            members._delObject('index_html')
+            logger.info("'index_html' method removed from members.")
+    if members.getPortalTypeName() != 'Members':
+        members._setPortalTypeName('Members')
+        logger.info("Portal type of '{0}' fixed.".format(members.getId()))
+    for f in members.objectValues('Portal Folder'):
+        if f.getPortalTypeName() != 'Member Area':
+            f._setPortalTypeName('Member Area')
+            logger.info("Portal type of '{0}' fixed.".format(f.getId()))



More information about the checkins mailing list