Skip to content

Commit

Permalink
Init commit
Browse files Browse the repository at this point in the history
  • Loading branch information
ayacoo committed Dec 6, 2022
1 parent 12e1e41 commit 0cb1788
Show file tree
Hide file tree
Showing 9 changed files with 377 additions and 1 deletion.
134 changes: 134 additions & 0 deletions Classes/Helper/SoundcloudHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
<?php

declare(strict_types=1);

namespace Ayacoo\AyacooSoundcloud\Helper;

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;

/**
* Soundcloud helper class
*/
class SoundcloudHelper extends AbstractOEmbedHelper
{
private const SOUNDCLOUD_URL = 'https://soundcloud.com/';

protected function getOEmbedUrl($mediaId, $format = 'json')
{
return trim(sprintf(
self::SOUNDCLOUD_URL . 'oembed?format=' . $format . '&url=' . self::SOUNDCLOUD_URL . '%s',
$mediaId
));
}

public function transformUrlToFile($url, Folder $targetFolder)
{
$audioId = null;
// Try to get the Soundcloud code from given url.
// https://www.soundlcoud.com/<username>/<path_segment>?parameter # Audio detail URL
if (preg_match('%(?:.*)soundcloud\.com\/([a-z.\-_0-9]*)\/([a-z.\-_0-9]*)%i', $url, $match)) {
$audioId = $match[1] . '/'. $match[2];
}
if (empty($audioId)) {
return null;
}

return $this->transformMediaIdToFile($audioId, $targetFolder, $this->extension);
}

/**
* Transform mediaId to File
*
* We override the abstract function so that we can integrate our own handling for the title field
*
* @param string $mediaId
* @param Folder $targetFolder
* @param string $fileExtension
* @return File
*/
protected function transformMediaIdToFile($mediaId, Folder $targetFolder, $fileExtension)
{
$file = $this->findExistingFileByOnlineMediaId($mediaId, $targetFolder, $fileExtension);
if ($file === null) {
$fileName = $mediaId . '.' . $fileExtension;

$oEmbed = $this->getOEmbedData($mediaId);
if (!empty($oEmbed['title'])) {
$title = $this->handleSoundcloudTitle($oEmbed['title']);
if (!empty($title)) {
$fileName = $title . '.' . $fileExtension;
}
}
$file = $this->createNewFile($targetFolder, $fileName, $mediaId);
}
return $file;
}

public function getPublicUrl(File $file, $relativeToCurrentScript = false)
{
// @deprecated $relativeToCurrentScript since v11, will be removed in TYPO3 v12.0
$audioId = $this->getOnlineMediaId($file);

return sprintf(self::SOUNDCLOUD_URL . '%s', $audioId);
}

public function getPreviewImage(File $file)
{
$properties = $file->getProperties();
$previewImageUrl = $properties['soundcloud_thumbnail_url'] ?? '';

$audioId = $this->getOnlineMediaId($file);
$temporaryFileName = $this->getTempFolderPath() . 'soundcloud_' . md5($audioId) . '.jpg';

if (!empty($previewImageUrl)) {
$previewImage = GeneralUtility::getUrl($previewImageUrl);
file_put_contents($temporaryFileName, $previewImage);
GeneralUtility::fixPermissions($temporaryFileName);
return $temporaryFileName;
}

return '';
}

/**
* Get meta data for OnlineMedia item
* Using the meta data from oEmbed
*
* @param File $file
* @return array with metadata
*/
public function getMetaData(File $file)
{
$metaData = [];

$oEmbed = $this->getOEmbedData($this->getOnlineMediaId($file));
if ($oEmbed) {
$metaData['width'] = (int)$oEmbed['width'];
// We only get the value "100%" from the oEmbed query
// The 225 pixels come from the 16:9 format at 400 pixels
$metaData['height'] = 225;
if (empty($file->getProperty('title'))) {
$metaData['title'] = $this->handleSoundcloudTitle($oEmbed['title']);
}
$metaData['author'] = $oEmbed['author_name'];
$metaData['soundcloud_html'] = $oEmbed['html'];
$metaData['soundcloud_thumbnail_url'] = $oEmbed['thumbnail_url'];
$metaData['soundcloud_author_url'] = $oEmbed['author_url'];
}

return $metaData;
}

/**
* @param string $title
* @return string
*/
protected function handleSoundcloudTitle(string $title): string
{
return trim(mb_substr(strip_tags($title), 0, 255));
}
}
76 changes: 76 additions & 0 deletions Classes/Rendering/SoundcloudRenderer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

