1<?php
2/**
3 * Class helper_plugin_bureaucracyau_fieldfieldset
4 *
5 * Creates a new set of fields, which optional can be shown/hidden depending on the value of another field above it.
6 */
7class helper_plugin_bureaucracyau_fieldfieldset extends helper_plugin_bureaucracyau_field {
8    protected $mandatory_args = 1;
9    /** @var array with zero, one entry (fieldname) or two entries (fieldname and match value) */
10    public $depends_on = array();
11
12    /**
13     * Arguments:
14     *  - cmd
15     *  - label (optional)
16     *  - field name where switching depends on (optional)
17     *  - match value (optional)
18     *
19     * @param array $args The tokenized definition, only split at spaces
20     */
21    public function initialize($args) {
22        // get standard arguments
23        $this->opt = array('cmd' => array_shift($args));
24
25        if (count($args) > 0) {
26            $this->opt['label'] = array_shift($args);
27            $this->opt['display'] = $this->opt['label'];
28
29            $this->depends_on = $args;
30        }
31    }
32
33    /**
34     * Render the top of the fieldset as XHTML
35     *
36     * @param array     $params Additional HTML specific parameters
37     * @param Doku_Form $form   The target Doku_Form object
38     * @param int       $formid unique identifier of the form which contains this field
39     */
40    function renderfield($params, Doku_Form $form, $formid) {
41        $form->startFieldset(hsc($this->getParam('display')));
42        if (!empty($this->depends_on)) {
43            $dependencies = array_map('hsc',(array) $this->depends_on);
44            if (count($this->depends_on) > 1) {
45                $msg = 'Only edit this fieldset if ' .
46                       '“<span class="bureaucracyau_depends_fname">%s</span>” '.
47                       'is set to “<span class="bureaucracyau_depends_fvalue">%s</span>”.';
48            } else {
49                $msg = 'Only edit this fieldset if ' .
50                       '“<span class="bureaucracyau_depends_fname">%s</span>” is set.';
51            }
52
53            $form->addElement('<p class="bureaucracyau_depends">' . vsprintf($msg, $dependencies) . '</p>');
54        }
55    }
56
57    /**
58     * Handle a post to the fieldset
59     *
60     * When fieldset is closed, set containing fields to hidden
61     *
62     * @param null $value field value of fieldset always empty
63     * @param helper_plugin_bureaucracyau_field[] $fields (reference) form fields (POST handled upto $this field)
64     * @param int    $index  index number of field in form
65     * @param int    $formid unique identifier of the form which contains this field
66     * @return bool Whether the passed value is valid
67     */
68    public function handle_post($value, &$fields, $index, $formid) {
69        if(empty($this->depends_on)) {
70            return true;
71        }
72
73        // search the field where fieldset depends on in fields before fieldset
74        $hidden = false;
75        for ($n = 0 ; $n < $index; ++$n) {
76            $field = $fields[$n];
77            if ($field->getParam('label') != $this->depends_on[0]) {
78                continue;
79            }
80            if(count($this->depends_on) > 1) {
81                $hidden = $field->getParam('value') != $this->depends_on[1];
82            } else {
83                $hidden = !$field->isSet_();
84            }
85            break;
86        }
87        // mark fields after this fieldset as hidden
88        if ($hidden) {
89            $this->hidden = true;
90            for ($n = $index + 1 ; $n < count($fields) ; ++$n) {
91                $field = $fields[$n];
92                if ($field->getFieldType() === 'fieldset') {
93                    break;
94                }
95                $field->hidden = true;
96            }
97        }
98        return true;
99    }
100
101    /**
102     * Get an arbitrary parameter
103     *
104     * @param string $name
105     * @return mixed|null
106     */
107    function getParam($name) {
108        if($name === 'value') {
109            return null;
110        } else {
111            return parent::getParam($name);
112        }
113    }
114}
115