[FEATURE] Move workspaces scheduler tasks to native symfony commands 56/58056/5
authorBenni Mack <benni@typo3.org>
Tue, 28 Aug 2018 04:51:18 +0000 (06:51 +0200)
committerBenni Mack <benni@typo3.org>
Tue, 28 Aug 2018 11:11:11 +0000 (13:11 +0200)
The previously available scheduler tasks for auto-publishing and cleaning up
preview links have been moved to a symfony/command, allowing them to be
scheduled, but also triggered manually on the command line without having
to create a task record in scheduler.

The old tasks have been deprecated, as there is the possibility to create
tasks out of symfony commands as well.

The AutoPublishService, which only acted as a wrapper, but had a major
design flaw has been deprecated as well.

The scheduler tasks will be removed in TYPO3 v10. For TYPO3 v9, their
labels have been updated, and they will trigger a deprecation notice.

Resolves: #86001
Releases: master
Change-Id: I9c1f1e31b6ff59d02b20ffc2df805e645bb3f675
Reviewed-on: https://review.typo3.org/58056
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Benni Mack <benni@typo3.org>
Tested-by: Benni Mack <benni@typo3.org>
typo3/sysext/core/Documentation/Changelog/master/Deprecation-86001-WorkspacesTasksMigratedToSymfonyCommands.rst [new file with mode: 0644]
typo3/sysext/core/Documentation/Changelog/master/Feature-86001-RegularWorkspaceCleanupTasksAvailableViaCLICommands.rst [new file with mode: 0644]
typo3/sysext/install/Configuration/ExtensionScanner/Php/ClassNameMatcher.php
typo3/sysext/workspaces/Classes/Command/AutoPublishCommand.php [new file with mode: 0644]
typo3/sysext/workspaces/Classes/Command/CleanupPreviewLinksCommand.php [new file with mode: 0644]
typo3/sysext/workspaces/Classes/Service/AutoPublishService.php
typo3/sysext/workspaces/Classes/Task/AutoPublishTask.php
typo3/sysext/workspaces/Classes/Task/CleanupPreviewLinkTask.php
typo3/sysext/workspaces/Configuration/Commands.php
typo3/sysext/workspaces/Resources/Private/Language/locallang_mod.xlf
typo3/sysext/workspaces/ext_localconf.php

diff --git a/typo3/sysext/core/Documentation/Changelog/master/Deprecation-86001-WorkspacesTasksMigratedToSymfonyCommands.rst b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-86001-WorkspacesTasksMigratedToSymfonyCommands.rst
new file mode 100644 (file)
index 0000000..74f87d1
--- /dev/null
@@ -0,0 +1,46 @@
+.. include:: ../../Includes.txt
+
+===================================================================
+Deprecation: #86001 - Workspaces tasks migrated to symfony commands
+===================================================================
+
+See :issue:`86001`
+
+Description
+===========
+
+The custom scheduler tasks for workspace publishing and removing of preview links have been migrated
+to custom symfony commands, making the functionality specifically within the scheduler context obsolete.
+
+The following tasks should not be used anymore:
+* Workspaces auto-publication
+* Workspaces cleanup preview links
+
+The following related classes have been deprecated:
+* :php:`TYPO3\CMS\Workspaces\Service\AutoPublishService`
+* :php:`TYPO3\CMS\Workspaces\Task\AutoPublishTask`
+* :php:`TYPO3\CMS\Workspaces\Task\CleanupPreviewLinkTask`
+
+The scheduler tasks are still available, but marked as obsolete.
+
+
+Impact
+======
+
+Executing one of the tasks above will trigger a deprecation message. Calling any of the classes from the outside
+will also trigger a deprecation message.
+
+
+Affected Installations
+======================
+
+TYPO3 Installations using workspaces in combination with any of the two scheduler tasks.
+
+
+Migration
+=========
+
+Create a new scheduler task based on the Symfony Command and select one of the symfony-based commands
+"cleanup:previewlinks" or "workspace:auto-publish" respectively.
+
+.. index:: CLI, FullyScanned, ext:workspaces
\ No newline at end of file
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-86001-RegularWorkspaceCleanupTasksAvailableViaCLICommands.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-86001-RegularWorkspaceCleanupTasksAvailableViaCLICommands.rst
new file mode 100644 (file)
index 0000000..12bcb1f
--- /dev/null
@@ -0,0 +1,30 @@
+.. include:: ../../Includes.txt
+
+============================================================================
+Feature: #86001 - Regular Workspace cleanup tasks available via CLI commands
+============================================================================
+
+See :issue:`86001`
+
+Description
+===========
+
+TYPO3 now supports two new symfony-based commands to trigger regular tasks, which were previously only
+available when the scheduler component was available.
+
+* typo3/sysext/core/bin/typo3 workspace:autopublish
+
+Checks for workspaces with auto-publishing configured and does a publishing/swapping process.
+
+* typo3/sysext/core/bin/typo3 cleanup:previewlinks
+
+Removes expired previewlinks stored within `sys_preview` from the database.
+
+
+Impact
+======
+
+It is possible to execute these commands from the CLI context without having to install the scheduler extension
+and to create a scheduler task for that.
+
+.. index:: CLI, ext:workspaces
\ No newline at end of file
index c274a05..c2835eb 100644 (file)
@@ -809,4 +809,19 @@ return [
             'Deprecation-85833-ExtensionSaltedpasswordsMergedIntoCoreExtension.rst',
         ],
     ],
