Timber - Version 1.2.0

Version Description

  • Fixed issues with WordPress 4.7
  • Introduced Timber\CommentThread object
Download this release

Release Info

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

Code changes from version 1.1.12 to 1.2.0

README.md CHANGED
@@ -84,6 +84,7 @@ Timber is great for any WordPress developer who cares about writing good, mainta
84
  * [**Timber Sugar**](https://github.com/timber/sugar) A catch-all for goodies to use w Timber.
85
  * [**Timmy**](https://github.com/MINDKomm/Timmy) Advanced image manipulation for Timber.
86
  * [**Twig**](https://github.com/fabpot/Twig) The template language used by Timber.
 
87
 
88
  #### Projects that use Timber
89
  * [**Gantry5**](https://wordpress.org/plugins/gantry5/) a framework for theme development
84
  * [**Timber Sugar**](https://github.com/timber/sugar) A catch-all for goodies to use w Timber.
85
  * [**Timmy**](https://github.com/MINDKomm/Timmy) Advanced image manipulation for Timber.
86
  * [**Twig**](https://github.com/fabpot/Twig) The template language used by Timber.
87
+ * [**Pine**](https://github.com/azeemhassni/pine) A CLI installer for timber
88
 
89
  #### Projects that use Timber
90
  * [**Gantry5**](https://wordpress.org/plugins/gantry5/) a framework for theme development
lib/Comment.php CHANGED
@@ -41,6 +41,7 @@ class Comment extends Core implements CoreInterface {
41
  public $user_id;
42
  public $post_id;
43
  public $comment_author;
 
44
 
45
  protected $children = array();
46
 
@@ -160,6 +161,7 @@ class Comment extends Core implements CoreInterface {
160
  }
161
 
162
  /**
 
163
  */
164
  public function add_child( Comment $child_comment ) {
165
  if ( !is_array($this->children) ) {
@@ -168,6 +170,22 @@ class Comment extends Core implements CoreInterface {
168
  return $this->children[] = $child_comment;
169
  }
170
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
171
  /**
172
  * @api
173
  * @example
41
  public $user_id;
42
  public $post_id;
43
  public $comment_author;
44
+ public $_depth = 0;
45
 
46
  protected $children = array();
47
 
161
  }
162
 
163
  /**
164
+ * @param Comment $child_comment;
165
  */
166
  public function add_child( Comment $child_comment ) {
167
  if ( !is_array($this->children) ) {
170
  return $this->children[] = $child_comment;
171
  }
172
 
173
+ /**
174
+ * @param int $depth
175
+ */
176
+ public function update_depth( $depth = 0 ) {
177
+ $this->_depth = $depth;
178
+ $children = $this->children();
179
+ foreach ( $children as $comment ) {
180
+ $child_depth = $depth + 1;
181
+ $comment->update_depth( $child_depth );
182
+ }
183
+ }
184
+
185
+ public function depth() {
186
+ return $this->_depth;
187
+ }
188
+
189
  /**
190
  * @api
191
  * @example
lib/CommentThread.php ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Timber;
4
+
5
+ use Timber\Comment;
6
+
7
+ class CommentThread extends \ArrayObject {
8
+
9
+ var $CommentClass = 'Timber\Comment';
10
+ var $post_id;
11
+ var $_orderby = '';
12
+ var $_order = 'ASC';
13
+
14
+ public function __construct( $post_id, $args = array() ) {
15
+ parent::__construct();
16
+ $this->post_id = $post_id;
17
+ $this->init($args);
18
+ }
19
+
20
+ protected function fetch_comments( $args = array() ) {
21
+ $args['post_id'] = $this->post_id;
22
+ $comments = get_comments($args);
23
+ return $comments;
24
+ }
25
+
26
+ /**
27
+ * @experimental
28
+ */
29
+ public function orderby( $orderby = 'wp' ) {
30
+ $this->_orderby = $orderby;
31
+ $this->init();
32
+ return $this;
33
+ }
34
+
35
+ protected function merge_args( $args ) {
36
+ $base = array('status' => 'approve');
37
+ $overrides = array('order' => $this->_order);
38
+ return array_merge($base, $args, $overrides);
39
+ }
40
+
41
+ /**
42
+ * @experimental
43
+ */
44
+ public function order( $order = 'ASC' ) {
45
+ $this->_order = $order;
46
+ $this->init();
47
+ return $this;
48
+ }
49
+
50
+ protected function init( $args = array() ) {
51
+ global $overridden_cpage;
52
+ $args = self::merge_args($args);
53
+ $comments = $this->fetch_comments( $args );
54
+ $tcs = array();
55
+ if ( '' == get_query_var('cpage') && get_option('page_comments') ) {
56
+ set_query_var('cpage', 'newest' == get_option('default_comments_page') ? get_comment_pages_count() : 1);
57
+ $overridden_cpage = true;
58
+ }
59
+ foreach ( $comments as $key => &$comment ) {
60
+ $timber_comment = new $this->CommentClass($comment);
61
+ $tcs[$timber_comment->id] = $timber_comment;
62
+ }
63
+
64
+ $parents = array();
65
+ $children = array();
66
+
67
+ foreach( $tcs as $comment ) {
68
+ if ( $comment->is_child() ) {
69
+ $children[$comment->ID] = $comment;
70
+ } else {
71
+ $parents[$comment->ID] = $comment;
72
+ }
73
+ }
74
+
75
+
76
+
77
+ foreach ( $children as &$comment ) {
78
+ $parent_id = $comment->comment_parent;
79
+ if ( isset($parents[$parent_id]) ) {
80
+ $parents[$parent_id]->add_child( $comment );
81
+ }
82
+ if ( isset($children[$parent_id]) ) {
83
+ $children[$parent_id]->add_child( $comment );
84
+ }
85
+ }
86
+ //there's something in update_depth that breaks order?
87
+
88
+ foreach ( $parents as $comment ) {
89
+ $comment->update_depth();
90
+ }
91
+ $this->import_comments($parents);
92
+ }
93
+
94
+ protected function clear() {
95
+ $this->exchangeArray(array());
96
+ }
97
+
98
+ protected function import_comments( $arr ) {
99
+ $this->clear();
100
+ $i = 0;
101
+ foreach ( $arr as $comment ) {
102
+ $this[$i] = $comment;
103
+ $i++;
104
+ }
105
+ }
106
+
107
+ }
lib/Image/Operation.php CHANGED
@@ -50,4 +50,8 @@ abstract class Operation {
50
  $int = hexdec($hexstr);
51
  return array("red" => 0xFF & ($int >> 0x10), "green" => 0xFF & ($int >> 0x8), "blue" => 0xFF & $int);
52
  }
 
 
 
 
53
  }
50
  $int = hexdec($hexstr);
51
  return array("red" => 0xFF & ($int >> 0x10), "green" => 0xFF & ($int >> 0x8), "blue" => 0xFF & $int);
52
  }
53
+
54
+ public static function rgbhex( $r, $g, $b ) {
55
+ return '#' . sprintf('%02x', $r) . sprintf('%02x', $g) . sprintf('%02x', $b);
56
+ }
57
  }
lib/ImageHelper.php CHANGED
@@ -375,18 +375,37 @@ class ImageHelper {
375
  }
376
  if ( 0 === strpos($tmp, content_url()) ) {
377
  $result['base'] = self::BASE_CONTENT; // content-based
378
- $tmp = str_replace(content_url(), '', $tmp);
379
  }
380
  }
381
  $parts = pathinfo($tmp);
 
382
  $result['subdir'] = ($parts['dirname'] === '/') ? '' : $parts['dirname'];
383
  $result['filename'] = $parts['filename'];
384
  $result['extension'] = strtolower($parts['extension']);
385
  $result['basename'] = $parts['basename'];
386
- // todo filename
387
  return $result;
388
  }
389
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
390
  /**
391
  * Builds the public URL of a file based on its different components
392
  *
@@ -433,10 +452,15 @@ class ImageHelper {
433
  if ( self::BASE_CONTENT == $base ) {
434
  $path = WP_CONTENT_DIR;
435
  }
 
 
 
 
436
  if ( !empty($subdir) ) {
437
  $path .= $subdir;
438
  }
439
  $path .= '/'.$filename;
 
440
  return $path;
441
  }
442
 
@@ -459,7 +483,6 @@ class ImageHelper {
459
  return '';
460
  }
461
  $external = false;
462
-
463
  // if external image, load it first
464
  if ( URLHelper::is_external_content($src) ) {
465
  $src = self::sideload_image($src);
375
  }
376
  if ( 0 === strpos($tmp, content_url()) ) {
377
  $result['base'] = self::BASE_CONTENT; // content-based
378
+ $tmp = self::theme_url_to_dir($tmp);
379
  }
380
  }
381
  $parts = pathinfo($tmp);
382
+
383
  $result['subdir'] = ($parts['dirname'] === '/') ? '' : $parts['dirname'];
384
  $result['filename'] = $parts['filename'];
385
  $result['extension'] = strtolower($parts['extension']);
386
  $result['basename'] = $parts['basename'];
 
387
  return $result;
388
  }
389
 
390
+ /**
391
+ * Converts a URL located in a theme directory into the raw path
392
+ * @param string $src a URL (http://example.org/wp-content/themes/twentysixteen/images/home.jpg)
393
+ * @return string full path to the file in question
394
+ */
395
+ protected static function theme_url_to_dir( $tmp ) {
396
+ $root = trailingslashit(get_theme_root_uri()).get_stylesheet();
397
+ $tmp = str_replace($root, '', $tmp);
398
+ $tmp = realpath(get_stylesheet_directory_uri().$tmp);
399
+ return $tmp;
400
+ }
401
+
402
+ protected static function is_in_theme_dir( $path ) {
403
+ $root = realpath(get_stylesheet_directory_uri());
404
+ if ( 0 === strpos($path, $root) ) {
405
+ return true;
406
+ }
407
+ }
408
+
409
  /**
410
  * Builds the public URL of a file based on its different components
411
  *
452
  if ( self::BASE_CONTENT == $base ) {
453
  $path = WP_CONTENT_DIR;
454
  }
455
+ if ( self::is_in_theme_dir(trailingslashit($subdir).$filename) ) {
456
+ return trailingslashit($subdir).$filename;
457
+ $path = $subdir;
458
+ }
459
  if ( !empty($subdir) ) {
460
  $path .= $subdir;
461
  }
462
  $path .= '/'.$filename;
463
+
464
  return $path;
465
  }
466
 
483
  return '';
484
  }
485
  $external = false;
 
486
  // if external image, load it first
487
  if ( URLHelper::is_external_content($src) ) {
488
  $src = self::sideload_image($src);
lib/MenuItem.php CHANGED
@@ -311,4 +311,22 @@ class MenuItem extends Core implements CoreInterface {
311
  return $this->__title;
312
  }
313
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
314
  }
311
  return $this->__title;
312
  }
313
  }
314
+
315
+ /**
316
+ * Gets the post thumbnail image object
317
+ * @example
318
+ * ```twig
319
+ * {% for item in menu.items %}
320
+ * <li><a href="{{ item.link }}"><img src="{{ item.thumbnail }}"/></a></li>
321
+ * {% endfor %}
322
+ * ```
323
+ * @return string the public thumbnail url
324
+ */
325
+ public function thumbnail() {
326
+ if ( $this->menu_object && method_exists($this->menu_object, 'thumbnail')) {
327
+ return $this->menu_object->thumbnail();
328
+ } else {
329
+ error_log('no master object');
330
+ }
331
+ }
332
  }
lib/Post.php CHANGED
@@ -4,7 +4,7 @@ namespace Timber;
4
 
5
  use Timber\Core;
6
  use Timber\CoreInterface;
7
-
8
  use Timber\Term;
9
  use Timber\User;
10
  use Timber\Image;
@@ -882,14 +882,14 @@ class Post extends Core implements CoreInterface {
882
  * ```
883
  * @return bool|array
884
  */
885
- public function comments( $count = 0, $order = 'wp', $type = 'comment', $status = 'approve', $CommentClass = 'Timber\Comment' ) {
886
  global $overridden_cpage, $user_ID;
887
  $overridden_cpage = false;
888
 
889
  $commenter = wp_get_current_commenter();
890
  $comment_author_email = $commenter['comment_author_email'];
891
 
892
- $args = array('post_id' => $this->ID, 'status' => $status, 'order' => $order);
893
  if ( $count > 0 ) {
894
  $args['number'] = $count;
895
  }
@@ -903,45 +903,7 @@ class Post extends Core implements CoreInterface {
903
  $args['include_unapproved'] = array($comment_author_email);
904
  }
905
 
906
- $comments = get_comments($args);
907
- $timber_comments = array();
908
-
909
- if ( '' == get_query_var('cpage') && get_option('page_comments') ) {
910
- set_query_var('cpage', 'newest' == get_option('default_comments_page') ? get_comment_pages_count() : 1);
911
- $overridden_cpage = true;
912
- }
913
-
914
- foreach ( $comments as $key => &$comment ) {
915
- $timber_comment = new $CommentClass($comment);
916
- $timber_comments[$timber_comment->id] = $timber_comment;
917
- }
918
-
919
- // Build a flattened (depth=1) comment tree
920
- $comments_tree = array();
921
- foreach ( $timber_comments as $key => $comment ) {
922
- if ( !$comment->is_child() ) {
923
- continue;
924
- }
925
-
926
- $tree_element = $comment;
927
- do {
928
- $tree_element = $timber_comments[$tree_element->comment_parent];
929
- } while ( $tree_element->is_child() );
930
-
931
- $comments_tree[$tree_element->id][] = $comment->id;
932
- }
933
-
934
- // Add child comments to the relative "super parents"
935
- foreach ( $comments_tree as $comment_parent => $comment_children ) {
936
- foreach ( $comment_children as $comment_child ) {
937
- $timber_comments[$comment_parent]->add_child($timber_comments[$comment_child]);
938
- unset($timber_comments[$comment_child]);
939
- }
940
- }
941
-
942
- $timber_comments = array_values($timber_comments);
943
-
944
- return $timber_comments;
945
  }
946
 
947
  /**
@@ -1652,7 +1614,7 @@ class Post extends Core implements CoreInterface {
1652
  * @param string $CommentClass
1653
  * @return array|mixed
1654
  */
1655
- public function get_comments( $count = 0, $order = 'wp', $type = 'comment', $status = 'approve', $CommentClass = 'Timber\Comment' ) {
1656
  return $this->comments($count, $order, $type, $status, $CommentClass);
1657
  }
1658
 
4
 
5
  use Timber\Core;
6
  use Timber\CoreInterface;
7
+ use Timber\CommentThread;
8
  use Timber\Term;
9
  use Timber\User;
10
  use Timber\Image;
882
  * ```
883
  * @return bool|array
884
  */
885
+ public function comments( $count = null, $order = 'wp', $type = 'comment', $status = 'approve', $CommentClass = 'Timber\Comment' ) {
886
  global $overridden_cpage, $user_ID;
887
  $overridden_cpage = false;
888
 
889
  $commenter = wp_get_current_commenter();
890
  $comment_author_email = $commenter['comment_author_email'];
891
 
892
+ $args = array('status' => $status, 'order' => $order);
893
  if ( $count > 0 ) {
894
  $args['number'] = $count;
895
  }
903
  $args['include_unapproved'] = array($comment_author_email);
904
  }
905
 
906
+ return new CommentThread($this->ID, $args);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
907
  }
908
 
909
  /**
1614
  * @param string $CommentClass
1615
  * @return array|mixed
1616
  */
1617
+ public function get_comments( $count = null, $order = 'wp', $type = 'comment', $status = 'approve', $CommentClass = 'Timber\Comment' ) {
1618
  return $this->comments($count, $order, $type, $status, $CommentClass);
1619
  }
1620
 
lib/Timber.php CHANGED
@@ -35,7 +35,7 @@ use Timber\Loader;
35
  */
36
  class Timber {
37
 
38
- public static $version = '1.1.12';
39
  public static $locations;
40
  public static $dirname = 'views';
41
  public static $twig_cache = false;
35
  */
36
  class Timber {
37
 
38
+ public static $version = '1.2.0';
39
  public static $locations;
40
  public static $dirname = 'views';
41
  public static $twig_cache = false;
readme.txt CHANGED
@@ -41,6 +41,10 @@ Timber is great for any WordPress developer who cares about writing good, mainta
41
 
42
  == Changelog ==
43
 
 
 
 
 
44
  = 1.1.12 =
45
  * Fixed Twig issue with deprecation #1265 (thanks @codesman)!
46
  * Cleaned-up the warnings for WP.org users and disabled easy updates for major/milestone versions 331314d9aaf90a52ff1c5a213656b8c02a27c60e
41
 
42
  == Changelog ==
43
 
44
+ = 1.2.0 =
45
+ * Fixed issues with WordPress 4.7
46
+ * Introduced Timber\CommentThread object
47
+
48
  = 1.1.12 =
49
  * Fixed Twig issue with deprecation #1265 (thanks @codesman)!
50
  * Cleaned-up the warnings for WP.org users and disabled easy updates for major/milestone versions 331314d9aaf90a52ff1c5a213656b8c02a27c60e
timber.php CHANGED
@@ -4,7 +4,7 @@ Plugin Name: Timber
4
  Description: The WordPress Timber Library allows you to write themes using the power Twig templates.
5
  Plugin URI: http://timber.upstatement.com
6
  Author: Jared Novack + Upstatement
7
- Version: 1.1.12
8
  Author URI: http://upstatement.com/
9
  */
10
  // we look for Composer files first in the plugins dir.
4
  Description: The WordPress Timber Library allows you to write themes using the power Twig templates.
5
  Plugin URI: http://timber.upstatement.com
6
  Author: Jared Novack + Upstatement
7
+ Version: 1.2.0
8
  Author URI: http://upstatement.com/
9
  */
10
  // we look for Composer files first in the plugins dir.
vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer' . '/autoload_real.php';
6
 
7
- return ComposerAutoloaderInit22f8a762fefc8182d5b4a7cd2473d3dc::getLoader();
4
 
5
  require_once __DIR__ . '/composer' . '/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInitbae1da8343e649dd75a784392ec6d01a::getLoader();
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInit22f8a762fefc8182d5b4a7cd2473d3dc
6
  {
7
  private static $loader;
8
 
@@ -19,9 +19,9 @@ class ComposerAutoloaderInit22f8a762fefc8182d5b4a7cd2473d3dc
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInit22f8a762fefc8182d5b4a7cd2473d3dc', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInit22f8a762fefc8182d5b4a7cd2473d3dc', 'loadClassLoader'));
25
 
26
  $map = require __DIR__ . '/autoload_namespaces.php';
27
  foreach ($map as $namespace => $path) {
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInitbae1da8343e649dd75a784392ec6d01a
6
  {
7
  private static $loader;
8
 
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInitbae1da8343e649dd75a784392ec6d01a', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInitbae1da8343e649dd75a784392ec6d01a', 'loadClassLoader'));
25
 
26
  $map = require __DIR__ . '/autoload_namespaces.php';
27
  foreach ($map as $namespace => $path) {