From 49382ab1063a846c66503284908069a054989d4a Mon Sep 17 00:00:00 2001 From: Benjamin Trenkle Date: Wed, 7 Jul 2021 12:27:00 +0200 Subject: [PATCH 001/615] Update hash --- .drone.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.drone.yml b/.drone.yml index 097ddda712328..bf2cacaf38389 100644 --- a/.drone.yml +++ b/.drone.yml @@ -270,6 +270,6 @@ steps: --- kind: signature -hmac: d9dd36c1bf3ac28d03a3a2e7593357ed2f5dd87a098be4115fb4c844b9304eab +hmac: ec1b070b49dd11b007d258a698c5b0d0217e5d90dabf1b9cb606e4fb4a28d1a0 ... From fc5664ed0ef1bfb38b44c49eaa2e611787eb0d9e Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Sat, 3 Jul 2021 01:50:37 +0530 Subject: [PATCH 002/615] Add manifest --- .../components/com_cronjobs/cronjobs.xml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 administrator/components/com_cronjobs/cronjobs.xml diff --git a/administrator/components/com_cronjobs/cronjobs.xml b/administrator/components/com_cronjobs/cronjobs.xml new file mode 100644 index 0000000000000..8dda0d5120970 --- /dev/null +++ b/administrator/components/com_cronjobs/cronjobs.xml @@ -0,0 +1,15 @@ + + + Cronjobs + July 2021 + Ditsuke + GPL v3 + 0.0.0 + + COM_CRONJOBS_XML_DESCRIPTION + + Joomla\Component\Cronjobs + + Cronjobs + + From dfc7f3a95b2c8f12e543c9a668ca6b723f9d159d Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Sat, 3 Jul 2021 17:39:53 +0530 Subject: [PATCH 003/615] Add database tables Adds install, uninstall SQL scripts to create component tables. Updates manifest to match. --- .../components/com_cronjobs/cronjobs.xml | 14 ++++++ .../com_cronjobs/sql/mysql/install.sql | 39 +++++++++++++++ .../com_cronjobs/sql/mysql/uninstall.sql | 3 ++ .../com_cronjobs/sql/postgresql/install.sql | 48 +++++++++++++++++++ .../com_cronjobs/sql/postgresql/uninstall.sql | 6 +++ 5 files changed, 110 insertions(+) create mode 100644 administrator/components/com_cronjobs/sql/mysql/install.sql create mode 100644 administrator/components/com_cronjobs/sql/mysql/uninstall.sql create mode 100644 administrator/components/com_cronjobs/sql/postgresql/install.sql create mode 100644 administrator/components/com_cronjobs/sql/postgresql/uninstall.sql diff --git a/administrator/components/com_cronjobs/cronjobs.xml b/administrator/components/com_cronjobs/cronjobs.xml index 8dda0d5120970..28e480abf87af 100644 --- a/administrator/components/com_cronjobs/cronjobs.xml +++ b/administrator/components/com_cronjobs/cronjobs.xml @@ -9,6 +9,20 @@ COM_CRONJOBS_XML_DESCRIPTION Joomla\Component\Cronjobs + + + + sql/mysql/install.sql + sql/postgresql/install.sql + + + + + sql/mysql/uninstall.sql + sql/postgresql/uninstall.sql + + + Cronjobs diff --git a/administrator/components/com_cronjobs/sql/mysql/install.sql b/administrator/components/com_cronjobs/sql/mysql/install.sql new file mode 100644 index 0000000000000..165cd384aea35 --- /dev/null +++ b/administrator/components/com_cronjobs/sql/mysql/install.sql @@ -0,0 +1,39 @@ +-- Table Structure `#__cronjobs` [Main] + +CREATE TABLE IF NOT EXISTS `#__cronjobs` +( + `job_id` int(4) NOT NULL AUTO_INCREMENT, + `name` varchar(128) NOT NULL UNIQUE, + -- Job type. Can execute a script or plugin routine + `type` ENUM ('script', 'plugin') NOT NULL DEFAULT 'script', + -- Trigger type, default to PseudoCron (compatible everywhere). + `trigger` ENUM ('pseudoCron', 'cron', 'visit_count') NOT NULL DEFAULT 'pseudoCron' COMMENT 'Defines how job is triggered', + `enabled` BOOL NOT NULL DEFAULT FALSE, + `last_exit_code` INT(11) NOT NULL DEFAULT 0 COMMENT 'Exit code when job was last run', + `last_execution` DATETIME NOT NULL COMMENT 'Timestamp of when job was last run', + `next_execution` DATETIME NOT NULL COMMENT 'Timestamp of when job should next run, referred for execution on trigger', + `times_executed` INT(11) DEFAULT 0 COMMENT 'Count of times job has been triggered to run', + `times_failed` INT(11) DEFAULT 0 COMMENT 'Count of times job has failed', + `note` varchar(128), + PRIMARY KEY (job_id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 + DEFAULT COLLATE = utf8mb4_unicode_ci; + + +-- Table structure `#__cronjobs_scripts` + +CREATE TABLE IF NOT EXISTS `#__cronjobs_scripts` +( + `script_id` int(4) NOT NULL AUTO_INCREMENT, + `job_id` int(4) NOT NULL COMMENT 'Cronjob ID', + `directory` varchar(1024) NOT NULL, + `file` varchar(256) NOT NULL, + PRIMARY KEY (script_id), + FOREIGN KEY (job_id) REFERENCES `#__cronjobs` (job_id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 + DEFAULT COLLATE = utf8mb4_unicode_ci; + diff --git a/administrator/components/com_cronjobs/sql/mysql/uninstall.sql b/administrator/components/com_cronjobs/sql/mysql/uninstall.sql new file mode 100644 index 0000000000000..8d53a097f01fa --- /dev/null +++ b/administrator/components/com_cronjobs/sql/mysql/uninstall.sql @@ -0,0 +1,3 @@ +DROP TABLE IF EXISTS `#__cronjobs`; +DROP TABLE IF EXISTS `#__cronjobs_scripts`; +DROP TABLE IF EXISTS `#__cronjobs_plg`; -- Table TBD diff --git a/administrator/components/com_cronjobs/sql/postgresql/install.sql b/administrator/components/com_cronjobs/sql/postgresql/install.sql new file mode 100644 index 0000000000000..13a08d754a7c2 --- /dev/null +++ b/administrator/components/com_cronjobs/sql/postgresql/install.sql @@ -0,0 +1,48 @@ +------- Create required enumerated types with exception handling ---------- +DO +$$ + BEGIN + CREATE TYPE job_type AS ENUM ('script', 'plugin'); + EXCEPTION + WHEN duplicate_object THEN null; + END +$$; + +DO +$$ + BEGIN + CREATE TYPE trigger_type AS ENUM ('pseudoCron', 'cron', 'visit_count'); + EXCEPTION + WHEN duplicate_object THEN null; + END +$$; +--------------------------------------------------------------------------- + +-- Table Structure "#__cronjobs" [Main] -- + +CREATE TABLE IF NOT EXISTS "#__cronjobs" +( + "job_id" INT GENERATED ALWAYS AS IDENTITY, + "name" varchar(255) NOT NULL, + "type" job_type, + "trigger" trigger_type NOT NULL DEFAULT 'pseudoCron', + "enabled" boolean NOT NULL DEFAULT false, + "last_exit_code" int NOT NULL DEFAULT 0, + "last_execution" timestamp NOT NULL, + "next_execution" timestamp NOT NULL, + "times_executed" timestamp NOT NULL, + "times_failed" int DEFAULT 0, + "note" varchar(512) +); + +-- Table Structure "#__cronjobs_scripts" -- +CREATE TABLE IF NOT EXISTS "#cronjobs_scripts" +( + "script_id" INT GENERATED ALWAYS AS IDENTITY, + "job_id" INT, + "directory" varchar(256) NOT NULL, + "file" varchar(128) NOT NULL, + CONSTRAINT "job_id" + FOREIGN KEY (job_id) + REFERENCES "#__cronjobs" (job_id) +); diff --git a/administrator/components/com_cronjobs/sql/postgresql/uninstall.sql b/administrator/components/com_cronjobs/sql/postgresql/uninstall.sql new file mode 100644 index 0000000000000..19962f1f53a2b --- /dev/null +++ b/administrator/components/com_cronjobs/sql/postgresql/uninstall.sql @@ -0,0 +1,6 @@ +DROP TABLE IF EXISTS "#__cronjobs"; +DROP TABLE IF EXISTS "#__cronjobs_scripts"; +DROP TABLE IF EXISTS "#__cronjobs_plg"; -- Table TBD + +DROP TYPE IF EXISTS job_type CASCADE; +DROP TYPE IF EXISTS trigger_type CASCADE; From 642b4d9c6de0dc3edb3a092be8f26cc68c47a1c3 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Sat, 3 Jul 2021 19:08:53 +0530 Subject: [PATCH 004/615] Make type enum labels consistent --- administrator/components/com_cronjobs/sql/mysql/install.sql | 2 +- .../components/com_cronjobs/sql/postgresql/install.sql | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/administrator/components/com_cronjobs/sql/mysql/install.sql b/administrator/components/com_cronjobs/sql/mysql/install.sql index 165cd384aea35..bdc5a63567f37 100644 --- a/administrator/components/com_cronjobs/sql/mysql/install.sql +++ b/administrator/components/com_cronjobs/sql/mysql/install.sql @@ -7,7 +7,7 @@ CREATE TABLE IF NOT EXISTS `#__cronjobs` -- Job type. Can execute a script or plugin routine `type` ENUM ('script', 'plugin') NOT NULL DEFAULT 'script', -- Trigger type, default to PseudoCron (compatible everywhere). - `trigger` ENUM ('pseudoCron', 'cron', 'visit_count') NOT NULL DEFAULT 'pseudoCron' COMMENT 'Defines how job is triggered', + `trigger` ENUM ('pseudo_cron', 'cron', 'visit_count') NOT NULL DEFAULT 'pseudo_cron' COMMENT 'Defines how job is triggered', `enabled` BOOL NOT NULL DEFAULT FALSE, `last_exit_code` INT(11) NOT NULL DEFAULT 0 COMMENT 'Exit code when job was last run', `last_execution` DATETIME NOT NULL COMMENT 'Timestamp of when job was last run', diff --git a/administrator/components/com_cronjobs/sql/postgresql/install.sql b/administrator/components/com_cronjobs/sql/postgresql/install.sql index 13a08d754a7c2..f67ced5737d8c 100644 --- a/administrator/components/com_cronjobs/sql/postgresql/install.sql +++ b/administrator/components/com_cronjobs/sql/postgresql/install.sql @@ -11,7 +11,7 @@ $$; DO $$ BEGIN - CREATE TYPE trigger_type AS ENUM ('pseudoCron', 'cron', 'visit_count'); + CREATE TYPE trigger_type AS ENUM ('pseudo_cron', 'cron', 'visit_count'); EXCEPTION WHEN duplicate_object THEN null; END @@ -25,7 +25,7 @@ CREATE TABLE IF NOT EXISTS "#__cronjobs" "job_id" INT GENERATED ALWAYS AS IDENTITY, "name" varchar(255) NOT NULL, "type" job_type, - "trigger" trigger_type NOT NULL DEFAULT 'pseudoCron', + "trigger" trigger_type NOT NULL DEFAULT 'pseudo_cron', "enabled" boolean NOT NULL DEFAULT false, "last_exit_code" int NOT NULL DEFAULT 0, "last_execution" timestamp NOT NULL, From d56786c8646571ae2fe4e39e7ae60555222ba03e Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Sun, 4 Jul 2021 17:45:41 +0530 Subject: [PATCH 005/615] Add component initialisation file --- .../com_cronjobs/services/provider.php | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 administrator/components/com_cronjobs/services/provider.php diff --git a/administrator/components/com_cronjobs/services/provider.php b/administrator/components/com_cronjobs/services/provider.php new file mode 100644 index 0000000000000..dc0d5edf7d432 --- /dev/null +++ b/administrator/components/com_cronjobs/services/provider.php @@ -0,0 +1,66 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Dispatcher\ComponentDispatcherFactoryInterface; +use Joomla\CMS\Extension\ComponentInterface; +use Joomla\CMS\Extension\Service\Provider\ComponentDispatcherFactory; +use Joomla\CMS\Extension\Service\Provider\MVCFactory; +use Joomla\CMS\HTML\Registry; +use Joomla\CMS\MVC\Factory\MVCFactoryInterface; +use Joomla\Component\Cronjobs\Administrator\Extension\CronjobsComponent; +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; + +/** + * The cronjobs service provider. + * Returns an instance of the Component's Service Provider Interface + * used to register the components initializers into it's DI container + * created by Joomla. + * + * @since __DEPLOY_VERSION__ + */ +return new class implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function register(Container $container) + { + /* + * Register the MVCFactory and ComponentDispatcherFactory providers to map + * 'MVCFactoryInterface' and 'ComponentDispatcherFactoryInterface' to their + * initializers and register them with the component's DI container. + */ + $container->registerServiceProvider(new MVCFactory('\\Joomla\\Component\\Cronjobs')); + $container->registerServiceProvider(new ComponentDispatcherFactory('\\Joomla\\Component\\Cronjobs')); + + $container->set( + ComponentInterface::class, + function (Container $container) + { + $component = new CronjobsComponent($container->get(ComponentDispatcherFactoryInterface::class)); + + $component->setRegistry($container->get(Registry::class)); + $component->setMVCFactory($container->get(MVCFactoryInterface::class)); + + return $component; + } + ); + } +}; From a4cddf4c7c051799006567576f6348199665ffd8 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Sun, 4 Jul 2021 18:46:27 +0530 Subject: [PATCH 006/615] Add interval in main DB table Adds execution_interval column to main DB table and format install.sql files --- .../com_cronjobs/sql/mysql/install.sql | 27 ++++++++++--------- .../com_cronjobs/sql/postgresql/install.sql | 27 ++++++++++--------- 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/administrator/components/com_cronjobs/sql/mysql/install.sql b/administrator/components/com_cronjobs/sql/mysql/install.sql index bdc5a63567f37..a1aa8f7628f22 100644 --- a/administrator/components/com_cronjobs/sql/mysql/install.sql +++ b/administrator/components/com_cronjobs/sql/mysql/install.sql @@ -1,20 +1,21 @@ --- Table Structure `#__cronjobs` [Main] +-- Table Structure `#__cronjobs` [Main] -- CREATE TABLE IF NOT EXISTS `#__cronjobs` ( - `job_id` int(4) NOT NULL AUTO_INCREMENT, - `name` varchar(128) NOT NULL UNIQUE, + `job_id` int(4) NOT NULL AUTO_INCREMENT, + `name` varchar(128) NOT NULL UNIQUE, -- Job type. Can execute a script or plugin routine - `type` ENUM ('script', 'plugin') NOT NULL DEFAULT 'script', + `type` ENUM ('script', 'plugin') NOT NULL DEFAULT 'script', -- Trigger type, default to PseudoCron (compatible everywhere). - `trigger` ENUM ('pseudo_cron', 'cron', 'visit_count') NOT NULL DEFAULT 'pseudo_cron' COMMENT 'Defines how job is triggered', - `enabled` BOOL NOT NULL DEFAULT FALSE, - `last_exit_code` INT(11) NOT NULL DEFAULT 0 COMMENT 'Exit code when job was last run', - `last_execution` DATETIME NOT NULL COMMENT 'Timestamp of when job was last run', - `next_execution` DATETIME NOT NULL COMMENT 'Timestamp of when job should next run, referred for execution on trigger', - `times_executed` INT(11) DEFAULT 0 COMMENT 'Count of times job has been triggered to run', - `times_failed` INT(11) DEFAULT 0 COMMENT 'Count of times job has failed', - `note` varchar(128), + `trigger` ENUM ('pseudo_cron', 'cron', 'visit_count') NOT NULL DEFAULT 'pseudo_cron' COMMENT 'Defines how job is triggered', + `execution_interval` INT NOT NULL COMMENT 'Configured time between executions, in seconds', + `enabled` BOOL NOT NULL DEFAULT FALSE, + `last_exit_code` INT(11) NOT NULL DEFAULT 0 COMMENT 'Exit code when job was last run', + `last_execution` DATETIME NOT NULL COMMENT 'Timestamp of when job was last run', + `next_execution` DATETIME NOT NULL COMMENT 'Timestamp of when job should next run, referred for execution on trigger', + `times_executed` INT(11) DEFAULT 0 COMMENT 'Count of times job has been triggered to run', + `times_failed` INT(11) DEFAULT 0 COMMENT 'Count of times job has failed', + `note` varchar(128), PRIMARY KEY (job_id) ) ENGINE = InnoDB @@ -22,7 +23,7 @@ CREATE TABLE IF NOT EXISTS `#__cronjobs` DEFAULT COLLATE = utf8mb4_unicode_ci; --- Table structure `#__cronjobs_scripts` +-- Table structure `#__cronjobs_scripts` -- CREATE TABLE IF NOT EXISTS `#__cronjobs_scripts` ( diff --git a/administrator/components/com_cronjobs/sql/postgresql/install.sql b/administrator/components/com_cronjobs/sql/postgresql/install.sql index f67ced5737d8c..0c2c43d220c00 100644 --- a/administrator/components/com_cronjobs/sql/postgresql/install.sql +++ b/administrator/components/com_cronjobs/sql/postgresql/install.sql @@ -22,17 +22,18 @@ $$; CREATE TABLE IF NOT EXISTS "#__cronjobs" ( - "job_id" INT GENERATED ALWAYS AS IDENTITY, - "name" varchar(255) NOT NULL, - "type" job_type, - "trigger" trigger_type NOT NULL DEFAULT 'pseudo_cron', - "enabled" boolean NOT NULL DEFAULT false, - "last_exit_code" int NOT NULL DEFAULT 0, - "last_execution" timestamp NOT NULL, - "next_execution" timestamp NOT NULL, - "times_executed" timestamp NOT NULL, - "times_failed" int DEFAULT 0, - "note" varchar(512) + "job_id" INT GENERATED ALWAYS AS IDENTITY, + "name" VARCHAR(255) NOT NULL, + "type" JOB_TYPE, + "execution_interval" INT NOT NULL, + "trigger" TRIGGER_TYPE NOT NULL DEFAULT 'pseudo_cron', + "enabled" BOOLEAN NOT NULL DEFAULT false, + "last_exit_code" INT NOT NULL DEFAULT 0, + "last_execution" TIMESTAMP NOT NULL, + "next_execution" TIMESTAMP NOT NULL, + "times_executed" TIMESTAMP NOT NULL, + "times_failed" int DEFAULT 0, + "note" varchar(512) ); -- Table Structure "#__cronjobs_scripts" -- @@ -40,8 +41,8 @@ CREATE TABLE IF NOT EXISTS "#cronjobs_scripts" ( "script_id" INT GENERATED ALWAYS AS IDENTITY, "job_id" INT, - "directory" varchar(256) NOT NULL, - "file" varchar(128) NOT NULL, + "directory" VARCHAR(256) NOT NULL, + "file" VARCHAR(128) NOT NULL, CONSTRAINT "job_id" FOREIGN KEY (job_id) REFERENCES "#__cronjobs" (job_id) From 5dcd3847190bbe54dd18d131d5d3101cf5f5a6e6 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Sun, 4 Jul 2021 18:50:14 +0530 Subject: [PATCH 007/615] Add base CronjobsComponent class --- .../src/Extension/CronjobsComponent.php | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 administrator/components/com_cronjobs/src/Extension/CronjobsComponent.php diff --git a/administrator/components/com_cronjobs/src/Extension/CronjobsComponent.php b/administrator/components/com_cronjobs/src/Extension/CronjobsComponent.php new file mode 100644 index 0000000000000..641fc56509323 --- /dev/null +++ b/administrator/components/com_cronjobs/src/Extension/CronjobsComponent.php @@ -0,0 +1,37 @@ + Date: Sun, 4 Jul 2021 20:07:30 +0530 Subject: [PATCH 008/615] Add controller --- .../src/Controller/DisplayController.php | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 administrator/components/com_cronjobs/src/Controller/DisplayController.php diff --git a/administrator/components/com_cronjobs/src/Controller/DisplayController.php b/administrator/components/com_cronjobs/src/Controller/DisplayController.php new file mode 100644 index 0000000000000..dbda0e2b7887f --- /dev/null +++ b/administrator/components/com_cronjobs/src/Controller/DisplayController.php @@ -0,0 +1,51 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace Joomla\Component\Cronjobs\Administrator\Controller; + +// Restrict direct access +\defined('_JEXEC_') or die; + +use Exception; +use Joomla\CMS\MVC\Controller\BaseController; +use Joomla\CMS\MVC\Controller\ControllerInterface; + + +/** + * Default controller for com_cronjobs + * + * @since __DEPLOY_VERSION__ + */ +class DisplayController extends BaseController +{ + /** + * ! View 'cronjobs' has not been implemented yet + * + * @var string + * @since __DEPLOY_VERSION__ + */ + protected $default_view = 'cronjobs'; + + /** + * @param boolean $cachable If true, the view output will be cached + * @param array $urlparams An array of safe url parameters and their variable types, for valid values see {@link InputFilter::clean()}. + * + * @return BaseController + * + * @throws Exception + * @since __DEPLOY_VERSION__ + */ + public function display($cachable = false, $urlparams = array()) : ControllerInterface + { + // ! TODO + return parent::display($cachable, $urlparams); + } +} From b6e7edf68d211814108506a7607a7511fe53047b Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Sun, 4 Jul 2021 20:46:51 +0530 Subject: [PATCH 009/615] Add file doc comment to CronjobsComponents.php --- .../src/Extension/CronjobsComponent.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Extension/CronjobsComponent.php b/administrator/components/com_cronjobs/src/Extension/CronjobsComponent.php index 641fc56509323..34c7e8c2532b6 100644 --- a/administrator/components/com_cronjobs/src/Extension/CronjobsComponent.php +++ b/administrator/components/com_cronjobs/src/Extension/CronjobsComponent.php @@ -1,4 +1,13 @@ + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ namespace Joomla\Component\Cronjobs\Administrator\Extension; @@ -24,13 +33,13 @@ class CronjobsComponent extends MVCComponent implements BootableExtensionInterfa * If required, some initial set up can be done from services of the container, eg. * registering HTML services. * - * @param ContainerInterface $container The container + * @param ContainerInterface $container The container * * @return void * * @since __DEPLOY_VERSION__ */ - public function boot(ContainerInterface $container) : void + public function boot(ContainerInterface $container): void { // Pass } From 394028759542e3706b450e09c893a0d02ae33b21 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Sun, 4 Jul 2021 22:20:41 +0530 Subject: [PATCH 010/615] Add en-GB language files --- .../components/com_cronjobs/language/en-GB/com_cronjobs.ini | 6 ++++++ .../com_cronjobs/language/en-GB/com_cronjobs.sys.ini | 6 ++++++ 2 files changed, 12 insertions(+) create mode 100644 administrator/components/com_cronjobs/language/en-GB/com_cronjobs.ini create mode 100644 administrator/components/com_cronjobs/language/en-GB/com_cronjobs.sys.ini diff --git a/administrator/components/com_cronjobs/language/en-GB/com_cronjobs.ini b/administrator/components/com_cronjobs/language/en-GB/com_cronjobs.ini new file mode 100644 index 0000000000000..ffa9fe2b92998 --- /dev/null +++ b/administrator/components/com_cronjobs/language/en-GB/com_cronjobs.ini @@ -0,0 +1,6 @@ +; Joomla! Project +; (C) 2021 Open Source Matters, Inc. +; GPL v3 + +COM_CRONJOBS="Cronjobs" +COM_CRONJOBS_XML_DESCRIPTION="Component for managing pseudo-cronjobs and cronjobs (if server supports)" diff --git a/administrator/components/com_cronjobs/language/en-GB/com_cronjobs.sys.ini b/administrator/components/com_cronjobs/language/en-GB/com_cronjobs.sys.ini new file mode 100644 index 0000000000000..ffa9fe2b92998 --- /dev/null +++ b/administrator/components/com_cronjobs/language/en-GB/com_cronjobs.sys.ini @@ -0,0 +1,6 @@ +; Joomla! Project +; (C) 2021 Open Source Matters, Inc. +; GPL v3 + +COM_CRONJOBS="Cronjobs" +COM_CRONJOBS_XML_DESCRIPTION="Component for managing pseudo-cronjobs and cronjobs (if server supports)" From 4db8ce4ed2299103ce93dfe7473a1bab3ab7f639 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Sun, 4 Jul 2021 22:21:09 +0530 Subject: [PATCH 011/615] Update manifest --- administrator/components/com_cronjobs/cronjobs.xml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/administrator/components/com_cronjobs/cronjobs.xml b/administrator/components/com_cronjobs/cronjobs.xml index 28e480abf87af..23196aa9df069 100644 --- a/administrator/components/com_cronjobs/cronjobs.xml +++ b/administrator/components/com_cronjobs/cronjobs.xml @@ -1,8 +1,8 @@ - Cronjobs + com_cronjob July 2021 - Ditsuke + Joomla! Project GPL v3 0.0.0 @@ -25,5 +25,12 @@ Cronjobs + + language/en-GB/com_cronjobs.ini + language/en-GB/com_cronjobs.sys.ini + + + cronjobs + From 243579331ea977f1507858db106225a21b2ff973 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Sun, 4 Jul 2021 22:39:47 +0530 Subject: [PATCH 012/615] Fix typo in manifest --- administrator/components/com_cronjobs/cronjobs.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/administrator/components/com_cronjobs/cronjobs.xml b/administrator/components/com_cronjobs/cronjobs.xml index 23196aa9df069..827793de1cf03 100644 --- a/administrator/components/com_cronjobs/cronjobs.xml +++ b/administrator/components/com_cronjobs/cronjobs.xml @@ -1,6 +1,6 @@ - com_cronjob + com_cronjobs July 2021 Joomla! Project GPL v3 @@ -19,7 +19,7 @@ sql/mysql/uninstall.sql - sql/postgresql/uninstall.sql + sql/postgresql/uninstall.sql From b2f1d9462182148d687471d90133acf7e0c86478 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Mon, 5 Jul 2021 03:36:15 +0530 Subject: [PATCH 013/615] Lay out the MVC to deal with single entries Adds a base for MVC classes meant to handle single 'Cronjob' entries. --- .../src/Controller/CronjobController.php | 25 +++++++ .../com_cronjobs/src/Model/CronjobModel.php | 27 ++++++++ .../src/View/Cronjob/HtmlView.php | 66 +++++++++++++++++++ 3 files changed, 118 insertions(+) create mode 100644 administrator/components/com_cronjobs/src/Controller/CronjobController.php create mode 100644 administrator/components/com_cronjobs/src/Model/CronjobModel.php create mode 100644 administrator/components/com_cronjobs/src/View/Cronjob/HtmlView.php diff --git a/administrator/components/com_cronjobs/src/Controller/CronjobController.php b/administrator/components/com_cronjobs/src/Controller/CronjobController.php new file mode 100644 index 0000000000000..c4f1f58d1eb2e --- /dev/null +++ b/administrator/components/com_cronjobs/src/Controller/CronjobController.php @@ -0,0 +1,25 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// Restrict direct access +\defined('_JEXEC') or die; + +use Joomla\CMS\MVC\Controller\FormController; + +/** + * The CronjobModel controller. + * + * @since __DEPLOY_VERSION__ + */ +class CronjobController extends FormController +{ + // ! TODO +} diff --git a/administrator/components/com_cronjobs/src/Model/CronjobModel.php b/administrator/components/com_cronjobs/src/Model/CronjobModel.php new file mode 100644 index 0000000000000..07c49abba42c4 --- /dev/null +++ b/administrator/components/com_cronjobs/src/Model/CronjobModel.php @@ -0,0 +1,27 @@ + + * @license GPL v3 + */ + +namespace Joomla\Component\Cronjobs\Administrator\Model; + +// Restrict direct access +\defined('_JEXEC_') or die; + +use Joomla\CMS\MVC\Model\AdminModel; + +/** + * MVC Model to deal operations concerning a single 'Cronjob' entry. + * + * @since __DEPLOY_VERSION__ + */ +class CronjobModel extends AdminModel +{ + // ! TODO +} diff --git a/administrator/components/com_cronjobs/src/View/Cronjob/HtmlView.php b/administrator/components/com_cronjobs/src/View/Cronjob/HtmlView.php new file mode 100644 index 0000000000000..5ff8a6b5a8a36 --- /dev/null +++ b/administrator/components/com_cronjobs/src/View/Cronjob/HtmlView.php @@ -0,0 +1,66 @@ + + * @license GPL v3 + */ + +namespace Joomla\Component\Cronjobs\Administrator\View\Cronjob; + +// Restrict direct access +\defined('_JEXEC_') or die; + +use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView; + +/** + * The MVC View AddCronjob + * + * @package Joomla.Administrator + * @subpackage com_cronjobs + * + * @since __DEPLOY_VERSION__ + */ +class HtmlView extends BaseHtmlView +{ + /** + * The Form object + * + * @var \JForm + * @since __DEPLOY__VERSION__ + */ + protected $form; + + /** + * The active item + * + * @var object + * @since __DEPLOY__VERSION__ + */ + protected $item; + + /** + * The model state + * + * @var \JObject + * @since __DEPLOY__VERSION__ + */ + protected $state; + + + /** + * @param string $tpl The name of the template file to parse; automatically searches through the template paths. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function display($tpl = null) : void + { + // ! TODO + } + +} From f390e33a3929cbef9287e38d69a2ba4e5aaf92ec Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Mon, 5 Jul 2021 03:40:01 +0530 Subject: [PATCH 014/615] Lay out the MVC to deal with multiple entries Adds a base for MVC classes meant to handle multiple 'Cronjob' entries. --- .../src/Controller/CronjobsController.php | 25 +++++++ .../com_cronjobs/src/Model/CronjobsModel.php | 27 ++++++++ .../src/View/Cronjobs/HtmlView.php | 66 +++++++++++++++++++ 3 files changed, 118 insertions(+) create mode 100644 administrator/components/com_cronjobs/src/Controller/CronjobsController.php create mode 100644 administrator/components/com_cronjobs/src/Model/CronjobsModel.php create mode 100644 administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php diff --git a/administrator/components/com_cronjobs/src/Controller/CronjobsController.php b/administrator/components/com_cronjobs/src/Controller/CronjobsController.php new file mode 100644 index 0000000000000..695524a406cd9 --- /dev/null +++ b/administrator/components/com_cronjobs/src/Controller/CronjobsController.php @@ -0,0 +1,25 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +// Restrict direct access +\defined('_JEXEC') or die; + +use Joomla\CMS\MVC\Controller\AdminController; + +/** + * The CronjobsModel controller. + * + * @since __DEPLOY_VERSION__ + */ +class CronjobsController extends AdminController +{ + // ! TODO +} diff --git a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php new file mode 100644 index 0000000000000..1cde1dbb1a27b --- /dev/null +++ b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php @@ -0,0 +1,27 @@ + + * @license GPL v3 + */ + +namespace Joomla\Component\Cronjobs\Administrator\Model; + +// Restrict direct access +\defined('_JEXEC_') or die; + +use Joomla\CMS\MVC\Model\ListModel; + +/** + * MVC Model to deal with operations concerning multiple 'Cronjob' entries. + * + * @since __DEPLOY_VERSION__ + */ +class CronjobsModel extends ListModel +{ + // ! TODO +} diff --git a/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php b/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php new file mode 100644 index 0000000000000..6798385a09418 --- /dev/null +++ b/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php @@ -0,0 +1,66 @@ + + * @license GPL v3 + */ + +namespace Joomla\Component\Cronjobs\Administrator\View\Cronjobs; + +// Restrict direct access +\defined('_JEXEC_') or die; + +use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView; + +/** + * The MVC View AddCronjob + * + * @package Joomla.Administrator + * @subpackage com_cronjobs + * + * @since __DEPLOY_VERSION__ + */ +class HtmlView extends BaseHtmlView +{ + /** + * The Form object + * + * @var \JForm + * @since __DEPLOY__VERSION__ + */ + protected $form; + + /** + * The active item + * + * @var object + * @since __DEPLOY__VERSION__ + */ + protected $item; + + /** + * The model state + * + * @var \JObject + * @since __DEPLOY__VERSION__ + */ + protected $state; + + + /** + * @param string $tpl The name of the template file to parse; automatically searches through the template paths. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function display($tpl = null) : void + { + // ! TODO + } + +} From 56460a9d7b27add48cf04fc1026312af08fd8345 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Wed, 7 Jul 2021 12:21:08 +0530 Subject: [PATCH 015/615] Add View SelectPlugin Does nothing yet --- .../src/View/SelectPlugin/HtmlView.php | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 administrator/components/com_cronjobs/src/View/SelectPlugin/HtmlView.php diff --git a/administrator/components/com_cronjobs/src/View/SelectPlugin/HtmlView.php b/administrator/components/com_cronjobs/src/View/SelectPlugin/HtmlView.php new file mode 100644 index 0000000000000..fc048d7ddf8da --- /dev/null +++ b/administrator/components/com_cronjobs/src/View/SelectPlugin/HtmlView.php @@ -0,0 +1,67 @@ + + * @license GPL v3 + */ + +namespace Joomla\Component\Cronjobs\Administrator\View\SelectPlugin; + +// Restrict direct access +\defined('_JEXEC_') or die; + +use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView; + +/** + * The MVC View SelectPlugin + * Should let the user choose a plugin from installed Cronjob supporting ones + * + * @package Joomla.Administrator + * @subpackage com_cronjobs + * + * @since __DEPLOY_VERSION__ + */ +class HtmlView extends BaseHtmlView +{ + /** + * The Form object + * + * @var \JForm + * @since __DEPLOY__VERSION__ + */ + protected $form; + + /** + * The active item + * + * @var object + * @since __DEPLOY__VERSION__ + */ + protected $item; + + /** + * The model state + * + * @var \JObject + * @since __DEPLOY__VERSION__ + */ + protected $state; + + + /** + * @param string $tpl The name of the template file to parse; automatically searches through the template paths. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function display($tpl = null) : void + { + // ! TODO + } + +} From 38d3c56f95441e2d3fadfb7882c9f08b1a768284 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Wed, 7 Jul 2021 15:46:43 +0530 Subject: [PATCH 016/615] Update DisplayController --- .../src/Controller/DisplayController.php | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Controller/DisplayController.php b/administrator/components/com_cronjobs/src/Controller/DisplayController.php index dbda0e2b7887f..59f167d287042 100644 --- a/administrator/components/com_cronjobs/src/Controller/DisplayController.php +++ b/administrator/components/com_cronjobs/src/Controller/DisplayController.php @@ -17,6 +17,9 @@ use Exception; use Joomla\CMS\MVC\Controller\BaseController; use Joomla\CMS\MVC\Controller\ControllerInterface; +use Joomla\CMS\Language\Text; +use Joomla\CMS\Router\Route; +use Joomla\CMS\Uri\Uri; /** @@ -24,6 +27,7 @@ * * @since __DEPLOY_VERSION__ */ + class DisplayController extends BaseController { /** @@ -38,14 +42,31 @@ class DisplayController extends BaseController * @param boolean $cachable If true, the view output will be cached * @param array $urlparams An array of safe url parameters and their variable types, for valid values see {@link InputFilter::clean()}. * - * @return BaseController + * @return BaseController|boolean Returns either this object itself, to support chaining, or false on failure. * * @throws Exception * @since __DEPLOY_VERSION__ */ - public function display($cachable = false, $urlparams = array()) : ControllerInterface + public function display($cachable = false, $urlparams = array()) { - // ! TODO + // ! Untested + $layout = $this->input->get('layout', 'edit'); + $id = $this->input->getInt('id'); + + // Check for edit form. + if ($layout == 'edit' && !$this->checkEditId('com_cronjobs.edit.module', $id)) + { + // Somehow the person just went to the form - we don't allow that. + if (!\count($this->app->getMessageQueue())) + { + $this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id), 'error'); + } + + $this->setRedirect(Route::_('index.php?option=com_cronjobs&view=cronjobs')); + + return false; + } + return parent::display($cachable, $urlparams); } } From a0ec65bc62c5e3460dce2a85ff0e2ae65692d0ec Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Wed, 7 Jul 2021 20:40:31 +0530 Subject: [PATCH 017/615] Add ACL file --- administrator/components/com_cronjobs/access.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 administrator/components/com_cronjobs/access.xml diff --git a/administrator/components/com_cronjobs/access.xml b/administrator/components/com_cronjobs/access.xml new file mode 100644 index 0000000000000..ad157daad76cc --- /dev/null +++ b/administrator/components/com_cronjobs/access.xml @@ -0,0 +1,12 @@ + + +
+ + + + + + + +
+
From f6f9fe17b8a1f3cf6ad8ad7c9f1d03a9774b6b4e Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Wed, 7 Jul 2021 23:22:26 +0530 Subject: [PATCH 018/615] Implement CronjobsModel Missing filter queries and access to all db fields at the moment. --- .../com_cronjobs/src/Model/CronjobsModel.php | 125 +++++++++++++++++- 1 file changed, 120 insertions(+), 5 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php index 1cde1dbb1a27b..5a15ce1013711 100644 --- a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php +++ b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php @@ -1,20 +1,28 @@ - * @license GPL v3 + * @license GPL v3 */ namespace Joomla\Component\Cronjobs\Administrator\Model; // Restrict direct access -\defined('_JEXEC_') or die; +defined('_JEXEC') or die; +use Exception; +use Joomla\CMS\Factory; +use Joomla\CMS\MVC\Factory\MVCFactoryInterface; use Joomla\CMS\MVC\Model\ListModel; +use Joomla\Database\QueryInterface; + +use function defined; /** * MVC Model to deal with operations concerning multiple 'Cronjob' entries. @@ -23,5 +31,112 @@ */ class CronjobsModel extends ListModel { - // ! TODO + /** + * Constructor. + * + * @param array $config An optional associative array of configuration settings. + * + * @param MVCFactoryInterface|null $factory The factory. + * + * @throws Exception + * @since __DEPLOY_VERSION__ + * @see \JControllerLegacy + */ + public function __construct($config = array(), MVCFactoryInterface $factory = null) + { + if (empty($config['filter_fields'])) + { + // ! TODO: Doesn't set everything yet + $config['filter_fields'] = array( + 'job_id', + 'a.job_id', + + 'name', + 'a.name', + + 'type', + 'a.type', + + 'trigger', + 'a.trigger', + + 'execution_interval', + 'a.execution_interval', + + 'enabled', + 'a.enabled' + ); + } + + parent::__construct($config, $factory); + } + + /** + * Method to get an array of data items. + * + * @return mixed An array of data items on success, false on failure. + * + * @since __DEPLOY_VERSION__ + */ + public function getItems() + { + return parent::getItems(); + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string A store id. + * + * @since __DEPLOY_VERSION__ + */ + protected function getStoreId($id = ''): string + { + // Compile the store id. + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.enabled'); + $id .= ':' . $this->getState('filter.job_type'); + + return parent::getStoreId($id); + } + + /** + * Method to create a query for a list of items. + * + * @return QueryInterface + * + * @throws Exception + * @since __DEPLOY_VERSION__ + */ + // ⚠ No filters at the moment ⚠ + protected function getListQuery(): QueryInterface + { + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + $user = Factory::getApplication()->getIdentity(); + + // Select the required fields from the table. + // TODO : Should add a "created_by" column to `#__cronjobs` + $query->select( + $this->getState( + 'list.select', + 'a.job_id, a.name, a.type, a.trigger, a.execution_interval, a.enabled, a.last_exit_code' . + ', a.next_execution, a.times_executed, a.times_failed' + ) + ); + + $query->from($db->quoteName('#__cronjobs', 'a')); + + // TODO : Implement filters here + + return $query; + } + } From be6caf4176a992724d00faa33ef8ad716cf08dbc Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Wed, 7 Jul 2021 23:42:04 +0530 Subject: [PATCH 019/615] Implement Cronjobs View Likely to be incomplete or buggy but seems to call the template with the right data. --- .../src/View/Cronjobs/HtmlView.php | 188 ++++++++++++++++-- 1 file changed, 170 insertions(+), 18 deletions(-) diff --git a/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php b/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php index 6798385a09418..01c469202920c 100644 --- a/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php +++ b/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php @@ -2,19 +2,28 @@ /** * Declares the MVC View for CronjobsModel. * - * @package Joomla.Administrator - * @subpackage com_cronjobs + * @package Joomla.Administrator + * @subpackage com_cronjobs * * @copyright (C) 2021 Open Source Matters, Inc. - * @license GPL v3 + * @license GPL v3 */ namespace Joomla\Component\Cronjobs\Administrator\View\Cronjobs; // Restrict direct access -\defined('_JEXEC_') or die; +\defined('_JEXEC') or die; +use Exception; +use JObject; +use Joomla\CMS\Factory; +use Joomla\CMS\Helper\ContentHelper; +use Joomla\CMS\MVC\View\GenericDataException; use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView; +use Joomla\CMS\Pagination\Pagination; +use Joomla\CMS\Toolbar\Toolbar; +use Joomla\CMS\Toolbar\ToolbarHelper; +use Joomla\CMS\Language\Text; /** * The MVC View AddCronjob @@ -22,45 +31,188 @@ * @package Joomla.Administrator * @subpackage com_cronjobs * - * @since __DEPLOY_VERSION__ + * @since __DEPLOY_VERSION__ */ class HtmlView extends BaseHtmlView { /** - * The Form object + * An array of items * - * @var \JForm - * @since __DEPLOY__VERSION__ + * @var array + * @since __DEPLOY_VERSION__ */ - protected $form; + protected $items; /** - * The active item + * The pagination object * - * @var object - * @since __DEPLOY__VERSION__ + * @var Pagination + * @since __DEPLOY_VERSION__ */ - protected $item; + protected $pagination; /** * The model state * - * @var \JObject - * @since __DEPLOY__VERSION__ + * @var JObject + * @since __DEPLOY_VERSION__ */ protected $state; + /** + * Form object for search filters + * + * @var \JForm + * @since __DEPLOY_VERSION__ + */ + public $filterForm; + + /** + * The active search filters + * + * @var array + * @since 4.0.0 + */ + public $activeFilters; + + /** + * Is this view an Empty State + * + * @var boolean + * @since 4.0.0 + */ + private $isEmptyState = false; + + /** + * Execute and display a template script. + * + * @param string $tpl The name of the template file to parse; automatically searches through the template paths. + * + * @return mixed A string if successful, otherwise an Error object. + */ + /** * @param string $tpl The name of the template file to parse; automatically searches through the template paths. * * @return void * - * @since __DEPLOY_VERSION__ + * @throws Exception + * + * @since __DEPLOY_VERSION__ */ - public function display($tpl = null) : void + public function display($tpl = null): void { - // ! TODO + // ! TODO : testing + + $this->items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + if (!\count($this->items) && $this->isEmptyState = $this->get('IsEmptyState')) + { + $this->setLayout('empty_state'); + } + + // Check for errors. + if (\count($errors = $this->get('Errors'))) + { + throw new GenericDataException(implode("\n", $errors), 500); + } + + // We don't need toolbar in the modal window. + if ($this->getLayout() !== 'modal') + { + $this->addToolbar(); + } + + parent::display($tpl); } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @throws Exception + * + * @since __DEPLOY_VERSION__ + */ + protected function addToolbar(): void + { + // TODO: eval $canDo('core.delete') + $canDo = ContentHelper::getActions('com_cronjobs'); + $user = Factory::getApplication()->getIdentity(); + + /* + * Get the toolbar object instance + * !! TODO : Replace usage with ToolbarFactoryInterface + */ + $toolbar = Toolbar::getInstance('toolbar'); + + // TODO : 'cronjobs' icon + ToolbarHelper::title(Text::_('COM_CRONJOBS_MANAGER_CRONJOBS'), 'tags'); + + + if ($canDo->get('core.create')) + { + $toolbar->addNew('cronjob.add'); + } + + if (!$this->isEmptyState && ($canDo->get('core.edit.state') || $user->authorise('core.admin'))) + { + $dropdown = $toolbar->dropdownButton('status-group') + ->text('JTOOLBAR_CHANGE_STATUS') + ->toggleSplit(false) + ->icon('icon-ellipsis-h') + ->buttonClass('btn btn-action') + ->listCheck(true); + + $childBar = $dropdown->getChildToolbar(); + + if ($canDo->get('core.edit.state')) + { + $childBar->publish('cronjob.enable')->listCheck(true); + $childBar->unpublish('cronjob.disable')->listCheck(true); + $childBar->archive('cronjob.delete')->listCheck(true); + } + + /* + * TODO: Remove this + * This is probably unneeded + */ + if ($canDo->get('core.edit.state') && $this->state->get('filter.published') != -2) + { + $childBar->trash('cronjobs.trash')->listCheck(true); + } + + // Add a batch button + if ($canDo->get('core.create') && $canDo->get('core.edit') && $canDo->get('core.edit.state')) + { + $childBar->popupButton('batch') + ->text('JTOOLBAR_BATCH') + ->selector('collapseModal') + ->listCheck(true); + } + } + + // TODO: Check states + if ($this->state->get('filter.enabled') == 0 && $canDo->get('core.delete')) + { + $toolbar->delete('cronjobs.delete') + ->text('JTOOLBAR_EMPTY_TRASH') + ->message('JGLOBAL_CONFIRM_DELETE') + ->listCheck(true); + } + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + $toolbar->preferences('com_cronjobs'); + } + + $toolbar->help('JHELP_COMPONENTS_CRONJOBS_MANAGER'); + } } From 71d9d2892368af6616d9a8569f6461cd6345b8fb Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Thu, 8 Jul 2021 00:32:19 +0530 Subject: [PATCH 020/615] Update manifest and other fixes Fixes version in manifest, _JEXEC typos (cause of much headache) and changes the default view's layout in the DisplayController. Also fixes the codestyle. Oops! :p --- .../components/com_cronjobs/cronjobs.xml | 2 +- .../com_cronjobs/services/provider.php | 29 +++++----- .../src/Controller/DisplayController.php | 20 +++---- .../src/Extension/CronjobsComponent.php | 17 +++--- .../com_cronjobs/src/Model/CronjobsModel.php | 55 +++++++++--------- .../src/View/Cronjobs/HtmlView.php | 57 +++++++++---------- .../src/View/SelectPlugin/HtmlView.php | 20 +++---- 7 files changed, 100 insertions(+), 100 deletions(-) diff --git a/administrator/components/com_cronjobs/cronjobs.xml b/administrator/components/com_cronjobs/cronjobs.xml index 827793de1cf03..62e307ac5eda4 100644 --- a/administrator/components/com_cronjobs/cronjobs.xml +++ b/administrator/components/com_cronjobs/cronjobs.xml @@ -4,7 +4,7 @@ July 2021 Joomla! Project GPL v3 - 0.0.0 + 4.0.0 COM_CRONJOBS_XML_DESCRIPTION diff --git a/administrator/components/com_cronjobs/services/provider.php b/administrator/components/com_cronjobs/services/provider.php index dc0d5edf7d432..258738b7e3f2a 100644 --- a/administrator/components/com_cronjobs/services/provider.php +++ b/administrator/components/com_cronjobs/services/provider.php @@ -2,11 +2,11 @@ /** * Declares how component is to be initialised. * - * @package Joomla.Administrator - * @subpackage com_cronjobs + * @package Joomla.Administrator + * @subpackage com_cronjobs * - * @copyright (C) 2021 Open Source Matters, Inc. - * @license GNU General Public License version 2 or later; see LICENSE.txt + * @copyright (C) 2021 Open Source Matters, Inc. + * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; @@ -27,33 +27,32 @@ * used to register the components initializers into it's DI container * created by Joomla. * - * @since __DEPLOY_VERSION__ + * @since __DEPLOY_VERSION__ */ return new class implements ServiceProviderInterface { /** * Registers the service provider with a DI container. * - * @param Container $container The DI container. + * @param Container $container The DI container. * - * @return void + * @return void * - * @since __DEPLOY_VERSION__ + * @since __DEPLOY_VERSION__ */ public function register(Container $container) { - /* - * Register the MVCFactory and ComponentDispatcherFactory providers to map - * 'MVCFactoryInterface' and 'ComponentDispatcherFactoryInterface' to their - * initializers and register them with the component's DI container. - */ + /* + * Register the MVCFactory and ComponentDispatcherFactory providers to map + * 'MVCFactoryInterface' and 'ComponentDispatcherFactoryInterface' to their + * initializers and register them with the component's DI container. + */ $container->registerServiceProvider(new MVCFactory('\\Joomla\\Component\\Cronjobs')); $container->registerServiceProvider(new ComponentDispatcherFactory('\\Joomla\\Component\\Cronjobs')); $container->set( ComponentInterface::class, - function (Container $container) - { + function (Container $container) { $component = new CronjobsComponent($container->get(ComponentDispatcherFactoryInterface::class)); $component->setRegistry($container->get(Registry::class)); diff --git a/administrator/components/com_cronjobs/src/Controller/DisplayController.php b/administrator/components/com_cronjobs/src/Controller/DisplayController.php index 59f167d287042..b6bd9e688c5f4 100644 --- a/administrator/components/com_cronjobs/src/Controller/DisplayController.php +++ b/administrator/components/com_cronjobs/src/Controller/DisplayController.php @@ -2,17 +2,17 @@ /** * Declares the default display controller for com_cronjobs * - * @package Joomla.Administrator - * @subpackage com_cronjobs + * @package Joomla.Administrator + * @subpackage com_cronjobs * - * @copyright (C) 2021 Open Source Matters, Inc. - * @license GNU General Public License version 2 or later; see LICENSE.txt + * @copyright (C) 2021 Open Source Matters, Inc. + * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Component\Cronjobs\Administrator\Controller; // Restrict direct access -\defined('_JEXEC_') or die; +\defined('_JEXEC') or die; use Exception; use Joomla\CMS\MVC\Controller\BaseController; @@ -33,24 +33,24 @@ class DisplayController extends BaseController /** * ! View 'cronjobs' has not been implemented yet * - * @var string + * @var string * @since __DEPLOY_VERSION__ */ protected $default_view = 'cronjobs'; /** - * @param boolean $cachable If true, the view output will be cached - * @param array $urlparams An array of safe url parameters and their variable types, for valid values see {@link InputFilter::clean()}. + * @param boolean $cachable If true, the view output will be cached + * @param array $urlparams An array of safe url parameters and their variable types, for valid values see {@link InputFilter::clean()}. * * @return BaseController|boolean Returns either this object itself, to support chaining, or false on failure. * * @throws Exception - * @since __DEPLOY_VERSION__ + * @since __DEPLOY_VERSION__ */ public function display($cachable = false, $urlparams = array()) { // ! Untested - $layout = $this->input->get('layout', 'edit'); + $layout = $this->input->get('layout', 'default'); $id = $this->input->getInt('id'); // Check for edit form. diff --git a/administrator/components/com_cronjobs/src/Extension/CronjobsComponent.php b/administrator/components/com_cronjobs/src/Extension/CronjobsComponent.php index 34c7e8c2532b6..3aef8fc5662b5 100644 --- a/administrator/components/com_cronjobs/src/Extension/CronjobsComponent.php +++ b/administrator/components/com_cronjobs/src/Extension/CronjobsComponent.php @@ -2,15 +2,18 @@ /** * Implements the main component class * - * @package Joomla.Administrator - * @subpackage com_cronjobs + * @package Joomla.Administrator + * @subpackage com_cronjobs * - * @copyright (C) 2021 Open Source Matters, Inc. - * @license GNU General Public License version 2 or later; see LICENSE.txt + * @copyright (C) 2021 Open Source Matters, Inc. + * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Component\Cronjobs\Administrator\Extension; +// Restrict direct access +\defined('_JEXEC') or die; + use Joomla\CMS\Extension\BootableExtensionInterface; use Joomla\CMS\Extension\MVCComponent; use Joomla\CMS\HTML\HTMLRegistryAwareTrait; @@ -33,11 +36,11 @@ class CronjobsComponent extends MVCComponent implements BootableExtensionInterfa * If required, some initial set up can be done from services of the container, eg. * registering HTML services. * - * @param ContainerInterface $container The container + * @param ContainerInterface $container The container * - * @return void + * @return void * - * @since __DEPLOY_VERSION__ + * @since __DEPLOY_VERSION__ */ public function boot(ContainerInterface $container): void { diff --git a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php index 5a15ce1013711..1843ea88048cd 100644 --- a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php +++ b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php @@ -4,11 +4,11 @@ * TODO: Implement query filters in $GetListQuery() * TODO: Complete $config['filter_fields'] * - * @package Joomla.Administrator - * @subpackage com_cronjobs + * @package Joomla.Administrator + * @subpackage com_cronjobs * - * @copyright (C) 2021 Open Source Matters, Inc. - * @license GPL v3 + * @copyright (C) 2021 Open Source Matters, Inc. + * @license GPL v3 */ namespace Joomla\Component\Cronjobs\Administrator\Model; @@ -34,11 +34,11 @@ class CronjobsModel extends ListModel /** * Constructor. * - * @param array $config An optional associative array of configuration settings. + * @param array $config An optional associative array of configuration settings. * - * @param MVCFactoryInterface|null $factory The factory. + * @param MVCFactoryInterface|null $factory The factory. * - * @throws Exception + * @throws Exception * @since __DEPLOY_VERSION__ * @see \JControllerLegacy */ @@ -48,23 +48,23 @@ public function __construct($config = array(), MVCFactoryInterface $factory = nu { // ! TODO: Doesn't set everything yet $config['filter_fields'] = array( - 'job_id', - 'a.job_id', + 'job_id', + 'a.job_id', - 'name', - 'a.name', + 'name', + 'a.name', - 'type', - 'a.type', + 'type', + 'a.type', - 'trigger', - 'a.trigger', + 'trigger', + 'a.trigger', - 'execution_interval', - 'a.execution_interval', + 'execution_interval', + 'a.execution_interval', - 'enabled', - 'a.enabled' + 'enabled', + 'a.enabled' ); } @@ -74,9 +74,9 @@ public function __construct($config = array(), MVCFactoryInterface $factory = nu /** * Method to get an array of data items. * - * @return mixed An array of data items on success, false on failure. + * @return mixed An array of data items on success, false on failure. * - * @since __DEPLOY_VERSION__ + * @since __DEPLOY_VERSION__ */ public function getItems() { @@ -90,11 +90,11 @@ public function getItems() * different modules that might need different sets of data or different * ordering requirements. * - * @param string $id A prefix for the store id. + * @param string $id A prefix for the store id. * - * @return string A store id. + * @return string A store id. * - * @since __DEPLOY_VERSION__ + * @since __DEPLOY_VERSION__ */ protected function getStoreId($id = ''): string { @@ -108,13 +108,12 @@ protected function getStoreId($id = ''): string /** * Method to create a query for a list of items. + * ! No filters at the moment ⚠ + * @return QueryInterface * - * @return QueryInterface - * - * @throws Exception + * @throws Exception * @since __DEPLOY_VERSION__ */ - // ⚠ No filters at the moment ⚠ protected function getListQuery(): QueryInterface { // Create a new query object. diff --git a/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php b/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php index 01c469202920c..22a6599e169e6 100644 --- a/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php +++ b/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php @@ -2,11 +2,11 @@ /** * Declares the MVC View for CronjobsModel. * - * @package Joomla.Administrator - * @subpackage com_cronjobs + * @package Joomla.Administrator + * @subpackage com_cronjobs * - * @copyright (C) 2021 Open Source Matters, Inc. - * @license GPL v3 + * @copyright (C) 2021 Open Source Matters, Inc. + * @license GPL v3 */ namespace Joomla\Component\Cronjobs\Administrator\View\Cronjobs; @@ -31,14 +31,14 @@ * @package Joomla.Administrator * @subpackage com_cronjobs * - * @since __DEPLOY_VERSION__ + * @since __DEPLOY_VERSION__ */ class HtmlView extends BaseHtmlView { /** * An array of items * - * @var array + * @var array * @since __DEPLOY_VERSION__ */ protected $items; @@ -46,7 +46,7 @@ class HtmlView extends BaseHtmlView /** * The pagination object * - * @var Pagination + * @var Pagination * @since __DEPLOY_VERSION__ */ protected $pagination; @@ -54,7 +54,7 @@ class HtmlView extends BaseHtmlView /** * The model state * - * @var JObject + * @var JObject * @since __DEPLOY_VERSION__ */ protected $state; @@ -62,23 +62,23 @@ class HtmlView extends BaseHtmlView /** * Form object for search filters * - * @var \JForm - * @since __DEPLOY_VERSION__ + * @var \JForm + * @since __DEPLOY_VERSION__ */ public $filterForm; /** * The active search filters * - * @var array - * @since 4.0.0 + * @var array + * @since 4.0.0 */ public $activeFilters; /** * Is this view an Empty State * - * @var boolean + * @var boolean * @since 4.0.0 */ private $isEmptyState = false; @@ -86,20 +86,20 @@ class HtmlView extends BaseHtmlView /** * Execute and display a template script. * - * @param string $tpl The name of the template file to parse; automatically searches through the template paths. + * @param string $tpl The name of the template file to parse; automatically searches through the template paths. * - * @return mixed A string if successful, otherwise an Error object. + * @return mixed A string if successful, otherwise an Error object. */ /** - * @param string $tpl The name of the template file to parse; automatically searches through the template paths. + * @param string $tpl The name of the template file to parse; automatically searches through the template paths. * - * @return void + * @return void * - * @throws Exception + * @throws Exception * - * @since __DEPLOY_VERSION__ + * @since __DEPLOY_VERSION__ */ public function display($tpl = null): void { @@ -135,11 +135,11 @@ public function display($tpl = null): void /** * Add the page title and toolbar. * - * @return void + * @return void * - * @throws Exception + * @throws Exception * - * @since __DEPLOY_VERSION__ + * @since __DEPLOY_VERSION__ */ protected function addToolbar(): void { @@ -148,15 +148,14 @@ protected function addToolbar(): void $user = Factory::getApplication()->getIdentity(); /* - * Get the toolbar object instance - * !! TODO : Replace usage with ToolbarFactoryInterface - */ + * Get the toolbar object instance + * !! TODO : Replace usage with ToolbarFactoryInterface + */ $toolbar = Toolbar::getInstance('toolbar'); // TODO : 'cronjobs' icon ToolbarHelper::title(Text::_('COM_CRONJOBS_MANAGER_CRONJOBS'), 'tags'); - if ($canDo->get('core.create')) { $toolbar->addNew('cronjob.add'); @@ -181,9 +180,9 @@ protected function addToolbar(): void } /* - * TODO: Remove this - * This is probably unneeded - */ + * TODO: Remove this + * This is probably unneeded + */ if ($canDo->get('core.edit.state') && $this->state->get('filter.published') != -2) { $childBar->trash('cronjobs.trash')->listCheck(true); diff --git a/administrator/components/com_cronjobs/src/View/SelectPlugin/HtmlView.php b/administrator/components/com_cronjobs/src/View/SelectPlugin/HtmlView.php index fc048d7ddf8da..f0e6b41491844 100644 --- a/administrator/components/com_cronjobs/src/View/SelectPlugin/HtmlView.php +++ b/administrator/components/com_cronjobs/src/View/SelectPlugin/HtmlView.php @@ -2,17 +2,17 @@ /** * Declares the MVC View for SelectPluginModel. * - * @package Joomla.Administrator - * @subpackage com_cronjobs + * @package Joomla.Administrator + * @subpackage com_cronjobs * - * @copyright (C) 2021 Open Source Matters, Inc. - * @license GPL v3 + * @copyright (C) 2021 Open Source Matters, Inc. + * @license GPL v3 */ namespace Joomla\Component\Cronjobs\Administrator\View\SelectPlugin; // Restrict direct access -\defined('_JEXEC_') or die; +\defined('_JEXEC') or die; use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView; @@ -30,7 +30,7 @@ class HtmlView extends BaseHtmlView /** * The Form object * - * @var \JForm + * @var \JForm * @since __DEPLOY__VERSION__ */ protected $form; @@ -38,7 +38,7 @@ class HtmlView extends BaseHtmlView /** * The active item * - * @var object + * @var object * @since __DEPLOY__VERSION__ */ protected $item; @@ -46,16 +46,16 @@ class HtmlView extends BaseHtmlView /** * The model state * - * @var \JObject + * @var \JObject * @since __DEPLOY__VERSION__ */ protected $state; /** - * @param string $tpl The name of the template file to parse; automatically searches through the template paths. + * @param string $tpl The name of the template file to parse; automatically searches through the template paths. * - * @return void + * @return void * * @since __DEPLOY_VERSION__ */ From aabe6be9df20e8cec03acab60012321b84d7c35e Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Thu, 8 Jul 2021 17:23:47 +0530 Subject: [PATCH 021/615] Add filter form for Cronjobs View Needs changes down the line. Filtering and sorting won't work because CronjobsModel is yet to support them. --- .../com_cronjobs/forms/filter_cronjobs.xml | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 administrator/components/com_cronjobs/forms/filter_cronjobs.xml diff --git a/administrator/components/com_cronjobs/forms/filter_cronjobs.xml b/administrator/components/com_cronjobs/forms/filter_cronjobs.xml new file mode 100644 index 0000000000000..12d6388df608a --- /dev/null +++ b/administrator/components/com_cronjobs/forms/filter_cronjobs.xml @@ -0,0 +1,77 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
From 8d6c3ca0807ec538858cd52f9757c1a7fa7393e7 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Thu, 8 Jul 2021 17:26:07 +0530 Subject: [PATCH 022/615] Add template for Cronjobs View Currently rough around the edges and requires cleanup but it works fine for things CronjobsModel and Cronjob support at the moment. --- .../com_cronjobs/tmpl/cronjobs/default.php | 224 ++++++++++++++++++ .../com_cronjobs/tmpl/cronjobs/default.xml | 8 + .../tmpl/cronjobs/default_batch_body.php | 29 +++ .../tmpl/cronjobs/default_batch_footer.php | 21 ++ .../tmpl/cronjobs/empty_state.php | 27 +++ 5 files changed, 309 insertions(+) create mode 100644 administrator/components/com_cronjobs/tmpl/cronjobs/default.php create mode 100644 administrator/components/com_cronjobs/tmpl/cronjobs/default.xml create mode 100644 administrator/components/com_cronjobs/tmpl/cronjobs/default_batch_body.php create mode 100644 administrator/components/com_cronjobs/tmpl/cronjobs/default_batch_footer.php create mode 100644 administrator/components/com_cronjobs/tmpl/cronjobs/empty_state.php diff --git a/administrator/components/com_cronjobs/tmpl/cronjobs/default.php b/administrator/components/com_cronjobs/tmpl/cronjobs/default.php new file mode 100644 index 0000000000000..10cf6d8e882f8 --- /dev/null +++ b/administrator/components/com_cronjobs/tmpl/cronjobs/default.php @@ -0,0 +1,224 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory; +use Joomla\CMS\HTML\HTMLHelper; +use Joomla\CMS\Language\Multilanguage; +use Joomla\CMS\Language\Text; +use Joomla\CMS\Layout\LayoutHelper; +use Joomla\CMS\Router\Route; +use Joomla\CMS\Session\Session; + +HTMLHelper::_('behavior.multiselect'); + +try +{ + $app = Factory::getApplication(); +} catch (Exception $e) +{ + die('Failed to get app'); +} + +$user = $app->getIdentity(); +$userId = $user->get('id'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$saveOrder = ($listOrder == 'a.lft' && strtolower($listDirn) == 'asc'); +$section = null; +$mode = false; + + +if ($saveOrder && !empty($this->items)) +{ + // TODO : Check if this works + $saveOrderingUrl = 'index.php?option=com_cronjobs&task=cronjobs.saveOrderAjax&' . Session::getFormToken() . '=1'; + HTMLHelper::_('draggablelist.draggable'); +} +?> + +
+
+ $this)); + ?> + + + items)): ?> + +
+ + +
+ + + + items)): ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + class="js-draggable" data-url="" data-direction="" data-nested="true"> + items as $i => $item): + // TODO : Check if $user->authorise() calls work as they should + $orderKey = $item->job_id; + $canCreate = $user->authorise('core.create', 'com_cronjobs'); + $canEdit = $user->authorise('core.edit', 'com_cronjobs'); + $canChange = $user->authorise('core.edit.state', 'com_cronjobs'); ?> + + + + + + + + + + + + + + + + + + + + + + + + +
+ , + , + +
+ + + + + + + + + + + + + + +
+ job_id, false, 'cid', 'cb', $item->name); ?> + + + + + + + + + + enabled, $i, 'cronjobs.', $canChange); ?> + + + + escape($item->name); ?> + + escape($item->name); ?> + + + note)): ?> + + + + escape($item->note)); ?> + + + escape($item->type); ?> + + + + + + + + job_id; ?> +
+ + + pagination->getListFooter(); ?> + + + authorise('core.create', 'com_tags') + && $user->authorise('core.edit', 'com_tags') + && $user->authorise('core.edit.state', 'com_tags')) + : + ?> + Text::_('COM_TAGS_BATCH_OPTIONS'), + 'footer' => $this->loadTemplate('batch_footer'), + ), + $this->loadTemplate('batch_body') + ); ?> + + + + + + +
+
diff --git a/administrator/components/com_cronjobs/tmpl/cronjobs/default.xml b/administrator/components/com_cronjobs/tmpl/cronjobs/default.xml new file mode 100644 index 0000000000000..b7fb940e986ad --- /dev/null +++ b/administrator/components/com_cronjobs/tmpl/cronjobs/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/administrator/components/com_cronjobs/tmpl/cronjobs/default_batch_body.php b/administrator/components/com_cronjobs/tmpl/cronjobs/default_batch_body.php new file mode 100644 index 0000000000000..a7af48a378973 --- /dev/null +++ b/administrator/components/com_cronjobs/tmpl/cronjobs/default_batch_body.php @@ -0,0 +1,29 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ +defined('_JEXEC') or die; + +use Joomla\CMS\Layout\LayoutHelper; + +$published = $this->state->get('filter.published'); +?> + +
+
+
+
+ +
+
+
+
+ +
+
+
+
diff --git a/administrator/components/com_cronjobs/tmpl/cronjobs/default_batch_footer.php b/administrator/components/com_cronjobs/tmpl/cronjobs/default_batch_footer.php new file mode 100644 index 0000000000000..7633fa6535180 --- /dev/null +++ b/administrator/components/com_cronjobs/tmpl/cronjobs/default_batch_footer.php @@ -0,0 +1,21 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ +defined('_JEXEC') or die; + +use Joomla\CMS\Language\Text; + +?> + + diff --git a/administrator/components/com_cronjobs/tmpl/cronjobs/empty_state.php b/administrator/components/com_cronjobs/tmpl/cronjobs/empty_state.php new file mode 100644 index 0000000000000..ca703ec5f16d2 --- /dev/null +++ b/administrator/components/com_cronjobs/tmpl/cronjobs/empty_state.php @@ -0,0 +1,27 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory; +use Joomla\CMS\Layout\LayoutHelper; + +$displayData = [ + 'textPrefix' => 'COM_CRONJOBS', + 'formURL' => 'index.php?option=com_cronjobs&task=cronjob.add', + 'helpURL' => 'https://github.com/joomla-projects/soc21_website-cronjob', + 'icon' => 'icon-cronjobs cronjobs', +]; + +if (Factory::getApplication()->getIdentity()->authorise('core.create', 'com_cronjobs')) +{ + $displayData['createURL'] = 'index.php?option=com_cronjobs&task=cronjob.add'; +} + +echo LayoutHelper::render('joomla.content.emptystate', $displayData); From 62bbadfde43491ba1b68f0f6009c5d9b99683b54 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Thu, 8 Jul 2021 17:52:43 +0530 Subject: [PATCH 023/615] Add component config file Adds granular config for ACL --- .../components/com_cronjobs/config.xml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 administrator/components/com_cronjobs/config.xml diff --git a/administrator/components/com_cronjobs/config.xml b/administrator/components/com_cronjobs/config.xml new file mode 100644 index 0000000000000..ae8597a1f788f --- /dev/null +++ b/administrator/components/com_cronjobs/config.xml @@ -0,0 +1,18 @@ + + +
+ +
+
From da4a7992e80e094a16c9d814f4f0d1e47c7c92a1 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Thu, 8 Jul 2021 18:25:10 +0530 Subject: [PATCH 024/615] Add granular access control to access.xml Also sneaks in some formatting fixes >.< --- .../components/com_cronjobs/access.xml | 19 ++-- .../com_cronjobs/src/Model/CronjobsModel.php | 67 ++++++++++----- .../com_cronjobs/tmpl/cronjobs/default.php | 86 ++++++++++++------- 3 files changed, 111 insertions(+), 61 deletions(-) diff --git a/administrator/components/com_cronjobs/access.xml b/administrator/components/com_cronjobs/access.xml index ad157daad76cc..fc723614ee512 100644 --- a/administrator/components/com_cronjobs/access.xml +++ b/administrator/components/com_cronjobs/access.xml @@ -1,12 +1,17 @@
- - - - - - - + + + + + + + +
+
+ + +
diff --git a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php index 1843ea88048cd..7c9016d01e04c 100644 --- a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php +++ b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php @@ -4,11 +4,11 @@ * TODO: Implement query filters in $GetListQuery() * TODO: Complete $config['filter_fields'] * - * @package Joomla.Administrator - * @subpackage com_cronjobs + * @package Joomla.Administrator + * @subpackage com_cronjobs * * @copyright (C) 2021 Open Source Matters, Inc. - * @license GPL v3 + * @license GPL v3 */ namespace Joomla\Component\Cronjobs\Administrator\Model; @@ -34,9 +34,9 @@ class CronjobsModel extends ListModel /** * Constructor. * - * @param array $config An optional associative array of configuration settings. + * @param array $config An optional associative array of configuration settings. * - * @param MVCFactoryInterface|null $factory The factory. + * @param MVCFactoryInterface|null $factory The factory. * * @throws Exception * @since __DEPLOY_VERSION__ @@ -46,26 +46,45 @@ public function __construct($config = array(), MVCFactoryInterface $factory = nu { if (empty($config['filter_fields'])) { - // ! TODO: Doesn't set everything yet - $config['filter_fields'] = array( - 'job_id', - 'a.job_id', + // TODO : Works right? Need to implement filtering to check. + $config['filter_fields'] + = array( + 'job_id', + 'a.job_id', - 'name', - 'a.name', + 'name', + 'a.name', - 'type', - 'a.type', + 'type', + 'a.type', - 'trigger', - 'a.trigger', + 'trigger', + 'a.trigger', - 'execution_interval', - 'a.execution_interval', + 'execution_interval', + 'a.execution_interval', - 'enabled', - 'a.enabled' - ); + 'enabled', + 'a.enabled', + + 'last_exit_code', + 'a.last_exit_code', + + 'last_execution', + 'a.last_execution', + + 'next_execution', + 'a.next_execution', + + 'times_executed', + 'a.times_executed', + + 'times_failed', + 'a.times_failed', + + 'note', + 'a.note' + ); } parent::__construct($config, $factory); @@ -74,7 +93,7 @@ public function __construct($config = array(), MVCFactoryInterface $factory = nu /** * Method to get an array of data items. * - * @return mixed An array of data items on success, false on failure. + * @return array|boolean An array of data items on success, false on failure. * * @since __DEPLOY_VERSION__ */ @@ -90,7 +109,7 @@ public function getItems() * different modules that might need different sets of data or different * ordering requirements. * - * @param string $id A prefix for the store id. + * @param string $id A prefix for the store id. * * @return string A store id. * @@ -109,6 +128,7 @@ protected function getStoreId($id = ''): string /** * Method to create a query for a list of items. * ! No filters at the moment ⚠ + * * @return QueryInterface * * @throws Exception @@ -129,11 +149,12 @@ protected function getListQuery(): QueryInterface 'a.job_id, a.name, a.type, a.trigger, a.execution_interval, a.enabled, a.last_exit_code' . ', a.next_execution, a.times_executed, a.times_failed' ) + // ? Does 'list.select' exist ? ); $query->from($db->quoteName('#__cronjobs', 'a')); - // TODO : Implement filters here + // TODO : Implement filters and sorting here return $query; } diff --git a/administrator/components/com_cronjobs/tmpl/cronjobs/default.php b/administrator/components/com_cronjobs/tmpl/cronjobs/default.php index 10cf6d8e882f8..d92754186da78 100644 --- a/administrator/components/com_cronjobs/tmpl/cronjobs/default.php +++ b/administrator/components/com_cronjobs/tmpl/cronjobs/default.php @@ -1,4 +1,4 @@ - - items)): ?> + items)) + : + ?>
- items)): ?> + items)) + : + ?> @@ -109,10 +114,14 @@ class="visually-hidden"> - + class="js-draggable" data-url="" data-direction="" data-nested="true"> - items as $i => $item): + endif; ?>> + items as $i => $item) + : // TODO : Check if $user->authorise() calls work as they should $orderKey = $item->job_id; $canCreate = $user->authorise('core.create', 'com_cronjobs'); @@ -125,25 +134,28 @@ class="js-draggable" data-url="" data-direction=" data-draggable-group="job_id; ?>"> @@ -176,7 +198,9 @@ class="js-draggable" data-url="" data-direction=" escape($item->type); ?> - + @@ -189,7 +213,7 @@ class="js-draggable" data-url="" data-direction=" @@ -201,10 +225,10 @@ class="js-draggable" data-url="" data-direction=" authorise('core.create', 'com_tags') - && $user->authorise('core.edit', 'com_tags') - && $user->authorise('core.edit.state', 'com_tags')) - : - ?> + && $user->authorise('core.edit', 'com_tags') + && $user->authorise('core.edit.state', 'com_tags')) + : + ?> " data-direction=" 'footer' => $this->loadTemplate('batch_footer'), ), $this->loadTemplate('batch_body') - ); ?> + ); ?> From 6ae51d2f13b333accf6036288a2b501c33bad518 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Thu, 8 Jul 2021 19:34:19 +0530 Subject: [PATCH 025/615] Add DB columns to support ACL and creation history Adds the 'asset_id' column to support per-item access control. Adds 'created_by' and 'created' columns to keep track of when and who created a cronjob. --- .../components/com_cronjobs/forms/cronjob.xml | 18 +++++ .../com_cronjobs/sql/mysql/install.sql | 17 +++-- .../com_cronjobs/sql/postgresql/install.sql | 19 ++++-- .../sql/updates/mysql/08-07-2021.mysql.sql | 7 ++ .../updates/postgresql/08-07-2021.postgre.sql | 7 ++ .../src/View/SelectType/HtmlView.php | 67 +++++++++++++++++++ 6 files changed, 121 insertions(+), 14 deletions(-) create mode 100644 administrator/components/com_cronjobs/forms/cronjob.xml create mode 100644 administrator/components/com_cronjobs/sql/updates/mysql/08-07-2021.mysql.sql create mode 100644 administrator/components/com_cronjobs/sql/updates/postgresql/08-07-2021.postgre.sql create mode 100644 administrator/components/com_cronjobs/src/View/SelectType/HtmlView.php diff --git a/administrator/components/com_cronjobs/forms/cronjob.xml b/administrator/components/com_cronjobs/forms/cronjob.xml new file mode 100644 index 0000000000000..d5e285f460f2c --- /dev/null +++ b/administrator/components/com_cronjobs/forms/cronjob.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/administrator/components/com_cronjobs/sql/mysql/install.sql b/administrator/components/com_cronjobs/sql/mysql/install.sql index a1aa8f7628f22..e99a4b0be2d4a 100644 --- a/administrator/components/com_cronjobs/sql/mysql/install.sql +++ b/administrator/components/com_cronjobs/sql/mysql/install.sql @@ -2,19 +2,22 @@ CREATE TABLE IF NOT EXISTS `#__cronjobs` ( - `job_id` int(4) NOT NULL AUTO_INCREMENT, + `job_id` INT(4) NOT NULL AUTO_INCREMENT, `name` varchar(128) NOT NULL UNIQUE, + `asset_id` INT(10) NOT NULL UNIQUE DEFAULT '0', + `created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', + `created_by` INT(10) UNSIGNED NOT NULL DEFAULT '0', -- Job type. Can execute a script or plugin routine - `type` ENUM ('script', 'plugin') NOT NULL DEFAULT 'script', + `type` ENUM ('script', 'plugin') NOT NULL DEFAULT 'script', -- Trigger type, default to PseudoCron (compatible everywhere). - `trigger` ENUM ('pseudo_cron', 'cron', 'visit_count') NOT NULL DEFAULT 'pseudo_cron' COMMENT 'Defines how job is triggered', + `trigger` ENUM ('pseudo_cron', 'cron', 'visit_count') NOT NULL DEFAULT 'pseudo_cron' COMMENT 'Defines how job is triggered', `execution_interval` INT NOT NULL COMMENT 'Configured time between executions, in seconds', - `enabled` BOOL NOT NULL DEFAULT FALSE, - `last_exit_code` INT(11) NOT NULL DEFAULT 0 COMMENT 'Exit code when job was last run', + `enabled` BOOL NOT NULL DEFAULT FALSE, + `last_exit_code` INT(11) NOT NULL DEFAULT '0' COMMENT 'Exit code when job was last run', `last_execution` DATETIME NOT NULL COMMENT 'Timestamp of when job was last run', `next_execution` DATETIME NOT NULL COMMENT 'Timestamp of when job should next run, referred for execution on trigger', - `times_executed` INT(11) DEFAULT 0 COMMENT 'Count of times job has been triggered to run', - `times_failed` INT(11) DEFAULT 0 COMMENT 'Count of times job has failed', + `times_executed` INT(11) DEFAULT '0' COMMENT 'Count of times job has been triggered to run', + `times_failed` INT(11) DEFAULT '0' COMMENT 'Count of times job has failed', `note` varchar(128), PRIMARY KEY (job_id) ) diff --git a/administrator/components/com_cronjobs/sql/postgresql/install.sql b/administrator/components/com_cronjobs/sql/postgresql/install.sql index 0c2c43d220c00..e13e117d2d8da 100644 --- a/administrator/components/com_cronjobs/sql/postgresql/install.sql +++ b/administrator/components/com_cronjobs/sql/postgresql/install.sql @@ -18,25 +18,29 @@ $$ $$; --------------------------------------------------------------------------- --- Table Structure "#__cronjobs" [Main] -- - +------------------- Table Structure "#__cronjobs" [Main] ------------------- CREATE TABLE IF NOT EXISTS "#__cronjobs" ( "job_id" INT GENERATED ALWAYS AS IDENTITY, "name" VARCHAR(255) NOT NULL, + "asset_id" INT NOT NULL UNIQUE DEFAULT '0', + "created" TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00', + "created_by" INT NOT NULL DEFAULT '0', "type" JOB_TYPE, "execution_interval" INT NOT NULL, - "trigger" TRIGGER_TYPE NOT NULL DEFAULT 'pseudo_cron', - "enabled" BOOLEAN NOT NULL DEFAULT false, - "last_exit_code" INT NOT NULL DEFAULT 0, + "trigger" TRIGGER_TYPE NOT NULL DEFAULT 'pseudo_cron', + "enabled" BOOLEAN NOT NULL DEFAULT false, + "last_exit_code" INT NOT NULL DEFAULT 0, "last_execution" TIMESTAMP NOT NULL, "next_execution" TIMESTAMP NOT NULL, "times_executed" TIMESTAMP NOT NULL, - "times_failed" int DEFAULT 0, + "times_failed" int DEFAULT 0, "note" varchar(512) ); +---------------------------------------------------------------------------- + +------ Table Structure "#__cronjobs_scripts" ------ --- Table Structure "#__cronjobs_scripts" -- CREATE TABLE IF NOT EXISTS "#cronjobs_scripts" ( "script_id" INT GENERATED ALWAYS AS IDENTITY, @@ -47,3 +51,4 @@ CREATE TABLE IF NOT EXISTS "#cronjobs_scripts" FOREIGN KEY (job_id) REFERENCES "#__cronjobs" (job_id) ); +--------------------------------------------------- diff --git a/administrator/components/com_cronjobs/sql/updates/mysql/08-07-2021.mysql.sql b/administrator/components/com_cronjobs/sql/updates/mysql/08-07-2021.mysql.sql new file mode 100644 index 0000000000000..fcc8544ab9840 --- /dev/null +++ b/administrator/components/com_cronjobs/sql/updates/mysql/08-07-2021.mysql.sql @@ -0,0 +1,7 @@ +ALTER TABLE `#__cronjobs` + ADD COLUMN `asset_id` INT(10) NOT NULL DEFAULT '0'; + +ALTER TABLE `#__cronjobs` + ADD COLUMN `created` INT(10) NOT NULL DEFAULT '0'; +ALTER TABLE `#__cronjobs` + ADD COLUMN `created_by` INT(10) NOT NULL DEFAULT '0'; diff --git a/administrator/components/com_cronjobs/sql/updates/postgresql/08-07-2021.postgre.sql b/administrator/components/com_cronjobs/sql/updates/postgresql/08-07-2021.postgre.sql new file mode 100644 index 0000000000000..55c3a717bfaf6 --- /dev/null +++ b/administrator/components/com_cronjobs/sql/updates/postgresql/08-07-2021.postgre.sql @@ -0,0 +1,7 @@ +ALTER TABLE "#__cronjobs" + ADD COLUMN "asset_id" INT NOT NULL DEFAULT '0'; + +ALTER TABLE "#__cronjobs" + ADD COLUMN "created" INT NOT NULL DEFAULT '0'; +ALTER TABLE "#__cronjobs" + ADD COLUMN "created_by" INT NOT NULL DEFAULT '0'; diff --git a/administrator/components/com_cronjobs/src/View/SelectType/HtmlView.php b/administrator/components/com_cronjobs/src/View/SelectType/HtmlView.php new file mode 100644 index 0000000000000..888102810449d --- /dev/null +++ b/administrator/components/com_cronjobs/src/View/SelectType/HtmlView.php @@ -0,0 +1,67 @@ + + * @license GPL v3 + */ + +namespace Joomla\Component\Cronjobs\Administrator\View\SelectType; + +// Restrict direct access +\defined('_JEXEC_') or die; + +use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView; + +/** + * The MVC View SelectType + * Should let the user choose between adding a Script or a Plugin 'Cronjob' + * + * @package Joomla.Administrator + * @subpackage com_cronjobs + * + * @since __DEPLOY_VERSION__ + */ +class HtmlView extends BaseHtmlView +{ + /** + * The Form object + * + * @var \JForm + * @since __DEPLOY__VERSION__ + */ + protected $form; + + /** + * The active item + * + * @var object + * @since __DEPLOY__VERSION__ + */ + protected $item; + + /** + * The model state + * + * @var \JObject + * @since __DEPLOY__VERSION__ + */ + protected $state; + + + /** + * @param string $tpl The name of the template file to parse; automatically searches through the template paths. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function display($tpl = null) : void + { + // ! TODO + } + +} From edf8531e554a9cbb83825852706bf5c6cadb186b Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Fri, 9 Jul 2021 03:10:17 +0530 Subject: [PATCH 026/615] Add path for SQL updates to manifest --- administrator/components/com_cronjobs/cronjobs.xml | 6 ++++++ .../com_cronjobs/sql/updates/mysql/08-07-2021.mysql.sql | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/administrator/components/com_cronjobs/cronjobs.xml b/administrator/components/com_cronjobs/cronjobs.xml index 62e307ac5eda4..a081b1f24c07f 100644 --- a/administrator/components/com_cronjobs/cronjobs.xml +++ b/administrator/components/com_cronjobs/cronjobs.xml @@ -22,6 +22,12 @@ sql/postgresql/uninstall.sql + + + sql/updates/mysql + sql/updates/postgresql + + Cronjobs diff --git a/administrator/components/com_cronjobs/sql/updates/mysql/08-07-2021.mysql.sql b/administrator/components/com_cronjobs/sql/updates/mysql/08-07-2021.mysql.sql index fcc8544ab9840..80f735fa38359 100644 --- a/administrator/components/com_cronjobs/sql/updates/mysql/08-07-2021.mysql.sql +++ b/administrator/components/com_cronjobs/sql/updates/mysql/08-07-2021.mysql.sql @@ -1,6 +1,5 @@ ALTER TABLE `#__cronjobs` ADD COLUMN `asset_id` INT(10) NOT NULL DEFAULT '0'; - ALTER TABLE `#__cronjobs` ADD COLUMN `created` INT(10) NOT NULL DEFAULT '0'; ALTER TABLE `#__cronjobs` From 75e2342db6b27f67d21811b1594cadfaa0d41301 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Fri, 9 Jul 2021 17:56:39 +0530 Subject: [PATCH 027/615] Update database tables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ⚠ This commit includes destructive DB updates. ⚠ To make database structure more consistent with Joomla's existing implicit conventions, column names are changed, datatypes are made more appropriate to column contents, and foreign key constraints are removed. Also reorders the table columns to have creation history records at the end and 'asset_id' next to 'id'. --- .../com_cronjobs/sql/mysql/install.sql | 29 +++++----- .../com_cronjobs/sql/postgresql/install.sql | 39 ++++++------- ...07-2021.mysql.sql => 2021-07-08.mysql.sql} | 0 .../sql/updates/mysql/2021-07-09.mysql.sql | 46 +++++++++++++++ ...021.postgre.sql => 2021-07-08.postgre.sql} | 0 .../updates/postgresql/2021-07-09.postgre.sql | 57 +++++++++++++++++++ 6 files changed, 135 insertions(+), 36 deletions(-) rename administrator/components/com_cronjobs/sql/updates/mysql/{08-07-2021.mysql.sql => 2021-07-08.mysql.sql} (100%) create mode 100644 administrator/components/com_cronjobs/sql/updates/mysql/2021-07-09.mysql.sql rename administrator/components/com_cronjobs/sql/updates/postgresql/{08-07-2021.postgre.sql => 2021-07-08.postgre.sql} (100%) create mode 100644 administrator/components/com_cronjobs/sql/updates/postgresql/2021-07-09.postgre.sql diff --git a/administrator/components/com_cronjobs/sql/mysql/install.sql b/administrator/components/com_cronjobs/sql/mysql/install.sql index e99a4b0be2d4a..30d4c6e4c8b44 100644 --- a/administrator/components/com_cronjobs/sql/mysql/install.sql +++ b/administrator/components/com_cronjobs/sql/mysql/install.sql @@ -2,24 +2,24 @@ CREATE TABLE IF NOT EXISTS `#__cronjobs` ( - `job_id` INT(4) NOT NULL AUTO_INCREMENT, - `name` varchar(128) NOT NULL UNIQUE, + `id` INT(4) NOT NULL AUTO_INCREMENT, `asset_id` INT(10) NOT NULL UNIQUE DEFAULT '0', - `created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', - `created_by` INT(10) UNSIGNED NOT NULL DEFAULT '0', + `title` varchar(128) NOT NULL UNIQUE, -- Job type. Can execute a script or plugin routine `type` ENUM ('script', 'plugin') NOT NULL DEFAULT 'script', -- Trigger type, default to PseudoCron (compatible everywhere). `trigger` ENUM ('pseudo_cron', 'cron', 'visit_count') NOT NULL DEFAULT 'pseudo_cron' COMMENT 'Defines how job is triggered', `execution_interval` INT NOT NULL COMMENT 'Configured time between executions, in seconds', - `enabled` BOOL NOT NULL DEFAULT FALSE, + `state` TINYINT NOT NULL DEFAULT FALSE, `last_exit_code` INT(11) NOT NULL DEFAULT '0' COMMENT 'Exit code when job was last run', - `last_execution` DATETIME NOT NULL COMMENT 'Timestamp of when job was last run', - `next_execution` DATETIME NOT NULL COMMENT 'Timestamp of when job should next run, referred for execution on trigger', - `times_executed` INT(11) DEFAULT '0' COMMENT 'Count of times job has been triggered to run', - `times_failed` INT(11) DEFAULT '0' COMMENT 'Count of times job has failed', - `note` varchar(128), - PRIMARY KEY (job_id) + `last_execution` DATETIME NOT NULL COMMENT 'Timestamp of last run', + `next_execution` DATETIME NOT NULL COMMENT 'Timestamp of next (planned) run, referred for execution on trigger', + `times_executed` INT(11) DEFAULT '0' COMMENT 'Count of successful triggers', + `times_failed` INT(11) DEFAULT '0' COMMENT 'Count of failures', + `note` TEXT, + `created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', + `created_by` INT(10) UNSIGNED NOT NULL DEFAULT '0', + PRIMARY KEY (id) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 @@ -30,12 +30,11 @@ CREATE TABLE IF NOT EXISTS `#__cronjobs` CREATE TABLE IF NOT EXISTS `#__cronjobs_scripts` ( - `script_id` int(4) NOT NULL AUTO_INCREMENT, - `job_id` int(4) NOT NULL COMMENT 'Cronjob ID', + `id` int(4) NOT NULL AUTO_INCREMENT, + `job_id` int(4) NOT NULL COMMENT 'Cronjob ID', -- References `#__cronjobs`(id) `directory` varchar(1024) NOT NULL, `file` varchar(256) NOT NULL, - PRIMARY KEY (script_id), - FOREIGN KEY (job_id) REFERENCES `#__cronjobs` (job_id) + PRIMARY KEY (id) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 diff --git a/administrator/components/com_cronjobs/sql/postgresql/install.sql b/administrator/components/com_cronjobs/sql/postgresql/install.sql index e13e117d2d8da..b71273be89410 100644 --- a/administrator/components/com_cronjobs/sql/postgresql/install.sql +++ b/administrator/components/com_cronjobs/sql/postgresql/install.sql @@ -21,34 +21,31 @@ $$; ------------------- Table Structure "#__cronjobs" [Main] ------------------- CREATE TABLE IF NOT EXISTS "#__cronjobs" ( - "job_id" INT GENERATED ALWAYS AS IDENTITY, - "name" VARCHAR(255) NOT NULL, - "asset_id" INT NOT NULL UNIQUE DEFAULT '0', - "created" TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00', - "created_by" INT NOT NULL DEFAULT '0', + "id" INT GENERATED ALWAYS AS IDENTITY, + "asset_id" BIGINT NOT NULL DEFAULT '0', + "title" VARCHAR(255) NOT NULL, "type" JOB_TYPE, - "execution_interval" INT NOT NULL, - "trigger" TRIGGER_TYPE NOT NULL DEFAULT 'pseudo_cron', - "enabled" BOOLEAN NOT NULL DEFAULT false, - "last_exit_code" INT NOT NULL DEFAULT 0, - "last_execution" TIMESTAMP NOT NULL, - "next_execution" TIMESTAMP NOT NULL, - "times_executed" TIMESTAMP NOT NULL, - "times_failed" int DEFAULT 0, - "note" varchar(512) + "execution_interval" INT NOT NULL, + "trigger" TRIGGER_TYPE NOT NULL DEFAULT 'pseudo_cron', + "state" SMALLINT NOT NULL DEFAULT '0', + "last_exit_code" INT NOT NULL DEFAULT '0', + "last_execution" TIMESTAMP NOT NULL, + "next_execution" TIMESTAMP NOT NULL, + "times_executed" TIMESTAMP NOT NULL, + "times_failed" INT DEFAULT '0', + "note" TEXT DEFAULT '', + "created" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT '0000-00-00 00:00:00', + "created_by" BIGINT NOT NULL DEFAULT '0' ); ---------------------------------------------------------------------------- ------ Table Structure "#__cronjobs_scripts" ------ -CREATE TABLE IF NOT EXISTS "#cronjobs_scripts" +CREATE TABLE IF NOT EXISTS "#__cronjobs_scripts" ( - "script_id" INT GENERATED ALWAYS AS IDENTITY, - "job_id" INT, + "id" INT GENERATED ALWAYS AS IDENTITY, + "job_id" INT, -- References "#__cronjobs"(id) "directory" VARCHAR(256) NOT NULL, - "file" VARCHAR(128) NOT NULL, - CONSTRAINT "job_id" - FOREIGN KEY (job_id) - REFERENCES "#__cronjobs" (job_id) + "file" VARCHAR(128) NOT NULL ); --------------------------------------------------- diff --git a/administrator/components/com_cronjobs/sql/updates/mysql/08-07-2021.mysql.sql b/administrator/components/com_cronjobs/sql/updates/mysql/2021-07-08.mysql.sql similarity index 100% rename from administrator/components/com_cronjobs/sql/updates/mysql/08-07-2021.mysql.sql rename to administrator/components/com_cronjobs/sql/updates/mysql/2021-07-08.mysql.sql diff --git a/administrator/components/com_cronjobs/sql/updates/mysql/2021-07-09.mysql.sql b/administrator/components/com_cronjobs/sql/updates/mysql/2021-07-09.mysql.sql new file mode 100644 index 0000000000000..1a1e02ce63f4f --- /dev/null +++ b/administrator/components/com_cronjobs/sql/updates/mysql/2021-07-09.mysql.sql @@ -0,0 +1,46 @@ +-- ⚠ This update causes data loss. + +DROP TABLE IF EXISTS `#__cronjobs_scripts`; +DROP TABLE IF EXISTS `#__cronjobs`; + +-- Table Structure `#__cronjobs` [Main] -- + +CREATE TABLE IF NOT EXISTS `#__cronjobs` +( + `id` INT(4) NOT NULL AUTO_INCREMENT, + `asset_id` INT(10) NOT NULL UNIQUE DEFAULT '0', + `title` varchar(128) NOT NULL UNIQUE, + -- Job type. Can execute a script or plugin routine + `type` ENUM ('script', 'plugin') NOT NULL DEFAULT 'script', + -- Trigger type, default to PseudoCron (compatible everywhere). + `trigger` ENUM ('pseudo_cron', 'cron', 'visit_count') NOT NULL DEFAULT 'pseudo_cron' COMMENT 'Defines how job is triggered', + `execution_interval` INT NOT NULL COMMENT 'Configured time between executions, in seconds', + `state` TINYINT NOT NULL DEFAULT '0', + `last_exit_code` INT(11) NOT NULL DEFAULT '0' COMMENT 'Exit code when job was last run', + `last_execution` DATETIME NOT NULL COMMENT 'Timestamp of last run', + `next_execution` DATETIME NOT NULL COMMENT 'Timestamp of next (planned) run, referred for execution on trigger', + `times_executed` INT(11) DEFAULT '0' COMMENT 'Count of successful triggers', + `times_failed` INT(11) DEFAULT '0' COMMENT 'Count of failures', + `note` TEXT, + `created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', + `created_by` INT(10) UNSIGNED NOT NULL DEFAULT '0', + PRIMARY KEY (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 + DEFAULT COLLATE = utf8mb4_unicode_ci; + + +-- Table structure `#__cronjobs_scripts` -- + +CREATE TABLE IF NOT EXISTS `#__cronjobs_scripts` +( + `id` int(4) NOT NULL AUTO_INCREMENT, + `job_id` int(4) NOT NULL COMMENT 'Cronjob ID', -- References `#__cronjobs`(id) + `directory` varchar(1024) NOT NULL, + `file` varchar(256) NOT NULL, + PRIMARY KEY (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 + DEFAULT COLLATE = utf8mb4_unicode_ci; diff --git a/administrator/components/com_cronjobs/sql/updates/postgresql/08-07-2021.postgre.sql b/administrator/components/com_cronjobs/sql/updates/postgresql/2021-07-08.postgre.sql similarity index 100% rename from administrator/components/com_cronjobs/sql/updates/postgresql/08-07-2021.postgre.sql rename to administrator/components/com_cronjobs/sql/updates/postgresql/2021-07-08.postgre.sql diff --git a/administrator/components/com_cronjobs/sql/updates/postgresql/2021-07-09.postgre.sql b/administrator/components/com_cronjobs/sql/updates/postgresql/2021-07-09.postgre.sql new file mode 100644 index 0000000000000..03c90e97b370c --- /dev/null +++ b/administrator/components/com_cronjobs/sql/updates/postgresql/2021-07-09.postgre.sql @@ -0,0 +1,57 @@ +-- ⚠ This update causes data loss. + +DROP TABLE IF EXISTS "#__cronjobs_scripts"; +DROP TABLE IF EXISTS "#__cronjobs"; + +------- Create required enumerated types with exception handling ---------- +DO +$$ + BEGIN + CREATE TYPE job_type AS ENUM ('script', 'plugin'); + EXCEPTION + WHEN duplicate_object THEN null; + END +$$; + +DO +$$ + BEGIN + CREATE TYPE trigger_type AS ENUM ('pseudo_cron', 'cron', 'visit_count'); + EXCEPTION + WHEN duplicate_object THEN null; + END +$$; +--------------------------------------------------------------------------- + +------------------- Table Structure "#__cronjobs" [Main] ------------------- +CREATE TABLE IF NOT EXISTS "#__cronjobs" +( + "id" INT GENERATED ALWAYS AS IDENTITY, + "asset_id" BIGINT NOT NULL DEFAULT '0', + "title" VARCHAR(255) NOT NULL, + "type" JOB_TYPE, + "execution_interval" INT NOT NULL, + "trigger" TRIGGER_TYPE NOT NULL DEFAULT 'pseudo_cron', + "state" SMALLINT NOT NULL DEFAULT '0', + "last_exit_code" INT NOT NULL DEFAULT '0', + "last_execution" TIMESTAMP NOT NULL, + "next_execution" TIMESTAMP NOT NULL, + "times_executed" TIMESTAMP NOT NULL, + "times_failed" INT DEFAULT '0', + "note" TEXT DEFAULT '', + "created" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT '0000-00-00 00:00:00', + "created_by" BIGINT NOT NULL DEFAULT '0' +); +---------------------------------------------------------------------------- + +------ Table Structure "#__cronjobs_scripts" ------ + +CREATE TABLE IF NOT EXISTS "#__cronjobs_scripts" +( + "id" INT GENERATED ALWAYS AS IDENTITY, + "job_id" INT, -- References "#__cronjobs"(id) + "directory" VARCHAR(256) NOT NULL, + "file" VARCHAR(128) NOT NULL +); +--------------------------------------------------- + From 1cd21a1057cb19e93849c03905a95f27b6691601 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Fri, 9 Jul 2021 18:21:21 +0530 Subject: [PATCH 028/615] Make CronjobsModel compatible with DB updates --- .../com_cronjobs/src/Model/CronjobsModel.php | 77 +++++++++++-------- 1 file changed, 47 insertions(+), 30 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php index 7c9016d01e04c..9a39b6654f995 100644 --- a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php +++ b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php @@ -2,7 +2,7 @@ /** * Declares the CronjobsModel MVC Model. * TODO: Implement query filters in $GetListQuery() - * TODO: Complete $config['filter_fields'] + * ~~TODO: Complete $config['filter_fields']~~ * * @package Joomla.Administrator * @subpackage com_cronjobs @@ -46,44 +46,56 @@ public function __construct($config = array(), MVCFactoryInterface $factory = nu { if (empty($config['filter_fields'])) { - // TODO : Works right? Need to implement filtering to check. + /* + * TODO : Works right? Need to implement filtering to check. + * TODO: Might want to remove unnecessary fields + */ $config['filter_fields'] = array( - 'job_id', - 'a.job_id', + 'id', + 'a.id', - 'name', - 'a.name', + 'asset_id', + 'a.asset_id', - 'type', - 'a.type', + 'title', + 'a.title', - 'trigger', - 'a.trigger', + 'type', + 'a.type', - 'execution_interval', - 'a.execution_interval', + 'trigger', + 'a.trigger', - 'enabled', - 'a.enabled', + 'execution_interval', + 'a.execution_interval', - 'last_exit_code', - 'a.last_exit_code', + 'enabled', + 'a.enabled', - 'last_execution', - 'a.last_execution', + 'last_exit_code', + 'a.last_exit_code', - 'next_execution', - 'a.next_execution', + 'last_execution', + 'a.last_execution', - 'times_executed', - 'a.times_executed', + 'next_execution', + 'a.next_execution', - 'times_failed', - 'a.times_failed', + 'times_executed', + 'a.times_executed', - 'note', - 'a.note' + 'times_failed', + 'a.times_failed', + + 'note', + 'a.note', + + 'created', + 'a.created', + + 'created_by', + 'a.created_by' ); } @@ -109,6 +121,9 @@ public function getItems() * different modules that might need different sets of data or different * ordering requirements. * + * ? What does this do internally ? + * TODO: + * * @param string $id A prefix for the store id. * * @return string A store id. @@ -141,13 +156,15 @@ protected function getListQuery(): QueryInterface $query = $db->getQuery(true); $user = Factory::getApplication()->getIdentity(); - // Select the required fields from the table. - // TODO : Should add a "created_by" column to `#__cronjobs` + /* + * Select the required fields from the table. + * ? Do we need all these defaults ? + */ $query->select( $this->getState( 'list.select', - 'a.job_id, a.name, a.type, a.trigger, a.execution_interval, a.enabled, a.last_exit_code' . - ', a.next_execution, a.times_executed, a.times_failed' + 'a.id, a.asset_id, a.title, a.type, a.trigger, a.execution_interval, a.state, a.last_exit_code' . + ', a.last_execution, a.next_execution, a.times_executed, a.times_failed' ) // ? Does 'list.select' exist ? ); From 302137a86725c9642eb89103b786ad85f9b7c957 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Fri, 9 Jul 2021 18:32:38 +0530 Subject: [PATCH 029/615] Make Cronjobs template compatible with DB changes --- .../com_cronjobs/tmpl/cronjobs/default.php | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/administrator/components/com_cronjobs/tmpl/cronjobs/default.php b/administrator/components/com_cronjobs/tmpl/cronjobs/default.php index d92754186da78..c9e37fc7fead9 100644 --- a/administrator/components/com_cronjobs/tmpl/cronjobs/default.php +++ b/administrator/components/com_cronjobs/tmpl/cronjobs/default.php @@ -123,18 +123,18 @@ class="js-draggable" data-url="" data-direction=" foreach ($this->items as $i => $item) : // TODO : Check if $user->authorise() calls work as they should - $orderKey = $item->job_id; + $orderKey = $item->id; $canCreate = $user->authorise('core.create', 'com_cronjobs'); $canEdit = $user->authorise('core.edit', 'com_cronjobs'); $canChange = $user->authorise('core.edit.state', 'com_cronjobs'); ?> + data-item-id="id; ?>" + data-draggable-group="id; ?>"> From ec788fe7797daf81263e6cf8343e2276946fd61a Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Sat, 10 Jul 2021 21:26:15 +0530 Subject: [PATCH 030/615] Add main DB Table class CronjobTable --- .../com_cronjobs/src/Table/CronjobTable.php | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 administrator/components/com_cronjobs/src/Table/CronjobTable.php diff --git a/administrator/components/com_cronjobs/src/Table/CronjobTable.php b/administrator/components/com_cronjobs/src/Table/CronjobTable.php new file mode 100644 index 0000000000000..bb547f22bc2d6 --- /dev/null +++ b/administrator/components/com_cronjobs/src/Table/CronjobTable.php @@ -0,0 +1,66 @@ + + * @license GPL v3 + */ + +namespace Joomla\Component\Cronjobs\Administrator\Table; + +// Restrict direct access +\defined('_JEXEC') or die; + +use Joomla\CMS\Factory; +use Joomla\CMS\Table\Table; +use Joomla\Database\DatabaseDriver; + +/** + * The main DB Table object for com_cronjobs + * + * @since __DEPLOY_VERSION__ + */ +class CronjobTable extends Table +{ + /** + * Indicates that columns do not fully support the NULL value in the database + * + * @var boolean + * @since __DEPLOY_VERSION__ + */ + protected $_supportNullValue = false; + + /** + * Injected into the 'created' column + * + * @var string + * @since __DEPLOY_VERSION__ + */ + private $created; + + /** + * CronjobTable constructor. + * Just passes the DB table name and primary key name to parent constructor. + * + * ? : How do we incorporate the supporting job type tables? + * Is the solution a Table class for each of them + * Or can we have a more elegant arrangement? + * + * @param DatabaseDriver $db A database connector object (?) + * + * @since __DEPLOY_VERSION__ + */ + public function __construct(DatabaseDriver $db) + { + $this->typeAlias = 'com_cronjobs.cronjob'; + $this->created = Factory::getDate()->toSql(); + + // Just for the sake of it, might remove + $this->setColumnAlias('state', 'published'); + + parent::__construct('#__cronjobs', 'id', $db); + } +} From 7f949b407bc2fcd723702bd2f766818c0f323d04 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Sun, 11 Jul 2021 17:31:17 +0530 Subject: [PATCH 031/615] Overload primary JTable methods in CronjobTable CronjobTable now overloads the parent check() and save() methods. Changes remain untested while CronjobModel as of yet. --- .../com_cronjobs/src/Table/CronjobTable.php | 79 ++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/administrator/components/com_cronjobs/src/Table/CronjobTable.php b/administrator/components/com_cronjobs/src/Table/CronjobTable.php index bb547f22bc2d6..7b9a3c910c6bd 100644 --- a/administrator/components/com_cronjobs/src/Table/CronjobTable.php +++ b/administrator/components/com_cronjobs/src/Table/CronjobTable.php @@ -14,6 +14,7 @@ // Restrict direct access \defined('_JEXEC') or die; +use Exception; use Joomla\CMS\Factory; use Joomla\CMS\Table\Table; use Joomla\Database\DatabaseDriver; @@ -39,7 +40,15 @@ class CronjobTable extends Table * @var string * @since __DEPLOY_VERSION__ */ - private $created; + protected $created; + + /** + * Injected into the 'title' column + * + * @var string + * @since __DEPLOY_VERSION__ + */ + protected $title; /** * CronjobTable constructor. @@ -63,4 +72,72 @@ public function __construct(DatabaseDriver $db) parent::__construct('#__cronjobs', 'id', $db); } + + /** + * Overloads the parent check function. + * Performs sanity checks on properties to make + * sure they're safe to store in the DB. + * + * @return boolean True if checks were successful + * + * @throws Exception + * @since __DEPLOY_VERSION__ + */ + public function check() : bool + { + try + { + parent::check(); + } + catch (Exception $e) + { + Factory::getApplication()->enqueueMessage($e->getMessage()); + + return false; + } + + $this->title = htmlspecialchars_decode($this->title, ENT_QUOTES); + + // Set created date if not set. + // ? : Might not need since the constructor already sets this + if (!(int) $this->created) + { + $this->created = Factory::getDate()->toSql(); + } + + // TODO : Add more checks if needed + + return true; + } + + /** + * @param boolean $updateNulls True to update fields even if they're null [?] + * + * @return boolean True if successful [yes?] + * + * @since __DEPLOY_VERSION__ + * @throws Exception + */ + public function store($updateNulls = false) : bool + { + $date = Factory::getDate()->toSql(); + $userId = Factory::getApplication()->getIdentity(); + + // Set creation date if not set + if (!(int) $this->created) + { + $this->created = $date; + } + + // TODO : Should we add modified, modified_by fields? [ ] + + // Set created_by if needed + if (empty($this->created_by)) + { + $this->created_by = $userId; + } + + return parent::store($updateNulls); + } + } From a7d670f9cd0c3ce4c1953b1703b5003411f70d6c Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Sun, 11 Jul 2021 21:07:21 +0530 Subject: [PATCH 032/615] Partially implement CronjobModel ! No support for secondary tables yet This implements all apparently required methods in CronJobModel, but many of the implementations remain incomplete. The model remains untested until CronjobView and the view template implemented and functional. --- .../com_cronjobs/src/Model/CronjobModel.php | 237 +++++++++++++++++- 1 file changed, 230 insertions(+), 7 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Model/CronjobModel.php b/administrator/components/com_cronjobs/src/Model/CronjobModel.php index 07c49abba42c4..d26b0ce6af7a7 100644 --- a/administrator/components/com_cronjobs/src/Model/CronjobModel.php +++ b/administrator/components/com_cronjobs/src/Model/CronjobModel.php @@ -2,26 +2,249 @@ /** * Declares the CronjobModel MVC Model. * - * @package Joomla.Administrator - * @subpackage com_cronjobs + * @package Joomla.Administrator + * @subpackage com_cronjobs * - * @copyright (C) 2021 Open Source Matters, Inc. - * @license GPL v3 + * @copyright (C) 2021 Open Source Matters, Inc. + * @license GPL v3 */ namespace Joomla\Component\Cronjobs\Administrator\Model; // Restrict direct access -\defined('_JEXEC_') or die; +\defined('_JEXEC') or die; +use Exception; +use Joomla\CMS\Form\Form; use Joomla\CMS\MVC\Model\AdminModel; +use Joomla\CMS\Factory; +use Joomla\CMS\Table\Table; /** - * MVC Model to deal operations concerning a single 'Cronjob' entry. + * MVC Model to interact with the Cronjobs DB. + * Implements methods to add, remove, edit cronjobs. * * @since __DEPLOY_VERSION__ */ class CronjobModel extends AdminModel { - // ! TODO + /** + * Maps logical states to their values in the DB + * ? : Do we end up using this? + * + * @var array + * @since __DEPLOY_VERSION__ + */ + protected $STATES = array( + 'enabled' => 1, + 'disabled' => 0 + ); + + /** + * @var string + * @since __DEPLOY_VERSION__ + */ + protected $text_prefix = 'COM_CRONJOBS'; + + /** + * @var string + * @since __DEPLOY_VERSION__ + */ + public $typeAlias = 'com_cronjobs.cronjob'; + + + /** + * Fetches the form object associated with this model. By default, + * loads the corresponding data from the DB and binds it with the form. + * + * @param array $data Data that needs to go into the form + * @param bool $loadData Should the form load its data from the DB? + * + * @return Form|boolean A JForm object on success, false on failure. + * + * @throws Exception + * @since __DEPLOY_VERSION__ + */ + public function getForm($data = array(), $loadData = true) + { + // TODO : Can we need any custom fields [?] + Form::addFieldPath(JPATH_ADMINISTRATOR . 'components/com_cronjobs/src/Field'); + + /* + * * : loadForm() (defined by FormBehaviourTrait) also loads the form data by calling + * loadFormData() : $data [implemented here] and binds it to the form by calling + * $form->bind($data). + */ + $form = $this->loadForm('com_cronjobs.cronjob', 'cronjob', ['control' => 'jform', 'load_data' => $loadData]); + + if (empty($form)) + { + return false; + } + + $user = Factory::getApplication()->getIdentity(); + + /* + * TODO : Check if this works as expected + * ? : Is this the right way to check permissions? (In particular, the assetName) + * ? : Are we guaranteed a $data['id'], does this work OK if it's null? + */ + if (!$user->authorise('core.edit.state', 'com_cronjobs.cronjob.' . $data['id'])) + { + // Disable fields + $form->setFieldAttribute('state', 'disabled', 'true'); + + // No "hacking" ._. + $form->setFieldAttribute('state', 'filter', 'unset'); + } + + return $form; + } + + /** + * Determine whether a record may be deleted taking into consideration + * the user's permissions over the record. + * + * @param object $record The database row/record in question + * + * @return boolean True if the record may be deleted + * + * @throws Exception + * @since __DEPLOY_VERSION__ + */ + protected function canDelete($record): bool + { + // Record doesn't exist, can't delete + if (empty($record->id)) + { + return false; + } + + // TODO : Check if this is the right way to check authority (in particular the assetName) + return Factory::getApplication()->getIdentity()->authorise('core.delete', 'com.cronjobs.cronjob.' . $record->id); + } + + /** + * Populate the model state based on user input. + * ? : Do we need this? + * The parent method already sets the primary key + * for the Table object, which might be all we need here. + * + * @return void + * + * @throws Exception + * @since __DEPLOY_VERSION__ + */ + protected function populateState(): void + { + parent::populateState(); + } + + /** + * Probably don't _need_ to define this method since the parent getTable() + * implicitly deduces $name and $prefix anyways. This does make the object + * more transparent though. + * + * @param string $name Name of the table + * @param string $prefix Class prefix + * @param array $options Model config array + * + * @return Table + * + * @throws Exception + * @since __DEPLOY_VERSION__ + */ + public function getTable($name = 'Cronjob', $prefix = 'Table', $options = array()): Table + { + return parent::getTable($name, $prefix, $options); + } + + /** + * Fetches the data to be injected into the form + * + * @return array Associative array of form data. + * + * @throws Exception + * @since version + */ + protected function loadFormData(): array + { + /* + * Check session for previously entered form data + * ? : How and where does this data get saved? + * + * ! : getUserState() makes the IDE scream "Potentially Polymorphic Call" + * because ConsoleApplication and StubGenerator don't implement the method. + * While we'll never call loadFormData() from those, it looks ugly as it is. + * Is there any way to get rid of it? + */ + $app = Factory::getApplication(); + $data = $app->getUserState('com_cronjobs.edit.cronjob.data', array()); + + // If the UserState didn't have form data, we fetch it with getItem() + if (empty($data)) + { + $data = $this->getItem(); + + // TODO : Do we need any _priming_ on the $data here? + } + + // ? What would this do here? Is it needed or (just) good practice? + $this->preprocessData('com_cronjobs.cronjob', $data); + + return $data; + } + + /** + * Overloads the parent getItem() method. + * ! : Currently does nothing + * + * ? : Is this needed at all? + * Should be removed if we end up not needing any special handling. + * + * @param integer $pk Primary key + * + * @return object|boolean Object on success, false on failure + * + * @since __DEPLOY_VERSION__ + */ + public function getItem($pk = null) + { + // TODO : Add CronjobModel specific handling or remove ⚠ + return parent::getItem($pk); + } + + /** + * @param array $data The form data + * + * @return boolean True on success, false on failure + * + * @since __DEPLOY_VERSION__ + */ + public function save($data): bool + { + /** + * @var object $field Holds the record we're saving $data to + */ + $field = null; + + if (isset($data['id'])) + { + $field = $this->getItem($data['id']); + } + + /* + * The parent save() takes care of saving to the main + * `#__cronjobs` table + */ + if (! parent::save($data)) + { + return false; + } + + // TODO: Handle the type-specific tables below! ⚠ + + // No failures if we get here + return true; + } } From 5e2eadf79a3a670d5478ef662ab2a01d6652c886 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Sun, 11 Jul 2021 23:18:45 +0530 Subject: [PATCH 033/615] Implement CronjobView The toolbar might still need some work but it looks OK until it can be tested with CronjobModel and the view template in place. --- .../src/View/Cronjob/HtmlView.php | 103 ++++++++++++++++-- 1 file changed, 91 insertions(+), 12 deletions(-) diff --git a/administrator/components/com_cronjobs/src/View/Cronjob/HtmlView.php b/administrator/components/com_cronjobs/src/View/Cronjob/HtmlView.php index 5ff8a6b5a8a36..e121af1cae608 100644 --- a/administrator/components/com_cronjobs/src/View/Cronjob/HtmlView.php +++ b/administrator/components/com_cronjobs/src/View/Cronjob/HtmlView.php @@ -2,19 +2,25 @@ /** * Declares the MVC View for CronjobModel. * - * @package Joomla.Administrator - * @subpackage com_cronjobs + * @package Joomla.Administrator + * @subpackage com_cronjobs * - * @copyright (C) 2021 Open Source Matters, Inc. - * @license GPL v3 + * @copyright (C) 2021 Open Source Matters, Inc. + * @license GPL v3 */ namespace Joomla\Component\Cronjobs\Administrator\View\Cronjob; // Restrict direct access -\defined('_JEXEC_') or die; +\defined('_JEXEC') or die; +use Exception; +use JObject; +use Joomla\CMS\Factory; +use Joomla\CMS\Language\Text; use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView; +use Joomla\CMS\Helper\ContentHelper; +use Joomla\CMS\Toolbar\ToolbarHelper; /** * The MVC View AddCronjob @@ -22,14 +28,14 @@ * @package Joomla.Administrator * @subpackage com_cronjobs * - * @since __DEPLOY_VERSION__ + * @since __DEPLOY_VERSION__ */ class HtmlView extends BaseHtmlView { /** * The Form object * - * @var \JForm + * @var \JForm * @since __DEPLOY__VERSION__ */ protected $form; @@ -37,7 +43,7 @@ class HtmlView extends BaseHtmlView /** * The active item * - * @var object + * @var object * @since __DEPLOY__VERSION__ */ protected $item; @@ -45,22 +51,95 @@ class HtmlView extends BaseHtmlView /** * The model state * - * @var \JObject + * @var JObject * @since __DEPLOY__VERSION__ */ protected $state; + /** + * The actions the user is authorised to perform + * + * @var JObject + * @since 4.0.0 + */ + protected $canDo; + /** * @param string $tpl The name of the template file to parse; automatically searches through the template paths. * - * @return void + * @return void + * + * @throws Exception + * @since __DEPLOY_VERSION__ + */ + public function display($tpl = null): void + { + /* + * Will call the getForm() method of cronjobModel + */ + $this->form = $this->get('Form'); + $this->item = $this->get('Item'); + + // ? : Where is getState() implemented? [✔] (StateBehaviourTrait) + $this->state = $this->get('State'); + $this->canDo = ContentHelper::getActions('com_cronjobs', 'cronjob', $this->item->id); + + $this->addToolbar(); + parent::display($tpl); + } + + /** + * Adds the page title and toolbar + * + * @return void * + * @throws Exception * @since __DEPLOY_VERSION__ */ - public function display($tpl = null) : void + protected function addToolbar(): void { - // ! TODO + $app = Factory::getApplication(); + + /** @noinspection SpellCheckingInspection */ + $app->getInput()->set('hidemainmenu', true); + $user = $app->getIdentity(); + $userId = $user->id; + $isNew = ($this->item->id == 0); + $canDo = $this->canDo; + + // TODO : icon? + ToolbarHelper::title($isNew ? Text::_('COM_CRONJOBS_MANAGER_CRONJOB_NEW') : Text::_('COM_CRONJOBS_MANAGER_CRONJOB_EDIT'), 'tags'); + + // Goes into ToolbarHelper::saveGroup() + $toolbarButtons = []; + + // For a new cronjob, check if user has 'core.create' access + if ($isNew && $canDo->get('core.create')) + { + // The cronjob.apply task maps to the save() method in CronjobController + ToolbarHelper::apply('cronjob.apply'); + + $toolbarButtons[] = ['save', 'module.save']; + } + else + { + if (!$isNew && $canDo->get('core.edit')) + { + ToolbarHelper::apply('cronjob.apply'); + $toolbarButtons[] = ['save', 'module.save']; + + // TODO | ? : Do we need save2new and save2copy? If yes, need to support in the Model, + // here and the Controller. + } + } + + ToolbarHelper::saveGroup( + $toolbarButtons, + 'btn-success' + ); + + ToolbarHelper::cancel('cronjob.cancel', $isNew ? 'JTOOLBAR_CANCEL' : 'JTOOLBAR_CLOSE'); } } From aa7e46ba626c46ecb57d3797ca8ababcc165f1df Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Mon, 12 Jul 2021 16:05:50 +0530 Subject: [PATCH 034/615] Fix loadFormData() return type in CronjobModel Changes return type from 'array' to 'object' --- .../components/com_cronjobs/src/Model/CronjobModel.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Model/CronjobModel.php b/administrator/components/com_cronjobs/src/Model/CronjobModel.php index d26b0ce6af7a7..012c37b03c367 100644 --- a/administrator/components/com_cronjobs/src/Model/CronjobModel.php +++ b/administrator/components/com_cronjobs/src/Model/CronjobModel.php @@ -162,12 +162,12 @@ public function getTable($name = 'Cronjob', $prefix = 'Table', $options = array( /** * Fetches the data to be injected into the form * - * @return array Associative array of form data. + * @return object Associative array of form data. * * @throws Exception - * @since version + * @since __DEPLOY_VERSION__ */ - protected function loadFormData(): array + protected function loadFormData(): object { /* * Check session for previously entered form data @@ -233,6 +233,8 @@ public function save($data): bool $field = $this->getItem($data['id']); } + // TODO : Unset fields based on type an trigger selected + /* * The parent save() takes care of saving to the main * `#__cronjobs` table From 30f6a9d0ed6e42964d991df5e10766b8f91ba0e4 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Mon, 12 Jul 2021 16:31:52 +0530 Subject: [PATCH 035/615] Fix URLs in CronjobsView template --- .../com_cronjobs/tmpl/cronjobs/default.php | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/administrator/components/com_cronjobs/tmpl/cronjobs/default.php b/administrator/components/com_cronjobs/tmpl/cronjobs/default.php index c9e37fc7fead9..f0e4422ba0daa 100644 --- a/administrator/components/com_cronjobs/tmpl/cronjobs/default.php +++ b/administrator/components/com_cronjobs/tmpl/cronjobs/default.php @@ -55,7 +55,7 @@ items)) - : +: ?>
@@ -67,7 +67,7 @@ class="visually-hidden"> items)) - : +: ?>
- job_id, false, 'cid', 'cb', $item->name); ?> + job_id, false, 'cid', 'cb', $item->name); ?> - + - + @@ -155,19 +167,29 @@ class="js-draggable" data-url="" data-direction=" + if ($canEdit) + : + ?> escape($item->name); ?> - + escape($item->name); ?> note)): ?> + if (empty($item->note)) + : + ?> - + escape($item->note)); ?> - job_id; ?> + job_id; ?>
- job_id, false, 'cid', 'cb', $item->name); ?> + id, false, 'cid', 'cb', $item->title); ?> @@ -162,7 +162,7 @@ class="js-draggable" data-url="" data-direction=" - enabled, $i, 'cronjobs.', $canChange); ?> + state, $i, 'cronjobs.', $canChange); ?> @@ -170,14 +170,14 @@ class="js-draggable" data-url="" data-direction=" if ($canEdit) : ?> - - escape($item->name); ?> + + escape($item->title); ?> - escape($item->name); ?> + escape($item->title); ?> " data-direction=" - job_id; ?> + id; ?>
@@ -115,13 +115,13 @@ class="visually-hidden"> class="js-draggable" data-url="" data-direction="" data-nested="true"> items as $i => $item) - : + : // TODO : Check if $user->authorise() calls work as they should $orderKey = $item->id; $canCreate = $user->authorise('core.create', 'com_cronjobs'); @@ -142,11 +142,11 @@ class="js-draggable" data-url="" data-direction=" $iconClass = ''; if (!$canChange) - { + { $iconClass = ' inactive'; } elseif (!$saveOrder) - { + { $iconClass = ' inactive" title="' . Text::_('JORDERINGDISABLED'); } ?> @@ -154,7 +154,7 @@ class="js-draggable" data-url="" data-direction=" @@ -168,27 +168,27 @@ class="js-draggable" data-url="" data-direction=" - - - - - class="js-draggable" data-url="" data-direction="" data-nested="true" > items as $i => $item): - // TODO : Check if $user->authorise() calls work as they should $canCreate = $user->authorise('core.create', 'com_cronjobs'); $canEdit = $user->authorise('core.edit', 'com_cronjobs'); $canChange = $user->authorise('core.edit.state', 'com_cronjobs'); @@ -160,7 +158,7 @@ class="js-draggable" data-url="" data-direction=" state, $i, 'cronjobs.', $canChange); ?> - + class="js-draggable" data-url="" data-direction="" data-nested="true" > items as $i => $item): - // TODO : Check if $user->authorise() calls work as they should $canCreate = $user->authorise('core.create', 'com_cronjobs'); $canEdit = $user->authorise('core.edit', 'com_cronjobs'); $canChange = $user->authorise('core.edit.state', 'com_cronjobs'); @@ -160,7 +158,7 @@ class="js-draggable" data-url="" data-direction=" state, $i, 'cronjobs.', $canChange); ?> - +
- escape($item->title); ?> escape($item->title); ?> note)) - : + : ?> escape($item->note)); ?> @@ -199,7 +199,7 @@ class="js-draggable" data-url="" data-direction=" @@ -224,16 +224,16 @@ class="js-draggable" data-url="" data-direction=" pagination->getListFooter(); ?> - authorise('core.create', 'com_tags') - && $user->authorise('core.edit', 'com_tags') - && $user->authorise('core.edit.state', 'com_tags')) + authorise('core.create', 'com_cronjobs') + && $user->authorise('core.edit', 'com_cronjobs') + && $user->authorise('core.edit.state', 'com_cronjobs')) : ?> Text::_('COM_TAGS_BATCH_OPTIONS'), + 'title' => Text::_('com_cronjobs_BATCH_OPTIONS'), 'footer' => $this->loadTemplate('batch_footer'), ), $this->loadTemplate('batch_body') From 1f98a5101d074863a5985eff51420372d4091d15 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Mon, 12 Jul 2021 17:12:00 +0530 Subject: [PATCH 036/615] Implement CronjobController Due testing and cleanup once the view template is up. --- .../src/Controller/CronjobController.php | 96 ++++++++++++++++++- 1 file changed, 91 insertions(+), 5 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Controller/CronjobController.php b/administrator/components/com_cronjobs/src/Controller/CronjobController.php index c4f1f58d1eb2e..b4761bbd3aeda 100644 --- a/administrator/components/com_cronjobs/src/Controller/CronjobController.php +++ b/administrator/components/com_cronjobs/src/Controller/CronjobController.php @@ -2,13 +2,19 @@ /** * Declares the MVC controller for CronjobModel. * - * @package Joomla.Administrator - * @subpackage com_cronjobs + * * : Model will implicitly default to CronjobModel through a call to getModel() * - * @copyright (C) 2021 Open Source Matters, Inc. - * @license GNU General Public License version 2 or later; see LICENSE.txt + * TODO : Check if the controller needs more methods + * + * @package Joomla.Administrator + * @subpackage com_cronjobs + * + * @copyright (C) 2021 Open Source Matters, Inc. + * @license GPL v3 */ +namespace Joomla\Component\Cronjobs\Administrator\Controller; + // Restrict direct access \defined('_JEXEC') or die; @@ -21,5 +27,85 @@ */ class CronjobController extends FormController { - // ! TODO + /** + * Add a new record + * + * ! : Just acting as a proxy to the parent method at the moment + * Due removal if no additional handling needed here ⚠ + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + */ + public function add(): bool + { + // TODO: Change the autogenerated stub + return parent::add(); + } + + /** + * Edit an existing record + * + * ! : Just acting as a proxy to the parent method atm + * Due removal if no additional handling needed here ⚠ + * + * @param string $key Name of primary key from urlVar + * @param string $urlVar Name of urlVar if different from primary key [?] + * + * @return boolean True if access user has sufficient privileges + * + * @since __DEPLOY_VERSION__ + */ + public function edit($key = null, $urlVar = null): bool + { + // TODO: Change the autogenerated stub + return parent::edit($key, $urlVar); + } + + /** + * Check if user has permissions to add an entry + * + * ! : Does nothing at the moment + * Remove if no special handling required ⚠ + * + * @param array $data Array of input data + * + * @return boolean True if user can add an entry + * + * @since __DEPLOY_VERSION__ + */ + protected function allowAdd($data = array()): bool + { + // TODO: Change or remove + return parent::allowAdd($data); + } + + /** + * Check if user has the authority to edit an asset + * + * @param array $data Array of input data + * @param string $key Name of key for primary key, defaults to 'id' + * + * @return boolean True if user is allowed to edit record + * + * @since __DEPLOY_VERSION__ + */ + protected function allowEdit($data = array(), $key = 'id'): bool + { + // Extract the recordId from $data, will come in handy + $recordId = (int) $data[$key] ?? 0; + + /* + * Zero record (id:0), return component edit permission by calling parent controller method + * ? : Is this the right way to do this? + */ + if (!$recordId) + { + return parent::allowEdit($data, $key); + } + + // TODO : Check if this is working as expected. + return $this->app->getIdentity()->authorise('core.edit', 'com_cronjobs.cronjob.' . $recordId); + + } } From eb466e4ec4a61969a55297e644edcf7864b2c53e Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Mon, 12 Jul 2021 19:14:16 +0530 Subject: [PATCH 037/615] Bugfix and update DisplayController Updates DisplayController with the updated state of the component, removes unused imports and fixes a minor bug with access checking. --- .../src/Controller/DisplayController.php | 25 ++++++++----------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Controller/DisplayController.php b/administrator/components/com_cronjobs/src/Controller/DisplayController.php index b6bd9e688c5f4..89b124a672e52 100644 --- a/administrator/components/com_cronjobs/src/Controller/DisplayController.php +++ b/administrator/components/com_cronjobs/src/Controller/DisplayController.php @@ -1,12 +1,12 @@ - * @license GNU General Public License version 2 or later; see LICENSE.txt + * @license GPL v3 */ namespace Joomla\Component\Cronjobs\Administrator\Controller; @@ -16,10 +16,8 @@ use Exception; use Joomla\CMS\MVC\Controller\BaseController; -use Joomla\CMS\MVC\Controller\ControllerInterface; use Joomla\CMS\Language\Text; use Joomla\CMS\Router\Route; -use Joomla\CMS\Uri\Uri; /** @@ -27,34 +25,30 @@ * * @since __DEPLOY_VERSION__ */ - class DisplayController extends BaseController { /** - * ! View 'cronjobs' has not been implemented yet - * * @var string * @since __DEPLOY_VERSION__ */ protected $default_view = 'cronjobs'; /** - * @param boolean $cachable If true, the view output will be cached - * @param array $urlparams An array of safe url parameters and their variable types, for valid values see {@link InputFilter::clean()}. + * @param boolean $cachable If true, the view output will be cached + * @param array $urlparams An array of safe url parameters and their variable types, for valid values see {@link InputFilter::clean()}. * - * @return BaseController|boolean Returns either this object itself, to support chaining, or false on failure. + * @return BaseController|boolean Returns either a BaseController object to support chaining, or false on failure * * @throws Exception * @since __DEPLOY_VERSION__ */ public function display($cachable = false, $urlparams = array()) { - // ! Untested $layout = $this->input->get('layout', 'default'); - $id = $this->input->getInt('id'); + $id = $this->input->getInt('id'); // Check for edit form. - if ($layout == 'edit' && !$this->checkEditId('com_cronjobs.edit.module', $id)) + if ($layout == 'edit' && !$this->checkEditId('com_cronjobs.edit.cronjob', $id)) { // Somehow the person just went to the form - we don't allow that. if (!\count($this->app->getMessageQueue())) @@ -67,6 +61,7 @@ public function display($cachable = false, $urlparams = array()) return false; } + // Let the parent method take over return parent::display($cachable, $urlparams); } } From 05c37fa10d0fa70376abdfd364b0df2fe132af34 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Tue, 13 Jul 2021 01:05:04 +0530 Subject: [PATCH 038/615] Update XML for CronjobView form --- .../components/com_cronjobs/forms/cronjob.xml | 128 ++++++++++++++++-- 1 file changed, 116 insertions(+), 12 deletions(-) diff --git a/administrator/components/com_cronjobs/forms/cronjob.xml b/administrator/components/com_cronjobs/forms/cronjob.xml index d5e285f460f2c..15c81f9feea0b 100644 --- a/administrator/components/com_cronjobs/forms/cronjob.xml +++ b/administrator/components/com_cronjobs/forms/cronjob.xml @@ -1,18 +1,122 @@ + +
- + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ +
+ + + + + + + +
+ + +
+ + + + + + + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+ - From c298305a9c0a0aafe32c1bc61ce5f200e057e728 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Tue, 13 Jul 2021 01:05:27 +0530 Subject: [PATCH 039/615] Add CronjobView template Might need some changes along with the XML to support xvisits trigger and more. As of committing, the toolbar is not functional - CronjobView should be responsible. --- .../com_cronjobs/tmpl/cronjob/edit.php | 127 ++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 administrator/components/com_cronjobs/tmpl/cronjob/edit.php diff --git a/administrator/components/com_cronjobs/tmpl/cronjob/edit.php b/administrator/components/com_cronjobs/tmpl/cronjob/edit.php new file mode 100644 index 0000000000000..2e6c989834b5b --- /dev/null +++ b/administrator/components/com_cronjobs/tmpl/cronjob/edit.php @@ -0,0 +1,127 @@ + + * @license GPL v3 + * + * @codingStandardsIgnoreStart + */ + +// Restrict direct access +\defined('_JEXEC') or die; + +use Joomla\CMS\Factory; +use Joomla\CMS\HTML\HTMLHelper; +use Joomla\CMS\Language\Text; +use Joomla\CMS\Layout\LayoutHelper; +use Joomla\CMS\Router\Route; + +/** @var \Joomla\Component\Cronjobs\Administrator\View\Cronjob\HtmlView $this */ + + +$wa = $this->document->getWebAssetManager(); + +$wa->useScript('keepalive'); +$wa->useScript('form.validate'); + +try +{ + /** @var Joomla\CMS\Application\WebApplication $app */ + $app = Factory::getApplication(); +} catch (Exception $e) +{ + // ? : Is there a better way? + die('Failed to fetch application object'); +} + +$input = $app->getInput(); + +// ? +$this->ignore_fieldsets = []; + +// ? : Are these of use here? +$isModal = $input->get('layout') === 'modal'; +$layout = $isModal ? 'modal' : 'edit'; +$tmpl = $isModal || $input->get('tmpl', '', 'cmd') === 'component' ? '&tmpl=component' : ''; +?> + + +
+ + + + + +
+ 'details')); ?> + + + item->id) ? Text::_('COM_CRONJOBS_NEW_CRONJOB') : Text::_('COM_CRONJOBS_EDIT_CRONJOB') + ); + ?> +
+
+
+ + form->renderFieldset('basic'); ?> +
+ +
+ + form->renderFieldset('cron-options') ?> +
+
+
+ form->renderFieldset('aside') ?> +
+
+ + + + +
+
+
+ + form->renderFieldset('exec_hist'); ?> +
+
+
+ + + + +
+
+
+ + form->renderFieldset('details'); ?> +
+
+
+ + + + canDo->get('core.admin')) : ?> + +
+ +
+ form->getInput('rules'); ?> +
+
+ + + + +
+ +
From 88dea46f1f89293342a36a6c632232672bebecc3 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Tue, 13 Jul 2021 01:33:22 +0530 Subject: [PATCH 040/615] Bugfix and update CronjobView template, XML Adds a hidden task field and some other minor changes to the template, fixing the issue with submission/cancelling not working. Moves the 'id' field out of the basic fieldset in XML to fix duplication in the rendered template and have the title placement consistent with other core components. --- .../components/com_cronjobs/forms/cronjob.xml | 36 +++++++++---------- .../com_cronjobs/tmpl/cronjob/edit.php | 10 +++--- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/administrator/components/com_cronjobs/forms/cronjob.xml b/administrator/components/com_cronjobs/forms/cronjob.xml index 15c81f9feea0b..3a539147ec8e3 100644 --- a/administrator/components/com_cronjobs/forms/cronjob.xml +++ b/administrator/components/com_cronjobs/forms/cronjob.xml @@ -2,13 +2,13 @@
-
- - + + +
- - - - - - - + + + + + + +
diff --git a/administrator/components/com_cronjobs/tmpl/cronjob/edit.php b/administrator/components/com_cronjobs/tmpl/cronjob/edit.php index 2e6c989834b5b..b71792ba7828a 100644 --- a/administrator/components/com_cronjobs/tmpl/cronjob/edit.php +++ b/administrator/components/com_cronjobs/tmpl/cronjob/edit.php @@ -49,8 +49,8 @@ @@ -120,8 +120,10 @@ class="form-validate">
- - + + form->getInput('context'); ?> + + From 41b70966326cb088088d1acf4d926f3cae17918e Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Tue, 13 Jul 2021 01:52:04 +0530 Subject: [PATCH 041/615] Update CronjobsView template Cleans up styling and adds ignore flag for phpcs --- .../com_cronjobs/tmpl/cronjobs/default.php | 114 ++++++++---------- 1 file changed, 52 insertions(+), 62 deletions(-) diff --git a/administrator/components/com_cronjobs/tmpl/cronjobs/default.php b/administrator/components/com_cronjobs/tmpl/cronjobs/default.php index f0e4422ba0daa..c77aaa3d9d3de 100644 --- a/administrator/components/com_cronjobs/tmpl/cronjobs/default.php +++ b/administrator/components/com_cronjobs/tmpl/cronjobs/default.php @@ -5,6 +5,8 @@ * * @copyright (C) 2021 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt + * + * @codingStandardsIgnoreStart */ defined('_JEXEC') or die; @@ -22,8 +24,7 @@ try { $app = Factory::getApplication(); -} -catch (Exception $e) +} catch (Exception $e) { die('Failed to get app'); } @@ -55,7 +56,7 @@ items)) -: + : ?>
@@ -67,7 +68,7 @@ class="visually-hidden"> items)) -: + : ?> @@ -83,7 +84,8 @@ class="visually-hidden"> - class="js-draggable" data-url="" data-direction="" data-nested="true"> - items as $i => $item) - : + class="js-draggable" data-url="" data-direction="" data-nested="true" > + items as $i => $item): // TODO : Check if $user->authorise() calls work as they should $orderKey = $item->id; $canCreate = $user->authorise('core.create', 'com_cronjobs'); @@ -134,77 +133,64 @@ class="js-draggable" data-url="" data-direction=" data-draggable-group="id; ?>"> + + - - + + + + +
- + @@ -115,13 +117,10 @@ class="visually-hidden">
- id, false, 'cid', 'cb', $item->title); ?> + id, false, 'cid', 'cb', $item->title); ?> - - - - - + + + + + + + state, $i, 'cronjobs.', $canChange); ?> - - - escape($item->title); ?> - + + escape($item->title); ?> + escape($item->title); ?> - note)) - : - ?> + note)): ?> - + escape($item->note)); ?> escape($item->type); ?> @@ -212,24 +198,27 @@ class="js-draggable" data-url="" data-direction=" - id; ?> + id; ?>
- + pagination->getListFooter(); ?> - + + authorise('core.create', 'com_cronjobs') - && $user->authorise('core.edit', 'com_cronjobs') - && $user->authorise('core.edit.state', 'com_cronjobs')) - : - ?> - authorise('core.edit', 'com_cronjobs') + && $user->authorise('core.edit.state', 'com_cronjobs')): ?> + + " data-direction=" 'footer' => $this->loadTemplate('batch_footer'), ), $this->loadTemplate('batch_body') - ); ?> - + ); ?> + + From 0b452d255fd270a5166d8be831b9f68afb113e99 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Tue, 13 Jul 2021 02:52:55 +0530 Subject: [PATCH 042/615] Bugfix CronjobTable Makes 2 CronjobTable properties required by the DB public (oops!) This fixes a db driver error that indicated 'title' was not set even when it was passed through the CronjobView form. --- .../components/com_cronjobs/src/Table/CronjobTable.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Table/CronjobTable.php b/administrator/components/com_cronjobs/src/Table/CronjobTable.php index 7b9a3c910c6bd..712344a9cfec7 100644 --- a/administrator/components/com_cronjobs/src/Table/CronjobTable.php +++ b/administrator/components/com_cronjobs/src/Table/CronjobTable.php @@ -40,7 +40,7 @@ class CronjobTable extends Table * @var string * @since __DEPLOY_VERSION__ */ - protected $created; + public $created; /** * Injected into the 'title' column @@ -48,7 +48,7 @@ class CronjobTable extends Table * @var string * @since __DEPLOY_VERSION__ */ - protected $title; + public $title; /** * CronjobTable constructor. From cb563e032138d2f2fb2bba06226ee3fe2d9dd8aa Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Tue, 13 Jul 2021 03:11:36 +0530 Subject: [PATCH 043/615] Update filter XML for CronjobsView --- .../components/com_cronjobs/forms/cronjob.xml | 3 ++- .../com_cronjobs/forms/filter_cronjobs.xml | 12 ++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/administrator/components/com_cronjobs/forms/cronjob.xml b/administrator/components/com_cronjobs/forms/cronjob.xml index 3a539147ec8e3..f4551e20ee012 100644 --- a/administrator/components/com_cronjobs/forms/cronjob.xml +++ b/administrator/components/com_cronjobs/forms/cronjob.xml @@ -5,7 +5,8 @@
diff --git a/administrator/components/com_cronjobs/forms/filter_cronjobs.xml b/administrator/components/com_cronjobs/forms/filter_cronjobs.xml index 12d6388df608a..8e6aefb6cf748 100644 --- a/administrator/components/com_cronjobs/forms/filter_cronjobs.xml +++ b/administrator/components/com_cronjobs/forms/filter_cronjobs.xml @@ -13,7 +13,7 @@ /> - - - - + + + + From 0c92f1842232c872814ae8bc17f296a734dd5328 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Tue, 13 Jul 2021 03:15:32 +0530 Subject: [PATCH 044/615] Fix CronjobView toolbar tasks The buttons now correctly to CronjobController tasks instead of ModuleController's. --- .../components/com_cronjobs/src/View/Cronjob/HtmlView.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/administrator/components/com_cronjobs/src/View/Cronjob/HtmlView.php b/administrator/components/com_cronjobs/src/View/Cronjob/HtmlView.php index e121af1cae608..534accf7b810e 100644 --- a/administrator/components/com_cronjobs/src/View/Cronjob/HtmlView.php +++ b/administrator/components/com_cronjobs/src/View/Cronjob/HtmlView.php @@ -120,14 +120,14 @@ protected function addToolbar(): void // The cronjob.apply task maps to the save() method in CronjobController ToolbarHelper::apply('cronjob.apply'); - $toolbarButtons[] = ['save', 'module.save']; + $toolbarButtons[] = ['save', 'cronjob.save']; } else { if (!$isNew && $canDo->get('core.edit')) { ToolbarHelper::apply('cronjob.apply'); - $toolbarButtons[] = ['save', 'module.save']; + $toolbarButtons[] = ['save', 'cronjob.save']; // TODO | ? : Do we need save2new and save2copy? If yes, need to support in the Model, // here and the Controller. From c8c3e9191c73ef597b04004312edbec484e58c28 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Tue, 13 Jul 2021 16:28:06 +0530 Subject: [PATCH 045/615] Update database tables Removes 2 NOT NULL constraints and changes interval datatype --- .../components/com_cronjobs/sql/mysql/install.sql | 6 +++--- .../com_cronjobs/sql/postgresql/install.sql | 6 +++--- .../sql/updates/mysql/2021-07-12.mysql.sql | 11 +++++++++++ .../sql/updates/postgresql/2021-07-12.postgre.sql | 12 ++++++++++++ 4 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 administrator/components/com_cronjobs/sql/updates/mysql/2021-07-12.mysql.sql create mode 100644 administrator/components/com_cronjobs/sql/updates/postgresql/2021-07-12.postgre.sql diff --git a/administrator/components/com_cronjobs/sql/mysql/install.sql b/administrator/components/com_cronjobs/sql/mysql/install.sql index 30d4c6e4c8b44..c484350770438 100644 --- a/administrator/components/com_cronjobs/sql/mysql/install.sql +++ b/administrator/components/com_cronjobs/sql/mysql/install.sql @@ -9,11 +9,11 @@ CREATE TABLE IF NOT EXISTS `#__cronjobs` `type` ENUM ('script', 'plugin') NOT NULL DEFAULT 'script', -- Trigger type, default to PseudoCron (compatible everywhere). `trigger` ENUM ('pseudo_cron', 'cron', 'visit_count') NOT NULL DEFAULT 'pseudo_cron' COMMENT 'Defines how job is triggered', - `execution_interval` INT NOT NULL COMMENT 'Configured time between executions, in seconds', + `execution_interval` TIME NOT NULL COMMENT 'Configured time between executions,in HH:MM:SS format', `state` TINYINT NOT NULL DEFAULT FALSE, `last_exit_code` INT(11) NOT NULL DEFAULT '0' COMMENT 'Exit code when job was last run', - `last_execution` DATETIME NOT NULL COMMENT 'Timestamp of last run', - `next_execution` DATETIME NOT NULL COMMENT 'Timestamp of next (planned) run, referred for execution on trigger', + `last_execution` DATETIME COMMENT 'Timestamp of last run', + `next_execution` DATETIME COMMENT 'Timestamp of next (planned) run, referred for execution on trigger', `times_executed` INT(11) DEFAULT '0' COMMENT 'Count of successful triggers', `times_failed` INT(11) DEFAULT '0' COMMENT 'Count of failures', `note` TEXT, diff --git a/administrator/components/com_cronjobs/sql/postgresql/install.sql b/administrator/components/com_cronjobs/sql/postgresql/install.sql index b71273be89410..b220f04354e13 100644 --- a/administrator/components/com_cronjobs/sql/postgresql/install.sql +++ b/administrator/components/com_cronjobs/sql/postgresql/install.sql @@ -25,12 +25,12 @@ CREATE TABLE IF NOT EXISTS "#__cronjobs" "asset_id" BIGINT NOT NULL DEFAULT '0', "title" VARCHAR(255) NOT NULL, "type" JOB_TYPE, - "execution_interval" INT NOT NULL, + "execution_interval" INTERVAL NOT NULL, "trigger" TRIGGER_TYPE NOT NULL DEFAULT 'pseudo_cron', "state" SMALLINT NOT NULL DEFAULT '0', "last_exit_code" INT NOT NULL DEFAULT '0', - "last_execution" TIMESTAMP NOT NULL, - "next_execution" TIMESTAMP NOT NULL, + "last_execution" TIMESTAMP, + "next_execution" TIMESTAMP, "times_executed" TIMESTAMP NOT NULL, "times_failed" INT DEFAULT '0', "note" TEXT DEFAULT '', diff --git a/administrator/components/com_cronjobs/sql/updates/mysql/2021-07-12.mysql.sql b/administrator/components/com_cronjobs/sql/updates/mysql/2021-07-12.mysql.sql new file mode 100644 index 0000000000000..632d23cbb7d6b --- /dev/null +++ b/administrator/components/com_cronjobs/sql/updates/mysql/2021-07-12.mysql.sql @@ -0,0 +1,11 @@ +-- Modify execution_interval column, changes type to TIME [⚠ experimental] +ALTER TABLE `#__cronjobs` + MODIFY `execution_interval` TIME; + +-- Remove NOT NULL constraint from last_execution +ALTER TABLE `#__cronjobs` + MODIFY `last_execution` DATETIME COMMENT 'Timestamp of last run'; + +-- Remove NOT NULL constraint from next_execution +ALTER TABLE `#__cronjobs` + MODIFY `next_execution` DATETIME COMMENT 'Timestamp of next (planned) run, referred for execution on trigger'; diff --git a/administrator/components/com_cronjobs/sql/updates/postgresql/2021-07-12.postgre.sql b/administrator/components/com_cronjobs/sql/updates/postgresql/2021-07-12.postgre.sql new file mode 100644 index 0000000000000..804d04d47b0fd --- /dev/null +++ b/administrator/components/com_cronjobs/sql/updates/postgresql/2021-07-12.postgre.sql @@ -0,0 +1,12 @@ +-- Modify execution_interval column, changes type to INTERVAL [⚠ experimental] +ALTER TABLE IF EXISTS "#__cronjobs" + ALTER COLUMN "execution_interval" TYPE INTERVAL; + +-- Remove NOT NULL constraint from last_execution +ALTER TABLE IF EXISTS "#__cronjobs" + ALTER COLUMN "last_execution" TYPE TIMESTAMP; + +-- Remove NOT NULL constraint from next_execution +ALTER TABLE IF EXISTS "#__cronjobs" + ALTER COLUMN "next_execution" TYPE TIMESTAMP; + From 9cd2df6dec94897f73741151278f5cc21ef1581e Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Tue, 13 Jul 2021 16:58:13 +0530 Subject: [PATCH 046/615] Improve record fetching, handling in CronjobModel Fixes user auth, record fetching and handling, in particular for execution intervals. Still feels kind of hacky, so due a polish with a custom field (post scrutiny). --- .../com_cronjobs/src/Model/CronjobModel.php | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Model/CronjobModel.php b/administrator/components/com_cronjobs/src/Model/CronjobModel.php index 012c37b03c367..bb898df4e0de6 100644 --- a/administrator/components/com_cronjobs/src/Model/CronjobModel.php +++ b/administrator/components/com_cronjobs/src/Model/CronjobModel.php @@ -67,6 +67,8 @@ class CronjobModel extends AdminModel */ public function getForm($data = array(), $loadData = true) { + $input = Factory::getApplication()->getInput(); + // TODO : Can we need any custom fields [?] Form::addFieldPath(JPATH_ADMINISTRATOR . 'components/com_cronjobs/src/Field'); @@ -87,9 +89,9 @@ public function getForm($data = array(), $loadData = true) /* * TODO : Check if this works as expected * ? : Is this the right way to check permissions? (In particular, the assetName) - * ? : Are we guaranteed a $data['id'], does this work OK if it's null? + * ? : Are we guaranteed a $data['id'], does this work OK if it's null? A : [NO, IT IS NOT GUARANTEED] */ - if (!$user->authorise('core.edit.state', 'com_cronjobs.cronjob.' . $data['id'])) + if (!$user->authorise('core.edit.state', 'com_cronjobs.cronjob.' . $input->get('id'))) { // Disable fields $form->setFieldAttribute('state', 'disabled', 'true'); @@ -167,7 +169,7 @@ public function getTable($name = 'Cronjob', $prefix = 'Table', $options = array( * @throws Exception * @since __DEPLOY_VERSION__ */ - protected function loadFormData(): object + protected function loadFormData() { /* * Check session for previously entered form data @@ -187,6 +189,9 @@ protected function loadFormData(): object $data = $this->getItem(); // TODO : Do we need any _priming_ on the $data here? + $time = explode(':', $data->get('execution_interval')); + $data->set('interval-hours', $time[0]); + $data->set('interval-minutes', $time[1]); } // ? What would this do here? Is it needed or (just) good practice? @@ -228,12 +233,23 @@ public function save($data): bool */ $field = null; + // ? : Is this the right way? 'id' == 0 with $data for a New item so this wouldn't work. if (isset($data['id'])) { + // ? : Why aren't we doing anything with the field? $field = $this->getItem($data['id']); } - // TODO : Unset fields based on type an trigger selected + /* + * ! : Due change + * TODO : Change execution interval in DB to TIME, change handling below + * TODO : Custom fields and we might not need this ugly handling + */ + $intervalHours = str_pad($data['interval-hours'] ?? '0', 2); + $intervalMinutes = str_pad($data['interval-minutes'] ?? '0', 2); + $data['execution_interval'] = "$intervalHours:$intervalMinutes:00"; + + // TODO : Unset fields based on type and trigger selected /* * The parent save() takes care of saving to the main From fca757a170f90da25c37455ce2944ce15305e5de Mon Sep 17 00:00:00 2001 From: Harald Leithner Date: Mon, 19 Jul 2021 13:53:15 +0200 Subject: [PATCH 047/615] Update drone --- .drone.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.drone.yml b/.drone.yml index bf2cacaf38389..03543638d6790 100644 --- a/.drone.yml +++ b/.drone.yml @@ -247,12 +247,12 @@ steps: from_secret: ftpusername FTP_PASSWORD: from_secret: ftppassword - FTP_HOSTNAME: ci.joomla.org + FTP_HOSTNAME: ftp.artifacts.joomla.org FTP_PORT: "21" - FTP_DEST_DIR: /artifacts + FTP_DEST_DIR: / FTP_VERIFY: "false" FTP_SECURE: "true" - HTTP_ROOT: "https://ci.joomla.org/artifacts" + HTTP_ROOT: "https://artifacts.joomla.org/drone" DRONE_PULL_REQUEST: DRONE_PULL_REQUEST DRONE_COMMIT: DRONE_COMMIT GITHUB_TOKEN: From 5ca28549b61c7528827e92c4e982102da8521dbd Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Tue, 13 Jul 2021 19:48:00 +0530 Subject: [PATCH 048/615] Fix CronjobView form handling Fixes the time interval handling and the 'note' field in the XML --- .../components/com_cronjobs/forms/cronjob.xml | 2 +- .../com_cronjobs/src/Model/CronjobModel.php | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/administrator/components/com_cronjobs/forms/cronjob.xml b/administrator/components/com_cronjobs/forms/cronjob.xml index f4551e20ee012..1dc5a5aa3a5e1 100644 --- a/administrator/components/com_cronjobs/forms/cronjob.xml +++ b/administrator/components/com_cronjobs/forms/cronjob.xml @@ -53,7 +53,7 @@ -
diff --git a/administrator/components/com_cronjobs/src/Model/CronjobModel.php b/administrator/components/com_cronjobs/src/Model/CronjobModel.php index bb898df4e0de6..2a005db7805b2 100644 --- a/administrator/components/com_cronjobs/src/Model/CronjobModel.php +++ b/administrator/components/com_cronjobs/src/Model/CronjobModel.php @@ -190,8 +190,8 @@ protected function loadFormData() // TODO : Do we need any _priming_ on the $data here? $time = explode(':', $data->get('execution_interval')); - $data->set('interval-hours', $time[0]); - $data->set('interval-minutes', $time[1]); + $data->set('interval-hours', $time[0] ?? 0); + $data->set('interval-minutes', $time[1] ?? 0); } // ? What would this do here? Is it needed or (just) good practice? @@ -229,7 +229,7 @@ public function getItem($pk = null) public function save($data): bool { /** - * @var object $field Holds the record we're saving $data to + * @var object $field Holds the record we're saving $data to */ $field = null; @@ -245,8 +245,8 @@ public function save($data): bool * TODO : Change execution interval in DB to TIME, change handling below * TODO : Custom fields and we might not need this ugly handling */ - $intervalHours = str_pad($data['interval-hours'] ?? '0', 2); - $intervalMinutes = str_pad($data['interval-minutes'] ?? '0', 2); + $intervalHours = str_pad($data['interval-hours'] ?? '0', 2, '0', STR_PAD_LEFT); + $intervalMinutes = str_pad($data['interval-minutes'] ?? '0', 2, '0', STR_PAD_LEFT); $data['execution_interval'] = "$intervalHours:$intervalMinutes:00"; // TODO : Unset fields based on type and trigger selected @@ -255,7 +255,7 @@ public function save($data): bool * The parent save() takes care of saving to the main * `#__cronjobs` table */ - if (! parent::save($data)) + if (!parent::save($data)) { return false; } From 4ce27ea54c160e79eb6b73481bf1a3aac317c6d9 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Wed, 14 Jul 2021 17:30:26 +0530 Subject: [PATCH 049/615] Update en-GB language files A bit cluttered, but covers nearly all language constants including some which are not in use. Can use a cleanup later. --- .../language/en-GB/com_cronjobs.ini | 34 ++++++++++++++++++- .../language/en-GB/com_cronjobs.sys.ini | 34 ++++++++++++++++++- 2 files changed, 66 insertions(+), 2 deletions(-) diff --git a/administrator/components/com_cronjobs/language/en-GB/com_cronjobs.ini b/administrator/components/com_cronjobs/language/en-GB/com_cronjobs.ini index ffa9fe2b92998..27b9cfca5e07b 100644 --- a/administrator/components/com_cronjobs/language/en-GB/com_cronjobs.ini +++ b/administrator/components/com_cronjobs/language/en-GB/com_cronjobs.ini @@ -1,6 +1,38 @@ ; Joomla! Project ; (C) 2021 Open Source Matters, Inc. ; GPL v3 - COM_CRONJOBS="Cronjobs" COM_CRONJOBS_XML_DESCRIPTION="Component for managing pseudo-cronjobs and cronjobs (if server supports)" +COM_CRONJOBS_TABLE_CAPTION="Cronjobs List" +COM_CRONJOBS_HEADING_JOB_TYPE="Job Type" +COM_CRONJOBS_SELECT_TYPE="Cronjob Type" +COM_CRONJOBS_TYPE_SCRIPT="CLI Script" +COM_CRONJOBS_TYPE_PLG="Plugin" +COM_CRONJOBS_SELECT_TRIGGER="Trigger" +COM_CRONJOBS_EMPTYSTATE_CONTENT="No entries!" +COM_CRONJOBS_EMPTYSTATE_BUTTON_ADD="Add a Cronjob!" +COM_CRONJOBS_FIELD_CREATED_BY_LABEL="Created By" +COM_CRONJOBS_FIELD_CREATED_LABEL="Created" +COM_CRONJOBS_TRIGGER_PSEUDOCRON="Pseudocron" +COM_CRONJOBS_TRIGGER_CRON="Cron" +COM_CRONJOBS_TRIGGER_XVISITS="X-Visits" +COM_CRONJOBS_MANAGER_CRONJOBS="Cronjobs Manager" +COM_CRONJOBS_MANAGER_CRONJOB="Cronjob Manager" +COM_CRONJOBS_MANAGER_CRONJOB_EDIT="Edit Cronjob" +COM_CRONJOBS_NEW_CRONJOB="New Cronjob" +COM_CRONJOBS_EDIT_CRONJOB="Edit Cronjob" +COM_CRONJOBS_FIELDSET_RULES="Rules" +COM_CRONJOBS_FIELDSET_EXEC_HIST="Execution History" +COM_CRONJOBS_FIELDSET_DETAILS="Details" +COM_CRONJOBS_FIELDSET_CRON_OPTIONS="Cron Options" +COM_CRONJOBS_FIELDSET_BASIC="Basic Fields" +COM_CRONJOBS_LABEL_HOURS="Hours" +COM_CRONJOBS_LABEL_MINUTES="Minutes" +COM_CRONJOBS_LABEL_EXIT_CODE="Last Exit Code" +COM_CRONJOBS_LABEL_LAST_EXEC="Last Executed" +COM_CRONJOBS_LABEL_NEXT_EXEC="Next Execution" +COM_CRONJOBS_LABEL_TIMES_EXEC="Times Executed" +COM_CRONJOBS_LABEL_TIMES_FAIL="Times Failed" +COM_CRONJOBS_LABEL_NOTES="Notes" +COM_CRONJOBS_FORM_TITLE_NEW="New Cronjob" +COM_CRONJOBS_FORM_TITLE_EDIT="Edit Cronjob" diff --git a/administrator/components/com_cronjobs/language/en-GB/com_cronjobs.sys.ini b/administrator/components/com_cronjobs/language/en-GB/com_cronjobs.sys.ini index ffa9fe2b92998..27b9cfca5e07b 100644 --- a/administrator/components/com_cronjobs/language/en-GB/com_cronjobs.sys.ini +++ b/administrator/components/com_cronjobs/language/en-GB/com_cronjobs.sys.ini @@ -1,6 +1,38 @@ ; Joomla! Project ; (C) 2021 Open Source Matters, Inc. ; GPL v3 - COM_CRONJOBS="Cronjobs" COM_CRONJOBS_XML_DESCRIPTION="Component for managing pseudo-cronjobs and cronjobs (if server supports)" +COM_CRONJOBS_TABLE_CAPTION="Cronjobs List" +COM_CRONJOBS_HEADING_JOB_TYPE="Job Type" +COM_CRONJOBS_SELECT_TYPE="Cronjob Type" +COM_CRONJOBS_TYPE_SCRIPT="CLI Script" +COM_CRONJOBS_TYPE_PLG="Plugin" +COM_CRONJOBS_SELECT_TRIGGER="Trigger" +COM_CRONJOBS_EMPTYSTATE_CONTENT="No entries!" +COM_CRONJOBS_EMPTYSTATE_BUTTON_ADD="Add a Cronjob!" +COM_CRONJOBS_FIELD_CREATED_BY_LABEL="Created By" +COM_CRONJOBS_FIELD_CREATED_LABEL="Created" +COM_CRONJOBS_TRIGGER_PSEUDOCRON="Pseudocron" +COM_CRONJOBS_TRIGGER_CRON="Cron" +COM_CRONJOBS_TRIGGER_XVISITS="X-Visits" +COM_CRONJOBS_MANAGER_CRONJOBS="Cronjobs Manager" +COM_CRONJOBS_MANAGER_CRONJOB="Cronjob Manager" +COM_CRONJOBS_MANAGER_CRONJOB_EDIT="Edit Cronjob" +COM_CRONJOBS_NEW_CRONJOB="New Cronjob" +COM_CRONJOBS_EDIT_CRONJOB="Edit Cronjob" +COM_CRONJOBS_FIELDSET_RULES="Rules" +COM_CRONJOBS_FIELDSET_EXEC_HIST="Execution History" +COM_CRONJOBS_FIELDSET_DETAILS="Details" +COM_CRONJOBS_FIELDSET_CRON_OPTIONS="Cron Options" +COM_CRONJOBS_FIELDSET_BASIC="Basic Fields" +COM_CRONJOBS_LABEL_HOURS="Hours" +COM_CRONJOBS_LABEL_MINUTES="Minutes" +COM_CRONJOBS_LABEL_EXIT_CODE="Last Exit Code" +COM_CRONJOBS_LABEL_LAST_EXEC="Last Executed" +COM_CRONJOBS_LABEL_NEXT_EXEC="Next Execution" +COM_CRONJOBS_LABEL_TIMES_EXEC="Times Executed" +COM_CRONJOBS_LABEL_TIMES_FAIL="Times Failed" +COM_CRONJOBS_LABEL_NOTES="Notes" +COM_CRONJOBS_FORM_TITLE_NEW="New Cronjob" +COM_CRONJOBS_FORM_TITLE_EDIT="Edit Cronjob" From 577bf9dc6d562ab933605b675507d2ef30b799aa Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Wed, 14 Jul 2021 17:38:54 +0530 Subject: [PATCH 050/615] Remove SelectTypeView --- .../src/View/SelectType/HtmlView.php | 67 ------------------- 1 file changed, 67 deletions(-) delete mode 100644 administrator/components/com_cronjobs/src/View/SelectType/HtmlView.php diff --git a/administrator/components/com_cronjobs/src/View/SelectType/HtmlView.php b/administrator/components/com_cronjobs/src/View/SelectType/HtmlView.php deleted file mode 100644 index 888102810449d..0000000000000 --- a/administrator/components/com_cronjobs/src/View/SelectType/HtmlView.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @license GPL v3 - */ - -namespace Joomla\Component\Cronjobs\Administrator\View\SelectType; - -// Restrict direct access -\defined('_JEXEC_') or die; - -use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView; - -/** - * The MVC View SelectType - * Should let the user choose between adding a Script or a Plugin 'Cronjob' - * - * @package Joomla.Administrator - * @subpackage com_cronjobs - * - * @since __DEPLOY_VERSION__ - */ -class HtmlView extends BaseHtmlView -{ - /** - * The Form object - * - * @var \JForm - * @since __DEPLOY__VERSION__ - */ - protected $form; - - /** - * The active item - * - * @var object - * @since __DEPLOY__VERSION__ - */ - protected $item; - - /** - * The model state - * - * @var \JObject - * @since __DEPLOY__VERSION__ - */ - protected $state; - - - /** - * @param string $tpl The name of the template file to parse; automatically searches through the template paths. - * - * @return void - * - * @since __DEPLOY_VERSION__ - */ - public function display($tpl = null) : void - { - // ! TODO - } - -} From ea93353d5801b7b24101f1326be996f46d5289f2 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Wed, 14 Jul 2021 17:47:24 +0530 Subject: [PATCH 051/615] Rename SelectPluginView to SelectView --- .../com_cronjobs/src/View/{SelectPlugin => Select}/HtmlView.php | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename administrator/components/com_cronjobs/src/View/{SelectPlugin => Select}/HtmlView.php (100%) diff --git a/administrator/components/com_cronjobs/src/View/SelectPlugin/HtmlView.php b/administrator/components/com_cronjobs/src/View/Select/HtmlView.php similarity index 100% rename from administrator/components/com_cronjobs/src/View/SelectPlugin/HtmlView.php rename to administrator/components/com_cronjobs/src/View/Select/HtmlView.php From c16789a7d01444b6d69fcb4ded8533c0ab16a0eb Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Wed, 14 Jul 2021 18:12:50 +0530 Subject: [PATCH 052/615] Add base MVC Model for SelectView Also makes minor changes in SelectView to complete the class refactor. --- .../com_cronjobs/src/Model/SelectModel.php | 26 +++++++++++++++++++ .../com_cronjobs/src/View/Select/HtmlView.php | 6 ++--- 2 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 administrator/components/com_cronjobs/src/Model/SelectModel.php diff --git a/administrator/components/com_cronjobs/src/Model/SelectModel.php b/administrator/components/com_cronjobs/src/Model/SelectModel.php new file mode 100644 index 0000000000000..634d18f187ae3 --- /dev/null +++ b/administrator/components/com_cronjobs/src/Model/SelectModel.php @@ -0,0 +1,26 @@ + + * @license GPL v3 + */ + +namespace Joomla\Component\Cronjobs\Administrator\Model; + +// Restrict direct access +\defined('_JEXEC') or die; + +use Joomla\CMS\MVC\Model\ListModel; + +/** + * MVC Model for SelectView + * + * @since __DEPLOY_VERSION__ + */ +class SelectModel extends ListModel +{ +} diff --git a/administrator/components/com_cronjobs/src/View/Select/HtmlView.php b/administrator/components/com_cronjobs/src/View/Select/HtmlView.php index f0e6b41491844..cfec5d7cec565 100644 --- a/administrator/components/com_cronjobs/src/View/Select/HtmlView.php +++ b/administrator/components/com_cronjobs/src/View/Select/HtmlView.php @@ -9,7 +9,7 @@ * @license GPL v3 */ -namespace Joomla\Component\Cronjobs\Administrator\View\SelectPlugin; +namespace Joomla\Component\Cronjobs\Administrator\View\Select; // Restrict direct access \defined('_JEXEC') or die; @@ -17,8 +17,8 @@ use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView; /** - * The MVC View SelectPlugin - * Should let the user choose a plugin from installed Cronjob supporting ones + * The MVC View Select + * Should let the user choose from a list of plugin defined Jobs or a CLI job. * * @package Joomla.Administrator * @subpackage com_cronjobs From 7d32fd751fa18a19b79a9c3850bca58fcedbde6f Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Thu, 15 Jul 2021 13:51:51 +0530 Subject: [PATCH 053/615] Implement SelectModel Implements in particular the getItems() method. Due significant changes in the plugin API particularly the $items object (currently array) used as the `onCronOptionsList` Event's 'subject' argument. --- .../com_cronjobs/src/Model/SelectModel.php | 50 ++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/administrator/components/com_cronjobs/src/Model/SelectModel.php b/administrator/components/com_cronjobs/src/Model/SelectModel.php index 634d18f187ae3..ac6fafd996ddb 100644 --- a/administrator/components/com_cronjobs/src/Model/SelectModel.php +++ b/administrator/components/com_cronjobs/src/Model/SelectModel.php @@ -12,9 +12,15 @@ namespace Joomla\Component\Cronjobs\Administrator\Model; // Restrict direct access -\defined('_JEXEC') or die; +defined('_JEXEC') or die; +use Exception; +use Joomla\CMS\Application\CMSApplication; +use Joomla\CMS\Event\AbstractEvent; +use Joomla\CMS\Factory; use Joomla\CMS\MVC\Model\ListModel; +use Joomla\CMS\Plugin\PluginHelper; +use function defined; /** * MVC Model for SelectView @@ -23,4 +29,46 @@ */ class SelectModel extends ListModel { + /** + * @var CMSApplication + * @since __DEPLOY_VERSION__ + */ + protected $app; + + + /** + * SelectModel constructor. + * + * @throws Exception + * @since __DEPLOY_VERSION__ + */ + public function __construct() + { + $this->app = Factory::getApplication(); + parent::__construct(); + } + + /** + * + * @return array An array of items + * + * @since __DEPLOY_VERSION__ + */ + public function getItems(): array + { + // TODO : Implement an object for $items + $items = []; + PluginHelper::importPlugin('job'); + $this->app->getDispatcher()->dispatch('onCronOptionsList', + AbstractEvent::create( + 'onCronOptionsList', + [ + 'eventClass' => 'Joomla\Component\Cronjobs\Administrator\Model\SelectModel', + 'subject' => &$items + ] + ) + ); + + return $items; + } } From 9cba9ad68148e8dded216302bb012ede3895fef3 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Thu, 15 Jul 2021 15:14:57 +0530 Subject: [PATCH 054/615] Implement SelectView Remains untested until the SelectView template is implemented. --- .../com_cronjobs/src/View/Select/HtmlView.php | 102 ++++++++++++++---- 1 file changed, 83 insertions(+), 19 deletions(-) diff --git a/administrator/components/com_cronjobs/src/View/Select/HtmlView.php b/administrator/components/com_cronjobs/src/View/Select/HtmlView.php index cfec5d7cec565..2f7e52d911723 100644 --- a/administrator/components/com_cronjobs/src/View/Select/HtmlView.php +++ b/administrator/components/com_cronjobs/src/View/Select/HtmlView.php @@ -2,11 +2,11 @@ /** * Declares the MVC View for SelectPluginModel. * - * @package Joomla.Administrator - * @subpackage com_cronjobs + * @package Joomla.Administrator + * @subpackage com_cronjobs * * @copyright (C) 2021 Open Source Matters, Inc. - * @license GPL v3 + * @license GPL v3 */ namespace Joomla\Component\Cronjobs\Administrator\View\Select; @@ -14,54 +14,118 @@ // Restrict direct access \defined('_JEXEC') or die; +use Joomla\CMS\Language\Text; +use Joomla\CMS\Layout\FileLayout; +use Joomla\CMS\MVC\View\GenericDataException; use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView; +use Joomla\CMS\Toolbar\Toolbar; +use Joomla\CMS\Toolbar\ToolbarHelper; /** * The MVC View Select * Should let the user choose from a list of plugin defined Jobs or a CLI job. + * ! : Untested * * @package Joomla.Administrator * @subpackage com_cronjobs * - * @since __DEPLOY_VERSION__ + * @since __DEPLOY_VERSION__ */ class HtmlView extends BaseHtmlView { /** - * The Form object + * The model state * - * @var \JForm - * @since __DEPLOY__VERSION__ + * @var \JObject + * @since __DEPLOY_VERSION__ */ - protected $form; + protected $state; /** - * The active item + * An array of items [TODO: Implement a 'Job' object or similar] * - * @var object - * @since __DEPLOY__VERSION__ + * @var array + * @since __DEPLOY_VERSION__ */ - protected $item; + protected $items; /** - * The model state + * Will be used for the "CLI" / "Script" type job * - * @var \JObject - * @since __DEPLOY__VERSION__ + * @var object + * @since version */ - protected $state; + protected $specialItem; + + /** + * A suffix for links for modal use [?] + * + * @var string + * @since __DEPLOY_VERSION__ + */ + protected $modalLink; /** - * @param string $tpl The name of the template file to parse; automatically searches through the template paths. + * @param string $tpl The name of the template file to parse; automatically searches through the template paths. * * @return void * + * @throws \Exception * @since __DEPLOY_VERSION__ */ - public function display($tpl = null) : void + public function display($tpl = null): void { - // ! TODO + // ! Untested + + $this->state = $this->get('State'); + $this->items = $this->get('Items'); + $this->modalLink = ''; + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new GenericDataException(implode("\n", $errors), 500); + } + + $this->addToolbar(); + parent::display($tpl); } + /** + * Add the page title and toolbar. + * ! : Untested + * + * @return void + * + * @since __DEPLOY_VERSION + */ + protected function addToolbar() + { + $state = $this->get('State'); + $clientId = (int) $state->get('client_id', 0); + + /* + * Add page title + * TODO: 'cronjobs' icon + */ + ToolbarHelper::title(Text::_('COM_CRONJOBS_MANAGER_CRONJOBS'), 'tags'); + + + /* + * Get the toolbar object instance + * TODO : Replace usage with ToolbarFactoryInterface + */ + $bar = Toolbar::getInstance('toolbar'); + + // Instantiate a new FileLayout instance and render the layout + $layout = new FileLayout('toolbar.cancelselect'); + + /* + * ? : What is this doing? + * ! : appendButton seems to want a ToolbarButton object, but we're passing a string? + * TODO : Button object? + */ + $bar->appendButton('Custom', $layout->render(array('client_id' => $clientId)), 'new'); + } } From 33134f2bf6f75722f291dcceda3ab6de5a1359c1 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Fri, 16 Jul 2021 12:29:36 +0530 Subject: [PATCH 055/615] Add JS for SelectView search, update manifest Updates the manifest with the specs of the new media/ folder. Adds JS for SelectView plugin job search, adapted from com_modules SelectView search JS. --- .../components/com_cronjobs/cronjobs.xml | 4 +- media/com_cronjobs/joomla.asset.json | 32 ++++++ .../js/admin-plg-job-search-es5.js | 106 ++++++++++++++++++ media/com_cronjobs/js/admin-plg-job-search.js | 100 +++++++++++++++++ 4 files changed, 241 insertions(+), 1 deletion(-) create mode 100644 media/com_cronjobs/joomla.asset.json create mode 100644 media/com_cronjobs/js/admin-plg-job-search-es5.js create mode 100644 media/com_cronjobs/js/admin-plg-job-search.js diff --git a/administrator/components/com_cronjobs/cronjobs.xml b/administrator/components/com_cronjobs/cronjobs.xml index a081b1f24c07f..5c5313b0cbc94 100644 --- a/administrator/components/com_cronjobs/cronjobs.xml +++ b/administrator/components/com_cronjobs/cronjobs.xml @@ -28,7 +28,9 @@ sql/updates/postgresql - + + js + Cronjobs diff --git a/media/com_cronjobs/joomla.asset.json b/media/com_cronjobs/joomla.asset.json new file mode 100644 index 0000000000000..a41f4d3dd9818 --- /dev/null +++ b/media/com_cronjobs/joomla.asset.json @@ -0,0 +1,32 @@ +{ + "$schema": "https://developer.joomla.org/schemas/json-schema/web_assets.json", + "name": "com_cronjobs", + "version": "4.0.0", + "description": "Joomla CMS", + "license": "GPL v3", + "assets": [ + { + "name": "com_cronjobs.admin-plg-job-search.es5", + "type": "script", + "uri": "com_cronjobs/admin-plg-job-search-es5.js", + "dependencies": [ + "core" + ], + "attributes": { + "nomodule": true, + "defer": true + } + }, + { + "name": "com_cronjobs.admin-plg-job-search", + "type": "script", + "uri": "com_cronjobs/admin-plg-job-search.js", + "dependencies": [ + "com_cronjobs.admin-plg-job-search.es5" + ], + "attributes": { + "type" : "module" + } + } + ] +} diff --git a/media/com_cronjobs/js/admin-plg-job-search-es5.js b/media/com_cronjobs/js/admin-plg-job-search-es5.js new file mode 100644 index 0000000000000..96ec218e1bdeb --- /dev/null +++ b/media/com_cronjobs/js/admin-plg-job-search-es5.js @@ -0,0 +1,106 @@ +(function () { + 'use strict'; + + /** + * @copyright (C) 2021 Open Source Matters, Inc. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + + /** + * Add a keyboard event listener to the Select a Module Type search element. + * + * IMPORTANT! This script is meant to be loaded deferred. This means that a. it's non-blocking + * (the browser can load it whenever) and b. it doesn't need an on DOMContentLoaded event handler + * because the browser is guaranteed to execute it only after the DOM content has loaded, the + * whole point of it being deferred. + * + * The search box has a keyboard handler that fires every time you press a keyboard button or send + * a keypress with a touch / virtual keyboard. We then iterate all module type cards and check if + * the plain text (HTML stripped out) representation of the module title or description partially + * matches the text you entered in the search box. If it doesn't we add a Bootstrap class to hide + * the module. + * + * This way we limit the displayed modules only to those searched. + * + * This feature follows progressive enhancement. The search box is hidden by default and only + * displayed when this JavaScript here executes. Furthermore, session storage is only used if it + * is available in the browser. That's a bit of a pain but makes sure things won't break in older + * browsers. + * + * Furthermore and to facilitate the user experience we auto-focus the search element which has a + * suitable title so that non-sighted users are not startled. This way we address both UX concerns + * and accessibility. + * + * Finally, the search string is saved into session storage on the assumption that the user is + * probably going to be creating multiple instances of the same module, one after another, as is + * typical when building a new Joomla! site. + * @codingStandardsIgnoreStart + */ + // Make sure the element exists i.e. a template override has not removed it. + var elSearch = document.getElementById('comCronjobsSelectSearch'); + var elSearchContainer = document.getElementById('comCronjobsSelectSearchContainer'); + var elSearchHeader = document.getElementById('comCronjobsSelectTypeHeader'); + var elSearchResults = document.getElementById('comCronjobsSelectResultsContainer'); + var alertElement = document.querySelector('.jobs-alert'); + var elCards = [].slice.call(document.querySelectorAll('.comCronjobsSelectCard')); + + if (elSearch && elSearchContainer) { + // Add the keyboard event listener which performs the live search in the cards + elSearch.addEventListener('keyup', function (event) { + /** @type {KeyboardEvent} event */ + var partialSearch = event.target.value; + var hasSearchResults = false; // Save the search string into session storage + + if (typeof sessionStorage !== 'undefined') { + sessionStorage.setItem('Joomla.com_cronjobs.new.search', partialSearch); + } // Iterate all the module cards + + + elCards.forEach(function (card) { + // First remove the class which hides the job cards + card.classList.remove('d-none'); // An empty search string means that we should show everything + + if (!partialSearch) { + return; + } + + var cardHeader = card.querySelector('.new-job-title'); + var cardBody = card.querySelector('.card-body'); + var title = cardHeader ? cardHeader.textContent : ''; + var description = cardBody ? cardBody.textContent : ''; // If the job title and description don’t match add a class to hide it. + + if (title && !title.toLowerCase().includes(partialSearch.toLowerCase()) && description && !description.toLowerCase().includes(partialSearch.toLowerCase())) { + card.classList.add('d-none'); + } else { + hasSearchResults = true; + } + } + ); + + if (hasSearchResults || !partialSearch) { + alertElement.classList.add('d-none'); + elSearchHeader.classList.remove('d-none'); + elSearchResults.classList.remove('d-none'); + } else { + alertElement.classList.remove('d-none'); + elSearchHeader.classList.add('d-none'); + elSearchResults.classList.add('d-none'); + } + }); // For reasons of progressive enhancement the search box is hidden by default. + + elSearchContainer.classList.remove('d-none'); // Focus the just show element + + elSearch.focus(); + + try { + if (typeof sessionStorage !== 'undefined') { + // Load the search string from session storage + elSearch.value = sessionStorage.getItem('Joomla.com_cronjobs.new.search') || ''; // Trigger the keyboard handler event manually to initiate the search + + elSearch.dispatchEvent(new KeyboardEvent('keyup')); + } + } catch (e) {// This is probably Internet Explorer which doesn't support the KeyboardEvent constructor :( + } + } + +}()); diff --git a/media/com_cronjobs/js/admin-plg-job-search.js b/media/com_cronjobs/js/admin-plg-job-search.js new file mode 100644 index 0000000000000..f90c3962a394d --- /dev/null +++ b/media/com_cronjobs/js/admin-plg-job-search.js @@ -0,0 +1,100 @@ +/** + * @copyright (C) 2021 Open Source Matters, Inc. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +/** + * Add a keyboard event listener to the Select a Module Type search element. + * + * IMPORTANT! This script is meant to be loaded deferred. This means that a. it's non-blocking + * (the browser can load it whenever) and b. it doesn't need an on DOMContentLoaded event handler + * because the browser is guaranteed to execute it only after the DOM content has loaded, the + * whole point of it being deferred. + * + * The search box has a keyboard handler that fires every time you press a keyboard button or send + * a keypress with a touch / virtual keyboard. We then iterate all module type cards and check if + * the plain text (HTML stripped out) representation of the module title or description partially + * matches the text you entered in the search box. If it doesn't we add a Bootstrap class to hide + * the module. + * + * This way we limit the displayed modules only to those searched. + * + * This feature follows progressive enhancement. The search box is hidden by default and only + * displayed when this JavaScript here executes. Furthermore, session storage is only used if it + * is available in the browser. That's a bit of a pain but makes sure things won't break in older + * browsers. + * + * Furthermore and to facilitate the user experience we auto-focus the search element which has a + * suitable title so that non-sighted users are not startled. This way we address both UX concerns + * and accessibility. + * + * Finally, the search string is saved into session storage on the assumption that the user is + * probably going to be creating multiple instances of the same module, one after another, as is + * typical when building a new Joomla! site. + * @codingStandardsIgnoreStart + */ +// Make sure the element exists i.e. a template override has not removed it. +const elSearch = document.getElementById('comCronjobsSelectSearch'); +const elSearchContainer = document.getElementById('comCronjobsSelectSearchContainer'); +const elSearchHeader = document.getElementById('comCronjobsSelectTypeHeader'); +const elSearchResults = document.getElementById('comCronjobsSelectResultsContainer'); +const alertElement = document.querySelector('.jobs-alert'); +const elCards = [].slice.call(document.querySelectorAll('.comCronjobsSelectCard')); + +if (elSearch && elSearchContainer) { + // Add the keyboard event listener which performs the live search in the cards + elSearch.addEventListener('keyup', event => { + /** @type {KeyboardEvent} event */ + const partialSearch = event.target.value; + let hasSearchResults = false; // Save the search string into session storage + + if (typeof sessionStorage !== 'undefined') { + sessionStorage.setItem('Joomla.com_cronjobs.new.search', partialSearch); + } // Iterate all the job cards + + + elCards.forEach(card => { + // First remove the class which hide the job cards + card.classList.remove('d-none'); // An empty search string means that we should show everything + + if (!partialSearch) { + return; + } + + const cardHeader = card.querySelector('.new-job-title'); + const cardBody = card.querySelector('.card-body'); + const title = cardHeader ? cardHeader.textContent : ''; + const description = cardBody ? cardBody.textContent : ''; // If the module title and description don’t match add a class to hide it. + + if (title && !title.toLowerCase().includes(partialSearch.toLowerCase()) && description && !description.toLowerCase().includes(partialSearch.toLowerCase())) { + card.classList.add('d-none'); + } else { + hasSearchResults = true; + } + }); + + if (hasSearchResults || !partialSearch) { + alertElement.classList.add('d-none'); + elSearchHeader.classList.remove('d-none'); + elSearchResults.classList.remove('d-none'); + } else { + alertElement.classList.remove('d-none'); + elSearchHeader.classList.add('d-none'); + elSearchResults.classList.add('d-none'); + } + }); // For reasons of progressive enhancement the search box is hidden by default. + + elSearchContainer.classList.remove('d-none'); // Focus the just show element + + elSearch.focus(); + + try { + if (typeof sessionStorage !== 'undefined') { + // Load the search string from session storage + elSearch.value = sessionStorage.getItem('Joomla.com_cronjobs.new.search') || ''; // Trigger the keyboard handler event manually to initiate the search + + elSearch.dispatchEvent(new KeyboardEvent('keyup')); + } + } catch (e) {// This is probably Internet Explorer which doesn't support the KeyboardEvent constructor :( + } +} From 48d0a85e31911130e338de63a6573844b90a871f Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Fri, 16 Jul 2021 15:24:52 +0530 Subject: [PATCH 056/615] Update SelectView Adds the application object as a property and some other minor changes. Also sneaks in a phpdocs param comment for the HtmlView constructor fixing the codesniffer error. --- .../com_cronjobs/src/View/Select/HtmlView.php | 36 +++++++++++++++++-- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/administrator/components/com_cronjobs/src/View/Select/HtmlView.php b/administrator/components/com_cronjobs/src/View/Select/HtmlView.php index 2f7e52d911723..60db3f64b70dd 100644 --- a/administrator/components/com_cronjobs/src/View/Select/HtmlView.php +++ b/administrator/components/com_cronjobs/src/View/Select/HtmlView.php @@ -14,6 +14,9 @@ // Restrict direct access \defined('_JEXEC') or die; +use Exception; +use Joomla\CMS\Application\CMSApplication; +use Joomla\CMS\Factory; use Joomla\CMS\Language\Text; use Joomla\CMS\Layout\FileLayout; use Joomla\CMS\MVC\View\GenericDataException; @@ -33,6 +36,12 @@ */ class HtmlView extends BaseHtmlView { + /** + * @var CMSApplication + * @since __DEPLOY_VERSION__ + */ + protected $app; + /** * The model state * @@ -51,6 +60,7 @@ class HtmlView extends BaseHtmlView /** * Will be used for the "CLI" / "Script" type job + * ! : Not in use yet * * @var object * @since version @@ -66,12 +76,33 @@ class HtmlView extends BaseHtmlView protected $modalLink; + /** + * HtmlView constructor. + * + * @param array $config A named configuration array for object construction. + * name: the name (optional) of the view (defaults to the view class name suffix). + * charset: the character set to use for display + * escape: the name (optional) of the function to use for escaping strings + * base_path: the parent path (optional) of the views directory (defaults to the component folder) + * template_plath: the path (optional) of the layout directory (defaults to base_path + /views/ + view name + * helper_path: the path (optional) of the helper files (defaults to base_path + /helpers/) + * layout: the layout (optional) to use to display the view + * + * @throws Exception + * @since __DEPLOY_VERSION__ + */ + public function __construct($config = array()) + { + $this->app = Factory::getApplication(); + parent::__construct($config); + } + /** * @param string $tpl The name of the template file to parse; automatically searches through the template paths. * * @return void * - * @throws \Exception + * @throws Exception * @since __DEPLOY_VERSION__ */ public function display($tpl = null): void @@ -111,12 +142,11 @@ protected function addToolbar() */ ToolbarHelper::title(Text::_('COM_CRONJOBS_MANAGER_CRONJOBS'), 'tags'); - /* * Get the toolbar object instance * TODO : Replace usage with ToolbarFactoryInterface */ - $bar = Toolbar::getInstance('toolbar'); + $bar = Toolbar::getInstance(); // Instantiate a new FileLayout instance and render the layout $layout = new FileLayout('toolbar.cancelselect'); From d7c6f26d09d7a1abf3ab580fd7331b22210771b0 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Fri, 16 Jul 2021 15:49:13 +0530 Subject: [PATCH 057/615] Add classes to support the Plugin API Adds the CronOption and CronOptions classes. An instance of the CronOptions class is (currently) passed as the `subject` arg for the `onCronOptionsList` event. The plugin subscriber is supposed to use the addOptions method of CronOptions to pass supported jobs. The changes in the SelectModel and a test plugin implementation follow this commit. --- .../com_cronjobs/src/Cronjobs/CronOption.php | 61 +++++++++++++++++++ .../com_cronjobs/src/Cronjobs/CronOptions.php | 56 +++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 administrator/components/com_cronjobs/src/Cronjobs/CronOption.php create mode 100644 administrator/components/com_cronjobs/src/Cronjobs/CronOptions.php diff --git a/administrator/components/com_cronjobs/src/Cronjobs/CronOption.php b/administrator/components/com_cronjobs/src/Cronjobs/CronOption.php new file mode 100644 index 0000000000000..3dc4e430920a0 --- /dev/null +++ b/administrator/components/com_cronjobs/src/Cronjobs/CronOption.php @@ -0,0 +1,61 @@ + + * @license GPL v3 + * + * @TODO : Review! Is it too convoluted? Plugins could perhaps call the CronOption constructor themselves. Or a change of + * documentation might suffice. + */ + +namespace Joomla\Component\Cronjobs\Administrator\Cronjobs; + +use Joomla\CMS\Language\Text; + +/** + * The CronOption class. + * Each plugin supporting jobs calls the CronOptions addOptions() method with an array of CronOption constructor argument pairs as argument. + * Internally, the CronOption object generates the job title and description from the language constant prefix. + * + * @since __DEPLOY_VERSION__ + */ +class CronOption +{ + /** + * Job title + * @var string + * @since __DEPLOY_VERSION__ + */ + public $title; + + /** + * @var string + * @since __DEPLOY_VERSION__ + */ + public $desc; + + /** + * @var string + * @since __DEPLOY_VERSION__ + */ + public $id; + + /** + * CronOption constructor. + * + * @param string $id A unique string for the job routine used internally by the job plugin. + * @param string $langConstPrefix The Language constant prefix $p. Expects $p . _TITLE and $p . _DESC to exist. + * + * @since __DEPLOY_VERSION__ + */ + public function __construct(string $id, string $langConstPrefix) + { + $this->id = $id; + $this->title = Text::_("${langConstPrefix}_TITLE"); + $this->desc = Text::_("${langConstPrefix}_DESC"); + } +} diff --git a/administrator/components/com_cronjobs/src/Cronjobs/CronOptions.php b/administrator/components/com_cronjobs/src/Cronjobs/CronOptions.php new file mode 100644 index 0000000000000..de4937cde6674 --- /dev/null +++ b/administrator/components/com_cronjobs/src/Cronjobs/CronOptions.php @@ -0,0 +1,56 @@ + + * @license GPL v3 + * + */ + +namespace Joomla\Component\Cronjobs\Administrator\Cronjobs; + +// Restrict direct access +defined('_JEXEC') or die; + +use function defined; + +/** + * The CronOptions class. + * Used as the subject argument for the `OnCronOptionsList` event, plugins that support jobs must add them to the object + * through the addOptions() method. + * + * @since __DEPLOY_VERSION + */ +class CronOptions +{ + /** + * An array of CronOptions + * + * @var CronOption[] + * @since __DEPLOY_VERSION__ + */ + public $jobs = []; + + + /** + * A plugin can support several jobs + * This method is used by a plugin's OnCronOptionsList subscriber to advertise supported jobs. + * + * @param array $jobsArray An associative array of {@var CronOption} constructor argument pairs: + * [ 'jobId' => 'languageConstantPrefix', ... ] + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function addOptions(array $jobsArray): void + { + foreach ($jobsArray as $jobId => $langConstPrefix) + { + $this->jobs[] = new CronOption($jobId, $langConstPrefix); + } + } +} From a5eba0d6545a83e8777604a3ceda5744fb66c1f7 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Fri, 16 Jul 2021 16:39:38 +0530 Subject: [PATCH 058/615] Update SelectModel Switches to a CronOptions object as the 'subject' argument for the onCronOptionsList Event. Also fixes the parent constructor call along with some minor changes. --- .../com_cronjobs/src/Model/SelectModel.php | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Model/SelectModel.php b/administrator/components/com_cronjobs/src/Model/SelectModel.php index ac6fafd996ddb..38e2e785be506 100644 --- a/administrator/components/com_cronjobs/src/Model/SelectModel.php +++ b/administrator/components/com_cronjobs/src/Model/SelectModel.php @@ -18,8 +18,11 @@ use Joomla\CMS\Application\CMSApplication; use Joomla\CMS\Event\AbstractEvent; use Joomla\CMS\Factory; +use Joomla\CMS\MVC\Factory\MVCFactoryInterface; use Joomla\CMS\MVC\Model\ListModel; use Joomla\CMS\Plugin\PluginHelper; +use Joomla\Component\Cronjobs\Administrator\Cronjobs\CronOptions; +use Joomla\Component\Cronjobs\Administrator\Cronjobs\CronOption; use function defined; /** @@ -39,36 +42,38 @@ class SelectModel extends ListModel /** * SelectModel constructor. * + * @param array $config An array of configuration options (name, state, dbo, table_path, ignore_request). + * @param ?MVCFactoryInterface $factory The factory. + * * @throws Exception * @since __DEPLOY_VERSION__ */ - public function __construct() + public function __construct($config = array(), ?MVCFactoryInterface $factory = null) { $this->app = Factory::getApplication(); - parent::__construct(); + parent::__construct($config, $factory); } /** * - * @return array An array of items + * @return CronOption[] An array of CronOption objects * * @since __DEPLOY_VERSION__ */ public function getItems(): array { + $options = new CronOptions; + $event = AbstractEvent::create( + 'onCronOptionsList', + [ + 'subject' => $options + ] + ); + // TODO : Implement an object for $items - $items = []; PluginHelper::importPlugin('job'); - $this->app->getDispatcher()->dispatch('onCronOptionsList', - AbstractEvent::create( - 'onCronOptionsList', - [ - 'eventClass' => 'Joomla\Component\Cronjobs\Administrator\Model\SelectModel', - 'subject' => &$items - ] - ) - ); + $this->app->getDispatcher()->dispatch('onCronOptionsList', $event); - return $items; + return $options->jobs; } } From 105bd7477ac3ac0d3f622a2aaaa3d0dbbe6ef8cb Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Fri, 16 Jul 2021 16:56:46 +0530 Subject: [PATCH 059/615] Add dummy job plugin Adds a dummy test plugin that subscribes to both the onCronOptionsList and onCronRun events. Compatible with the new CronOptions subject argument for onCronOptionsList. --- plugins/system/testjob/testjob.php | 88 ++++++++++++++++++++++++++++++ plugins/system/testjob/testjob.xml | 12 ++++ 2 files changed, 100 insertions(+) create mode 100644 plugins/system/testjob/testjob.php create mode 100644 plugins/system/testjob/testjob.xml diff --git a/plugins/system/testjob/testjob.php b/plugins/system/testjob/testjob.php new file mode 100644 index 0000000000000..34687393ce42b --- /dev/null +++ b/plugins/system/testjob/testjob.php @@ -0,0 +1,88 @@ + + * @license GPL v3 + */ + +use Joomla\CMS\Plugin\CMSPlugin; +use Joomla\Event\SubscriberInterface; +use Joomla\Event\Event; +use Joomla\Component\Cronjobs\Administrator\Cronjobs\CronOption; + +/** + * The Testjobplug class + * + * @since __DEPLOY__ + */ +class PlgSystemTestjob extends CMSPlugin implements SubscriberInterface +{ + + /** + * Returns event subscriptions + * + * @return string[] + * + * @since __DEPLOY__ + */ + public static function getSubscribedEvents(): array + { + return [ + 'onCronOptionsList' => 'pluginCronOptions', + 'onCronRun' => 'cronSampleRoutine' + ]; + } + + /** + * Just returns a jobId => langConstPrefix mapped array (for now) + * + * @param Event $event onCronOptionsList Event + * + * @return string[] + * + * @since __DEPLOY_VERSION__ + */ + public function pluginCronOptions(Event $event): array + { + $jobsArray = [ + 'job1' => 'COM_TESTJOBPLG_JOB1', + 'job2' => 'COM_TESTJOBPLG_JOB2' + ]; + + $subject = $event['subject']; + + $subject->addOptions($jobsArray); + + return $jobsArray; + } + + /** + * @param Event $event onCronRun Event + * + * @return void + * + * @since __DEPLOY_VERSION + */ + public function cronSampleRoutine(Event $event): void + { + /** + * ! : com_cronjobs does not trigger anything as of yet. The operations below only exist as an example. + * ! : The $subject object has not been implemented, nor are the operations below its intended form. + */ + + $subject = $event['subject']; + $supportedJobs = [ + 'job1' => 'routine1', + 'job2' => 'routine2' + ]; + + if (\array_key_exists($subject->jobId, $supportedJobs)) + { + $subject->exec[] = ['plugin' => $this->_name, 'exit' => 0]; + } + } +} diff --git a/plugins/system/testjob/testjob.xml b/plugins/system/testjob/testjob.xml new file mode 100644 index 0000000000000..e488421d4364d --- /dev/null +++ b/plugins/system/testjob/testjob.xml @@ -0,0 +1,12 @@ + + + Test Job! + Joomla! Projects + July 2021 + GPL v3 + 4.1 + Test jobs for com_cronjobs + + testjob.php + + From 63fc068767659f5694b5f881e51c2c1ac299febb Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Fri, 16 Jul 2021 22:01:07 +0530 Subject: [PATCH 060/615] Add SelectView stylesheet Also adds the css folder to the manifest, updates the asset json and sneaks in minor changes into the JS files. --- .../components/com_cronjobs/cronjobs.xml | 1 + media/com_cronjobs/css/admin-plg-job.css | 54 +++++++++++++++++++ media/com_cronjobs/joomla.asset.json | 5 ++ .../js/admin-plg-job-search-es5.js | 14 ++--- media/com_cronjobs/js/admin-plg-job-search.js | 14 ++--- 5 files changed, 74 insertions(+), 14 deletions(-) create mode 100644 media/com_cronjobs/css/admin-plg-job.css diff --git a/administrator/components/com_cronjobs/cronjobs.xml b/administrator/components/com_cronjobs/cronjobs.xml index 5c5313b0cbc94..a42cd45f01579 100644 --- a/administrator/components/com_cronjobs/cronjobs.xml +++ b/administrator/components/com_cronjobs/cronjobs.xml @@ -30,6 +30,7 @@ js + css Cronjobs diff --git a/media/com_cronjobs/css/admin-plg-job.css b/media/com_cronjobs/css/admin-plg-job.css new file mode 100644 index 0000000000000..70545228b3ade --- /dev/null +++ b/media/com_cronjobs/css/admin-plg-job.css @@ -0,0 +1,54 @@ +.new-job { + display: flex; + overflow: hidden; + color: hsl(var(--hue),30%,40%); + background-color: hsl(var(--hue),60%,97%); + border: 1px solid hsl(var(--hue),50%,93%); + border-radius: .25rem; +} + +.new-job-title { + margin-bottom: .25rem; + font-size: 1rem; + font-weight: 700; +} + +.new-job-link { + display: flex; + align-items: flex-end; + justify-content: center; + width: 2.5rem; + font-size: 1.2rem; + background: hsl(var(--hue),50%,93%); +} + +.new-job-caption { + display: box; + margin: 0; + overflow: hidden; + font-size: .875rem; + box-orient: vertical; + -webkit-line-clamp: 3; +} + +.new-job-details { + flex: 1 0; + padding: 1rem; +} + +.new-job * { + transition: all .25s ease; +} + +.new-job:hover .new-job-link { + background: var(--atum-bg-dark); +} + +.new-job-link span { + margin-bottom: 10px; + color: hsl(var(--hue),30%,40%); +} + +.new-job:hover .new-job-link span { + color: #fff; +} diff --git a/media/com_cronjobs/joomla.asset.json b/media/com_cronjobs/joomla.asset.json index a41f4d3dd9818..77f025214a487 100644 --- a/media/com_cronjobs/joomla.asset.json +++ b/media/com_cronjobs/joomla.asset.json @@ -27,6 +27,11 @@ "attributes": { "type" : "module" } + }, + { + "name": "com_cronjobs.admin-plg-job-css", + "type": "style", + "uri": "com_cronjobs/admin-plg-job.css" } ] } diff --git a/media/com_cronjobs/js/admin-plg-job-search-es5.js b/media/com_cronjobs/js/admin-plg-job-search-es5.js index 96ec218e1bdeb..aaf608dfdc781 100644 --- a/media/com_cronjobs/js/admin-plg-job-search-es5.js +++ b/media/com_cronjobs/js/admin-plg-job-search-es5.js @@ -7,7 +7,7 @@ */ /** - * Add a keyboard event listener to the Select a Module Type search element. + * Add a keyboard event listener to the Select a Job Type search element. * * IMPORTANT! This script is meant to be loaded deferred. This means that a. it's non-blocking * (the browser can load it whenever) and b. it doesn't need an on DOMContentLoaded event handler @@ -15,12 +15,12 @@ * whole point of it being deferred. * * The search box has a keyboard handler that fires every time you press a keyboard button or send - * a keypress with a touch / virtual keyboard. We then iterate all module type cards and check if - * the plain text (HTML stripped out) representation of the module title or description partially + * a keypress with a touch / virtual keyboard. We then iterate all job type cards and check if + * the plain text (HTML stripped out) representation of the job title or description partially * matches the text you entered in the search box. If it doesn't we add a Bootstrap class to hide - * the module. + * the job. * - * This way we limit the displayed modules only to those searched. + * This way we limit the displayed jobs only to those searched. * * This feature follows progressive enhancement. The search box is hidden by default and only * displayed when this JavaScript here executes. Furthermore, session storage is only used if it @@ -32,7 +32,7 @@ * and accessibility. * * Finally, the search string is saved into session storage on the assumption that the user is - * probably going to be creating multiple instances of the same module, one after another, as is + * probably going to be creating multiple instances of the same job, one after another, as is * typical when building a new Joomla! site. * @codingStandardsIgnoreStart */ @@ -53,7 +53,7 @@ if (typeof sessionStorage !== 'undefined') { sessionStorage.setItem('Joomla.com_cronjobs.new.search', partialSearch); - } // Iterate all the module cards + } // Iterate all the job cards elCards.forEach(function (card) { diff --git a/media/com_cronjobs/js/admin-plg-job-search.js b/media/com_cronjobs/js/admin-plg-job-search.js index f90c3962a394d..2212605dfe9f6 100644 --- a/media/com_cronjobs/js/admin-plg-job-search.js +++ b/media/com_cronjobs/js/admin-plg-job-search.js @@ -4,7 +4,7 @@ */ /** - * Add a keyboard event listener to the Select a Module Type search element. + * Add a keyboard event listener to the Select a Job Type search element. * * IMPORTANT! This script is meant to be loaded deferred. This means that a. it's non-blocking * (the browser can load it whenever) and b. it doesn't need an on DOMContentLoaded event handler @@ -12,12 +12,12 @@ * whole point of it being deferred. * * The search box has a keyboard handler that fires every time you press a keyboard button or send - * a keypress with a touch / virtual keyboard. We then iterate all module type cards and check if - * the plain text (HTML stripped out) representation of the module title or description partially + * a keypress with a touch / virtual keyboard. We then iterate all job type cards and check if + * the plain text (HTML stripped out) representation of the job title or description partially * matches the text you entered in the search box. If it doesn't we add a Bootstrap class to hide - * the module. + * the job. * - * This way we limit the displayed modules only to those searched. + * This way we limit the displayed jobs only to those searched. * * This feature follows progressive enhancement. The search box is hidden by default and only * displayed when this JavaScript here executes. Furthermore, session storage is only used if it @@ -29,7 +29,7 @@ * and accessibility. * * Finally, the search string is saved into session storage on the assumption that the user is - * probably going to be creating multiple instances of the same module, one after another, as is + * probably going to be creating multiple instances of the same job, one after another, as is * typical when building a new Joomla! site. * @codingStandardsIgnoreStart */ @@ -64,7 +64,7 @@ if (elSearch && elSearchContainer) { const cardHeader = card.querySelector('.new-job-title'); const cardBody = card.querySelector('.card-body'); const title = cardHeader ? cardHeader.textContent : ''; - const description = cardBody ? cardBody.textContent : ''; // If the module title and description don’t match add a class to hide it. + const description = cardBody ? cardBody.textContent : ''; // If the job title and description don’t match add a class to hide it. if (title && !title.toLowerCase().includes(partialSearch.toLowerCase()) && description && !description.toLowerCase().includes(partialSearch.toLowerCase())) { card.classList.add('d-none'); From 5bb56af28e7af9c673bbc6d7cee9a1e68a198f5d Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Fri, 16 Jul 2021 23:42:42 +0530 Subject: [PATCH 061/615] Add SelectView default layout template Still due treatment for the CLI job type (a special cell on a row of its own). --- .../com_cronjobs/tmpl/select/default.php | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 administrator/components/com_cronjobs/tmpl/select/default.php diff --git a/administrator/components/com_cronjobs/tmpl/select/default.php b/administrator/components/com_cronjobs/tmpl/select/default.php new file mode 100644 index 0000000000000..fedf6407c2fc9 --- /dev/null +++ b/administrator/components/com_cronjobs/tmpl/select/default.php @@ -0,0 +1,105 @@ + + * @license GPL v3 + * @codingStandardsIgnoreStart + */ + +// Restrict direct access +defined('_JEXEC') or die; + +use Joomla\CMS\Factory; +use Joomla\CMS\HTML\HTMLHelper; +use Joomla\CMS\Language\Text; +use Joomla\CMS\Router\Route; +use Joomla\Component\Cronjobs\Administrator\View\Select\HtmlView; + +/** @var HtmlView $this */ + +$app = $this->app; + +// ? : What does this do? +// ! : This is going down into loading the select-modal script, what does that do? +// $function = $app->getInput()->get('function'); + +// TODO : Cronjob search script +$wa = $this->document->getWebAssetManager(); +$wa->useStyle('com_cronjobs.admin-plg-job-css'); +$wa->useScript('com_cronjobs.admin-plg-job-search'); + +/* + * if ($function) : + * $wa->useScript('COM_CRONJOBS.admin-select-modal'); + * endif;*/ +?> + + +
+
+
+ +
+ +
+ +
+
+
+
+
+ + +
+
+ +
+ + +
+

+ +

+
+ + +
+ + + + + + items as &$item) : ?> + + id . '&type=plugin'; ?> + escape($item->title); ?> + escape(strip_tags($item->desc)), 200); ?> + + +
+

+

+ +

+
+ + + +
+ + +
+
+
From 23049271ff4ccba4ec69b57557f001cf84711ad9 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Fri, 16 Jul 2021 23:50:34 +0530 Subject: [PATCH 062/615] Add language files to plg_testjob --- .../testjob/language/en-GB/en-GB.plg_system_testjob.ini | 4 ++++ .../language/en-GB/en-GB.plg_system_testjob.sys.ini | 4 ++++ plugins/system/testjob/testjob.php | 7 +++++++ plugins/system/testjob/testjob.xml | 4 ++++ 4 files changed, 19 insertions(+) create mode 100644 plugins/system/testjob/language/en-GB/en-GB.plg_system_testjob.ini create mode 100644 plugins/system/testjob/language/en-GB/en-GB.plg_system_testjob.sys.ini diff --git a/plugins/system/testjob/language/en-GB/en-GB.plg_system_testjob.ini b/plugins/system/testjob/language/en-GB/en-GB.plg_system_testjob.ini new file mode 100644 index 0000000000000..6700c323b920a --- /dev/null +++ b/plugins/system/testjob/language/en-GB/en-GB.plg_system_testjob.ini @@ -0,0 +1,4 @@ +COM_TESTJOBPLG_JOB1_TITLE="First Test Job" +COM_TESTJOBPLG_JOB1_DESC="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." +COM_TESTJOBPLG_JOB2_TITLE="Second Test Job" +COM_TESTJOBPLG_JOB2_DESC="Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?" diff --git a/plugins/system/testjob/language/en-GB/en-GB.plg_system_testjob.sys.ini b/plugins/system/testjob/language/en-GB/en-GB.plg_system_testjob.sys.ini new file mode 100644 index 0000000000000..6700c323b920a --- /dev/null +++ b/plugins/system/testjob/language/en-GB/en-GB.plg_system_testjob.sys.ini @@ -0,0 +1,4 @@ +COM_TESTJOBPLG_JOB1_TITLE="First Test Job" +COM_TESTJOBPLG_JOB1_DESC="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." +COM_TESTJOBPLG_JOB2_TITLE="Second Test Job" +COM_TESTJOBPLG_JOB2_DESC="Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?" diff --git a/plugins/system/testjob/testjob.php b/plugins/system/testjob/testjob.php index 34687393ce42b..d6decd877c180 100644 --- a/plugins/system/testjob/testjob.php +++ b/plugins/system/testjob/testjob.php @@ -21,6 +21,13 @@ */ class PlgSystemTestjob extends CMSPlugin implements SubscriberInterface { + /** + * Autoload the language file + * + * @var boolean + * @since __DEPLOY_VERSION__ + */ + protected $autoloadLanguage = true; /** * Returns event subscriptions diff --git a/plugins/system/testjob/testjob.xml b/plugins/system/testjob/testjob.xml index e488421d4364d..a2e12d26c1b66 100644 --- a/plugins/system/testjob/testjob.xml +++ b/plugins/system/testjob/testjob.xml @@ -9,4 +9,8 @@ testjob.php + + en-GB.plg_system_testjob.ini + en-GB.plg_system_testjob.sys.ini + From 3b27e37cce833eece2abbddd3388e4bdca7a4dd5 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Sat, 17 Jul 2021 16:57:22 +0530 Subject: [PATCH 063/615] Move sql scripts to core sql locations Moves the installation sql to /installation and as update scripts for existing installations. Removes uninstall sql as standard for core extensions. Existing sql update scripts are also removed. --- .../sql/updates/mysql/4.1.0-2021-07-17.sql} | 14 ++-- .../updates/postgresql/4.1.0-2021-07-17.sql} | 45 ++++++++----- .../com_cronjobs/sql/mysql/uninstall.sql | 3 - .../com_cronjobs/sql/postgresql/uninstall.sql | 6 -- .../sql/updates/mysql/2021-07-08.mysql.sql | 6 -- .../sql/updates/mysql/2021-07-09.mysql.sql | 46 ------------- .../sql/updates/mysql/2021-07-12.mysql.sql | 11 ---- .../updates/postgresql/2021-07-08.postgre.sql | 7 -- .../updates/postgresql/2021-07-09.postgre.sql | 57 ---------------- .../updates/postgresql/2021-07-12.postgre.sql | 12 ---- installation/sql/mysql/extensions.sql | 51 +++++++++++++++ installation/sql/postgresql/extensions.sql | 65 +++++++++++++++++++ 12 files changed, 154 insertions(+), 169 deletions(-) rename administrator/components/{com_cronjobs/sql/mysql/install.sql => com_admin/sql/updates/mysql/4.1.0-2021-07-17.sql} (90%) rename administrator/components/{com_cronjobs/sql/postgresql/install.sql => com_admin/sql/updates/postgresql/4.1.0-2021-07-17.sql} (64%) delete mode 100644 administrator/components/com_cronjobs/sql/mysql/uninstall.sql delete mode 100644 administrator/components/com_cronjobs/sql/postgresql/uninstall.sql delete mode 100644 administrator/components/com_cronjobs/sql/updates/mysql/2021-07-08.mysql.sql delete mode 100644 administrator/components/com_cronjobs/sql/updates/mysql/2021-07-09.mysql.sql delete mode 100644 administrator/components/com_cronjobs/sql/updates/mysql/2021-07-12.mysql.sql delete mode 100644 administrator/components/com_cronjobs/sql/updates/postgresql/2021-07-08.postgre.sql delete mode 100644 administrator/components/com_cronjobs/sql/updates/postgresql/2021-07-09.postgre.sql delete mode 100644 administrator/components/com_cronjobs/sql/updates/postgresql/2021-07-12.postgre.sql diff --git a/administrator/components/com_cronjobs/sql/mysql/install.sql b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-17.sql similarity index 90% rename from administrator/components/com_cronjobs/sql/mysql/install.sql rename to administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-17.sql index c484350770438..8966dd6c95fdc 100644 --- a/administrator/components/com_cronjobs/sql/mysql/install.sql +++ b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-17.sql @@ -1,4 +1,6 @@ --- Table Structure `#__cronjobs` [Main] -- +-- +-- Table structure for table `#__cronjobs` +-- CREATE TABLE IF NOT EXISTS `#__cronjobs` ( @@ -20,13 +22,16 @@ CREATE TABLE IF NOT EXISTS `#__cronjobs` `created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', `created_by` INT(10) UNSIGNED NOT NULL DEFAULT '0', PRIMARY KEY (id) -) + ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 DEFAULT COLLATE = utf8mb4_unicode_ci; +-- -------------------------------------------------------- --- Table structure `#__cronjobs_scripts` -- +-- +-- Table structure for table `#__cronjobs_scripts` +-- CREATE TABLE IF NOT EXISTS `#__cronjobs_scripts` ( @@ -35,8 +40,9 @@ CREATE TABLE IF NOT EXISTS `#__cronjobs_scripts` `directory` varchar(1024) NOT NULL, `file` varchar(256) NOT NULL, PRIMARY KEY (id) -) + ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 DEFAULT COLLATE = utf8mb4_unicode_ci; +-- -------------------------------------------------------- diff --git a/administrator/components/com_cronjobs/sql/postgresql/install.sql b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-17.sql similarity index 64% rename from administrator/components/com_cronjobs/sql/postgresql/install.sql rename to administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-17.sql index b220f04354e13..05a625d0ff23c 100644 --- a/administrator/components/com_cronjobs/sql/postgresql/install.sql +++ b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-17.sql @@ -1,24 +1,31 @@ -------- Create required enumerated types with exception handling ---------- +-- +-- Create enumerated types for com_cronjobs +-- + DO $$ - BEGIN - CREATE TYPE job_type AS ENUM ('script', 'plugin'); - EXCEPTION +BEGIN +CREATE TYPE job_type AS ENUM ('script', 'plugin'); +EXCEPTION WHEN duplicate_object THEN null; - END +END $$; DO $$ - BEGIN - CREATE TYPE trigger_type AS ENUM ('pseudo_cron', 'cron', 'visit_count'); - EXCEPTION +BEGIN +CREATE TYPE trigger_type AS ENUM ('pseudo_cron', 'cron', 'visit_count'); +EXCEPTION WHEN duplicate_object THEN null; - END +END $$; ---------------------------------------------------------------------------- -------------------- Table Structure "#__cronjobs" [Main] ------------------- +-- -------------------------------------------------------- + +-- +-- Table structure for table "#__cronjobs" +-- + CREATE TABLE IF NOT EXISTS "#__cronjobs" ( "id" INT GENERATED ALWAYS AS IDENTITY, @@ -35,11 +42,14 @@ CREATE TABLE IF NOT EXISTS "#__cronjobs" "times_failed" INT DEFAULT '0', "note" TEXT DEFAULT '', "created" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT '0000-00-00 00:00:00', - "created_by" BIGINT NOT NULL DEFAULT '0' -); ----------------------------------------------------------------------------- + "created_by" BIGINT NOT NULL DEFAULT '0' + ); ------- Table Structure "#__cronjobs_scripts" ------ +-- -------------------------------------------------------- + +-- +-- Table structure for table "#__cronjobs_scripts" +-- CREATE TABLE IF NOT EXISTS "#__cronjobs_scripts" ( @@ -47,5 +57,6 @@ CREATE TABLE IF NOT EXISTS "#__cronjobs_scripts" "job_id" INT, -- References "#__cronjobs"(id) "directory" VARCHAR(256) NOT NULL, "file" VARCHAR(128) NOT NULL -); ---------------------------------------------------- + ); + +-- -------------------------------------------------------- diff --git a/administrator/components/com_cronjobs/sql/mysql/uninstall.sql b/administrator/components/com_cronjobs/sql/mysql/uninstall.sql deleted file mode 100644 index 8d53a097f01fa..0000000000000 --- a/administrator/components/com_cronjobs/sql/mysql/uninstall.sql +++ /dev/null @@ -1,3 +0,0 @@ -DROP TABLE IF EXISTS `#__cronjobs`; -DROP TABLE IF EXISTS `#__cronjobs_scripts`; -DROP TABLE IF EXISTS `#__cronjobs_plg`; -- Table TBD diff --git a/administrator/components/com_cronjobs/sql/postgresql/uninstall.sql b/administrator/components/com_cronjobs/sql/postgresql/uninstall.sql deleted file mode 100644 index 19962f1f53a2b..0000000000000 --- a/administrator/components/com_cronjobs/sql/postgresql/uninstall.sql +++ /dev/null @@ -1,6 +0,0 @@ -DROP TABLE IF EXISTS "#__cronjobs"; -DROP TABLE IF EXISTS "#__cronjobs_scripts"; -DROP TABLE IF EXISTS "#__cronjobs_plg"; -- Table TBD - -DROP TYPE IF EXISTS job_type CASCADE; -DROP TYPE IF EXISTS trigger_type CASCADE; diff --git a/administrator/components/com_cronjobs/sql/updates/mysql/2021-07-08.mysql.sql b/administrator/components/com_cronjobs/sql/updates/mysql/2021-07-08.mysql.sql deleted file mode 100644 index 80f735fa38359..0000000000000 --- a/administrator/components/com_cronjobs/sql/updates/mysql/2021-07-08.mysql.sql +++ /dev/null @@ -1,6 +0,0 @@ -ALTER TABLE `#__cronjobs` - ADD COLUMN `asset_id` INT(10) NOT NULL DEFAULT '0'; -ALTER TABLE `#__cronjobs` - ADD COLUMN `created` INT(10) NOT NULL DEFAULT '0'; -ALTER TABLE `#__cronjobs` - ADD COLUMN `created_by` INT(10) NOT NULL DEFAULT '0'; diff --git a/administrator/components/com_cronjobs/sql/updates/mysql/2021-07-09.mysql.sql b/administrator/components/com_cronjobs/sql/updates/mysql/2021-07-09.mysql.sql deleted file mode 100644 index 1a1e02ce63f4f..0000000000000 --- a/administrator/components/com_cronjobs/sql/updates/mysql/2021-07-09.mysql.sql +++ /dev/null @@ -1,46 +0,0 @@ --- ⚠ This update causes data loss. - -DROP TABLE IF EXISTS `#__cronjobs_scripts`; -DROP TABLE IF EXISTS `#__cronjobs`; - --- Table Structure `#__cronjobs` [Main] -- - -CREATE TABLE IF NOT EXISTS `#__cronjobs` -( - `id` INT(4) NOT NULL AUTO_INCREMENT, - `asset_id` INT(10) NOT NULL UNIQUE DEFAULT '0', - `title` varchar(128) NOT NULL UNIQUE, - -- Job type. Can execute a script or plugin routine - `type` ENUM ('script', 'plugin') NOT NULL DEFAULT 'script', - -- Trigger type, default to PseudoCron (compatible everywhere). - `trigger` ENUM ('pseudo_cron', 'cron', 'visit_count') NOT NULL DEFAULT 'pseudo_cron' COMMENT 'Defines how job is triggered', - `execution_interval` INT NOT NULL COMMENT 'Configured time between executions, in seconds', - `state` TINYINT NOT NULL DEFAULT '0', - `last_exit_code` INT(11) NOT NULL DEFAULT '0' COMMENT 'Exit code when job was last run', - `last_execution` DATETIME NOT NULL COMMENT 'Timestamp of last run', - `next_execution` DATETIME NOT NULL COMMENT 'Timestamp of next (planned) run, referred for execution on trigger', - `times_executed` INT(11) DEFAULT '0' COMMENT 'Count of successful triggers', - `times_failed` INT(11) DEFAULT '0' COMMENT 'Count of failures', - `note` TEXT, - `created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', - `created_by` INT(10) UNSIGNED NOT NULL DEFAULT '0', - PRIMARY KEY (id) -) - ENGINE = InnoDB - DEFAULT CHARSET = utf8mb4 - DEFAULT COLLATE = utf8mb4_unicode_ci; - - --- Table structure `#__cronjobs_scripts` -- - -CREATE TABLE IF NOT EXISTS `#__cronjobs_scripts` -( - `id` int(4) NOT NULL AUTO_INCREMENT, - `job_id` int(4) NOT NULL COMMENT 'Cronjob ID', -- References `#__cronjobs`(id) - `directory` varchar(1024) NOT NULL, - `file` varchar(256) NOT NULL, - PRIMARY KEY (id) -) - ENGINE = InnoDB - DEFAULT CHARSET = utf8mb4 - DEFAULT COLLATE = utf8mb4_unicode_ci; diff --git a/administrator/components/com_cronjobs/sql/updates/mysql/2021-07-12.mysql.sql b/administrator/components/com_cronjobs/sql/updates/mysql/2021-07-12.mysql.sql deleted file mode 100644 index 632d23cbb7d6b..0000000000000 --- a/administrator/components/com_cronjobs/sql/updates/mysql/2021-07-12.mysql.sql +++ /dev/null @@ -1,11 +0,0 @@ --- Modify execution_interval column, changes type to TIME [⚠ experimental] -ALTER TABLE `#__cronjobs` - MODIFY `execution_interval` TIME; - --- Remove NOT NULL constraint from last_execution -ALTER TABLE `#__cronjobs` - MODIFY `last_execution` DATETIME COMMENT 'Timestamp of last run'; - --- Remove NOT NULL constraint from next_execution -ALTER TABLE `#__cronjobs` - MODIFY `next_execution` DATETIME COMMENT 'Timestamp of next (planned) run, referred for execution on trigger'; diff --git a/administrator/components/com_cronjobs/sql/updates/postgresql/2021-07-08.postgre.sql b/administrator/components/com_cronjobs/sql/updates/postgresql/2021-07-08.postgre.sql deleted file mode 100644 index 55c3a717bfaf6..0000000000000 --- a/administrator/components/com_cronjobs/sql/updates/postgresql/2021-07-08.postgre.sql +++ /dev/null @@ -1,7 +0,0 @@ -ALTER TABLE "#__cronjobs" - ADD COLUMN "asset_id" INT NOT NULL DEFAULT '0'; - -ALTER TABLE "#__cronjobs" - ADD COLUMN "created" INT NOT NULL DEFAULT '0'; -ALTER TABLE "#__cronjobs" - ADD COLUMN "created_by" INT NOT NULL DEFAULT '0'; diff --git a/administrator/components/com_cronjobs/sql/updates/postgresql/2021-07-09.postgre.sql b/administrator/components/com_cronjobs/sql/updates/postgresql/2021-07-09.postgre.sql deleted file mode 100644 index 03c90e97b370c..0000000000000 --- a/administrator/components/com_cronjobs/sql/updates/postgresql/2021-07-09.postgre.sql +++ /dev/null @@ -1,57 +0,0 @@ --- ⚠ This update causes data loss. - -DROP TABLE IF EXISTS "#__cronjobs_scripts"; -DROP TABLE IF EXISTS "#__cronjobs"; - -------- Create required enumerated types with exception handling ---------- -DO -$$ - BEGIN - CREATE TYPE job_type AS ENUM ('script', 'plugin'); - EXCEPTION - WHEN duplicate_object THEN null; - END -$$; - -DO -$$ - BEGIN - CREATE TYPE trigger_type AS ENUM ('pseudo_cron', 'cron', 'visit_count'); - EXCEPTION - WHEN duplicate_object THEN null; - END -$$; ---------------------------------------------------------------------------- - -------------------- Table Structure "#__cronjobs" [Main] ------------------- -CREATE TABLE IF NOT EXISTS "#__cronjobs" -( - "id" INT GENERATED ALWAYS AS IDENTITY, - "asset_id" BIGINT NOT NULL DEFAULT '0', - "title" VARCHAR(255) NOT NULL, - "type" JOB_TYPE, - "execution_interval" INT NOT NULL, - "trigger" TRIGGER_TYPE NOT NULL DEFAULT 'pseudo_cron', - "state" SMALLINT NOT NULL DEFAULT '0', - "last_exit_code" INT NOT NULL DEFAULT '0', - "last_execution" TIMESTAMP NOT NULL, - "next_execution" TIMESTAMP NOT NULL, - "times_executed" TIMESTAMP NOT NULL, - "times_failed" INT DEFAULT '0', - "note" TEXT DEFAULT '', - "created" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT '0000-00-00 00:00:00', - "created_by" BIGINT NOT NULL DEFAULT '0' -); ----------------------------------------------------------------------------- - ------- Table Structure "#__cronjobs_scripts" ------ - -CREATE TABLE IF NOT EXISTS "#__cronjobs_scripts" -( - "id" INT GENERATED ALWAYS AS IDENTITY, - "job_id" INT, -- References "#__cronjobs"(id) - "directory" VARCHAR(256) NOT NULL, - "file" VARCHAR(128) NOT NULL -); ---------------------------------------------------- - diff --git a/administrator/components/com_cronjobs/sql/updates/postgresql/2021-07-12.postgre.sql b/administrator/components/com_cronjobs/sql/updates/postgresql/2021-07-12.postgre.sql deleted file mode 100644 index 804d04d47b0fd..0000000000000 --- a/administrator/components/com_cronjobs/sql/updates/postgresql/2021-07-12.postgre.sql +++ /dev/null @@ -1,12 +0,0 @@ --- Modify execution_interval column, changes type to INTERVAL [⚠ experimental] -ALTER TABLE IF EXISTS "#__cronjobs" - ALTER COLUMN "execution_interval" TYPE INTERVAL; - --- Remove NOT NULL constraint from last_execution -ALTER TABLE IF EXISTS "#__cronjobs" - ALTER COLUMN "last_execution" TYPE TIMESTAMP; - --- Remove NOT NULL constraint from next_execution -ALTER TABLE IF EXISTS "#__cronjobs" - ALTER COLUMN "next_execution" TYPE TIMESTAMP; - diff --git a/installation/sql/mysql/extensions.sql b/installation/sql/mysql/extensions.sql index 52a6c316af3e5..48a06b7894908 100644 --- a/installation/sql/mysql/extensions.sql +++ b/installation/sql/mysql/extensions.sql @@ -882,3 +882,54 @@ CREATE TABLE IF NOT EXISTS `#__action_logs_users` ( PRIMARY KEY (`user_id`), KEY `idx_notify` (`notify`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `#__cronjobs` +-- + +CREATE TABLE IF NOT EXISTS `#__cronjobs` +( + `id` INT(4) NOT NULL AUTO_INCREMENT, + `asset_id` INT(10) NOT NULL UNIQUE DEFAULT '0', + `title` varchar(128) NOT NULL UNIQUE, + -- Job type. Can execute a script or plugin routine + `type` ENUM ('script', 'plugin') NOT NULL DEFAULT 'script', + -- Trigger type, default to PseudoCron (compatible everywhere). + `trigger` ENUM ('pseudo_cron', 'cron', 'visit_count') NOT NULL DEFAULT 'pseudo_cron' COMMENT 'Defines how job is triggered', + `execution_interval` TIME NOT NULL COMMENT 'Configured time between executions,in HH:MM:SS format', + `state` TINYINT NOT NULL DEFAULT FALSE, + `last_exit_code` INT(11) NOT NULL DEFAULT '0' COMMENT 'Exit code when job was last run', + `last_execution` DATETIME COMMENT 'Timestamp of last run', + `next_execution` DATETIME COMMENT 'Timestamp of next (planned) run, referred for execution on trigger', + `times_executed` INT(11) DEFAULT '0' COMMENT 'Count of successful triggers', + `times_failed` INT(11) DEFAULT '0' COMMENT 'Count of failures', + `note` TEXT, + `created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', + `created_by` INT(10) UNSIGNED NOT NULL DEFAULT '0', + PRIMARY KEY (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 + DEFAULT COLLATE = utf8mb4_unicode_ci; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `#__cronjobs_scripts` +-- + +CREATE TABLE IF NOT EXISTS `#__cronjobs_scripts` +( + `id` int(4) NOT NULL AUTO_INCREMENT, + `job_id` int(4) NOT NULL COMMENT 'Cronjob ID', -- References `#__cronjobs`(id) + `directory` varchar(1024) NOT NULL, + `file` varchar(256) NOT NULL, + PRIMARY KEY (id) +) + ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 + DEFAULT COLLATE = utf8mb4_unicode_ci; + +-- -------------------------------------------------------- diff --git a/installation/sql/postgresql/extensions.sql b/installation/sql/postgresql/extensions.sql index 628c12098f02f..3f84dcde8c5b6 100644 --- a/installation/sql/postgresql/extensions.sql +++ b/installation/sql/postgresql/extensions.sql @@ -907,3 +907,68 @@ BEGIN RETURN soundex; END; $$; + +-- -------------------------------------------------------- + +-- +-- Create enumerated types for com_cronjobs +-- + +DO +$$ + BEGIN + CREATE TYPE job_type AS ENUM ('script', 'plugin'); + EXCEPTION + WHEN duplicate_object THEN null; + END +$$; + +DO +$$ + BEGIN + CREATE TYPE trigger_type AS ENUM ('pseudo_cron', 'cron', 'visit_count'); + EXCEPTION + WHEN duplicate_object THEN null; + END +$$; + +-- -------------------------------------------------------- + +-- +-- Table structure for table "#__cronjobs" +-- + +CREATE TABLE IF NOT EXISTS "#__cronjobs" +( + "id" INT GENERATED ALWAYS AS IDENTITY, + "asset_id" BIGINT NOT NULL DEFAULT '0', + "title" VARCHAR(255) NOT NULL, + "type" JOB_TYPE, + "execution_interval" INTERVAL NOT NULL, + "trigger" TRIGGER_TYPE NOT NULL DEFAULT 'pseudo_cron', + "state" SMALLINT NOT NULL DEFAULT '0', + "last_exit_code" INT NOT NULL DEFAULT '0', + "last_execution" TIMESTAMP, + "next_execution" TIMESTAMP, + "times_executed" TIMESTAMP NOT NULL, + "times_failed" INT DEFAULT '0', + "note" TEXT DEFAULT '', + "created" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT '0000-00-00 00:00:00', + "created_by" BIGINT NOT NULL DEFAULT '0' +); + +-- -------------------------------------------------------- + +-- +-- Table structure for table "#__cronjobs_scripts" +-- + +CREATE TABLE IF NOT EXISTS "#__cronjobs_scripts" +( + "id" INT GENERATED ALWAYS AS IDENTITY, + "job_id" INT, -- References "#__cronjobs"(id) + "directory" VARCHAR(256) NOT NULL, + "file" VARCHAR(128) NOT NULL +); + +-- -------------------------------------------------------- From 7fb787e75e8fbed06614cfdb0b502dc5b0e22424 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Sat, 17 Jul 2021 19:53:44 +0530 Subject: [PATCH 064/615] Move language files to core location Moves the files from the Joomla global /language/en-GB directory. Also updates the language files with some new constants. --- .../com_cronjobs => }/language/en-GB/com_cronjobs.ini | 8 +++++++- .../com_cronjobs => }/language/en-GB/com_cronjobs.sys.ini | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) rename administrator/{components/com_cronjobs => }/language/en-GB/com_cronjobs.ini (80%) rename administrator/{components/com_cronjobs => }/language/en-GB/com_cronjobs.sys.ini (80%) diff --git a/administrator/components/com_cronjobs/language/en-GB/com_cronjobs.ini b/administrator/language/en-GB/com_cronjobs.ini similarity index 80% rename from administrator/components/com_cronjobs/language/en-GB/com_cronjobs.ini rename to administrator/language/en-GB/com_cronjobs.ini index 27b9cfca5e07b..d4cdf8be37a29 100644 --- a/administrator/components/com_cronjobs/language/en-GB/com_cronjobs.ini +++ b/administrator/language/en-GB/com_cronjobs.ini @@ -1,4 +1,4 @@ -; Joomla! Project +; Joomla! Projects ; (C) 2021 Open Source Matters, Inc. ; GPL v3 COM_CRONJOBS="Cronjobs" @@ -36,3 +36,9 @@ COM_CRONJOBS_LABEL_TIMES_FAIL="Times Failed" COM_CRONJOBS_LABEL_NOTES="Notes" COM_CRONJOBS_FORM_TITLE_NEW="New Cronjob" COM_CRONJOBS_FORM_TITLE_EDIT="Edit Cronjob" +COM_CRONJOBS_TYPE_CHOOSE="Select a Job type" +COM_CRONJOBS_MSG_MANAGE_NO_JOB_PLUGINS="There are no plugin jobs matching your query" +COM_CRONJOBS_SELECT_PLG_JOB="Select job, %s" +COM_CRONJOBS_CLI_JOBS_TITLE="CLI/Script Job" +COM_CRONJOBS_CLI_JOBS_DESC="Configure a CLI script to run at a scheduled interval or another condition." +COM_CRONJOBS_SELECT_CLI_JOB="Select CLI job" diff --git a/administrator/components/com_cronjobs/language/en-GB/com_cronjobs.sys.ini b/administrator/language/en-GB/com_cronjobs.sys.ini similarity index 80% rename from administrator/components/com_cronjobs/language/en-GB/com_cronjobs.sys.ini rename to administrator/language/en-GB/com_cronjobs.sys.ini index 27b9cfca5e07b..d4cdf8be37a29 100644 --- a/administrator/components/com_cronjobs/language/en-GB/com_cronjobs.sys.ini +++ b/administrator/language/en-GB/com_cronjobs.sys.ini @@ -1,4 +1,4 @@ -; Joomla! Project +; Joomla! Projects ; (C) 2021 Open Source Matters, Inc. ; GPL v3 COM_CRONJOBS="Cronjobs" @@ -36,3 +36,9 @@ COM_CRONJOBS_LABEL_TIMES_FAIL="Times Failed" COM_CRONJOBS_LABEL_NOTES="Notes" COM_CRONJOBS_FORM_TITLE_NEW="New Cronjob" COM_CRONJOBS_FORM_TITLE_EDIT="Edit Cronjob" +COM_CRONJOBS_TYPE_CHOOSE="Select a Job type" +COM_CRONJOBS_MSG_MANAGE_NO_JOB_PLUGINS="There are no plugin jobs matching your query" +COM_CRONJOBS_SELECT_PLG_JOB="Select job, %s" +COM_CRONJOBS_CLI_JOBS_TITLE="CLI/Script Job" +COM_CRONJOBS_CLI_JOBS_DESC="Configure a CLI script to run at a scheduled interval or another condition." +COM_CRONJOBS_SELECT_CLI_JOB="Select CLI job" From 4d666edfd1dd15fae15b7b7a2bb31bd353b5d8b1 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Sat, 17 Jul 2021 19:57:04 +0530 Subject: [PATCH 065/615] Update SelectView default layout template - Makes cards narrower (now look the same as com_modules SelectView) - Adds a special option for CLI Jobs (can look better) - Alters the option link params marginally --- .../com_cronjobs/tmpl/select/default.php | 71 ++++++++++++------- media/com_cronjobs/css/admin-plg-job.css | 20 ++++-- 2 files changed, 59 insertions(+), 32 deletions(-) diff --git a/administrator/components/com_cronjobs/tmpl/select/default.php b/administrator/components/com_cronjobs/tmpl/select/default.php index fedf6407c2fc9..b65752fcd499c 100644 --- a/administrator/components/com_cronjobs/tmpl/select/default.php +++ b/administrator/components/com_cronjobs/tmpl/select/default.php @@ -13,7 +13,6 @@ // Restrict direct access defined('_JEXEC') or die; -use Joomla\CMS\Factory; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\Router\Route; @@ -59,9 +58,9 @@ class="form-control" id="comCronjobsSelectSearch" -
-
- +
+
+
@@ -70,36 +69,54 @@ class="visually-hidden">

-
- - -
- - - - - items as &$item) : ?> - - id . '&type=plugin'; ?> - escape($item->title); ?> - escape(strip_tags($item->desc)), 200); ?> - - + + + + + +
+ + + items as &$item) : ?> + + id; ?> + escape($item->title); ?> + escape(strip_tags($item->desc)), 200); ?> + + +
+

+

+ +

+
+ + + +
+ + +
-
+ + diff --git a/media/com_cronjobs/css/admin-plg-job.css b/media/com_cronjobs/css/admin-plg-job.css index 70545228b3ade..57e53ab1ea18e 100644 --- a/media/com_cronjobs/css/admin-plg-job.css +++ b/media/com_cronjobs/css/admin-plg-job.css @@ -1,9 +1,9 @@ .new-job { display: flex; overflow: hidden; - color: hsl(var(--hue),30%,40%); - background-color: hsl(var(--hue),60%,97%); - border: 1px solid hsl(var(--hue),50%,93%); + color: hsl(var(--hue), 30%, 40%); + background-color: hsl(var(--hue), 60%, 97%); + border: 1px solid hsl(var(--hue), 50%, 93%); border-radius: .25rem; } @@ -19,7 +19,7 @@ justify-content: center; width: 2.5rem; font-size: 1.2rem; - background: hsl(var(--hue),50%,93%); + background: hsl(var(--hue), 50%, 93%); } .new-job-caption { @@ -46,9 +46,19 @@ .new-job-link span { margin-bottom: 10px; - color: hsl(var(--hue),30%,40%); + color: hsl(var(--hue), 30%, 40%); } .new-job:hover .new-job-link span { color: #fff; } + +.new-jobs .card-columns { + grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)) !important; +} + +#cli-job .new-job { + width: clamp(20em, 25vw, 50em); + margin: auto; + height: 12em; +} \ No newline at end of file From 982462e85b78f72b70fc53b0c7ec163954958b5a Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Sun, 18 Jul 2021 14:28:05 +0530 Subject: [PATCH 066/615] Fix SelectView toolbar Fixes the toolbar (didn't render before), adds the preferences and help buttons. Also adds the SpecialItem for the CLI job option and cleans up the code and comments. --- .../com_cronjobs/src/View/Select/HtmlView.php | 64 ++++++++++--------- 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/administrator/components/com_cronjobs/src/View/Select/HtmlView.php b/administrator/components/com_cronjobs/src/View/Select/HtmlView.php index 60db3f64b70dd..dbb738e8c773b 100644 --- a/administrator/components/com_cronjobs/src/View/Select/HtmlView.php +++ b/administrator/components/com_cronjobs/src/View/Select/HtmlView.php @@ -12,22 +12,23 @@ namespace Joomla\Component\Cronjobs\Administrator\View\Select; // Restrict direct access -\defined('_JEXEC') or die; +defined('_JEXEC') or die; use Exception; -use Joomla\CMS\Application\CMSApplication; +use JObject; +use Joomla\CMS\Application\AdministratorApplication; use Joomla\CMS\Factory; +use Joomla\CMS\Helper\ContentHelper; use Joomla\CMS\Language\Text; -use Joomla\CMS\Layout\FileLayout; use Joomla\CMS\MVC\View\GenericDataException; use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView; use Joomla\CMS\Toolbar\Toolbar; use Joomla\CMS\Toolbar\ToolbarHelper; +use function defined; /** * The MVC View Select * Should let the user choose from a list of plugin defined Jobs or a CLI job. - * ! : Untested * * @package Joomla.Administrator * @subpackage com_cronjobs @@ -37,7 +38,7 @@ class HtmlView extends BaseHtmlView { /** - * @var CMSApplication + * @var AdministratorApplication * @since __DEPLOY_VERSION__ */ protected $app; @@ -45,13 +46,13 @@ class HtmlView extends BaseHtmlView /** * The model state * - * @var \JObject + * @var JObject * @since __DEPLOY_VERSION__ */ protected $state; /** - * An array of items [TODO: Implement a 'Job' object or similar] + * An array of items * * @var array * @since __DEPLOY_VERSION__ @@ -60,7 +61,6 @@ class HtmlView extends BaseHtmlView /** * Will be used for the "CLI" / "Script" type job - * ! : Not in use yet * * @var object * @since version @@ -75,7 +75,6 @@ class HtmlView extends BaseHtmlView */ protected $modalLink; - /** * HtmlView constructor. * @@ -107,10 +106,12 @@ public function __construct($config = array()) */ public function display($tpl = null): void { - // ! Untested - $this->state = $this->get('State'); $this->items = $this->get('Items'); + $this->specialItem = (object) [ + 'title' => Text::_('COM_CRONJOBS_CLI_JOBS_TITLE'), + 'desc' => Text::_('COM_CRONJOBS_CLI_JOBS_DESC') + ]; $this->modalLink = ''; // Check for errors. @@ -125,16 +126,21 @@ public function display($tpl = null): void /** * Add the page title and toolbar. - * ! : Untested * * @return void * - * @since __DEPLOY_VERSION + * @since __DEPLOY_VERSION__ */ - protected function addToolbar() + protected function addToolbar(): void { - $state = $this->get('State'); - $clientId = (int) $state->get('client_id', 0); + $canDo = ContentHelper::getActions('com_cronjobs'); + + /* + * Get the global Toolbar instance + * TODO : Replace usage with ToolbarFactoryInterface. but how? + * Probably some changes in the core, since mod_menu calls and renders the getInstance() toolbar + */ + $toolbar = Toolbar::getInstance('toolbar'); /* * Add page title @@ -142,20 +148,20 @@ protected function addToolbar() */ ToolbarHelper::title(Text::_('COM_CRONJOBS_MANAGER_CRONJOBS'), 'tags'); - /* - * Get the toolbar object instance - * TODO : Replace usage with ToolbarFactoryInterface - */ - $bar = Toolbar::getInstance(); + $toolbar->linkButton('cancel') + ->buttonClass('btn btn-danger') + ->icon('icon-times') + ->text(Text::_('JCANCEL')) + ->url('index.php?option=com_cronjobs'); + + // Adds preferences button if user has privileges + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + $toolbar->preferences('com_cronjobs'); + } - // Instantiate a new FileLayout instance and render the layout - $layout = new FileLayout('toolbar.cancelselect'); + // Adds help button + $toolbar->help('JHELP_COMPONENTS_CRONJOBS_MANAGER'); - /* - * ? : What is this doing? - * ! : appendButton seems to want a ToolbarButton object, but we're passing a string? - * TODO : Button object? - */ - $bar->appendButton('Custom', $layout->render(array('client_id' => $clientId)), 'new'); } } From cfa3eceefa5325bffb87c8871495c49298fc253f Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Sun, 18 Jul 2021 20:19:45 +0530 Subject: [PATCH 067/615] Update MySQL SQL Scripts - Removes display width for integer types (deprecated 8.0, pull #32606) - Changes codestyle to follow existing Joomla SQL style --- .../sql/updates/mysql/4.1.0-2021-07-17.sql | 62 ++++++++----------- installation/sql/mysql/extensions.sql | 62 ++++++++----------- 2 files changed, 54 insertions(+), 70 deletions(-) diff --git a/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-17.sql b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-17.sql index 8966dd6c95fdc..ad324e9046fdc 100644 --- a/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-17.sql +++ b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-17.sql @@ -2,30 +2,26 @@ -- Table structure for table `#__cronjobs` -- -CREATE TABLE IF NOT EXISTS `#__cronjobs` -( - `id` INT(4) NOT NULL AUTO_INCREMENT, - `asset_id` INT(10) NOT NULL UNIQUE DEFAULT '0', - `title` varchar(128) NOT NULL UNIQUE, - -- Job type. Can execute a script or plugin routine - `type` ENUM ('script', 'plugin') NOT NULL DEFAULT 'script', - -- Trigger type, default to PseudoCron (compatible everywhere). - `trigger` ENUM ('pseudo_cron', 'cron', 'visit_count') NOT NULL DEFAULT 'pseudo_cron' COMMENT 'Defines how job is triggered', - `execution_interval` TIME NOT NULL COMMENT 'Configured time between executions,in HH:MM:SS format', - `state` TINYINT NOT NULL DEFAULT FALSE, - `last_exit_code` INT(11) NOT NULL DEFAULT '0' COMMENT 'Exit code when job was last run', - `last_execution` DATETIME COMMENT 'Timestamp of last run', - `next_execution` DATETIME COMMENT 'Timestamp of next (planned) run, referred for execution on trigger', - `times_executed` INT(11) DEFAULT '0' COMMENT 'Count of successful triggers', - `times_failed` INT(11) DEFAULT '0' COMMENT 'Count of failures', - `note` TEXT, - `created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', - `created_by` INT(10) UNSIGNED NOT NULL DEFAULT '0', - PRIMARY KEY (id) - ) - ENGINE = InnoDB - DEFAULT CHARSET = utf8mb4 - DEFAULT COLLATE = utf8mb4_unicode_ci; +CREATE TABLE IF NOT EXISTS `#__cronjobs` ( + `id` int NOT NULL AUTO_INCREMENT, + `asset_id` int NOT NULL UNIQUE DEFAULT '0', + `title` varchar(128) NOT NULL UNIQUE, + -- Job type. Can execute a script or plugin routine + `type` enum ('script', 'plugin') NOT NULL DEFAULT 'script', + -- Trigger type, default to PseudoCron (compatible everywhere). + `trigger` enum ('pseudo_cron', 'cron', 'visit_count') NOT NULL DEFAULT 'pseudo_cron' COMMENT 'Defines how job is triggered', + `execution_interval` time NOT NULL COMMENT 'Configured time between executions,in HH:MM:SS format', + `state` tinyint NOT NULL DEFAULT FALSE, + `last_exit_code` int NOT NULL DEFAULT '0' COMMENT 'Exit code when job was last run', + `last_execution` datetime COMMENT 'Timestamp of last run', + `next_execution` datetime COMMENT 'Timestamp of next (planned) run, referred for execution on trigger', + `times_executed` int DEFAULT '0' COMMENT 'Count of successful triggers', + `times_failed` int DEFAULT '0' COMMENT 'Count of failures', + `note` text, + `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `created_by` int UNSIGNED NOT NULL DEFAULT '0', + PRIMARY KEY (id) +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 DEFAULT COLLATE = utf8mb4_unicode_ci; -- -------------------------------------------------------- @@ -33,16 +29,12 @@ CREATE TABLE IF NOT EXISTS `#__cronjobs` -- Table structure for table `#__cronjobs_scripts` -- -CREATE TABLE IF NOT EXISTS `#__cronjobs_scripts` -( - `id` int(4) NOT NULL AUTO_INCREMENT, - `job_id` int(4) NOT NULL COMMENT 'Cronjob ID', -- References `#__cronjobs`(id) - `directory` varchar(1024) NOT NULL, - `file` varchar(256) NOT NULL, - PRIMARY KEY (id) - ) - ENGINE = InnoDB - DEFAULT CHARSET = utf8mb4 - DEFAULT COLLATE = utf8mb4_unicode_ci; +CREATE TABLE IF NOT EXISTS `#__cronjobs_scripts` ( + `id` int NOT NULL AUTO_INCREMENT, + `job_id` int NOT NULL COMMENT 'Cronjob ID', -- References `#__cronjobs`(id) + `directory` varchar(1024) NOT NULL, + `file` varchar(256) NOT NULL, + PRIMARY KEY (id) +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 DEFAULT COLLATE = utf8mb4_unicode_ci; -- -------------------------------------------------------- diff --git a/installation/sql/mysql/extensions.sql b/installation/sql/mysql/extensions.sql index 48a06b7894908..00f08c56411a4 100644 --- a/installation/sql/mysql/extensions.sql +++ b/installation/sql/mysql/extensions.sql @@ -889,30 +889,26 @@ CREATE TABLE IF NOT EXISTS `#__action_logs_users` ( -- Table structure for table `#__cronjobs` -- -CREATE TABLE IF NOT EXISTS `#__cronjobs` -( - `id` INT(4) NOT NULL AUTO_INCREMENT, - `asset_id` INT(10) NOT NULL UNIQUE DEFAULT '0', - `title` varchar(128) NOT NULL UNIQUE, - -- Job type. Can execute a script or plugin routine - `type` ENUM ('script', 'plugin') NOT NULL DEFAULT 'script', - -- Trigger type, default to PseudoCron (compatible everywhere). - `trigger` ENUM ('pseudo_cron', 'cron', 'visit_count') NOT NULL DEFAULT 'pseudo_cron' COMMENT 'Defines how job is triggered', - `execution_interval` TIME NOT NULL COMMENT 'Configured time between executions,in HH:MM:SS format', - `state` TINYINT NOT NULL DEFAULT FALSE, - `last_exit_code` INT(11) NOT NULL DEFAULT '0' COMMENT 'Exit code when job was last run', - `last_execution` DATETIME COMMENT 'Timestamp of last run', - `next_execution` DATETIME COMMENT 'Timestamp of next (planned) run, referred for execution on trigger', - `times_executed` INT(11) DEFAULT '0' COMMENT 'Count of successful triggers', - `times_failed` INT(11) DEFAULT '0' COMMENT 'Count of failures', - `note` TEXT, - `created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', - `created_by` INT(10) UNSIGNED NOT NULL DEFAULT '0', - PRIMARY KEY (id) -) - ENGINE = InnoDB - DEFAULT CHARSET = utf8mb4 - DEFAULT COLLATE = utf8mb4_unicode_ci; +CREATE TABLE IF NOT EXISTS `#__cronjobs` ( + `id` int NOT NULL AUTO_INCREMENT, + `asset_id` int NOT NULL UNIQUE DEFAULT '0', + `title` varchar(128) NOT NULL UNIQUE, + -- Job type. Can execute a script or plugin routine + `type` enum ('script', 'plugin') NOT NULL DEFAULT 'script', + -- Trigger type, default to PseudoCron (compatible everywhere). + `trigger` enum ('pseudo_cron', 'cron', 'visit_count') NOT NULL DEFAULT 'pseudo_cron' COMMENT 'Defines how job is triggered', + `execution_interval` time NOT NULL COMMENT 'Configured time between executions,in HH:MM:SS format', + `state` tinyint NOT NULL DEFAULT FALSE, + `last_exit_code` int NOT NULL DEFAULT '0' COMMENT 'Exit code when job was last run', + `last_execution` datetime COMMENT 'Timestamp of last run', + `next_execution` datetime COMMENT 'Timestamp of next (planned) run, referred for execution on trigger', + `times_executed` int DEFAULT '0' COMMENT 'Count of successful triggers', + `times_failed` int DEFAULT '0' COMMENT 'Count of failures', + `note` text, + `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `created_by` int UNSIGNED NOT NULL DEFAULT '0', + PRIMARY KEY (id) +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 DEFAULT COLLATE = utf8mb4_unicode_ci; -- -------------------------------------------------------- @@ -920,16 +916,12 @@ CREATE TABLE IF NOT EXISTS `#__cronjobs` -- Table structure for table `#__cronjobs_scripts` -- -CREATE TABLE IF NOT EXISTS `#__cronjobs_scripts` -( - `id` int(4) NOT NULL AUTO_INCREMENT, - `job_id` int(4) NOT NULL COMMENT 'Cronjob ID', -- References `#__cronjobs`(id) - `directory` varchar(1024) NOT NULL, - `file` varchar(256) NOT NULL, - PRIMARY KEY (id) -) - ENGINE = InnoDB - DEFAULT CHARSET = utf8mb4 - DEFAULT COLLATE = utf8mb4_unicode_ci; +CREATE TABLE IF NOT EXISTS `#__cronjobs_scripts` ( + `id` int NOT NULL AUTO_INCREMENT, + `job_id` int NOT NULL COMMENT 'Cronjob ID', -- References `#__cronjobs`(id) + `directory` varchar(1024) NOT NULL, + `file` varchar(256) NOT NULL, + PRIMARY KEY (id) +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 DEFAULT COLLATE = utf8mb4_unicode_ci; -- -------------------------------------------------------- From ce5c136f631e42714d45fc883377e2416b15c705 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Sun, 18 Jul 2021 20:43:08 +0530 Subject: [PATCH 068/615] Fix PostegreSQL SQL scripts - Fixes blocking PostegreSQL issues causing builds to fails - Changes codestyle to follow existing Joomla SQL style --- .../updates/postgresql/4.1.0-2021-07-17.sql | 64 +++++++++---------- installation/sql/postgresql/extensions.sql | 48 +++++++------- 2 files changed, 56 insertions(+), 56 deletions(-) diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-17.sql b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-17.sql index 05a625d0ff23c..1bc6bc91afda2 100644 --- a/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-17.sql +++ b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-17.sql @@ -1,23 +1,23 @@ -- --- Create enumerated types for com_cronjobs +-- Create enumerated types for "#__cronjobs" -- DO $$ -BEGIN -CREATE TYPE job_type AS ENUM ('script', 'plugin'); -EXCEPTION - WHEN duplicate_object THEN null; -END + BEGIN + CREATE TYPE job_type AS enum ('script', 'plugin'); + EXCEPTION + WHEN duplicate_object THEN NULL; + END $$; DO $$ -BEGIN -CREATE TYPE trigger_type AS ENUM ('pseudo_cron', 'cron', 'visit_count'); -EXCEPTION - WHEN duplicate_object THEN null; -END + BEGIN + CREATE TYPE trigger_type AS enum ('pseudo_cron', 'cron', 'visit_count'); + EXCEPTION + WHEN duplicate_object THEN NULL; + END $$; -- -------------------------------------------------------- @@ -28,22 +28,22 @@ $$; CREATE TABLE IF NOT EXISTS "#__cronjobs" ( - "id" INT GENERATED ALWAYS AS IDENTITY, - "asset_id" BIGINT NOT NULL DEFAULT '0', - "title" VARCHAR(255) NOT NULL, - "type" JOB_TYPE, - "execution_interval" INTERVAL NOT NULL, - "trigger" TRIGGER_TYPE NOT NULL DEFAULT 'pseudo_cron', - "state" SMALLINT NOT NULL DEFAULT '0', - "last_exit_code" INT NOT NULL DEFAULT '0', - "last_execution" TIMESTAMP, - "next_execution" TIMESTAMP, - "times_executed" TIMESTAMP NOT NULL, - "times_failed" INT DEFAULT '0', - "note" TEXT DEFAULT '', - "created" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT '0000-00-00 00:00:00', - "created_by" BIGINT NOT NULL DEFAULT '0' - ); + "id" int GENERATED ALWAYS AS IDENTITY, + "asset_id" bigint NOT NULL DEFAULT '0', + "title" varchar(255) NOT NULL, + "type" job_type, + "execution_interval" interval NOT NULL, + "trigger" trigger_type NOT NULL DEFAULT 'pseudo_cron', + "state" smallint NOT NULL DEFAULT '0', + "last_exit_code" int NOT NULL DEFAULT '0', + "last_execution" timestamp without time zone, + "next_execution" timestamp without time zone, + "times_executed" int NOT NULL DEFAULT '0', + "times_failed" int DEFAULT '0', + "note" text DEFAULT '', + "created" timestamp without time zone NOT NULL, + "created_by" bigint NOT NULL DEFAULT '0' +); -- -------------------------------------------------------- @@ -53,10 +53,10 @@ CREATE TABLE IF NOT EXISTS "#__cronjobs" CREATE TABLE IF NOT EXISTS "#__cronjobs_scripts" ( - "id" INT GENERATED ALWAYS AS IDENTITY, - "job_id" INT, -- References "#__cronjobs"(id) - "directory" VARCHAR(256) NOT NULL, - "file" VARCHAR(128) NOT NULL - ); + "id" int GENERATED ALWAYS AS IDENTITY, + "job_id" int, -- References "#__cronjobs"(id) + "directory" varchar(256) NOT NULL, + "file" varchar(128) NOT NULL +); -- -------------------------------------------------------- diff --git a/installation/sql/postgresql/extensions.sql b/installation/sql/postgresql/extensions.sql index 3f84dcde8c5b6..794e75614a147 100644 --- a/installation/sql/postgresql/extensions.sql +++ b/installation/sql/postgresql/extensions.sql @@ -911,24 +911,24 @@ $$; -- -------------------------------------------------------- -- --- Create enumerated types for com_cronjobs +-- Create enumerated types for "#__cronjobs" -- DO $$ BEGIN - CREATE TYPE job_type AS ENUM ('script', 'plugin'); + CREATE TYPE job_type AS enum ('script', 'plugin'); EXCEPTION - WHEN duplicate_object THEN null; + WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN - CREATE TYPE trigger_type AS ENUM ('pseudo_cron', 'cron', 'visit_count'); + CREATE TYPE trigger_type AS enum ('pseudo_cron', 'cron', 'visit_count'); EXCEPTION - WHEN duplicate_object THEN null; + WHEN duplicate_object THEN NULL; END $$; @@ -940,21 +940,21 @@ $$; CREATE TABLE IF NOT EXISTS "#__cronjobs" ( - "id" INT GENERATED ALWAYS AS IDENTITY, - "asset_id" BIGINT NOT NULL DEFAULT '0', - "title" VARCHAR(255) NOT NULL, - "type" JOB_TYPE, - "execution_interval" INTERVAL NOT NULL, - "trigger" TRIGGER_TYPE NOT NULL DEFAULT 'pseudo_cron', - "state" SMALLINT NOT NULL DEFAULT '0', - "last_exit_code" INT NOT NULL DEFAULT '0', - "last_execution" TIMESTAMP, - "next_execution" TIMESTAMP, - "times_executed" TIMESTAMP NOT NULL, - "times_failed" INT DEFAULT '0', - "note" TEXT DEFAULT '', - "created" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT '0000-00-00 00:00:00', - "created_by" BIGINT NOT NULL DEFAULT '0' + "id" int GENERATED ALWAYS AS IDENTITY, + "asset_id" bigint NOT NULL DEFAULT '0', + "title" varchar(255) NOT NULL, + "type" job_type, + "execution_interval" interval NOT NULL, + "trigger" trigger_type NOT NULL DEFAULT 'pseudo_cron', + "state" smallint NOT NULL DEFAULT '0', + "last_exit_code" int NOT NULL DEFAULT '0', + "last_execution" timestamp without time zone, + "next_execution" timestamp without time zone, + "times_executed" int NOT NULL DEFAULT '0', + "times_failed" int DEFAULT '0', + "note" text DEFAULT '', + "created" timestamp without time zone NOT NULL, + "created_by" bigint NOT NULL DEFAULT '0' ); -- -------------------------------------------------------- @@ -965,10 +965,10 @@ CREATE TABLE IF NOT EXISTS "#__cronjobs" CREATE TABLE IF NOT EXISTS "#__cronjobs_scripts" ( - "id" INT GENERATED ALWAYS AS IDENTITY, - "job_id" INT, -- References "#__cronjobs"(id) - "directory" VARCHAR(256) NOT NULL, - "file" VARCHAR(128) NOT NULL + "id" int GENERATED ALWAYS AS IDENTITY, + "job_id" int, -- References "#__cronjobs"(id) + "directory" varchar(256) NOT NULL, + "file" varchar(128) NOT NULL ); -- -------------------------------------------------------- From 64ecdd77046c32cd6bc002d2de0f836e365da18d Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Sun, 18 Jul 2021 22:52:51 +0530 Subject: [PATCH 069/615] Fix asset tracking in CronjobTable - Adds the `_getAssetName()` method to override the parent method which defaulted to an asset name of #__cronjobs.${jobId}. This resulted in an unwanted extra entry in the #__assets table that was never referenced. Instead, a com_cronjobs.cronjob.${jobId} entry was created when updating asset permissions and referenced by com_cronjobs when checking for permissions. This entry should be created at cronjob creation now. --- .../com_cronjobs/src/Table/CronjobTable.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/administrator/components/com_cronjobs/src/Table/CronjobTable.php b/administrator/components/com_cronjobs/src/Table/CronjobTable.php index 712344a9cfec7..08cf95adedacf 100644 --- a/administrator/components/com_cronjobs/src/Table/CronjobTable.php +++ b/administrator/components/com_cronjobs/src/Table/CronjobTable.php @@ -140,4 +140,18 @@ public function store($updateNulls = false) : bool return parent::store($updateNulls); } + /** + * Declares the assetName for the entry as in the `#__assets` table + * + * @return string The asset name + * + * @since __DEPLOY_VERSION__ + */ + protected function _getAssetName(): string + { + $k = $this->_tbl_key; + + return 'com_cronjobs.cronjob.' . (int) $this->$k; + } + } From 7516a0652d263c97559d3e32d6298681dc3cf9b8 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Mon, 19 Jul 2021 16:27:39 +0530 Subject: [PATCH 070/615] Replace enums with strings for PostgreSQL tables Since enum types are not working (issue #6 in dev repo), this replaces them with strings until the issue is resolved. --- .../updates/postgresql/4.1.0-2021-07-17.sql | 28 ++----------------- installation/sql/postgresql/extensions.sql | 28 ++----------------- 2 files changed, 4 insertions(+), 52 deletions(-) diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-17.sql b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-17.sql index 1bc6bc91afda2..ac6d565e6967c 100644 --- a/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-17.sql +++ b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-17.sql @@ -1,27 +1,3 @@ --- --- Create enumerated types for "#__cronjobs" --- - -DO -$$ - BEGIN - CREATE TYPE job_type AS enum ('script', 'plugin'); - EXCEPTION - WHEN duplicate_object THEN NULL; - END -$$; - -DO -$$ - BEGIN - CREATE TYPE trigger_type AS enum ('pseudo_cron', 'cron', 'visit_count'); - EXCEPTION - WHEN duplicate_object THEN NULL; - END -$$; - --- -------------------------------------------------------- - -- -- Table structure for table "#__cronjobs" -- @@ -31,9 +7,9 @@ CREATE TABLE IF NOT EXISTS "#__cronjobs" "id" int GENERATED ALWAYS AS IDENTITY, "asset_id" bigint NOT NULL DEFAULT '0', "title" varchar(255) NOT NULL, - "type" job_type, + "type" varchar(6), "execution_interval" interval NOT NULL, - "trigger" trigger_type NOT NULL DEFAULT 'pseudo_cron', + "trigger" varchar(12) NOT NULL DEFAULT 'pseudo_cron', "state" smallint NOT NULL DEFAULT '0', "last_exit_code" int NOT NULL DEFAULT '0', "last_execution" timestamp without time zone, diff --git a/installation/sql/postgresql/extensions.sql b/installation/sql/postgresql/extensions.sql index 794e75614a147..9fc53bbfc4840 100644 --- a/installation/sql/postgresql/extensions.sql +++ b/installation/sql/postgresql/extensions.sql @@ -910,30 +910,6 @@ $$; -- -------------------------------------------------------- --- --- Create enumerated types for "#__cronjobs" --- - -DO -$$ - BEGIN - CREATE TYPE job_type AS enum ('script', 'plugin'); - EXCEPTION - WHEN duplicate_object THEN NULL; - END -$$; - -DO -$$ - BEGIN - CREATE TYPE trigger_type AS enum ('pseudo_cron', 'cron', 'visit_count'); - EXCEPTION - WHEN duplicate_object THEN NULL; - END -$$; - --- -------------------------------------------------------- - -- -- Table structure for table "#__cronjobs" -- @@ -943,9 +919,9 @@ CREATE TABLE IF NOT EXISTS "#__cronjobs" "id" int GENERATED ALWAYS AS IDENTITY, "asset_id" bigint NOT NULL DEFAULT '0', "title" varchar(255) NOT NULL, - "type" job_type, + "type" varchar(6), "execution_interval" interval NOT NULL, - "trigger" trigger_type NOT NULL DEFAULT 'pseudo_cron', + "trigger" varchar(12) NOT NULL DEFAULT 'pseudo_cron', "state" smallint NOT NULL DEFAULT '0', "last_exit_code" int NOT NULL DEFAULT '0', "last_execution" timestamp without time zone, From 661e6c37b2be5f2fef48350ee94989cf82ad1180 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Mon, 19 Jul 2021 18:00:20 +0530 Subject: [PATCH 071/615] Shift PostgreSQL DDL to before Soundex Not sure why, but DDL placed after soundex fails with the same error as in issue #6 in dev. Doing the same to b130fc2 yields a new error which #6 will be updated with. This commit state successfully installs with Postgre. --- installation/sql/postgresql/extensions.sql | 84 +++++++++++----------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/installation/sql/postgresql/extensions.sql b/installation/sql/postgresql/extensions.sql index 9fc53bbfc4840..62ddfa5c7c32e 100644 --- a/installation/sql/postgresql/extensions.sql +++ b/installation/sql/postgresql/extensions.sql @@ -846,6 +846,47 @@ CREATE TABLE "#__action_logs_users" ( CREATE INDEX "#__action_logs_users_idx_notify" ON "#__action_logs_users" ("notify"); +-- -------------------------------------------------------- + +-- +-- Table structure for table "#__cronjobs" +-- + +CREATE TABLE IF NOT EXISTS "#__cronjobs" +( + "id" int GENERATED ALWAYS AS IDENTITY, + "asset_id" bigint NOT NULL DEFAULT '0', + "title" varchar(255) NOT NULL, + "type" varchar(6), + "execution_interval" interval NOT NULL, + "trigger" varchar(12) NOT NULL DEFAULT 'pseudo_cron', + "state" smallint NOT NULL DEFAULT '0', + "last_exit_code" int NOT NULL DEFAULT '0', + "last_execution" timestamp without time zone, + "next_execution" timestamp without time zone, + "times_executed" int NOT NULL DEFAULT '0', + "times_failed" int DEFAULT '0', + "note" text DEFAULT '', + "created" timestamp without time zone NOT NULL, + "created_by" bigint NOT NULL DEFAULT '0' +); + +-- -------------------------------------------------------- + +-- +-- Table structure for table "#__cronjobs_scripts" +-- + +CREATE TABLE IF NOT EXISTS "#__cronjobs_scripts" +( + "id" int GENERATED ALWAYS AS IDENTITY, + "job_id" int, -- References "#__cronjobs"(id) + "directory" varchar(256) NOT NULL, + "file" varchar(128) NOT NULL +); + +-- -------------------------------------------------------- + -- -- Here is SOUNDEX replacement for those who can't enable fuzzystrmatch module -- from contrib folder. @@ -906,45 +947,4 @@ BEGIN RETURN soundex; END; -$$; - --- -------------------------------------------------------- - --- --- Table structure for table "#__cronjobs" --- - -CREATE TABLE IF NOT EXISTS "#__cronjobs" -( - "id" int GENERATED ALWAYS AS IDENTITY, - "asset_id" bigint NOT NULL DEFAULT '0', - "title" varchar(255) NOT NULL, - "type" varchar(6), - "execution_interval" interval NOT NULL, - "trigger" varchar(12) NOT NULL DEFAULT 'pseudo_cron', - "state" smallint NOT NULL DEFAULT '0', - "last_exit_code" int NOT NULL DEFAULT '0', - "last_execution" timestamp without time zone, - "next_execution" timestamp without time zone, - "times_executed" int NOT NULL DEFAULT '0', - "times_failed" int DEFAULT '0', - "note" text DEFAULT '', - "created" timestamp without time zone NOT NULL, - "created_by" bigint NOT NULL DEFAULT '0' -); - --- -------------------------------------------------------- - --- --- Table structure for table "#__cronjobs_scripts" --- - -CREATE TABLE IF NOT EXISTS "#__cronjobs_scripts" -( - "id" int GENERATED ALWAYS AS IDENTITY, - "job_id" int, -- References "#__cronjobs"(id) - "directory" varchar(256) NOT NULL, - "file" varchar(128) NOT NULL -); - --- -------------------------------------------------------- +$$; \ No newline at end of file From 9bd2b5e32a3f5b6962f446d0634ca8ca7fd309be Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Tue, 20 Jul 2021 14:20:36 +0530 Subject: [PATCH 072/615] Add SelectView modal layout template --- .../com_cronjobs/tmpl/select/modal.php | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 administrator/components/com_cronjobs/tmpl/select/modal.php diff --git a/administrator/components/com_cronjobs/tmpl/select/modal.php b/administrator/components/com_cronjobs/tmpl/select/modal.php new file mode 100644 index 0000000000000..f59725ac2a55f --- /dev/null +++ b/administrator/components/com_cronjobs/tmpl/select/modal.php @@ -0,0 +1,37 @@ + + * @license GPL v3 + * @codingStandardsIgnoreStart + */ + +// Restrict direct access +defined('_JEXEC') or die; + +use Joomla\Component\Cronjobs\Administrator\View\Select\HtmlView; + +/** @var HtmlView $this */ + +// Is this needed? +$this->modalLink = '&tmpl=component&view=select&layout=modal'; + +// Wrap the default layout in a div.container-popup +?> +
+ setLayout('default'); ?> + + loadTemplate(); + } + catch (Exception $e) + { + die('Exception while loading template..'); + } + ?> +
From e657be54d4a4589aa135d67c5194c98cd286b263 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Tue, 20 Jul 2021 14:33:10 +0530 Subject: [PATCH 073/615] Revert changes to drone - Reverts changes made in ed767bd to unblock the testing pipeline. --- .drone.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.drone.yml b/.drone.yml index 03543638d6790..bf2cacaf38389 100644 --- a/.drone.yml +++ b/.drone.yml @@ -247,12 +247,12 @@ steps: from_secret: ftpusername FTP_PASSWORD: from_secret: ftppassword - FTP_HOSTNAME: ftp.artifacts.joomla.org + FTP_HOSTNAME: ci.joomla.org FTP_PORT: "21" - FTP_DEST_DIR: / + FTP_DEST_DIR: /artifacts FTP_VERIFY: "false" FTP_SECURE: "true" - HTTP_ROOT: "https://artifacts.joomla.org/drone" + HTTP_ROOT: "https://ci.joomla.org/artifacts" DRONE_PULL_REQUEST: DRONE_PULL_REQUEST DRONE_COMMIT: DRONE_COMMIT GITHUB_TOKEN: From 3010db73be965bab1b5fa48a08ef63319424ebe9 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Wed, 21 Jul 2021 01:10:52 +0530 Subject: [PATCH 074/615] Update SelectView template Changes the parameter for passing plugin jod id --- .../components/com_cronjobs/tmpl/select/default.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/administrator/components/com_cronjobs/tmpl/select/default.php b/administrator/components/com_cronjobs/tmpl/select/default.php index b65752fcd499c..b059325055d9d 100644 --- a/administrator/components/com_cronjobs/tmpl/select/default.php +++ b/administrator/components/com_cronjobs/tmpl/select/default.php @@ -26,7 +26,6 @@ // ! : This is going down into loading the select-modal script, what does that do? // $function = $app->getInput()->get('function'); -// TODO : Cronjob search script $wa = $this->document->getWebAssetManager(); $wa->useStyle('com_cronjobs.admin-plg-job-css'); $wa->useScript('com_cronjobs.admin-plg-job-search'); @@ -37,7 +36,7 @@ * endif;*/ ?> - +
@@ -96,7 +95,7 @@ class="new-job mb-3" items as &$item) : ?> - id; ?> + id; ?> escape($item->title); ?> escape(strip_tags($item->desc)), 200); ?> From 45be99ddc5c125d3b1307156c7e1ac0295e8645f Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Wed, 21 Jul 2021 01:23:50 +0530 Subject: [PATCH 075/615] Update CronjobView form XML, language files - Adds a new `plg_job_id` field - Disables the `type` field, since it will be set through SelectView - Replaces some labels with language constants --- .../components/com_cronjobs/forms/cronjob.xml | 12 +++++++++++- administrator/language/en-GB/com_cronjobs.ini | 4 ++++ administrator/language/en-GB/com_cronjobs.sys.ini | 4 ++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/administrator/components/com_cronjobs/forms/cronjob.xml b/administrator/components/com_cronjobs/forms/cronjob.xml index 1dc5a5aa3a5e1..8361b19a7f25a 100644 --- a/administrator/components/com_cronjobs/forms/cronjob.xml +++ b/administrator/components/com_cronjobs/forms/cronjob.xml @@ -13,7 +13,9 @@ + @@ -30,8 +32,16 @@
+ +
+ + +
+ -
+
Date: Wed, 21 Jul 2021 01:47:30 +0530 Subject: [PATCH 076/615] Partly integrate CronjobView with SelectView - Retain params passed by SelectView in CronjobModel state - Set job type based on SelectView option, manual selection is disabled - Fix CronjobView default tab - Keep the Application object as a model property - Get rid of getInput() calls in CronjobModel except in populateState() - Clean up and update comments --- .../src/Controller/CronjobController.php | 42 +++++++- .../com_cronjobs/src/Model/CronjobModel.php | 99 ++++++++++++++----- .../src/View/Cronjob/HtmlView.php | 3 +- .../com_cronjobs/tmpl/cronjob/edit.php | 2 +- 4 files changed, 115 insertions(+), 31 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Controller/CronjobController.php b/administrator/components/com_cronjobs/src/Controller/CronjobController.php index b4761bbd3aeda..fadc0d927655f 100644 --- a/administrator/components/com_cronjobs/src/Controller/CronjobController.php +++ b/administrator/components/com_cronjobs/src/Controller/CronjobController.php @@ -16,9 +16,14 @@ namespace Joomla\Component\Cronjobs\Administrator\Controller; // Restrict direct access -\defined('_JEXEC') or die; +defined('_JEXEC') or die; +use Joomla\CMS\Application\CMSApplication; +use Joomla\CMS\Language\Text; use Joomla\CMS\MVC\Controller\FormController; +use Joomla\CMS\Router\Route; +use function defined; +use function in_array; /** * The CronjobModel controller. @@ -39,8 +44,39 @@ class CronjobController extends FormController */ public function add(): bool { - // TODO: Change the autogenerated stub - return parent::add(); + /**@var CMSApplication $app */ + $app = $this->app; + $input = $app->getInput(); + $validTypes = ['script', 'plugin']; + + $result = parent::add(); + + if ($result !== true) + { + return false; + } + + $jobType = $input->get('type'); + + // ! Change plg_job param to 'jid' in SelectView + $pluginJobId = $input->get('jid'); + + if (!in_array($jobType, $validTypes)) + { + // ? : Is this the right redirect + $redirectUrl = 'index.php?option=' . $this->option . '&view' . $this->view_item . '&layout=edit'; + $this->setRedirect(Route::_($redirectUrl, false)); + $app->enqueueMessage(Text::_('COM_CRONJOBS_ERROR_INVALID_JOB_TYPE'), 'warning'); + + return false; + } + + $app->setUserState('com_cronjobs.add.cronjob.cronjob_type', $jobType); + $app->setUserState('com_cronjobs.add.cronjob.plg_job_id', $pluginJobId); + + // TODO : Parameter array handling below? + + return true; } /** diff --git a/administrator/components/com_cronjobs/src/Model/CronjobModel.php b/administrator/components/com_cronjobs/src/Model/CronjobModel.php index 2a005db7805b2..e717863bdb055 100644 --- a/administrator/components/com_cronjobs/src/Model/CronjobModel.php +++ b/administrator/components/com_cronjobs/src/Model/CronjobModel.php @@ -12,13 +12,18 @@ namespace Joomla\Component\Cronjobs\Administrator\Model; // Restrict direct access -\defined('_JEXEC') or die; +defined('_JEXEC') or die; use Exception; +use Joomla\CMS\Application\AdministratorApplication; +use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Form\Form; +use Joomla\CMS\Form\FormFactoryInterface; +use Joomla\CMS\MVC\Factory\MVCFactoryInterface; use Joomla\CMS\MVC\Model\AdminModel; use Joomla\CMS\Factory; use Joomla\CMS\Table\Table; +use function defined; /** * MVC Model to interact with the Cronjobs DB. @@ -41,17 +46,45 @@ class CronjobModel extends AdminModel ); /** + * Prefix used with controller messages + * * @var string * @since __DEPLOY_VERSION__ */ protected $text_prefix = 'COM_CRONJOBS'; /** + * Type alias for content type + * * @var string * @since __DEPLOY_VERSION__ */ public $typeAlias = 'com_cronjobs.cronjob'; + /** + * The Application object, for convenience + * + * @var AdministratorApplication $app + * @since __DEPLOY_VERSION__ + */ + protected $app; + + + /** + * CronjobModel constructor. Needed just to set $app + * + * @param array $config An array of configuration options + * @param MVCFactoryInterface|null $factory The factory [?] + * @param FormFactoryInterface|null $formFactory The form factory [?] + * + * @throws Exception + * @since __DEPLOY_VERSION__ + */ + public function __construct($config = array(), MVCFactoryInterface $factory = null, FormFactoryInterface $formFactory = null) + { + $this->app = Factory::getApplication(); + parent::__construct($config, $factory, $formFactory); + } /** * Fetches the form object associated with this model. By default, @@ -67,7 +100,6 @@ class CronjobModel extends AdminModel */ public function getForm($data = array(), $loadData = true) { - $input = Factory::getApplication()->getInput(); // TODO : Can we need any custom fields [?] Form::addFieldPath(JPATH_ADMINISTRATOR . 'components/com_cronjobs/src/Field'); @@ -84,14 +116,18 @@ public function getForm($data = array(), $loadData = true) return false; } - $user = Factory::getApplication()->getIdentity(); + $user = $this->app->getIdentity(); + + // If new entry, set type (and plg_job, if applicable) + if ($this->getState('cronjob.id', 0) === 0 && $this->getState('cronjob.type') !== null) + { + $form->setValue('type', null, $this->getState('cronjob.type')); + } /* - * TODO : Check if this works as expected - * ? : Is this the right way to check permissions? (In particular, the assetName) - * ? : Are we guaranteed a $data['id'], does this work OK if it's null? A : [NO, IT IS NOT GUARANTEED] + * TODO : Check if this is working as expected (what about new items, id == 0 ?) */ - if (!$user->authorise('core.edit.state', 'com_cronjobs.cronjob.' . $input->get('id'))) + if (!$user->authorise('core.edit.state', 'com_cronjobs.cronjob.' . $this->getState('job.id'))) { // Disable fields $form->setFieldAttribute('state', 'disabled', 'true'); @@ -123,14 +159,11 @@ protected function canDelete($record): bool } // TODO : Check if this is the right way to check authority (in particular the assetName) - return Factory::getApplication()->getIdentity()->authorise('core.delete', 'com.cronjobs.cronjob.' . $record->id); + return $this->app->getIdentity()->authorise('core.delete', 'com.cronjobs.cronjob.' . $record->id); } /** - * Populate the model state based on user input. - * ? : Do we need this? - * The parent method already sets the primary key - * for the Table object, which might be all we need here. + * Populate the model state, we use these instead of toying with input or the global state * * @return void * @@ -139,7 +172,23 @@ protected function canDelete($record): bool */ protected function populateState(): void { - parent::populateState(); + $app = $this->app; + + $jobId = $app->getInput()->getInt('id'); + $jobType = $app->getUserState('com_cronjobs.add.cronjob.cronjob_type'); + $pluginJobId = $app->getUserState('com_cronjobs.add.cronjob.plg_job_id'); + + $this->setState('cronjob.id', $jobId); + $this->setState('cronjob.type', $jobType); + + if ($pluginJobId !== null) + { + $this->setState('job.plg_job_id', $pluginJobId); + } + + // Load component params, though com_cronjobs does not (yet) have any params + $cParams = ComponentHelper::getParams($this->option); + $this->setState('params', $cParams); } /** @@ -147,6 +196,7 @@ protected function populateState(): void * implicitly deduces $name and $prefix anyways. This does make the object * more transparent though. * + * * @param string $name Name of the table * @param string $prefix Class prefix * @param array $options Model config array @@ -175,27 +225,26 @@ protected function loadFormData() * Check session for previously entered form data * ? : How and where does this data get saved? * - * ! : getUserState() makes the IDE scream "Potentially Polymorphic Call" - * because ConsoleApplication and StubGenerator don't implement the method. - * While we'll never call loadFormData() from those, it looks ugly as it is. - * Is there any way to get rid of it? */ - $app = Factory::getApplication(); - $data = $app->getUserState('com_cronjobs.edit.cronjob.data', array()); + $data = $this->app->getUserState('com_cronjobs.edit.cronjob.data', array()); - // If the UserState didn't have form data, we fetch it with getItem() + // If the data from UserState is empty, we fetch it with getItem() if (empty($data)) { $data = $this->getItem(); - // TODO : Do we need any _priming_ on the $data here? $time = explode(':', $data->get('execution_interval')); $data->set('interval-hours', $time[0] ?? 0); $data->set('interval-minutes', $time[1] ?? 0); + + // TODO : Any further data processing goes here } - // ? What would this do here? Is it needed or (just) good practice? - $this->preprocessData('com_cronjobs.cronjob', $data); + /* + * Let plugins manipulate the form (add fields) + * ? Using the 'job' group (as SelectModel), or should we target the 'cronjob' group? + */ + $this->preprocessData('com_cronjobs.cronjob', $data, 'job'); return $data; } @@ -209,7 +258,7 @@ protected function loadFormData() * * @param integer $pk Primary key * - * @return object|boolean Object on success, false on failure + * @return object|boolean Object on success, false on failure * * @since __DEPLOY_VERSION__ */ @@ -222,7 +271,7 @@ public function getItem($pk = null) /** * @param array $data The form data * - * @return boolean True on success, false on failure + * @return boolean True on success, false on failure * * @since __DEPLOY_VERSION__ */ diff --git a/administrator/components/com_cronjobs/src/View/Cronjob/HtmlView.php b/administrator/components/com_cronjobs/src/View/Cronjob/HtmlView.php index 534accf7b810e..a3459230d89d1 100644 --- a/administrator/components/com_cronjobs/src/View/Cronjob/HtmlView.php +++ b/administrator/components/com_cronjobs/src/View/Cronjob/HtmlView.php @@ -76,12 +76,11 @@ class HtmlView extends BaseHtmlView public function display($tpl = null): void { /* - * Will call the getForm() method of cronjobModel + * Will call the getForm() method of CronjobModel */ $this->form = $this->get('Form'); $this->item = $this->get('Item'); - // ? : Where is getState() implemented? [✔] (StateBehaviourTrait) $this->state = $this->get('State'); $this->canDo = ContentHelper::getActions('com_cronjobs', 'cronjob', $this->item->id); diff --git a/administrator/components/com_cronjobs/tmpl/cronjob/edit.php b/administrator/components/com_cronjobs/tmpl/cronjob/edit.php index b71792ba7828a..f412236946e90 100644 --- a/administrator/components/com_cronjobs/tmpl/cronjob/edit.php +++ b/administrator/components/com_cronjobs/tmpl/cronjob/edit.php @@ -58,7 +58,7 @@ class="form-validate">
- 'details')); ?> + 'general')); ?> Date: Wed, 21 Jul 2021 18:58:29 +0530 Subject: [PATCH 077/615] Apply suggested changes to MySQL Scripts Changes suggested by @richard67: - Removes default values for the `created` column Co-authored-by: Richard Fath --- .../components/com_admin/sql/updates/mysql/4.1.0-2021-07-17.sql | 2 +- installation/sql/mysql/extensions.sql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-17.sql b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-17.sql index ad324e9046fdc..f500dadf2b6ea 100644 --- a/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-17.sql +++ b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-17.sql @@ -18,7 +18,7 @@ CREATE TABLE IF NOT EXISTS `#__cronjobs` ( `times_executed` int DEFAULT '0' COMMENT 'Count of successful triggers', `times_failed` int DEFAULT '0' COMMENT 'Count of failures', `note` text, - `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `created` datetime NOT NULL, `created_by` int UNSIGNED NOT NULL DEFAULT '0', PRIMARY KEY (id) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 DEFAULT COLLATE = utf8mb4_unicode_ci; diff --git a/installation/sql/mysql/extensions.sql b/installation/sql/mysql/extensions.sql index 00f08c56411a4..79efcb5548b6b 100644 --- a/installation/sql/mysql/extensions.sql +++ b/installation/sql/mysql/extensions.sql @@ -905,7 +905,7 @@ CREATE TABLE IF NOT EXISTS `#__cronjobs` ( `times_executed` int DEFAULT '0' COMMENT 'Count of successful triggers', `times_failed` int DEFAULT '0' COMMENT 'Count of failures', `note` text, - `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `created` datetime NOT NULL, `created_by` int UNSIGNED NOT NULL DEFAULT '0', PRIMARY KEY (id) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 DEFAULT COLLATE = utf8mb4_unicode_ci; From e446062ae28fd92338591d5a0f699f611fe5a9a4 Mon Sep 17 00:00:00 2001 From: dst27 <72784348+dst27@users.noreply.github.com> Date: Wed, 21 Jul 2021 22:35:47 +0530 Subject: [PATCH 078/615] Update database tables - Drops the `#__cronjobs_scripts` table - Adds the `params` column to `#__cronjobs` - Modifies the `type` column in `#__cronjobs` to varchar(1024) - The `type` column is now supposed to hold the plg_job_id --- .../sql/updates/mysql/4.1.0-2021-07-21.sql | 4 ++++ .../updates/postgresql/4.1.0-2021-07-21.sql | 5 +++++ installation/sql/mysql/extensions.sql | 17 ++--------------- installation/sql/postgresql/extensions.sql | 19 +++---------------- 4 files changed, 14 insertions(+), 31 deletions(-) create mode 100644 administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-21.sql create mode 100644 administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-21.sql diff --git a/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-21.sql b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-21.sql new file mode 100644 index 0000000000000..76c3053f42366 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-21.sql @@ -0,0 +1,4 @@ +DROP TABLE IF EXISTS `#__cronjobs_scripts`; +ALTER TABLE `#__cronjobs` + MODIFY COLUMN `type` varchar(1024) NOT NULL COMMENT 'unique identifier for job defined by plugin', + ADD COLUMN `params` text NOT NULL AFTER `times_failed`; diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-21.sql b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-21.sql new file mode 100644 index 0000000000000..d562a2fd07a95 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-21.sql @@ -0,0 +1,5 @@ +DROP TABLE IF EXISTS "#__cronjobs_scripts"; +ALTER TABLE "#__cronjobs" + ALTER COLUMN "type" TYPE varchar(1024), + ALTER COLUMN "type" SET NOT NULL, + ADD COLUMN "params" text NOT NULL; diff --git a/installation/sql/mysql/extensions.sql b/installation/sql/mysql/extensions.sql index 79efcb5548b6b..7022e87d98a0c 100644 --- a/installation/sql/mysql/extensions.sql +++ b/installation/sql/mysql/extensions.sql @@ -894,7 +894,7 @@ CREATE TABLE IF NOT EXISTS `#__cronjobs` ( `asset_id` int NOT NULL UNIQUE DEFAULT '0', `title` varchar(128) NOT NULL UNIQUE, -- Job type. Can execute a script or plugin routine - `type` enum ('script', 'plugin') NOT NULL DEFAULT 'script', + `type` varchar(1024) NOT NULL COMMENT 'unique identifier for job defined by plugin', -- Trigger type, default to PseudoCron (compatible everywhere). `trigger` enum ('pseudo_cron', 'cron', 'visit_count') NOT NULL DEFAULT 'pseudo_cron' COMMENT 'Defines how job is triggered', `execution_interval` time NOT NULL COMMENT 'Configured time between executions,in HH:MM:SS format', @@ -904,6 +904,7 @@ CREATE TABLE IF NOT EXISTS `#__cronjobs` ( `next_execution` datetime COMMENT 'Timestamp of next (planned) run, referred for execution on trigger', `times_executed` int DEFAULT '0' COMMENT 'Count of successful triggers', `times_failed` int DEFAULT '0' COMMENT 'Count of failures', + `params` text NOT NULL, `note` text, `created` datetime NOT NULL, `created_by` int UNSIGNED NOT NULL DEFAULT '0', @@ -911,17 +912,3 @@ CREATE TABLE IF NOT EXISTS `#__cronjobs` ( ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 DEFAULT COLLATE = utf8mb4_unicode_ci; -- -------------------------------------------------------- - --- --- Table structure for table `#__cronjobs_scripts` --- - -CREATE TABLE IF NOT EXISTS `#__cronjobs_scripts` ( - `id` int NOT NULL AUTO_INCREMENT, - `job_id` int NOT NULL COMMENT 'Cronjob ID', -- References `#__cronjobs`(id) - `directory` varchar(1024) NOT NULL, - `file` varchar(256) NOT NULL, - PRIMARY KEY (id) -) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 DEFAULT COLLATE = utf8mb4_unicode_ci; - --- -------------------------------------------------------- diff --git a/installation/sql/postgresql/extensions.sql b/installation/sql/postgresql/extensions.sql index 62ddfa5c7c32e..3acf6d8c1c61a 100644 --- a/installation/sql/postgresql/extensions.sql +++ b/installation/sql/postgresql/extensions.sql @@ -857,7 +857,7 @@ CREATE TABLE IF NOT EXISTS "#__cronjobs" "id" int GENERATED ALWAYS AS IDENTITY, "asset_id" bigint NOT NULL DEFAULT '0', "title" varchar(255) NOT NULL, - "type" varchar(6), + "type" varchar(1024) NOT NULL, "execution_interval" interval NOT NULL, "trigger" varchar(12) NOT NULL DEFAULT 'pseudo_cron', "state" smallint NOT NULL DEFAULT '0', @@ -866,6 +866,7 @@ CREATE TABLE IF NOT EXISTS "#__cronjobs" "next_execution" timestamp without time zone, "times_executed" int NOT NULL DEFAULT '0', "times_failed" int DEFAULT '0', + "params" text NOT NULL, "note" text DEFAULT '', "created" timestamp without time zone NOT NULL, "created_by" bigint NOT NULL DEFAULT '0' @@ -873,20 +874,6 @@ CREATE TABLE IF NOT EXISTS "#__cronjobs" -- -------------------------------------------------------- --- --- Table structure for table "#__cronjobs_scripts" --- - -CREATE TABLE IF NOT EXISTS "#__cronjobs_scripts" -( - "id" int GENERATED ALWAYS AS IDENTITY, - "job_id" int, -- References "#__cronjobs"(id) - "directory" varchar(256) NOT NULL, - "file" varchar(128) NOT NULL -); - --- -------------------------------------------------------- - -- -- Here is SOUNDEX replacement for those who can't enable fuzzystrmatch module -- from contrib folder. @@ -947,4 +934,4 @@ BEGIN RETURN soundex; END; -$$; \ No newline at end of file +$$; From 1ffdccb9b86a7a38c4fb52e68175488061b5fa9d Mon Sep 17 00:00:00 2001 From: ditsuke Date: Thu, 22 Jul 2021 13:52:20 +0530 Subject: [PATCH 079/615] Add CronjobsHelper class, remove duplication This class was needed to contain code which may be used by multiple parts of the component. Since the option fetching code will also be needed by CronjobModel: - Implements the getCronOptions() method in CronjobsHelper - Removes duplicated code from SelectModel --- .../src/Helper/CronjobsHelper.php | 68 +++++++++++++++++++ .../com_cronjobs/src/Model/SelectModel.php | 21 ++---- 2 files changed, 73 insertions(+), 16 deletions(-) create mode 100644 administrator/components/com_cronjobs/src/Helper/CronjobsHelper.php diff --git a/administrator/components/com_cronjobs/src/Helper/CronjobsHelper.php b/administrator/components/com_cronjobs/src/Helper/CronjobsHelper.php new file mode 100644 index 0000000000000..c57d697d642ca --- /dev/null +++ b/administrator/components/com_cronjobs/src/Helper/CronjobsHelper.php @@ -0,0 +1,68 @@ + + * @license GPL v3 + * + */ + +namespace Joomla\Component\Cronjobs\Administrator\Helper; + +// Restrict direct access +defined('_JEXEC') or die; + +use Exception; +use Joomla\CMS\Application\AdministratorApplication; +use Joomla\CMS\Event\AbstractEvent; +use Joomla\CMS\Factory; +use Joomla\CMS\Plugin\PluginHelper; +use Joomla\Component\Cronjobs\Administrator\Cronjobs\CronOptions; +use function \defined; + +/** + * The CronjobsHelper class. + * Provides static methods used across com_cronjobs + * + * @since __DEPLOY_VERSION__ + */ +class CronjobsHelper +{ + /** + * Private constructor to prevent instantiation + * + * @since __DEPLOY_VERSION__ + */ + private function __construct() + { + } + + /** + * Returns available jobs as a CronOptions object + * + * @return CronOptions A CronOptions object populated with jobs offered by plugins + * @throws Exception + * @since __DEPLOY_VERSION__ + */ + public static function getCronOptions() : CronOptions + { + /**@var AdministratorApplication $app */ + $app = Factory::getApplication(); + $options = new CronOptions; + $event = AbstractEvent::create( + 'onCronOptionsList', + [ + 'subject' => $options + ] + ); + + // TODO : Implement an object for $items + PluginHelper::importPlugin('job'); + $app->getDispatcher()->dispatch('onCronOptionsList', $event); + + return $options; + } +} diff --git a/administrator/components/com_cronjobs/src/Model/SelectModel.php b/administrator/components/com_cronjobs/src/Model/SelectModel.php index 38e2e785be506..e5857e9a53260 100644 --- a/administrator/components/com_cronjobs/src/Model/SelectModel.php +++ b/administrator/components/com_cronjobs/src/Model/SelectModel.php @@ -16,13 +16,11 @@ use Exception; use Joomla\CMS\Application\CMSApplication; -use Joomla\CMS\Event\AbstractEvent; use Joomla\CMS\Factory; use Joomla\CMS\MVC\Factory\MVCFactoryInterface; use Joomla\CMS\MVC\Model\ListModel; -use Joomla\CMS\Plugin\PluginHelper; -use Joomla\Component\Cronjobs\Administrator\Cronjobs\CronOptions; use Joomla\Component\Cronjobs\Administrator\Cronjobs\CronOption; +use Joomla\Component\Cronjobs\Administrator\Helper\CronjobsHelper; use function defined; /** @@ -33,6 +31,8 @@ class SelectModel extends ListModel { /** + * The Application object. Due removal. + * * @var CMSApplication * @since __DEPLOY_VERSION__ */ @@ -58,22 +58,11 @@ public function __construct($config = array(), ?MVCFactoryInterface $factory = n * * @return CronOption[] An array of CronOption objects * + * @throws Exception * @since __DEPLOY_VERSION__ */ public function getItems(): array { - $options = new CronOptions; - $event = AbstractEvent::create( - 'onCronOptionsList', - [ - 'subject' => $options - ] - ); - - // TODO : Implement an object for $items - PluginHelper::importPlugin('job'); - $this->app->getDispatcher()->dispatch('onCronOptionsList', $event); - - return $options->jobs; + return CronjobsHelper::getCronOptions()->jobs; } } From 1637eeede692c2833f5ea3ea2420d2233dc2fef0 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Thu, 22 Jul 2021 16:24:28 +0530 Subject: [PATCH 080/615] Add findOption() to CronOptions class - Adds CronOptions::findOption() to: - Fetch details for a job type, - And validate job type on submission and form display - Also makes a minor property name change in the CronOption class --- .../com_cronjobs/src/Cronjobs/CronOption.php | 8 ++++---- .../com_cronjobs/src/Cronjobs/CronOptions.php | 20 +++++++++++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Cronjobs/CronOption.php b/administrator/components/com_cronjobs/src/Cronjobs/CronOption.php index 3dc4e430920a0..c4d68fde8f539 100644 --- a/administrator/components/com_cronjobs/src/Cronjobs/CronOption.php +++ b/administrator/components/com_cronjobs/src/Cronjobs/CronOption.php @@ -42,19 +42,19 @@ class CronOption * @var string * @since __DEPLOY_VERSION__ */ - public $id; + public $type; /** * CronOption constructor. * - * @param string $id A unique string for the job routine used internally by the job plugin. + * @param string $type A unique string for the job routine used internally by the job plugin. * @param string $langConstPrefix The Language constant prefix $p. Expects $p . _TITLE and $p . _DESC to exist. * * @since __DEPLOY_VERSION__ */ - public function __construct(string $id, string $langConstPrefix) + public function __construct(string $type, string $langConstPrefix) { - $this->id = $id; + $this->type = $type; $this->title = Text::_("${langConstPrefix}_TITLE"); $this->desc = Text::_("${langConstPrefix}_DESC"); } diff --git a/administrator/components/com_cronjobs/src/Cronjobs/CronOptions.php b/administrator/components/com_cronjobs/src/Cronjobs/CronOptions.php index de4937cde6674..8eb374653a056 100644 --- a/administrator/components/com_cronjobs/src/Cronjobs/CronOptions.php +++ b/administrator/components/com_cronjobs/src/Cronjobs/CronOptions.php @@ -53,4 +53,24 @@ public function addOptions(array $jobsArray): void $this->jobs[] = new CronOption($jobId, $langConstPrefix); } } + + /** + * @param string $jobType A unique identifier for the job routine offered by a plugin + * + * @return CronOption|false A matching CronOption if available, false otherwise + * + * @since __DEPLOY_VERSION__ + */ + public function findOptions(string $jobType) + { + foreach ($this->jobs as $job) + { + if ($job->type === $jobType) + { + return $job; + } + } + + return false; + } } From 56163372e1560c3332b8f6a51090291df1ab238c Mon Sep 17 00:00:00 2001 From: ditsuke Date: Thu, 22 Jul 2021 18:36:36 +0530 Subject: [PATCH 081/615] Update CronjobView XML, other minor changes - Updates the CronjobView XML for the recent changes in the DB - Fix typo in CronOptions's findOption() method - Minor style fix in CronjobsHelper::getCronOptions() declaration --- .../components/com_cronjobs/forms/cronjob.xml | 29 +++++-------------- .../com_cronjobs/src/Cronjobs/CronOptions.php | 2 +- .../src/Helper/CronjobsHelper.php | 2 +- 3 files changed, 10 insertions(+), 23 deletions(-) diff --git a/administrator/components/com_cronjobs/forms/cronjob.xml b/administrator/components/com_cronjobs/forms/cronjob.xml index 8361b19a7f25a..101eb56d2b8c7 100644 --- a/administrator/components/com_cronjobs/forms/cronjob.xml +++ b/administrator/components/com_cronjobs/forms/cronjob.xml @@ -10,19 +10,14 @@ />
- - - - - - - - - - + + + + + @@ -32,14 +27,6 @@
- -
- - -
-
diff --git a/administrator/components/com_cronjobs/src/Cronjobs/CronOptions.php b/administrator/components/com_cronjobs/src/Cronjobs/CronOptions.php index 8eb374653a056..5eb6db00fb03a 100644 --- a/administrator/components/com_cronjobs/src/Cronjobs/CronOptions.php +++ b/administrator/components/com_cronjobs/src/Cronjobs/CronOptions.php @@ -61,7 +61,7 @@ public function addOptions(array $jobsArray): void * * @since __DEPLOY_VERSION__ */ - public function findOptions(string $jobType) + public function findOption(string $jobType) { foreach ($this->jobs as $job) { diff --git a/administrator/components/com_cronjobs/src/Helper/CronjobsHelper.php b/administrator/components/com_cronjobs/src/Helper/CronjobsHelper.php index c57d697d642ca..a716701f8e73e 100644 --- a/administrator/components/com_cronjobs/src/Helper/CronjobsHelper.php +++ b/administrator/components/com_cronjobs/src/Helper/CronjobsHelper.php @@ -47,7 +47,7 @@ private function __construct() * @throws Exception * @since __DEPLOY_VERSION__ */ - public static function getCronOptions() : CronOptions + public static function getCronOptions(): CronOptions { /**@var AdministratorApplication $app */ $app = Factory::getApplication(); From 30d87b70e9ff20c3e02c7d317b2626988f76b4be Mon Sep 17 00:00:00 2001 From: ditsuke Date: Thu, 22 Jul 2021 18:43:40 +0530 Subject: [PATCH 082/615] Update type validation in CronjobController - Updates validation to use CronOptions::findOption() - Changes invalid type redirect to the SelectView - CronjobController now sets state variable for valid CronOption - Updates SelectView template to pass the right params - Updates language files for changes in CronjobView form --- .../src/Controller/CronjobController.php | 22 ++++++++----------- .../com_cronjobs/tmpl/select/default.php | 3 ++- administrator/language/en-GB/com_cronjobs.ini | 2 +- .../language/en-GB/com_cronjobs.sys.ini | 2 +- 4 files changed, 13 insertions(+), 16 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Controller/CronjobController.php b/administrator/components/com_cronjobs/src/Controller/CronjobController.php index fadc0d927655f..2a1e0f7dad7ff 100644 --- a/administrator/components/com_cronjobs/src/Controller/CronjobController.php +++ b/administrator/components/com_cronjobs/src/Controller/CronjobController.php @@ -18,12 +18,13 @@ // Restrict direct access defined('_JEXEC') or die; +use Exception; use Joomla\CMS\Application\CMSApplication; use Joomla\CMS\Language\Text; use Joomla\CMS\MVC\Controller\FormController; use Joomla\CMS\Router\Route; +use Joomla\Component\Cronjobs\Administrator\Helper\CronjobsHelper; use function defined; -use function in_array; /** * The CronjobModel controller. @@ -35,11 +36,8 @@ class CronjobController extends FormController /** * Add a new record * - * ! : Just acting as a proxy to the parent method at the moment - * Due removal if no additional handling needed here ⚠ - * * @return boolean - * + * @throws Exception * @since __DEPLOY_VERSION__ */ public function add(): bool @@ -47,7 +45,7 @@ public function add(): bool /**@var CMSApplication $app */ $app = $this->app; $input = $app->getInput(); - $validTypes = ['script', 'plugin']; + $validJobOptions = CronjobsHelper::getCronOptions(); $result = parent::add(); @@ -57,14 +55,12 @@ public function add(): bool } $jobType = $input->get('type'); + $jobOption = $validJobOptions->findOption($jobType); - // ! Change plg_job param to 'jid' in SelectView - $pluginJobId = $input->get('jid'); - - if (!in_array($jobType, $validTypes)) + if (!$jobOption) { - // ? : Is this the right redirect - $redirectUrl = 'index.php?option=' . $this->option . '&view' . $this->view_item . '&layout=edit'; + // ? : Is this the right redirect [review] + $redirectUrl = 'index.php?option=' . $this->option . '&view=select&layout=edit'; $this->setRedirect(Route::_($redirectUrl, false)); $app->enqueueMessage(Text::_('COM_CRONJOBS_ERROR_INVALID_JOB_TYPE'), 'warning'); @@ -72,7 +68,7 @@ public function add(): bool } $app->setUserState('com_cronjobs.add.cronjob.cronjob_type', $jobType); - $app->setUserState('com_cronjobs.add.cronjob.plg_job_id', $pluginJobId); + $app->setUserState('com_cronjobs.add.cronjob.cronjob_option', $jobOption); // TODO : Parameter array handling below? diff --git a/administrator/components/com_cronjobs/tmpl/select/default.php b/administrator/components/com_cronjobs/tmpl/select/default.php index b059325055d9d..1222f941d711b 100644 --- a/administrator/components/com_cronjobs/tmpl/select/default.php +++ b/administrator/components/com_cronjobs/tmpl/select/default.php @@ -70,6 +70,7 @@ class="visually-hidden"> +
items as &$item) : ?> - id; ?> + type; ?> escape($item->title); ?> escape(strip_tags($item->desc)), 200); ?> diff --git a/administrator/language/en-GB/com_cronjobs.ini b/administrator/language/en-GB/com_cronjobs.ini index 5236f6ecb37c2..0142cd65b9f15 100644 --- a/administrator/language/en-GB/com_cronjobs.ini +++ b/administrator/language/en-GB/com_cronjobs.ini @@ -45,4 +45,4 @@ COM_CRONJOBS_SELECT_CLI_JOB="Select CLI job" COM_CRONJOBS_ERROR_INVALID_JOB_TYPE="Invalid Job Type!" COM_CRONJOBS_LABEL_EXEC_INTERVAL="Execution Interval" COM_CRONJOBS_LABEL_PLG_JOB_ID="Plugin Job ID" -COM_CRONJOBS_SELECT_JOB_TYPE="Select Job Type" +COM_CRONJOBS_FIELD_JOB_TYPE="Job Type (identifier)" diff --git a/administrator/language/en-GB/com_cronjobs.sys.ini b/administrator/language/en-GB/com_cronjobs.sys.ini index 5236f6ecb37c2..0142cd65b9f15 100644 --- a/administrator/language/en-GB/com_cronjobs.sys.ini +++ b/administrator/language/en-GB/com_cronjobs.sys.ini @@ -45,4 +45,4 @@ COM_CRONJOBS_SELECT_CLI_JOB="Select CLI job" COM_CRONJOBS_ERROR_INVALID_JOB_TYPE="Invalid Job Type!" COM_CRONJOBS_LABEL_EXEC_INTERVAL="Execution Interval" COM_CRONJOBS_LABEL_PLG_JOB_ID="Plugin Job ID" -COM_CRONJOBS_SELECT_JOB_TYPE="Select Job Type" +COM_CRONJOBS_FIELD_JOB_TYPE="Job Type (identifier)" From c5bc47dc6d8e6df92860842b12370bfd3d431b58 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Fri, 23 Jul 2021 03:25:10 +0530 Subject: [PATCH 083/615] Make CronjobView job type aware - Adds job type details to main tab, similar to com_modules. While the description is truncated, there's no "read more" funtionality atm. This should be added in the future. - A warning if an existing entry's job type was not advertised - Minor codestyle fix in SelectView default layout template --- .../com_cronjobs/src/Model/CronjobModel.php | 27 ++++++++---- .../src/View/Cronjob/HtmlView.php | 28 ++++++++++++ .../com_cronjobs/tmpl/cronjob/edit.php | 43 +++++++++++++------ .../com_cronjobs/tmpl/select/default.php | 2 - 4 files changed, 77 insertions(+), 23 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Model/CronjobModel.php b/administrator/components/com_cronjobs/src/Model/CronjobModel.php index e717863bdb055..cdfcd9c1c325f 100644 --- a/administrator/components/com_cronjobs/src/Model/CronjobModel.php +++ b/administrator/components/com_cronjobs/src/Model/CronjobModel.php @@ -23,7 +23,9 @@ use Joomla\CMS\MVC\Model\AdminModel; use Joomla\CMS\Factory; use Joomla\CMS\Table\Table; +use Joomla\Component\Cronjobs\Administrator\Helper\CronjobsHelper; use function defined; +use function is_object; /** * MVC Model to interact with the Cronjobs DB. @@ -118,7 +120,7 @@ public function getForm($data = array(), $loadData = true) $user = $this->app->getIdentity(); - // If new entry, set type (and plg_job, if applicable) + // If new entry, set job type from state if ($this->getState('cronjob.id', 0) === 0 && $this->getState('cronjob.type') !== null) { $form->setValue('type', null, $this->getState('cronjob.type')); @@ -176,15 +178,11 @@ protected function populateState(): void $jobId = $app->getInput()->getInt('id'); $jobType = $app->getUserState('com_cronjobs.add.cronjob.cronjob_type'); - $pluginJobId = $app->getUserState('com_cronjobs.add.cronjob.plg_job_id'); + $jobOption = $app->getUserState('com_cronjobs.add.cronjob.cronjob_option'); $this->setState('cronjob.id', $jobId); $this->setState('cronjob.type', $jobType); - - if ($pluginJobId !== null) - { - $this->setState('job.plg_job_id', $pluginJobId); - } + $this->setState('cronjob.option', $jobOption); // Load component params, though com_cronjobs does not (yet) have any params $cParams = ComponentHelper::getParams($this->option); @@ -260,12 +258,25 @@ protected function loadFormData() * * @return object|boolean Object on success, false on failure * + * @throws Exception * @since __DEPLOY_VERSION__ */ public function getItem($pk = null) { // TODO : Add CronjobModel specific handling or remove ⚠ - return parent::getItem($pk); + $item = parent::getItem($pk); + + if (!is_object($item)) + { + return false; + } + + $cronOption = ($item->id ?? 0) ? CronjobsHelper::getCronOptions()->findOption($item->type ?? 0) + : ($this->getState('cronjob.option')); + + $item->set('cronOption', $cronOption); + + return $item; } /** diff --git a/administrator/components/com_cronjobs/src/View/Cronjob/HtmlView.php b/administrator/components/com_cronjobs/src/View/Cronjob/HtmlView.php index a3459230d89d1..5100e3e9f21da 100644 --- a/administrator/components/com_cronjobs/src/View/Cronjob/HtmlView.php +++ b/administrator/components/com_cronjobs/src/View/Cronjob/HtmlView.php @@ -16,6 +16,7 @@ use Exception; use JObject; +use Joomla\CMS\Application\AdministratorApplication; use Joomla\CMS\Factory; use Joomla\CMS\Language\Text; use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView; @@ -32,6 +33,12 @@ */ class HtmlView extends BaseHtmlView { + /** + * @var AdministratorApplication $app + * @since __DEPLOY_VERSION__ + */ + protected $app; + /** * The Form object * @@ -64,6 +71,27 @@ class HtmlView extends BaseHtmlView */ protected $canDo; + /** + * Overloads the parent constructor. + * Just needed to fetch the Application object. + * + * @param array $config A named configuration array for object construction. + * name: the name (optional) of the view (defaults to the view class name suffix). + * charset: the character set to use for display + * escape: the name (optional) of the function to use for escaping strings + * base_path: the parent path (optional) of the views directory (defaults to the component folder) + * template_plath: the path (optional) of the layout directory (defaults to base_path + /views/ + view name + * helper_path: the path (optional) of the helper files (defaults to base_path + /helpers/) + * layout: the layout (optional) to use to display the view + * + * @throws Exception + * @since __DEPLOY_VERSION__ + */ + public function __construct($config = array()) + { + $this->app = Factory::getApplication(); + parent::__construct($config); + } /** * @param string $tpl The name of the template file to parse; automatically searches through the template paths. diff --git a/administrator/components/com_cronjobs/tmpl/cronjob/edit.php b/administrator/components/com_cronjobs/tmpl/cronjob/edit.php index f412236946e90..4ef6d8e9311b6 100644 --- a/administrator/components/com_cronjobs/tmpl/cronjob/edit.php +++ b/administrator/components/com_cronjobs/tmpl/cronjob/edit.php @@ -10,15 +10,18 @@ */ // Restrict direct access -\defined('_JEXEC') or die; +defined('_JEXEC') or die; +use Joomla\CMS\Application\AdministratorApplication; use Joomla\CMS\Factory; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\Layout\LayoutHelper; use Joomla\CMS\Router\Route; +use Joomla\Component\Cronjobs\Administrator\Cronjobs\CronOption; +use Joomla\Component\Cronjobs\Administrator\View\Cronjob\HtmlView; -/** @var \Joomla\Component\Cronjobs\Administrator\View\Cronjob\HtmlView $this */ +/** @var HtmlView $this */ $wa = $this->document->getWebAssetManager(); @@ -26,15 +29,8 @@ $wa->useScript('keepalive'); $wa->useScript('form.validate'); -try -{ - /** @var Joomla\CMS\Application\WebApplication $app */ - $app = Factory::getApplication(); -} catch (Exception $e) -{ - // ? : Is there a better way? - die('Failed to fetch application object'); -} +/** @var AdministratorApplication $app */ +$app = $this->app; $input = $app->getInput(); @@ -48,9 +44,9 @@ ?> -
@@ -69,6 +65,27 @@ class="form-validate"> ?>
+ + item->cronOption): + /** @var CronOption $cronOption */ + $cronOption = $this->item->cronOption; ?> +
+

+ title ?> +

+

+ escape(strip_tags($cronOption->desc)), 250); + echo $desc; + ?> +

+
+ + enqueueMessage(Text::_('COM_CRONJOBS_WARNING_EXISTING_JOB_TYPE_NOT_FOUND'), 'warning'); + ?> +
form->renderFieldset('basic'); ?> diff --git a/administrator/components/com_cronjobs/tmpl/select/default.php b/administrator/components/com_cronjobs/tmpl/select/default.php index 1222f941d711b..06a542405dd70 100644 --- a/administrator/components/com_cronjobs/tmpl/select/default.php +++ b/administrator/components/com_cronjobs/tmpl/select/default.php @@ -118,5 +118,3 @@ class="new-job mb-3"
- - From 6656e3ec209dd0b6b919fe86da54a3e0c4ff7647 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Fri, 23 Jul 2021 14:29:32 +0530 Subject: [PATCH 084/615] Add cancel() override to CronjobController Override was needed to reset state variables set by CronjobController::add() --- .../src/Controller/CronjobController.php | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Controller/CronjobController.php b/administrator/components/com_cronjobs/src/Controller/CronjobController.php index 2a1e0f7dad7ff..c3bd0bf1f4710 100644 --- a/administrator/components/com_cronjobs/src/Controller/CronjobController.php +++ b/administrator/components/com_cronjobs/src/Controller/CronjobController.php @@ -19,7 +19,7 @@ defined('_JEXEC') or die; use Exception; -use Joomla\CMS\Application\CMSApplication; +use Joomla\CMS\Application\AdministratorApplication; use Joomla\CMS\Language\Text; use Joomla\CMS\MVC\Controller\FormController; use Joomla\CMS\Router\Route; @@ -42,7 +42,7 @@ class CronjobController extends FormController */ public function add(): bool { - /**@var CMSApplication $app */ + /**@var AdministratorApplication $app */ $app = $this->app; $input = $app->getInput(); $validJobOptions = CronjobsHelper::getCronOptions(); @@ -75,6 +75,27 @@ public function add(): bool return true; } + /** + * Override parent cancel method to reset the add cronjob state + * + * @param null $key Primary key from the URL param + * + * @return boolean True if access level checks pass + * + * @since __DEPLOY_VERSION__ + */ + public function cancel($key = null): bool + { + $result = parent::cancel($key); + + $this->app->setUserState('com_cronjobs.add.cronjob.cronjob_type', null); + $this->app->setUserState('com_cronjobs.add.cronjob.cronjob_option', null); + + // ? Do we need to redirect based on URL's 'return' param? {@see ModuleController} + + return $result; + } + /** * Edit an existing record * From 2153cb315637802dd3b5ed4616e4aed1effd65cc Mon Sep 17 00:00:00 2001 From: ditsuke Date: Fri, 23 Jul 2021 19:12:36 +0530 Subject: [PATCH 085/615] Add plugin params support for Cronjobs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Job plugins can now store params by adding fields to the params group ⚠ Pending support for multiple fieldsets, some issue rendering the `joomla.edit.params` template --- .../components/com_cronjobs/forms/cronjob.xml | 210 +++++++++--------- .../com_cronjobs/src/Table/CronjobTable.php | 7 + .../com_cronjobs/tmpl/cronjob/edit.php | 15 +- 3 files changed, 129 insertions(+), 103 deletions(-) diff --git a/administrator/components/com_cronjobs/forms/cronjob.xml b/administrator/components/com_cronjobs/forms/cronjob.xml index 101eb56d2b8c7..c24a4e1e188ca 100644 --- a/administrator/components/com_cronjobs/forms/cronjob.xml +++ b/administrator/components/com_cronjobs/forms/cronjob.xml @@ -2,119 +2,129 @@ - - - -
- - - + + - - - - - - - -
- -
- - - - - -
+
+ + + + + + + + + + +
-
- - - - - - - -
+ +
+ + + + + +
- -
- - +
+ + + + + + + +
- - + +
+ + - - + + - - + + - - -
+ + - -
- - + + +
- - + +
+ + - - + + + + + + + + +
- -
+ - + + + +
+
+
diff --git a/administrator/components/com_cronjobs/src/Table/CronjobTable.php b/administrator/components/com_cronjobs/src/Table/CronjobTable.php index 08cf95adedacf..ad0603249bd66 100644 --- a/administrator/components/com_cronjobs/src/Table/CronjobTable.php +++ b/administrator/components/com_cronjobs/src/Table/CronjobTable.php @@ -34,6 +34,13 @@ class CronjobTable extends Table */ protected $_supportNullValue = false; + /** + * Ensure params are json encoded by the bind method + * @var string[] + * @since __DEPLOY_VERSION__ + */ + protected $_jsonEncode = ['params']; + /** * Injected into the 'created' column * diff --git a/administrator/components/com_cronjobs/tmpl/cronjob/edit.php b/administrator/components/com_cronjobs/tmpl/cronjob/edit.php index 4ef6d8e9311b6..35e53b7767cdb 100644 --- a/administrator/components/com_cronjobs/tmpl/cronjob/edit.php +++ b/administrator/components/com_cronjobs/tmpl/cronjob/edit.php @@ -61,7 +61,7 @@ class="form-validate"> HTMLHelper::_('uitab.addTab', 'myTab', 'general', empty($this->item->id) ? Text::_('COM_CRONJOBS_NEW_CRONJOB') : Text::_('COM_CRONJOBS_EDIT_CRONJOB') - ); + ); ?>
@@ -93,11 +93,20 @@ class="form-validate">
- form->renderFieldset('cron-options') ?> + form->renderFieldset('cron-options'); ?> +
+ +
+ + form->renderFieldset('params-fs'); + ?>
- form->renderFieldset('aside') ?> + form->renderFieldset('aside'); ?>
From ba64a65f4ac31c9d5053d925c047cfd303f2ab07 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Fri, 23 Jul 2021 19:29:28 +0530 Subject: [PATCH 086/615] Update plg_testjob with form injection - Now injects CronjobView form with a "sample" field, saved as a param in CronjobTable. --- plugins/system/testjob/forms/testJobForm.xml | 9 ++++ .../en-GB/en-GB.plg_system_testjob.ini | 1 + .../en-GB/en-GB.plg_system_testjob.sys.ini | 1 + plugins/system/testjob/testjob.php | 43 +++++++++++++++++-- 4 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 plugins/system/testjob/forms/testJobForm.xml diff --git a/plugins/system/testjob/forms/testJobForm.xml b/plugins/system/testjob/forms/testJobForm.xml new file mode 100644 index 0000000000000..2b724aa7459c6 --- /dev/null +++ b/plugins/system/testjob/forms/testJobForm.xml @@ -0,0 +1,9 @@ + +
+ +
+ +
+
+
diff --git a/plugins/system/testjob/language/en-GB/en-GB.plg_system_testjob.ini b/plugins/system/testjob/language/en-GB/en-GB.plg_system_testjob.ini index 6700c323b920a..416e94f0237cd 100644 --- a/plugins/system/testjob/language/en-GB/en-GB.plg_system_testjob.ini +++ b/plugins/system/testjob/language/en-GB/en-GB.plg_system_testjob.ini @@ -2,3 +2,4 @@ COM_TESTJOBPLG_JOB1_TITLE="First Test Job" COM_TESTJOBPLG_JOB1_DESC="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." COM_TESTJOBPLG_JOB2_TITLE="Second Test Job" COM_TESTJOBPLG_JOB2_DESC="Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?" +PLG_TESTJOB_LABEL_SAMPLE_FIELD="Sample Field" diff --git a/plugins/system/testjob/language/en-GB/en-GB.plg_system_testjob.sys.ini b/plugins/system/testjob/language/en-GB/en-GB.plg_system_testjob.sys.ini index 6700c323b920a..416e94f0237cd 100644 --- a/plugins/system/testjob/language/en-GB/en-GB.plg_system_testjob.sys.ini +++ b/plugins/system/testjob/language/en-GB/en-GB.plg_system_testjob.sys.ini @@ -2,3 +2,4 @@ COM_TESTJOBPLG_JOB1_TITLE="First Test Job" COM_TESTJOBPLG_JOB1_DESC="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." COM_TESTJOBPLG_JOB2_TITLE="Second Test Job" COM_TESTJOBPLG_JOB2_DESC="Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?" +PLG_TESTJOB_LABEL_SAMPLE_FIELD="Sample Field" diff --git a/plugins/system/testjob/testjob.php b/plugins/system/testjob/testjob.php index d6decd877c180..6fbf9b078a4e8 100644 --- a/plugins/system/testjob/testjob.php +++ b/plugins/system/testjob/testjob.php @@ -9,10 +9,11 @@ * @license GPL v3 */ +use Joomla\CMS\Form\Form; +use Joomla\CMS\Form\FormHelper; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\Event\SubscriberInterface; use Joomla\Event\Event; -use Joomla\Component\Cronjobs\Administrator\Cronjobs\CronOption; /** * The Testjobplug class @@ -29,6 +30,16 @@ class PlgSystemTestjob extends CMSPlugin implements SubscriberInterface */ protected $autoloadLanguage = true; + /** + * An array of supported Form contexts + * + * @var string[] + * @since __DEPLOY_VERSION__ + */ + private $supportedFormContexts = [ + 'com_cronjobs.cronjob' + ]; + /** * Returns event subscriptions * @@ -40,7 +51,8 @@ public static function getSubscribedEvents(): array { return [ 'onCronOptionsList' => 'pluginCronOptions', - 'onCronRun' => 'cronSampleRoutine' + 'onCronRun' => 'cronSampleRoutine', + 'onContentPrepareForm' => 'manipulateForms' ]; } @@ -87,9 +99,34 @@ public function cronSampleRoutine(Event $event): void 'job2' => 'routine2' ]; - if (\array_key_exists($subject->jobId, $supportedJobs)) + if (array_key_exists($subject->jobId, $supportedJobs)) { $subject->exec[] = ['plugin' => $this->_name, 'exit' => 0]; } } + + /** + * @param Event $event The onContentPrepareForm event. + * + * @return void + * @since __DEPLOY_VERSION + */ + public function manipulateForms(Event $event): void + { + /** @var Form $form */ + $form = $event->getArgument('0'); + + $context = $form->getName(); + + // Return early if form is not supported + if (!in_array($context, $this->supportedFormContexts)) + { + return; + } + + FormHelper::addFormPath(__DIR__ . '/forms'); + $loaded = $form->loadFile('testJobForm'); + + return; + } } From 824434d9e02e5b9b143d95115245d1e3d903d67b Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 25 Jul 2021 15:26:16 +0530 Subject: [PATCH 087/615] Fix CronjobsController namespace --- .../com_cronjobs/src/Controller/CronjobsController.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/administrator/components/com_cronjobs/src/Controller/CronjobsController.php b/administrator/components/com_cronjobs/src/Controller/CronjobsController.php index 695524a406cd9..a5e9344d20b65 100644 --- a/administrator/components/com_cronjobs/src/Controller/CronjobsController.php +++ b/administrator/components/com_cronjobs/src/Controller/CronjobsController.php @@ -9,6 +9,8 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt */ + namespace Joomla\Component\Cronjobs\Administrator\Controller; + // Restrict direct access \defined('_JEXEC') or die; From ba5efbcb770d3ffc53d052992a8549308185a0c8 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 25 Jul 2021 15:26:39 +0530 Subject: [PATCH 088/615] Add Fields to support Cronjob form --- .../src/Field/IntervalTypesField.php | 69 ++++++++ .../com_cronjobs/src/Field/IntervalsField.php | 167 ++++++++++++++++++ 2 files changed, 236 insertions(+) create mode 100644 administrator/components/com_cronjobs/src/Field/IntervalTypesField.php create mode 100644 administrator/components/com_cronjobs/src/Field/IntervalsField.php diff --git a/administrator/components/com_cronjobs/src/Field/IntervalTypesField.php b/administrator/components/com_cronjobs/src/Field/IntervalTypesField.php new file mode 100644 index 0000000000000..58ffbb999b2bd --- /dev/null +++ b/administrator/components/com_cronjobs/src/Field/IntervalTypesField.php @@ -0,0 +1,69 @@ + + * @license GPL v3 + */ + +namespace Joomla\Component\Cronjobs\Administrator\Field; + +// Restrict direct access +defined('_JEXEC') or die; + +use Joomla\CMS\Form\Field\ListField; +use Joomla\CMS\Form\Field\RadioField; +use Joomla\CMS\HTML\HTMLHelper; +use Joomla\CMS\Language\Text; + +/** + * A select list containing valid Cron interval types. + * + * @since __DEPLOY_VERSION__ + */ +class IntervalTypesField extends ListField +{ + /** + * The form field type. + * + * @var string + * @since __DEPLOY_VERSION__ + */ + protected $type = 'intervalType'; + + /** + * @var string[] + * @since __DEPLOY_VERSION__ + */ + private $responseMap = [ + 'minutes' => 'COM_CRONJOBS_FIELD_OPTION_INTERVAL_MINUTES', + 'hours' => 'COM_CRONJOBS_FIELD_OPTION_INTERVAL_HOURS', + 'days_month' => 'COM_CRONJOBS_FIELD_OPTION_INTERVAL_DAYS_M', + 'months' => 'COM_CRONJOBS_FIELD_OPTION_INTERVAL_MONTHS', + 'days_week' => 'COM_CRONJOBS_FIELD_OPTION_INTERVAL_DAYS_W' + ]; + + public function __construct($form = null) + { + parent::__construct($form); + } + + /** + * + * @return array Array of objects representing options in the options list + * + * @since __DEPLOY_VERSION__ + */ + protected function getOptions(): array + { + $options = []; + + foreach ($this->responseMap as $value => $label) + { + $options[] = HTMLHelper::_('select.option', $value, Text::_($label)); + } + + return $options; + } +} diff --git a/administrator/components/com_cronjobs/src/Field/IntervalsField.php b/administrator/components/com_cronjobs/src/Field/IntervalsField.php new file mode 100644 index 0000000000000..7e0c4f65c192f --- /dev/null +++ b/administrator/components/com_cronjobs/src/Field/IntervalsField.php @@ -0,0 +1,167 @@ + + * @license GPL v3 + */ + +namespace Joomla\Component\Cronjobs\Administrator\Field; + +// Restrict direct access +defined('_JEXEC') or die; + +use Joomla\CMS\Form\Field\ListField; +use Joomla\CMS\HTML\HTMLHelper; +use Joomla\CMS\Language\Text; +use SimpleXMLElement; +use function in_array; + +/** + * Multi-select form field, supporting inputs of: + * minutes, hours, . + * + * @since __DEPLOY_VERSION__ + */ +class IntervalsField extends ListField +{ + /** + * The form field type. + * + * @var string + * @since __DEPLOY_VERSION__ + */ + protected $type = 'cronIntervals'; + + /** + * The subtypes supported by this field type. + * + * @var string[] + * @since __DEPLOY_VERSION__ + */ + private static $subtypes = [ + 'minutes', + 'hours', + 'days_month', + 'months', + 'days_week' + ]; + + /** + * Response labels for the 'month' and 'days_week' subtypes + * + * @var string[][] + * @since __DEPLOY_VERSION__ + */ + private static $preparedResponseLabels = [ + 'months' => [ + 'JANUARY', 'FEBRUARY', 'MARCH', 'APRIL', 'MAY', 'JUNE', + 'JULY', 'AUGUST', 'SEPTEMBER', 'OCTOBER', 'NOVEMBER', 'DECEMBER' + ], + 'days_week' => [ + 'MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', + 'FRIDAY', 'SATURDAY', 'SUNDAY' + ] + ]; + + /** + * For options without explicit labels, count of options + * + * @var int[] + * @since __DEPLOY_VERSION__ + */ + private static $optionsCount = [ + 'minutes' => 59, + 'hours' => 23, + 'days_month' => 31 + ]; + + /** + * The subtype of the CronIntervals field + * + * @var string + * @since __DEPLOY_VERSION__ + */ + private $subtype; + + /** + * The multiple attribute is enabled by default. + * + * @var boolean + * @since __DEPLOY_VERSION__ + */ + protected $multiple = true; + + /** + * Override the parent method to set deal with subtypes. + * + * @param SimpleXMLElement $element The SimpleXMLElement object representing the `` tag for the form field object. + * @param mixed $value The form field value to validate. + * @param string $group The field name group control value. This acts as as an array container for the field. + * For example if the field has name="foo" and the group value is set to "bar" then the + * full field name would end up being "bar[foo]". + * + * @return boolean True on success. + * + * @since __DEPLOY_VERSION__ + */ + public function setup(SimpleXMLElement $element, $value, $group = null): bool + { + $parentResult = parent::setup($element, $value, $group); + + $subtype = (string) $element['subtype'] ?? null; + + if (!($subtype && in_array($subtype, self::$subtypes))) + { + return false; + } + + $this->subtype = $subtype; + $this->multiple = true; + $element['multiple'] = $element['multiple'] ?? 'true'; + + return $parentResult; + } + + /** + * + * @return array Array of objects representing options in the options list + * + * @since __DEPLOY_VERSION__ + */ + protected function getOptions() + { + $subtype = $this->subtype; + $options = []; + + if (!in_array($subtype, self::$subtypes)) + { + return $options; + } + + $options[] = HTMLHelper::_('select.option', '*', '*'); + + if (array_key_exists($subtype, self::$preparedResponseLabels)) + { + $labels = self::$preparedResponseLabels[$subtype]; + $responseCount = count($labels); + + for ($i = 0; $i < $responseCount; $i++) + { + $options[] = HTMLHelper::_('select.option', $i, Text::_($labels[$i])); + } + } + elseif (array_key_exists($subtype, self::$optionsCount)) + { + $responseCount = self::$optionsCount[$subtype]; + + for ($i = 0; $i < $responseCount; $i++) + { + $options[] = HTMLHelper::_('select.option', $i, (string) ($i + 1)); + } + } + + return $options; + } +} From a17b3689540e9aca0a40ac72a4dce178ddb9f578 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 25 Jul 2021 15:53:08 +0530 Subject: [PATCH 089/615] Switch to FancySelect for IntervalsField --- .../layouts/Joomla/form/field/interval.php | 129 ++++++++++++++++++ .../com_cronjobs/src/Field/IntervalsField.php | 8 ++ 2 files changed, 137 insertions(+) create mode 100644 administrator/components/com_cronjobs/layouts/Joomla/form/field/interval.php diff --git a/administrator/components/com_cronjobs/layouts/Joomla/form/field/interval.php b/administrator/components/com_cronjobs/layouts/Joomla/form/field/interval.php new file mode 100644 index 0000000000000..351fbc79dcc4e --- /dev/null +++ b/administrator/components/com_cronjobs/layouts/Joomla/form/field/interval.php @@ -0,0 +1,129 @@ + + * @license GPL v3 + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Application\AdministratorApplication; +use Joomla\CMS\Factory; +use Joomla\CMS\HTML\HTMLHelper; +use Joomla\CMS\Language\Text; + +extract($displayData); + +/** + * Layout variables + * ----------------- + * @var string $autocomplete Autocomplete attribute for the field. + * @var boolean $autofocus Is autofocus enabled? + * @var string $class Classes for the input. + * @var string $description Description of the field. + * @var boolean $disabled Is this field disabled? + * @var string $group Group the field belongs to. section in form XML. + * @var boolean $hidden Is this field hidden in the form? + * @var string $hint Placeholder for the field. + * @var string $id DOM id of the field. + * @var string $label Label of the field. + * @var string $labelclass Classes to apply to the label. + * @var boolean $multiple Does this field support multiple values? + * @var string $name Name of the input field. + * @var string $onchange Onchange attribute for the field. + * @var string $onclick Onclick attribute for the field. + * @var string $pattern Pattern (Reg Ex) of value of the form field. + * @var boolean $readonly Is this field read only? + * @var boolean $repeat Allows extensions to duplicate elements. + * @var boolean $required Is this field required? + * @var integer $size Size attribute of the input. + * @var boolean $spellcheck Spellcheck state for the form field. + * @var string $validate Validation rules to apply. + * @var string $value Value attribute of the field. + * @var array $checkedOptions Options that will be set as checked. + * @var boolean $hasValue Has this field a value assigned? + * @var array $options Options available for this field. + * @var array $inputType Options available for this field. + * @var boolean $allowCustom Flag, to allow add custom values + * @var integer $minTermLength Minimum length of the term to start searching + * @var string $dataAttribute Miscellaneous data attributes preprocessed for HTML output + * @var array $dataAttributes Miscellaneous data attributes for eg, data-*. + */ + +$html = array(); +$attr = ''; + +// Initialize some field attributes. +$attr .= $multiple ? ' multiple' : ''; +$attr .= $autofocus ? ' autofocus' : ''; +$attr .= $onchange ? ' onchange="' . $onchange . '"' : ''; +$attr .= $dataAttribute; + +// To avoid user's confusion, readonly="readonly" should imply disabled="disabled". +if ($readonly || $disabled) +{ + $attr .= ' disabled="disabled"'; +} + +$attr2 = ''; +$attr2 .= !empty($class) ? ' class="' . $class . '"' : ''; +$attr2 .= ' placeholder="' . $this->escape($hint ?: Text::_('COM_CRONJOBS_TYPE_OR_SELECT_OPTIONS')) . '" '; +$attr2 .= $dataAttribute; + +if ($required) +{ + $attr .= ' required class="required"'; + $attr2 .= ' required'; +} + +// Create a read-only list (no name) with hidden input(s) to store the value(s). +if ($readonly) +{ + $html[] = HTMLHelper::_('select.genericlist', $options, '', trim($attr), 'value', 'text', $value, $id); + + // E.g. form field type tag sends $this->value as array + if ($multiple && is_array($value)) + { + if (!count($value)) + { + $value[] = ''; + } + + foreach ($value as $val) + { + $html[] = ''; + } + } + else + { + $html[] = ''; + } +} +else +// Create a regular list. +{ + $html[] = HTMLHelper::_('select.genericlist', $options, $name, trim($attr), 'value', 'text', $value, $id); +} + +Text::script('JGLOBAL_SELECT_NO_RESULTS_MATCH'); +Text::script('JGLOBAL_SELECT_PRESS_TO_SELECT'); + +/** @var AdministratorApplication $app */ +try +{ + $app = Factory::getApplication(); +} +catch (Exception $e) +{ + die('Could not get application object'); +} + +$app->getDocument()->getWebAssetManager() + ->usePreset('choicesjs') + ->useScript('webcomponent.field-fancy-select'); + +?> + +> diff --git a/administrator/components/com_cronjobs/src/Field/IntervalsField.php b/administrator/components/com_cronjobs/src/Field/IntervalsField.php index 7e0c4f65c192f..39cef13778646 100644 --- a/administrator/components/com_cronjobs/src/Field/IntervalsField.php +++ b/administrator/components/com_cronjobs/src/Field/IntervalsField.php @@ -34,6 +34,14 @@ class IntervalsField extends ListField */ protected $type = 'cronIntervals'; + /** + * Layout used to render the field + * + * @var string + * @since __DEPLOY_VERSION__ + */ + protected $layout = 'joomla.form.field.interval'; + /** * The subtypes supported by this field type. * From 954f88d072d1dc2bf9b8915e4290a126f15ee25c Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 25 Jul 2021 15:58:14 +0530 Subject: [PATCH 090/615] Update Cronjob form - Switches to the new IntervalsField - Adds the same interval options as Cron (DB, Model pending update) - Switches to a new field group for intervals --- .../components/com_cronjobs/forms/cronjob.xml | 39 ++++++++++++++++--- .../com_cronjobs/tmpl/cronjob/edit.php | 11 ++++-- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/administrator/components/com_cronjobs/forms/cronjob.xml b/administrator/components/com_cronjobs/forms/cronjob.xml index c24a4e1e188ca..807f8c110da55 100644 --- a/administrator/components/com_cronjobs/forms/cronjob.xml +++ b/administrator/components/com_cronjobs/forms/cronjob.xml @@ -1,7 +1,7 @@ -
+ -
- - + + <!– TODO : JS and submission validation. Minutes >= 1 if Hours == 0 –> -
+
-->
@@ -120,6 +120,33 @@ /> + + + +
+ + + + + + + + +
+
+ + +
+ + form->renderFieldset('interval'); ?>
@@ -151,5 +155,4 @@ class="form-validate">
- From a954de7bd20fa282c39347133f169d5b2fc1ad8d Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 25 Jul 2021 23:42:55 +0530 Subject: [PATCH 091/615] Update database table Changes execution_interval column to TEXT --- .../components/com_admin/sql/updates/mysql/4.1.0-2021-07-25.sql | 2 ++ .../com_admin/sql/updates/postgresql/4.1.0-2021-07-25.sql | 2 ++ installation/sql/mysql/extensions.sql | 2 +- installation/sql/postgresql/extensions.sql | 2 +- 4 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-25.sql create mode 100644 administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-25.sql diff --git a/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-25.sql b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-25.sql new file mode 100644 index 0000000000000..9786c8c3b2edf --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-25.sql @@ -0,0 +1,2 @@ +ALTER TABLE `#__cronjobs` + MODIFY COLUMN `execution_interval` text COMMENT 'Configured execution interval, cron format'; diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-25.sql b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-25.sql new file mode 100644 index 0000000000000..2cccaf8e2caca --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-25.sql @@ -0,0 +1,2 @@ +ALTER TABLE "#__cronjobs" + ALTER COLUMN "execution_interval" TYPE text; diff --git a/installation/sql/mysql/extensions.sql b/installation/sql/mysql/extensions.sql index 7022e87d98a0c..a16e9cd2606ad 100644 --- a/installation/sql/mysql/extensions.sql +++ b/installation/sql/mysql/extensions.sql @@ -897,7 +897,7 @@ CREATE TABLE IF NOT EXISTS `#__cronjobs` ( `type` varchar(1024) NOT NULL COMMENT 'unique identifier for job defined by plugin', -- Trigger type, default to PseudoCron (compatible everywhere). `trigger` enum ('pseudo_cron', 'cron', 'visit_count') NOT NULL DEFAULT 'pseudo_cron' COMMENT 'Defines how job is triggered', - `execution_interval` time NOT NULL COMMENT 'Configured time between executions,in HH:MM:SS format', + `execution_interval` text COMMENT 'Configured execution interval, cron format', `state` tinyint NOT NULL DEFAULT FALSE, `last_exit_code` int NOT NULL DEFAULT '0' COMMENT 'Exit code when job was last run', `last_execution` datetime COMMENT 'Timestamp of last run', diff --git a/installation/sql/postgresql/extensions.sql b/installation/sql/postgresql/extensions.sql index 3acf6d8c1c61a..19ce315143f83 100644 --- a/installation/sql/postgresql/extensions.sql +++ b/installation/sql/postgresql/extensions.sql @@ -858,7 +858,7 @@ CREATE TABLE IF NOT EXISTS "#__cronjobs" "asset_id" bigint NOT NULL DEFAULT '0', "title" varchar(255) NOT NULL, "type" varchar(1024) NOT NULL, - "execution_interval" interval NOT NULL, + "execution_interval" text, "trigger" varchar(12) NOT NULL DEFAULT 'pseudo_cron', "state" smallint NOT NULL DEFAULT '0', "last_exit_code" int NOT NULL DEFAULT '0', From 629ad03535748b0609983069f99e514551131f77 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Tue, 27 Jul 2021 19:03:28 +0530 Subject: [PATCH 092/615] Update Cronjob form and IntervalsField - To Cronjob form: - Adds friendly intervals (hours, minutes, days...) as rules. - Delegates custom Cron-style matches to an "Advanced" option. - To IntervalsField: - Adds support for custom options. - Adds `wildcard` and `onlyNumericLabels` attributes. - Removes fancyselect, as it didn't look apt for the use. --- .../components/com_cronjobs/forms/cronjob.xml | 67 +++++++++++-------- .../com_cronjobs/src/Field/IntervalsField.php | 43 ++++++++---- 2 files changed, 70 insertions(+), 40 deletions(-) diff --git a/administrator/components/com_cronjobs/forms/cronjob.xml b/administrator/components/com_cronjobs/forms/cronjob.xml index 807f8c110da55..bc73b364d030e 100644 --- a/administrator/components/com_cronjobs/forms/cronjob.xml +++ b/administrator/components/com_cronjobs/forms/cronjob.xml @@ -28,19 +28,6 @@
- - -
- -
+ + +
- + + + + + + + + + + + + + + + + + + +
- + + - - - -
diff --git a/administrator/components/com_cronjobs/src/Field/IntervalsField.php b/administrator/components/com_cronjobs/src/Field/IntervalsField.php index 39cef13778646..589db24e4854c 100644 --- a/administrator/components/com_cronjobs/src/Field/IntervalsField.php +++ b/administrator/components/com_cronjobs/src/Field/IntervalsField.php @@ -36,11 +36,12 @@ class IntervalsField extends ListField /** * Layout used to render the field + * ! Due removal * * @var string * @since __DEPLOY_VERSION__ */ - protected $layout = 'joomla.form.field.interval'; + // protected $layout = 'joomla.form.field.interval'; /** * The subtypes supported by this field type. @@ -74,7 +75,7 @@ class IntervalsField extends ListField ]; /** - * For options without explicit labels, count of options + * Count of predefined options for each subtype * * @var int[] * @since __DEPLOY_VERSION__ @@ -82,7 +83,9 @@ class IntervalsField extends ListField private static $optionsCount = [ 'minutes' => 59, 'hours' => 23, - 'days_month' => 31 + 'days_week' => 7, + 'days_month' => 31, + 'months' => 12 ]; /** @@ -94,12 +97,20 @@ class IntervalsField extends ListField private $subtype; /** - * The multiple attribute is enabled by default. + * If true, field options will include a wildcard * - * @var boolean - * @since __DEPLOY_VERSION__ + * @var boolean + * @since __DEPLOY_VERSION__ + */ + private $wildcard; + + /** + * If true, field will only have numeric labels (for days_week and months) + * + * @var boolean + * @since __DEPLOY_VERSION__ */ - protected $multiple = true; + private $onlyNumericLabels; /** * Override the parent method to set deal with subtypes. @@ -119,6 +130,8 @@ public function setup(SimpleXMLElement $element, $value, $group = null): bool $parentResult = parent::setup($element, $value, $group); $subtype = (string) $element['subtype'] ?? null; + $wildcard = (string) $element['wildcard'] ?? false; + $onlyNumericLabels = (string) $element['onlyNumericLabels'] ?? false; if (!($subtype && in_array($subtype, self::$subtypes))) { @@ -126,8 +139,8 @@ public function setup(SimpleXMLElement $element, $value, $group = null): bool } $this->subtype = $subtype; - $this->multiple = true; - $element['multiple'] = $element['multiple'] ?? 'true'; + $this->wildcard = $wildcard; + $this->onlyNumericLabels = $onlyNumericLabels; return $parentResult; } @@ -138,19 +151,25 @@ public function setup(SimpleXMLElement $element, $value, $group = null): bool * * @since __DEPLOY_VERSION__ */ - protected function getOptions() + protected function getOptions(): array { $subtype = $this->subtype; $options = []; + $options = parent::getOptions(); + if (!in_array($subtype, self::$subtypes)) { return $options; } - $options[] = HTMLHelper::_('select.option', '*', '*'); + // $options[] = HTMLHelper::_('select.option', '*', '*'); + if ($this->wildcard) + { + $options[] = HTMLHelper::_('select.option', '*', '*'); + } - if (array_key_exists($subtype, self::$preparedResponseLabels)) + if (!$this->onlyNumericLabels && array_key_exists($subtype, self::$preparedResponseLabels)) { $labels = self::$preparedResponseLabels[$subtype]; $responseCount = count($labels); From 55ee299fc973a09d8df88f169d89b7d13613d7bc Mon Sep 17 00:00:00 2001 From: ditsuke Date: Wed, 28 Jul 2021 02:09:57 +0530 Subject: [PATCH 093/615] Fix option indices in IntervalsField --- .../components/com_cronjobs/src/Field/IntervalsField.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Field/IntervalsField.php b/administrator/components/com_cronjobs/src/Field/IntervalsField.php index 589db24e4854c..b4db967c7d5f1 100644 --- a/administrator/components/com_cronjobs/src/Field/IntervalsField.php +++ b/administrator/components/com_cronjobs/src/Field/IntervalsField.php @@ -176,7 +176,7 @@ protected function getOptions(): array for ($i = 0; $i < $responseCount; $i++) { - $options[] = HTMLHelper::_('select.option', $i, Text::_($labels[$i])); + $options[] = HTMLHelper::_('select.option', (string) ($i + 1), Text::_($labels[$i])); } } elseif (array_key_exists($subtype, self::$optionsCount)) @@ -185,7 +185,7 @@ protected function getOptions(): array for ($i = 0; $i < $responseCount; $i++) { - $options[] = HTMLHelper::_('select.option', $i, (string) ($i + 1)); + $options[] = HTMLHelper::_('select.option', (string) ($i + 1), (string) ($i + 1)); } } From d8b95735e8fb8cf035c4341cb89b65a902cc09cf Mon Sep 17 00:00:00 2001 From: ditsuke Date: Wed, 28 Jul 2021 02:10:30 +0530 Subject: [PATCH 094/615] Update CronjobView template - Adds custom execution rules to a fieldset that shows when the custom ruletype is selected --- .../components/com_cronjobs/tmpl/cronjob/edit.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/administrator/components/com_cronjobs/tmpl/cronjob/edit.php b/administrator/components/com_cronjobs/tmpl/cronjob/edit.php index 31f6c41064be0..0b0d99045d8d7 100644 --- a/administrator/components/com_cronjobs/tmpl/cronjob/edit.php +++ b/administrator/components/com_cronjobs/tmpl/cronjob/edit.php @@ -27,6 +27,7 @@ $wa->useScript('keepalive'); $wa->useScript('form.validate'); +$wa->useStyle('com_cronjobs.admin-view-cronjob-css'); /** @var AdministratorApplication $app */ $app = $this->app; @@ -90,14 +91,12 @@ class="form-validate"> form->renderFieldset('basic'); ?>
- -
+
- form->renderFieldset('interval'); ?> + form->renderFieldset('custom-cron-rules'); ?>
From c6122e5fc4e9e3179ea094c087e63c31dbf684f9 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Wed, 28 Jul 2021 02:14:57 +0530 Subject: [PATCH 095/615] Add CSS for CronjobView Defines styles for the custom rules fieldset --- media/com_cronjobs/css/admin-view-cronjob.css | 24 +++++++++++++++++++ media/com_cronjobs/joomla.asset.json | 5 ++++ 2 files changed, 29 insertions(+) create mode 100644 media/com_cronjobs/css/admin-view-cronjob.css diff --git a/media/com_cronjobs/css/admin-view-cronjob.css b/media/com_cronjobs/css/admin-view-cronjob.css new file mode 100644 index 0000000000000..fa9fea928e813 --- /dev/null +++ b/media/com_cronjobs/css/admin-view-cronjob.css @@ -0,0 +1,24 @@ +.match-custom .control-group .control-label { + width: auto; + padding: 0 0 0 0; +} + +.match-custom .control-group .controls { + /* flex: 1; */ + display: inline-block; + min-width: 7rem; +} + +.match-custom .control-group { + /* display: flex; */ + display: inline-block; + margin-right: 1.5rem; +} + +.match-custom label { + font-size: small; +} + +.match-custom select[multiple] { + height: 15rem; +} diff --git a/media/com_cronjobs/joomla.asset.json b/media/com_cronjobs/joomla.asset.json index 77f025214a487..65d0704203765 100644 --- a/media/com_cronjobs/joomla.asset.json +++ b/media/com_cronjobs/joomla.asset.json @@ -32,6 +32,11 @@ "name": "com_cronjobs.admin-plg-job-css", "type": "style", "uri": "com_cronjobs/admin-plg-job.css" + }, + { + "name": "com_cronjobs.admin-view-cronjob-css", + "type": "style", + "uri": "com_cronjobs/admin-view-cronjob.css" } ] } From 949261c4590271eb5623f31c51af5913400f7ac2 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Wed, 28 Jul 2021 02:16:45 +0530 Subject: [PATCH 096/615] Update language files Adds definitions for new Cronjob form fields --- administrator/language/en-GB/com_cronjobs.ini | 21 ++++++++++++++++++ .../language/en-GB/com_cronjobs.sys.ini | 22 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/administrator/language/en-GB/com_cronjobs.ini b/administrator/language/en-GB/com_cronjobs.ini index 0142cd65b9f15..c64a6bbb1cd24 100644 --- a/administrator/language/en-GB/com_cronjobs.ini +++ b/administrator/language/en-GB/com_cronjobs.ini @@ -46,3 +46,24 @@ COM_CRONJOBS_ERROR_INVALID_JOB_TYPE="Invalid Job Type!" COM_CRONJOBS_LABEL_EXEC_INTERVAL="Execution Interval" COM_CRONJOBS_LABEL_PLG_JOB_ID="Plugin Job ID" COM_CRONJOBS_FIELD_JOB_TYPE="Job Type (identifier)" +COM_CRONJOBS_FIELD_LABEL_EXEC_RULE="Execution Rule" +COM_CRONJOBS_SELECT_EXEC_RULE="--- Select Rule ---" +COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_MINUTES="Minutes" +COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_HOURS="Hours" +COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_DAYS_M="Days of Month" +COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_MONTHS="Months" +COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_DAYS_W="Days of Week" +COM_CRONJOBS_TYPE_OR_SELECT_OPTIONS="Type or select options" +COM_CRONJOBS_OPTION_INTERVAL_MINUTES="Interval, Minutes" +COM_CRONJOBS_OPTION_INTERVAL_HOURS="Interval, Hours" +COM_CRONJOBS_OPTION_INTERVAL_DAYS="Interval, Days" +COM_CRONJOBS_OPTION_INTERVAL_MONTHS="Interval, Months" +COM_CRONJOBS_OPTION_INTERVAL_CUSTOM="Custom Match (Advanced)" +COM_CRONJOBS_FIELD_LABEL_INTERVAL_MINUTES="Interval in Minutes" +COM_CRONJOBS_FIELD_LABEL_INTERVAL_HOURS="Interval in Hours" +COM_CRONJOBS_FIELD_LABEL_INTERVAL_DAYS="Interval in Days" +COM_CRONJOBS_FIELD_LABEL_INTERVAL_MONTHS="Interval in Months" +COM_CRONJOBS_SELECT_INTERVAL_MINUTES="-- Select Interval in Minutes --" +COM_CRONJOBS_SELECT_INTERVAL_HOURS="-- Select Interval in Hours" +COM_CRONJOBS_SELECT_INTERVAL_DAYS="-- Select Interval in Days --" +COM_CRONJOBS_SELECT_INTERVAL_MONTHS="-- Select Interval in Months" diff --git a/administrator/language/en-GB/com_cronjobs.sys.ini b/administrator/language/en-GB/com_cronjobs.sys.ini index 0142cd65b9f15..2170f5ce7da75 100644 --- a/administrator/language/en-GB/com_cronjobs.sys.ini +++ b/administrator/language/en-GB/com_cronjobs.sys.ini @@ -46,3 +46,25 @@ COM_CRONJOBS_ERROR_INVALID_JOB_TYPE="Invalid Job Type!" COM_CRONJOBS_LABEL_EXEC_INTERVAL="Execution Interval" COM_CRONJOBS_LABEL_PLG_JOB_ID="Plugin Job ID" COM_CRONJOBS_FIELD_JOB_TYPE="Job Type (identifier)" +COM_CRONJOBS_FIELD_LABEL_EXEC_RULE="Execution Rule" +COM_CRONJOBS_SELECT_EXEC_RULE="--- Select Rule ---" +COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_MINUTES="Minutes" +COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_HOURS="Hours" +COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_DAYS_M="Days of Month" +COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_MONTHS="Months" +COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_DAYS_W="Days of Week" +COM_CRONJOBS_TYPE_OR_SELECT_OPTIONS="Type or select options" +COM_CRONJOBS_OPTION_INTERVAL_MINUTES="Interval, Minutes" +COM_CRONJOBS_OPTION_INTERVAL_HOURS="Interval, Hours" +COM_CRONJOBS_OPTION_INTERVAL_DAYS="Interval, Days" +COM_CRONJOBS_OPTION_INTERVAL_MONTHS="Interval, Months" +COM_CRONJOBS_OPTION_INTERVAL_CUSTOM="Custom Match (Advanced)" +COM_CRONJOBS_FIELD_LABEL_INTERVAL_MINUTES="Interval in Minutes" +COM_CRONJOBS_FIELD_LABEL_INTERVAL_HOURS="Interval in Hours" +COM_CRONJOBS_FIELD_LABEL_INTERVAL_DAYS="Interval in Days" +COM_CRONJOBS_FIELD_LABEL_INTERVAL_MONTHS="Interval in Months" +COM_CRONJOBS_SELECT_INTERVAL_MINUTES="-- Select Interval in Minutes --" +COM_CRONJOBS_SELECT_INTERVAL_HOURS="-- Select Interval in Hours" +COM_CRONJOBS_SELECT_INTERVAL_DAYS="-- Select Interval in Days --" +COM_CRONJOBS_SELECT_INTERVAL_MONTHS="-- Select Interval in Months" + From 3c5e9d5d5530ba187c2d63a27d2def112b5020fb Mon Sep 17 00:00:00 2001 From: ditsuke Date: Wed, 28 Jul 2021 02:23:41 +0530 Subject: [PATCH 097/615] Cleanup IntervalsField Removes the layout property, previously commented out. It was due removal anyways and blocked tests on push. --- .../components/com_cronjobs/src/Field/IntervalsField.php | 9 --------- 1 file changed, 9 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Field/IntervalsField.php b/administrator/components/com_cronjobs/src/Field/IntervalsField.php index b4db967c7d5f1..9eb990000e381 100644 --- a/administrator/components/com_cronjobs/src/Field/IntervalsField.php +++ b/administrator/components/com_cronjobs/src/Field/IntervalsField.php @@ -34,15 +34,6 @@ class IntervalsField extends ListField */ protected $type = 'cronIntervals'; - /** - * Layout used to render the field - * ! Due removal - * - * @var string - * @since __DEPLOY_VERSION__ - */ - // protected $layout = 'joomla.form.field.interval'; - /** * The subtypes supported by this field type. * From c81ee46fbaa1e51634a5c0d515a3f7623732d2c8 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Wed, 28 Jul 2021 23:37:52 +0530 Subject: [PATCH 098/615] Refactor IntervalsField - Fixes option value ranges. - Replaces use of static members with class constants where appropriate. - Reduces code duplication. --- .../com_cronjobs/src/Field/IntervalsField.php | 78 +++++++++---------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Field/IntervalsField.php b/administrator/components/com_cronjobs/src/Field/IntervalsField.php index 9eb990000e381..13170b494beb6 100644 --- a/administrator/components/com_cronjobs/src/Field/IntervalsField.php +++ b/administrator/components/com_cronjobs/src/Field/IntervalsField.php @@ -17,6 +17,7 @@ use Joomla\CMS\Language\Text; use SimpleXMLElement; use function in_array; +use function range; /** * Multi-select form field, supporting inputs of: @@ -26,21 +27,13 @@ */ class IntervalsField extends ListField { - /** - * The form field type. - * - * @var string - * @since __DEPLOY_VERSION__ - */ - protected $type = 'cronIntervals'; - /** * The subtypes supported by this field type. * * @var string[] * @since __DEPLOY_VERSION__ */ - private static $subtypes = [ + private const SUBTYPES = [ 'minutes', 'hours', 'days_month', @@ -48,13 +41,27 @@ class IntervalsField extends ListField 'days_week' ]; + /** + * Count of predefined options for each subtype + * + * @var int[][] + * @since __DEPLOY_VERSION__ + */ + private const OPTIONS_RANGE = [ + 'minutes' => [0, 59], + 'hours' => [0, 23], + 'days_week' => [1, 7], + 'days_month' => [1, 31], + 'months' => [1, 12] + ]; + /** * Response labels for the 'month' and 'days_week' subtypes * * @var string[][] * @since __DEPLOY_VERSION__ */ - private static $preparedResponseLabels = [ + private const PREPARED_RESPONSE_LABELS = [ 'months' => [ 'JANUARY', 'FEBRUARY', 'MARCH', 'APRIL', 'MAY', 'JUNE', 'JULY', 'AUGUST', 'SEPTEMBER', 'OCTOBER', 'NOVEMBER', 'DECEMBER' @@ -66,18 +73,12 @@ class IntervalsField extends ListField ]; /** - * Count of predefined options for each subtype + * The form field type. * - * @var int[] - * @since __DEPLOY_VERSION__ + * @var string + * @since __DEPLOY_VERSION__ */ - private static $optionsCount = [ - 'minutes' => 59, - 'hours' => 23, - 'days_week' => 7, - 'days_month' => 31, - 'months' => 12 - ]; + protected $type = 'cronIntervals'; /** * The subtype of the CronIntervals field @@ -124,7 +125,7 @@ public function setup(SimpleXMLElement $element, $value, $group = null): bool $wildcard = (string) $element['wildcard'] ?? false; $onlyNumericLabels = (string) $element['onlyNumericLabels'] ?? false; - if (!($subtype && in_array($subtype, self::$subtypes))) + if (!($subtype && in_array($subtype, self::SUBTYPES))) { return false; } @@ -137,6 +138,7 @@ public function setup(SimpleXMLElement $element, $value, $group = null): bool } /** + * Method to get field options * * @return array Array of objects representing options in the options list * @@ -145,39 +147,37 @@ public function setup(SimpleXMLElement $element, $value, $group = null): bool protected function getOptions(): array { $subtype = $this->subtype; - $options = []; - $options = parent::getOptions(); - if (!in_array($subtype, self::$subtypes)) + if (!in_array($subtype, self::SUBTYPES)) { return $options; } - // $options[] = HTMLHelper::_('select.option', '*', '*'); if ($this->wildcard) { $options[] = HTMLHelper::_('select.option', '*', '*'); } - if (!$this->onlyNumericLabels && array_key_exists($subtype, self::$preparedResponseLabels)) - { - $labels = self::$preparedResponseLabels[$subtype]; - $responseCount = count($labels); + [$optionLower, $optionUpper] = self::OPTIONS_RANGE[$subtype]; - for ($i = 0; $i < $responseCount; $i++) - { - $options[] = HTMLHelper::_('select.option', (string) ($i + 1), Text::_($labels[$i])); - } + if (array_key_exists($subtype, self::PREPARED_RESPONSE_LABELS) && !$this->onlyNumericLabels) + { + $labels = array_map( + function (string $string): string { + return Text::_($string); + }, + self::PREPARED_RESPONSE_LABELS[$subtype] + ); } - elseif (array_key_exists($subtype, self::$optionsCount)) + else { - $responseCount = self::$optionsCount[$subtype]; + $labels = range(... self::OPTIONS_RANGE[$subtype]); + } - for ($i = 0; $i < $responseCount; $i++) - { - $options[] = HTMLHelper::_('select.option', (string) ($i + 1), (string) ($i + 1)); - } + for ([$i, $l] = [$optionLower, 0]; $i <= $optionUpper; $i++, $l++) + { + $options[] = HTMLHelper::_('select.option', (string) ($i), $labels[$l]); } return $options; From 72e7386722bfef2cec6384d0cb9eae5836f3c1ff Mon Sep 17 00:00:00 2001 From: ditsuke Date: Thu, 29 Jul 2021 00:31:41 +0530 Subject: [PATCH 099/615] Bugfix CronOptions::findOptions() - Fixes bug with null argument method calls: such calls used to fail since type declaration for the argument (CronOption) was not nullable. - Refactors the $options member variable (earlier $jobs). --- .../com_cronjobs/src/Cronjobs/CronOptions.php | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Cronjobs/CronOptions.php b/administrator/components/com_cronjobs/src/Cronjobs/CronOptions.php index 5eb6db00fb03a..6843d32fb262f 100644 --- a/administrator/components/com_cronjobs/src/Cronjobs/CronOptions.php +++ b/administrator/components/com_cronjobs/src/Cronjobs/CronOptions.php @@ -22,7 +22,7 @@ * Used as the subject argument for the `OnCronOptionsList` event, plugins that support jobs must add them to the object * through the addOptions() method. * - * @since __DEPLOY_VERSION + * @since __DEPLOY_VERSION__ */ class CronOptions { @@ -32,7 +32,7 @@ class CronOptions * @var CronOption[] * @since __DEPLOY_VERSION__ */ - public $jobs = []; + public $options = []; /** @@ -50,20 +50,25 @@ public function addOptions(array $jobsArray): void { foreach ($jobsArray as $jobId => $langConstPrefix) { - $this->jobs[] = new CronOption($jobId, $langConstPrefix); + $this->options[] = new CronOption($jobId, $langConstPrefix); } } /** - * @param string $jobType A unique identifier for the job routine offered by a plugin + * @param ?string $jobType A unique identifier for the job routine offered by a plugin * - * @return CronOption|false A matching CronOption if available, false otherwise + * @return CronOption|false A matching CronOption if available, false otherwise * * @since __DEPLOY_VERSION__ */ - public function findOption(string $jobType) + public function findOption(?string $jobType) { - foreach ($this->jobs as $job) + if ($jobType === null) + { + return false; + } + + foreach ($this->options as $job) { if ($job->type === $jobType) { From 067f868696425c7f1dba7f1d1456cfc8ae1d0daa Mon Sep 17 00:00:00 2001 From: ditsuke Date: Thu, 29 Jul 2021 03:26:20 +0530 Subject: [PATCH 100/615] Improve view entry validation - Fixes erroneous "Existing Type Not Found" warning when jumping to new entry form. - Redirects to CronjobsView and displays error message if user jumps to new entry form bypassing SelectView. - Improves code readability and delegates some validation logic in the DisplayController to a new private method. --- .../src/Controller/CronjobController.php | 11 ++-- .../src/Controller/DisplayController.php | 64 +++++++++++++++---- 2 files changed, 58 insertions(+), 17 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Controller/CronjobController.php b/administrator/components/com_cronjobs/src/Controller/CronjobController.php index c3bd0bf1f4710..db1141b33a362 100644 --- a/administrator/components/com_cronjobs/src/Controller/CronjobController.php +++ b/administrator/components/com_cronjobs/src/Controller/CronjobController.php @@ -47,15 +47,15 @@ public function add(): bool $input = $app->getInput(); $validJobOptions = CronjobsHelper::getCronOptions(); - $result = parent::add(); + $canAdd = parent::add(); - if ($result !== true) + if ($canAdd !== true) { return false; } $jobType = $input->get('type'); - $jobOption = $validJobOptions->findOption($jobType); + $jobOption = $validJobOptions->findOption($jobType) ?: null; if (!$jobOption) { @@ -63,8 +63,7 @@ public function add(): bool $redirectUrl = 'index.php?option=' . $this->option . '&view=select&layout=edit'; $this->setRedirect(Route::_($redirectUrl, false)); $app->enqueueMessage(Text::_('COM_CRONJOBS_ERROR_INVALID_JOB_TYPE'), 'warning'); - - return false; + $canAdd = false; } $app->setUserState('com_cronjobs.add.cronjob.cronjob_type', $jobType); @@ -72,7 +71,7 @@ public function add(): bool // TODO : Parameter array handling below? - return true; + return $canAdd; } /** diff --git a/administrator/components/com_cronjobs/src/Controller/DisplayController.php b/administrator/components/com_cronjobs/src/Controller/DisplayController.php index 89b124a672e52..e31cffc78ed83 100644 --- a/administrator/components/com_cronjobs/src/Controller/DisplayController.php +++ b/administrator/components/com_cronjobs/src/Controller/DisplayController.php @@ -12,12 +12,14 @@ namespace Joomla\Component\Cronjobs\Administrator\Controller; // Restrict direct access -\defined('_JEXEC') or die; +defined('_JEXEC') or die; use Exception; -use Joomla\CMS\MVC\Controller\BaseController; use Joomla\CMS\Language\Text; +use Joomla\CMS\MVC\Controller\BaseController; use Joomla\CMS\Router\Route; +use function count; +use function defined; /** @@ -45,23 +47,63 @@ class DisplayController extends BaseController public function display($cachable = false, $urlparams = array()) { $layout = $this->input->get('layout', 'default'); - $id = $this->input->getInt('id'); // Check for edit form. - if ($layout == 'edit' && !$this->checkEditId('com_cronjobs.edit.cronjob', $id)) + if ($layout === 'edit') { - // Somehow the person just went to the form - we don't allow that. - if (!\count($this->app->getMessageQueue())) + if (!$this->validateEntry()) { - $this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id), 'error'); - } - - $this->setRedirect(Route::_('index.php?option=com_cronjobs&view=cronjobs')); + $cronjobsViewUrl = Route::_('index.php?option=com_cronjobs&view=cronjobs'); + $this->setRedirect($cronjobsViewUrl); - return false; + return false; + } } // Let the parent method take over return parent::display($cachable, $urlparams); } + + /** + * Validates entry to the view + * + * @param string $layout The layout to validate entry for (defaults to 'edit') + * + * @return boolean True is entry is valid + * + * @since __DEPLOY_VERSION__ + */ + private function validateEntry(string $layout = 'edit'): bool + { + $context = 'com_cronjobs'; + $id = $this->input->getInt('id'); + $isValid = true; + + switch ($layout) + { + case 'edit': + + // True if controller was called and verified permissions + $canEdit = $this->checkEditId("${context}.edit.cronjob", $id); + $isNew = ($id == 0); + + // For new item, entry is invalid if job type was not selected through SelectView + if ($isNew && !$this->app->getUserState("${context}.add.cronjob.cronjob_type")) + { + $this->setMessage((Text::_('COM_CRONJOBS_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW')), 'error'); + $isValid = false; + } + // For existing item, entry is invalid if CronjobController has not granted access + elseif (!$canEdit && !count($this->app->getMessageQueue())) + { + $this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id), 'error'); + $isValid = false; + } + break; + default: + break; + } + + return $isValid; + } } From 6bc9bcb81e5cf4416ab928f7c06baafcd7df0fec Mon Sep 17 00:00:00 2001 From: ditsuke Date: Thu, 29 Jul 2021 04:03:05 +0530 Subject: [PATCH 101/615] Add caching to CronjobsHelper Caches the CronOptions object on first call to ::getCronOptions() for efficiency. Should make it feasible to refer to it as a stateful object rather than storing the CronOption in the userState, where it probably doesn't belong. --- .../src/Helper/CronjobsHelper.php | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Helper/CronjobsHelper.php b/administrator/components/com_cronjobs/src/Helper/CronjobsHelper.php index a716701f8e73e..6de1722ac0377 100644 --- a/administrator/components/com_cronjobs/src/Helper/CronjobsHelper.php +++ b/administrator/components/com_cronjobs/src/Helper/CronjobsHelper.php @@ -21,7 +21,7 @@ use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Component\Cronjobs\Administrator\Cronjobs\CronOptions; -use function \defined; +use function defined; /** * The CronjobsHelper class. @@ -29,8 +29,16 @@ * * @since __DEPLOY_VERSION__ */ -class CronjobsHelper +final class CronjobsHelper { + /** + * Cached CronOptions object + * + * @var CronOptions + * @since __DEPLOY_VERSION__ + */ + protected static $cronOptionsCache = null; + /** * Private constructor to prevent instantiation * @@ -49,6 +57,11 @@ private function __construct() */ public static function getCronOptions(): CronOptions { + if (self::$cronOptionsCache !== null) + { + return self::$cronOptionsCache; + } + /**@var AdministratorApplication $app */ $app = Factory::getApplication(); $options = new CronOptions; @@ -59,10 +72,11 @@ public static function getCronOptions(): CronOptions ] ); - // TODO : Implement an object for $items PluginHelper::importPlugin('job'); $app->getDispatcher()->dispatch('onCronOptionsList', $event); + self::$cronOptionsCache = $options; + return $options; } } From 1cb5d613eb365a28a0b65cb1c62a71a723384d33 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Thu, 29 Jul 2021 04:16:18 +0530 Subject: [PATCH 102/615] Update Cronjob form XML Includes uncommitted changes that go with the latest changes to the template and stylesheet: - Un-hides custom rule labels (the CSS takes care of laying them out). - Removes the wildcard option from custom rules. --- .../components/com_cronjobs/forms/cronjob.xml | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/administrator/components/com_cronjobs/forms/cronjob.xml b/administrator/components/com_cronjobs/forms/cronjob.xml index bc73b364d030e..0ce5050c611fd 100644 --- a/administrator/components/com_cronjobs/forms/cronjob.xml +++ b/administrator/components/com_cronjobs/forms/cronjob.xml @@ -122,38 +122,41 @@ - - + + - + - - + - + + - +
- - - - -
From f53a7dbcea13ffcb62bd2cc6cab926747fceeee4 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Thu, 29 Jul 2021 22:35:58 +0530 Subject: [PATCH 103/615] Limit interval options in Cronjob form - Adds IntervalField for limited interval options - Rename IntervalsField to CronField - Update Cronjob form to use the limited option field --- .../components/com_cronjobs/forms/cronjob.xml | 20 +-- .../{IntervalsField.php => CronField.php} | 2 +- .../com_cronjobs/src/Field/IntervalField.php | 120 ++++++++++++++++++ 3 files changed, 131 insertions(+), 11 deletions(-) rename administrator/components/com_cronjobs/src/Field/{IntervalsField.php => CronField.php} (99%) create mode 100644 administrator/components/com_cronjobs/src/Field/IntervalField.php diff --git a/administrator/components/com_cronjobs/forms/cronjob.xml b/administrator/components/com_cronjobs/forms/cronjob.xml index 0ce5050c611fd..e992173e80013 100644 --- a/administrator/components/com_cronjobs/forms/cronjob.xml +++ b/administrator/components/com_cronjobs/forms/cronjob.xml @@ -125,37 +125,37 @@ - - + - - -
- - - - -
diff --git a/administrator/components/com_cronjobs/src/Field/IntervalsField.php b/administrator/components/com_cronjobs/src/Field/CronField.php similarity index 99% rename from administrator/components/com_cronjobs/src/Field/IntervalsField.php rename to administrator/components/com_cronjobs/src/Field/CronField.php index 13170b494beb6..2ba89fa8a7fc7 100644 --- a/administrator/components/com_cronjobs/src/Field/IntervalsField.php +++ b/administrator/components/com_cronjobs/src/Field/CronField.php @@ -25,7 +25,7 @@ * * @since __DEPLOY_VERSION__ */ -class IntervalsField extends ListField +class CronField extends ListField { /** * The subtypes supported by this field type. diff --git a/administrator/components/com_cronjobs/src/Field/IntervalField.php b/administrator/components/com_cronjobs/src/Field/IntervalField.php new file mode 100644 index 0000000000000..3f7065f6abb96 --- /dev/null +++ b/administrator/components/com_cronjobs/src/Field/IntervalField.php @@ -0,0 +1,120 @@ + + * @license GPL v3 + */ + +namespace Joomla\Component\Cronjobs\Administrator\Field; + +// Restrict direct access +defined('_JEXEC') or die; + +use Joomla\CMS\Form\Field\ListField; +use Joomla\CMS\HTML\HTMLHelper; +use SimpleXMLElement; + +/** + * Select style field for interval(s) in minutes, hours, days and months. + * + * @since __DEPLOY_VERSION__ + */ +class IntervalField extends ListField +{ + /** + * The subtypes supported by this field type. + * + * @var string[] + * @since __DEPLOY_VERSION__ + */ + private const SUBTYPES = [ + 'minutes', + 'hours', + 'days', + 'months' + ]; + + /** + * Options corresponding to each subtype + * + * @var int[][] + * @since __DEPLOY_VERSION__ + */ + private const OPTIONS = [ + 'minutes' => [1, 2, 3, 5, 10, 15, 30], + 'hours' => [1, 2, 3, 6, 12], + 'days' => [1, 2, 3, 5, 10, 15], + 'months' => [1, 2, 3, 6, 12] + ]; + + /** + * The form field type. + * + * @var string + * @since __DEPLOY_VERSION__ + */ + protected $type = 'cronIntervals'; + + /** + * The subtype of the CronIntervals field + * + * @var string + * @since __DEPLOY_VERSION__ + */ + private $subtype; + + /** + * Override the parent method to set deal with subtypes. + * + * @param SimpleXMLElement $element The SimpleXMLElement object representing the `` tag for the form field object. + * @param mixed $value The form field value to validate. + * @param string $group The field name group control value. This acts as as an array container for the field. + * For example if the field has name="foo" and the group value is set to "bar" then the + * full field name would end up being "bar[foo]". + * + * @return boolean True on success. + * + * @since __DEPLOY_VERSION__ + */ + public function setup(SimpleXMLElement $element, $value, $group = null): bool + { + $parentResult = parent::setup($element, $value, $group); + $subtype = (string) $element['subtype'] ?? null; + + if (!($subtype && in_array($subtype, self::SUBTYPES))) + { + return false; + } + + $this->subtype = $subtype; + + return $parentResult; + } + + /** + * Method to get field options + * + * @return array Array of objects representing options in the options list + * + * @since __DEPLOY_VERSION__ + */ + protected function getOptions(): array + { + $subtype = $this->subtype; + $options = parent::getOptions(); + + if (!in_array($subtype, self::SUBTYPES)) + { + return $options; + } + + foreach (self::OPTIONS[$subtype] as $option) + { + $options[] = HTMLHelper::_('select.option', (string) ($option), (string) $option); + } + + return $options; + } +} From 2dabb4593e4dcb9121092ac34b4bcb4e1099431f Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sat, 31 Jul 2021 16:36:20 +0530 Subject: [PATCH 104/615] Add fields to Cronjob form Adds the exec_time and exec_day fields, applicable to select exec rules. --- administrator/components/com_cronjobs/forms/cronjob.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/administrator/components/com_cronjobs/forms/cronjob.xml b/administrator/components/com_cronjobs/forms/cronjob.xml index e992173e80013..bc6ff1dc66bb7 100644 --- a/administrator/components/com_cronjobs/forms/cronjob.xml +++ b/administrator/components/com_cronjobs/forms/cronjob.xml @@ -139,6 +139,12 @@ + + + +
From fbac3edcc93ae598e24dbf1c46ac2c2e9099222c Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sat, 31 Jul 2021 21:23:24 +0530 Subject: [PATCH 105/615] Update database tables - Renames `execution_interval` to `execution_rule` - Adds new column `cron_rules` --- .../com_admin/sql/updates/mysql/4.1.0-2021-07-31.sql | 5 +++++ .../com_admin/sql/updates/postgresql/4.1.0-2021-07-31.sql | 6 ++++++ installation/sql/mysql/extensions.sql | 3 ++- installation/sql/postgresql/extensions.sql | 3 ++- 4 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-31.sql create mode 100644 administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-31.sql diff --git a/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-31.sql b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-31.sql new file mode 100644 index 0000000000000..defbd307d91d7 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-31.sql @@ -0,0 +1,5 @@ +ALTER TABLE `#__cronjobs` + -- Rename `execution_interval` to `execution_rules` + CHANGE `execution_interval` `execution_rules` text COMMENT 'Execution Rules, Unprocessed', + -- Add column `cron_rules` + ADD `cron_rules` text COMMENT 'Processed execution rules, crontab-like JSON form'; diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-31.sql b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-31.sql new file mode 100644 index 0000000000000..11df565f0d00f --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-31.sql @@ -0,0 +1,6 @@ +-- Rename "execution_interval" to "execution_rules" +ALTER TABLE "#__cronjobs" + RENAME COLUMN "execution_interval" TO "execution_rules"; +-- Add column "cron_rules" +ALTER TABLE "#__cronjobs" + ADD COLUMN "cron_rules" text; diff --git a/installation/sql/mysql/extensions.sql b/installation/sql/mysql/extensions.sql index a16e9cd2606ad..a3e4dc1b6e91b 100644 --- a/installation/sql/mysql/extensions.sql +++ b/installation/sql/mysql/extensions.sql @@ -897,7 +897,8 @@ CREATE TABLE IF NOT EXISTS `#__cronjobs` ( `type` varchar(1024) NOT NULL COMMENT 'unique identifier for job defined by plugin', -- Trigger type, default to PseudoCron (compatible everywhere). `trigger` enum ('pseudo_cron', 'cron', 'visit_count') NOT NULL DEFAULT 'pseudo_cron' COMMENT 'Defines how job is triggered', - `execution_interval` text COMMENT 'Configured execution interval, cron format', + `execution_rules` text COMMENT 'Execution Rules, Unprocessed', + `cron_rules` text COMMENT 'Processed execution rules, crontab-like JSON form', `state` tinyint NOT NULL DEFAULT FALSE, `last_exit_code` int NOT NULL DEFAULT '0' COMMENT 'Exit code when job was last run', `last_execution` datetime COMMENT 'Timestamp of last run', diff --git a/installation/sql/postgresql/extensions.sql b/installation/sql/postgresql/extensions.sql index 19ce315143f83..c443351d19fc1 100644 --- a/installation/sql/postgresql/extensions.sql +++ b/installation/sql/postgresql/extensions.sql @@ -858,7 +858,8 @@ CREATE TABLE IF NOT EXISTS "#__cronjobs" "asset_id" bigint NOT NULL DEFAULT '0', "title" varchar(255) NOT NULL, "type" varchar(1024) NOT NULL, - "execution_interval" text, + "execution_rules" text, + "cron_rules" text, "trigger" varchar(12) NOT NULL DEFAULT 'pseudo_cron', "state" smallint NOT NULL DEFAULT '0', "last_exit_code" int NOT NULL DEFAULT '0', From fa0648e328b79d6fff09483696bb24e8d2c1652d Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 1 Aug 2021 01:26:46 +0530 Subject: [PATCH 106/615] Add ExecutionRulesRule for Cronjob form validation This class is responsible for validating all execution rule fields against the rule type. This does not include the day/time fields which will be auto-populated if not provided. --- .../src/Rule/ExecutionRulesRule.php | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 administrator/components/com_cronjobs/src/Rule/ExecutionRulesRule.php diff --git a/administrator/components/com_cronjobs/src/Rule/ExecutionRulesRule.php b/administrator/components/com_cronjobs/src/Rule/ExecutionRulesRule.php new file mode 100644 index 0000000000000..b0bee6acbfbd0 --- /dev/null +++ b/administrator/components/com_cronjobs/src/Rule/ExecutionRulesRule.php @@ -0,0 +1,86 @@ + + * @license GPL v3 + */ + +namespace Joomla\Component\Cronjobs\Administrator\Rule; + +// Restrict direct access +defined('_JEXEC') or die; + +use Joomla\CMS\Form\Form; +use Joomla\CMS\Form\FormRule; +use Joomla\CMS\Form\Rule\OptionsRule; +use Joomla\Registry\Registry; +use SimpleXMLElement; + +/** + * The ExecutionRulesRule Class. + * Validates execution rules, with input for other fields as context. + * + * @since __DEPLOY_VERSION__ + */ +class ExecutionRulesRule extends FormRule +{ + /** + * @var string RULE_TYPE_FIELD The field containing the rule type to test against + * @since __DEPLOY_VERSION__ + */ + private const RULE_TYPE_FIELD = "execution_rules.rule-type"; + + /** + * @var string CUSTOM_RULE_GROUP The field group containing custom execution rules + * @since __DEPLOY_VERSION__ + */ + private const CUSTOM_RULE_GROUP = "execution_rules.custom"; + + /** + * @param SimpleXMLElement $element The SimpleXMLElement object representing the `` tag for the form field object. + * @param mixed $value The form field value to validate. + * @param ?string $group The field name group control value. This acts as an array container for the field. + * For example if the field has name="foo" and the group value is set to "bar" then the + * full field name would end up being "bar[foo]". + * @param ?Registry $input An optional Registry object with the entire data set to validate against the entire form. + * @param ?Form $form The form object for which the field is being tested. + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + */ + public function test(SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null): bool + { + $fieldName = (string) $element['name']; + $ruleType = $input->get(self::RULE_TYPE_FIELD); + + if ($ruleType === $fieldName || ($ruleType === 'custom' && $group === self::CUSTOM_RULE_GROUP)) + { + return self::validateField($element, $value, $group, $form); + } + + return true; + } + + /** + * @param SimpleXMLElement $element The SimpleXMLElement for the field. + * @param mixed $value The field value. + * @param ?string $group The form field group the element belongs to. + * @param Form|null $form The Form object against which the field is tested/ + * + * @return boolean True if field is valid + * + * @since __DEPLOY_VERSION__ + */ + private function validateField(SimpleXMLElement $element, $value, ?string $group = null, ?Form $form = null): bool + { + // Test that the option is valid + $optionsTest = (new OptionsRule)->test($element, $value, $group, null, $form); + + return $value && $optionsTest; + } +} From 56dc7d1710de5f94461e03f7696f343382002266 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 1 Aug 2021 01:29:08 +0530 Subject: [PATCH 107/615] Add new validation rules to Cronjob form Rule fields are now validation against ExecutionRulesRule --- .../components/com_cronjobs/forms/cronjob.xml | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/administrator/components/com_cronjobs/forms/cronjob.xml b/administrator/components/com_cronjobs/forms/cronjob.xml index bc6ff1dc66bb7..bb5fcdcf810c2 100644 --- a/administrator/components/com_cronjobs/forms/cronjob.xml +++ b/administrator/components/com_cronjobs/forms/cronjob.xml @@ -1,7 +1,8 @@ -
+ + label="COM_CRONJOBS_FIELD_LABEL_EXEC_RULE" validate="options"> @@ -125,19 +126,19 @@ - - - - - + - - - - +
From 79010050f1d2edbb2c9d1995f4f78545b2469472 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 1 Aug 2021 17:21:18 +0530 Subject: [PATCH 108/615] Add missing placeholder options to Cronjob form Adds previously missing placeholder options for intervals. --- .../components/com_cronjobs/forms/cronjob.xml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/administrator/components/com_cronjobs/forms/cronjob.xml b/administrator/components/com_cronjobs/forms/cronjob.xml index bb5fcdcf810c2..c5c05ef157d47 100644 --- a/administrator/components/com_cronjobs/forms/cronjob.xml +++ b/administrator/components/com_cronjobs/forms/cronjob.xml @@ -132,14 +132,20 @@
+ label="COM_CRONJOBS_FIELD_LABEL_INTERVAL_HOURS" showon="rule-type:interval-hours"> + + + label="COM_CRONJOBS_FIELD_LABEL_INTERVAL_DAYS" showon="rule-type:interval-days"> + + + label="COM_CRONJOBS_FIELD_LABEL_INTERVAL_MONTHS" showon="rule-type:interval-months"> + + From 0a306ea57949eed46bc2076dcf3dd3957a088904 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 1 Aug 2021 17:50:10 +0530 Subject: [PATCH 109/615] Add execution_rules handling to CronjobModel `execution_rules` from Cronjob form are sanitised, then used to build crontab-like `cron_rules`. These rules will be used internally to determine due executions. Handling for this is due to be added. --- .../com_cronjobs/src/Model/CronjobModel.php | 147 +++++++++++++++--- 1 file changed, 123 insertions(+), 24 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Model/CronjobModel.php b/administrator/components/com_cronjobs/src/Model/CronjobModel.php index cdfcd9c1c325f..96fb352c66ff8 100644 --- a/administrator/components/com_cronjobs/src/Model/CronjobModel.php +++ b/administrator/components/com_cronjobs/src/Model/CronjobModel.php @@ -17,15 +17,19 @@ use Exception; use Joomla\CMS\Application\AdministratorApplication; use Joomla\CMS\Component\ComponentHelper; +use Joomla\CMS\Factory; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormFactoryInterface; use Joomla\CMS\MVC\Factory\MVCFactoryInterface; use Joomla\CMS\MVC\Model\AdminModel; -use Joomla\CMS\Factory; use Joomla\CMS\Table\Table; use Joomla\Component\Cronjobs\Administrator\Helper\CronjobsHelper; +use function array_diff; +use function array_fill_keys; use function defined; +use function gmdate; use function is_object; +use function sort; /** * MVC Model to interact with the Cronjobs DB. @@ -37,7 +41,7 @@ class CronjobModel extends AdminModel { /** * Maps logical states to their values in the DB - * ? : Do we end up using this? + * ? Do we end up using this? * * @var array * @since __DEPLOY_VERSION__ @@ -249,10 +253,6 @@ protected function loadFormData() /** * Overloads the parent getItem() method. - * ! : Currently does nothing - * - * ? : Is this needed at all? - * Should be removed if we end up not needing any special handling. * * @param integer $pk Primary key * @@ -263,7 +263,6 @@ protected function loadFormData() */ public function getItem($pk = null) { - // TODO : Add CronjobModel specific handling or remove ⚠ $item = parent::getItem($pk); if (!is_object($item)) @@ -274,6 +273,7 @@ public function getItem($pk = null) $cronOption = ($item->id ?? 0) ? CronjobsHelper::getCronOptions()->findOption($item->type ?? 0) : ($this->getState('cronjob.option')); + CronjobsHelper::getCronOptions(); $item->set('cronOption', $cronOption); return $item; @@ -284,12 +284,13 @@ public function getItem($pk = null) * * @return boolean True on success, false on failure * + * @throws Exception * @since __DEPLOY_VERSION__ */ public function save($data): bool { /** - * @var object $field Holds the record we're saving $data to + * @var object $field Holds the record we're saving $data to */ $field = null; @@ -300,29 +301,127 @@ public function save($data): bool $field = $this->getItem($data['id']); } - /* - * ! : Due change - * TODO : Change execution interval in DB to TIME, change handling below - * TODO : Custom fields and we might not need this ugly handling - */ - $intervalHours = str_pad($data['interval-hours'] ?? '0', 2, '0', STR_PAD_LEFT); - $intervalMinutes = str_pad($data['interval-minutes'] ?? '0', 2, '0', STR_PAD_LEFT); - $data['execution_interval'] = "$intervalHours:$intervalMinutes:00"; + // Clean up execution rules + $this->processExecutionRules($data); - // TODO : Unset fields based on type and trigger selected + // Build the `cron_rules` column from `execution_rules` + $this->buildCronRule($data); - /* - * The parent save() takes care of saving to the main - * `#__cronjobs` table - */ + // Parent method takes care of saving to the table if (!parent::save($data)) { return false; } - // TODO: Handle the type-specific tables below! ⚠ - - // No failures if we get here return true; } + + /** + * Clean up and standardise execution rules + * + * @param array $data The form data [? can just replace with execution_interval] + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + private function processExecutionRules(array &$data): void + { + $executionRules = &$data['execution_rules']; + $ruleType = $executionRules['rule-type']; + $retainKeys = ['rule-type', $ruleType, 'exec-day', 'exec-time']; + $executionRules = array_intersect_key($executionRules, array_flip($retainKeys)); + + $executionRules['exec-day'] = $executionRules['exec-day'] ?: (string) gmdate('d'); + $executionRules['exec-time'] = $executionRules['exec-time'] ?: (string) gmdate('H:i'); + + // If custom ruleset, sort it + // ? Is this necessary + if ($ruleType === 'custom') + { + foreach ($executionRules['custom'] as &$values) + { + sort($values); + } + } + } + + /** + * Private method to build cron rules from input execution rules. + * Cron rules are used internally to determine execution times/conditions. + * + * @param array $data The form input data + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + private function buildCronRule(array &$data): void + { + $executionRules = $data['execution_rules']; + $cronRules = &$data['cron_rules']; + $standardRules = ['minutes', 'hours', 'days_month', 'months', 'days_week']; + $cronRules = array_fill_keys($standardRules, '*'); + $cronRules['visits'] = null; + $basisDayOfMonth = $executionRules['exec-day']; + $basisTime = $executionRules['exec-time']; + [$basisHour, $basisMinute] = explode(':', $basisTime); + + switch ($executionRules['rule-type']) + { + case 'interval-minutes': + $cronRules['minutes'] = "*/${executionRules['interval-minutes']}"; + break; + case 'interval-hours': + $cronRules['minutes'] = (int) $basisMinute; + $cronRules['hours'] = "*/${executionRules['interval-hours']}"; + break; + case 'interval-days': + $cronRules['minutes'] = (int) $basisMinute; + $cronRules['hours'] = (int) $basisHour; + $cronRules['days'] = "*/${executionRules['interval-days']}"; + break; + case 'interval-months': + $cronRules['minutes'] = (int) $basisMinute; + $cronRules['hours'] = (int) $basisHour; + $cronRules['days'] = (int) $basisDayOfMonth; + $cronRules['months'] = "*/${executionRules['interval-months']}"; + break; + case 'custom': + $customRules = &$executionRules['custom']; + $cronRules['minutes'] = $this->wildcardIfMatch($customRules['minutes'], range(0, 59), true); + $cronRules['hours'] = $this->wildcardIfMatch($customRules['hours'], range(0, 23), true); + $cronRules['days_month'] = $this->wildcardIfMatch($customRules['days_month'], range(1, 31), true); + $cronRules['months'] = $this->wildcardIfMatch($customRules['months'], range(1, 12), true); + $cronRules['days_week'] = $this->wildcardIfMatch($customRules['days_week'], range(1, 7), true); + } + } + + /** + * Determine if an array is populated by all its possible values by comparison to a reference array. + * + * @param array $target The target array + * @param array $reference The reference array, populated by the complete set of possible values in $target + * @param bool $targetToInt If true, converts $target array values to integers before comparing + * + * @return string|int[] A wildcard string if $target is fully populated, else $target itself. + * + * @since __DEPLOY_VERSION__ + */ + private function wildcardIfMatch(array $target, array $reference, bool $targetToInt = false) + { + if ($targetToInt) + { + $target = array_map( + function (string $x): int { + return (int) $x; + }, + $target + ); + } + + $isMatch = array_diff($reference, $target) === []; + + return $isMatch ? "*" : $target; + } } From 2821be75a24e7fdc6a7460ac393ba2d11dc320ef Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 1 Aug 2021 18:18:51 +0530 Subject: [PATCH 110/615] Update CronjobTable Adds `execution_rules` and `cron_rules` to _jsonEncode[] --- .../components/com_cronjobs/src/Table/CronjobTable.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/administrator/components/com_cronjobs/src/Table/CronjobTable.php b/administrator/components/com_cronjobs/src/Table/CronjobTable.php index ad0603249bd66..adfafc30ddc83 100644 --- a/administrator/components/com_cronjobs/src/Table/CronjobTable.php +++ b/administrator/components/com_cronjobs/src/Table/CronjobTable.php @@ -39,7 +39,7 @@ class CronjobTable extends Table * @var string[] * @since __DEPLOY_VERSION__ */ - protected $_jsonEncode = ['params']; + protected $_jsonEncode = ['params', 'execution_rules', 'cron_rules']; /** * Injected into the 'created' column From 5ff878147014a690dd2d4012691058dc2294731a Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 1 Aug 2021 18:37:16 +0530 Subject: [PATCH 111/615] Fix fetching of execution_rules in CronjobModel The parent getItem() call leaves nested json objects encoded. This adds calls to json_decode() for both `execution_rules` and `cron_rules`. --- .../components/com_cronjobs/src/Model/CronjobModel.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Model/CronjobModel.php b/administrator/components/com_cronjobs/src/Model/CronjobModel.php index 96fb352c66ff8..d418d04b8c829 100644 --- a/administrator/components/com_cronjobs/src/Model/CronjobModel.php +++ b/administrator/components/com_cronjobs/src/Model/CronjobModel.php @@ -22,6 +22,7 @@ use Joomla\CMS\Form\FormFactoryInterface; use Joomla\CMS\MVC\Factory\MVCFactoryInterface; use Joomla\CMS\MVC\Model\AdminModel; +use Joomla\CMS\Object\CMSObject; use Joomla\CMS\Table\Table; use Joomla\Component\Cronjobs\Administrator\Helper\CronjobsHelper; use function array_diff; @@ -233,12 +234,9 @@ protected function loadFormData() // If the data from UserState is empty, we fetch it with getItem() if (empty($data)) { + /** @var CMSObject $data */ $data = $this->getItem(); - $time = explode(':', $data->get('execution_interval')); - $data->set('interval-hours', $time[0] ?? 0); - $data->set('interval-minutes', $time[1] ?? 0); - // TODO : Any further data processing goes here } @@ -270,6 +268,10 @@ public function getItem($pk = null) return false; } + // Parent call leaves `execution_rules` and `cron_rules` JSON encoded + $item->set('execution_rules', json_decode($item->get('execution_rules'))); + $item->set('cron_rules', json_decode($item->get('cron_rules'))); + $cronOption = ($item->id ?? 0) ? CronjobsHelper::getCronOptions()->findOption($item->type ?? 0) : ($this->getState('cronjob.option')); From 6366708d47e2a3277cecdee0d92c0ec889b93cc6 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 1 Aug 2021 18:43:45 +0530 Subject: [PATCH 112/615] Cleanup CronjobTable Removes some outdated comments --- .../components/com_cronjobs/src/Table/CronjobTable.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Table/CronjobTable.php b/administrator/components/com_cronjobs/src/Table/CronjobTable.php index adfafc30ddc83..82d4dad193300 100644 --- a/administrator/components/com_cronjobs/src/Table/CronjobTable.php +++ b/administrator/components/com_cronjobs/src/Table/CronjobTable.php @@ -61,10 +61,6 @@ class CronjobTable extends Table * CronjobTable constructor. * Just passes the DB table name and primary key name to parent constructor. * - * ? : How do we incorporate the supporting job type tables? - * Is the solution a Table class for each of them - * Or can we have a more elegant arrangement? - * * @param DatabaseDriver $db A database connector object (?) * * @since __DEPLOY_VERSION__ @@ -106,7 +102,7 @@ public function check() : bool $this->title = htmlspecialchars_decode($this->title, ENT_QUOTES); // Set created date if not set. - // ? : Might not need since the constructor already sets this + // ? Might not need since the constructor already sets this if (!(int) $this->created) { $this->created = Factory::getDate()->toSql(); From 3c1299cabcf4c95285d06569431d7cab747e4016 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 1 Aug 2021 19:45:04 +0530 Subject: [PATCH 113/615] Update SelectModel Changes from the CronOptions refactor: - References `CronOptions->options` instead of `CronOptions->jobs`. --- administrator/components/com_cronjobs/src/Model/SelectModel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/administrator/components/com_cronjobs/src/Model/SelectModel.php b/administrator/components/com_cronjobs/src/Model/SelectModel.php index e5857e9a53260..540627a761b1b 100644 --- a/administrator/components/com_cronjobs/src/Model/SelectModel.php +++ b/administrator/components/com_cronjobs/src/Model/SelectModel.php @@ -63,6 +63,6 @@ public function __construct($config = array(), ?MVCFactoryInterface $factory = n */ public function getItems(): array { - return CronjobsHelper::getCronOptions()->jobs; + return CronjobsHelper::getCronOptions()->options; } } From 65636a0cf3a0b5618b3eae383c98f200db9c2f31 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 1 Aug 2021 19:48:14 +0530 Subject: [PATCH 114/615] Patch list view MVC - Patches "New Job" button (now links to SelectView). - Removes/replaces refs to `execution_interval`. --- .../components/com_cronjobs/src/Model/CronjobsModel.php | 5 +---- .../components/com_cronjobs/src/View/Cronjobs/HtmlView.php | 6 ++++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php index 9a39b6654f995..d6e57a231d7bb 100644 --- a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php +++ b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php @@ -67,9 +67,6 @@ public function __construct($config = array(), MVCFactoryInterface $factory = nu 'trigger', 'a.trigger', - 'execution_interval', - 'a.execution_interval', - 'enabled', 'a.enabled', @@ -163,7 +160,7 @@ protected function getListQuery(): QueryInterface $query->select( $this->getState( 'list.select', - 'a.id, a.asset_id, a.title, a.type, a.trigger, a.execution_interval, a.state, a.last_exit_code' . + 'a.id, a.asset_id, a.title, a.type, a.trigger, a.execution_rules, a.state, a.last_exit_code' . ', a.last_execution, a.next_execution, a.times_executed, a.times_failed' ) // ? Does 'list.select' exist ? diff --git a/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php b/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php index 22a6599e169e6..f6b5731a66905 100644 --- a/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php +++ b/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php @@ -143,7 +143,6 @@ public function display($tpl = null): void */ protected function addToolbar(): void { - // TODO: eval $canDo('core.delete') $canDo = ContentHelper::getActions('com_cronjobs'); $user = Factory::getApplication()->getIdentity(); @@ -158,7 +157,10 @@ protected function addToolbar(): void if ($canDo->get('core.create')) { - $toolbar->addNew('cronjob.add'); + $toolbar->linkButton('new', 'JTOOLBAR_NEW') + ->url('index.php?option=com_cronjobs&view=select&layout=default') + ->buttonClass('btn btn-success') + ->icon('icon-new'); } if (!$this->isEmptyState && ($canDo->get('core.edit.state') || $user->authorise('core.admin'))) From 472ec87ea657fb8773718c1520a5ef0d7d0145c7 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 1 Aug 2021 19:51:27 +0530 Subject: [PATCH 115/615] Update language files Adds new constants for CronjobView, error handling --- administrator/language/en-GB/com_cronjobs.ini | 7 +++++-- administrator/language/en-GB/com_cronjobs.sys.ini | 8 +++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/administrator/language/en-GB/com_cronjobs.ini b/administrator/language/en-GB/com_cronjobs.ini index c64a6bbb1cd24..e593e66f05f53 100644 --- a/administrator/language/en-GB/com_cronjobs.ini +++ b/administrator/language/en-GB/com_cronjobs.ini @@ -64,6 +64,9 @@ COM_CRONJOBS_FIELD_LABEL_INTERVAL_HOURS="Interval in Hours" COM_CRONJOBS_FIELD_LABEL_INTERVAL_DAYS="Interval in Days" COM_CRONJOBS_FIELD_LABEL_INTERVAL_MONTHS="Interval in Months" COM_CRONJOBS_SELECT_INTERVAL_MINUTES="-- Select Interval in Minutes --" -COM_CRONJOBS_SELECT_INTERVAL_HOURS="-- Select Interval in Hours" +COM_CRONJOBS_SELECT_INTERVAL_HOURS="-- Select Interval in Hours --" COM_CRONJOBS_SELECT_INTERVAL_DAYS="-- Select Interval in Days --" -COM_CRONJOBS_SELECT_INTERVAL_MONTHS="-- Select Interval in Months" +COM_CRONJOBS_SELECT_INTERVAL_MONTHS="-- Select Interval in Months --" +COM_CRONJOBS_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW="You need to select a job type first!" +COM_CRONJOBS_LABEL_EXEC_TIME="Execution Time (UTC)" +COM_CRONJOBS_LABEL_EXEC_DAY="Execution Day (UTC)" diff --git a/administrator/language/en-GB/com_cronjobs.sys.ini b/administrator/language/en-GB/com_cronjobs.sys.ini index 2170f5ce7da75..e593e66f05f53 100644 --- a/administrator/language/en-GB/com_cronjobs.sys.ini +++ b/administrator/language/en-GB/com_cronjobs.sys.ini @@ -64,7 +64,9 @@ COM_CRONJOBS_FIELD_LABEL_INTERVAL_HOURS="Interval in Hours" COM_CRONJOBS_FIELD_LABEL_INTERVAL_DAYS="Interval in Days" COM_CRONJOBS_FIELD_LABEL_INTERVAL_MONTHS="Interval in Months" COM_CRONJOBS_SELECT_INTERVAL_MINUTES="-- Select Interval in Minutes --" -COM_CRONJOBS_SELECT_INTERVAL_HOURS="-- Select Interval in Hours" +COM_CRONJOBS_SELECT_INTERVAL_HOURS="-- Select Interval in Hours --" COM_CRONJOBS_SELECT_INTERVAL_DAYS="-- Select Interval in Days --" -COM_CRONJOBS_SELECT_INTERVAL_MONTHS="-- Select Interval in Months" - +COM_CRONJOBS_SELECT_INTERVAL_MONTHS="-- Select Interval in Months --" +COM_CRONJOBS_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW="You need to select a job type first!" +COM_CRONJOBS_LABEL_EXEC_TIME="Execution Time (UTC)" +COM_CRONJOBS_LABEL_EXEC_DAY="Execution Day (UTC)" From fabafc611aa81a611f931f9a8a2772fe71b0b5a1 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Mon, 2 Aug 2021 04:57:07 +0530 Subject: [PATCH 116/615] Update language files - Adds some missing strings - Changes the EXEC_DAY label --- administrator/language/en-GB/com_cronjobs.ini | 4 +++- administrator/language/en-GB/com_cronjobs.sys.ini | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/administrator/language/en-GB/com_cronjobs.ini b/administrator/language/en-GB/com_cronjobs.ini index e593e66f05f53..adf4e508455f1 100644 --- a/administrator/language/en-GB/com_cronjobs.ini +++ b/administrator/language/en-GB/com_cronjobs.ini @@ -11,6 +11,7 @@ COM_CRONJOBS_TYPE_PLG="Plugin" COM_CRONJOBS_SELECT_TRIGGER="Trigger" COM_CRONJOBS_EMPTYSTATE_CONTENT="No entries!" COM_CRONJOBS_EMPTYSTATE_BUTTON_ADD="Add a Cronjob!" +COM_CRONJOBS_EMPTYSTATE_TITLE="No Cronjobs have been created yet!" COM_CRONJOBS_FIELD_CREATED_BY_LABEL="Created By" COM_CRONJOBS_FIELD_CREATED_LABEL="Created" COM_CRONJOBS_TRIGGER_PSEUDOCRON="Pseudocron" @@ -19,6 +20,7 @@ COM_CRONJOBS_TRIGGER_XVISITS="X-Visits" COM_CRONJOBS_MANAGER_CRONJOBS="Cronjobs Manager" COM_CRONJOBS_MANAGER_CRONJOB="Cronjob Manager" COM_CRONJOBS_MANAGER_CRONJOB_EDIT="Edit Cronjob" +COM_CRONJOBS_MANAGER_CRONJOB_NEW="New Cronjob" COM_CRONJOBS_NEW_CRONJOB="New Cronjob" COM_CRONJOBS_EDIT_CRONJOB="Edit Cronjob" COM_CRONJOBS_FIELDSET_RULES="Rules" @@ -69,4 +71,4 @@ COM_CRONJOBS_SELECT_INTERVAL_DAYS="-- Select Interval in Days --" COM_CRONJOBS_SELECT_INTERVAL_MONTHS="-- Select Interval in Months --" COM_CRONJOBS_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW="You need to select a job type first!" COM_CRONJOBS_LABEL_EXEC_TIME="Execution Time (UTC)" -COM_CRONJOBS_LABEL_EXEC_DAY="Execution Day (UTC)" +COM_CRONJOBS_LABEL_EXEC_DAY="Execution Day" diff --git a/administrator/language/en-GB/com_cronjobs.sys.ini b/administrator/language/en-GB/com_cronjobs.sys.ini index e593e66f05f53..adf4e508455f1 100644 --- a/administrator/language/en-GB/com_cronjobs.sys.ini +++ b/administrator/language/en-GB/com_cronjobs.sys.ini @@ -11,6 +11,7 @@ COM_CRONJOBS_TYPE_PLG="Plugin" COM_CRONJOBS_SELECT_TRIGGER="Trigger" COM_CRONJOBS_EMPTYSTATE_CONTENT="No entries!" COM_CRONJOBS_EMPTYSTATE_BUTTON_ADD="Add a Cronjob!" +COM_CRONJOBS_EMPTYSTATE_TITLE="No Cronjobs have been created yet!" COM_CRONJOBS_FIELD_CREATED_BY_LABEL="Created By" COM_CRONJOBS_FIELD_CREATED_LABEL="Created" COM_CRONJOBS_TRIGGER_PSEUDOCRON="Pseudocron" @@ -19,6 +20,7 @@ COM_CRONJOBS_TRIGGER_XVISITS="X-Visits" COM_CRONJOBS_MANAGER_CRONJOBS="Cronjobs Manager" COM_CRONJOBS_MANAGER_CRONJOB="Cronjob Manager" COM_CRONJOBS_MANAGER_CRONJOB_EDIT="Edit Cronjob" +COM_CRONJOBS_MANAGER_CRONJOB_NEW="New Cronjob" COM_CRONJOBS_NEW_CRONJOB="New Cronjob" COM_CRONJOBS_EDIT_CRONJOB="Edit Cronjob" COM_CRONJOBS_FIELDSET_RULES="Rules" @@ -69,4 +71,4 @@ COM_CRONJOBS_SELECT_INTERVAL_DAYS="-- Select Interval in Days --" COM_CRONJOBS_SELECT_INTERVAL_MONTHS="-- Select Interval in Months --" COM_CRONJOBS_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW="You need to select a job type first!" COM_CRONJOBS_LABEL_EXEC_TIME="Execution Time (UTC)" -COM_CRONJOBS_LABEL_EXEC_DAY="Execution Day (UTC)" +COM_CRONJOBS_LABEL_EXEC_DAY="Execution Day" From 925feec2b50d15a8ba9007e9b37c43097c9b3076 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Mon, 2 Aug 2021 04:58:58 +0530 Subject: [PATCH 117/615] Patch CronjobsView empty state The createURL now points to the SelectView --- .../components/com_cronjobs/tmpl/cronjobs/empty_state.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/administrator/components/com_cronjobs/tmpl/cronjobs/empty_state.php b/administrator/components/com_cronjobs/tmpl/cronjobs/empty_state.php index ca703ec5f16d2..6428412a937f4 100644 --- a/administrator/components/com_cronjobs/tmpl/cronjobs/empty_state.php +++ b/administrator/components/com_cronjobs/tmpl/cronjobs/empty_state.php @@ -21,7 +21,7 @@ if (Factory::getApplication()->getIdentity()->authorise('core.create', 'com_cronjobs')) { - $displayData['createURL'] = 'index.php?option=com_cronjobs&task=cronjob.add'; + $displayData['createURL'] = 'index.php?option=com_cronjobs&view=select&layout=default'; } echo LayoutHelper::render('joomla.content.emptystate', $displayData); From 884a21d8ecdd28b32b3e6c8d613a6683cb64fb42 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Mon, 2 Aug 2021 21:10:58 +0530 Subject: [PATCH 118/615] Update language files Adds new constants for the list view --- administrator/language/en-GB/com_cronjobs.ini | 3 +++ administrator/language/en-GB/com_cronjobs.sys.ini | 3 +++ 2 files changed, 6 insertions(+) diff --git a/administrator/language/en-GB/com_cronjobs.ini b/administrator/language/en-GB/com_cronjobs.ini index adf4e508455f1..e69dcdbe61086 100644 --- a/administrator/language/en-GB/com_cronjobs.ini +++ b/administrator/language/en-GB/com_cronjobs.ini @@ -72,3 +72,6 @@ COM_CRONJOBS_SELECT_INTERVAL_MONTHS="-- Select Interval in Months --" COM_CRONJOBS_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW="You need to select a job type first!" COM_CRONJOBS_LABEL_EXEC_TIME="Execution Time (UTC)" COM_CRONJOBS_LABEL_EXEC_DAY="Execution Day" +COM_CRONJOBS_JOB_TYPE="Job Type" +COM_CRONJOBS_JOB_TYPE_ASC="Job Type Ascending" +COM_CRONJOBS_JOB_TYPE_DESC="Job Type Descending" diff --git a/administrator/language/en-GB/com_cronjobs.sys.ini b/administrator/language/en-GB/com_cronjobs.sys.ini index adf4e508455f1..e69dcdbe61086 100644 --- a/administrator/language/en-GB/com_cronjobs.sys.ini +++ b/administrator/language/en-GB/com_cronjobs.sys.ini @@ -72,3 +72,6 @@ COM_CRONJOBS_SELECT_INTERVAL_MONTHS="-- Select Interval in Months --" COM_CRONJOBS_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW="You need to select a job type first!" COM_CRONJOBS_LABEL_EXEC_TIME="Execution Time (UTC)" COM_CRONJOBS_LABEL_EXEC_DAY="Execution Day" +COM_CRONJOBS_JOB_TYPE="Job Type" +COM_CRONJOBS_JOB_TYPE_ASC="Job Type Ascending" +COM_CRONJOBS_JOB_TYPE_DESC="Job Type Descending" From b179c887cd2ac1fea5a8a4134b981ea8ea99505f Mon Sep 17 00:00:00 2001 From: ditsuke Date: Mon, 2 Aug 2021 21:17:55 +0530 Subject: [PATCH 119/615] Update Cronjobs filter form - Removes ref to access - Adds options for ordering by exit code, type title --- .../components/com_cronjobs/forms/filter_cronjobs.xml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/administrator/components/com_cronjobs/forms/filter_cronjobs.xml b/administrator/components/com_cronjobs/forms/filter_cronjobs.xml index 8e6aefb6cf748..95fd9f464f234 100644 --- a/administrator/components/com_cronjobs/forms/filter_cronjobs.xml +++ b/administrator/components/com_cronjobs/forms/filter_cronjobs.xml @@ -46,7 +46,7 @@ - + JSTATUS_DESC - - - + + + + Date: Mon, 2 Aug 2021 22:06:14 +0530 Subject: [PATCH 120/615] Override _getList() in CronjobsModel - Adds the `j.type_title` filter field - Adds the attachCronOptions() method to associate item -> CronOption - Implements ordering by job type title in _getList() override --- .../com_cronjobs/src/Model/CronjobsModel.php | 85 ++++++++++++++++++- 1 file changed, 83 insertions(+), 2 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php index d6e57a231d7bb..5abda650d2d68 100644 --- a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php +++ b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php @@ -64,11 +64,14 @@ public function __construct($config = array(), MVCFactoryInterface $factory = nu 'type', 'a.type', + 'type_title', + 'j.type_title', + 'trigger', 'a.trigger', - 'enabled', - 'a.enabled', + 'state', + 'a.state', 'last_exit_code', 'a.last_exit_code', @@ -173,4 +176,82 @@ protected function getListQuery(): QueryInterface return $query; } + /** + * Overloads the parent _getList() method. + * Takes care of attaching CronOption objects and sorting by type titles. + * + * @param DatabaseQuery $query The database query to get the list with + * @param int $limitstart The list offset + * @param int $limit Number of list items to fetch + * + * @return object[] + * + * @throws Exception + * @since __DEPLOY_VERSION__ + * @codingStandardsIgnoreStart + */ + protected function _getList($query, $limitstart = 0, $limit = 0): array + { + /** @codingStandardsIgnoreEnd */ + + // Get stuff from the model state + $listOrder = $this->getState('list.ordering', 'a.title'); + $listDirectionN = strtolower($this->getState('list.direction', 'desc')) == 'desc' ? -1 : 1; + + // Set limit parameters and get object list + $query->setLimit($limit, $limitstart); + $this->getDbo()->setQuery($query); + $responseList = $this->getDbo()->loadObjectList(); + + // Attach CronOptions objects and a safe type title + $this->attachCronOptions($responseList); + + // If ordering by non-db fields, we need to sort here in code + if ($listOrder == 'j.type_title') + { + $responseList = ArrayHelper::sortObjects($responseList, 'safeTypeTitle', $listDirectionN, true, false); + } + + return $responseList; + } + + /** + * For an array of items, attaches CronOption objects and (safe) type titles to each. + * + * @param array $items Array of items, passed by reference + * + * @return void + * + * @throws Exception + * @since __DEPLOY_VERSION__ + */ + private function attachCronOptions(array &$items): void + { + $cronOptions = CronjobsHelper::getCronOptions(); + + foreach ($items as &$item) + { + // $jobType = $item->job_type; + $item->cronOption = $cronOptions->findOption($item->type); + $item->safeTypeTitle = $item->cronOption->title ?? 'N/A'; + } + } + + /** + * Overload the parent populateState() method. + * ! Does nothing at the moment. + * TODO : Remove if no special handling needed. + * + * @param ?string $ordering Field to order/sort list by + * @param ?string $direction Direction in which to sort list + * + * @return void + * @since __DEPLOY_VERSION__ + */ + protected function populateState($ordering = null, $direction = null): void + { + // TODO: Change the autogenerated stub + parent::populateState($ordering, $direction); + } + } From 33f7d8ad84ea5344083b54fbd4355a0a82e46e08 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Mon, 2 Aug 2021 23:02:15 +0530 Subject: [PATCH 121/615] Implement ordering & filtering in CronjobsModel - Implements ordering by relevant properties - Implements filtering by most properties (due: job type) --- .../com_cronjobs/src/Model/CronjobsModel.php | 82 ++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php index 5abda650d2d68..01fb562c0710d 100644 --- a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php +++ b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php @@ -20,9 +20,14 @@ use Joomla\CMS\Factory; use Joomla\CMS\MVC\Factory\MVCFactoryInterface; use Joomla\CMS\MVC\Model\ListModel; +use Joomla\Component\Cronjobs\Administrator\Helper\CronjobsHelper; +use Joomla\Database\DatabaseQuery; +use Joomla\Database\ParameterType; use Joomla\Database\QueryInterface; +use Joomla\Utilities\ArrayHelper; use function defined; +use function in_array; /** * MVC Model to deal with operations concerning multiple 'Cronjob' entries. @@ -169,9 +174,82 @@ protected function getListQuery(): QueryInterface // ? Does 'list.select' exist ? ); + // From the #__cronjobs table as 'a' $query->from($db->quoteName('#__cronjobs', 'a')); - // TODO : Implement filters and sorting here + // Filter over job type (this should go to _getList()) [! this is not in the filter form yet] + + // Filter over state ---- + $state = $this->getState('filter.state'); + + if (is_numeric($state)) + { + $state = (int) $state; + $query->where($db->quoteName('a.state') . '= :state') + ->bind(':state', $state); + } + + // ! [Are we showing the orphaned pseudo-state by default or no? (handled in _getList())] + + // Filter over exit code + $exitCode = $this->getState('filter.last_exit_code'); + + if (is_numeric($exitCode)) + { + $exitCode = (int) $exitCode; + $query->where($db->quoteName('a.last_exit_code') . '= :last_exit_code') + ->bind(':last_exit_code', $exitCode, ParameterType::INTEGER); + } + + // TODO: Filter over access levels [? should access level be retained] ---- + + // Filter over search string if set (title, type title, note, id) ---- + $searchStr = $this->getState('filter.search'); + + if (!empty($searchStr)) + { + // Allow search by ID + if (\stripos($searchStr, 'id:') === 0) + { + // Add array support [?] + $id = (int) \substr($searchStr, 3); + $query->where($db->quoteName('a.id') . '= :id') + ->bind(':id', $id, ParameterType::INTEGER); + } + // Search by type is handled exceptionally in _getList() [TODO] + elseif (\stripos($searchStr, 'type:') !== 0) + { + // The where clause is extended to allow other filters to act + $query->extendWhere( + 'AND', + [ + $db->quoteName('a.title') . ' LIKE :searchStr', + $db->quoteName('a.note') . 'LIKE : searchStr' + ], + 'OR' + ) + ->bind(':searchStr', $searchStr, ParameterType::STRING); + } + } + + // Add list ordering clause. ---- + $orderCol = $this->state->get('list.ordering', 'a.title'); + $orderDir = $this->state->get('list.direction', 'desc'); + + // Type title ordering is handled exceptionally in _getList() + if ($orderCol !== 'j.type_title') + { + // If ordering by type or state, also order by title. + if (in_array($orderCol, ['a.type', 'a.state'])) + { + // TODO : Test if things are working as expected + $query->order($db->quoteName('a.title') . ' ' . $orderDir); + + // $orderCol = $db->quoteName('a.title') . ' ' . $orderDir . ', ' . $db->quoteName('a.ordering'); + } + + $query->order($db->quoteName($orderCol) . ' ' . $orderDir); + } return $query; } @@ -212,6 +290,8 @@ protected function _getList($query, $limitstart = 0, $limit = 0): array $responseList = ArrayHelper::sortObjects($responseList, 'safeTypeTitle', $listDirectionN, true, false); } + // TODO: Implement filtering by type title here + return $responseList; } From 3501b3591546e4a10238c4b32278d1aa24d12282 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Mon, 2 Aug 2021 23:16:08 +0530 Subject: [PATCH 122/615] Sort language files Sorts language files alphabetically. --- administrator/language/en-GB/com_cronjobs.ini | 116 +++++++++--------- .../language/en-GB/com_cronjobs.sys.ini | 116 +++++++++--------- 2 files changed, 116 insertions(+), 116 deletions(-) diff --git a/administrator/language/en-GB/com_cronjobs.ini b/administrator/language/en-GB/com_cronjobs.ini index e69dcdbe61086..c85d94508efde 100644 --- a/administrator/language/en-GB/com_cronjobs.ini +++ b/administrator/language/en-GB/com_cronjobs.ini @@ -2,76 +2,76 @@ ; (C) 2021 Open Source Matters, Inc. ; GPL v3 COM_CRONJOBS="Cronjobs" -COM_CRONJOBS_XML_DESCRIPTION="Component for managing pseudo-cronjobs and cronjobs (if server supports)" -COM_CRONJOBS_TABLE_CAPTION="Cronjobs List" -COM_CRONJOBS_HEADING_JOB_TYPE="Job Type" -COM_CRONJOBS_SELECT_TYPE="Cronjob Type" -COM_CRONJOBS_TYPE_SCRIPT="CLI Script" -COM_CRONJOBS_TYPE_PLG="Plugin" -COM_CRONJOBS_SELECT_TRIGGER="Trigger" -COM_CRONJOBS_EMPTYSTATE_CONTENT="No entries!" +COM_CRONJOBS_CLI_JOBS_DESC="Configure a CLI script to run at a scheduled interval or another condition." +COM_CRONJOBS_CLI_JOBS_TITLE="CLI/Script Job" +COM_CRONJOBS_EDIT_CRONJOB="Edit Cronjob" COM_CRONJOBS_EMPTYSTATE_BUTTON_ADD="Add a Cronjob!" +COM_CRONJOBS_EMPTYSTATE_CONTENT="No entries!" COM_CRONJOBS_EMPTYSTATE_TITLE="No Cronjobs have been created yet!" +COM_CRONJOBS_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW="You need to select a Job Type first!" +COM_CRONJOBS_ERROR_INVALID_JOB_TYPE="Invalid Job Type!" COM_CRONJOBS_FIELD_CREATED_BY_LABEL="Created By" COM_CRONJOBS_FIELD_CREATED_LABEL="Created" -COM_CRONJOBS_TRIGGER_PSEUDOCRON="Pseudocron" -COM_CRONJOBS_TRIGGER_CRON="Cron" -COM_CRONJOBS_TRIGGER_XVISITS="X-Visits" -COM_CRONJOBS_MANAGER_CRONJOBS="Cronjobs Manager" -COM_CRONJOBS_MANAGER_CRONJOB="Cronjob Manager" -COM_CRONJOBS_MANAGER_CRONJOB_EDIT="Edit Cronjob" -COM_CRONJOBS_MANAGER_CRONJOB_NEW="New Cronjob" -COM_CRONJOBS_NEW_CRONJOB="New Cronjob" -COM_CRONJOBS_EDIT_CRONJOB="Edit Cronjob" -COM_CRONJOBS_FIELDSET_RULES="Rules" -COM_CRONJOBS_FIELDSET_EXEC_HIST="Execution History" -COM_CRONJOBS_FIELDSET_DETAILS="Details" -COM_CRONJOBS_FIELDSET_CRON_OPTIONS="Cron Options" +COM_CRONJOBS_FIELD_JOB_TYPE="Job Type (identifier)" +COM_CRONJOBS_FIELD_LABEL_EXEC_RULE="Execution Rule" +COM_CRONJOBS_FIELD_LABEL_INTERVAL_DAYS="Interval in Days" +COM_CRONJOBS_FIELD_LABEL_INTERVAL_HOURS="Interval in Hours" +COM_CRONJOBS_FIELD_LABEL_INTERVAL_MINUTES="Interval in Minutes" +COM_CRONJOBS_FIELD_LABEL_INTERVAL_MONTHS="Interval in Months" +COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_DAYS_M="Days of Month" +COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_DAYS_W="Days of Week" +COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_HOURS="Hours" +COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_MINUTES="Minutes" +COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_MONTHS="Months" COM_CRONJOBS_FIELDSET_BASIC="Basic Fields" -COM_CRONJOBS_LABEL_HOURS="Hours" -COM_CRONJOBS_LABEL_MINUTES="Minutes" +COM_CRONJOBS_FIELDSET_CRON_OPTIONS="Cron Options" +COM_CRONJOBS_FIELDSET_DETAILS="Details" +COM_CRONJOBS_FIELDSET_EXEC_HIST="Execution History" +COM_CRONJOBS_FIELDSET_RULES="Rules" +COM_CRONJOBS_FORM_TITLE_EDIT="Edit Cronjob" +COM_CRONJOBS_FORM_TITLE_NEW="New Cronjob" +COM_CRONJOBS_HEADING_JOB_TYPE="Job Type" +COM_CRONJOBS_JOB_TYPE="Job Type" +COM_CRONJOBS_JOB_TYPE_ASC="Job Type Ascending" +COM_CRONJOBS_JOB_TYPE_DESC="Job Type Descending" +COM_CRONJOBS_LABEL_EXEC_DAY="Execution Day" +COM_CRONJOBS_LABEL_EXEC_INTERVAL="Execution Interval" +COM_CRONJOBS_LABEL_EXEC_TIME="Execution Time (UTC)" COM_CRONJOBS_LABEL_EXIT_CODE="Last Exit Code" +COM_CRONJOBS_LABEL_HOURS="Hours" COM_CRONJOBS_LABEL_LAST_EXEC="Last Executed" +COM_CRONJOBS_LABEL_MINUTES="Minutes" COM_CRONJOBS_LABEL_NEXT_EXEC="Next Execution" +COM_CRONJOBS_LABEL_NOTES="Notes" +COM_CRONJOBS_LABEL_PLG_JOB_ID="Plugin Job ID" COM_CRONJOBS_LABEL_TIMES_EXEC="Times Executed" COM_CRONJOBS_LABEL_TIMES_FAIL="Times Failed" -COM_CRONJOBS_LABEL_NOTES="Notes" -COM_CRONJOBS_FORM_TITLE_NEW="New Cronjob" -COM_CRONJOBS_FORM_TITLE_EDIT="Edit Cronjob" -COM_CRONJOBS_TYPE_CHOOSE="Select a Job type" +COM_CRONJOBS_MANAGER_CRONJOB="Cronjob Manager" +COM_CRONJOBS_MANAGER_CRONJOB_EDIT="Edit Cronjob" +COM_CRONJOBS_MANAGER_CRONJOB_NEW="New Cronjob" +COM_CRONJOBS_MANAGER_CRONJOBS="Cronjobs Manager" COM_CRONJOBS_MSG_MANAGE_NO_JOB_PLUGINS="There are no plugin jobs matching your query" -COM_CRONJOBS_SELECT_PLG_JOB="Select job, %s" -COM_CRONJOBS_CLI_JOBS_TITLE="CLI/Script Job" -COM_CRONJOBS_CLI_JOBS_DESC="Configure a CLI script to run at a scheduled interval or another condition." -COM_CRONJOBS_SELECT_CLI_JOB="Select CLI job" -COM_CRONJOBS_ERROR_INVALID_JOB_TYPE="Invalid Job Type!" -COM_CRONJOBS_LABEL_EXEC_INTERVAL="Execution Interval" -COM_CRONJOBS_LABEL_PLG_JOB_ID="Plugin Job ID" -COM_CRONJOBS_FIELD_JOB_TYPE="Job Type (identifier)" -COM_CRONJOBS_FIELD_LABEL_EXEC_RULE="Execution Rule" -COM_CRONJOBS_SELECT_EXEC_RULE="--- Select Rule ---" -COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_MINUTES="Minutes" -COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_HOURS="Hours" -COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_DAYS_M="Days of Month" -COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_MONTHS="Months" -COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_DAYS_W="Days of Week" -COM_CRONJOBS_TYPE_OR_SELECT_OPTIONS="Type or select options" -COM_CRONJOBS_OPTION_INTERVAL_MINUTES="Interval, Minutes" -COM_CRONJOBS_OPTION_INTERVAL_HOURS="Interval, Hours" +COM_CRONJOBS_NEW_CRONJOB="New Cronjob" +COM_CRONJOBS_OPTION_INTERVAL_CUSTOM="Custom Match (Advanced)" COM_CRONJOBS_OPTION_INTERVAL_DAYS="Interval, Days" +COM_CRONJOBS_OPTION_INTERVAL_HOURS="Interval, Hours" +COM_CRONJOBS_OPTION_INTERVAL_MINUTES="Interval, Minutes" COM_CRONJOBS_OPTION_INTERVAL_MONTHS="Interval, Months" -COM_CRONJOBS_OPTION_INTERVAL_CUSTOM="Custom Match (Advanced)" -COM_CRONJOBS_FIELD_LABEL_INTERVAL_MINUTES="Interval in Minutes" -COM_CRONJOBS_FIELD_LABEL_INTERVAL_HOURS="Interval in Hours" -COM_CRONJOBS_FIELD_LABEL_INTERVAL_DAYS="Interval in Days" -COM_CRONJOBS_FIELD_LABEL_INTERVAL_MONTHS="Interval in Months" -COM_CRONJOBS_SELECT_INTERVAL_MINUTES="-- Select Interval in Minutes --" -COM_CRONJOBS_SELECT_INTERVAL_HOURS="-- Select Interval in Hours --" +COM_CRONJOBS_SELECT_CLI_JOB="Select CLI job" +COM_CRONJOBS_SELECT_EXEC_RULE="--- Select Rule ---" COM_CRONJOBS_SELECT_INTERVAL_DAYS="-- Select Interval in Days --" +COM_CRONJOBS_SELECT_INTERVAL_HOURS="-- Select Interval in Hours --" +COM_CRONJOBS_SELECT_INTERVAL_MINUTES="-- Select Interval in Minutes --" COM_CRONJOBS_SELECT_INTERVAL_MONTHS="-- Select Interval in Months --" -COM_CRONJOBS_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW="You need to select a job type first!" -COM_CRONJOBS_LABEL_EXEC_TIME="Execution Time (UTC)" -COM_CRONJOBS_LABEL_EXEC_DAY="Execution Day" -COM_CRONJOBS_JOB_TYPE="Job Type" -COM_CRONJOBS_JOB_TYPE_ASC="Job Type Ascending" -COM_CRONJOBS_JOB_TYPE_DESC="Job Type Descending" +COM_CRONJOBS_SELECT_PLG_JOB="Select job, %s" +COM_CRONJOBS_SELECT_TRIGGER="Trigger" +COM_CRONJOBS_SELECT_TYPE="Cronjob Type" +COM_CRONJOBS_TABLE_CAPTION="Cronjobs List" +COM_CRONJOBS_TRIGGER_CRON="Cron" +COM_CRONJOBS_TRIGGER_PSEUDOCRON="Pseudocron" +COM_CRONJOBS_TRIGGER_XVISITS="X-Visits" +COM_CRONJOBS_TYPE_CHOOSE="Select a Job type" +COM_CRONJOBS_TYPE_OR_SELECT_OPTIONS="Type or select options" +COM_CRONJOBS_TYPE_PLG="Plugin" +COM_CRONJOBS_TYPE_SCRIPT="CLI Script" +COM_CRONJOBS_XML_DESCRIPTION="Component for managing pseudo-cronjobs and cronjobs (if server supports)" diff --git a/administrator/language/en-GB/com_cronjobs.sys.ini b/administrator/language/en-GB/com_cronjobs.sys.ini index e69dcdbe61086..c85d94508efde 100644 --- a/administrator/language/en-GB/com_cronjobs.sys.ini +++ b/administrator/language/en-GB/com_cronjobs.sys.ini @@ -2,76 +2,76 @@ ; (C) 2021 Open Source Matters, Inc. ; GPL v3 COM_CRONJOBS="Cronjobs" -COM_CRONJOBS_XML_DESCRIPTION="Component for managing pseudo-cronjobs and cronjobs (if server supports)" -COM_CRONJOBS_TABLE_CAPTION="Cronjobs List" -COM_CRONJOBS_HEADING_JOB_TYPE="Job Type" -COM_CRONJOBS_SELECT_TYPE="Cronjob Type" -COM_CRONJOBS_TYPE_SCRIPT="CLI Script" -COM_CRONJOBS_TYPE_PLG="Plugin" -COM_CRONJOBS_SELECT_TRIGGER="Trigger" -COM_CRONJOBS_EMPTYSTATE_CONTENT="No entries!" +COM_CRONJOBS_CLI_JOBS_DESC="Configure a CLI script to run at a scheduled interval or another condition." +COM_CRONJOBS_CLI_JOBS_TITLE="CLI/Script Job" +COM_CRONJOBS_EDIT_CRONJOB="Edit Cronjob" COM_CRONJOBS_EMPTYSTATE_BUTTON_ADD="Add a Cronjob!" +COM_CRONJOBS_EMPTYSTATE_CONTENT="No entries!" COM_CRONJOBS_EMPTYSTATE_TITLE="No Cronjobs have been created yet!" +COM_CRONJOBS_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW="You need to select a Job Type first!" +COM_CRONJOBS_ERROR_INVALID_JOB_TYPE="Invalid Job Type!" COM_CRONJOBS_FIELD_CREATED_BY_LABEL="Created By" COM_CRONJOBS_FIELD_CREATED_LABEL="Created" -COM_CRONJOBS_TRIGGER_PSEUDOCRON="Pseudocron" -COM_CRONJOBS_TRIGGER_CRON="Cron" -COM_CRONJOBS_TRIGGER_XVISITS="X-Visits" -COM_CRONJOBS_MANAGER_CRONJOBS="Cronjobs Manager" -COM_CRONJOBS_MANAGER_CRONJOB="Cronjob Manager" -COM_CRONJOBS_MANAGER_CRONJOB_EDIT="Edit Cronjob" -COM_CRONJOBS_MANAGER_CRONJOB_NEW="New Cronjob" -COM_CRONJOBS_NEW_CRONJOB="New Cronjob" -COM_CRONJOBS_EDIT_CRONJOB="Edit Cronjob" -COM_CRONJOBS_FIELDSET_RULES="Rules" -COM_CRONJOBS_FIELDSET_EXEC_HIST="Execution History" -COM_CRONJOBS_FIELDSET_DETAILS="Details" -COM_CRONJOBS_FIELDSET_CRON_OPTIONS="Cron Options" +COM_CRONJOBS_FIELD_JOB_TYPE="Job Type (identifier)" +COM_CRONJOBS_FIELD_LABEL_EXEC_RULE="Execution Rule" +COM_CRONJOBS_FIELD_LABEL_INTERVAL_DAYS="Interval in Days" +COM_CRONJOBS_FIELD_LABEL_INTERVAL_HOURS="Interval in Hours" +COM_CRONJOBS_FIELD_LABEL_INTERVAL_MINUTES="Interval in Minutes" +COM_CRONJOBS_FIELD_LABEL_INTERVAL_MONTHS="Interval in Months" +COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_DAYS_M="Days of Month" +COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_DAYS_W="Days of Week" +COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_HOURS="Hours" +COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_MINUTES="Minutes" +COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_MONTHS="Months" COM_CRONJOBS_FIELDSET_BASIC="Basic Fields" -COM_CRONJOBS_LABEL_HOURS="Hours" -COM_CRONJOBS_LABEL_MINUTES="Minutes" +COM_CRONJOBS_FIELDSET_CRON_OPTIONS="Cron Options" +COM_CRONJOBS_FIELDSET_DETAILS="Details" +COM_CRONJOBS_FIELDSET_EXEC_HIST="Execution History" +COM_CRONJOBS_FIELDSET_RULES="Rules" +COM_CRONJOBS_FORM_TITLE_EDIT="Edit Cronjob" +COM_CRONJOBS_FORM_TITLE_NEW="New Cronjob" +COM_CRONJOBS_HEADING_JOB_TYPE="Job Type" +COM_CRONJOBS_JOB_TYPE="Job Type" +COM_CRONJOBS_JOB_TYPE_ASC="Job Type Ascending" +COM_CRONJOBS_JOB_TYPE_DESC="Job Type Descending" +COM_CRONJOBS_LABEL_EXEC_DAY="Execution Day" +COM_CRONJOBS_LABEL_EXEC_INTERVAL="Execution Interval" +COM_CRONJOBS_LABEL_EXEC_TIME="Execution Time (UTC)" COM_CRONJOBS_LABEL_EXIT_CODE="Last Exit Code" +COM_CRONJOBS_LABEL_HOURS="Hours" COM_CRONJOBS_LABEL_LAST_EXEC="Last Executed" +COM_CRONJOBS_LABEL_MINUTES="Minutes" COM_CRONJOBS_LABEL_NEXT_EXEC="Next Execution" +COM_CRONJOBS_LABEL_NOTES="Notes" +COM_CRONJOBS_LABEL_PLG_JOB_ID="Plugin Job ID" COM_CRONJOBS_LABEL_TIMES_EXEC="Times Executed" COM_CRONJOBS_LABEL_TIMES_FAIL="Times Failed" -COM_CRONJOBS_LABEL_NOTES="Notes" -COM_CRONJOBS_FORM_TITLE_NEW="New Cronjob" -COM_CRONJOBS_FORM_TITLE_EDIT="Edit Cronjob" -COM_CRONJOBS_TYPE_CHOOSE="Select a Job type" +COM_CRONJOBS_MANAGER_CRONJOB="Cronjob Manager" +COM_CRONJOBS_MANAGER_CRONJOB_EDIT="Edit Cronjob" +COM_CRONJOBS_MANAGER_CRONJOB_NEW="New Cronjob" +COM_CRONJOBS_MANAGER_CRONJOBS="Cronjobs Manager" COM_CRONJOBS_MSG_MANAGE_NO_JOB_PLUGINS="There are no plugin jobs matching your query" -COM_CRONJOBS_SELECT_PLG_JOB="Select job, %s" -COM_CRONJOBS_CLI_JOBS_TITLE="CLI/Script Job" -COM_CRONJOBS_CLI_JOBS_DESC="Configure a CLI script to run at a scheduled interval or another condition." -COM_CRONJOBS_SELECT_CLI_JOB="Select CLI job" -COM_CRONJOBS_ERROR_INVALID_JOB_TYPE="Invalid Job Type!" -COM_CRONJOBS_LABEL_EXEC_INTERVAL="Execution Interval" -COM_CRONJOBS_LABEL_PLG_JOB_ID="Plugin Job ID" -COM_CRONJOBS_FIELD_JOB_TYPE="Job Type (identifier)" -COM_CRONJOBS_FIELD_LABEL_EXEC_RULE="Execution Rule" -COM_CRONJOBS_SELECT_EXEC_RULE="--- Select Rule ---" -COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_MINUTES="Minutes" -COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_HOURS="Hours" -COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_DAYS_M="Days of Month" -COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_MONTHS="Months" -COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_DAYS_W="Days of Week" -COM_CRONJOBS_TYPE_OR_SELECT_OPTIONS="Type or select options" -COM_CRONJOBS_OPTION_INTERVAL_MINUTES="Interval, Minutes" -COM_CRONJOBS_OPTION_INTERVAL_HOURS="Interval, Hours" +COM_CRONJOBS_NEW_CRONJOB="New Cronjob" +COM_CRONJOBS_OPTION_INTERVAL_CUSTOM="Custom Match (Advanced)" COM_CRONJOBS_OPTION_INTERVAL_DAYS="Interval, Days" +COM_CRONJOBS_OPTION_INTERVAL_HOURS="Interval, Hours" +COM_CRONJOBS_OPTION_INTERVAL_MINUTES="Interval, Minutes" COM_CRONJOBS_OPTION_INTERVAL_MONTHS="Interval, Months" -COM_CRONJOBS_OPTION_INTERVAL_CUSTOM="Custom Match (Advanced)" -COM_CRONJOBS_FIELD_LABEL_INTERVAL_MINUTES="Interval in Minutes" -COM_CRONJOBS_FIELD_LABEL_INTERVAL_HOURS="Interval in Hours" -COM_CRONJOBS_FIELD_LABEL_INTERVAL_DAYS="Interval in Days" -COM_CRONJOBS_FIELD_LABEL_INTERVAL_MONTHS="Interval in Months" -COM_CRONJOBS_SELECT_INTERVAL_MINUTES="-- Select Interval in Minutes --" -COM_CRONJOBS_SELECT_INTERVAL_HOURS="-- Select Interval in Hours --" +COM_CRONJOBS_SELECT_CLI_JOB="Select CLI job" +COM_CRONJOBS_SELECT_EXEC_RULE="--- Select Rule ---" COM_CRONJOBS_SELECT_INTERVAL_DAYS="-- Select Interval in Days --" +COM_CRONJOBS_SELECT_INTERVAL_HOURS="-- Select Interval in Hours --" +COM_CRONJOBS_SELECT_INTERVAL_MINUTES="-- Select Interval in Minutes --" COM_CRONJOBS_SELECT_INTERVAL_MONTHS="-- Select Interval in Months --" -COM_CRONJOBS_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW="You need to select a job type first!" -COM_CRONJOBS_LABEL_EXEC_TIME="Execution Time (UTC)" -COM_CRONJOBS_LABEL_EXEC_DAY="Execution Day" -COM_CRONJOBS_JOB_TYPE="Job Type" -COM_CRONJOBS_JOB_TYPE_ASC="Job Type Ascending" -COM_CRONJOBS_JOB_TYPE_DESC="Job Type Descending" +COM_CRONJOBS_SELECT_PLG_JOB="Select job, %s" +COM_CRONJOBS_SELECT_TRIGGER="Trigger" +COM_CRONJOBS_SELECT_TYPE="Cronjob Type" +COM_CRONJOBS_TABLE_CAPTION="Cronjobs List" +COM_CRONJOBS_TRIGGER_CRON="Cron" +COM_CRONJOBS_TRIGGER_PSEUDOCRON="Pseudocron" +COM_CRONJOBS_TRIGGER_XVISITS="X-Visits" +COM_CRONJOBS_TYPE_CHOOSE="Select a Job type" +COM_CRONJOBS_TYPE_OR_SELECT_OPTIONS="Type or select options" +COM_CRONJOBS_TYPE_PLG="Plugin" +COM_CRONJOBS_TYPE_SCRIPT="CLI Script" +COM_CRONJOBS_XML_DESCRIPTION="Component for managing pseudo-cronjobs and cronjobs (if server supports)" From 85bada2c02f974f1a4b8c0f016ad496408775a52 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 25 Jul 2021 15:26:16 +0530 Subject: [PATCH 123/615] Fix CronjobsController namespace --- .../com_cronjobs/src/Controller/CronjobsController.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/administrator/components/com_cronjobs/src/Controller/CronjobsController.php b/administrator/components/com_cronjobs/src/Controller/CronjobsController.php index 695524a406cd9..a5e9344d20b65 100644 --- a/administrator/components/com_cronjobs/src/Controller/CronjobsController.php +++ b/administrator/components/com_cronjobs/src/Controller/CronjobsController.php @@ -9,6 +9,8 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt */ + namespace Joomla\Component\Cronjobs\Administrator\Controller; + // Restrict direct access \defined('_JEXEC') or die; From 45c9482d0f46fbf50702c08050994019c1856f8a Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 25 Jul 2021 15:26:39 +0530 Subject: [PATCH 124/615] Add Fields to support Cronjob form --- .../src/Field/IntervalTypesField.php | 69 ++++++++ .../com_cronjobs/src/Field/IntervalsField.php | 167 ++++++++++++++++++ 2 files changed, 236 insertions(+) create mode 100644 administrator/components/com_cronjobs/src/Field/IntervalTypesField.php create mode 100644 administrator/components/com_cronjobs/src/Field/IntervalsField.php diff --git a/administrator/components/com_cronjobs/src/Field/IntervalTypesField.php b/administrator/components/com_cronjobs/src/Field/IntervalTypesField.php new file mode 100644 index 0000000000000..58ffbb999b2bd --- /dev/null +++ b/administrator/components/com_cronjobs/src/Field/IntervalTypesField.php @@ -0,0 +1,69 @@ + + * @license GPL v3 + */ + +namespace Joomla\Component\Cronjobs\Administrator\Field; + +// Restrict direct access +defined('_JEXEC') or die; + +use Joomla\CMS\Form\Field\ListField; +use Joomla\CMS\Form\Field\RadioField; +use Joomla\CMS\HTML\HTMLHelper; +use Joomla\CMS\Language\Text; + +/** + * A select list containing valid Cron interval types. + * + * @since __DEPLOY_VERSION__ + */ +class IntervalTypesField extends ListField +{ + /** + * The form field type. + * + * @var string + * @since __DEPLOY_VERSION__ + */ + protected $type = 'intervalType'; + + /** + * @var string[] + * @since __DEPLOY_VERSION__ + */ + private $responseMap = [ + 'minutes' => 'COM_CRONJOBS_FIELD_OPTION_INTERVAL_MINUTES', + 'hours' => 'COM_CRONJOBS_FIELD_OPTION_INTERVAL_HOURS', + 'days_month' => 'COM_CRONJOBS_FIELD_OPTION_INTERVAL_DAYS_M', + 'months' => 'COM_CRONJOBS_FIELD_OPTION_INTERVAL_MONTHS', + 'days_week' => 'COM_CRONJOBS_FIELD_OPTION_INTERVAL_DAYS_W' + ]; + + public function __construct($form = null) + { + parent::__construct($form); + } + + /** + * + * @return array Array of objects representing options in the options list + * + * @since __DEPLOY_VERSION__ + */ + protected function getOptions(): array + { + $options = []; + + foreach ($this->responseMap as $value => $label) + { + $options[] = HTMLHelper::_('select.option', $value, Text::_($label)); + } + + return $options; + } +} diff --git a/administrator/components/com_cronjobs/src/Field/IntervalsField.php b/administrator/components/com_cronjobs/src/Field/IntervalsField.php new file mode 100644 index 0000000000000..7e0c4f65c192f --- /dev/null +++ b/administrator/components/com_cronjobs/src/Field/IntervalsField.php @@ -0,0 +1,167 @@ + + * @license GPL v3 + */ + +namespace Joomla\Component\Cronjobs\Administrator\Field; + +// Restrict direct access +defined('_JEXEC') or die; + +use Joomla\CMS\Form\Field\ListField; +use Joomla\CMS\HTML\HTMLHelper; +use Joomla\CMS\Language\Text; +use SimpleXMLElement; +use function in_array; + +/** + * Multi-select form field, supporting inputs of: + * minutes, hours, . + * + * @since __DEPLOY_VERSION__ + */ +class IntervalsField extends ListField +{ + /** + * The form field type. + * + * @var string + * @since __DEPLOY_VERSION__ + */ + protected $type = 'cronIntervals'; + + /** + * The subtypes supported by this field type. + * + * @var string[] + * @since __DEPLOY_VERSION__ + */ + private static $subtypes = [ + 'minutes', + 'hours', + 'days_month', + 'months', + 'days_week' + ]; + + /** + * Response labels for the 'month' and 'days_week' subtypes + * + * @var string[][] + * @since __DEPLOY_VERSION__ + */ + private static $preparedResponseLabels = [ + 'months' => [ + 'JANUARY', 'FEBRUARY', 'MARCH', 'APRIL', 'MAY', 'JUNE', + 'JULY', 'AUGUST', 'SEPTEMBER', 'OCTOBER', 'NOVEMBER', 'DECEMBER' + ], + 'days_week' => [ + 'MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', + 'FRIDAY', 'SATURDAY', 'SUNDAY' + ] + ]; + + /** + * For options without explicit labels, count of options + * + * @var int[] + * @since __DEPLOY_VERSION__ + */ + private static $optionsCount = [ + 'minutes' => 59, + 'hours' => 23, + 'days_month' => 31 + ]; + + /** + * The subtype of the CronIntervals field + * + * @var string + * @since __DEPLOY_VERSION__ + */ + private $subtype; + + /** + * The multiple attribute is enabled by default. + * + * @var boolean + * @since __DEPLOY_VERSION__ + */ + protected $multiple = true; + + /** + * Override the parent method to set deal with subtypes. + * + * @param SimpleXMLElement $element The SimpleXMLElement object representing the `` tag for the form field object. + * @param mixed $value The form field value to validate. + * @param string $group The field name group control value. This acts as as an array container for the field. + * For example if the field has name="foo" and the group value is set to "bar" then the + * full field name would end up being "bar[foo]". + * + * @return boolean True on success. + * + * @since __DEPLOY_VERSION__ + */ + public function setup(SimpleXMLElement $element, $value, $group = null): bool + { + $parentResult = parent::setup($element, $value, $group); + + $subtype = (string) $element['subtype'] ?? null; + + if (!($subtype && in_array($subtype, self::$subtypes))) + { + return false; + } + + $this->subtype = $subtype; + $this->multiple = true; + $element['multiple'] = $element['multiple'] ?? 'true'; + + return $parentResult; + } + + /** + * + * @return array Array of objects representing options in the options list + * + * @since __DEPLOY_VERSION__ + */ + protected function getOptions() + { + $subtype = $this->subtype; + $options = []; + + if (!in_array($subtype, self::$subtypes)) + { + return $options; + } + + $options[] = HTMLHelper::_('select.option', '*', '*'); + + if (array_key_exists($subtype, self::$preparedResponseLabels)) + { + $labels = self::$preparedResponseLabels[$subtype]; + $responseCount = count($labels); + + for ($i = 0; $i < $responseCount; $i++) + { + $options[] = HTMLHelper::_('select.option', $i, Text::_($labels[$i])); + } + } + elseif (array_key_exists($subtype, self::$optionsCount)) + { + $responseCount = self::$optionsCount[$subtype]; + + for ($i = 0; $i < $responseCount; $i++) + { + $options[] = HTMLHelper::_('select.option', $i, (string) ($i + 1)); + } + } + + return $options; + } +} From 04ae4fabec4ff05d8865c96a908707ed0340a686 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 25 Jul 2021 15:53:08 +0530 Subject: [PATCH 125/615] Switch to FancySelect for IntervalsField --- .../layouts/Joomla/form/field/interval.php | 129 ++++++++++++++++++ .../com_cronjobs/src/Field/IntervalsField.php | 8 ++ 2 files changed, 137 insertions(+) create mode 100644 administrator/components/com_cronjobs/layouts/Joomla/form/field/interval.php diff --git a/administrator/components/com_cronjobs/layouts/Joomla/form/field/interval.php b/administrator/components/com_cronjobs/layouts/Joomla/form/field/interval.php new file mode 100644 index 0000000000000..351fbc79dcc4e --- /dev/null +++ b/administrator/components/com_cronjobs/layouts/Joomla/form/field/interval.php @@ -0,0 +1,129 @@ + + * @license GPL v3 + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Application\AdministratorApplication; +use Joomla\CMS\Factory; +use Joomla\CMS\HTML\HTMLHelper; +use Joomla\CMS\Language\Text; + +extract($displayData); + +/** + * Layout variables + * ----------------- + * @var string $autocomplete Autocomplete attribute for the field. + * @var boolean $autofocus Is autofocus enabled? + * @var string $class Classes for the input. + * @var string $description Description of the field. + * @var boolean $disabled Is this field disabled? + * @var string $group Group the field belongs to. section in form XML. + * @var boolean $hidden Is this field hidden in the form? + * @var string $hint Placeholder for the field. + * @var string $id DOM id of the field. + * @var string $label Label of the field. + * @var string $labelclass Classes to apply to the label. + * @var boolean $multiple Does this field support multiple values? + * @var string $name Name of the input field. + * @var string $onchange Onchange attribute for the field. + * @var string $onclick Onclick attribute for the field. + * @var string $pattern Pattern (Reg Ex) of value of the form field. + * @var boolean $readonly Is this field read only? + * @var boolean $repeat Allows extensions to duplicate elements. + * @var boolean $required Is this field required? + * @var integer $size Size attribute of the input. + * @var boolean $spellcheck Spellcheck state for the form field. + * @var string $validate Validation rules to apply. + * @var string $value Value attribute of the field. + * @var array $checkedOptions Options that will be set as checked. + * @var boolean $hasValue Has this field a value assigned? + * @var array $options Options available for this field. + * @var array $inputType Options available for this field. + * @var boolean $allowCustom Flag, to allow add custom values + * @var integer $minTermLength Minimum length of the term to start searching + * @var string $dataAttribute Miscellaneous data attributes preprocessed for HTML output + * @var array $dataAttributes Miscellaneous data attributes for eg, data-*. + */ + +$html = array(); +$attr = ''; + +// Initialize some field attributes. +$attr .= $multiple ? ' multiple' : ''; +$attr .= $autofocus ? ' autofocus' : ''; +$attr .= $onchange ? ' onchange="' . $onchange . '"' : ''; +$attr .= $dataAttribute; + +// To avoid user's confusion, readonly="readonly" should imply disabled="disabled". +if ($readonly || $disabled) +{ + $attr .= ' disabled="disabled"'; +} + +$attr2 = ''; +$attr2 .= !empty($class) ? ' class="' . $class . '"' : ''; +$attr2 .= ' placeholder="' . $this->escape($hint ?: Text::_('COM_CRONJOBS_TYPE_OR_SELECT_OPTIONS')) . '" '; +$attr2 .= $dataAttribute; + +if ($required) +{ + $attr .= ' required class="required"'; + $attr2 .= ' required'; +} + +// Create a read-only list (no name) with hidden input(s) to store the value(s). +if ($readonly) +{ + $html[] = HTMLHelper::_('select.genericlist', $options, '', trim($attr), 'value', 'text', $value, $id); + + // E.g. form field type tag sends $this->value as array + if ($multiple && is_array($value)) + { + if (!count($value)) + { + $value[] = ''; + } + + foreach ($value as $val) + { + $html[] = ''; + } + } + else + { + $html[] = ''; + } +} +else +// Create a regular list. +{ + $html[] = HTMLHelper::_('select.genericlist', $options, $name, trim($attr), 'value', 'text', $value, $id); +} + +Text::script('JGLOBAL_SELECT_NO_RESULTS_MATCH'); +Text::script('JGLOBAL_SELECT_PRESS_TO_SELECT'); + +/** @var AdministratorApplication $app */ +try +{ + $app = Factory::getApplication(); +} +catch (Exception $e) +{ + die('Could not get application object'); +} + +$app->getDocument()->getWebAssetManager() + ->usePreset('choicesjs') + ->useScript('webcomponent.field-fancy-select'); + +?> + +> diff --git a/administrator/components/com_cronjobs/src/Field/IntervalsField.php b/administrator/components/com_cronjobs/src/Field/IntervalsField.php index 7e0c4f65c192f..39cef13778646 100644 --- a/administrator/components/com_cronjobs/src/Field/IntervalsField.php +++ b/administrator/components/com_cronjobs/src/Field/IntervalsField.php @@ -34,6 +34,14 @@ class IntervalsField extends ListField */ protected $type = 'cronIntervals'; + /** + * Layout used to render the field + * + * @var string + * @since __DEPLOY_VERSION__ + */ + protected $layout = 'joomla.form.field.interval'; + /** * The subtypes supported by this field type. * From 58951ec8262863a4c7dc353a4a95ff05948dd745 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 25 Jul 2021 15:58:14 +0530 Subject: [PATCH 126/615] Update Cronjob form - Switches to the new IntervalsField - Adds the same interval options as Cron (DB, Model pending update) - Switches to a new field group for intervals --- .../components/com_cronjobs/forms/cronjob.xml | 39 ++++++++++++++++--- .../com_cronjobs/tmpl/cronjob/edit.php | 11 ++++-- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/administrator/components/com_cronjobs/forms/cronjob.xml b/administrator/components/com_cronjobs/forms/cronjob.xml index c24a4e1e188ca..807f8c110da55 100644 --- a/administrator/components/com_cronjobs/forms/cronjob.xml +++ b/administrator/components/com_cronjobs/forms/cronjob.xml @@ -1,7 +1,7 @@ - + -
- - + + <!– TODO : JS and submission validation. Minutes >= 1 if Hours == 0 –> -
+ -->
@@ -120,6 +120,33 @@ /> + + + +
+ + + + + + + + +
+
+ + +
+ + form->renderFieldset('interval'); ?>
@@ -151,5 +155,4 @@ class="form-validate"> - From a616914efd1d7a0fdceb191f7f4df110bdb316a4 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 25 Jul 2021 23:42:55 +0530 Subject: [PATCH 127/615] Update database table Changes execution_interval column to TEXT --- .../components/com_admin/sql/updates/mysql/4.1.0-2021-07-25.sql | 2 ++ .../com_admin/sql/updates/postgresql/4.1.0-2021-07-25.sql | 2 ++ installation/sql/mysql/extensions.sql | 2 +- installation/sql/postgresql/extensions.sql | 2 +- 4 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-25.sql create mode 100644 administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-25.sql diff --git a/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-25.sql b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-25.sql new file mode 100644 index 0000000000000..9786c8c3b2edf --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-25.sql @@ -0,0 +1,2 @@ +ALTER TABLE `#__cronjobs` + MODIFY COLUMN `execution_interval` text COMMENT 'Configured execution interval, cron format'; diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-25.sql b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-25.sql new file mode 100644 index 0000000000000..2cccaf8e2caca --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-25.sql @@ -0,0 +1,2 @@ +ALTER TABLE "#__cronjobs" + ALTER COLUMN "execution_interval" TYPE text; diff --git a/installation/sql/mysql/extensions.sql b/installation/sql/mysql/extensions.sql index 7022e87d98a0c..a16e9cd2606ad 100644 --- a/installation/sql/mysql/extensions.sql +++ b/installation/sql/mysql/extensions.sql @@ -897,7 +897,7 @@ CREATE TABLE IF NOT EXISTS `#__cronjobs` ( `type` varchar(1024) NOT NULL COMMENT 'unique identifier for job defined by plugin', -- Trigger type, default to PseudoCron (compatible everywhere). `trigger` enum ('pseudo_cron', 'cron', 'visit_count') NOT NULL DEFAULT 'pseudo_cron' COMMENT 'Defines how job is triggered', - `execution_interval` time NOT NULL COMMENT 'Configured time between executions,in HH:MM:SS format', + `execution_interval` text COMMENT 'Configured execution interval, cron format', `state` tinyint NOT NULL DEFAULT FALSE, `last_exit_code` int NOT NULL DEFAULT '0' COMMENT 'Exit code when job was last run', `last_execution` datetime COMMENT 'Timestamp of last run', diff --git a/installation/sql/postgresql/extensions.sql b/installation/sql/postgresql/extensions.sql index 3acf6d8c1c61a..19ce315143f83 100644 --- a/installation/sql/postgresql/extensions.sql +++ b/installation/sql/postgresql/extensions.sql @@ -858,7 +858,7 @@ CREATE TABLE IF NOT EXISTS "#__cronjobs" "asset_id" bigint NOT NULL DEFAULT '0', "title" varchar(255) NOT NULL, "type" varchar(1024) NOT NULL, - "execution_interval" interval NOT NULL, + "execution_interval" text, "trigger" varchar(12) NOT NULL DEFAULT 'pseudo_cron', "state" smallint NOT NULL DEFAULT '0', "last_exit_code" int NOT NULL DEFAULT '0', From 3d95b86010fede6f0a1f25fad7f6ed16652566ad Mon Sep 17 00:00:00 2001 From: ditsuke Date: Tue, 27 Jul 2021 19:03:28 +0530 Subject: [PATCH 128/615] Update Cronjob form and IntervalsField - To Cronjob form: - Adds friendly intervals (hours, minutes, days...) as rules. - Delegates custom Cron-style matches to an "Advanced" option. - To IntervalsField: - Adds support for custom options. - Adds `wildcard` and `onlyNumericLabels` attributes. - Removes fancyselect, as it didn't look apt for the use. --- .../components/com_cronjobs/forms/cronjob.xml | 67 +++++++++++-------- .../com_cronjobs/src/Field/IntervalsField.php | 43 ++++++++---- 2 files changed, 70 insertions(+), 40 deletions(-) diff --git a/administrator/components/com_cronjobs/forms/cronjob.xml b/administrator/components/com_cronjobs/forms/cronjob.xml index 807f8c110da55..bc73b364d030e 100644 --- a/administrator/components/com_cronjobs/forms/cronjob.xml +++ b/administrator/components/com_cronjobs/forms/cronjob.xml @@ -28,19 +28,6 @@
- - -
- -
+ + +
- + + + + + + + + + + + + + + + + + + +
- + + - - - -
diff --git a/administrator/components/com_cronjobs/src/Field/IntervalsField.php b/administrator/components/com_cronjobs/src/Field/IntervalsField.php index 39cef13778646..589db24e4854c 100644 --- a/administrator/components/com_cronjobs/src/Field/IntervalsField.php +++ b/administrator/components/com_cronjobs/src/Field/IntervalsField.php @@ -36,11 +36,12 @@ class IntervalsField extends ListField /** * Layout used to render the field + * ! Due removal * * @var string * @since __DEPLOY_VERSION__ */ - protected $layout = 'joomla.form.field.interval'; + // protected $layout = 'joomla.form.field.interval'; /** * The subtypes supported by this field type. @@ -74,7 +75,7 @@ class IntervalsField extends ListField ]; /** - * For options without explicit labels, count of options + * Count of predefined options for each subtype * * @var int[] * @since __DEPLOY_VERSION__ @@ -82,7 +83,9 @@ class IntervalsField extends ListField private static $optionsCount = [ 'minutes' => 59, 'hours' => 23, - 'days_month' => 31 + 'days_week' => 7, + 'days_month' => 31, + 'months' => 12 ]; /** @@ -94,12 +97,20 @@ class IntervalsField extends ListField private $subtype; /** - * The multiple attribute is enabled by default. + * If true, field options will include a wildcard * - * @var boolean - * @since __DEPLOY_VERSION__ + * @var boolean + * @since __DEPLOY_VERSION__ + */ + private $wildcard; + + /** + * If true, field will only have numeric labels (for days_week and months) + * + * @var boolean + * @since __DEPLOY_VERSION__ */ - protected $multiple = true; + private $onlyNumericLabels; /** * Override the parent method to set deal with subtypes. @@ -119,6 +130,8 @@ public function setup(SimpleXMLElement $element, $value, $group = null): bool $parentResult = parent::setup($element, $value, $group); $subtype = (string) $element['subtype'] ?? null; + $wildcard = (string) $element['wildcard'] ?? false; + $onlyNumericLabels = (string) $element['onlyNumericLabels'] ?? false; if (!($subtype && in_array($subtype, self::$subtypes))) { @@ -126,8 +139,8 @@ public function setup(SimpleXMLElement $element, $value, $group = null): bool } $this->subtype = $subtype; - $this->multiple = true; - $element['multiple'] = $element['multiple'] ?? 'true'; + $this->wildcard = $wildcard; + $this->onlyNumericLabels = $onlyNumericLabels; return $parentResult; } @@ -138,19 +151,25 @@ public function setup(SimpleXMLElement $element, $value, $group = null): bool * * @since __DEPLOY_VERSION__ */ - protected function getOptions() + protected function getOptions(): array { $subtype = $this->subtype; $options = []; + $options = parent::getOptions(); + if (!in_array($subtype, self::$subtypes)) { return $options; } - $options[] = HTMLHelper::_('select.option', '*', '*'); + // $options[] = HTMLHelper::_('select.option', '*', '*'); + if ($this->wildcard) + { + $options[] = HTMLHelper::_('select.option', '*', '*'); + } - if (array_key_exists($subtype, self::$preparedResponseLabels)) + if (!$this->onlyNumericLabels && array_key_exists($subtype, self::$preparedResponseLabels)) { $labels = self::$preparedResponseLabels[$subtype]; $responseCount = count($labels); From 9a1f62bcdd2061ff111c5d88082de29aad2a455a Mon Sep 17 00:00:00 2001 From: ditsuke Date: Wed, 28 Jul 2021 02:09:57 +0530 Subject: [PATCH 129/615] Fix option indices in IntervalsField --- .../components/com_cronjobs/src/Field/IntervalsField.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Field/IntervalsField.php b/administrator/components/com_cronjobs/src/Field/IntervalsField.php index 589db24e4854c..b4db967c7d5f1 100644 --- a/administrator/components/com_cronjobs/src/Field/IntervalsField.php +++ b/administrator/components/com_cronjobs/src/Field/IntervalsField.php @@ -176,7 +176,7 @@ protected function getOptions(): array for ($i = 0; $i < $responseCount; $i++) { - $options[] = HTMLHelper::_('select.option', $i, Text::_($labels[$i])); + $options[] = HTMLHelper::_('select.option', (string) ($i + 1), Text::_($labels[$i])); } } elseif (array_key_exists($subtype, self::$optionsCount)) @@ -185,7 +185,7 @@ protected function getOptions(): array for ($i = 0; $i < $responseCount; $i++) { - $options[] = HTMLHelper::_('select.option', $i, (string) ($i + 1)); + $options[] = HTMLHelper::_('select.option', (string) ($i + 1), (string) ($i + 1)); } } From 03ab171328fe7da27eb17ebf400172b93ce0a46a Mon Sep 17 00:00:00 2001 From: ditsuke Date: Wed, 28 Jul 2021 02:10:30 +0530 Subject: [PATCH 130/615] Update CronjobView template - Adds custom execution rules to a fieldset that shows when the custom ruletype is selected --- .../components/com_cronjobs/tmpl/cronjob/edit.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/administrator/components/com_cronjobs/tmpl/cronjob/edit.php b/administrator/components/com_cronjobs/tmpl/cronjob/edit.php index 31f6c41064be0..0b0d99045d8d7 100644 --- a/administrator/components/com_cronjobs/tmpl/cronjob/edit.php +++ b/administrator/components/com_cronjobs/tmpl/cronjob/edit.php @@ -27,6 +27,7 @@ $wa->useScript('keepalive'); $wa->useScript('form.validate'); +$wa->useStyle('com_cronjobs.admin-view-cronjob-css'); /** @var AdministratorApplication $app */ $app = $this->app; @@ -90,14 +91,12 @@ class="form-validate"> form->renderFieldset('basic'); ?>
- -
+
- form->renderFieldset('interval'); ?> + form->renderFieldset('custom-cron-rules'); ?>
From ce7b9a177690932345c91032fe342442f1deb324 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Wed, 28 Jul 2021 02:14:57 +0530 Subject: [PATCH 131/615] Add CSS for CronjobView Defines styles for the custom rules fieldset --- media/com_cronjobs/css/admin-view-cronjob.css | 24 +++++++++++++++++++ media/com_cronjobs/joomla.asset.json | 5 ++++ 2 files changed, 29 insertions(+) create mode 100644 media/com_cronjobs/css/admin-view-cronjob.css diff --git a/media/com_cronjobs/css/admin-view-cronjob.css b/media/com_cronjobs/css/admin-view-cronjob.css new file mode 100644 index 0000000000000..fa9fea928e813 --- /dev/null +++ b/media/com_cronjobs/css/admin-view-cronjob.css @@ -0,0 +1,24 @@ +.match-custom .control-group .control-label { + width: auto; + padding: 0 0 0 0; +} + +.match-custom .control-group .controls { + /* flex: 1; */ + display: inline-block; + min-width: 7rem; +} + +.match-custom .control-group { + /* display: flex; */ + display: inline-block; + margin-right: 1.5rem; +} + +.match-custom label { + font-size: small; +} + +.match-custom select[multiple] { + height: 15rem; +} diff --git a/media/com_cronjobs/joomla.asset.json b/media/com_cronjobs/joomla.asset.json index 77f025214a487..65d0704203765 100644 --- a/media/com_cronjobs/joomla.asset.json +++ b/media/com_cronjobs/joomla.asset.json @@ -32,6 +32,11 @@ "name": "com_cronjobs.admin-plg-job-css", "type": "style", "uri": "com_cronjobs/admin-plg-job.css" + }, + { + "name": "com_cronjobs.admin-view-cronjob-css", + "type": "style", + "uri": "com_cronjobs/admin-view-cronjob.css" } ] } From f213a6e059f54597f07a95080d05e45c48f9bc7e Mon Sep 17 00:00:00 2001 From: ditsuke Date: Wed, 28 Jul 2021 02:16:45 +0530 Subject: [PATCH 132/615] Update language files Adds definitions for new Cronjob form fields --- administrator/language/en-GB/com_cronjobs.ini | 21 ++++++++++++++++++ .../language/en-GB/com_cronjobs.sys.ini | 22 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/administrator/language/en-GB/com_cronjobs.ini b/administrator/language/en-GB/com_cronjobs.ini index 0142cd65b9f15..c64a6bbb1cd24 100644 --- a/administrator/language/en-GB/com_cronjobs.ini +++ b/administrator/language/en-GB/com_cronjobs.ini @@ -46,3 +46,24 @@ COM_CRONJOBS_ERROR_INVALID_JOB_TYPE="Invalid Job Type!" COM_CRONJOBS_LABEL_EXEC_INTERVAL="Execution Interval" COM_CRONJOBS_LABEL_PLG_JOB_ID="Plugin Job ID" COM_CRONJOBS_FIELD_JOB_TYPE="Job Type (identifier)" +COM_CRONJOBS_FIELD_LABEL_EXEC_RULE="Execution Rule" +COM_CRONJOBS_SELECT_EXEC_RULE="--- Select Rule ---" +COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_MINUTES="Minutes" +COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_HOURS="Hours" +COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_DAYS_M="Days of Month" +COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_MONTHS="Months" +COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_DAYS_W="Days of Week" +COM_CRONJOBS_TYPE_OR_SELECT_OPTIONS="Type or select options" +COM_CRONJOBS_OPTION_INTERVAL_MINUTES="Interval, Minutes" +COM_CRONJOBS_OPTION_INTERVAL_HOURS="Interval, Hours" +COM_CRONJOBS_OPTION_INTERVAL_DAYS="Interval, Days" +COM_CRONJOBS_OPTION_INTERVAL_MONTHS="Interval, Months" +COM_CRONJOBS_OPTION_INTERVAL_CUSTOM="Custom Match (Advanced)" +COM_CRONJOBS_FIELD_LABEL_INTERVAL_MINUTES="Interval in Minutes" +COM_CRONJOBS_FIELD_LABEL_INTERVAL_HOURS="Interval in Hours" +COM_CRONJOBS_FIELD_LABEL_INTERVAL_DAYS="Interval in Days" +COM_CRONJOBS_FIELD_LABEL_INTERVAL_MONTHS="Interval in Months" +COM_CRONJOBS_SELECT_INTERVAL_MINUTES="-- Select Interval in Minutes --" +COM_CRONJOBS_SELECT_INTERVAL_HOURS="-- Select Interval in Hours" +COM_CRONJOBS_SELECT_INTERVAL_DAYS="-- Select Interval in Days --" +COM_CRONJOBS_SELECT_INTERVAL_MONTHS="-- Select Interval in Months" diff --git a/administrator/language/en-GB/com_cronjobs.sys.ini b/administrator/language/en-GB/com_cronjobs.sys.ini index 0142cd65b9f15..2170f5ce7da75 100644 --- a/administrator/language/en-GB/com_cronjobs.sys.ini +++ b/administrator/language/en-GB/com_cronjobs.sys.ini @@ -46,3 +46,25 @@ COM_CRONJOBS_ERROR_INVALID_JOB_TYPE="Invalid Job Type!" COM_CRONJOBS_LABEL_EXEC_INTERVAL="Execution Interval" COM_CRONJOBS_LABEL_PLG_JOB_ID="Plugin Job ID" COM_CRONJOBS_FIELD_JOB_TYPE="Job Type (identifier)" +COM_CRONJOBS_FIELD_LABEL_EXEC_RULE="Execution Rule" +COM_CRONJOBS_SELECT_EXEC_RULE="--- Select Rule ---" +COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_MINUTES="Minutes" +COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_HOURS="Hours" +COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_DAYS_M="Days of Month" +COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_MONTHS="Months" +COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_DAYS_W="Days of Week" +COM_CRONJOBS_TYPE_OR_SELECT_OPTIONS="Type or select options" +COM_CRONJOBS_OPTION_INTERVAL_MINUTES="Interval, Minutes" +COM_CRONJOBS_OPTION_INTERVAL_HOURS="Interval, Hours" +COM_CRONJOBS_OPTION_INTERVAL_DAYS="Interval, Days" +COM_CRONJOBS_OPTION_INTERVAL_MONTHS="Interval, Months" +COM_CRONJOBS_OPTION_INTERVAL_CUSTOM="Custom Match (Advanced)" +COM_CRONJOBS_FIELD_LABEL_INTERVAL_MINUTES="Interval in Minutes" +COM_CRONJOBS_FIELD_LABEL_INTERVAL_HOURS="Interval in Hours" +COM_CRONJOBS_FIELD_LABEL_INTERVAL_DAYS="Interval in Days" +COM_CRONJOBS_FIELD_LABEL_INTERVAL_MONTHS="Interval in Months" +COM_CRONJOBS_SELECT_INTERVAL_MINUTES="-- Select Interval in Minutes --" +COM_CRONJOBS_SELECT_INTERVAL_HOURS="-- Select Interval in Hours" +COM_CRONJOBS_SELECT_INTERVAL_DAYS="-- Select Interval in Days --" +COM_CRONJOBS_SELECT_INTERVAL_MONTHS="-- Select Interval in Months" + From 13d9faa0eb40b360e7f6129df621c5b94e406169 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Wed, 28 Jul 2021 02:23:41 +0530 Subject: [PATCH 133/615] Cleanup IntervalsField Removes the layout property, previously commented out. It was due removal anyways and blocked tests on push. --- .../components/com_cronjobs/src/Field/IntervalsField.php | 9 --------- 1 file changed, 9 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Field/IntervalsField.php b/administrator/components/com_cronjobs/src/Field/IntervalsField.php index b4db967c7d5f1..9eb990000e381 100644 --- a/administrator/components/com_cronjobs/src/Field/IntervalsField.php +++ b/administrator/components/com_cronjobs/src/Field/IntervalsField.php @@ -34,15 +34,6 @@ class IntervalsField extends ListField */ protected $type = 'cronIntervals'; - /** - * Layout used to render the field - * ! Due removal - * - * @var string - * @since __DEPLOY_VERSION__ - */ - // protected $layout = 'joomla.form.field.interval'; - /** * The subtypes supported by this field type. * From f2ab044eb22e1bc9dbc85c31ab226718ae1cf908 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Wed, 28 Jul 2021 23:37:52 +0530 Subject: [PATCH 134/615] Refactor IntervalsField - Fixes option value ranges. - Replaces use of static members with class constants where appropriate. - Reduces code duplication. --- .../com_cronjobs/src/Field/IntervalsField.php | 78 +++++++++---------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Field/IntervalsField.php b/administrator/components/com_cronjobs/src/Field/IntervalsField.php index 9eb990000e381..13170b494beb6 100644 --- a/administrator/components/com_cronjobs/src/Field/IntervalsField.php +++ b/administrator/components/com_cronjobs/src/Field/IntervalsField.php @@ -17,6 +17,7 @@ use Joomla\CMS\Language\Text; use SimpleXMLElement; use function in_array; +use function range; /** * Multi-select form field, supporting inputs of: @@ -26,21 +27,13 @@ */ class IntervalsField extends ListField { - /** - * The form field type. - * - * @var string - * @since __DEPLOY_VERSION__ - */ - protected $type = 'cronIntervals'; - /** * The subtypes supported by this field type. * * @var string[] * @since __DEPLOY_VERSION__ */ - private static $subtypes = [ + private const SUBTYPES = [ 'minutes', 'hours', 'days_month', @@ -48,13 +41,27 @@ class IntervalsField extends ListField 'days_week' ]; + /** + * Count of predefined options for each subtype + * + * @var int[][] + * @since __DEPLOY_VERSION__ + */ + private const OPTIONS_RANGE = [ + 'minutes' => [0, 59], + 'hours' => [0, 23], + 'days_week' => [1, 7], + 'days_month' => [1, 31], + 'months' => [1, 12] + ]; + /** * Response labels for the 'month' and 'days_week' subtypes * * @var string[][] * @since __DEPLOY_VERSION__ */ - private static $preparedResponseLabels = [ + private const PREPARED_RESPONSE_LABELS = [ 'months' => [ 'JANUARY', 'FEBRUARY', 'MARCH', 'APRIL', 'MAY', 'JUNE', 'JULY', 'AUGUST', 'SEPTEMBER', 'OCTOBER', 'NOVEMBER', 'DECEMBER' @@ -66,18 +73,12 @@ class IntervalsField extends ListField ]; /** - * Count of predefined options for each subtype + * The form field type. * - * @var int[] - * @since __DEPLOY_VERSION__ + * @var string + * @since __DEPLOY_VERSION__ */ - private static $optionsCount = [ - 'minutes' => 59, - 'hours' => 23, - 'days_week' => 7, - 'days_month' => 31, - 'months' => 12 - ]; + protected $type = 'cronIntervals'; /** * The subtype of the CronIntervals field @@ -124,7 +125,7 @@ public function setup(SimpleXMLElement $element, $value, $group = null): bool $wildcard = (string) $element['wildcard'] ?? false; $onlyNumericLabels = (string) $element['onlyNumericLabels'] ?? false; - if (!($subtype && in_array($subtype, self::$subtypes))) + if (!($subtype && in_array($subtype, self::SUBTYPES))) { return false; } @@ -137,6 +138,7 @@ public function setup(SimpleXMLElement $element, $value, $group = null): bool } /** + * Method to get field options * * @return array Array of objects representing options in the options list * @@ -145,39 +147,37 @@ public function setup(SimpleXMLElement $element, $value, $group = null): bool protected function getOptions(): array { $subtype = $this->subtype; - $options = []; - $options = parent::getOptions(); - if (!in_array($subtype, self::$subtypes)) + if (!in_array($subtype, self::SUBTYPES)) { return $options; } - // $options[] = HTMLHelper::_('select.option', '*', '*'); if ($this->wildcard) { $options[] = HTMLHelper::_('select.option', '*', '*'); } - if (!$this->onlyNumericLabels && array_key_exists($subtype, self::$preparedResponseLabels)) - { - $labels = self::$preparedResponseLabels[$subtype]; - $responseCount = count($labels); + [$optionLower, $optionUpper] = self::OPTIONS_RANGE[$subtype]; - for ($i = 0; $i < $responseCount; $i++) - { - $options[] = HTMLHelper::_('select.option', (string) ($i + 1), Text::_($labels[$i])); - } + if (array_key_exists($subtype, self::PREPARED_RESPONSE_LABELS) && !$this->onlyNumericLabels) + { + $labels = array_map( + function (string $string): string { + return Text::_($string); + }, + self::PREPARED_RESPONSE_LABELS[$subtype] + ); } - elseif (array_key_exists($subtype, self::$optionsCount)) + else { - $responseCount = self::$optionsCount[$subtype]; + $labels = range(... self::OPTIONS_RANGE[$subtype]); + } - for ($i = 0; $i < $responseCount; $i++) - { - $options[] = HTMLHelper::_('select.option', (string) ($i + 1), (string) ($i + 1)); - } + for ([$i, $l] = [$optionLower, 0]; $i <= $optionUpper; $i++, $l++) + { + $options[] = HTMLHelper::_('select.option', (string) ($i), $labels[$l]); } return $options; From 300c02e3c78f987faf3fe5a779102aa36b548c53 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Thu, 29 Jul 2021 00:31:41 +0530 Subject: [PATCH 135/615] Bugfix CronOptions::findOptions() - Fixes bug with null argument method calls: such calls used to fail since type declaration for the argument (CronOption) was not nullable. - Refactors the $options member variable (earlier $jobs). --- .../com_cronjobs/src/Cronjobs/CronOptions.php | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Cronjobs/CronOptions.php b/administrator/components/com_cronjobs/src/Cronjobs/CronOptions.php index 5eb6db00fb03a..6843d32fb262f 100644 --- a/administrator/components/com_cronjobs/src/Cronjobs/CronOptions.php +++ b/administrator/components/com_cronjobs/src/Cronjobs/CronOptions.php @@ -22,7 +22,7 @@ * Used as the subject argument for the `OnCronOptionsList` event, plugins that support jobs must add them to the object * through the addOptions() method. * - * @since __DEPLOY_VERSION + * @since __DEPLOY_VERSION__ */ class CronOptions { @@ -32,7 +32,7 @@ class CronOptions * @var CronOption[] * @since __DEPLOY_VERSION__ */ - public $jobs = []; + public $options = []; /** @@ -50,20 +50,25 @@ public function addOptions(array $jobsArray): void { foreach ($jobsArray as $jobId => $langConstPrefix) { - $this->jobs[] = new CronOption($jobId, $langConstPrefix); + $this->options[] = new CronOption($jobId, $langConstPrefix); } } /** - * @param string $jobType A unique identifier for the job routine offered by a plugin + * @param ?string $jobType A unique identifier for the job routine offered by a plugin * - * @return CronOption|false A matching CronOption if available, false otherwise + * @return CronOption|false A matching CronOption if available, false otherwise * * @since __DEPLOY_VERSION__ */ - public function findOption(string $jobType) + public function findOption(?string $jobType) { - foreach ($this->jobs as $job) + if ($jobType === null) + { + return false; + } + + foreach ($this->options as $job) { if ($job->type === $jobType) { From 8c54167b6225a813b5cb1bd117b8ffc852e83152 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Thu, 29 Jul 2021 03:26:20 +0530 Subject: [PATCH 136/615] Improve view entry validation - Fixes erroneous "Existing Type Not Found" warning when jumping to new entry form. - Redirects to CronjobsView and displays error message if user jumps to new entry form bypassing SelectView. - Improves code readability and delegates some validation logic in the DisplayController to a new private method. --- .../src/Controller/CronjobController.php | 11 ++-- .../src/Controller/DisplayController.php | 64 +++++++++++++++---- 2 files changed, 58 insertions(+), 17 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Controller/CronjobController.php b/administrator/components/com_cronjobs/src/Controller/CronjobController.php index c3bd0bf1f4710..db1141b33a362 100644 --- a/administrator/components/com_cronjobs/src/Controller/CronjobController.php +++ b/administrator/components/com_cronjobs/src/Controller/CronjobController.php @@ -47,15 +47,15 @@ public function add(): bool $input = $app->getInput(); $validJobOptions = CronjobsHelper::getCronOptions(); - $result = parent::add(); + $canAdd = parent::add(); - if ($result !== true) + if ($canAdd !== true) { return false; } $jobType = $input->get('type'); - $jobOption = $validJobOptions->findOption($jobType); + $jobOption = $validJobOptions->findOption($jobType) ?: null; if (!$jobOption) { @@ -63,8 +63,7 @@ public function add(): bool $redirectUrl = 'index.php?option=' . $this->option . '&view=select&layout=edit'; $this->setRedirect(Route::_($redirectUrl, false)); $app->enqueueMessage(Text::_('COM_CRONJOBS_ERROR_INVALID_JOB_TYPE'), 'warning'); - - return false; + $canAdd = false; } $app->setUserState('com_cronjobs.add.cronjob.cronjob_type', $jobType); @@ -72,7 +71,7 @@ public function add(): bool // TODO : Parameter array handling below? - return true; + return $canAdd; } /** diff --git a/administrator/components/com_cronjobs/src/Controller/DisplayController.php b/administrator/components/com_cronjobs/src/Controller/DisplayController.php index 89b124a672e52..e31cffc78ed83 100644 --- a/administrator/components/com_cronjobs/src/Controller/DisplayController.php +++ b/administrator/components/com_cronjobs/src/Controller/DisplayController.php @@ -12,12 +12,14 @@ namespace Joomla\Component\Cronjobs\Administrator\Controller; // Restrict direct access -\defined('_JEXEC') or die; +defined('_JEXEC') or die; use Exception; -use Joomla\CMS\MVC\Controller\BaseController; use Joomla\CMS\Language\Text; +use Joomla\CMS\MVC\Controller\BaseController; use Joomla\CMS\Router\Route; +use function count; +use function defined; /** @@ -45,23 +47,63 @@ class DisplayController extends BaseController public function display($cachable = false, $urlparams = array()) { $layout = $this->input->get('layout', 'default'); - $id = $this->input->getInt('id'); // Check for edit form. - if ($layout == 'edit' && !$this->checkEditId('com_cronjobs.edit.cronjob', $id)) + if ($layout === 'edit') { - // Somehow the person just went to the form - we don't allow that. - if (!\count($this->app->getMessageQueue())) + if (!$this->validateEntry()) { - $this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id), 'error'); - } - - $this->setRedirect(Route::_('index.php?option=com_cronjobs&view=cronjobs')); + $cronjobsViewUrl = Route::_('index.php?option=com_cronjobs&view=cronjobs'); + $this->setRedirect($cronjobsViewUrl); - return false; + return false; + } } // Let the parent method take over return parent::display($cachable, $urlparams); } + + /** + * Validates entry to the view + * + * @param string $layout The layout to validate entry for (defaults to 'edit') + * + * @return boolean True is entry is valid + * + * @since __DEPLOY_VERSION__ + */ + private function validateEntry(string $layout = 'edit'): bool + { + $context = 'com_cronjobs'; + $id = $this->input->getInt('id'); + $isValid = true; + + switch ($layout) + { + case 'edit': + + // True if controller was called and verified permissions + $canEdit = $this->checkEditId("${context}.edit.cronjob", $id); + $isNew = ($id == 0); + + // For new item, entry is invalid if job type was not selected through SelectView + if ($isNew && !$this->app->getUserState("${context}.add.cronjob.cronjob_type")) + { + $this->setMessage((Text::_('COM_CRONJOBS_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW')), 'error'); + $isValid = false; + } + // For existing item, entry is invalid if CronjobController has not granted access + elseif (!$canEdit && !count($this->app->getMessageQueue())) + { + $this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id), 'error'); + $isValid = false; + } + break; + default: + break; + } + + return $isValid; + } } From ab8695ae1b415140a73508a7f20487c854c6a887 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Thu, 29 Jul 2021 04:03:05 +0530 Subject: [PATCH 137/615] Add caching to CronjobsHelper Caches the CronOptions object on first call to ::getCronOptions() for efficiency. Should make it feasible to refer to it as a stateful object rather than storing the CronOption in the userState, where it probably doesn't belong. --- .../src/Helper/CronjobsHelper.php | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Helper/CronjobsHelper.php b/administrator/components/com_cronjobs/src/Helper/CronjobsHelper.php index a716701f8e73e..6de1722ac0377 100644 --- a/administrator/components/com_cronjobs/src/Helper/CronjobsHelper.php +++ b/administrator/components/com_cronjobs/src/Helper/CronjobsHelper.php @@ -21,7 +21,7 @@ use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Component\Cronjobs\Administrator\Cronjobs\CronOptions; -use function \defined; +use function defined; /** * The CronjobsHelper class. @@ -29,8 +29,16 @@ * * @since __DEPLOY_VERSION__ */ -class CronjobsHelper +final class CronjobsHelper { + /** + * Cached CronOptions object + * + * @var CronOptions + * @since __DEPLOY_VERSION__ + */ + protected static $cronOptionsCache = null; + /** * Private constructor to prevent instantiation * @@ -49,6 +57,11 @@ private function __construct() */ public static function getCronOptions(): CronOptions { + if (self::$cronOptionsCache !== null) + { + return self::$cronOptionsCache; + } + /**@var AdministratorApplication $app */ $app = Factory::getApplication(); $options = new CronOptions; @@ -59,10 +72,11 @@ public static function getCronOptions(): CronOptions ] ); - // TODO : Implement an object for $items PluginHelper::importPlugin('job'); $app->getDispatcher()->dispatch('onCronOptionsList', $event); + self::$cronOptionsCache = $options; + return $options; } } From bec89b3a706bb8b99be21be0be3a9a9ca8796454 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Thu, 29 Jul 2021 04:16:18 +0530 Subject: [PATCH 138/615] Update Cronjob form XML Includes uncommitted changes that go with the latest changes to the template and stylesheet: - Un-hides custom rule labels (the CSS takes care of laying them out). - Removes the wildcard option from custom rules. --- .../components/com_cronjobs/forms/cronjob.xml | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/administrator/components/com_cronjobs/forms/cronjob.xml b/administrator/components/com_cronjobs/forms/cronjob.xml index bc73b364d030e..0ce5050c611fd 100644 --- a/administrator/components/com_cronjobs/forms/cronjob.xml +++ b/administrator/components/com_cronjobs/forms/cronjob.xml @@ -122,38 +122,41 @@ - - + + - + - - + - + + - +
- - - - -
From 576872303d116b0c0a534da883a767c596ff87d9 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Thu, 29 Jul 2021 22:35:58 +0530 Subject: [PATCH 139/615] Limit interval options in Cronjob form - Adds IntervalField for limited interval options - Rename IntervalsField to CronField - Update Cronjob form to use the limited option field --- .../components/com_cronjobs/forms/cronjob.xml | 20 +-- .../{IntervalsField.php => CronField.php} | 2 +- .../com_cronjobs/src/Field/IntervalField.php | 120 ++++++++++++++++++ 3 files changed, 131 insertions(+), 11 deletions(-) rename administrator/components/com_cronjobs/src/Field/{IntervalsField.php => CronField.php} (99%) create mode 100644 administrator/components/com_cronjobs/src/Field/IntervalField.php diff --git a/administrator/components/com_cronjobs/forms/cronjob.xml b/administrator/components/com_cronjobs/forms/cronjob.xml index 0ce5050c611fd..e992173e80013 100644 --- a/administrator/components/com_cronjobs/forms/cronjob.xml +++ b/administrator/components/com_cronjobs/forms/cronjob.xml @@ -125,37 +125,37 @@ - - + - - -
- - - - -
diff --git a/administrator/components/com_cronjobs/src/Field/IntervalsField.php b/administrator/components/com_cronjobs/src/Field/CronField.php similarity index 99% rename from administrator/components/com_cronjobs/src/Field/IntervalsField.php rename to administrator/components/com_cronjobs/src/Field/CronField.php index 13170b494beb6..2ba89fa8a7fc7 100644 --- a/administrator/components/com_cronjobs/src/Field/IntervalsField.php +++ b/administrator/components/com_cronjobs/src/Field/CronField.php @@ -25,7 +25,7 @@ * * @since __DEPLOY_VERSION__ */ -class IntervalsField extends ListField +class CronField extends ListField { /** * The subtypes supported by this field type. diff --git a/administrator/components/com_cronjobs/src/Field/IntervalField.php b/administrator/components/com_cronjobs/src/Field/IntervalField.php new file mode 100644 index 0000000000000..3f7065f6abb96 --- /dev/null +++ b/administrator/components/com_cronjobs/src/Field/IntervalField.php @@ -0,0 +1,120 @@ + + * @license GPL v3 + */ + +namespace Joomla\Component\Cronjobs\Administrator\Field; + +// Restrict direct access +defined('_JEXEC') or die; + +use Joomla\CMS\Form\Field\ListField; +use Joomla\CMS\HTML\HTMLHelper; +use SimpleXMLElement; + +/** + * Select style field for interval(s) in minutes, hours, days and months. + * + * @since __DEPLOY_VERSION__ + */ +class IntervalField extends ListField +{ + /** + * The subtypes supported by this field type. + * + * @var string[] + * @since __DEPLOY_VERSION__ + */ + private const SUBTYPES = [ + 'minutes', + 'hours', + 'days', + 'months' + ]; + + /** + * Options corresponding to each subtype + * + * @var int[][] + * @since __DEPLOY_VERSION__ + */ + private const OPTIONS = [ + 'minutes' => [1, 2, 3, 5, 10, 15, 30], + 'hours' => [1, 2, 3, 6, 12], + 'days' => [1, 2, 3, 5, 10, 15], + 'months' => [1, 2, 3, 6, 12] + ]; + + /** + * The form field type. + * + * @var string + * @since __DEPLOY_VERSION__ + */ + protected $type = 'cronIntervals'; + + /** + * The subtype of the CronIntervals field + * + * @var string + * @since __DEPLOY_VERSION__ + */ + private $subtype; + + /** + * Override the parent method to set deal with subtypes. + * + * @param SimpleXMLElement $element The SimpleXMLElement object representing the `` tag for the form field object. + * @param mixed $value The form field value to validate. + * @param string $group The field name group control value. This acts as as an array container for the field. + * For example if the field has name="foo" and the group value is set to "bar" then the + * full field name would end up being "bar[foo]". + * + * @return boolean True on success. + * + * @since __DEPLOY_VERSION__ + */ + public function setup(SimpleXMLElement $element, $value, $group = null): bool + { + $parentResult = parent::setup($element, $value, $group); + $subtype = (string) $element['subtype'] ?? null; + + if (!($subtype && in_array($subtype, self::SUBTYPES))) + { + return false; + } + + $this->subtype = $subtype; + + return $parentResult; + } + + /** + * Method to get field options + * + * @return array Array of objects representing options in the options list + * + * @since __DEPLOY_VERSION__ + */ + protected function getOptions(): array + { + $subtype = $this->subtype; + $options = parent::getOptions(); + + if (!in_array($subtype, self::SUBTYPES)) + { + return $options; + } + + foreach (self::OPTIONS[$subtype] as $option) + { + $options[] = HTMLHelper::_('select.option', (string) ($option), (string) $option); + } + + return $options; + } +} From 09ab0735ddecc9055c845d2f8b6e18b68b329d35 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sat, 31 Jul 2021 16:36:20 +0530 Subject: [PATCH 140/615] Add fields to Cronjob form Adds the exec_time and exec_day fields, applicable to select exec rules. --- administrator/components/com_cronjobs/forms/cronjob.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/administrator/components/com_cronjobs/forms/cronjob.xml b/administrator/components/com_cronjobs/forms/cronjob.xml index e992173e80013..bc6ff1dc66bb7 100644 --- a/administrator/components/com_cronjobs/forms/cronjob.xml +++ b/administrator/components/com_cronjobs/forms/cronjob.xml @@ -139,6 +139,12 @@ + + + +
From 2534056d7f0b1358a8f25496e39af2e163ea5ce7 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sat, 31 Jul 2021 21:23:24 +0530 Subject: [PATCH 141/615] Update database tables - Renames `execution_interval` to `execution_rule` - Adds new column `cron_rules` --- .../com_admin/sql/updates/mysql/4.1.0-2021-07-31.sql | 5 +++++ .../com_admin/sql/updates/postgresql/4.1.0-2021-07-31.sql | 6 ++++++ installation/sql/mysql/extensions.sql | 3 ++- installation/sql/postgresql/extensions.sql | 3 ++- 4 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-31.sql create mode 100644 administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-31.sql diff --git a/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-31.sql b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-31.sql new file mode 100644 index 0000000000000..defbd307d91d7 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-31.sql @@ -0,0 +1,5 @@ +ALTER TABLE `#__cronjobs` + -- Rename `execution_interval` to `execution_rules` + CHANGE `execution_interval` `execution_rules` text COMMENT 'Execution Rules, Unprocessed', + -- Add column `cron_rules` + ADD `cron_rules` text COMMENT 'Processed execution rules, crontab-like JSON form'; diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-31.sql b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-31.sql new file mode 100644 index 0000000000000..11df565f0d00f --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-31.sql @@ -0,0 +1,6 @@ +-- Rename "execution_interval" to "execution_rules" +ALTER TABLE "#__cronjobs" + RENAME COLUMN "execution_interval" TO "execution_rules"; +-- Add column "cron_rules" +ALTER TABLE "#__cronjobs" + ADD COLUMN "cron_rules" text; diff --git a/installation/sql/mysql/extensions.sql b/installation/sql/mysql/extensions.sql index a16e9cd2606ad..a3e4dc1b6e91b 100644 --- a/installation/sql/mysql/extensions.sql +++ b/installation/sql/mysql/extensions.sql @@ -897,7 +897,8 @@ CREATE TABLE IF NOT EXISTS `#__cronjobs` ( `type` varchar(1024) NOT NULL COMMENT 'unique identifier for job defined by plugin', -- Trigger type, default to PseudoCron (compatible everywhere). `trigger` enum ('pseudo_cron', 'cron', 'visit_count') NOT NULL DEFAULT 'pseudo_cron' COMMENT 'Defines how job is triggered', - `execution_interval` text COMMENT 'Configured execution interval, cron format', + `execution_rules` text COMMENT 'Execution Rules, Unprocessed', + `cron_rules` text COMMENT 'Processed execution rules, crontab-like JSON form', `state` tinyint NOT NULL DEFAULT FALSE, `last_exit_code` int NOT NULL DEFAULT '0' COMMENT 'Exit code when job was last run', `last_execution` datetime COMMENT 'Timestamp of last run', diff --git a/installation/sql/postgresql/extensions.sql b/installation/sql/postgresql/extensions.sql index 19ce315143f83..c443351d19fc1 100644 --- a/installation/sql/postgresql/extensions.sql +++ b/installation/sql/postgresql/extensions.sql @@ -858,7 +858,8 @@ CREATE TABLE IF NOT EXISTS "#__cronjobs" "asset_id" bigint NOT NULL DEFAULT '0', "title" varchar(255) NOT NULL, "type" varchar(1024) NOT NULL, - "execution_interval" text, + "execution_rules" text, + "cron_rules" text, "trigger" varchar(12) NOT NULL DEFAULT 'pseudo_cron', "state" smallint NOT NULL DEFAULT '0', "last_exit_code" int NOT NULL DEFAULT '0', From ad88bd6a1d2d6d7260f561dd53c0510e1bd6a3c6 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 1 Aug 2021 01:26:46 +0530 Subject: [PATCH 142/615] Add ExecutionRulesRule for Cronjob form validation This class is responsible for validating all execution rule fields against the rule type. This does not include the day/time fields which will be auto-populated if not provided. --- .../src/Rule/ExecutionRulesRule.php | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 administrator/components/com_cronjobs/src/Rule/ExecutionRulesRule.php diff --git a/administrator/components/com_cronjobs/src/Rule/ExecutionRulesRule.php b/administrator/components/com_cronjobs/src/Rule/ExecutionRulesRule.php new file mode 100644 index 0000000000000..b0bee6acbfbd0 --- /dev/null +++ b/administrator/components/com_cronjobs/src/Rule/ExecutionRulesRule.php @@ -0,0 +1,86 @@ + + * @license GPL v3 + */ + +namespace Joomla\Component\Cronjobs\Administrator\Rule; + +// Restrict direct access +defined('_JEXEC') or die; + +use Joomla\CMS\Form\Form; +use Joomla\CMS\Form\FormRule; +use Joomla\CMS\Form\Rule\OptionsRule; +use Joomla\Registry\Registry; +use SimpleXMLElement; + +/** + * The ExecutionRulesRule Class. + * Validates execution rules, with input for other fields as context. + * + * @since __DEPLOY_VERSION__ + */ +class ExecutionRulesRule extends FormRule +{ + /** + * @var string RULE_TYPE_FIELD The field containing the rule type to test against + * @since __DEPLOY_VERSION__ + */ + private const RULE_TYPE_FIELD = "execution_rules.rule-type"; + + /** + * @var string CUSTOM_RULE_GROUP The field group containing custom execution rules + * @since __DEPLOY_VERSION__ + */ + private const CUSTOM_RULE_GROUP = "execution_rules.custom"; + + /** + * @param SimpleXMLElement $element The SimpleXMLElement object representing the `` tag for the form field object. + * @param mixed $value The form field value to validate. + * @param ?string $group The field name group control value. This acts as an array container for the field. + * For example if the field has name="foo" and the group value is set to "bar" then the + * full field name would end up being "bar[foo]". + * @param ?Registry $input An optional Registry object with the entire data set to validate against the entire form. + * @param ?Form $form The form object for which the field is being tested. + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + */ + public function test(SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null): bool + { + $fieldName = (string) $element['name']; + $ruleType = $input->get(self::RULE_TYPE_FIELD); + + if ($ruleType === $fieldName || ($ruleType === 'custom' && $group === self::CUSTOM_RULE_GROUP)) + { + return self::validateField($element, $value, $group, $form); + } + + return true; + } + + /** + * @param SimpleXMLElement $element The SimpleXMLElement for the field. + * @param mixed $value The field value. + * @param ?string $group The form field group the element belongs to. + * @param Form|null $form The Form object against which the field is tested/ + * + * @return boolean True if field is valid + * + * @since __DEPLOY_VERSION__ + */ + private function validateField(SimpleXMLElement $element, $value, ?string $group = null, ?Form $form = null): bool + { + // Test that the option is valid + $optionsTest = (new OptionsRule)->test($element, $value, $group, null, $form); + + return $value && $optionsTest; + } +} From 023f8873cdf825c795672a0a44a56f2633629fb8 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 1 Aug 2021 01:29:08 +0530 Subject: [PATCH 143/615] Add new validation rules to Cronjob form Rule fields are now validation against ExecutionRulesRule --- .../components/com_cronjobs/forms/cronjob.xml | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/administrator/components/com_cronjobs/forms/cronjob.xml b/administrator/components/com_cronjobs/forms/cronjob.xml index bc6ff1dc66bb7..bb5fcdcf810c2 100644 --- a/administrator/components/com_cronjobs/forms/cronjob.xml +++ b/administrator/components/com_cronjobs/forms/cronjob.xml @@ -1,7 +1,8 @@ -
+ + label="COM_CRONJOBS_FIELD_LABEL_EXEC_RULE" validate="options"> @@ -125,19 +126,19 @@ - - - - - + - - - - +
From cf8cb995f71ad14f7e65879e97534da9efcbbe7f Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 1 Aug 2021 17:21:18 +0530 Subject: [PATCH 144/615] Add missing placeholder options to Cronjob form Adds previously missing placeholder options for intervals. --- .../components/com_cronjobs/forms/cronjob.xml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/administrator/components/com_cronjobs/forms/cronjob.xml b/administrator/components/com_cronjobs/forms/cronjob.xml index bb5fcdcf810c2..c5c05ef157d47 100644 --- a/administrator/components/com_cronjobs/forms/cronjob.xml +++ b/administrator/components/com_cronjobs/forms/cronjob.xml @@ -132,14 +132,20 @@
+ label="COM_CRONJOBS_FIELD_LABEL_INTERVAL_HOURS" showon="rule-type:interval-hours"> + + + label="COM_CRONJOBS_FIELD_LABEL_INTERVAL_DAYS" showon="rule-type:interval-days"> + + + label="COM_CRONJOBS_FIELD_LABEL_INTERVAL_MONTHS" showon="rule-type:interval-months"> + + From e4b340b04e2eeae8d38dfebb1b581080fa855f7e Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 1 Aug 2021 17:50:10 +0530 Subject: [PATCH 145/615] Add execution_rules handling to CronjobModel `execution_rules` from Cronjob form are sanitised, then used to build crontab-like `cron_rules`. These rules will be used internally to determine due executions. Handling for this is due to be added. --- .../com_cronjobs/src/Model/CronjobModel.php | 147 +++++++++++++++--- 1 file changed, 123 insertions(+), 24 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Model/CronjobModel.php b/administrator/components/com_cronjobs/src/Model/CronjobModel.php index cdfcd9c1c325f..96fb352c66ff8 100644 --- a/administrator/components/com_cronjobs/src/Model/CronjobModel.php +++ b/administrator/components/com_cronjobs/src/Model/CronjobModel.php @@ -17,15 +17,19 @@ use Exception; use Joomla\CMS\Application\AdministratorApplication; use Joomla\CMS\Component\ComponentHelper; +use Joomla\CMS\Factory; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormFactoryInterface; use Joomla\CMS\MVC\Factory\MVCFactoryInterface; use Joomla\CMS\MVC\Model\AdminModel; -use Joomla\CMS\Factory; use Joomla\CMS\Table\Table; use Joomla\Component\Cronjobs\Administrator\Helper\CronjobsHelper; +use function array_diff; +use function array_fill_keys; use function defined; +use function gmdate; use function is_object; +use function sort; /** * MVC Model to interact with the Cronjobs DB. @@ -37,7 +41,7 @@ class CronjobModel extends AdminModel { /** * Maps logical states to their values in the DB - * ? : Do we end up using this? + * ? Do we end up using this? * * @var array * @since __DEPLOY_VERSION__ @@ -249,10 +253,6 @@ protected function loadFormData() /** * Overloads the parent getItem() method. - * ! : Currently does nothing - * - * ? : Is this needed at all? - * Should be removed if we end up not needing any special handling. * * @param integer $pk Primary key * @@ -263,7 +263,6 @@ protected function loadFormData() */ public function getItem($pk = null) { - // TODO : Add CronjobModel specific handling or remove ⚠ $item = parent::getItem($pk); if (!is_object($item)) @@ -274,6 +273,7 @@ public function getItem($pk = null) $cronOption = ($item->id ?? 0) ? CronjobsHelper::getCronOptions()->findOption($item->type ?? 0) : ($this->getState('cronjob.option')); + CronjobsHelper::getCronOptions(); $item->set('cronOption', $cronOption); return $item; @@ -284,12 +284,13 @@ public function getItem($pk = null) * * @return boolean True on success, false on failure * + * @throws Exception * @since __DEPLOY_VERSION__ */ public function save($data): bool { /** - * @var object $field Holds the record we're saving $data to + * @var object $field Holds the record we're saving $data to */ $field = null; @@ -300,29 +301,127 @@ public function save($data): bool $field = $this->getItem($data['id']); } - /* - * ! : Due change - * TODO : Change execution interval in DB to TIME, change handling below - * TODO : Custom fields and we might not need this ugly handling - */ - $intervalHours = str_pad($data['interval-hours'] ?? '0', 2, '0', STR_PAD_LEFT); - $intervalMinutes = str_pad($data['interval-minutes'] ?? '0', 2, '0', STR_PAD_LEFT); - $data['execution_interval'] = "$intervalHours:$intervalMinutes:00"; + // Clean up execution rules + $this->processExecutionRules($data); - // TODO : Unset fields based on type and trigger selected + // Build the `cron_rules` column from `execution_rules` + $this->buildCronRule($data); - /* - * The parent save() takes care of saving to the main - * `#__cronjobs` table - */ + // Parent method takes care of saving to the table if (!parent::save($data)) { return false; } - // TODO: Handle the type-specific tables below! ⚠ - - // No failures if we get here return true; } + + /** + * Clean up and standardise execution rules + * + * @param array $data The form data [? can just replace with execution_interval] + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + private function processExecutionRules(array &$data): void + { + $executionRules = &$data['execution_rules']; + $ruleType = $executionRules['rule-type']; + $retainKeys = ['rule-type', $ruleType, 'exec-day', 'exec-time']; + $executionRules = array_intersect_key($executionRules, array_flip($retainKeys)); + + $executionRules['exec-day'] = $executionRules['exec-day'] ?: (string) gmdate('d'); + $executionRules['exec-time'] = $executionRules['exec-time'] ?: (string) gmdate('H:i'); + + // If custom ruleset, sort it + // ? Is this necessary + if ($ruleType === 'custom') + { + foreach ($executionRules['custom'] as &$values) + { + sort($values); + } + } + } + + /** + * Private method to build cron rules from input execution rules. + * Cron rules are used internally to determine execution times/conditions. + * + * @param array $data The form input data + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + private function buildCronRule(array &$data): void + { + $executionRules = $data['execution_rules']; + $cronRules = &$data['cron_rules']; + $standardRules = ['minutes', 'hours', 'days_month', 'months', 'days_week']; + $cronRules = array_fill_keys($standardRules, '*'); + $cronRules['visits'] = null; + $basisDayOfMonth = $executionRules['exec-day']; + $basisTime = $executionRules['exec-time']; + [$basisHour, $basisMinute] = explode(':', $basisTime); + + switch ($executionRules['rule-type']) + { + case 'interval-minutes': + $cronRules['minutes'] = "*/${executionRules['interval-minutes']}"; + break; + case 'interval-hours': + $cronRules['minutes'] = (int) $basisMinute; + $cronRules['hours'] = "*/${executionRules['interval-hours']}"; + break; + case 'interval-days': + $cronRules['minutes'] = (int) $basisMinute; + $cronRules['hours'] = (int) $basisHour; + $cronRules['days'] = "*/${executionRules['interval-days']}"; + break; + case 'interval-months': + $cronRules['minutes'] = (int) $basisMinute; + $cronRules['hours'] = (int) $basisHour; + $cronRules['days'] = (int) $basisDayOfMonth; + $cronRules['months'] = "*/${executionRules['interval-months']}"; + break; + case 'custom': + $customRules = &$executionRules['custom']; + $cronRules['minutes'] = $this->wildcardIfMatch($customRules['minutes'], range(0, 59), true); + $cronRules['hours'] = $this->wildcardIfMatch($customRules['hours'], range(0, 23), true); + $cronRules['days_month'] = $this->wildcardIfMatch($customRules['days_month'], range(1, 31), true); + $cronRules['months'] = $this->wildcardIfMatch($customRules['months'], range(1, 12), true); + $cronRules['days_week'] = $this->wildcardIfMatch($customRules['days_week'], range(1, 7), true); + } + } + + /** + * Determine if an array is populated by all its possible values by comparison to a reference array. + * + * @param array $target The target array + * @param array $reference The reference array, populated by the complete set of possible values in $target + * @param bool $targetToInt If true, converts $target array values to integers before comparing + * + * @return string|int[] A wildcard string if $target is fully populated, else $target itself. + * + * @since __DEPLOY_VERSION__ + */ + private function wildcardIfMatch(array $target, array $reference, bool $targetToInt = false) + { + if ($targetToInt) + { + $target = array_map( + function (string $x): int { + return (int) $x; + }, + $target + ); + } + + $isMatch = array_diff($reference, $target) === []; + + return $isMatch ? "*" : $target; + } } From 0c52372a201ad8a50ee3f2b8daa4c0dc5c13d6b4 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 1 Aug 2021 18:18:51 +0530 Subject: [PATCH 146/615] Update CronjobTable Adds `execution_rules` and `cron_rules` to _jsonEncode[] --- .../components/com_cronjobs/src/Table/CronjobTable.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/administrator/components/com_cronjobs/src/Table/CronjobTable.php b/administrator/components/com_cronjobs/src/Table/CronjobTable.php index ad0603249bd66..adfafc30ddc83 100644 --- a/administrator/components/com_cronjobs/src/Table/CronjobTable.php +++ b/administrator/components/com_cronjobs/src/Table/CronjobTable.php @@ -39,7 +39,7 @@ class CronjobTable extends Table * @var string[] * @since __DEPLOY_VERSION__ */ - protected $_jsonEncode = ['params']; + protected $_jsonEncode = ['params', 'execution_rules', 'cron_rules']; /** * Injected into the 'created' column From 020bcb892ba55aa0ed97a10a2d680b75fea349fd Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 1 Aug 2021 18:37:16 +0530 Subject: [PATCH 147/615] Fix fetching of execution_rules in CronjobModel The parent getItem() call leaves nested json objects encoded. This adds calls to json_decode() for both `execution_rules` and `cron_rules`. --- .../components/com_cronjobs/src/Model/CronjobModel.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Model/CronjobModel.php b/administrator/components/com_cronjobs/src/Model/CronjobModel.php index 96fb352c66ff8..d418d04b8c829 100644 --- a/administrator/components/com_cronjobs/src/Model/CronjobModel.php +++ b/administrator/components/com_cronjobs/src/Model/CronjobModel.php @@ -22,6 +22,7 @@ use Joomla\CMS\Form\FormFactoryInterface; use Joomla\CMS\MVC\Factory\MVCFactoryInterface; use Joomla\CMS\MVC\Model\AdminModel; +use Joomla\CMS\Object\CMSObject; use Joomla\CMS\Table\Table; use Joomla\Component\Cronjobs\Administrator\Helper\CronjobsHelper; use function array_diff; @@ -233,12 +234,9 @@ protected function loadFormData() // If the data from UserState is empty, we fetch it with getItem() if (empty($data)) { + /** @var CMSObject $data */ $data = $this->getItem(); - $time = explode(':', $data->get('execution_interval')); - $data->set('interval-hours', $time[0] ?? 0); - $data->set('interval-minutes', $time[1] ?? 0); - // TODO : Any further data processing goes here } @@ -270,6 +268,10 @@ public function getItem($pk = null) return false; } + // Parent call leaves `execution_rules` and `cron_rules` JSON encoded + $item->set('execution_rules', json_decode($item->get('execution_rules'))); + $item->set('cron_rules', json_decode($item->get('cron_rules'))); + $cronOption = ($item->id ?? 0) ? CronjobsHelper::getCronOptions()->findOption($item->type ?? 0) : ($this->getState('cronjob.option')); From 35a4dea3ab8db8238ede72d602fe80f788b26484 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 1 Aug 2021 18:43:45 +0530 Subject: [PATCH 148/615] Cleanup CronjobTable Removes some outdated comments --- .../components/com_cronjobs/src/Table/CronjobTable.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Table/CronjobTable.php b/administrator/components/com_cronjobs/src/Table/CronjobTable.php index adfafc30ddc83..82d4dad193300 100644 --- a/administrator/components/com_cronjobs/src/Table/CronjobTable.php +++ b/administrator/components/com_cronjobs/src/Table/CronjobTable.php @@ -61,10 +61,6 @@ class CronjobTable extends Table * CronjobTable constructor. * Just passes the DB table name and primary key name to parent constructor. * - * ? : How do we incorporate the supporting job type tables? - * Is the solution a Table class for each of them - * Or can we have a more elegant arrangement? - * * @param DatabaseDriver $db A database connector object (?) * * @since __DEPLOY_VERSION__ @@ -106,7 +102,7 @@ public function check() : bool $this->title = htmlspecialchars_decode($this->title, ENT_QUOTES); // Set created date if not set. - // ? : Might not need since the constructor already sets this + // ? Might not need since the constructor already sets this if (!(int) $this->created) { $this->created = Factory::getDate()->toSql(); From 7c22db02f79efcbc7dbba935b933a6b42c4cd92e Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 1 Aug 2021 19:45:04 +0530 Subject: [PATCH 149/615] Update SelectModel Changes from the CronOptions refactor: - References `CronOptions->options` instead of `CronOptions->jobs`. --- administrator/components/com_cronjobs/src/Model/SelectModel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/administrator/components/com_cronjobs/src/Model/SelectModel.php b/administrator/components/com_cronjobs/src/Model/SelectModel.php index e5857e9a53260..540627a761b1b 100644 --- a/administrator/components/com_cronjobs/src/Model/SelectModel.php +++ b/administrator/components/com_cronjobs/src/Model/SelectModel.php @@ -63,6 +63,6 @@ public function __construct($config = array(), ?MVCFactoryInterface $factory = n */ public function getItems(): array { - return CronjobsHelper::getCronOptions()->jobs; + return CronjobsHelper::getCronOptions()->options; } } From e5172b9ddf89bbfc50559e59ee022e96e0b71827 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 1 Aug 2021 19:48:14 +0530 Subject: [PATCH 150/615] Patch list view MVC - Patches "New Job" button (now links to SelectView). - Removes/replaces refs to `execution_interval`. --- .../components/com_cronjobs/src/Model/CronjobsModel.php | 5 +---- .../components/com_cronjobs/src/View/Cronjobs/HtmlView.php | 6 ++++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php index 9a39b6654f995..d6e57a231d7bb 100644 --- a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php +++ b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php @@ -67,9 +67,6 @@ public function __construct($config = array(), MVCFactoryInterface $factory = nu 'trigger', 'a.trigger', - 'execution_interval', - 'a.execution_interval', - 'enabled', 'a.enabled', @@ -163,7 +160,7 @@ protected function getListQuery(): QueryInterface $query->select( $this->getState( 'list.select', - 'a.id, a.asset_id, a.title, a.type, a.trigger, a.execution_interval, a.state, a.last_exit_code' . + 'a.id, a.asset_id, a.title, a.type, a.trigger, a.execution_rules, a.state, a.last_exit_code' . ', a.last_execution, a.next_execution, a.times_executed, a.times_failed' ) // ? Does 'list.select' exist ? diff --git a/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php b/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php index 22a6599e169e6..f6b5731a66905 100644 --- a/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php +++ b/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php @@ -143,7 +143,6 @@ public function display($tpl = null): void */ protected function addToolbar(): void { - // TODO: eval $canDo('core.delete') $canDo = ContentHelper::getActions('com_cronjobs'); $user = Factory::getApplication()->getIdentity(); @@ -158,7 +157,10 @@ protected function addToolbar(): void if ($canDo->get('core.create')) { - $toolbar->addNew('cronjob.add'); + $toolbar->linkButton('new', 'JTOOLBAR_NEW') + ->url('index.php?option=com_cronjobs&view=select&layout=default') + ->buttonClass('btn btn-success') + ->icon('icon-new'); } if (!$this->isEmptyState && ($canDo->get('core.edit.state') || $user->authorise('core.admin'))) From 3da30f0e0c58594ef3da5a2e5ccea50721c49037 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 1 Aug 2021 19:51:27 +0530 Subject: [PATCH 151/615] Update language files Adds new constants for CronjobView, error handling --- administrator/language/en-GB/com_cronjobs.ini | 7 +++++-- administrator/language/en-GB/com_cronjobs.sys.ini | 8 +++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/administrator/language/en-GB/com_cronjobs.ini b/administrator/language/en-GB/com_cronjobs.ini index c64a6bbb1cd24..e593e66f05f53 100644 --- a/administrator/language/en-GB/com_cronjobs.ini +++ b/administrator/language/en-GB/com_cronjobs.ini @@ -64,6 +64,9 @@ COM_CRONJOBS_FIELD_LABEL_INTERVAL_HOURS="Interval in Hours" COM_CRONJOBS_FIELD_LABEL_INTERVAL_DAYS="Interval in Days" COM_CRONJOBS_FIELD_LABEL_INTERVAL_MONTHS="Interval in Months" COM_CRONJOBS_SELECT_INTERVAL_MINUTES="-- Select Interval in Minutes --" -COM_CRONJOBS_SELECT_INTERVAL_HOURS="-- Select Interval in Hours" +COM_CRONJOBS_SELECT_INTERVAL_HOURS="-- Select Interval in Hours --" COM_CRONJOBS_SELECT_INTERVAL_DAYS="-- Select Interval in Days --" -COM_CRONJOBS_SELECT_INTERVAL_MONTHS="-- Select Interval in Months" +COM_CRONJOBS_SELECT_INTERVAL_MONTHS="-- Select Interval in Months --" +COM_CRONJOBS_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW="You need to select a job type first!" +COM_CRONJOBS_LABEL_EXEC_TIME="Execution Time (UTC)" +COM_CRONJOBS_LABEL_EXEC_DAY="Execution Day (UTC)" diff --git a/administrator/language/en-GB/com_cronjobs.sys.ini b/administrator/language/en-GB/com_cronjobs.sys.ini index 2170f5ce7da75..e593e66f05f53 100644 --- a/administrator/language/en-GB/com_cronjobs.sys.ini +++ b/administrator/language/en-GB/com_cronjobs.sys.ini @@ -64,7 +64,9 @@ COM_CRONJOBS_FIELD_LABEL_INTERVAL_HOURS="Interval in Hours" COM_CRONJOBS_FIELD_LABEL_INTERVAL_DAYS="Interval in Days" COM_CRONJOBS_FIELD_LABEL_INTERVAL_MONTHS="Interval in Months" COM_CRONJOBS_SELECT_INTERVAL_MINUTES="-- Select Interval in Minutes --" -COM_CRONJOBS_SELECT_INTERVAL_HOURS="-- Select Interval in Hours" +COM_CRONJOBS_SELECT_INTERVAL_HOURS="-- Select Interval in Hours --" COM_CRONJOBS_SELECT_INTERVAL_DAYS="-- Select Interval in Days --" -COM_CRONJOBS_SELECT_INTERVAL_MONTHS="-- Select Interval in Months" - +COM_CRONJOBS_SELECT_INTERVAL_MONTHS="-- Select Interval in Months --" +COM_CRONJOBS_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW="You need to select a job type first!" +COM_CRONJOBS_LABEL_EXEC_TIME="Execution Time (UTC)" +COM_CRONJOBS_LABEL_EXEC_DAY="Execution Day (UTC)" From 1bb5371763742f2f6987c6aeb336685dfc8b1129 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Mon, 2 Aug 2021 04:57:07 +0530 Subject: [PATCH 152/615] Update language files - Adds some missing strings - Changes the EXEC_DAY label --- administrator/language/en-GB/com_cronjobs.ini | 4 +++- administrator/language/en-GB/com_cronjobs.sys.ini | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/administrator/language/en-GB/com_cronjobs.ini b/administrator/language/en-GB/com_cronjobs.ini index e593e66f05f53..adf4e508455f1 100644 --- a/administrator/language/en-GB/com_cronjobs.ini +++ b/administrator/language/en-GB/com_cronjobs.ini @@ -11,6 +11,7 @@ COM_CRONJOBS_TYPE_PLG="Plugin" COM_CRONJOBS_SELECT_TRIGGER="Trigger" COM_CRONJOBS_EMPTYSTATE_CONTENT="No entries!" COM_CRONJOBS_EMPTYSTATE_BUTTON_ADD="Add a Cronjob!" +COM_CRONJOBS_EMPTYSTATE_TITLE="No Cronjobs have been created yet!" COM_CRONJOBS_FIELD_CREATED_BY_LABEL="Created By" COM_CRONJOBS_FIELD_CREATED_LABEL="Created" COM_CRONJOBS_TRIGGER_PSEUDOCRON="Pseudocron" @@ -19,6 +20,7 @@ COM_CRONJOBS_TRIGGER_XVISITS="X-Visits" COM_CRONJOBS_MANAGER_CRONJOBS="Cronjobs Manager" COM_CRONJOBS_MANAGER_CRONJOB="Cronjob Manager" COM_CRONJOBS_MANAGER_CRONJOB_EDIT="Edit Cronjob" +COM_CRONJOBS_MANAGER_CRONJOB_NEW="New Cronjob" COM_CRONJOBS_NEW_CRONJOB="New Cronjob" COM_CRONJOBS_EDIT_CRONJOB="Edit Cronjob" COM_CRONJOBS_FIELDSET_RULES="Rules" @@ -69,4 +71,4 @@ COM_CRONJOBS_SELECT_INTERVAL_DAYS="-- Select Interval in Days --" COM_CRONJOBS_SELECT_INTERVAL_MONTHS="-- Select Interval in Months --" COM_CRONJOBS_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW="You need to select a job type first!" COM_CRONJOBS_LABEL_EXEC_TIME="Execution Time (UTC)" -COM_CRONJOBS_LABEL_EXEC_DAY="Execution Day (UTC)" +COM_CRONJOBS_LABEL_EXEC_DAY="Execution Day" diff --git a/administrator/language/en-GB/com_cronjobs.sys.ini b/administrator/language/en-GB/com_cronjobs.sys.ini index e593e66f05f53..adf4e508455f1 100644 --- a/administrator/language/en-GB/com_cronjobs.sys.ini +++ b/administrator/language/en-GB/com_cronjobs.sys.ini @@ -11,6 +11,7 @@ COM_CRONJOBS_TYPE_PLG="Plugin" COM_CRONJOBS_SELECT_TRIGGER="Trigger" COM_CRONJOBS_EMPTYSTATE_CONTENT="No entries!" COM_CRONJOBS_EMPTYSTATE_BUTTON_ADD="Add a Cronjob!" +COM_CRONJOBS_EMPTYSTATE_TITLE="No Cronjobs have been created yet!" COM_CRONJOBS_FIELD_CREATED_BY_LABEL="Created By" COM_CRONJOBS_FIELD_CREATED_LABEL="Created" COM_CRONJOBS_TRIGGER_PSEUDOCRON="Pseudocron" @@ -19,6 +20,7 @@ COM_CRONJOBS_TRIGGER_XVISITS="X-Visits" COM_CRONJOBS_MANAGER_CRONJOBS="Cronjobs Manager" COM_CRONJOBS_MANAGER_CRONJOB="Cronjob Manager" COM_CRONJOBS_MANAGER_CRONJOB_EDIT="Edit Cronjob" +COM_CRONJOBS_MANAGER_CRONJOB_NEW="New Cronjob" COM_CRONJOBS_NEW_CRONJOB="New Cronjob" COM_CRONJOBS_EDIT_CRONJOB="Edit Cronjob" COM_CRONJOBS_FIELDSET_RULES="Rules" @@ -69,4 +71,4 @@ COM_CRONJOBS_SELECT_INTERVAL_DAYS="-- Select Interval in Days --" COM_CRONJOBS_SELECT_INTERVAL_MONTHS="-- Select Interval in Months --" COM_CRONJOBS_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW="You need to select a job type first!" COM_CRONJOBS_LABEL_EXEC_TIME="Execution Time (UTC)" -COM_CRONJOBS_LABEL_EXEC_DAY="Execution Day (UTC)" +COM_CRONJOBS_LABEL_EXEC_DAY="Execution Day" From 35079b554821f05ecaea5b4a2c073813ad7cd430 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Mon, 2 Aug 2021 04:58:58 +0530 Subject: [PATCH 153/615] Patch CronjobsView empty state The createURL now points to the SelectView --- .../components/com_cronjobs/tmpl/cronjobs/empty_state.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/administrator/components/com_cronjobs/tmpl/cronjobs/empty_state.php b/administrator/components/com_cronjobs/tmpl/cronjobs/empty_state.php index ca703ec5f16d2..6428412a937f4 100644 --- a/administrator/components/com_cronjobs/tmpl/cronjobs/empty_state.php +++ b/administrator/components/com_cronjobs/tmpl/cronjobs/empty_state.php @@ -21,7 +21,7 @@ if (Factory::getApplication()->getIdentity()->authorise('core.create', 'com_cronjobs')) { - $displayData['createURL'] = 'index.php?option=com_cronjobs&task=cronjob.add'; + $displayData['createURL'] = 'index.php?option=com_cronjobs&view=select&layout=default'; } echo LayoutHelper::render('joomla.content.emptystate', $displayData); From f648e2877b533cc29d3b0bc3394aaf0089ca659e Mon Sep 17 00:00:00 2001 From: ditsuke Date: Mon, 2 Aug 2021 21:10:58 +0530 Subject: [PATCH 154/615] Update language files Adds new constants for the list view --- administrator/language/en-GB/com_cronjobs.ini | 3 +++ administrator/language/en-GB/com_cronjobs.sys.ini | 3 +++ 2 files changed, 6 insertions(+) diff --git a/administrator/language/en-GB/com_cronjobs.ini b/administrator/language/en-GB/com_cronjobs.ini index adf4e508455f1..e69dcdbe61086 100644 --- a/administrator/language/en-GB/com_cronjobs.ini +++ b/administrator/language/en-GB/com_cronjobs.ini @@ -72,3 +72,6 @@ COM_CRONJOBS_SELECT_INTERVAL_MONTHS="-- Select Interval in Months --" COM_CRONJOBS_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW="You need to select a job type first!" COM_CRONJOBS_LABEL_EXEC_TIME="Execution Time (UTC)" COM_CRONJOBS_LABEL_EXEC_DAY="Execution Day" +COM_CRONJOBS_JOB_TYPE="Job Type" +COM_CRONJOBS_JOB_TYPE_ASC="Job Type Ascending" +COM_CRONJOBS_JOB_TYPE_DESC="Job Type Descending" diff --git a/administrator/language/en-GB/com_cronjobs.sys.ini b/administrator/language/en-GB/com_cronjobs.sys.ini index adf4e508455f1..e69dcdbe61086 100644 --- a/administrator/language/en-GB/com_cronjobs.sys.ini +++ b/administrator/language/en-GB/com_cronjobs.sys.ini @@ -72,3 +72,6 @@ COM_CRONJOBS_SELECT_INTERVAL_MONTHS="-- Select Interval in Months --" COM_CRONJOBS_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW="You need to select a job type first!" COM_CRONJOBS_LABEL_EXEC_TIME="Execution Time (UTC)" COM_CRONJOBS_LABEL_EXEC_DAY="Execution Day" +COM_CRONJOBS_JOB_TYPE="Job Type" +COM_CRONJOBS_JOB_TYPE_ASC="Job Type Ascending" +COM_CRONJOBS_JOB_TYPE_DESC="Job Type Descending" From 72c3fad1d124bed34229a66edf450c25ce03b8e6 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Mon, 2 Aug 2021 21:17:55 +0530 Subject: [PATCH 155/615] Update Cronjobs filter form - Removes ref to access - Adds options for ordering by exit code, type title --- .../components/com_cronjobs/forms/filter_cronjobs.xml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/administrator/components/com_cronjobs/forms/filter_cronjobs.xml b/administrator/components/com_cronjobs/forms/filter_cronjobs.xml index 8e6aefb6cf748..95fd9f464f234 100644 --- a/administrator/components/com_cronjobs/forms/filter_cronjobs.xml +++ b/administrator/components/com_cronjobs/forms/filter_cronjobs.xml @@ -46,7 +46,7 @@ - + JSTATUS_DESC - - - + + + + Date: Mon, 2 Aug 2021 22:06:14 +0530 Subject: [PATCH 156/615] Override _getList() in CronjobsModel - Adds the `j.type_title` filter field - Adds the attachCronOptions() method to associate item -> CronOption - Implements ordering by job type title in _getList() override --- .../com_cronjobs/src/Model/CronjobsModel.php | 85 ++++++++++++++++++- 1 file changed, 83 insertions(+), 2 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php index d6e57a231d7bb..5abda650d2d68 100644 --- a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php +++ b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php @@ -64,11 +64,14 @@ public function __construct($config = array(), MVCFactoryInterface $factory = nu 'type', 'a.type', + 'type_title', + 'j.type_title', + 'trigger', 'a.trigger', - 'enabled', - 'a.enabled', + 'state', + 'a.state', 'last_exit_code', 'a.last_exit_code', @@ -173,4 +176,82 @@ protected function getListQuery(): QueryInterface return $query; } + /** + * Overloads the parent _getList() method. + * Takes care of attaching CronOption objects and sorting by type titles. + * + * @param DatabaseQuery $query The database query to get the list with + * @param int $limitstart The list offset + * @param int $limit Number of list items to fetch + * + * @return object[] + * + * @throws Exception + * @since __DEPLOY_VERSION__ + * @codingStandardsIgnoreStart + */ + protected function _getList($query, $limitstart = 0, $limit = 0): array + { + /** @codingStandardsIgnoreEnd */ + + // Get stuff from the model state + $listOrder = $this->getState('list.ordering', 'a.title'); + $listDirectionN = strtolower($this->getState('list.direction', 'desc')) == 'desc' ? -1 : 1; + + // Set limit parameters and get object list + $query->setLimit($limit, $limitstart); + $this->getDbo()->setQuery($query); + $responseList = $this->getDbo()->loadObjectList(); + + // Attach CronOptions objects and a safe type title + $this->attachCronOptions($responseList); + + // If ordering by non-db fields, we need to sort here in code + if ($listOrder == 'j.type_title') + { + $responseList = ArrayHelper::sortObjects($responseList, 'safeTypeTitle', $listDirectionN, true, false); + } + + return $responseList; + } + + /** + * For an array of items, attaches CronOption objects and (safe) type titles to each. + * + * @param array $items Array of items, passed by reference + * + * @return void + * + * @throws Exception + * @since __DEPLOY_VERSION__ + */ + private function attachCronOptions(array &$items): void + { + $cronOptions = CronjobsHelper::getCronOptions(); + + foreach ($items as &$item) + { + // $jobType = $item->job_type; + $item->cronOption = $cronOptions->findOption($item->type); + $item->safeTypeTitle = $item->cronOption->title ?? 'N/A'; + } + } + + /** + * Overload the parent populateState() method. + * ! Does nothing at the moment. + * TODO : Remove if no special handling needed. + * + * @param ?string $ordering Field to order/sort list by + * @param ?string $direction Direction in which to sort list + * + * @return void + * @since __DEPLOY_VERSION__ + */ + protected function populateState($ordering = null, $direction = null): void + { + // TODO: Change the autogenerated stub + parent::populateState($ordering, $direction); + } + } From 5c624a00ec9f321590efa244488e9a7470ee9042 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Mon, 2 Aug 2021 23:02:15 +0530 Subject: [PATCH 157/615] Implement ordering & filtering in CronjobsModel - Implements ordering by relevant properties - Implements filtering by most properties (due: job type) --- .../com_cronjobs/src/Model/CronjobsModel.php | 82 ++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php index 5abda650d2d68..01fb562c0710d 100644 --- a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php +++ b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php @@ -20,9 +20,14 @@ use Joomla\CMS\Factory; use Joomla\CMS\MVC\Factory\MVCFactoryInterface; use Joomla\CMS\MVC\Model\ListModel; +use Joomla\Component\Cronjobs\Administrator\Helper\CronjobsHelper; +use Joomla\Database\DatabaseQuery; +use Joomla\Database\ParameterType; use Joomla\Database\QueryInterface; +use Joomla\Utilities\ArrayHelper; use function defined; +use function in_array; /** * MVC Model to deal with operations concerning multiple 'Cronjob' entries. @@ -169,9 +174,82 @@ protected function getListQuery(): QueryInterface // ? Does 'list.select' exist ? ); + // From the #__cronjobs table as 'a' $query->from($db->quoteName('#__cronjobs', 'a')); - // TODO : Implement filters and sorting here + // Filter over job type (this should go to _getList()) [! this is not in the filter form yet] + + // Filter over state ---- + $state = $this->getState('filter.state'); + + if (is_numeric($state)) + { + $state = (int) $state; + $query->where($db->quoteName('a.state') . '= :state') + ->bind(':state', $state); + } + + // ! [Are we showing the orphaned pseudo-state by default or no? (handled in _getList())] + + // Filter over exit code + $exitCode = $this->getState('filter.last_exit_code'); + + if (is_numeric($exitCode)) + { + $exitCode = (int) $exitCode; + $query->where($db->quoteName('a.last_exit_code') . '= :last_exit_code') + ->bind(':last_exit_code', $exitCode, ParameterType::INTEGER); + } + + // TODO: Filter over access levels [? should access level be retained] ---- + + // Filter over search string if set (title, type title, note, id) ---- + $searchStr = $this->getState('filter.search'); + + if (!empty($searchStr)) + { + // Allow search by ID + if (\stripos($searchStr, 'id:') === 0) + { + // Add array support [?] + $id = (int) \substr($searchStr, 3); + $query->where($db->quoteName('a.id') . '= :id') + ->bind(':id', $id, ParameterType::INTEGER); + } + // Search by type is handled exceptionally in _getList() [TODO] + elseif (\stripos($searchStr, 'type:') !== 0) + { + // The where clause is extended to allow other filters to act + $query->extendWhere( + 'AND', + [ + $db->quoteName('a.title') . ' LIKE :searchStr', + $db->quoteName('a.note') . 'LIKE : searchStr' + ], + 'OR' + ) + ->bind(':searchStr', $searchStr, ParameterType::STRING); + } + } + + // Add list ordering clause. ---- + $orderCol = $this->state->get('list.ordering', 'a.title'); + $orderDir = $this->state->get('list.direction', 'desc'); + + // Type title ordering is handled exceptionally in _getList() + if ($orderCol !== 'j.type_title') + { + // If ordering by type or state, also order by title. + if (in_array($orderCol, ['a.type', 'a.state'])) + { + // TODO : Test if things are working as expected + $query->order($db->quoteName('a.title') . ' ' . $orderDir); + + // $orderCol = $db->quoteName('a.title') . ' ' . $orderDir . ', ' . $db->quoteName('a.ordering'); + } + + $query->order($db->quoteName($orderCol) . ' ' . $orderDir); + } return $query; } @@ -212,6 +290,8 @@ protected function _getList($query, $limitstart = 0, $limit = 0): array $responseList = ArrayHelper::sortObjects($responseList, 'safeTypeTitle', $listDirectionN, true, false); } + // TODO: Implement filtering by type title here + return $responseList; } From 9cd836f3725d528fe23e384c1e54a1fab6ea1132 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Tue, 3 Aug 2021 14:52:28 +0530 Subject: [PATCH 158/615] Add CronjobStateField Lists all possible cronjob states: enabled, disabled and trashed. Used in both filter_cronjobs.xml and cronjobs.xml. --- .../src/Field/CronjobStateField.php | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 administrator/components/com_cronjobs/src/Field/CronjobStateField.php diff --git a/administrator/components/com_cronjobs/src/Field/CronjobStateField.php b/administrator/components/com_cronjobs/src/Field/CronjobStateField.php new file mode 100644 index 0000000000000..e64ea0ad0bb59 --- /dev/null +++ b/administrator/components/com_cronjobs/src/Field/CronjobStateField.php @@ -0,0 +1,44 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ +namespace Joomla\Component\Cronjobs\Administrator\Field; + +// Restrict direct access +defined('_JEXEC') or die; + +use Joomla\CMS\Form\Field\PredefinedlistField; + +/** + * A predefined list field with all possible states for a com_cronjobs entry. + * + * @since __DEPLOY_VERSION__ + */ +class CronjobStateField extends PredefinedlistField +{ + /** + * The form field type. + * + * @var string + * @since 3.2 + */ + public $type = 'CronjobState'; + + /** + * Available states + * + * @var array + * @since 3.2 + */ + protected $predefinedOptions = [ + -1 => 'JTRASHED', + 0 => 'JDISABLED', + 1 => 'JENABLED', + '*' => 'JALL' + ]; +} From 9c0ee7a984c0e1c4bbdb79917c075d1425219f78 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Tue, 3 Aug 2021 15:02:41 +0530 Subject: [PATCH 159/615] Update supported job states in Cronjob form - Adds support for the 'trashed' state. - Uses the new CronjobStateField. --- administrator/components/com_cronjobs/forms/cronjob.xml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/administrator/components/com_cronjobs/forms/cronjob.xml b/administrator/components/com_cronjobs/forms/cronjob.xml index c5c05ef157d47..6d71a0643330c 100644 --- a/administrator/components/com_cronjobs/forms/cronjob.xml +++ b/administrator/components/com_cronjobs/forms/cronjob.xml @@ -31,13 +31,10 @@
- - - - + size="1" validate="options" optionsFilter="-1,0,1" + /> Date: Tue, 3 Aug 2021 17:32:36 +0530 Subject: [PATCH 160/615] Update Cronjobs filter form - Remove access filter (no display access control) - Use CronjobStateField for item state. --- .../com_cronjobs/forms/filter_cronjobs.xml | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/administrator/components/com_cronjobs/forms/filter_cronjobs.xml b/administrator/components/com_cronjobs/forms/filter_cronjobs.xml index 95fd9f464f234..f34f1e592ff79 100644 --- a/administrator/components/com_cronjobs/forms/filter_cronjobs.xml +++ b/administrator/components/com_cronjobs/forms/filter_cronjobs.xml @@ -1,5 +1,5 @@ - + @@ -11,27 +11,18 @@ description="COM_TAGS_FILTER_SEARCH" hint="JSEARCH_FILTER" /> - + + - - - - - - + - + COM_CRONJOBS_JOB_TYPE_ASC + + Date: Tue, 3 Aug 2021 19:02:48 +0530 Subject: [PATCH 161/615] Update CronOptions class [breaking] - Changes the failure return type for CronOption::findOptions(), which now returns a `null` on failure instead of False. - This should break a few things in the CronjobView MVC. [!] --- .../components/com_cronjobs/src/Cronjobs/CronOptions.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Cronjobs/CronOptions.php b/administrator/components/com_cronjobs/src/Cronjobs/CronOptions.php index 6843d32fb262f..d940e9a4245d6 100644 --- a/administrator/components/com_cronjobs/src/Cronjobs/CronOptions.php +++ b/administrator/components/com_cronjobs/src/Cronjobs/CronOptions.php @@ -57,15 +57,15 @@ public function addOptions(array $jobsArray): void /** * @param ?string $jobType A unique identifier for the job routine offered by a plugin * - * @return CronOption|false A matching CronOption if available, false otherwise + * @return ?CronOption A matching CronOption if available, null otherwise * * @since __DEPLOY_VERSION__ */ - public function findOption(?string $jobType) + public function findOption(?string $jobType): ?CronOption { if ($jobType === null) { - return false; + return null; } foreach ($this->options as $job) @@ -76,6 +76,6 @@ public function findOption(?string $jobType) } } - return false; + return null; } } From ff89f1a44b23074d8c100c26564e9cdba84f1c72 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Tue, 3 Aug 2021 19:30:10 +0530 Subject: [PATCH 162/615] Update language files - Adds new constants for list view filters. - Adds some missing constants. - Modifies some old constants. --- administrator/language/en-GB/com_cronjobs.ini | 7 ++++++- administrator/language/en-GB/com_cronjobs.sys.ini | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/administrator/language/en-GB/com_cronjobs.ini b/administrator/language/en-GB/com_cronjobs.ini index c85d94508efde..615d4060728e6 100644 --- a/administrator/language/en-GB/com_cronjobs.ini +++ b/administrator/language/en-GB/com_cronjobs.ini @@ -18,6 +18,7 @@ COM_CRONJOBS_FIELD_LABEL_INTERVAL_DAYS="Interval in Days" COM_CRONJOBS_FIELD_LABEL_INTERVAL_HOURS="Interval in Hours" COM_CRONJOBS_FIELD_LABEL_INTERVAL_MINUTES="Interval in Minutes" COM_CRONJOBS_FIELD_LABEL_INTERVAL_MONTHS="Interval in Months" +COM_CRONJOBS_FIELD_LABEL_SHOW_ORPHANED="Show Orphaned" COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_DAYS_M="Days of Month" COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_DAYS_W="Days of Week" COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_HOURS="Hours" @@ -28,9 +29,11 @@ COM_CRONJOBS_FIELDSET_CRON_OPTIONS="Cron Options" COM_CRONJOBS_FIELDSET_DETAILS="Details" COM_CRONJOBS_FIELDSET_EXEC_HIST="Execution History" COM_CRONJOBS_FIELDSET_RULES="Rules" +COM_CRONJOBS_FILTER_SEARCH_DESC="Search in cronjob title and note. Prefix with 'ID:' or 'TYPE:' to search for a job ID or Type" +COM_CRONJOBS_FILTER_SEARCH_LABEL="Search Cronjobs" COM_CRONJOBS_FORM_TITLE_EDIT="Edit Cronjob" COM_CRONJOBS_FORM_TITLE_NEW="New Cronjob" -COM_CRONJOBS_HEADING_JOB_TYPE="Job Type" +COM_CRONJOBS_HEADING_JOB_TYPE="- Job Type -" COM_CRONJOBS_JOB_TYPE="Job Type" COM_CRONJOBS_JOB_TYPE_ASC="Job Type Ascending" COM_CRONJOBS_JOB_TYPE_DESC="Job Type Descending" @@ -57,6 +60,8 @@ COM_CRONJOBS_OPTION_INTERVAL_DAYS="Interval, Days" COM_CRONJOBS_OPTION_INTERVAL_HOURS="Interval, Hours" COM_CRONJOBS_OPTION_INTERVAL_MINUTES="Interval, Minutes" COM_CRONJOBS_OPTION_INTERVAL_MONTHS="Interval, Months" +COM_CRONJOBS_OPTION_ORPHANED_HIDE="Hide Orphaned" +COM_CRONJOBS_OPTION_ORPHANED_SHOW="Show Orphaned" COM_CRONJOBS_SELECT_CLI_JOB="Select CLI job" COM_CRONJOBS_SELECT_EXEC_RULE="--- Select Rule ---" COM_CRONJOBS_SELECT_INTERVAL_DAYS="-- Select Interval in Days --" diff --git a/administrator/language/en-GB/com_cronjobs.sys.ini b/administrator/language/en-GB/com_cronjobs.sys.ini index c85d94508efde..615d4060728e6 100644 --- a/administrator/language/en-GB/com_cronjobs.sys.ini +++ b/administrator/language/en-GB/com_cronjobs.sys.ini @@ -18,6 +18,7 @@ COM_CRONJOBS_FIELD_LABEL_INTERVAL_DAYS="Interval in Days" COM_CRONJOBS_FIELD_LABEL_INTERVAL_HOURS="Interval in Hours" COM_CRONJOBS_FIELD_LABEL_INTERVAL_MINUTES="Interval in Minutes" COM_CRONJOBS_FIELD_LABEL_INTERVAL_MONTHS="Interval in Months" +COM_CRONJOBS_FIELD_LABEL_SHOW_ORPHANED="Show Orphaned" COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_DAYS_M="Days of Month" COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_DAYS_W="Days of Week" COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_HOURS="Hours" @@ -28,9 +29,11 @@ COM_CRONJOBS_FIELDSET_CRON_OPTIONS="Cron Options" COM_CRONJOBS_FIELDSET_DETAILS="Details" COM_CRONJOBS_FIELDSET_EXEC_HIST="Execution History" COM_CRONJOBS_FIELDSET_RULES="Rules" +COM_CRONJOBS_FILTER_SEARCH_DESC="Search in cronjob title and note. Prefix with 'ID:' or 'TYPE:' to search for a job ID or Type" +COM_CRONJOBS_FILTER_SEARCH_LABEL="Search Cronjobs" COM_CRONJOBS_FORM_TITLE_EDIT="Edit Cronjob" COM_CRONJOBS_FORM_TITLE_NEW="New Cronjob" -COM_CRONJOBS_HEADING_JOB_TYPE="Job Type" +COM_CRONJOBS_HEADING_JOB_TYPE="- Job Type -" COM_CRONJOBS_JOB_TYPE="Job Type" COM_CRONJOBS_JOB_TYPE_ASC="Job Type Ascending" COM_CRONJOBS_JOB_TYPE_DESC="Job Type Descending" @@ -57,6 +60,8 @@ COM_CRONJOBS_OPTION_INTERVAL_DAYS="Interval, Days" COM_CRONJOBS_OPTION_INTERVAL_HOURS="Interval, Hours" COM_CRONJOBS_OPTION_INTERVAL_MINUTES="Interval, Minutes" COM_CRONJOBS_OPTION_INTERVAL_MONTHS="Interval, Months" +COM_CRONJOBS_OPTION_ORPHANED_HIDE="Hide Orphaned" +COM_CRONJOBS_OPTION_ORPHANED_SHOW="Show Orphaned" COM_CRONJOBS_SELECT_CLI_JOB="Select CLI job" COM_CRONJOBS_SELECT_EXEC_RULE="--- Select Rule ---" COM_CRONJOBS_SELECT_INTERVAL_DAYS="-- Select Interval in Days --" From 0680ce6924edca2e65e7260797dc88c2aa757ee6 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Tue, 3 Aug 2021 19:45:14 +0530 Subject: [PATCH 163/615] Implement orphan filtering in CronjobsView - Implements filtering of orphaned jobs - jobs whose parent plugins are either disabled or not installed. - Filtering is on by default with only 2 states (on/off) - Question: Should there be an "orphaned only" option? --- .../com_cronjobs/forms/filter_cronjobs.xml | 12 ++++++++++++ .../com_cronjobs/src/Model/CronjobsModel.php | 15 +++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/administrator/components/com_cronjobs/forms/filter_cronjobs.xml b/administrator/components/com_cronjobs/forms/filter_cronjobs.xml index f34f1e592ff79..c7f18e31f5821 100644 --- a/administrator/components/com_cronjobs/forms/filter_cronjobs.xml +++ b/administrator/components/com_cronjobs/forms/filter_cronjobs.xml @@ -33,6 +33,18 @@ + + + + + + diff --git a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php index 01fb562c0710d..b5cbd9ad12c28 100644 --- a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php +++ b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php @@ -292,6 +292,21 @@ protected function _getList($query, $limitstart = 0, $limit = 0): array // TODO: Implement filtering by type title here + // Filter out orphaned jobs if the state allows + // ! This breaks pagination at the moment [TODO: fix] + $showOrphaned = $this->getState('filter.show_orphaned'); + + if (!$showOrphaned) + { + $responseList = array_filter( + $responseList, + function (object $c) + { + return isset($c->cronOption); + } + ); + } + return $responseList; } From af302698aef3a71fba22416775c093fd160f8bb4 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Tue, 3 Aug 2021 19:58:30 +0530 Subject: [PATCH 164/615] Patch CronjobsView "Empty Trash" button The Empty Trash button used to show on the standard filter view, should now only appear when filtering by Trashed state. --- .../components/com_cronjobs/src/View/Cronjobs/HtmlView.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php b/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php index f6b5731a66905..070ce8c39a901 100644 --- a/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php +++ b/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php @@ -200,8 +200,8 @@ protected function addToolbar(): void } } - // TODO: Check states - if ($this->state->get('filter.enabled') == 0 && $canDo->get('core.delete')) + // Add "Empty Trash" button if filtering by trashed. + if ($this->state->get('filter.state') == -1 && $canDo->get('core.delete')) { $toolbar->delete('cronjobs.delete') ->text('JTOOLBAR_EMPTY_TRASH') From 2cf5a96b0df7e51a0e77be219df4df108c2bff49 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Tue, 3 Aug 2021 20:14:20 +0530 Subject: [PATCH 165/615] Update CronjobsView While still due more updates, this commit: - Removes access column from the table - Removes access refs from the filter form - Fixes table head sorting buttons - Shows job type titles instead of type identifiers - Improves styling and readability --- .../com_cronjobs/tmpl/cronjobs/default.php | 88 +++++++++---------- 1 file changed, 41 insertions(+), 47 deletions(-) diff --git a/administrator/components/com_cronjobs/tmpl/cronjobs/default.php b/administrator/components/com_cronjobs/tmpl/cronjobs/default.php index c77aaa3d9d3de..3f2d6cb1fe493 100644 --- a/administrator/components/com_cronjobs/tmpl/cronjobs/default.php +++ b/administrator/components/com_cronjobs/tmpl/cronjobs/default.php @@ -9,6 +9,7 @@ * @codingStandardsIgnoreStart */ +// Restrict direct access defined('_JEXEC') or die; use Joomla\CMS\Factory; @@ -55,9 +56,7 @@ ?> - items)) - : - ?> + items)): ?>
- items)) - : - ?> + items)): ?> @@ -82,59 +79,61 @@ class="visually-hidden"> + + - + - + + - + + - - + - + class="js-draggable" data-url="" data-direction="" data-nested="true" > items as $i => $item): // TODO : Check if $user->authorise() calls work as they should $orderKey = $item->id; $canCreate = $user->authorise('core.create', 'com_cronjobs'); $canEdit = $user->authorise('core.edit', 'com_cronjobs'); - $canChange = $user->authorise('core.edit.state', 'com_cronjobs'); ?> + $canChange = $user->authorise('core.edit.state', 'com_cronjobs'); + ?> + data-draggable-group="id; ?>" + > + + @@ -191,23 +191,16 @@ class="js-draggable" data-url="" data-direction=" - - - - +
- + - + - + - - - + - +
id, false, 'cid', 'cb', $item->title); ?> " data-direction=" } elseif (!$saveOrder) { $iconClass = ' inactive" title="' . Text::_('JORDERINGDISABLED'); - } ?> + } + ?> - - + + state, $i, 'cronjobs.', $canChange); ?> - escape($item->title); ?> @@ -181,7 +181,7 @@ class="js-draggable" data-url="" data-direction=" - escape($item->type); ?> + escape($item->safeTypeTitle); ?> - - - - - id; ?> + id; ?>
- pagination->getListFooter(); ?> @@ -215,20 +208,21 @@ class="js-draggable" data-url="" data-direction=" ?> authorise('core.create', 'com_cronjobs') - && $user->authorise('core.edit', 'com_cronjobs') - && $user->authorise('core.edit.state', 'com_cronjobs')): ?> + && $user->authorise('core.edit', 'com_cronjobs') + && $user->authorise('core.edit.state', 'com_cronjobs')): + ?> - Text::_('com_cronjobs_BATCH_OPTIONS'), 'footer' => $this->loadTemplate('batch_footer'), - ), + ], $this->loadTemplate('batch_body') - ); ?> - - + ); + ?> + From 9011f60f351662091079a668f13eb2c59f8aabe1 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Tue, 3 Aug 2021 20:17:00 +0530 Subject: [PATCH 166/615] Fix language constants in cronjobs filter form Fixes language constants for orphan filtering and search --- .../components/com_cronjobs/forms/filter_cronjobs.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/administrator/components/com_cronjobs/forms/filter_cronjobs.xml b/administrator/components/com_cronjobs/forms/filter_cronjobs.xml index c7f18e31f5821..be911678730d9 100644 --- a/administrator/components/com_cronjobs/forms/filter_cronjobs.xml +++ b/administrator/components/com_cronjobs/forms/filter_cronjobs.xml @@ -8,7 +8,7 @@ type="text" inputmode="search" label="COM_CRONJOBS_FILTER_SEARCH_LABEL" - description="COM_TAGS_FILTER_SEARCH" + description="COM_CRONJOBS_FILTER_SEARCH_DESC" hint="JSEARCH_FILTER" /> @@ -42,8 +42,8 @@ default="0" onchange="this.form.submit()" > - - + + From d14639003bbb26e75451592e1f8aab8f77d27ada Mon Sep 17 00:00:00 2001 From: ditsuke Date: Tue, 3 Aug 2021 20:47:47 +0530 Subject: [PATCH 167/615] Fix state toggling in CronjobsView - Adds column alias for `state` in CronjobTable - Adds proxy for getModel() in CronjobsController --- .../src/Controller/CronjobsController.php | 21 +++++++++++++++++-- .../com_cronjobs/src/Table/CronjobTable.php | 9 ++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Controller/CronjobsController.php b/administrator/components/com_cronjobs/src/Controller/CronjobsController.php index a5e9344d20b65..45f4855e9d195 100644 --- a/administrator/components/com_cronjobs/src/Controller/CronjobsController.php +++ b/administrator/components/com_cronjobs/src/Controller/CronjobsController.php @@ -12,9 +12,12 @@ namespace Joomla\Component\Cronjobs\Administrator\Controller; // Restrict direct access -\defined('_JEXEC') or die; +defined('_JEXEC') or die; use Joomla\CMS\MVC\Controller\AdminController; +use Joomla\CMS\MVC\Model\BaseDatabaseModel; +use Joomla\Component\Cronjobs\Administrator\Model\CronjobModel; +use function defined; /** * The CronjobsModel controller. @@ -23,5 +26,19 @@ */ class CronjobsController extends AdminController { - // ! TODO + /** + * Proxy for the parent method, set + * + * @param string $name The name of the model. + * @param string $prefix The prefix for the PHP class name. + * @param array $config Array of configuration parameters. + * + * @return BaseDatabaseModel + * + * @since __DEPLOY_VERSION__ + */ + public function getModel($name = 'Cronjob', $prefix = 'Administrator', $config = ['ignore_request' => true]): BaseDatabaseModel + { + return parent::getModel($name, $prefix, $config); + } } diff --git a/administrator/components/com_cronjobs/src/Table/CronjobTable.php b/administrator/components/com_cronjobs/src/Table/CronjobTable.php index 82d4dad193300..1eb0d0f8f9bbf 100644 --- a/administrator/components/com_cronjobs/src/Table/CronjobTable.php +++ b/administrator/components/com_cronjobs/src/Table/CronjobTable.php @@ -41,6 +41,15 @@ class CronjobTable extends Table */ protected $_jsonEncode = ['params', 'execution_rules', 'cron_rules']; + /** + * Aliases for special columns, allowing to work with built-in Joomla! methods + * @var string[] + * @since __DEPLOY_VERSION__ + */ + protected $_columnAlias = [ + 'published' => 'state' + ]; + /** * Injected into the 'created' column * From 1acf1643a08cdca98ce7a9b395a2ded81e3ba7cb Mon Sep 17 00:00:00 2001 From: ditsuke Date: Tue, 3 Aug 2021 21:19:51 +0530 Subject: [PATCH 168/615] Fix batch operation buttons in CronjobsView - Removes buttons for unsupported states - Adds buttons for the Enabled, Disabled, and Trashed states. - Removes "batch" button - we don't support view access or lang. - Rearranges some chained method calls for the right semantics and to silence "Potentially polymorphic call" warnings. --- .../src/View/Cronjobs/HtmlView.php | 37 +++++++------------ 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php b/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php index 070ce8c39a901..8907a1b7f860a 100644 --- a/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php +++ b/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php @@ -21,6 +21,7 @@ use Joomla\CMS\MVC\View\GenericDataException; use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView; use Joomla\CMS\Pagination\Pagination; +use Joomla\CMS\Toolbar\Button\DropdownButton; use Joomla\CMS\Toolbar\Toolbar; use Joomla\CMS\Toolbar\ToolbarHelper; use Joomla\CMS\Language\Text; @@ -165,38 +166,27 @@ protected function addToolbar(): void if (!$this->isEmptyState && ($canDo->get('core.edit.state') || $user->authorise('core.admin'))) { + /** @var DropdownButton $dropdown */ $dropdown = $toolbar->dropdownButton('status-group') - ->text('JTOOLBAR_CHANGE_STATUS') ->toggleSplit(false) + ->text('JTOOLBAR_CHANGE_STATUS') ->icon('icon-ellipsis-h') ->buttonClass('btn btn-action') ->listCheck(true); $childBar = $dropdown->getChildToolbar(); + // Add the batch Enable, Disable and Trash buttons if privileged if ($canDo->get('core.edit.state')) { - $childBar->publish('cronjob.enable')->listCheck(true); - $childBar->unpublish('cronjob.disable')->listCheck(true); - $childBar->archive('cronjob.delete')->listCheck(true); - } - - /* - * TODO: Remove this - * This is probably unneeded - */ - if ($canDo->get('core.edit.state') && $this->state->get('filter.published') != -2) - { - $childBar->trash('cronjobs.trash')->listCheck(true); - } - - // Add a batch button - if ($canDo->get('core.create') && $canDo->get('core.edit') && $canDo->get('core.edit.state')) - { - $childBar->popupButton('batch') - ->text('JTOOLBAR_BATCH') - ->selector('collapseModal') - ->listCheck(true); + $childBar->addNew('cronjobs.publish', 'JTOOLBAR_ENABLE')->listCheck(true)->icon('icon-publish'); + $childBar->addNew('cronjobs.unpublish', 'JTOOLBAR_DISABLE')->listCheck(true)->icon('icon-unpublish'); + + // We don't want the batch Trash button if displayed entries are all trashed + if ($this->state->get('filter.state') != -1) + { + $childBar->trash('cronjobs.trash')->listCheck(true); + } } } @@ -204,11 +194,12 @@ protected function addToolbar(): void if ($this->state->get('filter.state') == -1 && $canDo->get('core.delete')) { $toolbar->delete('cronjobs.delete') - ->text('JTOOLBAR_EMPTY_TRASH') ->message('JGLOBAL_CONFIRM_DELETE') + ->text('JTOOLBAR_EMPTY_TRASH') ->listCheck(true); } + // Link to component preferences if user has admin privileges if ($canDo->get('core.admin') || $canDo->get('core.options')) { $toolbar->preferences('com_cronjobs'); From 0c4f9783ec864832a8edbe5237e201658434fd68 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Tue, 3 Aug 2021 22:39:04 +0530 Subject: [PATCH 169/615] Change Trashed state index for compatibility Changes the index for Trashed state to -2 from -1 for compatibility with existing Joomla! methods. --- administrator/components/com_cronjobs/forms/cronjob.xml | 2 +- .../components/com_cronjobs/src/Field/CronjobStateField.php | 2 +- .../components/com_cronjobs/src/View/Cronjobs/HtmlView.php | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/administrator/components/com_cronjobs/forms/cronjob.xml b/administrator/components/com_cronjobs/forms/cronjob.xml index 6d71a0643330c..8946ce9e48a53 100644 --- a/administrator/components/com_cronjobs/forms/cronjob.xml +++ b/administrator/components/com_cronjobs/forms/cronjob.xml @@ -33,7 +33,7 @@ 'JTRASHED', + -2 => 'JTRASHED', 0 => 'JDISABLED', 1 => 'JENABLED', '*' => 'JALL' diff --git a/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php b/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php index 8907a1b7f860a..ca5af848f2284 100644 --- a/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php +++ b/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php @@ -183,7 +183,7 @@ protected function addToolbar(): void $childBar->addNew('cronjobs.unpublish', 'JTOOLBAR_DISABLE')->listCheck(true)->icon('icon-unpublish'); // We don't want the batch Trash button if displayed entries are all trashed - if ($this->state->get('filter.state') != -1) + if ($this->state->get('filter.state') != -2) { $childBar->trash('cronjobs.trash')->listCheck(true); } @@ -191,7 +191,7 @@ protected function addToolbar(): void } // Add "Empty Trash" button if filtering by trashed. - if ($this->state->get('filter.state') == -1 && $canDo->get('core.delete')) + if ($this->state->get('filter.state') == -2 && $canDo->get('core.delete')) { $toolbar->delete('cronjobs.delete') ->message('JGLOBAL_CONFIRM_DELETE') From e234bab8c4ef39705b09d3bbbeec61d854794d00 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Tue, 3 Aug 2021 22:46:06 +0530 Subject: [PATCH 170/615] Add/replace icon for com_cronjob views Adds the 'clock' icon as the page header icon for all Cronjobs component views. --- .../components/com_cronjobs/src/View/Cronjob/HtmlView.php | 2 +- .../components/com_cronjobs/src/View/Cronjobs/HtmlView.php | 2 +- .../components/com_cronjobs/src/View/Select/HtmlView.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/administrator/components/com_cronjobs/src/View/Cronjob/HtmlView.php b/administrator/components/com_cronjobs/src/View/Cronjob/HtmlView.php index 5100e3e9f21da..806582ae21155 100644 --- a/administrator/components/com_cronjobs/src/View/Cronjob/HtmlView.php +++ b/administrator/components/com_cronjobs/src/View/Cronjob/HtmlView.php @@ -136,7 +136,7 @@ protected function addToolbar(): void $canDo = $this->canDo; // TODO : icon? - ToolbarHelper::title($isNew ? Text::_('COM_CRONJOBS_MANAGER_CRONJOB_NEW') : Text::_('COM_CRONJOBS_MANAGER_CRONJOB_EDIT'), 'tags'); + ToolbarHelper::title($isNew ? Text::_('COM_CRONJOBS_MANAGER_CRONJOB_NEW') : Text::_('COM_CRONJOBS_MANAGER_CRONJOB_EDIT'), 'clock'); // Goes into ToolbarHelper::saveGroup() $toolbarButtons = []; diff --git a/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php b/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php index ca5af848f2284..41cc3cc3e7b22 100644 --- a/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php +++ b/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php @@ -154,7 +154,7 @@ protected function addToolbar(): void $toolbar = Toolbar::getInstance('toolbar'); // TODO : 'cronjobs' icon - ToolbarHelper::title(Text::_('COM_CRONJOBS_MANAGER_CRONJOBS'), 'tags'); + ToolbarHelper::title(Text::_('COM_CRONJOBS_MANAGER_CRONJOBS'), 'clock'); if ($canDo->get('core.create')) { diff --git a/administrator/components/com_cronjobs/src/View/Select/HtmlView.php b/administrator/components/com_cronjobs/src/View/Select/HtmlView.php index dbb738e8c773b..71294ce7b42c8 100644 --- a/administrator/components/com_cronjobs/src/View/Select/HtmlView.php +++ b/administrator/components/com_cronjobs/src/View/Select/HtmlView.php @@ -146,7 +146,7 @@ protected function addToolbar(): void * Add page title * TODO: 'cronjobs' icon */ - ToolbarHelper::title(Text::_('COM_CRONJOBS_MANAGER_CRONJOBS'), 'tags'); + ToolbarHelper::title(Text::_('COM_CRONJOBS_MANAGER_CRONJOBS'), 'clock'); $toolbar->linkButton('cancel') ->buttonClass('btn btn-danger') From aa89d5b0258b7f4e52ec1f6b6b070d670156c7d9 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Tue, 3 Aug 2021 23:11:18 +0530 Subject: [PATCH 171/615] Update database table Adds a new `ordering` column to #__cronjobs to support custom list ordering. --- .../com_admin/sql/updates/mysql/4.1.0-2021-08-03.sql | 3 +++ .../com_admin/sql/updates/postgresql/4.1.0-2021-08-03.sql | 2 ++ installation/sql/mysql/extensions.sql | 1 + installation/sql/postgresql/extensions.sql | 1 + 4 files changed, 7 insertions(+) create mode 100644 administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-08-03.sql create mode 100644 administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-08-03.sql diff --git a/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-08-03.sql b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-08-03.sql new file mode 100644 index 0000000000000..f4217fede4d8a --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-08-03.sql @@ -0,0 +1,3 @@ +-- Add column `ordering` +ALTER TABLE `#__cronjobs` + ADD `ordering` int NOT NULL DEFAULT 0 COMMENT 'Configurable list ordering'; diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-08-03.sql b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-08-03.sql new file mode 100644 index 0000000000000..af3ece4f3f33b --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-08-03.sql @@ -0,0 +1,2 @@ +ALTER TABLE "#__cronjobs" + ADD COLUMN "ordering" bigint DEFAULT 0 NOT NULL; diff --git a/installation/sql/mysql/extensions.sql b/installation/sql/mysql/extensions.sql index a3e4dc1b6e91b..1305b18f8bc7e 100644 --- a/installation/sql/mysql/extensions.sql +++ b/installation/sql/mysql/extensions.sql @@ -905,6 +905,7 @@ CREATE TABLE IF NOT EXISTS `#__cronjobs` ( `next_execution` datetime COMMENT 'Timestamp of next (planned) run, referred for execution on trigger', `times_executed` int DEFAULT '0' COMMENT 'Count of successful triggers', `times_failed` int DEFAULT '0' COMMENT 'Count of failures', + `ordering` int NOT NULL DEFAULT 0 COMMENT 'Configurable list ordering', `params` text NOT NULL, `note` text, `created` datetime NOT NULL, diff --git a/installation/sql/postgresql/extensions.sql b/installation/sql/postgresql/extensions.sql index c443351d19fc1..f76fc5cae2bdc 100644 --- a/installation/sql/postgresql/extensions.sql +++ b/installation/sql/postgresql/extensions.sql @@ -867,6 +867,7 @@ CREATE TABLE IF NOT EXISTS "#__cronjobs" "next_execution" timestamp without time zone, "times_executed" int NOT NULL DEFAULT '0', "times_failed" int DEFAULT '0', + "ordering" bigint DEFAULT 0 NOT NULL, "params" text NOT NULL, "note" text DEFAULT '', "created" timestamp without time zone NOT NULL, From b41ad8d6cb50fa6a4ffdde37f4228e3bbd8ff089 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Tue, 3 Aug 2021 23:21:52 +0530 Subject: [PATCH 172/615] Update language files - Adds new constants for CronjobsView batch operations and N/A strings. - Minor fix on a constant for a select placeholder. --- administrator/language/en-GB/com_cronjobs.ini | 11 ++++++++++- administrator/language/en-GB/com_cronjobs.sys.ini | 11 ++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/administrator/language/en-GB/com_cronjobs.ini b/administrator/language/en-GB/com_cronjobs.ini index 615d4060728e6..04de5bf305264 100644 --- a/administrator/language/en-GB/com_cronjobs.ini +++ b/administrator/language/en-GB/com_cronjobs.ini @@ -54,6 +54,15 @@ COM_CRONJOBS_MANAGER_CRONJOB_EDIT="Edit Cronjob" COM_CRONJOBS_MANAGER_CRONJOB_NEW="New Cronjob" COM_CRONJOBS_MANAGER_CRONJOBS="Cronjobs Manager" COM_CRONJOBS_MSG_MANAGE_NO_JOB_PLUGINS="There are no plugin jobs matching your query" +COM_CRONJOBS_N_ITEMS_DELETED="%s cronjobs deleted." +COM_CRONJOBS_N_ITEMS_DELETED_1="Cronjob deleted." +COM_CRONJOBS_N_ITEMS_PUBLISHED="%s cronjobs enabled." +COM_CRONJOBS_N_ITEMS_PUBLISHED_1="Cronjob enabled." +COM_CRONJOBS_N_ITEMS_TRASHED="%s cronjobs trashed." +COM_CRONJOBS_N_ITEMS_TRASHED_1="Cronjob trashed." +COM_CRONJOBS_N_ITEMS_UNPUBLISHED="%s cronjobs disabled." +COM_CRONJOBS_N_ITEMS_UNPUBLISHED_1="Cronjob disabled." +COM_CRONJOBS_NA="N/A" COM_CRONJOBS_NEW_CRONJOB="New Cronjob" COM_CRONJOBS_OPTION_INTERVAL_CUSTOM="Custom Match (Advanced)" COM_CRONJOBS_OPTION_INTERVAL_DAYS="Interval, Days" @@ -70,7 +79,7 @@ COM_CRONJOBS_SELECT_INTERVAL_MINUTES="-- Select Interval in Minutes --" COM_CRONJOBS_SELECT_INTERVAL_MONTHS="-- Select Interval in Months --" COM_CRONJOBS_SELECT_PLG_JOB="Select job, %s" COM_CRONJOBS_SELECT_TRIGGER="Trigger" -COM_CRONJOBS_SELECT_TYPE="Cronjob Type" +COM_CRONJOBS_SELECT_TYPE="- Cronjob Type -" COM_CRONJOBS_TABLE_CAPTION="Cronjobs List" COM_CRONJOBS_TRIGGER_CRON="Cron" COM_CRONJOBS_TRIGGER_PSEUDOCRON="Pseudocron" diff --git a/administrator/language/en-GB/com_cronjobs.sys.ini b/administrator/language/en-GB/com_cronjobs.sys.ini index 615d4060728e6..04de5bf305264 100644 --- a/administrator/language/en-GB/com_cronjobs.sys.ini +++ b/administrator/language/en-GB/com_cronjobs.sys.ini @@ -54,6 +54,15 @@ COM_CRONJOBS_MANAGER_CRONJOB_EDIT="Edit Cronjob" COM_CRONJOBS_MANAGER_CRONJOB_NEW="New Cronjob" COM_CRONJOBS_MANAGER_CRONJOBS="Cronjobs Manager" COM_CRONJOBS_MSG_MANAGE_NO_JOB_PLUGINS="There are no plugin jobs matching your query" +COM_CRONJOBS_N_ITEMS_DELETED="%s cronjobs deleted." +COM_CRONJOBS_N_ITEMS_DELETED_1="Cronjob deleted." +COM_CRONJOBS_N_ITEMS_PUBLISHED="%s cronjobs enabled." +COM_CRONJOBS_N_ITEMS_PUBLISHED_1="Cronjob enabled." +COM_CRONJOBS_N_ITEMS_TRASHED="%s cronjobs trashed." +COM_CRONJOBS_N_ITEMS_TRASHED_1="Cronjob trashed." +COM_CRONJOBS_N_ITEMS_UNPUBLISHED="%s cronjobs disabled." +COM_CRONJOBS_N_ITEMS_UNPUBLISHED_1="Cronjob disabled." +COM_CRONJOBS_NA="N/A" COM_CRONJOBS_NEW_CRONJOB="New Cronjob" COM_CRONJOBS_OPTION_INTERVAL_CUSTOM="Custom Match (Advanced)" COM_CRONJOBS_OPTION_INTERVAL_DAYS="Interval, Days" @@ -70,7 +79,7 @@ COM_CRONJOBS_SELECT_INTERVAL_MINUTES="-- Select Interval in Minutes --" COM_CRONJOBS_SELECT_INTERVAL_MONTHS="-- Select Interval in Months --" COM_CRONJOBS_SELECT_PLG_JOB="Select job, %s" COM_CRONJOBS_SELECT_TRIGGER="Trigger" -COM_CRONJOBS_SELECT_TYPE="Cronjob Type" +COM_CRONJOBS_SELECT_TYPE="- Cronjob Type -" COM_CRONJOBS_TABLE_CAPTION="Cronjobs List" COM_CRONJOBS_TRIGGER_CRON="Cron" COM_CRONJOBS_TRIGGER_PSEUDOCRON="Pseudocron" From 77121cb02b4d01fe6aa34c1ce7bdd3992cca5921 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Wed, 4 Aug 2021 00:24:52 +0530 Subject: [PATCH 173/615] Refactor column alias config in CronjobTable Now uses the Table::setColumnAlias() method instead, which was already in use but with flipped parameters. --- .../com_cronjobs/src/Table/CronjobTable.php | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Table/CronjobTable.php b/administrator/components/com_cronjobs/src/Table/CronjobTable.php index 1eb0d0f8f9bbf..28c95c1fcfb5c 100644 --- a/administrator/components/com_cronjobs/src/Table/CronjobTable.php +++ b/administrator/components/com_cronjobs/src/Table/CronjobTable.php @@ -41,15 +41,6 @@ class CronjobTable extends Table */ protected $_jsonEncode = ['params', 'execution_rules', 'cron_rules']; - /** - * Aliases for special columns, allowing to work with built-in Joomla! methods - * @var string[] - * @since __DEPLOY_VERSION__ - */ - protected $_columnAlias = [ - 'published' => 'state' - ]; - /** * Injected into the 'created' column * @@ -79,8 +70,7 @@ public function __construct(DatabaseDriver $db) $this->typeAlias = 'com_cronjobs.cronjob'; $this->created = Factory::getDate()->toSql(); - // Just for the sake of it, might remove - $this->setColumnAlias('state', 'published'); + $this->setColumnAlias('published', 'state'); parent::__construct('#__cronjobs', 'id', $db); } From 92761a6331855cc53d7e95a15eca2fc2fa16b891 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Wed, 4 Aug 2021 01:01:51 +0530 Subject: [PATCH 174/615] Add ordering support in CronjobsView - Adds support for standard draggable item ordering - Doesn't work right now, for some reason! --- .../com_cronjobs/forms/filter_cronjobs.xml | 6 ++++-- .../com_cronjobs/src/Model/CronjobsModel.php | 5 ++++- .../com_cronjobs/tmpl/cronjobs/default.php | 14 +++++++------- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/administrator/components/com_cronjobs/forms/filter_cronjobs.xml b/administrator/components/com_cronjobs/forms/filter_cronjobs.xml index be911678730d9..f07c4057ac357 100644 --- a/administrator/components/com_cronjobs/forms/filter_cronjobs.xml +++ b/administrator/components/com_cronjobs/forms/filter_cronjobs.xml @@ -59,8 +59,10 @@ validate="options" > - - + + + + diff --git a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php index b5cbd9ad12c28..942a524056420 100644 --- a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php +++ b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php @@ -93,6 +93,9 @@ public function __construct($config = array(), MVCFactoryInterface $factory = nu 'times_failed', 'a.times_failed', + 'ordering', + 'a.ordering', + 'note', 'a.note', @@ -169,7 +172,7 @@ protected function getListQuery(): QueryInterface $this->getState( 'list.select', 'a.id, a.asset_id, a.title, a.type, a.trigger, a.execution_rules, a.state, a.last_exit_code' . - ', a.last_execution, a.next_execution, a.times_executed, a.times_failed' + ', a.last_execution, a.next_execution, a.times_executed, a.times_failed, a.ordering' ) // ? Does 'list.select' exist ? ); diff --git a/administrator/components/com_cronjobs/tmpl/cronjobs/default.php b/administrator/components/com_cronjobs/tmpl/cronjobs/default.php index 3f2d6cb1fe493..a37ed46958b3e 100644 --- a/administrator/components/com_cronjobs/tmpl/cronjobs/default.php +++ b/administrator/components/com_cronjobs/tmpl/cronjobs/default.php @@ -34,7 +34,7 @@ $userId = $user->get('id'); $listOrder = $this->escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); -$saveOrder = ($listOrder == 'a.lft' && strtolower($listDirn) == 'asc'); +$saveOrder = $listOrder == 'a.ordering'; $section = null; $mode = false; @@ -42,7 +42,7 @@ if ($saveOrder && !empty($this->items)) { // TODO : Check if this works - $saveOrderingUrl = 'index.php?option=com_cronjobs&task=cronjobs.saveOrderAjax&' . Session::getFormToken() . '=1'; + $saveOrderingUrl = 'index.php?option=com_cronjobs&task=cronjobs.saveOrderAjax&tmpl=component&' . Session::getFormToken() . '=1'; HTMLHelper::_('draggablelist.draggable'); } ?> @@ -89,7 +89,7 @@ class="visually-hidden">
- + @@ -118,7 +118,6 @@ class="visually-hidden"> class="js-draggable" data-url="" data-direction="" data-nested="true" > items as $i => $item): // TODO : Check if $user->authorise() calls work as they should - $orderKey = $item->id; $canCreate = $user->authorise('core.create', 'com_cronjobs'); $canEdit = $user->authorise('core.edit', 'com_cronjobs'); $canChange = $user->authorise('core.edit.state', 'com_cronjobs'); @@ -149,11 +148,12 @@ class="js-draggable" data-url="" data-direction=" - + - + From 9573a39b4a5625673b22bd4c8f021381da984f20 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Wed, 4 Aug 2021 02:11:51 +0530 Subject: [PATCH 175/615] Fix ordering support in CronjobsView Removes data-draggable-group attributes and changes data-draggable-ids to "none". With this, job ordering is fully functional. --- .../components/com_cronjobs/tmpl/cronjobs/default.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/administrator/components/com_cronjobs/tmpl/cronjobs/default.php b/administrator/components/com_cronjobs/tmpl/cronjobs/default.php index a37ed46958b3e..992eba013900d 100644 --- a/administrator/components/com_cronjobs/tmpl/cronjobs/default.php +++ b/administrator/components/com_cronjobs/tmpl/cronjobs/default.php @@ -125,8 +125,7 @@ class="js-draggable" data-url="" data-direction="
From 5edde450ff3e8f28c425815e1ba9388d25548508 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Wed, 4 Aug 2021 13:25:19 +0530 Subject: [PATCH 176/615] Update CronjobsView layout - Fixes rendering of job notes (comes with a patch in the model) - Removes multi-language check. Jobs don't support that. - Adds a constant to language files --- .../com_cronjobs/src/Model/CronjobsModel.php | 2 +- .../com_cronjobs/tmpl/cronjobs/default.php | 20 +++++++------------ administrator/language/en-GB/com_cronjobs.ini | 1 + .../language/en-GB/com_cronjobs.sys.ini | 1 + 4 files changed, 10 insertions(+), 14 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php index 942a524056420..7738edf1f9438 100644 --- a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php +++ b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php @@ -172,7 +172,7 @@ protected function getListQuery(): QueryInterface $this->getState( 'list.select', 'a.id, a.asset_id, a.title, a.type, a.trigger, a.execution_rules, a.state, a.last_exit_code' . - ', a.last_execution, a.next_execution, a.times_executed, a.times_failed, a.ordering' + ', a.last_execution, a.next_execution, a.times_executed, a.times_failed, a.ordering, a.note' ) // ? Does 'list.select' exist ? ); diff --git a/administrator/components/com_cronjobs/tmpl/cronjobs/default.php b/administrator/components/com_cronjobs/tmpl/cronjobs/default.php index 992eba013900d..712b648929770 100644 --- a/administrator/components/com_cronjobs/tmpl/cronjobs/default.php +++ b/administrator/components/com_cronjobs/tmpl/cronjobs/default.php @@ -170,12 +170,13 @@ class="js-draggable" data-url="" data-direction=" escape($item->title); ?> - note)): ?> - - - - escape($item->note)); ?> - + + note)): ?> + + + escape($item->note)); ?> + + @@ -183,13 +184,6 @@ class="js-draggable" data-url="" data-direction=" escape($item->safeTypeTitle); ?> - - id; ?> diff --git a/administrator/language/en-GB/com_cronjobs.ini b/administrator/language/en-GB/com_cronjobs.ini index 04de5bf305264..2ea94cfb81124 100644 --- a/administrator/language/en-GB/com_cronjobs.ini +++ b/administrator/language/en-GB/com_cronjobs.ini @@ -64,6 +64,7 @@ COM_CRONJOBS_N_ITEMS_UNPUBLISHED="%s cronjobs disabled." COM_CRONJOBS_N_ITEMS_UNPUBLISHED_1="Cronjob disabled." COM_CRONJOBS_NA="N/A" COM_CRONJOBS_NEW_CRONJOB="New Cronjob" +COM_CRONJOBS_NO_NOTE="" COM_CRONJOBS_OPTION_INTERVAL_CUSTOM="Custom Match (Advanced)" COM_CRONJOBS_OPTION_INTERVAL_DAYS="Interval, Days" COM_CRONJOBS_OPTION_INTERVAL_HOURS="Interval, Hours" diff --git a/administrator/language/en-GB/com_cronjobs.sys.ini b/administrator/language/en-GB/com_cronjobs.sys.ini index 04de5bf305264..2ea94cfb81124 100644 --- a/administrator/language/en-GB/com_cronjobs.sys.ini +++ b/administrator/language/en-GB/com_cronjobs.sys.ini @@ -64,6 +64,7 @@ COM_CRONJOBS_N_ITEMS_UNPUBLISHED="%s cronjobs disabled." COM_CRONJOBS_N_ITEMS_UNPUBLISHED_1="Cronjob disabled." COM_CRONJOBS_NA="N/A" COM_CRONJOBS_NEW_CRONJOB="New Cronjob" +COM_CRONJOBS_NO_NOTE="" COM_CRONJOBS_OPTION_INTERVAL_CUSTOM="Custom Match (Advanced)" COM_CRONJOBS_OPTION_INTERVAL_DAYS="Interval, Days" COM_CRONJOBS_OPTION_INTERVAL_HOURS="Interval, Hours" From 665a3246eb2f60f649d5114c6abd18ddf510f3c8 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Wed, 4 Aug 2021 17:20:21 +0530 Subject: [PATCH 177/615] Enhance CronjobsModel Enhances multiple parts of the model: - Fixes store ID compilation (outdated filter) - Re-indexes orphan-filtered results before returning. - Makes safe type title translatable. - Passes default ordering to parent populateState() method. --- .../com_cronjobs/src/Model/CronjobsModel.php | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php index 7738edf1f9438..27366c8c2afb5 100644 --- a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php +++ b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php @@ -18,6 +18,7 @@ use Exception; use Joomla\CMS\Factory; +use Joomla\CMS\Language\Text; use Joomla\CMS\MVC\Factory\MVCFactoryInterface; use Joomla\CMS\MVC\Model\ListModel; use Joomla\Component\Cronjobs\Administrator\Helper\CronjobsHelper; @@ -142,7 +143,7 @@ protected function getStoreId($id = ''): string { // Compile the store id. $id .= ':' . $this->getState('filter.search'); - $id .= ':' . $this->getState('filter.enabled'); + $id .= ':' . $this->getState('filter.state'); $id .= ':' . $this->getState('filter.job_type'); return parent::getStoreId($id); @@ -301,12 +302,14 @@ protected function _getList($query, $limitstart = 0, $limit = 0): array if (!$showOrphaned) { - $responseList = array_filter( - $responseList, - function (object $c) - { - return isset($c->cronOption); - } + $responseList = array_values( + array_filter( + $responseList, + function (object $c) + { + return isset($c->cronOption); + } + ) ); } @@ -331,7 +334,7 @@ private function attachCronOptions(array &$items): void { // $jobType = $item->job_type; $item->cronOption = $cronOptions->findOption($item->type); - $item->safeTypeTitle = $item->cronOption->title ?? 'N/A'; + $item->safeTypeTitle = $item->cronOption->title ?? Text::_('COM_CRONJOBS_NA'); } } @@ -346,7 +349,7 @@ private function attachCronOptions(array &$items): void * @return void * @since __DEPLOY_VERSION__ */ - protected function populateState($ordering = null, $direction = null): void + protected function populateState($ordering = 'a.id', $direction = 'ASC'): void { // TODO: Change the autogenerated stub parent::populateState($ordering, $direction); From 74f30728a3b99f04edacd0c250af4a7cf7b38f1f Mon Sep 17 00:00:00 2001 From: ditsuke Date: Wed, 4 Aug 2021 17:26:08 +0530 Subject: [PATCH 178/615] Cleanup CronjobsModel Cleans up outdated comments and updates others. Also brings some styling fixes. --- .../com_cronjobs/src/Model/CronjobsModel.php | 23 +++++-------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php index 27366c8c2afb5..8191c0e138c02 100644 --- a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php +++ b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php @@ -1,8 +1,6 @@ getState('filter.state'); $id .= ':' . $this->getState('filter.job_type'); + // ? Does the store id need more specificity + return parent::getStoreId($id); } @@ -181,8 +180,6 @@ protected function getListQuery(): QueryInterface // From the #__cronjobs table as 'a' $query->from($db->quoteName('#__cronjobs', 'a')); - // Filter over job type (this should go to _getList()) [! this is not in the filter form yet] - // Filter over state ---- $state = $this->getState('filter.state'); @@ -193,8 +190,6 @@ protected function getListQuery(): QueryInterface ->bind(':state', $state); } - // ! [Are we showing the orphaned pseudo-state by default or no? (handled in _getList())] - // Filter over exit code $exitCode = $this->getState('filter.last_exit_code'); @@ -205,8 +200,6 @@ protected function getListQuery(): QueryInterface ->bind(':last_exit_code', $exitCode, ParameterType::INTEGER); } - // TODO: Filter over access levels [? should access level be retained] ---- - // Filter over search string if set (title, type title, note, id) ---- $searchStr = $this->getState('filter.search'); @@ -248,8 +241,6 @@ protected function getListQuery(): QueryInterface { // TODO : Test if things are working as expected $query->order($db->quoteName('a.title') . ' ' . $orderDir); - - // $orderCol = $db->quoteName('a.title') . ' ' . $orderDir . ', ' . $db->quoteName('a.ordering'); } $query->order($db->quoteName($orderCol) . ' ' . $orderDir); @@ -294,7 +285,7 @@ protected function _getList($query, $limitstart = 0, $limit = 0): array $responseList = ArrayHelper::sortObjects($responseList, 'safeTypeTitle', $listDirectionN, true, false); } - // TODO: Implement filtering by type title here + // TODO: Implement filtering by type title here [filter form + search] // Filter out orphaned jobs if the state allows // ! This breaks pagination at the moment [TODO: fix] @@ -332,16 +323,14 @@ private function attachCronOptions(array &$items): void foreach ($items as &$item) { - // $jobType = $item->job_type; $item->cronOption = $cronOptions->findOption($item->type); $item->safeTypeTitle = $item->cronOption->title ?? Text::_('COM_CRONJOBS_NA'); } } /** - * Overload the parent populateState() method. - * ! Does nothing at the moment. - * TODO : Remove if no special handling needed. + * Proxy for the parent method. + * Sets ordering defaults. * * @param ?string $ordering Field to order/sort list by * @param ?string $direction Direction in which to sort list @@ -351,7 +340,7 @@ private function attachCronOptions(array &$items): void */ protected function populateState($ordering = 'a.id', $direction = 'ASC'): void { - // TODO: Change the autogenerated stub + // Call the parent method parent::populateState($ordering, $direction); } From 0839067d380718e89b7578c0faa7cd1ab4e3dcf0 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Wed, 4 Aug 2021 17:33:07 +0530 Subject: [PATCH 179/615] Add SQL for auto-installation. Adds SQL to: - Add #__assets and #__extensions on Joomla install, this includes: - #__assets entry for com_cronjob - #__extensions entries for com_cronjob, plg_testjob. - Add #__extensions entries for existing installations, this includes: - #__extensions entries for com_cronjob, plg_testjob. --- .../com_admin/sql/updates/mysql/4.1.0-2021-08-04.sql | 9 +++++++++ .../sql/updates/postgresql/4.1.0-2021-08-04.sql | 9 +++++++++ installation/sql/mysql/base.sql | 11 +++++++---- installation/sql/postgresql/base.sql | 11 +++++++---- 4 files changed, 32 insertions(+), 8 deletions(-) create mode 100644 administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-08-04.sql create mode 100644 administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-08-04.sql diff --git a/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-08-04.sql b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-08-04.sql new file mode 100644 index 0000000000000..40cec2110ede8 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-08-04.sql @@ -0,0 +1,9 @@ +-- Add `com_cronjobs` to `#__extensions` +INSERT INTO `#__extensions` (`package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, + `protected`, `locked`, `manifest_cache`, `params`, `custom_data`) +VALUES (0, 'com_cronjobs', 'component', 'com_cronjobs', 1, 1, 1, 1, 0, 1, '', '', ''); + +-- Add `plg_job_testjob` to `#__extensions` +INSERT INTO `#__extensions` (`package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, + `protected`, `locked`, `manifest_cache`, `params`, `custom_data`, `ordering`, `state`) +VALUES (0, 'plg_job_testjob', 'plugin', 'testjob', 'job', 0, 1, 1, 0, 0, '', '{}', '', 15, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-08-04.sql b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-08-04.sql new file mode 100644 index 0000000000000..cbdbcef234b95 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-08-04.sql @@ -0,0 +1,9 @@ +-- Add "com_cronjobs" to "#__extensions" +INSERT INTO "#__extensions" ("package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", + "protected", "locked", "manifest_cache", "params", "custom_data", "ordering", "state") +VALUES (0, 'com_cronjobs', 'component', 'com_cronjobs', 1, 1, 1, 1, 0, 1, '', '{}', '', 0, 0); + +-- Add "plg_job_testjob" to "#__extensions" +INSERT INTO "#__extensions" ("package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", + "protected", "locked", "manifest_cache", "params", "custom_data", "ordering", "state") +VALUES (0, 'plg_job_testjob', 'plugin', 'testjob', 'job', 0, 1, 1, 0, 0, '', '{}', '', 15, 0); diff --git a/installation/sql/mysql/base.sql b/installation/sql/mysql/base.sql index 34cc812385ffd..36b1241d0a614 100644 --- a/installation/sql/mysql/base.sql +++ b/installation/sql/mysql/base.sql @@ -25,7 +25,7 @@ CREATE TABLE IF NOT EXISTS `#__assets` ( -- INSERT INTO `#__assets` (`id`, `parent_id`, `lft`, `rgt`, `level`, `name`, `title`, `rules`) VALUES -(1, 0, 0, 161, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.login.api":{"8":1},"core.login.offline":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), +(1, 0, 0, 163, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.login.api":{"8":1},"core.login.offline":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), (2, 1, 1, 2, 1, 'com_admin', 'com_admin', '{}'), (3, 1, 3, 6, 1, 'com_banners', 'com_banners', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), (4, 1, 7, 8, 1, 'com_cache', 'com_cache', '{"core.admin":{"7":1},"core.manage":{"7":1}}'), @@ -105,7 +105,8 @@ INSERT INTO `#__assets` (`id`, `parent_id`, `lft`, `rgt`, `level`, `name`, `titl (85, 18, 120, 121, 2, 'com_modules.module.108', 'Privacy Status', '{}'), (86, 18, 122, 123, 2, 'com_modules.module.96', 'Popular Articles', '{}'), (87, 18, 124, 125, 2, 'com_modules.module.97', 'Recently Added Articles', '{}'), -(88, 18, 126, 127, 2, 'com_modules.module.98', 'Logged-in Users', '{}'); +(88, 18, 126, 127, 2, 'com_modules.module.98', 'Logged-in Users', '{}'), +(89, 1, 161, 162, 1, 'com_cronjobs', 'com_cronjobs', '{}'); -- -------------------------------------------------------- @@ -179,7 +180,8 @@ INSERT INTO `#__extensions` (`package_id`, `name`, `type`, `element`, `folder`, (0, 'com_privacy', 'component', 'com_privacy', '', 1, 1, 1, 0, 1, '', '', ''), (0, 'com_actionlogs', 'component', 'com_actionlogs', '', 1, 1, 1, 0, 1, '', '{"ip_logging":0,"csv_delimiter":",","loggable_extensions":["com_banners","com_cache","com_categories","com_checkin","com_config","com_contact","com_content","com_installer","com_media","com_menus","com_messages","com_modules","com_newsfeeds","com_plugins","com_redirect","com_tags","com_templates","com_users"]}', ''), (0, 'com_workflow', 'component', 'com_workflow', '', 1, 1, 0, 1, 1, '', '{}', ''), -(0, 'com_mails', 'component', 'com_mails', '', 1, 1, 1, 1, 1, '', '', ''); +(0, 'com_mails', 'component', 'com_mails', '', 1, 1, 1, 1, 1, '', '', ''), +(0, 'com_cronjobs', 'component', 'com_cronjobs', 1, 1, 1, 1, 0, 1, '', '', ''); -- Libraries INSERT INTO `#__extensions` (`package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `locked`, `manifest_cache`, `params`, `custom_data`) VALUES @@ -365,7 +367,8 @@ INSERT INTO `#__extensions` (`package_id`, `name`, `type`, `element`, `folder`, (0, 'plg_webservices_users', 'plugin', 'users', 'webservices', 0, 1, 1, 0, 1, '', '{}', '', 16, 0), (0, 'plg_workflow_featuring', 'plugin', 'featuring', 'workflow', 0, 1, 1, 0, 1, '', '{}', '', 1, 0), (0, 'plg_workflow_notification', 'plugin', 'notification', 'workflow', 0, 1, 1, 0, 1, '', '{}', '', 2, 0), -(0, 'plg_workflow_publishing', 'plugin', 'publishing', 'workflow', 0, 1, 1, 0, 1, '', '{}', '', 3, 0); +(0, 'plg_workflow_publishing', 'plugin', 'publishing', 'workflow', 0, 1, 1, 0, 1, '', '{}', '', 3, 0), +(0, 'plg_job_testjob', 'plugin', 'testjob', 'job', 0, 1, 1, 0, 0, '', '{}', '', 15, 0); -- Templates INSERT INTO `#__extensions` (`package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `locked`, `manifest_cache`, `params`, `custom_data`, `ordering`, `state`) VALUES diff --git a/installation/sql/postgresql/base.sql b/installation/sql/postgresql/base.sql index fa574a0c74245..b78fa01bb38d5 100644 --- a/installation/sql/postgresql/base.sql +++ b/installation/sql/postgresql/base.sql @@ -31,7 +31,7 @@ COMMENT ON COLUMN "#__assets"."rules" IS 'JSON encoded access control.'; -- INSERT INTO "#__assets" ("id", "parent_id", "lft", "rgt", "level", "name", "title", "rules") VALUES -(1, 0, 0, 161, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.login.api":{"8":1},"core.login.offline":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), +(1, 0, 0, 163, 0, 'root.1', 'Root Asset', '{"core.login.site":{"6":1,"2":1},"core.login.admin":{"6":1},"core.login.api":{"8":1},"core.login.offline":{"6":1},"core.admin":{"8":1},"core.manage":{"7":1},"core.create":{"6":1,"3":1},"core.delete":{"6":1},"core.edit":{"6":1,"4":1},"core.edit.state":{"6":1,"5":1},"core.edit.own":{"6":1,"3":1}}'), (2, 1, 1, 2, 1, 'com_admin', 'com_admin', '{}'), (3, 1, 3, 6, 1, 'com_banners', 'com_banners', '{"core.admin":{"7":1},"core.manage":{"6":1}}'), (4, 1, 7, 8, 1, 'com_cache', 'com_cache', '{"core.admin":{"7":1},"core.manage":{"7":1}}'), @@ -111,7 +111,8 @@ INSERT INTO "#__assets" ("id", "parent_id", "lft", "rgt", "level", "name", "titl (85, 18, 120, 121, 2, 'com_modules.module.108', 'Privacy Status', '{}'), (86, 18, 122, 123, 2, 'com_modules.module.96', 'Popular Articles', '{}'), (87, 18, 124, 125, 2, 'com_modules.module.97', 'Recently Added Articles', '{}'), -(88, 18, 126, 127, 2, 'com_modules.module.98', 'Logged-in Users', '{}'); +(88, 18, 126, 127, 2, 'com_modules.module.98', 'Logged-in Users', '{}'), +(89, 1, 161, 162, 1, 'com_cronjobs', 'com_cronjobs', '{}'); SELECT setval('#__assets_id_seq', 89, false); @@ -185,7 +186,8 @@ INSERT INTO "#__extensions" ("package_id", "name", "type", "element", "folder", (0, 'com_privacy', 'component', 'com_privacy', '', 1, 1, 1, 0, 1, '', '', '', 0, 0), (0, 'com_actionlogs', 'component', 'com_actionlogs', '', 1, 1, 1, 0, 1, '', '{"ip_logging":0,"csv_delimiter":",","loggable_extensions":["com_banners","com_cache","com_categories","com_checkin","com_config","com_contact","com_content","com_installer","com_media","com_menus","com_messages","com_modules","com_newsfeeds","com_plugins","com_redirect","com_tags","com_templates","com_users"]}', '', 0, 0), (0, 'com_workflow', 'component', 'com_workflow', '', 1, 1, 0, 1, 1, '', '{}', '', 0, 0), -(0, 'com_mails', 'component', 'com_mails', '', 1, 1, 1, 1, 1, '', '', '', 0, 0); +(0, 'com_mails', 'component', 'com_mails', '', 1, 1, 1, 1, 1, '', '', '', 0, 0), +(0, 'com_cronjobs', 'component', 'com_cronjobs', 1, 1, 1, 1, 0, 1, '', '{}', '', 0, 0); -- Libraries INSERT INTO "#__extensions" ("package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "locked", "manifest_cache", "params", "custom_data", "ordering", "state") VALUES @@ -371,7 +373,8 @@ INSERT INTO "#__extensions" ("package_id", "name", "type", "element", "folder", (0, 'plg_webservices_users', 'plugin', 'users', 'webservices', 0, 1, 1, 0, 1, '', '{}', '', 16, 0), (0, 'plg_workflow_featuring', 'plugin', 'featuring', 'workflow', 0, 1, 1, 0, 1, '', '{}', '', 1, 0), (0, 'plg_workflow_notification', 'plugin', 'notification', 'workflow', 0, 1, 1, 0, 1, '', '{}', '', 2, 0), -(0, 'plg_workflow_publishing', 'plugin', 'publishing', 'workflow', 0, 1, 1, 0, 1, '', '{}', '', 3, 0); +(0, 'plg_workflow_publishing', 'plugin', 'publishing', 'workflow', 0, 1, 1, 0, 1, '', '{}', '', 3, 0), +(0, 'plg_job_testjob', 'plugin', 'testjob', 'job', 0, 1, 1, 0, 0, '', '{}', '', 15, 0); -- Templates INSERT INTO "#__extensions" ("package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "locked", "manifest_cache", "params", "custom_data", "ordering", "state") VALUES From 1fc14367da6d72863120123167c35fb7f3db0c64 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Wed, 4 Aug 2021 18:12:14 +0530 Subject: [PATCH 180/615] Move plg_testjob to the 'job' plugin group - Moves the plugin files to plugins/job. - Renames plugin class to PlgJobTestjob. - Renames language files. - Updates some comments. --- plugins/{system => job}/testjob/forms/testJobForm.xml | 0 .../testjob/language/en-GB/en-GB.plg_job_testjob.ini} | 0 .../language/en-GB/en-GB.plg_job_testjob.sys.ini} | 0 plugins/{system => job}/testjob/testjob.php | 10 +++++----- plugins/{system => job}/testjob/testjob.xml | 6 +++--- 5 files changed, 8 insertions(+), 8 deletions(-) rename plugins/{system => job}/testjob/forms/testJobForm.xml (100%) rename plugins/{system/testjob/language/en-GB/en-GB.plg_system_testjob.ini => job/testjob/language/en-GB/en-GB.plg_job_testjob.ini} (100%) rename plugins/{system/testjob/language/en-GB/en-GB.plg_system_testjob.sys.ini => job/testjob/language/en-GB/en-GB.plg_job_testjob.sys.ini} (100%) rename plugins/{system => job}/testjob/testjob.php (87%) rename plugins/{system => job}/testjob/testjob.xml (63%) diff --git a/plugins/system/testjob/forms/testJobForm.xml b/plugins/job/testjob/forms/testJobForm.xml similarity index 100% rename from plugins/system/testjob/forms/testJobForm.xml rename to plugins/job/testjob/forms/testJobForm.xml diff --git a/plugins/system/testjob/language/en-GB/en-GB.plg_system_testjob.ini b/plugins/job/testjob/language/en-GB/en-GB.plg_job_testjob.ini similarity index 100% rename from plugins/system/testjob/language/en-GB/en-GB.plg_system_testjob.ini rename to plugins/job/testjob/language/en-GB/en-GB.plg_job_testjob.ini diff --git a/plugins/system/testjob/language/en-GB/en-GB.plg_system_testjob.sys.ini b/plugins/job/testjob/language/en-GB/en-GB.plg_job_testjob.sys.ini similarity index 100% rename from plugins/system/testjob/language/en-GB/en-GB.plg_system_testjob.sys.ini rename to plugins/job/testjob/language/en-GB/en-GB.plg_job_testjob.sys.ini diff --git a/plugins/system/testjob/testjob.php b/plugins/job/testjob/testjob.php similarity index 87% rename from plugins/system/testjob/testjob.php rename to plugins/job/testjob/testjob.php index 6fbf9b078a4e8..e4e751469c11c 100644 --- a/plugins/system/testjob/testjob.php +++ b/plugins/job/testjob/testjob.php @@ -16,11 +16,11 @@ use Joomla\Event\Event; /** - * The Testjobplug class + * The PlgJobTestjob class * - * @since __DEPLOY__ + * @since __DEPLOY__VERSION__ */ -class PlgSystemTestjob extends CMSPlugin implements SubscriberInterface +class PlgJobTestjob extends CMSPlugin implements SubscriberInterface { /** * Autoload the language file @@ -89,8 +89,8 @@ public function pluginCronOptions(Event $event): array public function cronSampleRoutine(Event $event): void { /** - * ! : com_cronjobs does not trigger anything as of yet. The operations below only exist as an example. - * ! : The $subject object has not been implemented, nor are the operations below its intended form. + * ! com_cronjobs does not trigger anything as yet. The operations below only exist as an example. + * ! The $subject object has not been implemented, nor are the operations below its intended form. */ $subject = $event['subject']; diff --git a/plugins/system/testjob/testjob.xml b/plugins/job/testjob/testjob.xml similarity index 63% rename from plugins/system/testjob/testjob.xml rename to plugins/job/testjob/testjob.xml index a2e12d26c1b66..22941103593d4 100644 --- a/plugins/system/testjob/testjob.xml +++ b/plugins/job/testjob/testjob.xml @@ -1,5 +1,5 @@ - + Test Job! Joomla! Projects July 2021 @@ -10,7 +10,7 @@ testjob.php - en-GB.plg_system_testjob.ini - en-GB.plg_system_testjob.sys.ini + en-GB.plg_job_testjob.ini + en-GB.plg_job_testjob.sys.ini From 12c821f686efd5d40fa8fc10e74ed8a57a3aa5d9 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Wed, 4 Aug 2021 18:31:03 +0530 Subject: [PATCH 181/615] Add default system menu entry Adds a "Cronjobs" entry in the system menu's Manage module. --- administrator/components/com_menus/presets/system.xml | 8 ++++++++ administrator/language/en-GB/mod_menu.ini | 1 + 2 files changed, 9 insertions(+) diff --git a/administrator/components/com_menus/presets/system.xml b/administrator/components/com_menus/presets/system.xml index 2b12741cafeb3..27b2221d4feef 100644 --- a/administrator/components/com_menus/presets/system.xml +++ b/administrator/components/com_menus/presets/system.xml @@ -164,6 +164,14 @@ permission="core.manage;com_redirect" /> + + Date: Wed, 4 Aug 2021 18:38:34 +0530 Subject: [PATCH 182/615] Update Cronjobs filter form Adds validation for state filtering options and removes option for sorting by exit code. --- .../components/com_cronjobs/forms/filter_cronjobs.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/administrator/components/com_cronjobs/forms/filter_cronjobs.xml b/administrator/components/com_cronjobs/forms/filter_cronjobs.xml index f07c4057ac357..27adf4e896039 100644 --- a/administrator/components/com_cronjobs/forms/filter_cronjobs.xml +++ b/administrator/components/com_cronjobs/forms/filter_cronjobs.xml @@ -18,6 +18,7 @@ type="CronjobState" label="JSTATUS" onchange="this.form.submit();" + validate="options" > @@ -67,8 +68,6 @@ - - From f3563b21bca6f4a098b91af6fe99f22c28602e79 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Wed, 4 Aug 2021 21:53:00 +0530 Subject: [PATCH 183/615] Cleanup and improve CronjobsModel code-style - Replaces some qualifiers with imports - Fixes a minor search bug (L190, note) - Removes outdated comments - Replaces array() with [] in the constructor and condenses array assignment vertically. --- .../com_cronjobs/src/Model/CronjobsModel.php | 87 ++++++------------- 1 file changed, 26 insertions(+), 61 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php index 8191c0e138c02..52336fa34fefb 100644 --- a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php +++ b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php @@ -26,6 +26,8 @@ use Joomla\Utilities\ArrayHelper; use function defined; use function in_array; +use function stripos; +use function substr; /** * MVC Model to deal with operations concerning multiple 'Cronjob' entries. @@ -49,60 +51,24 @@ public function __construct($config = array(), MVCFactoryInterface $factory = nu { if (empty($config['filter_fields'])) { - /* - * TODO : Works right? Need to implement filtering to check. - * TODO: Might want to remove unnecessary fields - */ - $config['filter_fields'] - = array( - 'id', - 'a.id', - - 'asset_id', - 'a.asset_id', - - 'title', - 'a.title', - - 'type', - 'a.type', - - 'type_title', - 'j.type_title', - - 'trigger', - 'a.trigger', - - 'state', - 'a.state', - - 'last_exit_code', - 'a.last_exit_code', - - 'last_execution', - 'a.last_execution', - - 'next_execution', - 'a.next_execution', - - 'times_executed', - 'a.times_executed', - - 'times_failed', - 'a.times_failed', - - 'ordering', - 'a.ordering', - - 'note', - 'a.note', - - 'created', - 'a.created', - - 'created_by', - 'a.created_by' - ); + $config['filter_fields'] = [ + 'id', 'a.id', + 'asset_id', 'a.asset_id', + 'title', 'a.title', + 'type', 'a.type', + 'type_title', 'j.type_title', + 'trigger', 'a.trigger', + 'state', 'a.state', + 'last_exit_code', 'a.last_exit_code', + 'last_execution', 'a.last_execution', + 'next_execution', 'a.next_execution', + 'times_executed', 'a.times_executed', + 'times_failed', 'a.times_failed', + 'ordering', 'a.ordering', + 'note', 'a.note', + 'created', 'a.created', + 'created_by', 'a.created_by' + ]; } parent::__construct($config, $factory); @@ -190,7 +156,7 @@ protected function getListQuery(): QueryInterface ->bind(':state', $state); } - // Filter over exit code + // Filter over exit code ---- $exitCode = $this->getState('filter.last_exit_code'); if (is_numeric($exitCode)) @@ -206,22 +172,22 @@ protected function getListQuery(): QueryInterface if (!empty($searchStr)) { // Allow search by ID - if (\stripos($searchStr, 'id:') === 0) + if (stripos($searchStr, 'id:') === 0) { // Add array support [?] - $id = (int) \substr($searchStr, 3); + $id = (int) substr($searchStr, 3); $query->where($db->quoteName('a.id') . '= :id') ->bind(':id', $id, ParameterType::INTEGER); } // Search by type is handled exceptionally in _getList() [TODO] - elseif (\stripos($searchStr, 'type:') !== 0) + elseif (stripos($searchStr, 'type:') !== 0) { // The where clause is extended to allow other filters to act $query->extendWhere( 'AND', [ $db->quoteName('a.title') . ' LIKE :searchStr', - $db->quoteName('a.note') . 'LIKE : searchStr' + $db->quoteName('a.note') . 'LIKE :searchStr' ], 'OR' ) @@ -296,8 +262,7 @@ protected function _getList($query, $limitstart = 0, $limit = 0): array $responseList = array_values( array_filter( $responseList, - function (object $c) - { + function (object $c) { return isset($c->cronOption); } ) From 76713c99a540e17f1d04b5d44808785e32eb57ad Mon Sep 17 00:00:00 2001 From: ditsuke Date: Wed, 4 Aug 2021 22:52:31 +0530 Subject: [PATCH 184/615] Move Type ID to details tab in Cronjob form Also cleans up outdated comments. --- .../components/com_cronjobs/forms/cronjob.xml | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/administrator/components/com_cronjobs/forms/cronjob.xml b/administrator/components/com_cronjobs/forms/cronjob.xml index 8946ce9e48a53..fc145f6f0d1c5 100644 --- a/administrator/components/com_cronjobs/forms/cronjob.xml +++ b/administrator/components/com_cronjobs/forms/cronjob.xml @@ -12,14 +12,6 @@ />
- - - - - @@ -77,6 +69,12 @@ default="0" class="readonly" readonly="true" /> + + + COM_CRONJOBS_OPTION_INTERVAL_CUSTOM - From 6ebe8bbb315b19ceb3040782d2820a7955cede86 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Wed, 4 Aug 2021 22:56:48 +0530 Subject: [PATCH 185/615] Update language files Updates the rules and type id constants for cronjob form. --- administrator/language/en-GB/com_cronjobs.ini | 4 ++-- administrator/language/en-GB/com_cronjobs.sys.ini | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/administrator/language/en-GB/com_cronjobs.ini b/administrator/language/en-GB/com_cronjobs.ini index 2ea94cfb81124..168ca155dba4d 100644 --- a/administrator/language/en-GB/com_cronjobs.ini +++ b/administrator/language/en-GB/com_cronjobs.ini @@ -12,7 +12,7 @@ COM_CRONJOBS_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW="You need to select a Job Type fir COM_CRONJOBS_ERROR_INVALID_JOB_TYPE="Invalid Job Type!" COM_CRONJOBS_FIELD_CREATED_BY_LABEL="Created By" COM_CRONJOBS_FIELD_CREATED_LABEL="Created" -COM_CRONJOBS_FIELD_JOB_TYPE="Job Type (identifier)" +COM_CRONJOBS_FIELD_JOB_TYPE="Type ID" COM_CRONJOBS_FIELD_LABEL_EXEC_RULE="Execution Rule" COM_CRONJOBS_FIELD_LABEL_INTERVAL_DAYS="Interval in Days" COM_CRONJOBS_FIELD_LABEL_INTERVAL_HOURS="Interval in Hours" @@ -28,7 +28,7 @@ COM_CRONJOBS_FIELDSET_BASIC="Basic Fields" COM_CRONJOBS_FIELDSET_CRON_OPTIONS="Cron Options" COM_CRONJOBS_FIELDSET_DETAILS="Details" COM_CRONJOBS_FIELDSET_EXEC_HIST="Execution History" -COM_CRONJOBS_FIELDSET_RULES="Rules" +COM_CRONJOBS_FIELDSET_RULES="Permissions" COM_CRONJOBS_FILTER_SEARCH_DESC="Search in cronjob title and note. Prefix with 'ID:' or 'TYPE:' to search for a job ID or Type" COM_CRONJOBS_FILTER_SEARCH_LABEL="Search Cronjobs" COM_CRONJOBS_FORM_TITLE_EDIT="Edit Cronjob" diff --git a/administrator/language/en-GB/com_cronjobs.sys.ini b/administrator/language/en-GB/com_cronjobs.sys.ini index 2ea94cfb81124..18ff2a058d742 100644 --- a/administrator/language/en-GB/com_cronjobs.sys.ini +++ b/administrator/language/en-GB/com_cronjobs.sys.ini @@ -1,6 +1,7 @@ ; Joomla! Projects ; (C) 2021 Open Source Matters, Inc. ; GPL v3 +; TODO: Remove unneeded constants from sys.ini COM_CRONJOBS="Cronjobs" COM_CRONJOBS_CLI_JOBS_DESC="Configure a CLI script to run at a scheduled interval or another condition." COM_CRONJOBS_CLI_JOBS_TITLE="CLI/Script Job" @@ -12,7 +13,7 @@ COM_CRONJOBS_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW="You need to select a Job Type fir COM_CRONJOBS_ERROR_INVALID_JOB_TYPE="Invalid Job Type!" COM_CRONJOBS_FIELD_CREATED_BY_LABEL="Created By" COM_CRONJOBS_FIELD_CREATED_LABEL="Created" -COM_CRONJOBS_FIELD_JOB_TYPE="Job Type (identifier)" +COM_CRONJOBS_FIELD_JOB_TYPE="Type ID" COM_CRONJOBS_FIELD_LABEL_EXEC_RULE="Execution Rule" COM_CRONJOBS_FIELD_LABEL_INTERVAL_DAYS="Interval in Days" COM_CRONJOBS_FIELD_LABEL_INTERVAL_HOURS="Interval in Hours" @@ -28,7 +29,7 @@ COM_CRONJOBS_FIELDSET_BASIC="Basic Fields" COM_CRONJOBS_FIELDSET_CRON_OPTIONS="Cron Options" COM_CRONJOBS_FIELDSET_DETAILS="Details" COM_CRONJOBS_FIELDSET_EXEC_HIST="Execution History" -COM_CRONJOBS_FIELDSET_RULES="Rules" +COM_CRONJOBS_FIELDSET_RULES="Permissions" COM_CRONJOBS_FILTER_SEARCH_DESC="Search in cronjob title and note. Prefix with 'ID:' or 'TYPE:' to search for a job ID or Type" COM_CRONJOBS_FILTER_SEARCH_LABEL="Search Cronjobs" COM_CRONJOBS_FORM_TITLE_EDIT="Edit Cronjob" From 1b2fc1db67f4caef404a1bdfd67227504f3308db Mon Sep 17 00:00:00 2001 From: ditsuke Date: Wed, 4 Aug 2021 22:59:08 +0530 Subject: [PATCH 186/615] Remove rule placeholder from Cronjob form Removes the placeholder option for rule type. --- administrator/components/com_cronjobs/forms/cronjob.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/administrator/components/com_cronjobs/forms/cronjob.xml b/administrator/components/com_cronjobs/forms/cronjob.xml index fc145f6f0d1c5..c4e4b29b09f0a 100644 --- a/administrator/components/com_cronjobs/forms/cronjob.xml +++ b/administrator/components/com_cronjobs/forms/cronjob.xml @@ -111,7 +111,6 @@ - From 45f14eaf2e75516af8f53f010f53c6534b39cda9 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Thu, 5 Aug 2021 01:00:44 +0530 Subject: [PATCH 187/615] Fix db update scripts Patches some old db update scripts and removes one's incompatible with the current state of the db. These used to force errors in com_installer's database manager. --- .../sql/updates/mysql/4.1.0-2021-07-21.sql | 2 +- .../sql/updates/mysql/4.1.0-2021-07-25.sql | 2 -- .../updates/postgresql/4.1.0-2021-07-17.sql | 16 ----------- .../updates/postgresql/4.1.0-2021-07-25.sql | 2 -- .../com_cronjobs/src/Field/JobTypeField.php | 27 +++++++++++++++++++ 5 files changed, 28 insertions(+), 21 deletions(-) delete mode 100644 administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-25.sql delete mode 100644 administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-25.sql create mode 100644 administrator/components/com_cronjobs/src/Field/JobTypeField.php diff --git a/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-21.sql b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-21.sql index 76c3053f42366..d32dfb543d4df 100644 --- a/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-21.sql +++ b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-21.sql @@ -1,4 +1,4 @@ DROP TABLE IF EXISTS `#__cronjobs_scripts`; ALTER TABLE `#__cronjobs` - MODIFY COLUMN `type` varchar(1024) NOT NULL COMMENT 'unique identifier for job defined by plugin', + MODIFY `type` varchar(1024) NOT NULL COMMENT 'unique identifier for job defined by plugin', ADD COLUMN `params` text NOT NULL AFTER `times_failed`; diff --git a/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-25.sql b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-25.sql deleted file mode 100644 index 9786c8c3b2edf..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-07-25.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE `#__cronjobs` - MODIFY COLUMN `execution_interval` text COMMENT 'Configured execution interval, cron format'; diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-17.sql b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-17.sql index ac6d565e6967c..3450ac73d6030 100644 --- a/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-17.sql +++ b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-17.sql @@ -20,19 +20,3 @@ CREATE TABLE IF NOT EXISTS "#__cronjobs" "created" timestamp without time zone NOT NULL, "created_by" bigint NOT NULL DEFAULT '0' ); - --- -------------------------------------------------------- - --- --- Table structure for table "#__cronjobs_scripts" --- - -CREATE TABLE IF NOT EXISTS "#__cronjobs_scripts" -( - "id" int GENERATED ALWAYS AS IDENTITY, - "job_id" int, -- References "#__cronjobs"(id) - "directory" varchar(256) NOT NULL, - "file" varchar(128) NOT NULL -); - --- -------------------------------------------------------- diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-25.sql b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-25.sql deleted file mode 100644 index 2cccaf8e2caca..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-07-25.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE "#__cronjobs" - ALTER COLUMN "execution_interval" TYPE text; diff --git a/administrator/components/com_cronjobs/src/Field/JobTypeField.php b/administrator/components/com_cronjobs/src/Field/JobTypeField.php new file mode 100644 index 0000000000000..89999129ec931 --- /dev/null +++ b/administrator/components/com_cronjobs/src/Field/JobTypeField.php @@ -0,0 +1,27 @@ + + * @license GPL v3 + */ + +namespace Joomla\Component\Cronjobs\Administrator\Field; + +// Restrict direct access +defined('_JEXEC') or die; + +use Joomla\CMS\Form\Field\ListField; + +/** + * A list field with all available job types + * + * @since __DEPLOY_VERSION__ + */ +class JobTypeField extends ListField +{ + +} From b189d68df7a3cf4b3b6432fed09608d7a0c32bf5 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Thu, 5 Aug 2021 03:52:43 +0530 Subject: [PATCH 188/615] Fix form manipulation by 'job' plugins Before this change, job plugins were only loaded while displaying the form. This meant it was not possible to save an injected form field to the `params` column or change its value, since the injected XML did not show itself while validating form data. This commit fixes this issue, adds job plugins to some events in the constructor (needs review) and adds the new trashed state to the STATES array. --- .../com_cronjobs/src/Model/CronjobModel.php | 38 +++++++++++++++++-- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Model/CronjobModel.php b/administrator/components/com_cronjobs/src/Model/CronjobModel.php index d418d04b8c829..fc9bf03c15f7c 100644 --- a/administrator/components/com_cronjobs/src/Model/CronjobModel.php +++ b/administrator/components/com_cronjobs/src/Model/CronjobModel.php @@ -23,6 +23,7 @@ use Joomla\CMS\MVC\Factory\MVCFactoryInterface; use Joomla\CMS\MVC\Model\AdminModel; use Joomla\CMS\Object\CMSObject; +use Joomla\CMS\Plugin\PluginHelper; use Joomla\CMS\Table\Table; use Joomla\Component\Cronjobs\Administrator\Helper\CronjobsHelper; use function array_diff; @@ -47,10 +48,11 @@ class CronjobModel extends AdminModel * @var array * @since __DEPLOY_VERSION__ */ - protected $STATES = array( + protected $STATES = [ 'enabled' => 1, - 'disabled' => 0 - ); + 'disabled' => 0, + 'trashed' => -2 + ]; /** * Prefix used with controller messages @@ -89,6 +91,15 @@ class CronjobModel extends AdminModel */ public function __construct($config = array(), MVCFactoryInterface $factory = null, FormFactoryInterface $formFactory = null) { + $config['events_map'] = $config['events_map'] ?? []; + $config['events_map'] = array_merge( + [ + 'save' => 'job', + 'validate' => 'job' + ], + $config['events_map'] + ); + $this->app = Factory::getApplication(); parent::__construct($config, $factory, $formFactory); } @@ -426,4 +437,25 @@ function (string $x): int { return $isMatch ? "*" : $target; } + + /** + * Method to allow derived classes to preprocess the form. + * + * @param Form $form A Form object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import (defaults to "content"). + * + * @return void + * + * @since __DEPLOY_VERSION__ + * @throws Exception if there is an error in the form event. + */ + protected function preprocessForm(Form $form, $data, $group = 'content'): void + { + // Load the 'job' plugin group + PluginHelper::importPlugin('job'); + + // Let the parent method take over + parent::preprocessForm($form, $data, $group); + } } From 7337cb8797962c95acd9bc77225bc02e240a3244 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Thu, 5 Aug 2021 03:56:48 +0530 Subject: [PATCH 189/615] Cleanup CronjobModel Removes outdated comments, updates some others and fixes some formatting errors. --- .../com_cronjobs/src/Model/CronjobModel.php | 31 ++++++------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Model/CronjobModel.php b/administrator/components/com_cronjobs/src/Model/CronjobModel.php index fc9bf03c15f7c..16cb55b0037f2 100644 --- a/administrator/components/com_cronjobs/src/Model/CronjobModel.php +++ b/administrator/components/com_cronjobs/src/Model/CronjobModel.php @@ -118,14 +118,12 @@ public function __construct($config = array(), MVCFactoryInterface $factory = nu */ public function getForm($data = array(), $loadData = true) { - - // TODO : Can we need any custom fields [?] Form::addFieldPath(JPATH_ADMINISTRATOR . 'components/com_cronjobs/src/Field'); /* - * * : loadForm() (defined by FormBehaviourTrait) also loads the form data by calling - * loadFormData() : $data [implemented here] and binds it to the form by calling - * $form->bind($data). + * loadForm() (defined by FormBehaviourTrait) also loads the form data by calling + * loadFormData() : $data [implemented here] and binds it to the form by calling + * $form->bind($data). */ $form = $this->loadForm('com_cronjobs.cronjob', 'cronjob', ['control' => 'jform', 'load_data' => $loadData]); @@ -142,9 +140,7 @@ public function getForm($data = array(), $loadData = true) $form->setValue('type', null, $this->getState('cronjob.type')); } - /* - * TODO : Check if this is working as expected (what about new items, id == 0 ?) - */ + // TODO : Check if this is working as expected for new items (id == 0) if (!$user->authorise('core.edit.state', 'com_cronjobs.cronjob.' . $this->getState('job.id'))) { // Disable fields @@ -176,7 +172,6 @@ protected function canDelete($record): bool return false; } - // TODO : Check if this is the right way to check authority (in particular the assetName) return $this->app->getIdentity()->authorise('core.delete', 'com.cronjobs.cronjob.' . $record->id); } @@ -206,11 +201,10 @@ protected function populateState(): void } /** - * Probably don't _need_ to define this method since the parent getTable() - * implicitly deduces $name and $prefix anyways. This does make the object + * Don't need to define this method since the parent getTable() + * implicitly deduces $name and $prefix anyways. This makes the object * more transparent though. * - * * @param string $name Name of the table * @param string $prefix Class prefix * @param array $options Model config array @@ -235,11 +229,6 @@ public function getTable($name = 'Cronjob', $prefix = 'Table', $options = array( */ protected function loadFormData() { - /* - * Check session for previously entered form data - * ? : How and where does this data get saved? - * - */ $data = $this->app->getUserState('com_cronjobs.edit.cronjob.data', array()); // If the data from UserState is empty, we fetch it with getItem() @@ -251,10 +240,7 @@ protected function loadFormData() // TODO : Any further data processing goes here } - /* - * Let plugins manipulate the form (add fields) - * ? Using the 'job' group (as SelectModel), or should we target the 'cronjob' group? - */ + // Let plugins manipulate the data $this->preprocessData('com_cronjobs.cronjob', $data, 'job'); return $data; @@ -286,7 +272,6 @@ public function getItem($pk = null) $cronOption = ($item->id ?? 0) ? CronjobsHelper::getCronOptions()->findOption($item->type ?? 0) : ($this->getState('cronjob.option')); - CronjobsHelper::getCronOptions(); $item->set('cronOption', $cronOption); return $item; @@ -363,6 +348,8 @@ private function processExecutionRules(array &$data): void * Private method to build cron rules from input execution rules. * Cron rules are used internally to determine execution times/conditions. * + * ! A lot of DRY violations here... + * * @param array $data The form input data * * @return void From f55fc83ebf0b1ad012f05ace99220b24ba773cbd Mon Sep 17 00:00:00 2001 From: ditsuke Date: Thu, 5 Aug 2021 04:15:08 +0530 Subject: [PATCH 190/615] Implement JobTypeField to list all job types JobTypeField is a standard select field with options sorted naturally. With this commit, the Cronjobs filter form uses this field. --- .../com_cronjobs/forms/filter_cronjobs.xml | 4 +- .../com_cronjobs/src/Field/JobTypeField.php | 41 +++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/administrator/components/com_cronjobs/forms/filter_cronjobs.xml b/administrator/components/com_cronjobs/forms/filter_cronjobs.xml index 27adf4e896039..7b10ad6e8dff6 100644 --- a/administrator/components/com_cronjobs/forms/filter_cronjobs.xml +++ b/administrator/components/com_cronjobs/forms/filter_cronjobs.xml @@ -26,13 +26,11 @@ - - diff --git a/administrator/components/com_cronjobs/src/Field/JobTypeField.php b/administrator/components/com_cronjobs/src/Field/JobTypeField.php index 89999129ec931..27739bc7db903 100644 --- a/administrator/components/com_cronjobs/src/Field/JobTypeField.php +++ b/administrator/components/com_cronjobs/src/Field/JobTypeField.php @@ -14,7 +14,13 @@ // Restrict direct access defined('_JEXEC') or die; +use Exception; use Joomla\CMS\Form\Field\ListField; +use Joomla\CMS\HTML\HTMLHelper; +use Joomla\Component\Cronjobs\Administrator\Cronjobs\CronOption; +use Joomla\Component\Cronjobs\Administrator\Helper\CronjobsHelper; +use Joomla\Utilities\ArrayHelper; +use function array_map; /** * A list field with all available job types @@ -23,5 +29,40 @@ */ class JobTypeField extends ListField { + /** + * The form field type. + * + * @var string + * @since __DEPLOY_VERSION__ + */ + protected $type = 'jobType'; + /** + * Method to get field options + * + * @return array + * + * @throws Exception + * @since __DEPLOY_VERSION__ + */ + protected function getOptions(): array + { + $options = parent::getOptions(); + + // Get all available job types and sort by title + $types = ArrayHelper::sortObjects( + CronjobsHelper::getCronOptions()->options, + 'title', 1 + ); + + // Closure to add a CronOption as a
Joomla\Component\Cronjobs - - - - sql/mysql/install.sql - sql/postgresql/install.sql - - - - - sql/mysql/uninstall.sql - sql/postgresql/uninstall.sql - - - - - sql/updates/mysql - sql/updates/postgresql - - js css - Cronjobs + access.xml + config.xml + cronjobs.xml + forms + services + src + tmpl language/en-GB/com_cronjobs.ini language/en-GB/com_cronjobs.sys.ini + com_cronjobs - cronjobs + com_cronjobs From 4e262e373c6755262a8491545c6c767c5ad34245 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Thu, 19 Aug 2021 12:46:47 +0530 Subject: [PATCH 293/615] Fix XML code-style [2] - Align right angular brackets on newlines - Multiline tags have the first attribute on a newline - Tabs - Removes comments - Cleans up redundant tags --- .../components/com_cronjobs/config.xml | 22 +- .../components/com_cronjobs/cronjobs.xml | 4 +- .../components/com_cronjobs/forms/cronjob.xml | 396 +++++++++--------- .../com_cronjobs/forms/filter_cronjobs.xml | 80 ++-- plugins/job/requests/forms/get_requests.xml | 69 +-- plugins/job/testjob/forms/testJobForm.xml | 9 +- 6 files changed, 278 insertions(+), 302 deletions(-) diff --git a/administrator/components/com_cronjobs/config.xml b/administrator/components/com_cronjobs/config.xml index ae8597a1f788f..9b22dbdd154c9 100644 --- a/administrator/components/com_cronjobs/config.xml +++ b/administrator/components/com_cronjobs/config.xml @@ -1,18 +1,18 @@
+ name="permissions" + label="JCONFIG_PERMISSIONS_LABEL" + description="JCONFIG_PERMISSIONS_DESC" + >
diff --git a/administrator/components/com_cronjobs/cronjobs.xml b/administrator/components/com_cronjobs/cronjobs.xml index b5e75547ef2c0..6529a36c5a91c 100644 --- a/administrator/components/com_cronjobs/cronjobs.xml +++ b/administrator/components/com_cronjobs/cronjobs.xml @@ -28,6 +28,8 @@ com_cronjobs - com_cronjobs + + com_cronjobs + diff --git a/administrator/components/com_cronjobs/forms/cronjob.xml b/administrator/components/com_cronjobs/forms/cronjob.xml index 224cce5bc9204..8ddceedd30353 100644 --- a/administrator/components/com_cronjobs/forms/cronjob.xml +++ b/administrator/components/com_cronjobs/forms/cronjob.xml @@ -1,26 +1,23 @@ - - - - + + - - -
+ type="list" + label="COM_CRONJOBS_SELECT_TRIGGER" + validate="options" + required="true" + > @@ -28,236 +25,216 @@
- - - -
-
- - - - - - - - -
-
- - - - - - -
-
- - - - - - - - - - - - - - - - -
-
- +
- - - - -
@@ -266,8 +243,9 @@ + ! joomla.edit.params is resolved in the template -->
+
diff --git a/administrator/components/com_cronjobs/forms/filter_cronjobs.xml b/administrator/components/com_cronjobs/forms/filter_cronjobs.xml index 739d4289caf47..629ba069f4fe8 100644 --- a/administrator/components/com_cronjobs/forms/filter_cronjobs.xml +++ b/administrator/components/com_cronjobs/forms/filter_cronjobs.xml @@ -1,61 +1,53 @@
- - - - + name="state" + type="CronjobState" + label="JSTATUS" + onchange="this.form.submit();" + validate="options" + > - + name="type" + type="JobType" + label="COM_CRONJOBS_HEADING_JOB_TYPE" + onchange="this.form.submit();" + > - - + name="show_orphaned" + type="list" + label="COM_CRONJOBS_FIELD_LABEL_SHOW_ORPHANED" + default="0" + onchange="this.form.submit()" + > - + name="fullordering" + type="list" + label="JGLOBAL_SORT_BY" + onchange="this.form.submit();" + default="a.title DESC" + validate="options" + > @@ -68,14 +60,12 @@ - -
diff --git a/plugins/job/requests/forms/get_requests.xml b/plugins/job/requests/forms/get_requests.xml index 4d21ca6ff5348..fae4546cb1b8a 100644 --- a/plugins/job/requests/forms/get_requests.xml +++ b/plugins/job/requests/forms/get_requests.xml @@ -2,46 +2,51 @@
- - - + - + -
diff --git a/plugins/job/testjob/forms/testJobForm.xml b/plugins/job/testjob/forms/testJobForm.xml index e1ebad2d9aa9c..c31b3a8c4752e 100644 --- a/plugins/job/testjob/forms/testJobForm.xml +++ b/plugins/job/testjob/forms/testJobForm.xml @@ -2,10 +2,11 @@
-
From 17b40659205f3b1dd1251d6183431374f445b20a Mon Sep 17 00:00:00 2001 From: ditsuke Date: Thu, 19 Aug 2021 15:37:49 +0530 Subject: [PATCH 294/615] Move media files to the build directory Moves media files (js, css) to the `/build` directory. /media is populated by building/transpiling these files. Ref: #35143#discussion_r689947697 / @dgrammatiko --- .../com_cronjobs/css/admin-plg-job.css | 0 .../com_cronjobs/css/admin-view-cronjob.css | 0 .../com_cronjobs/joomla.asset.json | 0 .../js/admin-plg-job-search.es6..js | 0 .../js/admin-plg-job-search-es5.js | 106 ------------------ 5 files changed, 106 deletions(-) rename {media => build/media_source}/com_cronjobs/css/admin-plg-job.css (100%) rename {media => build/media_source}/com_cronjobs/css/admin-view-cronjob.css (100%) rename {media => build/media_source}/com_cronjobs/joomla.asset.json (100%) rename media/com_cronjobs/js/admin-plg-job-search.js => build/media_source/com_cronjobs/js/admin-plg-job-search.es6..js (100%) delete mode 100644 media/com_cronjobs/js/admin-plg-job-search-es5.js diff --git a/media/com_cronjobs/css/admin-plg-job.css b/build/media_source/com_cronjobs/css/admin-plg-job.css similarity index 100% rename from media/com_cronjobs/css/admin-plg-job.css rename to build/media_source/com_cronjobs/css/admin-plg-job.css diff --git a/media/com_cronjobs/css/admin-view-cronjob.css b/build/media_source/com_cronjobs/css/admin-view-cronjob.css similarity index 100% rename from media/com_cronjobs/css/admin-view-cronjob.css rename to build/media_source/com_cronjobs/css/admin-view-cronjob.css diff --git a/media/com_cronjobs/joomla.asset.json b/build/media_source/com_cronjobs/joomla.asset.json similarity index 100% rename from media/com_cronjobs/joomla.asset.json rename to build/media_source/com_cronjobs/joomla.asset.json diff --git a/media/com_cronjobs/js/admin-plg-job-search.js b/build/media_source/com_cronjobs/js/admin-plg-job-search.es6..js similarity index 100% rename from media/com_cronjobs/js/admin-plg-job-search.js rename to build/media_source/com_cronjobs/js/admin-plg-job-search.es6..js diff --git a/media/com_cronjobs/js/admin-plg-job-search-es5.js b/media/com_cronjobs/js/admin-plg-job-search-es5.js deleted file mode 100644 index aaf608dfdc781..0000000000000 --- a/media/com_cronjobs/js/admin-plg-job-search-es5.js +++ /dev/null @@ -1,106 +0,0 @@ -(function () { - 'use strict'; - - /** - * @copyright (C) 2021 Open Source Matters, Inc. - * @license GNU General Public License version 2 or later; see LICENSE.txt - */ - - /** - * Add a keyboard event listener to the Select a Job Type search element. - * - * IMPORTANT! This script is meant to be loaded deferred. This means that a. it's non-blocking - * (the browser can load it whenever) and b. it doesn't need an on DOMContentLoaded event handler - * because the browser is guaranteed to execute it only after the DOM content has loaded, the - * whole point of it being deferred. - * - * The search box has a keyboard handler that fires every time you press a keyboard button or send - * a keypress with a touch / virtual keyboard. We then iterate all job type cards and check if - * the plain text (HTML stripped out) representation of the job title or description partially - * matches the text you entered in the search box. If it doesn't we add a Bootstrap class to hide - * the job. - * - * This way we limit the displayed jobs only to those searched. - * - * This feature follows progressive enhancement. The search box is hidden by default and only - * displayed when this JavaScript here executes. Furthermore, session storage is only used if it - * is available in the browser. That's a bit of a pain but makes sure things won't break in older - * browsers. - * - * Furthermore and to facilitate the user experience we auto-focus the search element which has a - * suitable title so that non-sighted users are not startled. This way we address both UX concerns - * and accessibility. - * - * Finally, the search string is saved into session storage on the assumption that the user is - * probably going to be creating multiple instances of the same job, one after another, as is - * typical when building a new Joomla! site. - * @codingStandardsIgnoreStart - */ - // Make sure the element exists i.e. a template override has not removed it. - var elSearch = document.getElementById('comCronjobsSelectSearch'); - var elSearchContainer = document.getElementById('comCronjobsSelectSearchContainer'); - var elSearchHeader = document.getElementById('comCronjobsSelectTypeHeader'); - var elSearchResults = document.getElementById('comCronjobsSelectResultsContainer'); - var alertElement = document.querySelector('.jobs-alert'); - var elCards = [].slice.call(document.querySelectorAll('.comCronjobsSelectCard')); - - if (elSearch && elSearchContainer) { - // Add the keyboard event listener which performs the live search in the cards - elSearch.addEventListener('keyup', function (event) { - /** @type {KeyboardEvent} event */ - var partialSearch = event.target.value; - var hasSearchResults = false; // Save the search string into session storage - - if (typeof sessionStorage !== 'undefined') { - sessionStorage.setItem('Joomla.com_cronjobs.new.search', partialSearch); - } // Iterate all the job cards - - - elCards.forEach(function (card) { - // First remove the class which hides the job cards - card.classList.remove('d-none'); // An empty search string means that we should show everything - - if (!partialSearch) { - return; - } - - var cardHeader = card.querySelector('.new-job-title'); - var cardBody = card.querySelector('.card-body'); - var title = cardHeader ? cardHeader.textContent : ''; - var description = cardBody ? cardBody.textContent : ''; // If the job title and description don’t match add a class to hide it. - - if (title && !title.toLowerCase().includes(partialSearch.toLowerCase()) && description && !description.toLowerCase().includes(partialSearch.toLowerCase())) { - card.classList.add('d-none'); - } else { - hasSearchResults = true; - } - } - ); - - if (hasSearchResults || !partialSearch) { - alertElement.classList.add('d-none'); - elSearchHeader.classList.remove('d-none'); - elSearchResults.classList.remove('d-none'); - } else { - alertElement.classList.remove('d-none'); - elSearchHeader.classList.add('d-none'); - elSearchResults.classList.add('d-none'); - } - }); // For reasons of progressive enhancement the search box is hidden by default. - - elSearchContainer.classList.remove('d-none'); // Focus the just show element - - elSearch.focus(); - - try { - if (typeof sessionStorage !== 'undefined') { - // Load the search string from session storage - elSearch.value = sessionStorage.getItem('Joomla.com_cronjobs.new.search') || ''; // Trigger the keyboard handler event manually to initiate the search - - elSearch.dispatchEvent(new KeyboardEvent('keyup')); - } - } catch (e) {// This is probably Internet Explorer which doesn't support the KeyboardEvent constructor :( - } - } - -}()); From 47041148d3f4bfa311da479231b9114a551dbf38 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Thu, 19 Aug 2021 19:35:28 +0530 Subject: [PATCH 295/615] Update media build files - Fixes JS filename. - Fix JS styling, syntax and check ES6 compliance (it was already there). - Clean up and fix CSS. Ref: 35143#discussion_r689947697 / @dgrammatiko --- .../com_cronjobs/css/admin-plg-job.css | 8 +----- ...ch.es6..js => admin-plg-job-search.es6.js} | 28 +++++++++++-------- 2 files changed, 18 insertions(+), 18 deletions(-) rename build/media_source/com_cronjobs/js/{admin-plg-job-search.es6..js => admin-plg-job-search.es6.js} (81%) diff --git a/build/media_source/com_cronjobs/css/admin-plg-job.css b/build/media_source/com_cronjobs/css/admin-plg-job.css index 57e53ab1ea18e..e7330954d5939 100644 --- a/build/media_source/com_cronjobs/css/admin-plg-job.css +++ b/build/media_source/com_cronjobs/css/admin-plg-job.css @@ -41,7 +41,7 @@ } .new-job:hover .new-job-link { - background: var(--atum-bg-dark); + background: var(--template-bg-dark); } .new-job-link span { @@ -56,9 +56,3 @@ .new-jobs .card-columns { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)) !important; } - -#cli-job .new-job { - width: clamp(20em, 25vw, 50em); - margin: auto; - height: 12em; -} \ No newline at end of file diff --git a/build/media_source/com_cronjobs/js/admin-plg-job-search.es6..js b/build/media_source/com_cronjobs/js/admin-plg-job-search.es6.js similarity index 81% rename from build/media_source/com_cronjobs/js/admin-plg-job-search.es6..js rename to build/media_source/com_cronjobs/js/admin-plg-job-search.es6.js index 2212605dfe9f6..11598af71e0cf 100644 --- a/build/media_source/com_cronjobs/js/admin-plg-job-search.es6..js +++ b/build/media_source/com_cronjobs/js/admin-plg-job-search.es6.js @@ -43,20 +43,20 @@ const elCards = [].slice.call(document.querySelectorAll('.comCronjobsSelectCard' if (elSearch && elSearchContainer) { // Add the keyboard event listener which performs the live search in the cards - elSearch.addEventListener('keyup', event => { + elSearch.addEventListener('keyup', ({ target }) => { /** @type {KeyboardEvent} event */ - const partialSearch = event.target.value; + const partialSearch = target.value; let hasSearchResults = false; // Save the search string into session storage if (typeof sessionStorage !== 'undefined') { sessionStorage.setItem('Joomla.com_cronjobs.new.search', partialSearch); } // Iterate all the job cards - - elCards.forEach(card => { + elCards.forEach((card) => { // First remove the class which hide the job cards - card.classList.remove('d-none'); // An empty search string means that we should show everything + card.classList.remove('d-none'); + // An empty search string means that we should show everything if (!partialSearch) { return; } @@ -64,9 +64,11 @@ if (elSearch && elSearchContainer) { const cardHeader = card.querySelector('.new-job-title'); const cardBody = card.querySelector('.card-body'); const title = cardHeader ? cardHeader.textContent : ''; - const description = cardBody ? cardBody.textContent : ''; // If the job title and description don’t match add a class to hide it. + const description = cardBody ? cardBody.textContent : ''; - if (title && !title.toLowerCase().includes(partialSearch.toLowerCase()) && description && !description.toLowerCase().includes(partialSearch.toLowerCase())) { + // If the job title and description don’t match add a class to hide it. + if (title && !title.toLowerCase().includes(partialSearch.toLowerCase()) + && description && !description.toLowerCase().includes(partialSearch.toLowerCase())) { card.classList.add('d-none'); } else { hasSearchResults = true; @@ -82,19 +84,23 @@ if (elSearch && elSearchContainer) { elSearchHeader.classList.add('d-none'); elSearchResults.classList.add('d-none'); } - }); // For reasons of progressive enhancement the search box is hidden by default. + }); - elSearchContainer.classList.remove('d-none'); // Focus the just show element + // For reasons of progressive enhancement the search box is hidden by default. + elSearchContainer.classList.remove('d-none'); + // Focus the just show element elSearch.focus(); try { if (typeof sessionStorage !== 'undefined') { // Load the search string from session storage - elSearch.value = sessionStorage.getItem('Joomla.com_cronjobs.new.search') || ''; // Trigger the keyboard handler event manually to initiate the search + elSearch.value = sessionStorage.getItem('Joomla.com_cronjobs.new.search') || ''; + // Trigger the keyboard handler event manually to initiate the search elSearch.dispatchEvent(new KeyboardEvent('keyup')); } - } catch (e) {// This is probably Internet Explorer which doesn't support the KeyboardEvent constructor :( + } catch (e) { + // This is probably Internet Explorer which doesn't support the KeyboardEvent constructor :( } } From 62deeb495cc69eb6f820751cbb816ed7bb8a7cd8 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Thu, 19 Aug 2021 08:01:39 +0530 Subject: [PATCH 296/615] Replace TODO with @todo tag 's/TODO/@todo/g' Replaces TODO with @todo, which is parsed better by IDEs and static analyzers. Ref: #35143#discussion_r689548141 / @PhilETaylor --- .../components/com_cronjobs/forms/cronjob.xml | 2 +- .../components/com_cronjobs/forms/filter_cronjobs.xml | 2 +- .../com_cronjobs/src/Controller/CronjobController.php | 10 +++++----- .../com_cronjobs/src/Helper/ExecRuleHelper.php | 4 ++-- .../components/com_cronjobs/src/Model/CronjobModel.php | 4 ++-- .../com_cronjobs/src/Model/CronjobsModel.php | 10 +++++----- .../components/com_cronjobs/src/Table/CronjobTable.php | 4 ++-- .../com_cronjobs/src/View/Cronjob/HtmlView.php | 2 +- .../com_cronjobs/src/View/Cronjobs/HtmlView.php | 4 +--- .../com_cronjobs/src/View/Select/HtmlView.php | 2 +- .../components/com_cronjobs/tmpl/cronjob/edit.php | 4 ++-- .../components/com_cronjobs/tmpl/cronjobs/default.php | 6 ++---- 12 files changed, 25 insertions(+), 29 deletions(-) diff --git a/administrator/components/com_cronjobs/forms/cronjob.xml b/administrator/components/com_cronjobs/forms/cronjob.xml index d85d97928d955..224cce5bc9204 100644 --- a/administrator/components/com_cronjobs/forms/cronjob.xml +++ b/administrator/components/com_cronjobs/forms/cronjob.xml @@ -1,6 +1,6 @@ - + diff --git a/administrator/components/com_cronjobs/forms/filter_cronjobs.xml b/administrator/components/com_cronjobs/forms/filter_cronjobs.xml index 483d1de659d21..739d4289caf47 100644 --- a/administrator/components/com_cronjobs/forms/filter_cronjobs.xml +++ b/administrator/components/com_cronjobs/forms/filter_cronjobs.xml @@ -47,7 +47,7 @@ - + setUserState('com_cronjobs.add.cronjob.cronjob_type', $jobType); $app->setUserState('com_cronjobs.add.cronjob.cronjob_option', $jobOption); - // TODO : Parameter array handling below? + // @todo : Parameter array handling below? return $canAdd; } @@ -110,7 +110,7 @@ public function cancel($key = null): bool */ public function edit($key = null, $urlVar = null): bool { - // TODO: Change or remove + // @todo: Change or remove return parent::edit($key, $urlVar); } @@ -128,7 +128,7 @@ public function edit($key = null, $urlVar = null): bool */ protected function allowAdd($data = array()): bool { - // TODO: Change or remove + // @todo: Change or remove return parent::allowAdd($data); } @@ -156,7 +156,7 @@ protected function allowEdit($data = array(), $key = 'id'): bool return parent::allowEdit($data, $key); } - // TODO : Check if this works as expected + // @todo : Check if this works as expected return $this->app->getIdentity()->authorise('core.edit', 'com_cronjobs.cronjob.' . $recordId); } diff --git a/administrator/components/com_cronjobs/src/Helper/ExecRuleHelper.php b/administrator/components/com_cronjobs/src/Helper/ExecRuleHelper.php index 183fa28627a19..12a5065e90d18 100644 --- a/administrator/components/com_cronjobs/src/Helper/ExecRuleHelper.php +++ b/administrator/components/com_cronjobs/src/Helper/ExecRuleHelper.php @@ -101,7 +101,7 @@ public function nextExec(bool $string = true) $nextExec = $string ? $nextExec->toSql() : $nextExec; break; case 'cron': - // TODO: testing + // @todo: testing $cExp = new CronExpression((string) $this->rule->exp); $nextExec = $cExp->getNextRunDate('now', 0, false, 'GMT'); $nextExec = $string ? $this->dateTimeToSql($nextExec) : $nextExec; @@ -125,7 +125,7 @@ public function nextExec(bool $string = true) */ private function dateTimeToSql(DateTime $dateTime): string { - // TODO: Get DBO from DI container + // @todo: Get DBO from DI container static $db; $db = $db ?? Factory::getDbo(); diff --git a/administrator/components/com_cronjobs/src/Model/CronjobModel.php b/administrator/components/com_cronjobs/src/Model/CronjobModel.php index d1dada9f8684a..51fd857792a82 100644 --- a/administrator/components/com_cronjobs/src/Model/CronjobModel.php +++ b/administrator/components/com_cronjobs/src/Model/CronjobModel.php @@ -140,7 +140,7 @@ public function getForm($data = array(), $loadData = true) $form->setValue('type', null, $this->getState('cronjob.type')); } - // TODO : Check if this is working as expected for new items (id == 0) + // @todo : Check if this is working as expected for new items (id == 0) if (!$user->authorise('core.edit.state', 'com_cronjobs.cronjob.' . $this->getState('job.id'))) { // Disable fields @@ -237,7 +237,7 @@ protected function loadFormData() /** @var CMSObject $data */ $data = $this->getItem(); - // TODO : further data processing goes here + // @todo : further data processing goes here // For a fresh object, set exec-day and exec-time if (!$id = $data->id ?? 0) diff --git a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php index e3514fce16020..0e19c4b914bb6 100644 --- a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php +++ b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php @@ -190,7 +190,7 @@ protected function getListQuery(): QueryInterface ->bind(':type', $typeFilter); } - // TODO: Filter over trigger + // @todo: Filter over trigger // Filter over exit code ---- $exitCode = $this->getState('filter.last_exit_code'); @@ -226,7 +226,7 @@ protected function getListQuery(): QueryInterface $query->where($db->quoteName('a.id') . '= :id') ->bind(':id', $id, ParameterType::INTEGER); } - // Search by type is handled exceptionally in _getList() [TODO: remove refs] + // Search by type is handled exceptionally in _getList() [@todo: remove refs] elseif (stripos($searchStr, 'type:') !== 0) { $searchStr = "%$searchStr%"; @@ -252,7 +252,7 @@ protected function getListQuery(): QueryInterface // If ordering by type or state, also order by title. if (in_array($orderCol, ['a.type', 'a.state'])) { - // TODO : Test if things are working as expected + // @todo : Test if things are working as expected $query->order($db->quoteName('a.title') . ' ' . $orderDir); } @@ -289,7 +289,7 @@ protected function _getList($query, $limitstart = 0, $limit = 0): array $this->getDbo()->setQuery($query); // Return optionally an extended class. - // TODO: Use something other than CMSObject.. + // @todo: Use something other than CMSObject.. if ($customObj = $this->getState('list.customClass')) { $responseList = array_map( @@ -321,7 +321,7 @@ function (array $arr) { } // Filter out orphaned jobs if the state allows - // ! This breaks pagination at the moment [TODO: fix] + // ! This breaks pagination at the moment [@todo: fix] $showOrphaned = $this->getState('filter.show_orphaned'); if (!$showOrphaned) diff --git a/administrator/components/com_cronjobs/src/Table/CronjobTable.php b/administrator/components/com_cronjobs/src/Table/CronjobTable.php index dca0d9c315ee5..781b2227201e2 100644 --- a/administrator/components/com_cronjobs/src/Table/CronjobTable.php +++ b/administrator/components/com_cronjobs/src/Table/CronjobTable.php @@ -109,7 +109,7 @@ public function check(): bool $this->created = Factory::getDate()->toSql(); } - // TODO : Add more checks if needed + // @todo : Add more checks if needed return true; } @@ -133,7 +133,7 @@ public function store($updateNulls = false): bool $this->created = $date; } - // TODO : Should we add modified, modified_by fields? [ ] + // @todo : Should we add modified, modified_by fields? [ ] // Set created_by if needed if (empty($this->created_by)) diff --git a/administrator/components/com_cronjobs/src/View/Cronjob/HtmlView.php b/administrator/components/com_cronjobs/src/View/Cronjob/HtmlView.php index a0e240e4cc2b0..f74fce8327204 100644 --- a/administrator/components/com_cronjobs/src/View/Cronjob/HtmlView.php +++ b/administrator/components/com_cronjobs/src/View/Cronjob/HtmlView.php @@ -153,7 +153,7 @@ protected function addToolbar(): void ToolbarHelper::apply('cronjob.apply'); $toolbarButtons[] = ['save', 'cronjob.save']; - // TODO | ? : Do we need save2new and save2copy? If yes, need to support in the Model, + // @todo | ? : Do we need save2new and save2copy? If yes, need to support in the Model, // here and the Controller. } } diff --git a/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php b/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php index ac5f93cac9122..de3e824ae49d9 100644 --- a/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php +++ b/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php @@ -104,8 +104,6 @@ class HtmlView extends BaseHtmlView */ public function display($tpl = null): void { - // ! TODO : testing - $this->items = $this->get('Items'); $this->pagination = $this->get('Pagination'); $this->state = $this->get('State'); @@ -149,7 +147,7 @@ protected function addToolbar(): void /* * Get the toolbar object instance - * !! TODO : Replace usage with ToolbarFactoryInterface + * !! @todo : Replace usage with ToolbarFactoryInterface */ $toolbar = Toolbar::getInstance('toolbar'); diff --git a/administrator/components/com_cronjobs/src/View/Select/HtmlView.php b/administrator/components/com_cronjobs/src/View/Select/HtmlView.php index 85dae318ffb83..2e83acfae8e2c 100644 --- a/administrator/components/com_cronjobs/src/View/Select/HtmlView.php +++ b/administrator/components/com_cronjobs/src/View/Select/HtmlView.php @@ -123,7 +123,7 @@ protected function addToolbar(): void /* * Get the global Toolbar instance - * TODO : Replace usage with ToolbarFactoryInterface. but how? + * @todo : Replace usage with ToolbarFactoryInterface. but how? * Probably some changes in the core, since mod_menu calls and renders the getInstance() toolbar */ $toolbar = Toolbar::getInstance(); diff --git a/administrator/components/com_cronjobs/tmpl/cronjob/edit.php b/administrator/components/com_cronjobs/tmpl/cronjob/edit.php index bf57cdf7ea35d..f9546a680cc5d 100644 --- a/administrator/components/com_cronjobs/tmpl/cronjob/edit.php +++ b/administrator/components/com_cronjobs/tmpl/cronjob/edit.php @@ -74,7 +74,7 @@ class="form-validate">

escape(strip_tags($cronOption->desc)), 250); echo $desc; ?> @@ -101,7 +101,7 @@ class="form-validate">

form->renderFieldset('params-fs'); ?> diff --git a/administrator/components/com_cronjobs/tmpl/cronjobs/default.php b/administrator/components/com_cronjobs/tmpl/cronjobs/default.php index 7291b805992dd..3c54f7c35ad48 100644 --- a/administrator/components/com_cronjobs/tmpl/cronjobs/default.php +++ b/administrator/components/com_cronjobs/tmpl/cronjobs/default.php @@ -40,7 +40,6 @@ if ($saveOrder && !empty($this->items)) { - // TODO : Check if this works $saveOrderingUrl = 'index.php?option=com_cronjobs&task=cronjobs.saveOrderAjax&tmpl=component&' . Session::getFormToken() . '=1'; HTMLHelper::_('draggablelist.draggable'); } @@ -116,7 +115,6 @@ class="visually-hidden">
Joomla\Component\Cronjobs - - - - sql/mysql/install.sql - sql/postgresql/install.sql - - - - - sql/mysql/uninstall.sql - sql/postgresql/uninstall.sql - - - - - sql/updates/mysql - sql/updates/postgresql - - js css - Cronjobs + access.xml + config.xml + cronjobs.xml + forms + services + src + tmpl language/en-GB/com_cronjobs.ini language/en-GB/com_cronjobs.sys.ini + com_cronjobs - cronjobs + com_cronjobs From fd84074e7883b2dc661257415bb021f27b48ea6c Mon Sep 17 00:00:00 2001 From: ditsuke Date: Thu, 19 Aug 2021 12:46:47 +0530 Subject: [PATCH 298/615] Fix XML code-style [2] - Align right angular brackets on newlines - Multiline tags have the first attribute on a newline - Tabs - Removes comments - Cleans up redundant tags --- .../components/com_cronjobs/config.xml | 22 +- .../components/com_cronjobs/cronjobs.xml | 4 +- .../components/com_cronjobs/forms/cronjob.xml | 396 +++++++++--------- .../com_cronjobs/forms/filter_cronjobs.xml | 80 ++-- plugins/job/requests/forms/get_requests.xml | 69 +-- plugins/job/testjob/forms/testJobForm.xml | 9 +- 6 files changed, 278 insertions(+), 302 deletions(-) diff --git a/administrator/components/com_cronjobs/config.xml b/administrator/components/com_cronjobs/config.xml index ae8597a1f788f..9b22dbdd154c9 100644 --- a/administrator/components/com_cronjobs/config.xml +++ b/administrator/components/com_cronjobs/config.xml @@ -1,18 +1,18 @@
+ name="permissions" + label="JCONFIG_PERMISSIONS_LABEL" + description="JCONFIG_PERMISSIONS_DESC" + >
diff --git a/administrator/components/com_cronjobs/cronjobs.xml b/administrator/components/com_cronjobs/cronjobs.xml index b5e75547ef2c0..6529a36c5a91c 100644 --- a/administrator/components/com_cronjobs/cronjobs.xml +++ b/administrator/components/com_cronjobs/cronjobs.xml @@ -28,6 +28,8 @@ com_cronjobs - com_cronjobs + + com_cronjobs + diff --git a/administrator/components/com_cronjobs/forms/cronjob.xml b/administrator/components/com_cronjobs/forms/cronjob.xml index 224cce5bc9204..8ddceedd30353 100644 --- a/administrator/components/com_cronjobs/forms/cronjob.xml +++ b/administrator/components/com_cronjobs/forms/cronjob.xml @@ -1,26 +1,23 @@ - - - - + + - - -
+ type="list" + label="COM_CRONJOBS_SELECT_TRIGGER" + validate="options" + required="true" + > @@ -28,236 +25,216 @@
- - - -
-
- - - - - - - - -
-
- - - - - - -
-
- - - - - - - - - - - - - - - - -
-
- +
- - - - -
@@ -266,8 +243,9 @@ + ! joomla.edit.params is resolved in the template -->
+
diff --git a/administrator/components/com_cronjobs/forms/filter_cronjobs.xml b/administrator/components/com_cronjobs/forms/filter_cronjobs.xml index 739d4289caf47..629ba069f4fe8 100644 --- a/administrator/components/com_cronjobs/forms/filter_cronjobs.xml +++ b/administrator/components/com_cronjobs/forms/filter_cronjobs.xml @@ -1,61 +1,53 @@
- - - - + name="state" + type="CronjobState" + label="JSTATUS" + onchange="this.form.submit();" + validate="options" + > - + name="type" + type="JobType" + label="COM_CRONJOBS_HEADING_JOB_TYPE" + onchange="this.form.submit();" + > - - + name="show_orphaned" + type="list" + label="COM_CRONJOBS_FIELD_LABEL_SHOW_ORPHANED" + default="0" + onchange="this.form.submit()" + > - + name="fullordering" + type="list" + label="JGLOBAL_SORT_BY" + onchange="this.form.submit();" + default="a.title DESC" + validate="options" + > @@ -68,14 +60,12 @@ - -
diff --git a/plugins/job/requests/forms/get_requests.xml b/plugins/job/requests/forms/get_requests.xml index 4d21ca6ff5348..fae4546cb1b8a 100644 --- a/plugins/job/requests/forms/get_requests.xml +++ b/plugins/job/requests/forms/get_requests.xml @@ -2,46 +2,51 @@
- - - + - + -
diff --git a/plugins/job/testjob/forms/testJobForm.xml b/plugins/job/testjob/forms/testJobForm.xml index e1ebad2d9aa9c..c31b3a8c4752e 100644 --- a/plugins/job/testjob/forms/testJobForm.xml +++ b/plugins/job/testjob/forms/testJobForm.xml @@ -2,10 +2,11 @@
-
From 38ac6568e0181f96f54d060f97f97e0858e8d988 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Thu, 19 Aug 2021 15:37:49 +0530 Subject: [PATCH 299/615] Move media files to the build directory Moves media files (js, css) to the `/build` directory. /media is populated by building/transpiling these files. Ref: #35143#discussion_r689947697 / @dgrammatiko --- .../com_cronjobs/css/admin-plg-job.css | 0 .../com_cronjobs/css/admin-view-cronjob.css | 0 .../com_cronjobs/joomla.asset.json | 0 .../js/admin-plg-job-search.es6..js | 0 .../js/admin-plg-job-search-es5.js | 106 ------------------ 5 files changed, 106 deletions(-) rename {media => build/media_source}/com_cronjobs/css/admin-plg-job.css (100%) rename {media => build/media_source}/com_cronjobs/css/admin-view-cronjob.css (100%) rename {media => build/media_source}/com_cronjobs/joomla.asset.json (100%) rename media/com_cronjobs/js/admin-plg-job-search.js => build/media_source/com_cronjobs/js/admin-plg-job-search.es6..js (100%) delete mode 100644 media/com_cronjobs/js/admin-plg-job-search-es5.js diff --git a/media/com_cronjobs/css/admin-plg-job.css b/build/media_source/com_cronjobs/css/admin-plg-job.css similarity index 100% rename from media/com_cronjobs/css/admin-plg-job.css rename to build/media_source/com_cronjobs/css/admin-plg-job.css diff --git a/media/com_cronjobs/css/admin-view-cronjob.css b/build/media_source/com_cronjobs/css/admin-view-cronjob.css similarity index 100% rename from media/com_cronjobs/css/admin-view-cronjob.css rename to build/media_source/com_cronjobs/css/admin-view-cronjob.css diff --git a/media/com_cronjobs/joomla.asset.json b/build/media_source/com_cronjobs/joomla.asset.json similarity index 100% rename from media/com_cronjobs/joomla.asset.json rename to build/media_source/com_cronjobs/joomla.asset.json diff --git a/media/com_cronjobs/js/admin-plg-job-search.js b/build/media_source/com_cronjobs/js/admin-plg-job-search.es6..js similarity index 100% rename from media/com_cronjobs/js/admin-plg-job-search.js rename to build/media_source/com_cronjobs/js/admin-plg-job-search.es6..js diff --git a/media/com_cronjobs/js/admin-plg-job-search-es5.js b/media/com_cronjobs/js/admin-plg-job-search-es5.js deleted file mode 100644 index aaf608dfdc781..0000000000000 --- a/media/com_cronjobs/js/admin-plg-job-search-es5.js +++ /dev/null @@ -1,106 +0,0 @@ -(function () { - 'use strict'; - - /** - * @copyright (C) 2021 Open Source Matters, Inc. - * @license GNU General Public License version 2 or later; see LICENSE.txt - */ - - /** - * Add a keyboard event listener to the Select a Job Type search element. - * - * IMPORTANT! This script is meant to be loaded deferred. This means that a. it's non-blocking - * (the browser can load it whenever) and b. it doesn't need an on DOMContentLoaded event handler - * because the browser is guaranteed to execute it only after the DOM content has loaded, the - * whole point of it being deferred. - * - * The search box has a keyboard handler that fires every time you press a keyboard button or send - * a keypress with a touch / virtual keyboard. We then iterate all job type cards and check if - * the plain text (HTML stripped out) representation of the job title or description partially - * matches the text you entered in the search box. If it doesn't we add a Bootstrap class to hide - * the job. - * - * This way we limit the displayed jobs only to those searched. - * - * This feature follows progressive enhancement. The search box is hidden by default and only - * displayed when this JavaScript here executes. Furthermore, session storage is only used if it - * is available in the browser. That's a bit of a pain but makes sure things won't break in older - * browsers. - * - * Furthermore and to facilitate the user experience we auto-focus the search element which has a - * suitable title so that non-sighted users are not startled. This way we address both UX concerns - * and accessibility. - * - * Finally, the search string is saved into session storage on the assumption that the user is - * probably going to be creating multiple instances of the same job, one after another, as is - * typical when building a new Joomla! site. - * @codingStandardsIgnoreStart - */ - // Make sure the element exists i.e. a template override has not removed it. - var elSearch = document.getElementById('comCronjobsSelectSearch'); - var elSearchContainer = document.getElementById('comCronjobsSelectSearchContainer'); - var elSearchHeader = document.getElementById('comCronjobsSelectTypeHeader'); - var elSearchResults = document.getElementById('comCronjobsSelectResultsContainer'); - var alertElement = document.querySelector('.jobs-alert'); - var elCards = [].slice.call(document.querySelectorAll('.comCronjobsSelectCard')); - - if (elSearch && elSearchContainer) { - // Add the keyboard event listener which performs the live search in the cards - elSearch.addEventListener('keyup', function (event) { - /** @type {KeyboardEvent} event */ - var partialSearch = event.target.value; - var hasSearchResults = false; // Save the search string into session storage - - if (typeof sessionStorage !== 'undefined') { - sessionStorage.setItem('Joomla.com_cronjobs.new.search', partialSearch); - } // Iterate all the job cards - - - elCards.forEach(function (card) { - // First remove the class which hides the job cards - card.classList.remove('d-none'); // An empty search string means that we should show everything - - if (!partialSearch) { - return; - } - - var cardHeader = card.querySelector('.new-job-title'); - var cardBody = card.querySelector('.card-body'); - var title = cardHeader ? cardHeader.textContent : ''; - var description = cardBody ? cardBody.textContent : ''; // If the job title and description don’t match add a class to hide it. - - if (title && !title.toLowerCase().includes(partialSearch.toLowerCase()) && description && !description.toLowerCase().includes(partialSearch.toLowerCase())) { - card.classList.add('d-none'); - } else { - hasSearchResults = true; - } - } - ); - - if (hasSearchResults || !partialSearch) { - alertElement.classList.add('d-none'); - elSearchHeader.classList.remove('d-none'); - elSearchResults.classList.remove('d-none'); - } else { - alertElement.classList.remove('d-none'); - elSearchHeader.classList.add('d-none'); - elSearchResults.classList.add('d-none'); - } - }); // For reasons of progressive enhancement the search box is hidden by default. - - elSearchContainer.classList.remove('d-none'); // Focus the just show element - - elSearch.focus(); - - try { - if (typeof sessionStorage !== 'undefined') { - // Load the search string from session storage - elSearch.value = sessionStorage.getItem('Joomla.com_cronjobs.new.search') || ''; // Trigger the keyboard handler event manually to initiate the search - - elSearch.dispatchEvent(new KeyboardEvent('keyup')); - } - } catch (e) {// This is probably Internet Explorer which doesn't support the KeyboardEvent constructor :( - } - } - -}()); From fa1e39b009d32b47a7ebae4fa645c4bde45a7876 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Thu, 19 Aug 2021 19:35:28 +0530 Subject: [PATCH 300/615] Update media build files - Fixes JS filename. - Fix JS styling, syntax and check ES6 compliance (it was already there). - Clean up and fix CSS. Ref: 35143#discussion_r689947697 / @dgrammatiko --- .../com_cronjobs/css/admin-plg-job.css | 8 +----- ...ch.es6..js => admin-plg-job-search.es6.js} | 28 +++++++++++-------- 2 files changed, 18 insertions(+), 18 deletions(-) rename build/media_source/com_cronjobs/js/{admin-plg-job-search.es6..js => admin-plg-job-search.es6.js} (81%) diff --git a/build/media_source/com_cronjobs/css/admin-plg-job.css b/build/media_source/com_cronjobs/css/admin-plg-job.css index 57e53ab1ea18e..e7330954d5939 100644 --- a/build/media_source/com_cronjobs/css/admin-plg-job.css +++ b/build/media_source/com_cronjobs/css/admin-plg-job.css @@ -41,7 +41,7 @@ } .new-job:hover .new-job-link { - background: var(--atum-bg-dark); + background: var(--template-bg-dark); } .new-job-link span { @@ -56,9 +56,3 @@ .new-jobs .card-columns { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)) !important; } - -#cli-job .new-job { - width: clamp(20em, 25vw, 50em); - margin: auto; - height: 12em; -} \ No newline at end of file diff --git a/build/media_source/com_cronjobs/js/admin-plg-job-search.es6..js b/build/media_source/com_cronjobs/js/admin-plg-job-search.es6.js similarity index 81% rename from build/media_source/com_cronjobs/js/admin-plg-job-search.es6..js rename to build/media_source/com_cronjobs/js/admin-plg-job-search.es6.js index 2212605dfe9f6..11598af71e0cf 100644 --- a/build/media_source/com_cronjobs/js/admin-plg-job-search.es6..js +++ b/build/media_source/com_cronjobs/js/admin-plg-job-search.es6.js @@ -43,20 +43,20 @@ const elCards = [].slice.call(document.querySelectorAll('.comCronjobsSelectCard' if (elSearch && elSearchContainer) { // Add the keyboard event listener which performs the live search in the cards - elSearch.addEventListener('keyup', event => { + elSearch.addEventListener('keyup', ({ target }) => { /** @type {KeyboardEvent} event */ - const partialSearch = event.target.value; + const partialSearch = target.value; let hasSearchResults = false; // Save the search string into session storage if (typeof sessionStorage !== 'undefined') { sessionStorage.setItem('Joomla.com_cronjobs.new.search', partialSearch); } // Iterate all the job cards - - elCards.forEach(card => { + elCards.forEach((card) => { // First remove the class which hide the job cards - card.classList.remove('d-none'); // An empty search string means that we should show everything + card.classList.remove('d-none'); + // An empty search string means that we should show everything if (!partialSearch) { return; } @@ -64,9 +64,11 @@ if (elSearch && elSearchContainer) { const cardHeader = card.querySelector('.new-job-title'); const cardBody = card.querySelector('.card-body'); const title = cardHeader ? cardHeader.textContent : ''; - const description = cardBody ? cardBody.textContent : ''; // If the job title and description don’t match add a class to hide it. + const description = cardBody ? cardBody.textContent : ''; - if (title && !title.toLowerCase().includes(partialSearch.toLowerCase()) && description && !description.toLowerCase().includes(partialSearch.toLowerCase())) { + // If the job title and description don’t match add a class to hide it. + if (title && !title.toLowerCase().includes(partialSearch.toLowerCase()) + && description && !description.toLowerCase().includes(partialSearch.toLowerCase())) { card.classList.add('d-none'); } else { hasSearchResults = true; @@ -82,19 +84,23 @@ if (elSearch && elSearchContainer) { elSearchHeader.classList.add('d-none'); elSearchResults.classList.add('d-none'); } - }); // For reasons of progressive enhancement the search box is hidden by default. + }); - elSearchContainer.classList.remove('d-none'); // Focus the just show element + // For reasons of progressive enhancement the search box is hidden by default. + elSearchContainer.classList.remove('d-none'); + // Focus the just show element elSearch.focus(); try { if (typeof sessionStorage !== 'undefined') { // Load the search string from session storage - elSearch.value = sessionStorage.getItem('Joomla.com_cronjobs.new.search') || ''; // Trigger the keyboard handler event manually to initiate the search + elSearch.value = sessionStorage.getItem('Joomla.com_cronjobs.new.search') || ''; + // Trigger the keyboard handler event manually to initiate the search elSearch.dispatchEvent(new KeyboardEvent('keyup')); } - } catch (e) {// This is probably Internet Explorer which doesn't support the KeyboardEvent constructor :( + } catch (e) { + // This is probably Internet Explorer which doesn't support the KeyboardEvent constructor :( } } From 5d9330bb848a69fab6273438bf56b5030152f432 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Thu, 19 Aug 2021 20:14:56 +0530 Subject: [PATCH 301/615] Update com_cronjobs language files, usages - Replaces redundant strings, usages with global equivalents. - Updates language strings for SelectView, CronjobsView. Ref: #35143#issuecomment-899266766 / @brianteeman --- administrator/components/com_cronjobs/forms/cronjob.xml | 4 ++-- .../components/com_cronjobs/src/Model/CronjobsModel.php | 2 +- .../components/com_cronjobs/tmpl/cronjob/edit.php | 8 ++++---- administrator/language/en-GB/com_cronjobs.ini | 9 ++------- administrator/language/en-GB/com_cronjobs.sys.ini | 2 +- 5 files changed, 10 insertions(+), 15 deletions(-) diff --git a/administrator/components/com_cronjobs/forms/cronjob.xml b/administrator/components/com_cronjobs/forms/cronjob.xml index 8ddceedd30353..4aeacd1a14935 100644 --- a/administrator/components/com_cronjobs/forms/cronjob.xml +++ b/administrator/components/com_cronjobs/forms/cronjob.xml @@ -106,7 +106,7 @@
diff --git a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php index 0e19c4b914bb6..c35dce592392f 100644 --- a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php +++ b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php @@ -356,7 +356,7 @@ private function attachCronOptions(array &$items): void foreach ($items as $item) { $item->cronOption = $cronOptions->findOption($item->type); - $item->safeTypeTitle = $item->cronOption->title ?? Text::_('COM_CRONJOBS_NA'); + $item->safeTypeTitle = $item->cronOption->title ?? Text::_('JGLOBAL_NONAPPLICABLE'); } } diff --git a/administrator/components/com_cronjobs/tmpl/cronjob/edit.php b/administrator/components/com_cronjobs/tmpl/cronjob/edit.php index f9546a680cc5d..b39dc15ca8dca 100644 --- a/administrator/components/com_cronjobs/tmpl/cronjob/edit.php +++ b/administrator/components/com_cronjobs/tmpl/cronjob/edit.php @@ -126,11 +126,11 @@ class="form-validate"> - +
- + form->renderFieldset('details'); ?>
@@ -139,9 +139,9 @@ class="form-validate"> canDo->get('core.admin')) : ?> - +
- +
form->getInput('rules'); ?>
diff --git a/administrator/language/en-GB/com_cronjobs.ini b/administrator/language/en-GB/com_cronjobs.ini index 7991cff7be1da..236e066fa2611 100644 --- a/administrator/language/en-GB/com_cronjobs.ini +++ b/administrator/language/en-GB/com_cronjobs.ini @@ -8,12 +8,10 @@ COM_CRONJOBS_CLI_JOBS_TITLE="CLI/Script Job" COM_CRONJOBS_DASHBOARD_TITLE="Cronjobs Manager" COM_CRONJOBS_EDIT_CRONJOB="Edit Cronjob" COM_CRONJOBS_EMPTYSTATE_BUTTON_ADD="Add a Cronjob!" -COM_CRONJOBS_EMPTYSTATE_CONTENT="No entries!" +COM_CRONJOBS_EMPTYSTATE_CONTENT="No cronjobs!" COM_CRONJOBS_EMPTYSTATE_TITLE="No Cronjobs have been created yet!" COM_CRONJOBS_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW="You need to select a Job Type first!" COM_CRONJOBS_ERROR_INVALID_JOB_TYPE="Invalid Job Type!" -COM_CRONJOBS_FIELD_CREATED_BY_LABEL="Created By" -COM_CRONJOBS_FIELD_CREATED_LABEL="Created" COM_CRONJOBS_FIELD_JOB_TYPE="Type ID" COM_CRONJOBS_FIELD_LABEL_EXEC_RULE="Execution Rule" COM_CRONJOBS_FIELD_LABEL_INTERVAL_DAYS="Interval in Days" @@ -28,10 +26,8 @@ COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_MINUTES="Minutes" COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_MONTHS="Months" COM_CRONJOBS_FIELDSET_BASIC="Basic Fields" COM_CRONJOBS_FIELDSET_CRON_OPTIONS="Cron Options" -COM_CRONJOBS_FIELDSET_DETAILS="Details" COM_CRONJOBS_FIELDSET_EXEC_HIST="Execution History" COM_CRONJOBS_FIELDSET_PARAMS_FS="Job Parameters" -COM_CRONJOBS_FIELDSET_RULES="Permissions" COM_CRONJOBS_FILTER_SEARCH_DESC="Search in cronjob title and note. Prefix with 'ID:' to search for a job ID" COM_CRONJOBS_FILTER_SEARCH_LABEL="Search Cronjobs" COM_CRONJOBS_FORM_TITLE_EDIT="Edit Cronjob" @@ -57,7 +53,7 @@ COM_CRONJOBS_MANAGER_CRONJOB="Cronjob Manager" COM_CRONJOBS_MANAGER_CRONJOB_EDIT="Edit Cronjob" COM_CRONJOBS_MANAGER_CRONJOB_NEW="New Cronjob" COM_CRONJOBS_MANAGER_CRONJOBS="Cronjobs Manager" -COM_CRONJOBS_MSG_MANAGE_NO_JOB_PLUGINS="There are no plugin jobs matching your query" +COM_CRONJOBS_MSG_MANAGE_NO_JOB_PLUGINS="There are no jobs types matching your query" COM_CRONJOBS_N_ITEMS_DELETED="%s cronjobs deleted." COM_CRONJOBS_N_ITEMS_DELETED_1="Cronjob deleted." COM_CRONJOBS_N_ITEMS_PUBLISHED="%s cronjobs enabled." @@ -66,7 +62,6 @@ COM_CRONJOBS_N_ITEMS_TRASHED="%s cronjobs trashed." COM_CRONJOBS_N_ITEMS_TRASHED_1="Cronjob trashed." COM_CRONJOBS_N_ITEMS_UNPUBLISHED="%s cronjobs disabled." COM_CRONJOBS_N_ITEMS_UNPUBLISHED_1="Cronjob disabled." -COM_CRONJOBS_NA="N/A" COM_CRONJOBS_NEW_CRONJOB="New Cronjob" COM_CRONJOBS_NO_NOTE="" COM_CRONJOBS_OPTION_INTERVAL_CUSTOM="Custom Match (Advanced)" diff --git a/administrator/language/en-GB/com_cronjobs.sys.ini b/administrator/language/en-GB/com_cronjobs.sys.ini index e6cae94d445e2..930633c6cfff0 100644 --- a/administrator/language/en-GB/com_cronjobs.sys.ini +++ b/administrator/language/en-GB/com_cronjobs.sys.ini @@ -9,5 +9,5 @@ COM_CRONJOBS_MANAGER_CRONJOB="Cronjob Manager" COM_CRONJOBS_MANAGER_CRONJOB_EDIT="Edit Cronjob" COM_CRONJOBS_MANAGER_CRONJOB_NEW="New Cronjob" COM_CRONJOBS_MANAGER_CRONJOBS="Cronjobs Manager" -COM_CRONJOBS_MSG_MANAGE_NO_JOB_PLUGINS="There are no plugin jobs matching your query" +COM_CRONJOBS_MSG_MANAGE_NO_JOB_PLUGINS="There are no jobs types matching your query" COM_CRONJOBS_XML_DESCRIPTION="Component for managing pseudo-cronjobs and cronjobs (if server supports)" From 101a03d14f5f020c4cb4e144eac8e5537ddd64bb Mon Sep 17 00:00:00 2001 From: ditsuke Date: Thu, 19 Aug 2021 20:14:56 +0530 Subject: [PATCH 302/615] Update com_cronjobs language files, usages - Replaces redundant strings, usages with global equivalents. - Updates language strings for SelectView, CronjobsView. Ref: #35143#issuecomment-899266766 / @brianteeman --- administrator/components/com_cronjobs/forms/cronjob.xml | 4 ++-- .../components/com_cronjobs/src/Model/CronjobsModel.php | 2 +- .../components/com_cronjobs/tmpl/cronjob/edit.php | 8 ++++---- administrator/language/en-GB/com_cronjobs.ini | 9 ++------- administrator/language/en-GB/com_cronjobs.sys.ini | 2 +- 5 files changed, 10 insertions(+), 15 deletions(-) diff --git a/administrator/components/com_cronjobs/forms/cronjob.xml b/administrator/components/com_cronjobs/forms/cronjob.xml index 8ddceedd30353..4aeacd1a14935 100644 --- a/administrator/components/com_cronjobs/forms/cronjob.xml +++ b/administrator/components/com_cronjobs/forms/cronjob.xml @@ -106,7 +106,7 @@
diff --git a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php index 0e19c4b914bb6..c35dce592392f 100644 --- a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php +++ b/administrator/components/com_cronjobs/src/Model/CronjobsModel.php @@ -356,7 +356,7 @@ private function attachCronOptions(array &$items): void foreach ($items as $item) { $item->cronOption = $cronOptions->findOption($item->type); - $item->safeTypeTitle = $item->cronOption->title ?? Text::_('COM_CRONJOBS_NA'); + $item->safeTypeTitle = $item->cronOption->title ?? Text::_('JGLOBAL_NONAPPLICABLE'); } } diff --git a/administrator/components/com_cronjobs/tmpl/cronjob/edit.php b/administrator/components/com_cronjobs/tmpl/cronjob/edit.php index f9546a680cc5d..b39dc15ca8dca 100644 --- a/administrator/components/com_cronjobs/tmpl/cronjob/edit.php +++ b/administrator/components/com_cronjobs/tmpl/cronjob/edit.php @@ -126,11 +126,11 @@ class="form-validate"> - +
- + form->renderFieldset('details'); ?>
@@ -139,9 +139,9 @@ class="form-validate"> canDo->get('core.admin')) : ?> - +
- +
form->getInput('rules'); ?>
diff --git a/administrator/language/en-GB/com_cronjobs.ini b/administrator/language/en-GB/com_cronjobs.ini index 7991cff7be1da..236e066fa2611 100644 --- a/administrator/language/en-GB/com_cronjobs.ini +++ b/administrator/language/en-GB/com_cronjobs.ini @@ -8,12 +8,10 @@ COM_CRONJOBS_CLI_JOBS_TITLE="CLI/Script Job" COM_CRONJOBS_DASHBOARD_TITLE="Cronjobs Manager" COM_CRONJOBS_EDIT_CRONJOB="Edit Cronjob" COM_CRONJOBS_EMPTYSTATE_BUTTON_ADD="Add a Cronjob!" -COM_CRONJOBS_EMPTYSTATE_CONTENT="No entries!" +COM_CRONJOBS_EMPTYSTATE_CONTENT="No cronjobs!" COM_CRONJOBS_EMPTYSTATE_TITLE="No Cronjobs have been created yet!" COM_CRONJOBS_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW="You need to select a Job Type first!" COM_CRONJOBS_ERROR_INVALID_JOB_TYPE="Invalid Job Type!" -COM_CRONJOBS_FIELD_CREATED_BY_LABEL="Created By" -COM_CRONJOBS_FIELD_CREATED_LABEL="Created" COM_CRONJOBS_FIELD_JOB_TYPE="Type ID" COM_CRONJOBS_FIELD_LABEL_EXEC_RULE="Execution Rule" COM_CRONJOBS_FIELD_LABEL_INTERVAL_DAYS="Interval in Days" @@ -28,10 +26,8 @@ COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_MINUTES="Minutes" COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_MONTHS="Months" COM_CRONJOBS_FIELDSET_BASIC="Basic Fields" COM_CRONJOBS_FIELDSET_CRON_OPTIONS="Cron Options" -COM_CRONJOBS_FIELDSET_DETAILS="Details" COM_CRONJOBS_FIELDSET_EXEC_HIST="Execution History" COM_CRONJOBS_FIELDSET_PARAMS_FS="Job Parameters" -COM_CRONJOBS_FIELDSET_RULES="Permissions" COM_CRONJOBS_FILTER_SEARCH_DESC="Search in cronjob title and note. Prefix with 'ID:' to search for a job ID" COM_CRONJOBS_FILTER_SEARCH_LABEL="Search Cronjobs" COM_CRONJOBS_FORM_TITLE_EDIT="Edit Cronjob" @@ -57,7 +53,7 @@ COM_CRONJOBS_MANAGER_CRONJOB="Cronjob Manager" COM_CRONJOBS_MANAGER_CRONJOB_EDIT="Edit Cronjob" COM_CRONJOBS_MANAGER_CRONJOB_NEW="New Cronjob" COM_CRONJOBS_MANAGER_CRONJOBS="Cronjobs Manager" -COM_CRONJOBS_MSG_MANAGE_NO_JOB_PLUGINS="There are no plugin jobs matching your query" +COM_CRONJOBS_MSG_MANAGE_NO_JOB_PLUGINS="There are no jobs types matching your query" COM_CRONJOBS_N_ITEMS_DELETED="%s cronjobs deleted." COM_CRONJOBS_N_ITEMS_DELETED_1="Cronjob deleted." COM_CRONJOBS_N_ITEMS_PUBLISHED="%s cronjobs enabled." @@ -66,7 +62,6 @@ COM_CRONJOBS_N_ITEMS_TRASHED="%s cronjobs trashed." COM_CRONJOBS_N_ITEMS_TRASHED_1="Cronjob trashed." COM_CRONJOBS_N_ITEMS_UNPUBLISHED="%s cronjobs disabled." COM_CRONJOBS_N_ITEMS_UNPUBLISHED_1="Cronjob disabled." -COM_CRONJOBS_NA="N/A" COM_CRONJOBS_NEW_CRONJOB="New Cronjob" COM_CRONJOBS_NO_NOTE="" COM_CRONJOBS_OPTION_INTERVAL_CUSTOM="Custom Match (Advanced)" diff --git a/administrator/language/en-GB/com_cronjobs.sys.ini b/administrator/language/en-GB/com_cronjobs.sys.ini index e6cae94d445e2..930633c6cfff0 100644 --- a/administrator/language/en-GB/com_cronjobs.sys.ini +++ b/administrator/language/en-GB/com_cronjobs.sys.ini @@ -9,5 +9,5 @@ COM_CRONJOBS_MANAGER_CRONJOB="Cronjob Manager" COM_CRONJOBS_MANAGER_CRONJOB_EDIT="Edit Cronjob" COM_CRONJOBS_MANAGER_CRONJOB_NEW="New Cronjob" COM_CRONJOBS_MANAGER_CRONJOBS="Cronjobs Manager" -COM_CRONJOBS_MSG_MANAGE_NO_JOB_PLUGINS="There are no plugin jobs matching your query" +COM_CRONJOBS_MSG_MANAGE_NO_JOB_PLUGINS="There are no jobs types matching your query" COM_CRONJOBS_XML_DESCRIPTION="Component for managing pseudo-cronjobs and cronjobs (if server supports)" From 3da8a754cfa9016c93041ba9ebbd8f967567cb98 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Fri, 20 Aug 2021 10:25:30 +0530 Subject: [PATCH 303/615] Get DBO from the DI Container Gets the DBO from the DI container instead of the deprecated Factory::getDBO() method. Ref: #35143#issuecomment-899532810 / @PhilETaylor --- .../components/com_cronjobs/src/Helper/ExecRuleHelper.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/administrator/components/com_cronjobs/src/Helper/ExecRuleHelper.php b/administrator/components/com_cronjobs/src/Helper/ExecRuleHelper.php index 12a5065e90d18..35e21138cfe71 100644 --- a/administrator/components/com_cronjobs/src/Helper/ExecRuleHelper.php +++ b/administrator/components/com_cronjobs/src/Helper/ExecRuleHelper.php @@ -20,6 +20,7 @@ use Exception; use Joomla\CMS\Date\Date; use Joomla\CMS\Factory; +use Joomla\Database\DatabaseDriver; use Joomla\Utilities\ArrayHelper; /** @@ -125,9 +126,8 @@ public function nextExec(bool $string = true) */ private function dateTimeToSql(DateTime $dateTime): string { - // @todo: Get DBO from DI container static $db; - $db = $db ?? Factory::getDbo(); + $db = $db ?? Factory::getContainer()->get(DatabaseDriver::class); return $dateTime->format($db->getDateFormat()); } From 3d91703de4ff110f8ec0462d8c275a2cd64ea3f9 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Fri, 20 Aug 2021 15:17:44 +0530 Subject: [PATCH 304/615] Update plg testjob Adds a 20s sleep as the routine for both supported jobs. TBC. --- plugins/job/testjob/testjob.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/job/testjob/testjob.php b/plugins/job/testjob/testjob.php index bace074d49984..c932d71a51f7e 100644 --- a/plugins/job/testjob/testjob.php +++ b/plugins/job/testjob/testjob.php @@ -94,6 +94,9 @@ public function cronSampleRoutine(CronRunEvent $event): void $params = $event->getArgument('params'); // Plugin does whatever it wants + $this->addJobLog('Starting 20s timeout'); + sleep(20); + $this->addJobLog('20s timeout over!'); $this->jobEnd($event, 0); } From 81d4d5ddb1b83ae60c06aaa16a6d39b8818b3bcc Mon Sep 17 00:00:00 2001 From: ditsuke Date: Fri, 20 Aug 2021 21:10:45 +0530 Subject: [PATCH 305/615] Refactor com_cronjobs [1] - Renames /components `com_cronjobs` => `com_scheduler`. - Renames /build `com_cronjobs` => `com_scheduler`. - Renames all com_cronjobs occurrences. - Renames language files and strings. - Renames DB table and #__extensions, #__assets entries. --- .../sql/updates/mysql/4.1.0-2021-08-04.sql | 4 +- .../updates/postgresql/4.1.0-2021-08-04.sql | 4 +- .../com_cronjobs/tmpl/cronjobs/default.xml | 8 -- .../components/com_menus/presets/system.xml | 6 +- .../access.xml | 2 +- .../config.xml | 2 +- .../forms/cronjob.xml | 52 +++++------ .../forms/filter_cronjobs.xml | 18 ++-- .../layouts/Joomla/form/field/interval.php | 4 +- .../scheduler.xml} | 18 ++-- .../services/provider.php | 4 +- .../src/Controller/CronjobController.php | 14 +-- .../src/Controller/CronjobsController.php | 2 +- .../src/Controller/DisplayController.php | 12 +-- .../src/Cronjobs/CronOption.php | 4 +- .../src/Cronjobs/CronOptions.php | 4 +- .../src/Event/CronRunEvent.php | 2 +- .../src/Extension/CronjobsComponent.php | 2 +- .../src/Field/CronField.php | 2 +- .../src/Field/CronjobStateField.php | 4 +- .../src/Field/ExecutionRuleField.php | 12 +-- .../src/Field/IntervalField.php | 2 +- .../src/Field/JobTypeField.php | 2 +- .../src/Helper/CronjobsHelper.php | 4 +- .../src/Helper/ExecRuleHelper.php | 2 +- .../src/Model/CronjobModel.php | 22 ++--- .../src/Model/CronjobsModel.php | 2 +- .../src/Model/SelectModel.php | 2 +- .../src/Rule/ExecutionRulesRule.php | 2 +- .../src/Table/CronjobTable.php | 10 +- .../src/Traits/CronjobPluginTrait.php | 8 +- .../src/View/Cronjob/HtmlView.php | 6 +- .../src/View/Cronjobs/HtmlView.php | 10 +- .../src/View/Select/HtmlView.php | 10 +- .../tmpl/cronjob/edit.php | 22 ++--- .../tmpl/cronjobs/default.php | 28 +++--- .../com_scheduler/tmpl/cronjobs/default.xml | 8 ++ .../tmpl/cronjobs/default_batch_body.php | 2 +- .../tmpl/cronjobs/default_batch_footer.php | 2 +- .../tmpl/cronjobs/empty_state.php | 10 +- .../tmpl/select/default.php | 18 ++-- .../tmpl/select/modal.php | 2 +- administrator/language/en-GB/com_cronjobs.ini | 91 ------------------- .../language/en-GB/com_cronjobs.sys.ini | 13 --- .../language/en-GB/com_scheduler.ini | 91 +++++++++++++++++++ .../language/en-GB/com_scheduler.sys.ini | 13 +++ .../com_scheduler/css/admin-plg-job.css | 58 ++++++++++++ .../com_scheduler/css/admin-view-cronjob.css | 24 +++++ .../joomla.asset.json | 20 ++-- .../js/admin-plg-job-search.es6.js | 4 +- installation/sql/mysql/base.sql | 4 +- installation/sql/postgresql/base.sql | 4 +- plugins/job/requests/requests.php | 4 +- plugins/job/testjob/testjob.php | 6 +- plugins/job/testjob/testjob.xml | 2 +- plugins/job/toggleoffline/toggleoffline.php | 2 +- plugins/system/cronjobs/cronjobs.php | 6 +- .../en-GB/en-GB.plg_system.cronjobs.sys.ini | 2 +- .../en-GB/en-GB.plg_system_cronjobs.ini | 2 +- 59 files changed, 391 insertions(+), 309 deletions(-) delete mode 100644 administrator/components/com_cronjobs/tmpl/cronjobs/default.xml rename administrator/components/{com_cronjobs => com_scheduler}/access.xml (95%) rename administrator/components/{com_cronjobs => com_scheduler}/config.xml (91%) rename administrator/components/{com_cronjobs => com_scheduler}/forms/cronjob.xml (76%) rename administrator/components/{com_cronjobs => com_scheduler}/forms/filter_cronjobs.xml (75%) rename administrator/components/{com_cronjobs => com_scheduler}/layouts/Joomla/form/field/interval.php (98%) rename administrator/components/{com_cronjobs/cronjobs.xml => com_scheduler/scheduler.xml} (62%) rename administrator/components/{com_cronjobs => com_scheduler}/services/provider.php (95%) rename administrator/components/{com_cronjobs => com_scheduler}/src/Controller/CronjobController.php (89%) rename administrator/components/{com_cronjobs => com_scheduler}/src/Controller/CronjobsController.php (97%) rename administrator/components/{com_cronjobs => com_scheduler}/src/Controller/DisplayController.php (87%) rename administrator/components/{com_cronjobs => com_scheduler}/src/Cronjobs/CronOption.php (93%) rename administrator/components/{com_cronjobs => com_scheduler}/src/Cronjobs/CronOptions.php (92%) rename administrator/components/{com_cronjobs => com_scheduler}/src/Event/CronRunEvent.php (98%) rename administrator/components/{com_cronjobs => com_scheduler}/src/Extension/CronjobsComponent.php (97%) rename administrator/components/{com_cronjobs => com_scheduler}/src/Field/CronField.php (99%) rename administrator/components/{com_cronjobs => com_scheduler}/src/Field/CronjobStateField.php (88%) rename administrator/components/{com_cronjobs => com_scheduler}/src/Field/ExecutionRuleField.php (70%) rename administrator/components/{com_cronjobs => com_scheduler}/src/Field/IntervalField.php (98%) rename administrator/components/{com_cronjobs => com_scheduler}/src/Field/JobTypeField.php (98%) rename administrator/components/{com_cronjobs => com_scheduler}/src/Helper/CronjobsHelper.php (95%) rename administrator/components/{com_cronjobs => com_scheduler}/src/Helper/ExecRuleHelper.php (98%) rename administrator/components/{com_cronjobs => com_scheduler}/src/Model/CronjobModel.php (93%) rename administrator/components/{com_cronjobs => com_scheduler}/src/Model/CronjobsModel.php (99%) rename administrator/components/{com_cronjobs => com_scheduler}/src/Model/SelectModel.php (98%) rename administrator/components/{com_cronjobs => com_scheduler}/src/Rule/ExecutionRulesRule.php (99%) rename administrator/components/{com_cronjobs => com_scheduler}/src/Table/CronjobTable.php (93%) rename administrator/components/{com_cronjobs => com_scheduler}/src/Traits/CronjobPluginTrait.php (94%) rename administrator/components/{com_cronjobs => com_scheduler}/src/View/Cronjob/HtmlView.php (94%) rename administrator/components/{com_cronjobs => com_scheduler}/src/View/Cronjobs/HtmlView.php (94%) rename administrator/components/{com_cronjobs => com_scheduler}/src/View/Select/HtmlView.php (93%) rename administrator/components/{com_cronjobs => com_scheduler}/tmpl/cronjob/edit.php (83%) rename administrator/components/{com_cronjobs => com_scheduler}/tmpl/cronjobs/default.php (84%) create mode 100644 administrator/components/com_scheduler/tmpl/cronjobs/default.xml rename administrator/components/{com_cronjobs => com_scheduler}/tmpl/cronjobs/default_batch_body.php (95%) rename administrator/components/{com_cronjobs => com_scheduler}/tmpl/cronjobs/default_batch_footer.php (95%) rename administrator/components/{com_cronjobs => com_scheduler}/tmpl/cronjobs/empty_state.php (69%) rename administrator/components/{com_cronjobs => com_scheduler}/tmpl/select/default.php (83%) rename administrator/components/{com_cronjobs => com_scheduler}/tmpl/select/modal.php (96%) delete mode 100644 administrator/language/en-GB/com_cronjobs.ini delete mode 100644 administrator/language/en-GB/com_cronjobs.sys.ini create mode 100644 administrator/language/en-GB/com_scheduler.ini create mode 100644 administrator/language/en-GB/com_scheduler.sys.ini create mode 100644 build/media_source/com_scheduler/css/admin-plg-job.css create mode 100644 build/media_source/com_scheduler/css/admin-view-cronjob.css rename build/media_source/{com_cronjobs => com_scheduler}/joomla.asset.json (54%) rename build/media_source/{com_cronjobs => com_scheduler}/js/admin-plg-job-search.es6.js (96%) diff --git a/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-08-04.sql b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-08-04.sql index d537d9ab48ff1..652328f02a71b 100644 --- a/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-08-04.sql +++ b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-08-04.sql @@ -1,7 +1,7 @@ --- Add `com_cronjobs` to `#__extensions` +-- Add `com_scheduler` to `#__extensions` INSERT INTO `#__extensions` (`package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `locked`, `manifest_cache`, `params`, `custom_data`) -VALUES (0, 'com_cronjobs', 'component', 'com_cronjobs', '', 1, 1, 1, 0, 1, '', '', ''); +VALUES (0, 'com_scheduler', 'component', 'com_scheduler', '', 1, 1, 1, 0, 1, '', '', ''); -- Add `plg_job_testjob` to `#__extensions` INSERT INTO `#__extensions` (`package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-08-04.sql b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-08-04.sql index 6d5ec3ac4bbb0..74beff5acd21d 100644 --- a/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-08-04.sql +++ b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-08-04.sql @@ -1,7 +1,7 @@ --- Add "com_cronjobs" to "#__extensions" +-- Add "com_scheduler" to "#__extensions" INSERT INTO "#__extensions" ("package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "locked", "manifest_cache", "params", "custom_data", "ordering", "state") -VALUES (0, 'com_cronjobs', 'component', 'com_cronjobs', '', 1, 1, 1, 0, 1, '', '{}', '', 0, 0); +VALUES (0, 'com_scheduler', 'component', 'com_scheduler', '', 1, 1, 1, 0, 1, '', '{}', '', 0, 0); -- Add "plg_job_testjob" to "#__extensions" INSERT INTO "#__extensions" ("package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", diff --git a/administrator/components/com_cronjobs/tmpl/cronjobs/default.xml b/administrator/components/com_cronjobs/tmpl/cronjobs/default.xml deleted file mode 100644 index b7fb940e986ad..0000000000000 --- a/administrator/components/com_cronjobs/tmpl/cronjobs/default.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/administrator/components/com_menus/presets/system.xml b/administrator/components/com_menus/presets/system.xml index 27b2221d4feef..ce69eba24658c 100644 --- a/administrator/components/com_menus/presets/system.xml +++ b/administrator/components/com_menus/presets/system.xml @@ -167,9 +167,9 @@ - +
diff --git a/administrator/components/com_cronjobs/config.xml b/administrator/components/com_scheduler/config.xml similarity index 91% rename from administrator/components/com_cronjobs/config.xml rename to administrator/components/com_scheduler/config.xml index 9b22dbdd154c9..e8f939853005d 100644 --- a/administrator/components/com_cronjobs/config.xml +++ b/administrator/components/com_scheduler/config.xml @@ -12,7 +12,7 @@ validate="rules" filter="rules" section="component" - component="com_cronjobs" + component="com_scheduler" />
diff --git a/administrator/components/com_cronjobs/forms/cronjob.xml b/administrator/components/com_scheduler/forms/cronjob.xml similarity index 76% rename from administrator/components/com_cronjobs/forms/cronjob.xml rename to administrator/components/com_scheduler/forms/cronjob.xml index 4aeacd1a14935..bb2399705832b 100644 --- a/administrator/components/com_cronjobs/forms/cronjob.xml +++ b/administrator/components/com_scheduler/forms/cronjob.xml @@ -14,13 +14,13 @@
- - - + + +
@@ -38,7 +38,7 @@ @@ -48,7 +48,7 @@ @@ -95,7 +95,7 @@ @@ -137,25 +137,25 @@ -
+
@@ -21,20 +21,20 @@ - + - - + + @@ -57,8 +57,8 @@ - - + + * @license GNU General Public License version 2 or later; see LICENSE.txt @@ -69,7 +69,7 @@ $attr2 = ''; $attr2 .= !empty($class) ? ' class="' . $class . '"' : ''; -$attr2 .= ' placeholder="' . $this->escape($hint ?: Text::_('COM_CRONJOBS_TYPE_OR_SELECT_OPTIONS')) . '" '; +$attr2 .= ' placeholder="' . $this->escape($hint ?: Text::_('COM_SCHEDULER_TYPE_OR_SELECT_OPTIONS')) . '" '; $attr2 .= $dataAttribute; if ($required) diff --git a/administrator/components/com_cronjobs/cronjobs.xml b/administrator/components/com_scheduler/scheduler.xml similarity index 62% rename from administrator/components/com_cronjobs/cronjobs.xml rename to administrator/components/com_scheduler/scheduler.xml index 6529a36c5a91c..6d8e1dab3c768 100644 --- a/administrator/components/com_cronjobs/cronjobs.xml +++ b/administrator/components/com_scheduler/scheduler.xml @@ -1,35 +1,35 @@ - com_cronjobs + com_scheduler July 2021 Joomla! Projects GNU General Public License version 2 or later; see LICENSE.txt 4.1.0 - COM_CRONJOBS_XML_DESCRIPTION + COM_SCHEDULER_XML_DESCRIPTION Joomla\Component\Cronjobs - + js css access.xml config.xml - cronjobs.xml + scheduler.xml forms services src tmpl - language/en-GB/com_cronjobs.ini - language/en-GB/com_cronjobs.sys.ini + language/en-GB/com_scheduler.ini + language/en-GB/com_scheduler.sys.ini - com_cronjobs + com_scheduler - - com_cronjobs + + com_scheduler diff --git a/administrator/components/com_cronjobs/services/provider.php b/administrator/components/com_scheduler/services/provider.php similarity index 95% rename from administrator/components/com_cronjobs/services/provider.php rename to administrator/components/com_scheduler/services/provider.php index 6243dfb0901ec..bea53352356f4 100644 --- a/administrator/components/com_cronjobs/services/provider.php +++ b/administrator/components/com_scheduler/services/provider.php @@ -1,9 +1,9 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt diff --git a/administrator/components/com_cronjobs/src/Controller/CronjobController.php b/administrator/components/com_scheduler/src/Controller/CronjobController.php similarity index 89% rename from administrator/components/com_cronjobs/src/Controller/CronjobController.php rename to administrator/components/com_scheduler/src/Controller/CronjobController.php index 932e9be32f878..6a317febea72c 100644 --- a/administrator/components/com_cronjobs/src/Controller/CronjobController.php +++ b/administrator/components/com_scheduler/src/Controller/CronjobController.php @@ -7,7 +7,7 @@ * @todo : Check if the controller needs more overrides * * @package Joomla.Administrator - * @subpackage com_cronjobs + * @subpackage com_scheduler * * @copyright (C) 2021 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt @@ -62,12 +62,12 @@ public function add(): bool // ? : Is this the right redirect [review] $redirectUrl = 'index.php?option=' . $this->option . '&view=select&layout=edit'; $this->setRedirect(Route::_($redirectUrl, false)); - $app->enqueueMessage(Text::_('COM_CRONJOBS_ERROR_INVALID_JOB_TYPE'), 'warning'); + $app->enqueueMessage(Text::_('COM_SCHEDULER_ERROR_INVALID_JOB_TYPE'), 'warning'); $canAdd = false; } - $app->setUserState('com_cronjobs.add.cronjob.cronjob_type', $jobType); - $app->setUserState('com_cronjobs.add.cronjob.cronjob_option', $jobOption); + $app->setUserState('com_scheduler.add.cronjob.cronjob_type', $jobType); + $app->setUserState('com_scheduler.add.cronjob.cronjob_option', $jobOption); // @todo : Parameter array handling below? @@ -87,8 +87,8 @@ public function cancel($key = null): bool { $result = parent::cancel($key); - $this->app->setUserState('com_cronjobs.add.cronjob.cronjob_type', null); - $this->app->setUserState('com_cronjobs.add.cronjob.cronjob_option', null); + $this->app->setUserState('com_scheduler.add.cronjob.cronjob_type', null); + $this->app->setUserState('com_scheduler.add.cronjob.cronjob_option', null); // ? Do we need to redirect based on URL's 'return' param? {@see ModuleController} @@ -157,7 +157,7 @@ protected function allowEdit($data = array(), $key = 'id'): bool } // @todo : Check if this works as expected - return $this->app->getIdentity()->authorise('core.edit', 'com_cronjobs.cronjob.' . $recordId); + return $this->app->getIdentity()->authorise('core.edit', 'com_scheduler.cronjob.' . $recordId); } } diff --git a/administrator/components/com_cronjobs/src/Controller/CronjobsController.php b/administrator/components/com_scheduler/src/Controller/CronjobsController.php similarity index 97% rename from administrator/components/com_cronjobs/src/Controller/CronjobsController.php rename to administrator/components/com_scheduler/src/Controller/CronjobsController.php index 7a949dd51beee..c814cfc1a1766 100644 --- a/administrator/components/com_cronjobs/src/Controller/CronjobsController.php +++ b/administrator/components/com_scheduler/src/Controller/CronjobsController.php @@ -3,7 +3,7 @@ * Declares the MVC controller for CronJobsModel. * * @package Joomla.Administrator - * @subpackage com_cronjobs + * @subpackage com_scheduler * * @copyright (C) 2021 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt diff --git a/administrator/components/com_cronjobs/src/Controller/DisplayController.php b/administrator/components/com_scheduler/src/Controller/DisplayController.php similarity index 87% rename from administrator/components/com_cronjobs/src/Controller/DisplayController.php rename to administrator/components/com_scheduler/src/Controller/DisplayController.php index d2f95084c4559..3dbdf833e6a0c 100644 --- a/administrator/components/com_cronjobs/src/Controller/DisplayController.php +++ b/administrator/components/com_scheduler/src/Controller/DisplayController.php @@ -1,9 +1,9 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt @@ -23,7 +23,7 @@ /** - * Default controller for com_cronjobs. + * Default controller for com_scheduler. * * @since __DEPLOY_VERSION__ */ @@ -53,7 +53,7 @@ public function display($cachable = false, $urlparams = array()) { if (!$this->validateEntry()) { - $cronjobsViewUrl = Route::_('index.php?option=com_cronjobs&view=cronjobs'); + $cronjobsViewUrl = Route::_('index.php?option=com_scheduler&view=cronjobs'); $this->setRedirect($cronjobsViewUrl); return false; @@ -75,7 +75,7 @@ public function display($cachable = false, $urlparams = array()) */ private function validateEntry(string $layout = 'edit'): bool { - $context = 'com_cronjobs'; + $context = 'com_scheduler'; $id = $this->input->getInt('id'); $isValid = true; @@ -90,7 +90,7 @@ private function validateEntry(string $layout = 'edit'): bool // For new item, entry is invalid if job type was not selected through SelectView if ($isNew && !$this->app->getUserState("${context}.add.cronjob.cronjob_type")) { - $this->setMessage((Text::_('COM_CRONJOBS_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW')), 'error'); + $this->setMessage((Text::_('COM_SCHEDULER_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW')), 'error'); $isValid = false; } // For existing item, entry is invalid if CronjobController has not granted access diff --git a/administrator/components/com_cronjobs/src/Cronjobs/CronOption.php b/administrator/components/com_scheduler/src/Cronjobs/CronOption.php similarity index 93% rename from administrator/components/com_cronjobs/src/Cronjobs/CronOption.php rename to administrator/components/com_scheduler/src/Cronjobs/CronOption.php index a5aec44347578..f335c5b6f81f3 100644 --- a/administrator/components/com_cronjobs/src/Cronjobs/CronOption.php +++ b/administrator/components/com_scheduler/src/Cronjobs/CronOption.php @@ -1,9 +1,9 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt diff --git a/administrator/components/com_cronjobs/src/Cronjobs/CronOptions.php b/administrator/components/com_scheduler/src/Cronjobs/CronOptions.php similarity index 92% rename from administrator/components/com_cronjobs/src/Cronjobs/CronOptions.php rename to administrator/components/com_scheduler/src/Cronjobs/CronOptions.php index 52f5f6ace841f..1e8105ecd7781 100644 --- a/administrator/components/com_cronjobs/src/Cronjobs/CronOptions.php +++ b/administrator/components/com_scheduler/src/Cronjobs/CronOptions.php @@ -1,9 +1,9 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt diff --git a/administrator/components/com_cronjobs/src/Event/CronRunEvent.php b/administrator/components/com_scheduler/src/Event/CronRunEvent.php similarity index 98% rename from administrator/components/com_cronjobs/src/Event/CronRunEvent.php rename to administrator/components/com_scheduler/src/Event/CronRunEvent.php index 878e7086a26c9..d8fbfaa36bc48 100644 --- a/administrator/components/com_cronjobs/src/Event/CronRunEvent.php +++ b/administrator/components/com_scheduler/src/Event/CronRunEvent.php @@ -3,7 +3,7 @@ * Declares the CronjobsModel MVC Model. * * @package Joomla.Administrator - * @subpackage com_cronjobs + * @subpackage com_scheduler * * @copyright (C) 2021 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt diff --git a/administrator/components/com_cronjobs/src/Extension/CronjobsComponent.php b/administrator/components/com_scheduler/src/Extension/CronjobsComponent.php similarity index 97% rename from administrator/components/com_cronjobs/src/Extension/CronjobsComponent.php rename to administrator/components/com_scheduler/src/Extension/CronjobsComponent.php index 45e749cf905fb..8de554b144abd 100644 --- a/administrator/components/com_cronjobs/src/Extension/CronjobsComponent.php +++ b/administrator/components/com_scheduler/src/Extension/CronjobsComponent.php @@ -3,7 +3,7 @@ * Implements the Cronjobs component class * * @package Joomla.Administrator - * @subpackage com_cronjobs + * @subpackage com_scheduler * * @copyright (C) 2021 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt diff --git a/administrator/components/com_cronjobs/src/Field/CronField.php b/administrator/components/com_scheduler/src/Field/CronField.php similarity index 99% rename from administrator/components/com_cronjobs/src/Field/CronField.php rename to administrator/components/com_scheduler/src/Field/CronField.php index 4ecddb9530417..7222f49d259f4 100644 --- a/administrator/components/com_cronjobs/src/Field/CronField.php +++ b/administrator/components/com_scheduler/src/Field/CronField.php @@ -1,7 +1,7 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt diff --git a/administrator/components/com_cronjobs/src/Field/CronjobStateField.php b/administrator/components/com_scheduler/src/Field/CronjobStateField.php similarity index 88% rename from administrator/components/com_cronjobs/src/Field/CronjobStateField.php rename to administrator/components/com_scheduler/src/Field/CronjobStateField.php index 3876b02635df1..f7a4ddef9a37b 100644 --- a/administrator/components/com_cronjobs/src/Field/CronjobStateField.php +++ b/administrator/components/com_scheduler/src/Field/CronjobStateField.php @@ -3,7 +3,7 @@ * Declares a list field with all possible states for a (cron)job entry. * * @package Joomla.Administrator - * @subpackage com_cronjobs + * @subpackage com_scheduler * * @copyright (C) 2021 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt @@ -17,7 +17,7 @@ use Joomla\CMS\Form\Field\PredefinedlistField; /** - * A predefined list field with all possible states for a com_cronjobs entry. + * A predefined list field with all possible states for a com_scheduler entry. * * @since __DEPLOY_VERSION__ */ diff --git a/administrator/components/com_cronjobs/src/Field/ExecutionRuleField.php b/administrator/components/com_scheduler/src/Field/ExecutionRuleField.php similarity index 70% rename from administrator/components/com_cronjobs/src/Field/ExecutionRuleField.php rename to administrator/components/com_scheduler/src/Field/ExecutionRuleField.php index 03dec01dc6d13..538de699527e0 100644 --- a/administrator/components/com_cronjobs/src/Field/ExecutionRuleField.php +++ b/administrator/components/com_scheduler/src/Field/ExecutionRuleField.php @@ -1,7 +1,7 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt @@ -36,10 +36,10 @@ class ExecutionRuleField extends PredefinedlistField * @since __DEPLOY_VERSION__ */ protected $predefinedOptions = [ - 'interval-minutes' => 'COM_CRONJOBS_OPTION_INTERVAL_MINUTES', - 'interval-hours' => 'COM_CRONJOBS_OPTION_INTERVAL_HOURS', - 'interval-days' => 'COM_CRONJOBS_OPTION_INTERVAL_DAYS', - 'interval-months' => 'COM_CRONJOBS_OPTION_INTERVAL_MONTHS', - 'custom' => 'COM_CRONJOBS_OPTION_INTERVAL_CUSTOM' + 'interval-minutes' => 'COM_SCHEDULER_OPTION_INTERVAL_MINUTES', + 'interval-hours' => 'COM_SCHEDULER_OPTION_INTERVAL_HOURS', + 'interval-days' => 'COM_SCHEDULER_OPTION_INTERVAL_DAYS', + 'interval-months' => 'COM_SCHEDULER_OPTION_INTERVAL_MONTHS', + 'custom' => 'COM_SCHEDULER_OPTION_INTERVAL_CUSTOM' ]; } diff --git a/administrator/components/com_cronjobs/src/Field/IntervalField.php b/administrator/components/com_scheduler/src/Field/IntervalField.php similarity index 98% rename from administrator/components/com_cronjobs/src/Field/IntervalField.php rename to administrator/components/com_scheduler/src/Field/IntervalField.php index 258ecb4d72e2c..34e9e056146be 100644 --- a/administrator/components/com_cronjobs/src/Field/IntervalField.php +++ b/administrator/components/com_scheduler/src/Field/IntervalField.php @@ -1,7 +1,7 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt diff --git a/administrator/components/com_cronjobs/src/Field/JobTypeField.php b/administrator/components/com_scheduler/src/Field/JobTypeField.php similarity index 98% rename from administrator/components/com_cronjobs/src/Field/JobTypeField.php rename to administrator/components/com_scheduler/src/Field/JobTypeField.php index ff74796718a4f..c1880cb8dcd16 100644 --- a/administrator/components/com_cronjobs/src/Field/JobTypeField.php +++ b/administrator/components/com_scheduler/src/Field/JobTypeField.php @@ -3,7 +3,7 @@ * Declares the JobTypeField for listing all available job types. * * @package Joomla.Administrator - * @subpackage com_cronjobs + * @subpackage com_scheduler * * @copyright (C) 2021 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt diff --git a/administrator/components/com_cronjobs/src/Helper/CronjobsHelper.php b/administrator/components/com_scheduler/src/Helper/CronjobsHelper.php similarity index 95% rename from administrator/components/com_cronjobs/src/Helper/CronjobsHelper.php rename to administrator/components/com_scheduler/src/Helper/CronjobsHelper.php index ea140d68169c9..235d2955dbfb0 100644 --- a/administrator/components/com_cronjobs/src/Helper/CronjobsHelper.php +++ b/administrator/components/com_scheduler/src/Helper/CronjobsHelper.php @@ -3,7 +3,7 @@ * Implements the CronjobsHelper class * * @package Joomla.Administrator - * @subpackage com_cronjobs + * @subpackage com_scheduler * * @copyright (C) 2021 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt @@ -25,7 +25,7 @@ /** * The CronjobsHelper class. - * Provides static methods used across com_cronjobs + * Provides static methods used across com_scheduler * * @since __DEPLOY_VERSION__ */ diff --git a/administrator/components/com_cronjobs/src/Helper/ExecRuleHelper.php b/administrator/components/com_scheduler/src/Helper/ExecRuleHelper.php similarity index 98% rename from administrator/components/com_cronjobs/src/Helper/ExecRuleHelper.php rename to administrator/components/com_scheduler/src/Helper/ExecRuleHelper.php index 35e21138cfe71..c142eeac2be9f 100644 --- a/administrator/components/com_cronjobs/src/Helper/ExecRuleHelper.php +++ b/administrator/components/com_scheduler/src/Helper/ExecRuleHelper.php @@ -3,7 +3,7 @@ * Declares the CronjobsModel MVC Model. * * @package Joomla.Administrator - * @subpackage com_cronjobs + * @subpackage com_scheduler * * @copyright (C) 2021 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt diff --git a/administrator/components/com_cronjobs/src/Model/CronjobModel.php b/administrator/components/com_scheduler/src/Model/CronjobModel.php similarity index 93% rename from administrator/components/com_cronjobs/src/Model/CronjobModel.php rename to administrator/components/com_scheduler/src/Model/CronjobModel.php index 51fd857792a82..58ba7008cfa22 100644 --- a/administrator/components/com_cronjobs/src/Model/CronjobModel.php +++ b/administrator/components/com_scheduler/src/Model/CronjobModel.php @@ -3,7 +3,7 @@ * Declares the CronjobModel MVC Model. * * @package Joomla.Administrator - * @subpackage com_cronjobs + * @subpackage com_scheduler * * @copyright (C) 2021 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt @@ -60,7 +60,7 @@ class CronjobModel extends AdminModel * @var string * @since __DEPLOY_VERSION__ */ - protected $text_prefix = 'COM_CRONJOBS'; + protected $text_prefix = 'COM_SCHEDULER'; /** * Type alias for content type @@ -68,7 +68,7 @@ class CronjobModel extends AdminModel * @var string * @since __DEPLOY_VERSION__ */ - public $typeAlias = 'com_cronjobs.cronjob'; + public $typeAlias = 'com_scheduler.cronjob'; /** * The Application object, for convenience @@ -118,14 +118,14 @@ public function __construct($config = array(), MVCFactoryInterface $factory = nu */ public function getForm($data = array(), $loadData = true) { - Form::addFieldPath(JPATH_ADMINISTRATOR . 'components/com_cronjobs/src/Field'); + Form::addFieldPath(JPATH_ADMINISTRATOR . 'components/com_scheduler/src/Field'); /* * loadForm() (defined by FormBehaviourTrait) also loads the form data by calling * loadFormData() : $data [implemented here] and binds it to the form by calling * $form->bind($data). */ - $form = $this->loadForm('com_cronjobs.cronjob', 'cronjob', ['control' => 'jform', 'load_data' => $loadData]); + $form = $this->loadForm('com_scheduler.cronjob', 'cronjob', ['control' => 'jform', 'load_data' => $loadData]); if (empty($form)) { @@ -141,7 +141,7 @@ public function getForm($data = array(), $loadData = true) } // @todo : Check if this is working as expected for new items (id == 0) - if (!$user->authorise('core.edit.state', 'com_cronjobs.cronjob.' . $this->getState('job.id'))) + if (!$user->authorise('core.edit.state', 'com_scheduler.cronjob.' . $this->getState('job.id'))) { // Disable fields $form->setFieldAttribute('state', 'disabled', 'true'); @@ -188,14 +188,14 @@ protected function populateState(): void $app = $this->app; $jobId = $app->getInput()->getInt('id'); - $jobType = $app->getUserState('com_cronjobs.add.cronjob.cronjob_type'); - $jobOption = $app->getUserState('com_cronjobs.add.cronjob.cronjob_option'); + $jobType = $app->getUserState('com_scheduler.add.cronjob.cronjob_type'); + $jobOption = $app->getUserState('com_scheduler.add.cronjob.cronjob_option'); $this->setState('cronjob.id', $jobId); $this->setState('cronjob.type', $jobType); $this->setState('cronjob.option', $jobOption); - // Load component params, though com_cronjobs does not (yet) have any params + // Load component params, though com_scheduler does not (yet) have any params $cParams = ComponentHelper::getParams($this->option); $this->setState('params', $cParams); } @@ -229,7 +229,7 @@ public function getTable($name = 'Cronjob', $prefix = 'Table', $options = array( */ protected function loadFormData() { - $data = $this->app->getUserState('com_cronjobs.edit.cronjob.data', array()); + $data = $this->app->getUserState('com_scheduler.edit.cronjob.data', array()); // If the data from UserState is empty, we fetch it with getItem() if (empty($data)) @@ -248,7 +248,7 @@ protected function loadFormData() } // Let plugins manipulate the data - $this->preprocessData('com_cronjobs.cronjob', $data, 'job'); + $this->preprocessData('com_scheduler.cronjob', $data, 'job'); return $data; } diff --git a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php b/administrator/components/com_scheduler/src/Model/CronjobsModel.php similarity index 99% rename from administrator/components/com_cronjobs/src/Model/CronjobsModel.php rename to administrator/components/com_scheduler/src/Model/CronjobsModel.php index c35dce592392f..11232bad8fc62 100644 --- a/administrator/components/com_cronjobs/src/Model/CronjobsModel.php +++ b/administrator/components/com_scheduler/src/Model/CronjobsModel.php @@ -3,7 +3,7 @@ * Declares the CronjobsModel MVC Model. * * @package Joomla.Administrator - * @subpackage com_cronjobs + * @subpackage com_scheduler * * @copyright (C) 2021 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt diff --git a/administrator/components/com_cronjobs/src/Model/SelectModel.php b/administrator/components/com_scheduler/src/Model/SelectModel.php similarity index 98% rename from administrator/components/com_cronjobs/src/Model/SelectModel.php rename to administrator/components/com_scheduler/src/Model/SelectModel.php index 3c790d10af3ea..06bd6571d1573 100644 --- a/administrator/components/com_cronjobs/src/Model/SelectModel.php +++ b/administrator/components/com_scheduler/src/Model/SelectModel.php @@ -3,7 +3,7 @@ * Declares the SelectModel MVC Model. * * @package Joomla.Administrator - * @subpackage com_cronjobs + * @subpackage com_scheduler * * @copyright (C) 2021 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt diff --git a/administrator/components/com_cronjobs/src/Rule/ExecutionRulesRule.php b/administrator/components/com_scheduler/src/Rule/ExecutionRulesRule.php similarity index 99% rename from administrator/components/com_cronjobs/src/Rule/ExecutionRulesRule.php rename to administrator/components/com_scheduler/src/Rule/ExecutionRulesRule.php index b57d714686c34..178f31c34b1e4 100644 --- a/administrator/components/com_cronjobs/src/Rule/ExecutionRulesRule.php +++ b/administrator/components/com_scheduler/src/Rule/ExecutionRulesRule.php @@ -3,7 +3,7 @@ * Declares the validation class for execution-rules. * * @package Joomla.Administrator - * @subpackage com_cronjobs + * @subpackage com_scheduler * * @copyright (C) 2021 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt diff --git a/administrator/components/com_cronjobs/src/Table/CronjobTable.php b/administrator/components/com_scheduler/src/Table/CronjobTable.php similarity index 93% rename from administrator/components/com_cronjobs/src/Table/CronjobTable.php rename to administrator/components/com_scheduler/src/Table/CronjobTable.php index 781b2227201e2..d927cd3158989 100644 --- a/administrator/components/com_cronjobs/src/Table/CronjobTable.php +++ b/administrator/components/com_scheduler/src/Table/CronjobTable.php @@ -1,9 +1,9 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt @@ -21,7 +21,7 @@ use function defined; /** - * The main DB Table class for com_cronjobs + * The main DB Table class for com_scheduler * * @since __DEPLOY_VERSION__ */ @@ -69,7 +69,7 @@ class CronjobTable extends Table */ public function __construct(DatabaseDriver $db) { - $this->typeAlias = 'com_cronjobs.cronjob'; + $this->typeAlias = 'com_scheduler.cronjob'; $this->created = Factory::getDate()->toSql(); $this->setColumnAlias('published', 'state'); @@ -155,7 +155,7 @@ protected function _getAssetName(): string { $k = $this->_tbl_key; - return 'com_cronjobs.cronjob.' . (int) $this->$k; + return 'com_scheduler.cronjob.' . (int) $this->$k; } } diff --git a/administrator/components/com_cronjobs/src/Traits/CronjobPluginTrait.php b/administrator/components/com_scheduler/src/Traits/CronjobPluginTrait.php similarity index 94% rename from administrator/components/com_cronjobs/src/Traits/CronjobPluginTrait.php rename to administrator/components/com_scheduler/src/Traits/CronjobPluginTrait.php index ef7ceb1ac1366..cbad03a6f2784 100644 --- a/administrator/components/com_cronjobs/src/Traits/CronjobPluginTrait.php +++ b/administrator/components/com_scheduler/src/Traits/CronjobPluginTrait.php @@ -3,7 +3,7 @@ * Declares the CronjobsPluginTrait. * * @package Joomla.Administrator - * @subpackage com_cronjobs + * @subpackage com_scheduler * * @copyright (C) 2021 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt @@ -28,7 +28,7 @@ use function is_file; /** - * Utility trait for plugins that support com_cronjobs jobs + * Utility trait for plugins that support com_scheduler jobs * * @since __DEPLOY_VERSION__ */ @@ -215,10 +215,10 @@ protected function addJobLog(string $message, string $priority = 'info'): void if (!$langLoaded) { $app = $this->app ?? Factory::getApplication(); - $app->getLanguage()->load('com_cronjobs', JPATH_ADMINISTRATOR); + $app->getLanguage()->load('com_scheduler', JPATH_ADMINISTRATOR); $langLoaded = true; } - Log::add(Text::_('COM_CRONJOBS_JOB_LOG_PREFIX') . $message, $priorityMap[$priority] ?? Log::INFO, 'cronjobs'); + Log::add(Text::_('COM_SCHEDULER_JOB_LOG_PREFIX') . $message, $priorityMap[$priority] ?? Log::INFO, 'cronjobs'); } } diff --git a/administrator/components/com_cronjobs/src/View/Cronjob/HtmlView.php b/administrator/components/com_scheduler/src/View/Cronjob/HtmlView.php similarity index 94% rename from administrator/components/com_cronjobs/src/View/Cronjob/HtmlView.php rename to administrator/components/com_scheduler/src/View/Cronjob/HtmlView.php index f74fce8327204..8ecd607483366 100644 --- a/administrator/components/com_cronjobs/src/View/Cronjob/HtmlView.php +++ b/administrator/components/com_scheduler/src/View/Cronjob/HtmlView.php @@ -3,7 +3,7 @@ * Declares the MVC View for the Cronjob form. * * @package Joomla.Administrator - * @subpackage com_cronjobs + * @subpackage com_scheduler * * @copyright (C) 2021 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt @@ -109,7 +109,7 @@ public function display($tpl = null): void $this->item = $this->get('Item'); $this->state = $this->get('State'); - $this->canDo = ContentHelper::getActions('com_cronjobs', 'cronjob', $this->item->id); + $this->canDo = ContentHelper::getActions('com_scheduler', 'cronjob', $this->item->id); $this->addToolbar(); parent::display($tpl); @@ -133,7 +133,7 @@ protected function addToolbar(): void $isNew = ($this->item->id == 0); $canDo = $this->canDo; - ToolbarHelper::title($isNew ? Text::_('COM_CRONJOBS_MANAGER_CRONJOB_NEW') : Text::_('COM_CRONJOBS_MANAGER_CRONJOB_EDIT'), 'clock'); + ToolbarHelper::title($isNew ? Text::_('COM_SCHEDULER_MANAGER_CRONJOB_NEW') : Text::_('COM_SCHEDULER_MANAGER_CRONJOB_EDIT'), 'clock'); // Goes into ToolbarHelper::saveGroup() $toolbarButtons = []; diff --git a/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php b/administrator/components/com_scheduler/src/View/Cronjobs/HtmlView.php similarity index 94% rename from administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php rename to administrator/components/com_scheduler/src/View/Cronjobs/HtmlView.php index de3e824ae49d9..89ac654c75c3f 100644 --- a/administrator/components/com_cronjobs/src/View/Cronjobs/HtmlView.php +++ b/administrator/components/com_scheduler/src/View/Cronjobs/HtmlView.php @@ -3,7 +3,7 @@ * Declares the MVC View for the Cronjobs list view. * * @package Joomla.Administrator - * @subpackage com_cronjobs + * @subpackage com_scheduler * * @copyright (C) 2021 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt @@ -142,7 +142,7 @@ public function display($tpl = null): void */ protected function addToolbar(): void { - $canDo = ContentHelper::getActions('com_cronjobs'); + $canDo = ContentHelper::getActions('com_scheduler'); $user = Factory::getApplication()->getIdentity(); /* @@ -151,12 +151,12 @@ protected function addToolbar(): void */ $toolbar = Toolbar::getInstance('toolbar'); - ToolbarHelper::title(Text::_('COM_CRONJOBS_MANAGER_CRONJOBS'), 'clock'); + ToolbarHelper::title(Text::_('COM_SCHEDULER_MANAGER_CRONJOBS'), 'clock'); if ($canDo->get('core.create')) { $toolbar->linkButton('new', 'JTOOLBAR_NEW') - ->url('index.php?option=com_cronjobs&view=select&layout=default') + ->url('index.php?option=com_scheduler&view=select&layout=default') ->buttonClass('btn btn-success') ->icon('icon-new'); } @@ -199,7 +199,7 @@ protected function addToolbar(): void // Link to component preferences if user has admin privileges if ($canDo->get('core.admin') || $canDo->get('core.options')) { - $toolbar->preferences('com_cronjobs'); + $toolbar->preferences('com_scheduler'); } $toolbar->help('JHELP_COMPONENTS_CRONJOBS_MANAGER'); diff --git a/administrator/components/com_cronjobs/src/View/Select/HtmlView.php b/administrator/components/com_scheduler/src/View/Select/HtmlView.php similarity index 93% rename from administrator/components/com_cronjobs/src/View/Select/HtmlView.php rename to administrator/components/com_scheduler/src/View/Select/HtmlView.php index 2e83acfae8e2c..ca975ab043d19 100644 --- a/administrator/components/com_cronjobs/src/View/Select/HtmlView.php +++ b/administrator/components/com_scheduler/src/View/Select/HtmlView.php @@ -3,7 +3,7 @@ * Declares the MVC View for Cronjob type selection. * * @package Joomla.Administrator - * @subpackage com_cronjobs + * @subpackage com_scheduler * * @copyright (C) 2021 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt @@ -119,7 +119,7 @@ public function display($tpl = null): void */ protected function addToolbar(): void { - $canDo = ContentHelper::getActions('com_cronjobs'); + $canDo = ContentHelper::getActions('com_scheduler'); /* * Get the global Toolbar instance @@ -129,10 +129,10 @@ protected function addToolbar(): void $toolbar = Toolbar::getInstance(); // Add page title - ToolbarHelper::title(Text::_('COM_CRONJOBS_MANAGER_CRONJOBS'), 'clock'); + ToolbarHelper::title(Text::_('COM_SCHEDULER_MANAGER_CRONJOBS'), 'clock'); $toolbar->linkButton('cancel') - ->url('index.php?option=com_cronjobs') + ->url('index.php?option=com_scheduler') ->buttonClass('btn btn-danger') ->icon('icon-times') ->text(Text::_('JCANCEL')); @@ -140,7 +140,7 @@ protected function addToolbar(): void // Add preferences button if user has privileges if ($canDo->get('core.admin') || $canDo->get('core.options')) { - $toolbar->preferences('com_cronjobs'); + $toolbar->preferences('com_scheduler'); } // Add help button diff --git a/administrator/components/com_cronjobs/tmpl/cronjob/edit.php b/administrator/components/com_scheduler/tmpl/cronjob/edit.php similarity index 83% rename from administrator/components/com_cronjobs/tmpl/cronjob/edit.php rename to administrator/components/com_scheduler/tmpl/cronjob/edit.php index b39dc15ca8dca..5ee8a4dbb943e 100644 --- a/administrator/components/com_cronjobs/tmpl/cronjob/edit.php +++ b/administrator/components/com_scheduler/tmpl/cronjob/edit.php @@ -1,7 +1,7 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt @@ -26,7 +26,7 @@ $wa->useScript('keepalive'); $wa->useScript('form.validate'); -$wa->useStyle('com_cronjobs.admin-view-cronjob-css'); +$wa->useStyle('com_scheduler.admin-view-cronjob-css'); /** @var AdministratorApplication $app */ $app = $this->app; @@ -43,9 +43,9 @@ ?> - @@ -59,7 +59,7 @@ class="form-validate"> item->id) ? Text::_('COM_CRONJOBS_NEW_CRONJOB') : Text::_('COM_CRONJOBS_EDIT_CRONJOB') + empty($this->item->id) ? Text::_('COM_SCHEDULER_NEW_CRONJOB') : Text::_('COM_SCHEDULER_EDIT_CRONJOB') ); ?>
@@ -82,11 +82,11 @@ class="form-validate">
enqueueMessage(Text::_('COM_CRONJOBS_WARNING_EXISTING_JOB_TYPE_NOT_FOUND'), 'warning'); + $app->enqueueMessage(Text::_('COM_SCHEDULER_WARNING_EXISTING_JOB_TYPE_NOT_FOUND'), 'warning'); ?>
- + form->renderFieldset('basic'); ?>
@@ -94,12 +94,12 @@ class="form-validate">
- + form->renderFieldset('custom-cron-rules'); ?>
- + - +
- + form->renderFieldset('exec_hist'); ?>
diff --git a/administrator/components/com_cronjobs/tmpl/cronjobs/default.php b/administrator/components/com_scheduler/tmpl/cronjobs/default.php similarity index 84% rename from administrator/components/com_cronjobs/tmpl/cronjobs/default.php rename to administrator/components/com_scheduler/tmpl/cronjobs/default.php index 3c54f7c35ad48..1849f3434e72c 100644 --- a/administrator/components/com_cronjobs/tmpl/cronjobs/default.php +++ b/administrator/components/com_scheduler/tmpl/cronjobs/default.php @@ -1,7 +1,7 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt @@ -40,12 +40,12 @@ if ($saveOrder && !empty($this->items)) { - $saveOrderingUrl = 'index.php?option=com_cronjobs&task=cronjobs.saveOrderAjax&tmpl=component&' . Session::getFormToken() . '=1'; + $saveOrderingUrl = 'index.php?option=com_scheduler&task=cronjobs.saveOrderAjax&tmpl=component&' . Session::getFormToken() . '=1'; HTMLHelper::_('draggablelist.draggable'); } ?> -
@@ -101,7 +101,7 @@ class="visually-hidden"> @@ -115,9 +115,9 @@ class="visually-hidden"> class="js-draggable" data-url="" data-direction="" data-nested="true" > items as $i => $item): - $canCreate = $user->authorise('core.create', 'com_cronjobs'); - $canEdit = $user->authorise('core.edit', 'com_cronjobs'); - $canChange = $user->authorise('core.edit.state', 'com_cronjobs'); + $canCreate = $user->authorise('core.create', 'com_scheduler'); + $canEdit = $user->authorise('core.edit', 'com_scheduler'); + $canChange = $user->authorise('core.edit.state', 'com_scheduler'); ?> @@ -161,7 +161,7 @@ class="js-draggable" data-url="" data-direction=" diff --git a/administrator/components/com_scheduler/tmpl/select/default.php b/administrator/components/com_scheduler/tmpl/select/default.php index 8c0c365ea738e..6dcc7b3550c56 100644 --- a/administrator/components/com_scheduler/tmpl/select/default.php +++ b/administrator/components/com_scheduler/tmpl/select/default.php @@ -63,7 +63,7 @@ class="form-control" id="comCronjobsSelectSearch"
- +

@@ -81,7 +81,7 @@ class="visually-hidden"> + aria-label="">

diff --git a/administrator/language/en-GB/com_scheduler.ini b/administrator/language/en-GB/com_scheduler.ini index bb603011ca26d..db4fd8cbd9f4b 100644 --- a/administrator/language/en-GB/com_scheduler.ini +++ b/administrator/language/en-GB/com_scheduler.ini @@ -4,13 +4,13 @@ COM_SCHEDULER="Scheduled Tasks" COM_SCHEDULER_DASHBOARD_TITLE="Scheduled Tasks Manager" -COM_SCHEDULER_EDIT_CRONJOB="Edit Task" +COM_SCHEDULER_EDIT_TASK="Edit Task" COM_SCHEDULER_EMPTYSTATE_BUTTON_ADD="Add a Task!" COM_SCHEDULER_EMPTYSTATE_CONTENT="No Tasks!" COM_SCHEDULER_EMPTYSTATE_TITLE="No Tasks have been created yet!" COM_SCHEDULER_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW="You need to select a Task type first!" -COM_SCHEDULER_ERROR_INVALID_JOB_TYPE="Invalid Task Type!" -COM_SCHEDULER_FIELD_JOB_TYPE="Type ID" +COM_SCHEDULER_ERROR_INVALID_TASK_TYPE="Invalid Task Type!" +COM_SCHEDULER_FIELD_TASK_TYPE="Type ID" COM_SCHEDULER_FIELD_LABEL_EXEC_RULE="Execution Rule" COM_SCHEDULER_FIELD_LABEL_INTERVAL_DAYS="Interval in Days" COM_SCHEDULER_FIELD_LABEL_INTERVAL_HOURS="Interval in Hours" @@ -27,14 +27,14 @@ COM_SCHEDULER_FIELDSET_CRON_OPTIONS="Cron Match" COM_SCHEDULER_FIELDSET_EXEC_HIST="Execution History" COM_SCHEDULER_FIELDSET_PARAMS_FS="Task Parameters" COM_SCHEDULER_FILTER_SEARCH_DESC="Search in Task title and note. Prefix with 'ID:' to search for a task ID" -COM_SCHEDULER_FILTER_SEARCH_LABEL="Search Cronjobs" +COM_SCHEDULER_FILTER_SEARCH_LABEL="Search Tasks" COM_SCHEDULER_FORM_TITLE_EDIT="Edit Task" COM_SCHEDULER_FORM_TITLE_NEW="New Task" -COM_SCHEDULER_HEADING_JOB_TYPE="- Job Type -" -COM_SCHEDULER_JOB_LOG_PREFIX="Task> " -COM_SCHEDULER_JOB_TYPE="Task Type" -COM_SCHEDULER_JOB_TYPE_ASC="Task Type Ascending" -COM_SCHEDULER_JOB_TYPE_DESC="Task Type Descending" +COM_SCHEDULER_HEADING_TASK_TYPE="- Task Type -" +COM_SCHEDULER_TASK_LOG_PREFIX="Task> " +COM_SCHEDULER_TASK_TYPE="Task Type" +COM_SCHEDULER_TASK_TYPE_ASC="Task Type Ascending" +COM_SCHEDULER_TASK_TYPE_DESC="Task Type Descending" COM_SCHEDULER_LABEL_EXEC_DAY="Execution Day" COM_SCHEDULER_LABEL_EXEC_INTERVAL="Execution Interval" COM_SCHEDULER_LABEL_EXEC_TIME="Execution Time (UTC)" @@ -46,11 +46,11 @@ COM_SCHEDULER_LABEL_NEXT_EXEC="Next Execution" COM_SCHEDULER_LABEL_NOTES="Notes" COM_SCHEDULER_LABEL_TIMES_EXEC="Times Executed" COM_SCHEDULER_LABEL_TIMES_FAIL="Times Failed" -COM_SCHEDULER_MANAGER_CRONJOB="Task Manager" -COM_SCHEDULER_MANAGER_CRONJOB_EDIT="Edit Task" -COM_SCHEDULER_MANAGER_CRONJOB_NEW="New Task" -COM_SCHEDULER_MANAGER_CRONJOBS="Tasks Manager" -COM_SCHEDULER_MSG_MANAGE_NO_JOB_PLUGINS="There are no task types matching your query!" +COM_SCHEDULER_MANAGER_TASK="Task Manager" +COM_SCHEDULER_MANAGER_TASK_EDIT="Edit Task" +COM_SCHEDULER_MANAGER_TASK_NEW="New Task" +COM_SCHEDULER_MANAGER_TASKS="Tasks Manager" +COM_SCHEDULER_MSG_MANAGE_NO_TASK_PLUGINS="There are no task types matching your query!" COM_SCHEDULER_N_ITEMS_DELETED="%s tasks deleted." COM_SCHEDULER_N_ITEMS_DELETED_1="Task deleted." COM_SCHEDULER_N_ITEMS_PUBLISHED="%s tasks enabled." @@ -59,7 +59,7 @@ COM_SCHEDULER_N_ITEMS_TRASHED="%s tasks trashed." COM_SCHEDULER_N_ITEMS_TRASHED_1="Task trashed." COM_SCHEDULER_N_ITEMS_UNPUBLISHED="%s tasks disabled." COM_SCHEDULER_N_ITEMS_UNPUBLISHED_1="Task disabled." -COM_SCHEDULER_NEW_CRONJOB="New Task" +COM_SCHEDULER_NEW_TASK="New Task" COM_SCHEDULER_NO_NOTE="" COM_SCHEDULER_OPTION_INTERVAL_CUSTOM="Custom Match (Advanced)" COM_SCHEDULER_OPTION_INTERVAL_DAYS="Interval, Days" @@ -73,7 +73,7 @@ COM_SCHEDULER_SELECT_INTERVAL_DAYS="-- Select Interval in Days --" COM_SCHEDULER_SELECT_INTERVAL_HOURS="-- Select Interval in Hours --" COM_SCHEDULER_SELECT_INTERVAL_MINUTES="-- Select Interval in Minutes --" COM_SCHEDULER_SELECT_INTERVAL_MONTHS="-- Select Interval in Months --" -COM_SCHEDULER_SELECT_PLG_JOB="Select task, %s" +COM_SCHEDULER_SELECT_TASK_TYPE="Select task, %s" COM_SCHEDULER_SELECT_TRIGGER="Trigger" COM_SCHEDULER_SELECT_TYPE="- Task Type -" COM_SCHEDULER_TABLE_CAPTION="Tasks List" diff --git a/administrator/language/en-GB/com_scheduler.sys.ini b/administrator/language/en-GB/com_scheduler.sys.ini index 171a450771f31..75973e779aeb2 100644 --- a/administrator/language/en-GB/com_scheduler.sys.ini +++ b/administrator/language/en-GB/com_scheduler.sys.ini @@ -2,12 +2,12 @@ ; (C) 2021 Open Source Matters, Inc. ; GNU General Public License version 2 or later; see LICENSE.txt -COM_SCHEDULER="Cronjobs" +COM_SCHEDULER="Scheduled Tasks" COM_SCHEDULER_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW="You need to select a Task type first!" -COM_SCHEDULER_ERROR_INVALID_JOB_TYPE="Invalid Task Type!" -COM_SCHEDULER_MANAGER_CRONJOB="Task Manager" -COM_SCHEDULER_MANAGER_CRONJOB_EDIT="Edit Task" -COM_SCHEDULER_MANAGER_CRONJOB_NEW="New Task" -COM_SCHEDULER_MANAGER_CRONJOBS="Tasks Manager" -COM_SCHEDULER_MSG_MANAGE_NO_JOB_PLUGINS="There are no task types matching your query!" +COM_SCHEDULER_ERROR_INVALID_TASK_TYPE="Invalid Task Type!" +COM_SCHEDULER_MANAGER_TASK="Task Manager" +COM_SCHEDULER_MANAGER_TASK_EDIT="Edit Task" +COM_SCHEDULER_MANAGER_TASK_NEW="New Task" +COM_SCHEDULER_MANAGER_TASKS="Tasks Manager" +COM_SCHEDULER_MSG_MANAGE_NO_TASK_PLUGINS="There are no task types matching your query!" COM_SCHEDULER_XML_DESCRIPTION="Component for managing scheduled tasks and cronjobs (if supported by the server)" From b12fbe33f1612baa2619985c458fe31f5ad0e68f Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sat, 21 Aug 2021 01:37:36 +0530 Subject: [PATCH 308/615] Refactor com_cronjobs [4] Updates component namespace to `Joomla\Component\Scheduler` --- administrator/components/com_scheduler/forms/cronjob.xml | 7 ++++--- .../components/com_scheduler/forms/filter_cronjobs.xml | 2 +- .../components/com_scheduler/services/provider.php | 2 +- .../com_scheduler/src/Controller/CronjobController.php | 4 ++-- .../com_scheduler/src/Controller/CronjobsController.php | 2 +- .../com_scheduler/src/Controller/DisplayController.php | 2 +- .../components/com_scheduler/src/Cronjobs/CronOption.php | 2 +- .../components/com_scheduler/src/Cronjobs/CronOptions.php | 2 +- .../components/com_scheduler/src/Event/CronRunEvent.php | 2 +- .../com_scheduler/src/Extension/CronjobsComponent.php | 2 +- .../components/com_scheduler/src/Field/CronField.php | 2 +- .../com_scheduler/src/Field/CronjobStateField.php | 2 +- .../com_scheduler/src/Field/ExecutionRuleField.php | 2 +- .../components/com_scheduler/src/Field/IntervalField.php | 2 +- .../components/com_scheduler/src/Field/JobTypeField.php | 6 +++--- .../com_scheduler/src/Helper/CronjobsHelper.php | 4 ++-- .../com_scheduler/src/Helper/ExecRuleHelper.php | 2 +- .../components/com_scheduler/src/Model/CronjobModel.php | 6 +++--- .../components/com_scheduler/src/Model/CronjobsModel.php | 4 ++-- .../components/com_scheduler/src/Model/SelectModel.php | 6 +++--- .../com_scheduler/src/Rule/ExecutionRulesRule.php | 2 +- .../components/com_scheduler/src/Table/CronjobTable.php | 2 +- .../com_scheduler/src/Traits/CronjobPluginTrait.php | 4 ++-- .../com_scheduler/src/View/Cronjob/HtmlView.php | 2 +- .../com_scheduler/src/View/Cronjobs/HtmlView.php | 2 +- .../components/com_scheduler/src/View/Select/HtmlView.php | 4 ++-- .../components/com_scheduler/tmpl/cronjob/edit.php | 4 ++-- .../components/com_scheduler/tmpl/select/default.php | 2 +- .../components/com_scheduler/tmpl/select/modal.php | 2 +- plugins/job/requests/requests.php | 4 ++-- plugins/job/testjob/testjob.php | 4 ++-- plugins/job/toggleoffline/toggleoffline.php | 4 ++-- plugins/system/cronjobs/cronjobs.php | 8 ++++---- 33 files changed, 54 insertions(+), 53 deletions(-) diff --git a/administrator/components/com_scheduler/forms/cronjob.xml b/administrator/components/com_scheduler/forms/cronjob.xml index 284d855144a10..1dbce79d3059b 100644 --- a/administrator/components/com_scheduler/forms/cronjob.xml +++ b/administrator/components/com_scheduler/forms/cronjob.xml @@ -1,7 +1,8 @@ - + + - + 'Joomla\Component\Cronjobs\Administrator\Event\CronRunEvent', + 'eventClass' => 'Joomla\Component\Scheduler\Administrator\Event\CronRunEvent', 'subject' => $this, 'jobId' => $cronjob->type, 'langConstPrefix' => $cronjob->cronOption->langConstPrefix, From cc6bd0c2889c6e67ae031e983080c2c787345d2a Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sat, 21 Aug 2021 02:51:57 +0530 Subject: [PATCH 309/615] Refactor com_cronjobs [5] - Refactor component classes: - Refactors MVC classes. - Refactors Helper classes. - Refactors Table, Component class. - Refactors the Plugin trait. --- .../com_scheduler/services/provider.php | 8 ++++---- .../src/Controller/DisplayController.php | 2 +- ...onjobController.php => TaskController.php} | 10 +++++----- ...jobsController.php => TasksController.php} | 4 ++-- .../com_scheduler/src/Event/CronRunEvent.php | 2 +- ...bsComponent.php => SchedulerComponent.php} | 4 ++-- .../com_scheduler/src/Field/JobTypeField.php | 10 +++++----- .../src/Helper/ExecRuleHelper.php | 2 +- ...CronjobsHelper.php => SchedulerHelper.php} | 20 +++++++++---------- .../com_scheduler/src/Model/SelectModel.php | 8 ++++---- .../Model/{CronjobModel.php => TaskModel.php} | 14 ++++++------- .../{CronjobsModel.php => TasksModel.php} | 14 ++++++------- .../TaskOption.php} | 12 +++++------ .../TaskOptions.php} | 18 ++++++++--------- .../Table/{CronjobTable.php => TaskTable.php} | 2 +- ...jobPluginTrait.php => TaskPluginTrait.php} | 2 +- .../src/View/Select/HtmlView.php | 6 +++--- .../src/View/{Cronjob => Task}/HtmlView.php | 8 ++++---- .../src/View/{Cronjobs => Tasks}/HtmlView.php | 4 ++-- .../com_scheduler/tmpl/cronjob/edit.php | 4 ++-- plugins/job/requests/requests.php | 4 ++-- plugins/job/testjob/testjob.php | 4 ++-- plugins/job/toggleoffline/toggleoffline.php | 4 ++-- plugins/system/cronjobs/cronjobs.php | 20 +++++++++---------- 24 files changed, 93 insertions(+), 93 deletions(-) rename administrator/components/com_scheduler/src/Controller/{CronjobController.php => TaskController.php} (92%) rename administrator/components/com_scheduler/src/Controller/{CronjobsController.php => TasksController.php} (84%) rename administrator/components/com_scheduler/src/Extension/{CronjobsComponent.php => SchedulerComponent.php} (89%) rename administrator/components/com_scheduler/src/Helper/{CronjobsHelper.php => SchedulerHelper.php} (77%) rename administrator/components/com_scheduler/src/Model/{CronjobModel.php => TaskModel.php} (96%) rename administrator/components/com_scheduler/src/Model/{CronjobsModel.php => TasksModel.php} (96%) rename administrator/components/com_scheduler/src/{Cronjobs/CronOption.php => Scheduler/TaskOption.php} (84%) rename administrator/components/com_scheduler/src/{Cronjobs/CronOptions.php => Scheduler/TaskOptions.php} (76%) rename administrator/components/com_scheduler/src/Table/{CronjobTable.php => TaskTable.php} (99%) rename administrator/components/com_scheduler/src/Traits/{CronjobPluginTrait.php => TaskPluginTrait.php} (99%) rename administrator/components/com_scheduler/src/View/{Cronjob => Task}/HtmlView.php (95%) rename administrator/components/com_scheduler/src/View/{Cronjobs => Tasks}/HtmlView.php (98%) diff --git a/administrator/components/com_scheduler/services/provider.php b/administrator/components/com_scheduler/services/provider.php index 5cc65aac6aa83..6d75346d08488 100644 --- a/administrator/components/com_scheduler/services/provider.php +++ b/administrator/components/com_scheduler/services/provider.php @@ -17,7 +17,7 @@ use Joomla\CMS\Extension\Service\Provider\MVCFactory; use Joomla\CMS\HTML\Registry; use Joomla\CMS\MVC\Factory\MVCFactoryInterface; -use Joomla\Component\Scheduler\Administrator\Extension\CronjobsComponent; +use Joomla\Component\Scheduler\Administrator\Extension\SchedulerComponent; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; @@ -47,13 +47,13 @@ public function register(Container $container) * 'MVCFactoryInterface' and 'ComponentDispatcherFactoryInterface' to their * initializers and register them with the component's DI container. */ - $container->registerServiceProvider(new MVCFactory('\\Joomla\\Component\\Cronjobs')); - $container->registerServiceProvider(new ComponentDispatcherFactory('\\Joomla\\Component\\Cronjobs')); + $container->registerServiceProvider(new MVCFactory('\\Joomla\\Component\\Scheduler')); + $container->registerServiceProvider(new ComponentDispatcherFactory('\\Joomla\\Component\\Scheduler')); $container->set( ComponentInterface::class, function (Container $container) { - $component = new CronjobsComponent($container->get(ComponentDispatcherFactoryInterface::class)); + $component = new SchedulerComponent($container->get(ComponentDispatcherFactoryInterface::class)); $component->setRegistry($container->get(Registry::class)); $component->setMVCFactory($container->get(MVCFactoryInterface::class)); diff --git a/administrator/components/com_scheduler/src/Controller/DisplayController.php b/administrator/components/com_scheduler/src/Controller/DisplayController.php index ecda4d2578626..d2d57a7d62789 100644 --- a/administrator/components/com_scheduler/src/Controller/DisplayController.php +++ b/administrator/components/com_scheduler/src/Controller/DisplayController.php @@ -93,7 +93,7 @@ private function validateEntry(string $layout = 'edit'): bool $this->setMessage((Text::_('COM_SCHEDULER_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW')), 'error'); $isValid = false; } - // For existing item, entry is invalid if CronjobController has not granted access + // For existing item, entry is invalid if TaskController has not granted access elseif (!$canEdit && !count($this->app->getMessageQueue())) { $this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id), 'error'); diff --git a/administrator/components/com_scheduler/src/Controller/CronjobController.php b/administrator/components/com_scheduler/src/Controller/TaskController.php similarity index 92% rename from administrator/components/com_scheduler/src/Controller/CronjobController.php rename to administrator/components/com_scheduler/src/Controller/TaskController.php index 173f42231a679..ca712903fd7e1 100644 --- a/administrator/components/com_scheduler/src/Controller/CronjobController.php +++ b/administrator/components/com_scheduler/src/Controller/TaskController.php @@ -1,8 +1,8 @@ app; $input = $app->getInput(); - $validJobOptions = CronjobsHelper::getCronOptions(); + $validJobOptions = SchedulerHelper::getCronOptions(); $canAdd = parent::add(); diff --git a/administrator/components/com_scheduler/src/Controller/CronjobsController.php b/administrator/components/com_scheduler/src/Controller/TasksController.php similarity index 84% rename from administrator/components/com_scheduler/src/Controller/CronjobsController.php rename to administrator/components/com_scheduler/src/Controller/TasksController.php index a362c36b78cf7..18d4463e21fcb 100644 --- a/administrator/components/com_scheduler/src/Controller/CronjobsController.php +++ b/administrator/components/com_scheduler/src/Controller/TasksController.php @@ -23,7 +23,7 @@ * * @since __DEPLOY_VERSION__ */ -class CronjobsController extends AdminController +class TasksController extends AdminController { /** * Proxy for the parent method. @@ -36,7 +36,7 @@ class CronjobsController extends AdminController * * @since __DEPLOY_VERSION__ */ - public function getModel($name = 'Cronjob', $prefix = 'Administrator', $config = ['ignore_request' => true]): BaseDatabaseModel + public function getModel($name = 'Task', $prefix = 'Administrator', $config = ['ignore_request' => true]): BaseDatabaseModel { return parent::getModel($name, $prefix, $config); } diff --git a/administrator/components/com_scheduler/src/Event/CronRunEvent.php b/administrator/components/com_scheduler/src/Event/CronRunEvent.php index f4d51dd6cf526..4993be2009e8c 100644 --- a/administrator/components/com_scheduler/src/Event/CronRunEvent.php +++ b/administrator/components/com_scheduler/src/Event/CronRunEvent.php @@ -1,6 +1,6 @@ options, + SchedulerHelper::getCronOptions()->options, 'title', 1 ); - // Closure to add a CronOption as a option in $options: array + $addTypeAsOption = function (TaskOption $type) use (&$options) { $options[] = HTMLHelper::_('select.option', $type->type, $type->title); }; diff --git a/administrator/components/com_scheduler/src/Helper/ExecRuleHelper.php b/administrator/components/com_scheduler/src/Helper/ExecRuleHelper.php index b9f037d3abbaf..27e0dd71d1bf3 100644 --- a/administrator/components/com_scheduler/src/Helper/ExecRuleHelper.php +++ b/administrator/components/com_scheduler/src/Helper/ExecRuleHelper.php @@ -1,6 +1,6 @@ options; + return SchedulerHelper::getCronOptions()->options; } } diff --git a/administrator/components/com_scheduler/src/Model/CronjobModel.php b/administrator/components/com_scheduler/src/Model/TaskModel.php similarity index 96% rename from administrator/components/com_scheduler/src/Model/CronjobModel.php rename to administrator/components/com_scheduler/src/Model/TaskModel.php index 172a4db731f30..75bff8ac67a42 100644 --- a/administrator/components/com_scheduler/src/Model/CronjobModel.php +++ b/administrator/components/com_scheduler/src/Model/TaskModel.php @@ -1,6 +1,6 @@ set('execution_rules', json_decode($item->get('execution_rules'))); $item->set('cron_rules', json_decode($item->get('cron_rules'))); - $cronOption = CronjobsHelper::getCronOptions()->findOption( + $cronOption = SchedulerHelper::getCronOptions()->findOption( ($item->id ?? 0) ? ($item->type ?? 0) : $this->getState('cronjob.type') ); diff --git a/administrator/components/com_scheduler/src/Model/CronjobsModel.php b/administrator/components/com_scheduler/src/Model/TasksModel.php similarity index 96% rename from administrator/components/com_scheduler/src/Model/CronjobsModel.php rename to administrator/components/com_scheduler/src/Model/TasksModel.php index 188a8f22f4578..922b1b6bc0764 100644 --- a/administrator/components/com_scheduler/src/Model/CronjobsModel.php +++ b/administrator/components/com_scheduler/src/Model/TasksModel.php @@ -1,6 +1,6 @@ getDbo()->loadObjectList(); } - // Attach CronOptions objects and a safe type title + // Attach TaskOptions objects and a safe type title $this->attachCronOptions($responseList); // If ordering by non-db fields, we need to sort here in code @@ -340,7 +340,7 @@ function (object $c) { } /** - * For an array of items, attaches CronOption objects and (safe) type titles to each. + * For an array of items, attaches TaskOption objects and (safe) type titles to each. * * @param array $items Array of items, passed by reference * @@ -351,7 +351,7 @@ function (object $c) { */ private function attachCronOptions(array &$items): void { - $cronOptions = CronjobsHelper::getCronOptions(); + $cronOptions = SchedulerHelper::getCronOptions(); foreach ($items as $item) { diff --git a/administrator/components/com_scheduler/src/Cronjobs/CronOption.php b/administrator/components/com_scheduler/src/Scheduler/TaskOption.php similarity index 84% rename from administrator/components/com_scheduler/src/Cronjobs/CronOption.php rename to administrator/components/com_scheduler/src/Scheduler/TaskOption.php index 99d3e6ff7364c..a65ddede913a8 100644 --- a/administrator/components/com_scheduler/src/Cronjobs/CronOption.php +++ b/administrator/components/com_scheduler/src/Scheduler/TaskOption.php @@ -1,6 +1,6 @@ 'languageConstantPrefix', ... ] * * @return void @@ -50,18 +50,18 @@ public function addOptions(array $jobsArray): void { foreach ($jobsArray as $jobId => $langConstPrefix) { - $this->options[] = new CronOption($jobId, $langConstPrefix); + $this->options[] = new TaskOption($jobId, $langConstPrefix); } } /** * @param ?string $jobType A unique identifier for the job routine offered by a plugin * - * @return ?CronOption A matching CronOption if available, null otherwise + * @return ?TaskOption A matching TaskOption if available, null otherwise * * @since __DEPLOY_VERSION__ */ - public function findOption(?string $jobType): ?CronOption + public function findOption(?string $jobType): ?TaskOption { if ($jobType === null) { diff --git a/administrator/components/com_scheduler/src/Table/CronjobTable.php b/administrator/components/com_scheduler/src/Table/TaskTable.php similarity index 99% rename from administrator/components/com_scheduler/src/Table/CronjobTable.php rename to administrator/components/com_scheduler/src/Table/TaskTable.php index 8e220f6d8d13a..bbb355ff9f032 100644 --- a/administrator/components/com_scheduler/src/Table/CronjobTable.php +++ b/administrator/components/com_scheduler/src/Table/TaskTable.php @@ -25,7 +25,7 @@ * * @since __DEPLOY_VERSION__ */ -class CronjobTable extends Table +class TaskTable extends Table { /** * Indicates that columns do not fully support the NULL value in the database diff --git a/administrator/components/com_scheduler/src/Traits/CronjobPluginTrait.php b/administrator/components/com_scheduler/src/Traits/TaskPluginTrait.php similarity index 99% rename from administrator/components/com_scheduler/src/Traits/CronjobPluginTrait.php rename to administrator/components/com_scheduler/src/Traits/TaskPluginTrait.php index f7517101daafb..a012cff93065b 100644 --- a/administrator/components/com_scheduler/src/Traits/CronjobPluginTrait.php +++ b/administrator/components/com_scheduler/src/Traits/TaskPluginTrait.php @@ -32,7 +32,7 @@ * * @since __DEPLOY_VERSION__ */ -trait CronjobPluginTrait +trait TaskPluginTrait { /** * Stores the job state. diff --git a/administrator/components/com_scheduler/src/View/Select/HtmlView.php b/administrator/components/com_scheduler/src/View/Select/HtmlView.php index 52fb5d0d61212..7cd36e71d849b 100644 --- a/administrator/components/com_scheduler/src/View/Select/HtmlView.php +++ b/administrator/components/com_scheduler/src/View/Select/HtmlView.php @@ -1,6 +1,6 @@ form = $this->get('Form'); $this->item = $this->get('Item'); @@ -141,7 +141,7 @@ protected function addToolbar(): void // For a new cronjob, check if user has 'core.create' access if ($isNew && $canDo->get('core.create')) { - // The cronjob.apply task maps to the save() method in CronjobController + // The cronjob.apply task maps to the save() method in TaskController ToolbarHelper::apply('cronjob.apply'); $toolbarButtons[] = ['save', 'cronjob.save']; diff --git a/administrator/components/com_scheduler/src/View/Cronjobs/HtmlView.php b/administrator/components/com_scheduler/src/View/Tasks/HtmlView.php similarity index 98% rename from administrator/components/com_scheduler/src/View/Cronjobs/HtmlView.php rename to administrator/components/com_scheduler/src/View/Tasks/HtmlView.php index 61f93920bc24f..9f6961507e331 100644 --- a/administrator/components/com_scheduler/src/View/Cronjobs/HtmlView.php +++ b/administrator/components/com_scheduler/src/View/Tasks/HtmlView.php @@ -1,6 +1,6 @@

item->cronOption): - /** @var CronOption $cronOption */ + /** @var TaskOption $cronOption */ $cronOption = $this->item->cronOption; ?>

diff --git a/plugins/job/requests/requests.php b/plugins/job/requests/requests.php index 2ef4141c7020c..7abd66754ddaa 100644 --- a/plugins/job/requests/requests.php +++ b/plugins/job/requests/requests.php @@ -17,7 +17,7 @@ use Joomla\CMS\Language\Text; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\Component\Scheduler\Administrator\Event\CronRunEvent; -use Joomla\Component\Scheduler\Administrator\Traits\CronjobPluginTrait; +use Joomla\Component\Scheduler\Administrator\Traits\TaskPluginTrait; use Joomla\Event\Event; use Joomla\Event\SubscriberInterface; use Joomla\Registry\Registry; @@ -29,7 +29,7 @@ */ class PlgJobRequests extends CMSPlugin implements SubscriberInterface { - use CronjobPluginTrait; + use TaskPluginTrait; /** * @var string[] diff --git a/plugins/job/testjob/testjob.php b/plugins/job/testjob/testjob.php index 09f270f2d3da3..f6fa7f615a890 100644 --- a/plugins/job/testjob/testjob.php +++ b/plugins/job/testjob/testjob.php @@ -15,7 +15,7 @@ use Joomla\CMS\Form\Form; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\Component\Scheduler\Administrator\Event\CronRunEvent; -use Joomla\Component\Scheduler\Administrator\Traits\CronjobPluginTrait; +use Joomla\Component\Scheduler\Administrator\Traits\TaskPluginTrait; use Joomla\Event\Event; use Joomla\Event\SubscriberInterface; @@ -26,7 +26,7 @@ */ class PlgJobTestjob extends CMSPlugin implements SubscriberInterface { - use CronjobPluginTrait; + use TaskPluginTrait; /** * @var string[] diff --git a/plugins/job/toggleoffline/toggleoffline.php b/plugins/job/toggleoffline/toggleoffline.php index 52670e91267ca..842a31557d53f 100644 --- a/plugins/job/toggleoffline/toggleoffline.php +++ b/plugins/job/toggleoffline/toggleoffline.php @@ -18,7 +18,7 @@ use Joomla\CMS\Language\Text; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\Component\Scheduler\Administrator\Event\CronRunEvent; -use Joomla\Component\Scheduler\Administrator\Traits\CronjobPluginTrait; +use Joomla\Component\Scheduler\Administrator\Traits\TaskPluginTrait; use Joomla\Event\SubscriberInterface; use Joomla\Registry\Registry; use Joomla\Utilities\ArrayHelper; @@ -30,7 +30,7 @@ */ class PlgJobToggleoffline extends CMSPlugin implements SubscriberInterface { - use CronjobPluginTrait; + use TaskPluginTrait; /** * @var string[] diff --git a/plugins/system/cronjobs/cronjobs.php b/plugins/system/cronjobs/cronjobs.php index f9a47e7465472..1c3e5e4e4cc63 100644 --- a/plugins/system/cronjobs/cronjobs.php +++ b/plugins/system/cronjobs/cronjobs.php @@ -21,7 +21,7 @@ use Joomla\CMS\Plugin\PluginHelper; use Joomla\Component\Scheduler\Administrator\Event\CronRunEvent; use Joomla\Component\Scheduler\Administrator\Helper\ExecRuleHelper; -use Joomla\Component\Scheduler\Administrator\Model\CronjobsModel; +use Joomla\Component\Scheduler\Administrator\Model\TasksModel; use Joomla\Database\DatabaseInterface; use Joomla\Database\ParameterType; use Joomla\Event\DispatcherInterface; @@ -108,15 +108,15 @@ class PlgSystemCronjobs extends CMSPlugin implements SubscriberInterface * Override parent constructor. * Prevents the plugin from attaching to the subject if conditions are not met. * - * @param DispatcherInterface $subject The object to observe - * @param array $config An optional associative array of configuration settings. + * @param DispatcherInterface $subject The object to observe + * @param array $config An optional associative array of configuration settings. * * @since __DEPLOY_VERSION__ */ public function __construct(&$subject, $config = []) { // Make sure com_scheduler is installed and enabled - if (! ComponentHelper::isEnabled('com_scheduler')) + if (!ComponentHelper::isEnabled('com_scheduler')) { return; } @@ -160,8 +160,8 @@ public function executeDueJob(Event $event): void /** @var MVCComponent $component */ $component = $this->app->bootComponent('com_scheduler'); - /** @var CronjobsModel $model */ - $model = $component->getMVCFactory()->createModel('Cronjobs', 'Administrator'); + /** @var TasksModel $model */ + $model = $component->getMVCFactory()->createModel('Tasks', 'Administrator'); if (!$model) { @@ -214,17 +214,17 @@ public function executeDueJob(Event $event): void } /** - * Fetches due jobs from CronjobsModel + * Fetches due jobs from TasksModel * ! Orphan filtering + pagination issues in the Model will break this if orphaned jobs exist [TODO] * - * @param CronjobsModel $model The CronjobsModel - * @param boolean $single If true, only a single job is returned + * @param TasksModel $model The TasksModel + * @param boolean $single If true, only a single job is returned * * @return object[] * @throws Exception * @since __DEPLOY_VERSION__ */ - private function getDueJobs(CronjobsModel $model, bool $single = true): array + private function getDueJobs(TasksModel $model, bool $single = true): array { $model->set('__state_set', true); From db0fa8fc25686cee18ea7c7e8d1a9a2ca5cd8cd6 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sat, 21 Aug 2021 17:52:22 +0530 Subject: [PATCH 310/615] Refactor com_cronjobs [6] Refactors database table: `#__cronjobs` => `#__scheduler_tasks`. --- .../com_admin/sql/updates/mysql/4.1.0-2021-08-08.sql | 4 ++-- .../com_admin/sql/updates/postgresql/4.1.0-2021-08-08.sql | 4 ++-- .../components/com_scheduler/src/Model/TasksModel.php | 6 +++--- .../components/com_scheduler/src/Table/TaskTable.php | 2 +- installation/sql/mysql/extensions.sql | 4 ++-- installation/sql/postgresql/extensions.sql | 4 ++-- plugins/system/cronjobs/cronjobs.php | 6 +++--- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-08-08.sql b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-08-08.sql index a1fca78aa4fae..1153f1fd4a22b 100644 --- a/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-08-08.sql +++ b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-08-08.sql @@ -1,8 +1,8 @@ -- --- Table structure for table `#__cronjobs` +-- Table structure for table `#__scheduler_tasks` -- -CREATE TABLE IF NOT EXISTS `#__cronjobs` ( +CREATE TABLE IF NOT EXISTS `#__scheduler_tasks` ( `id` int NOT NULL AUTO_INCREMENT, `asset_id` int NOT NULL UNIQUE DEFAULT '0', `title` varchar(128) NOT NULL UNIQUE, diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-08-08.sql b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-08-08.sql index 255ced252687c..6493e8fb7fb2e 100644 --- a/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-08-08.sql +++ b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-08-08.sql @@ -1,8 +1,8 @@ -- --- Table structure for table "#__cronjobs" +-- Table structure for table "#__scheduler_tasks" -- -CREATE TABLE IF NOT EXISTS "#__cronjobs" +CREATE TABLE IF NOT EXISTS "#__scheduler_tasks" ( "id" int GENERATED ALWAYS AS IDENTITY, "asset_id" bigint NOT NULL DEFAULT '0', diff --git a/administrator/components/com_scheduler/src/Model/TasksModel.php b/administrator/components/com_scheduler/src/Model/TasksModel.php index 922b1b6bc0764..094c436e27d3b 100644 --- a/administrator/components/com_scheduler/src/Model/TasksModel.php +++ b/administrator/components/com_scheduler/src/Model/TasksModel.php @@ -31,7 +31,7 @@ use function substr; /** - * MVC Model to deal with operations concerning multiple `#__cronjobs` entries. + * MVC Model to deal with operations concerning multiple `#__scheduler_tasks` entries. * * @since __DEPLOY_VERSION__ */ @@ -142,8 +142,8 @@ protected function getListQuery(): QueryInterface ) ); - // From the #__cronjobs table as 'a' - $query->from($db->quoteName('#__cronjobs', 'a')); + // From the #__scheduler_tasks table as 'a' + $query->from($db->quoteName('#__scheduler_tasks', 'a')); // Filters go below $filterCount = 0; diff --git a/administrator/components/com_scheduler/src/Table/TaskTable.php b/administrator/components/com_scheduler/src/Table/TaskTable.php index bbb355ff9f032..f548f979cbe62 100644 --- a/administrator/components/com_scheduler/src/Table/TaskTable.php +++ b/administrator/components/com_scheduler/src/Table/TaskTable.php @@ -74,7 +74,7 @@ public function __construct(DatabaseDriver $db) $this->setColumnAlias('published', 'state'); - parent::__construct('#__cronjobs', 'id', $db); + parent::__construct('#__scheduler_tasks', 'id', $db); } /** diff --git a/installation/sql/mysql/extensions.sql b/installation/sql/mysql/extensions.sql index ba6a85e938c2a..3f6a38f7570f1 100644 --- a/installation/sql/mysql/extensions.sql +++ b/installation/sql/mysql/extensions.sql @@ -886,10 +886,10 @@ CREATE TABLE IF NOT EXISTS `#__action_logs_users` ( -- -------------------------------------------------------- -- --- Table structure for table `#__cronjobs` +-- Table structure for table `#__scheduler_tasks` -- -CREATE TABLE IF NOT EXISTS `#__cronjobs` ( +CREATE TABLE IF NOT EXISTS `#__scheduler_tasks` ( `id` int NOT NULL AUTO_INCREMENT, `asset_id` int NOT NULL UNIQUE DEFAULT '0', `title` varchar(128) NOT NULL UNIQUE, diff --git a/installation/sql/postgresql/extensions.sql b/installation/sql/postgresql/extensions.sql index 7ea34ad27b27f..2e60aee8f449c 100644 --- a/installation/sql/postgresql/extensions.sql +++ b/installation/sql/postgresql/extensions.sql @@ -849,10 +849,10 @@ CREATE INDEX "#__action_logs_users_idx_notify" ON "#__action_logs_users" ("notif -- -------------------------------------------------------- -- --- Table structure for table "#__cronjobs" +-- Table structure for table "#__scheduler_tasks" -- -CREATE TABLE IF NOT EXISTS "#__cronjobs" +CREATE TABLE IF NOT EXISTS "#__scheduler_tasks" ( "id" int GENERATED ALWAYS AS IDENTITY, "asset_id" bigint NOT NULL DEFAULT '0', diff --git a/plugins/system/cronjobs/cronjobs.php b/plugins/system/cronjobs/cronjobs.php index 1c3e5e4e4cc63..a052c182df99b 100644 --- a/plugins/system/cronjobs/cronjobs.php +++ b/plugins/system/cronjobs/cronjobs.php @@ -323,7 +323,7 @@ private function setLock(object $cronjob): bool $db = $this->db; $query = $db->getQuery(true); - $query->update($db->qn('#__cronjobs', 'j')) + $query->update($db->qn('#__scheduler_tasks', 'j')) ->set('j.locked = 1') ->where($db->qn('j.id') . ' = :jobId') ->where($db->qn('j.locked') . ' = 0') @@ -354,7 +354,7 @@ private function releaseLock(object $cronjob, array $snapshot = null, bool $sche $db = $this->db; $releaseQuery = $db->getQuery(true); - $releaseQuery->update($db->qn('#__cronjobs', 'j')) + $releaseQuery->update($db->qn('#__scheduler_tasks', 'j')) ->set('locked = 0') ->where($db->qn('id') . ' = :jobId') ->where($db->qn('locked') . ' = 1') @@ -378,7 +378,7 @@ private function releaseLock(object $cronjob, array $snapshot = null, bool $sche /* * [TODO] Failed status - should go in runJob() */ - $updateQuery->update($db->qn('#__cronjobs', 'j')) + $updateQuery->update($db->qn('#__scheduler_tasks', 'j')) ->set( [ 'j.last_execution = :now', From 5d073e4274637a66c29d278396a533db734a3fe3 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sat, 21 Aug 2021 18:48:47 +0530 Subject: [PATCH 311/615] Refactor com_cronjobs [7] - Refactors user/model state variables. - Updates TaskController sets. - Updates TaskModel sets. - Refactors TaskController variables. - Updates DisplayController. - Refactors SchedulerHelper. - Refactors method names and method variables. - Updates namespace. - Updates authority checks. - Updates access.xml. - Updates checks in the controllers and models. - Updates namespace in manifest. - Updates comments in provider.php. - Fixes and updates the TaskModel::canDelete() method. --- .../components/com_scheduler/access.xml | 2 +- .../components/com_scheduler/scheduler.xml | 2 +- .../com_scheduler/services/provider.php | 6 +-- .../src/Controller/DisplayController.php | 12 +++--- .../src/Controller/TaskController.php | 18 ++++----- .../src/Controller/TasksController.php | 4 +- .../com_scheduler/src/Field/JobTypeField.php | 4 +- .../src/Helper/SchedulerHelper.php | 4 +- .../com_scheduler/src/Model/SelectModel.php | 4 +- .../com_scheduler/src/Model/TaskModel.php | 38 ++++++++++--------- .../com_scheduler/src/Model/TasksModel.php | 10 ++--- .../src/Scheduler/TaskOption.php | 4 +- .../src/Scheduler/TaskOptions.php | 14 +++---- .../src/View/Select/HtmlView.php | 2 +- .../com_scheduler/tmpl/cronjob/edit.php | 2 +- 15 files changed, 64 insertions(+), 62 deletions(-) diff --git a/administrator/components/com_scheduler/access.xml b/administrator/components/com_scheduler/access.xml index b16963dd1eba3..b3acaf05016d1 100644 --- a/administrator/components/com_scheduler/access.xml +++ b/administrator/components/com_scheduler/access.xml @@ -9,7 +9,7 @@ -
+
diff --git a/administrator/components/com_scheduler/scheduler.xml b/administrator/components/com_scheduler/scheduler.xml index 6d8e1dab3c768..a99bdb2e42620 100644 --- a/administrator/components/com_scheduler/scheduler.xml +++ b/administrator/components/com_scheduler/scheduler.xml @@ -8,7 +8,7 @@ COM_SCHEDULER_XML_DESCRIPTION - Joomla\Component\Cronjobs + Joomla\Component\Scheduler js css diff --git a/administrator/components/com_scheduler/services/provider.php b/administrator/components/com_scheduler/services/provider.php index 6d75346d08488..bf16ef16af2f4 100644 --- a/administrator/components/com_scheduler/services/provider.php +++ b/administrator/components/com_scheduler/services/provider.php @@ -22,10 +22,10 @@ use Joomla\DI\ServiceProviderInterface; /** - * The cronjobs service provider. + * The com_scheduler service provider. * Returns an instance of the Component's Service Provider Interface - * used to register the components initializers into it's DI container - * created by Joomla. + * used to register the components initializers into a DI container + * created by the application. * * @since __DEPLOY_VERSION__ */ diff --git a/administrator/components/com_scheduler/src/Controller/DisplayController.php b/administrator/components/com_scheduler/src/Controller/DisplayController.php index d2d57a7d62789..4396db960ae1c 100644 --- a/administrator/components/com_scheduler/src/Controller/DisplayController.php +++ b/administrator/components/com_scheduler/src/Controller/DisplayController.php @@ -33,7 +33,7 @@ class DisplayController extends BaseController * @var string * @since __DEPLOY_VERSION__ */ - protected $default_view = 'cronjobs'; + protected $default_view = 'tasks'; /** * @param boolean $cachable If true, the view output will be cached @@ -53,8 +53,8 @@ public function display($cachable = false, $urlparams = array()) { if (!$this->validateEntry()) { - $cronjobsViewUrl = Route::_('index.php?option=com_scheduler&view=cronjobs'); - $this->setRedirect($cronjobsViewUrl); + $tasksViewUrl = Route::_('index.php?option=com_scheduler&view=tasks'); + $this->setRedirect($tasksViewUrl); return false; } @@ -84,11 +84,11 @@ private function validateEntry(string $layout = 'edit'): bool case 'edit': // True if controller was called and verified permissions - $canEdit = $this->checkEditId("${context}.edit.cronjob", $id); + $canEdit = $this->checkEditId("$context.edit.task", $id); $isNew = ($id == 0); - // For new item, entry is invalid if job type was not selected through SelectView - if ($isNew && !$this->app->getUserState("${context}.add.cronjob.cronjob_type")) + // For new item, entry is invalid if task type was not selected through SelectView + if ($isNew && !$this->app->getUserState("$context.add.task.task_type")) { $this->setMessage((Text::_('COM_SCHEDULER_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW')), 'error'); $isValid = false; diff --git a/administrator/components/com_scheduler/src/Controller/TaskController.php b/administrator/components/com_scheduler/src/Controller/TaskController.php index ca712903fd7e1..b3a601338bcb1 100644 --- a/administrator/components/com_scheduler/src/Controller/TaskController.php +++ b/administrator/components/com_scheduler/src/Controller/TaskController.php @@ -45,7 +45,7 @@ public function add(): bool /** @var AdministratorApplication $app */ $app = $this->app; $input = $app->getInput(); - $validJobOptions = SchedulerHelper::getCronOptions(); + $validTaskOptions = SchedulerHelper::getTaskOptions(); $canAdd = parent::add(); @@ -54,10 +54,10 @@ public function add(): bool return false; } - $jobType = $input->get('type'); - $jobOption = $validJobOptions->findOption($jobType) ?: null; + $taskType = $input->get('type'); + $taskOption = $validTaskOptions->findOption($taskType) ?: null; - if (!$jobOption) + if (!$taskOption) { // ? : Is this the right redirect [review] $redirectUrl = 'index.php?option=' . $this->option . '&view=select&layout=edit'; @@ -66,8 +66,8 @@ public function add(): bool $canAdd = false; } - $app->setUserState('com_scheduler.add.cronjob.cronjob_type', $jobType); - $app->setUserState('com_scheduler.add.cronjob.cronjob_option', $jobOption); + $app->setUserState('com_scheduler.add.task.task_type', $taskType); + $app->setUserState('com_scheduler.add.task.task_option', $taskOption); // @todo : Parameter array handling below? @@ -87,8 +87,8 @@ public function cancel($key = null): bool { $result = parent::cancel($key); - $this->app->setUserState('com_scheduler.add.cronjob.cronjob_type', null); - $this->app->setUserState('com_scheduler.add.cronjob.cronjob_option', null); + $this->app->setUserState('com_scheduler.add.task.task_type', null); + $this->app->setUserState('com_scheduler.add.task.task_option', null); // ? Do we need to redirect based on URL's 'return' param? {@see ModuleController} @@ -157,7 +157,7 @@ protected function allowEdit($data = array(), $key = 'id'): bool } // @todo : Check if this works as expected - return $this->app->getIdentity()->authorise('core.edit', 'com_scheduler.cronjob.' . $recordId); + return $this->app->getIdentity()->authorise('core.edit', 'com_scheduler.task.' . $recordId); } } diff --git a/administrator/components/com_scheduler/src/Controller/TasksController.php b/administrator/components/com_scheduler/src/Controller/TasksController.php index 18d4463e21fcb..1a2296ec001ca 100644 --- a/administrator/components/com_scheduler/src/Controller/TasksController.php +++ b/administrator/components/com_scheduler/src/Controller/TasksController.php @@ -1,6 +1,6 @@ options, + SchedulerHelper::getTaskOptions()->options, 'title', 1 ); diff --git a/administrator/components/com_scheduler/src/Helper/SchedulerHelper.php b/administrator/components/com_scheduler/src/Helper/SchedulerHelper.php index b4064c4c924e7..0561bf6e5359e 100644 --- a/administrator/components/com_scheduler/src/Helper/SchedulerHelper.php +++ b/administrator/components/com_scheduler/src/Helper/SchedulerHelper.php @@ -20,7 +20,7 @@ use Joomla\CMS\Event\AbstractEvent; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; -use Joomla\Component\Scheduler\Administrator\Cronjobs\TaskOptions; +use Joomla\Component\Scheduler\Administrator\Tasks\TaskOptions; use function defined; /** @@ -55,7 +55,7 @@ private function __construct() * @throws Exception * @since __DEPLOY_VERSION__ */ - public static function getCronOptions(): TaskOptions + public static function getTaskOptions(): TaskOptions { if (self::$cronOptionsCache !== null) { diff --git a/administrator/components/com_scheduler/src/Model/SelectModel.php b/administrator/components/com_scheduler/src/Model/SelectModel.php index 62d75e13a305b..7d148fb8b6fa8 100644 --- a/administrator/components/com_scheduler/src/Model/SelectModel.php +++ b/administrator/components/com_scheduler/src/Model/SelectModel.php @@ -19,7 +19,7 @@ use Joomla\CMS\Factory; use Joomla\CMS\MVC\Factory\MVCFactoryInterface; use Joomla\CMS\MVC\Model\ListModel; -use Joomla\Component\Scheduler\Administrator\Cronjobs\TaskOption; +use Joomla\Component\Scheduler\Administrator\Tasks\TaskOption; use Joomla\Component\Scheduler\Administrator\Helper\SchedulerHelper; use function defined; @@ -63,6 +63,6 @@ public function __construct($config = array(), ?MVCFactoryInterface $factory = n */ public function getItems(): array { - return SchedulerHelper::getCronOptions()->options; + return SchedulerHelper::getTaskOptions()->options; } } diff --git a/administrator/components/com_scheduler/src/Model/TaskModel.php b/administrator/components/com_scheduler/src/Model/TaskModel.php index 75bff8ac67a42..0de21064b94da 100644 --- a/administrator/components/com_scheduler/src/Model/TaskModel.php +++ b/administrator/components/com_scheduler/src/Model/TaskModel.php @@ -35,7 +35,7 @@ /** * MVC Model to interact with the Scheduler DB. - * Implements methods to add, remove, edit cronjobs. + * Implements methods to add, remove, edit tasks. * * @since __DEPLOY_VERSION__ */ @@ -68,7 +68,7 @@ class TaskModel extends AdminModel * @var string * @since __DEPLOY_VERSION__ */ - public $typeAlias = 'com_scheduler.cronjob'; + public $typeAlias = 'com_scheduler.task'; /** * The Application object, for convenience @@ -125,7 +125,7 @@ public function getForm($data = array(), $loadData = true) * loadFormData() : $data [implemented here] and binds it to the form by calling * $form->bind($data). */ - $form = $this->loadForm('com_scheduler.cronjob', 'cronjob', ['control' => 'jform', 'load_data' => $loadData]); + $form = $this->loadForm('com_scheduler.task', 'task', ['control' => 'jform', 'load_data' => $loadData]); if (empty($form)) { @@ -134,14 +134,14 @@ public function getForm($data = array(), $loadData = true) $user = $this->app->getIdentity(); - // If new entry, set job type from state - if ($this->getState('cronjob.id', 0) === 0 && $this->getState('cronjob.type') !== null) + // If new entry, set task type from state + if ($this->getState('task.id', 0) === 0 && $this->getState('task.type') !== null) { - $form->setValue('type', null, $this->getState('cronjob.type')); + $form->setValue('type', null, $this->getState('task.type')); } // @todo : Check if this is working as expected for new items (id == 0) - if (!$user->authorise('core.edit.state', 'com_scheduler.cronjob.' . $this->getState('job.id'))) + if (!$user->authorise('core.edit.state', 'com_scheduler.task.' . $this->getState('task.id'))) { // Disable fields $form->setFieldAttribute('state', 'disabled', 'true'); @@ -172,7 +172,7 @@ protected function canDelete($record): bool return false; } - return $this->app->getIdentity()->authorise('core.delete', 'com.cronjobs.cronjob.' . $record->id); + return $this->app->getIdentity()->authorise('core.delete', 'com_scheduler.task.' . $record->id); } /** @@ -187,13 +187,15 @@ protected function populateState(): void { $app = $this->app; - $jobId = $app->getInput()->getInt('id'); - $jobType = $app->getUserState('com_scheduler.add.cronjob.cronjob_type'); - $jobOption = $app->getUserState('com_scheduler.add.cronjob.cronjob_option'); + $taskId = $app->getInput()->getInt('id'); + $taskType = $app->getUserState('com_scheduler.add.task.task_type'); - $this->setState('cronjob.id', $jobId); - $this->setState('cronjob.type', $jobType); - $this->setState('cronjob.option', $jobOption); + // @todo: Remove this. Get the option through a helper call. + $taskOption = $app->getUserState('com_scheduler.add.task.task_option'); + + $this->setState('task.id', $taskId); + $this->setState('task.type', $taskType); + $this->setState('task.option', $taskOption); // Load component params, though com_scheduler does not (yet) have any params $cParams = ComponentHelper::getParams($this->option); @@ -229,7 +231,7 @@ public function getTable($name = 'Task', $prefix = 'Table', $options = array()): */ protected function loadFormData() { - $data = $this->app->getUserState('com_scheduler.edit.cronjob.data', array()); + $data = $this->app->getUserState('com_scheduler.edit.task.data', array()); // If the data from UserState is empty, we fetch it with getItem() if (empty($data)) @@ -248,7 +250,7 @@ protected function loadFormData() } // Let plugins manipulate the data - $this->preprocessData('com_scheduler.cronjob', $data, 'job'); + $this->preprocessData('com_scheduler.task', $data, 'job'); return $data; } @@ -276,8 +278,8 @@ public function getItem($pk = null) $item->set('execution_rules', json_decode($item->get('execution_rules'))); $item->set('cron_rules', json_decode($item->get('cron_rules'))); - $cronOption = SchedulerHelper::getCronOptions()->findOption( - ($item->id ?? 0) ? ($item->type ?? 0) : $this->getState('cronjob.type') + $cronOption = SchedulerHelper::getTaskOptions()->findOption( + ($item->id ?? 0) ? ($item->type ?? 0) : $this->getState('task.type') ); $item->set('cronOption', $cronOption); diff --git a/administrator/components/com_scheduler/src/Model/TasksModel.php b/administrator/components/com_scheduler/src/Model/TasksModel.php index 094c436e27d3b..7e1f6b099814f 100644 --- a/administrator/components/com_scheduler/src/Model/TasksModel.php +++ b/administrator/components/com_scheduler/src/Model/TasksModel.php @@ -312,7 +312,7 @@ function (array $arr) { } // Attach TaskOptions objects and a safe type title - $this->attachCronOptions($responseList); + $this->attachTaskOptions($responseList); // If ordering by non-db fields, we need to sort here in code if ($listOrder == 'j.type_title') @@ -320,7 +320,7 @@ function (array $arr) { $responseList = ArrayHelper::sortObjects($responseList, 'safeTypeTitle', $listDirectionN, true, false); } - // Filter out orphaned jobs if the state allows + // Filter out orphaned tasks if the state allows // ! This breaks pagination at the moment [@todo: fix] $showOrphaned = $this->getState('filter.show_orphaned'); @@ -330,7 +330,7 @@ function (array $arr) { array_filter( $responseList, function (object $c) { - return isset($c->cronOption); + return isset($c->taskOption); } ) ); @@ -349,9 +349,9 @@ function (object $c) { * @throws Exception * @since __DEPLOY_VERSION__ */ - private function attachCronOptions(array &$items): void + private function attachTaskOptions(array &$items): void { - $cronOptions = SchedulerHelper::getCronOptions(); + $cronOptions = SchedulerHelper::getTaskOptions(); foreach ($items as $item) { diff --git a/administrator/components/com_scheduler/src/Scheduler/TaskOption.php b/administrator/components/com_scheduler/src/Scheduler/TaskOption.php index a65ddede913a8..930fb3356025f 100644 --- a/administrator/components/com_scheduler/src/Scheduler/TaskOption.php +++ b/administrator/components/com_scheduler/src/Scheduler/TaskOption.php @@ -9,7 +9,7 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt */ -namespace Joomla\Component\Scheduler\Administrator\Cronjobs; +namespace Joomla\Component\Scheduler\Administrator\Tasks; // Restrict direct access defined('_JEXEC') or die; @@ -18,7 +18,7 @@ /** * The TaskOption class. - * Each plugin supporting jobs calls the TaskOptions addOptions() method with an array of TaskOption constructor argument pairs as argument. + * Each plugin supporting tasks calls the TaskOptions addOptions() method with an array of TaskOption constructor argument pairs as argument. * Internally, the TaskOption object generates the job title and description from the language constant prefix. * * @since __DEPLOY_VERSION__ diff --git a/administrator/components/com_scheduler/src/Scheduler/TaskOptions.php b/administrator/components/com_scheduler/src/Scheduler/TaskOptions.php index 3b4bf55add08d..ede3155723fed 100644 --- a/administrator/components/com_scheduler/src/Scheduler/TaskOptions.php +++ b/administrator/components/com_scheduler/src/Scheduler/TaskOptions.php @@ -10,7 +10,7 @@ * */ -namespace Joomla\Component\Scheduler\Administrator\Cronjobs; +namespace Joomla\Component\Scheduler\Administrator\Tasks; // Restrict direct access defined('_JEXEC') or die; @@ -55,24 +55,24 @@ public function addOptions(array $jobsArray): void } /** - * @param ?string $jobType A unique identifier for the job routine offered by a plugin + * @param ?string $taskType A unique identifier for the job routine offered by a plugin * * @return ?TaskOption A matching TaskOption if available, null otherwise * * @since __DEPLOY_VERSION__ */ - public function findOption(?string $jobType): ?TaskOption + public function findOption(?string $taskType): ?TaskOption { - if ($jobType === null) + if ($taskType === null) { return null; } - foreach ($this->options as $job) + foreach ($this->options as $task) { - if ($job->type === $jobType) + if ($task->type === $taskType) { - return $job; + return $task; } } diff --git a/administrator/components/com_scheduler/src/View/Select/HtmlView.php b/administrator/components/com_scheduler/src/View/Select/HtmlView.php index 7cd36e71d849b..75b44e281b1d5 100644 --- a/administrator/components/com_scheduler/src/View/Select/HtmlView.php +++ b/administrator/components/com_scheduler/src/View/Select/HtmlView.php @@ -24,7 +24,7 @@ use Joomla\CMS\Object\CMSObject; use Joomla\CMS\Toolbar\Toolbar; use Joomla\CMS\Toolbar\ToolbarHelper; -use Joomla\Component\Scheduler\Administrator\Cronjobs\TaskOption; +use Joomla\Component\Scheduler\Administrator\Tasks\TaskOption; use function defined; /** diff --git a/administrator/components/com_scheduler/tmpl/cronjob/edit.php b/administrator/components/com_scheduler/tmpl/cronjob/edit.php index 05b64b8e9a27e..9bab3066c0bfe 100644 --- a/administrator/components/com_scheduler/tmpl/cronjob/edit.php +++ b/administrator/components/com_scheduler/tmpl/cronjob/edit.php @@ -17,7 +17,7 @@ use Joomla\CMS\Language\Text; use Joomla\CMS\Layout\LayoutHelper; use Joomla\CMS\Router\Route; -use Joomla\Component\Scheduler\Administrator\Cronjobs\TaskOption; +use Joomla\Component\Scheduler\Administrator\Tasks\TaskOption; use Joomla\Component\Scheduler\Administrator\View\Cronjob\HtmlView; /** @var HtmlView $this */ From 85ec75c3f945ee285dcdb6afe20b5f56c761e1e2 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sat, 21 Aug 2021 19:45:47 +0530 Subject: [PATCH 312/615] Refactor com_cronjobs [8] - Refactor TaskOptions, TaskOption. - Refactor TaskPluginTrait. - Language constants: '_JOB_LOG_PREFIX' => '_TASK_LOG_PREFIX'. - Log category: 'cronjobs' => 'scheduler'. - Class constant JOBS_MAP => TASKS_MAP. --- .../src/Scheduler/TaskOption.php | 12 ++-- .../src/Scheduler/TaskOptions.php | 18 +++--- .../src/Traits/TaskPluginTrait.php | 56 ++++++++++--------- .../language/en-GB/en-GB.plg_job_requests.ini | 2 +- plugins/job/requests/requests.php | 15 ++--- .../language/en-GB/en-GB.plg_job_testjob.ini | 4 +- plugins/job/testjob/testjob.php | 15 ++--- .../en-GB/en-GB.plg_job_toggleoffline.ini | 6 +- plugins/job/toggleoffline/toggleoffline.php | 21 +++---- plugins/system/cronjobs/cronjobs.php | 8 +-- 10 files changed, 83 insertions(+), 74 deletions(-) diff --git a/administrator/components/com_scheduler/src/Scheduler/TaskOption.php b/administrator/components/com_scheduler/src/Scheduler/TaskOption.php index 930fb3356025f..2ba342bdc42ae 100644 --- a/administrator/components/com_scheduler/src/Scheduler/TaskOption.php +++ b/administrator/components/com_scheduler/src/Scheduler/TaskOption.php @@ -1,6 +1,6 @@ 'languageConstantPrefix', ... ] + * @param array $taskRoutines An associative array of {@var TaskOption} constructor argument pairs: + * [ 'taskId' => 'languageConstantPrefix', ... ] * * @return void * * @since __DEPLOY_VERSION__ */ - public function addOptions(array $jobsArray): void + public function addOptions(array $taskRoutines): void { - foreach ($jobsArray as $jobId => $langConstPrefix) + foreach ($taskRoutines as $routineId => $langConstPrefix) { - $this->options[] = new TaskOption($jobId, $langConstPrefix); + $this->options[] = new TaskOption($routineId, $langConstPrefix); } } /** - * @param ?string $taskType A unique identifier for the job routine offered by a plugin + * @param ?string $taskType A unique identifier for a plugin task routine * * @return ?TaskOption A matching TaskOption if available, null otherwise * diff --git a/administrator/components/com_scheduler/src/Traits/TaskPluginTrait.php b/administrator/components/com_scheduler/src/Traits/TaskPluginTrait.php index a012cff93065b..438959e8d25aa 100644 --- a/administrator/components/com_scheduler/src/Traits/TaskPluginTrait.php +++ b/administrator/components/com_scheduler/src/Traits/TaskPluginTrait.php @@ -1,6 +1,6 @@ getArgument('langConstPrefix')); Log::add( - Text::sprintf($langConstPrefix . '_JOB_LOG_MESSAGE', + Text::sprintf($langConstPrefix . '_TASK_LOG_MESSAGE', $this->snapshot['status'], $this->snapshot['duration'] ), Log::INFO, - 'cronjobs' + 'scheduler' ); } } /** - * Enhance the cronjob form with a job specific form. - * Expects the JOBS_MAP class constant to have the relevant information. + * Enhance the task form with task specific fields. + * Expects the TASKS_MAP class constant to have relevant information. * * @param Form $form The form * @param mixed $data The data @@ -123,13 +123,13 @@ private function jobEnd(CronRunEvent $event, int $exitCode, bool $log = true): v * @throws Exception * @since __DEPLOY_VERSION__ */ - protected function enhanceCronjobItemForm(Form $form, $data): bool + protected function enhanceTaskItemForm(Form $form, $data): bool { - $jobId = $this->getJobId($form, $data); + $routineId = $this->getRoutineId($form, $data); - $isSupported = array_key_exists($jobId, self::JOBS_MAP); + $isSupported = array_key_exists($routineId, self::TASKS_MAP); - if (!$isSupported || !$enhancementForm = self::JOBS_MAP[$jobId]['form'] ?? '') + if (!$isSupported || !$enhancementForm = self::TASKS_MAP[$routineId]['form'] ?? '') { return false; } @@ -145,7 +145,8 @@ protected function enhanceCronjobItemForm(Form $form, $data): bool } /** - * Advertises jobs supported by this plugin. + * Advertises the task routines supported by the parent plugin. + * Expects the TASKS_MAP class constant to have relevant information. * * @param Event $event onCronOptionsList Event * @@ -153,13 +154,13 @@ protected function enhanceCronjobItemForm(Form $form, $data): bool * * @since __DEPLOY_VERSION__ */ - public function advertiseJobs(Event $event): void + public function advertiseRoutines(Event $event): void { $options = []; - foreach (self::JOBS_MAP as $job => $details) + foreach (self::TASKS_MAP as $routineId => $details) { - $options[$job] = $details['langConstPrefix']; + $options[$routineId] = $details['langConstPrefix']; } $subject = $event->getArgument('subject'); @@ -175,22 +176,22 @@ public function advertiseJobs(Event $event): void * @throws Exception * @since __DEPLOY_VERSION__ */ - protected function getJobId(Form $form, $data): string + protected function getRoutineId(Form $form, $data): string { - $jobId = $data->cronOption->type ?? $data['cronOption']->type ?? $form->getValue('type'); + $routineId = $data->cronOption->type ?? $data['cronOption']->type ?? $form->getValue('type'); - if (!$jobId) + if (!$routineId) { $app = $this->app ?? Factory::getApplication(); $form = $app->getInput()->get('jform', []); - $jobId = ArrayHelper::getValue($form, 'type', '', 'STRING'); + $routineId = ArrayHelper::getValue($form, 'type', '', 'STRING'); } - return $jobId; + return $routineId; } /** - * Add a log message to the `cronjobs` category. + * Add a log message to the `scheduler` category. * ! This might change * ? Maybe use a PSR3 logger instead? * @@ -199,9 +200,10 @@ protected function getJobId(Form $form, $data): string * * @return void * + * @throws Exception * @since __DEPLOY_VERSION__ */ - protected function addJobLog(string $message, string $priority = 'info'): void + protected function addTaskLog(string $message, string $priority = 'info'): void { static $langLoaded; static $priorityMap = [ @@ -219,6 +221,6 @@ protected function addJobLog(string $message, string $priority = 'info'): void $langLoaded = true; } - Log::add(Text::_('COM_SCHEDULER_TASK_LOG_PREFIX') . $message, $priorityMap[$priority] ?? Log::INFO, 'cronjobs'); + Log::add(Text::_('COM_SCHEDULER_TASK_LOG_PREFIX') . $message, $priorityMap[$priority] ?? Log::INFO, 'scheduler'); } } diff --git a/plugins/job/requests/language/en-GB/en-GB.plg_job_requests.ini b/plugins/job/requests/language/en-GB/en-GB.plg_job_requests.ini index b8ce65eabe6d8..8d4b2ad0a7d69 100644 --- a/plugins/job/requests/language/en-GB/en-GB.plg_job_requests.ini +++ b/plugins/job/requests/language/en-GB/en-GB.plg_job_requests.ini @@ -5,7 +5,7 @@ PLG_JOB_REQUESTS="Job - Requests" PLG_JOB_REQUESTS_BEARER="Bearer" PLG_JOB_REQUESTS_JOB_GET_REQUEST_DESC="Make GET requests to a server. Supports a custom timeout and authorization headers." -PLG_JOB_REQUESTS_JOB_GET_REQUEST_JOB_LOG_MESSAGE="Job> GET return code is: %1$d. Processing Time: %2$.2f seconds" +PLG_JOB_REQUESTS_JOB_GET_REQUEST_TASK_LOG_MESSAGE="Job> GET return code is: %1$d. Processing Time: %2$.2f seconds" PLG_JOB_REQUESTS_JOB_GET_REQUEST_LOG_RESPONSE="Request response code was: %1$d" PLG_JOB_REQUESTS_JOB_GET_REQUEST_TITLE="GET Requests" PLG_JOB_REQUESTS_JOOMLA_TOKEN="X-Joomla-Token" diff --git a/plugins/job/requests/requests.php b/plugins/job/requests/requests.php index 7abd66754ddaa..e96157b9d8888 100644 --- a/plugins/job/requests/requests.php +++ b/plugins/job/requests/requests.php @@ -35,7 +35,7 @@ class PlgJobRequests extends CMSPlugin implements SubscriberInterface * @var string[] * @since __DEPLOY_VERSION__ */ - protected const JOBS_MAP = [ + protected const TASKS_MAP = [ 'plg_job_requests_job_get' => [ 'langConstPrefix' => 'PLG_JOB_REQUESTS_JOB_GET_REQUEST', 'form' => 'get_requests', @@ -86,15 +86,15 @@ public static function getSubscribedEvents(): array */ public function makeRequest(CronRunEvent $event): void { - if (!array_key_exists($event->getJobId(), self::JOBS_MAP)) + if (!array_key_exists($event->getJobId(), self::TASKS_MAP)) { return; } - $this->jobStart(); + $this->taskStart(); $jobId = $event->getJobId(); - $exitCode = $this->{self::JOBS_MAP[$jobId]['call']}($event); - $this->jobEnd($event, $exitCode); + $exitCode = $this->{self::TASKS_MAP[$jobId]['call']}($event); + $this->taskEnd($event, $exitCode); } /** @@ -115,7 +115,7 @@ public function enhanceForm(Event $event): void if ($context === 'com_scheduler.cronjob') { - $this->enhanceCronjobItemForm($form, $data); + $this->enhanceTaskItemForm($form, $data); } } @@ -124,6 +124,7 @@ public function enhanceForm(Event $event): void * * @return integer The exit code * + * @throws Exception * @since __DEPLOY_VERSION__ */ protected function makeGetRequest(CronRunEvent $event): int @@ -155,7 +156,7 @@ protected function makeGetRequest(CronRunEvent $event): int } $responseCode = $response->code; - $this->addJobLog(Text::sprintf('PLG_JOB_REQUESTS_JOB_GET_REQUEST_LOG_RESPONSE', $responseCode)); + $this->addTaskLog(Text::sprintf('PLG_JOB_REQUESTS_JOB_GET_REQUEST_LOG_RESPONSE', $responseCode)); if ($response->code !== 200) { diff --git a/plugins/job/testjob/language/en-GB/en-GB.plg_job_testjob.ini b/plugins/job/testjob/language/en-GB/en-GB.plg_job_testjob.ini index fbe4cbfe5e285..32c7cab014e6b 100644 --- a/plugins/job/testjob/language/en-GB/en-GB.plg_job_testjob.ini +++ b/plugins/job/testjob/language/en-GB/en-GB.plg_job_testjob.ini @@ -4,10 +4,10 @@ PLG_JOB_TESTJOB="Job - Test Plugin" PLG_JOB_TESTJOB_JOB1_DESC="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor." -PLG_JOB_TESTJOB_JOB1_JOB_LOG_MESSAGE="Job> TestJob1 return code is: %1$d. Processing Time: %2$.2f seconds" +PLG_JOB_TESTJOB_JOB1_TASK_LOG_MESSAGE="Job> TestJob1 return code is: %1$d. Processing Time: %2$.2f seconds" PLG_JOB_TESTJOB_JOB1_TITLE="First Test Job" PLG_JOB_TESTJOB_JOB2_DESC="Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium." -PLG_JOB_TESTJOB_JOB2_JOB_LOG_MESSAGE="Job> TestJob2 return code is: %1$d. Processing Time: %2$.2f seconds" +PLG_JOB_TESTJOB_JOB2_TASK_LOG_MESSAGE="Job> TestJob2 return code is: %1$d. Processing Time: %2$.2f seconds" PLG_JOB_TESTJOB_JOB2_TITLE="Second Test Job" PLG_JOB_TESTJOB_LABEL_SAMPLE_FIELD="Sample Field" PLG_JOB_TESTJOB_XML_DESCRIPTION="This is a test plugin for the development of Joomla! Cronjobs" diff --git a/plugins/job/testjob/testjob.php b/plugins/job/testjob/testjob.php index f6fa7f615a890..ebcf49d567762 100644 --- a/plugins/job/testjob/testjob.php +++ b/plugins/job/testjob/testjob.php @@ -32,7 +32,7 @@ class PlgJobTestjob extends CMSPlugin implements SubscriberInterface * @var string[] * @since __DEPLOY_VERSION__ */ - private const JOBS_MAP = [ + private const TASKS_MAP = [ 'job1' => [ 'langConstPrefix' => 'PLG_JOB_TESTJOB_JOB1', 'form' => 'testJobForm' @@ -82,23 +82,24 @@ public static function getSubscribedEvents(): array * * @return void * + * @throws Exception * @since __DEPLOY_VERSION */ public function cronSampleRoutine(CronRunEvent $event): void { - if (array_key_exists($event->getJobId(), self::JOBS_MAP)) + if (array_key_exists($event->getJobId(), self::TASKS_MAP)) { - $this->jobStart(); + $this->taskStart(); // Access to job parameters $params = $event->getArgument('params'); // Plugin does whatever it wants - $this->addJobLog('Starting 20s timeout'); + $this->addTaskLog('Starting 20s timeout'); sleep(20); - $this->addJobLog('20s timeout over!'); + $this->addTaskLog('20s timeout over!'); - $this->jobEnd($event, 0); + $this->taskEnd($event, 0); } } @@ -120,7 +121,7 @@ public function manipulateForms(Event $event): void if ($context === 'com_scheduler.cronjob') { - $this->enhanceCronjobItemForm($form, $data); + $this->enhanceTaskItemForm($form, $data); } } } diff --git a/plugins/job/toggleoffline/language/en-GB/en-GB.plg_job_toggleoffline.ini b/plugins/job/toggleoffline/language/en-GB/en-GB.plg_job_toggleoffline.ini index 415c34823749e..392099b72c9a2 100644 --- a/plugins/job/toggleoffline/language/en-GB/en-GB.plg_job_toggleoffline.ini +++ b/plugins/job/toggleoffline/language/en-GB/en-GB.plg_job_toggleoffline.ini @@ -7,13 +7,13 @@ PLG_JOB_TOGGLE_OFFLINE_DESC="Toggles the site's status on each run." PLG_JOB_TOGGLE_OFFLINE_ERROR_CONFIGURATION_PHP_NOTUNWRITABLE="Could not make configuration.php un-writable." PLG_JOB_TOGGLE_OFFLINE_ERROR_CONFIGURATION_PHP_NOTWRITABLE="Could not make configuration.php writable." PLG_JOB_TOGGLE_OFFLINE_ERROR_WRITE_FAILED="Could not write to the configuration file!" -PLG_JOB_TOGGLE_OFFLINE_JOB_LOG_MESSAGE="Job> ToggleOffline return code is: %1$d. Processing Time: %2$.2f seconds." +PLG_JOB_TOGGLE_OFFLINE_TASK_LOG_MESSAGE="Job> ToggleOffline return code is: %1$d. Processing Time: %2$.2f seconds." PLG_JOB_TOGGLE_OFFLINE_JOB_LOG_SITE_STATUS="Site was %1$s, is now %2$s." PLG_JOB_TOGGLE_OFFLINE_SET_OFFLINE_DESC="Sets site offline to online on each run." -PLG_JOB_TOGGLE_OFFLINE_SET_OFFLINE_JOB_LOG_MESSAGE="Job> SetOffline return code is: %1$d. Processing Time: %2$.2f seconds." +PLG_JOB_TOGGLE_OFFLINE_SET_OFFLINE_TASK_LOG_MESSAGE="Job> SetOffline return code is: %1$d. Processing Time: %2$.2f seconds." PLG_JOB_TOGGLE_OFFLINE_SET_OFFLINE_TITLE="Get Site Offline." PLG_JOB_TOGGLE_OFFLINE_SET_ONLINE_DESC="Sets site status to online on each run." -PLG_JOB_TOGGLE_OFFLINE_SET_ONLINE_JOB_LOG_MESSAGE="Job> SetOnline return code is: %1$d. Processing Time: %2$.2f seconds." +PLG_JOB_TOGGLE_OFFLINE_SET_ONLINE_TASK_LOG_MESSAGE="Job> SetOnline return code is: %1$d. Processing Time: %2$.2f seconds." PLG_JOB_TOGGLE_OFFLINE_SET_ONLINE_TITLE="Get Site Online." PLG_JOB_TOGGLE_OFFLINE_TITLE="Toggle Offline." PLG_JOB_TOGGLE_OFFLINE_XML_DESCRIPTION="Toggles the site's offline status on each run." diff --git a/plugins/job/toggleoffline/toggleoffline.php b/plugins/job/toggleoffline/toggleoffline.php index 842a31557d53f..b81be666bff55 100644 --- a/plugins/job/toggleoffline/toggleoffline.php +++ b/plugins/job/toggleoffline/toggleoffline.php @@ -36,7 +36,7 @@ class PlgJobToggleoffline extends CMSPlugin implements SubscriberInterface * @var string[] * @since __DEPLOY_VERSION__ */ - protected const JOBS_MAP = [ + protected const TASKS_MAP = [ 'plg_job_toggle_offline' => [ 'langConstPrefix' => 'PLG_JOB_TOGGLE_OFFLINE', 'toggle' => true @@ -104,16 +104,16 @@ public static function getSubscribedEvents(): array */ public function toggleOffline(CronRunEvent $event): void { - if (!array_key_exists($event->getJobId(), self::JOBS_MAP)) + if (!array_key_exists($event->getJobId(), self::TASKS_MAP)) { return; } - $this->jobStart(); + $this->taskStart(); $config = ArrayHelper::fromObject(new JConfig); - $toggle = self::JOBS_MAP[$event->getJobId()]['toggle']; + $toggle = self::TASKS_MAP[$event->getJobId()]['toggle']; $oldStatus = $config['offline'] ? 'offline' : 'online'; if ($toggle) @@ -122,15 +122,15 @@ public function toggleOffline(CronRunEvent $event): void } else { - $offline = self::JOBS_MAP[$event->getJobId()]['offline']; + $offline = self::TASKS_MAP[$event->getJobId()]['offline']; $config['offline'] = $offline; } $newStatus = $config['offline'] ? 'offline' : 'online'; $exit = $this->writeConfigFile(new Registry($config)); - $this->addJobLog(Text::sprintf('PLG_JOB_TOGGLE_OFFLINE_JOB_LOG_SITE_STATUS', $oldStatus, $newStatus)); + $this->addTaskLog(Text::sprintf('PLG_JOB_TOGGLE_OFFLINE_JOB_LOG_SITE_STATUS', $oldStatus, $newStatus)); - $this->jobEnd($event, $exit); + $this->taskEnd($event, $exit); } /** @@ -140,6 +140,7 @@ public function toggleOffline(CronRunEvent $event): void * * @return integer The job exit code * + * @throws Exception * @since __DEPLOY_VERSION__ */ private function writeConfigFile(Registry $config): int @@ -150,7 +151,7 @@ private function writeConfigFile(Registry $config): int // Attempt to make the file writeable. if (Path::isOwner($file) && !Path::setPermissions($file)) { - $this->addJobLog(Text::_('PLG_JOB_TOGGLE_OFFLINE_ERROR_CONFIGURATION_PHP_NOTWRITABLE'), 'notice'); + $this->addTaskLog(Text::_('PLG_JOB_TOGGLE_OFFLINE_ERROR_CONFIGURATION_PHP_NOTWRITABLE'), 'notice'); } // Attempt to write the configuration file as a PHP class named JConfig. @@ -158,7 +159,7 @@ private function writeConfigFile(Registry $config): int if (!File::write($file, $configuration)) { - $this->addJobLog(Text::_('PLG_JOB_TOGGLE_OFFLINE_ERROR_WRITE_FAILED'), 'error'); + $this->addTaskLog(Text::_('PLG_JOB_TOGGLE_OFFLINE_ERROR_WRITE_FAILED'), 'error'); return self::$STATUS['KO_RUN']; } @@ -172,7 +173,7 @@ private function writeConfigFile(Registry $config): int // Attempt to make the file un-writeable. if (Path::isOwner($file) && !Path::setPermissions($file, '0444')) { - $this->addJobLog(Text::_('PLG_JOB_TOGGLE_OFFLINE_ERROR_CONFIGURATION_PHP_NOTUNWRITABLE'), 'notice'); + $this->addTaskLog(Text::_('PLG_JOB_TOGGLE_OFFLINE_ERROR_CONFIGURATION_PHP_NOTUNWRITABLE'), 'notice'); } return self::$STATUS['OK_RUN']; diff --git a/plugins/system/cronjobs/cronjobs.php b/plugins/system/cronjobs/cronjobs.php index a052c182df99b..6cfb18e168fc5 100644 --- a/plugins/system/cronjobs/cronjobs.php +++ b/plugins/system/cronjobs/cronjobs.php @@ -178,7 +178,7 @@ public function executeDueJob(Event $event): void // Log events -- should we use action logger or this or both? $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; $options['text_file'] = 'joomla_cronjobs.php'; - Log::addLogger($options, Log::INFO, ['cronjobs']); + Log::addLogger($options, Log::INFO, ['scheduler']); $jobId = $dueJob->id; $jobTitle = $dueJob->title; @@ -187,7 +187,7 @@ public function executeDueJob(Event $event): void Log::add( Text::sprintf('PLG_SYSTEM_CRONJOBS_START', $jobId, $jobTitle), Log::INFO, - 'cronjobs' + 'scheduler' ); $jobRun = $this->runJob($dueJob); @@ -200,7 +200,7 @@ public function executeDueJob(Event $event): void Log::add( Text::sprintf(self::LOG_TEXT[$status], $jobId, 0), Log::INFO, - 'cronjobs' + 'scheduler' ); return; @@ -209,7 +209,7 @@ public function executeDueJob(Event $event): void Log::add( Text::sprintf(self::LOG_TEXT[$status], $jobId, $duration, 0), LOG::INFO, - 'cronjobs' + 'scheduler' ); } From 721f17f6420adbec5b0714df1af6f33b8838ea3a Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sat, 21 Aug 2021 19:53:29 +0530 Subject: [PATCH 313/615] Refactor com_cronjobs [9] - Update namespace TaskOption, TaskOptions (again, oops). - Update TaskOption, TaskOptions directory (`Scheduler` => `Task`). --- .../components/com_scheduler/src/Field/JobTypeField.php | 2 +- .../components/com_scheduler/src/Helper/SchedulerHelper.php | 2 +- .../components/com_scheduler/src/Model/SelectModel.php | 2 +- .../com_scheduler/src/{Scheduler => Task}/TaskOption.php | 2 +- .../com_scheduler/src/{Scheduler => Task}/TaskOptions.php | 2 +- .../components/com_scheduler/src/View/Select/HtmlView.php | 2 +- administrator/components/com_scheduler/tmpl/cronjob/edit.php | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) rename administrator/components/com_scheduler/src/{Scheduler => Task}/TaskOption.php (97%) rename administrator/components/com_scheduler/src/{Scheduler => Task}/TaskOptions.php (96%) diff --git a/administrator/components/com_scheduler/src/Field/JobTypeField.php b/administrator/components/com_scheduler/src/Field/JobTypeField.php index bb28f8431911a..c86c2d4d79fab 100644 --- a/administrator/components/com_scheduler/src/Field/JobTypeField.php +++ b/administrator/components/com_scheduler/src/Field/JobTypeField.php @@ -17,7 +17,7 @@ use Exception; use Joomla\CMS\Form\Field\ListField; use Joomla\CMS\HTML\HTMLHelper; -use Joomla\Component\Scheduler\Administrator\Tasks\TaskOption; +use Joomla\Component\Scheduler\Administrator\Task\TaskOption; use Joomla\Component\Scheduler\Administrator\Helper\SchedulerHelper; use Joomla\Utilities\ArrayHelper; use function array_map; diff --git a/administrator/components/com_scheduler/src/Helper/SchedulerHelper.php b/administrator/components/com_scheduler/src/Helper/SchedulerHelper.php index 0561bf6e5359e..4b9c22d02c42a 100644 --- a/administrator/components/com_scheduler/src/Helper/SchedulerHelper.php +++ b/administrator/components/com_scheduler/src/Helper/SchedulerHelper.php @@ -20,7 +20,7 @@ use Joomla\CMS\Event\AbstractEvent; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; -use Joomla\Component\Scheduler\Administrator\Tasks\TaskOptions; +use Joomla\Component\Scheduler\Administrator\Task\TaskOptions; use function defined; /** diff --git a/administrator/components/com_scheduler/src/Model/SelectModel.php b/administrator/components/com_scheduler/src/Model/SelectModel.php index 7d148fb8b6fa8..ee3f4544197ed 100644 --- a/administrator/components/com_scheduler/src/Model/SelectModel.php +++ b/administrator/components/com_scheduler/src/Model/SelectModel.php @@ -19,7 +19,7 @@ use Joomla\CMS\Factory; use Joomla\CMS\MVC\Factory\MVCFactoryInterface; use Joomla\CMS\MVC\Model\ListModel; -use Joomla\Component\Scheduler\Administrator\Tasks\TaskOption; +use Joomla\Component\Scheduler\Administrator\Task\TaskOption; use Joomla\Component\Scheduler\Administrator\Helper\SchedulerHelper; use function defined; diff --git a/administrator/components/com_scheduler/src/Scheduler/TaskOption.php b/administrator/components/com_scheduler/src/Task/TaskOption.php similarity index 97% rename from administrator/components/com_scheduler/src/Scheduler/TaskOption.php rename to administrator/components/com_scheduler/src/Task/TaskOption.php index 2ba342bdc42ae..31f9baa824fbb 100644 --- a/administrator/components/com_scheduler/src/Scheduler/TaskOption.php +++ b/administrator/components/com_scheduler/src/Task/TaskOption.php @@ -9,7 +9,7 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt */ -namespace Joomla\Component\Scheduler\Administrator\Tasks; +namespace Joomla\Component\Scheduler\Administrator\Task; // Restrict direct access defined('_JEXEC') or die; diff --git a/administrator/components/com_scheduler/src/Scheduler/TaskOptions.php b/administrator/components/com_scheduler/src/Task/TaskOptions.php similarity index 96% rename from administrator/components/com_scheduler/src/Scheduler/TaskOptions.php rename to administrator/components/com_scheduler/src/Task/TaskOptions.php index 9e38787d2d94d..05e5f53e44c34 100644 --- a/administrator/components/com_scheduler/src/Scheduler/TaskOptions.php +++ b/administrator/components/com_scheduler/src/Task/TaskOptions.php @@ -10,7 +10,7 @@ * */ -namespace Joomla\Component\Scheduler\Administrator\Tasks; +namespace Joomla\Component\Scheduler\Administrator\Task; // Restrict direct access defined('_JEXEC') or die; diff --git a/administrator/components/com_scheduler/src/View/Select/HtmlView.php b/administrator/components/com_scheduler/src/View/Select/HtmlView.php index 75b44e281b1d5..a227f8b745af6 100644 --- a/administrator/components/com_scheduler/src/View/Select/HtmlView.php +++ b/administrator/components/com_scheduler/src/View/Select/HtmlView.php @@ -24,7 +24,7 @@ use Joomla\CMS\Object\CMSObject; use Joomla\CMS\Toolbar\Toolbar; use Joomla\CMS\Toolbar\ToolbarHelper; -use Joomla\Component\Scheduler\Administrator\Tasks\TaskOption; +use Joomla\Component\Scheduler\Administrator\Task\TaskOption; use function defined; /** diff --git a/administrator/components/com_scheduler/tmpl/cronjob/edit.php b/administrator/components/com_scheduler/tmpl/cronjob/edit.php index 9bab3066c0bfe..8d5ce1d6d2515 100644 --- a/administrator/components/com_scheduler/tmpl/cronjob/edit.php +++ b/administrator/components/com_scheduler/tmpl/cronjob/edit.php @@ -17,7 +17,7 @@ use Joomla\CMS\Language\Text; use Joomla\CMS\Layout\LayoutHelper; use Joomla\CMS\Router\Route; -use Joomla\Component\Scheduler\Administrator\Tasks\TaskOption; +use Joomla\Component\Scheduler\Administrator\Task\TaskOption; use Joomla\Component\Scheduler\Administrator\View\Cronjob\HtmlView; /** @var HtmlView $this */ From 07a1a88481451ad8e7afdd2a18148d5cec553f31 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sat, 21 Aug 2021 19:57:56 +0530 Subject: [PATCH 314/615] Refactor com_cronjobs [10] Cleanup com_cronjobs directory. --- .../src/Extension/JobAddCommand.php | 0 .../com_cronjobs/css/admin-plg-job.css | 58 ------------------- .../com_cronjobs/css/admin-view-cronjob.css | 24 -------- 3 files changed, 82 deletions(-) delete mode 100644 administrator/components/com_cronjobs/src/Extension/JobAddCommand.php delete mode 100644 build/media_source/com_cronjobs/css/admin-plg-job.css delete mode 100644 build/media_source/com_cronjobs/css/admin-view-cronjob.css diff --git a/administrator/components/com_cronjobs/src/Extension/JobAddCommand.php b/administrator/components/com_cronjobs/src/Extension/JobAddCommand.php deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/build/media_source/com_cronjobs/css/admin-plg-job.css b/build/media_source/com_cronjobs/css/admin-plg-job.css deleted file mode 100644 index e7330954d5939..0000000000000 --- a/build/media_source/com_cronjobs/css/admin-plg-job.css +++ /dev/null @@ -1,58 +0,0 @@ -.new-job { - display: flex; - overflow: hidden; - color: hsl(var(--hue), 30%, 40%); - background-color: hsl(var(--hue), 60%, 97%); - border: 1px solid hsl(var(--hue), 50%, 93%); - border-radius: .25rem; -} - -.new-job-title { - margin-bottom: .25rem; - font-size: 1rem; - font-weight: 700; -} - -.new-job-link { - display: flex; - align-items: flex-end; - justify-content: center; - width: 2.5rem; - font-size: 1.2rem; - background: hsl(var(--hue), 50%, 93%); -} - -.new-job-caption { - display: box; - margin: 0; - overflow: hidden; - font-size: .875rem; - box-orient: vertical; - -webkit-line-clamp: 3; -} - -.new-job-details { - flex: 1 0; - padding: 1rem; -} - -.new-job * { - transition: all .25s ease; -} - -.new-job:hover .new-job-link { - background: var(--template-bg-dark); -} - -.new-job-link span { - margin-bottom: 10px; - color: hsl(var(--hue), 30%, 40%); -} - -.new-job:hover .new-job-link span { - color: #fff; -} - -.new-jobs .card-columns { - grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)) !important; -} diff --git a/build/media_source/com_cronjobs/css/admin-view-cronjob.css b/build/media_source/com_cronjobs/css/admin-view-cronjob.css deleted file mode 100644 index fa9fea928e813..0000000000000 --- a/build/media_source/com_cronjobs/css/admin-view-cronjob.css +++ /dev/null @@ -1,24 +0,0 @@ -.match-custom .control-group .control-label { - width: auto; - padding: 0 0 0 0; -} - -.match-custom .control-group .controls { - /* flex: 1; */ - display: inline-block; - min-width: 7rem; -} - -.match-custom .control-group { - /* display: flex; */ - display: inline-block; - margin-right: 1.5rem; -} - -.match-custom label { - font-size: small; -} - -.match-custom select[multiple] { - height: 15rem; -} From 59c3a89d263e5ca34e8ba9008fb3cbae154508ed Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sat, 21 Aug 2021 23:06:39 +0530 Subject: [PATCH 315/615] Refactor com_cronjobs [11] - Refactors View classes: - Updates namespaces. - Updates toolbar. - Help buttons. - Button task parameters in TaskView, TasksView. - Refactors SchedulerHelper, ExecRuleHelper - Renames plugin group: 'job' => 'task'. - Change plugin directory: 'job' => 'task'. (plugin refactor pending). - Rename forms: - `cronjob.xml` => `task.xml` - `filter_cronjobs.xml` => `filter_tasks.xml` --- .../{filter_cronjobs.xml => filter_tasks.xml} | 0 .../forms/{cronjob.xml => task.xml} | 0 .../src/Helper/ExecRuleHelper.php | 18 +++++----- .../src/Helper/SchedulerHelper.php | 23 ++++++------ .../com_scheduler/src/Model/TaskModel.php | 10 +++--- .../src/View/Select/HtmlView.php | 17 +++++---- .../com_scheduler/src/View/Task/HtmlView.php | 24 ++++++------- .../com_scheduler/src/View/Tasks/HtmlView.php | 36 +++++++++---------- .../requests/forms/get_requests.xml | 0 .../language/en-GB/en-GB.plg_job_requests.ini | 0 .../en-GB/en-GB.plg_job_requests.sys.ini | 0 plugins/{job => task}/requests/requests.php | 0 plugins/{job => task}/requests/requests.xml | 0 .../testjob/forms/testJobForm.xml | 0 .../language/en-GB/en-GB.plg_job_testjob.ini | 0 .../en-GB/en-GB.plg_job_testjob.sys.ini | 0 plugins/{job => task}/testjob/testjob.php | 0 plugins/{job => task}/testjob/testjob.xml | 0 .../en-GB/en-GB.plg_job_toggleoffline.ini | 0 .../en-GB/en-GB.plg_job_toggleoffline.sys.ini | 0 .../toggleoffline/toggleoffline.php | 0 .../toggleoffline/toggleoffline.xml | 0 22 files changed, 62 insertions(+), 66 deletions(-) rename administrator/components/com_scheduler/forms/{filter_cronjobs.xml => filter_tasks.xml} (100%) rename administrator/components/com_scheduler/forms/{cronjob.xml => task.xml} (100%) rename plugins/{job => task}/requests/forms/get_requests.xml (100%) rename plugins/{job => task}/requests/language/en-GB/en-GB.plg_job_requests.ini (100%) rename plugins/{job => task}/requests/language/en-GB/en-GB.plg_job_requests.sys.ini (100%) rename plugins/{job => task}/requests/requests.php (100%) rename plugins/{job => task}/requests/requests.xml (100%) rename plugins/{job => task}/testjob/forms/testJobForm.xml (100%) rename plugins/{job => task}/testjob/language/en-GB/en-GB.plg_job_testjob.ini (100%) rename plugins/{job => task}/testjob/language/en-GB/en-GB.plg_job_testjob.sys.ini (100%) rename plugins/{job => task}/testjob/testjob.php (100%) rename plugins/{job => task}/testjob/testjob.xml (100%) rename plugins/{job => task}/toggleoffline/language/en-GB/en-GB.plg_job_toggleoffline.ini (100%) rename plugins/{job => task}/toggleoffline/language/en-GB/en-GB.plg_job_toggleoffline.sys.ini (100%) rename plugins/{job => task}/toggleoffline/toggleoffline.php (100%) rename plugins/{job => task}/toggleoffline/toggleoffline.xml (100%) diff --git a/administrator/components/com_scheduler/forms/filter_cronjobs.xml b/administrator/components/com_scheduler/forms/filter_tasks.xml similarity index 100% rename from administrator/components/com_scheduler/forms/filter_cronjobs.xml rename to administrator/components/com_scheduler/forms/filter_tasks.xml diff --git a/administrator/components/com_scheduler/forms/cronjob.xml b/administrator/components/com_scheduler/forms/task.xml similarity index 100% rename from administrator/components/com_scheduler/forms/cronjob.xml rename to administrator/components/com_scheduler/forms/task.xml diff --git a/administrator/components/com_scheduler/src/Helper/ExecRuleHelper.php b/administrator/components/com_scheduler/src/Helper/ExecRuleHelper.php index 27e0dd71d1bf3..97524510d4a73 100644 --- a/administrator/components/com_scheduler/src/Helper/ExecRuleHelper.php +++ b/administrator/components/com_scheduler/src/Helper/ExecRuleHelper.php @@ -42,7 +42,7 @@ class ExecRuleHelper * @var array * @since __DEPLOY_VERSION__ */ - private $cronjob; + private $task; /** * @var object @@ -51,14 +51,14 @@ class ExecRuleHelper private $rule; /** - * @param array|object $cronjob A cronjob entry + * @param array|object $task A task entry * * @since __DEPLOY_VERSION__ */ - public function __construct($cronjob) + public function __construct($task) { - $this->cronjob = is_array($cronjob) ? $cronjob : ArrayHelper::fromObject($cronjob); - $rule = $this->getFromCronjob('cron_rules'); + $this->task = is_array($task) ? $task : ArrayHelper::fromObject($task); + $rule = $this->getFromTask('cron_rules'); $this->rule = is_string($rule) ? json_decode($rule) : (is_array($rule) ? (object) $rule : $rule); @@ -66,7 +66,7 @@ public function __construct($cronjob) } /** - * Get a property from the cronjob array + * Get a property from the task array * * @param string $property The property to get * @param mixed $default The default value returned if property does not exist @@ -75,9 +75,9 @@ public function __construct($cronjob) * * @since __DEPLOY_VERSION__ */ - private function getFromCronjob(string $property, $default = null) + private function getFromTask(string $property, $default = null) { - $property = ArrayHelper::getValue($this->cronjob, $property); + $property = ArrayHelper::getValue($this->task, $property); return $property ?? $default; } @@ -96,7 +96,7 @@ public function nextExec(bool $string = true) switch ($this->type) { case 'interval': - $lastExec = Factory::getDate($this->getFromCronjob('last_execution'), 'GMT'); + $lastExec = Factory::getDate($this->getFromTask('last_execution'), 'GMT'); $interval = new DateInterval($this->rule->exp); $nextExec = $lastExec->add($interval); $nextExec = $string ? $nextExec->toSql() : $nextExec; diff --git a/administrator/components/com_scheduler/src/Helper/SchedulerHelper.php b/administrator/components/com_scheduler/src/Helper/SchedulerHelper.php index 4b9c22d02c42a..5d760a922b42c 100644 --- a/administrator/components/com_scheduler/src/Helper/SchedulerHelper.php +++ b/administrator/components/com_scheduler/src/Helper/SchedulerHelper.php @@ -7,7 +7,6 @@ * * @copyright (C) 2021 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt - * */ namespace Joomla\Component\Scheduler\Administrator\Helper; @@ -34,35 +33,35 @@ final class SchedulerHelper /** * Cached TaskOptions object * - * @var TaskOptions + * @var TaskOptions * @since __DEPLOY_VERSION__ */ - protected static $cronOptionsCache = null; + protected static $taskOptionsCache = null; /** * Private constructor to prevent instantiation * - * @since __DEPLOY_VERSION__ + * @since __DEPLOY_VERSION__ */ private function __construct() { } /** - * Returns available jobs as a TaskOptions object + * Returns available task routines as a TaskOptions object. * - * @return TaskOptions A TaskOptions object populated with jobs offered by plugins - * @throws Exception + * @return TaskOptions A TaskOptions object populated with task routines offered by plugins + * @throws Exception * @since __DEPLOY_VERSION__ */ public static function getTaskOptions(): TaskOptions { - if (self::$cronOptionsCache !== null) + if (self::$taskOptionsCache !== null) { - return self::$cronOptionsCache; + return self::$taskOptionsCache; } - /**@var AdministratorApplication $app */ + /**@var AdministratorApplication $app */ $app = Factory::getApplication(); $options = new TaskOptions; $event = AbstractEvent::create( @@ -72,10 +71,10 @@ public static function getTaskOptions(): TaskOptions ] ); - PluginHelper::importPlugin('job'); + PluginHelper::importPlugin('task'); $app->getDispatcher()->dispatch('onCronOptionsList', $event); - self::$cronOptionsCache = $options; + self::$taskOptionsCache = $options; return $options; } diff --git a/administrator/components/com_scheduler/src/Model/TaskModel.php b/administrator/components/com_scheduler/src/Model/TaskModel.php index 0de21064b94da..f1ea41ae26060 100644 --- a/administrator/components/com_scheduler/src/Model/TaskModel.php +++ b/administrator/components/com_scheduler/src/Model/TaskModel.php @@ -94,8 +94,8 @@ public function __construct($config = array(), MVCFactoryInterface $factory = nu $config['events_map'] = $config['events_map'] ?? []; $config['events_map'] = array_merge( [ - 'save' => 'job', - 'validate' => 'job' + 'save' => 'task', + 'validate' => 'task' ], $config['events_map'] ); @@ -250,7 +250,7 @@ protected function loadFormData() } // Let plugins manipulate the data - $this->preprocessData('com_scheduler.task', $data, 'job'); + $this->preprocessData('com_scheduler.task', $data, 'task'); return $data; } @@ -457,8 +457,8 @@ function (string $x): int { */ protected function preprocessForm(Form $form, $data, $group = 'content'): void { - // Load the 'job' plugin group - PluginHelper::importPlugin('job'); + // Load the 'task' plugin group + PluginHelper::importPlugin('task'); // Let the parent method take over parent::preprocessForm($form, $data, $group); diff --git a/administrator/components/com_scheduler/src/View/Select/HtmlView.php b/administrator/components/com_scheduler/src/View/Select/HtmlView.php index a227f8b745af6..d0bf273ccbb76 100644 --- a/administrator/components/com_scheduler/src/View/Select/HtmlView.php +++ b/administrator/components/com_scheduler/src/View/Select/HtmlView.php @@ -28,15 +28,15 @@ use function defined; /** - * The MVC View Select - * Lets the user choose from a list of plugin defined Job routines. + * The MVC View SelectView + * Lets the user choose from a list of plugin defined task routines. * * @since __DEPLOY_VERSION__ */ class HtmlView extends BaseHtmlView { /** - * @var AdministratorApplication + * @var AdministratorApplication * @since __DEPLOY_VERSION__ */ protected $app; @@ -77,7 +77,7 @@ class HtmlView extends BaseHtmlView * helper_path: the path (optional) of the helper files (defaults to base_path + /helpers/) * layout: the layout (optional) to use to display the view * - * @throws Exception + * @throws Exception * @since __DEPLOY_VERSION__ */ public function __construct($config = []) @@ -89,9 +89,9 @@ public function __construct($config = []) /** * @param string $tpl The name of the template file to parse; automatically searches through the template paths. * - * @return void + * @return void * - * @throws Exception + * @throws Exception * @since __DEPLOY_VERSION__ */ public function display($tpl = null): void @@ -124,7 +124,7 @@ protected function addToolbar(): void /* * Get the global Toolbar instance * @todo : Replace usage with ToolbarFactoryInterface. but how? - * Probably some changes in the core, since mod_menu calls and renders the getInstance() toolbar + * Probably some changes in the core, since mod_menu calls and renders the getInstance() toolbar */ $toolbar = Toolbar::getInstance(); @@ -144,7 +144,6 @@ protected function addToolbar(): void } // Add help button - $toolbar->help('JHELP_COMPONENTS_CRONJOBS_MANAGER'); - + $toolbar->help('JHELP_COMPONENTS_SCHEDULED_TASKS_MANAGER'); } } diff --git a/administrator/components/com_scheduler/src/View/Task/HtmlView.php b/administrator/components/com_scheduler/src/View/Task/HtmlView.php index 5709f42c1effb..a7ead82515769 100644 --- a/administrator/components/com_scheduler/src/View/Task/HtmlView.php +++ b/administrator/components/com_scheduler/src/View/Task/HtmlView.php @@ -9,7 +9,7 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt */ -namespace Joomla\Component\Scheduler\Administrator\View\Cronjob; +namespace Joomla\Component\Scheduler\Administrator\View\Task; // Restrict direct access defined('_JEXEC') or die; @@ -107,9 +107,8 @@ public function display($tpl = null): void */ $this->form = $this->get('Form'); $this->item = $this->get('Item'); - $this->state = $this->get('State'); - $this->canDo = ContentHelper::getActions('com_scheduler', 'cronjob', $this->item->id); + $this->canDo = ContentHelper::getActions('com_scheduler', 'task', $this->item->id); $this->addToolbar(); parent::display($tpl); @@ -120,12 +119,11 @@ public function display($tpl = null): void * * @return void * - * @throws Exception * @since __DEPLOY_VERSION__ */ protected function addToolbar(): void { - $app = Factory::getApplication(); + $app = $this->app; $app->getInput()->set('hidemainmenu', true); $user = $app->getIdentity(); @@ -138,20 +136,20 @@ protected function addToolbar(): void // Goes into ToolbarHelper::saveGroup() $toolbarButtons = []; - // For a new cronjob, check if user has 'core.create' access + // For a new task, check if user has 'core.create' access if ($isNew && $canDo->get('core.create')) { - // The cronjob.apply task maps to the save() method in TaskController - ToolbarHelper::apply('cronjob.apply'); + // The task.apply task maps to the save() method in TaskController + ToolbarHelper::apply('task.apply'); - $toolbarButtons[] = ['save', 'cronjob.save']; + $toolbarButtons[] = ['save', 'task.save']; } else { if (!$isNew && $canDo->get('core.edit')) { - ToolbarHelper::apply('cronjob.apply'); - $toolbarButtons[] = ['save', 'cronjob.save']; + ToolbarHelper::apply('task.apply'); + $toolbarButtons[] = ['save', 'task.save']; // @todo | ? : Do we need save2new and save2copy? If yes, need to support in the Model, // here and the Controller. @@ -162,7 +160,7 @@ protected function addToolbar(): void $toolbarButtons ); - ToolbarHelper::cancel('cronjob.cancel', $isNew ? 'JTOOLBAR_CANCEL' : 'JTOOLBAR_CLOSE'); + ToolbarHelper::cancel('task.cancel', $isNew ? 'JTOOLBAR_CANCEL' : 'JTOOLBAR_CLOSE'); + ToolbarHelper::help('JHELP_COMPONENTS_SCHEDULED_TASKS_MANAGER'); } - } diff --git a/administrator/components/com_scheduler/src/View/Tasks/HtmlView.php b/administrator/components/com_scheduler/src/View/Tasks/HtmlView.php index 9f6961507e331..a337bc9d62f30 100644 --- a/administrator/components/com_scheduler/src/View/Tasks/HtmlView.php +++ b/administrator/components/com_scheduler/src/View/Tasks/HtmlView.php @@ -9,7 +9,7 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt */ -namespace Joomla\Component\Scheduler\Administrator\View\Cronjobs; +namespace Joomla\Component\Scheduler\Administrator\View\Tasks; // Restrict direct access defined('_JEXEC') or die; @@ -39,7 +39,7 @@ class HtmlView extends BaseHtmlView /** * An array of items * - * @var array + * @var array * @since __DEPLOY_VERSION__ */ protected $items; @@ -47,7 +47,7 @@ class HtmlView extends BaseHtmlView /** * The pagination object * - * @var Pagination + * @var Pagination * @since __DEPLOY_VERSION__ */ protected $pagination; @@ -55,7 +55,7 @@ class HtmlView extends BaseHtmlView /** * The model state * - * @var CMSObject + * @var CMSObject * @since __DEPLOY_VERSION__ */ protected $state; @@ -63,7 +63,7 @@ class HtmlView extends BaseHtmlView /** * A Form object for search filters * - * @var Form + * @var Form * @since __DEPLOY_VERSION__ */ public $filterForm; @@ -71,7 +71,7 @@ class HtmlView extends BaseHtmlView /** * The active search filters * - * @var array + * @var array * @since __DEPLOY_VERSION__ */ public $activeFilters; @@ -79,7 +79,7 @@ class HtmlView extends BaseHtmlView /** * Is this view an Empty State * - * @var boolean + * @var boolean * @since __DEPLOY_VERSION__ */ private $isEmptyState = false; @@ -96,9 +96,9 @@ class HtmlView extends BaseHtmlView /** * @param string $tpl The name of the template file to parse; automatically searches through the template paths. * - * @return void + * @return void * - * @throws Exception + * @throws Exception * * @since __DEPLOY_VERSION__ */ @@ -134,9 +134,9 @@ public function display($tpl = null): void /** * Add the page title and toolbar. * - * @return void + * @return void * - * @throws Exception + * @throws Exception * * @since __DEPLOY_VERSION__ */ @@ -149,7 +149,7 @@ protected function addToolbar(): void * Get the toolbar object instance * !! @todo : Replace usage with ToolbarFactoryInterface */ - $toolbar = Toolbar::getInstance('toolbar'); + $toolbar = Toolbar::getInstance(); ToolbarHelper::title(Text::_('COM_SCHEDULER_MANAGER_TASKS'), 'clock'); @@ -163,7 +163,7 @@ protected function addToolbar(): void if (!$this->isEmptyState && ($canDo->get('core.edit.state') || $user->authorise('core.admin'))) { - /** @var DropdownButton $dropdown */ + /** @var DropdownButton $dropdown */ $dropdown = $toolbar->dropdownButton('status-group') ->toggleSplit(false) ->text('JTOOLBAR_CHANGE_STATUS') @@ -176,13 +176,13 @@ protected function addToolbar(): void // Add the batch Enable, Disable and Trash buttons if privileged if ($canDo->get('core.edit.state')) { - $childBar->addNew('cronjobs.publish', 'JTOOLBAR_ENABLE')->listCheck(true)->icon('icon-publish'); - $childBar->addNew('cronjobs.unpublish', 'JTOOLBAR_DISABLE')->listCheck(true)->icon('icon-unpublish'); + $childBar->addNew('tasks.publish', 'JTOOLBAR_ENABLE')->listCheck(true)->icon('icon-publish'); + $childBar->addNew('tasks.unpublish', 'JTOOLBAR_DISABLE')->listCheck(true)->icon('icon-unpublish'); // We don't want the batch Trash button if displayed entries are all trashed if ($this->state->get('filter.state') != -2) { - $childBar->trash('cronjobs.trash')->listCheck(true); + $childBar->trash('tasks.trash')->listCheck(true); } } } @@ -190,7 +190,7 @@ protected function addToolbar(): void // Add "Empty Trash" button if filtering by trashed. if ($this->state->get('filter.state') == -2 && $canDo->get('core.delete')) { - $toolbar->delete('cronjobs.delete') + $toolbar->delete('tasks.delete') ->message('JGLOBAL_CONFIRM_DELETE') ->text('JTOOLBAR_EMPTY_TRASH') ->listCheck(true); @@ -202,6 +202,6 @@ protected function addToolbar(): void $toolbar->preferences('com_scheduler'); } - $toolbar->help('JHELP_COMPONENTS_CRONJOBS_MANAGER'); + $toolbar->help('JHELP_COMPONENTS_SCHEDULED_TASKS_MANAGER'); } } diff --git a/plugins/job/requests/forms/get_requests.xml b/plugins/task/requests/forms/get_requests.xml similarity index 100% rename from plugins/job/requests/forms/get_requests.xml rename to plugins/task/requests/forms/get_requests.xml diff --git a/plugins/job/requests/language/en-GB/en-GB.plg_job_requests.ini b/plugins/task/requests/language/en-GB/en-GB.plg_job_requests.ini similarity index 100% rename from plugins/job/requests/language/en-GB/en-GB.plg_job_requests.ini rename to plugins/task/requests/language/en-GB/en-GB.plg_job_requests.ini diff --git a/plugins/job/requests/language/en-GB/en-GB.plg_job_requests.sys.ini b/plugins/task/requests/language/en-GB/en-GB.plg_job_requests.sys.ini similarity index 100% rename from plugins/job/requests/language/en-GB/en-GB.plg_job_requests.sys.ini rename to plugins/task/requests/language/en-GB/en-GB.plg_job_requests.sys.ini diff --git a/plugins/job/requests/requests.php b/plugins/task/requests/requests.php similarity index 100% rename from plugins/job/requests/requests.php rename to plugins/task/requests/requests.php diff --git a/plugins/job/requests/requests.xml b/plugins/task/requests/requests.xml similarity index 100% rename from plugins/job/requests/requests.xml rename to plugins/task/requests/requests.xml diff --git a/plugins/job/testjob/forms/testJobForm.xml b/plugins/task/testjob/forms/testJobForm.xml similarity index 100% rename from plugins/job/testjob/forms/testJobForm.xml rename to plugins/task/testjob/forms/testJobForm.xml diff --git a/plugins/job/testjob/language/en-GB/en-GB.plg_job_testjob.ini b/plugins/task/testjob/language/en-GB/en-GB.plg_job_testjob.ini similarity index 100% rename from plugins/job/testjob/language/en-GB/en-GB.plg_job_testjob.ini rename to plugins/task/testjob/language/en-GB/en-GB.plg_job_testjob.ini diff --git a/plugins/job/testjob/language/en-GB/en-GB.plg_job_testjob.sys.ini b/plugins/task/testjob/language/en-GB/en-GB.plg_job_testjob.sys.ini similarity index 100% rename from plugins/job/testjob/language/en-GB/en-GB.plg_job_testjob.sys.ini rename to plugins/task/testjob/language/en-GB/en-GB.plg_job_testjob.sys.ini diff --git a/plugins/job/testjob/testjob.php b/plugins/task/testjob/testjob.php similarity index 100% rename from plugins/job/testjob/testjob.php rename to plugins/task/testjob/testjob.php diff --git a/plugins/job/testjob/testjob.xml b/plugins/task/testjob/testjob.xml similarity index 100% rename from plugins/job/testjob/testjob.xml rename to plugins/task/testjob/testjob.xml diff --git a/plugins/job/toggleoffline/language/en-GB/en-GB.plg_job_toggleoffline.ini b/plugins/task/toggleoffline/language/en-GB/en-GB.plg_job_toggleoffline.ini similarity index 100% rename from plugins/job/toggleoffline/language/en-GB/en-GB.plg_job_toggleoffline.ini rename to plugins/task/toggleoffline/language/en-GB/en-GB.plg_job_toggleoffline.ini diff --git a/plugins/job/toggleoffline/language/en-GB/en-GB.plg_job_toggleoffline.sys.ini b/plugins/task/toggleoffline/language/en-GB/en-GB.plg_job_toggleoffline.sys.ini similarity index 100% rename from plugins/job/toggleoffline/language/en-GB/en-GB.plg_job_toggleoffline.sys.ini rename to plugins/task/toggleoffline/language/en-GB/en-GB.plg_job_toggleoffline.sys.ini diff --git a/plugins/job/toggleoffline/toggleoffline.php b/plugins/task/toggleoffline/toggleoffline.php similarity index 100% rename from plugins/job/toggleoffline/toggleoffline.php rename to plugins/task/toggleoffline/toggleoffline.php diff --git a/plugins/job/toggleoffline/toggleoffline.xml b/plugins/task/toggleoffline/toggleoffline.xml similarity index 100% rename from plugins/job/toggleoffline/toggleoffline.xml rename to plugins/task/toggleoffline/toggleoffline.xml From 1d39ad8ed91c64445fb53b6a7d27a101e78f3504 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 22 Aug 2021 04:23:51 +0530 Subject: [PATCH 316/615] Refactor com_cronjobs [12] - Refactors plugin group 'job' => 'task'. - Refactors manifests. - Refactors language constants. - Refactors installation SQL. - Refactors plg `testjob` => `testtasks` (dir, files pending). - Refactors TaskTable contexts. --- .../sql/updates/mysql/4.1.0-2021-08-04.sql | 4 +-- .../updates/postgresql/4.1.0-2021-08-04.sql | 4 +-- .../com_scheduler/forms/filter_tasks.xml | 2 +- .../com_scheduler/src/Table/TaskTable.php | 4 +-- .../com_scheduler/tmpl/cronjob/edit.php | 6 ++-- .../com_scheduler/tmpl/cronjobs/default.php | 3 ++ .../com_scheduler/tmpl/select/default.php | 2 +- installation/sql/mysql/base.sql | 6 ++-- installation/sql/postgresql/base.sql | 6 ++-- plugins/task/requests/forms/get_requests.xml | 14 ++++---- .../language/en-GB/en-GB.plg_job_requests.ini | 26 +++++++------- .../en-GB/en-GB.plg_job_requests.sys.ini | 4 +-- plugins/task/requests/requests.php | 18 +++++----- plugins/task/requests/requests.xml | 8 ++--- plugins/task/testjob/forms/testJobForm.xml | 2 +- .../language/en-GB/en-GB.plg_job_testjob.ini | 18 +++++----- .../en-GB/en-GB.plg_job_testjob.sys.ini | 4 +-- plugins/task/testjob/testjob.php | 36 +++++++++---------- plugins/task/testjob/testjob.xml | 12 +++---- .../en-GB/en-GB.plg_job_toggleoffline.ini | 30 ++++++++-------- .../en-GB/en-GB.plg_job_toggleoffline.sys.ini | 4 +-- plugins/task/toggleoffline/toggleoffline.php | 32 ++++++++--------- plugins/task/toggleoffline/toggleoffline.xml | 10 +++--- 23 files changed, 129 insertions(+), 126 deletions(-) diff --git a/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-08-04.sql b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-08-04.sql index 652328f02a71b..ca897eca7b2a1 100644 --- a/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-08-04.sql +++ b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-08-04.sql @@ -3,7 +3,7 @@ INSERT INTO `#__extensions` (`package_id`, `name`, `type`, `element`, `folder`, `protected`, `locked`, `manifest_cache`, `params`, `custom_data`) VALUES (0, 'com_scheduler', 'component', 'com_scheduler', '', 1, 1, 1, 0, 1, '', '', ''); --- Add `plg_job_testjob` to `#__extensions` +-- Add `plg_task_testtasks` to `#__extensions` INSERT INTO `#__extensions` (`package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `locked`, `manifest_cache`, `params`, `custom_data`, `ordering`, `state`) -VALUES (0, 'plg_job_testjob', 'plugin', 'testjob', 'job', 0, 1, 1, 0, 0, '', '{}', '', 15, 0); +VALUES (0, 'plg_task_testtasks', 'plugin', 'testtasks', 'job', 0, 1, 1, 0, 0, '', '{}', '', 15, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-08-04.sql b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-08-04.sql index 74beff5acd21d..2f75825effa99 100644 --- a/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-08-04.sql +++ b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-08-04.sql @@ -3,7 +3,7 @@ INSERT INTO "#__extensions" ("package_id", "name", "type", "element", "folder", "protected", "locked", "manifest_cache", "params", "custom_data", "ordering", "state") VALUES (0, 'com_scheduler', 'component', 'com_scheduler', '', 1, 1, 1, 0, 1, '', '{}', '', 0, 0); --- Add "plg_job_testjob" to "#__extensions" +-- Add "plg_task_testtasks" to "#__extensions" INSERT INTO "#__extensions" ("package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "locked", "manifest_cache", "params", "custom_data", "ordering", "state") -VALUES (0, 'plg_job_testjob', 'plugin', 'testjob', 'job', 0, 1, 1, 0, 0, '', '{}', '', 15, 0); +VALUES (0, 'plg_task_testtasks', 'plugin', 'testtasks', 'job', 0, 1, 1, 0, 0, '', '{}', '', 15, 0); diff --git a/administrator/components/com_scheduler/forms/filter_tasks.xml b/administrator/components/com_scheduler/forms/filter_tasks.xml index df7684bf3b5a5..deaec434195db 100644 --- a/administrator/components/com_scheduler/forms/filter_tasks.xml +++ b/administrator/components/com_scheduler/forms/filter_tasks.xml @@ -21,7 +21,7 @@ diff --git a/administrator/components/com_scheduler/src/Table/TaskTable.php b/administrator/components/com_scheduler/src/Table/TaskTable.php index f548f979cbe62..51d5f29857802 100644 --- a/administrator/components/com_scheduler/src/Table/TaskTable.php +++ b/administrator/components/com_scheduler/src/Table/TaskTable.php @@ -69,7 +69,7 @@ class TaskTable extends Table */ public function __construct(DatabaseDriver $db) { - $this->typeAlias = 'com_scheduler.cronjob'; + $this->typeAlias = 'com_scheduler.task'; $this->created = Factory::getDate()->toSql(); $this->setColumnAlias('published', 'state'); @@ -155,7 +155,7 @@ protected function _getAssetName(): string { $k = $this->_tbl_key; - return 'com_scheduler.cronjob.' . (int) $this->$k; + return 'com_scheduler.task.' . (int) $this->$k; } } diff --git a/administrator/components/com_scheduler/tmpl/cronjob/edit.php b/administrator/components/com_scheduler/tmpl/cronjob/edit.php index 8d5ce1d6d2515..f30185e9e988a 100644 --- a/administrator/components/com_scheduler/tmpl/cronjob/edit.php +++ b/administrator/components/com_scheduler/tmpl/cronjob/edit.php @@ -18,9 +18,9 @@ use Joomla\CMS\Layout\LayoutHelper; use Joomla\CMS\Router\Route; use Joomla\Component\Scheduler\Administrator\Task\TaskOption; -use Joomla\Component\Scheduler\Administrator\View\Cronjob\HtmlView; +use Joomla\Component\Scheduler\Administrator\View\Task\HtmlView; -/** @var HtmlView $this */ +/** @var HtmlView $this */ $wa = $this->document->getWebAssetManager(); @@ -82,7 +82,7 @@ class="form-validate">

enqueueMessage(Text::_('COM_SCHEDULER_WARNING_EXISTING_JOB_TYPE_NOT_FOUND'), 'warning'); + $app->enqueueMessage(Text::_('COM_SCHEDULER_WARNING_EXISTING_TASK_TYPE_NOT_FOUND'), 'warning'); ?>
diff --git a/administrator/components/com_scheduler/tmpl/cronjobs/default.php b/administrator/components/com_scheduler/tmpl/cronjobs/default.php index 61e14a9581ac8..cb1bab2d18f79 100644 --- a/administrator/components/com_scheduler/tmpl/cronjobs/default.php +++ b/administrator/components/com_scheduler/tmpl/cronjobs/default.php @@ -18,6 +18,9 @@ use Joomla\CMS\Layout\LayoutHelper; use Joomla\CMS\Router\Route; use Joomla\CMS\Session\Session; +use Joomla\Component\Scheduler\Administrator\View\Tasks\HtmlView; + +/** @var HtmlView $this*/ HTMLHelper::_('behavior.multiselect'); diff --git a/administrator/components/com_scheduler/tmpl/select/default.php b/administrator/components/com_scheduler/tmpl/select/default.php index 5ddc276e5cb90..c4e2c213bd924 100644 --- a/administrator/components/com_scheduler/tmpl/select/default.php +++ b/administrator/components/com_scheduler/tmpl/select/default.php @@ -18,7 +18,7 @@ use Joomla\CMS\Router\Route; use Joomla\Component\Scheduler\Administrator\View\Select\HtmlView; -/** @var HtmlView $this */ +/** @var HtmlView $this */ $app = $this->app; diff --git a/installation/sql/mysql/base.sql b/installation/sql/mysql/base.sql index 2256ff2ee6e3c..8a61ab14cdb8f 100644 --- a/installation/sql/mysql/base.sql +++ b/installation/sql/mysql/base.sql @@ -368,10 +368,10 @@ INSERT INTO `#__extensions` (`package_id`, `name`, `type`, `element`, `folder`, (0, 'plg_workflow_featuring', 'plugin', 'featuring', 'workflow', 0, 1, 1, 0, 1, '', '{}', '', 1, 0), (0, 'plg_workflow_notification', 'plugin', 'notification', 'workflow', 0, 1, 1, 0, 1, '', '{}', '', 2, 0), (0, 'plg_workflow_publishing', 'plugin', 'publishing', 'workflow', 0, 1, 1, 0, 1, '', '{}', '', 3, 0), -(0, 'plg_job_testjob', 'plugin', 'testjob', 'job', 0, 1, 1, 0, 0, '', '{}', '', 15, 0), +(0, 'plg_task_testtasks', 'plugin', 'testtasks', 'job', 0, 1, 1, 0, 0, '', '{}', '', 15, 0), (0, 'plg_system_cronjobs', 'plugin', 'cronjobs', 'system', 0, 1, 1, 0, 0, '', '{}', '', 15, 0), -(0, 'plg_job_requests', 'plugin', 'requests', 'job', 0, 1, 1, 0, 0, '', '{}', '', 15, 0), -(0, 'plg_job_toggleoffline', 'plugin', 'toggleoffline', 'job', 0, 1, 1, 0, 0, '', '{}', '', 15, 0); +(0, 'plg_task_requests', 'plugin', 'requests', 'job', 0, 1, 1, 0, 0, '', '{}', '', 15, 0), +(0, 'plg_task_toggleoffline', 'plugin', 'toggleoffline', 'job', 0, 1, 1, 0, 0, '', '{}', '', 15, 0); -- Templates INSERT INTO `#__extensions` (`package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `locked`, `manifest_cache`, `params`, `custom_data`, `ordering`, `state`) VALUES diff --git a/installation/sql/postgresql/base.sql b/installation/sql/postgresql/base.sql index aba00bc7ee52a..fd0fa90e5b3fb 100644 --- a/installation/sql/postgresql/base.sql +++ b/installation/sql/postgresql/base.sql @@ -374,10 +374,10 @@ INSERT INTO "#__extensions" ("package_id", "name", "type", "element", "folder", (0, 'plg_workflow_featuring', 'plugin', 'featuring', 'workflow', 0, 1, 1, 0, 1, '', '{}', '', 1, 0), (0, 'plg_workflow_notification', 'plugin', 'notification', 'workflow', 0, 1, 1, 0, 1, '', '{}', '', 2, 0), (0, 'plg_workflow_publishing', 'plugin', 'publishing', 'workflow', 0, 1, 1, 0, 1, '', '{}', '', 3, 0), -(0, 'plg_job_testjob', 'plugin', 'testjob', 'job', 0, 1, 1, 0, 0, '', '{}', '', 15, 0), +(0, 'plg_task_testtasks', 'plugin', 'testtasks', 'job', 0, 1, 1, 0, 0, '', '{}', '', 15, 0), (0, 'plg_system_cronjobs', 'plugin', 'cronjobs', 'system', 0, 1, 1, 0, 0, '', '{}', '', 15, 0), -(0, 'plg_job_requests', 'plugin', 'requests', 'job', 0, 1, 1, 0, 0, '', '{}', '', 15, 0), -(0, 'plg_job_toggleoffline', 'plugin', 'toggleoffline', 'job', 0, 1, 1, 0, 0, '', '{}', '', 15, 0); +(0, 'plg_task_requests', 'plugin', 'requests', 'job', 0, 1, 1, 0, 0, '', '{}', '', 15, 0), +(0, 'plg_task_toggleoffline', 'plugin', 'toggleoffline', 'job', 0, 1, 1, 0, 0, '', '{}', '', 15, 0); -- Templates INSERT INTO "#__extensions" ("package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "locked", "manifest_cache", "params", "custom_data", "ordering", "state") VALUES diff --git a/plugins/task/requests/forms/get_requests.xml b/plugins/task/requests/forms/get_requests.xml index fae4546cb1b8a..28b0d096c4286 100644 --- a/plugins/task/requests/forms/get_requests.xml +++ b/plugins/task/requests/forms/get_requests.xml @@ -5,7 +5,7 @@ - - + +
diff --git a/plugins/task/requests/language/en-GB/en-GB.plg_job_requests.ini b/plugins/task/requests/language/en-GB/en-GB.plg_job_requests.ini index 8d4b2ad0a7d69..8965b16e8623a 100644 --- a/plugins/task/requests/language/en-GB/en-GB.plg_job_requests.ini +++ b/plugins/task/requests/language/en-GB/en-GB.plg_job_requests.ini @@ -2,16 +2,16 @@ ; (C) 2021 Open Source Matters, Inc. ; GNU General Public License version 2 or later; see LICENSE.txt -PLG_JOB_REQUESTS="Job - Requests" -PLG_JOB_REQUESTS_BEARER="Bearer" -PLG_JOB_REQUESTS_JOB_GET_REQUEST_DESC="Make GET requests to a server. Supports a custom timeout and authorization headers." -PLG_JOB_REQUESTS_JOB_GET_REQUEST_TASK_LOG_MESSAGE="Job> GET return code is: %1$d. Processing Time: %2$.2f seconds" -PLG_JOB_REQUESTS_JOB_GET_REQUEST_LOG_RESPONSE="Request response code was: %1$d" -PLG_JOB_REQUESTS_JOB_GET_REQUEST_TITLE="GET Requests" -PLG_JOB_REQUESTS_JOOMLA_TOKEN="X-Joomla-Token" -PLG_JOB_REQUESTS_LABEL_AUTH="Authorization" -PLG_JOB_REQUESTS_LABEL_AUTH_HEADER="Authorization Header" -PLG_JOB_REQUESTS_LABEL_AUTH_KEY="Authorization Key" -PLG_JOB_REQUESTS_LABEL_REQUEST_TIMEOUT="Request Timeout" -PLG_JOB_REQUESTS_LABEL_REQUEST_URL="Request URL" -PLG_JOB_REQUESTS_XML_DESCRIPTION="Job plugin to make GET requests to a server." +PLG_TASK_REQUESTS="Task - Requests" +PLG_TASK_REQUESTS_BEARER="Bearer" +PLG_TASK_REQUESTS_TASK_GET_REQUEST_DESC="Make GET requests to a server. Supports a custom timeout and authorization headers." +PLG_TASK_REQUESTS_TASK_GET_REQUEST_TASK_LOG_MESSAGE="Job> GET return code is: %1$d. Processing Time: %2$.2f seconds" +PLG_TASK_REQUESTS_TASK_GET_REQUEST_LOG_RESPONSE="Request response code was: %1$d" +PLG_TASK_REQUESTS_TASK_GET_REQUEST_TITLE="GET Requests" +PLG_TASK_REQUESTS_JOOMLA_TOKEN="X-Joomla-Token" +PLG_TASK_REQUESTS_LABEL_AUTH="Authorization" +PLG_TASK_REQUESTS_LABEL_AUTH_HEADER="Authorization Header" +PLG_TASK_REQUESTS_LABEL_AUTH_KEY="Authorization Key" +PLG_TASK_REQUESTS_LABEL_REQUEST_TIMEOUT="Request Timeout" +PLG_TASK_REQUESTS_LABEL_REQUEST_URL="Request URL" +PLG_TASK_REQUESTS_XML_DESCRIPTION="Job plugin to make GET requests to a server." diff --git a/plugins/task/requests/language/en-GB/en-GB.plg_job_requests.sys.ini b/plugins/task/requests/language/en-GB/en-GB.plg_job_requests.sys.ini index 534119fc88b31..fafbc7a2445ed 100644 --- a/plugins/task/requests/language/en-GB/en-GB.plg_job_requests.sys.ini +++ b/plugins/task/requests/language/en-GB/en-GB.plg_job_requests.sys.ini @@ -2,5 +2,5 @@ ; (C) 2021 Open Source Matters, Inc. ; GNU General Public License version 2 or later; see LICENSE.txt -PLG_JOB_REQUESTS="Job - Requests" -PLG_JOB_REQUESTS_XML_DESCRIPTION="Job plugin to make GET requests to a server." +PLG_TASK_REQUESTS="Task - Requests" +PLG_TASK_REQUESTS_XML_DESCRIPTION="Job plugin to make GET requests to a server." diff --git a/plugins/task/requests/requests.php b/plugins/task/requests/requests.php index e96157b9d8888..c138e600f7460 100644 --- a/plugins/task/requests/requests.php +++ b/plugins/task/requests/requests.php @@ -1,9 +1,9 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt @@ -27,7 +27,7 @@ * * @since __DEPLOY_VERSION__ */ -class PlgJobRequests extends CMSPlugin implements SubscriberInterface +class PlgTaskRequests extends CMSPlugin implements SubscriberInterface { use TaskPluginTrait; @@ -36,8 +36,8 @@ class PlgJobRequests extends CMSPlugin implements SubscriberInterface * @since __DEPLOY_VERSION__ */ protected const TASKS_MAP = [ - 'plg_job_requests_job_get' => [ - 'langConstPrefix' => 'PLG_JOB_REQUESTS_JOB_GET_REQUEST', + 'plg_task_requests_task_get' => [ + 'langConstPrefix' => 'PLG_TASK_REQUESTS_TASK_GET_REQUEST', 'form' => 'get_requests', 'call' => 'makeGetRequest' ] @@ -58,7 +58,7 @@ class PlgJobRequests extends CMSPlugin implements SubscriberInterface * @since __DEPLOY_VERSION__ */ private $supportedFormContexts = [ - 'com_scheduler.cronjob' + 'com_scheduler.task' ]; /** @@ -71,7 +71,7 @@ class PlgJobRequests extends CMSPlugin implements SubscriberInterface public static function getSubscribedEvents(): array { return [ - 'onCronOptionsList' => 'advertiseJobs', + 'onCronOptionsList' => 'advertiseRoutines', 'onCronRun' => 'makeRequest', 'onContentPrepareForm' => 'enhanceForm' ]; @@ -113,7 +113,7 @@ public function enhanceForm(Event $event): void $context = $form->getName(); - if ($context === 'com_scheduler.cronjob') + if ($context === 'com_scheduler.task') { $this->enhanceTaskItemForm($form, $data); } @@ -156,7 +156,7 @@ protected function makeGetRequest(CronRunEvent $event): int } $responseCode = $response->code; - $this->addTaskLog(Text::sprintf('PLG_JOB_REQUESTS_JOB_GET_REQUEST_LOG_RESPONSE', $responseCode)); + $this->addTaskLog(Text::sprintf('PLG_TASK_REQUESTS_TASK_GET_REQUEST_LOG_RESPONSE', $responseCode)); if ($response->code !== 200) { diff --git a/plugins/task/requests/requests.xml b/plugins/task/requests/requests.xml index 9c6251f3924a8..43b81dea5f7c6 100644 --- a/plugins/task/requests/requests.xml +++ b/plugins/task/requests/requests.xml @@ -1,18 +1,18 @@ - + Requests Joomla! Projects August 2021 GNU General Public License version 2 or later; see LICENSE.txt 4.1 - PLG_JOB_REQUESTS_XML_DESCRIPTION + PLG_TASK_REQUESTS_XML_DESCRIPTION requests.php language forms - en-GB.plg_job_requests.ini - en-GB.plg_job_requests.sys.ini + en-GB.plg_task_requests.ini + en-GB.plg_task_requests.sys.ini diff --git a/plugins/task/testjob/forms/testJobForm.xml b/plugins/task/testjob/forms/testJobForm.xml index c31b3a8c4752e..753280023bb23 100644 --- a/plugins/task/testjob/forms/testJobForm.xml +++ b/plugins/task/testjob/forms/testJobForm.xml @@ -5,7 +5,7 @@ diff --git a/plugins/task/testjob/language/en-GB/en-GB.plg_job_testjob.ini b/plugins/task/testjob/language/en-GB/en-GB.plg_job_testjob.ini index 32c7cab014e6b..987f6ad91f04d 100644 --- a/plugins/task/testjob/language/en-GB/en-GB.plg_job_testjob.ini +++ b/plugins/task/testjob/language/en-GB/en-GB.plg_job_testjob.ini @@ -2,12 +2,12 @@ ; (C) 2021 Open Source Matters, Inc. ; GNU General Public License version 2 or later; see LICENSE.txt -PLG_JOB_TESTJOB="Job - Test Plugin" -PLG_JOB_TESTJOB_JOB1_DESC="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor." -PLG_JOB_TESTJOB_JOB1_TASK_LOG_MESSAGE="Job> TestJob1 return code is: %1$d. Processing Time: %2$.2f seconds" -PLG_JOB_TESTJOB_JOB1_TITLE="First Test Job" -PLG_JOB_TESTJOB_JOB2_DESC="Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium." -PLG_JOB_TESTJOB_JOB2_TASK_LOG_MESSAGE="Job> TestJob2 return code is: %1$d. Processing Time: %2$.2f seconds" -PLG_JOB_TESTJOB_JOB2_TITLE="Second Test Job" -PLG_JOB_TESTJOB_LABEL_SAMPLE_FIELD="Sample Field" -PLG_JOB_TESTJOB_XML_DESCRIPTION="This is a test plugin for the development of Joomla! Cronjobs" +PLG_TASK_TESTTASKS="Task - Test Tasks!" +PLG_TASK_TESTTASKS_TASK_1_DESC="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor." +PLG_TASK_TESTTASKS_TASK_1_TASK_LOG_MESSAGE="Task> TestTask1 return code is: %1$d. Processing Time: %2$.2f seconds" +PLG_TASK_TESTTASKS_TASK_1_TITLE="First Test Task" +PLG_TASK_TESTTASKS_TASK_2_DESC="Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium." +PLG_TASK_TESTTASKS_TASK_2_TASK_LOG_MESSAGE="Task> TestTask2 return code is: %1$d. Processing Time: %2$.2f seconds" +PLG_TASK_TESTTASKS_TASK_2_TITLE="Second Test Task" +PLG_TASK_TESTTASKS_LABEL_SAMPLE_FIELD="Sample Field" +PLG_TASK_TESTTASKS_XML_DESCRIPTION="This is a test plugin for the development of Joomla! CronTasks" diff --git a/plugins/task/testjob/language/en-GB/en-GB.plg_job_testjob.sys.ini b/plugins/task/testjob/language/en-GB/en-GB.plg_job_testjob.sys.ini index af937797b311a..4b6bbc52e9e8b 100644 --- a/plugins/task/testjob/language/en-GB/en-GB.plg_job_testjob.sys.ini +++ b/plugins/task/testjob/language/en-GB/en-GB.plg_job_testjob.sys.ini @@ -2,5 +2,5 @@ ; (C) 2021 Open Source Matters, Inc. ; GNU General Public License version 2 or later; see LICENSE.txt -PLG_JOB_TESTJOB="Job - Test Plugin" -PLG_JOB_TESTJOB_XML_DESCRIPTION="This is a test plugin for the development of Joomla! Cronjobs" +PLG_TASK_TESTTASKS="Task - Test Tasks!" +PLG_TASK_TESTTASKS_XML_DESCRIPTION="This is a test plugin for the development of Joomla! Cronjobs" diff --git a/plugins/task/testjob/testjob.php b/plugins/task/testjob/testjob.php index ebcf49d567762..ccfcf003626db 100644 --- a/plugins/task/testjob/testjob.php +++ b/plugins/task/testjob/testjob.php @@ -3,7 +3,7 @@ * A test plugin for com_scheduler. * * @package Joomla.Plugins - * @subpackage System.TestJob + * @subpackage Task.Testtasks * * @copyright (C) 2021 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt @@ -24,7 +24,7 @@ * * @since __DEPLOY__VERSION__ */ -class PlgJobTestjob extends CMSPlugin implements SubscriberInterface +class PlgTaskTesttasks extends CMSPlugin implements SubscriberInterface { use TaskPluginTrait; @@ -33,13 +33,13 @@ class PlgJobTestjob extends CMSPlugin implements SubscriberInterface * @since __DEPLOY_VERSION__ */ private const TASKS_MAP = [ - 'job1' => [ - 'langConstPrefix' => 'PLG_JOB_TESTJOB_JOB1', - 'form' => 'testJobForm' + 'routine_1' => [ + 'langConstPrefix' => 'PLG_TASK_TESTTASKS_TASK_1', + 'form' => 'testTaskForm' ], - 'job2' => [ - 'langConstPrefix' => 'PLG_JOB_TESTJOB_JOB2', - 'form' => 'testJobForm' + 'routine_2' => [ + 'langConstPrefix' => 'PLG_TASK_TESTTASKS_TASK_2', + 'form' => 'testTaskForm' ] ]; @@ -58,7 +58,7 @@ class PlgJobTestjob extends CMSPlugin implements SubscriberInterface * @since __DEPLOY_VERSION__ */ private $supportedFormContexts = [ - 'com_scheduler.cronjob' + 'com_scheduler.task' ]; /** @@ -71,7 +71,7 @@ class PlgJobTestjob extends CMSPlugin implements SubscriberInterface public static function getSubscribedEvents(): array { return [ - 'onCronOptionsList' => 'advertiseJobs', + 'onCronOptionsList' => 'advertiseRoutines', 'onCronRun' => 'cronSampleRoutine', 'onContentPrepareForm' => 'manipulateForms' ]; @@ -80,10 +80,10 @@ public static function getSubscribedEvents(): array /** * @param CronRunEvent $event onCronRun Event * - * @return void + * @return void * - * @throws Exception - * @since __DEPLOY_VERSION + * @throws Exception + * @since __DEPLOY_VERSION */ public function cronSampleRoutine(CronRunEvent $event): void { @@ -91,7 +91,7 @@ public function cronSampleRoutine(CronRunEvent $event): void { $this->taskStart(); - // Access to job parameters + // Access to task parameters $params = $event->getArgument('params'); // Plugin does whatever it wants @@ -106,10 +106,10 @@ public function cronSampleRoutine(CronRunEvent $event): void /** * @param Event $event The onContentPrepareForm event. * - * @return void + * @return void * - * @throws Exception - * @since __DEPLOY_VERSION__ + * @throws Exception + * @since __DEPLOY_VERSION__ */ public function manipulateForms(Event $event): void { @@ -119,7 +119,7 @@ public function manipulateForms(Event $event): void $context = $form->getName(); - if ($context === 'com_scheduler.cronjob') + if ($context === 'com_scheduler.task') { $this->enhanceTaskItemForm($form, $data); } diff --git a/plugins/task/testjob/testjob.xml b/plugins/task/testjob/testjob.xml index f6a74a0bc8756..6acedbb1318af 100644 --- a/plugins/task/testjob/testjob.xml +++ b/plugins/task/testjob/testjob.xml @@ -1,16 +1,16 @@ - - Test Job! + + Test Tasks! Joomla! Projects July 2021 GNU General Public License version 2 or later; see LICENSE.txt 4.1 - Test jobs for com_scheduler + Test task routines for com_scheduler - testjob.php + testtasks.php - en-GB.plg_job_testjob.ini - en-GB.plg_job_testjob.sys.ini + en-GB.plg_task_testtasks.ini + en-GB.plg_task_testtasks.sys.ini diff --git a/plugins/task/toggleoffline/language/en-GB/en-GB.plg_job_toggleoffline.ini b/plugins/task/toggleoffline/language/en-GB/en-GB.plg_job_toggleoffline.ini index 392099b72c9a2..1d9be104e0476 100644 --- a/plugins/task/toggleoffline/language/en-GB/en-GB.plg_job_toggleoffline.ini +++ b/plugins/task/toggleoffline/language/en-GB/en-GB.plg_job_toggleoffline.ini @@ -2,18 +2,18 @@ ; (C) 2021 Open Source Matters, Inc. ; GNU General Public License version 2 or later; see LICENSE.txt -PLG_JOB_TOGGLE_OFFLINE="Job - Toggle Offline" -PLG_JOB_TOGGLE_OFFLINE_DESC="Toggles the site's status on each run." -PLG_JOB_TOGGLE_OFFLINE_ERROR_CONFIGURATION_PHP_NOTUNWRITABLE="Could not make configuration.php un-writable." -PLG_JOB_TOGGLE_OFFLINE_ERROR_CONFIGURATION_PHP_NOTWRITABLE="Could not make configuration.php writable." -PLG_JOB_TOGGLE_OFFLINE_ERROR_WRITE_FAILED="Could not write to the configuration file!" -PLG_JOB_TOGGLE_OFFLINE_TASK_LOG_MESSAGE="Job> ToggleOffline return code is: %1$d. Processing Time: %2$.2f seconds." -PLG_JOB_TOGGLE_OFFLINE_JOB_LOG_SITE_STATUS="Site was %1$s, is now %2$s." -PLG_JOB_TOGGLE_OFFLINE_SET_OFFLINE_DESC="Sets site offline to online on each run." -PLG_JOB_TOGGLE_OFFLINE_SET_OFFLINE_TASK_LOG_MESSAGE="Job> SetOffline return code is: %1$d. Processing Time: %2$.2f seconds." -PLG_JOB_TOGGLE_OFFLINE_SET_OFFLINE_TITLE="Get Site Offline." -PLG_JOB_TOGGLE_OFFLINE_SET_ONLINE_DESC="Sets site status to online on each run." -PLG_JOB_TOGGLE_OFFLINE_SET_ONLINE_TASK_LOG_MESSAGE="Job> SetOnline return code is: %1$d. Processing Time: %2$.2f seconds." -PLG_JOB_TOGGLE_OFFLINE_SET_ONLINE_TITLE="Get Site Online." -PLG_JOB_TOGGLE_OFFLINE_TITLE="Toggle Offline." -PLG_JOB_TOGGLE_OFFLINE_XML_DESCRIPTION="Toggles the site's offline status on each run." +PLG_TASK_TOGGLE_OFFLINE="Task - Toggle Offline" +PLG_TASK_TOGGLE_OFFLINE_DESC="Toggles the site's status on each run." +PLG_TASK_TOGGLE_OFFLINE_ERROR_CONFIGURATION_PHP_NOTUNWRITABLE="Could not make configuration.php un-writable." +PLG_TASK_TOGGLE_OFFLINE_ERROR_CONFIGURATION_PHP_NOTWRITABLE="Could not make configuration.php writable." +PLG_TASK_TOGGLE_OFFLINE_ERROR_WRITE_FAILED="Could not write to the configuration file!" +PLG_TASK_TOGGLE_OFFLINE_TASK_LOG_MESSAGE="Job> ToggleOffline return code is: %1$d. Processing Time: %2$.2f seconds." +PLG_TASK_TOGGLE_OFFLINE_TASK_LOG_SITE_STATUS="Site was %1$s, is now %2$s." +PLG_TASK_TOGGLE_OFFLINE_SET_OFFLINE_DESC="Sets site offline to online on each run." +PLG_TASK_TOGGLE_OFFLINE_SET_OFFLINE_TASK_LOG_MESSAGE="Job> SetOffline return code is: %1$d. Processing Time: %2$.2f seconds." +PLG_TASK_TOGGLE_OFFLINE_SET_OFFLINE_TITLE="Get Site Offline." +PLG_TASK_TOGGLE_OFFLINE_SET_ONLINE_DESC="Sets site status to online on each run." +PLG_TASK_TOGGLE_OFFLINE_SET_ONLINE_TASK_LOG_MESSAGE="Job> SetOnline return code is: %1$d. Processing Time: %2$.2f seconds." +PLG_TASK_TOGGLE_OFFLINE_SET_ONLINE_TITLE="Get Site Online." +PLG_TASK_TOGGLE_OFFLINE_TITLE="Toggle Offline." +PLG_TASK_TOGGLE_OFFLINE_XML_DESCRIPTION="Toggles the site's offline status on each run." diff --git a/plugins/task/toggleoffline/language/en-GB/en-GB.plg_job_toggleoffline.sys.ini b/plugins/task/toggleoffline/language/en-GB/en-GB.plg_job_toggleoffline.sys.ini index 1f8d5877edeb6..cec2b2d7b19ec 100644 --- a/plugins/task/toggleoffline/language/en-GB/en-GB.plg_job_toggleoffline.sys.ini +++ b/plugins/task/toggleoffline/language/en-GB/en-GB.plg_job_toggleoffline.sys.ini @@ -2,5 +2,5 @@ ; (C) 2021 Open Source Matters, Inc. ; GNU General Public License version 2 or later; see LICENSE.txt -PLG_JOB_TOGGLE_OFFLINE="Job - Toggle Offline" -PLG_JOB_TOGGLE_OFFLINE_XML_DESCRIPTION="Toggles the site's offline status on each run" +PLG_TASK_TOGGLE_OFFLINE="Task - Toggle Offline" +PLG_TASK_TOGGLE_OFFLINE_XML_DESCRIPTION="Toggles the site's offline status on each run" diff --git a/plugins/task/toggleoffline/toggleoffline.php b/plugins/task/toggleoffline/toggleoffline.php index b81be666bff55..3ffaa4d3b398c 100644 --- a/plugins/task/toggleoffline/toggleoffline.php +++ b/plugins/task/toggleoffline/toggleoffline.php @@ -1,9 +1,9 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt @@ -28,7 +28,7 @@ * * @since __DEPLOY_VERSION__ */ -class PlgJobToggleoffline extends CMSPlugin implements SubscriberInterface +class PlgTaskToggleoffline extends CMSPlugin implements SubscriberInterface { use TaskPluginTrait; @@ -37,17 +37,17 @@ class PlgJobToggleoffline extends CMSPlugin implements SubscriberInterface * @since __DEPLOY_VERSION__ */ protected const TASKS_MAP = [ - 'plg_job_toggle_offline' => [ - 'langConstPrefix' => 'PLG_JOB_TOGGLE_OFFLINE', + 'plg_task_toggle_offline' => [ + 'langConstPrefix' => 'PLG_TASK_TOGGLE_OFFLINE', 'toggle' => true ], - 'plg_job_toggle_offline_set_online' => [ - 'langConstPrefix' => 'PLG_JOB_TOGGLE_OFFLINE_SET_ONLINE', + 'plg_task_toggle_offline_set_online' => [ + 'langConstPrefix' => 'PLG_TASK_TOGGLE_OFFLINE_SET_ONLINE', 'toggle' => false, 'offline' => false ], - 'plg_job_toggle_offline_set_offline' => [ - 'langConstPrefix' => 'PLG_JOB_TOGGLE_OFFLINE_SET_OFFLINE', + 'plg_task_toggle_offline_set_offline' => [ + 'langConstPrefix' => 'PLG_TASK_TOGGLE_OFFLINE_SET_OFFLINE', 'toggle' => false, 'offline' => true ], @@ -77,7 +77,7 @@ class PlgJobToggleoffline extends CMSPlugin implements SubscriberInterface * @since __DEPLOY_VERSION__ */ private $supportedFormContexts = [ - 'com_scheduler.cronjob' + 'com_scheduler.task' ]; /** @@ -90,7 +90,7 @@ class PlgJobToggleoffline extends CMSPlugin implements SubscriberInterface public static function getSubscribedEvents(): array { return [ - 'onCronOptionsList' => 'advertiseJobs', + 'onCronOptionsList' => 'advertiseRoutines', 'onCronRun' => 'toggleOffline', ]; } @@ -128,7 +128,7 @@ public function toggleOffline(CronRunEvent $event): void $newStatus = $config['offline'] ? 'offline' : 'online'; $exit = $this->writeConfigFile(new Registry($config)); - $this->addTaskLog(Text::sprintf('PLG_JOB_TOGGLE_OFFLINE_JOB_LOG_SITE_STATUS', $oldStatus, $newStatus)); + $this->addTaskLog(Text::sprintf('PLG_TASK_TOGGLE_OFFLINE_TASK_LOG_SITE_STATUS', $oldStatus, $newStatus)); $this->taskEnd($event, $exit); } @@ -138,7 +138,7 @@ public function toggleOffline(CronRunEvent $event): void * * @param Registry $config A Registry object containing all global config data. * - * @return integer The job exit code + * @return integer The task exit code * * @throws Exception * @since __DEPLOY_VERSION__ @@ -151,7 +151,7 @@ private function writeConfigFile(Registry $config): int // Attempt to make the file writeable. if (Path::isOwner($file) && !Path::setPermissions($file)) { - $this->addTaskLog(Text::_('PLG_JOB_TOGGLE_OFFLINE_ERROR_CONFIGURATION_PHP_NOTWRITABLE'), 'notice'); + $this->addTaskLog(Text::_('PLG_TASK_TOGGLE_OFFLINE_ERROR_CONFIGURATION_PHP_NOTWRITABLE'), 'notice'); } // Attempt to write the configuration file as a PHP class named JConfig. @@ -159,7 +159,7 @@ private function writeConfigFile(Registry $config): int if (!File::write($file, $configuration)) { - $this->addTaskLog(Text::_('PLG_JOB_TOGGLE_OFFLINE_ERROR_WRITE_FAILED'), 'error'); + $this->addTaskLog(Text::_('PLG_TASK_TOGGLE_OFFLINE_ERROR_WRITE_FAILED'), 'error'); return self::$STATUS['KO_RUN']; } @@ -173,7 +173,7 @@ private function writeConfigFile(Registry $config): int // Attempt to make the file un-writeable. if (Path::isOwner($file) && !Path::setPermissions($file, '0444')) { - $this->addTaskLog(Text::_('PLG_JOB_TOGGLE_OFFLINE_ERROR_CONFIGURATION_PHP_NOTUNWRITABLE'), 'notice'); + $this->addTaskLog(Text::_('PLG_TASK_TOGGLE_OFFLINE_ERROR_CONFIGURATION_PHP_NOTUNWRITABLE'), 'notice'); } return self::$STATUS['OK_RUN']; diff --git a/plugins/task/toggleoffline/toggleoffline.xml b/plugins/task/toggleoffline/toggleoffline.xml index 911efa7b5e1eb..2cfd2d1257646 100644 --- a/plugins/task/toggleoffline/toggleoffline.xml +++ b/plugins/task/toggleoffline/toggleoffline.xml @@ -1,16 +1,16 @@ - - PLG_JOB_TOGGLE_OFFLINE + + PLG_TASK_TOGGLE_OFFLINE Joomla! Projects August 2021 GNU General Public License version 2 or later; see LICENSE.txt 4.1 - PLG_JOB_TOGGLE_OFFLINE_XML_DESCRIPTION + PLG_TASK_TOGGLE_OFFLINE_XML_DESCRIPTION toggleoffline.php - en-GB.plg_job_toggleoffline.ini - en-GB.plg_job_toggleoffline.sys.ini + en-GB.plg_task_toggleoffline.ini + en-GB.plg_task_toggleoffline.sys.ini From 5a5ed661a436e7454df5f3c9c7c726ae1fbdfcc7 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 22 Aug 2021 04:29:10 +0530 Subject: [PATCH 317/615] Refactor com_cronjobs [13] - Renames plg system `cronjobs` => `schedulerunner` (files, dir). - Renames plg `testjob` => `testtasks` (files, dir). - Updates task plugin language files filenames. --- .../language/en-GB/en-GB.plg_system.schedulerunner.sys.ini} | 0 .../language/en-GB/en-GB.plg_system_schedulerunner.ini} | 0 .../{cronjobs/cronjobs.php => schedulerunner/schedulerunner.php} | 0 .../{cronjobs/cronjobs.xml => schedulerunner/schedulerunner.xml} | 0 .../{en-GB.plg_job_requests.ini => en-GB.plg_task_requests.ini} | 0 ...B.plg_job_requests.sys.ini => en-GB.plg_task_requests.sys.ini} | 0 .../forms/testJobForm.xml => testtasks/forms/testTaskForm.xml} | 0 .../language/en-GB/en-GB.plg_task_testtasks.ini} | 0 .../language/en-GB/en-GB.plg_task_testtasks.sys.ini} | 0 plugins/task/{testjob/testjob.php => testtasks/testtasks.php} | 0 plugins/task/{testjob/testjob.xml => testtasks/testtasks.xml} | 0 ...plg_job_toggleoffline.ini => en-GB.plg_task_toggleoffline.ini} | 0 ...toggleoffline.sys.ini => en-GB.plg_task_toggleoffline.sys.ini} | 0 13 files changed, 0 insertions(+), 0 deletions(-) rename plugins/system/{cronjobs/language/en-GB/en-GB.plg_system.cronjobs.sys.ini => schedulerunner/language/en-GB/en-GB.plg_system.schedulerunner.sys.ini} (100%) rename plugins/system/{cronjobs/language/en-GB/en-GB.plg_system_cronjobs.ini => schedulerunner/language/en-GB/en-GB.plg_system_schedulerunner.ini} (100%) rename plugins/system/{cronjobs/cronjobs.php => schedulerunner/schedulerunner.php} (100%) rename plugins/system/{cronjobs/cronjobs.xml => schedulerunner/schedulerunner.xml} (100%) rename plugins/task/requests/language/en-GB/{en-GB.plg_job_requests.ini => en-GB.plg_task_requests.ini} (100%) rename plugins/task/requests/language/en-GB/{en-GB.plg_job_requests.sys.ini => en-GB.plg_task_requests.sys.ini} (100%) rename plugins/task/{testjob/forms/testJobForm.xml => testtasks/forms/testTaskForm.xml} (100%) rename plugins/task/{testjob/language/en-GB/en-GB.plg_job_testjob.ini => testtasks/language/en-GB/en-GB.plg_task_testtasks.ini} (100%) rename plugins/task/{testjob/language/en-GB/en-GB.plg_job_testjob.sys.ini => testtasks/language/en-GB/en-GB.plg_task_testtasks.sys.ini} (100%) rename plugins/task/{testjob/testjob.php => testtasks/testtasks.php} (100%) rename plugins/task/{testjob/testjob.xml => testtasks/testtasks.xml} (100%) rename plugins/task/toggleoffline/language/en-GB/{en-GB.plg_job_toggleoffline.ini => en-GB.plg_task_toggleoffline.ini} (100%) rename plugins/task/toggleoffline/language/en-GB/{en-GB.plg_job_toggleoffline.sys.ini => en-GB.plg_task_toggleoffline.sys.ini} (100%) diff --git a/plugins/system/cronjobs/language/en-GB/en-GB.plg_system.cronjobs.sys.ini b/plugins/system/schedulerunner/language/en-GB/en-GB.plg_system.schedulerunner.sys.ini similarity index 100% rename from plugins/system/cronjobs/language/en-GB/en-GB.plg_system.cronjobs.sys.ini rename to plugins/system/schedulerunner/language/en-GB/en-GB.plg_system.schedulerunner.sys.ini diff --git a/plugins/system/cronjobs/language/en-GB/en-GB.plg_system_cronjobs.ini b/plugins/system/schedulerunner/language/en-GB/en-GB.plg_system_schedulerunner.ini similarity index 100% rename from plugins/system/cronjobs/language/en-GB/en-GB.plg_system_cronjobs.ini rename to plugins/system/schedulerunner/language/en-GB/en-GB.plg_system_schedulerunner.ini diff --git a/plugins/system/cronjobs/cronjobs.php b/plugins/system/schedulerunner/schedulerunner.php similarity index 100% rename from plugins/system/cronjobs/cronjobs.php rename to plugins/system/schedulerunner/schedulerunner.php diff --git a/plugins/system/cronjobs/cronjobs.xml b/plugins/system/schedulerunner/schedulerunner.xml similarity index 100% rename from plugins/system/cronjobs/cronjobs.xml rename to plugins/system/schedulerunner/schedulerunner.xml diff --git a/plugins/task/requests/language/en-GB/en-GB.plg_job_requests.ini b/plugins/task/requests/language/en-GB/en-GB.plg_task_requests.ini similarity index 100% rename from plugins/task/requests/language/en-GB/en-GB.plg_job_requests.ini rename to plugins/task/requests/language/en-GB/en-GB.plg_task_requests.ini diff --git a/plugins/task/requests/language/en-GB/en-GB.plg_job_requests.sys.ini b/plugins/task/requests/language/en-GB/en-GB.plg_task_requests.sys.ini similarity index 100% rename from plugins/task/requests/language/en-GB/en-GB.plg_job_requests.sys.ini rename to plugins/task/requests/language/en-GB/en-GB.plg_task_requests.sys.ini diff --git a/plugins/task/testjob/forms/testJobForm.xml b/plugins/task/testtasks/forms/testTaskForm.xml similarity index 100% rename from plugins/task/testjob/forms/testJobForm.xml rename to plugins/task/testtasks/forms/testTaskForm.xml diff --git a/plugins/task/testjob/language/en-GB/en-GB.plg_job_testjob.ini b/plugins/task/testtasks/language/en-GB/en-GB.plg_task_testtasks.ini similarity index 100% rename from plugins/task/testjob/language/en-GB/en-GB.plg_job_testjob.ini rename to plugins/task/testtasks/language/en-GB/en-GB.plg_task_testtasks.ini diff --git a/plugins/task/testjob/language/en-GB/en-GB.plg_job_testjob.sys.ini b/plugins/task/testtasks/language/en-GB/en-GB.plg_task_testtasks.sys.ini similarity index 100% rename from plugins/task/testjob/language/en-GB/en-GB.plg_job_testjob.sys.ini rename to plugins/task/testtasks/language/en-GB/en-GB.plg_task_testtasks.sys.ini diff --git a/plugins/task/testjob/testjob.php b/plugins/task/testtasks/testtasks.php similarity index 100% rename from plugins/task/testjob/testjob.php rename to plugins/task/testtasks/testtasks.php diff --git a/plugins/task/testjob/testjob.xml b/plugins/task/testtasks/testtasks.xml similarity index 100% rename from plugins/task/testjob/testjob.xml rename to plugins/task/testtasks/testtasks.xml diff --git a/plugins/task/toggleoffline/language/en-GB/en-GB.plg_job_toggleoffline.ini b/plugins/task/toggleoffline/language/en-GB/en-GB.plg_task_toggleoffline.ini similarity index 100% rename from plugins/task/toggleoffline/language/en-GB/en-GB.plg_job_toggleoffline.ini rename to plugins/task/toggleoffline/language/en-GB/en-GB.plg_task_toggleoffline.ini diff --git a/plugins/task/toggleoffline/language/en-GB/en-GB.plg_job_toggleoffline.sys.ini b/plugins/task/toggleoffline/language/en-GB/en-GB.plg_task_toggleoffline.sys.ini similarity index 100% rename from plugins/task/toggleoffline/language/en-GB/en-GB.plg_job_toggleoffline.sys.ini rename to plugins/task/toggleoffline/language/en-GB/en-GB.plg_task_toggleoffline.sys.ini From 679deb79ddb9cad73e99f49e0a135395ada508ee Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 22 Aug 2021 04:53:00 +0530 Subject: [PATCH 318/615] Refactor com_cronjobs [14] - Refactors plugin `cronjobs` => `schedulerunner`. --- .../en-GB.plg_system.schedulerunner.sys.ini | 4 +- .../en-GB/en-GB.plg_system_schedulerunner.ini | 12 +- .../system/schedulerunner/schedulerunner.php | 142 +++++++++--------- .../system/schedulerunner/schedulerunner.xml | 10 +- 4 files changed, 84 insertions(+), 84 deletions(-) diff --git a/plugins/system/schedulerunner/language/en-GB/en-GB.plg_system.schedulerunner.sys.ini b/plugins/system/schedulerunner/language/en-GB/en-GB.plg_system.schedulerunner.sys.ini index 6959d041efe4b..741c749eaa113 100644 --- a/plugins/system/schedulerunner/language/en-GB/en-GB.plg_system.schedulerunner.sys.ini +++ b/plugins/system/schedulerunner/language/en-GB/en-GB.plg_system.schedulerunner.sys.ini @@ -2,5 +2,5 @@ ; (C) 2021 Open Source Matters, Inc. ; GNU General Public License version 2 or later; see LICENSE.txt -PLG_SYSTEM_CRONJOBS="System - Cronjobs Scheduler" -PLG_SYSTEM_CRONJOBS_XML_DESCRIPTION="This plugin lazy runs due cronjobs managed through >." +PLG_SYSTEM_SCHEDULE_RUNNER="System - Schedule Runner" +PLG_SYSTEM_SCHEDULE_RUNNER_XML_DESCRIPTION="This plugin lazily runs due tasks, managed through com_scheduler" diff --git a/plugins/system/schedulerunner/language/en-GB/en-GB.plg_system_schedulerunner.ini b/plugins/system/schedulerunner/language/en-GB/en-GB.plg_system_schedulerunner.ini index cf578efb43528..b9b4659b288b3 100644 --- a/plugins/system/schedulerunner/language/en-GB/en-GB.plg_system_schedulerunner.ini +++ b/plugins/system/schedulerunner/language/en-GB/en-GB.plg_system_schedulerunner.ini @@ -2,10 +2,10 @@ ; (C) 2021 Open Source Matters, Inc. ; GNU General Public License version 2 or later; see LICENSE.txt -PLG_SYSTEM_CRONJOBS="System - Cronjobs Scheduler" -PLG_SYSTEM_CRONJOBS_LOCKED="Job#%02d is locked." -PLG_SYSTEM_CRONJOBS_RUN_COMPLETE="Finished job#%02d in %.2f seconds with exit code %d." -PLG_SYSTEM_CRONJOBS_START="Running job#%02d '%s'." +PLG_SYSTEM_SCHEDULE_RUNNER="System - Schedule Runner" +PLG_SYSTEM_SCHEDULE_RUNNER_LOCKED="task#%02d is locked." +PLG_SYSTEM_SCHEDULE_RUNNER_RUN_COMPLETE="Finished task#%02d in %.2f seconds with exit code %d." +PLG_SYSTEM_SCHEDULE_RUNNER_START="Running task#%02d '%s'." ; Maybe not this -PLG_SYSTEM_CRONJOBS_UNLOCKED="Job#%02d was unlocked." -PLG_SYSTEM_CRONJOBS_XML_DESCRIPTION="This plugin lazy runs due cronjobs managed through >." +PLG_SYSTEM_SCHEDULE_RUNNER_UNLOCKED="Task#%02d was unlocked." +PLG_SYSTEM_SCHEDULE_RUNNER_XML_DESCRIPTION="This plugin lazily runs due tasks, managed through com_scheduler" diff --git a/plugins/system/schedulerunner/schedulerunner.php b/plugins/system/schedulerunner/schedulerunner.php index 6cfb18e168fc5..34dd728be1044 100644 --- a/plugins/system/schedulerunner/schedulerunner.php +++ b/plugins/system/schedulerunner/schedulerunner.php @@ -1,7 +1,7 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt @@ -29,11 +29,11 @@ use Joomla\Event\SubscriberInterface; /** - * The plugin class for Plg_System_Cronjobs. + * The plugin class for Plg_System_Schedulerunner. * * @since __DEPLOY_VERSION__ */ -class PlgSystemCronjobs extends CMSPlugin implements SubscriberInterface +class PlgSystemSchedulerunner extends CMSPlugin implements SubscriberInterface { /** @@ -41,36 +41,36 @@ class PlgSystemCronjobs extends CMSPlugin implements SubscriberInterface * * @since __DEPLOY_VERSION__ */ - public const JOB_NO_TIME = 1; + public const TASK_NO_TIME = 1; /** * Exit Code For lock failure * * @since __DEPLOY_VERSION__ */ - public const JOB_NO_LOCK = 2; + public const TASK_NO_LOCK = 2; /** * Exit Code For execution failure * * @since __DEPLOY_VERSION__ */ - public const JOB_NO_RUN = 3; + public const TASK_NO_RUN = 3; /** * Exit Code For execution success * * @since __DEPLOY_VERSION__ */ - public const JOB_OK_RUN = 0; + public const TASK_OK_RUN = 0; /** - * Replacement exit code for job with no exit code + * Replacement exit code for task with no exit code * ! Removal due * * @since __DEPLOY_VERSION__ */ - public const JOB_NO_EXIT = -1; + public const TASK_NO_EXIT = -1; /** * @var CMSApplication @@ -91,7 +91,7 @@ class PlgSystemCronjobs extends CMSPlugin implements SubscriberInterface protected $autoloadLanguage = true; /** - * Stores the pseudo-cron status + * Stores the schedule runner status * * @var string[] * @since __DEPLOY_VERSION__ @@ -99,9 +99,9 @@ class PlgSystemCronjobs extends CMSPlugin implements SubscriberInterface protected $snapshot = []; private const LOG_TEXT = [ - self::JOB_OK_RUN => 'PLG_SYSTEM_CRONJOBS_RUN_COMPLETE', - self::JOB_NO_LOCK => 'PLG_SYSTEM_CRONJOBS_LOCKED', - self::JOB_NO_RUN => 'PLG_SYSTEM_CRONJOBS_UNLOCKED' + self::TASK_OK_RUN => 'PLG_SYSTEM_SCHEDULE_RUNNER_RUN_COMPLETE', + self::TASK_NO_LOCK => 'PLG_SYSTEM_SCHEDULE_RUNNER_LOCKED', + self::TASK_NO_RUN => 'PLG_SYSTEM_SCHEDULE_RUNNER_UNLOCKED' ]; /** @@ -134,7 +134,7 @@ public function __construct(&$subject, $config = []) public static function getSubscribedEvents(): array { return [ - 'onAfterRespond' => 'executeDueJob' + 'onAfterRespond' => 'executeDueTask' ]; } @@ -145,7 +145,7 @@ public static function getSubscribedEvents(): array * @throws Exception|RuntimeException * @since __DEPLOY_VERSION__ */ - public function executeDueJob(Event $event): void + public function executeDueTask(Event $event): void { // We only act on site requests if (!$this->app->isClient('site')) @@ -168,37 +168,37 @@ public function executeDueJob(Event $event): void throw new RuntimeException('JLIB_APPLICATION_ERROR_MODEL_CREATE'); } - $dueJob = $this->getDueJobs($model)[0] ?? null; + $dueTask = $this->getDueTasks($model)[0] ?? null; - if (!$dueJob) + if (!$dueTask) { return; } // Log events -- should we use action logger or this or both? $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; - $options['text_file'] = 'joomla_cronjobs.php'; + $options['text_file'] = 'joomla_scheduler.php'; Log::addLogger($options, Log::INFO, ['scheduler']); - $jobId = $dueJob->id; - $jobTitle = $dueJob->title; + $taskId = $dueTask->id; + $taskTitle = $dueTask->title; - // Add job ID, Title etc + // Add task ID, Title etc Log::add( - Text::sprintf('PLG_SYSTEM_CRONJOBS_START', $jobId, $jobTitle), + Text::sprintf('PLG_SYSTEM_SCHEDULE_RUNNER_START', $taskId, $taskTitle), Log::INFO, 'scheduler' ); - $jobRun = $this->runJob($dueJob); + $taskRun = $this->runTask($dueTask); $status = $this->snapshot['status']; $duration = $this->snapshot['duration']; - if (!$jobRun) + if (!$taskRun) { // TODO: Exit code ? Log::add( - Text::sprintf(self::LOG_TEXT[$status], $jobId, 0), + Text::sprintf(self::LOG_TEXT[$status], $taskId, 0), Log::INFO, 'scheduler' ); @@ -207,24 +207,24 @@ public function executeDueJob(Event $event): void } Log::add( - Text::sprintf(self::LOG_TEXT[$status], $jobId, $duration, 0), + Text::sprintf(self::LOG_TEXT[$status], $taskId, $duration, 0), LOG::INFO, 'scheduler' ); } /** - * Fetches due jobs from TasksModel - * ! Orphan filtering + pagination issues in the Model will break this if orphaned jobs exist [TODO] + * Fetches due tasks from TasksModel + * ! Orphan filtering + pagination issues in the Model will break this if orphaned tasks exist [TODO] * * @param TasksModel $model The TasksModel - * @param boolean $single If true, only a single job is returned + * @param boolean $single If true, only a single task is returned * * @return object[] * @throws Exception * @since __DEPLOY_VERSION__ */ - private function getDueJobs(TasksModel $model, bool $single = true): array + private function getDueTasks(TasksModel $model, bool $single = true): array { $model->set('__state_set', true); @@ -255,7 +255,7 @@ private function getDueJobs(TasksModel $model, bool $single = true): array } /** - * @param object $cronjob The cronjob entry + * @param object $task The task entry * @param boolean $scheduling Respect scheduling settings and state * ! Does nothing * @@ -264,17 +264,17 @@ private function getDueJobs(TasksModel $model, bool $single = true): array * @throws Exception * @since __DEPLOY_VERSION__ */ - private function runJob(object $cronjob, bool $scheduling = true): bool + private function runTask(object $task, bool $scheduling = true): bool { - $this->snapshot['jobId'] = $cronjob->id; - $this->snapshot['jobTitle'] = $cronjob->title; - $this->snapshot['status'] = self::JOB_NO_TIME; + $this->snapshot['taskId'] = $task->id; + $this->snapshot['taskTitle'] = $task->title; + $this->snapshot['status'] = self::TASK_NO_TIME; $this->snapshot['startTime'] = $this->snapshot['startTime'] ?? microtime(true); $this->snapshot['duration'] = 0; - if (!$setLock = $this->setLock($cronjob)) + if (!$setLock = $this->setLock($task)) { - $this->snapshot['status'] = self::JOB_NO_LOCK; + $this->snapshot['status'] = self::TASK_NO_LOCK; return false; } @@ -287,47 +287,47 @@ private function runJob(object $cronjob, bool $scheduling = true): bool [ 'eventClass' => 'Joomla\Component\Scheduler\Administrator\Event\CronRunEvent', 'subject' => $this, - 'jobId' => $cronjob->type, - 'langConstPrefix' => $cronjob->cronOption->langConstPrefix, - 'params' => json_decode($cronjob->params), + 'TaskId' => $task->type, + 'langConstPrefix' => $task->taskOption->langConstPrefix, + 'params' => json_decode($task->params), ] ); - // TODO: test -- can use exception handling here to prevent locked jobs - PluginHelper::importPlugin('job'); + // TODO: test -- can use exception handling here to prevent locked tasks + PluginHelper::importPlugin('task'); $app->getDispatcher()->dispatch('onCronRun', $event); - if (!$this->releaseLock($cronjob, $event->getResultSnapshot())) + if (!$this->releaseLock($task, $event->getResultSnapshot())) { - $this->snapshot['status'] = self::JOB_NO_RUN; + $this->snapshot['status'] = self::TASK_NO_RUN; return false; } $this->snapshot['endTime'] = microtime(true); - $this->snapshot['status'] = self::JOB_OK_RUN; + $this->snapshot['status'] = self::TASK_OK_RUN; $this->snapshot['duration'] = $this->snapshot['endTime'] - $this->snapshot['startTime']; return true; } /** - * @param object $cronjob The cronjob entry + * @param object $task The task entry * * @return boolean True on success * * @since __DEPLOY_VERSION__ */ - private function setLock(object $cronjob): bool + private function setLock(object $task): bool { $db = $this->db; $query = $db->getQuery(true); - $query->update($db->qn('#__scheduler_tasks', 'j')) - ->set('j.locked = 1') - ->where($db->qn('j.id') . ' = :jobId') - ->where($db->qn('j.locked') . ' = 0') - ->bind(':jobId', $cronjob->id, ParameterType::INTEGER); + $query->update($db->qn('#__scheduler_tasks', 't')) + ->set('t.locked = 1') + ->where($db->qn('t.id') . ' = :taskId') + ->where($db->qn('t.locked') . ' = 0') + ->bind(':taskId', $task->id, ParameterType::INTEGER); $db->setQuery($query)->execute(); if (!$affRow = $db->getAffectedRows()) @@ -339,8 +339,8 @@ private function setLock(object $cronjob): bool } /** - * @param object $cronjob The cronjob entry - * @param ?array $snapshot The job snapshot, optional + * @param object $task The task entry + * @param ?array $snapshot The task snapshot, optional * @param boolean $scheduling Respect scheduling settings and state * ! Does nothing * @@ -349,16 +349,16 @@ private function setLock(object $cronjob): bool * @throws Exception * @since __DEPLOY_VERSION__ */ - private function releaseLock(object $cronjob, array $snapshot = null, bool $scheduling = true): bool + private function releaseLock(object $task, array $snapshot = null, bool $scheduling = true): bool { $db = $this->db; $releaseQuery = $db->getQuery(true); $releaseQuery->update($db->qn('#__scheduler_tasks', 'j')) - ->set('locked = 0') - ->where($db->qn('id') . ' = :jobId') - ->where($db->qn('locked') . ' = 1') - ->bind(':jobId', $cronjob->id, ParameterType::INTEGER); + ->set('j.locked = 0') + ->where($db->qn('j.id') . ' = :taskId') + ->where($db->qn('j.locked') . ' = 1') + ->bind(':taskId', $task->id, ParameterType::INTEGER); $db->setQuery($releaseQuery)->execute(); if (!$affRow = $db->getAffectedRows()) @@ -369,29 +369,29 @@ private function releaseLock(object $cronjob, array $snapshot = null, bool $sche $updateQuery = $db->getQuery(true); - $jobId = $cronjob->get('id'); - $ruleType = $cronjob->get('cron_rules'); - $nextExec = (new ExecRuleHelper($cronjob))->nextExec(); - $exitCode = $snapshot['status'] ?? self::JOB_NO_EXIT; + $taskId = $task->get('id'); + $ruleType = $task->get('cron_rules'); + $nextExec = (new ExecRuleHelper($task))->nextExec(); + $exitCode = $snapshot['status'] ?? self::TASK_NO_EXIT; $now = Factory::getDate('now', 'GMT')->toSql(); /* - * [TODO] Failed status - should go in runJob() + * [TODO] Failed status - should go in runTask() */ - $updateQuery->update($db->qn('#__scheduler_tasks', 'j')) + $updateQuery->update($db->qn('#__scheduler_tasks', 't')) ->set( [ - 'j.last_execution = :now', - 'j.next_execution = :nextExec', - 'j.last_exit_code = :exitCode', - 'j.times_executed = j.times_executed + 1' + 't.last_execution = :now', + 't.next_execution = :nextExec', + 't.last_exit_code = :exitCode', + 't.times_executed = t.times_executed + 1' ] ) - ->where('j.id = :jobId') + ->where('t.id = :taskId') ->bind(':nextExec', $nextExec) ->bind(':exitCode', $exitCode, ParameterType::INTEGER) ->bind(':now', $now) - ->bind(':jobId', $jobId, ParameterType::INTEGER); + ->bind(':taskId', $taskId, ParameterType::INTEGER); $db->setQuery($updateQuery)->execute(); if (!$affRow = $db->getAffectedRows()) diff --git a/plugins/system/schedulerunner/schedulerunner.xml b/plugins/system/schedulerunner/schedulerunner.xml index 31e8c4824bf87..a993426708659 100644 --- a/plugins/system/schedulerunner/schedulerunner.xml +++ b/plugins/system/schedulerunner/schedulerunner.xml @@ -1,16 +1,16 @@ - Cronjobs + PLG_SYSTEM_SCHEDULE_RUNNER Joomla! Projects August 2021 GNU General Public License version 2 or later; see LICENSE.txt 4.1 - PLG_SYSTEM_CRONJOBS_XML_DESCRIPTION + PLG_SYSTEM_SCHEDULE_RUNNER_XML_DESCRIPTION - cronjobs.php + schedulerunner.php - en-GB.plg_system_cronjobs.ini - en-GB.plg_system_cronjobs.sys.ini + en-GB.plg_system_schedulerunner.ini + en-GB.plg_system_schedulerunner.sys.ini From 417e67acc64410e71e05ada336e263f733f8d36a Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 22 Aug 2021 11:38:22 +0530 Subject: [PATCH 319/615] Refactor com_cronjobs [15] - Rename Fields: - Refactors classes. - Updates usages. - Update access fieldset in task form. - Rename, update refs to media build files. --- .../com_scheduler/forms/filter_tasks.xml | 4 ++-- .../components/com_scheduler/forms/task.xml | 4 ++-- ...ronjobStateField.php => TaskStateField.php} | 4 ++-- .../{JobTypeField.php => TaskTypeField.php} | 4 ++-- .../com_scheduler/tmpl/cronjob/edit.php | 2 +- .../com_scheduler/tmpl/select/default.php | 4 ++-- ...-plg-job.css => admin-view-select-task.css} | 0 ...in-view-cronjob.css => admin-view-task.css} | 0 .../com_scheduler/joomla.asset.json | 18 +++++++++--------- ...js => admin-view-select-task-search.es6.js} | 0 10 files changed, 20 insertions(+), 20 deletions(-) rename administrator/components/com_scheduler/src/Field/{CronjobStateField.php => TaskStateField.php} (91%) rename administrator/components/com_scheduler/src/Field/{JobTypeField.php => TaskTypeField.php} (95%) rename build/media_source/com_scheduler/css/{admin-plg-job.css => admin-view-select-task.css} (100%) rename build/media_source/com_scheduler/css/{admin-view-cronjob.css => admin-view-task.css} (100%) rename build/media_source/com_scheduler/js/{admin-plg-job-search.es6.js => admin-view-select-task-search.es6.js} (100%) diff --git a/administrator/components/com_scheduler/forms/filter_tasks.xml b/administrator/components/com_scheduler/forms/filter_tasks.xml index deaec434195db..0b64f0d33f469 100644 --- a/administrator/components/com_scheduler/forms/filter_tasks.xml +++ b/administrator/components/com_scheduler/forms/filter_tasks.xml @@ -11,7 +11,7 @@ /> diff --git a/administrator/components/com_scheduler/forms/task.xml b/administrator/components/com_scheduler/forms/task.xml index 1dbce79d3059b..d62648b24a886 100644 --- a/administrator/components/com_scheduler/forms/task.xml +++ b/administrator/components/com_scheduler/forms/task.xml @@ -28,7 +28,7 @@
diff --git a/administrator/components/com_scheduler/src/Field/CronjobStateField.php b/administrator/components/com_scheduler/src/Field/TaskStateField.php similarity index 91% rename from administrator/components/com_scheduler/src/Field/CronjobStateField.php rename to administrator/components/com_scheduler/src/Field/TaskStateField.php index 6c787e8b1b0e5..ba6ae6253c9b0 100644 --- a/administrator/components/com_scheduler/src/Field/CronjobStateField.php +++ b/administrator/components/com_scheduler/src/Field/TaskStateField.php @@ -21,7 +21,7 @@ * * @since __DEPLOY_VERSION__ */ -class CronjobStateField extends PredefinedlistField +class TaskStateField extends PredefinedlistField { /** * The form field type. @@ -29,7 +29,7 @@ class CronjobStateField extends PredefinedlistField * @var string * @since __DEPLOY_VERSION__ */ - public $type = 'CronjobState'; + public $type = 'TaskState'; /** * Available states diff --git a/administrator/components/com_scheduler/src/Field/JobTypeField.php b/administrator/components/com_scheduler/src/Field/TaskTypeField.php similarity index 95% rename from administrator/components/com_scheduler/src/Field/JobTypeField.php rename to administrator/components/com_scheduler/src/Field/TaskTypeField.php index c86c2d4d79fab..7e7f481380f6c 100644 --- a/administrator/components/com_scheduler/src/Field/JobTypeField.php +++ b/administrator/components/com_scheduler/src/Field/TaskTypeField.php @@ -27,7 +27,7 @@ * * @since __DEPLOY_VERSION__ */ -class JobTypeField extends ListField +class TaskTypeField extends ListField { /** * The form field type. @@ -35,7 +35,7 @@ class JobTypeField extends ListField * @var string * @since __DEPLOY_VERSION__ */ - protected $type = 'jobType'; + protected $type = 'TaskType'; /** * Method to get field options diff --git a/administrator/components/com_scheduler/tmpl/cronjob/edit.php b/administrator/components/com_scheduler/tmpl/cronjob/edit.php index f30185e9e988a..82e9f928686ef 100644 --- a/administrator/components/com_scheduler/tmpl/cronjob/edit.php +++ b/administrator/components/com_scheduler/tmpl/cronjob/edit.php @@ -26,7 +26,7 @@ $wa->useScript('keepalive'); $wa->useScript('form.validate'); -$wa->useStyle('com_scheduler.admin-view-cronjob-css'); +$wa->useStyle('com_scheduler.admin-view-task-css'); /** @var AdministratorApplication $app */ $app = $this->app; diff --git a/administrator/components/com_scheduler/tmpl/select/default.php b/administrator/components/com_scheduler/tmpl/select/default.php index c4e2c213bd924..a44be83111f86 100644 --- a/administrator/components/com_scheduler/tmpl/select/default.php +++ b/administrator/components/com_scheduler/tmpl/select/default.php @@ -27,8 +27,8 @@ // $function = $app->getInput()->get('function'); $wa = $this->document->getWebAssetManager(); -$wa->useStyle('com_scheduler.admin-plg-job-css'); -$wa->useScript('com_scheduler.admin-plg-job-search'); +$wa->useStyle('com_scheduler.admin-view-select-task-css'); +$wa->useScript('com_scheduler.admin-view-select-task-search'); /* * if ($function) : diff --git a/build/media_source/com_scheduler/css/admin-plg-job.css b/build/media_source/com_scheduler/css/admin-view-select-task.css similarity index 100% rename from build/media_source/com_scheduler/css/admin-plg-job.css rename to build/media_source/com_scheduler/css/admin-view-select-task.css diff --git a/build/media_source/com_scheduler/css/admin-view-cronjob.css b/build/media_source/com_scheduler/css/admin-view-task.css similarity index 100% rename from build/media_source/com_scheduler/css/admin-view-cronjob.css rename to build/media_source/com_scheduler/css/admin-view-task.css diff --git a/build/media_source/com_scheduler/joomla.asset.json b/build/media_source/com_scheduler/joomla.asset.json index 4248d5688970a..fc304820625a0 100644 --- a/build/media_source/com_scheduler/joomla.asset.json +++ b/build/media_source/com_scheduler/joomla.asset.json @@ -6,9 +6,9 @@ "license": "GNU General Public License version 2 or later; see LICENSE.txt", "assets": [ { - "name": "com_scheduler.admin-plg-job-search.es5", + "name": "com_scheduler.admin-view-select-task-search.es5", "type": "script", - "uri": "com_scheduler/admin-plg-job-search-es5.js", + "uri": "com_scheduler/admin-view-select-task-search-es5.js", "dependencies": [ "core" ], @@ -18,25 +18,25 @@ } }, { - "name": "com_scheduler.admin-plg-job-search", + "name": "com_scheduler.admin-view-select-task-search", "type": "script", - "uri": "com_scheduler/admin-plg-job-search.js", + "uri": "com_scheduler/admin-view-select-task-search.js", "dependencies": [ - "com_scheduler.admin-plg-job-search.es5" + "com_scheduler.admin-view-select-task-search.es5" ], "attributes": { "type" : "module" } }, { - "name": "com_scheduler.admin-plg-job-css", + "name": "com_scheduler.admin-view-select-task-css", "type": "style", - "uri": "com_scheduler/admin-plg-job.css" + "uri": "com_scheduler/admin-view-select-task.css" }, { - "name": "com_scheduler.admin-view-cronjob-css", + "name": "com_scheduler.admin-view-task-css", "type": "style", - "uri": "com_scheduler/admin-view-cronjob.css" + "uri": "com_scheduler/admin-view-task.css" } ] } diff --git a/build/media_source/com_scheduler/js/admin-plg-job-search.es6.js b/build/media_source/com_scheduler/js/admin-view-select-task-search.es6.js similarity index 100% rename from build/media_source/com_scheduler/js/admin-plg-job-search.es6.js rename to build/media_source/com_scheduler/js/admin-view-select-task-search.es6.js From 9e45c7a23ad293ffb8a6bab1f1dcd66cf49e73ad Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 22 Aug 2021 14:34:07 +0530 Subject: [PATCH 320/615] Refactor com_cronjobs [16] - Refactors media build files. - Refactors view templates (dir renames pending). - Updates language files: - Add missing constants. - Alpha-sorts. - Updates task params in SelectView. - Refactor `cronOption` refs in TasksModel, TaskModel, TaskPluginTrait. --- .../com_scheduler/src/Model/TaskModel.php | 4 +-- .../com_scheduler/src/Model/TasksModel.php | 6 ++-- .../src/Traits/TaskPluginTrait.php | 2 +- .../com_scheduler/tmpl/cronjob/edit.php | 26 +++++++------- .../com_scheduler/tmpl/cronjobs/default.php | 26 +++++++------- .../com_scheduler/tmpl/cronjobs/default.xml | 4 +-- .../tmpl/cronjobs/default_batch_footer.php | 2 +- .../tmpl/cronjobs/empty_state.php | 2 +- .../com_scheduler/tmpl/select/default.php | 36 +++++++++---------- .../com_scheduler/tmpl/select/modal.php | 2 +- .../language/en-GB/com_scheduler.ini | 12 ++++--- .../css/admin-view-select-task.css | 20 +++++------ .../js/admin-view-select-task-search.es6.js | 33 ++++++++--------- 13 files changed, 89 insertions(+), 86 deletions(-) diff --git a/administrator/components/com_scheduler/src/Model/TaskModel.php b/administrator/components/com_scheduler/src/Model/TaskModel.php index f1ea41ae26060..157acb00e9991 100644 --- a/administrator/components/com_scheduler/src/Model/TaskModel.php +++ b/administrator/components/com_scheduler/src/Model/TaskModel.php @@ -278,11 +278,11 @@ public function getItem($pk = null) $item->set('execution_rules', json_decode($item->get('execution_rules'))); $item->set('cron_rules', json_decode($item->get('cron_rules'))); - $cronOption = SchedulerHelper::getTaskOptions()->findOption( + $taskOption = SchedulerHelper::getTaskOptions()->findOption( ($item->id ?? 0) ? ($item->type ?? 0) : $this->getState('task.type') ); - $item->set('cronOption', $cronOption); + $item->set('taskOption', $taskOption); return $item; } diff --git a/administrator/components/com_scheduler/src/Model/TasksModel.php b/administrator/components/com_scheduler/src/Model/TasksModel.php index 7e1f6b099814f..87916555e69b0 100644 --- a/administrator/components/com_scheduler/src/Model/TasksModel.php +++ b/administrator/components/com_scheduler/src/Model/TasksModel.php @@ -351,12 +351,12 @@ function (object $c) { */ private function attachTaskOptions(array &$items): void { - $cronOptions = SchedulerHelper::getTaskOptions(); + $taskOptions = SchedulerHelper::getTaskOptions(); foreach ($items as $item) { - $item->cronOption = $cronOptions->findOption($item->type); - $item->safeTypeTitle = $item->cronOption->title ?? Text::_('JGLOBAL_NONAPPLICABLE'); + $item->taskOption = $taskOptions->findOption($item->type); + $item->safeTypeTitle = $item->taskOption->title ?? Text::_('JGLOBAL_NONAPPLICABLE'); } } diff --git a/administrator/components/com_scheduler/src/Traits/TaskPluginTrait.php b/administrator/components/com_scheduler/src/Traits/TaskPluginTrait.php index 438959e8d25aa..d8cf4d3015e5a 100644 --- a/administrator/components/com_scheduler/src/Traits/TaskPluginTrait.php +++ b/administrator/components/com_scheduler/src/Traits/TaskPluginTrait.php @@ -178,7 +178,7 @@ public function advertiseRoutines(Event $event): void */ protected function getRoutineId(Form $form, $data): string { - $routineId = $data->cronOption->type ?? $data['cronOption']->type ?? $form->getValue('type'); + $routineId = $data->taskOption->type ?? $data['taskOption']->type ?? $form->getValue('type'); if (!$routineId) { diff --git a/administrator/components/com_scheduler/tmpl/cronjob/edit.php b/administrator/components/com_scheduler/tmpl/cronjob/edit.php index 82e9f928686ef..734a74ad82577 100644 --- a/administrator/components/com_scheduler/tmpl/cronjob/edit.php +++ b/administrator/components/com_scheduler/tmpl/cronjob/edit.php @@ -39,16 +39,16 @@ // ? : Are these of use here? $isModal = $input->get('layout') === 'modal'; $layout = $isModal ? 'modal' : 'edit'; -$tmpl = $isModal || $input->get('tmpl', '', 'cmd') === 'component' ? '&tmpl=component' : ''; +$tmpl = $isModal || $input->get('tmpl', '') === 'component' ? '&tmpl=component' : ''; ?> - + @@ -64,23 +64,23 @@ class="form-validate"> ?>
- - item->cronOption): - /** @var TaskOption $cronOption */ - $cronOption = $this->item->cronOption; ?> -
-

- title ?> + + item->taskOption): + /** @var TaskOption $taskOption */ + $taskOption = $this->item->taskOption; ?> +
+

+ title ?>

-

+

escape(strip_tags($cronOption->desc)), 250); + $desc = HTMLHelper::_('string.truncate', $this->escape(strip_tags($taskOption->desc)), 250); echo $desc; ?>

- + enqueueMessage(Text::_('COM_SCHEDULER_WARNING_EXISTING_TASK_TYPE_NOT_FOUND'), 'warning'); ?> diff --git a/administrator/components/com_scheduler/tmpl/cronjobs/default.php b/administrator/components/com_scheduler/tmpl/cronjobs/default.php index cb1bab2d18f79..eba888b94fee3 100644 --- a/administrator/components/com_scheduler/tmpl/cronjobs/default.php +++ b/administrator/components/com_scheduler/tmpl/cronjobs/default.php @@ -43,12 +43,12 @@ if ($saveOrder && !empty($this->items)) { - $saveOrderingUrl = 'index.php?option=com_scheduler&task=cronjobs.saveOrderAjax&tmpl=component&' . Session::getFormToken() . '=1'; + $saveOrderingUrl = 'index.php?option=com_scheduler&task=tasks.saveOrderAjax&tmpl=component&' . Session::getFormToken() . '=1'; HTMLHelper::_('draggablelist.draggable'); } ?> -
$this)); ?> - + items)): ?> - +
@@ -66,9 +66,9 @@ class="visually-hidden">
- + items)): ?> - +

- , + , ,
- +
- escape($item->title); ?> escape($item->title); ?> @@ -169,7 +169,7 @@ class="js-draggable" data-url="" data-direction=" note)): ?> - + escape($item->note)); ?> @@ -197,16 +197,16 @@ class="js-draggable" data-url="" data-direction=" - authorise('core.create', 'com_cronjobs') - && $user->authorise('core.edit', 'com_cronjobs') - && $user->authorise('core.edit.state', 'com_cronjobs')): + authorise('core.create', 'com_scheduler') + && $user->authorise('core.edit', 'com_scheduler') + && $user->authorise('core.edit.state', 'com_scheduler')): ?> Text::_('com_cronjobs_BATCH_OPTIONS'), + 'title' => Text::_('COM_SCHEDULER_BATCH_OPTIONS'), 'footer' => $this->loadTemplate('batch_footer'), ], $this->loadTemplate('batch_body') diff --git a/administrator/components/com_scheduler/tmpl/cronjobs/default.xml b/administrator/components/com_scheduler/tmpl/cronjobs/default.xml new file mode 100644 index 0000000000000..d292320fa0267 --- /dev/null +++ b/administrator/components/com_scheduler/tmpl/cronjobs/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/administrator/components/com_cronjobs/tmpl/cronjobs/default_batch_body.php b/administrator/components/com_scheduler/tmpl/cronjobs/default_batch_body.php similarity index 95% rename from administrator/components/com_cronjobs/tmpl/cronjobs/default_batch_body.php rename to administrator/components/com_scheduler/tmpl/cronjobs/default_batch_body.php index 92260e37f6f7f..988e06c4f4f60 100644 --- a/administrator/components/com_cronjobs/tmpl/cronjobs/default_batch_body.php +++ b/administrator/components/com_scheduler/tmpl/cronjobs/default_batch_body.php @@ -1,7 +1,7 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt diff --git a/administrator/components/com_cronjobs/tmpl/cronjobs/default_batch_footer.php b/administrator/components/com_scheduler/tmpl/cronjobs/default_batch_footer.php similarity index 95% rename from administrator/components/com_cronjobs/tmpl/cronjobs/default_batch_footer.php rename to administrator/components/com_scheduler/tmpl/cronjobs/default_batch_footer.php index 047b30a06dc44..d683fc38afd94 100644 --- a/administrator/components/com_cronjobs/tmpl/cronjobs/default_batch_footer.php +++ b/administrator/components/com_scheduler/tmpl/cronjobs/default_batch_footer.php @@ -1,7 +1,7 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt diff --git a/administrator/components/com_cronjobs/tmpl/cronjobs/empty_state.php b/administrator/components/com_scheduler/tmpl/cronjobs/empty_state.php similarity index 69% rename from administrator/components/com_cronjobs/tmpl/cronjobs/empty_state.php rename to administrator/components/com_scheduler/tmpl/cronjobs/empty_state.php index a402edd450740..8cf1dcc6d730c 100644 --- a/administrator/components/com_cronjobs/tmpl/cronjobs/empty_state.php +++ b/administrator/components/com_scheduler/tmpl/cronjobs/empty_state.php @@ -1,7 +1,7 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt @@ -13,15 +13,15 @@ use Joomla\CMS\Layout\LayoutHelper; $displayData = [ - 'textPrefix' => 'COM_CRONJOBS', - 'formURL' => 'index.php?option=com_cronjobs&task=cronjob.add', + 'textPrefix' => 'COM_SCHEDULER', + 'formURL' => 'index.php?option=com_scheduler&task=cronjob.add', 'helpURL' => 'https://github.com/joomla-projects/soc21_website-cronjob', 'icon' => 'icon-clock clock', ]; -if (Factory::getApplication()->getIdentity()->authorise('core.create', 'com_cronjobs')) +if (Factory::getApplication()->getIdentity()->authorise('core.create', 'com_scheduler')) { - $displayData['createURL'] = 'index.php?option=com_cronjobs&view=select&layout=default'; + $displayData['createURL'] = 'index.php?option=com_scheduler&view=select&layout=default'; } echo LayoutHelper::render('joomla.content.emptystate', $displayData); diff --git a/administrator/components/com_cronjobs/tmpl/select/default.php b/administrator/components/com_scheduler/tmpl/select/default.php similarity index 83% rename from administrator/components/com_cronjobs/tmpl/select/default.php rename to administrator/components/com_scheduler/tmpl/select/default.php index 2dd7dedda846d..8c0c365ea738e 100644 --- a/administrator/components/com_cronjobs/tmpl/select/default.php +++ b/administrator/components/com_scheduler/tmpl/select/default.php @@ -3,7 +3,7 @@ * The SelectView default layout template. * * @package Joomla.Administrator - * @subpackage com_cronjobs + * @subpackage com_scheduler * * @copyright (C) 2021 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt @@ -27,12 +27,12 @@ // $function = $app->getInput()->get('function'); $wa = $this->document->getWebAssetManager(); -$wa->useStyle('com_cronjobs.admin-plg-job-css'); -$wa->useScript('com_cronjobs.admin-plg-job-search'); +$wa->useStyle('com_scheduler.admin-plg-job-css'); +$wa->useScript('com_scheduler.admin-plg-job-search'); /* * if ($function) : - * $wa->useScript('COM_CRONJOBS.admin-select-modal'); + * $wa->useScript('com_scheduler.admin-select-modal'); * endif;*/ ?> @@ -41,7 +41,7 @@
- +

- +

@@ -75,13 +75,13 @@ class="visually-hidden"> items as &$item) : ?> - type; ?> + type; ?> escape($item->title); ?> escape(strip_tags($item->desc)), 200); ?> + aria-label="">

diff --git a/administrator/components/com_cronjobs/tmpl/select/modal.php b/administrator/components/com_scheduler/tmpl/select/modal.php similarity index 96% rename from administrator/components/com_cronjobs/tmpl/select/modal.php rename to administrator/components/com_scheduler/tmpl/select/modal.php index a5a87fdf452be..b97f9c9293412 100644 --- a/administrator/components/com_cronjobs/tmpl/select/modal.php +++ b/administrator/components/com_scheduler/tmpl/select/modal.php @@ -3,7 +3,7 @@ * The SelectView modal layout template. * * @package Joomla.Administrator - * @subpackage com_cronjobs + * @subpackage com_scheduler * * @copyright (C) 2021 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt diff --git a/administrator/language/en-GB/com_cronjobs.ini b/administrator/language/en-GB/com_cronjobs.ini deleted file mode 100644 index 236e066fa2611..0000000000000 --- a/administrator/language/en-GB/com_cronjobs.ini +++ /dev/null @@ -1,91 +0,0 @@ -; Joomla! Projects -; (C) 2021 Open Source Matters, Inc. -; GNU General Public License version 2 or later; see LICENSE.txt - -COM_CRONJOBS="Cronjobs" -COM_CRONJOBS_CLI_JOBS_DESC="Configure a CLI script to run at a scheduled interval or another condition." -COM_CRONJOBS_CLI_JOBS_TITLE="CLI/Script Job" -COM_CRONJOBS_DASHBOARD_TITLE="Cronjobs Manager" -COM_CRONJOBS_EDIT_CRONJOB="Edit Cronjob" -COM_CRONJOBS_EMPTYSTATE_BUTTON_ADD="Add a Cronjob!" -COM_CRONJOBS_EMPTYSTATE_CONTENT="No cronjobs!" -COM_CRONJOBS_EMPTYSTATE_TITLE="No Cronjobs have been created yet!" -COM_CRONJOBS_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW="You need to select a Job Type first!" -COM_CRONJOBS_ERROR_INVALID_JOB_TYPE="Invalid Job Type!" -COM_CRONJOBS_FIELD_JOB_TYPE="Type ID" -COM_CRONJOBS_FIELD_LABEL_EXEC_RULE="Execution Rule" -COM_CRONJOBS_FIELD_LABEL_INTERVAL_DAYS="Interval in Days" -COM_CRONJOBS_FIELD_LABEL_INTERVAL_HOURS="Interval in Hours" -COM_CRONJOBS_FIELD_LABEL_INTERVAL_MINUTES="Interval in Minutes" -COM_CRONJOBS_FIELD_LABEL_INTERVAL_MONTHS="Interval in Months" -COM_CRONJOBS_FIELD_LABEL_SHOW_ORPHANED="Show Orphaned" -COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_DAYS_M="Days of Month" -COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_DAYS_W="Days of Week" -COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_HOURS="Hours" -COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_MINUTES="Minutes" -COM_CRONJOBS_FIELD_OPTION_INTERVAL_MATCH_MONTHS="Months" -COM_CRONJOBS_FIELDSET_BASIC="Basic Fields" -COM_CRONJOBS_FIELDSET_CRON_OPTIONS="Cron Options" -COM_CRONJOBS_FIELDSET_EXEC_HIST="Execution History" -COM_CRONJOBS_FIELDSET_PARAMS_FS="Job Parameters" -COM_CRONJOBS_FILTER_SEARCH_DESC="Search in cronjob title and note. Prefix with 'ID:' to search for a job ID" -COM_CRONJOBS_FILTER_SEARCH_LABEL="Search Cronjobs" -COM_CRONJOBS_FORM_TITLE_EDIT="Edit Cronjob" -COM_CRONJOBS_FORM_TITLE_NEW="New Cronjob" -COM_CRONJOBS_HEADING_JOB_TYPE="- Job Type -" -COM_CRONJOBS_JOB_LOG_PREFIX="Job> " -COM_CRONJOBS_JOB_TYPE="Job Type" -COM_CRONJOBS_JOB_TYPE_ASC="Job Type Ascending" -COM_CRONJOBS_JOB_TYPE_DESC="Job Type Descending" -COM_CRONJOBS_LABEL_EXEC_DAY="Execution Day" -COM_CRONJOBS_LABEL_EXEC_INTERVAL="Execution Interval" -COM_CRONJOBS_LABEL_EXEC_TIME="Execution Time (UTC)" -COM_CRONJOBS_LABEL_EXIT_CODE="Last Exit Code" -COM_CRONJOBS_LABEL_HOURS="Hours" -COM_CRONJOBS_LABEL_LAST_EXEC="Last Executed" -COM_CRONJOBS_LABEL_MINUTES="Minutes" -COM_CRONJOBS_LABEL_NEXT_EXEC="Next Execution" -COM_CRONJOBS_LABEL_NOTES="Notes" -COM_CRONJOBS_LABEL_PLG_JOB_ID="Plugin Job ID" -COM_CRONJOBS_LABEL_TIMES_EXEC="Times Executed" -COM_CRONJOBS_LABEL_TIMES_FAIL="Times Failed" -COM_CRONJOBS_MANAGER_CRONJOB="Cronjob Manager" -COM_CRONJOBS_MANAGER_CRONJOB_EDIT="Edit Cronjob" -COM_CRONJOBS_MANAGER_CRONJOB_NEW="New Cronjob" -COM_CRONJOBS_MANAGER_CRONJOBS="Cronjobs Manager" -COM_CRONJOBS_MSG_MANAGE_NO_JOB_PLUGINS="There are no jobs types matching your query" -COM_CRONJOBS_N_ITEMS_DELETED="%s cronjobs deleted." -COM_CRONJOBS_N_ITEMS_DELETED_1="Cronjob deleted." -COM_CRONJOBS_N_ITEMS_PUBLISHED="%s cronjobs enabled." -COM_CRONJOBS_N_ITEMS_PUBLISHED_1="Cronjob enabled." -COM_CRONJOBS_N_ITEMS_TRASHED="%s cronjobs trashed." -COM_CRONJOBS_N_ITEMS_TRASHED_1="Cronjob trashed." -COM_CRONJOBS_N_ITEMS_UNPUBLISHED="%s cronjobs disabled." -COM_CRONJOBS_N_ITEMS_UNPUBLISHED_1="Cronjob disabled." -COM_CRONJOBS_NEW_CRONJOB="New Cronjob" -COM_CRONJOBS_NO_NOTE="" -COM_CRONJOBS_OPTION_INTERVAL_CUSTOM="Custom Match (Advanced)" -COM_CRONJOBS_OPTION_INTERVAL_DAYS="Interval, Days" -COM_CRONJOBS_OPTION_INTERVAL_HOURS="Interval, Hours" -COM_CRONJOBS_OPTION_INTERVAL_MINUTES="Interval, Minutes" -COM_CRONJOBS_OPTION_INTERVAL_MONTHS="Interval, Months" -COM_CRONJOBS_OPTION_ORPHANED_HIDE="Hide Orphaned" -COM_CRONJOBS_OPTION_ORPHANED_SHOW="Show Orphaned" -COM_CRONJOBS_SELECT_CLI_JOB="Select CLI job" -COM_CRONJOBS_SELECT_EXEC_RULE="--- Select Rule ---" -COM_CRONJOBS_SELECT_INTERVAL_DAYS="-- Select Interval in Days --" -COM_CRONJOBS_SELECT_INTERVAL_HOURS="-- Select Interval in Hours --" -COM_CRONJOBS_SELECT_INTERVAL_MINUTES="-- Select Interval in Minutes --" -COM_CRONJOBS_SELECT_INTERVAL_MONTHS="-- Select Interval in Months --" -COM_CRONJOBS_SELECT_PLG_JOB="Select job, %s" -COM_CRONJOBS_SELECT_TRIGGER="Trigger" -COM_CRONJOBS_SELECT_TYPE="- Cronjob Type -" -COM_CRONJOBS_TABLE_CAPTION="Cronjobs List" -COM_CRONJOBS_TRIGGER_CRON="Cron" -COM_CRONJOBS_TRIGGER_PSEUDOCRON="Pseudocron" -COM_CRONJOBS_TRIGGER_XVISITS="X-Visits" -COM_CRONJOBS_TYPE_CHOOSE="Select a Job type" -COM_CRONJOBS_TYPE_OR_SELECT_OPTIONS="Type or select options" -COM_CRONJOBS_TYPE_PLG="Plugin" -COM_CRONJOBS_TYPE_SCRIPT="CLI Script" -COM_CRONJOBS_XML_DESCRIPTION="Component for managing pseudo-cronjobs and cronjobs (if server supports)" diff --git a/administrator/language/en-GB/com_cronjobs.sys.ini b/administrator/language/en-GB/com_cronjobs.sys.ini deleted file mode 100644 index 930633c6cfff0..0000000000000 --- a/administrator/language/en-GB/com_cronjobs.sys.ini +++ /dev/null @@ -1,13 +0,0 @@ -; Joomla! Projects -; (C) 2021 Open Source Matters, Inc. -; GNU General Public License version 2 or later; see LICENSE.txt - -COM_CRONJOBS="Cronjobs" -COM_CRONJOBS_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW="You need to select a Job Type first!" -COM_CRONJOBS_ERROR_INVALID_JOB_TYPE="Invalid Job Type!" -COM_CRONJOBS_MANAGER_CRONJOB="Cronjob Manager" -COM_CRONJOBS_MANAGER_CRONJOB_EDIT="Edit Cronjob" -COM_CRONJOBS_MANAGER_CRONJOB_NEW="New Cronjob" -COM_CRONJOBS_MANAGER_CRONJOBS="Cronjobs Manager" -COM_CRONJOBS_MSG_MANAGE_NO_JOB_PLUGINS="There are no jobs types matching your query" -COM_CRONJOBS_XML_DESCRIPTION="Component for managing pseudo-cronjobs and cronjobs (if server supports)" diff --git a/administrator/language/en-GB/com_scheduler.ini b/administrator/language/en-GB/com_scheduler.ini new file mode 100644 index 0000000000000..ea1cf5c511cfb --- /dev/null +++ b/administrator/language/en-GB/com_scheduler.ini @@ -0,0 +1,91 @@ +; Joomla! Projects +; (C) 2021 Open Source Matters, Inc. +; GNU General Public License version 2 or later; see LICENSE.txt + +COM_SCHEDULER="Cronjobs" +COM_SCHEDULER_CLI_JOBS_DESC="Configure a CLI script to run at a scheduled interval or another condition." +COM_SCHEDULER_CLI_JOBS_TITLE="CLI/Script Job" +COM_SCHEDULER_DASHBOARD_TITLE="Cronjobs Manager" +COM_SCHEDULER_EDIT_CRONJOB="Edit Cronjob" +COM_SCHEDULER_EMPTYSTATE_BUTTON_ADD="Add a Cronjob!" +COM_SCHEDULER_EMPTYSTATE_CONTENT="No cronjobs!" +COM_SCHEDULER_EMPTYSTATE_TITLE="No Cronjobs have been created yet!" +COM_SCHEDULER_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW="You need to select a Job Type first!" +COM_SCHEDULER_ERROR_INVALID_JOB_TYPE="Invalid Job Type!" +COM_SCHEDULER_FIELD_JOB_TYPE="Type ID" +COM_SCHEDULER_FIELD_LABEL_EXEC_RULE="Execution Rule" +COM_SCHEDULER_FIELD_LABEL_INTERVAL_DAYS="Interval in Days" +COM_SCHEDULER_FIELD_LABEL_INTERVAL_HOURS="Interval in Hours" +COM_SCHEDULER_FIELD_LABEL_INTERVAL_MINUTES="Interval in Minutes" +COM_SCHEDULER_FIELD_LABEL_INTERVAL_MONTHS="Interval in Months" +COM_SCHEDULER_FIELD_LABEL_SHOW_ORPHANED="Show Orphaned" +COM_SCHEDULER_FIELD_OPTION_INTERVAL_MATCH_DAYS_M="Days of Month" +COM_SCHEDULER_FIELD_OPTION_INTERVAL_MATCH_DAYS_W="Days of Week" +COM_SCHEDULER_FIELD_OPTION_INTERVAL_MATCH_HOURS="Hours" +COM_SCHEDULER_FIELD_OPTION_INTERVAL_MATCH_MINUTES="Minutes" +COM_SCHEDULER_FIELD_OPTION_INTERVAL_MATCH_MONTHS="Months" +COM_SCHEDULER_FIELDSET_BASIC="Basic Fields" +COM_SCHEDULER_FIELDSET_CRON_OPTIONS="Cron Options" +COM_SCHEDULER_FIELDSET_EXEC_HIST="Execution History" +COM_SCHEDULER_FIELDSET_PARAMS_FS="Job Parameters" +COM_SCHEDULER_FILTER_SEARCH_DESC="Search in cronjob title and note. Prefix with 'ID:' to search for a job ID" +COM_SCHEDULER_FILTER_SEARCH_LABEL="Search Cronjobs" +COM_SCHEDULER_FORM_TITLE_EDIT="Edit Cronjob" +COM_SCHEDULER_FORM_TITLE_NEW="New Cronjob" +COM_SCHEDULER_HEADING_JOB_TYPE="- Job Type -" +COM_SCHEDULER_JOB_LOG_PREFIX="Job> " +COM_SCHEDULER_JOB_TYPE="Job Type" +COM_SCHEDULER_JOB_TYPE_ASC="Job Type Ascending" +COM_SCHEDULER_JOB_TYPE_DESC="Job Type Descending" +COM_SCHEDULER_LABEL_EXEC_DAY="Execution Day" +COM_SCHEDULER_LABEL_EXEC_INTERVAL="Execution Interval" +COM_SCHEDULER_LABEL_EXEC_TIME="Execution Time (UTC)" +COM_SCHEDULER_LABEL_EXIT_CODE="Last Exit Code" +COM_SCHEDULER_LABEL_HOURS="Hours" +COM_SCHEDULER_LABEL_LAST_EXEC="Last Executed" +COM_SCHEDULER_LABEL_MINUTES="Minutes" +COM_SCHEDULER_LABEL_NEXT_EXEC="Next Execution" +COM_SCHEDULER_LABEL_NOTES="Notes" +COM_SCHEDULER_LABEL_PLG_JOB_ID="Plugin Job ID" +COM_SCHEDULER_LABEL_TIMES_EXEC="Times Executed" +COM_SCHEDULER_LABEL_TIMES_FAIL="Times Failed" +COM_SCHEDULER_MANAGER_CRONJOB="Cronjob Manager" +COM_SCHEDULER_MANAGER_CRONJOB_EDIT="Edit Cronjob" +COM_SCHEDULER_MANAGER_CRONJOB_NEW="New Cronjob" +COM_SCHEDULER_MANAGER_CRONJOBS="Cronjobs Manager" +COM_SCHEDULER_MSG_MANAGE_NO_JOB_PLUGINS="There are no jobs types matching your query" +COM_SCHEDULER_N_ITEMS_DELETED="%s cronjobs deleted." +COM_SCHEDULER_N_ITEMS_DELETED_1="Cronjob deleted." +COM_SCHEDULER_N_ITEMS_PUBLISHED="%s cronjobs enabled." +COM_SCHEDULER_N_ITEMS_PUBLISHED_1="Cronjob enabled." +COM_SCHEDULER_N_ITEMS_TRASHED="%s cronjobs trashed." +COM_SCHEDULER_N_ITEMS_TRASHED_1="Cronjob trashed." +COM_SCHEDULER_N_ITEMS_UNPUBLISHED="%s cronjobs disabled." +COM_SCHEDULER_N_ITEMS_UNPUBLISHED_1="Cronjob disabled." +COM_SCHEDULER_NEW_CRONJOB="New Cronjob" +COM_SCHEDULER_NO_NOTE="" +COM_SCHEDULER_OPTION_INTERVAL_CUSTOM="Custom Match (Advanced)" +COM_SCHEDULER_OPTION_INTERVAL_DAYS="Interval, Days" +COM_SCHEDULER_OPTION_INTERVAL_HOURS="Interval, Hours" +COM_SCHEDULER_OPTION_INTERVAL_MINUTES="Interval, Minutes" +COM_SCHEDULER_OPTION_INTERVAL_MONTHS="Interval, Months" +COM_SCHEDULER_OPTION_ORPHANED_HIDE="Hide Orphaned" +COM_SCHEDULER_OPTION_ORPHANED_SHOW="Show Orphaned" +COM_SCHEDULER_SELECT_CLI_JOB="Select CLI job" +COM_SCHEDULER_SELECT_EXEC_RULE="--- Select Rule ---" +COM_SCHEDULER_SELECT_INTERVAL_DAYS="-- Select Interval in Days --" +COM_SCHEDULER_SELECT_INTERVAL_HOURS="-- Select Interval in Hours --" +COM_SCHEDULER_SELECT_INTERVAL_MINUTES="-- Select Interval in Minutes --" +COM_SCHEDULER_SELECT_INTERVAL_MONTHS="-- Select Interval in Months --" +COM_SCHEDULER_SELECT_PLG_JOB="Select job, %s" +COM_SCHEDULER_SELECT_TRIGGER="Trigger" +COM_SCHEDULER_SELECT_TYPE="- Cronjob Type -" +COM_SCHEDULER_TABLE_CAPTION="Cronjobs List" +COM_SCHEDULER_TRIGGER_CRON="Cron" +COM_SCHEDULER_TRIGGER_PSEUDOCRON="Pseudocron" +COM_SCHEDULER_TRIGGER_XVISITS="X-Visits" +COM_SCHEDULER_TYPE_CHOOSE="Select a Job type" +COM_SCHEDULER_TYPE_OR_SELECT_OPTIONS="Type or select options" +COM_SCHEDULER_TYPE_PLG="Plugin" +COM_SCHEDULER_TYPE_SCRIPT="CLI Script" +COM_SCHEDULER_XML_DESCRIPTION="Component for managing pseudo-cronjobs and cronjobs (if server supports)" diff --git a/administrator/language/en-GB/com_scheduler.sys.ini b/administrator/language/en-GB/com_scheduler.sys.ini new file mode 100644 index 0000000000000..f6bed32bc9747 --- /dev/null +++ b/administrator/language/en-GB/com_scheduler.sys.ini @@ -0,0 +1,13 @@ +; Joomla! Projects +; (C) 2021 Open Source Matters, Inc. +; GNU General Public License version 2 or later; see LICENSE.txt + +COM_SCHEDULER="Cronjobs" +COM_SCHEDULER_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW="You need to select a Job Type first!" +COM_SCHEDULER_ERROR_INVALID_JOB_TYPE="Invalid Job Type!" +COM_SCHEDULER_MANAGER_CRONJOB="Cronjob Manager" +COM_SCHEDULER_MANAGER_CRONJOB_EDIT="Edit Cronjob" +COM_SCHEDULER_MANAGER_CRONJOB_NEW="New Cronjob" +COM_SCHEDULER_MANAGER_CRONJOBS="Cronjobs Manager" +COM_SCHEDULER_MSG_MANAGE_NO_JOB_PLUGINS="There are no jobs types matching your query" +COM_SCHEDULER_XML_DESCRIPTION="Component for managing pseudo-cronjobs and cronjobs (if server supports)" diff --git a/build/media_source/com_scheduler/css/admin-plg-job.css b/build/media_source/com_scheduler/css/admin-plg-job.css new file mode 100644 index 0000000000000..e7330954d5939 --- /dev/null +++ b/build/media_source/com_scheduler/css/admin-plg-job.css @@ -0,0 +1,58 @@ +.new-job { + display: flex; + overflow: hidden; + color: hsl(var(--hue), 30%, 40%); + background-color: hsl(var(--hue), 60%, 97%); + border: 1px solid hsl(var(--hue), 50%, 93%); + border-radius: .25rem; +} + +.new-job-title { + margin-bottom: .25rem; + font-size: 1rem; + font-weight: 700; +} + +.new-job-link { + display: flex; + align-items: flex-end; + justify-content: center; + width: 2.5rem; + font-size: 1.2rem; + background: hsl(var(--hue), 50%, 93%); +} + +.new-job-caption { + display: box; + margin: 0; + overflow: hidden; + font-size: .875rem; + box-orient: vertical; + -webkit-line-clamp: 3; +} + +.new-job-details { + flex: 1 0; + padding: 1rem; +} + +.new-job * { + transition: all .25s ease; +} + +.new-job:hover .new-job-link { + background: var(--template-bg-dark); +} + +.new-job-link span { + margin-bottom: 10px; + color: hsl(var(--hue), 30%, 40%); +} + +.new-job:hover .new-job-link span { + color: #fff; +} + +.new-jobs .card-columns { + grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)) !important; +} diff --git a/build/media_source/com_scheduler/css/admin-view-cronjob.css b/build/media_source/com_scheduler/css/admin-view-cronjob.css new file mode 100644 index 0000000000000..fa9fea928e813 --- /dev/null +++ b/build/media_source/com_scheduler/css/admin-view-cronjob.css @@ -0,0 +1,24 @@ +.match-custom .control-group .control-label { + width: auto; + padding: 0 0 0 0; +} + +.match-custom .control-group .controls { + /* flex: 1; */ + display: inline-block; + min-width: 7rem; +} + +.match-custom .control-group { + /* display: flex; */ + display: inline-block; + margin-right: 1.5rem; +} + +.match-custom label { + font-size: small; +} + +.match-custom select[multiple] { + height: 15rem; +} diff --git a/build/media_source/com_cronjobs/joomla.asset.json b/build/media_source/com_scheduler/joomla.asset.json similarity index 54% rename from build/media_source/com_cronjobs/joomla.asset.json rename to build/media_source/com_scheduler/joomla.asset.json index c9888f3896c21..4248d5688970a 100644 --- a/build/media_source/com_cronjobs/joomla.asset.json +++ b/build/media_source/com_scheduler/joomla.asset.json @@ -1,14 +1,14 @@ { "$schema": "https://developer.joomla.org/schemas/json-schema/web_assets.json", - "name": "com_cronjobs", + "name": "com_scheduler", "version": "4.0.0", "description": "Joomla CMS", "license": "GNU General Public License version 2 or later; see LICENSE.txt", "assets": [ { - "name": "com_cronjobs.admin-plg-job-search.es5", + "name": "com_scheduler.admin-plg-job-search.es5", "type": "script", - "uri": "com_cronjobs/admin-plg-job-search-es5.js", + "uri": "com_scheduler/admin-plg-job-search-es5.js", "dependencies": [ "core" ], @@ -18,25 +18,25 @@ } }, { - "name": "com_cronjobs.admin-plg-job-search", + "name": "com_scheduler.admin-plg-job-search", "type": "script", - "uri": "com_cronjobs/admin-plg-job-search.js", + "uri": "com_scheduler/admin-plg-job-search.js", "dependencies": [ - "com_cronjobs.admin-plg-job-search.es5" + "com_scheduler.admin-plg-job-search.es5" ], "attributes": { "type" : "module" } }, { - "name": "com_cronjobs.admin-plg-job-css", + "name": "com_scheduler.admin-plg-job-css", "type": "style", - "uri": "com_cronjobs/admin-plg-job.css" + "uri": "com_scheduler/admin-plg-job.css" }, { - "name": "com_cronjobs.admin-view-cronjob-css", + "name": "com_scheduler.admin-view-cronjob-css", "type": "style", - "uri": "com_cronjobs/admin-view-cronjob.css" + "uri": "com_scheduler/admin-view-cronjob.css" } ] } diff --git a/build/media_source/com_cronjobs/js/admin-plg-job-search.es6.js b/build/media_source/com_scheduler/js/admin-plg-job-search.es6.js similarity index 96% rename from build/media_source/com_cronjobs/js/admin-plg-job-search.es6.js rename to build/media_source/com_scheduler/js/admin-plg-job-search.es6.js index 11598af71e0cf..2dc82719ed646 100644 --- a/build/media_source/com_cronjobs/js/admin-plg-job-search.es6.js +++ b/build/media_source/com_scheduler/js/admin-plg-job-search.es6.js @@ -49,7 +49,7 @@ if (elSearch && elSearchContainer) { let hasSearchResults = false; // Save the search string into session storage if (typeof sessionStorage !== 'undefined') { - sessionStorage.setItem('Joomla.com_cronjobs.new.search', partialSearch); + sessionStorage.setItem('Joomla.com_scheduler.new.search', partialSearch); } // Iterate all the job cards elCards.forEach((card) => { @@ -95,7 +95,7 @@ if (elSearch && elSearchContainer) { try { if (typeof sessionStorage !== 'undefined') { // Load the search string from session storage - elSearch.value = sessionStorage.getItem('Joomla.com_cronjobs.new.search') || ''; + elSearch.value = sessionStorage.getItem('Joomla.com_scheduler.new.search') || ''; // Trigger the keyboard handler event manually to initiate the search elSearch.dispatchEvent(new KeyboardEvent('keyup')); diff --git a/installation/sql/mysql/base.sql b/installation/sql/mysql/base.sql index e7d761153ff9f..2256ff2ee6e3c 100644 --- a/installation/sql/mysql/base.sql +++ b/installation/sql/mysql/base.sql @@ -106,7 +106,7 @@ INSERT INTO `#__assets` (`id`, `parent_id`, `lft`, `rgt`, `level`, `name`, `titl (86, 18, 122, 123, 2, 'com_modules.module.96', 'Popular Articles', '{}'), (87, 18, 124, 125, 2, 'com_modules.module.97', 'Recently Added Articles', '{}'), (88, 18, 126, 127, 2, 'com_modules.module.98', 'Logged-in Users', '{}'), -(89, 1, 161, 162, 1, 'com_cronjobs', 'com_cronjobs', '{}'); +(89, 1, 161, 162, 1, 'com_scheduler', 'com_scheduler', '{}'); -- -------------------------------------------------------- @@ -181,7 +181,7 @@ INSERT INTO `#__extensions` (`package_id`, `name`, `type`, `element`, `folder`, (0, 'com_actionlogs', 'component', 'com_actionlogs', '', 1, 1, 1, 0, 1, '', '{"ip_logging":0,"csv_delimiter":",","loggable_extensions":["com_banners","com_cache","com_categories","com_checkin","com_config","com_contact","com_content","com_installer","com_media","com_menus","com_messages","com_modules","com_newsfeeds","com_plugins","com_redirect","com_tags","com_templates","com_users"]}', ''), (0, 'com_workflow', 'component', 'com_workflow', '', 1, 1, 0, 1, 1, '', '{}', ''), (0, 'com_mails', 'component', 'com_mails', '', 1, 1, 1, 1, 1, '', '', ''), -(0, 'com_cronjobs', 'component', 'com_cronjobs', 1, 1, 1, 1, 0, 1, '', '', ''); +(0, 'com_scheduler', 'component', 'com_scheduler', 1, 1, 1, 1, 0, 1, '', '', ''); -- Libraries INSERT INTO `#__extensions` (`package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `locked`, `manifest_cache`, `params`, `custom_data`) VALUES diff --git a/installation/sql/postgresql/base.sql b/installation/sql/postgresql/base.sql index 03b9003ec5701..aba00bc7ee52a 100644 --- a/installation/sql/postgresql/base.sql +++ b/installation/sql/postgresql/base.sql @@ -112,7 +112,7 @@ INSERT INTO "#__assets" ("id", "parent_id", "lft", "rgt", "level", "name", "titl (86, 18, 122, 123, 2, 'com_modules.module.96', 'Popular Articles', '{}'), (87, 18, 124, 125, 2, 'com_modules.module.97', 'Recently Added Articles', '{}'), (88, 18, 126, 127, 2, 'com_modules.module.98', 'Logged-in Users', '{}'), -(89, 1, 161, 162, 1, 'com_cronjobs', 'com_cronjobs', '{}'); +(89, 1, 161, 162, 1, 'com_scheduler', 'com_scheduler', '{}'); SELECT setval('#__assets_id_seq', 89, false); @@ -187,7 +187,7 @@ INSERT INTO "#__extensions" ("package_id", "name", "type", "element", "folder", (0, 'com_actionlogs', 'component', 'com_actionlogs', '', 1, 1, 1, 0, 1, '', '{"ip_logging":0,"csv_delimiter":",","loggable_extensions":["com_banners","com_cache","com_categories","com_checkin","com_config","com_contact","com_content","com_installer","com_media","com_menus","com_messages","com_modules","com_newsfeeds","com_plugins","com_redirect","com_tags","com_templates","com_users"]}', '', 0, 0), (0, 'com_workflow', 'component', 'com_workflow', '', 1, 1, 0, 1, 1, '', '{}', '', 0, 0), (0, 'com_mails', 'component', 'com_mails', '', 1, 1, 1, 1, 1, '', '', '', 0, 0), -(0, 'com_cronjobs', 'component', 'com_cronjobs', 1, 1, 1, 1, 0, 1, '', '{}', '', 0, 0); +(0, 'com_scheduler', 'component', 'com_scheduler', 1, 1, 1, 1, 0, 1, '', '{}', '', 0, 0); -- Libraries INSERT INTO "#__extensions" ("package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "locked", "manifest_cache", "params", "custom_data", "ordering", "state") VALUES diff --git a/plugins/job/requests/requests.php b/plugins/job/requests/requests.php index 7c4b76894dbb8..e19d8be85d20a 100644 --- a/plugins/job/requests/requests.php +++ b/plugins/job/requests/requests.php @@ -58,7 +58,7 @@ class PlgJobRequests extends CMSPlugin implements SubscriberInterface * @since __DEPLOY_VERSION__ */ private $supportedFormContexts = [ - 'com_cronjobs.cronjob' + 'com_scheduler.cronjob' ]; /** @@ -113,7 +113,7 @@ public function enhanceForm(Event $event): void $context = $form->getName(); - if ($context === 'com_cronjobs.cronjob') + if ($context === 'com_scheduler.cronjob') { $this->enhanceCronjobItemForm($form, $data); } diff --git a/plugins/job/testjob/testjob.php b/plugins/job/testjob/testjob.php index c932d71a51f7e..b40f392a3f8c5 100644 --- a/plugins/job/testjob/testjob.php +++ b/plugins/job/testjob/testjob.php @@ -1,6 +1,6 @@ getName(); - if ($context === 'com_cronjobs.cronjob') + if ($context === 'com_scheduler.cronjob') { $this->enhanceCronjobItemForm($form, $data); } diff --git a/plugins/job/testjob/testjob.xml b/plugins/job/testjob/testjob.xml index c1ffa20c5320c..f6a74a0bc8756 100644 --- a/plugins/job/testjob/testjob.xml +++ b/plugins/job/testjob/testjob.xml @@ -5,7 +5,7 @@ July 2021 GNU General Public License version 2 or later; see LICENSE.txt 4.1 - Test jobs for com_cronjobs + Test jobs for com_scheduler testjob.php diff --git a/plugins/job/toggleoffline/toggleoffline.php b/plugins/job/toggleoffline/toggleoffline.php index f929a6cc7a242..17b44df260e2a 100644 --- a/plugins/job/toggleoffline/toggleoffline.php +++ b/plugins/job/toggleoffline/toggleoffline.php @@ -77,7 +77,7 @@ class PlgJobToggleoffline extends CMSPlugin implements SubscriberInterface * @since __DEPLOY_VERSION__ */ private $supportedFormContexts = [ - 'com_cronjobs.cronjob' + 'com_scheduler.cronjob' ]; /** diff --git a/plugins/system/cronjobs/cronjobs.php b/plugins/system/cronjobs/cronjobs.php index 65550e95a999c..403f0eaaa9338 100644 --- a/plugins/system/cronjobs/cronjobs.php +++ b/plugins/system/cronjobs/cronjobs.php @@ -115,8 +115,8 @@ class PlgSystemCronjobs extends CMSPlugin implements SubscriberInterface */ public function __construct(&$subject, $config = []) { - // Make sure com_cronjobs is installed and enabled - if (! ComponentHelper::isEnabled('com_cronjobs')) + // Make sure com_scheduler is installed and enabled + if (! ComponentHelper::isEnabled('com_scheduler')) { return; } @@ -158,7 +158,7 @@ public function executeDueJob(Event $event): void $this->snapshot['startTime'] = microtime(true); /** @var MVCComponent $component */ - $component = $this->app->bootComponent('com_cronjobs'); + $component = $this->app->bootComponent('com_scheduler'); /** @var CronjobsModel $model */ $model = $component->getMVCFactory()->createModel('Cronjobs', 'Administrator'); diff --git a/plugins/system/cronjobs/language/en-GB/en-GB.plg_system.cronjobs.sys.ini b/plugins/system/cronjobs/language/en-GB/en-GB.plg_system.cronjobs.sys.ini index 3bd457b57b19b..6959d041efe4b 100644 --- a/plugins/system/cronjobs/language/en-GB/en-GB.plg_system.cronjobs.sys.ini +++ b/plugins/system/cronjobs/language/en-GB/en-GB.plg_system.cronjobs.sys.ini @@ -3,4 +3,4 @@ ; GNU General Public License version 2 or later; see LICENSE.txt PLG_SYSTEM_CRONJOBS="System - Cronjobs Scheduler" -PLG_SYSTEM_CRONJOBS_XML_DESCRIPTION="This plugin lazy runs due cronjobs managed through com_cronjobs." +PLG_SYSTEM_CRONJOBS_XML_DESCRIPTION="This plugin lazy runs due cronjobs managed through >." diff --git a/plugins/system/cronjobs/language/en-GB/en-GB.plg_system_cronjobs.ini b/plugins/system/cronjobs/language/en-GB/en-GB.plg_system_cronjobs.ini index 7436b602839a7..cf578efb43528 100644 --- a/plugins/system/cronjobs/language/en-GB/en-GB.plg_system_cronjobs.ini +++ b/plugins/system/cronjobs/language/en-GB/en-GB.plg_system_cronjobs.ini @@ -8,4 +8,4 @@ PLG_SYSTEM_CRONJOBS_RUN_COMPLETE="Finished job#%02d in %.2f seconds with exit co PLG_SYSTEM_CRONJOBS_START="Running job#%02d '%s'." ; Maybe not this PLG_SYSTEM_CRONJOBS_UNLOCKED="Job#%02d was unlocked." -PLG_SYSTEM_CRONJOBS_XML_DESCRIPTION="This plugin lazy runs due cronjobs managed through com_cronjobs." +PLG_SYSTEM_CRONJOBS_XML_DESCRIPTION="This plugin lazy runs due cronjobs managed through >." From 5db3fe56efe7aa6c9e0ff59563cd62399a28c29d Mon Sep 17 00:00:00 2001 From: ditsuke Date: Fri, 20 Aug 2021 23:26:35 +0530 Subject: [PATCH 306/615] Refactor com_cronjobs [2] - Update language files: - Update cronjob(s) refs - 'Cronjobs' (component) => 'Scheduled Tasks' - 'Cronjob'(s) => 'Task'(s) - 'Job' => 'Task' - Remove unneeded constants --- .../language/en-GB/com_scheduler.ini | 78 +++++++++---------- .../language/en-GB/com_scheduler.sys.ini | 16 ++-- 2 files changed, 44 insertions(+), 50 deletions(-) diff --git a/administrator/language/en-GB/com_scheduler.ini b/administrator/language/en-GB/com_scheduler.ini index ea1cf5c511cfb..bb603011ca26d 100644 --- a/administrator/language/en-GB/com_scheduler.ini +++ b/administrator/language/en-GB/com_scheduler.ini @@ -2,16 +2,14 @@ ; (C) 2021 Open Source Matters, Inc. ; GNU General Public License version 2 or later; see LICENSE.txt -COM_SCHEDULER="Cronjobs" -COM_SCHEDULER_CLI_JOBS_DESC="Configure a CLI script to run at a scheduled interval or another condition." -COM_SCHEDULER_CLI_JOBS_TITLE="CLI/Script Job" -COM_SCHEDULER_DASHBOARD_TITLE="Cronjobs Manager" -COM_SCHEDULER_EDIT_CRONJOB="Edit Cronjob" -COM_SCHEDULER_EMPTYSTATE_BUTTON_ADD="Add a Cronjob!" -COM_SCHEDULER_EMPTYSTATE_CONTENT="No cronjobs!" -COM_SCHEDULER_EMPTYSTATE_TITLE="No Cronjobs have been created yet!" -COM_SCHEDULER_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW="You need to select a Job Type first!" -COM_SCHEDULER_ERROR_INVALID_JOB_TYPE="Invalid Job Type!" +COM_SCHEDULER="Scheduled Tasks" +COM_SCHEDULER_DASHBOARD_TITLE="Scheduled Tasks Manager" +COM_SCHEDULER_EDIT_CRONJOB="Edit Task" +COM_SCHEDULER_EMPTYSTATE_BUTTON_ADD="Add a Task!" +COM_SCHEDULER_EMPTYSTATE_CONTENT="No Tasks!" +COM_SCHEDULER_EMPTYSTATE_TITLE="No Tasks have been created yet!" +COM_SCHEDULER_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW="You need to select a Task type first!" +COM_SCHEDULER_ERROR_INVALID_JOB_TYPE="Invalid Task Type!" COM_SCHEDULER_FIELD_JOB_TYPE="Type ID" COM_SCHEDULER_FIELD_LABEL_EXEC_RULE="Execution Rule" COM_SCHEDULER_FIELD_LABEL_INTERVAL_DAYS="Interval in Days" @@ -25,18 +23,18 @@ COM_SCHEDULER_FIELD_OPTION_INTERVAL_MATCH_HOURS="Hours" COM_SCHEDULER_FIELD_OPTION_INTERVAL_MATCH_MINUTES="Minutes" COM_SCHEDULER_FIELD_OPTION_INTERVAL_MATCH_MONTHS="Months" COM_SCHEDULER_FIELDSET_BASIC="Basic Fields" -COM_SCHEDULER_FIELDSET_CRON_OPTIONS="Cron Options" +COM_SCHEDULER_FIELDSET_CRON_OPTIONS="Cron Match" COM_SCHEDULER_FIELDSET_EXEC_HIST="Execution History" -COM_SCHEDULER_FIELDSET_PARAMS_FS="Job Parameters" -COM_SCHEDULER_FILTER_SEARCH_DESC="Search in cronjob title and note. Prefix with 'ID:' to search for a job ID" +COM_SCHEDULER_FIELDSET_PARAMS_FS="Task Parameters" +COM_SCHEDULER_FILTER_SEARCH_DESC="Search in Task title and note. Prefix with 'ID:' to search for a task ID" COM_SCHEDULER_FILTER_SEARCH_LABEL="Search Cronjobs" -COM_SCHEDULER_FORM_TITLE_EDIT="Edit Cronjob" -COM_SCHEDULER_FORM_TITLE_NEW="New Cronjob" +COM_SCHEDULER_FORM_TITLE_EDIT="Edit Task" +COM_SCHEDULER_FORM_TITLE_NEW="New Task" COM_SCHEDULER_HEADING_JOB_TYPE="- Job Type -" -COM_SCHEDULER_JOB_LOG_PREFIX="Job> " -COM_SCHEDULER_JOB_TYPE="Job Type" -COM_SCHEDULER_JOB_TYPE_ASC="Job Type Ascending" -COM_SCHEDULER_JOB_TYPE_DESC="Job Type Descending" +COM_SCHEDULER_JOB_LOG_PREFIX="Task> " +COM_SCHEDULER_JOB_TYPE="Task Type" +COM_SCHEDULER_JOB_TYPE_ASC="Task Type Ascending" +COM_SCHEDULER_JOB_TYPE_DESC="Task Type Descending" COM_SCHEDULER_LABEL_EXEC_DAY="Execution Day" COM_SCHEDULER_LABEL_EXEC_INTERVAL="Execution Interval" COM_SCHEDULER_LABEL_EXEC_TIME="Execution Time (UTC)" @@ -46,23 +44,22 @@ COM_SCHEDULER_LABEL_LAST_EXEC="Last Executed" COM_SCHEDULER_LABEL_MINUTES="Minutes" COM_SCHEDULER_LABEL_NEXT_EXEC="Next Execution" COM_SCHEDULER_LABEL_NOTES="Notes" -COM_SCHEDULER_LABEL_PLG_JOB_ID="Plugin Job ID" COM_SCHEDULER_LABEL_TIMES_EXEC="Times Executed" COM_SCHEDULER_LABEL_TIMES_FAIL="Times Failed" -COM_SCHEDULER_MANAGER_CRONJOB="Cronjob Manager" -COM_SCHEDULER_MANAGER_CRONJOB_EDIT="Edit Cronjob" -COM_SCHEDULER_MANAGER_CRONJOB_NEW="New Cronjob" -COM_SCHEDULER_MANAGER_CRONJOBS="Cronjobs Manager" -COM_SCHEDULER_MSG_MANAGE_NO_JOB_PLUGINS="There are no jobs types matching your query" -COM_SCHEDULER_N_ITEMS_DELETED="%s cronjobs deleted." -COM_SCHEDULER_N_ITEMS_DELETED_1="Cronjob deleted." -COM_SCHEDULER_N_ITEMS_PUBLISHED="%s cronjobs enabled." -COM_SCHEDULER_N_ITEMS_PUBLISHED_1="Cronjob enabled." -COM_SCHEDULER_N_ITEMS_TRASHED="%s cronjobs trashed." -COM_SCHEDULER_N_ITEMS_TRASHED_1="Cronjob trashed." -COM_SCHEDULER_N_ITEMS_UNPUBLISHED="%s cronjobs disabled." -COM_SCHEDULER_N_ITEMS_UNPUBLISHED_1="Cronjob disabled." -COM_SCHEDULER_NEW_CRONJOB="New Cronjob" +COM_SCHEDULER_MANAGER_CRONJOB="Task Manager" +COM_SCHEDULER_MANAGER_CRONJOB_EDIT="Edit Task" +COM_SCHEDULER_MANAGER_CRONJOB_NEW="New Task" +COM_SCHEDULER_MANAGER_CRONJOBS="Tasks Manager" +COM_SCHEDULER_MSG_MANAGE_NO_JOB_PLUGINS="There are no task types matching your query!" +COM_SCHEDULER_N_ITEMS_DELETED="%s tasks deleted." +COM_SCHEDULER_N_ITEMS_DELETED_1="Task deleted." +COM_SCHEDULER_N_ITEMS_PUBLISHED="%s tasks enabled." +COM_SCHEDULER_N_ITEMS_PUBLISHED_1="Task enabled." +COM_SCHEDULER_N_ITEMS_TRASHED="%s tasks trashed." +COM_SCHEDULER_N_ITEMS_TRASHED_1="Task trashed." +COM_SCHEDULER_N_ITEMS_UNPUBLISHED="%s tasks disabled." +COM_SCHEDULER_N_ITEMS_UNPUBLISHED_1="Task disabled." +COM_SCHEDULER_NEW_CRONJOB="New Task" COM_SCHEDULER_NO_NOTE="" COM_SCHEDULER_OPTION_INTERVAL_CUSTOM="Custom Match (Advanced)" COM_SCHEDULER_OPTION_INTERVAL_DAYS="Interval, Days" @@ -71,21 +68,18 @@ COM_SCHEDULER_OPTION_INTERVAL_MINUTES="Interval, Minutes" COM_SCHEDULER_OPTION_INTERVAL_MONTHS="Interval, Months" COM_SCHEDULER_OPTION_ORPHANED_HIDE="Hide Orphaned" COM_SCHEDULER_OPTION_ORPHANED_SHOW="Show Orphaned" -COM_SCHEDULER_SELECT_CLI_JOB="Select CLI job" COM_SCHEDULER_SELECT_EXEC_RULE="--- Select Rule ---" COM_SCHEDULER_SELECT_INTERVAL_DAYS="-- Select Interval in Days --" COM_SCHEDULER_SELECT_INTERVAL_HOURS="-- Select Interval in Hours --" COM_SCHEDULER_SELECT_INTERVAL_MINUTES="-- Select Interval in Minutes --" COM_SCHEDULER_SELECT_INTERVAL_MONTHS="-- Select Interval in Months --" -COM_SCHEDULER_SELECT_PLG_JOB="Select job, %s" +COM_SCHEDULER_SELECT_PLG_JOB="Select task, %s" COM_SCHEDULER_SELECT_TRIGGER="Trigger" -COM_SCHEDULER_SELECT_TYPE="- Cronjob Type -" -COM_SCHEDULER_TABLE_CAPTION="Cronjobs List" +COM_SCHEDULER_SELECT_TYPE="- Task Type -" +COM_SCHEDULER_TABLE_CAPTION="Tasks List" COM_SCHEDULER_TRIGGER_CRON="Cron" COM_SCHEDULER_TRIGGER_PSEUDOCRON="Pseudocron" COM_SCHEDULER_TRIGGER_XVISITS="X-Visits" -COM_SCHEDULER_TYPE_CHOOSE="Select a Job type" +COM_SCHEDULER_TYPE_CHOOSE="Select a Task type" COM_SCHEDULER_TYPE_OR_SELECT_OPTIONS="Type or select options" -COM_SCHEDULER_TYPE_PLG="Plugin" -COM_SCHEDULER_TYPE_SCRIPT="CLI Script" -COM_SCHEDULER_XML_DESCRIPTION="Component for managing pseudo-cronjobs and cronjobs (if server supports)" +COM_SCHEDULER_XML_DESCRIPTION="Component for managing scheduled tasks and cronjobs (if supported by the server)" diff --git a/administrator/language/en-GB/com_scheduler.sys.ini b/administrator/language/en-GB/com_scheduler.sys.ini index f6bed32bc9747..171a450771f31 100644 --- a/administrator/language/en-GB/com_scheduler.sys.ini +++ b/administrator/language/en-GB/com_scheduler.sys.ini @@ -3,11 +3,11 @@ ; GNU General Public License version 2 or later; see LICENSE.txt COM_SCHEDULER="Cronjobs" -COM_SCHEDULER_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW="You need to select a Job Type first!" -COM_SCHEDULER_ERROR_INVALID_JOB_TYPE="Invalid Job Type!" -COM_SCHEDULER_MANAGER_CRONJOB="Cronjob Manager" -COM_SCHEDULER_MANAGER_CRONJOB_EDIT="Edit Cronjob" -COM_SCHEDULER_MANAGER_CRONJOB_NEW="New Cronjob" -COM_SCHEDULER_MANAGER_CRONJOBS="Cronjobs Manager" -COM_SCHEDULER_MSG_MANAGE_NO_JOB_PLUGINS="There are no jobs types matching your query" -COM_SCHEDULER_XML_DESCRIPTION="Component for managing pseudo-cronjobs and cronjobs (if server supports)" +COM_SCHEDULER_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW="You need to select a Task type first!" +COM_SCHEDULER_ERROR_INVALID_JOB_TYPE="Invalid Task Type!" +COM_SCHEDULER_MANAGER_CRONJOB="Task Manager" +COM_SCHEDULER_MANAGER_CRONJOB_EDIT="Edit Task" +COM_SCHEDULER_MANAGER_CRONJOB_NEW="New Task" +COM_SCHEDULER_MANAGER_CRONJOBS="Tasks Manager" +COM_SCHEDULER_MSG_MANAGE_NO_JOB_PLUGINS="There are no task types matching your query!" +COM_SCHEDULER_XML_DESCRIPTION="Component for managing scheduled tasks and cronjobs (if supported by the server)" From fb4c66708fedd3462b139bd56e4afa841ac63113 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Fri, 20 Aug 2021 23:43:04 +0530 Subject: [PATCH 307/615] Refactor com_cronjobs [3] Updates language constants and usages to new branding. --- .../com_scheduler/forms/cronjob.xml | 2 +- .../com_scheduler/forms/filter_cronjobs.xml | 4 +-- .../src/Controller/CronjobController.php | 2 +- .../src/Traits/CronjobPluginTrait.php | 2 +- .../src/View/Cronjob/HtmlView.php | 2 +- .../src/View/Cronjobs/HtmlView.php | 2 +- .../src/View/Select/HtmlView.php | 2 +- .../com_scheduler/tmpl/cronjob/edit.php | 2 +- .../com_scheduler/tmpl/cronjobs/default.php | 2 +- .../com_scheduler/tmpl/select/default.php | 4 +-- .../language/en-GB/com_scheduler.ini | 32 +++++++++---------- .../language/en-GB/com_scheduler.sys.ini | 14 ++++---- 12 files changed, 35 insertions(+), 35 deletions(-) diff --git a/administrator/components/com_scheduler/forms/cronjob.xml b/administrator/components/com_scheduler/forms/cronjob.xml index bb2399705832b..284d855144a10 100644 --- a/administrator/components/com_scheduler/forms/cronjob.xml +++ b/administrator/components/com_scheduler/forms/cronjob.xml @@ -95,7 +95,7 @@ JSTATUS_DESC - - + + option . '&view=select&layout=edit'; $this->setRedirect(Route::_($redirectUrl, false)); - $app->enqueueMessage(Text::_('COM_SCHEDULER_ERROR_INVALID_JOB_TYPE'), 'warning'); + $app->enqueueMessage(Text::_('COM_SCHEDULER_ERROR_INVALID_TASK_TYPE'), 'warning'); $canAdd = false; } diff --git a/administrator/components/com_scheduler/src/Traits/CronjobPluginTrait.php b/administrator/components/com_scheduler/src/Traits/CronjobPluginTrait.php index cbad03a6f2784..b4b263546f413 100644 --- a/administrator/components/com_scheduler/src/Traits/CronjobPluginTrait.php +++ b/administrator/components/com_scheduler/src/Traits/CronjobPluginTrait.php @@ -219,6 +219,6 @@ protected function addJobLog(string $message, string $priority = 'info'): void $langLoaded = true; } - Log::add(Text::_('COM_SCHEDULER_JOB_LOG_PREFIX') . $message, $priorityMap[$priority] ?? Log::INFO, 'cronjobs'); + Log::add(Text::_('COM_SCHEDULER_TASK_LOG_PREFIX') . $message, $priorityMap[$priority] ?? Log::INFO, 'cronjobs'); } } diff --git a/administrator/components/com_scheduler/src/View/Cronjob/HtmlView.php b/administrator/components/com_scheduler/src/View/Cronjob/HtmlView.php index 8ecd607483366..a16ac4aab1ebc 100644 --- a/administrator/components/com_scheduler/src/View/Cronjob/HtmlView.php +++ b/administrator/components/com_scheduler/src/View/Cronjob/HtmlView.php @@ -133,7 +133,7 @@ protected function addToolbar(): void $isNew = ($this->item->id == 0); $canDo = $this->canDo; - ToolbarHelper::title($isNew ? Text::_('COM_SCHEDULER_MANAGER_CRONJOB_NEW') : Text::_('COM_SCHEDULER_MANAGER_CRONJOB_EDIT'), 'clock'); + ToolbarHelper::title($isNew ? Text::_('COM_SCHEDULER_MANAGER_TASK_NEW') : Text::_('COM_SCHEDULER_MANAGER_TASK_EDIT'), 'clock'); // Goes into ToolbarHelper::saveGroup() $toolbarButtons = []; diff --git a/administrator/components/com_scheduler/src/View/Cronjobs/HtmlView.php b/administrator/components/com_scheduler/src/View/Cronjobs/HtmlView.php index 89ac654c75c3f..5fb1b3c683f37 100644 --- a/administrator/components/com_scheduler/src/View/Cronjobs/HtmlView.php +++ b/administrator/components/com_scheduler/src/View/Cronjobs/HtmlView.php @@ -151,7 +151,7 @@ protected function addToolbar(): void */ $toolbar = Toolbar::getInstance('toolbar'); - ToolbarHelper::title(Text::_('COM_SCHEDULER_MANAGER_CRONJOBS'), 'clock'); + ToolbarHelper::title(Text::_('COM_SCHEDULER_MANAGER_TASKS'), 'clock'); if ($canDo->get('core.create')) { diff --git a/administrator/components/com_scheduler/src/View/Select/HtmlView.php b/administrator/components/com_scheduler/src/View/Select/HtmlView.php index ca975ab043d19..540a93ea76b94 100644 --- a/administrator/components/com_scheduler/src/View/Select/HtmlView.php +++ b/administrator/components/com_scheduler/src/View/Select/HtmlView.php @@ -129,7 +129,7 @@ protected function addToolbar(): void $toolbar = Toolbar::getInstance(); // Add page title - ToolbarHelper::title(Text::_('COM_SCHEDULER_MANAGER_CRONJOBS'), 'clock'); + ToolbarHelper::title(Text::_('COM_SCHEDULER_MANAGER_TASKS'), 'clock'); $toolbar->linkButton('cancel') ->url('index.php?option=com_scheduler') diff --git a/administrator/components/com_scheduler/tmpl/cronjob/edit.php b/administrator/components/com_scheduler/tmpl/cronjob/edit.php index 5ee8a4dbb943e..86089ada80f30 100644 --- a/administrator/components/com_scheduler/tmpl/cronjob/edit.php +++ b/administrator/components/com_scheduler/tmpl/cronjob/edit.php @@ -59,7 +59,7 @@ class="form-validate"> item->id) ? Text::_('COM_SCHEDULER_NEW_CRONJOB') : Text::_('COM_SCHEDULER_EDIT_CRONJOB') + empty($this->item->id) ? Text::_('COM_SCHEDULER_NEW_TASK') : Text::_('COM_SCHEDULER_EDIT_TASK') ); ?>

diff --git a/administrator/components/com_scheduler/tmpl/cronjobs/default.php b/administrator/components/com_scheduler/tmpl/cronjobs/default.php index 1849f3434e72c..61e14a9581ac8 100644 --- a/administrator/components/com_scheduler/tmpl/cronjobs/default.php +++ b/administrator/components/com_scheduler/tmpl/cronjobs/default.php @@ -101,7 +101,7 @@ class="visually-hidden">
- +
- + @@ -92,22 +92,22 @@ class="visually-hidden"> - + - + - + - + @@ -158,13 +158,13 @@ class="js-draggable" data-url="" data-direction=" - + + + + + +
@@ -77,7 +77,7 @@ class="visually-hidden">
- state, $i, 'cronjobs.', $canChange); ?> + state, $i, 'tasks.', $canChange); ?> - escape($item->title); ?> escape($item->title); ?> diff --git a/administrator/components/com_scheduler/tmpl/cronjobs/default.xml b/administrator/components/com_scheduler/tmpl/cronjobs/default.xml index d292320fa0267..2a93aaf81afb6 100644 --- a/administrator/components/com_scheduler/tmpl/cronjobs/default.xml +++ b/administrator/components/com_scheduler/tmpl/cronjobs/default.xml @@ -1,8 +1,8 @@ - + - + diff --git a/administrator/components/com_scheduler/tmpl/cronjobs/default_batch_footer.php b/administrator/components/com_scheduler/tmpl/cronjobs/default_batch_footer.php index d683fc38afd94..ee4e2d2c7f8f3 100644 --- a/administrator/components/com_scheduler/tmpl/cronjobs/default_batch_footer.php +++ b/administrator/components/com_scheduler/tmpl/cronjobs/default_batch_footer.php @@ -16,6 +16,6 @@ data-bs-dismiss="modal"> - diff --git a/administrator/components/com_scheduler/tmpl/cronjobs/empty_state.php b/administrator/components/com_scheduler/tmpl/cronjobs/empty_state.php index 8cf1dcc6d730c..5ce326cf675b8 100644 --- a/administrator/components/com_scheduler/tmpl/cronjobs/empty_state.php +++ b/administrator/components/com_scheduler/tmpl/cronjobs/empty_state.php @@ -14,7 +14,7 @@ $displayData = [ 'textPrefix' => 'COM_SCHEDULER', - 'formURL' => 'index.php?option=com_scheduler&task=cronjob.add', + 'formURL' => 'index.php?option=com_scheduler&task=task.add', 'helpURL' => 'https://github.com/joomla-projects/soc21_website-cronjob', 'icon' => 'icon-clock clock', ]; diff --git a/administrator/components/com_scheduler/tmpl/select/default.php b/administrator/components/com_scheduler/tmpl/select/default.php index a44be83111f86..1bb780235b530 100644 --- a/administrator/components/com_scheduler/tmpl/select/default.php +++ b/administrator/components/com_scheduler/tmpl/select/default.php @@ -36,16 +36,16 @@ * endif;*/ ?> - -
+ +
-
+ + + @@ -184,6 +194,14 @@ class="js-draggable" data-url="" data-direction=" escape($item->safeTypeTitle); ?> + + + + id; ?> @@ -196,7 +214,24 @@ class="js-draggable" data-url="" data-direction=" pagination->getListFooter(); + + // Modal for test runs + $modalparams = [ + 'title' => Text::_('COM_SCHEDULER_TEST_RUN_TITLE') + ]; + + $modalbody = '
'; + $modalbody .= '

' . Text::_('COM_SCHEDULER_TEST_RUN_TASK') . '

'; + $modalbody .= '
    '; + $modalbody .= '
  • ' . Text::_('COM_SCHEDULER_TEST_RUN_STATUS_STARTED') . '
  • '; + $modalbody .= '
  • '; + $modalbody .= '
'; + $modalbody .= '
'; + + echo HTMLHelper::_('bootstrap.renderModal', 'scheduler-test-modal', $modalparams, $modalbody); + ?> + diff --git a/administrator/language/en-GB/com_scheduler.ini b/administrator/language/en-GB/com_scheduler.ini index c1f72592c210f..ad2bcafc31322 100644 --- a/administrator/language/en-GB/com_scheduler.ini +++ b/administrator/language/en-GB/com_scheduler.ini @@ -115,6 +115,13 @@ COM_SCHEDULER_TASK_TYPE_ASC="Task Type Ascending" COM_SCHEDULER_TASK_TYPE_DESC="Task Type Descending" COM_SCHEDULER_TASKS_VIEW_DEFAULT_DESC="Schedule and Manage Task Routines." COM_SCHEDULER_TASKS_VIEW_DEFAULT_TITLE="Scheduled Tasks Manager" +COM_SCHEDULER_TEST_TASK="Test task" +COM_SCHEDULER_TEST_RUN="Run Test" +COM_SCHEDULER_TEST_RUN_STATUS_COMPLETED="Status: Completed" +COM_SCHEDULER_TEST_RUN_STATUS_STARTED="Status: Started" +COM_SCHEDULER_TEST_RUN_STATUS_TERMINATED="Status: Terminated" +COM_SCHEDULER_TEST_RUN_TASK="Task: \"%s\"" +COM_SCHEDULER_TEST_RUN_TITLE="Test task (%d)" COM_SCHEDULER_TRIGGER_CRON="Cron" COM_SCHEDULER_TRIGGER_PSEUDOCRON="Pseudocron" COM_SCHEDULER_TRIGGER_XVISITS="X-Visits" diff --git a/build/media_source/com_scheduler/joomla.asset.json b/build/media_source/com_scheduler/joomla.asset.json index fc304820625a0..3dfd4633a10c6 100644 --- a/build/media_source/com_scheduler/joomla.asset.json +++ b/build/media_source/com_scheduler/joomla.asset.json @@ -5,6 +5,29 @@ "description": "Joomla CMS", "license": "GNU General Public License version 2 or later; see LICENSE.txt", "assets": [ + { + "name": "com_scheduler.test-task.es5", + "type": "script", + "uri": "com_scheduler/admin-view-run-test-task-es5.js", + "dependencies": [ + "core" + ], + "attributes": { + "nomodule": true, + "defer": true + } + }, + { + "name": "com_scheduler.test-task", + "type": "script", + "uri": "com_scheduler/admin-view-run-test-task.js", + "dependencies": [ + "com_scheduler.test-task.es5" + ], + "attributes": { + "type" : "module" + } + }, { "name": "com_scheduler.admin-view-select-task-search.es5", "type": "script", diff --git a/build/media_source/com_scheduler/js/admin-view-run-test-task.es6.js b/build/media_source/com_scheduler/js/admin-view-run-test-task.es6.js new file mode 100644 index 0000000000000..324cf89f72e70 --- /dev/null +++ b/build/media_source/com_scheduler/js/admin-view-run-test-task.es6.js @@ -0,0 +1,41 @@ +/** + * @copyright (C) 2021 Open Source Matters, Inc. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +/** + * Run the test task in the scheduler backend list + * + * Used for the play button in the list view + * + * @package Joomla.Components + * @subpackage Scheduler.Tasks + * + * @since __DEPLOY_VERSION__ + */ +if (!window.Joomla) { + throw new Error('Joomla API was not properly initialised'); +} + +const initRunner = () => { + const modal = document.getElementById('scheduler-test-modal'); + + modal.addEventListener('open.bd.modal', () => { + alert('test'); + }); + const options = Joomla.getOptions('plg_system_schedulerunner'); + const paths = Joomla.getOptions('system.paths'); + const interval = (options && options.inverval ? parseInt(options.interval, 10) : 300) * 1000; + const uri = `${paths ? `${paths.root}/index.php` : window.location.pathname}?option=com_ajax&format=raw&plugin=RunSchedulerLazy&group=system`; + + setInterval(() => navigator.sendBeacon(uri), interval); + + // Run it at the beginning at least once + navigator.sendBeacon(uri); +}; + +((document) => { + document.addEventListener('DOMContentLoaded', () => { + initRunner(); + }); +})(document); diff --git a/build/media_source/plg_system_schedulerunner/js/run-schedule.es6.js b/build/media_source/plg_system_schedulerunner/js/run-schedule.es6.js index c5b0846d204ab..c2d1e92418a82 100644 --- a/build/media_source/plg_system_schedulerunner/js/run-schedule.es6.js +++ b/build/media_source/plg_system_schedulerunner/js/run-schedule.es6.js @@ -17,13 +17,20 @@ if (!window.Joomla) { throw new Error('Joomla API was not properly initialised'); } -const scheduleRunnerOptions = Joomla.getOptions('plg_system_schedulerunner'); -const systemPaths = Joomla.getOptions('system.paths'); +const initScheduler = () => { + const options = Joomla.getOptions('plg_system_schedulerunner'); + const paths = Joomla.getOptions('system.paths'); + const interval = (options && options.inverval ? parseInt(options.interval, 10) : 300) * 1000; + const uri = `${paths ? `${paths.root}/index.php` : window.location.pathname}?option=com_ajax&format=raw&plugin=RunSchedulerLazy&group=system`; -const scheduleRunnerInterval = (scheduleRunnerOptions && scheduleRunnerOptions.interval ? parseInt(scheduleRunnerOptions.interval, 10) : 300) * 1000; -const scheduleRunnerUri = `${(systemPaths ? `${systemPaths.root}/index.php` : window.location.pathname)}?option=com_ajax&format=raw&plugin=RunSchedulerLazy&group=system`; + setInterval(() => navigator.sendBeacon(uri), interval); -setInterval(() => navigator.sendBeacon(scheduleRunnerUri), scheduleRunnerInterval); + // Run it at the beginning at least once + navigator.sendBeacon(uri); +}; -// Run it at the beginning at least once -navigator.sendBeacon(scheduleRunnerUri); +((document) => { + document.addEventListener('DOMContentLoaded', () => { + initScheduler(); + }); +})(document); From 63bf24b726b3eab2373264250ce0a33b1691960a Mon Sep 17 00:00:00 2001 From: Benjamin Trenkle Date: Wed, 27 Oct 2021 03:23:19 +0200 Subject: [PATCH 509/615] Finish test cron --- .../com_scheduler/src/Model/TasksModel.php | 10 +-- .../com_scheduler/src/Scheduler/Scheduler.php | 51 +++++++------ .../com_scheduler/src/Task/Task.php | 26 +++++-- .../src/Traits/TaskPluginTrait.php | 1 + .../com_scheduler/tmpl/tasks/default.php | 24 +++--- .../language/en-GB/com_scheduler.ini | 4 +- .../js/admin-view-run-test-task.es6.js | 76 +++++++++++++++---- libraries/src/Console/TasksRunCommand.php | 3 +- .../system/schedulerunner/schedulerunner.php | 31 ++++---- .../tasknotification/tasknotification.php | 25 +++--- plugins/task/requests/requests.php | 2 +- 11 files changed, 164 insertions(+), 89 deletions(-) diff --git a/administrator/components/com_scheduler/src/Model/TasksModel.php b/administrator/components/com_scheduler/src/Model/TasksModel.php index 415df41c1813a..7d9ca764f5d84 100644 --- a/administrator/components/com_scheduler/src/Model/TasksModel.php +++ b/administrator/components/com_scheduler/src/Model/TasksModel.php @@ -176,15 +176,13 @@ protected function getListQuery(): QueryInterface if (is_numeric($state)) { - $filterCount++; $state = (int) $state; - $query->where($db->quoteName('a.state') . '= :state') - ->bind(':state', $state); + $query->where($db->quoteName('a.state') . ' = :state') + ->bind(':state', $state, ParameterType::INTEGER); } - elseif ($state == null) + elseif ($state === '') { - $filterCount++; - $query->whereIn($db->quoteName('a.state'), [0, 1]); + $query->where($db->quoteName('a.state') . ' IN (0, 1)'); } // Filter over type ---- diff --git a/administrator/components/com_scheduler/src/Scheduler/Scheduler.php b/administrator/components/com_scheduler/src/Scheduler/Scheduler.php index 0cbab6a1f8f99..1563521f4db60 100644 --- a/administrator/components/com_scheduler/src/Scheduler/Scheduler.php +++ b/administrator/components/com_scheduler/src/Scheduler/Scheduler.php @@ -96,21 +96,21 @@ public function __construct() * Run a scheduled task. * Runs a single due task from the task queue by default if $id and $title are not passed. * - * @param int $id The task ID - * @param string|null $title The task title + * @param int $id The task ID + * @param bool $unpublished The task title * - * @return integer The task exit code. + * @return Task|null The task executed or null if not exists * * @throws AssertionFailedException|\Exception * @since __DEPLOY_VERSION__ */ - public function runTask(int $id = 0, ?string $title = ''): int + public function runTask(int $id = 0, bool $unpublished = false): ?Task { - $task = $this->fetchTask($id, $title); + $task = $this->fetchTask($id, $unpublished); if (empty($task)) { - return Status::NO_TASK; + return null; } $options['text_entry_format'] = '{DATE} {TIME} {PRIORITY} {MESSAGE}'; @@ -139,31 +139,31 @@ public function runTask(int $id = 0, ?string $title = ''): int $level = $exitCode === Status::OK ? 'info' : 'warning'; $task->log(Text::sprintf(self::LOG_TEXT[$exitCode], $taskId, $duration, $netDuration), $level); - return $exitCode; + return $task; } $task->log(Text::sprintf('COM_SCHEDULER_SCHEDULER_TASK_UNKNOWN_EXIT', $taskId, $duration, $netDuration, $exitCode), 'warning' ); - return $exitCode; + return $task; } /** * Fetches a single scheduled task in a Task instance. * If no id or title is specified, a due task is returned. * - * @param int|null $id The task ID - * @param string|null $title The task title + * @param int $id The task ID + * @param bool $unpublished The task title * * @return ?Task * * @throws \Exception * @since __DEPLOY_VERSION__ */ - public function fetchTask(int $id = 0, string $title = ''): ?Task + public function fetchTask(int $id = 0, bool $unpublished = false): ?Task { - $record = $this->fetchTaskRecord($id, $title); + $record = $this->fetchTaskRecord($id, $unpublished); if ($record === null) { @@ -177,27 +177,22 @@ public function fetchTask(int $id = 0, string $title = ''): ?Task * Fetches a single scheduled task in a Task instance. * If no id or title is specified, a due task is returned. * - * @param int $id The task ID - * @param string $title The task title + * @param int $id The task ID + * @param bool $title The task title * * @return ?object * * @since __DEPLOY_VERSION__ */ - public function fetchTaskRecord(int $id = 0, string $title = ''): ?object + public function fetchTaskRecord(int $id = 0, bool $unpublished = false): ?object { $filters = []; $listConfig = ['limit' => 1]; - if ($id !== 0) + if ($id > 0) { $filters['id'] = $id; } - elseif ($title !== '') - { - // Maybe, search? - $filters['title'] = $title; - } else { // Filters and list config for scheduled task queue @@ -209,6 +204,11 @@ public function fetchTaskRecord(int $id = 0, string $title = ''): ?object ]; } + if ($unpublished) + { + $filters['state'] = ''; + } + return $this->fetchTaskRecords($filters, $listConfig)[0] ?? null; } @@ -227,7 +227,7 @@ public function fetchTaskRecords(array $filters, array $listConfig): array try { /** @var TasksModel $model */ - $model = $this->component->getMVCFactory()->createModel('Tasks', 'Administrator'); + $model = $this->component->getMVCFactory()->createModel('Tasks', 'Administrator', ['ignore_request' => true]); } catch (\Exception $e) { @@ -238,12 +238,13 @@ public function fetchTaskRecords(array $filters, array $listConfig): array throw new \RunTimeException('JLIB_APPLICATION_ERROR_MODEL_CREATE'); } - $model->set('__state_set', true); - $model->setState('list.select', '*'); // Default to only enabled tasks - $model->setState('filter.state', 1); + if (!isset($filters['state'])) + { + $model->setState('filter.state', 1); + } // Default to including orphaned tasks $model->setState('filter.orphaned', 0); diff --git a/administrator/components/com_scheduler/src/Task/Task.php b/administrator/components/com_scheduler/src/Task/Task.php index 5692d6cb1e595..9c7a8fecb5550 100644 --- a/administrator/components/com_scheduler/src/Task/Task.php +++ b/administrator/components/com_scheduler/src/Task/Task.php @@ -49,7 +49,7 @@ class Task extends Registry implements LoggerAwareInterface * @var [] * @since __DEPLOY_VERSION__ */ - public $snapshot = []; + protected $snapshot = []; /** * @var string @@ -146,6 +146,7 @@ public function run(): bool 'subject' => $this ] ); + $this->app->getDispatcher()->dispatch('onTaskRecoverFailure', $event); } @@ -155,14 +156,14 @@ public function run(): bool $this->snapshot['status'] = Status::NO_ROUTINE; $this->skipExecution(); - return $this->handleExit(); + return $this->isSuccess(); } if (!$this->acquireLock()) { $this->snapshot['status'] = Status::NO_LOCK; - return $this->handleExit(); + return $this->isSuccess(); } $this->snapshot['status'] = Status::RUNNING; @@ -194,11 +195,19 @@ public function run(): bool if (!$this->releaseLock()) { $this->snapshot['status'] = Status::NO_RELEASE; - - return $this->handleExit(); } - return $this->handleExit(); + return $this->isSuccess(); + } + + /** + * Get the snapshot content + * + * @return array + */ + public function getContent() + { + return $this->snapshot; } /** @@ -388,15 +397,16 @@ public function skipExecution(): void * * @since __DEPLOY_VERSION__ */ - private function handleExit(): bool + public function isSuccess(): bool { - $exitCode = $this->snapshot['status']; + $exitCode = $this->snapshot['status'] ?? 'NA'; $eventName = self::EVENTS_MAP[$exitCode] ?? self::EVENTS_MAP['NA']; $event = AbstractEvent::create($eventName, [ 'subject' => $this ] ); + $this->app->getDispatcher()->dispatch($eventName, $event); return $exitCode === Status::OK; diff --git a/administrator/components/com_scheduler/src/Traits/TaskPluginTrait.php b/administrator/components/com_scheduler/src/Traits/TaskPluginTrait.php index f0b865e52369c..d15fb795d69ec 100644 --- a/administrator/components/com_scheduler/src/Traits/TaskPluginTrait.php +++ b/administrator/components/com_scheduler/src/Traits/TaskPluginTrait.php @@ -319,6 +319,7 @@ public function standardRoutineHandler(ExecuteTaskEvent $event): void catch (\Exception $e) { $this->logTask('Exception when calling routine: ' . $e->getMessage(), 'error'); + $exitCode = Status::NO_RUN; } } diff --git a/administrator/components/com_scheduler/tmpl/tasks/default.php b/administrator/components/com_scheduler/tmpl/tasks/default.php index 8c6af02eaf4c2..d998cb518e80b 100644 --- a/administrator/components/com_scheduler/tmpl/tasks/default.php +++ b/administrator/components/com_scheduler/tmpl/tasks/default.php @@ -26,6 +26,16 @@ Text::script('COM_SCHEDULER_TEST_RUN_TITLE'); Text::script('COM_SCHEDULER_TEST_RUN_TASK'); +Text::script('COM_SCHEDULER_TEST_RUN_DURATION'); +Text::script('COM_SCHEDULER_TEST_RUN_OUTPUT'); +Text::script('COM_SCHEDULER_TEST_RUN_STATUS_STARTED'); +Text::script('COM_SCHEDULER_TEST_RUN_STATUS_COMPLETED'); +Text::script('COM_SCHEDULER_TEST_RUN_STATUS_TERMINATED'); +Text::script('JLIB_JS_AJAX_ERROR_OTHER'); +Text::script('JLIB_JS_AJAX_ERROR_CONNECTION_ABORT'); +Text::script('JLIB_JS_AJAX_ERROR_TIMEOUT'); +Text::script('JLIB_JS_AJAX_ERROR_NO_CONTENT'); +Text::script('JLIB_JS_AJAX_ERROR_PARSE'); try { @@ -50,7 +60,7 @@ HTMLHelper::_('draggablelist.draggable'); } -$app->getDocument()->getWebAssetManager()->usePreset('com_scheduler.test-task'); +$app->getDocument()->getWebAssetManager()->useScript('com_scheduler.test-task'); ?> - @@ -217,16 +227,10 @@ class="js-draggable" data-url="" data-direction=" // Modal for test runs $modalparams = [ - 'title' => Text::_('COM_SCHEDULER_TEST_RUN_TITLE') + 'title' => '' ]; - $modalbody = '
'; - $modalbody .= '

' . Text::_('COM_SCHEDULER_TEST_RUN_TASK') . '

'; - $modalbody .= '
    '; - $modalbody .= '
  • ' . Text::_('COM_SCHEDULER_TEST_RUN_STATUS_STARTED') . '
  • '; - $modalbody .= '
  • '; - $modalbody .= '
'; - $modalbody .= '
'; + $modalbody = '
'; echo HTMLHelper::_('bootstrap.renderModal', 'scheduler-test-modal', $modalparams, $modalbody); diff --git a/administrator/language/en-GB/com_scheduler.ini b/administrator/language/en-GB/com_scheduler.ini index ad2bcafc31322..211c84c3a8784 100644 --- a/administrator/language/en-GB/com_scheduler.ini +++ b/administrator/language/en-GB/com_scheduler.ini @@ -117,11 +117,13 @@ COM_SCHEDULER_TASKS_VIEW_DEFAULT_DESC="Schedule and Manage Task Routines." COM_SCHEDULER_TASKS_VIEW_DEFAULT_TITLE="Scheduled Tasks Manager" COM_SCHEDULER_TEST_TASK="Test task" COM_SCHEDULER_TEST_RUN="Run Test" +COM_SCHEDULER_TEST_RUN_DURATION="Duration: %s seconds" +COM_SCHEDULER_TEST_RUN_OUTPUT="Output:
%s" COM_SCHEDULER_TEST_RUN_STATUS_COMPLETED="Status: Completed" COM_SCHEDULER_TEST_RUN_STATUS_STARTED="Status: Started" COM_SCHEDULER_TEST_RUN_STATUS_TERMINATED="Status: Terminated" COM_SCHEDULER_TEST_RUN_TASK="Task: \"%s\"" -COM_SCHEDULER_TEST_RUN_TITLE="Test task (%d)" +COM_SCHEDULER_TEST_RUN_TITLE="Test task (ID: %d)" COM_SCHEDULER_TRIGGER_CRON="Cron" COM_SCHEDULER_TRIGGER_PSEUDOCRON="Pseudocron" COM_SCHEDULER_TRIGGER_XVISITS="X-Visits" diff --git a/build/media_source/com_scheduler/js/admin-view-run-test-task.es6.js b/build/media_source/com_scheduler/js/admin-view-run-test-task.es6.js index 324cf89f72e70..fd56441142f6f 100644 --- a/build/media_source/com_scheduler/js/admin-view-run-test-task.es6.js +++ b/build/media_source/com_scheduler/js/admin-view-run-test-task.es6.js @@ -16,25 +16,75 @@ if (!window.Joomla) { throw new Error('Joomla API was not properly initialised'); } - -const initRunner = () => { + + const initRunner = () => { const modal = document.getElementById('scheduler-test-modal'); - modal.addEventListener('open.bd.modal', () => { - alert('test'); - }); - const options = Joomla.getOptions('plg_system_schedulerunner'); - const paths = Joomla.getOptions('system.paths'); - const interval = (options && options.inverval ? parseInt(options.interval, 10) : 300) * 1000; - const uri = `${paths ? `${paths.root}/index.php` : window.location.pathname}?option=com_ajax&format=raw&plugin=RunSchedulerLazy&group=system`; + const template = ` +

${ Joomla.Text._('COM_SCHEDULER_TEST_RUN_TASK') }

+
${ Joomla.Text._('COM_SCHEDULER_TEST_RUN_STATUS_STARTED') }
+
+ `; + + const paths = Joomla.getOptions('system.paths');console.log(paths); + const uri = `${paths ? `${paths.base}/index.php` : window.location.pathname}?option=com_ajax&format=json&plugin=RunSchedulerTest&group=system&id=%d`; + + modal.addEventListener('show.bs.modal', (e) => { + const button = e.relatedTarget; + const id = parseInt(button.dataset.id); + const title = button.dataset.title; + + modal.querySelector('.modal-title').innerHTML = Joomla.Text._('COM_SCHEDULER_TEST_RUN_TITLE').replace('%d', id); + modal.querySelector('.modal-body > div').innerHTML = template.replace('%s', title); + + Joomla.request({ + url: uri.replace('%d', id), + onSuccess: (data, xhr) => { + [].slice.call(modal.querySelectorAll('.modal-body > div > div')).forEach((el) => { + el.parentNode.removeChild(el); + }); - setInterval(() => navigator.sendBeacon(uri), interval); + const output = JSON.parse(data); - // Run it at the beginning at least once - navigator.sendBeacon(uri); + if (output && output.success && output.data && output.data.status == 0) + { + modal.querySelector('.modal-body > div').innerHTML += '
' + Joomla.Text._('COM_SCHEDULER_TEST_RUN_STATUS_COMPLETED') + '
'; + + if (output.data.duration > 0) + { + modal.querySelector('.modal-body > div').innerHTML += '
' + Joomla.Text._('COM_SCHEDULER_TEST_RUN_DURATION').replace('%s', output.data.duration.toFixed(2)) + '
'; + } + + if (output.data.output) + { + const result = output.data.output + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/"/g, """) + .replace(/'/g, "'") + .replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1
$2'); + + modal.querySelector('.modal-body > div').innerHTML += '
' + Joomla.Text._('COM_SCHEDULER_TEST_RUN_OUTPUT').replace('%s', result) + '
'; + } + } + else + {console.log(xhr); + modal.querySelector('.modal-body > div').innerHTML += '
' + Joomla.Text._('COM_SCHEDULER_TEST_RUN_STATUS_TERMINATED') + '
'; + modal.querySelector('.modal-body > div').innerHTML += '
' + Joomla.Text._('COM_SCHEDULER_TEST_RUN_OUTPUT').replace('%s', Joomla.Text._('JLIB_JS_AJAX_ERROR_OTHER').replace('%s', xhr.status)) + '
'; + } + }, + onError: (xhr) => { + modal.querySelector('.modal-body > div').innerHTML += '
' + Joomla.Text._('COM_SCHEDULER_TEST_RUN_STATUS_TERMINATED') + '
'; + + const msg = Joomla.ajaxErrorsMessages(xhr); + modal.querySelector('.modal-body > div').innerHTML += '
' + Joomla.Text._('COM_SCHEDULER_TEST_RUN_OUTPUT').replace('%s', msg.error) + '
'; + } + }); + }); }; -((document) => { +(document => { document.addEventListener('DOMContentLoaded', () => { initRunner(); }); diff --git a/libraries/src/Console/TasksRunCommand.php b/libraries/src/Console/TasksRunCommand.php index ed5c12901a589..e2492842a41e6 100644 --- a/libraries/src/Console/TasksRunCommand.php +++ b/libraries/src/Console/TasksRunCommand.php @@ -118,7 +118,8 @@ protected function doExecute(InputInterface $input, OutputInterface $output): in foreach ($records as $record) { $cStart = microtime(true); - $exit = $scheduler->runTask($record->id); + $task = $scheduler->runTask($record->id); + $exit = $task->isSuccess(); $duration = microtime(true) - $cStart; $key = (array_key_exists($exit, $outTextMap)) ? $exit : 'N/A'; $this->ioStyle->writeln(sprintf($outTextMap[$key], $record->id, $record->title, $duration, $exit)); diff --git a/plugins/system/schedulerunner/schedulerunner.php b/plugins/system/schedulerunner/schedulerunner.php index ba78622f4f93d..4646058044574 100644 --- a/plugins/system/schedulerunner/schedulerunner.php +++ b/plugins/system/schedulerunner/schedulerunner.php @@ -17,8 +17,10 @@ use Joomla\CMS\Language\Text; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\Component\Scheduler\Administrator\Scheduler\Scheduler; +use Joomla\Component\Scheduler\Administrator\Task\Task; use Joomla\Event\DispatcherInterface; use Joomla\Event\Event; +use Joomla\Event\EventInterface; use Joomla\Event\SubscriberInterface; use Joomla\Registry\Registry; @@ -68,8 +70,6 @@ public static function getSubscribedEvents(): array } elseif ($app->isClient('administrator')) { - $user = Factory::getUser(); - $mapping['onAjaxRunSchedulerTest'] = 'runTestCron'; } } @@ -125,6 +125,12 @@ public function runLazyCron() throw new \Exception(Text::_('JERROR_ALERTNOAUTHOR'), 403); } + // Since `navigator.sendBeacon()` may time out, allow execution after disconnect if possible. + if (\function_exists('ignore_user_abort')) + { + ignore_user_abort(true); + } + $this->runScheduler(); } @@ -155,7 +161,7 @@ public function runWebCron() * * @return void */ - public function runTestCron() + public function runTestCron(Event $event) { $id = (int) $this->app->input->getInt('id'); @@ -166,7 +172,12 @@ public function runTestCron() throw new \Exception(Text::_('JERROR_ALERTNOAUTHOR'), 403); } - $this->runScheduler($id); + $task = $this->runScheduler($id, true); + + if ($task) + { + $event->addArgument('result', $task->getContent()); + } } /** @@ -174,19 +185,13 @@ public function runTestCron() * * @param integer $id The optional ID of the task to run * - * @return void + * @return Task|bool * * @throws AssertionFailedException * @since __DEPLOY_VERSION__ */ - protected function runScheduler(int $id = 0): void + protected function runScheduler(int $id = 0, bool $unpublish = false): ?Task { - // Since `navigator.sendBeacon()` may time out, allow execution after disconnect if possible. - if (\function_exists('ignore_user_abort')) - { - ignore_user_abort(true); - } - - (new Scheduler)->runTask($id); + return (new Scheduler)->runTask($id, $unpublish); } } diff --git a/plugins/system/tasknotification/tasknotification.php b/plugins/system/tasknotification/tasknotification.php index 0399e2c565f1a..b4a31765b231e 100644 --- a/plugins/system/tasknotification/tasknotification.php +++ b/plugins/system/tasknotification/tasknotification.php @@ -85,7 +85,7 @@ public function notifyFailure(Event $event): void } // @todo safety checks, multiple files [?] - $outFile = $event->getArgument('subject')->snapshot['output_file'] ?? ''; + $outFile = $event->getArgument('subject')->getContent()['output_file'] ?? ''; $data = $this->getDataFromTask($event->getArgument('subject')); $this->sendMail('plg_system_tasknotification.failure_mail', $data, $outFile); } @@ -127,7 +127,7 @@ public function notifySuccess(Event $event): void // @todo safety checks, multiple files [?] $outFile = $event->getArgument('subject')->snapshot['output_file'] ?? ''; $data = $this->getDataFromTask($event->getArgument('subject')); - $this->sendMail('plg_system_tasknotification.success_mail', $data, $outFile); + $this->sendMail('plg_system_tasknotification.success_mail', $data); } /** @@ -160,12 +160,15 @@ private function getDataFromTask(Task $task): array { $lockOrExecTime = Factory::getDate($task->get('locked') ?? $task->get('last_execution'))->toRFC822(); + $snapshot = $task->getContent(); + return [ - 'TASK_ID' => $task->get('id'), - 'TASK_TITLE' => $task->get('title'), - 'EXIT_CODE' => $task->snapshot['status'] ?? Status::NO_EXIT, - 'EXEC_DATE_TIME' => $lockOrExecTime, - 'TASK_OUTPUT' => $task->snapshot['output_body'] ?? '', + 'TASK_ID' => $task->get('id'), + 'TASK_TITLE' => $task->get('title'), + 'EXIT_CODE' => $snapshot['status'] ?? Status::NO_EXIT, + 'EXEC_DATE_TIME' => $lockOrExecTime, + 'TASK_OUTPUT' => $snapshot['output'] ?? '', + 'TASK_OUTPUT_FILE' => $snapshot['output_file'] ?? '', ]; } @@ -179,7 +182,7 @@ private function getDataFromTask(Task $task): array * @throws Exception * @since __DEPLOY_VERSION__ */ - private function sendMail(string $template, array $data, string $attachment = ''): void + private function sendMail(string $template, array $data): void { $app = $this->app; $db = $this->db; @@ -220,11 +223,11 @@ private function sendMail(string $template, array $data, string $attachment = '' $mailer->addRecipient($user->email); // @todo improve and make safe - if ($attachment) + if (!empty($data['TASK_OUTPUT_FILE'])) { // @todo we allow multiple files - $attachName = pathinfo($attachment, PATHINFO_BASENAME); - $mailer->addAttachment($attachName, $attachment); + $attachName = pathinfo($data['TASK_OUTPUT_FILE'], PATHINFO_BASENAME); + $mailer->addAttachment($attachName, $data['TASK_OUTPUT_FILE']); } $mailer->send(); diff --git a/plugins/task/requests/requests.php b/plugins/task/requests/requests.php index 2cbade91b6429..b8e19bfdee256 100644 --- a/plugins/task/requests/requests.php +++ b/plugins/task/requests/requests.php @@ -111,7 +111,7 @@ protected function makeGetRequest(ExecuteTaskEvent $event): int $responseFile = JPATH_ROOT . "/tmp/task_{$id}_response.html"; File::write($responseFile, $responseBody); $this->snapshot['output_file'] = $responseFile; - $this->snapshot['output_body'] = <<< EOF + $this->snapshot['output'] = <<< EOF ======= Task Output Body ======= > URL: $url > Response Code: ${responseCode} From 7a015df3a92916d4ccbf403d3494b051f5ee2bb8 Mon Sep 17 00:00:00 2001 From: Benjamin Trenkle Date: Wed, 27 Oct 2021 03:32:58 +0200 Subject: [PATCH 510/615] Fix CS --- .../js/admin-view-run-test-task.es6.js | 55 +++++++++---------- 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/build/media_source/com_scheduler/js/admin-view-run-test-task.es6.js b/build/media_source/com_scheduler/js/admin-view-run-test-task.es6.js index fd56441142f6f..8c82d8dcc92a1 100644 --- a/build/media_source/com_scheduler/js/admin-view-run-test-task.es6.js +++ b/build/media_source/com_scheduler/js/admin-view-run-test-task.es6.js @@ -16,23 +16,23 @@ if (!window.Joomla) { throw new Error('Joomla API was not properly initialised'); } - - const initRunner = () => { + +const initRunner = () => { const modal = document.getElementById('scheduler-test-modal'); const template = ` -

${ Joomla.Text._('COM_SCHEDULER_TEST_RUN_TASK') }

-
${ Joomla.Text._('COM_SCHEDULER_TEST_RUN_STATUS_STARTED') }
+

${Joomla.Text._('COM_SCHEDULER_TEST_RUN_TASK')}

+
${Joomla.Text._('COM_SCHEDULER_TEST_RUN_STATUS_STARTED')}
`; - const paths = Joomla.getOptions('system.paths');console.log(paths); + const paths = Joomla.getOptions('system.paths'); const uri = `${paths ? `${paths.base}/index.php` : window.location.pathname}?option=com_ajax&format=json&plugin=RunSchedulerTest&group=system&id=%d`; modal.addEventListener('show.bs.modal', (e) => { const button = e.relatedTarget; - const id = parseInt(button.dataset.id); - const title = button.dataset.title; + const id = parseInt(button.dataset.id, 10); + const { title } = button.dataset; modal.querySelector('.modal-title').innerHTML = Joomla.Text._('COM_SCHEDULER_TEST_RUN_TITLE').replace('%d', id); modal.querySelector('.modal-body > div').innerHTML = template.replace('%s', title); @@ -46,45 +46,40 @@ if (!window.Joomla) { const output = JSON.parse(data); - if (output && output.success && output.data && output.data.status == 0) - { - modal.querySelector('.modal-body > div').innerHTML += '
' + Joomla.Text._('COM_SCHEDULER_TEST_RUN_STATUS_COMPLETED') + '
'; + if (output && output.success && output.data && output.data.status === 0) { + modal.querySelector('.modal-body > div').innerHTML += `
${Joomla.Text._('COM_SCHEDULER_TEST_RUN_STATUS_COMPLETED')}
`; - if (output.data.duration > 0) - { - modal.querySelector('.modal-body > div').innerHTML += '
' + Joomla.Text._('COM_SCHEDULER_TEST_RUN_DURATION').replace('%s', output.data.duration.toFixed(2)) + '
'; + if (output.data.duration > 0) { + modal.querySelector('.modal-body > div').innerHTML += `
${Joomla.Text._('COM_SCHEDULER_TEST_RUN_DURATION').replace('%s', output.data.duration.toFixed(2))}
`; } - if (output.data.output) - { + if (output.data.output) { const result = output.data.output - .replace(/&/g, "&") - .replace(//g, ">") - .replace(/"/g, """) - .replace(/'/g, "'") + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, ''') .replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1
$2'); - modal.querySelector('.modal-body > div').innerHTML += '
' + Joomla.Text._('COM_SCHEDULER_TEST_RUN_OUTPUT').replace('%s', result) + '
'; + modal.querySelector('.modal-body > div').innerHTML += `
${Joomla.Text._('COM_SCHEDULER_TEST_RUN_OUTPUT').replace('%s', result)}
`; } - } - else - {console.log(xhr); - modal.querySelector('.modal-body > div').innerHTML += '
' + Joomla.Text._('COM_SCHEDULER_TEST_RUN_STATUS_TERMINATED') + '
'; - modal.querySelector('.modal-body > div').innerHTML += '
' + Joomla.Text._('COM_SCHEDULER_TEST_RUN_OUTPUT').replace('%s', Joomla.Text._('JLIB_JS_AJAX_ERROR_OTHER').replace('%s', xhr.status)) + '
'; + } else { + modal.querySelector('.modal-body > div').innerHTML += `
${Joomla.Text._('COM_SCHEDULER_TEST_RUN_STATUS_TERMINATED')}
`; + modal.querySelector('.modal-body > div').innerHTML += `
${Joomla.Text._('COM_SCHEDULER_TEST_RUN_OUTPUT').replace('%s', Joomla.Text._('JLIB_JS_AJAX_ERROR_OTHER').replace('%s', xhr.status))}
`; } }, onError: (xhr) => { - modal.querySelector('.modal-body > div').innerHTML += '
' + Joomla.Text._('COM_SCHEDULER_TEST_RUN_STATUS_TERMINATED') + '
'; + modal.querySelector('.modal-body > div').innerHTML += `
${Joomla.Text._('COM_SCHEDULER_TEST_RUN_STATUS_TERMINATED')}
`; const msg = Joomla.ajaxErrorsMessages(xhr); - modal.querySelector('.modal-body > div').innerHTML += '
' + Joomla.Text._('COM_SCHEDULER_TEST_RUN_OUTPUT').replace('%s', msg.error) + '
'; - } + modal.querySelector('.modal-body > div').innerHTML += `
${Joomla.Text._('COM_SCHEDULER_TEST_RUN_OUTPUT').replace('%s', msg.error)}
`; + }, }); }); }; -(document => { +((document) => { document.addEventListener('DOMContentLoaded', () => { initRunner(); }); From 4ebbc006e5a5e9ba9ca84134e2d9ca7958394ca5 Mon Sep 17 00:00:00 2001 From: Benjamin Trenkle Date: Wed, 27 Oct 2021 03:46:48 +0200 Subject: [PATCH 511/615] Revert SQL query --- .../components/com_scheduler/src/Model/TasksModel.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/administrator/components/com_scheduler/src/Model/TasksModel.php b/administrator/components/com_scheduler/src/Model/TasksModel.php index 7d9ca764f5d84..a14bdaf6f6ff7 100644 --- a/administrator/components/com_scheduler/src/Model/TasksModel.php +++ b/administrator/components/com_scheduler/src/Model/TasksModel.php @@ -176,13 +176,15 @@ protected function getListQuery(): QueryInterface if (is_numeric($state)) { + $filterCount++; $state = (int) $state; $query->where($db->quoteName('a.state') . ' = :state') ->bind(':state', $state, ParameterType::INTEGER); } elseif ($state === '') { - $query->where($db->quoteName('a.state') . ' IN (0, 1)'); + $filterCount++; + $query->whereIn($db->quoteName('a.state'), [0, 1]); } // Filter over type ---- From 5ff273fca65337b8a2ab15917c54e19fa628c171 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Wed, 27 Oct 2021 17:37:42 +0530 Subject: [PATCH 512/615] Add webcron to scheduler config Updates the `com_scheduler` config.xml with the webcron fieldset. --- .../components/com_scheduler/config.xml | 49 ++++++++++++++++--- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/administrator/components/com_scheduler/config.xml b/administrator/components/com_scheduler/config.xml index 3c1fac77f6126..df3f93db100aa 100644 --- a/administrator/components/com_scheduler/config.xml +++ b/administrator/components/com_scheduler/config.xml @@ -47,11 +47,18 @@ default="300" /> - + +
+ JDISABLED - - +
Date: Wed, 27 Oct 2021 17:43:33 +0530 Subject: [PATCH 513/615] Add webcron key autogen and more to Schedulerunner - Schedulerunner auto-generates the webcron key and does some form usability enhancements on the config form (much like the user API token plugin). --- .../system/schedulerunner/schedulerunner.php | 113 +++++++++++++++++- 1 file changed, 109 insertions(+), 4 deletions(-) diff --git a/plugins/system/schedulerunner/schedulerunner.php b/plugins/system/schedulerunner/schedulerunner.php index ba78622f4f93d..9f53d97d63e57 100644 --- a/plugins/system/schedulerunner/schedulerunner.php +++ b/plugins/system/schedulerunner/schedulerunner.php @@ -14,11 +14,15 @@ use Joomla\CMS\Application\CMSApplication; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Factory; +use Joomla\CMS\Form\Form; use Joomla\CMS\Language\Text; use Joomla\CMS\Plugin\CMSPlugin; +use Joomla\CMS\Router\Route; +use Joomla\CMS\Table\Extension; +use Joomla\CMS\User\UserHelper; use Joomla\Component\Scheduler\Administrator\Scheduler\Scheduler; -use Joomla\Event\DispatcherInterface; use Joomla\Event\Event; +use Joomla\Event\EventInterface; use Joomla\Event\SubscriberInterface; use Joomla\Registry\Registry; @@ -28,11 +32,21 @@ * injects into each response with an HTML context a JS file {@see PlgSystemSchedulerunner::injectScheduleRunner()} that * sets up an AJAX callback to trigger the scheduler {@see PlgSystemSchedulerunner::runScheduler()}. This is achieved * through a call to the `com_ajax` component. + * Also supports the scheduler component configuration form through auto-generation of the webcron key and injection + * of JS of usability enhancement. * * @since __DEPLOY_VERSION__ */ class PlgSystemSchedulerunner extends CMSPlugin implements SubscriberInterface { + /** + * Length of auto-generated webcron key. + * + * @var integer + * @since __DEPLOY_VERSION__ + */ + private const WEBCRON_KEY_LENGTH = 20; + /** * @var CMSApplication * @since __DEPLOY_VERSION__ @@ -45,6 +59,8 @@ class PlgSystemSchedulerunner extends CMSPlugin implements SubscriberInterface * @return string[] * * @since __DEPLOY_VERSION__ + * + * @throws Exception */ public static function getSubscribedEvents(): array { @@ -68,7 +84,8 @@ public static function getSubscribedEvents(): array } elseif ($app->isClient('administrator')) { - $user = Factory::getUser(); + $mapping['onContentPrepareForm'] = 'enhanceSchedulerConfig'; + $mapping['onExtensionBeforeSave'] = 'generateWebcronKey'; $mapping['onAjaxRunSchedulerTest'] = 'runTestCron'; } @@ -115,6 +132,12 @@ public function injectLazyJS(Event $event): void * Runs the lazy cron in the frontend when activated. No ID allowed * * @return void + * + * @since __DEPLOY_VERSION__ + * + * @throws AssertionFailedException + * + * @throws Exception */ public function runLazyCron() { @@ -132,14 +155,18 @@ public function runLazyCron() * Runs the webcron and uses an ID if given. * * @return void + * + * @since __DEPLOY_VERSION__ + * + * @throws AssertionFailedException + * @throws Exception */ public function runWebCron() { $config = ComponentHelper::getParams('com_scheduler'); - $hash = $config->get('webcron.hash'); + $hash = $config->get('webcron.key'); - // @todo enforce a minimum complexity for hash? if (!strlen($hash) || $hash !== $this->app->input->get('hash')) { throw new \Exception(Text::_('JERROR_ALERTNOAUTHOR'), 403); @@ -154,6 +181,11 @@ public function runWebCron() * Runs the test cron in the backend. ID is required * * @return void + * + * @since __DEPLOY_VERSION__ + * + * @throws AssertionFailedException + * @throws Exception */ public function runTestCron() { @@ -177,6 +209,7 @@ public function runTestCron() * @return void * * @throws AssertionFailedException + * * @since __DEPLOY_VERSION__ */ protected function runScheduler(int $id = 0): void @@ -189,4 +222,76 @@ protected function runScheduler(int $id = 0): void (new Scheduler)->runTask($id); } + + /** + * Enhance the scheduler config form by dynamically populating or removing display fields. + * @todo Move to another plugin? + * + * @param EventInterface $event The onContentPrepareForm event. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function enhanceSchedulerConfig(EventInterface $event): void + { + /** @var Form $form */ + $form = $event->getArgument('0'); + $data = $event->getArgument('1'); + + if ($form->getName() !== 'com_config.component' + || $this->app->input->get('component') !== 'com_scheduler') + { + return; + } + + if (!empty($data['webcron']['key'])) + { + $form->removeField('generate_key_on_save', 'webcron'); + + $relative = 'index.php?option=com_ajax&plugin=RunSchedulerLazy&group=system&format=json&hash=' . $data['webcron']['key']; + $link = Route::link('site', $relative, false, Route::TLS_IGNORE, true); + $form->setValue('base_link', 'webcron', $link); + } + else + { + $form->removeField('base_link', 'webcron'); + $form->removeField('reset_key', 'webcron'); + } + } + + /** + * Auto-generate a key/hash for the webcron functionality. + * This method acts on table save, when a hash doesn't already exist or a reset is required. + * @todo Move to another plugin? + * + * @param EventInterface $event The onExtensionBeforeSave event. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function generateWebcronKey(EventInterface $event): void + { + /** @var Extension $table */ + [$context, $table] = $event->getArguments(); + + if ($context !== 'com_config.component' + || $this->app->input->get('component') !== 'com_scheduler') + { + return; + } + + $params = new Registry(json_decode($table->params)); + + if (empty($params->get('webcron.key')) + || (int) $params->get('webcron.reset_key') === 1) + { + $params->set('webcron.key', UserHelper::genRandomPassword(self::WEBCRON_KEY_LENGTH)); + } + + $params->remove('webcron.base_link'); + $params->remove('webcron.reset_key'); + $table->params = $params->toString(); + } } From adbe28fe1996193c759ef6d9627080dcb39757d4 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Wed, 27 Oct 2021 17:51:37 +0530 Subject: [PATCH 514/615] Add custom field for webcron link - Adds new field 'WebcronLinkField', this field is not really needed except for to support the custom layout location. - Allows for the webcron link to be copies on click, much like the user API token field. - Adds field JS to the `com_scheduler` media source provider. --- .../layouts/form/field/webcron_link.php | 56 +++++++++++++++++++ .../src/Field/WebcronLinkField.php | 52 +++++++++++++++++ .../com_scheduler/joomla.asset.json | 25 ++++++++- .../com_scheduler/js/scheduler-config.es6.js | 51 +++++++++++++++++ 4 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 administrator/components/com_scheduler/layouts/form/field/webcron_link.php create mode 100644 administrator/components/com_scheduler/src/Field/WebcronLinkField.php create mode 100644 build/media_source/com_scheduler/js/scheduler-config.es6.js diff --git a/administrator/components/com_scheduler/layouts/form/field/webcron_link.php b/administrator/components/com_scheduler/layouts/form/field/webcron_link.php new file mode 100644 index 0000000000000..b16dd49449617 --- /dev/null +++ b/administrator/components/com_scheduler/layouts/form/field/webcron_link.php @@ -0,0 +1,56 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Application\CMSApplication; +use Joomla\CMS\Factory; +use Joomla\CMS\Language\Text; + +extract($displayData); + +/** + * Layout variables + * ----------------- + * + * @var string $id DOM id of the field. + * @var string $label Label of the field. + * @var string $name Name of the input field. + * @var string $value Value attribute of the field. + */ + +Text::script('ERROR'); +Text::script('MESSAGE'); +Text::script('COM_SCHEDULER_WEBCRON_LINK_COPY_SUCCESS'); +Text::script('COM_SCHEDULER_WEBCRON_LINK_COPY_FAIL'); + +/** @var CMSApplication $app */ +$app = Factory::getApplication(); +$wa = $app->getDocument()->getWebAssetManager(); +$wa->getRegistry()->addExtensionRegistryFile('com_scheduler'); +$wa->useScript('com_scheduler.scheduler-config'); +?> + +
+ + +
+ diff --git a/administrator/components/com_scheduler/src/Field/WebcronLinkField.php b/administrator/components/com_scheduler/src/Field/WebcronLinkField.php new file mode 100644 index 0000000000000..f7be39739e8c1 --- /dev/null +++ b/administrator/components/com_scheduler/src/Field/WebcronLinkField.php @@ -0,0 +1,52 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace Joomla\Component\Scheduler\Administrator\Field; + +// Restrict direct access +use Joomla\CMS\Form\Field\TextField; + +defined('_JEXEC') or die; + +/** + * Field to override the text field layout to add a copy-text button, used in the com_scheduler + * configuration form. + * This field class is only needed because the layout file is in a non-global directory, so this should + * be made redundant and removed if/once the layout is shifted to `JPATH_SITE/layout/` + * + * @since __DEPLOY_VERSION__ + */ +class WebcronLinkField extends TextField +{ + /** + * We use a custom layout that allows for the link to be copied. + * + * @var string + * @since __DEPLOY_VERSION__ + */ + protected $layout = 'form.field.webcron_link'; + + + /** + * Override layout paths. + * + * @inheritDoc + * @return string[] + * + * @since __DEPLOY_VERSION__ + */ + protected function getLayoutPaths(): array + { + $s = DIRECTORY_SEPARATOR; + + return [ + JPATH_ADMINISTRATOR . "${s}/components${s}com_scheduler${s}layouts${s}", + ] + parent::getLayoutPaths(); + } +} diff --git a/build/media_source/com_scheduler/joomla.asset.json b/build/media_source/com_scheduler/joomla.asset.json index fc304820625a0..c2a56bdc73115 100644 --- a/build/media_source/com_scheduler/joomla.asset.json +++ b/build/media_source/com_scheduler/joomla.asset.json @@ -25,7 +25,30 @@ "com_scheduler.admin-view-select-task-search.es5" ], "attributes": { - "type" : "module" + "type": "module" + } + }, + { + "name": "com_scheduler.scheduler-config.es5", + "type": "script", + "uri": "com_scheduler/scheduler-config-es5.js", + "dependencies": [ + "core" + ], + "attributes": { + "nomodule": true + } + }, + { + "name": "com_scheduler.scheduler-config", + "type": "script", + "uri": "com_scheduler/scheduler-config.js", + "dependencies": [ + "core", + "com_scheduler.scheduler-config.es5" + ], + "attributes": { + "type": "module" } }, { diff --git a/build/media_source/com_scheduler/js/scheduler-config.es6.js b/build/media_source/com_scheduler/js/scheduler-config.es6.js new file mode 100644 index 0000000000000..31c6b2266913a --- /dev/null +++ b/build/media_source/com_scheduler/js/scheduler-config.es6.js @@ -0,0 +1,51 @@ +/** + * @copyright (C) 2021 Open Source Matters, Inc. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +if (!window.Joomla) { + throw new Error('Joomla API was not properly initialised!'); +} + +const copyToClipboardFallback = (input) => { + input.focus(); + input.select(); + + try { + const copy = document.execCommand('copy'); + if (copy) { + Joomla.renderMessages({ message: [Joomla.Text._('COM_SCHEDULER_WEBCRON_LINK_COPY_SUCCESS')] }); + } else { + Joomla.renderMessages({ error: [Joomla.Text._('COM_SCHEDULER_WEBCRON_LINK_COPY_FAIL')] }); + } + } catch (err) { + Joomla.renderMessages({ error: [err] }); + } +}; + +const copyToClipboard = () => { + const button = document.getElementById('link-copy'); + + button.addEventListener('click', ({ currentTarget }) => { + const input = currentTarget.previousElementSibling; + + if (!navigator.clipboard) { + copyToClipboardFallback(input); + return; + } + + navigator.clipboard.writeText(input.value).then(() => { + Joomla.renderMessages({ message: [Joomla.Text._('COM_SCHEDULER_WEBCRON_LINK_COPY_SUCCESS')] }); + }, () => { + Joomla.renderMessages({ error: [Joomla.Text._('COM_SCHEDULER_WEBCRON_LINK_COPY_FAIL')] }); + }); + }); +}; + +const onBoot = () => { + copyToClipboard(); + + document.removeEventListener('DOMContentLoaded', onBoot); +}; + +document.addEventListener('DOMContentLoaded', onBoot); From a87ef9d4d75b2dd1fb6b8bab5238eb4a0878e737 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Wed, 27 Oct 2021 17:59:19 +0530 Subject: [PATCH 515/615] Update com_scheduler language file Adds new strings for the config form and updates some refs. --- .../layouts/form/field/webcron_link.php | 6 +++--- administrator/language/en-GB/com_scheduler.ini | 17 +++++++++++++---- .../com_scheduler/js/scheduler-config.es6.js | 8 ++++---- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/administrator/components/com_scheduler/layouts/form/field/webcron_link.php b/administrator/components/com_scheduler/layouts/form/field/webcron_link.php index b16dd49449617..5d86b26d14fa4 100644 --- a/administrator/components/com_scheduler/layouts/form/field/webcron_link.php +++ b/administrator/components/com_scheduler/layouts/form/field/webcron_link.php @@ -27,8 +27,8 @@ Text::script('ERROR'); Text::script('MESSAGE'); -Text::script('COM_SCHEDULER_WEBCRON_LINK_COPY_SUCCESS'); -Text::script('COM_SCHEDULER_WEBCRON_LINK_COPY_FAIL'); +Text::script('COM_SCHEDULER_CONFIG_WEBCRON_LINK_COPY_SUCCESS'); +Text::script('COM_SCHEDULER_CONFIG_WEBCRON_LINK_COPY_FAIL'); /** @var CMSApplication $app */ $app = Factory::getApplication(); @@ -50,7 +50,7 @@ class="form-control" class="btn btn-primary" type="button" id="link-copy" - title=""> + title=""> diff --git a/administrator/language/en-GB/com_scheduler.ini b/administrator/language/en-GB/com_scheduler.ini index c1f72592c210f..908623d92f8d0 100644 --- a/administrator/language/en-GB/com_scheduler.ini +++ b/administrator/language/en-GB/com_scheduler.ini @@ -4,18 +4,27 @@ ; Note : All ini files need to be saved as UTF-8 COM_SCHEDULER="Scheduled Tasks" +COM_SCHEDULER_CONFIGURATION="Scheduled Tasks Manager Configuration" COM_SCHEDULER_CONFIG_FIELDSET_LAZY_SCHEDULER_DESC="Configure how site visits trigger Scheduled Tasks." COM_SCHEDULER_CONFIG_FIELDSET_LAZY_SCHEDULER_LABEL="Lazy Scheduler" +COM_SCHEDULER_CONFIG_GENERATE_WEBCRON_KEY_DESC="The webcron needs a protection key before it is functional. Saving this configuration will autogenerate the key." +COM_SCHEDULER_CONFIG_GLOBAL_WEBCRON_KEY_LABEL="Global Key" +COM_SCHEDULER_CONFIG_GLOBAL_WEBCRON_LINK_DESC="By default, requesting this base link will only run tasks due for execution. To execute a specific task, use the task's ID as a query parameter appended to the URL: BASE_URL&task_id=<task's id>" +COM_SCHEDULER_CONFIG_GLOBAL_WEBCRON_LINK_LABEL="Webcron Link (Base)" COM_SCHEDULER_CONFIG_HASH_PROTECTION_DESC="If enabled, tasks will only be triggered when URLs have the scheduler hash as a parameter." -COM_SCHEDULER_CONFIG_HASH_PROTECTION_LABEL="Hash Protection" COM_SCHEDULER_CONFIG_LAZY_SCHEDULER_ENABLED_DESC="If disabled, scheduled tasks will not be triggered by visitors on the site.
Recommended if triggering with native cron." COM_SCHEDULER_CONFIG_LAZY_SCHEDULER_ENABLED_LABEL="Lazy Scheduler" -COM_SCHEDULER_CONFIG_LAZY_SCHEDULER_HASH_LABEL="Hash" COM_SCHEDULER_CONFIG_LAZY_SCHEDULER_INTERVAL_DESC="Interval between scheduler trigger requests from the client." COM_SCHEDULER_CONFIG_LAZY_SCHEDULER_INTERVAL_LABEL="Request Interval" -COM_SCHEDULER_CONFIG_TASK_TIMEOUT_LABEL="Task Timeout (seconds)" +COM_SCHEDULER_CONFIG_RESET_WEBCRON_KEY_LABEL="Reset Access Key" COM_SCHEDULER_CONFIG_TASKS_FIELDSET_LABEL="Configure Tasks" -COM_SCHEDULER_CONFIGURATION="Scheduled Tasks Manager Configuration" +COM_SCHEDULER_CONFIG_TASK_TIMEOUT_LABEL="Task Timeout (seconds)" +COM_SCHEDULER_CONFIG_WEBCRON_DESC="Trigger and manage task execution with an external service." +COM_SCHEDULER_CONFIG_WEBCRON_ENABLED_LABEL="Web Cron" +COM_SCHEDULER_CONFIG_WEBCRON_LABEL="Web Cron" +COM_SCHEDULER_CONFIG_WEBCRON_LINK_COPY_DESC="Copy the link to your clipboard." +COM_SCHEDULER_CONFIG_WEBCRON_LINK_COPY_FAIL="Could not copy link!" +COM_SCHEDULER_CONFIG_WEBCRON_LINK_COPY_SUCCESS="Link copied!" COM_SCHEDULER_DASHBOARD_TITLE="Scheduled Tasks Manager" COM_SCHEDULER_DESCRIPTION_TASK_PRIORITY="⚠ This is an advanced option. Higher priority tasks can potentially block out lower priority tasks." COM_SCHEDULER_EDIT_TASK="Edit Task" diff --git a/build/media_source/com_scheduler/js/scheduler-config.es6.js b/build/media_source/com_scheduler/js/scheduler-config.es6.js index 31c6b2266913a..b980848ad2ce8 100644 --- a/build/media_source/com_scheduler/js/scheduler-config.es6.js +++ b/build/media_source/com_scheduler/js/scheduler-config.es6.js @@ -14,9 +14,9 @@ const copyToClipboardFallback = (input) => { try { const copy = document.execCommand('copy'); if (copy) { - Joomla.renderMessages({ message: [Joomla.Text._('COM_SCHEDULER_WEBCRON_LINK_COPY_SUCCESS')] }); + Joomla.renderMessages({ message: [Joomla.Text._('COM_SCHEDULER_CONFIG_WEBCRON_LINK_COPY_SUCCESS')] }); } else { - Joomla.renderMessages({ error: [Joomla.Text._('COM_SCHEDULER_WEBCRON_LINK_COPY_FAIL')] }); + Joomla.renderMessages({ error: [Joomla.Text._('COM_SCHEDULER_CONFIG_WEBCRON_LINK_COPY_FAIL')] }); } } catch (err) { Joomla.renderMessages({ error: [err] }); @@ -35,9 +35,9 @@ const copyToClipboard = () => { } navigator.clipboard.writeText(input.value).then(() => { - Joomla.renderMessages({ message: [Joomla.Text._('COM_SCHEDULER_WEBCRON_LINK_COPY_SUCCESS')] }); + Joomla.renderMessages({ message: [Joomla.Text._('COM_SCHEDULER_CONFIG_WEBCRON_LINK_COPY_SUCCESS')] }); }, () => { - Joomla.renderMessages({ error: [Joomla.Text._('COM_SCHEDULER_WEBCRON_LINK_COPY_FAIL')] }); + Joomla.renderMessages({ error: [Joomla.Text._('COM_SCHEDULER_CONFIG_WEBCRON_LINK_COPY_FAIL')] }); }); }); }; From 6fe554237596d484e8f1f85b00525d5a83782c3b Mon Sep 17 00:00:00 2001 From: ditsuke Date: Wed, 27 Oct 2021 23:11:14 +0530 Subject: [PATCH 516/615] Fix regression in Scheduler class - Fix regression due to newly protected status of Task::snapshot + accessor. - Update some doc-blocks and related formatting. - Optimise some imports. - Minor miscellaneous changes. --- .../com_scheduler/src/Scheduler/Scheduler.php | 21 ++++++++------- .../com_scheduler/src/Task/Task.php | 26 ++++++++++--------- .../system/schedulerunner/schedulerunner.php | 14 +++++----- 3 files changed, 33 insertions(+), 28 deletions(-) diff --git a/administrator/components/com_scheduler/src/Scheduler/Scheduler.php b/administrator/components/com_scheduler/src/Scheduler/Scheduler.php index 1563521f4db60..ba68012d04d47 100644 --- a/administrator/components/com_scheduler/src/Scheduler/Scheduler.php +++ b/administrator/components/com_scheduler/src/Scheduler/Scheduler.php @@ -1,10 +1,10 @@ - * @license GNU General Public License version 2 or later; see LICENSE.txt + * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Component\Scheduler\Administrator\Scheduler; @@ -122,17 +122,18 @@ public function runTask(int $id = 0, bool $unpublished = false): ?Task $task->log(Text::sprintf('COM_SCHEDULER_SCHEDULER_TASK_START', $taskId, $taskTitle), 'info'); - // Let's try to avoid time outs + // Let's try to avoid time-outs if (\function_exists('set_time_limit')) { set_time_limit(0); } $task->run(); - $exitCode = $task->snapshot['status'] ?? Status::NO_EXIT; - $netDuration = $task->snapshot['netDuration'] ?? 0; - $duration = $task->snapshot['duration'] ?? 0; + $executionSnapshot = $task->getContent(); + $exitCode = $executionSnapshot['status'] ?? Status::NO_EXIT; + $netDuration = $executionSnapshot['netDuration'] ?? 0; + $duration = $executionSnapshot['duration'] ?? 0; if (array_key_exists($exitCode, self::LOG_TEXT)) { @@ -177,10 +178,10 @@ public function fetchTask(int $id = 0, bool $unpublished = false): ?Task * Fetches a single scheduled task in a Task instance. * If no id or title is specified, a due task is returned. * - * @param int $id The task ID - * @param bool $title The task title + * @param int $id The task ID + * @param bool $unpublished Allow disabled/trashed tasks? * - * @return ?object + * @return ?object A matching task record, if it exists * * @since __DEPLOY_VERSION__ */ diff --git a/administrator/components/com_scheduler/src/Task/Task.php b/administrator/components/com_scheduler/src/Task/Task.php index 9c7a8fecb5550..cecf7cef59d80 100644 --- a/administrator/components/com_scheduler/src/Task/Task.php +++ b/administrator/components/com_scheduler/src/Task/Task.php @@ -1,14 +1,12 @@ - * @license GNU General Public License version 2 or later; see LICENSE.txt + * @copyright (C) 2021 Open Source Matters, Inc. + * @license GNU General Public License version 2 or later; see LICENSE.txt */ -/** Implements the Task class. */ - namespace Joomla\Component\Scheduler\Administrator\Task; // Restrict direct access @@ -33,9 +31,9 @@ use Psr\Log\LoggerAwareTrait; /** - * The Task class. - * This class essentially extends a task record to define methods for its execution, logging and - * related properties. + * The Task class defines methods for the execution, logging and + * related properties of Tasks as supported by `com_scheduler`, + * a Task Scheduling component. * * @since __DEPLOY_VERSION__ */ @@ -105,10 +103,11 @@ public function __construct(object $record) $options['text_file'] = $logFile; Log::addLogger($options, Log::ALL, [$this->logCategory]); } - } /** + * Get the task as a data object that can be stored back in the database. + * ! This method should be removed or changed as part of a better API implementation for the driver. * * @return object * @@ -201,11 +200,14 @@ public function run(): bool } /** - * Get the snapshot content + * Get the task execution snapshot, + * ! Access locations will need updates once a more robust Snapshot container is implemented. * * @return array + * + * @since __DEPLOY_VERSION__ */ - public function getContent() + public function getContent(): array { return $this->snapshot; } diff --git a/plugins/system/schedulerunner/schedulerunner.php b/plugins/system/schedulerunner/schedulerunner.php index 7ec037edc9cbe..20be22d81e2b4 100644 --- a/plugins/system/schedulerunner/schedulerunner.php +++ b/plugins/system/schedulerunner/schedulerunner.php @@ -22,7 +22,6 @@ use Joomla\CMS\User\UserHelper; use Joomla\Component\Scheduler\Administrator\Scheduler\Scheduler; use Joomla\Component\Scheduler\Administrator\Task\Task; -use Joomla\Event\DispatcherInterface; use Joomla\Event\Event; use Joomla\Event\EventInterface; use Joomla\Event\SubscriberInterface; @@ -188,6 +187,8 @@ public function runWebCron() /** * Runs the test cron in the backend. ID is required * + * @param Event $event The onAjaxRunScheduler event. + * * @return void * * @since __DEPLOY_VERSION__ @@ -217,17 +218,18 @@ public function runTestCron(Event $event) /** * Run the scheduler, allowing execution of a single due task. * - * @param integer $id The optional ID of the task to run + * @param integer $id The optional ID of the task to run + * @param boolean $unpublished Allow execution of unpublished tasks? * - * @return Task|bool + * @return Task|boolean * + * @since __DEPLOY_VERSION__ * @throws AssertionFailedException * - * @since __DEPLOY_VERSION__ */ - protected function runScheduler(int $id = 0, bool $unpublish = false): ?Task + protected function runScheduler(int $id = 0, bool $unpublished = false): ?Task { - return (new Scheduler)->runTask($id, $unpublish); + return (new Scheduler)->runTask($id, $unpublished); } /** From 09ca90bb571a5d5a2baa34c23f8b525d0541cc2c Mon Sep 17 00:00:00 2001 From: ditsuke Date: Thu, 28 Oct 2021 20:50:14 +0530 Subject: [PATCH 517/615] Fix test run JS Fixes apparent JS parse error on non-zero task exits. --- .../js/admin-view-run-test-task.es6.js | 43 ++++++++++--------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/build/media_source/com_scheduler/js/admin-view-run-test-task.es6.js b/build/media_source/com_scheduler/js/admin-view-run-test-task.es6.js index 8c82d8dcc92a1..7f889452fdf2d 100644 --- a/build/media_source/com_scheduler/js/admin-view-run-test-task.es6.js +++ b/build/media_source/com_scheduler/js/admin-view-run-test-task.es6.js @@ -4,9 +4,7 @@ */ /** - * Run the test task in the scheduler backend list - * - * Used for the play button in the list view + * Provides the manual-run functionality for tasks over the com_scheduler administrator backend. * * @package Joomla.Components * @subpackage Scheduler.Tasks @@ -18,18 +16,27 @@ if (!window.Joomla) { } const initRunner = () => { + const paths = Joomla.getOptions('system.paths'); + const uri = `${paths ? `${paths.base}/index.php` : window.location.pathname}?option=com_ajax&format=json&plugin=RunSchedulerTest&group=system&id=%d`; const modal = document.getElementById('scheduler-test-modal'); + // Task output template const template = `

${Joomla.Text._('COM_SCHEDULER_TEST_RUN_TASK')}

${Joomla.Text._('COM_SCHEDULER_TEST_RUN_STATUS_STARTED')}
`; - const paths = Joomla.getOptions('system.paths'); - const uri = `${paths ? `${paths.base}/index.php` : window.location.pathname}?option=com_ajax&format=json&plugin=RunSchedulerTest&group=system&id=%d`; + const sanitiseTaskOutput = (text) => text + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, ''') + .replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1
$2'); - modal.addEventListener('show.bs.modal', (e) => { + // Trigger the task through a GET request, populate the modal with output on completion. + const triggerTaskAndShowOutput = (e) => { const button = e.relatedTarget; const id = parseInt(button.dataset.id, 10); const { title } = button.dataset; @@ -38,7 +45,7 @@ const initRunner = () => { modal.querySelector('.modal-body > div').innerHTML = template.replace('%s', title); Joomla.request({ - url: uri.replace('%d', id), + url: uri.replace('%d', id.toString()), onSuccess: (data, xhr) => { [].slice.call(modal.querySelectorAll('.modal-body > div > div')).forEach((el) => { el.parentNode.removeChild(el); @@ -46,7 +53,7 @@ const initRunner = () => { const output = JSON.parse(data); - if (output && output.success && output.data && output.data.status === 0) { + if (output && output.success && output.data) { modal.querySelector('.modal-body > div').innerHTML += `
${Joomla.Text._('COM_SCHEDULER_TEST_RUN_STATUS_COMPLETED')}
`; if (output.data.duration > 0) { @@ -54,14 +61,9 @@ const initRunner = () => { } if (output.data.output) { - const result = output.data.output - .replace(/&/g, '&') - .replace(//g, '>') - .replace(/"/g, '"') - .replace(/'/g, ''') - .replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1
$2'); + const result = Joomla.sanitizeHtml((output.data.output), null, sanitiseTaskOutput); + // Can use an indication for non-0 exit codes modal.querySelector('.modal-body > div').innerHTML += `
${Joomla.Text._('COM_SCHEDULER_TEST_RUN_OUTPUT').replace('%s', result)}
`; } } else { @@ -76,11 +78,10 @@ const initRunner = () => { modal.querySelector('.modal-body > div').innerHTML += `
${Joomla.Text._('COM_SCHEDULER_TEST_RUN_OUTPUT').replace('%s', msg.error)}
`; }, }); - }); + }; + + modal.addEventListener('show.bs.modal', triggerTaskAndShowOutput); + document.removeEventListener('DOMContentLoaded', initRunner); }; -((document) => { - document.addEventListener('DOMContentLoaded', () => { - initRunner(); - }); -})(document); +document.addEventListener('DOMContentLoaded', initRunner); From 4e6c8f4edc01b76cd30f92d110f0e19fa8455272 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Thu, 28 Oct 2021 21:06:06 +0530 Subject: [PATCH 518/615] Improve form manipulation code - Check for `com_scheduler` in the subject table for table event. - Minor code simplification. --- plugins/system/schedulerunner/schedulerunner.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/system/schedulerunner/schedulerunner.php b/plugins/system/schedulerunner/schedulerunner.php index 20be22d81e2b4..4d4524d6a7aab 100644 --- a/plugins/system/schedulerunner/schedulerunner.php +++ b/plugins/system/schedulerunner/schedulerunner.php @@ -286,15 +286,15 @@ public function generateWebcronKey(EventInterface $event): void [$context, $table] = $event->getArguments(); if ($context !== 'com_config.component' - || $this->app->input->get('component') !== 'com_scheduler') + || ($table->name ?? '') !== 'COM_SCHEDULER') { return; } - $params = new Registry(json_decode($table->params)); + $params = new Registry($table->params ?? ''); if (empty($params->get('webcron.key')) - || (int) $params->get('webcron.reset_key') === 1) + || $params->get('webcron.reset_key') === 1) { $params->set('webcron.key', UserHelper::genRandomPassword(self::WEBCRON_KEY_LENGTH)); } From 431591d355024014fb1bee242b467ae6960b0b0e Mon Sep 17 00:00:00 2001 From: ditsuke Date: Fri, 29 Oct 2021 12:43:17 +0530 Subject: [PATCH 519/615] Clean up redundant field from Tasks table - Remove redundant `trigger` field from `#__scheduler_tasks`. - From install and update SQL. - Task item form. - Language file. - Fix regression in GenericDataException ref. - Minor styling/doc fixes and upgrades. --- .../sql/updates/mysql/4.1.0-2021-08-08.sql | 2 - .../updates/postgresql/4.1.0-2021-08-08.sql | 1 - .../components/com_scheduler/forms/task.xml | 16 ------ .../com_scheduler/src/Model/TasksModel.php | 3 +- .../com_scheduler/src/View/Tasks/HtmlView.php | 57 ++++++++----------- .../language/en-GB/com_scheduler.ini | 1 - installation/sql/mysql/extensions.sql | 2 - installation/sql/postgresql/extensions.sql | 1 - 8 files changed, 26 insertions(+), 57 deletions(-) diff --git a/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-08-08.sql b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-08-08.sql index c9b9361d01617..ea307099431aa 100644 --- a/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-08-08.sql +++ b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-08-08.sql @@ -7,8 +7,6 @@ CREATE TABLE IF NOT EXISTS `#__scheduler_tasks` ( `asset_id` int NOT NULL UNIQUE DEFAULT '0', `title` varchar(255) NOT NULL DEFAULT '', `type` varchar(1024) NOT NULL COMMENT 'unique identifier for job defined by plugin', - -- Trigger type, default to PseudoCron (compatible everywhere). - `trigger` enum ('pseudo_cron', 'cron', 'visit_count') NOT NULL DEFAULT 'pseudo_cron' COMMENT 'Defines how job is triggered', `execution_rules` text COMMENT 'Execution Rules, Unprocessed', `cron_rules` text COMMENT 'Processed execution rules, crontab-like JSON form', `state` tinyint NOT NULL DEFAULT FALSE, diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-08-08.sql b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-08-08.sql index b769a091e34bb..6991233d78a13 100644 --- a/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-08-08.sql +++ b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-08-08.sql @@ -10,7 +10,6 @@ CREATE TABLE IF NOT EXISTS "#__scheduler_tasks" "type" varchar(1024) NOT NULL, "execution_rules" text, "cron_rules" text, - "trigger" varchar(12) NOT NULL DEFAULT 'pseudo_cron', "state" smallint NOT NULL DEFAULT '0', "last_exit_code" int NOT NULL DEFAULT '0', "last_execution" timestamp without time zone, diff --git a/administrator/components/com_scheduler/forms/task.xml b/administrator/components/com_scheduler/forms/task.xml index b6a1f0addc23b..b03bdf57007d3 100644 --- a/administrator/components/com_scheduler/forms/task.xml +++ b/administrator/components/com_scheduler/forms/task.xml @@ -12,22 +12,6 @@ maxlength="100" required="true" /> -
- - - - - - -
select( $this->getState( 'list.select', - 'a.id, a.asset_id, a.title, a.type, a.trigger, a.execution_rules, a.state, a.last_exit_code' . + 'a.id, a.asset_id, a.title, a.type, a.execution_rules, a.state, a.last_exit_code' . ', a.last_execution, a.next_execution, a.times_executed, a.times_failed, a.ordering, a.note' ) ); diff --git a/administrator/components/com_scheduler/src/View/Tasks/HtmlView.php b/administrator/components/com_scheduler/src/View/Tasks/HtmlView.php index 426d891d0fb94..e3f309d2f4540 100644 --- a/administrator/components/com_scheduler/src/View/Tasks/HtmlView.php +++ b/administrator/components/com_scheduler/src/View/Tasks/HtmlView.php @@ -1,14 +1,12 @@ - * @license GNU General Public License version 2 or later; see LICENSE.txt + * @copyright (C) 2021 Open Source Matters, Inc. + * @license GNU General Public License version 2 or later; see LICENSE.txt */ -/** Implements the MVC View for the Tasks list view (TasksView). */ - namespace Joomla\Component\Scheduler\Administrator\View\Tasks; // Restrict direct access @@ -27,14 +25,14 @@ use Joomla\CMS\Toolbar\ToolbarHelper; /** - * The MVC View for Tasks list view + * MVC View for the Tasks list page. * * @since __DEPLOY_VERSION__ */ class HtmlView extends BaseHtmlView { /** - * An array of items + * Array of task items. * * @var array * @since __DEPLOY_VERSION__ @@ -42,15 +40,16 @@ class HtmlView extends BaseHtmlView protected $items; /** - * The pagination object + * The pagination object. * * @var Pagination * @since __DEPLOY_VERSION__ + * @todo Test pagination. */ protected $pagination; /** - * The model state + * The model state. * * @var CMSObject * @since __DEPLOY_VERSION__ @@ -58,7 +57,7 @@ class HtmlView extends BaseHtmlView protected $state; /** - * A Form object for search filters + * A Form object for search filters. * * @var Form * @since __DEPLOY_VERSION__ @@ -66,7 +65,7 @@ class HtmlView extends BaseHtmlView public $filterForm; /** - * The active search filters + * The active search filters. * * @var array * @since __DEPLOY_VERSION__ @@ -74,37 +73,31 @@ class HtmlView extends BaseHtmlView public $activeFilters; /** - * Is this view an Empty State + * Is this view in an empty state? * * @var boolean * @since __DEPLOY_VERSION__ */ private $isEmptyState = false; - /** - * Execute and display a template script. - * - * @param string $tpl The name of the template file to parse; automatically searches through the template paths. - * - * @return mixed A string if successful, otherwise an Error object. - */ - /** + * @inheritDoc + * * @param string $tpl The name of the template file to parse; automatically searches through the template paths. * * @return void * - * @throws Exception - * * @since __DEPLOY_VERSION__ + * @throws \Exception + * */ public function display($tpl = null): void { - $this->items = $this->get('Items'); - $this->pagination = $this->get('Pagination'); - $this->state = $this->get('State'); - $this->filterForm = $this->get('FilterForm'); + $this->items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->filterForm = $this->get('FilterForm'); $this->activeFilters = $this->get('ActiveFilters'); if (!\count($this->items) && $this->isEmptyState = $this->get('IsEmptyState')) @@ -115,7 +108,7 @@ public function display($tpl = null): void // Check for errors. if (\count($errors = $this->get('Errors'))) { - throw new \GenericDataException(implode("\n", $errors), 500); + throw new GenericDataException(implode("\n", $errors), 500); } // We don't need toolbar in the modal window. @@ -133,14 +126,14 @@ public function display($tpl = null): void * * @return void * - * @throws Exception - * * @since __DEPLOY_VERSION__ + * @throws \Exception + * */ protected function addToolbar(): void { $canDo = ContentHelper::getActions('com_scheduler'); - $user = Factory::getApplication()->getIdentity(); + $user = Factory::getApplication()->getIdentity(); /* * Get the toolbar object instance @@ -160,7 +153,7 @@ protected function addToolbar(): void if (!$this->isEmptyState && ($canDo->get('core.edit.state') || $user->authorise('core.admin'))) { - /** @var DropdownButton $dropdown */ + /** @var DropdownButton $dropdown */ $dropdown = $toolbar->dropdownButton('status-group') ->toggleSplit(false) ->text('JTOOLBAR_CHANGE_STATUS') diff --git a/administrator/language/en-GB/com_scheduler.ini b/administrator/language/en-GB/com_scheduler.ini index 55aa2197e8ea4..3ca3dfcd8ac98 100644 --- a/administrator/language/en-GB/com_scheduler.ini +++ b/administrator/language/en-GB/com_scheduler.ini @@ -102,7 +102,6 @@ COM_SCHEDULER_SELECT_INTERVAL_HOURS="-- Select Interval in Hours --" COM_SCHEDULER_SELECT_INTERVAL_MINUTES="-- Select Interval in Minutes --" COM_SCHEDULER_SELECT_INTERVAL_MONTHS="-- Select Interval in Months --" COM_SCHEDULER_SELECT_TASK_TYPE="Select task, %s" -COM_SCHEDULER_SELECT_TRIGGER="Trigger" COM_SCHEDULER_SELECT_TYPE="- Task Type -" COM_SCHEDULER_TABLE_CAPTION="Tasks List" COM_SCHEDULER_TASK="Task" diff --git a/installation/sql/mysql/extensions.sql b/installation/sql/mysql/extensions.sql index 1b77c38165e25..8bf5792775073 100644 --- a/installation/sql/mysql/extensions.sql +++ b/installation/sql/mysql/extensions.sql @@ -896,8 +896,6 @@ CREATE TABLE IF NOT EXISTS `#__scheduler_tasks` ( `asset_id` int NOT NULL UNIQUE DEFAULT '0', `title` varchar(255) NOT NULL DEFAULT '', `type` varchar(1024) NOT NULL COMMENT 'unique identifier for job defined by plugin', - -- Trigger type, default to PseudoCron (compatible everywhere). - `trigger` enum ('pseudo_cron', 'cron', 'visit_count') NOT NULL DEFAULT 'pseudo_cron' COMMENT 'Defines how job is triggered', `execution_rules` text COMMENT 'Execution Rules, Unprocessed', `cron_rules` text COMMENT 'Processed execution rules, crontab-like JSON form', `state` tinyint NOT NULL DEFAULT FALSE, diff --git a/installation/sql/postgresql/extensions.sql b/installation/sql/postgresql/extensions.sql index 5d21a78a0f710..827edcf609889 100644 --- a/installation/sql/postgresql/extensions.sql +++ b/installation/sql/postgresql/extensions.sql @@ -862,7 +862,6 @@ CREATE TABLE IF NOT EXISTS "#__scheduler_tasks" "type" varchar(1024) NOT NULL, "execution_rules" text, "cron_rules" text, - "trigger" varchar(12) NOT NULL DEFAULT 'pseudo_cron', "state" smallint NOT NULL DEFAULT '0', "last_exit_code" int NOT NULL DEFAULT '0', "last_execution" timestamp without time zone, From 954b32504ccd39d792df9b4fe8e8301ee8b2fb06 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Fri, 29 Oct 2021 12:48:06 +0530 Subject: [PATCH 520/615] Remove global task configuration config - Removes task configuration config from `plgSystemTasknotifications` plugin config. - ! Does not update any usages. --- .../tasknotification/tasknotification.xml | 46 ------------------- 1 file changed, 46 deletions(-) diff --git a/plugins/system/tasknotification/tasknotification.xml b/plugins/system/tasknotification/tasknotification.xml index 2e9a9e6a9dec0..f238225a69a59 100644 --- a/plugins/system/tasknotification/tasknotification.xml +++ b/plugins/system/tasknotification/tasknotification.xml @@ -17,50 +17,4 @@ language/en-GB/plg_system_tasknotification.ini language/en-GB/plg_system_tasknotification.sys.ini - - -
- - - - - - - - - - - - - - - - -
-
-
From 983ee4786c4fea0b19997c0fe2a741cbd124aaba Mon Sep 17 00:00:00 2001 From: ditsuke Date: Fri, 29 Oct 2021 12:50:30 +0530 Subject: [PATCH 521/615] Add task notification config as injected form - Task notification config is now injected into the task item form. - ! Usages are not updated. --- .../forms/task_notification.xml | 49 +++++++++++++++++++ .../tasknotification/tasknotification.php | 40 +++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 plugins/system/tasknotification/forms/task_notification.xml diff --git a/plugins/system/tasknotification/forms/task_notification.xml b/plugins/system/tasknotification/forms/task_notification.xml new file mode 100644 index 0000000000000..0b8ae9c40d07a --- /dev/null +++ b/plugins/system/tasknotification/forms/task_notification.xml @@ -0,0 +1,49 @@ + + + + +
+ + + + + + + + + + + + + + + + +
+
+
+ diff --git a/plugins/system/tasknotification/tasknotification.php b/plugins/system/tasknotification/tasknotification.php index 0399e2c565f1a..661b116ea8fa0 100644 --- a/plugins/system/tasknotification/tasknotification.php +++ b/plugins/system/tasknotification/tasknotification.php @@ -62,6 +62,7 @@ class PlgSystemTasknotification extends CMSPlugin implements SubscriberInterface public static function getSubscribedEvents(): array { return [ + 'onContentPrepareForm' => 'injectTaskNotificationFieldset', 'onTaskExecuteSuccess' => 'notifySuccess', 'onTaskExecuteFailure' => 'notifyFailure', 'onTaskRoutineNotFound' => 'notifyOrphan', @@ -69,6 +70,45 @@ public static function getSubscribedEvents(): array ]; } + /** + * Inject fields to support configuration of post-execution notifications into the task item form. + * + * @param EventInterface $event The onContentPrepareForm event. + * + * @return boolean True if successful. + * + * @since __DEPLOY_VERSION__ + */ + public function injectTaskNotificationFieldset(EventInterface $event): bool + { + /** @var Form $form */ + $form = $event->getArgument('0'); + + if ($form->getName() !== 'com_scheduler.task') + { + return true; + } + + $formFile = __DIR__ . "/forms/" . self::TASK_NOTIFICATION_FORM . '.xml'; + + try + { + $formFile = Path::check($formFile); + } + catch (Exception $e) + { + // Log? + return false; + } + + if (!File::exists($formFile)) + { + return false; + } + + return $form->loadFile($formFile); + } + /** * @param Event $event The onTaskExecuteFailure event. * From 2973ad8295966f02600717aa81b9bd5ce04801ba Mon Sep 17 00:00:00 2001 From: ditsuke Date: Fri, 29 Oct 2021 12:53:30 +0530 Subject: [PATCH 522/615] Improve plgSystemTaskNotification code style - Updates docs. - Improves docblocks, general code style for compliance with unenforced Joomla! style guide. --- .../tasknotification/tasknotification.php | 57 ++++++++++++------- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/plugins/system/tasknotification/tasknotification.php b/plugins/system/tasknotification/tasknotification.php index 661b116ea8fa0..094b3cc143129 100644 --- a/plugins/system/tasknotification/tasknotification.php +++ b/plugins/system/tasknotification/tasknotification.php @@ -1,19 +1,20 @@ - * @license GNU General Public License version 2 or later; see LICENSE.txt + * @copyright (C) 2021 Open Source Matters, Inc. + * @license GNU General Public License version 2 or later; see LICENSE.txt */ -/** Notifications for (scheduled) task executions. */ - // Restrict direct access defined('_JEXEC') or die; use Joomla\CMS\Application\CMSApplication; use Joomla\CMS\Factory; +use Joomla\CMS\Filesystem\File; +use Joomla\CMS\Filesystem\Path; +use Joomla\CMS\Form\Form; use Joomla\CMS\Language\Text; use Joomla\CMS\Log\Log; use Joomla\CMS\Mail\MailTemplate; @@ -21,23 +22,33 @@ use Joomla\CMS\User\UserFactoryInterface; use Joomla\Component\Scheduler\Administrator\Task\Status; use Joomla\Component\Scheduler\Administrator\Task\Task; -use Joomla\Database\DatabaseDriver; +use Joomla\Database\DatabaseInterface; use Joomla\Event\Event; +use Joomla\Event\EventInterface; use Joomla\Event\SubscriberInterface; use PHPMailer\PHPMailer\Exception as MailerException; /** - * Plugin class + * This plugin implements email notification functionality for Tasks configured through the Scheduler component. + * Notification configuration is supported on a per-task basis, which can be set-up through the Task item form, made + * possible by injecting the notification fields into the item form with a `onContentPrepareForm` listener.
+ * + * Notifications can be set-up on: task success, failure, fatal failure (task running too long or crashing the request), + * or on _orphaned_ task routines (missing parent plugin - either uninstalled, disabled or no longer offering a routine + * with the same ID). * * @since __DEPLOY_VERSION__ */ class PlgSystemTasknotification extends CMSPlugin implements SubscriberInterface { /** - * @var DatabaseDriver - * @since __DEPLOY_VERSION__ + * The task notification form. This form is merged into the task item form by {@see + * injectTaskNotificationFieldset()}. + * + * @var string + * @since __DEPLOY_VERSION__ */ - protected $db; + private const TASK_NOTIFICATION_FORM = 'task_notification'; /** * @var CMSApplication @@ -45,6 +56,12 @@ class PlgSystemTasknotification extends CMSPlugin implements SubscriberInterface */ protected $app; + /** + * @var DatabaseInterface + * @since __DEPLOY_VERSION__ + */ + protected $db; + /** * @var boolean * @since __DEPLOY_VERSION__ @@ -53,7 +70,7 @@ class PlgSystemTasknotification extends CMSPlugin implements SubscriberInterface /** - * Returns event subscriptions + * @inheritDoc * * @return array * @@ -114,8 +131,8 @@ public function injectTaskNotificationFieldset(EventInterface $event): bool * * @return void * - * @throws Exception * @since __DEPLOY_VERSION__ + * @throws Exception */ public function notifyFailure(Event $event): void { @@ -126,7 +143,7 @@ public function notifyFailure(Event $event): void // @todo safety checks, multiple files [?] $outFile = $event->getArgument('subject')->snapshot['output_file'] ?? ''; - $data = $this->getDataFromTask($event->getArgument('subject')); + $data = $this->getDataFromTask($event->getArgument('subject')); $this->sendMail('plg_system_tasknotification.failure_mail', $data, $outFile); } @@ -135,8 +152,8 @@ public function notifyFailure(Event $event): void * * @return void * - * @throws Exception * @since __DEPLOY_VERSION__ + * @throws Exception */ public function notifyOrphan(Event $event): void { @@ -154,8 +171,8 @@ public function notifyOrphan(Event $event): void * * @return void * - * @throws Exception * @since __DEPLOY_VERSION__ + * @throws Exception */ public function notifySuccess(Event $event): void { @@ -166,7 +183,7 @@ public function notifySuccess(Event $event): void // @todo safety checks, multiple files [?] $outFile = $event->getArgument('subject')->snapshot['output_file'] ?? ''; - $data = $this->getDataFromTask($event->getArgument('subject')); + $data = $this->getDataFromTask($event->getArgument('subject')); $this->sendMail('plg_system_tasknotification.success_mail', $data, $outFile); } @@ -175,8 +192,8 @@ public function notifySuccess(Event $event): void * * @return void * - * @throws Exception * @since __DEPLOY_VERSION__ + * @throws Exception */ public function notifyFatalRecovery(Event $event): void { @@ -216,13 +233,13 @@ private function getDataFromTask(Task $task): array * * @return void * - * @throws Exception * @since __DEPLOY_VERSION__ + * @throws Exception */ private function sendMail(string $template, array $data, string $attachment = ''): void { $app = $this->app; - $db = $this->db; + $db = $this->db; /** @var UserFactoryInterface $userFactory */ $userFactory = Factory::getContainer()->get('user.factory'); From 60e8eb037c3f539a0ad283d3c836aed6c73b8bf5 Mon Sep 17 00:00:00 2001 From: Benjamin Trenkle Date: Fri, 29 Oct 2021 13:11:11 +0200 Subject: [PATCH 523/615] Fix params display in task view --- .../components/com_scheduler/forms/task.xml | 72 +++++++++---------- .../com_scheduler/tmpl/task/edit.php | 26 ++++++- .../forms/task_notification.xml | 2 +- plugins/task/requests/forms/get_requests.xml | 2 +- 4 files changed, 60 insertions(+), 42 deletions(-) diff --git a/administrator/components/com_scheduler/forms/task.xml b/administrator/components/com_scheduler/forms/task.xml index b03bdf57007d3..1121ec6483904 100644 --- a/administrator/components/com_scheduler/forms/task.xml +++ b/administrator/components/com_scheduler/forms/task.xml @@ -233,45 +233,43 @@
- -
- - - - - -
-
+
+ + + + + +
-
- - - - - +
+ + + + +
diff --git a/administrator/components/com_scheduler/tmpl/task/edit.php b/administrator/components/com_scheduler/tmpl/task/edit.php index e23dc2e3193f3..85337ddf45572 100644 --- a/administrator/components/com_scheduler/tmpl/task/edit.php +++ b/administrator/components/com_scheduler/tmpl/task/edit.php @@ -34,9 +34,20 @@ $input = $app->getInput(); // ? -$this->ignore_fieldsets = ['aside', 'details', 'exec_hist', 'custom-cron-rules', 'basic', 'advanced']; +$this->ignore_fieldsets = ['aside', 'details', 'exec_hist', 'custom-cron-rules', 'basic', 'advanced', 'priority']; $this->useCoreUI = true; +$advancedFieldsets = $this->form->getFieldsets('params'); + +// Don't show the params fieldset, they will be loaded later +foreach ($advancedFieldsets as $fieldset) : + if (!empty($fieldset->showFront)) : + continue; + endif; + + $this->ignore_fieldsets[] = $fieldset->name; +endforeach; + // ? : Are these of use here? $isModal = $input->get('layout') === 'modal'; $layout = $isModal ? 'modal' : 'edit'; @@ -111,10 +122,19 @@ class="form-validate">
+
+ + form->renderFieldset('priority') ?> +
+ + showFront)) : + continue; + endif; ?>
- - form->renderFieldset('advanced') ?> + label ?: 'JGLOBAL_FIELDSET_' . $fieldset->name) ?> + form->renderFieldset($fieldset->name) ?>
+
diff --git a/plugins/system/tasknotification/forms/task_notification.xml b/plugins/system/tasknotification/forms/task_notification.xml index 0b8ae9c40d07a..45f4d2dd38a5b 100644 --- a/plugins/system/tasknotification/forms/task_notification.xml +++ b/plugins/system/tasknotification/forms/task_notification.xml @@ -2,7 +2,7 @@
-
+
-
+
Date: Sat, 30 Oct 2021 17:17:43 +0530 Subject: [PATCH 524/615] Add fieldset labels for task form - Adds missing fieldset labels. - Adds some comments and fixes marginally code-style. --- .../com_scheduler/tmpl/task/edit.php | 21 +++++++++---------- .../language/en-GB/com_scheduler.ini | 14 +++++++------ 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/administrator/components/com_scheduler/tmpl/task/edit.php b/administrator/components/com_scheduler/tmpl/task/edit.php index 85337ddf45572..3a0820eff3f15 100644 --- a/administrator/components/com_scheduler/tmpl/task/edit.php +++ b/administrator/components/com_scheduler/tmpl/task/edit.php @@ -1,12 +1,10 @@ - * @license GNU General Public License version 2 or later; see LICENSE.txt - * - * phpcs:ignoreFile + * @copyright (C) 2021 Open Source Matters, Inc. + * @license GNU General Public License version 2 or later; see LICENSE.txt */ // Restrict direct access @@ -33,15 +31,17 @@ $input = $app->getInput(); -// ? +// Fieldsets to be ignored by the `joomla.edit.params` template. $this->ignore_fieldsets = ['aside', 'details', 'exec_hist', 'custom-cron-rules', 'basic', 'advanced', 'priority']; + +// Used by the `joomla.edit.params` template to render the right template for UI tabs. $this->useCoreUI = true; $advancedFieldsets = $this->form->getFieldsets('params'); // Don't show the params fieldset, they will be loaded later foreach ($advancedFieldsets as $fieldset) : - if (!empty($fieldset->showFront)) : + if (!empty($fieldset->showFront) || $fieldset->name === 'task_params') : continue; endif; @@ -54,7 +54,6 @@ $tmpl = $isModal || $input->get('tmpl', '') === 'component' ? '&tmpl=component' : ''; ?> -
- + form->renderFieldset('priority') ?>
@@ -131,7 +130,7 @@ class="form-validate"> continue; endif; ?>
- label ?: 'JGLOBAL_FIELDSET_' . $fieldset->name) ?> + label ?: 'COM_SCHEDULER_FIELDSET_' . $fieldset->name) ?> form->renderFieldset($fieldset->name) ?>
diff --git a/administrator/language/en-GB/com_scheduler.ini b/administrator/language/en-GB/com_scheduler.ini index 3ca3dfcd8ac98..69733f22e7d52 100644 --- a/administrator/language/en-GB/com_scheduler.ini +++ b/administrator/language/en-GB/com_scheduler.ini @@ -24,25 +24,28 @@ COM_SCHEDULER_EMPTYSTATE_CONTENT="No Tasks!" COM_SCHEDULER_EMPTYSTATE_TITLE="No Tasks have been created yet!" COM_SCHEDULER_ERROR_FORBIDDEN_JUMP_TO_ADD_VIEW="You need to select a Task type first!" COM_SCHEDULER_ERROR_INVALID_TASK_TYPE="Invalid Task Type!" +COM_SCHEDULER_FIELDSET_BASIC="Basic Fields" +COM_SCHEDULER_FIELDSET_CRON_OPTIONS="Cron Match" +COM_SCHEDULER_FIELDSET_EXEC_HIST="Execution History" +COM_SCHEDULER_FIELDSET_LOGGING="Logging" +COM_SCHEDULER_FIELDSET_NOTIFICATIONS="Notifications" +COM_SCHEDULER_FIELDSET_PRIORITY="Priority" +COM_SCHEDULER_FIELDSET_TASK_PARAMS="Task Parameters" COM_SCHEDULER_FIELD_HINT_LOG_FILE_AUTO="defaults to 'task_.log.php'" COM_SCHEDULER_FIELD_LABEL_EXEC_RULE="Execution Rule" +COM_SCHEDULER_FIELD_LABEL_INDIVIDUAL_LOG="Individual Task Logs" COM_SCHEDULER_FIELD_LABEL_INTERVAL_DAYS="Interval in Days" COM_SCHEDULER_FIELD_LABEL_INTERVAL_HOURS="Interval in Hours" COM_SCHEDULER_FIELD_LABEL_INTERVAL_MINUTES="Interval in Minutes" COM_SCHEDULER_FIELD_LABEL_INTERVAL_MONTHS="Interval in Months" COM_SCHEDULER_FIELD_LABEL_LOG_FILE="Log Filename" COM_SCHEDULER_FIELD_LABEL_SHOW_ORPHANED="Show Orphaned" -COM_SCHEDULER_FIELD_LABEL_INDIVIDUAL_LOG="Individual Task Logs" COM_SCHEDULER_FIELD_OPTION_INTERVAL_MATCH_DAYS_M="Days of Month" COM_SCHEDULER_FIELD_OPTION_INTERVAL_MATCH_DAYS_W="Days of Week" COM_SCHEDULER_FIELD_OPTION_INTERVAL_MATCH_HOURS="Hours" COM_SCHEDULER_FIELD_OPTION_INTERVAL_MATCH_MINUTES="Minutes" COM_SCHEDULER_FIELD_OPTION_INTERVAL_MATCH_MONTHS="Months" COM_SCHEDULER_FIELD_TASK_TYPE="Type ID" -COM_SCHEDULER_FIELDSET_BASIC="Basic Fields" -COM_SCHEDULER_FIELDSET_CRON_OPTIONS="Cron Match" -COM_SCHEDULER_FIELDSET_EXEC_HIST="Execution History" -COM_SCHEDULER_FIELDSET_PARAMS_FS="Task Parameters" COM_SCHEDULER_FILTER_SEARCH_DESC="Search in Task title and note. Prefix with 'ID:' to search for a task ID" COM_SCHEDULER_FILTER_SEARCH_LABEL="Search Tasks" COM_SCHEDULER_FORM_TITLE_EDIT="Edit Task" @@ -105,7 +108,6 @@ COM_SCHEDULER_SELECT_TASK_TYPE="Select task, %s" COM_SCHEDULER_SELECT_TYPE="- Task Type -" COM_SCHEDULER_TABLE_CAPTION="Tasks List" COM_SCHEDULER_TASK="Task" -COM_SCHEDULER_TASK_PARAMS_FIELDSET_LABEL="Task Parameters" COM_SCHEDULER_TASK_PRIORITY_ASC="Task Priority, Ascending" COM_SCHEDULER_TASK_PRIORITY_DESC="Task Priority, Descending" COM_SCHEDULER_TASK_TYPE="Task Type" From 31e9b8f66e61ab3bb015390a60bada30b6318e71 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 31 Oct 2021 18:06:24 +0530 Subject: [PATCH 525/615] Update task notification logic - Replaces checks with updated task item configuration. - Improves logging (additional checks). - Makes file attachment handling safer. - Fixes/updates code-style. --- .../tasknotification/tasknotification.php | 63 ++++++++++++++++--- 1 file changed, 53 insertions(+), 10 deletions(-) diff --git a/plugins/system/tasknotification/tasknotification.php b/plugins/system/tasknotification/tasknotification.php index 094b3cc143129..431c222d48345 100644 --- a/plugins/system/tasknotification/tasknotification.php +++ b/plugins/system/tasknotification/tasknotification.php @@ -127,6 +127,8 @@ public function injectTaskNotificationFieldset(EventInterface $event): bool } /** + * Send out email notifications on Task execution failure if task configuration allows it. + * * @param Event $event The onTaskExecuteFailure event. * * @return void @@ -136,7 +138,10 @@ public function injectTaskNotificationFieldset(EventInterface $event): bool */ public function notifyFailure(Event $event): void { - if (!(int) $this->params->get('failure_mail', 1)) + /** @var Task $task */ + $task = $event->getArgument('subject'); + + if (!(int) $task->get('params.notifications.failure_mail', 1)) { return; } @@ -148,6 +153,10 @@ public function notifyFailure(Event $event): void } /** + * Send out email notifications on orphaned task if task configuration allows.
+ * A task is `orphaned` if the task's parent plugin has been removed/disabled, or no longer offers a task + * with the same routine ID. + * * @param Event $event The onTaskRoutineNotFound event. * * @return void @@ -157,7 +166,10 @@ public function notifyFailure(Event $event): void */ public function notifyOrphan(Event $event): void { - if (!(int) $this->params->get('orphan_mail', 1)) + /** @var Task $task */ + $task = $event->getArgument('subject'); + + if (!(int) $task->get('params.notifications.orphan_mail', 1)) { return; } @@ -167,6 +179,8 @@ public function notifyOrphan(Event $event): void } /** + * Send out email notifications on Task execution success if task configuration allows. + * * @param Event $event The onTaskExecuteSuccess event. * * @return void @@ -176,7 +190,10 @@ public function notifyOrphan(Event $event): void */ public function notifySuccess(Event $event): void { - if (!(int) $this->params->get('success_mail', 0)) + /** @var Task $task */ + $task = $event->getArgument('subject'); + + if (!(int) $task->get('params.notifications.success_mail', 0)) { return; } @@ -188,6 +205,13 @@ public function notifySuccess(Event $event): void } /** + * Send out email notifications on fatal recovery of task execution if task configuration allows.
+ * Fatal recovery indicated that the task either crashed the parent process or its execution lasted longer + * than the global task timeout (this is configurable through the Scheduler component configuration). + * In the latter case, the global task timeout should be adjusted so that this false positive can be avoided. + * This stands as a limitation of the Scheduler's current task execution implementation, which doesn't involve + * keeping track of the parent PHP process which could enable keeping track of the task's status. + * * @param Event $event The onTaskRecoverFailure event. * * @return void @@ -197,7 +221,10 @@ public function notifySuccess(Event $event): void */ public function notifyFatalRecovery(Event $event): void { - if (!(int) $this->params->get('fatal_failure_mail', 1)) + /** @var Task $task */ + $task = $event->getArgument('subject'); + + if (!(int) $task->get('params.notifications.fatal_failure_mail', 1)) { return; } @@ -244,7 +271,7 @@ private function sendMail(string $template, array $data, string $attachment = '' /** @var UserFactoryInterface $userFactory */ $userFactory = Factory::getContainer()->get('user.factory'); - // Get all admin users + // Get all users who are not blocked and have opted in for system mails. $query = $db->getQuery(true); $query->select($db->qn(['name', 'email', 'sendEmail', 'id'])) @@ -263,7 +290,16 @@ private function sendMail(string $template, array $data, string $attachment = '' return; } - // Mail all users with access to scheduler, opt-in mail + if ($users === null) + { + Log::add(Text::_('PLG_SYSTEM_TASK_NOTIFICATION_USER_FETCH_FAIL'), Log::ERROR); + + return; + } + + $mailSent = false; + + // Mail all matching users who also have the `core.manage` privilege for com_scheduler. foreach ($users as $user) { $user = $userFactory->loadUserById($user->id); @@ -276,21 +312,28 @@ private function sendMail(string $template, array $data, string $attachment = '' $mailer->addTemplateData($data); $mailer->addRecipient($user->email); - // @todo improve and make safe - if ($attachment) + if (!empty($attachment) + && File::exists($attachment) + && is_file($attachment)) { - // @todo we allow multiple files + // @todo we allow multiple files [?] $attachName = pathinfo($attachment, PATHINFO_BASENAME); $mailer->addAttachment($attachName, $attachment); } $mailer->send(); + $mailSent = true; } catch (MailerException $exception) { - Log::Add(Text::_('PLG_SYSTEM_TASK_NOTIFICATION_NOTIFY_SEND_EMAIL_FAIL')); + Log::add(Text::_('PLG_SYSTEM_TASK_NOTIFICATION_NOTIFY_SEND_EMAIL_FAIL'), Log::ERROR); } } } + + if (!$mailSent) + { + Log::add(Text::_('PLG_SYSTEM_TASK_NOTIFICATION_NO_MAIL_SENT'), Log::WARNING); + } } } From daffabb6b80a9960957adc68c9da52312f5910b5 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 31 Oct 2021 18:07:56 +0530 Subject: [PATCH 526/615] Update plgSystemTaskNotification language file - Adds new constants for logging. - Fixes ordering. --- .../language/en-GB/plg_system_tasknotification.ini | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/plugins/system/tasknotification/language/en-GB/plg_system_tasknotification.ini b/plugins/system/tasknotification/language/en-GB/plg_system_tasknotification.ini index b2fba1c03a116..ba7edac52e748 100644 --- a/plugins/system/tasknotification/language/en-GB/plg_system_tasknotification.ini +++ b/plugins/system/tasknotification/language/en-GB/plg_system_tasknotification.ini @@ -3,12 +3,14 @@ PLG_SYSTEM_TASK_NOTIFICATION_FAILURE_MAIL_BODY="Hello,\n\n\nPlanned execution of PLG_SYSTEM_TASK_NOTIFICATION_FAILURE_MAIL_SUBJECT="Task Failure" PLG_SYSTEM_TASK_NOTIFICATION_FATAL_MAIL_BODY="Hello,\n\nPlanned execution of Scheduler Task#{TASK_ID}, {TASK_TITLE}, recovered from a fatal failure.\n\nThis could mean that the task execution exhausted the system resources or the restrictions from the PHP INI.\n\nPlease visit the Joomla! backend for more information." PLG_SYSTEM_TASK_NOTIFICATION_FATAL_MAIL_SUBJECT="Task Recover from Fatal Failure" +PLG_SYSTEM_TASK_NOTIFICATION_LABEL_FAILURE_MAIL_TOGGLE="Notifications on Task Failure" +PLG_SYSTEM_TASK_NOTIFICATION_LABEL_FATAL_FAILURE_MAIL_TOGGLE="Notifications on Fatal Failures/Crashes (Recommended)" +PLG_SYSTEM_TASK_NOTIFICATION_LABEL_ORPHANED_TASK_MAIL_TOGGLE="Notifications on Orphaned Tasks (Recommended)" +PLG_SYSTEM_TASK_NOTIFICATION_LABEL_SUCCESS_MAIL_TOGGLE="Notifications on Task Success" +PLG_SYSTEM_TASK_NOTIFICATION_NO_MAIL_SENT="Could not send task notification to any user. This either means that mailer is not set up properly or no user with system emails enabled, com_scheduler `core.manage` privilege exists." PLG_SYSTEM_TASK_NOTIFICATION_ORPHAN_MAIL_BODY="Hello,\n\nScheduled Task#{TASK_ID}, {TASK_TITLE}, has been orphaned. This likely means that the provider plugin was removed or disabled from your Joomla! installation.\n\nPlease visit the Joomla! backend to investigate." PLG_SYSTEM_TASK_NOTIFICATION_ORPHAN_MAIL_SUBJECT="New Orphaned Task" PLG_SYSTEM_TASK_NOTIFICATION_SUCCESS_MAIL_BODY="Hello,\n\nScheduled Task#{TASK_ID}, {TASK_TITLE}, has been successfully executed at {EXEC_DATE_TIME}.\n\n{TASK_OUTPUT}" PLG_SYSTEM_TASK_NOTIFICATION_SUCCESS_MAIL_SUBJECT="Task Successful" +PLG_SYSTEM_TASK_NOTIFICATION_USER_FETCH_FAIL="Failed to fetch users to send notifications to." PLG_SYSTEM_TASK_NOTIFICATION_XML_DESCRIPTION="Responsible for email notifications for execution of Scheduled tasks." -PLG_SYSTEM_TASK_NOTIFICATION_LABEL_SUCCESS_MAIL_TOGGLE="Notifications on Task Success" -PLG_SYSTEM_TASK_NOTIFICATION_LABEL_FAILURE_MAIL_TOGGLE="Notifications on Task Failure" -PLG_SYSTEM_TASK_NOTIFICATION_LABEL_FATAL_FAILURE_MAIL_TOGGLE="Notifications on Fatal Failures/Crashes (Recommended)" -PLG_SYSTEM_TASK_NOTIFICATION_LABEL_ORPHANED_TASK_MAIL_TOGGLE="Notifications on Orphaned Tasks (Recommended)" From eb126f2080a30f9751c9ff95c2a0f5312fca3f82 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 31 Oct 2021 23:33:24 +0530 Subject: [PATCH 527/615] Fix Task driver behavior The run() method now updates the object state instead of leaving it to releaseLock(). The class continues to appear a clunky build :D. --- .../com_scheduler/src/Task/Task.php | 59 ++++++++++--------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/administrator/components/com_scheduler/src/Task/Task.php b/administrator/components/com_scheduler/src/Task/Task.php index cecf7cef59d80..babdfbc9cb69e 100644 --- a/administrator/components/com_scheduler/src/Task/Task.php +++ b/administrator/components/com_scheduler/src/Task/Task.php @@ -27,6 +27,7 @@ use Joomla\Database\DatabaseInterface; use Joomla\Database\ParameterType; use Joomla\Registry\Registry; +use Psr\Log\InvalidArgumentException; use Psr\Log\LoggerAwareInterface; use Psr\Log\LoggerAwareTrait; @@ -118,7 +119,6 @@ public function getRecord(): object // ! Probably, an array instead $recObject = $this->toObject(); - // phpcs:ignore $recObject->cron_rules = (array) $recObject->cron_rules; return $recObject; @@ -137,7 +137,6 @@ public function run(): bool /* * Dispatch event if task lock is not released (NULL). This only happens if the task execution * was interrupted by a fatal failure. - * @todo add listeners. We can have opt-in hooks for email (priority), push-bullet, etc */ if ($this->get('locked') !== null) { @@ -191,6 +190,18 @@ public function run(): bool $this->snapshot['netDuration'] = $this->snapshot['taskEnd'] - $this->snapshot['taskStart']; $this->snapshot = array_merge($this->snapshot, $resultSnapshot); + // @todo make the ExecRuleHelper usage less ugly, perhaps it should be composed into Task + // Update object state. + $this->set('last_execution', Factory::getDate('@' . $this->snapshot['taskStart'])->toSql()); + $this->set('next_execution', (new ExecRuleHelper($this->toObject()))->nextExec()); + $this->set('last_exit_code', $this->snapshot['status']); + $this->set('times_executed', $this->get('times_executed') + 1); + + if ($this->snapshot['status'] !== Status::OK) + { + $this->set('times_failed', $this->get('times_failed') + 1); + } + if (!$this->releaseLock()) { $this->snapshot['status'] = Status::NO_RELEASE; @@ -200,7 +211,7 @@ public function run(): bool } /** - * Get the task execution snapshot, + * Get the task execution snapshot. * ! Access locations will need updates once a more robust Snapshot container is implemented. * * @return array @@ -267,7 +278,6 @@ public function acquireLock(): bool * Remove the pseudo-lock and optionally update the task record. * * @param bool $update If true, the record is updated with the snapshot - * TODO: Update object state * * @return boolean * @@ -288,25 +298,26 @@ public function releaseLock(bool $update = true): bool if ($update) { - $id = $this->get('id'); - - // @todo make this look less ugly - // @todo this is broken! fix it and do it right by updating times in the run() method !! - $nextExec = (new ExecRuleHelper($this->toObject()))->nextExec(false, true); - $exitCode = $this->snapshot['status'] ?? Status::NO_EXIT; - $now = Factory::getDate('now', 'GMT')->toSql(); + $exitCode = $this->get('last_exit_code'); + $lastExec = $this->get('last_execution'); + $nextExec = $this->get('next_execution'); + $timesFailed = $this->get('times_failed'); + $timesExecuted = $this->get('times_executed'); $query->set( [ - 't.last_execution = :now', - 't.next_execution = :nextExec', 't.last_exit_code = :exitCode', - 't.times_executed = t.times_executed + 1' + 't.last_execution = :lastExec', + 't.next_execution = :nextExec', + 't.times_executed = :times_executed', + 't.times_failed = :times_failed' ] ) - ->bind(':nextExec', $nextExec) ->bind(':exitCode', $exitCode, ParameterType::INTEGER) - ->bind(':now', $now); + ->bind(':lastExec', $lastExec) + ->bind(':nextExec', $nextExec) + ->bind(':times_executed', $timesExecuted) + ->bind(':times_failed', $timesFailed); if ($exitCode !== Status::OK) { @@ -317,19 +328,6 @@ public function releaseLock(bool $update = true): bool try { $db->setQuery($query)->execute(); - - if ($update) - { - $this->set('last_execution', $now); - $this->set('next_execution', $nextExec); - $this->set('last_exit_code', $exitCode); - $this->set('times_executed', $this->get('times_executed') + 1); - - if ($exitCode !== Status::OK) - { - $this->set('times_failed', $this->get('times_failed') + 1); - } - } } catch (\RuntimeException $e) { @@ -353,6 +351,7 @@ public function releaseLock(bool $update = true): bool * @return void * * @since __DEPLOY_VERSION__ + * @throws InvalidArgumentException */ public function log(string $message, string $priority = 'info'): void { @@ -398,6 +397,8 @@ public function skipExecution(): void * @return boolean If true, execution was successful * * @since __DEPLOY_VERSION__ + * @throws \UnexpectedValueException + * @throws \BadMethodCallException */ public function isSuccess(): bool { From c3c83d6cfd10fc6018408e8d4340bf60e043826a Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 31 Oct 2021 23:35:11 +0530 Subject: [PATCH 528/615] Fix TasksRunCommand regression --- libraries/src/Console/TasksRunCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/src/Console/TasksRunCommand.php b/libraries/src/Console/TasksRunCommand.php index e2492842a41e6..91566c4b64e15 100644 --- a/libraries/src/Console/TasksRunCommand.php +++ b/libraries/src/Console/TasksRunCommand.php @@ -119,7 +119,7 @@ protected function doExecute(InputInterface $input, OutputInterface $output): in { $cStart = microtime(true); $task = $scheduler->runTask($record->id); - $exit = $task->isSuccess(); + $exit = $task->getContent()['status']; $duration = microtime(true) - $cStart; $key = (array_key_exists($exit, $outTextMap)) ? $exit : 'N/A'; $this->ioStyle->writeln(sprintf($outTextMap[$key], $record->id, $record->title, $duration, $exit)); From 064f76f7307b2f6cdfe1dbcbc22b935b833b4494 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 31 Oct 2021 23:37:58 +0530 Subject: [PATCH 529/615] Fix scheduleRunner default behaviour - Uses again sensible defaults (enabled lazy cron). - Check webcron.enabled. - Some useful logging. - Improved docblocks. --- .../system/schedulerunner/schedulerunner.php | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/plugins/system/schedulerunner/schedulerunner.php b/plugins/system/schedulerunner/schedulerunner.php index 4d4524d6a7aab..0a50f8580fc17 100644 --- a/plugins/system/schedulerunner/schedulerunner.php +++ b/plugins/system/schedulerunner/schedulerunner.php @@ -16,6 +16,7 @@ use Joomla\CMS\Factory; use Joomla\CMS\Form\Form; use Joomla\CMS\Language\Text; +use Joomla\CMS\Log\Log; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Router\Route; use Joomla\CMS\Table\Extension; @@ -114,7 +115,7 @@ public function injectLazyJS(Event $event): void $config = ComponentHelper::getParams('com_scheduler'); - if (!$config->get('lazy_scheduler.enabled')) + if (!$config->get('lazy_scheduler.enabled', true)) { return; } @@ -144,7 +145,7 @@ public function runLazyCron() { $config = ComponentHelper::getParams('com_scheduler'); - if (!$config->get('lazy_scheduler.enabled')) + if (!$config->get('lazy_scheduler.enabled', true)) { throw new \Exception(Text::_('JERROR_ALERTNOAUTHOR'), 403); } @@ -171,8 +172,13 @@ public function runLazyCron() public function runWebCron() { $config = ComponentHelper::getParams('com_scheduler'); + $hash = $config->get('webcron.key', ''); - $hash = $config->get('webcron.key'); + if (!$config->get('webcron.enabled', false)) + { + Log::add(Text::_('PLG_SYSTEM_SCHEDULE_RUNNER_WEBCRON_DISABLED')); + throw new \Exception(Text::_('JERROR_ALERTNOAUTHOR'), 403); + } if (!strlen($hash) || $hash !== $this->app->input->get('hash')) { @@ -200,7 +206,7 @@ public function runTestCron(Event $event) { $id = (int) $this->app->input->getInt('id'); - $user = Factory::getUser(); + $user = Factory::getApplication()->getIdentity(); if (empty($id) || !$user->authorise('core.testrun', 'com_scheduler.task.' . $id)) { @@ -234,13 +240,16 @@ protected function runScheduler(int $id = 0, bool $unpublished = false): ?Task /** * Enhance the scheduler config form by dynamically populating or removing display fields. - * @todo Move to another plugin? * * @param EventInterface $event The onContentPrepareForm event. * * @return void * * @since __DEPLOY_VERSION__ + * @throws UnexpectedValueException + * @throws RuntimeException + * @todo Move to another plugin? + * */ public function enhanceSchedulerConfig(EventInterface $event): void { From 882a5f6846b7fe602dfc0226296a931cbe487ea8 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Sun, 31 Oct 2021 23:38:27 +0530 Subject: [PATCH 530/615] Update scheduleRunner language files Adds new constant for a logging string. --- .../schedulerunner/language/en-GB/plg_system_schedulerunner.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/system/schedulerunner/language/en-GB/plg_system_schedulerunner.ini b/plugins/system/schedulerunner/language/en-GB/plg_system_schedulerunner.ini index 1e7918f8ae9f7..74b6c8d6ca4b8 100644 --- a/plugins/system/schedulerunner/language/en-GB/plg_system_schedulerunner.ini +++ b/plugins/system/schedulerunner/language/en-GB/plg_system_schedulerunner.ini @@ -4,4 +4,5 @@ ; Note : All ini files need to be saved as UTF-8 PLG_SYSTEM_SCHEDULE_RUNNER="System - Schedule Runner" +PLG_SYSTEM_SCHEDULE_RUNNER_WEBCRON_DISABLED="Webcron called but has not been enabled in the Scheduler component config." PLG_SYSTEM_SCHEDULE_RUNNER_XML_DESCRIPTION="This plugin lazily runs due tasks, managed through com_scheduler" From 9fea821e2442f67db7557a5649b148c0a3c038ad Mon Sep 17 00:00:00 2001 From: ditsuke Date: Mon, 1 Nov 2021 02:20:37 +0530 Subject: [PATCH 531/615] Update and fix code-style - Fix license header formatting. - Fix doc phpdoc tag ordering. - Cleanup and marginally improve doc-blocks. - Fix unqualified global refs in doc-blocks. - Misc formatting fixes/improvements. - Remove phpcs ignores. --- .../com_scheduler/services/provider.php | 10 +-- .../src/Controller/DisplayController.php | 17 ++-- .../src/Controller/TaskController.php | 18 ++-- .../src/Controller/TasksController.php | 10 +-- .../src/Event/ExecuteTaskEvent.php | 11 ++- .../src/Extension/SchedulerComponent.php | 14 ++-- .../com_scheduler/src/Field/CronField.php | 61 ++++++++------ .../src/Field/ExecutionRuleField.php | 14 ++-- .../com_scheduler/src/Field/IntervalField.php | 12 +-- .../src/Field/TaskStateField.php | 16 ++-- .../com_scheduler/src/Field/TaskTypeField.php | 22 +++-- .../src/Helper/ExecRuleHelper.php | 25 +++--- .../src/Helper/SchedulerHelper.php | 20 ++--- .../com_scheduler/src/Model/SelectModel.php | 16 ++-- .../com_scheduler/src/Model/TaskModel.php | 38 ++++----- .../com_scheduler/src/Model/TasksModel.php | 43 +++++----- .../src/Rule/ExecutionRulesRule.php | 36 ++++---- .../com_scheduler/src/Scheduler/Scheduler.php | 39 +++++---- .../com_scheduler/src/Table/TaskTable.php | 4 +- .../com_scheduler/src/Task/Task.php | 83 ++++++++++--------- .../com_scheduler/src/Task/TaskOption.php | 20 ++--- .../com_scheduler/src/Task/TaskOptions.php | 17 ++-- .../src/View/Select/HtmlView.php | 33 ++++---- .../com_scheduler/src/View/Task/HtmlView.php | 26 +++--- .../com_scheduler/tmpl/select/default.php | 9 +- .../com_scheduler/tmpl/select/modal.php | 9 +- .../com_scheduler/tmpl/tasks/default.php | 8 +- .../com_scheduler/tmpl/tasks/empty_state.php | 8 +- libraries/src/Console/TasksListCommand.php | 26 +++--- libraries/src/Console/TasksRunCommand.php | 37 +++++---- plugins/task/requests/requests.php | 4 +- 31 files changed, 352 insertions(+), 354 deletions(-) diff --git a/administrator/components/com_scheduler/services/provider.php b/administrator/components/com_scheduler/services/provider.php index 948ce66d8d88d..dfb7f317a679e 100644 --- a/administrator/components/com_scheduler/services/provider.php +++ b/administrator/components/com_scheduler/services/provider.php @@ -1,14 +1,12 @@ - * @license GNU General Public License version 2 or later; see LICENSE.txt + * @copyright (C) 2021 Open Source Matters, Inc. + * @license GNU General Public License version 2 or later; see LICENSE.txt */ -/** Returns the service provider class for com_scheduler. */ - // Restrict direct access defined('_JEXEC') or die; diff --git a/administrator/components/com_scheduler/src/Controller/DisplayController.php b/administrator/components/com_scheduler/src/Controller/DisplayController.php index 909ad0bb715e7..839f70c34f1d0 100644 --- a/administrator/components/com_scheduler/src/Controller/DisplayController.php +++ b/administrator/components/com_scheduler/src/Controller/DisplayController.php @@ -1,10 +1,10 @@ - * @license GNU General Public License version 2 or later; see LICENSE.txt + * @copyright (C) 2021 Open Source Matters, Inc. + * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Component\Scheduler\Administrator\Controller; @@ -31,12 +31,13 @@ class DisplayController extends BaseController /** * @param boolean $cachable If true, the view output will be cached - * @param array $urlparams An array of safe url parameters and their variable types, for valid values see {@link InputFilter::clean()}. + * @param array $urlparams An array of safe url parameters and their variable types, for valid values see + * {@link InputFilter::clean()}. * * @return BaseController|boolean Returns either a BaseController object to support chaining, or false on failure * - * @throws Exception * @since __DEPLOY_VERSION__ + * @throws \Exception */ public function display($cachable = false, $urlparams = array()) { @@ -70,7 +71,7 @@ public function display($cachable = false, $urlparams = array()) private function validateEntry(string $layout = 'edit'): bool { $context = 'com_scheduler'; - $id = $this->input->getInt('id'); + $id = $this->input->getInt('id'); $isValid = true; switch ($layout) @@ -79,7 +80,7 @@ private function validateEntry(string $layout = 'edit'): bool // True if controller was called and verified permissions $inEditList = $this->checkEditId("$context.edit.task", $id); - $isNew = ($id == 0); + $isNew = ($id == 0); // For new item, entry is invalid if task type was not selected through SelectView if ($isNew && !$this->app->getUserState("$context.add.task.task_type")) diff --git a/administrator/components/com_scheduler/src/Controller/TaskController.php b/administrator/components/com_scheduler/src/Controller/TaskController.php index 215b527616b31..83a37cb69b2e7 100644 --- a/administrator/components/com_scheduler/src/Controller/TaskController.php +++ b/administrator/components/com_scheduler/src/Controller/TaskController.php @@ -1,14 +1,12 @@ - * @license GNU General Public License version 2 or later; see LICENSE.txt + * @copyright (C) 2021 Open Source Matters, Inc. + * @license GNU General Public License version 2 or later; see LICENSE.txt */ -/** Implements the MVC controller for TaskModel. */ - namespace Joomla\Component\Scheduler\Administrator\Controller; // Restrict direct access @@ -21,11 +19,9 @@ use Joomla\Component\Scheduler\Administrator\Helper\SchedulerHelper; /** - * MVC Controller for TaskView. + * MVC Controller for the item configuration page (TaskView). * * @since __DEPLOY_VERSION__ - * @todo check if we need more overrides - * */ class TaskController extends FormController { @@ -33,8 +29,8 @@ class TaskController extends FormController * Add a new record * * @return boolean - * @throws Exception * @since __DEPLOY_VERSION__ + * @throws \Exception */ public function add(): bool { @@ -108,7 +104,7 @@ protected function allowEdit($data = array(), $key = 'id'): bool /** * Zero record (id:0), return component edit permission by calling parent controller method - * ? : Is this the right way to do this? + * ?: Is this the right way to do this? */ if ($recordId === 0) { diff --git a/administrator/components/com_scheduler/src/Controller/TasksController.php b/administrator/components/com_scheduler/src/Controller/TasksController.php index 414834054b3ef..bfdfafb7e9735 100644 --- a/administrator/components/com_scheduler/src/Controller/TasksController.php +++ b/administrator/components/com_scheduler/src/Controller/TasksController.php @@ -1,14 +1,12 @@ - * @license GNU General Public License version 2 or later; see LICENSE.txt + * @copyright (C) 2021 Open Source Matters, Inc. + * @license GNU General Public License version 2 or later; see LICENSE.txt */ -/** Implements the MVC controller for TasksView. */ - namespace Joomla\Component\Scheduler\Administrator\Controller; // Restrict direct access diff --git a/administrator/components/com_scheduler/src/Event/ExecuteTaskEvent.php b/administrator/components/com_scheduler/src/Event/ExecuteTaskEvent.php index 86b80eed41ca5..9a1635410cf27 100644 --- a/administrator/components/com_scheduler/src/Event/ExecuteTaskEvent.php +++ b/administrator/components/com_scheduler/src/Event/ExecuteTaskEvent.php @@ -1,10 +1,10 @@ - * @license GNU General Public License version 2 or later; see LICENSE.txt + * @copyright (C) 2021 Open Source Matters, Inc. + * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Component\Scheduler\Administrator\Event; @@ -28,9 +28,8 @@ class ExecuteTaskEvent extends AbstractEvent * @param string $name The event name. * @param array $arguments The event arguments. * - * @throws \BadMethodCallException - * * @since __DEPLOY_VERSION__ + * @throws \BadMethodCallException */ public function __construct($name, array $arguments = array()) { diff --git a/administrator/components/com_scheduler/src/Extension/SchedulerComponent.php b/administrator/components/com_scheduler/src/Extension/SchedulerComponent.php index 36a5d469bfd53..64f03f1f53873 100644 --- a/administrator/components/com_scheduler/src/Extension/SchedulerComponent.php +++ b/administrator/components/com_scheduler/src/Extension/SchedulerComponent.php @@ -1,14 +1,12 @@ - * @license GNU General Public License version 2 or later; see LICENSE.txt + * @copyright (C) 2021 Open Source Matters, Inc. + * @license GNU General Public License version 2 or later; see LICENSE.txt */ -/** Implements the Scheduler component class. */ - namespace Joomla\Component\Scheduler\Administrator\Extension; // Restrict direct access @@ -20,10 +18,10 @@ use Psr\Container\ContainerInterface; /** - * Component Class - * ! Does not do much yet + * Component class for com_scheduler. * * @since __DEPLOY_VERSION__ + * @todo Set up logger(s) here. */ class SchedulerComponent extends MVCComponent implements BootableExtensionInterface { diff --git a/administrator/components/com_scheduler/src/Field/CronField.php b/administrator/components/com_scheduler/src/Field/CronField.php index cc6e086d81efd..5c43c8a377c7c 100644 --- a/administrator/components/com_scheduler/src/Field/CronField.php +++ b/administrator/components/com_scheduler/src/Field/CronField.php @@ -1,10 +1,10 @@ - * @license GNU General Public License version 2 or later; see LICENSE.txt + * @copyright (C) 2021 Open Source Matters, Inc. + * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Component\Scheduler\Administrator\Field; @@ -36,7 +36,7 @@ class CronField extends ListField 'hours', 'days_month', 'months', - 'days_week' + 'days_week', ]; /** @@ -47,11 +47,11 @@ class CronField extends ListField * @since __DEPLOY_VERSION__ */ private const OPTIONS_RANGE = [ - 'minutes' => [0, 59], - 'hours' => [0, 23], - 'days_week' => [0, 6], + 'minutes' => [0, 59], + 'hours' => [0, 23], + 'days_week' => [0, 6], 'days_month' => [1, 31], - 'months' => [1, 12] + 'months' => [1, 12], ]; /** @@ -62,14 +62,14 @@ class CronField extends ListField * @since __DEPLOY_VERSION__ */ private const PREPARED_RESPONSE_LABELS = [ - 'months' => [ + 'months' => [ 'JANUARY', 'FEBRUARY', 'MARCH', 'APRIL', 'MAY', 'JUNE', - 'JULY', 'AUGUST', 'SEPTEMBER', 'OCTOBER', 'NOVEMBER', 'DECEMBER' + 'JULY', 'AUGUST', 'SEPTEMBER', 'OCTOBER', 'NOVEMBER', 'DECEMBER', ], 'days_week' => [ 'MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', - 'FRIDAY', 'SATURDAY', 'SUNDAY' - ] + 'FRIDAY', 'SATURDAY', 'SUNDAY', + ], ]; /** @@ -108,11 +108,12 @@ class CronField extends ListField /** * Override the parent method to set deal with subtypes. * - * @param SimpleXMLElement $element The SimpleXMLElement object representing the `` tag for the form field object. - * @param mixed $value The form field value to validate. - * @param string $group The field name group control value. This acts as an array container for the field. - * For example if the field has name="foo" and the group value is set to "bar" then the - * full field name would end up being "bar[foo]". + * @param \SimpleXMLElement $element The SimpleXMLElement object representing the `` tag for the form + * field object. + * @param mixed $value The form field value to validate. + * @param string $group The field name group control value. This acts as an array container for + * the field. For example if the field has `name="foo"` and the group value is + * set to "bar" then the full field name would end up being "bar[foo]". * * @return boolean True on success. * @@ -122,8 +123,8 @@ public function setup(\SimpleXMLElement $element, $value, $group = null): bool { $parentResult = parent::setup($element, $value, $group); - $subtype = ((string) $element['subtype'] ?? '') ?: null; - $wildcard = ((string) $element['wildcard'] ?? '') === 'true'; + $subtype = ((string) $element['subtype'] ?? '') ?: null; + $wildcard = ((string) $element['wildcard'] ?? '') === 'true'; $onlyNumericLabels = ((string) $element['onlyNumericLabels']) === 'true'; if (!($subtype && \in_array($subtype, self::SUBTYPES))) @@ -131,8 +132,8 @@ public function setup(\SimpleXMLElement $element, $value, $group = null): bool return false; } - $this->subtype = $subtype; - $this->wildcard = $wildcard; + $this->subtype = $subtype; + $this->wildcard = $wildcard; $this->onlyNumericLabels = $onlyNumericLabels; return $parentResult; @@ -157,7 +158,13 @@ protected function getOptions(): array if ($this->wildcard) { - $options[] = HTMLHelper::_('select.option', '*', '*'); + try + { + $options[] = HTMLHelper::_('select.option', '*', '*'); + } + catch (\InvalidArgumentException $e) + { + } } [$optionLower, $optionUpper] = self::OPTIONS_RANGE[$subtype]; @@ -179,7 +186,13 @@ static function (string $string): string { for ([$i, $l] = [$optionLower, 0]; $i <= $optionUpper; $i++, $l++) { - $options[] = HTMLHelper::_('select.option', (string) ($i), $labels[$l]); + try + { + $options[] = HTMLHelper::_('select.option', (string) ($i), $labels[$l]); + } + catch (\InvalidArgumentException $e) + { + } } return $options; diff --git a/administrator/components/com_scheduler/src/Field/ExecutionRuleField.php b/administrator/components/com_scheduler/src/Field/ExecutionRuleField.php index b2c71dda601c9..2b11cdc6ad8d3 100644 --- a/administrator/components/com_scheduler/src/Field/ExecutionRuleField.php +++ b/administrator/components/com_scheduler/src/Field/ExecutionRuleField.php @@ -1,10 +1,10 @@ - * @license GNU General Public License version 2 or later; see LICENSE.txt + * @copyright (C) 2021 Open Source Matters, Inc. + * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Component\Scheduler\Administrator\Field; @@ -25,16 +25,14 @@ class ExecutionRuleField extends PredefinedlistField * The form field type. * * @var string - * * @since __DEPLOY_VERSION__ */ protected $type = 'ExecutionRule'; /** - * Available execution rules + * Available execution rules. * * @var string[] - * * @since __DEPLOY_VERSION__ */ protected $predefinedOptions = [ @@ -43,6 +41,6 @@ class ExecutionRuleField extends PredefinedlistField 'interval-days' => 'COM_SCHEDULER_EXECUTION_INTERVAL_DAYS', 'interval-months' => 'COM_SCHEDULER_EXECUTION_INTERVAL_MONTHS', 'cron-expression' => 'COM_SCHEDULER_EXECUTION_CRON_EXPRESSION', - 'manual' => 'COM_SCHEDULER_OPTION_EXECUTION_MANUAL_LABEL' + 'manual' => 'COM_SCHEDULER_OPTION_EXECUTION_MANUAL_LABEL', ]; } diff --git a/administrator/components/com_scheduler/src/Field/IntervalField.php b/administrator/components/com_scheduler/src/Field/IntervalField.php index 45e173136b6f1..ff81c5d3709e6 100644 --- a/administrator/components/com_scheduler/src/Field/IntervalField.php +++ b/administrator/components/com_scheduler/src/Field/IntervalField.php @@ -1,10 +1,10 @@ - * @license GNU General Public License version 2 or later; see LICENSE.txt + * @copyright (C) 2021 Open Source Matters, Inc. + * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Component\Scheduler\Administrator\Field; @@ -40,7 +40,7 @@ class IntervalField extends NumberField 'minutes' => [1, 59], 'hours' => [1, 23], 'days' => [1, 30], - 'months' => [1, 12] + 'months' => [1, 12], ]; /** @@ -74,7 +74,7 @@ class IntervalField extends NumberField * field object. * @param mixed $value The form field value to validate. * @param string $group The field name group control value. This acts as an array container for - * the field. For example if the field has name="foo" and the group value is + * the field. For example if the field has `name="foo"` and the group value is * set to "bar" then the full field name would end up being "bar[foo]". * * @return boolean True on success. diff --git a/administrator/components/com_scheduler/src/Field/TaskStateField.php b/administrator/components/com_scheduler/src/Field/TaskStateField.php index 9b394a731849d..b800e629c5068 100644 --- a/administrator/components/com_scheduler/src/Field/TaskStateField.php +++ b/administrator/components/com_scheduler/src/Field/TaskStateField.php @@ -1,14 +1,12 @@ - * @license GNU General Public License version 2 or later; see LICENSE.txt + * @copyright (C) 2021 Open Source Matters, Inc. + * @license GNU General Public License version 2 or later; see LICENSE.txt */ -/** Declares a list field with all possible states for a task entry. */ - namespace Joomla\Component\Scheduler\Administrator\Field; // Restrict direct access @@ -38,9 +36,9 @@ class TaskStateField extends PredefinedlistField * @since __DEPLOY_VERSION__ */ protected $predefinedOptions = [ - -2 => 'JTRASHED', - 0 => 'JDISABLED', - 1 => 'JENABLED', + -2 => 'JTRASHED', + 0 => 'JDISABLED', + 1 => 'JENABLED', '*' => 'JALL', ]; } diff --git a/administrator/components/com_scheduler/src/Field/TaskTypeField.php b/administrator/components/com_scheduler/src/Field/TaskTypeField.php index 3204ae6934c30..413ea6cf8ee65 100644 --- a/administrator/components/com_scheduler/src/Field/TaskTypeField.php +++ b/administrator/components/com_scheduler/src/Field/TaskTypeField.php @@ -1,14 +1,12 @@ - * @license GNU General Public License version 2 or later; see LICENSE.txt + * @copyright (C) 2021 Open Source Matters, Inc. + * @license GNU General Public License version 2 or later; see LICENSE.txt */ -/** Declares the TaskTypeField for listing all available task routines. */ - namespace Joomla\Component\Scheduler\Administrator\Field; // Restrict direct access @@ -21,7 +19,7 @@ use Joomla\Utilities\ArrayHelper; /** - * A list field with all available job types + * A list field with all available task routines. * * @since __DEPLOY_VERSION__ */ @@ -40,8 +38,8 @@ class TaskTypeField extends ListField * * @return array * - * @throws Exception * @since __DEPLOY_VERSION__ + * @throws \Exception */ protected function getOptions(): array { @@ -55,7 +53,13 @@ protected function getOptions(): array // Closure to add a TaskOption as a
diff --git a/administrator/components/com_scheduler/tmpl/tasks/default.php b/administrator/components/com_scheduler/tmpl/tasks/default.php index e45bc83845c78..89d0fd3c33b55 100644 --- a/administrator/components/com_scheduler/tmpl/tasks/default.php +++ b/administrator/components/com_scheduler/tmpl/tasks/default.php @@ -164,7 +164,7 @@ class="js-draggable" data-url="" data-direction=" ?> - + diff --git a/administrator/language/en-GB/com_scheduler.ini b/administrator/language/en-GB/com_scheduler.ini index cc227a322a82c..dd8a113148a98 100644 --- a/administrator/language/en-GB/com_scheduler.ini +++ b/administrator/language/en-GB/com_scheduler.ini @@ -26,7 +26,7 @@ COM_SCHEDULER_CONFIG_WEBCRON_LINK_COPY_DESC="Copy the link to your clipboard." COM_SCHEDULER_CONFIG_WEBCRON_LINK_COPY_FAIL="Could not copy link!" COM_SCHEDULER_CONFIG_WEBCRON_LINK_COPY_SUCCESS="Link copied!" COM_SCHEDULER_DASHBOARD_TITLE="Scheduled Tasks Manager" -COM_SCHEDULER_DESCRIPTION_TASK_PRIORITY="⚠ This is an advanced option. Higher priority tasks can potentially block out lower priority tasks." +COM_SCHEDULER_DESCRIPTION_TASK_PRIORITY="This is an advanced option. Higher priority tasks can potentially block lower priority tasks." COM_SCHEDULER_EDIT_TASK="Edit Task" COM_SCHEDULER_EMPTYSTATE_BUTTON_ADD="Add a Task!" COM_SCHEDULER_EMPTYSTATE_CONTENT="No Tasks!" @@ -73,7 +73,7 @@ COM_SCHEDULER_LABEL_HOURS="Hours" COM_SCHEDULER_LABEL_LAST_EXEC="Last Executed" COM_SCHEDULER_LABEL_MINUTES="Minutes" COM_SCHEDULER_LABEL_NEXT_EXEC="Next Execution" -COM_SCHEDULER_LABEL_NOTES="Notes" +COM_SCHEDULER_LABEL_NOTES="Note" COM_SCHEDULER_LABEL_TASK_PRIORITY="Priority" COM_SCHEDULER_LABEL_TASK_PRIORITY_HIGH="High" COM_SCHEDULER_LABEL_TASK_PRIORITY_LOW="Low" @@ -141,4 +141,4 @@ COM_SCHEDULER_TRIGGER_XVISITS="X-Visits" COM_SCHEDULER_TYPE_CHOOSE="Select a Task type" COM_SCHEDULER_TYPE_OR_SELECT_OPTIONS="Type or select options" COM_SCHEDULER_WARNING_EXISTING_TASK_TYPE_NOT_FOUND="The task routine for this task could not be found!
It's likely that the provider plugin was removed or disabled." -COM_SCHEDULER_XML_DESCRIPTION="Component for managing scheduled tasks and cronjobs (if supported by the server)" +COM_SCHEDULER_XML_DESCRIPTION="Component for managing scheduled tasks and cronjobs (if supported by the server)." diff --git a/administrator/language/en-GB/com_scheduler.sys.ini b/administrator/language/en-GB/com_scheduler.sys.ini index eef3318292118..7f17b0054d015 100644 --- a/administrator/language/en-GB/com_scheduler.sys.ini +++ b/administrator/language/en-GB/com_scheduler.sys.ini @@ -11,4 +11,4 @@ COM_SCHEDULER_MANAGER_TASK_EDIT="Edit Task" COM_SCHEDULER_MANAGER_TASK_NEW="New Task" COM_SCHEDULER_MANAGER_TASKS="Tasks Manager" COM_SCHEDULER_MSG_MANAGE_NO_TASK_PLUGINS="There are no task types matching your query!" -COM_SCHEDULER_XML_DESCRIPTION="Component for managing scheduled tasks and cronjobs (if supported by the server)" +COM_SCHEDULER_XML_DESCRIPTION="Component for managing scheduled tasks and cronjobs (if supported by the server)." diff --git a/libraries/src/Console/TasksListCommand.php b/libraries/src/Console/TasksListCommand.php index 17451dedec481..dc39c31940926 100644 --- a/libraries/src/Console/TasksListCommand.php +++ b/libraries/src/Console/TasksListCommand.php @@ -69,7 +69,7 @@ protected function doExecute(InputInterface $input, OutputInterface $output): in $tasks = array_map( function (\stdClass $task): array { - $enabled = $task->state === 1; + $enabled = $task->state === 1; $nextExec = Factory::getDate($task->next_execution, 'UTC'); $due = $enabled && $task->taskOption && Factory::getDate('now', 'UTC') > $nextExec; @@ -90,7 +90,7 @@ function (\stdClass $task): array { } /** - * Returns an stdClass object array of scheduled tasks. + * Returns a stdClass object array of scheduled tasks. * * @return array * diff --git a/plugins/task/demotasks/language/en-GB/plg_task_demotasks.ini b/plugins/task/demotasks/language/en-GB/plg_task_demotasks.ini index f81c607c8bd91..649edc08aed31 100644 --- a/plugins/task/demotasks/language/en-GB/plg_task_demotasks.ini +++ b/plugins/task/demotasks/language/en-GB/plg_task_demotasks.ini @@ -12,4 +12,4 @@ PLG_TASK_DEMO_TASKS_STRESS_MEMORY_TITLE="Stress Memory" PLG_TASK_DEMO_TASKS_TASK_SLEEP_DESC="Sleep, do nothing for x seconds." PLG_TASK_DEMO_TASKS_TASK_SLEEP_ROUTINE_END_LOG_MESSAGE="TestTask1 return code is: %1$d. Processing Time: %2$.2f seconds" PLG_TASK_DEMO_TASKS_TASK_SLEEP_TITLE="Demo Task - Sleep" -PLG_TASK_DEMO_TASKS_XML_DESCRIPTION="This is a demo plugin for the development of Joomla! Scheduled Tasks" +PLG_TASK_DEMO_TASKS_XML_DESCRIPTION="This is a demo plugin for the development of Joomla! Scheduled Tasks." diff --git a/plugins/task/demotasks/language/en-GB/plg_task_demotasks.sys.ini b/plugins/task/demotasks/language/en-GB/plg_task_demotasks.sys.ini index 8a7156028a4aa..eae925bdd1289 100644 --- a/plugins/task/demotasks/language/en-GB/plg_task_demotasks.sys.ini +++ b/plugins/task/demotasks/language/en-GB/plg_task_demotasks.sys.ini @@ -4,4 +4,4 @@ ; Note : All ini files need to be saved as UTF-8 PLG_TASK_DEMO_TASKS="Task - Demo Tasks!" -PLG_TASK_DEMO_TASKS_XML_DESCRIPTION="This is a demo plugin for the development of Joomla! Scheduled Tasks" +PLG_TASK_DEMO_TASKS_XML_DESCRIPTION="This is a demo plugin for the development of Joomla! Scheduled Tasks." diff --git a/plugins/task/sitestatus/language/en-GB/plg_task_sitestatus.ini b/plugins/task/sitestatus/language/en-GB/plg_task_sitestatus.ini index fc6cc951ff58c..508ea4e010ba4 100644 --- a/plugins/task/sitestatus/language/en-GB/plg_task_sitestatus.ini +++ b/plugins/task/sitestatus/language/en-GB/plg_task_sitestatus.ini @@ -12,9 +12,9 @@ PLG_TASK_SITE_STATUS_ROUTINE_END_LOG_MESSAGE="ToggleOffline return code is: %1$d PLG_TASK_SITE_STATUS_TASK_LOG_SITE_STATUS="Site was %1$s, is now %2$s." PLG_TASK_SITE_STATUS_SET_OFFLINE_DESC="Sets site offline to online on each run." PLG_TASK_SITE_STATUS_SET_OFFLINE_ROUTINE_END_LOG_MESSAGE="SetOffline return code is: %1$d. Processing Time: %2$.2f seconds." -PLG_TASK_SITE_STATUS_SET_OFFLINE_TITLE="Get Site Offline." +PLG_TASK_SITE_STATUS_SET_OFFLINE_TITLE="Set Site Offline." PLG_TASK_SITE_STATUS_SET_ONLINE_DESC="Sets site status to online on each run." PLG_TASK_SITE_STATUS_SET_ONLINE_ROUTINE_END_LOG_MESSAGE="SetOnline return code is: %1$d. Processing Time: %2$.2f seconds." -PLG_TASK_SITE_STATUS_SET_ONLINE_TITLE="Get Site Online." +PLG_TASK_SITE_STATUS_SET_ONLINE_TITLE="Set Site Online." PLG_TASK_SITE_STATUS_TITLE="Toggle Offline." PLG_TASK_SITE_STATUS_XML_DESCRIPTION="Offers task routines to change the site's offline status." From cd4428b2726f3e064a8ae68c523c0e5c819b045d Mon Sep 17 00:00:00 2001 From: Tushar Date: Mon, 1 Nov 2021 10:48:05 +0530 Subject: [PATCH 535/615] Apply suggestions from code review Code-style and language improvements. Co-authored-by: Brian Teeman --- .../components/com_scheduler/access.xml | 24 +++++++++---------- .../components/com_scheduler/config.xml | 3 +-- .../layouts/form/field/webcron_link.php | 22 ++++++++--------- .../com_scheduler/tmpl/tasks/default.php | 2 +- .../language/en-GB/com_scheduler.ini | 6 ++--- .../language/en-GB/com_scheduler.sys.ini | 2 +- libraries/src/Console/TasksListCommand.php | 4 ++-- .../language/en-GB/plg_task_demotasks.ini | 2 +- .../language/en-GB/plg_task_demotasks.sys.ini | 2 +- .../language/en-GB/plg_task_sitestatus.ini | 4 ++-- 10 files changed, 35 insertions(+), 36 deletions(-) diff --git a/administrator/components/com_scheduler/access.xml b/administrator/components/com_scheduler/access.xml index 0fc12201099cb..1c7933d75abdb 100644 --- a/administrator/components/com_scheduler/access.xml +++ b/administrator/components/com_scheduler/access.xml @@ -1,19 +1,19 @@
- - - - - - - - + + + + + + + +
- - - - + + + +
diff --git a/administrator/components/com_scheduler/config.xml b/administrator/components/com_scheduler/config.xml index df3f93db100aa..05bac35af1db5 100644 --- a/administrator/components/com_scheduler/config.xml +++ b/administrator/components/com_scheduler/config.xml @@ -53,8 +53,7 @@ label="COM_SCHEDULER_CONFIG_WEBCRON_LABEL" description="COM_SCHEDULER_CONFIG_WEBCRON_DESC" > - + + * @copyright (C) 2021 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -39,18 +39,18 @@
diff --git a/administrator/components/com_scheduler/tmpl/tasks/default.php b/administrator/components/com_scheduler/tmpl/tasks/default.php index e45bc83845c78..89d0fd3c33b55 100644 --- a/administrator/components/com_scheduler/tmpl/tasks/default.php +++ b/administrator/components/com_scheduler/tmpl/tasks/default.php @@ -164,7 +164,7 @@ class="js-draggable" data-url="" data-direction=" ?> - + diff --git a/administrator/language/en-GB/com_scheduler.ini b/administrator/language/en-GB/com_scheduler.ini index cc227a322a82c..dd8a113148a98 100644 --- a/administrator/language/en-GB/com_scheduler.ini +++ b/administrator/language/en-GB/com_scheduler.ini @@ -26,7 +26,7 @@ COM_SCHEDULER_CONFIG_WEBCRON_LINK_COPY_DESC="Copy the link to your clipboard." COM_SCHEDULER_CONFIG_WEBCRON_LINK_COPY_FAIL="Could not copy link!" COM_SCHEDULER_CONFIG_WEBCRON_LINK_COPY_SUCCESS="Link copied!" COM_SCHEDULER_DASHBOARD_TITLE="Scheduled Tasks Manager" -COM_SCHEDULER_DESCRIPTION_TASK_PRIORITY="⚠ This is an advanced option. Higher priority tasks can potentially block out lower priority tasks." +COM_SCHEDULER_DESCRIPTION_TASK_PRIORITY="This is an advanced option. Higher priority tasks can potentially block lower priority tasks." COM_SCHEDULER_EDIT_TASK="Edit Task" COM_SCHEDULER_EMPTYSTATE_BUTTON_ADD="Add a Task!" COM_SCHEDULER_EMPTYSTATE_CONTENT="No Tasks!" @@ -73,7 +73,7 @@ COM_SCHEDULER_LABEL_HOURS="Hours" COM_SCHEDULER_LABEL_LAST_EXEC="Last Executed" COM_SCHEDULER_LABEL_MINUTES="Minutes" COM_SCHEDULER_LABEL_NEXT_EXEC="Next Execution" -COM_SCHEDULER_LABEL_NOTES="Notes" +COM_SCHEDULER_LABEL_NOTES="Note" COM_SCHEDULER_LABEL_TASK_PRIORITY="Priority" COM_SCHEDULER_LABEL_TASK_PRIORITY_HIGH="High" COM_SCHEDULER_LABEL_TASK_PRIORITY_LOW="Low" @@ -141,4 +141,4 @@ COM_SCHEDULER_TRIGGER_XVISITS="X-Visits" COM_SCHEDULER_TYPE_CHOOSE="Select a Task type" COM_SCHEDULER_TYPE_OR_SELECT_OPTIONS="Type or select options" COM_SCHEDULER_WARNING_EXISTING_TASK_TYPE_NOT_FOUND="The task routine for this task could not be found!
It's likely that the provider plugin was removed or disabled." -COM_SCHEDULER_XML_DESCRIPTION="Component for managing scheduled tasks and cronjobs (if supported by the server)" +COM_SCHEDULER_XML_DESCRIPTION="Component for managing scheduled tasks and cronjobs (if supported by the server)." diff --git a/administrator/language/en-GB/com_scheduler.sys.ini b/administrator/language/en-GB/com_scheduler.sys.ini index eef3318292118..7f17b0054d015 100644 --- a/administrator/language/en-GB/com_scheduler.sys.ini +++ b/administrator/language/en-GB/com_scheduler.sys.ini @@ -11,4 +11,4 @@ COM_SCHEDULER_MANAGER_TASK_EDIT="Edit Task" COM_SCHEDULER_MANAGER_TASK_NEW="New Task" COM_SCHEDULER_MANAGER_TASKS="Tasks Manager" COM_SCHEDULER_MSG_MANAGE_NO_TASK_PLUGINS="There are no task types matching your query!" -COM_SCHEDULER_XML_DESCRIPTION="Component for managing scheduled tasks and cronjobs (if supported by the server)" +COM_SCHEDULER_XML_DESCRIPTION="Component for managing scheduled tasks and cronjobs (if supported by the server)." diff --git a/libraries/src/Console/TasksListCommand.php b/libraries/src/Console/TasksListCommand.php index 17451dedec481..dc39c31940926 100644 --- a/libraries/src/Console/TasksListCommand.php +++ b/libraries/src/Console/TasksListCommand.php @@ -69,7 +69,7 @@ protected function doExecute(InputInterface $input, OutputInterface $output): in $tasks = array_map( function (\stdClass $task): array { - $enabled = $task->state === 1; + $enabled = $task->state === 1; $nextExec = Factory::getDate($task->next_execution, 'UTC'); $due = $enabled && $task->taskOption && Factory::getDate('now', 'UTC') > $nextExec; @@ -90,7 +90,7 @@ function (\stdClass $task): array { } /** - * Returns an stdClass object array of scheduled tasks. + * Returns a stdClass object array of scheduled tasks. * * @return array * diff --git a/plugins/task/demotasks/language/en-GB/plg_task_demotasks.ini b/plugins/task/demotasks/language/en-GB/plg_task_demotasks.ini index f81c607c8bd91..649edc08aed31 100644 --- a/plugins/task/demotasks/language/en-GB/plg_task_demotasks.ini +++ b/plugins/task/demotasks/language/en-GB/plg_task_demotasks.ini @@ -12,4 +12,4 @@ PLG_TASK_DEMO_TASKS_STRESS_MEMORY_TITLE="Stress Memory" PLG_TASK_DEMO_TASKS_TASK_SLEEP_DESC="Sleep, do nothing for x seconds." PLG_TASK_DEMO_TASKS_TASK_SLEEP_ROUTINE_END_LOG_MESSAGE="TestTask1 return code is: %1$d. Processing Time: %2$.2f seconds" PLG_TASK_DEMO_TASKS_TASK_SLEEP_TITLE="Demo Task - Sleep" -PLG_TASK_DEMO_TASKS_XML_DESCRIPTION="This is a demo plugin for the development of Joomla! Scheduled Tasks" +PLG_TASK_DEMO_TASKS_XML_DESCRIPTION="This is a demo plugin for the development of Joomla! Scheduled Tasks." diff --git a/plugins/task/demotasks/language/en-GB/plg_task_demotasks.sys.ini b/plugins/task/demotasks/language/en-GB/plg_task_demotasks.sys.ini index 8a7156028a4aa..eae925bdd1289 100644 --- a/plugins/task/demotasks/language/en-GB/plg_task_demotasks.sys.ini +++ b/plugins/task/demotasks/language/en-GB/plg_task_demotasks.sys.ini @@ -4,4 +4,4 @@ ; Note : All ini files need to be saved as UTF-8 PLG_TASK_DEMO_TASKS="Task - Demo Tasks!" -PLG_TASK_DEMO_TASKS_XML_DESCRIPTION="This is a demo plugin for the development of Joomla! Scheduled Tasks" +PLG_TASK_DEMO_TASKS_XML_DESCRIPTION="This is a demo plugin for the development of Joomla! Scheduled Tasks." diff --git a/plugins/task/sitestatus/language/en-GB/plg_task_sitestatus.ini b/plugins/task/sitestatus/language/en-GB/plg_task_sitestatus.ini index fc6cc951ff58c..508ea4e010ba4 100644 --- a/plugins/task/sitestatus/language/en-GB/plg_task_sitestatus.ini +++ b/plugins/task/sitestatus/language/en-GB/plg_task_sitestatus.ini @@ -12,9 +12,9 @@ PLG_TASK_SITE_STATUS_ROUTINE_END_LOG_MESSAGE="ToggleOffline return code is: %1$d PLG_TASK_SITE_STATUS_TASK_LOG_SITE_STATUS="Site was %1$s, is now %2$s." PLG_TASK_SITE_STATUS_SET_OFFLINE_DESC="Sets site offline to online on each run." PLG_TASK_SITE_STATUS_SET_OFFLINE_ROUTINE_END_LOG_MESSAGE="SetOffline return code is: %1$d. Processing Time: %2$.2f seconds." -PLG_TASK_SITE_STATUS_SET_OFFLINE_TITLE="Get Site Offline." +PLG_TASK_SITE_STATUS_SET_OFFLINE_TITLE="Set Site Offline." PLG_TASK_SITE_STATUS_SET_ONLINE_DESC="Sets site status to online on each run." PLG_TASK_SITE_STATUS_SET_ONLINE_ROUTINE_END_LOG_MESSAGE="SetOnline return code is: %1$d. Processing Time: %2$.2f seconds." -PLG_TASK_SITE_STATUS_SET_ONLINE_TITLE="Get Site Online." +PLG_TASK_SITE_STATUS_SET_ONLINE_TITLE="Set Site Online." PLG_TASK_SITE_STATUS_TITLE="Toggle Offline." PLG_TASK_SITE_STATUS_XML_DESCRIPTION="Offers task routines to change the site's offline status." From e2f2c65dc4feeb3b3d7691cf6e91090b33f89e3e Mon Sep 17 00:00:00 2001 From: ditsuke Date: Mon, 1 Nov 2021 10:59:04 +0530 Subject: [PATCH 536/615] Update language constants for plgSysScheduleRunner Updates plugin description string. --- .../language/en-GB/plg_system.schedulerunner.sys.ini | 2 +- .../language/en-GB/plg_system_schedulerunner.ini | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/plugins/system/schedulerunner/language/en-GB/plg_system.schedulerunner.sys.ini b/plugins/system/schedulerunner/language/en-GB/plg_system.schedulerunner.sys.ini index 1e7918f8ae9f7..1098c573d54a7 100644 --- a/plugins/system/schedulerunner/language/en-GB/plg_system.schedulerunner.sys.ini +++ b/plugins/system/schedulerunner/language/en-GB/plg_system.schedulerunner.sys.ini @@ -4,4 +4,4 @@ ; Note : All ini files need to be saved as UTF-8 PLG_SYSTEM_SCHEDULE_RUNNER="System - Schedule Runner" -PLG_SYSTEM_SCHEDULE_RUNNER_XML_DESCRIPTION="This plugin lazily runs due tasks, managed through com_scheduler" +PLG_SYSTEM_SCHEDULE_RUNNER_XML_DESCRIPTION="This plugin is responsible for the lazy scheduling, webcron and click to run functionalities of com_scheduler. Besides that, this also implements form enhancers/manipulators for the com_scheduler component configuration." diff --git a/plugins/system/schedulerunner/language/en-GB/plg_system_schedulerunner.ini b/plugins/system/schedulerunner/language/en-GB/plg_system_schedulerunner.ini index 74b6c8d6ca4b8..1098c573d54a7 100644 --- a/plugins/system/schedulerunner/language/en-GB/plg_system_schedulerunner.ini +++ b/plugins/system/schedulerunner/language/en-GB/plg_system_schedulerunner.ini @@ -4,5 +4,4 @@ ; Note : All ini files need to be saved as UTF-8 PLG_SYSTEM_SCHEDULE_RUNNER="System - Schedule Runner" -PLG_SYSTEM_SCHEDULE_RUNNER_WEBCRON_DISABLED="Webcron called but has not been enabled in the Scheduler component config." -PLG_SYSTEM_SCHEDULE_RUNNER_XML_DESCRIPTION="This plugin lazily runs due tasks, managed through com_scheduler" +PLG_SYSTEM_SCHEDULE_RUNNER_XML_DESCRIPTION="This plugin is responsible for the lazy scheduling, webcron and click to run functionalities of com_scheduler. Besides that, this also implements form enhancers/manipulators for the com_scheduler component configuration." From 1c938ddb687e7dadc3252f50fc95f57b441c0d12 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Mon, 1 Nov 2021 13:00:41 +0530 Subject: [PATCH 537/615] Bugfix Task::run() For some reason, the UNIX timestamp with microseconds `microtime()` broke the DateTime breaking down the task usual scheduling. This commit introduces an int cast for the timestamp which makes things work as expected. --- administrator/components/com_scheduler/src/Task/Task.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/administrator/components/com_scheduler/src/Task/Task.php b/administrator/components/com_scheduler/src/Task/Task.php index 141db655e9877..9f446850356d3 100644 --- a/administrator/components/com_scheduler/src/Task/Task.php +++ b/administrator/components/com_scheduler/src/Task/Task.php @@ -194,7 +194,7 @@ public function run(): bool // @todo make the ExecRuleHelper usage less ugly, perhaps it should be composed into Task // Update object state. - $this->set('last_execution', Factory::getDate('@' . $this->snapshot['taskStart'])->toSql()); + $this->set('last_execution', Factory::getDate('@' . (int) $this->snapshot['taskStart'])->toSql()); $this->set('next_execution', (new ExecRuleHelper($this->toObject()))->nextExec()); $this->set('last_exit_code', $this->snapshot['status']); $this->set('times_executed', $this->get('times_executed') + 1); From 7f253754ac2991c7dcbba6ce03425256120929ad Mon Sep 17 00:00:00 2001 From: ditsuke Date: Tue, 2 Nov 2021 22:40:05 +0530 Subject: [PATCH 538/615] Fix webcron url & description Fixes webcron url and description as exposed in the Scheduler component config. Ref: joomla-projects/soc21_website-cronjob#37 --- administrator/language/en-GB/com_scheduler.ini | 2 +- plugins/system/schedulerunner/schedulerunner.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/administrator/language/en-GB/com_scheduler.ini b/administrator/language/en-GB/com_scheduler.ini index dd8a113148a98..732aaba736a75 100644 --- a/administrator/language/en-GB/com_scheduler.ini +++ b/administrator/language/en-GB/com_scheduler.ini @@ -9,7 +9,7 @@ COM_SCHEDULER_CONFIG_FIELDSET_LAZY_SCHEDULER_DESC="Configure how site visits tri COM_SCHEDULER_CONFIG_FIELDSET_LAZY_SCHEDULER_LABEL="Lazy Scheduler" COM_SCHEDULER_CONFIG_GENERATE_WEBCRON_KEY_DESC="The webcron needs a protection key before it is functional. Saving this configuration will autogenerate the key." COM_SCHEDULER_CONFIG_GLOBAL_WEBCRON_KEY_LABEL="Global Key" -COM_SCHEDULER_CONFIG_GLOBAL_WEBCRON_LINK_DESC="By default, requesting this base link will only run tasks due for execution. To execute a specific task, use the task's ID as a query parameter appended to the URL: BASE_URL&task_id=<task's id>" +COM_SCHEDULER_CONFIG_GLOBAL_WEBCRON_LINK_DESC="By default, requesting this base link will only run tasks due for execution. To execute a specific task, use the task's ID as a query parameter appended to the URL: BASE_URL&id=<task's id>" COM_SCHEDULER_CONFIG_GLOBAL_WEBCRON_LINK_LABEL="Webcron Link (Base)" COM_SCHEDULER_CONFIG_HASH_PROTECTION_DESC="If enabled, tasks will only be triggered when URLs have the scheduler hash as a parameter." COM_SCHEDULER_CONFIG_LAZY_SCHEDULER_ENABLED_DESC="If disabled, scheduled tasks will not be triggered by visitors on the site.
Recommended if triggering with native cron." diff --git a/plugins/system/schedulerunner/schedulerunner.php b/plugins/system/schedulerunner/schedulerunner.php index 0a50f8580fc17..0d9cde86a6000 100644 --- a/plugins/system/schedulerunner/schedulerunner.php +++ b/plugins/system/schedulerunner/schedulerunner.php @@ -267,7 +267,7 @@ public function enhanceSchedulerConfig(EventInterface $event): void { $form->removeField('generate_key_on_save', 'webcron'); - $relative = 'index.php?option=com_ajax&plugin=RunSchedulerLazy&group=system&format=json&hash=' . $data['webcron']['key']; + $relative = 'index.php?option=com_ajax&plugin=RunSchedulerWebcron&group=system&format=json&hash=' . $data['webcron']['key']; $link = Route::link('site', $relative, false, Route::TLS_IGNORE, true); $form->setValue('base_link', 'webcron', $link); } From 1a8038b7050de26da87b0b2475be336c30138b1b Mon Sep 17 00:00:00 2001 From: Benjamin Trenkle Date: Wed, 3 Nov 2021 09:42:13 +0100 Subject: [PATCH 539/615] Update joomla.asset.json --- build/media_source/plg_system_schedulerunner/joomla.asset.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/media_source/plg_system_schedulerunner/joomla.asset.json b/build/media_source/plg_system_schedulerunner/joomla.asset.json index 9acf239b3240f..0feb3c9850ef5 100644 --- a/build/media_source/plg_system_schedulerunner/joomla.asset.json +++ b/build/media_source/plg_system_schedulerunner/joomla.asset.json @@ -8,7 +8,7 @@ { "name": "plg_system_schedulerunner.run-schedule.es5", "type": "script", - "uri": "plg_system_schedulerunner/run-schedule.es5.min.js", + "uri": "plg_system_schedulerunner/run-schedule-es5.min.js", "dependencies": [ "core" ], From 233fd3a9412805d16068db934391724a085e6c24 Mon Sep 17 00:00:00 2001 From: Benjamin Trenkle Date: Sat, 6 Nov 2021 14:06:20 +0100 Subject: [PATCH 540/615] Improve the locking mechanism --- .../com_scheduler/src/Model/TaskModel.php | 68 +++++++++++++++++ .../com_scheduler/src/Model/TasksModel.php | 1 + .../com_scheduler/src/Scheduler/Scheduler.php | 75 +++++++------------ .../com_scheduler/src/Task/Task.php | 23 ------ libraries/src/Console/TasksRunCommand.php | 8 +- .../system/schedulerunner/schedulerunner.php | 32 +++++++- 6 files changed, 129 insertions(+), 78 deletions(-) diff --git a/administrator/components/com_scheduler/src/Model/TaskModel.php b/administrator/components/com_scheduler/src/Model/TaskModel.php index 1410349f54fe7..cd103c22a6122 100644 --- a/administrator/components/com_scheduler/src/Model/TaskModel.php +++ b/administrator/components/com_scheduler/src/Model/TaskModel.php @@ -24,6 +24,7 @@ use Joomla\CMS\Table\Table; use Joomla\Component\Scheduler\Administrator\Helper\ExecRuleHelper; use Joomla\Component\Scheduler\Administrator\Helper\SchedulerHelper; +use Joomla\Database\ParameterType; /** * MVC Model to interact with the Scheduler DB. @@ -280,6 +281,73 @@ public function getItem($pk = null) return $item; } + /** + * Lock the next task when no task is locked and returns it, otherwise null + * + * @param [type] $id + * + * @return void + */ + public function getNextTask($id = null, $unpublished = false) + { + $now = Factory::getDate()->toSql(); + + // Try to lock the next task + $query = $this->getDbo()->getQuery(true); + $subquery = $this->getDbo()->getQuery(true); + + $subquery->select('COUNT(*)') + ->from($query->qn('#__scheduler_tasks')) + ->where('!' . $query->isNullDatetime($query->qn('locked'))); + + $query ->update($query->qn('#__scheduler_tasks')) + ->set('locked = :date1') + ->where('(' . $subquery . ') = 0') + ->where($query->qn('next_execution') . '<= :date2') + ->bind(':date1', $now) + ->bind(':date2', $now) + ->order($query->qn('priority') . ' DESC') + ->order($query->qn('next_execution') . ' ASC') + ->setLimit(1); + + if ($unpublished) + { + $query->whereIn($query->qn('state'), [0, 1]); + } + else + { + $query->where($query->qn('state') . ' = 1'); + } + + if ($id > 0) + { + $query ->where($query->qn('id') . ' = :taskId') + ->bind(':taskId', $id, ParameterType::INTEGER); + } + + $this->getDbo()->setQuery($query)->execute(); + + if ($this->getDbo()->getAffectedRows() === 0) + { + return null; + } + + $query = $this->getDbo()->getQuery(true); + + $query->select('*') + ->from($query->qn('#__scheduler_tasks')) + ->where($query->qn('locked') . ' IS NOT NULL'); + + $task = $this->getDbo()->setQuery($query)->loadObject(); + + $task->execution_rules = json_decode($task->execution_rules); + $task->cron_rules = json_decode($task->cron_rules); + + $task->taskOption = SchedulerHelper::getTaskOptions()->findOption($task->type); + + return $task; + } + /** * @param array $data The form data * diff --git a/administrator/components/com_scheduler/src/Model/TasksModel.php b/administrator/components/com_scheduler/src/Model/TasksModel.php index c0234e313055d..eeb29b2bf6c0e 100644 --- a/administrator/components/com_scheduler/src/Model/TasksModel.php +++ b/administrator/components/com_scheduler/src/Model/TasksModel.php @@ -91,6 +91,7 @@ protected function getStoreId($id = ''): string $id .= ':' . $this->getState('filter.type'); $id .= ':' . $this->getState('filter.orphaned'); $id .= ':' . $this->getState('filter.due'); + $id .= ':' . $this->getState('filter.locked'); $id .= ':' . $this->getState('filter.trigger'); $id .= ':' . $this->getState('list.select'); diff --git a/administrator/components/com_scheduler/src/Scheduler/Scheduler.php b/administrator/components/com_scheduler/src/Scheduler/Scheduler.php index 421d8861b4489..a52b43b210dcd 100644 --- a/administrator/components/com_scheduler/src/Scheduler/Scheduler.php +++ b/administrator/components/com_scheduler/src/Scheduler/Scheduler.php @@ -62,38 +62,6 @@ class Scheduler 'multi_ordering' => ['a.priority DESC ', 'a.next_execution ASC'], ]; - /** - * @var CMSApplication - * @since __DEPLOY_VERSION__ - */ - protected $app; - - /** - * @var DatabaseInterface - * @since __DEPLOY_VERSION__ - */ - protected $db; - - /** - * @var SchedulerComponent - * @since __DEPLOY_VERSION__ - */ - protected $component; - - /** - * Scheduler class constructor - * - * @since __DEPLOY_VERSION__ - * @throws \Exception - */ - public function __construct() - { - $this->app = Factory::getApplication(); - $this->db = Factory::getContainer()->get(DatabaseDriver::class); - $this->component = $this->app->bootComponent('com_scheduler'); - $this->app->getLanguage()->load('com_scheduler', JPATH_ADMINISTRATOR); - } - /** * Run a scheduled task. * Runs a single due task from the task queue by default if $id and $title are not passed. @@ -108,13 +76,15 @@ public function __construct() */ public function runTask(int $id = 0, bool $unpublished = false): ?Task { - $task = $this->fetchTask($id, $unpublished); + $task = $this->getNextTask($id, $unpublished); if (empty($task)) { return null; } + Factory::getApplication()->getLanguage()->load('com_scheduler', JPATH_ADMINISTRATOR); + $options['text_entry_format'] = '{DATE} {TIME} {PRIORITY} {MESSAGE}'; $options['text_file'] = 'joomla_scheduler.php'; Log::addLogger($options, Log::ALL, $task->logCategory); @@ -154,27 +124,38 @@ public function runTask(int $id = 0, bool $unpublished = false): ?Task } /** - * Fetches a single scheduled task in a Task instance. - * If no id or title is specified, a due task is returned. + * Get the next task which is due to run, limit to a specific task when ID is given * - * @param int $id The task ID - * @param bool $unpublished The task title - * - * @return ?Task + * @param integer $id * - * @since __DEPLOY_VERSION__ - * @throws \Exception + * @return Task $task The task to execute */ - public function fetchTask(int $id = 0, bool $unpublished = false): ?Task + public function getNextTask(int $id = 0) { - $record = $this->fetchTaskRecord($id, $unpublished); + try + { + $component = Factory::getApplication()->bootComponent('com_scheduler'); - if ($record === null) + /** @var TasksModel $model */ + $model = $component->getMVCFactory()->createModel('Task', 'Administrator', ['ignore_request' => true]); + } + catch (\Exception $e) + { + } + + if (!isset($model)) + { + throw new \RunTimeException('JLIB_APPLICATION_ERROR_MODEL_CREATE'); + } + + $task = $model->getNextTask($id); + + if (empty($task)) { return null; } - return new Task($record); + return new Task($task); } /** @@ -231,8 +212,10 @@ public function fetchTaskRecords(array $filters, array $listConfig): array try { + $component = Factory::getApplication()->bootComponent('com_scheduler'); + /** @var TasksModel $model */ - $model = $this->component->getMVCFactory() + $model = $component->getMVCFactory() ->createModel('Tasks', 'Administrator', ['ignore_request' => true]); } catch (\Exception $e) diff --git a/administrator/components/com_scheduler/src/Task/Task.php b/administrator/components/com_scheduler/src/Task/Task.php index 9f446850356d3..3b81a17e53e66 100644 --- a/administrator/components/com_scheduler/src/Task/Task.php +++ b/administrator/components/com_scheduler/src/Task/Task.php @@ -134,22 +134,6 @@ public function getRecord(): object */ public function run(): bool { - /* - * Dispatch event if task lock is not released (NULL). This only happens if the task execution - * was interrupted by a fatal failure. - */ - if ($this->get('locked') !== null) - { - $event = AbstractEvent::create( - 'onTaskRecoverFailure', - [ - 'subject' => $this, - ] - ); - - $this->app->getDispatcher()->dispatch('onTaskRecoverFailure', $event); - } - // Exit early if task routine is not available if (!SchedulerHelper::getTaskOptions()->findOption($this->get('type'))) { @@ -159,13 +143,6 @@ public function run(): bool return $this->isSuccess(); } - if (!$this->acquireLock()) - { - $this->snapshot['status'] = Status::NO_LOCK; - - return $this->isSuccess(); - } - $this->snapshot['status'] = Status::RUNNING; $this->snapshot['taskStart'] = $this->snapshot['taskStart'] ?? microtime(true); $this->snapshot['netDuration'] = 0; diff --git a/libraries/src/Console/TasksRunCommand.php b/libraries/src/Console/TasksRunCommand.php index 30b8418490ada..af50f3a5b7693 100644 --- a/libraries/src/Console/TasksRunCommand.php +++ b/libraries/src/Console/TasksRunCommand.php @@ -81,17 +81,12 @@ protected function doExecute(InputInterface $input, OutputInterface $output): in $scheduler = new Scheduler; $id = $input->getOption('id'); - $title = $input->getOption('title'); $all = $input->getOption('all'); if ($id) { $records[] = $scheduler->fetchTaskRecord($id); } - elseif ($title) - { - $records[] = $scheduler->fetchTaskRecord(0, $title); - } else { $filters = $scheduler::TASK_QUEUE_FILTERS; @@ -101,7 +96,7 @@ protected function doExecute(InputInterface $input, OutputInterface $output): in $records = $scheduler->fetchTaskRecords($filters, $listConfig); } - if (($id || $title) && !$records[0]) + if ($id && !$records[0]) { $this->ioStyle->writeln('No matching task found!'); @@ -160,7 +155,6 @@ private function configureIO(InputInterface $input, OutputInterface $output) protected function configure(): void { $this->addOption('id', 'i', InputOption::VALUE_REQUIRED, 'The id of the task to run'); - $this->addOption('title', 't', InputOption::VALUE_REQUIRED, 'The title of the task to run, can be incomplete.'); $this->addOption('all', '', InputOption::VALUE_NONE, 'Run all due tasks. Note that this is overridden if --id or --title are used.'); $help = "%command.name% run scheduled tasks. diff --git a/plugins/system/schedulerunner/schedulerunner.php b/plugins/system/schedulerunner/schedulerunner.php index 0d9cde86a6000..d8c326755a812 100644 --- a/plugins/system/schedulerunner/schedulerunner.php +++ b/plugins/system/schedulerunner/schedulerunner.php @@ -120,6 +120,26 @@ public function injectLazyJS(Event $event): void return; } + // Check if any task is due to decrease the load + $model = $this->app->bootComponent('com_scheduler') + ->getMVCFactory()->createModel('Tasks', 'Administrator', ['ignore_request' => true]); + + $model->setState('filter.state', 1); + $model->setState('filter.due', 1); + + $items = $model->getItems(); + + // See if we are running currently + $model->setState('filter.locked', 1); + $model->setState('filter.due', 0); + + $items2 = $model->getItems(); + + if (empty($items) || !empty($items2)) + { + return; + } + // Add configuration options $triggerInterval = $config->get('lazy_scheduler.interval', 300); $this->app->getDocument()->addScriptOptions('plg_system_schedulerunner', ['interval' => $triggerInterval]); @@ -147,7 +167,7 @@ public function runLazyCron() if (!$config->get('lazy_scheduler.enabled', true)) { - throw new \Exception(Text::_('JERROR_ALERTNOAUTHOR'), 403); + return; } // Since `navigator.sendBeacon()` may time out, allow execution after disconnect if possible. @@ -156,7 +176,15 @@ public function runLazyCron() ignore_user_abort(true); } - $this->runScheduler(); + // Supress all errors to avoid any output + try + { + $this->runScheduler(); + } + catch (\Exception $e) + { + + } } /** From bda45f861066876ba9447579dc99098b2256d80c Mon Sep 17 00:00:00 2001 From: Benjamin Trenkle Date: Sat, 6 Nov 2021 15:32:00 +0100 Subject: [PATCH 541/615] Add table locking when locking task --- .../components/com_scheduler/src/Model/TaskModel.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/administrator/components/com_scheduler/src/Model/TaskModel.php b/administrator/components/com_scheduler/src/Model/TaskModel.php index cd103c22a6122..2648baa9b2e8c 100644 --- a/administrator/components/com_scheduler/src/Model/TaskModel.php +++ b/administrator/components/com_scheduler/src/Model/TaskModel.php @@ -325,8 +325,12 @@ public function getNextTask($id = null, $unpublished = false) ->bind(':taskId', $id, ParameterType::INTEGER); } + $this->getDbo()->lockTable($query->qn('#__scheduler_tasks')); + $this->getDbo()->setQuery($query)->execute(); + $this->getDbo()->unlockTables(); + if ($this->getDbo()->getAffectedRows() === 0) { return null; From b206a972148671957ec4f84a09d8c292172d6e0c Mon Sep 17 00:00:00 2001 From: Benjamin Trenkle Date: Sat, 6 Nov 2021 15:50:40 +0100 Subject: [PATCH 542/615] CS --- .../components/com_scheduler/src/Model/TaskModel.php | 6 +++--- plugins/system/schedulerunner/schedulerunner.php | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/administrator/components/com_scheduler/src/Model/TaskModel.php b/administrator/components/com_scheduler/src/Model/TaskModel.php index 2648baa9b2e8c..fd868ec3eff97 100644 --- a/administrator/components/com_scheduler/src/Model/TaskModel.php +++ b/administrator/components/com_scheduler/src/Model/TaskModel.php @@ -286,7 +286,7 @@ public function getItem($pk = null) * * @param [type] $id * - * @return void + * @return Task|null */ public function getNextTask($id = null, $unpublished = false) { @@ -339,8 +339,8 @@ public function getNextTask($id = null, $unpublished = false) $query = $this->getDbo()->getQuery(true); $query->select('*') - ->from($query->qn('#__scheduler_tasks')) - ->where($query->qn('locked') . ' IS NOT NULL'); + ->from($query->qn('#__scheduler_tasks')) + ->where($query->qn('locked') . ' IS NOT NULL'); $task = $this->getDbo()->setQuery($query)->loadObject(); diff --git a/plugins/system/schedulerunner/schedulerunner.php b/plugins/system/schedulerunner/schedulerunner.php index d8c326755a812..d6e900f92a9a0 100644 --- a/plugins/system/schedulerunner/schedulerunner.php +++ b/plugins/system/schedulerunner/schedulerunner.php @@ -183,7 +183,6 @@ public function runLazyCron() } catch (\Exception $e) { - } } From ed0fc7ae70ebb1da93dcb86e895230eaee70bacf Mon Sep 17 00:00:00 2001 From: Benjamin Trenkle Date: Sat, 6 Nov 2021 16:50:39 +0100 Subject: [PATCH 543/615] Simplify null date check --- administrator/components/com_scheduler/src/Model/TaskModel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/administrator/components/com_scheduler/src/Model/TaskModel.php b/administrator/components/com_scheduler/src/Model/TaskModel.php index fd868ec3eff97..ee35b098117cd 100644 --- a/administrator/components/com_scheduler/src/Model/TaskModel.php +++ b/administrator/components/com_scheduler/src/Model/TaskModel.php @@ -298,7 +298,7 @@ public function getNextTask($id = null, $unpublished = false) $subquery->select('COUNT(*)') ->from($query->qn('#__scheduler_tasks')) - ->where('!' . $query->isNullDatetime($query->qn('locked'))); + ->where($query->qn('locked') . ' IS NOT NULL'); $query ->update($query->qn('#__scheduler_tasks')) ->set('locked = :date1') From fab13faeab2e5c47794ea419d0ab71bc8af6f0a2 Mon Sep 17 00:00:00 2001 From: Benjamin Trenkle Date: Sat, 6 Nov 2021 16:54:37 +0100 Subject: [PATCH 544/615] Add column quote --- administrator/components/com_scheduler/src/Model/TaskModel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/administrator/components/com_scheduler/src/Model/TaskModel.php b/administrator/components/com_scheduler/src/Model/TaskModel.php index ee35b098117cd..14553965faa18 100644 --- a/administrator/components/com_scheduler/src/Model/TaskModel.php +++ b/administrator/components/com_scheduler/src/Model/TaskModel.php @@ -301,7 +301,7 @@ public function getNextTask($id = null, $unpublished = false) ->where($query->qn('locked') . ' IS NOT NULL'); $query ->update($query->qn('#__scheduler_tasks')) - ->set('locked = :date1') + ->set($query->qn('locked') . ' = :date1') ->where('(' . $subquery . ') = 0') ->where($query->qn('next_execution') . '<= :date2') ->bind(':date1', $now) From 5b76026734146321d9495c31f5b651b73f7f77c2 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Tue, 9 Nov 2021 22:26:43 +0530 Subject: [PATCH 545/615] Extend TaskModel's getter method ! Fails in MySQL 5.6 with "Table was not locked with LOCK TABLES" - Adds options array to customise behavior. - Adds static option resolver for proxies to the getter. - Wrap queue behavior in a sub-query for compatibility. ... --- .../com_scheduler/src/Model/TaskModel.php | 196 ++++++++++++++---- 1 file changed, 155 insertions(+), 41 deletions(-) diff --git a/administrator/components/com_scheduler/src/Model/TaskModel.php b/administrator/components/com_scheduler/src/Model/TaskModel.php index 14553965faa18..f5131ac8ff7d7 100644 --- a/administrator/components/com_scheduler/src/Model/TaskModel.php +++ b/administrator/components/com_scheduler/src/Model/TaskModel.php @@ -25,6 +25,10 @@ use Joomla\Component\Scheduler\Administrator\Helper\ExecRuleHelper; use Joomla\Component\Scheduler\Administrator\Helper\SchedulerHelper; use Joomla\Database\ParameterType; +use Symfony\Component\OptionsResolver\Exception\AccessException; +use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException; +use Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException; +use Symfony\Component\OptionsResolver\OptionsResolver; /** * MVC Model to interact with the Scheduler DB. @@ -41,12 +45,20 @@ class TaskModel extends AdminModel * @var array * @since __DEPLOY_VERSION__ */ - protected $STATES = [ + protected const TASK_STATES = [ 'enabled' => 1, 'disabled' => 0, 'trashed' => -2, ]; + /** + * The name of the database table with task records. + * + * @var string + * @since __DEPLOY_VERSION__ + */ + public const TASK_TABLE = '#__scheduler_tasks'; + /** * Prefix used with controller messages * @@ -282,76 +294,178 @@ public function getItem($pk = null) } /** - * Lock the next task when no task is locked and returns it, otherwise null + * Get a task from the database, only if an exclusive "lock" on the task can be acquired. + * The method supports options to customise the limitations on the fetch. + * + * @param array $options Array with options to fetch the task: + * 1. `id`: Optional id of the task to fetch. + * 2. `allowDisabled`: If true, disabled tasks can also be fetched. + * (default: false) + * 3. `bypassScheduling`: If true, tasks that are not due can also be + * fetched. Should only be true if an `id` is targeted instead of the + * task queue. (default: false) + * 4. `allowConcurrent`: If true, fetches even when another task is + * running ('locked'). (default: false) * - * @param [type] $id + * @return ?\stdClass Task entry as in the database. * - * @return Task|null + * @since __DEPLOY_VERSION__ + * @throws UndefinedOptionsException|InvalidOptionsException + * @throws \RuntimeException */ - public function getNextTask($id = null, $unpublished = false) + public function getTask(array $options = []): ?\stdClass { - $now = Factory::getDate()->toSql(); + $resolver = new OptionsResolver; - // Try to lock the next task - $query = $this->getDbo()->getQuery(true); - $subquery = $this->getDbo()->getQuery(true); - - $subquery->select('COUNT(*)') - ->from($query->qn('#__scheduler_tasks')) - ->where($query->qn('locked') . ' IS NOT NULL'); - - $query ->update($query->qn('#__scheduler_tasks')) - ->set($query->qn('locked') . ' = :date1') - ->where('(' . $subquery . ') = 0') - ->where($query->qn('next_execution') . '<= :date2') - ->bind(':date1', $now) - ->bind(':date2', $now) - ->order($query->qn('priority') . ' DESC') - ->order($query->qn('next_execution') . ' ASC') - ->setLimit(1); - - if ($unpublished) + try { - $query->whereIn($query->qn('state'), [0, 1]); + $this->configureTaskGetterOptions($resolver); } - else + catch (\Exception $e) + { + } + + try + { + $options = $resolver->resolve($options); + } + catch (\Exception $e) + { + if ($e instanceof UndefinedOptionsException || $e instanceof InvalidOptionsException) + { + throw $e; + } + } + + $db = $this->getDbo(); + $now = Factory::getDate()->toSql(); + + // Get lock on the table to help with concurrency issues + $db->lockTable(self::TASK_TABLE); + + $lockQuery = $db->getQuery(true); + $idQuery = $db->getQuery(true); + $idWrapperQuery = $db->getQuery(true); + + // Get the id of the next task in the task queue + $idQuery->from($db->quoteName(self::TASK_TABLE)) + ->select('id') + ->order($db->quoteName('priority') . ' DESC') + ->order($db->quoteName('next_execution') . ' ASC') + ->setLimit(1) + ->alias($db->quoteName('nextTask')); + + // Wrap the id query for compatibility + $idWrapperQuery->select('*')->from($idQuery); + + // We'll attempt to get a lock on the task requested, if another task does not already have a pseudo-lock. + $lockQuery->update($db->quoteName(self::TASK_TABLE)) + ->set($db->quoteName('locked') . ' = :now1') + ->bind(':now1', $now) + ->where($db->quoteName('id') . " IN ($idWrapperQuery)"); + + if (!$options['bypassScheduling']) { - $query->where($query->qn('state') . ' = 1'); + $lockQuery->where($db->quoteName('next_execution') . ' <= :now2') + ->bind(':now2', $now); } - if ($id > 0) + if (!$options['allowConcurrent']) { - $query ->where($query->qn('id') . ' = :taskId') - ->bind(':taskId', $id, ParameterType::INTEGER); + $subQuery = $db->getQuery(true); + + // Sub-query to get count of locked tasks. + $subQuery->from($db->quoteName(self::TASK_TABLE)) + ->select('COUNT(*)') + ->where($db->quoteName('locked') . ' IS NOT NULL'); + + $lockQuery->where("($subQuery) = 0"); } - $this->getDbo()->lockTable($query->qn('#__scheduler_tasks')); + if ($options['allowDisabled']) + { + $lockQuery->whereIn($db->quoteName('state'), [0, 1]); + } + else + { + $lockQuery->where($db->quoteName('state') . ' = 1'); + } - $this->getDbo()->setQuery($query)->execute(); + if ($options['id'] > 0) + { + $lockQuery->where($db->quoteName('id') . ' = :taskId') + ->bind(':taskId', $options['id'], ParameterType::INTEGER); + } - $this->getDbo()->unlockTables(); + try + { + // Dbg + $db->lockTable(self::TASK_TABLE); + $queryStr = $lockQuery->__toString(); + $db->setQuery($lockQuery)->execute(); + } + catch (\RuntimeException $e) + { + } - if ($this->getDbo()->getAffectedRows() === 0) + if ($db->getAffectedRows() != 1) { + /* + // @todo + // ? Fatal failure handling here? + // ! Question is, how? If we check for tasks running beyond there time here, we have no way of + // ! what's already been notified (since we're not auto-unlocking/recovering tasks anymore). + // The solution __may__ be in a "last_successful_finish" (or something) column. + */ + return null; } - $query = $this->getDbo()->getQuery(true); + $getQuery = $db->getQuery(true); - $query->select('*') - ->from($query->qn('#__scheduler_tasks')) - ->where($query->qn('locked') . ' IS NOT NULL'); + $getQuery->select('*') + ->from($db->quoteName(self::TASK_TABLE)) + ->where($db->quoteName('locked') . ' = :now') + ->bind(':now', $now); - $task = $this->getDbo()->setQuery($query)->loadObject(); + $task = $db->setQuery($getQuery)->loadObject(); $task->execution_rules = json_decode($task->execution_rules); - $task->cron_rules = json_decode($task->cron_rules); + $task->cron_rules = json_decode($task->cron_rules); $task->taskOption = SchedulerHelper::getTaskOptions()->findOption($task->type); return $task; } + /** + * Set up an {@see OptionsResolver} to resolve options compatible with the {@see GetTask()} method. + * + * @param OptionsResolver $resolver The {@see OptionsResolver} instance to set up. + * + * @return OptionsResolver + * + * @since __DEPLOY_VERSION__ + * @throws AccessException + */ + public static function configureTaskGetterOptions(OptionsResolver $resolver): OptionsResolver + { + $resolver->setDefaults( + [ + 'id' => 0, + 'allowDisabled' => false, + 'bypassScheduling' => false, + 'allowConcurrent' => false, + ] + ) + ->setAllowedTypes('id', 'int') + ->setAllowedTypes('allowDisabled', 'bool') + ->setAllowedTypes('bypassScheduling', 'bool') + ->setAllowedTypes('allowConcurrent', 'bool'); + + return $resolver; + } + /** * @param array $data The form data * From d7d0605b49ae8bed94a0788bf0b80692ae4d7632 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Tue, 9 Nov 2021 22:37:43 +0530 Subject: [PATCH 546/615] Update Scheduler::getTask() and runTask() Updates Scheduler::getTask() and Scheduler::runTask() to match the updated TaskModel::getTask() method. --- .../com_scheduler/src/Scheduler/Scheduler.php | 61 +++++++++++++++---- 1 file changed, 50 insertions(+), 11 deletions(-) diff --git a/administrator/components/com_scheduler/src/Scheduler/Scheduler.php b/administrator/components/com_scheduler/src/Scheduler/Scheduler.php index a52b43b210dcd..72d5a3295a5e3 100644 --- a/administrator/components/com_scheduler/src/Scheduler/Scheduler.php +++ b/administrator/components/com_scheduler/src/Scheduler/Scheduler.php @@ -13,16 +13,17 @@ defined('_JEXEC') or die; use Assert\AssertionFailedException; -use Joomla\CMS\Application\CMSApplication; use Joomla\CMS\Factory; use Joomla\CMS\Language\Text; use Joomla\CMS\Log\Log; use Joomla\Component\Scheduler\Administrator\Extension\SchedulerComponent; +use Joomla\Component\Scheduler\Administrator\Model\TaskModel; use Joomla\Component\Scheduler\Administrator\Model\TasksModel; use Joomla\Component\Scheduler\Administrator\Task\Status; use Joomla\Component\Scheduler\Administrator\Task\Task; -use Joomla\Database\DatabaseDriver; -use Joomla\Database\DatabaseInterface; +use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException; +use Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException; +use Symfony\Component\OptionsResolver\OptionsResolver; /** * The Scheduler class provides the core functionality of ComScheduler. @@ -47,6 +48,8 @@ class Scheduler * Filters for the task queue. Can be used with fetchTaskRecords(). * * @since __DEPLOY_VERSION__ + * @todo remove? + * */ public const TASK_QUEUE_FILTERS = [ 'due' => 1, @@ -57,6 +60,8 @@ class Scheduler * List config for the task queue. Can be used with fetchTaskRecords(). * * @since __DEPLOY_VERSION__ + * @todo remove? + * */ public const TASK_QUEUE_LIST_CONFIG = [ 'multi_ordering' => ['a.priority DESC ', 'a.next_execution ASC'], @@ -66,17 +71,25 @@ class Scheduler * Run a scheduled task. * Runs a single due task from the task queue by default if $id and $title are not passed. * - * @param int $id The task ID - * @param bool $unpublished The task title + * @param int $id The task ID. By default, this is 0 and targets the task next in the task queue. + * @param bool $allowDisabled If true, disabled tasks can also be run. * * @return Task|null The task executed or null if not exists * * @since __DEPLOY_VERSION__ * @throws AssertionFailedException|\Exception */ - public function runTask(int $id = 0, bool $unpublished = false): ?Task + public function runTask(int $id = 0, bool $allowDisabled = false): ?Task { - $task = $this->getNextTask($id, $unpublished); + // ? Sure about inferring scheduling bypass? + $task = $this->getTask( + [ + 'id' => $id, + 'allowDisabled' => $allowDisabled, + 'bypassScheduling' => $id === 0, + 'allowConcurrent' => false, + ] + ); if (empty($task)) { @@ -126,17 +139,43 @@ public function runTask(int $id = 0, bool $unpublished = false): ?Task /** * Get the next task which is due to run, limit to a specific task when ID is given * - * @param integer $id + * @param array $options Options for the getter, see {@see TaskModel::getTask()}. + * ! should probably also support a non-locking getter. * * @return Task $task The task to execute + * + * @since __DEPLOY_VERSION__ + * @throws \RuntimeException */ - public function getNextTask(int $id = 0) + public function getTask(array $options = []): ?Task { + $resolver = new OptionsResolver; + + try + { + TaskModel::configureTaskGetterOptions($resolver); + } + catch (\Exception $e) + { + } + + try + { + $options = $resolver->resolve($options); + } + catch (\Exception $e) + { + if ($e instanceof UndefinedOptionsException || $e instanceof InvalidOptionsException) + { + throw $e; + } + } + try { $component = Factory::getApplication()->bootComponent('com_scheduler'); - /** @var TasksModel $model */ + /** @var TaskModel $model */ $model = $component->getMVCFactory()->createModel('Task', 'Administrator', ['ignore_request' => true]); } catch (\Exception $e) @@ -148,7 +187,7 @@ public function getNextTask(int $id = 0) throw new \RunTimeException('JLIB_APPLICATION_ERROR_MODEL_CREATE'); } - $task = $model->getNextTask($id); + $task = $model->getTask($options); if (empty($task)) { From e46a1437c65aee6865cf53e2ca20629fef30761c Mon Sep 17 00:00:00 2001 From: ditsuke Date: Tue, 9 Nov 2021 22:40:09 +0530 Subject: [PATCH 547/615] Fix typos and improve static analysis support Fixes some typos and adds some doc IDE typehint for improved static analysis to the Scheduler class. --- .../components/com_scheduler/src/Scheduler/Scheduler.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/administrator/components/com_scheduler/src/Scheduler/Scheduler.php b/administrator/components/com_scheduler/src/Scheduler/Scheduler.php index 72d5a3295a5e3..23b4dcf2eb907 100644 --- a/administrator/components/com_scheduler/src/Scheduler/Scheduler.php +++ b/administrator/components/com_scheduler/src/Scheduler/Scheduler.php @@ -173,6 +173,7 @@ public function getTask(array $options = []): ?Task try { + /** @var SchedulerComponent $component */ $component = Factory::getApplication()->bootComponent('com_scheduler'); /** @var TaskModel $model */ @@ -184,7 +185,7 @@ public function getTask(array $options = []): ?Task if (!isset($model)) { - throw new \RunTimeException('JLIB_APPLICATION_ERROR_MODEL_CREATE'); + throw new \RuntimeException('JLIB_APPLICATION_ERROR_MODEL_CREATE'); } $task = $model->getTask($options); @@ -207,6 +208,7 @@ public function getTask(array $options = []): ?Task * @return ?object A matching task record, if it exists * * @since __DEPLOY_VERSION__ + * @throws \RuntimeException */ public function fetchTaskRecord(int $id = 0, bool $unpublished = false): ?object { @@ -251,6 +253,7 @@ public function fetchTaskRecords(array $filters, array $listConfig): array try { + /** @var SchedulerComponent $component */ $component = Factory::getApplication()->bootComponent('com_scheduler'); /** @var TasksModel $model */ @@ -263,7 +266,7 @@ public function fetchTaskRecords(array $filters, array $listConfig): array if (!$model) { - throw new \RunTimeException('JLIB_APPLICATION_ERROR_MODEL_CREATE'); + throw new \RuntimeException('JLIB_APPLICATION_ERROR_MODEL_CREATE'); } $model->setState('list.select', '*'); From e2e61ada366563220493db5254219dc1ed4a0585 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Tue, 9 Nov 2021 22:42:47 +0530 Subject: [PATCH 548/615] Update/fix Schedulerunner Updates primarily the Schedulerunner::runTestCron() method. Other methods might need to be updated still. --- .../system/schedulerunner/schedulerunner.php | 37 ++++++++++++++----- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/plugins/system/schedulerunner/schedulerunner.php b/plugins/system/schedulerunner/schedulerunner.php index d6e900f92a9a0..92cd74e661d7c 100644 --- a/plugins/system/schedulerunner/schedulerunner.php +++ b/plugins/system/schedulerunner/schedulerunner.php @@ -176,7 +176,7 @@ public function runLazyCron() ignore_user_abort(true); } - // Supress all errors to avoid any output + // Suppress all errors to avoid any output try { $this->runScheduler(); @@ -212,7 +212,7 @@ public function runWebCron() throw new \Exception(Text::_('JERROR_ALERTNOAUTHOR'), 403); } - $id = (int) $this->app->input->getInt('id'); + $id = (int) $this->app->input->getInt('id', 0); $this->runScheduler($id); } @@ -232,6 +232,7 @@ public function runWebCron() public function runTestCron(Event $event) { $id = (int) $this->app->input->getInt('id'); + $allowConcurrent = $this->app->input->getBool('allowConcurrent', false); $user = Factory::getApplication()->getIdentity(); @@ -240,19 +241,37 @@ public function runTestCron(Event $event) throw new \Exception(Text::_('JERROR_ALERTNOAUTHOR'), 403); } - $task = $this->runScheduler($id, true); - - if ($task) + // About allow simultaneous, how do we detect if it failed because of pre-existing lock? + $task = (new Scheduler)->getTask( + [ + 'id' => $id, + 'allowDisabled' => true, + 'bypassScheduling' => true, + 'allowConcurrent' => $allowConcurrent + ] + ); + + if (!is_null($task)) { + $task->run(); $event->addArgument('result', $task->getContent()); } + + else + { + /* + * Placeholder result, but the idea is if we failed to fetch the task, its likely because another task was + * already running. This is a fair assumption if this test run was triggered through the administrator backend, + * so we know the task probably exists and is either enabled/disabled (not trashed, todo: check if button is disabled on trash view). + */ + $event->addArgument('result', ['message' => 'could not acquire lock on task. retry or allow concurrency.']); + } } /** * Run the scheduler, allowing execution of a single due task. * - * @param integer $id The optional ID of the task to run - * @param boolean $unpublished Allow execution of unpublished tasks? + * @param integer $id The optional ID of the task to run * * @return Task|boolean * @@ -260,9 +279,9 @@ public function runTestCron(Event $event) * @throws AssertionFailedException * */ - protected function runScheduler(int $id = 0, bool $unpublished = false): ?Task + protected function runScheduler(int $id = 0): ?Task { - return (new Scheduler)->runTask($id, $unpublished); + return (new Scheduler)->runTask($id); } /** From 7495b04cb716bed40213cd47f30a5f6ac8472a23 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Tue, 9 Nov 2021 22:46:37 +0530 Subject: [PATCH 549/615] Update Task class Minor updates, comments for the future. --- .../com_scheduler/src/Task/Task.php | 38 ++++++++++++++++--- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/administrator/components/com_scheduler/src/Task/Task.php b/administrator/components/com_scheduler/src/Task/Task.php index 3b81a17e53e66..e95171a784212 100644 --- a/administrator/components/com_scheduler/src/Task/Task.php +++ b/administrator/components/com_scheduler/src/Task/Task.php @@ -23,6 +23,7 @@ use Joomla\Component\Scheduler\Administrator\Event\ExecuteTaskEvent; use Joomla\Component\Scheduler\Administrator\Helper\ExecRuleHelper; use Joomla\Component\Scheduler\Administrator\Helper\SchedulerHelper; +use Joomla\Component\Scheduler\Administrator\Scheduler\Scheduler; use Joomla\Database\DatabaseDriver; use Joomla\Database\DatabaseInterface; use Joomla\Database\ParameterType; @@ -134,6 +135,22 @@ public function getRecord(): object */ public function run(): bool { + /** + * We try to acquire the lock here, only if we don't already have one. + * We do this, so we can support two ways of running tasks: + * 1. Directly through {@see Scheduler}, which optimises acquiring a lock while fetching from the task queue. + * 2. Running a task without a pre-acquired lock. + * ! This needs some more thought, for whether it should be allowed or if the single-query optimisation + * should be used everywhere, although it doesn't make sense in the context of fetching + * a task when it doesn't need to be run. This might be solved if we force a re-fetch + * with the lock or do it here ourselves (using acquireLock as a proxy to the model's + * getter). + */ + if ($this->get('locked') === null) + { + $this->acquireLock(); + } + // Exit early if task routine is not available if (!SchedulerHelper::getTaskOptions()->findOption($this->get('type'))) { @@ -204,6 +221,9 @@ public function getContent(): array /** * Acquire a pseudo-lock on the task record. + * ! At the moment, this method is not used anywhere as task locks are already + * acquired when they're fetched. As such this method is not functional and should + * not be reviewed until it is updated. * * @return boolean * @@ -222,14 +242,15 @@ public function acquireLock(): bool $timeoutThreshold = (clone $now)->sub($timeout)->toSql(); $now = $now->toSql(); - $query->update($db->qn('#__scheduler_tasks', 't')) - ->set('t.locked = :now') - ->where($db->qn('t.id') . ' = :taskId') + // @todo update or remove this method + $query->update($db->qn('#__scheduler_tasks')) + ->set('locked = :now') + ->where($db->qn('id') . ' = :taskId') ->extendWhere( 'AND', [ - $db->qn('t.locked') . ' < :threshold', - $db->qn('t.locked') . 'IS NULL', + $db->qn('locked') . ' < :threshold', + $db->qn('locked') . 'IS NULL', ], 'OR' ) @@ -239,14 +260,19 @@ public function acquireLock(): bool try { + $db->lockTable('#__scheduler_tasks'); $db->setQuery($query)->execute(); } catch (\RuntimeException $e) { return false; } + finally + { + $db->unlockTables(); + } - if (!$db->getAffectedRows()) + if ($db->getAffectedRows() === 0) { return false; } From e39fe8debd0ccbd0bf5b0c4e4563ec58c5520198 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Wed, 10 Nov 2021 17:18:16 +0530 Subject: [PATCH 550/615] Update Task::releaseLock() Fixes compatibility with PostgreSQL (tested on 11). Removes table specificity from columns (this confuses Postgres for some reason). --- .../components/com_scheduler/src/Task/Task.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/administrator/components/com_scheduler/src/Task/Task.php b/administrator/components/com_scheduler/src/Task/Task.php index e95171a784212..d22d6c6903f91 100644 --- a/administrator/components/com_scheduler/src/Task/Task.php +++ b/administrator/components/com_scheduler/src/Task/Task.php @@ -299,9 +299,9 @@ public function releaseLock(bool $update = true): bool $id = $this->get('id'); $query->update($db->qn('#__scheduler_tasks', 't')) - ->set('t.locked = NULL') - ->where($db->qn('t.id') . ' = :taskId') - ->where($db->qn('t.locked') . ' IS NOT NULL') + ->set('locked = NULL') + ->where($db->qn('id') . ' = :taskId') + ->where($db->qn('locked') . ' IS NOT NULL') ->bind(':taskId', $id, ParameterType::INTEGER); if ($update) @@ -314,11 +314,11 @@ public function releaseLock(bool $update = true): bool $query->set( [ - 't.last_exit_code = :exitCode', - 't.last_execution = :lastExec', - 't.next_execution = :nextExec', - 't.times_executed = :times_executed', - 't.times_failed = :times_failed', + 'last_exit_code = :exitCode', + 'last_execution = :lastExec', + 'next_execution = :nextExec', + 'times_executed = :times_executed', + 'times_failed = :times_failed', ] ) ->bind(':exitCode', $exitCode, ParameterType::INTEGER) @@ -329,7 +329,7 @@ public function releaseLock(bool $update = true): bool if ($exitCode !== Status::OK) { - $query->set('t.times_failed = t.times_failed + 1'); + $query->set('times_failed = t.times_failed + 1'); } } From d3e518baf0941b23a12ada93a4200187fb2ac8ce Mon Sep 17 00:00:00 2001 From: ditsuke Date: Wed, 10 Nov 2021 17:21:41 +0530 Subject: [PATCH 551/615] Update TaskModel::getTask() Fixes task queue behavior (now only applies when an ID is not passed). --- .../com_scheduler/src/Model/TaskModel.php | 43 +++++++++++-------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/administrator/components/com_scheduler/src/Model/TaskModel.php b/administrator/components/com_scheduler/src/Model/TaskModel.php index f5131ac8ff7d7..3b47e8af17674 100644 --- a/administrator/components/com_scheduler/src/Model/TaskModel.php +++ b/administrator/components/com_scheduler/src/Model/TaskModel.php @@ -344,25 +344,11 @@ public function getTask(array $options = []): ?\stdClass $db->lockTable(self::TASK_TABLE); $lockQuery = $db->getQuery(true); - $idQuery = $db->getQuery(true); - $idWrapperQuery = $db->getQuery(true); - - // Get the id of the next task in the task queue - $idQuery->from($db->quoteName(self::TASK_TABLE)) - ->select('id') - ->order($db->quoteName('priority') . ' DESC') - ->order($db->quoteName('next_execution') . ' ASC') - ->setLimit(1) - ->alias($db->quoteName('nextTask')); - - // Wrap the id query for compatibility - $idWrapperQuery->select('*')->from($idQuery); // We'll attempt to get a lock on the task requested, if another task does not already have a pseudo-lock. $lockQuery->update($db->quoteName(self::TASK_TABLE)) ->set($db->quoteName('locked') . ' = :now1') - ->bind(':now1', $now) - ->where($db->quoteName('id') . " IN ($idWrapperQuery)"); + ->bind(':now1', $now); if (!$options['bypassScheduling']) { @@ -396,17 +382,40 @@ public function getTask(array $options = []): ?\stdClass $lockQuery->where($db->quoteName('id') . ' = :taskId') ->bind(':taskId', $options['id'], ParameterType::INTEGER); } + else + { + $idQuery = $db->getQuery(true); + $idWrapperQuery = $db->getQuery(true); + + // Get the id of the next task in the task queue + $idQuery->from($db->quoteName(self::TASK_TABLE)) + ->select('id') + ->where($db->quoteName('state') . ' = 1') + ->order($db->quoteName('priority') . ' DESC') + ->order($db->quoteName('next_execution') . ' ASC') + ->setLimit(1) + ->alias($db->quoteName('nextTask')); + + // Wrap the id query for compatibility + $idWrapperQuery->select('*')->from($idQuery); + + // $lockQuery->join('INNER', $idQuery, $db->quoteName('#__scheduler_tasks.id') . ' = ' . $db->quoteName('nextTask.id')); + $lockQuery->where($db->quoteName('id') . " IN ($idWrapperQuery)"); + } try { - // Dbg - $db->lockTable(self::TASK_TABLE); + // @todo Remove -- Dbg $queryStr = $lockQuery->__toString(); $db->setQuery($lockQuery)->execute(); } catch (\RuntimeException $e) { } + finally + { + $db->unlockTables(); + } if ($db->getAffectedRows() != 1) { From da30f735bc119192fd2e42797bff20a6cceea264 Mon Sep 17 00:00:00 2001 From: ditsuke Date: Wed, 10 Nov 2021 21:40:18 +0530 Subject: [PATCH 552/615] Improve TaskModel::getTask() mysql compat ! Still fails because of table locks - Adds pseudo-source for sub-query. https://stackoverflow.com/q/44970574 - Adds reference comments to try to make the SQL gymnastics make sense. --- .../com_scheduler/src/Model/TaskModel.php | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/administrator/components/com_scheduler/src/Model/TaskModel.php b/administrator/components/com_scheduler/src/Model/TaskModel.php index 3b47e8af17674..2637809609a57 100644 --- a/administrator/components/com_scheduler/src/Model/TaskModel.php +++ b/administrator/components/com_scheduler/src/Model/TaskModel.php @@ -356,13 +356,19 @@ public function getTask(array $options = []): ?\stdClass ->bind(':now2', $now); } + // If concurrency is not allowed, we only get a task if another one does not have a "lock" if (!$options['allowConcurrent']) { + // MySQL needs a pseudo-source for the sub-query (https://stackoverflow.com/q/44970574) + $pseudoSource = $db->getQuery(true) + ->select($db->quoteName('id')) + ->from($db->quoteName(self::TASK_TABLE)) + ->alias('table_clone'); + $subQuery = $db->getQuery(true); // Sub-query to get count of locked tasks. - $subQuery->from($db->quoteName(self::TASK_TABLE)) - ->select('COUNT(*)') + $subQuery->from($pseudoSource)->select('COUNT(id)') ->where($db->quoteName('locked') . ' IS NOT NULL'); $lockQuery->where("($subQuery) = 0"); @@ -382,13 +388,12 @@ public function getTask(array $options = []): ?\stdClass $lockQuery->where($db->quoteName('id') . ' = :taskId') ->bind(':taskId', $options['id'], ParameterType::INTEGER); } + // Pick from the front of the task queue if no 'id' is specified else { - $idQuery = $db->getQuery(true); - $idWrapperQuery = $db->getQuery(true); - // Get the id of the next task in the task queue - $idQuery->from($db->quoteName(self::TASK_TABLE)) + $idQuery = $db->getQuery(true) + ->from($db->quoteName(self::TASK_TABLE)) ->select('id') ->where($db->quoteName('state') . ' = 1') ->order($db->quoteName('priority') . ' DESC') @@ -396,8 +401,8 @@ public function getTask(array $options = []): ?\stdClass ->setLimit(1) ->alias($db->quoteName('nextTask')); - // Wrap the id query for compatibility - $idWrapperQuery->select('*')->from($idQuery); + // Wrap the id query for compatibility (https://stackoverflow.com/q/17892762A) + $idWrapperQuery = $db->getQuery(true)->select('*')->from($idQuery); // $lockQuery->join('INNER', $idQuery, $db->quoteName('#__scheduler_tasks.id') . ' = ' . $db->quoteName('nextTask.id')); $lockQuery->where($db->quoteName('id') . " IN ($idWrapperQuery)"); From a370a150dc684cc0f9184985fe5a637877efc25f Mon Sep 17 00:00:00 2001 From: Benjamin Trenkle Date: Sat, 13 Nov 2021 11:49:48 +0100 Subject: [PATCH 553/615] Add unlock function --- .../src/Controller/TasksController.php | 64 ++++++++ .../com_scheduler/src/Model/TaskModel.php | 153 ++++++++++++++++++ .../com_scheduler/src/Model/TasksModel.php | 2 +- .../com_scheduler/src/Table/TaskTable.php | 127 +++++++++++++++ .../com_scheduler/src/View/Tasks/HtmlView.php | 2 + .../com_scheduler/tmpl/tasks/default.php | 18 +++ .../language/en-GB/com_scheduler.ini | 7 + 7 files changed, 372 insertions(+), 1 deletion(-) diff --git a/administrator/components/com_scheduler/src/Controller/TasksController.php b/administrator/components/com_scheduler/src/Controller/TasksController.php index bfdfafb7e9735..8f2d2d72f1e2e 100644 --- a/administrator/components/com_scheduler/src/Controller/TasksController.php +++ b/administrator/components/com_scheduler/src/Controller/TasksController.php @@ -12,8 +12,12 @@ // Restrict direct access \defined('_JEXEC') or die; +use Joomla\CMS\Factory; +use Joomla\CMS\Language\Text; use Joomla\CMS\MVC\Controller\AdminController; use Joomla\CMS\MVC\Model\BaseDatabaseModel; +use Joomla\CMS\Router\Route; +use Joomla\Utilities\ArrayHelper; /** * MVC Controller for TasksView. @@ -37,4 +41,64 @@ public function getModel($name = 'Task', $prefix = 'Administrator', $config = [' { return parent::getModel($name, $prefix, $config); } + + /** + * Unlocks a running task + * + * @return void + */ + public function unlock() + { + // Check for request forgeries + $this->checkToken(); + + // Get items to publish from the request. + $cid = $this->input->get('cid', array(), 'array'); + + if (empty($cid)) + { + $this->app->getLogger()->warning(Text::_($this->text_prefix . '_NO_ITEM_SELECTED'), array('category' => 'jerror')); + } + else + { + // Get the model. + $model = $this->getModel(); + + // Make sure the item ids are integers + $cid = ArrayHelper::toInteger($cid); + + // Unlock the items. + try + { + $model->unlock($cid); + $errors = $model->getErrors(); + $ntext = null; + + if ($errors) + { + Factory::getApplication()->enqueueMessage(Text::plural($this->text_prefix . '_N_ITEMS_FAILED_UNLOCKING', \count($cid)), 'error'); + } + else + { + $ntext = $this->text_prefix . '_N_ITEMS_UNLOCKED'; + } + + if (\count($cid)) + { + $this->setMessage(Text::plural($ntext, \count($cid))); + } + } + catch (\Exception $e) + { + $this->setMessage($e->getMessage(), 'error'); + } + } + + $this->setRedirect( + Route::_( + 'index.php?option=' . $this->option . '&view=' . $this->view_list + . $this->getRedirectToListAppend(), false + ) + ); + } } diff --git a/administrator/components/com_scheduler/src/Model/TaskModel.php b/administrator/components/com_scheduler/src/Model/TaskModel.php index 1410349f54fe7..24c5cd7705caa 100644 --- a/administrator/components/com_scheduler/src/Model/TaskModel.php +++ b/administrator/components/com_scheduler/src/Model/TaskModel.php @@ -14,9 +14,12 @@ use Joomla\CMS\Application\AdministratorApplication; use Joomla\CMS\Component\ComponentHelper; +use Joomla\CMS\Event\AbstractEvent; use Joomla\CMS\Factory; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormFactoryInterface; +use Joomla\CMS\Language\Text; +use Joomla\CMS\Log\Log; use Joomla\CMS\MVC\Factory\MVCFactoryInterface; use Joomla\CMS\MVC\Model\AdminModel; use Joomla\CMS\Object\CMSObject; @@ -70,6 +73,22 @@ class TaskModel extends AdminModel */ protected $app; + /** + * The event to trigger before unlocking the data. + * + * @var string + * @since __DEPLOY_VERSION__ + */ + protected $event_before_unlock = null; + + /** + * The event to trigger after unlocking the data. + * + * @var string + * @since __DEPLOY_VERSION__ + */ + protected $event_unlock = null; + /** * TaskModel constructor. Needed just to set $app @@ -84,14 +103,34 @@ class TaskModel extends AdminModel public function __construct($config = array(), MVCFactoryInterface $factory = null, FormFactoryInterface $formFactory = null) { $config['events_map'] = $config['events_map'] ?? []; + $config['events_map'] = array_merge( [ 'save' => 'task', 'validate' => 'task', + 'unlock' => 'task', ], $config['events_map'] ); + if (isset($config['event_before_unlock'])) + { + $this->event_before_unlock = $config['event_before_unlock']; + } + elseif (empty($this->event_before_unlock)) + { + $this->event_before_unlock = 'onContentBeforeUnlock'; + } + + if (isset($config['event_unlock'])) + { + $this->event_unlock = $config['event_unlock']; + } + elseif (empty($this->event_unlock)) + { + $this->event_unlock = 'onContentUnlock'; + } + $this->app = Factory::getApplication(); parent::__construct($config, $factory, $formFactory); @@ -415,6 +454,120 @@ private function buildExecutionRules(array $executionRules): array ]; } + /** + * Method to unlock one or more records. + * + * @param array &$pks A list of the primary keys to unlock. + * @param integer $value The value of the published state. + * + * @return boolean True on success. + * + * @since __DEPLOY_VERSION__ + */ + public function unlock(&$pks) + { + $user = Factory::getUser(); + $table = $this->getTable(); + $pks = (array) $pks; + + $context = $this->option . '.' . $this->name; + + // Include the plugins for the change of state event. + PluginHelper::importPlugin($this->events_map['unlock']); + + // Access checks. + foreach ($pks as $i => $pk) + { + $table->reset(); + + if ($table->load($pk)) + { + if (!$this->canEditState($table)) + { + // Prune items that you can't change. + unset($pks[$i]); + + Log::add(Text::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED'), Log::WARNING, 'jerror'); + + return false; + } + + /** + * Prune items that are already at the given state. Note: Only models whose table correctly + * sets 'published' column alias (if different than published) will benefit from this + */ + $lockedColumnName = $table->getColumnAlias('locked'); + + if (property_exists($table, $lockedColumnName) && is_null($table->get($lockedColumnName))) + { + unset($pks[$i]); + + continue; + } + } + } + + // Check if there are items to change + if (!\count($pks)) + { + return true; + } + + $event = AbstractEvent::create( + $this->event_before_unlock, + [ + 'subject' => $this, + 'context' => $context, + 'pks' => $pks + ] + ); + + try + { + Factory::getApplication()->getDispatcher()->dispatch($this->event_before_unlock, $event); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // Attempt to unlock the records. + if (!$table->unlock($pks)) + { + $this->setError($table->getError()); + + return false; + } + + // Trigger the after unlock event + $event = AbstractEvent::create( + $this->event_unlock, + [ + 'subject' => $this, + 'context' => $context, + 'pks' => $pks + ] + ); + + try + { + Factory::getApplication()->getDispatcher()->dispatch($this->event_unlock, $event); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // Clear the component's cache + $this->cleanCache(); + + return true; + } + /** * Determine if an array is populated by all its possible values by comparison to a reference array, if found a * match a wildcard '*' is returned. diff --git a/administrator/components/com_scheduler/src/Model/TasksModel.php b/administrator/components/com_scheduler/src/Model/TasksModel.php index c0234e313055d..ea3cec6426979 100644 --- a/administrator/components/com_scheduler/src/Model/TasksModel.php +++ b/administrator/components/com_scheduler/src/Model/TasksModel.php @@ -119,7 +119,7 @@ protected function getListQuery(): QueryInterface $query->select( $this->getState( 'list.select', - 'a.id, a.asset_id, a.title, a.type, a.execution_rules, a.state, a.last_exit_code' . + 'a.id, a.asset_id, a.title, a.type, a.execution_rules, a.state, a.last_exit_code, a.locked' . ', a.last_execution, a.next_execution, a.times_executed, a.times_failed, a.ordering, a.note' ) ); diff --git a/administrator/components/com_scheduler/src/Table/TaskTable.php b/administrator/components/com_scheduler/src/Table/TaskTable.php index f45555393e119..c78b3309bdad3 100644 --- a/administrator/components/com_scheduler/src/Table/TaskTable.php +++ b/administrator/components/com_scheduler/src/Table/TaskTable.php @@ -12,6 +12,7 @@ // Restrict direct access defined('_JEXEC') or die; +use Joomla\CMS\Event\AbstractEvent; use Joomla\CMS\Factory; use Joomla\CMS\MVC\Model\AdminModel; use Joomla\CMS\Table\Asset; @@ -181,4 +182,130 @@ public function bind($src, $ignore = array()): bool return parent::bind($src, $ignore); } + /** + * Method to unlockr a row or list of rows in the database table. + * + * @param mixed $pks An optional array of primary key values to update. If not set the instance property value is used. + * + * @return boolean True on success; false if $pks is empty. + * + * @since 1.7.0 + */ + public function unlock($pks = null) + { + // Sanitize input + $userId = (int) $userId; + $state = (int) $state; + + // Pre-processing by observers + $event = AbstractEvent::create( + 'onTableBeforeUnlock', + [ + 'subject' => $this, + 'pks' => $pks, + 'state' => $state, + 'userId' => $userId, + ] + ); + + $this->getDispatcher()->dispatch('onTableBeforeUnlock', $event); + + if (!\is_null($pks)) + { + if (!\is_array($pks)) + { + $pks = array($pks); + } + + foreach ($pks as $key => $pk) + { + if (!\is_array($pk)) + { + $pks[$key] = array($this->_tbl_key => $pk); + } + } + } + + // If there are no primary keys set check to see if the instance key is set. + if (empty($pks)) + { + $pk = array(); + + foreach ($this->_tbl_keys as $key) + { + if ($this->$key) + { + $pk[$key] = $this->$key; + } + // We don't have a full primary key - return false + else + { + $this->setError(Text::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED')); + + return false; + } + } + + $pks = array($pk); + } + + $lockedField = $this->getColumnAlias('locked'); + + foreach ($pks as $pk) + { + // Update the publishing state for rows with the given primary keys. + $query = $this->_db->getQuery(true) + ->update($this->_tbl) + ->set($this->_db->quoteName($lockedField) . ' = NULL'); + + // Build the WHERE clause for the primary keys. + $this->appendPrimaryKeys($query, $pk); + + $this->_db->setQuery($query); + + try + { + $this->_db->execute(); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // If the Table instance value is in the list of primary keys that were set, set the instance. + $ours = true; + + foreach ($this->_tbl_keys as $key) + { + if ($this->$key != $pk[$key]) + { + $ours = false; + } + } + + if ($ours) + { + $this->$lockedField = null; + } + } + + $this->setError(''); + + // Pre-processing by observers + $event = AbstractEvent::create( + 'onTableAfterUnlock', + [ + 'subject' => $this, + 'pks' => $pks, + 'state' => $state, + 'userId' => $userId, + ] + ); + + $this->getDispatcher()->dispatch('onTableAfterUnlock', $event); + + return true; + } } diff --git a/administrator/components/com_scheduler/src/View/Tasks/HtmlView.php b/administrator/components/com_scheduler/src/View/Tasks/HtmlView.php index e3f309d2f4540..e7c9820e3376f 100644 --- a/administrator/components/com_scheduler/src/View/Tasks/HtmlView.php +++ b/administrator/components/com_scheduler/src/View/Tasks/HtmlView.php @@ -169,6 +169,8 @@ protected function addToolbar(): void $childBar->addNew('tasks.publish', 'JTOOLBAR_ENABLE')->listCheck(true)->icon('icon-publish'); $childBar->addNew('tasks.unpublish', 'JTOOLBAR_DISABLE')->listCheck(true)->icon('icon-unpublish'); + $childBar->checkin('tasks.unlock', 'COM_SCHEDULER_TOOLBAR_UNLOCK')->listCheck(true)->icon('icon-unlock'); + // We don't want the batch Trash button if displayed entries are all trashed if ($this->state->get('filter.state') != -2) { diff --git a/administrator/components/com_scheduler/tmpl/tasks/default.php b/administrator/components/com_scheduler/tmpl/tasks/default.php index 89d0fd3c33b55..a189c6ccf3bdb 100644 --- a/administrator/components/com_scheduler/tmpl/tasks/default.php +++ b/administrator/components/com_scheduler/tmpl/tasks/default.php @@ -120,6 +120,11 @@ class="visually-hidden"> + +
+ + @@ -181,6 +186,14 @@ class="js-draggable" data-url="" data-direction=" + locked) : ?> + $canChange, 'prefix' => 'tasks.', + 'active_class' => 'none fa fa-running border-dark text-body', + 'inactive_class' => 'none fa fa-running', 'tip' => true, 'translate' => false, + 'active_title' => Text::sprintf('COM_SCHEDULER_RUNNING_SINCE', HTMLHelper::_('date', $item->last_execution, 'DATE_FORMAT_LC5')), + 'inactive_title' => Text::sprintf('COM_SCHEDULER_RUNNING_SINCE', HTMLHelper::_('date', $item->last_execution, 'DATE_FORMAT_LC5')) + ]); ?> + escape($item->title); ?> @@ -202,6 +215,11 @@ class="js-draggable" data-url="" data-direction=" escape($item->safeTypeTitle); ?> + + + last_execution ? HTMLHelper::_('date', $item->last_execution, 'DATE_FORMAT_LC5') : '-'; ?> +