declare(strict_types=1);

namespace Ayacoo\AyacooSoundcloud\Rendering;

use TYPO3\CMS\Core\Resource\File;
use TYPO3\CMS\Core\Resource\FileInterface;
use TYPO3\CMS\Core\Resource\FileReference;
use TYPO3\CMS\Core\Resource\OnlineMedia\Helpers\OnlineMediaHelperInterface;
use TYPO3\CMS\Core\Resource\OnlineMedia\Helpers\OnlineMediaHelperRegistry;
use TYPO3\CMS\Core\Resource\Rendering\FileRendererInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;

/**
* Soundcloud renderer class
*/
class SoundcloudRenderer implements FileRendererInterface
{
/**
* @var OnlineMediaHelperInterface|false
*/
protected $onlineMediaHelper;

/**
* Returns the priority of the renderer
* This way it is possible to define/overrule a renderer
* for a specific file type/context.
* For example create a video renderer for a certain storage/driver type.
* Should be between 1 and 100, 100 is more important than 1
*
* @return int
*/
public function getPriority()
{
return 1;
}

/**
* Check if given File(Reference) can be rendered
*
* @param FileInterface $file File of FileReference to render
* @return bool
*/
public function canRender(FileInterface $file)
{
return ($file->getMimeType() === 'audio/soundcloud' || $file->getExtension() === 'soundcloud') && $this->getOnlineMediaHelper($file) !== false;
}

public function render(FileInterface $file, $width, $height, array $options = [], $usedPathsRelativeToCurrentScript = false)
{
return $file->getProperty('soundcloud_html') ?? '';
}

/**
* Get online media helper
*
* @param FileInterface $file
* @return false|OnlineMediaHelperInterface
*/
protected function getOnlineMediaHelper(FileInterface $file)
{
if ($this->onlineMediaHelper === null) {
$orgFile = $file;
if ($orgFile instanceof FileReference) {
$orgFile = $orgFile->getOriginalFile();
}
if ($orgFile instanceof File) {
$this->onlineMediaHelper = GeneralUtility::makeInstance(OnlineMediaHelperRegistry::class)->getOnlineMediaHelper($orgFile);
} else {
$this->onlineMediaHelper = false;
}
}
return $this->onlineMediaHelper;
}
}
7 changes: 7 additions & 0 deletions Configuration/Icons.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php
return [
'mimetypes-media-image-soundcloud' => [
'provider' => \TYPO3\CMS\Core\Imaging\IconProvider\SvgIconProvider::class,
'source' => 'EXT:ayacoo-soundcloud/Resources/Public/Icons/soundcloud.svg',
],
];
72 changes: 71 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,71 @@
# ayacoo-soundcloud
# TYPO3 Extension ayacoo-soundcloud

## 1 Features

* Soundcloud audios can be created as a file in the TYPO3 file list
* Soundcloud audios can be used and output with the text with media element

## 2 Usage

### 2.1 Installation

#### Installation using Composer

The recommended way to install the extension is using Composer.

Run the following command within your [Composer][1] based TYPO3 project:

```
composer require ayacoo/ayacoo-soundcloud
```

### 2.2 Hints

#### Output

For the output, the HTML is used directly from [Soundcloud][4].

#### SQL changes

In order not to have to access the oEmbed interface permanently, four fields are added to the sys_file_metadata table

## 3 Administration corner

### 3.1 Versions and support

| AyacooSoundcloud | TYPO3 | PHP | Support / Development |
|------------------|-------------| ----------|---------------------------------------- |
| 1.x | 11.x | 7.4 - 8.0 | features, bugfixes, security updates |

### 3.2 Release Management

ayacoo-soundcloud uses [**semantic versioning**][2], which means, that

