Plugin Name: WPLib Plugin URI: http://wordpress.org/plugins/wplib/ Description: A WordPress Website Foundation Library Agency and Internal Corporate Developers Version: 0.13.2 Author: The WPLib Team Author URI: http://wplib.org Text Domain: wplib License: GPLv2 or later Copyright 2015 NewClarity Consulting LLC This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
See also: https://github.com/wplib/wplib/commit/8dc27c368e84f7ba6e1448753e1b1f082a60ac6d#commitcomment-11027141
Ejemplo n.º 1
0
 /**
  *
  */
 static function _wp_loaded()
 {
     if (!WPLib::cache_get($cache_key = 'roles_initialized')) {
         self::_initialize_roles();
         WPLib::cache_set($cache_key, true);
     }
 }
Ejemplo n.º 2
0
 /**
  *
  */
 static function on_load()
 {
     /**
      * Add this class as a helper to WPLib
      */
     WPLib::register_helper(__CLASS__);
 }
Ejemplo n.º 3
0
 /**
  * Returns the "current screen."
  *
  * Same as WordPress' get_current_screen() but will call set_current_screen() if is null.
  *
  * @since 0.9.9
  * @return WP_Screen
  */
 static function current_screen()
 {
     if (!function_exists('get_current_screen')) {
         $err_msg = __("%s() cannot be called before WordPress' get_current_screen() is loaded.", 'wplib');
         WPLib::trigger_error($err_msg, __METHOD__, E_USER_ERROR);
         $current_screen = null;
     } else {
         if (is_null($current_screen = get_current_screen())) {
             /*
              * set_current_screen() has to be called before
              * get_current_screen() will return a non-null value.
              */
             set_current_screen();
             $current_screen = get_current_screen();
         }
     }
     return $current_screen;
 }
Ejemplo n.º 4
0
 /**
  * Call at the start of a method to check stability level.
  *
  * Stability levels can be one of:
  *
  *      WPLib_Stability::DEPRECATED (0)
  *      WPLib_Stability::EXPERIMENTAL (1)
  *      WPLib_Stability::STABLE (2)
  *      WPLib_Stability::LOCKED (3)
  *
  * @example The follow illustrates how to check that the stability
  *          level is low enough to support EXPERIMENTAL methods.
  *
  *      /**                                                                                                             `
  *       * @stablity 1 - Experimental
  *       * /
  *      function foo() {
  *          self::stability()->check_method( __METHOD__, WPLib_Stability::EXPERIMENTAL );
  *          // Do the work of foo()
  *          return;
  *      }
  *
  * @param string $method_name
  * @param int $stability
  */
 static function check_method($method_name, $stability)
 {
     if (intval((string) WPLib::stability()) > $stability) {
         $err_msg = __('The %s method has been marked with a stability of %d ' . 'but the current WPLIB_STABILITY requirement is set to %d. ' . 'You can enable this in wp-config-local.php but BE AWARE that ', 'wplib');
         switch ($stability) {
             case self::DEPRECATED:
                 $err_msg .= __('the method has been DEPRECATED and you ' . 'should really revise your code.', 'wplib');
                 break;
             case self::EXPERIMENTAL:
                 $err_msg .= __('the method is EXPERIMENTAL so it is likely to ' . 'change thus forcing you to modify your own code ' . 'when it changes when you plan to upgrade to a ' . 'newer version of WPLib.', 'wplib');
                 break;
             case self::STABLE:
                 $err_msg .= __('the method is STABLE so it is unlikely to change ' . 'but it has not yet been locked to it is possible ' . 'this it could change. If so you will need to modify ' . 'your own code when you plan to upgrade to a newer ' . 'version of WPLib.', 'wplib');
                 break;
             default:
                 $err_msg = false;
                 break;
         }
         if ($err_msg) {
             $err_msg .= __(' To enable add "define( \'WPLIB_STABILITY\', %d );" to your config file.', 'wplib');
             WPLib::trigger_error(sprintf($err_msg, $method_name, $stability, WPLIB_STABILITY, $stability));
         }
     }
 }
