first commit
This commit is contained in:
commit
1218dd1517
12716 files changed
+989233
No files matched your search
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Impexp\Command\Exception;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Import failed
|
||||
*/
|
||||
class ImportFailedException extends \RuntimeException
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Impexp\Command\Exception;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* File was not found or could not be opened
|
||||
*/
|
||||
class InvalidFileException extends \InvalidArgumentException
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Impexp\Command\Exception;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* File could not be loaded
|
||||
*/
|
||||
class LoadingFileFailedException extends \RuntimeException
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Impexp\Command\Exception;
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Prerequisites are not met
|
||||
*/
|
||||
class PrerequisitesNotMetException extends \RuntimeException
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Impexp\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\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
use TYPO3\CMS\Core\Core\Bootstrap;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Impexp\Import;
|
||||
|
||||
/**
|
||||
* Command for importing T3D/XML data files
|
||||
*/
|
||||
class ImportCommand extends Command
|
||||
{
|
||||
/**
|
||||
* Configure the command by defining the name, options and arguments
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setDescription('Imports a T3D / XML file with content into a page tree')
|
||||
->addArgument(
|
||||
'file',
|
||||
InputArgument::REQUIRED,
|
||||
'The path and filename to import (.t3d or .xml)'
|
||||
)
|
||||
->addArgument(
|
||||
'pageId',
|
||||
InputArgument::OPTIONAL,
|
||||
'The page ID to start from. If empty, the root level (= pageId=0) is used.'
|
||||
)->addOption(
|
||||
'updateRecords',
|
||||
null,
|
||||
InputOption::VALUE_NONE,
|
||||
'If set, existing records with the same UID will be updated instead of inserted'
|
||||
)->addOption(
|
||||
'ignorePid',
|
||||
null,
|
||||
InputOption::VALUE_NONE,
|
||||
'If set, page IDs of updated records are not corrected (only works in conjunction with the updateRecords option)'
|
||||
)->addOption(
|
||||
'enableLog',
|
||||
null,
|
||||
InputOption::VALUE_NONE,
|
||||
'If set, all database actions are logged'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the command for importing a t3d/xml file into the TYPO3 system
|
||||
*
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$fileName = $input->getArgument('file');
|
||||
$fileName = GeneralUtility::getFileAbsFileName($fileName);
|
||||
if (empty($fileName) || !file_exists($fileName)) {
|
||||
throw new Exception\InvalidFileException('The given filename "' . ($fileName ?? $input->getArgument('file')) . '" could not be found', 1484483040);
|
||||
}
|
||||
|
||||
$io = new SymfonyStyle($input, $output);
|
||||
|
||||
// Ensure the _cli_ user is authenticated
|
||||
Bootstrap::initializeBackendAuthentication();
|
||||
|
||||
$pageId = (int)$input->getArgument('pageId');
|
||||
|
||||
$import = GeneralUtility::makeInstance(Import::class);
|
||||
$import->init();
|
||||
$import->update = (bool)($input->hasOption('updateRecords') && $input->getOption('updateRecords'));
|
||||
// Only used when $updateRecords is "true"
|
||||
$import->global_ignore_pid = (bool)($input->hasOption('ignorePid') && $input->getOption('ignorePid'));
|
||||
// Enables logging of database actions
|
||||
$import->enableLogging = (bool)($input->hasOption('enableLog') && $input->getOption('enableLog'));
|
||||
|
||||
if (!$import->loadFile($fileName, true)) {
|
||||
$io->error($import->errorLog);
|
||||
throw new Exception\LoadingFileFailedException('Loading of the import file failed.', 1484484619);
|
||||
}
|
||||
|
||||
$messages = $import->checkImportPrerequisites();
|
||||
if (!empty($messages)) {
|
||||
$io->error($messages);
|
||||
throw new Exception\PrerequisitesNotMetException('Prerequisites for file import are not met.', 1484484612);
|
||||
}
|
||||
|
||||
$import->importData($pageId);
|
||||
if (!empty($import->errorLog)) {
|
||||
$io->error($import->errorLog);
|
||||
throw new Exception\ImportFailedException('The import has failed.', 1484484613);
|
||||
}
|
||||
|
||||
$io->success('Imported ' . $input->getArgument('file') . ' to page ' . $pageId . ' successfully');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
namespace TYPO3\CMS\Impexp\ContextMenu;
|
||||
|
||||
/*
|
||||
* 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 TYPO3\CMS\Backend\ContextMenu\ItemProviders\AbstractProvider;
|
||||
|
||||
/**
|
||||
* Context menu item provider adding export and import items
|
||||
* @internal this is a internal TYPO3 hook implementation and solely used for EXT:impexp and not part of TYPO3's Core API.
|
||||
*/
|
||||
class ItemProvider extends AbstractProvider
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $itemsConfiguration = [
|
||||
'exportT3d' => [
|
||||
'type' => 'item',
|
||||
'label' => 'LLL:EXT:impexp/Resources/Private/Language/locallang.xlf:export',
|
||||
'iconIdentifier' => 'actions-document-export-t3d',
|
||||
'callbackAction' => 'exportT3d'
|
||||
],
|
||||
'importT3d' => [
|
||||
'type' => 'item',
|
||||
'label' => 'LLL:EXT:impexp/Resources/Private/Language/locallang.xlf:import',
|
||||
'iconIdentifier' => 'actions-document-import-t3d',
|
||||
'callbackAction' => 'importT3d',
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
* Export item is added for all database records except files
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canHandle(): bool
|
||||
{
|
||||
return !in_array($this->table, ['sys_file', 'sys_filemounts', 'sys_file_storage'], true)
|
||||
&& strpos($this->table, '-drag') === false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This needs to be lower than priority of the RecordProvider
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getPriority(): int
|
||||
{
|
||||
return 50;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds import/export items to the "submenu" if available
|
||||
*
|
||||
* @param array $items
|
||||
* @return array
|
||||
*/
|
||||
public function addItems(array $items): array
|
||||
{
|
||||
$this->initDisabledItems();
|
||||
$localItems = $this->prepareItems($this->itemsConfiguration);
|
||||
if (isset($items['more']['childItems'])) {
|
||||
$items['more']['childItems'] = $items['more']['childItems'] + $localItems;
|
||||
} else {
|
||||
$items += $localItems;
|
||||
}
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $itemName
|
||||
* @param string $type
|
||||
* @return bool
|
||||
*/
|
||||
protected function canRender(string $itemName, string $type): bool
|
||||
{
|
||||
if (in_array($itemName, $this->disabledItems, true)) {
|
||||
return false;
|
||||
}
|
||||
$canRender = false;
|
||||
switch ($itemName) {
|
||||
case 'exportT3d':
|
||||
$canRender = true;
|
||||
break;
|
||||
case 'importT3d':
|
||||
$canRender = $this->table === 'pages' && $this->isImportEnabled();
|
||||
break;
|
||||
}
|
||||
return $canRender;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers custom JS module with item onclick behaviour
|
||||
*
|
||||
* @param string $itemName
|
||||
* @return array
|
||||
*/
|
||||
protected function getAdditionalAttributes(string $itemName): array
|
||||
{
|
||||
return ['data-callback-module' => 'TYPO3/CMS/Impexp/ContextMenuActions'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if import functionality is available for current user
|
||||
*/
|
||||
protected function isImportEnabled(): bool
|
||||
{
|
||||
return $this->backendUser->isAdmin()
|
||||
|| !$this->backendUser->isAdmin() && (bool)($this->backendUser->getTSConfig()['options.']['impexp.']['enableImportForNonAdminUser'] ?? false);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,230 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Impexp\Domain\Repository;
|
||||
|
||||
/*
|
||||
* 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 TYPO3\CMS\Core\Database\Connection;
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Messaging\FlashMessage;
|
||||
use TYPO3\CMS\Core\Messaging\FlashMessageQueue;
|
||||
use TYPO3\CMS\Core\Messaging\FlashMessageService;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Handling of presets
|
||||
* @internal this is not part of TYPO3's Core API.
|
||||
*/
|
||||
class PresetRepository
|
||||
{
|
||||
/**
|
||||
* @param int $pageId
|
||||
* @return array
|
||||
*/
|
||||
public function getPresets($pageId)
|
||||
{
|
||||
$options = [''];
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable('tx_impexp_presets');
|
||||
|
||||
$queryBuilder->select('*')
|
||||
->from('tx_impexp_presets')
|
||||
->where(
|
||||
$queryBuilder->expr()->orX(
|
||||
$queryBuilder->expr()->gt(
|
||||
'public',
|
||||
$queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)
|
||||
),
|
||||
$queryBuilder->expr()->eq(
|
||||
'user_uid',
|
||||
$queryBuilder->createNamedParameter($this->getBackendUser()->user['uid'], \PDO::PARAM_INT)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
if ($pageId) {
|
||||
$queryBuilder->andWhere(
|
||||
$queryBuilder->expr()->orX(
|
||||
$queryBuilder->expr()->eq(
|
||||
'item_uid',
|
||||
$queryBuilder->createNamedParameter($pageId, \PDO::PARAM_INT)
|
||||
),
|
||||
$queryBuilder->expr()->eq(
|
||||
'item_uid',
|
||||
$queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$presets = $queryBuilder->execute();
|
||||
while ($presetCfg = $presets->fetch()) {
|
||||
$options[$presetCfg['uid']] = $presetCfg['title'] . ' [' . $presetCfg['uid'] . ']'
|
||||
. ($presetCfg['public'] ? ' [Public]' : '')
|
||||
. ($presetCfg['user_uid'] === $this->getBackendUser()->user['uid'] ? ' [Own]' : '');
|
||||
}
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get single preset record
|
||||
*
|
||||
* @param int $uid Preset record
|
||||
* @return array Preset record, if any (otherwise FALSE)
|
||||
*/
|
||||
public function getPreset($uid)
|
||||
{
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable('tx_impexp_presets');
|
||||
|
||||
return $queryBuilder->select('*')
|
||||
->from('tx_impexp_presets')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq(
|
||||
'uid',
|
||||
$queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT)
|
||||
)
|
||||
)
|
||||
->execute()
|
||||
->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Manipulate presets
|
||||
*
|
||||
* @param array $inData In data array, passed by reference!
|
||||
*/
|
||||
public function processPresets(&$inData)
|
||||
{
|
||||
$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('tx_impexp_presets');
|
||||
$presetData = GeneralUtility::_GP('preset');
|
||||
$err = false;
|
||||
$msg = '';
|
||||
// Save preset
|
||||
$beUser = $this->getBackendUser();
|
||||
// cast public checkbox to int, since this is an int field and NULL is not allowed
|
||||
$inData['preset']['public'] = (int)$inData['preset']['public'];
|
||||
if (isset($presetData['save'])) {
|
||||
$preset = $this->getPreset($presetData['select']);
|
||||
// Update existing
|
||||
if (is_array($preset)) {
|
||||
if ($beUser->isAdmin() || $preset['user_uid'] === $beUser->user['uid']) {
|
||||
$connection->update(
|
||||
'tx_impexp_presets',
|
||||
[
|
||||
'public' => $inData['preset']['public'],
|
||||
'title' => $inData['preset']['title'],
|
||||
'item_uid' => $inData['pagetree']['id'],
|
||||
'preset_data' => serialize($inData)
|
||||
],
|
||||
['uid' => (int)$preset['uid']],
|
||||
['preset_data' => Connection::PARAM_LOB]
|
||||
);
|
||||
|
||||
$msg = 'Preset #' . $preset['uid'] . ' saved!';
|
||||
} else {
|
||||
$msg = 'ERROR: The preset was not saved because you were not the owner of it!';
|
||||
$err = true;
|
||||
}
|
||||
} else {
|
||||
// Insert new:
|
||||
$connection->insert(
|
||||
'tx_impexp_presets',
|
||||
[
|
||||
'user_uid' => $beUser->user['uid'],
|
||||
'public' => $inData['preset']['public'],
|
||||
'title' => $inData['preset']['title'],
|
||||
'item_uid' => (int)$inData['pagetree']['id'],
|
||||
'preset_data' => serialize($inData)
|
||||
],
|
||||
['preset_data' => Connection::PARAM_LOB]
|
||||
);
|
||||
|
||||
$msg = 'New preset "' . htmlspecialchars($inData['preset']['title']) . '" is created';
|
||||
}
|
||||
}
|
||||
// Delete preset:
|
||||
if (isset($presetData['delete'])) {
|
||||
$preset = $this->getPreset($presetData['select']);
|
||||
if (is_array($preset)) {
|
||||
// Update existing
|
||||
if ($beUser->isAdmin() || $preset['user_uid'] === $beUser->user['uid']) {
|
||||
$connection->delete(
|
||||
'tx_impexp_presets',
|
||||
['uid' => (int)$preset['uid']]
|
||||
);
|
||||
|
||||
$msg = 'Preset #' . $preset['uid'] . ' deleted!';
|
||||
} else {
|
||||
$msg = 'ERROR: You were not the owner of the preset so you could not delete it.';
|
||||
$err = true;
|
||||
}
|
||||
} else {
|
||||
$msg = 'ERROR: No preset selected for deletion.';
|
||||
$err = true;
|
||||
}
|
||||
}
|
||||
// Load preset
|
||||
if (isset($presetData['load']) || isset($presetData['merge'])) {
|
||||
$preset = $this->getPreset($presetData['select']);
|
||||
if (is_array($preset)) {
|
||||
// Update existing
|
||||
$inData_temp = unserialize($preset['preset_data'], ['allowed_classes' => false]);
|
||||
if (is_array($inData_temp)) {
|
||||
if (isset($presetData['merge'])) {
|
||||
// Merge records in:
|
||||
if (is_array($inData_temp['record'])) {
|
||||
$inData['record'] = array_merge((array)$inData['record'], $inData_temp['record']);
|
||||
}
|
||||
// Merge lists in:
|
||||
if (is_array($inData_temp['list'])) {
|
||||
$inData['list'] = array_merge((array)$inData['list'], $inData_temp['list']);
|
||||
}
|
||||
} else {
|
||||
$msg = 'Preset #' . $preset['uid'] . ' loaded!';
|
||||
$inData = $inData_temp;
|
||||
}
|
||||
} else {
|
||||
$msg = 'ERROR: No configuratio data found in preset record!';
|
||||
$err = true;
|
||||
}
|
||||
} else {
|
||||
$msg = 'ERROR: No preset selected for loading.';
|
||||
$err = true;
|
||||
}
|
||||
}
|
||||
// Show message:
|
||||
if ($msg !== '') {
|
||||
/** @var FlashMessage $flashMessage */
|
||||
$flashMessage = GeneralUtility::makeInstance(
|
||||
FlashMessage::class,
|
||||
'Presets',
|
||||
$msg,
|
||||
$err ? FlashMessage::ERROR : FlashMessage::INFO
|
||||
);
|
||||
/** @var FlashMessageService $flashMessageService */
|
||||
$flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
|
||||
/** @var FlashMessageQueue $defaultFlashMessageQueue */
|
||||
$defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
|
||||
$defaultFlashMessageQueue->enqueue($flashMessage);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
|
||||
*/
|
||||
protected function getBackendUser()
|
||||
{
|
||||
return $GLOBALS['BE_USER'];
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Impexp\Hook;
|
||||
|
||||
/*
|
||||
* 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 TYPO3\CMS\Backend\Controller\BackendController;
|
||||
use TYPO3\CMS\Core\Page\PageRenderer;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* This class adds import export related JavaScript to the backend
|
||||
* @internal this is a internal TYPO3 hook implementation and solely used for EXT:impexp and not part of TYPO3's Core API.
|
||||
*/
|
||||
class BackendControllerHook
|
||||
{
|
||||
/**
|
||||
* Adds ImportExport-specific JavaScript
|
||||
*
|
||||
* @param array $configuration
|
||||
* @param BackendController $backendController
|
||||
*/
|
||||
public function addJavaScript(array $configuration, BackendController $backendController)
|
||||
{
|
||||
/** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */
|
||||
$uriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class);
|
||||
$this->getPageRenderer()->addInlineSetting('ImportExport', 'moduleUrl', (string)$uriBuilder->buildUriFromRoute('xMOD_tximpexp'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return PageRenderer
|
||||
*/
|
||||
protected function getPageRenderer()
|
||||
{
|
||||
return GeneralUtility::makeInstance(PageRenderer::class);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,259 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Impexp\Task;
|
||||
|
||||
/*
|
||||
* 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 TYPO3\CMS\Backend\Utility\BackendUtility;
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Messaging\FlashMessage;
|
||||
use TYPO3\CMS\Core\Messaging\FlashMessageService;
|
||||
use TYPO3\CMS\Core\Resource\Exception;
|
||||
use TYPO3\CMS\Core\Type\Bitmask\Permission;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Taskcenter\Controller\TaskModuleController;
|
||||
use TYPO3\CMS\Taskcenter\TaskInterface;
|
||||
|
||||
/**
|
||||
* This class provides a textarea to save personal notes
|
||||
* @internal this is a internal TYPO3 Backend implementation and solely used for EXT:impexp and not part of TYPO3's Core API.
|
||||
*/
|
||||
class ImportExportTask implements TaskInterface
|
||||
{
|
||||
/**
|
||||
* Back-reference to the calling reports module
|
||||
*
|
||||
* @var TaskModuleController $taskObject
|
||||
*/
|
||||
protected $taskObject;
|
||||
|
||||
/**
|
||||
* URL to task module
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $moduleUrl;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param TaskModuleController $taskObject
|
||||
*/
|
||||
public function __construct(TaskModuleController $taskObject)
|
||||
{
|
||||
/** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */
|
||||
$uriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class);
|
||||
$this->moduleUrl = (string)$uriBuilder->buildUriFromRoute('user_task');
|
||||
$this->taskObject = $taskObject;
|
||||
$this->getLanguageService()->includeLLFile('EXT:impexp/Resources/Private/Language/locallang_csh.xlf');
|
||||
}
|
||||
|
||||
/**
|
||||
* This method renders the report
|
||||
*
|
||||
* @return string The status report as HTML
|
||||
*/
|
||||
public function getTask()
|
||||
{
|
||||
return $this->main();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render an optional additional information for the 1st view in taskcenter.
|
||||
* Empty for this task
|
||||
*
|
||||
* @return string Overview as HTML
|
||||
*/
|
||||
public function getOverview()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Main Task center module
|
||||
*
|
||||
* @return string HTML content.
|
||||
*/
|
||||
public function main()
|
||||
{
|
||||
$content = '';
|
||||
$id = (int)GeneralUtility::_GP('display');
|
||||
/** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */
|
||||
$uriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class);
|
||||
// If a preset is found, it is rendered using an iframe
|
||||
if ($id > 0) {
|
||||
$url = (string)$uriBuilder->buildUriFromRoute(
|
||||
'xMOD_tximpexp',
|
||||
[
|
||||
'tx_impexp[action]' => 'export',
|
||||
'preset[load]' => 1,
|
||||
'preset[select]' => $id,
|
||||
'returnUrl' => $this->moduleUrl
|
||||
]
|
||||
);
|
||||
\TYPO3\CMS\Core\Utility\HttpUtility::redirect($url);
|
||||
} else {
|
||||
// Header
|
||||
$lang = $this->getLanguageService();
|
||||
$content .= $this->taskObject->description($lang->getLL('.alttitle'), $lang->getLL('.description'));
|
||||
$clause = $this->getBackendUser()->getPagePermsClause(Permission::PAGE_SHOW);
|
||||
$usernames = BackendUtility::getUserNames();
|
||||
// Create preset links:
|
||||
$presets = $this->getPresets();
|
||||
// If any presets found
|
||||
if (is_array($presets) && !empty($presets)) {
|
||||
$lines = [];
|
||||
foreach ($presets as $key => $presetCfg) {
|
||||
$configuration = unserialize($presetCfg['preset_data'], ['allowed_classes' => false]);
|
||||
$title = strlen($presetCfg['title']) ? $presetCfg['title'] : '[' . $presetCfg['uid'] . ']';
|
||||
$icon = 'EXT:impexp/Resources/Public/Images/export.gif';
|
||||
$description = [];
|
||||
// Is public?
|
||||
if ($presetCfg['public']) {
|
||||
$description[] = $lang->getLL('task.public') . ': ' . $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:yes');
|
||||
}
|
||||
// Owner
|
||||
$description[] = $lang->getLL('task.owner') . ': '
|
||||
. (
|
||||
$presetCfg['user_uid'] === $GLOBALS['BE_USER']->user['uid']
|
||||
? $lang->getLL('task.own')
|
||||
: '[' . htmlspecialchars($usernames[$presetCfg['user_uid']]['username']) . ']'
|
||||
);
|
||||
// Page & path
|
||||
if ($configuration['pagetree']['id']) {
|
||||
$description[] = $lang->getLL('task.page') . ': ' . $configuration['pagetree']['id'];
|
||||
$description[] = $lang->getLL('task.path') . ': ' . htmlspecialchars(
|
||||
BackendUtility::getRecordPath($configuration['pagetree']['id'], $clause, 20)
|
||||
);
|
||||
} else {
|
||||
$description[] = $lang->getLL('single-record');
|
||||
}
|
||||
// Meta information
|
||||
if ($configuration['meta']['title'] || $configuration['meta']['description'] || $configuration['meta']['notes']) {
|
||||
$metaInformation = '';
|
||||
if ($configuration['meta']['title']) {
|
||||
$metaInformation .= '<strong>' . htmlspecialchars($configuration['meta']['title']) . '</strong><br />';
|
||||
}
|
||||
if ($configuration['meta']['description']) {
|
||||
$metaInformation .= htmlspecialchars($configuration['meta']['description']);
|
||||
}
|
||||
if ($configuration['meta']['notes']) {
|
||||
$metaInformation .= '<br /><br />
|
||||
<strong>' . $lang->getLL('notes') . ': </strong>
|
||||
<em>' . htmlspecialchars($configuration['meta']['notes']) . '</em>';
|
||||
}
|
||||
$description[] = '<br />' . $metaInformation;
|
||||
}
|
||||
// Collect all preset information
|
||||
$lines[$key] = [
|
||||
'uid' => 'impexp' . $key,
|
||||
'icon' => $icon,
|
||||
'title' => $title,
|
||||
'descriptionHtml' => implode('<br />', $description),
|
||||
'link' => (string)$uriBuilder->buildUriFromRoute('user_task') . '&SET[function]=impexp.TYPO3\\CMS\\Impexp\\Task\\ImportExportTask&display=' . $presetCfg['uid']
|
||||
];
|
||||
}
|
||||
// Render preset list
|
||||
$content .= $this->taskObject->renderListMenu($lines);
|
||||
} else {
|
||||
// No presets found
|
||||
$flashMessage = GeneralUtility::makeInstance(
|
||||
FlashMessage::class,
|
||||
$lang->getLL('no-presets'),
|
||||
$lang->getLL('.alttitle'),
|
||||
FlashMessage::NOTICE
|
||||
);
|
||||
/** @var \TYPO3\CMS\Core\Messaging\FlashMessageService $flashMessageService */
|
||||
$flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
|
||||
/** @var \TYPO3\CMS\Core\Messaging\FlashMessageQueue $defaultFlashMessageQueue */
|
||||
$defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
|
||||
$defaultFlashMessageQueue->enqueue($flashMessage);
|
||||
}
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Select presets for this user
|
||||
*
|
||||
* @return array|bool Array of preset records
|
||||
*/
|
||||
protected function getPresets()
|
||||
{
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable('tx_impexp_presets');
|
||||
|
||||
return $queryBuilder->select('*')
|
||||
->from('tx_impexp_presets')
|
||||
->where(
|
||||
$queryBuilder->expr()->orX(
|
||||
$queryBuilder->expr()->gt(
|
||||
'public',
|
||||
$queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)
|
||||
),
|
||||
$queryBuilder->expr()->eq(
|
||||
'user_uid',
|
||||
$queryBuilder->createNamedParameter($this->getBackendUser()->user['uid'], \PDO::PARAM_INT)
|
||||
)
|
||||
)
|
||||
)
|
||||
->orderBy('item_uid', 'DESC')
|
||||
->addOrderBy('title')
|
||||
->execute()
|
||||
->fetchAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a \TYPO3\CMS\Core\Resource\Folder object for saving export files
|
||||
* to the server and is also used for uploading import files.
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
* @return \TYPO3\CMS\Core\Resource\Folder|null
|
||||
*/
|
||||
protected function getDefaultImportExportFolder()
|
||||
{
|
||||
$defaultImportExportFolder = null;
|
||||
|
||||
$defaultTemporaryFolder = $this->getBackendUser()->getDefaultUploadTemporaryFolder();
|
||||
if ($defaultTemporaryFolder !== null) {
|
||||
$importExportFolderName = 'importexport';
|
||||
$createFolder = !$defaultTemporaryFolder->hasFolder($importExportFolderName);
|
||||
if ($createFolder === true) {
|
||||
try {
|
||||
$defaultImportExportFolder = $defaultTemporaryFolder->createFolder($importExportFolderName);
|
||||
} catch (Exception $folderAccessException) {
|
||||
}
|
||||
} else {
|
||||
$defaultImportExportFolder = $defaultTemporaryFolder->getSubfolder($importExportFolderName);
|
||||
}
|
||||
}
|
||||
|
||||
return $defaultImportExportFolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
|
||||
*/
|
||||
protected function getBackendUser()
|
||||
{
|
||||
return $GLOBALS['BE_USER'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getLanguageService()
|
||||
{
|
||||
return $GLOBALS['LANG'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Impexp\Utility;
|
||||
|
||||
/*
|
||||
* 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 TYPO3\CMS\Core\Log\LogManager;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\SignalSlot\Dispatcher;
|
||||
use TYPO3\CMS\Impexp\Import;
|
||||
|
||||
/**
|
||||
* Utility for import / export
|
||||
* Can be used for API access for simple importing of files
|
||||
* @internal
|
||||
*/
|
||||
class ImportExportUtility
|
||||
{
|
||||
/**
|
||||
* Import a T3D file directly
|
||||
*
|
||||
* @param string $file The full absolute path to the file
|
||||
* @param int $pid The pid under which the t3d file should be imported
|
||||
* @throws \ErrorException
|
||||
* @throws \InvalidArgumentException
|
||||
* @return int
|
||||
*/
|
||||
public function importT3DFile($file, $pid)
|
||||
{
|
||||
if (!is_string($file)) {
|
||||
throw new \InvalidArgumentException('Input parameter $file has to be of type string', 1377625645);
|
||||
}
|
||||
if (!is_int($pid)) {
|
||||
throw new \InvalidArgumentException('Input parameter $int has to be of type integer', 1377625646);
|
||||
}
|
||||
/** @var Import $import */
|
||||
$import = GeneralUtility::makeInstance(Import::class);
|
||||
$import->init();
|
||||
|
||||
$this->emitAfterImportExportInitialisationSignal($import);
|
||||
|
||||
$importResponse = 0;
|
||||
if ($file && @is_file($file)) {
|
||||
if ($import->loadFile($file, 1)) {
|
||||
// Import to root page:
|
||||
$import->importData($pid);
|
||||
// Get id of first created page:
|
||||
$newPages = $import->import_mapId['pages'];
|
||||
$importResponse = (int)reset($newPages);
|
||||
}
|
||||
}
|
||||
|
||||
// Check for errors during the import process:
|
||||
$errors = $import->printErrorLog();
|
||||
if ($errors !== '') {
|
||||
$logger = GeneralUtility::makeInstance(LogManager::class)->getLogger(__CLASS__);
|
||||
$logger->warning($errors);
|
||||
|
||||
if (!$importResponse) {
|
||||
throw new \ErrorException('No page records imported', 1377625537);
|
||||
}
|
||||
}
|
||||
return $importResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SignalSlot dispatcher
|
||||
*
|
||||
* @return Dispatcher
|
||||
*/
|
||||
protected function getSignalSlotDispatcher()
|
||||
{
|
||||
return GeneralUtility::makeInstance(Dispatcher::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits a signal after initialization
|
||||
*
|
||||
* @param Import $import
|
||||
* @throws \TYPO3\CMS\Extbase\SignalSlot\Exception\InvalidSlotException
|
||||
* @throws \TYPO3\CMS\Extbase\SignalSlot\Exception\InvalidSlotReturnException
|
||||
*/
|
||||
protected function emitAfterImportExportInitialisationSignal(Import $import)
|
||||
{
|
||||
$this->getSignalSlotDispatcher()->dispatch(__CLASS__, 'afterImportExportInitialisation', [$import]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Impexp\View;
|
||||
|
||||
/*
|
||||
* 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 TYPO3\CMS\Backend\Tree\View\BrowseTreeView;
|
||||
use TYPO3\CMS\Backend\Utility\BackendUtility;
|
||||
use TYPO3\CMS\Core\Imaging\Icon;
|
||||
use TYPO3\CMS\Core\Imaging\IconFactory;
|
||||
use TYPO3\CMS\Core\Type\Bitmask\Permission;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Extension of the page tree class. Used to get the tree of pages to export.
|
||||
* @internal
|
||||
*/
|
||||
class ExportPageTreeView extends BrowseTreeView
|
||||
{
|
||||
/**
|
||||
* Initialization
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapping title from page tree.
|
||||
*
|
||||
* @param string $title Title to wrap
|
||||
* @param string $row Item record
|
||||
* @param int $bank Bank pointer (which mount point number)
|
||||
* @return string Wrapped title
|
||||
* @internal
|
||||
*/
|
||||
public function wrapTitle($title, $row, $bank = 0)
|
||||
{
|
||||
return trim($title) === '' ? '<em>[' . htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.no_title')) . ']</em>' : htmlspecialchars($title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapping Plus/Minus icon
|
||||
*
|
||||
* @param string $icon Icon HTML
|
||||
* @param mixed $cmd (See parent class)
|
||||
* @param mixed $bMark (See parent class)
|
||||
* @param bool $isOpen
|
||||
* @return string Icon HTML
|
||||
*/
|
||||
public function PM_ATagWrap($icon, $cmd, $bMark = '', $isOpen = false)
|
||||
{
|
||||
return $icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapping Icon
|
||||
*
|
||||
* @param string $icon Icon HTML
|
||||
* @param array $row Record row (page)
|
||||
* @return string Icon HTML
|
||||
*/
|
||||
public function wrapIcon($icon, $row)
|
||||
{
|
||||
return $icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tree rendering
|
||||
*
|
||||
* @param int $pid PID value
|
||||
* @param string $clause Additional where clause
|
||||
* @return array Array of tree elements
|
||||
*/
|
||||
public function ext_tree($pid, $clause = '')
|
||||
{
|
||||
// Initialize:
|
||||
$this->init(' AND ' . $this->BE_USER->getPagePermsClause(Permission::PAGE_SHOW) . $clause);
|
||||
// Get stored tree structure:
|
||||
$this->stored = unserialize($this->BE_USER->uc['browseTrees']['browsePages'], ['allowed_classes' => false]);
|
||||
$treeArr = [];
|
||||
$idx = 0;
|
||||
// Set first:
|
||||
$this->bank = $idx;
|
||||
$isOpen = $this->stored[$idx][$pid] || $this->expandFirst;
|
||||
// save ids
|
||||
$curIds = $this->ids;
|
||||
$this->reset();
|
||||
$this->ids = $curIds;
|
||||
if ($pid > 0) {
|
||||
$rootRec = BackendUtility::getRecordWSOL('pages', $pid);
|
||||
$iconFactory = GeneralUtility::makeInstance(IconFactory::class);
|
||||
$firstHtml = $iconFactory->getIconForRecord('pages', $rootRec, Icon::SIZE_SMALL)->render();
|
||||
} else {
|
||||
$rootRec = [
|
||||
'title' => $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'],
|
||||
'uid' => 0
|
||||
];
|
||||
$firstHtml = $this->getRootIcon($rootRec);
|
||||
}
|
||||
$this->tree[] = ['HTML' => $firstHtml, 'row' => $rootRec, 'hasSub' => $isOpen];
|
||||
if ($isOpen) {
|
||||
// Set depth:
|
||||
if ($this->addSelfId) {
|
||||
$this->ids[] = $pid;
|
||||
}
|
||||
$this->getTree($pid, 999, '');
|
||||
$idH = [];
|
||||
$idH[$pid]['uid'] = $pid;
|
||||
if (!empty($this->buffer_idH)) {
|
||||
$idH[$pid]['subrow'] = $this->buffer_idH;
|
||||
}
|
||||
$this->buffer_idH = $idH;
|
||||
}
|
||||
// Add tree:
|
||||
return array_merge($treeArr, $this->tree);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user