├── .gitignore
├── templates
└── index.twig
├── .scrutinizer.yml
├── composer.json
├── .editorconfig
├── config.php
├── phpunit.xml.dist
├── elementactions
├── TaskManager_DeleteElementAction.php
└── TaskManager_RestartElementAction.php
├── LICENSE
├── translations
└── nl.php
├── .travis.yml
├── consolecommands
└── TaskManagerCommand.php
├── models
└── TaskManagerModel.php
├── TaskManagerPlugin.php
├── controllers
└── TaskManagerController.php
├── tests
└── TaskManager_ModelTest.php
├── README.md
└── elementtypes
└── TaskManagerElementType.php
/.gitignore:
--------------------------------------------------------------------------------
1 | build/
2 |
--------------------------------------------------------------------------------
/templates/index.twig:
--------------------------------------------------------------------------------
1 | {% extends "_layouts/elementindex" %}
2 | {% set title = "Task Manager"|t %}
3 | {% set elementType = 'TaskManager' %}
4 |
--------------------------------------------------------------------------------
/.scrutinizer.yml:
--------------------------------------------------------------------------------
1 | checks:
2 | php:
3 | code_rating: true
4 | duplication: true
5 |
6 | tools:
7 | external_code_coverage: true
8 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "boboldehampsink/taskmanager",
3 | "description": "Task Manager Plugin for Craft CMS",
4 | "authors": [
5 | {
6 | "name": "Bob Olde Hampsink",
7 | "email": "b.oldehampsink@itmundi.nl",
8 | "homepage": "http://github.com/boboldehampsink",
9 | "role": "Developer"
10 | }
11 | ],
12 | "license": "MIT",
13 | "type": "craft-plugin",
14 | "require": {
15 | "composer/installers": "~1.0"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # For more information about the properties used in
2 | # this file, please see the EditorConfig documentation:
3 | # http://editorconfig.org/
4 |
5 | # top-most EditorConfig file
6 | root = true
7 |
8 | [*]
9 | charset = utf-8
10 | end_of_line = lf
11 | indent_style = space
12 | indent_size = 2
13 | insert_final_newline = true
14 | trim_trailing_whitespace = true
15 |
16 | [*.{html,twig,css,less,scss,php}]
17 | indent_size = 4
18 |
19 | [*.md]
20 | trim_trailing_whitespace = false
21 |
22 | [package.json]
23 | # The indent size used in the `package.json` file cannot be changed
24 | # https://github.com/npm/npm/pull/3180#issuecomment-16336516
25 | indent_size = 2
26 | indent_style = space
27 |
--------------------------------------------------------------------------------
/config.php:
--------------------------------------------------------------------------------
1 |
7 | * @copyright Copyright (c) 2015, Bob Olde Hampsink
8 | * @license MIT
9 | *
10 | * @link http://github.com/boboldehampsink
11 | */
12 | return array(
13 |
14 | // How long should we wait before we forfeit a task as hanging?
15 | 'taskTimeout' => 0,
16 |
17 | // At what interval should the watcher watch for new tasks? (in seconds)
18 | 'taskInterval' => 10,
19 |
20 | // Hirefire.io token
21 | 'hirefireToken' => getenv('HIREFIRE_TOKEN'),
22 |
23 | // Name of the task worker you're using (if using Heroku + Hirefire.io)
24 | 'hirefireWorker' => 'worker',
25 | );
26 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 | tests
14 |
15 |
16 |
17 |
18 | ./models
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/elementactions/TaskManager_DeleteElementAction.php:
--------------------------------------------------------------------------------
1 |
9 | * @copyright Copyright (c) 2015, Bob Olde Hampsink
10 | * @license MIT
11 | *
12 | * @link http://github.com/boboldehampsink
13 | */
14 | class TaskManager_DeleteElementAction extends BaseElementAction
15 | {
16 | /**
17 | * Get element action name.
18 | *
19 | * @return string
20 | */
21 | public function getName()
22 | {
23 | return Craft::t('Delete task(s)');
24 | }
25 |
26 | /**
27 | * Delete given task.
28 | *
29 | * @param ElementCriteriaModel $criteria
30 | *
31 | * @return bool
32 | */
33 | public function performAction(ElementCriteriaModel $criteria)
34 | {
35 | foreach ($criteria->id as $taskId) {
36 | craft()->tasks->deleteTaskById($taskId);
37 | }
38 |
39 | $this->setMessage(Craft::t('Task(s) deleted.'));
40 |
41 | return true;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/elementactions/TaskManager_RestartElementAction.php:
--------------------------------------------------------------------------------
1 |
9 | * @copyright Copyright (c) 2015, Bob Olde Hampsink
10 | * @license MIT
11 | *
12 | * @link http://github.com/boboldehampsink
13 | */
14 | class TaskManager_RestartElementAction extends BaseElementAction
15 | {
16 | /**
17 | * Get element action name.
18 | *
19 | * @return string
20 | */
21 | public function getName()
22 | {
23 | return Craft::t('Restart task(s)');
24 | }
25 |
26 | /**
27 | * Restart given tasks.
28 | *
29 | * @param ElementCriteriaModel $criteria
30 | *
31 | * @return bool
32 | */
33 | public function performAction(ElementCriteriaModel $criteria)
34 | {
35 | foreach ($criteria->id as $taskId) {
36 | craft()->tasks->rerunTaskById($taskId);
37 | }
38 |
39 | $this->setMessage(Craft::t('Task(s) restarted.'));
40 |
41 | return true;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Bob Olde Hampsink
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/translations/nl.php:
--------------------------------------------------------------------------------
1 |
9 | * @copyright Copyright (c) 2015, Bob Olde Hampsink
10 | * @license MIT
11 | *
12 | * @link http://github.com/boboldehampsink
13 | */
14 | return array(
15 | 'Task Manager' => 'Taakbeheer',
16 | 'All tasks' => 'Alle taken',
17 | 'Description' => 'Omschrijving',
18 | 'Created' => 'Aangemaakt',
19 | 'Current step' => 'Huidige stap',
20 | 'Total steps' => 'Totaal aantal stappen',
21 | 'User' => 'Gebruiker',
22 | 'Restart task(s)' => 'Herstart taken',
23 | 'Are you sure you want to restart the selected task(s)?' => 'Weet je zeker dat je de geselecteerde taken wilt herstarten?',
24 | 'Task(s) restarted' => 'Taken herstart.',
25 | 'Delete task(s)' => 'Verwijder taken',
26 | 'Are you sure you want to delete the selected task(s)?' => 'Weet je zeker dat je de geselecteerde taken wilt verwijderen?',
27 | 'Task(s) deleted' => 'Taken verwijderd.',
28 | 'Error' => 'Fout',
29 | 'Running' => 'Lopend',
30 | 'No description' => 'Geen omschrijving',
31 | );
32 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | # see http://about.travis-ci.org/docs/user/languages/php/ for more hints
2 | language: php
3 |
4 | # list any PHP version you want to test against
5 | php:
6 | # using major version aliases
7 |
8 | # aliased to 5.3.29
9 | - 5.3
10 | # aliased to a recent 5.4.x version
11 | - 5.4
12 | # aliased to a recent 5.5.x version
13 | - 5.5
14 | # aliased to a recent 5.6.x version
15 | - 5.6
16 | # aliased to a recent 7.x version
17 | - 7.0
18 | # aliased to a recent hhvm version
19 | - hhvm
20 |
21 | # optionally set up exclutions and allowed failures in the matrix
22 | matrix:
23 | allow_failures:
24 | - php: 7.0
25 | - php: hhvm
26 |
27 | # execute any number of scripts before the test run, custom env's are available as variables
28 | before_script:
29 | - curl -sS https://codeload.github.com/pixelandtonic/Craft-Release/zip/master > craft.zip
30 | - unzip craft.zip
31 | - rm craft.zip
32 | - mv Craft-Release-master craft
33 | - mkdir craft/config
34 | - echo " 'test');" > craft/config/db.php
35 | - mkdir craft/storage
36 | - mkdir -p craft/plugins/taskmanager
37 | - for item in *; do if [[ ! "$item" == "craft" ]]; then mv $item craft/plugins/taskmanager; fi; done
38 | - cd craft/app
39 | - composer require mockery/mockery
40 | - cd ../..
41 |
42 | # execute tests
43 | script: phpunit --bootstrap craft/app/tests/bootstrap.php --configuration craft/plugins/taskmanager/phpunit.xml.dist --coverage-clover coverage.clover craft/plugins/taskmanager/tests
44 |
45 | # upload coverage to scrutinizer
46 | after_script:
47 | - wget https://scrutinizer-ci.com/ocular.phar
48 | - php ocular.phar code-coverage:upload --format=php-clover coverage.clover
49 |
--------------------------------------------------------------------------------
/consolecommands/TaskManagerCommand.php:
--------------------------------------------------------------------------------
1 |
9 | * @copyright Copyright (c) 2015, Bob Olde Hampsink
10 | * @license MIT
11 | *
12 | * @link http://github.com/boboldehampsink
13 | */
14 | class TaskManagerCommand extends BaseCommand
15 | {
16 | /**
17 | * Runs pending tasks.
18 | *
19 | * @return int
20 | */
21 | public function actionRun()
22 | {
23 | Craft::log(Craft::t('Running new tasks.'));
24 |
25 | // Start running tasks
26 | craft()->tasks->runPendingTasks();
27 |
28 | return 1;
29 | }
30 |
31 | /**
32 | * Watch for tasks and run them.
33 | */
34 | public function actionWatch()
35 | {
36 | Craft::log(Craft::t('Watching for new tasks.'));
37 |
38 | // Keep on checking for pending tasks
39 | while (true) {
40 |
41 | // Open db connection, if closed
42 | craft()->db->setActive(true);
43 |
44 | // Reset next pending tasks cache
45 | $this->resetCraftNextPendingTasksCache();
46 |
47 | // Start running tasks
48 | craft()->tasks->runPendingTasks();
49 |
50 | // Close db connection, if open
51 | craft()->db->setActive(false);
52 |
53 | // Sleep a little
54 | sleep(craft()->config->get('taskInterval', 'taskManager'));
55 | }
56 | }
57 |
58 | /**
59 | * Reset craft next pending task cache using reflection.
60 | */
61 | private function resetCraftNextPendingTasksCache()
62 | {
63 | $obj = craft()->tasks;
64 | $refObject = new \ReflectionObject($obj);
65 | $refProperty = $refObject->getProperty('_nextPendingTask');
66 | $refProperty->setAccessible(true);
67 | $refProperty->setValue($obj, null);
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/models/TaskManagerModel.php:
--------------------------------------------------------------------------------
1 |
9 | * @copyright Copyright (c) 2015, Bob Olde Hampsink
10 | * @license MIT
11 | *
12 | * @link http://github.com/boboldehampsink
13 | */
14 | class TaskManagerModel extends BaseElementModel
15 | {
16 | /**
17 | * Element Type.
18 | *
19 | * @var string
20 | */
21 | protected $elementType = 'TaskManager';
22 |
23 | /**
24 | * Define attributes.
25 | *
26 | * @return array
27 | */
28 | protected function defineAttributes()
29 | {
30 | return array_merge(parent::defineAttributes(), array(
31 | 'level' => AttributeType::Number,
32 | 'type' => AttributeType::String,
33 | 'description' => AttributeType::String,
34 | 'parentId' => AttributeType::Mixed,
35 | 'totalSteps' => AttributeType::Number,
36 | 'currentStep' => AttributeType::Number,
37 | 'settings' => AttributeType::Mixed,
38 | 'status' => array(AttributeType::Enum, 'values' => array(TaskStatus::Pending, TaskStatus::Error, TaskStatus::Running), 'default' => TaskStatus::Pending),
39 | ));
40 | }
41 |
42 | /**
43 | * Get title.
44 | */
45 | public function getTitle()
46 | {
47 | return !empty($this->description) ? $this->description : Craft::t('No description');
48 | }
49 |
50 | /**
51 | * Returns the element's status.
52 | *
53 | * @return string
54 | */
55 | public function getStatus()
56 | {
57 | switch ($this->status) {
58 |
59 | case TaskStatus::Pending:
60 | return EntryModel::PENDING;
61 |
62 | case TaskStatus::Error:
63 | return EntryModel::EXPIRED;
64 |
65 | case TaskStatus::Running:
66 | return EntryModel::LIVE;
67 |
68 | default:
69 | return EntryModel::DISABLED;
70 |
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/TaskManagerPlugin.php:
--------------------------------------------------------------------------------
1 |
9 | * @copyright Copyright (c) 2015, Bob Olde Hampsink
10 | * @license MIT
11 | *
12 | * @link http://github.com/boboldehampsink
13 | */
14 | class TaskManagerPlugin extends BasePlugin
15 | {
16 | /**
17 | * Get plugin name.
18 | *
19 | * @return string
20 | */
21 | public function getName()
22 | {
23 | return Craft::t('Task Manager');
24 | }
25 |
26 | /**
27 | * Get plugin description.
28 | *
29 | * @return string
30 | */
31 | public function getDescription()
32 | {
33 | return Craft::t('Adds a "Task Manager" section to your CP to easily cancel or delete Craft Tasks.');
34 | }
35 |
36 | /**
37 | * Get plugin version.
38 | *
39 | * @return string
40 | */
41 | public function getVersion()
42 | {
43 | return '0.4.3';
44 | }
45 |
46 | /**
47 | * Get plugin developer.
48 | *
49 | * @return string
50 | */
51 | public function getDeveloper()
52 | {
53 | return 'Bob Olde Hampsink';
54 | }
55 |
56 | /**
57 | * Get plugin developer url.
58 | *
59 | * @return string
60 | */
61 | public function getDeveloperUrl()
62 | {
63 | return 'https://github.com/boboldehampsink';
64 | }
65 |
66 | /**
67 | * Get plugin documentation url.
68 | *
69 | * @return string
70 | */
71 | public function getDocumentationUrl()
72 | {
73 | return 'https://github.com/boboldehampsink/taskmanager';
74 | }
75 |
76 | /**
77 | * Has Control Panel section.
78 | *
79 | * @return bool
80 | */
81 | public function hasCpSection()
82 | {
83 | return true;
84 | }
85 |
86 | /**
87 | * Register hirefire endpoint
88 | *
89 | * @return array
90 | */
91 | public function registerSiteRoutes()
92 | {
93 | return array(
94 | 'hirefire/(?P(.*?))/info' => array('action' => 'taskManager/getPendingTasks'),
95 | );
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/controllers/TaskManagerController.php:
--------------------------------------------------------------------------------
1 |
9 | * @copyright Copyright (c) 2015, Bob Olde Hampsink
10 | * @license MIT
11 | *
12 | * @link http://github.com/boboldehampsink
13 | */
14 | class TaskManagerController extends BaseController
15 | {
16 | /**
17 | * Allow anonymous access (for a cronjob perhaps).
18 | *
19 | * @var bool
20 | */
21 | public $allowAnonymous = true;
22 |
23 | /**
24 | * Get pending tasks in Hirefire.io format
25 | *
26 | * @param array $variables
27 | *
28 | * @throws HttpException
29 | */
30 | public function actionGetPendingTasks(array $variables = array())
31 | {
32 | // Verify hirefire token
33 | if ($variables['token'] != craft()->config->get('hirefireToken', 'taskManager')) {
34 | throw new HttpException(400, Craft::t('Invalid Hirefire token.'));
35 | }
36 |
37 | // Return pending tasks for worker
38 | $this->returnJson(array(array(
39 | 'name' => craft()->config->get('hirefireWorker', 'taskManager'),
40 | 'quantity' => craft()->tasks->getTotalTasks(),
41 | )));
42 | }
43 |
44 | /**
45 | * Rerun all failed tasks.
46 | */
47 | public function actionRerunAllFailedTasks()
48 | {
49 | // Get all failed tasks
50 | $query = craft()->db->createCommand()
51 | ->select('id')
52 | ->from('tasks')
53 | ->where(array('and', 'lft = 1', 'status = :status'), array(':status' => TaskStatus::Error));
54 |
55 | // Get all hanging? tasks
56 | if ($timeout = craft()->config->get('taskTimeout', 'taskManager')) {
57 | $query->orWhere(array('and', 'lft = 1', 'dateCreated < (NOW() - INTERVAL :seconds SECOND)'), array(':seconds' => $timeout));
58 | }
59 |
60 | // Get all
61 | $tasks = $query->queryAll();
62 |
63 | // Loop through failed tasks
64 | foreach ($tasks as $task) {
65 |
66 | // Rerun task
67 | craft()->tasks->rerunTaskById($task['id']);
68 | }
69 |
70 | // Run pending tasks controller
71 | craft()->runController('tasks/runPendingTasks');
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/tests/TaskManager_ModelTest.php:
--------------------------------------------------------------------------------
1 |
11 | * @copyright Copyright (c) 2015, Bob Olde Hampsink
12 | * @license MIT
13 | *
14 | * @link http://github.com/boboldehampsink
15 | *
16 | * @coversDefaultClass Craft\TaskManagerModel
17 | * @covers ::
18 | */
19 | class TaskManager_ModelTest extends BaseTest
20 | {
21 | /**
22 | * {@inheritdoc}
23 | */
24 | public static function setUpBeforeClass()
25 | {
26 | parent::setUpBeforeClass();
27 | require_once __DIR__ . '/../models/TaskManagerModel.php';
28 | }
29 |
30 | /**
31 | * Test getTitle.
32 | *
33 | * @covers ::getTitle
34 | */
35 | final public function testGetTitle()
36 | {
37 | // Mock localization service
38 | $this->setMockLocalizationService();
39 |
40 | // Set up model
41 | $model = new TaskManagerModel();
42 |
43 | // Set description attribute
44 | $model->description = 'test';
45 |
46 | // Assert title/description
47 | $this->assertSame($model->getTitle(), $model->description);
48 | }
49 |
50 | /**
51 | * Test getStatus.
52 | *
53 | * @covers ::getStatus
54 | * @dataProvider provideStatuses
55 | */
56 | final public function testGetStatus($taskStatus, $elementStatus)
57 | {
58 | // Mock localization service
59 | $this->setMockLocalizationService();
60 |
61 | // Set up model
62 | $model = new TaskManagerModel();
63 |
64 | // Set status attribute
65 | $model->status = $taskStatus;
66 |
67 | // Assert element status
68 | $this->assertSame($model->getStatus(), $elementStatus);
69 | }
70 |
71 | /**
72 | * Mock localization service.
73 | *
74 | * @return LocalizationService
75 | */
76 | private function setMockLocalizationService()
77 | {
78 | $mock = $this->getMockBuilder('Craft\LocalizationService')
79 | ->disableOriginalConstructor()
80 | ->getMock();
81 |
82 | $this->setComponent(craft(), 'i18n', $mock);
83 | }
84 |
85 | /**
86 | * Provide statuses.
87 | *
88 | * @return array
89 | */
90 | final public function provideStatuses()
91 | {
92 | return array(
93 | 'Pending' => array(TaskStatus::Pending, EntryModel::PENDING),
94 | 'Error' => array(TaskStatus::Error, EntryModel::EXPIRED),
95 | 'Running' => array(TaskStatus::Running, EntryModel::LIVE),
96 | 'Unknown' => array('unknown', EntryModel::DISABLED),
97 | );
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | DEPRECATED - Task Manager plugin for Craft CMS [](https://travis-ci.org/boboldehampsink/taskmanager) [](https://scrutinizer-ci.com/g/boboldehampsink/taskmanager/?branch=develop) [](https://scrutinizer-ci.com/g/boboldehampsink/taskmanager/?branch=develop) [](https://packagist.org/packages/boboldehampsink/taskmanager) [](https://packagist.org/packages/boboldehampsink/taskmanager) [](https://packagist.org/packages/boboldehampsink/taskmanager) [](https://packagist.org/packages/boboldehampsink/taskmanager)
2 | =================
3 |
4 | Adds a "Task Manager" section to your CP to easily cancel or delete Craft Tasks.
5 |
6 | __Important__
7 | - The plugin's folder should be named "taskmanager"
8 |
9 | Deprecated
10 | =================
11 |
12 | With the release of Craft 3 on 4-4-2018, this plugin has been deprecated. You can still use this with Craft 2 but you are encouraged to use (and develop) a Craft 3 version. At this moment, I have no plans to do so.
13 |
14 | Features
15 | =================
16 | - View detail task info
17 | - Cancel running tasks
18 | - Rerun running or failed tasks
19 | - If you set up a cronjob to run /actions/taskManager/rerunAllFailedTasks, you can automatically rerun failed tasks
20 | - Comes with two console commands, one to run pending tasks and one to watch for pending tasks and run them.
21 | - Has an endpoint for Hirefire, see http://support.hirefire.io/help/kb/guides/any-programming-language
22 |
23 | To run pending tasks just run
24 |
25 | ```
26 | ./craft/app/etc/console/yiic taskmanager run
27 | ```
28 |
29 | To watch for pending tasks and them run them, run
30 |
31 | ```
32 | ./craft/app/etc/console/yiic taskmanager watch
33 | ```
34 |
35 | Development
36 | =================
37 | Run this from your Craft installation to test your changes to this plugin before submitting a Pull Request
38 | ```bash
39 | phpunit --bootstrap craft/app/tests/bootstrap.php --configuration craft/plugins/taskmanager/phpunit.xml.dist --coverage-clover coverage.clover craft/plugins/taskmanager/tests
40 | ```
41 |
42 | Changelog
43 | =================
44 | ### 0.4.3 ###
45 | - Added the ability to get pending tasks in Hirefire.io format
46 | - Recycle db connection
47 |
48 | ### 0.4.2 ###
49 | - Fixed bug with reading default config values
50 |
51 | ### 0.4.1 ###
52 | - Added the ability to control the watch interval via the `taskInterval` config setting
53 |
54 | ### 0.4.0 ###
55 | - Added the ability to run and watch for tasks via the command line.
56 |
57 | ### 0.3.1 ###
58 | - Updated the plugin for Craft 2.5
59 | - The hook "modifyTaskManagerAttributes" is now "defineAdditionalTaskManagerTableAttributes"
60 | - Added description and documentation url
61 |
62 | ### 0.3.0 ###
63 | - Added sources by type
64 | - Replaced action buttons by element actions
65 | - Added endpoint for rerunning all failed tasks
66 | - Added the ability to restart hanging tasks after a given timeout
67 | - Added "modifyTaskManagerSources" hook
68 | - Added "addTaskManagerActions" hook
69 | - Added "modifyTaskManagerTableAttributes" hook
70 | - Added "getTaskManagerTableAttributeHtml" hook
71 | - Added "modifyTaskManagerSortableAttributes"
72 |
73 | ### 0.2.0 ###
74 | - Added the ability to restart a task
75 | - Deleting a task is now more graceful
76 |
77 | ### 0.1.0 ###
78 | - Initial release
79 |
--------------------------------------------------------------------------------
/elementtypes/TaskManagerElementType.php:
--------------------------------------------------------------------------------
1 |
9 | * @copyright Copyright (c) 2015, Bob Olde Hampsink
10 | * @license MIT
11 | *
12 | * @link http://github.com/boboldehampsink
13 | */
14 | class TaskManagerElementType extends BaseElementType
15 | {
16 | /**
17 | * Returns the element type name.
18 | *
19 | * @return string
20 | */
21 | public function getName()
22 | {
23 | return Craft::t('Task Manager');
24 | }
25 |
26 | /**
27 | * Returns whether this element type has content.
28 | *
29 | * @return bool
30 | */
31 | public function hasContent()
32 | {
33 | return false;
34 | }
35 |
36 | /**
37 | * Returns whether this element type has titles.
38 | *
39 | * @return bool
40 | */
41 | public function hasTitles()
42 | {
43 | return false;
44 | }
45 |
46 | /**
47 | * Returns whether this element type has statuses.
48 | *
49 | * @return bool
50 | */
51 | public function hasStatuses()
52 | {
53 | return true;
54 | }
55 |
56 | /**
57 | * Returns this element's statuses.
58 | *
59 | * @return array
60 | */
61 | public function getStatuses()
62 | {
63 | return array(
64 | EntryModel::PENDING => Craft::t('Pending'),
65 | EntryModel::EXPIRED => Craft::t('Error'),
66 | EntryModel::LIVE => Craft::t('Running'),
67 | );
68 | }
69 |
70 | /**
71 | * Return sources.
72 | *
73 | * @param string $context
74 | *
75 | * @return array
76 | */
77 | public function getSources($context = null)
78 | {
79 | $sources = array(
80 | '*' => array(
81 | 'label' => Craft::t('All tasks'),
82 | 'criteria' => array('editable' => true),
83 | ),
84 | );
85 |
86 | // Get sources by type
87 | $results = craft()->db->createCommand()
88 | ->select('id, type')
89 | ->from('tasks')
90 | ->order('root asc, lft asc')
91 | ->group('type')
92 | ->queryAll();
93 | foreach ($results as $result) {
94 | $sources['type:'.$result['type']] = array(
95 | 'label' => $result['type'],
96 | 'data' => array('id' => $result['id']),
97 | 'criteria' => array('type' => $result['type'], 'editable' => true),
98 | );
99 | }
100 |
101 | // Allow plugins to modify the sources
102 | craft()->plugins->call('modifyTaskManagerSources', array(&$sources, $context));
103 |
104 | return $sources;
105 | }
106 |
107 | /**
108 | * @inheritDoc IElementType::getAvailableActions()
109 | *
110 | * @param string|null $source
111 | *
112 | * @return array|null
113 | */
114 | public function getAvailableActions($source = null)
115 | {
116 | $actions = array();
117 |
118 | $restartAction = craft()->elements->getAction('TaskManager_Restart');
119 | $restartAction->setParams(array(
120 | 'confirmationMessage' => Craft::t('Are you sure you want to restart the selected task(s)?'),
121 | 'successMessage' => Craft::t('Task(s) restarted'),
122 | ));
123 | $actions[] = $restartAction;
124 |
125 | $deleteAction = craft()->elements->getAction('TaskManager_Delete');
126 | $deleteAction->setParams(array(
127 | 'confirmationMessage' => Craft::t('Are you sure you want to delete the selected task(s)?'),
128 | 'successMessage' => Craft::t('Task(s) deleted'),
129 | ));
130 | $actions[] = $deleteAction;
131 |
132 | // Allow plugins to add additional actions
133 | $allPluginActions = craft()->plugins->call('addTaskManagerActions', array($source), true);
134 |
135 | foreach ($allPluginActions as $pluginActions) {
136 | $actions = array_merge($actions, $pluginActions);
137 | }
138 |
139 | return $actions;
140 | }
141 |
142 | /**
143 | * @inheritDoc IElementType::defineAvailableTableAttributes()
144 | *
145 | * @return array
146 | */
147 | public function defineAvailableTableAttributes()
148 | {
149 | $attributes = array(
150 | 'description' => Craft::t('Description'),
151 | 'type' => Craft::t('Type'),
152 | 'dateCreated' => Craft::t('Created'),
153 | 'currentStep' => Craft::t('Current step'),
154 | 'totalSteps' => Craft::t('Total steps'),
155 | );
156 |
157 | // Allow plugins to modify the attributes
158 | $pluginAttributes = craft()->plugins->call('defineAdditionalTaskManagerTableAttributes', array(), true);
159 | foreach ($pluginAttributes as $thisPluginAttributes) {
160 | $attributes = array_merge($attributes, $thisPluginAttributes);
161 | }
162 |
163 | return $attributes;
164 | }
165 |
166 | /**
167 | * @inheritDoc IElementType::getDefaultTableAttributes()
168 | *
169 | * @param string|null $source
170 | *
171 | * @return array
172 | */
173 | public function getDefaultTableAttributes($source = null)
174 | {
175 | return array(
176 | 'description',
177 | 'type',
178 | 'dateCreated',
179 | 'currentStep',
180 | 'totalSteps',
181 | );
182 | }
183 |
184 | /**
185 | * Get table attribute html.
186 | *
187 | * @param BaseElementModel $element
188 | * @param string $attribute
189 | *
190 | * @return string
191 | */
192 | public function getTableAttributeHtml(BaseElementModel $element, $attribute)
193 | {
194 | // First give plugins a chance to set this
195 | $pluginAttributeHtml = craft()->plugins->callFirst('getTaskManagerTableAttributeHtml', array($element, $attribute), true);
196 |
197 | if ($pluginAttributeHtml !== null) {
198 | return $pluginAttributeHtml;
199 | }
200 |
201 | // Or format default
202 | return parent::getTableAttributeHtml($element, $attribute);
203 | }
204 |
205 | /**
206 | * Define sortable attributes.
207 | *
208 | * @param string $source
209 | *
210 | * @return array
211 | */
212 | public function defineSortableAttributes($source = null)
213 | {
214 | $attributes = array(
215 | 'type' => Craft::t('Type'),
216 | 'dateCreated' => Craft::t('Created'),
217 | );
218 |
219 | // Allow plugins to modify the attributes
220 | craft()->plugins->call('modifyTaskManagerSortableAttributes', array(&$attributes));
221 |
222 | return $attributes;
223 | }
224 |
225 | /**
226 | * Defines any custom element criteria attributes for this element type.
227 | *
228 | * @return array
229 | */
230 | public function defineCriteriaAttributes()
231 | {
232 | return array(
233 | 'type' => AttributeType::String,
234 | 'dateCreated' => AttributeType::DateTime,
235 | );
236 | }
237 |
238 | /**
239 | * Modifies an element query targeting elements of this type.
240 | *
241 | * @param DbCommand $query
242 | * @param ElementCriteriaModel $criteria
243 | *
244 | * @return mixed
245 | */
246 | public function modifyElementsQuery(DbCommand $query, ElementCriteriaModel $criteria)
247 | {
248 | // Default query
249 | $query
250 | ->select('id, currentStep, totalSteps, status, type, description, settings, dateCreated')
251 | ->from('tasks elements');
252 |
253 | // Reset default element type query parts
254 | $query->setJoin('');
255 | $query->setWhere('1=1');
256 | $query->setGroup('');
257 | unset($query->params[':locale']);
258 | unset($query->params[':elementsid1']);
259 |
260 | if ($criteria->type) {
261 | $query->andWhere(DbHelper::parseParam('type', $criteria->type, $query->params));
262 | }
263 |
264 | // Add search capabilities
265 | if ($criteria->search) {
266 | $query->andWhere(DbHelper::parseParam('description', '*'.$criteria->search.'*', $query->params));
267 | $criteria->search = null;
268 | }
269 | }
270 |
271 | /**
272 | * Populates an element model based on a query result.
273 | *
274 | * @param array $row
275 | *
276 | * @return array
277 | */
278 | public function populateElementModel($row)
279 | {
280 | return TaskManagerModel::populateModel($row);
281 | }
282 | }
283 |
--------------------------------------------------------------------------------