From b641405587604b3a60a54a316f0e1f0d3d838ec0 Mon Sep 17 00:00:00 2001
From: Ivan Tyagov <ivan@nexedi.com>
Date: Fri, 20 May 2011 15:28:40 +0300
Subject: [PATCH] Enable "Tales" definitions for captcha form field.

---
 product/ERP5Form/CaptchaField.py             | 95 ++++++++++++++++----
 product/ERP5Form/dtml/captchaFieldTales.dtml | 92 +++++++++++++++++++
 2 files changed, 171 insertions(+), 16 deletions(-)
 create mode 100644 product/ERP5Form/dtml/captchaFieldTales.dtml

diff --git a/product/ERP5Form/CaptchaField.py b/product/ERP5Form/CaptchaField.py
index 6612c6d3d7..713257a826 100644
--- a/product/ERP5Form/CaptchaField.py
+++ b/product/ERP5Form/CaptchaField.py
@@ -34,6 +34,7 @@ from Products.Formulator.Errors import ValidationError
 from Products.PageTemplates.PageTemplateFile import PageTemplateFile
 from AccessControl import ClassSecurityInfo
 from Products.ERP5Type.Globals import DTMLFile
+from Products.Formulator.TALESField import TALESField
 import CaptchasDotNet
 import string
 import random
@@ -66,6 +67,7 @@ class CaptchasDotNetProvider(object):
   def getImageGenerator (self, field):
     captchas_client = field.get_value("captcha_dot_net_client") or "demo"
     captchas_secret = field.get_value("captcha_dot_net_secret") or "secret"
+    print "--", captchas_client, captchas_secret
     return CaptchasDotNet.CaptchasDotNet(client = captchas_client, secret = captchas_secret)
   
   def generate(self, field):
@@ -77,19 +79,26 @@ class CaptchasDotNetProvider(object):
     image_generator = self.getImageGenerator(field)
     return image_generator.image(captcha_key, "__captcha_" + md5.new(captcha_key).hexdigest())
 
+  # dynamic fields
+  _dynamic_property_list = [dict(id='captcha_dot_net_client',
+                                 title='Captchas.net client login',
+                                 description='Your login on captchas.net to get the pictures.',
+                                 default="demo",
+                                 size=32,
+                                 required=0),
+                            dict(id='captcha_dot_net_secret',
+                                 title='Captchas.net client secret',
+                                 description='Your secret on captchas.net to get the pictures.',
+                                 default="secret",
+                                 size=32,
+                                 required=0)]
   def getExtraPropertyList(self):
-    return [fields.StringField('captcha_dot_net_client',
-                               title='Captchas.net client login',
-                               description='Your login on captchas.net to get the pictures.',
-                               default="demo",
-                               size=32,
-                               required=0),
-            fields.PasswordField('captcha_dot_net_secret',
-                               title='Captchas.net client secret',
-                               description='Your secret on captchas.net to get the pictures.',
-                               default="secret",
-                               size=32,
-                               required=0)]
+    return [fields.StringField(**self._dynamic_property_list[0]),
+            fields.PasswordField(**self._dynamic_property_list[1])]    
+
+  def getExtraTalesPropertyList(self):
+    return [TALESField(**self._dynamic_property_list[0]),
+            TALESField(**self._dynamic_property_list[1])]                           
 
 class NumericCaptchaProvider(object):
 
@@ -122,6 +131,9 @@ class NumericCaptchaProvider(object):
   def getExtraPropertyList(self):
     return []
 
+  def getExtraTalesPropertyList(self):
+    return []
+
 class CaptchaProviderFactory(object):
   @staticmethod
   def getProvider(name):
