Completed
Push — master ( 84cb25...a8d95f )
by Alexander
13:35
created

View   C

Complexity

Total Complexity 57

Size/Duplication

Total Lines 558
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 12

Test Coverage

Coverage 66.87%

Importance

Changes 0
Metric Value
wmc 57
lcom 2
cbo 12
dl 0
loc 558
ccs 107
cts 160
cp 0.6687
rs 6.433
c 0
b 0
f 0

25 Methods

Rating   Name   Duplication   Size   Complexity  
A render() 0 5 1
A init() 0 12 4
D findViewFile() 0 33 10
C renderFile() 0 44 8
A getViewFile() 0 4 2
A getRequestedViewFile() 0 4 2
A beforeRender() 0 10 1
A afterRender() 0 12 2
C renderPhpFile() 0 25 7
A renderDynamic() 0 12 2
A getDynamicPlaceholders() 0 4 1
A setDynamicPlaceholders() 0 4 1
A addDynamicPlaceholder() 0 12 3
A evaluateDynamicContent() 0 4 1
A getDynamicContents() 0 4 1
A pushDynamicContent() 0 4 1
A popDynamicContent() 0 4 1
A beginBlock() 0 8 1
A endBlock() 0 4 1
A beginContent() 0 8 1
A endContent() 0 4 1
A beginCache() 0 14 2
A endCache() 0 4 1
A beginPage() 0 7 1
A endPage() 0 5 1

How to fix   Complexity   

Complex Class

Complex classes like View often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use View, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * @link http://www.yiiframework.com/
4
 * @copyright Copyright (c) 2008 Yii Software LLC
5
 * @license http://www.yiiframework.com/license/
6
 */
7
8
namespace yii\base;
9
10
use Yii;
11
use yii\helpers\FileHelper;
12
use yii\widgets\Block;
13
use yii\widgets\ContentDecorator;
14
use yii\widgets\FragmentCache;
15
16
/**
17
 * View represents a view object in the MVC pattern.
18
 *
19
 * View provides a set of methods (e.g. [[render()]]) for rendering purpose.
20
 *
21
 * For more details and usage information on View, see the [guide article on views](guide:structure-views).
22
 *
23
 * @property string|bool $viewFile The view file currently being rendered. False if no view file is being
24
 * rendered. This property is read-only.
25
 *
26
 * @author Qiang Xue <[email protected]>
27
 * @since 2.0
28
 */
