From 306ca8aa54954ea2623d9e4927a2c07b9efdfea3 Mon Sep 17 00:00:00 2001
From: chris <chris@jalakai.co.uk>
Date: Wed, 5 Jul 2006 03:21:42 +0200
Subject: [PATCH] disabled actions addition to config plugin

This patch adds a new generic settings class, setting_multicheckbox.  The class
displays each of a list of possible choices as a checkbox and an additional text
input field for "other" values.  The final result is saved in the config file as
a comma separated list.

It also supports an additional, optional, parameter, "_combine" which can be used
to group complimentary values, allowing them to be set or unset together with one
checkbox.

darcs-hash:20060705012142-9b6ab-b92daddd1393bfc5e9b650a57348237726957c71.gz
---
 lib/plugins/config/lang/en/lang.php           |   7 +-
 lib/plugins/config/settings/config.class.php  | 128 ++++++++++++++++++
 .../config/settings/config.metadata.php       |  20 ++-
 lib/plugins/config/settings/extra.class.php   |  19 +++
 lib/plugins/config/style.css                  |  22 +++
 5 files changed, 187 insertions(+), 9 deletions(-)

diff --git a/lib/plugins/config/lang/en/lang.php b/lib/plugins/config/lang/en/lang.php
index e0a76da66..5ed638f52 100644
--- a/lib/plugins/config/lang/en/lang.php
+++ b/lib/plugins/config/lang/en/lang.php
@@ -83,14 +83,17 @@ $lang['mailguard']   = 'Obfuscate email addresses';
 
 /* Authentication Options */
 $lang['useacl']      = 'Use access control lists';
-$lang['openregister']= 'Allow everyone to register';
 $lang['autopasswd']  = 'Autogenerate passwords';
-$lang['resendpasswd']= 'Allow resend password';
 $lang['authtype']    = 'Authentication backend';
 $lang['passcrypt']   = 'Password encryption method';
 $lang['defaultgroup']= 'Default group';
 $lang['superuser']   = 'Superuser';
 $lang['profileconfirm'] = 'Confirm profile changes with password';
+$lang['disableactions'] = 'Disable DokuWiki actions';
+$lang['disableactions_check'] = 'Check';
+$lang['disableactions_subscription'] = 'Subscribe/Unsubscribe';
+$lang['disableactions_wikicode'] = 'View source/Export Raw';
+$lang['disableactions_other'] = 'Other actions (comma separated)';
 
 /* Advanced Options */
 $lang['userewrite']  = 'Use nice URLs';
diff --git a/lib/plugins/config/settings/config.class.php b/lib/plugins/config/settings/config.class.php
index 105d6c83a..10c9f4616 100644
--- a/lib/plugins/config/settings/config.class.php
+++ b/lib/plugins/config/settings/config.class.php
@@ -660,6 +660,134 @@ if (!class_exists('setting_no_default')) {
   }
 }
 
