Skip to content

Commit

Permalink
Merge pull request #1 from ayacoo/v2
Browse files Browse the repository at this point in the history
V2
  • Loading branch information
ayacoo authored Dec 28, 2022
2 parents afbbcc9 + ab352a4 commit db4545d
Show file tree
Hide file tree
Showing 15 changed files with 528 additions and 18 deletions.
102 changes: 102 additions & 0 deletions Classes/Command/UpdateMetadataCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<?php

declare(strict_types=1);

namespace Ayacoo\AyacooSoundcloud\Command;

use Ayacoo\AyacooSoundcloud\Domain\Repository\FileRepository;
use Ayacoo\AyacooSoundcloud\Helper\SoundcloudHelper;
use Symfony\Component\Console\Command\Command;
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\Environment;
use TYPO3\CMS\Core\Resource\File;
use TYPO3\CMS\Core\Resource\Index\MetaDataRepository;
use TYPO3\CMS\Core\Resource\OnlineMedia\Helpers\AbstractOnlineMediaHelper;
use TYPO3\CMS\Core\Resource\ProcessedFileRepository;
use TYPO3\CMS\Core\Resource\ResourceFactory;
use TYPO3\CMS\Core\Utility\GeneralUtility;

class UpdateMetadataCommand extends Command
{
protected function configure(): void
{
$this->setDescription('Updates the Soundcloud metadata');
$this->addOption(
'limit',
null,
InputOption::VALUE_OPTIONAL,
'Defines the number of Soundcloud audios to be checked',
10
);
}

public function __construct(
protected FileRepository $fileRepository,
protected MetaDataRepository $metadataRepository,
protected ResourceFactory $resourceFactory,
protected ProcessedFileRepository $processedFileRepository
)
{
parent::__construct();
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$limit = (int)($input->getOption('limit') ?? 10);

$soundcloudHelper = GeneralUtility::makeInstance(SoundcloudHelper::class, 'soundcloud');

$audios = $this->fileRepository->getVideosByFileExtension('soundcloud', $limit);
foreach ($audios as $audio) {
$file = $this->resourceFactory->getFileObject($audio['uid']);
$metaData = $soundcloudHelper->getMetaData($file);
if (!empty($metaData)) {
$newMetaData = [
'width' => (int)$metaData['width'],
'height' => (int)$metaData['height'],
'soundcloud_html' => $metaData['soundcloud_html'],
'soundcloud_author_url' => $metaData['soundcloud_author_url'],
'soundcloud_thumbnail_url' => $metaData['soundcloud_thumbnail_url'],
];
if (isset($metaData['title'])) {
$newMetaData['title'] = $metaData['title'];
}
if (isset($metaData['author'])) {
$newMetaData['author'] = $metaData['author'];
}
$this->metadataRepository->update($file->getUid(), $newMetaData);
$this->handlePreviewImage($soundcloudHelper, $file);
$io->success($file->getProperty('title') . '(UID: ' . $file->getUid() . ') was processed');
}
}

return Command::SUCCESS;
}


protected function handlePreviewImage(AbstractOnlineMediaHelper $onlineMediaHelper, File $file): void
{
$processedFiles = $this->processedFileRepository->findAllByOriginalFile($file);
foreach ($processedFiles as $processedFile) {
$processedFile->delete();
}

$videoId = $onlineMediaHelper->getOnlineMediaId($file);
$temporaryFileName = $this->getTempFolderPath() . $file->getExtension() . '_' . md5($videoId) . '.jpg';
@unlink($temporaryFileName);
$onlineMediaHelper->getPreviewImage($file);
}

protected function getTempFolderPath(): string
{
$path = Environment::getPublicPath() . '/typo3temp/assets/online_media/';
if (!is_dir($path)) {
GeneralUtility::mkdir_deep($path);
}
return $path;
}
}
89 changes: 89 additions & 0 deletions Classes/Controller/OnlineMediaUpdateController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<?php

declare(strict_types=1);

namespace Ayacoo\AyacooSoundcloud\Controller;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Core\Core\Environment;
use TYPO3\CMS\Core\Http\JsonResponse;
use TYPO3\CMS\Core\Resource\Exception\FileDoesNotExistException;
use TYPO3\CMS\Core\Resource\File;
use TYPO3\CMS\Core\Resource\Index\MetaDataRepository;
use TYPO3\CMS\Core\Resource\OnlineMedia\Helpers\OnlineMediaHelperRegistry;
use TYPO3\CMS\Core\Resource\ProcessedFileRepository;
use TYPO3\CMS\Core\Resource\ResourceFactory;
use TYPO3\CMS\Core\Utility\GeneralUtility;

