Commit b30d9285 authored by Arnaud Fontaine's avatar Arnaud Fontaine

WIP: Portal Type as Classes: ERP5Form: Instances of Documents should never be created directly.

This has been banned since the introduction of Portal Type class. When creating
a new ERP5Form via addERP5Form/ZMI, its MRO:
  * Before:
    <class 'Products.ERP5Form.Form.ERP5Form'>
    <class 'Products.ERP5Type.Base.Base'>
    ...
    <type 'ExtensionClass.Base'>
  * Now:
    <class 'erp5.portal_type.ERP5 Form'>,
    <class 'Products.ERP5Form.Form.ERP5Form'>,
    <class 'Products.ERP5Type.Base.Base'>,
    ...
    <class 'erp5.accessor_holder.property_sheet.SimpleItem'>
    <class 'erp5.accessor_holder.property_sheet.Folder'>
    <class 'erp5.accessor_holder.property_sheet.Base'>
    <class 'erp5.accessor_holder.property_sheet.CategoryCore'>
    <class 'erp5.accessor_holder.BaseAccessorHolder'>
    <class 'Products.ERP5Type.dynamic.portal_type_class.GetAcquireLocalRolesMixIn'>
    <type 'ExtensionClass.Base'>

Thus it was missing many accessors and was working only by chance (or at least
unless these accessors were not called until the object was automatically migrated
by the next call to __setstate__). Namely, as `providesI*` accessors are now in
BaseAccessorHolder rather than Base due to ZODB Components, this breaks reindexing
(`AttributeError: providesIPredicate`).

Also, remove hardcoded _getAcquireLocalRoles() now that it is not used as a regular
class anymore. Set this on the portal type object instead.

TODO: Add commit IDs of:
  * ZODB Components: providesIFoo() getters were only created for FS Interfaces.
  * erp5_certificate_authority: Certificate Authortiy Tool: All ERP5 objects *must* have have a Portal Type in Types Tool.
