function bb_get_theme_data($theme_file) { if (strpos($theme_file, '#') !== false) { $theme_file = bb_get_theme_directory($theme_file) . 'style.css'; } $theme_code = implode('', file($theme_file)); $theme_code = str_replace('\\r', '\\n', $theme_code); // Grab just the first commented area from the file preg_match('|/\\*(.*)\\*/|msU', $theme_code, $theme_block); $theme_data = trim($theme_block[1]); preg_match('|Theme Name:(.*)|i', $theme_data, $theme_name); preg_match('|Theme URI:(.*)|i', $theme_data, $theme_uri); preg_match('|Description:(.*)|i', $theme_data, $description); preg_match('|Author:(.*)|i', $theme_data, $author_name); preg_match('|Author URI:(.*)|i', $theme_data, $author_uri); preg_match('|Ported By:(.*)|i', $theme_data, $porter_name); preg_match('|Porter URI:(.*)|i', $theme_data, $porter_uri); // preg_match( '|Template:(.*)|i', $theme_data, $template ); if (preg_match('|Version:(.*)|i', $theme_data, $version)) { $version = esc_html(trim($version[1])); } else { $version = ''; } if (preg_match('|Status:(.*)|i', $theme_data, $status)) { $status = esc_html(trim($status[1])); } else { $status = 'publish'; } $description = trim($description[1]); $description = bb_encode_bad($description); $description = bb_code_trick($description); $description = force_balance_tags($description); $description = bb_filter_kses($description); $description = bb_autop($description); $name = $theme_name[1]; $name = esc_html(trim($name)); $theme = $name; if ($author_name || $author_uri) { if (empty($author_uri[1])) { $author = bb_filter_kses(trim($author_name[1])); } else { $author = '<a href="' . esc_url(trim($author_uri[1])) . '" title="' . esc_attr__('Visit author homepage') . '">' . bb_filter_kses(trim($author_name[1])) . '</a>'; } } else { $author = ''; } if ($porter_name || $porter_uri) { if (empty($porter_uri[1])) { $porter = bb_filter_kses(trim($porter_name[1])); } else { $porter = '<a href="' . esc_url(trim($porter_uri[1])) . '" title="' . esc_attr__('Visit porter homepage') . '">' . bb_filter_kses(trim($porter_name[1])) . '</a>'; } } else { $porter = ''; } global $bb; // Normalise the path to the theme $theme_file = str_replace('\\', '/', $theme_file); foreach ($bb->theme_locations as $_name => $_data) { $_directory = str_replace('\\', '/', $_data['dir']); if (0 === strpos($theme_file, $_directory)) { $location = $_name; break; } } return array('Location' => $location, 'Name' => $name, 'Title' => $theme, 'Description' => $description, 'Author' => $author, 'Porter' => $porter, 'Version' => $version, 'Status' => $status, 'URI' => esc_url($theme_uri[1])); }
/** * Parse the plugin contents to retrieve plugin's metadata. * * The metadata of the plugin's data searches for the following in the plugin's * header. All plugin data must be on its own line. For plugin description, it * must not have any newlines or only parts of the description will be displayed * and the same goes for the plugin data. The below is formatted for printing. * * <code> * /* * Plugin Name: Name of Plugin * Plugin URI: Link to plugin information * Description: Plugin Description * Author: Plugin author's name * Author URI: Link to the author's web site * Version: Must be set * Requires at least: Optional. Minimum bbPress version this plugin requires * Tested up to: Optional. Maximum bbPress version this plugin has been tested with * Text Domain: Optional. Unique identifier, should be same as the one used in * bb_load_plugin_textdomain() * Domain Path: Optional. Only useful if the translations are located in a * folder above the plugin's base path. For example, if .mo files are * located in the locale folder then Domain Path will be "/locale/" and * must have the first slash. Defaults to the base folder the plugin is * located in. * * / # You must remove the space to close comment (the space is here only for documentation purposes). * </code> * * Plugin data returned array contains the following: * 'location' - Location of plugin file * 'name' - Name of the plugin, must be unique. * 'uri' - Plugin's web site. * 'plugin_link' - Title of plugin linked to plugin's web site. * 'description' - Description of what the plugin does and/or notes * from the author. * 'author' - The author's name * 'author_uri' - The author's web site address. * 'author_link' - The author's name linked to the author's web site. * 'version' - The plugin version number. * 'requires' - Minimum bbPress version plugin requires * 'tested' - Maximum bbPress version plugin has been tested with * 'text_domain' - Plugin's text domain for localization. * 'domain_path' - Plugin's relative directory path to .mo files. * * Some users have issues with opening large files and manipulating the contents * for want is usually the first 1kiB or 2kiB. This function stops pulling in * the plugin contents when it has all of the required plugin data. * * The first 8kiB of the file will be pulled in and if the plugin data is not * within that first 8kiB, then the plugin author should correct their plugin * and move the plugin data headers to the top. * * The plugin file is assumed to have permissions to allow for scripts to read * the file. This is not checked however and the file is only opened for * reading. * * @link http://trac.nxtclass.org/ticket/5651 Previous Optimizations. * @link http://trac.nxtclass.org/ticket/7372 Further and better Optimizations. * @since 1.5.0 * * @param string $plugin_file Path to the plugin file * @param bool $markup If the returned data should have HTML markup applied * @param bool $translate If the returned data should be translated * @return array See above for description. */ function bb_get_plugin_data($plugin_file, $markup = true, $translate = true) { global $bb; if (preg_match('/^([a-z0-9_-]+)#((?:[a-z0-9\\/\\_-]+.)+)(php)$/i', $plugin_file, $_matches)) { $plugin_file = $bb->plugin_locations[$_matches[1]]['dir'] . $_matches[2] . $_matches[3]; $_directory = $bb->plugin_locations[$_matches[1]]['dir']; $_plugin = $_matches[2] . $_matches[3]; if (!$_plugin) { // Not likely return false; } if (validate_file($_plugin)) { // $plugin has .., :, etc. return false; } $plugin_file = $_directory . $_plugin; unset($_matches, $_directory, $_plugin); } if (!file_exists($plugin_file)) { // The plugin isn't there return false; } // We don't need to write to the file, so just open for reading. $fp = fopen($plugin_file, 'r'); // Pull only the first 8kiB of the file in. $plugin_code = fread($fp, 8192); // PHP will close file handle, but we are good citizens. fclose($fp); // Grab just the first commented area from the file if (!preg_match('|/\\*(.*?Plugin Name:.*?)\\*/|ims', $plugin_code, $plugin_block)) { return false; } $plugin_data = trim($plugin_block[1]); preg_match('|Plugin Name:(.*)$|mi', $plugin_data, $name); preg_match('|Plugin URI:(.*)$|mi', $plugin_data, $uri); preg_match('|Version:(.*)|i', $plugin_data, $version); preg_match('|Description:(.*)$|mi', $plugin_data, $description); preg_match('|Author:(.*)$|mi', $plugin_data, $author); preg_match('|Author URI:(.*)$|mi', $plugin_data, $author_uri); preg_match('|Text Domain:(.*)$|mi', $plugin_data, $text_domain); preg_match('|Domain Path:(.*)$|mi', $plugin_data, $domain_path); preg_match('|Requires at least:(.*)$|mi', $plugin_data, $requires); preg_match('|Tested up to:(.*)$|mi', $plugin_data, $tested); // Normalise the path to the plugin $plugin_file = str_replace('\\', '/', $plugin_file); foreach ($bb->plugin_locations as $_name => $_data) { $_directory = str_replace('\\', '/', $_data['dir']); if (0 === strpos($plugin_file, $_directory)) { $location = array(1 => $_name); break; } } $plugins_allowedtags = array('a' => array('href' => array(), 'title' => array()), 'abbr' => array('title' => array()), 'acronym' => array('title' => array()), 'code' => array(), 'em' => array(), 'strong' => array()); $fields = array('location' => '', 'name' => 'html', 'uri' => 'url', 'version' => 'text', 'description' => 'html', 'author' => 'html', 'author_uri' => 'url', 'text_domain' => '', 'domain_path' => '', 'requires' => 'text', 'tested' => 'text'); foreach ($fields as $field => $san) { if (!empty(${$field})) { ${$field} = trim(${$field}[1]); switch ($san) { case 'html': ${$field} = bb_filter_kses(${$field}); break; case 'text': ${$field} = esc_html(${$field}); break; case 'url': ${$field} = esc_url(${$field}); break; } } else { ${$field} = ''; } } $plugin_data = compact(array_keys($fields)); if ($translate) { $plugin_data = _bb_get_plugin_data_translate($plugin_data, $plugin_file); } if ($markup) { $plugin_data['description'] = bb_autop(preg_replace('/[\\r\\n]+/', "\n", trim($plugin_data['description']))); } $plugin_data['plugin_link'] = $plugin_data['uri'] ? "<a href='{$plugin_data['uri']}' title='" . esc_attr__('Visit plugin site') . "'>{$plugin_data['name']}</a>" : $plugin_data['name']; $plugin_data['author_link'] = $plugin_data['author'] && $plugin_data['author_uri'] ? "<a href='{$plugin_data['author_uri']}' title='" . esc_attr__('Visit author homepage') . "'>{$plugin_data['author']}</a>" : $plugin_data['author']; return $plugin_data; }