Timber - Version 1.9.1

Version Description

Changes for Theme Developers - You can now pass params to {{ user.avatar }} such as {{ user.avatar({size: 128}) }} #1730 (thanks @palmiak)

Fixes and improvements - Fix for URLHelper::is_external for URLs without protocol #1924 (thanks @hacknug)

Download this release

Release Info

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

Code changes from version 1.9.0 to 1.9.1

lib/Image.php CHANGED
@@ -94,7 +94,7 @@ class Image extends Post implements CoreInterface {
94
  * //Or send it a URL to an image
95
  * $myImage = new TimberImage('http://google.com/logo.jpg');
96
  * ```
97
- * @param int|string $iid
98
  */
99
  public function __construct( $iid ) {
100
  $this->init($iid);
@@ -214,7 +214,7 @@ class Image extends Post implements CoreInterface {
214
 
215
  /**
216
  * @internal
217
- * @param int $iid
218
  */
219
  public function init( $iid = false ) {
220
  //Make sure we actually have something to work with
@@ -470,14 +470,14 @@ class Image extends Post implements CoreInterface {
470
  return wp_get_attachment_image_srcset($this->ID, $size);
471
  }
472
  }
473
-
474
  /**
475
  * @param string $size a size known to WordPress (like "medium")
476
  * @api
477
  * @example
478
  * ```twig
479
  * <h1>{{ post.title }}</h1>
480
- * <img src="{{ post.thumbnail.src }}" srcset="{{ post.thumnbail.srcset }}" sizes="{{ post.thumbnail.sizes }}" />
481
  * ```
482
  * ```html
483
  * <img src="http://example.org/wp-content/uploads/2018/10/pic.jpg" srcset="http://example.org/wp-content/uploads/2018/10/pic.jpg 1024w, http://example.org/wp-content/uploads/2018/10/pic-600x338.jpg 600w, http://example.org/wp-content/uploads/2018/10/pic-300x169.jpg 300w sizes="(max-width: 1024px) 100vw, 102" />
@@ -489,7 +489,7 @@ class Image extends Post implements CoreInterface {
489
  return wp_get_attachment_image_sizes($this->ID, $size);
490
  }
491
  }
492
-
493
  /**
494
  * @internal
495
  * @return bool true if media is an image
94
  * //Or send it a URL to an image
95
  * $myImage = new TimberImage('http://google.com/logo.jpg');
96
  * ```
97
+ * @param bool|int|string $iid
98
  */
99
  public function __construct( $iid ) {
100
  $this->init($iid);
214
 
215
  /**
216
  * @internal
217
+ * @param int|bool|string $iid
218
  */
219
  public function init( $iid = false ) {
220
  //Make sure we actually have something to work with
470
  return wp_get_attachment_image_srcset($this->ID, $size);
471
  }
472
  }
473
+
474
  /**
475
  * @param string $size a size known to WordPress (like "medium")
476
  * @api
477
  * @example
478
  * ```twig
479
  * <h1>{{ post.title }}</h1>
480
+ * <img src="{{ post.thumbnail.src }}" srcset="{{ post.thumnbail.srcset }}" sizes="{{ post.thumbnail.img_sizes }}" />
481
  * ```
482
  * ```html
483
  * <img src="http://example.org/wp-content/uploads/2018/10/pic.jpg" srcset="http://example.org/wp-content/uploads/2018/10/pic.jpg 1024w, http://example.org/wp-content/uploads/2018/10/pic-600x338.jpg 600w, http://example.org/wp-content/uploads/2018/10/pic-300x169.jpg 300w sizes="(max-width: 1024px) 100vw, 102" />
489
  return wp_get_attachment_image_sizes($this->ID, $size);
490
  }
491
  }
492
+
493
  /**
494
  * @internal
495
  * @return bool true if media is an image
lib/ImageHelper.php CHANGED
@@ -206,7 +206,7 @@ class ImageHelper {
206
  /**
207
  * Generates a new image by converting the source into WEBP if supported by the server
208
  *
209
- * @param string $src a url or path to the image (http://example.org/wp-content/uploads/2014/image.webp)
210
  * or (/wp-content/uploads/2014/image.jpg)
211
  * If webp is not supported, a jpeg image will be generated
212
  * @param int $quality ranges from 0 (worst quality, smaller file) to 100 (best quality, biggest file)
@@ -327,7 +327,7 @@ class ImageHelper {
327
  * @return string
328
  */
