aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/phpbb/extension/metadata_manager.php
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB/phpbb/extension/metadata_manager.php')
-rw-r--r--phpBB/phpbb/extension/metadata_manager.php373
1 files changed, 373 insertions, 0 deletions
diff --git a/phpBB/phpbb/extension/metadata_manager.php b/phpBB/phpbb/extension/metadata_manager.php
new file mode 100644
index 0000000000..a77f3a2c6e
--- /dev/null
+++ b/phpBB/phpbb/extension/metadata_manager.php
@@ -0,0 +1,373 @@
+<?php
+/**
+*
+* @package extension
+* @copyright (c) 2012 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+namespace phpbb\extension;
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+/**
+* The extension metadata manager validates and gets meta-data for extensions
+*
+* @package extension
+*/
+class metadata_manager
+{
+ /**
+ * phpBB Config instance
+ * @var \phpbb\config\config
+ */
+ protected $config;
+
+ /**
+ * phpBB Extension Manager
+ * @var \phpbb\extension\manager
+ */
+ protected $extension_manager;
+
+ /**
+ * phpBB Template instance
+ * @var \phpbb\template\template
+ */
+ protected $template;
+
+ /**
+ * phpBB root path
+ * @var string
+ */
+ protected $phpbb_root_path;
+
+ /**
+ * Name (including vendor) of the extension
+ * @var string
+ */
+ protected $ext_name;
+
+ /**
+ * Metadata from the composer.json file
+ * @var array
+ */
+ protected $metadata;
+
+ /**
+ * Link (including root path) to the metadata file
+ * @var string
+ */
+ protected $metadata_file;
+
+ /**
+ * Creates the metadata manager
+ *
+ * @param string $ext_name Name (including vendor) of the extension
+ * @param \phpbb\config\config $config phpBB Config instance
+ * @param \phpbb\extension\manager $extension_manager An instance of the phpBBb extension manager
+ * @param \phpbb\template\template $template phpBB Template instance
+ * @param string $phpbb_root_path Path to the phpbb includes directory.
+ */
+ public function __construct($ext_name, \phpbb\config\config $config, \phpbb\extension\manager $extension_manager, \phpbb\template\template $template, $phpbb_root_path)
+ {
+ $this->config = $config;
+ $this->extension_manager = $extension_manager;
+ $this->template = $template;
+ $this->phpbb_root_path = $phpbb_root_path;
+
+ $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']) : '',
+ ));
+ }
+ }
+}