* **bugfix updates** (e.g. 1.0.0 => 1.0.1) just includes small bugfixes or security relevant stuff without breaking
changes,
* **minor updates** (e.g. 1.0.0 => 1.1.0) includes new features and smaller tasks without breaking changes,
* and **major updates** (e.g. 1.0.0 => 2.0.0) breaking changes which can be refactorings, features or bugfixes.

### 3.3 Contribution

**Pull Requests** are gladly welcome! Nevertheless please don't forget to add an issue and connect it to your pull
requests. This
is very helpful to understand what kind of issue the **PR** is going to solve.

**Bugfixes**: Please describe what kind of bug your fix solve and give us feedback how to reproduce the issue. We're
going
to accept only bugfixes if we can reproduce the issue.

## 4 Thanks / Notices

Special thanks to Georg Ringer and his [news][3] extension. A good template to build a TYPO3 extension. Here, for
example, the structure of README.md is used.


[1]: https://getcomposer.org/

[2]: https://semver.org/

[3]: https://github.com/georgringer/news

[4]: https://developers.soundcloud.com/docs/oembed
1 change: 1 addition & 0 deletions Resources/Public/Icons/soundcloud.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 35 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"name": "ayacoo/ayacoo-soundcloud",
"version": "1.0.0",
"type": "typo3-cms-extension",
"description": "Provides a Soundcloud online media helper",
"homepage": "https://www.ayacoo.de",
"authors": [
{
"name": "Guido Schmechel",
"role": "Developer"
}
],
"license": [
"GPL-2.0-or-later"
],
"require": {
"typo3/cms-core": "^11.5.0"
},
"autoload": {
"psr-4": {
"Ayacoo\\AyacooSoundcloud\\": "Classes/"
}
},
"config": {
"vendor-dir": ".Build/vendor",
"bin-dir": ".Build/bin"
},
"extra": {
"typo3/cms": {
"extension-key": "ayacoo-soundcloud",
"cms-package-dir": "{$vendor-dir}/typo3/cms",
"web-dir": ".Build/Web"
}
}
}
21 changes: 21 additions & 0 deletions ext_emconf.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

$EM_CONF[$_EXTKEY] = [
'title' => 'Soundcloud online media helper',
'category' => 'plugin',
'author' => 'Guido Schmechel',
'author_email' => 'info@ayacoo.de',
'state' => 'stable',
'createDirs' => '',
'clearCacheOnLoad' => 0,
'version' => '1.0.0',
'constraints' => [
'depends' => [
'typo3' => '11.5.0-11.5.99',
],
'conflicts' => [
],
'suggests' => [
],
],
];
23 changes: 23 additions & 0 deletions ext_localconf.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

use Ayacoo\AyacooSoundcloud\Helper\SoundcloudHelper;
use Ayacoo\AyacooSoundcloud\Rendering\SoundcloudRenderer;
use TYPO3\CMS\Core\Imaging\IconRegistry;
use TYPO3\CMS\Core\Resource\Rendering\RendererRegistry;
use TYPO3\CMS\Core\Utility\GeneralUtility;

defined('TYPO3_MODE') || die();

(function ($mediaFileExt) {
$GLOBALS['TYPO3_CONF_VARS']['SYS']['fal']['onlineMediaHelpers'][$mediaFileExt] = SoundcloudHelper::class;

$rendererRegistry = GeneralUtility::makeInstance(RendererRegistry::class);
$rendererRegistry->registerRendererClass(SoundcloudRenderer::class);

$GLOBALS['TYPO3_CONF_VARS']['SYS']['FileInfo']['fileExtensionToMimeType'][$mediaFileExt] = 'audio/' . $mediaFileExt;
$GLOBALS['TYPO3_CONF_VARS']['SYS']['mediafile_ext'] .= ',' . $mediaFileExt;

$iconRegistry = GeneralUtility::makeInstance(IconRegistry::class);
$iconRegistry->registerFileExtension($mediaFileExt, 'mimetypes-media-image-' . $mediaFileExt);

})('soundcloud');
9 changes: 9 additions & 0 deletions ext_tables.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#
# Table structure for table 'sys_file_metadata'
#
CREATE TABLE sys_file_metadata
(
soundcloud_thumbnail_url text,
soundcloud_html text,
soundcloud_author_url varchar(2048) DEFAULT '',
);

0 comments on commit 0cb1788

Please sign in to comment.