Posts 2 Posts - Version 1.6.5

Version Description

  • fixed error when Mustache is already loaded. props ApatheticG
  • fixed WP_User_Query warning. props PatelUtkarsh
  • added Chinese translation. props iwillhappy1314
Download this release

Release Info

Developer scribu
Plugin Icon wp plugin Posts 2 Posts
Version 1.6.5
Comparing to
See all releases

Code changes from version 1.6.4 to 1.6.5

Files changed (55) hide show
  1. posts-to-posts.php +6 -4
  2. readme.txt +8 -3
  3. vendor/mustache/mustache/.php_cs +26 -0
  4. vendor/mustache/mustache/.styleci.yml +13 -0
  5. vendor/mustache/mustache/.travis.yml +10 -3
  6. vendor/mustache/mustache/CONTRIBUTING.md +6 -4
  7. vendor/mustache/mustache/LICENSE +1 -1
  8. vendor/mustache/mustache/README.md +5 -5
  9. vendor/mustache/mustache/composer.json +2 -1
  10. vendor/mustache/mustache/src/Mustache/Autoloader.php +2 -2
  11. vendor/mustache/mustache/src/Mustache/Cache.php +2 -4
  12. vendor/mustache/mustache/src/Mustache/Cache/AbstractCache.php +4 -4
  13. vendor/mustache/mustache/src/Mustache/Cache/FilesystemCache.php +5 -9
  14. vendor/mustache/mustache/src/Mustache/Cache/NoopCache.php +2 -4
  15. vendor/mustache/mustache/src/Mustache/Compiler.php +276 -88
  16. vendor/mustache/mustache/src/Mustache/Context.php +103 -15
  17. vendor/mustache/mustache/src/Mustache/Engine.php +58 -18
  18. vendor/mustache/mustache/src/Mustache/Exception.php +1 -1
  19. vendor/mustache/mustache/src/Mustache/Exception/InvalidArgumentException.php +1 -1
  20. vendor/mustache/mustache/src/Mustache/Exception/LogicException.php +1 -1
  21. vendor/mustache/mustache/src/Mustache/Exception/RuntimeException.php +1 -1
  22. vendor/mustache/mustache/src/Mustache/Exception/SyntaxException.php +1 -1
  23. vendor/mustache/mustache/src/Mustache/Exception/UnknownFilterException.php +1 -1
  24. vendor/mustache/mustache/src/Mustache/Exception/UnknownHelperException.php +1 -1
  25. vendor/mustache/mustache/src/Mustache/Exception/UnknownTemplateException.php +1 -1
  26. vendor/mustache/mustache/src/Mustache/HelperCollection.php +4 -4
  27. vendor/mustache/mustache/src/Mustache/LambdaHelper.php +1 -1
  28. vendor/mustache/mustache/src/Mustache/Loader.php +1 -1
  29. vendor/mustache/mustache/src/Mustache/Loader/ArrayLoader.php +1 -1
  30. vendor/mustache/mustache/src/Mustache/Loader/CascadingLoader.php +2 -2
  31. vendor/mustache/mustache/src/Mustache/Loader/FilesystemLoader.php +2 -2
  32. vendor/mustache/mustache/src/Mustache/Loader/InlineLoader.php +2 -2
  33. vendor/mustache/mustache/src/Mustache/Loader/MutableLoader.php +1 -5
  34. vendor/mustache/mustache/src/Mustache/Loader/StringLoader.php +1 -1
  35. vendor/mustache/mustache/src/Mustache/Logger.php +3 -21
  36. vendor/mustache/mustache/src/Mustache/Logger/AbstractLogger.php +1 -1
  37. vendor/mustache/mustache/src/Mustache/Logger/StreamLogger.php +11 -11
  38. vendor/mustache/mustache/src/Mustache/Parser.php +117 -6
  39. vendor/mustache/mustache/src/Mustache/Template.php +22 -17
  40. vendor/mustache/mustache/src/Mustache/Tokenizer.php +21 -26
  41. vendor/scribu/lib-posts-to-posts/README.md +8 -0
  42. vendor/scribu/lib-posts-to-posts/side-user.php +1 -21
  43. vendor/scribu/lib-posts-to-posts/widget.php +3 -5
  44. vendor/scribu/scb-framework/AdminPage.php +159 -93
  45. vendor/scribu/scb-framework/BoxesPage.php +111 -30
  46. vendor/scribu/scb-framework/Cron.php +73 -37
  47. vendor/scribu/scb-framework/Forms.php +219 -100
  48. vendor/scribu/scb-framework/Hooks.php +56 -9
  49. vendor/scribu/scb-framework/Options.php +90 -43
  50. vendor/scribu/scb-framework/PostMetabox.php +187 -23
  51. vendor/scribu/scb-framework/Table.php +41 -6
  52. vendor/scribu/scb-framework/Util.php +235 -64
  53. vendor/scribu/scb-framework/Widget.php +66 -17
  54. vendor/scribu/scb-framework/load-composer.php +3 -2
  55. vendor/scribu/scb-framework/load.php +30 -18
posts-to-posts.php CHANGED
@@ -2,7 +2,7 @@
2
  /*
3
  Plugin Name: Posts 2 Posts
4
  Description: Create many-to-many relationships between all types of posts.
5
- Version: 1.6.4
6
  Author: scribu
7
  Author URI: http://scribu.net/
8
  Plugin URI: http://scribu.net/wordpress/posts-to-posts
@@ -10,7 +10,7 @@ Text Domain: posts-to-posts
10
  Domain Path: /lang
11
  */
12
 
13
- define( 'P2P_PLUGIN_VERSION', '1.6.4' );
14
 
15
  define( 'P2P_TEXTDOMAIN', 'posts-to-posts' );
16
 
