Issues (3)

src/PinkCrab_BladeOne.php (1 issue)

Labels
Severity
1
<?php
2
3
declare( strict_types=1 );
4
5
/**
6
 * Wrapper for BladeOne with HTML enabled
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_Engine
23
 */
24
25
// phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
26
27
namespace PinkCrab\BladeOne;
28
29
use COM;
30
use eftec\bladeone\BladeOne;
0 ignored issues
show
This use statement conflicts with another class in this namespace, PinkCrab\BladeOne\BladeOne. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
31
use eftec\bladeonehtml\BladeOneHtml;
32
use PinkCrab\Perique\Application\App;
33
use PinkCrab\Perique\Services\View\View;
34
use PinkCrab\Perique\Services\View\View_Model;
35
use PinkCrab\Perique\Services\View\Component\Component;
36
37
/**
38
 * Custom BladeOne Engine with HTML Escaping
39
 */
40
class PinkCrab_BladeOne extends BladeOne {
41
	use BladeOneHtml;
42
43
	public const SETUP_CONFIG = 'PinkCrab/BladeOne_Engine/Setup_Config';
44
45
	public const COMMENT_PHP  = 0;
46
	public const COMMENT_RAW  = 1;
47
	public const COMMENT_NONE = 2;
48
49
	/**
50
	 * Bob the constructor.
51
	 * The folder at $compiled_path is created in case it doesn't exist.
52
	 *
53
	 * @param string  $template_path If null then it uses (caller_folder)/views
54
	 * @param string  $compiled_path If null then it uses (caller_folder)/compiles
55
	 * @param integer $mode          =[BladeOne::MODE_AUTO,BladeOne::MODE_DEBUG,BladeOne::MODE_FAST,BladeOne::MODE_SLOW][$i]
56
	 * @param integer $comment_mode  =[BladeOne::COMMENT_PHP,BladeOne::COMMENT_RAW,BladeOne::COMMENT_NONE][$i]
57
	 */
58
	public function __construct( $template_path = null, $compiled_path = null, $mode = 0, $comment_mode = 0 ) {
59
		parent::__construct( $template_path, $compiled_path, $mode, $comment_mode );
60
61
		// Add the viewModel directive.
62
		$this->directiveRT( 'viewModel', fn( $expression ) => $this->view_model( $expression, true ) );
63
64
		// Add the component directive.
65
		$this->directiveRT( 'viewComponent', fn( $expression ) => $this->component( $expression, true ) );
66
67
		// Add the WP_Nonce directive.
68
		$this->directiveRT(
69
			'nonce',
70
			function ( string $action, ?string $field = null, bool $inc_referer = true ): void {
71
				\wp_nonce_field(
72
					$action,
73
					$field ?? '_pcnonce',
74
					$inc_referer,
75
					true
76
				);
77
			}
78
		);
79
80
		// Allow other plugins to add their own directives.
81
		\do_action( self::SETUP_CONFIG, $this );
82
	}
83
84
	/**
85
	 * The esc function to use
86
	 *
87
	 * @var callable(mixed):string
88
	 */
89
	protected static $esc_function = 'esc_html';
90
91
	/**
92
	 * The default echo format
93
	 *
94
	 * @var string
95
	 */
96
	protected string $echoFormat = '\esc_html(%s)'; //phpcs:ignore WordPress.NamingConventions.ValidVariableName.PropertyNotSnakeCase
97
98
99
	/**
100
	 * Sets the esc function to use
101
	 *
102
	 * @param string $esc_function
103
	 * @return void
104
	 */
105
	public function set_esc_function( string $esc_function ): void {
106
		// Throw exception if not a valid callable.
107
		if ( ! \is_callable( $esc_function ) ) {
108
			throw new \InvalidArgumentException( 'Invalid esc function provided.' );
109
		}
110
111
		static::$esc_function = $esc_function;
112
		$this->echoFormat     = sprintf( '\\%s(%%s)', $esc_function ); //phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
113
	}
114
115
	/**
116
	 * Returns the template paths
117
	 *
118
	 * @return string[]
119
	 */
120
	public function get_template_paths(): array {
121
		return $this->templatePath; //phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
122
	}
123
124
	/**
125
	 * Escape HTML entities in a string.
126
	 *
127
	 * @param integer|float|string|null|mixed[]|object $value
128
	 * @return string
129
	 */
130
	public static function e( $value ): string {
131
		if ( \is_null( $value ) ) {
132
			return '';
133
		}
134
		if ( \is_array( $value ) || \is_object( $value ) ) {
135
			return \call_user_func( static::$esc_function, \print_r( $value, true ) );//phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
136
		}
137
		if ( \is_numeric( $value ) ) {
138
			$value = (string) $value;
139
		}
140
		return \call_user_func( static::$esc_function, $value );
141
	}
142
143
	/**
144
	 * Renders  component
145
	 *
146
	 * @param Component $component  The component to render
147
	 * @param boolean   $print_mode Print or Return the HTML
148
	 *
149
	 * @return string|void
150
	 */
151
	public function component( Component $component, bool $print_mode = true ) {
152
		/**
153
		 * Creates a new instance of the view.
154
		 *
155
		 * @var View
156
		 */
157
		$view = App::view();
158
159
		return $view->component( $component, $print_mode );
160
	}
161
162
	/**
163
	 * Renders a view model
164
	 *
165
	 * @param View_Model $view_model The view model to render
166
	 * @param boolean    $print_mode Print or Return the HTML
167
	 *
168
	 * @return string|void
169
	 */
170
	public function view_model( View_Model $view_model, bool $print_mode = true ) {
171
		/**
172
		 * Creates a new instance of the view.
173
		 *
174
		 * @var View
175
		 */
176
		$view = App::view();
177
178
		return $view->view_model( $view_model, $print_mode );
179
	}
180
181
	/**
182
	 * Compile the auth statements into valid PHP.
183
	 *
184
	 * @param string $expression
185
	 * @return string
186
	 */
187
	protected function compileAuth( $expression = '' ): string {
188
		$role = $this->stripParentheses( $expression );
189
		if ( $role === '' ) {
190
			return $this->phpTag . 'if(!PinkCrab\FunctionConstructors\Strings\isBlank($this->currentUser)): ?>';
191
		}
192
193
		return $this->phpTag . "if(!PinkCrab\FunctionConstructors\Strings\isBlank(\$this->currentUser) && \$this->currentRole==$role): ?>";
194
	}
195
196
	/**
197
	 * Compile the elseauth statements into valid PHP.
198
	 *
199
	 * @param string $expression
200
	 * @return string
201
	 */
202
	protected function compileElseAuth( $expression = '' ): string {
203
		$role = $this->stripParentheses( $expression );
204
		if ( $role === '' ) {
205
			return $this->phpTag . 'else: ?>';
206
		}
207
208
		return $this->phpTag . "elseif(!PinkCrab\FunctionConstructors\Strings\isBlank(\$this->currentUser) && \$this->currentRole==$role): ?>";
209
	}
210
211
	/**
212
	 * Compile the guest statements into valid PHP.
213
	 *
214
	 * @param string|null $expression
215
	 * @return string
216
	 */
217
	protected function compileGuest( $expression = null ): string {
218
219
		if ( $expression === null ) {
220
			return $this->phpTag . 'if(PinkCrab\FunctionConstructors\Strings\isBlank($this->currentUser)): ?>';
221
		}
222
223
		$role = $this->stripParentheses( $expression );
224
		if ( $role === '' ) {
225
			return $this->phpTag . 'if(PinkCrab\FunctionConstructors\Strings\isBlank($this->currentUser)): ?>';
226
		}
227
228
		return $this->phpTag . "if(PinkCrab\FunctionConstructors\Strings\isBlank(\$this->currentUser) || \$this->currentRole!=$role): ?>";
229
	}
230
231
	/**
232
	 * Compile the else statements into valid PHP.
233
	 *
234
	 * @param string|null $expression
235
	 * @return string
236
	 */
237
	protected function compileElseGuest( $expression ): string {
238
		$role = $this->stripParentheses( $expression );
239
		if ( $role === '' ) {
240
			return $this->phpTag . 'else: ?>';
241
		}
242
243
		return $this->phpTag . "elseif(PinkCrab\FunctionConstructors\Strings\isBlank(\$this->currentUser) || \$this->currentRole!=$role): ?>";
244
	}
245
246
	/**
247
	 * Get the comment mode.
248
	 *
249
	 * @return integer
250
	 */
251
	public function getCommentMode(): int {
252
		return $this->commentMode;
253
	}
254
}
255