From 07b95dc49b31d131b1fecdabf2059a447935c196 Mon Sep 17 00:00:00 2001
From: thomascube <thomas@roundcube.net>
Date: Sun, 06 Feb 2011 17:21:23 -0500
Subject: [PATCH] Delegate contact input validation to rcube_addressbook instance; accept already localized texts in rcube_output::show_message()

---
 program/include/rcube_addressbook.php |   29 +++++++++
 program/include/main.inc              |   13 ++++
 program/include/rcube_json_output.php |    7 -
 program/steps/addressbook/save.inc    |   29 +++------
 program/include/rcmail.php            |   16 +++++
 program/include/rcube_template.php    |    6 -
 program/js/app.js                     |    6 +-
 program/include/rcube_contacts.php    |   22 +++++++
 8 files changed, 97 insertions(+), 31 deletions(-)

diff --git a/program/include/main.inc b/program/include/main.inc
index 697b3ff..155f4af 100644
--- a/program/include/main.inc
+++ b/program/include/main.inc
@@ -84,6 +84,7 @@
  * It's a global wrapper for rcmail::gettext()
  *
  * @param mixed Named parameters array or label name
+ * @param string Domain to search in (e.g. plugin name)
  * @return string Localized text
  * @see rcmail::gettext()
  */
@@ -94,6 +95,18 @@
 
 
 /**
+ * Global wrapper of rcmail::text_exists()
+ * to check whether a text label is defined
+ *
+ * @see rcmail::text_exists()
+ */
+function rcube_label_exists($name, $domain=null)
+{
+  return rcmail::get_instance()->text_exists($name, $domain);
+}
+
+
+/**
  * Overwrite action variable
  *
  * @param string New action value
diff --git a/program/include/rcmail.php b/program/include/rcmail.php
index 8c80fe2..1c98106 100644
--- a/program/include/rcmail.php
+++ b/program/include/rcmail.php
@@ -926,6 +926,22 @@
 
 
   /**
+   * Check if the given text lable exists
+   *
+   * @param string Label name
+   * @return boolean True if text exists (either in the current language or in en_US)
+   */
+  public function text_exists($name, $domain=null)
+  {
+    // load localization files if not done yet
+    if (empty($this->texts))
+      $this->load_language();
+
+    // check for text with domain first
+    return ($domain && isset($this->texts[$domain.'.'.$name])) || isset($this->texts[$name]);
+  }
+
+  /**
    * Load a localization package
    *
    * @param string Language ID
diff --git a/program/include/rcube_addressbook.php b/program/include/rcube_addressbook.php
index c3c8e92..648ef83 100644
--- a/program/include/rcube_addressbook.php
+++ b/program/include/rcube_addressbook.php
@@ -168,6 +168,35 @@
         $this->page_size = (int)$size;
     }
 
+
+    /**
+     * Check the given data before saving.
+     * If input not valid, the message to display can be fetched using get_error()
+     *
+     * @param array Assoziative array with data to save
+     * @return boolean True if input is valid, False if not.
+     */
+    public function validate($save_data)
+    {
+        if (empty($save_data['name'])) {
+            $this->set_error('warning', 'nonamewarning');
+            return false;
+        }
+
+        // check validity of email addresses
+        foreach ($this->get_col_values('email', $save_data, true) as $email) {
+            if (strlen($email)) {
+                if (!check_email(rcube_idn_to_ascii($email))) {
+                    $this->set_error('warning', rcube_label(array('name' => 'emailformaterror', 'vars' => array('email' => $email))));
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+
+
     /**
      * Create a new contact record
      *
diff --git a/program/include/rcube_contacts.php b/program/include/rcube_contacts.php
index 4a4c1e2..9ad4f17 100644
--- a/program/include/rcube_contacts.php
+++ b/program/include/rcube_contacts.php
@@ -396,6 +396,28 @@
 
 
     /**
+     * Check the given data before saving.
+     * If input not valid, the message to display can be fetched using get_error()
+     *
+     * @param array Assoziative array with data to save
+     * @return boolean True if input is valid, False if not.
+     */
+    public function validate($save_data)
+    {
+        // check for name input
+        $valid = parent::validate($save_data);
+
+        // require at least one e-mail address (syntax check is done later in save.inc)
+        if ($valid && !array_filter($this->get_col_values('email', $save_data, true))) {
+            $this->set_error('warning', 'noemailwarning');
+            $valid = false;
+        }
+
+        return $valid;
+    }
+
+
+    /**
      * Create a new contact record
      *
      * @param array Associative array with save data
diff --git a/program/include/rcube_json_output.php b/program/include/rcube_json_output.php
index c6d3c25..d1c9de2 100644
--- a/program/include/rcube_json_output.php
+++ b/program/include/rcube_json_output.php
@@ -170,11 +170,8 @@
     {
         if ($override || !$this->message) {
             $this->message = $message;
-            $this->command(
-                'display_message',
-                rcube_label(array('name' => $message, 'vars' => $vars)),
-                $type
-            );
+            $msgtext = rcube_label_exists($message) ? rcube_label(array('name' => $message, 'vars' => $vars)) : $message;
+            $this->command('display_message', $msgtext, $type);
         }
     }
 
diff --git a/program/include/rcube_template.php b/program/include/rcube_template.php
index 2102aaa..70c175a 100755
--- a/program/include/rcube_template.php
+++ b/program/include/rcube_template.php
@@ -255,10 +255,8 @@
     {
         if ($override || !$this->message) {
             $this->message = $message;
-            $this->command(
-                'display_message',
-                rcube_label(array('name' => $message, 'vars' => $vars)),
-                $type);
+            $msgtext = rcube_label_exists($message) ? rcube_label(array('name' => $message, 'vars' => $vars)) : $message;
+            $this->command('display_message', $msgtext, $type);
         }
     }
 
diff --git a/program/js/app.js b/program/js/app.js
index 84e018f..3c8502d 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -331,7 +331,7 @@
             this.selectedIndex = 0;
           });
 
-          $("input[type='text']").first().focus();
+          $("input[type='text']:visible").first().focus();
         }
         else if (this.gui_objects.qsearchbox) {
           this.enable_command('search', 'reset-search', 'moveto', true);
@@ -646,7 +646,7 @@
               input_name.focus();
               break;
             }
-            else if (input_email.length && !rcube_check_email(input_email.val())) {
+            else if (this.task == 'settings' && input_email.length && !rcube_check_email(input_email.val())) {
               alert(this.get_label('noemailwarning'));
               input_email.focus();
               break;
@@ -3977,7 +3977,7 @@
     
     elem.focus(function(){ ref.focus_textfield(this); })
       .blur(function(){ ref.blur_textfield(this); })
-      .each(function(){ this._placeholder = ref.env.coltypes[col].label; ref.blur_textfield(this); });
+      .each(function(){ this._placeholder = this.title = ref.env.coltypes[col].label; ref.blur_textfield(this); });
   };
 
   this.insert_edit_field = function(col, section, menu)
diff --git a/program/steps/addressbook/save.inc b/program/steps/addressbook/save.inc
index 3d55d95..10155a1 100644
--- a/program/steps/addressbook/save.inc
+++ b/program/steps/addressbook/save.inc
@@ -128,27 +128,18 @@
   }
 }
 
-if (empty($a_record['name']))
-  $a_record['name'] = join(' ', array_filter(array($a_record['prefix'], $a_record['firstname'], $a_record['middlename'], $a_record['surname'], $a_record['suffix'],)));
-
-
-// Basic input checks (TODO: delegate to $CONTACTS instance)
-if (empty($a_record['name'])/* || empty($a_record['email'])*/) {
-  $OUTPUT->show_message('formincomplete', 'warning');
-  rcmail_overwrite_action($return_action);
-  return;
+if (empty($a_record['name'])) {
+    // TODO: let a dedicated function or a plugin compose the full name
+    $a_record['name'] = join(' ', array_filter(array($a_record['prefix'], $a_record['firstname'], $a_record['middlename'], $a_record['surname'], $a_record['suffix'],)));
 }
 
-// Validity checks
-foreach ($CONTACTS->get_col_values('email', $a_record, true) as $email) {
-  if (strlen($email)) {
-    $_email = rcube_idn_to_ascii($email);
-    if (!check_email($_email)) {
-      $OUTPUT->show_message('emailformaterror', 'warning', array('email' => $email));
-      rcmail_overwrite_action($return_action);
-      return;
-    }
-  }
+
+// do input checks (delegated to $CONTACTS instance)
+if (!$CONTACTS->validate($a_record)) {
+    $err = (array)$CONTACTS->get_error() + array('message' => 'formincomplete', 'type' => 'warning');
+    $OUTPUT->show_message($err['message'], $err['type']);
+    rcmail_overwrite_action($return_action);
+    return;
 }
 
 // get raw photo data if changed

--
Gitblit v1.9.1