Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorThomas Steur <thomas.steur@googlemail.com>2014-06-05 08:44:37 +0400
committerThomas Steur <thomas.steur@googlemail.com>2014-06-05 08:44:37 +0400
commit3e03b0a7ca4055b4f05be7d4ec7bcfaacf364eff (patch)
tree47afa18c0b671f38e17405078bdee156ad020058 /core
parent0ed11b178860844b97b967f6cfa1ffd12ab2eaab (diff)
refs #5301 started to simplify scheduled tasks API while staying backwards compatible
Diffstat (limited to 'core')
-rw-r--r--core/Menu/MenuAbstract.php33
-rw-r--r--core/Plugin.php38
-rw-r--r--core/Plugin/Manager.php33
-rw-r--r--core/Plugin/Tasks.php133
-rw-r--r--core/TaskScheduler.php55
5 files changed, 237 insertions, 55 deletions
diff --git a/core/Menu/MenuAbstract.php b/core/Menu/MenuAbstract.php
index 4ffbe8f532..06d972f064 100644
--- a/core/Menu/MenuAbstract.php
+++ b/core/Menu/MenuAbstract.php
@@ -61,42 +61,11 @@ abstract class MenuAbstract extends Singleton
return self::$menus;
}
- $pluginNames = PluginManager::getInstance()->getLoadedPluginsName();
-
- self::$menus = array();
- foreach ($pluginNames as $pluginName) {
- $menu = $this->findMenuInPlugin($pluginName);
-
- if (!empty($menu)) {
- self::$menus[] = $menu;
- }
- }
+ self::$menus = PluginManager::getInstance()->findComponents('Menu', 'Piwik\\Plugin\\Menu');
return self::$menus;
}
- private function findMenuInPlugin($pluginName)
- {
- $menuFile = PIWIK_INCLUDE_PATH . '/plugins/' . $pluginName . '/Menu.php';
-
- if (!file_exists($menuFile)) {
- return;
- }
-
- $klassName = sprintf('Piwik\\Plugins\\%s\\Menu', $pluginName);
-
- if (!class_exists($klassName)) {
- return;
- }
-
- if (!is_subclass_of($klassName, 'Piwik\\Plugin\\Menu')) {
- Log::warning(sprintf('Cannot use menu for plugin %s, class %s does not extend Piwik\Plugin\Menu', $pluginName, $klassName));
- return;
- }
-
- return new $klassName;
- }
-
/**
* Adds a new entry to the menu.
*
diff --git a/core/Plugin.php b/core/Plugin.php
index 1392fc3bc0..0c2c8e8d8b 100644
--- a/core/Plugin.php
+++ b/core/Plugin.php
@@ -277,6 +277,44 @@ class Plugin
}
/**
+ * Tries to find a component such as a Menu or Tasks within this plugin.
+ *
+ * @param string $componentName The name of the component you want to look for. In case you request a
+ * component named 'Menu' it'll look for a file named 'Menu.php' within the
+ * root of the plugin folder that implements a class named
+ * Piwik\Plugin\$PluginName\Menu . If such a file exists but does not implement
+ * this class it'll silently ignored.
+ * @param string $expectedSubclass If not empty, a check will be performed whether a found file extends the
+ * given subclass. If the requested file exists but does not extend this class
+ * a warning will be shown to advice a developer to extend this certain class.
+ *
+ * @return \stdClass|null Null if the requested component does not exist or an instance of the found
+ * component.
+ */
+ public function findComponent($componentName, $expectedSubclass)
+ {
+ $componentFile = sprintf('%s/plugins/%s/%s.php', PIWIK_INCLUDE_PATH, $this->pluginName, $componentName);
+
+ if (!file_exists($componentFile)) {
+ return;
+ }
+
+ $klassName = sprintf('Piwik\\Plugins\\%s\\%s', $this->pluginName, $componentName);
+
+ if (!class_exists($klassName)) {
+ return;
+ }
+
+ if (!empty($expectedSubclass) && !is_subclass_of($klassName, $expectedSubclass)) {
+ Log::warning(sprintf('Cannot use component %s for plugin %s, class %s does not extend %s',
+ $componentName, $this->pluginName, $klassName, $expectedSubclass));
+ return;
+ }
+
+ return new $klassName;
+ }
+
+ /**
* Detect whether there are any missing dependencies.
*
* @param null $piwikVersion Defaults to the current Piwik version
diff --git a/core/Plugin/Manager.php b/core/Plugin/Manager.php
index 9c481bb03b..5a31e484e4 100644
--- a/core/Plugin/Manager.php
+++ b/core/Plugin/Manager.php
@@ -34,6 +34,7 @@ class Manager extends Singleton
protected $pluginsToLoad = array();
protected $doLoadPlugins = true;
+
/**
* @var Plugin[]
*/
@@ -325,6 +326,38 @@ class Manager extends Singleton
}
/**
+ * Tries to find the given components such as a Menu or Tasks implemented by plugins.
+ * This method won't cache the found components. If you need to find the same component multiple times you might
+ * want to cache the result to save a tiny bit of time.
+ *
+ * @param string $componentName The name of the component you want to look for. In case you request a
+ * component named 'Menu' it'll look for a file named 'Menu.php' within the
+ * root of all plugin folders that implement a class named
+ * Piwik\Plugin\$PluginName\Menu.
+ * @param string $expectedSubclass If not empty, a check will be performed whether a found file extends the
+ * given subclass. If the requested file exists but does not extend this class
+ * a warning will be shown to advice a developer to extend this certain class.
+ *
+ * @return \stdClass[]
+ */
+ public function findComponents($componentName, $expectedSubclass)
+ {
+ $pluginNames = $this->getLoadedPlugins();
+
+ $components = array();
+
+ foreach ($pluginNames as $plugin) {
+ $component = $plugin->findComponent($componentName, $expectedSubclass);
+
+ if (!empty($component)) {
+ $components[] = $component;
+ }
+ }
+
+ return $components;
+ }
+
+ /**
* Uninstalls a Plugin (deletes plugin files from the disk)
* Only deactivated plugins can be uninstalled
*
diff --git a/core/Plugin/Tasks.php b/core/Plugin/Tasks.php
new file mode 100644
index 0000000000..2b22c90825
--- /dev/null
+++ b/core/Plugin/Tasks.php
@@ -0,0 +1,133 @@
+<?php
+/**
+ * Piwik - Open source web analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ */
+namespace Piwik\Plugin;
+
+use Piwik\ScheduledTask;
+use Piwik\ScheduledTime;
+
+class Tasks
+{
+ /**
+ * @var ScheduledTask[]
+ */
+ private $tasks = array();
+
+ const LOWEST_PRIORITY = ScheduledTask::LOWEST_PRIORITY;
+ const LOW_PRIORITY = ScheduledTask::LOW_PRIORITY;
+ const NORMAL_PRIORITY = ScheduledTask::NORMAL_PRIORITY;
+ const HIGH_PRIORITY = ScheduledTask::HIGH_PRIORITY;
+ const HIGHEST_PRIORITY = ScheduledTask::HIGHEST_PRIORITY;
+
+ public function schedule()
+ {
+ }
+
+ /**
+ * @return ScheduledTask[] $tasks
+ */
+ public function getScheduledTasks()
+ {
+ return $this->tasks;
+ }
+
+ /**
+ * Schedule the given tasks/method to run once every hour.
+ *
+ * @param string $methodName The name of the method that will be called when the task is being
+ * exectuted. To make it work you need to create a public method having the
+ * given method name in your Tasks class.
+ * @param null|string $methodParameter Can be null if the task does not need any parameter or a string. It is not
+ * possible to specify multiple parameters as an array etc. If you need to
+ * pass multiple parameters separate them via any characters such as '###'.
+ * For instance '$param1###$param2###$param3'
+ * @param int $priority Can be any constant such as self::LOW_PRIORITY
+ *
+ * @return ScheduledTime
+ * @api
+ */
+ protected function hourly($methodName, $methodParameter = null, $priority = self::NORMAL_PRIORITY)
+ {
+ return $this->custom($this, $methodName, $methodParameter, 'hourly', $priority);
+ }
+
+ /**
+ * Schedule the given tasks/method to run once every day.
+ *
+ * See {@link hourly()}
+ * @api
+ */
+ protected function daily($methodName, $methodParameter = null, $priority = self::NORMAL_PRIORITY)
+ {
+ return $this->custom($this, $methodName, $methodParameter, 'daily', $priority);
+ }
+
+ /**
+ * Schedule the given tasks/method to run once every week.
+ *
+ * See {@link hourly()}
+ * @api
+ */
+ protected function weekly($methodName, $methodParameter = null, $priority = self::NORMAL_PRIORITY)
+ {
+ return $this->custom($this, $methodName, $methodParameter, 'weekly', $priority);
+ }
+
+ /**
+ * Schedule the given tasks/method to run once every month.
+ *
+ * See {@link hourly()}
+ * @api
+ */
+ protected function monthly($methodName, $methodParameter = null, $priority = self::NORMAL_PRIORITY)
+ {
+ return $this->custom($this, $methodName, $methodParameter, 'monthly', $priority);
+ }
+
+ /**
+ * Schedules the given tasks/method to run depending at the given scheduled time. Unlike the convenient methods
+ * such as {@link hourly()} you need to specify the object on which the given method should be called. This can be
+ * either an instance of a class or a class name. For more information about these parameters see {@link hourly()}
+ *
+ * @param string|object $objectOrClassName
+ * @param string $methodName
+ * @param null|string $methodParameter
+ * @param string|ScheduledTime $time
+ * @param int $priority
+ *
+ * @return ScheduledTime
+ *
+ * @throws \Exception If a wrong time format is given. Needs to be either a string such as 'daily', 'weekly', ...
+ * or an instance of {@link Piwik\ScheduledTime}
+ *
+ * @api
+ */
+ protected function custom($objectOrClassName, $methodName, $methodParameter, $time, $priority = self::NORMAL_PRIORITY)
+ {
+ if (is_string($time)) {
+ $time = ScheduledTime::factory($time);
+ }
+
+ if (!($time instanceof ScheduledTime)) {
+ throw new \Exception('$time should be an instance of ScheduledTime');
+ }
+
+ if (!is_string($objectOrClassName)) {
+ $objectOrClassName = get_class($objectOrClassName);
+ }
+
+ $this->addScheduledTask(new ScheduledTask($objectOrClassName, $methodName, $methodParameter, $time, $priority));
+
+ return $time;
+ }
+
+ protected function addScheduledTask(ScheduledTask $task)
+ {
+ $this->tasks[] = $task;
+ }
+} \ No newline at end of file
diff --git a/core/TaskScheduler.php b/core/TaskScheduler.php
index a3eab34c24..85c71c9ef8 100644
--- a/core/TaskScheduler.php
+++ b/core/TaskScheduler.php
@@ -10,6 +10,7 @@
namespace Piwik;
use Exception;
+use Piwik\Plugin\Manager as PluginManager;
// When set to true, all scheduled tasks will be triggered in all requests (careful!)
define('DEBUG_FORCE_SCHEDULED_TASKS', false);
@@ -52,7 +53,7 @@ define('DEBUG_FORCE_SCHEDULED_TASKS', false);
*/
class TaskScheduler extends Singleton
{
- const GET_TASKS_EVENT = "TaskScheduler.getScheduledTasks";
+ const GET_TASKS_EVENT = 'TaskScheduler.getScheduledTasks';
private $isRunning = false;
@@ -81,34 +82,42 @@ class TaskScheduler extends Singleton
return self::getInstance()->doRunTasks();
}
- private function doRunTasks()
+
+ // for backwards compatibility
+ private function collectTasksRegisteredViaEvent()
{
- // collect tasks
$tasks = array();
/**
- * Triggered during scheduled task execution. Collects all the tasks to run.
- *
- * Subscribe to this event to schedule code execution on an hourly, daily, weekly or monthly
- * basis.
- *
- * **Example**
- *
- * public function getScheduledTasks(&$tasks)
- * {
- * $tasks[] = new ScheduledTask(
- * 'Piwik\Plugins\CorePluginsAdmin\MarketplaceApiClient',
- * 'clearAllCacheEntries',
- * null,
- * ScheduledTime::factory('daily'),
- * ScheduledTask::LOWEST_PRIORITY
- * );
- * }
- *
- * @param ScheduledTask[] &$tasks List of tasks to run periodically.
+ * @ignore
*/
Piwik::postEvent(self::GET_TASKS_EVENT, array(&$tasks));
- /** @var ScheduledTask[] $tasks */
+
+ return $tasks;
+ }
+
+ private function getScheduledTasks()
+ {
+ /** @var \Piwik\ScheduledTask[] $tasks */
+ $tasks = $this->collectTasksRegisteredViaEvent();
+
+ /** @var \Piwik\Plugin\Tasks[] $pluginTasks */
+ $pluginTasks = PluginManager::getInstance()->findComponents('Tasks', 'Piwik\\Plugin\\Tasks');
+ foreach ($pluginTasks as $pluginTask) {
+
+ $pluginTask->schedule();
+
+ foreach ($pluginTask->getScheduledTasks() as $task) {
+ $tasks[] = $task;
+ }
+ }
+
+ return $tasks;
+ }
+
+ private function doRunTasks()
+ {
+ $tasks = $this->getScheduledTasks();
// remove from timetable tasks that are not active anymore
$this->timetable->removeInactiveTasks($tasks);