From ade1e8cef5b6b15ff83910813de8ce673adcbded Mon Sep 17 00:00:00 2001 From: Franz Holzinger Date: Thu, 28 Nov 2019 14:13:18 +0100 Subject: [PATCH] * Add example slots * Add scheduler tasks * Support for TYPO3 9 together with typo3db_legacy --- ChangeLog | 14 +- Classes/Api/Api.php | 6 +- Classes/Api/ImportApi.php | 131 +++++++++++ ...rtTablesWizardModuleFunctionController.php | 0 ...mpleSlots.php => ExampleFunctionSlots.php} | 5 +- Classes/Slots/ExampleSchedulerSlots.php | 55 +++++ Classes/Task/ImportTask.php | 146 +++++++++++++ .../ImportTaskAdditionalFieldProvider.php | 205 ++++++++++++++++++ README.txt => README.md | 0 Resources/Private/Language/locallang.xlf | 12 + .../Private/Language/locallang_csh_import.xlf | 11 + composer.json | 8 +- ext_localconf.php | 112 +++++++--- ext_tables.php | 9 +- 14 files changed, 668 insertions(+), 46 deletions(-) create mode 100755 Classes/Api/ImportApi.php mode change 100644 => 100755 Classes/Controller/ImportTablesWizardModuleFunctionController.php rename Classes/Slots/{ExampleSlots.php => ExampleFunctionSlots.php} (93%) mode change 100644 => 100755 create mode 100755 Classes/Slots/ExampleSchedulerSlots.php create mode 100755 Classes/Task/ImportTask.php create mode 100755 Classes/Task/ImportTaskAdditionalFieldProvider.php rename README.txt => README.md (100%) mode change 100644 => 100755 Resources/Private/Language/locallang.xlf create mode 100755 Resources/Private/Language/locallang_csh_import.xlf mode change 100644 => 100755 composer.json diff --git a/ChangeLog b/ChangeLog index 37beca8..4fb525b 100755 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,16 @@ -(add new changes on top of this file) +2019-11-28 Franz Holzinger + + * Add example slots + * Add scheduler tasks + * Support for TYPO3 9 together with typo3db_legacy + +2019-01-18 Franz Holzinger + + * Make usage of the scheduler + +2019-01-18 Franz Holzinger + + * rename Classes/Slots/ExampleSlots.php -> Classes/Slots/ExampleFunctionSlots.php 2017-06-06 Franz Holzinger diff --git a/Classes/Api/Api.php b/Classes/Api/Api.php index a25a507..52cf158 100755 --- a/Classes/Api/Api.php +++ b/Classes/Api/Api.php @@ -26,6 +26,8 @@ * */ +use TYPO3\CMS\Core\Utility\GeneralUtility; + class Api { /** @@ -38,7 +40,7 @@ class Api { */ public function __construct () { - $this->signalSlotDispatcher = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\SignalSlot\Dispatcher::class); + $this->signalSlotDispatcher = GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\SignalSlot\Dispatcher::class); } public function importTableFile ( @@ -48,7 +50,7 @@ public function importTableFile ( $separator = ',', $enclosure = '"', $mode = 0, - $firstLineFieldnames = FALSE + $firstLineFieldnames = false ) { $result = false; diff --git a/Classes/Api/ImportApi.php b/Classes/Api/ImportApi.php new file mode 100755 index 0000000..702ee77 --- /dev/null +++ b/Classes/Api/ImportApi.php @@ -0,0 +1,131 @@ + + * @maintainer Franz Holzinger + * @package TYPO3 + * @subpackage import + */ + + + +class ImportApi { + + static public function getTableArray () { + $result = array(); + + if ( + isset($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][IMPORT_EXT]) && + is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][IMPORT_EXT]) && + isset($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][IMPORT_EXT]['import.']) + ) { + $systemTableArray = array(); + $extensionTableArray = array(); + + if ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][IMPORT_EXT]['import.']['systemtables'] != '') { + $systemTableArray = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][IMPORT_EXT]['import.']['systemtables']); + } + + if ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][IMPORT_EXT]['import.']['extensiontables'] != '') { + $extensionTableArray = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][IMPORT_EXT]['import.']['extensiontables']); + } + + $tableArray = array_merge($systemTableArray, $extensionTableArray); + foreach ($tableArray as $table) { + $result[] = array( + 'table' => $table, + 'title' => $table // TODO: title of the table + ); + } + } + + return $result; + } + + static public function getLocalDefinitionArray () { + $tableArray = self::getTableArray(); + + $result = array( + array( + 'ext' => IMPORT_EXT, + 'tables' => $tableArray + ) + ); + return $result; + } + + static public function getPathname () { + $result = false; + + if ( + isset($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][IMPORT_EXT]) && + is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][IMPORT_EXT]) && + isset($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][IMPORT_EXT]['import.']) && + isset($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][IMPORT_EXT]['import.']['path']) + ) { + $result = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][IMPORT_EXT]['import.']['path']; + } + + return $result; + } + + + static public function execute (...$params) { + $result = false; + + if ( + isset($params) && + is_array($params) && + !empty($params) + ) { + $result = true; + $tableArray = $params['0']; + foreach ($tableArray as $table) { + if ( + isset($GLOBALS['TCA'][$table]) && + isset($GLOBALS['TCA'][$table]['columns']) + ) { + $select_fields = '*'; + $where_clause = + $table . '.deleted=0'; +// $result = \JambageCom\Move\Api\MoveItemsApi::execute( +// $configurationFile, +// $table, +// $select_fields, +// $where_clause +// ); + } + } + } + + return $result; + } +} diff --git a/Classes/Controller/ImportTablesWizardModuleFunctionController.php b/Classes/Controller/ImportTablesWizardModuleFunctionController.php old mode 100644 new mode 100755 diff --git a/Classes/Slots/ExampleSlots.php b/Classes/Slots/ExampleFunctionSlots.php old mode 100644 new mode 100755 similarity index 93% rename from Classes/Slots/ExampleSlots.php rename to Classes/Slots/ExampleFunctionSlots.php index 9464158..e1b336c --- a/Classes/Slots/ExampleSlots.php +++ b/Classes/Slots/ExampleFunctionSlots.php @@ -19,9 +19,9 @@ use JambageCom\Import\Api\Api; /** - * Class for example slots to import files into TYPO3 tables + * Class for example slots to import files into TYPO3 tables based on the Function Module */ -class ExampleSlots implements \TYPO3\CMS\Core\SingletonInterface +class ExampleFunctionSlots implements \TYPO3\CMS\Core\SingletonInterface { protected $tables = array('pages', 'tt_content'); @@ -98,4 +98,3 @@ public function processImport ( } } - diff --git a/Classes/Slots/ExampleSchedulerSlots.php b/Classes/Slots/ExampleSchedulerSlots.php new file mode 100755 index 0000000..6cf947f --- /dev/null +++ b/Classes/Slots/ExampleSchedulerSlots.php @@ -0,0 +1,55 @@ + IMPORT_EXT, + 'class' => null, + 'tables' => array( + array( + 'table' => 'pages', + 'title' => 'Pages' + ), + array( + 'table' => 'fe_users', + 'title' => 'Front End Users' + ), + ) + ); + + $definitionArray[] = $newDefinitionArray; + $result = array($pObj, $definitionArray); + return $result; + } +} + + diff --git a/Classes/Task/ImportTask.php b/Classes/Task/ImportTask.php new file mode 100755 index 0000000..786ff50 --- /dev/null +++ b/Classes/Task/ImportTask.php @@ -0,0 +1,146 @@ + + * @maintainer Franz Holzinger + * @package TYPO3 + * @subpackage import + */ + +use TYPO3\CMS\Core\Utility\GeneralUtility; + +class ImportTask extends \TYPO3\CMS\Scheduler\Task\AbstractTask { + + /** + * Array of tables to import + * + * @var array $tableArray + */ + public $tableArray; + + /** + * @var \TYPO3\CMS\Extbase\SignalSlot\Dispatcher + */ + protected $signalSlotDispatcher; + + /** + * Constructor + */ + public function __construct() + { + parent::__construct(); + + $this->signalSlotDispatcher = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\SignalSlot\Dispatcher::class); + } + + public function execute () + { + $result = false; + $slotDefinitionArray = array(); + $slotResult = + $this->signalSlotDispatcher->dispatch( + __CLASS__, + 'definition', + array( + $this, + $slotDefinitionArray + ) + ); + $slotDefinitionArray = $slotResult['1']; + + if ( + isset($this->tableArray) && + is_array($this->tableArray) && + !empty($this->tableArray) + ) { + $result = true; + $localDefinitionArray = \JambageCom\Import\Api\ImportApi::getLocalDefinitionArray(); + $definitionArray = array_merge($localDefinitionArray, $slotDefinitionArray); +// + foreach ($definitionArray as $definition) { + if ( + !isset($definition['tables']) || + !is_array($definition['tables']) + ) { + continue; + } + + if (isset($definition['ext'])) { + + $foreignExtension = $definition['ext']; + if ( + $foreignExtension != IMPORT_EXT && + !\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded($foreignExtension) + ) { + return false; + } + } + + $extensionTables = array(); + foreach ($definition['tables'] as $tableDefinition) { + $extensionTables[] = $tableDefinition['table']; + } + $theTableArray = array(); + + foreach ($this->tableArray as $table) { + if (in_array($table, $extensionTables)) { + $theTableArray[] = $table; + } + } + + if (!empty($theTableArray)) { + if (isset($definition['class'])) { + + $foreignClass = $definition['class']; + if ( + class_exists($foreignClass) && + method_exists($foreignClass, 'execute') + ) { + $foreignObject = GeneralUtility::makeInstance($foreignClass); + $result = $foreignObject->execute($theTableArray); + } else { + $result = false; + break; + } + } else { + \JambageCom\Import\Api\ImportApi::execute($theTableArray); + } + } + } + } + + return $result; + } + + + public function getAdditionalInformation () + { + } +} diff --git a/Classes/Task/ImportTaskAdditionalFieldProvider.php b/Classes/Task/ImportTaskAdditionalFieldProvider.php new file mode 100755 index 0000000..5ad0443 --- /dev/null +++ b/Classes/Task/ImportTaskAdditionalFieldProvider.php @@ -0,0 +1,205 @@ + + * @maintainer Franz Holzinger + * @package TYPO3 + * @subpackage import + */ + + +class ImportTaskAdditionalFieldProvider implements \TYPO3\CMS\Scheduler\AdditionalFieldProviderInterface { + /** + * @var \TYPO3\CMS\Extbase\SignalSlot\Dispatcher + */ + protected $signalSlotDispatcher; + + /** + * Constructor + */ + public function __construct() + { + $this->signalSlotDispatcher = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\SignalSlot\Dispatcher::class); + } + + public function getAdditionalFields ( + array &$taskInfo, + $task, + \TYPO3\CMS\Scheduler\Controller\SchedulerModuleController $parentObject + ) { + $result = array(); + $cmd = $parentObject->CMD; + + if (empty($taskInfo['additionalscheduler_numberDays'])) { + if ($cmd == 'edit') { + $taskInfo['additionalscheduler_numberDays'] = $task->numberDays; + } else { + $taskInfo['additionalscheduler_numberDays'] = ''; + } + } + $additionalFields = array(); + $fieldID = 'task_numberDays'; + $fieldCode = ''; + $additionalFields[$fieldID] = array( + 'code' => $fieldCode, + 'label' => 'LLL:EXT:additional_scheduler/Resources/Private/Language/locallang.xlf:numberDays', + 'cshKey' => 'additional_scheduler', + 'cshLabel' => $fieldID + ); + + $field = 'tables'; + $fieldID = IMPORT_EXT . '_' . $field; + $mainFieldDefaultName = 'tx_scheduler[' . IMPORT_EXT . ']'; + $tableFieldName = 'tx_scheduler[' . IMPORT_EXT . '][' . $field . ']'; + + $slotDefinitionArray = array(); + $slotResult = + $this->signalSlotDispatcher->dispatch( + __CLASS__, + 'definition', + array( + $this, + $slotDefinitionArray + ) + ); + $slotDefinitionArray = $slotResult['1']; + $localDefinitionArray = \JambageCom\Import\Api\ImportApi::getLocalDefinitionArray(); + + if ( + isset($slotDefinitionArray) && + is_array($slotDefinitionArray) + ) { + $definitionArray = array_merge($localDefinitionArray, $slotDefinitionArray); + } else { + $definitionArray = $localDefinitionArray; + } + + $label = ''; + $fieldCode = ''; + $checkbox = array(); + $defaultTable = 'pages'; + $selectedTables = array(); + + if ( + empty($taskInfo[IMPORT_EXT]) || + empty($taskInfo[IMPORT_EXT]) || + empty($taskInfo[IMPORT_EXT][$field]) + ) { + if ($cmd == 'edit') { + $taskInfo[IMPORT_EXT][$foreignExtension][$field] = $task->{$field}; + } else { + $taskInfo[IMPORT_EXT][$foreignExtension][$field] = array($defaultTable); + } + } else { + $selectedTables = $taskInfo[IMPORT_EXT][$field]; + } + + foreach ($definitionArray as $definition) { + if ( + !isset($definition['ext']) || + !isset($definition['tables']) || + !is_array($definition['tables']) + ) { + continue; + } + $foreignExtension = $definition['ext']; + if ( + $foreignExtension != IMPORT_EXT && + !\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded($foreignExtension) + ) { + continue; + } + + foreach ($definition['tables'] as $definitionArray) { + if ( + !isset($definitionArray['table']) || + !isset($definitionArray['title']) + ) { + continue; + } + $theTable = $definitionArray['table']; + $checked = ''; + if (in_array($theTable, $selectedTables)) { + $checked = ' checked '; + } + + $checkbox[] = ' ' . htmlspecialchars($definitionArray['title']) . ' '; + } + } + + $fieldCode = $label; + + if (!empty($checkbox)) { + foreach ($checkbox as $line) { + $innerHtml .= '
  • ' . $line . '
  • '; + } + } + + $fieldCode .= '
      ' . $innerHtml . '
    '; + + $result[$fieldID] = array( + 'code' => $fieldCode, + 'label' => 'LLL:EXT:' . IMPORT_EXT . '/Resources/Private/Language/locallang.xlf:importTables', // Todo: use the $foreignExtension label here + 'cshKey' => IMPORT_CSHKEY, + 'cshLabel' => $fieldID + ); + + return $result; + } + + + public function validateAdditionalFields ( + array &$submittedData, + \TYPO3\CMS\Scheduler\Controller\SchedulerModuleController $parentObject + ) { + $result = true; + + return $result; + } + + public function saveAdditionalFields ( + array $submittedData, + \TYPO3\CMS\Scheduler\Task\AbstractTask $task + ) { + $field = 'tables'; + + if ( + empty($submittedData) || + empty($submittedData[IMPORT_EXT]) || + empty($submittedData[IMPORT_EXT][$field]) + ) { + $task->tableArray = array(); + } else { + $task->tableArray = $submittedData[IMPORT_EXT][$field]; + } + } +} + diff --git a/README.txt b/README.md similarity index 100% rename from README.txt rename to README.md diff --git a/Resources/Private/Language/locallang.xlf b/Resources/Private/Language/locallang.xlf old mode 100644 new mode 100755 index aca5ce4..7470812 --- a/Resources/Private/Language/locallang.xlf +++ b/Resources/Private/Language/locallang.xlf @@ -5,6 +5,9 @@ Import into database tables. + + The import into database tables has been finished. + Pages @@ -17,6 +20,15 @@ The tables have been imported. + + Import task + + + The import task reads various CSV and XML files and writes their data into database tables. + + + Tables for Import + diff --git a/Resources/Private/Language/locallang_csh_import.xlf b/Resources/Private/Language/locallang_csh_import.xlf new file mode 100755 index 0000000..923689a --- /dev/null +++ b/Resources/Private/Language/locallang_csh_import.xlf @@ -0,0 +1,11 @@ + + + +
    + + + Class of the task + + + + diff --git a/composer.json b/composer.json old mode 100644 new mode 100755 index 5752fc3..e39ffc6 --- a/composer.json +++ b/composer.json @@ -15,14 +15,14 @@ { "name": "Franz Holzinger", "role": "Developer", - "homepage": "http://ttproducts.de" + "homepage": "https://ttproducts.de" } ], "license": [ - "GPL-2.0+" + "GPL-2.0-or-later" ], "require": { - "typo3/cms-core": ">=7.6.0,<8.99.99" + "typo3/cms-core": ">=7.6.0,<9.99.99" }, "autoload": { "psr-4": { @@ -30,7 +30,7 @@ } }, "replace": { - "import": "self.version", + "jambagecom/import": "self.version", "typo3-ter/import": "self.version" }, "extra": { diff --git a/ext_localconf.php b/ext_localconf.php index 1528e82..7df772d 100755 --- a/ext_localconf.php +++ b/ext_localconf.php @@ -1,47 +1,91 @@ connect( - \JambageCom\Import\Controller\ImportTablesWizardModuleFunctionController::class, - // Signal class name - 'menu', // Signal name - \JambageCom\Import\Slots\ExampleSlots::class, // Slot class name - 'getMenu' // Slot name -); + if ( + defined('TYPO3_version') && + version_compare(TYPO3_version, '9.0.0', '>=') + ) { + $extensionConfiguration = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance( + \TYPO3\CMS\Core\Configuration\ExtensionConfiguration::class + )->get(IMPORT_EXT); + } else { // before TYPO3 9 + $extensionConfiguration = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf'][IMPORT_EXT]); + } + define('IMPORT_CSHKEY', '_MOD_system_txschedulerM1_' . IMPORT_EXT); // key for the Context Sensitive Help -$signalSlotDispatcher->connect( - \JambageCom\Import\Controller\ImportTablesWizardModuleFunctionController::class, - // Signal class name - 'import', // Signal name - \JambageCom\Import\Slots\ExampleSlots::class, // Slot class name - 'importTables' // Slot name -); + /** @var \TYPO3\CMS\Extbase\SignalSlot\Dispatcher $signalSlotDispatcher */ + $signalSlotDispatcher = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\SignalSlot\Dispatcher::class); + $signalSlotDispatcher->connect( + \JambageCom\Import\Controller\ImportTablesWizardModuleFunctionController::class, + // Signal class name + 'menu', // Signal name + \JambageCom\Import\Slots\ExampleFunctionSlots::class, // Slot class name + 'getMenu' // Slot name + ); + + $signalSlotDispatcher->connect( + \JambageCom\Import\Controller\ImportTablesWizardModuleFunctionController::class, + // Signal class name + 'import', // Signal name + \JambageCom\Import\Slots\ExampleFunctionSlots::class, // Slot class name + 'importTables' // Slot name + ); + $signalSlotDispatcher->connect( + \JambageCom\Import\Api\Api::class, + // Signal class name + 'importTableFile', // Signal name + \JambageCom\Import\Slots\ExampleFunctionSlots::class, // Slot class name + 'processImport' // Slot name + ); -$signalSlotDispatcher->connect( - \JambageCom\Import\Api\Api::class, + $signalSlotDispatcher->connect( + \JambageCom\Import\Task\ImportTask::class, // Signal class name - 'importTableFile', // Signal name - \JambageCom\Import\Slots\ExampleSlots::class, // Slot class name - 'processImport' // Slot name -); + 'definition', // Signal name + \JambageCom\Import\Slots\ExampleSchedulerSlots::class, // Slot class name + 'addDefinitionArray' // Slot name + ); + $signalSlotDispatcher->connect( + \JambageCom\Import\Task\ImportTaskAdditionalFieldProvider::class, + // Signal class name + 'definition', // Signal name + \JambageCom\Import\Slots\ExampleSchedulerSlots::class, // Slot class name + 'addDefinitionArray' // Slot name + ); + + // Add the import task to the scheduler + $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['scheduler']['tasks'][\JambageCom\Import\Task\ImportTask::class] = array( + 'extension' => IMPORT_EXT, + 'title' => 'LLL:EXT:' . IMPORT_EXT . '/Resources/Private/Language/locallang.xlf:importTask.name', + 'description' => 'LLL:EXT:' . IMPORT_EXT . '/Resources/Private/Language/locallang.xlf:importTask.description', + 'additionalFields' => \JambageCom\Import\Task\ImportTaskAdditionalFieldProvider::class + ); + if ( + isset($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][IMPORT_EXT]) && + is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][IMPORT_EXT]) + ) { + $tmpArray = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][IMPORT_EXT]; + } -// TODO: scheduler + if (isset($extensionConfiguration) && is_array($extensionConfiguration)) { + $GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][IMPORT_EXT] = $extensionConfiguration; + if (isset($tmpArray) && is_array($tmpArray)) { + $GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][IMPORT_EXT] = + array_merge($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][IMPORT_EXT], $tmpArray); + } + } else if (!isset($tmpArray)) { + $GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][IMPORT_EXT] = array(); + } + }); +} -// $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['scheduler']['tasks']['tx_import_Task'] = array( -// 'extension' => $_EXTKEY, -// 'title' => 'LLL:EXT:' . $_EXTKEY . '/tasks/locallang.xml:importTask.name', -// 'description' => 'LLL:EXT:' . $_EXTKEY . '/tasks/locallang.xml:importTask.description', -// 'additionalFields' => 'tx_import_Task_AdditionalFieldProvider' -// ); -// diff --git a/ext_tables.php b/ext_tables.php index 307e39e..32b674a 100755 --- a/ext_tables.php +++ b/ext_tables.php @@ -1,5 +1,5 @@