Completed
Pull Request — master (#892)
by Jared
02:40
created
lib/timber-helper.php 1 patch
Indentation   +647 added lines, -647 removed lines patch added patch discarded remove patch
@@ -5,664 +5,664 @@
 block discarded – undo
5 5
  */
6 6
 class TimberHelper {
7 7
 
8
-	/**
9
-	 * A utility for a one-stop shop for Transients
10
-	 * @api
11
-	 * @example
12
-	 * ```php
13
-	 * $favorites = Timber::transient('user-'.$uid.'-favorites', function() use ($uid) {
14
-	 *  	//some expensive query here that's doing something you want to store to a transient
15
-	 *  	return $favorites;
16
-	 * }, 600);
17
-	 * Timber::context['favorites'] = $favorites;
18
-	 * Timber::render('single.twig', $context);
19
-	 * ```
20
-	 *
21
-	 * @param string  $slug           Unique identifier for transient
22
-	 * @param callable $callback      Callback that generates the data that's to be cached
23
-	 * @param int     $transient_time (optional) Expiration of transients in seconds
24
-	 * @param int     $lock_timeout   (optional) How long (in seconds) to lock the transient to prevent race conditions
25
-	 * @param bool    $force          (optional) Force callback to be executed when transient is locked
26
-	 * @return mixed
27
-	 */
28
-	public static function transient( $slug, $callback, $transient_time = 0, $lock_timeout = 5, $force = false ) {
29
-		$slug = apply_filters( 'timber/transient/slug', $slug );
30
-
31
-		$enable_transients = ( $transient_time === false || ( defined( 'WP_DISABLE_TRANSIENTS' ) && WP_DISABLE_TRANSIENTS ) ) ? false : true;
32
-		$data = $enable_transients ? get_transient( $slug ) : false;
33
-
34
-		if ( false === $data ) {
35
-
36
-			if ( $enable_transients && self::_is_transient_locked( $slug ) ) {
37
-
38
-				$force = apply_filters( 'timber_force_transients', $force );
39
-				$force = apply_filters( 'timber_force_transient_' . $slug, $force );
40
-
41
-				if ( !$force ) {
42
-					//the server is currently executing the process.
43
-					//We're just gonna dump these users. Sorry!
44
-					return false;
45
-				}
46
-
47
-				$enable_transients = false;
48
-			}
49
-
50
-			// lock timeout shouldn't be higher than 5 seconds, unless
51
-			// remote calls with high timeouts are made here
52
-			if ( $enable_transients )
53
-				self::_lock_transient( $slug, $lock_timeout );
54
-
55
-			$data = $callback();
56
-
57
-			if ( $enable_transients ) {
58
-				set_transient( $slug, $data, $transient_time );
59
-				self::_unlock_transient( $slug );
60
-			}
61
-
62
-		}
63
-
64
-		return $data;
65
-
66
-	}
67
-
68
-	/**
69
-	 * @internal
70
-	 * @param string $slug
71
-	 * @param integer $lock_timeout
72
-	 */
73
-	static function _lock_transient( $slug, $lock_timeout ) {
74
-		set_transient( $slug . '_lock', true, $lock_timeout );
75
-	}
76
-
77
-	/**
78
-	 * @internal
79
-	 * @param string $slug
80
-	 */
81
-	static function _unlock_transient( $slug ) {
82
-		delete_transient( $slug . '_lock', true );
83
-	}
84
-
85
-	/**
86
-	 * @internal
87
-	 * @param string $slug
88
-	 */
89
-	static function _is_transient_locked( $slug ) {
90
-		return (bool)get_transient( $slug . '_lock' );
91
-	}
92
-
93
-	/* These are for measuring page render time */
94
-
95
-	/**
96
-	 * For measuring time, this will start a timer
97
-	 * @api
98
-	 * @return float
99
-	 */
100
-	public static function start_timer() {
101
-		$time = microtime();
102
-		$time = explode( ' ', $time );
103
-		$time = $time[1] + $time[0];
104
-		return $time;
105
-	}
106
-
107
-	/**
108
-	 * For stopping time and getting the data
109
-	 * @example
110
-	 * ```php
111
-	 * $start = TimberHelper::start_timer();
112
-	 * // do some stuff that takes awhile
113
-	 * echo TimberHelper::stop_timer( $start );
114
-	 * ```
115
-	 * @param int     $start
116
-	 * @return string
117
-	 */
118
-	public static function stop_timer( $start ) {
119
-		$time = microtime();
120
-		$time = explode( ' ', $time );
121
-		$time = $time[1] + $time[0];
122
-		$finish = $time;
123
-		$total_time = round( ( $finish - $start ), 4 );
124
-		return $total_time . ' seconds.';
125
-	}
126
-
127
-	/* Function Utilities
8
+    /**
9
+     * A utility for a one-stop shop for Transients
10
+     * @api
11
+     * @example
12
+     * ```php
13
+     * $favorites = Timber::transient('user-'.$uid.'-favorites', function() use ($uid) {
14
+     *  	//some expensive query here that's doing something you want to store to a transient
15
+     *  	return $favorites;
16
+     * }, 600);
17
+     * Timber::context['favorites'] = $favorites;
18
+     * Timber::render('single.twig', $context);
19
+     * ```
20
+     *
21
+     * @param string  $slug           Unique identifier for transient
22
+     * @param callable $callback      Callback that generates the data that's to be cached
23
+     * @param int     $transient_time (optional) Expiration of transients in seconds
24
+     * @param int     $lock_timeout   (optional) How long (in seconds) to lock the transient to prevent race conditions
25
+     * @param bool    $force          (optional) Force callback to be executed when transient is locked
26
+     * @return mixed
27
+     */
28
+    public static function transient( $slug, $callback, $transient_time = 0, $lock_timeout = 5, $force = false ) {
29
+        $slug = apply_filters( 'timber/transient/slug', $slug );
30
+
31
+        $enable_transients = ( $transient_time === false || ( defined( 'WP_DISABLE_TRANSIENTS' ) && WP_DISABLE_TRANSIENTS ) ) ? false : true;
32
+        $data = $enable_transients ? get_transient( $slug ) : false;
33
+
34
+        if ( false === $data ) {
35
+
36
+            if ( $enable_transients && self::_is_transient_locked( $slug ) ) {
37
+
38
+                $force = apply_filters( 'timber_force_transients', $force );
39
+                $force = apply_filters( 'timber_force_transient_' . $slug, $force );
40
+
41
+                if ( !$force ) {
42
+                    //the server is currently executing the process.
43
+                    //We're just gonna dump these users. Sorry!
44
+                    return false;
45
+                }
46
+
47
+                $enable_transients = false;
48
+            }
49
+
50
+            // lock timeout shouldn't be higher than 5 seconds, unless
51
+            // remote calls with high timeouts are made here
52
+            if ( $enable_transients )
53
+                self::_lock_transient( $slug, $lock_timeout );
54
+
55
+            $data = $callback();
56
+
57
+            if ( $enable_transients ) {
58
+                set_transient( $slug, $data, $transient_time );
59
+                self::_unlock_transient( $slug );
60
+            }
61
+
62
+        }
63
+
64
+        return $data;
65
+
66
+    }
67
+
68
+    /**
69
+     * @internal
70
+     * @param string $slug
71
+     * @param integer $lock_timeout
72
+     */
73
+    static function _lock_transient( $slug, $lock_timeout ) {
74
+        set_transient( $slug . '_lock', true, $lock_timeout );
75
+    }
76
+
77
+    /**
78
+     * @internal
79
+     * @param string $slug
80
+     */
81
+    static function _unlock_transient( $slug ) {
82
+        delete_transient( $slug . '_lock', true );
83
+    }
84
+
85
+    /**
86
+     * @internal
87
+     * @param string $slug
88
+     */
89
+    static function _is_transient_locked( $slug ) {
90
+        return (bool)get_transient( $slug . '_lock' );
91
+    }
92
+
93
+    /* These are for measuring page render time */
94
+
95
+    /**
96
+     * For measuring time, this will start a timer
97
+     * @api
98
+     * @return float
99
+     */
100
+    public static function start_timer() {
101
+        $time = microtime();
102
+        $time = explode( ' ', $time );
103
+        $time = $time[1] + $time[0];
104
+        return $time;
105
+    }
106
+
107
+    /**
108
+     * For stopping time and getting the data
109
+     * @example
110
+     * ```php
111
+     * $start = TimberHelper::start_timer();
112
+     * // do some stuff that takes awhile
113
+     * echo TimberHelper::stop_timer( $start );
114
+     * ```
115
+     * @param int     $start
116
+     * @return string
117
+     */
118
+    public static function stop_timer( $start ) {
119
+        $time = microtime();
120
+        $time = explode( ' ', $time );
121
+        $time = $time[1] + $time[0];
122
+        $finish = $time;
123
+        $total_time = round( ( $finish - $start ), 4 );
124
+        return $total_time . ' seconds.';
125
+    }
126
+
127
+    /* Function Utilities
128 128
 	======================== */
129 129
 
130
-	/**
131
-	 * Calls a function with an output buffer. This is useful if you have a function that outputs text that you want to capture and use within a twig template.
132
-	 * @example
133
-	 * ```php
134
-	 * function the_form() {
135
-	 *     echo '<form action="form.php"><input type="text" /><input type="submit /></form>';
136
-	 * }
137
-	 *
138
-	 * $context = Timber::get_context();
139
-	 * $context['post'] = new TimberPost();
140
-	 * $context['my_form'] = TimberHelper::ob_function('the_form');
141
-	 * Timber::render('single-form.twig', $context);
142
-	 * ```
143
-	 * ```twig
144
-	 * <h1>{{ post.title }}</h1>
145
-	 * {{ my_form }}
146
-	 * ```
147
-	 * ```html
148
-	 * <h1>Apply to my contest!</h1>
149
-	 * <form action="form.php"><input type="text" /><input type="submit /></form>
150
-	 * ```
151
-	 * @api
152
-	 * @param callback $function
153
-	 * @param array   $args
154
-	 * @return string
155
-	 */
156
-	public static function ob_function( $function, $args = array( null ) ) {
157
-		ob_start();
158
-		call_user_func_array( $function, $args );
159
-		$data = ob_get_contents();
160
-		ob_end_clean();
161
-		return $data;
162
-	}
163
-
164
-	/**
165
-	 *
166
-	 *
167
-	 * @param string  $function_name
168
-	 * @param integer[]   $defaults
169
-	 * @param bool    $return_output_buffer
170
-	 * @return TimberFunctionWrapper
171
-	 */
172
-	public static function function_wrapper( $function_name, $defaults = array(), $return_output_buffer = false ) {
173
-		return new TimberFunctionWrapper( $function_name, $defaults, $return_output_buffer );
174
-	}
175
-
176
-	/**
177
-	 *
178
-	 *
179
-	 * @param mixed $arg that you want to error_log
180
-	 * @return void
181
-	 */
182
-	public static function error_log( $arg ) {
183
-		if ( !WP_DEBUG ) {
184
-			return;
185
-		}
186
-		if ( is_object( $arg ) || is_array( $arg ) ) {
187
-			$arg = print_r( $arg, true );
188
-		}
189
-		return error_log( $arg );
190
-	}
191
-
192
-	/**
193
-	 *
194
-	 *
195
-	 * @param string  $separator
196
-	 * @param string  $seplocation
197
-	 * @return string
198
-	 */
199
-	public static function get_wp_title( $separator = ' ', $seplocation = 'left' ) {
200
-		$separator = apply_filters( 'timber_wp_title_seperator', $separator );
201
-		return trim( wp_title( $separator, false, $seplocation ) );
202
-	}
203
-
204
-	/* Text Utilities
130
+    /**
131
+     * Calls a function with an output buffer. This is useful if you have a function that outputs text that you want to capture and use within a twig template.
132
+     * @example
133
+     * ```php
134
+     * function the_form() {
135
+     *     echo '<form action="form.php"><input type="text" /><input type="submit /></form>';
136
+     * }
137
+     *
138
+     * $context = Timber::get_context();
139
+     * $context['post'] = new TimberPost();
140
+     * $context['my_form'] = TimberHelper::ob_function('the_form');
141
+     * Timber::render('single-form.twig', $context);
142
+     * ```
143
+     * ```twig
144
+     * <h1>{{ post.title }}</h1>
145
+     * {{ my_form }}
146
+     * ```
147
+     * ```html
148
+     * <h1>Apply to my contest!</h1>
149
+     * <form action="form.php"><input type="text" /><input type="submit /></form>
150
+     * ```
151
+     * @api
152
+     * @param callback $function
153
+     * @param array   $args
154
+     * @return string
155
+     */
156
+    public static function ob_function( $function, $args = array( null ) ) {
157
+        ob_start();
158
+        call_user_func_array( $function, $args );
159
+        $data = ob_get_contents();
160
+        ob_end_clean();
161
+        return $data;
162
+    }
163
+
164
+    /**
165
+     *
166
+     *
167
+     * @param string  $function_name
168
+     * @param integer[]   $defaults
169
+     * @param bool    $return_output_buffer
170
+     * @return TimberFunctionWrapper
171
+     */
172
+    public static function function_wrapper( $function_name, $defaults = array(), $return_output_buffer = false ) {
173
+        return new TimberFunctionWrapper( $function_name, $defaults, $return_output_buffer );
174
+    }
175
+
176
+    /**
177
+     *
178
+     *
179
+     * @param mixed $arg that you want to error_log
180
+     * @return void
181
+     */
182
+    public static function error_log( $arg ) {
183
+        if ( !WP_DEBUG ) {
184
+            return;
185
+        }
186
+        if ( is_object( $arg ) || is_array( $arg ) ) {
187
+            $arg = print_r( $arg, true );
188
+        }
189
+        return error_log( $arg );
190
+    }
191
+
192
+    /**
193
+     *
194
+     *
195
+     * @param string  $separator
196
+     * @param string  $seplocation
197
+     * @return string
198
+     */
199
+    public static function get_wp_title( $separator = ' ', $seplocation = 'left' ) {
200
+        $separator = apply_filters( 'timber_wp_title_seperator', $separator );
201
+        return trim( wp_title( $separator, false, $seplocation ) );
202
+    }
203
+
204
+    /* Text Utilities
205 205
 	======================== */
206 206
 
207
-	/**
208
-	 *
209
-	 *
210
-	 * @param string  $text
211
-	 * @param int     $num_words
212
-	 * @param string|null|false  $more text to appear in "Read more...". Null to use default, false to hide
213
-	 * @param string  $allowed_tags
214
-	 * @return string
215
-	 */
216
-	public static function trim_words( $text, $num_words = 55, $more = null, $allowed_tags = 'p a span b i br blockquote' ) {
217
-		if ( null === $more ) {
218
-			$more = __( '&hellip;' );
219
-		}
220
-		$original_text = $text;
221
-		$allowed_tag_string = '';
222
-		foreach ( explode( ' ', apply_filters( 'timber/trim_words/allowed_tags', $allowed_tags ) ) as $tag ) {
223
-			$allowed_tag_string .= '<' . $tag . '>';
224
-		}
225
-		$text = strip_tags( $text, $allowed_tag_string );
226
-		/* translators: If your word count is based on single characters (East Asian characters), enter 'characters'. Otherwise, enter 'words'. Do not translate into your own language. */
227
-		if ( 'characters' == _x( 'words', 'word count: words or characters?' ) && preg_match( '/^utf\-?8$/i', get_option( 'blog_charset' ) ) ) {
228
-			$text = trim( preg_replace( "/[\n\r\t ]+/", ' ', $text ), ' ' );
229
-			preg_match_all( '/./u', $text, $words_array );
230
-			$words_array = array_slice( $words_array[0], 0, $num_words + 1 );
231
-			$sep = '';
232
-		} else {
233
-			$words_array = preg_split( "/[\n\r\t ]+/", $text, $num_words + 1, PREG_SPLIT_NO_EMPTY );
234
-			$sep = ' ';
235
-		}
236
-		if ( count( $words_array ) > $num_words ) {
237
-			array_pop( $words_array );
238
-			$text = implode( $sep, $words_array );
239
-			$text = $text . $more;
240
-		} else {
241
-			$text = implode( $sep, $words_array );
242
-		}
243
-		$text = self::close_tags( $text );
244
-		return apply_filters( 'wp_trim_words', $text, $num_words, $more, $original_text );
245
-	}
246
-
247
-	/**
248
-	 *
249
-	 *
250
-	 * @param string  $html
251
-	 * @return string
252
-	 */
253
-	public static function close_tags( $html ) {
254
-		//put all opened tags into an array
255
-		preg_match_all( '#<([a-z]+)(?: .*)?(?<![/|/ ])>#iU', $html, $result );
256
-		$openedtags = $result[1];
257
-		//put all closed tags into an array
258
-		preg_match_all( '#</([a-z]+)>#iU', $html, $result );
259
-		$closedtags = $result[1];
260
-		$len_opened = count( $openedtags );
261
-		// all tags are closed
262
-		if ( count( $closedtags ) == $len_opened ) {
263
-			return $html;
264
-		}
265
-		$openedtags = array_reverse( $openedtags );
266
-		// close tags
267
-		for ( $i = 0; $i < $len_opened; $i++ ) {
268
-			if ( !in_array( $openedtags[$i], $closedtags ) ) {
269
-				$html .= '</' . $openedtags[$i] . '>';
270
-			} else {
271
-				unset( $closedtags[array_search( $openedtags[$i], $closedtags )] );
272
-			}
273
-		}
274
-		$html = str_replace(array('</br>','</hr>','</wbr>'), '', $html);
275
-		$html = str_replace(array('<br>','<hr>','<wbr>'), array('<br />','<hr />','<wbr />'), $html);
276
-		return $html;
277
-	}
278
-
279
-	/* WordPress Query Utilities
207
+    /**
208
+     *
209
+     *
210
+     * @param string  $text
211
+     * @param int     $num_words
212
+     * @param string|null|false  $more text to appear in "Read more...". Null to use default, false to hide
213
+     * @param string  $allowed_tags
214
+     * @return string
215
+     */
216
+    public static function trim_words( $text, $num_words = 55, $more = null, $allowed_tags = 'p a span b i br blockquote' ) {
217
+        if ( null === $more ) {
218
+            $more = __( '&hellip;' );
219
+        }
220
+        $original_text = $text;
221
+        $allowed_tag_string = '';
222
+        foreach ( explode( ' ', apply_filters( 'timber/trim_words/allowed_tags', $allowed_tags ) ) as $tag ) {
223
+            $allowed_tag_string .= '<' . $tag . '>';
224
+        }
225
+        $text = strip_tags( $text, $allowed_tag_string );
226
+        /* translators: If your word count is based on single characters (East Asian characters), enter 'characters'. Otherwise, enter 'words'. Do not translate into your own language. */
227
+        if ( 'characters' == _x( 'words', 'word count: words or characters?' ) && preg_match( '/^utf\-?8$/i', get_option( 'blog_charset' ) ) ) {
228
+            $text = trim( preg_replace( "/[\n\r\t ]+/", ' ', $text ), ' ' );
229
+            preg_match_all( '/./u', $text, $words_array );
230
+            $words_array = array_slice( $words_array[0], 0, $num_words + 1 );
231
+            $sep = '';
232
+        } else {
233
+            $words_array = preg_split( "/[\n\r\t ]+/", $text, $num_words + 1, PREG_SPLIT_NO_EMPTY );
234
+            $sep = ' ';
235
+        }
236
+        if ( count( $words_array ) > $num_words ) {
237
+            array_pop( $words_array );
238
+            $text = implode( $sep, $words_array );
239
+            $text = $text . $more;
240
+        } else {
241
+            $text = implode( $sep, $words_array );
242
+        }
243
+        $text = self::close_tags( $text );
244
+        return apply_filters( 'wp_trim_words', $text, $num_words, $more, $original_text );
245
+    }
246
+
247
+    /**
248
+     *
249
+     *
250
+     * @param string  $html
251
+     * @return string
252
+     */
253
+    public static function close_tags( $html ) {
254
+        //put all opened tags into an array
255
+        preg_match_all( '#<([a-z]+)(?: .*)?(?<![/|/ ])>#iU', $html, $result );
256
+        $openedtags = $result[1];
257
+        //put all closed tags into an array
258
+        preg_match_all( '#</([a-z]+)>#iU', $html, $result );
259
+        $closedtags = $result[1];
260
+        $len_opened = count( $openedtags );
261
+        // all tags are closed
262
+        if ( count( $closedtags ) == $len_opened ) {
263
+            return $html;
264
+        }
265
+        $openedtags = array_reverse( $openedtags );
266
+        // close tags
267
+        for ( $i = 0; $i < $len_opened; $i++ ) {
268
+            if ( !in_array( $openedtags[$i], $closedtags ) ) {
269
+                $html .= '</' . $openedtags[$i] . '>';
270
+            } else {
271
+                unset( $closedtags[array_search( $openedtags[$i], $closedtags )] );
272
+            }
273
+        }
274
+        $html = str_replace(array('</br>','</hr>','</wbr>'), '', $html);
275
+        $html = str_replace(array('<br>','<hr>','<wbr>'), array('<br />','<hr />','<wbr />'), $html);
276
+        return $html;
277
+    }
278
+
279
+    /* WordPress Query Utilities
280 280
 	======================== */
281 281
 
282
-	/**
283
-	 * @param string  $key
284
-	 * @param string  $value
285
-	 * @return array|int
286
-	 * @deprecated 0.20.0
287
-	 */
288
-	public static function get_posts_by_meta( $key, $value ) {
289
-		global $wpdb;
290
-		$query = $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %s", $key, $value );
291
-		$results = $wpdb->get_col( $query );
292
-		$pids = array();
293
-		foreach ( $results as $result ) {
294
-			if ( get_post( $result ) ) {
295
-				$pids[] = $result;
296
-			}
297
-		}
298
-		if ( count( $pids ) ) {
299
-			return $pids;
300
-		}
301
-		return 0;
302
-	}
303
-
304
-	/**
305
-	 *
306
-	 *
307
-	 * @param string  $key
308
-	 * @param string  $value
309
-	 * @return int
310
-	 * @deprecated 0.20.0
311
-	 */
312
-	public static function get_post_by_meta( $key, $value ) {
313
-		global $wpdb;
314
-		$query = $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %s ORDER BY post_id", $key, $value );
315
-		$results = $wpdb->get_col( $query );
316
-		foreach ( $results as $result ) {
317
-			if ( $result && get_post( $result ) ) {
318
-				return $result;
319
-			}
320
-		}
321
-		return 0;
322
-	}
323
-
324
-	/**
325
-	 *
326
-	 * @deprecated 0.21.8
327
-	 * @param int     $ttid
328
-	 * @return mixed
329
-	 */
330
-	public static function get_term_id_by_term_taxonomy_id( $ttid ) {
331
-		global $wpdb;
332
-		$query = $wpdb->prepare( "SELECT term_id FROM $wpdb->term_taxonomy WHERE term_taxonomy_id = %s", $ttid );
333
-		return $wpdb->get_var( $query );
334
-	}
335
-
336
-	/* Object Utilities
282
+    /**
283
+     * @param string  $key
284
+     * @param string  $value
285
+     * @return array|int
286
+     * @deprecated 0.20.0
287
+     */
288
+    public static function get_posts_by_meta( $key, $value ) {
289
+        global $wpdb;
290
+        $query = $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %s", $key, $value );
291
+        $results = $wpdb->get_col( $query );
292
+        $pids = array();
293
+        foreach ( $results as $result ) {
294
+            if ( get_post( $result ) ) {
295
+                $pids[] = $result;
296
+            }
297
+        }
298
+        if ( count( $pids ) ) {
299
+            return $pids;
300
+        }
301
+        return 0;
302
+    }
303
+
304
+    /**
305
+     *
306
+     *
307
+     * @param string  $key
308
+     * @param string  $value
309
+     * @return int
310
+     * @deprecated 0.20.0
311
+     */
312
+    public static function get_post_by_meta( $key, $value ) {
313
+        global $wpdb;
314
+        $query = $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %s ORDER BY post_id", $key, $value );
315
+        $results = $wpdb->get_col( $query );
316
+        foreach ( $results as $result ) {
317
+            if ( $result && get_post( $result ) ) {
318
+                return $result;
319
+            }
320
+        }
321
+        return 0;
322
+    }
323
+
324
+    /**
325
+     *
326
+     * @deprecated 0.21.8
327
+     * @param int     $ttid
328
+     * @return mixed
329
+     */
330
+    public static function get_term_id_by_term_taxonomy_id( $ttid ) {
331
+        global $wpdb;
332
+        $query = $wpdb->prepare( "SELECT term_id FROM $wpdb->term_taxonomy WHERE term_taxonomy_id = %s", $ttid );
333
+        return $wpdb->get_var( $query );
334
+    }
335
+
336
+    /* Object Utilities
337 337
 	======================== */
338 338
 
339
-	/**
340
-	 *
341
-	 *
342
-	 * @param array   $array
343
-	 * @param string  $prop
344
-	 * @return void
345
-	 */
346
-	public static function osort( &$array, $prop ) {
347
-		usort( $array, function ( $a, $b ) use ( $prop ) {
348
-				return $a->$prop > $b->$prop ? 1 : -1;
349
-			} );
350
-	}
351
-
352
-	/**
353
-	 *
354
-	 *
355
-	 * @param array   $arr
356
-	 * @return bool
357
-	 */
358
-	public static function is_array_assoc( $arr ) {
359
-		if ( !is_array( $arr ) ) {
360
-			return false;
361
-		}
362
-		return (bool)count( array_filter( array_keys( $arr ), 'is_string' ) );
363
-	}
364
-
365
-	/**
366
-	 *
367
-	 *
368
-	 * @param array   $array
369
-	 * @return stdClass
370
-	 */
371
-	public static function array_to_object( $array ) {
372
-		$obj = new stdClass;
373
-		foreach ( $array as $k => $v ) {
374
-			if ( is_array( $v ) ) {
375
-				$obj->{$k} = self::array_to_object( $v ); //RECURSION
376
-			} else {
377
-				$obj->{$k} = $v;
378
-			}
379
-		}
380
-		return $obj;
381
-	}
382
-
383
-	/**
384
-	 *
385
-	 *
386
-	 * @param array   $array
387
-	 * @param string  $key
388
-	 * @param mixed   $value
389
-	 * @return bool|int
390
-	 */
391
-	public static function get_object_index_by_property( $array, $key, $value ) {
392
-		if ( is_array( $array ) ) {
393
-			$i = 0;
394
-			foreach ( $array as $arr ) {
395
-				if ( is_array( $arr ) ) {
396
-					if ( $arr[$key] == $value ) {
397
-						return $i;
398
-					}
399
-				} else {
400
-					if ( $arr->$key == $value ) {
401
-						return $i;
402
-					}
403
-				}
404
-				$i++;
405
-			}
406
-		}
407
-		return false;
408
-	}
409
-
410
-	/**
411
-	 *
412
-	 *
413
-	 * @param array   $array
414
-	 * @param string  $key
415
-	 * @param mixed   $value
416
-	 * @return array|null
417
-	 * @throws Exception
418
-	 */
419
-	public static function get_object_by_property( $array, $key, $value ) {
420
-		if ( is_array( $array ) ) {
421
-			foreach ( $array as $arr ) {
422
-				if ( $arr->$key == $value ) {
423
-					return $arr;
424
-				}
425
-			}
426
-		} else {
427
-			throw new InvalidArgumentException( '$array is not an array, got:' );
428
-			TimberHelper::error_log( $array );
429
-		}
430
-	}
431
-
432
-	/**
433
-	 *
434
-	 *
435
-	 * @param array   $array
436
-	 * @param int     $len
437
-	 * @return array
438
-	 */
439
-	public static function array_truncate( $array, $len ) {
440
-		if ( sizeof( $array ) > $len ) {
441
-			$array = array_splice( $array, 0, $len );
442
-		}
443
-		return $array;
444
-	}
445
-
446
-	/* Bool Utilities
339
+    /**
340
+     *
341
+     *
342
+     * @param array   $array
343
+     * @param string  $prop
344
+     * @return void
345
+     */
346
+    public static function osort( &$array, $prop ) {
347
+        usort( $array, function ( $a, $b ) use ( $prop ) {
348
+                return $a->$prop > $b->$prop ? 1 : -1;
349
+            } );
350
+    }
351
+
352
+    /**
353
+     *
354
+     *
355
+     * @param array   $arr
356
+     * @return bool
357
+     */
358
+    public static function is_array_assoc( $arr ) {
359
+        if ( !is_array( $arr ) ) {
360
+            return false;
361
+        }
362
+        return (bool)count( array_filter( array_keys( $arr ), 'is_string' ) );
363
+    }
364
+
365
+    /**
366
+     *
367
+     *
368
+     * @param array   $array
369
+     * @return stdClass
370
+     */
371
+    public static function array_to_object( $array ) {
372
+        $obj = new stdClass;
373
+        foreach ( $array as $k => $v ) {
374
+            if ( is_array( $v ) ) {
375
+                $obj->{$k} = self::array_to_object( $v ); //RECURSION
376
+            } else {
377
+                $obj->{$k} = $v;
378
+            }
379
+        }
380
+        return $obj;
381
+    }
382
+
383
+    /**
384
+     *
385
+     *
386
+     * @param array   $array
387
+     * @param string  $key
388
+     * @param mixed   $value
389
+     * @return bool|int
390
+     */
391
+    public static function get_object_index_by_property( $array, $key, $value ) {
392
+        if ( is_array( $array ) ) {
393
+            $i = 0;
394
+            foreach ( $array as $arr ) {
395
+                if ( is_array( $arr ) ) {
396
+                    if ( $arr[$key] == $value ) {
397
+                        return $i;
398
+                    }
399
+                } else {
400
+                    if ( $arr->$key == $value ) {
401
+                        return $i;
402
+                    }
403
+                }
404
+                $i++;
405
+            }
406
+        }
407
+        return false;
408
+    }
409
+
410
+    /**
411
+     *
412
+     *
413
+     * @param array   $array
414
+     * @param string  $key
415
+     * @param mixed   $value
416
+     * @return array|null
417
+     * @throws Exception
418
+     */
419
+    public static function get_object_by_property( $array, $key, $value ) {
420
+        if ( is_array( $array ) ) {
421
+            foreach ( $array as $arr ) {
422
+                if ( $arr->$key == $value ) {
423
+                    return $arr;
424
+                }
425
+            }
426
+        } else {
427
+            throw new InvalidArgumentException( '$array is not an array, got:' );
428
+            TimberHelper::error_log( $array );
429
+        }
430
+    }
431
+
432
+    /**
433
+     *
434
+     *
435
+     * @param array   $array
436
+     * @param int     $len
437
+     * @return array
438
+     */
439
+    public static function array_truncate( $array, $len ) {
440
+        if ( sizeof( $array ) > $len ) {
441
+            $array = array_splice( $array, 0, $len );
442
+        }
443
+        return $array;
444
+    }
445
+
446
+    /* Bool Utilities
447 447
 	======================== */
448 448
 
449
-	/**
450
-	 *
451
-	 *
452
-	 * @param mixed   $value
453
-	 * @return bool
454
-	 */
455
-	public static function is_true( $value ) {
456
-		if ( isset( $value ) ) {
457
-			if (is_string($value)) {
458
-				$value = strtolower($value);
459
-			}
460
-			if ( ($value == 'true' || $value === 1 || $value === '1' || $value == true) && $value !== false && $value !== 'false') {
461
-				return true;
462
-			}
463
-		}
464
-		return false;
465
-	}
466
-
467
-	/**
468
-	 *
469
-	 *
470
-	 * @param int     $i
471
-	 * @return bool
472
-	 */
473
-	public static function iseven( $i ) {
474
-		return ( $i % 2 ) == 0;
475
-	}
476
-
477
-	/**
478
-	 *
479
-	 *
480
-	 * @param int     $i
481
-	 * @return bool
482
-	 */
483
-	public static function isodd( $i ) {
484
-		return ( $i % 2 ) != 0;
485
-	}
486
-
487
-	/* Links, Forms, Etc. Utilities
449
+    /**
450
+     *
451
+     *
452
+     * @param mixed   $value
453
+     * @return bool
454
+     */
455
+    public static function is_true( $value ) {
456
+        if ( isset( $value ) ) {
457
+            if (is_string($value)) {
458
+                $value = strtolower($value);
459
+            }
460
+            if ( ($value == 'true' || $value === 1 || $value === '1' || $value == true) && $value !== false && $value !== 'false') {
461
+                return true;
462
+            }
463
+        }
464
+        return false;
465
+    }
466
+
467
+    /**
468
+     *
469
+     *
470
+     * @param int     $i
471
+     * @return bool
472
+     */
473
+    public static function iseven( $i ) {
474
+        return ( $i % 2 ) == 0;
475
+    }
476
+
477
+    /**
478
+     *
479
+     *
480
+     * @param int     $i
481
+     * @return bool
482
+     */
483
+    public static function isodd( $i ) {
484
+        return ( $i % 2 ) != 0;
485
+    }
486
+
487
+    /* Links, Forms, Etc. Utilities
488 488
 	======================== */
489 489
 
490
-	/**
491
-	 *
492
-	 * Gets the comment form for use on a single article page
493
-	 * @deprecated 0.21.8 use `{{ function('comment_form') }}` instead
494
-	 * @param int     $post_id which post_id should the form be tied to?
495
-	 * @param array   $args this $args thing is a fucking mess, [fix at some point](http://codex.wordpress.org/Function_Reference/comment_form)
496
-	 * @return string
497
-	 */
498
-	public static function get_comment_form( $post_id = null, $args = array() ) {
499
-		return self::ob_function( 'comment_form', array( $args, $post_id ) );
500
-	}
501
-
502
-	/**
503
-	 *
504
-	 *
505
-	 * @param string  $args
506
-	 * @return array
507
-	 */
508
-	public static function paginate_links( $args = '' ) {
509
-		$defaults = array(
510
-			'base' => '%_%', // http://example.com/all_posts.php%_% : %_% is replaced by format (below)
511
-			'format' => '?page=%#%', // ?page=%#% : %#% is replaced by the page number
512
-			'total' => 1,
513
-			'current' => 0,
514
-			'show_all' => false,
515
-			'prev_next' => false,
516
-			'prev_text' => __( '&laquo; Previous' ),
517
-			'next_text' => __( 'Next &raquo;' ),
518
-			'end_size' => 1,
519
-			'mid_size' => 2,
520
-			'type' => 'array',
521
-			'add_args' => false, // array of query args to add
522
-			'add_fragment' => ''
523
-		);
524
-		$args = wp_parse_args( $args, $defaults );
525
-		// Who knows what else people pass in $args
526
-		$args['total'] = intval( (int)$args['total'] );
527
-		if ( $args['total'] < 2 ) {
528
-			return array();
529
-		}
530
-		$args['current'] = (int)$args['current'];
531
-		$args['end_size'] = 0 < (int)$args['end_size'] ? (int)$args['end_size'] : 1; // Out of bounds?  Make it the default.
532
-		$args['mid_size'] = 0 <= (int)$args['mid_size'] ? (int)$args['mid_size'] : 2;
533
-		$args['add_args'] = is_array( $args['add_args'] ) ? $args['add_args'] : false;
534
-		$page_links = array();
535
-		$dots = false;
536
-		for ( $n = 1; $n <= $args['total']; $n++ ) {
537
-			$n_display = number_format_i18n( $n );
538
-			if ( $n == $args['current'] ) {
539
-				$page_links[] = array(
540
-					'class' => 'page-number page-numbers current',
541
-					'title' => $n_display,
542
-					'text' => $n_display,
543
-					'name' => $n_display,
544
-					'current' => true
545
-				);
546
-				$dots = true;
547
-			} else {
548
-				if ( $args['show_all'] || ( $n <= $args['end_size'] || ( $args['current'] && $n >= $args['current'] - $args['mid_size'] && $n <= $args['current'] + $args['mid_size'] ) || $n > $args['total'] - $args['end_size'] ) ) {
549
-					$link = str_replace( '%_%', 1 == $n ? '' : $args['format'], $args['base'] );
550
-					$link = str_replace( '%#%', $n, $link );
551
-					$link = trailingslashit( $link ) . ltrim( $args['add_fragment'], '/' );
552
-					if ( $args['add_args'] ) {
553
-						$link = rtrim( add_query_arg( $args['add_args'], $link ), '/' );
554
-					}
555
-					$link = str_replace(' ', '+', $link);
556
-					$link = untrailingslashit( $link );
557
-					$page_links[] = array(
558
-						'class' => 'page-number page-numbers',
559
-						'link' => esc_url( apply_filters( 'paginate_links', $link ) ),
560
-						'title' => $n_display,
561
-						'name' => $n_display,
562
-						'current' => $args['current'] == $n
563
-					);
564
-					$dots = true;
565
-				} elseif ( $dots && !$args['show_all'] ) {
566
-					$page_links[] = array(
567
-						'class' => 'dots',
568
-						'title' => __( '&hellip;' )
569
-					);
570
-					$dots = false;
571
-				}
572
-			}
573
-		}
574
-		return $page_links;
575
-	}
576
-
577
-	/**
578
-	 * @deprecated 0.18.0
579
-	 */
580
-	static function get_current_url() {
581
-		return TimberURLHelper::get_current_url();
582
-	}
583
-
584
-	/**
585
-	 * @deprecated 0.18.0
586
-	 */
587
-	static function is_url( $url ) {
588
-		return TimberURLHelper::is_url( $url );
589
-	}
590
-
591
-	/**
592
-	 * @deprecated 0.18.0
593
-	 */
594
-	static function get_path_base() {
595
-		return TimberURLHelper::get_path_base();
596
-	}
597
-
598
-	/**
599
-	 * @deprecated 0.18.0
600
-	 */
601
-	static function get_rel_url( $url, $force = false ) {
602
-		return TimberURLHelper::get_rel_url( $url, $force );
603
-	}
604
-
605
-	/**
606
-	 * @deprecated 0.18.0
607
-	 */
608
-	static function is_local( $url ) {
609
-		return TimberURLHelper::is_local( $url );
610
-	}
611
-
612
-	/**
613
-	 * @deprecated 0.18.0
614
-	 */
615
-	static function get_full_path( $src ) {
616
-		return TimberURLHelper::get_full_path( $src );
617
-	}
618
-
619
-	/**
620
-	 * @deprecated 0.18.0
621
-	 */
622
-	static function get_rel_path( $src ) {
623
-		return TimberURLHelper::get_rel_path( $src );
624
-	}
625
-
626
-	/**
627
-	 * @deprecated 0.18.0
628
-	 */
629
-	static function remove_double_slashes( $url ) {
630
-		return TimberURLHelper::remove_double_slashes( $url );
631
-	}
632
-
633
-	/**
634
-	 * @deprecated 0.18.0
635
-	 */
636
-	static function prepend_to_url( $url, $path ) {
637
-		return TimberURLHelper::prepend_to_url( $url, $path );
638
-	}
639
-
640
-	/**
641
-	 * @deprecated 0.18.0
642
-	 */
643
-	static function preslashit( $path ) {
644
-		return TimberURLHelper::preslashit( $path );
645
-	}
646
-
647
-	/**
648
-	 * @deprecated 0.18.0
649
-	 */
650
-	static function is_external( $url ) {
651
-		return TimberURLHelper::is_external( $url );
652
-	}
653
-
654
-	/**
655
-	 * @deprecated 0.18.0
656
-	 */
657
-	static function download_url( $url, $timeout = 300 ) {
658
-		return TimberURLHelper::download_url( $url, $timeout );
659
-	}
660
-
661
-	/**
662
-	 * @deprecated 0.18.0
663
-	 */
664
-	static function get_params( $i = -1 ) {
665
-		return TimberURLHelper::get_params( $i );
666
-	}
490
+    /**
491
+     *
492
+     * Gets the comment form for use on a single article page
493
+     * @deprecated 0.21.8 use `{{ function('comment_form') }}` instead
494
+     * @param int     $post_id which post_id should the form be tied to?
495
+     * @param array   $args this $args thing is a fucking mess, [fix at some point](http://codex.wordpress.org/Function_Reference/comment_form)
496
+     * @return string
497
+     */
498
+    public static function get_comment_form( $post_id = null, $args = array() ) {
499
+        return self::ob_function( 'comment_form', array( $args, $post_id ) );
500
+    }
501
+
502
+    /**
503
+     *
504
+     *
505
+     * @param string  $args
506
+     * @return array
507
+     */
508
+    public static function paginate_links( $args = '' ) {
509
+        $defaults = array(
510
+            'base' => '%_%', // http://example.com/all_posts.php%_% : %_% is replaced by format (below)
511
+            'format' => '?page=%#%', // ?page=%#% : %#% is replaced by the page number
512
+            'total' => 1,
513
+            'current' => 0,
514
+            'show_all' => false,
515
+            'prev_next' => false,
516
+            'prev_text' => __( '&laquo; Previous' ),
517
+            'next_text' => __( 'Next &raquo;' ),
518
+            'end_size' => 1,
519
+            'mid_size' => 2,
520
+            'type' => 'array',
521
+            'add_args' => false, // array of query args to add
522
+            'add_fragment' => ''
523
+        );
524
+        $args = wp_parse_args( $args, $defaults );
525
+        // Who knows what else people pass in $args
526
+        $args['total'] = intval( (int)$args['total'] );
527
+        if ( $args['total'] < 2 ) {
528
+            return array();
529
+        }
530
+        $args['current'] = (int)$args['current'];
531
+        $args['end_size'] = 0 < (int)$args['end_size'] ? (int)$args['end_size'] : 1; // Out of bounds?  Make it the default.
532
+        $args['mid_size'] = 0 <= (int)$args['mid_size'] ? (int)$args['mid_size'] : 2;
533
+        $args['add_args'] = is_array( $args['add_args'] ) ? $args['add_args'] : false;
534
+        $page_links = array();
535
+        $dots = false;
536
+        for ( $n = 1; $n <= $args['total']; $n++ ) {
537
+            $n_display = number_format_i18n( $n );
538
+            if ( $n == $args['current'] ) {
539
+                $page_links[] = array(
540
+                    'class' => 'page-number page-numbers current',
541
+                    'title' => $n_display,
542
+                    'text' => $n_display,
543
+                    'name' => $n_display,
544
+                    'current' => true
545
+                );
546
+                $dots = true;
547
+            } else {
548
+                if ( $args['show_all'] || ( $n <= $args['end_size'] || ( $args['current'] && $n >= $args['current'] - $args['mid_size'] && $n <= $args['current'] + $args['mid_size'] ) || $n > $args['total'] - $args['end_size'] ) ) {
549
+                    $link = str_replace( '%_%', 1 == $n ? '' : $args['format'], $args['base'] );
550
+                    $link = str_replace( '%#%', $n, $link );
551
+                    $link = trailingslashit( $link ) . ltrim( $args['add_fragment'], '/' );
552
+                    if ( $args['add_args'] ) {
553
+                        $link = rtrim( add_query_arg( $args['add_args'], $link ), '/' );
554
+                    }
555
+                    $link = str_replace(' ', '+', $link);
556
+                    $link = untrailingslashit( $link );
557
+                    $page_links[] = array(
558
+                        'class' => 'page-number page-numbers',
559
+                        'link' => esc_url( apply_filters( 'paginate_links', $link ) ),
560
+                        'title' => $n_display,
561
+                        'name' => $n_display,
562
+                        'current' => $args['current'] == $n
563
+                    );
564
+                    $dots = true;
565
+                } elseif ( $dots && !$args['show_all'] ) {
566
+                    $page_links[] = array(
567
+                        'class' => 'dots',
568
+                        'title' => __( '&hellip;' )
569
+                    );
570
+                    $dots = false;
571
+                }
572
+            }
573
+        }
574
+        return $page_links;
575
+    }
576
+
577
+    /**
578
+     * @deprecated 0.18.0
579
+     */
580
+    static function get_current_url() {
581
+        return TimberURLHelper::get_current_url();
582
+    }
583
+
584
+    /**
585
+     * @deprecated 0.18.0
586
+     */
587
+    static function is_url( $url ) {
588
+        return TimberURLHelper::is_url( $url );
589
+    }
590
+
591
+    /**
592
+     * @deprecated 0.18.0
593
+     */
594
+    static function get_path_base() {
595
+        return TimberURLHelper::get_path_base();
596
+    }
597
+
598
+    /**
599
+     * @deprecated 0.18.0
600
+     */
601
+    static function get_rel_url( $url, $force = false ) {
602
+        return TimberURLHelper::get_rel_url( $url, $force );
603
+    }
604
+
605
+    /**
606
+     * @deprecated 0.18.0
607
+     */
608
+    static function is_local( $url ) {
609
+        return TimberURLHelper::is_local( $url );
610
+    }
611
+
612
+    /**
613
+     * @deprecated 0.18.0
614
+     */
615
+    static function get_full_path( $src ) {
616
+        return TimberURLHelper::get_full_path( $src );
617
+    }
618
+
619
+    /**
620
+     * @deprecated 0.18.0
621
+     */
622
+    static function get_rel_path( $src ) {
623
+        return TimberURLHelper::get_rel_path( $src );
624
+    }
625
+
626
+    /**
627
+     * @deprecated 0.18.0
628
+     */
629
+    static function remove_double_slashes( $url ) {
630
+        return TimberURLHelper::remove_double_slashes( $url );
631
+    }
632
+
633
+    /**
634
+     * @deprecated 0.18.0
635
+     */
636
+    static function prepend_to_url( $url, $path ) {
637
+        return TimberURLHelper::prepend_to_url( $url, $path );
638
+    }
639
+
640
+    /**
641
+     * @deprecated 0.18.0
642
+     */
643
+    static function preslashit( $path ) {
644
+        return TimberURLHelper::preslashit( $path );
645
+    }
646
+
647
+    /**
648
+     * @deprecated 0.18.0
649
+     */
650
+    static function is_external( $url ) {
651
+        return TimberURLHelper::is_external( $url );
652
+    }
653
+
654
+    /**
655
+     * @deprecated 0.18.0
656
+     */
657
+    static function download_url( $url, $timeout = 300 ) {
658
+        return TimberURLHelper::download_url( $url, $timeout );
659
+    }
660
+
661
+    /**
662
+     * @deprecated 0.18.0
663
+     */
664
+    static function get_params( $i = -1 ) {
665
+        return TimberURLHelper::get_params( $i );
666
+    }
667 667
 
668 668
 }
Please login to merge, or discard this patch.
lib/timber-post-getter.php 1 patch
Indentation   +87 added lines, -87 removed lines patch added patch discarded remove patch
@@ -2,103 +2,103 @@
 block discarded – undo
2 2
 
3 3
 class TimberPostGetter {
4 4
 
5
-	/**
6
-	 * @param mixed $query
7
-	 * @param string $PostClass
8
-	 * @return array|bool|null
9
-	 */
10
-	static function get_post($query = false, $PostClass = 'TimberPost') {
11
-		$posts = self::get_posts( $query, $PostClass );
12
-		if ( $post = reset($posts ) ) {
13
-			return $post;
14
-		}
15
-	}
5
+    /**
6
+     * @param mixed $query
7
+     * @param string $PostClass
8
+     * @return array|bool|null
9
+     */
10
+    static function get_post($query = false, $PostClass = 'TimberPost') {
11
+        $posts = self::get_posts( $query, $PostClass );
12
+        if ( $post = reset($posts ) ) {
13
+            return $post;
14
+        }
15
+    }
16 16
 
17
-	static function get_posts( $query = false, $PostClass = 'TimberPost', $return_collection = false ) {
18
-		$posts = self::query_posts( $query, $PostClass );
19
-		return apply_filters('timber_post_getter_get_posts', $posts->get_posts( $return_collection ));
20
-	}
17
+    static function get_posts( $query = false, $PostClass = 'TimberPost', $return_collection = false ) {
18
+        $posts = self::query_posts( $query, $PostClass );
19
+        return apply_filters('timber_post_getter_get_posts', $posts->get_posts( $return_collection ));
20
+    }
21 21
 
22
-	static function query_post( $query = false, $PostClass = 'TimberPost' ) {
23
-		$posts = self::query_posts( $query, $PostClass );
24
-		if ( method_exists($posts, 'current') && $post = $posts->current() ) {
25
-			return $post;
26
-		}
27
-	}
22
+    static function query_post( $query = false, $PostClass = 'TimberPost' ) {
23
+        $posts = self::query_posts( $query, $PostClass );
24
+        if ( method_exists($posts, 'current') && $post = $posts->current() ) {
25
+            return $post;
26
+        }
27
+    }
28 28
 
29
-	/**
30
-	 * @param mixed $query
31
-	 * @param string $PostClass
32
-	 * @return array|bool|null
33
-	 */
34
-	static function query_posts($query = false, $PostClass = 'TimberPost' ) {
35
-		if (self::is_post_class_or_class_map($query)) {
36
-			$PostClass = $query;
37
-			$query = false;
38
-		}
29
+    /**
30
+     * @param mixed $query
31
+     * @param string $PostClass
32
+     * @return array|bool|null
33
+     */
34
+    static function query_posts($query = false, $PostClass = 'TimberPost' ) {
35
+        if (self::is_post_class_or_class_map($query)) {
36
+            $PostClass = $query;
37
+            $query = false;
38
+        }
39 39
 
40
-		if (is_object($query) && !is_a($query, 'WP_Query') ){
41
-			// The only object other than a query is a type of post object
42
-			$query = array( $query );
43
-		}
40
+        if (is_object($query) && !is_a($query, 'WP_Query') ){
41
+            // The only object other than a query is a type of post object
42
+            $query = array( $query );
43
+        }
44 44
 
45
-		if ( is_array( $query ) && count( $query ) && isset( $query[0] ) && is_object( $query[0] ) ) {
46
-			// We have an array of post objects that already have data
47
-			return new TimberPostsCollection( $query, $PostClass );
48
-		} else {
49
-			// We have a query (of sorts) to work with
50
-			$tqi = new TimberQueryIterator( $query, $PostClass );
51
-			return $tqi;
52
-		}
53
-	}
45
+        if ( is_array( $query ) && count( $query ) && isset( $query[0] ) && is_object( $query[0] ) ) {
46
+            // We have an array of post objects that already have data
47
+            return new TimberPostsCollection( $query, $PostClass );
48
+        } else {
49
+            // We have a query (of sorts) to work with
50
+            $tqi = new TimberQueryIterator( $query, $PostClass );
51
+            return $tqi;
52
+        }
53
+    }
54 54
 
55
-	static function get_pids($query){
56
-		$posts = self::get_posts($query);
57
-		$pids = array();
58
-		foreach($posts as $post){
59
-			if (isset($post->ID)){
60
-				$pids[] = $post->ID;
61
-			}
62
-		}
63
-		return $pids;
64
-	}
55
+    static function get_pids($query){
56
+        $posts = self::get_posts($query);
57
+        $pids = array();
58
+        foreach($posts as $post){
59
+            if (isset($post->ID)){
60
+                $pids[] = $post->ID;
61
+            }
62
+        }
63
+        return $pids;
64
+    }
65 65
 
66
-	static function loop_to_id() {
67
-		if (!self::wp_query_has_posts()) { return false; }
66
+    static function loop_to_id() {
67
+        if (!self::wp_query_has_posts()) { return false; }
68 68
 
69
-		global $wp_query;
70
-		$post_num = property_exists($wp_query, 'current_post')
71
-				  ? $wp_query->current_post + 1
72
-				  : 0
73
-				  ;
69
+        global $wp_query;
70
+        $post_num = property_exists($wp_query, 'current_post')
71
+                  ? $wp_query->current_post + 1
72
+                  : 0
73
+                    ;
74 74
 
75
-		if (!isset($wp_query->posts[$post_num])) { return false; }
75
+        if (!isset($wp_query->posts[$post_num])) { return false; }
76 76
 
77
-		return $wp_query->posts[$post_num]->ID;
78
-	}
77
+        return $wp_query->posts[$post_num]->ID;
78
+    }
79 79
 
80
-	/**
81
-	 * @return bool
82
-	 */
83
-	static function wp_query_has_posts() {
84
-		global $wp_query;
85
-		return ($wp_query && property_exists($wp_query, 'posts') && $wp_query->posts);
86
-	}
80
+    /**
81
+     * @return bool
82
+     */
83
+    static function wp_query_has_posts() {
84
+        global $wp_query;
85
+        return ($wp_query && property_exists($wp_query, 'posts') && $wp_query->posts);
86
+    }
87 87
 
88
-	/**
89
-	 * @param string|array $arg
90
-	 * @return bool
91
-	 */
92
-	static function is_post_class_or_class_map($arg){
93
-		if (is_string($arg) && class_exists($arg)) {
94
-			return true;
95
-		}
96
-		if (is_array($arg)) {
97
-			foreach ($arg as $item) {
98
-				if (is_string($item) && (class_exists($item) && is_subclass_of($item, 'TimberPost'))) {
99
-					return true;
100
-				}
101
-			}
102
-		}
103
-	}
88
+    /**
89
+     * @param string|array $arg
90
+     * @return bool
91
+     */
92
+    static function is_post_class_or_class_map($arg){
93
+        if (is_string($arg) && class_exists($arg)) {
94
+            return true;
95
+        }
96
+        if (is_array($arg)) {
97
+            foreach ($arg as $item) {
98
+                if (is_string($item) && (class_exists($item) && is_subclass_of($item, 'TimberPost'))) {
99
+                    return true;
100
+                }
101
+            }
102
+        }
103
+    }
104 104
 }
Please login to merge, or discard this patch.
lib/timber-post.php 1 patch
Indentation   +1404 added lines, -1404 removed lines patch added patch discarded remove patch
@@ -34,1409 +34,1409 @@
 block discarded – undo
34 34
  */
35 35
 class TimberPost extends TimberCore implements TimberCoreInterface {
36 36
 
37
-	/**
38
-	 * @var string $ImageClass the name of the class to handle images by default
39
-	 */
40
-	public $ImageClass = 'TimberImage';
41
-
42
-	/**
43
-	 * @var string $PostClass the name of the class to handle posts by default
44
-	 */
45
-	public $PostClass = 'TimberPost';
46
-
47
-	/**
48
-	 * @var string $TermClass the name of the class to handle terms by default
49
-	 */
50
-	public $TermClass = 'TimberTerm';
51
-
52
-	/**
53
-	 * @var string $object_type what does this class represent in WordPress terms?
54
-	 */
55
-	public $object_type = 'post';
56
-
57
-	/**
58
-	 * @var string $representation what does this class represent in WordPress terms?
59
-	 */
60
-	public static $representation = 'post';
61
-
62
-	/**
63
-	 * @internal
64
-	 * @var string $_content stores the processed content internally
65
-	 */
66
-	protected $_content;
67
-
68
-	/**
69
-	 * @internal
70
-	 * @var array $_get_terms stores the results of a get_terms method call
71
-	 * @deprecated
72
-	 */
73
-	protected $_get_terms;
74
-
75
-	/**
76
-	 * @var string $_permalink the returned permalink from WP's get_permalink function
77
-	 */
78
-	protected $_permalink;
79
-
80
-	/**
81
-	 * @var array $_next stores the results of the next TimberPost in a set inside an array (in order to manage by-taxonomy)
82
-	 */
83
-	protected $_next = array();
84
-
85
-	/**
86
-	 * @var array $_prev stores the results of the previous TimberPost in a set inside an array (in order to manage by-taxonomy)
87
-	 */
88
-	protected $_prev = array();
89
-
90
-	/**
91
-	 * @api
92
-	 * @var string $class stores the CSS classes for the post (ex: "post post-type-book post-123")
93
-	 */
94
-	public $class;
95
-
96
-	/**
97
-	 * @api
98
-	 * @var string $id the numeric WordPress id of a post
99
-	 */
100
-	public $id;
101
-
102
-	/**
103
-	 * @var string 	$ID 			the numeric WordPress id of a post, capitalized to match WP usage
104
-	 */
105
-	public $ID;
106
-
107
-	/**
108
-	 * @var int 	$post_author 	the numeric ID of the a post's author corresponding to the wp_user dtable
109
-	 */
110
-	public $post_author;
111
-
112
-	/**
113
-	 * @var string 	$post_content 	the raw text of a WP post as stored in the database
114
-	 */
115
-	public $post_content;
116
-
117
-	/**
118
-	 * @var string 	$post_date 		the raw date string as stored in the WP database, ex: 2014-07-05 18:01:39
119
-	 */
120
-	public $post_date;
121
-
122
-	/**
123
-	 * @var string 	$post_exceprt 	the raw text of a manual post exceprt as stored in the database
124
-	 */
125
-	public $post_excerpt;
126
-
127
-	/**
128
-	 * @var int 		$post_parent 	the numeric ID of a post's parent post
129
-	 */
130
-	public $post_parent;
131
-
132
-	/**
133
-	 * @api
134
-	 * @var string 		$post_status 	the status of a post ("draft", "publish", etc.)
135
-	 */
136
-	public $post_status;
137
-
138
-	/**
139
-	 * @var string 	$post_title 	the raw text of a post's title as stored in the database
140
-	 */
141
-	public $post_title;
142
-
143
-	/**
144
-	 * @api
145
-	 * @var string 	$post_type 		the name of the post type, this is the machine name (so "my_custom_post_type" as opposed to "My Custom Post Type")
146
-	 */
147
-	public $post_type;
148
-
149
-	/**
150
-	 * @api
151
-	 * @var string 	$slug 		the URL-safe slug, this corresponds to the poorly-named "post_name" in the WP database, ex: "hello-world"
152
-	 */
153
-	public $slug;
154
-
155
-	/**
156
-	 * If you send the constructor nothing it will try to figure out the current post id based on being inside The_Loop
157
-	 * @example
158
-	 * ```php
159
-	 * $post = new TimberPost();
160
-	 * $other_post = new TimberPost($random_post_id);
161
-	 * ```
162
-	 * @param mixed $pid
163
-	 */
164
-	public function __construct($pid = null) {
165
-		$pid = $this->determine_id( $pid );
166
-		$this->init($pid);
167
-	}
168
-
169
-	/**
170
-	 * tries to figure out what post you want to get if not explictly defined (or if it is, allows it to be passed through)
171
-	 * @internal
172
-	 * @param mixed a value to test against
173
-	 * @return int the numberic id we should be using for this post object
174
-	 */
175
-	protected function determine_id($pid) {
176
-		global $wp_query;
177
-		if ( $pid === null &&
178
-			isset($wp_query->queried_object_id)
179
-			&& $wp_query->queried_object_id
180
-			&& isset($wp_query->queried_object)
181
-			&& is_object($wp_query->queried_object)
182
-			&& get_class($wp_query->queried_object) == 'WP_Post'
183
-			) {
184
-				if( isset( $_GET['preview'] ) && isset( $_GET['preview_nonce'] ) && wp_verify_nonce( $_GET['preview_nonce'], 'post_preview_' . $wp_query->queried_object_id ) ) {
185
-					$pid = $this->get_post_preview_id( $wp_query );
186
-				} else if ( !$pid ) {
187
-					$pid = $wp_query->queried_object_id;
188
-				}
189
-		} else if ( $pid === null && $wp_query->is_home && isset($wp_query->queried_object_id) && $wp_query->queried_object_id )  {
190
-			//hack for static page as home page
191
-			$pid = $wp_query->queried_object_id;
192
-		} else if ( $pid === null ) {
193
-			$gtid = false;
194
-			$maybe_post = get_post();
195
-			if ( isset($maybe_post->ID) ){
196
-				$gtid = true;
197
-			}
198
-			if ( $gtid ) {
199
-				$pid = get_the_ID();
200
-			}
201
-			if ( !$pid ) {
202
-				global $wp_query;
203
-				if ( isset($wp_query->query['p']) ) {
204
-					$pid = $wp_query->query['p'];
205
-				}
206
-			}
207
-		}
208
-		if ( $pid === null && ($pid_from_loop = TimberPostGetter::loop_to_id()) ) {
209
-			$pid = $pid_from_loop;
210
-		}
211
-		return $pid;
212
-	}
213
-
214
-	/**
215
-	 * Outputs the title of the post if you do something like `<h1>{{post}}</h1>`
216
-	 * @return string
217
-	 */
218
-	public function __toString() {
219
-		return $this->title();
220
-	}
221
-
222
-	protected function get_post_preview_id( $query ) {
223
-		$can = array(
224
-	 		'edit_' . $query->queried_object->post_type . 's',
225
-	 	);
226
-
227
-	 	if ( $query->queried_object->author_id !== get_current_user_id() ) {
228
-	 		$can[] = 'edit_others_' . $query->queried_object->post_type . 's';
229
-	 	}
230
-
231
-	 	$can_preview = array();
232
-
233
-		foreach( $can as $type ) {
234
-		     if( current_user_can( $type ) ) {
235
-		        $can_preview[] = true;
236
-		     }
237
-		}
238
-
239
-		if ( count( $can_preview ) !== count( $can ) ) {
240
-		     return;
241
-		}
242
-
243
-		$revisions = wp_get_post_revisions( $query->queried_object_id );
244
-
245
-		if( !empty( $revisions ) ) {
246
-			$last = end($revisions);
247
-			return $last->ID;
248
-		}
249
-
250
-		return false;
251
-	}
252
-
253
-	/**
254
-	 * Initializes a TimberPost
255
-	 * @internal
256
-	 * @param int|bool $pid
257
-	 */
258
-	protected function init($pid = false) {
259
-		if ( $pid === false ) {
260
-			$pid = get_the_ID();
261
-		}
262
-		if ( is_numeric($pid) ) {
263
-			$this->ID = $pid;
264
-		}
265
-		$post_info = $this->get_info($pid);
266
-		$this->import($post_info);
267
-		//cant have a function, so gots to do it this way
268
-		$post_class = $this->post_class();
269
-		$this->class = $post_class;
270
-	}
271
-
272
-	/**
273
-	 * Get the URL that will edit the current post/object
274
-	 * @internal
275
-	 * @see TimberPost::edit_link
276
-	 * @return bool|string
277
-	 */
278
-	function get_edit_url() {
279
-		if ( $this->can_edit() ) {
280
-			return get_edit_post_link($this->ID);
281
-		}
282
-	}
283
-
284
-	/**
285
-	 * updates the post_meta of the current object with the given value
286
-	 * @param string $field
287
-	 * @param mixed $value
288
-	 */
289
-	public function update( $field, $value ) {
290
-		if ( isset($this->ID) ) {
291
-			update_post_meta($this->ID, $field, $value);
292
-			$this->$field = $value;
293
-		}
294
-	}
295
-
296
-
297
-	/**
298
-	 * takes a mix of integer (post ID), string (post slug),
299
-	 * or object to return a WordPress post object from WP's built-in get_post() function
300
-	 * @internal
301
-	 * @param mixed $pid
302
-	 * @return WP_Post on success
303
-	 */
304
-	protected function prepare_post_info( $pid = 0 ) {
305
-		if ( is_string($pid) || is_numeric($pid) || (is_object($pid) && !isset($pid->post_title)) || $pid === 0 ) {
306
-			$pid = self::check_post_id($pid);
307
-			$post = get_post($pid);
308
-			if ( $post ) {
309
-				return $post;
310
-			}
311
-		}
312
-		//we can skip if already is WP_Post
313
-		return $pid;
314
-	}
315
-
316
-
317
-	/**
318
-	 * helps you find the post id regardless of whether you send a string or whatever
319
-	 * @param integer $pid ;
320
-	 * @internal
321
-	 * @return integer ID number of a post
322
-	 */
323
-	protected function check_post_id( $pid ) {
324
-		if ( is_numeric($pid) && $pid === 0 ) {
325
-			$pid = get_the_ID();
326
-			return $pid;
327
-		}
328
-		if ( !is_numeric($pid) && is_string($pid) ) {
329
-			$pid = self::get_post_id_by_name($pid);
330
-			return $pid;
331
-		}
332
-		if ( !$pid ) {
333
-			return null;
334
-		}
335
-		return $pid;
336
-	}
337
-
338
-
339
-	/**
340
-	 * get_post_id_by_name($post_name)
341
-	 * @internal
342
-	 * @param string $post_name
343
-	 * @return int
344
-	 */
345
-	static function get_post_id_by_name($post_name) {
346
-		global $wpdb;
347
-		$query = $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_name = %s LIMIT 1", $post_name);
348
-		$result = $wpdb->get_row($query);
349
-		if (!$result) {
350
-			return null;
351
-		}
352
-		return $result->ID;
353
-	}
354
-
355
-	/**
356
-	 * get a preview of your post, if you have an excerpt it will use that,
357
-	 * otherwise it will pull from the post_content.
358
-	 * If there's a <!-- more --> tag it will use that to mark where to pull through.
359
-	 * @api
360
-	 * @example
361
-	 * ```twig
362
-	 * <p>{{post.get_preview(50)}}</p>
363
-	 * ```
364
-	 * @param int $len The number of words that WP should use to make the tease. (Isn't this better than [this mess](http://wordpress.org/support/topic/changing-the-default-length-of-the_excerpt-1?replies=14)?). If you've set a post_excerpt on a post, we'll use that for the preview text; otherwise the first X words of the post_content
365
-	 * @param bool $force What happens if your custom post excerpt is longer then the length requested? By default (`$force = false`) it will use the full `post_excerpt`. However, you can set this to true to *force* your excerpt to be of the desired length
366
-	 * @param string $readmore The text you want to use on the 'readmore' link
367
-	 * @param bool|string $strip true for default, false for none, string for list of custom attributes
368
-	 * @param string $end The text to end the preview with (defaults to ...)
369
-	 * @return string of the post preview
370
-	 */
371
-	function get_preview($len = 50, $force = false, $readmore = 'Read More', $strip = true, $end = '&hellip;') {
372
-		$text = '';
373
-		$trimmed = false;
374
-		if ( isset($this->post_excerpt) && strlen($this->post_excerpt) ) {
375
-			if ( $force ) {
376
-				$text = TimberHelper::trim_words($this->post_excerpt, $len, false);
377
-				$trimmed = true;
378
-			} else {
379
-				$text = $this->post_excerpt;
380
-			}
381
-		}
382
-		if ( !strlen($text) && preg_match('/<!--\s?more(.*?)?-->/', $this->post_content, $readmore_matches) ) {
383
-			$pieces = explode($readmore_matches[0], $this->post_content);
384
-			$text = $pieces[0];
385
-			if ( $force ) {
386
-				$text = TimberHelper::trim_words($text, $len, false);
387
-				$trimmed = true;
388
-			}
389
-			$text = do_shortcode( $text );
390
-		}
391
-		if ( !strlen($text) ) {
392
-			$text = TimberHelper::trim_words($this->get_content(), $len, false);
393
-			$trimmed = true;
394
-		}
395
-		if ( !strlen(trim($text)) ) {
396
-			return trim($text);
397
-		}
398
-		if ( $strip ) {
399
-			$allowable_tags = (is_string($strip)) ? $strip : null;
400
-			$text = trim(strip_tags($text, $allowable_tags));
401
-		}
402
-		if ( strlen($text) ) {
403
-			$text = trim($text);
404
-			$last = $text[strlen($text) - 1];
405
-			if ( $last != '.' && $trimmed ) {
406
-				$text .= $end;
407
-			}
408
-			if ( !$strip ) {
409
-				$last_p_tag = strrpos($text, '</p>');
410
-				if ( $last_p_tag !== false ) {
411
-					$text = substr($text, 0, $last_p_tag);
412
-				}
413
-				if ( $last != '.' && $trimmed ) {
414
-					$text .= $end . ' ';
415
-				}
416
-			}
417
-			$read_more_class = apply_filters('timber/post/get_preview/read_more_class', "read-more");
418
-			if ( $readmore && isset($readmore_matches) && !empty($readmore_matches[1]) ) {
419
-				$text .= ' <a href="' . $this->get_permalink() . '" class="'.$read_more_class .'">' . trim($readmore_matches[1]) . '</a>';
420
-			} elseif ( $readmore ) {
421
-				$text .= ' <a href="' . $this->get_permalink() . '" class="'.$read_more_class .'">' . trim($readmore) . '</a>';
422
-			}
423
-			if ( !$strip && $last_p_tag && ( strpos($text, '<p>') || strpos($text, '<p ') ) ) {
424
-				$text .= '</p>';
425
-			}
426
-		}
427
-		return trim($text);
428
-	}
429
-
430
-	/**
431
-	 * gets the post custom and attaches it to the current object
432
-	 * @internal
433
-	 * @param bool|int $pid a post ID number
434
-	 */
435
-	function import_custom( $pid = false ) {
436
-		if ( !$pid ) {
437
-			$pid = $this->ID;
438
-		}
439
-		$customs = $this->get_post_custom($pid);
440
-		$this->import($customs);
441
-	}
442
-
443
-	/**
444
-	 * Used internally to fetch the metadata fields (wp_postmeta table)
445
-	 * and attach them to our TimberPost object
446
-	 * @internal
447
-	 * @param int $pid
448
-	 * @return array
449
-	 */
450
-	protected function get_post_custom( $pid ) {
451
-		apply_filters('timber_post_get_meta_pre', array(), $pid, $this);
452
-		$customs = get_post_custom($pid);
453
-		if ( !is_array($customs) || empty($customs) ) {
454
-			return array();
455
-		}
456
-		foreach ( $customs as $key => $value ) {
457
-			if ( is_array($value) && count($value) == 1 && isset($value[0]) ) {
458
-				$value = $value[0];
459
-			}
460
-			$customs[$key] = maybe_unserialize($value);
461
-		}
462
-		$customs = apply_filters('timber_post_get_meta', $customs, $pid, $this);
463
-		return $customs;
464
-	}
465
-
466
-	/**
467
-	 * @internal
468
-	 * @see TimberPost::thumbnail
469
-	 * @return null|TimberImage
470
-	 */
471
-	function get_thumbnail() {
472
-		if ( function_exists('get_post_thumbnail_id') ) {
473
-			$tid = get_post_thumbnail_id($this->ID);
474
-			if ( $tid ) {
475
-				return new $this->ImageClass($tid);
476
-			}
477
-		}
478
-	}
479
-
480
-	/**
481
-	 * @internal
482
-	 * @see TimberPost::link
483
-	 * @return string
484
-	 */
485
-	function get_permalink() {
486
-		if ( isset($this->_permalink) ) {
487
-			return $this->_permalink;
488
-		}
489
-		$this->_permalink = get_permalink($this->ID);
490
-		return $this->_permalink;
491
-	}
492
-
493
-	/**
494
-	 * get the permalink for a post object
495
-	 * In your templates you should use link:
496
-	 * <a href="{{post.link}}">Read my post</a>
497
-	 * @internal
498
-	 * @return string
499
-	 */
500
-	function get_link() {
501
-		return $this->get_permalink();
502
-	}
503
-
504
-	/**
505
-	 * Get the next post in WordPress's ordering
506
-	 * @internal
507
-	 * @param bool $taxonomy
508
-	 * @return TimberPost|boolean
509
-	 */
510
-	function get_next( $taxonomy = false ) {
511
-		if ( !isset($this->_next) || !isset($this->_next[$taxonomy]) ) {
512
-			global $post;
513
-			$this->_next = array();
514
-			$old_global = $post;
515
-			$post = $this;
516
-			if ( $taxonomy ) {
517
-				$adjacent = get_adjacent_post(true, '', false, $taxonomy);
518
-			} else {
519
-				$adjacent = get_adjacent_post(false, '', false);
520
-			}
521
-
522
-			if ( $adjacent ) {
523
-				$this->_next[$taxonomy] = new $this->PostClass($adjacent);
524
-			} else {
525
-				$this->_next[$taxonomy] = false;
526
-			}
527
-			$post = $old_global;
528
-		}
529
-		return $this->_next[$taxonomy];
530
-	}
531
-
532
-	/**
533
-	 * Get a data array of pagination so you can navigate to the previous/next for a paginated post
534
-	 * @return array
535
-	 */
536
-	public function get_pagination() {
537
-		global $post, $page, $numpages, $multipage;
538
-		$post = $this;
539
-		$ret = array();
540
-		if ( $multipage ) {
541
-			for ( $i = 1; $i <= $numpages; $i++ ) {
542
-				$link = self::get_wp_link_page($i);
543
-				$data = array('name' => $i, 'title' => $i, 'text' => $i, 'link' => $link);
544
-				if ( $i == $page ) {
545
-					$data['current'] = true;
546
-				}
547
-				$ret['pages'][] = $data;
548
-			}
549
-			$i = $page - 1;
550
-			if ( $i ) {
551
-				$link = self::get_wp_link_page($i);
552
-				$ret['prev'] = array('link' => $link);
553
-			}
554
-			$i = $page + 1;
555
-			if ( $i <= $numpages ) {
556
-				$link = self::get_wp_link_page($i);
557
-				$ret['next'] = array('link' => $link);
558
-			}
559
-		}
560
-		return $ret;
561
-	}
562
-
563
-	/**
564
-	 * @param int $i
565
-	 * @return string
566
-	 */
567
-	protected static function get_wp_link_page($i) {
568
-		$link = _wp_link_page($i);
569
-		$link = new SimpleXMLElement($link . '</a>');
570
-		if ( isset($link['href']) ) {
571
-			return $link['href'];
572
-		}
573
-		return '';
574
-	}
575
-
576
-	/**
577
-	 * Get the permalink for a post, but as a relative path
578
-	 * For example, where {{post.link}} would return "http://example.org/2015/07/04/my-cool-post"
579
-	 * this will return the relative version: "/2015/07/04/my-cool-post"
580
-	 * @internal
581
-	 * @return string
582
-	 */
583
-	function get_path() {
584
-		return TimberURLHelper::get_rel_url($this->get_link());
585
-	}
586
-
587
-	/**
588
-	 * Get the next post in WordPress's ordering
589
-	 * @internal
590
-	 * @param bool $taxonomy
591
-	 * @return TimberPost|boolean
592
-	 */
593
-	function get_prev( $taxonomy = false ) {
594
-		if ( isset($this->_prev) && isset($this->_prev[$taxonomy]) ) {
595
-			return $this->_prev[$taxonomy];
596
-		}
597
-		global $post;
598
-		$old_global = $post;
599
-		$post = $this;
600
-		$within_taxonomy = ($taxonomy) ? $taxonomy : 'category';
601
-		$adjacent = get_adjacent_post(($taxonomy), '', true, $within_taxonomy);
602
-		$prev_in_taxonomy = false;
603
-		if ( $adjacent ) {
604
-			$prev_in_taxonomy = new $this->PostClass($adjacent);
605
-		}
606
-		$this->_prev[$taxonomy] = $prev_in_taxonomy;
607
-		$post = $old_global;
608
-		return $this->_prev[$taxonomy];
609
-	}
610
-
611
-	/**
612
-	 * Get the parent post of the post
613
-	 * @internal
614
-	 * @return bool|TimberPost
615
-	 */
616
-	function get_parent() {
617
-		if ( !$this->post_parent ) {
618
-			return false;
619
-		}
620
-		return new $this->PostClass($this->post_parent);
621
-	}
622
-
623
-	/**
624
-	 * Gets a User object from the author of the post
625
-	 * @internal
626
-	 * @see TimberPost::author
627
-	 * @return bool|TimberUser
628
-	 */
629
-	function get_author() {
630
-		if ( isset($this->post_author) ) {
631
-			return new TimberUser($this->post_author);
632
-		}
633
-	}
634
-
635
-	/**
636
-	 * @internal
637
-	 * @return bool|TimberUser
638
-	 */
639
-	function get_modified_author() {
640
-		$user_id = get_post_meta($this->ID, '_edit_last', true);
641
-		return ($user_id ? new TimberUser($user_id) : $this->get_author());
642
-	}
643
-
644
-	/**
645
-	 * Used internally by init, etc. to build TimberPost object
646
-	 * @internal
647
-	 * @param  int $pid
648
-	 * @return null|object|WP_Post
649
-	 */
650
-	protected function get_info($pid) {
651
-		$post = $this->prepare_post_info($pid);
652
-		if ( !isset($post->post_status) ) {
653
-			return null;
654
-		}
655
-		$post->status = $post->post_status;
656
-		$post->id = $post->ID;
657
-		$post->slug = $post->post_name;
658
-		$customs = $this->get_post_custom($post->ID);
659
-		$post->custom = $customs;
660
-		$post = (object) array_merge((array)$customs, (array)$post);
661
-		return $post;
662
-	}
663
-
664
-	/**
665
-	 * @internal
666
-	 * @see TimberPost::date
667
-	 * @param  string $date_format
668
-	 * @return string
669
-	 */
670
-	function get_date( $date_format = '' ) {
671
-		$df = $date_format ? $date_format : get_option('date_format');
672
-		$the_date = (string)mysql2date($df, $this->post_date);
673
-		return apply_filters('get_the_date', $the_date, $df);
674
-	}
675
-
676
-	/**
677
-	 * @internal
678
-	 * @param  string $date_format
679
-	 * @return string
680
-	 */
681
-	function get_modified_date( $date_format = '' ) {
682
-		$df = $date_format ? $date_format : get_option('date_format');
683
-		$the_time = $this->get_modified_time($df);
684
-		return apply_filters('get_the_modified_date', $the_time, $date_format);
685
-	}
686
-
687
-	/**
688
-	 * @internal
689
-	 * @param  string $time_format
690
-	 * @return string
691
-	 */
692
-	function get_modified_time( $time_format = '' ) {
693
-		$tf = $time_format ? $time_format : get_option('time_format');
694
-		$the_time = get_post_modified_time($tf, false, $this->ID, true);
695
-		return apply_filters('get_the_modified_time', $the_time, $time_format);
696
-	}
697
-
698
-	/**
699
-	 * @internal
700
-	 * @see TimberPost::children
701
-	 * @param string 		$post_type
702
-	 * @param bool|string 	$childPostClass
703
-	 * @return array
704
-	 */
705
-	function get_children( $post_type = 'any', $childPostClass = false ) {
706
-		if ( $childPostClass === false ) {
707
-			$childPostClass = $this->PostClass;
708
-		}
709
-		if ( $post_type == 'parent' ) {
710
-			$post_type = $this->post_type;
711
-		}
712
-		$children = get_children('post_parent=' . $this->ID . '&post_type=' . $post_type . '&numberposts=-1&orderby=menu_order title&order=ASC&post_status=publish');
713
-		foreach ( $children as &$child ) {
714
-			$child = new $childPostClass($child->ID);
715
-		}
716
-		$children = array_values($children);
717
-		return $children;
718
-	}
719
-
720
-
721
-	/**
722
-	 * Get the comments for a post
723
-	 * @internal
724
-	 * @see TimberPost::comments
725
-	 * @param int $ct
726
-	 * @param string $order
727
-	 * @param string $type
728
-	 * @param string $status
729
-	 * @param string $CommentClass
730
-	 * @return array|mixed
731
-	 */
732
-
733
-	function get_comments($ct = 0, $order = 'wp', $type = 'comment', $status = 'approve', $CommentClass = 'TimberComment') {
734
-
735
-		global $overridden_cpage, $user_ID;
736
-		$overridden_cpage = false;
737
-
738
-		$commenter = wp_get_current_commenter();
739
-		$comment_author_email = $commenter['comment_author_email'];
740
-
741
-		$args = array('post_id' => $this->ID, 'status' => $status, 'order' => $order);
742
-		if ( $ct > 0 ) {
743
-			$args['number'] = $ct;
744
-		}
745
-		if ( strtolower($order) == 'wp' || strtolower($order) == 'wordpress' ) {
746
-			$args['order'] = get_option('comment_order');
747
-		}
748
-
749
-		if ( $user_ID ) {
750
-			$args['include_unapproved'] = array( $user_ID );
751
-		} elseif ( ! empty( $comment_author_email ) ) {
752
-			$args['include_unapproved'] = array( $comment_author_email );
753
-		}
754
-
755
-		$comments = get_comments($args);
756
-		$timber_comments = array();
757
-
758
-		if ( '' == get_query_var('cpage') && get_option('page_comments') ) {
759
-			set_query_var( 'cpage', 'newest' == get_option('default_comments_page') ? get_comment_pages_count() : 1 );
760
-			$overridden_cpage = true;
761
-		}
762
-
763
-		foreach($comments as $key => &$comment) {
764
-			$timber_comment = new $CommentClass($comment);
765
-			$timber_comments[$timber_comment->id] = $timber_comment;
766
-		}
767
-
768
-		// Build a flattened (depth=1) comment tree
769
-		$comments_tree = array();
770
-		foreach( $timber_comments as $key => $comment ) {
771
-			if ( ! $comment->is_child() ) {
772
-				continue;
773
-			}
774
-
775
-			$tree_element = $comment;
776
-			do {
777
-				$tree_element = $timber_comments[$tree_element->comment_parent];
778
-			} while( $tree_element->is_child() );
779
-
780
-			$comments_tree[$tree_element->id][] = $comment->id;
781
-		}
782
-
783
-		// Add child comments to the relative "super parents"
784
-		foreach($comments_tree as $comment_parent => $comment_children) {
785
-			foreach($comment_children as $comment_child) {
786
-				$timber_comments[$comment_parent]->children[] = $timber_comments[$comment_child];
787
-				unset($timber_comments[$comment_child]);
788
-			}
789
-		}
790
-
791
-		$timber_comments = array_values($timber_comments);
792
-
793
-		return $timber_comments;
794
-	}
795
-
796
-	/**
797
-	 * Get the categories for a post
798
-	 * @internal
799
-	 * @see TimberPost::categories
800
-	 * @return array of TimberTerms
801
-	 */
802
-	function get_categories() {
803
-		return $this->get_terms('category');
804
-	}
805
-
806
-	/**
807
-	 * @internal
808
-	 * @see TimberPost::category
809
-	 * @return mixed
810
-	 */
811
-	function get_category( ) {
812
-		$cats = $this->get_categories();
813
-		if ( count($cats) && isset($cats[0]) ) {
814
-			return $cats[0];
815
-		}
816
-	}
817
-
818
-	/**
819
-	 * @internal
820
-	 * @param string|array $tax
821
-	 * @param bool $merge
822
-	 * @param string $TermClass
823
-	 * @return array
824
-	 */
825
-	function get_terms( $tax = '', $merge = true, $TermClass = '' ) {
826
-
827
-		$TermClass = $TermClass ?: $this->TermClass;
828
-
829
-		if ( is_string($merge) && class_exists($merge) ) {
830
-			$TermClass = $merge;
831
-		}
832
-		if ( is_array($tax) ) {
833
-			$taxonomies = $tax;
834
-		}
835
-		if ( is_string($tax) ) {
836
-			if ( in_array($tax, array('all','any','')) ) {
837
-				$taxonomies = get_object_taxonomies($this->post_type);
838
-			} else {
839
-				$taxonomies = array($tax);
840
-			}
841
-		}
842
-
843
-		$term_class_objects = array();
844
-
845
-		foreach ( $taxonomies as $taxonomy ) {
846
-			if ( in_array($taxonomy, array('tag','tags')) ) {
847
-				$taxonomy = 'post_tag';
848
-			}
849
-			if ( $taxonomy == 'categories' ) {
850
-				$taxonomy = 'category';
851
-			}
852
-
853
-			$terms = wp_get_post_terms($this->ID, $taxonomy);
854
-
855
-			if ( is_wp_error($terms) ) {
856
-				/* @var $terms WP_Error */
857
-				TimberHelper::error_log("Error retrieving terms for taxonomy '$taxonomy' on a post in timber-post.php");
858
-				TimberHelper::error_log('tax = ' . print_r($tax, true));
859
-				TimberHelper::error_log('WP_Error: ' . $terms->get_error_message());
860
-
861
-				return $term_class_objects;
862
-			}
863
-
864
-			// map over array of wordpress terms, and transform them into instances of the TermClass
865
-			$terms = array_map(function($term) use ($TermClass, $taxonomy) {
866
-				return call_user_func(array($TermClass, 'from'), $term->term_id, $taxonomy);
867
-			}, $terms);
868
-
869
-			if ( $merge && is_array($terms) ) {
870
-				$term_class_objects = array_merge($term_class_objects, $terms);
871
-			} else if ( count($terms) ) {
872
-				$term_class_objects[$taxonomy] = $terms;
873
-			}
874
-		}
875
-		return $term_class_objects;
876
-	}
877
-
878
-	/**
879
-	 * @param string|int $term_name_or_id
880
-	 * @param string $taxonomy
881
-	 * @return bool
882
-	 */
883
-	function has_term( $term_name_or_id, $taxonomy = 'all' ) {
884
-		if ( $taxonomy == 'all' || $taxonomy == 'any' ) {
885
-			$taxes = get_object_taxonomies($this->post_type, 'names');
886
-			$ret = false;
887
-			foreach ( $taxes as $tax ) {
888
-				if ( has_term($term_name_or_id, $tax, $this->ID) ) {
889
-					$ret = true;
890
-					break;
891
-				}
892
-			}
893
-			return $ret;
894
-		}
895
-		return has_term($term_name_or_id, $taxonomy, $this->ID);
896
-	}
897
-
898
-	/**
899
-	 * @param string $field
900
-	 * @return TimberImage
901
-	 */
902
-	function get_image( $field ) {
903
-		return new $this->ImageClass($this->$field);
904
-	}
905
-
906
-	/**
907
-	 * Gets an array of tags for you to use
908
-	 * @internal
909
-	 * @example
910
-	 * ```twig
911
-	 * <ul class="tags">
912
-	 *     {% for tag in post.tags %}
913
-	 *         <li>{{tag.name}}</li>
914
-	 *     {% endfor %}
915
-	 * </ul>
916
-	 * ```
917
-	 * @return array
918
-	 */
919
-	function get_tags() {
920
-		return $this->get_terms('post_tag');
921
-	}
922
-
923
-	/**
924
-	 * Outputs the title with filters applied
925
-	 * @internal
926
-	 * @example
927
-	 * ```twig
928
-	 * <h1>{{post.get_title}}</h1>
929
-	 * ```
930
-	 * ```html
931
-	 * <h1>Hello World!</h1>
932
-	 * ```
933
-	 * @return string
934
-	 */
935
-	function get_title() {
936
-		return apply_filters('the_title', $this->post_title, $this->ID);
937
-	}
938
-
939
-	/**
940
-	 * Displays the content of the post with filters, shortcodes and wpautop applied
941
-	 * @example
942
-	 * ```twig
943
-	 * <div class="article-text">{{post.get_content}}</div>
944
-	 * ```
945
-	 * ```html
946
-	 * <div class="article-text"><p>Blah blah blah</p><p>More blah blah blah.</p></div>
947
-	 * ```
948
-	 * @param int $len
949
-	 * @param int $page
950
-	 * @return string
951
-	 */
952
-	function get_content( $len = 0, $page = 0 ) {
953
-		if ( $len == 0 && $page == 0 && $this->_content ) {
954
-			return $this->_content;
955
-		}
956
-		$content = $this->post_content;
957
-		if ( $len ) {
958
-			$content = wp_trim_words($content, $len);
959
-		}
960
-		if ( $page ) {
961
-			$contents = explode('<!--nextpage-->', $content);
962
-			$page--;
963
-			if ( count($contents) > $page ) {
964
-				$content = $contents[$page];
965
-			}
966
-		}
967
-		$content = apply_filters('the_content', ($content));
968
-		if ( $len == 0 && $page == 0 ) {
969
-			$this->_content = $content;
970
-		}
971
-		return $content;
972
-	}
973
-
974
-	/**
975
-	 * @return string
976
-	 */
977
-	function get_paged_content() {
978
-		global $page;
979
-		return $this->get_content(0, $page);
980
-	}
981
-	/**
982
-	 *
983
-	 * Here is my summary
984
-	 * @example
985
-	 * ```twig
986
-	 * This post is from <span>{{ post.get_post_type.labels.plural }}</span>
987
-	 * ```
988
-	 *
989
-	 * ```html
990
-	 * This post is from <span>Recipes</span>
991
-	 * ```
992
-	 * @return mixed
993
-	 */
994
-	public function get_post_type() {
995
-		return get_post_type_object($this->post_type);
996
-	}
997
-
998
-	/**
999
-	 * @return int the number of comments on a post
1000
-	 */
1001
-	public function get_comment_count() {
1002
-		return get_comments_number($this->ID);
1003
-	}
1004
-
1005
-	/**
1006
-	 * @param string $field_name
1007
-	 * @return mixed
1008
-	 */
1009
-	public function get_field( $field_name ) {
1010
-		$value = apply_filters('timber_post_get_meta_field_pre', null, $this->ID, $field_name, $this);
1011
-		if ( $value === null ) {
1012
-			$value = get_post_meta($this->ID, $field_name);
1013
-			if ( is_array($value) && count($value) == 1 ) {
1014
-				$value = $value[0];
1015
-			}
1016
-			if ( is_array($value) && count($value) == 0 ) {
1017
-				$value = null;
1018
-			}
1019
-		}
1020
-		$value = apply_filters('timber_post_get_meta_field', $value, $this->ID, $field_name, $this);
1021
-		return $value;
1022
-	}
1023
-
1024
-	/**
1025
-	 * @param string $field_name
1026
-	 */
1027
-	function import_field( $field_name ) {
1028
-		$this->$field_name = $this->get_field($field_name);
1029
-	}
1030
-
1031
-	/**
1032
-	 * @internal
1033
-	 * @return mixed
1034
-	 */
1035
-	function get_format() {
1036
-		return get_post_format($this->ID);
1037
-	}
1038
-
1039
-	/**
1040
-	 * Get the CSS classes for a post. For usage you should use `{{post.class}}` instead of `{{post.post_class}}`
1041
-	 * @internal
1042
-	 * @param string $class additional classes you want to add
1043
-	 * @see TimberPost::$class
1044
-	 * @example
1045
-	 * ```twig
1046
-	 * <article class="{{ post.class }}">
1047
-	 *    {# Some stuff here #}
1048
-	 * </article>
1049
-	 * ```
1050
-	 *
1051
-	 * ```html
1052
-	 * <article class="post-2612 post type-post status-publish format-standard has-post-thumbnail hentry category-data tag-charleston-church-shooting tag-dylann-roof tag-gun-violence tag-hate-crimes tag-national-incident-based-reporting-system">
1053
-	 *    {# Some stuff here #}
1054
-	 * </article>
1055
-	 * ```
1056
-	 * @return string a space-seperated list of classes
1057
-	 */
1058
-	public function post_class( $class='' ) {
1059
-		global $post;
1060
-		$old_global_post = $post;
1061
-		$post = $this;
1062
-		$class_array = get_post_class($class, $this->ID);
1063
-		$post = $old_global_post;
1064
-		if ( is_array($class_array) ){
1065
-			return implode(' ', $class_array);
1066
-		}
1067
-		return $class_array;
1068
-	}
1069
-
1070
-	// Docs
1071
-
1072
-	/**
1073
-	 * @return array
1074
-	 * @codeCoverageIgnore
1075
-	 */
1076
-	public function get_method_values() {
1077
-		$ret = parent::get_method_values();
1078
-		$ret['author'] = $this->author();
1079
-		$ret['categories'] = $this->categories();
1080
-		$ret['category'] = $this->category();
1081
-		$ret['children'] = $this->children();
1082
-		$ret['comments'] = $this->comments();
1083
-		$ret['content'] = $this->content();
1084
-		$ret['edit_link'] = $this->edit_link();
1085
-		$ret['format'] = $this->format();
1086
-		$ret['link'] = $this->link();
1087
-		$ret['next'] = $this->next();
1088
-		$ret['pagination'] = $this->pagination();
1089
-		$ret['parent'] = $this->parent();
1090
-		$ret['path'] = $this->path();
1091
-		$ret['prev'] = $this->prev();
1092
-		$ret['terms'] = $this->terms();
1093
-		$ret['tags'] = $this->tags();
1094
-		$ret['thumbnail'] = $this->thumbnail();
1095
-		$ret['title'] = $this->title();
1096
-		return $ret;
1097
-	}
1098
-
1099
-	/**
1100
-	 * Return the author of a post
1101
-	 * @api
1102
-	 * @example
1103
-	 * ```twig
1104
-	 * <h1>{{post.title}}</h1>
1105
-	 * <p class="byline">
1106
-	 *     <a href="{{post.author.link}}">{{post.author.name}}</a>
1107
-	 * </p>
1108
-	 * ```
1109
-	 * @return TimberUser|bool A TimberUser object if found, false if not
1110
-	 */
1111
-	public function author() {
1112
-		return $this->get_author();
1113
-	}
1114
-
1115
-	/**
1116
-	 * Get the author (WordPress user) who last modified the post
1117
-	 * @example
1118
-	 * ```twig
1119
-	 * Last updated by {{ post.modified_author.name }}
1120
-	 * ```
1121
-	 * ```html
1122
-	 * Last updated by Harper Lee
1123
-	 * ```
1124
-	 * @return TimberUser|bool A TimberUser object if found, false if not
1125
-	 */
1126
-	public function modified_author() {
1127
-		return $this->get_modified_author();
1128
-	}
1129
-
1130
-	/**
1131
-	 * Get the categoires on a particular post
1132
-	 * @api
1133
-	 * @return array of TimberTerms
1134
-	 */
1135
-	public function categories() {
1136
-		return $this->get_terms('category');
1137
-	}
1138
-
1139
-	/**
1140
-	 * Returns a category attached to a post
1141
-	 * @api
1142
-	 * If mulitpuile categories are set, it will return just the first one
1143
-	 * @return TimberTerm|null
1144
-	 */
1145
-	public function category() {
1146
-		return $this->get_category();
1147
-	}
1148
-
1149
-	/**
1150
-	 * Returns an array of children on the post as TimberPosts
1151
-	 * (or other claass as you define).
1152
-	 * @api
1153
-	 * @example
1154
-	 * ```twig
1155
-	 * {% if post.children %}
1156
-	 *     Here are the child pages:
1157
-	 *     {% for child in page.children %}
1158
-	 *         <a href="{{ child.link }}">{{ child.title }}</a>
1159
-	 *     {% endfor %}
1160
-	 * {% endif %}
1161
-	 * ```
1162
-	 * @param string $post_type _optional_ use to find children of a particular post type (attachment vs. page for example). You might want to restrict to certain types of children in case other stuff gets all mucked in there. You can use 'parent' to use the parent's post type
1163
-	 * @param string|bool $childPostClass _optional_ a custom post class (ex: 'MyTimberPost') to return the objects as. By default (false) it will use TimberPost::$post_class value.
1164
-	 * @return array
1165
-	 */
1166
-	public function children( $post_type = 'any', $childPostClass = false ) {
1167
-		return $this->get_children( $post_type, $childPostClass );
1168
-	}
1169
-
1170
-	/**
1171
-	 * Gets the comments on a TimberPost and returns them as an array of [TimberComments](#TimberComment) (or whatever comment class you set).
1172
-	 * @api
1173
-	 * @param int $count Set the number of comments you want to get. `0` is analogous to "all"
1174
-	 * @param string $order use ordering set in WordPress admin, or a different scheme
1175
-	 * @param string $type For when other plugins use the comments table for their own special purposes, might be set to 'liveblog' or other depending on what's stored in yr comments table
1176
-	 * @param string $status Could be 'pending', etc.
1177
-	 * @param string $CommentClass What class to use when returning Comment objects. As you become a Timber pro, you might find yourself extending TimberComment for your site or app (obviously, totally optional)
1178
-	 * @example
1179
-	 * ```twig
1180
-	 * {# single.twig #}
1181
-	 * <h4>Comments:</h4>
1182
-	 * {% for comment in post.comments %}
1183
-	 * 	<div class="comment-{{comment.ID}} comment-order-{{loop.index}}">
1184
-	 * 		<p>{{comment.author.name}} said:</p>
1185
-	 * 		<p>{{comment.content}}</p>
1186
-	 * 	</div>
1187
-	 * {% endfor %}
1188
-	 * ```
1189
-	 * @return bool|array
1190
-	 */
1191
-	public function comments( $count = 0, $order = 'wp', $type = 'comment', $status = 'approve', $CommentClass = 'TimberComment' ) {
1192
-		return $this->get_comments($count, $order, $type, $status, $CommentClass);
1193
-	}
1194
-
1195
-	/**
1196
-	 * Gets the actual content of a WP Post, as opposed to post_content this will run the hooks/filters attached to the_content. \This guy will return your posts content with WordPress filters run on it (like for shortcodes and wpautop).
1197
-	 * @api
1198
-	 * @example
1199
-	 * ```twig
1200
-	 * <div class="article">
1201
-	 *     <h2>{{post.title}}</h2>
1202
-	 *     <div class="content">{{ post.content }}</div>
1203
-	 * </div>
1204
-	 * ```
1205
-	 * @param int $page
1206
-	 * @return string
1207
-	 */
1208
-	public function content( $page = 0 ) {
1209
-		return $this->get_content(0, $page);
1210
-	}
1211
-
1212
-	/**
1213
-	 * @return string
1214
-	 */
1215
-	public function paged_content() {
1216
-		return $this->get_paged_content();
1217
-	}
1218
-
1219
-	/**
1220
-	 * Get the date to use in your template!
1221
-	 * @api
1222
-	 * @example
1223
-	 * ```twig
1224
-	 * Published on {{ post.date }} // Uses WP's formatting set in Admin
1225
-	 * OR
1226
-	 * Published on {{ post.date | date('F jS') }} // Jan 12th
1227
-	 * ```
1228
-	 *
1229
-	 * ```html
1230
-	 * Published on January 12, 2015
1231
-	 * OR
1232
-	 * Published on Jan 12th
1233
-	 * ```
1234
-	 * @param string $date_format
1235
-	 * @return string
1236
-	 */
1237
-	public function date( $date_format = '' ) {
1238
-		return $this->get_date($date_format);
1239
-	}
1240
-
1241
-	/**
1242
-	 * Get the time to use in your template
1243
-	 * @api
1244
-	 * @example
1245
-	 * ```twig
1246
-	 * Published at {{ post.time }} // Uses WP's formatting set in Admin
1247
-	 * OR
1248
-	 * Published at {{ post.time | time('G:i') }} // 13:25
1249
-	 * ```
1250
-	 *
1251
-	 * ```html
1252
-	 * Published at 1:25 pm
1253
-	 * OR
1254
-	 * Published at 13:25
1255
-	 * ```
1256
-	 * @param string $time_format
1257
-	 * @return string
1258
-	 */
1259
-	public function time( $time_format = '' ) {
1260
-		$tf = $time_format ? $time_format : get_option('time_format');
1261
-	 	$the_time = (string)mysql2date($tf, $this->post_date);
1262
-	 	return apply_filters('get_the_time', $the_time, $tf);
1263
-	}
1264
-
1265
-	/**
1266
-	 * @return bool|string
1267
-	 */
1268
-	public function edit_link() {
1269
-		return $this->get_edit_url();
1270
-	}
1271
-
1272
-	/**
1273
-	 * @api
1274
-	 * @return mixed
1275
-	 */
1276
-	public function format() {
1277
-		return $this->get_format();
1278
-	}
1279
-
1280
-	/**
1281
-	 * get the permalink for a post object
1282
-	 * @api
1283
-	 * @example
1284
-	 * ```twig
1285
-	 * <a href="{{post.link}}">Read my post</a>
1286
-	 * ```
1287
-	 * @return string ex: http://example.org/2015/07/my-awesome-post
1288
-	 */
1289
-	public function link() {
1290
-		return $this->get_permalink();
1291
-	}
1292
-
1293
-	/**
1294
-	 * @param string $field_name
1295
-	 * @return mixed
1296
-	 */
1297
-	public function meta( $field_name = null ) {
1298
-		if ( $field_name === null ) {
1299
-			//on the off-chance the field is actually named meta
1300
-			$field_name = 'meta';
1301
-		}
1302
-		return $this->get_field($field_name);
1303
-	}
1304
-
1305
-	/**
1306
-	 * @return string
1307
-	 */
1308
-	public function name(){
1309
-		return $this->title();
1310
-	}
1311
-
1312
-	/**
1313
-	 * @param string $date_format
1314
-	 * @return string
1315
-	 */
1316
-	public function modified_date( $date_format = '' ) {
1317
-		return $this->get_modified_date($date_format);
1318
-	}
1319
-
1320
-	/**
1321
-	 * @param string $time_format
1322
-	 * @return string
1323
-	 */
1324
-	public function modified_time( $time_format = '' ) {
1325
-		return $this->get_modified_time($time_format);
1326
-	}
1327
-
1328
-	/**
1329
-	 * @api
1330
-	 * @param bool $in_same_cat
1331
-	 * @return mixed
1332
-	 */
1333
-	public function next( $in_same_cat = false ) {
1334
-		return $this->get_next($in_same_cat);
1335
-	}
1336
-
1337
-	/**
1338
-	 * @return array
1339
-	 */
1340
-	public function pagination() {
1341
-		return $this->get_pagination();
1342
-	}
1343
-
1344
-	/**
1345
-	 * Gets the parent (if one exists) from a post as a TimberPost object (or whatever is set in TimberPost::$PostClass)
1346
-	 * @api
1347
-	 * @example
1348
-	 * ```twig
1349
-	 * Parent page: <a href="{{ post.parent.link }}">{{ post.parent.title }}</a>
1350
-	 * ```
1351
-	 * @return bool|TimberPost
1352
-	 */
1353
-	public function parent() {
1354
-		return $this->get_parent();
1355
-	}
1356
-
1357
-	/**
1358
-	 * Gets the relative path of a WP Post, so while link() will return http://example.org/2015/07/my-cool-post
1359
-	 * this will return just /2015/07/my-cool-post
1360
-	 * @api
1361
-	 * @example
1362
-	 * ```twig
1363
-	 * <a href="{{post.path}}">{{post.title}}</a>
1364
-	 * ```
1365
-	 * @return string
1366
-	 */
1367
-	public function path() {
1368
-		return $this->get_path();
1369
-	}
1370
-
1371
-	/**
1372
-	 * @deprecated 0.20.0 use link() instead
1373
-	 * @return string
1374
-	 */
1375
-	public function permalink() {
1376
-		return $this->get_permalink();
1377
-	}
1378
-
1379
-	/**
1380
-	 * Get the previous post in a set
1381
-	 * @api
1382
-	 * @example
1383
-	 * ```twig
1384
-	 * <h4>Prior Entry:</h4>
1385
-	 * <h3>{{post.prev.title}}</h3>
1386
-	 * <p>{{post.prev.get_preview(25)}}</p>
1387
-	 * ```
1388
-	 * @param bool $in_same_cat
1389
-	 * @return mixed
1390
-	 */
1391
-	public function prev( $in_same_cat = false ) {
1392
-		return $this->get_prev($in_same_cat);
1393
-	}
1394
-
1395
-	/**
1396
-	 * Get the terms associated with the post
1397
-	 * This goes across all taxonomies by default
1398
-	 * @api
1399
-	 * @param string|array $tax What taxonom(y|ies) to pull from. Defaults to all registered taxonomies for the post type. You can use custom ones, or built-in WordPress taxonomies (category, tag). Timber plays nice and figures out that tag/tags/post_tag are all the same (and categories/category), for custom taxonomies you're on your own.
1400
-	 * @param bool $merge Should the resulting array be one big one (true)? Or should it be an array of sub-arrays for each taxonomy (false)?
1401
-	 * @return array
1402
-	 */
1403
-	public function terms( $tax = '', $merge = true ) {
1404
-		return $this->get_terms($tax, $merge);
1405
-	}
1406
-
1407
-	/**
1408
-	 * Gets the tags on a post, uses WP's post_tag taxonomy
1409
-	 * @api
1410
-	 * @return array
1411
-	 */
1412
-	public function tags() {
1413
-		return $this->get_tags();
1414
-	}
1415
-
1416
-	/**
1417
-	 * get the featured image as a TimberImage
1418
-	 * @api
1419
-	 * @example
1420
-	 * ```twig
1421
-	 * <img src="{{post.thumbnail.src}}" />
1422
-	 * ```
1423
-	 * @return TimberImage|null of your thumbnail
1424
-	 */
1425
-	public function thumbnail() {
1426
-		return $this->get_thumbnail();
1427
-	}
1428
-
1429
-	/**
1430
-	 * Returns the processed title to be used in templates. This returns the title of the post after WP's filters have run. This is analogous to `the_title()` in standard WP template tags.
1431
-	 * @api
1432
-	 * @example
1433
-	 * ```twig
1434
-	 * <h1>{{ post.title }}</h1>
1435
-	 * ```
1436
-	 * @return string
1437
-	 */
1438
-	public function title() {
1439
-		return $this->get_title();
1440
-	}
37
+    /**
38
+     * @var string $ImageClass the name of the class to handle images by default
39
+     */
40
+    public $ImageClass = 'TimberImage';
41
+
42
+    /**
43
+     * @var string $PostClass the name of the class to handle posts by default
44
+     */
45
+    public $PostClass = 'TimberPost';
46
+
47
+    /**
48
+     * @var string $TermClass the name of the class to handle terms by default
49
+     */
50
+    public $TermClass = 'TimberTerm';
51
+
52
+    /**
53
+     * @var string $object_type what does this class represent in WordPress terms?
54
+     */
55
+    public $object_type = 'post';
56
+
57
+    /**
58
+     * @var string $representation what does this class represent in WordPress terms?
59
+     */
60
+    public static $representation = 'post';
61
+
62
+    /**
63
+     * @internal
64
+     * @var string $_content stores the processed content internally
65
+     */
66
+    protected $_content;
67
+
68
+    /**
69
+     * @internal
70
+     * @var array $_get_terms stores the results of a get_terms method call
71
+     * @deprecated
72
+     */
73
+    protected $_get_terms;
74
+
75
+    /**
76
+     * @var string $_permalink the returned permalink from WP's get_permalink function
77
+     */
78
+    protected $_permalink;
79
+
80
+    /**
81
+     * @var array $_next stores the results of the next TimberPost in a set inside an array (in order to manage by-taxonomy)
82
+     */
83
+    protected $_next = array();
84
+
85
+    /**
86
+     * @var array $_prev stores the results of the previous TimberPost in a set inside an array (in order to manage by-taxonomy)
87
+     */
88
+    protected $_prev = array();
89
+
90
+    /**
91
+     * @api
92
+     * @var string $class stores the CSS classes for the post (ex: "post post-type-book post-123")
93
+     */
94
+    public $class;
95
+
96
+    /**
97
+     * @api
98
+     * @var string $id the numeric WordPress id of a post
99
+     */
100
+    public $id;
101
+
102
+    /**
103
+     * @var string 	$ID 			the numeric WordPress id of a post, capitalized to match WP usage
104
+     */
105
+    public $ID;
106
+
107
+    /**
108
+     * @var int 	$post_author 	the numeric ID of the a post's author corresponding to the wp_user dtable
109
+     */
110
+    public $post_author;
111
+
112
+    /**
113
+     * @var string 	$post_content 	the raw text of a WP post as stored in the database
114
+     */
115
+    public $post_content;
116
+
117
+    /**
118
+     * @var string 	$post_date 		the raw date string as stored in the WP database, ex: 2014-07-05 18:01:39
119
+     */
120
+    public $post_date;
121
+
122
+    /**
123
+     * @var string 	$post_exceprt 	the raw text of a manual post exceprt as stored in the database
124
+     */
125
+    public $post_excerpt;
126
+
127
+    /**
128
+     * @var int 		$post_parent 	the numeric ID of a post's parent post
129
+     */
130
+    public $post_parent;
131
+
132
+    /**
133
+     * @api
134
+     * @var string 		$post_status 	the status of a post ("draft", "publish", etc.)
135
+     */
136
+    public $post_status;
137
+
138
+    /**
139
+     * @var string 	$post_title 	the raw text of a post's title as stored in the database
140
+     */
141
+    public $post_title;
142
+
143
+    /**
144
+     * @api
145
+     * @var string 	$post_type 		the name of the post type, this is the machine name (so "my_custom_post_type" as opposed to "My Custom Post Type")
146
+     */
147
+    public $post_type;
148
+
149
+    /**
150
+     * @api
151
+     * @var string 	$slug 		the URL-safe slug, this corresponds to the poorly-named "post_name" in the WP database, ex: "hello-world"
152
+     */
153
+    public $slug;
154
+
155
+    /**
156
+     * If you send the constructor nothing it will try to figure out the current post id based on being inside The_Loop
157
+     * @example
158
+     * ```php
159
+     * $post = new TimberPost();
160
+     * $other_post = new TimberPost($random_post_id);
161
+     * ```
162
+     * @param mixed $pid
163
+     */
164
+    public function __construct($pid = null) {
165
+        $pid = $this->determine_id( $pid );
166
+        $this->init($pid);
167
+    }
168
+
169
+    /**
170
+     * tries to figure out what post you want to get if not explictly defined (or if it is, allows it to be passed through)
171
+     * @internal
172
+     * @param mixed a value to test against
173
+     * @return int the numberic id we should be using for this post object
174
+     */
175
+    protected function determine_id($pid) {
176
+        global $wp_query;
177
+        if ( $pid === null &&
178
+            isset($wp_query->queried_object_id)
179
+            && $wp_query->queried_object_id
180
+            && isset($wp_query->queried_object)
181
+            && is_object($wp_query->queried_object)
182
+            && get_class($wp_query->queried_object) == 'WP_Post'
183
+            ) {
184
+                if( isset( $_GET['preview'] ) && isset( $_GET['preview_nonce'] ) && wp_verify_nonce( $_GET['preview_nonce'], 'post_preview_' . $wp_query->queried_object_id ) ) {
185
+                    $pid = $this->get_post_preview_id( $wp_query );
186
+                } else if ( !$pid ) {
187
+                    $pid = $wp_query->queried_object_id;
188
+                }
189
+        } else if ( $pid === null && $wp_query->is_home && isset($wp_query->queried_object_id) && $wp_query->queried_object_id )  {
190
+            //hack for static page as home page
191
+            $pid = $wp_query->queried_object_id;
192
+        } else if ( $pid === null ) {
193
+            $gtid = false;
194
+            $maybe_post = get_post();
195
+            if ( isset($maybe_post->ID) ){
196
+                $gtid = true;
197
+            }
198
+            if ( $gtid ) {
199
+                $pid = get_the_ID();
200
+            }
201
+            if ( !$pid ) {
202
+                global $wp_query;
203
+                if ( isset($wp_query->query['p']) ) {
204
+                    $pid = $wp_query->query['p'];
205
+                }
206
+            }
207
+        }
208
+        if ( $pid === null && ($pid_from_loop = TimberPostGetter::loop_to_id()) ) {
209
+            $pid = $pid_from_loop;
210
+        }
211
+        return $pid;
212
+    }
213
+
214
+    /**
215
+     * Outputs the title of the post if you do something like `<h1>{{post}}</h1>`
216
+     * @return string
217
+     */
218
+    public function __toString() {
219
+        return $this->title();
220
+    }
221
+
222
+    protected function get_post_preview_id( $query ) {
223
+        $can = array(
224
+                'edit_' . $query->queried_object->post_type . 's',
225
+            );
226
+
227
+            if ( $query->queried_object->author_id !== get_current_user_id() ) {
228
+                $can[] = 'edit_others_' . $query->queried_object->post_type . 's';
229
+            }
230
+
231
+            $can_preview = array();
232
+
233
+        foreach( $can as $type ) {
234
+                if( current_user_can( $type ) ) {
235
+                $can_preview[] = true;
236
+                }
237
+        }
238
+
239
+        if ( count( $can_preview ) !== count( $can ) ) {
240
+                return;
241
+        }
242
+
243
+        $revisions = wp_get_post_revisions( $query->queried_object_id );
244
+
245
+        if( !empty( $revisions ) ) {
246
+            $last = end($revisions);
247
+            return $last->ID;
248
+        }
249
+
250
+        return false;
251
+    }
252
+
253
+    /**
254
+     * Initializes a TimberPost
255
+     * @internal
256
+     * @param int|bool $pid
257
+     */
258
+    protected function init($pid = false) {
259
+        if ( $pid === false ) {
260
+            $pid = get_the_ID();
261
+        }
262
+        if ( is_numeric($pid) ) {
263
+            $this->ID = $pid;
264
+        }
265
+        $post_info = $this->get_info($pid);
266
+        $this->import($post_info);
267
+        //cant have a function, so gots to do it this way
268
+        $post_class = $this->post_class();
269
+        $this->class = $post_class;
270
+    }
271
+
272
+    /**
273
+     * Get the URL that will edit the current post/object
274
+     * @internal
275
+     * @see TimberPost::edit_link
276
+     * @return bool|string
277
+     */
278
+    function get_edit_url() {
279
+        if ( $this->can_edit() ) {
280
+            return get_edit_post_link($this->ID);
281
+        }
282
+    }
283
+
284
+    /**
285
+     * updates the post_meta of the current object with the given value
286
+     * @param string $field
287
+     * @param mixed $value
288
+     */
289
+    public function update( $field, $value ) {
290
+        if ( isset($this->ID) ) {
291
+            update_post_meta($this->ID, $field, $value);
292
+            $this->$field = $value;
293
+        }
294
+    }
295
+
296
+
297
+    /**
298
+     * takes a mix of integer (post ID), string (post slug),
299
+     * or object to return a WordPress post object from WP's built-in get_post() function
300
+     * @internal
301
+     * @param mixed $pid
302
+     * @return WP_Post on success
303
+     */
304
+    protected function prepare_post_info( $pid = 0 ) {
305
+        if ( is_string($pid) || is_numeric($pid) || (is_object($pid) && !isset($pid->post_title)) || $pid === 0 ) {
306
+            $pid = self::check_post_id($pid);
307
+            $post = get_post($pid);
308
+            if ( $post ) {
309
+                return $post;
310
+            }
311
+        }
312
+        //we can skip if already is WP_Post
313
+        return $pid;
314
+    }
315
+
316
+
317
+    /**
318
+     * helps you find the post id regardless of whether you send a string or whatever
319
+     * @param integer $pid ;
320
+     * @internal
321
+     * @return integer ID number of a post
322
+     */
323
+    protected function check_post_id( $pid ) {
324
+        if ( is_numeric($pid) && $pid === 0 ) {
325
+            $pid = get_the_ID();
326
+            return $pid;
327
+        }
328
+        if ( !is_numeric($pid) && is_string($pid) ) {
329
+            $pid = self::get_post_id_by_name($pid);
330
+            return $pid;
331
+        }
332
+        if ( !$pid ) {
333
+            return null;
334
+        }
335
+        return $pid;
336
+    }
337
+
338
+
339
+    /**
340
+     * get_post_id_by_name($post_name)
341
+     * @internal
342
+     * @param string $post_name
343
+     * @return int
344
+     */
345
+    static function get_post_id_by_name($post_name) {
346
+        global $wpdb;
347
+        $query = $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_name = %s LIMIT 1", $post_name);
348
+        $result = $wpdb->get_row($query);
349
+        if (!$result) {
350
+            return null;
351
+        }
352
+        return $result->ID;
353
+    }
354
+
355
+    /**
356
+     * get a preview of your post, if you have an excerpt it will use that,
357
+     * otherwise it will pull from the post_content.
358
+     * If there's a <!-- more --> tag it will use that to mark where to pull through.
359
+     * @api
360
+     * @example
361
+     * ```twig
362
+     * <p>{{post.get_preview(50)}}</p>
363
+     * ```
364
+     * @param int $len The number of words that WP should use to make the tease. (Isn't this better than [this mess](http://wordpress.org/support/topic/changing-the-default-length-of-the_excerpt-1?replies=14)?). If you've set a post_excerpt on a post, we'll use that for the preview text; otherwise the first X words of the post_content
365
+     * @param bool $force What happens if your custom post excerpt is longer then the length requested? By default (`$force = false`) it will use the full `post_excerpt`. However, you can set this to true to *force* your excerpt to be of the desired length
366
+     * @param string $readmore The text you want to use on the 'readmore' link
367
+     * @param bool|string $strip true for default, false for none, string for list of custom attributes
368
+     * @param string $end The text to end the preview with (defaults to ...)
369
+     * @return string of the post preview
370
+     */
371
+    function get_preview($len = 50, $force = false, $readmore = 'Read More', $strip = true, $end = '&hellip;') {
372
+        $text = '';
373
+        $trimmed = false;
374
+        if ( isset($this->post_excerpt) && strlen($this->post_excerpt) ) {
375
+            if ( $force ) {
376
+                $text = TimberHelper::trim_words($this->post_excerpt, $len, false);
377
+                $trimmed = true;
378
+            } else {
379
+                $text = $this->post_excerpt;
380
+            }
381
+        }
382
+        if ( !strlen($text) && preg_match('/<!--\s?more(.*?)?-->/', $this->post_content, $readmore_matches) ) {
383
+            $pieces = explode($readmore_matches[0], $this->post_content);
384
+            $text = $pieces[0];
385
+            if ( $force ) {
386
+                $text = TimberHelper::trim_words($text, $len, false);
387
+                $trimmed = true;
388
+            }
389
+            $text = do_shortcode( $text );
390
+        }
391
+        if ( !strlen($text) ) {
392
+            $text = TimberHelper::trim_words($this->get_content(), $len, false);
393
+            $trimmed = true;
394
+        }
395
+        if ( !strlen(trim($text)) ) {
396
+            return trim($text);
397
+        }
398
+        if ( $strip ) {
399
+            $allowable_tags = (is_string($strip)) ? $strip : null;
400
+            $text = trim(strip_tags($text, $allowable_tags));
401
+        }
402
+        if ( strlen($text) ) {
403
+            $text = trim($text);
404
+            $last = $text[strlen($text) - 1];
405
+            if ( $last != '.' && $trimmed ) {
406
+                $text .= $end;
407
+            }
408
+            if ( !$strip ) {
409
+                $last_p_tag = strrpos($text, '</p>');
410
+                if ( $last_p_tag !== false ) {
411
+                    $text = substr($text, 0, $last_p_tag);
412
+                }
413
+                if ( $last != '.' && $trimmed ) {
414
+                    $text .= $end . ' ';
415
+                }
416
+            }
417
+            $read_more_class = apply_filters('timber/post/get_preview/read_more_class', "read-more");
418
+            if ( $readmore && isset($readmore_matches) && !empty($readmore_matches[1]) ) {
419
+                $text .= ' <a href="' . $this->get_permalink() . '" class="'.$read_more_class .'">' . trim($readmore_matches[1]) . '</a>';
420
+            } elseif ( $readmore ) {
421
+                $text .= ' <a href="' . $this->get_permalink() . '" class="'.$read_more_class .'">' . trim($readmore) . '</a>';
422
+            }
423
+            if ( !$strip && $last_p_tag && ( strpos($text, '<p>') || strpos($text, '<p ') ) ) {
424
+                $text .= '</p>';
425
+            }
426
+        }
427
+        return trim($text);
428
+    }
429
+
430
+    /**
431
+     * gets the post custom and attaches it to the current object
432
+     * @internal
433
+     * @param bool|int $pid a post ID number
434
+     */
435
+    function import_custom( $pid = false ) {
436
+        if ( !$pid ) {
437
+            $pid = $this->ID;
438
+        }
439
+        $customs = $this->get_post_custom($pid);
440
+        $this->import($customs);
441
+    }
442
+
443
+    /**
444
+     * Used internally to fetch the metadata fields (wp_postmeta table)
445
+     * and attach them to our TimberPost object
446
+     * @internal
447
+     * @param int $pid
448
+     * @return array
449
+     */
450
+    protected function get_post_custom( $pid ) {
451
+        apply_filters('timber_post_get_meta_pre', array(), $pid, $this);
452
+        $customs = get_post_custom($pid);
453
+        if ( !is_array($customs) || empty($customs) ) {
454
+            return array();
455
+        }
456
+        foreach ( $customs as $key => $value ) {
457
+            if ( is_array($value) && count($value) == 1 && isset($value[0]) ) {
458
+                $value = $value[0];
459
+            }
460
+            $customs[$key] = maybe_unserialize($value);
461
+        }
462
+        $customs = apply_filters('timber_post_get_meta', $customs, $pid, $this);
463
+        return $customs;
464
+    }
465
+
466
+    /**
467
+     * @internal
468
+     * @see TimberPost::thumbnail
469
+     * @return null|TimberImage
470
+     */
471
+    function get_thumbnail() {
472
+        if ( function_exists('get_post_thumbnail_id') ) {
473
+            $tid = get_post_thumbnail_id($this->ID);
474
+            if ( $tid ) {
475
+                return new $this->ImageClass($tid);
476
+            }
477
+        }
478
+    }
479
+
480
+    /**
481
+     * @internal
482
+     * @see TimberPost::link
483
+     * @return string
484
+     */
485
+    function get_permalink() {
486
+        if ( isset($this->_permalink) ) {
487
+            return $this->_permalink;
488
+        }
489
+        $this->_permalink = get_permalink($this->ID);
490
+        return $this->_permalink;
491
+    }
492
+
493
+    /**
494
+     * get the permalink for a post object
495
+     * In your templates you should use link:
496
+     * <a href="{{post.link}}">Read my post</a>
497
+     * @internal
498
+     * @return string
499
+     */
500
+    function get_link() {
501
+        return $this->get_permalink();
502
+    }
503
+
504
+    /**
505
+     * Get the next post in WordPress's ordering
506
+     * @internal
507
+     * @param bool $taxonomy
508
+     * @return TimberPost|boolean
509
+     */
510
+    function get_next( $taxonomy = false ) {
511
+        if ( !isset($this->_next) || !isset($this->_next[$taxonomy]) ) {
512
+            global $post;
513
+            $this->_next = array();
514
+            $old_global = $post;
515
+            $post = $this;
516
+            if ( $taxonomy ) {
517
+                $adjacent = get_adjacent_post(true, '', false, $taxonomy);
518
+            } else {
519
+                $adjacent = get_adjacent_post(false, '', false);
520
+            }
521
+
522
+            if ( $adjacent ) {
523
+                $this->_next[$taxonomy] = new $this->PostClass($adjacent);
524
+            } else {
525
+                $this->_next[$taxonomy] = false;
526
+            }
527
+            $post = $old_global;
528
+        }
529
+        return $this->_next[$taxonomy];
530
+    }
531
+
532
+    /**
533
+     * Get a data array of pagination so you can navigate to the previous/next for a paginated post
534
+     * @return array
535
+     */
536
+    public function get_pagination() {
537
+        global $post, $page, $numpages, $multipage;
538
+        $post = $this;
539
+        $ret = array();
540
+        if ( $multipage ) {
541
+            for ( $i = 1; $i <= $numpages; $i++ ) {
542
+                $link = self::get_wp_link_page($i);
543
+                $data = array('name' => $i, 'title' => $i, 'text' => $i, 'link' => $link);
544
+                if ( $i == $page ) {
545
+                    $data['current'] = true;
546
+                }
547
+                $ret['pages'][] = $data;
548
+            }
549
+            $i = $page - 1;
550
+            if ( $i ) {
551
+                $link = self::get_wp_link_page($i);
552
+                $ret['prev'] = array('link' => $link);
553
+            }
554
+            $i = $page + 1;
555
+            if ( $i <= $numpages ) {
556
+                $link = self::get_wp_link_page($i);
557
+                $ret['next'] = array('link' => $link);
558
+            }
559
+        }
560
+        return $ret;
561
+    }
562
+
563
+    /**
564
+     * @param int $i
565
+     * @return string
566
+     */
567
+    protected static function get_wp_link_page($i) {
568
+        $link = _wp_link_page($i);
569
+        $link = new SimpleXMLElement($link . '</a>');
570
+        if ( isset($link['href']) ) {
571
+            return $link['href'];
572
+        }
573
+        return '';
574
+    }
575
+
576
+    /**
577
+     * Get the permalink for a post, but as a relative path
578
+     * For example, where {{post.link}} would return "http://example.org/2015/07/04/my-cool-post"
579
+     * this will return the relative version: "/2015/07/04/my-cool-post"
580
+     * @internal
581
+     * @return string
582
+     */
583
+    function get_path() {
584
+        return TimberURLHelper::get_rel_url($this->get_link());
585
+    }
586
+
587
+    /**
588
+     * Get the next post in WordPress's ordering
589
+     * @internal
590
+     * @param bool $taxonomy
591
+     * @return TimberPost|boolean
592
+     */
593
+    function get_prev( $taxonomy = false ) {
594
+        if ( isset($this->_prev) && isset($this->_prev[$taxonomy]) ) {
595
+            return $this->_prev[$taxonomy];
596
+        }
597
+        global $post;
598
+        $old_global = $post;
599
+        $post = $this;
600
+        $within_taxonomy = ($taxonomy) ? $taxonomy : 'category';
601
+        $adjacent = get_adjacent_post(($taxonomy), '', true, $within_taxonomy);
602
+        $prev_in_taxonomy = false;
603
+        if ( $adjacent ) {
604
+            $prev_in_taxonomy = new $this->PostClass($adjacent);
605
+        }
606
+        $this->_prev[$taxonomy] = $prev_in_taxonomy;
607
+        $post = $old_global;
608
+        return $this->_prev[$taxonomy];
609
+    }
610
+
611
+    /**
612
+     * Get the parent post of the post
613
+     * @internal
614
+     * @return bool|TimberPost
615
+     */
616
+    function get_parent() {
617
+        if ( !$this->post_parent ) {
618
+            return false;
619
+        }
620
+        return new $this->PostClass($this->post_parent);
621
+    }
622
+
623
+    /**
624
+     * Gets a User object from the author of the post
625
+     * @internal
626
+     * @see TimberPost::author
627
+     * @return bool|TimberUser
628
+     */
629
+    function get_author() {
630
+        if ( isset($this->post_author) ) {
631
+            return new TimberUser($this->post_author);
632
+        }
633
+    }
634
+
635
+    /**
636
+     * @internal
637
+     * @return bool|TimberUser
638
+     */
639
+    function get_modified_author() {
640
+        $user_id = get_post_meta($this->ID, '_edit_last', true);
641
+        return ($user_id ? new TimberUser($user_id) : $this->get_author());
642
+    }
643
+
644
+    /**
645
+     * Used internally by init, etc. to build TimberPost object
646
+     * @internal
647
+     * @param  int $pid
648
+     * @return null|object|WP_Post
649
+     */
650
+    protected function get_info($pid) {
651
+        $post = $this->prepare_post_info($pid);
652
+        if ( !isset($post->post_status) ) {
653
+            return null;
654
+        }
655
+        $post->status = $post->post_status;
656
+        $post->id = $post->ID;
657
+        $post->slug = $post->post_name;
658
+        $customs = $this->get_post_custom($post->ID);
659
+        $post->custom = $customs;
660
+        $post = (object) array_merge((array)$customs, (array)$post);
661
+        return $post;
662
+    }
663
+
664
+    /**
665
+     * @internal
666
+     * @see TimberPost::date
667
+     * @param  string $date_format
668
+     * @return string
669
+     */
670
+    function get_date( $date_format = '' ) {
671
+        $df = $date_format ? $date_format : get_option('date_format');
672
+        $the_date = (string)mysql2date($df, $this->post_date);
673
+        return apply_filters('get_the_date', $the_date, $df);
674
+    }
675
+
676
+    /**
677
+     * @internal
678
+     * @param  string $date_format
679
+     * @return string
680
+     */
681
+    function get_modified_date( $date_format = '' ) {
682
+        $df = $date_format ? $date_format : get_option('date_format');
683
+        $the_time = $this->get_modified_time($df);
684
+        return apply_filters('get_the_modified_date', $the_time, $date_format);
685
+    }
686
+
687
+    /**
688
+     * @internal
689
+     * @param  string $time_format
690
+     * @return string
691
+     */
692
+    function get_modified_time( $time_format = '' ) {
693
+        $tf = $time_format ? $time_format : get_option('time_format');
694
+        $the_time = get_post_modified_time($tf, false, $this->ID, true);
695
+        return apply_filters('get_the_modified_time', $the_time, $time_format);
696
+    }
697
+
698
+    /**
699
+     * @internal
700
+     * @see TimberPost::children
701
+     * @param string 		$post_type
702
+     * @param bool|string 	$childPostClass
703
+     * @return array
704
+     */
705
+    function get_children( $post_type = 'any', $childPostClass = false ) {
706
+        if ( $childPostClass === false ) {
707
+            $childPostClass = $this->PostClass;
708
+        }
709
+        if ( $post_type == 'parent' ) {
710
+            $post_type = $this->post_type;
711
+        }
712
+        $children = get_children('post_parent=' . $this->ID . '&post_type=' . $post_type . '&numberposts=-1&orderby=menu_order title&order=ASC&post_status=publish');
713
+        foreach ( $children as &$child ) {
714
+            $child = new $childPostClass($child->ID);
715
+        }
716
+        $children = array_values($children);
717
+        return $children;
718
+    }
719
+
720
+
721
+    /**
722
+     * Get the comments for a post
723
+     * @internal
724
+     * @see TimberPost::comments
725
+     * @param int $ct
726
+     * @param string $order
727
+     * @param string $type
728
+     * @param string $status
729
+     * @param string $CommentClass
730
+     * @return array|mixed
731
+     */
732
+
733
+    function get_comments($ct = 0, $order = 'wp', $type = 'comment', $status = 'approve', $CommentClass = 'TimberComment') {
734
+
735
+        global $overridden_cpage, $user_ID;
736
+        $overridden_cpage = false;
737
+
738
+        $commenter = wp_get_current_commenter();
739
+        $comment_author_email = $commenter['comment_author_email'];
740
+
741
+        $args = array('post_id' => $this->ID, 'status' => $status, 'order' => $order);
742
+        if ( $ct > 0 ) {
743
+            $args['number'] = $ct;
744
+        }
745
+        if ( strtolower($order) == 'wp' || strtolower($order) == 'wordpress' ) {
746
+            $args['order'] = get_option('comment_order');
747
+        }
748
+
749
+        if ( $user_ID ) {
750
+            $args['include_unapproved'] = array( $user_ID );
751
+        } elseif ( ! empty( $comment_author_email ) ) {
752
+            $args['include_unapproved'] = array( $comment_author_email );
753
+        }
754
+
755
+        $comments = get_comments($args);
756
+        $timber_comments = array();
757
+
758
+        if ( '' == get_query_var('cpage') && get_option('page_comments') ) {
759
+            set_query_var( 'cpage', 'newest' == get_option('default_comments_page') ? get_comment_pages_count() : 1 );
760
+            $overridden_cpage = true;
761
+        }
762
+
763
+        foreach($comments as $key => &$comment) {
764
+            $timber_comment = new $CommentClass($comment);
765
+            $timber_comments[$timber_comment->id] = $timber_comment;
766
+        }
767
+
768
+        // Build a flattened (depth=1) comment tree
769
+        $comments_tree = array();
770
+        foreach( $timber_comments as $key => $comment ) {
771
+            if ( ! $comment->is_child() ) {
772
+                continue;
773
+            }
774
+
775
+            $tree_element = $comment;
776
+            do {
777
+                $tree_element = $timber_comments[$tree_element->comment_parent];
778
+            } while( $tree_element->is_child() );
779
+
780
+            $comments_tree[$tree_element->id][] = $comment->id;
781
+        }
782
+
783
+        // Add child comments to the relative "super parents"
784
+        foreach($comments_tree as $comment_parent => $comment_children) {
785
+            foreach($comment_children as $comment_child) {
786
+                $timber_comments[$comment_parent]->children[] = $timber_comments[$comment_child];
787
+                unset($timber_comments[$comment_child]);
788
+            }
789
+        }
790
+
791
+        $timber_comments = array_values($timber_comments);
792
+
793
+        return $timber_comments;
794
+    }
795
+
796
+    /**
797
+     * Get the categories for a post
798
+     * @internal
799
+     * @see TimberPost::categories
800
+     * @return array of TimberTerms
801
+     */
802
+    function get_categories() {
803
+        return $this->get_terms('category');
804
+    }
805
+
806
+    /**
807
+     * @internal
808
+     * @see TimberPost::category
809
+     * @return mixed
810
+     */
811
+    function get_category( ) {
812
+        $cats = $this->get_categories();
813
+        if ( count($cats) && isset($cats[0]) ) {
814
+            return $cats[0];
815
+        }
816
+    }
817
+
818
+    /**
819
+     * @internal
820
+     * @param string|array $tax
821
+     * @param bool $merge
822
+     * @param string $TermClass
823
+     * @return array
824
+     */
825
+    function get_terms( $tax = '', $merge = true, $TermClass = '' ) {
826
+
827
+        $TermClass = $TermClass ?: $this->TermClass;
828
+
829
+        if ( is_string($merge) && class_exists($merge) ) {
830
+            $TermClass = $merge;
831
+        }
832
+        if ( is_array($tax) ) {
833
+            $taxonomies = $tax;
834
+        }
835
+        if ( is_string($tax) ) {
836
+            if ( in_array($tax, array('all','any','')) ) {
837
+                $taxonomies = get_object_taxonomies($this->post_type);
838
+            } else {
839
+                $taxonomies = array($tax);
840
+            }
841
+        }
842
+
843
+        $term_class_objects = array();
844
+
845
+        foreach ( $taxonomies as $taxonomy ) {
846
+            if ( in_array($taxonomy, array('tag','tags')) ) {
847
+                $taxonomy = 'post_tag';
848
+            }
849
+            if ( $taxonomy == 'categories' ) {
850
+                $taxonomy = 'category';
851
+            }
852
+
853
+            $terms = wp_get_post_terms($this->ID, $taxonomy);
854
+
855
+            if ( is_wp_error($terms) ) {
856
+                /* @var $terms WP_Error */
857
+                TimberHelper::error_log("Error retrieving terms for taxonomy '$taxonomy' on a post in timber-post.php");
858
+                TimberHelper::error_log('tax = ' . print_r($tax, true));
859
+                TimberHelper::error_log('WP_Error: ' . $terms->get_error_message());
860
+
861
+                return $term_class_objects;
862
+            }
863
+
864
+            // map over array of wordpress terms, and transform them into instances of the TermClass
865
+            $terms = array_map(function($term) use ($TermClass, $taxonomy) {
866
+                return call_user_func(array($TermClass, 'from'), $term->term_id, $taxonomy);
867
+            }, $terms);
868
+
869
+            if ( $merge && is_array($terms) ) {
870
+                $term_class_objects = array_merge($term_class_objects, $terms);
871
+            } else if ( count($terms) ) {
872
+                $term_class_objects[$taxonomy] = $terms;
873
+            }
874
+        }
875
+        return $term_class_objects;
876
+    }
877
+
878
+    /**
879
+     * @param string|int $term_name_or_id
880
+     * @param string $taxonomy
881
+     * @return bool
882
+     */
883
+    function has_term( $term_name_or_id, $taxonomy = 'all' ) {
884
+        if ( $taxonomy == 'all' || $taxonomy == 'any' ) {
885
+            $taxes = get_object_taxonomies($this->post_type, 'names');
886
+            $ret = false;
887
+            foreach ( $taxes as $tax ) {
888
+                if ( has_term($term_name_or_id, $tax, $this->ID) ) {
889
+                    $ret = true;
890
+                    break;
891
+                }
892
+            }
893
+            return $ret;
894
+        }
895
+        return has_term($term_name_or_id, $taxonomy, $this->ID);
896
+    }
897
+
898
+    /**
899
+     * @param string $field
900
+     * @return TimberImage
901
+     */
902
+    function get_image( $field ) {
903
+        return new $this->ImageClass($this->$field);
904
+    }
905
+
906
+    /**
907
+     * Gets an array of tags for you to use
908
+     * @internal
909
+     * @example
910
+     * ```twig
911
+     * <ul class="tags">
912
+     *     {% for tag in post.tags %}
913
+     *         <li>{{tag.name}}</li>
914
+     *     {% endfor %}
915
+     * </ul>
916
+     * ```
917
+     * @return array
918
+     */
919
+    function get_tags() {
920
+        return $this->get_terms('post_tag');
921
+    }
922
+
923
+    /**
924
+     * Outputs the title with filters applied
925
+     * @internal
926
+     * @example
927
+     * ```twig
928
+     * <h1>{{post.get_title}}</h1>
929
+     * ```
930
+     * ```html
931
+     * <h1>Hello World!</h1>
932
+     * ```
933
+     * @return string
934
+     */
935
+    function get_title() {
936
+        return apply_filters('the_title', $this->post_title, $this->ID);
937
+    }
938
+
939
+    /**
940
+     * Displays the content of the post with filters, shortcodes and wpautop applied
941
+     * @example
942
+     * ```twig
943
+     * <div class="article-text">{{post.get_content}}</div>
944
+     * ```
945
+     * ```html
946
+     * <div class="article-text"><p>Blah blah blah</p><p>More blah blah blah.</p></div>
947
+     * ```
948
+     * @param int $len
949
+     * @param int $page
950
+     * @return string
951
+     */
952
+    function get_content( $len = 0, $page = 0 ) {
953
+        if ( $len == 0 && $page == 0 && $this->_content ) {
954
+            return $this->_content;
955
+        }
956
+        $content = $this->post_content;
957
+        if ( $len ) {
958
+            $content = wp_trim_words($content, $len);
959
+        }
960
+        if ( $page ) {
961
+            $contents = explode('<!--nextpage-->', $content);
962
+            $page--;
963
+            if ( count($contents) > $page ) {
964
+                $content = $contents[$page];
965
+            }
966
+        }
967
+        $content = apply_filters('the_content', ($content));
968
+        if ( $len == 0 && $page == 0 ) {
969
+            $this->_content = $content;
970
+        }
971
+        return $content;
972
+    }
973
+
974
+    /**
975
+     * @return string
976
+     */
977
+    function get_paged_content() {
978
+        global $page;
979
+        return $this->get_content(0, $page);
980
+    }
981
+    /**
982
+     *
983
+     * Here is my summary
984
+     * @example
985
+     * ```twig
986
+     * This post is from <span>{{ post.get_post_type.labels.plural }}</span>
987
+     * ```
988
+     *
989
+     * ```html
990
+     * This post is from <span>Recipes</span>
991
+     * ```
992
+     * @return mixed
993
+     */
994
+    public function get_post_type() {
995
+        return get_post_type_object($this->post_type);
996
+    }
997
+
998
+    /**
999
+     * @return int the number of comments on a post
1000
+     */
1001
+    public function get_comment_count() {
1002
+        return get_comments_number($this->ID);
1003
+    }
1004
+
1005
+    /**
1006
+     * @param string $field_name
1007
+     * @return mixed
1008
+     */
1009
+    public function get_field( $field_name ) {
1010
+        $value = apply_filters('timber_post_get_meta_field_pre', null, $this->ID, $field_name, $this);
1011
+        if ( $value === null ) {
1012
+            $value = get_post_meta($this->ID, $field_name);
1013
+            if ( is_array($value) && count($value) == 1 ) {
1014
+                $value = $value[0];
1015
+            }
1016
+            if ( is_array($value) && count($value) == 0 ) {
1017
+                $value = null;
1018
+            }
1019
+        }
1020
+        $value = apply_filters('timber_post_get_meta_field', $value, $this->ID, $field_name, $this);
1021
+        return $value;
1022
+    }
1023
+
1024
+    /**
1025
+     * @param string $field_name
1026
+     */
1027
+    function import_field( $field_name ) {
1028
+        $this->$field_name = $this->get_field($field_name);
1029
+    }
1030
+
1031
+    /**
1032
+     * @internal
1033
+     * @return mixed
1034
+     */
1035
+    function get_format() {
1036
+        return get_post_format($this->ID);
1037
+    }
1038
+
1039
+    /**
1040
+     * Get the CSS classes for a post. For usage you should use `{{post.class}}` instead of `{{post.post_class}}`
1041
+     * @internal
1042
+     * @param string $class additional classes you want to add
1043
+     * @see TimberPost::$class
1044
+     * @example
1045
+     * ```twig
1046
+     * <article class="{{ post.class }}">
1047
+     *    {# Some stuff here #}
1048
+     * </article>
1049
+     * ```
1050
+     *
1051
+     * ```html
1052
+     * <article class="post-2612 post type-post status-publish format-standard has-post-thumbnail hentry category-data tag-charleston-church-shooting tag-dylann-roof tag-gun-violence tag-hate-crimes tag-national-incident-based-reporting-system">
1053
+     *    {# Some stuff here #}
1054
+     * </article>
1055
+     * ```
1056
+     * @return string a space-seperated list of classes
1057
+     */
1058
+    public function post_class( $class='' ) {
1059
+        global $post;
1060
+        $old_global_post = $post;
1061
+        $post = $this;
1062
+        $class_array = get_post_class($class, $this->ID);
1063
+        $post = $old_global_post;
1064
+        if ( is_array($class_array) ){
1065
+            return implode(' ', $class_array);
1066
+        }
1067
+        return $class_array;
1068
+    }
1069
+
1070
+    // Docs
1071
+
1072
+    /**
1073
+     * @return array
1074
+     * @codeCoverageIgnore
1075
+     */
1076
+    public function get_method_values() {
1077
+        $ret = parent::get_method_values();
1078
+        $ret['author'] = $this->author();
1079
+        $ret['categories'] = $this->categories();
1080
+        $ret['category'] = $this->category();
1081
+        $ret['children'] = $this->children();
1082
+        $ret['comments'] = $this->comments();
1083
+        $ret['content'] = $this->content();
1084
+        $ret['edit_link'] = $this->edit_link();
1085
+        $ret['format'] = $this->format();
1086
+        $ret['link'] = $this->link();
1087
+        $ret['next'] = $this->next();
1088
+        $ret['pagination'] = $this->pagination();
1089
+        $ret['parent'] = $this->parent();
1090
+        $ret['path'] = $this->path();
1091
+        $ret['prev'] = $this->prev();
1092
+        $ret['terms'] = $this->terms();
1093
+        $ret['tags'] = $this->tags();
1094
+        $ret['thumbnail'] = $this->thumbnail();
1095
+        $ret['title'] = $this->title();
1096
+        return $ret;
1097
+    }
1098
+
1099
+    /**
1100
+     * Return the author of a post
1101
+     * @api
1102
+     * @example
1103
+     * ```twig
1104
+     * <h1>{{post.title}}</h1>
1105
+     * <p class="byline">
1106
+     *     <a href="{{post.author.link}}">{{post.author.name}}</a>
1107
+     * </p>
1108
+     * ```
1109
+     * @return TimberUser|bool A TimberUser object if found, false if not
1110
+     */
1111
+    public function author() {
1112
+        return $this->get_author();
1113
+    }
1114
+
1115
+    /**
1116
+     * Get the author (WordPress user) who last modified the post
1117
+     * @example
1118
+     * ```twig
1119
+     * Last updated by {{ post.modified_author.name }}
1120
+     * ```
1121
+     * ```html
1122
+     * Last updated by Harper Lee
1123
+     * ```
1124
+     * @return TimberUser|bool A TimberUser object if found, false if not
1125
+     */
1126
+    public function modified_author() {
1127
+        return $this->get_modified_author();
1128
+    }
1129
+
1130
+    /**
1131
+     * Get the categoires on a particular post
1132
+     * @api
1133
+     * @return array of TimberTerms
1134
+     */
1135
+    public function categories() {
1136
+        return $this->get_terms('category');
1137
+    }
1138
+
1139
+    /**
1140
+     * Returns a category attached to a post
1141
+     * @api
1142
+     * If mulitpuile categories are set, it will return just the first one
1143
+     * @return TimberTerm|null
1144
+     */
1145
+    public function category() {
1146
+        return $this->get_category();
1147
+    }
1148
+
1149
+    /**
1150
+     * Returns an array of children on the post as TimberPosts
1151
+     * (or other claass as you define).
1152
+     * @api
1153
+     * @example
1154
+     * ```twig
1155
+     * {% if post.children %}
1156
+     *     Here are the child pages:
1157
+     *     {% for child in page.children %}
1158
+     *         <a href="{{ child.link }}">{{ child.title }}</a>
1159
+     *     {% endfor %}
1160
+     * {% endif %}
1161
+     * ```
1162
+     * @param string $post_type _optional_ use to find children of a particular post type (attachment vs. page for example). You might want to restrict to certain types of children in case other stuff gets all mucked in there. You can use 'parent' to use the parent's post type
1163
+     * @param string|bool $childPostClass _optional_ a custom post class (ex: 'MyTimberPost') to return the objects as. By default (false) it will use TimberPost::$post_class value.
1164
+     * @return array
1165
+     */
1166
+    public function children( $post_type = 'any', $childPostClass = false ) {
1167
+        return $this->get_children( $post_type, $childPostClass );
1168
+    }
1169
+
1170
+    /**
1171
+     * Gets the comments on a TimberPost and returns them as an array of [TimberComments](#TimberComment) (or whatever comment class you set).
1172
+     * @api
1173
+     * @param int $count Set the number of comments you want to get. `0` is analogous to "all"
1174
+     * @param string $order use ordering set in WordPress admin, or a different scheme
1175
+     * @param string $type For when other plugins use the comments table for their own special purposes, might be set to 'liveblog' or other depending on what's stored in yr comments table
1176
+     * @param string $status Could be 'pending', etc.
1177
+     * @param string $CommentClass What class to use when returning Comment objects. As you become a Timber pro, you might find yourself extending TimberComment for your site or app (obviously, totally optional)
1178
+     * @example
1179
+     * ```twig
1180
+     * {# single.twig #}
1181
+     * <h4>Comments:</h4>
1182
+     * {% for comment in post.comments %}
1183
+     * 	<div class="comment-{{comment.ID}} comment-order-{{loop.index}}">
1184
+     * 		<p>{{comment.author.name}} said:</p>
1185
+     * 		<p>{{comment.content}}</p>
1186
+     * 	</div>
1187
+     * {% endfor %}
1188
+     * ```
1189
+     * @return bool|array
1190
+     */
1191
+    public function comments( $count = 0, $order = 'wp', $type = 'comment', $status = 'approve', $CommentClass = 'TimberComment' ) {
1192
+        return $this->get_comments($count, $order, $type, $status, $CommentClass);
1193
+    }
1194
+
1195
+    /**
1196
+     * Gets the actual content of a WP Post, as opposed to post_content this will run the hooks/filters attached to the_content. \This guy will return your posts content with WordPress filters run on it (like for shortcodes and wpautop).
1197
+     * @api
1198
+     * @example
1199
+     * ```twig
1200
+     * <div class="article">
1201
+     *     <h2>{{post.title}}</h2>
1202
+     *     <div class="content">{{ post.content }}</div>
1203
+     * </div>
1204
+     * ```
1205
+     * @param int $page
1206
+     * @return string
1207
+     */
1208
+    public function content( $page = 0 ) {
1209
+        return $this->get_content(0, $page);
1210
+    }
1211
+
1212
+    /**
1213
+     * @return string
1214
+     */
1215
+    public function paged_content() {
1216
+        return $this->get_paged_content();
1217
+    }
1218
+
1219
+    /**
1220
+     * Get the date to use in your template!
1221
+     * @api
1222
+     * @example
1223
+     * ```twig
1224
+     * Published on {{ post.date }} // Uses WP's formatting set in Admin
1225
+     * OR
1226
+     * Published on {{ post.date | date('F jS') }} // Jan 12th
1227
+     * ```
1228
+     *
1229
+     * ```html
1230
+     * Published on January 12, 2015
1231
+     * OR
1232
+     * Published on Jan 12th
1233
+     * ```
1234
+     * @param string $date_format
1235
+     * @return string
1236
+     */
1237
+    public function date( $date_format = '' ) {
1238
+        return $this->get_date($date_format);
1239
+    }
1240
+
1241
+    /**
1242
+     * Get the time to use in your template
1243
+     * @api
1244
+     * @example
1245
+     * ```twig
1246
+     * Published at {{ post.time }} // Uses WP's formatting set in Admin
1247
+     * OR
1248
+     * Published at {{ post.time | time('G:i') }} // 13:25
1249
+     * ```
1250
+     *
1251
+     * ```html
1252
+     * Published at 1:25 pm
1253
+     * OR
1254
+     * Published at 13:25
1255
+     * ```
1256
+     * @param string $time_format
1257
+     * @return string
1258
+     */
1259
+    public function time( $time_format = '' ) {
1260
+        $tf = $time_format ? $time_format : get_option('time_format');
1261
+            $the_time = (string)mysql2date($tf, $this->post_date);
1262
+            return apply_filters('get_the_time', $the_time, $tf);
1263
+    }
1264
+
1265
+    /**
1266
+     * @return bool|string
1267
+     */
1268
+    public function edit_link() {
1269
+        return $this->get_edit_url();
1270
+    }
1271
+
1272
+    /**
1273
+     * @api
1274
+     * @return mixed
1275
+     */
1276
+    public function format() {
1277
+        return $this->get_format();
1278
+    }
1279
+
1280
+    /**
1281
+     * get the permalink for a post object
1282
+     * @api
1283
+     * @example
1284
+     * ```twig
1285
+     * <a href="{{post.link}}">Read my post</a>
1286
+     * ```
1287
+     * @return string ex: http://example.org/2015/07/my-awesome-post
1288
+     */
1289
+    public function link() {
1290
+        return $this->get_permalink();
1291
+    }
1292
+
1293
+    /**
1294
+     * @param string $field_name
1295
+     * @return mixed
1296
+     */
1297
+    public function meta( $field_name = null ) {
1298
+        if ( $field_name === null ) {
1299
+            //on the off-chance the field is actually named meta
1300
+            $field_name = 'meta';
1301
+        }
1302
+        return $this->get_field($field_name);
1303
+    }
1304
+
1305
+    /**
1306
+     * @return string
1307
+     */
1308
+    public function name(){
1309
+        return $this->title();
1310
+    }
1311
+
1312
+    /**
1313
+     * @param string $date_format
1314
+     * @return string
1315
+     */
1316
+    public function modified_date( $date_format = '' ) {
1317
+        return $this->get_modified_date($date_format);
1318
+    }
1319
+
1320
+    /**
1321
+     * @param string $time_format
1322
+     * @return string
1323
+     */
1324
+    public function modified_time( $time_format = '' ) {
1325
+        return $this->get_modified_time($time_format);
1326
+    }
1327
+
1328
+    /**
1329
+     * @api
1330
+     * @param bool $in_same_cat
1331
+     * @return mixed
1332
+     */
1333
+    public function next( $in_same_cat = false ) {
1334
+        return $this->get_next($in_same_cat);
1335
+    }
1336
+
1337
+    /**
1338
+     * @return array
1339
+     */
1340
+    public function pagination() {
1341
+        return $this->get_pagination();
1342
+    }
1343
+
1344
+    /**
1345
+     * Gets the parent (if one exists) from a post as a TimberPost object (or whatever is set in TimberPost::$PostClass)
1346
+     * @api
1347
+     * @example
1348
+     * ```twig
1349
+     * Parent page: <a href="{{ post.parent.link }}">{{ post.parent.title }}</a>
1350
+     * ```
1351
+     * @return bool|TimberPost
1352
+     */
1353
+    public function parent() {
1354
+        return $this->get_parent();
1355
+    }
1356
+
1357
+    /**
1358
+     * Gets the relative path of a WP Post, so while link() will return http://example.org/2015/07/my-cool-post
1359
+     * this will return just /2015/07/my-cool-post
1360
+     * @api
1361
+     * @example
1362
+     * ```twig
1363
+     * <a href="{{post.path}}">{{post.title}}</a>
1364
+     * ```
1365
+     * @return string
1366
+     */
1367
+    public function path() {
1368
+        return $this->get_path();
1369
+    }
1370
+
1371
+    /**
1372
+     * @deprecated 0.20.0 use link() instead
1373
+     * @return string
1374
+     */
1375
+    public function permalink() {
1376
+        return $this->get_permalink();
1377
+    }
1378
+
1379
+    /**
1380
+     * Get the previous post in a set
1381
+     * @api
1382
+     * @example
1383
+     * ```twig
1384
+     * <h4>Prior Entry:</h4>
1385
+     * <h3>{{post.prev.title}}</h3>
1386
+     * <p>{{post.prev.get_preview(25)}}</p>
1387
+     * ```
1388
+     * @param bool $in_same_cat
1389
+     * @return mixed
1390
+     */
1391
+    public function prev( $in_same_cat = false ) {
1392
+        return $this->get_prev($in_same_cat);
1393
+    }
1394
+
1395
+    /**
1396
+     * Get the terms associated with the post
1397
+     * This goes across all taxonomies by default
1398
+     * @api
1399
+     * @param string|array $tax What taxonom(y|ies) to pull from. Defaults to all registered taxonomies for the post type. You can use custom ones, or built-in WordPress taxonomies (category, tag). Timber plays nice and figures out that tag/tags/post_tag are all the same (and categories/category), for custom taxonomies you're on your own.
1400
+     * @param bool $merge Should the resulting array be one big one (true)? Or should it be an array of sub-arrays for each taxonomy (false)?
1401
+     * @return array
1402
+     */
1403
+    public function terms( $tax = '', $merge = true ) {
1404
+        return $this->get_terms($tax, $merge);
1405
+    }
1406
+
1407
+    /**
1408
+     * Gets the tags on a post, uses WP's post_tag taxonomy
1409
+     * @api
1410
+     * @return array
1411
+     */
1412
+    public function tags() {
1413
+        return $this->get_tags();
1414
+    }
1415
+
1416
+    /**
1417
+     * get the featured image as a TimberImage
1418
+     * @api
1419
+     * @example
1420
+     * ```twig
1421
+     * <img src="{{post.thumbnail.src}}" />
1422
+     * ```
1423
+     * @return TimberImage|null of your thumbnail
1424
+     */
1425
+    public function thumbnail() {
1426
+        return $this->get_thumbnail();
1427
+    }
1428
+
1429
+    /**
1430
+     * Returns the processed title to be used in templates. This returns the title of the post after WP's filters have run. This is analogous to `the_title()` in standard WP template tags.
1431
+     * @api
1432
+     * @example
1433
+     * ```twig
1434
+     * <h1>{{ post.title }}</h1>
1435
+     * ```
1436
+     * @return string
1437
+     */
1438
+    public function title() {
1439
+        return $this->get_title();
1440
+    }
1441 1441
 
1442 1442
 }
Please login to merge, or discard this patch.
lib/timber-core-interface.php 1 patch
Indentation   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -2,15 +2,15 @@
 block discarded – undo
2 2
 
3 3
 interface TimberCoreInterface {
4 4
 
5
-	public function __call( $field, $args );
5
+    public function __call( $field, $args );
6 6
 
7
-	public function __get( $field );
7
+    public function __get( $field );
8 8
 
9
-	/**
10
-	 * @return boolean
11
-	 */
12
-	public function __isset( $field );
9
+    /**
10
+     * @return boolean
11
+     */
12
+    public function __isset( $field );
13 13
 
14
-	public function meta( $key );
14
+    public function meta( $key );
15 15
 
16 16
 }
Please login to merge, or discard this patch.
lib/timber-function-wrapper.php 1 patch
Indentation   +73 added lines, -73 removed lines patch added patch discarded remove patch
@@ -2,91 +2,91 @@
 block discarded – undo
2 2
 
3 3
 class TimberFunctionWrapper {
4 4
 
5
-	private $_class;
6
-	private $_function;
7
-	private $_args;
8
-	private $_use_ob;
5
+    private $_class;
6
+    private $_function;
7
+    private $_args;
8
+    private $_use_ob;
9 9
 
10
-	public function __toString() {
11
-		 try {
12
-			return (string)$this->call();
13
-		 } catch (Exception $e) {
14
-		 	return 'Caught exception: ' . $e->getMessage() . "\n";
15
-		 }
16
-	}
10
+    public function __toString() {
11
+            try {
12
+            return (string)$this->call();
13
+            } catch (Exception $e) {
14
+                return 'Caught exception: ' . $e->getMessage() . "\n";
15
+            }
16
+    }
17 17
 
18
-	/**
19
-	 *
20
-	 *
21
-	 * @param callable $function
22
-	 * @param array   $args
23
-	 * @param bool    $return_output_buffer
24
-	 */
25
-	public function __construct( $function, $args = array(), $return_output_buffer = false ) {
26
-		if( is_array( $function ) ) {
27
-			if( (is_string( $function[0] ) && class_exists( $function[0] ) ) || gettype( $function[0] ) === 'object' ) {
28
-				$this->_class = $function[0];
29
-			}
18
+    /**
19
+     *
20
+     *
21
+     * @param callable $function
22
+     * @param array   $args
23
+     * @param bool    $return_output_buffer
24
+     */
25
+    public function __construct( $function, $args = array(), $return_output_buffer = false ) {
26
+        if( is_array( $function ) ) {
27
+            if( (is_string( $function[0] ) && class_exists( $function[0] ) ) || gettype( $function[0] ) === 'object' ) {
28
+                $this->_class = $function[0];
29
+            }
30 30
 			
31
-			if( is_string( $function[1] ) ) $this->_function = $function[1];
32
-		} else {
33
-			$this->_function = $function;
34
-		}
31
+            if( is_string( $function[1] ) ) $this->_function = $function[1];
32
+        } else {
33
+            $this->_function = $function;
34
+        }
35 35
 
36
-		$this->_args = $args;
37
-		$this->_use_ob = $return_output_buffer;
36
+        $this->_args = $args;
37
+        $this->_use_ob = $return_output_buffer;
38 38
 
39
-		add_filter( 'get_twig', array( &$this, 'add_to_twig' ) );
40
-	}
39
+        add_filter( 'get_twig', array( &$this, 'add_to_twig' ) );
40
+    }
41 41
 
42
-	/**
43
-	 *
44
-	 *
45
-	 * @param Twig_Environment $twig
46
-	 * @return Twig_Environment
47
-	 */
48
-	public function add_to_twig( $twig ) {
49
-		$wrapper = $this;
42
+    /**
43
+     *
44
+     *
45
+     * @param Twig_Environment $twig
46
+     * @return Twig_Environment
47
+     */
48
+    public function add_to_twig( $twig ) {
49
+        $wrapper = $this;
50 50
 
51
-		$twig->addFunction( new Twig_SimpleFunction( $this->_function, function () use ( $wrapper ) {
52
-					return call_user_func_array( array( $wrapper, 'call' ), func_get_args() );
53
-				} ) );
51
+        $twig->addFunction( new Twig_SimpleFunction( $this->_function, function () use ( $wrapper ) {
52
+                    return call_user_func_array( array( $wrapper, 'call' ), func_get_args() );
53
+                } ) );
54 54
 
55
-		return $twig;
56
-	}
55
+        return $twig;
56
+    }
57 57
 
58
-	/**
59
-	 *
60
-	 *
61
-	 * @return string
62
-	 */
63
-	public function call() {
64
-		$args = $this->_parse_args( func_get_args(), $this->_args );
65
-		$callable = ( isset( $this->_class ) ) ? array( $this->_class, $this->_function ) : $this->_function;
58
+    /**
59
+     *
60
+     *
61
+     * @return string
62
+     */
63
+    public function call() {
64
+        $args = $this->_parse_args( func_get_args(), $this->_args );
65
+        $callable = ( isset( $this->_class ) ) ? array( $this->_class, $this->_function ) : $this->_function;
66 66
 
67
-		if ( $this->_use_ob ) {
68
-			return TimberHelper::ob_function( $callable, $args );
69
-		} else {
70
-			return call_user_func_array( $callable, $args );
71
-		}
72
-	}
67
+        if ( $this->_use_ob ) {
68
+            return TimberHelper::ob_function( $callable, $args );
69
+        } else {
70
+            return call_user_func_array( $callable, $args );
71
+        }
72
+    }
73 73
 
74
-	/**
75
-	 *
76
-	 *
77
-	 * @param array   $args
78
-	 * @param array   $defaults
79
-	 * @return array
80
-	 */
81
-	private function _parse_args( $args, $defaults ) {
82
-		$_arg = reset( $defaults );
74
+    /**
75
+     *
76
+     *
77
+     * @param array   $args
78
+     * @param array   $defaults
79
+     * @return array
80
+     */
81
+    private function _parse_args( $args, $defaults ) {
82
+        $_arg = reset( $defaults );
83 83
 
84
-		foreach ( $args as $index => $arg ) {
85
-			$defaults[$index] = is_null( $arg ) ? $_arg : $arg;
86
-			$_arg = next( $defaults );
87
-		}
84
+        foreach ( $args as $index => $arg ) {
85
+            $defaults[$index] = is_null( $arg ) ? $_arg : $arg;
86
+            $_arg = next( $defaults );
87
+        }
88 88
 
89
-		return $defaults;
90
-	}
89
+        return $defaults;
90
+    }
91 91
 
92 92
 }
Please login to merge, or discard this patch.
lib/timber-term-getter.php 1 patch
Indentation   +167 added lines, -167 removed lines patch added patch discarded remove patch
@@ -2,180 +2,180 @@
 block discarded – undo
2 2
 
3 3
 class TimberTermGetter {
4 4
 
5
-	/**
6
-	 * @param string|array $args
7
-	 * @param array $maybe_args
8
-	 * @param string $TermClass
9
-	 * @return mixed
10
-	 */
11
-	public static function get_terms($args = null, $maybe_args = array(), $TermClass = 'TimberTerm') {
12
-		if ( is_string($maybe_args) && !strstr($maybe_args, '=') ) {
13
-			//the user is sending the $TermClass in the second argument
14
-			$TermClass = $maybe_args;
15
-		}
16
-		if ( is_string($maybe_args) && strstr($maybe_args, '=') ) {
17
-			parse_str($maybe_args, $maybe_args);
18
-		}
19
-		if ( is_string($args) && strstr($args, '=') ) {
20
-			//a string and a query string!
21
-			$parsed = self::get_term_query_from_query_string($args);
22
-			if ( is_array($maybe_args) ) {
23
-				$parsed->args = array_merge($parsed->args, $maybe_args);
24
-			}
25
-			return self::handle_term_query($parsed->taxonomies, $parsed->args, $TermClass);
26
-		} else if ( is_string($args) ) {
27
-			//its just a string with a single taxonomy
28
-			$parsed = self::get_term_query_from_string($args);
29
-			if ( is_array($maybe_args) ) {
30
-				$parsed->args = array_merge($parsed->args, $maybe_args);
31
-			}
32
-			return self::handle_term_query($parsed->taxonomies, $parsed->args, $TermClass);
33
-		} else if ( is_array($args) && TimberHelper::is_array_assoc($args) ) {
34
-			//its an associative array, like a good ole query
35
-			$parsed = self::get_term_query_from_assoc_array($args);
36
-			return self::handle_term_query($parsed->taxonomies, $parsed->args, $TermClass);
37
-		} else if ( is_array($args) ) {
38
-			//its just an array of strings or IDs (hopefully)
39
-			$parsed = self::get_term_query_from_array($args);
40
-			if ( is_array($maybe_args) ) {
41
-				$parsed->args = array_merge($parsed->args, $maybe_args);
42
-			}
43
-			return self::handle_term_query($parsed->taxonomies, $parsed->args, $TermClass);
44
-		} else if ( is_null($args) ) {
45
-			return self::handle_term_query(get_taxonomies(), array(), $TermClass);
46
-		}
47
-		return null;
48
-	}
5
+    /**
6
+     * @param string|array $args
7
+     * @param array $maybe_args
8
+     * @param string $TermClass
9
+     * @return mixed
10
+     */
11
+    public static function get_terms($args = null, $maybe_args = array(), $TermClass = 'TimberTerm') {
12
+        if ( is_string($maybe_args) && !strstr($maybe_args, '=') ) {
13
+            //the user is sending the $TermClass in the second argument
14
+            $TermClass = $maybe_args;
15
+        }
16
+        if ( is_string($maybe_args) && strstr($maybe_args, '=') ) {
17
+            parse_str($maybe_args, $maybe_args);
18
+        }
19
+        if ( is_string($args) && strstr($args, '=') ) {
20
+            //a string and a query string!
21
+            $parsed = self::get_term_query_from_query_string($args);
22
+            if ( is_array($maybe_args) ) {
23
+                $parsed->args = array_merge($parsed->args, $maybe_args);
24
+            }
25
+            return self::handle_term_query($parsed->taxonomies, $parsed->args, $TermClass);
26
+        } else if ( is_string($args) ) {
27
+            //its just a string with a single taxonomy
28
+            $parsed = self::get_term_query_from_string($args);
29
+            if ( is_array($maybe_args) ) {
30
+                $parsed->args = array_merge($parsed->args, $maybe_args);
31
+            }
32
+            return self::handle_term_query($parsed->taxonomies, $parsed->args, $TermClass);
33
+        } else if ( is_array($args) && TimberHelper::is_array_assoc($args) ) {
34
+            //its an associative array, like a good ole query
35
+            $parsed = self::get_term_query_from_assoc_array($args);
36
+            return self::handle_term_query($parsed->taxonomies, $parsed->args, $TermClass);
37
+        } else if ( is_array($args) ) {
38
+            //its just an array of strings or IDs (hopefully)
39
+            $parsed = self::get_term_query_from_array($args);
40
+            if ( is_array($maybe_args) ) {
41
+                $parsed->args = array_merge($parsed->args, $maybe_args);
42
+            }
43
+            return self::handle_term_query($parsed->taxonomies, $parsed->args, $TermClass);
44
+        } else if ( is_null($args) ) {
45
+            return self::handle_term_query(get_taxonomies(), array(), $TermClass);
46
+        }
47
+        return null;
48
+    }
49 49
 
50
-	/**
51
-	 * @param string|array $taxonomies
52
-	 * @param string|array $args
53
-	 * @param string $TermClass
54
-	 * @return mixed
55
-	 */
56
-	public static function handle_term_query($taxonomies, $args, $TermClass) {
57
-		if ( !isset($args['hide_empty']) ) {
58
-			$args['hide_empty'] = false;
59
-		}
60
-		if ( isset($args['term_id']) && is_int($args['term_id']) ) {
61
-			$args['term_id'] = array($args['term_id']);
62
-		}
63
-		if ( isset($args['term_id']) ) {
64
-			$args['include'] = $args['term_id'];
65
-		}
66
-		$terms = get_terms($taxonomies, $args);
67
-		foreach ($terms as &$term) {
68
-			$term = new $TermClass($term->term_id, $term->taxonomy);
69
-		}
70
-		return $terms;
71
-	}
50
+    /**
51
+     * @param string|array $taxonomies
52
+     * @param string|array $args
53
+     * @param string $TermClass
54
+     * @return mixed
55
+     */
56
+    public static function handle_term_query($taxonomies, $args, $TermClass) {
57
+        if ( !isset($args['hide_empty']) ) {
58
+            $args['hide_empty'] = false;
59
+        }
60
+        if ( isset($args['term_id']) && is_int($args['term_id']) ) {
61
+            $args['term_id'] = array($args['term_id']);
62
+        }
63
+        if ( isset($args['term_id']) ) {
64
+            $args['include'] = $args['term_id'];
65
+        }
66
+        $terms = get_terms($taxonomies, $args);
67
+        foreach ($terms as &$term) {
68
+            $term = new $TermClass($term->term_id, $term->taxonomy);
69
+        }
70
+        return $terms;
71
+    }
72 72
 
73
-	/**
74
-	 * @param string $query_string
75
-	 * @return stdClass
76
-	 */
77
-	protected static function get_term_query_from_query_string($query_string) {
78
-		$args = array();
79
-		parse_str($query_string, $args);
80
-		$ret = self::get_term_query_from_assoc_array($args);
81
-		return $ret;
82
-	}
73
+    /**
74
+     * @param string $query_string
75
+     * @return stdClass
76
+     */
77
+    protected static function get_term_query_from_query_string($query_string) {
78
+        $args = array();
79
+        parse_str($query_string, $args);
80
+        $ret = self::get_term_query_from_assoc_array($args);
81
+        return $ret;
82
+    }
83 83
 
84
-	/**
85
-	 * @param string $taxs
86
-	 * @return stdClass
87
-	 */
88
-	protected static function get_term_query_from_string($taxs) {
89
-		$ret = new stdClass();
90
-		$ret->args = array();
91
-		if ( is_string($taxs) ) {
92
-			$taxs = array($taxs);
93
-		}
94
-		$ret->taxonomies = self::correct_taxonomy_names($taxs);
95
-		return $ret;
96
-	}
84
+    /**
85
+     * @param string $taxs
86
+     * @return stdClass
87
+     */
88
+    protected static function get_term_query_from_string($taxs) {
89
+        $ret = new stdClass();
90
+        $ret->args = array();
91
+        if ( is_string($taxs) ) {
92
+            $taxs = array($taxs);
93
+        }
94
+        $ret->taxonomies = self::correct_taxonomy_names($taxs);
95
+        return $ret;
96
+    }
97 97
 
98
-	/**
99
-	 * @param array $args
100
-	 * @return stdClass
101
-	 */
102
-	public static function get_term_query_from_assoc_array($args) {
103
-		$ret = new stdClass();
104
-		$ret->args = $args;
105
-		if ( isset($ret->args['tax']) ) {
106
-			$ret->taxonomies = $ret->args['tax'];
107
-		} else if ( isset($ret->args['taxonomies']) ) {
108
-			$ret->taxonomies = $ret->args['taxonomies'];
109
-		} else if ( isset($ret->args['taxs']) ) {
110
-			$ret->taxonomies = $ret->args['taxs'];
111
-		} else if ( isset($ret->args['taxonomy']) ) {
112
-			$ret->taxonomies = $ret->args['taxonomy'];
113
-		}
114
-		if ( isset($ret->taxonomies) ) {
115
-			if ( is_string($ret->taxonomies) ) {
116
-				$ret->taxonomies = array($ret->taxonomies);
117
-			}
118
-			$ret->taxonomies = self::correct_taxonomy_names($ret->taxonomies);
119
-		} else {
120
-			$ret->taxonomies = get_taxonomies();
121
-		}
122
-		return $ret;
123
-	}
98
+    /**
99
+     * @param array $args
100
+     * @return stdClass
101
+     */
102
+    public static function get_term_query_from_assoc_array($args) {
103
+        $ret = new stdClass();
104
+        $ret->args = $args;
105
+        if ( isset($ret->args['tax']) ) {
106
+            $ret->taxonomies = $ret->args['tax'];
107
+        } else if ( isset($ret->args['taxonomies']) ) {
108
+            $ret->taxonomies = $ret->args['taxonomies'];
109
+        } else if ( isset($ret->args['taxs']) ) {
110
+            $ret->taxonomies = $ret->args['taxs'];
111
+        } else if ( isset($ret->args['taxonomy']) ) {
112
+            $ret->taxonomies = $ret->args['taxonomy'];
113
+        }
114
+        if ( isset($ret->taxonomies) ) {
115
+            if ( is_string($ret->taxonomies) ) {
116
+                $ret->taxonomies = array($ret->taxonomies);
117
+            }
118
+            $ret->taxonomies = self::correct_taxonomy_names($ret->taxonomies);
119
+        } else {
120
+            $ret->taxonomies = get_taxonomies();
121
+        }
122
+        return $ret;
123
+    }
124 124
 
125
-	/**
126
-	 * @param array $args
127
-	 * @return stdClass
128
-	 */
129
-	public static function get_term_query_from_array($args) {
130
-		if ( is_array($args) && !empty($args) ) {
131
-			//okay its an array with content
132
-			if ( is_int($args[0]) ) {
133
-				return self::get_term_query_from_array_of_ids($args);
134
-			} else if ( is_string($args[0]) ) {
135
-				return self::get_term_query_from_array_of_strings($args);
136
-			}
137
-		}
138
-		return null;
139
-	}
125
+    /**
126
+     * @param array $args
127
+     * @return stdClass
128
+     */
129
+    public static function get_term_query_from_array($args) {
130
+        if ( is_array($args) && !empty($args) ) {
131
+            //okay its an array with content
132
+            if ( is_int($args[0]) ) {
133
+                return self::get_term_query_from_array_of_ids($args);
134
+            } else if ( is_string($args[0]) ) {
135
+                return self::get_term_query_from_array_of_strings($args);
136
+            }
137
+        }
138
+        return null;
139
+    }
140 140
 
141
-	/**
142
-	 * @param integer[] $args
143
-	 * @return stdClass
144
-	 */
145
-	public static function get_term_query_from_array_of_ids($args) {
146
-		$ret = new stdClass();
147
-		$ret->taxonomies = get_taxonomies();
148
-		$ret->args['include'] = $args;
149
-		return $ret;
150
-	}
141
+    /**
142
+     * @param integer[] $args
143
+     * @return stdClass
144
+     */
145
+    public static function get_term_query_from_array_of_ids($args) {
146
+        $ret = new stdClass();
147
+        $ret->taxonomies = get_taxonomies();
148
+        $ret->args['include'] = $args;
149
+        return $ret;
150
+    }
151 151
 
152
-	/**
153
-	 * @param string[] $args
154
-	 * @return stdClass
155
-	 */
156
-	public static function get_term_query_from_array_of_strings($args) {
157
-		$ret = new stdClass();
158
-		$ret->taxonomies = self::correct_taxonomy_names($args);
159
-		$ret->args = array();
160
-		return $ret;
161
-	}
152
+    /**
153
+     * @param string[] $args
154
+     * @return stdClass
155
+     */
156
+    public static function get_term_query_from_array_of_strings($args) {
157
+        $ret = new stdClass();
158
+        $ret->taxonomies = self::correct_taxonomy_names($args);
159
+        $ret->args = array();
160
+        return $ret;
161
+    }
162 162
 
163
-	/**
164
-	 * @param string|array $taxs
165
-	 * @return array
166
-	 */
167
-	private static function correct_taxonomy_names($taxs) {
168
-		if ( is_string($taxs) ) {
169
-			$taxs = array($taxs);
170
-		}
171
-		foreach ($taxs as &$tax) {
172
-			if ( $tax == 'tags' || $tax == 'tag' ) {
173
-				$tax = 'post_tag';
174
-			} else if ( $tax == 'categories' ) {
175
-				$tax = 'category';
176
-			}
177
-		}
178
-		return $taxs;
179
-	}
163
+    /**
164
+     * @param string|array $taxs
165
+     * @return array
166
+     */
167
+    private static function correct_taxonomy_names($taxs) {
168
+        if ( is_string($taxs) ) {
169
+            $taxs = array($taxs);
170
+        }
171
+        foreach ($taxs as &$tax) {
172
+            if ( $tax == 'tags' || $tax == 'tag' ) {
173
+                $tax = 'post_tag';
174
+            } else if ( $tax == 'categories' ) {
175
+                $tax = 'category';
176
+            }
177
+        }
178
+        return $taxs;
179
+    }
180 180
 
181 181
 }
Please login to merge, or discard this patch.
lib/timber-loader.php 1 patch
Indentation   +407 added lines, -407 removed lines patch added patch discarded remove patch
@@ -2,412 +2,412 @@
 block discarded – undo
2 2
 
3 3
 class TimberLoader {
4 4
 
5
-	const CACHEGROUP = 'timberloader';
6
-
7
-	const TRANS_KEY_LEN = 50;
8
-
9
-	const CACHE_NONE = 'none';
10
-	const CACHE_OBJECT = 'cache';
11
-	const CACHE_TRANSIENT = 'transient';
12
-	const CACHE_SITE_TRANSIENT = 'site-transient';
13
-	const CACHE_USE_DEFAULT = 'default';
14
-
15
-	public static $cache_modes = array(
16
-		self::CACHE_NONE,
17
-		self::CACHE_OBJECT,
18
-		self::CACHE_TRANSIENT,
19
-		self::CACHE_SITE_TRANSIENT
20
-	);
21
-
22
-	protected $cache_mode = self::CACHE_TRANSIENT;
23
-
24
-	public $locations;
25
-
26
-	/**
27
-	 * @param bool|string   $caller the calling directory or false
28
-	 */
29
-	function __construct($caller = false) {
30
-		$this->locations = $this->get_locations($caller);
31
-		$this->cache_mode = apply_filters('timber_cache_mode', $this->cache_mode);
32
-		$this->cache_mode = apply_filters('timber/cache/mode', $this->cache_mode);
33
-	}
34
-
35
-	/**
36
-	 * @param string        $file
37
-	 * @param array         $data
38
-	 * @param bool          $expires
39
-	 * @param string        $cache_mode
40
-	 * @return bool|string
41
-	 */
42
-	function render($file, $data = null, $expires = false, $cache_mode = self::CACHE_USE_DEFAULT) {
43
-		// Different $expires if user is anonymous or logged in
44
-		if (is_array($expires)) {
45
-			if (is_user_logged_in() && isset($expires[1])) {
46
-				$expires = $expires[1];
47
-			} else {
48
-				$expires = $expires[0];
49
-			}
50
-		}
51
-
52
-		$key = null;
53
-		$output = false;
54
-		if (false !== $expires) {
55
-			ksort($data);
56
-			$key = md5($file . json_encode($data));
57
-			$output = $this->get_cache($key, self::CACHEGROUP, $cache_mode);
58
-		}
59
-
60
-		if (false === $output || null === $output) {
61
-			$twig = $this->get_twig();
62
-			if (strlen($file)) {
63
-				$loader = $this->get_loader();
64
-				$result = $loader->getCacheKey($file);
65
-				do_action('timber_loader_render_file', $result);
66
-			}
67
-			$data = apply_filters('timber_loader_render_data', $data);
68
-			$data = apply_filters('timber/loader/render_data', $data);
69
-			$output = $twig->render($file, $data);
70
-		}
71
-
72
-		if (false !== $output && false !== $expires && null !== $key) {
73
-			$this->set_cache($key, $output, self::CACHEGROUP, $expires, $cache_mode);
74
-		}
75
-		$output = apply_filters('timber_output', $output);
76
-		return apply_filters('timber/output', $output);
77
-	}
78
-
79
-	/**
80
-	 * @param array $filenames
81
-	 * @return bool
82
-	 */
83
-	public function choose_template($filenames) {
84
-		if (is_array($filenames)) {
85
-			/* its an array so we have to figure out which one the dev wants */
86
-			foreach ($filenames as $filename) {
87
-				if (self::template_exists($filename)) {
88
-					return $filename;
89
-				}
90
-			}
91
-			return $filenames[0];
92
-		}
93
-		return $filenames;
94
-	}
95
-
96
-	/**
97
-	 * @param string $file
98
-	 * @return bool
99
-	 */
100
-	protected function template_exists($file) {
101
-		foreach ($this->locations as $dir) {
102
-			$look_for = trailingslashit($dir) . $file;
103
-			if (file_exists($look_for)) {
104
-				return true;
105
-			}
106
-		}
107
-		return false;
108
-	}
109
-
110
-	/**
111
-	 * @return array
112
-	 */
113
-	function get_locations_theme() {
114
-		$theme_locs = array();
115
-		$child_loc = get_stylesheet_directory();
116
-		$parent_loc = get_template_directory();
117
-		if (DIRECTORY_SEPARATOR == '\\') {
118
-			$child_loc = str_replace('/', '\\', $child_loc);
119
-			$parent_loc = str_replace('/', '\\', $parent_loc);
120
-		}
121
-		$theme_locs[] = $child_loc;
122
-		foreach ($this->get_locations_theme_dir() as $dirname) {
123
-			$theme_locs[] = trailingslashit($child_loc) . trailingslashit($dirname);
124
-		}
125
-		if ($child_loc != $parent_loc) {
126
-			$theme_locs[] = $parent_loc;
127
-			foreach ($this->get_locations_theme_dir() as $dirname) {
128
-				$theme_locs[] = trailingslashit($parent_loc) . trailingslashit($dirname);
129
-			}
130
-		}
131
-		//now make sure theres a trailing slash on everything
132
-		$theme_locs = array_map('trailingslashit', $theme_locs);
133
-		return $theme_locs;
134
-	}
135
-
136
-	/**
137
-	 * returns an array of the directory inside themes that holds twig files
138
-	 * @return string[] the names of directores, ie: array('templats', 'views');
139
-	 */
140
-	private function get_locations_theme_dir() {
141
-		if (is_string(Timber::$dirname)) {
142
-			return array(Timber::$dirname);
143
-		}
144
-		return Timber::$dirname;
145
-	}
146
-
147
-	/**
148
-	 * @return array
149
-	 */
150
-	function get_locations_user() {
151
-		$locs = array();
152
-		if (isset(Timber::$locations)) {
153
-			if (is_string(Timber::$locations)) {
154
-				Timber::$locations = array(Timber::$locations);
155
-			}
156
-			foreach (Timber::$locations as $tloc) {
157
-				$tloc = realpath($tloc);
158
-				if (is_dir($tloc)) {
159
-					$locs[] = $tloc;
160
-				}
161
-			}
162
-		}
163
-		return $locs;
164
-	}
165
-
166
-	/**
167
-	 * @param bool|string   $caller the calling directory
168
-	 * @return array
169
-	 */
170
-	function get_locations_caller($caller = false) {
171
-		$locs = array();
172
-		if ($caller && is_string($caller)) {
173
-			$caller = trailingslashit($caller);
174
-			if (is_dir($caller)) {
175
-				$locs[] = $caller;
176
-			}
177
-			foreach ($this->get_locations_theme_dir() as $dirname) {
178
-				$caller_sub = $caller . trailingslashit($dirname);
179
-				if (is_dir($caller_sub)) {
180
-					$locs[] = $caller_sub;
181
-				}
182
-			}
183
-		}
184
-		return $locs;
185
-	}
186
-
187
-	/**
188
-	 * @param bool|string   $caller the calling directory (or false)
189
-	 * @return array
190
-	 */
191
-	function get_locations($caller = false) {
192
-		//prioirty: user locations, caller (but not theme), child theme, parent theme, caller
193
-		$locs = array();
194
-		$locs = array_merge($locs, $this->get_locations_user());
195
-		$locs = array_merge($locs, $this->get_locations_caller($caller));
196
-		//remove themes from caller
197
-		$locs = array_diff($locs, $this->get_locations_theme());
198
-		$locs = array_merge($locs, $this->get_locations_theme());
199
-		$locs = array_merge($locs, $this->get_locations_caller($caller));
200
-		$locs = array_unique($locs);
201
-		$locs = apply_filters('timber_locations', $locs);
202
-		$locs = apply_filters('timber/locations', $locs);
203
-		return $locs;
204
-	}
205
-
206
-	/**
207
-	 * @return Twig_Loader_Filesystem
208
-	 */
209
-	function get_loader() {
210
-		$paths = array();
211
-		foreach ($this->locations as $loc) {
212
-			$loc = realpath($loc);
213
-			if (is_dir($loc)) {
214
-				$loc = realpath($loc);
215
-				$paths[] = $loc;
216
-			} else {
217
-				//error_log($loc.' is not a directory');
218
-			}
219
-		}
220
-		if (!ini_get('open_basedir')) {
221
-			$paths[] = '/';
222
-		} else {
223
-			$paths[] = ABSPATH;
224
-		}
225
-		$paths = apply_filters('timber/loader/paths', $paths);
226
-		$loader = new Twig_Loader_Filesystem($paths);
227
-		return $loader;
228
-	}
229
-
230
-	/**
231
-	 * @return Twig_Environment
232
-	 */
233
-	function get_twig() {
234
-		$loader = $this->get_loader();
235
-		$params = array('debug' => WP_DEBUG, 'autoescape' => false);
236
-		if (isset(Timber::$autoescape)) {
237
-			$params['autoescape'] = Timber::$autoescape;
238
-		}
239
-		if (Timber::$cache === true) {
240
-			Timber::$twig_cache = true;
241
-		}
242
-		if (Timber::$twig_cache) {
243
-			$twig_cache_loc = apply_filters( 'timber/cache/location', TIMBER_LOC . '/cache/twig' );
244
-			if (!file_exists($twig_cache_loc)) {
245
-				mkdir($twig_cache_loc, 0777, true);
246
-			}
247
-			$params['cache'] = $twig_cache_loc;
248
-		}
249
-		$twig = new Twig_Environment($loader, $params);
250
-		if ( WP_DEBUG ) {
251
-			$twig->addExtension(new Twig_Extension_Debug());
252
-		}
253
-		$twig->addExtension($this->_get_cache_extension());
254
-
255
-		$twig = apply_filters('twig_apply_filters', $twig);
256
-		$twig = apply_filters('timber/twig/filters', $twig);
257
-		$twig = apply_filters('timber/loader/twig', $twig);
258
-		return $twig;
259
-	}
260
-
261
-	public function clear_cache_timber($cache_mode = self::CACHE_USE_DEFAULT){
262
-		//_transient_timberloader
263
-		$object_cache = false;
264
-		if (isset($GLOBALS['wp_object_cache']) && is_object($GLOBALS['wp_object_cache'])) {
265
-			$object_cache = true;
266
-		}
267
-		$cache_mode = $this->_get_cache_mode($cache_mode);
268
-		if (self::CACHE_TRANSIENT === $cache_mode) {
269
-			global $wpdb;
270
-			$query = $wpdb->prepare("DELETE FROM $wpdb->options WHERE option_name LIKE '%s'", '_transient_timberloader_%');
271
-			$wpdb->query( $query );
272
-			return true;
273
-		} else if (self::CACHE_SITE_TRANSIENT === $cache_mode) {
274
-			global $wpdb;
275
-			$query = $wpdb->prepare("DELETE FROM $wpdb->options WHERE option_name LIKE '%s'", '_transient_timberloader_%');
276
-			$wpdb->query( $query );
277
-			return true;
278
-		} else if (self::CACHE_OBJECT === $cache_mode && $object_cache) {
279
-			global $wp_object_cache;
280
-			if (isset($wp_object_cache->cache[self::CACHEGROUP])){
281
-				unset($wp_object_cache->cache[self::CACHEGROUP]);
282
-				return true;
283
-			}
284
-		}
285
-		return false;
286
-	}
287
-
288
-	public function clear_cache_twig() {
289
-		$twig = $this->get_twig();
290
-		$twig->clearCacheFiles();
291
-		$cache = $twig->getCache();
292
-		if ($cache){
293
-			self::rrmdir($twig->getCache());
294
-			return true;
295
-		}
296
-		return false;
297
-	}
298
-
299
-	/**
300
-	 * @param string|false $dirPath
301
-	 */
302
-	public static function rrmdir($dirPath) {
303
-		if (! is_dir($dirPath)) {
304
-			throw new InvalidArgumentException("$dirPath must be a directory");
305
-		}
306
-		if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {
307
-			$dirPath .= '/';
308
-		}
309
-		$files = glob($dirPath . '*', GLOB_MARK);
310
-		foreach ($files as $file) {
311
-			if (is_dir($file)) {
312
-				self::rrmdir($file);
313
-			} else {
314
-				unlink($file);
315
-			}
316
-		}
317
-		rmdir($dirPath);
318
-	}
319
-
320
-	/**
321
-	 * @return \Asm89\Twig\CacheExtension\Extension
322
-	 */
323
-	private function _get_cache_extension() {
324
-
325
-		$key_generator   = new \Timber\Cache\KeyGenerator();
326
-		$cache_provider  = new \Timber\Cache\WPObjectCacheAdapter( $this );
327
-		$cache_strategy  = new \Asm89\Twig\CacheExtension\CacheStrategy\GenerationalCacheStrategy( $cache_provider, $key_generator );
328
-		$cache_extension = new \Asm89\Twig\CacheExtension\Extension( $cache_strategy );
329
-
330
-		return $cache_extension;
331
-	}
332
-
333
-	/**
334
-	 * @param string $key
335
-	 * @param string $group
336
-	 * @param string $cache_mode
337
-	 * @return bool
338
-	 */
339
-	public function get_cache($key, $group = self::CACHEGROUP, $cache_mode = self::CACHE_USE_DEFAULT) {
340
-		$object_cache = false;
341
-
342
-		if (isset($GLOBALS['wp_object_cache']) && is_object($GLOBALS['wp_object_cache'])) {
343
-			$object_cache = true;
344
-		}
345
-
346
-		$cache_mode = $this->_get_cache_mode($cache_mode);
347
-
348
-		$value = false;
349
-
350
-		$trans_key = substr($group . '_' . $key, 0, self::TRANS_KEY_LEN);
351
-		if (self::CACHE_TRANSIENT === $cache_mode)
352
-			$value = get_transient($trans_key);
353
-
354
-		elseif (self::CACHE_SITE_TRANSIENT === $cache_mode)
355
-			$value = get_site_transient($trans_key);
356
-
357
-		elseif (self::CACHE_OBJECT === $cache_mode && $object_cache)
358
-			$value = wp_cache_get($key, $group);
359
-
360
-		return $value;
361
-	}
362
-
363
-	/**
364
-	 * @param string $key
365
-	 * @param string|boolean $value
366
-	 * @param string $group
367
-	 * @param int $expires
368
-	 * @param string $cache_mode
369
-	 * @return string|boolean
370
-	 */
371
-	public function set_cache($key, $value, $group = self::CACHEGROUP, $expires = 0, $cache_mode = self::CACHE_USE_DEFAULT) {
372
-		$object_cache = false;
373
-
374
-		if (isset($GLOBALS['wp_object_cache']) && is_object($GLOBALS['wp_object_cache'])) {
375
-			$object_cache = true;
376
-		}
377
-
378
-		if ((int)$expires < 1)
379
-			$expires = 0;
380
-
381
-		$cache_mode = self::_get_cache_mode($cache_mode);
382
-		$trans_key = substr($group . '_' . $key, 0, self::TRANS_KEY_LEN);
383
-
384
-		if (self::CACHE_TRANSIENT === $cache_mode)
385
-			set_transient($trans_key, $value, $expires);
386
-
387
-		elseif (self::CACHE_SITE_TRANSIENT === $cache_mode)
388
-			set_site_transient($trans_key, $value, $expires);
389
-
390
-		elseif (self::CACHE_OBJECT === $cache_mode && $object_cache)
391
-			wp_cache_set($key, $value, $group, $expires);
392
-
393
-		return $value;
394
-	}
395
-
396
-	/**
397
-	 * @param string $cache_mode
398
-	 * @return string
399
-	 */
400
-	private function _get_cache_mode($cache_mode) {
401
-		if (empty($cache_mode) || self::CACHE_USE_DEFAULT === $cache_mode) {
402
-			$cache_mode = $this->cache_mode;
403
-		}
404
-
405
-		// Fallback if self::$cache_mode did not get a valid value
406
-		if (!in_array($cache_mode, self::$cache_modes)) {
407
-			$cache_mode = self::CACHE_OBJECT;
408
-		}
409
-
410
-		return $cache_mode;
411
-	}
5
+    const CACHEGROUP = 'timberloader';
6
+
7
+    const TRANS_KEY_LEN = 50;
8
+
9
+    const CACHE_NONE = 'none';
10
+    const CACHE_OBJECT = 'cache';
11
+    const CACHE_TRANSIENT = 'transient';
12
+    const CACHE_SITE_TRANSIENT = 'site-transient';
13
+    const CACHE_USE_DEFAULT = 'default';
14
+
15
+    public static $cache_modes = array(
16
+        self::CACHE_NONE,
17
+        self::CACHE_OBJECT,
18
+        self::CACHE_TRANSIENT,
19
+        self::CACHE_SITE_TRANSIENT
20
+    );
21
+
22
+    protected $cache_mode = self::CACHE_TRANSIENT;
23
+
24
+    public $locations;
25
+
26
+    /**
27
+     * @param bool|string   $caller the calling directory or false
28
+     */
29
+    function __construct($caller = false) {
30
+        $this->locations = $this->get_locations($caller);
31
+        $this->cache_mode = apply_filters('timber_cache_mode', $this->cache_mode);
32
+        $this->cache_mode = apply_filters('timber/cache/mode', $this->cache_mode);
33
+    }
34
+
35
+    /**
36
+     * @param string        $file
37
+     * @param array         $data
38
+     * @param bool          $expires
39
+     * @param string        $cache_mode
40
+     * @return bool|string
41
+     */
42
+    function render($file, $data = null, $expires = false, $cache_mode = self::CACHE_USE_DEFAULT) {
43
+        // Different $expires if user is anonymous or logged in
44
+        if (is_array($expires)) {
45
+            if (is_user_logged_in() && isset($expires[1])) {
46
+                $expires = $expires[1];
47
+            } else {
48
+                $expires = $expires[0];
49
+            }
50
+        }
51
+
52
+        $key = null;
53
+        $output = false;
54
+        if (false !== $expires) {
55
+            ksort($data);
56
+            $key = md5($file . json_encode($data));
57
+            $output = $this->get_cache($key, self::CACHEGROUP, $cache_mode);
58
+        }
59
+
60
+        if (false === $output || null === $output) {
61
+            $twig = $this->get_twig();
62
+            if (strlen($file)) {
63
+                $loader = $this->get_loader();
64
+                $result = $loader->getCacheKey($file);
65
+                do_action('timber_loader_render_file', $result);
66
+            }
67
+            $data = apply_filters('timber_loader_render_data', $data);
68
+            $data = apply_filters('timber/loader/render_data', $data);
69
+            $output = $twig->render($file, $data);
70
+        }
71
+
72
+        if (false !== $output && false !== $expires && null !== $key) {
73
+            $this->set_cache($key, $output, self::CACHEGROUP, $expires, $cache_mode);
74
+        }
75
+        $output = apply_filters('timber_output', $output);
76
+        return apply_filters('timber/output', $output);
77
+    }
78
+
79
+    /**
80
+     * @param array $filenames
81
+     * @return bool
82
+     */
83
+    public function choose_template($filenames) {
84
+        if (is_array($filenames)) {
85
+            /* its an array so we have to figure out which one the dev wants */
86
+            foreach ($filenames as $filename) {
87
+                if (self::template_exists($filename)) {
88
+                    return $filename;
89
+                }
90
+            }
91
+            return $filenames[0];
92
+        }
93
+        return $filenames;
94
+    }
95
+
96
+    /**
97
+     * @param string $file
98
+     * @return bool
99
+     */
100
+    protected function template_exists($file) {
101
+        foreach ($this->locations as $dir) {
102
+            $look_for = trailingslashit($dir) . $file;
103
+            if (file_exists($look_for)) {
104
+                return true;
105
+            }
106
+        }
107
+        return false;
108
+    }
109
+
110
+    /**
111
+     * @return array
112
+     */
113
+    function get_locations_theme() {
114
+        $theme_locs = array();
115
+        $child_loc = get_stylesheet_directory();
116
+        $parent_loc = get_template_directory();
117
+        if (DIRECTORY_SEPARATOR == '\\') {
118
+            $child_loc = str_replace('/', '\\', $child_loc);
119
+            $parent_loc = str_replace('/', '\\', $parent_loc);
120
+        }
121
+        $theme_locs[] = $child_loc;
122
+        foreach ($this->get_locations_theme_dir() as $dirname) {
123
+            $theme_locs[] = trailingslashit($child_loc) . trailingslashit($dirname);
124
+        }
125
+        if ($child_loc != $parent_loc) {
126
+            $theme_locs[] = $parent_loc;
127
+            foreach ($this->get_locations_theme_dir() as $dirname) {
128
+                $theme_locs[] = trailingslashit($parent_loc) . trailingslashit($dirname);
129
+            }
130
+        }
131
+        //now make sure theres a trailing slash on everything
132
+        $theme_locs = array_map('trailingslashit', $theme_locs);
133
+        return $theme_locs;
134
+    }
135
+
136
+    /**
137
+     * returns an array of the directory inside themes that holds twig files
138
+     * @return string[] the names of directores, ie: array('templats', 'views');
139
+     */
140
+    private function get_locations_theme_dir() {
141
+        if (is_string(Timber::$dirname)) {
142
+            return array(Timber::$dirname);
143
+        }
144
+        return Timber::$dirname;
145
+    }
146
+
147
+    /**
148
+     * @return array
149
+     */
150
+    function get_locations_user() {
151
+        $locs = array();
152
+        if (isset(Timber::$locations)) {
153
+            if (is_string(Timber::$locations)) {
154
+                Timber::$locations = array(Timber::$locations);
155
+            }
156
+            foreach (Timber::$locations as $tloc) {
157
+                $tloc = realpath($tloc);
158
+                if (is_dir($tloc)) {
159
+                    $locs[] = $tloc;
160
+                }
161
+            }
162
+        }
163
+        return $locs;
164
+    }
165
+
166
+    /**
167
+     * @param bool|string   $caller the calling directory
168
+     * @return array
169
+     */
170
+    function get_locations_caller($caller = false) {
171
+        $locs = array();
172
+        if ($caller && is_string($caller)) {
173
+            $caller = trailingslashit($caller);
174
+            if (is_dir($caller)) {
175
+                $locs[] = $caller;
176
+            }
177
+            foreach ($this->get_locations_theme_dir() as $dirname) {
178
+                $caller_sub = $caller . trailingslashit($dirname);
179
+                if (is_dir($caller_sub)) {
180
+                    $locs[] = $caller_sub;
181
+                }
182
+            }
183
+        }
184
+        return $locs;
185
+    }
186
+
187
+    /**
188
+     * @param bool|string   $caller the calling directory (or false)
189
+     * @return array
190
+     */
191
+    function get_locations($caller = false) {
192
+        //prioirty: user locations, caller (but not theme), child theme, parent theme, caller
193
+        $locs = array();
194
+        $locs = array_merge($locs, $this->get_locations_user());
195
+        $locs = array_merge($locs, $this->get_locations_caller($caller));
196
+        //remove themes from caller
197
+        $locs = array_diff($locs, $this->get_locations_theme());
198
+        $locs = array_merge($locs, $this->get_locations_theme());
199
+        $locs = array_merge($locs, $this->get_locations_caller($caller));
200
+        $locs = array_unique($locs);
201
+        $locs = apply_filters('timber_locations', $locs);
202
+        $locs = apply_filters('timber/locations', $locs);
203
+        return $locs;
204
+    }
205
+
206
+    /**
207
+     * @return Twig_Loader_Filesystem
208
+     */
209
+    function get_loader() {
210
+        $paths = array();
211
+        foreach ($this->locations as $loc) {
212
+            $loc = realpath($loc);
213
+            if (is_dir($loc)) {
214
+                $loc = realpath($loc);
215
+                $paths[] = $loc;
216
+            } else {
217
+                //error_log($loc.' is not a directory');
218
+            }
219
+        }
220
+        if (!ini_get('open_basedir')) {
221
+            $paths[] = '/';
222
+        } else {
223
+            $paths[] = ABSPATH;
224
+        }
225
+        $paths = apply_filters('timber/loader/paths', $paths);
226
+        $loader = new Twig_Loader_Filesystem($paths);
227
+        return $loader;
228
+    }
229
+
230
+    /**
231
+     * @return Twig_Environment
232
+     */
233
+    function get_twig() {
234
+        $loader = $this->get_loader();
235
+        $params = array('debug' => WP_DEBUG, 'autoescape' => false);
236
+        if (isset(Timber::$autoescape)) {
237
+            $params['autoescape'] = Timber::$autoescape;
238
+        }
239
+        if (Timber::$cache === true) {
240
+            Timber::$twig_cache = true;
241
+        }
242
+        if (Timber::$twig_cache) {
243
+            $twig_cache_loc = apply_filters( 'timber/cache/location', TIMBER_LOC . '/cache/twig' );
244
+            if (!file_exists($twig_cache_loc)) {
245
+                mkdir($twig_cache_loc, 0777, true);
246
+            }
247
+            $params['cache'] = $twig_cache_loc;
248
+        }
249
+        $twig = new Twig_Environment($loader, $params);
250
+        if ( WP_DEBUG ) {
251
+            $twig->addExtension(new Twig_Extension_Debug());
252
+        }
253
+        $twig->addExtension($this->_get_cache_extension());
254
+
255
+        $twig = apply_filters('twig_apply_filters', $twig);
256
+        $twig = apply_filters('timber/twig/filters', $twig);
257
+        $twig = apply_filters('timber/loader/twig', $twig);
258
+        return $twig;
259
+    }
260
+
261
+    public function clear_cache_timber($cache_mode = self::CACHE_USE_DEFAULT){
262
+        //_transient_timberloader
263
+        $object_cache = false;
264
+        if (isset($GLOBALS['wp_object_cache']) && is_object($GLOBALS['wp_object_cache'])) {
265
+            $object_cache = true;
266
+        }
267
+        $cache_mode = $this->_get_cache_mode($cache_mode);
268
+        if (self::CACHE_TRANSIENT === $cache_mode) {
269
+            global $wpdb;
270
+            $query = $wpdb->prepare("DELETE FROM $wpdb->options WHERE option_name LIKE '%s'", '_transient_timberloader_%');
271
+            $wpdb->query( $query );
272
+            return true;
273
+        } else if (self::CACHE_SITE_TRANSIENT === $cache_mode) {
274
+            global $wpdb;
275
+            $query = $wpdb->prepare("DELETE FROM $wpdb->options WHERE option_name LIKE '%s'", '_transient_timberloader_%');
276
+            $wpdb->query( $query );
277
+            return true;
278
+        } else if (self::CACHE_OBJECT === $cache_mode && $object_cache) {
279
+            global $wp_object_cache;
280
+            if (isset($wp_object_cache->cache[self::CACHEGROUP])){
281
+                unset($wp_object_cache->cache[self::CACHEGROUP]);
282
+                return true;
283
+            }
284
+        }
285
+        return false;
286
+    }
287
+
288
+    public function clear_cache_twig() {
289
+        $twig = $this->get_twig();
290
+        $twig->clearCacheFiles();
291
+        $cache = $twig->getCache();
292
+        if ($cache){
293
+            self::rrmdir($twig->getCache());
294
+            return true;
295
+        }
296
+        return false;
297
+    }
298
+
299
+    /**
300
+     * @param string|false $dirPath
301
+     */
302
+    public static function rrmdir($dirPath) {
303
+        if (! is_dir($dirPath)) {
304
+            throw new InvalidArgumentException("$dirPath must be a directory");
305
+        }
306
+        if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {
307
+            $dirPath .= '/';
308
+        }
309
+        $files = glob($dirPath . '*', GLOB_MARK);
310
+        foreach ($files as $file) {
311
+            if (is_dir($file)) {
312
+                self::rrmdir($file);
313
+            } else {
314
+                unlink($file);
315
+            }
316
+        }
317
+        rmdir($dirPath);
318
+    }
319
+
320
+    /**
321
+     * @return \Asm89\Twig\CacheExtension\Extension
322
+     */
323
+    private function _get_cache_extension() {
324
+
325
+        $key_generator   = new \Timber\Cache\KeyGenerator();
326
+        $cache_provider  = new \Timber\Cache\WPObjectCacheAdapter( $this );
327
+        $cache_strategy  = new \Asm89\Twig\CacheExtension\CacheStrategy\GenerationalCacheStrategy( $cache_provider, $key_generator );
328
+        $cache_extension = new \Asm89\Twig\CacheExtension\Extension( $cache_strategy );
329
+
330
+        return $cache_extension;
331
+    }
332
+
333
+    /**
334
+     * @param string $key
335
+     * @param string $group
336
+     * @param string $cache_mode
337
+     * @return bool
338
+     */
339
+    public function get_cache($key, $group = self::CACHEGROUP, $cache_mode = self::CACHE_USE_DEFAULT) {
340
+        $object_cache = false;
341
+
342
+        if (isset($GLOBALS['wp_object_cache']) && is_object($GLOBALS['wp_object_cache'])) {
343
+            $object_cache = true;
344
+        }
345
+
346
+        $cache_mode = $this->_get_cache_mode($cache_mode);
347
+
348
+        $value = false;
349
+
350
+        $trans_key = substr($group . '_' . $key, 0, self::TRANS_KEY_LEN);
351
+        if (self::CACHE_TRANSIENT === $cache_mode)
352
+            $value = get_transient($trans_key);
353
+
354
+        elseif (self::CACHE_SITE_TRANSIENT === $cache_mode)
355
+            $value = get_site_transient($trans_key);
356
+
357
+        elseif (self::CACHE_OBJECT === $cache_mode && $object_cache)
358
+            $value = wp_cache_get($key, $group);
359
+
360
+        return $value;
361
+    }
362
+
363
+    /**
364
+     * @param string $key
365
+     * @param string|boolean $value
366
+     * @param string $group
367
+     * @param int $expires
368
+     * @param string $cache_mode
369
+     * @return string|boolean
370
+     */
371
+    public function set_cache($key, $value, $group = self::CACHEGROUP, $expires = 0, $cache_mode = self::CACHE_USE_DEFAULT) {
372
+        $object_cache = false;
373
+
374
+        if (isset($GLOBALS['wp_object_cache']) && is_object($GLOBALS['wp_object_cache'])) {
375
+            $object_cache = true;
376
+        }
377
+
378
+        if ((int)$expires < 1)
379
+            $expires = 0;
380
+
381
+        $cache_mode = self::_get_cache_mode($cache_mode);
382
+        $trans_key = substr($group . '_' . $key, 0, self::TRANS_KEY_LEN);
383
+
384
+        if (self::CACHE_TRANSIENT === $cache_mode)
385
+            set_transient($trans_key, $value, $expires);
386
+
387
+        elseif (self::CACHE_SITE_TRANSIENT === $cache_mode)
388
+            set_site_transient($trans_key, $value, $expires);
389
+
390
+        elseif (self::CACHE_OBJECT === $cache_mode && $object_cache)
391
+            wp_cache_set($key, $value, $group, $expires);
392
+
393
+        return $value;
394
+    }
395
+
396
+    /**
397
+     * @param string $cache_mode
398
+     * @return string
399
+     */
400
+    private function _get_cache_mode($cache_mode) {
401
+        if (empty($cache_mode) || self::CACHE_USE_DEFAULT === $cache_mode) {
402
+            $cache_mode = $this->cache_mode;
403
+        }
404
+
405
+        // Fallback if self::$cache_mode did not get a valid value
406
+        if (!in_array($cache_mode, self::$cache_modes)) {
407
+            $cache_mode = self::CACHE_OBJECT;
408
+        }
409
+
410
+        return $cache_mode;
411
+    }
412 412
 
413 413
 }
Please login to merge, or discard this patch.
lib/timber-term.php 1 patch
Indentation   +387 added lines, -387 removed lines patch added patch discarded remove patch
@@ -32,398 +32,398 @@
 block discarded – undo
32 32
  */
33 33
 class TimberTerm extends TimberCore implements TimberCoreInterface {
34 34
 
35
-	public $PostClass = 'TimberPost';
36
-	public $TermClass = 'TimberTerm';
37
-
38
-	public $object_type = 'term';
39
-	public static $representation = 'term';
40
-
41
-	public $_children;
42
-	/**
43
-	 * @api
44
-	 * @var string the human-friendly name of the term (ex: French Cuisine)
45
-	 */
46
-	public $name;
47
-	/**
48
-	 * @api
49
-	 * @var strng the WordPress taxonomy slug (ex: `post_tag` or `actors`)
50
-	 */
51
-	public $taxonomy;
52
-
53
-	/**
54
-	 * @param int $tid
55
-	 * @param string $tax
56
-	 */
57
-	public function __construct( $tid = null, $tax = '' ) {
58
-		if ($tid === null) {
59
-			$tid = $this->get_term_from_query();
60
-		}
61
-		if (strlen($tax)) {
62
-			$this->taxonomy = $tax;
63
-		}
64
-		$this->init($tid);
65
-	}
66
-
67
-	/**
68
-	 * @return string
69
-	 */
70
-	public function __toString() {
71
-		return $this->name;
72
-	}
73
-
74
-	/**
75
-	 * @param $tid
76
-	 * @param $taxonomy
77
-	 *
78
-	 * @return static
79
-	 */
80
-	public static function from( $tid, $taxonomy ) {
81
-		return new static($tid, $taxonomy);
82
-	}
83
-
84
-
85
-	/* Setup
35
+    public $PostClass = 'TimberPost';
36
+    public $TermClass = 'TimberTerm';
37
+
38
+    public $object_type = 'term';
39
+    public static $representation = 'term';
40
+
41
+    public $_children;
42
+    /**
43
+     * @api
44
+     * @var string the human-friendly name of the term (ex: French Cuisine)
45
+     */
46
+    public $name;
47
+    /**
48
+     * @api
49
+     * @var strng the WordPress taxonomy slug (ex: `post_tag` or `actors`)
50
+     */
51
+    public $taxonomy;
52
+
53
+    /**
54
+     * @param int $tid
55
+     * @param string $tax
56
+     */
57
+    public function __construct( $tid = null, $tax = '' ) {
58
+        if ($tid === null) {
59
+            $tid = $this->get_term_from_query();
60
+        }
61
+        if (strlen($tax)) {
62
+            $this->taxonomy = $tax;
63
+        }
64
+        $this->init($tid);
65
+    }
66
+
67
+    /**
68
+     * @return string
69
+     */
70
+    public function __toString() {
71
+        return $this->name;
72
+    }
73
+
74
+    /**
75
+     * @param $tid
76
+     * @param $taxonomy
77
+     *
78
+     * @return static
79
+     */
80
+    public static function from( $tid, $taxonomy ) {
81
+        return new static($tid, $taxonomy);
82
+    }
83
+
84
+
85
+    /* Setup
86 86
 	===================== */
87 87
 
88
-	/**
89
-	 * @internal
90
-	 * @return integer
91
-	 */
92
-	protected function get_term_from_query() {
93
-		global $wp_query;
94
-		if ( isset($wp_query->queried_object) ) {
95
-			$qo = $wp_query->queried_object;
96
-			if (isset($qo->term_id)) {
97
-				return $qo->term_id;
98
-			}
99
-		}
100
-		if ( isset($wp_query->tax_query->queries[0]['terms'][0]) ) {
101
-			return $wp_query->tax_query->queries[0]['terms'][0];
102
-		}
103
-	}
104
-
105
-	/**
106
-	 * @internal
107
-	 * @param int $tid
108
-	 */
109
-	protected function init( $tid ) {
110
-		$term = $this->get_term($tid);
111
-		if ( isset($term->id) ) {
112
-			$term->ID = $term->id;
113
-		} else if ( isset($term->term_id) ) {
114
-			$term->ID = $term->term_id;
115
-		} else if ( is_string($tid) ) {
116
-			//echo 'bad call using '.$tid;
117
-			//TimberHelper::error_log(debug_backtrace());
118
-		}
119
-		if ( isset($term->ID) ){
120
-			$term->id = $term->ID;
121
-			$this->import($term);
122
-			if ( isset($term->term_id) ) {
123
-				$custom = $this->get_term_meta($term->term_id);
124
-				$this->import($custom);
125
-			}
126
-		}
127
-	}
128
-
129
-	/**
130
-	 * @internal
131
-	 * @param int $tid
132
-	 * @return array
133
-	 */
134
-	protected function get_term_meta($tid) {
135
-		$customs = array();
136
-		$customs = apply_filters('timber_term_get_meta', $customs, $tid, $this);
137
-		return apply_filters('timber/term/meta', $customs, $tid, $this);
138
-	}
139
-
140
-	/**
141
-	 * @internal
142
-	 * @param int $tid
143
-	 * @return mixed
144
-	 */
145
-	protected function get_term( $tid ) {
146
-		if ( is_object($tid) || is_array($tid) ) {
147
-			return $tid;
148
-		}
149
-		$tid = self::get_tid($tid);
150
-
151
-		if ( isset($this->taxonomy) && strlen($this->taxonomy) ) {
152
-			return get_term($tid, $this->taxonomy);
153
-		} else {
154
-			global $wpdb;
155
-			$query = $wpdb->prepare("SELECT taxonomy FROM $wpdb->term_taxonomy WHERE term_id = %d LIMIT 1", $tid);
156
-			$tax = $wpdb->get_var($query);
157
-			if (isset($tax) && strlen($tax)) {
158
-				$this->taxonomy = $tax;
159
-				return get_term($tid, $tax);
160
-			}
161
-		}
162
-		return null;
163
-	}
164
-
165
-	/**
166
-	 * @internal
167
-	 * @param int $tid
168
-	 * @return int
169
-	 */
170
-	protected function get_tid( $tid ) {
171
-		global $wpdb;
172
-		if ( is_numeric($tid) ) {
173
-			return $tid;
174
-		}
175
-		if ( gettype($tid) == 'object' ) {
176
-			$tid = $tid->term_id;
177
-		}
178
-		if ( is_numeric($tid) ) {
179
-			$query = $wpdb->prepare("SELECT * FROM $wpdb->terms WHERE term_id = %d", $tid);
180
-		} else {
181
-			$query = $wpdb->prepare("SELECT * FROM $wpdb->terms WHERE slug = %s", $tid);
182
-		}
183
-		$result = $wpdb->get_row($query);
184
-		if ( isset($result->term_id) ) {
185
-			$result->ID = $result->term_id;
186
-			$result->id = $result->term_id;
187
-			return $result->ID;
188
-		}
189
-		return 0;
190
-	}
191
-
192
-	/* Public methods
88
+    /**
89
+     * @internal
90
+     * @return integer
91
+     */
92
+    protected function get_term_from_query() {
93
+        global $wp_query;
94
+        if ( isset($wp_query->queried_object) ) {
95
+            $qo = $wp_query->queried_object;
96
+            if (isset($qo->term_id)) {
97
+                return $qo->term_id;
98
+            }
99
+        }
100
+        if ( isset($wp_query->tax_query->queries[0]['terms'][0]) ) {
101
+            return $wp_query->tax_query->queries[0]['terms'][0];
102
+        }
103
+    }
104
+
105
+    /**
106
+     * @internal
107
+     * @param int $tid
108
+     */
109
+    protected function init( $tid ) {
110
+        $term = $this->get_term($tid);
111
+        if ( isset($term->id) ) {
112
+            $term->ID = $term->id;
113
+        } else if ( isset($term->term_id) ) {
114
+            $term->ID = $term->term_id;
115
+        } else if ( is_string($tid) ) {
116
+            //echo 'bad call using '.$tid;
117
+            //TimberHelper::error_log(debug_backtrace());
118
+        }
119
+        if ( isset($term->ID) ){
120
+            $term->id = $term->ID;
121
+            $this->import($term);
122
+            if ( isset($term->term_id) ) {
123
+                $custom = $this->get_term_meta($term->term_id);
124
+                $this->import($custom);
125
+            }
126
+        }
127
+    }
128
+
129
+    /**
130
+     * @internal
131
+     * @param int $tid
132
+     * @return array
133
+     */
134
+    protected function get_term_meta($tid) {
135
+        $customs = array();
136
+        $customs = apply_filters('timber_term_get_meta', $customs, $tid, $this);
137
+        return apply_filters('timber/term/meta', $customs, $tid, $this);
138
+    }
139
+
140
+    /**
141
+     * @internal
142
+     * @param int $tid
143
+     * @return mixed
144
+     */
145
+    protected function get_term( $tid ) {
146
+        if ( is_object($tid) || is_array($tid) ) {
147
+            return $tid;
148
+        }
149
+        $tid = self::get_tid($tid);
150
+
151
+        if ( isset($this->taxonomy) && strlen($this->taxonomy) ) {
152
+            return get_term($tid, $this->taxonomy);
153
+        } else {
154
+            global $wpdb;
155
+            $query = $wpdb->prepare("SELECT taxonomy FROM $wpdb->term_taxonomy WHERE term_id = %d LIMIT 1", $tid);
156
+            $tax = $wpdb->get_var($query);
157
+            if (isset($tax) && strlen($tax)) {
158
+                $this->taxonomy = $tax;
159
+                return get_term($tid, $tax);
160
+            }
161
+        }
162
+        return null;
163
+    }
164
+
165
+    /**
166
+     * @internal
167
+     * @param int $tid
168
+     * @return int
169
+     */
170
+    protected function get_tid( $tid ) {
171
+        global $wpdb;
172
+        if ( is_numeric($tid) ) {
173
+            return $tid;
174
+        }
175
+        if ( gettype($tid) == 'object' ) {
176
+            $tid = $tid->term_id;
177
+        }
178
+        if ( is_numeric($tid) ) {
179
+            $query = $wpdb->prepare("SELECT * FROM $wpdb->terms WHERE term_id = %d", $tid);
180
+        } else {
181
+            $query = $wpdb->prepare("SELECT * FROM $wpdb->terms WHERE slug = %s", $tid);
182
+        }
183
+        $result = $wpdb->get_row($query);
184
+        if ( isset($result->term_id) ) {
185
+            $result->ID = $result->term_id;
186
+            $result->id = $result->term_id;
187
+            return $result->ID;
188
+        }
189
+        return 0;
190
+    }
191
+
192
+    /* Public methods
193 193
 	===================== */
194 194
 
195
-	/**
196
-	 * @internal
197
-	 * @return string
198
-	 */
199
-	public function get_edit_url() {
200
-		return get_edit_term_link($this->ID, $this->taxonomy);
201
-	}
202
-
203
-	/**
204
-	 * @internal
205
-	 * @param string $field_name
206
-	 * @return string
207
-	 */
208
-	public function get_meta_field( $field_name ) {
209
-		if (!isset($this->$field_name)) {
210
-			$field_value = '';
211
-			$field_value = apply_filters('timber_term_get_meta_field', $field_value, $this->ID, $field_name, $this);
212
-			$field_value = apply_filters('timber/term/meta/field', $field_value, $this->ID, $field_name, $this);
213
-			$this->$field_name = $field_value;
214
-		}
215
-		return $this->$field_name;
216
-	}
217
-
218
-	/**
219
-	 * @internal
220
-	 * @return string
221
-	 */
222
-	public function get_path() {
223
-		$link = $this->get_link();
224
-		$rel = TimberURLHelper::get_rel_url($link, true);
225
-		$rel = apply_filters('timber_term_path', $rel, $this);
226
-		return apply_filters('timber/term/path', $rel, $this);
227
-	}
228
-
229
-	/**
230
-	 * @internal
231
-	 * @return string
232
-	 */
233
-	public function get_link() {
234
-		$link = get_term_link($this);
235
-		$link = apply_filters('timber_term_link', $link, $this);
236
-		return apply_filters('timber/term/link', $link, $this);
237
-	}
238
-
239
-	/**
240
-	 * Get Posts that have been "tagged" with the particular term
241
-	 * @internal
242
-	 * @param int $numberposts
243
-	 * @param string $post_type
244
-	 * @param string $PostClass
245
-	 * @return array|bool|null
246
-	 */
247
-	public function get_posts( $numberposts = 10, $post_type = 'any', $PostClass = '' ) {
248
-		if (!strlen($PostClass)) {
249
-			$PostClass = $this->PostClass;
250
-		}
251
-		$default_tax_query = array(array(
252
-			'field' => 'id',
253
-			'terms' => $this->ID,
254
-			'taxonomy' => $this->taxonomy,
255
-		));
256
-		if ( is_string($numberposts) && strstr($numberposts, '=') ) {
257
-			$args = $numberposts;
258
-			$new_args = array();
259
-			parse_str($args, $new_args);
260
-			$args = $new_args;
261
-			$args['tax_query'] = $default_tax_query;
262
-			if (!isset($args['post_type'])) {
263
-				$args['post_type'] = 'any';
264
-			}
265
-			if (class_exists($post_type)) {
266
-				$PostClass = $post_type;
267
-			}
268
-		} else if ( is_array($numberposts) ) {
269
-			//they sent us an array already baked
270
-			$args = $numberposts;
271
-			if ( !isset($args['tax_query']) ) {
272
-				$args['tax_query'] = $default_tax_query;
273
-			}
274
-			if ( class_exists($post_type) ) {
275
-				$PostClass = $post_type;
276
-			}
277
-			if ( !isset($args['post_type']) ) {
278
-				$args['post_type'] = 'any';
279
-			}
280
-		} else {
281
-			$args = array(
282
-				'numberposts' => $numberposts,
283
-				'tax_query' => $default_tax_query,
284
-				'post_type' => $post_type
285
-			);
286
-		}
287
-		return Timber::get_posts($args, $PostClass);
288
-	}
289
-
290
-	/**
291
-	 * @internal
292
-	 * @return array
293
-	 */
294
-	public function get_children() {
295
-		if ( !isset($this->_children) ) {
296
-			$children = get_term_children($this->ID, $this->taxonomy);
297
-			foreach ($children as &$child) {
298
-				$child = new TimberTerm($child);
299
-			}
300
-			$this->_children = $children;
301
-		}
302
-		return $this->_children;
303
-	}
304
-
305
-	/**
306
-	 *
307
-	 *
308
-	 * @param string  $key
309
-	 * @param mixed   $value
310
-	 */
311
-	function update( $key, $value ) {
312
-		$value = apply_filters( 'timber_term_set_meta', $value, $key, $this->ID, $this );
313
-		$this->$key = $value;
314
-	}
315
-
316
-	/* Alias
195
+    /**
196
+     * @internal
197
+     * @return string
198
+     */
199
+    public function get_edit_url() {
200
+        return get_edit_term_link($this->ID, $this->taxonomy);
201
+    }
202
+
203
+    /**
204
+     * @internal
205
+     * @param string $field_name
206
+     * @return string
207
+     */
208
+    public function get_meta_field( $field_name ) {
209
+        if (!isset($this->$field_name)) {
210
+            $field_value = '';
211
+            $field_value = apply_filters('timber_term_get_meta_field', $field_value, $this->ID, $field_name, $this);
212
+            $field_value = apply_filters('timber/term/meta/field', $field_value, $this->ID, $field_name, $this);
213
+            $this->$field_name = $field_value;
214
+        }
215
+        return $this->$field_name;
216
+    }
217
+
218
+    /**
219
+     * @internal
220
+     * @return string
221
+     */
222
+    public function get_path() {
223
+        $link = $this->get_link();
224
+        $rel = TimberURLHelper::get_rel_url($link, true);
225
+        $rel = apply_filters('timber_term_path', $rel, $this);
226
+        return apply_filters('timber/term/path', $rel, $this);
227
+    }
228
+
229
+    /**
230
+     * @internal
231
+     * @return string
232
+     */
233
+    public function get_link() {
234
+        $link = get_term_link($this);
235
+        $link = apply_filters('timber_term_link', $link, $this);
236
+        return apply_filters('timber/term/link', $link, $this);
237
+    }
238
+
239
+    /**
240
+     * Get Posts that have been "tagged" with the particular term
241
+     * @internal
242
+     * @param int $numberposts
243
+     * @param string $post_type
244
+     * @param string $PostClass
245
+     * @return array|bool|null
246
+     */
247
+    public function get_posts( $numberposts = 10, $post_type = 'any', $PostClass = '' ) {
248
+        if (!strlen($PostClass)) {
249
+            $PostClass = $this->PostClass;
250
+        }
251
+        $default_tax_query = array(array(
252
+            'field' => 'id',
253
+            'terms' => $this->ID,
254
+            'taxonomy' => $this->taxonomy,
255
+        ));
256
+        if ( is_string($numberposts) && strstr($numberposts, '=') ) {
257
+            $args = $numberposts;
258
+            $new_args = array();
259
+            parse_str($args, $new_args);
260
+            $args = $new_args;
261
+            $args['tax_query'] = $default_tax_query;
262
+            if (!isset($args['post_type'])) {
263
+                $args['post_type'] = 'any';
264
+            }
265
+            if (class_exists($post_type)) {
266
+                $PostClass = $post_type;
267
+            }
268
+        } else if ( is_array($numberposts) ) {
269
+            //they sent us an array already baked
270
+            $args = $numberposts;
271
+            if ( !isset($args['tax_query']) ) {
272
+                $args['tax_query'] = $default_tax_query;
273
+            }
274
+            if ( class_exists($post_type) ) {
275
+                $PostClass = $post_type;
276
+            }
277
+            if ( !isset($args['post_type']) ) {
278
+                $args['post_type'] = 'any';
279
+            }
280
+        } else {
281
+            $args = array(
282
+                'numberposts' => $numberposts,
283
+                'tax_query' => $default_tax_query,
284
+                'post_type' => $post_type
285
+            );
286
+        }
287
+        return Timber::get_posts($args, $PostClass);
288
+    }
289
+
290
+    /**
291
+     * @internal
292
+     * @return array
293
+     */
294
+    public function get_children() {
295
+        if ( !isset($this->_children) ) {
296
+            $children = get_term_children($this->ID, $this->taxonomy);
297
+            foreach ($children as &$child) {
298
+                $child = new TimberTerm($child);
299
+            }
300
+            $this->_children = $children;
301
+        }
302
+        return $this->_children;
303
+    }
304
+
305
+    /**
306
+     *
307
+     *
308
+     * @param string  $key
309
+     * @param mixed   $value
310
+     */
311
+    function update( $key, $value ) {
312
+        $value = apply_filters( 'timber_term_set_meta', $value, $key, $this->ID, $this );
313
+        $this->$key = $value;
314
+    }
315
+
316
+    /* Alias
317 317
 	====================== */
318 318
 
319
-	/**
320
-	 * @api
321
-	 * @return array
322
-	 */
323
-	public function children() {
324
-		return $this->get_children();
325
-	}
326
-
327
-	/**
328
-	 * @api
329
-	 * @return string
330
-	 */
331
-	public function description() {
332
-		$prefix = '<p>';
333
-		$suffix = '</p>';
334
-		$desc = term_description( $this->ID, $this->taxonomy );
335
-		if (substr($desc, 0, strlen($prefix)) == $prefix) {
336
-    		$desc = substr($desc, strlen($prefix));
337
-		}
338
-		$desc = preg_replace('/'. preg_quote('</p>', '/') . '$/', '', $desc);
339
-		return trim($desc);
340
-	}
341
-
342
-	/**
343
-	 * @api
344
-	 * @return string
345
-	 */
346
-	public function edit_link() {
347
-		return $this->get_edit_url();
348
-	}
349
-
350
-	/**
351
-	 * @internal
352
-	 * @deprecated 0.21.8 use TimberTerm::link() instead
353
-	 * @return string
354
-	 */
355
-	public function get_url() {
356
-		return $this->get_link();
357
-	}
358
-
359
-	/**
360
-	 * @api
361
-	 * @return string
362
-	 */
363
-	public function link() {
364
-		return $this->get_link();
365
-	}
366
-
367
-	/**
368
-	 * @api
369
-	 * @param string $field_name
370
-	 * @return string
371
-	 */
372
-	public function meta( $field_name ) {
373
-		return $this->get_meta_field($field_name);
374
-	}
375
-
376
-	/**
377
-	 * @api
378
-	 * @return string
379
-	 */
380
-	public function path() {
381
-		return $this->get_path();
382
-	}
383
-
384
-	/**
385
-	 * @api
386
-	 * @param int $numberposts_or_args
387
-	 * @param string $post_type_or_class
388
-	 * @param string $post_class
389
-	 * @example
390
-	 * ```twig
391
-	 * <h4>Recent posts in {{term.name}}</h4>
392
-	 * <ul>
393
-	 * {% for post in term.posts(3, 'post') %}
394
-	 *     <li><a href="{{post.link}}">{{post.title}}</a></li>
395
-	 * {% endfor %}
396
-	 * </ul>
397
-	 * ```
398
-	 * @return array|bool|null
399
-	 */
400
-	public function posts( $numberposts_or_args = 10, $post_type_or_class = 'any', $post_class = '' ) {
401
-		return $this->get_posts($numberposts_or_args, $post_type_or_class, $post_class);
402
-	}
403
-
404
-	/**
405
-	 * @api
406
-	 * @return string
407
-	 */
408
-	public function title() {
409
-		return $this->name;
410
-	}
411
-
412
-	/**
413
-	 * @deprecated 0.21.9 use TimberTerm::link() instead
414
-	 * @return string
415
-	 */
416
-	public function url() {
417
-		return $this->get_url();
418
-	}
419
-
420
-	/**
421
-	 * @deprecated 0.20.0 this was a dumb idea
422
-	 * @param int $i
423
-	 * @return string
424
-	 */
425
-	function get_page( $i ) {
426
-		return $this->get_path() . '/page/' . $i;
427
-	}
319
+    /**
320
+     * @api
321
+     * @return array
322
+     */
323
+    public function children() {
324
+        return $this->get_children();
325
+    }
326
+
327
+    /**
328
+     * @api
329
+     * @return string
330
+     */
331
+    public function description() {
332
+        $prefix = '<p>';
333
+        $suffix = '</p>';
334
+        $desc = term_description( $this->ID, $this->taxonomy );
335
+        if (substr($desc, 0, strlen($prefix)) == $prefix) {
336
+            $desc = substr($desc, strlen($prefix));
337
+        }
338
+        $desc = preg_replace('/'. preg_quote('</p>', '/') . '$/', '', $desc);
339
+        return trim($desc);
340
+    }
341
+
342
+    /**
343
+     * @api
344
+     * @return string
345
+     */
346
+    public function edit_link() {
347
+        return $this->get_edit_url();
348
+    }
349
+
350
+    /**
351
+     * @internal
352
+     * @deprecated 0.21.8 use TimberTerm::link() instead
353
+     * @return string
354
+     */
355
+    public function get_url() {
356
+        return $this->get_link();
357
+    }
358
+
359
+    /**
360
+     * @api
361
+     * @return string
362
+     */
363
+    public function link() {
364
+        return $this->get_link();
365
+    }
366
+
367
+    /**
368
+     * @api
369
+     * @param string $field_name
370
+     * @return string
371
+     */
372
+    public function meta( $field_name ) {
373
+        return $this->get_meta_field($field_name);
374
+    }
375
+
376
+    /**
377
+     * @api
378
+     * @return string
379
+     */
380
+    public function path() {
381
+        return $this->get_path();
382
+    }
383
+
384
+    /**
385
+     * @api
386
+     * @param int $numberposts_or_args
387
+     * @param string $post_type_or_class
388
+     * @param string $post_class
389
+     * @example
390
+     * ```twig
391
+     * <h4>Recent posts in {{term.name}}</h4>
392
+     * <ul>
393
+     * {% for post in term.posts(3, 'post') %}
394
+     *     <li><a href="{{post.link}}">{{post.title}}</a></li>
395
+     * {% endfor %}
396
+     * </ul>
397
+     * ```
398
+     * @return array|bool|null
399
+     */
400
+    public function posts( $numberposts_or_args = 10, $post_type_or_class = 'any', $post_class = '' ) {
401
+        return $this->get_posts($numberposts_or_args, $post_type_or_class, $post_class);
402
+    }
403
+
404
+    /**
405
+     * @api
406
+     * @return string
407
+     */
408
+    public function title() {
409
+        return $this->name;
410
+    }
411
+
412
+    /**
413
+     * @deprecated 0.21.9 use TimberTerm::link() instead
414
+     * @return string
415
+     */
416
+    public function url() {
417
+        return $this->get_url();
418
+    }
419
+
420
+    /**
421
+     * @deprecated 0.20.0 this was a dumb idea
422
+     * @param int $i
423
+     * @return string
424
+     */
425
+    function get_page( $i ) {
426
+        return $this->get_path() . '/page/' . $i;
427
+    }
428 428
 
429 429
 }
Please login to merge, or discard this patch.
lib/timber-user.php 1 patch
Indentation   +225 added lines, -225 removed lines patch added patch discarded remove patch
@@ -19,230 +19,230 @@
 block discarded – undo
19 19
  */
20 20
 class TimberUser extends TimberCore implements TimberCoreInterface {
21 21
 
22
-	public $object_type = 'user';
23
-	public static $representation = 'user';
24
-
25
-	public $_link;
26
-
27
-	/**
28
-	 * @api
29
-	 * @var string The description from WordPress
30
-	 */
31
-	public $description;
32
-	public $display_name;
33
-
34
-	/**
35
-	 * @api
36
-	 * @var  string The first name of the user
37
-	 */
38
-	public $first_name;
39
-
40
-	/**
41
-	 * @api
42
-	 * @var  string The last name of the user
43
-	 */
44
-	public $last_name;
45
-
46
-	/**
47
-	 * @api
48
-	 * @var int The ID from WordPress
49
-	 */
50
-	public $id;
51
-	public $user_nicename;
52
-
53
-	/**
54
-	 * @param int|bool $uid
55
-	 */
56
-	function __construct($uid = false) {
57
-		$this->init($uid);
58
-	}
59
-
60
-	/**
61
-	 * @example
62
-	 * ```twig
63
-	 * This post is by {{ post.author }}
64
-	 * ```
65
-	 * ```html
66
-	 * This post is by Jared Novack
67
-	 * ```
68
-	 *
69
-	 * @return string a fallback for TimberUser::name()
70
-	 */
71
-	function __toString() {
72
-		$name = $this->name();
73
-		if ( strlen($name) ) {
74
-			return $name;
75
-		}
76
-		if ( strlen($this->name) ) {
77
-			return $this->name;
78
-		}
79
-		return '';
80
-	}
81
-
82
-	/**
83
-	 * @internal
84
-	 * @param string $field_name
85
-	 * @return null
86
-	 */
87
-	function get_meta($field_name) {
88
-		return $this->get_meta_field($field_name);
89
-	}
90
-
91
-	/**
92
-	 * @internal
93
-	 * @param string 	$field
94
-	 * @param mixed 	$value
95
-	 */
96
-	function __set($field, $value) {
97
-		if ( $field == 'name' ) {
98
-			$this->display_name = $value;
99
-		}
100
-		$this->$field = $value;
101
-	}
102
-
103
-	/**
104
-	 * @internal
105
-	 * @param int|bool $uid The user ID to use
106
-	 */
107
-	protected function init($uid = false) {
108
-		if ( $uid === false ) {
109
-			$uid = get_current_user_id();
110
-		}
111
-		if ( is_object($uid) || is_array($uid) ) {
112
-			$data = $uid;
113
-			if ( is_array($uid) ) {
114
-				$data = (object) $uid;
115
-			}
116
-			$uid = $data->ID;
117
-		}
118
-		if ( is_numeric($uid) ) {
119
-			$data = get_userdata($uid);
120
-		} else if ( is_string($uid) ) {
121
-			$data = get_user_by('login', $uid);
122
-		}
123
-		if ( isset($data) && is_object($data) ) {
124
-			if ( isset($data->data) ) {
125
-				$this->import($data->data);
126
-			} else {
127
-				$this->import($data);
128
-			}
129
-		}
130
-		$this->id = $this->ID;
131
-		$this->name = $this->name();
132
-		$custom = $this->get_custom();
133
-		$this->import($custom);
134
-	}
135
-
136
-	/**
137
-	 * @param string $field_name
138
-	 * @return mixed
139
-	 */
140
-	function get_meta_field($field_name) {
141
-		$value = null;
142
-		$value = apply_filters('timber_user_get_meta_field_pre', $value, $this->ID, $field_name, $this);
143
-		if ( $value === null ) {
144
-			$value = get_user_meta($this->ID, $field_name, true);
145
-		}
146
-		$value = apply_filters('timber_user_get_meta_field', $value, $this->ID, $field_name, $this);
147
-		return $value;
148
-	}
149
-
150
-	/**
151
-	 * @return array|null
152
-	 */
153
-	function get_custom() {
154
-		if ( $this->ID ) {
155
-			$um = array();
156
-			$um = apply_filters('timber_user_get_meta_pre', $um, $this->ID, $this);
157
-			if ( empty($um) ) {
158
-				$um = get_user_meta($this->ID);
159
-			}
160
-			$custom = array();
161
-			foreach ($um as $key => $value) {
162
-				if ( is_array($value) && count($value) == 1 ) {
163
-					$value = $value[0];
164
-				}
165
-				$custom[$key] = maybe_unserialize($value);
166
-			}
167
-			$custom = apply_filters('timber_user_get_meta', $custom, $this->ID, $this);
168
-			return $custom;
169
-		}
170
-		return null;
171
-	}
172
-
173
-	/**
174
-	 * @api
175
-	 * @return string http://example.org/author/lincoln
176
-	 */
177
-	public function link() {
178
-		if ( !$this->_link ) {
179
-			$this->_link = untrailingslashit(get_author_posts_url($this->ID));
180
-		}
181
-		return $this->_link;
182
-	}
183
-
184
-	/**
185
-	 * @api
186
-	 * @return string the human-friendly name of the user (ex: "Buster Bluth")
187
-	 */
188
-	function name() {
189
-		return $this->display_name;
190
-	}
191
-
192
-	/**
193
-	 * @param string $field_name
194
-	 * @return mixed
195
-	 */
196
-	function meta($field_name) {
197
-		return $this->get_meta_field($field_name);
198
-	}
199
-
200
-	/**
201
-	 * @api
202
-	 * @return string ex: /author/lincoln
203
-	 */
204
-	public function path() {
205
-		return TimberURLHelper::get_rel_url($this->get_link());
206
-	}
207
-
208
-	/**
209
-	 * @api
210
-	 * @return string ex baberaham-lincoln
211
-	 */
212
-	public function slug() {
213
-		return $this->user_nicename;
214
-	}
215
-
216
-	/**
217
-	 * @deprecated 0.21.9
218
-	 * @return string The link to a user's profile page
219
-	 */
220
-	function get_link() {
221
-		return $this->link();
222
-	}
223
-
224
-	/**
225
-	 * @deprecated 0.21.8
226
-	 * @return string ex: /author/lincoln
227
-	 */
228
-	function get_path() {
229
-		return $this->path();
230
-	}
231
-
232
-	/**
233
-	 * @deprecated 0.21.8
234
-	 * @return string
235
-	 */
236
-	function get_permalink() {
237
-		return $this->get_link();
238
-	}
239
-
240
-	/**
241
-	 * @deprecated 0.21.8
242
-	 * @return string
243
-	 */
244
-	function permalink() {
245
-		return $this->get_permalink();
246
-	}
22
+    public $object_type = 'user';
23
+    public static $representation = 'user';
24
+
25
+    public $_link;
26
+
27
+    /**
28
+     * @api
29
+     * @var string The description from WordPress
30
+     */
31
+    public $description;
32
+    public $display_name;
33
+
34
+    /**
35
+     * @api
36
+     * @var  string The first name of the user
37
+     */
38
+    public $first_name;
39
+
40
+    /**
41
+     * @api
42
+     * @var  string The last name of the user
43
+     */
44
+    public $last_name;
45
+
46
+    /**
47
+     * @api
48
+     * @var int The ID from WordPress
49
+     */
50
+    public $id;
51
+    public $user_nicename;
52
+
53
+    /**
54
+     * @param int|bool $uid
55
+     */
56
+    function __construct($uid = false) {
57
+        $this->init($uid);
58
+    }
59
+
60
+    /**
61
+     * @example
62
+     * ```twig
63
+     * This post is by {{ post.author }}
64
+     * ```
65
+     * ```html
66
+     * This post is by Jared Novack
67
+     * ```
68
+     *
69
+     * @return string a fallback for TimberUser::name()
70
+     */
71
+    function __toString() {
72
+        $name = $this->name();
73
+        if ( strlen($name) ) {
74
+            return $name;
75
+        }
76
+        if ( strlen($this->name) ) {
77
+            return $this->name;
78
+        }
79
+        return '';
80
+    }
81
+
82
+    /**
83
+     * @internal
84
+     * @param string $field_name
85
+     * @return null
86
+     */
87
+    function get_meta($field_name) {
88
+        return $this->get_meta_field($field_name);
89
+    }
90
+
91
+    /**
92
+     * @internal
93
+     * @param string 	$field
94
+     * @param mixed 	$value
95
+     */
96
+    function __set($field, $value) {
97
+        if ( $field == 'name' ) {
98
+            $this->display_name = $value;
99
+        }
100
+        $this->$field = $value;
101
+    }
102
+
103
+    /**
104
+     * @internal
105
+     * @param int|bool $uid The user ID to use
106
+     */
107
+    protected function init($uid = false) {
108
+        if ( $uid === false ) {
109
+            $uid = get_current_user_id();
110
+        }
111
+        if ( is_object($uid) || is_array($uid) ) {
112
+            $data = $uid;
113
+            if ( is_array($uid) ) {
114
+                $data = (object) $uid;
115
+            }
116
+            $uid = $data->ID;
117
+        }
118
+        if ( is_numeric($uid) ) {
119
+            $data = get_userdata($uid);
120
+        } else if ( is_string($uid) ) {
121
+            $data = get_user_by('login', $uid);
122
+        }
123
+        if ( isset($data) && is_object($data) ) {
124
+            if ( isset($data->data) ) {
125
+                $this->import($data->data);
126
+            } else {
127
+                $this->import($data);
128
+            }
129
+        }
130
+        $this->id = $this->ID;
131
+        $this->name = $this->name();
132
+        $custom = $this->get_custom();
133
+        $this->import($custom);
134
+    }
135
+
136
+    /**
137
+     * @param string $field_name
138
+     * @return mixed
139
+     */
140
+    function get_meta_field($field_name) {
141
+        $value = null;
142
+        $value = apply_filters('timber_user_get_meta_field_pre', $value, $this->ID, $field_name, $this);
143
+        if ( $value === null ) {
144
+            $value = get_user_meta($this->ID, $field_name, true);
145
+        }
146
+        $value = apply_filters('timber_user_get_meta_field', $value, $this->ID, $field_name, $this);
147
+        return $value;
148
+    }
149
+
150
+    /**
151
+     * @return array|null
152
+     */
153
+    function get_custom() {
154
+        if ( $this->ID ) {
155
+            $um = array();
156
+            $um = apply_filters('timber_user_get_meta_pre', $um, $this->ID, $this);
157
+            if ( empty($um) ) {
158
+                $um = get_user_meta($this->ID);
159
+            }
160
+            $custom = array();
161
+            foreach ($um as $key => $value) {
162
+                if ( is_array($value) && count($value) == 1 ) {
163
+                    $value = $value[0];
164
+                }
165
+                $custom[$key] = maybe_unserialize($value);
166
+            }
167
+            $custom = apply_filters('timber_user_get_meta', $custom, $this->ID, $this);
168
+            return $custom;
169
+        }
170
+        return null;
171
+    }
172
+
173
+    /**
174
+     * @api
175
+     * @return string http://example.org/author/lincoln
176
+     */
177
+    public function link() {
178
+        if ( !$this->_link ) {
179
+            $this->_link = untrailingslashit(get_author_posts_url($this->ID));
180
+        }
181
+        return $this->_link;
182
+    }
183
+
184
+    /**
185
+     * @api
186
+     * @return string the human-friendly name of the user (ex: "Buster Bluth")
187
+     */
188
+    function name() {
189
+        return $this->display_name;
190
+    }
191
+
192
+    /**
193
+     * @param string $field_name
194
+     * @return mixed
195
+     */
196
+    function meta($field_name) {
197
+        return $this->get_meta_field($field_name);
198
+    }
199
+
200
+    /**
201
+     * @api
202
+     * @return string ex: /author/lincoln
203
+     */
204
+    public function path() {
205
+        return TimberURLHelper::get_rel_url($this->get_link());
206
+    }
207
+
208
+    /**
209
+     * @api
210
+     * @return string ex baberaham-lincoln
211
+     */
212
+    public function slug() {
213
+        return $this->user_nicename;
214
+    }
215
+
216
+    /**
217
+     * @deprecated 0.21.9
218
+     * @return string The link to a user's profile page
219
+     */
220
+    function get_link() {
221
+        return $this->link();
222
+    }
223
+
224
+    /**
225
+     * @deprecated 0.21.8
226
+     * @return string ex: /author/lincoln
227
+     */
228
+    function get_path() {
229
+        return $this->path();
230
+    }
231
+
232
+    /**
233
+     * @deprecated 0.21.8
234
+     * @return string
235
+     */
236
+    function get_permalink() {
237
+        return $this->get_link();
238
+    }
239
+
240
+    /**
241
+     * @deprecated 0.21.8
242
+     * @return string
243
+     */
244
+    function permalink() {
245
+        return $this->get_permalink();
246
+    }
247 247
 
248 248
 }
Please login to merge, or discard this patch.