1<?php
2/**
3 * Federated Login for DokuWiki - manage providers class
4 *
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @link       http://www.dokuwiki.org/plugin:fedauth
7 * @author     Aoi Karasu <aoikarasu@gmail.com>
8 */
9
10/**
11 * Authorization providers management class. Handles all requests from
12 * the admin module and renders the results of current action.
13 *
14 * @author     Aoi Karasu <aoikarasu@gmail.com>
15 */
16class fa_manage extends fa_base {
17
18    /**
19     * Source form/ajax call identifier used with provider lists.
20     */
21    var $listSource = null;
22
23    /**
24     * Creates the class instance bound with the admin plugin and an authorization provider.
25     *
26     * @param objref $manager object reference to the admin plugin
27     * @param string $cmd name of the command to handle
28     * @param string $provid (optional) an authorization provider id
29     */
30    function __construct(&$manager, $cmd, $provid='') {
31        parent::__construct(&$manager, $cmd, $provid);
32    }
33
34    /**
35     * Verifies whether the request contains valid list type.
36     * Used by derived classes to ensure that the request is
37     * related to any of the provider lists.
38     *
39     * @return bool true, if list type is valid
40     */
41    function isValidListSource() {
42        if (is_null($this->listSource)) {
43             $source = strtolower($_REQUEST['source']);
44             $this->listSource = (($source == 'large') || ($source == 'small')) ? $source : null;
45        }
46        return !is_null($this->listSource);
47    }
48
49    /**
50     * Returns a reference to an associative array cotaining the providers
51     * selected by current list source. Use isValidListSource() method first,
52     * to ensure that calling this method won't fail.
53     *
54     * @return arrayref reference to a providers array
55     */
56    function &getProvidersByListSource() {
57        return $this->manager->providers->{'get'.ucfirst($this->listSource)}();
58    }
59
60    /**
61     * Saves the authorization providers cofiguration file.
62     */
63    function saveConfig() {
64        $this->manager->providers->save($_SERVER['REMOTE_USER']);
65
66        // NOTE: Expiring the dokuwiki caches seem to be necessary,
67        //       because Opera and IE9 seem not to refresh the management page
68        //       on reload for changes made using different browser/session.
69        //       Guess what, Firefox and Chrome don't need this!
70
71        // TODO: Find a less intrusive solution.
72
73        global $config_cascade;
74
75        // touching local.php expires wiki page, JS and CSS caches
76        @touch(reset($config_cascade['main']['local']));
77    }
78
79    /**
80     * Performs an action depending on current command (and function).
81     *
82     * @return string the processing result message
83     */
84    function process() {
85        $method = 'process_' . $this->cmd;
86        if (method_exists($this, $method)) {
87            return $this->$method();
88        }
89        $this->success = true;
90        return '';
91    }
92
93    /**
94     * Outputs data for AJAX call.
95     *
96     * @return bool true on success
97     */
98    function ajax() {
99        $method = 'handle_ajax_' . $this->cmd;
100        if (method_exists($this, $method)) {
101            return $this->$method();
102        }
103        return false;
104    }
105
106    /**
107     * Handles AJAX call to display provider details.
108     *
109     * @return bool true on success
110     */
111    function handle_ajax_details() {
112        print $this->_html_details($this->provid);
113        return true;
114    }
115
116    /**
117     * Outputs the XHTML of the management page.
118     */
119    function html() {
120        $out = $this->manager->plugin_locale_xhtml('admproviders');
121        $out = str_replace('@LARGELIST@', $this->html_providers_form(true), $out);
122        $out = str_replace('@SMALLLIST@', $this->html_providers_form(), $out);
123        $out = str_replace('@ADDPROVIDER@', $this->html_add_provider_form(), $out);
124        $out = str_replace('@RESTOREDEFAULTS@', $this->html_restore_defaults_form(), $out);
125        print $out;
126    }
127
128    /**
129     * Renders the form with provider buttons table and action buttons.
130     *
131     * @param bool $large true for providers configured to use large buttons or else small
132     * @return string rendered provider list form
133     */
134    function html_providers_form($large=false) {
135        global $ID;
136
137        $listtype = $large ? 'large' : 'small';
138
139        $out = '<div id="fa__' . $listtype . '" class="sprovs"><form action="'.wl($ID).'" method="post">'
140             . '  <fieldset class="hidden">'
141             . '    <input type="hidden" name="do" value="admin" />'
142             . '    <input type="hidden" name="page" value="fedauth" />'
143             . '    <input type="hidden" name="source" value="' . $listtype . '" />'
144             . formSecurityToken(false)
145             . '  </fieldset>'
146             . '  <div id="axwrap__' . $listtype . '">'
147             . $this->html_providers_list($this->manager->providers->{'get'.ucfirst($listtype)}(), $large)
148             . '  </div>'
149             . '  <fieldset class="buttons">'
150             . '    <input type="submit" class="button" name="fa[toggle]" value="' . $this->lang['btn_toggle'] . '" />'
151             . '  </fieldset>'
152             . '</form></div>';
153        return $out;
154    }
155
156    /**
157     * Renders the form for adding a custom authorization provider.
158     */
159    function html_add_provider_form() {
160        return '<b>WARNING:</b> This version does not support adding custom providers.';
161    }
162
163    /**
164     * Renders the form for restoring the default settings.
165     */
166    function html_restore_defaults_form() {
167        global $ID;
168
169        $out = '<div id="fa__restore"><form action="'.wl($ID).'" method="post">'
170             . '  <fieldset class="hidden">'
171             . '    <input type="hidden" name="do" value="admin" />'
172             . '    <input type="hidden" name="page" value="fedauth" />'
173             . '    <input type="hidden" name="source" value="restore" />'
174             . formSecurityToken(false)
175             . '  </fieldset>'
176             . '  <fieldset class="buttons">'
177             . '    <input type="submit" class="button" name="fa[restore]" value="' . $this->lang['btn_restore'] . '" />'
178             . '  </fieldset>'
179             . '</form></div>';
180        return $out;
181    }
182
183    function html_providers_list(&$source, $large=false) {
184        if (!is_array($source)) return '';
185
186        $out = '';
187        $even = false;
188
189        foreach ($source as $id => $pro) {
190
191            $protected = false;
192
193            $class = array();
194            if (!$pro->isEnabled()) $class[] = 'disabled';
195            if ($even = !$even) $class[] = 'even';
196            $class = count($class) ? ' class="'.join('', $class).'"' : '';
197
198            $checked = $pro->isEnabled() ? ' checked="checked"' : '';
199            $check_disabled = ($protected) ? ' disabled="disabled"' : '';
200
201            // this might need ajax disable check
202            $details = ($this->cmd == 'details' && $this->provid == $id) ? $this->_html_details($id, true) : '';
203
204            $out .= '    <fieldset'.$class.'>'
205                 .  '      <legend>'.$id.'</legend>'
206                 .  '      <input type="checkbox" class="enable" name="toggle[]" id="dw__p_'.$id.'" value="'.$id.'"'.$checked.$check_disabled.' />'
207                 .  '      <div class="legend"><label for="dw__p_'.$id.'">'.$pro->getImageXHTML().$pro->getName().'</label>'.(!$pro->isEnabled()?'<span class="disabled">('.$this->lang['disabled'].')</span>':'')
208                 .  '      <div id="fa__det_'.$id.'">'.$details.'</div></div>'
209                 .  $this->_html_button($id, 'details', false, 6)
210                 .  $this->_html_button($id, 'moveup', $this->manager->providers->isFirst($id), 6)
211                 .  $this->_html_button($id, 'movedn', $this->manager->providers->isLast($id), 6)
212                 .  $this->_html_button($id, $large ? 'usesmall' : 'uselarge', false, 6)
213                 .  $this->_html_button($id, 'remove', !$pro->isRemovable(), 6)
214                 .  '    </fieldset>';
215            //$out .= "<h2>$id</h2><pre>" . print_r($pro, true) . "</pre>";
216        }
217        return $out;
218    }
219
220    function _html_button($provid, $btn, $disabled=false, $indent=0, $class='') {
221        $disabled = ($disabled) ? 'disabled="disabled"' : '';
222        return str_repeat(' ', $indent)
223            . '<input type="submit" class="button '.$class.'" '.$disabled.' name="fa['.$btn.']['.$provid.']" title="'.$this->lang['btn_'.$btn].'" value="'.$this->lang['btn_'.$btn].'" />';
224    }
225
226    function _html_details($provid, $forcevisible=false) {
227        $fv = $forcevisible ? ' style="display: block;"' : '';
228        $pro =& $this->manager->providers->get($provid);
229        return '<div class="details"'.$fv.'><b>ID:</b> '.$provid.'<br/><b>'.$this->lang['serviceurl'].':</b> '.$pro->getURL().'<br/>'
230               .$pro->getImageXHTML(PROV_LARGE,'imgdetails').' 80x40 '.$pro->getImageXHTML(PROV_SMALL,'imgdetails').' 16x16</div>';
231    }
232
233    function _json_buttoninfo($cmd) {
234        return sprintf('{"success":1,"name":"fa[%s][%s]","title":"%s","value":"%s"}',
235            $cmd, $this->provid, $this->lang['btn_'.$cmd], $this->lang['btn_'.$cmd]);
236    }
237
238} /* fa_manage */
239
240/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
241