+if (!class_exists('setting_multicheckbox')) {
+  class setting_multicheckbox extends setting_string {
+
+    var $_choices = array();
+    var $_combine = array();
+
+    function update($input) {
+        if ($this->is_protected()) return false;
+
+        // split any combined values + convert from array to comma separated string
+        $input = ($input) ? $input : array();        
+        $input = $this->_array2str($input);
+
+        $value = is_null($this->_local) ? $this->_default : $this->_local;
+        if ($value == $input) return false;
+
+        if ($this->_pattern && !preg_match($this->_pattern,$input)) {
+          $this->_error = true;
+          $this->_input = $input;
+          return false;
+        }
+
+        $this->_local = $input;
+        return true;
+    }
+
+    function html(&$plugin, $echo=false) {
+
+        $value = '';
+        $disable = '';
+
+        if ($this->is_protected()) {
+          $value = $this->_protected;
+          $disable = 'disabled="disabled"';
+        } else {
+          if ($echo && $this->_error) {
+            $value = $this->_input;
+          } else {
+            $value = is_null($this->_local) ? $this->_default : $this->_local;
+          }
+        }
+
+        $key = htmlspecialchars($this->_key);
+
+        // convert from comma separated list into array + combine complimentary actions
+        $value = $this->_str2array($value);
+
+        $input = '';
+        foreach ($this->_choices as $choice) {
+          $idx = array_search($choice, $value);
+          $checked = ($idx !== false) ? 'checked="checked"' : '';
+
+          $prompt = ($plugin->getLang($this->_key.'_'.$choice) ?
+                          $plugin->getLang($this->_key.'_'.$choice) : htmlspecialchars($choice));
+
+          $input .= '<div class="selection">'."\n";
+          $input .= '<label for="config__'.$key.'_'.$choice.'">'.$prompt."</label>\n";
+          $input .= '<input id="config__'.$key.'_'.$choice.'" name="config['.$key.'][]" type="checkbox" class="checkbox" value="'.$choice.'" '.$disable.' '.$checked."/>\n";
+          $input .= "</div>\n";
+
+          // remove this action from the disabledactions array
+          if ($idx !== false) unset($value[$idx]);
+        }
+
+        // handle any remaining values
+        $other = join(',',$value);
+
+        $input .= '<div class="other">'."\n";
+        $input .= '<label for="config__'.$key.'_other">'.$plugin->getLang($key.'_other')."</label>\n";
+        $input .= '<input id="config__'.$key.'_other" name="config['.$key.'][other]" type="text" class="edit" value="'.htmlspecialchars($other).'" '.$disable." />\n";
+        $input .= "</div>\n";
+
+        $label = '<label for="config__'.$key.'">'.$this->prompt($plugin).'</label>';
+        return array($label,$input);
+    }
+
+    /**
+     * convert comma separated list to an array and combine any complimentary values
+     */
+    function _str2array($str) {
+      $array = explode(',',$str);
+
+      if (!empty($this->_combine)) {
+        foreach ($this->_combine as $key => $combinators) {
+          $idx = array();
+          foreach ($combinators as $val) {
+            if  (($idx[] = array_search($val, $array)) === false) break;
+          }
+
+          if (count($idx) && $idx[count($idx)-1] !== false) {
+            foreach ($idx as $i) unset($array[$i]);
+            $array[] = $key;
+          }
+        }
+      }
+
+      return $array;
+    }
+
+    /**
+     * convert array of values + other back to a comma separated list, incl. splitting any combined values
+     */
+    function _array2str($input) {
+
+      // handle other
+      $other = trim($input['other']);
+      $other = !empty($other) ? explode(',',str_replace(' ','',$input['other'])) : array();
+      unset($input['other']);
+
+      $array = array_unique(array_merge($input, $other));
+
+      // deconstruct any combinations
+      if (!empty($this->_combine)) {
+       foreach ($this->_combine as $key => $combinators) {
+
+          $idx = array_search($key,$array);
+          if ($idx !== false) {
+            unset($array[$idx]);
+            $array = array_merge($array, $combinators);
+          }
+        }
+      }
+
+      return join(',',array_unique($array));
+    }
+  }
+}
+
 
 /**
  *  Provide php_strip_whitespace (php5 function) functionality
diff --git a/lib/plugins/config/settings/config.metadata.php b/lib/plugins/config/settings/config.metadata.php
index 7ec106fa8..3b8b9d006 100644
--- a/lib/plugins/config/settings/config.metadata.php
+++ b/lib/plugins/config/settings/config.metadata.php
@@ -11,8 +11,8 @@
  *   <handler class id>  is the handler class name without the "setting_" prefix
  *
  * Defined classes:
- *   Generic
- *   -------------
+ *   Generic (source: settings/config.class.php)
+ *   -------------------------------------------
  *   ''             - default class ('setting'), textarea, minimal input validation, setting output in quotes
  *   'string'       - single line text input, minimal input validation, setting output in quotes
  *   'numeric'      - text input, accepts numbers and arithmetic operators, setting output without quotes
@@ -22,15 +22,18 @@
  *   'password'     - password input, minimal input validation, setting output plain text in quotes
  *   'dirchoice'    - as multichoice, selection choices based on folders found at location specified in _dir
  *                    parameter (required)
+ *   'multicheckbox'- a checkbox for each choice plus an "other" string input, config file setting is a comma
+ *                    separated list of checked choices
  *   'fieldset'     - used to group configuration settings, but is not itself a setting. To make this clear in
  *                    the language files the keys for this type should start with '_'.
  *
- *  Single Setting
- *  --------------
+ *  Single Setting (source: settings/extra.class.php)
+ *  -------------------------------------------------
  *   'savedir'     - as 'setting', input tested against initpath() (inc/init.php)
  *   'sepchar'     - as multichoice, selection constructed from string of valid values
  *   'authtype'    - as 'setting', input validated against a valid php file at expected location for auth files
  *   'im_convert'  - as 'setting', input must exist and be an im_convert module
+ *   'disableactions' - as 'setting'
  *
  *  Any setting commented or missing will use 'setting' class - text input, minimal validation, quoted output
  *
@@ -39,9 +42,11 @@
  *                   optional all classes, except onoff, multichoice & dirchoice which ignore it
  *   '_choices'    - array of choices. used to populate a selection box. choice will be replaced by a localised
  *                   language string, indexed by  <setting name>_o_<choice>, if one exists
- *                   required by 'multichoice' class, ignored by other classes
+ *                   required by 'multichoice' & 'multicheckbox' classes, ignored by others
  *   '_dir'        - location of directory to be used to populate choice list
  *                   required by 'dirchoice' class, ignored by other classes
+ *   '_combine'    - complimentary output setting values which can be combined into a single display checkbox
+ *                   optional for 'multicheckbox', ignored by other classes
  *
  * @author    Chris Smith <chris@jalakai.co.uk>
  */