329
  public static function get_server_location( $url ) {
330
- // if we're already an absolute dir, just return
331
  if ( 0 === strpos($url, ABSPATH) ) {
332
  return $url;
333
  }
@@ -456,10 +456,24 @@ class ImageHelper {
456
  return $tmp;
457
  }
458
 
 
 
 
 
 
 
 
459
  protected static function is_in_theme_dir( $path ) {
460
- $root = realpath(get_stylesheet_directory_uri());
461
- if ( 0 === strpos($path, $root) ) {
 
 
 
 
 
462
  return true;
 
 
463
  }
464
  }
465
 
206
  /**
207
  * Generates a new image by converting the source into WEBP if supported by the server
208
  *
209
+ * @param string $src a url or path to the image (http://example.org/wp-content/uploads/2014/image.webp)
210
  * or (/wp-content/uploads/2014/image.jpg)
211
  * If webp is not supported, a jpeg image will be generated
212
  * @param int $quality ranges from 0 (worst quality, smaller file) to 100 (best quality, biggest file)
327
  * @return string
328
  */
329
  public static function get_server_location( $url ) {
330
+ // if we're already an absolute dir, just return.
331
  if ( 0 === strpos($url, ABSPATH) ) {
332
  return $url;
333
  }
456
  return $tmp;
457
  }
458
 
459
+ /**
460
+ * Checks if uploaded image is located in theme.
461
+ *
462
+ * @param string $path image path.
463
+ * @return bool If the image is located in the theme directory it returns true.
464
+ * If not or $path doesn't exits it returns false.
465
+ */
466
  protected static function is_in_theme_dir( $path ) {
467
+ $root = realpath(get_stylesheet_directory());
468
+
469
+ if ( false === $root ) {
470
+ return false;
471
+ }
472
+
473
+ if ( 0 === strpos($path, (string) $root) ) {
474
  return true;
475
+ } else {
476
+ return false;
477
  }
478
  }
479
 
lib/Integrations/CoAuthorsPlusUser.php CHANGED
@@ -34,6 +34,9 @@ class CoAuthorsPlusUser extends \Timber\User {
34
  $avatar_url = get_avatar_url($coauthor->user_email);
35
  }
36
  if ( $avatar_url ) {
 
 
 
37
  $this->avatar = new \Timber\Image($avatar_url);
38
  }
39
  }
34
  $avatar_url = get_avatar_url($coauthor->user_email);
35
  }
36
  if ( $avatar_url ) {
37
+ /**
38
+ * @property string url to use for avatar image
39
+ */
40
  $this->avatar = new \Timber\Image($avatar_url);
41
  }
42
  }
lib/Term.php CHANGED
@@ -37,7 +37,7 @@ use Timber\URLHelper;
37
  * <h3>Teams</h3>
38
  * <ul>
39
  * <li>St. Louis Cardinals - Winner of 11 World Series</li>
40
- * <li>New England Patriots - Winner of 4 Super Bowls</li>
41
  * </ul>
42
  * ```
43
  */
37
  * <h3>Teams</h3>
38
  * <ul>
39
  * <li>St. Louis Cardinals - Winner of 11 World Series</li>
40
+ * <li>New England Patriots - Winner of 6 Super Bowls</li>
41
  * </ul>
42
  * ```
43
  */
lib/Timber.php CHANGED
@@ -35,7 +35,7 @@ use Timber\Loader;
35
  */