Ejemplo n.º 5
0
 /**
  * @param array|string|WPLib_Query $query
  * @param array $args {
  *
  *      @type string $list_class        The specific class for the list, i.e. WPLib_Post_List
  *
  *      @type string $default_list      The default list if no $list_class, i.e. WPLib_Post_List_Default
  *
  *      @type string $items The array of items, or a callable that will return a list of items.
  *
  *      @type string $list_owner        The class "owning" the list, typically "Owner" if Owner::get_list()
  *
  *      @type string $instance_class    The class for items in the list, i.e. WP_Post
  * }
  *
  * @return WPLib_List_Default[]
  *
  */
 static function get_list($query = array(), $args = array())
 {
     if (is_string($query)) {
         $query = wp_parse_args($query);
     } else {
         if (is_null($query)) {
             $query = array();
         }
     }
     if (!isset($args['list_owner'])) {
         $args['list_owner'] = get_called_class();
     }
     if (!isset($args['instance_class'])) {
         $args['instance_class'] = WPLib::get_constant('INSTANCE_CLASS', $args['list_owner']);
     }
     $try_class = $args['instance_class'];
     $args = wp_parse_args($args, array('list_class' => "{$try_class}_List", 'default_list' => 'WPLib_List_Default', 'items' => false));
     if (!class_exists($args['list_class'])) {
         do {
             /**
              * @future Provide a more robust mechanism for discovering 'list_class'
              */
             /*
              * Add '_Default' to last list class checked,
              * i.e. WPLib_Post_List_Default for WPLib_Posts::get_list()
              */
             $args['list_class'] = "{$args['list_class']}_Default";
             if (class_exists($args['list_class'])) {
                 break;
             }
             $args['list_class'] = false;
             $try_class = preg_replace('#^(.+)_Base$#', '$1', get_parent_class($try_class));
             if (!$try_class) {
                 break;
             }
             /*
              * Add '_List' to element class,
              * i.e. WPLib_Post_List for WPLib_Posts::get_list()
              */
             $args['list_class'] = "{$try_class}_List";
             if (class_exists($args['list_class'])) {
                 break;
             }
         } while ($try_class);
     }
     if (!$args['list_class']) {
         /*
          * Give up and use default, i.e. WPLib_List_Default
          */
         $args['list_class'] = $args['default_list'];
     }
     $list_class = $args['list_class'];
     $items = is_callable($args['items']) ? call_user_func($args['items'], $query, $args) : null;
     if (is_null($args['instance_class'])) {
         $message = __('No constant %s::INSTANCE_CLASS defined.', 'wplib');
         WPLib::trigger_error(sprintf($message, $args['list_owner']));
         $list = array();
     } else {
         $list = !is_null($items) ? new $list_class($items, $args) : array();
     }
     unset($args['list_owner'], $args['list_class'], $args['list_default'], $args['default_list'], $args['items']);
     return $list;
 }
Ejemplo n.º 6
0
 /**
  * @param WPLib_Item_Base|WP_Post|WP_Term $item
  * @param array $args
  *
  * @return WPLib_Term_Base|WPLib_Post_Base
  */
 static function make_new_item($item, $args = array())
 {
     $class = get_called_class();
     if (WPLib::get_constant('POST_TYPE', $class)) {
         $item = WPLib_Posts::make_new_item($item, $args);
     } else {
         if (WPLib::get_constant('TAXONOMY', $class)) {
             $item = WPLib_Terms::make_new_item($item, $args);
         } else {
             $err_msg = __('Cannot make new item. Class %s does not have POST_TYPE or TAXONOMY constant.', 'wplib');
             WPLib::trigger_error(sprintf($err_msg, $class));
         }
     }
     return $item;
 }
Ejemplo n.º 7
0
 /**
  * Magic method for calling inaccessible methods
  * Examples:
  *  $this->date             Return original ISO 8601 date format from model
  *  $this->get_date()       Return custom formatted date
  *  $this->get_date_html()  Return custom formatted date HTML
  *  $this->the_date()       Output custom formatted date
  *  $this->the_date_html()  Output custom formatted date HTML
  *
  * @param string $method_name
  * @param array  $args
  *
  * @return mixed|null
  */
 function __call($method_name, $args = array())
 {
     $value = null;
     if (false !== strpos($method_name, 'the_')) {
         $value = WPLib::do_the_methods($this, $this->model(), $method_name, $args);
     } else {
         $value = call_user_func_array(array($this->model(), $method_name), $args);
     }
     return $value;
 }
