Version Description
- Fixed a potentail XSS security issue
- Fixed handling of images stored on S3
Download this release
Release Info
Developer | jarednova |
Plugin | Timber |
Version | 1.2.3 |
Comparing to | |
See all releases |
Code changes from version 1.2.2 to 1.2.3
- README.md +2 -4
- lib/Image.php +5 -20
- lib/Pagination.php +24 -13
- lib/PostCollection.php +1 -1
- lib/PostGetter.php +8 -8
- lib/PostQuery.php +1 -1
- lib/Timber.php +1 -1
- readme.txt +6 -2
- timber.php +1 -1
- vendor/autoload.php +1 -1
- vendor/composer/autoload_real.php +3 -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 |
-
|
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 |
-
|
|
|
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'] =
|
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(
|
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(
|
194 |
-
$format_query = isset(
|
195 |
|
196 |
-
wp_parse_str(
|
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(
|
201 |
}
|
202 |
|
203 |
-
$url_parts = explode(
|
204 |
-
|
|
|
205 |
// Find the query args of the requested URL.
|
206 |
$url_query_args = array();
|
207 |
-
wp_parse_str(
|
208 |
|
209 |
-
$args['add_args'] = array_merge(
|
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
|
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(
|
107 |
$post_class_use = '\Timber\Post';
|
108 |
|
109 |
-
if ( is_array($post_class) )
|
110 |
-
if ( isset(
|
111 |
$post_class_use = $post_class[$post_type];
|
112 |
} else {
|
113 |
-
Helper::error_log($post_type
|
114 |
}
|
115 |
} elseif ( is_string($post_class) ) {
|
116 |
$post_class_use = $post_class;
|
117 |
} else {
|
118 |
-
Helper::error_log('Unexpeted value for PostClass: '
|
119 |
}
|
120 |
|
121 |
-
if ( !class_exists(
|
122 |
-
Helper::error_log('Class '
|
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.
|
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.
|
6 |
-
Tested up to: 4.7.
|
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.
|
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
|
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
|
6 |
{
|
7 |
private static $loader;
|
8 |
|
@@ -19,9 +19,9 @@ class ComposerAutoloaderInit224e0edbae26e0da9078296bff38b54c
|
|
19 |
return self::$loader;
|
20 |
}
|
21 |
|
22 |
-
spl_autoload_register(array('
|
23 |
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
24 |
-
spl_autoload_unregister(array('
|
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) {
|