SVN: zope.formlib/trunk/ Introduced ``zope.formlib.form.applyData`` which works like

Philipp von Weitershausen <[email protected]>
Newsgroups gmane.comp.web.zope.zope3.cvs
Message-ID <20071109190322.A9FED203B41__44197.6195354529$1194635030$gmane$org@mail.zope.org>
Log message for revision 81649:
    Introduced ``zope.formlib.form.applyData`` which works like
    ``applyChanges`` but returns a dictionary with information about
    which attribute of which schema changed.  This information is then
    sent along with the ``IObjectModifiedEvent``.
  
    This fixes https://bugs.launchpad.net/zope3/+bug/98483.
  
    This comprises a new feature, therefore bumping version to 3.5.0.
  

Changed:
  U   zope.formlib/trunk/CHANGES.txt
  U   zope.formlib/trunk/setup.py
  U   zope.formlib/trunk/src/zope/formlib/form.py
  U   zope.formlib/trunk/src/zope/formlib/form.txt

-=-
Modified: zope.formlib/trunk/CHANGES.txt
===================================================================
--- zope.formlib/trunk/CHANGES.txt	2007-11-09 16:44:29 UTC (rev 81648)
+++ zope.formlib/trunk/CHANGES.txt	2007-11-09 19:03:22 UTC (rev 81649)
@@ -2,11 +2,18 @@
 Changes
 =======
 
-3.4.1 (unreleased)
+3.5.0 (unreleased)
 ==================
 
-...
+* Introduced ``zope.formlib.form.applyData`` which works like
+  ``applyChanges`` but returns a dictionary with information about
+  which attribute of which schema changed.  This information is then
+  sent along with the ``IObjectModifiedEvent``.
 
+  This fixes https://bugs.launchpad.net/zope3/+bug/98483.
+
+* ...
+
 3.4.0 (2007-09-28)
 ==================
 

Modified: zope.formlib/trunk/setup.py
===================================================================
--- zope.formlib/trunk/setup.py	2007-11-09 16:44:29 UTC (rev 81648)
+++ zope.formlib/trunk/setup.py	2007-11-09 19:03:22 UTC (rev 81649)
@@ -22,7 +22,7 @@
     return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
 
 setup(name='zope.formlib',
-      version = '3.4.1dev',
+      version = '3.5.0dev',
       url='http://pypi.python.org/pypi/zope.formlib',
       license='ZPL 2.1',
       description='Form generation and validation library for Zope',

Modified: zope.formlib/trunk/src/zope/formlib/form.py
===================================================================
--- zope.formlib/trunk/src/zope/formlib/form.py	2007-11-09 16:44:29 UTC (rev 81648)
+++ zope.formlib/trunk/src/zope/formlib/form.py	2007-11-09 19:03:22 UTC (rev 81649)
@@ -31,8 +31,8 @@
 from zope.interface.interface import InterfaceClass
 from zope.schema.interfaces import IField
 from zope.schema.interfaces import ValidationError
-import zope.security
 from zope.lifecycleevent import ObjectCreatedEvent, ObjectModifiedEvent
+from zope.lifecycleevent import Attributes
 
 import zope.app.container.interfaces
 import zope.app.form.browser.interfaces
@@ -507,11 +507,11 @@
 
     return [error for error in errors if not isinstance(error, NoInputData)]
 
-def applyChanges(context, form_fields, data, adapters=None):
+def applyData(context, form_fields, data, adapters=None):
     if adapters is None:
         adapters = {}
 
-    changed = False
+    descriptions = {}
 
     for form_field in form_fields:
         field = form_field.field
@@ -528,10 +528,13 @@
         name = form_field.__name__
         newvalue = data.get(name, form_field) # using form_field as marker
         if (newvalue is not form_field) and (field.get(adapter) != newvalue):
-            changed = True
+            descriptions.setdefault(interface, []).append(field.__name__)
             field.set(adapter, newvalue)
 
-    return changed
+    return descriptions
+    
+def applyChanges(context, form_fields, data, adapters=None):
+    return bool(applyData(context, form_fields, data, adapters))
 
 _identifier = re.compile('[A-Za-z][a-zA-Z0-9_]*$')
 
@@ -808,8 +811,12 @@
 
     @action(_("Apply"), condition=haveInputWidgets)
     def handle_edit_action(self, action, data):
-        if applyChanges(self.context, self.form_fields, data, self.adapters):
-            zope.event.notify(ObjectModifiedEvent(self.context))
+        descriptions = applyData(self.context, self.form_fields, data,
+                                self.adapters)
+        if descriptions:
+            descriptions = [Attributes(interface, *tuple(keys))
+                           for interface, keys in descriptions.items()]
+            zope.event.notify(ObjectModifiedEvent(self.context, *descriptions))
             formatter = self.request.locale.dates.getFormatter(
                 'dateTime', 'medium')
 

Modified: zope.formlib/trunk/src/zope/formlib/form.txt
===================================================================
--- zope.formlib/trunk/src/zope/formlib/form.txt	2007-11-09 16:44:29 UTC (rev 81648)
+++ zope.formlib/trunk/src/zope/formlib/form.txt	2007-11-09 19:03:22 UTC (rev 81649)
@@ -1802,3 +1802,38 @@
 
   >>> form.applyChanges(blah, form_fields, {'title': 'new'})
   True
+
+
+Event descriptions
+------------------
+
+The ObjectModifiedEvent can be annotated with descriptions about the involved
+schemas and fields. The formlib provides these annotations with the help of the
+applyData function, which returns a list of modification descriptions:
+
+    >>> form.applyData(blah, form_fields, {'title': 'modified'})
+    {<InterfaceClass __builtin__.IFooBar>: ['title']}
+
+The events are annotated with these descriptions. We need a subscriber to log these
+infos:
+
+    >>> def eventLog(event):
+    ...     desc = event.descriptions[0]
+    ...     print 'Modified:', desc.interface.__identifier__, desc.attributes
+    >>> zope.event.subscribers.append(eventLog)
+
+
+    >>> class MyForm(form.EditForm):
+    ...     form_fields = form.FormFields(IFooBar)
+
+    >>> request = TestRequest()
+    >>> request.form['form.title'] = u'again modified'
+    >>> request.form['form.actions.apply'] = u''
+    >>> MyForm(FooBar(), request)()
+    Modified: __builtin__.IFooBar ('title',)
+    ...
+
+Cleanup:
+
+    >>> zope.event.subscribers.remove(eventLog)
+
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.