29
class View extends Component implements DynamicContentAwareInterface
30
{
31
    /**
32
     * @event Event an event that is triggered by [[beginPage()]].
33
     */
34
    const EVENT_BEGIN_PAGE = 'beginPage';
35
    /**
36
     * @event Event an event that is triggered by [[endPage()]].
37
     */
38
    const EVENT_END_PAGE = 'endPage';
39
    /**
40
     * @event ViewEvent an event that is triggered by [[renderFile()]] right before it renders a view file.
41
     */
42
    const EVENT_BEFORE_RENDER = 'beforeRender';
43
    /**
44
     * @event ViewEvent an event that is triggered by [[renderFile()]] right after it renders a view file.
45
     */
46
    const EVENT_AFTER_RENDER = 'afterRender';
47
48
    /**
49
     * @var ViewContextInterface the context under which the [[renderFile()]] method is being invoked.
50
     */
51
    public $context;
52
    /**
53
     * @var mixed custom parameters that are shared among view templates.
54
     */
55
    public $params = [];
56
    /**
57
     * @var array a list of available renderers indexed by their corresponding supported file extensions.
58
     * Each renderer may be a view renderer object or the configuration for creating the renderer object.
59
     * For example, the following configuration enables both Smarty and Twig view renderers:
60
     *
61
     * ```php
62
     * [
63
     *     'tpl' => ['class' => 'yii\smarty\ViewRenderer'],
64
     *     'twig' => ['class' => 'yii\twig\ViewRenderer'],
65
     * ]
66
     * ```
67
     *
68
     * If no renderer is available for the given view file, the view file will be treated as a normal PHP
69
     * and rendered via [[renderPhpFile()]].
70
     */
71
    public $renderers;
72
    /**
73
     * @var string the default view file extension. This will be appended to view file names if they don't have file extensions.
74
     */
75
    public $defaultExtension = 'php';
76
    /**
77
     * @var Theme|array|string the theme object or the configuration for creating the theme object.
78
     * If not set, it means theming is not enabled.
79
     */
80
    public $theme;
81
    /**
82
     * @var array a list of named output blocks. The keys are the block names and the values
83
     * are the corresponding block content. You can call [[beginBlock()]] and [[endBlock()]]
84
     * to capture small fragments of a view. They can be later accessed somewhere else
85
     * through this property.
86
     */
87
    public $blocks;
88
    /**
89
     * @var array|DynamicContentAwareInterface[] a list of currently active dynamic content class instances.
90
     * This property is used internally to implement the dynamic content caching feature. Do not modify it directly.
91
     * @internal
92
     * @deprecated Since 2.0.14. Do not use this property directly. Use methods [[getDynamicContents()]],
93
     * [[pushDynamicContent()]], [[popDynamicContent()]] instead.
94
     */
95
    public $cacheStack = [];
96
    /**
97
     * @var array a list of placeholders for embedding dynamic contents. This property
98
     * is used internally to implement the content caching feature. Do not modify it directly.
99
     * @internal
100
     * @deprecated Since 2.0.14. Do not use this property directly. Use methods [[getDynamicPlaceholders()]],
101
     * [[setDynamicPlaceholders()]], [[addDynamicPlaceholder()]] instead.
102
     */
103
    public $dynamicPlaceholders = [];
104
105
    /**
106
     * @var array the view files currently being rendered. There may be multiple view files being
107
     * rendered at a moment because one view may be rendered within another.
108
     */
109
    private $_viewFiles = [];
110
111
112
    /**
113
     * Initializes the view component.
114
     */
115 152
    public function init()
116
    {
117 152
        parent::init();
118 152
        if (is_array($this->theme)) {
119
            if (!isset($this->theme['class'])) {
120
                $this->theme['class'] = 'yii\base\Theme';
121
            }
122
            $this->theme = Yii::createObject($this->theme);
123 152
        } elseif (is_string($this->theme)) {
124
            $this->theme = Yii::createObject($this->theme);
125
        }
126 152
    }
127
128
    /**
129
     * Renders a view.
130
     *
131
     * The view to be rendered can be specified in one of the following formats:
132
     *
133
     * - [path alias](guide:concept-aliases) (e.g. "@app/views/site/index");
134
     * - absolute path within application (e.g. "//site/index"): the view name starts with double slashes.
135
     *   The actual view file will be looked for under the [[Application::viewPath|view path]] of the application.
136
     * - absolute path within current module (e.g. "/site/index"): the view name starts with a single slash.
137
     *   The actual view file will be looked for under the [[Module::viewPath|view path]] of the [[Controller::module|current module]].
138
     * - relative view (e.g. "index"): the view name does not start with `@` or `/`. The corresponding view file will be
139
     *   looked for under the [[ViewContextInterface::getViewPath()|view path]] of the view `$context`.
140
     *   If `$context` is not given, it will be looked for under the directory containing the view currently
141
     *   being rendered (i.e., this happens when rendering a view within another view).
142
     *
143
     * @param string $view the view name.
144
     * @param array $params the parameters (name-value pairs) that will be extracted and made available in the view file.
145
     * @param object $context the context to be assigned to the view and can later be accessed via [[context]]
146
     * in the view. If the context implements [[ViewContextInterface]], it may also be used to locate
147
     * the view file corresponding to a relative view name.
148
     * @return string the rendering result
149
     * @throws ViewNotFoundException if the view file does not exist.
150
     * @throws InvalidCallException if the view cannot be resolved.
151
     * @see renderFile()
152
     */
153 36
    public function render($view, $params = [], $context = null)
154
    {
155 36
        $viewFile = $this->findViewFile($view, $context);
156 36
        return $this->renderFile($viewFile, $params, $context);
0 ignored issues
show
Bug introduced by
It seems like $viewFile defined by $this->findViewFile($view, $context) on line 155 can also be of type boolean; however, yii\base\View::renderFile() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
157
    }
158
159
    /**
160
     * Finds the view file based on the given view name.
161
     * @param string $view the view name or the [path alias](guide:concept-aliases) of the view file. Please refer to [[render()]]
162
     * on how to specify this parameter.
163
     * @param object $context the context to be assigned to the view and can later be accessed via [[context]]
164
     * in the view. If the context implements [[ViewContextInterface]], it may also be used to locate
165
     * the view file corresponding to a relative view name.
166
     * @return string the view file path. Note that the file may not exist.
167
     * @throws InvalidCallException if a relative view name is given while there is no active context to
168
     * determine the corresponding view file.
169
     */
170 36
    protected function findViewFile($view, $context = null)
171
    {
172 36
        if (strncmp($view, '@', 1) === 0) {
173
            // e.g. "@app/views/main"
174 25
            $file = Yii::getAlias($view);
175 12
        } elseif (strncmp($view, '//', 2) === 0) {
176
            // e.g. "//layouts/main"
177
            $file = Yii::$app->getViewPath() . DIRECTORY_SEPARATOR . ltrim($view, '/');
178 12
        } elseif (strncmp($view, '/', 1) === 0) {
179
            // e.g. "/site/index"
180
            if (Yii::$app->controller !== null) {
181
                $file = Yii::$app->controller->module->getViewPath() . DIRECTORY_SEPARATOR . ltrim($view, '/');
182
            } else {
183
                throw new InvalidCallException("Unable to locate view file for view '$view': no active controller.");
184
            }
185 12
        } elseif ($context instanceof ViewContextInterface) {
186 6
            $file = $context->getViewPath() . DIRECTORY_SEPARATOR . $view;
187 6
        } elseif (($currentViewFile = $this->getRequestedViewFile()) !== false) {
188 6
            $file = dirname($currentViewFile) . DIRECTORY_SEPARATOR . $view;
189
        } else {
190
            throw new InvalidCallException("Unable to resolve view file for view '$view': no active view context.");
191
        }
192
193 36
        if (pathinfo($file, PATHINFO_EXTENSION) !== '') {
194 23
            return $file;
195
        }
196 13
        $path = $file . '.' . $this->defaultExtension;
197 13
        if ($this->defaultExtension !== 'php' && !is_file($path)) {
198
            $path = $file . '.php';
199
        }
200
201 13
        return $path;
202
    }
203
204
    /**
205
     * Renders a view file.
206
     *
207
     * If [[theme]] is enabled (not null), it will try to render the themed version of the view file as long
208
     * as it is available.
209
     *
210
     * The method will call [[FileHelper::localize()]] to localize the view file.
211
     *
212
     * If [[renderers|renderer]] is enabled (not null), the method will use it to render the view file.
213
     * Otherwise, it will simply include the view file as a normal PHP file, capture its output and
214
     * return it as a string.
215
     *
216
     * @param string $viewFile the view file. This can be either an absolute file path or an alias of it.
217
     * @param array $params the parameters (name-value pairs) that will be extracted and made available in the view file.
218
     * @param object $context the context that the view should use for rendering the view. If null,
219
     * existing [[context]] will be used.
220
     * @return string the rendering result
221
     * @throws ViewNotFoundException if the view file does not exist
222
     */
223 76
    public function renderFile($viewFile, $params = [], $context = null)
224
    {
225 76
        $viewFile = $requestedFile = Yii::getAlias($viewFile);
226
227 76
        if ($this->theme !== null) {
228 1
            $viewFile = $this->theme->applyTo($viewFile);
229
        }
230 76
        if (is_file($viewFile)) {
231 75
            $viewFile = FileHelper::localize($viewFile);
232
        } else {
233 2
            throw new ViewNotFoundException("The view file does not exist: $viewFile");
234
        }
235
236 75
        $oldContext = $this->context;
237 75
        if ($context !== null) {
238 25
            $this->context = $context;
239
        }
240 75
        $output = '';
241 75
        $this->_viewFiles[] = [
242 75
            'resolved' => $viewFile,
243 75
            'requested' => $requestedFile
244
        ];
245
246 75
        if ($this->beforeRender($viewFile, $params)) {
247 75
            Yii::debug("Rendering view file: $viewFile", __METHOD__);
248 75
            $ext = pathinfo($viewFile, PATHINFO_EXTENSION);
249 75
            if (isset($this->renderers[$ext])) {
250
                if (is_array($this->renderers[$ext]) || is_string($this->renderers[$ext])) {
251
                    $this->renderers[$ext] = Yii::createObject($this->renderers[$ext]);
252
                }
253
                /* @var $renderer ViewRenderer */
254
                $renderer = $this->renderers[$ext];
255
                $output = $renderer->render($this, $viewFile, $params);
256
            } else {
257 75
                $output = $this->renderPhpFile($viewFile, $params);
258
            }
259 75
            $this->afterRender($viewFile, $params, $output);
260
        }
261
262 75
        array_pop($this->_viewFiles);
263 75
        $this->context = $oldContext;
264
265 75
        return $output;
266
    }
267
268
    /**
269
     * @return string|bool the view file currently being rendered. False if no view file is being rendered.
270
     */
271
    public function getViewFile()
272
    {
273
        return empty($this->_viewFiles) ? false : end($this->_viewFiles)['resolved'];
274
    }
275
276
    /**
277
     * @return string|bool the requested view currently being rendered. False if no view file is being rendered.
278
     * @since 2.0.16
279
     */
280 6
    protected function getRequestedViewFile()
281
    {
282 6
        return empty($this->_viewFiles) ? false : end($this->_viewFiles)['requested'];
283
    }
284
285
    /**
286
     * This method is invoked right before [[renderFile()]] renders a view file.
287
     * The default implementation will trigger the [[EVENT_BEFORE_RENDER]] event.
288
     * If you override this method, make sure you call the parent implementation first.
289
     * @param string $viewFile the view file to be rendered.
290
     * @param array $params the parameter array passed to the [[render()]] method.
291
     * @return bool whether to continue rendering the view file.
292
     */
293 75
    public function beforeRender($viewFile, $params)
294
    {
295 75
        $event = new ViewEvent([
296 75
            'viewFile' => $viewFile,
297 75
            'params' => $params,
298
        ]);
299 75
        $this->trigger(self::EVENT_BEFORE_RENDER, $event);
300
301 75
        return $event->isValid;
302
    }
303
304
    /**
305
     * This method is invoked right after [[renderFile()]] renders a view file.
306
     * The default implementation will trigger the [[EVENT_AFTER_RENDER]] event.
307
     * If you override this method, make sure you call the parent implementation first.
308
     * @param string $viewFile the view file being rendered.
309
     * @param array $params the parameter array passed to the [[render()]] method.
310
     * @param string $output the rendering result of the view file. Updates to this parameter
311
     * will be passed back and returned by [[renderFile()]].
312
     */
313 75
    public function afterRender($viewFile, $params, &$output)
314
    {
315 75
        if ($this->hasEventHandlers(self::EVENT_AFTER_RENDER)) {
316
            $event = new ViewEvent([
317
                'viewFile' => $viewFile,
318
                'params' => $params,
319
                'output' => $output,
320
            ]);
321
            $this->trigger(self::EVENT_AFTER_RENDER, $event);
322
            $output = $event->output;
323
        }
324 75
    }
325
326
    /**
327
     * Renders a view file as a PHP script.
328
     *
329
     * This method treats the view file as a PHP script and includes the file.
330
     * It extracts the given parameters and makes them available in the view file.
331
     * The method captures the output of the included view file and returns it as a string.
332
     *
333
     * This method should mainly be called by view renderer or [[renderFile()]].
334
     *
335
     * @param string $_file_ the view file.
336
     * @param array $_params_ the parameters (name-value pairs) that will be extracted and made available in the view file.
337
     * @return string the rendering result
338
     * @throws \Exception
339
     * @throws \Throwable
340
     */
341 75
    public function renderPhpFile($_file_, $_params_ = [])
342
    {
343 75
        $_obInitialLevel_ = ob_get_level();
344 75
        ob_start();
345 75
        ob_implicit_flush(false);
346 75
        extract($_params_, EXTR_OVERWRITE);
347
        try {
348 75
            require $_file_;
349 75
            return ob_get_clean();
350 1
        } catch (\Exception $e) {
351 1
            while (ob_get_level() > $_obInitialLevel_) {
352 1
                if (!@ob_end_clean()) {
353
                    ob_clean();
354
                }
355
            }
356 1
            throw $e;
357
        } catch (\Throwable $e) {
0 ignored issues
show
Bug introduced by
The class Throwable does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
358
            while (ob_get_level() > $_obInitialLevel_) {
359
                if (!@ob_end_clean()) {
360
                    ob_clean();
361
                }
362
            }
363
            throw $e;
364
        }
365
    }
366
367
    /**
368
     * Renders dynamic content returned by the given PHP statements.
369
     * This method is mainly used together with content caching (fragment caching and page caching)
370
     * when some portions of the content (called *dynamic content*) should not be cached.
371
     * The dynamic content must be returned by some PHP statements.
372
     * @param string $statements the PHP statements for generating the dynamic content.
373
     * @return string the placeholder of the dynamic content, or the dynamic content if there is no
374
     * active content cache currently.
375
     */
376 18
    public function renderDynamic($statements)
377
    {
378 18
        if (!empty($this->cacheStack)) {
0 ignored issues
show
Deprecated Code introduced by
The property yii\base\View::$cacheStack has been deprecated with message: Since 2.0.14. Do not use this property directly. Use methods [[getDynamicContents()]],
[[pushDynamicContent()]], [[popDynamicContent()]] instead.

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
379 16
            $n = count($this->dynamicPlaceholders);
0 ignored issues
show
Deprecated Code introduced by
The property yii\base\View::$dynamicPlaceholders has been deprecated with message: Since 2.0.14. Do not use this property directly. Use methods [[getDynamicPlaceholders()]],
[[setDynamicPlaceholders()]], [[addDynamicPlaceholder()]] instead.

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
380 16
            $placeholder = "<![CDATA[YII-DYNAMIC-$n]]>";
381 16
            $this->addDynamicPlaceholder($placeholder, $statements);
382
383 16
            return $placeholder;
384
        }
385
386 2
        return $this->evaluateDynamicContent($statements);
387
    }
388
389
    /**
390
     * {@inheritdoc}
391
     */
392
    public function getDynamicPlaceholders()
393
    {
394
        return $this->dynamicPlaceholders;
0 ignored issues
show
Deprecated Code introduced by
The property yii\base\View::$dynamicPlaceholders has been deprecated with message: Since 2.0.14. Do not use this property directly. Use methods [[getDynamicPlaceholders()]],
[[setDynamicPlaceholders()]], [[addDynamicPlaceholder()]] instead.

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
395
    }
396
397
    /**
398
     * {@inheritdoc}
399
     */
400
    public function setDynamicPlaceholders($placeholders)
401
    {
402
        $this->dynamicPlaceholders = $placeholders;
0 ignored issues
show
Deprecated Code introduced by
The property yii\base\View::$dynamicPlaceholders has been deprecated with message: Since 2.0.14. Do not use this property directly. Use methods [[getDynamicPlaceholders()]],
[[setDynamicPlaceholders()]], [[addDynamicPlaceholder()]] instead.

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
403
    }
404
405
    /**
406
     * {@inheritdoc}
407
     */
408 16
    public function addDynamicPlaceholder($placeholder, $statements)
409
    {
410 16
        foreach ($this->cacheStack as $cache) {
0 ignored issues
show
Deprecated Code introduced by
The property yii\base\View::$cacheStack has been deprecated with message: Since 2.0.14. Do not use this property directly. Use methods [[getDynamicContents()]],
[[pushDynamicContent()]], [[popDynamicContent()]] instead.

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
411 16
            if ($cache instanceof DynamicContentAwareInterface) {
412 16
                $cache->addDynamicPlaceholder($placeholder, $statements);
413
            } else {
414
                // TODO: Remove in 2.1
415 16
                $cache->dynamicPlaceholders[$placeholder] = $statements;
416
            }
417
        }
418 16
        $this->dynamicPlaceholders[$placeholder] = $statements;
0 ignored issues
show
Deprecated Code introduced by
The property yii\base\View::$dynamicPlaceholders has been deprecated with message: Since 2.0.14. Do not use this property directly. Use methods [[getDynamicPlaceholders()]],
[[setDynamicPlaceholders()]], [[addDynamicPlaceholder()]] instead.

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
419 16
}
420
421
    /**
422
     * Evaluates the given PHP statements.
423
     * This method is mainly used internally to implement dynamic content feature.
424
     * @param string $statements the PHP statements to be evaluated.
425
     * @return mixed the return value of the PHP statements.
426
     */
427 18
    public function evaluateDynamicContent($statements)
428
    {
429 18
        return eval($statements);
430
    }
431
432
    /**
433
     * Returns a list of currently active dynamic content class instances.
434
     * @return DynamicContentAwareInterface[] class instances supporting dynamic contents.
435
     * @since 2.0.14
436
     */
437 16
    public function getDynamicContents()
438
    {
439 16
        return $this->cacheStack;
0 ignored issues
show
Deprecated Code introduced by
The property yii\base\View::$cacheStack has been deprecated with message: Since 2.0.14. Do not use this property directly. Use methods [[getDynamicContents()]],
[[pushDynamicContent()]], [[popDynamicContent()]] instead.

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
440
    }
441
442
    /**
443
     * Adds a class instance supporting dynamic contents to the end of a list of currently active
444
     * dynamic content class instances.
445
     * @param DynamicContentAwareInterface $instance class instance supporting dynamic contents.
446
     * @since 2.0.14
447
     */
448 21
    public function pushDynamicContent(DynamicContentAwareInterface $instance)
449
    {
450 21
        $this->cacheStack[] = $instance;
0 ignored issues
show
Deprecated Code introduced by
The property yii\base\View::$cacheStack has been deprecated with message: Since 2.0.14. Do not use this property directly. Use methods [[getDynamicContents()]],
[[pushDynamicContent()]], [[popDynamicContent()]] instead.

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
451 21
    }
452
453
    /**
454
     * Removes a last class instance supporting dynamic contents from a list of currently active
455
     * dynamic content class instances.
456
     * @since 2.0.14
457
     */
458 21
    public function popDynamicContent()
459
    {
460 21
        array_pop($this->cacheStack);
0 ignored issues
show
Deprecated Code introduced by
The property yii\base\View::$cacheStack has been deprecated with message: Since 2.0.14. Do not use this property directly. Use methods [[getDynamicContents()]],
[[pushDynamicContent()]], [[popDynamicContent()]] instead.

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
461 21
    }
462
463
    /**
464
     * Begins recording a block.
465
     *
466
     * This method is a shortcut to beginning [[Block]].
467
     * @param string $id the block ID.
468
     * @param bool $renderInPlace whether to render the block content in place.
469
     * Defaults to false, meaning the captured block will not be displayed.
470
     * @return Block the Block widget instance
471
     */
472
    public function beginBlock($id, $renderInPlace = false)
473
    {
474
        return Block::begin([
475
            'id' => $id,
476
            'renderInPlace' => $renderInPlace,
477
            'view' => $this,
478
        ]);
479
    }
480
481
    /**
482
     * Ends recording a block.
483
     */
484
    public function endBlock()
485
    {
486
        Block::end();
487
    }
488
489
    /**
490
     * Begins the rendering of content that is to be decorated by the specified view.
491
     *
492
     * This method can be used to implement nested layout. For example, a layout can be embedded
493
     * in another layout file specified as '@app/views/layouts/base.php' like the following:
494
     *
495
     * ```php
496
     * <?php $this->beginContent('@app/views/layouts/base.php'); ?>
497
     * //...layout content here...
498
     * <?php $this->endContent(); ?>
499
     * ```
500
     *
501
     * @param string $viewFile the view file that will be used to decorate the content enclosed by this widget.
502
     * This can be specified as either the view file path or [path alias](guide:concept-aliases).
503
     * @param array $params the variables (name => value) to be extracted and made available in the decorative view.
504
     * @return ContentDecorator the ContentDecorator widget instance
505
     * @see ContentDecorator
506
     */
507
    public function beginContent($viewFile, $params = [])
508
    {
509
        return ContentDecorator::begin([
510
            'viewFile' => $viewFile,
511
            'params' => $params,
512
            'view' => $this,
513
        ]);
514
    }
515
516
    /**
517
     * Ends the rendering of content.
518
     */
519
    public function endContent()
520
    {
521
        ContentDecorator::end();
522
    }
523
524
    /**
525
     * Begins fragment caching.
526
     *
527
     * This method will display cached content if it is available.
528
     * If not, it will start caching and would expect an [[endCache()]]
529
     * call to end the cache and save the content into cache.
530
     * A typical usage of fragment caching is as follows,
531
     *
532
     * ```php
533
     * if ($this->beginCache($id)) {
534
     *     // ...generate content here
535
     *     $this->endCache();
536
     * }
537
     * ```
538
     *
539
     * @param string $id a unique ID identifying the fragment to be cached.
540
     * @param array $properties initial property values for [[FragmentCache]]
541
     * @return bool whether you should generate the content for caching.
542
     * False if the cached version is available.
543
     */
544 10
    public function beginCache($id, $properties = [])
545
    {
546 10
        $properties['id'] = $id;
547 10
        $properties['view'] = $this;
548
        /* @var $cache FragmentCache */
549 10
        $cache = FragmentCache::begin($properties);
550 10
        if ($cache->getCachedContent() !== false) {
551 7
            $this->endCache();
552
553 7
            return false;
554
        }
555
556 10
        return true;
557
    }
558
559
    /**
560
     * Ends fragment caching.
561
     */
562 10
    public function endCache()
563
    {
564 10
        FragmentCache::end();
565 10
    }
566
567
    /**
568
     * Marks the beginning of a page.
569
     */
570 50
    public function beginPage()
571
    {
572 50
        ob_start();
573 50
        ob_implicit_flush(false);
574
575 50
        $this->trigger(self::EVENT_BEGIN_PAGE);
576 50
    }
577
578
    /**
579
     * Marks the ending of a page.
580
     */
581
    public function endPage()
582
    {
583
        $this->trigger(self::EVENT_END_PAGE);
584
        ob_end_flush();
585
    }
586
}
587