Completed
Push — master ( e7ad5b...332fd2 )
by Glynn
14s queued 13s
created

BladeOne_Provider::base_view_path()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 2
nc 2
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare( strict_types=1 );
4
5
/**
6
 * Implementation of BladeOne for the PinkCrab Perique frameworks Renderable interface
7
 *
8
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
9
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
10
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
11
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
12
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
13
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
14
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
15
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
16
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
18
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19
 *
20
 * @author Glynn Quelch <[email protected]>
21
 * @license http://www.opensource.org/licenses/mit-license.html  MIT License
22
 * @package PinkCrab\BladeOne_Provider
23
 */
24
25
namespace PinkCrab\BladeOne;
26
27
use Exception;
28
use ReflectionClass;
29
use BadMethodCallException;
30
use eftec\bladeone\BladeOne;
31
use eftec\bladeonehtml\BladeOneHtml;
32
use PinkCrab\BladeOne\PinkCrab_BladeOne;
33
use PinkCrab\Perique\Interfaces\Renderable;
34
use PinkCrab\Perique\Services\View\View_Model;
35
use PinkCrab\Perique\Services\View\Component\Component;
36
use PinkCrab\Perique\Services\View\Component\Component_Compiler;
37
38
class BladeOne_Provider implements Renderable {
39
40
	/**
41
	 * BladeOne Instance
42
	 *
43
	 * @var PinkCrab_BladeOne
44
	 */
45
	protected static $blade;
46
47
	/**
48
	 * Access to the component compiler.
49
	 *
50
	 * @var Component_Compiler
51
	 */
52
	protected $component_compiler;
53
54
	/**
55
	 * Creates an instance with blade one.
56
	 *
57
	 * @param PinkCrab_BladeOne $blade
58
	 */
59
	final public function __construct( PinkCrab_BladeOne $blade ) {
60
		static::$blade = $blade;
61
	}
62
63
	/**
64
	 * Static constructor with BladeOne initialisation details
65
	 *
66
	 * @param string|array<mixed> $template_path If null then it uses (caller_folder)/views
67
	 * @param string $compiled_path If null then it uses (caller_folder)/compiles
68
	 * @param int $mode =[BladeOne::MODE_AUTO,BladeOne::MODE_DEBUG,BladeOne::MODE_FAST,BladeOne::MODE_SLOW][$i]
69
	 * @return self
70
	 */
71
	public static function init(
72
		$template_path = null,
73
		?string $compiled_path = null,
74
		int $mode = 0
75
	): self {
76
		return new static( new PinkCrab_BladeOne( $template_path, $compiled_path, $mode ) );
77
	}
78
79
	/**
80
	 * Returns the current BladeOne instance.
81
	 *
82
	 * @return BladeOne
83
	 */
84
	public function get_blade(): BladeOne {
85
		return static::$blade;
86
	}
87
88
	/**
89
	 * Returns the base view path.
90
	 *
91
	 * @return string
92
	 * @since 1.4.0
93
	 */
94
	public function base_view_path(): string {
95
		$paths = static::$blade->get_template_paths();
96
		return ! empty( $paths ) ? reset( $paths ) : '';
97
	}
98
99
	/**
100
	 * Sets the esc function.
101
	 *
102
	 * @param string $esc
103
	 * @return self
104
	 */
105
	public function set_esc_function( string $esc ): self {
106
		static::$blade->set_esc_function( $esc );
107
		return $this;
108
	}
109
110
	/**
111
	 * Sets the component compiler.
112
	 *
113
	 * @param Component_Compiler $compiler
114
	 * @return void
115
	 */
116
	public function set_component_compiler( Component_Compiler $compiler ): void {
117
		$this->component_compiler = $compiler;
118
	}
119
120
	/**
121
	 * Display a view and its context.
122
	 *
123
	 * @param string $view
124
	 * @param iterable<string, mixed> $data
125
	 * @param bool $print
126
	 * @return void|string
127
	 */
128
	public function render( string $view, iterable $data, bool $print = true ) {
129
		if ( $print ) {
130
			print static::$blade->run( $view, (array) $data ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
131
		} else {
132
			return static::$blade->run( $view, (array) $data );
133
		}
134
	}
135
136
	/**
137
	 * Renders a view Model
138
	 *
139
	 * @param View_Model $view_model
140
	 * @return string|void
141
	 */
142
	public function view_model( View_Model $view_model, bool $print = true ) {
143
		return $this->render( str_replace( array( '/', '\\' ), '.', $view_model->template() ), $view_model->data(), $print );
144
	}
145
146
		/**
147
	 * Renders a component.
148
	 *
149
	 * @param Component $component
150
	 * @return string|void
151
	 */
152
	public function component( Component $component, bool $print = true ) {
153
154
		// Throw exception of no compiler passed.
155
		if ( ! is_a( $this->component_compiler, Component_Compiler::class ) ) {
156
			throw new Exception( 'No component compiler passed to BladeOne' );
157
		}
158
159
		// Compile the component.
160
		$compiled = $this->component_compiler->compile( $component );
161
		return $this->render( str_replace( array( '/', '\\' ), '.', $compiled->template() ), $compiled->data(), $print );
162
	}
163
164
	/**
165
	 * magic instanced method caller.
166
	 *
167
	 * @param string $method
168
	 * @param array<mixed> $args
169
	 * @return mixed
170
	 * @throws BadMethodCallException
171
	 */
172
	public function __call( string $method, array $args = array() ) {
173
		if ( ! $this->is_method( $method ) ) {
174
			throw new BadMethodCallException( "{$method} is not a valid method on the BladeOne instance." );
175
		}
176
177
		return static::$blade->{$method}( ...$args );
178
	}
179
180
	/**
181
	 * Magic static method caller.
182
	 *
183
	 * @param string $method
184
	 * @param array<mixed> $args
185
	 * @return mixed
186
	 * @throws BadMethodCallException
187
	 */
188
	public static function __callStatic( string $method, array $args = array() ) {
189
		if ( ! static::is_static_method( $method ) ) {
190
			throw new BadMethodCallException( "{$method} is not a valid method on the BladeOne instance." );
191
		}
192
193
		return static::$blade::{$method}( ...$args );
194
	}
195
196
	/**
197
	 * Checks if the passed method exists, is public and isnt static.
198
	 *
199
	 * @param string $method
200
	 * @return bool
201
	 */
202
	protected function is_method( string $method ): bool {
203
		$class_reflection = new ReflectionClass( static::$blade );
204
205
		// Check method exists.
206
		if ( ! $class_reflection->hasMethod( $method ) ) {
207
			return false;
208
		}
209
210
		$method_reflection = $class_reflection->getMethod( $method );
211
212
		return $method_reflection->isPublic() && ! $method_reflection->isStatic();
213
	}
214
215
	/**
216
	 * Checks if the passed method exists, is public and IS static.
217
	 *
218
	 * @param string $method
219
	 * @return bool
220
	 */
221
	protected static function is_static_method( string $method ): bool {
222
		$class_reflection = new ReflectionClass( static::$blade );
223
224
		// Check method exists.
225
		if ( ! $class_reflection->hasMethod( $method ) ) {
226
			return false;
227
		}
228
229
		$method_reflection = $class_reflection->getMethod( $method );
230
		return $method_reflection->isPublic() && $method_reflection->isStatic();
231
	}
232
233
	/**
234
	 * Sets if piping is enabled in templates.
235
	 *
236
	 * @param bool $bool
237
	 * @return self
238
	 */
239
	public function allow_pipe( bool $bool = true ): self {
240
		static::$blade->pipeEnable = $bool; //phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
241
		return $this;
242
	}
243
244
	/**
245
	 * Register a handler for custom directives.
246
	 *
247
	 * @param string   $name
248
	 * @param callable $handler
249
	 * @return self
250
	 */
251
	public function directive( string $name, callable $handler ): self {
252
		static::$blade->directive( $name, $handler );
253
		return $this;
254
	}
255
256
	/**
257
	 * Register a handler for custom directives for run at runtime
258
	 *
259
	 * @param string   $name
260
	 * @param callable $handler
261
	 * @return self
262
	 */
263
	public function directive_rt( $name, callable $handler ): self {
264
		static::$blade->directiveRT( $name, $handler );
265
		return $this;
266
	}
267
268
	/**
269
	 * Define a template alias
270
	 *
271
	 * @param string      $view  example "folder.template"
272
	 * @param string|null $alias example "mynewop". If null then it uses the name of the template.
273
	 * @return self
274
	 */
275
	public function add_include( $view, $alias = null ): self {
276
		static::$blade->addInclude( $view, $alias );
277
		return $this;
278
	}
279
280
	/**
281
	 * Define a class with a namespace
282
	 *
283
	 * @param string $alias_name
284
	 * @param string $class_with_namespace
285
	 * @return self
286
	 */
287
	public function add_alias_classes( $alias_name, $class_with_namespace ): self {
288
		static::$blade->addAliasClasses( $alias_name, $class_with_namespace );
289
		return $this;
290
	}
291
292
	/**
293
	 * Set the compile mode
294
	 *
295
	 * @param int $mode BladeOne::MODE_AUTO, BladeOne::MODE_DEBUG, BladeOne::MODE_FAST, BladeOne::MODE_SLOW
296
	 * @return self
297
	 */
298
	public function set_mode( int $mode ): self {
299
		static::$blade->setMode( $mode );
300
		return $this;
301
	}
302
303
	/**
304
	 * Adds a global variable. If <b>$var_name</b> is an array then it merges all the values.
305
	 * <b>Example:</b>
306
	 * <pre>
307
	 * $this->share('variable',10.5);
308
	 * $this->share('variable2','hello');
309
	 * // or we could add the two variables as:
310
	 * $this->share(['variable'=>10.5,'variable2'=>'hello']);
311
	 * </pre>
312
	 *
313
	 * @param string|array<string, mixed> $var_name It is the name of the variable or it is an associative array
314
	 * @param mixed        $value
315
	 * @return $this
316
	 */
317
	public function share( $var_name, $value = null ): self {
318
		static::$blade->share( $var_name, $value );
319
		return $this;
320
	}
321
322
	/**
323
	 * Sets the function used for resolving classes with inject.
324
	 *
325
	 * @param callable $function
326
	 * @return $this
327
	 */
328
	public function set_inject_resolver( callable $function ): self {
329
		static::$blade->setInjectResolver( $function );
330
		return $this;
331
	}
332
333
	/**
334
	 * Set the file extension for the template files.
335
	 * It must includes the leading dot e.g. .blade.php
336
	 *
337
	 * @param string $file_extension Example: .prefix.ext
338
	 * @return $this
339
	 */
340
	public function set_file_extension( string $file_extension ): self {
341
		static::$blade->setFileExtension( $file_extension );
342
		return $this;
343
	}
344
345
	/**
346
	 * Set the file extension for the compiled files.
347
	 * Including the leading dot for the extension is required, e.g. .bladec
348
	 *
349
	 * @param string $file_extension
350
	 * @return $this
351
	 */
352
	public function set_compiled_extension( string $file_extension ): self {
353
		static::$blade->setCompiledExtension( $file_extension );
354
		return $this;
355
	}
356
357
}
358
359