@@ -57,8 +57,10 @@ function _p2p_init() {
57
  if ( is_dir( dirname( __FILE__ ) . '/vendor' ) ) {
58
  // Not using vendor/autload.php because scb-framework/load.php has better compatibility
59
 
60
- require_once dirname( __FILE__ ) . '/vendor/mustache/mustache/src/Mustache/Autoloader.php';
61
- Mustache_Autoloader::register();
 
 
62
 
63
  require_once dirname( __FILE__ ) . '/vendor/scribu/scb-framework/load.php';
64
  }
2
  /*
3
  Plugin Name: Posts 2 Posts
4
  Description: Create many-to-many relationships between all types of posts.
5
+ Version: 1.6.5
6
  Author: scribu
7
  Author URI: http://scribu.net/
8
  Plugin URI: http://scribu.net/wordpress/posts-to-posts
10
  Domain Path: /lang
11
  */
12
 
13
+ define( 'P2P_PLUGIN_VERSION', '1.6.5' );
14
 
15
  define( 'P2P_TEXTDOMAIN', 'posts-to-posts' );
16
 
57
  if ( is_dir( dirname( __FILE__ ) . '/vendor' ) ) {
58
  // Not using vendor/autload.php because scb-framework/load.php has better compatibility
59
 
60
+ if (!class_exists('Mustache_Autoloader')) {
61
+ require_once dirname( __FILE__ ) . '/vendor/mustache/mustache/src/Mustache/Autoloader.php';
62
+ Mustache_Autoloader::register();
63
+ }
64
 
65
  require_once dirname( __FILE__ ) . '/vendor/scribu/scb-framework/load.php';
66
  }
readme.txt CHANGED
@@ -2,9 +2,9 @@
2
 
3
  Contributors: scribu, ciobi
4
  Tags: connections, custom post types, relationships, many-to-many, users
5
- Requires at least: 3.5
6
- Tested up to: 4.2
7
- Stable tag: 1.6.4
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -57,6 +57,11 @@ Additional info can be found on the [wiki](http://github.com/scribu/wp-posts-to-
57
 
58
  == Changelog ==
59
 
 
 
 
 
 
60
  = 1.6.4 =
61
  * added Danish translation. props phh
62
  * updated Swedish translation. props EyesX
2
 
3
  Contributors: scribu, ciobi
4
  Tags: connections, custom post types, relationships, many-to-many, users
5
+ Requires at least: 3.9
6
+ Tested up to: 4.3
7
+ Stable tag: 1.6.5
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
57
 
58
  == Changelog ==
59
 
60
+ = 1.6.5 =
61
+ * fixed error when Mustache is already loaded. props ApatheticG
62
+ * fixed WP_User_Query warning. props PatelUtkarsh
63
+ * added Chinese translation. props iwillhappy1314
64
+
65
  = 1.6.4 =
66
  * added Danish translation. props phh
67
  * updated Swedish translation. props EyesX
vendor/mustache/mustache/.php_cs ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ use Symfony\CS\Config\Config;
4
+ use Symfony\CS\FixerInterface;
5
+
6
+ $config = Config::create()
7
+ // use symfony level and extra fixers:
8
+ ->level(Symfony\CS\FixerInterface::SYMFONY_LEVEL)
9
+ ->fixers(array(
10
+ '-concat_without_spaces',
11
+ '-pre_increment',
12
+ '-unalign_double_arrow',
13
+ '-unalign_equals',
14
+ 'align_double_arrow',
15
+ 'concat_with_spaces',
16
+ 'ordered_use',
17
+ 'strict',
18
+ ))
19
+ ->setUsingLinter(false);
20
+
21
+ $finder = $config->getFinder()
22
+ ->in('bin')
23
+ ->in('src')
24
+ ->in('test');
25
+
26
+ return $config;
vendor/mustache/mustache/.styleci.yml ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ preset: symfony
2
+
3
+ enabled:
4
+ - align_double_arrow
5
+ - concat_with_spaces
6
+ - ordered_use
7
+ - strict
8
+
9
+ disabled:
10
+ - concat_without_spaces
11
+ - pre_increment
12
+ - unalign_double_arrow
13
+ - unalign_equals
vendor/mustache/mustache/.travis.yml CHANGED
@@ -1,12 +1,19 @@
1
  language: php
 
 
 
 
 
 
 
 
2
  php:
3
  - 5.2
4
  - 5.3
5
  - 5.4
6
  - 5.5
7
  - 5.6
 
8
  - hhvm
9
 
10
- matrix:
11
- allow_failures:
12
- - php: hhvm # See https://github.com/facebook/hhvm/pull/1860
1
  language: php
2
+
3
+ install:
4
+ - curl http://get.sensiolabs.org/php-cs-fixer.phar -o php-cs-fixer.phar
5
+
6
+ script:
7
+ - phpunit
8
+ - if [[ `php -r "echo version_compare(PHP_VERSION, '5.3.6', '>=') && !defined('HHVM_VERSION');"` ]]; then php php-cs-fixer.phar --diff --dry-run -vv fix; fi
9
+
10
  php:
11
  - 5.2
12
  - 5.3
13
  - 5.4
14
  - 5.5
15
  - 5.6
16
+ - 7.0
17
  - hhvm
18
 
19
+ sudo: false
 
 
vendor/mustache/mustache/CONTRIBUTING.md CHANGED
@@ -5,13 +5,15 @@
5
 
6
  1. [Fork the repo on GitHub](https://github.com/bobthecow/mustache.php).
7
 
8
- 2. Run the test suite. We only take pull requests with passing tests, and it's great to know that you have a clean slate. Make sure you have PHPUnit 3.5+, then run `phpunit` from the project directory.
9
 
10
- 3. Add tests for your change. Only refactoring and documentation changes require no new tests. If you are adding functionality or fixing a bug, add a test!
11
 
12
- 4. Make the tests pass.
13
 
14
- 5. Push your fork to GitHub and submit a pull request against the `dev` branch.
 
 
15
 
16
 
17
  ### You can do some things to increase the chance that your pull request is accepted the first time:
5
 
6
  1. [Fork the repo on GitHub](https://github.com/bobthecow/mustache.php).
7
 
8
+ 2. Update submodules: `git submodule update --init`
9
 
10
+ 3. Run the test suite. We only take pull requests with passing tests, and it's great to know that you have a clean slate. Make sure you have PHPUnit 3.5+, then run `phpunit` from the project directory.
11
 
12
+ 4. Add tests for your change. Only refactoring and documentation changes require no new tests. If you are adding functionality or fixing a bug, add a test!
13
 
14
+ 5. Make the tests pass.
15
+
16
+ 6. Push your fork to GitHub and submit a pull request against the `dev` branch.
17
 
18
 
19
  ### You can do some things to increase the chance that your pull request is accepted the first time:
vendor/mustache/mustache/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
  The MIT License (MIT)
2
 
3
- Copyright (c) 2010-2014 Justin Hileman
4
 
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
  of this software and associated documentation files (the "Software"), to deal
1
  The MIT License (MIT)
2
 
3
+ Copyright (c) 2010-2015 Justin Hileman
4
 
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
  of this software and associated documentation files (the "Software"), to deal
vendor/mustache/mustache/README.md CHANGED
@@ -3,9 +3,9 @@ Mustache.php
3
 
4
  A [Mustache](http://mustache.github.com/) implementation in PHP.
5
 
6
- [![Package version](http://img.shields.io/packagist/v/mustache/mustache.svg)](https://packagist.org/packages/mustache/mustache)
7
- [![Build status](http://img.shields.io/travis/bobthecow/mustache.php/dev.svg)](http://travis-ci.org/bobthecow/mustache.php)
8
- [![Monthly downloads](http://img.shields.io/packagist/dm/mustache/mustache.svg)](https://packagist.org/packages/mustache/mustache)
9
 
10
 
11
  Usage
@@ -24,9 +24,9 @@ And a more in-depth example -- this is the canonical Mustache template:
24
 
25
  ```html+jinja
26
  Hello {{name}}
27
- You have just won ${{value}}!
28
  {{#in_ca}}
29
- Well, ${{taxed_value}}, after taxes.
30
  {{/in_ca}}
31
  ```
32
 
3
 
4
  A [Mustache](http://mustache.github.com/) implementation in PHP.
5
 
6
+ [![Package version](http://img.shields.io/packagist/v/mustache/mustache.svg?style=flat-square)](https://packagist.org/packages/mustache/mustache)
7
+ [![Build status](http://img.shields.io/travis/bobthecow/mustache.php/dev.svg?style=flat-square)](http://travis-ci.org/bobthecow/mustache.php)
8
+ [![Monthly downloads](http://img.shields.io/packagist/dm/mustache/mustache.svg?style=flat-square)](https://packagist.org/packages/mustache/mustache)
9
 
10
 
11
  Usage
24
 
25
  ```html+jinja
26
  Hello {{name}}
27
+ You have just won {{value}} dollars!
28
  {{#in_ca}}
29
+ Well, {{taxed_value}} dollars, after taxes.
30
  {{/in_ca}}
31
  ```
32
 
vendor/mustache/mustache/composer.json CHANGED
@@ -16,7 +16,8 @@
16
  "php": ">=5.2.4"
17
  },
18
  "require-dev": {
19
- "phpunit/phpunit": "*"
 
20
  },
21
  "autoload": {
22
  "psr-0": { "Mustache": "src/" }
16
  "php": ">=5.2.4"
17
  },
18
  "require-dev": {
19
+ "phpunit/phpunit": "~3.7|~4.0",
20
+ "fabpot/php-cs-fixer": "~1.6"
21
  },
22
  "autoload": {
23
  "psr-0": { "Mustache": "src/" }
vendor/mustache/mustache/src/Mustache/Autoloader.php CHANGED
@@ -3,7 +3,7 @@
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
- * (c) 2010-2014 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
@@ -24,7 +24,7 @@ class Mustache_Autoloader
24
  public function __construct($baseDir = null)
25
  {
26
  if ($baseDir === null) {
27
- $baseDir = dirname(__FILE__).'/..';
28
  }
29
 
30
  // realpath doesn't always work, for example, with stream URIs
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
+ * (c) 2010-2015 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
24
  public function __construct($baseDir = null)
25
  {
26
  if ($baseDir === null) {
27
+ $baseDir = dirname(__FILE__) . '/..';
28
  }
29
 
30
  // realpath doesn't always work, for example, with stream URIs
vendor/mustache/mustache/src/Mustache/Cache.php CHANGED
@@ -3,7 +3,7 @@
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
- * (c) 2010-2014 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
@@ -22,7 +22,7 @@ interface Mustache_Cache
22
  *
23
  * @param string $key
24
  *
25
- * @return boolean indicates successfully class load
26
  */
27
  public function load($key);
28
 
@@ -31,8 +31,6 @@ interface Mustache_Cache
31
  *
32
  * @param string $key
33
  * @param string $value
34
- *
35
- * @return void
36
  */
37
  public function cache($key, $value);
38
  }
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
+ * (c) 2010-2015 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
22
  *
23
  * @param string $key
24
  *
25
+ * @return bool indicates successfully class load
26
  */
27
  public function load($key);
28
 
31
  *
32
  * @param string $key
33
  * @param string $value
 
 
34
  */
35
  public function cache($key, $value);
36
  }
vendor/mustache/mustache/src/Mustache/Cache/AbstractCache.php CHANGED
@@ -3,7 +3,7 @@
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
- * (c) 2010-2014 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
@@ -47,9 +47,9 @@ abstract class Mustache_Cache_AbstractCache implements Mustache_Cache
47
  /**
48
  * Add a log record if logging is enabled.
49
  *
50
- * @param integer $level The logging level
51
- * @param string $message The log message
52
- * @param array $context The log context
53
  */
54
  protected function log($level, $message, array $context = array())
55
  {
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
+ * (c) 2010-2015 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
47
  /**
48
  * Add a log record if logging is enabled.
49
  *
50
+ * @param int $level The logging level
51
+ * @param string $message The log message
52
+ * @param array $context The log context
53
  */
54
  protected function log($level, $message, array $context = array())
55
  {
vendor/mustache/mustache/src/Mustache/Cache/FilesystemCache.php CHANGED
@@ -3,7 +3,7 @@
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
- * (c) 2010-2014 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
@@ -41,7 +41,7 @@ class Mustache_Cache_FilesystemCache extends Mustache_Cache_AbstractCache
41
  *
42
  * @param string $key
43
  *
44
- * @return boolean
45
  */
46
  public function load($key)
47
  {
@@ -56,12 +56,10 @@ class Mustache_Cache_FilesystemCache extends Mustache_Cache_AbstractCache
56
  }
57
 
58
  /**
59
- * Cache and load the compiled class
60
  *
61
  * @param string $key
62
  * @param string $value
63
- *
64
- * @return void
65
  */
66
  public function cache($key, $value)
67
  {
@@ -91,7 +89,7 @@ class Mustache_Cache_FilesystemCache extends Mustache_Cache_AbstractCache
91
  }
92
 
93
  /**
94
- * Create cache directory
95
  *
96
  * @throws Mustache_Exception_RuntimeException If unable to create directory
97
  *
@@ -119,14 +117,12 @@ class Mustache_Cache_FilesystemCache extends Mustache_Cache_AbstractCache
119
  }
120
 
121
  /**
122
- * Write cache file
123
  *
124
  * @throws Mustache_Exception_RuntimeException If unable to write file
125
  *
126
  * @param string $fileName
127
  * @param string $value
128
- *
129
- * @return void
130
  */
131
  private function writeFile($fileName, $value)
132
  {
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
+ * (c) 2010-2015 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
41
  *
42
  * @param string $key
43
  *
44
+ * @return bool
45
  */
46
  public function load($key)
47
  {
56
  }
57
 
58
  /**
59
+ * Cache and load the compiled class.
60
  *
61
  * @param string $key
62
  * @param string $value
 
 
63
  */
64
  public function cache($key, $value)
65
  {
89
  }
90
 
91
  /**
92
+ * Create cache directory.
93
  *
94
  * @throws Mustache_Exception_RuntimeException If unable to create directory
95
  *
117
  }
118
 
119
  /**
120
+ * Write cache file.
121
  *
122
  * @throws Mustache_Exception_RuntimeException If unable to write file
123
  *
124
  * @param string $fileName
125
  * @param string $value
 
 
126
  */
127
  private function writeFile($fileName, $value)
128
  {
vendor/mustache/mustache/src/Mustache/Cache/NoopCache.php CHANGED
@@ -3,7 +3,7 @@
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
- * (c) 2010-2014 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
@@ -22,7 +22,7 @@ class Mustache_Cache_NoopCache extends Mustache_Cache_AbstractCache
22
  *
23
  * @param string $key
24
  *
25
- * @return boolean
26
  */
27
  public function load($key)
28
  {
@@ -34,8 +34,6 @@ class Mustache_Cache_NoopCache extends Mustache_Cache_AbstractCache
34
  *
35
  * @param string $key
36
  * @param string $value
37
- *
38
- * @return void
39
  */
40
  public function cache($key, $value)
41
  {
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
+ * (c) 2010-2015 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
22
  *
23
  * @param string $key
24
  *
25
+ * @return bool
26
  */
27
  public function load($key)
28
  {
34
  *
35
  * @param string $key
36
  * @param string $value
 
 
37
  */
38
  public function cache($key, $value)
39
  {
vendor/mustache/mustache/src/Mustache/Compiler.php CHANGED
@@ -3,7 +3,7 @@
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
- * (c) 2010-2014 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
@@ -16,14 +16,16 @@
16
  */
17
  class Mustache_Compiler
18
  {
 
 
19
  private $sections;
 
20
  private $source;
21
  private $indentNextLine;
22
  private $customEscape;
23
  private $entityFlags;
24
  private $charset;
25
  private $strictCallables;
26
- private $pragmas;
27
 
28
  /**
29
  * Compile a Mustache token parse tree into PHP source code.
@@ -40,8 +42,9 @@ class Mustache_Compiler
40
  */
41
  public function compile($source, array $tree, $name, $customEscape = false, $charset = 'UTF-8', $strictCallables = false, $entityFlags = ENT_COMPAT)
42
  {
43
- $this->pragmas = array();
44
  $this->sections = array();
 
45
  $this->source = $source;
46
  $this->indentNextLine = true;
47
  $this->customEscape = $customEscape;
@@ -52,6 +55,23 @@ class Mustache_Compiler
52
  return $this->writeCode($tree, $name);
53
  }
54
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  /**
56
  * Helper function for walking the Mustache token parse tree.
57
  *
@@ -76,6 +96,7 @@ class Mustache_Compiler
76
  $code .= $this->section(
77
  $node[Mustache_Tokenizer::NODES],
78
  $node[Mustache_Tokenizer::NAME],
 
79
  $node[Mustache_Tokenizer::INDEX],
80
  $node[Mustache_Tokenizer::END],
81
  $node[Mustache_Tokenizer::OTAG],
@@ -88,12 +109,12 @@ class Mustache_Compiler
88
  $code .= $this->invertedSection(
89
  $node[Mustache_Tokenizer::NODES],
90
  $node[Mustache_Tokenizer::NAME],
 
91
  $level
92
  );
93
  break;
94
 
95
  case Mustache_Tokenizer::T_PARTIAL:
96
- case Mustache_Tokenizer::T_PARTIAL_2:
97
  $code .= $this->partial(
98
  $node[Mustache_Tokenizer::NAME],
99
  isset($node[Mustache_Tokenizer::INDENT]) ? $node[Mustache_Tokenizer::INDENT] : '',
@@ -101,16 +122,51 @@ class Mustache_Compiler
101
  );
102
  break;
103
 
104
- case Mustache_Tokenizer::T_UNESCAPED:
105
- case Mustache_Tokenizer::T_UNESCAPED_2:
106
- $code .= $this->variable($node[Mustache_Tokenizer::NAME], false, $level);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
  break;
108
 
109
  case Mustache_Tokenizer::T_COMMENT:
110
  break;
111
 
112
  case Mustache_Tokenizer::T_ESCAPED:
113
- $code .= $this->variable($node[Mustache_Tokenizer::NAME], true, $level);
 
 
 
 
 
 
 
114
  break;
115
 
116
  case Mustache_Tokenizer::T_TEXT:
@@ -135,11 +191,13 @@ class Mustache_Compiler
135
  {
136
  $this->lambdaHelper = new Mustache_LambdaHelper($this->mustache, $context);
137
  $buffer = \'\';
 
138
  %s
139
 
140
  return $buffer;
141
  }
142
  %s
 
143
  }';
144
 
145
  const KLASS_NO_LAMBDAS = '<?php
@@ -149,6 +207,7 @@ class Mustache_Compiler
149
  public function renderInternal(Mustache_Context $context, $indent = \'\')
150
  {
151
  $buffer = \'\';
 
152
  %s
153
 
154
  return $buffer;
@@ -169,10 +228,92 @@ class Mustache_Compiler
169
  {
170
  $code = $this->walk($tree);
171
  $sections = implode("\n", $this->sections);
172
- $klass = empty($this->sections) ? self::KLASS_NO_LAMBDAS : self::KLASS;
 
 
173
  $callable = $this->strictCallables ? $this->prepare(self::STRICT_CALLABLE) : '';
174
 
175
- return sprintf($this->prepare($klass, 0, false, true), $name, $callable, $code, $sections);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
  }
177
 
178
  const SECTION_CALL = '
@@ -198,53 +339,57 @@ class Mustache_Compiler
198
  } elseif (!empty($value)) {
199
  $values = $this->isIterable($value) ? $value : array($value);
200
  foreach ($values as $value) {
201
- $context->push($value);%s
 
202
  $context->pop();
203
  }
204
  }
205
 
206
  return $buffer;
207
- }';
 
208
 
209
  /**
210
  * Generate Mustache Template section PHP source.
211
  *
212
- * @param array $nodes Array of child tokens
213
- * @param string $id Section name
214
- * @param int $start Section start offset
215
- * @param int $end Section end offset
216
- * @param string $otag Current Mustache opening tag
217
- * @param string $ctag Current Mustache closing tag
218
- * @param int $level
 
 
219
  *
220
  * @return string Generated section PHP source code
221
  */
222
- private function section($nodes, $id, $start, $end, $otag, $ctag, $level)
223
  {
224
- $filters = '';
225
-
226
- if (isset($this->pragmas[Mustache_Engine::PRAGMA_FILTERS])) {
227
- list($id, $filters) = $this->getFilters($id, $level);
228
- }
229
-
230
- $method = $this->getFindMethod($id);
231
- $id = var_export($id, true);
232
  $source = var_export(substr($this->source, $start, $end - $start), true);
233
  $callable = $this->getCallable();
234
 
235
  if ($otag !== '{{' || $ctag !== '}}') {
236
- $delims = ', '.var_export(sprintf('{{= %s %s =}}', $otag, $ctag), true);
237
  } else {
238
  $delims = '';
239
  }
240
 
241
- $key = ucfirst(md5($delims."\n".$source));
242
 
243
  if (!isset($this->sections[$key])) {
244
  $this->sections[$key] = sprintf($this->prepare(self::SECTION), $key, $callable, $source, $delims, $this->walk($nodes, 2));
245
  }
246
 
247
- return sprintf($this->prepare(self::SECTION_CALL, $level), $id, $method, $id, $filters, $key);
 
 
 
 
 
 
 
 
248
  }
249
 
250
  const INVERTED_SECTION = '
@@ -252,34 +397,32 @@ class Mustache_Compiler
252
  $value = $context->%s(%s);%s
253
  if (empty($value)) {
254
  %s
255
- }';
 
256
 
257
  /**
258
  * Generate Mustache Template inverted section PHP source.
259
  *
260
- * @param array $nodes Array of child tokens
261
- * @param string $id Section name
262
- * @param int $level
 
263
  *
264
  * @return string Generated inverted section PHP source code
265
  */
266
- private function invertedSection($nodes, $id, $level)
267
  {
268
- $filters = '';
269
-
270
- if (isset($this->pragmas[Mustache_Engine::PRAGMA_FILTERS])) {
271
- list($id, $filters) = $this->getFilters($id, $level);
272
- }
273
-
274
- $method = $this->getFindMethod($id);
275
- $id = var_export($id, true);
276
 
277
  return sprintf($this->prepare(self::INVERTED_SECTION, $level), $id, $method, $id, $filters, $this->walk($nodes, $level));
278
  }
279
 
 
280
  const PARTIAL = '
281
  if ($partial = $this->mustache->loadPartial(%s)) {
282
- $buffer .= $partial->renderInternal($context, $indent . %s);
283
  }
284
  ';
285
 
@@ -294,56 +437,86 @@ class Mustache_Compiler
294
  */
295
  private function partial($id, $indent, $level)
296
  {
 
 
 
 
 
 
297
  return sprintf(
298
  $this->prepare(self::PARTIAL, $level),
299
  var_export($id, true),
300
- var_export($indent, true)
301
  );
302
  }
303
 
304
- const VARIABLE = '
305
- $value = $this->resolveValue($context->%s(%s), $context, $indent);%s
306
- $buffer .= %s%s;
 
 
 
 
 
307
  ';
308
 
309
  /**
310
- * Generate Mustache Template variable interpolation PHP source.
311
  *
312
- * @param string $id Variable name
313
- * @param boolean $escape Escape the variable value for output?
314
- * @param int $level
 
315
  *
316
- * @return string Generated variable interpolation PHP source
317
  */
318
- private function variable($id, $escape, $level)
319
  {
320
- $filters = '';
321
 
322
- if (isset($this->pragmas[Mustache_Engine::PRAGMA_FILTERS])) {
323
- list($id, $filters) = $this->getFilters($id, $level);
324
- }
325
-
326
- $method = $this->getFindMethod($id);
327
- $id = ($method !== 'last') ? var_export($id, true) : '';
328
- $value = $escape ? $this->getEscape() : '$value';
329
 
330
- return sprintf($this->prepare(self::VARIABLE, $level), $method, $id, $filters, $this->flushIndent(), $value);
 
 
 
 
 
 
 
 
 
331
  }
332
 
 
 
 
 
 
333
  /**
334
- * Generate Mustache Template variable filtering PHP source.
335
  *
336
- * @param string $id Variable name
337
- * @param int $level
 
 
338
  *
339
- * @return string Generated variable filtering PHP source
340
  */
341
- private function getFilters($id, $level)
342
  {
343
- $filters = array_map('trim', explode('|', $id));
344
- $id = array_shift($filters);
 
 
345
 
346
- return array($id, $this->getFilter($filters, $level));
347
  }
348
 
349
  const FILTER = '
@@ -355,14 +528,14 @@ class Mustache_Compiler
355
  ';
356
 
357
  /**
358
- * Generate PHP source for a single filter.
359
  *
360
- * @param array $filters
361
- * @param int $level
362
  *
363
  * @return string Generated filter PHP source
364
  */
365
- private function getFilter(array $filters, $level)
366
  {
367
  if (empty($filters)) {
368
  return '';
@@ -374,7 +547,7 @@ class Mustache_Compiler
374
  $callable = $this->getCallable('$filter');
375
  $msg = var_export($name, true);
376
 
377
- return sprintf($this->prepare(self::FILTER, $level), $method, $filter, $callable, $msg, $this->getFilter($filters, $level));
378
  }
379
 
380
  const LINE = '$buffer .= "\n";';
@@ -400,16 +573,16 @@ class Mustache_Compiler
400
  /**
401
  * Prepare PHP source code snippet for output.
402
  *
403
- * @param string $text
404
- * @param int $bonus Additional indent level (default: 0)
405
- * @param boolean $prependNewline Prepend a newline to the snippet? (default: true)
406
- * @param boolean $appendNewline Append a newline to the snippet? (default: false)
407
  *
408
  * @return string PHP source code snippet
409
  */
410
  private function prepare($text, $bonus = 0, $prependNewline = true, $appendNewline = false)
411
  {
412
- $text = ($prependNewline ? "\n" : '').trim($text);
413
  if ($prependNewline) {
414
  $bonus++;
415
  }
@@ -417,7 +590,7 @@ class Mustache_Compiler
417
  $text .= "\n";
418
  }
419
 
420
- return preg_replace("/\n( {8})?/", "\n".str_repeat(" ", $bonus * 4), $text);
421
  }
422
 
423
  const DEFAULT_ESCAPE = 'htmlspecialchars(%s, %s, %s)';
@@ -434,9 +607,9 @@ class Mustache_Compiler
434
  {
435
  if ($this->customEscape) {
436
  return sprintf(self::CUSTOM_ESCAPE, $value);
437
- } else {
438
- return sprintf(self::DEFAULT_ESCAPE, $value, var_export($this->entityFlags, true), var_export($this->charset, true));
439
  }
 
 
440
  }
441
 
442
  /**
@@ -456,16 +629,31 @@ class Mustache_Compiler
456
  {
457
  if ($id === '.') {
458
  return 'last';
459
- } elseif (strpos($id, '.') === false) {
 
 
 
 
 
 
 
 
460
  return 'find';
461
- } else {
462
- return 'findDot';
463
  }
 
 
464
  }
465
 
466
  const IS_CALLABLE = '!is_string(%s) && is_callable(%s)';
467
  const STRICT_IS_CALLABLE = 'is_object(%s) && is_callable(%s)';
468
 
 
 
 
 
 
 
 
469
  private function getCallable($variable = '$value')
470
  {
471
  $tpl = $this->strictCallables ? self::STRICT_IS_CALLABLE : self::IS_CALLABLE;
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
+ * (c) 2010-2015 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
16
  */
17
  class Mustache_Compiler
18
  {
19
+ private $pragmas;
20
+ private $defaultPragmas = array();
21
  private $sections;
22
+ private $blocks;
23
  private $source;
24
  private $indentNextLine;
25
  private $customEscape;
26
  private $entityFlags;
27
  private $charset;
28
  private $strictCallables;
 
29
 
30
  /**
31
  * Compile a Mustache token parse tree into PHP source code.
42
  */
43
  public function compile($source, array $tree, $name, $customEscape = false, $charset = 'UTF-8', $strictCallables = false, $entityFlags = ENT_COMPAT)
44
  {
45
+ $this->pragmas = $this->defaultPragmas;
46
  $this->sections = array();
47
+ $this->blocks = array();
48
  $this->source = $source;
49
  $this->indentNextLine = true;
50
  $this->customEscape = $customEscape;
55
  return $this->writeCode($tree, $name);
56
  }
57
 
58
+ /**
59
+ * Enable pragmas across all templates, regardless of the presence of pragma
60
+ * tags in the individual templates.
61
+ *
62
+ * @internal Users should set global pragmas in Mustache_Engine, not here :)
63
+ *
64
+ * @param string[] $pragmas
65
+ */
66
+ public function setPragmas(array $pragmas)
67
+ {
68
+ $this->pragmas = array();
69
+ foreach ($pragmas as $pragma) {
70
+ $this->pragmas[$pragma] = true;
71
+ }
72
+ $this->defaultPragmas = $this->pragmas;
73
+ }
74
+
75
  /**
76
  * Helper function for walking the Mustache token parse tree.
77
  *
96
  $code .= $this->section(
97
  $node[Mustache_Tokenizer::NODES],
98
  $node[Mustache_Tokenizer::NAME],
99
+ isset($node[Mustache_Tokenizer::FILTERS]) ? $node[Mustache_Tokenizer::FILTERS] : array(),
100
  $node[Mustache_Tokenizer::INDEX],
101
  $node[Mustache_Tokenizer::END],
102
  $node[Mustache_Tokenizer::OTAG],
109
  $code .= $this->invertedSection(
110
  $node[Mustache_Tokenizer::NODES],
111
  $node[Mustache_Tokenizer::NAME],
112
+ isset($node[Mustache_Tokenizer::FILTERS]) ? $node[Mustache_Tokenizer::FILTERS] : array(),
113
  $level
114
  );
115
  break;
116
 
117
  case Mustache_Tokenizer::T_PARTIAL:
 
118
  $code .= $this->partial(
119
  $node[Mustache_Tokenizer::NAME],
120
  isset($node[Mustache_Tokenizer::INDENT]) ? $node[Mustache_Tokenizer::INDENT] : '',
122
  );
123
  break;
124
 
125
+ case Mustache_Tokenizer::T_PARENT:
126
+ $code .= $this->parent(
127
+ $node[Mustache_Tokenizer::NAME],
128
+ isset($node[Mustache_Tokenizer::INDENT]) ? $node[Mustache_Tokenizer::INDENT] : '',
129
+ $node[Mustache_Tokenizer::NODES],
130
+ $level
131
+ );
132
+ break;
133
+
134
+ case Mustache_Tokenizer::T_BLOCK_ARG:
135
+ $code .= $this->blockArg(
136
+ $node[Mustache_Tokenizer::NODES],
137
+ $node[Mustache_Tokenizer::NAME],
138
+ $node[Mustache_Tokenizer::INDEX],
139
+ $node[Mustache_Tokenizer::END],
140
+ $node[Mustache_Tokenizer::OTAG],
141
+ $node[Mustache_Tokenizer::CTAG],
142
+ $level
143
+ );
144
+ break;
145
+
146
+ case Mustache_Tokenizer::T_BLOCK_VAR:
147
+ $code .= $this->blockVar(
148
+ $node[Mustache_Tokenizer::NODES],
149
+ $node[Mustache_Tokenizer::NAME],
150
+ $node[Mustache_Tokenizer::INDEX],
151
+ $node[Mustache_Tokenizer::END],
152
+ $node[Mustache_Tokenizer::OTAG],
153
+ $node[Mustache_Tokenizer::CTAG],
154
+ $level
155
+ );
156
  break;
157
 
158
  case Mustache_Tokenizer::T_COMMENT:
159
  break;
160
 
161
  case Mustache_Tokenizer::T_ESCAPED:
162
+ case Mustache_Tokenizer::T_UNESCAPED:
163
+ case Mustache_Tokenizer::T_UNESCAPED_2:
164
+ $code .= $this->variable(
165
+ $node[Mustache_Tokenizer::NAME],
166
+ isset($node[Mustache_Tokenizer::FILTERS]) ? $node[Mustache_Tokenizer::FILTERS] : array(),
167
+ $node[Mustache_Tokenizer::TYPE] === Mustache_Tokenizer::T_ESCAPED,
168
+ $level
169
+ );
170
  break;
171
 
172
  case Mustache_Tokenizer::T_TEXT:
191
  {
192
  $this->lambdaHelper = new Mustache_LambdaHelper($this->mustache, $context);
193
  $buffer = \'\';
194
+ $newContext = array();
195
  %s
196
 
197
  return $buffer;
198
  }
199
  %s
200
+ %s
201
  }';
202
 
203
  const KLASS_NO_LAMBDAS = '<?php
207
  public function renderInternal(Mustache_Context $context, $indent = \'\')
208
  {
209
  $buffer = \'\';
210
+ $newContext = array();
211
  %s
212
 
213
  return $buffer;
228
  {
229
  $code = $this->walk($tree);
230
  $sections = implode("\n", $this->sections);
231
+ $blocks = implode("\n", $this->blocks);
232
+ $klass = empty($this->sections) && empty($this->blocks) ? self::KLASS_NO_LAMBDAS : self::KLASS;
233
+
234
  $callable = $this->strictCallables ? $this->prepare(self::STRICT_CALLABLE) : '';
235
 
236
+ return sprintf($this->prepare($klass, 0, false, true), $name, $callable, $code, $sections, $blocks);
237
+ }
238
+
239
+ const BLOCK_VAR = '
240
+ $blockFunction = $context->findInBlock(%s);
241
+ if (is_callable($blockFunction)) {
242
+ $buffer .= call_user_func($blockFunction, $context);
243
+ } else {%s
244
+ }
245
+ ';
246
+
247
+ /**
248
+ * Generate Mustache Template inheritance block variable PHP source.
249
+ *
250
+ * @param array $nodes Array of child tokens
251
+ * @param string $id Section name
252
+ * @param int $start Section start offset
253
+ * @param int $end Section end offset
254
+ * @param string $otag Current Mustache opening tag
255
+ * @param string $ctag Current Mustache closing tag
256
+ * @param int $level
257
+ *
258
+ * @return string Generated PHP source code
259
+ */
260
+ private function blockVar($nodes, $id, $start, $end, $otag, $ctag, $level)
261
+ {
262
+ $id = var_export($id, true);
263
+
264
+ return sprintf($this->prepare(self::BLOCK_VAR, $level), $id, $this->walk($nodes, $level));
265
+ }
266
+
267
+ const BLOCK_ARG = '$newContext[%s] = array($this, \'block%s\');';
268
+
269
+ /**
270
+ * Generate Mustache Template inheritance block argument PHP source.
271
+ *
272
+ * @param array $nodes Array of child tokens
273
+ * @param string $id Section name
274
+ * @param int $start Section start offset
275
+ * @param int $end Section end offset
276
+ * @param string $otag Current Mustache opening tag
277
+ * @param string $ctag Current Mustache closing tag
278
+ * @param int $level
279
+ *
280
+ * @return string Generated PHP source code
281
+ */
282
+ private function blockArg($nodes, $id, $start, $end, $otag, $ctag, $level)
283
+ {
284
+ $key = $this->block($nodes);
285
+ $keystr = var_export($key, true);
286
+ $id = var_export($id, true);
287
+
288
+ return sprintf($this->prepare(self::BLOCK_ARG, 1), $id, $key);
289
+ }
290
+
291
+ const BLOCK_FUNCTION = '
292
+ public function block%s($context)
293
+ {
294
+ $indent = $buffer = \'\';%s
295
+
296
+ return $buffer;
297
+ }
298
+ ';
299
+
300
+ /**
301
+ * Generate Mustache Template inheritance block function PHP source.
302
+ *
303
+ * @param array $nodes Array of child tokens
304
+ *
305
+ * @return string key of new block function
306
+ */
307
+ private function block($nodes)
308
+ {
309
+ $code = $this->walk($nodes, 0);
310
+ $key = ucfirst(md5($code));
311
+
312
+ if (!isset($this->blocks[$key])) {
313
+ $this->blocks[$key] = sprintf($this->prepare(self::BLOCK_FUNCTION, 0), $key, $code);
314
+ }
315
+
316
+ return $key;
317
  }
318
 
319
  const SECTION_CALL = '
339
  } elseif (!empty($value)) {
340
  $values = $this->isIterable($value) ? $value : array($value);
341
  foreach ($values as $value) {
342
+ $context->push($value);
343
+ %s
344
  $context->pop();
345
  }
346
  }
347
 
348
  return $buffer;
349
+ }
350
+ ';
351
 
352
  /**
353
  * Generate Mustache Template section PHP source.
354
  *
355
+ * @param array $nodes Array of child tokens
356
+ * @param string $id Section name
357
+ * @param string[] $filters Array of filters
358
+ * @param int $start Section start offset
359
+ * @param int $end Section end offset
360
+ * @param string $otag Current Mustache opening tag
361
+ * @param string $ctag Current Mustache closing tag
362
+ * @param int $level
363
+ * @param bool $arg (default: false)
364
  *
365
  * @return string Generated section PHP source code
366
  */
367
+ private function section($nodes, $id, $filters, $start, $end, $otag, $ctag, $level, $arg = false)
368
  {
 
 
 
 
 
 
 
 
369
  $source = var_export(substr($this->source, $start, $end - $start), true);
370
  $callable = $this->getCallable();
371
 
372
  if ($otag !== '{{' || $ctag !== '}}') {
373
+ $delims = ', ' . var_export(sprintf('{{= %s %s =}}', $otag, $ctag), true);
374
  } else {
375
  $delims = '';
376
  }
377
 
378
+ $key = ucfirst(md5($delims . "\n" . $source));
379
 
380
  if (!isset($this->sections[$key])) {
381
  $this->sections[$key] = sprintf($this->prepare(self::SECTION), $key, $callable, $source, $delims, $this->walk($nodes, 2));
382
  }
383
 
384
+ if ($arg === true) {
385
+ return $key;
386
+ } else {
387
+ $method = $this->getFindMethod($id);
388
+ $id = var_export($id, true);
389
+ $filters = $this->getFilters($filters, $level);
390
+
391
+ return sprintf($this->prepare(self::SECTION_CALL, $level), $id, $method, $id, $filters, $key);
392
+ }
393
  }
394
 
395
  const INVERTED_SECTION = '
397
  $value = $context->%s(%s);%s
398
  if (empty($value)) {
399
  %s
400
+ }
401
+ ';
402
 
403
  /**
404
  * Generate Mustache Template inverted section PHP source.
405
  *
406
+ * @param array $nodes Array of child tokens
407
+ * @param string $id Section name
408
+ * @param string[] $filters Array of filters
409
+ * @param int $level
410
  *
411
  * @return string Generated inverted section PHP source code
412
  */
413
+ private function invertedSection($nodes, $id, $filters, $level)
414
  {
415
+ $method = $this->getFindMethod($id);
416
+ $id = var_export($id, true);
417
+ $filters = $this->getFilters($filters, $level);
 
 
 
 
 
418
 
419
  return sprintf($this->prepare(self::INVERTED_SECTION, $level), $id, $method, $id, $filters, $this->walk($nodes, $level));
420
  }
421
 
422
+ const PARTIAL_INDENT = ', $indent . %s';
423
  const PARTIAL = '
424
  if ($partial = $this->mustache->loadPartial(%s)) {
425
+ $buffer .= $partial->renderInternal($context%s);
426
  }
427
  ';
428
 
437
  */
438
  private function partial($id, $indent, $level)
439
  {
440
+ if ($indent !== '') {
441
+ $indentParam = sprintf(self::PARTIAL_INDENT, var_export($indent, true));
442
+ } else {
443
+ $indentParam = '';
444
+ }
445
+
446
  return sprintf(
447
  $this->prepare(self::PARTIAL, $level),
448
  var_export($id, true),
449
+ $indentParam
450
  );
451
  }
452
 
453
+ const PARENT = '
454
+ %s
455
+
456
+ if ($parent = $this->mustache->LoadPartial(%s)) {
457
+ $context->pushBlockContext($newContext);
458
+ $buffer .= $parent->renderInternal($context, $indent);
459
+ $context->popBlockContext();
460
+ }
461
  ';
462
 
463
  /**
464
+ * Generate Mustache Template inheritance parent call PHP source.
465
  *
466
+ * @param string $id Parent tag name
467
+ * @param string $indent Whitespace indent to apply to parent
468
+ * @param array $children Child nodes
469
+ * @param int $level
470
  *
471
+ * @return string Generated PHP source code
472
  */
473
+ private function parent($id, $indent, array $children, $level)
474
  {
475
+ $realChildren = array_filter($children, array(__CLASS__, 'onlyBlockArgs'));
476
 
477
+ return sprintf(
478
+ $this->prepare(self::PARENT, $level),
479
+ $this->walk($realChildren, $level),
480
+ var_export($id, true),
481
+ var_export($indent, true)
482
+ );
483
+ }
484
 
485
+ /**
486
+ * Helper method for filtering out non-block-arg tokens.
487
+ *
488
+ * @param array $node
489
+ *
490
+ * @return bool True if $node is a block arg token.
491
+ */
492
+ private static function onlyBlockArgs(array $node)
493
+ {
494
+ return $node[Mustache_Tokenizer::TYPE] === Mustache_Tokenizer::T_BLOCK_ARG;
495
  }
496
 
497
+ const VARIABLE = '
498
+ $value = $this->resolveValue($context->%s(%s), $context, $indent);%s
499
+ $buffer .= %s%s;
500
+ ';
501
+
502
  /**
503
+ * Generate Mustache Template variable interpolation PHP source.
504
  *
505
+ * @param string $id Variable name
506
+ * @param string[] $filters Array of filters
507
+ * @param bool $escape Escape the variable value for output?
508
+ * @param int $level
509
  *
510
+ * @return string Generated variable interpolation PHP source
511
  */
512
+ private function variable($id, $filters, $escape, $level)
513
  {
514
+ $method = $this->getFindMethod($id);
515
+ $id = ($method !== 'last') ? var_export($id, true) : '';
516
+ $filters = $this->getFilters($filters, $level);
517
+ $value = $escape ? $this->getEscape() : '$value';
518
 
519
+ return sprintf($this->prepare(self::VARIABLE, $level), $method, $id, $filters, $this->flushIndent(), $value);
520
  }
521
 
522
  const FILTER = '
528
  ';
529
 
530
  /**
531
+ * Generate Mustache Template variable filtering PHP source.
532
  *
533
+ * @param string[] $filters Array of filters
534
+ * @param int $level
535
  *
536
  * @return string Generated filter PHP source
537
  */
538
+ private function getFilters(array $filters, $level)
539
  {
540
  if (empty($filters)) {
541
  return '';
547
  $callable = $this->getCallable('$filter');
548
  $msg = var_export($name, true);
549
 
550
+ return sprintf($this->prepare(self::FILTER, $level), $method, $filter, $callable, $msg, $this->getFilters($filters, $level));
551
  }
552
 
553
  const LINE = '$buffer .= "\n";';
573
  /**
574
  * Prepare PHP source code snippet for output.
575
  *
576
+ * @param string $text
577
+ * @param int $bonus Additional indent level (default: 0)
578
+ * @param bool $prependNewline Prepend a newline to the snippet? (default: true)
579
+ * @param bool $appendNewline Append a newline to the snippet? (default: false)
580
  *
581
  * @return string PHP source code snippet
582
  */
583
  private function prepare($text, $bonus = 0, $prependNewline = true, $appendNewline = false)
584
  {
585
+ $text = ($prependNewline ? "\n" : '') . trim($text);
586
  if ($prependNewline) {
587
  $bonus++;
588
  }
590
  $text .= "\n";
591
  }
592
 
593
+ return preg_replace("/\n( {8})?/", "\n" . str_repeat(' ', $bonus * 4), $text);
594
  }
595
 
596
  const DEFAULT_ESCAPE = 'htmlspecialchars(%s, %s, %s)';
607
  {
608
  if ($this->customEscape) {
609
  return sprintf(self::CUSTOM_ESCAPE, $value);
 
 
610
  }
611
+
612
+ return sprintf(self::DEFAULT_ESCAPE, $value, var_export($this->entityFlags, true), var_export($this->charset, true));
613
  }
614
 
615
  /**
629
  {
630
  if ($id === '.') {
631
  return 'last';
632
+ }
633
+
634
+ if (isset($this->pragmas[Mustache_Engine::PRAGMA_ANCHORED_DOT]) && $this->pragmas[Mustache_Engine::PRAGMA_ANCHORED_DOT]) {
635
+ if (substr($id, 0, 1) === '.') {
636
+ return 'findAnchoredDot';
637
+ }
638
+ }
639
+
640
+ if (strpos($id, '.') === false) {
641
  return 'find';
 
 
642
  }
643
+
644
+ return 'findDot';
645
  }
646
 
647
  const IS_CALLABLE = '!is_string(%s) && is_callable(%s)';
648
  const STRICT_IS_CALLABLE = 'is_object(%s) && is_callable(%s)';
649
 
650
+ /**
651
+ * Helper function to compile strict vs lax "is callable" logic.
652
+ *
653
+ * @param string $variable (default: '$value')
654
+ *
655
+ * @return string "is callable" logic
656
+ */
657
  private function getCallable($variable = '$value')
658
  {
659
  $tpl = $this->strictCallables ? self::STRICT_IS_CALLABLE : self::IS_CALLABLE;
vendor/mustache/mustache/src/Mustache/Context.php CHANGED
@@ -3,7 +3,7 @@
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
- * (c) 2010-2014 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
@@ -14,7 +14,8 @@
14
  */
15
  class Mustache_Context
16
  {
17
- private $stack = array();
 
18
 
19
  /**
20
  * Mustache rendering Context constructor.
@@ -38,6 +39,16 @@ class Mustache_Context
38
  array_push($this->stack, $value);
39
  }
40
 
 
 
 
 
 
 
 
 
 
 
41
  /**
42
  * Pop the last Context frame from the stack.
43
  *
@@ -48,6 +59,16 @@ class Mustache_Context
48
  return array_pop($this->stack);
49
  }
50
 
 
 
 
 
 
 
 
 
 
 
51
  /**
52
  * Get the last Context frame.
53
  *
@@ -120,6 +141,60 @@ class Mustache_Context
120
  return $value;
121
  }
122
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  /**
124
  * Helper function to find a variable in the Context stack.
125
  *
@@ -133,19 +208,32 @@ class Mustache_Context
133
  private function findVariableInStack($id, array $stack)
134
  {
135
  for ($i = count($stack) - 1; $i >= 0; $i--) {
136
- if (is_object($stack[$i]) && !($stack[$i] instanceof Closure)) {
137
-
138
- // Note that is_callable() *will not work here*
139
- // See https://github.com/bobthecow/mustache.php/wiki/Magic-Methods
140
- if (method_exists($stack[$i], $id)) {
141
- return $stack[$i]->$id();
142
- } elseif (isset($stack[$i]->$id)) {
143
- return $stack[$i]->$id;
144
- } elseif ($stack[$i] instanceof ArrayAccess && isset($stack[$i][$id])) {
145
- return $stack[$i][$id];
146
- }
147
- } elseif (is_array($stack[$i]) && array_key_exists($id, $stack[$i])) {
148
- return $stack[$i][$id];
 
 
 
 
 
 
 
 
 
 
 
 
 
149
  }
150
  }
151
 
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
+ * (c) 2010-2015 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
14
  */
15
  class Mustache_Context
16
  {
17
+ private $stack = array();
18
+ private $blockStack = array();
19
 
20
  /**
21
  * Mustache rendering Context constructor.
39
  array_push($this->stack, $value);
40
  }
41
 
42
+ /**
43
+ * Push a new Context frame onto the block context stack.
44
+ *
45
+ * @param mixed $value Object or array to use for block context
46
+ */
47
+ public function pushBlockContext($value)
48
+ {
49
+ array_push($this->blockStack, $value);
50
+ }
51
+
52
  /**
53
  * Pop the last Context frame from the stack.
54
  *
59
  return array_pop($this->stack);
60
  }
61
 
62
+ /**
63
+ * Pop the last block Context frame from the stack.
64
+ *
65
+ * @return mixed Last block Context frame (object or array)
66
+ */
67
+ public function popBlockContext()
68
+ {
69
+ return array_pop($this->blockStack);
70
+ }
71
+
72
  /**
73
  * Get the last Context frame.
74
  *
141
  return $value;
142
  }
143
 
144
+ /**
145
+ * Find an 'anchored dot notation' variable in the Context stack.
146
+ *
147
+ * This is the same as findDot(), except it looks in the top of the context
148
+ * stack for the first value, rather than searching the whole context stack
149
+ * and starting from there.
150
+ *
151
+ * @see Mustache_Context::findDot
152
+ *
153
+ * @throws Mustache_Exception_InvalidArgumentException if given an invalid anchored dot $id.
154
+ *
155
+ * @param string $id Dotted variable selector
156
+ *
157
+ * @return mixed Variable value, or '' if not found
158
+ */
159
+ public function findAnchoredDot($id)
160
+ {
161
+ $chunks = explode('.', $id);
162
+ $first = array_shift($chunks);
163
+ if ($first !== '') {
164
+ throw new Mustache_Exception_InvalidArgumentException(sprintf('Unexpected id for findAnchoredDot: %s', $id));
165
+ }
166
+
167
+ $value = $this->last();
168
+
169
+ foreach ($chunks as $chunk) {
170
+ if ($value === '') {
171
+ return $value;
172
+ }
173
+
174
+ $value = $this->findVariableInStack($chunk, array($value));
175
+ }
176
+
177
+ return $value;
178
+ }
179
+
180
+ /**
181
+ * Find an argument in the block context stack.
182
+ *
183
+ * @param string $id
184
+ *
185
+ * @return mixed Variable value, or '' if not found.
186
+ */
187
+ public function findInBlock($id)
188
+ {
189
+ foreach ($this->blockStack as $context) {
190
+ if (array_key_exists($id, $context)) {
191
+ return $context[$id];
192
+ }
193
+ }
194
+
195
+ return '';
196
+ }
197
+
198
  /**
199
  * Helper function to find a variable in the Context stack.
200
  *
208
  private function findVariableInStack($id, array $stack)
209
  {
210
  for ($i = count($stack) - 1; $i >= 0; $i--) {
211
+ $frame = &$stack[$i];
212
+
213
+ switch (gettype($frame)) {
214
+ case 'object':
215
+ if (!($frame instanceof Closure)) {
216
+ // Note that is_callable() *will not work here*
217
+ // See https://github.com/bobthecow/mustache.php/wiki/Magic-Methods
218
+ if (method_exists($frame, $id)) {
219
+ return $frame->$id();
220
+ }
221
+
222
+ if (isset($frame->$id)) {
223
+ return $frame->$id;
224
+ }
225
+
226
+ if ($frame instanceof ArrayAccess && isset($frame[$id])) {
227
+ return $frame[$id];
228
+ }
229
+ }
230
+ break;
231
+
232
+ case 'array':
233
+ if (array_key_exists($id, $frame)) {
234
+ return $frame[$id];
235
+ }
236
+ break;
237
  }
238
  }
239
 
vendor/mustache/mustache/src/Mustache/Engine.php CHANGED
@@ -3,7 +3,7 @@
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
- * (c) 2010-2014 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
@@ -23,10 +23,19 @@
23
  */
24
  class Mustache_Engine
25
  {
26
- const VERSION = '2.6.1';
27
  const SPEC_VERSION = '1.1.2';
28
 
29
- const PRAGMA_FILTERS = 'FILTERS';
 
 
 
 
 
 
 
 
 
30
 
31
  // Template cache
32
  private $templates = array();
@@ -44,6 +53,7 @@ class Mustache_Engine
44
  private $charset = 'UTF-8';
45
  private $logger;
46
  private $strictCallables = false;
 
47
 
48
  // Services
49
  private $tokenizer;
@@ -110,6 +120,10 @@ class Mustache_Engine
110
  * // helps protect against arbitrary code execution when user input is passed directly into the template.
111
  * // This currently defaults to false, but will default to true in v3.0.
112
  * 'strict_callables' => true,
 
 
 
 
113
  * );
114
  *
115
  * @throws Mustache_Exception_InvalidArgumentException If `escape` option is not callable.
@@ -162,7 +176,7 @@ class Mustache_Engine
162
  }
163
 
164
  if (isset($options['entity_flags'])) {
165
- $this->entityFlags = $options['entity_flags'];
166
  }
167
 
168
  if (isset($options['charset'])) {
@@ -176,6 +190,15 @@ class Mustache_Engine
176
  if (isset($options['strict_callables'])) {
177
  $this->strictCallables = $options['strict_callables'];
178
  }
 
 
 
 
 
 
 
 
 
179
  }
180
 
181
  /**
@@ -226,6 +249,16 @@ class Mustache_Engine
226
  return $this->charset;
227
  }
228
 
 
 
 
 
 
 
 
 
 
 
229
  /**
230
  * Set the Mustache template Loader instance.
231
  *
@@ -247,7 +280,7 @@ class Mustache_Engine
247
  public function getLoader()
248
  {
249
  if (!isset($this->loader)) {
250
- $this->loader = new Mustache_Loader_StringLoader;
251
  }
252
 
253
  return $this->loader;
@@ -274,7 +307,7 @@ class Mustache_Engine
274
  public function getPartialsLoader()
275
  {
276
  if (!isset($this->partialsLoader)) {
277
- $this->partialsLoader = new Mustache_Loader_ArrayLoader;
278
  }
279
 
280
  return $this->partialsLoader;
@@ -290,7 +323,7 @@ class Mustache_Engine
290
  public function setPartials(array $partials = array())
291
  {
292
  if (!isset($this->partialsLoader)) {
293
- $this->partialsLoader = new Mustache_Loader_ArrayLoader;
294
  }
295
 
296
  if (!$this->partialsLoader instanceof Mustache_Loader_MutableLoader) {
@@ -334,7 +367,7 @@ class Mustache_Engine
334
  public function getHelpers()
335
  {
336
  if (!isset($this->helpers)) {
337
- $this->helpers = new Mustache_HelperCollection;
338
  }
339
 
340
  return $this->helpers;
@@ -374,7 +407,7 @@ class Mustache_Engine
374
  *
375
  * @param string $name
376
  *
377
- * @return boolean True if the helper is present
378
  */
379
  public function hasHelper($name)
380
  {
@@ -443,7 +476,7 @@ class Mustache_Engine
443
  public function getTokenizer()
444
  {
445
  if (!isset($this->tokenizer)) {
446
- $this->tokenizer = new Mustache_Tokenizer;
447
  }
448
 
449
  return $this->tokenizer;
@@ -469,7 +502,7 @@ class Mustache_Engine
469
  public function getParser()
470
  {
471
  if (!isset($this->parser)) {
472
- $this->parser = new Mustache_Parser;
473
  }
474
 
475
  return $this->parser;
@@ -495,7 +528,7 @@ class Mustache_Engine
495
  public function getCompiler()
496
  {
497
  if (!isset($this->compiler)) {
498
- $this->compiler = new Mustache_Compiler;
499
  }
500
 
501
  return $this->compiler;
@@ -563,12 +596,13 @@ class Mustache_Engine
563
  public function getTemplateClassName($source)
564
  {
565
  return $this->templateClassPrefix . md5(sprintf(
566
- 'version:%s,escape:%s,entity_flags:%i,charset:%s,strict_callables:%s,source:%s',
567
  self::VERSION,
568
  isset($this->escape) ? 'custom' : 'default',
569
  $this->entityFlags,
570
  $this->charset,
571
  $this->strictCallables ? 'true' : 'false',
 
572
  $source
573
  ));
574
  }
@@ -705,7 +739,10 @@ class Mustache_Engine
705
  */
706
  private function parse($source)
707
  {
708
- return $this->getParser()->parse($this->tokenize($source));
 
 
 
709
  }
710
 
711
  /**
@@ -728,15 +765,18 @@ class Mustache_Engine
728
  array('className' => $name)
729
  );
730
 
731
- return $this->getCompiler()->compile($source, $tree, $name, isset($this->escape), $this->charset, $this->strictCallables, $this->entityFlags);
 
 
 
732
  }
733
 
734
  /**
735
  * Add a log record if logging is enabled.
736
  *
737
- * @param integer $level The logging level
738
- * @param string $message The log message
739
- * @param array $context The log context
740
  */
741
  private function log($level, $message, array $context = array())
742
  {
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
+ * (c) 2010-2015 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
23
  */
24
  class Mustache_Engine
25
  {
26
+ const VERSION = '2.9.0';
27
  const SPEC_VERSION = '1.1.2';
28
 
29
+ const PRAGMA_FILTERS = 'FILTERS';
30
+ const PRAGMA_BLOCKS = 'BLOCKS';
31
+ const PRAGMA_ANCHORED_DOT = 'ANCHORED-DOT';
32
+
33
+ // Known pragmas
34
+ private static $knownPragmas = array(
35
+ self::PRAGMA_FILTERS => true,
36
+ self::PRAGMA_BLOCKS => true,
37
+ self::PRAGMA_ANCHORED_DOT => true,
38
+ );
39
 
40
  // Template cache
41
  private $templates = array();
53
  private $charset = 'UTF-8';
54
  private $logger;
55
  private $strictCallables = false;
56
+ private $pragmas = array();
57
 
58
  // Services
59
  private $tokenizer;
120
  * // helps protect against arbitrary code execution when user input is passed directly into the template.
121
  * // This currently defaults to false, but will default to true in v3.0.
122
  * 'strict_callables' => true,
123
+ *
124
+ * // Enable pragmas across all templates, regardless of the presence of pragma tags in the individual
125
+ * // templates.
126
+ * 'pragmas' => [Mustache_Engine::PRAGMA_FILTERS],
127
  * );
128
  *
129
  * @throws Mustache_Exception_InvalidArgumentException If `escape` option is not callable.
176
  }
177
 
178
  if (isset($options['entity_flags'])) {
179
+ $this->entityFlags = $options['entity_flags'];
180
  }
181
 
182
  if (isset($options['charset'])) {
190
  if (isset($options['strict_callables'])) {
191
  $this->strictCallables = $options['strict_callables'];
192
  }
193
+
194
+ if (isset($options['pragmas'])) {
195
+ foreach ($options['pragmas'] as $pragma) {
196
+ if (!isset(self::$knownPragmas[$pragma])) {
197
+ throw new Mustache_Exception_InvalidArgumentException(sprintf('Unknown pragma: "%s".', $pragma));
198
+ }
199
+ $this->pragmas[$pragma] = true;
200
+ }
201
+ }
202
  }
203
 
204
  /**
249
  return $this->charset;
250
  }
251
 
252
+ /**
253
+ * Get the current globally enabled pragmas.
254
+ *
255
+ * @return array
256
+ */
257
+ public function getPragmas()
258
+ {
259
+ return array_keys($this->pragmas);
260
+ }
261
+
262
  /**
263
  * Set the Mustache template Loader instance.
264
  *
280
  public function getLoader()
281
  {
282
  if (!isset($this->loader)) {
283
+ $this->loader = new Mustache_Loader_StringLoader();
284
  }
285
 
286
  return $this->loader;
307
  public function getPartialsLoader()
308
  {
309
  if (!isset($this->partialsLoader)) {
310
+ $this->partialsLoader = new Mustache_Loader_ArrayLoader();
311
  }
312
 
313
  return $this->partialsLoader;
323
  public function setPartials(array $partials = array())
324
  {
325
  if (!isset($this->partialsLoader)) {
326
+ $this->partialsLoader = new Mustache_Loader_ArrayLoader();
327
  }
328
 
329
  if (!$this->partialsLoader instanceof Mustache_Loader_MutableLoader) {
367
  public function getHelpers()
368
  {
369
  if (!isset($this->helpers)) {
370
+ $this->helpers = new Mustache_HelperCollection();
371
  }
372
 
373
  return $this->helpers;
407
  *
408
  * @param string $name
409
  *
410
+ * @return bool True if the helper is present
411
  */
412
  public function hasHelper($name)
413
  {
476
  public function getTokenizer()
477
  {
478
  if (!isset($this->tokenizer)) {
479
+ $this->tokenizer = new Mustache_Tokenizer();
480
  }
481
 
482
  return $this->tokenizer;
502
  public function getParser()
503
  {
504
  if (!isset($this->parser)) {
505
+ $this->parser = new Mustache_Parser();
506
  }
507
 
508
  return $this->parser;
528
  public function getCompiler()
529
  {
530
  if (!isset($this->compiler)) {
531
+ $this->compiler = new Mustache_Compiler();
532
  }
533
 
534
  return $this->compiler;
596
  public function getTemplateClassName($source)
597
  {
598
  return $this->templateClassPrefix . md5(sprintf(
599
+ 'version:%s,escape:%s,entity_flags:%i,charset:%s,strict_callables:%s,pragmas:%s,source:%s',
600
  self::VERSION,
601
  isset($this->escape) ? 'custom' : 'default',
602
  $this->entityFlags,
603
  $this->charset,
604
  $this->strictCallables ? 'true' : 'false',
605
+ implode(' ', $this->getPragmas()),
606
  $source
607
  ));
608
  }
739
  */
740
  private function parse($source)
741
  {
742
+ $parser = $this->getParser();
743
+ $parser->setPragmas($this->getPragmas());
744
+
745
+ return $parser->parse($this->tokenize($source));
746
  }
747
 
748
  /**
765
  array('className' => $name)
766
  );
767
 
768
+ $compiler = $this->getCompiler();
769
+ $compiler->setPragmas($this->getPragmas());
770
+
771
+ return $compiler->compile($source, $tree, $name, isset($this->escape), $this->charset, $this->strictCallables, $this->entityFlags);
772
  }
773
 
774
  /**
775
  * Add a log record if logging is enabled.
776
  *
777
+ * @param int $level The logging level
778
+ * @param string $message The log message
779
+ * @param array $context The log context
780
  */
781
  private function log($level, $message, array $context = array())
782
  {
vendor/mustache/mustache/src/Mustache/Exception.php CHANGED
@@ -3,7 +3,7 @@
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
- * (c) 2010-2014 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
+ * (c) 2010-2015 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
vendor/mustache/mustache/src/Mustache/Exception/InvalidArgumentException.php CHANGED
@@ -3,7 +3,7 @@
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
- * (c) 2010-2014 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
+ * (c) 2010-2015 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
vendor/mustache/mustache/src/Mustache/Exception/LogicException.php CHANGED
@@ -3,7 +3,7 @@
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
- * (c) 2010-2014 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
+ * (c) 2010-2015 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
vendor/mustache/mustache/src/Mustache/Exception/RuntimeException.php CHANGED
@@ -3,7 +3,7 @@
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
- * (c) 2010-2014 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
+ * (c) 2010-2015 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
vendor/mustache/mustache/src/Mustache/Exception/SyntaxException.php CHANGED
@@ -3,7 +3,7 @@
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
- * (c) 2010-2014 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
+ * (c) 2010-2015 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
vendor/mustache/mustache/src/Mustache/Exception/UnknownFilterException.php CHANGED
@@ -3,7 +3,7 @@
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
- * (c) 2010-2014 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
+ * (c) 2010-2015 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
vendor/mustache/mustache/src/Mustache/Exception/UnknownHelperException.php CHANGED
@@ -3,7 +3,7 @@
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
- * (c) 2010-2014 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
+ * (c) 2010-2015 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
vendor/mustache/mustache/src/Mustache/Exception/UnknownTemplateException.php CHANGED
@@ -3,7 +3,7 @@
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
- * (c) 2010-2014 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
+ * (c) 2010-2015 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
vendor/mustache/mustache/src/Mustache/HelperCollection.php CHANGED
@@ -3,7 +3,7 @@
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
- * (c) 2010-2014 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
@@ -103,7 +103,7 @@ class Mustache_HelperCollection
103
  *
104
  * @param string $name
105
  *
106
- * @return boolean True if helper is present
107
  */
108
  public function __isset($name)
109
  {
@@ -115,7 +115,7 @@ class Mustache_HelperCollection
115
  *
116
  * @param string $name
117
  *
118
- * @return boolean True if helper is present
119
  */
120
  public function has($name)
121
  {
@@ -163,7 +163,7 @@ class Mustache_HelperCollection
163
  /**
164
  * Check whether the helper collection is empty.
165
  *
166
- * @return boolean True if the collection is empty
167
  */
168
  public function isEmpty()
169
  {
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
+ * (c) 2010-2015 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
103
  *
104
  * @param string $name
105
  *
106
+ * @return bool True if helper is present
107
  */
108
  public function __isset($name)
109
  {
115
  *
116
  * @param string $name
117
  *
118
+ * @return bool True if helper is present
119
  */
120
  public function has($name)
121
  {
163
  /**
164
  * Check whether the helper collection is empty.
165
  *
166
+ * @return bool True if the collection is empty
167
  */
168
  public function isEmpty()
169
  {
vendor/mustache/mustache/src/Mustache/LambdaHelper.php CHANGED
@@ -3,7 +3,7 @@
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
- * (c) 2010-2014 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
+ * (c) 2010-2015 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
vendor/mustache/mustache/src/Mustache/Loader.php CHANGED
@@ -3,7 +3,7 @@
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
- * (c) 2010-2014 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
+ * (c) 2010-2015 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
vendor/mustache/mustache/src/Mustache/Loader/ArrayLoader.php CHANGED
@@ -3,7 +3,7 @@
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
- * (c) 2010-2014 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
+ * (c) 2010-2015 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
vendor/mustache/mustache/src/Mustache/Loader/CascadingLoader.php CHANGED
@@ -3,7 +3,7 @@
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
- * (c) 2010-2014 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
@@ -18,7 +18,7 @@ class Mustache_Loader_CascadingLoader implements Mustache_Loader
18
  private $loaders;
19
 
20
  /**
21
- * Construct a CascadingLoader with an array of loaders:
22
  *
23
  * $loader = new Mustache_Loader_CascadingLoader(array(
24
  * new Mustache_Loader_InlineLoader(__FILE__, __COMPILER_HALT_OFFSET__),
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
+ * (c) 2010-2015 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
18
  private $loaders;
19
 
20
  /**
21
+ * Construct a CascadingLoader with an array of loaders.
22
  *
23
  * $loader = new Mustache_Loader_CascadingLoader(array(
24
  * new Mustache_Loader_InlineLoader(__FILE__, __COMPILER_HALT_OFFSET__),
vendor/mustache/mustache/src/Mustache/Loader/FilesystemLoader.php CHANGED
@@ -3,7 +3,7 @@
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
- * (c) 2010-2014 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
@@ -49,7 +49,7 @@ class Mustache_Loader_FilesystemLoader implements Mustache_Loader
49
  {
50
  $this->baseDir = $baseDir;
51
 
52
- if (strpos($this->baseDir, '://') === -1) {
53
  $this->baseDir = realpath($this->baseDir);
54
  }
55
 
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
+ * (c) 2010-2015 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
49
  {
50
  $this->baseDir = $baseDir;
51
 
52
+ if (strpos($this->baseDir, '://') === false) {
53
  $this->baseDir = realpath($this->baseDir);
54
  }
55
 
vendor/mustache/mustache/src/Mustache/Loader/InlineLoader.php CHANGED
@@ -3,7 +3,7 @@
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
- * (c) 2010-2014 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
@@ -46,7 +46,6 @@
46
  *
47
  * @@ hello
48
  * Hello, {{ name }}!
49
- *
50
  */
51
  class Mustache_Loader_InlineLoader implements Mustache_Loader
52
  {
@@ -56,6 +55,7 @@ class Mustache_Loader_InlineLoader implements Mustache_Loader
56
 
57
  /**
58
  * The InlineLoader requires a filename and offset to process templates.
 
59
  * The magic constants `__FILE__` and `__COMPILER_HALT_OFFSET__` are usually
60
  * perfectly suited to the job:
61
  *
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
+ * (c) 2010-2015 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
46
  *
47
  * @@ hello
48
  * Hello, {{ name }}!
 
49
  */
50
  class Mustache_Loader_InlineLoader implements Mustache_Loader
51
  {
55
 
56
  /**
57
  * The InlineLoader requires a filename and offset to process templates.
58
+ *
59
  * The magic constants `__FILE__` and `__COMPILER_HALT_OFFSET__` are usually
60
  * perfectly suited to the job:
61
  *
vendor/mustache/mustache/src/Mustache/Loader/MutableLoader.php CHANGED
@@ -3,7 +3,7 @@
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
- * (c) 2010-2014 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
@@ -18,8 +18,6 @@ interface Mustache_Loader_MutableLoader
18
  * Set an associative array of Template sources for this loader.
19
  *
20
  * @param array $templates
21
- *
22
- * @return void
23
  */
24
  public function setTemplates(array $templates);
25
 
@@ -28,8 +26,6 @@ interface Mustache_Loader_MutableLoader
28
  *
29
  * @param string $name
30
  * @param string $template Mustache Template source
31
- *
32
- * @return void
33
  */
34
  public function setTemplate($name, $template);
35
  }
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
+ * (c) 2010-2015 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
18
  * Set an associative array of Template sources for this loader.
19
  *
20
  * @param array $templates
 
 
21
  */
22
  public function setTemplates(array $templates);
23
 
26
  *
27
  * @param string $name
28
  * @param string $template Mustache Template source
 
 
29
  */
30
  public function setTemplate($name, $template);
31
  }
vendor/mustache/mustache/src/Mustache/Loader/StringLoader.php CHANGED
@@ -3,7 +3,7 @@
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
- * (c) 2010-2014 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
+ * (c) 2010-2015 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
vendor/mustache/mustache/src/Mustache/Logger.php CHANGED
@@ -3,14 +3,14 @@
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
- * (c) 2010-2014 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
 
12
  /**
13
- * Describes a Mustache logger instance
14
  *
15
  * This is identical to the Psr\Log\LoggerInterface.
16
  *
@@ -29,7 +29,7 @@
29
  interface Mustache_Logger
30
  {
31
  /**
32
- * Psr\Log compatible log levels
33
  */
34
  const EMERGENCY = 'emergency';
35
  const ALERT = 'alert';
@@ -45,8 +45,6 @@ interface Mustache_Logger
45
  *
46
  * @param string $message
47
  * @param array $context
48
- *
49
- * @return null
50
  */
51
  public function emergency($message, array $context = array());
52
 
@@ -58,8 +56,6 @@ interface Mustache_Logger
58
  *
59
  * @param string $message
60
  * @param array $context
61
- *
62
- * @return null
63
  */
64
  public function alert($message, array $context = array());
65
 
@@ -70,8 +66,6 @@ interface Mustache_Logger
70
  *
71
  * @param string $message
72
  * @param array $context
73
- *
74
- * @return null
75
  */
76
  public function critical($message, array $context = array());
77
 
@@ -81,8 +75,6 @@ interface Mustache_Logger
81
  *
82
  * @param string $message
83
  * @param array $context
84
- *
85
- * @return null
86
  */
87
  public function error($message, array $context = array());
88
 
@@ -94,8 +86,6 @@ interface Mustache_Logger
94
  *
95
  * @param string $message
96
  * @param array $context
97
- *
98
- * @return null
99
  */
100
  public function warning($message, array $context = array());
101
 
@@ -104,8 +94,6 @@ interface Mustache_Logger
104
  *
105
  * @param string $message
106
  * @param array $context
107
- *
108
- * @return null
109
  */
110
  public function notice($message, array $context = array());
111
 
@@ -116,8 +104,6 @@ interface Mustache_Logger
116
  *
117
  * @param string $message
118
  * @param array $context
119
- *
120
- * @return null
121
  */
122
  public function info($message, array $context = array());
123
 
@@ -126,8 +112,6 @@ interface Mustache_Logger
126
  *
127
  * @param string $message
128
  * @param array $context
129
- *
130
- * @return null
131
  */
132
  public function debug($message, array $context = array());
133
 
@@ -137,8 +121,6 @@ interface Mustache_Logger
137
  * @param mixed $level
138
  * @param string $message
139
  * @param array $context
140
- *
141
- * @return null
142
  */
143
  public function log($level, $message, array $context = array());
144
  }
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
+ * (c) 2010-2015 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
 
12
  /**
13
+ * Describes a Mustache logger instance.
14
  *
15
  * This is identical to the Psr\Log\LoggerInterface.
16
  *
29
  interface Mustache_Logger
30
  {
31
  /**
32
+ * Psr\Log compatible log levels.
33
  */
34
  const EMERGENCY = 'emergency';
35
  const ALERT = 'alert';
45
  *
46
  * @param string $message
47
  * @param array $context
 
 
48
  */
49
  public function emergency($message, array $context = array());
50
 
56
  *
57
  * @param string $message
58
  * @param array $context
 
 
59
  */
60
  public function alert($message, array $context = array());
61
 
66
  *
67
  * @param string $message
68
  * @param array $context
 
 
69
  */
70
  public function critical($message, array $context = array());
71
 
75
  *
76
  * @param string $message
77
  * @param array $context
 
 
78
  */
79
  public function error($message, array $context = array());
80
 
86
  *
87
  * @param string $message
88
  * @param array $context
 
 
89
  */
90
  public function warning($message, array $context = array());
91
 
94
  *
95
  * @param string $message
96
  * @param array $context
 
 
97
  */
98
  public function notice($message, array $context = array());
99
 
104
  *
105
  * @param string $message
106
  * @param array $context
 
 
107
  */
108
  public function info($message, array $context = array());
109
 
112
  *
113
  * @param string $message
114
  * @param array $context
 
 
115
  */
116
  public function debug($message, array $context = array());
117
 
121
  * @param mixed $level
122
  * @param string $message
123
  * @param array $context
 
 
124
  */
125
  public function log($level, $message, array $context = array());
126
  }
vendor/mustache/mustache/src/Mustache/Logger/AbstractLogger.php CHANGED
@@ -3,7 +3,7 @@
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
- * (c) 2010-2014 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
+ * (c) 2010-2015 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
vendor/mustache/mustache/src/Mustache/Logger/StreamLogger.php CHANGED
@@ -3,7 +3,7 @@
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
- * (c) 2010-2014 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
@@ -39,7 +39,7 @@ class Mustache_Logger_StreamLogger extends Mustache_Logger_AbstractLogger
39
  * @throws InvalidArgumentException if the logging level is unknown.
40
  *
41
  * @param resource|string $stream Resource instance or URL
42
- * @param integer $level The minimum logging level at which this handler will be triggered
43
  */
44
  public function __construct($stream, $level = Mustache_Logger::ERROR)
45
  {
@@ -67,7 +67,7 @@ class Mustache_Logger_StreamLogger extends Mustache_Logger_AbstractLogger
67
  *
68
  * @throws Mustache_Exception_InvalidArgumentException if the logging level is unknown.
69
  *
70
- * @param integer $level The minimum logging level which will be written
71
  */
72
  public function setLevel($level)
73
  {
@@ -81,7 +81,7 @@ class Mustache_Logger_StreamLogger extends Mustache_Logger_AbstractLogger
81
  /**
82
  * Get the current minimum logging level.
83
  *
84
- * @return integer
85
  */
86
  public function getLevel()
87
  {
@@ -114,9 +114,9 @@ class Mustache_Logger_StreamLogger extends Mustache_Logger_AbstractLogger
114
  * @throws Mustache_Exception_LogicException If neither a stream resource nor url is present.
115
  * @throws Mustache_Exception_RuntimeException If the stream url cannot be opened.
116
  *
117
- * @param integer $level The logging level
118
- * @param string $message The log message
119
- * @param array $context The log context
120
  */
121
  protected function writeLog($level, $message, array $context = array())
122
  {
@@ -141,7 +141,7 @@ class Mustache_Logger_StreamLogger extends Mustache_Logger_AbstractLogger
141
  *
142
  * @throws InvalidArgumentException if the logging level is unknown.
143
  *
144
- * @param integer $level
145
  *
146
  * @return string
147
  */
@@ -153,9 +153,9 @@ class Mustache_Logger_StreamLogger extends Mustache_Logger_AbstractLogger
153
  /**
154
  * Format a log line for output.
155
  *
156
- * @param integer $level The logging level
157
- * @param string $message The log message
158
- * @param array $context The log context
159
  *
160
  * @return string
161
  */
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
+ * (c) 2010-2015 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
39
  * @throws InvalidArgumentException if the logging level is unknown.
40
  *
41
  * @param resource|string $stream Resource instance or URL
42
+ * @param int $level The minimum logging level at which this handler will be triggered
43
  */
44
  public function __construct($stream, $level = Mustache_Logger::ERROR)
45
  {
67
  *
68
  * @throws Mustache_Exception_InvalidArgumentException if the logging level is unknown.
69
  *
70
+ * @param int $level The minimum logging level which will be written
71
  */
72
  public function setLevel($level)
73
  {
81
  /**
82
  * Get the current minimum logging level.
83
  *
84
+ * @return int
85
  */
86
  public function getLevel()
87
  {
114
  * @throws Mustache_Exception_LogicException If neither a stream resource nor url is present.
115
  * @throws Mustache_Exception_RuntimeException If the stream url cannot be opened.
116
  *
117
+ * @param int $level The logging level
118
+ * @param string $message The log message
119
+ * @param array $context The log context
120
  */
121
  protected function writeLog($level, $message, array $context = array())
122
  {
141
  *
142
  * @throws InvalidArgumentException if the logging level is unknown.
143
  *
144
+ * @param int $level
145
  *
146
  * @return string
147
  */
153
  /**
154
  * Format a log line for output.
155
  *
156
+ * @param int $level The logging level
157
+ * @param string $message The log message
158
+ * @param array $context The log context
159
  *
160
  * @return string
161
  */
vendor/mustache/mustache/src/Mustache/Parser.php CHANGED
@@ -3,7 +3,7 @@
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
- * (c) 2010-2014 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
@@ -18,6 +18,11 @@ class Mustache_Parser
18
  {
19
  private $lineNum;
20
  private $lineTokens;
 
 
 
 
 
21
 
22
  /**
23
  * Process an array of Mustache tokens and convert them into a parse tree.
@@ -30,10 +35,31 @@ class Mustache_Parser
30
  {
31
  $this->lineNum = -1;
32
  $this->lineTokens = 0;
 
 
 
 
33
 
34
  return $this->buildTree($tokens);
35
  }
36
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  /**
38
  * Helper method for recursively building a parse tree.
39
  *
@@ -58,13 +84,23 @@ class Mustache_Parser
58
  $this->lineTokens = 0;
59
  }
60
 
 
 
 
 
 
 
 
 
61
  switch ($token[Mustache_Tokenizer::TYPE]) {
62
  case Mustache_Tokenizer::T_DELIM_CHANGE:
 
63
  $this->clearStandaloneLines($nodes, $tokens);
64
  break;
65
 
66
  case Mustache_Tokenizer::T_SECTION:
67
  case Mustache_Tokenizer::T_INVERTED:
 
68
  $this->clearStandaloneLines($nodes, $tokens);
69
  $nodes[] = $this->buildTree($tokens, $token);
70
  break;
@@ -97,15 +133,40 @@ class Mustache_Parser
97
  return $parent;
98
 
99
  case Mustache_Tokenizer::T_PARTIAL:
100
- case Mustache_Tokenizer::T_PARTIAL_2:
101
- // store the whitespace prefix for laters!
102
  if ($indent = $this->clearStandaloneLines($nodes, $tokens)) {
103
  $token[Mustache_Tokenizer::INDENT] = $indent[Mustache_Tokenizer::VALUE];
104
  }
105
  $nodes[] = $token;
106
  break;
107
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  case Mustache_Tokenizer::T_PRAGMA:
 
 
 
109
  case Mustache_Tokenizer::T_COMMENT:
110
  $this->clearStandaloneLines($nodes, $tokens);
111
  $nodes[] = $token;
@@ -137,7 +198,7 @@ class Mustache_Parser
137
  * @param array $nodes Parsed nodes.
138
  * @param array $tokens Tokens to be parsed.
139
  *
140
- * @return array Resulting indent token, if any.
141
  */
142
  private function clearStandaloneLines(array &$nodes, array &$tokens)
143
  {
@@ -193,14 +254,64 @@ class Mustache_Parser
193
  *
194
  * @param array $token
195
  *
196
- * @return boolean True if token is a whitespace token
197
  */
198
  private function tokenIsWhitespace(array $token)
199
  {
200
- if ($token[Mustache_Tokenizer::TYPE] == Mustache_Tokenizer::T_TEXT) {
201
  return preg_match('/^\s*$/', $token[Mustache_Tokenizer::VALUE]);
202
  }
203
 
204
  return false;
205
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
206
  }
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
+ * (c) 2010-2015 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
18
  {
19
  private $lineNum;
20
  private $lineTokens;
21
+ private $pragmas;
22
+ private $defaultPragmas = array();
23
+
24
+ private $pragmaFilters;
25
+ private $pragmaBlocks;
26
 
27
  /**
28
  * Process an array of Mustache tokens and convert them into a parse tree.
35
  {
36
  $this->lineNum = -1;
37
  $this->lineTokens = 0;
38
+ $this->pragmas = $this->defaultPragmas;
39
+
40
+ $this->pragmaFilters = isset($this->pragmas[Mustache_Engine::PRAGMA_FILTERS]);
41
+ $this->pragmaBlocks = isset($this->pragmas[Mustache_Engine::PRAGMA_BLOCKS]);
42
 
43
  return $this->buildTree($tokens);
44
  }
45
 
46
+ /**
47
+ * Enable pragmas across all templates, regardless of the presence of pragma
48
+ * tags in the individual templates.
49
+ *
50
+ * @internal Users should set global pragmas in Mustache_Engine, not here :)
51
+ *
52
+ * @param string[] $pragmas
53
+ */
54
+ public function setPragmas(array $pragmas)
55
+ {
56
+ $this->pragmas = array();
57
+ foreach ($pragmas as $pragma) {
58
+ $this->enablePragma($pragma);
59
+ }
60
+ $this->defaultPragmas = $this->pragmas;
61
+ }
62
+
63
  /**
64
  * Helper method for recursively building a parse tree.
65
  *
84
  $this->lineTokens = 0;
85
  }
86
 
87
+ if ($this->pragmaFilters && isset($token[Mustache_Tokenizer::NAME])) {
88
+ list($name, $filters) = $this->getNameAndFilters($token[Mustache_Tokenizer::NAME]);
89
+ if (!empty($filters)) {
90
+ $token[Mustache_Tokenizer::NAME] = $name;
91
+ $token[Mustache_Tokenizer::FILTERS] = $filters;
92
+ }
93
+ }
94
+
95
  switch ($token[Mustache_Tokenizer::TYPE]) {
96
  case Mustache_Tokenizer::T_DELIM_CHANGE:
97
+ $this->checkIfTokenIsAllowedInParent($parent, $token);
98
  $this->clearStandaloneLines($nodes, $tokens);
99
  break;
100
 
101
  case Mustache_Tokenizer::T_SECTION:
102
  case Mustache_Tokenizer::T_INVERTED:
103
+ $this->checkIfTokenIsAllowedInParent($parent, $token);
104
  $this->clearStandaloneLines($nodes, $tokens);
105
  $nodes[] = $this->buildTree($tokens, $token);
106
  break;
133
  return $parent;
134
 
135
  case Mustache_Tokenizer::T_PARTIAL:
136
+ $this->checkIfTokenIsAllowedInParent($parent, $token);
137
+ //store the whitespace prefix for laters!
138
  if ($indent = $this->clearStandaloneLines($nodes, $tokens)) {
139
  $token[Mustache_Tokenizer::INDENT] = $indent[Mustache_Tokenizer::VALUE];
140
  }
141
  $nodes[] = $token;
142
  break;
143
 
144
+ case Mustache_Tokenizer::T_PARENT:
145
+ $this->checkIfTokenIsAllowedInParent($parent, $token);
146
+ $nodes[] = $this->buildTree($tokens, $token);
147
+ break;
148
+
149
+ case Mustache_Tokenizer::T_BLOCK_VAR:
150
+ if ($this->pragmaBlocks) {
151
+ // BLOCKS pragma is enabled, let's do this!
152
+ if ($parent[Mustache_Tokenizer::TYPE] === Mustache_Tokenizer::T_PARENT) {
153
+ $token[Mustache_Tokenizer::TYPE] = Mustache_Tokenizer::T_BLOCK_ARG;
154
+ }
155
+ $this->clearStandaloneLines($nodes, $tokens);
156
+ $nodes[] = $this->buildTree($tokens, $token);
157
+ } else {
158
+ // pretend this was just a normal "escaped" token...
159
+ $token[Mustache_Tokenizer::TYPE] = Mustache_Tokenizer::T_ESCAPED;
160
+ // TODO: figure out how to figure out if there was a space after this dollar:
161
+ $token[Mustache_Tokenizer::NAME] = '$' . $token[Mustache_Tokenizer::NAME];
162
+ $nodes[] = $token;
163
+ }
164
+ break;
165
+
166
  case Mustache_Tokenizer::T_PRAGMA:
167
+ $this->enablePragma($token[Mustache_Tokenizer::NAME]);
168
+ // no break
169
+
170
  case Mustache_Tokenizer::T_COMMENT:
171
  $this->clearStandaloneLines($nodes, $tokens);
172
  $nodes[] = $token;
198
  * @param array $nodes Parsed nodes.
199
  * @param array $tokens Tokens to be parsed.
200
  *
201
+ * @return array|null Resulting indent token, if any.
202
  */
203
  private function clearStandaloneLines(array &$nodes, array &$tokens)
204
  {
254
  *
255
  * @param array $token
256
  *
257
+ * @return bool True if token is a whitespace token
258
  */
259
  private function tokenIsWhitespace(array $token)
260
  {
261
+ if ($token[Mustache_Tokenizer::TYPE] === Mustache_Tokenizer::T_TEXT) {
262
  return preg_match('/^\s*$/', $token[Mustache_Tokenizer::VALUE]);
263
  }
264
 
265
  return false;
266
  }
267
+
268
+ /**
269
+ * Check whether a token is allowed inside a parent tag.
270
+ *
271
+ * @throws Mustache_Exception_SyntaxException if an invalid token is found inside a parent tag.
272
+ *
273
+ * @param array|null $parent
274
+ * @param array $token
275
+ */
276
+ private function checkIfTokenIsAllowedInParent($parent, array $token)
277
+ {
278
+ if ($parent[Mustache_Tokenizer::TYPE] === Mustache_Tokenizer::T_PARENT) {
279
+ throw new Mustache_Exception_SyntaxException('Illegal content in < parent tag', $token);
280
+ }
281
+ }
282
+
283
+ /**
284
+ * Split a tag name into name and filters.
285
+ *
286
+ * @param string $name
287
+ *
288
+ * @return array [Tag name, Array of filters]
289
+ */
290
+ private function getNameAndFilters($name)
291
+ {
292
+ $filters = array_map('trim', explode('|', $name));
293
+ $name = array_shift($filters);
294
+
295
+ return array($name, $filters);
296
+ }
297
+
298
+ /**
299
+ * Enable a pragma.
300
+ *
301
+ * @param string $name
302
+ */
303
+ private function enablePragma($name)
304
+ {
305
+ $this->pragmas[$name] = true;
306
+
307
+ switch ($name) {
308
+ case Mustache_Engine::PRAGMA_BLOCKS:
309
+ $this->pragmaBlocks = true;
310
+ break;
311
+
312
+ case Mustache_Engine::PRAGMA_FILTERS:
313
+ $this->pragmaFilters = true;
314
+ break;
315
+ }
316
+ }
317
  }
vendor/mustache/mustache/src/Mustache/Template.php CHANGED
@@ -3,7 +3,7 @@
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
- * (c) 2010-2014 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
@@ -22,7 +22,7 @@ abstract class Mustache_Template
22
  protected $mustache;
23
 
24
  /**
25
- * @var boolean
26
  */
27
  protected $strictCallables = false;
28
 
@@ -37,7 +37,7 @@ abstract class Mustache_Template
37
  }
38
 
39
  /**
40
- * Mustache Template instances can be treated as a function and rendered by simply calling them:
41
  *
42
  * $m = new Mustache_Engine;
43
  * $tpl = $m->loadTemplate('Hello, {{ name }}!');
@@ -63,7 +63,9 @@ abstract class Mustache_Template
63
  */
64
  public function render($context = array())
65
  {
66
- return $this->renderInternal($this->prepareContextStack($context));
 
 
67
  }
68
 
69
  /**
@@ -107,23 +109,26 @@ abstract class Mustache_Template
107
  *
108
  * @param mixed $value
109
  *
110
- * @return boolean True if the value is 'iterable'
111
  */
112
  protected function isIterable($value)
113
  {
114
- if (is_object($value)) {
115
- return $value instanceof Traversable;
116
- } elseif (is_array($value)) {
117
- $i = 0;
118
- foreach ($value as $k => $v) {
119
- if ($k !== $i++) {
120
- return false;
 
 
 
121
  }
122
- }
123
 
124
- return true;
125
- } else {
126
- return false;
 
127
  }
128
  }
129
 
@@ -138,7 +143,7 @@ abstract class Mustache_Template
138
  */
139
  protected function prepareContextStack($context = null)
140
  {
141
- $stack = new Mustache_Context;
142
 
143
  $helpers = $this->mustache->getHelpers();
144
  if (!$helpers->isEmpty()) {
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
+ * (c) 2010-2015 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
22
  protected $mustache;
23
 
24
  /**
25
+ * @var bool
26
  */
27
  protected $strictCallables = false;
28
 
37
  }
38
 
39
  /**
40
+ * Mustache Template instances can be treated as a function and rendered by simply calling them.
41
  *
42
  * $m = new Mustache_Engine;
43
  * $tpl = $m->loadTemplate('Hello, {{ name }}!');
63
  */
64
  public function render($context = array())
65
  {
66
+ return $this->renderInternal(
67
+ $this->prepareContextStack($context)
68
+ );
69
  }
70
 
71
  /**
109
  *
110
  * @param mixed $value
111
  *
112
+ * @return bool True if the value is 'iterable'
113
  */
114
  protected function isIterable($value)
115
  {
116
+ switch (gettype($value)) {
117
+ case 'object':
118
+ return $value instanceof Traversable;
119
+
120
+ case 'array':
121
+ $i = 0;
122
+ foreach ($value as $k => $v) {
123
+ if ($k !== $i++) {
124
+ return false;
125
+ }
126
  }
 
127
 
128
+ return true;
129
+
130
+ default:
131
+ return false;
132
  }
133
  }
134
 
143
  */
144
  protected function prepareContextStack($context = null)
145
  {
146
+ $stack = new Mustache_Context();
147
 
148
  $helpers = $this->mustache->getHelpers();
149
  if (!$helpers->isEmpty()) {
vendor/mustache/mustache/src/Mustache/Tokenizer.php CHANGED
@@ -3,7 +3,7 @@
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
- * (c) 2010-2014 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
@@ -27,13 +27,15 @@ class Mustache_Tokenizer
27
  const T_END_SECTION = '/';
28
  const T_COMMENT = '!';
29
  const T_PARTIAL = '>';
30
- const T_PARTIAL_2 = '<';
31
  const T_DELIM_CHANGE = '=';
32
  const T_ESCAPED = '_v';
33
  const T_UNESCAPED = '{';
34
  const T_UNESCAPED_2 = '&';
35
  const T_TEXT = '_t';
36
  const T_PRAGMA = '%';
 
 
37
 
38
  // Valid token types
39
  private static $tagTypes = array(
@@ -42,36 +44,30 @@ class Mustache_Tokenizer
42
  self::T_END_SECTION => true,
43
  self::T_COMMENT => true,
44
  self::T_PARTIAL => true,
45
- self::T_PARTIAL_2 => true,
46
  self::T_DELIM_CHANGE => true,
47
  self::T_ESCAPED => true,
48
  self::T_UNESCAPED => true,
49
  self::T_UNESCAPED_2 => true,
50
  self::T_PRAGMA => true,
51
- );
52
-
53
- // Interpolated tags
54
- private static $interpolatedTags = array(
55
- self::T_ESCAPED => true,
56
- self::T_UNESCAPED => true,
57
- self::T_UNESCAPED_2 => true,
58
  );
59
 
60
  // Token properties
61
- const TYPE = 'type';
62
- const NAME = 'name';
63
- const OTAG = 'otag';
64
- const CTAG = 'ctag';
65
- const LINE = 'line';
66
- const INDEX = 'index';
67
- const END = 'end';
68
- const INDENT = 'indent';
69
- const NODES = 'nodes';
70
- const VALUE = 'value';
 
71
 
72
  private $state;
73
  private $tagType;
74
- private $tag;
75
  private $buffer;
76
  private $tokens;
77
  private $seenTag;
@@ -159,7 +155,7 @@ class Mustache_Tokenizer
159
  self::OTAG => $this->otag,
160
  self::CTAG => $this->ctag,
161
  self::LINE => $this->line,
162
- self::INDEX => ($this->tagType === self::T_END_SECTION) ? $this->seenTag - $this->otagLen : $i + $this->ctagLen
163
  );
164
 
165
  if ($this->tagType === self::T_UNESCAPED) {
@@ -220,7 +216,6 @@ class Mustache_Tokenizer
220
  {
221
  $this->state = self::IN_TEXT;
222
  $this->tagType = null;
223
- $this->tag = null;
224
  $this->buffer = '';
225
  $this->tokens = array();
226
  $this->seenTag = false;
@@ -240,7 +235,7 @@ class Mustache_Tokenizer
240
  $this->tokens[] = array(
241
  self::TYPE => self::T_TEXT,
242
  self::LINE => $this->line,
243
- self::VALUE => $this->buffer
244
  );
245
  $this->buffer = '';
246
  }
@@ -257,7 +252,7 @@ class Mustache_Tokenizer
257
  private function changeDelimiters($text, $index)
258
  {
259
  $startIndex = strpos($text, '=', $index) + 1;
260
- $close = '='.$this->ctag;
261
  $closeIndex = strpos($text, $close, $index);
262
 
263
  $this->setDelimiters(trim(substr($text, $startIndex, $closeIndex - $startIndex)));
@@ -318,7 +313,7 @@ class Mustache_Tokenizer
318
  * @param string $text Mustache template source
319
  * @param int $index Current tokenizer index
320
  *
321
- * @return boolean True if this is a closing section tag
322
  */
323
  private function tagChange($tag, $tagLen, $text, $index)
324
  {
3
  /*
4
  * This file is part of Mustache.php.
5
  *
6
+ * (c) 2010-2015 Justin Hileman
7
  *
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
27
  const T_END_SECTION = '/';
28
  const T_COMMENT = '!';
29
  const T_PARTIAL = '>';
30
+ const T_PARENT = '<';
31
  const T_DELIM_CHANGE = '=';
32
  const T_ESCAPED = '_v';
33
  const T_UNESCAPED = '{';
34
  const T_UNESCAPED_2 = '&';
35
  const T_TEXT = '_t';
36
  const T_PRAGMA = '%';
37
+ const T_BLOCK_VAR = '$';
38
+ const T_BLOCK_ARG = '$arg';
39
 
40
  // Valid token types
41
  private static $tagTypes = array(
44
  self::T_END_SECTION => true,
45
  self::T_COMMENT => true,
46
  self::T_PARTIAL => true,
47
+ self::T_PARENT => true,
48
  self::T_DELIM_CHANGE => true,
49
  self::T_ESCAPED => true,
50
  self::T_UNESCAPED => true,
51
  self::T_UNESCAPED_2 => true,
52
  self::T_PRAGMA => true,
53
+ self::T_BLOCK_VAR => true,
 
 
 
 
 
 
54
  );
55
 
56
  // Token properties
57
+ const TYPE = 'type';
58
+ const NAME = 'name';
59
+ const OTAG = 'otag';
60
+ const CTAG = 'ctag';
61
+ const LINE = 'line';
62
+ const INDEX = 'index';
63
+ const END = 'end';
64
+ const INDENT = 'indent';
65
+ const NODES = 'nodes';
66
+ const VALUE = 'value';
67
+ const FILTERS = 'filters';
68
 
69
  private $state;
70
  private $tagType;
 
71
  private $buffer;
72
  private $tokens;
73
  private $seenTag;
155
  self::OTAG => $this->otag,
156
  self::CTAG => $this->ctag,
157
  self::LINE => $this->line,
158
+ self::INDEX => ($this->tagType === self::T_END_SECTION) ? $this->seenTag - $this->otagLen : $i + $this->ctagLen,
159
  );
160
 
161
  if ($this->tagType === self::T_UNESCAPED) {
216
  {
217
  $this->state = self::IN_TEXT;
218
  $this->tagType = null;
 
219
  $this->buffer = '';
220
  $this->tokens = array();
221
  $this->seenTag = false;
235
  $this->tokens[] = array(
236
  self::TYPE => self::T_TEXT,
237
  self::LINE => $this->line,
238
+ self::VALUE => $this->buffer,
239
  );
240
  $this->buffer = '';
241
  }
252
  private function changeDelimiters($text, $index)
253
  {
254
  $startIndex = strpos($text, '=', $index) + 1;
255
+ $close = '=' . $this->ctag;
256
  $closeIndex = strpos($text, $close, $index);
257
 
258
  $this->setDelimiters(trim(substr($text, $startIndex, $closeIndex - $startIndex)));
313
  * @param string $text Mustache template source
314
  * @param int $index Current tokenizer index
315
  *
316
+ * @return bool True if this is a closing section tag
317
  */
318
  private function tagChange($tag, $tagLen, $text, $index)
319
  {
vendor/scribu/lib-posts-to-posts/README.md ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ lib-posts-to-posts
2
+ ==================
3
+
4
+ This repository contains the library for managing connections and connection types. It does not contain any UI code.
5
+
6
+ It is meant to be integrated into a theme or a plugin.
7
+
8
+ See the [`_p2p_load()`](https://github.com/scribu/wp-posts-to-posts/blob/master/posts-to-posts.php) from the original Posts 2 Posts plugin to see what's needed for initializing it.
vendor/scribu/lib-posts-to-posts/side-user.php CHANGED
@@ -66,27 +66,7 @@ class P2P_Side_User extends P2P_Side {
66
  $uq = new WP_User_Query;
67
  $uq->_p2p_capture = true; // needed by P2P_URL_Query
68
 
69
- // see http://core.trac.wordpress.org/ticket/21119
70
- $uq->query_vars = wp_parse_args( $args, array(
71
- 'blog_id' => $GLOBALS['blog_id'],
72
- 'role' => '',
73
- 'meta_key' => '',
74
- 'meta_value' => '',
75
- 'meta_compare' => '',
76
- 'include' => array(),
77
- 'exclude' => array(),
78
- 'search' => '',
79
- 'search_columns' => array(),
80
- 'orderby' => 'login',
81
- 'order' => 'ASC',
82
- 'offset' => '',
83
- 'number' => '',
84
- 'count_total' => true,
85
- 'fields' => 'all',
86
- 'who' => ''
87
- ) );
88
-
89
- $uq->prepare_query();
90
 
91
  return "SELECT $uq->query_fields $uq->query_from $uq->query_where $uq->query_orderby $uq->query_limit";
92
  }
66
  $uq = new WP_User_Query;
67
  $uq->_p2p_capture = true; // needed by P2P_URL_Query
68
 
69
+ $uq->prepare_query( $args );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
 
71
  return "SELECT $uq->query_fields $uq->query_from $uq->query_where $uq->query_orderby $uq->query_limit";
72
  }
vendor/scribu/lib-posts-to-posts/widget.php CHANGED
@@ -75,16 +75,14 @@ class P2P_Widget extends scbWidget {
75
 
76
  $title = apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base );
77
 
78
- extract( $args );
79
-
80
- echo $before_widget;
81
 
82
  if ( ! empty( $title ) )
83
- echo $before_title . $title . $after_title;
84
 
85
  echo $output;
86
 
87
- echo $after_widget;
88
  }
89
  }
90
 
75
 
76
  $title = apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base );
77
 
78
+ echo $args['before_widget'];
 
 
79
 
80
  if ( ! empty( $title ) )
81
+ echo $args['before_title'] . $title . $args['after_title'];
82
 
83
  echo $output;
84
 
85
+ echo $args['after_widget'];
86
  }
87
  }
88
 
vendor/scribu/scb-framework/AdminPage.php CHANGED
@@ -1,7 +1,6 @@
1
  <?php
2
-
3
  /**
4
- * Administration page base class
5
  */
6
  abstract class scbAdminPage {
7
  /** Page args
@@ -43,17 +42,20 @@ abstract class scbAdminPage {
43
  private static $registered = array();
44
 
45
  /**
46
- * @param string $class
47
- * @param string $file
48
- * @param scbOptions $options
 
 
49
  *
50
  * @return bool
51
  */
52
- static function register( $class, $file, $options = null ) {
53
- if ( isset( self::$registered[$class] ) )
54
  return false;
 
55
 
56
- self::$registered[$class] = array( $file, $options );
57
 
58
  add_action( '_admin_menu', array( __CLASS__, '_pages_init' ) );
59
 
@@ -61,38 +63,50 @@ abstract class scbAdminPage {
61
  }
62
 
63
  /**
 
 
64
  * @param string $old_class
65
  * @param string $new_class
66
  *
67
  * @return bool
68
  */
69
- static function replace( $old_class, $new_class ) {
70
- if ( ! isset( self::$registered[$old_class] ) )
71
  return false;
 
72
 
73
- self::$registered[$new_class] = self::$registered[$old_class];
74
- unset( self::$registered[$old_class] );
75
 
76
  return true;
77
  }
78
 
79
  /**
 
 
80
  * @param string $class
81
  *
82
  * @return bool
83
  */
84
- static function remove( $class ) {
85
- if ( ! isset( self::$registered[$class] ) )
86
  return false;
 
87
 
88
- unset( self::$registered[$class] );
89
 
90
  return true;
91
  }
92
 
93
- static function _pages_init() {
94
- foreach ( self::$registered as $class => $args )
 
 
 
 
 
95
  new $class( $args[0], $args[1] );
 
96
  }
97
 
98
 
@@ -100,14 +114,17 @@ abstract class scbAdminPage {
100
 
101
 
102
  /**
103
- * Constructor
104
  *
105
- * @param string|bool $file
106
- * @param scbOptions $options
 
 
107
  */
108
- function __construct( $file = false, $options = null ) {
109
- if ( is_a( $options, 'scbOptions' ) )
110
  $this->options = $options;
 
111
 
112
  $this->setup();
113
  $this->check_args();
@@ -124,82 +141,96 @@ abstract class scbAdminPage {
124
  $this->file = $file;
125
  $this->plugin_url = plugin_dir_url( $file );
126
 
127
- if ( $this->args['action_link'] )
128
  add_filter( 'plugin_action_links_' . plugin_basename( $file ), array( $this, '_action_link' ) );
 
129
  }
130
  }
131
 
132
  /**
133
- * This is where all the page args can be set
 
 
134
  */
135
- function setup(){}
136
 
137
  /**
138
  * Called when the page is loaded, but before any rendering.
139
- *
140
  * Useful for calling $screen->add_help_tab() etc.
 
 
141
  */
142
- function page_loaded() {
143
  $this->form_handler();
144
  }
145
 
146
  /**
147
- * This is where the css and js go
148
- * Both wp_enqueue_*() and inline code can be added
 
 
149
  */
150
- function page_head(){}
151
 
152
  /**
153
- * This is where the contextual help goes
 
154
  * @return string
155
  */
156
- function page_help(){}
157
 
158
  /**
159
- * A generic page header
 
 
160
  */
161
- function page_header() {
162
  echo "<div class='wrap'>\n";
163
  screen_icon( $this->args['screen_icon'] );
164
  echo html( 'h2', $this->args['page_title'] );
165
  }
166
 
167
  /**
168
- * This is where the page content goes
 
 
169
  */
170
- abstract function page_content();
171
 
172
  /**
173
- * A generic page footer
 
 
174
  */
175
- function page_footer() {
176
  echo "</div>\n";
177
  }
178
 
179
  /**
180
- * This is where the form data should be validated
181
  *
182
  * @param array $new_data
183
  * @param array $old_data
184
  *
185
  * @return array
186
  */
187
- function validate( $new_data, $old_data ) {
188
  return $new_data;
189
  }
190
 
191
  /**
192
- * Manually handle option saving ( use Settings API instead )
193
  *
194
  * @return bool
195
  */
196
- function form_handler() {
197
- if ( empty( $_POST['submit'] ) && empty( $_POST['action'] ) )
198
  return false;
 
199
 
200
  check_admin_referer( $this->nonce );
201
 
202
- if ( !isset($this->options) ) {
203
  trigger_error( 'options handler not set', E_USER_WARNING );
204
  return false;
205
  }
@@ -218,14 +249,17 @@ abstract class scbAdminPage {
218
  }
219
 
220
  /**
221
- * Manually generate a standard admin notice ( use Settings API instead )
222
  *
223
- * @param string $msg
224
- * @param string $class
 
 
225
  */
226
- function admin_msg( $msg = '', $class = 'updated' ) {
227
- if ( empty( $msg ) )
228
  $msg = __( 'Settings <strong>saved</strong>.', $this->textdomain );
 
229
 
230
  echo scb_admin_notice( $msg, $class );
231
  }
@@ -235,15 +269,15 @@ abstract class scbAdminPage {
235
 
236
 
237
  /**
238
- * Generates a form submit button
239
  *
240
- * @param string|array $value button text or array of arguments
241
- * @param string $action
242
- * @param string $class
243
  *
244
  * @return string
245
  */
246
- function submit_button( $value = '', $action = 'submit', $class = 'button' ) {
247
 
248
  $args = is_array( $value ) ? $value : compact( 'value', 'action', 'class' );
249
  $args = wp_parse_args( $args, array(
@@ -271,20 +305,20 @@ abstract class scbAdminPage {
271
  * @see scbForms::form_wrap()
272
  *
273
  * @param string $content
274
- * @param boolean|string|array $submit_button
275
  *
276
  * @return string
277
  */
278
- function form_wrap( $content, $submit_button = true ) {
279
  if ( is_array( $submit_button ) ) {
280
  $content .= $this->submit_button( $submit_button );
281
- } elseif ( true === $submit_button ) {
282
  $content .= $this->submit_button();
283
- } elseif ( false !== strpos( $submit_button, '<input' ) ) {
284
  $content .= $submit_button;
285
- } elseif ( false !== strpos( $submit_button, '<button' ) ) {
286
  $content .= $submit_button;
287
- } elseif ( false !== $submit_button ) {
288
  $button_args = array_slice( func_get_args(), 1 );
289
  $content .= call_user_func_array( array( $this, 'submit_button' ), $button_args );
290
  }
@@ -293,17 +327,18 @@ abstract class scbAdminPage {
293
  }
294
 
295
  /**
296
- * Generates a table wrapped in a form
297
  *
298
  * @param array $rows
299
- * @param array|boolean $formdata
300
  *
301
  * @return string
302
  */
303
- function form_table( $rows, $formdata = false ) {
304
  $output = '';
305
- foreach ( $rows as $row )
306
  $output .= $this->table_row( $row, $formdata );
 
307
 
308
  $output = $this->form_table_wrap( $output );
309
 
@@ -317,7 +352,7 @@ abstract class scbAdminPage {
317
  *
318
  * @return string
319
  */
320
- function form_table_wrap( $content ) {
321
  $output = $this->table_wrap( $content );
322
  $output = $this->form_wrap( $output );
323
 
@@ -325,17 +360,18 @@ abstract class scbAdminPage {
325
  }
326
 
327
  /**
328
- * Generates a form table
329
  *
330
  * @param array $rows
331
- * @param array|boolean $formdata
332
  *
333
  * @return string
334
  */
335
- function table( $rows, $formdata = false ) {
336
  $output = '';
337
- foreach ( $rows as $row )
338
  $output .= $this->table_row( $row, $formdata );
 
339
 
340
  $output = $this->table_wrap( $output );
341
 
@@ -343,19 +379,19 @@ abstract class scbAdminPage {
343
  }
344
 
345
  /**
346
- * Generates a table row
347
  *
348
  * @param array $args
349
- * @param array|boolean $formdata
350
  *
351
  * @return string
352
  */
353
- function table_row( $args, $formdata = false ) {
354
  return $this->row_wrap( $args['title'], $this->input( $args, $formdata ) );
355
  }
356
 
357
  /**
358
- * Mimic scbForms inheritance
359
  *
360
  * @see scbForms
361
  *
@@ -364,37 +400,39 @@ abstract class scbAdminPage {
364
  *
365
  * @return mixed
366
  */
367
- function __call( $method, $args ) {
368
  if ( in_array( $method, array( 'input', 'form' ) ) ) {
369
- if ( empty( $args[1] ) && isset( $this->options ) )
370
  $args[1] = $this->options->get();
 
371
 
372
- if ( 'form' == $method )
373
  $args[2] = $this->nonce;
 
374
  }
375
 
376
  return call_user_func_array( array( 'scbForms', $method ), $args );
377
  }
378
 
379
  /**
380
- * Wraps a string in a <script> tag
381
  *
382
  * @param string $string
383
  *
384
  * @return string
385
  */
386
- function js_wrap( $string ) {
387
  return html( "script type='text/javascript'", $string );
388
  }
389
 
390
  /**
391
- * Wraps a string in a <style> tag
392
  *
393
  * @param string $string
394
  *
395
  * @return string
396
  */
397
- function css_wrap( $string ) {
398
  return html( "style type='text/css'", $string );
399
  }
400
 
@@ -403,9 +441,11 @@ abstract class scbAdminPage {
403
 
404
 
405
  /**
406
- * Registers a page
 
 
407
  */
408
- function page_init() {
409
 
410
  if ( ! $this->args['toplevel'] ) {
411
  $this->pagehook = add_submenu_page(
@@ -438,21 +478,33 @@ abstract class scbAdminPage {
438
  );
439
  }
440
 
441
- if ( ! $this->pagehook )
442
  return;
 
443
 
444
  add_action( 'load-' . $this->pagehook, array( $this, 'page_loaded' ) );
445
 
446
  add_action( 'admin_print_styles-' . $this->pagehook, array( $this, 'page_head' ) );
447
  }
448
 
449
- function option_init() {
 
 
 
 
 
450
  register_setting( $this->option_name, $this->option_name, array( $this, 'validate' ) );
451
  }
452
 
 
 
 
 
 
453
  private function check_args() {
454
- if ( empty( $this->args['page_title'] ) )
455
  trigger_error( 'Page title cannot be empty', E_USER_WARNING );
 
456
 
457
  $this->args = wp_parse_args( $this->args, array(
458
  'toplevel' => '',
@@ -468,46 +520,60 @@ abstract class scbAdminPage {
468
  'admin_action_priority' => 10,
469
  ) );
470
 
471
- if ( empty( $this->args['submenu_title'] ) )
472
  $this->args['submenu_title'] = $this->args['menu_title'];
 
473
 
474
- if ( empty( $this->args['page_slug'] ) )
475
  $this->args['page_slug'] = sanitize_title_with_dashes( $this->args['menu_title'] );
 
476
 
477
- if ( empty( $this->args['nonce'] ) )
478
  $this->nonce = $this->args['page_slug'];
 
479
  }
480
 
481
  /**
 
 
482
  * @param string $help
483
  * @param string|object $screen
484
  *
485
  * @return string
486
  */
487
- function _contextual_help( $help, $screen ) {
488
- if ( is_object( $screen ) )
489
  $screen = $screen->id;
 
490
 
491
  $actual_help = $this->page_help();
492
 
493
- if ( $screen == $this->pagehook && $actual_help )
494
  return $actual_help;
 
495
 
496
  return $help;
497
  }
498
 
499
- function _page_content_hook() {
 
 
 
 
 
500
  $this->page_header();
501
  $this->page_content();
502
  $this->page_footer();
503
  }
504
 
505
  /**
 
 
506
  * @param array $links
507
  *
508
  * @return array
509
  */
510
- function _action_link( $links ) {
511
  $url = add_query_arg( 'page', $this->args['page_slug'], admin_url( $this->args['parent'] ) );
512
 
513
  $links[] = html_link( $url, $this->args['action_link'] );
1
  <?php
 
2
  /**
3
+ * Administration page base class.
4
  */
5
  abstract class scbAdminPage {
6
  /** Page args
42
  private static $registered = array();
43
 
44
  /**
45
+ * Registers class of page.
46
+ *
47
+ * @param string $class
48
+ * @param string $file
49
+ * @param object $options (optional) A scbOptions object.
50
  *
51
  * @return bool
52
  */
53
+ public static function register( $class, $file, $options = null ) {
54
+ if ( isset( self::$registered[ $class ] ) ) {
55
  return false;
56
+ }
57
 
58
+ self::$registered[ $class ] = array( $file, $options );
59
 
60
  add_action( '_admin_menu', array( __CLASS__, '_pages_init' ) );
61
 
63
  }
64
 
65
  /**
66
+ * Replaces class of page.
67
+ *
68
  * @param string $old_class
69
  * @param string $new_class
70
  *
71
  * @return bool
72
  */
73
+ public static function replace( $old_class, $new_class ) {
74
+ if ( ! isset( self::$registered[ $old_class ] ) ) {
75
  return false;
76
+ }
77
 
78
+ self::$registered[ $new_class ] = self::$registered[ $old_class ];
79
+ unset( self::$registered[ $old_class ] );
80
 
81
  return true;
82
  }
83
 
84
  /**
85
+ * Removes class of page.
86
+ *
87
  * @param string $class
88
  *
89
  * @return bool
90
  */
91
+ public static function remove( $class ) {
92
+ if ( ! isset( self::$registered[ $class ] ) ) {
93
  return false;
94
+ }
95
 
96
+ unset( self::$registered[ $class ] );
97
 
98
  return true;
99
  }
100
 
101
+ /**
102
+ * Instantiates classes of pages.
103
+ *
104
+ * @return void
105
+ */
106
+ public static function _pages_init() {
107
+ foreach ( self::$registered as $class => $args ) {
108
  new $class( $args[0], $args[1] );
109
+ }
110
  }
111
 
112
 
114
 
115
 
116
  /**
117
+ * Constructor.
118
  *
119
+ * @param string|bool $file (optional)
120
+ * @param object $options (optional) A scbOptions object.
121
+ *
122
+ * @return void
123
  */
124
+ public function __construct( $file = false, $options = null ) {
125
+ if ( is_a( $options, 'scbOptions' ) ) {
126
  $this->options = $options;
127
+ }
128
 
129
  $this->setup();
130
  $this->check_args();
141
  $this->file = $file;
142
  $this->plugin_url = plugin_dir_url( $file );
143
 
144
+ if ( $this->args['action_link'] ) {
145
  add_filter( 'plugin_action_links_' . plugin_basename( $file ), array( $this, '_action_link' ) );
146
+ }
147
  }
148
  }
149
 
150
  /**
151
+ * This is where all the page args can be set.
152
+ *
153
+ * @return void
154
  */
155
+ protected function setup() { }
156
 
157
  /**
158
  * Called when the page is loaded, but before any rendering.
 
159
  * Useful for calling $screen->add_help_tab() etc.
160
+ *
161
+ * @return void
162
  */
163
+ public function page_loaded() {
164
  $this->form_handler();
165
  }
166
 
167
  /**
168
+ * This is where the css and js go.
169
+ * Both wp_enqueue_*() and inline code can be added.
170
+ *
171
+ * @return void
172
  */
173
+ public function page_head() { }
174
 
175
  /**
176
+ * This is where the contextual help goes.
177
+ *
178
  * @return string
179
  */
180
+ protected function page_help() { }
181
 
182
  /**
183
+ * A generic page header.
184
+ *
185
+ * @return void
186
  */
187
+ protected function page_header() {
188
  echo "<div class='wrap'>\n";
189
  screen_icon( $this->args['screen_icon'] );
190
  echo html( 'h2', $this->args['page_title'] );
191
  }
192
 
193
  /**
194
+ * This is where the page content goes.
195
+ *
196
+ * @return void
197
  */
198
+ abstract protected function page_content();
199
 
200
  /**
201
+ * A generic page footer.
202
+ *
203
+ * @return void
204
  */
205
+ protected function page_footer() {
206
  echo "</div>\n";
207
  }
208
 
209
  /**
210
+ * This is where the form data should be validated.
211
  *
212
  * @param array $new_data
213
  * @param array $old_data
214
  *
215
  * @return array
216
  */
217
+ public function validate( $new_data, $old_data ) {
218
  return $new_data;
219
  }
220
 
221
  /**
222
+ * Manually handle option saving ( use Settings API instead ).
223
  *
224
  * @return bool
225
  */
226
+ protected function form_handler() {
227
+ if ( empty( $_POST['submit'] ) && empty( $_POST['action'] ) ) {
228
  return false;
229
+ }
230
 
231
  check_admin_referer( $this->nonce );
232
 
233
+ if ( ! isset( $this->options ) ) {
234
  trigger_error( 'options handler not set', E_USER_WARNING );
235
  return false;
236
  }
249
  }
250
 
251
  /**
252
+ * Manually generate a standard admin notice ( use Settings API instead ).
253
  *
254
+ * @param string $msg (optional)
255
+ * @param string $class (optional)
256
+ *
257
+ * @return void
258
  */
259
+ public function admin_msg( $msg = '', $class = 'updated' ) {
260
+ if ( empty( $msg ) ) {
261
  $msg = __( 'Settings <strong>saved</strong>.', $this->textdomain );
262
+ }
263
 
264
  echo scb_admin_notice( $msg, $class );
265
  }
269
 
270
 
271
  /**
272
+ * Generates a form submit button.
273
  *
274
+ * @param string|array $value (optional) Button text or array of arguments.
275
+ * @param string $action (optional)
276
+ * @param string $class (optional)
277
  *
278
  * @return string
279
  */
280
+ public function submit_button( $value = '', $action = 'submit', $class = 'button' ) {
281
 
282
  $args = is_array( $value ) ? $value : compact( 'value', 'action', 'class' );
283
  $args = wp_parse_args( $args, array(
305
  * @see scbForms::form_wrap()
306
  *
307
  * @param string $content
308
+ * @param boolean|string|array $submit_button (optional)
309
  *
310
  * @return string
311
  */
312
+ public function form_wrap( $content, $submit_button = true ) {
313
  if ( is_array( $submit_button ) ) {
314
  $content .= $this->submit_button( $submit_button );
315
+ } else if ( true === $submit_button ) {
316
  $content .= $this->submit_button();
317
+ } else if ( false !== strpos( $submit_button, '<input' ) ) {
318
  $content .= $submit_button;
319
+ } else if ( false !== strpos( $submit_button, '<button' ) ) {
320
  $content .= $submit_button;
321
+ } else if ( false !== $submit_button ) {
322
  $button_args = array_slice( func_get_args(), 1 );
323
  $content .= call_user_func_array( array( $this, 'submit_button' ), $button_args );
324
  }
327
  }
328
 
329
  /**
330
+ * Generates a table wrapped in a form.
331
  *
332
  * @param array $rows
333
+ * @param array|boolean $formdata (optional)
334
  *
335
  * @return string
336
  */
337
+ public function form_table( $rows, $formdata = false ) {
338
  $output = '';
339
+ foreach ( $rows as $row ) {
340
  $output .= $this->table_row( $row, $formdata );
341
+ }
342
 
343
  $output = $this->form_table_wrap( $output );
344
 
352
  *
353
  * @return string
354
  */
355
+ public function form_table_wrap( $content ) {
356
  $output = $this->table_wrap( $content );
357
  $output = $this->form_wrap( $output );
358
 
360
  }
361
 
362
  /**
363
+ * Generates a form table.
364
  *
365
  * @param array $rows
366
+ * @param array|boolean $formdata (optional)
367
  *
368
  * @return string
369
  */
370
+ public function table( $rows, $formdata = false ) {
371
  $output = '';
372
+ foreach ( $rows as $row ) {
373
  $output .= $this->table_row( $row, $formdata );
374
+ }
375
 
376
  $output = $this->table_wrap( $output );
377
 
379
  }
380
 
381
  /**
382
+ * Generates a table row.
383
  *
384
  * @param array $args
385
+ * @param array|boolean $formdata (optional)
386
  *
387
  * @return string
388
  */
389
+ public function table_row( $args, $formdata = false ) {
390
  return $this->row_wrap( $args['title'], $this->input( $args, $formdata ) );
391
  }
392
 
393
  /**
394
+ * Mimic scbForms inheritance.
395
  *
396
  * @see scbForms
397
  *
400
  *
401
  * @return mixed
402
  */
403
+ public function __call( $method, $args ) {
404
  if ( in_array( $method, array( 'input', 'form' ) ) ) {
405
+ if ( empty( $args[1] ) && isset( $this->options ) ) {
406
  $args[1] = $this->options->get();
407
+ }
408
 
409
+ if ( 'form' == $method ) {
410
  $args[2] = $this->nonce;
411
+ }
412
  }
413
 
414
  return call_user_func_array( array( 'scbForms', $method ), $args );
415
  }
416
 
417
  /**
418
+ * Wraps a string in a <script> tag.
419
  *
420
  * @param string $string
421
  *
422
  * @return string
423
  */
424
+ public function js_wrap( $string ) {
425
  return html( "script type='text/javascript'", $string );
426
  }
427
 
428
  /**
429
+ * Wraps a string in a <style> tag.
430
  *
431
  * @param string $string
432
  *
433
  * @return string
434
  */
435
+ public function css_wrap( $string ) {
436
  return html( "style type='text/css'", $string );
437
  }
438
 
441
 
442
 
443
  /**
444
+ * Registers a page.
445
+ *
446
+ * @return void
447
  */
448
+ public function page_init() {
449
 
450
  if ( ! $this->args['toplevel'] ) {
451
  $this->pagehook = add_submenu_page(
478
  );
479
  }
480
 
481
+ if ( ! $this->pagehook ) {
482
  return;
483
+ }
484
 
485
  add_action( 'load-' . $this->pagehook, array( $this, 'page_loaded' ) );
486
 
487
  add_action( 'admin_print_styles-' . $this->pagehook, array( $this, 'page_head' ) );
488
  }
489
 
490
+ /**
491
+ * Registers a option.
492
+ *
493
+ * @return void
494
+ */
495
+ public function option_init() {
496
  register_setting( $this->option_name, $this->option_name, array( $this, 'validate' ) );
497
  }
498
 
499
+ /**
500
+ * Checks page args.
501
+ *
502
+ * @return void
503
+ */
504
  private function check_args() {
505
+ if ( empty( $this->args['page_title'] ) ) {
506
  trigger_error( 'Page title cannot be empty', E_USER_WARNING );
507
+ }
508
 
509
  $this->args = wp_parse_args( $this->args, array(
510
  'toplevel' => '',
520
  'admin_action_priority' => 10,
521
  ) );
522
 
523
+ if ( empty( $this->args['submenu_title'] ) ) {
524
  $this->args['submenu_title'] = $this->args['menu_title'];
525
+ }
526
 
527
+ if ( empty( $this->args['page_slug'] ) ) {
528
  $this->args['page_slug'] = sanitize_title_with_dashes( $this->args['menu_title'] );
529
+ }
530
 
531
+ if ( empty( $this->args['nonce'] ) ) {
532
  $this->nonce = $this->args['page_slug'];
533
+ }
534
  }
535
 
536
  /**
537
+ * Adds contextual help.
538
+ *
539
  * @param string $help
540
  * @param string|object $screen
541
  *
542
  * @return string
543
  */
544
+ public function _contextual_help( $help, $screen ) {
545
+ if ( is_object( $screen ) ) {
546
  $screen = $screen->id;
547
+ }
548
 
549
  $actual_help = $this->page_help();
550
 
551
+ if ( $screen == $this->pagehook && $actual_help ) {
552
  return $actual_help;
553
+ }
554
 
555
  return $help;
556
  }
557
 
558
+ /**
559
+ * Displays page content.
560
+ *
561
+ * @return void
562
+ */
563
+ public function _page_content_hook() {
564
  $this->page_header();
565
  $this->page_content();
566
  $this->page_footer();
567
  }
568
 
569
  /**
570
+ * Adds an action link.
571
+ *
572
  * @param array $links
573
  *
574
  * @return array
575
  */
576
+ public function _action_link( $links ) {
577
  $url = add_query_arg( 'page', $this->args['page_slug'], admin_url( $this->args['parent'] ) );
578
 
579
  $links[] = html_link( $url, $this->args['action_link'] );
vendor/scribu/scb-framework/BoxesPage.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
-
3
- // Admin screen with metaboxes base class
4
-
5
  abstract class scbBoxesPage extends scbAdminPage {
6
  /*
7
  A box definition looks like this:
@@ -11,22 +11,41 @@ abstract class scbBoxesPage extends scbAdminPage {
11
  */
12
  protected $boxes = array();
13
 
14
- function __construct( $file = false, $options = null ) {
 
 
 
 
 
 
 
 
15
  parent::__construct( $file, $options );
16
 
17
  scbUtil::add_uninstall_hook( $this->file, array( $this, 'uninstall' ) );
18
  }
19
 
20
- function page_init() {
21
- if ( !isset( $this->args['columns'] ) )
 
 
 
 
 
22
  $this->args['columns'] = 2;
 
23
 
24
  parent::page_init();
25
 
26
  add_action( 'load-' . $this->pagehook, array( $this, 'boxes_init' ) );
27
  }
28
 
29
- function default_css() {
 
 
 
 
 
30
  ?>
31
  <style type="text/css">
32
  .postbox-container + .postbox-container {
@@ -66,11 +85,20 @@ abstract class scbBoxesPage extends scbAdminPage {
66
  padding: 0 !important;
67
  margin-bottom: 0 !important;
68
  }
 
 
 
 
69
  </style>
70
  <?php
71
  }
72
 
73
- function page_content() {
 
 
 
 
 
74
  $this->default_css();
75
 
76
  global $screen_layout_columns;
@@ -79,29 +107,33 @@ abstract class scbBoxesPage extends scbAdminPage {
79
  $hide2 = $hide3 = $hide4 = '';
80
  switch ( $screen_layout_columns ) {
81
  case 4:
82
- if( !isset( $this->args['column_widths'] ) )
83
  $this->args['column_widths'] = array( 24.5, 24.5, 24.5, 24.5 );
 
84
  break;
85
  case 3:
86
- if( !isset( $this->args['column_widths'] ) )
87
  $this->args['column_widths'] = array( 32.67, 32.67, 32.67 );
 
88
  $hide4 = 'display:none;';
89
  break;
90
  case 2:
91
- if( !isset( $this->args['column_widths'] ) )
92
  $this->args['column_widths'] = array( 49, 49 );
 
93
  $hide3 = $hide4 = 'display:none;';
94
  break;
95
  default:
96
- if( !isset( $this->args['column_widths'] ) )
97
  $this->args['column_widths'] = array( 98 );
 
98
  $hide2 = $hide3 = $hide4 = 'display:none;';
99
  }
100
 
101
  $this->args['column_widths'] = array_pad( $this->args['column_widths'], 4, 0 );
102
  }
103
  ?>
104
- <div id='<?php echo $this->pagehook ?>-widgets' class='metabox-holder'>
105
  <?php
106
  echo "\t<div class='postbox-container' style='width:{$this->args['column_widths'][0]}%'>\n";
107
  do_meta_boxes( $this->pagehook, 'normal', '' );
@@ -119,14 +151,25 @@ abstract class scbBoxesPage extends scbAdminPage {
119
  <?php
120
  }
121
 
122
- function page_footer() {
 
 
 
 
 
123
  parent::page_footer();
124
  $this->_boxes_js_init();
125
  }
126
 
127
- function form_handler() {
128
- if ( empty( $_POST ) )
 
 
 
 
 
129
  return;
 
130
 
131
  check_admin_referer( $this->nonce );
132
 
@@ -136,18 +179,25 @@ abstract class scbBoxesPage extends scbAdminPage {
136
 
137
  $handler = $box[0] . '_handler';
138
 
139
- if ( method_exists( $this, $handler ) )
140
  call_user_func_array( array( $this, $handler ), $args );
 
141
  }
142
  }
143
 
144
- function uninstall() {
 
 
 
 
 
145
  global $wpdb;
146
 
147
  $hook = str_replace( '-', '', $this->pagehook );
148
 
149
- foreach ( array( 'metaboxhidden', 'closedpostboxes', 'wp_metaboxorder', 'screen_layout' ) as $option )
150
  $keys[] = "'{$option}_{$hook}'";
 
151
 
152
  $keys = '( ' . implode( ', ', $keys ) . ' )';
153
 
@@ -157,7 +207,12 @@ abstract class scbBoxesPage extends scbAdminPage {
157
  " );
158
  }
159
 
160
- function boxes_init() {
 
 
 
 
 
161
  wp_enqueue_script( 'postbox' );
162
 
163
  add_screen_option( 'layout_columns', array(
@@ -202,37 +257,65 @@ abstract class scbBoxesPage extends scbAdminPage {
202
  }
203
  }
204
 
 
 
 
 
 
 
 
 
205
  private static function numeric_to_assoc( $argv, $keys ) {
206
  $args = array();
207
 
208
  foreach ( $keys as $i => $key ) {
209
- if ( isset( $argv[ $i ] ) )
210
  $args[ $key ] = $argv[ $i ];
 
211
  }
212
 
213
  return $args;
214
  }
215
 
216
- // Since we don't pass an object to do_meta_boxes(),
217
- // pass $box['args'] directly to each method.
218
- function _intermediate_callback( $_, $box ) {
 
 
 
 
 
 
 
219
  list( $name ) = explode( '-', $box['id'] );
220
 
221
  call_user_func_array( array( $this, $name . '_box' ), $box['args'] );
222
  }
223
 
 
 
 
 
 
 
 
224
  private function _increment( $name ) {
225
  $parts = explode( '-', $name );
226
- if ( isset( $parts[1] ) )
227
  $parts[1]++;
228
- else
229
  $parts[1] = 2;
 
230
 
231
  return implode( '-', $parts );
232
  }
233
 
234
- // Adds necesary code for JS to work
235
- function _boxes_js_init() {
 
 
 
 
236
  echo $this->js_wrap( <<<EOT
237
  jQuery( document ).ready( function( $ ){
238
  // close postboxes that should be closed
@@ -256,5 +339,3 @@ EOT
256
  }
257
  }
258
 
259
-
260
-
1
  <?php
2
+ /**
3
+ * Admin screen with metaboxes base class.
4
+ */
5
  abstract class scbBoxesPage extends scbAdminPage {
6
  /*
7
  A box definition looks like this:
11
  */
12
  protected $boxes = array();
13
 
14
+ /**
15
+ * Constructor.
16
+ *
17
+ * @param string|bool $file (optional)
18
+ * @param object $options (optional) A scbOptions object.
19
+ *
20
+ * @return void
21
+ */
22
+ public function __construct( $file = false, $options = null ) {
23
  parent::__construct( $file, $options );
24
 
25
  scbUtil::add_uninstall_hook( $this->file, array( $this, 'uninstall' ) );
26
  }
27
 
28
+ /**
29
+ * Registers a page.
30
+ *
31
+ * @return void
32
+ */
33
+ public function page_init() {
34
+ if ( ! isset( $this->args['columns'] ) ) {
35
  $this->args['columns'] = 2;
36
+ }
37
 
38
  parent::page_init();
39
 
40
  add_action( 'load-' . $this->pagehook, array( $this, 'boxes_init' ) );
41
  }
42
 
43
+ /**
44
+ * Prints default CSS styles.
45
+ *
46
+ * @return void
47
+ */
48
+ protected function default_css() {
49
  ?>
50
  <style type="text/css">
51
  .postbox-container + .postbox-container {
85
  padding: 0 !important;
86
  margin-bottom: 0 !important;
87
  }
88
+ .meta-box-sortables {
89
+ min-height: 100px;
90
+ width: 100%;
91
+ }
92
  </style>
93
  <?php
94
  }
95
 
96
+ /**
97
+ * Displays page content.
98
+ *
99
+ * @return void
100
+ */
101
+ protected function page_content() {
102
  $this->default_css();
103
 
104
  global $screen_layout_columns;
107
  $hide2 = $hide3 = $hide4 = '';
108
  switch ( $screen_layout_columns ) {
109
  case 4:
110
+ if ( ! isset( $this->args['column_widths'] ) ) {
111
  $this->args['column_widths'] = array( 24.5, 24.5, 24.5, 24.5 );
112
+ }
113
  break;
114
  case 3:
115
+ if ( ! isset( $this->args['column_widths'] ) ) {
116
  $this->args['column_widths'] = array( 32.67, 32.67, 32.67 );
117
+ }
118
  $hide4 = 'display:none;';
119
  break;
120
  case 2:
121
+ if ( ! isset( $this->args['column_widths'] ) ) {
122
  $this->args['column_widths'] = array( 49, 49 );
123
+ }
124
  $hide3 = $hide4 = 'display:none;';
125
  break;
126
  default:
127
+ if ( ! isset( $this->args['column_widths'] ) ) {
128
  $this->args['column_widths'] = array( 98 );
129
+ }
130
  $hide2 = $hide3 = $hide4 = 'display:none;';
131
  }
132
 
133
  $this->args['column_widths'] = array_pad( $this->args['column_widths'], 4, 0 );
134
  }
135
  ?>
136
+ <div id='<?php echo $this->pagehook; ?>-widgets' class='metabox-holder'>
137
  <?php
138
  echo "\t<div class='postbox-container' style='width:{$this->args['column_widths'][0]}%'>\n";
139
  do_meta_boxes( $this->pagehook, 'normal', '' );
151
  <?php
152
  }
153
 
154
+ /**
155
+ * Displays page footer.
156
+ *
157
+ * @return void
158
+ */
159
+ protected function page_footer() {
160
  parent::page_footer();
161
  $this->_boxes_js_init();
162
  }
163
 
164
+ /**
165
+ * Handles option saving.
166
+ *
167
+ * @return void
168
+ */
169
+ protected function form_handler() {
170
+ if ( empty( $_POST ) ) {
171
  return;
172
+ }
173
 
174
  check_admin_referer( $this->nonce );
175
 
179
 
180
  $handler = $box[0] . '_handler';
181
 
182
+ if ( method_exists( $this, $handler ) ) {
183
  call_user_func_array( array( $this, $handler ), $args );
184
+ }
185
  }
186
  }
187
 
188
+ /**
189
+ * Uninstalls boxes.
190
+ *
191
+ * @return void
192
+ */
193
+ public function uninstall() {
194
  global $wpdb;
195
 
196
  $hook = str_replace( '-', '', $this->pagehook );
197
 
198
+ foreach ( array( 'metaboxhidden', 'closedpostboxes', 'wp_metaboxorder', 'screen_layout' ) as $option ) {
199
  $keys[] = "'{$option}_{$hook}'";
200
+ }
201
 
202
  $keys = '( ' . implode( ', ', $keys ) . ' )';
203
 
207
  " );
208
  }
209
 
210
+ /**
211
+ * Adds boxes.
212
+ *
213
+ * @return void
214
+ */
215
+ public function boxes_init() {
216
  wp_enqueue_script( 'postbox' );
217
 
218
  add_screen_option( 'layout_columns', array(
257
  }
258
  }
259
 
260
+ /**
261
+ * Transforms numeric array to associative.
262
+ *
263
+ * @param array $argv
264
+ * @param array $keys
265
+ *
266
+ * @return array
267
+ */
268
  private static function numeric_to_assoc( $argv, $keys ) {
269
  $args = array();
270
 
271
  foreach ( $keys as $i => $key ) {
272
+ if ( isset( $argv[ $i ] ) ) {
273
  $args[ $key ] = $argv[ $i ];
274
+ }
275
  }
276
 
277
  return $args;
278
  }
279
 
280
+ /**
281
+ * Since we don't pass an object to do_meta_boxes(),
282
+ * pass $box['args'] directly to each method.
283
+ *
284
+ * @param string $_
285
+ * @param array $box
286
+ *
287
+ * @return void
288
+ */
289
+ public function _intermediate_callback( $_, $box ) {
290
  list( $name ) = explode( '-', $box['id'] );
291
 
292
  call_user_func_array( array( $this, $name . '_box' ), $box['args'] );
293
  }
294
 
295
+ /**
296
+ * Adds/Increments ID in box name.
297
+ *
298
+ * @param string $name
299
+ *
300
+ * @return string
301
+ */
302
  private function _increment( $name ) {
303
  $parts = explode( '-', $name );
304
+ if ( isset( $parts[1] ) ) {
305
  $parts[1]++;
306
+ } else {
307
  $parts[1] = 2;
308
+ }
309
 
310
  return implode( '-', $parts );
311
  }
312
 
313
+ /**
314
+ * Adds necesary code for JS to work.
315
+ *
316
+ * @return void
317
+ */
318
+ protected function _boxes_js_init() {
319
  echo $this->js_wrap( <<<EOT
320
  jQuery( document ).ready( function( $ ){
321
  // close postboxes that should be closed
339
  }
340
  }
341
 
 
 
vendor/scribu/scb-framework/Cron.php CHANGED
@@ -1,7 +1,6 @@
1
  <?php
2
-
3
  /**
4
- * wp-cron job container
5
  */
6
  class scbCron {
7
  protected $schedule;
@@ -12,19 +11,22 @@ class scbCron {
12
  protected $callback_args = array();
13
 
14
  /**
15
- * Create a new cron job
16
  *
17
- * @param string|bool $file Reference to main plugin file
18
  * @param array $args List of args:
19
  * string $action OR callback $callback
20
  * string $schedule OR number $interval
21
  * array $callback_args (optional)
 
 
22
  */
23
- function __construct( $file = false, $args ) {
24
 
25
  // Set time & schedule
26
- if ( isset( $args['time'] ) )
27
  $this->time = $args['time'];
 
28
 
29
  if ( isset( $args['interval'] ) ) {
30
  $this->schedule = $args['interval'] . 'secs';
@@ -36,18 +38,19 @@ class scbCron {
36
  // Set hook
37
  if ( isset( $args['action'] ) ) {
38
  $this->hook = $args['action'];
39
- } elseif ( isset( $args['callback'] ) ) {
40
  $this->hook = self::_callback_to_string( $args['callback'] );
41
  add_action( $this->hook, $args['callback'] );
42
- } elseif ( method_exists( $this, 'callback' ) ) {
43
  $this->hook = self::_callback_to_string( array( $this, 'callback' ) );
44
  add_action( $this->hook, $args['callback'] );
45
  } else {
46
  trigger_error( '$action OR $callback not set', E_USER_WARNING );
47
  }
48
 
49
- if ( isset( $args['callback_args'] ) )
50
  $this->callback_args = (array) $args['callback_args'];
 
51
 
52
  if ( $file && $this->schedule ) {
53
  scbUtil::add_activation_hook( $file, array( $this, 'reset' ) );
@@ -58,13 +61,15 @@ class scbCron {
58
  }
59
 
60
  /**
61
- * Change the interval of the cron job
62
  *
63
  * @param array $args List of args:
64
  * string $schedule OR number $interval
65
  * timestamp $time ( optional )
 
 
66
  */
67
- function reschedule( $args ) {
68
 
69
  if ( $args['schedule'] && $this->schedule != $args['schedule'] ) {
70
  $this->schedule = $args['schedule'];
@@ -79,40 +84,52 @@ class scbCron {
79
  }
80
 
81
  /**
82
- * Reset the schedule
 
 
83
  */
84
- function reset() {
85
  $this->unschedule();
86
  $this->schedule();
87
  }
88
 
89
  /**
90
- * Clear the cron job
 
 
91
  */
92
- function unschedule() {
93
  # wp_clear_scheduled_hook( $this->hook, $this->callback_args );
94
  self::really_clear_scheduled_hook( $this->hook );
95
  }
96
 
97
  /**
98
- * Execute the job now
99
- * @param array $args List of arguments to pass to the callback
 
 
 
100
  */
101
- function do_now( $args = null ) {
102
- if ( is_null( $args ) )
103
  $args = $this->callback_args;
 
104
 
105
  do_action_ref_array( $this->hook, $args );
106
  }
107
 
108
  /**
109
- * Execute the job with a given delay
110
- * @param int $delay in seconds
111
- * @param array $args List of arguments to pass to the callback
 
 
 
112
  */
113
- function do_once( $delay = 0, $args = null ) {
114
- if ( is_null( $args ) )
115
  $args = $this->callback_args;
 
116
 
117
  wp_clear_scheduled_hook( $this->hook, $args );
118
  wp_schedule_single_event( time() + $delay, $this->hook, $args );
@@ -122,15 +139,18 @@ class scbCron {
122
  //_____INTERNAL METHODS_____
123
 
124
  /**
 
 
125
  * @param array $schedules
126
  *
127
  * @return array
128
  */
129
- function _add_timing( $schedules ) {
130
- if ( isset( $schedules[$this->schedule] ) )
131
  return $schedules;
 
132
 
133
- $schedules[$this->schedule] = array(
134
  'interval' => $this->interval,
135
  'display' => $this->interval . ' seconds',
136
  );
@@ -138,43 +158,59 @@ class scbCron {
138
  return $schedules;
139
  }
140
 
 
 
 
 
 
141
  protected function schedule() {
142
- if ( ! $this->time )
143
  $this->time = time();
 
144
 
145
  wp_schedule_event( $this->time, $this->schedule, $this->hook, $this->callback_args );
146
  }
147
 
148
  /**
 
 
149
  * @param string $name
 
 
150
  */
151
  protected static function really_clear_scheduled_hook( $name ) {
152
  $crons = _get_cron_array();
153
 
154
  foreach ( $crons as $timestamp => $hooks ) {
155
- foreach ( $hooks as $hook => $args )
156
- if ( $hook == $name )
157
- unset( $crons[$timestamp][$hook] );
158
-
159
- if ( empty( $crons[$timestamp] ) )
160
- unset( $crons[$timestamp] );
 
 
 
161
  }
162
 
163
  _set_cron_array( $crons );
164
  }
165
 
166
  /**
 
 
167
  * @param callback $callback
168
  *
169
  * @return string
170
  */
171
  protected static function _callback_to_string( $callback ) {
172
- if ( ! is_array( $callback ) )
173
  $str = $callback;
174
- elseif ( ! is_string( $callback[0] ) )
175
  $str = get_class( $callback[0] ) . '_' . $callback[1];
176
- else
177
  $str = $callback[0] . '::' . $callback[1];
 
178
 
179
  $str .= '_hook';
180
 
1
  <?php
 
2
  /**
3
+ * WP Cron job container.
4
  */
5
  class scbCron {
6
  protected $schedule;
11
  protected $callback_args = array();
12
 
13
  /**
14
+ * Create a new cron job.
15
  *
16
+ * @param string|bool $file (optional) Reference to main plugin file
17
  * @param array $args List of args:
18
  * string $action OR callback $callback
19
  * string $schedule OR number $interval
20
  * array $callback_args (optional)
21
+ *
22
+ * @return void
23
  */
24
+ public function __construct( $file = false, $args ) {
25
 
26
  // Set time & schedule
27
+ if ( isset( $args['time'] ) ) {
28
  $this->time = $args['time'];
29
+ }
30
 
31
  if ( isset( $args['interval'] ) ) {
32
  $this->schedule = $args['interval'] . 'secs';
38
  // Set hook
39
  if ( isset( $args['action'] ) ) {
40
  $this->hook = $args['action'];
41
+ } else if ( isset( $args['callback'] ) ) {
42
  $this->hook = self::_callback_to_string( $args['callback'] );
43
  add_action( $this->hook, $args['callback'] );
44
+ } else if ( method_exists( $this, 'callback' ) ) {
45
  $this->hook = self::_callback_to_string( array( $this, 'callback' ) );
46
  add_action( $this->hook, $args['callback'] );
47
  } else {
48
  trigger_error( '$action OR $callback not set', E_USER_WARNING );
49
  }
50
 
51
+ if ( isset( $args['callback_args'] ) ) {
52
  $this->callback_args = (array) $args['callback_args'];
53
+ }
54
 
55
  if ( $file && $this->schedule ) {
56
  scbUtil::add_activation_hook( $file, array( $this, 'reset' ) );
61
  }
62
 
63
  /**
64
+ * Change the interval of the cron job.
65
  *
66
  * @param array $args List of args:
67
  * string $schedule OR number $interval
68
  * timestamp $time ( optional )
69
+ *
70
+ * @return void
71
  */
72
+ public function reschedule( $args ) {
73
 
74
  if ( $args['schedule'] && $this->schedule != $args['schedule'] ) {
75
  $this->schedule = $args['schedule'];
84
  }
85
 
86
  /**
87
+ * Reset the schedule.
88
+ *
89
+ * @return void
90
  */
91
+ public function reset() {
92
  $this->unschedule();
93
  $this->schedule();
94
  }
95
 
96
  /**
97
+ * Clear the cron job.
98
+ *
99
+ * @return void
100
  */
101
+ public function unschedule() {
102
  # wp_clear_scheduled_hook( $this->hook, $this->callback_args );
103
  self::really_clear_scheduled_hook( $this->hook );
104
  }
105
 
106
  /**
107
+ * Execute the job now.
108
+ *
109
+ * @param array $args (optional) List of arguments to pass to the callback.
110
+ *
111
+ * @return void
112
  */
113
+ public function do_now( $args = null ) {
114
+ if ( is_null( $args ) ) {
115
  $args = $this->callback_args;
116
+ }
117
 
118
  do_action_ref_array( $this->hook, $args );
119
  }
120
 
121
  /**
122
+ * Execute the job with a given delay.
123
+ *
124
+ * @param int $delay (optional) Delay in seconds.
125
+ * @param array $args (optional) List of arguments to pass to the callback.
126
+ *
127
+ * @return void
128
  */
129
+ public function do_once( $delay = 0, $args = null ) {
130
+ if ( is_null( $args ) ) {
131
  $args = $this->callback_args;
132
+ }
133
 
134
  wp_clear_scheduled_hook( $this->hook, $args );
135
  wp_schedule_single_event( time() + $delay, $this->hook, $args );
139
  //_____INTERNAL METHODS_____
140
 
141
  /**
142
+ * Adds custom schedule timing.
143
+ *
144
  * @param array $schedules
145
  *
146
  * @return array
147
  */
148
+ public function _add_timing( $schedules ) {
149
+ if ( isset( $schedules[ $this->schedule ] ) ) {
150
  return $schedules;
151
+ }
152
 
153
+ $schedules[ $this->schedule ] = array(
154
  'interval' => $this->interval,
155
  'display' => $this->interval . ' seconds',
156
  );
158
  return $schedules;
159
  }
160
 
161
+ /**
162
+ * Schedule the job.
163
+ *
164
+ * @return void
165
+ */
166
  protected function schedule() {
167
+ if ( ! $this->time ) {
168
  $this->time = time();
169
+ }
170
 
171
  wp_schedule_event( $this->time, $this->schedule, $this->hook, $this->callback_args );
172
  }
173
 
174
  /**
175
+ * Clears scheduled job.
176
+ *
177
  * @param string $name
178
+ *
179
+ * @return void
180
  */
181
  protected static function really_clear_scheduled_hook( $name ) {
182
  $crons = _get_cron_array();
183
 
184
  foreach ( $crons as $timestamp => $hooks ) {
185
+ foreach ( $hooks as $hook => $args ) {
186
+ if ( $hook == $name ) {
187
+ unset( $crons[ $timestamp ][ $hook ] );
188
+ }
189
+ }
190
+
191
+ if ( empty( $crons[ $timestamp ] ) ) {
192
+ unset( $crons[ $timestamp ] );
193
+ }
194
  }
195
 
196
  _set_cron_array( $crons );
197
  }
198
 
199
  /**
200
+ * Generates a hook name from given callback.
201
+ *
202
  * @param callback $callback
203
  *
204
  * @return string
205
  */
206
  protected static function _callback_to_string( $callback ) {
207
+ if ( ! is_array( $callback ) ) {
208
  $str = $callback;
209
+ } else if ( ! is_string( $callback[0] ) ) {
210
  $str = get_class( $callback[0] ) . '_' . $callback[1];
211
+ } else {
212
  $str = $callback[0] . '::' . $callback[1];
213
+ }
214
 
215
  $str .= '_hook';
216
 
vendor/scribu/scb-framework/Forms.php CHANGED
@@ -1,48 +1,52 @@
1
  <?php
2
-
3
  /**
4
- * Data-aware form generator
5
  */
6
  class scbForms {
7
 
8
  const TOKEN = '%input%';
9
 
10
  /**
 
 
11
  * @param array|scbFormField_I $args
12
  * @param mixed $value
13
  *
14
  * @return string
15
  */
16
- static function input_with_value( $args, $value ) {
17
  $field = scbFormField::create( $args );
18
 
19
  return $field->render( $value );
20
  }
21
 
22
  /**
 
 
23
  * @param array|scbFormField_I $args
24
- * @param array $formdata
25
  *
26
  * @return string
27
  */
28
- static function input( $args, $formdata = null ) {
29
  $field = scbFormField::create( $args );
30
 
31
  return $field->render( scbForms::get_value( $args['name'], $formdata ) );
32
  }
33
 
34
  /**
35
- * Generates a table wrapped in a form
36
  *
37
  * @param array $rows
38
- * @param array $formdata
39
  *
40
  * @return string
41
  */
42
- static function form_table( $rows, $formdata = null ) {
43
  $output = '';
44
- foreach ( $rows as $row )
45
  $output .= self::table_row( $row, $formdata );
 
46
 
47
  $output = self::form_table_wrap( $output );
48
 
@@ -50,18 +54,19 @@ class scbForms {
50
  }
51
 
52
  /**
53
- * Generates a form
54
  *
55
  * @param array $inputs
56
- * @param array $formdata
57
  * @param string $nonce
58
  *
59
  * @return string
60
  */
61
- static function form( $inputs, $formdata = null, $nonce ) {
62
  $output = '';
63
- foreach ( $inputs as $input )
64
  $output .= self::input( $input, $formdata );
 
65
 
66
  $output = self::form_wrap( $output, $nonce );
67
 
@@ -69,17 +74,18 @@ class scbForms {
69
  }
70
 
71
  /**
72
- * Generates a table
73
  *
74
  * @param array $rows
75
- * @param array $formdata
76
  *
77
  * @return string
78
  */
79
- static function table( $rows, $formdata = null ) {
80
  $output = '';
81
- foreach ( $rows as $row )
82
  $output .= self::table_row( $row, $formdata );
 
83
 
84
  $output = self::table_wrap( $output );
85
 
@@ -87,14 +93,14 @@ class scbForms {
87
  }
88
 
89
  /**
90
- * Generates a table row
91
  *
92
  * @param array $args
93
- * @param array $formdata
94
  *
95
  * @return string
96
  */
97
- static function table_row( $args, $formdata = null ) {
98
  return self::row_wrap( $args['title'], self::input( $args, $formdata ) );
99
  }
100
 
@@ -102,22 +108,26 @@ class scbForms {
102
  // ____________WRAPPERS____________
103
 
104
  /**
 
 
105
  * @param string $content
106
- * @param string $nonce
107
  *
108
  * @return string
109
  */
110
- static function form_table_wrap( $content, $nonce = 'update_options' ) {
111
  return self::form_wrap( self::table_wrap( $content ), $nonce );
112
  }
113
 
114
  /**
 
 
115
  * @param string $content
116
- * @param string $nonce
117
  *
118
  * @return string
119
  */
120
- static function form_wrap( $content, $nonce = 'update_options' ) {
121
  return html( "form method='post' action=''",
122
  $content,
123
  wp_nonce_field( $nonce, '_wpnonce', $referer = true, $echo = false )
@@ -125,21 +135,25 @@ class scbForms {
125
  }
126
 
127
  /**
 
 
128
  * @param string $content
129
  *
130
  * @return string
131
  */
132
- static function table_wrap( $content ) {
133
  return html( "table class='form-table'", $content );
134
  }
135
 
136
  /**
 
 
137
  * @param string $title
138
  * @param string $content
139
  *
140
  * @return string
141
  */
142
- static function row_wrap( $title, $content ) {
143
  return html( 'tr',
144
  html( "th scope='row'", $title ),
145
  html( 'td', $content )
@@ -160,7 +174,7 @@ class scbForms {
160
  *
161
  * @return string
162
  */
163
- static function get_name( $name ) {
164
  $name = (array) $name;
165
 
166
  $name_str = array_shift( $name );
@@ -177,16 +191,17 @@ class scbForms {
177
  *
178
  * @param string $name The name of the value
179
  * @param array $value The data that will be traversed
180
- * @param mixed $fallback The value returned when the key is not found
181
  *
182
  * @return mixed
183
  */
184
- static function get_value( $name, $value, $fallback = null ) {
185
  foreach ( (array) $name as $key ) {
186
- if ( !isset( $value[ $key ] ) )
187
  return $fallback;
 
188
 
189
- $value = $value[$key];
190
  }
191
 
192
  return $value;
@@ -196,12 +211,12 @@ class scbForms {
196
  * Given a list of fields, validate some data.
197
  *
198
  * @param array $fields List of args that would be sent to scbForms::input()
199
- * @param array $data The data to validate. Defaults to $_POST
200
- * @param array $to_update Existing data to populate. Necessary for nested values
201
  *
202
  * @return array
203
  */
204
- static function validate_post_data( $fields, $data = null, $to_update = array() ) {
205
  if ( null === $data ) {
206
  $data = stripslashes_deep( $_POST );
207
  }
@@ -213,8 +228,9 @@ class scbForms {
213
 
214
  $value = $fieldObj->validate( $value );
215
 
216
- if ( null !== $value )
217
  self::set_value( $to_update, $field['name'], $value );
 
218
  }
219
 
220
  return $to_update;
@@ -227,11 +243,11 @@ class scbForms {
227
  *
228
  * @param array $args Field arguments.
229
  * @param int $object_id The object ID the metadata is attached to
230
- * @param string $meta_type
231
  *
232
  * @return string
233
  */
234
- static function input_from_meta( $args, $object_id, $meta_type = 'post' ) {
235
  $single = ( 'checkbox' != $args['type'] );
236
 
237
  $key = (array) $args['name'];
@@ -243,51 +259,63 @@ class scbForms {
243
  }
244
 
245
  /**
 
 
246
  * @param array $fields
247
  * @param array $data
248
- * @param int $object_id
249
- * @param string $meta_type
 
 
250
  */
251
- static function update_meta( $fields, $data, $object_id, $meta_type = 'post' ) {
252
  foreach ( $fields as $field_args ) {
253
  $key = $field_args['name'];
254
 
255
  if ( 'checkbox' == $field_args['type'] ) {
256
- $new_values = isset( $data[$key] ) ? $data[$key] : array();
257
 
258
  $old_values = get_metadata( $meta_type, $object_id, $key );
259
 
260
- foreach ( array_diff( $new_values, $old_values ) as $value )
261
  add_metadata( $meta_type, $object_id, $key, $value );
 
262
 
263
- foreach ( array_diff( $old_values, $new_values ) as $value )
264
  delete_metadata( $meta_type, $object_id, $key, $value );
 
265
  } else {
266
- $value = isset( $data[$key] ) ? $data[$key] : '';
267
 
268
- if ( '' === $value )
269
  delete_metadata( $meta_type, $object_id, $key );
270
- else
271
  update_metadata( $meta_type, $object_id, $key, $value );
 
272
  }
273
  }
274
  }
275
 
276
  /**
 
 
277
  * @param array $arr
278
  * @param string $name
279
  * @param mixed $value
 
 
280
  */
281
  private static function set_value( &$arr, $name, $value ) {
282
  $name = (array) $name;
283
 
284
  $final_key = array_pop( $name );
285
 
286
- while ( !empty( $name ) ) {
287
  $key = array_shift( $name );
288
 
289
- if ( !isset( $arr[ $key ] ) )
290
  $arr[ $key ] = array();
 
291
 
292
  $arr =& $arr[ $key ];
293
  }
@@ -298,30 +326,38 @@ class scbForms {
298
 
299
 
300
  /**
301
- * A wrapper for scbForms, containing the formdata
302
  */
303
  class scbForm {
304
  protected $data = array();
305
  protected $prefix = array();
306
 
307
  /**
 
 
308
  * @param array $data
309
- * @param string|boolean $prefix
 
 
310
  */
311
- function __construct( $data, $prefix = false ) {
312
- if ( is_array( $data ) )
313
  $this->data = $data;
 
314
 
315
- if ( $prefix )
316
  $this->prefix = (array) $prefix;
 
317
  }
318
 
319
  /**
 
 
320
  * @param string $path
321
  *
322
- * @return scbForm
323
  */
324
- function traverse_to( $path ) {
325
  $data = scbForms::get_value( $path, $this->data );
326
 
327
  $prefix = array_merge( $this->prefix, (array) $path );
@@ -330,14 +366,16 @@ class scbForm {
330
  }
331
 
332
  /**
 
 
333
  * @param array $args
334
  *
335
  * @return string
336
  */
337
- function input( $args ) {
338
  $value = scbForms::get_value( $args['name'], $this->data );
339
 
340
- if ( !empty( $this->prefix ) ) {
341
  $args['name'] = array_merge( $this->prefix, (array) $args['name'] );
342
  }
343
 
@@ -351,9 +389,9 @@ class scbForm {
351
  interface scbFormField_I {
352
 
353
  /**
354
- * Generate the corresponding HTML for a field
355
  *
356
- * @param mixed $value The value to use
357
  *
358
  * @return string
359
  */
@@ -362,7 +400,7 @@ interface scbFormField_I {
362
  /**
363
  * Validates a value against a field.
364
  *
365
- * @param mixed $value The value to check
366
  *
367
  * @return mixed null if the validation failed, sanitized value otherwise.
368
  */
@@ -377,13 +415,16 @@ abstract class scbFormField implements scbFormField_I {
377
  protected $args;
378
 
379
  /**
 
 
380
  * @param array|scbFormField_I $args
381
  *
382
  * @return mixed false on failure or instance of form class
383
  */
384
  public static function create( $args ) {
385
- if ( is_a( $args, 'scbFormField_I' ) )
386
  return $args;
 
387
 
388
  if ( empty( $args['name'] ) ) {
389
  return trigger_error( 'Empty name', E_USER_WARNING );
@@ -399,8 +440,9 @@ abstract class scbFormField implements scbFormField_I {
399
  unset( $args['values'] );
400
  }
401
 
402
- if ( isset( $args['extra'] ) && !is_array( $args['extra'] ) )
403
  $args['extra'] = shortcode_parse_atts( $args['extra'] );
 
404
 
405
  $args = wp_parse_args( $args, array(
406
  'desc' => '',
@@ -410,34 +452,42 @@ abstract class scbFormField implements scbFormField_I {
410
  ) );
411
 
412
  // depends on $args['desc']
413
- if ( isset( $args['choices'] ) )
414
  self::_expand_choices( $args );
 
415
 
416
  switch ( $args['type'] ) {
417
- case 'radio':
418
- return new scbRadiosField( $args );
419
- case 'select':
420
- return new scbSelectField( $args );
421
- case 'checkbox':
422
- if ( isset( $args['choices'] ) )
423
- return new scbMultipleChoiceField( $args );
424
- else
425
- return new scbSingleCheckboxField( $args );
426
- case 'custom':
427
- return new scbCustomField( $args );
428
- default:
429
- return new scbTextField( $args );
 
430
  }
431
  }
432
 
433
  /**
 
 
434
  * @param array $args
 
 
435
  */
436
  protected function __construct( $args ) {
437
  $this->args = $args;
438
  }
439
 
440
  /**
 
 
441
  * @param string $key
442
  *
443
  * @return mixed
@@ -447,6 +497,8 @@ abstract class scbFormField implements scbFormField_I {
447
  }
448
 
449
  /**
 
 
450
  * @param string $key
451
  *
452
  * @return bool
@@ -456,18 +508,22 @@ abstract class scbFormField implements scbFormField_I {
456
  }
457
 
458
  /**
459
- * @param mixed $value
 
 
460
  *
461
  * @return string
462
  */
463
  public function render( $value = null ) {
464
- if ( null === $value && isset( $this->default ) )
465
  $value = $this->default;
 
466
 
467
  $args = $this->args;
468
 
469
- if ( null !== $value )
470
  $this->_set_value( $args, $value );
 
471
 
472
  $args['name'] = scbForms::get_name( $args['name'] );
473
 
@@ -483,14 +539,14 @@ abstract class scbFormField implements scbFormField_I {
483
  abstract protected function _set_value( &$args, $value );
484
 
485
  /**
486
- * The actual rendering
487
  *
488
  * @param array $args
489
  */
490
  abstract protected function _render( $args );
491
 
492
  /**
493
- * Handle args for a single checkbox or radio input
494
  *
495
  * @param array $args
496
  *
@@ -506,14 +562,15 @@ abstract class scbFormField implements scbFormField_I {
506
 
507
  $args['extra']['checked'] = $args['checked'];
508
 
509
- if ( is_null( $args['desc'] ) && ! is_bool( $args['value'] ) )
510
  $args['desc'] = str_replace( '[]', '', $args['value'] );
 
511
 
512
  return self::_input_gen( $args );
513
  }
514
 
515
  /**
516
- * Generate html with the final args
517
  *
518
  * @param array $args
519
  *
@@ -540,6 +597,8 @@ abstract class scbFormField implements scbFormField_I {
540
  }
541
 
542
  /**
 
 
543
  * @param string $input
544
  * @param string $desc
545
  * @param string $desc_pos
@@ -551,6 +610,8 @@ abstract class scbFormField implements scbFormField_I {
551
  }
552
 
553
  /**
 
 
554
  * @param string $input
555
  * @param string $desc
556
  * @param string $desc_pos
@@ -558,13 +619,15 @@ abstract class scbFormField implements scbFormField_I {
558
  * @return string
559
  */
560
  protected static function add_desc( $input, $desc, $desc_pos ) {
561
- if ( empty( $desc ) )
562
  return $input;
 
563
 
564
- if ( 'before' == $desc_pos )
565
  return $desc . ' ' . $input;
566
- else
567
  return $input . ' ' . $desc;
 
568
  }
569
 
570
  /**
@@ -573,17 +636,19 @@ abstract class scbFormField implements scbFormField_I {
573
  private static function _expand_choices( &$args ) {
574
  $choices =& $args['choices'];
575
 
576
- if ( !empty( $choices ) && !self::is_associative( $choices ) ) {
577
  if ( is_array( $args['desc'] ) ) {
578
  $choices = array_combine( $choices, $args['desc'] ); // back-compat
579
  $args['desc'] = false;
580
- } elseif ( !isset( $args['numeric'] ) || !$args['numeric'] ) {
581
  $choices = array_combine( $choices, $choices );
582
  }
583
  }
584
  }
585
 
586
  /**
 
 
587
  * @param array $array
588
  *
589
  * @return bool
@@ -600,6 +665,8 @@ abstract class scbFormField implements scbFormField_I {
600
  class scbTextField extends scbFormField {
601
 
602
  /**
 
 
603
  * @param string $value
604
  *
605
  * @return string
@@ -611,6 +678,8 @@ class scbTextField extends scbFormField {
611
  }
612
 
613
  /**
 
 
614
  * @param array $args
615
  *
616
  * @return string
@@ -622,15 +691,20 @@ class scbTextField extends scbFormField {
622
  'extra' => array( 'class' => 'regular-text' ),
623
  ) );
624
 
625
- if ( ! isset( $args['extra']['id'] ) && ! is_array( $args['name'] ) && false === strpos( $args['name'], '[' ) )
626
  $args['extra']['id'] = $args['name'];
 
627
 
628
  return scbFormField::_input_gen( $args );
629
  }
630
 
631
  /**
 
 
632
  * @param array $args
633
  * @param string $value
 
 
634
  */
635
  protected function _set_value( &$args, $value ) {
636
  $args['value'] = $value;
@@ -643,18 +717,23 @@ class scbTextField extends scbFormField {
643
  abstract class scbSingleChoiceField extends scbFormField {
644
 
645
  /**
 
 
646
  * @param mixed $value
647
  *
648
  * @return mixed|null
649
  */
650
  public function validate( $value ) {
651
- if ( isset( $this->choices[ $value ] ) )
652
  return $value;
 
653
 
654
  return null;
655
  }
656
 
657
  /**
 
 
658
  * @param array $args
659
  *
660
  * @return string
@@ -667,21 +746,27 @@ abstract class scbSingleChoiceField extends scbFormField {
667
  if ( isset( $args['selected'] ) ) {
668
  $args['selected'] = (string) $args['selected'];
669
  } else {
670
- $args['selected'] = array('foo'); // hack to make default blank
671
  }
672
 
673
  return $this->_render_specific( $args );
674
  }
675
 
676
  /**
677
- * @param array $args
678
- * @param mixed $value
 
 
 
 
679
  */
680
  protected function _set_value( &$args, $value ) {
681
  $args['selected'] = $value;
682
  }
683
 
684
  /**
 
 
685
  * @param array $args
686
  *
687
  * @return string
@@ -695,6 +780,8 @@ abstract class scbSingleChoiceField extends scbFormField {
695
  class scbSelectField extends scbSingleChoiceField {
696
 
697
  /**
 
 
698
  * @param array $args
699
  *
700
  * @return string
@@ -744,6 +831,8 @@ class scbSelectField extends scbSingleChoiceField {
744
  class scbRadiosField extends scbSelectField {
745
 
746
  /**
 
 
747
  * @param array $args
748
  *
749
  * @return string
@@ -781,6 +870,8 @@ class scbRadiosField extends scbSelectField {
781
  class scbMultipleChoiceField extends scbFormField {
782
 
783
  /**
 
 
784
  * @param mixed $value
785
  *
786
  * @return array
@@ -790,6 +881,8 @@ class scbMultipleChoiceField extends scbFormField {
790
  }
791
 
792
  /**
 
 
793
  * @param array $args
794
  *
795
  * @return string
@@ -800,8 +893,9 @@ class scbMultipleChoiceField extends scbFormField {
800
  'checked' => null,
801
  ) );
802
 
803
- if ( ! is_array( $args['checked'] ) )
804
  $args['checked'] = array();
 
805
 
806
  $opts = '';
807
  foreach ( $args['choices'] as $value => $title ) {
@@ -821,8 +915,12 @@ class scbMultipleChoiceField extends scbFormField {
821
  }
822
 
823
  /**
824
- * @param array $args
825
- * @param mixed $value
 
 
 
 
826
  */
827
  protected function _set_value( &$args, $value ) {
828
  $args['checked'] = (array) $value;
@@ -835,6 +933,8 @@ class scbMultipleChoiceField extends scbFormField {
835
  class scbSingleCheckboxField extends scbFormField {
836
 
837
  /**
 
 
838
  * @param mixed $value
839
  *
840
  * @return boolean
@@ -844,6 +944,8 @@ class scbSingleCheckboxField extends scbFormField {
844
  }
845
 
846
  /**
 
 
847
  * @param array $args
848
  *
849
  * @return string
@@ -858,15 +960,20 @@ class scbSingleCheckboxField extends scbFormField {
858
 
859
  $args['extra']['checked'] = $args['checked'];
860
 
861
- if ( is_null( $args['desc'] ) && ! is_bool( $args['value'] ) )
862
  $args['desc'] = str_replace( '[]', '', $args['value'] );
 
863
 
864
  return scbFormField::_input_gen( $args );
865
  }
866
 
867
  /**
868
- * @param array $args
869
- * @param mixed $value
 
 
 
 
870
  */
871
  protected function _set_value( &$args, $value ) {
872
  $args['checked'] = ( $value || ( isset( $args['value'] ) && $value == $args['value'] ) );
@@ -881,7 +988,11 @@ class scbCustomField implements scbFormField_I {
881
  protected $args;
882
 
883
  /**
 
 
884
  * @param array $args
 
 
885
  */
886
  function __construct( $args ) {
887
  $this->args = wp_parse_args( $args, array(
@@ -891,6 +1002,8 @@ class scbCustomField implements scbFormField_I {
891
  }
892
 
893
  /**
 
 
894
  * @param string $key
895
  *
896
  * @return mixed
@@ -900,6 +1013,8 @@ class scbCustomField implements scbFormField_I {
900
  }
901
 
902
  /**
 
 
903
  * @param string $key
904
  *
905
  * @return boolean
@@ -909,7 +1024,9 @@ class scbCustomField implements scbFormField_I {
909
  }
910
 
911
  /**
912
- * @param mixed $value
 
 
913
  *
914
  * @return string
915
  */
@@ -918,6 +1035,8 @@ class scbCustomField implements scbFormField_I {
918
  }
919
 
920
  /**
 
 
921
  * @param mixed $value
922
  *
923
  * @return mixed
1
  <?php
 
2
  /**
3
+ * Data-aware form generator.
4
  */
5
  class scbForms {
6
 
7
  const TOKEN = '%input%';
8
 
9
  /**
10
+ * Generates form field.
11
+ *
12
  * @param array|scbFormField_I $args
13
  * @param mixed $value
14
  *
15
  * @return string
16
  */
17
+ public static function input_with_value( $args, $value ) {
18
  $field = scbFormField::create( $args );
19
 
20
  return $field->render( $value );
21
  }
22
 
23
  /**
24
+ * Generates form field.
25
+ *
26
  * @param array|scbFormField_I $args
27
+ * @param array $formdata (optional)
28
  *
29
  * @return string
30
  */
31
+ public static function input( $args, $formdata = null ) {
32
  $field = scbFormField::create( $args );
33
 
34
  return $field->render( scbForms::get_value( $args['name'], $formdata ) );
35
  }
36
 
37
  /**
38
+ * Generates a table wrapped in a form.
39
  *
40
  * @param array $rows
41
+ * @param array $formdata (optional)
42
  *
43
  * @return string
44
  */
45
+ public static function form_table( $rows, $formdata = null ) {
46
  $output = '';
47
+ foreach ( $rows as $row ) {
48
  $output .= self::table_row( $row, $formdata );
49
+ }
50
 
51
  $output = self::form_table_wrap( $output );
52
 
54
  }
55
 
56
  /**
57
+ * Generates a form.
58
  *
59
  * @param array $inputs
60
+ * @param array $formdata (optional)
61
  * @param string $nonce
62
  *
63
  * @return string
64
  */
65
+ public static function form( $inputs, $formdata = null, $nonce ) {
66
  $output = '';
67
+ foreach ( $inputs as $input ) {
68
  $output .= self::input( $input, $formdata );
69
+ }
70
 
71
  $output = self::form_wrap( $output, $nonce );
72
 
74
  }
75
 
76
  /**
77
+ * Generates a table.
78
  *
79
  * @param array $rows
80
+ * @param array $formdata (optional)
81
  *
82
  * @return string
83
  */
84
+ public static function table( $rows, $formdata = null ) {
85
  $output = '';
86
+ foreach ( $rows as $row ) {
87
  $output .= self::table_row( $row, $formdata );
88
+ }
89
 
90
  $output = self::table_wrap( $output );
91
 
93
  }
94
 
95
  /**
96
+ * Generates a table row.
97
  *
98
  * @param array $args
99
+ * @param array $formdata (optional)
100
  *
101
  * @return string
102
  */
103
+ public static function table_row( $args, $formdata = null ) {
104
  return self::row_wrap( $args['title'], self::input( $args, $formdata ) );
105
  }
106
 
108
  // ____________WRAPPERS____________
109
 
110
  /**
111
+ * Wraps a table in a form.
112
+ *
113
  * @param string $content
114
+ * @param string $nonce (optional)
115
  *
116
  * @return string
117
  */
118
+ public static function form_table_wrap( $content, $nonce = 'update_options' ) {
119
  return self::form_wrap( self::table_wrap( $content ), $nonce );
120
  }
121
 
122
  /**
123
+ * Wraps a content in a form.
124
+ *
125
  * @param string $content
126
+ * @param string $nonce (optional)
127
  *
128
  * @return string
129
  */
130
+ public static function form_wrap( $content, $nonce = 'update_options' ) {
131
  return html( "form method='post' action=''",
132
  $content,
133
  wp_nonce_field( $nonce, '_wpnonce', $referer = true, $echo = false )
135
  }
136
 
137
  /**
138
+ * Wraps a content in a table.
139
+ *
140
  * @param string $content
141
  *
142
  * @return string
143
  */
144
+ public static function table_wrap( $content ) {
145
  return html( "table class='form-table'", $content );
146
  }
147
 
148
  /**
149
+ * Wraps a content in a table row.
150
+ *
151
  * @param string $title
152
  * @param string $content
153
  *
154
  * @return string
155
  */
156
+ public static function row_wrap( $title, $content ) {
157
  return html( 'tr',
158
  html( "th scope='row'", $title ),
159
  html( 'td', $content )
174
  *
175
  * @return string
176
  */
177
+ public static function get_name( $name ) {
178
  $name = (array) $name;
179
 
180
  $name_str = array_shift( $name );
191
  *
192
  * @param string $name The name of the value
193
  * @param array $value The data that will be traversed
194
+ * @param mixed $fallback (optional) The value returned when the key is not found
195
  *
196
  * @return mixed
197
  */
198
+ public static function get_value( $name, $value, $fallback = null ) {
199
  foreach ( (array) $name as $key ) {
200
+ if ( ! isset( $value[ $key ] ) ) {
201
  return $fallback;
202
+ }
203
 
204
+ $value = $value[ $key ];
205
  }
206
 
207
  return $value;
211
  * Given a list of fields, validate some data.
212
  *
213
  * @param array $fields List of args that would be sent to scbForms::input()
214
+ * @param array $data (optional) The data to validate. Defaults to $_POST
215
+ * @param array $to_update (optional) Existing data to populate. Necessary for nested values
216
  *
217
  * @return array
218
  */
219
+ public static function validate_post_data( $fields, $data = null, $to_update = array() ) {
220
  if ( null === $data ) {
221
  $data = stripslashes_deep( $_POST );
222
  }
228
 
229
  $value = $fieldObj->validate( $value );
230
 
231
+ if ( null !== $value ) {
232
  self::set_value( $to_update, $field['name'], $value );
233
+ }
234
  }
235
 
236
  return $to_update;
243
  *
244
  * @param array $args Field arguments.
245
  * @param int $object_id The object ID the metadata is attached to
246
+ * @param string $meta_type (optional)
247
  *
248
  * @return string
249
  */
250
+ public static function input_from_meta( $args, $object_id, $meta_type = 'post' ) {
251
  $single = ( 'checkbox' != $args['type'] );
252
 
253
  $key = (array) $args['name'];
259
  }
260
 
261
  /**
262
+ * Updates metadata for passed list of fields.
263
+ *
264
  * @param array $fields
265
  * @param array $data
266
+ * @param int $object_id The object ID the metadata is attached to
267
+ * @param string $meta_type (optional) Defaults to 'post'
268
+ *
269
+ * @return void
270
  */
271
+ public static function update_meta( $fields, $data, $object_id, $meta_type = 'post' ) {
272
  foreach ( $fields as $field_args ) {
273
  $key = $field_args['name'];
274
 
275
  if ( 'checkbox' == $field_args['type'] ) {
276
+ $new_values = isset( $data[ $key ] ) ? $data[ $key ] : array();
277
 
278
  $old_values = get_metadata( $meta_type, $object_id, $key );
279
 
280
+ foreach ( array_diff( $new_values, $old_values ) as $value ) {
281
  add_metadata( $meta_type, $object_id, $key, $value );
282
+ }
283
 
284
+ foreach ( array_diff( $old_values, $new_values ) as $value ) {
285
  delete_metadata( $meta_type, $object_id, $key, $value );
286
+ }
287
  } else {
288
+ $value = isset( $data[ $key ] ) ? $data[ $key ] : '';
289
 
290
+ if ( '' === $value ) {
291
  delete_metadata( $meta_type, $object_id, $key );
292
+ } else {
293
  update_metadata( $meta_type, $object_id, $key, $value );
294
+ }
295
  }
296
  }
297
  }
298
 
299
  /**
300
+ * Sets value using a reference.
301
+ *
302
  * @param array $arr
303
  * @param string $name
304
  * @param mixed $value
305
+ *
306
+ * @return void
307
  */
308
  private static function set_value( &$arr, $name, $value ) {
309
  $name = (array) $name;
310
 
311
  $final_key = array_pop( $name );
312
 
313
+ while ( ! empty( $name ) ) {
314
  $key = array_shift( $name );
315
 
316
+ if ( ! isset( $arr[ $key ] ) ) {
317
  $arr[ $key ] = array();
318
+ }
319
 
320
  $arr =& $arr[ $key ];
321
  }
326
 
327
 
328
  /**
329
+ * A wrapper for scbForms, containing the formdata.
330
  */
331
  class scbForm {
332
  protected $data = array();
333
  protected $prefix = array();
334
 
335
  /**
336
+ * Constructor.
337
+ *
338
  * @param array $data
339
+ * @param string|boolean $prefix (optional)
340
+ *
341
+ * @return void
342
  */
343
+ public function __construct( $data, $prefix = false ) {
344
+ if ( is_array( $data ) ) {
345
  $this->data = $data;
346
+ }
347
 
348
+ if ( $prefix ) {
349
  $this->prefix = (array) $prefix;
350
+ }
351
  }
352
 
353
  /**
354
+ * Traverses the form.
355
+ *
356
  * @param string $path
357
  *
358
+ * @return object A scbForm
359
  */
360
+ public function traverse_to( $path ) {
361
  $data = scbForms::get_value( $path, $this->data );
362
 
363
  $prefix = array_merge( $this->prefix, (array) $path );
366
  }
367
 
368
  /**
369
+ * Generates form field.
370
+ *
371
  * @param array $args
372
  *
373
  * @return string
374
  */
375
+ public function input( $args ) {
376
  $value = scbForms::get_value( $args['name'], $this->data );
377
 
378
+ if ( ! empty( $this->prefix ) ) {
379
  $args['name'] = array_merge( $this->prefix, (array) $args['name'] );
380
  }
381
 
389
  interface scbFormField_I {
390
 
391
  /**
392
+ * Generate the corresponding HTML for a field.
393
  *
394
+ * @param mixed $value (optional) The value to use.
395
  *
396
  * @return string
397
  */
400
  /**
401
  * Validates a value against a field.
402
  *
403
+ * @param mixed $value The value to check.
404
  *
405
  * @return mixed null if the validation failed, sanitized value otherwise.
406
  */
415
  protected $args;
416
 
417
  /**
418
+ * Creates form field.
419
+ *
420
  * @param array|scbFormField_I $args
421
  *
422
  * @return mixed false on failure or instance of form class
423
  */
424
  public static function create( $args ) {
425
+ if ( is_a( $args, 'scbFormField_I' ) ) {
426
  return $args;
427
+ }
428
 
429
  if ( empty( $args['name'] ) ) {
430
  return trigger_error( 'Empty name', E_USER_WARNING );
440
  unset( $args['values'] );
441
  }
442
 
443
+ if ( isset( $args['extra'] ) && ! is_array( $args['extra'] ) ) {
444
  $args['extra'] = shortcode_parse_atts( $args['extra'] );
445
+ }
446
 
447
  $args = wp_parse_args( $args, array(
448
  'desc' => '',
452
  ) );
453
 
454
  // depends on $args['desc']
455
+ if ( isset( $args['choices'] ) ) {
456
  self::_expand_choices( $args );
457
+ }
458
 
459
  switch ( $args['type'] ) {
460
+ case 'radio':
461
+ return new scbRadiosField( $args );
462
+ case 'select':
463
+ return new scbSelectField( $args );
464
+ case 'checkbox':
465
+ if ( isset( $args['choices'] ) ) {
466
+ return new scbMultipleChoiceField( $args );
467
+ } else {
468
+ return new scbSingleCheckboxField( $args );
469
+ }
470
+ case 'custom':
471
+ return new scbCustomField( $args );
472
+ default:
473
+ return new scbTextField( $args );
474
  }
475
  }
476
 
477
  /**
478
+ * Constructor.
479
+ *
480
  * @param array $args
481
+ *
482
+ * @return void
483
  */
484
  protected function __construct( $args ) {
485
  $this->args = $args;
486
  }
487
 
488
  /**
489
+ * Magic method: $field->arg
490
+ *
491
  * @param string $key
492
  *
493
  * @return mixed
497
  }
498
 
499
  /**
500
+ * Magic method: isset( $field->arg )
501
+ *
502
  * @param string $key
503
  *
504
  * @return bool
508
  }
509
 
510
  /**
511
+ * Generate the corresponding HTML for a field.
512
+ *
513
+ * @param mixed $value (optional)
514
  *
515
  * @return string
516
  */
517
  public function render( $value = null ) {
518
+ if ( null === $value && isset( $this->default ) ) {
519
  $value = $this->default;
520
+ }
521
 
522
  $args = $this->args;
523
 
524
+ if ( null !== $value ) {
525
  $this->_set_value( $args, $value );
526
+ }
527
 
528
  $args['name'] = scbForms::get_name( $args['name'] );
529
 
539
  abstract protected function _set_value( &$args, $value );
540
 
541
  /**
542
+ * The actual rendering.
543
  *
544
  * @param array $args
545
  */
546
  abstract protected function _render( $args );
547
 
548
  /**
549
+ * Handle args for a single checkbox or radio input.
550
  *
551
  * @param array $args
552
  *
562
 
563
  $args['extra']['checked'] = $args['checked'];
564
 
565
+ if ( is_null( $args['desc'] ) && ! is_bool( $args['value'] ) ) {
566
  $args['desc'] = str_replace( '[]', '', $args['value'] );
567
+ }
568
 
569
  return self::_input_gen( $args );
570
  }
571
 
572
  /**
573
+ * Generate html with the final args.
574
  *
575
  * @param array $args
576
  *
597
  }
598
 
599
  /**
600
+ * Wraps a form field in a label, and position field description.
601
+ *
602
  * @param string $input
603
  * @param string $desc
604
  * @param string $desc_pos
610
  }
611
 
612
  /**
613
+ * Adds description before/after the form field.
614
+ *
615
  * @param string $input
616
  * @param string $desc
617
  * @param string $desc_pos
619
  * @return string
620
  */
621
  protected static function add_desc( $input, $desc, $desc_pos ) {
622
+ if ( empty( $desc ) ) {
623
  return $input;
624
+ }
625
 
626
+ if ( 'before' == $desc_pos ) {
627
  return $desc . ' ' . $input;
628
+ } else {
629
  return $input . ' ' . $desc;
630
+ }
631
  }
632
 
633
  /**
636
  private static function _expand_choices( &$args ) {
637
  $choices =& $args['choices'];
638
 
639
+ if ( ! empty( $choices ) && ! self::is_associative( $choices ) ) {
640
  if ( is_array( $args['desc'] ) ) {
641
  $choices = array_combine( $choices, $args['desc'] ); // back-compat
642
  $args['desc'] = false;
643
+ } else if ( ! isset( $args['numeric'] ) || ! $args['numeric'] ) {
644
  $choices = array_combine( $choices, $choices );
645
  }
646
  }
647
  }
648
 
649
  /**
650
+ * Checks if passed array is associative.
651
+ *
652
  * @param array $array
653
  *
654
  * @return bool
665
  class scbTextField extends scbFormField {
666
 
667
  /**
668
+ * Sanitizes value.
669
+ *
670
  * @param string $value
671
  *
672
  * @return string
678
  }
679
 
680
  /**
681
+ * Generate the corresponding HTML for a field.
682
+ *
683
  * @param array $args
684
  *
685
  * @return string
691
  'extra' => array( 'class' => 'regular-text' ),
692
  ) );
693
 
694
+ if ( ! isset( $args['extra']['id'] ) && ! is_array( $args['name'] ) && false === strpos( $args['name'], '[' ) ) {
695
  $args['extra']['id'] = $args['name'];
696
+ }
697
 
698
  return scbFormField::_input_gen( $args );
699
  }
700
 
701
  /**
702
+ * Sets value using a reference.
703
+ *
704
  * @param array $args
705
  * @param string $value
706
+ *
707
+ * @return void
708
  */
709
  protected function _set_value( &$args, $value ) {
710
  $args['value'] = $value;
717
  abstract class scbSingleChoiceField extends scbFormField {
718
 
719
  /**
720
+ * Validates a value against a field.
721
+ *
722
  * @param mixed $value
723
  *
724
  * @return mixed|null
725
  */
726
  public function validate( $value ) {
727
+ if ( isset( $this->choices[ $value ] ) ) {
728
  return $value;
729
+ }
730
 
731
  return null;
732
  }
733
 
734
  /**
735
+ * Generate the corresponding HTML for a field.
736
+ *
737
  * @param array $args
738
  *
739
  * @return string
746
  if ( isset( $args['selected'] ) ) {
747
  $args['selected'] = (string) $args['selected'];
748
  } else {
749
+ $args['selected'] = array( 'foo' ); // hack to make default blank
750
  }
751
 
752
  return $this->_render_specific( $args );
753
  }
754
 
755
  /**
756
+ * Sets value using a reference.
757
+ *
758
+ * @param array $args
759
+ * @param string $value
760
+ *
761
+ * @return void
762
  */
763
  protected function _set_value( &$args, $value ) {
764
  $args['selected'] = $value;
765
  }
766
 
767
  /**
768
+ * Generate the corresponding HTML for a field.
769
+ *
770
  * @param array $args
771
  *
772
  * @return string
780
  class scbSelectField extends scbSingleChoiceField {
781
 
782
  /**
783
+ * Generate the corresponding HTML for a field.
784
+ *
785
  * @param array $args
786
  *
787
  * @return string
831
  class scbRadiosField extends scbSelectField {
832
 
833
  /**
834
+ * Generate the corresponding HTML for a field.
835
+ *
836
  * @param array $args
837
  *
838
  * @return string
870
  class scbMultipleChoiceField extends scbFormField {
871
 
872
  /**
873
+ * Validates a value against a field.
874
+ *
875
  * @param mixed $value
876
  *
877
  * @return array
881
  }
882
 
883
  /**
884
+ * Generate the corresponding HTML for a field.
885
+ *
886
  * @param array $args
887
  *
888
  * @return string
893
  'checked' => null,
894
  ) );
895
 
896
+ if ( ! is_array( $args['checked'] ) ) {
897
  $args['checked'] = array();
898
+ }
899
 
900
  $opts = '';
901
  foreach ( $args['choices'] as $value => $title ) {
915
  }
916
 
917
  /**
918
+ * Sets value using a reference.
919
+ *
920
+ * @param array $args
921
+ * @param string $value
922
+ *
923
+ * @return void
924
  */
925
  protected function _set_value( &$args, $value ) {
926
  $args['checked'] = (array) $value;
933
  class scbSingleCheckboxField extends scbFormField {
934
 
935
  /**
936
+ * Validates a value against a field.
937
+ *
938
  * @param mixed $value
939
  *
940
  * @return boolean
944
  }
945
 
946
  /**
947
+ * Generate the corresponding HTML for a field.
948
+ *
949
  * @param array $args
950
  *
951
  * @return string
960
 
961
  $args['extra']['checked'] = $args['checked'];
962
 
963
+ if ( is_null( $args['desc'] ) && ! is_bool( $args['value'] ) ) {
964
  $args['desc'] = str_replace( '[]', '', $args['value'] );
965
+ }
966
 
967
  return scbFormField::_input_gen( $args );
968
  }
969
 
970
  /**
971
+ * Sets value using a reference.
972
+ *
973
+ * @param array $args
974
+ * @param string $value
975
+ *
976
+ * @return void
977
  */
978
  protected function _set_value( &$args, $value ) {
979
  $args['checked'] = ( $value || ( isset( $args['value'] ) && $value == $args['value'] ) );
988
  protected $args;
989
 
990
  /**
991
+ * Constructor.
992
+ *
993
  * @param array $args
994
+ *
995
+ * @return void
996
  */
997
  function __construct( $args ) {
998
  $this->args = wp_parse_args( $args, array(
1002
  }
1003
 
1004
  /**
1005
+ * Magic method: $field->arg
1006
+ *
1007
  * @param string $key
1008
  *
1009
  * @return mixed
1013
  }
1014
 
1015
  /**
1016
+ * Magic method: isset( $field->arg )
1017
+ *
1018
  * @param string $key
1019
  *
1020
  * @return boolean
1024
  }
1025
 
1026
  /**
1027
+ * Generate the corresponding HTML for a field.
1028
+ *
1029
+ * @param mixed $value (optional)
1030
  *
1031
  * @return string
1032
  */
1035
  }
1036
 
1037
  /**
1038
+ * Sanitizes value.
1039
+ *
1040
  * @param mixed $value
1041
  *
1042
  * @return mixed
vendor/scribu/scb-framework/Hooks.php CHANGED
@@ -1,16 +1,40 @@
1
  <?php
2
-
 
 
3
  class scbHooks {
4
  private static $mangle_name;
5
 
 
 
 
 
 
 
 
6
  public static function add( $class ) {
7
  self::_do( 'add_filter', $class );
8
  }
9
 
 
 
 
 
 
 
 
10
  public static function remove( $class ) {
11
  self::_do( 'remove_filter', $class );
12
  }
13
 
 
 
 
 
 
 
 
 
14
  public static function debug( $class, $mangle_name = false ) {
15
  self::$mangle_name = $mangle_name;
16
 
@@ -19,15 +43,26 @@ class scbHooks {
19
  echo "</pre>";
20
  }
21
 
 
 
 
 
 
 
 
 
 
 
22
  private static function _print( $tag, $callback, $prio, $argc ) {
23
- $static = !is_object( $callback[0] );
24
 
25
- if ( self::$mangle_name )
26
  $class = $static ? '__CLASS__' : '$this';
27
- else if ( $static )
28
  $class = "'" . $callback[0] . "'";
29
- else
30
  $class = '$' . get_class( $callback[0] );
 
31
 
32
  $func = "array( $class, '$callback[1]' )";
33
 
@@ -36,18 +71,27 @@ class scbHooks {
36
  if ( $prio != 10 || $argc > 1 ) {
37
  echo ", $prio";
38
 
39
- if ( $argc > 1 )
40
  echo ", $argc";
 
41
  }
42
 
43
  echo " );\n";
44
  }
45
 
 
 
 
 
 
 
 
 
46
  private static function _do( $action, $class ) {
47
  $reflection = new ReflectionClass( $class );
48
 
49
  foreach ( $reflection->getMethods() as $method ) {
50
- if ( $method->isPublic() && !$method->isConstructor() ) {
51
  $comment = $method->getDocComment();
52
 
53
  if ( preg_match( '/@nohook[ \t\*\n]+/', $comment ) ) {
@@ -55,10 +99,11 @@ class scbHooks {
55
  }
56
 
57
  preg_match_all( '/@hook:?\s+([^\s]+)/', $comment, $matches ) ? $matches[1] : $method->name;
58
- if ( empty( $matches[1] ) )
59
  $hooks = array( $method->name );
60
- else
61
  $hooks = $matches[1];
 
62
 
63
  $priority = preg_match( '/@priority:?\s+(\d+)/', $comment, $matches ) ? $matches[1] : 10;
64
 
@@ -67,6 +112,8 @@ class scbHooks {
67
  }
68
  }
69
  }
 
70
  }
 
71
  }
72
 
1
  <?php
2
+ /**
3
+ * Automatic filter binding.
4
+ */
5
  class scbHooks {
6
  private static $mangle_name;
7
 
8
+ /**
9
+ * Adds.
10
+ *
11
+ * @param string $class
12
+ *
13
+ * @return void
14
+ */
15
  public static function add( $class ) {
16
  self::_do( 'add_filter', $class );
17
  }
18
 
19
+ /**
20
+ * Removes.
21
+ *
22
+ * @param string $class
23
+ *
24
+ * @return void
25
+ */
26
  public static function remove( $class ) {
27
  self::_do( 'remove_filter', $class );
28
  }
29
 
30
+ /**
31
+ * Prints debug.
32
+ *
33
+ * @param string $class
34
+ * @param string $mangle_name (optional)
35
+ *
36
+ * @return void
37
+ */
38
  public static function debug( $class, $mangle_name = false ) {
39
  self::$mangle_name = $mangle_name;
40
 
43
  echo "</pre>";
44
  }
45
 
46
+ /**
47
+ * Prints.
48
+ *
49
+ * @param string $tag
50
+ * @param array $callback
51
+ * @param int $prio
52
+ * @param int $argc
53
+ *
54
+ * @return void
55
+ */
56
  private static function _print( $tag, $callback, $prio, $argc ) {
57
+ $static = ! is_object( $callback[0] );
58
 
59
+ if ( self::$mangle_name ) {
60
  $class = $static ? '__CLASS__' : '$this';
61
+ } else if ( $static ) {
62
  $class = "'" . $callback[0] . "'";
63
+ } else {
64
  $class = '$' . get_class( $callback[0] );
65
+ }
66
 
67
  $func = "array( $class, '$callback[1]' )";
68
 
71
  if ( $prio != 10 || $argc > 1 ) {
72
  echo ", $prio";
73
 
74
+ if ( $argc > 1 ) {
75
  echo ", $argc";
76
+ }
77
  }
78
 
79
  echo " );\n";
80
  }
81
 
82
+ /**
83
+ * Processes.
84
+ *
85
+ * @param string $action
86
+ * @param string $class
87
+ *
88
+ * @return void
89
+ */
90
  private static function _do( $action, $class ) {
91
  $reflection = new ReflectionClass( $class );
92
 
93
  foreach ( $reflection->getMethods() as $method ) {
94
+ if ( $method->isPublic() && ! $method->isConstructor() ) {
95
  $comment = $method->getDocComment();
96
 
97
  if ( preg_match( '/@nohook[ \t\*\n]+/', $comment ) ) {
99
  }
100
 
101
  preg_match_all( '/@hook:?\s+([^\s]+)/', $comment, $matches ) ? $matches[1] : $method->name;
102
+ if ( empty( $matches[1] ) ) {
103
  $hooks = array( $method->name );
104
+ } else {
105
  $hooks = $matches[1];
106
+ }
107
 
108
  $priority = preg_match( '/@priority:?\s+(\d+)/', $comment, $matches ) ? $matches[1] : 10;
109
 
112
  }
113
  }
114
  }
115
+
116
  }
117
+
118
  }
119
 
vendor/scribu/scb-framework/Options.php CHANGED
@@ -1,21 +1,35 @@
1
  <?php
2
-
3
- // Container for an array of options
4
-
5
  class scbOptions {
6
 
7
- protected $key; // the option name
 
 
 
 
8
 
9
- protected $defaults; // the default values
 
 
 
 
10
 
11
- public $wp_filter_id; // used by WP hooks
 
 
 
 
12
 
13
  /**
14
- * Create a new set of options
 
 
 
 
15
  *
16
- * @param string $key Option name
17
- * @param string $file Reference to main plugin file
18
- * @param array $defaults An associative array of default values (optional)
19
  */
20
  public function __construct( $key, $file, $defaults = array() ) {
21
  $this->key = $key;
@@ -28,17 +42,21 @@ class scbOptions {
28
  }
29
 
30
  /**
31
- * Get option name
 
 
32
  */
33
  public function get_key() {
34
  return $this->key;
35
  }
36
 
37
  /**
38
- * Get option values for one or all fields
 
 
 
39
  *
40
- * @param string|array $field The field to get
41
- * @return mixed Whatever is in those fields
42
  */
43
  public function get( $field = null, $default = null ) {
44
  $data = array_merge( $this->defaults, get_option( $this->key, array() ) );
@@ -47,67 +65,72 @@ class scbOptions {
47
  }
48
 
49
  /**
50
- * Get default values for one or all fields
 
 
51
  *
52
- * @param string|array $field The field to get
53
- * @return mixed Whatever is in those fields
54
  */
55
  public function get_defaults( $field = null ) {
56
  return scbForms::get_value( $field, $this->defaults );
57
  }
58
 
59
  /**
60
- * Set all data fields, certain fields or a single field
61
  *
62
- * @param string|array $field The field to update or an associative array
63
- * @param mixed $value The new value ( ignored if $field is array )
64
- * @return null
 
65
  */
66
  public function set( $field, $value = '' ) {
67
- if ( is_array( $field ) )
68
  $newdata = $field;
69
- else
70
  $newdata = array( $field => $value );
 
71
 
72
  $this->update( array_merge( $this->get(), $newdata ) );
73
  }
74
 
75
  /**
76
- * Reset option to defaults
77
  *
78
- * @return null
79
  */
80
  public function reset() {
81
  $this->update( $this->defaults, false );
82
  }
83
 
84
  /**
85
- * Remove any keys that are not in the defaults array
86
  *
87
- * @return bool
88
  */
89
  public function cleanup() {
90
  $this->update( $this->get(), true );
91
  }
92
 
93
  /**
94
- * Update raw data
95
  *
96
  * @param mixed $newdata
97
- * @param bool $clean wether to remove unrecognized keys or not
98
- * @return null
 
99
  */
100
  public function update( $newdata, $clean = true ) {
101
- if ( $clean )
102
  $newdata = $this->_clean( $newdata );
 
103
 
104
  update_option( $this->key, array_merge( $this->get(), $newdata ) );
105
  }
106
 
107
  /**
108
- * Delete the option
109
  *
110
- * @return null
111
  */
112
  public function delete() {
113
  delete_option( $this->key );
@@ -117,12 +140,22 @@ class scbOptions {
117
  //_____INTERNAL METHODS_____
118
 
119
 
120
- // Saves an extra query
121
- function _activation() {
 
 
 
 
122
  add_option( $this->key, $this->defaults );
123
  }
124
 
125
- // Keep only the keys defined in $this->defaults
 
 
 
 
 
 
126
  private function _clean( $data ) {
127
  return wp_array_slice_assoc( $data, array_keys( $this->defaults ) );
128
  }
@@ -130,20 +163,34 @@ class scbOptions {
130
  private function &_get( $field, $data ) {
131
  }
132
 
133
- // Magic method: $options->field
134
- function __get( $field ) {
 
 
 
 
 
 
135
  return $this->get( $field );
136
  }
137
 
138
- // Magic method: $options->field = $value
139
- function __set( $field, $value ) {
 
 
 
 
140
  $this->set( $field, $value );
141
  }
142
 
143
- // Magic method: isset( $options->field )
144
- function __isset( $field ) {
 
 
 
 
145
  $data = $this->get();
146
- return isset( $data[$field] );
147
  }
148
  }
149
 
1
  <?php
2
+ /**
3
+ * Container for an array of options.
4
+ */
5
  class scbOptions {
6
 
7
+ /**
8
+ * The option name.
9
+ * @var string
10
+ */
11
+ protected $key;
12
 
13
+ /**
14
+ * The default values.
15
+ * @var array
16
+ */
17
+ protected $defaults;
18
 
19
+ /**
20
+ * Used by WP hooks.
21
+ * @var null
22
+ */
23
+ public $wp_filter_id;
24
 
25
  /**
26
+ * Create a new set of options.
27
+ *
28
+ * @param string $key Option name.
29
+ * @param string $file Reference to main plugin file.
30
+ * @param array $defaults (optional) An associative array of default values.
31
  *
32
+ * @return void
 
 
33
  */
34
  public function __construct( $key, $file, $defaults = array() ) {
35
  $this->key = $key;
42
  }
43
 
44
  /**
45
+ * Returns option name.
46
+ *
47
+ * @return string
48
  */
49
  public function get_key() {
50
  return $this->key;
51
  }
52
 
53
  /**
54
+ * Get option values for one or all fields.
55
+ *
56
+ * @param string|array $field (optional) The field to get.
57
+ * @param mixed $default (optional) The value returned when the key is not found.
58
  *
59
+ * @return mixed Whatever is in those fields.
 
60
  */
61
  public function get( $field = null, $default = null ) {
62
  $data = array_merge( $this->defaults, get_option( $this->key, array() ) );
65
  }
66
 
67
  /**
68
+ * Get default values for one or all fields.
69
+ *
70
+ * @param string|array $field (optional) The field to get.
71
  *
72
+ * @return mixed Whatever is in those fields.
 
73
  */
74
  public function get_defaults( $field = null ) {
75
  return scbForms::get_value( $field, $this->defaults );
76
  }
77
 
78
  /**
79
+ * Set all data fields, certain fields or a single field.
80
  *
81
+ * @param string|array $field The field to update or an associative array.
82
+ * @param mixed $value (optional) The new value ( ignored if $field is array ).
83
+ *
84
+ * @return void
85
  */
86
  public function set( $field, $value = '' ) {
87
+ if ( is_array( $field ) ) {
88
  $newdata = $field;
89
+ } else {
90
  $newdata = array( $field => $value );
91
+ }
92
 
93
  $this->update( array_merge( $this->get(), $newdata ) );
94
  }
95
 
96
  /**
97
+ * Reset option to defaults.
98
  *
99
+ * @return void
100
  */
101
  public function reset() {
102
  $this->update( $this->defaults, false );
103
  }
104
 
105
  /**
106
+ * Remove any keys that are not in the defaults array.
107
  *
108
+ * @return void
109
  */
110
  public function cleanup() {
111
  $this->update( $this->get(), true );
112
  }
113
 
114
  /**
115
+ * Update raw data.
116
  *
117
  * @param mixed $newdata
118
+ * @param bool $clean (optional) Whether to remove unrecognized keys or not.
119
+ *
120
+ * @return void
121
  */
122
  public function update( $newdata, $clean = true ) {
123
+ if ( $clean ) {
124
  $newdata = $this->_clean( $newdata );
125
+ }
126
 
127
  update_option( $this->key, array_merge( $this->get(), $newdata ) );
128
  }
129
 
130
  /**
131
+ * Delete the option.
132
  *
133
+ * @return void
134
  */
135
  public function delete() {
136
  delete_option( $this->key );
140
  //_____INTERNAL METHODS_____
141
 
142
 
143
+ /**
144
+ * Saves an extra query.
145
+ *
146
+ * @return void
147
+ */
148
+ public function _activation() {
149
  add_option( $this->key, $this->defaults );
150
  }
151
 
152
+ /**
153
+ * Keep only the keys defined in $this->defaults
154
+ *
155
+ * @param array $data
156
+ *
157
+ * @return array
158
+ */
159
  private function _clean( $data ) {
160
  return wp_array_slice_assoc( $data, array_keys( $this->defaults ) );
161
  }
163
  private function &_get( $field, $data ) {
164
  }
165
 
166
+ /**
167
+ * Magic method: $options->field
168
+ *
169
+ * @param string|array $field The field to get.
170
+ *
171
+ * @return mixed
172
+ */
173
+ public function __get( $field ) {
174
  return $this->get( $field );
175
  }
176
 
177
+ /**
178
+ * Magic method: $options->field = $value
179
+ *
180
+ * @return void
181
+ */
182
+ public function __set( $field, $value ) {
183
  $this->set( $field, $value );
184
  }
185
 
186
+ /**
187
+ * Magic method: isset( $options->field )
188
+ *
189
+ * @return bool
190
+ */
191
+ public function __isset( $field ) {
192
  $data = $this->get();
193
+ return isset( $data[ $field ] );
194
  }
195
  }
196
 
vendor/scribu/scb-framework/PostMetabox.php CHANGED
@@ -1,15 +1,48 @@
1
  <?php
2
-
 
 
3
  class scbPostMetabox {
4
 
5
- private $id, $title;
6
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  private $post_types;
8
 
 
 
 
 
9
  private $post_data = array();
10
 
 
 
 
 
11
  protected $actions = array( 'admin_enqueue_scripts', 'post_updated_messages' );
12
 
 
 
 
 
 
 
 
 
 
13
  public function __construct( $id, $title, $args = array() ) {
14
  $this->id = $id;
15
  $this->title = $title;
@@ -17,13 +50,14 @@ class scbPostMetabox {
17
  $args = wp_parse_args( $args, array(
18
  'post_type' => 'post',
19
  'context' => 'advanced',
20
- 'priority' => 'default'
21
  ) );
22
 
23
- if ( is_string( $args['post_type'] ) )
24
  $args['post_type'] = array( $args['post_type'] );
25
- $this->post_types = $args['post_type'];
26
 
 
27
  $this->context = $args['context'];
28
  $this->priority = $args['priority'];
29
 
@@ -31,42 +65,76 @@ class scbPostMetabox {
31
  add_action( 'load-post-new.php', array( $this, 'pre_register' ) );
32
  }
33
 
 
 
 
 
 
34
  final public function pre_register() {
35
- if ( ! in_array( get_current_screen()->post_type, $this->post_types ) )
36
  return;
 
37
 
38
- if ( ! $this->condition() )
39
  return;
 
40
 
41
- if ( isset( $_GET['post'] ) )
42
  $this->post_data = $this->get_meta( intval( $_GET['post'] ) );
 
43
 
44
  add_action( 'add_meta_boxes', array( $this, 'register' ) );
45
  add_action( 'save_post', array( $this, '_save_post' ), 10, 2 );
46
 
47
  foreach ( $this->actions as $action ) {
48
- if ( method_exists( $this, $action ) )
49
  add_action( $action, array( $this, $action ) );
 
50
  }
51
  }
52
 
53
- // Additional checks before registering the metabox
 
 
 
 
54
  protected function condition() {
55
  return true;
56
  }
57
 
 
 
 
 
 
58
  final public function register() {
59
  add_meta_box( $this->id, $this->title, array( $this, 'display' ), null, $this->context, $this->priority );
60
  }
61
 
 
 
 
 
 
 
 
 
62
  public function before_display( $form_data, $post ) {
63
  return $form_data;
64
  }
65
 
 
 
 
 
 
 
 
66
  public function display( $post ) {
67
  $form_fields = $this->form_fields();
68
- if ( ! $form_fields )
69
  return;
 
70
 
71
  $form_data = $this->post_data;
72
  $error_fields = array();
@@ -76,6 +144,8 @@ class scbPostMetabox {
76
 
77
  $error_fields = $data['fields'];
78
  $form_data = $data['data'];
 
 
79
  }
80
 
81
  $form_data = $this->before_display( $form_data, $post );
@@ -87,6 +157,15 @@ class scbPostMetabox {
87
  delete_post_meta( $post->ID, '_error_data_' . $this->id );
88
  }
89
 
 
 
 
 
 
 
 
 
 
90
  public function table( $rows, $formdata, $errors = array() ) {
91
  $output = '';
92
  foreach ( $rows as $row ) {
@@ -98,11 +177,20 @@ class scbPostMetabox {
98
  return $output;
99
  }
100
 
 
 
 
 
 
 
 
 
 
101
  public function table_row( $row, $formdata, $errors = array() ) {
102
  $input = scbForms::input( $row, $formdata );
103
 
104
  // If row has an error, highlight it
105
- $style = ( in_array( $row['name'], $errors ) ) ? 'style= "background-color: #FFCCCC"' : '';
106
 
107
  return html( 'tr',
108
  html( "th $style scope='row'", $row['title'] ),
@@ -110,31 +198,81 @@ class scbPostMetabox {
110
  );
111
  }
112
 
113
- // Display some extra HTML before the form
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  public function before_form( $post ) { }
115
 
116
- // Return the list of form fields
 
 
 
 
117
  public function form_fields() {
118
  return array();
119
  }
120
 
121
- // Display some extra HTML after the form
 
 
 
 
 
 
122
  public function after_form( $post ) { }
123
 
124
- // Makes sure that the saving occurs only for the post being edited
 
 
 
 
 
 
 
125
  final public function _save_post( $post_id, $post ) {
126
- if ( ! isset( $_POST['action'] ) || $_POST['action'] != 'editpost' )
127
  return;
 
128
 
129
- if ( $post_id != $_POST['post_ID'] )
130
  return;
 
131
 
132
- if ( ! in_array( $post->post_type, $this->post_types ) )
133
  return;
 
134
 
135
  $this->save( $post->ID );
136
  }
137
 
 
 
 
 
 
 
 
138
  protected function save( $post_id ) {
139
  $form_fields = $this->form_fields();
140
 
@@ -149,12 +287,13 @@ class scbPostMetabox {
149
 
150
  $error_data = array(
151
  'fields' => $is_valid->get_error_codes(),
152
- 'data' => $to_update
 
153
  );
154
  update_post_meta( $post_id, '_error_data_' . $this->id, $error_data );
155
 
156
  $location = add_query_arg( 'message', 1, get_edit_post_link( $post_id, 'url' ) );
157
- wp_redirect( apply_filters( 'redirect_post_location', $location, $post_id ) );
158
  exit;
159
  }
160
 
@@ -163,20 +302,45 @@ class scbPostMetabox {
163
  }
164
  }
165
 
 
 
 
 
 
 
 
 
166
  protected function before_save( $post_data, $post_id ) {
167
  return $post_data;
168
  }
169
 
 
 
 
 
 
 
 
 
170
  protected function validate_post_data( $post_data, $post_id ) {
171
  return false;
172
  }
173
 
 
 
 
 
 
 
 
174
  private function get_meta( $post_id ) {
175
  $meta = get_post_custom( $post_id );
176
- foreach ( $meta as $key => $values )
177
  $meta[ $key ] = maybe_unserialize( $meta[ $key ][0] );
 
178
 
179
  return $meta;
180
  }
 
181
  }
182
 
1
  <?php
2
+ /**
3
+ * Class that creates metaboxes on the post editing page.
4
+ */
5
  class scbPostMetabox {
6
 
7
+ /**
8
+ * Metabox ID.
9
+ * @var string
10
+ */
11
+ private $id;
12
+
13
+ /**
14
+ * Title.
15
+ * @var string
16
+ */
17
+ private $title;
18
+
19
+ /**
20
+ * Post types.
21
+ * @var array
22
+ */
23
  private $post_types;
24
 
25
+ /**
26
+ * Post meta data.
27
+ * @var array
28
+ */
29
  private $post_data = array();
30
 
31
+ /**
32
+ * Action hooks.
33
+ * @var array
34
+ */
35
  protected $actions = array( 'admin_enqueue_scripts', 'post_updated_messages' );
36
 
37
+ /**
38
+ * Sets up metabox.
39
+ *
40
+ * @param string $id
41
+ * @param string $title
42
+ * @param array $args (optional)
43
+ *
44
+ * @return void
45
+ */
46
  public function __construct( $id, $title, $args = array() ) {
47
  $this->id = $id;
48
  $this->title = $title;
50
  $args = wp_parse_args( $args, array(
51
  'post_type' => 'post',
52
  'context' => 'advanced',
53
+ 'priority' => 'default',
54
  ) );
55
 
56
+ if ( is_string( $args['post_type'] ) ) {
57
  $args['post_type'] = array( $args['post_type'] );
58
+ }
59
 
60
+ $this->post_types = $args['post_type'];
61
  $this->context = $args['context'];
62
  $this->priority = $args['priority'];
63
 
65
  add_action( 'load-post-new.php', array( $this, 'pre_register' ) );
66
  }
67
 
68
+ /**
69
+ * Pre register the metabox.
70
+ *
71
+ * @return void
72
+ */
73
  final public function pre_register() {
74
+ if ( ! in_array( get_current_screen()->post_type, $this->post_types ) ) {
75
  return;
76
+ }
77
 
78
+ if ( ! $this->condition() ) {
79
  return;
80
+ }
81
 
82
+ if ( isset( $_GET['post'] ) ) {
83
  $this->post_data = $this->get_meta( intval( $_GET['post'] ) );
84
+ }
85
 
86
  add_action( 'add_meta_boxes', array( $this, 'register' ) );
87
  add_action( 'save_post', array( $this, '_save_post' ), 10, 2 );
88
 
89
  foreach ( $this->actions as $action ) {
90
+ if ( method_exists( $this, $action ) ) {
91
  add_action( $action, array( $this, $action ) );
92
+ }
93
  }
94
  }
95
 
96
+ /**
97
+ * Additional checks before registering the metabox.
98
+ *
99
+ * @return bool
100
+ */
101
  protected function condition() {
102
  return true;
103
  }
104
 
105
+ /**
106
+ * Registers the metabox.
107
+ *
108
+ * @return void
109
+ */
110
  final public function register() {
111
  add_meta_box( $this->id, $this->title, array( $this, 'display' ), null, $this->context, $this->priority );
112
  }
113
 
114
+ /**
115
+ * Filter data before display.
116
+ *
117
+ * @param array $form_data
118
+ * @param object $post
119
+ *
120
+ * @return array
121
+ */
122
  public function before_display( $form_data, $post ) {
123
  return $form_data;
124
  }
125
 
126
+ /**
127
+ * Displays metabox content.
128
+ *
129
+ * @param object $post
130
+ *
131
+ * @return void
132
+ */
133
  public function display( $post ) {
134
  $form_fields = $this->form_fields();
135
+ if ( ! $form_fields ) {
136
  return;
137
+ }
138
 
139
  $form_data = $this->post_data;
140
  $error_fields = array();
144
 
145
  $error_fields = $data['fields'];
146
  $form_data = $data['data'];
147
+
148
+ $this->display_notices( $data['messages'], 'error' );
149
  }
150
 
151
  $form_data = $this->before_display( $form_data, $post );
157
  delete_post_meta( $post->ID, '_error_data_' . $this->id );
158
  }
159
 
160
+ /**
161
+ * Returns table.
162
+ *
163
+ * @param array $rows
164
+ * @param array $formdata
165
+ * @param array $errors (optional)
166
+ *
167
+ * @return string
168
+ */
169
  public function table( $rows, $formdata, $errors = array() ) {
170
  $output = '';
171
  foreach ( $rows as $row ) {
177
  return $output;
178
  }
179
 
180
+ /**
181
+ * Returns table row.
182
+ *
183
+ * @param array $row
184
+ * @param array $formdata
185
+ * @param array $errors (optional)
186
+ *
187
+ * @return string
188
+ */
189
  public function table_row( $row, $formdata, $errors = array() ) {
190
  $input = scbForms::input( $row, $formdata );
191
 
192
  // If row has an error, highlight it
193
+ $style = ( in_array( $row['name'], $errors ) ) ? 'style="background-color: #FFCCCC"' : '';
194
 
195
  return html( 'tr',
196
  html( "th $style scope='row'", $row['title'] ),
198
  );
199
  }
200
 
201
+ /**
202
+ * Displays notices.
203
+ *
204
+ * @param array|string $notices
205
+ * @param string $class (optional)
206
+ *
207
+ * @return void
208
+ */
209
+ public function display_notices( $notices, $class = 'updated' ) {
210
+ // add inline class so the notices stays in metabox
211
+ $class .= ' inline';
212
+
213
+ foreach ( (array) $notices as $notice ) {
214
+ echo scb_admin_notice( $notice, $class );
215
+ }
216
+ }
217
+
218
+ /**
219
+ * Display some extra HTML before the form.
220
+ *
221
+ * @param object $post
222
+ *
223
+ * @return void
224
+ */
225
  public function before_form( $post ) { }
226
 
227
+ /**
228
+ * Return an array of form fields.
229
+ *
230
+ * @return array
231
+ */
232
  public function form_fields() {
233
  return array();
234
  }
235
 
236
+ /**
237
+ * Display some extra HTML after the form.
238
+ *
239
+ * @param object $post
240
+ *
241
+ * @return void
242
+ */
243
  public function after_form( $post ) { }
244
 
245
+ /**
246
+ * Makes sure that the saving occurs only for the post being edited.
247
+ *
248
+ * @param int $post_id
249
+ * @param object $post
250
+ *
251
+ * @return void
252
+ */
253
  final public function _save_post( $post_id, $post ) {
254
+ if ( ! isset( $_POST['action'] ) || $_POST['action'] != 'editpost' ) {
255
  return;
256
+ }
257
 
258
+ if ( ! isset( $_POST['post_ID'] ) || $_POST['post_ID'] != $post_id ) {
259
  return;
260
+ }
261
 
262
+ if ( ! in_array( $post->post_type, $this->post_types ) ) {
263
  return;
264
+ }
265
 
266
  $this->save( $post->ID );
267
  }
268
 
269
+ /**
270
+ * Saves metabox form data.
271
+ *
272
+ * @param int $post_id
273
+ *
274
+ * @return void
275
+ */
276
  protected function save( $post_id ) {
277
  $form_fields = $this->form_fields();
278
 
287
 
288
  $error_data = array(
289
  'fields' => $is_valid->get_error_codes(),
290
+ 'messages' => $is_valid->get_error_messages(),
291
+ 'data' => $to_update,
292
  );
293
  update_post_meta( $post_id, '_error_data_' . $this->id, $error_data );
294
 
295
  $location = add_query_arg( 'message', 1, get_edit_post_link( $post_id, 'url' ) );
296
+ wp_redirect( esc_url_raw( apply_filters( 'redirect_post_location', $location, $post_id ) ) );
297
  exit;
298
  }
299
 
302
  }
303
  }
304
 
305
+ /**
306
+ * Filter data before save.
307
+ *
308
+ * @param array $post_data
309
+ * @param int $post_id
310
+ *
311
+ * @return array
312
+ */
313
  protected function before_save( $post_data, $post_id ) {
314
  return $post_data;
315
  }
316
 
317
+ /**
318
+ * Validate posted data.
319
+ *
320
+ * @param array $post_data
321
+ * @param int $post_id
322
+ *
323
+ * @return bool|object A WP_Error object if posted data are invalid.
324
+ */
325
  protected function validate_post_data( $post_data, $post_id ) {
326
  return false;
327
  }
328
 
329
+ /**
330
+ * Returns an array of post meta.
331
+ *
332
+ * @param int $post_id
333
+ *
334
+ * @return array
335
+ */
336
  private function get_meta( $post_id ) {
337
  $meta = get_post_custom( $post_id );
338
+ foreach ( $meta as $key => $values ) {
339
  $meta[ $key ] = maybe_unserialize( $meta[ $key ][0] );
340
+ }
341
 
342
  return $meta;
343
  }
344
+
345
  }
346
 
vendor/scribu/scb-framework/Table.php CHANGED
@@ -1,13 +1,38 @@
1
  <?php
2
-
3
- // Takes care of creating, updating and deleting database tables
4
-
5
  class scbTable {
 
 
 
 
 
6
  protected $name;
 
 
 
 
 
7
  protected $columns;
 
 
 
 
 
8
  protected $upgrade_method;
9
 
10
- function __construct( $name, $file, $columns, $upgrade_method = 'dbDelta' ) {
 
 
 
 
 
 
 
 
 
 
11
  $this->name = $name;
12
  $this->columns = $columns;
13
  $this->upgrade_method = $upgrade_method;
@@ -20,11 +45,21 @@ class scbTable {
20
  }
21
  }
22
 
23
- function install() {
 
 
 
 
 
24
  scb_install_table( $this->name, $this->columns, $this->upgrade_method );
25
  }
26
 
27
- function uninstall() {
 
 
 
 
 
28
  scb_uninstall_table( $this->name );
29
  }
30
  }
1
  <?php
2
+ /**
3
+ * Takes care of creating, updating and deleting database tables.
4
+ */
5
  class scbTable {
6
+
7
+ /**
8
+ * The table name.
9
+ * @var string
10
+ */
11
  protected $name;
12
+
13
+ /**
14
+ * The table columns.
15
+ * @var string
16
+ */
17
  protected $columns;
18
+
19
+ /**
20
+ * The upgrade method.
21
+ * @var string
22
+ */
23
  protected $upgrade_method;
24
 
25
+ /**
26
+ * Sets up table.
27
+ *
28
+ * @param string $name Table name.
29
+ * @param string $file Reference to main plugin file.
30
+ * @param string $columns The SQL columns for the CREATE TABLE statement.
31
+ * @param array $upgrade_method (optional)
32
+ *
33
+ * @return void
34
+ */
35
+ public function __construct( $name, $file, $columns, $upgrade_method = 'dbDelta' ) {
36
  $this->name = $name;
37
  $this->columns = $columns;
38
  $this->upgrade_method = $upgrade_method;
45
  }
46
  }
47
 
48
+ /**
49
+ * Installs table.
50
+ *
51
+ * @return void
52
+ */
53
+ public function install() {
54
  scb_install_table( $this->name, $this->columns, $this->upgrade_method );
55
  }
56
 
57
+ /**
58
+ * Uninstalls table.
59
+ *
60
+ * @return void
61
+ */
62
+ public function uninstall() {
63
  scb_uninstall_table( $this->name );
64
  }
65
  }
vendor/scribu/scb-framework/Util.php CHANGED
@@ -1,27 +1,41 @@
1
  <?php
2
-
3
- // Various utilities
4
-
5
  class scbUtil {
6
 
7
- // Force script enqueue
8
- static function do_scripts( $handles ) {
 
 
 
 
 
 
9
  global $wp_scripts;
10
 
11
- if ( ! is_a( $wp_scripts, 'WP_Scripts' ) )
12
  $wp_scripts = new WP_Scripts();
 
13
 
14
  $wp_scripts->do_items( ( array ) $handles );
15
  }
16
 
17
- // Force style enqueue
18
- static function do_styles( $handles ) {
 
 
 
 
 
 
19
  self::do_scripts( 'jquery' );
20
 
21
  global $wp_styles;
22
 
23
- if ( ! is_a( $wp_styles, 'WP_Styles' ) )
24
  $wp_styles = new WP_Styles();
 
25
 
26
  ob_start();
27
  $wp_styles->do_items( ( array ) $handles );
@@ -34,83 +48,173 @@ class scbUtil {
34
  echo "</script>";
35
  }
36
 
37
- // Enable delayed activation; to be used with scb_init()
38
- static function add_activation_hook( $plugin, $callback ) {
39
- if ( defined( 'SCB_LOAD_MU' ) )
 
 
 
 
 
 
 
40
  register_activation_hook( $plugin, $callback );
41
- else
42
  add_action( 'scb_activation_' . plugin_basename( $plugin ), $callback );
 
43
  }
44
 
45
- // For debugging
46
- static function do_activation( $plugin ) {
 
 
 
 
 
 
 
47
  do_action( 'scb_activation_' . plugin_basename( $plugin ) );
48
  }
49
 
50
- // Allows more than one uninstall hooks.
51
- // Also prevents an UPDATE query on each page load.
52
- static function add_uninstall_hook( $plugin, $callback ) {
53
- if ( !is_admin() )
 
 
 
 
 
 
 
54
  return;
 
55
 
56
  register_uninstall_hook( $plugin, '__return_false' ); // dummy
57
 
58
  add_action( 'uninstall_' . plugin_basename( $plugin ), $callback );
59
  }
60
 
61
- // For debugging
62
- static function do_uninstall( $plugin ) {
 
 
 
 
 
 
 
63
  do_action( 'uninstall_' . plugin_basename( $plugin ) );
64
  }
65
 
66
- // Get the current, full URL
67
- static function get_current_url() {
 
 
 
 
68
  return ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
69
  }
70
 
71
- // Apply a function to each element of a ( nested ) array recursively
72
- static function array_map_recursive( $callback, $array ) {
 
 
 
 
 
 
 
73
  array_walk_recursive( $array, array( __CLASS__, 'array_map_recursive_helper' ), $callback );
74
 
75
  return $array;
76
  }
77
 
78
- static function array_map_recursive_helper( &$val, $key, $callback ) {
79
  $val = call_user_func( $callback, $val );
80
  }
81
 
82
- // Extract certain $keys from $array
83
- static function array_extract( $array, $keys ) {
 
 
 
 
 
 
 
 
 
 
 
84
  _deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'WP 3.1', 'wp_array_slice_assoc()' );
85
  return wp_array_slice_assoc( $array, $keys );
86
  }
87
 
88
- // Extract a certain value from a list of arrays
89
- static function array_pluck( $array, $key ) {
 
 
 
 
 
 
 
 
 
 
 
90
  _deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'WP 3.1', 'wp_list_pluck()' );
91
  return wp_list_pluck( $array, $key );
92
  }
93
 
94
- // Transform a list of objects into an associative array
95
- static function objects_to_assoc( $objects, $key, $value ) {
 
 
 
 
 
 
 
 
 
 
 
 
96
  _deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'r41', 'scb_list_fold()' );
97
  return scb_list_fold( $objects, $key, $value );
98
  }
99
 
100
- // Prepare an array for an IN statement
101
- static function array_to_sql( $values ) {
102
- foreach ( $values as &$val )
 
 
 
 
 
 
103
  $val = "'" . esc_sql( trim( $val ) ) . "'";
 
104
 
105
  return implode( ',', $values );
106
  }
107
 
108
- // Example: split_at( '</', '<a></a>' ) => array( '<a>', '</a>' )
109
- static function split_at( $delim, $str ) {
 
 
 
 
 
 
 
110
  $i = strpos( $str, $delim );
111
 
112
- if ( false === $i )
113
  return false;
 
114
 
115
  $start = substr( $str, 0, $i );
116
  $finish = substr( $str, $i );
@@ -119,21 +223,38 @@ class scbUtil {
119
  }
120
  }
121
 
122
- // Return a standard admin notice
 
 
 
 
 
 
 
123
  function scb_admin_notice( $msg, $class = 'updated' ) {
124
  return html( "div class='$class fade'", html( "p", $msg ) );
125
  }
126
 
127
- // Transform a list of objects into an associative array
 
 
 
 
 
 
 
 
128
  function scb_list_fold( $list, $key, $value ) {
129
  $r = array();
130
 
131
  if ( is_array( reset( $list ) ) ) {
132
- foreach ( $list as $item )
133
  $r[ $item[ $key ] ] = $item[ $value ];
 
134
  } else {
135
- foreach ( $list as $item )
136
  $r[ $item->$key ] = $item->$value;
 
137
  }
138
 
139
  return $r;
@@ -142,8 +263,10 @@ function scb_list_fold( $list, $key, $value ) {
142
  /**
143
  * Splits a list into sets, grouped by the result of running each value through $fn.
144
  *
145
- * @param array List of items to be partitioned
146
- * @param callback Function that takes an element and returns a string key
 
 
147
  */
148
  function scb_list_group_by( $list, $fn ) {
149
  $groups = array();
@@ -151,8 +274,9 @@ function scb_list_group_by( $list, $fn ) {
151
  foreach ( $list as $item ) {
152
  $key = call_user_func( $fn, $item );
153
 
154
- if ( null === $key )
155
  continue;
 
156
 
157
  $groups[ $key ][] = $item;
158
  }
@@ -163,27 +287,32 @@ function scb_list_group_by( $list, $fn ) {
163
  //_____Database Table Utilities_____
164
 
165
  /**
166
- * Register a table with $wpdb
167
  *
168
- * @param string $key The key to be used on the $wpdb object
169
- * @param string $name The actual name of the table, without $wpdb->prefix
 
 
170
  */
171
  function scb_register_table( $key, $name = false ) {
172
  global $wpdb;
173
 
174
- if ( !$name )
175
  $name = $key;
 
176
 
177
  $wpdb->tables[] = $name;
178
  $wpdb->$key = $wpdb->prefix . $name;
179
  }
180
 
181
  /**
182
- * Runs the SQL query for installing/upgrading a table
 
 
 
 
183
  *
184
- * @param string $key The key used in scb_register_table()
185
- * @param string $columns The SQL columns for the CREATE TABLE statement
186
- * @param array $opts Various other options
187
  */
188
  function scb_install_table( $key, $columns, $opts = array() ) {
189
  global $wpdb;
@@ -201,10 +330,12 @@ function scb_install_table( $key, $columns, $opts = array() ) {
201
 
202
  $charset_collate = '';
203
  if ( $wpdb->has_cap( 'collation' ) ) {
204
- if ( ! empty( $wpdb->charset ) )
205
  $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
206
- if ( ! empty( $wpdb->collate ) )
 
207
  $charset_collate .= " COLLATE $wpdb->collate";
 
208
  }
209
 
210
  $table_options = $charset_collate . ' ' . $opts['table_options'];
@@ -215,12 +346,20 @@ function scb_install_table( $key, $columns, $opts = array() ) {
215
  return;
216
  }
217
 
218
- if ( 'delete_first' == $opts['upgrade_method'] )
219
  $wpdb->query( "DROP TABLE IF EXISTS $full_table_name;" );
 
220
 
221
  $wpdb->query( "CREATE TABLE IF NOT EXISTS $full_table_name ( $columns ) $table_options;" );
222
  }
223
 
 
 
 
 
 
 
 
224
  function scb_uninstall_table( $key ) {
225
  global $wpdb;
226
 
@@ -231,6 +370,10 @@ function scb_uninstall_table( $key ) {
231
 
232
  /**
233
  * Generate an HTML tag. Atributes are escaped. Content is NOT escaped.
 
 
 
 
234
  */
235
  if ( ! function_exists( 'html' ) ):
236
  function html( $tag ) {
@@ -244,11 +387,13 @@ function html( $tag ) {
244
  $closing = $tag;
245
  $attributes = array_shift( $args );
246
  foreach ( $attributes as $key => $value ) {
247
- if ( false === $value )
248
  continue;
 
249
 
250
- if ( true === $value )
251
  $value = $key;
 
252
 
253
  $tag .= ' ' . $key . '="' . esc_attr( $value ) . '"';
254
  }
@@ -266,24 +411,41 @@ function html( $tag ) {
266
  }
267
  endif;
268
 
269
- // Generate an <a> tag
 
 
 
 
 
 
 
270
  if ( ! function_exists( 'html_link' ) ):
271
  function html_link( $url, $title = '' ) {
272
- if ( empty( $title ) )
273
  $title = $url;
 
274
 
275
- return html( 'a', array( 'href' => $url ), $title );
276
  }
277
  endif;
278
 
 
 
 
 
 
 
 
279
  function scb_get_query_flags( $wp_query = null ) {
280
- if ( !$wp_query )
281
  $wp_query = $GLOBALS['wp_query'];
 
282
 
283
  $flags = array();
284
  foreach ( get_object_vars( $wp_query ) as $key => $val ) {
285
- if ( 'is_' == substr( $key, 0, 3 ) && $val )
286
  $flags[] = substr( $key, 3 );
 
287
  }
288
 
289
  return $flags;
@@ -291,7 +453,16 @@ function scb_get_query_flags( $wp_query = null ) {
291
 
292
  //_____Compatibility layer_____
293
 
294
- // WP < ?
 
 
 
 
 
 
 
 
 
295
  if ( ! function_exists( 'set_post_field' ) ) :
296
  function set_post_field( $field, $value, $post_id ) {
297
  global $wpdb;
1
  <?php
2
+ /**
3
+ * Various utilities.
4
+ */
5
  class scbUtil {
6
 
7
+ /**
8
+ * Force script enqueue.
9
+ *
10
+ * @param array $handles
11
+ *
12
+ * @return void
13
+ */
14
+ public static function do_scripts( $handles ) {
15
  global $wp_scripts;
16
 
17
+ if ( ! is_a( $wp_scripts, 'WP_Scripts' ) ) {
18
  $wp_scripts = new WP_Scripts();
19
+ }
20
 
21
  $wp_scripts->do_items( ( array ) $handles );
22
  }
23
 
24
+ /**
25
+ * Force style enqueue.
26
+ *
27
+ * @param array $handles
28
+ *
29
+ * @return void
30
+ */
31
+ public static function do_styles( $handles ) {
32
  self::do_scripts( 'jquery' );
33
 
34
  global $wp_styles;
35
 
36
+ if ( ! is_a( $wp_styles, 'WP_Styles' ) ) {
37
  $wp_styles = new WP_Styles();
38
+ }
39
 
40
  ob_start();
41
  $wp_styles->do_items( ( array ) $handles );
48
  echo "</script>";
49
  }
50
 
51
+ /**
52
+ * Enable delayed plugin activation. To be used with scb_init()
53
+ *
54
+ * @param string $plugin
55
+ * @param string|array $callback
56
+ *
57
+ * @return void
58
+ */
59
+ public static function add_activation_hook( $plugin, $callback ) {
60
+ if ( defined( 'SCB_LOAD_MU' ) ) {
61
  register_activation_hook( $plugin, $callback );
62
+ } else {
63
  add_action( 'scb_activation_' . plugin_basename( $plugin ), $callback );
64
+ }
65
  }
66
 
67
+ /**
68
+ * Execute activation hook.
69
+ * For debugging.
70
+ *
71
+ * @param string $plugin
72
+ *
73
+ * @return void
74
+ */
75
+ public static function do_activation( $plugin ) {
76
  do_action( 'scb_activation_' . plugin_basename( $plugin ) );
77
  }
78
 
79
+ /**
80
+ * Allows more than one uninstall hooks.
81
+ * Also prevents an UPDATE query on each page load.
82
+ *
83
+ * @param string $plugin
84
+ * @param string|array $callback
85
+ *
86
+ * @return void
87
+ */
88
+ public static function add_uninstall_hook( $plugin, $callback ) {
89
+ if ( ! is_admin() ) {
90
  return;
91
+ }
92
 
93
  register_uninstall_hook( $plugin, '__return_false' ); // dummy
94
 
95
  add_action( 'uninstall_' . plugin_basename( $plugin ), $callback );
96
  }
97
 
98
+ /**
99
+ * Execute uninstall hook.
100
+ * For debugging.
101
+ *
102
+ * @param string $plugin
103
+ *
104
+ * @return void
105
+ */
106
+ public static function do_uninstall( $plugin ) {
107
  do_action( 'uninstall_' . plugin_basename( $plugin ) );
108
  }
109
 
110
+ /**
111
+ * Get the current, full URL.
112
+ *
113
+ * @return string
114
+ */
115
+ public static function get_current_url() {
116
  return ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
117
  }
118
 
119
+ /**
120
+ * Apply a function to each element of a ( nested ) array recursively.
121
+ *
122
+ * @param string|array $callback
123
+ * @param array $array
124
+ *
125
+ * @return array
126
+ */
127
+ public static function array_map_recursive( $callback, $array ) {
128
  array_walk_recursive( $array, array( __CLASS__, 'array_map_recursive_helper' ), $callback );
129
 
130
  return $array;
131
  }
132
 
133
+ public static function array_map_recursive_helper( &$val, $key, $callback ) {
134
  $val = call_user_func( $callback, $val );
135
  }
136
 
137
+ /**
138
+ * Extract certain $keys from $array.
139
+ *
140
+ * @deprecated WP 3.1
141
+ * @deprecated Use wp_array_slice_assoc()
142
+ * @see wp_array_slice_assoc()
143
+ *
144
+ * @param array $array
145
+ * @param array $keys
146
+ *
147
+ * @return array
148
+ */
149
+ public static function array_extract( $array, $keys ) {
150
  _deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'WP 3.1', 'wp_array_slice_assoc()' );
151
  return wp_array_slice_assoc( $array, $keys );
152
  }
153
 
154
+ /**
155
+ * Extract a certain value from a list of arrays.
156
+ *
157
+ * @deprecated WP 3.1
158
+ * @deprecated Use wp_list_pluck()
159
+ * @see wp_list_pluck()
160
+ *
161
+ * @param array $array
162
+ * @param string $key
163
+ *
164
+ * @return array
165
+ */
166
+ public static function array_pluck( $array, $key ) {
167
  _deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'WP 3.1', 'wp_list_pluck()' );
168
  return wp_list_pluck( $array, $key );
169
  }
170
 
171
+ /**
172
+ * Transform a list of objects into an associative array.
173
+ *
174
+ * @deprecated r41
175
+ * @deprecated Use scb_list_fold()
176
+ * @see scb_list_fold()
177
+ *
178
+ * @param array $objects
179
+ * @param string $key
180
+ * @param string $value
181
+ *
182
+ * @return array
183
+ */
184
+ public static function objects_to_assoc( $objects, $key, $value ) {
185
  _deprecated_function( __CLASS__ . '::' . __FUNCTION__, 'r41', 'scb_list_fold()' );
186
  return scb_list_fold( $objects, $key, $value );
187
  }
188
 
189
+ /**
190
+ * Prepare an array for an IN statement.
191
+ *
192
+ * @param array $values
193
+ *
194
+ * @return string
195
+ */
196
+ public static function array_to_sql( $values ) {
197
+ foreach ( $values as &$val ) {
198
  $val = "'" . esc_sql( trim( $val ) ) . "'";
199
+ }
200
 
201
  return implode( ',', $values );
202
  }
203
 
204
+ /**
205
+ * Example: split_at( '</', '<a></a>' ) => array( '<a>', '</a>' )
206
+ *
207
+ * @param string $delim
208
+ * @param string $str
209
+ *
210
+ * @return array
211
+ */
212
+ public static function split_at( $delim, $str ) {
213
  $i = strpos( $str, $delim );
214
 
215
+ if ( false === $i ) {
216
  return false;
217
+ }
218
 
219
  $start = substr( $str, 0, $i );
220
  $finish = substr( $str, $i );
223
  }
224
  }
225
 
226
+ /**
227
+ * Return a standard admin notice.
228
+ *
229
+ * @param string $msg
230
+ * @param string $class (optional)
231
+ *
232
+ * @return string
233
+ */
234
  function scb_admin_notice( $msg, $class = 'updated' ) {
235
  return html( "div class='$class fade'", html( "p", $msg ) );
236
  }
237
 
238
+ /**
239
+ * Transform a list of objects into an associative array.
240
+ *
241
+ * @param array $objects
242
+ * @param string $key
243
+ * @param string $value
244
+ *
245
+ * @return array
246
+ */
247
  function scb_list_fold( $list, $key, $value ) {
248
  $r = array();
249
 
250
  if ( is_array( reset( $list ) ) ) {
251
+ foreach ( $list as $item ) {
252
  $r[ $item[ $key ] ] = $item[ $value ];
253
+ }
254
  } else {
255
+ foreach ( $list as $item ) {
256
  $r[ $item->$key ] = $item->$value;
257
+ }
258
  }
259
 
260
  return $r;
263
  /**
264
  * Splits a list into sets, grouped by the result of running each value through $fn.
265
  *
266
+ * @param array $list List of items to be partitioned.
267
+ * @param callback $fn Function that takes an element and returns a string key.
268
+ *
269
+ * @return array
270
  */
271
  function scb_list_group_by( $list, $fn ) {
272
  $groups = array();
274
  foreach ( $list as $item ) {
275
  $key = call_user_func( $fn, $item );
276
 
277
+ if ( null === $key ) {
278
  continue;
279
+ }
280
 
281
  $groups[ $key ][] = $item;
282
  }
287
  //_____Database Table Utilities_____
288
 
289
  /**
290
+ * Register a table with $wpdb.
291
  *
292
+ * @param string $key The key to be used on the $wpdb object.
293
+ * @param string $name (optional) The actual name of the table, without $wpdb->prefix.
294
+ *
295
+ * @return void
296
  */
297
  function scb_register_table( $key, $name = false ) {
298
  global $wpdb;
299
 
300
+ if ( ! $name ) {
301
  $name = $key;
302
+ }
303
 
304
  $wpdb->tables[] = $name;
305
  $wpdb->$key = $wpdb->prefix . $name;
306
  }
307
 
308
  /**
309
+ * Runs the SQL query for installing/upgrading a table.
310
+ *
311
+ * @param string $key The key used in scb_register_table().
312
+ * @param string $columns The SQL columns for the CREATE TABLE statement.
313
+ * @param array $opts (optional) Various other options.
314
  *
315
+ * @return void
 
 
316
  */
317
  function scb_install_table( $key, $columns, $opts = array() ) {
318
  global $wpdb;
330
 
331
  $charset_collate = '';
332
  if ( $wpdb->has_cap( 'collation' ) ) {
333
+ if ( ! empty( $wpdb->charset ) ) {
334
  $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
335
+ }
336
+ if ( ! empty( $wpdb->collate ) ) {
337
  $charset_collate .= " COLLATE $wpdb->collate";
338
+ }
339
  }
340
 
341
  $table_options = $charset_collate . ' ' . $opts['table_options'];
346
  return;
347
  }
348
 
349
+ if ( 'delete_first' == $opts['upgrade_method'] ) {
350
  $wpdb->query( "DROP TABLE IF EXISTS $full_table_name;" );
351
+ }
352
 
353
  $wpdb->query( "CREATE TABLE IF NOT EXISTS $full_table_name ( $columns ) $table_options;" );
354
  }
355
 
356
+ /**
357
+ * Runs the SQL query for uninstalling a table.
358
+ *
359
+ * @param string $key The key used in scb_register_table().
360
+ *
361
+ * @return void
362
+ */
363
  function scb_uninstall_table( $key ) {
364
  global $wpdb;
365
 
370
 
371
  /**
372
  * Generate an HTML tag. Atributes are escaped. Content is NOT escaped.
373
+ *
374
+ * @param string $tag
375
+ *
376
+ * @return string
377
  */
378
  if ( ! function_exists( 'html' ) ):
379
  function html( $tag ) {
387
  $closing = $tag;
388
  $attributes = array_shift( $args );
389
  foreach ( $attributes as $key => $value ) {
390
+ if ( false === $value ) {
391
  continue;
392
+ }
393
 
394
+ if ( true === $value ) {
395
  $value = $key;
396
+ }
397
 
398
  $tag .= ' ' . $key . '="' . esc_attr( $value ) . '"';
399
  }
411
  }
412
  endif;
413
 
414
+ /**
415
+ * Generate an <a> tag.
416
+ *
417
+ * @param string $url
418
+ * @param string $title (optional)
419
+ *
420
+ * @return string
421
+ */
422
  if ( ! function_exists( 'html_link' ) ):
423
  function html_link( $url, $title = '' ) {
424
+ if ( empty( $title ) ) {
425
  $title = $url;
426
+ }
427
 
428
+ return html( 'a', array( 'href' => esc_url( $url ) ), $title );
429
  }
430
  endif;
431
 
432
+ /**
433
+ * Returns an array of query flags.
434
+ *
435
+ * @param object $wp_query (optional)
436
+ *
437
+ * @return array
438
+ */
439
  function scb_get_query_flags( $wp_query = null ) {
440
+ if ( ! $wp_query ) {
441
  $wp_query = $GLOBALS['wp_query'];
442
+ }
443
 
444
  $flags = array();
445
  foreach ( get_object_vars( $wp_query ) as $key => $val ) {
446
+ if ( 'is_' == substr( $key, 0, 3 ) && $val ) {
447
  $flags[] = substr( $key, 3 );
448
+ }
449
  }
450
 
451
  return $flags;
453
 
454
  //_____Compatibility layer_____
455
 
456
+ /**
457
+ * Update data from a post field based on Post ID.
458
+ * @see https://core.trac.wordpress.org/ticket/10946
459
+ *
460
+ * @param string $field Post field name.
461
+ * @param string $value Post field value.
462
+ * @param int $post_id Post ID.
463
+ *
464
+ * @return bool Result of UPDATE query.
465
+ */
466
  if ( ! function_exists( 'set_post_field' ) ) :
467
  function set_post_field( $field, $value, $post_id ) {
468
  global $wpdb;
vendor/scribu/scb-framework/Widget.php CHANGED
@@ -1,29 +1,61 @@
1
  <?php
2
-
3
- // Adds compatibility methods between WP_Widget and scbForms
4
-
5
  abstract class scbWidget extends WP_Widget {
 
 
 
 
 
6
  protected $defaults = array();
7
 
 
 
 
 
8
  private static $scb_widgets = array();
9
 
10
- static function init( $class, $file = '', $base = '' ) {
 
 
 
 
 
 
 
 
 
11
  self::$scb_widgets[] = $class;
12
 
13
  add_action( 'widgets_init', array( __CLASS__, '_scb_register' ) );
14
 
15
  // for auto-uninstall
16
- if ( $file && $base && class_exists( 'scbOptions' ) )
17
  new scbOptions( "widget_$base", $file );
 
18
  }
19
 
20
- static function _scb_register() {
21
- foreach ( self::$scb_widgets as $widget )
 
 
 
 
 
22
  register_widget( $widget );
 
23
  }
24
 
25
- // A pre-filled method, for convenience
26
- function widget( $args, $instance ) {
 
 
 
 
 
 
 
27
  $instance = wp_parse_args( $instance, $this->defaults );
28
 
29
  extract( $args );
@@ -32,44 +64,61 @@ abstract class scbWidget extends WP_Widget {
32
 
33
  $title = apply_filters( 'widget_title', isset( $instance['title'] ) ? $instance['title'] : '', $instance, $this->id_base );
34
 
35
- if ( ! empty( $title ) )
36
  echo $before_title . $title . $after_title;
 
37
 
38
  $this->content( $instance );
39
 
40
  echo $after_widget;
41
  }
42
 
43
- // This is where the actual widget content goes
44
- function content( $instance ) {}
 
 
 
 
 
 
45
 
46
 
47
  //_____HELPER METHODS_____
48
 
49
 
50
- // See scbForms::input()
51
- // Allows extra parameter $args['title']
 
 
 
 
 
 
52
  protected function input( $args, $formdata = array() ) {
53
  $prefix = array( 'widget-' . $this->id_base, $this->number );
54
 
55
  $form = new scbForm( $formdata, $prefix );
56
 
57
  // Add default class
58
- if ( !isset( $args['extra'] ) && 'text' == $args['type'] )
59
  $args['extra'] = array( 'class' => 'widefat' );
 
60
 
61
  // Add default label position
62
- if ( !in_array( $args['type'], array( 'checkbox', 'radio' ) ) && empty( $args['desc_pos'] ) )
63
  $args['desc_pos'] = 'before';
 
64
 
65
  $name = $args['name'];
66
 
67
- if ( !is_array( $name ) && '[]' == substr( $name, -2 ) )
68
  $name = array( substr( $name, 0, -2 ), '' );
 
69
 
70
  $args['name'] = $name;
71
 
72
  return $form->input( $args );
73
  }
 
74
  }
75
 
1
  <?php
2
+ /**
3
+ * Adds compatibility methods between WP_Widget and scbForms.
4
+ */
5
  abstract class scbWidget extends WP_Widget {
6
+
7
+ /**
8
+ * Widget defaults.
9
+ * @var array
10
+ */
11
  protected $defaults = array();
12
 
13
+ /**
14
+ * Widgets to register.
15
+ * @var array
16
+ */
17
  private static $scb_widgets = array();
18
 
19
+ /**
20
+ * Initializes widget.
21
+ *
22
+ * @param string $class
23
+ * @param string $file (optional)
24
+ * @param string $base (optional)
25
+ *
26
+ * @return void
27
+ */
28
+ public static function init( $class, $file = '', $base = '' ) {
29
  self::$scb_widgets[] = $class;
30
 
31
  add_action( 'widgets_init', array( __CLASS__, '_scb_register' ) );
32
 
33
  // for auto-uninstall
34
+ if ( $file && $base && class_exists( 'scbOptions' ) ) {
35
  new scbOptions( "widget_$base", $file );
36
+ }
37
  }
38
 
39
+ /**
40
+ * Registers widgets.
41
+ *
42
+ * @return void
43
+ */
44
+ public static function _scb_register() {
45
+ foreach ( self::$scb_widgets as $widget ) {
46
  register_widget( $widget );
47
+ }
48
  }
49
 
50
+ /**
51
+ * Displays widget content.
52
+ *
53
+ * @param array $args Display arguments including before_title, after_title, before_widget, and after_widget.
54
+ * @param array $instance The settings for the particular instance of the widget.
55
+ *
56
+ * @return void
57
+ */
58
+ public function widget( $args, $instance ) {
59
  $instance = wp_parse_args( $instance, $this->defaults );
60
 
61
  extract( $args );
64
 
65
  $title = apply_filters( 'widget_title', isset( $instance['title'] ) ? $instance['title'] : '', $instance, $this->id_base );
66
 
67
+ if ( ! empty( $title ) ) {
68
  echo $before_title . $title . $after_title;
69
+ }
70
 
71
  $this->content( $instance );
72
 
73
  echo $after_widget;
74
  }
75
 
76
+ /**
77
+ * This is where the actual widget content goes.
78
+ *
79
+ * @param array $instance The settings for the particular instance of the widget.
80
+ *
81
+ * @return void
82
+ */
83
+ protected function content( $instance ) { }
84
 
85
 
86
  //_____HELPER METHODS_____
87
 
88
 
89
+ /**
90
+ * Generates a input form field.
91
+ *
92
+ * @param array $args
93
+ * @param array $formdata (optional)
94
+ *
95
+ * @return string
96
+ */
97
  protected function input( $args, $formdata = array() ) {
98
  $prefix = array( 'widget-' . $this->id_base, $this->number );
99
 
100
  $form = new scbForm( $formdata, $prefix );
101
 
102
  // Add default class
103
+ if ( ! isset( $args['extra'] ) && 'text' == $args['type'] ) {
104
  $args['extra'] = array( 'class' => 'widefat' );
105
+ }
106
 
107
  // Add default label position
108
+ if ( ! in_array( $args['type'], array( 'checkbox', 'radio' ) ) && empty( $args['desc_pos'] ) ) {
109
  $args['desc_pos'] = 'before';
110
+ }
111
 
112
  $name = $args['name'];
113
 
114
+ if ( ! is_array( $name ) && '[]' == substr( $name, -2 ) ) {
115
  $name = array( substr( $name, 0, -2 ), '' );
116
+ }
117
 
118
  $args['name'] = $name;
119
 
120
  return $form->input( $args );
121
  }
122
+
123
  }
124
 
vendor/scribu/scb-framework/load-composer.php CHANGED
@@ -6,6 +6,7 @@
6
  * @param callable $callback
7
  */
8
  function scb_init( $callback = null ) {
9
- if ( $callback )
10
  call_user_func( $callback );
11
- }
 
6
  * @param callable $callback
7
  */
8
  function scb_init( $callback = null ) {
9
+ if ( $callback ) {
10
  call_user_func( $callback );
11
+ }
12
+ }
vendor/scribu/scb-framework/load.php CHANGED
@@ -1,12 +1,19 @@
1
  <?php
2
 
3
  $GLOBALS['_scb_data'] = array( 60, __FILE__, array(
4
- 'scbUtil', 'scbOptions', 'scbForms', 'scbTable',
5
- 'scbWidget', 'scbAdminPage', 'scbBoxesPage', 'scbPostMetabox',
6
- 'scbCron', 'scbHooks',
 
 
 
 
 
 
 
7
  ) );
8
 
9
- if ( !class_exists( 'scbLoad4' ) ) :
10
  /**
11
  * The main idea behind this class is to load the most recent version of the scb classes available.
12
  *
@@ -23,26 +30,28 @@ class scbLoad4 {
23
  static function init( $callback = '' ) {
24
  list( $rev, $file, $classes ) = $GLOBALS['_scb_data'];
25
 
26
- self::$candidates[$file] = $rev;
27
- self::$classes[$file] = $classes;
28
 
29
- if ( !empty( $callback ) ) {
30
- self::$callbacks[$file] = $callback;
31
 
32
  add_action( 'activate_plugin', array( __CLASS__, 'delayed_activation' ) );
33
  }
34
 
35
- if ( did_action( 'plugins_loaded' ) )
36
  self::load();
37
- else
38
  add_action( 'plugins_loaded', array( __CLASS__, 'load' ), 9, 0 );
 
39
  }
40
 
41
- static function delayed_activation( $plugin ) {
42
  $plugin_dir = dirname( $plugin );
43
 
44
- if ( '.' == $plugin_dir )
45
  return;
 
46
 
47
  foreach ( self::$callbacks as $file => $callback ) {
48
  if ( dirname( dirname( plugin_basename( $file ) ) ) == $plugin_dir ) {
@@ -54,16 +63,17 @@ class scbLoad4 {
54
  }
55
  }
56
 
57
- static function load( $do_callbacks = true ) {
58
  arsort( self::$candidates );
59
 
60
  $file = key( self::$candidates );
61
 
62
  $path = dirname( $file ) . '/';
63
 
64
- foreach ( self::$classes[$file] as $class_name ) {
65
- if ( class_exists( $class_name ) )
66
  continue;
 
67
 
68
  $fpath = $path . substr( $class_name, 3 ) . '.php';
69
  if ( file_exists( $fpath ) ) {
@@ -72,9 +82,11 @@ class scbLoad4 {
72
  }
73
  }
74
 
75
- if ( $do_callbacks )
76
- foreach ( self::$callbacks as $callback )
77
  call_user_func( $callback );
 
 
78
  }
79
 
80
  static function get_info() {
@@ -85,7 +97,7 @@ class scbLoad4 {
85
  }
86
  endif;
87
 
88
- if ( !function_exists( 'scb_init' ) ) :
89
  function scb_init( $callback = '' ) {
90
  scbLoad4::init( $callback );
91
  }
1
  <?php
2
 
3
  $GLOBALS['_scb_data'] = array( 60, __FILE__, array(
4
+ 'scbUtil',
5
+ 'scbOptions',
6
+ 'scbForms',
7
+ 'scbTable',
8
+ 'scbWidget',
9
+ 'scbAdminPage',
10
+ 'scbBoxesPage',
11
+ 'scbPostMetabox',
12
+ 'scbCron',
13
+ 'scbHooks',
14
  ) );
15
 
16
+ if ( ! class_exists( 'scbLoad4' ) ) :
17
  /**
18
  * The main idea behind this class is to load the most recent version of the scb classes available.
19
  *
30
  static function init( $callback = '' ) {
31
  list( $rev, $file, $classes ) = $GLOBALS['_scb_data'];
32
 
33
+ self::$candidates[ $file ] = $rev;
34
+ self::$classes[ $file ] = $classes;
35
 
36
+ if ( ! empty( $callback ) ) {
37
+ self::$callbacks[ $file ] = $callback;
38
 
39
  add_action( 'activate_plugin', array( __CLASS__, 'delayed_activation' ) );
40
  }
41
 
42
+ if ( did_action( 'plugins_loaded' ) ) {
43
  self::load();
44
+ } else {
45
  add_action( 'plugins_loaded', array( __CLASS__, 'load' ), 9, 0 );
46
+ }
47
  }
48
 
49
+ public static function delayed_activation( $plugin ) {
50
  $plugin_dir = dirname( $plugin );
51
 
52
+ if ( '.' == $plugin_dir ) {
53
  return;
54
+ }
55
 
56
  foreach ( self::$callbacks as $file => $callback ) {
57
  if ( dirname( dirname( plugin_basename( $file ) ) ) == $plugin_dir ) {
63
  }
64
  }
65
 
66
+ public static function load( $do_callbacks = true ) {
67
  arsort( self::$candidates );
68
 
69
  $file = key( self::$candidates );
70
 
71
  $path = dirname( $file ) . '/';
72
 
73
+ foreach ( self::$classes[ $file ] as $class_name ) {
74
+ if ( class_exists( $class_name ) ) {
75
  continue;
76
+ }
77
 
78
  $fpath = $path . substr( $class_name, 3 ) . '.php';
79
  if ( file_exists( $fpath ) ) {
82
  }
83
  }
84
 
85
+ if ( $do_callbacks ) {
86
+ foreach ( self::$callbacks as $callback ) {
87
  call_user_func( $callback );
88
+ }
89
+ }
90
  }
91
 
92
  static function get_info() {
97
  }
98
  endif;
99
 
100
+ if ( ! function_exists( 'scb_init' ) ) :
101
  function scb_init( $callback = '' ) {
102
  scbLoad4::init( $callback );
103
  }