@@ -164,9 +176,7 @@ class CaptchaWidget(Widget.TextWidget):
 
   captcha_type = fields.ListField('captcha_type',
                                    title='Captcha type',
-                                   description=(
-        "The type of captcha you want to use."
-        ""),
+                                   description=("The type of captcha you want to use."),
                                    default=CaptchaProviderFactory.getDefaultProvider(),
                                    required=1,
                                    size=1,
@@ -314,4 +324,57 @@ class CaptchaField(ZMIField):
     extraPropertyList = captcha_provider.getExtraPropertyList()
     self.__extraPropertyList = [x.id for x in extraPropertyList]
     return extraPropertyList
-    
+
+
+
+  security.declareProtected('View management screens', 'manage_talesForm')
+  manage_talesForm = DTMLFile('dtml/captchaFieldTales', globals())
+
+  security.declareProtected('Change Formulator Forms', 'manage_tales')
+  def manage_tales(self, REQUEST):
+    """Change TALES expressions.
+    """
+    result = {}
+    # add dynamic form fields for captcha
+    #captcha_provider = CaptchaProviderFactory.getProvider(self.get_value("captcha_type"))
+    for field in self.getCaptchaCustomTalesPropertyList():
+      try:
+        # validate the form and get results
+        result[field.id] = field.validate(REQUEST)
+      except ValidationError, err:
+        if REQUEST:
+          message = "Error: %s - %s" % (err.field.get_value('title'),
+                                        err.error_text)
+          return self.manage_talesForm(self, REQUEST,
+                                  manage_tabs_message=message)
+        else:
+          raise
+      
+    # standard tales form fields
+    try:
+      # validate the form and get results
+      result.update(self.tales_form.validate(REQUEST))
+    except ValidationError, err:
+      if REQUEST:
+        message = "Error: %s - %s" % (err.field.get_value('title'),
+                                      err.error_text)
+        return self.manage_talesForm(self,REQUEST,
+                                     manage_tabs_message=message)
+      else:
+        raise
+    self._edit_tales(result)
+
+    if REQUEST:
+      message="Content changed."
+      return self.manage_talesForm(self, REQUEST,
+                                   manage_tabs_message=message)
+                                     
+  def getCaptchaCustomTalesPropertyList(self):
+    if hasattr(self, "__extraTalesPropertyList"):
+      return self.__extraTalesPropertyList
+    captcha_type = ZMIField.get_value(self, "captcha_type")
+    captcha_provider = CaptchaProviderFactory.getProvider(captcha_type)
+    extraPropertyList = captcha_provider.getExtraTalesPropertyList()
+    self.__extraTalesPropertyList = [x.id for x in extraPropertyList]
+    return extraPropertyList                                     
+  
\ No newline at end of file
diff --git a/product/ERP5Form/dtml/captchaFieldTales.dtml b/product/ERP5Form/dtml/captchaFieldTales.dtml
new file mode 100644
index 0000000000..3c40ac39ab
--- /dev/null
+++ b/product/ERP5Form/dtml/captchaFieldTales.dtml
@@ -0,0 +1,92 @@
+<dtml-var manage_page_header>
+<dtml-var manage_tabs>
+
+<p class="form-help">
+Edit <dtml-var meta_type> method TALES expressions here.
+<dtml-if "not isTALESAvailable()"><br>
+<span style="color: #FF0000;">
+Zope Page Templates and therefore TALES is not installed.
+This tab can therefore not be used.
+</span>
+</dtml-if>
+</p>
+
+<form action="manage_tales" method="POST">
+<table cellspacing="0" cellpadding="2" border="0">
+
+<dtml-in "override_form.get_groups()">
+<dtml-let group=sequence-item fields="tales_form.get_fields_in_group(group)">
+
+<dtml-if fields>
+<tr>
+<td colspan="3" class="form-title">
+  <dtml-var "_.string.capitalize(group)"> properties
+</td>
+</tr>
+
+<dtml-var fieldListHeader>
+
+<dtml-let current_field="this()">
+<dtml-in fields>
+<dtml-let field=sequence-item field_id="field.id"
+          value="current_field.get_tales(field.id)">
+  <tr>
+    <td align="left" valign="top">
+    <div class="form-label">
+    <dtml-var "field.title()">
+    </div>
+    </td>
+    <td align="left" valign="top">
+    <dtml-var "field.render(value)">
+    </td>
+    <td valign="top"><div class="form-element">
+    <dtml-var "current_field.form.get_field(field.id).meta_type">
+    </div></td>
+  </tr>
+</dtml-let>
+</dtml-in>
+</dtml-let>
+</dtml-if>
+</dtml-let>
+</dtml-in>
+
+
+<!-- Then, display captcha-specific properties -->
+<dtml-let current_field="this()">
+<dtml-in "this().getCaptchaCustomTalesPropertyList()" prefix="captcha">
+
+<dtml-var expr="captcha_item">
+
+  <dtml-let field="captcha_item" 
+            value="current_field.get_tales(field.id)">
+    <tr>
+      <td align="left" valign="top">
+      <div class="form-label">
+      <dtml-var "field.title()">
+      </div>
+      </td>
+      <td align="left" valign="top">
+      <dtml-var "field.render(value)">
+      </td>
+      <td><div class="form-element">
+      <dtml-var "field.meta_type">
+      </div></td>
+    </tr>
+  </dtml-let>
+  
+</dtml-in>
+</dtml-let>
+
+
+  <tr>
+    <td align="left" valign="top">
+    <div class="form-element">
+    <input class="form-element" type="submit" name="submit" 
+     value="Save Changes" /> 
+    </div>
+    </td>
+  </tr>
+</table>
+</form>
+
+<dtml-var manage_page_footer>
-- 
2.30.9