Ejemplo n.º 8
0
 /**
  * @return array|mixed
  */
 static function role_classes()
 {
     if (!($role_classes = WPLib::cache_get($cache_key = 'role_classes'))) {
         WPLib::autoload_all_classes();
         $role_classes = array();
         foreach (get_declared_classes() as $user_class) {
             if (!is_subclass_of($user_class, 'WPLib_User_Base')) {
                 continue;
             }
             if ($role_slug = self::get_role_slug_by('class', $user_class)) {
                 $role_classes[$role_slug] = $user_class;
             }
         }
         WPLib::cache_set($cache_key, $role_classes);
     }
     return $role_classes;
 }
Ejemplo n.º 9
0
 /**
  * Outputs an HTML <a> link
  *
  * Convenience function so designers don't need to worry about WPLib:: vs. $theme->.
  *
  * @param string $href
  * @param string $link_text
  * @param array $args
  */
 function the_link($href, $link_text, $args = array())
 {
     WPLib::the_link($href, $link_text, $args);
 }
Ejemplo n.º 10
0
 /**
  * User role as declared in the class constant ROLE.
  *
  * @return string|null
  */
 function role_slug()
 {
     return WPLib::get_constant('ROLE', get_class($this->owner));
 }
Ejemplo n.º 11
0
 /**
  * @return string
  */
 static function post_type_list_class()
 {
     $called_class = get_called_class();
     if (!($post_type_list_class = WPLib::cache_get($cache_key = "list_post_type_class[{$called_class}]"))) {
         foreach (WPLib::site_classes() as $class_name) {
             if (is_subclass_of($class_name, 'WPLib_Post_List_Base') && ($post_type = static::get_constant('POST_TYPE', $class_name))) {
                 $post_type_list_class = $class_name;
             }
         }
         if (!$post_type_list_class) {
             $post_type_list_class = 'WPLib_Post_List_Default';
         }
         WPLib::cache_get($cache_key, $post_type_list_class);
     }
     return $post_type_list_class;
 }
Ejemplo n.º 12
0
 /**
  * Theme method for setting a theme instance for unit test mocking.
  *
  * @param $theme
  *
  * @return mixed
  */
 static function set_mock_theme($theme)
 {
     WPLib::set_theme($theme);
 }
Ejemplo n.º 13
0
 /**
  * @return int
  */
 function number_of_comment_pages()
 {
     $theme = WPLib::theme();
     if (!$theme->uses_paged_comments()) {
         $number = $this->has_comments() ? 1 : 0;
     } else {
         $number = $this->has_post() ? $theme->number_of_comment_pages() : 0;
     }
     return $number;
 }
Ejemplo n.º 14
0
 /**
  * Returns the TAXONOMY value for this model's item.
  *
  * @return mixed|null
  */
 static function item_taxonomy()
 {
     return WPLib::get_constant('TAXONOMY', self::item_class());
 }
Ejemplo n.º 15
0
 /**
  * @return string[]
  *
  * @future Enhance this to support multiple classes per term type
  * @future Rename to term_classes() and deprecate this name
  */
 static function taxonomy_classes()
 {
     return WPLib::get_child_classes('WPLib_Term_Base', 'TAXONOMY');
 }
