Completed
Push — master ( a7fcd1...e29bb4 )
by Cheren
01:58
created

FormHelper::file()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 27
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 27
rs 8.8571
c 0
b 0
f 0
cc 3
eloc 17
nc 3
nop 2
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
217
        $isProcess = $options['process'];
218
219
        if ($isProcess !== false) {
220
            $_options = [
221
                'url' => [
222
                    'plugin'     => $this->request->getParam('plugin'),
223
                    'controller' => $this->request->getParam('controller'),
224
                    'action'     => 'process'
225
                ]
226
            ];
227
228
            $options['jsForm'] = true;
229
            $options = Hash::merge($_options, $options);
230
        }
231
232
        $isJsForm = $options['jsForm'];
233
        if ($isJsForm) {
234
            $this->_isJsForm = true;
235
            $options = $this->addClass($options, 'jsForm');
236
        }
237
238
        unset($options['process'], $options['jsForm']);
239
240
        return parent::create($model, $options);
241
    }
242
243
    /**
244
     * End html form.
245
     *
246
     * @param   array $secureAttributes
247
     * @return  string
248
     */
249
    public function end(array $secureAttributes = [])
250
    {
251
        if ($this->_isJsForm) {
252
            return implode('', [
253
                $this->hidden('action', ['value' => '', 'class' => 'jsFormAction']),
254
                parent::end($secureAttributes)
255
            ]);
256
        }
257
258
        return parent::end($secureAttributes);
259
    }
260
261
    /**
262
     * Table row process checkbox.
263
     *
264
     * @param   string $name
265
     * @param   string $type
266
     * @return  string
267
     */
268
    public function processCheck($type, $name)
269
    {
270
        return $this->control($type . '.' . $name . '.id', ['type' => 'checkbox']);
271
    }
272
273
    /**
274
     * Add the default suite of context providers provided.
275
     *
276
     * @return  void
277
     */
278
    protected function _addDefaultContextProviders()
279
    {
280
        $this->addContextProvider('orm', function ($request, $data) {
281
            if (is_array($data['entity']) || $data['entity'] instanceof \Traversable) {
282
                $pass = (new Collection($data['entity']))->first() !== null;
283
                if ($pass) {
284
                    return new EntityContext($request, $data);
285
                }
286
            }
287
288
            return $this->_addEntityContent($request, $data);
289
        });
290
291
        $this->_addFormContextProvider();
292
        $this->_addFormArrayProvider();
293
    }
294
295
    /**
296
     * Generates an input container template
297
     *
298
     * @param   array $options The options for input container template
299
     * @return  string The generated input container template
300
     */
301
    protected function _inputContainerTemplate($options)
302
    {
303
        $inputContainerTemplate = $options['options']['type'] . 'Container' . $options['errorSuffix'];
304
        if (!$this->templater()->get($inputContainerTemplate)) {
305
            $inputContainerTemplate = 'inputContainer' . $options['errorSuffix'];
306
        }
307
308
        $_options = new Data($options['options']);
309
        $before   = $this->_prepareBeforeAfterContainer('before', $_options->get('before'));
310
        $after    = $this->_prepareBeforeAfterContainer('after', $_options->get('after'));
311
312
        return $this->formatTemplate($inputContainerTemplate, [
313
            'after'         => $after,
314
            'before'        => $before,
315
            'error'         => $options['error'],
316
            'content'       => $options['content'],
317
            'type'          => $options['options']['type'],
318
            'required'      => $options['options']['required'] ? ' required' : '',
319
            'templateVars'  => isset($options['options']['templateVars']) ? $options['options']['templateVars'] : []
320
        ]);
321
    }
322
323
    /**
324
     * Add the entity suite of context providers provided.
325
     *
326
     * @param   $request
327
     * @param   $data
328
     * @return  EntityContext
329
     */
330
    protected function _addEntityContent($request, $data)
331
    {
332
        if ($data['entity'] instanceof EntityInterface) {
333
            return new EntityContext($request, $data);
334
        }
335
336
        if (is_array($data['entity']) && empty($data['entity']['schema'])) {
337
            return new EntityContext($request, $data);
338
        }
339
    }
340
341
    /**
342
     * Add the array suite of context providers provided.
343
     *
344
     * @return  void
345
     */
346
    protected function _addFormArrayProvider()
347
    {
348
        $this->addContextProvider('array', function ($request, $data) {
349
            if (is_array($data['entity']) && isset($data['entity']['schema'])) {
350
                return new ArrayContext($request, $data['entity']);
351
            }
352
        });
353
    }
354
355
    /**
356
     * Add the form suite of context providers provided.
357
     *
358
     * @return  void
359
     */
360
    protected function _addFormContextProvider()
361
    {
362
        $this->addContextProvider('form', function ($request, $data) {
363
            if ($data['entity'] instanceof Form) {
364
                return new FormContext($request, $data);
365
            }
366
        });
367
    }
368
}
369