@@ -100,15 +105,16 @@ $meta['refshow']     = array('numeric');
 
 $meta['_authentication'] = array('fieldset');
 $meta['useacl']      = array('onoff');
-$meta['openregister']= array('onoff');
 $meta['autopasswd']  = array('onoff');
-$meta['resendpasswd'] = array('onoff');
 $meta['authtype']    = array('authtype');
 $meta['passcrypt']   = array('multichoice','_choices' => array('smd5','md5','sha1','ssha','crypt','mysql','my411'));
 $meta['defaultgroup']= array('string');
 $meta['superuser']   = array('string');
 $meta['profileconfirm'] = array('onoff');
 $meta['registernotify'] = array('email');
+$meta['disableactions'] = array('disableactions',
+                                '_choices' => array('backlink','index','recent','revisions','search','subscription','register','resendpwd','profile','edit','wikicode','check'),
+                                '_combine' => array('subscription' => array('subscribe','unsubscribe'), 'wikicode' => array('source','export_raw')));
 
 $meta['_anti_spam']  = array('fieldset');
 $meta['usewordblock']= array('onoff');
diff --git a/lib/plugins/config/settings/extra.class.php b/lib/plugins/config/settings/extra.class.php
index 260f32eaf..af97d85a8 100644
--- a/lib/plugins/config/settings/extra.class.php
+++ b/lib/plugins/config/settings/extra.class.php
@@ -79,3 +79,22 @@ if (!class_exists('setting_im_convert')) {
   }
 }
 
+if (!class_exists('setting_disableactions')) {
+  class setting_disableactions extends setting_multicheckbox {
+
+    function html(&$plugin, $echo=false) {
+        global $lang;
+
+        // make some language adjustments (there must be a better way)
+        // transfer some DokuWiki language strings to the plugin
+        if (!$plugin->localised) $this->setupLocale();
+        $plugin->lang[$this->_key.'_revisions'] = $lang['btn_revs'];
+        $plugin->lang[$this->_key.'_register'] = $lang['register'];
+
+        foreach ($this->_choices as $choice)
+          if (isset($lang['btn_'.$choice])) $plugin->lang[$this->_key.'_'.$choice] = $lang['btn_'.$choice];
+
+        return parent::html($plugin, $echo);
+    }
+  }
+}
diff --git a/lib/plugins/config/style.css b/lib/plugins/config/style.css
index 4c72a69cd..d5532e00d 100644
--- a/lib/plugins/config/style.css
+++ b/lib/plugins/config/style.css
@@ -66,4 +66,26 @@
     color: __dark__;
 }
 
+#config__manager .selection {
+  width: 14em;
+  float: left;
+  padding: 1px 0.3em 1px 0;
+}
+
+#config__manager .selection label {
+  float: right;
+  width: 14em;
+  font-size: 90%;
+}
+
+#config__manager .selection input.checkbox {
+  padding-left: 0.7em;
+}
+
+#config__manager .other {
+  clear: both;
+  padding-top: 1em;
+  font-size: 90%;
+}
+
 /* end plugin:configmanager */
-- 
GitLab