Version Description
- Fixed some Twig deprecation (thanks @alexlrobertson)
- Support for {{img.src|retina}} filter (@jarednova)
Download this release
Release Info
Developer | jarednova |
Plugin | Timber |
Version | 0.20.8 |
Comparing to | |
See all releases |
Code changes from version 0.20.7 to 0.20.8
- functions/functions/cache/KeyGenerator.php +30 -0
- functions/functions/cache/TimberKeyGeneratorInterface.php +8 -0
- functions/functions/cache/WPObjectCacheAdapter.php +29 -0
- functions/functions/cache/loader.php +24 -0
- functions/functions/integrations/acf-timber.php +62 -0
- functions/functions/integrations/wpcli-timber.php +88 -0
- functions/functions/timber-admin.php +31 -0
- functions/functions/timber-archives.php +272 -0
- functions/functions/timber-comment.php +239 -0
- functions/functions/timber-core-interface.php +16 -0
- functions/functions/timber-core.php +109 -0
- functions/functions/timber-function-wrapper.php +70 -0
- functions/functions/timber-helper.php +684 -0
- functions/functions/timber-image-helper.php +613 -0
- functions/functions/timber-image-retina-helper.php +54 -0
- functions/functions/timber-image.php +309 -0
- functions/functions/timber-loader.php +410 -0
- functions/functions/timber-menu-item.php +234 -0
- functions/functions/timber-menu.php +174 -0
- functions/functions/timber-page.php +6 -0
- functions/functions/timber-post-getter.php +137 -0
- functions/functions/timber-post.php +1007 -0
- functions/functions/timber-posts-collection.php +97 -0
- functions/functions/timber-query-iterator.php +141 -0
- functions/functions/timber-routes.php +111 -0
- functions/functions/timber-site.php +149 -0
- functions/functions/timber-term-getter.php +182 -0
- functions/functions/timber-term.php +328 -0
- functions/functions/timber-theme.php +58 -0
- functions/functions/timber-twig.php +289 -0
- functions/functions/timber-url-helper.php +246 -0
- functions/functions/timber-user.php +193 -0
- functions/timber-helper.php +4 -4
- functions/timber-image-helper.php +342 -249
- functions/timber-image-retina-helper.php +54 -0
- functions/timber-image.php +23 -4
- functions/timber-twig.php +177 -160
- functions/timber-url-helper.php +13 -0
- readme.txt +5 -1
- timber.php +1 -1
- vendor/autoload.php +1 -1
- vendor/composer/autoload_real.php +4 -4
- vendor/vendor/autoload.php +1 -1
- vendor/vendor/composer/autoload_real.php +4 -4
functions/functions/cache/KeyGenerator.php
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Timber\Cache;
|
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 |
+
}
|
29 |
+
|
30 |
+
}
|
functions/functions/cache/TimberKeyGeneratorInterface.php
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace Timber\Cache;
|
4 |
+
|
5 |
+
interface TimberKeyGeneratorInterface
|
6 |
+
{
|
7 |
+
public function _get_cache_key();
|
8 |
+
}
|
functions/functions/cache/WPObjectCacheAdapter.php
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php namespace Timber\Cache;
|
2 |
+
|
3 |
+
use Asm89\Twig\CacheExtension\CacheProviderInterface;
|
4 |
+
use TimberLoader;
|
5 |
+
|
6 |
+
class WPObjectCacheAdapter implements CacheProviderInterface
|
7 |
+
{
|
8 |
+
|
9 |
+
private $cache_group;
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @var TimberLoader
|
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/functions/cache/loader.php
ADDED
@@ -0,0 +1,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 {
|
10 |
+
spl_autoload_register(array(new self, 'autoload'));
|
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/integrations/acf-timber.php
ADDED
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class ACFTimber {
|
4 |
+
|
5 |
+
function __construct() {
|
6 |
+
add_filter( 'timber_post_get_meta', array( $this, 'post_get_meta' ), 10, 2 );
|
7 |
+
add_filter( 'timber_post_get_meta_field', array( $this, 'post_get_meta_field' ), 10, 3 );
|
8 |
+
add_filter( 'timber_term_get_meta', array( $this, 'term_get_meta' ), 10, 3 );
|
9 |
+
add_filter( 'timber_term_get_meta_field', array( $this, 'term_get_meta_field' ), 10, 4 );
|
10 |
+
add_filter( 'timber_user_get_meta_field_pre', array( $this, 'user_get_meta_field' ), 10, 3 );
|
11 |
+
add_filter( 'timber_term_set_meta', array( $this, 'term_set_meta'), 10, 4 );
|
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, $term_id, $field_name, $term ) {
|
23 |
+
$searcher = $term->taxonomy . "_" . $term->ID;
|
24 |
+
return get_field( $field_name, $searcher );
|
25 |
+
}
|
26 |
+
|
27 |
+
function term_set_meta( $value, $field, $term_id, $term ) {
|
28 |
+
$searcher = $term->taxonomy . "_" . $term->ID;
|
29 |
+
update_field( $field, $value, $searcher );
|
30 |
+
return $value;
|
31 |
+
}
|
32 |
+
|
33 |
+
function term_get_meta( $fields, $term_id, $term ) {
|
34 |
+
$searcher = $term->taxonomy . "_" . $term->ID; // save to a specific category
|
35 |
+
$fds = get_fields( $searcher );
|
36 |
+
if ( is_array( $fds ) ) {
|
37 |
+
foreach ( $fds as $key => $value ) {
|
38 |
+
$key = preg_replace( '/_/', '', $key, 1 );
|
39 |
+
$key = str_replace( $searcher, '', $key );
|
40 |
+
$key = preg_replace( '/_/', '', $key, 1 );
|
41 |
+
$field = get_field( $key, $searcher );
|
42 |
+
$fields[$key] = $field;
|
43 |
+
}
|
44 |
+
$fields = array_merge( $fields, $fds );
|
45 |
+
}
|
46 |
+
return $fields;
|
47 |
+
}
|
48 |
+
|
49 |
+
function user_get_meta( $fields, $user_id ) {
|
50 |
+
return $fields;
|
51 |
+
}
|
52 |
+
|
53 |
+
function user_get_meta_field( $value, $uid, $field ) {
|
54 |
+
return get_field( $field, 'user_' . $uid );
|
55 |
+
}
|
56 |
+
}
|
57 |
+
|
58 |
+
add_action( 'init', function () {
|
59 |
+
if ( class_exists( 'ACF' ) ) {
|
60 |
+
new ACFTimber();
|
61 |
+
}
|
62 |
+
} );
|
functions/functions/integrations/wpcli-timber.php
ADDED
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
if (class_exists('WP_CLI_Command')) {
|
3 |
+
class Timber_WP_CLI_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 |
+
public function clear_cache($mode = 'all') {
|
14 |
+
TimberCommand::clear_cache($mode);
|
15 |
+
}
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Clears Twig's Cache
|
19 |
+
*
|
20 |
+
* ## EXAMPLES
|
21 |
+
*
|
22 |
+
* wp timber clear_cache_twig
|
23 |
+
*
|
24 |
+
*/
|
25 |
+
function clear_cache_twig(){
|
26 |
+
$clear = TimberCommand::clear_cache_twig();
|
27 |
+
if ($clear){
|
28 |
+
WP_CLI::success('Cleared contents of twig cache');
|
29 |
+
} else {
|
30 |
+
WP_CLI::warning('Failed to clear twig cache');
|
31 |
+
}
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Clears Timber's Cache
|
36 |
+
*
|
37 |
+
* ## EXAMPLES
|
38 |
+
*
|
39 |
+
* wp timber clear_cache_timber
|
40 |
+
*
|
41 |
+
*/
|
42 |
+
function clear_cache_timber() {
|
43 |
+
$clear = TimberCommand::clear_cache_timber();
|
44 |
+
$message = 'Failed to clear timber cache';
|
45 |
+
if ($clear){
|
46 |
+
$message = "Cleared contents of Timber's Cache";
|
47 |
+
WP_CLI::success($message);
|
48 |
+
} else {
|
49 |
+
WP_CLI::warning($message);
|
50 |
+
}
|
51 |
+
return $message;
|
52 |
+
}
|
53 |
+
|
54 |
+
}
|
55 |
+
|
56 |
+
WP_CLI::add_command('timber', 'Timber_WP_CLI_Command');
|
57 |
+
}
|
58 |
+
|
59 |
+
class TimberCommand {
|
60 |
+
|
61 |
+
public static function clear_cache($mode = 'all'){
|
62 |
+
if (is_array($mode)){
|
63 |
+
$mode = reset($mode);
|
64 |
+
}
|
65 |
+
if ($mode == 'all') {
|
66 |
+
$twig_cache = self::clear_cache_twig();
|
67 |
+
$timber_cache = self::clear_cache_timber();
|
68 |
+
if ($twig_cache && $timber_cache){
|
69 |
+
return true;
|
70 |
+
}
|
71 |
+
} else if ($mode == 'twig') {
|
72 |
+
return self::clear_cache_twig();
|
73 |
+
} else if ($mode == 'timber') {
|
74 |
+
return self::clear_cache_timber();
|
75 |
+
}
|
76 |
+
}
|
77 |
+
|
78 |
+
static function clear_cache_timber(){
|
79 |
+
$loader = new TimberLoader();
|
80 |
+
return $loader->clear_cache_timber();
|
81 |
+
}
|
82 |
+
|
83 |
+
static function clear_cache_twig(){
|
84 |
+
$loader = new TimberLoader();
|
85 |
+
return $loader->clear_cache_twig();
|
86 |
+
}
|
87 |
+
|
88 |
+
}
|
functions/functions/timber-admin.php
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TimberAdmin {
|
4 |
+
|
5 |
+
function __construct() {
|
6 |
+
add_filter( 'plugin_row_meta', array( $this, 'meta_links' ), 10, 2 );
|
7 |
+
}
|
8 |
+
|
9 |
+
/**
|
10 |
+
*
|
11 |
+
*
|
12 |
+
* @param array $links
|
13 |
+
* @param string $file
|
14 |
+
* @return array
|
15 |
+
*/
|
16 |
+
function meta_links( $links, $file ) {
|
17 |
+
if ( strstr( $file, '/timber.php' ) ) {
|
18 |
+
unset($links[2]);
|
19 |
+
$links[] = '<a href="http://localhost/wp-admin/plugin-install.php?tab=plugin-information&plugin=timber-library&TB_iframe=true&width=600&height=550" class="thickbox" aria-label="More information about Timber" data-title="Timber">View details</a>';
|
20 |
+
$links[] = '<a href="http://upstatement.com/timber" target="_blank">Homepage</a>';
|
21 |
+
$links[] = '<a href="https://github.com/jarednova/timber/wiki" target="_blank">Documentation</a>';
|
22 |
+
$links[] = '<a href="https://github.com/jarednova/timber/wiki/getting-started" target="_blank">Starter Guide</a>';
|
23 |
+
return $links;
|
24 |
+
}
|
25 |
+
return $links;
|
26 |
+
}
|
27 |
+
|
28 |
+
}
|
29 |
+
|
30 |
+
global $timber_admin;
|
31 |
+
$timber_admin = new TimberAdmin();
|
functions/functions/timber-archives.php
ADDED
@@ -0,0 +1,272 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
24 |
+
* @param string $text
|
25 |
+
* @return mixed
|
26 |
+
*/
|
27 |
+
function get_archives_link($url, $text) {
|
28 |
+
$ret = array();
|
29 |
+
$ret['text'] = $ret['title'] = $ret['name'] = wptexturize($text);
|
30 |
+
$ret['url'] = $ret['link'] = esc_url(TimberURLHelper::prepend_to_url($url, $this->base));
|
31 |
+
return $ret;
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* @param array|string $args
|
36 |
+
* @param string $last_changed
|
37 |
+
* @param string $join
|
38 |
+
* @param string $where
|
39 |
+
* @param string $order
|
40 |
+
* @param string $limit
|
41 |
+
* @return array
|
42 |
+
*/
|
43 |
+
function get_items_yearly($args, $last_changed, $join, $where, $order, $limit) {
|
44 |
+
global $wpdb;
|
45 |
+
$output = array();
|
46 |
+
$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";
|
47 |
+
$key = md5($query);
|
48 |
+
$key = "wp_get_archives:$key:$last_changed";
|
49 |
+
if (!$results = wp_cache_get($key, 'posts')) {
|
50 |
+
$results = $wpdb->get_results($query);
|
51 |
+
wp_cache_set($key, $results, 'posts');
|
52 |
+
}
|
53 |
+
if ($results) {
|
54 |
+
foreach ((array)$results as $result) {
|
55 |
+
$url = get_year_link($result->year);
|
56 |
+
$text = sprintf('%d', $result->year);
|
57 |
+
$output[] = $this->get_archives_link($url, $text);
|
58 |
+
}
|
59 |
+
}
|
60 |
+
return $output;
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* @param array|string $args
|
65 |
+
* @param string $last_changed
|
66 |
+
* @param string $join
|
67 |
+
* @param string $where
|
68 |
+
* @param string $order
|
69 |
+
* @param int $limit
|
70 |
+
* @param bool $nested
|
71 |
+
* @return array
|
72 |
+
*/
|
73 |
+
function get_items_montly($args, $last_changed, $join, $where, $order, $limit = 1000, $nested = true) {
|
74 |
+
global $wpdb, $wp_locale;
|
75 |
+
$output = array();
|
76 |
+
$defaults = array(
|
77 |
+
'show_year' => true,
|
78 |
+
);
|
79 |
+
$r = wp_parse_args($args, $defaults);
|
80 |
+
|
81 |
+
$show_year = null;
|
82 |
+
extract($r, EXTR_SKIP);
|
83 |
+
|
84 |
+
//will need to specify which year we're looking for
|
85 |
+
$query = "SELECT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, count(ID) as posts "
|
86 |
+
. "FROM $wpdb->posts $join $where GROUP BY YEAR(post_date), MONTH(post_date) "
|
87 |
+
. "ORDER BY post_date $order $limit";
|
88 |
+
$key = md5($query);
|
89 |
+
$key = "wp_get_archives:$key:$last_changed";
|
90 |
+
if (!$results = wp_cache_get($key, 'posts')) {
|
91 |
+
$results = $wpdb->get_results($query);
|
92 |
+
wp_cache_set($key, $results, 'posts');
|
93 |
+
}
|
94 |
+
if ($results) {
|
95 |
+
foreach ((array)$results as $result) {
|
96 |
+
$url = get_month_link($result->year, $result->month);
|
97 |
+
/* translators: 1: month name, 2: 4-digit year */
|
98 |
+
|
99 |
+
if ($show_year && !$nested) {
|
100 |
+
$text = sprintf(__('%1$s %2$d'), $wp_locale->get_month($result->month), $result->year);
|
101 |
+
} else {
|
102 |
+
$text = sprintf(__('%1$s'), $wp_locale->get_month($result->month));
|
103 |
+
}
|
104 |
+
if ($nested) {
|
105 |
+
$output[$result->year][] = $this->get_archives_link($url, $text);
|
106 |
+
} else {
|
107 |
+
$output[] = $this->get_archives_link($url, $text);
|
108 |
+
}
|
109 |
+
}
|
110 |
+
}
|
111 |
+
if ($nested) {
|
112 |
+
$out2 = array();
|
113 |
+
foreach ($output as $year => $months) {
|
114 |
+
$out2[] = array('name' => $year, 'children' => $months);
|
115 |
+
}
|
116 |
+
return $out2;
|
117 |
+
}
|
118 |
+
return $output;
|
119 |
+
}
|
120 |
+
|
121 |
+
/**
|
122 |
+
* @param array|string $args
|
123 |
+
* @return array|string
|
124 |
+
*/
|
125 |
+
function get_items($args = null) {
|
126 |
+
global $wpdb;
|
127 |
+
|
128 |
+
$defaults = array(
|
129 |
+
'type' => 'monthly', 'limit' => '',
|
130 |
+
'format' => 'html', 'before' => '',
|
131 |
+
'after' => '', 'show_post_count' => false,
|
132 |
+
'order' => 'DESC',
|
133 |
+
'post_type' => 'post',
|
134 |
+
'nested' => true
|
135 |
+
);
|
136 |
+
|
137 |
+
$r = wp_parse_args($args, $defaults);
|
138 |
+
$type = $limit = $order = $post_type = $nested = $format = $before = $after = null;
|
139 |
+
extract($r, EXTR_SKIP);
|
140 |
+
|
141 |
+
if (empty($order)){
|
142 |
+
$order = 'DESC';
|
143 |
+
}
|
144 |
+
|
145 |
+
if (empty($post_type)){
|
146 |
+
$post_type = 'post';
|
147 |
+
}
|
148 |
+
if (empty($type)) {
|
149 |
+
$type = 'monthly';
|
150 |
+
}
|
151 |
+
|
152 |
+
if (!empty($limit)) {
|
153 |
+
$limit = absint($limit);
|
154 |
+
$limit = ' LIMIT ' . $limit;
|
155 |
+
}
|
156 |
+
|
157 |
+
$order = strtoupper($order);
|
158 |
+
if ($order !== 'ASC') {
|
159 |
+
$order = 'DESC';
|
160 |
+
}
|
161 |
+
|
162 |
+
// this is what will separate dates on weekly archive links
|
163 |
+
$archive_week_separator = '–';
|
164 |
+
|
165 |
+
// over-ride general date format ? 0 = no: use the date format set in Options, 1 = yes: over-ride
|
166 |
+
$archive_date_format_over_ride = 0;
|
167 |
+
|
168 |
+
// options for daily archive (only if you over-ride the general date format)
|
169 |
+
$archive_day_date_format = 'Y/m/d';
|
170 |
+
|
171 |
+
// options for weekly archive (only if you over-ride the general date format)
|
172 |
+
$archive_week_start_date_format = 'Y/m/d';
|
173 |
+
$archive_week_end_date_format = 'Y/m/d';
|
174 |
+
|
175 |
+
if (!$archive_date_format_over_ride) {
|
176 |
+
$archive_day_date_format = get_option('date_format');
|
177 |
+
$archive_week_start_date_format = get_option('date_format');
|
178 |
+
$archive_week_end_date_format = get_option('date_format');
|
179 |
+
}
|
180 |
+
|
181 |
+
$where = apply_filters('getarchives_where', 'WHERE post_type = "' . $post_type . '" AND post_status = "publish"', $r);
|
182 |
+
$join = apply_filters('getarchives_join', '', $r);
|
183 |
+
|
184 |
+
$output = array();
|
185 |
+
|
186 |
+
$last_changed = wp_cache_get('last_changed', 'posts');
|
187 |
+
if (!$last_changed) {
|
188 |
+
$last_changed = microtime();
|
189 |
+
wp_cache_set('last_changed', $last_changed, 'posts');
|
190 |
+
}
|
191 |
+
if ('monthly' == $type) {
|
192 |
+
$output = $this->get_items_montly($args, $last_changed, $join, $where, $order, $limit, $nested);
|
193 |
+
} elseif ('yearly' == $type) {
|
194 |
+
$output = $this->get_items_yearly($args, $last_changed, $join, $where, $order, $limit);
|
195 |
+
} elseif ('yearlymonthly' == $type || 'yearmonth' == $type) {
|
196 |
+
$years = $this->get_items_yearly($args, $last_changed, $join, $where, $order, $limit);
|
197 |
+
foreach ($years as &$year) {
|
198 |
+
$args = array('show_year' => false);
|
199 |
+
$year['children'] = $this->get_items_montly($args, $last_changed, $join, $where, $order, $limit);
|
200 |
+
}
|
201 |
+
$output = $years;
|
202 |
+
} elseif ('daily' == $type) {
|
203 |
+
$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";
|
204 |
+
$key = md5($query);
|
205 |
+
$key = "wp_get_archives:$key:$last_changed";
|
206 |
+
if (!$results = wp_cache_get($key, 'posts')) {
|
207 |
+
$results = $wpdb->get_results($query);
|
208 |
+
$cache = array();
|
209 |
+
$cache[$key] = $results;
|
210 |
+
wp_cache_set($key, $results, 'posts');
|
211 |
+
}
|
212 |
+
if ($results) {
|
213 |
+
foreach ((array)$results as $result) {
|
214 |
+
$url = get_day_link($result->year, $result->month, $result->dayofmonth);
|
215 |
+
$date = sprintf('%1$d-%2$02d-%3$02d 00:00:00', $result->year, $result->month, $result->dayofmonth);
|
216 |
+
$text = mysql2date($archive_day_date_format, $date);
|
217 |
+
$output[] = $this->get_archives_link($url, $text);
|
218 |
+
}
|
219 |
+
}
|
220 |
+
} elseif ('weekly' == $type) {
|
221 |
+
$week = _wp_mysql_week('`post_date`');
|
222 |
+
$query = "SELECT DISTINCT $week AS `week`, YEAR( `post_date` ) AS `yr`, DATE_FORMAT( `post_date`, '%Y-%m-%d' ) AS `yyyymmdd`, "
|
223 |
+
. "count( `ID` ) AS `posts` FROM `$wpdb->posts` $join $where GROUP BY $week, YEAR( `post_date` ) ORDER BY `post_date` $order $limit";
|
224 |
+
$key = md5($query);
|
225 |
+
$key = "wp_get_archives:$key:$last_changed";
|
226 |
+
if (!$results = wp_cache_get($key, 'posts')) {
|
227 |
+
$results = $wpdb->get_results($query);
|
228 |
+
wp_cache_set($key, $results, 'posts');
|
229 |
+
}
|
230 |
+
$arc_w_last = '';
|
231 |
+
if ($results) {
|
232 |
+
foreach ((array)$results as $result) {
|
233 |
+
if ($result->week != $arc_w_last) {
|
234 |
+
$arc_year = $result->yr;
|
235 |
+
$arc_w_last = $result->week;
|
236 |
+
$arc_week = get_weekstartend($result->yyyymmdd, get_option('start_of_week'));
|
237 |
+
$arc_week_start = date_i18n($archive_week_start_date_format, $arc_week['start']);
|
238 |
+
$arc_week_end = date_i18n($archive_week_end_date_format, $arc_week['end']);
|
239 |
+
$url = sprintf('%1$s/%2$s%3$sm%4$s%5$s%6$sw%7$s%8$d', home_url(), '', '?', '=', $arc_year, '&', '=', $result->week);
|
240 |
+
$text = $arc_week_start . $archive_week_separator . $arc_week_end;
|
241 |
+
$output[] = $this->get_archives_link($url, $text);
|
242 |
+
}
|
243 |
+
}
|
244 |
+
}
|
245 |
+
} elseif ('postbypost' == $type || 'alpha' == $type) {
|
246 |
+
$orderby = 'alpha' == $type ? 'post_title ASC ' : 'post_date DESC ';
|
247 |
+
$query = "SELECT * FROM $wpdb->posts $join $where ORDER BY $orderby $limit";
|
248 |
+
$key = md5($query);
|
249 |
+
$key = "wp_get_archives:$key:$last_changed";
|
250 |
+
if (!$results = wp_cache_get($key, 'posts')) {
|
251 |
+
$results = $wpdb->get_results($query);
|
252 |
+
wp_cache_set($key, $results, 'posts');
|
253 |
+
}
|
254 |
+
if ($results) {
|
255 |
+
foreach ((array)$results as $result) {
|
256 |
+
if ($result->post_date != '0000-00-00 00:00:00') {
|
257 |
+
$url = get_permalink($result);
|
258 |
+
if ($result->post_title) {
|
259 |
+
/** This filter is documented in wp-includes/post-template.php */
|
260 |
+
$text = strip_tags(apply_filters('the_title', $result->post_title, $result->ID));
|
261 |
+
} else {
|
262 |
+
$text = $result->ID;
|
263 |
+
}
|
264 |
+
$output .= get_archives_link($url, $text, $format, $before, $after);
|
265 |
+
}
|
266 |
+
}
|
267 |
+
}
|
268 |
+
}
|
269 |
+
return $output;
|
270 |
+
}
|
271 |
+
|
272 |
+
}
|
functions/functions/timber-comment.php
ADDED
@@ -0,0 +1,239 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TimberComment extends TimberCore implements TimberCoreInterface {
|
4 |
+
|
5 |
+
public $PostClass = 'TimberPost';
|
6 |
+
public $object_type = 'comment';
|
7 |
+
|
8 |
+
public static $representation = 'comment';
|
9 |
+
|
10 |
+
public $ID;
|
11 |
+
public $id;
|
12 |
+
public $comment_author_email;
|
13 |
+
public $comment_content;
|
14 |
+
public $comment_date;
|
15 |
+
public $comment_ID;
|
16 |
+
public $user_id;
|
17 |
+
public $comment_author;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @param int $cid
|
21 |
+
*/
|
22 |
+
function __construct($cid) {
|
23 |
+
$this->init($cid);
|
24 |
+
}
|
25 |
+
|
26 |
+
function __toString(){
|
27 |
+
return $this->content();
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* @param integer $cid
|
32 |
+
*/
|
33 |
+
function init($cid) {
|
34 |
+
$comment_data = $cid;
|
35 |
+
if (is_integer($cid)) {
|
36 |
+
$comment_data = get_comment($cid);
|
37 |
+
}
|
38 |
+
$this->import($comment_data);
|
39 |
+
$this->ID = $this->comment_ID;
|
40 |
+
$this->id = $this->comment_ID;
|
41 |
+
$comment_meta_data = $this->get_meta_fields($this->ID);
|
42 |
+
$this->import($comment_meta_data);
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* @return TimberUser
|
47 |
+
*/
|
48 |
+
public function author() {
|
49 |
+
if ($this->user_id) {
|
50 |
+
return new TimberUser($this->user_id);
|
51 |
+
} else {
|
52 |
+
$author = new TimberUser(0);
|
53 |
+
if (isset($this->comment_author) && $this->comment_author) {
|
54 |
+
$author->name = $this->comment_author;
|
55 |
+
} else {
|
56 |
+
$author->name = 'Anonymous';
|
57 |
+
}
|
58 |
+
}
|
59 |
+
return $author;
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* @param int $size
|
64 |
+
* @param string $default
|
65 |
+
* @return bool|mixed|string
|
66 |
+
*/
|
67 |
+
public function avatar($size = 92, $default = '') {
|
68 |
+
// Fetches the Gravatar
|
69 |
+
// use it like this
|
70 |
+
// {{comment.avatar(36,template_uri~"/img/dude.jpg")}}
|
71 |
+
|
72 |
+
if (!get_option('show_avatars')) {
|
73 |
+
return false;
|
74 |
+
}
|
75 |
+
if (!is_numeric($size)) {
|
76 |
+
$size = '92';
|
77 |
+
}
|
78 |
+
|
79 |
+
$email = $this->avatar_email();
|
80 |
+
$email_hash = '';
|
81 |
+
if (!empty($email)) {
|
82 |
+
$email_hash = md5(strtolower(trim($email)));
|
83 |
+
}
|
84 |
+
$host = $this->avatar_host($email_hash);
|
85 |
+
$default = $this->avatar_default($default, $email, $size, $host);
|
86 |
+
if (!empty($email)) {
|
87 |
+
$avatar = $this->avatar_out($email, $default, $host, $email_hash, $size);
|
88 |
+
} else {
|
89 |
+
$avatar = $default;
|
90 |
+
}
|
91 |
+
return $avatar;
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* @return string
|
96 |
+
*/
|
97 |
+
public function content() {
|
98 |
+
return $this->comment_content;
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* @return string
|
103 |
+
*/
|
104 |
+
public function date() {
|
105 |
+
return $this->comment_date;
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* @param string $field_name
|
110 |
+
* @return mixed
|
111 |
+
*/
|
112 |
+
public function meta($field_name) {
|
113 |
+
return $this->get_meta_field($field_name);
|
114 |
+
}
|
115 |
+
|
116 |
+
/**
|
117 |
+
* @param int $comment_id
|
118 |
+
* @return mixed
|
119 |
+
*/
|
120 |
+
private function get_meta_fields($comment_id = null) {
|
121 |
+
if ($comment_id === null) {
|
122 |
+
$comment_id = $this->ID;
|
123 |
+
}
|
124 |
+
//Could not find a WP function to fetch all comment meta data, so I made one.
|
125 |
+
apply_filters('timber_comment_get_meta_pre', array(), $comment_id);
|
126 |
+
$comment_metas = get_comment_meta($comment_id);
|
127 |
+
foreach ($comment_metas as &$cm) {
|
128 |
+
if (is_array($cm) && count($cm) == 1) {
|
129 |
+
$cm = $cm[0];
|
130 |
+
}
|
131 |
+
}
|
132 |
+
$comment_metas = apply_filters('timber_comment_get_meta', $comment_metas, $comment_id);
|
133 |
+
return $comment_metas;
|
134 |
+
}
|
135 |
+
|
136 |
+
/**
|
137 |
+
* @param string $field_name
|
138 |
+
* @return mixed
|
139 |
+
*/
|
140 |
+
private function get_meta_field($field_name) {
|
141 |
+
$value = apply_filters('timber_comment_get_meta_field_pre', null, $this->ID, $field_name, $this);
|
142 |
+
if ($value === null) {
|
143 |
+
$value = get_comment_meta($this->ID, $field_name, true);
|
144 |
+
}
|
145 |
+
$value = apply_filters('timber_comment_get_meta_field', $value, $this->ID, $field_name, $this);
|
146 |
+
return $value;
|
147 |
+
}
|
148 |
+
|
149 |
+
/* AVATAR Stuff
|
150 |
+
======================= */
|
151 |
+
|
152 |
+
/**
|
153 |
+
* @return string
|
154 |
+
*/
|
155 |
+
private function avatar_email() {
|
156 |
+
$id = (int)$this->user_id;
|
157 |
+
$user = get_userdata($id);
|
158 |
+
if ($user) {
|
159 |
+
$email = $user->user_email;
|
160 |
+
} else {
|
161 |
+
$email = $this->comment_author_email;
|
162 |
+
}
|
163 |
+
return $email;
|
164 |
+
}
|
165 |
+
|
166 |
+
/**
|
167 |
+
* @param string $email_hash
|
168 |
+
* @return string
|
169 |
+
*/
|
170 |
+
private function avatar_host($email_hash) {
|
171 |
+
if (is_ssl()) {
|
172 |
+
$host = 'https://secure.gravatar.com';
|
173 |
+
} else {
|
174 |
+
if (!empty($email_hash)) {
|
175 |
+
$host = sprintf("http://%d.gravatar.com", (hexdec($email_hash[0]) % 2));
|
176 |
+
} else {
|
177 |
+
$host = 'http://0.gravatar.com';
|
178 |
+
}
|
179 |
+
}
|
180 |
+
return $host;
|
181 |
+
}
|
182 |
+
|
183 |
+
/**
|
184 |
+
* @param string $default
|
185 |
+
* @param string $email
|
186 |
+
* @param string $size
|
187 |
+
* @param string $host
|
188 |
+
* @return string
|
189 |
+
*/
|
190 |
+
private function avatar_default($default, $email, $size, $host) {
|
191 |
+
# what if its relative.
|
192 |
+
if (substr($default, 0, 1) == '/') {
|
193 |
+
$default = home_url() . $default;
|
194 |
+
}
|
195 |
+
|
196 |
+
if (empty($default)) {
|
197 |
+
$avatar_default = get_option('avatar_default');
|
198 |
+
if (empty($avatar_default)) {
|
199 |
+
$default = 'mystery';
|
200 |
+
} else {
|
201 |
+
$default = $avatar_default;
|
202 |
+
}
|
203 |
+
}
|
204 |
+
if ('mystery' == $default) {
|
205 |
+
$default = $host . '/avatar/ad516503a11cd5ca435acc9bb6523536?s=' . $size;
|
206 |
+
// ad516503a11cd5ca435acc9bb6523536 == md5('unknown@gravatar.com')
|
207 |
+
} else if ('blank' == $default) {
|
208 |
+
$default = $email ? 'blank' : includes_url('images/blank.gif');
|
209 |
+
} else if (!empty($email) && 'gravatar_default' == $default) {
|
210 |
+
$default = '';
|
211 |
+
} else if ('gravatar_default' == $default) {
|
212 |
+
$default = $host . '/avatar/?s=' . $size;
|
213 |
+
} else if (empty($email) && !strstr($default, 'http://')) {
|
214 |
+
$default = $host . '/avatar/?d=' . $default . '&s=' . $size;
|
215 |
+
} else if (strpos($default, 'http://') === 0) {
|
216 |
+
//theyre just linking to an image so don't do anything else
|
217 |
+
//$default = add_query_arg( 's', $size, $default );
|
218 |
+
}
|
219 |
+
return $default;
|
220 |
+
}
|
221 |
+
|
222 |
+
/**
|
223 |
+
* @param string $email
|
224 |
+
* @param string $default
|
225 |
+
* @param string $host
|
226 |
+
* @param string $email_hash
|
227 |
+
* @param string $size
|
228 |
+
* @return mixed
|
229 |
+
*/
|
230 |
+
private function avatar_out($email, $default, $host, $email_hash, $size) {
|
231 |
+
$out = $host . '/avatar/' . $email_hash . '?s=' . $size . '&d=' . urlencode($default);
|
232 |
+
$rating = get_option('avatar_rating');
|
233 |
+
if (!empty($rating)) {
|
234 |
+
$out .= '&r=' . $rating;
|
235 |
+
}
|
236 |
+
return str_replace('&', '&', esc_url($out));
|
237 |
+
}
|
238 |
+
|
239 |
+
}
|
functions/functions/timber-core-interface.php
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
interface TimberCoreInterface {
|
4 |
+
|
5 |
+
public function __call( $field, $args );
|
6 |
+
|
7 |
+
public function __get( $field );
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @return boolean
|
11 |
+
*/
|
12 |
+
public function __isset( $field );
|
13 |
+
|
14 |
+
public function meta( $key );
|
15 |
+
|
16 |
+
}
|
functions/functions/timber-core.php
ADDED
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
abstract class TimberCore {
|
4 |
+
|
5 |
+
public $id;
|
6 |
+
public $ID;
|
7 |
+
public $object_type;
|
8 |
+
public $_can_edit;
|
9 |
+
|
10 |
+
/**
|
11 |
+
*
|
12 |
+
*
|
13 |
+
* @return boolean
|
14 |
+
*/
|
15 |
+
function __isset( $field ) {
|
16 |
+
if ( isset( $this->$field ) ) {
|
17 |
+
return $this->$field;
|
18 |
+
}
|
19 |
+
return false;
|
20 |
+
}
|
21 |
+
|
22 |
+
/**
|
23 |
+
* This is helpful for twig to return properties and methods see: https://github.com/fabpot/Twig/issues/2
|
24 |
+
* @return mixed
|
25 |
+
*/
|
26 |
+
function __call( $field, $args ) {
|
27 |
+
return $this->__get( $field );
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* This is helpful for twig to return properties and methods see: https://github.com/fabpot/Twig/issues/2
|
32 |
+
*
|
33 |
+
* @return mixed
|
34 |
+
*/
|
35 |
+
function __get( $field ) {
|
36 |
+
if ( isset( $this->$field ) ) {
|
37 |
+
return $this->$field;
|
38 |
+
}
|
39 |
+
if ( $meta_value = $this->meta( $field ) ) {
|
40 |
+
return $this->$field = $meta_value;
|
41 |
+
}
|
42 |
+
if (method_exists($this, $field)) {
|
43 |
+
return $this->$field = $this->$field();
|
44 |
+
}
|
45 |
+
return $this->$field = false;
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
*
|
50 |
+
*
|
51 |
+
* @param array|object $info an object or array you want to grab data from to attach to the Timber object
|
52 |
+
*/
|
53 |
+
function import( $info, $force = false ) {
|
54 |
+
if ( is_object( $info ) ) {
|
55 |
+
$info = get_object_vars( $info );
|
56 |
+
}
|
57 |
+
if ( is_array( $info ) ) {
|
58 |
+
foreach ( $info as $key => $value ) {
|
59 |
+
if ( !empty( $key ) && $force ) {
|
60 |
+
$this->$key = $value;
|
61 |
+
} else if ( !empty( $key ) && !method_exists($this, $key) ){
|
62 |
+
$this->$key = $value;
|
63 |
+
}
|
64 |
+
}
|
65 |
+
}
|
66 |
+
}
|
67 |
+
|
68 |
+
|
69 |
+
/**
|
70 |
+
*
|
71 |
+
*
|
72 |
+
* @param string $key
|
73 |
+
* @param mixed $value
|
74 |
+
*/
|
75 |
+
function update( $key, $value ) {
|
76 |
+
update_metadata( $this->object_type, $this->ID, $key, $value );
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
*
|
81 |
+
*
|
82 |
+
* @return bool
|
83 |
+
*/
|
84 |
+
function can_edit() {
|
85 |
+
if ( isset( $this->_can_edit ) ) {
|
86 |
+
return $this->_can_edit;
|
87 |
+
}
|
88 |
+
$this->_can_edit = false;
|
89 |
+
if ( !function_exists( 'current_user_can' ) ) {
|
90 |
+
return false;
|
91 |
+
}
|
92 |
+
if ( current_user_can( 'edit_post', $this->ID ) ) {
|
93 |
+
$this->_can_edit = true;
|
94 |
+
}
|
95 |
+
return $this->_can_edit;
|
96 |
+
}
|
97 |
+
|
98 |
+
/**
|
99 |
+
*
|
100 |
+
*
|
101 |
+
* @return array
|
102 |
+
*/
|
103 |
+
function get_method_values() {
|
104 |
+
$ret = array();
|
105 |
+
$ret['can_edit'] = $this->can_edit();
|
106 |
+
return $ret;
|
107 |
+
}
|
108 |
+
|
109 |
+
}
|
functions/functions/timber-function-wrapper.php
ADDED
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TimberFunctionWrapper
|
4 |
+
{
|
5 |
+
|
6 |
+
private $_function;
|
7 |
+
private $_args;
|
8 |
+
private $_use_ob;
|
9 |
+
|
10 |
+
public function __toString() {
|
11 |
+
return $this->call();
|
12 |
+
}
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @param callable $function
|
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 |
+
}
|
40 |
+
|
41 |
+
/**
|
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 TimberHelper::ob_function($this->_function, $args);
|
49 |
+
} else {
|
50 |
+
return (string)call_user_func_array($this->_function, $args);
|
51 |
+
}
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* @param array $args
|
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;
|
68 |
+
}
|
69 |
+
|
70 |
+
}
|
functions/functions/timber-helper.php
ADDED
@@ -0,0 +1,684 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TimberHelper {
|
4 |
+
|
5 |
+
/**
|
6 |
+
*
|
7 |
+
*
|
8 |
+
* @param string $slug Unique identifier for transient
|
9 |
+
* @param callable $callback Callback that generates the data that's to be cached
|
10 |
+
* @param int $transient_time (optional) Expiration of transients in seconds
|
11 |
+
* @param int $lock_timeout (optional) How long to lock the transient to prevent race conditions
|
12 |
+
* @param bool $force (optional) Force callback to be executed when transient is locked
|
13 |
+
* @return mixed
|
14 |
+
*/
|
15 |
+
public static function transient( $slug, $callback, $transient_time = 0, $lock_timeout = 5, $force = false ) {
|
16 |
+
|
17 |
+
$enable_transients = ( $transient_time === false || ( defined( 'WP_DISABLE_TRANSIENTS' ) && WP_DISABLE_TRANSIENTS ) ) ? false : true;
|
18 |
+
$data = $enable_transients ? get_transient( $slug ) : false;
|
19 |
+
|
20 |
+
if ( false === $data ) {
|
21 |
+
|
22 |
+
if ( $enable_transients && self::_is_transient_locked( $slug ) ) {
|
23 |
+
|
24 |
+
$force = apply_filters( 'timber_force_transients', $force );
|
25 |
+
$force = apply_filters( 'timber_force_transient_' . $slug, $force );
|
26 |
+
|
27 |
+
if ( !$force ) {
|
28 |
+
//the server is currently executing the process.
|
29 |
+
//We're just gonna dump these users. Sorry!
|
30 |
+
return false;
|
31 |
+
}
|
32 |
+
|
33 |
+
$enable_transients = false;
|
34 |
+
}
|
35 |
+
|
36 |
+
// lock timeout shouldn't be higher than 5 seconds, unless
|
37 |
+
// remote calls with high timeouts are made here
|
38 |
+
if ( $enable_transients )
|
39 |
+
self::_lock_transient( $slug, $lock_timeout );
|
40 |
+
|
41 |
+
$data = $callback();
|
42 |
+
|
43 |
+
if ( $enable_transients ) {
|
44 |
+
set_transient( $slug, $data, $transient_time );
|
45 |
+
self::_unlock_transient( $slug );
|
46 |
+
}
|
47 |
+
|
48 |
+
}
|
49 |
+
|
50 |
+
return $data;
|
51 |
+
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* @param string $slug
|
56 |
+
* @param integer $lock_timeout
|
57 |
+
*/
|
58 |
+
public static function _lock_transient( $slug, $lock_timeout ) {
|
59 |
+
set_transient( $slug . '_lock', true, $lock_timeout );
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* @param string $slug
|
64 |
+
*/
|
65 |
+
public static function _unlock_transient( $slug ) {
|
66 |
+
delete_transient( $slug . '_lock', true );
|
67 |
+
}
|
68 |
+
|
69 |
+
/**
|
70 |
+
* @param string $slug
|
71 |
+
*/
|
72 |
+
public static function _is_transient_locked( $slug ) {
|
73 |
+
return (bool)get_transient( $slug . '_lock' );
|
74 |
+
}
|
75 |
+
|
76 |
+
/* These are for measuring page render time */
|
77 |
+
|
78 |
+
/**
|
79 |
+
*
|
80 |
+
*
|
81 |
+
* @return float
|
82 |
+
*/
|
83 |
+
public static function start_timer() {
|
84 |
+
$time = microtime();
|
85 |
+
$time = explode( ' ', $time );
|
86 |
+
$time = $time[1] + $time[0];
|
87 |
+
return $time;
|
88 |
+
}
|
89 |
+
|
90 |
+
/**
|
91 |
+
*
|
92 |
+
*
|
93 |
+
* @param int $start
|
94 |
+
* @return string
|
95 |
+
*/
|
96 |
+
public static function stop_timer( $start ) {
|
97 |
+
$time = microtime();
|
98 |
+
$time = explode( ' ', $time );
|
99 |
+
$time = $time[1] + $time[0];
|
100 |
+
$finish = $time;
|
101 |
+
$total_time = round( ( $finish - $start ), 4 );
|
102 |
+
return $total_time . ' seconds.';
|
103 |
+
}
|
104 |
+
|
105 |
+
/* Function Utilities
|
106 |
+
======================== */
|
107 |
+
|
108 |
+
/**
|
109 |
+
*
|
110 |
+
*
|
111 |
+
* @param callback $function
|
112 |
+
* @param array $args
|
113 |
+
* @return string
|
114 |
+
*/
|
115 |
+
public static function ob_function( $function, $args = array( null ) ) {
|
116 |
+
ob_start();
|
117 |
+
call_user_func_array( $function, $args );
|
118 |
+
$data = ob_get_contents();
|
119 |
+
ob_end_clean();
|
120 |
+
return $data;
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
*
|
125 |
+
*
|
126 |
+
* @param string $function_name
|
127 |
+
* @param integer[] $defaults
|
128 |
+
* @param bool $return_output_buffer
|
129 |
+
* @return TimberFunctionWrapper
|
130 |
+
*/
|
131 |
+
public static function function_wrapper( $function_name, $defaults = array(), $return_output_buffer = false ) {
|
132 |
+
return new TimberFunctionWrapper( $function_name, $defaults, $return_output_buffer );
|
133 |
+
}
|
134 |
+
|
135 |
+
/**
|
136 |
+
*
|
137 |
+
*
|
138 |
+
* @param unknown $arg
|
139 |
+
* @return void
|
140 |
+
*/
|
141 |
+
public static function error_log( $arg ) {
|
142 |
+
if ( !WP_DEBUG ) {
|
143 |
+
return;
|
144 |
+
}
|
145 |
+
if ( is_object( $arg ) || is_array( $arg ) ) {
|
146 |
+
$arg = print_r( $arg, true );
|
147 |
+
}
|
148 |
+
error_log( $arg );
|
149 |
+
}
|
150 |
+
|
151 |
+
/**
|
152 |
+
*
|
153 |
+
*
|
154 |
+
* @param string $separator
|
155 |
+
* @param string $seplocation
|
156 |
+
* @return string
|
157 |
+
*/
|
158 |
+
public static function get_wp_title( $separator = ' ', $seplocation = 'left' ) {
|
159 |
+
$separator = apply_filters( 'timber_wp_title_seperator', $separator );
|
160 |
+
return trim( wp_title( $separator, false, $seplocation ) );
|
161 |
+
}
|
162 |
+
|
163 |
+
/* Text Utilities
|
164 |
+
======================== */
|
165 |
+
|
166 |
+
/**
|
167 |
+
*
|
168 |
+
*
|
169 |
+
* @param string $text
|
170 |
+
* @param int $num_words
|
171 |
+
* @param string $more
|
172 |
+
* @param string $allowed_tags
|
173 |
+
* @return string
|
174 |
+
*/
|
175 |
+
public static function trim_words( $text, $num_words = 55, $more = null, $allowed_tags = 'p a span b i br' ) {
|
176 |
+
if ( null === $more ) {
|
177 |
+
$more = __( '…' );
|
178 |
+
}
|
179 |
+
$original_text = $text;
|
180 |
+
$allowed_tag_string = '';
|
181 |
+
foreach ( explode( ' ', $allowed_tags ) as $tag ) {
|
182 |
+
$allowed_tag_string .= '<' . $tag . '>';
|
183 |
+
}
|
184 |
+
$text = strip_tags( $text, $allowed_tag_string );
|
185 |
+
/* translators: If your word count is based on single characters (East Asian characters),
|
186 |
+
enter 'characters'. Otherwise, enter 'words'. Do not translate into your own language. */
|
187 |
+
if ( 'characters' == _x( 'words', 'word count: words or characters?' ) && preg_match( '/^utf\-?8$/i', get_option( 'blog_charset' ) ) ) {
|
188 |
+
$text = trim( preg_replace( "/[\n\r\t ]+/", ' ', $text ), ' ' );
|
189 |
+
preg_match_all( '/./u', $text, $words_array );
|
190 |
+
$words_array = array_slice( $words_array[0], 0, $num_words + 1 );
|
191 |
+
$sep = '';
|
192 |
+
} else {
|
193 |
+
$words_array = preg_split( "/[\n\r\t ]+/", $text, $num_words + 1, PREG_SPLIT_NO_EMPTY );
|
194 |
+
$sep = ' ';
|
195 |
+
}
|
196 |
+
if ( count( $words_array ) > $num_words ) {
|
197 |
+
array_pop( $words_array );
|
198 |
+
$text = implode( $sep, $words_array );
|
199 |
+
$text = $text . $more;
|
200 |
+
} else {
|
201 |
+
$text = implode( $sep, $words_array );
|
202 |
+
}
|
203 |
+
$text = self::close_tags( $text );
|
204 |
+
return apply_filters( 'wp_trim_words', $text, $num_words, $more, $original_text );
|
205 |
+
}
|
206 |
+
|
207 |
+
/**
|
208 |
+
*
|
209 |
+
*
|
210 |
+
* @param string $html
|
211 |
+
* @return string
|
212 |
+
*/
|
213 |
+
public static function close_tags( $html ) {
|
214 |
+
//put all opened tags into an array
|
215 |
+
preg_match_all( '#<([a-z]+)(?: .*)?(?<![/|/ ])>#iU', $html, $result );
|
216 |
+
$openedtags = $result[1];
|
217 |
+
//put all closed tags into an array
|
218 |
+
preg_match_all( '#</([a-z]+)>#iU', $html, $result );
|
219 |
+
$closedtags = $result[1];
|
220 |
+
$len_opened = count( $openedtags );
|
221 |
+
// all tags are closed
|
222 |
+
if ( count( $closedtags ) == $len_opened ) {
|
223 |
+
return $html;
|
224 |
+
}
|
225 |
+
$openedtags = array_reverse( $openedtags );
|
226 |
+
// close tags
|
227 |
+
for ( $i = 0; $i < $len_opened; $i++ ) {
|
228 |
+
if ( !in_array( $openedtags[$i], $closedtags ) ) {
|
229 |
+
$html .= '</' . $openedtags[$i] . '>';
|
230 |
+
} else {
|
231 |
+
unset( $closedtags[array_search( $openedtags[$i], $closedtags )] );
|
232 |
+
}
|
233 |
+
}
|
234 |
+
$html = str_replace(array('</br>','</hr>','</wbr>'), '', $html);
|
235 |
+
$html = str_replace(array('<br>','<hr>','<wbr>'), array('<br />','<hr />','<wbr />'), $html);
|
236 |
+
return $html;
|
237 |
+
}
|
238 |
+
|
239 |
+
/**
|
240 |
+
*
|
241 |
+
*
|
242 |
+
* @param string $ret
|
243 |
+
* @return string
|
244 |
+
* @deprecated since 0.20.0
|
245 |
+
*/
|
246 |
+
public static function twitterify( $ret ) {
|
247 |
+
$ret = preg_replace( "#(^|[\n ])([\w]+?://[\w]+[^ \"\n\r\t< ]*)#", "\\1<a href=\"\\2\" target=\"_blank\">\\2</a>", $ret );
|
248 |
+
$ret = preg_replace( "#(^|[\n ])((www|ftp)\.[^ \"\t\n\r< ]*)#", "\\1<a href=\"http://\\2\" target=\"_blank\">\\2</a>", $ret );
|
249 |
+
$pattern = '#([0-9a-z]([-_.]?[0-9a-z])*@[0-9a-z]([-.]?[0-9a-z])*\\.';
|
250 |
+
$pattern .= '[a-wyz][a-z](fo|g|l|m|mes|o|op|pa|ro|seum|t|u|v|z)?)#i';
|
251 |
+
$ret = preg_replace( $pattern, '<a href="mailto:\\1">\\1</a>', $ret );
|
252 |
+
$ret = preg_replace( "/\B@(\w+)/", " <a href=\"http://www.twitter.com/\\1\" target=\"_blank\">@\\1</a>", $ret );
|
253 |
+
$ret = preg_replace( "/\B#(\w+)/", " <a href=\"http://twitter.com/search?q=\\1\" target=\"_blank\">#\\1</a>", $ret );
|
254 |
+
return $ret;
|
255 |
+
}
|
256 |
+
|
257 |
+
/* WordPress Query Utilities
|
258 |
+
======================== */
|
259 |
+
|
260 |
+
/**
|
261 |
+
*
|
262 |
+
*
|
263 |
+
* @param string $key
|
264 |
+
* @param string $value
|
265 |
+
* @return array|int
|
266 |
+
* @deprecated since 0.20.0
|
267 |
+
*/
|
268 |
+
public static function get_posts_by_meta( $key, $value ) {
|
269 |
+
global $wpdb;
|
270 |
+
$query = $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %s", $key, $value );
|
271 |
+
$results = $wpdb->get_col( $query );
|
272 |
+
$pids = array();
|
273 |
+
foreach ( $results as $result ) {
|
274 |
+
if ( get_post( $result ) ) {
|
275 |
+
$pids[] = $result;
|
276 |
+
}
|
277 |
+
}
|
278 |
+
if ( count( $pids ) ) {
|
279 |
+
return $pids;
|
280 |
+
}
|
281 |
+
return 0;
|
282 |
+
}
|
283 |
+
|
284 |
+
/**
|
285 |
+
*
|
286 |
+
*
|
287 |
+
* @param string $key
|
288 |
+
* @param string $value
|
289 |
+
* @return int
|
290 |
+
* @deprecated since 0.20.0
|
291 |
+
*/
|
292 |
+
public static function get_post_by_meta( $key, $value ) {
|
293 |
+
global $wpdb;
|
294 |
+
$query = $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %s ORDER BY post_id", $key, $value );
|
295 |
+
$results = $wpdb->get_col( $query );
|
296 |
+
foreach ( $results as $result ) {
|
297 |
+
if ( $result && get_post( $result ) ) {
|
298 |
+
return $result;
|
299 |
+
}
|
300 |
+
}
|
301 |
+
return 0;
|
302 |
+
}
|
303 |
+
|
304 |
+
/**
|
305 |
+
*
|
306 |
+
*
|
307 |
+
* @param int $ttid
|
308 |
+
* @return mixed
|
309 |
+
*/
|
310 |
+
public static function get_term_id_by_term_taxonomy_id( $ttid ) {
|
311 |
+
global $wpdb;
|
312 |
+
$query = $wpdb->prepare( "SELECT term_id FROM $wpdb->term_taxonomy WHERE term_taxonomy_id = %s", $ttid );
|
313 |
+
return $wpdb->get_var( $query );
|
314 |
+
}
|
315 |
+
|
316 |
+
/* Object Utilities
|
317 |
+
======================== */
|
318 |
+
|
319 |
+
/**
|
320 |
+
*
|
321 |
+
*
|
322 |
+
* @param array $array
|
323 |
+
* @param string $prop
|
324 |
+
* @return void
|
325 |
+
*/
|
326 |
+
public static function osort( &$array, $prop ) {
|
327 |
+
usort( $array, function ( $a, $b ) use ( $prop ) {
|
328 |
+
return $a->$prop > $b->$prop ? 1 : -1;
|
329 |
+
} );
|
330 |
+
}
|
331 |
+
|
332 |
+
/**
|
333 |
+
*
|
334 |
+
*
|
335 |
+
* @param array $arr
|
336 |
+
* @return bool
|
337 |
+
*/
|
338 |
+
public static function is_array_assoc( $arr ) {
|
339 |
+
if ( !is_array( $arr ) ) {
|
340 |
+
return false;
|
341 |
+
}
|
342 |
+
return (bool)count( array_filter( array_keys( $arr ), 'is_string' ) );
|
343 |
+
}
|
344 |
+
|
345 |
+
/**
|
346 |
+
*
|
347 |
+
*
|
348 |
+
* @param array $array
|
349 |
+
* @return stdClass
|
350 |
+
*/
|
351 |
+
public static function array_to_object( $array ) {
|
352 |
+
$obj = new stdClass;
|
353 |
+
foreach ( $array as $k => $v ) {
|
354 |
+
if ( is_array( $v ) ) {
|
355 |
+
$obj->{$k} = self::array_to_object( $v ); //RECURSION
|
356 |
+
} else {
|
357 |
+
$obj->{$k} = $v;
|
358 |
+
}
|
359 |
+
}
|
360 |
+
return $obj;
|
361 |
+
}
|
362 |
+
|
363 |
+
/**
|
364 |
+
*
|
365 |
+
*
|
366 |
+
* @param array $array
|
367 |
+
* @param string $key
|
368 |
+
* @param mixed $value
|
369 |
+
* @return bool|int
|
370 |
+
*/
|
371 |
+
public static function get_object_index_by_property( $array, $key, $value ) {
|
372 |
+
if ( is_array( $array ) ) {
|
373 |
+
$i = 0;
|
374 |
+
foreach ( $array as $arr ) {
|
375 |
+
if ( is_array( $arr ) ) {
|
376 |
+
if ( $arr[$key] == $value ) {
|
377 |
+
return $i;
|
378 |
+
}
|
379 |
+
} else {
|
380 |
+
if ( $arr->$key == $value ) {
|
381 |
+
return $i;
|
382 |
+
}
|
383 |
+
}
|
384 |
+
$i++;
|
385 |
+
}
|
386 |
+
}
|
387 |
+
return false;
|
388 |
+
}
|
389 |
+
|
390 |
+
/**
|
391 |
+
*
|
392 |
+
*
|
393 |
+
* @param array $array
|
394 |
+
* @param string $key
|
395 |
+
* @param mixed $value
|
396 |
+
* @return array|null
|
397 |
+
* @throws Exception
|
398 |
+
*/
|
399 |
+
public static function get_object_by_property( $array, $key, $value ) {
|
400 |
+
if ( is_array( $array ) ) {
|
401 |
+
foreach ( $array as $arr ) {
|
402 |
+
if ( $arr->$key == $value ) {
|
403 |
+
return $arr;
|
404 |
+
}
|
405 |
+
}
|
406 |
+
} else {
|
407 |
+
throw new Exception( '$array is not an array, given value: ' . $array );
|
408 |
+
}
|
409 |
+
return null;
|
410 |
+
}
|
411 |
+
|
412 |
+
/**
|
413 |
+
*
|
414 |
+
*
|
415 |
+
* @param array $array
|
416 |
+
* @param int $len
|
417 |
+
* @return array
|
418 |
+
*/
|
419 |
+
public static function array_truncate( $array, $len ) {
|
420 |
+
if ( sizeof( $array ) > $len ) {
|
421 |
+
$array = array_splice( $array, 0, $len );
|
422 |
+
}
|
423 |
+
return $array;
|
424 |
+
}
|
425 |
+
|
426 |
+
/* Bool Utilities
|
427 |
+
======================== */
|
428 |
+
|
429 |
+
/**
|
430 |
+
*
|
431 |
+
*
|
432 |
+
* @param mixed $property
|
433 |
+
* @return bool
|
434 |
+
*/
|
435 |
+
public static function is_true( $property ) {
|
436 |
+
if ( isset( $property ) ) {
|
437 |
+
if ( $property == 'true' || $property == 1 || $property == '1' || $property == true ) {
|
438 |
+
return true;
|
439 |
+
}
|
440 |
+
}
|
441 |
+
return false;
|
442 |
+
}
|
443 |
+
|
444 |
+
/**
|
445 |
+
*
|
446 |
+
*
|
447 |
+
* @param int $i
|
448 |
+
* @return bool
|
449 |
+
*/
|
450 |
+
public static function iseven( $i ) {
|
451 |
+
return ( $i % 2 ) == 0;
|
452 |
+
}
|
453 |
+
|
454 |
+
/**
|
455 |
+
*
|
456 |
+
*
|
457 |
+
* @param int $i
|
458 |
+
* @return bool
|
459 |
+
*/
|
460 |
+
public static function isodd( $i ) {
|
461 |
+
return ( $i % 2 ) != 0;
|
462 |
+
}
|
463 |
+
|
464 |
+
/* Links, Forms, Etc. Utilities
|
465 |
+
======================== */
|
466 |
+
|
467 |
+
/* this $args thing is a fucking mess, fix at some point:
|
468 |
+
|
469 |
+
http://codex.wordpress.org/Function_Reference/comment_form */
|
470 |
+
|
471 |
+
/**
|
472 |
+
*
|
473 |
+
*
|
474 |
+
* @param int $post_id
|
475 |
+
* @param array $args
|
476 |
+
* @return string
|
477 |
+
*/
|
478 |
+
public static function get_comment_form( $post_id = null, $args = array() ) {
|
479 |
+
return self::ob_function( 'comment_form', array( $args, $post_id ) );
|
480 |
+
}
|
481 |
+
|
482 |
+
/**
|
483 |
+
*
|
484 |
+
*
|
485 |
+
* @param string $args
|
486 |
+
* @return array
|
487 |
+
*/
|
488 |
+
public static function paginate_links( $args = '' ) {
|
489 |
+
$defaults = array(
|
490 |
+
'base' => '%_%', // http://example.com/all_posts.php%_% : %_% is replaced by format (below)
|
491 |
+
'format' => '?page=%#%', // ?page=%#% : %#% is replaced by the page number
|
492 |
+
'total' => 1,
|
493 |
+
'current' => 0,
|
494 |
+
'show_all' => false,
|
495 |
+
'prev_next' => true,
|
496 |
+
'prev_text' => __( '« Previous' ),
|
497 |
+
'next_text' => __( 'Next »' ),
|
498 |
+
'end_size' => 1,
|
499 |
+
'mid_size' => 2,
|
500 |
+
'type' => 'array',
|
501 |
+
'add_args' => false, // array of query args to add
|
502 |
+
'add_fragment' => ''
|
503 |
+
);
|
504 |
+
$args = wp_parse_args( $args, $defaults );
|
505 |
+
// Who knows what else people pass in $args
|
506 |
+
$args['total'] = intval( (int)$args['total'] );
|
507 |
+
if ( $args['total'] < 2 ) {
|
508 |
+
return array();
|
509 |
+
}
|
510 |
+
$args['current'] = (int)$args['current'];
|
511 |
+
$args['end_size'] = 0 < (int)$args['end_size'] ? (int)$args['end_size'] : 1; // Out of bounds? Make it the default.
|
512 |
+
$args['mid_size'] = 0 <= (int)$args['mid_size'] ? (int)$args['mid_size'] : 2;
|
513 |
+
$args['add_args'] = is_array( $args['add_args'] ) ? $args['add_args'] : false;
|
514 |
+
$page_links = array();
|
515 |
+
$dots = false;
|
516 |
+
if ( $args['prev_next'] && $args['current'] && 1 < $args['current'] ) {
|
517 |
+
$link = str_replace( '%_%', 2 == $args['current'] ? '' : $args['format'], $args['base'] );
|
518 |
+
$link = str_replace( '%#%', $args['current'] - 1, $link );
|
519 |
+
if ( $args['add_args'] ) {
|
520 |
+
$link = add_query_arg( $args['add_args'], $link );
|
521 |
+
}
|
522 |
+
$link .= $args['add_fragment'];
|
523 |
+
$link = untrailingslashit( $link );
|
524 |
+
$page_links[] = array(
|
525 |
+
'class' => 'prev page-numbers',
|
526 |
+
'link' => esc_url( apply_filters( 'paginate_links', $link ) ),
|
527 |
+
'title' => $args['prev_text']
|
528 |
+
);
|
529 |
+
}
|
530 |
+
for ( $n = 1; $n <= $args['total']; $n++ ) {
|
531 |
+
$n_display = number_format_i18n( $n );
|
532 |
+
if ( $n == $args['current'] ) {
|
533 |
+
$page_links[] = array(
|
534 |
+
'class' => 'page-number page-numbers current',
|
535 |
+
'title' => $n_display,
|
536 |
+
'text' => $n_display,
|
537 |
+
'name' => $n_display,
|
538 |
+
'current' => true
|
539 |
+
);
|
540 |
+
$dots = true;
|
541 |
+
} else {
|
542 |
+
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'] ) ) {
|
543 |
+
$link = str_replace( '%_%', 1 == $n ? '' : $args['format'], $args['base'] );
|
544 |
+
$link = str_replace( '%#%', $n, $link );
|
545 |
+
$link = trailingslashit( $link ) . ltrim( $args['add_fragment'], '/' );
|
546 |
+
if ( $args['add_args'] ) {
|
547 |
+
$link = rtrim( add_query_arg( $args['add_args'], $link ), '/' );
|
548 |
+
}
|
549 |
+
$link = str_replace(' ', '+', $link);
|
550 |
+
$link = untrailingslashit( $link );
|
551 |
+
$page_links[] = array(
|
552 |
+
'class' => 'page-number page-numbers',
|
553 |
+
'link' => esc_url( apply_filters( 'paginate_links', $link ) ),
|
554 |
+
'title' => $n_display,
|
555 |
+
'name' => $n_display,
|
556 |
+
'current' => $args['current'] == $n
|
557 |
+
);
|
558 |
+
$dots = true;
|
559 |
+
} elseif ( $dots && !$args['show_all'] ) {
|
560 |
+
$page_links[] = array(
|
561 |
+
'class' => 'dots',
|
562 |
+
'title' => __( '…' )
|
563 |
+
);
|
564 |
+
$dots = false;
|
565 |
+
}
|
566 |
+
}
|
567 |
+
}
|
568 |
+
if ( $args['prev_next'] && $args['current'] && ( $args['current'] < $args['total'] || -1 == $args['total'] ) ) {
|
569 |
+
$link = str_replace( '%_%', $args['format'], $args['base'] );
|
570 |
+
$link = str_replace( '%#%', $args['current'] + 1, $link );
|
571 |
+
if ( $args['add_args'] ) {
|
572 |
+
$link = add_query_arg( $args['add_args'], $link );
|
573 |
+
}
|
574 |
+
$link = untrailingslashit( trailingslashit( $link ) . $args['add_fragment'] );
|
575 |
+
$page_links[] = array(
|
576 |
+
'class' => 'next page-numbers',
|
577 |
+
'link' => esc_url( apply_filters( 'paginate_links', $link ) ),
|
578 |
+
'title' => $args['next_text']
|
579 |
+
);
|
580 |
+
}
|
581 |
+
return $page_links;
|
582 |
+
}
|
583 |
+
|
584 |
+
/* LEGACY These have since been re-organized; but keeping linkages for backwards-compatibility */
|
585 |
+
|
586 |
+
/**
|
587 |
+
* @deprecated
|
588 |
+
*/
|
589 |
+
static function get_image_path( $iid ) {
|
590 |
+
return TimberImageHelper::get_image_path( $iid );
|
591 |
+
}
|
592 |
+
|
593 |
+
/**
|
594 |
+
* @deprecated
|
595 |
+
*/
|
596 |
+
static function get_current_url() {
|
597 |
+
return TimberURLHelper::get_current_url();
|
598 |
+
}
|
599 |
+
|
600 |
+
/**
|
601 |
+
* @deprecated
|
602 |
+
*/
|
603 |
+
static function is_url( $url ) {
|
604 |
+
return TimberURLHelper::is_url( $url );
|
605 |
+
}
|
606 |
+
|
607 |
+
/**
|
608 |
+
* @deprecated
|
609 |
+
*/
|
610 |
+
static function get_path_base() {
|
611 |
+
return TimberURLHelper::get_path_base();
|
612 |
+
}
|
613 |
+
|
614 |
+
/**
|
615 |
+
* @deprecated
|
616 |
+
*/
|
617 |
+
static function get_rel_url( $url, $force = false ) {
|
618 |
+
return TimberURLHelper::get_rel_url( $url, $force );
|
619 |
+
}
|
620 |
+
|
621 |
+
/**
|
622 |
+
* @deprecated
|
623 |
+
*/
|
624 |
+
static function is_local( $url ) {
|
625 |
+
return TimberURLHelper::is_local( $url );
|
626 |
+
}
|
627 |
+
|
628 |
+
/**
|
629 |
+
* @deprecated
|
630 |
+
*/
|
631 |
+
static function get_full_path( $src ) {
|
632 |
+
return TimberURLHelper::get_full_path( $src );
|
633 |
+
}
|
634 |
+
|
635 |
+
/**
|
636 |
+
* @deprecated
|
637 |
+
*/
|
638 |
+
static function get_rel_path( $src ) {
|
639 |
+
return TimberURLHelper::get_rel_path( $src );
|
640 |
+
}
|
641 |
+
|
642 |
+
/**
|
643 |
+
* @deprecated
|
644 |
+
*/
|
645 |
+
static function remove_double_slashes( $url ) {
|
646 |
+
return TimberURLHelper::remove_double_slashes( $url );
|
647 |
+
}
|
648 |
+
|
649 |
+
/**
|
650 |
+
* @deprecated
|
651 |
+
*/
|
652 |
+
static function prepend_to_url( $url, $path ) {
|
653 |
+
return TimberURLHelper::prepend_to_url( $url, $path );
|
654 |
+
}
|
655 |
+
|
656 |
+
/**
|
657 |
+
* @deprecated
|
658 |
+
*/
|
659 |
+
static function preslashit( $path ) {
|
660 |
+
return TimberURLHelper::preslashit( $path );
|
661 |
+
}
|
662 |
+
|
663 |
+
/**
|
664 |
+
* @deprecated
|
665 |
+
*/
|
666 |
+
static function is_external( $url ) {
|
667 |
+
return TimberURLHelper::is_external( $url );
|
668 |
+
}
|
669 |
+
|
670 |
+
/**
|
671 |
+
* @deprecated
|
672 |
+
*/
|
673 |
+
static function download_url( $url, $timeout = 300 ) {
|
674 |
+
return TimberURLHelper::download_url( $url, $timeout );
|
675 |
+
}
|
676 |
+
|
677 |
+
/**
|
678 |
+
* @deprecated
|
679 |
+
*/
|
680 |
+
static function get_params( $i = -1 ) {
|
681 |
+
return TimberURLHelper::get_params( $i );
|
682 |
+
}
|
683 |
+
|
684 |
+
}
|
functions/functions/timber-image-helper.php
ADDED
@@ -0,0 +1,613 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require_once 'timber-image-retina-helper.php';
|
4 |
+
|
5 |
+
class TimberImageHelper {
|
6 |
+
|
7 |
+
static function add_actions() {
|
8 |
+
add_action( 'delete_post', function ( $post_id ) {
|
9 |
+
$post = get_post( $post_id );
|
10 |
+
$image_types = array( 'image/jpeg', 'image/png', 'image/gif', 'image/jpg' );
|
11 |
+
if ( $post->post_type == 'attachment' && in_array( $post->post_mime_type, $image_types ) ) {
|
12 |
+
TimberImageHelper::delete_resized_files_from_url( $post->guid );
|
13 |
+
TimberImageHelper::delete_letterboxed_files_from_url( $post->guid );
|
14 |
+
}
|
15 |
+
} );
|
16 |
+
}
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Adds a constant defining the path to the content directory relative to the site
|
20 |
+
* for example /wp-content or /content
|
21 |
+
*/
|
22 |
+
static function add_constants() {
|
23 |
+
if ( !defined( 'WP_CONTENT_SUBDIR' ) ) {
|
24 |
+
$wp_content_path = str_replace( home_url(), '', WP_CONTENT_URL );
|
25 |
+
define( 'WP_CONTENT_SUBDIR', $wp_content_path );
|
26 |
+
}
|
27 |
+
}
|
28 |
+
|
29 |
+
static function add_filters() {
|
30 |
+
add_filter( 'upload_dir', function ( $arr ) {
|
31 |
+
$arr['relative'] = str_replace( home_url(), '', $arr['baseurl'] );
|
32 |
+
return $arr;
|
33 |
+
} );
|
34 |
+
}
|
35 |
+
|
36 |
+
/**
|
37 |
+
*
|
38 |
+
*
|
39 |
+
* @param string $hexstr
|
40 |
+
* @return array
|
41 |
+
*/
|
42 |
+
public static function hexrgb( $hexstr ) {
|
43 |
+
if ( !strstr( $hexstr, '#' ) ) {
|
44 |
+
$hexstr = '#' . $hexstr;
|
45 |
+
}
|
46 |
+
if ( strlen( $hexstr ) == 4 ) {
|
47 |
+
$hexstr = '#' . $hexstr[1] . $hexstr[1] . $hexstr[2] . $hexstr[2] . $hexstr[3] . $hexstr[3];
|
48 |
+
}
|
49 |
+
$int = hexdec( $hexstr );
|
50 |
+
return array( "red" => 0xFF & ( $int >> 0x10 ), "green" => 0xFF & ( $int >> 0x8 ), "blue" => 0xFF & $int );
|
51 |
+
}
|
52 |
+
|
53 |
+
static function delete_resized_files_from_url( $src ) {
|
54 |
+
$local = TimberURLHelper::url_to_file_system( $src );
|
55 |
+
self::delete_resized_files( $local );
|
56 |
+
}
|
57 |
+
|
58 |
+
static function delete_letterboxed_files_from_url( $src ) {
|
59 |
+
$local = TimberURLHelper::url_to_file_system( $src );
|
60 |
+
self::delete_letterboxed_files( $local );
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
*
|
65 |
+
*
|
66 |
+
* @param string $local_file
|
67 |
+
*/
|
68 |
+
static function delete_resized_files( $local_file ) {
|
69 |
+
$info = pathinfo( $local_file );
|
70 |
+
$dir = $info['dirname'];
|
71 |
+
$ext = $info['extension'];
|
72 |
+
$filename = $info['filename'];
|
73 |
+
$searcher = '/' . $filename . '-[0-9999999]*';
|
74 |
+
foreach ( glob( $dir . $searcher ) as $found_file ) {
|
75 |
+
$regexdir = str_replace( '/', '\/', $dir );
|
76 |
+
$pattern = '/' . ( $regexdir ) . '\/' . $filename . '-[0-9]*x[0-9]*-c-[a-z]*.' . $ext . '/';
|
77 |
+
$match = preg_match( $pattern, $found_file );
|
78 |
+
//keeping these here so I know what the hell we're matching
|
79 |
+
//$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);
|
80 |
+
//$match = preg_match("/\/srv\/www\/wordpress-develop\/src\/wp-content\/uploads\/2014\/05\/arch-[0-9]*x[0-9]*-c-[a-z]*.jpg/", $filename);
|
81 |
+
if ( $match ) {
|
82 |
+
unlink( $found_file );
|
83 |
+
}
|
84 |
+
}
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
*
|
89 |
+
*
|
90 |
+
* @param string $local_file
|
91 |
+
*/
|
92 |
+
static function delete_letterboxed_files( $local_file ) {
|
93 |
+
$info = pathinfo( $local_file );
|
94 |
+
$dir = $info['dirname'];
|
95 |
+
$ext = $info['extension'];
|
96 |
+
$filename = $info['filename'];
|
97 |
+
$searcher = '/' . $filename . '-lbox-[0-9999999]*';
|
98 |
+
foreach ( glob( $dir . $searcher ) as $found_file ) {
|
99 |
+
$regexdir = str_replace( '/', '\/', $dir );
|
100 |
+
$pattern = '/' . ( $regexdir ) . '\/' . $filename . '-lbox-[0-9]*x[0-9]*-[a-zA-Z0-9]*.' . $ext . '/';
|
101 |
+
$match = preg_match( $pattern, $found_file );
|
102 |
+
if ( $match ) {
|
103 |
+
unlink( $found_file );
|
104 |
+
}
|
105 |
+
}
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
*
|
110 |
+
*
|
111 |
+
* @param string $src
|
112 |
+
* @param int $w
|
113 |
+
* @param int $h
|
114 |
+
* @param string $color
|
115 |
+
* @return string
|
116 |
+
*/
|
117 |
+
public static function get_letterbox_file_rel( $src, $w, $h, $color ) {
|
118 |
+
if ( !strlen( $src ) ) {
|
119 |
+
return null;
|
120 |
+
}
|
121 |
+
$new_path = self::get_letterbox_file_name_relative_to_content( $src, $w, $h, $color );
|
122 |
+
return WP_CONTENT_SUBDIR . $new_path;
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
*
|
127 |
+
*
|
128 |
+
* @param string $src The src of an image can be absolute, relative or server location
|
129 |
+
* @return mixed|null
|
130 |
+
*/
|
131 |
+
static function get_directory_relative_to_content( $src ) {
|
132 |
+
if ( !strlen( $src ) ) {
|
133 |
+
return null;
|
134 |
+
}
|
135 |
+
if ( !strlen( $src ) ) {
|
136 |
+
return null;
|
137 |
+
}
|
138 |
+
$abs = false;
|
139 |
+
if ( strstr( $src, 'http' ) ) {
|
140 |
+
$abs = true;
|
141 |
+
}
|
142 |
+
$path_parts = pathinfo( $src );
|
143 |
+
if ( $abs ) {
|
144 |
+
$dir_relative_to_content = str_replace( WP_CONTENT_URL, '', $path_parts['dirname'] );
|
145 |
+
} else {
|
146 |
+
$dir_relative_to_content = str_replace( WP_CONTENT_DIR, '', $path_parts['dirname'] );
|
147 |
+
$dir_relative_to_content = str_replace( WP_CONTENT_SUBDIR, '', $dir_relative_to_content );
|
148 |
+
}
|
149 |
+
return $dir_relative_to_content;
|
150 |
+
}
|
151 |
+
|
152 |
+
/**
|
153 |
+
*
|
154 |
+
*
|
155 |
+
* @param string $src
|
156 |
+
* @param int $w
|
157 |
+
* @param int $h
|
158 |
+
* @param string $color
|
159 |
+
* @return string
|
160 |
+
*/
|
161 |
+
static function get_letterbox_file_name_relative_to_content( $src, $w, $h, $color ) {
|
162 |
+
$path_parts = pathinfo( $src );
|
163 |
+
$dir_relative_to_content = self::get_directory_relative_to_content( $src );
|
164 |
+
$color = str_replace( '#', '', $color );
|
165 |
+
$newbase = $path_parts['filename'] . '-lbox-' . $w . 'x' . $h . '-' . $color;
|
166 |
+
$new_name = $newbase . '.' . $path_parts['extension'];
|
167 |
+
return $dir_relative_to_content . '/' . $new_name;
|
168 |
+
}
|
169 |
+
|
170 |
+
/**
|
171 |
+
*
|
172 |
+
*
|
173 |
+
* @param string $src
|
174 |
+
* @param int $w
|
175 |
+
* @param int $h
|
176 |
+
* @param string $color
|
177 |
+
* @return string
|
178 |
+
*/
|
179 |
+
public static function get_letterbox_file_path( $src, $w, $h, $color ) {
|
180 |
+
$new_name = self::get_letterbox_file_name_relative_to_content( $src, $w, $h, $color );
|
181 |
+
$new_server_path = WP_CONTENT_DIR . $new_name;
|
182 |
+
$new_server_path = TimberURLHelper::remove_double_slashes( $new_server_path );
|
183 |
+
return $new_server_path;
|
184 |
+
}
|
185 |
+
|
186 |
+
/**
|
187 |
+
*
|
188 |
+
*
|
189 |
+
* @param string $src
|
190 |
+
* @param int $w
|
191 |
+
* @param int $h
|
192 |
+
* @param string $crop
|
193 |
+
* @return string
|
194 |
+
*/
|
195 |
+
static function get_resize_file_rel( $src, $w, $h, $crop ) {
|
196 |
+
if ( !strlen( $src ) ) {
|
197 |
+
return null;
|
198 |
+
}
|
199 |
+
$new_path = self::get_resize_file_name_relative_to_content( $src, $w, $h, $crop );
|
200 |
+
return WP_CONTENT_SUBDIR . $new_path;
|
201 |
+
}
|
202 |
+
|
203 |
+
/**
|
204 |
+
*
|
205 |
+
*
|
206 |
+
* @param string $src
|
207 |
+
* @param int $w
|
208 |
+
* @param int $h
|
209 |
+
* @param string $crop
|
210 |
+
* @return string
|
211 |
+
*/
|
212 |
+
static function get_resize_file_name_relative_to_content( $src, $w, $h, $crop ) {
|
213 |
+
$path_parts = pathinfo( $src );
|
214 |
+
$dir_relative_to_content = self::get_directory_relative_to_content( $src );
|
215 |
+
$newbase = $path_parts['filename'] . '-' . $w . 'x' . $h . '-c-' . ( $crop ? $crop : 'f' ); // Crop will be either user named or f (false)
|
216 |
+
$new_name = $newbase . '.' . $path_parts['extension'];
|
217 |
+
return $dir_relative_to_content . '/' . $new_name;
|
218 |
+
}
|
219 |
+
|
220 |
+
/**
|
221 |
+
*
|
222 |
+
*
|
223 |
+
* @param string $src
|
224 |
+
*/
|
225 |
+
public static function in_uploads( $src ) {
|
226 |
+
$upload_dir = wp_upload_dir();
|
227 |
+
if ( strstr( $src, $upload_dir['relative'] ) ) {
|
228 |
+
return true;
|
229 |
+
}
|
230 |
+
return false;
|
231 |
+
}
|
232 |
+
|
233 |
+
/**
|
234 |
+
*
|
235 |
+
*
|
236 |
+
* @param string $src
|
237 |
+
* @param int $w
|
238 |
+
* @param int $h
|
239 |
+
* @param string $crop
|
240 |
+
* @return string
|
241 |
+
*/
|
242 |
+
static function get_resize_file_path( $src, $w, $h, $crop ) {
|
243 |
+
$new_name = self::get_resize_file_name_relative_to_content( $src, $w, $h, $crop );
|
244 |
+
$new_server_path = WP_CONTENT_DIR . $new_name;
|
245 |
+
$new_server_path = TimberURLHelper::remove_double_slashes( $new_server_path );
|
246 |
+
return $new_server_path;
|
247 |
+
}
|
248 |
+
|
249 |
+
/**
|
250 |
+
*
|
251 |
+
*
|
252 |
+
* @param int $iid
|
253 |
+
* @return string
|
254 |
+
*/
|
255 |
+
public static function get_image_path( $iid ) {
|
256 |
+
$size = 'full';
|
257 |
+
$src = wp_get_attachment_image_src( $iid, $size );
|
258 |
+
$src = $src[0];
|
259 |
+
return self::get_rel_path( $src );
|
260 |
+
}
|
261 |
+
|
262 |
+
/**
|
263 |
+
*
|
264 |
+
*
|
265 |
+
* @param string $url
|
266 |
+
*/
|
267 |
+
public static function get_server_location( $url ) {
|
268 |
+
if ( strpos( $url, ABSPATH ) === 0 ) {
|
269 |
+
return $url;
|
270 |
+
}
|
271 |
+
$upload_dir = wp_upload_dir();
|
272 |
+
$abs = false;
|
273 |
+
if ( strstr( $url, 'http' ) ) {
|
274 |
+
$abs = true;
|
275 |
+
}
|
276 |
+
if ( self::in_uploads( $url ) ) {
|
277 |
+
if ( $abs ) {
|
278 |
+
$relative_to_uploads_dir = str_replace( $upload_dir['baseurl'], '', $url );
|
279 |
+
} else {
|
280 |
+
$relative_to_uploads_dir = str_replace( $upload_dir['relative'], '', $url );
|
281 |
+
}
|
282 |
+
return $upload_dir['basedir'] . $relative_to_uploads_dir;
|
283 |
+
} else {
|
284 |
+
if ( $abs ) {
|
285 |
+
$relative_to_wp_content = str_replace( WP_CONTENT_URL, '', $url );
|
286 |
+
} else {
|
287 |
+
$relative_to_wp_content = str_replace( WP_CONTENT_SUBDIR, '', $url );
|
288 |
+
}
|
289 |
+
return WP_CONTENT_DIR . $relative_to_wp_content;
|
290 |
+
}
|
291 |
+
}
|
292 |
+
|
293 |
+
/**
|
294 |
+
*
|
295 |
+
*
|
296 |
+
* @param string $src
|
297 |
+
* @param int $w
|
298 |
+
* @param int $h
|
299 |
+
* @param string $color
|
300 |
+
* @param bool $force
|
301 |
+
* @return mixed|null|string
|
302 |
+
*/
|
303 |
+
public static function letterbox( $src, $w, $h, $color = '#000000', $force = false ) {
|
304 |
+
if ( strstr( $src, 'http' ) && !strstr( $src, home_url() ) ) {
|
305 |
+
$src = self::sideload_image( $src );
|
306 |
+
}
|
307 |
+
$abs = false;
|
308 |
+
if ( strstr( $src, 'http' ) ) {
|
309 |
+
$abs = true;
|
310 |
+
}
|
311 |
+
$new_file_rel = self::get_letterbox_file_rel( $src, $w, $h, $color );
|
312 |
+
$new_server_path = self::get_letterbox_file_path( $src, $w, $h, $color );
|
313 |
+
$old_server_path = self::get_server_location( $src );
|
314 |
+
$old_server_path = TimberURLHelper::remove_double_slashes( $old_server_path );
|
315 |
+
$new_server_path = TimberURLHelper::remove_double_slashes( $new_server_path );
|
316 |
+
if ( file_exists( $new_server_path ) && !$force ) {
|
317 |
+
if ( $abs ) {
|
318 |
+
return untrailingslashit( home_url() ) . $new_file_rel;
|
319 |
+
} else {
|
320 |
+
return TimberURLHelper::preslashit( $new_file_rel );
|
321 |
+
}
|
322 |
+
}
|
323 |
+
$bg = imagecreatetruecolor( $w, $h );
|
324 |
+
$c = self::hexrgb( $color );
|
325 |
+
$white = imagecolorallocate( $bg, $c['red'], $c['green'], $c['blue'] );
|
326 |
+
imagefill( $bg, 0, 0, $white );
|
327 |
+
$image = wp_get_image_editor( $old_server_path );
|
328 |
+
if ( !is_wp_error( $image ) ) {
|
329 |
+
$current_size = $image->get_size();
|
330 |
+
$ow = $current_size['width'];
|
331 |
+
$oh = $current_size['height'];
|
332 |
+
$new_aspect = $w / $h;
|
333 |
+
$old_aspect = $ow / $oh;
|
334 |
+
if ( $new_aspect > $old_aspect ) {
|
335 |
+
//taller than goal
|
336 |
+
$h_scale = $h / $oh;
|
337 |
+
$owt = $ow * $h_scale;
|
338 |
+
$y = 0;
|
339 |
+
$x = $w / 2 - $owt / 2;
|
340 |
+
$oht = $h;
|
341 |
+
$image->crop( 0, 0, $ow, $oh, $owt, $oht );
|
342 |
+
} else {
|
343 |
+
$w_scale = $w / $ow;
|
344 |
+
$oht = $oh * $w_scale;
|
345 |
+
$x = 0;
|
346 |
+
$y = $h / 2 - $oht / 2;
|
347 |
+
$owt = $w;
|
348 |
+
$image->crop( 0, 0, $ow, $oh, $owt, $oht );
|
349 |
+
}
|
350 |
+
$image->save( $new_server_path );
|
351 |
+
$func = 'imagecreatefromjpeg';
|
352 |
+
$ext = pathinfo( $new_server_path, PATHINFO_EXTENSION );
|
353 |
+
if ( $ext == 'gif' ) {
|
354 |
+
$func = 'imagecreatefromgif';
|
355 |
+
} else if ( $ext == 'png' ) {
|
356 |
+
$func = 'imagecreatefrompng';
|
357 |
+
}
|
358 |
+
$image = $func( $new_server_path );
|
359 |
+
imagecopy( $bg, $image, $x, $y, 0, 0, $owt, $oht );
|
360 |
+
imagejpeg( $bg, $new_server_path );
|
361 |
+
$new_relative_path = TimberURLHelper::get_rel_path( $new_server_path );
|
362 |
+
if ( $abs ) {
|
363 |
+
return home_url( $new_relative_path );
|
364 |
+
}
|
365 |
+
return $new_relative_path;
|
366 |
+
} else {
|
367 |
+
TimberHelper::error_log( $image );
|
368 |
+
}
|
369 |
+
return null;
|
370 |
+
}
|
371 |
+
|
372 |
+
/**
|
373 |
+
*
|
374 |
+
*
|
375 |
+
* @param string $src a url or path to the image (http://example.org/wp-content/uploads/2014/image.jpg) or (/wp-content/uploads/2014/image.jpg)
|
376 |
+
* @param string $bghex
|
377 |
+
* @return string
|
378 |
+
*/
|
379 |
+
public static function img_to_jpg( $src, $bghex = '#FFFFFF' ) {
|
380 |
+
$path = str_replace( home_url(), '', $src );
|
381 |
+
$output = str_replace( '.png', '.jpg', $path );
|
382 |
+
$input_file = self::get_server_location( $path );
|
383 |
+
$output_file = self::get_server_location( $output );
|
384 |
+
if ( file_exists( $output_file ) ) {
|
385 |
+
return $output;
|
386 |
+
}
|
387 |
+
$filename = $output;
|
388 |
+
$input = imagecreatefrompng( $input_file );
|
389 |
+
list( $width, $height ) = getimagesize( $input_file );
|
390 |
+
$output = imagecreatetruecolor( $width, $height );
|
391 |
+
$c = self::hexrgb( $bghex );
|
392 |
+
$white = imagecolorallocate( $output, $c['red'], $c['green'], $c['blue'] );
|
393 |
+
imagefilledrectangle( $output, 0, 0, $width, $height, $white );
|
394 |
+
imagecopy( $output, $input, 0, 0, 0, 0, $width, $height );
|
395 |
+
imagejpeg( $output, $output_file );
|
396 |
+
return $filename;
|
397 |
+
}
|
398 |
+
|
399 |
+
/**
|
400 |
+
*
|
401 |
+
*
|
402 |
+
* @param string $file
|
403 |
+
* @return string
|
404 |
+
*/
|
405 |
+
public static function get_sideloaded_file_loc( $file ) {
|
406 |
+
$upload = wp_upload_dir();
|
407 |
+
$dir = $upload['path'];
|
408 |
+
$filename = $file;
|
409 |
+
$file = parse_url( $file );
|
410 |
+
$path_parts = pathinfo( $file['path'] );
|
411 |
+
$basename = md5( $filename );
|
412 |
+
$ext = 'jpg';
|
413 |
+
if ( isset( $path_parts['extension'] ) ) {
|
414 |
+
$ext = $path_parts['extension'];
|
415 |
+
}
|
416 |
+
return $dir . '/' . $basename . '.' . $ext;
|
417 |
+
}
|
418 |
+
|
419 |
+
/**
|
420 |
+
*
|
421 |
+
*
|
422 |
+
* @param string $file
|
423 |
+
* @return string
|
424 |
+
*/
|
425 |
+
public static function sideload_image( $file ) {
|
426 |
+
$loc = self::get_sideloaded_file_loc( $file );
|
427 |
+
if ( file_exists( $loc ) ) {
|
428 |
+
return TimberURLHelper::preslashit( TimberURLHelper::get_rel_path( $loc ) );
|
429 |
+
}
|
430 |
+
// Download file to temp location
|
431 |
+
if ( !function_exists( 'download_url' ) ) {
|
432 |
+
require_once ABSPATH . '/wp-admin/includes/file.php';
|
433 |
+
}
|
434 |
+
$tmp = download_url( $file );
|
435 |
+
preg_match( '/[^\?]+\.(jpe?g|jpe|gif|png)\b/i', $file, $matches );
|
436 |
+
$file_array = array();
|
437 |
+
$file_array['name'] = basename( $matches[0] );
|
438 |
+
$file_array['tmp_name'] = $tmp;
|
439 |
+
// If error storing temporarily, unlink
|
440 |
+
if ( is_wp_error( $tmp ) ) {
|
441 |
+
@unlink( $file_array['tmp_name'] );
|
442 |
+
$file_array['tmp_name'] = '';
|
443 |
+
}
|
444 |
+
// do the validation and storage stuff
|
445 |
+
$locinfo = pathinfo( $loc );
|
446 |
+
$file = wp_upload_bits( $locinfo['basename'], null, file_get_contents( $file_array['tmp_name'] ) );
|
447 |
+
return $file['url'];
|
448 |
+
}
|
449 |
+
|
450 |
+
/**
|
451 |
+
*
|
452 |
+
*
|
453 |
+
* @param string $src
|
454 |
+
* @param float $multiplier
|
455 |
+
*/
|
456 |
+
public static function retina_resize( $src, $factor = 2 ) {
|
457 |
+
if ( empty( $src ) ) {
|
458 |
+
return '';
|
459 |
+
}
|
460 |
+
$abs = false;
|
461 |
+
if ( strstr( $src, 'http' ) ) {
|
462 |
+
$abs = true;
|
463 |
+
}
|
464 |
+
if ( strstr( $src, 'http' ) && !strstr( $src, home_url() ) ) {
|
465 |
+
$src = self::sideload_image( $src );
|
466 |
+
}
|
467 |
+
$old_server_path = self::get_server_location( $src );
|
468 |
+
$new_path = TimberImageRetinaHelper::get_retina_file_rel( $src, $factor );
|
469 |
+
$new_server_path = TimberImageRetinaHelper::get_retina_file_path( $src, $factor );
|
470 |
+
|
471 |
+
$old_server_path = TimberURLHelper::remove_double_slashes( $old_server_path );
|
472 |
+
$new_server_path = TimberURLHelper::remove_double_slashes( $new_server_path );
|
473 |
+
if ( file_exists( $new_server_path ) ) {
|
474 |
+
if ( !$abs ) {
|
475 |
+
return TimberURLHelper::preslashit( $new_path );
|
476 |
+
}
|
477 |
+
return untrailingslashit( home_url() ) . $new_path;
|
478 |
+
}
|
479 |
+
$image = wp_get_image_editor( $old_server_path );
|
480 |
+
if ( !is_wp_error( $image ) ) {
|
481 |
+
$current_size = $image->get_size();
|
482 |
+
|
483 |
+
$src_w = $current_size['width'];
|
484 |
+
$src_h = $current_size['height'];
|
485 |
+
|
486 |
+
$src_ratio = $src_w / $src_h;
|
487 |
+
|
488 |
+
// Get ratios
|
489 |
+
$w = $src_w * $factor;
|
490 |
+
$h = $src_h * $factor;
|
491 |
+
$image->crop( 0, 0, $src_w, $src_h, $w, $h );
|
492 |
+
$result = $image->save( $new_server_path );
|
493 |
+
return $new_path;
|
494 |
+
}
|
495 |
+
return $src;
|
496 |
+
|
497 |
+
}
|
498 |
+
|
499 |
+
/**
|
500 |
+
*
|
501 |
+
*
|
502 |
+
* @param string $src
|
503 |
+
* @param int $w
|
504 |
+
* @param int $h
|
505 |
+
* @param string $crop
|
506 |
+
* @param bool $force_resize
|
507 |
+
* @return string
|
508 |
+
*/
|
509 |
+
public static function resize( $src, $w, $h = 0, $crop = 'default', $force_resize = false ) {
|
510 |
+
if ( empty( $src ) ) {
|
511 |
+
return '';
|
512 |
+
}
|
513 |
+
if ( strstr( $src, 'http' ) && !strstr( $src, home_url() ) ) {
|
514 |
+
$src = self::sideload_image( $src );
|
515 |
+
}
|
516 |
+
$abs = false;
|
517 |
+
if ( strstr( $src, 'http' ) ) {
|
518 |
+
$abs = true;
|
519 |
+
}
|
520 |
+
// Sanitize crop position
|
521 |
+
$allowed_crop_positions = array( 'default', 'center', 'top', 'bottom', 'left', 'right' );
|
522 |
+
if ( $crop !== false && !in_array( $crop, $allowed_crop_positions ) ) {
|
523 |
+
$crop = $allowed_crop_positions[0];
|
524 |
+
}
|
525 |
+
//oh good, it's a relative image in the uploads folder!
|
526 |
+
$new_path = self::get_resize_file_rel( $src, $w, $h, $crop );
|
527 |
+
$new_server_path = self::get_resize_file_path( $src, $w, $h, $crop );
|
528 |
+
$old_server_path = self::get_server_location( $src );
|
529 |
+
$old_server_path = TimberURLHelper::remove_double_slashes( $old_server_path );
|
530 |
+
$new_server_path = TimberURLHelper::remove_double_slashes( $new_server_path );
|
531 |
+
if ( file_exists( $new_server_path ) ) {
|
532 |
+
if ( $force_resize ) {
|
533 |
+
// Force resize - warning: will regenerate the image on every pageload, use for testing purposes only!
|
534 |
+
unlink( $new_server_path );
|
535 |
+
} else {
|
536 |
+
if ( !$abs ) {
|
537 |
+
return TimberURLHelper::preslashit( $new_path );
|
538 |
+
}
|
539 |
+
return untrailingslashit( home_url() ) . $new_path;
|
540 |
+
}
|
541 |
+
}
|
542 |
+
$image = wp_get_image_editor( $old_server_path );
|
543 |
+
|
544 |
+
if ( !is_wp_error( $image ) ) {
|
545 |
+
$current_size = $image->get_size();
|
546 |
+
|
547 |
+
$src_w = $current_size['width'];
|
548 |
+
$src_h = $current_size['height'];
|
549 |
+
|
550 |
+
$src_ratio = $src_w / $src_h;
|
551 |
+
if ( !$h ) {
|
552 |
+
$h = round( $w / $src_ratio );
|
553 |
+
}
|
554 |
+
if ( !$w ) {
|
555 |
+
//the user wants to resize based on constant height
|
556 |
+
$w = round( $h * $src_ratio );
|
557 |
+
}
|
558 |
+
// Get ratios
|
559 |
+
$dest_ratio = $w / $h;
|
560 |
+
$src_wt = $src_h * $dest_ratio;
|
561 |
+
$src_ht = $src_w / $dest_ratio;
|
562 |
+
|
563 |
+
if ( !$crop ) {
|
564 |
+
// Always crop, to allow resizing upwards
|
565 |
+
$image->crop( 0, 0, $src_w, $src_h, $w, $h );
|
566 |
+
} else {
|
567 |
+
//start with defaults:
|
568 |
+
$src_x = $src_w / 2 - $src_wt / 2;
|
569 |
+
$src_y = ( $src_h - $src_ht ) / 6;
|
570 |
+
//now specific overrides based on options:
|
571 |
+
if ( $crop == 'center' ) {
|
572 |
+
// Get source x and y
|
573 |
+
$src_x = round( ( $src_w - $src_wt ) / 2 );
|
574 |
+
$src_y = round( ( $src_h - $src_ht ) / 2 );
|
575 |
+
} else if ( $crop == 'top' ) {
|
576 |
+
$src_y = 0;
|
577 |
+
} else if ( $crop == 'bottom' ) {
|
578 |
+
$src_y = $src_h - $src_ht;
|
579 |
+
} else if ( $crop == 'left' ) {
|
580 |
+
$src_x = 0;
|
581 |
+
} else if ( $crop == 'right' ) {
|
582 |
+
$src_x = $src_w - $src_wt;
|
583 |
+
}
|
584 |
+
|
585 |
+
// Crop the image
|
586 |
+
if ( $dest_ratio > $src_ratio ) {
|
587 |
+
$image->crop( 0, $src_y, $src_w, $src_ht, $w, $h );
|
588 |
+
} else {
|
589 |
+
$image->crop( $src_x, 0, $src_wt, $src_h, $w, $h );
|
590 |
+
}
|
591 |
+
|
592 |
+
}
|
593 |
+
$result = $image->save( $new_server_path );
|
594 |
+
if ( is_wp_error( $result ) ) {
|
595 |
+
error_log( 'Error resizing image' );
|
596 |
+
error_log( print_r( $result, true ) );
|
597 |
+
}
|
598 |
+
if ( $abs ) {
|
599 |
+
return untrailingslashit( home_url() ) . $new_path;
|
600 |
+
}
|
601 |
+
return $new_path;
|
602 |
+
} else if ( isset( $image->error_data['error_loading_image'] ) ) {
|
603 |
+
TimberHelper::error_log( 'Error loading ' . $image->error_data['error_loading_image'] );
|
604 |
+
} else {
|
605 |
+
TimberHelper::error_log( $image );
|
606 |
+
}
|
607 |
+
return $src;
|
608 |
+
}
|
609 |
+
}
|
610 |
+
|
611 |
+
TimberImageHelper::add_constants();
|
612 |
+
TimberImageHelper::add_actions();
|
613 |
+
TimberImageHelper::add_filters();
|
functions/functions/timber-image-retina-helper.php
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TimberImageRetinaHelper {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* @param string $src
|
7 |
+
* @param int $w
|
8 |
+
* @param int $h
|
9 |
+
* @param string $crop
|
10 |
+
* @return string
|
11 |
+
*/
|
12 |
+
static function get_retina_file_path( $src, $mult = 2 ) {
|
13 |
+
$new_name = self::get_retina_file_name_relative_to_content( $src, $mult );
|
14 |
+
$new_server_path = WP_CONTENT_DIR . $new_name;
|
15 |
+
$new_server_path = TimberURLHelper::remove_double_slashes( $new_server_path );
|
16 |
+
return $new_server_path;
|
17 |
+
}
|
18 |
+
|
19 |
+
|
20 |
+
/**
|
21 |
+
*
|
22 |
+
*
|
23 |
+
* @param string $src
|
24 |
+
* @param int $w
|
25 |
+
* @param int $h
|
26 |
+
* @param string $crop
|
27 |
+
* @return string
|
28 |
+
*/
|
29 |
+
public static function get_retina_file_rel( $src, $factor = 2 ) {
|
30 |
+
if ( !strlen( $src ) ) {
|
31 |
+
return null;
|
32 |
+
}
|
33 |
+
$new_path = self::get_retina_file_name_relative_to_content( $src, $factor );
|
34 |
+
return WP_CONTENT_SUBDIR . $new_path;
|
35 |
+
}
|
36 |
+
|
37 |
+
/**
|
38 |
+
*
|
39 |
+
*
|
40 |
+
* @param string $src
|
41 |
+
* @param int $w
|
42 |
+
* @param int $h
|
43 |
+
* @param string $crop
|
44 |
+
* @return string
|
45 |
+
*/
|
46 |
+
private static function get_retina_file_name_relative_to_content( $src, $mult = 2 ) {
|
47 |
+
$path_parts = pathinfo( $src );
|
48 |
+
$dir_relative_to_content = TimberImageHelper::get_directory_relative_to_content( $src );
|
49 |
+
$newbase = $path_parts['filename'] . '@' . $mult . 'x'; // add @2x, @3x, @1.5x, etc.
|
50 |
+
$new_name = $newbase . '.' . $path_parts['extension'];
|
51 |
+
return $dir_relative_to_content . '/' . $new_name;
|
52 |
+
}
|
53 |
+
|
54 |
+
}
|
functions/functions/timber-image.php
ADDED
@@ -0,0 +1,309 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TimberImage extends TimberPost implements TimberCoreInterface {
|
4 |
+
|
5 |
+
public $_can_edit;
|
6 |
+
public $_dimensions;
|
7 |
+
public $abs_url;
|
8 |
+
public $PostClass = 'TimberPost';
|
9 |
+
public $object_type = 'image';
|
10 |
+
|
11 |
+
public static $representation = 'image';
|
12 |
+
|
13 |
+
public $file_loc;
|
14 |
+
public $file;
|
15 |
+
public $sizes = array();
|
16 |
+
public $post_parent;
|
17 |
+
public $caption;
|
18 |
+
public $_wp_attached_file;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @param int $iid
|
22 |
+
*/
|
23 |
+
function __construct($iid) {
|
24 |
+
$this->init($iid);
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @return string
|
29 |
+
*/
|
30 |
+
function __toString() {
|
31 |
+
if ($this->get_src()) {
|
32 |
+
return $this->get_src();
|
33 |
+
}
|
34 |
+
return '';
|
35 |
+
}
|
36 |
+
|
37 |
+
/**
|
38 |
+
* @return mixed
|
39 |
+
*/
|
40 |
+
function get_pathinfo() {
|
41 |
+
return pathinfo($this->file);
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* @param string $dim
|
46 |
+
* @return array|int
|
47 |
+
*/
|
48 |
+
function get_dimensions($dim = null) {
|
49 |
+
if (isset($this->_dimensions)) {
|
50 |
+
return $this->get_dimensions_loaded($dim);
|
51 |
+
}
|
52 |
+
list($width, $height) = getimagesize($this->file_loc);
|
53 |
+
$this->_dimensions = array();
|
54 |
+
$this->_dimensions[0] = $width;
|
55 |
+
$this->_dimensions[1] = $height;
|
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 |
+
}
|
136 |
+
|
137 |
+
/**
|
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 = false ) {
|
167 |
+
if ( !is_numeric( $iid ) && is_string( $iid ) ) {
|
168 |
+
if (strstr($iid, '://')) {
|
169 |
+
$this->init_with_url($iid);
|
170 |
+
return;
|
171 |
+
}
|
172 |
+
if ( strstr($iid, ABSPATH) ) {
|
173 |
+
$this->init_with_file_path($iid);
|
174 |
+
return;
|
175 |
+
}
|
176 |
+
if (strstr(strtolower($iid), '.jpg')) {
|
177 |
+
$this->init_with_relative_path($iid);
|
178 |
+
return;
|
179 |
+
}
|
180 |
+
}
|
181 |
+
|
182 |
+
$image_info = $this->get_image_info($iid);
|
183 |
+
|
184 |
+
$this->import($image_info);
|
185 |
+
$basedir = self::wp_upload_dir();
|
186 |
+
$basedir = $basedir['basedir'];
|
187 |
+
if (isset($this->file)) {
|
188 |
+
$this->file_loc = $basedir . DIRECTORY_SEPARATOR . $this->file;
|
189 |
+
} else if (isset($this->_wp_attached_file)) {
|
190 |
+
$this->file = reset($this->_wp_attached_file);
|
191 |
+
$this->file_loc = $basedir . DIRECTORY_SEPARATOR . $this->file;
|
192 |
+
}
|
193 |
+
if (isset($image_info['id'])) {
|
194 |
+
$this->ID = $image_info['id'];
|
195 |
+
} else if (is_numeric($iid)) {
|
196 |
+
$this->ID = $iid;
|
197 |
+
}
|
198 |
+
if (isset($this->ID)) {
|
199 |
+
$custom = get_post_custom($this->ID);
|
200 |
+
foreach ($custom as $key => $value) {
|
201 |
+
$this->$key = $value[0];
|
202 |
+
}
|
203 |
+
} else {
|
204 |
+
if (is_array($iid)) {
|
205 |
+
TimberHelper::error_log('Not able to init in TimberImage with iid=');
|
206 |
+
TimberHelper::error_log($iid);
|
207 |
+
} else {
|
208 |
+
TimberHelper::error_log('Not able to init in TimberImage with iid=' . $iid);
|
209 |
+
}
|
210 |
+
}
|
211 |
+
}
|
212 |
+
|
213 |
+
private function get_image_info( $iid ) {
|
214 |
+
$image_info = $iid;
|
215 |
+
if (is_numeric($iid)) {
|
216 |
+
$image_info = wp_get_attachment_metadata($iid);
|
217 |
+
if (!is_array($image_info)) {
|
218 |
+
$image_info = array();
|
219 |
+
}
|
220 |
+
$image_custom = get_post_custom($iid);
|
221 |
+
$basic = get_post($iid);
|
222 |
+
if ($basic) {
|
223 |
+
if (isset($basic->post_excerpt)) {
|
224 |
+
$this->caption = $basic->post_excerpt;
|
225 |
+
}
|
226 |
+
$image_custom = array_merge($image_custom, get_object_vars($basic));
|
227 |
+
}
|
228 |
+
return array_merge($image_info, $image_custom);
|
229 |
+
}
|
230 |
+
if (is_array($image_info) && isset($image_info['image'])) {
|
231 |
+
return $image_info['image'];
|
232 |
+
}
|
233 |
+
if (is_object($image_info)) {
|
234 |
+
return get_object_vars($image_info);
|
235 |
+
}
|
236 |
+
return $iid;
|
237 |
+
}
|
238 |
+
|
239 |
+
private function init_with_relative_path( $relative_path ) {
|
240 |
+
$this->abs_url = home_url( $relative_path );
|
241 |
+
$file_path = TimberURLHelper::get_full_path( $relative_path );
|
242 |
+
$this->file_loc = $file_path;
|
243 |
+
$this->file = $file_path;
|
244 |
+
}
|
245 |
+
|
246 |
+
private function init_with_file_path( $file_path ) {
|
247 |
+
$url = TimberURLHelper::file_system_to_url( $file_path );
|
248 |
+
$this->abs_url = $url;
|
249 |
+
$this->file_loc = $file_path;
|
250 |
+
$this->file = $file_path;
|
251 |
+
}
|
252 |
+
|
253 |
+
/**
|
254 |
+
* @param string $url
|
255 |
+
*/
|
256 |
+
private function init_with_url($url) {
|
257 |
+
$this->abs_url = $url;
|
258 |
+
if (TimberURLHelper::is_local($url)) {
|
259 |
+
$this->file = ABSPATH . TimberURLHelper::get_rel_url($url);
|
260 |
+
$this->file_loc = ABSPATH . TimberURLHelper::get_rel_url($url);
|
261 |
+
}
|
262 |
+
}
|
263 |
+
|
264 |
+
/**
|
265 |
+
* @deprecated
|
266 |
+
* @return string
|
267 |
+
*/
|
268 |
+
function get_url() {
|
269 |
+
return $this->get_src();
|
270 |
+
}
|
271 |
+
|
272 |
+
/* Alias */
|
273 |
+
|
274 |
+
/**
|
275 |
+
* @return float
|
276 |
+
*/
|
277 |
+
public function aspect() {
|
278 |
+
$w = intval($this->width());
|
279 |
+
$h = intval($this->height());
|
280 |
+
return $w / $h;
|
281 |
+
}
|
282 |
+
|
283 |
+
/**
|
284 |
+
* @return int
|
285 |
+
*/
|
286 |
+
public function height() {
|
287 |
+
return $this->get_height();
|
288 |
+
}
|
289 |
+
|
290 |
+
/**
|
291 |
+
* @param string $size
|
292 |
+
* @return bool|string
|
293 |
+
*/
|
294 |
+
public function src($size = '') {
|
295 |
+
return $this->get_src($size);
|
296 |
+
}
|
297 |
+
|
298 |
+
/**
|
299 |
+
* @return int
|
300 |
+
*/
|
301 |
+
public function width() {
|
302 |
+
return $this->get_width();
|
303 |
+
}
|
304 |
+
|
305 |
+
public function alt() {
|
306 |
+
return $this->get_alt();
|
307 |
+
}
|
308 |
+
|
309 |
+
}
|
functions/functions/timber-loader.php
ADDED
@@ -0,0 +1,410 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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,
|
17 |
+
self::CACHE_OBJECT,
|
18 |
+
self::CACHE_TRANSIENT,
|
19 |
+
self::CACHE_SITE_TRANSIENT
|
20 |
+
);
|
21 |
+
|
22 |
+
protected $cache_mode = self::CACHE_TRANSIENT;
|
23 |
+
|
24 |
+
public $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
|
36 |
+
* @param array $data
|
37 |
+
* @param bool $expires
|
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 |
+
|
51 |
+
$key = null;
|
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 |
+
|
74 |
+
return apply_filters('timber_output', $output);
|
75 |
+
}
|
76 |
+
|
77 |
+
/**
|
78 |
+
* @param array $filenames
|
79 |
+
* @return bool
|
80 |
+
*/
|
81 |
+
function choose_template($filenames) {
|
82 |
+
if (is_array($filenames)) {
|
83 |
+
/* its an array so we have to figure out which one the dev wants */
|
84 |
+
foreach ($filenames as $filename) {
|
85 |
+
if ($this->template_exists($filename)) {
|
86 |
+
return $filename;
|
87 |
+
}
|
88 |
+
}
|
89 |
+
return false;
|
90 |
+
}
|
91 |
+
return $filenames;
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* @param string $file
|
96 |
+
* @return bool
|
97 |
+
*/
|
98 |
+
function template_exists($file) {
|
99 |
+
foreach ($this->locations as $dir) {
|
100 |
+
$look_for = trailingslashit($dir) . $file;
|
101 |
+
if (file_exists($look_for)) {
|
102 |
+
return true;
|
103 |
+
}
|
104 |
+
}
|
105 |
+
return false;
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* @return array
|
110 |
+
*/
|
111 |
+
function get_locations_theme() {
|
112 |
+
$theme_locs = array();
|
113 |
+
$child_loc = get_stylesheet_directory();
|
114 |
+
$parent_loc = get_template_directory();
|
115 |
+
if (DIRECTORY_SEPARATOR == '\\') {
|
116 |
+
$child_loc = str_replace('/', '\\', $child_loc);
|
117 |
+
$parent_loc = str_replace('/', '\\', $parent_loc);
|
118 |
+
}
|
119 |
+
$theme_locs[] = $child_loc;
|
120 |
+
foreach ($this->get_locations_theme_dir() as $dirname) {
|
121 |
+
$theme_locs[] = trailingslashit($child_loc) . trailingslashit($dirname);
|
122 |
+
}
|
123 |
+
if ($child_loc != $parent_loc) {
|
124 |
+
$theme_locs[] = $parent_loc;
|
125 |
+
foreach ($this->get_locations_theme_dir() as $dirname) {
|
126 |
+
$theme_locs[] = trailingslashit($parent_loc) . trailingslashit($dirname);
|
127 |
+
}
|
128 |
+
}
|
129 |
+
//now make sure theres a trailing slash on everything
|
130 |
+
$theme_locs = array_map('trailingslashit', $theme_locs);
|
131 |
+
return $theme_locs;
|
132 |
+
}
|
133 |
+
|
134 |
+
/**
|
135 |
+
* returns an array of the directory inside themes that holds twig files
|
136 |
+
* @return string[] the names of directores, ie: array('templats', 'views');
|
137 |
+
*/
|
138 |
+
private function get_locations_theme_dir() {
|
139 |
+
if (is_string(Timber::$dirname)) {
|
140 |
+
return array(Timber::$dirname);
|
141 |
+
}
|
142 |
+
return Timber::$dirname;
|
143 |
+
}
|
144 |
+
|
145 |
+
/**
|
146 |
+
* @return array
|
147 |
+
*/
|
148 |
+
function get_locations_user() {
|
149 |
+
$locs = array();
|
150 |
+
if (isset(Timber::$locations)) {
|
151 |
+
if (is_string(Timber::$locations)) {
|
152 |
+
Timber::$locations = array(Timber::$locations);
|
153 |
+
}
|
154 |
+
foreach (Timber::$locations as $tloc) {
|
155 |
+
$tloc = realpath($tloc);
|
156 |
+
if (is_dir($tloc)) {
|
157 |
+
$locs[] = $tloc;
|
158 |
+
}
|
159 |
+
}
|
160 |
+
}
|
161 |
+
return $locs;
|
162 |
+
}
|
163 |
+
|
164 |
+
/**
|
165 |
+
* @param bool $caller
|
166 |
+
* @return array
|
167 |
+
*/
|
168 |
+
function get_locations_caller($caller = false) {
|
169 |
+
$locs = array();
|
170 |
+
if ($caller && is_string($caller)) {
|
171 |
+
$caller = trailingslashit($caller);
|
172 |
+
if (is_dir($caller)) {
|
173 |
+
$locs[] = $caller;
|
174 |
+
}
|
175 |
+
foreach ($this->get_locations_theme_dir() as $dirname) {
|
176 |
+
$caller_sub = $caller . trailingslashit($dirname);
|
177 |
+
if (is_dir($caller_sub)) {
|
178 |
+
$locs[] = $caller_sub;
|
179 |
+
}
|
180 |
+
}
|
181 |
+
}
|
182 |
+
return $locs;
|
183 |
+
}
|
184 |
+
|
185 |
+
/**
|
186 |
+
* @param bool $caller
|
187 |
+
* @return array
|
188 |
+
*/
|
189 |
+
function get_locations($caller = false) {
|
190 |
+
//prioirty: user locations, caller (but not theme), child theme, parent theme, caller
|
191 |
+
$locs = array();
|
192 |
+
$locs = array_merge($locs, $this->get_locations_user());
|
193 |
+
$locs = array_merge($locs, $this->get_locations_caller($caller));
|
194 |
+
//remove themes from caller
|
195 |
+
$locs = array_diff($locs, $this->get_locations_theme());
|
196 |
+
$locs = array_merge($locs, $this->get_locations_theme());
|
197 |
+
$locs = array_merge($locs, $this->get_locations_caller($caller));
|
198 |
+
$locs = array_unique($locs);
|
199 |
+
$locs = apply_filters('timber_locations', $locs);
|
200 |
+
return $locs;
|
201 |
+
}
|
202 |
+
|
203 |
+
/**
|
204 |
+
* @return Twig_Loader_Filesystem
|
205 |
+
*/
|
206 |
+
function get_loader() {
|
207 |
+
$paths = array();
|
208 |
+
foreach ($this->locations as $loc) {
|
209 |
+
$loc = realpath($loc);
|
210 |
+
if (is_dir($loc)) {
|
211 |
+
$loc = realpath($loc);
|
212 |
+
$paths[] = $loc;
|
213 |
+
} else {
|
214 |
+
//error_log($loc.' is not a directory');
|
215 |
+
}
|
216 |
+
}
|
217 |
+
if (!ini_get('open_basedir')) {
|
218 |
+
$paths[] = '/';
|
219 |
+
} else {
|
220 |
+
$paths[] = ABSPATH;
|
221 |
+
}
|
222 |
+
$loader = new Twig_Loader_Filesystem($paths);
|
223 |
+
return $loader;
|
224 |
+
}
|
225 |
+
|
226 |
+
/**
|
227 |
+
* @return Twig_Environment
|
228 |
+
*/
|
229 |
+
function get_twig() {
|
230 |
+
$loader = $this->get_loader();
|
231 |
+
$params = array('debug' => WP_DEBUG, 'autoescape' => false);
|
232 |
+
if (isset(Timber::$autoescape)) {
|
233 |
+
$params['autoescape'] = Timber::$autoescape;
|
234 |
+
}
|
235 |
+
if (Timber::$cache == true) {
|
236 |
+
Timber::$twig_cache = true;
|
237 |
+
}
|
238 |
+
if (Timber::$twig_cache) {
|
239 |
+
$twig_cache_loc = TIMBER_LOC . '/cache/twig';
|
240 |
+
if (!file_exists($twig_cache_loc)) {
|
241 |
+
mkdir($twig_cache_loc, 0777, true);
|
242 |
+
}
|
243 |
+
$params['cache'] = $twig_cache_loc;
|
244 |
+
}
|
245 |
+
$twig = new Twig_Environment($loader, $params);
|
246 |
+
if (WP_DEBUG) {
|
247 |
+
$twig->addExtension(new Twig_Extension_Debug());
|
248 |
+
}
|
249 |
+
$twig->addExtension($this->_get_cache_extension());
|
250 |
+
|
251 |
+
$twig = apply_filters('twig_apply_filters', $twig);
|
252 |
+
return $twig;
|
253 |
+
}
|
254 |
+
|
255 |
+
public function clear_cache_timber($cache_mode = self::CACHE_USE_DEFAULT){
|
256 |
+
//_transient_timberloader
|
257 |
+
$object_cache = false;
|
258 |
+
if (isset($GLOBALS['wp_object_cache']) && is_object($GLOBALS['wp_object_cache'])) {
|
259 |
+
$object_cache = true;
|
260 |
+
}
|
261 |
+
$cache_mode = $this->_get_cache_mode($cache_mode);
|
262 |
+
if (self::CACHE_TRANSIENT === $cache_mode) {
|
263 |
+
global $wpdb;
|
264 |
+
$query = $wpdb->prepare("DELETE FROM $wpdb->options WHERE option_name LIKE '%s'", '_transient_timberloader_%');
|
265 |
+
$wpdb->query( $query );
|
266 |
+
return true;
|
267 |
+
} else if (self::CACHE_SITE_TRANSIENT === $cache_mode) {
|
268 |
+
global $wpdb;
|
269 |
+
$query = $wpdb->prepare("DELETE FROM $wpdb->options WHERE option_name LIKE '%s'", '_transient_timberloader_%');
|
270 |
+
$wpdb->query( $query );
|
271 |
+
return true;
|
272 |
+
} else if (self::CACHE_OBJECT === $cache_mode && $object_cache) {
|
273 |
+
global $wp_object_cache;
|
274 |
+
if (isset($wp_object_cache->cache[self::CACHEGROUP])){
|
275 |
+
unset($wp_object_cache->cache[self::CACHEGROUP]);
|
276 |
+
return true;
|
277 |
+
}
|
278 |
+
}
|
279 |
+
return false;
|
280 |
+
}
|
281 |
+
|
282 |
+
public function clear_cache_twig() {
|
283 |
+
$twig = $this->get_twig();
|
284 |
+
$twig->clearCacheFiles();
|
285 |
+
$cache = $twig->getCache();
|
286 |
+
if ($cache){
|
287 |
+
self::rrmdir($twig->getCache());
|
288 |
+
return true;
|
289 |
+
}
|
290 |
+
return false;
|
291 |
+
}
|
292 |
+
|
293 |
+
/**
|
294 |
+
* @param string|false $dirPath
|
295 |
+
*/
|
296 |
+
public static function rrmdir($dirPath) {
|
297 |
+
if (! is_dir($dirPath)) {
|
298 |
+
throw new InvalidArgumentException("$dirPath must be a directory");
|
299 |
+
}
|
300 |
+
if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {
|
301 |
+
$dirPath .= '/';
|
302 |
+
}
|
303 |
+
$files = glob($dirPath . '*', GLOB_MARK);
|
304 |
+
foreach ($files as $file) {
|
305 |
+
if (is_dir($file)) {
|
306 |
+
self::rrmdir($file);
|
307 |
+
} else {
|
308 |
+
unlink($file);
|
309 |
+
}
|
310 |
+
}
|
311 |
+
rmdir($dirPath);
|
312 |
+
}
|
313 |
+
|
314 |
+
/**
|
315 |
+
* @return \Asm89\Twig\CacheExtension\Extension
|
316 |
+
*/
|
317 |
+
private function _get_cache_extension() {
|
318 |
+
$loader_loc = trailingslashit(TIMBER_LOC) . 'functions/cache/loader.php';
|
319 |
+
require_once($loader_loc);
|
320 |
+
TimberCache_Loader::register();
|
321 |
+
|
322 |
+
$key_generator = new \Timber\Cache\KeyGenerator();
|
323 |
+
$cache_provider = new \Timber\Cache\WPObjectCacheAdapter($this);
|
324 |
+
$cache_strategy = new \Asm89\Twig\CacheExtension\CacheStrategy\GenerationalCacheStrategy($cache_provider, $key_generator);
|
325 |
+
$cache_extension = new \Asm89\Twig\CacheExtension\Extension($cache_strategy);
|
326 |
+
|
327 |
+
return $cache_extension;
|
328 |
+
}
|
329 |
+
|
330 |
+
/**
|
331 |
+
* @param string $key
|
332 |
+
* @param string $group
|
333 |
+
* @param string $cache_mode
|
334 |
+
* @return bool
|
335 |
+
*/
|
336 |
+
public function get_cache($key, $group = self::CACHEGROUP, $cache_mode = self::CACHE_USE_DEFAULT) {
|
337 |
+
$object_cache = false;
|
338 |
+
|
339 |
+
if (isset($GLOBALS['wp_object_cache']) && is_object($GLOBALS['wp_object_cache'])) {
|
340 |
+
$object_cache = true;
|
341 |
+
}
|
342 |
+
|
343 |
+
$cache_mode = $this->_get_cache_mode($cache_mode);
|
344 |
+
|
345 |
+
$value = false;
|
346 |
+
|
347 |
+
$trans_key = substr($group . '_' . $key, 0, self::TRANS_KEY_LEN);
|
348 |
+
if (self::CACHE_TRANSIENT === $cache_mode)
|
349 |
+
$value = get_transient($trans_key);
|
350 |
+
|
351 |
+
elseif (self::CACHE_SITE_TRANSIENT === $cache_mode)
|
352 |
+
$value = get_site_transient($trans_key);
|
353 |
+
|
354 |
+
elseif (self::CACHE_OBJECT === $cache_mode && $object_cache)
|
355 |
+
$value = wp_cache_get($key, $group);
|
356 |
+
|
357 |
+
return $value;
|
358 |
+
}
|
359 |
+
|
360 |
+
/**
|
361 |
+
* @param string $key
|
362 |
+
* @param string|boolean $value
|
363 |
+
* @param string $group
|
364 |
+
* @param int $expires
|
365 |
+
* @param string $cache_mode
|
366 |
+
* @return string|boolean
|
367 |
+
*/
|
368 |
+
public function set_cache($key, $value, $group = self::CACHEGROUP, $expires = 0, $cache_mode = self::CACHE_USE_DEFAULT) {
|
369 |
+
$object_cache = false;
|
370 |
+
|
371 |
+
if (isset($GLOBALS['wp_object_cache']) && is_object($GLOBALS['wp_object_cache'])) {
|
372 |
+
$object_cache = true;
|
373 |
+
}
|
374 |
+
|
375 |
+
if ((int)$expires < 1)
|
376 |
+
$expires = 0;
|
377 |
+
|
378 |
+
$cache_mode = self::_get_cache_mode($cache_mode);
|
379 |
+
$trans_key = substr($group . '_' . $key, 0, self::TRANS_KEY_LEN);
|
380 |
+
|
381 |
+
if (self::CACHE_TRANSIENT === $cache_mode)
|
382 |
+
set_transient($trans_key, $value, $expires);
|
383 |
+
|
384 |
+
elseif (self::CACHE_SITE_TRANSIENT === $cache_mode)
|
385 |
+
set_site_transient($trans_key, $value, $expires);
|
386 |
+
|
387 |
+
elseif (self::CACHE_OBJECT === $cache_mode && $object_cache)
|
388 |
+
wp_cache_set($key, $value, $group, $expires);
|
389 |
+
|
390 |
+
return $value;
|
391 |
+
}
|
392 |
+
|
393 |
+
/**
|
394 |
+
* @param string $cache_mode
|
395 |
+
* @return string
|
396 |
+
*/
|
397 |
+
private function _get_cache_mode($cache_mode) {
|
398 |
+
if (empty($cache_mode) || self::CACHE_USE_DEFAULT === $cache_mode) {
|
399 |
+
$cache_mode = $this->cache_mode;
|
400 |
+
}
|
401 |
+
|
402 |
+
// Fallback if self::$cache_mode did not get a valid value
|
403 |
+
if (!in_array($cache_mode, self::$cache_modes)) {
|
404 |
+
$cache_mode = self::CACHE_OBJECT;
|
405 |
+
}
|
406 |
+
|
407 |
+
return $cache_mode;
|
408 |
+
}
|
409 |
+
|
410 |
+
}
|
functions/functions/timber-menu-item.php
ADDED
@@ -0,0 +1,234 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TimberMenuItem extends TimberCore implements TimberCoreInterface {
|
4 |
+
|
5 |
+
public $children;
|
6 |
+
public $has_child_class = false;
|
7 |
+
|
8 |
+
public $classes = array();
|
9 |
+
public $class = '';
|
10 |
+
public $post_name;
|
11 |
+
public $type;
|
12 |
+
|
13 |
+
public $PostClass = 'TimberPost';
|
14 |
+
|
15 |
+
private $menu_object;
|
16 |
+
private $parent_object;
|
17 |
+
|
18 |
+
/**
|
19 |
+
*
|
20 |
+
*
|
21 |
+
* @param array|object $data
|
22 |
+
*/
|
23 |
+
function __construct( $data ) {
|
24 |
+
$this->import( $data );
|
25 |
+
$this->import_classes( $data );
|
26 |
+
if ( isset( $this->name ) ) {
|
27 |
+
$this->_name = $this->name;
|
28 |
+
}
|
29 |
+
$this->name = $this->name();
|
30 |
+
$this->add_class( 'menu-item-' . $this->ID );
|
31 |
+
$this->menu_object = $data;
|
32 |
+
if ( isset( $this->url ) && $this->url ) {
|
33 |
+
$this->url = TimberURLHelper::remove_trailing_slash( $this->url );
|
34 |
+
}
|
35 |
+
}
|
36 |
+
|
37 |
+
function __toString() {
|
38 |
+
return $this->name();
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
*
|
43 |
+
*
|
44 |
+
* @param string $class_name
|
45 |
+
*/
|
46 |
+
function add_class( $class_name ) {
|
47 |
+
$this->classes[] = $class_name;
|
48 |
+
$this->class .= ' ' . $class_name;
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
*
|
53 |
+
*
|
54 |
+
* @return string
|
55 |
+
*/
|
56 |
+
function name() {
|
57 |
+
if ( isset( $this->title ) ) {
|
58 |
+
return $this->title;
|
59 |
+
}
|
60 |
+
if ( isset( $this->_name ) ) {
|
61 |
+
return $this->_name;
|
62 |
+
}
|
63 |
+
return '';
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
*
|
68 |
+
*
|
69 |
+
* @return string
|
70 |
+
*/
|
71 |
+
function slug() {
|
72 |
+
if ( !isset( $this->parent_object ) ) {
|
73 |
+
$this->parent_object = $this->get_parent_object();
|
74 |
+
}
|
75 |
+
if ( isset( $this->parent_object->post_name ) && $this->parent_object->post_name ) {
|
76 |
+
return $this->parent_object->post_name;
|
77 |
+
}
|
78 |
+
return $this->post_name;
|
79 |
+
}
|
80 |
+
|
81 |
+
function get_parent_object() {
|
82 |
+
if ( isset( $this->_menu_item_object_id ) ) {
|
83 |
+
return new $this->PostClass( $this->_menu_item_object_id );
|
84 |
+
}
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
*
|
89 |
+
*
|
90 |
+
* @return string
|
91 |
+
*/
|
92 |
+
function get_link() {
|
93 |
+
if ( !isset( $this->url ) || !$this->url ) {
|
94 |
+
if ( isset( $this->_menu_item_type ) && $this->_menu_item_type == 'custom' ) {
|
95 |
+
$this->url = $this->_menu_item_url;
|
96 |
+
} else if ( isset( $this->menu_object ) && method_exists( $this->menu_object, 'get_link' ) ) {
|
97 |
+
$this->url = $this->menu_object->get_link();
|
98 |
+
}
|
99 |
+
}
|
100 |
+
return TimberURLHelper::remove_trailing_slash( $this->url );
|
101 |
+
}
|
102 |
+
|
103 |
+
/**
|
104 |
+
*
|
105 |
+
*
|
106 |
+
* @return string
|
107 |
+
*/
|
108 |
+
function get_path() {
|
109 |
+
return TimberURLHelper::remove_trailing_slash( TimberURLHelper::get_rel_url( $this->get_link() ) );
|
110 |
+
}
|
111 |
+
|
112 |
+
/**
|
113 |
+
*
|
114 |
+
*
|
115 |
+
* @param TimberMenuItem $item
|
116 |
+
*/
|
117 |
+
function add_child( $item ) {
|
118 |
+
if ( !$this->has_child_class ) {
|
119 |
+
$this->add_class( 'menu-item-has-children' );
|
120 |
+
$this->has_child_class = true;
|
121 |
+
}
|
122 |
+
if ( !isset( $this->children ) ) {
|
123 |
+
$this->children = array();
|
124 |
+
}
|
125 |
+
$this->children[] = $item;
|
126 |
+
}
|
127 |
+
|
128 |
+
/**
|
129 |
+
*
|
130 |
+
*
|
131 |
+
* @param object $data
|
132 |
+
*/
|
133 |
+
function import_classes( $data ) {
|
134 |
+
$this->classes = array_merge($this->classes, $data->classes);
|
135 |
+
$this->classes = array_unique($this->classes);
|
136 |
+
$this->class = trim( implode( ' ', $this->classes ) );
|
137 |
+
}
|
138 |
+
|
139 |
+
/**
|
140 |
+
*
|
141 |
+
*
|
142 |
+
* @return array|bool
|
143 |
+
*/
|
144 |
+
function get_children() {
|
145 |
+
if ( isset( $this->children ) ) {
|
146 |
+
return $this->children;
|
147 |
+
}
|
148 |
+
return false;
|
149 |
+
}
|
150 |
+
|
151 |
+
/**
|
152 |
+
*
|
153 |
+
*
|
154 |
+
* @return bool
|
155 |
+
*/
|
156 |
+
function is_external() {
|
157 |
+
if ( $this->type != 'custom' ) {
|
158 |
+
return false;
|
159 |
+
}
|
160 |
+
return TimberURLHelper::is_external( $this->url );
|
161 |
+
}
|
162 |
+
|
163 |
+
public function meta( $key ) {
|
164 |
+
if ( is_object( $this->menu_object ) && method_exists( $this->menu_object, 'meta' ) ) {
|
165 |
+
return $this->menu_object->meta( $key );
|
166 |
+
}
|
167 |
+
if ( isset( $this->$key ) ) {
|
168 |
+
return $this->$key;
|
169 |
+
}
|
170 |
+
}
|
171 |
+
|
172 |
+
/* Aliases */
|
173 |
+
|
174 |
+
/**
|
175 |
+
*
|
176 |
+
*
|
177 |
+
* @return array|bool
|
178 |
+
*/
|
179 |
+
public function children() {
|
180 |
+
return $this->get_children();
|
181 |
+
}
|
182 |
+
|
183 |
+
/**
|
184 |
+
*
|
185 |
+
*
|
186 |
+
* @return bool
|
187 |
+
*/
|
188 |
+
public function external() {
|
189 |
+
return $this->is_external();
|
190 |
+
}
|
191 |
+
|
192 |
+
/**
|
193 |
+
*
|
194 |
+
*
|
195 |
+
* @return string
|
196 |
+
*/
|
197 |
+
public function link() {
|
198 |
+
return $this->get_link();
|
199 |
+
}
|
200 |
+
|
201 |
+
/**
|
202 |
+
*
|
203 |
+
*
|
204 |
+
* @return string
|
205 |
+
*/
|
206 |
+
public function path() {
|
207 |
+
return $this->get_path();
|
208 |
+
}
|
209 |
+
|
210 |
+
/**
|
211 |
+
*
|
212 |
+
*
|
213 |
+
* @return string
|
214 |
+
*/
|
215 |
+
public function permalink() {
|
216 |
+
return $this->get_link();
|
217 |
+
}
|
218 |
+
|
219 |
+
/**
|
220 |
+
*
|
221 |
+
*
|
222 |
+
* @return string
|
223 |
+
*/
|
224 |
+
public function get_permalink() {
|
225 |
+
return $this->get_link();
|
226 |
+
}
|
227 |
+
|
228 |
+
public function title() {
|
229 |
+
if (isset($this->__title)){
|
230 |
+
return $this->__title;
|
231 |
+
}
|
232 |
+
}
|
233 |
+
|
234 |
+
}
|
functions/functions/timber-menu.php
ADDED
@@ -0,0 +1,174 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TimberMenu extends TimberCore {
|
4 |
+
|
5 |
+
public $MenuItemClass = 'TimberMenuItem';
|
6 |
+
public $PostClass = 'TimberPost';
|
7 |
+
|
8 |
+
public $items = null;
|
9 |
+
public $id = null;
|
10 |
+
public $ID = null;
|
11 |
+
public $name = null;
|
12 |
+
public $term_id;
|
13 |
+
public $title;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @param int $slug
|
17 |
+
*/
|
18 |
+
function __construct($slug = 0) {
|
19 |
+
$locations = get_nav_menu_locations();
|
20 |
+
if ($slug != 0 && is_numeric($slug)) {
|
21 |
+
$menu_id = $slug;
|
22 |
+
} else if (is_array($locations) && count($locations)) {
|
23 |
+
$menu_id = $this->get_menu_id_from_locations($slug, $locations);
|
24 |
+
} else if ($slug === false) {
|
25 |
+
$menu_id = false;
|
26 |
+
} else {
|
27 |
+
$menu_id = $this->get_menu_id_from_terms($slug);
|
28 |
+
}
|
29 |
+
if ($menu_id) {
|
30 |
+
$this->init($menu_id);
|
31 |
+
} else {
|
32 |
+
$this->init_as_page_menu();
|
33 |
+
//TimberHelper::error_log("Sorry, the menu you were looking for wasn't found ('" . $slug . "'). Here's what Timber did find:");
|
34 |
+
}
|
35 |
+
return null;
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* @param int $menu_id
|
40 |
+
*/
|
41 |
+
private function init($menu_id) {
|
42 |
+
$menu = wp_get_nav_menu_items($menu_id);
|
43 |
+
if ($menu) {
|
44 |
+
_wp_menu_item_classes_by_context($menu);
|
45 |
+
if (is_array($menu)){
|
46 |
+
$menu = self::order_children($menu);
|
47 |
+
}
|
48 |
+
$this->items = $menu;
|
49 |
+
$menu_info = wp_get_nav_menu_object($menu_id);
|
50 |
+
$this->import($menu_info);
|
51 |
+
$this->ID = $this->term_id;
|
52 |
+
$this->id = $this->term_id;
|
53 |
+
$this->title = $this->name;
|
54 |
+
}
|
55 |
+
}
|
56 |
+
|
57 |
+
private function init_as_page_menu() {
|
58 |
+
$menu = get_pages();
|
59 |
+
if ($menu) {
|
60 |
+
foreach($menu as $mi) {
|
61 |
+
$mi->__title = $mi->post_title;
|
62 |
+
}
|
63 |
+
_wp_menu_item_classes_by_context($menu);
|
64 |
+
if (is_array($menu)){
|
65 |
+
$menu = self::order_children($menu);
|
66 |
+
}
|
67 |
+
$this->items = $menu;
|
68 |
+
}
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* @param string $slug
|
73 |
+
* @param array $locations
|
74 |
+
* @return integer
|
75 |
+
*/
|
76 |
+
private function get_menu_id_from_locations($slug, $locations) {
|
77 |
+
if ($slug === 0) {
|
78 |
+
$slug = $this->get_menu_id_from_terms($slug);
|
79 |
+
}
|
80 |
+
if (is_numeric($slug)) {
|
81 |
+
$slug = array_search($slug, $locations);
|
82 |
+
}
|
83 |
+
if (isset($locations[$slug])) {
|
84 |
+
return $locations[$slug];
|
85 |
+
}
|
86 |
+
return null;
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* @param int $slug
|
91 |
+
* @return int
|
92 |
+
*/
|
93 |
+
private function get_menu_id_from_terms($slug = 0) {
|
94 |
+
if (!is_numeric($slug) && is_string($slug)) {
|
95 |
+
//we have a string so lets search for that
|
96 |
+
$menu_id = get_term_by('slug', $slug, 'nav_menu');
|
97 |
+
if ($menu_id) {
|
98 |
+
return $menu_id;
|
99 |
+
}
|
100 |
+
$menu_id = get_term_by('name', $slug, 'nav_menu');
|
101 |
+
if ($menu_id) {
|
102 |
+
return $menu_id;
|
103 |
+
}
|
104 |
+
}
|
105 |
+
$menus = get_terms('nav_menu', array('hide_empty' => true));
|
106 |
+
if (is_array($menus) && count($menus)) {
|
107 |
+
if (isset($menus[0]->term_id)) {
|
108 |
+
return $menus[0]->term_id;
|
109 |
+
}
|
110 |
+
}
|
111 |
+
return 0;
|
112 |
+
}
|
113 |
+
|
114 |
+
/**
|
115 |
+
* @param array $menu_items
|
116 |
+
* @param int $parent_id
|
117 |
+
* @return TimberMenuItem|null
|
118 |
+
*/
|
119 |
+
function find_parent_item_in_menu($menu_items, $parent_id) {
|
120 |
+
foreach ($menu_items as &$item) {
|
121 |
+
if ($item->ID == $parent_id) {
|
122 |
+
return $item;
|
123 |
+
}
|
124 |
+
}
|
125 |
+
return null;
|
126 |
+
}
|
127 |
+
|
128 |
+
/**
|
129 |
+
* @param array $items
|
130 |
+
* @return array
|
131 |
+
*/
|
132 |
+
function order_children($items) {
|
133 |
+
$index = array();
|
134 |
+
$menu = array();
|
135 |
+
foreach ($items as $item) {
|
136 |
+
if (isset($item->title)) {
|
137 |
+
//items from wp can come with a $title property which conflicts with methods
|
138 |
+
$item->__title = $item->title;
|
139 |
+
unset($item->title);
|
140 |
+
}
|
141 |
+
if(isset($item->ID)){
|
142 |
+
if (is_object($item) && get_class($item) == 'WP_Post'){
|
143 |
+
$old_menu_item = $item;
|
144 |
+
$item = new $this->PostClass($item);
|
145 |
+
}
|
146 |
+
$menu_item = new $this->MenuItemClass($item);
|
147 |
+
if (isset($old_menu_item)){
|
148 |
+
$menu_item->import_classes($old_menu_item);
|
149 |
+
}
|
150 |
+
$index[$item->ID] = $menu_item;
|
151 |
+
}
|
152 |
+
}
|
153 |
+
foreach ($index as $item) {
|
154 |
+
if (isset($item->menu_item_parent) && $item->menu_item_parent && isset($index[$item->menu_item_parent])) {
|
155 |
+
$index[$item->menu_item_parent]->add_child($item);
|
156 |
+
} else {
|
157 |
+
$menu[] = $item;
|
158 |
+
}
|
159 |
+
}
|
160 |
+
return $menu;
|
161 |
+
}
|
162 |
+
|
163 |
+
/**
|
164 |
+
* @return array
|
165 |
+
*/
|
166 |
+
function get_items() {
|
167 |
+
if (is_array($this->items)) {
|
168 |
+
return $this->items;
|
169 |
+
}
|
170 |
+
return array();
|
171 |
+
}
|
172 |
+
}
|
173 |
+
|
174 |
+
|
functions/functions/timber-page.php
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TimberPage extends TimberPost
|
4 |
+
{
|
5 |
+
|
6 |
+
}
|
functions/functions/timber-post-getter.php
ADDED
@@ -0,0 +1,137 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TimberPostGetter {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* @param mixed $query
|
7 |
+
* @param string $PostClass
|
8 |
+
* @return array|bool|null
|
9 |
+
*/
|
10 |
+
static function get_post($query = false, $PostClass = 'TimberPost') {
|
11 |
+
$posts = self::get_posts( $query, $PostClass );
|
12 |
+
if ( $post = reset($posts ) ) {
|
13 |
+
return $post;
|
14 |
+
}
|
15 |
+
return false;
|
16 |
+
}
|
17 |
+
|
18 |
+
static function get_posts( $query = false, $PostClass = 'TimberPost', $return_collection = false ) {
|
19 |
+
$posts = self::query_posts( $query, $PostClass );
|
20 |
+
return apply_filters('timber_post_getter_get_posts', $posts->get_posts( $return_collection ));
|
21 |
+
}
|
22 |
+
|
23 |
+
static function query_post( $query = false, $PostClass = 'TimberPost' ) {
|
24 |
+
$posts = self::query_posts( $query, $PostClass );
|
25 |
+
if ( $post = $posts->current() ) {
|
26 |
+
return $post;
|
27 |
+
}
|
28 |
+
return false;
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* @param mixed $query
|
33 |
+
* @param string $PostClass
|
34 |
+
* @return array|bool|null
|
35 |
+
*/
|
36 |
+
static function query_posts($query = false, $PostClass = 'TimberPost' ){
|
37 |
+
if (self::is_post_class_or_class_map($query)) {
|
38 |
+
$PostClass = $query;
|
39 |
+
$query = false;
|
40 |
+
}
|
41 |
+
|
42 |
+
if (is_object($query) && !is_a($query, 'WP_Query') ){
|
43 |
+
// The only object other than a query is a type of post object
|
44 |
+
$query = array( $query );
|
45 |
+
}
|
46 |
+
|
47 |
+
if ( is_array( $query ) && count( $query ) && isset( $query[0] ) && is_object( $query[0] ) ) {
|
48 |
+
// We have an array of post objects that already have data
|
49 |
+
return new TimberPostsCollection( $query, $PostClass );
|
50 |
+
} else {
|
51 |
+
// We have a query (of sorts) to work with
|
52 |
+
$tqi = new TimberQueryIterator( $query, $PostClass );
|
53 |
+
return $tqi;
|
54 |
+
}
|
55 |
+
}
|
56 |
+
|
57 |
+
static function get_pids($query){
|
58 |
+
$posts = self::get_posts($query);
|
59 |
+
$pids = array();
|
60 |
+
foreach($posts as $post){
|
61 |
+
if (isset($post->ID)){
|
62 |
+
$pids[] = $post->ID;
|
63 |
+
}
|
64 |
+
}
|
65 |
+
return $pids;
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* @param array $results
|
70 |
+
* @param string $PostClass
|
71 |
+
* @return TimberPostsCollection
|
72 |
+
*/
|
73 |
+
static function handle_post_results($results, $PostClass = 'TimberPost') {
|
74 |
+
$posts = array();
|
75 |
+
foreach ($results as $rid) {
|
76 |
+
$PostClassUse = $PostClass;
|
77 |
+
if (is_array($PostClass)) {
|
78 |
+
$post_type = get_post_type($rid);
|
79 |
+
$PostClassUse = 'TimberPost';
|
80 |
+
if (isset($PostClass[$post_type])) {
|
81 |
+
$PostClassUse = $PostClass[$post_type];
|
82 |
+
} else {
|
83 |
+
if (is_array($PostClass)) {
|
84 |
+
TimberHelper::error_log($post_type.' of '.$rid.' not found in ' . print_r($PostClass, true));
|
85 |
+
} else {
|
86 |
+
TimberHelper::error_log($post_type.' not found in '.$PostClass);
|
87 |
+
}
|
88 |
+
}
|
89 |
+
}
|
90 |
+
$post = new $PostClassUse($rid);
|
91 |
+
if (isset($post->ID)) {
|
92 |
+
$posts[] = $post;
|
93 |
+
}
|
94 |
+
}
|
95 |
+
return new TimberPostsCollection( $posts, $PostClass );
|
96 |
+
}
|
97 |
+
|
98 |
+
static function loop_to_id() {
|
99 |
+
if (!self::wp_query_has_posts()) { return false; }
|
100 |
+
|
101 |
+
global $wp_query;
|
102 |
+
$post_num = property_exists($wp_query, 'current_post')
|
103 |
+
? $wp_query->current_post + 1
|
104 |
+
: 0
|
105 |
+
;
|
106 |
+
|
107 |
+
if (!isset($wp_query->posts[$post_num])) { return false; }
|
108 |
+
|
109 |
+
return $wp_query->posts[$post_num]->ID;
|
110 |
+
}
|
111 |
+
|
112 |
+
/**
|
113 |
+
* @return bool
|
114 |
+
*/
|
115 |
+
static function wp_query_has_posts() {
|
116 |
+
global $wp_query;
|
117 |
+
return ($wp_query && property_exists($wp_query, 'posts') && $wp_query->posts);
|
118 |
+
}
|
119 |
+
|
120 |
+
/**
|
121 |
+
* @param string|array $arg
|
122 |
+
* @return bool
|
123 |
+
*/
|
124 |
+
static function is_post_class_or_class_map($arg){
|
125 |
+
if (is_string($arg) && class_exists($arg)) {
|
126 |
+
return true;
|
127 |
+
}
|
128 |
+
if (is_array($arg)) {
|
129 |
+
foreach ($arg as $item) {
|
130 |
+
if (is_string($item) && class_exists($item)) {
|
131 |
+
return true;
|
132 |
+
}
|
133 |
+
}
|
134 |
+
}
|
135 |
+
return false;
|
136 |
+
}
|
137 |
+
}
|
functions/functions/timber-post.php
ADDED
@@ -0,0 +1,1007 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TimberPost extends TimberCore implements TimberCoreInterface {
|
4 |
+
|
5 |
+
public $ImageClass = 'TimberImage';
|
6 |
+
public $PostClass = 'TimberPost';
|
7 |
+
|
8 |
+
public $object_type = 'post';
|
9 |
+
public static $representation = 'post';
|
10 |
+
|
11 |
+
public $_can_edit;
|
12 |
+
public $_custom_imported = false;
|
13 |
+
public $_content;
|
14 |
+
public $_get_terms;
|
15 |
+
|
16 |
+
private $_next = array();
|
17 |
+
private $_prev = array();
|
18 |
+
|
19 |
+
public $class;
|
20 |
+
public $display_date;
|
21 |
+
public $id;
|
22 |
+
public $ID;
|
23 |
+
public $post_content;
|
24 |
+
public $post_date;
|
25 |
+
public $post_parent;
|
26 |
+
public $post_title;
|
27 |
+
public $post_type;
|
28 |
+
public $slug;
|
29 |
+
|
30 |
+
/**
|
31 |
+
* If you send the constructor nothing it will try to figure out the current post id based on being inside The_Loop
|
32 |
+
* @param mixed $pid
|
33 |
+
* @return \TimberPost TimberPost object -- woo!
|
34 |
+
*/
|
35 |
+
function __construct($pid = null) {
|
36 |
+
global $wp_query;
|
37 |
+
if ($pid === null && isset($wp_query->queried_object_id) && $wp_query->queried_object_id) {
|
38 |
+
$pid = $wp_query->queried_object_id;
|
39 |
+
$this->ID = $pid;
|
40 |
+
} else if ($pid === null && get_the_ID()) {
|
41 |
+
$pid = get_the_ID();
|
42 |
+
$this->ID = $pid;
|
43 |
+
} else if ($pid === null && ($pid_from_loop = TimberPostGetter::loop_to_id())) {
|
44 |
+
$this->ID = $pid_from_loop;
|
45 |
+
}
|
46 |
+
if (is_numeric($pid)) {
|
47 |
+
$this->ID = $pid;
|
48 |
+
}
|
49 |
+
$this->init($pid);
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* @return string
|
54 |
+
*/
|
55 |
+
function __toString() {
|
56 |
+
return $this->title();
|
57 |
+
}
|
58 |
+
|
59 |
+
|
60 |
+
/**
|
61 |
+
* @param int|bool $pid
|
62 |
+
*/
|
63 |
+
function init($pid = false) {
|
64 |
+
if ($pid === false) {
|
65 |
+
$pid = get_the_ID();
|
66 |
+
}
|
67 |
+
$post_info = $this->get_info($pid);
|
68 |
+
$this->import($post_info);
|
69 |
+
/* deprecated, adding for support for older themes */
|
70 |
+
$this->display_date = $this->date();
|
71 |
+
//cant have a function, so gots to do it this way
|
72 |
+
$post_class = $this->post_class();
|
73 |
+
$this->class = $post_class;
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Get the URL that will edit the current post/object
|
78 |
+
*
|
79 |
+
* @return bool|string
|
80 |
+
*/
|
81 |
+
function get_edit_url() {
|
82 |
+
if ($this->can_edit()) {
|
83 |
+
return get_edit_post_link($this->ID);
|
84 |
+
}
|
85 |
+
return false;
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* updates the post_meta of the current object with the given value
|
90 |
+
*
|
91 |
+
* @param string $field
|
92 |
+
* @param mixed $value
|
93 |
+
*/
|
94 |
+
public function update($field, $value) {
|
95 |
+
if (isset($this->ID)) {
|
96 |
+
update_post_meta($this->ID, $field, $value);
|
97 |
+
$this->$field = $value;
|
98 |
+
}
|
99 |
+
}
|
100 |
+
|
101 |
+
|
102 |
+
/**
|
103 |
+
* 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
|
104 |
+
*
|
105 |
+
* @param mixed $pid
|
106 |
+
* @return WP_Post on success
|
107 |
+
*/
|
108 |
+
private function prepare_post_info($pid = 0) {
|
109 |
+
if (is_string($pid) || is_numeric($pid) || (is_object($pid) && !isset($pid->post_title)) || $pid === 0) {
|
110 |
+
$pid = self::check_post_id($pid);
|
111 |
+
$post = get_post($pid);
|
112 |
+
if ($post) {
|
113 |
+
return $post;
|
114 |
+
} else {
|
115 |
+
$post = get_page($pid);
|
116 |
+
return $post;
|
117 |
+
}
|
118 |
+
}
|
119 |
+
//we can skip if already is WP_Post
|
120 |
+
return $pid;
|
121 |
+
}
|
122 |
+
|
123 |
+
|
124 |
+
/**
|
125 |
+
* helps you find the post id regardless of whetehr you send a string or whatever
|
126 |
+
*
|
127 |
+
* @param integer $pid ;
|
128 |
+
* @return integer ID number of a post
|
129 |
+
*/
|
130 |
+
private function check_post_id($pid) {
|
131 |
+
if (is_numeric($pid) && $pid === 0) {
|
132 |
+
$pid = get_the_ID();
|
133 |
+
return $pid;
|
134 |
+
}
|
135 |
+
if (!is_numeric($pid) && is_string($pid)) {
|
136 |
+
$pid = self::get_post_id_by_name($pid);
|
137 |
+
return $pid;
|
138 |
+
}
|
139 |
+
if (!$pid) {
|
140 |
+
return null;
|
141 |
+
}
|
142 |
+
return $pid;
|
143 |
+
}
|
144 |
+
|
145 |
+
|
146 |
+
/**
|
147 |
+
* get_post_id_by_name($post_name)
|
148 |
+
*
|
149 |
+
* @param string $post_name
|
150 |
+
* @return int
|
151 |
+
*/
|
152 |
+
public static function get_post_id_by_name($post_name) {
|
153 |
+
global $wpdb;
|
154 |
+
$query = $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_name = %s LIMIT 1", $post_name);
|
155 |
+
$result = $wpdb->get_row($query);
|
156 |
+
if (!$result) {
|
157 |
+
return null;
|
158 |
+
}
|
159 |
+
return $result->ID;
|
160 |
+
}
|
161 |
+
|
162 |
+
|
163 |
+
/**
|
164 |
+
* ## get a preview of your post, if you have an excerpt it will use that,
|
165 |
+
* ## otherwise it will pull from the post_content.
|
166 |
+
* ## If there's a <!-- more --> tag it will use that to mark where to pull through.
|
167 |
+
* <p>{{post.get_preview(50)}}</p>
|
168 |
+
*/
|
169 |
+
|
170 |
+
/**
|
171 |
+
* @param int $len
|
172 |
+
* @param bool $force
|
173 |
+
* @param string $readmore
|
174 |
+
* @param bool $strip
|
175 |
+
* @return string
|
176 |
+
*/
|
177 |
+
function get_preview($len = 50, $force = false, $readmore = 'Read More', $strip = true) {
|
178 |
+
$text = '';
|
179 |
+
$trimmed = false;
|
180 |
+
if (isset($this->post_excerpt) && strlen($this->post_excerpt)) {
|
181 |
+
if ($force) {
|
182 |
+
$text = TimberHelper::trim_words($this->post_excerpt, $len, false);
|
183 |
+
$trimmed = true;
|
184 |
+
} else {
|
185 |
+
$text = $this->post_excerpt;
|
186 |
+
}
|
187 |
+
}
|
188 |
+
if (!strlen($text) && strpos($this->post_content, '<!--more-->') !== false) {
|
189 |
+
$pieces = explode('<!--more-->', $this->post_content);
|
190 |
+
$text = $pieces[0];
|
191 |
+
if ($force) {
|
192 |
+
$text = TimberHelper::trim_words($text, $len, false);
|
193 |
+
$trimmed = true;
|
194 |
+
}
|
195 |
+
}
|
196 |
+
if (!strlen($text)) {
|
197 |
+
$text = TimberHelper::trim_words($this->get_content(), $len, false);
|
198 |
+
$trimmed = true;
|
199 |
+
}
|
200 |
+
if (!strlen(trim($text))) {
|
201 |
+
return $text;
|
202 |
+
}
|
203 |
+
if ($strip) {
|
204 |
+
$text = trim(strip_tags($text));
|
205 |
+
}
|
206 |
+
if (strlen($text)) {
|
207 |
+
$text = trim($text);
|
208 |
+
$last = $text[strlen($text) - 1];
|
209 |
+
if ($last != '.' && $trimmed) {
|
210 |
+
$text .= ' … ';
|
211 |
+
}
|
212 |
+
if (!$strip) {
|
213 |
+
$last_p_tag = strrpos($text, '</p>');
|
214 |
+
if ($last_p_tag !== false) {
|
215 |
+
$text = substr($text, 0, $last_p_tag);
|
216 |
+
}
|
217 |
+
if ($last != '.' && $trimmed) {
|
218 |
+
$text .= ' … ';
|
219 |
+
}
|
220 |
+
}
|
221 |
+
|
222 |
+
if ($readmore) {
|
223 |
+
$text .= ' <a href="' . $this->get_permalink() . '" class="read-more">' . $readmore . '</a>';
|
224 |
+
}
|
225 |
+
if (!$strip) {
|
226 |
+
$text .= '</p>';
|
227 |
+
}
|
228 |
+
}
|
229 |
+
return $text;
|
230 |
+
}
|
231 |
+
|
232 |
+
/**
|
233 |
+
* gets the post custom and attaches it to the current object
|
234 |
+
* @param bool|int $pid a post ID number
|
235 |
+
* @nodoc
|
236 |
+
*/
|
237 |
+
function import_custom($pid = false) {
|
238 |
+
if (!$pid) {
|
239 |
+
$pid = $this->ID;
|
240 |
+
}
|
241 |
+
$customs = $this->get_post_custom($pid);
|
242 |
+
$this->import($customs);
|
243 |
+
}
|
244 |
+
|
245 |
+
/**
|
246 |
+
* @param int $pid
|
247 |
+
* @return array
|
248 |
+
*/
|
249 |
+
function get_post_custom($pid) {
|
250 |
+
apply_filters('timber_post_get_meta_pre', array(), $pid, $this);
|
251 |
+
$customs = get_post_custom($pid);
|
252 |
+
if (!is_array($customs) || empty($customs)) {
|
253 |
+
return array();
|
254 |
+
}
|
255 |
+
foreach ($customs as $key => $value) {
|
256 |
+
if (is_array($value) && count($value) == 1 && isset($value[0])) {
|
257 |
+
$value = $value[0];
|
258 |
+
}
|
259 |
+
$customs[$key] = maybe_unserialize($value);
|
260 |
+
}
|
261 |
+
$customs = apply_filters('timber_post_get_meta', $customs, $pid, $this);
|
262 |
+
return $customs;
|
263 |
+
}
|
264 |
+
|
265 |
+
/**
|
266 |
+
* ## get the featured image as a TimberImage
|
267 |
+
* <img src="{{post.get_thumbnail.get_src}}" />
|
268 |
+
*/
|
269 |
+
|
270 |
+
/**
|
271 |
+
* @return null|TimberImage
|
272 |
+
*/
|
273 |
+
function get_thumbnail() {
|
274 |
+
if (function_exists('get_post_thumbnail_id')) {
|
275 |
+
$tid = get_post_thumbnail_id($this->ID);
|
276 |
+
if ($tid) {
|
277 |
+
return new $this->ImageClass($tid);
|
278 |
+
}
|
279 |
+
}
|
280 |
+
return null;
|
281 |
+
}
|
282 |
+
|
283 |
+
/**
|
284 |
+
* @return string
|
285 |
+
*/
|
286 |
+
function get_permalink() {
|
287 |
+
if (isset($this->permalink)) {
|
288 |
+
return $this->permalink;
|
289 |
+
}
|
290 |
+
$this->permalink = get_permalink($this->ID);
|
291 |
+
return $this->permalink;
|
292 |
+
}
|
293 |
+
|
294 |
+
/**
|
295 |
+
* @return string
|
296 |
+
*/
|
297 |
+
function get_link() {
|
298 |
+
return $this->get_permalink();
|
299 |
+
}
|
300 |
+
|
301 |
+
/**
|
302 |
+
* @param bool $taxonomy
|
303 |
+
* @return mixed
|
304 |
+
*/
|
305 |
+
function get_next($taxonomy = false) {
|
306 |
+
if (!isset($this->_next) || !isset($this->_next[$taxonomy])) {
|
307 |
+
global $post;
|
308 |
+
$this->_next = array();
|
309 |
+
$old_global = $post;
|
310 |
+
$post = $this;
|
311 |
+
if ($taxonomy) {
|
312 |
+
$adjacent = get_adjacent_post(true, '', false, $taxonomy);
|
313 |
+
} else {
|
314 |
+
$adjacent = get_adjacent_post(false, '', false);
|
315 |
+
}
|
316 |
+
|
317 |
+
if ($adjacent) {
|
318 |
+
$this->_next[$taxonomy] = new $this->PostClass($adjacent);
|
319 |
+
} else {
|
320 |
+
$this->_next[$taxonomy] = false;
|
321 |
+
}
|
322 |
+
$post = $old_global;
|
323 |
+
}
|
324 |
+
return $this->_next[$taxonomy];
|
325 |
+
}
|
326 |
+
|
327 |
+
/**
|
328 |
+
* @return array
|
329 |
+
*/
|
330 |
+
public function get_pagination() {
|
331 |
+
global $post, $page, $numpages, $multipage;
|
332 |
+
$post = $this;
|
333 |
+
$ret = array();
|
334 |
+
if ($multipage) {
|
335 |
+
for ($i = 1; $i <= $numpages; $i++) {
|
336 |
+
$link = self::get_wp_link_page($i);
|
337 |
+
$data = array('name' => $i, 'title' => $i, 'text' => $i, 'link' => $link);
|
338 |
+
if ($i == $page) {
|
339 |
+
$data['current'] = true;
|
340 |
+
}
|
341 |
+
$ret['pages'][] = $data;
|
342 |
+
}
|
343 |
+
$i = $page - 1;
|
344 |
+
if ($i) {
|
345 |
+
$link = self::get_wp_link_page($i);
|
346 |
+
$ret['prev'] = array('link' => $link);
|
347 |
+
}
|
348 |
+
$i = $page + 1;
|
349 |
+
if ($i <= $numpages) {
|
350 |
+
$link = self::get_wp_link_page($i);
|
351 |
+
$ret['next'] = array('link' => $link);
|
352 |
+
}
|
353 |
+
}
|
354 |
+
return $ret;
|
355 |
+
}
|
356 |
+
|
357 |
+
/**
|
358 |
+
* @param int $i
|
359 |
+
* @return string
|
360 |
+
*/
|
361 |
+
private static function get_wp_link_page($i) {
|
362 |
+
$link = _wp_link_page($i);
|
363 |
+
$link = new SimpleXMLElement($link . '</a>');
|
364 |
+
if (isset($link['href'])) {
|
365 |
+
return $link['href'];
|
366 |
+
}
|
367 |
+
return '';
|
368 |
+
}
|
369 |
+
|
370 |
+
/**
|
371 |
+
* @return string
|
372 |
+
*/
|
373 |
+
function get_path() {
|
374 |
+
return TimberURLHelper::get_rel_url($this->get_link());
|
375 |
+
}
|
376 |
+
|
377 |
+
/**
|
378 |
+
* @param bool $taxonomy
|
379 |
+
* @return mixed
|
380 |
+
*/
|
381 |
+
function get_prev($taxonomy = false) {
|
382 |
+
if (isset($this->_prev) && isset($this->_prev[$taxonomy])) {
|
383 |
+
return $this->_prev[$taxonomy];
|
384 |
+
}
|
385 |
+
global $post;
|
386 |
+
$old_global = $post;
|
387 |
+
$post = $this;
|
388 |
+
$within_taxonomy = ($taxonomy) ? $taxonomy : 'category';
|
389 |
+
$adjacent = get_adjacent_post(($taxonomy), '', true, $within_taxonomy);
|
390 |
+
|
391 |
+
$prev_in_taxonomy = false;
|
392 |
+
if ($adjacent) {
|
393 |
+
$prev_in_taxonomy = new $this->PostClass($adjacent);
|
394 |
+
}
|
395 |
+
$this->_prev[$taxonomy] = $prev_in_taxonomy;
|
396 |
+
$post = $old_global;
|
397 |
+
return $this->_prev[$taxonomy];
|
398 |
+
}
|
399 |
+
|
400 |
+
/**
|
401 |
+
* @return bool|TimberPost
|
402 |
+
*/
|
403 |
+
function get_parent() {
|
404 |
+
if (!$this->post_parent) {
|
405 |
+
return false;
|
406 |
+
}
|
407 |
+
return new $this->PostClass($this->post_parent);
|
408 |
+
}
|
409 |
+
|
410 |
+
/**
|
411 |
+
* ## Gets a User object from the author of the post
|
412 |
+
* <p class="byline">{{post.get_author.name}}</p>
|
413 |
+
*/
|
414 |
+
|
415 |
+
/**
|
416 |
+
* @return bool|TimberUser
|
417 |
+
*/
|
418 |
+
function get_author() {
|
419 |
+
if (isset($this->post_author)) {
|
420 |
+
return new TimberUser($this->post_author);
|
421 |
+
}
|
422 |
+
return false;
|
423 |
+
}
|
424 |
+
|
425 |
+
/**
|
426 |
+
* @return bool|TimberUser
|
427 |
+
*/
|
428 |
+
function get_modified_author() {
|
429 |
+
$user_id = get_post_meta($this->ID, '_edit_last', true);
|
430 |
+
return ($user_id ? new TimberUser($user_id) : $this->get_author());
|
431 |
+
}
|
432 |
+
|
433 |
+
/**
|
434 |
+
* @param int $pid
|
435 |
+
* @return null|object|WP_Post
|
436 |
+
*/
|
437 |
+
function get_info($pid) {
|
438 |
+
$post = $this->prepare_post_info($pid);
|
439 |
+
if (!isset($post->post_status)) {
|
440 |
+
return null;
|
441 |
+
}
|
442 |
+
$post->status = $post->post_status;
|
443 |
+
$post->id = $post->ID;
|
444 |
+
$post->slug = $post->post_name;
|
445 |
+
$customs = $this->get_post_custom($post->ID);
|
446 |
+
$post->custom = $customs;
|
447 |
+
$post = (object)array_merge((array)$customs, (array)$post);
|
448 |
+
return $post;
|
449 |
+
}
|
450 |
+
|
451 |
+
/**
|
452 |
+
* This is deprecated!
|
453 |
+
* @param string $use
|
454 |
+
* @return string
|
455 |
+
*/
|
456 |
+
function get_display_date($use = 'post_date') {
|
457 |
+
return date(get_option('date_format'), strtotime($this->$use));
|
458 |
+
}
|
459 |
+
|
460 |
+
/**
|
461 |
+
* @param string $date_format
|
462 |
+
* @return string
|
463 |
+
*/
|
464 |
+
function get_date($date_format = '') {
|
465 |
+
$df = $date_format ? $date_format : get_option('date_format');
|
466 |
+
$the_date = (string)mysql2date($df, $this->post_date);
|
467 |
+
return apply_filters('get_the_date', $the_date, $date_format);
|
468 |
+
}
|
469 |
+
|
470 |
+
/**
|
471 |
+
* @param string $date_format
|
472 |
+
* @return string
|
473 |
+
*/
|
474 |
+
function get_modified_date($date_format = '') {
|
475 |
+
$df = $date_format ? $date_format : get_option('date_format');
|
476 |
+
$the_time = $this->get_modified_time($df, null, $this->ID, true);
|
477 |
+
return apply_filters('get_the_modified_date', $the_time, $date_format);
|
478 |
+
}
|
479 |
+
|
480 |
+
/**
|
481 |
+
* @param string $time_format
|
482 |
+
* @return string
|
483 |
+
*/
|
484 |
+
function get_modified_time($time_format = '') {
|
485 |
+
$tf = $time_format ? $time_format : get_option('time_format');
|
486 |
+
$the_time = get_post_modified_time($tf, false, $this->ID, true);
|
487 |
+
return apply_filters('get_the_modified_time', $the_time, $time_format);
|
488 |
+
}
|
489 |
+
|
490 |
+
/**
|
491 |
+
* @param string $post_type
|
492 |
+
* @param bool $childPostClass
|
493 |
+
* @return array
|
494 |
+
*/
|
495 |
+
function get_children($post_type = 'any', $childPostClass = false) {
|
496 |
+
if ($childPostClass == false) {
|
497 |
+
$childPostClass = $this->PostClass;
|
498 |
+
}
|
499 |
+
if ($post_type == 'parent') {
|
500 |
+
$post_type = $this->post_type;
|
501 |
+
}
|
502 |
+
$children = get_children('post_parent=' . $this->ID . '&post_type=' . $post_type . '&numberposts=-1&orderby=menu_order title&order=ASC');
|
503 |
+
foreach ($children as &$child) {
|
504 |
+
$child = new $childPostClass($child->ID);
|
505 |
+
}
|
506 |
+
$children = array_values($children);
|
507 |
+
return $children;
|
508 |
+
}
|
509 |
+
|
510 |
+
/**
|
511 |
+
* {% for comment in post.get_comments %}
|
512 |
+
* <p>{{comment.content}}</p>
|
513 |
+
* {% endfor %}
|
514 |
+
*/
|
515 |
+
|
516 |
+
/**
|
517 |
+
* @param int $ct
|
518 |
+
* @param string $order
|
519 |
+
* @param string $type
|
520 |
+
* @param string $status
|
521 |
+
* @param string $CommentClass
|
522 |
+
* @return mixed
|
523 |
+
*/
|
524 |
+
function get_comments($ct = 0, $order = 'wp', $type = 'comment', $status = 'approve', $CommentClass = 'TimberComment') {
|
525 |
+
$args = array('post_id' => $this->ID, 'status' => $status, 'order' => $order);
|
526 |
+
if ($ct > 0) {
|
527 |
+
$args['number'] = $ct;
|
528 |
+
}
|
529 |
+
if ($order == 'wp') {
|
530 |
+
$args['order'] = get_option('comment_order');
|
531 |
+
}
|
532 |
+
$comments = get_comments($args);
|
533 |
+
foreach ($comments as &$comment) {
|
534 |
+
$comment = new $CommentClass($comment);
|
535 |
+
}
|
536 |
+
return $comments;
|
537 |
+
}
|
538 |
+
|
539 |
+
/**
|
540 |
+
* <ul class="categories">
|
541 |
+
* {% for category in post.get_categories %}
|
542 |
+
* <li>{{category.name}}</li>
|
543 |
+
* {% endfor %}
|
544 |
+
* </ul>
|
545 |
+
*/
|
546 |
+
|
547 |
+
/**
|
548 |
+
* @return array
|
549 |
+
*/
|
550 |
+
function get_categories() {
|
551 |
+
return $this->get_terms('category');
|
552 |
+
}
|
553 |
+
|
554 |
+
/**
|
555 |
+
* @return mixed
|
556 |
+
*/
|
557 |
+
function get_category() {
|
558 |
+
$cats = $this->get_categories();
|
559 |
+
if (count($cats) && isset($cats[0])) {
|
560 |
+
return $cats[0];
|
561 |
+
}
|
562 |
+
return null;
|
563 |
+
}
|
564 |
+
|
565 |
+
/** # get terms is good
|
566 |
+
*
|
567 |
+
*/
|
568 |
+
|
569 |
+
/**
|
570 |
+
* @param string $tax
|
571 |
+
* @param bool $merge
|
572 |
+
* @param string $TermClass
|
573 |
+
* @return array
|
574 |
+
*/
|
575 |
+
function get_terms($tax = '', $merge = true, $TermClass = 'TimberTerm') {
|
576 |
+
if (is_string($merge) && class_exists($merge)){
|
577 |
+
$TermClass = $merge;
|
578 |
+
}
|
579 |
+
if (is_string($tax)) {
|
580 |
+
if (isset($this->_get_terms) && isset($this->_get_terms[$tax])) {
|
581 |
+
return $this->_get_terms[$tax];
|
582 |
+
}
|
583 |
+
}
|
584 |
+
if (!strlen($tax) || $tax == 'all' || $tax == 'any') {
|
585 |
+
$taxs = get_object_taxonomies($this->post_type);
|
586 |
+
} else if (is_array($tax)) {
|
587 |
+
$taxs = $tax;
|
588 |
+
} else {
|
589 |
+
$taxs = array($tax);
|
590 |
+
}
|
591 |
+
$ret = array();
|
592 |
+
foreach ($taxs as $tax) {
|
593 |
+
if ($tax == 'tags' || $tax == 'tag') {
|
594 |
+
$tax = 'post_tag';
|
595 |
+
} else if ($tax == 'categories') {
|
596 |
+
$tax = 'category';
|
597 |
+
}
|
598 |
+
$terms = wp_get_post_terms($this->ID, $tax);
|
599 |
+
if (!is_array($terms) && is_object($terms) && get_class($terms) == 'WP_Error') {
|
600 |
+
//something is very wrong
|
601 |
+
TimberHelper::error_log('You have an error retrieving terms on a post in timber-post.php:367');
|
602 |
+
TimberHelper::error_log('tax = ' . $tax);
|
603 |
+
TimberHelper::error_log($terms);
|
604 |
+
|
605 |
+
} else {
|
606 |
+
foreach ($terms as &$term) {
|
607 |
+
$term = new $TermClass($term->term_id, $tax);
|
608 |
+
}
|
609 |
+
if ($merge && is_array($terms)) {
|
610 |
+
$ret = array_merge($ret, $terms);
|
611 |
+
} else if (count($terms)) {
|
612 |
+
$ret[$tax] = $terms;
|
613 |
+
}
|
614 |
+
}
|
615 |
+
}
|
616 |
+
if (!isset($this->_get_terms)) {
|
617 |
+
$this->_get_terms = array();
|
618 |
+
}
|
619 |
+
$this->_get_terms[$tax] = $ret;
|
620 |
+
return $ret;
|
621 |
+
}
|
622 |
+
|
623 |
+
/**
|
624 |
+
* @param string|int $term_name_or_id
|
625 |
+
* @param string $taxonomy
|
626 |
+
* @return bool
|
627 |
+
*/
|
628 |
+
function has_term($term_name_or_id, $taxonomy = 'all') {
|
629 |
+
if ($taxonomy == 'all' || $taxonomy == 'any') {
|
630 |
+
$taxes = get_object_taxonomies($this->post_type, 'names');
|
631 |
+
$ret = false;
|
632 |
+
foreach ($taxes as $tax) {
|
633 |
+
if (has_term($term_name_or_id, $tax, $this->ID)) {
|
634 |
+
$ret = true;
|
635 |
+
break;
|
636 |
+
}
|
637 |
+
}
|
638 |
+
return $ret;
|
639 |
+
}
|
640 |
+
return has_term($term_name_or_id, $taxonomy, $this->ID);
|
641 |
+
}
|
642 |
+
|
643 |
+
/**
|
644 |
+
* @param string $field
|
645 |
+
* @return TimberImage
|
646 |
+
*/
|
647 |
+
function get_image($field) {
|
648 |
+
return new $this->ImageClass($this->$field);
|
649 |
+
}
|
650 |
+
|
651 |
+
/**
|
652 |
+
* ## Gets an array of tags for you to use
|
653 |
+
* <ul class="tags">
|
654 |
+
* {% for tag in post.tags %}
|
655 |
+
* <li>{{tag.name}}</li>
|
656 |
+
* {% endfor %}
|
657 |
+
* </ul>
|
658 |
+
*/
|
659 |
+
|
660 |
+
/**
|
661 |
+
* @return array
|
662 |
+
*/
|
663 |
+
function get_tags() {
|
664 |
+
return $this->get_terms('tags');
|
665 |
+
}
|
666 |
+
|
667 |
+
/**
|
668 |
+
* ## Outputs the title with filters applied
|
669 |
+
* <h1>{{post.get_title}}</h1>
|
670 |
+
*/
|
671 |
+
|
672 |
+
/**
|
673 |
+
* @return string
|
674 |
+
*/
|
675 |
+
function get_title() {
|
676 |
+
return apply_filters('the_title', $this->post_title, $this->ID);
|
677 |
+
}
|
678 |
+
|
679 |
+
/**
|
680 |
+
* ## Displays the content of the post with filters, shortcodes and wpautop applied
|
681 |
+
* <div class="article-text">{{post.get_content}}</div>
|
682 |
+
*/
|
683 |
+
|
684 |
+
/**
|
685 |
+
* @param int $len
|
686 |
+
* @param int $page
|
687 |
+
* @return string
|
688 |
+
*/
|
689 |
+
function get_content($len = 0, $page = 0) {
|
690 |
+
if ($len == 0 && $page == 0 && $this->_content) {
|
691 |
+
return $this->_content;
|
692 |
+
}
|
693 |
+
$content = $this->post_content;
|
694 |
+
if ($len) {
|
695 |
+
$content = wp_trim_words($content, $len);
|
696 |
+
}
|
697 |
+
if ($page) {
|
698 |
+
$contents = explode('<!--nextpage-->', $content);
|
699 |
+
$page--;
|
700 |
+
if (count($contents) > $page) {
|
701 |
+
$content = $contents[$page];
|
702 |
+
}
|
703 |
+
}
|
704 |
+
$content = apply_filters('the_content', ($content));
|
705 |
+
if ($len == 0 && $page == 0) {
|
706 |
+
$this->_content = $content;
|
707 |
+
}
|
708 |
+
return $content;
|
709 |
+
}
|
710 |
+
|
711 |
+
/**
|
712 |
+
* @return string
|
713 |
+
*/
|
714 |
+
function get_paged_content() {
|
715 |
+
global $page;
|
716 |
+
return $this->get_content(0, $page);
|
717 |
+
}
|
718 |
+
/**
|
719 |
+
* @return mixed
|
720 |
+
*/
|
721 |
+
public function get_post_type() {
|
722 |
+
return get_post_type_object($this->post_type);
|
723 |
+
}
|
724 |
+
|
725 |
+
/**
|
726 |
+
* @return int
|
727 |
+
*/
|
728 |
+
public function get_comment_count() {
|
729 |
+
if (isset($this->ID)) {
|
730 |
+
return get_comments_number($this->ID);
|
731 |
+
} else {
|
732 |
+
return 0;
|
733 |
+
}
|
734 |
+
}
|
735 |
+
|
736 |
+
/**
|
737 |
+
* @param string $field_name
|
738 |
+
* @return mixed
|
739 |
+
*/
|
740 |
+
public function get_field($field_name) {
|
741 |
+
$value = apply_filters('timber_post_get_meta_field_pre', null, $this->ID, $field_name, $this);
|
742 |
+
if ($value === null) {
|
743 |
+
$value = get_post_meta($this->ID, $field_name);
|
744 |
+
if (is_array($value) && count($value) == 1) {
|
745 |
+
$value = $value[0];
|
746 |
+
}
|
747 |
+
if (is_array($value) && count($value) == 0) {
|
748 |
+
$value = null;
|
749 |
+
}
|
750 |
+
}
|
751 |
+
$value = apply_filters('timber_post_get_meta_field', $value, $this->ID, $field_name, $this);
|
752 |
+
return $value;
|
753 |
+
}
|
754 |
+
|
755 |
+
/**
|
756 |
+
* @param string $field_name
|
757 |
+
*/
|
758 |
+
function import_field($field_name) {
|
759 |
+
$this->$field_name = $this->get_field($field_name);
|
760 |
+
}
|
761 |
+
|
762 |
+
/**
|
763 |
+
* @return mixed
|
764 |
+
*/
|
765 |
+
function get_format() {
|
766 |
+
return get_post_format($this->ID);
|
767 |
+
}
|
768 |
+
|
769 |
+
/**
|
770 |
+
* @param string $class
|
771 |
+
* @return string
|
772 |
+
*/
|
773 |
+
public function post_class($class='') {
|
774 |
+
global $post;
|
775 |
+
$old_global_post = $post;
|
776 |
+
$post = $this;
|
777 |
+
$class_array = get_post_class($class, $this->ID);
|
778 |
+
$post = $old_global_post;
|
779 |
+
if (is_array($class_array)){
|
780 |
+
return implode(' ', $class_array);
|
781 |
+
}
|
782 |
+
return $class_array;
|
783 |
+
}
|
784 |
+
|
785 |
+
// Docs
|
786 |
+
|
787 |
+
/**
|
788 |
+
* @return array
|
789 |
+
*/
|
790 |
+
public function get_method_values() {
|
791 |
+
$ret = parent::get_method_values();
|
792 |
+
$ret['author'] = $this->author();
|
793 |
+
$ret['categories'] = $this->categories();
|
794 |
+
$ret['category'] = $this->category();
|
795 |
+
$ret['children'] = $this->children();
|
796 |
+
$ret['comments'] = $this->comments();
|
797 |
+
$ret['content'] = $this->content();
|
798 |
+
$ret['edit_link'] = $this->edit_link();
|
799 |
+
$ret['format'] = $this->format();
|
800 |
+
$ret['link'] = $this->link();
|
801 |
+
$ret['next'] = $this->next();
|
802 |
+
$ret['pagination'] = $this->pagination();
|
803 |
+
$ret['parent'] = $this->parent();
|
804 |
+
$ret['path'] = $this->path();
|
805 |
+
$ret['prev'] = $this->prev();
|
806 |
+
$ret['terms'] = $this->terms();
|
807 |
+
$ret['tags'] = $this->tags();
|
808 |
+
$ret['thumbnail'] = $this->thumbnail();
|
809 |
+
$ret['title'] = $this->title();
|
810 |
+
return $ret;
|
811 |
+
}
|
812 |
+
|
813 |
+
// Aliases
|
814 |
+
/**
|
815 |
+
* @return bool|TimberUser
|
816 |
+
*/
|
817 |
+
public function author() {
|
818 |
+
return $this->get_author();
|
819 |
+
}
|
820 |
+
|
821 |
+
/**
|
822 |
+
* @return bool|TimberUser
|
823 |
+
*/
|
824 |
+
public function modified_author() {
|
825 |
+
return $this->get_modified_author();
|
826 |
+
}
|
827 |
+
|
828 |
+
/**
|
829 |
+
* @return array
|
830 |
+
*/
|
831 |
+
public function categories() {
|
832 |
+
return $this->get_terms('category');
|
833 |
+
}
|
834 |
+
|
835 |
+
/**
|
836 |
+
* @return mixed
|
837 |
+
*/
|
838 |
+
public function category() {
|
839 |
+
return $this->get_category();
|
840 |
+
}
|
841 |
+
|
842 |
+
/**
|
843 |
+
* @return array
|
844 |
+
*/
|
845 |
+
public function children( $post_type = 'any', $childPostClass = false ) {
|
846 |
+
return $this->get_children( $post_type, $childPostClass );
|
847 |
+
}
|
848 |
+
|
849 |
+
/**
|
850 |
+
* @return mixed
|
851 |
+
*/
|
852 |
+
public function comments() {
|
853 |
+
return $this->get_comments();
|
854 |
+
}
|
855 |
+
|
856 |
+
/**
|
857 |
+
* @param int $page
|
858 |
+
* @return string
|
859 |
+
*/
|
860 |
+
public function content($page = 0) {
|
861 |
+
return $this->get_content(0, $page);
|
862 |
+
}
|
863 |
+
|
864 |
+
/**
|
865 |
+
* @return string
|
866 |
+
*/
|
867 |
+
public function paged_content() {
|
868 |
+
return $this->get_paged_content();
|
869 |
+
}
|
870 |
+
|
871 |
+
/**
|
872 |
+
* @param string $date_format
|
873 |
+
* @return string
|
874 |
+
*/
|
875 |
+
public function date($date_format = '') {
|
876 |
+
return $this->get_date($date_format);
|
877 |
+
}
|
878 |
+
|
879 |
+
/**
|
880 |
+
* @return bool|string
|
881 |
+
*/
|
882 |
+
public function edit_link() {
|
883 |
+
return $this->get_edit_url();
|
884 |
+
}
|
885 |
+
|
886 |
+
/**
|
887 |
+
* @return mixed
|
888 |
+
*/
|
889 |
+
public function format() {
|
890 |
+
return $this->get_format();
|
891 |
+
}
|
892 |
+
|
893 |
+
/**
|
894 |
+
* @return string
|
895 |
+
*/
|
896 |
+
public function link() {
|
897 |
+
return $this->get_permalink();
|
898 |
+
}
|
899 |
+
|
900 |
+
/**
|
901 |
+
* @param string $field_name
|
902 |
+
* @return mixed
|
903 |
+
*/
|
904 |
+
public function meta($field_name = null) {
|
905 |
+
if ($field_name == null) {
|
906 |
+
$field_name = 'meta';
|
907 |
+
}
|
908 |
+
return $this->get_field($field_name);
|
909 |
+
}
|
910 |
+
|
911 |
+
/**
|
912 |
+
* @return string
|
913 |
+
*/
|
914 |
+
public function name(){
|
915 |
+
return $this->title();
|
916 |
+
}
|
917 |
+
|
918 |
+
/**
|
919 |
+
* @param string $date_format
|
920 |
+
* @return string
|
921 |
+
*/
|
922 |
+
public function modified_date($date_format = '') {
|
923 |
+
return $this->get_modified_date($date_format);
|
924 |
+
}
|
925 |
+
|
926 |
+
/**
|
927 |
+
* @param string $time_format
|
928 |
+
* @return string
|
929 |
+
*/
|
930 |
+
public function modified_time($time_format = '') {
|
931 |
+
return $this->get_modified_time($time_format);
|
932 |
+
}
|
933 |
+
|
934 |
+
/**
|
935 |
+
* @param bool $in_same_cat
|
936 |
+
* @return mixed
|
937 |
+
*/
|
938 |
+
public function next($in_same_cat = false) {
|
939 |
+
return $this->get_next($in_same_cat);
|
940 |
+
}
|
941 |
+
|
942 |
+
/**
|
943 |
+
* @return array
|
944 |
+
*/
|
945 |
+
public function pagination() {
|
946 |
+
return $this->get_pagination();
|
947 |
+
}
|
948 |
+
|
949 |
+
/**
|
950 |
+
* @return bool|TimberPost
|
951 |
+
*/
|
952 |
+
public function parent() {
|
953 |
+
return $this->get_parent();
|
954 |
+
}
|
955 |
+
|
956 |
+
/**
|
957 |
+
* @return string
|
958 |
+
*/
|
959 |
+
public function path() {
|
960 |
+
return $this->get_path();
|
961 |
+
}
|
962 |
+
|
963 |
+
/**
|
964 |
+
* @return string
|
965 |
+
*/
|
966 |
+
public function permalink() {
|
967 |
+
return $this->get_permalink();
|
968 |
+
}
|
969 |
+
|
970 |
+
/**
|
971 |
+
* @param bool $in_same_cat
|
972 |
+
* @return mixed
|
973 |
+
*/
|
974 |
+
public function prev($in_same_cat = false) {
|
975 |
+
return $this->get_prev($in_same_cat);
|
976 |
+
}
|
977 |
+
|
978 |
+
/**
|
979 |
+
* @param string $tax
|
980 |
+
* @return array
|
981 |
+
*/
|
982 |
+
public function terms($tax = '') {
|
983 |
+
return $this->get_terms($tax);
|
984 |
+
}
|
985 |
+
|
986 |
+
/**
|
987 |
+
* @return array
|
988 |
+
*/
|
989 |
+
public function tags() {
|
990 |
+
return $this->get_tags();
|
991 |
+
}
|
992 |
+
|
993 |
+
/**
|
994 |
+
* @return null|TimberImage
|
995 |
+
*/
|
996 |
+
public function thumbnail() {
|
997 |
+
return $this->get_thumbnail();
|
998 |
+
}
|
999 |
+
|
1000 |
+
/**
|
1001 |
+
* @return string
|
1002 |
+
*/
|
1003 |
+
public function title() {
|
1004 |
+
return $this->get_title();
|
1005 |
+
}
|
1006 |
+
|
1007 |
+
}
|
functions/functions/timber-posts-collection.php
ADDED
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// Exit if accessed directly
|
4 |
+
if ( !defined( 'ABSPATH' ) )
|
5 |
+
exit;
|
6 |
+
|
7 |
+
class TimberPostsCollection extends ArrayObject {
|
8 |
+
|
9 |
+
public function __construct( $array = array(), $post_class = 'TimberPost' ) {
|
10 |
+
$posts = array();
|
11 |
+
if ( is_null( $array ) ){
|
12 |
+
$array = array();
|
13 |
+
}
|
14 |
+
foreach ( $array as $rid ) {
|
15 |
+
$post_class_use = $post_class;
|
16 |
+
|
17 |
+
if ( is_array( $post_class ) ) {
|
18 |
+
$post_type = get_post_type( $rid );
|
19 |
+
$post_class_use = 'TimberPost';
|
20 |
+
|
21 |
+
if ( isset( $post_class[$post_type] ) ) {
|
22 |
+
$post_class_use = $post_class[$post_type];
|
23 |
+
|
24 |
+
} else {
|
25 |
+
if ( is_array( $post_class ) ) {
|
26 |
+
TimberHelper::error_log( $post_type . ' of ' . $rid . ' not found in ' . print_r( $post_class, true ) );
|
27 |
+
} else {
|
28 |
+
TimberHelper::error_log( $post_type . ' not found in ' . $post_class );
|
29 |
+
}
|
30 |
+
}
|
31 |
+
}
|
32 |
+
|
33 |
+
// Don't create yet another object if $rid is already of the right type
|
34 |
+
if ( is_a( $rid, $post_class_use ) ) {
|
35 |
+
$post = $rid;
|
36 |
+
} else {
|
37 |
+
$post = new $post_class_use( $rid );
|
38 |
+
}
|
39 |
+
|
40 |
+
if ( isset( $post->ID ) ) {
|
41 |
+
$posts[] = $post;
|
42 |
+
}
|
43 |
+
}
|
44 |
+
|
45 |
+
$posts = self::maybe_set_preview($posts);
|
46 |
+
|
47 |
+
parent::__construct( $posts, $flags = 0, 'TimberPostsIterator' );
|
48 |
+
}
|
49 |
+
|
50 |
+
public function get_posts() {
|
51 |
+
return $this->getArrayCopy();
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* @param array $posts
|
56 |
+
* @return array
|
57 |
+
*/
|
58 |
+
static function maybe_set_preview( $posts ) {
|
59 |
+
if ( is_array( $posts ) && isset( $_GET['preview'] ) && $_GET['preview']
|
60 |
+
&& isset( $_GET['preview_id'] ) && $_GET['preview_id']
|
61 |
+
&& current_user_can( 'edit_post', $_GET['preview_id'] ) ) {
|
62 |
+
// No need to check the nonce, that already happened in _show_post_preview on init
|
63 |
+
|
64 |
+
$preview_id = $_GET['preview_id'];
|
65 |
+
foreach( $posts as &$post ) {
|
66 |
+
if ( is_object( $post ) && $post->ID == $preview_id ) {
|
67 |
+
// Based on _set_preview( $post ), but adds import_custom
|
68 |
+
$preview = wp_get_post_autosave( $preview_id );
|
69 |
+
if ( is_object($preview) ) {
|
70 |
+
|
71 |
+
$preview = sanitize_post($preview);
|
72 |
+
|
73 |
+
$post->post_content = $preview->post_content;
|
74 |
+
$post->post_title = $preview->post_title;
|
75 |
+
$post->post_excerpt = $preview->post_excerpt;
|
76 |
+
$post->import_custom( $preview_id );
|
77 |
+
|
78 |
+
add_filter( 'get_the_terms', '_wp_preview_terms_filter', 10, 3 );
|
79 |
+
}
|
80 |
+
}
|
81 |
+
}
|
82 |
+
|
83 |
+
}
|
84 |
+
|
85 |
+
return $posts;
|
86 |
+
}
|
87 |
+
|
88 |
+
}
|
89 |
+
|
90 |
+
class TimberPostsIterator extends ArrayIterator {
|
91 |
+
|
92 |
+
public function current() {
|
93 |
+
global $post;
|
94 |
+
$post = parent::current();
|
95 |
+
return $post;
|
96 |
+
}
|
97 |
+
}
|
functions/functions/timber-query-iterator.php
ADDED
@@ -0,0 +1,141 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// Exit if accessed directly
|
3 |
+
if ( !defined( 'ABSPATH' ) )
|
4 |
+
exit;
|
5 |
+
|
6 |
+
class TimberQueryIterator implements Iterator {
|
7 |
+
|
8 |
+
/**
|
9 |
+
*
|
10 |
+
*
|
11 |
+
* @var WP_Query
|
12 |
+
*/
|
13 |
+
private $_query = null;
|
14 |
+
private $_posts_class = 'TimberPost';
|
15 |
+
|
16 |
+
public function __construct( $query = false, $posts_class = 'TimberPost' ) {
|
17 |
+
add_action( 'pre_get_posts', array($this, 'fix_number_posts_wp_quirk' ));
|
18 |
+
if ( $posts_class )
|
19 |
+
$this->_posts_class = $posts_class;
|
20 |
+
|
21 |
+
if ( is_a( $query, 'WP_Query' ) ) {
|
22 |
+
// We got a full-fledged WP Query, look no further!
|
23 |
+
$the_query = $query;
|
24 |
+
|
25 |
+
} elseif ( false === $query ) {
|
26 |
+
// If query is explicitly set to false, use the main loop
|
27 |
+
global $wp_query;
|
28 |
+
$the_query =& $wp_query;
|
29 |
+
|
30 |
+
} elseif ( TimberHelper::is_array_assoc( $query ) || ( is_string( $query ) && strstr( $query, '=' ) ) ) {
|
31 |
+
// We have a regularly formed WP query string or array to use
|
32 |
+
$the_query = new WP_Query( $query );
|
33 |
+
|
34 |
+
} elseif ( is_numeric( $query ) || is_string( $query ) ) {
|
35 |
+
// We have what could be a post name or post ID to pull out
|
36 |
+
$the_query = self::get_query_from_string( $query );
|
37 |
+
|
38 |
+
} elseif ( is_array( $query ) && count( $query ) && ( is_integer( $query[0] ) || is_string( $query[0] ) ) ) {
|
39 |
+
// We have a list of pids (post IDs) to extract from
|
40 |
+
$the_query = self::get_query_from_array_of_ids( $query );
|
41 |
+
} elseif ( is_array($query) && empty($query)) {
|
42 |
+
// it's an empty array
|
43 |
+
$the_query = array();
|
44 |
+
} else {
|
45 |
+
TimberHelper::error_log( 'I have failed you! in ' . basename( __FILE__ ) . '::' . __LINE__ );
|
46 |
+
TimberHelper::error_log( $query );
|
47 |
+
|
48 |
+
// We have failed hard, at least let get something.
|
49 |
+
$the_query = new WP_Query();
|
50 |
+
}
|
51 |
+
|
52 |
+
$this->_query = $the_query;
|
53 |
+
|
54 |
+
}
|
55 |
+
|
56 |
+
public function get_posts( $return_collection = false ) {
|
57 |
+
if (isset($this->_query->posts)){
|
58 |
+
$posts = new TimberPostsCollection( $this->_query->posts, $this->_posts_class );
|
59 |
+
return ( $return_collection ) ? $posts : $posts->get_posts();
|
60 |
+
}
|
61 |
+
}
|
62 |
+
|
63 |
+
//
|
64 |
+
// GET POSTS
|
65 |
+
//
|
66 |
+
public static function get_query_from_array_of_ids( $query = array() ) {
|
67 |
+
if ( !is_array( $query ) || !count( $query ) )
|
68 |
+
return null;
|
69 |
+
|
70 |
+
return new WP_Query( array(
|
71 |
+
'post_type'=> 'any',
|
72 |
+
'ignore_sticky_posts' => true,
|
73 |
+
'post__in' => $query,
|
74 |
+
'orderby' => 'post__in',
|
75 |
+
'nopaging' => true
|
76 |
+
) );
|
77 |
+
}
|
78 |
+
|
79 |
+
public static function get_query_from_string( $string = '' ) {
|
80 |
+
$post_type = false;
|
81 |
+
|
82 |
+
if ( is_string( $string ) && strstr( $string, '#' ) ) {
|
83 |
+
//we have a post_type directive here
|
84 |
+
list( $post_type, $string ) = explode( '#', $string );
|
85 |
+
}
|
86 |
+
|
87 |
+
$query = array(
|
88 |
+
'post_type' => ( $post_type ) ? $post_type : 'any'
|
89 |
+
);
|
90 |
+
|
91 |
+
if ( is_numeric( $string ) ) {
|
92 |
+
$query['p'] = $string;
|
93 |
+
|
94 |
+
} else {
|
95 |
+
$query['name'] = $string;
|
96 |
+
}
|
97 |
+
|
98 |
+
return new WP_Query( $query );
|
99 |
+
}
|
100 |
+
|
101 |
+
//
|
102 |
+
// Iterator Interface
|
103 |
+
//
|
104 |
+
|
105 |
+
public function valid() {
|
106 |
+
return $this->_query->have_posts();
|
107 |
+
}
|
108 |
+
|
109 |
+
public function current() {
|
110 |
+
global $post;
|
111 |
+
|
112 |
+
$this->_query->the_post();
|
113 |
+
|
114 |
+
// Sets up the global post, but also return the post, for use in Twig template
|
115 |
+
$posts_class = $this->_posts_class;
|
116 |
+
return new $posts_class( $post );
|
117 |
+
}
|
118 |
+
|
119 |
+
/**
|
120 |
+
* Don't implement next, because current already advances the loop
|
121 |
+
*/
|
122 |
+
final public function next() {}
|
123 |
+
|
124 |
+
public function rewind() {
|
125 |
+
$this->_query->rewind_posts();
|
126 |
+
}
|
127 |
+
|
128 |
+
public function key() {
|
129 |
+
$this->_query->current_post;
|
130 |
+
}
|
131 |
+
|
132 |
+
//get_posts users numberposts
|
133 |
+
static function fix_number_posts_wp_quirk( $query ) {
|
134 |
+
if (isset($query->query) && isset($query->query['numberposts'])
|
135 |
+
&& !isset($query->query['posts_per_page'])) {
|
136 |
+
$query->set( 'posts_per_page', $query->query['numberposts'] );
|
137 |
+
}
|
138 |
+
return $query;
|
139 |
+
}
|
140 |
+
|
141 |
+
}
|
functions/functions/timber-routes.php
ADDED
@@ -0,0 +1,111 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TimberRoutes {
|
4 |
+
|
5 |
+
protected $router;
|
6 |
+
|
7 |
+
function __construct(){
|
8 |
+
add_action('init', array($this, 'init'));
|
9 |
+
}
|
10 |
+
|
11 |
+
function init() {
|
12 |
+
global $timber;
|
13 |
+
if (isset($timber->router)) {
|
14 |
+
$route = $timber->router->matchCurrentRequest();
|
15 |
+
if ($route) {
|
16 |
+
$callback = $route->getTarget();
|
17 |
+
$params = $route->getParameters();
|
18 |
+
$callback($params);
|
19 |
+
}
|
20 |
+
}
|
21 |
+
}
|
22 |
+
|
23 |
+
/**
|
24 |
+
* @param string $route
|
25 |
+
* @param callable $callback
|
26 |
+
*/
|
27 |
+
public static function add_route($route, $callback, $args = array()) {
|
28 |
+
global $timber;
|
29 |
+
if (!isset($timber->router)) {
|
30 |
+
if (class_exists('PHPRouter\Router')){
|
31 |
+
$timber->router = new PHPRouter\Router();
|
32 |
+
$site_url = get_bloginfo('url');
|
33 |
+
$site_url_parts = explode('/', $site_url);
|
34 |
+
$site_url_parts = array_slice($site_url_parts, 3);
|
35 |
+
$base_path = implode('/', $site_url_parts);
|
36 |
+
if (!$base_path || strpos($route, $base_path) === 0) {
|
37 |
+
$base_path = '/';
|
38 |
+
} else {
|
39 |
+
$base_path = '/' . $base_path . '/';
|
40 |
+
}
|
41 |
+
$timber->router->setBasePath($base_path);
|
42 |
+
}
|
43 |
+
}
|
44 |
+
if (class_exists('PHPRouter\Router')){
|
45 |
+
$timber->router->map($route, $callback, $args);
|
46 |
+
}
|
47 |
+
}
|
48 |
+
|
49 |
+
/**
|
50 |
+
* @param array $template
|
51 |
+
* @param mixed $query
|
52 |
+
* @param int $status_code
|
53 |
+
* @param bool $tparams
|
54 |
+
* @return bool
|
55 |
+
*/
|
56 |
+
public static function load_view($template, $query = false, $status_code = 200, $tparams = false) {
|
57 |
+
$fullPath = is_readable($template);
|
58 |
+
if (!$fullPath) {
|
59 |
+
$template = locate_template($template);
|
60 |
+
}
|
61 |
+
if ($tparams){
|
62 |
+
global $params;
|
63 |
+
$params = $tparams;
|
64 |
+
}
|
65 |
+
if ($status_code) {
|
66 |
+
add_filter('status_header', function($status_header, $header, $text, $protocol) use ($status_code) {
|
67 |
+
$text = get_status_header_desc($status_code);
|
68 |
+
$header_string = "$protocol $status_code $text";
|
69 |
+
return $header_string;
|
70 |
+
}, 10, 4 );
|
71 |
+
if (404 != $status_code) {
|
72 |
+
add_action('parse_query', function($query) {
|
73 |
+
if ($query->is_main_query()){
|
74 |
+
$query->is_404 = false;
|
75 |
+
}
|
76 |
+
},1);
|
77 |
+
add_action('template_redirect', function(){
|
78 |
+
global $wp_query;
|
79 |
+
$wp_query->is_404 = false;
|
80 |
+
},1);
|
81 |
+
}
|
82 |
+
}
|
83 |
+
|
84 |
+
if ($query) {
|
85 |
+
add_action('do_parse_request', function() use ($query) {
|
86 |
+
global $wp;
|
87 |
+
if ( is_callable($query) )
|
88 |
+
$query = call_user_func($query);
|
89 |
+
|
90 |
+
if ( is_array($query) )
|
91 |
+
$wp->query_vars = $query;
|
92 |
+
elseif ( !empty($query) )
|
93 |
+
parse_str($query, $wp->query_vars);
|
94 |
+
else
|
95 |
+
return true; // Could not interpret query. Let WP try.
|
96 |
+
|
97 |
+
return false;
|
98 |
+
});
|
99 |
+
}
|
100 |
+
if ($template) {
|
101 |
+
add_filter('template_include', function($t) use ($template) {
|
102 |
+
return $template;
|
103 |
+
});
|
104 |
+
return true;
|
105 |
+
}
|
106 |
+
return false;
|
107 |
+
}
|
108 |
+
}
|
109 |
+
|
110 |
+
global $timberRoutes;
|
111 |
+
$timberRoutes = new TimberRoutes();
|
functions/functions/timber-site.php
ADDED
@@ -0,0 +1,149 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TimberSite extends TimberCore implements TimberCoreInterface {
|
4 |
+
|
5 |
+
public $admin_email;
|
6 |
+
public $blogname;
|
7 |
+
public $charset;
|
8 |
+
public $description;
|
9 |
+
public $id;
|
10 |
+
public $language;
|
11 |
+
public $language_attributes;
|
12 |
+
public $multisite;
|
13 |
+
public $name;
|
14 |
+
public $pingback_url;
|
15 |
+
public $siteurl;
|
16 |
+
public $theme;
|
17 |
+
public $title;
|
18 |
+
public $url;
|
19 |
+
|
20 |
+
/**
|
21 |
+
*
|
22 |
+
*
|
23 |
+
* @param string|int $site_name_or_id
|
24 |
+
*/
|
25 |
+
function __construct( $site_name_or_id = null ) {
|
26 |
+
if ( is_multisite() ) {
|
27 |
+
$this->init_with_multisite( $site_name_or_id );
|
28 |
+
} else {
|
29 |
+
$this->init();
|
30 |
+
}
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
*
|
35 |
+
*
|
36 |
+
* @param string|int $site_name_or_id
|
37 |
+
*/
|
38 |
+
function init_with_multisite( $site_name_or_id ) {
|
39 |
+
if ( $site_name_or_id === null ) {
|
40 |
+
//this is necessary for some reason, otherwise returns 1 all the time
|
41 |
+
if ( is_multisite() ) {
|
42 |
+
restore_current_blog();
|
43 |
+
$site_name_or_id = get_current_blog_id();
|
44 |
+
}
|
45 |
+
}
|
46 |
+
$info = get_blog_details( $site_name_or_id );
|
47 |
+
$this->import( $info );
|
48 |
+
$this->ID = $info->blog_id;
|
49 |
+
$this->name = $this->blogname;
|
50 |
+
$this->title = $this->blogname;
|
51 |
+
$this->url = $this->siteurl;
|
52 |
+
$this->id = $this->ID;
|
53 |
+
$theme_slug = get_blog_option( $info->blog_id, 'stylesheet' );
|
54 |
+
$this->theme = new TimberTheme( $theme_slug );
|
55 |
+
$this->description = get_blog_option( $info->blog_id, 'blogdescription' );
|
56 |
+
$this->multisite = true;
|
57 |
+
}
|
58 |
+
|
59 |
+
function init() {
|
60 |
+
$this->admin_email = get_bloginfo( 'admin_email' );
|
61 |
+
$this->name = get_bloginfo( 'name' );
|
62 |
+
$this->title = $this->name;
|
63 |
+
$this->description = get_bloginfo( 'description' );
|
64 |
+
$this->url = get_bloginfo( 'url' );
|
65 |
+
$this->language = get_bloginfo( 'language' );
|
66 |
+
$this->charset = get_bloginfo( 'charset' );
|
67 |
+
$this->pingback_url = get_bloginfo( 'pingback_url' );
|
68 |
+
$this->theme = new TimberTheme();
|
69 |
+
$this->language_attributes = TimberHelper::function_wrapper( 'language_attributes' );
|
70 |
+
$this->multisite = false;
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
*
|
75 |
+
*
|
76 |
+
* @param string $field
|
77 |
+
* @return mixed
|
78 |
+
*/
|
79 |
+
function __get( $field ) {
|
80 |
+
if ( !isset( $this->$field ) ) {
|
81 |
+
if ( is_multisite() ) {
|
82 |
+
$this->$field = get_blog_option( $this->ID, $field );
|
83 |
+
} else {
|
84 |
+
$this->$field = get_option( $field );
|
85 |
+
}
|
86 |
+
}
|
87 |
+
return $this->$field;
|
88 |
+
}
|
89 |
+
|
90 |
+
/**
|
91 |
+
*
|
92 |
+
*
|
93 |
+
* @return string
|
94 |
+
*/
|
95 |
+
function get_link() {
|
96 |
+
return $this->url;
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
*
|
101 |
+
*
|
102 |
+
* @return string
|
103 |
+
*/
|
104 |
+
function get_url() {
|
105 |
+
return $this->get_link();
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
*
|
110 |
+
*
|
111 |
+
* @return string
|
112 |
+
*/
|
113 |
+
function link() {
|
114 |
+
return $this->get_link();
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
*
|
119 |
+
*/
|
120 |
+
function meta( $field ) {
|
121 |
+
return $this->__get( $field );
|
122 |
+
}
|
123 |
+
|
124 |
+
/**
|
125 |
+
*
|
126 |
+
*
|
127 |
+
* @param string $key
|
128 |
+
* @param mixed $value
|
129 |
+
*/
|
130 |
+
function update( $key, $value ) {
|
131 |
+
$value = apply_filters( 'timber_site_set_meta', $value, $key, $this->ID, $this );
|
132 |
+
if ( is_multisite() ) {
|
133 |
+
update_blog_option( $this->ID, $key, $value );
|
134 |
+
} else {
|
135 |
+
update_option( $key, $value );
|
136 |
+
}
|
137 |
+
$this->$key = $value;
|
138 |
+
}
|
139 |
+
|
140 |
+
/**
|
141 |
+
*
|
142 |
+
*
|
143 |
+
* @return string
|
144 |
+
*/
|
145 |
+
function url() {
|
146 |
+
return $this->get_link();
|
147 |
+
}
|
148 |
+
|
149 |
+
}
|
functions/functions/timber-term-getter.php
ADDED
@@ -0,0 +1,182 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TimberTermGetter
|
4 |
+
{
|
5 |
+
|
6 |
+
/**
|
7 |
+
* @param string|array $args
|
8 |
+
* @param array $maybe_args
|
9 |
+
* @param string $TermClass
|
10 |
+
* @return mixed
|
11 |
+
*/
|
12 |
+
public static function get_terms($args = null, $maybe_args = array(), $TermClass = 'TimberTerm'){
|
13 |
+
if (is_string($maybe_args) && !strstr($maybe_args, '=')){
|
14 |
+
//the user is sending the $TermClass in the second argument
|
15 |
+
$TermClass = $maybe_args;
|
16 |
+
}
|
17 |
+
if (is_string($maybe_args) && strstr($maybe_args, '=')){
|
18 |
+
parse_str($maybe_args, $maybe_args);
|
19 |
+
}
|
20 |
+
if (is_string($args) && strstr($args, '=')){
|
21 |
+
//a string and a query string!
|
22 |
+
$parsed = TimberTermGetter::get_term_query_from_query_string($args);
|
23 |
+
if (is_array($maybe_args)){
|
24 |
+
$parsed->args = array_merge($parsed->args, $maybe_args);
|
25 |
+
}
|
26 |
+
return self::handle_term_query($parsed->taxonomies, $parsed->args, $TermClass);
|
27 |
+
} else if (is_string($args)){
|
28 |
+
//its just a string with a single taxonomy
|
29 |
+
$parsed = TimberTermGetter::get_term_query_from_string($args);
|
30 |
+
if (is_array($maybe_args)){
|
31 |
+
$parsed->args = array_merge($parsed->args, $maybe_args);
|
32 |
+
}
|
33 |
+
return self::handle_term_query($parsed->taxonomies, $parsed->args, $TermClass);
|
34 |
+
} else if (is_array($args) && TimberHelper::is_array_assoc($args)){
|
35 |
+
//its an associative array, like a good ole query
|
36 |
+
$parsed = TimberTermGetter::get_term_query_from_assoc_array($args);
|
37 |
+
return self::handle_term_query($parsed->taxonomies, $parsed->args, $TermClass);
|
38 |
+
} else if (is_array($args)){
|
39 |
+
//its just an array of strings or IDs (hopefully)
|
40 |
+
$parsed = TimberTermGetter::get_term_query_from_array($args);
|
41 |
+
if (is_array($maybe_args)){
|
42 |
+
$parsed->args = array_merge($parsed->args, $maybe_args);
|
43 |
+
}
|
44 |
+
return self::handle_term_query($parsed->taxonomies, $parsed->args, $TermClass);
|
45 |
+
} else if (is_null($args)) {
|
46 |
+
return self::handle_term_query(get_taxonomies(), array(), $TermClass);
|
47 |
+
}
|
48 |
+
return null;
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* @param string|array $taxonomies
|
53 |
+
* @param string|array $args
|
54 |
+
* @param string $TermClass
|
55 |
+
* @return mixed
|
56 |
+
*/
|
57 |
+
public static function handle_term_query($taxonomies, $args, $TermClass){
|
58 |
+
if (!isset($args['hide_empty'])){
|
59 |
+
$args['hide_empty'] = false;
|
60 |
+
}
|
61 |
+
if (isset($args['term_id']) && is_int($args['term_id'])){
|
62 |
+
$args['term_id'] = array($args['term_id']);
|
63 |
+
}
|
64 |
+
if (isset($args['term_id'])){
|
65 |
+
$args['include'] = $args['term_id'];
|
66 |
+
}
|
67 |
+
$terms = get_terms($taxonomies, $args);
|
68 |
+
foreach($terms as &$term){
|
69 |
+
$term = new $TermClass($term->term_id, $term->taxonomy);
|
70 |
+
}
|
71 |
+
return $terms;
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* @param string $query_string
|
76 |
+
* @return stdClass
|
77 |
+
*/
|
78 |
+
public static function get_term_query_from_query_string($query_string) {
|
79 |
+
$args = array();
|
80 |
+
parse_str($query_string, $args);
|
81 |
+
$ret = self::get_term_query_from_assoc_array($args);
|
82 |
+
return $ret;
|
83 |
+
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* @param string $taxs
|
87 |
+
* @return stdClass
|
88 |
+
*/
|
89 |
+
public static function get_term_query_from_string($taxs) {
|
90 |
+
$ret = new stdClass();
|
91 |
+
$ret->args = array();
|
92 |
+
if (is_string($taxs)) {
|
93 |
+
$taxs = array($taxs);
|
94 |
+
}
|
95 |
+
$ret->taxonomies = self::correct_taxonomy_names($taxs);
|
96 |
+
return $ret;
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* @param array $args
|
101 |
+
* @return stdClass
|
102 |
+
*/
|
103 |
+
public static function get_term_query_from_assoc_array($args) {
|
104 |
+
$ret = new stdClass();
|
105 |
+
$ret->args = $args;
|
106 |
+
if (isset($ret->args['tax'])) {
|
107 |
+
$ret->taxonomies = $ret->args['tax'];
|
108 |
+
} else if (isset($ret->args['taxonomies'])) {
|
109 |
+
$ret->taxonomies = $ret->args['taxonomies'];
|
110 |
+
} else if (isset($ret->args['taxs'])) {
|
111 |
+
$ret->taxonomies = $ret->args['taxs'];
|
112 |
+
} else if (isset($ret->args['taxonomy'])) {
|
113 |
+
$ret->taxonomies = $ret->args['taxonomy'];
|
114 |
+
}
|
115 |
+
if (isset($ret->taxonomies)) {
|
116 |
+
if (is_string($ret->taxonomies)) {
|
117 |
+
$ret->taxonomies = array($ret->taxonomies);
|
118 |
+
}
|
119 |
+
$ret->taxonomies = self::correct_taxonomy_names($ret->taxonomies);
|
120 |
+
} else {
|
121 |
+
$ret->taxonomies = get_taxonomies();
|
122 |
+
}
|
123 |
+
return $ret;
|
124 |
+
}
|
125 |
+
|
126 |
+
/**
|
127 |
+
* @param array $args
|
128 |
+
* @return stdClass
|
129 |
+
*/
|
130 |
+
public static function get_term_query_from_array($args) {
|
131 |
+
if (is_array($args) && !empty($args)) {
|
132 |
+
//okay its an array with content
|
133 |
+
if (is_int($args[0])) {
|
134 |
+
return self::get_term_query_from_array_of_ids($args);
|
135 |
+
} else if (is_string($args[0])) {
|
136 |
+
return self::get_term_query_from_array_of_strings($args);
|
137 |
+
}
|
138 |
+
}
|
139 |
+
return null;
|
140 |
+
}
|
141 |
+
|
142 |
+
/**
|
143 |
+
* @param integer[] $args
|
144 |
+
* @return stdClass
|
145 |
+
*/
|
146 |
+
public static function get_term_query_from_array_of_ids($args) {
|
147 |
+
$ret = new stdClass();
|
148 |
+
$ret->taxonomies = get_taxonomies();
|
149 |
+
$ret->args['include'] = $args;
|
150 |
+
return $ret;
|
151 |
+
}
|
152 |
+
|
153 |
+
/**
|
154 |
+
* @param string[] $args
|
155 |
+
* @return stdClass
|
156 |
+
*/
|
157 |
+
public static function get_term_query_from_array_of_strings($args) {
|
158 |
+
$ret = new stdClass();
|
159 |
+
$ret->taxonomies = self::correct_taxonomy_names($args);
|
160 |
+
$ret->args = array();
|
161 |
+
return $ret;
|
162 |
+
}
|
163 |
+
|
164 |
+
/**
|
165 |
+
* @param string|array $taxs
|
166 |
+
* @return array
|
167 |
+
*/
|
168 |
+
private static function correct_taxonomy_names($taxs) {
|
169 |
+
if (is_string($taxs)) {
|
170 |
+
$taxs = array($taxs);
|
171 |
+
}
|
172 |
+
foreach ($taxs as &$tax) {
|
173 |
+
if ($tax == 'tags' || $tax == 'tag') {
|
174 |
+
$tax = 'post_tag';
|
175 |
+
} else if ($tax == 'categories') {
|
176 |
+
$tax = 'category';
|
177 |
+
}
|
178 |
+
}
|
179 |
+
return $taxs;
|
180 |
+
}
|
181 |
+
|
182 |
+
}
|
functions/functions/timber-term.php
ADDED
@@ -0,0 +1,328 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TimberTerm extends TimberCore implements TimberCoreInterface {
|
4 |
+
|
5 |
+
public $PostClass = 'TimberPost';
|
6 |
+
public $TermClass = 'TimberTerm';
|
7 |
+
|
8 |
+
public $object_type = 'term';
|
9 |
+
public static $representation = 'term';
|
10 |
+
|
11 |
+
public $_children;
|
12 |
+
public $name;
|
13 |
+
public $taxonomy;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @param int $tid
|
17 |
+
* @param string $tax
|
18 |
+
*/
|
19 |
+
function __construct($tid = null, $tax = '') {
|
20 |
+
if ($tid === null) {
|
21 |
+
$tid = $this->get_term_from_query();
|
22 |
+
}
|
23 |
+
if (strlen($tax)) {
|
24 |
+
$this->taxonomy = $tax;
|
25 |
+
}
|
26 |
+
$this->init($tid);
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* @return string
|
31 |
+
*/
|
32 |
+
function __toString() {
|
33 |
+
return $this->name;
|
34 |
+
}
|
35 |
+
|
36 |
+
|
37 |
+
|
38 |
+
/* Setup
|
39 |
+
===================== */
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @return integer
|
43 |
+
*/
|
44 |
+
private function get_term_from_query() {
|
45 |
+
global $wp_query;
|
46 |
+
$qo = $wp_query->queried_object;
|
47 |
+
return $qo->term_id;
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* @param int $tid
|
52 |
+
*/
|
53 |
+
private function init($tid) {
|
54 |
+
$term = $this->get_term($tid);
|
55 |
+
if (isset($term->id)) {
|
56 |
+
$term->ID = $term->id;
|
57 |
+
} else if (isset($term->term_id)) {
|
58 |
+
$term->ID = $term->term_id;
|
59 |
+
} else if (is_string($tid)) {
|
60 |
+
//echo 'bad call using '.$tid;
|
61 |
+
//TimberHelper::error_log(debug_backtrace());
|
62 |
+
}
|
63 |
+
if (isset($term->ID)){
|
64 |
+
$term->id = $term->ID;
|
65 |
+
$this->import($term);
|
66 |
+
if (isset($term->term_id)) {
|
67 |
+
$custom = $this->get_term_meta($term->term_id);
|
68 |
+
$this->import($custom);
|
69 |
+
}
|
70 |
+
}
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* @param int $tid
|
75 |
+
* @return array
|
76 |
+
*/
|
77 |
+
private function get_term_meta($tid) {
|
78 |
+
$customs = array();
|
79 |
+
$customs = apply_filters('timber_term_get_meta', $customs, $tid, $this);
|
80 |
+
return $customs;
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* @param int $tid
|
85 |
+
* @return mixed
|
86 |
+
*/
|
87 |
+
private function get_term($tid) {
|
88 |
+
if (is_object($tid) || is_array($tid)) {
|
89 |
+
return $tid;
|
90 |
+
}
|
91 |
+
$tid = self::get_tid($tid);
|
92 |
+
|
93 |
+
if (isset($this->taxonomy) && strlen($this->taxonomy)) {
|
94 |
+
return get_term($tid, $this->taxonomy);
|
95 |
+
} else {
|
96 |
+
global $wpdb;
|
97 |
+
$query = $wpdb->prepare("SELECT taxonomy FROM $wpdb->term_taxonomy WHERE term_id = %d LIMIT 1", $tid);
|
98 |
+
$tax = $wpdb->get_var($query);
|
99 |
+
if (isset($tax) && strlen($tax)) {
|
100 |
+
return get_term($tid, $tax);
|
101 |
+
}
|
102 |
+
}
|
103 |
+
return null;
|
104 |
+
}
|
105 |
+
|
106 |
+
/**
|
107 |
+
* @param int $tid
|
108 |
+
* @return int
|
109 |
+
*/
|
110 |
+
private function get_tid($tid) {
|
111 |
+
global $wpdb;
|
112 |
+
if (is_numeric($tid)) {
|
113 |
+
return $tid;
|
114 |
+
}
|
115 |
+
if (gettype($tid) == 'object') {
|
116 |
+
$tid = $tid->term_id;
|
117 |
+
}
|
118 |
+
if (is_numeric($tid)) {
|
119 |
+
$query = $wpdb->prepare("SELECT * FROM $wpdb->terms WHERE term_id = %d", $tid);
|
120 |
+
} else {
|
121 |
+
$query = $wpdb->prepare("SELECT * FROM $wpdb->terms WHERE slug = %s", $tid);
|
122 |
+
}
|
123 |
+
$result = $wpdb->get_row($query);
|
124 |
+
if (isset($result->term_id)) {
|
125 |
+
$result->ID = $result->term_id;
|
126 |
+
$result->id = $result->term_id;
|
127 |
+
return $result->ID;
|
128 |
+
}
|
129 |
+
return 0;
|
130 |
+
}
|
131 |
+
|
132 |
+
/* Public methods
|
133 |
+
===================== */
|
134 |
+
|
135 |
+
/**
|
136 |
+
* @return string
|
137 |
+
*/
|
138 |
+
public function get_edit_url() {
|
139 |
+
return get_edit_term_link($this->ID, $this->taxonomy);
|
140 |
+
}
|
141 |
+
|
142 |
+
/**
|
143 |
+
* @param string $field_name
|
144 |
+
* @return string
|
145 |
+
*/
|
146 |
+
public function get_meta_field($field_name) {
|
147 |
+
if (!isset($this->$field_name)) {
|
148 |
+
$field_value = '';
|
149 |
+
$field_value = apply_filters('timber_term_get_meta_field', $field_value, $this->ID, $field_name, $this);
|
150 |
+
$this->$field_name = $field_value;
|
151 |
+
}
|
152 |
+
return $this->$field_name;
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
* @return string
|
157 |
+
*/
|
158 |
+
public function get_path() {
|
159 |
+
$link = $this->get_link();
|
160 |
+
$rel = TimberURLHelper::get_rel_url($link, true);
|
161 |
+
return apply_filters('timber_term_path', $rel, $this);
|
162 |
+
}
|
163 |
+
|
164 |
+
/**
|
165 |
+
* @return string
|
166 |
+
*/
|
167 |
+
public function get_link() {
|
168 |
+
$link = get_term_link($this);
|
169 |
+
return apply_filters('timber_term_link', $link, $this);
|
170 |
+
}
|
171 |
+
|
172 |
+
/**
|
173 |
+
* @param int $numberposts
|
174 |
+
* @param string $post_type
|
175 |
+
* @param string $PostClass
|
176 |
+
* @return array|bool|null
|
177 |
+
*/
|
178 |
+
public function get_posts($numberposts = 10, $post_type = 'any', $PostClass = '') {
|
179 |
+
if (!strlen($PostClass)) {
|
180 |
+
$PostClass = $this->PostClass;
|
181 |
+
}
|
182 |
+
$default_tax_query = array(array(
|
183 |
+
'field' => 'id',
|
184 |
+
'terms' => $this->ID,
|
185 |
+
'taxonomy' => $this->taxonomy,
|
186 |
+
));
|
187 |
+
if (is_string($numberposts) && strstr($numberposts, '=')) {
|
188 |
+
$args = $numberposts;
|
189 |
+
$new_args = array();
|
190 |
+
parse_str($args, $new_args);
|
191 |
+
$args = $new_args;
|
192 |
+
$args['tax_query'] = $default_tax_query;
|
193 |
+
if (!isset($args['post_type'])) {
|
194 |
+
$args['post_type'] = 'any';
|
195 |
+
}
|
196 |
+
if (class_exists($post_type)) {
|
197 |
+
$PostClass = $post_type;
|
198 |
+
}
|
199 |
+
} else if (is_array($numberposts)) {
|
200 |
+
//they sent us an array already baked
|
201 |
+
$args = $numberposts;
|
202 |
+
if (!isset($args['tax_query'])) {
|
203 |
+
$args['tax_query'] = $default_tax_query;
|
204 |
+
}
|
205 |
+
if (class_exists($post_type)) {
|
206 |
+
$PostClass = $post_type;
|
207 |
+
}
|
208 |
+
if (!isset($args['post_type'])) {
|
209 |
+
$args['post_type'] = 'any';
|
210 |
+
}
|
211 |
+
} else {
|
212 |
+
$args = array(
|
213 |
+
'numberposts' => $numberposts,
|
214 |
+
'tax_query' => $default_tax_query,
|
215 |
+
'post_type' => $post_type
|
216 |
+
);
|
217 |
+
}
|
218 |
+
return Timber::get_posts($args, $PostClass);
|
219 |
+
}
|
220 |
+
|
221 |
+
/**
|
222 |
+
* @return array
|
223 |
+
*/
|
224 |
+
public function get_children() {
|
225 |
+
if (!isset($this->_children)) {
|
226 |
+
$children = get_term_children($this->ID, $this->taxonomy);
|
227 |
+
foreach ($children as &$child) {
|
228 |
+
$child = new TimberTerm($child);
|
229 |
+
}
|
230 |
+
$this->_children = $children;
|
231 |
+
}
|
232 |
+
return $this->_children;
|
233 |
+
}
|
234 |
+
|
235 |
+
/**
|
236 |
+
*
|
237 |
+
*
|
238 |
+
* @param string $key
|
239 |
+
* @param mixed $value
|
240 |
+
*/
|
241 |
+
function update( $key, $value ) {
|
242 |
+
$value = apply_filters( 'timber_term_set_meta', $value, $key, $this->ID, $this );
|
243 |
+
$this->$key = $value;
|
244 |
+
}
|
245 |
+
|
246 |
+
/* Alias
|
247 |
+
====================== */
|
248 |
+
|
249 |
+
/**
|
250 |
+
* @return array
|
251 |
+
*/
|
252 |
+
public function children() {
|
253 |
+
return $this->get_children();
|
254 |
+
}
|
255 |
+
|
256 |
+
/**
|
257 |
+
* @return string
|
258 |
+
*/
|
259 |
+
public function edit_link() {
|
260 |
+
return $this->get_edit_url();
|
261 |
+
}
|
262 |
+
|
263 |
+
/**
|
264 |
+
* @return string
|
265 |
+
*/
|
266 |
+
public function get_url() {
|
267 |
+
return $this->get_link();
|
268 |
+
}
|
269 |
+
|
270 |
+
/**
|
271 |
+
* @return string
|
272 |
+
*/
|
273 |
+
public function link() {
|
274 |
+
return $this->get_link();
|
275 |
+
}
|
276 |
+
|
277 |
+
/**
|
278 |
+
* @param string $field_name
|
279 |
+
* @return string
|
280 |
+
*/
|
281 |
+
public function meta($field_name) {
|
282 |
+
return $this->get_meta_field($field_name);
|
283 |
+
}
|
284 |
+
|
285 |
+
/**
|
286 |
+
* @return string
|
287 |
+
*/
|
288 |
+
public function path() {
|
289 |
+
return $this->get_path();
|
290 |
+
}
|
291 |
+
|
292 |
+
/**
|
293 |
+
* @param int $numberposts_or_args
|
294 |
+
* @param string $post_type_or_class
|
295 |
+
* @param string $post_class
|
296 |
+
* @return array|bool|null
|
297 |
+
*/
|
298 |
+
public function posts($numberposts_or_args = 10, $post_type_or_class = 'any', $post_class = '') {
|
299 |
+
return $this->get_posts($numberposts_or_args, $post_type_or_class, $post_class);
|
300 |
+
}
|
301 |
+
|
302 |
+
/**
|
303 |
+
* @return string
|
304 |
+
*/
|
305 |
+
public function title() {
|
306 |
+
return $this->name;
|
307 |
+
}
|
308 |
+
|
309 |
+
/**
|
310 |
+
* @return string
|
311 |
+
*/
|
312 |
+
public function url() {
|
313 |
+
return $this->get_url();
|
314 |
+
}
|
315 |
+
|
316 |
+
/* Deprecated
|
317 |
+
===================== */
|
318 |
+
|
319 |
+
/**
|
320 |
+
* @deprecated
|
321 |
+
* @param int $i
|
322 |
+
* @return string
|
323 |
+
*/
|
324 |
+
function get_page($i) {
|
325 |
+
return $this->get_path() . '/page/' . $i;
|
326 |
+
}
|
327 |
+
|
328 |
+
}
|
functions/functions/timber-theme.php
ADDED
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TimberTheme extends TimberCore
|
4 |
+
{
|
5 |
+
|
6 |
+
public $link;
|
7 |
+
public $name;
|
8 |
+
public $path;
|
9 |
+
public $parent;
|
10 |
+
public $parent_slug;
|
11 |
+
public $slug;
|
12 |
+
public $uri;
|
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/functions/timber-twig.php
ADDED
@@ -0,0 +1,289 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TimberTwig {
|
4 |
+
|
5 |
+
public static $dir_name;
|
6 |
+
|
7 |
+
function __construct() {
|
8 |
+
add_action( 'twig_apply_filters', array( $this, 'add_timber_filters_deprecated' ) );
|
9 |
+
add_action( 'twig_apply_filters', array( $this, 'add_timber_filters' ) );
|
10 |
+
}
|
11 |
+
|
12 |
+
/**
|
13 |
+
* These are all deprecated and will be removed in 0.21.0
|
14 |
+
*
|
15 |
+
* @param Twig_Environment $twig
|
16 |
+
* @deprecated since 0.20.7
|
17 |
+
* @return Twig_Environment
|
18 |
+
*/
|
19 |
+
function add_timber_filters_deprecated( $twig ) {
|
20 |
+
$twig->addFilter( new Twig_SimpleFilter( 'get_src_from_attachment_id', 'twig_get_src_from_attachment_id' ) );
|
21 |
+
$twig->addFilter( new Twig_SimpleFilter( 'wp_body_class', array( $this, 'body_class' ) ) );
|
22 |
+
$twig->addFilter( new Twig_SimpleFilter( 'twitterify', array( 'TimberHelper', 'twitterify' ) ) );
|
23 |
+
$twig->addFilter( new Twig_SimpleFilter( 'twitterfy', array( 'TimberHelper', 'twitterify' ) ) );
|
24 |
+
return $twig;
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
*
|
29 |
+
*
|
30 |
+
* @param Twig_Environment $twig
|
31 |
+
* @return Twig_Environment
|
32 |
+
*/
|
33 |
+
function add_timber_filters( $twig ) {
|
34 |
+
/* image filters */
|
35 |
+
$twig->addFilter( new Twig_SimpleFilter( 'resize', array( 'TimberImageHelper', 'resize' ) ) );
|
36 |
+
$twig->addFilter( new Twig_SimpleFilter( 'retina', array( 'TimberImageHelper', 'retina_resize' ) ) );
|
37 |
+
$twig->addFilter( new Twig_SimpleFilter( 'letterbox', array( 'TimberImageHelper', 'letterbox' ) ) );
|
38 |
+
$twig->addFilter( new Twig_SimpleFilter( 'tojpg', array( 'TimberImageHelper', 'img_to_jpg' ) ) );
|
39 |
+
|
40 |
+
/* debugging filters */
|
41 |
+
$twig->addFilter( new Twig_SimpleFilter( 'docs', 'twig_object_docs' ) );
|
42 |
+
$twig->addFilter( new Twig_SimpleFilter( 'get_class', 'get_class' ) );
|
43 |
+
$twig->addFilter( new Twig_SimpleFilter( 'get_type', 'get_type' ) );
|
44 |
+
$twig->addFilter( new Twig_SimpleFilter( 'print_r', function( $arr ) {
|
45 |
+
return print_r( $arr, true );
|
46 |
+
} ) );
|
47 |
+
$twig->addFilter( new Twig_SimpleFilter( 'print_a', function( $arr ) {
|
48 |
+
return '<pre>' . self::object_docs( $arr, true ) . '</pre>';
|
49 |
+
} ) );
|
50 |
+
|
51 |
+
/* other filters */
|
52 |
+
$twig->addFilter( new Twig_SimpleFilter( 'stripshortcodes', 'strip_shortcodes' ) );
|
53 |
+
$twig->addFilter( new Twig_SimpleFilter( 'array', array( $this, 'to_array' ) ) );
|
54 |
+
$twig->addFilter( new Twig_SimpleFilter( 'string', array( $this, 'to_string' ) ) );
|
55 |
+
$twig->addFilter( new Twig_SimpleFilter( 'excerpt', 'wp_trim_words' ) );
|
56 |
+
$twig->addFilter( new Twig_SimpleFilter( 'function', array( $this, 'exec_function' ) ) );
|
57 |
+
$twig->addFilter( new Twig_SimpleFilter( 'pretags', array( $this, 'twig_pretags' ) ) );
|
58 |
+
$twig->addFilter( new Twig_SimpleFilter( 'sanitize', 'sanitize_title' ) );
|
59 |
+
$twig->addFilter( new Twig_SimpleFilter( 'shortcodes', 'do_shortcode' ) );
|
60 |
+
$twig->addFilter( new Twig_SimpleFilter( 'time_ago', array( $this, 'time_ago' ) ) );
|
61 |
+
$twig->addFilter( new Twig_SimpleFilter( 'wpautop', 'wpautop' ) );
|
62 |
+
|
63 |
+
$twig->addFilter( new Twig_SimpleFilter( 'relative', function ( $link ) {
|
64 |
+
return TimberURLHelper::get_rel_url( $link, true );
|
65 |
+
} ) );
|
66 |
+
|
67 |
+
$twig->addFilter( new Twig_SimpleFilter( 'date', array( $this, 'intl_date' ) ) );
|
68 |
+
|
69 |
+
$twig->addFilter( new Twig_SimpleFilter( 'truncate', function ( $text, $len ) {
|
70 |
+
return TimberHelper::trim_words( $text, $len );
|
71 |
+
} ) );
|
72 |
+
|
73 |
+
/* actions and filters */
|
74 |
+
$twig->addFunction( new Twig_SimpleFunction( 'action', function ( $context ) {
|
75 |
+
$args = func_get_args();
|
76 |
+
array_shift( $args );
|
77 |
+
$args[] = $context;
|
78 |
+
call_user_func_array( 'do_action', $args );
|
79 |
+
}, array( 'needs_context' => true ) ) );
|
80 |
+
|
81 |
+
$twig->addFilter( new Twig_SimpleFilter( 'apply_filters', function () {
|
82 |
+
$args = func_get_args();
|
83 |
+
$tag = current( array_splice( $args, 1, 1 ) );
|
84 |
+
|
85 |
+
return apply_filters_ref_array( $tag, $args );
|
86 |
+
} ) );
|
87 |
+
$twig->addFunction( new Twig_SimpleFunction( 'function', array( &$this, 'exec_function' ) ) );
|
88 |
+
$twig->addFunction( new Twig_SimpleFunction( 'fn', array( &$this, 'exec_function' ) ) );
|
89 |
+
|
90 |
+
/* TimberObjects */
|
91 |
+
$twig->addFunction( new Twig_SimpleFunction( 'TimberPost', function ( $pid, $PostClass = 'TimberPost' ) {
|
92 |
+
if ( is_array( $pid ) && !TimberHelper::is_array_assoc( $pid ) ) {
|
93 |
+
foreach ( $pid as &$p ) {
|
94 |
+
$p = new $PostClass( $p );
|
95 |
+
}
|
96 |
+
return $pid;
|
97 |
+
}
|
98 |
+
return new $PostClass( $pid );
|
99 |
+
} ) );
|
100 |
+
$twig->addFunction( new Twig_SimpleFunction( 'TimberImage', function ( $pid, $ImageClass = 'TimberImage' ) {
|
101 |
+
if ( is_array( $pid ) && !TimberHelper::is_array_assoc( $pid ) ) {
|
102 |
+
foreach ( $pid as &$p ) {
|
103 |
+
$p = new $ImageClass( $p );
|
104 |
+
}
|
105 |
+
return $pid;
|
106 |
+
}
|
107 |
+
return new $ImageClass( $pid );
|
108 |
+
} ) );
|
109 |
+
$twig->addFunction( new Twig_SimpleFunction( 'TimberTerm', function ( $pid, $TermClass = 'TimberTerm' ) {
|
110 |
+
if ( is_array( $pid ) && !TimberHelper::is_array_assoc( $pid ) ) {
|
111 |
+
foreach ( $pid as &$p ) {
|
112 |
+
$p = new $TermClass( $p );
|
113 |
+
}
|
114 |
+
return $pid;
|
115 |
+
}
|
116 |
+
return new $TermClass( $pid );
|
117 |
+
} ) );
|
118 |
+
$twig->addFunction( new Twig_SimpleFunction( 'TimberUser', function ( $pid, $UserClass = 'TimberUser' ) {
|
119 |
+
if ( is_array( $pid ) && !TimberHelper::is_array_assoc( $pid ) ) {
|
120 |
+
foreach ( $pid as &$p ) {
|
121 |
+
$p = new $UserClass( $p );
|
122 |
+
}
|
123 |
+
return $pid;
|
124 |
+
}
|
125 |
+
return new $UserClass( $pid );
|
126 |
+
} ) );
|
127 |
+
|
128 |
+
/* bloginfo and translate */
|
129 |
+
$twig->addFunction( 'bloginfo', new Twig_SimpleFunction( 'bloginfo', function ( $show = '', $filter = 'raw' ) {
|
130 |
+
return get_bloginfo( $show, $filter );
|
131 |
+
} ) );
|
132 |
+
$twig->addFunction( '__', new Twig_SimpleFunction( '__', function ( $text, $domain = 'default' ) {
|
133 |
+
return __( $text, $domain );
|
134 |
+
} ) );
|
135 |
+
|
136 |
+
$twig = apply_filters( 'get_twig', $twig );
|
137 |
+
|
138 |
+
return $twig;
|
139 |
+
}
|
140 |
+
|
141 |
+
/**
|
142 |
+
*
|
143 |
+
*
|
144 |
+
* @param mixed $arr
|
145 |
+
* @return array
|
146 |
+
*/
|
147 |
+
function to_array( $arr ) {
|
148 |
+
if ( is_array( $arr ) ) {
|
149 |
+
return $arr;
|
150 |
+
}
|
151 |
+
$arr = array( $arr );
|
152 |
+
return $arr;
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
*
|
157 |
+
*
|
158 |
+
* @param mixed $arr
|
159 |
+
* @param string $glue
|
160 |
+
* @return string
|
161 |
+
*/
|
162 |
+
function to_string( $arr, $glue = ' ' ) {
|
163 |
+
if ( is_string( $arr ) ) {
|
164 |
+
return $arr;
|
165 |
+
}
|
166 |
+
if ( is_array( $arr ) && count( $arr ) == 1 ) {
|
167 |
+
return $arr[0];
|
168 |
+
}
|
169 |
+
if ( is_array( $arr ) ) {
|
170 |
+
return implode( $glue, $arr );
|
171 |
+
}
|
172 |
+
return null;
|
173 |
+
}
|
174 |
+
|
175 |
+
/**
|
176 |
+
*
|
177 |
+
*
|
178 |
+
* @param string $function_name
|
179 |
+
* @return mixed
|
180 |
+
*/
|
181 |
+
function exec_function( $function_name ) {
|
182 |
+
$args = func_get_args();
|
183 |
+
array_shift( $args );
|
184 |
+
return call_user_func_array( trim( $function_name ), ( $args ) );
|
185 |
+
}
|
186 |
+
|
187 |
+
/**
|
188 |
+
*
|
189 |
+
*
|
190 |
+
* @param string $content
|
191 |
+
* @return string
|
192 |
+
*/
|
193 |
+
function twig_pretags( $content ) {
|
194 |
+
return preg_replace_callback( '|<pre.*>(.*)</pre|isU', array( &$this, 'convert_pre_entities' ), $content );
|
195 |
+
}
|
196 |
+
|
197 |
+
/**
|
198 |
+
*
|
199 |
+
*
|
200 |
+
* @param array $matches
|
201 |
+
* @return string
|
202 |
+
*/
|
203 |
+
function convert_pre_entities( $matches ) {
|
204 |
+
return str_replace( $matches[1], htmlentities( $matches[1] ), $matches[0] );
|
205 |
+
}
|
206 |
+
|
207 |
+
/**
|
208 |
+
*
|
209 |
+
*
|
210 |
+
* @param mixed $body_classes
|
211 |
+
* @return string
|
212 |
+
*/
|
213 |
+
function body_class( $body_classes ) {
|
214 |
+
ob_start();
|
215 |
+
if ( is_array( $body_classes ) ) {
|
216 |
+
$body_classes = explode( ' ', $body_classes );
|
217 |
+
}
|
218 |
+
body_class( $body_classes );
|
219 |
+
$return = ob_get_contents();
|
220 |
+
ob_end_clean();
|
221 |
+
return $return;
|
222 |
+
}
|
223 |
+
|
224 |
+
/**
|
225 |
+
*
|
226 |
+
*
|
227 |
+
* @param string $date
|
228 |
+
* @param string $format (optional)
|
229 |
+
* @return string
|
230 |
+
*/
|
231 |
+
function intl_date( $date, $format = null ) {
|
232 |
+
if ( $format === null ) {
|
233 |
+
$format = get_option( 'date_format' );
|
234 |
+
}
|
235 |
+
|
236 |
+
if ( $date instanceof DateTime ) {
|
237 |
+
$timestamp = $date->getTimestamp();
|
238 |
+
} else {
|
239 |
+
$timestamp = strtotime( $date );
|
240 |
+
}
|
241 |
+
|
242 |
+
return date_i18n( $format, $timestamp );
|
243 |
+
}
|
244 |
+
|
245 |
+
//debug
|
246 |
+
|
247 |
+
/**
|
248 |
+
*
|
249 |
+
*
|
250 |
+
* @param mixed $obj
|
251 |
+
* @param bool $methods
|
252 |
+
* @return string
|
253 |
+
*/
|
254 |
+
function object_docs( $obj, $methods = true ) {
|
255 |
+
$class = get_class( $obj );
|
256 |
+
$properties = (array)$obj;
|
257 |
+
if ( $methods ) {
|
258 |
+
/** @var array $methods */
|
259 |
+
$methods = $obj->get_method_values();
|
260 |
+
}
|
261 |
+
$rets = array_merge( $properties, $methods );
|
262 |
+
ksort( $rets );
|
263 |
+
$str = print_r( $rets, true );
|
264 |
+
$str = str_replace( 'Array', $class . ' Object', $str );
|
265 |
+
return $str;
|
266 |
+
}
|
267 |
+
|
268 |
+
/**
|
269 |
+
* @param int|string $from
|
270 |
+
* @param int|string $to
|
271 |
+
* @param string $format_past
|
272 |
+
* @param string $format_future
|
273 |
+
* @return string
|
274 |
+
*/
|
275 |
+
function time_ago( $from, $to = null, $format_past = '%s ago', $format_future = '%s from now' ) {
|
276 |
+
$to = $to === null ? time() : $to;
|
277 |
+
$to = is_int( $to ) ? $to : strtotime( $to );
|
278 |
+
$from = is_int( $from ) ? $from : strtotime( $from );
|
279 |
+
|
280 |
+
if ( $from < $to ) {
|
281 |
+
return sprintf( $format_past, human_time_diff( $from, $to ) );
|
282 |
+
} else {
|
283 |
+
return sprintf( $format_future, human_time_diff( $to, $from ) );
|
284 |
+
}
|
285 |
+
}
|
286 |
+
|
287 |
+
}
|
288 |
+
|
289 |
+
new TimberTwig();
|
functions/functions/timber-url-helper.php
ADDED
@@ -0,0 +1,246 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
+
$url_info = parse_url($url);
|
58 |
+
if (isset($url_info['host']) && $url_info['host'] != $_SERVER['HTTP_HOST'] && !$force) {
|
59 |
+
return $url;
|
60 |
+
}
|
61 |
+
$link = '';
|
62 |
+
if (isset($url_info['path'])){
|
63 |
+
$link = $url_info['path'];
|
64 |
+
}
|
65 |
+
if (isset($url_info['query']) && strlen($url_info['query'])) {
|
66 |
+
$link .= '?' . $url_info['query'];
|
67 |
+
}
|
68 |
+
if (isset($url_info['fragment']) && strlen($url_info['fragment'])) {
|
69 |
+
$link .= '#' . $url_info['fragment'];
|
70 |
+
}
|
71 |
+
$link = TimberURLHelper::remove_double_slashes($link);
|
72 |
+
return $link;
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* @param string $url
|
77 |
+
* @return bool
|
78 |
+
*/
|
79 |
+
public static function is_local($url) {
|
80 |
+
if (strstr($url, $_SERVER['HTTP_HOST'])) {
|
81 |
+
return true;
|
82 |
+
}
|
83 |
+
return false;
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* @param string $src
|
88 |
+
* @return string
|
89 |
+
*/
|
90 |
+
public static function get_full_path($src) {
|
91 |
+
$root = ABSPATH;
|
92 |
+
$old_root_path = $root . $src;
|
93 |
+
$old_root_path = str_replace('//', '/', $old_root_path);
|
94 |
+
return $old_root_path;
|
95 |
+
}
|
96 |
+
|
97 |
+
/**
|
98 |
+
* Takes a url and figures out its place based in the file system based on path
|
99 |
+
* NOTE: Not fool-proof, makes a lot of assumptions about the file path
|
100 |
+
* matching the URL path
|
101 |
+
* @param string $url
|
102 |
+
* @return string
|
103 |
+
*/
|
104 |
+
public static function url_to_file_system($url) {
|
105 |
+
$url_parts = parse_url($url);
|
106 |
+
$path = ABSPATH . $url_parts['path'];
|
107 |
+
$path = str_replace('//', '/', $path);
|
108 |
+
return $path;
|
109 |
+
}
|
110 |
+
|
111 |
+
public static function file_system_to_url( $fs ) {
|
112 |
+
$relative_path = self::get_rel_path($fs);
|
113 |
+
$home = home_url('/'.$relative_path);
|
114 |
+
return $home;
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
* @param string $src
|
119 |
+
* @return string
|
120 |
+
*/
|
121 |
+
public static function get_rel_path($src) {
|
122 |
+
if (strstr($src, ABSPATH)) {
|
123 |
+
return str_replace(ABSPATH, '', $src);
|
124 |
+
}
|
125 |
+
//its outside the wordpress directory, alternate setups:
|
126 |
+
$src = str_replace(WP_CONTENT_DIR, '', $src);
|
127 |
+
return WP_CONTENT_SUBDIR . $src;
|
128 |
+
}
|
129 |
+
|
130 |
+
/**
|
131 |
+
* @param string $url
|
132 |
+
* @return string
|
133 |
+
*/
|
134 |
+
public static function remove_double_slashes($url) {
|
135 |
+
$url = str_replace('//', '/', $url);
|
136 |
+
if (strstr($url, 'http:') && !strstr($url, 'http://')) {
|
137 |
+
$url = str_replace('http:/', 'http://', $url);
|
138 |
+
}
|
139 |
+
return $url;
|
140 |
+
}
|
141 |
+
|
142 |
+
/**
|
143 |
+
* @param string $url
|
144 |
+
* @param string $path
|
145 |
+
* @return string
|
146 |
+
*/
|
147 |
+
public static function prepend_to_url($url, $path) {
|
148 |
+
if (strstr(strtolower($url), 'http')) {
|
149 |
+
$url_parts = parse_url($url);
|
150 |
+
$url = $url_parts['scheme'] . '://' . $url_parts['host'] . $path . $url_parts['path'];
|
151 |
+
} else {
|
152 |
+
$url = $url . $path;
|
153 |
+
}
|
154 |
+
return self::remove_double_slashes($url);
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
* @param string $path
|
159 |
+
* @return string
|
160 |
+
*/
|
161 |
+
public static function preslashit($path) {
|
162 |
+
if (strpos($path, '/') != 0) {
|
163 |
+
$path = '/' . $path;
|
164 |
+
}
|
165 |
+
return $path;
|
166 |
+
}
|
167 |
+
|
168 |
+
/**
|
169 |
+
* @param string $url
|
170 |
+
* @return bool
|
171 |
+
*/
|
172 |
+
public static function is_external($url) {
|
173 |
+
$has_http = strstr(strtolower($url), 'http');
|
174 |
+
$on_domain = strstr($url, $_SERVER['HTTP_HOST']);
|
175 |
+
if ($has_http && !$on_domain) {
|
176 |
+
return true;
|
177 |
+
}
|
178 |
+
return false;
|
179 |
+
}
|
180 |
+
|
181 |
+
/**
|
182 |
+
* Pass links through untrailingslashit unless they are a single /
|
183 |
+
*
|
184 |
+
* @param string $link
|
185 |
+
* @return string
|
186 |
+
*/
|
187 |
+
public static function remove_trailing_slash($link) {
|
188 |
+
if ( $link != "/")
|
189 |
+
$link = untrailingslashit( $link );
|
190 |
+
return $link;
|
191 |
+
}
|
192 |
+
|
193 |
+
/**
|
194 |
+
* @param string $url
|
195 |
+
* @param int $timeout
|
196 |
+
* @return string|WP_Error
|
197 |
+
* @deprecated since 0.20.0
|
198 |
+
*/
|
199 |
+
static function download_url($url, $timeout = 300) {
|
200 |
+
if (!$url) {
|
201 |
+
return new WP_Error('http_no_url', __('Invalid URL Provided.'));
|
202 |
+
}
|
203 |
+
|
204 |
+
$tmpfname = wp_tempnam($url);
|
205 |
+
if (!$tmpfname) {
|
206 |
+
return new WP_Error('http_no_file', __('Could not create Temporary file.'));
|
207 |
+
}
|
208 |
+
|
209 |
+
$response = wp_remote_get($url, array('timeout' => $timeout, 'stream' => true, 'filename' => $tmpfname));
|
210 |
+
|
211 |
+
if (is_wp_error($response)) {
|
212 |
+
unlink($tmpfname);
|
213 |
+
return $response;
|
214 |
+
}
|
215 |
+
if (200 != wp_remote_retrieve_response_code($response)) {
|
216 |
+
unlink($tmpfname);
|
217 |
+
return new WP_Error('http_404', trim(wp_remote_retrieve_response_message($response)));
|
218 |
+
}
|
219 |
+
return $tmpfname;
|
220 |
+
}
|
221 |
+
|
222 |
+
/**
|
223 |
+
* @param int $i
|
224 |
+
* @return array
|
225 |
+
*/
|
226 |
+
public static function get_params($i = false) {
|
227 |
+
$args = explode('/', trim(strtolower($_SERVER['REQUEST_URI'])));
|
228 |
+
$newargs = array();
|
229 |
+
foreach ($args as $arg) {
|
230 |
+
if (strlen($arg)) {
|
231 |
+
$newargs[] = $arg;
|
232 |
+
}
|
233 |
+
}
|
234 |
+
if ($i === false){
|
235 |
+
return $newargs;
|
236 |
+
}
|
237 |
+
if ($i < 0){
|
238 |
+
//count from end
|
239 |
+
$i = count($newargs) + $i;
|
240 |
+
}
|
241 |
+
if (isset($newargs[$i])) {
|
242 |
+
return $newargs[$i];
|
243 |
+
}
|
244 |
+
}
|
245 |
+
|
246 |
+
}
|
functions/functions/timber-user.php
ADDED
@@ -0,0 +1,193 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TimberUser extends TimberCore implements TimberCoreInterface {
|
4 |
+
|
5 |
+
public $object_type = 'user';
|
6 |
+
public static $representation = 'user';
|
7 |
+
|
8 |
+
public $_link;
|
9 |
+
|
10 |
+
public $display_name;
|
11 |
+
public $id;
|
12 |
+
public $name;
|
13 |
+
public $user_nicename;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @param int|bool $uid
|
17 |
+
*/
|
18 |
+
function __construct($uid = false) {
|
19 |
+
$this->init($uid);
|
20 |
+
}
|
21 |
+
|
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 '';
|
34 |
+
}
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @param string $field_name
|
38 |
+
* @return null
|
39 |
+
*/
|
40 |
+
function get_meta($field_name) {
|
41 |
+
return $this->get_meta_field( $field_name );
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* @param string $field
|
46 |
+
* @param mixed $value
|
47 |
+
*/
|
48 |
+
function __set($field, $value) {
|
49 |
+
if ($field == 'name') {
|
50 |
+
$this->display_name = $value;
|
51 |
+
}
|
52 |
+
$this->$field = $value;
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* @return string
|
57 |
+
*/
|
58 |
+
public function get_link() {
|
59 |
+
if (!$this->_link) {
|
60 |
+
$this->_link = get_author_posts_url($this->ID);
|
61 |
+
}
|
62 |
+
return $this->_link;
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* @param int|bool $uid
|
67 |
+
*/
|
68 |
+
function init($uid = false) {
|
69 |
+
if ($uid === false) {
|
70 |
+
$uid = get_current_user_id();
|
71 |
+
}
|
72 |
+
if (is_object($uid) || is_array($uid)){
|
73 |
+
$data = $uid;
|
74 |
+
if (is_array($uid)){
|
75 |
+
$data = (object) $uid;
|
76 |
+
}
|
77 |
+
$uid = $data->ID;
|
78 |
+
}
|
79 |
+
if (is_numeric($uid)) {
|
80 |
+
$data = get_userdata($uid);
|
81 |
+
}
|
82 |
+
if (isset($data) && is_object($data)) {
|
83 |
+
if (isset($data->data)){
|
84 |
+
$this->import($data->data);
|
85 |
+
} else {
|
86 |
+
$this->import($data);
|
87 |
+
}
|
88 |
+
}
|
89 |
+
$this->id = $this->ID;
|
90 |
+
$this->name = $this->name();
|
91 |
+
$this->import_custom();
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* @param string $field_name
|
96 |
+
* @return mixed
|
97 |
+
*/
|
98 |
+
function get_meta_field($field_name) {
|
99 |
+
$value = null;
|
100 |
+
$value = apply_filters('timber_user_get_meta_field_pre', $value, $this->ID, $field_name, $this);
|
101 |
+
if ($value === null) {
|
102 |
+
$value = get_user_meta($this->ID, $field_name, true);
|
103 |
+
}
|
104 |
+
$value = apply_filters('timber_user_get_meta_field', $value, $this->ID, $field_name, $this);
|
105 |
+
return $value;
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* @return array|null
|
110 |
+
*/
|
111 |
+
function get_custom() {
|
112 |
+
if ($this->ID) {
|
113 |
+
$um = array();
|
114 |
+
$um = apply_filters('timber_user_get_meta_pre', $um, $this->ID, $this);
|
115 |
+
if (empty($um)) {
|
116 |
+
$um = get_user_meta($this->ID);
|
117 |
+
}
|
118 |
+
$custom = array();
|
119 |
+
foreach ($um as $key => $value) {
|
120 |
+
if (is_array($value) && count($value) == 1) {
|
121 |
+
$value = $value[0];
|
122 |
+
}
|
123 |
+
$custom[$key] = maybe_unserialize($value);
|
124 |
+
}
|
125 |
+
$custom = apply_filters('timber_user_get_meta', $custom, $this->ID, $this);
|
126 |
+
return $custom;
|
127 |
+
}
|
128 |
+
return null;
|
129 |
+
}
|
130 |
+
|
131 |
+
function import_custom() {
|
132 |
+
$custom = $this->get_custom();
|
133 |
+
$this->import($custom);
|
134 |
+
}
|
135 |
+
|
136 |
+
/**
|
137 |
+
* @return string
|
138 |
+
*/
|
139 |
+
function name() {
|
140 |
+
return $this->display_name;
|
141 |
+
}
|
142 |
+
|
143 |
+
/**
|
144 |
+
* @return string
|
145 |
+
*/
|
146 |
+
function get_permalink() {
|
147 |
+
return $this->get_link();
|
148 |
+
}
|
149 |
+
|
150 |
+
/**
|
151 |
+
* @return string
|
152 |
+
*/
|
153 |
+
function permalink() {
|
154 |
+
return $this->get_link();
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
* @return string
|
159 |
+
*/
|
160 |
+
function get_path() {
|
161 |
+
return $this->get_link();
|
162 |
+
}
|
163 |
+
|
164 |
+
/**
|
165 |
+
* @param string $field_name
|
166 |
+
* @return mixed
|
167 |
+
*/
|
168 |
+
function meta($field_name) {
|
169 |
+
return $this->get_meta_field($field_name);
|
170 |
+
}
|
171 |
+
|
172 |
+
/**
|
173 |
+
* @return string
|
174 |
+
*/
|
175 |
+
function path() {
|
176 |
+
return $this->get_path();
|
177 |
+
}
|
178 |
+
|
179 |
+
/**
|
180 |
+
* @return string
|
181 |
+
*/
|
182 |
+
function slug() {
|
183 |
+
return $this->user_nicename;
|
184 |
+
}
|
185 |
+
|
186 |
+
/**
|
187 |
+
* @return string
|
188 |
+
*/
|
189 |
+
function link() {
|
190 |
+
return $this->get_link();
|
191 |
+
}
|
192 |
+
|
193 |
+
}
|
functions/timber-helper.php
CHANGED
@@ -13,11 +13,8 @@ class TimberHelper {
|
|
13 |
* @return mixed
|
14 |
*/
|
15 |
public static function transient( $slug, $callback, $transient_time = 0, $lock_timeout = 5, $force = false ) {
|
16 |
-
$enable_transients = true;
|
17 |
-
if ( $transient_time === false || ( defined( 'WP_DISABLE_TRANSIENTS' ) && WP_DISABLE_TRANSIENTS ) ) {
|
18 |
-
$enable_transients = false;
|
19 |
-
}
|
20 |
|
|
|
21 |
$data = $enable_transients ? get_transient( $slug ) : false;
|
22 |
|
23 |
if ( false === $data ) {
|
@@ -47,8 +44,11 @@ class TimberHelper {
|
|
47 |
set_transient( $slug, $data, $transient_time );
|
48 |
self::_unlock_transient( $slug );
|
49 |
}
|
|
|
50 |
}
|
|
|
51 |
return $data;
|
|
|
52 |
}
|
53 |
|
54 |
/**
|
13 |
* @return mixed
|
14 |
*/
|
15 |
public static function transient( $slug, $callback, $transient_time = 0, $lock_timeout = 5, $force = false ) {
|
|
|
|
|
|
|
|
|
16 |
|
17 |
+
$enable_transients = ( $transient_time === false || ( defined( 'WP_DISABLE_TRANSIENTS' ) && WP_DISABLE_TRANSIENTS ) ) ? false : true;
|
18 |
$data = $enable_transients ? get_transient( $slug ) : false;
|
19 |
|
20 |
if ( false === $data ) {
|
44 |
set_transient( $slug, $data, $transient_time );
|
45 |
self::_unlock_transient( $slug );
|
46 |
}
|
47 |
+
|
48 |
}
|
49 |
+
|
50 |
return $data;
|
51 |
+
|
52 |
}
|
53 |
|
54 |
/**
|
functions/timber-image-helper.php
CHANGED
@@ -1,17 +1,18 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
|
4 |
-
|
|
|
5 |
|
6 |
static function add_actions() {
|
7 |
-
add_action('delete_post', function ($post_id) {
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
}
|
16 |
|
17 |
/**
|
@@ -19,497 +20,589 @@ class TimberImageHelper
|
|
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 |
-
|
31 |
-
|
32 |
-
|
33 |
}
|
34 |
|
35 |
/**
|
36 |
-
*
|
|
|
|
|
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 |
/**
|
61 |
-
*
|
|
|
|
|
62 |
*/
|
63 |
-
static function delete_resized_files($local_file) {
|
64 |
-
$info = pathinfo($local_file);
|
65 |
$dir = $info['dirname'];
|
66 |
$ext = $info['extension'];
|
67 |
$filename = $info['filename'];
|
68 |
$searcher = '/' . $filename . '-[0-9999999]*';
|
69 |
-
foreach (glob($dir . $searcher) as $found_file) {
|
70 |
-
$regexdir = str_replace('/', '\/', $dir);
|
71 |
-
$pattern = '/' . ($regexdir) . '\/' . $filename . '-[0-9]*x[0-9]*-c-[a-z]*.' . $ext . '/';
|
72 |
-
$match = preg_match($pattern, $found_file);
|
73 |
//keeping these here so I know what the hell we're matching
|
74 |
//$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);
|
75 |
//$match = preg_match("/\/srv\/www\/wordpress-develop\/src\/wp-content\/uploads\/2014\/05\/arch-[0-9]*x[0-9]*-c-[a-z]*.jpg/", $filename);
|
76 |
-
if ($match) {
|
77 |
-
unlink($found_file);
|
78 |
}
|
79 |
}
|
80 |
}
|
81 |
|
82 |
/**
|
83 |
-
*
|
|
|
|
|
84 |
*/
|
85 |
-
static function delete_letterboxed_files($local_file) {
|
86 |
-
$info = pathinfo($local_file);
|
87 |
$dir = $info['dirname'];
|
88 |
$ext = $info['extension'];
|
89 |
$filename = $info['filename'];
|
90 |
$searcher = '/' . $filename . '-lbox-[0-9999999]*';
|
91 |
-
foreach (glob($dir . $searcher) as $found_file) {
|
92 |
-
$regexdir = str_replace('/', '\/', $dir);
|
93 |
-
$pattern = '/' . ($regexdir) . '\/' . $filename . '-lbox-[0-9]*x[0-9]*-[a-zA-Z0-9]*.' . $ext . '/';
|
94 |
-
$match = preg_match($pattern, $found_file);
|
95 |
-
if ($match) {
|
96 |
-
unlink($found_file);
|
97 |
}
|
98 |
}
|
99 |
}
|
100 |
|
101 |
/**
|
102 |
-
*
|
103 |
-
*
|
104 |
-
* @param
|
105 |
-
* @param
|
|
|
|
|
106 |
* @return string
|
107 |
*/
|
108 |
-
public static function get_letterbox_file_rel($src, $w, $h, $color) {
|
109 |
-
if (!strlen($src)) {
|
110 |
return null;
|
111 |
}
|
112 |
-
$new_path = self::get_letterbox_file_name_relative_to_content($src, $w, $h, $color);
|
113 |
return WP_CONTENT_SUBDIR . $new_path;
|
114 |
}
|
115 |
|
116 |
/**
|
117 |
-
*
|
|
|
|
|
118 |
* @return mixed|null
|
119 |
*/
|
120 |
-
static function get_directory_relative_to_content($src) {
|
121 |
-
if (!strlen($src)) {
|
122 |
return null;
|
123 |
}
|
124 |
-
if (!strlen($src)) {
|
125 |
return null;
|
126 |
}
|
127 |
$abs = false;
|
128 |
-
if (strstr($src, 'http')) {
|
129 |
$abs = true;
|
130 |
}
|
131 |
-
$path_parts = pathinfo($src);
|
132 |
-
if ($abs) {
|
133 |
-
$dir_relative_to_content = str_replace(WP_CONTENT_URL, '', $path_parts['dirname']);
|
134 |
} else {
|
135 |
-
$dir_relative_to_content = str_replace(WP_CONTENT_DIR, '', $path_parts['dirname']);
|
136 |
-
$dir_relative_to_content = str_replace(WP_CONTENT_SUBDIR, '', $dir_relative_to_content);
|
137 |
}
|
138 |
return $dir_relative_to_content;
|
139 |
}
|
140 |
|
141 |
/**
|
142 |
-
*
|
143 |
-
*
|
144 |
-
* @param
|
145 |
-
* @param
|
|
|
|
|
146 |
* @return string
|
147 |
*/
|
148 |
-
static function get_letterbox_file_name_relative_to_content($src, $w, $h, $color) {
|
149 |
-
$path_parts = pathinfo($src);
|
150 |
-
$dir_relative_to_content = self::get_directory_relative_to_content($src);
|
151 |
-
$color = str_replace('#', '', $color);
|
152 |
$newbase = $path_parts['filename'] . '-lbox-' . $w . 'x' . $h . '-' . $color;
|
153 |
$new_name = $newbase . '.' . $path_parts['extension'];
|
154 |
return $dir_relative_to_content . '/' . $new_name;
|
155 |
}
|
156 |
|
157 |
/**
|
158 |
-
*
|
159 |
-
*
|
160 |
-
* @param
|
161 |
-
* @param
|
|
|
|
|
162 |
* @return string
|
163 |
*/
|
164 |
-
public static function get_letterbox_file_path($src, $w, $h, $color) {
|
165 |
-
$new_name = self::get_letterbox_file_name_relative_to_content($src, $w, $h, $color);
|
166 |
$new_server_path = WP_CONTENT_DIR . $new_name;
|
167 |
-
$new_server_path = TimberURLHelper::remove_double_slashes($new_server_path);
|
168 |
return $new_server_path;
|
169 |
}
|
170 |
|
171 |
/**
|
172 |
-
*
|
173 |
-
*
|
174 |
-
* @param
|
175 |
-
* @param
|
|
|
|
|
176 |
* @return string
|
177 |
*/
|
178 |
-
static function get_resize_file_rel($src, $w, $h, $crop) {
|
179 |
-
if (!strlen($src)) {
|
180 |
return null;
|
181 |
}
|
182 |
-
$new_path = self::get_resize_file_name_relative_to_content($src, $w, $h, $crop);
|
183 |
return WP_CONTENT_SUBDIR . $new_path;
|
184 |
}
|
185 |
|
186 |
/**
|
187 |
-
*
|
188 |
-
*
|
189 |
-
* @param
|
190 |
-
* @param
|
|
|
|
|
191 |
* @return string
|
192 |
*/
|
193 |
-
static function get_resize_file_name_relative_to_content($src, $w, $h, $crop) {
|
194 |
-
$path_parts = pathinfo($src);
|
195 |
-
$dir_relative_to_content = self::get_directory_relative_to_content($src);
|
196 |
-
$newbase = $path_parts['filename'] . '-' . $w . 'x' . $h . '-c-' . ($crop ? $crop : 'f'); // Crop will be either user named or f (false)
|
197 |
$new_name = $newbase . '.' . $path_parts['extension'];
|
198 |
return $dir_relative_to_content . '/' . $new_name;
|
199 |
}
|
200 |
|
201 |
/**
|
202 |
-
*
|
|
|
|
|
203 |
*/
|
204 |
-
public static function in_uploads($src) {
|
205 |
$upload_dir = wp_upload_dir();
|
206 |
-
if (strstr($src, $upload_dir['relative'])) {
|
207 |
return true;
|
208 |
}
|
209 |
return false;
|
210 |
}
|
211 |
|
212 |
/**
|
213 |
-
*
|
214 |
-
*
|
215 |
-
* @param
|
216 |
-
* @param
|
|
|
|
|
217 |
* @return string
|
218 |
*/
|
219 |
-
static function get_resize_file_path($src, $w, $h, $crop) {
|
220 |
-
$new_name = self::get_resize_file_name_relative_to_content($src, $w, $h, $crop);
|
221 |
$new_server_path = WP_CONTENT_DIR . $new_name;
|
222 |
-
$new_server_path = TimberURLHelper::remove_double_slashes($new_server_path);
|
223 |
return $new_server_path;
|
224 |
}
|
225 |
|
226 |
/**
|
227 |
-
*
|
|
|
|
|
228 |
* @return string
|
229 |
*/
|
230 |
-
public static function get_image_path($iid) {
|
231 |
$size = 'full';
|
232 |
-
$src = wp_get_attachment_image_src($iid, $size);
|
233 |
$src = $src[0];
|
234 |
-
return self::get_rel_path($src);
|
235 |
}
|
236 |
|
237 |
/**
|
238 |
-
*
|
|
|
|
|
239 |
*/
|
240 |
-
public static function get_server_location($url) {
|
|
|
|
|
|
|
241 |
$upload_dir = wp_upload_dir();
|
242 |
$abs = false;
|
243 |
-
if (strstr($url, 'http')) {
|
244 |
$abs = true;
|
245 |
}
|
246 |
-
if (self::in_uploads($url)) {
|
247 |
-
if ($abs) {
|
248 |
-
$relative_to_uploads_dir = str_replace($upload_dir['baseurl'], '', $url);
|
249 |
} else {
|
250 |
-
$relative_to_uploads_dir = str_replace($upload_dir['relative'], '', $url);
|
251 |
}
|
252 |
return $upload_dir['basedir'] . $relative_to_uploads_dir;
|
253 |
} else {
|
254 |
-
if ($abs) {
|
255 |
-
$relative_to_wp_content = str_replace(WP_CONTENT_URL, '', $url);
|
256 |
} else {
|
257 |
-
$relative_to_wp_content = str_replace(WP_CONTENT_SUBDIR, '', $url);
|
258 |
}
|
259 |
return WP_CONTENT_DIR . $relative_to_wp_content;
|
260 |
}
|
261 |
}
|
262 |
|
263 |
/**
|
264 |
-
*
|
265 |
-
*
|
266 |
-
* @param
|
267 |
-
* @param
|
268 |
-
* @param
|
|
|
|
|
269 |
* @return mixed|null|string
|
270 |
*/
|
271 |
-
public static function letterbox($src, $w, $h, $color = '#000000', $force = false) {
|
272 |
-
if (strstr($src, 'http') && !strstr($src, home_url())) {
|
273 |
-
$src = self::sideload_image($src);
|
274 |
}
|
275 |
$abs = false;
|
276 |
-
if (strstr($src, 'http')) {
|
277 |
$abs = true;
|
278 |
}
|
279 |
-
$new_file_rel = self::get_letterbox_file_rel($src, $w, $h, $color);
|
280 |
-
$new_server_path = self::get_letterbox_file_path($src, $w, $h, $color);
|
281 |
-
$old_server_path = self::get_server_location($src);
|
282 |
-
$old_server_path = TimberURLHelper::remove_double_slashes($old_server_path);
|
283 |
-
$new_server_path = TimberURLHelper::remove_double_slashes($new_server_path);
|
284 |
-
if (file_exists($new_server_path) && !$force) {
|
285 |
-
if ($abs) {
|
286 |
-
return untrailingslashit(home_url()) . $new_file_rel;
|
287 |
} else {
|
288 |
-
return TimberURLHelper::preslashit($new_file_rel);
|
289 |
}
|
290 |
}
|
291 |
-
$bg = imagecreatetruecolor($w, $h);
|
292 |
-
$c = self::hexrgb($color);
|
293 |
-
$white = imagecolorallocate($bg, $c['red'], $c['green'], $c['blue']);
|
294 |
-
imagefill($bg, 0, 0, $white);
|
295 |
-
$image = wp_get_image_editor($old_server_path);
|
296 |
-
if (!is_wp_error($image)) {
|
297 |
$current_size = $image->get_size();
|
298 |
$ow = $current_size['width'];
|
299 |
$oh = $current_size['height'];
|
300 |
$new_aspect = $w / $h;
|
301 |
$old_aspect = $ow / $oh;
|
302 |
-
if ($new_aspect > $old_aspect) {
|
303 |
//taller than goal
|
304 |
$h_scale = $h / $oh;
|
305 |
$owt = $ow * $h_scale;
|
306 |
$y = 0;
|
307 |
$x = $w / 2 - $owt / 2;
|
308 |
$oht = $h;
|
309 |
-
$image->crop(0, 0, $ow, $oh, $owt, $oht);
|
310 |
} else {
|
311 |
$w_scale = $w / $ow;
|
312 |
$oht = $oh * $w_scale;
|
313 |
$x = 0;
|
314 |
$y = $h / 2 - $oht / 2;
|
315 |
$owt = $w;
|
316 |
-
$image->crop(0, 0, $ow, $oh, $owt, $oht);
|
317 |
}
|
318 |
-
$image->save($new_server_path);
|
319 |
$func = 'imagecreatefromjpeg';
|
320 |
-
$ext = pathinfo($new_server_path, PATHINFO_EXTENSION);
|
321 |
-
if ($ext == 'gif') {
|
322 |
$func = 'imagecreatefromgif';
|
323 |
-
} else if ($ext == 'png') {
|
324 |
-
|
325 |
-
|
326 |
-
$image = $func($new_server_path);
|
327 |
-
imagecopy($bg, $image, $x, $y, 0, 0, $owt, $oht);
|
328 |
-
imagejpeg($bg, $new_server_path);
|
329 |
-
$new_relative_path = TimberURLHelper::get_rel_path($new_server_path);
|
330 |
-
if ($abs) {
|
331 |
-
return home_url($new_relative_path);
|
332 |
}
|
333 |
return $new_relative_path;
|
334 |
} else {
|
335 |
-
TimberHelper::error_log($image);
|
336 |
}
|
337 |
return null;
|
338 |
}
|
339 |
|
340 |
/**
|
341 |
-
*
|
342 |
-
*
|
|
|
|
|
343 |
* @return string
|
344 |
*/
|
345 |
-
public static function img_to_jpg($src, $bghex = '#FFFFFF') {
|
346 |
-
$path = str_replace(home_url(), '', $src);
|
347 |
-
$output = str_replace('.png', '.jpg', $path);
|
348 |
-
$input_file = self::get_server_location($path);
|
349 |
-
$output_file = self::get_server_location($output);
|
350 |
-
if (file_exists($output_file)) {
|
351 |
return $output;
|
352 |
}
|
353 |
$filename = $output;
|
354 |
-
$input = imagecreatefrompng($input_file);
|
355 |
-
list($width, $height) = getimagesize($input_file);
|
356 |
-
$output = imagecreatetruecolor($width, $height);
|
357 |
-
$c = self::hexrgb($bghex);
|
358 |
-
$white = imagecolorallocate($output, $c['red'], $c['green'], $c['blue']);
|
359 |
-
imagefilledrectangle($output, 0, 0, $width, $height, $white);
|
360 |
-
imagecopy($output, $input, 0, 0, 0, 0, $width, $height);
|
361 |
-
imagejpeg($output, $output_file);
|
362 |
return $filename;
|
363 |
}
|
364 |
|
365 |
/**
|
366 |
-
*
|
|
|
|
|
367 |
* @return string
|
368 |
*/
|
369 |
-
public static function get_sideloaded_file_loc($file) {
|
370 |
$upload = wp_upload_dir();
|
371 |
$dir = $upload['path'];
|
372 |
$filename = $file;
|
373 |
-
$file = parse_url($file);
|
374 |
-
$path_parts = pathinfo($file['path']);
|
375 |
-
$basename = md5($filename);
|
376 |
$ext = 'jpg';
|
377 |
-
if (isset($path_parts['extension'])) {
|
378 |
$ext = $path_parts['extension'];
|
379 |
}
|
380 |
return $dir . '/' . $basename . '.' . $ext;
|
381 |
}
|
382 |
|
383 |
/**
|
384 |
-
*
|
|
|
|
|
385 |
* @return string
|
386 |
*/
|
387 |
-
public static function sideload_image($file) {
|
388 |
-
$loc = self::get_sideloaded_file_loc($file);
|
389 |
-
if (file_exists($loc)) {
|
390 |
-
return TimberURLHelper::preslashit(TimberURLHelper::get_rel_path($loc));
|
391 |
}
|
392 |
// Download file to temp location
|
393 |
-
if (!function_exists('download_url')) {
|
394 |
-
require_once
|
395 |
}
|
396 |
-
$tmp = download_url($file);
|
397 |
-
preg_match('/[^\?]+\.(jpe?g|jpe|gif|png)\b/i', $file, $matches);
|
398 |
$file_array = array();
|
399 |
-
$file_array['name'] = basename($matches[0]);
|
400 |
$file_array['tmp_name'] = $tmp;
|
401 |
// If error storing temporarily, unlink
|
402 |
-
if (is_wp_error($tmp)) {
|
403 |
-
@unlink($file_array['tmp_name']);
|
404 |
$file_array['tmp_name'] = '';
|
405 |
}
|
406 |
// do the validation and storage stuff
|
407 |
-
$locinfo = pathinfo($loc);
|
408 |
-
$file = wp_upload_bits($locinfo['basename'], null, file_get_contents($file_array['tmp_name']));
|
409 |
return $file['url'];
|
410 |
}
|
411 |
|
412 |
/**
|
413 |
-
*
|
414 |
-
*
|
415 |
-
* @param
|
416 |
-
* @param
|
417 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
418 |
* @return string
|
419 |
*/
|
420 |
-
public static function resize($src, $w, $h = 0, $crop = 'default', $force_resize = false) {
|
421 |
-
if (empty($src)) {
|
422 |
return '';
|
423 |
}
|
424 |
-
if (strstr($src, 'http') && !strstr($src, home_url())) {
|
425 |
-
$src = self::sideload_image($src);
|
426 |
}
|
427 |
$abs = false;
|
428 |
-
if (strstr($src, 'http')) {
|
429 |
$abs = true;
|
430 |
}
|
431 |
// Sanitize crop position
|
432 |
-
$allowed_crop_positions = array('default', 'center', 'top', 'bottom', 'left', 'right');
|
433 |
-
if ($crop !== false && !in_array($crop, $allowed_crop_positions)) {
|
434 |
$crop = $allowed_crop_positions[0];
|
435 |
}
|
436 |
//oh good, it's a relative image in the uploads folder!
|
437 |
-
$new_path = self::get_resize_file_rel($src, $w, $h, $crop);
|
438 |
-
$new_server_path = self::get_resize_file_path($src, $w, $h, $crop);
|
439 |
-
$old_server_path = self::get_server_location($src);
|
440 |
-
$old_server_path = TimberURLHelper::remove_double_slashes($old_server_path);
|
441 |
-
$new_server_path = TimberURLHelper::remove_double_slashes($new_server_path);
|
442 |
-
if (file_exists($new_server_path)) {
|
443 |
-
if ($force_resize) {
|
444 |
// Force resize - warning: will regenerate the image on every pageload, use for testing purposes only!
|
445 |
-
unlink($new_server_path);
|
446 |
} else {
|
447 |
-
if (!$abs) {
|
448 |
-
return TimberURLHelper::preslashit($new_path);
|
449 |
}
|
450 |
-
return untrailingslashit(home_url()) . $new_path;
|
451 |
}
|
452 |
}
|
453 |
-
$image = wp_get_image_editor($old_server_path);
|
454 |
|
455 |
-
if (!is_wp_error($image)) {
|
456 |
$current_size = $image->get_size();
|
457 |
|
458 |
$src_w = $current_size['width'];
|
459 |
$src_h = $current_size['height'];
|
460 |
|
461 |
$src_ratio = $src_w / $src_h;
|
462 |
-
if (!$h) {
|
463 |
-
$h = round($w / $src_ratio);
|
|
|
|
|
|
|
|
|
464 |
}
|
465 |
// Get ratios
|
466 |
$dest_ratio = $w / $h;
|
467 |
$src_wt = $src_h * $dest_ratio;
|
468 |
$src_ht = $src_w / $dest_ratio;
|
469 |
|
470 |
-
if (!$crop) {
|
471 |
// Always crop, to allow resizing upwards
|
472 |
-
$image->crop(0, 0, $src_w, $src_h, $w, $h);
|
473 |
} else {
|
474 |
//start with defaults:
|
475 |
$src_x = $src_w / 2 - $src_wt / 2;
|
476 |
-
$src_y = ($src_h - $src_ht) / 6;
|
477 |
//now specific overrides based on options:
|
478 |
-
if ($crop == 'center') {
|
479 |
// Get source x and y
|
480 |
-
$src_x = round(($src_w - $src_wt) / 2);
|
481 |
-
$src_y = round(($src_h - $src_ht) / 2);
|
482 |
-
} else if ($crop == 'top') {
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
|
492 |
// Crop the image
|
493 |
-
if ($dest_ratio > $src_ratio) {
|
494 |
-
$image->crop(0, $src_y, $src_w, $src_ht, $w, $h);
|
495 |
} else {
|
496 |
-
$image->crop($src_x, 0, $src_wt, $src_h, $w, $h);
|
497 |
}
|
498 |
|
499 |
}
|
500 |
-
$result = $image->save($new_server_path);
|
501 |
-
if (is_wp_error($result)) {
|
502 |
-
error_log('Error resizing image');
|
503 |
-
error_log(print_r($result, true));
|
504 |
}
|
505 |
-
if ($abs) {
|
506 |
-
return untrailingslashit(home_url()) . $new_path;
|
507 |
}
|
508 |
return $new_path;
|
509 |
-
} else if (isset($image->error_data['error_loading_image'])) {
|
510 |
-
|
511 |
-
|
512 |
-
TimberHelper::error_log($image);
|
513 |
}
|
514 |
return $src;
|
515 |
}
|
1 |
<?php
|
2 |
|
3 |
+
require_once 'timber-image-retina-helper.php';
|
4 |
+
|
5 |
+
class TimberImageHelper {
|
6 |
|
7 |
static function add_actions() {
|
8 |
+
add_action( 'delete_post', function ( $post_id ) {
|
9 |
+
$post = get_post( $post_id );
|
10 |
+
$image_types = array( 'image/jpeg', 'image/png', 'image/gif', 'image/jpg' );
|
11 |
+
if ( $post->post_type == 'attachment' && in_array( $post->post_mime_type, $image_types ) ) {
|
12 |
+
TimberImageHelper::delete_resized_files_from_url( $post->guid );
|
13 |
+
TimberImageHelper::delete_letterboxed_files_from_url( $post->guid );
|
14 |
+
}
|
15 |
+
} );
|
16 |
}
|
17 |
|
18 |
/**
|
20 |
* for example /wp-content or /content
|
21 |
*/
|
22 |
static function add_constants() {
|
23 |
+
if ( !defined( 'WP_CONTENT_SUBDIR' ) ) {
|
24 |
+
$wp_content_path = str_replace( home_url(), '', WP_CONTENT_URL );
|
25 |
+
define( 'WP_CONTENT_SUBDIR', $wp_content_path );
|
26 |
}
|
27 |
}
|
28 |
|
29 |
static function add_filters() {
|
30 |
+
add_filter( 'upload_dir', function ( $arr ) {
|
31 |
+
$arr['relative'] = str_replace( home_url(), '', $arr['baseurl'] );
|
32 |
+
return $arr;
|
33 |
+
} );
|
34 |
}
|
35 |
|
36 |
/**
|
37 |
+
*
|
38 |
+
*
|
39 |
+
* @param string $hexstr
|
40 |
* @return array
|
41 |
*/
|
42 |
+
public static function hexrgb( $hexstr ) {
|
43 |
+
if ( !strstr( $hexstr, '#' ) ) {
|
44 |
$hexstr = '#' . $hexstr;
|
45 |
}
|
46 |
+
if ( strlen( $hexstr ) == 4 ) {
|
47 |
$hexstr = '#' . $hexstr[1] . $hexstr[1] . $hexstr[2] . $hexstr[2] . $hexstr[3] . $hexstr[3];
|
48 |
}
|
49 |
+
$int = hexdec( $hexstr );
|
50 |
+
return array( "red" => 0xFF & ( $int >> 0x10 ), "green" => 0xFF & ( $int >> 0x8 ), "blue" => 0xFF & $int );
|
51 |
}
|
52 |
|
53 |
+
static function delete_resized_files_from_url( $src ) {
|
54 |
+
$local = TimberURLHelper::url_to_file_system( $src );
|
55 |
+
self::delete_resized_files( $local );
|
56 |
}
|
57 |
|
58 |
+
static function delete_letterboxed_files_from_url( $src ) {
|
59 |
+
$local = TimberURLHelper::url_to_file_system( $src );
|
60 |
+
self::delete_letterboxed_files( $local );
|
61 |
}
|
62 |
|
63 |
/**
|
64 |
+
*
|
65 |
+
*
|
66 |
+
* @param string $local_file
|
67 |
*/
|
68 |
+
static function delete_resized_files( $local_file ) {
|
69 |
+
$info = pathinfo( $local_file );
|
70 |
$dir = $info['dirname'];
|
71 |
$ext = $info['extension'];
|
72 |
$filename = $info['filename'];
|
73 |
$searcher = '/' . $filename . '-[0-9999999]*';
|
74 |
+
foreach ( glob( $dir . $searcher ) as $found_file ) {
|
75 |
+
$regexdir = str_replace( '/', '\/', $dir );
|
76 |
+
$pattern = '/' . ( $regexdir ) . '\/' . $filename . '-[0-9]*x[0-9]*-c-[a-z]*.' . $ext . '/';
|
77 |
+
$match = preg_match( $pattern, $found_file );
|
78 |
//keeping these here so I know what the hell we're matching
|
79 |
//$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);
|
80 |
//$match = preg_match("/\/srv\/www\/wordpress-develop\/src\/wp-content\/uploads\/2014\/05\/arch-[0-9]*x[0-9]*-c-[a-z]*.jpg/", $filename);
|
81 |
+
if ( $match ) {
|
82 |
+
unlink( $found_file );
|
83 |
}
|
84 |
}
|
85 |
}
|
86 |
|
87 |
/**
|
88 |
+
*
|
89 |
+
*
|
90 |
+
* @param string $local_file
|
91 |
*/
|
92 |
+
static function delete_letterboxed_files( $local_file ) {
|
93 |
+
$info = pathinfo( $local_file );
|
94 |
$dir = $info['dirname'];
|
95 |
$ext = $info['extension'];
|
96 |
$filename = $info['filename'];
|
97 |
$searcher = '/' . $filename . '-lbox-[0-9999999]*';
|
98 |
+
foreach ( glob( $dir . $searcher ) as $found_file ) {
|
99 |
+
$regexdir = str_replace( '/', '\/', $dir );
|
100 |
+
$pattern = '/' . ( $regexdir ) . '\/' . $filename . '-lbox-[0-9]*x[0-9]*-[a-zA-Z0-9]*.' . $ext . '/';
|
101 |
+
$match = preg_match( $pattern, $found_file );
|
102 |
+
if ( $match ) {
|
103 |
+
unlink( $found_file );
|
104 |
}
|
105 |
}
|
106 |
}
|
107 |
|
108 |
/**
|
109 |
+
*
|
110 |
+
*
|
111 |
+
* @param string $src
|
112 |
+
* @param int $w
|
113 |
+
* @param int $h
|
114 |
+
* @param string $color
|
115 |
* @return string
|
116 |
*/
|
117 |
+
public static function get_letterbox_file_rel( $src, $w, $h, $color ) {
|
118 |
+
if ( !strlen( $src ) ) {
|
119 |
return null;
|
120 |
}
|
121 |
+
$new_path = self::get_letterbox_file_name_relative_to_content( $src, $w, $h, $color );
|
122 |
return WP_CONTENT_SUBDIR . $new_path;
|
123 |
}
|
124 |
|
125 |
/**
|
126 |
+
*
|
127 |
+
*
|
128 |
+
* @param string $src The src of an image can be absolute, relative or server location
|
129 |
* @return mixed|null
|
130 |
*/
|
131 |
+
static function get_directory_relative_to_content( $src ) {
|
132 |
+
if ( !strlen( $src ) ) {
|
133 |
return null;
|
134 |
}
|
135 |
+
if ( !strlen( $src ) ) {
|
136 |
return null;
|
137 |
}
|
138 |
$abs = false;
|
139 |
+
if ( strstr( $src, 'http' ) ) {
|
140 |
$abs = true;
|
141 |
}
|
142 |
+
$path_parts = pathinfo( $src );
|
143 |
+
if ( $abs ) {
|
144 |
+
$dir_relative_to_content = str_replace( WP_CONTENT_URL, '', $path_parts['dirname'] );
|
145 |
} else {
|
146 |
+
$dir_relative_to_content = str_replace( WP_CONTENT_DIR, '', $path_parts['dirname'] );
|
147 |
+
$dir_relative_to_content = str_replace( WP_CONTENT_SUBDIR, '', $dir_relative_to_content );
|
148 |
}
|
149 |
return $dir_relative_to_content;
|
150 |
}
|
151 |
|
152 |
/**
|
153 |
+
*
|
154 |
+
*
|
155 |
+
* @param string $src
|
156 |
+
* @param int $w
|
157 |
+
* @param int $h
|
158 |
+
* @param string $color
|
159 |
* @return string
|
160 |
*/
|
161 |
+
static function get_letterbox_file_name_relative_to_content( $src, $w, $h, $color ) {
|
162 |
+
$path_parts = pathinfo( $src );
|
163 |
+
$dir_relative_to_content = self::get_directory_relative_to_content( $src );
|
164 |
+
$color = str_replace( '#', '', $color );
|
165 |
$newbase = $path_parts['filename'] . '-lbox-' . $w . 'x' . $h . '-' . $color;
|
166 |
$new_name = $newbase . '.' . $path_parts['extension'];
|
167 |
return $dir_relative_to_content . '/' . $new_name;
|
168 |
}
|
169 |
|
170 |
/**
|
171 |
+
*
|
172 |
+
*
|
173 |
+
* @param string $src
|
174 |
+
* @param int $w
|
175 |
+
* @param int $h
|
176 |
+
* @param string $color
|
177 |
* @return string
|
178 |
*/
|
179 |
+
public static function get_letterbox_file_path( $src, $w, $h, $color ) {
|
180 |
+
$new_name = self::get_letterbox_file_name_relative_to_content( $src, $w, $h, $color );
|
181 |
$new_server_path = WP_CONTENT_DIR . $new_name;
|
182 |
+
$new_server_path = TimberURLHelper::remove_double_slashes( $new_server_path );
|
183 |
return $new_server_path;
|
184 |
}
|
185 |
|
186 |
/**
|
187 |
+
*
|
188 |
+
*
|
189 |
+
* @param string $src
|
190 |
+
* @param int $w
|
191 |
+
* @param int $h
|
192 |
+
* @param string $crop
|
193 |
* @return string
|
194 |
*/
|
195 |
+
static function get_resize_file_rel( $src, $w, $h, $crop ) {
|
196 |
+
if ( !strlen( $src ) ) {
|
197 |
return null;
|
198 |
}
|
199 |
+
$new_path = self::get_resize_file_name_relative_to_content( $src, $w, $h, $crop );
|
200 |
return WP_CONTENT_SUBDIR . $new_path;
|
201 |
}
|
202 |
|
203 |
/**
|
204 |
+
*
|
205 |
+
*
|
206 |
+
* @param string $src
|
207 |
+
* @param int $w
|
208 |
+
* @param int $h
|
209 |
+
* @param string $crop
|
210 |
* @return string
|
211 |
*/
|
212 |
+
static function get_resize_file_name_relative_to_content( $src, $w, $h, $crop ) {
|
213 |
+
$path_parts = pathinfo( $src );
|
214 |
+
$dir_relative_to_content = self::get_directory_relative_to_content( $src );
|
215 |
+
$newbase = $path_parts['filename'] . '-' . $w . 'x' . $h . '-c-' . ( $crop ? $crop : 'f' ); // Crop will be either user named or f (false)
|
216 |
$new_name = $newbase . '.' . $path_parts['extension'];
|
217 |
return $dir_relative_to_content . '/' . $new_name;
|
218 |
}
|
219 |
|
220 |
/**
|
221 |
+
*
|
222 |
+
*
|
223 |
+
* @param string $src
|
224 |
*/
|
225 |
+
public static function in_uploads( $src ) {
|
226 |
$upload_dir = wp_upload_dir();
|
227 |
+
if ( strstr( $src, $upload_dir['relative'] ) ) {
|
228 |
return true;
|
229 |
}
|
230 |
return false;
|
231 |
}
|
232 |
|
233 |
/**
|
234 |
+
*
|
235 |
+
*
|
236 |
+
* @param string $src
|
237 |
+
* @param int $w
|
238 |
+
* @param int $h
|
239 |
+
* @param string $crop
|
240 |
* @return string
|
241 |
*/
|
242 |
+
static function get_resize_file_path( $src, $w, $h, $crop ) {
|
243 |
+
$new_name = self::get_resize_file_name_relative_to_content( $src, $w, $h, $crop );
|
244 |
$new_server_path = WP_CONTENT_DIR . $new_name;
|
245 |
+
$new_server_path = TimberURLHelper::remove_double_slashes( $new_server_path );
|
246 |
return $new_server_path;
|
247 |
}
|
248 |
|
249 |
/**
|
250 |
+
*
|
251 |
+
*
|
252 |
+
* @param int $iid
|
253 |
* @return string
|
254 |
*/
|
255 |
+
public static function get_image_path( $iid ) {
|
256 |
$size = 'full';
|
257 |
+
$src = wp_get_attachment_image_src( $iid, $size );
|
258 |
$src = $src[0];
|
259 |
+
return self::get_rel_path( $src );
|
260 |
}
|
261 |
|
262 |
/**
|
263 |
+
*
|
264 |
+
*
|
265 |
+
* @param string $url
|
266 |
*/
|
267 |
+
public static function get_server_location( $url ) {
|
268 |
+
if ( strpos( $url, ABSPATH ) === 0 ) {
|
269 |
+
return $url;
|
270 |
+
}
|
271 |
$upload_dir = wp_upload_dir();
|
272 |
$abs = false;
|
273 |
+
if ( strstr( $url, 'http' ) ) {
|
274 |
$abs = true;
|
275 |
}
|
276 |
+
if ( self::in_uploads( $url ) ) {
|
277 |
+
if ( $abs ) {
|
278 |
+
$relative_to_uploads_dir = str_replace( $upload_dir['baseurl'], '', $url );
|
279 |
} else {
|
280 |
+
$relative_to_uploads_dir = str_replace( $upload_dir['relative'], '', $url );
|
281 |
}
|
282 |
return $upload_dir['basedir'] . $relative_to_uploads_dir;
|
283 |
} else {
|
284 |
+
if ( $abs ) {
|
285 |
+
$relative_to_wp_content = str_replace( WP_CONTENT_URL, '', $url );
|
286 |
} else {
|
287 |
+
$relative_to_wp_content = str_replace( WP_CONTENT_SUBDIR, '', $url );
|
288 |
}
|
289 |
return WP_CONTENT_DIR . $relative_to_wp_content;
|
290 |
}
|
291 |
}
|
292 |
|
293 |
/**
|
294 |
+
*
|
295 |
+
*
|
296 |
+
* @param string $src
|
297 |
+
* @param int $w
|
298 |
+
* @param int $h
|
299 |
+
* @param string $color
|
300 |
+
* @param bool $force
|
301 |
* @return mixed|null|string
|
302 |
*/
|
303 |
+
public static function letterbox( $src, $w, $h, $color = '#000000', $force = false ) {
|
304 |
+
if ( strstr( $src, 'http' ) && !strstr( $src, home_url() ) ) {
|
305 |
+
$src = self::sideload_image( $src );
|
306 |
}
|
307 |
$abs = false;
|
308 |
+
if ( strstr( $src, 'http' ) ) {
|
309 |
$abs = true;
|
310 |
}
|
311 |
+
$new_file_rel = self::get_letterbox_file_rel( $src, $w, $h, $color );
|
312 |
+
$new_server_path = self::get_letterbox_file_path( $src, $w, $h, $color );
|
313 |
+
$old_server_path = self::get_server_location( $src );
|
314 |
+
$old_server_path = TimberURLHelper::remove_double_slashes( $old_server_path );
|
315 |
+
$new_server_path = TimberURLHelper::remove_double_slashes( $new_server_path );
|
316 |
+
if ( file_exists( $new_server_path ) && !$force ) {
|
317 |
+
if ( $abs ) {
|
318 |
+
return untrailingslashit( home_url() ) . $new_file_rel;
|
319 |
} else {
|
320 |
+
return TimberURLHelper::preslashit( $new_file_rel );
|
321 |
}
|
322 |
}
|
323 |
+
$bg = imagecreatetruecolor( $w, $h );
|
324 |
+
$c = self::hexrgb( $color );
|
325 |
+
$white = imagecolorallocate( $bg, $c['red'], $c['green'], $c['blue'] );
|
326 |
+
imagefill( $bg, 0, 0, $white );
|
327 |
+
$image = wp_get_image_editor( $old_server_path );
|
328 |
+
if ( !is_wp_error( $image ) ) {
|
329 |
$current_size = $image->get_size();
|
330 |
$ow = $current_size['width'];
|
331 |
$oh = $current_size['height'];
|
332 |
$new_aspect = $w / $h;
|
333 |
$old_aspect = $ow / $oh;
|
334 |
+
if ( $new_aspect > $old_aspect ) {
|
335 |
//taller than goal
|
336 |
$h_scale = $h / $oh;
|
337 |
$owt = $ow * $h_scale;
|
338 |
$y = 0;
|
339 |
$x = $w / 2 - $owt / 2;
|
340 |
$oht = $h;
|
341 |
+
$image->crop( 0, 0, $ow, $oh, $owt, $oht );
|
342 |
} else {
|
343 |
$w_scale = $w / $ow;
|
344 |
$oht = $oh * $w_scale;
|
345 |
$x = 0;
|
346 |
$y = $h / 2 - $oht / 2;
|
347 |
$owt = $w;
|
348 |
+
$image->crop( 0, 0, $ow, $oh, $owt, $oht );
|
349 |
}
|
350 |
+
$image->save( $new_server_path );
|
351 |
$func = 'imagecreatefromjpeg';
|
352 |
+
$ext = pathinfo( $new_server_path, PATHINFO_EXTENSION );
|
353 |
+
if ( $ext == 'gif' ) {
|
354 |
$func = 'imagecreatefromgif';
|
355 |
+
} else if ( $ext == 'png' ) {
|
356 |
+
$func = 'imagecreatefrompng';
|
357 |
+
}
|
358 |
+
$image = $func( $new_server_path );
|
359 |
+
imagecopy( $bg, $image, $x, $y, 0, 0, $owt, $oht );
|
360 |
+
imagejpeg( $bg, $new_server_path );
|
361 |
+
$new_relative_path = TimberURLHelper::get_rel_path( $new_server_path );
|
362 |
+
if ( $abs ) {
|
363 |
+
return home_url( $new_relative_path );
|
364 |
}
|
365 |
return $new_relative_path;
|
366 |
} else {
|
367 |
+
TimberHelper::error_log( $image );
|
368 |
}
|
369 |
return null;
|
370 |
}
|
371 |
|
372 |
/**
|
373 |
+
*
|
374 |
+
*
|
375 |
+
* @param string $src a url or path to the image (http://example.org/wp-content/uploads/2014/image.jpg) or (/wp-content/uploads/2014/image.jpg)
|
376 |
+
* @param string $bghex
|
377 |
* @return string
|
378 |
*/
|
379 |
+
public static function img_to_jpg( $src, $bghex = '#FFFFFF' ) {
|
380 |
+
$path = str_replace( home_url(), '', $src );
|
381 |
+
$output = str_replace( '.png', '.jpg', $path );
|
382 |
+
$input_file = self::get_server_location( $path );
|
383 |
+
$output_file = self::get_server_location( $output );
|
384 |
+
if ( file_exists( $output_file ) ) {
|
385 |
return $output;
|
386 |
}
|
387 |
$filename = $output;
|
388 |
+
$input = imagecreatefrompng( $input_file );
|
389 |
+
list( $width, $height ) = getimagesize( $input_file );
|
390 |
+
$output = imagecreatetruecolor( $width, $height );
|
391 |
+
$c = self::hexrgb( $bghex );
|
392 |
+
$white = imagecolorallocate( $output, $c['red'], $c['green'], $c['blue'] );
|
393 |
+
imagefilledrectangle( $output, 0, 0, $width, $height, $white );
|
394 |
+
imagecopy( $output, $input, 0, 0, 0, 0, $width, $height );
|
395 |
+
imagejpeg( $output, $output_file );
|
396 |
return $filename;
|
397 |
}
|
398 |
|
399 |
/**
|
400 |
+
*
|
401 |
+
*
|
402 |
+
* @param string $file
|
403 |
* @return string
|
404 |
*/
|
405 |
+
public static function get_sideloaded_file_loc( $file ) {
|
406 |
$upload = wp_upload_dir();
|
407 |
$dir = $upload['path'];
|
408 |
$filename = $file;
|
409 |
+
$file = parse_url( $file );
|
410 |
+
$path_parts = pathinfo( $file['path'] );
|
411 |
+
$basename = md5( $filename );
|
412 |
$ext = 'jpg';
|
413 |
+
if ( isset( $path_parts['extension'] ) ) {
|
414 |
$ext = $path_parts['extension'];
|
415 |
}
|
416 |
return $dir . '/' . $basename . '.' . $ext;
|
417 |
}
|
418 |
|
419 |
/**
|
420 |
+
*
|
421 |
+
*
|
422 |
+
* @param string $file
|
423 |
* @return string
|
424 |
*/
|
425 |
+
public static function sideload_image( $file ) {
|
426 |
+
$loc = self::get_sideloaded_file_loc( $file );
|
427 |
+
if ( file_exists( $loc ) ) {
|
428 |
+
return TimberURLHelper::preslashit( TimberURLHelper::get_rel_path( $loc ) );
|
429 |
}
|
430 |
// Download file to temp location
|
431 |
+
if ( !function_exists( 'download_url' ) ) {
|
432 |
+
require_once ABSPATH . '/wp-admin/includes/file.php';
|
433 |
}
|
434 |
+
$tmp = download_url( $file );
|
435 |
+
preg_match( '/[^\?]+\.(jpe?g|jpe|gif|png)\b/i', $file, $matches );
|
436 |
$file_array = array();
|
437 |
+
$file_array['name'] = basename( $matches[0] );
|
438 |
$file_array['tmp_name'] = $tmp;
|
439 |
// If error storing temporarily, unlink
|
440 |
+
if ( is_wp_error( $tmp ) ) {
|
441 |
+
@unlink( $file_array['tmp_name'] );
|
442 |
$file_array['tmp_name'] = '';
|
443 |
}
|
444 |
// do the validation and storage stuff
|
445 |
+
$locinfo = pathinfo( $loc );
|
446 |
+
$file = wp_upload_bits( $locinfo['basename'], null, file_get_contents( $file_array['tmp_name'] ) );
|
447 |
return $file['url'];
|
448 |
}
|
449 |
|
450 |
/**
|
451 |
+
*
|
452 |
+
*
|
453 |
+
* @param string $src
|
454 |
+
* @param float $multiplier
|
455 |
+
*/
|
456 |
+
public static function retina_resize( $src, $factor = 2 ) {
|
457 |
+
if ( empty( $src ) ) {
|
458 |
+
return '';
|
459 |
+
}
|
460 |
+
$abs = false;
|
461 |
+
if ( strstr( $src, 'http' ) ) {
|
462 |
+
$abs = true;
|
463 |
+
}
|
464 |
+
if ( strstr( $src, 'http' ) && !strstr( $src, home_url() ) ) {
|
465 |
+
$src = self::sideload_image( $src );
|
466 |
+
}
|
467 |
+
$old_server_path = self::get_server_location( $src );
|
468 |
+
$new_path = TimberImageRetinaHelper::get_retina_file_rel( $src, $factor );
|
469 |
+
$new_server_path = TimberImageRetinaHelper::get_retina_file_path( $src, $factor );
|
470 |
+
|
471 |
+
$old_server_path = TimberURLHelper::remove_double_slashes( $old_server_path );
|
472 |
+
$new_server_path = TimberURLHelper::remove_double_slashes( $new_server_path );
|
473 |
+
if ( file_exists( $new_server_path ) ) {
|
474 |
+
if ( !$abs ) {
|
475 |
+
return TimberURLHelper::preslashit( $new_path );
|
476 |
+
}
|
477 |
+
return untrailingslashit( home_url() ) . $new_path;
|
478 |
+
}
|
479 |
+
$image = wp_get_image_editor( $old_server_path );
|
480 |
+
if ( !is_wp_error( $image ) ) {
|
481 |
+
$current_size = $image->get_size();
|
482 |
+
|
483 |
+
$src_w = $current_size['width'];
|
484 |
+
$src_h = $current_size['height'];
|
485 |
+
|
486 |
+
$src_ratio = $src_w / $src_h;
|
487 |
+
|
488 |
+
// Get ratios
|
489 |
+
$w = $src_w * $factor;
|
490 |
+
$h = $src_h * $factor;
|
491 |
+
$image->crop( 0, 0, $src_w, $src_h, $w, $h );
|
492 |
+
$result = $image->save( $new_server_path );
|
493 |
+
return $new_path;
|
494 |
+
}
|
495 |
+
return $src;
|
496 |
+
|
497 |
+
}
|
498 |
+
|
499 |
+
/**
|
500 |
+
*
|
501 |
+
*
|
502 |
+
* @param string $src
|
503 |
+
* @param int $w
|
504 |
+
* @param int $h
|
505 |
+
* @param string $crop
|
506 |
+
* @param bool $force_resize
|
507 |
* @return string
|
508 |
*/
|
509 |
+
public static function resize( $src, $w, $h = 0, $crop = 'default', $force_resize = false ) {
|
510 |
+
if ( empty( $src ) ) {
|
511 |
return '';
|
512 |
}
|
513 |
+
if ( strstr( $src, 'http' ) && !strstr( $src, home_url() ) ) {
|
514 |
+
$src = self::sideload_image( $src );
|
515 |
}
|
516 |
$abs = false;
|
517 |
+
if ( strstr( $src, 'http' ) ) {
|
518 |
$abs = true;
|
519 |
}
|
520 |
// Sanitize crop position
|
521 |
+
$allowed_crop_positions = array( 'default', 'center', 'top', 'bottom', 'left', 'right' );
|
522 |
+
if ( $crop !== false && !in_array( $crop, $allowed_crop_positions ) ) {
|
523 |
$crop = $allowed_crop_positions[0];
|
524 |
}
|
525 |
//oh good, it's a relative image in the uploads folder!
|
526 |
+
$new_path = self::get_resize_file_rel( $src, $w, $h, $crop );
|
527 |
+
$new_server_path = self::get_resize_file_path( $src, $w, $h, $crop );
|
528 |
+
$old_server_path = self::get_server_location( $src );
|
529 |
+
$old_server_path = TimberURLHelper::remove_double_slashes( $old_server_path );
|
530 |
+
$new_server_path = TimberURLHelper::remove_double_slashes( $new_server_path );
|
531 |
+
if ( file_exists( $new_server_path ) ) {
|
532 |
+
if ( $force_resize ) {
|
533 |
// Force resize - warning: will regenerate the image on every pageload, use for testing purposes only!
|
534 |
+
unlink( $new_server_path );
|
535 |
} else {
|
536 |
+
if ( !$abs ) {
|
537 |
+
return TimberURLHelper::preslashit( $new_path );
|
538 |
}
|
539 |
+
return untrailingslashit( home_url() ) . $new_path;
|
540 |
}
|
541 |
}
|
542 |
+
$image = wp_get_image_editor( $old_server_path );
|
543 |
|
544 |
+
if ( !is_wp_error( $image ) ) {
|
545 |
$current_size = $image->get_size();
|
546 |
|
547 |
$src_w = $current_size['width'];
|
548 |
$src_h = $current_size['height'];
|
549 |
|
550 |
$src_ratio = $src_w / $src_h;
|
551 |
+
if ( !$h ) {
|
552 |
+
$h = round( $w / $src_ratio );
|
553 |
+
}
|
554 |
+
if ( !$w ) {
|
555 |
+
//the user wants to resize based on constant height
|
556 |
+
$w = round( $h * $src_ratio );
|
557 |
}
|
558 |
// Get ratios
|
559 |
$dest_ratio = $w / $h;
|
560 |
$src_wt = $src_h * $dest_ratio;
|
561 |
$src_ht = $src_w / $dest_ratio;
|
562 |
|
563 |
+
if ( !$crop ) {
|
564 |
// Always crop, to allow resizing upwards
|
565 |
+
$image->crop( 0, 0, $src_w, $src_h, $w, $h );
|
566 |
} else {
|
567 |
//start with defaults:
|
568 |
$src_x = $src_w / 2 - $src_wt / 2;
|
569 |
+
$src_y = ( $src_h - $src_ht ) / 6;
|
570 |
//now specific overrides based on options:
|
571 |
+
if ( $crop == 'center' ) {
|
572 |
// Get source x and y
|
573 |
+
$src_x = round( ( $src_w - $src_wt ) / 2 );
|
574 |
+
$src_y = round( ( $src_h - $src_ht ) / 2 );
|
575 |
+
} else if ( $crop == 'top' ) {
|
576 |
+
$src_y = 0;
|
577 |
+
} else if ( $crop == 'bottom' ) {
|
578 |
+
$src_y = $src_h - $src_ht;
|
579 |
+
} else if ( $crop == 'left' ) {
|
580 |
+
$src_x = 0;
|
581 |
+
} else if ( $crop == 'right' ) {
|
582 |
+
$src_x = $src_w - $src_wt;
|
583 |
+
}
|
584 |
|
585 |
// Crop the image
|
586 |
+
if ( $dest_ratio > $src_ratio ) {
|
587 |
+
$image->crop( 0, $src_y, $src_w, $src_ht, $w, $h );
|
588 |
} else {
|
589 |
+
$image->crop( $src_x, 0, $src_wt, $src_h, $w, $h );
|
590 |
}
|
591 |
|
592 |
}
|
593 |
+
$result = $image->save( $new_server_path );
|
594 |
+
if ( is_wp_error( $result ) ) {
|
595 |
+
error_log( 'Error resizing image' );
|
596 |
+
error_log( print_r( $result, true ) );
|
597 |
}
|
598 |
+
if ( $abs ) {
|
599 |
+
return untrailingslashit( home_url() ) . $new_path;
|
600 |
}
|
601 |
return $new_path;
|
602 |
+
} else if ( isset( $image->error_data['error_loading_image'] ) ) {
|
603 |
+
TimberHelper::error_log( 'Error loading ' . $image->error_data['error_loading_image'] );
|
604 |
+
} else {
|
605 |
+
TimberHelper::error_log( $image );
|
606 |
}
|
607 |
return $src;
|
608 |
}
|
functions/timber-image-retina-helper.php
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TimberImageRetinaHelper {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* @param string $src
|
7 |
+
* @param int $w
|
8 |
+
* @param int $h
|
9 |
+
* @param string $crop
|
10 |
+
* @return string
|
11 |
+
*/
|
12 |
+
static function get_retina_file_path( $src, $mult = 2 ) {
|
13 |
+
$new_name = self::get_retina_file_name_relative_to_content( $src, $mult );
|
14 |
+
$new_server_path = WP_CONTENT_DIR . $new_name;
|
15 |
+
$new_server_path = TimberURLHelper::remove_double_slashes( $new_server_path );
|
16 |
+
return $new_server_path;
|
17 |
+
}
|
18 |
+
|
19 |
+
|
20 |
+
/**
|
21 |
+
*
|
22 |
+
*
|
23 |
+
* @param string $src
|
24 |
+
* @param int $w
|
25 |
+
* @param int $h
|
26 |
+
* @param string $crop
|
27 |
+
* @return string
|
28 |
+
*/
|
29 |
+
public static function get_retina_file_rel( $src, $factor = 2 ) {
|
30 |
+
if ( !strlen( $src ) ) {
|
31 |
+
return null;
|
32 |
+
}
|
33 |
+
$new_path = self::get_retina_file_name_relative_to_content( $src, $factor );
|
34 |
+
return WP_CONTENT_SUBDIR . $new_path;
|
35 |
+
}
|
36 |
+
|
37 |
+
/**
|
38 |
+
*
|
39 |
+
*
|
40 |
+
* @param string $src
|
41 |
+
* @param int $w
|
42 |
+
* @param int $h
|
43 |
+
* @param string $crop
|
44 |
+
* @return string
|
45 |
+
*/
|
46 |
+
private static function get_retina_file_name_relative_to_content( $src, $mult = 2 ) {
|
47 |
+
$path_parts = pathinfo( $src );
|
48 |
+
$dir_relative_to_content = TimberImageHelper::get_directory_relative_to_content( $src );
|
49 |
+
$newbase = $path_parts['filename'] . '@' . $mult . 'x'; // add @2x, @3x, @1.5x, etc.
|
50 |
+
$new_name = $newbase . '.' . $path_parts['extension'];
|
51 |
+
return $dir_relative_to_content . '/' . $new_name;
|
52 |
+
}
|
53 |
+
|
54 |
+
}
|
functions/timber-image.php
CHANGED
@@ -164,13 +164,18 @@ class TimberImage extends TimberPost implements TimberCoreInterface {
|
|
164 |
* @param int $iid
|
165 |
*/
|
166 |
function init( $iid = false ) {
|
167 |
-
if (!is_numeric($iid) && is_string($iid)) {
|
168 |
if (strstr($iid, '://')) {
|
169 |
$this->init_with_url($iid);
|
170 |
return;
|
171 |
}
|
|
|
|
|
|
|
|
|
172 |
if (strstr(strtolower($iid), '.jpg')) {
|
173 |
-
$this->
|
|
|
174 |
}
|
175 |
}
|
176 |
|
@@ -205,7 +210,7 @@ class TimberImage extends TimberPost implements TimberCoreInterface {
|
|
205 |
}
|
206 |
}
|
207 |
|
208 |
-
private function get_image_info($iid) {
|
209 |
$image_info = $iid;
|
210 |
if (is_numeric($iid)) {
|
211 |
$image_info = wp_get_attachment_metadata($iid);
|
@@ -231,14 +236,28 @@ class TimberImage extends TimberPost implements TimberCoreInterface {
|
|
231 |
return $iid;
|
232 |
}
|
233 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
234 |
/**
|
235 |
* @param string $url
|
236 |
*/
|
237 |
private function init_with_url($url) {
|
238 |
$this->abs_url = $url;
|
239 |
-
$this->file_loc = $url;
|
240 |
if (TimberURLHelper::is_local($url)) {
|
241 |
$this->file = ABSPATH . TimberURLHelper::get_rel_url($url);
|
|
|
242 |
}
|
243 |
}
|
244 |
|
164 |
* @param int $iid
|
165 |
*/
|
166 |
function init( $iid = false ) {
|
167 |
+
if ( !is_numeric( $iid ) && is_string( $iid ) ) {
|
168 |
if (strstr($iid, '://')) {
|
169 |
$this->init_with_url($iid);
|
170 |
return;
|
171 |
}
|
172 |
+
if ( strstr($iid, ABSPATH) ) {
|
173 |
+
$this->init_with_file_path($iid);
|
174 |
+
return;
|
175 |
+
}
|
176 |
if (strstr(strtolower($iid), '.jpg')) {
|
177 |
+
$this->init_with_relative_path($iid);
|
178 |
+
return;
|
179 |
}
|
180 |
}
|
181 |
|
210 |
}
|
211 |
}
|
212 |
|
213 |
+
private function get_image_info( $iid ) {
|
214 |
$image_info = $iid;
|
215 |
if (is_numeric($iid)) {
|
216 |
$image_info = wp_get_attachment_metadata($iid);
|
236 |
return $iid;
|
237 |
}
|
238 |
|
239 |
+
private function init_with_relative_path( $relative_path ) {
|
240 |
+
$this->abs_url = home_url( $relative_path );
|
241 |
+
$file_path = TimberURLHelper::get_full_path( $relative_path );
|
242 |
+
$this->file_loc = $file_path;
|
243 |
+
$this->file = $file_path;
|
244 |
+
}
|
245 |
+
|
246 |
+
private function init_with_file_path( $file_path ) {
|
247 |
+
$url = TimberURLHelper::file_system_to_url( $file_path );
|
248 |
+
$this->abs_url = $url;
|
249 |
+
$this->file_loc = $file_path;
|
250 |
+
$this->file = $file_path;
|
251 |
+
}
|
252 |
+
|
253 |
/**
|
254 |
* @param string $url
|
255 |
*/
|
256 |
private function init_with_url($url) {
|
257 |
$this->abs_url = $url;
|
|
|
258 |
if (TimberURLHelper::is_local($url)) {
|
259 |
$this->file = ABSPATH . TimberURLHelper::get_rel_url($url);
|
260 |
+
$this->file_loc = ABSPATH . TimberURLHelper::get_rel_url($url);
|
261 |
}
|
262 |
}
|
263 |
|
functions/timber-twig.php
CHANGED
@@ -1,236 +1,267 @@
|
|
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, '
|
|
|
10 |
}
|
11 |
|
12 |
/**
|
|
|
|
|
13 |
* @param Twig_Environment $twig
|
|
|
14 |
* @return Twig_Environment
|
15 |
*/
|
16 |
-
function
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
/* image filters */
|
18 |
-
$twig->addFilter('resize',
|
19 |
-
$twig->addFilter('
|
20 |
-
$twig->addFilter('
|
21 |
-
$twig->addFilter('
|
22 |
|
23 |
/* debugging filters */
|
24 |
-
$twig->addFilter('docs',
|
25 |
-
$twig->addFilter(
|
26 |
-
$twig->addFilter('get_type',
|
27 |
-
$twig->addFilter('print_r',
|
28 |
-
|
29 |
-
|
30 |
-
$twig->addFilter('print_a',
|
31 |
-
|
32 |
-
|
33 |
|
34 |
/* other filters */
|
35 |
-
$twig->addFilter('stripshortcodes',
|
36 |
-
$twig->addFilter('array',
|
37 |
-
$twig->addFilter('string',
|
38 |
-
$twig->addFilter('excerpt',
|
39 |
-
$twig->addFilter('function',
|
40 |
-
$twig->addFilter('
|
41 |
-
$twig->addFilter(
|
42 |
-
$twig->addFilter(
|
43 |
-
$twig->addFilter('
|
44 |
-
$twig->addFilter(
|
45 |
-
|
46 |
-
$twig->addFilter(
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
$twig->addFilter('
|
53 |
-
|
54 |
-
|
55 |
-
return TimberHelper::trim_words($text, $len);
|
56 |
-
}));
|
57 |
|
58 |
/* actions and filters */
|
59 |
-
$twig->addFunction(new Twig_SimpleFunction('action', function ($context) {
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
$twig->addFilter(new Twig_SimpleFilter('apply_filters', function () {
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
$twig->addFunction(new Twig_SimpleFunction('function', array(&$this, 'exec_function')));
|
73 |
-
$twig->addFunction(new Twig_SimpleFunction('fn', array(&$this, 'exec_function')));
|
74 |
|
75 |
/* TimberObjects */
|
76 |
-
$twig->addFunction(new Twig_SimpleFunction('TimberPost', function ($pid, $PostClass = 'TimberPost') {
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
$twig->addFunction(new Twig_SimpleFunction('TimberImage', function ($pid, $ImageClass = 'TimberImage') {
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
$twig->addFunction(new Twig_SimpleFunction('TimberTerm', function ($pid, $TermClass = 'TimberTerm') {
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
$twig->addFunction(new Twig_SimpleFunction('TimberUser', function ($pid, $UserClass = 'TimberUser') {
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
|
113 |
/* bloginfo and translate */
|
114 |
-
$twig->addFunction('bloginfo', new Twig_SimpleFunction('bloginfo', function ($show = '', $filter = 'raw') {
|
115 |
-
|
116 |
-
|
117 |
-
$twig->addFunction('__', new Twig_SimpleFunction('__', function ($text, $domain = 'default') {
|
118 |
-
|
119 |
-
|
120 |
|
121 |
-
$twig = apply_filters('get_twig', $twig);
|
122 |
|
123 |
return $twig;
|
124 |
}
|
125 |
|
126 |
/**
|
127 |
-
*
|
|
|
|
|
128 |
* @return array
|
129 |
*/
|
130 |
-
function to_array($arr) {
|
131 |
-
if (is_array($arr)) {
|
132 |
return $arr;
|
133 |
}
|
134 |
-
$arr = array($arr);
|
135 |
return $arr;
|
136 |
}
|
137 |
|
138 |
/**
|
139 |
-
*
|
140 |
-
*
|
|
|
|
|
141 |
* @return string
|
142 |
*/
|
143 |
-
function to_string($arr, $glue = ' ') {
|
144 |
-
if (is_string($arr)) {
|
145 |
return $arr;
|
146 |
}
|
147 |
-
if (is_array($arr) && count($arr) == 1) {
|
148 |
return $arr[0];
|
149 |
}
|
150 |
-
if (is_array($arr)) {
|
151 |
-
return implode($glue, $arr);
|
152 |
}
|
153 |
return null;
|
154 |
}
|
155 |
|
156 |
/**
|
157 |
-
*
|
|
|
|
|
158 |
* @return mixed
|
159 |
*/
|
160 |
-
function exec_function($function_name) {
|
161 |
$args = func_get_args();
|
162 |
-
array_shift($args);
|
163 |
-
return call_user_func_array(trim($function_name), ($args));
|
164 |
}
|
165 |
|
166 |
/**
|
167 |
-
*
|
|
|
|
|
168 |
* @return string
|
169 |
*/
|
170 |
-
function twig_pretags($content) {
|
171 |
-
return preg_replace_callback('|<pre.*>(.*)</pre|isU', array(&$this, 'convert_pre_entities'), $content);
|
172 |
}
|
173 |
|
174 |
/**
|
175 |
-
*
|
|
|
|
|
176 |
* @return string
|
177 |
*/
|
178 |
-
function convert_pre_entities($matches) {
|
179 |
-
return str_replace($matches[1], htmlentities($matches[1]), $matches[0]);
|
180 |
}
|
181 |
|
182 |
/**
|
183 |
-
*
|
|
|
|
|
184 |
* @return string
|
185 |
*/
|
186 |
-
function body_class($body_classes) {
|
187 |
ob_start();
|
188 |
-
if (is_array($body_classes)) {
|
189 |
-
$body_classes = explode(' ', $body_classes);
|
190 |
}
|
191 |
-
body_class($body_classes);
|
192 |
$return = ob_get_contents();
|
193 |
ob_end_clean();
|
194 |
return $return;
|
195 |
}
|
196 |
|
197 |
/**
|
198 |
-
*
|
199 |
-
*
|
|
|
|
|
200 |
* @return string
|
201 |
*/
|
202 |
-
function intl_date($date, $format = null) {
|
203 |
-
if ($format === null) {
|
204 |
-
$format = get_option('date_format');
|
205 |
}
|
206 |
|
207 |
-
if ($date instanceof DateTime) {
|
208 |
$timestamp = $date->getTimestamp();
|
209 |
} else {
|
210 |
-
$timestamp = strtotime($date);
|
211 |
}
|
212 |
|
213 |
-
return date_i18n($format, $timestamp);
|
214 |
}
|
215 |
|
216 |
//debug
|
217 |
|
218 |
/**
|
219 |
-
*
|
220 |
-
*
|
|
|
|
|
221 |
* @return string
|
222 |
*/
|
223 |
-
function object_docs($obj, $methods = true) {
|
224 |
-
$class = get_class($obj);
|
225 |
$properties = (array)$obj;
|
226 |
-
if ($methods) {
|
227 |
/** @var array $methods */
|
228 |
$methods = $obj->get_method_values();
|
229 |
}
|
230 |
-
$rets = array_merge($properties, $methods);
|
231 |
-
ksort($rets);
|
232 |
-
$str = print_r($rets, true);
|
233 |
-
$str = str_replace('Array', $class . ' Object', $str);
|
234 |
return $str;
|
235 |
}
|
236 |
|
@@ -241,32 +272,18 @@ class TimberTwig
|
|
241 |
* @param string $format_future
|
242 |
* @return string
|
243 |
*/
|
244 |
-
function time_ago($from, $to = null, $format_past = '%s ago', $format_future = '%s from now') {
|
245 |
$to = $to === null ? time() : $to;
|
246 |
-
$to = is_int($to) ? $to : strtotime($to);
|
247 |
-
$from = is_int($from) ? $from : strtotime($from);
|
248 |
|
249 |
-
if ($from < $to) {
|
250 |
-
return sprintf($format_past, human_time_diff($from, $to));
|
251 |
} else {
|
252 |
-
return sprintf($format_future, human_time_diff($to, $from));
|
253 |
}
|
254 |
}
|
255 |
|
256 |
}
|
257 |
|
258 |
new TimberTwig();
|
259 |
-
|
260 |
-
|
261 |
-
/* deprecated */
|
262 |
-
|
263 |
-
/**
|
264 |
-
* @param string $string
|
265 |
-
* @param array $data
|
266 |
-
* @return string
|
267 |
-
*/
|
268 |
-
function render_twig_string($string, $data = array()) {
|
269 |
-
return Timber::render_string($string, $data);
|
270 |
-
}
|
271 |
-
|
272 |
-
|
1 |
<?php
|
2 |
|
3 |
+
class TimberTwig {
|
|
|
4 |
|
5 |
public static $dir_name;
|
6 |
|
7 |
function __construct() {
|
8 |
+
add_action( 'twig_apply_filters', array( $this, 'add_timber_filters_deprecated' ) );
|
9 |
+
add_action( 'twig_apply_filters', array( $this, 'add_timber_filters' ) );
|
10 |
}
|
11 |
|
12 |
/**
|
13 |
+
* These are all deprecated and will be removed in 0.21.0
|
14 |
+
*
|
15 |
* @param Twig_Environment $twig
|
16 |
+
* @deprecated since 0.20.7
|
17 |
* @return Twig_Environment
|
18 |
*/
|
19 |
+
function add_timber_filters_deprecated( $twig ) {
|
20 |
+
$twig->addFilter( new Twig_SimpleFilter( 'get_src_from_attachment_id', 'twig_get_src_from_attachment_id' ) );
|
21 |
+
$twig->addFilter( new Twig_SimpleFilter( 'wp_body_class', array( $this, 'body_class' ) ) );
|
22 |
+
$twig->addFilter( new Twig_SimpleFilter( 'twitterify', array( 'TimberHelper', 'twitterify' ) ) );
|
23 |
+
$twig->addFilter( new Twig_SimpleFilter( 'twitterfy', array( 'TimberHelper', 'twitterify' ) ) );
|
24 |
+
return $twig;
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
*
|
29 |
+
*
|
30 |
+
* @param Twig_Environment $twig
|
31 |
+
* @return Twig_Environment
|
32 |
+
*/
|
33 |
+
function add_timber_filters( $twig ) {
|
34 |
/* image filters */
|
35 |
+
$twig->addFilter( new Twig_SimpleFilter( 'resize', array( 'TimberImageHelper', 'resize' ) ) );
|
36 |
+
$twig->addFilter( new Twig_SimpleFilter( 'retina', array( 'TimberImageHelper', 'retina_resize' ) ) );
|
37 |
+
$twig->addFilter( new Twig_SimpleFilter( 'letterbox', array( 'TimberImageHelper', 'letterbox' ) ) );
|
38 |
+
$twig->addFilter( new Twig_SimpleFilter( 'tojpg', array( 'TimberImageHelper', 'img_to_jpg' ) ) );
|
39 |
|
40 |
/* debugging filters */
|
41 |
+
$twig->addFilter( new Twig_SimpleFilter( 'docs', 'twig_object_docs' ) );
|
42 |
+
$twig->addFilter( new Twig_SimpleFilter( 'get_class', 'get_class' ) );
|
43 |
+
$twig->addFilter( new Twig_SimpleFilter( 'get_type', 'get_type' ) );
|
44 |
+
$twig->addFilter( new Twig_SimpleFilter( 'print_r', function( $arr ) {
|
45 |
+
return print_r( $arr, true );
|
46 |
+
} ) );
|
47 |
+
$twig->addFilter( new Twig_SimpleFilter( 'print_a', function( $arr ) {
|
48 |
+
return '<pre>' . self::object_docs( $arr, true ) . '</pre>';
|
49 |
+
} ) );
|
50 |
|
51 |
/* other filters */
|
52 |
+
$twig->addFilter( new Twig_SimpleFilter( 'stripshortcodes', 'strip_shortcodes' ) );
|
53 |
+
$twig->addFilter( new Twig_SimpleFilter( 'array', array( $this, 'to_array' ) ) );
|
54 |
+
$twig->addFilter( new Twig_SimpleFilter( 'string', array( $this, 'to_string' ) ) );
|
55 |
+
$twig->addFilter( new Twig_SimpleFilter( 'excerpt', 'wp_trim_words' ) );
|
56 |
+
$twig->addFilter( new Twig_SimpleFilter( 'function', array( $this, 'exec_function' ) ) );
|
57 |
+
$twig->addFilter( new Twig_SimpleFilter( 'pretags', array( $this, 'twig_pretags' ) ) );
|
58 |
+
$twig->addFilter( new Twig_SimpleFilter( 'sanitize', 'sanitize_title' ) );
|
59 |
+
$twig->addFilter( new Twig_SimpleFilter( 'shortcodes', 'do_shortcode' ) );
|
60 |
+
$twig->addFilter( new Twig_SimpleFilter( 'time_ago', array( $this, 'time_ago' ) ) );
|
61 |
+
$twig->addFilter( new Twig_SimpleFilter( 'wpautop', 'wpautop' ) );
|
62 |
+
|
63 |
+
$twig->addFilter( new Twig_SimpleFilter( 'relative', function ( $link ) {
|
64 |
+
return TimberURLHelper::get_rel_url( $link, true );
|
65 |
+
} ) );
|
66 |
+
|
67 |
+
$twig->addFilter( new Twig_SimpleFilter( 'date', array( $this, 'intl_date' ) ) );
|
68 |
+
|
69 |
+
$twig->addFilter( new Twig_SimpleFilter( 'truncate', function ( $text, $len ) {
|
70 |
+
return TimberHelper::trim_words( $text, $len );
|
71 |
+
} ) );
|
|
|
|
|
72 |
|
73 |
/* actions and filters */
|
74 |
+
$twig->addFunction( new Twig_SimpleFunction( 'action', function ( $context ) {
|
75 |
+
$args = func_get_args();
|
76 |
+
array_shift( $args );
|
77 |
+
$args[] = $context;
|
78 |
+
call_user_func_array( 'do_action', $args );
|
79 |
+
}, array( 'needs_context' => true ) ) );
|
80 |
+
|
81 |
+
$twig->addFilter( new Twig_SimpleFilter( 'apply_filters', function () {
|
82 |
+
$args = func_get_args();
|
83 |
+
$tag = current( array_splice( $args, 1, 1 ) );
|
84 |
+
|
85 |
+
return apply_filters_ref_array( $tag, $args );
|
86 |
+
} ) );
|
87 |
+
$twig->addFunction( new Twig_SimpleFunction( 'function', array( &$this, 'exec_function' ) ) );
|
88 |
+
$twig->addFunction( new Twig_SimpleFunction( 'fn', array( &$this, 'exec_function' ) ) );
|
89 |
|
90 |
/* TimberObjects */
|
91 |
+
$twig->addFunction( new Twig_SimpleFunction( 'TimberPost', function ( $pid, $PostClass = 'TimberPost' ) {
|
92 |
+
if ( is_array( $pid ) && !TimberHelper::is_array_assoc( $pid ) ) {
|
93 |
+
foreach ( $pid as &$p ) {
|
94 |
+
$p = new $PostClass( $p );
|
95 |
+
}
|
96 |
+
return $pid;
|
97 |
+
}
|
98 |
+
return new $PostClass( $pid );
|
99 |
+
} ) );
|
100 |
+
$twig->addFunction( new Twig_SimpleFunction( 'TimberImage', function ( $pid, $ImageClass = 'TimberImage' ) {
|
101 |
+
if ( is_array( $pid ) && !TimberHelper::is_array_assoc( $pid ) ) {
|
102 |
+
foreach ( $pid as &$p ) {
|
103 |
+
$p = new $ImageClass( $p );
|
104 |
+
}
|
105 |
+
return $pid;
|
106 |
+
}
|
107 |
+
return new $ImageClass( $pid );
|
108 |
+
} ) );
|
109 |
+
$twig->addFunction( new Twig_SimpleFunction( 'TimberTerm', function ( $pid, $TermClass = 'TimberTerm' ) {
|
110 |
+
if ( is_array( $pid ) && !TimberHelper::is_array_assoc( $pid ) ) {
|
111 |
+
foreach ( $pid as &$p ) {
|
112 |
+
$p = new $TermClass( $p );
|
113 |
+
}
|
114 |
+
return $pid;
|
115 |
+
}
|
116 |
+
return new $TermClass( $pid );
|
117 |
+
} ) );
|
118 |
+
$twig->addFunction( new Twig_SimpleFunction( 'TimberUser', function ( $pid, $UserClass = 'TimberUser' ) {
|
119 |
+
if ( is_array( $pid ) && !TimberHelper::is_array_assoc( $pid ) ) {
|
120 |
+
foreach ( $pid as &$p ) {
|
121 |
+
$p = new $UserClass( $p );
|
122 |
+
}
|
123 |
+
return $pid;
|
124 |
+
}
|
125 |
+
return new $UserClass( $pid );
|
126 |
+
} ) );
|
127 |
|
128 |
/* bloginfo and translate */
|
129 |
+
$twig->addFunction( 'bloginfo', new Twig_SimpleFunction( 'bloginfo', function ( $show = '', $filter = 'raw' ) {
|
130 |
+
return get_bloginfo( $show, $filter );
|
131 |
+
} ) );
|
132 |
+
$twig->addFunction( '__', new Twig_SimpleFunction( '__', function ( $text, $domain = 'default' ) {
|
133 |
+
return __( $text, $domain );
|
134 |
+
} ) );
|
135 |
|
136 |
+
$twig = apply_filters( 'get_twig', $twig );
|
137 |
|
138 |
return $twig;
|
139 |
}
|
140 |
|
141 |
/**
|
142 |
+
*
|
143 |
+
*
|
144 |
+
* @param mixed $arr
|
145 |
* @return array
|
146 |
*/
|
147 |
+
function to_array( $arr ) {
|
148 |
+
if ( is_array( $arr ) ) {
|
149 |
return $arr;
|
150 |
}
|
151 |
+
$arr = array( $arr );
|
152 |
return $arr;
|
153 |
}
|
154 |
|
155 |
/**
|
156 |
+
*
|
157 |
+
*
|
158 |
+
* @param mixed $arr
|
159 |
+
* @param string $glue
|
160 |
* @return string
|
161 |
*/
|
162 |
+
function to_string( $arr, $glue = ' ' ) {
|
163 |
+
if ( is_string( $arr ) ) {
|
164 |
return $arr;
|
165 |
}
|
166 |
+
if ( is_array( $arr ) && count( $arr ) == 1 ) {
|
167 |
return $arr[0];
|
168 |
}
|
169 |
+
if ( is_array( $arr ) ) {
|
170 |
+
return implode( $glue, $arr );
|
171 |
}
|
172 |
return null;
|
173 |
}
|
174 |
|
175 |
/**
|
176 |
+
*
|
177 |
+
*
|
178 |
+
* @param string $function_name
|
179 |
* @return mixed
|
180 |
*/
|
181 |
+
function exec_function( $function_name ) {
|
182 |
$args = func_get_args();
|
183 |
+
array_shift( $args );
|
184 |
+
return call_user_func_array( trim( $function_name ), ( $args ) );
|
185 |
}
|
186 |
|
187 |
/**
|
188 |
+
*
|
189 |
+
*
|
190 |
+
* @param string $content
|
191 |
* @return string
|
192 |
*/
|
193 |
+
function twig_pretags( $content ) {
|
194 |
+
return preg_replace_callback( '|<pre.*>(.*)</pre|isU', array( &$this, 'convert_pre_entities' ), $content );
|
195 |
}
|
196 |
|
197 |
/**
|
198 |
+
*
|
199 |
+
*
|
200 |
+
* @param array $matches
|
201 |
* @return string
|
202 |
*/
|
203 |
+
function convert_pre_entities( $matches ) {
|
204 |
+
return str_replace( $matches[1], htmlentities( $matches[1] ), $matches[0] );
|
205 |
}
|
206 |
|
207 |
/**
|
208 |
+
*
|
209 |
+
*
|
210 |
+
* @param mixed $body_classes
|
211 |
* @return string
|
212 |
*/
|
213 |
+
function body_class( $body_classes ) {
|
214 |
ob_start();
|
215 |
+
if ( is_array( $body_classes ) ) {
|
216 |
+
$body_classes = explode( ' ', $body_classes );
|
217 |
}
|
218 |
+
body_class( $body_classes );
|
219 |
$return = ob_get_contents();
|
220 |
ob_end_clean();
|
221 |
return $return;
|
222 |
}
|
223 |
|
224 |
/**
|
225 |
+
*
|
226 |
+
*
|
227 |
+
* @param string $date
|
228 |
+
* @param string $format (optional)
|
229 |
* @return string
|
230 |
*/
|
231 |
+
function intl_date( $date, $format = null ) {
|
232 |
+
if ( $format === null ) {
|
233 |
+
$format = get_option( 'date_format' );
|
234 |
}
|
235 |
|
236 |
+
if ( $date instanceof DateTime ) {
|
237 |
$timestamp = $date->getTimestamp();
|
238 |
} else {
|
239 |
+
$timestamp = strtotime( $date );
|
240 |
}
|
241 |
|
242 |
+
return date_i18n( $format, $timestamp );
|
243 |
}
|
244 |
|
245 |
//debug
|
246 |
|
247 |
/**
|
248 |
+
*
|
249 |
+
*
|
250 |
+
* @param mixed $obj
|
251 |
+
* @param bool $methods
|
252 |
* @return string
|
253 |
*/
|
254 |
+
function object_docs( $obj, $methods = true ) {
|
255 |
+
$class = get_class( $obj );
|
256 |
$properties = (array)$obj;
|
257 |
+
if ( $methods ) {
|
258 |
/** @var array $methods */
|
259 |
$methods = $obj->get_method_values();
|
260 |
}
|
261 |
+
$rets = array_merge( $properties, $methods );
|
262 |
+
ksort( $rets );
|
263 |
+
$str = print_r( $rets, true );
|
264 |
+
$str = str_replace( 'Array', $class . ' Object', $str );
|
265 |
return $str;
|
266 |
}
|
267 |
|
272 |
* @param string $format_future
|
273 |
* @return string
|
274 |
*/
|
275 |
+
function time_ago( $from, $to = null, $format_past = '%s ago', $format_future = '%s from now' ) {
|
276 |
$to = $to === null ? time() : $to;
|
277 |
+
$to = is_int( $to ) ? $to : strtotime( $to );
|
278 |
+
$from = is_int( $from ) ? $from : strtotime( $from );
|
279 |
|
280 |
+
if ( $from < $to ) {
|
281 |
+
return sprintf( $format_past, human_time_diff( $from, $to ) );
|
282 |
} else {
|
283 |
+
return sprintf( $format_future, human_time_diff( $to, $from ) );
|
284 |
}
|
285 |
}
|
286 |
|
287 |
}
|
288 |
|
289 |
new TimberTwig();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
functions/timber-url-helper.php
CHANGED
@@ -94,6 +94,13 @@ class TimberURLHelper {
|
|
94 |
return $old_root_path;
|
95 |
}
|
96 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
97 |
public static function url_to_file_system($url) {
|
98 |
$url_parts = parse_url($url);
|
99 |
$path = ABSPATH . $url_parts['path'];
|
@@ -101,6 +108,12 @@ class TimberURLHelper {
|
|
101 |
return $path;
|
102 |
}
|
103 |
|
|
|
|
|
|
|
|
|
|
|
|
|
104 |
/**
|
105 |
* @param string $src
|
106 |
* @return string
|
94 |
return $old_root_path;
|
95 |
}
|
96 |
|
97 |
+
/**
|
98 |
+
* Takes a url and figures out its place based in the file system based on path
|
99 |
+
* NOTE: Not fool-proof, makes a lot of assumptions about the file path
|
100 |
+
* matching the URL path
|
101 |
+
* @param string $url
|
102 |
+
* @return string
|
103 |
+
*/
|
104 |
public static function url_to_file_system($url) {
|
105 |
$url_parts = parse_url($url);
|
106 |
$path = ABSPATH . $url_parts['path'];
|
108 |
return $path;
|
109 |
}
|
110 |
|
111 |
+
public static function file_system_to_url( $fs ) {
|
112 |
+
$relative_path = self::get_rel_path($fs);
|
113 |
+
$home = home_url('/'.$relative_path);
|
114 |
+
return $home;
|
115 |
+
}
|
116 |
+
|
117 |
/**
|
118 |
* @param string $src
|
119 |
* @return string
|
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.20.
|
6 |
Tested up to: 4.0
|
7 |
PHP version: 5.3.0 or greater
|
8 |
License: GPLv2 or later
|
@@ -41,6 +41,10 @@ Timber is great for any WordPress developer who cares about writing good, mainta
|
|
41 |
|
42 |
== Changelog ==
|
43 |
|
|
|
|
|
|
|
|
|
44 |
= 0.20.7 =
|
45 |
* Cleaned-up logic for {{post.next}} and {{post.prev}} (thanks @alexlrobertson)
|
46 |
* Simplifiying internals of TimberCore, TimberPost (thanks @alexlrobertson)
|
2 |
Contributors: jarednova
|
3 |
Tags: template engine, templates, twig
|
4 |
Requires at least: 3.7
|
5 |
+
Stable tag: 0.20.8
|
6 |
Tested up to: 4.0
|
7 |
PHP version: 5.3.0 or greater
|
8 |
License: GPLv2 or later
|
41 |
|
42 |
== Changelog ==
|
43 |
|
44 |
+
= 0.20.8 =
|
45 |
+
* Fixed some Twig deprecation (thanks @alexlrobertson)
|
46 |
+
* Support for {{img.src|retina}} filter (@jarednova)
|
47 |
+
|
48 |
= 0.20.7 =
|
49 |
* Cleaned-up logic for {{post.next}} and {{post.prev}} (thanks @alexlrobertson)
|
50 |
* Simplifiying internals of TimberCore, TimberPost (thanks @alexlrobertson)
|
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.20.
|
8 |
Author URI: http://upstatement.com/
|
9 |
*/
|
10 |
|
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.20.8
|
8 |
Author URI: http://upstatement.com/
|
9 |
*/
|
10 |
|
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 ComposerAutoloaderInitba2f6a6f731944fa517757b2bd6a18c4::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 ComposerAutoloaderInit36822b6ae1dbe3e7b97c1dd14c0cb078
|
|
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 |
$vendorDir = dirname(__DIR__);
|
27 |
$baseDir = dirname($vendorDir);
|
@@ -47,7 +47,7 @@ class ComposerAutoloaderInit36822b6ae1dbe3e7b97c1dd14c0cb078
|
|
47 |
}
|
48 |
}
|
49 |
|
50 |
-
function
|
51 |
{
|
52 |
require $file;
|
53 |
}
|
2 |
|
3 |
// autoload_real.php @generated by Composer
|
4 |
|
5 |
+
class ComposerAutoloaderInitba2f6a6f731944fa517757b2bd6a18c4
|
6 |
{
|
7 |
private static $loader;
|
8 |
|
19 |
return self::$loader;
|
20 |
}
|
21 |
|
22 |
+
spl_autoload_register(array('ComposerAutoloaderInitba2f6a6f731944fa517757b2bd6a18c4', 'loadClassLoader'), true, true);
|
23 |
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
24 |
+
spl_autoload_unregister(array('ComposerAutoloaderInitba2f6a6f731944fa517757b2bd6a18c4', 'loadClassLoader'));
|
25 |
|
26 |
$vendorDir = dirname(__DIR__);
|
27 |
$baseDir = dirname($vendorDir);
|
47 |
}
|
48 |
}
|
49 |
|
50 |
+
function composerRequireba2f6a6f731944fa517757b2bd6a18c4($file)
|
51 |
{
|
52 |
require $file;
|
53 |
}
|
vendor/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 ComposerAutoloaderInita70107d44215103d417eb8d0d8675954::getLoader();
|
vendor/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 ComposerAutoloaderInit289078358ffed06c21324f80319e78c1
|
|
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 |
$vendorDir = dirname(__DIR__);
|
27 |
$baseDir = dirname($vendorDir);
|
@@ -47,7 +47,7 @@ class ComposerAutoloaderInit289078358ffed06c21324f80319e78c1
|
|
47 |
}
|
48 |
}
|
49 |
|
50 |
-
function
|
51 |
{
|
52 |
require $file;
|
53 |
}
|
2 |
|
3 |
// autoload_real.php @generated by Composer
|
4 |
|
5 |
+
class ComposerAutoloaderInita70107d44215103d417eb8d0d8675954
|
6 |
{
|
7 |
private static $loader;
|
8 |
|
19 |
return self::$loader;
|
20 |
}
|
21 |
|
22 |
+
spl_autoload_register(array('ComposerAutoloaderInita70107d44215103d417eb8d0d8675954', 'loadClassLoader'), true, true);
|
23 |
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
24 |
+
spl_autoload_unregister(array('ComposerAutoloaderInita70107d44215103d417eb8d0d8675954', 'loadClassLoader'));
|
25 |
|
26 |
$vendorDir = dirname(__DIR__);
|
27 |
$baseDir = dirname($vendorDir);
|
47 |
}
|
48 |
}
|
49 |
|
50 |
+
function composerRequirea70107d44215103d417eb8d0d8675954($file)
|
51 |
{
|
52 |
require $file;
|
53 |
}
|