Skip to content

Instantly share code, notes, and snippets.

@lorenzulrich
Last active November 24, 2017 18:49
Show Gist options
  • Save lorenzulrich/dc66044f4787b1563fb1cf81abae1e2d to your computer and use it in GitHub Desktop.
Save lorenzulrich/dc66044f4787b1563fb1cf81abae1e2d to your computer and use it in GitHub Desktop.
Command controller for TYPO3 7 LTS+ to migrate CType Media containing YouTube and Vimeo videos to CType textmedia using file references
if (TYPO3_MODE === 'BE') {
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['extbase']['commandControllers'][] = \Visol\Foobar\Command\MediaContentMigrationCommandController::class;
}
<?php
namespace Visol\Foobar\Command;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
use TYPO3\CMS\Core\DataHandling\DataHandler;
use TYPO3\CMS\Core\Resource\File;
use TYPO3\CMS\Core\Resource\OnlineMedia\Helpers\OnlineMediaHelperRegistry;
use TYPO3\CMS\Core\Resource\ResourceFactory;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Mvc\Controller\CommandController;
/**
*/
class MediaContentMigrationCommandController extends CommandController
{
/**
* @var bool
*/
protected $requestAdminPermissions = true;
/**
* @cli
*/
public function migrateCommand()
{
/** @var QueryBuilder $queryBuilder */
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tt_content');
$queryBuilder->getRestrictions()->add(
GeneralUtility::makeInstance(DeletedRestriction::class)
);
$mediaContentElements = $queryBuilder
->select('*')
->from('tt_content')
->where($queryBuilder->expr()->eq('CType', $queryBuilder->quote('media')))
->orderBy('uid')
->execute()
->fetchAll();
$this->outputLine(vsprintf('%s Media content elements in database.', [count($mediaContentElements)]));
$this->outputLine('========================================');
$numberOfYoutubeElements = 0;
$numberOfVimeoElements = 0;
foreach ($mediaContentElements as $key => $mediaContentElement) {
if (strpos($mediaContentElement['pi_flexform'], 'youtu')) {
// youtu because it can be youtube.com or youtu.be
$numberOfYoutubeElements++;
} elseif (strpos($mediaContentElement['pi_flexform'], 'vimeo')) {
$numberOfVimeoElements++;
} else {
unset($mediaContentElements[$key]);
}
}
$this->outputLine(vsprintf('%s YouTube content elements in database.', [$numberOfYoutubeElements]));
$this->outputLine(vsprintf('%s Vimeo content elements in database.', [$numberOfVimeoElements]));
foreach ($mediaContentElements as $mediaContentElement) {
$flexformContent = GeneralUtility::xml2array($mediaContentElement['pi_flexform']);
if (isset($flexformContent['data']) && isset($flexformContent['data']['sVideo']) && isset($flexformContent['data']['sVideo']['lDEF']) && isset($flexformContent['data']['sVideo']['lDEF']['mmFile']) && isset($flexformContent['data']['sVideo']['lDEF']['mmFile']['vDEF'])) {
$url = trim($flexformContent['data']['sVideo']['lDEF']['mmFile']['vDEF']);
$file = $this->addMediaFromUrl($url);
if ($file instanceof File) {
$data = [];
$data['sys_file_reference']['NEW' . uniqid(6)] = [
'uid_local' => $file->getUid(),
'table_local' => 'sys_file',
'uid_foreign' => $mediaContentElement['uid'],
'tablenames' => 'tt_content',
'fieldname' => 'assets',
'pid' => $mediaContentElement['pid'],
'sys_language_uid' => $mediaContentElement['sys_language_uid']
];
/** @var DataHandler $dataHandler */
$dataHandler = GeneralUtility::makeInstance(DataHandler::class);
$dataHandler->start($data, []);
$dataHandler->admin = true;
$dataHandler->process_datamap();
if (empty($dataHandler->errorLog)) {
// Relation was added, so we update the element
$data = [];
$data['tt_content'][$mediaContentElement['uid']] = [
'CType' => 'textmedia',
'pi_flexform' => [],
];
$dataHandler = GeneralUtility::makeInstance(DataHandler::class);
$dataHandler->start($data, []);
$dataHandler->admin = true;
$dataHandler->process_datamap();
if (empty($dataHandler->errorLog)) {
$this->outputFormatted('Media Content Element with uid %s (Media URL: %s, PID: %s) was successfully migrated to Text & Media element.', [$mediaContentElement['uid'], $url, $mediaContentElement['pid']]);
} else {
$this->outputFormatted('Media Content Element with uid %s (Media URL: %s, PID: %s) could not be migrated. Content could not be updated.', [$mediaContentElement['uid'], $url, $mediaContentElement['pid']]);
}
} else {
$this->outputFormatted('Media Content Element with uid %s (Media URL: %s, PID: %s) could not be migrated. File reference could not be added.', [$mediaContentElement['uid'], $url, $mediaContentElement['pid']]);
}
} else {
$this->outputFormatted('Media Content Element with uid %s (Media URL: %s, PID: %s) could not be migrated. No file could be created for given URL.', [$mediaContentElement['uid'], $url, $mediaContentElement['pid']]);
}
}
}
}
/**
* @param string $url
* @param string $targetFolderIdentifier
* @param string[] $allowedExtensions
* @return File|NULL
*/
protected function addMediaFromUrl($url, $targetFolderIdentifier = '1:/user_upload/', array $allowedExtensions = ['youtube', 'vimeo'])
{
$targetFolder = null;
if ($targetFolderIdentifier) {
try {
$targetFolder = ResourceFactory::getInstance()->getFolderObjectFromCombinedIdentifier($targetFolderIdentifier);
} catch (\Exception $e) {
$targetFolder = null;
}
}
if ($targetFolder === null) {
$targetFolder = $this->getBackendUser()->getDefaultUploadFolder();
}
return OnlineMediaHelperRegistry::getInstance()->transformUrlToFile($url, $targetFolder, $allowedExtensions);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment