aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/includes/extension/manager.php
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB/includes/extension/manager.php')
-rw-r--r--phpBB/includes/extension/manager.php98
1 files changed, 94 insertions, 4 deletions
diff --git a/phpBB/includes/extension/manager.php b/phpBB/includes/extension/manager.php
index 67cc81e407..44a30c6280 100644
--- a/phpBB/includes/extension/manager.php
+++ b/phpBB/includes/extension/manager.php
@@ -15,6 +15,8 @@ if (!defined('IN_PHPBB'))
exit;
}
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
/**
* The extension manager provides means to activate/deactivate extensions.
*
@@ -22,8 +24,12 @@ if (!defined('IN_PHPBB'))
*/
class phpbb_extension_manager
{
+ /** @var ContainerInterface */
+ protected $container;
+
protected $db;
protected $config;
+ protected $migrator;
protected $cache;
protected $php_ext;
protected $extensions;
@@ -34,19 +40,23 @@ class phpbb_extension_manager
/**
* Creates a manager and loads information from database
*
+ * @param ContainerInterface $container A container
* @param phpbb_db_driver $db A database connection
* @param phpbb_config $config phpbb_config
+ * @param phpbb_db_migrator $migrator
* @param string $extension_table The name of the table holding extensions
* @param string $phpbb_root_path Path to the phpbb includes directory.
* @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(phpbb_db_driver $db, phpbb_config $config, $extension_table, $phpbb_root_path, $php_ext = '.php', phpbb_cache_driver_interface $cache = null, $cache_name = '_ext')
+ public function __construct(ContainerInterface $container, phpbb_db_driver $db, phpbb_config $config, phpbb_db_migrator $migrator, $extension_table, $phpbb_root_path, $php_ext = '.php', phpbb_cache_driver_interface $cache = null, $cache_name = '_ext')
{
+ $this->container = $container;
$this->phpbb_root_path = $phpbb_root_path;
$this->db = $db;
$this->config = $config;
+ $this->migrator = $migrator;
$this->cache = $cache;
$this->php_ext = $php_ext;
$this->extension_table = $extension_table;
@@ -126,11 +136,11 @@ class phpbb_extension_manager
if (class_exists($extension_class_name))
{
- return new $extension_class_name;
+ return new $extension_class_name($this->container);
}
else
{
- return new phpbb_extension_base;
+ return new phpbb_extension_base($this->container);
}
}
@@ -166,6 +176,12 @@ class phpbb_extension_manager
$old_state = (isset($this->extensions[$name]['ext_state'])) ? unserialize($this->extensions[$name]['ext_state']) : false;
+ // Returns false if not completed
+ if (!$this->handle_migrations($name, 'enable'))
+ {
+ return true;
+ }
+
$extension = $this->get_extension($name);
$state = $extension->enable_step($old_state);
@@ -317,6 +333,12 @@ class phpbb_extension_manager
$old_state = unserialize($this->extensions[$name]['ext_state']);
+ // Returns false if not completed
+ if (!$this->handle_migrations($name, 'purge'))
+ {
+ return true;
+ }
+
$extension = $this->get_extension($name);
$state = $extension->purge_step($old_state);
@@ -384,7 +406,7 @@ class phpbb_extension_manager
}
$iterator = new RecursiveIteratorIterator(
- new RecursiveDirectoryIterator($this->phpbb_root_path . 'ext/'),
+ new RecursiveDirectoryIterator($this->phpbb_root_path . 'ext/', FilesystemIterator::NEW_CURRENT_AND_KEY | FilesystemIterator::FOLLOW_SYMLINKS),
RecursiveIteratorIterator::SELF_FIRST);
foreach ($iterator as $file_info)
{
@@ -490,4 +512,72 @@ class phpbb_extension_manager
{
return new phpbb_extension_finder($this, $this->phpbb_root_path, $this->cache, $this->php_ext, $this->cache_name . '_finder');
}
+
+ /**
+ * Handle installing/reverting migrations
+ *
+ * @param string $extension_name Name of the extension
+ * @param string $mode enable or purge
+ * @return bool True if completed, False if not completed
+ */
+ protected function handle_migrations($extension_name, $mode)
+ {
+ $extensions = array(
+ $extension_name => $this->phpbb_root_path . $this->get_extension_path($extension_name),
+ );
+
+ $finder = $this->get_finder();
+ $migrations = array();
+ $file_list = $finder
+ ->extension_directory('/migrations')
+ ->find_from_paths($extensions);
+
+ if (empty($file_list))
+ {
+ return true;
+ }
+
+ foreach ($file_list as $file)
+ {
+ $migrations[$file['named_path']] = $file['ext_name'];
+ }
+ $migrations = $finder->get_classes_from_files($migrations);
+ $this->migrator->set_migrations($migrations);
+
+ // What is a safe limit of execution time? Half the max execution time should be safe.
+ $safe_time_limit = (ini_get('max_execution_time') / 2);
+ $start_time = time();
+
+ if ($mode == 'enable')
+ {
+ while (!$this->migrator->finished())
+ {
+ $this->migrator->update();
+
+ // Are we approaching the time limit? If so we want to pause the update and continue after refreshing
+ if ((time() - $start_time) >= $safe_time_limit)
+ {
+ return false;
+ }
+ }
+ }
+ else if ($mode == 'purge')
+ {
+ foreach ($migrations as $migration)
+ {
+ while ($this->migrator->migration_state($migration) !== false)
+ {
+ $this->migrator->revert($migration);
+
+ // Are we approaching the time limit? If so we want to pause the update and continue after refreshing
+ if ((time() - $start_time) >= $safe_time_limit)
+ {
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+ }
}