forked from codeigniter4/CodeIgniter4
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathCell.php
More file actions
155 lines (127 loc) · 4.17 KB
/
Cell.php
File metadata and controls
155 lines (127 loc) · 4.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
<?php
declare(strict_types=1);
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <[email protected]>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace CodeIgniter\View\Cells;
use CodeIgniter\Exceptions\LogicException;
use CodeIgniter\Traits\PropertiesTrait;
use ReflectionClass;
use Stringable;
/**
* Class Cell
*
* The base class that View Cells should extend.
* Provides extended features for managing/rendering
* a single cell's contents.
*
* @function mount()
*/
class Cell implements Stringable
{
use PropertiesTrait;
/**
* The name of the view to render.
* If empty, will be determined based
* on the cell class' name.
*/
protected string $view = '';
/**
* Responsible for converting the view into HTML.
* Expected to be overridden by the child class
* in many occasions, but not all.
*/
public function render(): string
{
if (! function_exists('decamelize')) {
helper('inflector');
}
return $this->view($this->view);
}
/**
* Sets the view to use when rendered.
*
* @return $this
*/
public function setView(string $view)
{
$this->view = $view;
return $this;
}
/**
* Actually renders the view, and returns the HTML.
* In order to provide access to public properties and methods
* from within the view, this method extracts $data into the
* current scope and captures the output buffer instead of
* relying on the view service.
*
* @throws LogicException
*/
final protected function view(?string $view, array $data = []): string
{
$properties = $this->getPublicProperties();
$properties = $this->includeComputedProperties($properties);
$properties = array_merge($properties, $data);
$view = (string) $view;
if ($view === '') {
$viewName = decamelize(class_basename(static::class));
$directory = dirname((new ReflectionClass($this))->getFileName()) . DIRECTORY_SEPARATOR;
$possibleView1 = $directory . substr($viewName, 0, (int) strrpos($viewName, '_cell')) . '.php';
$possibleView2 = $directory . $viewName . '.php';
}
if ($view !== '' && ! is_file($view)) {
$directory = dirname((new ReflectionClass($this))->getFileName()) . DIRECTORY_SEPARATOR;
$view = $directory . $view . '.php';
}
$candidateViews = array_filter(
[$view, $possibleView1 ?? '', $possibleView2 ?? ''],
static fn (string $path): bool => $path !== '' && is_file($path),
);
if ($candidateViews === []) {
throw new LogicException(sprintf(
'Cannot locate the view file for the "%s" cell.',
static::class,
));
}
$foundView = current($candidateViews);
return (function () use ($properties, $foundView): string {
extract($properties);
ob_start();
include $foundView;
return ob_get_clean();
})();
}
/**
* Provides capability to render on string casting.
*/
public function __toString(): string
{
return $this->render();
}
/**
* Allows the developer to define computed properties
* as methods with `get` prefixed to the protected/private property name.
*/
private function includeComputedProperties(array $properties): array
{
$reservedProperties = ['data', 'view'];
$privateProperties = $this->getNonPublicProperties();
foreach ($privateProperties as $property) {
$name = $property->getName();
// don't include any methods in the base class
if (in_array($name, $reservedProperties, true)) {
continue;
}
$computedMethod = 'get' . ucfirst($name) . 'Property';
if (method_exists($this, $computedMethod)) {
$properties[$name] = $this->{$computedMethod}();
}
}
return $properties;
}
}