Completed
Push — master ( 78db53...7d214b )
by Cheren
02:18
created

FormHelper::_inputContainerTemplate()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 21
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

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