Timber - Version 0.20.0

Version Description

  • Iterators! You can now get data using query_posts which hooks into WP loop. Methods like get_the_title() now work (big thanks to @mgmartel)
  • Fixed img_to_jpg issue with alternate WP setups (@thetmkay)
  • Fixed issue with links in TimberMenuItem
  • post.date now supports a DateTime object (@aduth)
  • removal of long-since deprecated functions
  • Massive code clean-up and bug fixes (@jaredNova, @mgmartel)
Download this release

Release Info

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

Code changes from version 0.19.2 to 0.20.0

Files changed (61) hide show
  1. README.md +1 -1
  2. functions/integrations/acf-timber.php +36 -30
  3. functions/integrations/wpcli-timber.php +52 -28
  4. functions/timber-admin.php +15 -14
  5. functions/timber-comment.php +5 -2
  6. functions/timber-core-interface.php +13 -0
  7. functions/timber-core.php +61 -30
  8. functions/timber-function-wrapper.php +1 -1
  9. functions/timber-helper.php +274 -228
  10. functions/timber-image-helper.php +5 -5
  11. functions/timber-image.php +3 -5
  12. functions/timber-loader.php +28 -2
  13. functions/timber-menu-item.php +226 -0
  14. functions/timber-menu.php +13 -155
  15. functions/timber-post-getter.php +116 -0
  16. functions/timber-post.php +28 -6
  17. functions/timber-posts-collection.php +97 -0
  18. functions/timber-query-iterator.php +127 -0
  19. functions/timber-site.php +67 -26
  20. functions/timber-term-getter.php +70 -0
  21. functions/timber-term.php +17 -5
  22. functions/timber-twig.php +9 -2
  23. functions/timber-url-helper.php +12 -7
  24. functions/timber-user.php +1 -2
  25. readme.txt +10 -2
  26. timber-starter-theme/functions.php +4 -2
  27. timber-starter-theme/views/base.twig +1 -1
  28. timber.php +62 -264
  29. vendor/autoload.php +1 -1
  30. vendor/composer/autoload_real.php +4 -4
  31. vendor/composer/installed.json +19 -14
  32. vendor/composer/installers/.gitignore +1 -1
  33. vendor/composer/installers/README.md +6 -0
  34. vendor/composer/installers/composer.json +7 -2
  35. vendor/composer/installers/src/Composer/Installers/AglInstaller.php +1 -1
  36. vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php +1 -1
  37. vendor/composer/installers/src/Composer/Installers/BaseInstaller.php +3 -2
  38. vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php +10 -0
  39. vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php +40 -3
  40. vendor/composer/installers/src/Composer/Installers/CraftInstaller.php +1 -1
  41. vendor/composer/installers/src/Composer/Installers/DolibarrInstaller.php +16 -0
  42. vendor/composer/installers/src/Composer/Installers/Installer.php +10 -1
  43. vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php +2 -0
  44. vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php +111 -0
  45. vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php +47 -0
  46. vendor/composer/installers/src/Composer/Installers/PimcoreInstaller.php +21 -0
  47. vendor/composer/installers/src/Composer/Installers/RoundcubeInstaller.php +22 -0
  48. vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php +4 -4
  49. vendor/composer/installers/src/Composer/Installers/SilverStripeInstaller.php +2 -2
  50. vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php +2 -2
  51. vendor/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php +2 -1
  52. vendor/composer/installers/src/Composer/Installers/TuskInstaller.php +14 -0
  53. vendor/composer/installers/tests/Composer/Installers/Test/CakePHPInstallerTest.php +71 -4
  54. vendor/composer/installers/tests/Composer/Installers/Test/InstallerTest.php +28 -8
  55. vendor/composer/installers/tests/Composer/Installers/Test/MediaWikiInstallerTest.php +53 -54
  56. vendor/composer/installers/tests/Composer/Installers/Test/PimcoreInstallerTest.php +44 -0
  57. vendor/composer/installers/tests/Composer/Installers/Test/PiwikInstallerTest.php +0 -1
  58. vendor/symfony/yaml/Symfony/Component/Yaml/Inline.php +21 -3
  59. vendor/symfony/yaml/Symfony/Component/Yaml/Parser.php +20 -3
  60. vendor/symfony/yaml/Symfony/Component/Yaml/Tests/ParserTest.php +47 -0
  61. vendor/symfony/yaml/Symfony/Component/Yaml/composer.json +1 -1
README.md CHANGED
@@ -4,7 +4,7 @@
4
  By Jared Novack (<a href="http://twitter.com/jarednova">@JaredNova</a>) and <a href="http://upstatement.com">Upstatement</a> (<a href="http://twitter.com/upstatement">@Upstatement</a>)</div>
5
  </div>
6
 
