Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
File
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
4 / 4
8
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setTemplate
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 render
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 renderTemplate
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2declare(strict_types=1);
3/**
4 * Pop PHP Framework (https://www.popphp.org/)
5 *
6 * @link       https://github.com/popphp/popphp-framework
7 * @author     Nick Sagona, III <nick@popphp.org>
8 * @copyright  Copyright (c) 2009-2026 Nick Sagona, III
9 * @license    https://www.popphp.org/license     New BSD License
10 */
11
12/**
13 * @namespace
14 */
15namespace Pop\View\Template;
16
17/**
18 * View file template class
19 *
20 * @category   Pop
21 * @package    Pop\View
22 * @author     Nick Sagona, III <nick@popphp.org>
23 * @copyright  Copyright (c) 2009-2026 Nick Sagona, III
24 * @license    https://www.popphp.org/license     New BSD License
25 * @version    5.0.0
26 */
27class File extends AbstractTemplate
28{
29
30    /**
31     * Constructor
32     *
33     * Instantiate the view file template object
34     *
35     * @param  string $template
36     */
37    public function __construct(string $template)
38    {
39        $this->setTemplate($template);
40    }
41
42    /**
43     * Set view template
44     *
45     * @param  string $template
46     * @throws Exception
47     * @return static
48     */
49    public function setTemplate(string $template): static
50    {
51        if (!file_exists($template)) {
52            throw new Exception("Error: The template file '" . $template . "' does not exist.");
53        }
54        $this->template = $template;
55
56        return $this;
57    }
58
59    /**
60     * Render the view and return the output
61     *
62     * @param  ?array $data
63     * @throws \Exception
64     * @return string
65     */
66    public function render(?array $data = null): string
67    {
68        if ($data !== null) {
69            $this->data = $data;
70        }
71        $this->renderTemplate();
72        return $this->output;
73    }
74
75    /**
76     * Render view template file
77     *
78     * @return void
79     */
80    protected function renderTemplate(): void
81    {
82        foreach ($this->data as $key => $value) {
83            ${$key} = $value;
84        }
85
86        try {
87            ob_start();
88            include $this->template;
89            $this->output = ob_get_clean();
90        } catch (\Throwable $e) {
91            // ob_end_clean() (not ob_clean()) is required here: ob_clean() only empties the buffer's
92            // contents but leaves it on PHP's output-buffer stack, so a caller that catches this
93            // exception and continues execution is left with a dangling output buffer that silently
94            // swallows subsequent unrelated output. Catching \Throwable (not \Exception) matters too -
95            // a raw PHP/PHTML template can throw an Error (e.g. a typo'd function call), which would
96            // otherwise skip this cleanup entirely and leak the buffer via a different path.
97            ob_end_clean();
98            throw $e;
99        }
100    }
101
102}