Completed
Pull Request — 3.next (#13555)
by
unknown
03:33
created

ViewBuilder::layout()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 0
loc 9
rs 9.9666
c 0
b 0
f 0
1
<?php
2
/**
3
 * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
4
 * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
5
 *
6
 * Licensed under The MIT License
7
 * For full copyright and license information, please see the LICENSE.txt
8
 * Redistributions of files must retain the above copyright notice.
9
 *
10
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
11
 * @link          https://cakephp.org CakePHP(tm) Project
12
 * @since         3.1.0
13
 * @license       https://opensource.org/licenses/mit-license.php MIT License
14
 */
15
namespace Cake\View;
16
17
use Cake\Core\App;
18
use Cake\Event\EventManager;
19
use Cake\Http\Response;
20
use Cake\Http\ServerRequest;
21
use Cake\View\Exception\MissingViewException;
22
use JsonSerializable;
23
use Serializable;
24
25
/**
26
 * Provides an API for iteratively building a view up.
27
 *
28
 * Once you have configured the view and established all the context
29
 * you can create a view instance with `build()`.
30
 */
31
class ViewBuilder implements JsonSerializable, Serializable
32
{
33
34
    /**
35
     * The subdirectory to the template.
36
     *
37
     * @var string|null
38
     */
39
    protected $_templatePath;
40
41
    /**
42
     * The template file to render.
43
     *
44
     * @var string|null
45
     */
46
    protected $_template;
47
48
    /**
49
     * The plugin name to use.
50
     *
51
     * @var string|null|false
52
     */
53
    protected $_plugin;
54
55
    /**
56
     * The theme name to use.
57
     *
58
     * @var string|null|false
59
     */
60
    protected $_theme;
61
62
    /**
63
     * The layout name to render.
64
     *
65
     * @var string|null|false
66
     */
67
    protected $_layout;
68
69
    /**
70
     * Whether or not autoLayout should be enabled.
71
     *
72
     * @var bool|null
73
     */
74
    protected $_autoLayout;
75
76
    /**
77
     * The layout path to build the view with.
78
     *
79
     * @var string|null
80
     */
81
    protected $_layoutPath;
82
83
    /**
84
     * The view variables to use
85
     *
86
     * @var string|null
87
     */
88
    protected $_name;
89
90
    /**
91
     * The view class name to use.
92
     * Can either use plugin notation, a short name
93
     * or a fully namespaced classname.
94
     *
95
     * @var string|null
96
     */
97
    protected $_className;
98
99
    /**
100
     * Additional options used when constructing the view.
101
     *
102
     * This options array lets you provide custom constructor
103
     * arguments to application/plugin view classes.
104
     *
105
     * @var array
106
     */
107
    protected $_options = [];
108
109
    /**
110
     * The helpers to use
111
     *
112
     * @var array
113
     */
114
    protected $_helpers = [];
115
116
    /**
117
     * View vars
118
     *
119
     * @var array
120
     */
121
    protected $_vars = [];
122
123
    /**
124
     * Saves a variable for use inside a template.
125
     *
126
     * @param string $name A string or an array of data.
127
     * @param mixed $value Value.
128
     * @return $this
129
     */
130
    public function setVar($name, $value = null)
131
    {
132
        $this->_vars[$name] = $value;
133
134
        return $this;
135
    }
136
137
    /**
138
     * Saves view vars for use inside templates.
139
     *
140
     * @param array $data Array of data.
141
     * @param bool $merge Whether to merge with existing vars, default true.
142
     * @return $this
143
     */
144
    public function setVars($data, $merge = true)
145
    {
146
        if ($merge) {
147
            $this->_vars = $data + $this->_vars;
148
        } else {
149
            $this->_vars = $data;
150
        }
151
152
        return $this;
153
    }
154
155
    /**
156
     * Check if view var is set.
157
     *
158
     * @param string $name Var name
159
     * @return bool
160
     */
161
    public function hasVar($name)
162
    {
163
        return array_key_exists($name, $this->_vars);
164
    }
165
166
    /**
167
     * Get view var
168
     *
169
     * @param string $name Var name
170
     * @return mixed The var value or null if unset.
171
     */
172
    public function getVar($name)
173
    {
174
        return isset($this->_vars[$name]) ? $this->_vars[$name] : null;
175
    }
176
177
    /**
178
     * Get all view vars.
179
     *
180
     * @return array
181
     */
182
    public function getVars()
183
    {
184
        return $this->_vars;
185
    }
186
187
    /**
188
     * Sets path for template files.
189
     *
190
     * @param string|null $path Path for view files.
191
     * @return $this
192
     */
193
    public function setTemplatePath($path)
194
    {
195
        $this->_templatePath = $path;
196
197
        return $this;
198
    }
199
200
    /**
201
     * Gets path for template files.
202
     *
203
     * @return string|null
204
     */
205
    public function getTemplatePath()
206
    {
207
        return $this->_templatePath;
208
    }
209
210
    /**
211
     * Get/set path for template files.
212
     *
213
     * @deprecated 3.4.0 Use setTemplatePath()/getTemplatePath() instead.
214
     * @param string|null $path Path for view files. If null returns current path.
215
     * @return string|$this
216
     */
217
    public function templatePath($path = null)
218
    {
219
        deprecationWarning('ViewBuilder::templatePath() is deprecated. Use ViewBuilder::setTemplatePath() or ViewBuilder::getTemplatePath() instead.');
220
        if ($path !== null) {
221
            return $this->setTemplatePath($path);
222
        }
223
224
        return $this->getTemplatePath();
225
    }
226
227
    /**
228
     * Sets path for layout files.
229
     *
230
     * @param string|null $path Path for layout files.
231
     * @return $this
232
     */
233
    public function setLayoutPath($path)
234
    {
235
        $this->_layoutPath = $path;
236
237
        return $this;
238
    }
239
240
    /**
241
     * Gets path for layout files.
242
     *
243
     * @return string|null
244
     */
245
    public function getLayoutPath()
246
    {
247
        return $this->_layoutPath;
248
    }
249
250
    /**
251
     * Get/set path for layout files.
252
     *
253
     * @deprecated 3.4.0 Use setLayoutPath()/getLayoutPath() instead.
254
     * @param string|null $path Path for layout files. If null returns current path.
255
     * @return string|$this
256
     */
257
    public function layoutPath($path = null)
258
    {
259
        deprecationWarning('ViewBuilder::layoutPath() is deprecated. Use ViewBuilder::setLayoutPath() or ViewBuilder::getLayoutPath() instead.');
260
        if ($path !== null) {
261
            return $this->setLayoutPath($path);
262
        }
263
264
        return $this->getLayoutPath();
265
    }
266
267
    /**
268
     * Turns on or off CakePHP's conventional mode of applying layout files.
269
     * On by default. Setting to off means that layouts will not be
270
     * automatically applied to rendered views.
271
     *
272
     * @param bool $enable Boolean to turn on/off.
273
     * @return $this
274
     */
275
    public function enableAutoLayout($enable = true)
276
    {
277
        $this->_autoLayout = (bool)$enable;
278
279
        return $this;
280
    }
281
282
    /**
283
     * Turns off CakePHP's conventional mode of applying layout files.
284
     *
285
     * Setting to off means that layouts will not be automatically applied to
286
     * rendered views.
287
     *
288
     * @return $this
289
     */
290
    public function disableAutoLayout()
291
    {
292
        $this->_autoLayout = false;
293
294
        return $this;
295
    }
296
297
    /**
298
     * Returns if CakePHP's conventional mode of applying layout files is enabled.
299
     * Disabled means that layouts will not be automatically applied to rendered views.
300
     *
301
     * @return bool|null
302
     */
303
    public function isAutoLayoutEnabled()
304
    {
305
        return $this->_autoLayout;
306
    }
307
308
    /**
309
     * Turns on or off CakePHP's conventional mode of applying layout files.
310
     * On by default. Setting to off means that layouts will not be
311
     * automatically applied to rendered views.
312
     *
313
     * @deprecated 3.4.0 Use enableAutoLayout()/isAutoLayoutEnabled() instead.
314
     * @param bool|null $enable Boolean to turn on/off. If null returns current value.
315
     * @return bool|$this
316
     */
317
    public function autoLayout($enable = null)
318
    {
319
        deprecationWarning('ViewBuilder::autoLayout() is deprecated. Use ViewBuilder::enableAutoLayout() or ViewBuilder::isAutoLayoutEnable() instead.');
320
        if ($enable !== null) {
321
            return $this->enableAutoLayout($enable);
322
        }
323
324
        return $this->isAutoLayoutEnabled();
325
    }
326
327
    /**
328
     * Sets the plugin name to use.
329
     *
330
     * `False` to remove current plugin name is deprecated as of 3.4.0. Use directly `null` instead.
331
     *
332
     * @param string|null|false $name Plugin name.
333
     *   Use null or false to remove the current plugin name.
334
     * @return $this
335
     */
336
    public function setPlugin($name)
337
    {
338
        $this->_plugin = $name;
339
340
        return $this;
341
    }
342
343
    /**
344
     * Gets the plugin name to use.
345
     *
346
     * @return string|null|false
347
     */
348
    public function getPlugin()
349
    {
350
        return $this->_plugin;
351
    }
352
353
    /**
354
     * The plugin name to use
355
     *
356
     * @deprecated 3.4.0 Use setPlugin()/getPlugin() instead.
357
     * @param string|null|false $name Plugin name. If null returns current plugin.
358
     *   Use false to remove the current plugin name.
359
     * @return string|false|null|$this
360
     */
361
    public function plugin($name = null)
362
    {
363
        deprecationWarning('ViewBuilder::plugin() is deprecated. Use ViewBuilder::setPlugin() or ViewBuilder::getPlugin() instead.');
364
        if ($name !== null) {
365
            return $this->setPlugin($name);
366
        }
367
368
        return $this->getPlugin();
369
    }
370
371
    /**
372
     * Sets the helpers to use.
373
     *
374
     * @param array $helpers Helpers to use.
375
     * @param bool $merge Whether or not to merge existing data with the new data.
376
     * @return $this
377
     */
378
    public function setHelpers(array $helpers, $merge = true)
379
    {
380
        if ($merge) {
381
            $helpers = array_merge($this->_helpers, $helpers);
382
        }
383
        $this->_helpers = $helpers;
384
385
        return $this;
386
    }
387
388
    /**
389
     * Gets the helpers to use.
390
     *
391
     * @return array
392
     */
393
    public function getHelpers()
394
    {
395
        return $this->_helpers;
396
    }
397
398
    /**
399
     * The helpers to use
400
     *
401
     * @deprecated 3.4.0 Use setHelpers()/getHelpers() instead.
402
     * @param array|null $helpers Helpers to use.
403
     * @param bool $merge Whether or not to merge existing data with the new data.
404
     * @return array|$this
405
     */
406 View Code Duplication
    public function helpers(array $helpers = null, $merge = true)
407
    {
408
        deprecationWarning('ViewBuilder::helpers() is deprecated. Use ViewBuilder::setHelpers() or ViewBuilder::getHelpers() instead.');
409
        if ($helpers !== null) {
410
            return $this->setHelpers($helpers, $merge);
411
        }
412
413
        return $this->getHelpers();
414
    }
415
416
    /**
417
     * Sets the view theme to use.
418
     *
419
     * `False` to remove current theme is deprecated as of 3.4.0. Use directly `null` instead.
420
     *
421
     * @param string|null|false $theme Theme name.
422
     *   Use null or false to remove the current theme.
423
     * @return $this
424
     */
425
    public function setTheme($theme)
426
    {
427
        $this->_theme = $theme;
428
429
        return $this;
430
    }
431
432
    /**
433
     * Gets the view theme to use.
434
     *
435
     * @return string|null|false
436
     */
437
    public function getTheme()
438
    {
439
        return $this->_theme;
440
    }
441
442
    /**
443
     * The view theme to use.
444
     *
445
     * @deprecated 3.4.0 Use setTheme()/getTheme() instead.
446
     * @param string|null|false $theme Theme name. If null returns current theme.
447
     *   Use false to remove the current theme.
448
     * @return string|false|null|$this
449
     */
450 View Code Duplication
    public function theme($theme = null)
451
    {
452
        deprecationWarning('ViewBuilder::theme() is deprecated. Use ViewBuilder::setTheme() or ViewBuilder::getTheme() instead.');
453
        if ($theme !== null) {
454
            return $this->setTheme($theme);
455
        }
456
457
        return $this->getTheme();
458
    }
459
460
    /**
461
     * Sets the name of the view file to render. The name specified is the
462
     * filename in /src/Template/<SubFolder> without the .ctp extension.
463
     *
464
     * @param string|null $name View file name to set.
465
     * @return $this
466
     */
467
    public function setTemplate($name)
468
    {
469
        $this->_template = $name;
470
471
        return $this;
472
    }
473
474
    /**
475
     * Gets the name of the view file to render. The name specified is the
476
     * filename in /src/Template/<SubFolder> without the .ctp extension.
477
     *
478
     * @return string|null
479
     */
480
    public function getTemplate()
481
    {
482
        return $this->_template;
483
    }
484
485
    /**
486
     * Get/set the name of the view file to render. The name specified is the
487
     * filename in /src/Template/<SubFolder> without the .ctp extension.
488
     *
489
     * @deprecated 3.4.0 Use setTemplate()/getTemplate()
490
     * @param string|null $name View file name to set. If null returns current name.
491
     * @return string|$this
492
     */
493
    public function template($name = null)
494
    {
495
        deprecationWarning('ViewBuilder::template() is deprecated. Use ViewBuilder::setTemplate() or ViewBuilder::getTemplate() instead.');
496
        if ($name !== null) {
497
            return $this->setTemplate($name);
498
        }
499
500
        return $this->getTemplate();
501
    }
502
503
    /**
504
     * Sets the name of the layout file to render the view inside of.
505
     * The name specified is the filename of the layout in /src/Template/Layout
506
     * without the .ctp extension.
507
     *
508
     * @param string|null|false $name Layout file name to set.
509
     * @return $this
510
     */
511
    public function setLayout($name)
512
    {
513
        $this->_layout = $name;
514
515
        return $this;
516
    }
517
518
    /**
519
     * Gets the name of the layout file to render the view inside of.
520
     *
521
     * @return string|null|false
522
     */
523
    public function getLayout()
524
    {
525
        return $this->_layout;
526
    }
527
528
    /**
529
     * Get/set the name of the layout file to render the view inside of.
530
     * The name specified is the filename of the layout in /src/Template/Layout
531
     * without the .ctp extension.
532
     *
533
     * @deprecated 3.4.0 Use setLayout()/getLayout() instead.
534
     * @param string|null $name Layout file name to set. If null returns current name.
535
     * @return string|$this
536
     */
537
    public function layout($name = null)
538
    {
539
        deprecationWarning('ViewBuilder::layout() is deprecated. Use ViewBuilder::setLayout() or ViewBuilder::getLayout() instead.');
540
        if ($name !== null) {
541
            return $this->setLayout($name);
542
        }
543
544
        return $this->getLayout();
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression $this->getLayout(); of type string|null|false adds false to the return on line 544 which is incompatible with the return type documented by Cake\View\ViewBuilder::layout of type Cake\View\ViewBuilder|string. It seems like you forgot to handle an error condition.
Loading history...
545
    }
546
547
    /**
548
     * Sets additional options for the view.
549
     *
550
     * This lets you provide custom constructor arguments to application/plugin view classes.
551
     *
552
     * @param array $options An array of options.
553
     * @param bool $merge Whether or not to merge existing data with the new data.
554
     * @return $this
555
     */
556
    public function setOptions(array $options, $merge = true)
557
    {
558
        if ($merge) {
559
            $options = array_merge($this->_options, $options);
560
        }
561
        $this->_options = $options;
562
563
        return $this;
564
    }
565
566
    /**
567
     * Gets additional options for the view.
568
     *
569
     * @return array
570
     */
571
    public function getOptions()
572
    {
573
        return $this->_options;
574
    }
575
576
    /**
577
     * Set additional options for the view.
578
     *
579
     * This lets you provide custom constructor arguments to application/plugin view classes.
580
     *
581
     * @deprecated 3.4.0 Use setOptions()/getOptions() instead.
582
     * @param array|null $options Either an array of options or null to get current options.
583
     * @param bool $merge Whether or not to merge existing data with the new data.
584
     * @return array|$this
585
     */
586 View Code Duplication
    public function options(array $options = null, $merge = true)
587
    {
588
        deprecationWarning('ViewBuilder::options() is deprecated. Use ViewBuilder::setOptions() or ViewBuilder::getOptions() instead.');
589
        if ($options !== null) {
590
            return $this->setOptions($options, $merge);
591
        }
592
593
        return $this->getOptions();
594
    }
595
596
    /**
597
     * Sets the view name.
598
     *
599
     * @param string|null $name The name of the view.
600
     * @return $this
601
     */
602
    public function setName($name)
603
    {
604
        $this->_name = $name;
605
606
        return $this;
607
    }
608
609
    /**
610
     * Gets the view name.
611
     *
612
     * @return string|null
613
     */
614
    public function getName()
615
    {
616
        return $this->_name;
617
    }
618
619
    /**
620
     * Get/set the view name
621
     *
622
     * @deprecated 3.4.0 Use setName()/getName() instead.
623
     * @param string|null $name The name of the view
624
     * @return string|$this
625
     */
626 View Code Duplication
    public function name($name = null)
627
    {
628
        deprecationWarning('ViewBuilder::name() is deprecated. Use ViewBuilder::setName() or ViewBuilder::getName() instead.');
629
        if ($name !== null) {
630
            return $this->setName($name);
631
        }
632
633
        return $this->getName();
634
    }
635
636
    /**
637
     * Sets the view classname.
638
     *
639
     * Accepts either a short name (Ajax) a plugin name (MyPlugin.Ajax)
640
     * or a fully namespaced name (App\View\AppView) or null to use the
641
     * View class provided by CakePHP.
642
     *
643
     * @param string|null $name The class name for the view.
644
     * @return $this
645
     */
646
    public function setClassName($name)
647
    {
648
        $this->_className = $name;
649
650
        return $this;
651
    }
652
653
    /**
654
     * Gets the view classname.
655
     *
656
     * @return string|null
657
     */
658
    public function getClassName()
659
    {
660
        return $this->_className;
661
    }
662
663
    /**
664
     * Get/set the view classname.
665
     *
666
     * Accepts either a short name (Ajax) a plugin name (MyPlugin.Ajax)
667
     * or a fully namespaced name (App\View\AppView).
668
     *
669
     * @deprecated 3.4.0 Use setClassName()/getClassName() instead.
670
     * @param string|null $name The class name for the view. Can
671
     *   be a plugin.class name reference, a short alias, or a fully
672
     *   namespaced name.
673
     * @return string|$this
674
     */
675
    public function className($name = null)
676
    {
677
        deprecationWarning('ViewBuilder::className() is deprecated. Use ViewBuilder::setClassName() or ViewBuilder::getClassName() instead.');
678
        if ($name !== null) {
679
            return $this->setClassName($name);
680
        }
681
682
        return $this->getClassName();
683
    }
684
685
    /**
686
     * Using the data in the builder, create a view instance.
687
     *
688
     * If className() is null, App\View\AppView will be used.
689
     * If that class does not exist, then Cake\View\View will be used.
690
     *
691
     * @param array $vars The view variables/context to use.
692
     * @param \Cake\Http\ServerRequest|null $request The request to use.
693
     * @param \Cake\Http\Response|null $response The response to use.
694
     * @param \Cake\Event\EventManager|null $events The event manager to use.
695
     * @return \Cake\View\View
696
     * @throws \Cake\View\Exception\MissingViewException
697
     */
698
    public function build($vars = [], ServerRequest $request = null, Response $response = null, EventManager $events = null)
699
    {
700
        $className = $this->_className;
701
        if ($className === null) {
702
            $className = App::className('App', 'View', 'View') ?: 'Cake\View\View';
703
        }
704
        if ($className === 'View') {
705
            $className = App::className($className, 'View');
706
        } else {
707
            $className = App::className($className, 'View', 'View');
708
        }
709
        if (!$className) {
710
            throw new MissingViewException(['class' => $this->_className]);
711
        }
712
713
        $data = [
714
            'name' => $this->_name,
715
            'templatePath' => $this->_templatePath,
716
            'template' => $this->_template,
717
            'plugin' => $this->_plugin,
718
            'theme' => $this->_theme,
719
            'layout' => $this->_layout,
720
            'autoLayout' => $this->_autoLayout,
721
            'layoutPath' => $this->_layoutPath,
722
            'helpers' => $this->_helpers,
723
            'viewVars' => $vars + $this->_vars,
724
        ];
725
        $data += $this->_options;
726
727
        return new $className($request, $response, $events, $data);
728
    }
729
730
    /**
731
     * Serializes the view builder object to a value that can be natively
732
     * serialized and re-used to clone this builder instance.
733
     *
734
     * @return array Serializable array of configuration properties.
735
     */
736
    public function jsonSerialize()
737
    {
738
        $properties = [
739
            '_templatePath', '_template', '_plugin', '_theme', '_layout', '_autoLayout',
740
            '_layoutPath', '_name', '_className', '_options', '_helpers'
741
        ];
742
743
        $array = [];
744
745
        foreach ($properties as $property) {
746
            $array[$property] = $this->{$property};
747
        }
748
749
        return array_filter($array, function ($i) {
750
            return !is_array($i) && strlen($i) || !empty($i);
751
        });
752
    }
753
754
    /**
755
     * Configures a view builder instance from serialized config.
756
     *
757
     * @param array $config View builder configuration array.
758
     * @return $this Configured view builder instance.
759
     */
760
    public function createFromArray($config)
761
    {
762
        foreach ($config as $property => $value) {
763
            $this->{$property} = $value;
764
        }
765
766
        return $this;
767
    }
768
769
    /**
770
     * Serializes the view builder object.
771
     *
772
     * @return string
773
     */
774
    public function serialize()
775
    {
776
        $array = $this->jsonSerialize();
777
778
        return serialize($array);
779
    }
780
781
    /**
782
     * Unserializes the view builder object.
783
     *
784
     * @param string $data Serialized string.
785
     * @return $this Configured view builder instance.
786
     */
787
    public function unserialize($data)
788
    {
789
        return $this->createFromArray(unserialize($data));
790
    }
791
}
792