1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Implements WordPress template hierarchy. |
4
|
|
|
* |
5
|
|
|
* @package Classy |
6
|
|
|
*/ |
7
|
|
|
|
8
|
|
|
namespace Classy; |
9
|
|
|
|
10
|
|
|
/** |
11
|
|
|
* Class Hierarchy. |
12
|
|
|
*/ |
13
|
|
|
class Hierarchy { |
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* Stores current request for multiple use. |
17
|
|
|
* |
18
|
|
|
* @var string/null |
19
|
|
|
*/ |
20
|
|
|
protected static $current_request = null; |
21
|
|
|
|
22
|
|
|
/** |
23
|
|
|
* Protected function to get current request type. |
24
|
|
|
* |
25
|
|
|
* @return string |
26
|
|
|
*/ |
27
|
|
|
protected static function check_request() { |
28
|
|
|
|
29
|
|
|
if ( is_404() ) : return '404'; |
30
|
|
|
|
31
|
|
|
elseif ( is_search() ) : return 'search'; |
32
|
|
|
|
33
|
|
|
elseif ( is_front_page() ) : return 'front-page'; |
34
|
|
|
|
35
|
|
|
elseif ( is_home() ) : return 'home'; |
36
|
|
|
|
37
|
|
|
elseif ( is_post_type_archive() ) : return 'post_type_archive'; |
38
|
|
|
|
39
|
|
|
elseif ( is_tax() ) : return 'taxonomy'; |
40
|
|
|
|
41
|
|
|
elseif ( is_attachment() ) : return 'attachment'; |
42
|
|
|
|
43
|
|
|
elseif ( is_single() ) : return 'single'; |
44
|
|
|
|
45
|
|
|
elseif ( self::is_classy_template() ) : return 'classy-template'; |
46
|
|
|
|
47
|
|
|
elseif ( is_page() ) : return 'page'; |
48
|
|
|
|
49
|
|
|
elseif ( is_singular() ) : return 'singular'; |
50
|
|
|
|
51
|
|
|
elseif ( is_category() ) : return 'category'; |
52
|
|
|
|
53
|
|
|
elseif ( is_tag() ) : return 'tag'; |
54
|
|
|
|
55
|
|
|
elseif ( is_author() ) : return 'author'; |
56
|
|
|
|
57
|
|
|
elseif ( is_date() ) : return 'date'; |
58
|
|
|
|
59
|
|
|
elseif ( is_archive() ) : return 'archive'; |
60
|
|
|
|
61
|
|
|
elseif ( is_paged() ) : return 'paged'; |
62
|
|
|
|
63
|
|
|
else : |
64
|
|
|
|
65
|
|
|
return 'index'; |
66
|
|
|
|
67
|
|
|
endif; |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
/** |
71
|
|
|
* Returns current request type. |
72
|
|
|
* |
73
|
|
|
* @return string |
74
|
|
|
*/ |
75
|
|
|
public static function get_current_request() { |
76
|
|
|
if ( is_null( self::$current_request ) ) { |
77
|
|
|
self::$current_request = self::check_request(); |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
return self::$current_request; |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
|
84
|
|
|
/** |
85
|
|
|
* Returns file's absolute path. |
86
|
|
|
* |
87
|
|
|
* @param string $type View/scope. |
88
|
|
|
* @param string $view Path to view ex: "post/archive". |
89
|
|
|
* |
90
|
|
|
* @return string Full file path. |
91
|
|
|
*/ |
92
|
|
|
public static function get_file_path( $type = 'view', $view ) { |
93
|
|
|
$view = str_replace( '.', '/', $view ); |
94
|
|
|
|
95
|
|
|
if ( 'view' === $type ) { |
96
|
|
|
return CLASSY_THEME_PATH . View::$folder . '/' . $view . '.blade.php'; |
97
|
|
|
} elseif ( 'scope' === $type ) { |
98
|
|
|
return CLASSY_THEME_PATH . Scope::$folder . '/' . $view . '.php'; |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
return ''; |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
/** |
105
|
|
|
* Checks if view exists. |
106
|
|
|
* |
107
|
|
|
* @param string $type View|scope. |
108
|
|
|
* @param string $file In blade path format, ex: layout|header. |
109
|
|
|
* |
110
|
|
|
* @return boolean true|false |
111
|
|
|
*/ |
112
|
|
|
public static function file_exists( $type = 'view', $file ) { |
113
|
|
|
return file_exists( |
114
|
|
|
self::get_file_path( $type, str_replace( '.', '/', $file ) ) |
115
|
|
|
); |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
/** |
119
|
|
|
* Returns view name for render, based on type of request. |
120
|
|
|
* |
121
|
|
|
* @param string $type View|scope. |
122
|
|
|
* @param string $page Request type like: home, single etc. |
123
|
|
|
* |
124
|
|
|
* @return array|bool |
125
|
|
|
*/ |
126
|
|
|
public static function get_available_file( $type = 'view', $page ) { |
127
|
|
|
$views = self::get_request_hierarchy_list( $page ); |
128
|
|
|
|
129
|
|
|
foreach ( $views as $view ) { |
130
|
|
|
if ( self::file_exists( $type, $view ) ) { |
|
|
|
|
131
|
|
|
return $view; |
132
|
|
|
} |
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
return false; |
136
|
|
|
} |
137
|
|
|
|
138
|
|
|
/** |
139
|
|
|
* Returns list of filenames to check, based on type of request. |
140
|
|
|
* |
141
|
|
|
* @param string $type Request type like: home, single etc. |
142
|
|
|
* |
143
|
|
|
* @return array |
144
|
|
|
*/ |
145
|
|
|
private static function get_request_hierarchy_list( $type ) { |
146
|
|
|
$views = array(); |
147
|
|
|
|
148
|
|
|
if ( 'home' === $type ) : |
149
|
|
|
$views[] = 'home'; |
150
|
|
|
elseif ( 'single' === $type ) : |
151
|
|
|
|
152
|
|
|
$views[] = get_post_type() . '.single'; |
153
|
|
|
$views[] = 'single'; |
154
|
|
|
|
155
|
|
|
elseif ( 'post_type_archive' === $type ) : |
156
|
|
|
|
157
|
|
|
$views[] = get_post_type() . '.archive'; |
158
|
|
|
$views[] = 'archive'; |
159
|
|
|
|
160
|
|
|
elseif ( 'taxonomy' === $type ) : |
161
|
|
|
|
162
|
|
|
$term = get_queried_object(); |
163
|
|
|
|
164
|
|
|
if ( ! empty( $term->slug ) ) { |
165
|
|
|
$taxonomy = $term->taxonomy; |
166
|
|
|
|
167
|
|
|
$views[] = "taxonomy.$taxonomy-{$term->slug}"; |
168
|
|
|
$views[] = "taxonomy.$taxonomy"; |
169
|
|
|
} |
170
|
|
|
|
171
|
|
|
$views[] = 'taxonomy.taxonomy'; |
172
|
|
|
$views[] = 'taxonomy'; |
173
|
|
|
|
174
|
|
|
elseif ( 'category' === $type ) : |
175
|
|
|
|
176
|
|
|
$category = get_queried_object(); |
177
|
|
|
|
178
|
|
|
if ( ! empty( $category->slug ) ) { |
179
|
|
|
$views[] = "category.{$category->slug}"; |
180
|
|
|
$views[] = "category.{$category->term_id}"; |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
$views[] = 'category.category'; |
184
|
|
|
$views[] = 'category'; |
185
|
|
|
|
186
|
|
|
elseif ( 'attachment' === $type ) : |
187
|
|
|
|
188
|
|
|
$attachment = get_queried_object(); |
189
|
|
|
|
190
|
|
|
if ( $attachment ) { |
191
|
|
|
if ( false !== strpos( $attachment->post_mime_type, '/' ) ) { |
192
|
|
|
list( $type, $subtype ) = explode( '/', $attachment->post_mime_type ); |
193
|
|
|
} else { |
194
|
|
|
list( $type, $subtype ) = array( $attachment->post_mime_type, '' ); |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
if ( ! empty( $subtype ) ) { |
198
|
|
|
$views[] = "attachment.{$type}.{$subtype}"; |
199
|
|
|
$views[] = "attachment.{$subtype}"; |
200
|
|
|
|
201
|
|
|
$views[] = "{$type}.{$subtype}"; |
202
|
|
|
$views[] = "{$subtype}"; |
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
$views[] = "attachment.{$type}"; |
206
|
|
|
$views[] = "{$type}"; |
207
|
|
|
} |
208
|
|
|
|
209
|
|
|
$views[] = 'attachment.attachment'; |
210
|
|
|
$views[] = 'attachment'; |
211
|
|
|
|
212
|
|
|
elseif ( 'tag' === $type ) : |
213
|
|
|
|
214
|
|
|
$tag = get_queried_object(); |
215
|
|
|
|
216
|
|
|
if ( ! empty( $tag->slug ) ) { |
217
|
|
|
$views[] = "post.tag.{$tag->slug}"; |
218
|
|
|
$views[] = "post.tag.{$tag->term_id}"; |
219
|
|
|
|
220
|
|
|
$views[] = "tag.{$tag->slug}"; |
221
|
|
|
$views[] = "tag.{$tag->term_id}"; |
222
|
|
|
} |
223
|
|
|
|
224
|
|
|
$views[] = 'post.tag'; |
225
|
|
|
$views[] = 'tag'; |
226
|
|
|
|
227
|
|
|
elseif ( 'author' === $type ) : |
228
|
|
|
|
229
|
|
|
$author = get_queried_object(); |
230
|
|
|
|
231
|
|
|
if ( $author instanceof \WP_User ) { |
|
|
|
|
232
|
|
|
$views[] = "post.author.{$author->user_nicename}"; |
233
|
|
|
$views[] = "post.author.{$author->ID}"; |
234
|
|
|
|
235
|
|
|
$views[] = "author.{$author->user_nicename}"; |
236
|
|
|
$views[] = "author.{$author->ID}"; |
237
|
|
|
} |
238
|
|
|
|
239
|
|
|
$views[] = 'post.author'; |
240
|
|
|
$views[] = 'author'; |
241
|
|
|
|
242
|
|
|
elseif ( 'front-page' === $type ) : |
243
|
|
|
|
244
|
|
|
$template = self::get_classy_template(); |
245
|
|
|
|
246
|
|
|
if ( ! empty( $template ) ) { |
247
|
|
|
$views[] = $template; |
248
|
|
|
$views[] = 'page.' . $template; |
249
|
|
|
$views[] = 'template.' . $template; |
250
|
|
|
} |
251
|
|
|
|
252
|
|
|
$views[] = 'front-page.front-page'; |
253
|
|
|
$views[] = 'front-page'; |
254
|
|
|
|
255
|
|
|
$views[] = 'home.home'; |
256
|
|
|
$views[] = 'home'; |
257
|
|
|
|
258
|
|
|
$views = array_merge( $views, self::get_request_hierarchy_list( 'post_type_archive' ) ); |
259
|
|
|
|
260
|
|
|
elseif ( 'classy-template' === $type ) : |
261
|
|
|
|
262
|
|
|
$template = self::get_classy_template(); |
263
|
|
|
|
264
|
|
|
$views[] = $template; |
265
|
|
|
$views[] = 'page.' . $template; |
266
|
|
|
$views[] = 'template.' . $template; |
267
|
|
|
$views[] = 'page.page'; |
268
|
|
|
$views[] = 'page'; |
269
|
|
|
|
270
|
|
|
elseif ( 'page' === $type ) : |
271
|
|
|
|
272
|
|
|
$id = get_queried_object_id(); |
273
|
|
|
|
274
|
|
|
$pagename = get_query_var( 'pagename' ); |
275
|
|
|
|
276
|
|
|
if ( ! $pagename && $id ) { |
277
|
|
|
// If a static page is set as the front page, $pagename will not be set. Retrieve it from the queried object. |
278
|
|
|
if ( $post = get_queried_object() ) { |
279
|
|
|
$pagename = $post->post_name; |
280
|
|
|
} |
281
|
|
|
} |
282
|
|
|
|
283
|
|
|
if ( $pagename ) { |
284
|
|
|
$views[] = 'page.' . $pagename; |
285
|
|
|
} |
286
|
|
|
|
287
|
|
|
if ( $id ) { |
288
|
|
|
$views[] = 'page.' . $id; |
289
|
|
|
} |
290
|
|
|
|
291
|
|
|
$views[] = 'page.page'; |
292
|
|
|
$views[] = 'page'; |
293
|
|
|
|
294
|
|
|
else : |
295
|
|
|
|
296
|
|
|
$views[] = $type; |
297
|
|
|
|
298
|
|
|
endif; |
299
|
|
|
|
300
|
|
|
$views[] = 'index'; |
301
|
|
|
|
302
|
|
|
return $views; |
303
|
|
|
} |
304
|
|
|
|
305
|
|
|
/** |
306
|
|
|
* Checks if this is classy custom template |
307
|
|
|
* |
308
|
|
|
* @return boolean |
309
|
|
|
*/ |
310
|
|
|
public static function is_classy_template() { |
311
|
|
|
return self::get_classy_template() ? true : false; |
312
|
|
|
} |
313
|
|
|
|
314
|
|
|
/** |
315
|
|
|
* Returns classy template name or boolean if this is not classy template. |
316
|
|
|
* |
317
|
|
|
* @return mixed |
318
|
|
|
*/ |
319
|
|
|
public static function get_classy_template() { |
320
|
|
|
preg_match( '/classy\-(.*)/', get_page_template_slug(), $matches ); |
321
|
|
|
|
322
|
|
|
if ( ! empty( $matches ) && isset( $matches[1] ) ) { |
323
|
|
|
return $matches[1]; |
324
|
|
|
} |
325
|
|
|
|
326
|
|
|
return false; |
327
|
|
|
} |
328
|
|
|
} |
329
|
|
|
|
This check looks for type mismatches where the missing type is
false
. This is usually indicative of an error condtion.Consider the follow example
This function either returns a new
DateTime
object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returnedfalse
before passing on the value to another function or method that may not be able to handle afalse
.