Completed
Push — master ( f2187f...c03a3a )
by Sam
02:40
created

src/Template.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * This file contains only the Text class
4
 *
5
 * @package Tabulate
6
 */
7
8
namespace WordPress\Tabulate;
9
10
/**
11
 * A Template is a wrapper for a Twig file
12
 */
13
class Template {
14
15
	/**
16
	 * The name of the template to render (if not using a Twig string).
17
	 *
18
	 * @var string
19
	 */
20
	protected $template_name;
21
22
	/**
23
	 * The Twig string to render (if not using a template file).
24
	 *
25
	 * @var string
26
	 */
27
	protected $template_string;
28
29
	/**
30
	 * The template data, all of which is passed to the Twig template.
31
	 *
32
	 * @var string[]
33
	 */
34
	protected $data;
35
36
	/**
37
	 * Paths at which to find templates.
38
	 *
39
	 * @var string[]
40
	 */
41
	protected static $paths = array();
42
43
	/**
44
	 * The name of the transient used to store notices.
45
	 *
46
	 * @var string
47
	 */
48
	protected $transient_notices;
49
50
	/**
51
	 * Create a new template either with a file-based Twig template, or a Twig string.
52
	 *
53
	 * @global type $wpdb
54
	 * @param string|false $template_name   The name of a Twig file to render.
55
	 * @param string|false $template_string A Twig string to render.
56
	 */
57
	public function __construct( $template_name = false, $template_string = false ) {
58
		global $wpdb;
59
		$this->template_name = $template_name;
60
		$this->template_string = $template_string;
61
		$this->transient_notices = TABULATE_SLUG . '_notices';
62
		$notices = get_transient( $this->transient_notices );
63
		if ( ! is_array( $notices ) ) {
64
			$notices = array();
65
		}
66
		$this->data = array(
0 ignored issues
show
Documentation Bug introduced by
It seems like array('tabulate_version'...r_can('promote_users')) of type array<string,?,{"tabulat...nt_user_is_admin":"?"}> is incompatible with the declared type array<integer,string> of property $data.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
67
			'tabulate_version' => TABULATE_VERSION,
68
			'notices' => $notices,
69
			'wp_api' => Util::is_plugin_active( 'rest-api/plugin.php' ),
70
			'tfo_graphviz' => Util::is_plugin_active( 'tfo-graphviz/tfo-graphviz.php' ),
71
			'wpdb_prefix' => $wpdb->prefix,
72
			'current_user_is_admin' => current_user_can( 'promote_users' ),
73
		);
74
		self::add_path( __DIR__ . '/../templates' );
75
	}
76
77
	/**
78
	 * Add a filesystem path under which to look for template files.
79
	 *
80
	 * @param string $new_path The path to add.
81
	 */
82
	public static function add_path( $new_path ) {
83
		$path = realpath( $new_path );
84
		if ( ! in_array( $path, self::$paths, true ) ) {
85
			self::$paths[] = $path;
86
		}
87
	}
88
89
	/**
90
	 * Get a list of the filesystem paths searched for template files.
91
	 *
92
	 * @return string[] An array of paths
93
	 */
94
	public static function get_paths() {
95
		return self::$paths;
96
	}
97
98
	/**
99
	 * Get a list of templates in a given directory, across all registered template paths.
100
	 *
101
	 * @param string $directory The directory to search in.
102
	 */
103
	public function get_templates( $directory ) {
104
		$templates = array();
105
		foreach ( self::$paths as $path ) {
106
			$dir = $path . '/' . ltrim( $directory, '/' );
107
			foreach ( preg_grep( '/^[^\.].*\.(twig|html)$/', scandir( $dir ) ) as $file ) {
108
				$templates[] = $directory . '/' . $file;
109
			}
110
		}
111
		return $templates;
112
	}
113
114
	/**
115
	 * Magically set a template variable.
116
	 *
117
	 * @param string $name  The name of the variable.
118
	 * @param mixed  $value The value of the variable.
119
	 */
120
	public function __set( $name, $value ) {
121
		$this->data[ $name ] = $value;
122
	}
123
124
	/**
125
	 * Find out whether a given item of template data is set.
126
	 *
127
	 * @param string $name The property name.
128
	 * @return boolean
129
	 */
130
	public function __isset( $name ) {
131
		return isset( $this->data[ $name ] );
132
	}
133
134
	/**
135
	 * Get an item from this template's data.
136
	 *
137
	 * @param string $name The name of the template variable.
138
	 * @return mixed
139
	 */
140
	public function __get( $name ) {
141
		return $this->data[ $name ];
142
	}
143
144
	/**
145
	 * Add a notice. All notices are saved to a Transient, which is deleted when
146
	 * the template is rendered but otherwise available to all subsequent
147
	 * instances of the Template class.
148
	 *
149
	 * @param string $type Either 'updated' or 'error'.
150
	 * @param string $message The message to display.
151
	 */
152
	public function add_notice( $type, $message ) {
153
		$this->data['notices'][] = array(
154
			'type' => $type,
155
			'message' => $message,
156
		);
157
		set_transient( $this->transient_notices, $this->data['notices'] );
158
	}
159
160
	/**
161
	 * Render the template and output it.
162
	 *
163
	 * @return void
164
	 */
165
	public function __toString() {
166
		echo $this->render();
167
	}
168
169
	/**
170
	 * Render the template and return the output.
171
	 *
172
	 * @return string
173
	 */
174
	public function render() {
175
		delete_transient( $this->transient_notices );
176
		$loader = new \Twig_Loader_Filesystem( self::$paths );
177
		$twig = new \Twig_Environment( $loader );
178
179
		// Add some useful functions to Twig.
180
		$funcs = array( 'admin_url', '__', '_e', 'wp_create_nonce' );
181
		foreach ( $funcs as $f ) {
182
			$twig->addFunction( $f, new \Twig_SimpleFunction( $f, $f ) );
183
		}
184
		// Handle wp_nonce_field() differently in order to default it to returning the string.
185
		$wp_nonce_field = new \Twig_SimpleFunction( 'wp_nonce_field', function ( $action = -1, $name = "_wpnonce", $referer = true, $echo = false ) {
186
			return wp_nonce_field( $action, $name, $referer, $echo );
187
		} );
188
		$twig->addFunction( $wp_nonce_field );
189
190
		// Add titlecase filter.
191
		$titlecase_filter = new \Twig_SimpleFilter( 'titlecase', '\\WordPress\\Tabulate\\Text::titlecase' );
192
		$twig->addFilter( $titlecase_filter );
193
194
		// Add date and time filters.
195
		$date_filter = new \Twig_SimpleFilter( 'wp_date_format', '\\WordPress\\Tabulate\\Text::wp_date_format' );
196
		$twig->addFilter( $date_filter );
197
		$time_filter = new \Twig_SimpleFilter( 'wp_time_format', '\\WordPress\\Tabulate\\Text::wp_time_format' );
198
		$twig->addFilter( $time_filter );
199
		$twig->addFilter( new \Twig_SimpleFilter( 'get_date_from_gmt', 'get_date_from_gmt' ) );
200
201
		// Add strtolower filter.
202
		$strtolower_filter = new \Twig_SimpleFilter( 'strtolower', function( $str ) {
203
			if ( is_array( $str ) ) {
204
				return array_map( 'strtolower', $str );
205
			} else {
206
				return strtolower( $str );
207
			}
208
		} );
209
		$twig->addFilter( $strtolower_filter );
210
211
		// Enable debugging.
212
		if ( WP_DEBUG ) {
213
			$twig->enableDebug();
214
			$twig->addExtension( new \Twig_Extension_Debug() );
215
		}
216
217
		// Render the template.
218
		if ( ! empty( $this->template_string ) ) {
219
			$template = $twig->createTemplate( $this->template_string );
220
		} else {
221
			$template = $twig->loadTemplate( $this->template_name );
222
		}
223
		return $template->render( $this->data );
224
	}
225
}
226