aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/includes
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB/includes')
-rw-r--r--phpBB/includes/extension/base.php22
-rw-r--r--phpBB/includes/extension/interface.php39
-rw-r--r--phpBB/includes/extension/manager.php85
3 files changed, 128 insertions, 18 deletions
diff --git a/phpBB/includes/extension/base.php b/phpBB/includes/extension/base.php
index 0e6c89491d..8228364d44 100644
--- a/phpBB/includes/extension/base.php
+++ b/phpBB/includes/extension/base.php
@@ -16,20 +16,38 @@ if (!defined('IN_PHPBB'))
}
/**
+* A base class for extensions without custom enable/disbale/purge code.
*
* @package extension
*/
class phpbb_extension_base implements phpbb_extension_interface
{
- public function enable()
+ /**
+ * Single enable step that does nothing
+ *
+ * @return false Indicates no further steps are required
+ */
+ public function enable_step($old_state)
{
+ return false;
}
+ /**
+ * Empty disable method
+ *
+ * @return null
+ */
public function disable()
{
}
- public function purge()
+ /**
+ * Single purge step that does nothing
+ *
+ * @return false Indicates no further steps are required
+ */
+ public function purge_step($old_state)
{
+ return false;
}
}
diff --git a/phpBB/includes/extension/interface.php b/phpBB/includes/extension/interface.php
index 40a5a066a3..7d0ecd72c7 100644
--- a/phpBB/includes/extension/interface.php
+++ b/phpBB/includes/extension/interface.php
@@ -16,12 +16,47 @@ if (!defined('IN_PHPBB'))
}
/**
+* The interface extension meta classes have to implement to run custom code
+* on enable/disable/purge.
*
* @package extension
*/
interface phpbb_extension_interface
{
- public function enable();
+ /**
+ * enable_step is executed on enabling an extension until it returns false.
+ *
+ * Calls to this function can be made in subsequent requests, when the
+ * function is invoked through a webserver with a too low max_execution_time.
+ *
+ * @param mixed $old_state The return value of the previous call
+ * of this method, or false on the first call
+ * @return mixed Returns false after last step, otherwise
+ * temporary state which is passed as an
+ * argument to the next step
+ */
+ public function enable_step($old_state);
+
+ /**
+ * Disables the extension.
+ *
+ * Must be a quick operation, that finishes within max_execution_time.
+ *
+ * @return null
+ */
public function disable();
- public function purge();
+
+ /**
+ * purge_step is executed on purging an extension until it returns false.
+ *
+ * Calls to this function can be made in subsequent requests, when the
+ * function is invoked through a webserver with a too low max_execution_time.
+ *
+ * @param mixed $old_state The return value of the previous call
+ * of this method, or false on the first call
+ * @return mixed Returns false after last step, otherwise
+ * temporary state which is passed as an
+ * argument to the next step
+ */
+ public function purge_step($old_state);
}
diff --git a/phpBB/includes/extension/manager.php b/phpBB/includes/extension/manager.php
index d167bc6847..a1863040d0 100644
--- a/phpBB/includes/extension/manager.php
+++ b/phpBB/includes/extension/manager.php
@@ -109,28 +109,34 @@ class phpbb_extension_manager
}
/**
- * Enables an extension
+ * Runs a step of the extension enabling process.
*
- * Calls the enable method on the extension's meta class to allow it to
- * make database changes and execute other initialisation code.
+ * Allows the exentension to enable in a long running script that works
+ * in multiple steps across requests. State is kept for the extension
+ * in the extensions table.
*
- * @param string $name The extension's name
- * @return null
+ * @param string $name The extension's name
+ * @return bool Whether another run of enable_step is required
*/
- public function enable($name)
+ public function enable_step($name)
{
// ignore extensions that are already enabled
if (isset($this->extensions[$name]) && $this->extensions[$name]['ext_active'])
{
- return;
+ return false;
}
+ $old_state = (isset($this->extensions[$name]['ext_state'])) ? unserialize($this->extensions[$name]['ext_state']) : false;
+
$extension = $this->get_extension($name);
- $extension->enable();
+ $state = $extension->enable_step($old_state);
+
+ $active = ($state === false);
$extension_data = array(
- 'ext_name' => $name,
- 'ext_active' => true,
+ 'ext_name' => $name,
+ 'ext_active' => $active,
+ 'ext_state' => serialize($state),
);
$this->extensions[$name] = $extension_data;
@@ -148,6 +154,22 @@ class phpbb_extension_manager
' . $this->db->sql_build_array('INSERT', $extension_data);
$this->db->sql_query($sql);
}
+
+ return !$active;
+ }
+
+ /**
+ * Enables an extension
+ *
+ * This method completely enables an extension. But it could be long running
+ * so never call this in a script that has a max_execution time.
+ *
+ * @param string $name The extension's name
+ * @return null
+ */
+ public function enable($name)
+ {
+ while ($this->enable_step($name));
}
/**
@@ -172,9 +194,10 @@ class phpbb_extension_manager
$extension_data = array(
'ext_active' => false,
+ 'ext_state' => serialize(false),
);
$this->extensions[$name]['ext_active'] = false;
- ksort($this->extensions);
+ $this->extensions[$name]['ext_state'] = serialize(false);
$sql = 'UPDATE ' . $this->extension_table . '
SET ' . $this->db->sql_build_array('UPDATE', $extension_data) . "
@@ -191,12 +214,12 @@ class phpbb_extension_manager
* @param string $name The extension's name
* @return null
*/
- public function purge($name)
+ public function purge_step($name)
{
// ignore extensions that do not exist
if (!isset($this->extensions[$name]))
{
- return;
+ return false;
}
// disable first if necessary
@@ -205,14 +228,48 @@ class phpbb_extension_manager
$this->disable($name);
}
+ $old_state = unserialize($this->extensions[$name]['ext_state']);
+
$extension = $this->get_extension($name);
- $extension->purge();
+ $state = $extension->purge_step($old_state);
+
+ // continue until the state is false
+ if ($state !== false)
+ {
+ $extension_data = array(
+ 'ext_state' => serialize($state),
+ );
+ $this->extensions[$name]['ext_state'] = serialize($state);
+
+ $sql = 'UPDATE ' . $this->extension_table . '
+ SET ' . $this->db->sql_build_array('UPDATE', $extension_data) . "
+ WHERE ext_name = '" . $this->db->sql_escape($name) . "'";
+ $this->db->sql_query($sql);
+
+ return true;
+ }
unset($this->extensions[$name]);
$sql = 'DELETE FROM ' . $this->extension_table . "
WHERE ext_name = '" . $this->db->sql_escape($name) . "'";
$this->db->sql_query($sql);
+
+ return false;
+ }
+
+ /**
+ * Purge an extension
+ *
+ * Purges an extension completely at once. This process could run for a while
+ * so never call this in a script that has a max_execution time.
+ *
+ * @param string $name The extension's name
+ * @return null
+ */
+ public function purge($name)
+ {
+ while ($this->purge_step($name));
}
/**