parent d1701eb4
...@@ -33,7 +33,6 @@ from AccessControl import ClassSecurityInfo ...@@ -33,7 +33,6 @@ from AccessControl import ClassSecurityInfo
from Products.ERP5Type.Cache import CachingMethod from Products.ERP5Type.Cache import CachingMethod
from Products.ERP5Type import Permissions, PropertySheet from Products.ERP5Type import Permissions, PropertySheet
from Products.ERP5Type.ERP5Type import ERP5TypeInformation from Products.ERP5Type.ERP5Type import ERP5TypeInformation
from Products.ERP5Form.Form import ERP5Form
from Products.ERP5Form.PDFForm import PDFForm from Products.ERP5Form.PDFForm import PDFForm
from Products.ERP5Form.ScribusParser import ScribusParser from Products.ERP5Form.ScribusParser import ScribusParser
from Products.ERP5Form.PDFParser import PDFParser from Products.ERP5Form.PDFParser import PDFParser
...@@ -444,7 +443,10 @@ class PDFTypeInformation(ERP5TypeInformation): ...@@ -444,7 +443,10 @@ class PDFTypeInformation(ERP5TypeInformation):
def generateERP5Form(): def generateERP5Form():
form_name = "view" form_name = "view"
form = ERP5Form(form_name, self.getId()) form = self.newContent(temp_object=True,
portal_type='ERP5 Form',
id=form_name,
title=self.getId())
parsed_scribus = self._getParsedScribusFile() parsed_scribus = self._getParsedScribusFile()
pages = range(len(parsed_scribus)) pages = range(len(parsed_scribus))
#get the context for default values #get the context for default values
...@@ -546,7 +548,7 @@ class PDFTypeInformation(ERP5TypeInformation): ...@@ -546,7 +548,7 @@ class PDFTypeInformation(ERP5TypeInformation):
# ('PDFTypeInformation_generateERP5Form', # ('PDFTypeInformation_generateERP5Form',
# md5(self.getDefaultScribusFormValue().getData()).digest()), # md5(self.getDefaultScribusFormValue().getData()).digest()),
# cache_factory='dms_cache_factory') # cache_factory='dms_cache_factory')
return generateERP5Form().__of__(self) return generateERP5Form()
# XXX criticize Image Document # XXX criticize Image Document
# (we are forced to use xlarge preference) # (we are forced to use xlarge preference)
......
...@@ -6,6 +6,10 @@ ...@@ -6,6 +6,10 @@
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item>
<key> <string>acquire_local_roles</string> </key>
<value> <int>1</int> </value>
</item>
<item> <item>
<key> <string>content_icon</string> </key> <key> <string>content_icon</string> </key>
<value> <string>folder_icon.gif</string> </value> <value> <string>folder_icon.gif</string> </value>
......
...@@ -30,7 +30,6 @@ import unittest ...@@ -30,7 +30,6 @@ import unittest
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from AccessControl.SecurityManagement import newSecurityManager from AccessControl.SecurityManagement import newSecurityManager
from Products.ERP5Form.Form import ERP5Form
class TestICal(ERP5TypeTestCase): class TestICal(ERP5TypeTestCase):
...@@ -229,8 +228,7 @@ class TestICal(ERP5TypeTestCase): ...@@ -229,8 +228,7 @@ class TestICal(ERP5TypeTestCase):
self.request.set('portal_skin', 'iCal'); self.request.set('portal_skin', 'iCal');
self.portal.portal_skins.changeSkin('iCal'); self.portal.portal_skins.changeSkin('iCal');
self.portal._setObject('Test_view', self.portal.manage_addProduct['ERP5Form'].addERP5Form('Test_view', 'View')
ERP5Form('Test_view', 'View'))
self.portal.Test_view.manage_addField('listbox', 'listbox', 'ListBox') self.portal.Test_view.manage_addField('listbox', 'listbox', 'ListBox')
listbox=self.portal.Test_view.listbox listbox=self.portal.Test_view.listbox
......
...@@ -30,7 +30,6 @@ import unittest ...@@ -30,7 +30,6 @@ import unittest
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from AccessControl.SecurityManagement import newSecurityManager from AccessControl.SecurityManagement import newSecurityManager
from Products.ERP5Form.Form import ERP5Form
from xml.dom.minidom import parseString from xml.dom.minidom import parseString
...@@ -150,8 +149,7 @@ class TestRSS(ERP5TypeTestCase): ...@@ -150,8 +149,7 @@ class TestRSS(ERP5TypeTestCase):
request.set('portal_skin', 'RSS'); request.set('portal_skin', 'RSS');
portal.portal_skins.changeSkin('RSS'); portal.portal_skins.changeSkin('RSS');
self.getPortal()._setObject('Test_view', self.getPortal().manage_addProduct['ERP5Form'].addERP5Form('Test_view', 'View')
ERP5Form('Test_view', 'View'))
portal.Test_view.manage_addField('listbox', 'listbox', 'ListBox') portal.Test_view.manage_addField('listbox', 'listbox', 'ListBox')
portal.Test_view.manage_addField('listbox_link', 'listbox_link', 'StringField') portal.Test_view.manage_addField('listbox_link', 'listbox_link', 'StringField')
......
...@@ -31,7 +31,6 @@ from Products.Formulator.TALESField import TALESMethod ...@@ -31,7 +31,6 @@ from Products.Formulator.TALESField import TALESMethod
from Products.CMFCore.utils import getToolByName from Products.CMFCore.utils import getToolByName
from Products.ERP5Type.Message import translateString as translateStringAsMessage from Products.ERP5Type.Message import translateString as translateStringAsMessage
from Products.ERP5Form.Form import ERP5Form
from Products.ERP5Form.ListBox import ListBoxListRenderer from Products.ERP5Form.ListBox import ListBoxListRenderer
def translateString(*args, **kw): def translateString(*args, **kw):
...@@ -49,7 +48,10 @@ def getSearchDialog(self, REQUEST=None): ...@@ -49,7 +48,10 @@ def getSearchDialog(self, REQUEST=None):
default_view = self.getTypeInfo().getDefaultViewFor(self) default_view = self.getTypeInfo().getDefaultViewFor(self)
listbox = default_view.listbox listbox = default_view.listbox
temp_form = ERP5Form('Folder_viewSearchDialog', 'Search').__of__(portal).__of__(self) temp_form = self.newContent(temp_object=True,
portal_type='ERP5 Form',
id='Folder_viewSearchDialog',
title='Search')
temp_form.pt = 'form_dialog' temp_form.pt = 'form_dialog'
temp_form.action = 'Folder_search' temp_form.action = 'Folder_search'
......
...@@ -33,7 +33,11 @@ class ERP5FSForm(FSObject, ERP5Form): ...@@ -33,7 +33,11 @@ class ERP5FSForm(FSObject, ERP5Form):
def _createZODBClone(self): def _createZODBClone(self):
"""Create a ZODB (editable) equivalent of this object.""" """Create a ZODB (editable) equivalent of this object."""
obj = ERP5Form(self.getId(), self.title) type_info = self.getPortalObject().portal_types.getTypeInfo('ERP5 Form')
obj = type_info.constructInstance(container=self,
temp_object=True,
id=self.getId(),
title=self.title).aq_base
obj.set_xml(self.get_xml()) obj.set_xml(self.get_xml())
return obj return obj
......
...@@ -438,7 +438,8 @@ def addERP5Form(self, id, title="", REQUEST=None): ...@@ -438,7 +438,8 @@ def addERP5Form(self, id, title="", REQUEST=None):
Result -- empty string Result -- empty string
""" """
# add actual object # add actual object
id = self._setObject(id, ERP5Form(id, title)) type_info = self.getPortalObject().portal_types.getTypeInfo('ERP5 Form')
type_info.constructInstance(container=self, id=id, title=title)
# respond to the add_and_edit button if necessary # respond to the add_and_edit button if necessary
add_and_edit(self, id, REQUEST) add_and_edit(self, id, REQUEST)
return '' return ''
...@@ -643,7 +644,7 @@ class ERP5Form(Base, ZMIForm, ZopePageTemplate): ...@@ -643,7 +644,7 @@ class ERP5Form(Base, ZMIForm, ZopePageTemplate):
# don't get ERP5Type's Base default content_type. # don't get ERP5Type's Base default content_type.
content_type = ZopePageTemplate.content_type content_type = ZopePageTemplate.content_type
def __init__(self, id, title, unicode_mode=0, encoding='UTF-8', def __init__(self, id, title='', unicode_mode=0, encoding='UTF-8',
stored_encoding='UTF-8'): stored_encoding='UTF-8'):
"""Initialize form. """Initialize form.
id -- id of form id -- id of form
...@@ -1312,14 +1313,6 @@ class ERP5Form(Base, ZMIForm, ZopePageTemplate): ...@@ -1312,14 +1313,6 @@ class ERP5Form(Base, ZMIForm, ZopePageTemplate):
return str((self.pt, self.name, self.action, self.update_action, return str((self.pt, self.name, self.action, self.update_action,
self.encoding, self.stored_encoding, self.enctype)) self.encoding, self.stored_encoding, self.enctype))
# XXX: This class is a mix between a document class and a regular class.
# Ideally, it should be made an alias to "erp5.portal_type.ERP5 Form",
# which is the corresponding fully-functional document class.
# Until then, hardcode some methods expected to exist on all document
# classes so that they can be removed from Base.
def _getAcquireLocalRoles(self):
return True
# utility function # utility function
def get_field_meta_type_and_proxy_flag(field): def get_field_meta_type_and_proxy_flag(field):
if field.meta_type=='ProxyField': if field.meta_type=='ProxyField':
......
...@@ -44,7 +44,6 @@ from Products.Formulator.MethodField import Method, BoundMethod ...@@ -44,7 +44,6 @@ from Products.Formulator.MethodField import Method, BoundMethod
from Products.Formulator.TALESField import TALESMethod from Products.Formulator.TALESField import TALESMethod
from Products.ERP5Type.Core.Folder import Folder from Products.ERP5Type.Core.Folder import Folder
from Products.ERP5Form.Form import ERP5Form
from Products.ERP5Form.Form import field_value_cache from Products.ERP5Form.Form import field_value_cache
from Products.ERP5Form.Form import getFieldValue from Products.ERP5Form.Form import getFieldValue
from Products.ERP5Form import ProxyField from Products.ERP5Form import ProxyField
...@@ -638,10 +637,8 @@ class TestProxyField(ERP5TypeTestCase): ...@@ -638,10 +637,8 @@ class TestProxyField(ERP5TypeTestCase):
def afterSetUp(self): def afterSetUp(self):
self.container = Folder('container').__of__(self.portal) self.container = Folder('container').__of__(self.portal)
self.container._setObject('Base_viewProxyFieldLibrary', self.container.manage_addProduct['ERP5Form'].addERP5Form('Base_viewProxyFieldLibrary', 'Proxys')
ERP5Form('Base_viewProxyFieldLibrary', 'Proxys')) self.container.manage_addProduct['ERP5Form'].addERP5Form('Base_view', 'View')
self.container._setObject('Base_view',
ERP5Form('Base_view', 'View'))
from Products.CMFCore.tests.base.utils import _setUpDefaultTraversable from Products.CMFCore.tests.base.utils import _setUpDefaultTraversable
_setUpDefaultTraversable() _setUpDefaultTraversable()
...@@ -927,7 +924,7 @@ class TestFieldValueCache(ERP5TypeTestCase): ...@@ -927,7 +924,7 @@ class TestFieldValueCache(ERP5TypeTestCase):
def afterSetUp(self): def afterSetUp(self):
self.root = self.portal self.root = self.portal
self.root.form = ERP5Form('form', 'Form') self.root.manage_addProduct['ERP5Form'].addERP5Form('form', 'Form')
self.root.getProperty = lambda key, d=None: \ self.root.getProperty = lambda key, d=None: \
dict(on_memory_field='123').get(key, d) dict(on_memory_field='123').get(key, d)
......
...@@ -41,7 +41,6 @@ from Products.ERP5Type.tests.utils import createZODBPythonScript ...@@ -41,7 +41,6 @@ from Products.ERP5Type.tests.utils import createZODBPythonScript
from ZPublisher.HTTPRequest import FileUpload from ZPublisher.HTTPRequest import FileUpload
from StringIO import StringIO from StringIO import StringIO
from Products.ERP5Form.Selection import Selection from Products.ERP5Form.Selection import Selection
from Products.ERP5Form.Form import ERP5Form
from Products.Formulator.TALESField import TALESMethod from Products.Formulator.TALESField import TALESMethod
from Products.ERP5Form.ListBox import ListBoxHTMLRenderer from Products.ERP5Form.ListBox import ListBoxHTMLRenderer
...@@ -634,8 +633,7 @@ class TestListBox(ERP5TypeTestCase): ...@@ -634,8 +633,7 @@ class TestListBox(ERP5TypeTestCase):
field_columns=['listbox_value | Title',],) field_columns=['listbox_value | Title',],)
# create a form, to store our proxy field inside # create a form, to store our proxy field inside
portal._setObject('Test_view', portal.manage_addProduct['ERP5Form'].addERP5Form('Test_view', 'View')
ERP5Form('Test_view', 'View'))
portal.Test_view.manage_addField('listbox', 'listbox', 'ProxyField') portal.Test_view.manage_addField('listbox', 'listbox', 'ProxyField')
proxy_field = portal.Test_view.listbox proxy_field = portal.Test_view.listbox
proxy_field.manage_edit_xmlrpc(dict( proxy_field.manage_edit_xmlrpc(dict(
......
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
############################################################################## ##############################################################################
import unittest import unittest
from Products.ERP5Form.Form import ERP5Form
from DocumentTemplate import String from DocumentTemplate import String
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
...@@ -66,7 +65,7 @@ class TestOOoChart(ERP5TypeTestCase, ZopeTestCase.Functional): ...@@ -66,7 +65,7 @@ class TestOOoChart(ERP5TypeTestCase, ZopeTestCase.Functional):
portal = self.getPortal() portal = self.getPortal()
container = portal.portal_skins.custom container = portal.portal_skins.custom
if self.form_id not in container.objectIds(): if self.form_id not in container.objectIds():
container._setObject(self.form_id, ERP5Form(self.form_id, 'View')) container.manage_addProduct['ERP5Form'].addERP5Form(self.form_id, 'View')
form = getattr(container, self.form_id) form = getattr(container, self.form_id)
# create some persons in person_module # create some persons in person_module
......
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from Products.Formulator.TALESField import TALESMethod from Products.Formulator.TALESField import TALESMethod
from Products.ERP5Type.Core.Folder import Folder from Products.ERP5Type.Core.Folder import Folder
from Products.ERP5Form.Form import ERP5Form
from Products.ERP5Form.Form import field_value_cache from Products.ERP5Form.Form import field_value_cache
class TestProxify(ERP5TypeTestCase): class TestProxify(ERP5TypeTestCase):
...@@ -40,8 +39,7 @@ class TestProxify(ERP5TypeTestCase): ...@@ -40,8 +39,7 @@ class TestProxify(ERP5TypeTestCase):
def afterSetUp(self): def afterSetUp(self):
# base field library # base field library
self.container = Folder('container').__of__(self.portal) self.container = Folder('container').__of__(self.portal)
self.container._setObject('Base_view', self.container.manage_addProduct['ERP5Form'].addERP5Form('Base_view', 'Base')
ERP5Form('Base_view', 'Base'))
base_view = self.base_view = self.container.Base_view base_view = self.base_view = self.container.Base_view
base_view.manage_addField('my_string_field', 'String Field', 'StringField') base_view.manage_addField('my_string_field', 'String Field', 'StringField')
base_view.manage_addField('my_list_field', 'List Field', 'ListField') base_view.manage_addField('my_list_field', 'List Field', 'ListField')
...@@ -59,16 +57,14 @@ class TestProxify(ERP5TypeTestCase): ...@@ -59,16 +57,14 @@ class TestProxify(ERP5TypeTestCase):
del base_view.my_relation_string_field.values['relation_form_id'] del base_view.my_relation_string_field.values['relation_form_id']
# address view # address view
self.container._setObject('Address_view', self.container.manage_addProduct['ERP5Form'].addERP5Form('Address_view', 'Address')
ERP5Form('Address_view', 'Address'))
address_view = self.address_view = self.container.Address_view address_view = self.address_view = self.container.Address_view
address_view.manage_addField('my_region', 'Country', 'StringField') address_view.manage_addField('my_region', 'Country', 'StringField')
address_view.my_region.values['size'] = 1 address_view.my_region.values['size'] = 1
address_view.my_region.tales['items'] = TALESMethod('here/portal_categories/region/getCategoryChildTitleItemList') address_view.my_region.tales['items'] = TALESMethod('here/portal_categories/region/getCategoryChildTitleItemList')
# person view # person view
self.container._setObject('Person_view', self.container.manage_addProduct['ERP5Form'].addERP5Form('Person_view', 'Person')
ERP5Form('Person_view', 'Person'))
person_view = self.person_view = self.container.Person_view person_view = self.person_view = self.container.Person_view
person_view.manage_addField('my_name', 'Name', 'StringField') person_view.manage_addField('my_name', 'Name', 'StringField')
person_view.manage_addField('my_default_region', 'Country', 'ListField') person_view.manage_addField('my_default_region', 'Country', 'ListField')
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment