FormHelper::_addFormArrayProvider()   A
last analyzed

Complexity

Conditions 3
Paths 1

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 3
nc 1
nop 0
1
<?php
2
/**
3
 * CakeCMS Core
4
 *
5
 * This file is part of the of the simple cms based on CakePHP 3.
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 *
9
 * @package     Core
10
 * @license     MIT
11
 * @copyright   MIT License http://www.opensource.org/licenses/mit-license.php
12
 * @link        https://github.com/CakeCMS/Core".
13
 * @author      Sergey Kalistratov <[email protected]>
14
 */
15
16
namespace Core\View\Helper;
17
18
use Cake\Form\Form;
19
use Cake\View\View;
20
use JBZoo\Data\Data;
21
use JBZoo\Utils\Arr;
22
use JBZoo\Utils\Str;
23
use Cake\View\Helper;
24
use Cake\Utility\Hash;
25
use Cake\Core\Configure;
26
use Core\View\Form\FormContext;
27
use Cake\Collection\Collection;
28
use Core\View\Form\ArrayContext;
29
use Core\View\Form\EntityContext;
30
use Cake\Datasource\EntityInterface;
31
use Core\View\Helper\Traits\HelperTrait;
32
use Core\View\Helper\Traits\MaterializeCssTrait;
33
use Cake\View\Helper\FormHelper as CakeFormHelper;
34
35
/**
36
 * Class FormHelper
37
 *
38
 * @package     Core\View\Helper
39
 * @property    \Core\View\Helper\UrlHelper $Url
40
 * @property    \Core\View\Helper\HtmlHelper $Html
41
 */