36
  class Timber {
37
 
38
- public static $version = '1.9.0';
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.9.1';
39
  public static $locations;
40
  public static $dirname = 'views';
41
  public static $twig_cache = false;
lib/URLHelper.php CHANGED
@@ -19,30 +19,30 @@ class URLHelper {
19
  return $pageURL;
20
  }
21
 
22
- /**
23
- *
24
- * Get url scheme
25
- * @return string
26
- */
27
  public static function get_scheme() {
28
  return isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http';
29
- }
30
-
31
- /**
32
- *
33
- * Check to see if the URL begins with the string in question
34
- * Because it's a URL we don't care about protocol (HTTP vs HTTPS)
35
- * Or case (so it's cAsE iNsEnSeTiVe)
36
- * @return boolean
37
- */
38
- public static function starts_with( $haystack, $starts_with ) {
39
- $haystack = str_replace('https', 'http', strtolower($haystack));
40
- $starts_with = str_replace('https', 'http', strtolower($starts_with));
41
- if ( 0 === strpos($haystack, $starts_with) ) {
42
- return true;
43
- }
44
- return false;
45
- }
46
 
47
 
48
  /**
@@ -182,7 +182,7 @@ class URLHelper {
182
  $home_url = get_home_url();
183
  $home_url = apply_filters('timber/URLHelper/get_content_subdir/home_url', $home_url);
184
  return str_replace($home_url, '', WP_CONTENT_URL);
185
- }
186
 
187
  /**
188
  *
@@ -313,18 +313,19 @@ class URLHelper {
313
 
314
  return $is_content_url || $is_upload_url;
315
  }
316
-
317
  /**
 
 
318
  *
319
- *
320
- * @param string $url
321
  * @return bool true if $path is an external url, false if relative or local.
322
  * true if it's a subdomain (http://cdn.example.org = true)
323
  */
324
  public static function is_external( $url ) {
325
- $has_http = strstr(strtolower($url), 'http');
326
  $on_domain = strstr($url, self::get_host());
327
- if ( $has_http && !$on_domain ) {
328
  return true;
329
  }
330
  return false;
@@ -349,7 +350,7 @@ class URLHelper {
349
  * @author jarednova
350
  * @param string $haystack ex: http://example.org/wp-content/uploads/dog.jpg
351
  * @param string $needle ex: http://example.org/wp-content
352
- * @return string
353
  */
354
  public static function remove_url_component( $haystack, $needle ) {
355
  $haystack = str_replace($needle, '', $haystack);
@@ -387,10 +388,10 @@ class URLHelper {
387
  if ( !$link_parts ) {
388
  return $link;
389
  }
390
-
391
  if ( isset($link_parts['path']) && $link_parts['path'] != '/' ) {
392
  $new_path = user_trailingslashit($link_parts['path']);
393
-
394
  if ( $new_path != $link_parts['path'] ) {
395
  $link = str_replace($link_parts['path'], $new_path, $link);
396
  }
19
  return $pageURL;
20
  }
21
 
22
+ /**
23
+ *
24
+ * Get url scheme
25
+ * @return string
26
+ */
27
  public static function get_scheme() {
28
  return isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http';
29
+ }
30
+
31
+ /**
32
+ *
33
+ * Check to see if the URL begins with the string in question
34
+ * Because it's a URL we don't care about protocol (HTTP vs HTTPS)
35
+ * Or case (so it's cAsE iNsEnSeTiVe)
36
+ * @return boolean
37
+ */
38
+ public static function starts_with( $haystack, $starts_with ) {
39
+ $haystack = str_replace('https', 'http', strtolower($haystack));
40
+ $starts_with = str_replace('https', 'http', strtolower($starts_with));
41
+ if ( 0 === strpos($haystack, $starts_with) ) {
42
+ return true;
43
+ }
44
+ return false;
45
+ }
46
 
47
 
48
  /**
182
  $home_url = get_home_url();
183
  $home_url = apply_filters('timber/URLHelper/get_content_subdir/home_url', $home_url);
184
  return str_replace($home_url, '', WP_CONTENT_URL);
185
+ }
186
 
187
  /**
188
  *
313
 
314
  return $is_content_url || $is_upload_url;
315
  }
316
+
317
  /**
318
+ * Checks if URL is external or internal.
319
+ * Works with domains, subdomains and protocol relative domains.
320
  *
321
+ * @param string $url Url.
 
322
  * @return bool true if $path is an external url, false if relative or local.
323
  * true if it's a subdomain (http://cdn.example.org = true)
324
  */
325
  public static function is_external( $url ) {
326
+ $has_http = strstr(strtolower($url), 'http') || strstr(strtolower($url), '//');
327
  $on_domain = strstr($url, self::get_host());
328
+ if ( $has_http && ! $on_domain ) {
329
  return true;
330
  }
331
  return false;
350
  * @author jarednova
351
  * @param string $haystack ex: http://example.org/wp-content/uploads/dog.jpg
352
  * @param string $needle ex: http://example.org/wp-content
353
+ * @return string
354
  */
355
  public static function remove_url_component( $haystack, $needle ) {
356
  $haystack = str_replace($needle, '', $haystack);
388
  if ( !$link_parts ) {
389
  return $link;
390
  }
391
+
392
  if ( isset($link_parts['path']) && $link_parts['path'] != '/' ) {
393
  $new_path = user_trailingslashit($link_parts['path']);
394
+
395
  if ( $new_path != $link_parts['path'] ) {
396
  $link = str_replace($link_parts['path'], $new_path, $link);
397
  }
lib/User.php CHANGED
@@ -35,16 +35,16 @@ class User extends Core implements CoreInterface {
35
 
36
  /**
37
  * @api
38
- * @var string The description from WordPress
39
  */
40
- public $description;
41
- public $display_name;
42
 
43
  /**
44
  * @api
45
- * @var string|Image The URL of the author's avatar
46
  */
47
- public $avatar;
 
48
 
49
  /**
50
  * @api
@@ -94,14 +94,7 @@ class User extends Core implements CoreInterface {
94
  * @return string a fallback for TimberUser::name()
95
  */
96
  public function __toString() {
97
- $name = $this->name();
98
- if ( strlen($name) ) {
99
- return $name;
100
- }
101
- if ( strlen($this->name) ) {
102
- return $this->name;
103
- }
104
- return '';
105
  }
106
 
107
  /**
@@ -159,7 +152,6 @@ class User extends Core implements CoreInterface {
159
  unset($this->user_pass);
160
  $this->id = $this->ID;
161
  $this->name = $this->name();
162
- $this->avatar = new Image(get_avatar_url($this->id));
163
  $custom = $this->get_custom();
164
  $this->import($custom);
165
  }
@@ -337,4 +329,28 @@ class User extends Core implements CoreInterface {
337
  public function can( $capability ) {
338
  return user_can($this->ID, $capability);
339
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
340
  }
35
 
36
  /**
37
  * @api
38
+ * @var string A URL to an avatar that overrides anything from Gravatar, etc.
39
  */
40
+ public $avatar_override;
 
41
 
42
  /**
43
  * @api
44
+ * @var string The description from WordPress
45
  */
46
+ public $description;
47
+ public $display_name;
48
 
49
  /**
50
  * @api
94
  * @return string a fallback for TimberUser::name()
95
  */
96
  public function __toString() {
97
+ return $this->name();
 
 
 
 
 
 
 
98
  }
99
 
100
  /**
152
  unset($this->user_pass);
153
  $this->id = $this->ID;
154
  $this->name = $this->name();
 
155
  $custom = $this->get_custom();
156
  $this->import($custom);
157
  }
329
  public function can( $capability ) {
330
  return user_can($this->ID, $capability);
331
  }
332
+
333
+ /**
334
+ * Gets a user’s avatar URL.
335
+ *
336
+ * @api
337
+ * @since 1.9.1
338
+ * @example
339
+ * Get a user avatar with a width and height of 150px:
340
+ *
341
+ * ```twig
342
+ * <img src="{{ post.author.avatar({ size: 150 }) }}">
343
+ * ```
344
+ *
345
+ * @param null|array $args Parameters for
346
+ * [`get_avatar_url()`](https://developer.wordpress.org/reference/functions/get_avatar_url/).
347
+ * @return string|\Timber\Image The avatar URL.
348
+ */
349
+ public function avatar( $args = null ) {
350
+ if ( $this->avatar_override ) {
351
+ return $this->avatar_override;
352
+ }
353
+
354
+ return new Image( get_avatar_url( $this->id, $args ) );
355
+ }
356
  }
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: jarednova, connorjburton, lggorman
3
  Tags: template engine, templates, twig
4
  Requires at least: 4.7.9
5
  Tested up to: 5.0.3
6
- Stable tag: 1.9.0
7
  Requires PHP: 5.6
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -36,6 +36,14 @@ _Twig is the template language powering Timber; if you need a little background
36
  **Changes for Theme Developers**
37
  - Please add bullet points here with your PR. The heading for this section will get the correct version number once released.
38
 
 
 
 
 
 
 
 
 
39
  = 1.9.0 =
40
  Timber now requires PHP 5.6 or greater. While Timber may work on PHP 5.5 and older versions; support will no longer be maintained in future versions.
41
 
3
  Tags: template engine, templates, twig
4
  Requires at least: 4.7.9
5
  Tested up to: 5.0.3
6
+ Stable tag: 1.9.1
7
  Requires PHP: 5.6
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
36
  **Changes for Theme Developers**
37
  - Please add bullet points here with your PR. The heading for this section will get the correct version number once released.
38
 
39
+ = 1.9.1 =
40
+
41
+ **Changes for Theme Developers**
42
+ - You can now pass params to `{{ user.avatar }}` such as `{{ user.avatar({size: 128}) }}` #1730 (thanks @palmiak)
43
+
44
+ **Fixes and improvements**
45
+ - Fix for URLHelper::is_external for URLs without protocol #1924 (thanks @hacknug)
46
+
47
  = 1.9.0 =
48
  Timber now requires PHP 5.6 or greater. While Timber may work on PHP 5.5 and older versions; support will no longer be maintained in future versions.
49
 
timber.php CHANGED
@@ -4,7 +4,7 @@ Plugin Name: Timber
4
  Description: The WordPress Timber Library allows you to write themes using the power of Twig templates.
5
  Plugin URI: http://timber.upstatement.com
6
  Author: Jared Novack + Upstatement
7
- Version: 1.9.0
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 of Twig templates.
5
  Plugin URI: http://timber.upstatement.com
6
  Author: Jared Novack + Upstatement
7
+ Version: 1.9.1
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 ComposerAutoloaderInit47041c9f634303a394d98c7e6b876c3d::getLoader();
4
 
5
  require_once __DIR__ . '/composer' . '/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInit299ac90e7e60969457d3d264c8b850ff::getLoader();
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInit47041c9f634303a394d98c7e6b876c3d
6
  {
7
  private static $loader;
8
 
@@ -19,9 +19,9 @@ class ComposerAutoloaderInit47041c9f634303a394d98c7e6b876c3d
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInit47041c9f634303a394d98c7e6b876c3d', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInit47041c9f634303a394d98c7e6b876c3d', '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 ComposerAutoloaderInit299ac90e7e60969457d3d264c8b850ff
6
  {
7
  private static $loader;
8
 
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInit299ac90e7e60969457d3d264c8b850ff', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInit299ac90e7e60969457d3d264c8b850ff', 'loadClassLoader'));
25
 
26
  $map = require __DIR__ . '/autoload_namespaces.php';
27
  foreach ($map as $namespace => $path) {