Ejemplo n.º 16
0
 /**
  * Update the RECENT_COMMIT constant for WPLib or the App Class.
  *
  * The update does not affect the current value for RECENT_COMMIT until next page load.
  *
  * @param string $class_name
  */
 private static function _maybe_update_class($class_name)
 {
     $recent_commit = self::get_recent_commit($class_name, $defined);
     $not_exists = !$defined || is_null($recent_commit);
     $loaded_commit = self::load_recent_commit($class_name);
     if ($not_exists || !is_null($loaded_commit) && $recent_commit !== $loaded_commit) {
         $reflector = new ReflectionClass($class_name);
         $source_file = $reflector->getFileName();
         $source_code = WPLib::get_contents($source_file);
         $source_size = strlen($source_code);
         if (preg_match("#const\\s+RECENT_COMMIT#", $source_code)) {
             $marker = "const\\s+RECENT_COMMIT\\s*=\\s*'[^']*'\\s*;\\s*(//.*)?\\s*\n";
             $replacer = "const RECENT_COMMIT = '{$loaded_commit}'; \$1\n\n";
         } else {
             $marker = "class\\s+{$class_name}\\s+(extends\\s+\\w+)?\\s*\\{\\s*\n";
             $replacer = "\$0\tconst RECENT_COMMIT = '{$loaded_commit}';\n\n";
         }
         $new_code = preg_replace("#{$marker}#", $replacer, $source_code);
         if ($new_code && strlen($new_code) >= $source_size) {
             WPLib::put_contents($source_file, $new_code);
         }
     }
 }
Ejemplo n.º 17
0
 /**
  * @param string $template
  * @param array $_template_vars
  */
 function the_app_template($template, $_template_vars = array())
 {
     WPLib::the_app_template($template, $_template_vars, $this->owner);
 }
Ejemplo n.º 18
0
    /**
     * Returns  one or more HTML <li> elements
     *
     * @param string $element_text
     * @param array $args {
     *
     *      @type string $before
     *      @type string $before_text
     *      @type string[]|string $attributes
     *      @type string $class
     *      @type string $after_text
     *      @type string $after
     *      @type callable $filter
     *      @type mixed $index
     * }
     * @return string
     */
    static function get_html_li_element_html($element_text, $args = array())
    {
        $args = wp_parse_args($args, array('before' => '', 'class' => '', 'attributes' => array(), 'before_text' => '', 'after_text' => '', 'after' => '', 'filter' => null, 'elements' => array(), 'index' => null));
        $before_text = $args['before_text'] ? esc_html($args['before_text']) : '';
        $element_text = $element_text ? esc_html($element_text) : '';
        $after_text = $args['after_text'] ? esc_html($args['after_text']) : '';
        if (!empty($args['attributes']['class'])) {
            $args['class'] = esc_attr("{$args['attributes']['class']} {$args['class']}");
            unset($args['attributes']['class']);
        }
        if ($args['filter']) {
            $args = call_user_func($args['filter'], $args, $element_text, $args['elements']);
        }
        $attributes = count($args['attributes']) ? $args['attributes'] : '';
        if ($attributes) {
            $attributes = ' ' . WPLib::get_html_attributes_html($attributes);
        }
        $elements_html .= <<<HTML
{$args['before']}<li{$attributes} class="{$args['class']}">{$before_text}{$element_text}{$after_text}</li>{$args['after']}
HTML;
        return $elements_html;
    }
Ejemplo n.º 19
0
 /**
  * @return null|string
  */
 function app_class()
 {
     return WPLib::app_class($this);
 }
Ejemplo n.º 20
0
 /**
  * Generate debugging error message for attempts to call a non-existent method.
  *
  * @param string $method_name
  * @param array  $args
  *
  * @return mixed
  */
 function __call($method_name, $args)
 {
     $value = null;
     if (preg_match('#^the_#', $method_name) && is_callable(array($this, $method_name))) {
         $value = WPLib::do_the_methods($this, $this, $method_name, $args);
     } else {
         /*
          * Oops. No method was found.  Output an error message.
          */
         $message = sprintf(__('ERROR: There is no method %s() in class %s. ', 'wplib'), $method_name, get_class($this));
         WPLib::trigger_error($message, E_USER_ERROR);
     }
     return $value;
 }
Ejemplo n.º 21
0
 /**
  * @return string[]
  *
  * @future Enhance this to support multiple classes per post type
  * @future Rename to post_classes() and deprecate this name
  */
 static function post_type_classes()
 {
     return WPLib::get_child_classes('WPLib_Post_Base', 'POST_TYPE');
 }