class OnlineMediaUpdateController
{
/**
* AJAX endpoint for storing the URL as a sys_file record
*
* @param ServerRequestInterface $request
* @return ResponseInterface
* @throws FileDoesNotExistException
*/
public function updateAction(ServerRequestInterface $request): ResponseInterface
{
if ($request->getMethod() !== 'POST') {
return new JsonResponse(['Please use a POST request'], 500);
}

$parsedBody = $request->getParsedBody();
$uid = $parsedBody['uid'];
$resourceFactory = GeneralUtility::makeInstance(ResourceFactory::class);
$file = $resourceFactory->getFileObject($uid);

$onlineMediaViewHelper = GeneralUtility::makeInstance(OnlineMediaHelperRegistry::class)
->getOnlineMediaHelper($file);

// remove online media temp image
$videoId = $onlineMediaViewHelper->getOnlineMediaId($file);
$temporaryFileName = $this->getTempFolderPath() . $file->getExtension() . '_' . md5($videoId) . '.jpg';
@unlink($temporaryFileName);
$previewPath = $onlineMediaViewHelper->getPreviewImage($file);

$this->updateMetaData($file, $onlineMediaViewHelper->getMetaData($file));
$this->removeProcessedFiles($file);

return new JsonResponse(['path' => $previewPath]);
}

protected function getTempFolderPath(): string
{
$path = Environment::getPublicPath() . '/typo3temp/assets/online_media/';
if (!is_dir($path)) {
GeneralUtility::mkdir_deep($path);
}
return $path;
}

protected function removeProcessedFiles(File $file): void
{
$processedFileRepository = GeneralUtility::makeInstance(ProcessedFileRepository::class);
$processedFiles = $processedFileRepository->findAllByOriginalFile($file);

foreach ($processedFiles as $processedFile) {
$processedFile->delete();
}
}

/**
* We need to get an update on the metadata
*
* @param File $file
* @param array $metaData
* @return void
*/
protected function updateMetaData(File $file, array $metaData): void
{
$metadataRepository = GeneralUtility::makeInstance(MetaDataRepository::class);
$metadataRepository->update($file->getUid(), [
'width' => (int)$metaData['width'],
'height' => (int)$metaData['height'],
'soundcloud_thumbnail_url' => $metaData['soundcloud_thumbnail_url']
]);
}
}
55 changes: 55 additions & 0 deletions Classes/Domain/Repository/FileRepository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

declare(strict_types=1);

namespace Ayacoo\AyacooSoundcloud\Domain\Repository;

use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
use TYPO3\CMS\Core\Utility\GeneralUtility;

class FileRepository
{
private const SYS_FILE_TABLE = 'sys_file';

public function getVideosByFileExtension(string $extension, int $limit = 0): array
{
$queryBuilder = $this->getQueryBuilder(self::SYS_FILE_TABLE);

$whereConstraints = [];
$whereConstraints[] = $queryBuilder->expr()->eq(
'extension',
$queryBuilder->createNamedParameter(strtolower($extension))
);
$whereConstraints[] = $queryBuilder->expr()->eq(
'missing',
$queryBuilder->createNamedParameter(0, Connection::PARAM_INT)
);

$statement = $queryBuilder
->select('*')
->addSelectLiteral('RAND() AS randomnumber')
->from(self::SYS_FILE_TABLE)
->where(...$whereConstraints)
->orderBy('randomnumber');

if ($limit > 0) {
$statement->setMaxResults($limit);
}

return $queryBuilder->executeQuery()->fetchAllAssociative();
}

/**
* @param string $tableName
* @return QueryBuilder
*/
protected function getQueryBuilder(string $tableName = ''): QueryBuilder
{
$connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
$connection = $connectionPool->getConnectionForTable($tableName);

return $connection->createQueryBuilder();
}
}
62 changes: 62 additions & 0 deletions Classes/EventListener/FileListEventListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

declare(strict_types=1);

namespace Ayacoo\AyacooSoundcloud\EventListener;

use TYPO3\CMS\Core\Imaging\Icon;
use TYPO3\CMS\Core\Imaging\IconFactory;
use TYPO3\CMS\Core\Localization\LanguageService;
use TYPO3\CMS\Core\Page\PageRenderer;
use TYPO3\CMS\Core\Resource\File;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Filelist\Event\ProcessFileListActionsEvent;

