xref: /plugin/struct/helper/field.php (revision 1ca21e1738d74322247805adf021b3ed01d82538)
1ed3de3d6SAndreas Gohr<?php
2d6d97f60SAnna Dabrowska
3ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\Column;
4ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\Schema;
5ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\StructException;
6ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\Value;
793ca6f4fSAndreas Gohruse dokuwiki\plugin\struct\meta\ValueValidator;
8e46eaffdSSzymon Olewniczakuse dokuwiki\plugin\struct\types\Lookup;
9d1482d40SAnna Dabrowskause dokuwiki\plugin\struct\types\Page;
10ed3de3d6SAndreas Gohr
11ed3de3d6SAndreas Gohr/**
123ad9c1eaSAndreas Gohr * Allows adding a single struct field as a bureaucracy field
133ad9c1eaSAndreas Gohr *
143ad9c1eaSAndreas Gohr * This class is used when a field of the type struct_field is encountered in the
153ad9c1eaSAndreas Gohr * bureaucracy syntax.
16ed3de3d6SAndreas Gohr */
17d6d97f60SAnna Dabrowskaclass helper_plugin_struct_field extends helper_plugin_bureaucracy_field
18d6d97f60SAnna Dabrowska{
193ad9c1eaSAndreas Gohr    /** @var  Column */
203ad9c1eaSAndreas Gohr    public $column;
21ed3de3d6SAndreas Gohr
223ad9c1eaSAndreas Gohr    /**
233ad9c1eaSAndreas Gohr     * Initialize the appropriate column
243ad9c1eaSAndreas Gohr     *
253ad9c1eaSAndreas Gohr     * @param array $args
263ad9c1eaSAndreas Gohr     */
27d6d97f60SAnna Dabrowska    public function initialize($args)
28d6d97f60SAnna Dabrowska    {
2989be912bSSzymon Olewniczak        $this->init($args);
30ed3de3d6SAndreas Gohr
313ad9c1eaSAndreas Gohr        // find the column
323ad9c1eaSAndreas Gohr        try {
333ad9c1eaSAndreas Gohr            $this->column = $this->findColumn($this->opt['label']);
343ad9c1eaSAndreas Gohr        } catch (StructException $e) {
353ad9c1eaSAndreas Gohr            msg(hsc($e->getMessage()), -1);
363ad9c1eaSAndreas Gohr        }
3789be912bSSzymon Olewniczak
3889be912bSSzymon Olewniczak        $this->standardArgs($args);
393ad9c1eaSAndreas Gohr    }
403ad9c1eaSAndreas Gohr
413ad9c1eaSAndreas Gohr    /**
426c71c031SAndreas Gohr     * Sets the value and validates it
433ad9c1eaSAndreas Gohr     *
446c71c031SAndreas Gohr     * @param mixed $value
456c71c031SAndreas Gohr     * @return bool value was set successfully validated
463ad9c1eaSAndreas Gohr     */
47d6d97f60SAnna Dabrowska    protected function setVal($value)
48d6d97f60SAnna Dabrowska    {
496c71c031SAndreas Gohr        if (!$this->column) {
506c71c031SAndreas Gohr            $value = '';
51131fd507SSzymon Olewniczak            //don't validate placeholders here
52131fd507SSzymon Olewniczak        } elseif ($this->replace($value) == $value) {
5393ca6f4fSAndreas Gohr            $validator = new ValueValidator();
546c71c031SAndreas Gohr            $this->error = !$validator->validateValue($this->column, $value);
556c71c031SAndreas Gohr            if ($this->error) {
566c71c031SAndreas Gohr                foreach ($validator->getErrors() as $error) {
576c71c031SAndreas Gohr                    msg(hsc($error), -1);
586c71c031SAndreas Gohr                }
596c71c031SAndreas Gohr            }
606c71c031SAndreas Gohr        }
616c71c031SAndreas Gohr
626c71c031SAndreas Gohr        if ($value === array() || $value === '') {
636c71c031SAndreas Gohr            if (!isset($this->opt['optional'])) {
646c71c031SAndreas Gohr                $this->error = true;
652e0e9347SSzymon Olewniczak                if ($this->column) {
662e0e9347SSzymon Olewniczak                    $label = $this->column->getTranslatedLabel();
672e0e9347SSzymon Olewniczak                } else {
682e0e9347SSzymon Olewniczak                    $label = $this->opt['label'];
692e0e9347SSzymon Olewniczak                }
702e0e9347SSzymon Olewniczak                msg(sprintf($this->getLang('e_required'), hsc($label)), -1);
716c71c031SAndreas Gohr            }
726c71c031SAndreas Gohr        }
736c71c031SAndreas Gohr
746c71c031SAndreas Gohr        $this->opt['value'] = $value;
756c71c031SAndreas Gohr        return !$this->error;
763ad9c1eaSAndreas Gohr    }
773ad9c1eaSAndreas Gohr
783ad9c1eaSAndreas Gohr    /**
793ad9c1eaSAndreas Gohr     * Creates the HTML for the field
803ad9c1eaSAndreas Gohr     *
813ad9c1eaSAndreas Gohr     * @param array $params
823ad9c1eaSAndreas Gohr     * @param Doku_Form $form
833ad9c1eaSAndreas Gohr     * @param int $formid
843ad9c1eaSAndreas Gohr     */
85d6d97f60SAnna Dabrowska    public function renderfield($params, Doku_Form $form, $formid)
86d6d97f60SAnna Dabrowska    {
873ad9c1eaSAndreas Gohr        if (!$this->column) return;
883ad9c1eaSAndreas Gohr
893ad9c1eaSAndreas Gohr        // this is what parent does
903ad9c1eaSAndreas Gohr        $this->_handlePreload();
913ad9c1eaSAndreas Gohr        if (!$form->_infieldset) {
923ad9c1eaSAndreas Gohr            $form->startFieldset('');
933ad9c1eaSAndreas Gohr        }
943ad9c1eaSAndreas Gohr        if ($this->error) {
953ad9c1eaSAndreas Gohr            $params['class'] = 'bureaucracy_error';
963ad9c1eaSAndreas Gohr        }
973ad9c1eaSAndreas Gohr
983ad9c1eaSAndreas Gohr        // output the field
99d1482d40SAnna Dabrowska        $value = $this->createValue();
10095838d50SAndreas Gohr        $field = $this->makeField($value, $params['name']);
1013ad9c1eaSAndreas Gohr        $form->addElement($field);
1023ad9c1eaSAndreas Gohr    }
1033ad9c1eaSAndreas Gohr
10495838d50SAndreas Gohr    /**
105d1482d40SAnna Dabrowska     * Returns a Value object for the current column.
106d1482d40SAnna Dabrowska     * Special handling for Page and Lookup literal form values.
107d1482d40SAnna Dabrowska     *
108d1482d40SAnna Dabrowska     * @return Value
109d1482d40SAnna Dabrowska     */
110d1482d40SAnna Dabrowska    protected function createValue()
111d1482d40SAnna Dabrowska    {
112d1482d40SAnna Dabrowska        $preparedValue = $this->opt['value'];
113d1482d40SAnna Dabrowska
114d1482d40SAnna Dabrowska        // page fields might need to be JSON encoded depending on usetitles config
115d1482d40SAnna Dabrowska        if (
116d1482d40SAnna Dabrowska            $this->column->getType() instanceof Page
117d1482d40SAnna Dabrowska            && $this->column->getType()->getConfig()['usetitles']
118d1482d40SAnna Dabrowska        ) {
119d1482d40SAnna Dabrowska            $preparedValue = json_encode([$this->opt['value'], null]);
120d1482d40SAnna Dabrowska        }
121d1482d40SAnna Dabrowska
122d1482d40SAnna Dabrowska        $value = new Value($this->column, $preparedValue);
123d1482d40SAnna Dabrowska
124d1482d40SAnna Dabrowska        // no way to pass $israw parameter to constructor, so re-set the Lookup value
125d1482d40SAnna Dabrowska        if ($this->column->getType() instanceof Lookup) {
126d1482d40SAnna Dabrowska            $value->setValue($preparedValue, true);
127d1482d40SAnna Dabrowska        }
128d1482d40SAnna Dabrowska
129d1482d40SAnna Dabrowska        return $value;
130d1482d40SAnna Dabrowska    }
131d1482d40SAnna Dabrowska
132d1482d40SAnna Dabrowska    /**
13395838d50SAndreas Gohr     * Create the input field
13495838d50SAndreas Gohr     *
13595838d50SAndreas Gohr     * @param Value $field
13695838d50SAndreas Gohr     * @param String $name field's name
13795838d50SAndreas Gohr     * @return string
13895838d50SAndreas Gohr     */
139d6d97f60SAnna Dabrowska    protected function makeField(Value $field, $name)
140d6d97f60SAnna Dabrowska    {
14195838d50SAndreas Gohr        $trans = hsc($field->getColumn()->getTranslatedLabel());
14295838d50SAndreas Gohr        $hint = hsc($field->getColumn()->getTranslatedHint());
14395838d50SAndreas Gohr        $class = $hint ? 'hashint' : '';
14495838d50SAndreas Gohr        $lclass = $this->error ? 'bureaucracy_error' : '';
14595838d50SAndreas Gohr        $colname = $field->getColumn()->getFullQualifiedLabel();
146*1ca21e17SAnna Dabrowska        $required = !empty($this->opt['optional']) ? '' : ' <sup>*</sup>';
14795838d50SAndreas Gohr
1485275870bSAnna Dabrowska        $id = uniqid('struct__', true);
149ee983135SMichael Große        $input = $field->getValueEditor($name, $id);
15095838d50SAndreas Gohr
151ee983135SMichael Große        $html = '<div class="field">';
152ee983135SMichael Große        $html .= "<label class=\"$lclass\" data-column=\"$colname\" for=\"$id\">";
15395838d50SAndreas Gohr        $html .= "<span class=\"label $class\" title=\"$hint\">$trans$required</span>";
15495838d50SAndreas Gohr        $html .= '</label>';
155ee983135SMichael Große        $html .= "<span class=\"input\">$input</span>";
156ee983135SMichael Große        $html .= '</div>';
15795838d50SAndreas Gohr
15895838d50SAndreas Gohr        return $html;
15995838d50SAndreas Gohr    }
16095838d50SAndreas Gohr
1613ad9c1eaSAndreas Gohr    /**
1623ad9c1eaSAndreas Gohr     * Tries to find the correct column and schema
1633ad9c1eaSAndreas Gohr     *
1643ad9c1eaSAndreas Gohr     * @param string $colname
165ba766201SAndreas Gohr     * @return \dokuwiki\plugin\struct\meta\Column
1660549dcc5SAndreas Gohr     * @throws StructException
1673ad9c1eaSAndreas Gohr     */
168d6d97f60SAnna Dabrowska    protected function findColumn($colname)
169d6d97f60SAnna Dabrowska    {
1703ad9c1eaSAndreas Gohr        list($table, $label) = explode('.', $colname, 2);
1713ad9c1eaSAndreas Gohr        if (!$table || !$label) {
1723ad9c1eaSAndreas Gohr            throw new StructException('Field \'%s\' not given in schema.field form', $colname);
1733ad9c1eaSAndreas Gohr        }
1743ad9c1eaSAndreas Gohr        $schema = new Schema($table);
1753ad9c1eaSAndreas Gohr        return $schema->findColumn($label);
1763ad9c1eaSAndreas Gohr    }
1773ad9c1eaSAndreas Gohr
1783ad9c1eaSAndreas Gohr    /**
1793ad9c1eaSAndreas Gohr     * This ensures all language strings are still working
1803ad9c1eaSAndreas Gohr     *
1813ad9c1eaSAndreas Gohr     * @return string always 'bureaucracy'
1823ad9c1eaSAndreas Gohr     */
183d6d97f60SAnna Dabrowska    public function getPluginName()
184d6d97f60SAnna Dabrowska    {
1853ad9c1eaSAndreas Gohr        return 'bureaucracy';
1863ad9c1eaSAndreas Gohr    }
187ed3de3d6SAndreas Gohr}
188