Commit d1bd4db9 authored by Ayush Tiwari's avatar Ayush Tiwari

ERP5 Catalog View Improvement

This contains changes for 2 points:
1. To improve view of ERP5 Catalog and its sub-objects .
2. Export Catalog Methods with no duplication between attributes and properties after migration.

These changes are pointed out  in comment here: nexedi/erp5!178 (comment 52224)

/reviewed-on nexedi/erp5!510
parents 13d43568 5c3b63b5
...@@ -38,6 +38,7 @@ from AccessControl import ClassSecurityInfo, Unauthorized, getSecurityManager ...@@ -38,6 +38,7 @@ from AccessControl import ClassSecurityInfo, Unauthorized, getSecurityManager
from AccessControl.SecurityInfo import ModuleSecurityInfo from AccessControl.SecurityInfo import ModuleSecurityInfo
from Products.CMFCore.utils import getToolByName from Products.CMFCore.utils import getToolByName
from Products.PythonScripts.PythonScript import PythonScript from Products.PythonScripts.PythonScript import PythonScript
from Products.ZSQLMethods.SQL import SQL
from Products.ERP5Type.Accessor.Constant import PropertyGetter as ConstantGetter from Products.ERP5Type.Accessor.Constant import PropertyGetter as ConstantGetter
from Products.ERP5Type.Cache import transactional_cached from Products.ERP5Type.Cache import transactional_cached
from Products.ERP5Type.Message import translateString from Products.ERP5Type.Message import translateString
...@@ -143,6 +144,7 @@ SEPARATELY_EXPORTED_PROPERTY_DICT = { ...@@ -143,6 +144,7 @@ SEPARATELY_EXPORTED_PROPERTY_DICT = {
"PythonScript": ("py", 0, "_body"), "PythonScript": ("py", 0, "_body"),
"Spreadsheet": (None, 0, "data"), "Spreadsheet": (None, 0, "data"),
"SQL": ("sql", 0, "src"), "SQL": ("sql", 0, "src"),
"SQL Method": ("sql", 0, "src"),
"Test Component": ("py", 0, "text_content"), "Test Component": ("py", 0, "text_content"),
"Test Page": (None, 0, "text_content"), "Test Page": (None, 0, "text_content"),
"Web Page": (None, 0, "text_content"), "Web Page": (None, 0, "text_content"),
...@@ -621,7 +623,8 @@ class BaseTemplateItem(Implicit, Persistent): ...@@ -621,7 +623,8 @@ class BaseTemplateItem(Implicit, Persistent):
delattr(obj, attr) delattr(obj, attr)
elif classname in ('File', 'Image'): elif classname in ('File', 'Image'):
attr_set.update(('_EtagSupport__etag', 'size')) attr_set.update(('_EtagSupport__etag', 'size'))
elif classname == 'SQL' and klass.__module__== 'Products.ZSQLMethods.SQL': # SQL covers both ZSQL Methods and ERP5 SQL Methods
elif isinstance(obj, SQL):
attr_set.update(('_arg', 'template')) attr_set.update(('_arg', 'template'))
elif interfaces.IIdGenerator.providedBy(obj): elif interfaces.IIdGenerator.providedBy(obj):
attr_set.update(('last_max_id_dict', 'last_id_dict')) attr_set.update(('last_max_id_dict', 'last_id_dict'))
...@@ -2915,18 +2918,28 @@ class CatalogMethodTemplateItem(ObjectTemplateItem): ...@@ -2915,18 +2918,28 @@ class CatalogMethodTemplateItem(ObjectTemplateItem):
for prop in property_list: for prop in property_list:
if prop.get('select_variable') == 'getCatalogMethodIds': if prop.get('select_variable') == 'getCatalogMethodIds':
# In case the properties are defined via property sheet 'Catalog', the # In case the properties are defined via property sheet 'Catalog', the
# object would have two IDs if it is of type 'selection' or # object would have two IDs if it is of type 'selection' or
# 'multiple_selection': 'id' and 'base_id', usage of base_id is preferred # 'multiple_selection': 'id' and 'base_id', usage of base_id is preferred
# while building objects as it maintains consistency between the old # while building objects as it maintains consistency between the old
# catalog and new erp5 catalog # catalog and new erp5 catalog
prop_id = prop.get('base_id', prop['id']) prop_id = prop.get('base_id', prop['id'])
if prop['type'] == 'selection' and \
# IMPORTANT: After migration of Catalog, the properties which were of
# 'selection' type in ZSQL Catalog made more sense to be of 'string'
# type as they only contained one value. Also, putting them in
# 'selection' type, we would've ended up having to deal with accessors
# which end with '_list' which would've made no sense. So, we decided
# to move them to 'string' type
if prop['type'] in ('string', 'selection') and \
getattr(catalog, prop_id) == method_id: getattr(catalog, prop_id) == method_id:
method_properties[prop_id] = 1 method_properties[prop_id] = 1
elif prop['type'] == 'multiple selection' and \ elif prop['type'] == 'multiple selection' and \
method_id in getattr(catalog, prop_id): method_id in getattr(catalog, prop_id):
method_properties[prop_id] = 1 method_properties[prop_id] = 1
return method_properties return method_properties
def build(self, context, **kw): def build(self, context, **kw):
...@@ -2943,16 +2956,10 @@ class CatalogMethodTemplateItem(ObjectTemplateItem): ...@@ -2943,16 +2956,10 @@ class CatalogMethodTemplateItem(ObjectTemplateItem):
for obj in self._objects.values(): for obj in self._objects.values():
method_id = obj.id method_id = obj.id
# Check if the method exists in catalog before getting filter dict # Check if the method is sub-object of Catalog
if method_id in catalog.objectIds(): if method_id in catalog.objectIds():
self._method_properties[method_id] = self._extractMethodProperties( self._method_properties[method_id] = self._extractMethodProperties(
catalog, method_id) catalog, method_id)
filter = catalog._getFilterDict().get(method_id, {})
self._is_filtered_archive[method_id] = filter.get('filtered', 0)
for method in catalog_method_filter_list:
property = method[8:-8]
if property in filter:
getattr(self, method)[method_id] = filter[property]
def generateXml(self, path): def generateXml(self, path):
obj = self._objects[path] obj = self._objects[path]
...@@ -2964,22 +2971,6 @@ class CatalogMethodTemplateItem(ObjectTemplateItem): ...@@ -2964,22 +2971,6 @@ class CatalogMethodTemplateItem(ObjectTemplateItem):
xml_data += '\n <value>%s</value>' %(value,) xml_data += '\n <value>%s</value>' %(value,)
xml_data += '\n </item>' xml_data += '\n </item>'
if self._is_filtered_archive.get(method_id):
xml_data += '\n <item key="_is_filtered_archive" type="int">'
xml_data += '\n <value>1</value>'
xml_data += '\n </item>'
for method in catalog_method_filter_list:
if method != '_filter_expression_instance_archive':
value = getattr(self, method, {}).get(method_id)
if isinstance(value, basestring):
xml_data += '\n <item key="%s" type="str">' %(method,)
xml_data += '\n <value>%s</value>' %(str(value))
xml_data += '\n </item>'
elif value:
xml_data += '\n <item key="%s" type="tuple">'%(method)
for item in value:
xml_data += '\n <value>%s</value>' %(str(item))
xml_data += '\n </item>'
xml_data += '\n</catalog_method>\n' xml_data += '\n</catalog_method>\n'
return xml_data return xml_data
...@@ -3066,7 +3057,16 @@ class CatalogMethodTemplateItem(ObjectTemplateItem): ...@@ -3066,7 +3057,16 @@ class CatalogMethodTemplateItem(ObjectTemplateItem):
setattr(catalog, key, tuple(new_value)) setattr(catalog, key, tuple(new_value))
method = catalog._getOb(method_id) method = catalog._getOb(method_id)
# Restore filter
# Restore filter:
#
# Here we have to handle two cases:
# 1. CatalogMethodTemplateItem with _is_filtered_archive (possible for
# methods who still have filter attributes in `_catalog_keys.xml` file).
# 2. CatalogMethodTemplateItem where methods have filter properties
# directly on xml file of method rather than in `_catalog_keys.xml`.
# This would be case for BT which have been exported after catalog
# migration.
if self._is_filtered_archive.get(method_id, 0): if self._is_filtered_archive.get(method_id, 0):
expression = self._filter_expression_archive[method_id] expression = self._filter_expression_archive[method_id]
if expression and expression.strip(): if expression and expression.strip():
...@@ -3080,7 +3080,10 @@ class CatalogMethodTemplateItem(ObjectTemplateItem): ...@@ -3080,7 +3080,10 @@ class CatalogMethodTemplateItem(ObjectTemplateItem):
method.setExpressionCacheKey( method.setExpressionCacheKey(
self._filter_expression_cache_key_archive.get(method_id, ())) self._filter_expression_cache_key_archive.get(method_id, ()))
method.setTypeList(self._filter_type_archive.get(method_id, ())) method.setTypeList(self._filter_type_archive.get(method_id, ()))
else: # If there is no filter archive and the the meta_type of the catalog
# method isn't one of the ERP5-ified Catalog Method Document, then
# set the filter to 0
elif method.meta_type not in ('ERP5 SQL Method', 'ERP5 Python Script'):
method.setFiltered(0) method.setFiltered(0)
# backward compatibility # backward compatibility
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ActionInformation" module="Products.CMFCore.ActionInformation"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/object_action</string>
</tuple>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_action</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Exporting properties produces a human-readable XML file which can be imported later. It is useful to reconstruct the same catalog information.</string> </value>
</item>
<item>
<key> <string>icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>export_property_content</string> </value>
</item>
<item>
<key> <string>permissions</string> </key>
<value>
<tuple>
<string>View</string>
</tuple>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Action Information</string> </value>
</item>
<item>
<key> <string>priority</string> </key>
<value> <float>7.0</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Export Properties</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
<value> <int>1</int> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/Catalog_exportProperty</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -39,6 +39,10 @@ ...@@ -39,6 +39,10 @@
<type>Business Template</type> <type>Business Template</type>
<workflow>business_template_building_workflow, business_template_installation_workflow</workflow> <workflow>business_template_building_workflow, business_template_installation_workflow</workflow>
</chain> </chain>
<chain>
<type>Catalog</type>
<workflow>edit_workflow</workflow>
</chain>
<chain> <chain>
<type>Category</type> <type>Category</type>
<workflow>edit_workflow</workflow> <workflow>edit_workflow</workflow>
...@@ -135,6 +139,14 @@ ...@@ -135,6 +139,14 @@
<type>Property Type Validity Constraint</type> <type>Property Type Validity Constraint</type>
<workflow>dynamic_class_generation_interaction_workflow</workflow> <workflow>dynamic_class_generation_interaction_workflow</workflow>
</chain> </chain>
<chain>
<type>Python Script</type>
<workflow>edit_workflow</workflow>
</chain>
<chain>
<type>SQL Method</type>
<workflow>edit_workflow</workflow>
</chain>
<chain> <chain>
<type>Standard Property</type> <type>Standard Property</type>
<workflow>dynamic_class_generation_interaction_workflow</workflow> <workflow>dynamic_class_generation_interaction_workflow</workflow>
......
# Script to download XML properties for erp5 catalog
REQUEST = context.REQUEST
RESPONSE = context.REQUEST.RESPONSE
return context.manage_exportProperties(REQUEST, RESPONSE)
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Catalog_exportProperty</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -51,7 +51,9 @@ ...@@ -51,7 +51,9 @@
<item> <item>
<key> <string>center</string> </key> <key> <string>center</string> </key>
<value> <value>
<list/> <list>
<string>my_title</string>
</list>
</value> </value>
</item> </item>
<item> <item>
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
<key> <string>delegated_list</string> </key> <key> <string>delegated_list</string> </key>
<value> <value>
<list> <list>
<string>all_columns</string>
<string>columns</string> <string>columns</string>
<string>count_method</string> <string>count_method</string>
<string>lines</string> <string>lines</string>
...@@ -54,10 +55,18 @@ ...@@ -54,10 +55,18 @@
<key> <string>tales</string> </key> <key> <string>tales</string> </key>
<value> <value>
<dictionary> <dictionary>
<item>
<key> <string>all_columns</string> </key>
<value> <string></string> </value>
</item>
<item> <item>
<key> <string>columns</string> </key> <key> <string>columns</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item>
<key> <string>count_method</string> </key>
<value> <string></string> </value>
</item>
<item> <item>
<key> <string>field_id</string> </key> <key> <string>field_id</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
...@@ -84,7 +93,9 @@ ...@@ -84,7 +93,9 @@
</item> </item>
<item> <item>
<key> <string>url_columns</string> </key> <key> <string>url_columns</string> </key>
<value> <string></string> </value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item> </item>
</dictionary> </dictionary>
</value> </value>
...@@ -93,6 +104,21 @@ ...@@ -93,6 +104,21 @@
<key> <string>values</string> </key> <key> <string>values</string> </key>
<value> <value>
<dictionary> <dictionary>
<item>
<key> <string>all_columns</string> </key>
<value>
<list>
<tuple>
<string>creation_date</string>
<string>Creation Date</string>
</tuple>
<tuple>
<string>modification_date</string>
<string>Modification Date</string>
</tuple>
</list>
</value>
</item>
<item> <item>
<key> <string>columns</string> </key> <key> <string>columns</string> </key>
<value> <value>
...@@ -105,6 +131,10 @@ ...@@ -105,6 +131,10 @@
<string>id</string> <string>id</string>
<string>ID</string> <string>ID</string>
</tuple> </tuple>
<tuple>
<string>translated_portal_type</string>
<string>Type</string>
</tuple>
</list> </list>
</value> </value>
</item> </item>
...@@ -114,7 +144,7 @@ ...@@ -114,7 +144,7 @@
</item> </item>
<item> <item>
<key> <string>field_id</string> </key> <key> <string>field_id</string> </key>
<value> <string>my_list_mode_listbox</string> </value> <value> <string>my_view_mode_listbox</string> </value>
</item> </item>
<item> <item>
<key> <string>form_id</string> </key> <key> <string>form_id</string> </key>
...@@ -127,7 +157,7 @@ ...@@ -127,7 +157,7 @@
<item> <item>
<key> <string>list_method</string> </key> <key> <string>list_method</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value> </value>
</item> </item>
<item> <item>
...@@ -141,16 +171,7 @@ ...@@ -141,16 +171,7 @@
<item> <item>
<key> <string>url_columns</string> </key> <key> <string>url_columns</string> </key>
<value> <value>
<list> <list/>
<tuple>
<string>id</string>
<string></string>
</tuple>
<tuple>
<string>title</string>
<string>Catalog_getObjectViewUrl</string>
</tuple>
</list>
</value> </value>
</item> </item>
</dictionary> </dictionary>
...@@ -160,6 +181,19 @@ ...@@ -160,6 +181,19 @@
</pickle> </pickle>
</record> </record>
<record id="2" aka="AAAAAAAAAAI="> <record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: [(column_id, \'Catalog_getObjectViewUrl\') for column_id, _ in field.get_value(\'columns\')]</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<global name="Method" module="Products.Formulator.MethodField"/> <global name="Method" module="Products.Formulator.MethodField"/>
</pickle> </pickle>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>editable</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_title</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>editable</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_string_field</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Title</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -61,7 +61,9 @@ ...@@ -61,7 +61,9 @@
<item> <item>
<key> <string>center</string> </key> <key> <string>center</string> </key>
<value> <value>
<list/> <list>
<string>my_title</string>
</list>
</value> </value>
</item> </item>
<item> <item>
......
...@@ -59,6 +59,10 @@ ...@@ -59,6 +59,10 @@
<key> <string>columns</string> </key> <key> <string>columns</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item>
<key> <string>count_method</string> </key>
<value> <string></string> </value>
</item>
<item> <item>
<key> <string>editable_columns</string> </key> <key> <string>editable_columns</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
...@@ -87,12 +91,6 @@ ...@@ -87,12 +91,6 @@
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item>
<key> <string>url_columns</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary> </dictionary>
</value> </value>
</item> </item>
...@@ -120,6 +118,10 @@ ...@@ -120,6 +118,10 @@
<string>expression_cache_key</string> <string>expression_cache_key</string>
<string>Expression Key</string> <string>Expression Key</string>
</tuple> </tuple>
<tuple>
<string>translated_portal_type</string>
<string>Type</string>
</tuple>
</list> </list>
</value> </value>
</item> </item>
...@@ -148,7 +150,7 @@ ...@@ -148,7 +150,7 @@
</item> </item>
<item> <item>
<key> <string>field_id</string> </key> <key> <string>field_id</string> </key>
<value> <string>my_list_mode_listbox</string> </value> <value> <string>my_view_mode_listbox</string> </value>
</item> </item>
<item> <item>
<key> <string>form_id</string> </key> <key> <string>form_id</string> </key>
...@@ -161,7 +163,7 @@ ...@@ -161,7 +163,7 @@
<item> <item>
<key> <string>list_method</string> </key> <key> <string>list_method</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value> </value>
</item> </item>
<item> <item>
...@@ -172,7 +174,7 @@ ...@@ -172,7 +174,7 @@
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string>Filter</string> </value> <value> <string>Filter Methods</string> </value>
</item> </item>
<item> <item>
<key> <string>url_columns</string> </key> <key> <string>url_columns</string> </key>
...@@ -180,7 +182,11 @@ ...@@ -180,7 +182,11 @@
<list> <list>
<tuple> <tuple>
<string>id</string> <string>id</string>
<string>ID</string> <string>Catalog_getObjectViewUrl</string>
</tuple>
<tuple>
<string>translated_portal_type</string>
<string></string>
</tuple> </tuple>
</list> </list>
</value> </value>
...@@ -192,19 +198,6 @@ ...@@ -192,19 +198,6 @@
</pickle> </pickle>
</record> </record>
<record id="2" aka="AAAAAAAAAAI="> <record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: [(\'id\', \'Catalog_getObjectViewUrl\'),]</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<global name="Method" module="Products.Formulator.MethodField"/> <global name="Method" module="Products.Formulator.MethodField"/>
</pickle> </pickle>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>editable</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_title</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>editable</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_string_field</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Title</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -265,7 +265,7 @@ ...@@ -265,7 +265,7 @@
</item> </item>
<item> <item>
<key> <string>text_editor</string> </key> <key> <string>text_editor</string> </key>
<value> <string>text_area</string> </value> <value> <string>codemirror</string> </value>
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
......
...@@ -50,7 +50,6 @@ Catalog | catalog_filter_view ...@@ -50,7 +50,6 @@ Catalog | catalog_filter_view
Catalog | clear_catalog Catalog | clear_catalog
Catalog | clear_reserved Catalog | clear_reserved
Catalog | content_view Catalog | content_view
Catalog | export_property_content
Catalog | property Catalog | property
Catalog | update_catalog Catalog | update_catalog
Category Acquired Membership State Constraint | predicate Category Acquired Membership State Constraint | predicate
......
...@@ -11,6 +11,7 @@ Base Type | base_type_interaction_workflow ...@@ -11,6 +11,7 @@ Base Type | base_type_interaction_workflow
Base Type | dynamic_class_generation_interaction_workflow Base Type | dynamic_class_generation_interaction_workflow
Business Template | business_template_building_workflow Business Template | business_template_building_workflow
Business Template | business_template_installation_workflow Business Template | business_template_installation_workflow
Catalog | edit_workflow
Category Acquired Membership State Constraint | dynamic_class_generation_interaction_workflow Category Acquired Membership State Constraint | dynamic_class_generation_interaction_workflow
Category Existence Constraint | dynamic_class_generation_interaction_workflow Category Existence Constraint | dynamic_class_generation_interaction_workflow
Category Membership Arity Constraint | dynamic_class_generation_interaction_workflow Category Membership Arity Constraint | dynamic_class_generation_interaction_workflow
...@@ -41,6 +42,8 @@ Property Existence Constraint | dynamic_class_generation_interaction_workflow ...@@ -41,6 +42,8 @@ Property Existence Constraint | dynamic_class_generation_interaction_workflow
Property Sheet Tool | dynamic_class_generation_interaction_workflow Property Sheet Tool | dynamic_class_generation_interaction_workflow
Property Sheet | dynamic_class_generation_interaction_workflow Property Sheet | dynamic_class_generation_interaction_workflow
Property Type Validity Constraint | dynamic_class_generation_interaction_workflow Property Type Validity Constraint | dynamic_class_generation_interaction_workflow
Python Script | edit_workflow
SQL Method | edit_workflow
Standard Property | dynamic_class_generation_interaction_workflow Standard Property | dynamic_class_generation_interaction_workflow
String Attribute Match Constraint | dynamic_class_generation_interaction_workflow String Attribute Match Constraint | dynamic_class_generation_interaction_workflow
System Preference | edit_workflow System Preference | edit_workflow
......
<catalog_method>
<item key="sql_catalog_tables" type="int">
<value>1</value>
</item>
</catalog_method>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="SQL" module="Products.ZSQLMethods.SQL"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>allow_simple_one_argument_traversal</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>arguments_src</string> </key>
<value> <string>table</string> </value>
</item>
<item>
<key> <string>cache_time_</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>class_file_</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>class_name_</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>connection_hook</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>connection_id</string> </key>
<value> <string>erp5_sql_connection</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>z_show_tables</string> </value>
</item>
<item>
<key> <string>max_cache_</string> </key>
<value> <int>100</int> </value>
</item>
<item>
<key> <string>max_rows_</string> </key>
<value> <int>1000</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -137,7 +137,6 @@ erp5_mysql_innodb/z_select_optimizer_switch ...@@ -137,7 +137,6 @@ erp5_mysql_innodb/z_select_optimizer_switch
erp5_mysql_innodb/z_show_category_columns erp5_mysql_innodb/z_show_category_columns
erp5_mysql_innodb/z_show_columns erp5_mysql_innodb/z_show_columns
erp5_mysql_innodb/z_show_index erp5_mysql_innodb/z_show_index
erp5_mysql_innodb/z_show_tables
erp5_mysql_innodb/z_uncatalog_delivery erp5_mysql_innodb/z_uncatalog_delivery
erp5_mysql_innodb/z_uncatalog_object erp5_mysql_innodb/z_uncatalog_object
erp5_mysql_innodb/z_unique_values erp5_mysql_innodb/z_unique_values
\ No newline at end of file
...@@ -573,6 +573,54 @@ AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO ...@@ -573,6 +573,54 @@ AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
for property_id, property_value in method_document_kw.iteritems(): for property_id, property_value in method_document_kw.iteritems():
self.assertEqual(getattr(method_page, property_id), property_value) self.assertEqual(getattr(method_page, property_id), property_value)
def test_twoFileImportExportForERP5SQLMethodInCatalog(self):
"""Test Business Template Import And Export With ERP5 SQL Method In Catalog"""
catalog_tool = self.getCatalogTool()
catalog = catalog_tool.getSQLCatalog()
catalog_id = catalog.id
self.assertTrue(catalog is not None)
method_id = "z_another_dummy_method"
if method_id in catalog.objectIds():
catalog.manage_delObjects([method_id])
method_document_kw = {'id': method_id, 'title': 'dummy_method_title',
'connection_id': 'erp5_sql_connection',
'arguments_src': 'args', 'src': 'dummy_method_template'}
addSQLMethod = catalog.newContent
addSQLMethod(portal_type='SQL Method', id=method_id,
title='dummy_method_title',
connection_id='erp5_sql_connection',
arguments_src = 'args',
src='dummy_method_template',
)
zsql_method = catalog._getOb(method_id, None)
self.assertTrue(zsql_method is not None)
self.template.edit(template_catalog_method_id_list=[catalog_id+'/'+method_id])
self._buildAndExportBusinessTemplate()
method_document_path = os.path.join(self.export_dir,
'CatalogMethodTemplateItem',
'portal_catalog',
catalog_id, method_id)
import_template = self._exportAndReImport(
method_document_path,
".sql",
'dummy_method_template',
['src'])
catalog.manage_delObjects([method_id])
import_template.install()
method_page = catalog[method_id]
for property_id, property_value in method_document_kw.iteritems():
self.assertEqual(getattr(method_page, property_id), property_value)
def test_twoFileImportExportForCatalogMethodInPortalSkins(self): def test_twoFileImportExportForCatalogMethodInPortalSkins(self):
"""Test Business Template Import And Export With Catalog Method In Portal Skins""" """Test Business Template Import And Export With Catalog Method In Portal Skins"""
......
...@@ -712,58 +712,6 @@ class Catalog(Folder, ...@@ -712,58 +712,6 @@ class Catalog(Folder,
local_role_key_dict[role.strip()] = column.strip() local_role_key_dict[role.strip()] = column.strip()
return local_role_key_dict.items() return local_role_key_dict.items()
security.declareProtected(import_export_objects, 'manage_exportProperties')
def manage_exportProperties(self, REQUEST=None, RESPONSE=None):
"""
Export properties to an XML file.
"""
f = StringIO()
f.write('<?xml version="1.0"?>\n<SQLCatalogData>\n')
property_id_list = self.propertyIds()
# Get properties and values
property_list = []
for property_id in property_id_list:
value = self.getProperty(property_id)
if value is not None:
property_list.append((property_id, value))
# Sort for easy diff
property_list.sort(key=lambda x: x[0])
for property in property_list:
property_id = property[0]
value = property[1]
if isinstance(value, basestring):
f.write(' <property id=%s type="str">%s</property>\n' % (quoteattr(property_id), escape(value)))
elif isinstance(value, (tuple, list)):
f.write(' <property id=%s type="tuple">\n' % quoteattr(property_id))
# Sort for easy diff
item_list = []
for item in value:
if isinstance(item, basestring):
item_list.append(item)
item_list.sort()
for item in item_list:
f.write(' <item type="str">%s</item>\n' % escape(str(item)))
f.write(' </property>\n')
# Filters are now propeties in ERP5 SQL Method(s)
filter_dict = self._getFilterDict()
if filter_dict:
for filter_id, filter_def in sorted(filter_dict.iteritems()):
if not filter_def['filtered']:
# If a filter is not activated, no need to output it.
continue
if not filter_def['expression']:
# If the expression is not specified, meaningless to specify it.
continue
f.write(' <filter id=%s expression=%s />\n' % (quoteattr(filter_id), quoteattr(filter_def['expression'])))
# For now, portal types are not exported, because portal types are too specific to each site.
f.write('</SQLCatalogData>\n')
if RESPONSE is not None:
RESPONSE.setHeader('Content-type','application/data')
RESPONSE.setHeader('Content-Disposition',
'inline;filename=properties.xml')
return f.getvalue()
security.declareProtected(manage_zcatalog_entries, 'manage_historyCompare') security.declareProtected(manage_zcatalog_entries, 'manage_historyCompare')
def manage_historyCompare(self, rev1, rev2, REQUEST, def manage_historyCompare(self, rev1, rev2, REQUEST,
historyComparisonResults=''): historyComparisonResults=''):
......
...@@ -220,15 +220,6 @@ class ZCatalog(Folder, Persistent, Implicit): ...@@ -220,15 +220,6 @@ class ZCatalog(Folder, Persistent, Implicit):
return self._getOb(id, default_value) return self._getOb(id, default_value)
security.declareProtected(import_export_objects, 'manage_catalogExportProperties')
def manage_catalogExportProperties(self, REQUEST=None, RESPONSE=None, sql_catalog_id=None):
"""
Export properties to an XML file.
"""
catalog = self.getSQLCatalog(sql_catalog_id)
if catalog is not None:
return catalog.manage_exportProperties(REQUEST=REQUEST, RESPONSE=RESPONSE)
def __len__(self): def __len__(self):
catalog = self.getSQLCatalog() catalog = self.getSQLCatalog()
if catalog is None: if catalog is None:
......
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