final class FileListEventListener
{
protected IconFactory $iconFactory;

public function __construct()
{
$this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
}

public function __invoke(ProcessFileListActionsEvent $event): void
{
$actionItems = $event->getActionItems();

$pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
$pageRenderer->loadJavaScriptModule('@ayacoosoundcloud/updater.js');
$pageRenderer->addInlineLanguageLabelFile('EXT:ayacoo_soundcloud/Resources/Private/Language/locallang.xlf');

$fileOrFolderObject = $event->getResource();
if ($fileOrFolderObject instanceof File) {
$fileProperties = $fileOrFolderObject->getProperties();
$extension = $fileProperties['extension'] ?? '';

$registeredHelpers = $GLOBALS['TYPO3_CONF_VARS']['SYS']['fal']['onlineMediaHelpers'] ?? [];
if ($extension !== 'soundcloud' || !array_key_exists($extension, $registeredHelpers)) {
return;
}

$actionItems['soundcloud'] = '<a href="#" class="btn btn-default t3js-filelist-ayacoosoundcloud'
. '" data-filename="' . htmlspecialchars($fileOrFolderObject->getName())
. '" data-file-uid="' . $fileProperties['uid']
. '" title="' . $this->getLanguageService()->getLL('ayacoo_soundcloud.update') . '">'
. $this->iconFactory->getIcon('actions-refresh', Icon::SIZE_SMALL)->render() . '</a>';
}

$event->setActionItems($actionItems);
}

/**
* @return LanguageService
*/
protected function getLanguageService(): LanguageService
{
$languageService = $GLOBALS['LANG'];
$languageService->includeLLFile('EXT:ayacoo_soundcloud/Resources/Private/Language/locallang.xlf');

return $languageService;
}
}
1 change: 0 additions & 1 deletion Classes/Helper/SoundcloudHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
use TYPO3\CMS\Core\Resource\File;
use TYPO3\CMS\Core\Resource\Folder;
use TYPO3\CMS\Core\Resource\OnlineMedia\Helpers\AbstractOEmbedHelper;
use TYPO3\CMS\Core\Utility\DebugUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;

/**
Expand Down
61 changes: 61 additions & 0 deletions Classes/Rendering/SoundcloudPreviewRenderer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php
declare(strict_types=1);

namespace Ayacoo\AyacooSoundcloud\Rendering;

use TYPO3\CMS\Backend\Preview\StandardContentPreviewRenderer;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Backend\View\BackendLayout\Grid\GridColumnItem;
use TYPO3\CMS\Core\Resource\ProcessedFileRepository;
use TYPO3\CMS\Core\Utility\GeneralUtility;

/**
* Class SoundcloudPreviewRenderer
*/
class SoundcloudPreviewRenderer extends StandardContentPreviewRenderer
{
public function renderPageModulePreviewContent(GridColumnItem $item): string
{
$content = '';
$row = $item->getRecord();
if ($row['bodytext']) {
$content = $this->linkEditContent($this->renderText($row['bodytext']), $row);
}

if ($row['assets']) {
// $processedFileRepository = GeneralUtility::makeInstance(ProcessedFileRepository::class);

$content .= '<br/><br/><h6><strong>Assets</strong></h6>';
$fileReferences = BackendUtility::resolveFileReferences('tt_content', 'assets', $row);
foreach ($fileReferences as $fileReferenceObject) {
// Do not show previews of hidden references
if ($fileReferenceObject->getProperty('hidden')) {
continue;
}
$fileObject = $fileReferenceObject->getOriginalFile();
if (!$fileObject->isMissing()) {
$content .= '<a href="' . $fileObject->getPublicUrl() . '" target="_blank">';
$content .= htmlspecialchars($fileObject->getProperty('title'));

// use latest processed file (64px)
/**
* $processedFiles = $processedFileRepository->findAllByOriginalFile($fileObject);
* foreach ($processedFiles as $processedFile) {
* $content .= '<br/><img src="' . $processedFile->getPublicUrl() . '" />';
* break;
* }
*/

// use original thumbnail and control the size
$image = $fileObject->getMetaData()->offsetGet('soundcloud_thumbnail_url') ?? '';
$content .= '<br/><img style="height: 150px;" src="' . htmlspecialchars($image) . '" />';

$content .= '</a>';
$content .= '<hr/>';
}
}
}

return $content;
}
}
11 changes: 11 additions & 0 deletions Configuration/Backend/AjaxRoutes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

use Ayacoo\AyacooSoundcloud\Controller\OnlineMediaUpdateController;

return [
// Save a newly added online media
'ayacoo_soundcloud_online_media_updater' => [
'path' => '/ayacoo-soundcloud/update',
'target' => OnlineMediaUpdateController::class . '::updateAction',
],
];
Loading

0 comments on commit db4545d

Please sign in to comment.