Timber - Version 0.19.1

Version Description

Download this release

Release Info

Developer jarednova
Plugin Icon 128x128 Timber
Version 0.19.1
Comparing to
See all releases

Code changes from version 0.19.0 to 0.19.1

Files changed (40) hide show
  1. functions/cache/KeyGenerator.php +15 -9
  2. functions/cache/TimberKeyGeneratorInterface.php +1 -1
  3. functions/cache/WPObjectCacheAdapter.php +6 -6
  4. functions/cache/loader.php +9 -9
  5. functions/functions-twig.php +189 -168
  6. functions/integrations/acf-timber.php +55 -54
  7. functions/integrations/wpcli-timber.php +56 -68
  8. functions/timber-admin.php +10 -12
  9. functions/timber-archives.php +228 -213
  10. functions/timber-comment.php +83 -70
  11. functions/timber-core.php +44 -38
  12. functions/timber-function-wrapper.php +21 -19
  13. functions/timber-helper.php +442 -421
  14. functions/timber-image-helper.php +477 -381
  15. functions/timber-image.php +169 -158
  16. functions/timber-loader.php +204 -173
  17. functions/timber-menu.php +54 -42
  18. functions/timber-page.php +2 -1
  19. functions/timber-post.php +649 -579
  20. functions/timber-site.php +31 -14
  21. functions/timber-term-getter.php +37 -35
  22. functions/timber-term.php +194 -190
  23. functions/timber-theme.php +51 -42
  24. functions/timber-url-helper.php +209 -208
  25. functions/timber-user.php +26 -20
  26. readme.txt +10 -1
  27. timber-starter-theme/author.php +5 -5
  28. timber-starter-theme/footer.php +13 -0
  29. timber-starter-theme/functions.php +41 -23
  30. timber-starter-theme/header.php +7 -0
  31. timber-starter-theme/index.php +1 -0
  32. timber-starter-theme/views/page-plugin.twig +7 -0
  33. timber.php +47 -40
  34. vendor/asm89/twig-cache-extension/.gitignore +4 -0
  35. vendor/autoload.php +1 -1
  36. vendor/composer/autoload_real.php +4 -4
  37. vendor/composer/installed.json +6 -6
  38. vendor/symfony/yaml/Symfony/Component/Yaml/Parser.php +1 -1
  39. vendor/symfony/yaml/Symfony/Component/Yaml/Tests/ParserTest.php +2 -8
  40. vendor/symfony/yaml/Symfony/Component/Yaml/Unescaper.php +25 -30
functions/cache/KeyGenerator.php CHANGED
@@ -4,19 +4,25 @@ namespace Timber\Cache;
4
 
5
  use Asm89\Twig\CacheExtension\CacheStrategy\KeyGeneratorInterface;
6
 
7
- class KeyGenerator implements KeyGeneratorInterface
8
- {
9
-
10
- public function generateKey( $value ) {
11
- if ( is_a( $value, 'TimberKeyGeneratorInterface' ) )
 
 
 
12
  return $value->_get_cache_key();
 
13
 
14
- if ( is_array( $value ) && isset( $value['_cache_key'] ) )
15
  return $value['_cache_key'];
 
16
 
17
- $key = md5( json_encode( $value ) );
18
- if ( is_object( $value ) )
19
- $key = get_class( $key ) . '|' . $key;
 
20
 
21
  return $key;
22
  }
4
 
5
  use Asm89\Twig\CacheExtension\CacheStrategy\KeyGeneratorInterface;
6
 
7
+ class KeyGenerator implements KeyGeneratorInterface {
8
+
9
+ /**
10
+ * @param mixed $value
11
+ * @return string
12
+ */
13
+ public function generateKey($value) {
14
+ if (is_a($value, 'TimberKeyGeneratorInterface')) {
15
  return $value->_get_cache_key();
16
+ }
17
 
18
+ if (is_array($value) && isset($value['_cache_key'])) {
19
  return $value['_cache_key'];
20
+ }
21
 
22
+ $key = md5(json_encode($value));
23
+ if (is_object($value)) {
24
+ $key = get_class($value) . '|' . $key;
25
+ }
26
 
27
  return $key;
28
  }
functions/cache/TimberKeyGeneratorInterface.php CHANGED
@@ -5,4 +5,4 @@ namespace Timber\Cache;
5
  interface TimberKeyGeneratorInterface
6
  {
7
  public function _get_cache_key();
8
- }
5
  interface TimberKeyGeneratorInterface
6
  {
7
  public function _get_cache_key();
8
+ }
functions/cache/WPObjectCacheAdapter.php CHANGED
@@ -13,17 +13,17 @@ class WPObjectCacheAdapter implements CacheProviderInterface
13
  */
14
  private $timberloader;
15
 
16
- public function __construct( TimberLoader $timberloader, $cache_group = 'timber' ) {
17
- $this->cache_group = $cache_group;
18
  $this->timberloader = $timberloader;
19
  }
20
 
21
- public function fetch( $key ) {
22
- return $this->timberloader->get_cache( $key, $this->cache_group, TimberLoader::CACHE_USE_DEFAULT );
23
  }
24
 
25
- public function save( $key, $value, $expire = 0 ) {
26
- return $this->timberloader->set_cache( $key, $value, $this->cache_group, $expire, TimberLoader::CACHE_USE_DEFAULT );
27
  }
28
 
29
  }
13
  */
14
  private $timberloader;
15
 
16
+ public function __construct(TimberLoader $timberloader, $cache_group = 'timber') {
17
+ $this->cache_group = $cache_group;
18
  $this->timberloader = $timberloader;
19
  }
20
 
21
+ public function fetch($key) {
22
+ return $this->timberloader->get_cache($key, $this->cache_group, TimberLoader::CACHE_USE_DEFAULT);
23
  }
24
 
25
+ public function save($key, $value, $expire = 0) {
26
+ return $this->timberloader->set_cache($key, $value, $this->cache_group, $expire, TimberLoader::CACHE_USE_DEFAULT);
27
  }
28
 
29
  }
functions/cache/loader.php CHANGED
@@ -1,9 +1,9 @@
1
  <?php
 
2
  class TimberCache_Loader
3
  {
4
 
5
- public static function register($prepend = false)
6
- {
7
  if (version_compare(phpversion(), '5.3.0', '>=')) {
8
  spl_autoload_register(array(new self, 'autoload'), true, $prepend);
9
  } else {
@@ -11,14 +11,14 @@ class TimberCache_Loader
11
  }
12
  }
13
 
14
- public static function autoload($class)
15
- {
16
- if ( 0 === strpos($class, 'Timber\Cache') ) {
17
- $classes = explode( '\\', $class );
18
- array_splice( $classes, 0, 2 );
19
- $path = implode( $classes, '/' );
20
- if ( is_file($file = dirname(__FILE__) . '/' . $path . '.php'))
21
  require $file;
 
22
  }
23
  }
24
  }
1
  <?php
2
+
3
  class TimberCache_Loader
4
  {
5
 
6
+ public static function register($prepend = false) {
 
7
  if (version_compare(phpversion(), '5.3.0', '>=')) {
8
  spl_autoload_register(array(new self, 'autoload'), true, $prepend);
9
  } else {
11
  }
12
  }
13
 
14
+ public static function autoload($class) {
15
+ if (0 === strpos($class, 'Timber\Cache')) {
16
+ $classes = explode('\\', $class);
17
+ array_splice($classes, 0, 2);
18
+ $path = implode($classes, '/');
19
+ if (is_file($file = dirname(__FILE__) . '/' . $path . '.php')) {
 
20
  require $file;
21
+ }
22
  }
23
  }
24
  }
functions/functions-twig.php CHANGED
@@ -1,61 +1,65 @@
1
  <?php
2
 
3
- class TimberTwig {
4
-
5
- function __construct() {
6
- add_action('twig_apply_filters', array(&$this, 'add_twig_filters'));
7
- }
8
-
9
- /**
10
- * @param Twig_Environment $twig
11
- * @return Twig_Environment
12
- */
13
- function add_twig_filters($twig) {
14
- /* image filters */
15
- $twig->addFilter('resize', new Twig_Filter_Function(array('TimberImageHelper', 'resize')));
16
- $twig->addFilter('letterbox', new Twig_Filter_Function(array('TimberImageHelper', 'letterbox')));
17
- $twig->addFilter('tojpg', new Twig_Filter_Function(array('TimberImageHelper', 'img_to_jpg')));
18
- $twig->addFilter('get_src_from_attachment_id', new Twig_Filter_Function('twig_get_src_from_attachment_id'));
19
-
20
- /* debugging filters */
21
- $twig->addFilter('docs', new Twig_Filter_function('twig_object_docs'));
22
- $twig->addFilter('get_class', new Twig_Filter_Function('twig_get_class'));
23
- $twig->addFilter('get_type', new Twig_Filter_Function('twig_get_type'));
24
- $twig->addFilter('print_r', new Twig_Filter_Function('twig_print_r'));
25
- $twig->addFilter('print_a', new Twig_Filter_Function('twig_print_a'));
26
-
27
- /* other filters */
28
- $twig->addFilter('stripshortcodes', new Twig_Filter_Function('strip_shortcodes'));
29
- $twig->addFilter('array', new Twig_Filter_Function(array($this, 'to_array')));
30
- $twig->addFilter('excerpt', new Twig_Filter_Function('twig_make_excerpt'));
31
- $twig->addFilter('function', new Twig_Filter_Function(array($this, 'exec_function')));
32
- $twig->addFilter('path', new Twig_Filter_Function('twig_get_path'));
33
- $twig->addFilter('pretags', new Twig_Filter_Function(array($this, 'twig_pretags')));
34
- $twig->addFilter('sanitize', new Twig_Filter_Function('sanitize_title'));
35
- $twig->addFilter('shortcodes', new Twig_Filter_Function('twig_shortcodes'));
36
- $twig->addFilter('time_ago', new Twig_Filter_Function('twig_time_ago'));
37
- $twig->addFilter('twitterify', new Twig_Filter_Function(array('TimberHelper', 'twitterify')));
38
- $twig->addFilter('twitterfy', new Twig_Filter_Function(array('TimberHelper', 'twitterify')));
39
- $twig->addFilter('wp_body_class', new Twig_Filter_Function('twig_body_class'));
40
- $twig->addFilter('wpautop', new Twig_Filter_Function('wpautop'));
41
- $twig->addFilter('relative', new Twig_Filter_Function(function($link){
42
- return TimberURLHelper::get_rel_url($link, true);
43
- }));
 
 
 
 
44
  $twig->addFilter('date', new Twig_Filter_Function('twig_intl_date'));
45
 
46
- $twig->addFilter('truncate', new Twig_Filter_Function(function($text, $len){
47
- return TimberHelper::trim_words($text, $len);
48
- }));
49
 
50
  /* actions and filters */
51
- $twig->addFunction( new Twig_SimpleFunction('action', function($context){
52
- $args = func_get_args();
53
- array_shift($args);
54
- $args[] = $context;
55
- call_user_func_array('do_action', $args);
56
  }, array('needs_context' => true)));
57
 
58
- $twig->addFilter( new Twig_SimpleFilter('apply_filters', function(){
59
  $args = func_get_args();
60
  $tag = current(array_splice($args, 1, 1));
61
 
@@ -65,96 +69,114 @@ class TimberTwig {
65
  $twig->addFunction(new Twig_SimpleFunction('fn', array(&$this, 'exec_function')));
66
 
67
  /* TimberObjects */
68
- $twig->addFunction(new Twig_SimpleFunction('TimberPost', function($pid, $PostClass = 'TimberPost'){
69
- if (is_array($pid) && !TimberHelper::is_array_assoc($pid)){
70
- foreach($pid as &$p){
71
- $p = new $PostClass($p);
72
- }
73
- return $pid;
74
- }
75
- return new $PostClass($pid);
76
  }));
77
- $twig->addFunction(new Twig_SimpleFunction('TimberImage', function($pid, $ImageClass = 'TimberImage'){
78
- if (is_array($pid) && !TimberHelper::is_array_assoc($pid)){
79
- foreach($pid as &$p){
80
- $p = new $ImageClass($p);
81
- }
82
- return $pid;
83
- }
84
- return new $ImageClass($pid);
85
  }));
86
- $twig->addFunction(new Twig_SimpleFunction('TimberTerm', function($pid, $TermClass = 'TimberTerm'){
87
- if (is_array($pid) && !TimberHelper::is_array_assoc($pid)){
88
- foreach($pid as &$p){
89
- $p = new $TermClass($p);
90
- }
91
- return $pid;
92
- }
93
- return new $TermClass($pid);
94
  }));
95
 
96
  /* bloginfo and translate */
97
- $twig->addFunction('bloginfo', new Twig_SimpleFunction('bloginfo', function($show = '', $filter = 'raw'){
98
- return get_bloginfo($show, $filter);
99
- }));
100
- $twig->addFunction('__', new Twig_SimpleFunction('__', function($text, $domain = 'default'){
101
- return __($text, $domain);
102
- }));
103
 
104
- $twig = apply_filters('get_twig', $twig);
105
 
106
- return $twig;
107
- }
108
 
109
  /**
110
  * @param mixed $arr
111
  * @return array
112
  */
113
- function to_array($arr){
114
- if (is_array($arr)){
115
- return $arr;
116
- }
117
- $arr = array($arr);
118
- return $arr;
119
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
 
121
  /**
122
  * @param string $function_name
123
  * @return mixed
124
  */
125
- function exec_function($function_name){
126
- $args = func_get_args();
127
- array_shift($args);
128
- return call_user_func_array(trim($function_name), ($args));
129
- }
130
 
131
  /**
132
  * @param string $content
133
  * @return string
134
  */
135
- function twig_pretags( $content ) {
136
- return preg_replace_callback( '|<pre.*>(.*)</pre|isU' , array(&$this, 'convert_pre_entities'), $content );
137
- }
138
 
139
  /**
140
  * @param array $matches
141
  * @return string
142
  */
143
- function convert_pre_entities( $matches ) {
144
- return str_replace( $matches[1], htmlentities( $matches[1] ), $matches[0] );
145
- }
146
 
147
  /**
148
  * @param array $locs
149
  * @return array
150
  */
151
  function add_dir_name_to_locations($locs) {
152
- $locs = array_filter($locs);
153
- foreach ($locs as &$loc) {
154
- $loc = trailingslashit($loc) . trailingslashit(self::$dir_name);
155
- }
156
- return $locs;
157
- }
158
 
159
  /**
160
  * @param string $file
@@ -162,17 +184,17 @@ class TimberTwig {
162
  * @return bool
163
  */
164
  function template_exists($file, $dirs) {
165
- if (is_string($dirs)) {
166
- $dirs = array($dirs);
167
- }
168
- foreach ($dirs as $dir) {
169
- $look_for = trailingslashit($dir) . trailingslashit(self::$dir_name) . $file;
170
- if (file_exists($look_for)) {
171
- return true;
172
- }
173
- }
174
- return false;
175
- }
176
 
177
  }
178
 
@@ -181,8 +203,8 @@ class TimberTwig {
181
  * @return string
182
  */
183
  function twig_shortcodes($text) {
184
- return do_shortcode($text);
185
- //apply_filters('the_content', ($text));
186
  }
187
 
188
  /**
@@ -190,7 +212,7 @@ function twig_shortcodes($text) {
190
  * @return string
191
  */
192
  function twig_get_class($this) {
193
- return get_class($this);
194
  }
195
 
196
  /**
@@ -198,7 +220,7 @@ function twig_get_class($this) {
198
  * @return string
199
  */
200
  function twig_get_type($this) {
201
- return gettype($this);
202
  }
203
 
204
 
@@ -209,16 +231,16 @@ function twig_get_type($this) {
209
  * @param string $format_future
210
  * @return string
211
  */
212
- function twig_time_ago($from, $to = null, $format_past='%s ago', $format_future='%s from now') {
213
- $to = (($to === null) ? (time()) : ($to));
214
- $to = ((is_int($to)) ? ($to) : (strtotime($to)));
215
- $from = ((is_int($from)) ? ($from) : (strtotime($from)));
216
-
217
- if ($from < $to) {
218
- return sprintf($format_past, human_time_diff($from, $to));
219
- } else {
220
- return sprintf($format_future, human_time_diff($to, $from));
221
- }
222
  }
223
 
224
  /**
@@ -226,14 +248,14 @@ function twig_time_ago($from, $to = null, $format_past='%s ago', $format_future=
226
  * @return string
227
  */
228
  function twig_body_class($body_classes) {
229
- ob_start();
230
- if (is_array($body_classes)) {
231
- $body_classes = explode(' ', $body_classes);
232
- }
233
- body_class($body_classes);
234
- $return = ob_get_contents();
235
- ob_end_clean();
236
- return $return;
237
  }
238
 
239
  /**
@@ -254,11 +276,11 @@ function twig_intl_date($date, $format = null) {
254
  * @return string
255
  */
256
  function render_twig_string($string, $data = array()) {
257
- $timber_loader = new TimberLoader();
258
- $timber_loader->get_twig();
259
- $loader = new Twig_Loader_String();
260
- $twig = new Twig_Environment($loader);
261
- return $twig->render($string, $data);
262
  }
263
 
264
  /**
@@ -266,10 +288,10 @@ function render_twig_string($string, $data = array()) {
266
  * @return string
267
  */
268
  function get_calling_script_dir($backtrace) {
269
- $caller = $backtrace[0]['file'];
270
- $pathinfo = pathinfo($caller);
271
- $dir = $pathinfo['dirname'];
272
- return $dir . '/';
273
  }
274
 
275
  //deprecated
@@ -279,7 +301,7 @@ function get_calling_script_dir($backtrace) {
279
  * @return string
280
  */
281
  function twig_get_src_from_attachment_id($aid) {
282
- return TimberImageHelper::get_image_path($aid);
283
  }
284
 
285
  /**
@@ -287,8 +309,8 @@ function twig_get_src_from_attachment_id($aid) {
287
  * @return mixed
288
  */
289
  function twig_get_path($url) {
290
- $url = parse_url($url);
291
- return $url['path'];
292
  }
293
 
294
  /**
@@ -296,8 +318,8 @@ function twig_get_path($url) {
296
  * @param int $length
297
  * @return string
298
  */
299
- function twig_make_excerpt($text, $length = 55){
300
- return wp_trim_words($text, $length);
301
  }
302
 
303
  /**
@@ -305,9 +327,7 @@ function twig_make_excerpt($text, $length = 55){
305
  * @return mixed
306
  */
307
  function twig_print_r($arr) {
308
- //$rets = twig_object_docs($obj, false);
309
- return print_r($arr, true);
310
- return $rets;
311
  }
312
 
313
  /**
@@ -315,7 +335,7 @@ function twig_print_r($arr) {
315
  * @return string
316
  */
317
  function twig_print_a($arr) {
318
- return '<pre>' . twig_object_docs($arr, true) . '</pre>';
319
  }
320
 
321
  /**
@@ -324,16 +344,17 @@ function twig_print_a($arr) {
324
  * @return string
325
  */
326
  function twig_object_docs($obj, $methods = true) {
327
- $class = get_class($obj);
328
- $properties = (array) $obj;
329
- if ($methods){
330
- $methods = $obj->get_method_values();
331
- }
332
- $rets = array_merge($properties, $methods);
333
- ksort($rets);
334
- $str = print_r($rets, true);
335
- $str = str_replace('Array', $class . ' Object', $str);
336
- return $str;
 
337
  }
338
 
339
  new TimberTwig();
1
  <?php
2
 
3
+ class TimberTwig
4
+ {
5
+
6
+ public static $dir_name;
7
+
8
+ function __construct() {
9
+ add_action('twig_apply_filters', array($this, 'add_twig_filters'));
10
+ }
11
+
12
+ /**
13
+ * @param Twig_Environment $twig
14
+ * @return Twig_Environment
15
+ */
16
+ function add_twig_filters($twig) {
17
+ /* image filters */
18
+ $twig->addFilter('resize', new Twig_Filter_Function(array('TimberImageHelper', 'resize')));
19
+ $twig->addFilter('letterbox', new Twig_Filter_Function(array('TimberImageHelper', 'letterbox')));
20
+ $twig->addFilter('tojpg', new Twig_Filter_Function(array('TimberImageHelper', 'img_to_jpg')));
21
+ $twig->addFilter('get_src_from_attachment_id', new Twig_Filter_Function('twig_get_src_from_attachment_id'));
22
+
23
+ /* debugging filters */
24
+ $twig->addFilter('docs', new Twig_Filter_function('twig_object_docs'));
25
+ $twig->addFilter('get_class', new Twig_Filter_Function('twig_get_class'));
26
+ $twig->addFilter('get_type', new Twig_Filter_Function('twig_get_type'));
27
+ $twig->addFilter('print_r', new Twig_Filter_Function('twig_print_r'));
28
+ $twig->addFilter('print_a', new Twig_Filter_Function('twig_print_a'));
29
+
30
+ /* other filters */
31
+ $twig->addFilter('stripshortcodes', new Twig_Filter_Function('strip_shortcodes'));
32
+ $twig->addFilter('array', new Twig_Filter_Function(array($this, 'to_array')));
33
+ $twig->addFilter('string', new Twig_Filter_Function(array($this, 'to_string')));
34
+ $twig->addFilter('excerpt', new Twig_Filter_Function('twig_make_excerpt'));
35
+ $twig->addFilter('function', new Twig_Filter_Function(array($this, 'exec_function')));
36
+ $twig->addFilter('path', new Twig_Filter_Function('twig_get_path'));
37
+ $twig->addFilter('pretags', new Twig_Filter_Function(array($this, 'twig_pretags')));
38
+ $twig->addFilter('sanitize', new Twig_Filter_Function('sanitize_title'));
39
+ $twig->addFilter('shortcodes', new Twig_Filter_Function('twig_shortcodes'));
40
+ $twig->addFilter('time_ago', new Twig_Filter_Function('twig_time_ago'));
41
+ $twig->addFilter('twitterify', new Twig_Filter_Function(array('TimberHelper', 'twitterify')));
42
+ $twig->addFilter('twitterfy', new Twig_Filter_Function(array('TimberHelper', 'twitterify')));
43
+ $twig->addFilter('wp_body_class', new Twig_Filter_Function('twig_body_class'));
44
+ $twig->addFilter('wpautop', new Twig_Filter_Function('wpautop'));
45
+ $twig->addFilter('relative', new Twig_Filter_Function(function ($link) {
46
+ return TimberURLHelper::get_rel_url($link, true);
47
+ }));
48
  $twig->addFilter('date', new Twig_Filter_Function('twig_intl_date'));
49
 
50
+ $twig->addFilter('truncate', new Twig_Filter_Function(function ($text, $len) {
51
+ return TimberHelper::trim_words($text, $len);
52
+ }));
53
 
54
  /* actions and filters */
55
+ $twig->addFunction(new Twig_SimpleFunction('action', function ($context) {
56
+ $args = func_get_args();
57
+ array_shift($args);
58
+ $args[] = $context;
59
+ call_user_func_array('do_action', $args);
60
  }, array('needs_context' => true)));
61
 
62
+ $twig->addFilter(new Twig_SimpleFilter('apply_filters', function () {
63
  $args = func_get_args();
64
  $tag = current(array_splice($args, 1, 1));
65
 
69
  $twig->addFunction(new Twig_SimpleFunction('fn', array(&$this, 'exec_function')));
70
 
71
  /* TimberObjects */
72
+ $twig->addFunction(new Twig_SimpleFunction('TimberPost', function ($pid, $PostClass = 'TimberPost') {
73
+ if (is_array($pid) && !TimberHelper::is_array_assoc($pid)) {
74
+ foreach ($pid as &$p) {
75
+ $p = new $PostClass($p);
76
+ }
77
+ return $pid;
78
+ }
79
+ return new $PostClass($pid);
80
  }));
81
+ $twig->addFunction(new Twig_SimpleFunction('TimberImage', function ($pid, $ImageClass = 'TimberImage') {
82
+ if (is_array($pid) && !TimberHelper::is_array_assoc($pid)) {
83
+ foreach ($pid as &$p) {
84
+ $p = new $ImageClass($p);
85
+ }
86
+ return $pid;
87
+ }
88
+ return new $ImageClass($pid);
89
  }));
90
+ $twig->addFunction(new Twig_SimpleFunction('TimberTerm', function ($pid, $TermClass = 'TimberTerm') {
91
+ if (is_array($pid) && !TimberHelper::is_array_assoc($pid)) {
92
+ foreach ($pid as &$p) {
93
+ $p = new $TermClass($p);
94
+ }
95
+ return $pid;
96
+ }
97
+ return new $TermClass($pid);
98
  }));
99
 
100
  /* bloginfo and translate */
101
+ $twig->addFunction('bloginfo', new Twig_SimpleFunction('bloginfo', function ($show = '', $filter = 'raw') {
102
+ return get_bloginfo($show, $filter);
103
+ }));
104
+ $twig->addFunction('__', new Twig_SimpleFunction('__', function ($text, $domain = 'default') {
105
+ return __($text, $domain);
106
+ }));
107
 
108
+ $twig = apply_filters('get_twig', $twig);
109
 
110
+ return $twig;
111
+ }
112
 
113
  /**
114
  * @param mixed $arr
115
  * @return array
116
  */
117
+ function to_array($arr) {
118
+ if (is_array($arr)) {
119
+ return $arr;
120
+ }
121
+ $arr = array($arr);
122
+ return $arr;
123
+ }
124
+
125
+ /**
126
+ * @param mixed $arr
127
+ * @param string $glue
128
+ * @return string
129
+ */
130
+ function to_string($arr, $glue = ' ') {
131
+ if (is_string($arr)) {
132
+ return $arr;
133
+ }
134
+ if (is_array($arr) && count($arr) == 1) {
135
+ return $arr[0];
136
+ }
137
+ if (is_array($arr)) {
138
+ return implode($glue, $arr);
139
+ }
140
+ return null;
141
+ }
142
 
143
  /**
144
  * @param string $function_name
145
  * @return mixed
146
  */
147
+ function exec_function($function_name) {
148
+ $args = func_get_args();
149
+ array_shift($args);
150
+ return call_user_func_array(trim($function_name), ($args));
151
+ }
152
 
153
  /**
154
  * @param string $content
155
  * @return string
156
  */
157
+ function twig_pretags($content) {
158
+ return preg_replace_callback('|<pre.*>(.*)</pre|isU', array(&$this, 'convert_pre_entities'), $content);
159
+ }
160
 
161
  /**
162
  * @param array $matches
163
  * @return string
164
  */
165
+ function convert_pre_entities($matches) {
166
+ return str_replace($matches[1], htmlentities($matches[1]), $matches[0]);
167
+ }
168
 
169
  /**
170
  * @param array $locs
171
  * @return array
172
  */
173
  function add_dir_name_to_locations($locs) {
174
+ $locs = array_filter($locs);
175
+ foreach ($locs as &$loc) {
176
+ $loc = trailingslashit($loc) . trailingslashit(self::$dir_name);
177
+ }
178
+ return $locs;
179
+ }
180
 
181
  /**
182
  * @param string $file
184
  * @return bool
185
  */
186
  function template_exists($file, $dirs) {
187
+ if (is_string($dirs)) {
188
+ $dirs = array($dirs);
189
+ }
190
+ foreach ($dirs as $dir) {
191
+ $look_for = trailingslashit($dir) . trailingslashit(self::$dir_name) . $file;
192
+ if (file_exists($look_for)) {
193
+ return true;
194
+ }
195
+ }
196
+ return false;
197
+ }
198
 
199
  }
200
 
203
  * @return string
204
  */
205
  function twig_shortcodes($text) {
206
+ return do_shortcode($text);
207
+ //apply_filters('the_content', ($text));
208
  }
209
 
210
  /**
212
  * @return string
213
  */
214
  function twig_get_class($this) {
215
+ return get_class($this);
216
  }
217
 
218
  /**
220
  * @return string
221
  */
222
  function twig_get_type($this) {
223
+ return gettype($this);
224
  }
225
 
226
 
231
  * @param string $format_future
232
  * @return string
233
  */
234
+ function twig_time_ago($from, $to = null, $format_past = '%s ago', $format_future = '%s from now') {
235
+ $to = $to === null ? time() : $to;
236
+ $to = is_int($to) ? $to : strtotime($to);
237
+ $from = is_int($from) ? $from : strtotime($from);
238
+
239
+ if ($from < $to) {
240
+ return sprintf($format_past, human_time_diff($from, $to));
241
+ } else {
242
+ return sprintf($format_future, human_time_diff($to, $from));
243
+ }
244
  }
245
 
246
  /**
248
  * @return string
249
  */
250
  function twig_body_class($body_classes) {
251
+ ob_start();
252
+ if (is_array($body_classes)) {
253
+ $body_classes = explode(' ', $body_classes);
254
+ }
255
+ body_class($body_classes);
256
+ $return = ob_get_contents();
257
+ ob_end_clean();
258
+ return $return;
259
  }
260
 
261
  /**
276
  * @return string
277
  */
278
  function render_twig_string($string, $data = array()) {
279
+ $timber_loader = new TimberLoader();
280
+ $timber_loader->get_twig();
281
+ $loader = new Twig_Loader_String();
282
+ $twig = new Twig_Environment($loader);
283
+ return $twig->render($string, $data);
284
  }
285
 
286
  /**
288
  * @return string
289
  */
290
  function get_calling_script_dir($backtrace) {
291
+ $caller = $backtrace[0]['file'];
292
+ $pathinfo = pathinfo($caller);
293
+ $dir = $pathinfo['dirname'];
294
+ return $dir . '/';
295
  }
296
 
297
  //deprecated
301
  * @return string
302
  */
303
  function twig_get_src_from_attachment_id($aid) {
304
+ return TimberImageHelper::get_image_path($aid);
305
  }
306
 
307
  /**
309
  * @return mixed
310
  */
311
  function twig_get_path($url) {
312
+ $url = parse_url($url);
313
+ return $url['path'];
314
  }
315
 
316
  /**
318
  * @param int $length
319
  * @return string
320
  */
321
+ function twig_make_excerpt($text, $length = 55) {
322
+ return wp_trim_words($text, $length);
323
  }
324
 
325
  /**
327
  * @return mixed
328
  */
329
  function twig_print_r($arr) {
330
+ return print_r($arr, true);
 
 
331
  }
332
 
333
  /**
335
  * @return string
336
  */
337
  function twig_print_a($arr) {
338
+ return '<pre>' . twig_object_docs($arr, true) . '</pre>';
339
  }
340
 
341
  /**
344
  * @return string
345
  */
346
  function twig_object_docs($obj, $methods = true) {
347
+ $class = get_class($obj);
348
+ $properties = (array)$obj;
349
+ if ($methods) {
350
+ /** @var array $methods */
351
+ $methods = $obj->get_method_values();
352
+ }
353
+ $rets = array_merge($properties, $methods);
354
+ ksort($rets);
355
+ $str = print_r($rets, true);
356
+ $str = str_replace('Array', $class . ' Object', $str);
357
+ return $str;
358
  }
359
 
360
  new TimberTwig();
functions/integrations/acf-timber.php CHANGED
@@ -1,55 +1,56 @@
1
  <?php
2
- class ACFTimber {
3
-
4
- function __construct(){
5
- add_filter('timber_post_get_meta', array($this, 'post_get_meta'), 10, 2);
6
- add_filter('timber_post_get_meta_field', array($this, 'post_get_meta_field'), 10, 3);
7
- add_filter('timber_term_get_meta', array($this, 'term_get_meta'), 10, 3);
8
- add_filter('timber_term_get_meta_field', array($this, 'term_get_meta_field'), 10, 3);
9
- add_filter('timber_user_get_meta_field_pre', array($this, 'user_get_meta_field'), 10, 3);
10
- }
11
-
12
- function post_get_meta($customs, $post_id){
13
- return $customs;
14
- }
15
-
16
- function post_get_meta_field($value, $post_id, $field_name){
17
- return get_field($field_name, $post_id);
18
- }
19
-
20
- function term_get_meta_field($value, $field_name, $term){
21
- $searcher = $term->taxonomy . "_" . $term->ID . "_" .$field_name;
22
- $field = get_field($searcher, $term->ID);
23
- return $field;
24
- }
25
-
26
- function term_get_meta($fields, $term_id, $term){
27
- $searcher = $term->taxonomy . "_" . $term->ID; // save to a specific category
28
- $fds = get_fields($searcher);
29
- if (is_array($fds)) {
30
- foreach ($fds as $key => $value) {
31
- $key = preg_replace('/_/', '', $key, 1);
32
- $key = str_replace($searcher, '', $key);
33
- $key = preg_replace('/_/', '', $key, 1);
34
- $field = get_field($key, $searcher);
35
- $fields[$key] = $field;
36
- }
37
- $fields = array_merge($fields, $fds);
38
- }
39
- return $fields;
40
- }
41
-
42
- function user_get_meta($fields, $user_id){
43
- return $fields;
44
- }
45
-
46
- function user_get_meta_field($value, $field, $uid){
47
- return get_field($field, 'user_'.$uid);
48
- }
49
- }
50
- add_action( 'init', function(){
51
- if (class_exists('ACF')){
52
- new ACFTimber();
53
- }
54
- });
55
-
 
1
  <?php
2
+
3
+ class ACFTimber
4
+ {
5
+
6
+ function __construct() {
7
+ add_filter('timber_post_get_meta', array($this, 'post_get_meta'), 10, 2);
8
+ add_filter('timber_post_get_meta_field', array($this, 'post_get_meta_field'), 10, 3);
9
+ add_filter('timber_term_get_meta', array($this, 'term_get_meta'), 10, 3);
10
+ add_filter('timber_term_get_meta_field', array($this, 'term_get_meta_field'), 10, 3);
11
+ add_filter('timber_user_get_meta_field_pre', array($this, 'user_get_meta_field'), 10, 3);
12
+ }
13
+
14
+ function post_get_meta($customs, $post_id) {
15
+ return $customs;
16
+ }
17
+
18
+ function post_get_meta_field($value, $post_id, $field_name) {
19
+ return get_field($field_name, $post_id);
20
+ }
21
+
22
+ function term_get_meta_field($value, $field_name, $term) {
23
+ $searcher = $term->taxonomy . "_" . $term->ID . "_" . $field_name;
24
+ return get_field($searcher, $term->ID);
25
+ }
26
+
27
+ function term_get_meta($fields, $term_id, $term) {
28
+ $searcher = $term->taxonomy . "_" . $term->ID; // save to a specific category
29
+ $fds = get_fields($searcher);
30
+ if (is_array($fds)) {
31
+ foreach ($fds as $key => $value) {
32
+ $key = preg_replace('/_/', '', $key, 1);
33
+ $key = str_replace($searcher, '', $key);
34
+ $key = preg_replace('/_/', '', $key, 1);
35
+ $field = get_field($key, $searcher);
36
+ $fields[$key] = $field;
37
+ }
38
+ $fields = array_merge($fields, $fds);
39
+ }
40
+ return $fields;
41
+ }
42
+
43
+ function user_get_meta($fields, $user_id) {
44
+ return $fields;
45
+ }
46
+
47
+ function user_get_meta_field($value, $field, $uid) {
48
+ return get_field($field, 'user_' . $uid);
49
+ }
50
+ }
51
+
52
+ add_action('init', function () {
53
+ if (class_exists('ACF')) {
54
+ new ACFTimber();
55
+ }
56
+ });
functions/integrations/wpcli-timber.php CHANGED
@@ -1,76 +1,64 @@
1
  <?php
 
 
 
2
 
3
- class Timber_Command extends WP_CLI_Command{
 
 
 
 
 
 
 
4
 
5
- /**
6
- * Clears Timber and Twig's Cache
7
- *
8
- * ## EXAMPLES
9
- *
10
- * wp timber clear_cache
11
- *
12
- */
 
 
 
 
 
13
 
14
- function clear_cache($mode = 'all'){
15
- WP_CLI::line('#mode = '.print_r($mode, true));
16
- if ($mode == 'all'){
17
- self::clear_cache_twig();
18
- self::clear_cache_timber();
19
- }
20
- if ($mode == 'twig'){
21
- }
22
- if ($mode == 'timber'){
23
 
24
- }
25
- }
 
 
 
 
 
 
 
 
 
26
 
27
- /**
28
- * Clears Timber's Cache
29
- *
30
- * ## EXAMPLES
31
- *
32
- * wp timber clear_cache_timber
33
- *
34
- */
 
35
 
36
- function clear_cache_timber(){
37
- WP_CLI::success('Cleared contents of Timbers Cache');
38
- }
39
 
40
- /**
41
- * Clears Twig's Cache
42
- *
43
- * ## EXAMPLES
44
- *
45
- * wp timber clear_cache_twig
46
- *
47
- */
48
-
49
- function clear_cache_twig(){
50
- $loader = new TimberLoader();
51
- $twig = $loader->get_twig();
52
- $twig->clearCacheFiles();
53
- self::rrmdir($twig->getCache());
54
- WP_CLI::success('Cleared contents of '.$twig->getCache());
55
- }
56
-
57
- private function rrmdir($dir) {
58
- if (is_dir($dir)) {
59
- $objects = scandir($dir);
60
- foreach ($objects as $object) {
61
- if ($object != "." && $object != "..") {
62
- if (filetype($dir."/".$object) == "dir"){
63
- self::rrmdir($dir."/".$object);
64
- rmdir($dir."/".$object);
65
- } else {
66
- unlink($dir."/".$object);
67
- }
68
- }
69
- }
70
- reset($objects);
71
- }
72
- }
73
-
74
- }
75
-
76
- WP_CLI::add_command( 'timber', 'Timber_Command' );
1
  <?php
2
+ if (class_exists('WP_CLI_Command')) {
3
+ class Timber_Command extends WP_CLI_Command
4
+ {
5
 
6
+ /**
7
+ * Clears Timber and Twig's Cache
8
+ *
9
+ * ## EXAMPLES
10
+ *
11
+ * wp timber clear_cache
12
+ *
13
+ */
14
 
15
+ public function clear_cache($mode = 'all') {
16
+ if (is_array($mode)){
17
+ $mode = reset($mode);
18
+ }
19
+ if ($mode == 'all') {
20
+ self::clear_cache_twig();
21
+ self::clear_cache_timber();
22
+ } else if ($mode == 'twig') {
23
+ self::clear_cache_twig();
24
+ } else if ($mode == 'timber') {
25
+ self::clear_cache_timber();
26
+ }
27
+ }
28
 
29
+ function clear_cache_twig(){
30
+ $loader = new TimberLoader();
31
+ $clear = $loader->clear_cache_twig();
32
+ if ($clear){
33
+ WP_CLI::success('Cleared contents of twig cache');
34
+ } else {
35
+ WP_CLI::failure('Failed to clear cache');
36
+ }
37
+ }
38
 
39
+ /**
40
+ * Clears Timber's Cache
41
+ *
42
+ * ## EXAMPLES
43
+ *
44
+ * wp timber clear_cache_timber
45
+ *
46
+ */
47
+ function clear_cache_timber() {
48
+ WP_CLI::success("Cleared contents of Timber's Cache");
49
+ }
50
 
51
+ /**
52
+ * Clears Twig's Cache
53
+ *
54
+ * ## EXAMPLES
55
+ *
56
+ * wp timber clear_cache_twig
57
+ *
58
+ */
59
+
60
 
61
+ }
 
 
62
 
63
+ WP_CLI::add_command('timber', 'Timber_Command');
64
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
functions/timber-admin.php CHANGED
@@ -1,12 +1,13 @@
1
  <?php
2
 
3
- class TimberAdmin {
 
4
 
5
  function __construct() {
6
- if (!is_admin()) {
7
  return;
8
  }
9
- add_filter( 'plugin_action_links', array(&$this, 'settings_link'), 10, 2 );
10
  }
11
 
12
  /**
@@ -14,14 +15,11 @@ class TimberAdmin {
14
  * @param string $file
15
  * @return array
16
  */
17
- function settings_link( $links, $file ) {
18
- if (strstr($file, '/timber.php')){
19
- return array_merge(
20
- array(
21
- 'settings' => '<a href="https://github.com/jarednova/timber/wiki" target="_blank">Documentation</a> | <a href="https://github.com/jarednova/timber/wiki/getting-started" target="_blank">Starter Guide</a>'
22
- ),
23
- $links
24
- );
25
  }
26
  return $links;
27
  }
@@ -29,4 +27,4 @@ class TimberAdmin {
29
  }
30
 
31
  global $timber_admin;
32
- $timber_admin = new TimberAdmin();
1
  <?php
2
 
3
+ class TimberAdmin
4
+ {
5
 
6
  function __construct() {
7
+ if (!is_admin()) {
8
  return;
9
  }
10
+ add_filter('plugin_action_links', array(&$this, 'settings_link'), 10, 2);
11
  }
12
 
13
  /**
15
  * @param string $file
16
  * @return array
17
  */
18
+ function settings_link($links, $file) {
19
+ if (strstr($file, '/timber.php')) {
20
+ return array_merge(array(
21
+ 'settings' => '<a href="https://github.com/jarednova/timber/wiki" target="_blank">Documentation</a> | <a href="https://github.com/jarednova/timber/wiki/getting-started" target="_blank">Starter Guide</a>'
22
+ ), $links);
 
 
 
23
  }
24
  return $links;
25
  }
27
  }
28
 
29
  global $timber_admin;
30
+ $timber_admin = new TimberAdmin();
functions/timber-archives.php CHANGED
@@ -1,20 +1,23 @@
1
  <?php
2
- class TimberArchives extends TimberCore {
3
 
4
- var $base = '';
 
5
 
6
- function __construct($args, $base = ''){
7
- $this->init($args, $base);
8
- }
 
 
 
9
 
10
  /**
11
  * @param array|string $args
12
  * @param string $base
13
  */
14
- function init($args, $base = ''){
15
- $this->base = $base;
16
- $this->items = $this->get_items($args);
17
- }
18
 
19
  /**
20
  * @param string $url
@@ -22,10 +25,10 @@ class TimberArchives extends TimberCore {
22
  * @return mixed
23
  */
24
  function get_archives_link($url, $text) {
25
- $ret['text'] = $ret['title'] = $ret['name'] = wptexturize($text);
26
- $ret['url'] = $ret['link'] = esc_url(TimberURLHelper::prepend_to_url($url, $this->base));
27
- return $ret;
28
- }
29
 
30
  /**
31
  * @param array|string $args
@@ -36,25 +39,25 @@ class TimberArchives extends TimberCore {
36
  * @param string $limit
37
  * @return array
38
  */
39
- function get_items_yearly($args, $last_changed, $join, $where, $order, $limit){
40
- global $wpdb;
41
- $output = array();
42
- $query = "SELECT YEAR(post_date) AS `year`, count(ID) as posts FROM $wpdb->posts $join $where GROUP BY YEAR(post_date) ORDER BY post_date $order $limit";
43
- $key = md5( $query );
44
- $key = "wp_get_archives:$key:$last_changed";
45
- if ( ! $results = wp_cache_get( $key, 'posts' ) ) {
46
- $results = $wpdb->get_results( $query );
47
- wp_cache_set( $key, $results, 'posts' );
48
- }
49
- if ( $results ) {
50
- foreach ( (array) $results as $result) {
51
- $url = get_year_link($result->year);
52
- $text = sprintf('%d', $result->year);
53
- $output[] = $this->get_archives_link($url, $text);
54
- }
55
- }
56
- return $output;
57
- }
58
 
59
  /**
60
  * @param array|string $args
@@ -66,190 +69,202 @@ class TimberArchives extends TimberCore {
66
  * @param bool $nested
67
  * @return array
68
  */
69
- function get_items_montly($args, $last_changed, $join, $where, $order, $limit, $nested = true){
70
- global $wpdb, $wp_locale;
71
- $output = array();
72
- $defaults = array(
73
- 'show_year' => true,
74
- );
75
- $r = wp_parse_args( $args, $defaults );
76
- extract( $r, EXTR_SKIP );
77
- $where = $where;
78
- //will need to specify which year we're looking for
79
- $query = "SELECT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, count(ID) as posts FROM $wpdb->posts $join $where GROUP BY YEAR(post_date), MONTH(post_date) ORDER BY post_date $order $limit";
80
- $key = md5( $query );
81
- $key = "wp_get_archives:$key:$last_changed";
82
- if ( ! $results = wp_cache_get( $key, 'posts' ) ) {
83
- $results = $wpdb->get_results( $query );
84
- wp_cache_set( $key, $results, 'posts' );
85
- }
86
- if ( $results ) {
87
- foreach ( (array) $results as $result ) {
88
- $url = get_month_link( $result->year, $result->month );
89
- /* translators: 1: month name, 2: 4-digit year */
90
-
91
- if ($show_year && !$nested){
92
- $text = sprintf(__('%1$s %2$d'), $wp_locale->get_month($result->month), $result->year);
93
- } else {
94
- $text = sprintf(__('%1$s'), $wp_locale->get_month($result->month));
95
- }
96
- if ($nested){
97
- $output[$result->year][] = $this->get_archives_link($url, $text);
98
- } else {
99
- $output[] = $this->get_archives_link($url, $text);
100
- }
101
- }
102
- }
103
- if ($nested){
104
- $out2 = array();
105
- foreach($output as $year=>$months){
106
- $out2[] = array('name' => $year, 'children' => $months);
107
- }
108
- return $out2;
109
- }
110
- return $output;
111
- }
 
 
 
 
112
 
113
  /**
114
  * @param array|string $args
115
  * @return array|string
116
  */
117
- function get_items($args){
118
- global $wpdb, $wp_locale;
119
-
120
- $defaults = array(
121
- 'type' => 'monthly', 'limit' => '',
122
- 'format' => 'html', 'before' => '',
123
- 'after' => '', 'show_post_count' => false,
124
- 'order' => 'DESC',
125
- 'post_type' => 'post',
126
- 'nested' => true
127
- );
128
-
129
- $r = wp_parse_args( $args, $defaults );
130
- extract( $r, EXTR_SKIP );
131
-
132
- if ( '' == $type )
133
- $type = 'monthly';
134
-
135
- if ( '' != $limit ) {
136
- $limit = absint($limit);
137
- $limit = ' LIMIT '.$limit;
138
- }
139
-
140
- $order = strtoupper( $order );
141
- if ( $order !== 'ASC' ){
142
- $order = 'DESC';
143
- }
144
-
145
- // this is what will separate dates on weekly archive links
146
- $archive_week_separator = '&#8211;';
147
-
148
- // over-ride general date format ? 0 = no: use the date format set in Options, 1 = yes: over-ride
149
- $archive_date_format_over_ride = 0;
150
-
151
- // options for daily archive (only if you over-ride the general date format)
152
- $archive_day_date_format = 'Y/m/d';
153
-
154
- // options for weekly archive (only if you over-ride the general date format)
155
- $archive_week_start_date_format = 'Y/m/d';
156
- $archive_week_end_date_format = 'Y/m/d';
157
-
158
- if ( !$archive_date_format_over_ride ) {
159
- $archive_day_date_format = get_option('date_format');
160
- $archive_week_start_date_format = get_option('date_format');
161
- $archive_week_end_date_format = get_option('date_format');
162
- }
163
-
164
- $where = apply_filters( 'getarchives_where', "WHERE post_type = '".$post_type."' AND post_status = 'publish'", $r );
165
- $join = apply_filters( 'getarchives_join', '', $r );
166
-
167
- $output = array();
168
-
169
- $last_changed = wp_cache_get( 'last_changed', 'posts' );
170
- if ( ! $last_changed ) {
171
- $last_changed = microtime();
172
- wp_cache_set( 'last_changed', $last_changed, 'posts' );
173
- }
174
-
175
- if ( 'monthly' == $type ) {
176
- $output = $this->get_items_montly($args, $last_changed, $join, $where, $order, $limit, $nested);
177
- } elseif ('yearly' == $type) {
178
- $output = $this->get_items_yearly($args, $last_changed, $join, $where, $order, $limit);
179
- } elseif ( 'yearlymonthly' == $type || 'yearmonth' == $type){
180
- $years = $this->get_items_yearly($args, $last_changed, $join, $where, $order, $limit);
181
- foreach($years as &$year){
182
- $args = array('show_year' => false);
183
- $year['children'] = $this->get_items_montly($args, $last_changed, $join, $where, $order, $limit);
184
- }
185
- $output = $years;
186
- } elseif ( 'daily' == $type ) {
187
- $query = "SELECT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, DAYOFMONTH(post_date) AS `dayofmonth`, count(ID) as posts FROM $wpdb->posts $join $where GROUP BY YEAR(post_date), MONTH(post_date), DAYOFMONTH(post_date) ORDER BY post_date $order $limit";
188
- $key = md5( $query );
189
- $key = "wp_get_archives:$key:$last_changed";
190
- if ( ! $results = wp_cache_get( $key, 'posts' ) ) {
191
- $results = $wpdb->get_results( $query );
192
- $cache[ $key ] = $results;
193
- wp_cache_set( $key, $results, 'posts' );
194
- }
195
- if ( $results ) {
196
- $afterafter = $after;
197
- foreach ( (array) $results as $result ) {
198
- $url = get_day_link($result->year, $result->month, $result->dayofmonth);
199
- $date = sprintf('%1$d-%2$02d-%3$02d 00:00:00', $result->year, $result->month, $result->dayofmonth);
200
- $text = mysql2date($archive_day_date_format, $date);
201
- $output[] = $this->get_archives_link($url, $text);
202
- }
203
- }
204
- } elseif ( 'weekly' == $type ) {
205
- $week = _wp_mysql_week( '`post_date`' );
206
- $query = "SELECT DISTINCT $week AS `week`, YEAR( `post_date` ) AS `yr`, DATE_FORMAT( `post_date`, '%Y-%m-%d' ) AS `yyyymmdd`, count( `ID` ) AS `posts` FROM `$wpdb->posts` $join $where GROUP BY $week, YEAR( `post_date` ) ORDER BY `post_date` $order $limit";
207
- $key = md5( $query );
208
- $key = "wp_get_archives:$key:$last_changed";
209
- if ( ! $results = wp_cache_get( $key, 'posts' ) ) {
210
- $results = $wpdb->get_results( $query );
211
- wp_cache_set( $key, $results, 'posts' );
212
- }
213
- $arc_w_last = '';
214
- $afterafter = $after;
215
- if ( $results ) {
216
- foreach ( (array) $results as $result ) {
217
- if ( $result->week != $arc_w_last ) {
218
- $arc_year = $result->yr;
219
- $arc_w_last = $result->week;
220
- $arc_week = get_weekstartend($result->yyyymmdd, get_option('start_of_week'));
221
- $arc_week_start = date_i18n($archive_week_start_date_format, $arc_week['start']);
222
- $arc_week_end = date_i18n($archive_week_end_date_format, $arc_week['end']);
223
- $url = sprintf('%1$s/%2$s%3$sm%4$s%5$s%6$sw%7$s%8$d', home_url(), '', '?', '=', $arc_year, '&amp;', '=', $result->week);
224
- $text = $arc_week_start . $archive_week_separator . $arc_week_end;
225
- $output[] = $this->get_archives_link($url, $text);
226
- }
227
- }
228
- }
229
- } elseif ( ( 'postbypost' == $type ) || ('alpha' == $type) ) {
230
- $orderby = ('alpha' == $type) ? 'post_title ASC ' : 'post_date DESC ';
231
- $query = "SELECT * FROM $wpdb->posts $join $where ORDER BY $orderby $limit";
232
- $key = md5( $query );
233
- $key = "wp_get_archives:$key:$last_changed";
234
- if ( ! $results = wp_cache_get( $key, 'posts' ) ) {
235
- $results = $wpdb->get_results( $query );
236
- wp_cache_set( $key, $results, 'posts' );
237
- }
238
- if ( $results ) {
239
- foreach ( (array) $results as $result ) {
240
- if ( $result->post_date != '0000-00-00 00:00:00' ) {
241
- $url = get_permalink( $result );
242
- if ( $result->post_title ) {
243
- /** This filter is documented in wp-includes/post-template.php */
244
- $text = strip_tags( apply_filters( 'the_title', $result->post_title, $result->ID ) );
245
- } else {
246
- $text = $result->ID;
247
- }
248
- $output .= get_archives_link($url, $text, $format, $before, $after);
249
- }
250
- }
251
- }
252
- }
253
- return $output;
254
- }
 
 
 
 
 
 
 
 
255
  }
1
  <?php
 
2
 
3
+ class TimberArchives extends TimberCore
4
+ {
5
 
6
+ public $base = '';
7
+ public $items;
8
+
9
+ function __construct($args = null, $base = '') {
10
+ $this->init($args, $base);
11
+ }
12
 
13
  /**
14
  * @param array|string $args
15
  * @param string $base
16
  */
17
+ function init($args = null, $base = '') {
18
+ $this->base = $base;
19
+ $this->items = $this->get_items($args);
20
+ }
21
 
22
  /**
23
  * @param string $url
25
  * @return mixed
26
  */
27
  function get_archives_link($url, $text) {
28
+ $ret['text'] = $ret['title'] = $ret['name'] = wptexturize($text);
29
+ $ret['url'] = $ret['link'] = esc_url(TimberURLHelper::prepend_to_url($url, $this->base));
30
+ return $ret;
31
+ }
32
 
33
  /**
34
  * @param array|string $args
39
  * @param string $limit
40
  * @return array
41
  */
42
+ function get_items_yearly($args, $last_changed, $join, $where, $order, $limit) {
43
+ global $wpdb;
44
+ $output = array();
45
+ $query = "SELECT YEAR(post_date) AS `year`, count(ID) as posts FROM $wpdb->posts $join $where GROUP BY YEAR(post_date) ORDER BY post_date $order $limit";
46
+ $key = md5($query);
47
+ $key = "wp_get_archives:$key:$last_changed";
48
+ if (!$results = wp_cache_get($key, 'posts')) {
49
+ $results = $wpdb->get_results($query);
50
+ wp_cache_set($key, $results, 'posts');
51
+ }
52
+ if ($results) {
53
+ foreach ((array)$results as $result) {
54
+ $url = get_year_link($result->year);
55
+ $text = sprintf('%d', $result->year);
56
+ $output[] = $this->get_archives_link($url, $text);
57
+ }
58
+ }
59
+ return $output;
60
+ }
61
 
62
  /**
63
  * @param array|string $args
69
  * @param bool $nested
70
  * @return array
71
  */
72
+ function get_items_montly($args, $last_changed, $join, $where, $order, $limit = 1000, $nested = true) {
73
+ global $wpdb, $wp_locale;
74
+ $output = array();
75
+ $defaults = array(
76
+ 'show_year' => true,
77
+ );
78
+ $r = wp_parse_args($args, $defaults);
79
+
80
+ $show_year = null;
81
+ extract($r, EXTR_SKIP);
82
+
83
+ //will need to specify which year we're looking for
84
+ $query = "SELECT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, count(ID) as posts "
85
+ . "FROM $wpdb->posts $join $where GROUP BY YEAR(post_date), MONTH(post_date) "
86
+ . "ORDER BY post_date $order $limit";
87
+ $key = md5($query);
88
+ $key = "wp_get_archives:$key:$last_changed";
89
+ if (!$results = wp_cache_get($key, 'posts')) {
90
+ $results = $wpdb->get_results($query);
91
+ wp_cache_set($key, $results, 'posts');
92
+ }
93
+ if ($results) {
94
+ foreach ((array)$results as $result) {
95
+ $url = get_month_link($result->year, $result->month);
96
+ /* translators: 1: month name, 2: 4-digit year */
97
+
98
+ if ($show_year && !$nested) {
99
+ $text = sprintf(__('%1$s %2$d'), $wp_locale->get_month($result->month), $result->year);
100
+ } else {
101
+ $text = sprintf(__('%1$s'), $wp_locale->get_month($result->month));
102
+ }
103
+ if ($nested) {
104
+ $output[$result->year][] = $this->get_archives_link($url, $text);
105
+ } else {
106
+ $output[] = $this->get_archives_link($url, $text);
107
+ }
108
+ }
109
+ }
110
+ if ($nested) {
111
+ $out2 = array();
112
+ foreach ($output as $year => $months) {
113
+ $out2[] = array('name' => $year, 'children' => $months);
114
+ }
115
+ return $out2;
116
+ }
117
+ return $output;
118
+ }
119
 
120
  /**
121
  * @param array|string $args
122
  * @return array|string
123
  */
124
+ function get_items($args = null) {
125
+ global $wpdb;
126
+
127
+ $defaults = array(
128
+ 'type' => 'monthly', 'limit' => '',
129
+ 'format' => 'html', 'before' => '',
130
+ 'after' => '', 'show_post_count' => false,
131
+ 'order' => 'DESC',
132
+ 'post_type' => 'post',
133
+ 'nested' => true
134
+ );
135
+
136
+ $r = wp_parse_args($args, $defaults);
137
+ $type = $limit = $order = $post_type = $nested = $format = $before = $after = null;
138
+ extract($r, EXTR_SKIP);
139
+
140
+ if (empty($order)){
141
+ $order = 'DESC';
142
+ }
143
+
144
+ if (empty($post_type)){
145
+ $post_type = 'post';
146
+ }
147
+ if (empty($type)) {
148
+ $type = 'monthly';
149
+ }
150
+
151
+ if (!empty($limit)) {
152
+ $limit = absint($limit);
153
+ $limit = ' LIMIT ' . $limit;
154
+ }
155
+
156
+ $order = strtoupper($order);
157
+ if ($order !== 'ASC') {
158
+ $order = 'DESC';
159
+ }
160
+
161
+ // this is what will separate dates on weekly archive links
162
+ $archive_week_separator = '&#8211;';
163
+
164
+ // over-ride general date format ? 0 = no: use the date format set in Options, 1 = yes: over-ride
165
+ $archive_date_format_over_ride = 0;
166
+
167
+ // options for daily archive (only if you over-ride the general date format)
168
+ $archive_day_date_format = 'Y/m/d';
169
+
170
+ // options for weekly archive (only if you over-ride the general date format)
171
+ $archive_week_start_date_format = 'Y/m/d';
172
+ $archive_week_end_date_format = 'Y/m/d';
173
+
174
+ if (!$archive_date_format_over_ride) {
175
+ $archive_day_date_format = get_option('date_format');
176
+ $archive_week_start_date_format = get_option('date_format');
177
+ $archive_week_end_date_format = get_option('date_format');
178
+ }
179
+
180
+ $where = apply_filters('getarchives_where', 'WHERE post_type = "' . $post_type . '" AND post_status = "publish"', $r);
181
+ $join = apply_filters('getarchives_join', '', $r);
182
+
183
+ $output = array();
184
+
185
+ $last_changed = wp_cache_get('last_changed', 'posts');
186
+ if (!$last_changed) {
187
+ $last_changed = microtime();
188
+ wp_cache_set('last_changed', $last_changed, 'posts');
189
+ }
190
+ if ('monthly' == $type) {
191
+ $output = $this->get_items_montly($args, $last_changed, $join, $where, $order, $limit, $nested);
192
+ } elseif ('yearly' == $type) {
193
+ $output = $this->get_items_yearly($args, $last_changed, $join, $where, $order, $limit);
194
+ } elseif ('yearlymonthly' == $type || 'yearmonth' == $type) {
195
+ $years = $this->get_items_yearly($args, $last_changed, $join, $where, $order, $limit);
196
+ foreach ($years as &$year) {
197
+ $args = array('show_year' => false);
198
+ $year['children'] = $this->get_items_montly($args, $last_changed, $join, $where, $order, $limit);
199
+ }
200
+ $output = $years;
201
+ } elseif ('daily' == $type) {
202
+ $query = "SELECT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, DAYOFMONTH(post_date) AS `dayofmonth`, count(ID) as posts FROM $wpdb->posts $join $where GROUP BY YEAR(post_date), MONTH(post_date), DAYOFMONTH(post_date) ORDER BY post_date $order $limit";
203
+ $key = md5($query);
204
+ $key = "wp_get_archives:$key:$last_changed";
205
+ if (!$results = wp_cache_get($key, 'posts')) {
206
+ $results = $wpdb->get_results($query);
207
+ $cache[$key] = $results;
208
+ wp_cache_set($key, $results, 'posts');
209
+ }
210
+ if ($results) {
211
+ foreach ((array)$results as $result) {
212
+ $url = get_day_link($result->year, $result->month, $result->dayofmonth);
213
+ $date = sprintf('%1$d-%2$02d-%3$02d 00:00:00', $result->year, $result->month, $result->dayofmonth);
214
+ $text = mysql2date($archive_day_date_format, $date);
215
+ $output[] = $this->get_archives_link($url, $text);
216
+ }
217
+ }
218
+ } elseif ('weekly' == $type) {
219
+ $week = _wp_mysql_week('`post_date`');
220
+ $query = "SELECT DISTINCT $week AS `week`, YEAR( `post_date` ) AS `yr`, DATE_FORMAT( `post_date`, '%Y-%m-%d' ) AS `yyyymmdd`, "
221
+ . "count( `ID` ) AS `posts` FROM `$wpdb->posts` $join $where GROUP BY $week, YEAR( `post_date` ) ORDER BY `post_date` $order $limit";
222
+ $key = md5($query);
223
+ $key = "wp_get_archives:$key:$last_changed";
224
+ if (!$results = wp_cache_get($key, 'posts')) {
225
+ $results = $wpdb->get_results($query);
226
+ wp_cache_set($key, $results, 'posts');
227
+ }
228
+ $arc_w_last = '';
229
+ if ($results) {
230
+ foreach ((array)$results as $result) {
231
+ if ($result->week != $arc_w_last) {
232
+ $arc_year = $result->yr;
233
+ $arc_w_last = $result->week;
234
+ $arc_week = get_weekstartend($result->yyyymmdd, get_option('start_of_week'));
235
+ $arc_week_start = date_i18n($archive_week_start_date_format, $arc_week['start']);
236
+ $arc_week_end = date_i18n($archive_week_end_date_format, $arc_week['end']);
237
+ $url = sprintf('%1$s/%2$s%3$sm%4$s%5$s%6$sw%7$s%8$d', home_url(), '', '?', '=', $arc_year, '&amp;', '=', $result->week);
238
+ $text = $arc_week_start . $archive_week_separator . $arc_week_end;
239
+ $output[] = $this->get_archives_link($url, $text);
240
+ }
241
+ }
242
+ }
243
+ } elseif ('postbypost' == $type || 'alpha' == $type) {
244
+ $orderby = 'alpha' == $type ? 'post_title ASC ' : 'post_date DESC ';
245
+ $query = "SELECT * FROM $wpdb->posts $join $where ORDER BY $orderby $limit";
246
+ $key = md5($query);
247
+ $key = "wp_get_archives:$key:$last_changed";
248
+ if (!$results = wp_cache_get($key, 'posts')) {
249
+ $results = $wpdb->get_results($query);
250
+ wp_cache_set($key, $results, 'posts');
251
+ }
252
+ if ($results) {
253
+ foreach ((array)$results as $result) {
254
+ if ($result->post_date != '0000-00-00 00:00:00') {
255
+ $url = get_permalink($result);
256
+ if ($result->post_title) {
257
+ /** This filter is documented in wp-includes/post-template.php */
258
+ $text = strip_tags(apply_filters('the_title', $result->post_title, $result->ID));
259
+ } else {
260
+ $text = $result->ID;
261
+ }
262
+ $output .= get_archives_link($url, $text, $format, $before, $after);
263
+ }
264
+ }
265
+ }
266
+ }
267
+ return $output;
268
+ }
269
+
270
  }
functions/timber-comment.php CHANGED
@@ -1,12 +1,21 @@
1
  <?php
2
 
3
- class TimberComment extends TimberCore {
 
4
 
5
- var $PostClass = 'TimberPost';
6
- var $object_type = 'comment';
7
 
8
  public static $representation = 'comment';
9
 
 
 
 
 
 
 
 
 
10
  /**
11
  * @param int $cid
12
  */
@@ -15,7 +24,7 @@ class TimberComment extends TimberCore {
15
  }
16
 
17
  /**
18
- * @param int $cid
19
  */
20
  function init($cid) {
21
  $comment_data = $cid;
@@ -24,6 +33,7 @@ class TimberComment extends TimberCore {
24
  }
25
  $this->import($comment_data);
26
  $this->ID = $this->comment_ID;
 
27
  $comment_meta_data = $this->get_meta_fields($this->ID);
28
  $this->import($comment_meta_data);
29
  }
@@ -36,7 +46,7 @@ class TimberComment extends TimberCore {
36
  return new TimberUser($this->user_id);
37
  } else {
38
  $author = new TimberUser(0);
39
- if (isset($this->comment_author) && $this->comment_author){
40
  $author->name = $this->comment_author;
41
  } else {
42
  $author->name = 'Anonymous';
@@ -50,22 +60,26 @@ class TimberComment extends TimberCore {
50
  * @param string $default
51
  * @return bool|mixed|string
52
  */
53
- public function avatar($size=92, $default=''){
54
  // Fetches the Gravatar
55
  // use it like this
56
  // {{comment.avatar(36,template_uri~"/img/dude.jpg")}}
57
 
58
- if ( ! get_option('show_avatars') ) return false;
59
- if ( !is_numeric($size) ) $size = '92';
 
 
 
 
60
 
61
  $email = $this->avatar_email();
62
  $email_hash = '';
63
- if ( !empty($email) ){
64
- $email_hash = md5( strtolower( trim( $email ) ) );
65
  }
66
  $host = $this->avatar_host($email_hash);
67
  $default = $this->avatar_default($default, $email, $size, $host);
68
- if( !empty($email) ) {
69
  $avatar = $this->avatar_out($email, $default, $host, $email_hash, $size);
70
  } else {
71
  $avatar = $default;
@@ -91,7 +105,7 @@ class TimberComment extends TimberCore {
91
  * @param string $field_name
92
  * @return mixed
93
  */
94
- public function meta($field_name){
95
  return $this->get_meta_field($field_name);
96
  }
97
 
@@ -99,19 +113,19 @@ class TimberComment extends TimberCore {
99
  * @param int $comment_id
100
  * @return mixed
101
  */
102
- private function get_meta_fields($comment_id = null){
103
- if ($comment_id === null){
104
  $comment_id = $this->ID;
105
  }
106
  //Could not find a WP function to fetch all comment meta data, so I made one.
107
- $comment_metas = apply_filters('timber_comment_get_meta_pre', array(), $this->ID);
108
- $comment_metas = get_comment_meta($this->ID);
109
- foreach($comment_metas as &$cm){
110
- if (is_array($cm) && count($cm) == 1){
111
  $cm = $cm[0];
112
  }
113
  }
114
- $comment_metas = apply_filters('timber_comment_get_meta', $comment_metas, $this->ID);
115
  return $comment_metas;
116
  }
117
 
@@ -119,9 +133,9 @@ class TimberComment extends TimberCore {
119
  * @param string $field_name
120
  * @return mixed
121
  */
122
- private function get_meta_field($field_name){
123
  $value = apply_filters('timber_comment_get_meta_field_pre', null, $this->ID, $field_name, $this);
124
- if ($value === null){
125
  $value = get_comment_meta($this->ID, $field_name, true);
126
  }
127
  $value = apply_filters('timber_comment_get_meta_field', $value, $this->ID, $field_name, $this);
@@ -134,28 +148,27 @@ class TimberComment extends TimberCore {
134
  /**
135
  * @return string
136
  */
137
- private function avatar_email(){
138
- $email = '';
139
- $id = (int) $this->user_id;
140
- $user = get_userdata($id);
141
- if ($user){
142
- $email = $user->user_email;
143
- } else {
144
- $email = $this->comment_author_email;
145
- }
146
- return $email;
147
  }
148
 
149
  /**
150
  * @param string $email_hash
151
  * @return string
152
  */
153
- private function avatar_host($email_hash){
154
- if ( is_ssl() ) {
155
  $host = 'https://secure.gravatar.com';
156
  } else {
157
- if ( !empty($email_hash) ){
158
- $host = sprintf( "http://%d.gravatar.com", ( hexdec( $email_hash[0] ) % 2 ) );
159
  } else {
160
  $host = 'http://0.gravatar.com';
161
  }
@@ -170,36 +183,36 @@ class TimberComment extends TimberCore {
170
  * @param string $host
171
  * @return string
172
  */
173
- private function avatar_default($default, $email, $size, $host){
174
- # what if its relative.
175
- if(substr ( $default , 0, 1 ) == "/" ){
176
- $default = home_url() . $default;
177
- }
178
-
179
- if (empty($default) ){
180
- $avatar_default = get_option('avatar_default');
181
- if ( empty($avatar_default) ){
182
- $default = 'mystery';
183
- } else {
184
- $default = $avatar_default;
185
- }
186
- }
187
- if ( 'mystery' == $default ) {
188
- $default = "$host/avatar/ad516503a11cd5ca435acc9bb6523536?s={$size}";
189
- // ad516503a11cd5ca435acc9bb6523536 == md5('unknown@gravatar.com')
190
- } elseif ( 'blank' == $default ) {
191
- $default = $email ? 'blank' : includes_url( 'images/blank.gif' );
192
- } elseif ( !empty($email) && 'gravatar_default' == $default ) {
193
- $default = '';
194
- } elseif ( 'gravatar_default' == $default ) {
195
- $default = "$host/avatar/?s={$size}";
196
- } elseif ( empty($email) && !strstr($default, 'http://') ) {
197
- $default = "$host/avatar/?d=$default&amp;s={$size}";
198
- } elseif ( strpos($default, 'http://') === 0 ) {
199
  //theyre just linking to an image so don't do anything else
200
- //$default = add_query_arg( 's', $size, $default );
201
  }
202
- return $default;
203
  }
204
 
205
  /**
@@ -210,13 +223,13 @@ class TimberComment extends TimberCore {
210
  * @param string $size
211
  * @return mixed
212
  */
213
- private function avatar_out($email, $default, $host, $email_hash, $size){
214
- $out = "$host/avatar/";
215
- $out .= $email_hash;
216
- $out .= '?s='.$size;
217
- $out .= '&amp;d=' . urlencode( $default );
218
  $rating = get_option('avatar_rating');
219
- if ( !empty( $rating ) ) $out .= "&amp;r={$rating}";
220
- return str_replace( '&#038;', '&amp;', esc_url( $out ) );
 
 
221
  }
 
222
  }
1
  <?php
2
 
3
+ class TimberComment extends TimberCore
4
+ {
5
 
6
+ public $PostClass = 'TimberPost';
7
+ public $object_type = 'comment';
8
 
9
  public static $representation = 'comment';
10
 
11
+ public $ID;
12
+ public $id;
13
+ public $comment_author_email;
14
+ public $comment_content;
15
+ public $comment_date;
16
+ public $comment_ID;
17
+ public $user_id;
18
+
19
  /**
20
  * @param int $cid
21
  */
24
  }
25
 
26
  /**
27
+ * @param mixed $cid
28
  */
29
  function init($cid) {
30
  $comment_data = $cid;
33
  }
34
  $this->import($comment_data);
35
  $this->ID = $this->comment_ID;
36
+ $this->id = $this->comment_ID;
37
  $comment_meta_data = $this->get_meta_fields($this->ID);
38
  $this->import($comment_meta_data);
39
  }
46
  return new TimberUser($this->user_id);
47
  } else {
48
  $author = new TimberUser(0);
49
+ if (isset($this->comment_author) && $this->comment_author) {
50
  $author->name = $this->comment_author;
51
  } else {
52
  $author->name = 'Anonymous';
60
  * @param string $default
61
  * @return bool|mixed|string
62
  */
63
+ public function avatar($size = 92, $default = '') {
64
  // Fetches the Gravatar
65
  // use it like this
66
  // {{comment.avatar(36,template_uri~"/img/dude.jpg")}}
67
 
68
+ if (!get_option('show_avatars')) {
69
+ return false;
70
+ }
71
+ if (!is_numeric($size)) {
72
+ $size = '92';
73
+ }
74
 
75
  $email = $this->avatar_email();
76
  $email_hash = '';
77
+ if (!empty($email)) {
78
+ $email_hash = md5(strtolower(trim($email)));
79
  }
80
  $host = $this->avatar_host($email_hash);
81
  $default = $this->avatar_default($default, $email, $size, $host);
82
+ if (!empty($email)) {
83
  $avatar = $this->avatar_out($email, $default, $host, $email_hash, $size);
84
  } else {
85
  $avatar = $default;
105
  * @param string $field_name
106
  * @return mixed
107
  */
108
+ public function meta($field_name) {
109
  return $this->get_meta_field($field_name);
110
  }
111
 
113
  * @param int $comment_id
114
  * @return mixed
115
  */
116
+ private function get_meta_fields($comment_id = null) {
117
+ if ($comment_id === null) {
118
  $comment_id = $this->ID;
119
  }
120
  //Could not find a WP function to fetch all comment meta data, so I made one.
121
+ apply_filters('timber_comment_get_meta_pre', array(), $comment_id);
122
+ $comment_metas = get_comment_meta($comment_id);
123
+ foreach ($comment_metas as &$cm) {
124
+ if (is_array($cm) && count($cm) == 1) {
125
  $cm = $cm[0];
126
  }
127
  }
128
+ $comment_metas = apply_filters('timber_comment_get_meta', $comment_metas, $comment_id);
129
  return $comment_metas;
130
  }
131
 
133
  * @param string $field_name
134
  * @return mixed
135
  */
136
+ private function get_meta_field($field_name) {
137
  $value = apply_filters('timber_comment_get_meta_field_pre', null, $this->ID, $field_name, $this);
138
+ if ($value === null) {
139
  $value = get_comment_meta($this->ID, $field_name, true);
140
  }
141
  $value = apply_filters('timber_comment_get_meta_field', $value, $this->ID, $field_name, $this);
148
  /**
149
  * @return string
150
  */
151
+ private function avatar_email() {
152
+ $id = (int)$this->user_id;
153
+ $user = get_userdata($id);
154
+ if ($user) {
155
+ $email = $user->user_email;
156
+ } else {
157
+ $email = $this->comment_author_email;
158
+ }
159
+ return $email;
 
160
  }
161
 
162
  /**
163
  * @param string $email_hash
164
  * @return string
165
  */
166
+ private function avatar_host($email_hash) {
167
+ if (is_ssl()) {
168
  $host = 'https://secure.gravatar.com';
169
  } else {
170
+ if (!empty($email_hash)) {
171
+ $host = sprintf("http://%d.gravatar.com", (hexdec($email_hash[0]) % 2));
172
  } else {
173
  $host = 'http://0.gravatar.com';
174
  }
183
  * @param string $host
184
  * @return string
185
  */
186
+ private function avatar_default($default, $email, $size, $host) {
187
+ # what if its relative.
188
+ if (substr($default, 0, 1) == '/') {
189
+ $default = home_url() . $default;
190
+ }
191
+
192
+ if (empty($default)) {
193
+ $avatar_default = get_option('avatar_default');
194
+ if (empty($avatar_default)) {
195
+ $default = 'mystery';
196
+ } else {
197
+ $default = $avatar_default;
198
+ }
199
+ }
200
+ if ('mystery' == $default) {
201
+ $default = $host . '/avatar/ad516503a11cd5ca435acc9bb6523536?s=' . $size;
202
+ // ad516503a11cd5ca435acc9bb6523536 == md5('unknown@gravatar.com')
203
+ } else if ('blank' == $default) {
204
+ $default = $email ? 'blank' : includes_url('images/blank.gif');
205
+ } else if (!empty($email) && 'gravatar_default' == $default) {
206
+ $default = '';
207
+ } else if ('gravatar_default' == $default) {
208
+ $default = $host . '/avatar/?s=' . $size;
209
+ } else if (empty($email) && !strstr($default, 'http://')) {
210
+ $default = $host . '/avatar/?d=' . $default . '&amp;s=' . $size;
211
+ } else if (strpos($default, 'http://') === 0) {
212
  //theyre just linking to an image so don't do anything else
213
+ //$default = add_query_arg( 's', $size, $default );
214
  }
215
+ return $default;
216
  }
217
 
218
  /**
223
  * @param string $size
224
  * @return mixed
225
  */
226
+ private function avatar_out($email, $default, $host, $email_hash, $size) {
227
+ $out = $host . '/avatar/' . $email_hash . '?s=' . $size . '&amp;d=' . urlencode($default);
 
 
 
228
  $rating = get_option('avatar_rating');
229
+ if (!empty($rating)) {
230
+ $out .= '&amp;r=' . $rating;
231
+ }
232
+ return str_replace('&#038;', '&amp;', esc_url($out));
233
  }
234
+
235
  }
functions/timber-core.php CHANGED
@@ -1,56 +1,61 @@
1
  <?php
2
 
3
- class TimberCore {
 
 
 
 
 
4
 
5
  /**
6
  * @param array|object $info
7
  */
8
  function import($info) {
9
- if (is_object($info)) {
10
- $info = get_object_vars($info);
11
- }
12
- if (is_array($info)) {
13
- foreach ($info as $key => $value) {
14
- if(!empty($key)){
15
- $this->$key = $value;
16
- }
17
- }
18
- }
19
- }
20
 
21
  /**
22
  * @param string $key
23
  * @param mixed $value
24
  */
25
- function update($key, $value){
26
- update_metadata($this->object_type, $this->ID, $key, $value);
27
- }
28
 
29
  /**
30
  * @return bool
31
  */
32
  function can_edit() {
33
- if (isset($this->_can_edit)) {
34
- return $this->_can_edit;
35
- }
36
- $this->_can_edit = false;
37
- if (!function_exists('current_user_can')) {
38
- return false;
39
- }
40
- if (current_user_can('edit_post', $this->ID)) {
41
- $this->_can_edit = true;
42
- }
43
- return $this->_can_edit;
44
- }
45
 
46
  /**
47
  * @return array
48
  */
49
- function get_method_values(){
50
- $ret = array();
51
- $ret['can_edit'] = $this->can_edit();
52
- return $ret;
53
- }
54
 
55
  /**
56
  * @deprecated
@@ -58,10 +63,11 @@ class TimberCore {
58
  * @return mixed
59
  */
60
  function url_to_path($url = '') {
61
- if (!strlen($url) && $this->url) {
62
- $url = $this->url;
63
- }
64
- $url_info = parse_url($url);
65
- return $url_info['path'];
66
- }
 
67
  }
1
  <?php
2
 
3
+ class TimberCore
4
+ {
5
+
6
+ public $ID;
7
+ public $object_type;
8
+ public $url;
9
 
10
  /**
11
  * @param array|object $info
12
  */
13
  function import($info) {
14
+ if (is_object($info)) {
15
+ $info = get_object_vars($info);
16
+ }
17
+ if (is_array($info)) {
18
+ foreach ($info as $key => $value) {
19
+ if (!empty($key)) {
20
+ $this->$key = $value;
21
+ }
22
+ }
23
+ }
24
+ }
25
 
26
  /**
27
  * @param string $key
28
  * @param mixed $value
29
  */
30
+ function update($key, $value) {
31
+ update_metadata($this->object_type, $this->ID, $key, $value);
32
+ }
33
 
34
  /**
35
  * @return bool
36
  */
37
  function can_edit() {
38
+ if (isset($this->_can_edit)) {
39
+ return $this->_can_edit;
40
+ }
41
+ $this->_can_edit = false;
42
+ if (!function_exists('current_user_can')) {
43
+ return false;
44
+ }
45
+ if (current_user_can('edit_post', $this->ID)) {
46
+ $this->_can_edit = true;
47
+ }
48
+ return $this->_can_edit;
49
+ }
50
 
51
  /**
52
  * @return array
53
  */
54
+ function get_method_values() {
55
+ $ret = array();
56
+ $ret['can_edit'] = $this->can_edit();
57
+ return $ret;
58
+ }
59
 
60
  /**
61
  * @deprecated
63
  * @return mixed
64
  */
65
  function url_to_path($url = '') {
66
+ if (!strlen($url) && $this->url) {
67
+ $url = $this->url;
68
+ }
69
+ $url_info = parse_url($url);
70
+ return $url_info['path'];
71
+ }
72
+
73
  }
functions/timber-function-wrapper.php CHANGED
@@ -1,6 +1,7 @@
1
  <?php
2
 
3
- class TimberFunctionWrapper {
 
4
 
5
  private $_function;
6
  private $_args;
@@ -15,24 +16,24 @@ class TimberFunctionWrapper {
15
  * @param array $args
16
  * @param bool $return_output_buffer
17
  */
18
- public function __construct( $function, $args = array( ), $return_output_buffer = false ) {
19
  $this->_function = $function;
20
- $this->_args = $args;
21
- $this->_use_ob = $return_output_buffer;
22
 
23
- add_filter( 'get_twig', array( &$this, 'add_to_twig' ) );
24
  }
25
 
26
  /**
27
  * @param Twig_Environment $twig
28
  * @return Twig_Environment
29
  */
30
- public function add_to_twig( $twig ) {
31
  $wrapper = $this;
32
 
33
- $twig->addFunction( new Twig_SimpleFunction( $this->_function, function() use ( $wrapper ) {
34
- return call_user_func_array( array( $wrapper, 'call' ), func_get_args() );
35
- } ) );
36
 
37
  return $twig;
38
  }
@@ -41,12 +42,13 @@ class TimberFunctionWrapper {
41
  * @return string
42
  */
43
  public function call() {
44
- $args = $this->_parse_args( func_get_args(), $this->_args );
45
 
46
- if ( $this->_use_ob )
47
- return WPHelper::ob_function( $this->_function, $args );
48
- else
49
- return (string) call_user_func_array( $this->_function, $args );
 
50
  }
51
 
52
  /**
@@ -54,12 +56,12 @@ class TimberFunctionWrapper {
54
  * @param array $defaults
55
  * @return array
56
  */
57
- private function _parse_args( $args, $defaults ) {
58
- $_arg = reset( $defaults );
59
 
60
- foreach ( $args as $index => $arg ) {
61
- $defaults[$index] = is_null( $arg ) ? $_arg : $arg;
62
- $_arg = next( $defaults );
63
  }
64
 
65
  return $defaults;
1
  <?php
2
 
3
+ class TimberFunctionWrapper
4
+ {
5
 
6
  private $_function;
7
  private $_args;
16
  * @param array $args
17
  * @param bool $return_output_buffer
18
  */
19
+ public function __construct($function, $args = array(), $return_output_buffer = false) {
20
  $this->_function = $function;
21
+ $this->_args = $args;
22
+ $this->_use_ob = $return_output_buffer;
23
 
24
+ add_filter('get_twig', array(&$this, 'add_to_twig'));
25
  }
26
 
27
  /**
28
  * @param Twig_Environment $twig
29
  * @return Twig_Environment
30
  */
31
+ public function add_to_twig($twig) {
32
  $wrapper = $this;
33
 
34
+ $twig->addFunction(new Twig_SimpleFunction($this->_function, function () use ($wrapper) {
35
+ return call_user_func_array(array($wrapper, 'call'), func_get_args());
36
+ }));
37
 
38
  return $twig;
39
  }
42
  * @return string
43
  */
44
  public function call() {
45
+ $args = $this->_parse_args(func_get_args(), $this->_args);
46
 
47
+ if ($this->_use_ob) {
48
+ return WPHelper::ob_function($this->_function, $args);
49
+ } else {
50
+ return (string)call_user_func_array($this->_function, $args);
51
+ }
52
  }
53
 
54
  /**
56
  * @param array $defaults
57
  * @return array
58
  */
59
+ private function _parse_args($args, $defaults) {
60
+ $_arg = reset($defaults);
61
 
62
+ foreach ($args as $index => $arg) {
63
+ $defaults[$index] = is_null($arg) ? $_arg : $arg;
64
+ $_arg = next($defaults);
65
  }
66
 
67
  return $defaults;
functions/timber-helper.php CHANGED
@@ -1,6 +1,7 @@
1
  <?php
2
 
3
- class TimberHelper {
 
4
 
5
  /**
6
  * @param string $slug Unique identifier for transient
@@ -10,99 +11,100 @@ class TimberHelper {
10
  * @param bool $force (optional) Force callback to be executed when transient is locked
11
  * @return mixed
12
  */
13
- public static function transient( $slug, $callback, $transient_time = 0, $lock_timeout = 5, $force = false ) {
14
- if ( $transient_time === false || ( defined( 'WP_DISABLE_TRANSIENTS' ) && WP_DISABLE_TRANSIENTS ) ) {
15
  $enable_transients = false;
16
  } else {
17
  $enable_transients = true;
18
  }
19
 
20
- $data = $enable_transients ? get_transient( $slug ) : false;
21
 
22
- if ( false === $data ) {
23
 
24
- if ( $enable_transients && self::_is_transient_locked( $slug ) ) {
25
 
26
- $force = apply_filters( 'timber_force_transients', $force );
27
- $force = apply_filters( 'timber_force_transient_' . $slug, $force );
28
 
29
- if ( !$force )
30
- //the server is currently executing the process.
31
- //We're just gonna dump these users. Sorry!
32
  return false;
 
33
 
34
  $enable_transients = false;
35
  }
36
 
37
  // lock timeout shouldn't be higher than 5 seconds, unless
38
  // remote calls with high timeouts are made here
39
- if ( $enable_transients )
40
- self::_lock_transient( $slug, $lock_timeout );
41
 
42
  $data = $callback();
43
 
44
- if ( $enable_transients ) {
45
- set_transient( $slug, $data, $transient_time );
46
- self::_unlock_transient( $slug );
47
  }
48
  }
49
  return $data;
50
  }
51
 
52
- public static function _lock_transient( $slug, $lock_timeout ) {
53
- set_transient( $slug . '_lock', true, $lock_timeout );
54
- }
55
 
56
- public static function _unlock_transient( $slug ) {
57
- delete_transient( $slug . '_lock', true );
58
- }
59
 
60
- public static function _is_transient_locked( $slug ) {
61
- return (bool) get_transient( $slug . '_lock' );
62
- }
63
 
64
  /* These are for measuring page render time */
65
 
66
  /**
67
  * @return float
68
  */
69
- public static function start_timer(){
70
- $time = microtime();
71
- $time = explode(' ', $time);
72
- $time = $time[1] + $time[0];
73
- return $time;
74
- }
75
-
76
- /**
77
  * @param int $start
78
  * @return string
79
  */
80
- public static function stop_timer($start){
81
- $time = microtime();
82
- $time = explode(' ', $time);
83
- $time = $time[1] + $time[0];
84
- $finish = $time;
85
- $total_time = round(($finish - $start), 4);
86
- return $total_time.' seconds.';
87
- }
88
-
89
- /* Function Utilities
90
- ======================== */
91
-
92
- /**
93
  * @param callback $function
94
  * @param array $args
95
  * @return string
96
  */
97
- public static function ob_function($function, $args = array(null)) {
98
- ob_start();
99
- call_user_func_array($function, $args);
100
- $data = ob_get_contents();
101
- ob_end_clean();
102
- return $data;
103
- }
104
-
105
- /**
106
  * @param string $function_name
107
  * @param array $defaults
108
  * @param bool $return_output_buffer
@@ -116,448 +118,467 @@ class TimberHelper {
116
  * @param $arg
117
  * @return void
118
  */
119
- public static function error_log($arg) {
120
- if (!WP_DEBUG){
121
- return;
122
- }
123
- if (is_object($arg) || is_array($arg)) {
124
- $arg = print_r($arg, true);
125
- }
126
- error_log($arg);
127
- }
128
-
129
- /**
 
 
130
  * @return string
131
  */
132
- public static function get_wp_title($seperator = ' ', $seplocation = 'left') {
133
- $seperator = apply_filters('timber_wp_title_seperator', $seperator);
134
- return trim(wp_title($seperator, false, $seplocation));
135
- }
136
 
137
- /* Text Utilities
138
- ======================== */
139
 
140
- /**
141
  * @param string $text
142
  * @param int $num_words
143
  * @param string $more
144
  * @param string $allowed_tags
145
  * @return string
146
  */
147
- public static function trim_words($text, $num_words = 55, $more = null, $allowed_tags = 'p a span b i br') {
148
- if (null === $more) {
149
- $more = __('&hellip;');
150
- }
151
- $original_text = $text;
152
- $allowed_tag_string = '';
153
- foreach (explode(' ', $allowed_tags) as $tag) {
154
- $allowed_tag_string .= '<' . $tag . '>';
155
- }
156
- $text = strip_tags($text, $allowed_tag_string);
157
- /* translators: If your word count is based on single characters (East Asian characters),
158
- enter 'characters'. Otherwise, enter 'words'. Do not translate into your own language. */
159
- if ('characters' == _x('words', 'word count: words or characters?') && preg_match('/^utf\-?8$/i', get_option('blog_charset'))) {
160
- $text = trim(preg_replace("/[\n\r\t ]+/", ' ', $text), ' ');
161
- preg_match_all('/./u', $text, $words_array);
162
- $words_array = array_slice($words_array[0], 0, $num_words + 1);
163
- $sep = '';
164
- } else {
165
- $words_array = preg_split("/[\n\r\t ]+/", $text, $num_words + 1, PREG_SPLIT_NO_EMPTY);
166
- $sep = ' ';
167
- }
168
- if (count($words_array) > $num_words) {
169
- array_pop($words_array);
170
- $text = implode($sep, $words_array);
171
- $text = $text . $more;
172
- } else {
173
- $text = implode($sep, $words_array);
174
- }
175
- $text = self::close_tags($text);
176
- return apply_filters('wp_trim_words', $text, $num_words, $more, $original_text);
177
- }
178
-
179
- /**
180
  * @param string $html
181
  * @return string
182
  */
183
- public static function close_tags($html) {
184
- #put all opened tags into an array
185
- preg_match_all('#<([a-z]+)(?: .*)?(?<![/|/ ])>#iU', $html, $result);
186
- $openedtags = $result[1];
187
- #put all closed tags into an array
188
- preg_match_all('#</([a-z]+)>#iU', $html, $result);
189
- $closedtags = $result[1];
190
- $len_opened = count($openedtags);
191
- # all tags are closed
192
- if (count($closedtags) == $len_opened) {
193
- return $html;
194
- }
195
- $openedtags = array_reverse($openedtags);
196
- # close tags
197
- for ($i = 0; $i < $len_opened; $i++) {
198
- if (!in_array($openedtags[$i], $closedtags)) {
199
- $html .= '</' . $openedtags[$i] . '>';
200
- } else {
201
- unset($closedtags[array_search($openedtags[$i], $closedtags)]);
202
- }
203
- }
204
- return $html;
205
- }
206
-
207
- /**
208
  * @param string $ret
209
  * @return mixed
210
  */
211
- public static function twitterify($ret) {
212
- $ret = preg_replace("#(^|[\n ])([\w]+?://[\w]+[^ \"\n\r\t< ]*)#", "\\1<a href=\"\\2\" target=\"_blank\">\\2</a>", $ret);
213
- $ret = preg_replace("#(^|[\n ])((www|ftp)\.[^ \"\t\n\r< ]*)#", "\\1<a href=\"http://\\2\" target=\"_blank\">\\2</a>", $ret);
214
- $pattern = '#([0-9a-z]([-_.]?[0-9a-z])*@[0-9a-z]([-.]?[0-9a-z])*\\.';
215
- $pattern .= '[a-wyz][a-z](fo|g|l|m|mes|o|op|pa|ro|seum|t|u|v|z)?)#i';
216
- $ret = preg_replace($pattern, '<a href="mailto:\\1">\\1</a>', $ret);
217
- $ret = preg_replace("/\B@(\w+)/", " <a href=\"http://www.twitter.com/\\1\" target=\"_blank\">@\\1</a>", $ret);
218
- $ret = preg_replace("/\B#(\w+)/", " <a href=\"http://search.twitter.com/search?q=\\1\" target=\"_blank\">#\\1</a>", $ret);
219
- return $ret;
220
- }
221
-
222
- /* WordPress Query Utilities
223
- ======================== */
224
-
225
- /**
226
  * @param string $key
227
  * @param string $value
228
  * @return array|int
229
  */
230
- public static function get_posts_by_meta($key, $value) {
231
- global $wpdb;
232
- $query = $wpdb->prepare("SELECT post_id FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %s", $key, $value);
233
- $results = $wpdb->get_col($query);
234
- $pids = array();
235
- foreach ($results as $result) {
236
- if (get_post($result)) {
237
- $pids[] = $result;
238
- }
239
- }
240
- if (count($pids)) {
241
- return $pids;
242
- }
243
- return 0;
244
- }
245
-
246
- /**
247
  * @param string $key
248
  * @param string $value
249
  * @return int
250
  */
251
- public static function get_post_by_meta($key, $value) {
252
- global $wpdb;
253
- $query = $wpdb->prepare("SELECT post_id FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %s ORDER BY post_id", $key, $value);
254
- $results = $wpdb->get_col($query);
255
- foreach($results as $result){
256
- if ($result && get_post($result)) {
257
- return $result;
258
- }
259
- }
260
- return 0;
261
- }
262
-
263
- /**
264
- * @param int $ttid
265
- * @return mixed
266
- */
267
- public static function get_term_id_by_term_taxonomy_id($ttid){
268
- global $wpdb;
269
- $query = $wpdb->prepare("SELECT term_id FROM $wpdb->term_taxonomy WHERE term_taxonomy_id = %s", $ttid);
270
- return $wpdb->get_var($query);
271
- }
272
-
273
- /* Object Utilities
274
- ======================== */
275
-
276
- /**
277
  * @param array $array
278
  * @param string $prop
279
  * @return void
280
  */
281
- public static function osort(&$array, $prop) {
282
- usort($array, function ($a, $b) use ($prop) {
283
- return $a->$prop > $b->$prop ? 1 : -1;
284
- });
285
- }
286
 
287
- /**
288
  * @param array $arr
289
  * @return bool
290
  */
291
- public static function is_array_assoc($arr) {
292
- if (!is_array($arr)) {
293
- return false;
294
- }
295
- return (bool)count(array_filter(array_keys($arr), 'is_string'));
296
- }
297
-
298
- /**
299
  * @param array $array
300
  * @return stdClass
301
  */
302
- public static function array_to_object($array) {
303
- $obj = new stdClass;
304
- foreach ($array as $k => $v) {
305
- if (is_array($v)) {
306
- $obj->{$k} = self::array_to_object($v); //RECURSION
307
- } else {
308
- $obj->{$k} = $v;
309
- }
310
- }
311
- return $obj;
312
- }
313
-
314
- /**
315
  * @param array $array
316
  * @param string $key
317
  * @param mixed $value
318
  * @return bool|int
319
  */
320
- public static function get_object_index_by_property($array, $key, $value) {
321
- if (is_array($array)) {
322
- $i = 0;
323
- foreach ($array as $arr) {
324
- if (is_array($arr)){
325
- if ($arr[$key] == $value){
326
- return $i;
327
- }
328
- } else {
329
- if ($arr->$key == $value) {
330
- return $i;
331
- }
332
- }
333
- $i++;
334
- }
335
- }
336
- return false;
337
- }
338
-
339
- /**
340
  * @param array $array
341
  * @param string $key
342
  * @param mixed $value
343
  * @return array|null
344
  * @throws Exception
345
  */
346
- public static function get_object_by_property($array, $key, $value) {
347
- if (is_array($array)) {
348
- foreach ($array as $arr) {
349
- if ($arr->$key == $value) {
350
- return $arr;
351
- }
352
- }
353
- } else {
354
- throw new Exception('$array is not an array, given value: ' . $array);
355
- }
356
- return null;
357
- }
358
-
359
- /**
360
  * @param array $array
361
  * @param int $len
362
  * @return array
363
  */
364
- public static function array_truncate($array, $len) {
365
- if (sizeof($array) > $len) {
366
- $array = array_splice($array, 0, $len);
367
- }
368
- return $array;
369
- }
370
 
371
- /* Bool Utilities
372
- ======================== */
373
 
374
- /**
375
  * @param mixed $property
376
  * @return bool
377
  */
378
- public static function is_true($property) {
379
- if (isset($property)) {
380
- if ($property == 'true' || $property == 1 || $property == '1' || $property == true) {
381
- return true;
382
- }
383
- }
384
- return false;
385
- }
386
-
387
- /**
388
  * @param int $i
389
  * @return bool
390
  */
391
- public static function iseven($i) {
392
- return ($i % 2) == 0;
393
- }
394
 
395
- /**
396
  * @param int $i
397
  * @return bool
398
  */
399
- public static function isodd($i) {
400
- return ($i % 2) != 0;
401
- }
402
 
403
- /* Links, Forms, Etc. Utilities
404
- ======================== */
405
 
406
- /* this $args thing is a fucking mess, fix at some point:
407
 
408
- http://codex.wordpress.org/Function_Reference/comment_form */
409
 
410
- /**
411
  * @param int $post_id
412
  * @param array $args
413
  * @return string
414
  */
415
- public static function get_comment_form($post_id = null, $args = array()) {
416
- return self::ob_function('comment_form', array($args, $post_id));
417
- }
418
 
419
- /**
420
  * @param string $args
421
  * @return array
422
  */
423
- public static function paginate_links( $args = '' ) {
424
- $defaults = array(
425
- 'base' => '%_%', // http://example.com/all_posts.php%_% : %_% is replaced by format (below)
426
- 'format' => '?page=%#%', // ?page=%#% : %#% is replaced by the page number
427
- 'total' => 1,
428
- 'current' => 0,
429
- 'show_all' => false,
430
- 'prev_next' => true,
431
- 'prev_text' => __('&laquo; Previous'),
432
- 'next_text' => __('Next &raquo;'),
433
- 'end_size' => 1,
434
- 'mid_size' => 2,
435
- 'type' => 'array',
436
- 'add_args' => false, // array of query args to add
437
- 'add_fragment' => ''
438
- );
439
-
440
- $args = wp_parse_args( $args, $defaults );
441
- extract($args, EXTR_SKIP);
442
-
443
- // Who knows what else people pass in $args
444
- $total = (int) $total;
445
- if ( $total < 2 ){
446
- return;
447
- }
448
- $current = (int) $current;
449
- $end_size = 0 < (int) $end_size ? (int) $end_size : 1; // Out of bounds? Make it the default.
450
- $mid_size = 0 <= (int) $mid_size ? (int) $mid_size : 2;
451
- $add_args = is_array($add_args) ? $add_args : false;
452
- $r = '';
453
- $page_links = array();
454
- $n = 0;
455
- $dots = false;
456
- if ( $prev_next && $current && 1 < $current ){
457
- $link = str_replace('%_%', 2 == $current ? '' : $format, $base);
458
- $link = str_replace('%#%', $current - 1, $link);
459
- if ( $add_args ){
460
- $link = add_query_arg( $add_args, $link );
461
- }
462
- $link .= $add_fragment;
463
- $link = untrailingslashit($link);
464
- $page_links[] = array('class' => 'prev page-numbers', 'link' => esc_url( apply_filters( 'paginate_links', $link )), 'title' => $prev_text);
465
- }
466
- for ( $n = 1; $n <= $total; $n++ ) {
467
- $n_display = number_format_i18n($n);
468
- if ( $n == $current ) {
469
- $page_links[] = array('class' => 'page-number page-numbers current', 'title' => $n_display, 'text' => $n_display, 'name' => $n_display, 'current' => true);
470
- $dots = true;
471
- } else {
472
- if ( $show_all || ( $n <= $end_size || ( $current && $n >= $current - $mid_size && $n <= $current + $mid_size ) || $n > $total - $end_size ) ) {
473
- $link = str_replace('%_%', 1 == $n ? '' : $format, $base);
474
- $link = str_replace('%#%', $n, $link);
475
- $link = trailingslashit($link).ltrim($add_fragment, '/');
476
- if ( $add_args ) {
477
- $link = rtrim(add_query_arg( $add_args, $link ), '/');
478
- }
479
- $link = untrailingslashit($link);
480
- $page_links[] = array('class' => 'page-number page-numbers', 'link' => esc_url( apply_filters( 'paginate_links', $link ) ), 'title' => $n_display, 'current' => $current == $n);
481
- $dots = true;
482
- } elseif ( $dots && !$show_all ) {
483
- $page_links[] = array('class' => 'dots', 'title' => __( '&hellip;' ));
484
- $dots = false;
485
- }
486
- }
487
- }
488
- if ( $prev_next && $current && ( $current < $total || -1 == $total ) ) {
489
- $link = str_replace('%_%', $format, $base);
490
- $link = str_replace('%#%', $current + 1, $link);
491
- if ( $add_args ) {
492
- $link = add_query_arg( $add_args, $link );
493
- }
494
- $link = untrailingslashit(trailingslashit($link).$add_fragment);
495
- $page_links[] = array('class' => 'next page-numbers', 'link' => esc_url( apply_filters( 'paginate_links', $link ) ), 'title' => $next_text);
496
- }
497
- return $page_links;
498
- }
499
-
500
- /* LEGACY These have since been re-organized; but keeping linkages for backwards-compatability */
501
-
502
- public static function get_image_path($iid){
503
- return TimberImageHelper::get_image_path($iid);
504
- }
505
-
506
- public static function get_current_url() {
507
- return TimberURLHelper::get_current_url();
508
- }
509
-
510
- public static function is_url($url) {
511
- return TimberURLHelper::is_url($url);
512
- }
513
-
514
- public static function get_path_base() {
515
- return TimberURLHelper::get_path_base();
516
- }
517
-
518
- public static function get_rel_url($url, $force = false){
519
- return TimberURLHelper::get_rel_url($url, $force);
520
- }
521
-
522
- public static function is_local($url){
523
- return TimberURLHelper::is_local($url);
524
- }
525
-
526
- public static function get_full_path($src) {
527
- return TimberURLHelper::get_full_path($src);
528
- }
529
-
530
- public static function get_rel_path($src) {
531
- return TimberURLHelper::get_rel_path($src);
532
- }
533
-
534
- public static function remove_double_slashes($url){
535
- return TimberURLHelper::remove_double_slashes($url);
536
- }
537
-
538
- public static function prepend_to_url($url, $path){
539
- return TimberURLHelper::prepend_to_url($url, $path);
540
- }
541
-
542
- public static function preslashit($path){
543
- return TimberURLHelper::preslashit($path);
544
- }
545
-
546
- public static function is_external($url){
547
- return TimberURLHelper::is_external($url);
548
- }
549
-
550
- public static function download_url($url, $timeout = 300) {
551
- return TimberURLHelper::download_url($url, $timeout);
552
- }
553
-
554
- public static function get_params($i = -1) {
555
- return TimberURLHelper::get_params($i);
556
- }
557
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
558
 
559
  }
560
 
561
- class WPHelper extends TimberHelper {
562
- //for backwards compat, will remove eventually
 
563
  }
1
  <?php
2
 
3
+ class TimberHelper
4
+ {
5
 
6
  /**
7
  * @param string $slug Unique identifier for transient
11
  * @param bool $force (optional) Force callback to be executed when transient is locked
12
  * @return mixed
13
  */
14
+ public static function transient($slug, $callback, $transient_time = 0, $lock_timeout = 5, $force = false) {
15
+ if ($transient_time === false || (defined('WP_DISABLE_TRANSIENTS') && WP_DISABLE_TRANSIENTS)) {
16
  $enable_transients = false;
17
  } else {
18
  $enable_transients = true;
19
  }
20
 
21
+ $data = $enable_transients ? get_transient($slug) : false;
22
 
23
+ if (false === $data) {
24
 
25
+ if ($enable_transients && self::_is_transient_locked($slug)) {
26
 
27
+ $force = apply_filters('timber_force_transients', $force);
28
+ $force = apply_filters('timber_force_transient_' . $slug, $force);
29
 
30
+ if (!$force) {
31
+ //the server is currently executing the process.
32
+ //We're just gonna dump these users. Sorry!
33
  return false;
34
+ }
35
 
36
  $enable_transients = false;
37
  }
38
 
39
  // lock timeout shouldn't be higher than 5 seconds, unless
40
  // remote calls with high timeouts are made here
41
+ if ($enable_transients)
42
+ self::_lock_transient($slug, $lock_timeout);
43
 
44
  $data = $callback();
45
 
46
+ if ($enable_transients) {
47
+ set_transient($slug, $data, $transient_time);
48
+ self::_unlock_transient($slug);
49
  }
50
  }
51
  return $data;
52
  }
53
 
54
+ public static function _lock_transient($slug, $lock_timeout) {
55
+ set_transient($slug . '_lock', true, $lock_timeout);
56
+ }
57
 
58
+ public static function _unlock_transient($slug) {
59
+ delete_transient($slug . '_lock', true);
60
+ }
61
 
62
+ public static function _is_transient_locked($slug) {
63
+ return (bool)get_transient($slug . '_lock');
64
+ }
65
 
66
  /* These are for measuring page render time */
67
 
68
  /**
69
  * @return float
70
  */
71
+ public static function start_timer() {
72
+ $time = microtime();
73
+ $time = explode(' ', $time);
74
+ $time = $time[1] + $time[0];
75
+ return $time;
76
+ }
77
+
78
+ /**
79
  * @param int $start
80
  * @return string
81
  */
82
+ public static function stop_timer($start) {
83
+ $time = microtime();
84
+ $time = explode(' ', $time);
85
+ $time = $time[1] + $time[0];
86
+ $finish = $time;
87
+ $total_time = round(($finish - $start), 4);
88
+ return $total_time . ' seconds.';
89
+ }
90
+
91
+ /* Function Utilities
92
+ ======================== */
93
+
94
+ /**
95
  * @param callback $function
96
  * @param array $args
97
  * @return string
98
  */
99
+ public static function ob_function($function, $args = array(null)) {
100
+ ob_start();
101
+ call_user_func_array($function, $args);
102
+ $data = ob_get_contents();
103
+ ob_end_clean();
104
+ return $data;
105
+ }
106
+
107
+ /**
108
  * @param string $function_name
109
  * @param array $defaults
110
  * @param bool $return_output_buffer
118
  * @param $arg
119
  * @return void
120
  */
121
+ public static function error_log($arg) {
122
+ if (!WP_DEBUG) {
123
+ return;
124
+ }
125
+ if (is_object($arg) || is_array($arg)) {
126
+ $arg = print_r($arg, true);
127
+ }
128
+ error_log($arg);
129
+ }
130
+
131
+ /**
132
+ * @param string $seperator
133
+ * @param string $seplocation
134
  * @return string
135
  */
136
+ public static function get_wp_title($seperator = ' ', $seplocation = 'left') {
137
+ $seperator = apply_filters('timber_wp_title_seperator', $seperator);
138
+ return trim(wp_title($seperator, false, $seplocation));
139
+ }
140
 
141
+ /* Text Utilities
142
+ ======================== */
143
 
144
+ /**
145
  * @param string $text
146
  * @param int $num_words
147
  * @param string $more
148
  * @param string $allowed_tags
149
  * @return string
150
  */
151
+ public static function trim_words($text, $num_words = 55, $more = null, $allowed_tags = 'p a span b i br') {
152
+ if (null === $more) {
153
+ $more = __('&hellip;');
154
+ }
155
+ $original_text = $text;
156
+ $allowed_tag_string = '';
157
+ foreach (explode(' ', $allowed_tags) as $tag) {
158
+ $allowed_tag_string .= '<' . $tag . '>';
159
+ }
160
+ $text = strip_tags($text, $allowed_tag_string);
161
+ /* translators: If your word count is based on single characters (East Asian characters),
162
+ enter 'characters'. Otherwise, enter 'words'. Do not translate into your own language. */
163
+ if ('characters' == _x('words', 'word count: words or characters?') && preg_match('/^utf\-?8$/i', get_option('blog_charset'))) {
164
+ $text = trim(preg_replace("/[\n\r\t ]+/", ' ', $text), ' ');
165
+ preg_match_all('/./u', $text, $words_array);
166
+ $words_array = array_slice($words_array[0], 0, $num_words + 1);
167
+ $sep = '';
168
+ } else {
169
+ $words_array = preg_split("/[\n\r\t ]+/", $text, $num_words + 1, PREG_SPLIT_NO_EMPTY);
170
+ $sep = ' ';
171
+ }
172
+ if (count($words_array) > $num_words) {
173
+ array_pop($words_array);
174
+ $text = implode($sep, $words_array);
175
+ $text = $text . $more;
176
+ } else {
177
+ $text = implode($sep, $words_array);
178
+ }
179
+ $text = self::close_tags($text);
180
+ return apply_filters('wp_trim_words', $text, $num_words, $more, $original_text);
181
+ }
182
+
183
+ /**
184
  * @param string $html
185
  * @return string
186
  */
187
+ public static function close_tags($html) {
188
+ #put all opened tags into an array
189
+ preg_match_all('#<([a-z]+)(?: .*)?(?<![/|/ ])>#iU', $html, $result);
190
+ $openedtags = $result[1];
191
+ #put all closed tags into an array
192
+ preg_match_all('#</([a-z]+)>#iU', $html, $result);
193
+ $closedtags = $result[1];
194
+ $len_opened = count($openedtags);
195
+ # all tags are closed
196
+ if (count($closedtags) == $len_opened) {
197
+ return $html;
198
+ }
199
+ $openedtags = array_reverse($openedtags);
200
+ # close tags
201
+ for ($i = 0; $i < $len_opened; $i++) {
202
+ if (!in_array($openedtags[$i], $closedtags)) {
203
+ $html .= '</' . $openedtags[$i] . '>';
204
+ } else {
205
+ unset($closedtags[array_search($openedtags[$i], $closedtags)]);
206
+ }
207
+ }
208
+ return $html;
209
+ }
210
+
211
+ /**
212
  * @param string $ret
213
  * @return mixed
214
  */
215
+ public static function twitterify($ret) {
216
+ $ret = preg_replace("#(^|[\n ])([\w]+?://[\w]+[^ \"\n\r\t< ]*)#", "\\1<a href=\"\\2\" target=\"_blank\">\\2</a>", $ret);
217
+ $ret = preg_replace("#(^|[\n ])((www|ftp)\.[^ \"\t\n\r< ]*)#", "\\1<a href=\"http://\\2\" target=\"_blank\">\\2</a>", $ret);
218
+ $pattern = '#([0-9a-z]([-_.]?[0-9a-z])*@[0-9a-z]([-.]?[0-9a-z])*\\.';
219
+ $pattern .= '[a-wyz][a-z](fo|g|l|m|mes|o|op|pa|ro|seum|t|u|v|z)?)#i';
220
+ $ret = preg_replace($pattern, '<a href="mailto:\\1">\\1</a>', $ret);
221
+ $ret = preg_replace("/\B@(\w+)/", " <a href=\"http://www.twitter.com/\\1\" target=\"_blank\">@\\1</a>", $ret);
222
+ $ret = preg_replace("/\B#(\w+)/", " <a href=\"http://search.twitter.com/search?q=\\1\" target=\"_blank\">#\\1</a>", $ret);
223
+ return $ret;
224
+ }
225
+
226
+ /* WordPress Query Utilities
227
+ ======================== */
228
+
229
+ /**
230
  * @param string $key
231
  * @param string $value
232
  * @return array|int
233
  */
234
+ public static function get_posts_by_meta($key, $value) {
235
+ global $wpdb;
236
+ $query = $wpdb->prepare("SELECT post_id FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %s", $key, $value);
237
+ $results = $wpdb->get_col($query);
238
+ $pids = array();
239
+ foreach ($results as $result) {
240
+ if (get_post($result)) {
241
+ $pids[] = $result;
242
+ }
243
+ }
244
+ if (count($pids)) {
245
+ return $pids;
246
+ }
247
+ return 0;
248
+ }
249
+
250
+ /**
251
  * @param string $key
252
  * @param string $value
253
  * @return int
254
  */
255
+ public static function get_post_by_meta($key, $value) {
256
+ global $wpdb;
257
+ $query = $wpdb->prepare("SELECT post_id FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %s ORDER BY post_id", $key, $value);
258
+ $results = $wpdb->get_col($query);
259
+ foreach ($results as $result) {
260
+ if ($result && get_post($result)) {
261
+ return $result;
262
+ }
263
+ }
264
+ return 0;
265
+ }
266
+
267
+ /**
268
+ * @param int $ttid
269
+ * @return mixed
270
+ */
271
+ public static function get_term_id_by_term_taxonomy_id($ttid) {
272
+ global $wpdb;
273
+ $query = $wpdb->prepare("SELECT term_id FROM $wpdb->term_taxonomy WHERE term_taxonomy_id = %s", $ttid);
274
+ return $wpdb->get_var($query);
275
+ }
276
+
277
+ /* Object Utilities
278
+ ======================== */
279
+
280
+ /**
281
  * @param array $array
282
  * @param string $prop
283
  * @return void
284
  */
285
+ public static function osort(&$array, $prop) {
286
+ usort($array, function ($a, $b) use ($prop) {
287
+ return $a->$prop > $b->$prop ? 1 : -1;
288
+ });
289
+ }
290
 
291
+ /**
292
  * @param array $arr
293
  * @return bool
294
  */
295
+ public static function is_array_assoc($arr) {
296
+ if (!is_array($arr)) {
297
+ return false;
298
+ }
299
+ return (bool)count(array_filter(array_keys($arr), 'is_string'));
300
+ }
301
+
302
+ /**
303
  * @param array $array
304
  * @return stdClass
305
  */
306
+ public static function array_to_object($array) {
307
+ $obj = new stdClass;
308
+ foreach ($array as $k => $v) {
309
+ if (is_array($v)) {
310
+ $obj->{$k} = self::array_to_object($v); //RECURSION
311
+ } else {
312
+ $obj->{$k} = $v;
313
+ }
314
+ }
315
+ return $obj;
316
+ }
317
+
318
+ /**
319
  * @param array $array
320
  * @param string $key
321
  * @param mixed $value
322
  * @return bool|int
323
  */
324
+ public static function get_object_index_by_property($array, $key, $value) {
325
+ if (is_array($array)) {
326
+ $i = 0;
327
+ foreach ($array as $arr) {
328
+ if (is_array($arr)) {
329
+ if ($arr[$key] == $value) {
330
+ return $i;
331
+ }
332
+ } else {
333
+ if ($arr->$key == $value) {
334
+ return $i;
335
+ }
336
+ }
337
+ $i++;
338
+ }
339
+ }
340
+ return false;
341
+ }
342
+
343
+ /**
344
  * @param array $array
345
  * @param string $key
346
  * @param mixed $value
347
  * @return array|null
348
  * @throws Exception
349
  */
350
+ public static function get_object_by_property($array, $key, $value) {
351
+ if (is_array($array)) {
352
+ foreach ($array as $arr) {
353
+ if ($arr->$key == $value) {
354
+ return $arr;
355
+ }
356
+ }
357
+ } else {
358
+ throw new Exception('$array is not an array, given value: ' . $array);
359
+ }
360
+ return null;
361
+ }
362
+
363
+ /**
364
  * @param array $array
365
  * @param int $len
366
  * @return array
367
  */
368
+ public static function array_truncate($array, $len) {
369
+ if (sizeof($array) > $len) {
370
+ $array = array_splice($array, 0, $len);
371
+ }
372
+ return $array;
373
+ }
374
 
375
+ /* Bool Utilities
376
+ ======================== */
377
 
378
+ /**
379
  * @param mixed $property
380
  * @return bool
381
  */
382
+ public static function is_true($property) {
383
+ if (isset($property)) {
384
+ if ($property == 'true' || $property == 1 || $property == '1' || $property == true) {
385
+ return true;
386
+ }
387
+ }
388
+ return false;
389
+ }
390
+
391
+ /**
392
  * @param int $i
393
  * @return bool
394
  */
395
+ public static function iseven($i) {
396
+ return ($i % 2) == 0;
397
+ }
398
 
399
+ /**
400
  * @param int $i
401
  * @return bool
402
  */
403
+ public static function isodd($i) {
404
+ return ($i % 2) != 0;
405
+ }
406
 
407
+ /* Links, Forms, Etc. Utilities
408
+ ======================== */
409
 
410
+ /* this $args thing is a fucking mess, fix at some point:
411
 
412
+ http://codex.wordpress.org/Function_Reference/comment_form */
413
 
414
+ /**
415
  * @param int $post_id
416
  * @param array $args
417
  * @return string
418
  */
419
+ public static function get_comment_form($post_id = null, $args = array()) {
420
+ return self::ob_function('comment_form', array($args, $post_id));
421
+ }
422
 
423
+ /**
424
  * @param string $args
425
  * @return array
426
  */
427
+ public static function paginate_links($args = '') {
428
+ $defaults = array(
429
+ 'base' => '%_%', // http://example.com/all_posts.php%_% : %_% is replaced by format (below)
430
+ 'format' => '?page=%#%', // ?page=%#% : %#% is replaced by the page number
431
+ 'total' => 1,
432
+ 'current' => 0,
433
+ 'show_all' => false,
434
+ 'prev_next' => true,
435
+ 'prev_text' => __('&laquo; Previous'),
436
+ 'next_text' => __('Next &raquo;'),
437
+ 'end_size' => 1,
438
+ 'mid_size' => 2,
439
+ 'type' => 'array',
440
+ 'add_args' => false, // array of query args to add
441
+ 'add_fragment' => ''
442
+ );
443
+ $args = wp_parse_args($args, $defaults);
444
+ // Who knows what else people pass in $args
445
+ $args['total'] = intval((int)$args['total']);
446
+ if ($args['total'] < 2) {
447
+ return array();
448
+ }
449
+ $args['current'] = (int)$args['current'];
450
+ $args['end_size'] = 0 < (int)$args['end_size'] ? (int)$args['end_size'] : 1; // Out of bounds? Make it the default.
451
+ $args['mid_size'] = 0 <= (int)$args['mid_size'] ? (int)$args['mid_size'] : 2;
452
+ $args['add_args'] = is_array($args['add_args']) ? $args['add_args'] : false;
453
+ $page_links = array();
454
+ $dots = false;
455
+ if ($args['prev_next'] && $args['current'] && 1 < $args['current']) {
456
+ $link = str_replace('%_%', 2 == $args['current'] ? '' : $args['format'], $args['base']);
457
+ $link = str_replace('%#%', $args['current'] - 1, $link);
458
+ if ($args['add_args']) {
459
+ $link = add_query_arg($args['add_args'], $link);
460
+ }
461
+ $link .= $args['add_fragment'];
462
+ $link = untrailingslashit($link);
463
+ $page_links[] = array(
464
+ 'class' => 'prev page-numbers',
465
+ 'link' => esc_url(apply_filters('paginate_links', $link)),
466
+ 'title' => $args['prev_text']
467
+ );
468
+ }
469
+ for ($n = 1; $n <= $args['total']; $n++) {
470
+ $n_display = number_format_i18n($n);
471
+ if ($n == $args['current']) {
472
+ $page_links[] = array(
473
+ 'class' => 'page-number page-numbers current',
474
+ 'title' => $n_display,
475
+ 'text' => $n_display,
476
+ 'name' => $n_display,
477
+ 'current' => true
478
+ );
479
+ $dots = true;
480
+ } else {
481
+ 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'])) {
482
+ $link = str_replace('%_%', 1 == $n ? '' : $args['format'], $args['base']);
483
+ $link = str_replace('%#%', $n, $link);
484
+ $link = trailingslashit($link) . ltrim($args['add_fragment'], '/');
485
+ if ($args['add_args']) {
486
+ $link = rtrim(add_query_arg($args['add_args'], $link), '/');
487
+ }
488
+ $link = untrailingslashit($link);
489
+ $page_links[] = array(
490
+ 'class' => 'page-number page-numbers',
491
+ 'link' => esc_url(apply_filters('paginate_links', $link)),
492
+ 'title' => $n_display,
493
+ 'current' => $args['current'] == $n
494
+ );
495
+ $dots = true;
496
+ } elseif ($dots && !$args['show_all']) {
497
+ $page_links[] = array(
498
+ 'class' => 'dots',
499
+ 'title' => __('&hellip;')
500
+ );
501
+ $dots = false;
502
+ }
503
+ }
504
+ }
505
+ if ($args['prev_next'] && $args['current'] && ($args['current'] < $args['total'] || -1 == $args['total'])) {
506
+ $link = str_replace('%_%', $args['format'], $args['base']);
507
+ $link = str_replace('%#%', $args['current'] + 1, $link);
508
+ if ($args['add_args']) {
509
+ $link = add_query_arg($args['add_args'], $link);
510
+ }
511
+ $link = untrailingslashit(trailingslashit($link) . $args['add_fragment']);
512
+ $page_links[] = array(
513
+ 'class' => 'next page-numbers',
514
+ 'link' => esc_url(apply_filters('paginate_links', $link)),
515
+ 'title' => $args['next_text']
516
+ );
517
+ }
518
+ return $page_links;
519
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
520
 
521
+ /* LEGACY These have since been re-organized; but keeping linkages for backwards-compatability */
522
+
523
+ public static function get_image_path($iid) {
524
+ return TimberImageHelper::get_image_path($iid);
525
+ }
526
+
527
+ public static function get_current_url() {
528
+ return TimberURLHelper::get_current_url();
529
+ }
530
+
531
+ public static function is_url($url) {
532
+ return TimberURLHelper::is_url($url);
533
+ }
534
+
535
+ public static function get_path_base() {
536
+ return TimberURLHelper::get_path_base();
537
+ }
538
+
539
+ public static function get_rel_url($url, $force = false) {
540
+ return TimberURLHelper::get_rel_url($url, $force);
541
+ }
542
+
543
+ public static function is_local($url) {
544
+ return TimberURLHelper::is_local($url);
545
+ }
546
+
547
+ public static function get_full_path($src) {
548
+ return TimberURLHelper::get_full_path($src);
549
+ }
550
+
551
+ public static function get_rel_path($src) {
552
+ return TimberURLHelper::get_rel_path($src);
553
+ }
554
+
555
+ public static function remove_double_slashes($url) {
556
+ return TimberURLHelper::remove_double_slashes($url);
557
+ }
558
+
559
+ public static function prepend_to_url($url, $path) {
560
+ return TimberURLHelper::prepend_to_url($url, $path);
561
+ }
562
+
563
+ public static function preslashit($path) {
564
+ return TimberURLHelper::preslashit($path);
565
+ }
566
+
567
+ public static function is_external($url) {
568
+ return TimberURLHelper::is_external($url);
569
+ }
570
+
571
+ public static function download_url($url, $timeout = 300) {
572
+ return TimberURLHelper::download_url($url, $timeout);
573
+ }
574
+
575
+ public static function get_params($i = -1) {
576
+ return TimberURLHelper::get_params($i);
577
+ }
578
 
579
  }
580
 
581
+ class WPHelper extends TimberHelper
582
+ {
583
+ //for backwards compat, will remove eventually
584
  }
functions/timber-image-helper.php CHANGED
@@ -1,411 +1,507 @@
1
  <?php
2
 
3
- class TimberImageHelper {
 
4
 
5
- public static function add_actions(){
6
- add_action('delete_post', function($post_id){
7
- $post = get_post($post_id);
8
- $image_types = array('image/jpeg', 'image/png', 'image/gif', 'image/jpg');
9
- if ($post->post_type == 'attachment' && in_array($post->post_mime_type, $image_types)){
10
- TimberImageHelper::delete_resized_files_from_url($post->guid);
11
- TimberImageHelper::delete_letterboxed_files_from_url($post->guid);
12
- }
13
- });
14
- }
15
 
16
- /**
17
- * @param string $hexstr
18
- * @return array
19
- */
20
- public static function hexrgb($hexstr) {
21
- if (!strstr($hexstr, '#')){
22
- $hexstr = '#'.$hexstr;
23
- }
24
- if (strlen($hexstr) == 4){
25
- $hexstr = '#' . $hexstr[1] . $hexstr[1] . $hexstr[2] . $hexstr[2] . $hexstr[3] . $hexstr[3];
26
- }
27
- $int = hexdec($hexstr);
28
- return array("red" => 0xFF & ($int >> 0x10), "green" => 0xFF & ($int >> 0x8), "blue" => 0xFF & $int);
29
- }
30
 
31
- static function delete_resized_files_from_url($src){
32
- $local = TimberURLHelper::url_to_file_system($src);
33
- self::delete_resized_files($local);
34
- }
 
 
35
 
36
- static function delete_letterboxed_files_from_url($src){
37
- $local = TimberURLHelper::url_to_file_system($src);
38
- self::delete_letterboxed_files($local);
39
- }
 
 
 
 
 
 
 
 
 
 
40
 
41
- static function delete_resized_files($local_file){
42
- $info = pathinfo($local_file);
43
- $dir = $info['dirname'];
44
- $ext = $info['extension'];
45
- $filename = $info['filename'];
46
- $searcher = '/'.$filename.'-[0-9999999]*';
47
- foreach (glob($dir.$searcher) as $found_file){
48
- $regexdir = str_replace('/', '\/', $dir);
49
- $pattern = '/'.($regexdir).'\/'.$filename.'-[0-9]*x[0-9]*-c-[a-z]*.'.$ext.'/';
50
- $match = preg_match($pattern, $found_file);
51
- //$match = preg_match("/\/srv\/www\/wordpress-develop\/src\/wp-content\/uploads\/2014\/05\/$filename-[0-9]*x[0-9]*-c-[a-z]*.jpg/", $found_file);
52
- //$match = preg_match("/\/srv\/www\/wordpress-develop\/src\/wp-content\/uploads\/2014\/05\/arch-[0-9]*x[0-9]*-c-[a-z]*.jpg/", $filename);
53
- if ($match){
54
- unlink($found_file);
55
- }
56
- }
57
- }
58
 
59
- static function delete_letterboxed_files($local_file){
60
- $info = pathinfo($local_file);
61
- $dir = $info['dirname'];
62
- $ext = $info['extension'];
63
- $filename = $info['filename'];
64
- $searcher = '/'.$filename.'-lbox-[0-9999999]*';
65
- foreach (glob($dir.$searcher) as $found_file){
66
- $regexdir = str_replace('/', '\/', $dir);
67
- $pattern = '/'.($regexdir).'\/'.$filename.'-lbox-[0-9]*x[0-9]*-[a-zA-Z0-9]*.'.$ext.'/';
68
- $match = preg_match($pattern, $found_file);
69
- if ($match){
70
- unlink($found_file);
71
- }
72
- }
73
- }
74
 
75
- /**
76
- * @param string $src
77
- * @param int $w
78
- * @param int $h
79
- * @param string $color
80
- * @return string
81
- */
82
- public static function get_letterbox_file_rel($src, $w, $h, $color) {
83
- $path_parts = pathinfo($src);
84
- $basename = $path_parts['filename'];
85
- $ext = $path_parts['extension'];
86
- $dir = $path_parts['dirname'];
87
- $color = str_replace('#', '', $color);
88
- $newbase = $basename . '-lbox-' . $w . 'x' . $h . '-' . $color;
89
- $new_path = $dir . '/' . $newbase . '.' . $ext;
90
- $new_path = str_replace(home_url(), '', $new_path);
91
- return $new_path;
92
- }
93
 
94
- /**
95
- * @param string $src
96
- * @param int $w
97
- * @param int $h
98
- * @param string $color
99
- * @return string
100
- */
101
- public static function get_letterbox_file_path($src, $w, $h, $color) {
102
- $new_path = self::get_letterbox_file_rel($src, $w, $h, $color);
103
- $new_root_path = ABSPATH . $new_path;
104
- $new_root_path = str_replace('//', '/', $new_root_path);
105
- return $new_root_path;
106
- }
 
 
107
 
108
- /**
109
- * @param string $src
110
- * @param int $w
111
- * @param int $h
112
- * @param string $crop
113
- * @return string
114
- */
115
- public static function get_resize_file_rel($src, $w, $h, $crop){
116
- $path_parts = pathinfo($src);
117
- $basename = $path_parts['filename'];
118
- $ext = $path_parts['extension'];
119
- $dir = $path_parts['dirname'];
120
- $newbase = $basename . '-' . $w . 'x' . $h . '-c-' . ( $crop ? $crop : 'f' ); // Crop will be either user named or f (false)
121
- $new_path = $dir . '/' . $newbase . '.' . $ext;
122
- $new_path = str_replace(home_url(), '', $new_path);
123
- return $new_path;
124
  }
 
 
 
125
 
126
- /**
127
- * @param string $src
128
- * @param int $w
129
- * @param int $h
130
- * @param string $crop
131
- * @return string
132
- */
133
- public static function get_resize_file_path($src, $w, $h, $crop){
134
- $new_path = self::get_resize_file_rel($src, $w, $h, $crop);
135
- $new_root_path = ABSPATH . $new_path;
136
- $new_root_path = TimberURLHelper::remove_double_slashes($new_root_path);
137
- return $new_root_path;
 
 
 
 
 
 
 
 
 
138
  }
 
 
139
 
140
- /**
141
- * @param int $iid
142
- * @return string
143
- */
144
- public static function get_image_path($iid) {
145
- $size = 'full';
146
- $src = wp_get_attachment_image_src($iid, $size);
147
- $src = $src[0];
148
- return self::get_rel_path($src);
149
- }
 
 
 
 
 
150
 
151
- /**
152
- * @param string $src
153
- * @param int $w
154
- * @param int $h
155
- * @param string $color
156
- * @return mixed|null|string
157
- */
158
- public static function letterbox($src, $w, $h, $color = '#000000', $force = false) {
159
- if (strstr($src, 'http') && !strstr($src, home_url())) {
160
- $src = self::sideload_image($src);
161
- }
162
- $abs = false;
163
- if (strstr($src, 'http')){
164
- $abs = true;
165
- }
166
- $new_file_rel = self::get_letterbox_file_rel($src, $w, $h, $color);
167
- $new_root_path = self::get_letterbox_file_path($src, $w, $h, $color);
168
- $old_root_path = ABSPATH . str_replace(home_url(), '', $src);
169
- $old_root_path = str_replace('//', '/', $old_root_path);
170
- $new_root_path = str_replace('//', '/', $new_root_path);
171
- $urlinfo = parse_url($src);
172
- if (file_exists($new_root_path) && !$force) {
173
- if ($abs){
174
- return untrailingslashit(home_url()).$new_file_rel;
175
- } else {
176
- return TimberURLHelper::preslashit($new_file_rel);
177
- }
178
- }
179
- $bg = imagecreatetruecolor($w, $h);
180
- $c = self::hexrgb($color);
181
- $white = imagecolorallocate($bg, $c['red'], $c['green'], $c['blue']);
182
- imagefill($bg, 0, 0, $white);
183
- $image = wp_get_image_editor($old_root_path);
184
- if (!is_wp_error($image)) {
185
- $current_size = $image->get_size();
186
- $ow = $current_size['width'];
187
- $oh = $current_size['height'];
188
- $new_aspect = $w / $h;
189
- $old_aspect = $ow / $oh;
190
- if ($new_aspect > $old_aspect) {
191
- //taller than goal
192
- $h_scale = $h / $oh;
193
- $owt = $ow * $h_scale;
194
- $y = 0;
195
- $x = $w / 2 - $owt / 2;
196
- $oht = $h;
197
- $image->crop(0, 0, $ow, $oh, $owt, $oht);
198
- } else {
199
- $w_scale = $w / $ow;
200
- $oht = $oh * $w_scale;
201
- $x = 0;
202
- $y = $h / 2 - $oht / 2;
203
- $owt = $w;
204
- $image->crop(0, 0, $ow, $oh, $owt, $oht);
205
- }
206
- $image->save($new_root_path);
207
- $func = 'imagecreatefromjpeg';
208
- $ext = pathinfo($new_root_path, PATHINFO_EXTENSION);
209
- if ($ext == 'gif') {
210
- $func = 'imagecreatefromgif';
211
- } else if ($ext == 'png') {
212
- $func = 'imagecreatefrompng';
213
- }
214
- $image = $func($new_root_path);
215
- imagecopy($bg, $image, $x, $y, 0, 0, $owt, $oht);
216
- imagejpeg($bg, $new_root_path);
217
- return TimberURLHelper::get_rel_path($new_root_path);
218
- } else {
219
- TimberHelper::error_log($image);
220
- }
221
- return null;
222
- }
223
 
224
- /**
225
- * @param string $src
226
- * @param string $bghex
227
- * @return string
228
- */
229
- public static function img_to_jpg($src, $bghex = '#FFFFFF'){
230
- $src = str_replace(home_url(), '', $src);
231
- $output = str_replace('.png', '.jpg', $src);
232
- $input_file = ABSPATH . $src;
233
- $output_file = ABSPATH . $output;
234
- if (file_exists($output_file)) {
235
- return $output;
236
- }
237
- $filename = $output;
238
- $input = imagecreatefrompng($input_file);
239
- list($width, $height) = getimagesize($input_file);
240
- $output = imagecreatetruecolor($width, $height);
241
- $c = self::hexrgb($bghex);
242
- $white = imagecolorallocate($output, $c['red'], $c['green'], $c['blue']);
243
- imagefilledrectangle($output, 0, 0, $width, $height, $white);
244
- imagecopy($output, $input, 0, 0, 0, 0, $width, $height);
245
- imagejpeg($output, $output_file);
246
- return $filename;
247
- }
248
 
249
- /**
250
- * @param string $file
251
- * @return string
252
- */
253
- public static function get_sideloaded_file_loc($file){
254
- $upload = wp_upload_dir();
255
- $dir = $upload['path'];
256
- $filename = $file;
257
- $file = parse_url($file);
258
- $path_parts = pathinfo($file['path']);
259
- $basename = md5($filename);
260
- $ext = 'jpg';
261
- if (isset($path_parts['extension'])){
262
- $ext = $path_parts['extension'];
263
- }
264
- return $dir . '/' . $basename. '.' . $ext;
265
- }
266
 
267
- /**
268
- * @param string $file
269
- * @return string
270
- */
271
- public static function sideload_image($file) {
272
- $loc = self::get_sideloaded_file_loc($file);
273
- if (file_exists($loc)){
274
- return str_replace(ABSPATH, '', $loc);
275
- }
276
- // Download file to temp location
277
- if (!function_exists('download_url')){
278
- require_once(ABSPATH.'/wp-admin/includes/file.php');
279
- }
280
- $tmp = download_url($file);
281
- preg_match('/[^\?]+\.(jpe?g|jpe|gif|png)\b/i', $file, $matches);
282
- $file_array['name'] = basename($matches[0]);
283
- $file_array['tmp_name'] = $tmp;
284
- // If error storing temporarily, unlink
285
- if (is_wp_error($tmp)) {
286
- @unlink($file_array['tmp_name']);
287
- $file_array['tmp_name'] = '';
288
- }
289
- // do the validation and storage stuff
290
- $locinfo = pathinfo($loc);
291
- $file = wp_upload_bits($locinfo['basename'], null, file_get_contents($file_array['tmp_name']));
292
- return $file['url'];
293
- }
294
 
295
- /**
296
- * @param string $src
297
- * @param int $w
298
- * @param int $h
299
- * @param string $crop
300
- * @param bool $force_resize
301
- * @return string
302
- */
303
- public static function resize($src, $w, $h = 0, $crop = 'default', $force_resize = false ){
304
- if (empty($src)){
305
- return '';
306
- }
307
- if (strstr($src, 'http') && !strstr($src, home_url())) {
308
- $src = self::sideload_image($src);
309
- }
310
- $abs = false;
311
- if (strstr($src, 'http')){
312
- $abs = true;
313
- }
314
- // Sanitize crop position
315
- $allowed_crop_positions = array( 'default', 'center', 'top', 'bottom', 'left', 'right');
316
- if ( $crop !== false && ! in_array( $crop, $allowed_crop_positions ) ) {
317
- $crop = $allowed_crop_positions[ 0 ];
318
- }
319
- //oh good, it's a relative image in the uploads folder!
320
- $new_path = self::get_resize_file_rel($src, $w, $h, $crop);
321
- $new_root_path = self::get_resize_file_path($src, $w, $h, $crop);
322
- if ($abs){
323
- $old_root_path = ABSPATH . str_replace(home_url(), '', $src);
324
- } else {
325
- $old_root_path = ABSPATH . $src;
326
- }
327
- $old_root_path = TimberURLHelper::remove_double_slashes($old_root_path);
328
- $new_root_path = TimberURLHelper::remove_double_slashes($new_root_path);
329
- if ( file_exists($new_root_path) ) {
330
- if ( $force_resize ) {
331
- // Force resize - warning: will regenerate the image on every pageload, use for testing purposes only!
332
- unlink( $new_root_path );
333
- } else {
334
- if ($abs){
335
- return untrailingslashit(home_url()).$new_path;
336
- } else {
337
- $returning = TimberURLHelper::preslashit($new_path);
338
- return $returning;
339
- }
340
- return $new_path;
341
- }
342
- }
343
- $image = wp_get_image_editor($old_root_path);
344
 
345
- if (!is_wp_error($image)) {
 
 
 
 
 
 
 
 
 
346
 
347
- $current_size = $image->get_size();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
348
 
349
- $src_w = $current_size['width'];
350
- $src_h = $current_size['height'];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
351
 
352
- $src_ratio = $src_w / $src_h;
353
- if ( ! $h ) {
354
- $h = round( $w / $src_ratio);
355
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
356
 
357
- // Get ratios
358
- $dest_ratio = $w / $h;
359
- $src_wt = $src_h * $dest_ratio;
360
- $src_ht = $src_w / $dest_ratio;
 
 
 
 
 
 
 
 
 
 
 
 
 
361
 
362
- if ( ! $crop ) {
363
- // Always crop, to allow resizing upwards
364
- $image->crop( 0, 0, $src_w, $src_h, $w, $h );
365
- } else {
366
- //start with defaults:
367
- $src_x = $src_w / 2 - $src_wt / 2;
368
- $src_y = ( $src_h - $src_ht ) / 6;
369
- //now specific overrides based on options:
370
- if ( $crop == 'center' ) {
371
- // Get source x and y
372
- $src_x = round( ( $src_w - $src_wt ) / 2 );
373
- $src_y = round( ( $src_h - $src_ht ) / 2 );
374
- } else if ($crop == 'top') {
375
- $src_y = 0;
376
- } else if ($crop == 'bottom') {
377
- $src_y = $src_h - $src_ht;
378
- } else if ($crop == 'left') {
379
- $src_x = 0;
380
- } else if ($crop == 'right') {
381
- $src_x = $src_w - $src_wt;
382
- }
 
 
 
 
 
 
383
 
384
- // Crop the image
385
- if ( $dest_ratio > $src_ratio ) {
386
- $image->crop( 0, $src_y, $src_w, $src_ht, $w, $h );
387
- } else {
388
- $image->crop( $src_x, 0, $src_wt, $src_h, $w, $h );
389
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
390
 
391
- }
 
 
 
 
 
 
 
392
 
393
- $result = $image->save($new_root_path);
394
- if (is_wp_error($result)){
395
- error_log('Error resizing image');
396
- error_log(print_r($result, true));
397
- }
398
- if ($abs){
399
- return untrailingslashit(home_url()).$new_path;
400
- }
401
- return $new_path;
402
- } else if (isset($image->error_data['error_loading_image'])) {
403
- TimberHelper::error_log('Error loading '.$image->error_data['error_loading_image']);
404
- } else {
405
- TimberHelper::error_log($image);
406
- }
407
- return $src;
408
- }
409
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
410
 
411
- TimberImageHelper::add_actions();
 
 
1
  <?php
2
 
3
+ class TimberImageHelper
4
+ {
5
 
6
+ static function add_actions() {
7
+ add_action('delete_post', function ($post_id) {
8
+ $post = get_post($post_id);
9
+ $image_types = array('image/jpeg', 'image/png', 'image/gif', 'image/jpg');
10
+ if ($post->post_type == 'attachment' && in_array($post->post_mime_type, $image_types)) {
11
+ TimberImageHelper::delete_resized_files_from_url($post->guid);
12
+ TimberImageHelper::delete_letterboxed_files_from_url($post->guid);
13
+ }
14
+ });
15
+ }
16
 
17
+ /**
18
+ * Adds a constant defining the path to the content directory relative to the site
19
+ * for example /wp-content or /content
20
+ */
21
+ static function add_constants() {
22
+ if (!defined('WP_CONTENT_SUBDIR')) {
23
+ $wp_content_path = str_replace(home_url(), '', WP_CONTENT_URL);
24
+ define('WP_CONTENT_SUBDIR', $wp_content_path);
25
+ }
26
+ }
 
 
 
 
27
 
28
+ static function add_filters() {
29
+ add_filter('upload_dir', function ($arr) {
30
+ $arr['relative'] = str_replace(home_url(), '', $arr['baseurl']);
31
+ return $arr;
32
+ });
33
+ }
34
 
35
+ /**
36
+ * @param string $hexstr
37
+ * @return array
38
+ */
39
+ public static function hexrgb($hexstr) {
40
+ if (!strstr($hexstr, '#')) {
41
+ $hexstr = '#' . $hexstr;
42
+ }
43
+ if (strlen($hexstr) == 4) {
44
+ $hexstr = '#' . $hexstr[1] . $hexstr[1] . $hexstr[2] . $hexstr[2] . $hexstr[3] . $hexstr[3];
45
+ }
46
+ $int = hexdec($hexstr);
47
+ return array("red" => 0xFF & ($int >> 0x10), "green" => 0xFF & ($int >> 0x8), "blue" => 0xFF & $int);
48
+ }
49
 
50
+ static function delete_resized_files_from_url($src) {
51
+ $local = TimberURLHelper::url_to_file_system($src);
52
+ self::delete_resized_files($local);
53
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
54
 
55
+ static function delete_letterboxed_files_from_url($src) {
56
+ $local = TimberURLHelper::url_to_file_system($src);
57
+ self::delete_letterboxed_files($local);
58
+ }
 
 
 
 
 
 
 
 
 
 
 
59
 
60
+ static function delete_resized_files($local_file) {
61
+ $info = pathinfo($local_file);
62
+ $dir = $info['dirname'];
63
+ $ext = $info['extension'];
64
+ $filename = $info['filename'];
65
+ $searcher = '/' . $filename . '-[0-9999999]*';
66
+ foreach (glob($dir . $searcher) as $found_file) {
67
+ $regexdir = str_replace('/', '\/', $dir);
68
+ $pattern = '/' . ($regexdir) . '\/' . $filename . '-[0-9]*x[0-9]*-c-[a-z]*.' . $ext . '/';
69
+ $match = preg_match($pattern, $found_file);
70
+ //keeping these here so I know what the hell we're matching
71
+ //$match = preg_match("/\/srv\/www\/wordpress-develop\/src\/wp-content\/uploads\/2014\/05\/$filename-[0-9]*x[0-9]*-c-[a-z]*.jpg/", $found_file);
72
+ //$match = preg_match("/\/srv\/www\/wordpress-develop\/src\/wp-content\/uploads\/2014\/05\/arch-[0-9]*x[0-9]*-c-[a-z]*.jpg/", $filename);
73
+ if ($match) {
74
+ unlink($found_file);
75
+ }
76
+ }
77
+ }
78
 
79
+ static function delete_letterboxed_files($local_file) {
80
+ $info = pathinfo($local_file);
81
+ $dir = $info['dirname'];
82
+ $ext = $info['extension'];
83
+ $filename = $info['filename'];
84
+ $searcher = '/' . $filename . '-lbox-[0-9999999]*';
85
+ foreach (glob($dir . $searcher) as $found_file) {
86
+ $regexdir = str_replace('/', '\/', $dir);
87
+ $pattern = '/' . ($regexdir) . '\/' . $filename . '-lbox-[0-9]*x[0-9]*-[a-zA-Z0-9]*.' . $ext . '/';
88
+ $match = preg_match($pattern, $found_file);
89
+ if ($match) {
90
+ unlink($found_file);
91
+ }
92
+ }
93
+ }
94
 
95
+ /**
96
+ * @param string $src
97
+ * @param int $w
98
+ * @param int $h
99
+ * @param string $color
100
+ * @return string
101
+ */
102
+ public static function get_letterbox_file_rel($src, $w, $h, $color) {
103
+ if (!strlen($src)) {
104
+ return null;
 
 
 
 
 
 
105
  }
106
+ $new_path = self::get_letterbox_file_name_relative_to_content($src, $w, $h, $color);
107
+ return WP_CONTENT_SUBDIR . $new_path;
108
+ }
109
 
110
+ /**
111
+ * @param string $src The src of an image can be absolute, relative or server location
112
+ * @return mixed|null
113
+ */
114
+ static function get_directory_relative_to_content($src) {
115
+ if (!strlen($src)) {
116
+ return null;
117
+ }
118
+ if (!strlen($src)) {
119
+ return null;
120
+ }
121
+ $abs = false;
122
+ if (strstr($src, 'http')) {
123
+ $abs = true;
124
+ }
125
+ $path_parts = pathinfo($src);
126
+ if ($abs) {
127
+ $dir_relative_to_content = str_replace(WP_CONTENT_URL, '', $path_parts['dirname']);
128
+ } else {
129
+ $dir_relative_to_content = str_replace(WP_CONTENT_DIR, '', $path_parts['dirname']);
130
+ $dir_relative_to_content = str_replace(WP_CONTENT_SUBDIR, '', $dir_relative_to_content);
131
  }
132
+ return $dir_relative_to_content;
133
+ }
134
 
135
+ /**
136
+ * @param string $src
137
+ * @param int $w
138
+ * @param int $h
139
+ * @param $color
140
+ * @return string
141
+ */
142
+ static function get_letterbox_file_name_relative_to_content($src, $w, $h, $color) {
143
+ $path_parts = pathinfo($src);
144
+ $dir_relative_to_content = self::get_directory_relative_to_content($src);
145
+ $color = str_replace('#', '', $color);
146
+ $newbase = $path_parts['filename'] . '-lbox-' . $w . 'x' . $h . '-' . $color;
147
+ $new_name = $newbase . '.' . $path_parts['extension'];
148
+ return $dir_relative_to_content . '/' . $new_name;
149
+ }
150
 
151
+ /**
152
+ * @param string $src
153
+ * @param int $w
154
+ * @param int $h
155
+ * @param string $color
156
+ * @return string
157
+ */
158
+ public static function get_letterbox_file_path($src, $w, $h, $color) {
159
+ $new_name = self::get_letterbox_file_name_relative_to_content($src, $w, $h, $color);
160
+ $new_server_path = WP_CONTENT_DIR . $new_name;
161
+ $new_server_path = TimberURLHelper::remove_double_slashes($new_server_path);
162
+ return $new_server_path;
163
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
 
165
+ /**
166
+ * @param string $src
167
+ * @param int $w
168
+ * @param int $h
169
+ * @param string $crop
170
+ * @return string
171
+ */
172
+ static function get_resize_file_rel($src, $w, $h, $crop) {
173
+ if (!strlen($src)) {
174
+ return null;
175
+ }
176
+ $new_path = self::get_resize_file_name_relative_to_content($src, $w, $h, $crop);
177
+ return WP_CONTENT_SUBDIR . $new_path;
178
+ }
 
 
 
 
 
 
 
 
 
 
179
 
180
+ /**
181
+ * @param string $src
182
+ * @param int $w
183
+ * @param int $h
184
+ * @param string $crop
185
+ * @return string
186
+ */
187
+ static function get_resize_file_name_relative_to_content($src, $w, $h, $crop) {
188
+ $path_parts = pathinfo($src);
189
+ $dir_relative_to_content = self::get_directory_relative_to_content($src);
190
+ $newbase = $path_parts['filename'] . '-' . $w . 'x' . $h . '-c-' . ($crop ? $crop : 'f'); // Crop will be either user named or f (false)
191
+ $new_name = $newbase . '.' . $path_parts['extension'];
192
+ return $dir_relative_to_content . '/' . $new_name;
193
+ }
 
 
 
194
 
195
+ public static function in_uploads($src) {
196
+ $upload_dir = wp_upload_dir();
197
+ if (strstr($src, $upload_dir['relative'])) {
198
+ return true;
199
+ }
200
+ return false;
201
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202
 
203
+ /**
204
+ * @param string $src
205
+ * @param int $w
206
+ * @param int $h
207
+ * @param string $crop
208
+ * @return string
209
+ */
210
+ static function get_resize_file_path($src, $w, $h, $crop) {
211
+ $new_name = self::get_resize_file_name_relative_to_content($src, $w, $h, $crop);
212
+ $new_server_path = WP_CONTENT_DIR . $new_name;
213
+ $new_server_path = TimberURLHelper::remove_double_slashes($new_server_path);
214
+ return $new_server_path;
215
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
216
 
217
+ /**
218
+ * @param int $iid
219
+ * @return string
220
+ */
221
+ public static function get_image_path($iid) {
222
+ $size = 'full';
223
+ $src = wp_get_attachment_image_src($iid, $size);
224
+ $src = $src[0];
225
+ return self::get_rel_path($src);
226
+ }
227
 
228
+ public static function get_server_location($url) {
229
+ $upload_dir = wp_upload_dir();
230
+ $abs = false;
231
+ if (strstr($url, 'http')) {
232
+ $abs = true;
233
+ }
234
+ if (self::in_uploads($url)) {
235
+ if ($abs) {
236
+ $relative_to_uploads_dir = str_replace($upload_dir['baseurl'], '', $url);
237
+ } else {
238
+ $relative_to_uploads_dir = str_replace($upload_dir['relative'], '', $url);
239
+ }
240
+ return $upload_dir['basedir'] . $relative_to_uploads_dir;
241
+ } else {
242
+ if ($abs) {
243
+ $relative_to_wp_content = str_replace(WP_CONTENT_URL, '', $url);
244
+ } else {
245
+ $relative_to_wp_content = str_replace(WP_CONTENT_SUBDIR, '', $url);
246
+ }
247
+ return WP_CONTENT_DIR . $relative_to_wp_content;
248
+ }
249
+ }
250
 
251
+ /**
252
+ * @param string $src
253
+ * @param int $w
254
+ * @param int $h
255
+ * @param string $color
256
+ * @param bool $force
257
+ * @return mixed|null|string
258
+ */
259
+ public static function letterbox($src, $w, $h, $color = '#000000', $force = false) {
260
+ if (strstr($src, 'http') && !strstr($src, home_url())) {
261
+ $src = self::sideload_image($src);
262
+ }
263
+ $abs = false;
264
+ if (strstr($src, 'http')) {
265
+ $abs = true;
266
+ }
267
+ $new_file_rel = self::get_letterbox_file_rel($src, $w, $h, $color);
268
+ $new_server_path = self::get_letterbox_file_path($src, $w, $h, $color);
269
+ $old_server_path = self::get_server_location($src);
270
+ $old_server_path = TimberURLHelper::remove_double_slashes($old_server_path);
271
+ $new_server_path = TimberURLHelper::remove_double_slashes($new_server_path);
272
+ if (file_exists($new_server_path) && !$force) {
273
+ if ($abs) {
274
+ return untrailingslashit(home_url()) . $new_file_rel;
275
+ } else {
276
+ return TimberURLHelper::preslashit($new_file_rel);
277
+ }
278
+ }
279
+ $bg = imagecreatetruecolor($w, $h);
280
+ $c = self::hexrgb($color);
281
+ $white = imagecolorallocate($bg, $c['red'], $c['green'], $c['blue']);
282
+ imagefill($bg, 0, 0, $white);
283
+ $image = wp_get_image_editor($old_server_path);
284
+ if (!is_wp_error($image)) {
285
+ $current_size = $image->get_size();
286
+ $ow = $current_size['width'];
287
+ $oh = $current_size['height'];
288
+ $new_aspect = $w / $h;
289
+ $old_aspect = $ow / $oh;
290
+ if ($new_aspect > $old_aspect) {
291
+ //taller than goal
292
+ $h_scale = $h / $oh;
293
+ $owt = $ow * $h_scale;
294
+ $y = 0;
295
+ $x = $w / 2 - $owt / 2;
296
+ $oht = $h;
297
+ $image->crop(0, 0, $ow, $oh, $owt, $oht);
298
+ } else {
299
+ $w_scale = $w / $ow;
300
+ $oht = $oh * $w_scale;
301
+ $x = 0;
302
+ $y = $h / 2 - $oht / 2;
303
+ $owt = $w;
304
+ $image->crop(0, 0, $ow, $oh, $owt, $oht);
305
+ }
306
+ $image->save($new_server_path);
307
+ $func = 'imagecreatefromjpeg';
308
+ $ext = pathinfo($new_server_path, PATHINFO_EXTENSION);
309
+ if ($ext == 'gif') {
310
+ $func = 'imagecreatefromgif';
311
+ } else if ($ext == 'png') {
312
+ $func = 'imagecreatefrompng';
313
+ }
314
+ $image = $func($new_server_path);
315
+ imagecopy($bg, $image, $x, $y, 0, 0, $owt, $oht);
316
+ imagejpeg($bg, $new_server_path);
317
+ $new_relative_path = TimberURLHelper::get_rel_path($new_server_path);
318
+ if ($abs) {
319
+ return home_url($new_relative_path);
320
+ }
321
+ return $new_relative_path;
322
+ } else {
323
+ TimberHelper::error_log($image);
324
+ }
325
+ return null;
326
+ }
327
 
328
+ /**
329
+ * @param string $src
330
+ * @param string $bghex
331
+ * @return string
332
+ */
333
+ public static function img_to_jpg($src, $bghex = '#FFFFFF') {
334
+ $src = str_replace(home_url(), '', $src);
335
+ $output = str_replace('.png', '.jpg', $src);
336
+ $input_file = ABSPATH . $src;
337
+ $output_file = ABSPATH . $output;
338
+ if (file_exists($output_file)) {
339
+ return $output;
340
+ }
341
+ $filename = $output;
342
+ $input = imagecreatefrompng($input_file);
343
+ list($width, $height) = getimagesize($input_file);
344
+ $output = imagecreatetruecolor($width, $height);
345
+ $c = self::hexrgb($bghex);
346
+ $white = imagecolorallocate($output, $c['red'], $c['green'], $c['blue']);
347
+ imagefilledrectangle($output, 0, 0, $width, $height, $white);
348
+ imagecopy($output, $input, 0, 0, 0, 0, $width, $height);
349
+ imagejpeg($output, $output_file);
350
+ return $filename;
351
+ }
352
 
353
+ /**
354
+ * @param string $file
355
+ * @return string
356
+ */
357
+ public static function get_sideloaded_file_loc($file) {
358
+ $upload = wp_upload_dir();
359
+ $dir = $upload['path'];
360
+ $filename = $file;
361
+ $file = parse_url($file);
362
+ $path_parts = pathinfo($file['path']);
363
+ $basename = md5($filename);
364
+ $ext = 'jpg';
365
+ if (isset($path_parts['extension'])) {
366
+ $ext = $path_parts['extension'];
367
+ }
368
+ return $dir . '/' . $basename . '.' . $ext;
369
+ }
370
 
371
+ /**
372
+ * @param string $file
373
+ * @return string
374
+ */
375
+ public static function sideload_image($file) {
376
+ $loc = self::get_sideloaded_file_loc($file);
377
+ if (file_exists($loc)) {
378
+ return TimberURLHelper::preslashit(TimberURLHelper::get_rel_path($loc));
379
+ }
380
+ // Download file to temp location
381
+ if (!function_exists('download_url')) {
382
+ require_once(ABSPATH . '/wp-admin/includes/file.php');
383
+ }
384
+ $tmp = download_url($file);
385
+ preg_match('/[^\?]+\.(jpe?g|jpe|gif|png)\b/i', $file, $matches);
386
+ $file_array['name'] = basename($matches[0]);
387
+ $file_array['tmp_name'] = $tmp;
388
+ // If error storing temporarily, unlink
389
+ if (is_wp_error($tmp)) {
390
+ @unlink($file_array['tmp_name']);
391
+ $file_array['tmp_name'] = '';
392
+ }
393
+ // do the validation and storage stuff
394
+ $locinfo = pathinfo($loc);
395
+ $file = wp_upload_bits($locinfo['basename'], null, file_get_contents($file_array['tmp_name']));
396
+ return $file['url'];
397
+ }
398
 
399
+ /**
400
+ * @param string $src
401
+ * @param int $w
402
+ * @param int $h
403
+ * @param string $crop
404
+ * @param bool $force_resize
405
+ * @return string
406
+ */
407
+ public static function resize($src, $w, $h = 0, $crop = 'default', $force_resize = false) {
408
+ if (empty($src)) {
409
+ return '';
410
+ }
411
+ if (strstr($src, 'http') && !strstr($src, home_url())) {
412
+ $src = self::sideload_image($src);
413
+ }
414
+ $abs = false;
415
+ if (strstr($src, 'http')) {
416
+ $abs = true;
417
+ }
418
+ // Sanitize crop position
419
+ $allowed_crop_positions = array('default', 'center', 'top', 'bottom', 'left', 'right');
420
+ if ($crop !== false && !in_array($crop, $allowed_crop_positions)) {
421
+ $crop = $allowed_crop_positions[0];
422
+ }
423
+ //oh good, it's a relative image in the uploads folder!
424
+ $new_path = self::get_resize_file_rel($src, $w, $h, $crop);
425
+ $new_server_path = self::get_resize_file_path($src, $w, $h, $crop);
426
+ $old_server_path = self::get_server_location($src);
427
+ $old_server_path = TimberURLHelper::remove_double_slashes($old_server_path);
428
+ $new_server_path = TimberURLHelper::remove_double_slashes($new_server_path);
429
+ if (file_exists($new_server_path)) {
430
+ if ($force_resize) {
431
+ // Force resize - warning: will regenerate the image on every pageload, use for testing purposes only!
432
+ unlink($new_server_path);
433
+ } else {
434
+ if (!$abs) {
435
+ return TimberURLHelper::preslashit($new_path);
436
+ }
437
+ return untrailingslashit(home_url()) . $new_path;
438
+ }
439
+ }
440
+ $image = wp_get_image_editor($old_server_path);
441
+
442
+ if (!is_wp_error($image)) {
443
+ $current_size = $image->get_size();
444
+
445
+ $src_w = $current_size['width'];
446
+ $src_h = $current_size['height'];
447
 
448
+ $src_ratio = $src_w / $src_h;
449
+ if (!$h) {
450
+ $h = round($w / $src_ratio);
451
+ }
452
+ // Get ratios
453
+ $dest_ratio = $w / $h;
454
+ $src_wt = $src_h * $dest_ratio;
455
+ $src_ht = $src_w / $dest_ratio;
456
 
457
+ if (!$crop) {
458
+ // Always crop, to allow resizing upwards
459
+ $image->crop(0, 0, $src_w, $src_h, $w, $h);
460
+ } else {
461
+ //start with defaults:
462
+ $src_x = $src_w / 2 - $src_wt / 2;
463
+ $src_y = ($src_h - $src_ht) / 6;
464
+ //now specific overrides based on options:
465
+ if ($crop == 'center') {
466
+ // Get source x and y
467
+ $src_x = round(($src_w - $src_wt) / 2);
468
+ $src_y = round(($src_h - $src_ht) / 2);
469
+ } else if ($crop == 'top') {
470
+ $src_y = 0;
471
+ } else if ($crop == 'bottom') {
472
+ $src_y = $src_h - $src_ht;
473
+ } else if ($crop == 'left') {
474
+ $src_x = 0;
475
+ } else if ($crop == 'right') {
476
+ $src_x = $src_w - $src_wt;
477
+ }
478
+
479
+ // Crop the image
480
+ if ($dest_ratio > $src_ratio) {
481
+ $image->crop(0, $src_y, $src_w, $src_ht, $w, $h);
482
+ } else {
483
+ $image->crop($src_x, 0, $src_wt, $src_h, $w, $h);
484
+ }
485
+
486
+ }
487
+ $result = $image->save($new_server_path);
488
+ if (is_wp_error($result)) {
489
+ error_log('Error resizing image');
490
+ error_log(print_r($result, true));
491
+ }
492
+ if ($abs) {
493
+ return untrailingslashit(home_url()) . $new_path;
494
+ }
495
+ return $new_path;
496
+ } else if (isset($image->error_data['error_loading_image'])) {
497
+ TimberHelper::error_log('Error loading ' . $image->error_data['error_loading_image']);
498
+ } else {
499
+ TimberHelper::error_log($image);
500
+ }
501
+ return $src;
502
+ }
503
+ }
504
 
505
+ TimberImageHelper::add_constants();
506
+ TimberImageHelper::add_actions();
507
+ TimberImageHelper::add_filters();
functions/timber-image.php CHANGED
@@ -1,125 +1,135 @@
1
  <?php
2
 
3
- class TimberImage extends TimberCore {
 
4
 
5
- var $_can_edit;
6
- var $_dimensions;
7
- var $abs_url;
8
- var $PostClass = 'TimberPost';
9
- var $object_type = 'image';
10
 
11
- public static $representation = 'image';
 
 
 
 
 
12
 
13
  /**
14
  * @param int $iid
15
  */
16
  function __construct($iid) {
17
- $this->init($iid);
18
- }
19
 
20
  /**
21
  * @return string
22
  */
23
  function __toString() {
24
- if ($this->get_src()){
25
- return $this->get_src();
26
- }
27
- return '';
28
- }
29
 
30
  /**
31
  * @return mixed
32
  */
33
- function get_pathinfo(){
34
- return pathinfo($this->file);
35
- }
36
 
37
  /**
38
  * @param string $dim
39
  * @return array|int
40
  */
41
- function get_dimensions($dim = null){
42
- if (isset($this->_dimensions)){
43
- return $this->get_dimensions_loaded($dim);
44
- }
45
- list($width, $height) = getimagesize($this->file_loc);
46
- $this->_dimensions = array();
47
- $this->_dimensions[0] = $width;
48
- $this->_dimensions[1] = $height;
49
- TimberHelper::error_log($this->_dimensions);
50
- return $this->get_dimensions_loaded($dim);
51
- }
52
 
53
  /**
54
  * @param string $dim
55
  * @return array|int
56
  */
57
- function get_dimensions_loaded($dim){
58
- if ($dim == null){
59
- return $this->_dimensions;
60
- }
61
- if ($dim == 'w' || $dim == 'width'){
62
- return $this->_dimensions[0];
63
- }
64
- if ($dim == 'h' || $dim == 'height'){
65
- return $this->_dimensions[1];
66
- }
67
- }
 
68
 
69
  /**
70
  * @return int
71
  */
72
- function get_width(){
73
- return $this->get_dimensions('width');
74
- }
75
 
76
  /**
77
  * @return int
78
  */
79
- function get_height(){
80
- return $this->get_dimensions('height');
81
- }
82
 
83
  /**
84
  * @param string $size
85
  * @return bool|string
86
  */
87
- function get_src( $size = '' ) {
88
- if (isset($this->abs_url)) {
89
- return $this->_maybe_secure_url( $this->abs_url );
90
- }
91
 
92
  if ($size && is_string($size) && isset($this->sizes[$size])) {
93
- $image = image_downsize($this->ID, $size);
94
- return $this->_maybe_secure_url( reset($image) );
95
  }
96
 
97
  if (!isset($this->file) && isset($this->_wp_attached_file)) {
98
- $this->file = $this->_wp_attached_file;
99
- }
100
 
101
- if (!isset($this->file))
102
  return false;
 
103
 
104
  $dir = self::wp_upload_dir();
105
  $base = ($dir["baseurl"]);
106
 
107
- $src = trailingslashit( $this->_maybe_secure_url( $base ) ) . $this->file;
108
- return apply_filters('timber_image_src', $src);
109
- }
110
-
111
- private static function _maybe_secure_url( $url ) {
112
- if ( is_ssl() && strpos( $url, 'https' ) !== 0 && strpos( $url, 'http' ) === 0 )
113
- $url = 'https' . substr( $url, strlen( 'http' ) );
114
 
115
- return $url;
 
 
116
  }
117
 
 
 
 
118
  public static function wp_upload_dir() {
119
  static $wp_upload_dir = false;
120
 
121
- if ( !$wp_upload_dir )
122
  $wp_upload_dir = wp_upload_dir();
 
123
 
124
  return $wp_upload_dir;
125
  }
@@ -128,142 +138,143 @@ class TimberImage extends TimberCore {
128
  * @return string
129
  */
130
  function get_path() {
131
- if (strlen($this->abs_url)) {
132
- return $this->abs_url;
133
- }
134
- return get_permalink($this->ID);
135
- }
136
 
137
  /**
138
  * @return bool|TimberImage
139
  */
140
  function get_parent() {
141
- if (!$this->post_parent) {
142
- return false;
143
- }
144
- return new $this->PostClass($this->post_parent);
145
- }
146
 
147
- function get_alt() {
148
- $alt = trim(strip_tags(get_post_meta($this->ID, '_wp_attachment_image_alt', true)));
149
- return $alt;
150
- }
151
 
152
 
153
  /**
154
  * @param int $iid
155
  */
156
  function init($iid) {
157
- if (!is_numeric($iid) && is_string($iid)) {
158
- if (strstr($iid, '://')) {
159
- $this->init_with_url($iid);
160
- return;
161
- } else if (strstr(strtolower($iid), '.jpg')) {
162
- $this->init_with_url($iid);
163
- }
164
- }
165
- $image_info = $iid;
166
- if (is_numeric($iid)) {
167
- $image_info = wp_get_attachment_metadata($iid);
168
- if (!is_array($image_info)) {
169
- $image_info = array();
170
- }
171
- $image_custom = get_post_custom($iid);
172
- $basic = get_post($iid);
173
- if ($basic){
174
- if (isset($basic->post_excerpt)){
175
- $this->caption = $basic->post_excerpt;
176
- }
177
- $image_custom = array_merge($image_custom, get_object_vars($basic));
178
- }
179
- $image_info = array_merge($image_info, $image_custom);
180
- } else if (is_array($image_info) && isset($image_info['image'])) {
181
- $image_info = $image_info['image'];
182
- } else if (is_object($image_info)) {
183
- $image_info = get_object_vars($image_info);
184
- }
185
- $this->import($image_info);
186
- $basedir = self::wp_upload_dir();
187
- $basedir = $basedir['basedir'];
188
- if (isset($this->file)){
189
- $this->file_loc = $basedir . DIRECTORY_SEPARATOR . $this->file;
190
- } else if (isset($this->_wp_attached_file)){
191
- $this->file = reset($this->_wp_attached_file);
192
- $this->file_loc = $basedir . DIRECTORY_SEPARATOR . $this->file;
193
- }
194
- if (isset($image_info['id'])) {
195
- $this->ID = $image_info['id'];
196
- } else if (is_numeric($iid)) {
197
- $this->ID = $iid;
198
- }
199
- if (isset($this->ID)) {
200
- $custom = get_post_custom($this->ID);
201
- foreach ($custom as $key => $value) {
202
- $this->$key = $value[0];
203
- }
204
- } else {
205
- if (is_array($iid)){
206
- TimberHelper::error_log('Not able to init in TimberImage with iid=');
207
- TimberHelper::error_log($iid);
208
- } else {
209
- TimberHelper::error_log('Not able to init in TimberImage with iid=' . $iid);
210
- }
211
- }
212
- }
213
 
214
  /**
215
  * @param string $url
216
  */
217
  function init_with_url($url) {
218
- $this->abs_url = $url;
219
- $this->file_loc = $url;
220
- if (TimberURLHelper::is_local($url)){
221
- $this->file = ABSPATH . TimberURLHelper::get_rel_url($url);
222
- }
223
- }
224
 
225
  /**
226
  * @deprecated
227
  * @return string
228
  */
229
  function get_url() {
230
- return $this->get_src();
231
- }
232
 
233
- /* Alias */
234
 
235
  /**
236
  * @return float
237
  */
238
- public function aspect(){
239
- $w = intval($this->width());
240
- $h = intval($this->height());
241
- return $w/$h;
242
- }
243
 
244
  /**
245
  * @return int
246
  */
247
- public function height(){
248
- return $this->get_height();
249
- }
250
 
251
  /**
252
  * @param string $size
253
  * @return bool|string
254
  */
255
  public function src($size = '') {
256
- return $this->get_src($size);
257
- }
258
 
259
  /**
260
  * @return int
261
  */
262
- public function width(){
263
- return $this->get_width();
264
- }
 
 
 
 
265
 
266
- public function alt(){
267
- return $this->get_alt();
268
- }
269
  }
1
  <?php
2
 
3
+ class TimberImage extends TimberCore
4
+ {
5
 
6
+ public $_can_edit;
7
+ public $_dimensions;
8
+ public $abs_url;
9
+ public $PostClass = 'TimberPost';
10
+ public $object_type = 'image';
11
 
12
+ public static $representation = 'image';
13
+
14
+ public $file_loc;
15
+ public $file;
16
+ public $sizes = array();
17
+ public $post_parent;
18
 
19
  /**
20
  * @param int $iid
21
  */
22
  function __construct($iid) {
23
+ $this->init($iid);
24
+ }
25
 
26
  /**
27
  * @return string
28
  */
29
  function __toString() {
30
+ if ($this->get_src()) {
31
+ return $this->get_src();
32
+ }
33
+ return '';
34
+ }
35
 
36
  /**
37
  * @return mixed
38
  */
39
+ function get_pathinfo() {
40
+ return pathinfo($this->file);
41
+ }
42
 
43
  /**
44
  * @param string $dim
45
  * @return array|int
46
  */
47
+ function get_dimensions($dim = null) {
48
+ if (isset($this->_dimensions)) {
49
+ return $this->get_dimensions_loaded($dim);
50
+ }
51
+ list($width, $height) = getimagesize($this->file_loc);
52
+ $this->_dimensions = array();
53
+ $this->_dimensions[0] = $width;
54
+ $this->_dimensions[1] = $height;
55
+ TimberHelper::error_log($this->_dimensions);
56
+ return $this->get_dimensions_loaded($dim);
57
+ }
58
 
59
  /**
60
  * @param string $dim
61
  * @return array|int
62
  */
63
+ function get_dimensions_loaded($dim) {
64
+ if ($dim == null) {
65
+ return $this->_dimensions;
66
+ }
67
+ if ($dim == 'w' || $dim == 'width') {
68
+ return $this->_dimensions[0];
69
+ }
70
+ if ($dim == 'h' || $dim == 'height') {
71
+ return $this->_dimensions[1];
72
+ }
73
+ return null;
74
+ }
75
 
76
  /**
77
  * @return int
78
  */
79
+ function get_width() {
80
+ return $this->get_dimensions('width');
81
+ }
82
 
83
  /**
84
  * @return int
85
  */
86
+ function get_height() {
87
+ return $this->get_dimensions('height');
88
+ }
89
 
90
  /**
91
  * @param string $size
92
  * @return bool|string
93
  */
94
+ function get_src($size = '') {
95
+ if (isset($this->abs_url)) {
96
+ return $this->_maybe_secure_url($this->abs_url);
97
+ }
98
 
99
  if ($size && is_string($size) && isset($this->sizes[$size])) {
100
+ $image = image_downsize($this->ID, $size);
101
+ return $this->_maybe_secure_url(reset($image));
102
  }
103
 
104
  if (!isset($this->file) && isset($this->_wp_attached_file)) {
105
+ $this->file = $this->_wp_attached_file;
106
+ }
107
 
108
+ if (!isset($this->file)) {
109
  return false;
110
+ }
111
 
112
  $dir = self::wp_upload_dir();
113
  $base = ($dir["baseurl"]);
114
 
115
+ $src = trailingslashit($this->_maybe_secure_url($base)) . $this->file;
116
+ return apply_filters('timber_image_src', $src);
117
+ }
 
 
 
 
118
 
119
+ private static function _maybe_secure_url($url) {
120
+ if (is_ssl() && strpos($url, 'https') !== 0 && strpos($url, 'http') === 0) {
121
+ $url = 'https' . substr($url, strlen('http'));
122
  }
123
 
124
+ return $url;
125
+ }
126
+
127
  public static function wp_upload_dir() {
128
  static $wp_upload_dir = false;
129
 
130
+ if (!$wp_upload_dir) {
131
  $wp_upload_dir = wp_upload_dir();
132
+ }
133
 
134
  return $wp_upload_dir;
135
  }
138
  * @return string
139
  */
140
  function get_path() {
141
+ if (strlen($this->abs_url)) {
142
+ return $this->abs_url;
143
+ }
144
+ return get_permalink($this->ID);
145
+ }
146
 
147
  /**
148
  * @return bool|TimberImage
149
  */
150
  function get_parent() {
151
+ if (!$this->post_parent) {
152
+ return false;
153
+ }
154
+ return new $this->PostClass($this->post_parent);
155
+ }
156
 
157
+ function get_alt() {
158
+ $alt = trim(strip_tags(get_post_meta($this->ID, '_wp_attachment_image_alt', true)));
159
+ return $alt;
160
+ }
161
 
162
 
163
  /**
164
  * @param int $iid
165
  */
166
  function init($iid) {
167
+ if (!is_numeric($iid) && is_string($iid)) {
168
+ if (strstr($iid, '://')) {
169
+ $this->init_with_url($iid);
170
+ return;
171
+ } else if (strstr(strtolower($iid), '.jpg')) {
172
+ $this->init_with_url($iid);
173
+ }
174
+ }
175
+ $image_info = $iid;
176
+ if (is_numeric($iid)) {
177
+ $image_info = wp_get_attachment_metadata($iid);
178
+ if (!is_array($image_info)) {
179
+ $image_info = array();
180
+ }
181
+ $image_custom = get_post_custom($iid);
182
+ $basic = get_post($iid);
183
+ if ($basic) {
184
+ if (isset($basic->post_excerpt)) {
185
+ $this->caption = $basic->post_excerpt;
186
+ }
187
+ $image_custom = array_merge($image_custom, get_object_vars($basic));
188
+ }
189
+ $image_info = array_merge($image_info, $image_custom);
190
+ } else if (is_array($image_info) && isset($image_info['image'])) {
191
+ $image_info = $image_info['image'];
192
+ } else if (is_object($image_info)) {
193
+ $image_info = get_object_vars($image_info);
194
+ }
195
+ $this->import($image_info);
196
+ $basedir = self::wp_upload_dir();
197
+ $basedir = $basedir['basedir'];
198
+ if (isset($this->file)) {
199
+ $this->file_loc = $basedir . DIRECTORY_SEPARATOR . $this->file;
200
+ } else if (isset($this->_wp_attached_file)) {
201
+ $this->file = reset($this->_wp_attached_file);
202
+ $this->file_loc = $basedir . DIRECTORY_SEPARATOR . $this->file;
203
+ }
204
+ if (isset($image_info['id'])) {
205
+ $this->ID = $image_info['id'];
206
+ } else if (is_numeric($iid)) {
207
+ $this->ID = $iid;
208
+ }
209
+ if (isset($this->ID)) {
210
+ $custom = get_post_custom($this->ID);
211
+ foreach ($custom as $key => $value) {
212
+ $this->$key = $value[0];
213
+ }
214
+ } else {
215
+ if (is_array($iid)) {
216
+ TimberHelper::error_log('Not able to init in TimberImage with iid=');
217
+ TimberHelper::error_log($iid);
218
+ } else {
219
+ TimberHelper::error_log('Not able to init in TimberImage with iid=' . $iid);
220
+ }
221
+ }
222
+ }
223
 
224
  /**
225
  * @param string $url
226
  */
227
  function init_with_url($url) {
228
+ $this->abs_url = $url;
229
+ $this->file_loc = $url;
230
+ if (TimberURLHelper::is_local($url)) {
231
+ $this->file = ABSPATH . TimberURLHelper::get_rel_url($url);
232
+ }
233
+ }
234
 
235
  /**
236
  * @deprecated
237
  * @return string
238
  */
239
  function get_url() {
240
+ return $this->get_src();
241
+ }
242
 
243
+ /* Alias */
244
 
245
  /**
246
  * @return float
247
  */
248
+ public function aspect() {
249
+ $w = intval($this->width());
250
+ $h = intval($this->height());
251
+ return $w / $h;
252
+ }
253
 
254
  /**
255
  * @return int
256
  */
257
+ public function height() {
258
+ return $this->get_height();
259
+ }
260
 
261
  /**
262
  * @param string $size
263
  * @return bool|string
264
  */
265
  public function src($size = '') {
266
+ return $this->get_src($size);
267
+ }
268
 
269
  /**
270
  * @return int
271
  */
272
+ public function width() {
273
+ return $this->get_width();
274
+ }
275
+
276
+ public function alt() {
277
+ return $this->get_alt();
278
+ }
279
 
 
 
 
280
  }
functions/timber-loader.php CHANGED
@@ -1,16 +1,17 @@
1
  <?php
2
 
3
- class TimberLoader {
 
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,
@@ -21,15 +22,15 @@ class TimberLoader {
21
 
22
  protected $cache_mode = self::CACHE_TRANSIENT;
23
 
24
- var $locations;
25
 
26
  /**
27
  * @param bool $caller
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
- }
33
 
34
  /**
35
  * @param string $file
@@ -38,104 +39,105 @@ class TimberLoader {
38
  * @param string $cache_mode
39
  * @return bool|string
40
  */
41
- function render( $file, $data = null, $expires = false, $cache_mode = self::CACHE_USE_DEFAULT ) {
42
  // Different $expires if user is anonymous or logged in
43
- if ( is_array( $expires ) ) {
44
- if ( is_user_logged_in() && isset( $expires[1] ) )
45
  $expires = $expires[1];
46
- else
47
  $expires = $expires[0];
 
48
  }
49
 
50
  $key = null;
51
-
52
  $output = false;
53
- if ( false !== $expires ){
54
- ksort( $data );
55
- $key = md5( $file . json_encode( $data ) );
56
- $output = $this->get_cache( $key, self::CACHEGROUP, $cache_mode );
57
  }
58
 
59
- if ( false === $output || null === $output ) {
60
  $twig = $this->get_twig();
61
- if (strlen($file)){
62
- $loader = $this->get_loader();
63
- $result = $loader->getCacheKey($file);
64
- do_action('timber_loader_render_file', $result);
65
- }
66
- $data = apply_filters('timber_loader_render_data', $data);
67
  $output = $twig->render($file, $data);
68
  }
69
 
70
- if ( false !== $output && false !== $expires && null !== $key )
71
- $this->set_cache( $key, $output, self::CACHEGROUP, $expires, $cache_mode );
 
72
 
73
  return $output;
74
- }
75
 
76
  /**
77
  * @param array $filenames
78
  * @return bool
79
  */
80
  function choose_template($filenames) {
81
- if (is_array($filenames)) {
82
- /* its an array so we have to figure out which one the dev wants */
83
- foreach ($filenames as $filename) {
84
- if ($this->template_exists($filename)) {
85
- return $filename;
86
- }
87
- }
88
- return false;
89
- }
90
- return $filenames;
91
- }
92
 
93
  /**
94
  * @param string $file
95
  * @return bool
96
  */
97
  function template_exists($file) {
98
- foreach ($this->locations as $dir) {
99
- $look_for = trailingslashit($dir) . $file;
100
- if (file_exists($look_for)) {
101
- return true;
102
- }
103
- }
104
- return false;
105
- }
106
 
107
  /**
108
  * @return array
109
  */
110
  function get_locations_theme() {
111
- $theme_locs = array();
112
- $child_loc = get_stylesheet_directory();
113
- $parent_loc = get_template_directory();
114
- if (DIRECTORY_SEPARATOR == '\\') {
115
- $child_loc = str_replace('/', '\\', $child_loc);
116
- $parent_loc = str_replace('/', '\\', $parent_loc);
117
- }
118
- $theme_locs[] = $child_loc;
119
- foreach($this->get_locations_theme_dir() as $dirname){
120
- $theme_locs[] = trailingslashit($child_loc) . trailingslashit($dirname);
121
- }
122
- if ($child_loc != $parent_loc) {
123
- $theme_locs[] = $parent_loc;
124
- foreach($this->get_locations_theme_dir() as $dirname){
125
- $theme_locs[] = trailingslashit($parent_loc) . trailingslashit($dirname);
126
- }
127
- }
128
- //now make sure theres a trailing slash on everything
129
- $theme_locs = array_map('trailingslashit', $theme_locs);
130
- return $theme_locs;
131
- }
132
 
133
  /**
134
  * returns an array of the directory inside themes that holds twig files
135
  * @return array the names of directores, ie: array('templats', 'views');
136
  */
137
- private function get_locations_theme_dir(){
138
- if (is_string(Timber::$dirname)){
139
  return array(Timber::$dirname);
140
  }
141
  return Timber::$dirname;
@@ -145,115 +147,139 @@ class TimberLoader {
145
  * @return array
146
  */
147
  function get_locations_user() {
148
- $locs = array();
149
- if (isset(Timber::$locations)) {
150
- if (is_string(Timber::$locations)) {
151
- Timber::$locations = array(Timber::$locations);
152
- }
153
- foreach (Timber::$locations as $tloc) {
154
- $tloc = realpath($tloc);
155
- if (is_dir($tloc)) {
156
- $locs[] = $tloc;
157
- }
158
- }
159
- }
160
- return $locs;
161
- }
162
 
163
  /**
164
  * @param bool $caller
165
  * @return array
166
  */
167
  function get_locations_caller($caller = false) {
168
- $locs = array();
169
- if ($caller && is_string($caller)) {
170
- $caller = trailingslashit($caller);
171
- if (is_dir($caller)) {
172
- $locs[] = $caller;
173
- }
174
- foreach($this->get_locations_theme_dir() as $dirname){
175
- $caller_sub = $caller . trailingslashit($dirname);
176
- if (is_dir($caller_sub)) {
177
- $locs[] = $caller_sub;
178
- }
179
  }
180
- }
181
- return $locs;
182
- }
 
 
 
 
 
 
183
 
184
  /**
185
  * @param bool $caller
186
  * @return array
187
  */
188
  function get_locations($caller = false) {
189
- //prioirty: user locations, caller (but not theme), child theme, parent theme, caller
190
- $locs = array();
191
- $locs = array_merge($locs, $this->get_locations_user());
192
- $locs = array_merge($locs, $this->get_locations_caller($caller));
193
- //remove themes from caller
194
- $locs = array_diff($locs, $this->get_locations_theme());
195
- $locs = array_merge($locs, $this->get_locations_theme());
196
- $locs = array_merge($locs, $this->get_locations_caller($caller));
197
- $locs = array_unique($locs);
198
- $locs = apply_filters('timber_locations', $locs);
199
- return $locs;
200
- }
201
 
202
  /**
203
  * @return Twig_Loader_Chain
204
  */
205
  function get_loader() {
206
- $loaders = array();
207
- foreach ($this->locations as $loc) {
208
- $loc = realpath($loc);
209
- if (is_dir($loc)) {
210
- $loc = realpath($loc);
211
- $loaders[] = new Twig_Loader_Filesystem($loc);
212
- } else {
213
- //error_log($loc.' is not a directory');
214
- }
215
- }
216
- if (!ini_get('open_basedir')){
217
- $loaders[] = new Twig_Loader_Filesystem('/');
218
- } else {
219
- $loaders[] = new Twig_Loader_Filesystem(ABSPATH);;
220
- }
221
- $loader = new Twig_Loader_Chain($loaders);
222
- return $loader;
223
- }
224
 
225
  /**
226
  * @return Twig_Environment
227
  */
228
  function get_twig() {
229
- // if (!class_exists('Twig_Autoloader')) {
230
- // $loader_loc = trailingslashit(TIMBER_LOC) . 'Twig/lib/Twig/Autoloader.php';
231
- // require_once($loader_loc);
232
- // Twig_Autoloader::register();
233
- // }
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 = 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
- return $twig;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
257
  }
258
 
259
  /**
@@ -264,9 +290,9 @@ class TimberLoader {
264
  require_once($loader_loc);
265
  TimberCache_Loader::register();
266
 
267
- $key_generator = new \Timber\Cache\KeyGenerator();
268
- $cache_provider = new \Timber\Cache\WPObjectCacheAdapter( $this );
269
- $cache_strategy = new \Asm89\Twig\CacheExtension\CacheStrategy\GenerationalCacheStrategy( $cache_provider, $key_generator );
270
  $cache_extension = new \Asm89\Twig\CacheExtension\Extension($cache_strategy);
271
 
272
  return $cache_extension;
@@ -278,25 +304,26 @@ class TimberLoader {
278
  * @param string $cache_mode
279
  * @return bool
280
  */
281
- public function get_cache( $key, $group = self::CACHEGROUP, $cache_mode = self::CACHE_USE_DEFAULT ) {
282
  $object_cache = false;
283
 
284
- if ( isset( $GLOBALS[ 'wp_object_cache' ] ) && is_object( $GLOBALS[ 'wp_object_cache' ] ) )
285
  $object_cache = true;
 
286
 
287
- $cache_mode = $this->_get_cache_mode( $cache_mode );
288
 
289
  $value = false;
290
 
291
  $trans_key = substr($group . '_' . $key, 0, self::TRANS_KEY_LEN);
292
- if ( self::CACHE_TRANSIENT === $cache_mode )
293
- $value = get_transient( $trans_key );
294
 
295
- elseif ( self::CACHE_SITE_TRANSIENT === $cache_mode )
296
- $value = get_site_transient( $trans_key );
297
 
298
- elseif ( self::CACHE_OBJECT === $cache_mode && $object_cache )
299
- $value = wp_cache_get( $key, $group );
300
 
301
  return $value;
302
  }
@@ -309,26 +336,27 @@ class TimberLoader {
309
  * @param string $cache_mode
310
  * @return mixed
311
  */
312
- public function set_cache( $key, $value, $group = self::CACHEGROUP, $expires = 0, $cache_mode = self::CACHE_USE_DEFAULT ) {
313
  $object_cache = false;
314
 
315
- if ( isset( $GLOBALS[ 'wp_object_cache' ] ) && is_object( $GLOBALS[ 'wp_object_cache' ] ) )
316
  $object_cache = true;
 
317
 
318
- if ( (int) $expires < 1 )
319
  $expires = 0;
320
 
321
- $cache_mode = self::_get_cache_mode( $cache_mode );
322
  $trans_key = substr($group . '_' . $key, 0, self::TRANS_KEY_LEN);
323
 
324
- if ( self::CACHE_TRANSIENT === $cache_mode )
325
- set_transient( $trans_key, $value, $expires );
326
 
327
- elseif ( self::CACHE_SITE_TRANSIENT === $cache_mode )
328
- set_site_transient( $trans_key, $value, $expires );
329
 
330
- elseif ( self::CACHE_OBJECT === $cache_mode && $object_cache )
331
- wp_cache_set( $key, $value, $group, $expires );
332
 
333
  return $value;
334
  }
@@ -337,14 +365,17 @@ class TimberLoader {
337
  * @param string $cache_mode
338
  * @return string
339
  */
340
- private function _get_cache_mode( $cache_mode ) {
341
- if ( empty( $cache_mode ) || self::CACHE_USE_DEFAULT === $cache_mode )
342
  $cache_mode = $this->cache_mode;
 
343
 
344
  // Fallback if self::$cache_mode did not get a valid value
345
- if ( !in_array( $cache_mode, self::$cache_modes ) )
346
  $cache_mode = self::CACHE_OBJECT;
 
347
 
348
  return $cache_mode;
349
  }
 
350
  }
1
  <?php
2
 
3
+ class TimberLoader
4
+ {
5
 
6
  const CACHEGROUP = 'timberloader';
7
 
8
+ const TRANS_KEY_LEN = 50;
9
 
10
+ const CACHE_NONE = 'none';
11
+ const CACHE_OBJECT = 'cache';
12
+ const CACHE_TRANSIENT = 'transient';
13
  const CACHE_SITE_TRANSIENT = 'site-transient';
14
+ const CACHE_USE_DEFAULT = 'default';
15
 
16
  public static $cache_modes = array(
17
  self::CACHE_NONE,
22
 
23
  protected $cache_mode = self::CACHE_TRANSIENT;
24
 
25
+ public $locations;
26
 
27
  /**
28
  * @param bool $caller
29
  */
30
  function __construct($caller = false) {
31
+ $this->locations = $this->get_locations($caller);
32
+ $this->cache_mode = apply_filters('timber_cache_mode', $this->cache_mode);
33
+ }
34
 
35
  /**
36
  * @param string $file
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
  $output = $twig->render($file, $data);
69
  }
70
 
71
+ if (false !== $output && false !== $expires && null !== $key) {
72
+ $this->set_cache($key, $output, self::CACHEGROUP, $expires, $cache_mode);
73
+ }
74
 
75
  return $output;
76
+ }
77
 
78
  /**
79
  * @param array $filenames
80
  * @return bool
81
  */
82
  function choose_template($filenames) {
83
+ if (is_array($filenames)) {
84
+ /* its an array so we have to figure out which one the dev wants */
85
+ foreach ($filenames as $filename) {
86
+ if ($this->template_exists($filename)) {
87
+ return $filename;
88
+ }
89
+ }
90
+ return false;
91
+ }
92
+ return $filenames;
93
+ }
94
 
95
  /**
96
  * @param string $file
97
  * @return bool
98
  */
99
  function template_exists($file) {
100
+ foreach ($this->locations as $dir) {
101
+ $look_for = trailingslashit($dir) . $file;
102
+ if (file_exists($look_for)) {
103
+ return true;
104
+ }
105
+ }
106
+ return false;
107
+ }
108
 
109
  /**
110
  * @return array
111
  */
112
  function get_locations_theme() {
113
+ $theme_locs = array();
114
+ $child_loc = get_stylesheet_directory();
115
+ $parent_loc = get_template_directory();
116
+ if (DIRECTORY_SEPARATOR == '\\') {
117
+ $child_loc = str_replace('/', '\\', $child_loc);
118
+ $parent_loc = str_replace('/', '\\', $parent_loc);
119
+ }
120
+ $theme_locs[] = $child_loc;
121
+ foreach ($this->get_locations_theme_dir() as $dirname) {
122
+ $theme_locs[] = trailingslashit($child_loc) . trailingslashit($dirname);
123
+ }
124
+ if ($child_loc != $parent_loc) {
125
+ $theme_locs[] = $parent_loc;
126
+ foreach ($this->get_locations_theme_dir() as $dirname) {
127
+ $theme_locs[] = trailingslashit($parent_loc) . trailingslashit($dirname);
128
+ }
129
+ }
130
+ //now make sure theres a trailing slash on everything
131
+ $theme_locs = array_map('trailingslashit', $theme_locs);
132
+ return $theme_locs;
133
+ }
134
 
135
  /**
136
  * returns an array of the directory inside themes that holds twig files
137
  * @return array the names of directores, ie: array('templats', 'views');
138
  */
139
+ private function get_locations_theme_dir() {
140
+ if (is_string(Timber::$dirname)) {
141
  return array(Timber::$dirname);
142
  }
143
  return Timber::$dirname;
147
  * @return array
148
  */
149
  function get_locations_user() {
150
+ $locs = array();
151
+ if (isset(Timber::$locations)) {
152
+ if (is_string(Timber::$locations)) {
153
+ Timber::$locations = array(Timber::$locations);
154
+ }
155
+ foreach (Timber::$locations as $tloc) {
156
+ $tloc = realpath($tloc);
157
+ if (is_dir($tloc)) {
158
+ $locs[] = $tloc;
159
+ }
160
+ }
161
+ }
162
+ return $locs;
163
+ }
164
 
165
  /**
166
  * @param bool $caller
167
  * @return array
168
  */
169
  function get_locations_caller($caller = false) {
170
+ $locs = array();
171
+ if ($caller && is_string($caller)) {
172
+ $caller = trailingslashit($caller);
173
+ if (is_dir($caller)) {
174
+ $locs[] = $caller;
 
 
 
 
 
 
175
  }
176
+ foreach ($this->get_locations_theme_dir() as $dirname) {
177
+ $caller_sub = $caller . trailingslashit($dirname);
178
+ if (is_dir($caller_sub)) {
179
+ $locs[] = $caller_sub;
180
+ }
181
+ }
182
+ }
183
+ return $locs;
184
+ }
185
 
186
  /**
187
  * @param bool $caller
188
  * @return array
189
  */
190
  function get_locations($caller = false) {
191
+ //prioirty: user locations, caller (but not theme), child theme, parent theme, caller
192
+ $locs = array();
193
+ $locs = array_merge($locs, $this->get_locations_user());
194
+ $locs = array_merge($locs, $this->get_locations_caller($caller));
195
+ //remove themes from caller
196
+ $locs = array_diff($locs, $this->get_locations_theme());
197
+ $locs = array_merge($locs, $this->get_locations_theme());
198
+ $locs = array_merge($locs, $this->get_locations_caller($caller));
199
+ $locs = array_unique($locs);
200
+ $locs = apply_filters('timber_locations', $locs);
201
+ return $locs;
202
+ }
203
 
204
  /**
205
  * @return Twig_Loader_Chain
206
  */
207
  function get_loader() {
208
+ $paths = array();
209
+ foreach ($this->locations as $loc) {
210
+ $loc = realpath($loc);
211
+ if (is_dir($loc)) {
212
+ $loc = realpath($loc);
213
+ $paths[] = $loc;
214
+ } else {
215
+ //error_log($loc.' is not a directory');
216
+ }
217
+ }
218
+ if (!ini_get('open_basedir')) {
219
+ $paths[] = '/';
220
+ } else {
221
+ $paths[] = ABSPATH;
222
+ }
223
+ $loader = new Twig_Loader_Filesystem($paths);
224
+ return $loader;
225
+ }
226
 
227
  /**
228
  * @return Twig_Environment
229
  */
230
  function get_twig() {
231
+ $loader = $this->get_loader();
232
+ $params = array('debug' => WP_DEBUG, 'autoescape' => false);
233
+ if (isset(Timber::$autoescape)) {
234
+ $params['autoescape'] = Timber::$autoescape;
235
+ }
236
+ if (Timber::$cache == true) {
 
 
 
 
 
237
  Timber::$twig_cache = true;
238
  }
239
+ if (Timber::$twig_cache) {
240
  $twig_cache_loc = TIMBER_LOC . '/cache/twig';
241
  if (!file_exists($twig_cache_loc)) {
242
  mkdir($twig_cache_loc, 0777, true);
243
  }
244
+ $params['cache'] = $twig_cache_loc;
245
+ }
246
+ $twig = new Twig_Environment($loader, $params);
247
+ if (WP_DEBUG) {
248
+ $twig->addExtension(new Twig_Extension_Debug());
249
  }
250
  $twig->addExtension($this->_get_cache_extension());
251
 
252
+ $twig = apply_filters('twig_apply_filters', $twig);
253
+ return $twig;
254
+ }
255
+
256
+ public function clear_cache_twig() {
257
+ $twig = $this->get_twig();
258
+ $twig->clearCacheFiles();
259
+ $cache = $twig->getCache();
260
+ if ($cache){
261
+ self::rrmdir($twig->getCache());
262
+ return true;
263
+ }
264
+ return false;
265
+ }
266
+
267
+ public static function rrmdir($dirPath) {
268
+ if (! is_dir($dirPath)) {
269
+ throw new InvalidArgumentException("$dirPath must be a directory");
270
+ }
271
+ if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {
272
+ $dirPath .= '/';
273
+ }
274
+ $files = glob($dirPath . '*', GLOB_MARK);
275
+ foreach ($files as $file) {
276
+ if (is_dir($file)) {
277
+ self::rrmdir($file);
278
+ } else {
279
+ unlink($file);
280
+ }
281
+ }
282
+ rmdir($dirPath);
283
  }
284
 
285
  /**
290
  require_once($loader_loc);
291
  TimberCache_Loader::register();
292
 
293
+ $key_generator = new \Timber\Cache\KeyGenerator();
294
+ $cache_provider = new \Timber\Cache\WPObjectCacheAdapter($this);
295
+ $cache_strategy = new \Asm89\Twig\CacheExtension\CacheStrategy\GenerationalCacheStrategy($cache_provider, $key_generator);
296
  $cache_extension = new \Asm89\Twig\CacheExtension\Extension($cache_strategy);
297
 
298
  return $cache_extension;
304
  * @param string $cache_mode
305
  * @return bool
306
  */
307
+ public function get_cache($key, $group = self::CACHEGROUP, $cache_mode = self::CACHE_USE_DEFAULT) {
308
  $object_cache = false;
309
 
310
+ if (isset($GLOBALS['wp_object_cache']) && is_object($GLOBALS['wp_object_cache'])) {
311
  $object_cache = true;
312
+ }
313
 
314
+ $cache_mode = $this->_get_cache_mode($cache_mode);
315
 
316
  $value = false;
317
 
318
  $trans_key = substr($group . '_' . $key, 0, self::TRANS_KEY_LEN);
319
+ if (self::CACHE_TRANSIENT === $cache_mode)
320
+ $value = get_transient($trans_key);
321
 
322
+ elseif (self::CACHE_SITE_TRANSIENT === $cache_mode)
323
+ $value = get_site_transient($trans_key);
324
 
325
+ elseif (self::CACHE_OBJECT === $cache_mode && $object_cache)
326
+ $value = wp_cache_get($key, $group);
327
 
328
  return $value;
329
  }
336
  * @param string $cache_mode
337
  * @return mixed
338
  */
339
+ public function set_cache($key, $value, $group = self::CACHEGROUP, $expires = 0, $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
+ if ((int)$expires < 1)
347
  $expires = 0;
348
 
349
+ $cache_mode = self::_get_cache_mode($cache_mode);
350
  $trans_key = substr($group . '_' . $key, 0, self::TRANS_KEY_LEN);
351
 
352
+ if (self::CACHE_TRANSIENT === $cache_mode)
353
+ set_transient($trans_key, $value, $expires);
354
 
355
+ elseif (self::CACHE_SITE_TRANSIENT === $cache_mode)
356
+ set_site_transient($trans_key, $value, $expires);
357
 
358
+ elseif (self::CACHE_OBJECT === $cache_mode && $object_cache)
359
+ wp_cache_set($key, $value, $group, $expires);
360
 
361
  return $value;
362
  }
365
  * @param string $cache_mode
366
  * @return string
367
  */
368
+ private function _get_cache_mode($cache_mode) {
369
+ if (empty($cache_mode) || self::CACHE_USE_DEFAULT === $cache_mode) {
370
  $cache_mode = $this->cache_mode;
371
+ }
372
 
373
  // Fallback if self::$cache_mode did not get a valid value
374
+ if (!in_array($cache_mode, self::$cache_modes)) {
375
  $cache_mode = self::CACHE_OBJECT;
376
+ }
377
 
378
  return $cache_mode;
379
  }
380
+
381
  }
functions/timber-menu.php CHANGED
@@ -1,31 +1,34 @@
1
  <?php
2
 
3
- class TimberMenu extends TimberCore {
 
4
 
5
- var $MenuItemClass = 'TimberMenuItem';
6
 
7
- var $items = null;
8
- var $name = null;
9
- var $ID = null;
 
 
10
 
11
  /**
12
  * @param int $slug
13
  */
14
  function __construct($slug = 0) {
15
  $locations = get_nav_menu_locations();
16
- if ($slug != 0 && is_numeric($slug)){
17
  $menu_id = $slug;
18
- } else if (is_array($locations) && count($locations)){
19
  $menu_id = $this->get_menu_id_from_locations($slug, $locations);
20
- } else if ($slug === false){
21
  $menu_id = false;
22
  } else {
23
  $menu_id = $this->get_menu_id_from_terms($slug);
24
  }
25
- if ($menu_id){
26
  $this->init($menu_id);
27
  } else {
28
- TimberHelper::error_log("Sorry, the menu you were looking for wasn't found ('".$slug."'). Here's what Timber did find:");
29
  }
30
  return null;
31
  }
@@ -33,13 +36,14 @@ class TimberMenu extends TimberCore {
33
  /**
34
  * @param int $menu_id
35
  */
36
- private function init($menu_id){
37
  $menu = wp_get_nav_menu_items($menu_id);
38
  $menu = self::order_children($menu);
39
  $this->items = $menu;
40
  $menu_info = wp_get_nav_menu_object($menu_id);
41
  $this->import($menu_info);
42
  $this->ID = $this->term_id;
 
43
  }
44
 
45
  /**
@@ -47,37 +51,38 @@ class TimberMenu extends TimberCore {
47
  * @param array $locations
48
  * @return mixed
49
  */
50
- private function get_menu_id_from_locations($slug, $locations){
51
- if ($slug === 0){
52
  $slug = $this->get_menu_id_from_terms($slug);
53
  }
54
- if (is_numeric($slug)){
55
  $slug = array_search($slug, $locations);
56
  }
57
  if (isset($locations[$slug])) {
58
  return $locations[$slug];
59
  }
 
60
  }
61
 
62
  /**
63
  * @param int $slug
64
  * @return int
65
  */
66
- private function get_menu_id_from_terms($slug = 0){
67
- if (!is_numeric($slug) && is_string($slug)){
68
  //we have a string so lets search for that
69
  $menu_id = get_term_by('slug', $slug, 'nav_menu');
70
- if ($menu_id){
71
  return $menu_id;
72
  }
73
  $menu_id = get_term_by('name', $slug, 'nav_menu');
74
- if ($menu_id){
75
  return $menu_id;
76
  }
77
  }
78
- $menus = get_terms( 'nav_menu', array( 'hide_empty' => true ) );
79
- if (is_array($menus) && count($menus)){
80
- if (isset($menus[0]->term_id)){
81
  return $menus[0]->term_id;
82
  }
83
  }
@@ -106,11 +111,11 @@ class TimberMenu extends TimberCore {
106
  $index = array();
107
  $menu = array();
108
  _wp_menu_item_classes_by_context($items);
109
- foreach($items as $item) {
110
  $index[$item->ID] = new $this->MenuItemClass($item);
111
  }
112
- foreach($index as $item) {
113
- if($item->menu_item_parent && isset($index[$item->menu_item_parent])) {
114
  $index[$item->menu_item_parent]->add_child($item);
115
  } else {
116
  $menu[] = $item;
@@ -130,10 +135,16 @@ class TimberMenu extends TimberCore {
130
  }
131
  }
132
 
133
- class TimberMenuItem extends TimberCore {
 
 
 
 
134
 
135
- var $children;
136
- var $has_child_class = false;
 
 
137
 
138
  /**
139
  * @param array|object $data
@@ -141,26 +152,26 @@ class TimberMenuItem extends TimberCore {
141
  function __construct($data) {
142
  $this->import($data);
143
  $this->import_classes($data);
144
- if (isset($this->name)){
145
  $this->_name = $this->name;
146
  }
147
  $this->name = $this->name();
148
- $this->add_class('menu-item-'.$this->ID);
149
  }
150
 
151
  /**
152
  * @param string $class_name
153
  */
154
- function add_class($class_name){
155
  $this->classes[] = $class_name;
156
- $this->class .= ' '.$class_name;
157
  }
158
 
159
  /**
160
  * @return string
161
  */
162
  function name() {
163
- if (isset($this->title)){
164
  return $this->title;
165
  }
166
  return $this->_name;
@@ -191,7 +202,7 @@ class TimberMenuItem extends TimberCore {
191
  * @param TimberMenuItem $item
192
  */
193
  function add_child($item) {
194
- if (!$this->has_child_class){
195
  $this->add_class('menu-item-has-children');
196
  $this->has_child_class = true;
197
  }
@@ -204,7 +215,7 @@ class TimberMenuItem extends TimberCore {
204
  /**
205
  * @param object $data
206
  */
207
- function import_classes($data){
208
  $this->class = trim(implode(' ', $data->classes));
209
  }
210
 
@@ -221,8 +232,8 @@ class TimberMenuItem extends TimberCore {
221
  /**
222
  * @return bool
223
  */
224
- function is_external(){
225
- if ($this->type != 'custom'){
226
  return false;
227
  }
228
  return TimberURLHelper::is_external($this->url);
@@ -233,42 +244,43 @@ class TimberMenuItem extends TimberCore {
233
  /**
234
  * @return array|bool
235
  */
236
- public function children(){
237
  return $this->get_children();
238
  }
239
 
240
  /**
241
  * @return bool
242
  */
243
- public function external(){
244
  return $this->is_external();
245
  }
246
 
247
  /**
248
  * @return string
249
  */
250
- public function link(){
251
  return $this->get_link();
252
  }
253
 
254
  /**
255
  * @return string
256
  */
257
- public function path(){
258
  return $this->get_path();
259
  }
260
 
261
  /**
262
  * @return string
263
  */
264
- public function permalink(){
265
  return $this->get_link();
266
  }
267
 
268
  /**
269
  * @return string
270
  */
271
- public function get_permalink(){
272
  return $this->get_link();
273
  }
 
274
  }
1
  <?php
2
 
3
+ class TimberMenu extends TimberCore
4
+ {
5
 
6
+ public $MenuItemClass = 'TimberMenuItem';
7
 
8
+ public $items = null;
9
+ public $id = null;
10
+ public $ID = null;
11
+ public $name = null;
12
+ public $term_id;
13
 
14
  /**
15
  * @param int $slug
16
  */
17
  function __construct($slug = 0) {
18
  $locations = get_nav_menu_locations();
19
+ if ($slug != 0 && is_numeric($slug)) {
20
  $menu_id = $slug;
21
+ } else if (is_array($locations) && count($locations)) {
22
  $menu_id = $this->get_menu_id_from_locations($slug, $locations);
23
+ } else if ($slug === false) {
24
  $menu_id = false;
25
  } else {
26
  $menu_id = $this->get_menu_id_from_terms($slug);
27
  }
28
+ if ($menu_id) {
29
  $this->init($menu_id);
30
  } else {
31
+ TimberHelper::error_log("Sorry, the menu you were looking for wasn't found ('" . $slug . "'). Here's what Timber did find:");
32
  }
33
  return null;
34
  }
36
  /**
37
  * @param int $menu_id
38
  */
39
+ private function init($menu_id) {
40
  $menu = wp_get_nav_menu_items($menu_id);
41
  $menu = self::order_children($menu);
42
  $this->items = $menu;
43
  $menu_info = wp_get_nav_menu_object($menu_id);
44
  $this->import($menu_info);
45
  $this->ID = $this->term_id;
46
+ $this->id = $this->term_id;
47
  }
48
 
49
  /**
51
  * @param array $locations
52
  * @return mixed
53
  */
54
+ private function get_menu_id_from_locations($slug, $locations) {
55
+ if ($slug === 0) {
56
  $slug = $this->get_menu_id_from_terms($slug);
57
  }
58
+ if (is_numeric($slug)) {
59
  $slug = array_search($slug, $locations);
60
  }
61
  if (isset($locations[$slug])) {
62
  return $locations[$slug];
63
  }
64
+ return null;
65
  }
66
 
67
  /**
68
  * @param int $slug
69
  * @return int
70
  */
71
+ private function get_menu_id_from_terms($slug = 0) {
72
+ if (!is_numeric($slug) && is_string($slug)) {
73
  //we have a string so lets search for that
74
  $menu_id = get_term_by('slug', $slug, 'nav_menu');
75
+ if ($menu_id) {
76
  return $menu_id;
77
  }
78
  $menu_id = get_term_by('name', $slug, 'nav_menu');
79
+ if ($menu_id) {
80
  return $menu_id;
81
  }
82
  }
83
+ $menus = get_terms('nav_menu', array('hide_empty' => true));
84
+ if (is_array($menus) && count($menus)) {
85
+ if (isset($menus[0]->term_id)) {
86
  return $menus[0]->term_id;
87
  }
88
  }
111
  $index = array();
112
  $menu = array();
113
  _wp_menu_item_classes_by_context($items);
114
+ foreach ($items as $item) {
115
  $index[$item->ID] = new $this->MenuItemClass($item);
116
  }
117
+ foreach ($index as $item) {
118
+ if ($item->menu_item_parent && isset($index[$item->menu_item_parent])) {
119
  $index[$item->menu_item_parent]->add_child($item);
120
  } else {
121
  $menu[] = $item;
135
  }
136
  }
137
 
138
+ class TimberMenuItem extends TimberCore
139
+ {
140
+
141
+ public $children;
142
+ public $has_child_class = false;
143
 
144
+ public $classes = array();
145
+ public $class;
146
+ public $post_name;
147
+ public $type;
148
 
149
  /**
150
  * @param array|object $data
152
  function __construct($data) {
153
  $this->import($data);
154
  $this->import_classes($data);
155
+ if (isset($this->name)) {
156
  $this->_name = $this->name;
157
  }
158
  $this->name = $this->name();
159
+ $this->add_class('menu-item-' . $this->ID);
160
  }
161
 
162
  /**
163
  * @param string $class_name
164
  */
165
+ function add_class($class_name) {
166
  $this->classes[] = $class_name;
167
+ $this->class .= ' ' . $class_name;
168
  }
169
 
170
  /**
171
  * @return string
172
  */
173
  function name() {
174
+ if (isset($this->title)) {
175
  return $this->title;
176
  }
177
  return $this->_name;
202
  * @param TimberMenuItem $item
203
  */
204
  function add_child($item) {
205
+ if (!$this->has_child_class) {
206
  $this->add_class('menu-item-has-children');
207
  $this->has_child_class = true;
208
  }
215
  /**
216
  * @param object $data
217
  */
218
+ function import_classes($data) {
219
  $this->class = trim(implode(' ', $data->classes));
220
  }
221
 
232
  /**
233
  * @return bool
234
  */
235
+ function is_external() {
236
+ if ($this->type != 'custom') {
237
  return false;
238
  }
239
  return TimberURLHelper::is_external($this->url);
244
  /**
245
  * @return array|bool
246
  */
247
+ public function children() {
248
  return $this->get_children();
249
  }
250
 
251
  /**
252
  * @return bool
253
  */
254
+ public function external() {
255
  return $this->is_external();
256
  }
257
 
258
  /**
259
  * @return string
260
  */
261
+ public function link() {
262
  return $this->get_link();
263
  }
264
 
265
  /**
266
  * @return string
267
  */
268
+ public function path() {
269
  return $this->get_path();
270
  }
271
 
272
  /**
273
  * @return string
274
  */
275
+ public function permalink() {
276
  return $this->get_link();
277
  }
278
 
279
  /**
280
  * @return string
281
  */
282
+ public function get_permalink() {
283
  return $this->get_link();
284
  }
285
+
286
  }
functions/timber-page.php CHANGED
@@ -1,5 +1,6 @@
1
  <?php
2
 
3
- class TimberPage extends TimberPost {
 
4
 
5
  }
1
  <?php
2
 
3
+ class TimberPage extends TimberPost
4
+ {
5
 
6
  }
functions/timber-post.php CHANGED
@@ -1,40 +1,45 @@
1
  <?php
2
 
3
- class TimberPost extends TimberCore {
 
4
 
5
- var $ImageClass = 'TimberImage';
6
- var $PostClass = 'TimberPost';
7
- var $_can_edit;
8
- var $_get_terms;
9
- var $_content;
10
- var $object_type = 'post';
11
 
12
- var $_custom_imported = false;
13
 
14
- public static $representation = 'post';
15
 
 
 
 
 
 
 
 
16
 
17
- /**
18
- * If you send the contructor nothing it will try to figure out the current post id based on being inside The_Loop
19
- * @param mixed $pid
20
- * @return \TimberPost TimberPost object -- woo!
21
- */
22
- function __construct($pid = null) {
23
- if ($pid === null && get_the_ID()){
24
- $pid = get_the_ID();
25
- $this->ID = $pid;
26
- } else if ($pid === null && have_posts()) {
27
- ob_start();
28
- the_post();
29
- $pid = get_the_ID();
30
- $this->ID = $pid;
31
- ob_end_clean();
32
- }
33
- if (is_numeric($pid)) {
34
- $this->ID = $pid;
35
- }
36
- $this->init($pid);
37
- }
38
 
39
  /**
40
  * @param int|bool $pid
@@ -45,105 +50,106 @@ class TimberPost extends TimberCore {
45
  }
46
  $post_info = $this->get_info($pid);
47
  $this->import($post_info);
 
 
48
  //cant have a function, so gots to do it this way
49
  $post_class = $this->post_class();
50
  $this->class = $post_class;
51
  }
52
 
53
- /**
54
- * Get the URL that will edit the current post/object
55
  *
56
  * @return bool|string
57
  */
58
  function get_edit_url() {
59
- if ($this->can_edit()) {
60
- return get_edit_post_link($this->ID);
61
- return '/wp-admin/post.php?post=' . $this->ID . '&action=edit';
62
- }
63
- return false;
64
- }
65
 
66
- /**
67
- * updates the post_meta of the current object with the given value
68
- *
69
- * @param string $field
70
- * @param mixed $value
71
- */
72
- public function update($field, $value) {
73
- if (isset($this->ID)) {
74
- update_post_meta($this->ID, $field, $value);
75
- $this->$field = $value;
76
- }
77
- }
78
-
79
-
80
- /**
81
- * takes a mix of integer (post ID), string (post slug), or object to return a WordPress post object from WP's built-in get_post() function
82
- *
83
- * @param mixed $pid
84
- * @return WP_Post on success
85
- */
86
- private function prepare_post_info($pid = 0) {
87
- if (is_string($pid) || is_numeric($pid) || (is_object($pid) && !isset($pid->post_title)) || $pid === 0) {
88
- $pid = self::check_post_id($pid);
89
- $post = get_post($pid);
90
- if ($post) {
91
- return $post;
92
- } else {
93
- $post = get_page($pid);
94
- return $post;
95
- }
96
- }
97
- //we can skip if already is WP_Post
98
- return $pid;
99
- }
100
-
101
-
102
- /**
103
- * helps you find the post id regardless of whetehr you send a string or whatever
104
- *
105
- * @param mixed $pid;
106
- * @return integer ID number of a post
107
- */
108
- private function check_post_id($pid) {
109
- if (is_numeric($pid) && $pid === 0) {
110
- $pid = get_the_ID();
111
- return $pid;
112
- }
113
- if (!is_numeric($pid) && is_string($pid)) {
114
- $pid = self::get_post_id_by_name($pid);
115
- return $pid;
116
- }
117
- if (!$pid) {
118
- return null;
119
- }
120
- return $pid;
121
- }
122
 
123
 
124
- /**
125
- * get_post_id_by_name($post_name)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  *
127
  * @param $post_name
128
  * @return int
129
  */
130
  public static function get_post_id_by_name($post_name) {
131
- global $wpdb;
132
- $query = $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_name = %s LIMIT 1", $post_name);
133
- $result = $wpdb->get_row($query);
134
- if (!$result) {
135
- return null;
136
- }
137
- return $result->ID;
138
- }
139
 
140
 
141
- /**
142
- * ## get a preview of your post, if you have an excerpt it will use that,
143
- * ## otherwise it will pull from the post_content.
144
- * ## If there's a <!-- more --> tag it will use that to mark where to pull through.
145
- * <p>{{post.get_preview(50)}}</p>
146
- */
147
 
148
  /**
149
  * @param int $len
@@ -153,280 +159,319 @@ class TimberPost extends TimberCore {
153
  * @return string
154
  */
155
  function get_preview($len = 50, $force = false, $readmore = 'Read More', $strip = true) {
156
- $text = '';
157
- $trimmed = false;
158
- if (isset($this->post_excerpt) && strlen($this->post_excerpt)) {
159
- if ($force) {
160
- $text = TimberHelper::trim_words($this->post_excerpt, $len, false);
161
- $trimmed = true;
162
- } else {
163
- $text = $this->post_excerpt;
164
- }
165
- }
166
- if (!strlen($text) && strpos($this->post_content, '<!--more-->') !== false) {
167
- $pieces = explode('<!--more-->',$this->post_content);
168
- $text = $pieces[0];
169
- if ($force) {
170
- $text = TimberHelper::trim_words($text, $len, false);
171
- $trimmed = true;
172
- }
173
- }
174
- if (!strlen($text)) {
175
- $text = TimberHelper::trim_words($this->get_content(), $len, false);
176
- $trimmed = true;
177
- }
178
- if (!strlen(trim($text))) {
179
- return $text;
180
- }
181
- if ($strip) {
182
- $text = trim(strip_tags($text));
183
- }
184
- if (strlen($text)) {
185
- $text = trim($text);
186
- $last = $text[strlen($text) - 1];
187
- if ($last != '.' && $trimmed) {
188
- $text .= ' &hellip; ';
189
- }
190
- if (!$strip){
191
- $last_p_tag = strrpos($text, '</p>');
192
- if ($last_p_tag !== false){
193
- $text = substr($text, 0, $last_p_tag);
194
- }
195
- if ($last != '.' && $trimmed) {
196
- $text .= ' &hellip; ';
197
- }
198
- }
199
-
200
- if($readmore) {
201
- $text .= ' <a href="' . $this->get_permalink() . '" class="read-more">' . $readmore . '</a>';
202
- }
203
- if (!$strip){
204
- $text .= '</p>';
205
- }
206
- }
207
- return $text;
208
- }
209
 
210
  /**
211
  * gets the post custom and attaches it to the current object
212
  * @param bool|int $pid a post ID number
213
  * @nodoc
214
  */
215
- function import_custom($pid = false){
216
- if (!$pid){
217
- $pid = $this->ID;
218
- }
219
- $customs = $this->get_post_custom($pid);
220
- $this->import($customs);
221
- }
222
 
223
  /**
224
  * @param int $pid
225
  * @return array
226
  */
227
  function get_post_custom($pid) {
228
- $customs = apply_filters('timber_post_get_meta_pre', array(), $pid, $this);
229
- $customs = get_post_custom($pid);
230
- if (!is_array($customs) || empty($customs)){
231
- return;
232
- }
233
- foreach ($customs as $key => $value) {
234
- if (is_array($value) && count($value) == 1 && isset($value[0])){
235
- $value = $value[0];
236
- }
237
- $customs[$key] = maybe_unserialize($value);
238
- }
239
- $customs = apply_filters('timber_post_get_meta', $customs, $pid, $this);
240
- return $customs;
241
- }
242
 
243
- /**
244
- * ## get the featured image as a TimberImage
245
- * <img src="{{post.get_thumbnail.get_src}}" />
246
- */
247
 
248
  /**
249
  * @return null|TimberImage
250
  */
251
  function get_thumbnail() {
252
- if (function_exists('get_post_thumbnail_id')) {
253
- $tid = get_post_thumbnail_id($this->ID);
254
- if ($tid) {
255
- return new $this->ImageClass($tid);
256
- }
257
- }
258
- return null;
259
- }
260
 
261
  /**
262
  * @return string
263
  */
264
  function get_permalink() {
265
- if (isset($this->permalink)){
266
- return $this->permalink;
267
- }
268
- $this->permalink = get_permalink($this->ID);
269
- return $this->permalink;
270
- }
271
 
272
  /**
273
  * @return string
274
  */
275
  function get_link() {
276
- return $this->get_permalink();
277
- }
278
 
279
  /**
280
  * @param bool $by_taxonomy
281
  * @return mixed
282
  */
283
  function get_next($by_taxonomy = false) {
284
- if (!isset($this->_next) || !isset($this->_next[$by_taxonomy])){
285
- global $post;
286
- $this->_next = array();
287
- $old_global = $post;
288
- $post = $this;
289
- if ($by_taxonomy == 'category' || $by_taxonomy == 'categories'){
290
- $in_same_cat = true;
291
- } else {
292
- $in_same_cat = false;
293
- }
294
- $adjacent = get_adjacent_post($in_same_cat, '', false);
295
- if ($adjacent){
296
- $this->_next[$by_taxonomy] = new $this->PostClass($adjacent);
297
- } else {
298
- $this->_next[$by_taxonomy] = false;
299
- }
300
- $post = $old_global;
301
- }
302
- return $this->_next[$by_taxonomy];
303
- }
304
 
305
  /**
306
  * @return array
307
  */
308
- public function get_pagination(){
309
- global $post, $page, $numpages, $multipage, $more, $pagenow;
310
- $old_global_post = $post;
311
- $post = $this;
312
- $ret = array();
313
- if ($multipage){
314
- for ( $i = 1; $i <= $numpages; $i++ ) {
315
- $link = self::get_wp_link_page($i);
316
- $data = array('name' => $i, 'title' => $i, 'text' => $i, 'link' => $link);
317
- if ($i == $page){
318
- $data['current'] = true;
319
- }
320
- $ret['pages'][] = $data;
321
- }
322
- $i = $page - 1;
323
- if ( $i ) {
324
- $link = self::get_wp_link_page( $i );
325
- $ret['prev'] = array('link' => $link);
326
- }
327
- $i = $page + 1;
328
- if ( $i <= $numpages ) {
329
- $link = self::get_wp_link_page( $i );
330
- $ret['next'] = array('link' => $link);
331
- }
332
- }
333
- return $ret;
334
- }
335
 
336
  /**
337
  * @param int $i
338
  * @return string
339
  */
340
- private static function get_wp_link_page($i){
341
- $link = _wp_link_page($i);
342
- $link = new SimpleXMLElement($link.'</a>');
343
- if (isset($link['href'])){
344
- return $link['href'];
345
- }
346
- return '';
347
- }
348
 
349
  /**
350
  * @return string
351
  */
352
  function get_path() {
353
- return TimberURLHelper::get_rel_url($this->get_link());
354
- }
355
 
356
  /**
357
  * @param bool $by_taxonomy
358
  * @return mixed
359
  */
360
  function get_prev($by_taxonomy = false) {
361
- if (!isset($this->_prev) || !isset($this->_prev[$by_taxonomy])){
362
- global $post;
363
- $this->_prev = array();
364
- $old_global = $post;
365
- $post = $this;
366
- if ($by_taxonomy == 'category' || $by_taxonomy == 'categories'){
367
- $in_same_cat = true;
368
- } else {
369
- $in_same_cat = false;
370
- }
371
- $adjacent = get_adjacent_post($in_same_cat, '', true);
372
- if ($adjacent){
373
- $this->_prev[$by_taxonomy] = new $this->PostClass($adjacent);
374
- } else {
375
- $this->_prev[$by_taxonomy] = false;
376
- }
377
- $post = $old_global;
378
- }
379
- return $this->_prev[$by_taxonomy];
380
- }
381
 
382
  /**
383
  * @return bool|TimberPost
384
  */
385
  function get_parent() {
386
- if (!$this->post_parent) {
387
- return false;
388
- }
389
- return new $this->PostClass($this->post_parent);
390
- }
391
 
392
- /**
393
- * ## Gets a User object from the author of the post
394
- * <p class="byline">{{post.get_author.name}}</p>
395
- */
396
 
397
  /**
398
  * @return bool|TimberUser
399
  */
400
  function get_author() {
401
- if (isset($this->post_author)) {
402
- return new TimberUser($this->post_author);
403
- }
404
- return false;
405
- }
 
 
 
 
 
 
 
 
406
 
407
  /**
408
  * @param int $pid
409
  * @return null|object|WP_Post
410
  */
411
  function get_info($pid) {
412
- $post = $this->prepare_post_info($pid);
413
- if (!isset($post->post_status)) {
414
- return null;
415
- }
416
- $post->slug = $post->post_name;
417
- $post->status = $post->post_status;
418
- $customs = $this->get_post_custom($post->ID);
419
- $post = (object) array_merge((array) $post, (array) $customs);
420
- return $post;
421
- }
422
-
423
- /**
 
 
424
  * @param string $use
425
  * @return bool|string
426
  */
427
  function get_display_date($use = 'post_date') {
428
- return date(get_option('date_format'), strtotime($this->$use));
429
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
430
 
431
  /**
432
  * @param string $post_type
@@ -434,25 +479,25 @@ class TimberPost extends TimberCore {
434
  * @return array
435
  */
436
  function get_children($post_type = 'any', $childPostClass = false) {
437
- if ($childPostClass == false) {
438
- $childPostClass = $this->PostClass;
439
- }
440
- if ($post_type == 'parent') {
441
- $post_type = $this->post_type;
442
- }
443
- $children = get_children('post_parent=' . $this->ID . '&post_type=' . $post_type . '&numberposts=-1&orderby=menu_order title&order=ASC');
444
- foreach ($children as &$child) {
445
- $child = new $childPostClass($child->ID);
446
- }
447
- $children = array_values($children);
448
- return $children;
449
- }
450
 
451
- /**
452
- * {% for comment in post.get_comments %}
453
- * <p>{{comment.content}}</p>
454
- * {% endfor %}
455
- */
456
 
457
  /**
458
  * @param int $ct
@@ -463,49 +508,49 @@ class TimberPost extends TimberCore {
463
  * @return mixed
464
  */
465
  function get_comments($ct = 0, $order = 'wp', $type = 'comment', $status = 'approve', $CommentClass = 'TimberComment') {
466
- $args = array('post_id' => $this->ID, 'status' => $status, 'order' => $order);
467
- if ($ct > 0) {
468
- $args['number'] = $ct;
469
- }
470
- if ($order == 'wp'){
471
- $args['order'] = get_option('comment_order');
472
- }
473
- $comments = get_comments($args);
474
- foreach ($comments as &$comment) {
475
- $comment = new $CommentClass($comment);
476
- }
477
- return $comments;
478
- }
479
 
480
- /**
481
- * <ul class="categories">
482
- * {% for category in post.get_categories %}
483
- * <li>{{category.name}}</li>
484
- * {% endfor %}
485
- * </ul>
486
- */
487
 
488
  /**
489
  * @return array
490
  */
491
  function get_categories() {
492
- return $this->get_terms('category');
493
- }
494
 
495
  /**
496
  * @return mixed
497
  */
498
  function get_category() {
499
- $cats = $this->get_categories();
500
- if (count($cats) && isset($cats[0])) {
501
- return $cats[0];
502
- }
503
- return null;
504
- }
505
-
506
- /** # get terms is good
507
- *
508
- */
509
 
510
  /**
511
  * @param string $tax
@@ -514,111 +559,111 @@ class TimberPost extends TimberCore {
514
  * @return array
515
  */
516
  function get_terms($tax = '', $merge = true, $TermClass = 'TimberTerm') {
517
- if (is_string($tax)){
518
- if (isset($this->_get_terms) && isset($this->_get_terms[$tax])){
519
- return $this->_get_terms[$tax];
520
- }
521
- }
522
- if (!strlen($tax) || $tax == 'all' || $tax == 'any') {
523
- $taxs = get_object_taxonomies($this->post_type);
524
- } else if (is_array($tax)) {
525
- $taxs = $tax;
526
- } else {
527
- $taxs = array($tax);
528
- }
529
- $ret = array();
530
- foreach ($taxs as $tax) {
531
- if ($tax == 'tags' || $tax == 'tag') {
532
- $tax = 'post_tag';
533
- } else if ($tax == 'categories') {
534
- $tax = 'category';
535
- }
536
- $terms = wp_get_post_terms($this->ID, $tax);
537
- if (!is_array($terms) && is_object($terms) && get_class($terms) == 'WP_Error'){
538
- //something is very wrong
539
- TimberHelper::error_log('You have an error retrieving terms on a post in timber-post.php:367');
540
- TimberHelper::error_log('tax = '.$tax);
541
- TimberHelper::error_log($terms);
542
-
543
- } else {
544
- foreach ($terms as &$term) {
545
- $term = new $TermClass($term->term_id, $tax);
546
- }
547
- if ($merge && is_array($terms)) {
548
- $ret = array_merge($ret, $terms);
549
- } else if (count($terms)) {
550
- $ret[$tax] = $terms;
551
- }
552
- }
553
- }
554
- if (!isset($this->_get_terms)){
555
- $this->_get_terms = array();
556
- }
557
- $this->_get_terms[$tax] = $ret;
558
- return $ret;
559
- }
560
 
561
  /**
562
  * @param string|int $term_name_or_id
563
  * @param string $taxonomy
564
  * @return bool
565
  */
566
- function has_term($term_name_or_id, $taxonomy = 'all'){
567
- if ($taxonomy == 'all' || $taxonomy == 'any'){
568
- $taxes = get_object_taxonomies($this->post_type, 'names');
569
- $ret = false;
570
- foreach($taxes as $tax){
571
- if (has_term($term_name_or_id, $tax, $this->ID)){
572
- $ret = true;
573
- break;
574
- }
575
- }
576
- return $ret;
577
- }
578
- return has_term($term_name_or_id, $taxonomy, $this->ID);
579
- }
580
 
581
  /**
582
  * @param string $field
583
  * @return TimberImage
584
  */
585
  function get_image($field) {
586
- return new $this->ImageClass($this->$field);
587
- }
588
 
589
- /**
590
- * ## Gets an array of tags for you to use
591
- * <ul class="tags">
592
- * {% for tag in post.tags %}
593
- * <li>{{tag.name}}</li>
594
- * {% endfor %}
595
- * </ul>
596
- */
597
 
598
  /**
599
  * @return array
600
  */
601
  function get_tags() {
602
- return $this->get_terms('tags');
603
- }
604
 
605
- /**
606
- * ## Outputs the title with filters applied
607
- * <h1>{{post.get_title}}</h1>
608
- */
609
 
610
  /**
611
  * @return string
612
  */
613
  function get_title() {
614
- $title = $this->post_title;
615
- return apply_filters('the_title', $title);
616
- }
617
 
618
- /**
619
- * ## Displays the content of the post with filters, shortcodes and wpautop applied
620
- * <div class="article-text">{{post.get_content}}</div>
621
- */
622
 
623
  /**
624
  * @param int $len
@@ -626,274 +671,299 @@ class TimberPost extends TimberCore {
626
  * @return string
627
  */
628
  function get_content($len = 0, $page = 0) {
629
- if ($len == 0 && $page == 0 && $this->_content){
630
- return $this->_content;
631
- }
632
- $content = $this->post_content;
633
- if ($len) {
634
- $content = wp_trim_words($content, $len);
635
- }
636
- if ($page) {
637
- $contents = explode('<!--nextpage-->', $content);
638
- $page--;
639
- if (count($contents) > $page) {
640
- $content = $contents[$page];
641
- }
642
- }
643
- $content = apply_filters('the_content', ($content));
644
- if ($len == 0 && $page == 0){
645
- $this->_content = $content;
646
- }
647
- return $content;
648
- }
649
 
650
  /**
651
  * @return mixed
652
  */
653
  public function get_post_type() {
654
- return get_post_type_object($this->post_type);
655
- }
656
 
657
  /**
658
  * @return int
659
  */
660
  public function get_comment_count() {
661
- if (isset($this->ID)) {
662
- return get_comments_number($this->ID);
663
- } else {
664
- return 0;
665
- }
666
- }
667
 
668
  /**
669
  * @param string $field_name
670
  * @return mixed
671
  */
672
  public function get_field($field_name) {
673
- $value = apply_filters('timber_post_get_meta_field_pre', null, $this->ID, $field_name, $this);
674
- if ($value === null){
675
- $value = get_post_meta($this->ID, $field_name);
676
- if (is_array($value) && count($value) == 1){
677
- $value = $value[0];
678
- }
679
- if (is_array($value) && count($value) == 0){
680
- $value = null;
681
- }
682
- }
683
- $value = apply_filters('timber_post_get_meta_field', $value, $this->ID, $field_name, $this);
684
- return $value;
685
- }
686
 
687
  /**
688
  * @param string $field_name
689
  */
690
  function import_field($field_name) {
691
- $this->$field_name = $this->get_field($field_name);
692
- }
693
 
694
  /**
695
  * @return mixed
696
  */
697
- function get_format(){
698
- return get_post_format($this->ID);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
699
  }
700
 
701
- // Docs
702
 
703
  /**
704
  * @return array
705
  */
706
- public function get_method_values(){
707
- $ret = parent::get_method_values();
708
- $ret['author'] = $this->author();
709
- $ret['categories'] = $this->categories();
710
- $ret['category'] = $this->category();
711
- $ret['children'] = $this->children();
712
- $ret['comments'] = $this->comments();
713
- $ret['content'] = $this->content();
714
- $ret['display_date'] = $this->display_date();
715
- $ret['edit_link'] = $this->edit_link();
716
- $ret['format'] = $this->format();
717
- $ret['link'] = $this->link();
718
- $ret['next'] = $this->next();
719
- $ret['pagination'] = $this->pagination();
720
- $ret['parent'] = $this->parent();
721
- $ret['path'] = $this->path();
722
- $ret['prev'] = $this->prev();
723
- $ret['terms'] = $this->terms();
724
- $ret['tags'] = $this->tags();
725
- $ret['thumbnail'] = $this->thumbnail();
726
- $ret['title'] = $this->title();
727
- return $ret;
728
- }
729
-
730
- // Aliases
731
  /**
732
  * @return bool|TimberUser
733
  */
734
  public function author() {
735
- return $this->get_author();
736
- }
 
 
 
 
 
 
 
737
 
738
  /**
739
  * @return array
740
  */
741
  public function categories() {
742
- return $this->get_terms('category');
743
- }
744
 
745
  /**
746
  * @return mixed
747
  */
748
  public function category() {
749
- return $this->get_category();
750
- }
751
 
752
  /**
753
  * @return array
754
  */
755
  public function children() {
756
- return $this->get_children();
757
- }
758
 
759
  /**
760
  * @return mixed
761
  */
762
- public function comments(){
763
- return $this->get_comments();
764
- }
765
 
766
  /**
767
  * @param int $page
768
  * @return string
769
  */
770
- public function content($page = 0) {
771
- return $this->get_content(0, $page);
772
- }
773
 
774
  /**
775
- * @return mixed
 
776
  */
777
- public function display_date(){
778
- return date_i18n(get_option('date_format') , strtotime($this->post_date));
779
- }
780
 
781
  /**
782
  * @return bool|string
783
  */
784
- public function edit_link(){
785
- return $this->get_edit_url();
786
- }
787
 
788
  /**
789
  * @return mixed
790
  */
791
- public function format(){
792
- return $this->get_format();
793
- }
794
 
795
  /**
796
- * @return string */
 
797
  public function link() {
798
- return $this->get_permalink();
799
- }
800
 
801
  /**
802
  * @param string $field_name
803
  * @return mixed
804
  */
805
- public function meta($field_name = null){
806
- if ($field_name == null){
807
- $field_name = 'meta';
808
- }
809
- return $this->get_field($field_name);
810
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
811
 
812
  /**
813
  * @param bool $in_same_cat
814
  * @return mixed
815
  */
816
  public function next($in_same_cat = false) {
817
- return $this->get_next($in_same_cat);
818
- }
819
 
820
  /**
821
  * @return array
822
  */
823
- public function pagination(){
824
- return $this->get_pagination();
825
- }
826
 
827
  /**
828
  * @return bool|TimberPost
829
  */
830
- public function parent(){
831
- return $this->get_parent();
832
- }
833
 
834
  /**
835
  * @return string
836
  */
837
  public function path() {
838
- return $this->get_path();
839
- }
840
 
841
  /**
842
  * @return string
843
  */
844
  public function permalink() {
845
- return $this->get_permalink();
846
- }
847
 
848
  /**
849
  * @param bool $in_same_cat
850
  * @return mixed
851
  */
852
  public function prev($in_same_cat = false) {
853
- return $this->get_prev($in_same_cat);
854
- }
855
 
856
  /**
857
  * @param string $tax
858
  * @return array
859
  */
860
  public function terms($tax = '') {
861
- return $this->get_terms($tax);
862
- }
863
 
864
  /**
865
  * @return array
866
  */
867
  public function tags() {
868
- return $this->get_tags();
869
- }
870
 
871
  /**
872
  * @return null|TimberImage
873
  */
874
  public function thumbnail() {
875
- return $this->get_thumbnail();
876
- }
877
 
878
  /**
879
  * @return string
880
  */
881
  public function title() {
882
- return $this->get_title();
883
- }
884
-
885
- /**
886
- * @param string $class
887
- * @return string
888
- */
889
- public function post_class($class='') {
890
- global $post;
891
- $old_global_post = $post;
892
- $post = $this;
893
- $class_array = get_post_class($class, $this->ID);
894
- $post = $old_global_post;
895
- return implode(' ', $class_array);
896
- }
897
-
898
 
899
  }
1
  <?php
2
 
3
+ class TimberPost extends TimberCore
4
+ {
5
 
6
+ public $ImageClass = 'TimberImage';
7
+ public $PostClass = 'TimberPost';
8
+ public $_can_edit;
9
+ public $_get_terms;
10
+ public $_content;
11
+ public $object_type = 'post';
12
 
13
+ public $_custom_imported = false;
14
 
15
+ public static $representation = 'post';
16
 
17
+ public $post_type;
18
+ public $class;
19
+ public $id;
20
+ public $post_parent;
21
+ public $post_date;
22
+ public $post_title;
23
+ public $post_content;
24
 
25
+
26
+ /**
27
+ * If you send the constructor nothing it will try to figure out the current post id based on being inside The_Loop
28
+ * @param mixed $pid
29
+ * @return \TimberPost TimberPost object -- woo!
30
+ */
31
+ function __construct($pid = null) {
32
+ if ($pid === null && get_the_ID()) {
33
+ $pid = get_the_ID();
34
+ $this->ID = $pid;
35
+ } else if ($pid === null && ($pid_from_loop = Timber::loop_to_id())) {
36
+ $this->ID = $pid_from_loop;
37
+ }
38
+ if (is_numeric($pid)) {
39
+ $this->ID = $pid;
40
+ }
41
+ $this->init($pid);
42
+ }
 
 
 
43
 
44
  /**
45
  * @param int|bool $pid
50
  }
51
  $post_info = $this->get_info($pid);
52
  $this->import($post_info);
53
+ /* deprecated, adding for support for older themes */
54
+ $this->display_date = $this->date();
55
  //cant have a function, so gots to do it this way
56
  $post_class = $this->post_class();
57
  $this->class = $post_class;
58
  }
59
 
60
+ /**
61
+ * Get the URL that will edit the current post/object
62
  *
63
  * @return bool|string
64
  */
65
  function get_edit_url() {
66
+ if ($this->can_edit()) {
67
+ return get_edit_post_link($this->ID);
68
+ }
69
+ return false;
70
+ }
 
71
 
72
+ /**
73
+ * updates the post_meta of the current object with the given value
74
+ *
75
+ * @param string $field
76
+ * @param mixed $value
77
+ */
78
+ public function update($field, $value) {
79
+ if (isset($this->ID)) {
80
+ update_post_meta($this->ID, $field, $value);
81
+ $this->$field = $value;
82
+ }
83
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
 
85
 
86
+ /**
87
+ * takes a mix of integer (post ID), string (post slug), or object to return a WordPress post object from WP's built-in get_post() function
88
+ *
89
+ * @param mixed $pid
90
+ * @return WP_Post on success
91
+ */
92
+ private function prepare_post_info($pid = 0) {
93
+ if (is_string($pid) || is_numeric($pid) || (is_object($pid) && !isset($pid->post_title)) || $pid === 0) {
94
+ $pid = self::check_post_id($pid);
95
+ $post = get_post($pid);
96
+ if ($post) {
97
+ return $post;
98
+ } else {
99
+ $post = get_page($pid);
100
+ return $post;
101
+ }
102
+ }
103
+ //we can skip if already is WP_Post
104
+ return $pid;
105
+ }
106
+
107
+
108
+ /**
109
+ * helps you find the post id regardless of whetehr you send a string or whatever
110
+ *
111
+ * @param mixed $pid ;
112
+ * @return integer ID number of a post
113
+ */
114
+ private function check_post_id($pid) {
115
+ if (is_numeric($pid) && $pid === 0) {
116
+ $pid = get_the_ID();
117
+ return $pid;
118
+ }
119
+ if (!is_numeric($pid) && is_string($pid)) {
120
+ $pid = self::get_post_id_by_name($pid);
121
+ return $pid;
122
+ }
123
+ if (!$pid) {
124
+ return null;
125
+ }
126
+ return $pid;
127
+ }
128
+
129
+
130
+ /**
131
+ * get_post_id_by_name($post_name)
132
  *
133
  * @param $post_name
134
  * @return int
135
  */
136
  public static function get_post_id_by_name($post_name) {
137
+ global $wpdb;
138
+ $query = $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_name = %s LIMIT 1", $post_name);
139
+ $result = $wpdb->get_row($query);
140
+ if (!$result) {
141
+ return null;
142
+ }
143
+ return $result->ID;
144
+ }
145
 
146
 
147
+ /**
148
+ * ## get a preview of your post, if you have an excerpt it will use that,
149
+ * ## otherwise it will pull from the post_content.
150
+ * ## If there's a <!-- more --> tag it will use that to mark where to pull through.
151
+ * <p>{{post.get_preview(50)}}</p>
152
+ */
153
 
154
  /**
155
  * @param int $len
159
  * @return string
160
  */
161
  function get_preview($len = 50, $force = false, $readmore = 'Read More', $strip = true) {
162
+ $text = '';
163
+ $trimmed = false;
164
+ if (isset($this->post_excerpt) && strlen($this->post_excerpt)) {
165
+ if ($force) {
166
+ $text = TimberHelper::trim_words($this->post_excerpt, $len, false);
167
+ $trimmed = true;
168
+ } else {
169
+ $text = $this->post_excerpt;
170
+ }
171
+ }
172
+ if (!strlen($text) && strpos($this->post_content, '<!--more-->') !== false) {
173
+ $pieces = explode('<!--more-->', $this->post_content);
174
+ $text = $pieces[0];
175
+ if ($force) {
176
+ $text = TimberHelper::trim_words($text, $len, false);
177
+ $trimmed = true;
178
+ }
179
+ }
180
+ if (!strlen($text)) {
181
+ $text = TimberHelper::trim_words($this->get_content(), $len, false);
182
+ $trimmed = true;
183
+ }
184
+ if (!strlen(trim($text))) {
185
+ return $text;
186
+ }
187
+ if ($strip) {
188
+ $text = trim(strip_tags($text));
189
+ }
190
+ if (strlen($text)) {
191
+ $text = trim($text);
192
+ $last = $text[strlen($text) - 1];
193
+ if ($last != '.' && $trimmed) {
194
+ $text .= ' &hellip; ';
195
+ }
196
+ if (!$strip) {
197
+ $last_p_tag = strrpos($text, '</p>');
198
+ if ($last_p_tag !== false) {
199
+ $text = substr($text, 0, $last_p_tag);
200
+ }
201
+ if ($last != '.' && $trimmed) {
202
+ $text .= ' &hellip; ';
203
+ }
204
+ }
205
+
206
+ if ($readmore) {
207
+ $text .= ' <a href="' . $this->get_permalink() . '" class="read-more">' . $readmore . '</a>';
208
+ }
209
+ if (!$strip) {
210
+ $text .= '</p>';
211
+ }
212
+ }
213
+ return $text;
214
+ }
215
 
216
  /**
217
  * gets the post custom and attaches it to the current object
218
  * @param bool|int $pid a post ID number
219
  * @nodoc
220
  */
221
+ function import_custom($pid = false) {
222
+ if (!$pid) {
223
+ $pid = $this->ID;
224
+ }
225
+ $customs = $this->get_post_custom($pid);
226
+ $this->import($customs);
227
+ }
228
 
229
  /**
230
  * @param int $pid
231
  * @return array
232
  */
233
  function get_post_custom($pid) {
234
+ apply_filters('timber_post_get_meta_pre', array(), $pid, $this);
235
+ $customs = get_post_custom($pid);
236
+ if (!is_array($customs) || empty($customs)) {
237
+ return array();
238
+ }
239
+ foreach ($customs as $key => $value) {
240
+ if (is_array($value) && count($value) == 1 && isset($value[0])) {
241
+ $value = $value[0];
242
+ }
243
+ $customs[$key] = maybe_unserialize($value);
244
+ }
245
+ $customs = apply_filters('timber_post_get_meta', $customs, $pid, $this);
246
+ return $customs;
247
+ }
248
 
249
+ /**
250
+ * ## get the featured image as a TimberImage
251
+ * <img src="{{post.get_thumbnail.get_src}}" />
252
+ */
253
 
254
  /**
255
  * @return null|TimberImage
256
  */
257
  function get_thumbnail() {
258
+ if (function_exists('get_post_thumbnail_id')) {
259
+ $tid = get_post_thumbnail_id($this->ID);
260
+ if ($tid) {
261
+ return new $this->ImageClass($tid);
262
+ }
263
+ }
264
+ return null;
265
+ }
266
 
267
  /**
268
  * @return string
269
  */
270
  function get_permalink() {
271
+ if (isset($this->permalink)) {
272
+ return $this->permalink;
273
+ }
274
+ $this->permalink = get_permalink($this->ID);
275
+ return $this->permalink;
276
+ }
277
 
278
  /**
279
  * @return string
280
  */
281
  function get_link() {
282
+ return $this->get_permalink();
283
+ }
284
 
285
  /**
286
  * @param bool $by_taxonomy
287
  * @return mixed
288
  */
289
  function get_next($by_taxonomy = false) {
290
+ if (!isset($this->_next) || !isset($this->_next[$by_taxonomy])) {
291
+ global $post;
292
+ $this->_next = array();
293
+ $old_global = $post;
294
+ $post = $this;
295
+ if ($by_taxonomy == 'category' || $by_taxonomy == 'categories') {
296
+ $in_same_cat = true;
297
+ } else {
298
+ $in_same_cat = false;
299
+ }
300
+ $adjacent = get_adjacent_post($in_same_cat, '', false);
301
+ if ($adjacent) {
302
+ $this->_next[$by_taxonomy] = new $this->PostClass($adjacent);
303
+ } else {
304
+ $this->_next[$by_taxonomy] = false;
305
+ }
306
+ $post = $old_global;
307
+ }
308
+ return $this->_next[$by_taxonomy];
309
+ }
310
 
311
  /**
312
  * @return array
313
  */
314
+ public function get_pagination() {
315
+ global $post, $page, $numpages, $multipage;
316
+ $post = $this;
317
+ $ret = array();
318
+ if ($multipage) {
319
+ for ($i = 1; $i <= $numpages; $i++) {
320
+ $link = self::get_wp_link_page($i);
321
+ $data = array('name' => $i, 'title' => $i, 'text' => $i, 'link' => $link);
322
+ if ($i == $page) {
323
+ $data['current'] = true;
324
+ }
325
+ $ret['pages'][] = $data;
326
+ }
327
+ $i = $page - 1;
328
+ if ($i) {
329
+ $link = self::get_wp_link_page($i);
330
+ $ret['prev'] = array('link' => $link);
331
+ }
332
+ $i = $page + 1;
333
+ if ($i <= $numpages) {
334
+ $link = self::get_wp_link_page($i);
335
+ $ret['next'] = array('link' => $link);
336
+ }
337
+ }
338
+ return $ret;
339
+ }
 
340
 
341
  /**
342
  * @param int $i
343
  * @return string
344
  */
345
+ private static function get_wp_link_page($i) {
346
+ $link = _wp_link_page($i);
347
+ $link = new SimpleXMLElement($link . '</a>');
348
+ if (isset($link['href'])) {
349
+ return $link['href'];
350
+ }
351
+ return '';
352
+ }
353
 
354
  /**
355
  * @return string
356
  */
357
  function get_path() {
358
+ return TimberURLHelper::get_rel_url($this->get_link());
359
+ }
360
 
361
  /**
362
  * @param bool $by_taxonomy
363
  * @return mixed
364
  */
365
  function get_prev($by_taxonomy = false) {
366
+ if (!isset($this->_prev) || !isset($this->_prev[$by_taxonomy])) {
367
+ global $post;
368
+ $this->_prev = array();
369
+ $old_global = $post;
370
+ $post = $this;
371
+ if ($by_taxonomy == 'category' || $by_taxonomy == 'categories') {
372
+ $in_same_cat = true;
373
+ } else {
374
+ $in_same_cat = false;
375
+ }
376
+ $adjacent = get_adjacent_post($in_same_cat, '', true);
377
+ if ($adjacent) {
378
+ $this->_prev[$by_taxonomy] = new $this->PostClass($adjacent);
379
+ } else {
380
+ $this->_prev[$by_taxonomy] = false;
381
+ }
382
+ $post = $old_global;
383
+ }
384
+ return $this->_prev[$by_taxonomy];
385
+ }
386
 
387
  /**
388
  * @return bool|TimberPost
389
  */
390
  function get_parent() {
391
+ if (!$this->post_parent) {
392
+ return false;
393
+ }
394
+ return new $this->PostClass($this->post_parent);
395
+ }
396
 
397
+ /**
398
+ * ## Gets a User object from the author of the post
399
+ * <p class="byline">{{post.get_author.name}}</p>
400
+ */
401
 
402
  /**
403
  * @return bool|TimberUser
404
  */
405
  function get_author() {
406
+ if (isset($this->post_author)) {
407
+ return new TimberUser($this->post_author);
408
+ }
409
+ return false;
410
+ }
411
+
412
+ /**
413
+ * @return bool|TimberUser
414
+ */
415
+ function get_modified_author() {
416
+ $user_id = get_post_meta($this->ID, '_edit_last', true);
417
+ return ($user_id ? new TimberUser($user_id) : $this->get_author());
418
+ }
419
 
420
  /**
421
  * @param int $pid
422
  * @return null|object|WP_Post
423
  */
424
  function get_info($pid) {
425
+ $post = $this->prepare_post_info($pid);
426
+ if (!isset($post->post_status)) {
427
+ return null;
428
+ }
429
+ $post->slug = $post->post_name;
430
+ $post->id = $post->ID;
431
+ $post->status = $post->post_status;
432
+ $customs = $this->get_post_custom($post->ID);
433
+ $post = (object)array_merge((array)$post, (array)$customs);
434
+ return $post;
435
+ }
436
+
437
+ /**
438
+ * This is deprecated!
439
  * @param string $use
440
  * @return bool|string
441
  */
442
  function get_display_date($use = 'post_date') {
443
+ return date(get_option('date_format'), strtotime($this->$use));
444
+ }
445
+
446
+ /**
447
+ * @param string $date_format
448
+ * @return string
449
+ */
450
+ function get_date($date_format = '') {
451
+ $df = $date_format ? $date_format : get_option('date_format');
452
+ $the_date = (string)mysql2date($df, $this->post_date);
453
+ return apply_filters('get_the_date', $the_date, $date_format);
454
+ }
455
+
456
+ /**
457
+ * @param string $date_format
458
+ * @return string
459
+ */
460
+ function get_modified_date($date_format = '') {
461
+ $df = $date_format ? $date_format : get_option('date_format');
462
+ $the_time = $this->get_modified_time($df, null, $this->ID, true);
463
+ return apply_filters('get_the_modified_date', $the_time, $date_format);
464
+ }
465
+
466
+ /**
467
+ * @param string $time_format
468
+ * @return string
469
+ */
470
+ function get_modified_time($time_format = '') {
471
+ $tf = $time_format ? $time_format : get_option('time_format');
472
+ $the_time = get_post_modified_time($tf, false, $this->ID, true);
473
+ return apply_filters('get_the_modified_time', $the_time, $time_format);
474
+ }
475
 
476
  /**
477
  * @param string $post_type
479
  * @return array
480
  */
481
  function get_children($post_type = 'any', $childPostClass = false) {
482
+ if ($childPostClass == false) {
483
+ $childPostClass = $this->PostClass;
484
+ }
485
+ if ($post_type == 'parent') {
486
+ $post_type = $this->post_type;
487
+ }
488
+ $children = get_children('post_parent=' . $this->ID . '&post_type=' . $post_type . '&numberposts=-1&orderby=menu_order title&order=ASC');
489
+ foreach ($children as &$child) {
490
+ $child = new $childPostClass($child->ID);
491
+ }
492
+ $children = array_values($children);
493
+ return $children;
494
+ }
495
 
496
+ /**
497
+ * {% for comment in post.get_comments %}
498
+ * <p>{{comment.content}}</p>
499
+ * {% endfor %}
500
+ */
501
 
502
  /**
503
  * @param int $ct
508
  * @return mixed
509
  */
510
  function get_comments($ct = 0, $order = 'wp', $type = 'comment', $status = 'approve', $CommentClass = 'TimberComment') {
511
+ $args = array('post_id' => $this->ID, 'status' => $status, 'order' => $order);
512
+ if ($ct > 0) {
513
+ $args['number'] = $ct;
514
+ }
515
+ if ($order == 'wp') {
516
+ $args['order'] = get_option('comment_order');
517
+ }
518
+ $comments = get_comments($args);
519
+ foreach ($comments as &$comment) {
520
+ $comment = new $CommentClass($comment);
521
+ }
522
+ return $comments;
523
+ }
524
 
525
+ /**
526
+ * <ul class="categories">
527
+ * {% for category in post.get_categories %}
528
+ * <li>{{category.name}}</li>
529
+ * {% endfor %}
530
+ * </ul>
531
+ */
532
 
533
  /**
534
  * @return array
535
  */
536
  function get_categories() {
537
+ return $this->get_terms('category');
538
+ }
539
 
540
  /**
541
  * @return mixed
542
  */
543
  function get_category() {
544
+ $cats = $this->get_categories();
545
+ if (count($cats) && isset($cats[0])) {
546
+ return $cats[0];
547
+ }
548
+ return null;
549
+ }
550
+
551
+ /** # get terms is good
552
+ *
553
+ */
554
 
555
  /**
556
  * @param string $tax
559
  * @return array
560
  */
561
  function get_terms($tax = '', $merge = true, $TermClass = 'TimberTerm') {
562
+ if (is_string($tax)) {
563
+ if (isset($this->_get_terms) && isset($this->_get_terms[$tax])) {
564
+ return $this->_get_terms[$tax];
565
+ }
566
+ }
567
+ if (!strlen($tax) || $tax == 'all' || $tax == 'any') {
568
+ $taxs = get_object_taxonomies($this->post_type);
569
+ } else if (is_array($tax)) {
570
+ $taxs = $tax;
571
+ } else {
572
+ $taxs = array($tax);
573
+ }
574
+ $ret = array();
575
+ foreach ($taxs as $tax) {
576
+ if ($tax == 'tags' || $tax == 'tag') {
577
+ $tax = 'post_tag';
578
+ } else if ($tax == 'categories') {
579
+ $tax = 'category';
580
+ }
581
+ $terms = wp_get_post_terms($this->ID, $tax);
582
+ if (!is_array($terms) && is_object($terms) && get_class($terms) == 'WP_Error') {
583
+ //something is very wrong
584
+ TimberHelper::error_log('You have an error retrieving terms on a post in timber-post.php:367');
585
+ TimberHelper::error_log('tax = ' . $tax);
586
+ TimberHelper::error_log($terms);
587
+
588
+ } else {
589
+ foreach ($terms as &$term) {
590
+ $term = new $TermClass($term->term_id, $tax);
591
+ }
592
+ if ($merge && is_array($terms)) {
593
+ $ret = array_merge($ret, $terms);
594
+ } else if (count($terms)) {
595
+ $ret[$tax] = $terms;
596
+ }
597
+ }
598
+ }
599
+ if (!isset($this->_get_terms)) {
600
+ $this->_get_terms = array();
601
+ }
602
+ $this->_get_terms[$tax] = $ret;
603
+ return $ret;
604
+ }
605
 
606
  /**
607
  * @param string|int $term_name_or_id
608
  * @param string $taxonomy
609
  * @return bool
610
  */
611
+ function has_term($term_name_or_id, $taxonomy = 'all') {
612
+ if ($taxonomy == 'all' || $taxonomy == 'any') {
613
+ $taxes = get_object_taxonomies($this->post_type, 'names');
614
+ $ret = false;
615
+ foreach ($taxes as $tax) {
616
+ if (has_term($term_name_or_id, $tax, $this->ID)) {
617
+ $ret = true;
618
+ break;
619
+ }
620
+ }
621
+ return $ret;
622
+ }
623
+ return has_term($term_name_or_id, $taxonomy, $this->ID);
624
+ }
625
 
626
  /**
627
  * @param string $field
628
  * @return TimberImage
629
  */
630
  function get_image($field) {
631
+ return new $this->ImageClass($this->$field);
632
+ }
633
 
634
+ /**
635
+ * ## Gets an array of tags for you to use
636
+ * <ul class="tags">
637
+ * {% for tag in post.tags %}
638
+ * <li>{{tag.name}}</li>
639
+ * {% endfor %}
640
+ * </ul>
641
+ */
642
 
643
  /**
644
  * @return array
645
  */
646
  function get_tags() {
647
+ return $this->get_terms('tags');
648
+ }
649
 
650
+ /**
651
+ * ## Outputs the title with filters applied
652
+ * <h1>{{post.get_title}}</h1>
653
+ */
654
 
655
  /**
656
  * @return string
657
  */
658
  function get_title() {
659
+ $title = $this->post_title;
660
+ return apply_filters('the_title', $title);
661
+ }
662
 
663
+ /**
664
+ * ## Displays the content of the post with filters, shortcodes and wpautop applied
665
+ * <div class="article-text">{{post.get_content}}</div>
666
+ */
667
 
668
  /**
669
  * @param int $len
671
  * @return string
672
  */
673
  function get_content($len = 0, $page = 0) {
674
+ if ($len == 0 && $page == 0 && $this->_content) {
675
+ return $this->_content;
676
+ }
677
+ $content = $this->post_content;
678
+ if ($len) {
679
+ $content = wp_trim_words($content, $len);
680
+ }
681
+ if ($page) {
682
+ $contents = explode('<!--nextpage-->', $content);
683
+ $page--;
684
+ if (count($contents) > $page) {
685
+ $content = $contents[$page];
686
+ }
687
+ }
688
+ $content = apply_filters('the_content', ($content));
689
+ if ($len == 0 && $page == 0) {
690
+ $this->_content = $content;
691
+ }
692
+ return $content;
693
+ }
694
 
695
  /**
696
  * @return mixed
697
  */
698
  public function get_post_type() {
699
+ return get_post_type_object($this->post_type);
700
+ }
701
 
702
  /**
703
  * @return int
704
  */
705
  public function get_comment_count() {
706
+ if (isset($this->ID)) {
707
+ return get_comments_number($this->ID);
708
+ } else {
709
+ return 0;
710
+ }
711
+ }
712
 
713
  /**
714
  * @param string $field_name
715
  * @return mixed
716
  */
717
  public function get_field($field_name) {
718
+ $value = apply_filters('timber_post_get_meta_field_pre', null, $this->ID, $field_name, $this);
719
+ if ($value === null) {
720
+ $value = get_post_meta($this->ID, $field_name);
721
+ if (is_array($value) && count($value) == 1) {
722
+ $value = $value[0];
723
+ }
724
+ if (is_array($value) && count($value) == 0) {
725
+ $value = null;
726
+ }
727
+ }
728
+ $value = apply_filters('timber_post_get_meta_field', $value, $this->ID, $field_name, $this);
729
+ return $value;
730
+ }
731
 
732
  /**
733
  * @param string $field_name
734
  */
735
  function import_field($field_name) {
736
+ $this->$field_name = $this->get_field($field_name);
737
+ }
738
 
739
  /**
740
  * @return mixed
741
  */
742
+ function get_format() {
743
+ return get_post_format($this->ID);
744
+ }
745
+
746
+ /**
747
+ * @param string $class
748
+ * @return string
749
+ */
750
+ public function post_class($class='') {
751
+ global $post;
752
+ $old_global_post = $post;
753
+ $post = $this;
754
+ $class_array = get_post_class($class, $this->ID);
755
+ $post = $old_global_post;
756
+ if (is_array($class_array)){
757
+ return implode(' ', $class_array);
758
+ }
759
+ return $class_array;
760
  }
761
 
762
+ // Docs
763
 
764
  /**
765
  * @return array
766
  */
767
+ public function get_method_values() {
768
+ $ret = parent::get_method_values();
769
+ $ret['author'] = $this->author();
770
+ $ret['categories'] = $this->categories();
771
+ $ret['category'] = $this->category();
772
+ $ret['children'] = $this->children();
773
+ $ret['comments'] = $this->comments();
774
+ $ret['content'] = $this->content();
775
+ $ret['display_date'] = $this->display_date();
776
+ $ret['edit_link'] = $this->edit_link();
777
+ $ret['format'] = $this->format();
778
+ $ret['link'] = $this->link();
779
+ $ret['next'] = $this->next();
780
+ $ret['pagination'] = $this->pagination();
781
+ $ret['parent'] = $this->parent();
782
+ $ret['path'] = $this->path();
783
+ $ret['prev'] = $this->prev();
784
+ $ret['terms'] = $this->terms();
785
+ $ret['tags'] = $this->tags();
786
+ $ret['thumbnail'] = $this->thumbnail();
787
+ $ret['title'] = $this->title();
788
+ return $ret;
789
+ }
790
+
791
+ // Aliases
792
  /**
793
  * @return bool|TimberUser
794
  */
795
  public function author() {
796
+ return $this->get_author();
797
+ }
798
+
799
+ /**
800
+ * @return bool|TimberUser
801
+ */
802
+ public function modified_author() {
803
+ return $this->get_modified_author();
804
+ }
805
 
806
  /**
807
  * @return array
808
  */
809
  public function categories() {
810
+ return $this->get_terms('category');
811
+ }
812
 
813
  /**
814
  * @return mixed
815
  */
816
  public function category() {
817
+ return $this->get_category();
818
+ }
819
 
820
  /**
821
  * @return array
822
  */
823
  public function children() {
824
+ return $this->get_children();
825
+ }
826
 
827
  /**
828
  * @return mixed
829
  */
830
+ public function comments() {
831
+ return $this->get_comments();
832
+ }
833
 
834
  /**
835
  * @param int $page
836
  * @return string
837
  */
838
+ public function content($page = 0) {
839
+ return $this->get_content(0, $page);
840
+ }
841
 
842
  /**
843
+ * @param string $date_format
844
+ * @return string
845
  */
846
+ public function date($date_format = '') {
847
+ return $this->get_date($date_format);
848
+ }
849
 
850
  /**
851
  * @return bool|string
852
  */
853
+ public function edit_link() {
854
+ return $this->get_edit_url();
855
+ }
856
 
857
  /**
858
  * @return mixed
859
  */
860
+ public function format() {
861
+ return $this->get_format();
862
+ }
863
 
864
  /**
865
+ * @return string
866
+ */
867
  public function link() {
868
+ return $this->get_permalink();
869
+ }
870
 
871
  /**
872
  * @param string $field_name
873
  * @return mixed
874
  */
875
+ public function meta($field_name = null) {
876
+ if ($field_name == null) {
877
+ $field_name = 'meta';
878
+ }
879
+ return $this->get_field($field_name);
880
+ }
881
+
882
+ /**
883
+ * @return string
884
+ */
885
+ public function modified_date($date_format = '') {
886
+ return $this->get_modified_date($date_format);
887
+ }
888
+
889
+ /**
890
+ * @return string
891
+ */
892
+ public function modified_time($time_format = '') {
893
+ return $this->get_modified_time($time_format);
894
+ }
895
 
896
  /**
897
  * @param bool $in_same_cat
898
  * @return mixed
899
  */
900
  public function next($in_same_cat = false) {
901
+ return $this->get_next($in_same_cat);
902
+ }
903
 
904
  /**
905
  * @return array
906
  */
907
+ public function pagination() {
908
+ return $this->get_pagination();
909
+ }
910
 
911
  /**
912
  * @return bool|TimberPost
913
  */
914
+ public function parent() {
915
+ return $this->get_parent();
916
+ }
917
 
918
  /**
919
  * @return string
920
  */
921
  public function path() {
922
+ return $this->get_path();
923
+ }
924
 
925
  /**
926
  * @return string
927
  */
928
  public function permalink() {
929
+ return $this->get_permalink();
930
+ }
931
 
932
  /**
933
  * @param bool $in_same_cat
934
  * @return mixed
935
  */
936
  public function prev($in_same_cat = false) {
937
+ return $this->get_prev($in_same_cat);
938
+ }
939
 
940
  /**
941
  * @param string $tax
942
  * @return array
943
  */
944
  public function terms($tax = '') {
945
+ return $this->get_terms($tax);
946
+ }
947
 
948
  /**
949
  * @return array
950
  */
951
  public function tags() {
952
+ return $this->get_tags();
953
+ }
954
 
955
  /**
956
  * @return null|TimberImage
957
  */
958
  public function thumbnail() {
959
+ return $this->get_thumbnail();
960
+ }
961
 
962
  /**
963
  * @return string
964
  */
965
  public function title() {
966
+ return $this->get_title();
967
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
968
 
969
  }
functions/timber-site.php CHANGED
@@ -1,12 +1,25 @@
1
  <?php
2
 
3
- class TimberSite extends TimberCore {
4
-
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  /**
6
  * @param string|int $site_name_or_id
7
  */
8
- function __construct($site_name_or_id = null){
9
- if (is_multisite()){
10
  $this->init_with_multisite($site_name_or_id);
11
  } else {
12
  $this->init();
@@ -16,10 +29,10 @@ class TimberSite extends TimberCore {
16
  /**
17
  * @param string|int $site_name_or_id
18
  */
19
- function init_with_multisite($site_name_or_id){
20
- if ($site_name_or_id === null){
21
  //this is necessary for some reason, otherwise returns 1 all the time
22
- if (is_multisite()){
23
  restore_current_blog();
24
  $site_name_or_id = get_current_blog_id();
25
  }
@@ -34,9 +47,10 @@ class TimberSite extends TimberCore {
34
  $theme_slug = get_blog_option($info->blog_id, 'stylesheet');
35
  $this->theme = new TimberTheme($theme_slug);
36
  $this->description = get_blog_option($info->blog_id, 'blogdescription');
 
37
  }
38
 
39
- function init(){
40
  $this->name = get_bloginfo('name');
41
  $this->title = $this->name;
42
  $this->description = get_bloginfo('description');
@@ -44,15 +58,17 @@ class TimberSite extends TimberCore {
44
  $this->language = get_bloginfo('language');
45
  $this->charset = get_bloginfo('charset');
46
  $this->pingback_url = get_bloginfo('pingback_url');
 
47
  $this->language_attributes = TimberHelper::function_wrapper('language_attributes');
 
48
  }
49
 
50
  /**
51
  * @param string $field
52
  * @return mixed
53
  */
54
- function __get($field){
55
- if (!isset($this->$field)){
56
  $this->$field = get_blog_option($this->ID, $field);
57
  }
58
  return $this->$field;
@@ -61,28 +77,29 @@ class TimberSite extends TimberCore {
61
  /**
62
  * @return string
63
  */
64
- function get_link(){
65
  return $this->siteurl;
66
  }
67
 
68
  /**
69
  * @return string
70
  */
71
- function get_url(){
72
  return $this->get_link();
73
  }
74
 
75
  /**
76
  * @return string
77
  */
78
- function link(){
79
  return $this->get_link();
80
  }
81
 
82
  /**
83
  * @return string
84
  */
85
- function url(){
86
  return $this->get_link();
87
  }
 
88
  }
1
  <?php
2
 
3
+ class TimberSite extends TimberCore
4
+ {
5
+ public $blogname;
6
+ public $charset;
7
+ public $description;
8
+ public $id;
9
+ public $language;
10
+ public $language_attributes;
11
+ public $multisite;
12
+ public $name;
13
+ public $pingback_url;
14
+ public $siteurl;
15
+ public $theme;
16
+ public $title;
17
+
18
  /**
19
  * @param string|int $site_name_or_id
20
  */
21
+ function __construct($site_name_or_id = null) {
22
+ if (is_multisite()) {
23
  $this->init_with_multisite($site_name_or_id);
24
  } else {
25
  $this->init();
29
  /**
30
  * @param string|int $site_name_or_id
31
  */
32
+ function init_with_multisite($site_name_or_id) {
33
+ if ($site_name_or_id === null) {
34
  //this is necessary for some reason, otherwise returns 1 all the time
35
+ if (is_multisite()) {
36
  restore_current_blog();
37
  $site_name_or_id = get_current_blog_id();
38
  }
47
  $theme_slug = get_blog_option($info->blog_id, 'stylesheet');
48
  $this->theme = new TimberTheme($theme_slug);
49
  $this->description = get_blog_option($info->blog_id, 'blogdescription');
50
+ $this->multisite = true;
51
  }
52
 
53
+ function init() {
54
  $this->name = get_bloginfo('name');
55
  $this->title = $this->name;
56
  $this->description = get_bloginfo('description');
58
  $this->language = get_bloginfo('language');
59
  $this->charset = get_bloginfo('charset');
60
  $this->pingback_url = get_bloginfo('pingback_url');
61
+ $this->theme = new TimberTheme();
62
  $this->language_attributes = TimberHelper::function_wrapper('language_attributes');
63
+ $this->multisite = false;
64
  }
65
 
66
  /**
67
  * @param string $field
68
  * @return mixed
69
  */
70
+ function __get($field) {
71
+ if (!isset($this->$field)) {
72
  $this->$field = get_blog_option($this->ID, $field);
73
  }
74
  return $this->$field;
77
  /**
78
  * @return string
79
  */
80
+ function get_link() {
81
  return $this->siteurl;
82
  }
83
 
84
  /**
85
  * @return string
86
  */
87
+ function get_url() {
88
  return $this->get_link();
89
  }
90
 
91
  /**
92
  * @return string
93
  */
94
+ function link() {
95
  return $this->get_link();
96
  }
97
 
98
  /**
99
  * @return string
100
  */
101
+ function url() {
102
  return $this->get_link();
103
  }
104
+
105
  }
functions/timber-term-getter.php CHANGED
@@ -1,12 +1,13 @@
1
  <?php
2
 
3
- class TimberTermGetter {
 
4
 
5
  /**
6
  * @param string $query_string
7
  * @return stdClass
8
  */
9
- public static function get_term_query_from_query_string($query_string){
10
  $args = array();
11
  parse_str($query_string, $args);
12
  $ret = self::get_term_query_from_assoc_array($args);
@@ -17,10 +18,10 @@ class TimberTermGetter {
17
  * @param string $taxs
18
  * @return stdClass
19
  */
20
- public static function get_term_query_from_string($taxs){
21
  $ret = new stdClass();
22
  $ret->args = array();
23
- if (is_string($taxs)){
24
  $taxs = array($taxs);
25
  }
26
  $ret->taxonomies = self::correct_taxonomy_names($taxs);
@@ -31,20 +32,20 @@ class TimberTermGetter {
31
  * @param array $args
32
  * @return stdClass
33
  */
34
- public static function get_term_query_from_assoc_array($args){
35
  $ret = new stdClass();
36
  $ret->args = $args;
37
- if (isset($ret->args['tax'])){
38
  $ret->taxonomies = $ret->args['tax'];
39
- } else if (isset($ret->args['taxonomies'])){
40
  $ret->taxonomies = $ret->args['taxonomies'];
41
- } else if (isset($ret->args['taxs'])){
42
  $ret->taxonomies = $ret->args['taxs'];
43
- } else if (isset($ret->args['taxonomy'])){
44
  $ret->taxonomies = $ret->args['taxonomy'];
45
  }
46
- if (isset($ret->taxonomies)){
47
- if (is_string($ret->taxonomies)){
48
  $ret->taxonomies = array($ret->taxonomies);
49
  }
50
  $ret->taxonomies = self::correct_taxonomy_names($ret->taxonomies);
@@ -56,51 +57,52 @@ class TimberTermGetter {
56
  * @param array $args
57
  * @return stdClass
58
  */
59
- public static function get_term_query_from_array($args){
60
- if (is_array($args) && !empty($args)){
61
- //okay its an array with content
62
- if (is_int($args[0])){
63
- return self::get_term_query_from_array_of_ids($args);
64
- } else if (is_string($args[0])){
65
- return self::get_term_query_from_array_of_strings($args);
66
- }
67
- }
 
68
  }
69
 
70
  /**
71
  * @param array $args
72
  * @return stdClass
73
  */
74
- public static function get_term_query_from_array_of_ids($args){
75
- $ret = new stdClass();
76
- $ret->taxonomies = get_taxonomies();
77
- $ret->args['include'] = $args;
78
- return $ret;
79
  }
80
 
81
  /**
82
  * @param array $args
83
  * @return stdClass
84
  */
85
- public static function get_term_query_from_array_of_strings($args){
86
- $ret = new stdClass();
87
- $ret->taxonomies = self::correct_taxonomy_names($args);
88
- $ret->args = array();
89
- return $ret;
90
  }
91
 
92
  /**
93
  * @param string|array $taxs
94
  * @return array
95
  */
96
- private static function correct_taxonomy_names($taxs){
97
- if (is_string($taxs)){
98
  $taxs = array($taxs);
99
  }
100
- foreach($taxs as &$tax){
101
- if ($tax == 'tags' || $tax == 'tag'){
102
  $tax = 'post_tag';
103
- } else if ($tax == 'categories'){
104
  $tax = 'category';
105
  }
106
  }
1
  <?php
2
 
3
+ class TimberTermGetter
4
+ {
5
 
6
  /**
7
  * @param string $query_string
8
  * @return stdClass
9
  */
10
+ public static function get_term_query_from_query_string($query_string) {
11
  $args = array();
12
  parse_str($query_string, $args);
13
  $ret = self::get_term_query_from_assoc_array($args);
18
  * @param string $taxs
19
  * @return stdClass
20
  */
21
+ public static function get_term_query_from_string($taxs) {
22
  $ret = new stdClass();
23
  $ret->args = array();
24
+ if (is_string($taxs)) {
25
  $taxs = array($taxs);
26
  }
27
  $ret->taxonomies = self::correct_taxonomy_names($taxs);
32
  * @param array $args
33
  * @return stdClass
34
  */
35
+ public static function get_term_query_from_assoc_array($args) {
36
  $ret = new stdClass();
37
  $ret->args = $args;
38
+ if (isset($ret->args['tax'])) {
39
  $ret->taxonomies = $ret->args['tax'];
40
+ } else if (isset($ret->args['taxonomies'])) {
41
  $ret->taxonomies = $ret->args['taxonomies'];
42
+ } else if (isset($ret->args['taxs'])) {
43
  $ret->taxonomies = $ret->args['taxs'];
44
+ } else if (isset($ret->args['taxonomy'])) {
45
  $ret->taxonomies = $ret->args['taxonomy'];
46
  }
47
+ if (isset($ret->taxonomies)) {
48
+ if (is_string($ret->taxonomies)) {
49
  $ret->taxonomies = array($ret->taxonomies);
50
  }
51
  $ret->taxonomies = self::correct_taxonomy_names($ret->taxonomies);
57
  * @param array $args
58
  * @return stdClass
59
  */
60
+ public static function get_term_query_from_array($args) {
61
+ if (is_array($args) && !empty($args)) {
62
+ //okay its an array with content
63
+ if (is_int($args[0])) {
64
+ return self::get_term_query_from_array_of_ids($args);
65
+ } else if (is_string($args[0])) {
66
+ return self::get_term_query_from_array_of_strings($args);
67
+ }
68
+ }
69
+ return null;
70
  }
71
 
72
  /**
73
  * @param array $args
74
  * @return stdClass
75
  */
76
+ public static function get_term_query_from_array_of_ids($args) {
77
+ $ret = new stdClass();
78
+ $ret->taxonomies = get_taxonomies();
79
+ $ret->args['include'] = $args;
80
+ return $ret;
81
  }
82
 
83
  /**
84
  * @param array $args
85
  * @return stdClass
86
  */
87
+ public static function get_term_query_from_array_of_strings($args) {
88
+ $ret = new stdClass();
89
+ $ret->taxonomies = self::correct_taxonomy_names($args);
90
+ $ret->args = array();
91
+ return $ret;
92
  }
93
 
94
  /**
95
  * @param string|array $taxs
96
  * @return array
97
  */
98
+ private static function correct_taxonomy_names($taxs) {
99
+ if (is_string($taxs)) {
100
  $taxs = array($taxs);
101
  }
102
+ foreach ($taxs as &$tax) {
103
+ if ($tax == 'tags' || $tax == 'tag') {
104
  $tax = 'post_tag';
105
+ } else if ($tax == 'categories') {
106
  $tax = 'category';
107
  }
108
  }
functions/timber-term.php CHANGED
@@ -1,168 +1,172 @@
1
  <?php
2
 
3
- class TimberTerm extends TimberCore {
 
4
 
5
- var $taxonomy;
6
- var $_children;
7
- var $PostClass = 'TimberPost';
8
- var $TermClass = 'TimberTerm';
9
- var $object_type = 'term';
10
 
11
- public static $representation = 'term';
 
 
12
 
13
  /**
14
  * @param int $tid
15
  * @param string $tax
16
  */
17
- function __construct($tid = null, $tax='') {
18
- if ($tid === null) {
19
- $tid = $this->get_term_from_query();
20
- }
21
- if(strlen($tax))
22
- $this->taxonomy = $tax;
23
- $this->init($tid);
24
- }
 
25
 
26
  /**
27
  * @return string
28
  */
29
- function __toString(){
30
- return $this->name;
31
- }
32
 
33
- /* Setup
34
- ===================== */
35
 
36
  /**
37
  * @return mixed
38
  */
39
  private function get_term_from_query() {
40
- global $wp_query;
41
- $qo = $wp_query->queried_object;
42
- return $qo->term_id;
43
- }
44
 
45
  /**
46
  * @param int $tid
47
  */
48
  private function init($tid) {
49
- global $wpdb;
50
- $term = $this->get_term($tid);
51
- if (isset($term->id)) {
52
- $term->ID = $term->id;
53
- } else if (isset($term->term_id)) {
54
- $term->ID = $term->term_id;
55
- } else if (is_string($tid)) {
56
- //echo 'bad call using '.$tid;
57
- //TimberHelper::error_log(debug_backtrace());
58
- }
59
- $this->import($term);
60
- if (isset($term->term_id)){
61
- $custom = $this->get_term_meta($term->term_id);
62
- $this->import($custom);
63
- } else {
64
- //print_r($term);
65
- }
66
- }
67
 
68
  /**
69
  * @param int $tid
70
  * @return array
71
  */
72
- private function get_term_meta($tid){
73
- $customs = array();
74
- $customs = apply_filters('timber_term_get_meta', $customs, $tid, $this);
75
- return $customs;
76
- }
77
 
78
  /**
79
  * @param int $tid
80
- * @return int|null
81
  */
82
  private function get_term($tid) {
83
- if (is_object($tid) || is_array($tid)) {
84
- return $tid;
85
- }
86
- $tid = self::get_tid($tid);
87
-
88
- if(isset($this->taxonomy) && strlen($this->taxonomy)) {
89
- return get_term($tid, $this->taxonomy);
90
- } else {
91
- global $wpdb;
92
- $query = $wpdb->prepare("SELECT taxonomy FROM $wpdb->term_taxonomy WHERE term_id = %d LIMIT 1", $tid);
93
- $tax = $wpdb->get_var($query);
94
- if (isset($tax) && strlen($tax)) {
95
- $term = get_term($tid, $tax);
96
- return $term;
97
- }
98
- }
99
- return null;
100
- }
101
 
102
  /**
103
  * @param int $tid
104
  * @return int
105
  */
106
  private function get_tid($tid) {
107
- global $wpdb;
108
- if (is_numeric($tid)) {
109
- return $tid;
110
- }
111
- if (gettype($tid) == 'object') {
112
- $tid = $tid->term_id;
113
- }
114
- if (is_numeric($tid)) {
115
- $query = $wpdb->prepare("SELECT * FROM $wpdb->terms WHERE term_id = %d", $tid);
116
- } else {
117
- $query = $wpdb->prepare("SELECT * FROM $wpdb->terms WHERE slug = %s", $tid);
118
- }
119
- $result = $wpdb->get_row($query);
120
- if (isset($result->term_id)) {
121
- $result->ID = $result->term_id;
122
- return $result->ID;
123
- }
124
- return 0;
125
- }
126
-
127
- /* Public methods
128
- ===================== */
 
129
 
130
  /**
131
  * @return string
132
  */
133
- public function get_edit_url(){
134
- return get_edit_term_link($this->ID, $this->taxonomy);
135
- }
136
 
137
  /**
138
  * @param string $field_name
139
  * @return string
140
  */
141
- public function get_meta_field($field_name){
142
- if (!isset($this->$field_name)){
143
- $field = '';
144
- $field = apply_filters('timber_term_get_meta_field', $field, $this->ID, $field_name, $this);
145
- $this->$field_name = $field;
146
- }
147
- return $this->$field_name;
148
- }
149
 
150
  /**
151
  * @return string
152
  */
153
  public function get_path() {
154
- $link = $this->get_link();
155
- $rel = TimberURLHelper::get_rel_url($link, true);
156
- return apply_filters('timber_term_path', $rel, $this);
157
- }
158
 
159
  /**
160
  * @return string
161
  */
162
  public function get_link() {
163
- $link = get_term_link($this);
164
- return apply_filters('timber_term_link', $link, $this);
165
- }
166
 
167
  /**
168
  * @param int $numberposts
@@ -171,107 +175,107 @@ class TimberTerm extends TimberCore {
171
  * @return array|bool|null
172
  */
173
  public function get_posts($numberposts = 10, $post_type = 'any', $PostClass = '') {
174
- if (!strlen($PostClass)) {
175
- $PostClass = $this->PostClass;
176
- }
177
- $default_tax_query = array(array(
178
- 'field' => 'id',
179
- 'terms' => $this->ID,
180
- 'taxonomy' => $this->taxonomy,
181
- ));
182
- if (is_string($numberposts) && strstr($numberposts, '=')){
183
- $args = $numberposts;
184
- $new_args = array();
185
- parse_str($args, $new_args);
186
- $args = $new_args;
187
- $args['tax_query'] = $default_tax_query;
188
- if (!isset($args['post_type'])){
189
- $args['post_type'] = 'any';
190
- }
191
- if (class_exists($post_type)){
192
- $PostClass = $post_type;
193
- }
194
- } else if (is_array($numberposts)) {
195
- //they sent us an array already baked
196
- $args = $numberposts;
197
- if (!isset($args['tax_query'])){
198
- $args['tax_query'] = $default_tax_query;
199
- }
200
- if (class_exists($post_type)){
201
- $PostClass = $post_type;
202
- }
203
- if (!isset($args['post_type'])){
204
- $args['post_type'] = 'any';
205
- }
206
- } else {
207
- $args = array(
208
- 'numberposts' => $numberposts,
209
- 'tax_query' => $default_tax_query,
210
- 'post_type' => $post_type
211
- );
212
- }
213
- return Timber::get_posts($args, $PostClass);
214
- }
215
 
216
  /**
217
  * @return array
218
  */
219
- public function get_children(){
220
- if (!isset($this->_children)){
221
- $children = get_term_children($this->ID, $this->taxonomy);
222
- foreach($children as &$child){
223
- $child = new TimberTerm($child);
224
- }
225
- $this->_children = $children;
226
- }
227
- return $this->_children;
228
- }
229
-
230
- /* Alias
231
- ====================== */
232
 
233
  /**
234
  * @return array
235
  */
236
- public function children(){
237
- return $this->get_children();
238
- }
239
 
240
  /**
241
  * @return string
242
  */
243
- public function edit_link(){
244
- return $this->get_edit_url();
245
- }
246
 
247
  /**
248
  * @return string
249
  */
250
  public function get_url() {
251
- return $this->get_link();
252
- }
253
 
254
  /**
255
  * @return string
256
  */
257
- public function link(){
258
- return $this->get_link();
259
- }
260
 
261
  /**
262
  * @param string $field_name
263
  * @return mixed
264
  */
265
- public function meta($field_name){
266
- return $this->get_meta_field($field_name);
267
- }
268
 
269
  /**
270
  * @return string
271
  */
272
- public function path(){
273
- return $this->get_path();
274
- }
275
 
276
  /**
277
  * @param int $numberposts_or_args
@@ -279,26 +283,26 @@ class TimberTerm extends TimberCore {
279
  * @param string $post_class
280
  * @return array|bool|null
281
  */
282
- public function posts($numberposts_or_args = 10, $post_type_or_class = 'any', $post_class = ''){
283
- return $this->get_posts($numberposts_or_args, $post_type_or_class, $post_class);
284
- }
285
 
286
  /**
287
  * @return string
288
  */
289
- public function title(){
290
- return $this->name;
291
- }
292
 
293
  /**
294
  * @return string
295
  */
296
- public function url(){
297
- return $this->get_url();
298
- }
299
 
300
- /* Deprecated
301
- ===================== */
302
 
303
  /**
304
  * @deprecated
@@ -306,7 +310,7 @@ class TimberTerm extends TimberCore {
306
  * @return string
307
  */
308
  function get_page($i) {
309
- return $this->get_path() . '/page/' . $i;
310
- }
311
 
312
  }
1
  <?php
2
 
3
+ class TimberTerm extends TimberCore
4
+ {
5
 
6
+ public $taxonomy;
7
+ public $_children;
8
+ public $PostClass = 'TimberPost';
9
+ public $TermClass = 'TimberTerm';
10
+ public $object_type = 'term';
11
 
12
+ public static $representation = 'term';
13
+
14
+ public $name;
15
 
16
  /**
17
  * @param int $tid
18
  * @param string $tax
19
  */
20
+ function __construct($tid = null, $tax = '') {
21
+ if ($tid === null) {
22
+ $tid = $this->get_term_from_query();
23
+ }
24
+ if (strlen($tax)) {
25
+ $this->taxonomy = $tax;
26
+ }
27
+ $this->init($tid);
28
+ }
29
 
30
  /**
31
  * @return string
32
  */
33
+ function __toString() {
34
+ return $this->name;
35
+ }
36
 
37
+ /* Setup
38
+ ===================== */
39
 
40
  /**
41
  * @return mixed
42
  */
43
  private function get_term_from_query() {
44
+ global $wp_query;
45
+ $qo = $wp_query->queried_object;
46
+ return $qo->term_id;
47
+ }
48
 
49
  /**
50
  * @param int $tid
51
  */
52
  private function init($tid) {
53
+ $term = $this->get_term($tid);
54
+ if (isset($term->id)) {
55
+ $term->ID = $term->id;
56
+ } else if (isset($term->term_id)) {
57
+ $term->ID = $term->term_id;
58
+ } else if (is_string($tid)) {
59
+ //echo 'bad call using '.$tid;
60
+ //TimberHelper::error_log(debug_backtrace());
61
+ }
62
+ $term->id = $term->ID;
63
+ $this->import($term);
64
+ if (isset($term->term_id)) {
65
+ $custom = $this->get_term_meta($term->term_id);
66
+ $this->import($custom);
67
+ } else {
68
+ //print_r($term);
69
+ }
70
+ }
71
 
72
  /**
73
  * @param int $tid
74
  * @return array
75
  */
76
+ private function get_term_meta($tid) {
77
+ $customs = array();
78
+ $customs = apply_filters('timber_term_get_meta', $customs, $tid, $this);
79
+ return $customs;
80
+ }
81
 
82
  /**
83
  * @param int $tid
84
+ * @return mixed
85
  */
86
  private function get_term($tid) {
87
+ if (is_object($tid) || is_array($tid)) {
88
+ return $tid;
89
+ }
90
+ $tid = self::get_tid($tid);
91
+
92
+ if (isset($this->taxonomy) && strlen($this->taxonomy)) {
93
+ return get_term($tid, $this->taxonomy);
94
+ } else {
95
+ global $wpdb;
96
+ $query = $wpdb->prepare("SELECT taxonomy FROM $wpdb->term_taxonomy WHERE term_id = %d LIMIT 1", $tid);
97
+ $tax = $wpdb->get_var($query);
98
+ if (isset($tax) && strlen($tax)) {
99
+ return get_term($tid, $tax);
100
+ }
101
+ }
102
+ return null;
103
+ }
 
104
 
105
  /**
106
  * @param int $tid
107
  * @return int
108
  */
109
  private function get_tid($tid) {
110
+ global $wpdb;
111
+ if (is_numeric($tid)) {
112
+ return $tid;
113
+ }
114
+ if (gettype($tid) == 'object') {
115
+ $tid = $tid->term_id;
116
+ }
117
+ if (is_numeric($tid)) {
118
+ $query = $wpdb->prepare("SELECT * FROM $wpdb->terms WHERE term_id = %d", $tid);
119
+ } else {
120
+ $query = $wpdb->prepare("SELECT * FROM $wpdb->terms WHERE slug = %s", $tid);
121
+ }
122
+ $result = $wpdb->get_row($query);
123
+ if (isset($result->term_id)) {
124
+ $result->ID = $result->term_id;
125
+ $result->id = $result->term_id;
126
+ return $result->ID;
127
+ }
128
+ return 0;
129
+ }
130
+
131
+ /* Public methods
132
+ ===================== */
133
 
134
  /**
135
  * @return string
136
  */
137
+ public function get_edit_url() {
138
+ return get_edit_term_link($this->ID, $this->taxonomy);
139
+ }
140
 
141
  /**
142
  * @param string $field_name
143
  * @return string
144
  */
145
+ public function get_meta_field($field_name) {
146
+ if (!isset($this->$field_name)) {
147
+ $field = '';
148
+ $field = apply_filters('timber_term_get_meta_field', $field, $this->ID, $field_name, $this);
149
+ $this->$field_name = $field;
150
+ }
151
+ return $this->$field_name;
152
+ }
153
 
154
  /**
155
  * @return string
156
  */
157
  public function get_path() {
158
+ $link = $this->get_link();
159
+ $rel = TimberURLHelper::get_rel_url($link, true);
160
+ return apply_filters('timber_term_path', $rel, $this);
161
+ }
162
 
163
  /**
164
  * @return string
165
  */
166
  public function get_link() {
167
+ $link = get_term_link($this);
168
+ return apply_filters('timber_term_link', $link, $this);
169
+ }
170
 
171
  /**
172
  * @param int $numberposts
175
  * @return array|bool|null
176
  */
177
  public function get_posts($numberposts = 10, $post_type = 'any', $PostClass = '') {
178
+ if (!strlen($PostClass)) {
179
+ $PostClass = $this->PostClass;
180
+ }
181
+ $default_tax_query = array(array(
182
+ 'field' => 'id',
183
+ 'terms' => $this->ID,
184
+ 'taxonomy' => $this->taxonomy,
185
+ ));
186
+ if (is_string($numberposts) && strstr($numberposts, '=')) {
187
+ $args = $numberposts;
188
+ $new_args = array();
189
+ parse_str($args, $new_args);
190
+ $args = $new_args;
191
+ $args['tax_query'] = $default_tax_query;
192
+ if (!isset($args['post_type'])) {
193
+ $args['post_type'] = 'any';
194
+ }
195
+ if (class_exists($post_type)) {
196
+ $PostClass = $post_type;
197
+ }
198
+ } else if (is_array($numberposts)) {
199
+ //they sent us an array already baked
200
+ $args = $numberposts;
201
+ if (!isset($args['tax_query'])) {
202
+ $args['tax_query'] = $default_tax_query;
203
+ }
204
+ if (class_exists($post_type)) {
205
+ $PostClass = $post_type;
206
+ }
207
+ if (!isset($args['post_type'])) {
208
+ $args['post_type'] = 'any';
209
+ }
210
+ } else {
211
+ $args = array(
212
+ 'numberposts' => $numberposts,
213
+ 'tax_query' => $default_tax_query,
214
+ 'post_type' => $post_type
215
+ );
216
+ }
217
+ return Timber::get_posts($args, $PostClass);
218
+ }
219
 
220
  /**
221
  * @return array
222
  */
223
+ public function get_children() {
224
+ if (!isset($this->_children)) {
225
+ $children = get_term_children($this->ID, $this->taxonomy);
226
+ foreach ($children as &$child) {
227
+ $child = new TimberTerm($child);
228
+ }
229
+ $this->_children = $children;
230
+ }
231
+ return $this->_children;
232
+ }
233
+
234
+ /* Alias
235
+ ====================== */
236
 
237
  /**
238
  * @return array
239
  */
240
+ public function children() {
241
+ return $this->get_children();
242
+ }
243
 
244
  /**
245
  * @return string
246
  */
247
+ public function edit_link() {
248
+ return $this->get_edit_url();
249
+ }
250
 
251
  /**
252
  * @return string
253
  */
254
  public function get_url() {
255
+ return $this->get_link();
256
+ }
257
 
258
  /**
259
  * @return string
260
  */
261
+ public function link() {
262
+ return $this->get_link();
263
+ }
264
 
265
  /**
266
  * @param string $field_name
267
  * @return mixed
268
  */
269
+ public function meta($field_name) {
270
+ return $this->get_meta_field($field_name);
271
+ }
272
 
273
  /**
274
  * @return string
275
  */
276
+ public function path() {
277
+ return $this->get_path();
278
+ }
279
 
280
  /**
281
  * @param int $numberposts_or_args
283
  * @param string $post_class
284
  * @return array|bool|null
285
  */
286
+ public function posts($numberposts_or_args = 10, $post_type_or_class = 'any', $post_class = '') {
287
+ return $this->get_posts($numberposts_or_args, $post_type_or_class, $post_class);
288
+ }
289
 
290
  /**
291
  * @return string
292
  */
293
+ public function title() {
294
+ return $this->name;
295
+ }
296
 
297
  /**
298
  * @return string
299
  */
300
+ public function url() {
301
+ return $this->get_url();
302
+ }
303
 
304
+ /* Deprecated
305
+ ===================== */
306
 
307
  /**
308
  * @deprecated
310
  * @return string
311
  */
312
  function get_page($i) {
313
+ return $this->get_path() . '/page/' . $i;
314
+ }
315
 
316
  }
functions/timber-theme.php CHANGED
@@ -1,49 +1,58 @@
1
  <?php
2
 
3
- class TimberTheme extends TimberCore {
 
4
 
5
- /**
6
- * @param string $slug
7
- */
8
- function __construct($slug = null){
9
- $this->init($slug);
10
- }
 
11
 
12
- /**
13
- * @param string $slug
14
- */
15
- function init($slug = null){
16
- $data = wp_get_theme($slug);
17
- $this->name = $data->get('Name');
18
- $ss = $data->get_stylesheet();
19
- $this->slug = $ss;
20
- $this->path = '/'.str_replace(ABSPATH, '', get_stylesheet_directory());
21
- $this->uri = get_stylesheet_directory_uri();
22
- $this->link = $this->uri;
23
- $this->parent_slug = $data->get('Template');
24
- if (!$this->parent_slug){
25
- $this->path = '/'.str_replace(ABSPATH, '', get_template_directory());
26
- $this->uri = get_template_directory_uri();
27
- }
28
- if ($this->parent_slug && $this->parent_slug != $this->slug){
29
- $this->parent = new TimberTheme($this->parent_slug);
30
- }
31
- }
32
 
33
- /**
34
- * @param string $name
35
- * @param bool $default
36
- * @return string
37
- */
38
- public function theme_mod($name, $default = false){
39
- return get_theme_mod($name, $default);
40
- }
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
- /**
43
- * @return string
44
- */
45
- public function theme_mods(){
46
- return get_theme_mods();
47
- }
 
 
48
 
49
- }
 
 
 
 
 
 
 
1
  <?php
2
 
3
+ class TimberTheme extends TimberCore
4
+ {
5
 
6
+ public $name;
7
+ public $slug;
8
+ public $path;
9
+ public $uri;
10
+ public $link;
11
+ public $parent_slug;
12
+ public $parent;
13
 
14
+ /**
15
+ * @param string $slug
16
+ */
17
+ function __construct($slug = null) {
18
+ $this->init($slug);
19
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
 
21
+ /**
22
+ * @param string $slug
23
+ */
24
+ function init($slug = null) {
25
+ $data = wp_get_theme($slug);
26
+ $this->name = $data->get('Name');
27
+ $ss = $data->get_stylesheet();
28
+ $this->slug = $ss;
29
+ $this->path = WP_CONTENT_SUBDIR . str_replace(WP_CONTENT_DIR, '', get_stylesheet_directory());
30
+ $this->uri = get_stylesheet_directory_uri();
31
+ $this->link = $this->uri;
32
+ $this->parent_slug = $data->get('Template');
33
+ if (!$this->parent_slug) {
34
+ $this->path = WP_CONTENT_SUBDIR . str_replace(WP_CONTENT_DIR, '', get_template_directory());
35
+ $this->uri = get_template_directory_uri();
36
+ }
37
+ if ($this->parent_slug && $this->parent_slug != $this->slug) {
38
+ $this->parent = new TimberTheme($this->parent_slug);
39
+ }
40
+ }
41
 
42
+ /**
43
+ * @param string $name
44
+ * @param bool $default
45
+ * @return string
46
+ */
47
+ public function theme_mod($name, $default = false) {
48
+ return get_theme_mod($name, $default);
49
+ }
50
 
51
+ /**
52
+ * @return string
53
+ */
54
+ public function theme_mods() {
55
+ return get_theme_mods();
56
+ }
57
+
58
+ }
functions/timber-url-helper.php CHANGED
@@ -1,210 +1,211 @@
1
  <?php
2
 
3
- class TimberURLHelper {
4
-
5
- /**
6
- * @return string
7
- */
8
- public static function get_current_url() {
9
- $pageURL = "http://";
10
- if (isset($_SERVER['HTTPS']) && $_SERVER["HTTPS"] == "on"){
11
- $pageURL = "https://";;
12
- }
13
- if ($_SERVER["SERVER_PORT"] != "80") {
14
- $pageURL .= $_SERVER["SERVER_NAME"] . ":" . $_SERVER["SERVER_PORT"] . $_SERVER["REQUEST_URI"];
15
- } else {
16
- $pageURL .= $_SERVER["SERVER_NAME"] . $_SERVER["REQUEST_URI"];
17
- }
18
- return $pageURL;
19
- }
20
-
21
- /**
22
- * @param string $url
23
- * @return bool
24
- */
25
- public static function is_url($url) {
26
- if (!is_string($url)){
27
- return false;
28
- }
29
- $url = strtolower($url);
30
- if (strstr('://', $url)) {
31
- return true;
32
- }
33
- return false;
34
- }
35
-
36
- /**
37
- * @return string
38
- */
39
- public static function get_path_base() {
40
- $struc = get_option('permalink_structure');
41
- $struc = explode('/', $struc);
42
- $p = '/';
43
- foreach ($struc as $s) {
44
- if (!strstr($s, '%') && strlen($s)) {
45
- $p .= $s . '/';
46
- }
47
- }
48
- return $p;
49
- }
50
-
51
- /**
52
- * @param string $url
53
- * @param bool $force
54
- * @return string
55
- */
56
- public static function get_rel_url($url, $force = false){
57
- if (!strstr($url, $_SERVER['HTTP_HOST']) && !$force){
58
- return $url;
59
- }
60
- $url_info = parse_url($url);
61
- $link = $url_info['path'];
62
- if (isset($url_info['query']) && strlen($url_info['query'])){
63
- $link .= '?'.$url_info['query'];
64
- }
65
- $link = TimberURLHelper::remove_double_slashes($link);
66
- return $link;
67
- }
68
-
69
- /**
70
- * @param string $url
71
- * @return bool
72
- */
73
- public static function is_local($url){
74
- if (strstr($url, $_SERVER['HTTP_HOST'])){
75
- return true;
76
- }
77
- return false;
78
- }
79
-
80
- /**
81
- * @param string $src
82
- * @return string
83
- */
84
- public static function get_full_path($src) {
85
- $root = ABSPATH;
86
- $old_root_path = $root . $src;
87
- $old_root_path = str_replace('//', '/', $old_root_path);
88
- return $old_root_path;
89
- }
90
-
91
- public static function url_to_file_system($url){
92
- $url_parts = parse_url($url);
93
- $path = ABSPATH . $url_parts['path'];
94
- $path = str_replace('//', '/', $path);
95
- return $path;
96
- }
97
-
98
- /**
99
- * @param string $src
100
- * @return string
101
- */
102
- public static function get_rel_path($src) {
103
- return str_replace(ABSPATH, '', $src);
104
- }
105
-
106
- /**
107
- * @param string $url
108
- * @return string
109
- */
110
- public static function remove_double_slashes($url){
111
- $url = str_replace('//', '/', $url);
112
- if (strstr($url, 'http:') && !strstr($url, 'http://')){
113
- $url = str_replace('http:/', 'http://', $url);
114
- }
115
- return $url;
116
- }
117
-
118
- /**
119
- * @param string $url
120
- * @param string $path
121
- * @return string
122
- */
123
- public static function prepend_to_url($url, $path){
124
- if (strstr(strtolower($url), 'http')){
125
- $url_parts = parse_url($url);
126
- $url = $url_parts['scheme'].'://'.$url_parts['host'].$path.$url_parts['path'];
127
- } else {
128
- $url = $url.$path;
129
- }
130
- return self::remove_double_slashes($url);
131
- }
132
-
133
- /**
134
- * @param string $path
135
- * @return string
136
- */
137
- public static function preslashit($path){
138
- if (strpos($path, '/') != 0) {
139
- $path = '/' . $path;
140
- }
141
- return $path;
142
- }
143
-
144
- /**
145
- * @param string $url
146
- * @return bool
147
- */
148
- public static function is_external($url){
149
- $has_http = strstr(strtolower($url), 'http');
150
- $on_domain = strstr($url, $_SERVER['HTTP_HOST']);
151
- if ($has_http && !$on_domain){
152
- return true;
153
- }
154
- return false;
155
- }
156
-
157
- /**
158
- * @param string $url
159
- * @param int $timeout
160
- * @return string|WP_Error
161
- */
162
- public static function download_url($url, $timeout = 300) {
163
- if (!$url) {
164
- return new WP_Error('http_no_url', __('Invalid URL Provided.'));
165
- }
166
-
167
- $tmpfname = wp_tempnam($url);
168
- if (!$tmpfname) {
169
- return new WP_Error('http_no_file', __('Could not create Temporary file.'));
170
- }
171
-
172
- $response = wp_remote_get($url, array('timeout' => $timeout, 'stream' => true, 'filename' => $tmpfname));
173
-
174
- if (is_wp_error($response)) {
175
- unlink($tmpfname);
176
- return $response;
177
- }
178
- if (200 != wp_remote_retrieve_response_code($response)) {
179
- unlink($tmpfname);
180
- return new WP_Error('http_404', trim(wp_remote_retrieve_response_message($response)));
181
- }
182
- return $tmpfname;
183
- }
184
-
185
- public static function osort(&$array, $prop) {
186
- usort($array, function ($a, $b) use ($prop) {
187
- return $a->$prop > $b->$prop ? 1 : -1;
188
- });
189
- }
190
-
191
- /**
192
- * @param int $i
193
- * @return array
194
- */
195
- public static function get_params($i = -1) {
196
- $args = explode('/', trim(strtolower($_SERVER['REQUEST_URI'])));
197
- $newargs = array();
198
- foreach ($args as $arg) {
199
- if (strlen($arg)) {
200
- $newargs[] = $arg;
201
- }
202
- }
203
- if ($i > -1) {
204
- if (isset($newargs[$i])) {
205
- return $newargs[$i];
206
- }
207
- }
208
- return $newargs;
209
- }
210
- }
 
1
  <?php
2
 
3
+ class TimberURLHelper
4
+ {
5
+
6
+ /**
7
+ * @return string
8
+ */
9
+ public static function get_current_url() {
10
+ $pageURL = "http://";
11
+ if (isset($_SERVER['HTTPS']) && $_SERVER["HTTPS"] == "on") {
12
+ $pageURL = "https://";;
13
+ }
14
+ if ($_SERVER["SERVER_PORT"] != "80") {
15
+ $pageURL .= $_SERVER["SERVER_NAME"] . ":" . $_SERVER["SERVER_PORT"] . $_SERVER["REQUEST_URI"];
16
+ } else {
17
+ $pageURL .= $_SERVER["SERVER_NAME"] . $_SERVER["REQUEST_URI"];
18
+ }
19
+ return $pageURL;
20
+ }
21
+
22
+ /**
23
+ * @param string $url
24
+ * @return bool
25
+ */
26
+ public static function is_url($url) {
27
+ if (!is_string($url)) {
28
+ return false;
29
+ }
30
+ $url = strtolower($url);
31
+ if (strstr($url, '://')) {
32
+ return true;
33
+ }
34
+ return false;
35
+ }
36
+
37
+ /**
38
+ * @return string
39
+ */
40
+ public static function get_path_base() {
41
+ $struc = get_option('permalink_structure');
42
+ $struc = explode('/', $struc);
43
+ $p = '/';
44
+ foreach ($struc as $s) {
45
+ if (!strstr($s, '%') && strlen($s)) {
46
+ $p .= $s . '/';
47
+ }
48
+ }
49
+ return $p;
50
+ }
51
+
52
+ /**
53
+ * @param string $url
54
+ * @param bool $force
55
+ * @return string
56
+ */
57
+ public static function get_rel_url($url, $force = false) {
58
+ if (!strstr($url, $_SERVER['HTTP_HOST']) && !$force) {
59
+ return $url;
60
+ }
61
+ $url_info = parse_url($url);
62
+ $link = $url_info['path'];
63
+ if (isset($url_info['query']) && strlen($url_info['query'])) {
64
+ $link .= '?' . $url_info['query'];
65
+ }
66
+ $link = TimberURLHelper::remove_double_slashes($link);
67
+ return $link;
68
+ }
69
+
70
+ /**
71
+ * @param string $url
72
+ * @return bool
73
+ */
74
+ public static function is_local($url) {
75
+ if (strstr($url, $_SERVER['HTTP_HOST'])) {
76
+ return true;
77
+ }
78
+ return false;
79
+ }
80
+
81
+ /**
82
+ * @param string $src
83
+ * @return string
84
+ */
85
+ public static function get_full_path($src) {
86
+ $root = ABSPATH;
87
+ $old_root_path = $root . $src;
88
+ $old_root_path = str_replace('//', '/', $old_root_path);
89
+ return $old_root_path;
90
+ }
91
+
92
+ public static function url_to_file_system($url) {
93
+ $url_parts = parse_url($url);
94
+ $path = ABSPATH . $url_parts['path'];
95
+ $path = str_replace('//', '/', $path);
96
+ return $path;
97
+ }
98
+
99
+ /**
100
+ * @param string $src
101
+ * @return string
102
+ */
103
+ public static function get_rel_path($src) {
104
+ if (strstr($src, ABSPATH)) {
105
+ return str_replace(ABSPATH, '', $src);
106
+ }
107
+ //its outside the wordpress directory, alternate setups:
108
+ $src = str_replace(WP_CONTENT_DIR, '', $src);
109
+ return WP_CONTENT_SUBDIR . $src;
110
+ }
111
+
112
+ /**
113
+ * @param string $url
114
+ * @return string
115
+ */
116
+ public static function remove_double_slashes($url) {
117
+ $url = str_replace('//', '/', $url);
118
+ if (strstr($url, 'http:') && !strstr($url, 'http://')) {
119
+ $url = str_replace('http:/', 'http://', $url);
120
+ }
121
+ return $url;
122
+ }
123
+
124
+ /**
125
+ * @param string $url
126
+ * @param string $path
127
+ * @return string
128
+ */
129
+ public static function prepend_to_url($url, $path) {
130
+ if (strstr(strtolower($url), 'http')) {
131
+ $url_parts = parse_url($url);
132
+ $url = $url_parts['scheme'] . '://' . $url_parts['host'] . $path . $url_parts['path'];
133
+ } else {
134
+ $url = $url . $path;
135
+ }
136
+ return self::remove_double_slashes($url);
137
+ }
138
+
139
+ /**
140
+ * @param string $path
141
+ * @return string
142
+ */
143
+ public static function preslashit($path) {
144
+ if (strpos($path, '/') != 0) {
145
+ $path = '/' . $path;
146
+ }
147
+ return $path;
148
+ }
149
+
150
+ /**
151
+ * @param string $url
152
+ * @return bool
153
+ */
154
+ public static function is_external($url) {
155
+ $has_http = strstr(strtolower($url), 'http');
156
+ $on_domain = strstr($url, $_SERVER['HTTP_HOST']);
157
+ if ($has_http && !$on_domain) {
158
+ return true;
159
+ }
160
+ return false;
161
+ }
162
+
163
+ /**
164
+ * @param string $url
165
+ * @param int $timeout
166
+ * @return string|WP_Error
167
+ */
168
+ public static function download_url($url, $timeout = 300) {
169
+ if (!$url) {
170
+ return new WP_Error('http_no_url', __('Invalid URL Provided.'));
171
+ }
172
+
173
+ $tmpfname = wp_tempnam($url);
174
+ if (!$tmpfname) {
175
+ return new WP_Error('http_no_file', __('Could not create Temporary file.'));
176
+ }
177
+
178
+ $response = wp_remote_get($url, array('timeout' => $timeout, 'stream' => true, 'filename' => $tmpfname));
179
+
180
+ if (is_wp_error($response)) {
181
+ unlink($tmpfname);
182
+ return $response;
183
+ }
184
+ if (200 != wp_remote_retrieve_response_code($response)) {
185
+ unlink($tmpfname);
186
+ return new WP_Error('http_404', trim(wp_remote_retrieve_response_message($response)));
187
+ }
188
+ return $tmpfname;
189
+ }
190
+
191
+ /**
192
+ * @param int $i
193
+ * @return array
194
+ */
195
+ public static function get_params($i = -1) {
196
+ $args = explode('/', trim(strtolower($_SERVER['REQUEST_URI'])));
197
+ $newargs = array();
198
+ foreach ($args as $arg) {
199
+ if (strlen($arg)) {
200
+ $newargs[] = $arg;
201
+ }
202
+ }
203
+ if ($i > -1) {
204
+ if (isset($newargs[$i])) {
205
+ return $newargs[$i];
206
+ }
207
+ }
208
+ return $newargs;
209
+ }
210
+
211
+ }
functions/timber-user.php CHANGED
@@ -1,12 +1,17 @@
1
  <?php
2
 
3
- class TimberUser extends TimberCore {
 
4
 
5
- var $_link;
6
- var $object_type = 'user';
7
 
8
  public static $representation = 'user';
9
 
 
 
 
 
10
  /**
11
  * @param int|bool $uid
12
  */
@@ -17,12 +22,12 @@ class TimberUser extends TimberCore {
17
  /**
18
  * @return string
19
  */
20
- function __toString(){
21
  $name = $this->name();
22
- if (strlen($name)){
23
  return $name;
24
  }
25
- if (strlen($this->name)){
26
  return $this->name;
27
  }
28
  return '';
@@ -32,10 +37,10 @@ class TimberUser extends TimberCore {
32
  * @param string $field_name
33
  * @return null
34
  */
35
- function get_meta($field_name){
36
  $value = null;
37
  $value = apply_filters('timber_user_get_meta_field_pre', $value, $this->ID, $field_name, $this);
38
- if ($value === null){
39
  $value = get_post_meta($this->ID, $field_name, true);
40
  }
41
  $value = apply_filters('timber_user_get_meta_field', $value, $this->ID, $field_name, $this);
@@ -46,8 +51,8 @@ class TimberUser extends TimberCore {
46
  * @param string $field
47
  * @param mixed $value
48
  */
49
- function __set($field, $value){
50
- if ($field == 'name'){
51
  $this->display_name = $value;
52
  }
53
  $this->$field = $value;
@@ -57,7 +62,7 @@ class TimberUser extends TimberCore {
57
  * @return string
58
  */
59
  public function get_link() {
60
- if (!$this->_link){
61
  $this->_link = get_author_posts_url($this->ID);
62
  }
63
  return $this->_link;
@@ -70,12 +75,13 @@ class TimberUser extends TimberCore {
70
  if ($uid === false) {
71
  $uid = get_current_user_id();
72
  }
73
- if ($uid){
74
  $data = get_userdata($uid);
75
  if (is_object($data) && isset($data)) {
76
  $this->import($data->data);
77
  }
78
  $this->ID = $uid;
 
79
  $this->import_custom();
80
  }
81
  }
@@ -84,10 +90,10 @@ class TimberUser extends TimberCore {
84
  * @param string $field_name
85
  * @return mixed
86
  */
87
- function get_meta_field($field_name){
88
  $value = null;
89
  $value = apply_filters('timber_user_get_meta_field_pre', $value, $this->ID, $field_name, $this);
90
- if ($value === null){
91
  $value = get_user_meta($this->ID, $field_name, true);
92
  }
93
  $value = apply_filters('timber_user_get_meta_field', $value, $this->ID, $field_name, $this);
@@ -101,12 +107,12 @@ class TimberUser extends TimberCore {
101
  if ($this->ID) {
102
  $um = array();
103
  $um = apply_filters('timber_user_get_meta_pre', $um, $this->ID, $this);
104
- if (empty($um)){
105
  $um = get_user_meta($this->ID);
106
  }
107
  $custom = array();
108
  foreach ($um as $key => $value) {
109
- if (is_array($value) && count($value) == 1){
110
  $value = $value[0];
111
  }
112
  $custom[$key] = maybe_unserialize($value);
@@ -132,7 +138,7 @@ class TimberUser extends TimberCore {
132
  /**
133
  * @return string
134
  */
135
- function get_permalink(){
136
  return $this->get_link();
137
  }
138
 
@@ -154,7 +160,7 @@ class TimberUser extends TimberCore {
154
  * @param string $field_name
155
  * @return mixed
156
  */
157
- function meta($field_name){
158
  return $this->get_meta_field($field_name);
159
  }
160
 
@@ -175,8 +181,8 @@ class TimberUser extends TimberCore {
175
  /**
176
  * @return string
177
  */
178
- function link(){
179
  return $this->get_link();
180
  }
181
 
182
- }
1
  <?php
2
 
3
+ class TimberUser extends TimberCore
4
+ {
5
 
6
+ public $_link;
7
+ public $object_type = 'user';
8
 
9
  public static $representation = 'user';
10
 
11
+ public $display_name;
12
+ public $name;
13
+ public $user_nicename;
14
+
15
  /**
16
  * @param int|bool $uid
17
  */
22
  /**
23
  * @return string
24
  */
25
+ function __toString() {
26
  $name = $this->name();
27
+ if (strlen($name)) {
28
  return $name;
29
  }
30
+ if (strlen($this->name)) {
31
  return $this->name;
32
  }
33
  return '';
37
  * @param string $field_name
38
  * @return null
39
  */
40
+ function get_meta($field_name) {
41
  $value = null;
42
  $value = apply_filters('timber_user_get_meta_field_pre', $value, $this->ID, $field_name, $this);
43
+ if ($value === null) {
44
  $value = get_post_meta($this->ID, $field_name, true);
45
  }
46
  $value = apply_filters('timber_user_get_meta_field', $value, $this->ID, $field_name, $this);
51
  * @param string $field
52
  * @param mixed $value
53
  */
54
+ function __set($field, $value) {
55
+ if ($field == 'name') {
56
  $this->display_name = $value;
57
  }
58
  $this->$field = $value;
62
  * @return string
63
  */
64
  public function get_link() {
65
+ if (!$this->_link) {
66
  $this->_link = get_author_posts_url($this->ID);
67
  }
68
  return $this->_link;
75
  if ($uid === false) {
76
  $uid = get_current_user_id();
77
  }
78
+ if ($uid) {
79
  $data = get_userdata($uid);
80
  if (is_object($data) && isset($data)) {
81
  $this->import($data->data);
82
  }
83
  $this->ID = $uid;
84
+ $this->id = $uid;
85
  $this->import_custom();
86
  }
87
  }
90
  * @param string $field_name
91
  * @return mixed
92
  */
93
+ function get_meta_field($field_name) {
94
  $value = null;
95
  $value = apply_filters('timber_user_get_meta_field_pre', $value, $this->ID, $field_name, $this);
96
+ if ($value === null) {
97
  $value = get_user_meta($this->ID, $field_name, true);
98
  }
99
  $value = apply_filters('timber_user_get_meta_field', $value, $this->ID, $field_name, $this);
107
  if ($this->ID) {
108
  $um = array();
109
  $um = apply_filters('timber_user_get_meta_pre', $um, $this->ID, $this);
110
+ if (empty($um)) {
111
  $um = get_user_meta($this->ID);
112
  }
113
  $custom = array();
114
  foreach ($um as $key => $value) {
115
+ if (is_array($value) && count($value) == 1) {
116
  $value = $value[0];
117
  }
118
  $custom[$key] = maybe_unserialize($value);
138
  /**
139
  * @return string
140
  */
141
+ function get_permalink() {
142
  return $this->get_link();
143
  }
144
 
160
  * @param string $field_name
161
  * @return mixed
162
  */
163
+ function meta($field_name) {
164
  return $this->get_meta_field($field_name);
165
  }
166
 
181
  /**
182
  * @return string
183
  */
184
+ function link() {
185
  return $this->get_link();
186
  }
187
 
188
+ }
readme.txt CHANGED
@@ -2,7 +2,7 @@
2
  Contributors: jarednova
3
  Tags: template engine, templates, twig
4
  Requires at least: 3.7
5
- Stable tag: 0.19.0
6
  Tested up to: 3.9
7
  PHP version: 5.3.0 or greater
8
  License: GPLv2 or later
@@ -41,6 +41,15 @@ Timber is great for any WordPress developer who cares about writing good, mainta
41
 
42
  == Changelog ==
43
 
 
 
 
 
 
 
 
 
 
44
  = 0.19.0 =
45
  * Reorganized dependencies into /vendor directories based on composer (thanks @mgmartel, @rarst, @bryanaka)
46
  * Fixed issues with image library deletion (thanks @thetmkay)
2
  Contributors: jarednova
3
  Tags: template engine, templates, twig
4
  Requires at least: 3.7
5
+ Stable tag: 0.19.1
6
  Tested up to: 3.9
7
  PHP version: 5.3.0 or greater
8
  License: GPLv2 or later
41
 
42
  == Changelog ==
43
 
44
+ = 0.19.1
45
+ * Removed .git folder hiding in php-router
46
+ * Added support for WooCommerce and other plugins in starter theme (thanks @jamesagreenleaf)
47
+ * Starter theme now based on OO-style TimberSite convention
48
+ * You can not get the modified_author (thanks @jamesagreenleaf)
49
+ * ...oh and the modified date (thanks @jamesagreenleaf)
50
+ * Code clean-up like mad (thanks @hsz)
51
+ * Fixed bug when calling Timber::get_posts in loop (thanks @jamesagreenleaf)
52
+
53
  = 0.19.0 =
54
  * Reorganized dependencies into /vendor directories based on composer (thanks @mgmartel, @rarst, @bryanaka)
55
  * Fixed issues with image library deletion (thanks @thetmkay)
timber-starter-theme/author.php CHANGED
@@ -12,9 +12,9 @@ global $wp_query;
12
 
13
  $data = Timber::get_context();
14
  $data['posts'] = Timber::get_posts();
15
-
16
- $author = new TimberUser($wp_query->query_vars['author']);
17
- $data['author'] = $author;
18
- $data['title'] = 'Author Archives: ' . $author->name();
19
-
20
  Timber::render(array('author.twig', 'archive.twig'), $data);
12
 
13
  $data = Timber::get_context();
14
  $data['posts'] = Timber::get_posts();
15
+ if (isset($query_vars['author'])){
16
+ $author = new TimberUser($wp_query->query_vars['author']);
17
+ $data['author'] = $author;
18
+ $data['title'] = 'Author Archives: ' . $author->name();
19
+ }
20
  Timber::render(array('author.twig', 'archive.twig'), $data);
timber-starter-theme/footer.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Third party plugins that hijack the theme will call wp_footer() to get the footer template.
4
+ * We use this so end our output buffer (started in header.php) and render into the view/page-plugin.twig template.
5
+ */
6
+ $timberContext = $GLOBALS['timberContext'];
7
+ if (!isset($timberContext)) {
8
+ throw new \Exception('Timber context not set in footer.');
9
+ }
10
+ $timberContext['content'] = ob_get_contents();
11
+ ob_end_clean();
12
+ $templates = array('page-plugin.twig');
13
+ Timber::render($templates, $timberContext);
timber-starter-theme/functions.php CHANGED
@@ -1,34 +1,52 @@
1
  <?php
 
 
 
 
 
2
 
3
- add_theme_support('post-formats');
4
- add_theme_support('post-thumbnails');
5
- add_theme_support('menus');
6
 
7
- add_filter('get_twig', 'add_to_twig');
8
- add_filter('timber_context', 'add_to_context');
 
 
 
 
 
 
 
 
9
 
10
- add_action('wp_enqueue_scripts', 'load_scripts');
 
 
11
 
12
- define('THEME_URL', get_template_directory_uri());
13
- function add_to_context($data){
14
- /* this is where you can add your own data to Timber's context object */
15
- $data['qux'] = 'I am a value set in your functions.php file';
16
- $data['menu'] = new TimberMenu();
17
- return $data;
18
- }
 
 
 
 
 
 
 
 
 
 
 
 
19
 
20
- function add_to_twig($twig){
21
- /* this is where you can add your own fuctions to twig */
22
- $twig->addExtension(new Twig_Extension_StringLoader());
23
- $twig->addFilter('myfoo', new Twig_Filter_Function('myfoo'));
24
- return $twig;
25
  }
26
 
 
 
27
  function myfoo($text){
28
  $text .= ' bar!';
29
  return $text;
30
- }
31
-
32
- function load_scripts(){
33
- wp_enqueue_script('jquery');
34
- }
1
  <?php
2
+
3
+ if (!class_exists('Timber')){
4
+ echo 'Timber not activated. Make sure you activate the plugin in <a href="/wp-admin/plugins.php#timber">/wp-admin/plugins.php</a>';
5
+ return;
6
+ }
7
 
8
+ class StarterSite extends TimberSite {
 
 
9
 
10
+ function __construct(){
11
+ add_theme_support('post-formats');
12
+ add_theme_support('post-thumbnails');
13
+ add_theme_support('menus');
14
+ add_filter('timber_context', array($this, 'add_to_context'));
15
+ add_filter('get_twig', array($this, 'add_to_twig'));
16
+ add_action('init', array($this, 'register_post_types'));
17
+ add_action('init', array($this, 'register_taxonomies'));
18
+ parent::__construct();
19
+ }
20
 
21
+ function register_post_types(){
22
+ //this is where you can register custom post types
23
+ }
24
 
25
+ function register_taxonomies(){
26
+ //this is where you can register custom taxonomies
27
+ }
28
+
29
+ function add_to_context($context){
30
+ $context['foo'] = 'bar';
31
+ $context['stuff'] = 'I am a value set in your functions.php file';
32
+ $context['notes'] = 'These values are available everytime you call Timber::get_context();';
33
+ $context['menu'] = new TimberMenu();
34
+ $context['site'] = $this;
35
+ return $context;
36
+ }
37
+
38
+ function add_to_twig($twig){
39
+ /* this is where you can add your own fuctions to twig */
40
+ $twig->addExtension(new Twig_Extension_StringLoader());
41
+ $twig->addFilter('myfoo', new Twig_Filter_Function('myfoo'));
42
+ return $twig;
43
+ }
44
 
 
 
 
 
 
45
  }
46
 
47
+ new StarterSite();
48
+
49
  function myfoo($text){
50
  $text .= ' bar!';
51
  return $text;
52
+ }
 
 
 
 
timber-starter-theme/header.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Third party plugins that hijack the theme will call wp_head() to get the header template.
4
+ * We use this so start our output buffer and render into the view/page-plugin.twig template in footer.php
5
+ */
6
+ $GLOBALS['timberContext'] = Timber::get_context();
7
+ ob_start();
timber-starter-theme/index.php CHANGED
@@ -15,6 +15,7 @@
15
 
16
  if (!class_exists('Timber')){
17
  echo 'Timber not activated. Make sure you activate the plugin in <a href="/wp-admin/plugins.php#timber">/wp-admin/plugins.php</a>';
 
18
  }
19
  $context = Timber::get_context();
20
  $context['posts'] = Timber::get_posts();
15
 
16
  if (!class_exists('Timber')){
17
  echo 'Timber not activated. Make sure you activate the plugin in <a href="/wp-admin/plugins.php#timber">/wp-admin/plugins.php</a>';
18
+ return;
19
  }
20
  $context = Timber::get_context();
21
  $context['posts'] = Timber::get_posts();
timber-starter-theme/views/page-plugin.twig ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ {% extends "base.twig" %}
2
+
3
+ {% block content %}
4
+ <div class="container content-wrapper">
5
+ {{content}}
6
+ </div> <!-- /content-wrapper -->
7
+ {% endblock %}
timber.php CHANGED
@@ -4,7 +4,7 @@ Plugin Name: Timber
4
  Plugin URI: http://timber.upstatement.com
5
  Description: The WordPress Timber Library allows you to write themes using the power Twig templates
6
  Author: Jared Novack + Upstatement
7
- Version: 0.19.0
8
  Author URI: http://upstatement.com/
9
  */
10
 
@@ -124,7 +124,7 @@ class Timber {
124
  $query = false;
125
  }
126
  if (TimberHelper::is_array_assoc($query) || (is_string($query) && strstr($query, '='))) {
127
- // we have a regularly formed WP query string or array to use
128
  $posts = self::get_posts_from_wp_query($query, $PostClass);
129
  } else if (is_string($query) && !is_integer($query)) {
130
  // we have what could be a post name to pull out
@@ -135,7 +135,7 @@ class Timber {
135
  } else if (is_array($query) && count($query) && isset($query[0]) && is_object($query[0])) {
136
  // maybe its an array of post objects that already have data
137
  $posts = self::handle_post_results($query, $PostClass);
138
- } else if (have_posts()) {
139
  //lets just use the default WordPress current query
140
  $posts = self::get_posts_from_loop($PostClass);
141
  } else if (!$query) {
@@ -180,18 +180,12 @@ class Timber {
180
  * @return array
181
  */
182
  public static function get_pids_from_loop() {
183
- $posts = array();
184
- $i = 0;
185
- ob_start();
186
- while (have_posts() && $i < 99999) {
187
- the_post();
188
- $posts[] = get_the_ID();
189
- $i++;
190
- }
191
- //why is this here? seems to only cause pain.
192
- //wp_reset_query();
193
- ob_end_clean();
194
- return $posts;
195
  }
196
 
197
  /**
@@ -281,6 +275,11 @@ class Timber {
281
  return $post->ID;
282
  }
283
 
 
 
 
 
 
284
  /* Post Previews
285
  ================================ */
286
 
@@ -328,20 +327,25 @@ class Timber {
328
  * @param string $PostClass
329
  * @return bool|null
330
  */
331
- public function loop_to_posts($PostClass = 'TimberPost') {
332
  return self::get_posts(false, $PostClass);
333
  }
334
 
335
  /**
336
  * @return bool|int
337
  */
338
- public function loop_to_id() {
339
- if (have_posts()) {
340
- the_post();
341
- wp_reset_query();
342
- return get_the_ID();
343
- }
344
- return false;
 
 
 
 
 
345
  }
346
 
347
 
@@ -389,8 +393,8 @@ class Timber {
389
  return self::handle_term_query($parsed->taxonomies, $parsed->args, $TermClass);
390
  } else {
391
  //no clue, what you talkin' bout?
 
392
  }
393
-
394
  }
395
 
396
  /**
@@ -420,7 +424,7 @@ class Timber {
420
  public static function get_sites($blog_ids = false){
421
  if (!is_array($blog_ids)){
422
  global $wpdb;
423
- $site_ids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs");
424
  }
425
  $return = array();
426
  foreach($blog_ids as $blog_id){
@@ -443,19 +447,21 @@ class Timber {
443
  $data['wp_head'] = TimberHelper::function_wrapper('wp_head');
444
  $data['wp_footer'] = TimberHelper::function_wrapper('wp_footer');
445
  $data['body_class'] = implode(' ', get_body_class());
 
 
 
 
 
 
 
 
 
446
  if (function_exists('wp_nav_menu')) {
447
  $locations = get_nav_menu_locations();
448
  if (count($locations)){
449
  $data['wp_nav_menu'] = wp_nav_menu(array('container_class' => 'menu-header', 'echo' => false, 'menu_class' => 'nav-menu'));
450
  }
451
  }
452
- $data['theme_dir'] = str_replace(ABSPATH, '', get_stylesheet_directory());
453
- $data['language_attributes'] = TimberHelper::function_wrapper('language_attributes');
454
- $data['stylesheet_uri'] = get_stylesheet_uri();
455
- $data['template_uri'] = get_template_directory_uri();
456
- $data['theme'] = new TimberTheme();
457
- $data['site'] = new TimberSite();
458
- $data['site']->theme = $data['theme'];
459
  $data = apply_filters('timber_context', $data);
460
  return $data;
461
  }
@@ -473,6 +479,9 @@ class Timber {
473
  $loader = new TimberLoader($caller);
474
  $file = $loader->choose_template($filenames);
475
  $output = '';
 
 
 
476
  if (strlen($file)) {
477
  if ($via_render){
478
  $file = apply_filters('timber_render_file', $file);
@@ -631,7 +640,7 @@ class Timber {
631
  }
632
  }
633
 
634
- public static function cancel_query(){
635
  add_action('posts_request', array($this, 'cancel_query_posts_request'));
636
  }
637
 
@@ -643,9 +652,10 @@ class Timber {
643
 
644
  /**
645
  * @param array $template
646
- * @param bool $query
647
  * @param int $force_header
648
  * @param bool $tparams
 
649
  */
650
  public static function load_template($template, $query = false, $force_header = 0, $tparams = false) {
651
 
@@ -693,12 +703,9 @@ class Timber {
693
  });
694
  }
695
  if ($template) {
696
- add_action('wp_loaded', function() use ($template) {
697
- wp();
698
- do_action('template_redirect');
699
- load_template($template);
700
- die;
701
- });
702
  return true;
703
  }
704
  return false;
4
  Plugin URI: http://timber.upstatement.com
5
  Description: The WordPress Timber Library allows you to write themes using the power Twig templates
6
  Author: Jared Novack + Upstatement
7
+ Version: 0.19.1
8
  Author URI: http://upstatement.com/
9
  */
10
 
124
  $query = false;
125
  }
126
  if (TimberHelper::is_array_assoc($query) || (is_string($query) && strstr($query, '='))) {
127
+ // we have a regularly formed WP query string or array to use
128
  $posts = self::get_posts_from_wp_query($query, $PostClass);
129
  } else if (is_string($query) && !is_integer($query)) {
130
  // we have what could be a post name to pull out
135
  } else if (is_array($query) && count($query) && isset($query[0]) && is_object($query[0])) {
136
  // maybe its an array of post objects that already have data
137
  $posts = self::handle_post_results($query, $PostClass);
138
+ } else if (self::wp_query_has_posts()) {
139
  //lets just use the default WordPress current query
140
  $posts = self::get_posts_from_loop($PostClass);
141
  } else if (!$query) {
180
  * @return array
181
  */
182
  public static function get_pids_from_loop() {
183
+ if (!self::wp_query_has_posts()) { return array(); }
184
+
185
+ global $wp_query;
186
+ return array_filter(array_map(function($p) {
187
+ return ($p && property_exists($p, 'ID')) ? $p->ID : null;
188
+ }, $wp_query->posts));
 
 
 
 
 
 
189
  }
190
 
191
  /**
275
  return $post->ID;
276
  }
277
 
278
+ public static function wp_query_has_posts() {
279
+ global $wp_query;
280
+ return ($wp_query && property_exists($wp_query, 'posts') && $wp_query->posts);
281
+ }
282
+
283
  /* Post Previews
284
  ================================ */
285
 
327
  * @param string $PostClass
328
  * @return bool|null
329
  */
330
+ public static function loop_to_posts($PostClass = 'TimberPost') {
331
  return self::get_posts(false, $PostClass);
332
  }
333
 
334
  /**
335
  * @return bool|int
336
  */
337
+ public static function loop_to_id() {
338
+ if (!self::wp_query_has_posts()) { return false; }
339
+
340
+ global $wp_query;
341
+ $post_num = property_exists($wp_query, 'current_post')
342
+ ? $wp_query->current_post + 1
343
+ : 0
344
+ ;
345
+
346
+ if (!isset($wp_query->posts[$post_num])) { return false; }
347
+
348
+ return $wp_query->posts[$post_num]->ID;
349
  }
350
 
351
 
393
  return self::handle_term_query($parsed->taxonomies, $parsed->args, $TermClass);
394
  } else {
395
  //no clue, what you talkin' bout?
396
+ return null;
397
  }
 
398
  }
399
 
400
  /**
424
  public static function get_sites($blog_ids = false){
425
  if (!is_array($blog_ids)){
426
  global $wpdb;
427
+ $blog_ids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs");
428
  }
429
  $return = array();
430
  foreach($blog_ids as $blog_id){
447
  $data['wp_head'] = TimberHelper::function_wrapper('wp_head');
448
  $data['wp_footer'] = TimberHelper::function_wrapper('wp_footer');
449
  $data['body_class'] = implode(' ', get_body_class());
450
+
451
+ $data['site'] = new TimberSite();
452
+ $data['theme'] = $data['site']->theme;
453
+ //deprecated, these should be fetched via TimberSite or TimberTheme
454
+ $data['theme_dir'] = WP_CONTENT_SUBDIR.str_replace(WP_CONTENT_DIR, '', get_stylesheet_directory());
455
+ $data['language_attributes'] = TimberHelper::function_wrapper('language_attributes');
456
+ $data['stylesheet_uri'] = get_stylesheet_uri();
457
+ $data['template_uri'] = get_template_directory_uri();
458
+ //deprecated, this should be fetched via TimberMenu
459
  if (function_exists('wp_nav_menu')) {
460
  $locations = get_nav_menu_locations();
461
  if (count($locations)){
462
  $data['wp_nav_menu'] = wp_nav_menu(array('container_class' => 'menu-header', 'echo' => false, 'menu_class' => 'nav-menu'));
463
  }
464
  }
 
 
 
 
 
 
 
465
  $data = apply_filters('timber_context', $data);
466
  return $data;
467
  }
479
  $loader = new TimberLoader($caller);
480
  $file = $loader->choose_template($filenames);
481
  $output = '';
482
+ if (is_null($data)){
483
+ $data = array();
484
+ }
485
  if (strlen($file)) {
486
  if ($via_render){
487
  $file = apply_filters('timber_render_file', $file);
640
  }
641
  }
642
 
643
+ public function cancel_query(){
644
  add_action('posts_request', array($this, 'cancel_query_posts_request'));
645
  }
646
 
652
 
653
  /**
654
  * @param array $template
655
+ * @param mixed $query
656
  * @param int $force_header
657
  * @param bool $tparams
658
+ * @return bool
659
  */
660
  public static function load_template($template, $query = false, $force_header = 0, $tparams = false) {
661
 
703
  });
704
  }
705
  if ($template) {
706
+ add_filter('template_include', function($t) use ($template) {
707
+ return $template;
708
+ });
 
 
 
709
  return true;
710
  }
711
  return false;
vendor/asm89/twig-cache-extension/.gitignore ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ phpunit.xml
2
+ composer.lock
3
+ composer.phar
4
+ /vendor/
vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer' . '/autoload_real.php';
6
 
7
- return ComposerAutoloaderInit16db62602ddf09151da058b0c233959c::getLoader();
4
 
5
  require_once __DIR__ . '/composer' . '/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInit5a0dca61483fec0916bb0b4cbcd01f05::getLoader();
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInit16db62602ddf09151da058b0c233959c
6
  {
7
  private static $loader;
8
 
@@ -19,9 +19,9 @@ class ComposerAutoloaderInit16db62602ddf09151da058b0c233959c
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInit16db62602ddf09151da058b0c233959c', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInit16db62602ddf09151da058b0c233959c', 'loadClassLoader'));
25
 
26
  $vendorDir = dirname(__DIR__);
27
  $baseDir = dirname($vendorDir);
@@ -47,7 +47,7 @@ class ComposerAutoloaderInit16db62602ddf09151da058b0c233959c
47
  }
48
  }
49
 
50
- function composerRequire16db62602ddf09151da058b0c233959c($file)
51
  {
52
  require $file;
53
  }
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInit5a0dca61483fec0916bb0b4cbcd01f05
6
  {
7
  private static $loader;
8
 
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInit5a0dca61483fec0916bb0b4cbcd01f05', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInit5a0dca61483fec0916bb0b4cbcd01f05', 'loadClassLoader'));
25
 
26
  $vendorDir = dirname(__DIR__);
27
  $baseDir = dirname($vendorDir);
47
  }
48
  }
49
 
50
+ function composerRequire5a0dca61483fec0916bb0b4cbcd01f05($file)
51
  {
52
  require $file;
53
  }
vendor/composer/installed.json CHANGED
@@ -200,24 +200,24 @@
200
  },
201
  {
202
  "name": "symfony/yaml",
203
- "version": "v2.4.4",
204
- "version_normalized": "2.4.4.0",
205
  "target-dir": "Symfony/Component/Yaml",
206
  "source": {
207
  "type": "git",
208
  "url": "https://github.com/symfony/Yaml.git",
209
- "reference": "65539ecde838f9c0d18b006b2101e3deb4b5c9ff"
210
  },
211
  "dist": {
212
  "type": "zip",
213
- "url": "https://api.github.com/repos/symfony/Yaml/zipball/65539ecde838f9c0d18b006b2101e3deb4b5c9ff",
214
- "reference": "65539ecde838f9c0d18b006b2101e3deb4b5c9ff",
215
  "shasum": ""
216
  },
217
  "require": {
218
  "php": ">=5.3.3"
219
  },
220
- "time": "2014-04-18 20:37:09",
221
  "type": "library",
222
  "extra": {
223
  "branch-alias": {
200
  },
201
  {
202
  "name": "symfony/yaml",
203
+ "version": "v2.4.5",
204
+ "version_normalized": "2.4.5.0",
205
  "target-dir": "Symfony/Component/Yaml",
206
  "source": {
207
  "type": "git",
208
  "url": "https://github.com/symfony/Yaml.git",
209
+ "reference": "fd22bb88c3a6f73c898b39bec185a9e211b06265"
210
  },
211
  "dist": {
212
  "type": "zip",
213
+ "url": "https://api.github.com/repos/symfony/Yaml/zipball/fd22bb88c3a6f73c898b39bec185a9e211b06265",
214
+ "reference": "fd22bb88c3a6f73c898b39bec185a9e211b06265",
215
  "shasum": ""
216
  },
217
  "require": {
218
  "php": ">=5.3.3"
219
  },
220
+ "time": "2014-05-12 09:27:48",
221
  "type": "library",
222
  "extra": {
223
  "branch-alias": {
vendor/symfony/yaml/Symfony/Component/Yaml/Parser.php CHANGED
@@ -55,7 +55,7 @@ class Parser
55
  $this->currentLine = '';
56
  $this->lines = explode("\n", $this->cleanup($value));
57
 
58
- if (function_exists('mb_detect_encoding') && false === mb_detect_encoding($value, 'UTF-8', true)) {
59
  throw new ParseException('The YAML value does not appear to be valid UTF-8.');
60
  }
61
 
55
  $this->currentLine = '';
56
  $this->lines = explode("\n", $this->cleanup($value));
57
 
58
+ if (!preg_match('//u', $value)) {
59
  throw new ParseException('The YAML value does not appear to be valid UTF-8.');
60
  }
61
 
vendor/symfony/yaml/Symfony/Component/Yaml/Tests/ParserTest.php CHANGED
@@ -33,12 +33,6 @@ class ParserTest extends \PHPUnit_Framework_TestCase
33
  */
34
  public function testSpecifications($file, $expected, $yaml, $comment)
35
  {
36
- if ('escapedCharacters' == $file) {
37
- if (!function_exists('iconv') && !function_exists('mb_convert_encoding')) {
38
- $this->markTestSkipped('The iconv and mbstring extensions are not available.');
39
- }
40
- }
41
-
42
  $this->assertEquals($expected, var_export($this->parser->parse($yaml), true), $comment);
43
  }
44
 
@@ -446,8 +440,8 @@ EOF;
446
 
447
  public function testNonUtf8Exception()
448
  {
449
- if (!function_exists('mb_detect_encoding') || !function_exists('iconv')) {
450
- $this->markTestSkipped('Exceptions for non-utf8 charsets require the mb_detect_encoding() and iconv() functions.');
451
 
452
  return;
453
  }
33
  */
34
  public function testSpecifications($file, $expected, $yaml, $comment)
35
  {
 
 
 
 
 
 
36
  $this->assertEquals($expected, var_export($this->parser->parse($yaml), true), $comment);
37
  }
38
 
440
 
441
  public function testNonUtf8Exception()
442
  {
443
+ if (!function_exists('iconv')) {
444
+ $this->markTestSkipped('Exceptions for non-utf8 charsets require the iconv() function.');
445
 
446
  return;
447
  }
vendor/symfony/yaml/Symfony/Component/Yaml/Unescaper.php CHANGED
@@ -21,6 +21,7 @@ class Unescaper
21
  {
22
  // Parser and Inline assume UTF-8 encoding, so escaped Unicode characters
23
  // must be converted to that encoding.
 
24
  const ENCODING = 'UTF-8';
25
 
26
  // Regex fragment that matches an escaped character in a double quoted
@@ -80,13 +81,13 @@ class Unescaper
80
  case 'n':
81
  return "\n";
82
  case 'v':
83
- return "\xb";
84
  case 'f':
85
- return "\xc";
86
  case 'r':
87
- return "\xd";
88
  case 'e':
89
- return "\x1b";
90
  case ' ':
91
  return ' ';
92
  case '"':
@@ -97,50 +98,44 @@ class Unescaper
97
  return '\\';
98
  case 'N':
99
  // U+0085 NEXT LINE
100
- return $this->convertEncoding("\x00\x85", self::ENCODING, 'UCS-2BE');
101
  case '_':
102
  // U+00A0 NO-BREAK SPACE
103
- return $this->convertEncoding("\x00\xA0", self::ENCODING, 'UCS-2BE');
104
  case 'L':
105
  // U+2028 LINE SEPARATOR
106
- return $this->convertEncoding("\x20\x28", self::ENCODING, 'UCS-2BE');
107
  case 'P':
108
  // U+2029 PARAGRAPH SEPARATOR
109
- return $this->convertEncoding("\x20\x29", self::ENCODING, 'UCS-2BE');
110
  case 'x':
111
- $char = pack('n', hexdec(substr($value, 2, 2)));
112
-
113
- return $this->convertEncoding($char, self::ENCODING, 'UCS-2BE');
114
  case 'u':
115
- $char = pack('n', hexdec(substr($value, 2, 4)));
116
-
117
- return $this->convertEncoding($char, self::ENCODING, 'UCS-2BE');
118
  case 'U':
119
- $char = pack('N', hexdec(substr($value, 2, 8)));
120
-
121
- return $this->convertEncoding($char, self::ENCODING, 'UCS-4BE');
122
  }
123
  }
124
 
125
  /**
126
- * Convert a string from one encoding to another.
127
  *
128
- * @param string $value The string to convert
129
- * @param string $to The input encoding
130
- * @param string $from The output encoding
131
  *
132
- * @return string The string with the new encoding
133
- *
134
- * @throws \RuntimeException if no suitable encoding function is found (iconv or mbstring)
135
  */
136
- private function convertEncoding($value, $to, $from)
137
  {
138
- if (function_exists('mb_convert_encoding')) {
139
- return mb_convert_encoding($value, $to, $from);
140
- } elseif (function_exists('iconv')) {
141
- return iconv($from, $to, $value);
 
 
 
 
142
  }
143
 
144
- throw new \RuntimeException('No suitable convert encoding function (install the iconv or mbstring extension).');
145
  }
146
  }
21
  {
22
  // Parser and Inline assume UTF-8 encoding, so escaped Unicode characters
23
  // must be converted to that encoding.
24
+ // @deprecated since 2.5, to be removed in 3.0
25
  const ENCODING = 'UTF-8';
26
 
27
  // Regex fragment that matches an escaped character in a double quoted
81
  case 'n':
82
  return "\n";
83
  case 'v':
84
+ return "\xB";
85
  case 'f':
86
+ return "\xC";
87
  case 'r':
88
+ return "\r";
89
  case 'e':
90
+ return "\x1B";
91
  case ' ':
92
  return ' ';
93
  case '"':
98
  return '\\';
99
  case 'N':
100
  // U+0085 NEXT LINE
101
+ return "\xC2\x85";
102
  case '_':
103
  // U+00A0 NO-BREAK SPACE
104
+ return "\xC2\xA0";
105
  case 'L':
106
  // U+2028 LINE SEPARATOR
107
+ return "\xE2\x80\xA8";
108
  case 'P':
109
  // U+2029 PARAGRAPH SEPARATOR
110
+ return "\xE2\x80\xA9";
111
  case 'x':
112
+ return self::utf8chr(hexdec(substr($value, 2, 2)));
 
 
113
  case 'u':
114
+ return self::utf8chr(hexdec(substr($value, 2, 4)));
 
 
115
  case 'U':
116
+ return self::utf8chr(hexdec(substr($value, 2, 8)));
 
 
117
  }
118
  }
119
 
120
  /**
121
+ * Get the UTF-8 character for the given code point.
122
  *
123
+ * @param int $c The unicode code point
 
 
124
  *
125
+ * @return string The corresponding UTF-8 character
 
 
126
  */
127
+ private static function utf8chr($c)
128
  {
129
+ if (0x80 > $c %= 0x200000) {
130
+ return chr($c);
131
+ }
132
+ if (0x800 > $c) {
133
+ return chr(0xC0 | $c>>6).chr(0x80 | $c & 0x3F);
134
+ }
135
+ if (0x10000 > $c) {
136
+ return chr(0xE0 | $c>>12).chr(0x80 | $c>>6 & 0x3F).chr(0x80 | $c & 0x3F);
137
  }
138
 
139
+ return chr(0xF0 | $c>>18).chr(0x80 | $c>>12 & 0x3F).chr(0x80 | $c>>6 & 0x3F).chr(0x80 | $c & 0x3F);
140
  }
141
  }