Ejemplo n.º 22
0
 /**
  * @param WPLib_Item_Base|WP_Post|WP_Term $item
  * @param array $args
  *
  * @return WPLib_Term_Base|WPLib_Post_Base
  */
 static function make_new_item($item, $args = array())
 {
     $class = get_called_class();
     if (WPLib::get_constant('INSTANCE_CLASS', $class)) {
         if (self::class_declares_method($class, 'make_new_item')) {
             $item = $class::make_new_item($item, $args);
         } else {
             if (WPLib::is_development()) {
                 $err_msg = __('Cannot make new item. Class %s does not have make_new_item method', 'wplib');
                 WPLib::trigger_error(sprintf($err_msg, $class), E_USER_ERROR);
             }
         }
     } else {
         if (WPLib::is_development()) {
             $err_msg = __('Cannot make new item. Class %s does not have INSTANCE_CLASS constant.', 'wplib');
             WPLib::trigger_error(sprintf($err_msg, $class), E_USER_ERROR);
         }
     }
     return $item;
 }
Ejemplo n.º 23
0
 /**
  * Runs through all the registered roles and ensures that all roles and get_capabilities
  * are set as defined in the classes.
  *
  * @param string $recent_commit
  * @param string $previous_commit
  */
 private static function _initialize_roles($recent_commit, $previous_commit)
 {
     WPLib::autoload_all_classes();
     $app_slug = strtolower(WPLib::app_class());
     $option = get_option($option_name = "{$app_slug}_roles", array());
     $wp_roles = new WP_Roles();
     $dirty = false;
     foreach (self::$_roles as $role_slug => $role) {
         if (preg_match('#^WPLib_(Administrators|Editors|Contributors|Subscribers|Authors)$#', $role['class_name'])) {
             /*
              * Easier just to punt on these for right now.
              * WordPress does some weird things with built-in roles,
              * especially with Administrator related to Multisite
              */
             continue;
         }
         if (empty($role_slug)) {
             /*
              * Somehow we got an empty role slug?!?.  Carry on.
              */
             continue;
         }
         $capabilities = call_user_func(array($role['class_name'], 'capabilities'));
         if (!isset($option[$role_slug])) {
             $option[$role_slug] = array('prior_capabilities' => $capabilities, 'recent_commit' => $recent_commit, 'previous_commit' => $previous_commit);
             $dirty = true;
         }
         $display_name = self::get_role_display_name($role_slug);
         $prior_capabilities = $option[$role_slug]['prior_capabilities'];
         /*
          * Get the capabilities
          */
         if (is_null($current_capabilities = $wp_roles->role_objects[$role_slug]->capabilities)) {
             $current_capabilities = array();
         } else {
             /**
              * Remove all the legacy level_0 through level_10 capabilities.
              */
             for ($i = 0; $i <= 10; $i++) {
                 unset($current_capabilities["level_{$i}"]);
             }
         }
         if (empty($prior_capabilities)) {
             /**
              * First time in, let's assume previous are same as current.
              */
             $prior_capabilities = $current_capabilities;
         }
         /**
          * Filter the capabilities that should be applied for the role.
          *
          * @since 0.11.0
          *
          * @param string[] $capabilities
          * @param string   $role_slug {
          * @param array    $role {
          *     An array of information about the role as assigned in self::register_role().
          *
          *     @type string   $display_name  Title used to display the role to users.
          *     @type string[] $capabilities  Array of capabilities that should be assigned to the role.
          *     @type string   $class_name    Name of class defining the role that inherits from WPLib_Role_Module_Base.
          * }
          */
         $capabilities = apply_filters('wplib_role_capabilities', $capabilities, $role_slug, $role);
         $capabilities = array_fill_keys($capabilities, true);
         if (defined('WPLIB_UPDATE_ROLES') && WPLIB_UPDATE_ROLES) {
             $change_role = true;
         } else {
             if (!isset($wp_roles->roles[$role_slug])) {
                 /*
                  * Whelp, the role does not exists, so let's add it.
                  */
                 $change_role = true;
             } else {
                 if (isset($merged) || !self::_arrays_are_equivalent($capabilities, $current_capabilities)) {
                     /*
                      * The new capabilities are different than the current ones, AND
                      * nobody  changed the capabilities since we last updated them.
                      *
                      * This stops manually changed capabilities from being overwritten
                      * at the expense of not containing new capabilities defined in the
                      * code. Better to respect the user's efforts and add a burden on
                      * them then to ignore the user's efforts and simply reset.
                      */
                     $change_role = self::_arrays_are_equivalent($current_capabilities, $prior_capabilities);
                 } else {
                     if ($display_name !== $wp_roles->role_names[$role_slug]) {
                         /*
                          * The display name has changed so let's update the role.
                          */
                         $change_role = true;
                     } else {
                         if ($display_name !== $wp_roles->role_names[$role_slug]) {
                             /*
                              * Does not seem there is a reason to change.
                              */
                             $change_role = false;
                         } else {
                             /*
                              * Bah. Don't change it. No evidence we need to.
                              */
                             $change_role = false;
                         }
                     }
                 }
             }
         }
         if ($change_role) {
             /**
              * @note: Just FYI, this will remove the legacy get_capabilities of level_0..level_10.
              * @note: Should not be an issue for a modern WP app. If it becomes an issue we can test for them too.
              */
             remove_role($role_slug);
             call_user_func($role_slug, $display_name, $capabilities);
             $option[$role_slug] = array('prior_capabilities' => $capabilities, 'recent_commit' => $recent_commit, 'previous_commit' => $previous_commit);
             $dirty = true;
         }
     }
     self::$_roles = array();
     if ($dirty) {
         update_option($option_name, $option, 'no');
         /**
          * @future Change this to redirect to the same URL they were on
          *       Which means adding something like WPLib::current_url().
          *       Maybe even a WPLib::redirect_to_self().
          *       But I want to sleep on that a few days first.
          */
         wp_safe_redirect(home_url('/'));
         exit;
     }
 }
