diff --git a/product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/Base_edit.xml b/product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/Base_edit.xml index 348845e508ed400b9d79224e4a9c8d1a17a923bb..ea045523701e22c825fd2656576e0c5073f9aa8f 100644 --- a/product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/Base_edit.xml +++ b/product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/Base_edit.xml @@ -70,69 +70,70 @@ <key> <string>_body</string> </key> <value> <string encoding="cdata"><![CDATA[ -from Products.Formulator.Errors import ValidationError, FormValidationError\n -portal = context.getPortalObject()\n -N_ = portal.Base_translateString\n +from Products.Formulator.Errors import FormValidationError\n +\n request=context.REQUEST\n \n -#### Workaround for bug #21\n +# Prevent users who don\'t have rights to edit the object from\n +# editing it by calling the Base_edit script with correct \n +# parameters directly.\n if not request.AUTHENTICATED_USER.has_permission(\'Modify portal content\', context) :\n - redirect_url = \'%s/%s?selection_index=%s&selection_name=%s&%s\' % ( context.absolute_url()\n - , form_id, selection_index, selection_name, \'portal_status_message=You+don\\\'t+have+the+permissions+to+edit+the+object.\')\n - request[ \'RESPONSE\' ].redirect( redirect_url )\n - return\n + redirect_url = \'%s/%s?selection_index=%s&selection_name=%s&%s\' % (context.absolute_url(), form_id, selection_index, selection_name, \'portal_status_message=You+don\\\'t+have+the+permissions+to+edit+the+object.\')\n + return request[\'RESPONSE\'].redirect(redirect_url)\n \n -MARKER = []\n +# Define form\n +if dialog_id==\'\' or dialog_id is None:\n + form = getattr(context,form_id)\n +else:\n + form = getattr(context,dialog_id)\n \n try:\n - # Define form basic fields\n - if dialog_id==\'\' or dialog_id is None:\n - form = getattr(context,form_id)\n - else:\n - form = getattr(context,dialog_id)\n # Validate\n form.validate_all_to_request(request)\n - # Basic attributes\n - kw = {}\n - encapsulated_editor_list = []\n - # Parse attributes\n +except FormValidationError, validation_errors:\n + # Pack errors into the request\n + field_errors = form.ErrorFields(validation_errors)\n + request.set(\'field_errors\', field_errors)\n + # Make sure editors are pushed back as values into the REQUEST object\n for f in form.get_fields():\n - k = f.id\n - v = getattr(request, k, MARKER)\n - if hasattr(v, \'edit\'):\n - # This is an encapsulated editor\n - # call it\n - encapsulated_editor_list.append(v)\n -# v.edit(context)\n - pass\n - elif v is not MARKER:\n - if k[0:3] == \'my_\':\n - # We only take into account\n - # the object attributes\n - k = k[3:]\n - # XXXX The formulate is badly designed, no value should be None.\n - if v == \'\':\n - v = None\n - kw[k] = v\n + field_id = f.id\n + if request.has_key(field_id):\n + value = request.get(field_id)\n + if callable(value):\n + value(request)\n + return form(request)\n \n - # Update matrix attributes\n - # It is possible to display multiples matrixbox on the same form,\n - # if they are named matrixbox, matrixbox1, matrixbox2, ...\n -# matrixbox = request.get(\'matrixbox\')\n - matrixbox_field_id = \'matrixbox\'\n - matrixbox_number = 0\n - matrixbox = request.get(matrixbox_field_id)\n -# if matrixbox is not None:\n - while matrixbox is not None:\n - matrixbox_field = form.get_field(matrixbox_field_id)\n +def editListBox(listbox_field, listbox):\n + """ Function called to edit a listbox\n + """\n + if listbox is not None:\n + gv = {}\n + if listbox_field.has_value(\'global_attributes\'):\n + hidden_attributes = map(lambda x:x[0], listbox_field.get_value(\'global_attributes\'))\n + for k in hidden_attributes:\n + gv[k] = getattr(request, k, None)\n + for url, v in listbox.items():\n + v.update(gv)\n + context.restrictedTraverse(url).edit(**v)\n +\n +def editPlanningBox(planning_box):\n + """ Function called to edit a planning box\n + """\n + if planning_box is not None:\n + for url, v in planning_box.items():\n + context.restrictedTraverse(url).edit(**v)\n +\n +def editMatrixBox(matrixbox_field, matrixbox):\n + """ Function called to edit a Matrix box\n + """\n + if matrixbox is not None:\n cell_base_id = matrixbox_field.get_value(\'cell_base_id\')\n portal_type = matrixbox_field.get_value(\'cell_portal_type\')\n getter_method = matrixbox_field.get_value(\'getter_method\')\n - if getter_method not in (None,\'\'):\n + if getter_method not in (None, \'\'):\n matrix_context = getattr(context,getter_method)()\n else:\n matrix_context = context\n - \n if matrix_context is not None:\n kd = {}\n kd[\'portal_type\'] = portal_type\n @@ -141,154 +142,120 @@ try:\n if matrixbox_field.has_value(\'global_attributes\'):\n hidden_attributes = map(lambda x:x[0], matrixbox_field.get_value(\'global_attributes\'))\n for k in hidden_attributes:\n - gv[k] = getattr(request, k,None)\n -\n -\n + gv[k] = getattr(request, k, None)\n if matrixbox_field.get_value(\'update_cell_range\'):\n # Update cell range each time it is modified\n lines = matrixbox_field.get_value(\'lines\')\n columns = matrixbox_field.get_value(\'columns\')\n tabs = matrixbox_field.get_value(\'tabs\')\n -\n + \n column_ids = map(lambda x: x[0], columns)\n line_ids = map(lambda x: x[0], lines)\n tab_ids = map(lambda x: x[0], tabs)\n -\n + \n # There are 3 cases\n - # Case 1: we do 1 dimensional matrices\n - # Case 2: we do 2 dimensional matrices\n - # Case 3: we do 2 dimensinal matrices + tabs\n -\n + # Case 1: we do 1 dimensional matrix\n + # Case 2: we do 2 dimensional matrix\n + # Case 3: we do 2 dimensional matrix + tabs\n cell_range = matrix_context.getCellRange(base_id = cell_base_id)\n -\n - if (len(column_ids) == 0) or (column_ids[0] == None):\n + if (len(column_ids) == 0) or (column_ids[0] is None):\n matrixbox_cell_range = [line_ids]\n if cell_range != matrixbox_cell_range:\n matrix_context.setCellRange(line_ids, base_id=cell_base_id)\n -\n - elif (len(tab_ids) == 0) or (tab_ids[0] == None):\n + \n + elif (len(tab_ids) == 0) or (tab_ids[0] is None):\n matrixbox_cell_range = [line_ids, column_ids]\n if cell_range != matrixbox_cell_range:\n matrix_context.setCellRange(line_ids, column_ids, base_id=cell_base_id)\n -\n + \n else:\n matrixbox_cell_range = [line_ids, column_ids, tab_ids]\n if cell_range != matrixbox_cell_range:\n matrix_context.setCellRange(line_ids, column_ids, tab_ids, base_id=cell_base_id)\n -\n -\n - for k,v in matrixbox.items():\n - # Only update cells which still exist\n - if matrix_context.hasInRange(*k, **kd):\n - c = matrix_context.newCell(*k, **kd)\n - if c is not None:\n - c.edit(**gv) # First update globals which include the def. of property_list\n - if v.has_key(\'variated_property\'):\n - # For Variated Properties\n - value = v[\'variated_property\']\n - del v[\'variated_property\']\n - if gv.has_key(\'mapped_value_property_list\'):\n - # Change the property which is defined by the\n - # first element of mapped_value_property_list\n - # XXX May require some changes with Sets\n - key = gv[\'mapped_value_property_list\'][0]\n - v[key] = value\n - c.edit(**v) # and update the cell specific values\n + \n + for k,v in matrixbox.items():\n + # Only update cells which still exist\n + if matrix_context.hasInRange(*k, **kd):\n + c = matrix_context.newCell(*k, **kd)\n + if c is not None:\n + c.edit(**gv) # First update globals which include the def. of property_list\n + if v.has_key(\'variated_property\'):\n + # For Variated Properties\n + value = v[\'variated_property\']\n + del v[\'variated_property\']\n + if gv.has_key(\'mapped_value_property_list\'):\n + # Change the property which is defined by the\n + # first element of mapped_value_property_list\n + # XXX May require some changes with Sets\n + key = gv[\'mapped_value_property_list\'][0]\n + v[key] = value\n + c.edit(**v) # and update the cell specific values\n + else:\n + return "Could not create cell %s" % str(k)\n else:\n - return "Could not create cell %s" % str(k)\n - else:\n - return "Cell %s does not exist" % str(k)\n + return "Cell %s does not exist" % str(k)\n \n - matrixbox_number += 1\n - matrixbox_field_id = \'matrixbox%s\' % matrixbox_number\n - matrixbox = request.get(matrixbox_field_id)\n +def parseField(f):\n + """\n + Parse given form field, to put them in\n + kw or in encapsulated_editor_list\n + """\n + k = f.id\n + v = getattr(request, k, MARKER)\n + if hasattr(v, \'edit\'):\n + # This is an encapsulated editor\n + # call it\n + encapsulated_editor_list.append(v)\n + context.log(\'parseField\', k)\n + elif v is not MARKER:\n + if k.startswith(\'my_\'):\n + # We only take into account\n + # the object attributes\n + k = k[3:]\n + # Form: \'\' -> ERP5: None\n + if v == \'\':\n + v = None\n + kw[k] = v\n \n - # Update listbox attributes\n - list_block_error=[]\n - planning_box = request.get(\'planning_box\')\n - listbox = request.get(\'listbox\')\n - request_selection_name = request.get(\'selection_name\')\n -\n - # XXX XXX XXX don t remove. It prevent to delete listbox object property after a selection for a RelationField...\n - # must really improve !!!\n - #if listbox is not None and request_selection_name==selection_name:\n - if listbox is not None:\n - listbox_field = form.get_field(\'listbox\')\n - gv = {}\n - if listbox_field.has_value(\'global_attributes\'):\n - hidden_attributes = map(lambda x:x[0], listbox_field.get_value(\'global_attributes\'))\n - for k in hidden_attributes:\n - gv[k] = getattr(request, k,None)\n - for url, v in listbox.items():\n - o = context.restrictedTraverse(url)\n - v.update(gv)\n - o.edit(**v)\n - # This below was disabled by yo. Do not use flushActivity. It is forbidden.\n - # If you want to reactivate this, ask yo before doing.\n - #o.flushActivity(method_id="immediateReindexObject",\n - # invoke = 1) # This is required if we wish to provide immediate display\n - #o.flushActivity(method_id="recursiveImmediateReindexObject",\n - # invoke = 1) # Requires if we want to display indexed subobject data... but long\n - # However it seems it reindexed many many times... XXX\n - # Maybe we should build a list of objects we need\n -\n - if planning_box is not None:\n - planning_box_field = form.get_field(\'planning_box\')\n - gv = {}\n -\n - for url, v in planning_box.items():\n - o = context.restrictedTraverse(url)\n - v.update(gv)\n - o.edit(**v)\n - # This below was disabled by yo. Do not use flushActivity. It is forbidden.\n - # If you want to reactivate this, ask yo before doing.\n - #o.flushActivity(method_id="immediateReindexObject",\n - # invoke = 1) # This is required if we wish to provide immediate display\n - #o.flushActivity(method_id="recursiveImmediateReindexObject",\n - # invoke = 1) # Requires if we want to display indexed subobject data... but long\n - # However it seems it reindexed many many times... XXX\n - \n - # Maybe we should build a list of objects we need\n - # Update basic attributes\n - context.edit(REQUEST=request,**kw)\n - for encapsulated_editor in encapsulated_editor_list:\n - encapsulated_editor.edit(context)\n +# Some initilizations\n +kw = {}\n +encapsulated_editor_list = []\n +MARKER = []\n \n -except FormValidationError, validation_errors:\n - # Pack errors into the request\n - field_errors = form.ErrorFields(validation_errors)\n - request.set(\'field_errors\', field_errors)\n - # Make sure editors are pushed back as values into the REQUEST object\n - for f in form.get_fields():\n - field_id = f.id\n - if request.has_key(field_id):\n - value = request.get(field_id)\n - if callable(value):\n - value(request)\n - return form(request)\n +# We process all the field in form and\n +# we check if they are in the request,\n +# then we edit them\n +for field in form.get_fields():\n + parseField(field)\n + if(field.meta_type == \'ListBox\'):\n + editListBox(field, request.get(field.id))\n + elif(field.meta_type == \'MatrixBox\'):\n + editMatrixBox(field, request.get(field.id))\n + elif(field.meta_type == \'PlanningBox\'):\n + editPlanningBox(request.get(field.id))\n \n +# Maybe we should build a list of objects we need\n +# Update basic attributes\n +context.edit(REQUEST=request,**kw)\n +for encapsulated_editor in encapsulated_editor_list:\n + encapsulated_editor.edit(context)\n else:\n - message = N_("Data+Updated.")\n + message = context.getPortalObject().Base_translateString("Data+Updated.")\n if not(ignore_layout) and context.getApplicableLayout() :\n redirect_url = \'%s/%s?editable_mode=1\' % (context.REQUEST.URL1, form_id)\n elif not selection_index:\n - redirect_url = \'%s/%s?portal_status_message=%s\' % ( context.absolute_url()\n - , form_id\n - , message\n - )\n + redirect_url = \'%s/%s?portal_status_message=%s\' % (context.absolute_url(),\n + dialog_id,\n + message)\n else:\n - redirect_url = \'%s/%s?selection_index=%s&selection_name=%s&portal_status_message=%s\' % ( \n - context.absolute_url()\n - , form_id\n - , selection_index\n - , selection_name\n - , message\n - )\n -\n + redirect_url = \'%s/%s?selection_index=%s&selection_name=%s&portal_status_message=%s\' % (\n + context.absolute_url(),\n + dialog_id,\n + selection_index,\n + selection_name,\n + message)\n \n -\n -request[ \'RESPONSE\' ].redirect( redirect_url )\n -# vim: syntax=python\n +return request[\'RESPONSE\'].redirect(redirect_url)\n ]]></string> </value> @@ -307,7 +274,7 @@ request[ \'RESPONSE\' ].redirect( redirect_url )\n </item> <item> <key> <string>_filepath</string> </key> - <value> <string>Script (Python):/nexedi/portal_skins/erp5_core/Base_edit</string> </value> + <value> <string>Script (Python):/erp5/portal_skins/erp5_core/Base_edit</string> </value> </item> <item> <key> <string>_params</string> </key> @@ -343,66 +310,32 @@ request[ \'RESPONSE\' ].redirect( redirect_url )\n <string>dialog_id</string> <string>ignore_layout</string> <string>Products.Formulator.Errors</string> - <string>ValidationError</string> <string>FormValidationError</string> <string>_getattr_</string> <string>context</string> - <string>portal</string> - <string>N_</string> <string>request</string> <string>redirect_url</string> <string>_getitem_</string> - <string>MARKER</string> <string>None</string> <string>getattr</string> <string>form</string> - <string>kw</string> - <string>encapsulated_editor_list</string> - <string>_getiter_</string> - <string>f</string> - <string>k</string> - <string>v</string> - <string>hasattr</string> - <string>_write_</string> - <string>matrixbox_field_id</string> - <string>matrixbox_number</string> - <string>matrixbox</string> - <string>matrixbox_field</string> - <string>cell_base_id</string> - <string>portal_type</string> - <string>getter_method</string> - <string>matrix_context</string> - <string>kd</string> - <string>gv</string> - <string>map</string> - <string>hidden_attributes</string> - <string>lines</string> - <string>columns</string> - <string>tabs</string> - <string>column_ids</string> - <string>line_ids</string> - <string>tab_ids</string> - <string>cell_range</string> - <string>len</string> - <string>matrixbox_cell_range</string> - <string>_apply_</string> - <string>c</string> - <string>value</string> - <string>key</string> - <string>str</string> - <string>list_block_error</string> - <string>planning_box</string> - <string>listbox</string> - <string>request_selection_name</string> - <string>listbox_field</string> - <string>url</string> - <string>o</string> - <string>planning_box_field</string> - <string>encapsulated_editor</string> <string>validation_errors</string> <string>field_errors</string> + <string>_getiter_</string> + <string>f</string> <string>field_id</string> + <string>value</string> <string>callable</string> + <string>editListBox</string> + <string>editPlanningBox</string> + <string>editMatrixBox</string> + <string>MARKER</string> + <string>kw</string> + <string>encapsulated_editor_list</string> + <string>parseField</string> + <string>field</string> + <string>_apply_</string> + <string>encapsulated_editor</string> <string>message</string> </tuple> </value>