aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/includes/cron/manager.php
diff options
context:
space:
mode:
authorIgor Wiedler <igor@wiedler.ch>2011-02-13 15:54:42 +0100
committerIgor Wiedler <igor@wiedler.ch>2011-02-13 15:54:42 +0100
commit04bd2e640e771948671ab6554df8962de980f511 (patch)
treed1e5a226ca875e940d1d98c710051d1911d8b2ad /phpBB/includes/cron/manager.php
parent8f0e9aee5ce518937b7ed05c2cd602e85e5b0b8a (diff)
parent1fd8d6de7f6bb41505530c83e487a9dc18bd25af (diff)
downloadforums-04bd2e640e771948671ab6554df8962de980f511.tar
forums-04bd2e640e771948671ab6554df8962de980f511.tar.gz
forums-04bd2e640e771948671ab6554df8962de980f511.tar.bz2
forums-04bd2e640e771948671ab6554df8962de980f511.tar.xz
forums-04bd2e640e771948671ab6554df8962de980f511.zip
Merge branch 'feature/system-cron' into develop
* feature/system-cron: (67 commits) [feature/system-cron] More tests for cron manager. [feature/system-cron] Added documentation for cron manager constructor. [feature/system-cron] Remove an unecessary assignment and an unecessary comment [feature/system-cron] Clarify comments about flush() call in cron. [feature/system-cron] preg_match returns int so cast to bool, fix comment [feature/system-cron] Rename lock() to acquire and unlock() to release. [feature/system-cron] Cache cron's task names. [feature/system-cron] Use a RecursiveDirectoryIterator instead of readdir. [feature/system-cron] Add array type hints if appropriate and remove globals. [feature/system-cron] Make use of the new config class in locks. [feature/system-cron] Fix duplicate instantiation of class loader in tests. [feature/system-cron] Abstract the database locking mechanism out of cron. [feature/system-cron] Move tests to phpunit.xml and always load class loader [feature/system-cron] Basic tests for cron manager. [feature/system-cron] Added @param/@return documentation [feature/system-cron] Add phpDoc documentation for everything else. [feature/system-cron] Cast result in cron_manager::is_valid_name() to bool. [feature/system-cron] Add phpDoc documentation for phpbb_cron_manager class. [feature/system-cron] Add phpDoc documentation for phpbb_cron_lock class. [feature/system-cron] Adjust SQL query style to follow coding guidelines. ...
Diffstat (limited to 'phpBB/includes/cron/manager.php')
-rw-r--r--phpBB/includes/cron/manager.php251
1 files changed, 251 insertions, 0 deletions
diff --git a/phpBB/includes/cron/manager.php b/phpBB/includes/cron/manager.php
new file mode 100644
index 0000000000..21dcb91695
--- /dev/null
+++ b/phpBB/includes/cron/manager.php
@@ -0,0 +1,251 @@
+<?php
+/**
+*
+* @package phpBB3
+* @copyright (c) 2010 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+/**
+* Cron manager class.
+*
+* Finds installed cron tasks, stores task objects, provides task selection.
+*
+* @package phpBB3
+*/
+class phpbb_cron_manager
+{
+ /**
+ * Set of phpbb_cron_task_wrapper objects.
+ * Array holding all tasks that have been found.
+ *
+ * @var array
+ */
+ protected $tasks = array();
+
+ /**
+ * Path to the root of directory tree with tasks.
+ * For bundled phpBB tasks, this is the path to includes/cron/tasks
+ * under phpBB root.
+ * @var string
+ */
+ protected $task_path;
+
+ /**
+ * PHP file extension
+ * @var string
+ */
+ protected $phpEx;
+
+ /**
+ * Cache driver
+ * @var phpbb_cache_driver_interface
+ */
+ protected $cache;
+
+ /**
+ * Constructor. Loads all available tasks.
+ *
+ * Tasks will be looked up in directory tree rooted at $task_path.
+ * Task classes will be autoloaded and must be named according to
+ * autoloading naming conventions. To load cron tasks shipped with
+ * phpbb, pass $phpbb_root_path . 'includes/cron/task' as $task_path.
+ *
+ * If $cache is given, names of found cron tasks will be cached in it
+ * for one hour. Note that the cron task names are stored without
+ * namespacing; if two different phbb_cron_manager instances are
+ * constructed with different $task_path arguments but the same $cache,
+ * the second instance will use task names found by the first instance.
+ *
+ * @param string $task_path Directory containing cron tasks
+ * @param string $phpEx PHP file extension
+ * @param phpbb_cache_driver_interface $cache Cache for task names (optional)
+ * @return void
+ */
+ public function __construct($task_path, $phpEx, phpbb_cache_driver_interface $cache = null)
+ {
+ $this->task_path = $task_path;
+ $this->phpEx = $phpEx;
+ $this->cache = $cache;
+
+ $task_names = $this->find_cron_task_names();
+ $this->load_tasks($task_names);
+ }
+
+ /**
+ * Finds cron task names.
+ *
+ * A cron task file must follow the naming convention:
+ * includes/cron/task/$mod/$name.php.
+ * $mod is core for tasks that are part of phpbb.
+ * Modifications should use their name as $mod.
+ * $name is the name of the cron task.
+ * Cron task is expected to be a class named phpbb_cron_task_${mod}_${name}.
+ *
+ * @return array List of task names
+ */
+ public function find_cron_task_names()
+ {
+ if ($this->cache)
+ {
+ $task_names = $this->cache->get('_cron_tasks');
+
+ if ($task_names !== false)
+ {
+ return $task_names;
+ }
+ }
+
+ $task_names = array();
+ $ext = '.' . $this->phpEx;
+ $ext_length = strlen($ext);
+
+ $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->task_path));
+
+ foreach ($iterator as $fileinfo)
+ {
+ $file = preg_replace('#^' . preg_quote($this->task_path, '#') . '#', '', $fileinfo->getPathname());
+
+ // skip directories and files direclty in the task root path
+ if ($fileinfo->isFile() && strpos($file, '/') !== false)
+ {
+ $task_name = str_replace('/', '_', substr($file, 0, -$ext_length));
+ if (substr($file, -$ext_length) == $ext && $this->is_valid_name($task_name))
+ {
+ $task_names[] = 'phpbb_cron_task_' . $task_name;
+ }
+ }
+ }
+
+ if ($this->cache)
+ {
+ $this->cache->put('_cron_tasks', $task_names, 3600);
+ }
+
+ return $task_names;
+ }
+
+ /**
+ * Checks whether $name is a valid identifier, and
+ * therefore part of valid cron task class name.
+ *
+ * @param string $name Name to check
+ *
+ * @return bool
+ */
+ public function is_valid_name($name)
+ {
+ return (bool) preg_match('/^[a-zA-Z][a-zA-Z0-9_]*$/', $name);
+ }
+
+ /**
+ * Loads tasks given by name, wraps them
+ * and puts them into $this->tasks.
+ *
+ * @param array $task_names Array of strings
+ *
+ * @return void
+ */
+ public function load_tasks(array $task_names)
+ {
+ foreach ($task_names as $task_name)
+ {
+ $task = new $task_name();
+ $wrapper = new phpbb_cron_task_wrapper($task);
+ $this->tasks[] = $wrapper;
+ }
+ }
+
+ /**
+ * Finds a task that is ready to run.
+ *
+ * If several tasks are ready, any one of them could be returned.
+ *
+ * If no tasks are ready, null is returned.
+ *
+ * @return phpbb_cron_task_wrapper|null
+ */
+ public function find_one_ready_task()
+ {
+ foreach ($this->tasks as $task)
+ {
+ if ($task->is_ready())
+ {
+ return $task;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Finds all tasks that are ready to run.
+ *
+ * @return array List of tasks which are ready to run (wrapped in phpbb_cron_task_wrapper).
+ */
+ public function find_all_ready_tasks()
+ {
+ $tasks = array();
+ foreach ($this->tasks as $task)
+ {
+ if ($task->is_ready())
+ {
+ $tasks[] = $task;
+ }
+ }
+ return $tasks;
+ }
+
+ /**
+ * Finds a task by name.
+ *
+ * If there is no task with the specified name, null is returned.
+ *
+ * Web runner uses this method to resolve names to tasks.
+ *
+ * @param string $name Name of the task to look up.
+ * @return phpbb_cron_task A task corresponding to the given name, or null.
+ */
+ public function find_task($name)
+ {
+ foreach ($this->tasks as $task)
+ {
+ if ($task->get_name() == $name)
+ {
+ return $task;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Creates an instance of parametrized cron task $name with args $args.
+ * The constructed task is wrapped with cron task wrapper before being returned.
+ *
+ * @param string $name The task name, which is the same as cron task class name.
+ * @param array $args Will be passed to the task class's constructor.
+ *
+ * @return phpbb_cron_task_wrapper|null
+ */
+ public function instantiate_task($name, array $args)
+ {
+ $task = $this->find_task($name);
+ if ($task)
+ {
+ // task here is actually an instance of cron task wrapper
+ $class = $task->get_name();
+ $task = new $class($args);
+ // need to wrap the new task too
+ $task = new phpbb_cron_task_wrapper($task);
+ }
+ return $task;
+ }
+}