aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/includes/extension
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB/includes/extension')
-rw-r--r--phpBB/includes/extension/controller.php77
-rw-r--r--phpBB/includes/extension/controller_interface.php31
-rw-r--r--phpBB/includes/extension/exception.php27
-rw-r--r--phpBB/includes/extension/finder.php14
-rw-r--r--phpBB/includes/extension/manager.php52
-rw-r--r--phpBB/includes/extension/metadata_manager.php338
-rw-r--r--phpBB/includes/extension/provider.php12
7 files changed, 421 insertions, 130 deletions
diff --git a/phpBB/includes/extension/controller.php b/phpBB/includes/extension/controller.php
deleted file mode 100644
index c7fd439a19..0000000000
--- a/phpBB/includes/extension/controller.php
+++ /dev/null
@@ -1,77 +0,0 @@
-<?php
-/**
-*
-* @package extension
-* @copyright (c) 2011 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
-*
-*/
-
-/**
-* @ignore
-*/
-if (!defined('IN_PHPBB'))
-{
- exit;
-}
-
-/**
-* Abstract class extended by extension front controller classes
-*
-* @package extension
-*/
-abstract class phpbb_extension_controller implements phpbb_extension_controller_interface
-{
- /**
- * @var phpbb_request Request class object
- */
- protected $request;
-
- /**
- * @var dbal DBAL class object
- */
- protected $db;
-
- /**
- * @var user User class object
- */
- protected $user;
-
- /**
- * @var phpbb_template Template class object
- */
- protected $template;
-
- /**
- * @var array Config array
- */
- protected $config;
-
- /**
- * @var string PHP Extension
- */
- protected $phpEx;
-
- /**
- * @var string Relative path to board root
- */
- protected $phpbb_root_path;
-
- /**
- * Constructor method that provides the common phpBB objects as inherited class
- * properties for automatic availability in extension controllers
- */
- public function __construct()
- {
- global $request, $db, $user, $template, $config;
- global $phpEx, $phpbb_root_path;
-
- $this->request = $request;
- $this->db = $db;
- $this->user = $user;
- $this->template = $template;
- $this->config = $config;
- $this->phpEx = $phpEx;
- $this->phpbb_root_path = $phpbb_root_path;
- }
-}
diff --git a/phpBB/includes/extension/controller_interface.php b/phpBB/includes/extension/controller_interface.php
deleted file mode 100644
index 2b88925388..0000000000
--- a/phpBB/includes/extension/controller_interface.php
+++ /dev/null
@@ -1,31 +0,0 @@
-<?php
-/**
-*
-* @package extension
-* @copyright (c) 2011 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
-*
-*/
-
-/**
-* @ignore
-*/
-if (!defined('IN_PHPBB'))
-{
- exit;
-}
-
-/**
-* The interface that extension classes have to implement to run front pages
-*
-* @package extension
-*/
-interface phpbb_extension_controller_interface
-{
- /**
- * Handle the request to display a page from an extension
- *
- * @return null
- */
- public function handle();
-}
diff --git a/phpBB/includes/extension/exception.php b/phpBB/includes/extension/exception.php
new file mode 100644
index 0000000000..e08a8912ea
--- /dev/null
+++ b/phpBB/includes/extension/exception.php
@@ -0,0 +1,27 @@
+<?php
+/**
+*
+* @package extension
+* @copyright (c) 2012 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+/**
+ * Exception class for metadata
+ */
+class phpbb_extension_exception extends UnexpectedValueException
+{
+ public function __toString()
+ {
+ return $this->getMessage();
+ }
+} \ No newline at end of file
diff --git a/phpBB/includes/extension/finder.php b/phpBB/includes/extension/finder.php
index 87ca40917d..fb19b98429 100644
--- a/phpBB/includes/extension/finder.php
+++ b/phpBB/includes/extension/finder.php
@@ -25,7 +25,7 @@ class phpbb_extension_finder
protected $extension_manager;
protected $phpbb_root_path;
protected $cache;
- protected $phpEx;
+ protected $php_ext;
/**
* The cache variable name used to store $this->cached_queries in $this->cache.
@@ -56,16 +56,16 @@ class phpbb_extension_finder
* extensions and their locations
* @param string $phpbb_root_path Path to the phpbb root directory
* @param phpbb_cache_driver_interface $cache A cache instance or null
- * @param string $phpEx php file extension
+ * @param string $php_ext php file extension
* @param string $cache_name The name of the cache variable, defaults to
* _ext_finder
*/
- public function __construct(phpbb_extension_manager $extension_manager, $phpbb_root_path = '', phpbb_cache_driver_interface $cache = null, $phpEx = '.php', $cache_name = '_ext_finder')
+ public function __construct(phpbb_extension_manager $extension_manager, $phpbb_root_path = '', phpbb_cache_driver_interface $cache = null, $php_ext = '.php', $cache_name = '_ext_finder')
{
$this->extension_manager = $extension_manager;
$this->phpbb_root_path = $phpbb_root_path;
$this->cache = $cache;
- $this->phpEx = $phpEx;
+ $this->php_ext = $php_ext;
$this->cache_name = $cache_name;
$this->query = array(
@@ -251,8 +251,8 @@ class phpbb_extension_finder
*/
public function get_classes($cache = true)
{
- $this->query['extension_suffix'] .= $this->phpEx;
- $this->query['core_suffix'] .= $this->phpEx;
+ $this->query['extension_suffix'] .= $this->php_ext;
+ $this->query['core_suffix'] .= $this->php_ext;
$files = $this->find($cache, false);
@@ -261,7 +261,7 @@ class phpbb_extension_finder
{
$file = preg_replace('#^includes/#', '', $file);
- $classes[] = 'phpbb_' . str_replace('/', '_', substr($file, 0, -strlen($this->phpEx)));
+ $classes[] = 'phpbb_' . str_replace('/', '_', substr($file, 0, -strlen($this->php_ext)));
}
return $classes;
}
diff --git a/phpBB/includes/extension/manager.php b/phpBB/includes/extension/manager.php
index 537c19aff8..bfd4edde93 100644
--- a/phpBB/includes/extension/manager.php
+++ b/phpBB/includes/extension/manager.php
@@ -22,8 +22,10 @@ if (!defined('IN_PHPBB'))
*/
class phpbb_extension_manager
{
+ protected $db;
+ protected $config;
protected $cache;
- protected $phpEx;
+ protected $php_ext;
protected $extensions;
protected $extension_table;
protected $phpbb_root_path;
@@ -33,18 +35,20 @@ class phpbb_extension_manager
* Creates a manager and loads information from database
*
* @param dbal $db A database connection
+ * @param phpbb_config $config phpbb_config
* @param string $extension_table The name of the table holding extensions
* @param string $phpbb_root_path Path to the phpbb includes directory.
- * @param string $phpEx php file extension
+ * @param string $php_ext php file extension
* @param phpbb_cache_driver_interface $cache A cache instance or null
* @param string $cache_name The name of the cache variable, defaults to _ext
*/
- public function __construct(dbal $db, $extension_table, $phpbb_root_path, $phpEx = '.php', phpbb_cache_driver_interface $cache = null, $cache_name = '_ext')
+ public function __construct(dbal $db, phpbb_config $config, $extension_table, $phpbb_root_path, $php_ext = '.php', phpbb_cache_driver_interface $cache = null, $cache_name = '_ext')
{
$this->phpbb_root_path = $phpbb_root_path;
$this->db = $db;
+ $this->config = $config;
$this->cache = $cache;
- $this->phpEx = $phpEx;
+ $this->php_ext = $php_ext;
$this->extension_table = $extension_table;
$this->cache_name = $cache_name;
@@ -63,6 +67,17 @@ class phpbb_extension_manager
*/
public function load_extensions()
{
+ $this->extensions = array();
+
+ // Do not try to load any extensions when installing or updating
+ // Note: database updater invokes this code, and in 3.0
+ // there is no extension table therefore the rest of this function
+ // fails
+ if (defined('IN_INSTALL'))
+ {
+ return;
+ }
+
$sql = 'SELECT *
FROM ' . $this->extension_table;
@@ -70,7 +85,6 @@ class phpbb_extension_manager
$extensions = $this->db->sql_fetchrowset($result);
$this->db->sql_freeresult($result);
- $this->extensions = array();
foreach ($extensions as $extension)
{
$extension['ext_path'] = $this->get_extension_path($extension['ext_name']);
@@ -121,6 +135,18 @@ class phpbb_extension_manager
}
/**
+ * Instantiates the metadata manager for the extension with the given name
+ *
+ * @param string $name The extension name
+ * @param string $template The template manager
+ * @return phpbb_extension_metadata_manager Instance of the metadata manager
+ */
+ public function create_extension_metadata_manager($name, phpbb_template $template)
+ {
+ return new phpbb_extension_metadata_manager($name, $this->db, $this, $this->phpbb_root_path, $this->php_ext, $template, $this->config);
+ }
+
+ /**
* Runs a step of the extension enabling process.
*
* Allows the exentension to enable in a long running script that works
@@ -169,7 +195,7 @@ class phpbb_extension_manager
if ($this->cache)
{
- $this->cache->destroy($this->cache_name);
+ $this->cache->purge();
}
return !$active;
@@ -226,7 +252,7 @@ class phpbb_extension_manager
if ($this->cache)
{
- $this->cache->destroy($this->cache_name);
+ $this->cache->purge();
}
return true;
@@ -246,7 +272,7 @@ class phpbb_extension_manager
if ($this->cache)
{
- $this->cache->destroy($this->cache_name);
+ $this->cache->purge();
}
return false;
@@ -309,7 +335,7 @@ class phpbb_extension_manager
if ($this->cache)
{
- $this->cache->destroy($this->cache_name);
+ $this->cache->purge();
}
return true;
@@ -323,7 +349,7 @@ class phpbb_extension_manager
if ($this->cache)
{
- $this->cache->destroy($this->cache_name);
+ $this->cache->purge();
}
return false;
@@ -362,7 +388,7 @@ class phpbb_extension_manager
RecursiveIteratorIterator::SELF_FIRST);
foreach ($iterator as $file_info)
{
- if ($file_info->isFile() && $file_info->getFilename() == 'ext' . $this->phpEx)
+ if ($file_info->isFile() && $file_info->getFilename() == 'ext' . $this->php_ext)
{
$ext_name = $iterator->getInnerIterator()->getSubPath();
@@ -432,7 +458,7 @@ class phpbb_extension_manager
}
return $disabled;
}
-
+
/**
* Check to see if a given extension is available on the filesystem
*
@@ -462,6 +488,6 @@ class phpbb_extension_manager
*/
public function get_finder()
{
- return new phpbb_extension_finder($this, $this->phpbb_root_path, $this->cache, $this->phpEx, $this->cache_name . '_finder');
+ return new phpbb_extension_finder($this, $this->phpbb_root_path, $this->cache, $this->php_ext, $this->cache_name . '_finder');
}
}
diff --git a/phpBB/includes/extension/metadata_manager.php b/phpBB/includes/extension/metadata_manager.php
new file mode 100644
index 0000000000..ea85bd3c4e
--- /dev/null
+++ b/phpBB/includes/extension/metadata_manager.php
@@ -0,0 +1,338 @@
+<?php
+/**
+*
+* @package extension
+* @copyright (c) 2012 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+/**
+* The extension metadata manager validates and gets meta-data for extensions
+*
+* @package extension
+*/
+class phpbb_extension_metadata_manager
+{
+ protected $phpEx;
+ protected $extension_manager;
+ protected $db;
+ protected $phpbb_root_path;
+ protected $template;
+ protected $ext_name;
+ protected $metadata;
+ protected $metadata_file;
+
+ /**
+ * Creates the metadata manager
+ *
+ * @param dbal $db A database connection
+ * @param string $extension_manager An instance of the phpbb extension manager
+ * @param string $phpbb_root_path Path to the phpbb includes directory.
+ * @param string $phpEx php file extension
+ */
+ public function __construct($ext_name, dbal $db, phpbb_extension_manager $extension_manager, $phpbb_root_path, $phpEx = '.php', phpbb_template $template, phpbb_config $config)
+ {
+ $this->phpbb_root_path = $phpbb_root_path;
+ $this->db = $db;
+ $this->config = $config;
+ $this->phpEx = $phpEx;
+ $this->template = $template;
+ $this->extension_manager = $extension_manager;
+ $this->ext_name = $ext_name;
+ $this->metadata = array();
+ $this->metadata_file = '';
+ }
+
+ /**
+ * Processes and gets the metadata requested
+ *
+ * @param string $element All for all metadata that it has and is valid, otherwise specify which section you want by its shorthand term.
+ * @return array Contains all of the requested metadata, throws an exception on failure
+ */
+ public function get_metadata($element = 'all')
+ {
+ $this->set_metadata_file();
+
+ // Fetch the metadata
+ $this->fetch_metadata();
+
+ // Clean the metadata
+ $this->clean_metadata_array();
+
+ switch ($element)
+ {
+ case 'all':
+ default:
+ // Validate the metadata
+ if (!$this->validate())
+ {
+ return false;
+ }
+
+ return $this->metadata;
+ break;
+
+ case 'name':
+ return ($this->validate('name')) ? $this->metadata['name'] : false;
+ break;
+
+ case 'display-name':
+ if (isset($this->metadata['extra']['display-name']))
+ {
+ return $this->metadata['extra']['display-name'];
+ }
+ else
+ {
+ return ($this->validate('name')) ? $this->metadata['name'] : false;
+ }
+ break;
+ }
+ }
+
+ /**
+ * Sets the filepath of the metadata file
+ *
+ * @return boolean Set to true if it exists, throws an exception on failure
+ */
+ private function set_metadata_file()
+ {
+ $ext_filepath = $this->extension_manager->get_extension_path($this->ext_name);
+ $metadata_filepath = $this->phpbb_root_path . $ext_filepath . 'composer.json';
+
+ $this->metadata_file = $metadata_filepath;
+
+ if (!file_exists($this->metadata_file))
+ {
+ throw new phpbb_extension_exception('The required file does not exist: ' . $this->metadata_file);
+ }
+ }
+
+ /**
+ * Gets the contents of the composer.json file
+ *
+ * @return bool True if success, throws an exception on failure
+ */
+ private function fetch_metadata()
+ {
+ if (!file_exists($this->metadata_file))
+ {
+ throw new phpbb_extension_exception('The required file does not exist: ' . $this->metadata_file);
+ }
+ else
+ {
+ if (!($file_contents = file_get_contents($this->metadata_file)))
+ {
+ throw new phpbb_extension_exception('file_get_contents failed on ' . $this->metadata_file);
+ }
+
+ if (($metadata = json_decode($file_contents, true)) === NULL)
+ {
+ throw new phpbb_extension_exception('json_decode failed on ' . $this->metadata_file);
+ }
+
+ $this->metadata = $metadata;
+
+ return true;
+ }
+ }
+
+ /**
+ * This array handles the cleaning of the array
+ *
+ * @return array Contains the cleaned metadata array
+ */
+ private function clean_metadata_array()
+ {
+ return $this->metadata;
+ }
+
+ /**
+ * Validate fields
+ *
+ * @param string $name ("all" for display and enable validation
+ * "display" for name, type, and authors
+ * "name", "type")
+ * @return Bool True if valid, throws an exception if invalid
+ */
+ public function validate($name = 'display')
+ {
+ // Basic fields
+ $fields = array(
+ 'name' => '#^[a-zA-Z0-9_\x7f-\xff]{2,}/[a-zA-Z0-9_\x7f-\xff]{2,}$#',
+ 'type' => '#^phpbb3-extension$#',
+ 'licence' => '#.+#',
+ 'version' => '#.+#',
+ );
+
+ switch ($name)
+ {
+ case 'all':
+ $this->validate('display');
+
+ $this->validate_enable();
+ break;
+
+ case 'display':
+ foreach ($fields as $field => $data)
+ {
+ $this->validate($field);
+ }
+
+ $this->validate_authors();
+ break;
+
+ default:
+ if (isset($fields[$name]))
+ {
+ if (!isset($this->metadata[$name]))
+ {
+ throw new phpbb_extension_exception("Required meta field '$name' has not been set.");
+ }
+
+ if (!preg_match($fields[$name], $this->metadata[$name]))
+ {
+ throw new phpbb_extension_exception("Meta field '$name' is invalid.");
+ }
+ }
+ break;
+ }
+
+ return true;
+ }
+
+ /**
+ * Validates the contents of the authors field
+ *
+ * @return boolean True when passes validation, throws exception if invalid
+ */
+ public function validate_authors()
+ {
+ if (empty($this->metadata['authors']))
+ {
+ throw new phpbb_extension_exception("Required meta field 'authors' has not been set.");
+ }
+
+ foreach ($this->metadata['authors'] as $author)
+ {
+ if (!isset($author['name']))
+ {
+ throw new phpbb_extension_exception("Required meta field 'author name' has not been set.");
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * This array handles the verification that this extension can be enabled on this board
+ *
+ * @return bool True if validation succeeded, False if failed
+ */
+ public function validate_enable()
+ {
+ // Check for phpBB, PHP versions
+ if (!$this->validate_require_phpbb() || !$this->validate_require_php())
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+
+ /**
+ * Validates the contents of the phpbb requirement field
+ *
+ * @return boolean True when passes validation
+ */
+ public function validate_require_phpbb()
+ {
+ if (!isset($this->metadata['require']['phpbb']))
+ {
+ return true;
+ }
+
+ return $this->_validate_version($this->metadata['require']['phpbb'], $this->config['version']);
+ }
+
+ /**
+ * Validates the contents of the php requirement field
+ *
+ * @return boolean True when passes validation
+ */
+ public function validate_require_php()
+ {
+ if (!isset($this->metadata['require']['php']))
+ {
+ return true;
+ }
+
+ return $this->_validate_version($this->metadata['require']['php'], phpversion());
+ }
+
+ /**
+ * Version validation helper
+ *
+ * @param string $string The string for comparing to a version
+ * @param string $current_version The version to compare to
+ * @return bool True/False if meets version requirements
+ */
+ private function _validate_version($string, $current_version)
+ {
+ // Allow them to specify their own comparison operator (ex: <3.1.2, >=3.1.0)
+ $comparison_matches = false;
+ preg_match('#[=<>]+#', $string, $comparison_matches);
+
+ if (!empty($comparison_matches))
+ {
+ return version_compare($current_version, str_replace(array($comparison_matches[0], ' '), '', $string), $comparison_matches[0]);
+ }
+
+ return version_compare($current_version, $string, '>=');
+ }
+
+ /**
+ * Outputs the metadata into the template
+ *
+ * @return null
+ */
+ public function output_template_data()
+ {
+ $this->template->assign_vars(array(
+ 'META_NAME' => htmlspecialchars($this->metadata['name']),
+ 'META_TYPE' => htmlspecialchars($this->metadata['type']),
+ 'META_DESCRIPTION' => (isset($this->metadata['description'])) ? htmlspecialchars($this->metadata['description']) : '',
+ 'META_HOMEPAGE' => (isset($this->metadata['homepage'])) ? $this->metadata['homepage'] : '',
+ 'META_VERSION' => (isset($this->metadata['version'])) ? htmlspecialchars($this->metadata['version']) : '',
+ 'META_TIME' => (isset($this->metadata['time'])) ? htmlspecialchars($this->metadata['time']) : '',
+ 'META_LICENCE' => htmlspecialchars($this->metadata['licence']),
+
+ 'META_REQUIRE_PHP' => (isset($this->metadata['require']['php'])) ? htmlspecialchars($this->metadata['require']['php']) : '',
+ 'META_REQUIRE_PHP_FAIL' => !$this->validate_require_php(),
+
+ 'META_REQUIRE_PHPBB' => (isset($this->metadata['require']['phpbb'])) ? htmlspecialchars($this->metadata['require']['phpbb']) : '',
+ 'META_REQUIRE_PHPBB_FAIL' => !$this->validate_require_phpbb(),
+
+ 'META_DISPLAY_NAME' => (isset($this->metadata['extra']['display-name'])) ? htmlspecialchars($this->metadata['extra']['display-name']) : '',
+ ));
+
+ foreach ($this->metadata['authors'] as $author)
+ {
+ $this->template->assign_block_vars('meta_authors', array(
+ 'AUTHOR_NAME' => htmlspecialchars($author['name']),
+ 'AUTHOR_EMAIL' => (isset($author['email'])) ? $author['email'] : '',
+ 'AUTHOR_HOMEPAGE' => (isset($author['homepage'])) ? $author['homepage'] : '',
+ 'AUTHOR_ROLE' => (isset($author['role'])) ? htmlspecialchars($author['role']) : '',
+ ));
+ }
+ }
+}
diff --git a/phpBB/includes/extension/provider.php b/phpBB/includes/extension/provider.php
index d0541fa007..45b55e5cab 100644
--- a/phpBB/includes/extension/provider.php
+++ b/phpBB/includes/extension/provider.php
@@ -16,7 +16,15 @@ if (!defined('IN_PHPBB'))
}
/**
-* Provides a set of items found in extensions
+* Provides a set of items found in extensions.
+*
+* This abstract class is essentially a wrapper around item-specific
+* finding logic. It handles storing the extension manager via constructor
+* for the finding logic to use to find the items, and provides an
+* iterator interface over the items found by the finding logic.
+*
+* Items could be anything, for example template paths or cron task names.
+* Derived classes completely define what the items are.
*
* @package extension
*/
@@ -45,7 +53,7 @@ abstract class phpbb_extension_provider implements IteratorAggregate
}
/**
- * Finds template paths using the extension manager.
+ * Finds items using the extension manager.
*
* @return array List of task names
*/