Timber - Version 1.2.3

Version Description

  • Fixed a potentail XSS security issue
  • Fixed handling of images stored on S3
Download this release

Release Info

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

Code changes from version 1.2.2 to 1.2.3

README.md CHANGED
@@ -10,7 +10,6 @@ By Jared Novack (<a href="https://twitter.com/jarednova">@JaredNova</a>) and <a
10
  [![Scrutinizer Code Quality](https://img.shields.io/scrutinizer/g/timber/timber.svg?style=flat-square)](https://scrutinizer-ci.com/g/timber/timber/?branch=master)
11
  [![Latest Stable Version](https://img.shields.io/packagist/v/timber/timber.svg?style=flat-square)](https://packagist.org/packages/timber/timber)
12
  [![WordPress Download Count](https://img.shields.io/wordpress/plugin/dt/timber-library.svg?style=flat-square)](https://wordpress.org/plugins/timber-library/)
13
- [![HHVM Status](https://img.shields.io/hhvm/timber/timber.svg?style=flat-square)](http://hhvm.h4cc.de/package/timber/timber)
14
  [![Join the chat at https://gitter.im/timber/timber](https://img.shields.io/gitter/room/timber/timber.svg?style=flat-square)](https://gitter.im/timber/timber?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
15
 
16
 
@@ -109,13 +108,12 @@ Read the [contributor guidelines](https://github.com/timber/timber/wiki#contribu
109
 
110
  Documentation for Timber classes and functions is [auto generated](https://github.com/jarednova/PHP-Markdown-Documentation-Generator), so any changes to the object reference docs should be made by editing the function's DocBlock. To make a change to one of the guides, edit the relevant file in the `docs` directory.
111
 
112
- To publish docs:
 
113
  1. `composer install` if not already run
114
  2. Clone the [timber/slate](https://github.com/timber/slate) repo at the same directory level as Timber
115
  3. From the root of the slate directory, run these commands:
116
  ```bash
117
- gem install bundler
118
- bundle install
119
  sh publish-docs.sh
120
  ```
121
 
10
  [![Scrutinizer Code Quality](https://img.shields.io/scrutinizer/g/timber/timber.svg?style=flat-square)](https://scrutinizer-ci.com/g/timber/timber/?branch=master)
11
  [![Latest Stable Version](https://img.shields.io/packagist/v/timber/timber.svg?style=flat-square)](https://packagist.org/packages/timber/timber)
12
  [![WordPress Download Count](https://img.shields.io/wordpress/plugin/dt/timber-library.svg?style=flat-square)](https://wordpress.org/plugins/timber-library/)
 
13
  [![Join the chat at https://gitter.im/timber/timber](https://img.shields.io/gitter/room/timber/timber.svg?style=flat-square)](https://gitter.im/timber/timber?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
14
 
15
 
108
 
109
  Documentation for Timber classes and functions is [auto generated](https://github.com/jarednova/PHP-Markdown-Documentation-Generator), so any changes to the object reference docs should be made by editing the function's DocBlock. To make a change to one of the guides, edit the relevant file in the `docs` directory.
110
 
111
+ ####To publish docs:
112
+
113
  1. `composer install` if not already run
114
  2. Clone the [timber/slate](https://github.com/timber/slate) repo at the same directory level as Timber
115
  3. From the root of the slate directory, run these commands:
116
  ```bash
 
 
117
  sh publish-docs.sh
118
  ```
119
 
lib/Image.php CHANGED
@@ -428,8 +428,8 @@ class Image extends Post implements CoreInterface {
428
  * @api
429
  * @example
430
  * ```twig
431
- * <h1>{{post.title}}</h1>
432
- * <img src="{{post.thumbnail.src}}" />
433
  * ```
434
  * ```html
435
  * <img src="http://example.org/wp-content/uploads/2015/08/pic.jpg" />
@@ -441,25 +441,10 @@ class Image extends Post implements CoreInterface {
441
  return $this->_maybe_secure_url($this->abs_url);
442
  }
443
 
444
- if ( $size && is_string($size) && isset($this->sizes[$size]) ) {
445
- $image = image_downsize($this->ID, $size);
446
- return $this->_maybe_secure_url(reset($image));
447
- }
448
-
449
- if ( !isset($this->file) && isset($this->_wp_attached_file) ) {
450
- $this->file = $this->_wp_attached_file;
451
- }
452
-
453
- if ( !isset($this->file) ) {
454
- return false;
455
- }
456
-
457
- $dir = self::wp_upload_dir();
458
- $base = $dir['baseurl'];
459
-
460
- $src = trailingslashit($this->_maybe_secure_url($base)).$this->file;
461
  $src = apply_filters('timber/image/src', $src, $this->ID);
462
- return apply_filters('timber_image_src', $src, $this->ID);
 
463
  }
464
 
465
  /**
428
  * @api
429
  * @example
430
  * ```twig
431
+ * <h1>{{ post.title }}</h1>
432
+ * <img src="{{ post.thumbnail.src }}" />
433
  * ```
434
  * ```html
435
  * <img src="http://example.org/wp-content/uploads/2015/08/pic.jpg" />
441
  return $this->_maybe_secure_url($this->abs_url);
442
  }
443
 
444
+ $src = wp_get_attachment_image_src($this->ID, $size)[0];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
445
  $src = apply_filters('timber/image/src', $src, $this->ID);
446
+ $src = apply_filters('timber_image_src', $src, $this->ID);
447
+ return $src;
448
  }
449
 
450
  /**
lib/Pagination.php CHANGED
@@ -55,7 +55,7 @@ class Pagination {
55
  } else {
56
  $big = 999999999;
57
  $pagination_link = get_pagenum_link($big, false);
58
- $args['base'] = str_replace( 'paged='.$big, '', $pagination_link );
59
  $args['format'] = '?paged=%#%';
60
  }
61
 
@@ -149,11 +149,11 @@ class Pagination {
149
  } else {
150
  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']) ) {
151
 
152
- $link = str_replace('%_%', 1 == $n ? '' : $args['format'], $args['base'] );
153
  $link = str_replace('%#%', $n, $link);
154
 
155
  // we first follow the user trailing slash configuration
156
- $link = URLHelper::user_trailingslashit( $link );
157
 
158
  // then we add all required querystring parameters
159
  if ( $args['add_args'] ) {
@@ -185,31 +185,42 @@ class Pagination {
185
 
186
  return $page_links;
187
  }
 
 
 
 
 
 
 
188
 
189
  protected static function sanitize_args( $args ) {
190
 
191
  $format_args = array();
192
 
193
- $format = explode( '?', str_replace( '%_%', $args['format'], $args['base'] ) );
194
- $format_query = isset( $format[1] ) ? $format[1] : '';
195
 
196
- wp_parse_str( $format_query, $format_args );
197
 
198
  // Remove the format argument from the array of query arguments, to avoid overwriting custom format.
199
  foreach ( $format_args as $format_arg => $format_arg_value ) {
200
- unset( $args['add_args'][ $format_arg ] );
201
  }
202
 
203
- $url_parts = explode( '?', $args['base']);
204
- if ( isset( $url_parts[1] ) ) {
 
205
  // Find the query args of the requested URL.
206
  $url_query_args = array();
207
- wp_parse_str( $url_parts[1], $url_query_args );
208
 
209
- $args['add_args'] = array_merge( $args['add_args'], urlencode_deep( $url_query_args ));
210
- $args['base'] = $url_parts[0] . '%_%';
 
 
 
 
211
  }
212
-
213
  return $args;
214
  }
215
  }
55
  } else {
56
  $big = 999999999;
57
  $pagination_link = get_pagenum_link($big, false);
58
+ $args['base'] = str_replace('paged='.$big, '', $pagination_link);
59
  $args['format'] = '?paged=%#%';
60
  }
61
 
149
  } else {
150
  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']) ) {
151
 
152
+ $link = str_replace('%_%', 1 == $n ? '' : $args['format'], $args['base']);
153
  $link = str_replace('%#%', $n, $link);
154
 
155
  // we first follow the user trailing slash configuration
156
+ $link = URLHelper::user_trailingslashit($link);
157
 
158
  // then we add all required querystring parameters
159
  if ( $args['add_args'] ) {
185
 
186
  return $page_links;
187
  }
188
+
189
+ protected static function sanitize_url_params( $add_args ) {
190
+ foreach ( $add_args as $key => $value ) {
191
+ $add_args[$key] = urlencode_deep($value);
192
+ }
193
+ return $add_args;
194
+ }
195
 
196
  protected static function sanitize_args( $args ) {
197
 
198
  $format_args = array();
199
 
200
+ $format = explode('?', str_replace('%_%', $args['format'], $args['base']));
201
+ $format_query = isset($format[1]) ? $format[1] : '';
202
 
203
+ wp_parse_str($format_query, $format_args);
204
 
205
  // Remove the format argument from the array of query arguments, to avoid overwriting custom format.
206
  foreach ( $format_args as $format_arg => $format_arg_value ) {
207
+ unset($args['add_args'][urlencode_deep($format_arg)]);
208
  }
209
 
210
+ $url_parts = explode('?', $args['base']);
211
+
212
+ if ( isset($url_parts[1]) ) {
213
  // Find the query args of the requested URL.
214
  $url_query_args = array();
215
+ wp_parse_str($url_parts[1], $url_query_args);
216
 
217
+ $args['add_args'] = array_merge($args['add_args'], urlencode_deep($url_query_args));
218
+ $args['base'] = $url_parts[0].'%_%';
219
+ }
220
+
221
+ if ( isset($args['add_args']) ) {
222
+ $args['add_args'] = self::sanitize_url_params($args['add_args']);
223
  }
 
224
  return $args;
225
  }
226
  }
lib/PostCollection.php CHANGED
@@ -15,7 +15,7 @@ class PostCollection extends \ArrayObject {
15
  parent::__construct($returned_posts, $flags = 0, 'Timber\PostsIterator');
16
  }
17
 
18
- protected static function init($posts, $post_class) {
19
  $returned_posts = array();
20
  if ( is_null($posts) ) {
21
  $posts = array();
15
  parent::__construct($returned_posts, $flags = 0, 'Timber\PostsIterator');
16
  }
17
 
18
+ protected static function init( $posts, $post_class ) {
19
  $returned_posts = array();
20
  if ( is_null($posts) ) {
21
  $posts = array();
lib/PostGetter.php CHANGED
@@ -15,7 +15,7 @@ class PostGetter {
15
  public static function get_post( $query = false, $PostClass = '\Timber\Post' ) {
16
  // if a post id is passed, grab the post directly
17
  if ( is_numeric($query) ) {
18
- $post_type = get_post_type($query);
19
  $PostClass = PostGetter::get_post_class($post_type, $PostClass);
20
  $post = new $PostClass($query);
21
  // get the latest revision if we're dealing with a preview
@@ -103,23 +103,23 @@ class PostGetter {
103
  * @return string
104
  */
105
  public static function get_post_class( $post_type, $post_class = '\Timber\Post' ) {
106
- $post_class = apply_filters( 'Timber\PostClassMap', $post_class );
107
  $post_class_use = '\Timber\Post';
108
 
109
- if ( is_array($post_class) ) {
110
- if ( isset( $post_class[$post_type]) ) {
111
  $post_class_use = $post_class[$post_type];
112
  } else {
113
- Helper::error_log($post_type . ' not found in ' . print_r($post_class, true));
114
  }
115
  } elseif ( is_string($post_class) ) {
116
  $post_class_use = $post_class;
117
  } else {
118
- Helper::error_log('Unexpeted value for PostClass: ' . print_r( $post_class, true));
119
  }
120
 
121
- if ( !class_exists( $post_class_use ) || !( is_subclass_of($post_class_use, '\Timber\Post') || is_a($post_class_use, '\Timber\Post', true) ) ) {
122
- Helper::error_log('Class ' . $post_class_use . ' either does not exist or implement \Timber\Post');
123
  }
124
 
125
  return $post_class_use;
15
  public static function get_post( $query = false, $PostClass = '\Timber\Post' ) {
16
  // if a post id is passed, grab the post directly
17
  if ( is_numeric($query) ) {
18
+ $post_type = get_post_type($query);
19
  $PostClass = PostGetter::get_post_class($post_type, $PostClass);
20
  $post = new $PostClass($query);
21
  // get the latest revision if we're dealing with a preview
103
  * @return string
104
  */
105
  public static function get_post_class( $post_type, $post_class = '\Timber\Post' ) {
106
+ $post_class = apply_filters('Timber\PostClassMap', $post_class);
107
  $post_class_use = '\Timber\Post';
108
 
109
+ if ( is_array($post_class) ) {
110
+ if ( isset($post_class[$post_type]) ) {
111
  $post_class_use = $post_class[$post_type];
112
  } else {
113
+ Helper::error_log($post_type.' not found in '.print_r($post_class, true));
114
  }
115
  } elseif ( is_string($post_class) ) {
116
  $post_class_use = $post_class;
117
  } else {
118
+ Helper::error_log('Unexpeted value for PostClass: '.print_r($post_class, true));
119
  }
120
 
121
+ if ( !class_exists($post_class_use) || !(is_subclass_of($post_class_use, '\Timber\Post') || is_a($post_class_use, '\Timber\Post', true)) ) {
122
+ Helper::error_log('Class '.$post_class_use.' either does not exist or implement \Timber\Post');
123
  }
124
 
125
  return $post_class_use;
lib/PostQuery.php CHANGED
@@ -47,7 +47,7 @@ class PostQuery extends PostCollection {
47
  * @return Timber\Pagination object
48
  */
49
  public function pagination( $prefs = array() ) {
50
- if ( !$this->pagination && is_a($this->queryIterator, 'Timber\QueryIterator')) {
51
  $this->pagination = $this->queryIterator->get_pagination($prefs, $this->get_query());
52
  }
53
  return $this->pagination;
47
  * @return Timber\Pagination object
48
  */
49
  public function pagination( $prefs = array() ) {
50
+ if ( !$this->pagination && is_a($this->queryIterator, 'Timber\QueryIterator') ) {
51
  $this->pagination = $this->queryIterator->get_pagination($prefs, $this->get_query());
52
  }
53
  return $this->pagination;
lib/Timber.php CHANGED
@@ -35,7 +35,7 @@ use Timber\Loader;
35
  */
36
  class Timber {
37
 
38
- public static $version = '1.2.2';
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.3';
39
  public static $locations;
40
  public static $dirname = 'views';
41
  public static $twig_cache = false;
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: jarednova, connorjburton, lggorman
3
  Tags: template engine, templates, twig
4
  Requires at least: 3.7
5
- Stable tag: 1.2.2
6
- Tested up to: 4.7.1
7
  PHP version: 5.3.0 or greater
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -41,6 +41,10 @@ Timber is great for any WordPress developer who cares about writing good, mainta
41
 
42
  == Changelog ==
43
 
 
 
 
 
44
  = 1.2.2 =
45
  * A bunch of fixes to how images in themes are handled #1317 #1293 (@jarednova)
46
  * Fixed filter for avatar images in comments #1310 (@xavivars)
2
  Contributors: jarednova, connorjburton, lggorman
3
  Tags: template engine, templates, twig
4
  Requires at least: 3.7
5
+ Stable tag: 1.2.3
6
+ Tested up to: 4.7.2
7
  PHP version: 5.3.0 or greater
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
41
 
42
  == Changelog ==
43
 
44
+ = 1.2.3 =
45
+ * Fixed a potentail XSS security issue
46
+ * Fixed handling of images stored on S3
47
+
48
  = 1.2.2 =
49
  * A bunch of fixes to how images in themes are handled #1317 #1293 (@jarednova)
50
  * Fixed filter for avatar images in comments #1310 (@xavivars)
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.2.2
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.3
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 ComposerAutoloaderInit224e0edbae26e0da9078296bff38b54c::getLoader();
4
 
5
  require_once __DIR__ . '/composer' . '/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInit84cd2aa2b91dbce62f39c5742bc271e1::getLoader();
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInit224e0edbae26e0da9078296bff38b54c
6
  {
7
  private static $loader;
8
 
@@ -19,9 +19,9 @@ class ComposerAutoloaderInit224e0edbae26e0da9078296bff38b54c
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInit224e0edbae26e0da9078296bff38b54c', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInit224e0edbae26e0da9078296bff38b54c', '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 ComposerAutoloaderInit84cd2aa2b91dbce62f39c5742bc271e1
6
  {
7
  private static $loader;
8
 
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInit84cd2aa2b91dbce62f39c5742bc271e1', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInit84cd2aa2b91dbce62f39c5742bc271e1', 'loadClassLoader'));
25
 
26
  $map = require __DIR__ . '/autoload_namespaces.php';
27
  foreach ($map as $namespace => $path) {