[ Index ]

PHP Cross Reference of BuddyPress

title

Body

[close]

/src/bp-forums/bbpress/bb-admin/includes/ -> functions.bb-plugin.php (source)

   1  <?php
   2  
   3  function bb_get_plugins_callback( $type = 'normal', $path, $filename )
   4  {
   5      if ( '.php' != substr( $filename, -4 ) ) {
   6          return false;
   7      }
   8  
   9      $data = array( 'autoload' => 0 );
  10  
  11      if ( $has_underscore = '_' === substr( $filename, 0, 1 ) ) {
  12          switch ( $type ) {
  13              case 'all':
  14              case 'autoload':
  15                  $data['autoload'] = 1;
  16                  break;
  17              case 'normal':
  18              default:
  19                  return false;
  20                  break;
  21          }
  22      } elseif ( 'autoload' === $type ) {
  23          return false;
  24      }
  25  
  26      if ( $_data = bb_get_plugin_data( $path ) ) {
  27          return array_merge( $_data , $data );
  28      }
  29  
  30      return false;
  31  }
  32  
  33  function bb_get_plugins( $location = 'all', $type = 'normal', $status = 'all' )
  34  {
  35      static $plugin_cache = array();
  36  
  37      if ( !in_array( $type, array( 'all', 'autoload', 'normal' ) ) ) {
  38          $type = 'normal';
  39      }
  40  
  41      if ( 'autoload' === $type || !in_array( $status, array( 'all', 'active', 'inactive' ) ) ) {
  42          $status = 'all';
  43      }
  44  
  45      if ( isset( $plugin_cache[$location][$type][$status] ) ) {
  46          return $plugin_cache[$location][$type][$status];
  47      }
  48  
  49      global $bb;
  50      $directories = array();
  51      if ( 'all' === $location ) {
  52          foreach ( $bb->plugin_locations as $_data ) {
  53              $directories[] = $_data['dir'];
  54          }
  55      } elseif ( isset( $bb->plugin_locations[$location]['dir'] ) ) {
  56          $directories[] = $bb->plugin_locations[$location]['dir'];
  57      }
  58  
  59      require_once( BB_PATH . BB_INC . 'class.bb-dir-map.php' );
  60  
  61      $plugin_arrays = array();
  62      foreach ( $directories as $directory ) {
  63          $dir_map = new BB_Dir_Map(
  64              $directory,
  65              array(
  66                  'callback' => 'bb_get_plugins_callback',
  67                  'callback_args' => array( $type ),
  68                  'recurse' => 1
  69              )
  70          );
  71          $dir_plugins = $dir_map->get_results();
  72          $dir_plugins = is_wp_error( $dir_plugins ) ? array() : $dir_plugins;
  73          $plugin_arrays[] = $dir_plugins;
  74          unset($dir_map, $dir_plugins);
  75      }
  76      
  77      $plugins = array();
  78      foreach ($plugin_arrays as $plugin_array) {
  79          $plugins = array_merge($plugins, $plugin_array);
  80      }
  81  
  82      $active_plugins = (array) bb_get_option( 'active_plugins' );
  83      
  84      $adjusted_plugins = array();
  85      foreach ($plugins as $plugin => $plugin_data) {
  86          $_id = $plugin_data['location'] . '#' . $plugin;
  87          $plugin_data['active'] = 0;
  88          if ( 'autoload' === $type || in_array( $_id, $active_plugins ) ) {
  89              $plugin_data['active'] = 1;
  90          }
  91          if (
  92              'active' === $status && $plugin_data['active'] ||
  93              'inactive' === $status && !$plugin_data['active'] ||
  94              'all' === $status
  95          ) {
  96              $adjusted_plugins[$_id] = $plugin_data;
  97          }
  98      }
  99  
 100      uasort( $adjusted_plugins, 'bb_plugins_sort' );
 101  
 102      $plugin_cache[$location][$type][$status] = $adjusted_plugins;
 103  
 104      return $adjusted_plugins;
 105  }
 106  
 107  function bb_plugins_sort( $a, $b )
 108  {
 109      return strnatcasecmp( $a['name'], $b['name'] );
 110  }
 111  
 112  function bb_get_plugin_counts()
 113  {
 114      $all_plugins = bb_get_plugins( 'all', 'all' );
 115      $active_plugins = (array) bb_get_option( 'active_plugins' );
 116      $counts = array(
 117          'plugin_count_all' => count( $all_plugins ),
 118          'plugin_count_active' => count( $active_plugins ),
 119          'plugin_count_inactive' => 0,
 120          'plugin_count_autoload' => 0
 121      );
 122      foreach ( $all_plugins as $id => $all_plugin ) {
 123          if ( $all_plugin['autoload'] ) {
 124              $counts['plugin_count_autoload']++;
 125          } elseif ( !in_array( $id, $active_plugins ) ) {
 126              $counts['plugin_count_inactive']++;
 127          }
 128      }
 129      return $counts;
 130  }
 131  
 132  /**
 133   * Parse the plugin contents to retrieve plugin's metadata.
 134   *
 135   * The metadata of the plugin's data searches for the following in the plugin's
 136   * header. All plugin data must be on its own line. For plugin description, it
 137   * must not have any newlines or only parts of the description will be displayed
 138   * and the same goes for the plugin data. The below is formatted for printing.
 139   *
 140   * <code>
 141   * /*
 142   * Plugin Name: Name of Plugin
 143   * Plugin URI: Link to plugin information
 144   * Description: Plugin Description
 145   * Author: Plugin author's name
 146   * Author URI: Link to the author's web site
 147   * Version: Must be set
 148   * Requires at least: Optional.  Minimum bbPress version this plugin requires
 149   * Tested up to: Optional. Maximum bbPress version this plugin has been tested with
 150   * Text Domain: Optional. Unique identifier, should be same as the one used in
 151   *        bb_load_plugin_textdomain()
 152   * Domain Path: Optional. Only useful if the translations are located in a
 153   *        folder above the plugin's base path. For example, if .mo files are
 154   *        located in the locale folder then Domain Path will be "/locale/" and
 155   *        must have the first slash. Defaults to the base folder the plugin is
 156   *        located in.
 157   *  * / # You must remove the space to close comment (the space is here only for documentation purposes).
 158   * </code>
 159   *
 160   * Plugin data returned array contains the following:
 161   *        'location' - Location of plugin file
 162   *        'name' - Name of the plugin, must be unique.
 163   *        'uri' - Plugin's web site.
 164   *        'plugin_link' - Title of plugin linked to plugin's web site.
 165   *        'description' - Description of what the plugin does and/or notes
 166   *        from the author.
 167   *        'author' - The author's name
 168   *        'author_uri' - The author's web site address.
 169   *        'author_link' - The author's name linked to the author's web site.
 170   *        'version' - The plugin version number.
 171   *        'requires' - Minimum bbPress version plugin requires
 172   *        'tested' - Maximum bbPress version plugin has been tested with
 173   *        'text_domain' - Plugin's text domain for localization.
 174   *        'domain_path' - Plugin's relative directory path to .mo files.
 175   *
 176   * Some users have issues with opening large files and manipulating the contents
 177   * for want is usually the first 1kiB or 2kiB. This function stops pulling in
 178   * the plugin contents when it has all of the required plugin data.
 179   *
 180   * The first 8kiB of the file will be pulled in and if the plugin data is not
 181   * within that first 8kiB, then the plugin author should correct their plugin
 182   * and move the plugin data headers to the top.
 183   *
 184   * The plugin file is assumed to have permissions to allow for scripts to read
 185   * the file. This is not checked however and the file is only opened for
 186   * reading.
 187   *
 188   * @link http://trac.wordpress.org/ticket/5651 Previous Optimizations.
 189   * @link http://trac.wordpress.org/ticket/7372 Further and better Optimizations.
 190   * @since 1.5.0
 191   *
 192   * @param string $plugin_file Path to the plugin file
 193   * @param bool $markup If the returned data should have HTML markup applied
 194   * @param bool $translate If the returned data should be translated
 195   * @return array See above for description.
 196   */
 197  function bb_get_plugin_data( $plugin_file, $markup = true, $translate = true ) {
 198      global $bb;
 199  
 200      if ( preg_match( '/^([a-z0-9_-]+)#((?:[a-z0-9\/\\_-]+.)+)(php)$/i', $plugin_file, $_matches ) ) {
 201          $plugin_file = $bb->plugin_locations[$_matches[1]]['dir'] . $_matches[2] . $_matches[3];
 202          
 203          $_directory = $bb->plugin_locations[$_matches[1]]['dir'];
 204          $_plugin = $_matches[2] . $_matches[3];
 205  
 206          if ( !$_plugin ) {
 207              // Not likely
 208              return false;
 209          }
 210  
 211          if ( validate_file( $_plugin ) ) {
 212              // $plugin has .., :, etc.
 213              return false;
 214          }
 215  
 216          $plugin_file = $_directory . $_plugin;
 217          unset( $_matches, $_directory, $_plugin );
 218      }
 219  
 220      if ( !file_exists( $plugin_file ) ) {
 221          // The plugin isn't there
 222          return false;
 223      }
 224  
 225      // We don't need to write to the file, so just open for reading.
 226      $fp = fopen($plugin_file, 'r');
 227  
 228      // Pull only the first 8kiB of the file in.
 229      $plugin_code = fread( $fp, 8192 );
 230  
 231      // PHP will close file handle, but we are good citizens.
 232      fclose($fp);
 233  
 234      // Grab just the first commented area from the file
 235      if ( !preg_match( '|/\*(.*?Plugin Name:.*?)\*/|ims', $plugin_code, $plugin_block ) )
 236          return false;
 237          $plugin_data = trim( $plugin_block[1] );
 238  
 239      preg_match( '|Plugin Name:(.*)$|mi', $plugin_data, $name );
 240      preg_match( '|Plugin URI:(.*)$|mi', $plugin_data, $uri );
 241      preg_match( '|Version:(.*)|i', $plugin_data, $version );
 242      preg_match( '|Description:(.*)$|mi', $plugin_data, $description );
 243      preg_match( '|Author:(.*)$|mi', $plugin_data, $author );
 244      preg_match( '|Author URI:(.*)$|mi', $plugin_data, $author_uri );
 245      preg_match( '|Text Domain:(.*)$|mi', $plugin_data, $text_domain );
 246      preg_match( '|Domain Path:(.*)$|mi', $plugin_data, $domain_path );
 247      preg_match( '|Requires at least:(.*)$|mi', $plugin_data, $requires );
 248      preg_match( '|Tested up to:(.*)$|mi', $plugin_data, $tested );
 249  
 250      // Normalise the path to the plugin
 251      $plugin_file = str_replace( '\\', '/', $plugin_file );
 252  
 253      foreach ( $bb->plugin_locations as $_name => $_data ) {
 254          $_directory = str_replace( '\\', '/', $_data['dir'] );
 255          if ( 0 === strpos( $plugin_file, $_directory ) ) {
 256              $location = array( 1 => $_name );
 257              break;
 258          }
 259      }
 260  
 261      $plugins_allowedtags = array('a' => array('href' => array(),'title' => array()),'abbr' => array('title' => array()),'acronym' => array('title' => array()),'code' => array(),'em' => array(),'strong' => array());
 262  
 263      $fields = array(
 264          'location' => '',
 265          'name' => 'html',
 266          'uri' => 'url',
 267          'version' => 'text',
 268          'description' => 'html',
 269          'author' => 'html',
 270          'author_uri' => 'url',
 271          'text_domain' => '',
 272          'domain_path' => '',
 273          'requires' => 'text',
 274          'tested' => 'text',
 275      );
 276      foreach ( $fields as $field => $san ) {
 277          if ( !empty( ${$field} ) ) {
 278              ${$field} = trim(${$field}[1]);
 279              switch ( $san ) {
 280              case 'html' :
 281                  ${$field} = bb_filter_kses( ${$field} );
 282                  break;
 283              case 'text' :
 284                  ${$field} = esc_html(  ${$field} );
 285                  break;
 286              case 'url' :
 287                  ${$field} = esc_url( ${$field} );
 288                  break;
 289              }
 290          } else {
 291              ${$field} = '';
 292          }
 293      }
 294  
 295      $plugin_data = compact( array_keys( $fields ) );
 296  
 297      if ( $translate )
 298          $plugin_data = _bb_get_plugin_data_translate( $plugin_data, $plugin_file );
 299  
 300      if ( $markup )
 301          $plugin_data['description'] = bb_autop( preg_replace( '/[\r\n]+/', "\n", trim( $plugin_data['description'] ) ) );
 302  
 303      $plugin_data['plugin_link'] = ( $plugin_data['uri'] ) ?
 304          "<a href='{$plugin_data['uri']}' title='" . esc_attr__( 'Visit plugin site' ) . "'>{$plugin_data['name']}</a>" :
 305          $plugin_data['name'];
 306      $plugin_data['author_link'] = ( $plugin_data['author'] && $plugin_data['author_uri'] ) ?
 307          "<a href='{$plugin_data['author_uri']}' title='" . esc_attr__( 'Visit author homepage' ) . "'>{$plugin_data['author']}</a>" :
 308          $plugin_data['author'];
 309  
 310      return $plugin_data;
 311  }
 312  
 313  function _bb_get_plugin_data_translate( $plugin_data, $plugin_file ) {
 314      //Translate fields
 315      if( !empty($plugin_data['text_domain']) ) {
 316          if( ! empty( $plugin_data['domain_path'] ) )
 317              bb_load_plugin_textdomain($plugin_data['text_domain'], dirname($plugin_file). $plugin_data['domain_path']);
 318          else
 319              bb_load_plugin_textdomain($plugin_data['text_domain'], dirname($plugin_file));
 320  
 321          foreach ( array('name', 'plugin_url', 'description', 'author', 'author_uri', 'version') as $field )
 322              $plugin_data[$field] = translate($plugin_data[$field], $plugin_data['text_domain']);
 323      }
 324  
 325      return $plugin_data;
 326  }
 327  
 328  /**
 329   * Attempts activation of plugin in a "sandbox" and redirects on success.
 330   *
 331   * A plugin that is already activated will not attempt to be activated again.
 332   *
 333   * The way it works is by setting the redirection to the error before trying to
 334   * include the plugin file. If the plugin fails, then the redirection will not
 335   * be overwritten with the success message. Also, the options will not be
 336   * updated and the activation hook will not be called on plugin error.
 337   *
 338   * It should be noted that in no way the below code will actually prevent errors
 339   * within the file. The code should not be used elsewhere to replicate the
 340   * "sandbox", which uses redirection to work.
 341   *
 342   * If any errors are found or text is outputted, then it will be captured to
 343   * ensure that the success redirection will update the error redirection.
 344   *
 345   * @since 1.0
 346   *
 347   * @param string $plugin Plugin path to main plugin file with plugin data.
 348   * @param string $redirect Optional. URL to redirect to.
 349   * @return WP_Error|null WP_Error on invalid file or null on success.
 350   */
 351  function bb_activate_plugin( $plugin, $redirect = '' ) {
 352      $active_plugins = (array) bb_get_option( 'active_plugins' );
 353      $plugin = bb_plugin_basename( trim( $plugin ) );
 354  
 355      $valid_path = bb_validate_plugin( $plugin );
 356      if ( is_wp_error( $valid_path ) )
 357          return $valid_path;
 358  
 359      if ( in_array( $plugin, $active_plugins ) ) {
 360          return false;
 361      }
 362  
 363      if ( !empty( $redirect ) ) {
 364          // We'll override this later if the plugin can be included without fatal error
 365          wp_redirect( add_query_arg( '_scrape_nonce', bb_create_nonce( 'scrape-plugin_' . $plugin ), $redirect ) ); 
 366      }
 367  
 368      ob_start();
 369      @include( $valid_path );
 370      // Add to the active plugins array
 371      $active_plugins[] = $plugin;
 372      ksort( $active_plugins );
 373      bb_update_option( 'active_plugins', $active_plugins );
 374      do_action( 'bb_activate_plugin_' . $plugin );
 375      ob_end_clean();
 376  
 377      return $valid_path;
 378  }
 379  
 380  /**
 381   * Deactivate a single plugin or multiple plugins.
 382   *
 383   * The deactivation hook is disabled by the plugin upgrader by using the $silent
 384   * parameter.
 385   *
 386   * @since unknown
 387   *
 388   * @param string|array $plugins Single plugin or list of plugins to deactivate.
 389   * @param bool $silent Optional, default is false. Prevent calling deactivate hook.
 390   */
 391  function bb_deactivate_plugins( $plugins, $silent = false ) {
 392      $active_plugins = (array) bb_get_option( 'active_plugins' );
 393  
 394      if ( !is_array( $plugins ) ) {
 395          $plugins = array( $plugins );
 396      }
 397  
 398      foreach ( $plugins as $plugin ) {
 399          $plugin = bb_plugin_basename( trim( $plugin ) );
 400          if ( !in_array( $plugin, $active_plugins ) ) {
 401              continue;
 402          }
 403          // Remove the deactivated plugin
 404          array_splice( $active_plugins, array_search( $plugin, $active_plugins ), 1 );
 405          if ( !$silent ) {
 406              do_action( 'bb_deactivate_plugin_' . $plugin );
 407          }
 408      }
 409  
 410      bb_update_option( 'active_plugins', $active_plugins );
 411  }
 412  
 413  /**
 414   * Validate the plugin path.
 415   *
 416   * Checks that the file exists and is valid file.
 417   *
 418   * @since 1.0
 419   * @uses validate_file() to check the passed plugin identifier isn't malformed
 420   * @uses bb_get_plugin_path() to get the full path of the plugin
 421   * @uses bb_get_plugins() to get the plugins that actually exist
 422   *
 423   * @param string $plugin Plugin Path
 424   * @param string $location The location of plugin, one of 'user', 'core' or 'all'
 425   * @param string $type The type of plugin, one of 'all', 'autoload' or 'normal'
 426   * @return WP_Error|int 0 on success, WP_Error on failure.
 427   */
 428  function bb_validate_plugin( $plugin, $location = 'all', $type = 'all' ) {
 429      if ( validate_file( trim( $plugin ) ) ) {
 430          return new WP_Error( 'plugin_invalid', __( 'Invalid plugin path.' ) );
 431      }
 432      $path = bb_get_plugin_path( trim( $plugin ) );
 433      if ( !file_exists( $path ) ) {
 434          return new WP_Error( 'plugin_not_found', __( 'Plugin file does not exist.' ) );
 435      }
 436      if ( !in_array( trim( $plugin ), array_keys( bb_get_plugins( $location, $type ) ) ) ) {
 437          return new WP_Error( 'plugin_not_available', __( 'That type of plugin is not available in the specified location.' ) );
 438      }
 439  
 440      return $path;
 441  }


Generated: Thu Dec 7 01:01:35 2017 Cross-referenced by PHPXref 0.7.1