+    'TYPO3\CMS\Workspaces\Service\AutoPublishService' => [
+        'restFiles' => [
+            'Deprecation-86001-WorkspacesTasksMigratedToSymfonyCommands.rst',
+        ],
+    ],
+    'TYPO3\CMS\Workspaces\Task\AutoPublishTask' => [
+        'restFiles' => [
+            'Deprecation-86001-WorkspacesTasksMigratedToSymfonyCommands.rst',
+        ],
+    ],
+    'TYPO3\CMS\Workspaces\Task\CleanupPreviewLinkTask' => [
+        'restFiles' => [
+            'Deprecation-86001-WorkspacesTasksMigratedToSymfonyCommands.rst',
+        ],
+    ],
 ];
diff --git a/typo3/sysext/workspaces/Classes/Command/AutoPublishCommand.php b/typo3/sysext/workspaces/Classes/Command/AutoPublishCommand.php
new file mode 100644 (file)
index 0000000..15cafe1
--- /dev/null
@@ -0,0 +1,145 @@
+<?php
+declare(strict_types = 1);
+namespace TYPO3\CMS\Workspaces\Command;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
+use TYPO3\CMS\Core\Core\Bootstrap;
+use TYPO3\CMS\Core\Database\ConnectionPool;
+use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
+use TYPO3\CMS\Core\DataHandling\DataHandler;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Workspaces\Service\WorkspaceService;
+
+/**
+ * Call on the workspace logic to publish workspaces whose publication date is in the past
+ */
+class AutoPublishCommand extends Command
+{
+
+    /**
+     * Configuring the command options
+     */
+    public function configure()
+    {
+        $this
+            ->setDescription('Publish a workspace with a publication date.')
+            ->setHelp('Some workspaces can have an auto-publish publication date to put all "ready to publish" content online on a certain date.');
+    }
+
+    /**
+     * Executes the command to find versioned records
+     *
+     * @param InputInterface $input
+     * @param OutputInterface $output
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        // Make sure the _cli_ user is loaded
+        Bootstrap::initializeBackendAuthentication();
+        $io = new SymfonyStyle($input, $output);
+
+        $workspaceService = GeneralUtility::makeInstance(WorkspaceService::class);
+
+        // Select all workspaces that needs to be published / unpublished
+        $statement = $this->getAffectedWorkspacesToPublish();
+
+        $affectedWorkspaces = 0;
+        while ($workspaceRecord = $statement->fetch()) {
+            // First, clear start/end time so it doesn't get selected once again
+            $fieldArray = (int)$workspaceRecord['publish_time'] !== 0
+                ? ['publish_time' => 0]
+                : ['unpublish_time' => 0];
+
+            GeneralUtility::makeInstance(ConnectionPool::class)
+                ->getConnectionForTable('sys_workspace')
+                ->update(
+                    'sys_workspace',
+                    $fieldArray,
+                    ['uid' => (int)$workspaceRecord['uid']]
+                );
+
+            // Get CMD array
+            $cmd = $workspaceService->getCmdArrayForPublishWS(
+                $workspaceRecord['uid'],
+                (int)$workspaceRecord['swap_modes'] === 1
+            );
+            // $workspaceRecord['swap_modes'] == 1 means that auto-publishing will swap versions,
+            // not just publish and empty the workspace.
+            $tce = GeneralUtility::makeInstance(DataHandler::class);
+            $tce->start([], $cmd);
+            $tce->process_cmdmap();
+            $affectedWorkspaces++;
+        }
+
+        if ($affectedWorkspaces > 0) {
+            $io->success('Published ' . $affectedWorkspaces . ' workspaces.');
+        } else {
+            $io->note('Nothing to do.');
+        }
+    }
+
+    /**
+     * Fetch all sys_workspace records which could fit
+     * @return \Doctrine\DBAL\Driver\Statement|int
+     */
+    protected function getAffectedWorkspacesToPublish()
+    {
+        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_workspace');
+        $queryBuilder->getRestrictions()
+            ->removeAll()
+            ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
+
+        return $queryBuilder
+            ->select('uid', 'swap_modes', 'publish_time', 'unpublish_time')
+            ->from('sys_workspace')
+            ->where(
+                $queryBuilder->expr()->eq(
+                    'pid',
+                    $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)
+                ),
+                $queryBuilder->expr()->orX(
+                    $queryBuilder->expr()->andX(
+                        $queryBuilder->expr()->neq(
+                            'publish_time',
+                            $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)
+                        ),
+                        $queryBuilder->expr()->lte(
+                            'publish_time',
+                            $queryBuilder->createNamedParameter($GLOBALS['EXEC_TIME'], \PDO::PARAM_INT)
+                        )
+                    ),
+                    $queryBuilder->expr()->andX(
+                        $queryBuilder->expr()->eq(
+                            'publish_time',
+                            $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)
+                        ),
+                        $queryBuilder->expr()->neq(
+                            'unpublish_time',
+                            $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)
+                        ),
+                        $queryBuilder->expr()->lte(
+                            'unpublish_time',
+                            $queryBuilder->createNamedParameter($GLOBALS['EXEC_TIME'], \PDO::PARAM_INT)
+                        )
+                    )
+                )
+            )
+            ->execute();
+    }
+}
diff --git a/typo3/sysext/workspaces/Classes/Command/CleanupPreviewLinksCommand.php b/typo3/sysext/workspaces/Classes/Command/CleanupPreviewLinksCommand.php
new file mode 100644 (file)
index 0000000..4204307
--- /dev/null
@@ -0,0 +1,68 @@
+<?php
+declare(strict_types = 1);
+namespace TYPO3\CMS\Workspaces\Command;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
+use TYPO3\CMS\Core\Database\ConnectionPool;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+
+/**
+ * Removes unused records from sys_preview
+ */
+class CleanupPreviewLinksCommand extends Command
+{
+
+    /**
+     * Configuring the command options
+     */
+    public function configure()
+    {
+        $this
+            ->setDescription('Clean up expired preview links from shared workspace previews.')
+            ->setHelp('Look for preview links within the database table "sys_preview" that have been expired and and remove them. This command should be called regularly when working with workspaces.');
+    }
+
+    /**
+     * Executes the command to find versioned records
+     *
+     * @param InputInterface $input
+     * @param OutputInterface $output
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        $io = new SymfonyStyle($input, $output);
+
+        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_preview');
+        $affectedRows = $queryBuilder
+            ->delete('sys_preview')
+            ->where(
+                $queryBuilder->expr()->lt(
+                    'endtime',
+                    $queryBuilder->createNamedParameter($GLOBALS['EXEC_TIME'], \PDO::PARAM_INT)
+                )
+            )
+            ->execute();
+
+        if ($affectedRows > 0) {
+            $io->success('Cleaned up ' . $affectedRows . ' preview links.');
+        } else {
+            $io->note('No expired preview links found. All done.');
+        }
+    }
+}
index b5755eb..71fda9c 100644 (file)
@@ -21,14 +21,22 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
  * Automatic publishing of workspaces.
+ *
+ * @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0. This job is a one-time functionality now built into the "autopublish" functionality.
  */
 class AutoPublishService
 {
+    public function __construct()
+    {
+        trigger_error('AutoPublishService will be removed in TYPO3 v10.0. Use the symfony command "workspaces:autopublish" instead.', E_USER_DEPRECATED);
+    }
+
     /**
      * This method is called by the Scheduler task that triggers
      * the autopublication process
      * It searches for workspaces whose publication date is in the past
      * and publishes them
+     * @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
      */
     public function autoPublishWorkspaces()
     {
index c32528f..570c6b0 100644 (file)
@@ -17,6 +17,8 @@ namespace TYPO3\CMS\Workspaces\Task;
 /**
  * This class provides a wrapper around the autopublication
  * mechanism of workspaces, as a Scheduler task
+ *
+ * @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
  */
 class AutoPublishTask extends \TYPO3\CMS\Scheduler\Task\AbstractTask
 {
@@ -29,6 +31,7 @@ class AutoPublishTask extends \TYPO3\CMS\Scheduler\Task\AbstractTask
      */
     public function execute()
     {
+        trigger_error('This scheduler task is not in use anymore, please re-create the task within TYPO3 Scheduler by using the symfony command "Workspace Auto-Publish".', E_USER_DEPRECATED);
         $autopubObj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Workspaces\Service\AutoPublishService::class);
         // Publish the workspaces that need to be
         $autopubObj->autoPublishWorkspaces();
index ca22452..c92d79b 100644 (file)
@@ -18,6 +18,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
  * This class provides a task to cleanup ol preview links.
+ * @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
  */
 class CleanupPreviewLinkTask extends \TYPO3\CMS\Scheduler\Task\AbstractTask
 {
@@ -29,6 +30,7 @@ class CleanupPreviewLinkTask extends \TYPO3\CMS\Scheduler\Task\AbstractTask
      */
     public function execute()
     {
+        trigger_error('This scheduler task is not in use anymore, please re-create the task within TYPO3 Scheduler by using the symfony command "Cleanup Preview Links".', E_USER_DEPRECATED);
         $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_preview');
         $queryBuilder
             ->delete('sys_preview')
index 0eca608..e156d33 100644 (file)
@@ -8,5 +8,11 @@
 return [
     'cleanup:versions' => [
         'class' => \TYPO3\CMS\Workspaces\Command\WorkspaceVersionRecordsCommand::class,
-    ]
+    ],
+    'cleanup:previewlinks' => [
+        'class' => \TYPO3\CMS\Workspaces\Command\CleanupPreviewLinksCommand::class,
+    ],
+    'workspace:autopublish' => [
+        'class' => \TYPO3\CMS\Workspaces\Command\AutoPublishCommand::class,
+    ],
 ];
index a2fcfac..32dbf33 100644 (file)
                                <source>Create and handle versioning workflows</source>
                        </trans-unit>
                        <trans-unit id="autopublishTask.name">
-                               <source>Workspaces auto-publication</source>
+                               <source>Workspaces auto-publication (outdated, use the Symfony Command)</source>
                        </trans-unit>
                        <trans-unit id="autopublishTask.description">
                                <source>This tasks checks any workspace that has a publication date set in the past and automatically publishes it.</source>
                        </trans-unit>
                        <trans-unit id="cleanupPreviewLinkTask.name">
-                               <source>Workspaces cleanup preview links</source>
+                               <source>Workspaces cleanup preview links (outdated, use the Symfony Command)</source>
                        </trans-unit>
                        <trans-unit id="cleanupPreviewLinkTask.description">
                                <source>This task delete old preview links</source>
index c115222..a863934 100644 (file)
@@ -9,6 +9,7 @@ tx_version.workspaces.stageNotificationEmail.message = LLL:EXT:workspaces/Resour
 ');
 
 // Register the autopublishing task
+// This will be removed in favor of the CLI command workspace:autopublish
 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['scheduler']['tasks'][\TYPO3\CMS\Workspaces\Task\AutoPublishTask::class] = [
     'extension' => 'workspaces',
     'title' => 'LLL:EXT:workspaces/Resources/Private/Language/locallang_mod.xlf:autopublishTask.name',
@@ -16,6 +17,7 @@ $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['scheduler']['tasks'][\TYPO3\CMS\Works
 ];
 
 // Register the cleanup preview links task
+// This will be removed in favor of the CLI command cleanup:previewlinks
 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['scheduler']['tasks'][\TYPO3\CMS\Workspaces\Task\CleanupPreviewLinkTask::class] = [
     'extension' => 'workspaces',
     'title' => 'LLL:EXT:workspaces/Resources/Private/Language/locallang_mod.xlf:cleanupPreviewLinkTask.name',