7
- [![Build Status](https://travis-ci.org/jarednova/timber.png)](https://travis-ci.org/jarednova/timber)
8
 
9
  ### Because WordPress is awesome, but the_loop isn't
10
  Timber helps you create fully-customized WordPress themes faster with more sustainable code. With Timber, you write your HTML using the [Twig Template Engine](http://twig.sensiolabs.org/) separate from your PHP files.
4
  By Jared Novack (<a href="http://twitter.com/jarednova">@JaredNova</a>) and <a href="http://upstatement.com">Upstatement</a> (<a href="http://twitter.com/upstatement">@Upstatement</a>)</div>
5
  </div>
6
 
7
+ [![Build Status](https://travis-ci.org/jarednova/timber.png?branch=master)](https://travis-ci.org/jarednova/timber)
8
 
9
  ### Because WordPress is awesome, but the_loop isn't
10
  Timber helps you create fully-customized WordPress themes faster with more sustainable code. With Timber, you write your HTML using the [Twig Template Engine](http://twig.sensiolabs.org/) separate from your PHP files.
functions/integrations/acf-timber.php CHANGED
@@ -1,56 +1,62 @@
1
  <?php
2
 
3
- class ACFTimber
4
- {
5
 
6
  function __construct() {
7
- add_filter('timber_post_get_meta', array($this, 'post_get_meta'), 10, 2);
8
- add_filter('timber_post_get_meta_field', array($this, 'post_get_meta_field'), 10, 3);
9
- add_filter('timber_term_get_meta', array($this, 'term_get_meta'), 10, 3);
10
- add_filter('timber_term_get_meta_field', array($this, 'term_get_meta_field'), 10, 3);
11
- add_filter('timber_user_get_meta_field_pre', array($this, 'user_get_meta_field'), 10, 3);
 
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, $field_name, $term) {
23
- $searcher = $term->taxonomy . "_" . $term->ID . "_" . $field_name;
24
- return get_field($searcher, $term->ID);
25
  }
26
 
27
- function term_get_meta($fields, $term_id, $term) {
 
 
 
 
 
 
28
  $searcher = $term->taxonomy . "_" . $term->ID; // save to a specific category
29
- $fds = get_fields($searcher);
30
- if (is_array($fds)) {
31
- foreach ($fds as $key => $value) {
32
- $key = preg_replace('/_/', '', $key, 1);
33
- $key = str_replace($searcher, '', $key);
34
- $key = preg_replace('/_/', '', $key, 1);
35
- $field = get_field($key, $searcher);
36
  $fields[$key] = $field;
37
  }
38
- $fields = array_merge($fields, $fds);
39
  }
40
  return $fields;
41
  }
42
 
43
- function user_get_meta($fields, $user_id) {
44
  return $fields;
45
  }
46
 
47
- function user_get_meta_field($value, $field, $uid) {
48
- return get_field($field, 'user_' . $uid);
49
  }
50
  }
51
 
52
- add_action('init', function () {
53
- if (class_exists('ACF')) {
54
- new ACFTimber();
55
- }
56
- });
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, $field, $uid ) {
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/integrations/wpcli-timber.php CHANGED
@@ -1,7 +1,6 @@
1
  <?php
2
  if (class_exists('WP_CLI_Command')) {
3
- class Timber_Command extends WP_CLI_Command
4
- {
5
 
6
  /**
7
  * Clears Timber and Twig's Cache
@@ -11,28 +10,24 @@ if (class_exists('WP_CLI_Command')) {
11
  * wp timber clear_cache
12
  *
13
  */
14
-
15
  public function clear_cache($mode = 'all') {
16
- if (is_array($mode)){
17
- $mode = reset($mode);
18
- }
19
- if ($mode == 'all') {
20
- self::clear_cache_twig();
21
- self::clear_cache_timber();
22
- } else if ($mode == 'twig') {
23
- self::clear_cache_twig();
24
- } else if ($mode == 'timber') {
25
- self::clear_cache_timber();
26
- }
27
  }
28
 
 
 
 
 
 
 
 
 
29
  function clear_cache_twig(){
30
- $loader = new TimberLoader();
31
- $clear = $loader->clear_cache_twig();
32
  if ($clear){
33
  WP_CLI::success('Cleared contents of twig cache');
34
  } else {
35
- WP_CLI::failure('Failed to clear cache');
36
  }
37
  }
38
 
@@ -45,20 +40,49 @@ if (class_exists('WP_CLI_Command')) {
45
  *
46
  */
47
  function clear_cache_timber() {
48
- WP_CLI::success("Cleared contents of Timber's Cache");
 
 
 
 
 
 
 
 
49
  }
50
 
51
- /**
52
- * Clears Twig's Cache
53
- *
54
- * ## EXAMPLES
55
- *
56
- * wp timber clear_cache_twig
57
- *
58
- */
59
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
 
 
 
 
61
  }
62
 
63
- WP_CLI::add_command('timber', 'Timber_Command');
64
  }
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
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
 
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($messsage);
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/timber-admin.php CHANGED
@@ -1,25 +1,26 @@
1
  <?php
2
 
3
- class TimberAdmin
4
- {
5
 
6
  function __construct() {
7
- if (!is_admin()) {
8
  return;
9
  }
10
- add_filter('plugin_action_links', array(&$this, 'settings_link'), 10, 2);
11
  }
12
 
13
- /**
14
- * @param array $links
15
- * @param string $file
16
- * @return array
17
- */
18
- function settings_link($links, $file) {
19
- if (strstr($file, '/timber.php')) {
20
- return array_merge(array(
21
- 'settings' => '<a href="https://github.com/jarednova/timber/wiki" target="_blank">Documentation</a> | <a href="https://github.com/jarednova/timber/wiki/getting-started" target="_blank">Starter Guide</a>'
22
- ), $links);
 
 
23
  }
24
  return $links;
25
  }
1
  <?php
2
 
3
+ class TimberAdmin {
 
4
 
5
  function __construct() {
6
+ if ( !is_admin() ) {
7
  return;
8
  }
9
+ add_filter( 'plugin_action_links', array( $this, 'settings_link' ), 10, 2 );
10
  }
11
 
12
+ /**
13
+ *
14
+ *
15
+ * @param array $links
16
+ * @param string $file
17
+ * @return array
18
+ */
19
+ function settings_link( $links, $file ) {
20
+ if ( strstr( $file, '/timber.php' ) ) {
21
+ return array_merge( array(
22
+ 'settings' => '<a href="https://github.com/jarednova/timber/wiki" target="_blank">Documentation</a> | <a href="https://github.com/jarednova/timber/wiki/getting-started" target="_blank">Starter Guide</a> | <a href="http://upstatement.com/timber" target="_blank">Homepage</a>'
23
+ ), $links );
24
  }
25
  return $links;
26
  }
functions/timber-comment.php CHANGED
@@ -1,7 +1,6 @@
1
  <?php
2
 
3
- class TimberComment extends TimberCore
4
- {
5
 
6
  public $PostClass = 'TimberPost';
7
  public $object_type = 'comment';
@@ -23,6 +22,10 @@ class TimberComment extends TimberCore
23
  $this->init($cid);
24
  }
25
 
 
 
 
 
26
  /**
27
  * @param mixed $cid
28
  */
1
  <?php
2
 
3
+ class TimberComment extends TimberCore implements TimberCoreInterface {
 
4
 
5
  public $PostClass = 'TimberPost';
6
  public $object_type = 'comment';
22
  $this->init($cid);
23
  }
24
 
25
+ function __toString(){
26
+ return $this->content();
27
+ }
28
+
29
  /**
30
  * @param mixed $cid
31
  */
functions/timber-core-interface.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ interface TimberCoreInterface {
4
+
5
+ public function __call( $field, $args );
6
+
7
+ public function __get( $field );
8
+
9
+ public function __isset( $field );
10
+
11
+ public function meta( $key );
12
+
13
+ }
functions/timber-core.php CHANGED
@@ -1,54 +1,98 @@
1
  <?php
2
 
3
- class TimberCore
4
- {
5
 
 
6
  public $ID;
7
  public $object_type;
8
- public $url;
9
 
10
  /**
11
- * @param array|object $info
 
 
12
  */
13
- function import($info) {
14
- if (is_object($info)) {
15
- $info = get_object_vars($info);
16
  }
17
- if (is_array($info)) {
18
- foreach ($info as $key => $value) {
19
- if (!empty($key)) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  $this->$key = $value;
21
  }
22
  }
23
  }
24
  }
25
 
 
26
  /**
27
- * @param string $key
28
- * @param mixed $value
 
 
29
  */
30
- function update($key, $value) {
31
- update_metadata($this->object_type, $this->ID, $key, $value);
32
  }
33
 
34
  /**
 
 
35
  * @return bool
36
  */
37
  function can_edit() {
38
- if (isset($this->_can_edit)) {
39
  return $this->_can_edit;
40
  }
41
  $this->_can_edit = false;
42
- if (!function_exists('current_user_can')) {
43
  return false;
44
  }
45
- if (current_user_can('edit_post', $this->ID)) {
46
  $this->_can_edit = true;
47
  }
48
  return $this->_can_edit;
49
  }
50
 
51
  /**
 
 
52
  * @return array
53
  */
54
  function get_method_values() {
@@ -57,17 +101,4 @@ class TimberCore
57
  return $ret;
58
  }
59
 
60
- /**
61
- * @deprecated
62
- * @param string $url
63
- * @return mixed
64
- */
65
- function url_to_path($url = '') {
66
- if (!strlen($url) && $this->url) {
67
- $url = $this->url;
68
- }
69
- $url_info = parse_url($url);
70
- return $url_info['path'];
71
- }
72
-
73
  }
1
  <?php
2
 
3
+ abstract class TimberCore {
 
4
 
5
+ public $id;
6
  public $ID;
7
  public $object_type;
 
8
 
9
  /**
10
+ *
11
+ *
12
+ * @return boolean
13
  */
14
+ function __isset( $field ) {
15
+ if ( isset( $this->$field ) ) {
16
+ return $this->$field;
17
  }
18
+ return false;
19
+ }
20
+
21
+ /**
22
+ * This is helpful for twig to return properties and methods see: https://github.com/fabpot/Twig/issues/2
23
+ * @return mixed
24
+ */
25
+ function __call( $field, $args ) {
26
+ return $this->__get( $field );
27
+ }
28
+
29
+ /**
30
+ * This is helpful for twig to return properties and methods see: https://github.com/fabpot/Twig/issues/2
31
+ *
32
+ * @return mixed
33
+ */
34
+ function __get( $field ) {
35
+ if ( !isset( $this->$field ) ) {
36
+ if ( $meta_value = $this->meta( $field ) ) {
37
+ $this->$field = $meta_value;
38
+ } else if (method_exists($this, $field)){
39
+ $this->$field = $this->$field();
40
+ }
41
+ }
42
+ return $this->$field;
43
+ }
44
+
45
+ /**
46
+ *
47
+ *
48
+ * @param array|object $info an object or array you want to grab data from to attach to the Timber object
49
+ */
50
+ function import( $info ) {
51
+ if ( is_object( $info ) ) {
52
+ $info = get_object_vars( $info );
53
+ }
54
+ if ( is_array( $info ) ) {
55
+ foreach ( $info as $key => $value ) {
56
+ if ( !empty( $key ) ) {
57
  $this->$key = $value;
58
  }
59
  }
60
  }
61
  }
62
 
63
+
64
  /**
65
+ *
66
+ *
67
+ * @param string $key
68
+ * @param mixed $value
69
  */
70
+ function update( $key, $value ) {
71
+ update_metadata( $this->object_type, $this->ID, $key, $value );
72
  }
73
 
74
  /**
75
+ *
76
+ *
77
  * @return bool
78
  */
79
  function can_edit() {
80
+ if ( isset( $this->_can_edit ) ) {
81
  return $this->_can_edit;
82
  }
83
  $this->_can_edit = false;
84
+ if ( !function_exists( 'current_user_can' ) ) {
85
  return false;
86
  }
87
+ if ( current_user_can( 'edit_post', $this->ID ) ) {
88
  $this->_can_edit = true;
89
  }
90
  return $this->_can_edit;
91
  }
92
 
93
  /**
94
+ *
95
+ *
96
  * @return array
97
  */
98
  function get_method_values() {
101
  return $ret;
102
  }
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  }
functions/timber-function-wrapper.php CHANGED
@@ -45,7 +45,7 @@ class TimberFunctionWrapper
45
  $args = $this->_parse_args(func_get_args(), $this->_args);
46
 
47
  if ($this->_use_ob) {
48
- return WPHelper::ob_function($this->_function, $args);
49
  } else {
50
  return (string)call_user_func_array($this->_function, $args);
51
  }
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
  }
functions/timber-helper.php CHANGED
@@ -1,33 +1,34 @@
1
  <?php
2
 
3
- class TimberHelper
4
- {
5
 
6
  /**
7
- * @param string $slug Unique identifier for transient
8
- * @param callable $callback Callback that generates the data that's to be cached
9
- * @param int $transient_time (optional) Expiration of transients in seconds
10
- * @param int $lock_timeout (optional) How long to lock the transient to prevent race conditions
11
- * @param bool $force (optional) Force callback to be executed when transient is locked
 
 
12
  * @return mixed
13
  */
14
- public static function transient($slug, $callback, $transient_time = 0, $lock_timeout = 5, $force = false) {
15
- if ($transient_time === false || (defined('WP_DISABLE_TRANSIENTS') && WP_DISABLE_TRANSIENTS)) {
16
  $enable_transients = false;
17
  } else {
18
  $enable_transients = true;
19
  }
20
 
21
- $data = $enable_transients ? get_transient($slug) : false;
22
 
23
- if (false === $data) {
24
 
25
- if ($enable_transients && self::_is_transient_locked($slug)) {
26
 
27
- $force = apply_filters('timber_force_transients', $force);
28
- $force = apply_filters('timber_force_transient_' . $slug, $force);
29
 
30
- if (!$force) {
31
  //the server is currently executing the process.
32
  //We're just gonna dump these users. Sorry!
33
  return false;
@@ -38,53 +39,57 @@ class TimberHelper
38
 
39
  // lock timeout shouldn't be higher than 5 seconds, unless
40
  // remote calls with high timeouts are made here
41
- if ($enable_transients)
42
- self::_lock_transient($slug, $lock_timeout);
43
 
44
  $data = $callback();
45
 
46
- if ($enable_transients) {
47
- set_transient($slug, $data, $transient_time);
48
- self::_unlock_transient($slug);
49
  }
50
  }
51
  return $data;
52
  }
53
 
54
- public static function _lock_transient($slug, $lock_timeout) {
55
- set_transient($slug . '_lock', true, $lock_timeout);
56
  }
57
 
58
- public static function _unlock_transient($slug) {
59
- delete_transient($slug . '_lock', true);
60
  }
61
 
62
- public static function _is_transient_locked($slug) {
63
- return (bool)get_transient($slug . '_lock');
64
  }
65
 
66
  /* These are for measuring page render time */
67
 
68
  /**
 
 
69
  * @return float
70
  */
71
  public static function start_timer() {
72
  $time = microtime();
73
- $time = explode(' ', $time);
74
  $time = $time[1] + $time[0];
75
  return $time;
76
  }
77
 
78
  /**
79
- * @param int $start
 
 
80
  * @return string
81
  */
82
- public static function stop_timer($start) {
83
  $time = microtime();
84
- $time = explode(' ', $time);
85
  $time = $time[1] + $time[0];
86
  $finish = $time;
87
- $total_time = round(($finish - $start), 4);
88
  return $total_time . ' seconds.';
89
  }
90
 
@@ -92,134 +97,149 @@ class TimberHelper
92
  ======================== */
93
 
94
  /**
 
 
95
  * @param callback $function
96
- * @param array $args
97
  * @return string
98
  */
99
- public static function ob_function($function, $args = array(null)) {
100
  ob_start();
101
- call_user_func_array($function, $args);
102
  $data = ob_get_contents();
103
  ob_end_clean();
104
  return $data;
105
  }
106
 
107
  /**
108
- * @param string $function_name
109
- * @param array $defaults
110
- * @param bool $return_output_buffer
 
 
111
  * @return TimberFunctionWrapper
112
  */
113
- public static function function_wrapper($function_name, $defaults = array(), $return_output_buffer = false) {
114
- return new TimberFunctionWrapper($function_name, $defaults, $return_output_buffer);
115
  }
116
 
117
  /**
118
- * @param $arg
 
 
119
  * @return void
120
  */
121
- public static function error_log($arg) {
122
- if (!WP_DEBUG) {
123
  return;
124
  }
125
- if (is_object($arg) || is_array($arg)) {
126
- $arg = print_r($arg, true);
127
  }
128
- error_log($arg);
129
  }
130
 
131
  /**
132
- * @param string $separator
133
- * @param string $seplocation
 
 
134
  * @return string
135
  */
136
- public static function get_wp_title($separator = ' ', $seplocation = 'left') {
137
- $separator = apply_filters('timber_wp_title_seperator', $separator);
138
- return trim(wp_title($separator, false, $seplocation));
139
  }
140
 
141
  /* Text Utilities
142
  ======================== */
143
 
144
  /**
145
- * @param string $text
146
- * @param int $num_words
147
- * @param string $more
148
- * @param string $allowed_tags
 
 
149
  * @return string
150
  */
151
- public static function trim_words($text, $num_words = 55, $more = null, $allowed_tags = 'p a span b i br') {
152
- if (null === $more) {
153
- $more = __('&hellip;');
154
  }
155
  $original_text = $text;
156
  $allowed_tag_string = '';
157
- foreach (explode(' ', $allowed_tags) as $tag) {
158
  $allowed_tag_string .= '<' . $tag . '>';
159
  }
160
- $text = strip_tags($text, $allowed_tag_string);
161
  /* translators: If your word count is based on single characters (East Asian characters),
162
  enter 'characters'. Otherwise, enter 'words'. Do not translate into your own language. */
163
- if ('characters' == _x('words', 'word count: words or characters?') && preg_match('/^utf\-?8$/i', get_option('blog_charset'))) {
164
- $text = trim(preg_replace("/[\n\r\t ]+/", ' ', $text), ' ');
165
- preg_match_all('/./u', $text, $words_array);
166
- $words_array = array_slice($words_array[0], 0, $num_words + 1);
167
  $sep = '';
168
  } else {
169
- $words_array = preg_split("/[\n\r\t ]+/", $text, $num_words + 1, PREG_SPLIT_NO_EMPTY);
170
  $sep = ' ';
171
  }
172
- if (count($words_array) > $num_words) {
173
- array_pop($words_array);
174
- $text = implode($sep, $words_array);
175
  $text = $text . $more;
176
  } else {
177
- $text = implode($sep, $words_array);
178
  }
179
- $text = self::close_tags($text);
180
- return apply_filters('wp_trim_words', $text, $num_words, $more, $original_text);
181
  }
182
 
183
  /**
184
- * @param string $html
 
 
185
  * @return string
186
  */
187
- public static function close_tags($html) {
188
- #put all opened tags into an array
189
- preg_match_all('#<([a-z]+)(?: .*)?(?<![/|/ ])>#iU', $html, $result);
190
  $openedtags = $result[1];
191
- #put all closed tags into an array
192
- preg_match_all('#</([a-z]+)>#iU', $html, $result);
193
  $closedtags = $result[1];
194
- $len_opened = count($openedtags);
195
- # all tags are closed
196
- if (count($closedtags) == $len_opened) {
197
  return $html;
198
  }
199
- $openedtags = array_reverse($openedtags);
200
- # close tags
201
- for ($i = 0; $i < $len_opened; $i++) {
202
- if (!in_array($openedtags[$i], $closedtags)) {
203
  $html .= '</' . $openedtags[$i] . '>';
204
  } else {
205
- unset($closedtags[array_search($openedtags[$i], $closedtags)]);
206
  }
207
  }
208
  return $html;
209
  }
210
 
211
  /**
212
- * @param string $ret
 
 
213
  * @return mixed
 
214
  */
215
- public static function twitterify($ret) {
216
- $ret = preg_replace("#(^|[\n ])([\w]+?://[\w]+[^ \"\n\r\t< ]*)#", "\\1<a href=\"\\2\" target=\"_blank\">\\2</a>", $ret);
217
- $ret = preg_replace("#(^|[\n ])((www|ftp)\.[^ \"\t\n\r< ]*)#", "\\1<a href=\"http://\\2\" target=\"_blank\">\\2</a>", $ret);
218
  $pattern = '#([0-9a-z]([-_.]?[0-9a-z])*@[0-9a-z]([-.]?[0-9a-z])*\\.';
219
  $pattern .= '[a-wyz][a-z](fo|g|l|m|mes|o|op|pa|ro|seum|t|u|v|z)?)#i';
220
- $ret = preg_replace($pattern, '<a href="mailto:\\1">\\1</a>', $ret);
221
- $ret = preg_replace("/\B@(\w+)/", " <a href=\"http://www.twitter.com/\\1\" target=\"_blank\">@\\1</a>", $ret);
222
- $ret = preg_replace("/\B#(\w+)/", " <a href=\"http://search.twitter.com/search?q=\\1\" target=\"_blank\">#\\1</a>", $ret);
223
  return $ret;
224
  }
225
 
@@ -227,37 +247,43 @@ class TimberHelper
227
  ======================== */
228
 
229
  /**
230
- * @param string $key
231
- * @param string $value
 
 
232
  * @return array|int
 
233
  */
234
- public static function get_posts_by_meta($key, $value) {
235
  global $wpdb;
236
- $query = $wpdb->prepare("SELECT post_id FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %s", $key, $value);
237
- $results = $wpdb->get_col($query);
238
  $pids = array();
239
- foreach ($results as $result) {
240
- if (get_post($result)) {
241
  $pids[] = $result;
242
  }
243
  }
244
- if (count($pids)) {
245
  return $pids;
246
  }
247
  return 0;
248
  }
249
 
250
  /**
251
- * @param string $key
252
- * @param string $value
 
 
253
  * @return int
 
254
  */
255
- public static function get_post_by_meta($key, $value) {
256
  global $wpdb;
257
- $query = $wpdb->prepare("SELECT post_id FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %s ORDER BY post_id", $key, $value);
258
- $results = $wpdb->get_col($query);
259
- foreach ($results as $result) {
260
- if ($result && get_post($result)) {
261
  return $result;
262
  }
263
  }
@@ -265,49 +291,57 @@ class TimberHelper
265
  }
266
 
267
  /**
268
- * @param int $ttid
 
 
269
  * @return mixed
270
  */
271
- public static function get_term_id_by_term_taxonomy_id($ttid) {
272
  global $wpdb;
273
- $query = $wpdb->prepare("SELECT term_id FROM $wpdb->term_taxonomy WHERE term_taxonomy_id = %s", $ttid);
274
- return $wpdb->get_var($query);
275
  }
276
 
277
  /* Object Utilities
278
  ======================== */
279
 
280
  /**
281
- * @param array $array
282
- * @param string $prop
 
 
283
  * @return void
284
  */
285
- public static function osort(&$array, $prop) {
286
- usort($array, function ($a, $b) use ($prop) {
287
- return $a->$prop > $b->$prop ? 1 : -1;
288
- });
289
  }
290
 
291
  /**
292
- * @param array $arr
 
 
293
  * @return bool
294
  */
295
- public static function is_array_assoc($arr) {
296
- if (!is_array($arr)) {
297
  return false;
298
  }
299
- return (bool)count(array_filter(array_keys($arr), 'is_string'));
300
  }
301
 
302
  /**
303
- * @param array $array
 
 
304
  * @return stdClass
305
  */
306
- public static function array_to_object($array) {
307
  $obj = new stdClass;
308
- foreach ($array as $k => $v) {
309
- if (is_array($v)) {
310
- $obj->{$k} = self::array_to_object($v); //RECURSION
311
  } else {
312
  $obj->{$k} = $v;
313
  }
@@ -316,21 +350,23 @@ class TimberHelper
316
  }
317
 
318
  /**
319
- * @param array $array
320
- * @param string $key
321
- * @param mixed $value
 
 
322
  * @return bool|int
323
  */
324
- public static function get_object_index_by_property($array, $key, $value) {
325
- if (is_array($array)) {
326
  $i = 0;
327
- foreach ($array as $arr) {
328
- if (is_array($arr)) {
329
- if ($arr[$key] == $value) {
330
  return $i;
331
  }
332
  } else {
333
- if ($arr->$key == $value) {
334
  return $i;
335
  }
336
  }
@@ -341,33 +377,37 @@ class TimberHelper
341
  }
342
 
343
  /**
344
- * @param array $array
345
- * @param string $key
346
- * @param mixed $value
 
 
347
  * @return array|null
348
  * @throws Exception
349
  */
350
- public static function get_object_by_property($array, $key, $value) {
351
- if (is_array($array)) {
352
- foreach ($array as $arr) {
353
- if ($arr->$key == $value) {
354
  return $arr;
355
  }
356
  }
357
  } else {
358
- throw new Exception('$array is not an array, given value: ' . $array);
359
  }
360
  return null;
361
  }
362
 
363
  /**
364
- * @param array $array
365
- * @param int $len
 
 
366
  * @return array
367
  */
368
- public static function array_truncate($array, $len) {
369
- if (sizeof($array) > $len) {
370
- $array = array_splice($array, 0, $len);
371
  }
372
  return $array;
373
  }
@@ -376,12 +416,14 @@ class TimberHelper
376
  ======================== */
377
 
378
  /**
379
- * @param mixed $property
 
 
380
  * @return bool
381
  */
382
- public static function is_true($property) {
383
- if (isset($property)) {
384
- if ($property == 'true' || $property == 1 || $property == '1' || $property == true) {
385
  return true;
386
  }
387
  }
@@ -389,19 +431,23 @@ class TimberHelper
389
  }
390
 
391
  /**
392
- * @param int $i
 
 
393
  * @return bool
394
  */
395
- public static function iseven($i) {
396
- return ($i % 2) == 0;
397
  }
398
 
399
  /**
400
- * @param int $i
 
 
401
  * @return bool
402
  */
403
- public static function isodd($i) {
404
- return ($i % 2) != 0;
405
  }
406
 
407
  /* Links, Forms, Etc. Utilities
@@ -412,19 +458,23 @@ class TimberHelper
412
  http://codex.wordpress.org/Function_Reference/comment_form */
413
 
414
  /**
415
- * @param int $post_id
416
- * @param array $args
 
 
417
  * @return string
418
  */
419
- public static function get_comment_form($post_id = null, $args = array()) {
420
- return self::ob_function('comment_form', array($args, $post_id));
421
  }
422
 
423
  /**
424
- * @param string $args
 
 
425
  * @return array
426
  */
427
- public static function paginate_links($args = '') {
428
  $defaults = array(
429
  'base' => '%_%', // http://example.com/all_posts.php%_% : %_% is replaced by format (below)
430
  'format' => '?page=%#%', // ?page=%#% : %#% is replaced by the page number
@@ -432,43 +482,43 @@ class TimberHelper
432
  'current' => 0,
433
  'show_all' => false,
434
  'prev_next' => true,
435
- 'prev_text' => __('&laquo; Previous'),
436
- 'next_text' => __('Next &raquo;'),
437
  'end_size' => 1,
438
  'mid_size' => 2,
439
  'type' => 'array',
440
  'add_args' => false, // array of query args to add
441
  'add_fragment' => ''
442
  );
443
- $args = wp_parse_args($args, $defaults);
444
  // Who knows what else people pass in $args
445
- $args['total'] = intval((int)$args['total']);
446
- if ($args['total'] < 2) {
447
  return array();
448
  }
449
  $args['current'] = (int)$args['current'];
450
  $args['end_size'] = 0 < (int)$args['end_size'] ? (int)$args['end_size'] : 1; // Out of bounds? Make it the default.
451
  $args['mid_size'] = 0 <= (int)$args['mid_size'] ? (int)$args['mid_size'] : 2;
452
- $args['add_args'] = is_array($args['add_args']) ? $args['add_args'] : false;
453
  $page_links = array();
454
  $dots = false;
455
- if ($args['prev_next'] && $args['current'] && 1 < $args['current']) {
456
- $link = str_replace('%_%', 2 == $args['current'] ? '' : $args['format'], $args['base']);
457
- $link = str_replace('%#%', $args['current'] - 1, $link);
458
- if ($args['add_args']) {
459
- $link = add_query_arg($args['add_args'], $link);
460
  }
461
  $link .= $args['add_fragment'];
462
- $link = untrailingslashit($link);
463
  $page_links[] = array(
464
  'class' => 'prev page-numbers',
465
- 'link' => esc_url(apply_filters('paginate_links', $link)),
466
  'title' => $args['prev_text']
467
  );
468
  }
469
- for ($n = 1; $n <= $args['total']; $n++) {
470
- $n_display = number_format_i18n($n);
471
- if ($n == $args['current']) {
472
  $page_links[] = array(
473
  'class' => 'page-number page-numbers current',
474
  'title' => $n_display,
@@ -478,40 +528,41 @@ class TimberHelper
478
  );
479
  $dots = true;
480
  } else {
481
- 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'])) {
482
- $link = str_replace('%_%', 1 == $n ? '' : $args['format'], $args['base']);
483
- $link = str_replace('%#%', $n, $link);
484
- $link = trailingslashit($link) . ltrim($args['add_fragment'], '/');
485
- if ($args['add_args']) {
486
- $link = rtrim(add_query_arg($args['add_args'], $link), '/');
487
  }
488
- $link = untrailingslashit($link);
489
  $page_links[] = array(
490
  'class' => 'page-number page-numbers',
491
- 'link' => esc_url(apply_filters('paginate_links', $link)),
492
  'title' => $n_display,
 
493
  'current' => $args['current'] == $n
494
  );
495
  $dots = true;
496
- } elseif ($dots && !$args['show_all']) {
497
  $page_links[] = array(
498
  'class' => 'dots',
499
- 'title' => __('&hellip;')
500
  );
501
  $dots = false;
502
  }
503
  }
504
  }
505
- if ($args['prev_next'] && $args['current'] && ($args['current'] < $args['total'] || -1 == $args['total'])) {
506
- $link = str_replace('%_%', $args['format'], $args['base']);
507
- $link = str_replace('%#%', $args['current'] + 1, $link);
508
- if ($args['add_args']) {
509
- $link = add_query_arg($args['add_args'], $link);
510
  }
511
- $link = untrailingslashit(trailingslashit($link) . $args['add_fragment']);
512
  $page_links[] = array(
513
  'class' => 'next page-numbers',
514
- 'link' => esc_url(apply_filters('paginate_links', $link)),
515
  'title' => $args['next_text']
516
  );
517
  }
@@ -519,66 +570,61 @@ class TimberHelper
519
  }
520
 
521
  /* LEGACY These have since been re-organized; but keeping linkages for backwards-compatibility */
522
-
523
- public static function get_image_path($iid) {
524
- return TimberImageHelper::get_image_path($iid);
525
  }
526
 
527
- public static function get_current_url() {
528
  return TimberURLHelper::get_current_url();
529
  }
530
 
531
- public static function is_url($url) {
532
- return TimberURLHelper::is_url($url);
533
  }
534
 
535
- public static function get_path_base() {
536
  return TimberURLHelper::get_path_base();
537
  }
538
 
539
- public static function get_rel_url($url, $force = false) {
540
- return TimberURLHelper::get_rel_url($url, $force);
541
  }
542
 
543
- public static function is_local($url) {
544
- return TimberURLHelper::is_local($url);
545
  }
546
 
547
- public static function get_full_path($src) {
548
- return TimberURLHelper::get_full_path($src);
549
  }
550
 
551
- public static function get_rel_path($src) {
552
- return TimberURLHelper::get_rel_path($src);
553
  }
554
 
555
- public static function remove_double_slashes($url) {
556
- return TimberURLHelper::remove_double_slashes($url);
557
  }
558
 
559
- public static function prepend_to_url($url, $path) {
560
- return TimberURLHelper::prepend_to_url($url, $path);
561
  }
562
 
563
- public static function preslashit($path) {
564
- return TimberURLHelper::preslashit($path);
565
  }
566
 
567
- public static function is_external($url) {
568
- return TimberURLHelper::is_external($url);
569
  }
570
 
571
- public static function download_url($url, $timeout = 300) {
572
- return TimberURLHelper::download_url($url, $timeout);
573
  }
574
 
575
- public static function get_params($i = -1) {
576
- return TimberURLHelper::get_params($i);
577
  }
578
 
579
  }
580
-
581
- class WPHelper extends TimberHelper
582
- {
583
- //for backwards compatibility, will remove eventually
584
- }
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
+ if ( $transient_time === false || ( defined( 'WP_DISABLE_TRANSIENTS' ) && WP_DISABLE_TRANSIENTS ) ) {
17
  $enable_transients = false;
18
  } else {
19
  $enable_transients = true;
20
  }
21
 
22
+ $data = $enable_transients ? get_transient( $slug ) : false;
23
 
24
+ if ( false === $data ) {
25
 
26
+ if ( $enable_transients && self::_is_transient_locked( $slug ) ) {
27
 
28
+ $force = apply_filters( 'timber_force_transients', $force );
29
+ $force = apply_filters( 'timber_force_transient_' . $slug, $force );
30
 
31
+ if ( !$force ) {
32
  //the server is currently executing the process.
33
  //We're just gonna dump these users. Sorry!
34
  return false;
39
 
40
  // lock timeout shouldn't be higher than 5 seconds, unless
41
  // remote calls with high timeouts are made here
42
+ if ( $enable_transients )
43
+ self::_lock_transient( $slug, $lock_timeout );
44
 
45
  $data = $callback();
46
 
47
+ if ( $enable_transients ) {
48
+ set_transient( $slug, $data, $transient_time );
49
+ self::_unlock_transient( $slug );
50
  }
51
  }
52
  return $data;
53
  }
54
 
55
+ public static function _lock_transient( $slug, $lock_timeout ) {
56
+ set_transient( $slug . '_lock', true, $lock_timeout );
57
  }
58
 
59
+ public static function _unlock_transient( $slug ) {
60
+ delete_transient( $slug . '_lock', true );
61
  }
62
 
63
+ public static function _is_transient_locked( $slug ) {
64
+ return (bool)get_transient( $slug . '_lock' );
65
  }
66
 
67
  /* These are for measuring page render time */
68
 
69
  /**
70
+ *
71
+ *
72
  * @return float
73
  */
74
  public static function start_timer() {
75
  $time = microtime();
76
+ $time = explode( ' ', $time );
77
  $time = $time[1] + $time[0];
78
  return $time;
79
  }
80
 
81
  /**
82
+ *
83
+ *
84
+ * @param int $start
85
  * @return string
86
  */
87
+ public static function stop_timer( $start ) {
88
  $time = microtime();
89
+ $time = explode( ' ', $time );
90
  $time = $time[1] + $time[0];
91
  $finish = $time;
92
+ $total_time = round( ( $finish - $start ), 4 );
93
  return $total_time . ' seconds.';
94
  }
95
 
97
  ======================== */
98
 
99
  /**
100
+ *
101
+ *
102
  * @param callback $function
103
+ * @param array $args
104
  * @return string
105
  */
106
+ public static function ob_function( $function, $args = array( null ) ) {
107
  ob_start();
108
+ call_user_func_array( $function, $args );
109
  $data = ob_get_contents();
110
  ob_end_clean();
111
  return $data;
112
  }
113
 
114
  /**
115
+ *
116
+ *
117
+ * @param string $function_name
118
+ * @param array $defaults
119
+ * @param bool $return_output_buffer
120
  * @return TimberFunctionWrapper
121
  */
122
+ public static function function_wrapper( $function_name, $defaults = array(), $return_output_buffer = false ) {
123
+ return new TimberFunctionWrapper( $function_name, $defaults, $return_output_buffer );
124
  }
125
 
126
  /**
127
+ *
128
+ *
129
+ * @param unknown $arg
130
  * @return void
131
  */
132
+ public static function error_log( $arg ) {
133
+ if ( !WP_DEBUG ) {
134
  return;
135
  }
136
+ if ( is_object( $arg ) || is_array( $arg ) ) {
137
+ $arg = print_r( $arg, true );
138
  }
139
+ error_log( $arg );
140
  }
141
 
142
  /**
143
+ *
144
+ *
145
+ * @param string $separator
146
+ * @param string $seplocation
147
  * @return string
148
  */
149
+ public static function get_wp_title( $separator = ' ', $seplocation = 'left' ) {
150
+ $separator = apply_filters( 'timber_wp_title_seperator', $separator );
151
+ return trim( wp_title( $separator, false, $seplocation ) );
152
  }
153
 
154
  /* Text Utilities
155
  ======================== */
156
 
157
  /**
158
+ *
159
+ *
160
+ * @param string $text
161
+ * @param int $num_words
162
+ * @param string $more
163
+ * @param string $allowed_tags
164
  * @return string
165
  */
166
+ public static function trim_words( $text, $num_words = 55, $more = null, $allowed_tags = 'p a span b i br' ) {
167
+ if ( null === $more ) {
168
+ $more = __( '&hellip;' );
169
  }
170
  $original_text = $text;
171
  $allowed_tag_string = '';
172
+ foreach ( explode( ' ', $allowed_tags ) as $tag ) {
173
  $allowed_tag_string .= '<' . $tag . '>';
174
  }
175
+ $text = strip_tags( $text, $allowed_tag_string );
176
  /* translators: If your word count is based on single characters (East Asian characters),
177
  enter 'characters'. Otherwise, enter 'words'. Do not translate into your own language. */
178
+ if ( 'characters' == _x( 'words', 'word count: words or characters?' ) && preg_match( '/^utf\-?8$/i', get_option( 'blog_charset' ) ) ) {
179
+ $text = trim( preg_replace( "/[\n\r\t ]+/", ' ', $text ), ' ' );
180
+ preg_match_all( '/./u', $text, $words_array );
181
+ $words_array = array_slice( $words_array[0], 0, $num_words + 1 );
182
  $sep = '';
183
  } else {
184
+ $words_array = preg_split( "/[\n\r\t ]+/", $text, $num_words + 1, PREG_SPLIT_NO_EMPTY );
185
  $sep = ' ';
186
  }
187
+ if ( count( $words_array ) > $num_words ) {
188
+ array_pop( $words_array );
189
+ $text = implode( $sep, $words_array );
190
  $text = $text . $more;
191
  } else {
192
+ $text = implode( $sep, $words_array );
193
  }
194
+ $text = self::close_tags( $text );
195
+ return apply_filters( 'wp_trim_words', $text, $num_words, $more, $original_text );
196
  }
197
 
198
  /**
199
+ *
200
+ *
201
+ * @param string $html
202
  * @return string
203
  */
204
+ public static function close_tags( $html ) {
205
+ //put all opened tags into an array
206
+ preg_match_all( '#<([a-z]+)(?: .*)?(?<![/|/ ])>#iU', $html, $result );
207
  $openedtags = $result[1];
208
+ //put all closed tags into an array
209
+ preg_match_all( '#</([a-z]+)>#iU', $html, $result );
210
  $closedtags = $result[1];
211
+ $len_opened = count( $openedtags );
212
+ // all tags are closed
213
+ if ( count( $closedtags ) == $len_opened ) {
214
  return $html;
215
  }
216
+ $openedtags = array_reverse( $openedtags );
217
+ // close tags
218
+ for ( $i = 0; $i < $len_opened; $i++ ) {
219
+ if ( !in_array( $openedtags[$i], $closedtags ) ) {
220
  $html .= '</' . $openedtags[$i] . '>';
221
  } else {
222
+ unset( $closedtags[array_search( $openedtags[$i], $closedtags )] );
223
  }
224
  }
225
  return $html;
226
  }
227
 
228
  /**
229
+ *
230
+ *
231
+ * @param string $ret
232
  * @return mixed
233
+ * @deprecated since 0.20.0
234
  */
235
+ public static function twitterify( $ret ) {
236
+ $ret = preg_replace( "#(^|[\n ])([\w]+?://[\w]+[^ \"\n\r\t< ]*)#", "\\1<a href=\"\\2\" target=\"_blank\">\\2</a>", $ret );
237
+ $ret = preg_replace( "#(^|[\n ])((www|ftp)\.[^ \"\t\n\r< ]*)#", "\\1<a href=\"http://\\2\" target=\"_blank\">\\2</a>", $ret );
238
  $pattern = '#([0-9a-z]([-_.]?[0-9a-z])*@[0-9a-z]([-.]?[0-9a-z])*\\.';
239
  $pattern .= '[a-wyz][a-z](fo|g|l|m|mes|o|op|pa|ro|seum|t|u|v|z)?)#i';
240
+ $ret = preg_replace( $pattern, '<a href="mailto:\\1">\\1</a>', $ret );
241
+ $ret = preg_replace( "/\B@(\w+)/", " <a href=\"http://www.twitter.com/\\1\" target=\"_blank\">@\\1</a>", $ret );
242
+ $ret = preg_replace( "/\B#(\w+)/", " <a href=\"http://search.twitter.com/search?q=\\1\" target=\"_blank\">#\\1</a>", $ret );
243
  return $ret;
244
  }
245
 
247
  ======================== */
248
 
249
  /**
250
+ *
251
+ *
252
+ * @param string $key
253
+ * @param string $value
254
  * @return array|int
255
+ * @deprecated since 0.20.0
256
  */
257
+ public static function get_posts_by_meta( $key, $value ) {
258
  global $wpdb;
259
+ $query = $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %s", $key, $value );
260
+ $results = $wpdb->get_col( $query );
261
  $pids = array();
262
+ foreach ( $results as $result ) {
263
+ if ( get_post( $result ) ) {
264
  $pids[] = $result;
265
  }
266
  }
267
+ if ( count( $pids ) ) {
268
  return $pids;
269
  }
270
  return 0;
271
  }
272
 
273
  /**
274
+ *
275
+ *
276
+ * @param string $key
277
+ * @param string $value
278
  * @return int
279
+ * @deprecated since 0.20.0
280
  */
281
+ public static function get_post_by_meta( $key, $value ) {
282
  global $wpdb;
283
+ $query = $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %s ORDER BY post_id", $key, $value );
284
+ $results = $wpdb->get_col( $query );
285
+ foreach ( $results as $result ) {
286
+ if ( $result && get_post( $result ) ) {
287
  return $result;
288
  }
289
  }
291
  }
292
 
293
  /**
294
+ *
295
+ *
296
+ * @param int $ttid
297
  * @return mixed
298
  */
299
+ public static function get_term_id_by_term_taxonomy_id( $ttid ) {
300
  global $wpdb;
301
+ $query = $wpdb->prepare( "SELECT term_id FROM $wpdb->term_taxonomy WHERE term_taxonomy_id = %s", $ttid );
302
+ return $wpdb->get_var( $query );
303
  }
304
 
305
  /* Object Utilities
306
  ======================== */
307
 
308
  /**
309
+ *
310
+ *
311
+ * @param array $array
312
+ * @param string $prop
313
  * @return void
314
  */
315
+ public static function osort( &$array, $prop ) {
316
+ usort( $array, function ( $a, $b ) use ( $prop ) {
317
+ return $a->$prop > $b->$prop ? 1 : -1;
318
+ } );
319
  }
320
 
321
  /**
322
+ *
323
+ *
324
+ * @param array $arr
325
  * @return bool
326
  */
327
+ public static function is_array_assoc( $arr ) {
328
+ if ( !is_array( $arr ) ) {
329
  return false;
330
  }
331
+ return (bool)count( array_filter( array_keys( $arr ), 'is_string' ) );
332
  }
333
 
334
  /**
335
+ *
336
+ *
337
+ * @param array $array
338
  * @return stdClass
339
  */
340
+ public static function array_to_object( $array ) {
341
  $obj = new stdClass;
342
+ foreach ( $array as $k => $v ) {
343
+ if ( is_array( $v ) ) {
344
+ $obj->{$k} = self::array_to_object( $v ); //RECURSION
345
  } else {
346
  $obj->{$k} = $v;
347
  }
350
  }
351
 
352
  /**
353
+ *
354
+ *
355
+ * @param array $array
356
+ * @param string $key
357
+ * @param mixed $value
358
  * @return bool|int
359
  */
360
+ public static function get_object_index_by_property( $array, $key, $value ) {
361
+ if ( is_array( $array ) ) {
362
  $i = 0;
363
+ foreach ( $array as $arr ) {
364
+ if ( is_array( $arr ) ) {
365
+ if ( $arr[$key] == $value ) {
366
  return $i;
367
  }
368
  } else {
369
+ if ( $arr->$key == $value ) {
370
  return $i;
371
  }
372
  }
377
  }
378
 
379
  /**
380
+ *
381
+ *
382
+ * @param array $array
383
+ * @param string $key
384
+ * @param mixed $value
385
  * @return array|null
386
  * @throws Exception
387
  */
388
+ public static function get_object_by_property( $array, $key, $value ) {
389
+ if ( is_array( $array ) ) {
390
+ foreach ( $array as $arr ) {
391
+ if ( $arr->$key == $value ) {
392
  return $arr;
393
  }
394
  }
395
  } else {
396
+ throw new Exception( '$array is not an array, given value: ' . $array );
397
  }
398
  return null;
399
  }
400
 
401
  /**
402
+ *
403
+ *
404
+ * @param array $array
405
+ * @param int $len
406
  * @return array
407
  */
408
+ public static function array_truncate( $array, $len ) {
409
+ if ( sizeof( $array ) > $len ) {
410
+ $array = array_splice( $array, 0, $len );
411
  }
412
  return $array;
413
  }
416
  ======================== */
417
 
418
  /**
419
+ *
420
+ *
421
+ * @param mixed $property
422
  * @return bool
423
  */
424
+ public static function is_true( $property ) {
425
+ if ( isset( $property ) ) {
426
+ if ( $property == 'true' || $property == 1 || $property == '1' || $property == true ) {
427
  return true;
428
  }
429
  }
431
  }
432
 
433
  /**
434
+ *
435
+ *
436
+ * @param int $i
437
  * @return bool
438
  */
439
+ public static function iseven( $i ) {
440
+ return ( $i % 2 ) == 0;
441
  }
442
 
443
  /**
444
+ *
445
+ *
446
+ * @param int $i
447
  * @return bool
448
  */
449
+ public static function isodd( $i ) {
450
+ return ( $i % 2 ) != 0;
451
  }
452
 
453
  /* Links, Forms, Etc. Utilities
458
  http://codex.wordpress.org/Function_Reference/comment_form */
459
 
460
  /**
461
+ *
462
+ *
463
+ * @param int $post_id
464
+ * @param array $args
465
  * @return string
466
  */
467
+ public static function get_comment_form( $post_id = null, $args = array() ) {
468
+ return self::ob_function( 'comment_form', array( $args, $post_id ) );
469
  }
470
 
471
  /**
472
+ *
473
+ *
474
+ * @param string $args
475
  * @return array
476
  */
477
+ public static function paginate_links( $args = '' ) {
478
  $defaults = array(
479
  'base' => '%_%', // http://example.com/all_posts.php%_% : %_% is replaced by format (below)
480
  'format' => '?page=%#%', // ?page=%#% : %#% is replaced by the page number
482
  'current' => 0,
483
  'show_all' => false,
484
  'prev_next' => true,
485
+ 'prev_text' => __( '&laquo; Previous' ),
486
+ 'next_text' => __( 'Next &raquo;' ),
487
  'end_size' => 1,
488
  'mid_size' => 2,
489
  'type' => 'array',
490
  'add_args' => false, // array of query args to add
491
  'add_fragment' => ''
492
  );
493
+ $args = wp_parse_args( $args, $defaults );
494
  // Who knows what else people pass in $args
495
+ $args['total'] = intval( (int)$args['total'] );
496
+ if ( $args['total'] < 2 ) {
497
  return array();
498
  }
499
  $args['current'] = (int)$args['current'];
500
  $args['end_size'] = 0 < (int)$args['end_size'] ? (int)$args['end_size'] : 1; // Out of bounds? Make it the default.
501
  $args['mid_size'] = 0 <= (int)$args['mid_size'] ? (int)$args['mid_size'] : 2;
502
+ $args['add_args'] = is_array( $args['add_args'] ) ? $args['add_args'] : false;
503
  $page_links = array();
504
  $dots = false;
505
+ if ( $args['prev_next'] && $args['current'] && 1 < $args['current'] ) {
506
+ $link = str_replace( '%_%', 2 == $args['current'] ? '' : $args['format'], $args['base'] );
507
+ $link = str_replace( '%#%', $args['current'] - 1, $link );
508
+ if ( $args['add_args'] ) {
509
+ $link = add_query_arg( $args['add_args'], $link );
510
  }
511
  $link .= $args['add_fragment'];
512
+ $link = untrailingslashit( $link );
513
  $page_links[] = array(
514
  'class' => 'prev page-numbers',
515
+ 'link' => esc_url( apply_filters( 'paginate_links', $link ) ),
516
  'title' => $args['prev_text']
517
  );
518
  }
519
+ for ( $n = 1; $n <= $args['total']; $n++ ) {
520
+ $n_display = number_format_i18n( $n );
521
+ if ( $n == $args['current'] ) {
522
  $page_links[] = array(
523
  'class' => 'page-number page-numbers current',
524
  'title' => $n_display,
528
  );
529
  $dots = true;
530
  } else {
531
+ 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'] ) ) {
532
+ $link = str_replace( '%_%', 1 == $n ? '' : $args['format'], $args['base'] );
533
+ $link = str_replace( '%#%', $n, $link );
534
+ $link = trailingslashit( $link ) . ltrim( $args['add_fragment'], '/' );
535
+ if ( $args['add_args'] ) {
536
+ $link = rtrim( add_query_arg( $args['add_args'], $link ), '/' );
537
  }
538
+ $link = untrailingslashit( $link );
539
  $page_links[] = array(
540
  'class' => 'page-number page-numbers',
541
+ 'link' => esc_url( apply_filters( 'paginate_links', $link ) ),
542
  'title' => $n_display,
543
+ 'name' => $n_display,
544
  'current' => $args['current'] == $n
545
  );
546
  $dots = true;
547
+ } elseif ( $dots && !$args['show_all'] ) {
548
  $page_links[] = array(
549
  'class' => 'dots',
550
+ 'title' => __( '&hellip;' )
551
  );
552
  $dots = false;
553
  }
554
  }
555
  }
556
+ if ( $args['prev_next'] && $args['current'] && ( $args['current'] < $args['total'] || -1 == $args['total'] ) ) {
557
+ $link = str_replace( '%_%', $args['format'], $args['base'] );
558
+ $link = str_replace( '%#%', $args['current'] + 1, $link );
559
+ if ( $args['add_args'] ) {
560
+ $link = add_query_arg( $args['add_args'], $link );
561
  }
562
+ $link = untrailingslashit( trailingslashit( $link ) . $args['add_fragment'] );
563
  $page_links[] = array(
564
  'class' => 'next page-numbers',
565
+ 'link' => esc_url( apply_filters( 'paginate_links', $link ) ),
566
  'title' => $args['next_text']
567
  );
568
  }
570
  }
571
 
572
  /* LEGACY These have since been re-organized; but keeping linkages for backwards-compatibility */
573
+
574
+ static function get_image_path( $iid ) {
575
+ return TimberImageHelper::get_image_path( $iid );
576
  }
577
 
578
+ static function get_current_url() {
579
  return TimberURLHelper::get_current_url();
580
  }
581
 
582
+ static function is_url( $url ) {
583
+ return TimberURLHelper::is_url( $url );
584
  }
585
 
586
+ static function get_path_base() {
587
  return TimberURLHelper::get_path_base();
588
  }
589
 
590
+ static function get_rel_url( $url, $force = false ) {
591
+ return TimberURLHelper::get_rel_url( $url, $force );
592
  }
593
 
594
+ static function is_local( $url ) {
595
+ return TimberURLHelper::is_local( $url );
596
  }
597
 
598
+ static function get_full_path( $src ) {
599
+ return TimberURLHelper::get_full_path( $src );
600
  }
601
 
602
+ static function get_rel_path( $src ) {
603
+ return TimberURLHelper::get_rel_path( $src );
604
  }
605
 
606
+ static function remove_double_slashes( $url ) {
607
+ return TimberURLHelper::remove_double_slashes( $url );
608
  }
609
 
610
+ static function prepend_to_url( $url, $path ) {
611
+ return TimberURLHelper::prepend_to_url( $url, $path );
612
  }
613
 
614
+ static function preslashit( $path ) {
615
+ return TimberURLHelper::preslashit( $path );
616
  }
617
 
618
+ static function is_external( $url ) {
619
+ return TimberURLHelper::is_external( $url );
620
  }
621
 
622
+ static function download_url( $url, $timeout = 300 ) {
623
+ return TimberURLHelper::download_url( $url, $timeout );
624
  }
625
 
626
+ static function get_params( $i = -1 ) {
627
+ return TimberURLHelper::get_params( $i );
628
  }
629
 
630
  }
 
 
 
 
 
functions/timber-image-helper.php CHANGED
@@ -326,15 +326,15 @@ class TimberImageHelper
326
  }
327
 
328
  /**
329
- * @param string $src
330
  * @param string $bghex
331
  * @return string
332
  */
333
  public static function img_to_jpg($src, $bghex = '#FFFFFF') {
334
- $src = str_replace(home_url(), '', $src);
335
- $output = str_replace('.png', '.jpg', $src);
336
- $input_file = ABSPATH . $src;
337
- $output_file = ABSPATH . $output;
338
  if (file_exists($output_file)) {
339
  return $output;
340
  }
326
  }
327
 
328
  /**
329
+ * @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)
330
  * @param string $bghex
331
  * @return string
332
  */
333
  public static function img_to_jpg($src, $bghex = '#FFFFFF') {
334
+ $path = str_replace(home_url(), '', $src);
335
+ $output = str_replace('.png', '.jpg', $path);
336
+ $input_file = self::get_server_location($path);
337
+ $output_file = self::get_server_location($output);
338
  if (file_exists($output_file)) {
339
  return $output;
340
  }
functions/timber-image.php CHANGED
@@ -1,7 +1,6 @@
1
  <?php
2
 
3
- class TimberImage extends TimberCore
4
- {
5
 
6
  public $_can_edit;
7
  public $_dimensions;
@@ -53,7 +52,6 @@ class TimberImage extends TimberCore
53
  $this->_dimensions = array();
54
  $this->_dimensions[0] = $width;
55
  $this->_dimensions[1] = $height;
56
- TimberHelper::error_log($this->_dimensions);
57
  return $this->get_dimensions_loaded($dim);
58
  }
59
 
@@ -164,7 +162,7 @@ class TimberImage extends TimberCore
164
  /**
165
  * @param int $iid
166
  */
167
- function init($iid) {
168
  if (!is_numeric($iid) && is_string($iid)) {
169
  if (strstr($iid, '://')) {
170
  $this->init_with_url($iid);
@@ -225,7 +223,7 @@ class TimberImage extends TimberCore
225
  /**
226
  * @param string $url
227
  */
228
- function init_with_url($url) {
229
  $this->abs_url = $url;
230
  $this->file_loc = $url;
231
  if (TimberURLHelper::is_local($url)) {
1
  <?php
2
 
3
+ class TimberImage extends TimberPost implements TimberCoreInterface {
 
4
 
5
  public $_can_edit;
6
  public $_dimensions;
52
  $this->_dimensions = array();
53
  $this->_dimensions[0] = $width;
54
  $this->_dimensions[1] = $height;
 
55
  return $this->get_dimensions_loaded($dim);
56
  }
57
 
162
  /**
163
  * @param int $iid
164
  */
165
+ function init( $iid = false ) {
166
  if (!is_numeric($iid) && is_string($iid)) {
167
  if (strstr($iid, '://')) {
168
  $this->init_with_url($iid);
223
  /**
224
  * @param string $url
225
  */
226
+ private function init_with_url($url) {
227
  $this->abs_url = $url;
228
  $this->file_loc = $url;
229
  if (TimberURLHelper::is_local($url)) {
functions/timber-loader.php CHANGED
@@ -1,7 +1,6 @@
1
  <?php
2
 
3
- class TimberLoader
4
- {
5
 
6
  const CACHEGROUP = 'timberloader';
7
 
@@ -253,6 +252,33 @@ class TimberLoader
253
  return $twig;
254
  }
255
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
256
  public function clear_cache_twig() {
257
  $twig = $this->get_twig();
258
  $twig->clearCacheFiles();
1
  <?php
2
 
3
+ class TimberLoader {
 
4
 
5
  const CACHEGROUP = 'timberloader';
6
 
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();
functions/timber-menu-item.php ADDED
@@ -0,0 +1,226 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 = untrailingslashit( $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 = untrailingslashit( $this->menu_object->get_link() );
98
+ }
99
+ }
100
+ return untrailingslashit( $this->url );
101
+ }
102
+
103
+ /**
104
+ *
105
+ *
106
+ * @return string
107
+ */
108
+ function get_path() {
109
+ return untrailingslashit( 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->class = trim( implode( ' ', $data->classes ) );
135
+ }
136
+
137
+ /**
138
+ *
139
+ *
140
+ * @return array|bool
141
+ */
142
+ function get_children() {
143
+ if ( isset( $this->children ) ) {
144
+ return $this->children;
145
+ }
146
+ return false;
147
+ }
148
+
149
+ /**
150
+ *
151
+ *
152
+ * @return bool
153
+ */
154
+ function is_external() {
155
+ if ( $this->type != 'custom' ) {
156
+ return false;
157
+ }
158
+ return TimberURLHelper::is_external( $this->url );
159
+ }
160
+
161
+ public function meta( $key ) {
162
+ if ( is_object( $this->menu_object ) && method_exists( $this->menu_object, 'meta' ) ) {
163
+ return $this->menu_object->meta( $key );
164
+ }
165
+ if ( isset( $this->$key ) ) {
166
+ return $this->$key;
167
+ }
168
+ }
169
+
170
+ /* Aliases */
171
+
172
+ /**
173
+ *
174
+ *
175
+ * @return array|bool
176
+ */
177
+ public function children() {
178
+ return $this->get_children();
179
+ }
180
+
181
+ /**
182
+ *
183
+ *
184
+ * @return bool
185
+ */
186
+ public function external() {
187
+ return $this->is_external();
188
+ }
189
+
190
+ /**
191
+ *
192
+ *
193
+ * @return string
194
+ */
195
+ public function link() {
196
+ return $this->get_link();
197
+ }
198
+
199
+ /**
200
+ *
201
+ *
202
+ * @return string
203
+ */
204
+ public function path() {
205
+ return untrailingslashit( $this->get_path() );
206
+ }
207
+
208
+ /**
209
+ *
210
+ *
211
+ * @return string
212
+ */
213
+ public function permalink() {
214
+ return $this->get_link();
215
+ }
216
+
217
+ /**
218
+ *
219
+ *
220
+ * @return string
221
+ */
222
+ public function get_permalink() {
223
+ return $this->get_link();
224
+ }
225
+
226
+ }
functions/timber-menu.php CHANGED
@@ -1,9 +1,9 @@
1
  <?php
2
 
3
- class TimberMenu extends TimberCore
4
- {
5
 
6
  public $MenuItemClass = 'TimberMenuItem';
 
7
 
8
  public $items = null;
9
  public $id = null;
@@ -28,7 +28,7 @@ class TimberMenu extends TimberCore
28
  if ($menu_id) {
29
  $this->init($menu_id);
30
  } else {
31
- TimberHelper::error_log("Sorry, the menu you were looking for wasn't found ('" . $slug . "'). Here's what Timber did find:");
32
  }
33
  return null;
34
  }
@@ -38,7 +38,9 @@ class TimberMenu extends TimberCore
38
  */
39
  private function init($menu_id) {
40
  $menu = wp_get_nav_menu_items($menu_id);
41
- $menu = self::order_children($menu);
 
 
42
  $this->items = $menu;
43
  $menu_info = wp_get_nav_menu_object($menu_id);
44
  $this->import($menu_info);
@@ -110,12 +112,16 @@ class TimberMenu extends TimberCore
110
  function order_children($items) {
111
  $index = array();
112
  $menu = array();
113
- _wp_menu_item_classes_by_context($items);
114
  foreach ($items as $item) {
115
- $index[$item->ID] = new $this->MenuItemClass($item);
 
 
 
 
 
116
  }
117
  foreach ($index as $item) {
118
- if ($item->menu_item_parent && isset($index[$item->menu_item_parent])) {
119
  $index[$item->menu_item_parent]->add_child($item);
120
  } else {
121
  $menu[] = $item;
@@ -135,152 +141,4 @@ class TimberMenu extends TimberCore
135
  }
136
  }
137
 
138
- class TimberMenuItem extends TimberCore
139
- {
140
-
141
- public $children;
142
- public $has_child_class = false;
143
-
144
- public $classes = array();
145
- public $class;
146
- public $post_name;
147
- public $type;
148
-
149
- /**
150
- * @param array|object $data
151
- */
152
- function __construct($data) {
153
- $this->import($data);
154
- $this->import_classes($data);
155
- if (isset($this->name)) {
156
- $this->_name = $this->name;
157
- }
158
- $this->name = $this->name();
159
- $this->add_class('menu-item-' . $this->ID);
160
- }
161
-
162
- /**
163
- * @param string $class_name
164
- */
165
- function add_class($class_name) {
166
- $this->classes[] = $class_name;
167
- $this->class .= ' ' . $class_name;
168
- }
169
-
170
- /**
171
- * @return string
172
- */
173
- function name() {
174
- if (isset($this->title)) {
175
- return $this->title;
176
- }
177
- return $this->_name;
178
- }
179
-
180
- /**
181
- * @return string
182
- */
183
- function slug() {
184
- return $this->post_name;
185
- }
186
-
187
- /**
188
- * @return string
189
- */
190
- function get_link() {
191
- return $this->url;
192
- }
193
-
194
- /**
195
- * @return string
196
- */
197
- function get_path() {
198
- return TimberURLHelper::get_rel_url($this->url);
199
- }
200
-
201
- /**
202
- * @param TimberMenuItem $item
203
- */
204
- function add_child($item) {
205
- if (!$this->has_child_class) {
206
- $this->add_class('menu-item-has-children');
207
- $this->has_child_class = true;
208
- }
209
- if (!isset($this->children)) {
210
- $this->children = array();
211
- }
212
- $this->children[] = $item;
213
- }
214
-
215
- /**
216
- * @param object $data
217
- */
218
- function import_classes($data) {
219
- $this->class = trim(implode(' ', $data->classes));
220
- }
221
-
222
- /**
223
- * @return array|bool
224
- */
225
- function get_children() {
226
- if (isset($this->children)) {
227
- return $this->children;
228
- }
229
- return false;
230
- }
231
-
232
- /**
233
- * @return bool
234
- */
235
- function is_external() {
236
- if ($this->type != 'custom') {
237
- return false;
238
- }
239
- return TimberURLHelper::is_external($this->url);
240
- }
241
-
242
- /* Aliases */
243
-
244
- /**
245
- * @return array|bool
246
- */
247
- public function children() {
248
- return $this->get_children();
249
- }
250
-
251
- /**
252
- * @return bool
253
- */
254
- public function external() {
255
- return $this->is_external();
256
- }
257
-
258
- /**
259
- * @return string
260
- */
261
- public function link() {
262
- return $this->get_link();
263
- }
264
-
265
- /**
266
- * @return string
267
- */
268
- public function path() {
269
- return $this->get_path();
270
- }
271
 
272
- /**
273
- * @return string
274
- */
275
- public function permalink() {
276
- return $this->get_link();
277
- }
278
-
279
- /**
280
- * @return string
281
- */
282
- public function get_permalink() {
283
- return $this->get_link();
284
- }
285
-
286
- }
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;
28
  if ($menu_id) {
29
  $this->init($menu_id);
30
  } else {
31
+ //TimberHelper::error_log("Sorry, the menu you were looking for wasn't found ('" . $slug . "'). Here's what Timber did find:");
32
  }
33
  return null;
34
  }
38
  */
39
  private function init($menu_id) {
40
  $menu = wp_get_nav_menu_items($menu_id);
41
+ if (is_array($menu)){
42
+ $menu = self::order_children($menu);
43
+ }
44
  $this->items = $menu;
45
  $menu_info = wp_get_nav_menu_object($menu_id);
46
  $this->import($menu_info);
112
  function order_children($items) {
113
  $index = array();
114
  $menu = array();
 
115
  foreach ($items as $item) {
116
+ if(isset($item->ID)){
117
+ if (is_object($item) && get_class($item) == 'WP_Post'){
118
+ $item = new $this->PostClass($item);
119
+ }
120
+ $index[$item->ID] = new $this->MenuItemClass($item);
121
+ }
122
  }
123
  foreach ($index as $item) {
124
+ if (isset($item->menu_item_parent) && $item->menu_item_parent && isset($index[$item->menu_item_parent])) {
125
  $index[$item->menu_item_parent]->add_child($item);
126
  } else {
127
  $menu[] = $item;
141
  }
142
  }
143
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
functions/timber-post-getter.php ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class TimberPostGetter
4
+ {
5
+
6
+ /**
7
+ * @param mixed $query
8
+ * @param string $PostClass
9
+ * @return array|bool|null
10
+ */
11
+ public static function get_post($query = false, $PostClass = 'TimberPost') {
12
+ $posts = self::get_posts( $query, $PostClass );
13
+ if ( $post = reset( $posts ) ) {
14
+ return $post;
15
+ }
16
+ return false;
17
+ }
18
+
19
+ public static function get_posts( $query = false, $PostClass = 'TimberPost', $return_collection = false ) {
20
+ $posts = self::query_posts( $query, $PostClass );
21
+ return $posts->get_posts( $return_collection );
22
+ }
23
+
24
+ /**
25
+ * @param mixed $query
26
+ * @param string $PostClass
27
+ * @return array|bool|null
28
+ */
29
+ public static function query_posts($query = false, $PostClass = 'TimberPost'){
30
+ if (self::is_post_class_or_class_map($query)) {
31
+ $PostClass = $query;
32
+ $query = false;
33
+ }
34
+
35
+ if (is_object($query) && !is_a('WP_Query' ) ){
36
+ // The only object other than a query is a type of post object
37
+ $query = array( $query );
38
+ }
39
+
40
+ if ( is_array( $query ) && count( $query ) && isset( $query[0] ) && is_object( $query[0] ) ) {
41
+ // We have an array of post objects that already have data
42
+ return new TimberPostsCollection( $query, $PostClass );
43
+ } else {
44
+ // We have a query (of sorts) to work with
45
+ $tqi = new TimberQueryIterator( $query, $PostClass );
46
+ return $tqi;
47
+ }
48
+ }
49
+
50
+ public static function get_pids($query){
51
+ $posts = self::get_posts($query);
52
+ $pids = array();
53
+ foreach($posts as $post){
54
+ if (isset($post->ID)){
55
+ $pids[] = $post->ID;
56
+ }
57
+ }
58
+ return $pids;
59
+ }
60
+
61
+ /**
62
+ * @param array $results
63
+ * @param string $PostClass
64
+ * @return array
65
+ */
66
+ static function handle_post_results($results, $PostClass = 'TimberPost') {
67
+ $posts = array();
68
+ foreach ($results as $rid) {
69
+ $PostClassUse = $PostClass;
70
+ if (is_array($PostClass)) {
71
+ $post_type = get_post_type($rid);
72
+ $PostClassUse = 'TimberPost';
73
+ if (isset($PostClass[$post_type])) {
74
+ $PostClassUse = $PostClass[$post_type];
75
+ } else {
76
+ if (is_array($PostClass)) {
77
+ TimberHelper::error_log($post_type.' of '.$rid.' not found in ' . print_r($PostClass, true));
78
+ } else {
79
+ TimberHelper::error_log($post_type.' not found in '.$PostClass);
80
+ }
81
+ }
82
+ }
83
+ $post = new $PostClassUse($rid);
84
+ if (isset($post->ID)) {
85
+ $posts[] = $post;
86
+ }
87
+ }
88
+ return new TimberPostsCollection( $posts, $PostClass );
89
+ }
90
+
91
+ /**
92
+ * @return bool
93
+ */
94
+ static function wp_query_has_posts() {
95
+ global $wp_query;
96
+ return ($wp_query && property_exists($wp_query, 'posts') && $wp_query->posts);
97
+ }
98
+
99
+ /**
100
+ * @param string|array $arg
101
+ * @return bool
102
+ */
103
+ static function is_post_class_or_class_map($arg){
104
+ if (is_string($arg) && class_exists($arg)) {
105
+ return true;
106
+ }
107
+ if (is_array($arg)) {
108
+ foreach ($arg as $item) {
109
+ if (is_string($item) && class_exists($item)) {
110
+ return true;
111
+ }
112
+ }
113
+ }
114
+ return false;
115
+ }
116
+ }
functions/timber-post.php CHANGED
@@ -1,7 +1,6 @@
1
  <?php
2
 
3
- class TimberPost extends TimberCore
4
- {
5
 
6
  public $ImageClass = 'TimberImage';
7
  public $PostClass = 'TimberPost';
@@ -13,16 +12,18 @@ class TimberPost extends TimberCore
13
  public $_custom_imported = false;
14
  public $_content;
15
  public $_get_terms;
16
-
17
  public $class;
18
  public $display_date;
19
  public $id;
 
20
  public $post_content;
21
  public $post_date;
22
  public $post_parent;
23
  public $post_title;
24
  public $post_type;
25
-
 
26
  /**
27
  * If you send the constructor nothing it will try to figure out the current post id based on being inside The_Loop
28
  * @param mixed $pid
@@ -426,9 +427,9 @@ class TimberPost extends TimberCore
426
  if (!isset($post->post_status)) {
427
  return null;
428
  }
429
- $post->slug = $post->post_name;
430
- $post->id = $post->ID;
431
  $post->status = $post->post_status;
 
 
432
  $customs = $this->get_post_custom($post->ID);
433
  $post = (object)array_merge((array)$post, (array)$customs);
434
  return $post;
@@ -692,6 +693,13 @@ class TimberPost extends TimberCore
692
  return $content;
693
  }
694
 
 
 
 
 
 
 
 
695
  /**
696
  * @return mixed
697
  */
@@ -838,6 +846,13 @@ class TimberPost extends TimberCore
838
  return $this->get_content(0, $page);
839
  }
840
 
 
 
 
 
 
 
 
841
  /**
842
  * @param string $date_format
843
  * @return string
@@ -878,6 +893,13 @@ class TimberPost extends TimberCore
878
  return $this->get_field($field_name);
879
  }
880
 
 
 
 
 
 
 
 
881
  /**
882
  * @param string $date_format
883
  * @return string
1
  <?php
2
 
3
+ class TimberPost extends TimberCore implements TimberCoreInterface {
 
4
 
5
  public $ImageClass = 'TimberImage';
6
  public $PostClass = 'TimberPost';
12
  public $_custom_imported = false;
13
  public $_content;
14
  public $_get_terms;
15
+
16
  public $class;
17
  public $display_date;
18
  public $id;
19
+ public $ID;
20
  public $post_content;
21
  public $post_date;
22
  public $post_parent;
23
  public $post_title;
24
  public $post_type;
25
+ public $slug;
26
+
27
  /**
28
  * If you send the constructor nothing it will try to figure out the current post id based on being inside The_Loop
29
  * @param mixed $pid
427
  if (!isset($post->post_status)) {
428
  return null;
429
  }
 
 
430
  $post->status = $post->post_status;
431
+ $post->id = $post->ID;
432
+ $post->slug = $post->post_name;
433
  $customs = $this->get_post_custom($post->ID);
434
  $post = (object)array_merge((array)$post, (array)$customs);
435
  return $post;
693
  return $content;
694
  }
695
 
696
+ /**
697
+ * @return string
698
+ */
699
+ function get_paged_content() {
700
+ global $page;
701
+ return $this->get_content(0,$page);
702
+ }
703
  /**
704
  * @return mixed
705
  */
846
  return $this->get_content(0, $page);
847
  }
848
 
849
+ /**
850
+ * @return string
851
+ */
852
+ public function paged_content() {
853
+ return $this->get_paged_content();
854
+ }
855
+
856
  /**
857
  * @param string $date_format
858
  * @return string
893
  return $this->get_field($field_name);
894
  }
895
 
896
+ /**
897
+ * @return string
898
+ */
899
+ public function name(){
900
+ return $this->title();
901
+ }
902
+
903
  /**
904
  * @param string $date_format
905
  * @return string
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/timber-query-iterator.php ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+
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
+
42
+ } else {
43
+ TimberHelper::error_log( 'I have failed you! in ' . basename( __FILE__ ) . '::' . __LINE__ );
44
+ TimberHelper::error_log( $query );
45
+
46
+ // We have failed hard, at least let get something.
47
+ $the_query = new WP_Query();
48
+ }
49
+
50
+ $this->_query = $the_query;
51
+
52
+ }
53
+
54
+ public function get_posts( $return_collection = false ) {
55
+ $posts = new TimberPostsCollection( $this->_query->posts, $this->_posts_class );
56
+ return ( $return_collection ) ? $posts : $posts->get_posts();
57
+ }
58
+
59
+ //
60
+ // GET POSTS
61
+ //
62
+ public static function get_query_from_array_of_ids( $query = array() ) {
63
+ if ( !is_array( $query ) || !count( $query ) )
64
+ return null;
65
+
66
+ return new WP_Query( array(
67
+ 'post_type'=> 'any',
68
+ 'post__in' => $query,
69
+ 'orderby' => 'post__in',
70
+ 'numberposts' => -1
71
+ ) );
72
+ }
73
+
74
+ public static function get_query_from_string( $string = '' ) {
75
+ $post_type = false;
76
+
77
+ if ( is_string( $string ) && strstr( $string, '#' ) ) {
78
+ //we have a post_type directive here
79
+ list( $post_type, $string ) = explode( '#', $string );
80
+ }
81
+
82
+ $query = array(
83
+ 'post_type' => ( $post_type ) ? $post_type : 'any'
84
+ );
85
+
86
+ if ( is_numeric( $string ) ) {
87
+ $query['p'] = $string;
88
+
89
+ } else {
90
+ $query['name'] = $string;
91
+ }
92
+
93
+ return new WP_Query( $query );
94
+ }
95
+
96
+ //
97
+ // Iterator Interface
98
+ //
99
+
100
+ public function valid() {
101
+ return $this->_query->have_posts();
102
+ }
103
+
104
+ public function current() {
105
+ global $post;
106
+
107
+ $this->_query->the_post();
108
+
109
+ // Sets up the global post, but also return the post, for use in Twig template
110
+ $posts_class = $this->_posts_class;
111
+ return new $posts_class( $post );
112
+ }
113
+
114
+ /**
115
+ * Don't implement next, because current already advances the loop
116
+ */
117
+ final public function next() {}
118
+
119
+ public function rewind() {
120
+ $this->_query->rewind_posts();
121
+ }
122
+
123
+ public function key() {
124
+ $this->_query->current_post;
125
+ }
126
+
127
+ }
functions/timber-site.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
 
3
- class TimberSite extends TimberCore
4
- {
5
  public $blogname;
6
  public $charset;
7
  public $description;
@@ -14,74 +14,88 @@ class TimberSite extends TimberCore
14
  public $siteurl;
15
  public $theme;
16
  public $title;
17
-
18
  /**
 
 
19
  * @param string|int $site_name_or_id
20
  */
21
- function __construct($site_name_or_id = null) {
22
- if (is_multisite()) {
23
- $this->init_with_multisite($site_name_or_id);
24
  } else {
25
  $this->init();
26
  }
27
  }
28
 
29
  /**
 
 
30
  * @param string|int $site_name_or_id
31
  */
32
- function init_with_multisite($site_name_or_id) {
33
- if ($site_name_or_id === null) {
34
  //this is necessary for some reason, otherwise returns 1 all the time
35
- if (is_multisite()) {
36
  restore_current_blog();
37
  $site_name_or_id = get_current_blog_id();
38
  }
39
  }
40
- $info = get_blog_details($site_name_or_id);
41
- $this->import($info);
42
  $this->ID = $info->blog_id;
43
  $this->name = $this->blogname;
44
  $this->title = $this->blogname;
45
  $this->url = $this->siteurl;
46
  $this->id = $this->ID;
47
- $theme_slug = get_blog_option($info->blog_id, 'stylesheet');
48
- $this->theme = new TimberTheme($theme_slug);
49
- $this->description = get_blog_option($info->blog_id, 'blogdescription');
50
  $this->multisite = true;
51
  }
52
 
53
  function init() {
54
- $this->name = get_bloginfo('name');
55
  $this->title = $this->name;
56
- $this->description = get_bloginfo('description');
57
- $this->url = get_bloginfo('url');
58
- $this->language = get_bloginfo('language');
59
- $this->charset = get_bloginfo('charset');
60
- $this->pingback_url = get_bloginfo('pingback_url');
61
  $this->theme = new TimberTheme();
62
- $this->language_attributes = TimberHelper::function_wrapper('language_attributes');
63
  $this->multisite = false;
64
  }
65
 
66
  /**
67
- * @param string $field
 
 
68
  * @return mixed
69
  */
70
- function __get($field) {
71
- if (!isset($this->$field)) {
72
- $this->$field = get_blog_option($this->ID, $field);
 
 
 
 
73
  }
74
  return $this->$field;
75
  }
76
 
77
  /**
 
 
78
  * @return string
79
  */
80
  function get_link() {
81
- return $this->siteurl;
82
  }
83
 
84
  /**
 
 
85
  * @return string
86
  */
87
  function get_url() {
@@ -89,6 +103,8 @@ class TimberSite extends TimberCore
89
  }
90
 
91
  /**
 
 
92
  * @return string
93
  */
94
  function link() {
@@ -96,6 +112,31 @@ class TimberSite extends TimberCore
96
  }
97
 
98
  /**
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
  * @return string
100
  */
101
  function url() {
1
  <?php
2
 
3
+ class TimberSite extends TimberCore implements TimberCoreInterface {
4
+
5
  public $blogname;
6
  public $charset;
7
  public $description;
14
  public $siteurl;
15
  public $theme;
16
  public $title;
17
+
18
  /**
19
+ *
20
+ *
21
  * @param string|int $site_name_or_id
22
  */
23
+ function __construct( $site_name_or_id = null ) {
24
+ if ( is_multisite() ) {
25
+ $this->init_with_multisite( $site_name_or_id );
26
  } else {
27
  $this->init();
28
  }
29
  }
30
 
31
  /**
32
+ *
33
+ *
34
  * @param string|int $site_name_or_id
35
  */
36
+ function init_with_multisite( $site_name_or_id ) {
37
+ if ( $site_name_or_id === null ) {
38
  //this is necessary for some reason, otherwise returns 1 all the time
39
+ if ( is_multisite() ) {
40
  restore_current_blog();
41
  $site_name_or_id = get_current_blog_id();
42
  }
43
  }
44
+ $info = get_blog_details( $site_name_or_id );
45
+ $this->import( $info );
46
  $this->ID = $info->blog_id;
47
  $this->name = $this->blogname;
48
  $this->title = $this->blogname;
49
  $this->url = $this->siteurl;
50
  $this->id = $this->ID;
51
+ $theme_slug = get_blog_option( $info->blog_id, 'stylesheet' );
52
+ $this->theme = new TimberTheme( $theme_slug );
53
+ $this->description = get_blog_option( $info->blog_id, 'blogdescription' );
54
  $this->multisite = true;
55
  }
56
 
57
  function init() {
58
+ $this->name = get_bloginfo( 'name' );
59
  $this->title = $this->name;
60
+ $this->description = get_bloginfo( 'description' );
61
+ $this->url = get_bloginfo( 'url' );
62
+ $this->language = get_bloginfo( 'language' );
63
+ $this->charset = get_bloginfo( 'charset' );
64
+ $this->pingback_url = get_bloginfo( 'pingback_url' );
65
  $this->theme = new TimberTheme();
66
+ $this->language_attributes = TimberHelper::function_wrapper( 'language_attributes' );
67
  $this->multisite = false;
68
  }
69
 
70
  /**
71
+ *
72
+ *
73
+ * @param string $field
74
  * @return mixed
75
  */
76
+ function __get( $field ) {
77
+ if ( !isset( $this->$field ) ) {
78
+ if ( is_multisite() ) {
79
+ $this->$field = get_blog_option( $this->ID, $field );
80
+ } else {
81
+ $this->$field = get_option( $field );
82
+ }
83
  }
84
  return $this->$field;
85
  }
86
 
87
  /**
88
+ *
89
+ *
90
  * @return string
91
  */
92
  function get_link() {
93
+ return $this->url;
94
  }
95
 
96
  /**
97
+ *
98
+ *
99
  * @return string
100
  */
101
  function get_url() {
103
  }
104
 
105
  /**
106
+ *
107
+ *
108
  * @return string
109
  */
110
  function link() {
112
  }
113
 
114
  /**
115
+ *
116
+ */
117
+ function meta( $field ) {
118
+ return $this->__get( $field );
119
+ }
120
+
121
+ /**
122
+ *
123
+ *
124
+ * @param string $key
125
+ * @param mixed $value
126
+ */
127
+ function update( $key, $value ) {
128
+ $value = apply_filters( 'timber_site_set_meta', $value, $key, $this->ID, $this );
129
+ if ( is_multisite() ) {
130
+ update_blog_option( $this->ID, $key, $value );
131
+ } else {
132
+ update_option( $key, $value );
133
+ }
134
+ $this->$key = $value;
135
+ }
136
+
137
+ /**
138
+ *
139
+ *
140
  * @return string
141
  */
142
  function url() {
functions/timber-term-getter.php CHANGED
@@ -3,6 +3,74 @@
3
  class TimberTermGetter
4
  {
5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  /**
7
  * @param string $query_string
8
  * @return stdClass
@@ -49,6 +117,8 @@ class TimberTermGetter
49
  $ret->taxonomies = array($ret->taxonomies);
50
  }
51
  $ret->taxonomies = self::correct_taxonomy_names($ret->taxonomies);
 
 
52
  }
53
  return $ret;
54
  }
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 $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
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
  }
functions/timber-term.php CHANGED
@@ -1,7 +1,6 @@
1
  <?php
2
 
3
- class TimberTerm extends TimberCore
4
- {
5
 
6
  public $PostClass = 'TimberPost';
7
  public $TermClass = 'TimberTerm';
@@ -34,6 +33,8 @@ class TimberTerm extends TimberCore
34
  return $this->name;
35
  }
36
 
 
 
37
  /* Setup
38
  ===================== */
39
 
@@ -144,9 +145,9 @@ class TimberTerm extends TimberCore
144
  */
145
  public function get_meta_field($field_name) {
146
  if (!isset($this->$field_name)) {
147
- $field = '';
148
- $field = apply_filters('timber_term_get_meta_field', $field, $this->ID, $field_name, $this);
149
- $this->$field_name = $field;
150
  }
151
  return $this->$field_name;
152
  }
@@ -231,6 +232,17 @@ class TimberTerm extends TimberCore
231
  return $this->_children;
232
  }
233
 
 
 
 
 
 
 
 
 
 
 
 
234
  /* Alias
235
  ====================== */
236
 
1
  <?php
2
 
3
+ class TimberTerm extends TimberCore implements TimberCoreInterface {
 
4
 
5
  public $PostClass = 'TimberPost';
6
  public $TermClass = 'TimberTerm';
33
  return $this->name;
34
  }
35
 
36
+
37
+
38
  /* Setup
39
  ===================== */
40
 
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
  }
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
 
functions/timber-twig.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- class TimberTwig
4
  {
5
 
6
  public static $dir_name;
@@ -203,7 +203,14 @@ class TimberTwig
203
  if ($format === null) {
204
  $format = get_option('date_format');
205
  }
206
- return date_i18n($format, strtotime($date));
 
 
 
 
 
 
 
207
  }
208
 
209
  //debug
1
  <?php
2
 
3
+ class TimberTwig
4
  {
5
 
6
  public static $dir_name;
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
functions/timber-url-helper.php CHANGED
@@ -164,8 +164,9 @@ class TimberURLHelper
164
  * @param string $url
165
  * @param int $timeout
166
  * @return string|WP_Error
 
167
  */
168
- public static function download_url($url, $timeout = 300) {
169
  if (!$url) {
170
  return new WP_Error('http_no_url', __('Invalid URL Provided.'));
171
  }
@@ -192,7 +193,7 @@ class TimberURLHelper
192
  * @param int $i
193
  * @return array
194
  */
195
- public static function get_params($i = -1) {
196
  $args = explode('/', trim(strtolower($_SERVER['REQUEST_URI'])));
197
  $newargs = array();
198
  foreach ($args as $arg) {
@@ -200,12 +201,16 @@ class TimberURLHelper
200
  $newargs[] = $arg;
201
  }
202
  }
203
- if ($i > -1) {
204
- if (isset($newargs[$i])) {
205
- return $newargs[$i];
206
- }
 
 
 
 
 
207
  }
208
- return $newargs;
209
  }
210
 
211
  }
164
  * @param string $url
165
  * @param int $timeout
166
  * @return string|WP_Error
167
+ * @deprecated since 0.20.0
168
  */
169
+ static function download_url($url, $timeout = 300) {
170
  if (!$url) {
171
  return new WP_Error('http_no_url', __('Invalid URL Provided.'));
172
  }
193
  * @param int $i
194
  * @return array
195
  */
196
+ public static function get_params($i = false) {
197
  $args = explode('/', trim(strtolower($_SERVER['REQUEST_URI'])));
198
  $newargs = array();
199
  foreach ($args as $arg) {
201
  $newargs[] = $arg;
202
  }
203
  }
204
+ if ($i === false){
205
+ return $newargs;
206
+ }
207
+ if ($i < 0){
208
+ //count from end
209
+ $i = count($newargs) + $i;
210
+ }
211
+ if (isset($newargs[$i])) {
212
+ return $newargs[$i];
213
  }
 
214
  }
215
 
216
  }
functions/timber-user.php CHANGED
@@ -1,7 +1,6 @@
1
  <?php
2
 
3
- class TimberUser extends TimberCore
4
- {
5
 
6
  public $object_type = 'user';
7
  public static $representation = 'user';
1
  <?php
2
 
3
+ class TimberUser extends TimberCore implements TimberCoreInterface {
 
4
 
5
  public $object_type = 'user';
6
  public static $representation = 'user';
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: jarednova
3
  Tags: template engine, templates, twig
4
  Requires at least: 3.7
5
- Stable tag: 0.19.2
6
- Tested up to: 3.9
7
  PHP version: 5.3.0 or greater
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -41,6 +41,14 @@ Timber is great for any WordPress developer who cares about writing good, mainta
41
 
42
  == Changelog ==
43
 
 
 
 
 
 
 
 
 
44
  = 0.19.2 =
45
  * Fixed issue with {{post.author.name}}
46
  * Bug fixes and code organization (@hsz, @jaredNova)
2
  Contributors: jarednova
3
  Tags: template engine, templates, twig
4
  Requires at least: 3.7
5
+ Stable tag: 0.20.0
6
+ Tested up to: 3.9.1
7
  PHP version: 5.3.0 or greater
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
41
 
42
  == Changelog ==
43
 
44
+ = 0.20.0 =
45
+ * Iterators! You can now get data using query_posts which hooks into WP loop. Methods like get_the_title() now work (big thanks to @mgmartel)
46
+ * Fixed img_to_jpg issue with alternate WP setups (@thetmkay)
47
+ * Fixed issue with links in TimberMenuItem
48
+ * post.date now supports a DateTime object (@aduth)
49
+ * removal of long-since deprecated functions
50
+ * Massive code clean-up and bug fixes (@jaredNova, @mgmartel)
51
+
52
  = 0.19.2 =
53
  * Fixed issue with {{post.author.name}}
54
  * Bug fixes and code organization (@hsz, @jaredNova)
timber-starter-theme/functions.php CHANGED
@@ -1,7 +1,9 @@
1
  <?php
2
-
3
  if (!class_exists('Timber')){
4
- echo 'Timber not activated. Make sure you activate the plugin in <a href="/wp-admin/plugins.php#timber">/wp-admin/plugins.php</a>';
 
 
5
  return;
6
  }
7
 
1
  <?php
2
+
3
  if (!class_exists('Timber')){
4
+ add_action( 'admin_notices', function(){
5
+ echo '<div class="error"><p>Timber not activated. Make sure you activate the plugin in <a href="/wp-admin/plugins.php#timber">/wp-admin/plugins.php</a></p></div>';
6
+ });
7
  return;
8
  }
9
 
timber-starter-theme/views/base.twig CHANGED
@@ -1,5 +1,5 @@
1
  {% block html_head_container %}
2
- {% include 'html-header.twig' %}
3
  {% block head %}
4
  {% endblock %}
5
  </head>
1
  {% block html_head_container %}
2
+ {% include 'html-header.twig' %}
3
  {% block head %}
4
  {% endblock %}
5
  </head>
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.19.2
8
  Author URI: http://upstatement.com/
9
  */
10
 
@@ -21,27 +21,28 @@ require_once(__DIR__ . '/functions/timber-helper.php');
21
  require_once(__DIR__ . '/functions/timber-url-helper.php');
22
  require_once(__DIR__ . '/functions/timber-image-helper.php');
23
 
 
24
  require_once(__DIR__ . '/functions/timber-core.php');
25
  require_once(__DIR__ . '/functions/timber-post.php');
 
26
  require_once(__DIR__ . '/functions/timber-comment.php');
27
  require_once(__DIR__ . '/functions/timber-user.php');
28
  require_once(__DIR__ . '/functions/timber-term.php');
29
  require_once(__DIR__ . '/functions/timber-term-getter.php');
30
  require_once(__DIR__ . '/functions/timber-image.php');
 
31
  require_once(__DIR__ . '/functions/timber-menu.php');
 
 
32
 
33
  //Other 2nd-class citizens
34
  require_once(__DIR__ . '/functions/timber-archives.php');
35
  require_once(__DIR__ . '/functions/timber-site.php');
36
  require_once(__DIR__ . '/functions/timber-theme.php');
37
-
38
-
39
  require_once(__DIR__ . '/functions/timber-loader.php');
40
  require_once(__DIR__ . '/functions/timber-function-wrapper.php');
41
  require_once(__DIR__ . '/functions/integrations/acf-timber.php');
42
- if ( defined('WP_CLI') && WP_CLI ) {
43
- require_once(__DIR__ . '/functions/integrations/wpcli-timber.php');
44
- }
45
 
46
  require_once(__DIR__ . '/functions/timber-admin.php');
47
 
@@ -101,254 +102,100 @@ class Timber {
101
  * @return array|bool|null
102
  */
103
  public static function get_post($query = false, $PostClass = 'TimberPost') {
104
- if (is_int($query)) {
105
- /* its a post id number */
106
- $query = array($query);
107
- }
108
- $posts = self::get_posts($query, $PostClass);
109
- if (count($posts) && is_array($posts)) {
110
- return $posts[0];
111
- }
112
- return $posts;
113
  }
114
 
115
-
116
  /**
117
  * @param mixed $query
118
  * @param string $PostClass
119
  * @return array|bool|null
120
  */
121
- public static function get_posts($query = false, $PostClass = 'TimberPost'){
122
- if (self::is_post_class_or_class_map($query)) {
123
- $PostClass = $query;
124
- $query = false;
125
- }
126
- if (TimberHelper::is_array_assoc($query) || (is_string($query) && strstr($query, '='))) {
127
- // we have a regularly formed WP query string or array to use
128
- $posts = self::get_posts_from_wp_query($query, $PostClass);
129
- } else if (is_string($query) && !is_integer($query)) {
130
- // we have what could be a post name to pull out
131
- $posts = self::get_posts_from_slug($query, $PostClass);
132
- } else if (is_array($query) && count($query) && (is_integer($query[0]) || is_string($query[0]))) {
133
- // we have a list of pids (post IDs) to extract from
134
- $posts = self::get_posts_from_array_of_ids($query, $PostClass);
135
- } else if (is_array($query) && count($query) && isset($query[0]) && is_object($query[0])) {
136
- // maybe its an array of post objects that already have data
137
- $posts = self::handle_post_results($query, $PostClass);
138
- } else if (self::wp_query_has_posts()) {
139
- //lets just use the default WordPress current query
140
- $posts = self::get_posts_from_loop($PostClass);
141
- } else if (!$query) {
142
- //okay, everything failed lets just return some posts so that the user has something to work with
143
- //this turns out to cause all kinds of awful behavior
144
- //return self::get_posts_from_wp_query(array(), $PostClass);
145
- return null;
146
- } else {
147
- TimberHelper::error_log('I have failed you! in timber.php::94');
148
- TimberHelper::error_log($query);
149
- return $query;
150
- }
151
 
152
- return self::maybe_set_preview( $posts );
 
153
  }
154
 
155
  /**
156
  * @param array|string $query
157
  * @return array
 
158
  */
159
- public static function get_pids($query = null) {
160
- $posts = get_posts($query);
161
- $pids = array();
162
- foreach ($posts as $post) {
163
- if ($post->ID) {
164
- $pids[] = $post->ID;
165
- }
166
- }
167
- return $pids;
168
  }
169
 
170
  /**
171
  * @param string $PostClass
172
  * @return array
 
173
  */
174
- public static function get_posts_from_loop($PostClass) {
175
- $results = self::get_pids_from_loop();
176
- return self::handle_post_results($results, $PostClass);
177
- }
178
-
179
- /**
180
- * @return array
181
- */
182
- public static function get_pids_from_loop() {
183
- if (!self::wp_query_has_posts()) { return array(); }
184
-
185
- global $wp_query;
186
- return array_filter(array_map(function($p) {
187
- return ($p && property_exists($p, 'ID')) ? $p->ID : null;
188
- }, $wp_query->posts));
189
  }
190
 
191
  /**
192
  * @param string $slug
193
  * @param string $PostClass
194
  * @return array
 
195
  */
196
- public static function get_posts_from_slug($slug, $PostClass) {
197
- global $wpdb;
198
- $query = $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_name = %s", $slug);
199
- if (strstr($slug, '#')) {
200
- //we have a post_type directive here
201
- $q = explode('#', $slug);
202
- $q = array_filter($q);
203
- $q = array_values($q);
204
- if (count($q) == 1){
205
- $query = $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_name = %s", $q[0]);
206
- } else if (count($q) == 2){
207
- $query = $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_name = %s AND post_type = %s LIMIT 1", $q[1], $q[0]);
208
- } else {
209
- TimberHelper::error_log('something we dont understand about '.$slug);
210
- }
211
- }
212
- $results = $wpdb->get_col($query);
213
- return self::handle_post_results($results, $PostClass);
214
  }
215
 
216
  /**
217
  * @param array $query
218
  * @param string $PostClass
219
  * @return array
 
220
  */
221
- public static function get_posts_from_wp_query($query = array(), $PostClass = 'TimberPost') {
222
- $results = get_posts($query);
223
- return self::handle_post_results($results, $PostClass);
224
  }
225
 
226
  /**
227
  * @param array $query
228
  * @param string $PostClass
229
  * @return array|null
 
230
  */
231
- public static function get_posts_from_array_of_ids($query = array(), $PostClass = 'TimberPost') {
232
- if (!is_array($query) || !count($query)) {
233
- return null;
234
- }
235
- $results = get_posts(array('post_type'=>'any', 'post__in' =>$query, 'orderby' => 'post__in', 'numberposts' => -1));
236
- return self::handle_post_results($results, $PostClass);
237
  }
238
 
239
  /**
240
  * @param array $results
241
  * @param string $PostClass
242
  * @return array
 
243
  */
244
- public static function handle_post_results($results, $PostClass = 'TimberPost') {
245
- $posts = array();
246
- foreach ($results as $rid) {
247
- $PostClassUse = $PostClass;
248
- if (is_array($PostClass)) {
249
- $post_type = get_post_type($rid);
250
- $PostClassUse = 'TimberPost';
251
- if (isset($PostClass[$post_type])) {
252
- $PostClassUse = $PostClass[$post_type];
253
- } else {
254
- if (is_array($PostClass)) {
255
- TimberHelper::error_log($post_type.' of '.$rid.' not found in ' . print_r($PostClass, true));
256
- } else {
257
- TimberHelper::error_log($post_type.' not found in '.$PostClass);
258
- }
259
- }
260
- }
261
- $post = new $PostClassUse($rid);
262
- if (isset($post->ID)) {
263
- $posts[] = $post;
264
- }
265
- }
266
- return $posts;
267
  }
268
 
269
  /**
270
  * @param $query
271
- * @return mixed
272
- */
273
- public function get_pid($query) {
274
- $post = self::get_posts($query);
275
- return $post->ID;
276
- }
277
-
278
- public static function wp_query_has_posts() {
279
- global $wp_query;
280
- return ($wp_query && property_exists($wp_query, 'posts') && $wp_query->posts);
281
- }
282
-
283
- /* Post Previews
284
- ================================ */
285
-
286
- /**
287
- * @param array $posts
288
- * @return array
289
  */
290
- public static function maybe_set_preview( $posts ) {
291
- if ( is_array( $posts ) && isset( $_GET['preview'] ) && $_GET['preview']
292
- && isset( $_GET['preview_id'] ) && $_GET['preview_id']
293
- && current_user_can( 'edit_post', $_GET['preview_id'] ) ) {
294
-
295
- // No need to check the nonce, that already happened in _show_post_preview on init
296
-
297
- $preview_id = $_GET['preview_id'];
298
- foreach( $posts as &$post ) {
299
- if ( is_object( $post ) && $post->ID == $preview_id ) {
300
- // Based on _set_preview( $post ), but adds import_custom
301
- $preview = wp_get_post_autosave( $preview_id );
302
-
303
- if ( is_object($preview) ) {
304
-
305
- $preview = sanitize_post($preview);
306
-
307
- $post->post_content = $preview->post_content;
308
- $post->post_title = $preview->post_title;
309
- $post->post_excerpt = $preview->post_excerpt;
310
- $post->import_custom( $preview_id );
311
-
312
- add_filter( 'get_the_terms', '_wp_preview_terms_filter', 10, 3 );
313
- }
314
- }
315
- }
316
-
317
  }
318
-
319
- return $posts;
320
- }
321
-
322
-
323
- /* Deprecated
324
- ================================ */
325
-
326
- /**
327
- * @param string $PostClass
328
- * @return bool|null
329
- */
330
- public static function loop_to_posts($PostClass = 'TimberPost') {
331
- return self::get_posts(false, $PostClass);
332
  }
333
 
334
  /**
335
- * @return bool|int
 
336
  */
337
- public static function loop_to_id() {
338
- if (!self::wp_query_has_posts()) { return false; }
339
-
340
- global $wp_query;
341
- $post_num = property_exists($wp_query, 'current_post')
342
- ? $wp_query->current_post + 1
343
- : 0
344
- ;
345
-
346
- if (!isset($wp_query->posts[$post_num])) { return false; }
347
-
348
- return $wp_query->posts[$post_num]->ID;
349
  }
350
 
351
-
352
  /* Term Retrieval
353
  ================================ */
354
 
@@ -358,60 +205,8 @@ class Timber {
358
  * @param string $TermClass
359
  * @return mixed
360
  */
361
- public static function get_terms($args, $maybe_args = array(), $TermClass = 'TimberTerm'){
362
- if (is_string($maybe_args) && !strstr($maybe_args, '=')){
363
- //the user is sending the $TermClass in the second argument
364
- $TermClass = $maybe_args;
365
- }
366
- if (is_string($maybe_args) && strstr($maybe_args, '=')){
367
- parse_str($maybe_args, $maybe_args);
368
- }
369
- if (is_string($args) && strstr($args, '=')){
370
- //a string and a query string!
371
- $parsed = TimberTermGetter::get_term_query_from_query_string($args);
372
- if (is_array($maybe_args)){
373
- $parsed->args = array_merge($parsed->args, $maybe_args);
374
- }
375
- return self::handle_term_query($parsed->taxonomies, $parsed->args, $TermClass);
376
- } else if (is_string($args)){
377
- //its just a string with a single taxonomy
378
- $parsed = TimberTermGetter::get_term_query_from_string($args);
379
- if (is_array($maybe_args)){
380
- $parsed->args = array_merge($parsed->args, $maybe_args);
381
- }
382
- return self::handle_term_query($parsed->taxonomies, $parsed->args, $TermClass);
383
- } else if (is_array($args) && TimberHelper::is_array_assoc($args)){
384
- //its an associative array, like a good ole query
385
- $parsed = TimberTermGetter::get_term_query_from_assoc_array($args);
386
- return self::handle_term_query($parsed->taxonomies, $parsed->args, $TermClass);
387
- } else if (is_array($args)){
388
- //its just an array of strings or IDs (hopefully)
389
- $parsed = TimberTermGetter::get_term_query_from_array($args);
390
- if (is_array($maybe_args)){
391
- $parsed->args = array_merge($parsed->args, $maybe_args);
392
- }
393
- return self::handle_term_query($parsed->taxonomies, $parsed->args, $TermClass);
394
- } else {
395
- //no clue, what you talkin' bout?
396
- return null;
397
- }
398
- }
399
-
400
- /**
401
- * @param string|array $taxonomies
402
- * @param string|array $args
403
- * @param $TermClass
404
- * @return mixed
405
- */
406
- public static function handle_term_query($taxonomies, $args, $TermClass){
407
- if (!isset($args['hide_empty'])){
408
- $args['hide_empty'] = false;
409
- }
410
- $terms = get_terms($taxonomies, $args);
411
- foreach($terms as &$term){
412
- $term = new $TermClass($term->term_id, $term->taxonomy);
413
- }
414
- return $terms;
415
  }
416
 
417
  /* Site Retrieval
@@ -447,7 +242,7 @@ class Timber {
447
  $data['wp_head'] = TimberHelper::function_wrapper('wp_head');
448
  $data['wp_footer'] = TimberHelper::function_wrapper('wp_footer');
449
  $data['body_class'] = implode(' ', get_body_class());
450
-
451
  $data['site'] = new TimberSite();
452
  $data['theme'] = $data['site']->theme;
453
  //deprecated, these should be fetched via TimberSite or TimberTheme
@@ -455,6 +250,9 @@ class Timber {
455
  $data['language_attributes'] = TimberHelper::function_wrapper('language_attributes');
456
  $data['stylesheet_uri'] = get_stylesheet_uri();
457
  $data['template_uri'] = get_template_directory_uri();
 
 
 
458
  //deprecated, this should be fetched via TimberMenu
459
  if (function_exists('wp_nav_menu')) {
460
  $locations = get_nav_menu_locations();
@@ -601,7 +399,7 @@ class Timber {
601
  /* Routes
602
  ================================ */
603
 
604
- public function init_routes() {
605
  global $timber;
606
  if (isset($timber->router)) {
607
  $route = $timber->router->matchCurrentRequest();
@@ -650,6 +448,13 @@ class Timber {
650
  }
651
  }
652
 
 
 
 
 
 
 
 
653
  /**
654
  * @param array $template
655
  * @param mixed $query
@@ -657,7 +462,7 @@ class Timber {
657
  * @param bool $tparams
658
  * @return bool
659
  */
660
- public static function load_template($template, $query = false, $force_header = 0, $tparams = false) {
661
 
662
  $fullPath = is_readable($template);
663
  if (!$fullPath) {
@@ -765,6 +570,7 @@ class Timber {
765
  /**
766
  * @param int $offset
767
  * @return string
 
768
  */
769
  public static function get_calling_script_path($offset = 0) {
770
  $dir = self::get_calling_script_dir($offset);
@@ -774,6 +580,7 @@ class Timber {
774
  /**
775
  * @param int $offset
776
  * @return string|null
 
777
  */
778
  public static function get_calling_script_dir($offset = 0) {
779
  $caller = null;
@@ -798,21 +605,12 @@ class Timber {
798
  }
799
 
800
  /**
801
- * @param string|array $arg
802
  * @return bool
 
803
  */
804
- public static function is_post_class_or_class_map($arg){
805
- if (is_string($arg) && class_exists($arg)) {
806
- return true;
807
- }
808
- if (is_array($arg)) {
809
- foreach ($arg as $item) {
810
- if (is_string($item) && class_exists($item)) {
811
- return true;
812
- }
813
- }
814
- }
815
- return false;
816
  }
817
 
818
  }
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.0
8
  Author URI: http://upstatement.com/
9
  */
10
 
21
  require_once(__DIR__ . '/functions/timber-url-helper.php');
22
  require_once(__DIR__ . '/functions/timber-image-helper.php');
23
 
24
+ require_once(__DIR__ . '/functions/timber-core-interface.php');
25
  require_once(__DIR__ . '/functions/timber-core.php');
26
  require_once(__DIR__ . '/functions/timber-post.php');
27
+ require_once(__DIR__ . '/functions/timber-post-getter.php');
28
  require_once(__DIR__ . '/functions/timber-comment.php');
29
  require_once(__DIR__ . '/functions/timber-user.php');
30
  require_once(__DIR__ . '/functions/timber-term.php');
31
  require_once(__DIR__ . '/functions/timber-term-getter.php');
32
  require_once(__DIR__ . '/functions/timber-image.php');
33
+ require_once(__DIR__ . '/functions/timber-menu-item.php');
34
  require_once(__DIR__ . '/functions/timber-menu.php');
35
+ require_once(__DIR__ . '/functions/timber-query-iterator.php');
36
+ require_once(__DIR__ . '/functions/timber-posts-collection.php');
37
 
38
  //Other 2nd-class citizens
39
  require_once(__DIR__ . '/functions/timber-archives.php');
40
  require_once(__DIR__ . '/functions/timber-site.php');
41
  require_once(__DIR__ . '/functions/timber-theme.php');
 
 
42
  require_once(__DIR__ . '/functions/timber-loader.php');
43
  require_once(__DIR__ . '/functions/timber-function-wrapper.php');
44
  require_once(__DIR__ . '/functions/integrations/acf-timber.php');
45
+ require_once(__DIR__ . '/functions/integrations/wpcli-timber.php');
 
 
46
 
47
  require_once(__DIR__ . '/functions/timber-admin.php');
48
 
102
  * @return array|bool|null
103
  */
104
  public static function get_post($query = false, $PostClass = 'TimberPost') {
105
+ return TimberPostGetter::get_post($query, $PostClass);
 
 
 
 
 
 
 
 
106
  }
107
 
 
108
  /**
109
  * @param mixed $query
110
  * @param string $PostClass
111
  * @return array|bool|null
112
  */
113
+ public static function get_posts($query = false, $PostClass = 'TimberPost', $return_collection = false ){
114
+ return TimberPostGetter::get_posts($query, $PostClass, $return_collection);
115
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
 
117
+ public static function query_posts($query = false, $PostClass = 'TimberPost') {
118
+ return TimberPostGetter::query_posts( $query, $PostClass );
119
  }
120
 
121
  /**
122
  * @param array|string $query
123
  * @return array
124
+ * @deprecated since 0.20.0
125
  */
126
+ static function get_pids($query = null) {
127
+ return TimberPostGetter::get_pids($query);
 
 
 
 
 
 
 
128
  }
129
 
130
  /**
131
  * @param string $PostClass
132
  * @return array
133
+ * @deprecated since 0.20.0
134
  */
135
+ static function get_posts_from_loop($PostClass) {
136
+ return TimberPostGetter::get_posts($PostClass);
 
 
 
 
 
 
 
 
 
 
 
 
 
137
  }
138
 
139
  /**
140
  * @param string $slug
141
  * @param string $PostClass
142
  * @return array
143
+ * @deprecated since 0.20.0
144
  */
145
+ static function get_posts_from_slug($slug, $PostClass = 'TimberPost') {
146
+ return TimberPostGetter::get_posts($slug, $PostClass);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  }
148
 
149
  /**
150
  * @param array $query
151
  * @param string $PostClass
152
  * @return array
153
+ * @deprecated since 0.20.0
154
  */
155
+ static function get_posts_from_wp_query($query = array(), $PostClass = 'TimberPost') {
156
+ return TimberPostGetter::query_posts($query, $PostClass);
 
157
  }
158
 
159
  /**
160
  * @param array $query
161
  * @param string $PostClass
162
  * @return array|null
163
+ * @deprecated since 0.20.0
164
  */
165
+ static function get_posts_from_array_of_ids($query = array(), $PostClass = 'TimberPost') {
166
+ return TimberPostGetter::get_posts($query, $PostClass);
 
 
 
 
167
  }
168
 
169
  /**
170
  * @param array $results
171
  * @param string $PostClass
172
  * @return array
173
+ * @deprecated since 0.20.0
174
  */
175
+ static function handle_post_results($results, $PostClass = 'TimberPost') {
176
+ return TimberPostGetter::handle_post_results($results, $PostClass);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
  }
178
 
179
  /**
180
  * @param $query
181
+ * @return int
182
+ * @deprecated since 0.20.0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
  */
184
+ static function get_pid($query) {
185
+ $pids = TimberPostGetter::get_pids($query);
186
+ if (is_array($pids) && count($pids)){
187
+ return $pids[0];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
188
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189
  }
190
 
191
  /**
192
+ * @return bool
193
+ * @deprecated since 0.20.0
194
  */
195
+ static function wp_query_has_posts() {
196
+ return TimberPostGetter::wp_query_has_posts();
 
 
 
 
 
 
 
 
 
 
197
  }
198
 
 
199
  /* Term Retrieval
200
  ================================ */
201
 
205
  * @param string $TermClass
206
  * @return mixed
207
  */
208
+ public static function get_terms($args = null, $maybe_args = array(), $TermClass = 'TimberTerm'){
209
+ return TimberTermGetter::get_terms($args, $maybe_args, $TermClass);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
210
  }
211
 
212
  /* Site Retrieval
242
  $data['wp_head'] = TimberHelper::function_wrapper('wp_head');
243
  $data['wp_footer'] = TimberHelper::function_wrapper('wp_footer');
244
  $data['body_class'] = implode(' ', get_body_class());
245
+
246
  $data['site'] = new TimberSite();
247
  $data['theme'] = $data['site']->theme;
248
  //deprecated, these should be fetched via TimberSite or TimberTheme
250
  $data['language_attributes'] = TimberHelper::function_wrapper('language_attributes');
251
  $data['stylesheet_uri'] = get_stylesheet_uri();
252
  $data['template_uri'] = get_template_directory_uri();
253
+
254
+ $data['posts'] = Timber::query_posts();
255
+
256
  //deprecated, this should be fetched via TimberMenu
257
  if (function_exists('wp_nav_menu')) {
258
  $locations = get_nav_menu_locations();
399
  /* Routes
400
  ================================ */
401
 
402
+ function init_routes() {
403
  global $timber;
404
  if (isset($timber->router)) {
405
  $route = $timber->router->matchCurrentRequest();
448
  }
449
  }
450
 
451
+ /**
452
+ * @deprecated since 0.20.0
453
+ */
454
+ public static function load_template($template, $query = false, $force_header = 0, $tparams = false) {
455
+ return self::load_view($template, $query, $force_header, $tparams);
456
+ }
457
+
458
  /**
459
  * @param array $template
460
  * @param mixed $query
462
  * @param bool $tparams
463
  * @return bool
464
  */
465
+ public static function load_view($template, $query = false, $force_header = 0, $tparams = false) {
466
 
467
  $fullPath = is_readable($template);
468
  if (!$fullPath) {
570
  /**
571
  * @param int $offset
572
  * @return string
573
+ * @deprecated since 0.20.0
574
  */
575
  public static function get_calling_script_path($offset = 0) {
576
  $dir = self::get_calling_script_dir($offset);
580
  /**
581
  * @param int $offset
582
  * @return string|null
583
+ * @deprecated since 0.20.0
584
  */
585
  public static function get_calling_script_dir($offset = 0) {
586
  $caller = null;
605
  }
606
 
607
  /**
608
+ * @param string|array $args
609
  * @return bool
610
+ * @deprecated since 0.20.0
611
  */
612
+ public static function is_post_class_or_class_map($args){
613
+ return TimberPostGetter::is_post_class_or_class_map($args);
 
 
 
 
 
 
 
 
 
 
614
  }
615
 
616
  }
vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer' . '/autoload_real.php';
6
 
7
- return ComposerAutoloaderInitcef0c697444c47de03b382b296ede9e7::getLoader();
4
 
5
  require_once __DIR__ . '/composer' . '/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInite11ef494ebf2265b4e63668ffb2128bf::getLoader();
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInitcef0c697444c47de03b382b296ede9e7
6
  {
7
  private static $loader;
8
 
@@ -19,9 +19,9 @@ class ComposerAutoloaderInitcef0c697444c47de03b382b296ede9e7
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInitcef0c697444c47de03b382b296ede9e7', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInitcef0c697444c47de03b382b296ede9e7', 'loadClassLoader'));
25
 
26
  $vendorDir = dirname(__DIR__);
27
  $baseDir = dirname($vendorDir);
@@ -47,7 +47,7 @@ class ComposerAutoloaderInitcef0c697444c47de03b382b296ede9e7
47
  }
48
  }
49
 
50
- function composerRequirecef0c697444c47de03b382b296ede9e7($file)
51
  {
52
  require $file;
53
  }
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInite11ef494ebf2265b4e63668ffb2128bf
6
  {
7
  private static $loader;
8
 
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInite11ef494ebf2265b4e63668ffb2128bf', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInite11ef494ebf2265b4e63668ffb2128bf', 'loadClassLoader'));
25
 
26
  $vendorDir = dirname(__DIR__);
27
  $baseDir = dirname($vendorDir);
47
  }
48
  }
49
 
50
+ function composerRequiree11ef494ebf2265b4e63668ffb2128bf($file)
51
  {
52
  require $file;
53
  }
vendor/composer/installed.json CHANGED
@@ -1,27 +1,28 @@
1
  [
2
  {
3
  "name": "composer/installers",
4
- "version": "v1.0.13",
5
- "version_normalized": "1.0.13.0",
6
  "source": {
7
  "type": "git",
8
  "url": "https://github.com/composer/installers.git",
9
- "reference": "26d37e307f9aa6e2e81806a6525666f8ab5ba0ff"
10
  },
11
  "dist": {
12
  "type": "zip",
13
- "url": "https://api.github.com/repos/composer/installers/zipball/26d37e307f9aa6e2e81806a6525666f8ab5ba0ff",
14
- "reference": "26d37e307f9aa6e2e81806a6525666f8ab5ba0ff",
15
  "shasum": ""
16
  },
17
  "replace": {
 
18
  "shama/baton": "*"
19
  },
20
  "require-dev": {
21
  "composer/composer": "1.0.*@dev",
22
- "phpunit/phpunit": "3.7.*"
23
  },
24
- "time": "2014-04-09 16:12:43",
25
  "type": "composer-installer",
26
  "extra": {
27
  "class": "Composer\\Installers\\Installer",
@@ -51,12 +52,14 @@
51
  "homepage": "http://composer.github.com/installers/",
52
  "keywords": [
53
  "Craft",
 
54
  "Hurad",
55
  "MODX Evo",
56
  "OXID",
57
  "WolfCMS",
58
  "agl",
59
  "annotatecms",
 
60
  "cakephp",
61
  "codeigniter",
62
  "concrete5",
@@ -73,9 +76,11 @@
73
  "mako",
74
  "mediawiki",
75
  "modulework",
 
76
  "phpbb",
77
  "piwik",
78
  "ppi",
 
79
  "shopware",
80
  "silverstripe",
81
  "symfony",
@@ -200,28 +205,28 @@
200
  },
201
  {
202
  "name": "symfony/yaml",
203
- "version": "v2.4.5",
204
- "version_normalized": "2.4.5.0",
205
  "target-dir": "Symfony/Component/Yaml",
206
  "source": {
207
  "type": "git",
208
  "url": "https://github.com/symfony/Yaml.git",
209
- "reference": "fd22bb88c3a6f73c898b39bec185a9e211b06265"
210
  },
211
  "dist": {
212
  "type": "zip",
213
- "url": "https://api.github.com/repos/symfony/Yaml/zipball/fd22bb88c3a6f73c898b39bec185a9e211b06265",
214
- "reference": "fd22bb88c3a6f73c898b39bec185a9e211b06265",
215
  "shasum": ""
216
  },
217
  "require": {
218
  "php": ">=5.3.3"
219
  },
220
- "time": "2014-05-12 09:27:48",
221
  "type": "library",
222
  "extra": {
223
  "branch-alias": {
224
- "dev-master": "2.4-dev"
225
  }
226
  },
227
  "installation-source": "dist",
1
  [
2
  {
3
  "name": "composer/installers",
4
+ "version": "v1.0.15",
5
+ "version_normalized": "1.0.15.0",
6
  "source": {
7
  "type": "git",
8
  "url": "https://github.com/composer/installers.git",
9
+ "reference": "8e6a72a78f6cfd537fde3350720dfdc9ae3c5621"
10
  },
11
  "dist": {
12
  "type": "zip",
13
+ "url": "https://api.github.com/repos/composer/installers/zipball/8e6a72a78f6cfd537fde3350720dfdc9ae3c5621",
14
+ "reference": "8e6a72a78f6cfd537fde3350720dfdc9ae3c5621",
15
  "shasum": ""
16
  },
17
  "replace": {
18
+ "roundcube/plugin-installer": "*",
19
  "shama/baton": "*"
20
  },
21
  "require-dev": {
22
  "composer/composer": "1.0.*@dev",
23
+ "phpunit/phpunit": "4.1.*"
24
  },
25
+ "time": "2014-06-23 16:25:28",
26
  "type": "composer-installer",
27
  "extra": {
28
  "class": "Composer\\Installers\\Installer",
52
  "homepage": "http://composer.github.com/installers/",
53
  "keywords": [
54
  "Craft",
55
+ "Dolibarr",
56
  "Hurad",
57
  "MODX Evo",
58
  "OXID",
59
  "WolfCMS",
60
  "agl",
61
  "annotatecms",
62
+ "bitrix",
63
  "cakephp",
64
  "codeigniter",
65
  "concrete5",
76
  "mako",
77
  "mediawiki",
78
  "modulework",
79
+ "moodle",
80
  "phpbb",
81
  "piwik",
82
  "ppi",
83
+ "roundcube",
84
  "shopware",
85
  "silverstripe",
86
  "symfony",
205
  },
206
  {
207
  "name": "symfony/yaml",
208
+ "version": "v2.5.0",
209
+ "version_normalized": "2.5.0.0",
210
  "target-dir": "Symfony/Component/Yaml",
211
  "source": {
212
  "type": "git",
213
  "url": "https://github.com/symfony/Yaml.git",
214
+ "reference": "b4b09c68ec2f2727574544ef0173684281a5033c"
215
  },
216
  "dist": {
217
  "type": "zip",
218
+ "url": "https://api.github.com/repos/symfony/Yaml/zipball/b4b09c68ec2f2727574544ef0173684281a5033c",
219
+ "reference": "b4b09c68ec2f2727574544ef0173684281a5033c",
220
  "shasum": ""
221
  },
222
  "require": {
223
  "php": ">=5.3.3"
224
  },
225
+ "time": "2014-05-16 14:25:18",
226
  "type": "library",
227
  "extra": {
228
  "branch-alias": {
229
+ "dev-master": "2.5-dev"
230
  }
231
  },
232
  "installation-source": "dist",
vendor/composer/installers/.gitignore CHANGED
@@ -1,3 +1,3 @@
1
  vendor/
2
  composer.lock
3
- .idea/
1
  vendor/
2
  composer.lock
3
+ .idea/
vendor/composer/installers/README.md CHANGED
@@ -35,11 +35,13 @@ is not needed to install packages with these frameworks:
35
  | --------- | -----
36
  | AGL | `agl-module`
37
  | AnnotateCms | `annotatecms-module`<br>`annotatecms-component`<br>`annotatecms-service`
 
38
  | CakePHP 2+ | **`cakephp-plugin`**
39
  | CodeIgniter | `codeigniter-library`<br>`codeigniter-third-party`<br>`codeigniter-module`
40
  | concrete5 | `concrete5-block`<br>`concrete5-package`<br>`concrete5-theme`<br>`concrete5-update`
41
  | Craft | `craft-plugin`
42
  | Croogo | `croogo-plugin`<br>`croogo-theme`
 
43
  | Drupal | <b>`drupal-module`<br>`drupal-theme`</b><br>`drupal-library`<br>`drupal-profile`<br>`drupal-drush`
44
  | Elgg | `elgg-plugin`
45
  | FuelPHP v1.x | `fuel-module`<br>`fuel-package`<br/>`fuel-theme`
@@ -56,12 +58,16 @@ is not needed to install packages with these frameworks:
56
  | October | **`october-module`<br>`october-plugin`**
57
  | OXID | `oxid-module`<br>`oxid-theme`<br>`oxid-out`
58
  | MODULEWork | `modulework-module`
 
59
  | Piwik | `piwik-plugin`
60
  | phpBB | `phpbb-extension`<br>`phpbb-style`<br>`phpbb-language`
 
61
  | PPI | **`ppi-module`**
 
62
  | shopware | `shopware-backend-plugin`<br/>`shopware-core-plugin`<br/>`shopware-frontend-plugin`<br/>`shopware-theme`
63
  | SilverStripe | `silverstripe-module`<br>`silverstripe-theme`
64
  | symfony1 | **`symfony1-plugin`**
 
65
  | TYPO3 Flow | `typo3-flow-package`<br>`typo3-flow-framework`<br>`typo3-flow-plugin`<br>`typo3-flow-site`<br>`typo3-flow-boilerplate`<br>`typo3-flow-build`
66
  | TYPO3 CMS | `typo3-cms-extension`
67
  | Wolf CMS | `wolfcms-plugin`
35
  | --------- | -----
36
  | AGL | `agl-module`
37
  | AnnotateCms | `annotatecms-module`<br>`annotatecms-component`<br>`annotatecms-service`
38
+ | Bitrix | `bitrix-module`<br>`bitrix-component`
39
  | CakePHP 2+ | **`cakephp-plugin`**
40
  | CodeIgniter | `codeigniter-library`<br>`codeigniter-third-party`<br>`codeigniter-module`
41
  | concrete5 | `concrete5-block`<br>`concrete5-package`<br>`concrete5-theme`<br>`concrete5-update`
42
  | Craft | `craft-plugin`
43
  | Croogo | `croogo-plugin`<br>`croogo-theme`
44
+ | Dolibarr | `dolibarr-module`
45
  | Drupal | <b>`drupal-module`<br>`drupal-theme`</b><br>`drupal-library`<br>`drupal-profile`<br>`drupal-drush`
46
  | Elgg | `elgg-plugin`
47
  | FuelPHP v1.x | `fuel-module`<br>`fuel-package`<br/>`fuel-theme`
58
  | October | **`october-module`<br>`october-plugin`**
59
  | OXID | `oxid-module`<br>`oxid-theme`<br>`oxid-out`
60
  | MODULEWork | `modulework-module`
61
+ | Moodle | `moodle-*` (Please [check source](https://raw.githubusercontent.com/composer/installers/master/src/Composer/Installers/MoodleInstaller.php) for all supported types)
62
  | Piwik | `piwik-plugin`
63
  | phpBB | `phpbb-extension`<br>`phpbb-style`<br>`phpbb-language`
64
+ | Pimcore | `pimcore-plugin`
65
  | PPI | **`ppi-module`**
66
+ | Roundcube | `roundcube-plugin`
67
  | shopware | `shopware-backend-plugin`<br/>`shopware-core-plugin`<br/>`shopware-frontend-plugin`<br/>`shopware-theme`
68
  | SilverStripe | `silverstripe-module`<br>`silverstripe-theme`
69
  | symfony1 | **`symfony1-plugin`**
70
+ | Tusk | `tusk-task`<br>`tusk-command`<br>`tusk-asset`
71
  | TYPO3 Flow | `typo3-flow-package`<br>`typo3-flow-framework`<br>`typo3-flow-plugin`<br>`typo3-flow-site`<br>`typo3-flow-boilerplate`<br>`typo3-flow-build`
72
  | TYPO3 CMS | `typo3-cms-extension`
73
  | Wolf CMS | `wolfcms-plugin`
vendor/composer/installers/composer.json CHANGED
@@ -7,11 +7,13 @@
7
  "installer",
8
  "AGL",
9
  "AnnotateCms",
 
10
  "CakePHP",
11
  "CodeIgniter",
12
  "concrete5",
13
  "Craft",
14
  "Croogo",
 
15
  "Drupal",
16
  "Elgg",
17
  "FuelPHP",
@@ -26,9 +28,11 @@
26
  "MediaWiki",
27
  "OXID",
28
  "MODULEWork",
 
29
  "Piwik",
30
  "phpBB",
31
  "PPI",
 
32
  "shopware",
33
  "SilverStripe",
34
  "symfony",
@@ -56,10 +60,11 @@
56
  }
57
  },
58
  "replace": {
59
- "shama/baton": "*"
 
60
  },
61
  "require-dev": {
62
  "composer/composer": "1.0.*@dev",
63
- "phpunit/phpunit": "3.7.*"
64
  }
65
  }
7
  "installer",
8
  "AGL",
9
  "AnnotateCms",
10
+ "Bitrix",
11
  "CakePHP",
12
  "CodeIgniter",
13
  "concrete5",
14
  "Craft",
15
  "Croogo",
16
+ "Dolibarr",
17
  "Drupal",
18
  "Elgg",
19
  "FuelPHP",
28
  "MediaWiki",
29
  "OXID",
30
  "MODULEWork",
31
+ "Moodle",
32
  "Piwik",
33
  "phpBB",
34
  "PPI",
35
+ "Roundcube",
36
  "shopware",
37
  "SilverStripe",
38
  "symfony",
60
  }
61
  },
62
  "replace": {
63
+ "shama/baton": "*",
64
+ "roundcube/plugin-installer": "*"
65
  },
66
  "require-dev": {
67
  "composer/composer": "1.0.*@dev",
68
+ "phpunit/phpunit": "4.1.*"
69
  }
70
  }
vendor/composer/installers/src/Composer/Installers/AglInstaller.php CHANGED
@@ -12,7 +12,7 @@ class AglInstaller extends BaseInstaller
12
  */
13
  public function inflectPackageVars($vars)
14
  {
15
- $vars['name'] = preg_replace_callback('/(?:^|_|-)(.?)/', function($matches) {
16
  return strtoupper($matches[1]);
17
  }, $vars['name']);
18
 
12
  */
13
  public function inflectPackageVars($vars)
14
  {
15
+ $vars['name'] = preg_replace_callback('/(?:^|_|-)(.?)/', function ($matches) {
16
  return strtoupper($matches[1]);
17
  }, $vars['name']);
18
 
vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php CHANGED
@@ -8,4 +8,4 @@ class AnnotateCmsInstaller extends BaseInstaller
8
  'component' => 'addons/components/{$name}/',
9
  'service' => 'addons/services/{$name}/',
10
  );
11
- }
8
  'component' => 'addons/components/{$name}/',
9
  'service' => 'addons/services/{$name}/',
10
  );
11
+ }
vendor/composer/installers/src/Composer/Installers/BaseInstaller.php CHANGED
@@ -59,11 +59,12 @@ abstract class BaseInstaller
59
  }
60
 
61
  $packageType = substr($type, strlen($frameworkType) + 1);
62
- if (!isset($this->locations[$packageType])) {
 
63
  throw new \InvalidArgumentException(sprintf('Package type "%s" is not supported', $type));
64
  }
65
 
66
- return $this->templatePath($this->locations[$packageType], $availableVars);
67
  }
68
 
69
  /**
59
  }
60
 
61
  $packageType = substr($type, strlen($frameworkType) + 1);
62
+ $locations = $this->getLocations();
63
+ if (!isset($locations[$packageType])) {
64
  throw new \InvalidArgumentException(sprintf('Package type "%s" is not supported', $type));
65
  }
66
 
67
+ return $this->templatePath($locations[$packageType], $availableVars);
68
  }
69
 
70
  /**
vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class BitrixInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'local/modules/{$name}/',
8
+ 'component' => 'local/components/{$name}/',
9
+ );
10
+ }
vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php CHANGED
@@ -1,6 +1,11 @@
1
  <?php
2
  namespace Composer\Installers;
3
 
 
 
 
 
 
4
  class CakePHPInstaller extends BaseInstaller
5
  {
6
  protected $locations = array(
@@ -12,10 +17,42 @@ class CakePHPInstaller extends BaseInstaller
12
  */
13
  public function inflectPackageVars($vars)
14
  {
15
- $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
16
- $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
17
- $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
 
 
 
 
18
 
19
  return $vars;
20
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  }
1
  <?php
2
  namespace Composer\Installers;
3
 
4
+ use Composer\DependencyResolver\Pool;
5
+ use Composer\Package\PackageInterface;
6
+ use Composer\Package\LinkConstraint\MultiConstraint;
7
+ use Composer\Package\LinkConstraint\VersionConstraint;
8
+
9
  class CakePHPInstaller extends BaseInstaller
10
  {
11
  protected $locations = array(
17
  */
18
  public function inflectPackageVars($vars)
19
  {
20
+ $nameParts = explode('/', $vars['name']);
21
+ foreach ($nameParts as &$value) {
22
+ $value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value));
23
+ $value = str_replace(array('-', '_'), ' ', $value);
24
+ $value = str_replace(' ', '', ucwords($value));
25
+ }
26
+ $vars['name'] = implode('/', $nameParts);
27
 
28
  return $vars;
29
  }
30
+
31
+ /**
32
+ * Change the default plugin location when cakephp >= 3.0
33
+ */
34
+ public function getLocations() {
35
+ $repositoryManager = $this->composer->getRepositoryManager();
36
+ if ($repositoryManager) {
37
+ $repos = $repositoryManager->getLocalRepository();
38
+ if (!$repos) {
39
+ return $this->locations;
40
+ }
41
+ $cake3 = new MultiConstraint(array(
42
+ new VersionConstraint('>=', '3.0.0'),
43
+ new VersionConstraint('!=', '9999999-dev'),
44
+ ));
45
+ $pool = new Pool('dev');
46
+ $pool->addRepository($repos);
47
+ $packages = $pool->whatProvides('cakephp/cakephp');
48
+ foreach ($packages as $package) {
49
+ $installed = new VersionConstraint('=', $package->getVersion());
50
+ if ($cake3->matches($installed)) {
51
+ $this->locations['plugin'] = 'plugins/{$name}/';
52
+ break;
53
+ }
54
+ }
55
+ }
56
+ return $this->locations;
57
+ }
58
  }
vendor/composer/installers/src/Composer/Installers/CraftInstaller.php CHANGED
@@ -6,4 +6,4 @@ class CraftInstaller extends BaseInstaller
6
  protected $locations = array(
7
  'plugin' => 'craft/plugins/{$name}/',
8
  );
9
- }
6
  protected $locations = array(
7
  'plugin' => 'craft/plugins/{$name}/',
8
  );
9
+ }
vendor/composer/installers/src/Composer/Installers/DolibarrInstaller.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ /**
5
+ * Class DolibarrInstaller
6
+ *
7
+ * @package Composer\Installers
8
+ * @author Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
9
+ */
10
+ class DolibarrInstaller extends BaseInstaller
11
+ {
12
+ //TODO: Add support for scripts and themes
13
+ protected $locations = array(
14
+ 'module' => 'htdocs/custom/{$name}/',
15
+ );
16
+ }
vendor/composer/installers/src/Composer/Installers/Installer.php CHANGED
@@ -15,12 +15,14 @@ class Installer extends LibraryInstaller
15
  private $supportedTypes = array(
16
  'agl' => 'AglInstaller',
17
  'annotatecms' => 'AnnotateCmsInstaller',
 
18
  'cakephp' => 'CakePHPInstaller',
19
  'codeigniter' => 'CodeIgniterInstaller',
20
  'concrete5' => 'Concrete5Installer',
21
  'craft' => 'CraftInstaller',
22
  'croogo' => 'CroogoInstaller',
23
  'drupal' => 'DrupalInstaller',
 
24
  'elgg' => 'ElggInstaller',
25
  'piwik' => 'PiwikInstaller',
26
  'fuel' => 'FuelInstaller',
@@ -34,12 +36,16 @@ class Installer extends LibraryInstaller
34
  'mako' => 'MakoInstaller',
35
  'modxevo' => 'MODXEvoInstaller',
36
  'mediawiki' => 'MediaWikiInstaller',
 
37
  'modulework' => 'MODULEWorkInstaller',
 
38
  'october' => 'OctoberInstaller',
39
  'oxid' => 'OxidInstaller',
40
  'phpbb' => 'PhpBBInstaller',
41
  'piwik' => 'PiwikInstaller',
 
42
  'ppi' => 'PPIInstaller',
 
43
  'shopware' => 'ShopwareInstaller',
44
  'silverstripe' => 'SilverStripeInstaller',
45
  'symfony1' => 'Symfony1Installer',
@@ -49,6 +55,7 @@ class Installer extends LibraryInstaller
49
  'zikula' => 'ZikulaInstaller',
50
  'typo3-flow' => 'TYPO3FlowInstaller',
51
  'typo3-cms' => 'TYPO3CmsInstaller',
 
52
  );
53
 
54
  /**
@@ -95,6 +102,7 @@ class Installer extends LibraryInstaller
95
  }
96
 
97
  $locationPattern = $this->getLocationPattern($frameworkType);
 
98
  return preg_match('#' . $frameworkType . '-' . $locationPattern . '#', $packageType, $matches) === 1;
99
  }
100
 
@@ -131,10 +139,11 @@ class Installer extends LibraryInstaller
131
  if (!empty($this->supportedTypes[$frameworkType])) {
132
  $frameworkClass = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType];
133
  /** @var BaseInstaller $framework */
134
- $framework = new $frameworkClass;
135
  $locations = array_keys($framework->getLocations());
136
  $pattern = $locations ? '(' . implode('|', $locations) . ')' : false;
137
  }
 
138
  return $pattern ? : '(\w+)';
139
  }
140
  }
15
  private $supportedTypes = array(
16
  'agl' => 'AglInstaller',
17
  'annotatecms' => 'AnnotateCmsInstaller',
18
+ 'bitrix' => 'BitrixInstaller',
19
  'cakephp' => 'CakePHPInstaller',
20
  'codeigniter' => 'CodeIgniterInstaller',
21
  'concrete5' => 'Concrete5Installer',
22
  'craft' => 'CraftInstaller',
23
  'croogo' => 'CroogoInstaller',
24
  'drupal' => 'DrupalInstaller',
25
+ 'dolibarr' => 'DolibarrInstaller',
26
  'elgg' => 'ElggInstaller',
27
  'piwik' => 'PiwikInstaller',
28
  'fuel' => 'FuelInstaller',
36
  'mako' => 'MakoInstaller',
37
  'modxevo' => 'MODXEvoInstaller',
38
  'mediawiki' => 'MediaWikiInstaller',
39
+ 'microweber' => 'MicroweberInstaller',
40
  'modulework' => 'MODULEWorkInstaller',
41
+ 'moodle' => 'MoodleInstaller',
42
  'october' => 'OctoberInstaller',
43
  'oxid' => 'OxidInstaller',
44
  'phpbb' => 'PhpBBInstaller',
45
  'piwik' => 'PiwikInstaller',
46
+ 'pimcore' => 'PimcoreInstaller',
47
  'ppi' => 'PPIInstaller',
48
+ 'roundcube' => 'RoundcubeInstaller',
49
  'shopware' => 'ShopwareInstaller',
50
  'silverstripe' => 'SilverStripeInstaller',
51
  'symfony1' => 'Symfony1Installer',
55
  'zikula' => 'ZikulaInstaller',
56
  'typo3-flow' => 'TYPO3FlowInstaller',
57
  'typo3-cms' => 'TYPO3CmsInstaller',
58
+ 'tusk' => 'TuskInstaller',
59
  );
60
 
61
  /**
102
  }
103
 
104
  $locationPattern = $this->getLocationPattern($frameworkType);
105
+
106
  return preg_match('#' . $frameworkType . '-' . $locationPattern . '#', $packageType, $matches) === 1;
107
  }
108
 
139
  if (!empty($this->supportedTypes[$frameworkType])) {
140
  $frameworkClass = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType];
141
  /** @var BaseInstaller $framework */
142
+ $framework = new $frameworkClass(null, $this->composer);
143
  $locations = array_keys($framework->getLocations());
144
  $pattern = $locations ? '(' . implode('|', $locations) . ')' : false;
145
  }
146
+
147
  return $pattern ? : '(\w+)';
148
  }
149
  }
vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php CHANGED
@@ -36,12 +36,14 @@ class MediaWikiInstaller extends BaseInstaller
36
  $vars['name'] = preg_replace('/-extension$/', '', $vars['name']);
37
  $vars['name'] = str_replace('-', ' ', $vars['name']);
38
  $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
 
39
  return $vars;
40
  }
41
 
42
  protected function inflectSkinVars($vars)
43
  {
44
  $vars['name'] = preg_replace('/-skin$/', '', $vars['name']);
 
45
  return $vars;
46
  }
47
 
36
  $vars['name'] = preg_replace('/-extension$/', '', $vars['name']);
37
  $vars['name'] = str_replace('-', ' ', $vars['name']);
38
  $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
39
+
40
  return $vars;
41
  }
42
 
43
  protected function inflectSkinVars($vars)
44
  {
45
  $vars['name'] = preg_replace('/-skin$/', '', $vars['name']);
46
+
47
  return $vars;
48
  }
49
 
vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class MicroweberInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'userfiles/modules/{$name}/',
8
+ 'module-skin' => 'userfiles/modules/{$name}/templates/',
9
+ 'template' => 'userfiles/templates/{$name}/',
10
+ 'element' => 'userfiles/elements/{$name}/',
11
+ 'vendor' => 'vendor/{$name}/',
12
+ 'components' => 'components/{$name}/'
13
+ );
14
+
15
+ /**
16
+ * Format package name.
17
+ *
18
+ * For package type microweber-module, cut off a trailing '-module' if present
19
+ *
20
+ * For package type microweber-template, cut off a trailing '-template' if present.
21
+ *
22
+ */
23
+ public function inflectPackageVars($vars)
24
+ {
25
+ if ($vars['type'] === 'microweber-template') {
26
+ return $this->inflectTemplateVars($vars);
27
+ }
28
+ if ($vars['type'] === 'microweber-templates') {
29
+ return $this->inflectTemplatesVars($vars);
30
+ }
31
+ if ($vars['type'] === 'microweber-core') {
32
+ return $this->inflectCoreVars($vars);
33
+ }
34
+ if ($vars['type'] === 'microweber-adapter') {
35
+ return $this->inflectCoreVars($vars);
36
+ }
37
+ if ($vars['type'] === 'microweber-module') {
38
+ return $this->inflectModuleVars($vars);
39
+ }
40
+ if ($vars['type'] === 'microweber-modules') {
41
+ return $this->inflectModulesVars($vars);
42
+ }
43
+ if ($vars['type'] === 'microweber-skin') {
44
+ return $this->inflectSkinVars($vars);
45
+ }
46
+ if ($vars['type'] === 'microweber-element' or $vars['type'] === 'microweber-elements') {
47
+ return $this->inflectElementVars($vars);
48
+ }
49
+
50
+ return $vars;
51
+ }
52
+
53
+ protected function inflectTemplateVars($vars)
54
+ {
55
+ $vars['name'] = preg_replace('/-template$/', '', $vars['name']);
56
+ $vars['name'] = preg_replace('/template-$/', '', $vars['name']);
57
+
58
+ return $vars;
59
+ }
60
+
61
+ protected function inflectTemplatesVars($vars)
62
+ {
63
+ $vars['name'] = preg_replace('/-templates$/', '', $vars['name']);
64
+ $vars['name'] = preg_replace('/templates-$/', '', $vars['name']);
65
+
66
+ return $vars;
67
+ }
68
+
69
+ protected function inflectCoreVars($vars)
70
+ {
71
+ $vars['name'] = preg_replace('/-providers$/', '', $vars['name']);
72
+ $vars['name'] = preg_replace('/-provider$/', '', $vars['name']);
73
+ $vars['name'] = preg_replace('/-adapter$/', '', $vars['name']);
74
+
75
+ return $vars;
76
+ }
77
+
78
+ protected function inflectModuleVars($vars)
79
+ {
80
+ $vars['name'] = preg_replace('/-module$/', '', $vars['name']);
81
+ $vars['name'] = preg_replace('/module-$/', '', $vars['name']);
82
+
83
+ return $vars;
84
+ }
85
+
86
+ protected function inflectModulesVars($vars)
87
+ {
88
+ $vars['name'] = preg_replace('/-modules$/', '', $vars['name']);
89
+ $vars['name'] = preg_replace('/modules-$/', '', $vars['name']);
90
+
91
+ return $vars;
92
+ }
93
+
94
+ protected function inflectSkinVars($vars)
95
+ {
96
+ $vars['name'] = preg_replace('/-skin$/', '', $vars['name']);
97
+ $vars['name'] = preg_replace('/skin-$/', '', $vars['name']);
98
+
99
+ return $vars;
100
+ }
101
+
102
+ protected function inflectElementVars($vars)
103
+ {
104
+ $vars['name'] = preg_replace('/-elements$/', '', $vars['name']);
105
+ $vars['name'] = preg_replace('/elements-$/', '', $vars['name']);
106
+ $vars['name'] = preg_replace('/-element$/', '', $vars['name']);
107
+ $vars['name'] = preg_replace('/element-$/', '', $vars['name']);
108
+
109
+ return $vars;
110
+ }
111
+ }
vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class MoodleInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'mod' => 'mod/{$name}/',
8
+ 'report' => 'admin/report/{$name}/',
9
+ 'tool' => 'admin/tool/{$name}/',
10
+ 'assignment' => 'mod/assignment/type/{$name}/',
11
+ 'assignsubmission' => 'mod/assign/submission/{$name}/',
12
+ 'assignfeedback' => 'mod/assign/feedback/{$name}/',
13
+ 'auth' => 'auth/{$name}/',
14
+ 'availability' => 'availability/condition/{$name}/',
15
+ 'block' => 'blocks/{$name}/',
16
+ 'calendartype' => 'calendar/type/{$name}/',
17
+ 'format' => 'course/format/{$name}/',
18
+ 'coursereport' => 'course/report/{$name}/',
19
+ 'datafield' => 'mod/data/field/{$name}/',
20
+ 'datapreset' => 'mod/data/preset/{$name}/',
21
+ 'editor' => 'lib/editor/{$name}/',
22
+ 'enrol' => 'enrol/{$name}/',
23
+ 'filter' => 'filter/{$name}/',
24
+ 'gradeexport' => 'grade/export/{$name}/',
25
+ 'gradeimport' => 'grade/import/{$name}/',
26
+ 'gradereport' => 'grade/report/{$name}/',
27
+ 'gradingform' => 'grade/grading/form/{$name}/',
28
+ 'local' => 'local/{$name}/',
29
+ 'message' => 'message/output/{$name}/',
30
+ 'plagiarism' => 'plagiarism/{$name}/',
31
+ 'portfolio' => 'portfolio/{$name}/',
32
+ 'qbehaviour' => 'question/behaviour/{$name}/',
33
+ 'qformat' => 'question/format/{$name}/',
34
+ 'qtype' => 'question/type/{$name}/',
35
+ 'quizaccess' => 'mod/quiz/accessrule/{$name}/',
36
+ 'quiz' => 'mod/quiz/report/{$name}/',
37
+ 'report' => 'report/{$name}/',
38
+ 'repository' => 'repository/{$name}/',
39
+ 'scormreport' => 'mod/scorm/report/{$name}/',
40
+ 'theme' => 'theme/{$name}/',
41
+ 'profilefield' => 'user/profile/field/{$name}/',
42
+ 'webservice' => 'webservice/{$name}/',
43
+ 'workshopallocation' => 'mod/workshop/allocation/{$name}/',
44
+ 'workshopeval' => 'mod/workshop/eval/{$name}/',
45
+ 'workshopform' => 'mod/workshop/form/{$name}/'
46
+ );
47
+ }
vendor/composer/installers/src/Composer/Installers/PimcoreInstaller.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class PimcoreInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'plugin' => 'plugins/{$name}/',
8
+ );
9
+
10
+ /**
11
+ * Format package name to CamelCase
12
+ */
13
+ public function inflectPackageVars($vars)
14
+ {
15
+ $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
16
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
17
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
18
+
19
+ return $vars;
20
+ }
21
+ }
vendor/composer/installers/src/Composer/Installers/RoundcubeInstaller.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class RoundcubeInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'plugin' => 'plugins/{$name}/',
8
+ );
9
+
10
+ /**
11
+ * Lowercase name and changes the name to a underscores
12
+ *
13
+ * @param array $vars
14
+ * @return array
15
+ */
16
+ public function inflectPackageVars($vars)
17
+ {
18
+ $vars['name'] = strtolower(str_replace('-', '_', $vars['name']));
19
+
20
+ return $vars;
21
+ }
22
+ }
vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php CHANGED
@@ -16,12 +16,12 @@ class ShopwareInstaller extends BaseInstaller
16
 
17
  /**
18
  * Transforms the names
19
- * @param array $vars
20
  * @return array
21
  */
22
  public function inflectPackageVars($vars)
23
  {
24
- if($vars['type'] === 'shopware-theme') {
25
  return $this->correctThemeName($vars);
26
  } else {
27
  return $this->correctPluginName($vars);
@@ -30,7 +30,7 @@ class ShopwareInstaller extends BaseInstaller
30
 
31
  /**
32
  * Changes the name to a camelcased combination of vendor and name
33
- * @param array $vars
34
  * @return array
35
  */
36
  private function correctPluginName($vars)
@@ -46,7 +46,7 @@ class ShopwareInstaller extends BaseInstaller
46
 
47
  /**
48
  * Changes the name to a underscore separated name
49
- * @param array $vars
50
  * @return array
51
  */
52
  private function correctThemeName($vars)
16
 
17
  /**
18
  * Transforms the names
19
+ * @param array $vars
20
  * @return array
21
  */
22
  public function inflectPackageVars($vars)
23
  {
24
+ if ($vars['type'] === 'shopware-theme') {
25
  return $this->correctThemeName($vars);
26
  } else {
27
  return $this->correctPluginName($vars);
30
 
31
  /**
32
  * Changes the name to a camelcased combination of vendor and name
33
+ * @param array $vars
34
  * @return array
35
  */
36
  private function correctPluginName($vars)
46
 
47
  /**
48
  * Changes the name to a underscore separated name
49
+ * @param array $vars
50
  * @return array
51
  */
52
  private function correctThemeName($vars)
vendor/composer/installers/src/Composer/Installers/SilverStripeInstaller.php CHANGED
@@ -23,8 +23,8 @@ class SilverStripeInstaller extends BaseInstaller
23
  public function getInstallPath(PackageInterface $package, $frameworkType = '')
24
  {
25
  if (
26
- $package->getName() == 'silverstripe/framework'
27
- && preg_match('/^\d+\.\d+\.\d+/', $package->getVersion())
28
  && version_compare($package->getVersion(), '2.999.999') < 0
29
  ) {
30
  return $this->templatePath($this->locations['module'], array('name' => 'sapphire'));
23
  public function getInstallPath(PackageInterface $package, $frameworkType = '')
24
  {
25
  if (
26
+ $package->getName() == 'silverstripe/framework'
27
+ && preg_match('/^\d+\.\d+\.\d+/', $package->getVersion())
28
  && version_compare($package->getVersion(), '2.999.999') < 0
29
  ) {
30
  return $this->templatePath($this->locations['module'], array('name' => 'sapphire'));
vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php CHANGED
@@ -6,9 +6,9 @@ namespace Composer\Installers;
6
  *
7
  * @author Sascha Egerer <sascha.egerer@dkd.de>
8
  */
9
- class TYPO3CmsInstaller extends BaseInstaller
10
  {
11
  protected $locations = array(
12
  'extension' => 'typo3conf/ext/{$name}/',
13
  );
14
- }
6
  *
7
  * @author Sascha Egerer <sascha.egerer@dkd.de>
8
  */
9
+ class TYPO3CmsInstaller extends BaseInstaller
10
  {
11
  protected $locations = array(
12
  'extension' => 'typo3conf/ext/{$name}/',
13
  );
14
+ }
vendor/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php CHANGED
@@ -18,7 +18,7 @@ class TYPO3FlowInstaller extends BaseInstaller
18
  /**
19
  * Modify the package name to be a TYPO3 Flow style key.
20
  *
21
- * @param array $vars
22
  * @return array
23
  */
24
  public function inflectPackageVars($vars)
@@ -32,6 +32,7 @@ class TYPO3FlowInstaller extends BaseInstaller
32
  $namespace = key($autoload['psr-4']);
33
  $vars['name'] = rtrim(str_replace('\\', '.', $namespace), '.');
34
  }
 
35
  return $vars;
36
  }
37
  }
18
  /**
19
  * Modify the package name to be a TYPO3 Flow style key.
20
  *
21
+ * @param array $vars
22
  * @return array
23
  */
24
  public function inflectPackageVars($vars)
32
  $namespace = key($autoload['psr-4']);
33
  $vars['name'] = rtrim(str_replace('\\', '.', $namespace), '.');
34
  }
35
+
36
  return $vars;
37
  }
38
  }
vendor/composer/installers/src/Composer/Installers/TuskInstaller.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+ /**
4
+ * Composer installer for 3rd party Tusk utilities
5
+ * @author Drew Ewing <drew@phenocode.com>
6
+ */
7
+ class TuskInstaller extends BaseInstaller
8
+ {
9
+ protected $locations = array(
10
+ 'task' => '.tusk/tasks/{$name}/',
11
+ 'command' => '.tusk/commands/{$name}/',
12
+ 'asset' => 'assets/tusk/{$name}/',
13
+ );
14
+ }
vendor/composer/installers/tests/Composer/Installers/Test/CakePHPInstallerTest.php CHANGED
@@ -2,9 +2,13 @@
2
  namespace Composer\Installers\Test;
3
 
4
  use Composer\Installers\CakePHPInstaller;
 
 
5
  use Composer\Package\Package;
 
 
 
6
  use Composer\Composer;
7
- use Composer\Config;
8
 
9
  class CakePHPInstallerTest extends TestCase
10
  {
@@ -18,9 +22,9 @@ class CakePHPInstallerTest extends TestCase
18
  */
19
  public function setUp()
20
  {
21
- $this->package = new Package('CamelCased', '1.0', '1.0');
22
- $this->io = $this->getMock('Composer\IO\PackageInterface');
23
- $this->composer = new Composer();
24
  }
25
 
26
  /**
@@ -41,6 +45,69 @@ class CakePHPInstallerTest extends TestCase
41
  $installer = new CakePHPInstaller($this->package, $this->composer);
42
  $result = $installer->inflectPackageVars(array('name' => 'with_underscore'));
43
  $this->assertEquals($result, array('name' => 'WithUnderscore'));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  }
45
 
46
  }
2
  namespace Composer\Installers\Test;
3
 
4
  use Composer\Installers\CakePHPInstaller;
5
+ use Composer\Repository\RepositoryManager;
6
+ use Composer\Repository\InstalledArrayRepository;
7
  use Composer\Package\Package;
8
+ use Composer\Package\RootPackage;
9
+ use Composer\Package\Link;
10
+ use Composer\Package\Version\VersionParser;
11
  use Composer\Composer;
 
12
 
13
  class CakePHPInstallerTest extends TestCase
14
  {
22
  */
23
  public function setUp()
24
  {
25
+ $this->package = new Package('CamelCased', '1.0', '1.0');
26
+ $this->io = $this->getMock('Composer\IO\PackageInterface');
27
+ $this->composer = new Composer();
28
  }
29
 
30
  /**
45
  $installer = new CakePHPInstaller($this->package, $this->composer);
46
  $result = $installer->inflectPackageVars(array('name' => 'with_underscore'));
47
  $this->assertEquals($result, array('name' => 'WithUnderscore'));
48
+
49
+ $installer = new CakePHPInstaller($this->package, $this->composer);
50
+ $result = $installer->inflectPackageVars(array('name' => 'cake/acl'));
51
+ $this->assertEquals($result, array('name' => 'Cake/Acl'));
52
+
53
+ $installer = new CakePHPInstaller($this->package, $this->composer);
54
+ $result = $installer->inflectPackageVars(array('name' => 'cake/debug-kit'));
55
+ $this->assertEquals($result, array('name' => 'Cake/DebugKit'));
56
+ }
57
+
58
+ /**
59
+ * Test getLocations returning appropriate values based on CakePHP version
60
+ *
61
+ */
62
+ public function testGetLocations() {
63
+ $package = new RootPackage('CamelCased', '1.0', '1.0');
64
+ $composer = new Composer();
65
+ $rm = new RepositoryManager(
66
+ $this->getMock('Composer\IO\IOInterface'),
67
+ $this->getMock('Composer\Config')
68
+ );
69
+ $composer->setRepositoryManager($rm);
70
+ $installer = new CakePHPInstaller($package, $composer);
71
+
72
+ // 2.0 < cakephp < 3.0
73
+ $this->setCakephpVersion($rm, '2.0.0');
74
+ $result = $installer->getLocations();
75
+ $this->assertContains('Plugin/', $result['plugin']);
76
+
77
+ $this->setCakephpVersion($rm, '2.5.9');
78
+ $result = $installer->getLocations();
79
+ $this->assertContains('Plugin/', $result['plugin']);
80
+
81
+ $this->setCakephpVersion($rm, '~2.5');
82
+ $result = $installer->getLocations();
83
+ $this->assertContains('Plugin/', $result['plugin']);
84
+
85
+ // special handling for 2.x versions when 3.x is still in development
86
+ $this->setCakephpVersion($rm, 'dev-master');
87
+ $result = $installer->getLocations();
88
+ $this->assertContains('Plugin/', $result['plugin']);
89
+
90
+ $this->setCakephpVersion($rm, '>=2.5');
91
+ $result = $installer->getLocations();
92
+ $this->assertContains('Plugin/', $result['plugin']);
93
+
94
+ // cakephp >= 3.0
95
+ $this->setCakephpVersion($rm, '3.0.*-dev');
96
+ $result = $installer->getLocations();
97
+ $this->assertContains('plugins/', $result['plugin']);
98
+
99
+ $this->setCakephpVersion($rm, '~8.8');
100
+ $result = $installer->getLocations();
101
+ $this->assertContains('plugins/', $result['plugin']);
102
+ }
103
+
104
+ protected function setCakephpVersion($rm, $version) {
105
+ $parser = new VersionParser();
106
+ list(, $version) = explode(' ', $parser->parseConstraints($version));
107
+ $installed = new InstalledArrayRepository();
108
+ $package = new Package('cakephp/cakephp', $version, $version);
109
+ $installed->addPackage($package);
110
+ $rm->setLocalRepository($installed);
111
  }
112
 
113
  }
vendor/composer/installers/tests/Composer/Installers/Test/InstallerTest.php CHANGED
@@ -88,6 +88,8 @@ class InstallerTest extends TestCase
88
  array('annotatecms-module', true),
89
  array('annotatecms-component', true),
90
  array('annotatecms-service', true),
 
 
91
  array('cakephp', false),
92
  array('cakephp-', false),
93
  array('cakephp-app', false),
@@ -104,6 +106,7 @@ class InstallerTest extends TestCase
104
  array('croogo-plugin', true),
105
  array('croogo-theme', true),
106
  array('drupal-module', true),
 
107
  array('elgg-plugin', true),
108
  array('fuel-module', true),
109
  array('fuel-package', true),
@@ -123,12 +126,16 @@ class InstallerTest extends TestCase
123
  array('modxevo-lib', true),
124
  array('mediawiki-extension', true),
125
  array('mediawiki-skin', true),
 
126
  array('modulework-module', true),
 
127
  array('october-module', true),
128
  array('october-plugin', true),
129
  array('piwik-plugin', true),
130
  array('phpbb-extension', true),
 
131
  array('ppi-module', true),
 
132
  array('shopware-backend-plugin', true),
133
  array('shopware-core-plugin', true),
134
  array('shopware-frontend-plugin', true),
@@ -136,6 +143,8 @@ class InstallerTest extends TestCase
136
  array('silverstripe-module', true),
137
  array('silverstripe-theme', true),
138
  array('symfony1-plugin', true),
 
 
139
  array('typo3-flow-plugin', true),
140
  array('typo3-cms-extension', true),
141
  array('wolfcms-plugin', true),
@@ -172,6 +181,8 @@ class InstallerTest extends TestCase
172
  array('annotatecms-module', 'addons/modules/my_module/', 'vysinsky/my_module'),
173
  array('annotatecms-component', 'addons/components/my_component/', 'vysinsky/my_component'),
174
  array('annotatecms-service', 'addons/services/my_service/', 'vysinsky/my_service'),
 
 
175
  array('cakephp-plugin', 'Plugin/Ftp/', 'shama/ftp'),
176
  array('codeigniter-library', 'application/libraries/my_package/', 'shama/my_package'),
177
  array('codeigniter-module', 'application/modules/my_package/', 'shama/my_package'),
@@ -182,6 +193,7 @@ class InstallerTest extends TestCase
182
  array('craft-plugin', 'craft/plugins/my_plugin/', 'mdcpepper/my_plugin'),
183
  array('croogo-plugin', 'Plugin/Sitemaps/', 'fahad19/sitemaps'),
184
  array('croogo-theme', 'View/Themed/Readable/', 'rchavik/readable'),
 
185
  array('drupal-module', 'modules/my_module/', 'shama/my_module'),
186
  array('drupal-theme', 'themes/my_module/', 'shama/my_module'),
187
  array('drupal-profile', 'profiles/my_module/', 'shama/my_module'),
@@ -203,20 +215,25 @@ class InstallerTest extends TestCase
203
  array('modxevo-template', 'assets/templates/my_template/', 'shama/my_template'),
204
  array('modxevo-lib', 'assets/lib/my_lib/', 'shama/my_lib'),
205
  array('mako-package', 'app/packages/my_package/', 'shama/my_package'),
206
- array('mediawiki-extension', 'extensions/APC/', 'author/APC' ),
207
- array('mediawiki-extension', 'extensions/APC/', 'author/APC-extension' ),
208
- array('mediawiki-extension', 'extensions/UploadWizard/', 'author/upload-wizard' ),
209
- array('mediawiki-extension', 'extensions/SyntaxHighlight_GeSHi/', 'author/syntax-highlight_GeSHi' ),
210
- array('mediawiki-skin', 'skins/someskin/', 'author/someskin-skin' ),
211
- array('mediawiki-skin', 'skins/someskin/', 'author/someskin' ),
 
212
  array('modulework-module', 'modules/my_package/', 'shama/my_package'),
 
213
  array('october-module', 'modules/my_plugin/', 'shama/my_plugin'),
214
  array('october-plugin', 'plugins/shama/my_plugin/', 'shama/my_plugin'),
215
  array('piwik-plugin', 'plugins/VisitSummary/', 'shama/visit-summary'),
216
  array('phpbb-extension', 'ext/test/foo/', 'test/foo'),
217
  array('phpbb-style', 'styles/foo/', 'test/foo'),
218
  array('phpbb-language', 'language/foo/', 'test/foo'),
 
219
  array('ppi-module', 'modules/foo/', 'test/foo'),
 
 
220
  array('shopware-backend-plugin', 'engine/Shopware/Plugins/Local/Backend/ShamaMyBackendPlugin/', 'shama/my-backend-plugin'),
221
  array('shopware-core-plugin', 'engine/Shopware/Plugins/Local/Core/ShamaMyCorePlugin/', 'shama/my-core-plugin'),
222
  array('shopware-frontend-plugin', 'engine/Shopware/Plugins/Local/Frontend/ShamaMyFrontendPlugin/', 'shama/my-frontend-plugin'),
@@ -229,6 +246,7 @@ class InstallerTest extends TestCase
229
  array('silverstripe-theme', 'themes/my_theme/', 'shama/my_theme'),
230
  array('symfony1-plugin', 'plugins/sfShamaPlugin/', 'shama/sfShamaPlugin'),
231
  array('symfony1-plugin', 'plugins/sfShamaPlugin/', 'shama/sf-shama-plugin'),
 
232
  array('typo3-flow-package', 'Packages/Application/my_package/', 'shama/my_package'),
233
  array('typo3-flow-build', 'Build/my_package/', 'shama/my_package'),
234
  array('typo3-cms-extension', 'typo3conf/ext/my_extension/', 'shama/my_extension'),
@@ -282,7 +300,8 @@ class InstallerTest extends TestCase
282
  /**
283
  * testCustomInstallerName
284
  */
285
- public function testCustomInstallerName() {
 
286
  $installer = new Installer($this->io, $this->composer);
287
  $package = new Package('shama/cakephp-ftp-plugin', '1.0.0', '1.0.0');
288
  $package->setType('cakephp-plugin');
@@ -296,7 +315,8 @@ class InstallerTest extends TestCase
296
  /**
297
  * testCustomTypePath
298
  */
299
- public function testCustomTypePath() {
 
300
  $installer = new Installer($this->io, $this->composer);
301
  $package = new Package('slbmeh/my_plugin', '1.0.0', '1.0.0');
302
  $package->setType('wordpress-plugin');
88
  array('annotatecms-module', true),
89
  array('annotatecms-component', true),
90
  array('annotatecms-service', true),
91
+ array('bitrix-module', true),
92
+ array('bitrix-component', true),
93
  array('cakephp', false),
94
  array('cakephp-', false),
95
  array('cakephp-app', false),
106
  array('croogo-plugin', true),
107
  array('croogo-theme', true),
108
  array('drupal-module', true),
109
+ array('dolibarr-module', true),
110
  array('elgg-plugin', true),
111
  array('fuel-module', true),
112
  array('fuel-package', true),
126
  array('modxevo-lib', true),
127
  array('mediawiki-extension', true),
128
  array('mediawiki-skin', true),
129
+ array('microweber-module', true),
130
  array('modulework-module', true),
131
+ array('moodle-mod', true),
132
  array('october-module', true),
133
  array('october-plugin', true),
134
  array('piwik-plugin', true),
135
  array('phpbb-extension', true),
136
+ array('pimcore-plugin', true),
137
  array('ppi-module', true),
138
+ array('roundcube-plugin', true),
139
  array('shopware-backend-plugin', true),
140
  array('shopware-core-plugin', true),
141
  array('shopware-frontend-plugin', true),
143
  array('silverstripe-module', true),
144
  array('silverstripe-theme', true),
145
  array('symfony1-plugin', true),
146
+ array('tusk-task', true),
147
+ array('tusk-asset', true),
148
  array('typo3-flow-plugin', true),
149
  array('typo3-cms-extension', true),
150
  array('wolfcms-plugin', true),
181
  array('annotatecms-module', 'addons/modules/my_module/', 'vysinsky/my_module'),
182
  array('annotatecms-component', 'addons/components/my_component/', 'vysinsky/my_component'),
183
  array('annotatecms-service', 'addons/services/my_service/', 'vysinsky/my_service'),
184
+ array('bitrix-module', 'local/modules/my_module/', 'author/my_module'),
185
+ array('bitrix-component', 'local/components/my_component/', 'author/my_component'),
186
  array('cakephp-plugin', 'Plugin/Ftp/', 'shama/ftp'),
187
  array('codeigniter-library', 'application/libraries/my_package/', 'shama/my_package'),
188
  array('codeigniter-module', 'application/modules/my_package/', 'shama/my_package'),
193
  array('craft-plugin', 'craft/plugins/my_plugin/', 'mdcpepper/my_plugin'),
194
  array('croogo-plugin', 'Plugin/Sitemaps/', 'fahad19/sitemaps'),
195
  array('croogo-theme', 'View/Themed/Readable/', 'rchavik/readable'),
196
+ array('dolibarr-module', 'htdocs/custom/my_module/', 'shama/my_module'),
197
  array('drupal-module', 'modules/my_module/', 'shama/my_module'),
198
  array('drupal-theme', 'themes/my_module/', 'shama/my_module'),
199
  array('drupal-profile', 'profiles/my_module/', 'shama/my_module'),
215
  array('modxevo-template', 'assets/templates/my_template/', 'shama/my_template'),
216
  array('modxevo-lib', 'assets/lib/my_lib/', 'shama/my_lib'),
217
  array('mako-package', 'app/packages/my_package/', 'shama/my_package'),
218
+ array('mediawiki-extension', 'extensions/APC/', 'author/APC'),
219
+ array('mediawiki-extension', 'extensions/APC/', 'author/APC-extension'),
220
+ array('mediawiki-extension', 'extensions/UploadWizard/', 'author/upload-wizard'),
221
+ array('mediawiki-extension', 'extensions/SyntaxHighlight_GeSHi/', 'author/syntax-highlight_GeSHi'),
222
+ array('mediawiki-skin', 'skins/someskin/', 'author/someskin-skin'),
223
+ array('mediawiki-skin', 'skins/someskin/', 'author/someskin'),
224
+ array('microweber-module', 'userfiles/modules/my-thing/', 'author/my-thing-module'),
225
  array('modulework-module', 'modules/my_package/', 'shama/my_package'),
226
+ array('moodle-mod', 'mod/my_package/', 'shama/my_package'),
227
  array('october-module', 'modules/my_plugin/', 'shama/my_plugin'),
228
  array('october-plugin', 'plugins/shama/my_plugin/', 'shama/my_plugin'),
229
  array('piwik-plugin', 'plugins/VisitSummary/', 'shama/visit-summary'),
230
  array('phpbb-extension', 'ext/test/foo/', 'test/foo'),
231
  array('phpbb-style', 'styles/foo/', 'test/foo'),
232
  array('phpbb-language', 'language/foo/', 'test/foo'),
233
+ array('pimcore-plugin', 'plugins/MyPlugin/', 'ubikz/my_plugin'),
234
  array('ppi-module', 'modules/foo/', 'test/foo'),
235
+ array('roundcube-plugin', 'plugins/base/', 'test/base'),
236
+ array('roundcube-plugin', 'plugins/replace_dash/', 'test/replace-dash'),
237
  array('shopware-backend-plugin', 'engine/Shopware/Plugins/Local/Backend/ShamaMyBackendPlugin/', 'shama/my-backend-plugin'),
238
  array('shopware-core-plugin', 'engine/Shopware/Plugins/Local/Core/ShamaMyCorePlugin/', 'shama/my-core-plugin'),
239
  array('shopware-frontend-plugin', 'engine/Shopware/Plugins/Local/Frontend/ShamaMyFrontendPlugin/', 'shama/my-frontend-plugin'),
246
  array('silverstripe-theme', 'themes/my_theme/', 'shama/my_theme'),
247
  array('symfony1-plugin', 'plugins/sfShamaPlugin/', 'shama/sfShamaPlugin'),
248
  array('symfony1-plugin', 'plugins/sfShamaPlugin/', 'shama/sf-shama-plugin'),
249
+ array('tusk-task', '.tusk/tasks/my_task/', 'shama/my_task'),
250
  array('typo3-flow-package', 'Packages/Application/my_package/', 'shama/my_package'),
251
  array('typo3-flow-build', 'Build/my_package/', 'shama/my_package'),
252
  array('typo3-cms-extension', 'typo3conf/ext/my_extension/', 'shama/my_extension'),
300
  /**
301
  * testCustomInstallerName
302
  */
303
+ public function testCustomInstallerName()
304
+ {
305
  $installer = new Installer($this->io, $this->composer);
306
  $package = new Package('shama/cakephp-ftp-plugin', '1.0.0', '1.0.0');
307
  $package->setType('cakephp-plugin');
315
  /**
316
  * testCustomTypePath
317
  */
318
+ public function testCustomTypePath()
319
+ {
320
  $installer = new Installer($this->io, $this->composer);
321
  $package = new Package('slbmeh/my_plugin', '1.0.0', '1.0.0');
322
  $package->setType('wordpress-plugin');
vendor/composer/installers/tests/Composer/Installers/Test/MediaWikiInstallerTest.php CHANGED
@@ -4,64 +4,63 @@ namespace Composer\Installers\Test;
4
  use Composer\Installers\MediaWikiInstaller;
5
  use Composer\Package\Package;
6
  use Composer\Composer;
7
- use Composer\Config;
8
 
9
  class MediaWikiInstallerTest extends \PHPUnit_Framework_TestCase
10
  {
11
- /**
12
- * @var MediaWikiInstaller
13
- */
14
- private $installer;
15
 
16
- public function setUp()
17
- {
18
- $this->installer = new MediaWikiInstaller(
19
- new Package('NyanCat', '4.2', '4.2'),
20
- new Composer()
21
- );
22
- }
23
 
24
- /**
25
- * @dataProvider packageNameInflectionProvider
26
- */
27
- public function testInflectPackageVars($type, $name, $expected)
28
- {
29
- $this->assertEquals(
30
- $this->installer->inflectPackageVars(array('name' => $name, 'type'=>$type)),
31
- array('name' => $expected, 'type'=>$type)
32
- );
33
- }
34
 
35
- public function packageNameInflectionProvider()
36
- {
37
- return array(
38
- array(
39
- 'mediawiki-extension',
40
- 'sub-page-list',
41
- 'SubPageList',
42
- ),
43
- array(
44
- 'mediawiki-extension',
45
- 'sub-page-list-extension',
46
- 'SubPageList',
47
- ),
48
- array(
49
- 'mediawiki-extension',
50
- 'semantic-mediawiki',
51
- 'SemanticMediawiki',
52
- ),
53
- // tests that exactly one '-skin' is cut off, and that skins do not get ucwords treatment like extensions
54
- array(
55
- 'mediawiki-skin',
56
- 'some-skin-skin',
57
- 'some-skin',
58
- ),
59
- // tests that names without '-skin' suffix stay valid
60
- array(
61
- 'mediawiki-skin',
62
- 'someotherskin',
63
- 'someotherskin',
64
- ),
65
- );
66
- }
67
  }
4
  use Composer\Installers\MediaWikiInstaller;
5
  use Composer\Package\Package;
6
  use Composer\Composer;
 
7
 
8
  class MediaWikiInstallerTest extends \PHPUnit_Framework_TestCase
9
  {
10
+ /**
11
+ * @var MediaWikiInstaller
12
+ */
13
+ private $installer;
14
 
15
+ public function setUp()
16
+ {
17
+ $this->installer = new MediaWikiInstaller(
18
+ new Package('NyanCat', '4.2', '4.2'),
19
+ new Composer()
20
+ );
21
+ }
22
 
23
+ /**
24
+ * @dataProvider packageNameInflectionProvider
25
+ */
26
+ public function testInflectPackageVars($type, $name, $expected)
27
+ {
28
+ $this->assertEquals(
29
+ $this->installer->inflectPackageVars(array('name' => $name, 'type'=>$type)),
30
+ array('name' => $expected, 'type'=>$type)
31
+ );
32
+ }
33
 
34
+ public function packageNameInflectionProvider()
35
+ {
36
+ return array(
37
+ array(
38
+ 'mediawiki-extension',
39
+ 'sub-page-list',
40
+ 'SubPageList',
41
+ ),
42
+ array(
43
+ 'mediawiki-extension',
44
+ 'sub-page-list-extension',
45
+ 'SubPageList',
46
+ ),
47
+ array(
48
+ 'mediawiki-extension',
49
+ 'semantic-mediawiki',
50
+ 'SemanticMediawiki',
51
+ ),
52
+ // tests that exactly one '-skin' is cut off, and that skins do not get ucwords treatment like extensions
53
+ array(
54
+ 'mediawiki-skin',
55
+ 'some-skin-skin',
56
+ 'some-skin',
57
+ ),
58
+ // tests that names without '-skin' suffix stay valid
59
+ array(
60
+ 'mediawiki-skin',
61
+ 'someotherskin',
62
+ 'someotherskin',
63
+ ),
64
+ );
65
+ }
66
  }
vendor/composer/installers/tests/Composer/Installers/Test/PimcoreInstallerTest.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers\Test;
3
+
4
+ use Composer\Installers\PimcoreInstaller;
5
+ use Composer\Package\Package;
6
+ use Composer\Composer;
7
+
8
+ class PimcoreInstallerTest extends TestCase
9
+ {
10
+ private $composer;
11
+ private $io;
12
+
13
+ /**
14
+ * setUp
15
+ *
16
+ * @return void
17
+ */
18
+ public function setUp()
19
+ {
20
+ $this->package = new Package('CamelCased', '1.0', '1.0');
21
+ $this->io = $this->getMock('Composer\IO\PackageInterface');
22
+ $this->composer = new Composer();
23
+ }
24
+
25
+ /**
26
+ * testInflectPackageVars
27
+ *
28
+ * @return void
29
+ */
30
+ public function testInflectPackageVars()
31
+ {
32
+ $installer = new PimcoreInstaller($this->package, $this->composer);
33
+ $result = $installer->inflectPackageVars(array('name' => 'CamelCased'));
34
+ $this->assertEquals($result, array('name' => 'CamelCased'));
35
+
36
+ $installer = new PimcoreInstaller($this->package, $this->composer);
37
+ $result = $installer->inflectPackageVars(array('name' => 'with-dash'));
38
+ $this->assertEquals($result, array('name' => 'WithDash'));
39
+
40
+ $installer = new PimcoreInstaller($this->package, $this->composer);
41
+ $result = $installer->inflectPackageVars(array('name' => 'with_underscore'));
42
+ $this->assertEquals($result, array('name' => 'WithUnderscore'));
43
+ }
44
+ }
vendor/composer/installers/tests/Composer/Installers/Test/PiwikInstallerTest.php CHANGED
@@ -2,7 +2,6 @@
2
  namespace Composer\Installers\Test;
3
 
4
  use Composer\Composer;
5
- use Composer\Config;
6
  use Composer\Installers\PiwikInstaller;
7
  use Composer\Package\Package;
8
  use Composer\Package\PackageInterface;
2
  namespace Composer\Installers\Test;
3
 
4
  use Composer\Composer;
 
5
  use Composer\Installers\PiwikInstaller;
6
  use Composer\Package\Package;
7
  use Composer\Package\PackageInterface;
vendor/symfony/yaml/Symfony/Component/Yaml/Inline.php CHANGED
@@ -350,19 +350,37 @@ class Inline
350
  switch ($mapping[$i]) {
351
  case '[':
352
  // nested sequence
353
- $output[$key] = self::parseSequence($mapping, $i);
 
 
 
 
 
 
354
  $done = true;
355
  break;
356
  case '{':
357
  // nested mapping
358
- $output[$key] = self::parseMapping($mapping, $i);
 
 
 
 
 
 
359
  $done = true;
360
  break;
361
  case ':':
362
  case ' ':
363
  break;
364
  default:
365
- $output[$key] = self::parseScalar($mapping, array(',', '}'), array('"', "'"), $i);
 
 
 
 
 
 
366
  $done = true;
367
  --$i;
368
  }
350
  switch ($mapping[$i]) {
351
  case '[':
352
  // nested sequence
353
+ $value = self::parseSequence($mapping, $i);
354
+ // Spec: Keys MUST be unique; first one wins.
355
+ // Parser cannot abort this mapping earlier, since lines
356
+ // are processed sequentially.
357
+ if (!isset($output[$key])) {
358
+ $output[$key] = $value;
359
+ }
360
  $done = true;
361
  break;
362
  case '{':
363
  // nested mapping
364
+ $value = self::parseMapping($mapping, $i);
365
+ // Spec: Keys MUST be unique; first one wins.
366
+ // Parser cannot abort this mapping earlier, since lines
367
+ // are processed sequentially.
368
+ if (!isset($output[$key])) {
369
+ $output[$key] = $value;
370
+ }
371
  $done = true;
372
  break;
373
  case ':':
374
  case ' ':
375
  break;
376
  default:
377
+ $value = self::parseScalar($mapping, array(',', '}'), array('"', "'"), $i);
378
+ // Spec: Keys MUST be unique; first one wins.
379
+ // Parser cannot abort this mapping earlier, since lines
380
+ // are processed sequentially.
381
+ if (!isset($output[$key])) {
382
+ $output[$key] = $value;
383
+ }
384
  $done = true;
385
  --$i;
386
  }
vendor/symfony/yaml/Symfony/Component/Yaml/Parser.php CHANGED
@@ -178,18 +178,35 @@ class Parser
178
  } elseif (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) {
179
  // if next line is less indented or equal, then it means that the current value is null
180
  if (!$this->isNextLineIndented() && !$this->isNextLineUnIndentedCollection()) {
181
- $data[$key] = null;
 
 
 
 
 
182
  } else {
183
  $c = $this->getRealCurrentLineNb() + 1;
184
  $parser = new Parser($c);
185
  $parser->refs =& $this->refs;
186
- $data[$key] = $parser->parse($this->getNextEmbedBlock(), $exceptionOnInvalidType, $objectSupport);
 
 
 
 
 
 
187
  }
188
  } else {
189
  if ($isInPlace) {
190
  $data = $this->refs[$isInPlace];
191
  } else {
192
- $data[$key] = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport);
 
 
 
 
 
 
193
  }
194
  }
195
  } else {
178
  } elseif (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) {
179
  // if next line is less indented or equal, then it means that the current value is null
180
  if (!$this->isNextLineIndented() && !$this->isNextLineUnIndentedCollection()) {
181
+ // Spec: Keys MUST be unique; first one wins.
182
+ // Parser cannot abort this mapping earlier, since lines
183
+ // are processed sequentially.
184
+ if (!isset($data[$key])) {
185
+ $data[$key] = null;
186
+ }
187
  } else {
188
  $c = $this->getRealCurrentLineNb() + 1;
189
  $parser = new Parser($c);
190
  $parser->refs =& $this->refs;
191
+ $value = $parser->parse($this->getNextEmbedBlock(), $exceptionOnInvalidType, $objectSupport);
192
+ // Spec: Keys MUST be unique; first one wins.
193
+ // Parser cannot abort this mapping earlier, since lines
194
+ // are processed sequentially.
195
+ if (!isset($data[$key])) {
196
+ $data[$key] = $value;
197
+ }
198
  }
199
  } else {
200
  if ($isInPlace) {
201
  $data = $this->refs[$isInPlace];
202
  } else {
203
+ $value = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport);;
204
+ // Spec: Keys MUST be unique; first one wins.
205
+ // Parser cannot abort this mapping earlier, since lines
206
+ // are processed sequentially.
207
+ if (!isset($data[$key])) {
208
+ $data[$key] = $value;
209
+ }
210
  }
211
  }
212
  } else {
vendor/symfony/yaml/Symfony/Component/Yaml/Tests/ParserTest.php CHANGED
@@ -508,6 +508,53 @@ EOF
508
  );
509
  }
510
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
511
  public function testEmptyValue()
512
  {
513
  $input = <<<EOF
508
  );
509
  }
510
 
511
+ /**
512
+ * > It is an error for two equal keys to appear in the same mapping node.
513
+ * > In such a case the YAML processor may continue, ignoring the second
514
+ * > `key: value` pair and issuing an appropriate warning. This strategy
515
+ * > preserves a consistent information model for one-pass and random access
516
+ * > applications.
517
+ *
518
+ * @see http://yaml.org/spec/1.2/spec.html#id2759572
519
+ * @see http://yaml.org/spec/1.1/#id932806
520
+ *
521
+ * @covers \Symfony\Component\Yaml\Parser::parse
522
+ */
523
+ public function testMappingDuplicateKeyBlock()
524
+ {
525
+ $input = <<<EOD
526
+ parent:
527
+ child: first
528
+ child: duplicate
529
+ parent:
530
+ child: duplicate
531
+ child: duplicate
532
+ EOD;
533
+ $expected = array(
534
+ 'parent' => array(
535
+ 'child' => 'first',
536
+ ),
537
+ );
538
+ $this->assertSame($expected, Yaml::parse($input));
539
+ }
540
+
541
+ /**
542
+ * @covers \Symfony\Component\Yaml\Inline::parseMapping
543
+ */
544
+ public function testMappingDuplicateKeyFlow()
545
+ {
546
+ $input = <<<EOD
547
+ parent: { child: first, child: duplicate }
548
+ parent: { child: duplicate, child: duplicate }
549
+ EOD;
550
+ $expected = array(
551
+ 'parent' => array(
552
+ 'child' => 'first',
553
+ ),
554
+ );
555
+ $this->assertSame($expected, Yaml::parse($input));
556
+ }
557
+
558
  public function testEmptyValue()
559
  {
560
  $input = <<<EOF
vendor/symfony/yaml/Symfony/Component/Yaml/composer.json CHANGED
@@ -25,7 +25,7 @@
25
  "minimum-stability": "dev",
26
  "extra": {
27
  "branch-alias": {
28
- "dev-master": "2.4-dev"
29
  }
30
  }
31
  }
25
  "minimum-stability": "dev",
26
  "extra": {
27
  "branch-alias": {
28
+ "dev-master": "2.5-dev"
29
  }
30
  }
31
  }