Ejemplo n.º 24
0
 /**
  * Allows a post type to attach a taxonomy that is registered by someone else's code.
  *
  * @param string $taxonomy
  *
  * @stability 1 - Experimental
  */
 static function attach_taxonomy($taxonomy)
 {
     $VALID_HOOK = 'wplib_post_register_taxonomies';
     if (current_action() !== $VALID_HOOK) {
         $class_name = get_called_class();
         $err_msg = __('%s::%s() will only work correctly if called within the action hook %s.', 'wplib');
         WPLib::trigger_error(sprintf($err_msg, $class_name, __FUNCTION__, $VALID_HOOK));
     }
     register_taxonomy_for_object_type($taxonomy, static::POST_TYPE);
 }
Ejemplo n.º 25
0
 /**
  * @param string $filepath
  * @return string
  */
 function get_root_dir($filepath)
 {
     return WPLib::get_root_dir($filepath, get_class($this));
 }
Ejemplo n.º 26
0
 /**
  * @return bool|string
  */
 static function short_prefix()
 {
     return WPLib::get_constant('SHORT_PREFIX', get_called_class());
 }
Ejemplo n.º 27
0
 /**
  * @param array $args
  *
  */
 function the_comment_list_html($args = array())
 {
     wp_list_comments($args, WPLib::theme()->query()->comments);
 }
Ejemplo n.º 28
0
 /**
  * @param string $template
  * @param array $args
  * @return string
  */
 function get_template_html($template, $args = array())
 {
     $cache_key = "wplib_template[{$template}][" . md5(serialize($args)) . ']';
     if (!($output = WPLib::cache_get($cache_key))) {
         ob_start();
         $index = 0;
         foreach ($this->elements() as $element) {
             /**
              * @var WPLib_Item_Base $element
              *
              * @todo Create a interface that would indicate a class has a 'the_template' method.
              *
              */
             $args['index'] = $index++;
             $element->the_template($template, $args);
         }
         WPLib::cache_set($cache_key, $output = ob_get_clean());
     }
     return $output;
 }
Ejemplo n.º 29
0
 /**
  * @return array|mixed
  */
 static function role_classes()
 {
     return WPLib::get_child_classes('WPLib_User_Base', 'ROLE');
 }
Ejemplo n.º 30
0
 /**
  * @return mixed|null
  */
 static function var_name()
 {
     return WPLib::get_constant('VAR_NAME', static::instance_class());
 }