42
class FormHelper extends CakeFormHelper
43
{
44
45
    use HelperTrait, MaterializeCssTrait;
46
47
    /**
48
     * List of helpers used by this helper.
49
     *
50
     * @var array
51
     */
52
    public $helpers = [
53
        'Url'  => ['className' => 'Core.Url'],
54
        'Html' => ['className' => 'Core.Html'],
55
    ];
56
57
    /**
58
     * Hold js form type.
59
     *
60
     * @var bool
61
     */
62
    protected $_isJsForm = false;
63
64
    /**
65
     * HtmlHelper constructor.
66
     *
67
     * @param   View $View
68
     * @param   array $config
69
     */
70
    public function __construct(View $View, array $config = [])
71
    {
72
        $this->_defaultConfig = Hash::merge([
73
            'materializeCss' => false,
74
            'btnPref'        => Configure::read('Cms.btnPref'),
75
            'iconPref'       => Configure::read('Cms.iconPref'),
76
            'classPrefix'    => Configure::read('Cms.classPrefix'),
77
        ], $this->_defaultConfig);
78
79
        $config = new Data($config);
80
81
        if ($config->get('materializeCss', false) === true) {
82
            $config
83
                ->set('widgets', [
84
                    'file'     => 'Core\View\Widget\MaterializeCss\FileWidget',
85
                    'textarea' => 'Core\View\Widget\MaterializeCss\TextareaWidget',
86
                    'checkbox' => 'Core\View\Widget\MaterializeCss\CheckboxWidget'
87
                ])
88
                ->set('templates', 'Core.templates/materialize_css_form')
89
                ->set('prepareBtnClass', function (Helper $form, $options, $button) {
90
                    return $this->_prepareBtn($form, $options, $button);
91
                })
92
                ->set('prepareTooltip', function (Helper $html, $options, $tooltip) {
93
                    return $this->_prepareTooltip($html, $options, $tooltip);
94
                });
95
        }
96
97
        $widgets = Hash::merge(['_default' => 'Core\View\Widget\BasicWidget'], $config->get('widgets', []));
98
99
        $config->set('widgets', $widgets);
100
101
        parent::__construct($View, $config->getArrayCopy());
102
    }
103
104
    /**
105
     * Creates file input widget.
106
     *
107
     * @param   string $fieldName Name of a field, in the form "modelname.fieldname"
108
     * @param   array $options Array of HTML attributes.
109
     *
110
     * @return  string A generated file input.
111
     */
112
    public function file($fieldName, array $options = [])
113
    {
114
        $errorSuffix = null;
115
        $error       = $this->error($fieldName);
116
        $content     = parent::file($fieldName, $options);
117
118
        if ($this->getConfig('materializeCss', false) === false) {
119
            return $content;
120
        }
121
122
        $options = $this->_parseOptions($fieldName, $options);
123
124
        $options['type'] = __FUNCTION__;
125
        if ($error !== '') {
126
            $options['error'] = $error;
127
            $errorSuffix = 'Error';
128
        }
129
130
        $result = $this->_inputContainerTemplate([
131
            'error'       => $error,
132
            'content'     => $content,
133
            'options'     => $options,
134
            'errorSuffix' => $errorSuffix
135
        ]);
136
137
        return $result;
138
    }
139
140
    /**
141
     * Form switcher.
142
     *
143
     * @param   string $fieldName
144
     * @param   array $options
145
     * @return  string
146
     */
147
    public function switcher($fieldName, array $options = [])
148
    {
149
        $input = parent::checkbox($fieldName, $options);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (checkbox() instead of switcher()). Are you sure this is correct? If so, you might want to change this to $this->checkbox().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
150
151
        if ($this->getConfig('materializeCss', false) === false) {
152
            return $input;
153
        }
154
155
        $options += [
156
            'before' => __d('backend', 'Off'),
157
            'after'  => __d('backend', 'On')
158
        ];
159
160
        $title = (Arr::key('title', $options)) ? $options['title'] : $fieldName;
161
162
        if (!empty($title)) {
163
            $title = $this->Html->div('switch-title', $title);
164
        }
165
166
        $content = $this->formatTemplate(__FUNCTION__, [
167
            'input'  => $input,
168
            'title'  => $title,
169
            'after'  => $options['after'],
170
            'before' => $options['before'],
171
            'lever'  => '<span class="lever"></span>'
172
        ]);
173
174
        return $content;
175
    }
176
177
    /**
178
     * Creates a `<button>` tag.
179
     *
180
     * @param   string $title
181
     * @param   array $options
182
     * @return  string
183
     */
184
    public function button($title, array $options = [])
185
    {
186
        $options = $this->addClass($options, $this->_class(__FUNCTION__));
187
        $options = $this->_getBtnClass($options);
188
        $options = $this->_getToolTipAttr($options);
189
190
        list($title, $options) = $this->_createIcon($this->Html, $title, $options);
191
192
        return parent::button($title, $options);
193
    }
194
195
    /**
196
     * Input check all.
197
     *
198
     * @return  string
199
     */
200
    public function checkAll()
201
    {
202
        return $this->control('check-all', ['type' => 'checkbox', 'class' => 'jsCheckAll']);
203
    }
204
205
    /**
206
     * Create html form.
207
     *
208
     * @param   mixed $model
209
     * @param   array $options
210
     * @return  string
211
     */
212
    public function create($model = null, array $options = [])
213
    {
214
        $options += ['process' => false, 'jsForm' => false];
215
        $options = $this->addClass($options, $this->_class('form'));
216
        $request = $this->getView()->getRequest();
217
218
        $isProcess = $options['process'];
219
220
        if ($isProcess !== false) {
221
            $_options = [
222
                'url' => [
223
                    'plugin'     => $request->getParam('plugin'),
224
                    'controller' => $request->getParam('controller'),
225
                    'action'     => 'process'
226
                ]
227
            ];
228
229
            $options['jsForm'] = true;
230
            $options = Hash::merge($_options, $options);
231
        }
232
233
        $isJsForm = $options['jsForm'];
234
        if ($isJsForm) {
235
            $this->_isJsForm = true;
236
            $options = $this->addClass($options, 'jsForm');
237
        }
238
239
        unset($options['process'], $options['jsForm']);
240
241
        return parent::create($model, $options);
242
    }
243
244
    /**
245
     * End html form.
246
     *
247
     * @param   array $secureAttributes
248
     * @return  string
249
     */
250
    public function end(array $secureAttributes = [])
251
    {
252
        if ($this->_isJsForm) {
253
            return implode('', [
254
                $this->hidden('action', ['value' => '', 'class' => 'jsFormAction']),
255
                parent::end($secureAttributes)
256
            ]);
257
        }
258
259
        return parent::end($secureAttributes);
260
    }
261
262
    /**
263
     * Table row process checkbox.
264
     *
265
     * @param   string $name
266
     * @param   string $type
267
     * @return  string
268
     */
269
    public function processCheck($type, $name)
270
    {
271
        return $this->control($type . '.' . $name . '.id', ['type' => 'checkbox']);
272
    }
273
274
    /**
275
     * Add the default suite of context providers provided.
276
     *
277
     * @return  void
278
     */
279
    protected function _addDefaultContextProviders()
280
    {
281
        $this->addContextProvider('orm', function ($request, $data) {
282
            if (is_array($data['entity']) || $data['entity'] instanceof \Traversable) {
283
                $pass = (new Collection($data['entity']))->first() !== null;
284
                if ($pass) {
285
                    return new EntityContext($request, $data);
286
                }
287
            }
288
289
            return $this->_addEntityContent($request, $data);
290
        });
291
292
        $this->_addFormContextProvider();
293
        $this->_addFormArrayProvider();
294
    }
295
296
    /**
297
     * Generates an input container template
298
     *
299
     * @param   array $options The options for input container template
300
     * @return  string The generated input container template
301
     */
302
    protected function _inputContainerTemplate($options)
303
    {
304
        $inputContainerTemplate = $options['options']['type'] . 'Container' . $options['errorSuffix'];
305
        if (!$this->templater()->get($inputContainerTemplate)) {
306
            $inputContainerTemplate = 'inputContainer' . $options['errorSuffix'];
307
        }
308
309
        $_options = new Data($options['options']);
310
        $before   = $this->_prepareBeforeAfterContainer('before', $_options->get('before'));
311
        $after    = $this->_prepareBeforeAfterContainer('after', $_options->get('after'));
312
313
        return $this->formatTemplate($inputContainerTemplate, [
314
            'after'         => $after,
315
            'before'        => $before,
316
            'error'         => $options['error'],
317
            'content'       => $options['content'],
318
            'type'          => $options['options']['type'],
319
            'required'      => $options['options']['required'] ? ' required' : '',
320
            'templateVars'  => isset($options['options']['templateVars']) ? $options['options']['templateVars'] : []
321
        ]);
322
    }
323
324
    /**
325
     * Add the entity suite of context providers provided.
326
     *
327
     * @param   $request
328
     * @param   $data
329
     * @return  EntityContext
330
     */
331
    protected function _addEntityContent($request, $data)
332
    {
333
        if ($data['entity'] instanceof EntityInterface) {
334
            return new EntityContext($request, $data);
335
        }
336
337
        if (is_array($data['entity']) && empty($data['entity']['schema'])) {
338
            return new EntityContext($request, $data);
339
        }
340
    }
341
342
    /**
343
     * Add the array suite of context providers provided.
344
     *
345
     * @return  void
346
     */
347
    protected function _addFormArrayProvider()
348
    {
349
        $this->addContextProvider('array', function ($request, $data) {
350
            if (is_array($data['entity']) && isset($data['entity']['schema'])) {
351
                return new ArrayContext($request, $data['entity']);
352
            }
353
        });
354
    }
355
356
    /**
357
     * Add the form suite of context providers provided.
358
     *
359
     * @return  void
360
     */
361
    protected function _addFormContextProvider()
362
    {
363
        $this->addContextProvider('form', function ($request, $data) {
364
            if ($data['entity'] instanceof Form) {
365
                return new FormContext($request, $data);
366
            }
367
        });
368
    }
369
}
370