contrib modules updates
This commit is contained in:
@@ -23,8 +23,9 @@ of additional files. You can check the current status of installation at
|
||||
/admin/reports/status or read below for further details on how to install
|
||||
each player.
|
||||
|
||||
To install all external audio player libraries at once, you can run the drush
|
||||
command drush audiofield-download
|
||||
To install all external audio player libraries at once, you can run the Drush
|
||||
command drush audiofield-download (Drush 8) or drush audiofield:download (Drush
|
||||
9).
|
||||
|
||||
Audio.js Audio Player
|
||||
Audio.js requires installation of the audio.js library located at
|
||||
@@ -32,7 +33,8 @@ Audio.js Audio Player
|
||||
subfolder titled "audiojs" should be placed in /libraries/audiojs such that
|
||||
the file audio.min.js is found at /libraries/audiojs/.
|
||||
|
||||
Install through drush using command drush audiofield-download audiojs.
|
||||
Install through drush using command drush audiofield-download audiojs
|
||||
(Drush 8) or drush audiofield:download audiojs (Drush 9).
|
||||
|
||||
Audio.js does not offer any theme options, but can be fully styled by custom
|
||||
CSS.
|
||||
@@ -43,7 +45,8 @@ jPlayer Audio Player
|
||||
in /libraries/jplayer. It should be installed such that the file
|
||||
jquery.jplayer.min.js can be found at /libraries/jplayer/dist/jplayer/.
|
||||
|
||||
Install through drush using command drush audiofield-download jplayer.
|
||||
Install through drush using command drush audiofield-download jplayer
|
||||
(Drush 8) or drush audiofield:download jplayer (Drush 9).
|
||||
|
||||
jPlayer comes bundled with multiple skins by default. You can install
|
||||
additional skins by placing them in /libraries/jplayer/dist/skin/ and
|
||||
@@ -60,7 +63,8 @@ MediaElement Audio Player
|
||||
in /libraries/mediaelement such that the file mediaelement-and-player.min.js
|
||||
is found at /libraries/mediaelement/build/.
|
||||
|
||||
Install through drush using command drush audiofield-download mediaelement.
|
||||
Install through drush using command drush audiofield-download mediaelement
|
||||
(Drush 8) or drush audiofield:download mediaelement (Drush 9).
|
||||
|
||||
Projekktor Audio Player
|
||||
Projekktor requires installation of the Projekktor library located at
|
||||
@@ -73,7 +77,8 @@ Projekktor Audio Player
|
||||
projekktor-1.3.09.min.js at /libraries/projekktor/. This file will not exist
|
||||
unless the distribution has been properly compiled.
|
||||
|
||||
Install through drush using command drush audiofield-download projekktor.
|
||||
Install through drush using command drush audiofield-download projekktor
|
||||
(Drush 8) or drush audiofield:download projekktor (Drush 9).
|
||||
|
||||
SoundManager Audio Player
|
||||
WordPress Audio Player requires installation of the SoundManager library
|
||||
@@ -82,7 +87,8 @@ SoundManager Audio Player
|
||||
that the file soundmanager2-nodebug-jsmin.js can be found at
|
||||
/libraries/soundmanager/script/.
|
||||
|
||||
Install through drush using command drush audiofield-download soundmanager.
|
||||
Install through drush using command drush audiofield-download soundmanager
|
||||
(Drush 8) or drush audiofield:download soundmanager (Drush 9).
|
||||
|
||||
SoundManager is a highly configurable library. However, handling and allowing
|
||||
for all of the possible configurations and implementations of SoundManager is
|
||||
@@ -101,7 +107,8 @@ Wavesurfer Audio Player
|
||||
but there are small feature differences between the two to be aware of. The
|
||||
drush command will install the latest version.
|
||||
|
||||
Install through drush using command drush audiofield-download wavesurfer.
|
||||
Install through drush using command drush audiofield-download waveplayer
|
||||
(Drush 8) or drush audiofield:download waveplayer (Drush 9).
|
||||
|
||||
WordPress Audio Player
|
||||
WordPress Audio Player requires installation of the Standalone version of
|
||||
@@ -109,7 +116,8 @@ WordPress Audio Player
|
||||
These files should be downloaded and placed in /libraries/wordpress-audio such
|
||||
that the file audio-player.js can be found at /libraries/wordpress-audio.
|
||||
|
||||
Install through drush using command drush audiofield-download wordpress.
|
||||
Install through drush using command drush audiofield-download wordpress
|
||||
(Drush 8) or drush audiofield:download wordpress (Drush 9).
|
||||
|
||||
WordPress Audio Player only supports a single skin, but does support a
|
||||
single audio player for multiple files. However, the multi-file version of
|
||||
|
||||
@@ -5,8 +5,8 @@ type: module
|
||||
package: Field types
|
||||
# core: '8.x'
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-12-27
|
||||
version: '8.x-1.6'
|
||||
# Information added by Drupal.org packaging script on 2018-11-26
|
||||
version: '8.x-1.8'
|
||||
core: '8.x'
|
||||
project: 'audiofield'
|
||||
datestamp: 1514414887
|
||||
datestamp: 1543249984
|
||||
|
||||
@@ -1,18 +1,25 @@
|
||||
{
|
||||
"name": "drupal/audiofield",
|
||||
"description": "AudioField Module",
|
||||
"type": "drupal-module",
|
||||
"license": "GPL-2.0+",
|
||||
"homepage": "https://www.drupal.org/project/audiofield",
|
||||
"minimum-stability": "dev",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Daniel Moberly",
|
||||
"homepage": "https://www.drupal.org/u/danielmoberly",
|
||||
"role": "Maintainer"
|
||||
"name": "drupal/audiofield",
|
||||
"description": "AudioField Module",
|
||||
"type": "drupal-module",
|
||||
"license": "GPL-2.0+",
|
||||
"homepage": "https://www.drupal.org/project/audiofield",
|
||||
"minimum-stability": "dev",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Daniel Moberly",
|
||||
"homepage": "https://www.drupal.org/u/danielmoberly",
|
||||
"role": "Maintainer"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://www.drupal.org/project/issues/audiofield"
|
||||
},
|
||||
"extra": {
|
||||
"drush": {
|
||||
"services": {
|
||||
"drush.services.yml": "^9"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://www.drupal.org/project/issues/audiofield"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
services:
|
||||
audiofield.commands:
|
||||
class: \Drupal\audiofield\Commands\AudiofieldCommands
|
||||
arguments:
|
||||
- '@plugin.manager.audiofield'
|
||||
tags:
|
||||
- { name: drush.command }
|
||||
@@ -127,7 +127,7 @@
|
||||
},
|
||||
swfPath: '/libraries/jplayer/dist/jplayer',
|
||||
wmode: 'window',
|
||||
preload: settings.lazyload,
|
||||
preload: file.lazyload,
|
||||
keyEnabled: true,
|
||||
supplied: file.filetype,
|
||||
},
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
swfPath: '/libraries/jplayer/dist/jplayer',
|
||||
wmode: 'window',
|
||||
keyEnabled: true,
|
||||
preload: settings.lazyload,
|
||||
preload: file.lazyload,
|
||||
supplied: file.filetype
|
||||
});
|
||||
});
|
||||
|
||||
@@ -23,6 +23,18 @@
|
||||
// Create waveform.
|
||||
const wavesurfer = WaveSurfer.create({
|
||||
container: `#${$(wavecontainer).attr('id')} .waveform`,
|
||||
audioRate: settings.audioRate,
|
||||
autoCenter: settings.autoCenter,
|
||||
barGap: settings.barGap,
|
||||
barHeight: settings.barHeight,
|
||||
barWidth: settings.barWidth,
|
||||
cursorColor: settings.cursorColor,
|
||||
cursorWidth: settings.cursorWidth,
|
||||
forceDecode: settings.forceDecode,
|
||||
normalize: settings.normalize,
|
||||
progressColor: settings.progressColor,
|
||||
responsive: settings.responsive,
|
||||
waveColor: settings.waveColor,
|
||||
});
|
||||
|
||||
// Load the file.
|
||||
@@ -32,12 +44,12 @@
|
||||
wavesurfer.setVolume(settings.volume);
|
||||
|
||||
// Handle play/pause.
|
||||
$(wavecontainer).find('.player-button.playpause').on('click', () => {
|
||||
$(wavecontainer).find('.player-button.playpause').on('click', (event) => {
|
||||
Drupal.AudiofieldWavesurfer.PlayPause(wavecontainer, wavesurfer);
|
||||
});
|
||||
|
||||
// Handle volume change.
|
||||
$(wavecontainer).find('.volume').on('change', () => {
|
||||
$(wavecontainer).find('.volume').on('change', (event) => {
|
||||
wavesurfer.setVolume(($(event.currentTarget).val() / 10));
|
||||
});
|
||||
|
||||
@@ -61,6 +73,18 @@
|
||||
// Create waveform.
|
||||
const wavesurfer = WaveSurfer.create({
|
||||
container: `#${$(wavecontainer).attr('id')} .waveform`,
|
||||
audioRate: settings.audioRate,
|
||||
autoCenter: settings.autoCenter,
|
||||
barGap: settings.barGap,
|
||||
barHeight: settings.barHeight,
|
||||
barWidth: settings.barWidth,
|
||||
cursorColor: settings.cursorColor,
|
||||
cursorWidth: settings.cursorWidth,
|
||||
forceDecode: settings.forceDecode,
|
||||
normalize: settings.normalize,
|
||||
progressColor: settings.progressColor,
|
||||
responsive: settings.responsive,
|
||||
waveColor: settings.waveColor,
|
||||
});
|
||||
|
||||
// Set the default volume.
|
||||
@@ -77,28 +101,33 @@
|
||||
wavesurfer.load(first.attr('data-src'));
|
||||
|
||||
// Handle play/pause.
|
||||
$(wavecontainer).find('.player-button.playpause').on('click', () => {
|
||||
$(wavecontainer).find('.player-button.playpause').on('click', (event) => {
|
||||
Drupal.AudiofieldWavesurfer.PlayPause(wavecontainer, wavesurfer);
|
||||
});
|
||||
|
||||
// Handle next/previous.
|
||||
$(wavecontainer).find('.player-button.next').on('click', () => {
|
||||
$(wavecontainer).find('.player-button.next').on('click', (event) => {
|
||||
Drupal.AudiofieldWavesurfer.Next(wavecontainer, wavesurfer);
|
||||
});
|
||||
$(wavecontainer).find('.player-button.previous').on('click', () => {
|
||||
$(wavecontainer).find('.player-button.previous').on('click', (event) => {
|
||||
Drupal.AudiofieldWavesurfer.Previous(wavecontainer, wavesurfer);
|
||||
});
|
||||
|
||||
// Handle clicking track.
|
||||
$(wavecontainer).find('.playlist .track').on('click', () => {
|
||||
// Load the track.
|
||||
Drupal.AudiofieldWavesurfer.Load(wavecontainer, wavesurfer, $(event.currentTarget));
|
||||
// Play the track.
|
||||
Drupal.AudiofieldWavesurfer.PlayPause(wavecontainer, wavesurfer);
|
||||
$(wavecontainer).find('.playlist .track').on('click', (event) => {
|
||||
// Check if the track is already playing.
|
||||
if ($(this).hasClass('playing')) {
|
||||
// Play/pause the track if it is already loaded.
|
||||
Drupal.AudiofieldWavesurfer.PlayPause(wavecontainer, wavesurfer);
|
||||
}
|
||||
else {
|
||||
// Load the track.
|
||||
Drupal.AudiofieldWavesurfer.Load(wavecontainer, wavesurfer, $(event.currentTarget));
|
||||
}
|
||||
});
|
||||
|
||||
// Handle volume change.
|
||||
$(wavecontainer).find('.volume').on('change', () => {
|
||||
$(wavecontainer).find('.volume').on('change', (event) => {
|
||||
wavesurfer.setVolume(($(event.currentTarget).val() / 10));
|
||||
});
|
||||
|
||||
@@ -108,7 +137,7 @@
|
||||
}
|
||||
|
||||
// Handle track finishing.
|
||||
wavesurfer.on('finish', () => {
|
||||
wavesurfer.on('finish', (event) => {
|
||||
Drupal.AudiofieldWavesurfer.Next(wavecontainer, wavesurfer);
|
||||
});
|
||||
});
|
||||
@@ -147,13 +176,13 @@
|
||||
*/
|
||||
Drupal.AudiofieldWavesurfer.Load = (wavecontainer, wavesurfer, track) => {
|
||||
// Load the track.
|
||||
wavesurfer.on('ready', () => {
|
||||
wavesurfer.play();
|
||||
wavesurfer.load(track.attr('data-src'));
|
||||
wavesurfer.on('ready', (event) => {
|
||||
$(wavecontainer).removeClass('playing');
|
||||
$(wavecontainer).addClass('playing');
|
||||
$(wavecontainer).find('.player-button.playpause').html('Pause');
|
||||
wavesurfer.play();
|
||||
});
|
||||
wavesurfer.load(track.attr('data-src'));
|
||||
// Remove playing from all other tracks.
|
||||
$(wavecontainer).find('.track').removeClass('playing');
|
||||
// Set the class on this track.
|
||||
|
||||
@@ -13,18 +13,30 @@
|
||||
Drupal.AudiofieldWavesurfer.generate = function (context, file, settings) {
|
||||
$.each($(context).find('#' + file.id).once('generate-waveform'), function (index, wavecontainer) {
|
||||
var wavesurfer = WaveSurfer.create({
|
||||
container: '#' + $(wavecontainer).attr('id') + ' .waveform'
|
||||
container: '#' + $(wavecontainer).attr('id') + ' .waveform',
|
||||
audioRate: settings.audioRate,
|
||||
autoCenter: settings.autoCenter,
|
||||
barGap: settings.barGap,
|
||||
barHeight: settings.barHeight,
|
||||
barWidth: settings.barWidth,
|
||||
cursorColor: settings.cursorColor,
|
||||
cursorWidth: settings.cursorWidth,
|
||||
forceDecode: settings.forceDecode,
|
||||
normalize: settings.normalize,
|
||||
progressColor: settings.progressColor,
|
||||
responsive: settings.responsive,
|
||||
waveColor: settings.waveColor
|
||||
});
|
||||
|
||||
wavesurfer.load(file.path);
|
||||
|
||||
wavesurfer.setVolume(settings.volume);
|
||||
|
||||
$(wavecontainer).find('.player-button.playpause').on('click', function () {
|
||||
$(wavecontainer).find('.player-button.playpause').on('click', function (event) {
|
||||
Drupal.AudiofieldWavesurfer.PlayPause(wavecontainer, wavesurfer);
|
||||
});
|
||||
|
||||
$(wavecontainer).find('.volume').on('change', function () {
|
||||
$(wavecontainer).find('.volume').on('change', function (event) {
|
||||
wavesurfer.setVolume($(event.currentTarget).val() / 10);
|
||||
});
|
||||
|
||||
@@ -37,7 +49,19 @@
|
||||
Drupal.AudiofieldWavesurfer.generatePlaylist = function (context, settings) {
|
||||
$.each($(context).find('#wavesurfer_playlist').once('generate-waveform'), function (index, wavecontainer) {
|
||||
var wavesurfer = WaveSurfer.create({
|
||||
container: '#' + $(wavecontainer).attr('id') + ' .waveform'
|
||||
container: '#' + $(wavecontainer).attr('id') + ' .waveform',
|
||||
audioRate: settings.audioRate,
|
||||
autoCenter: settings.autoCenter,
|
||||
barGap: settings.barGap,
|
||||
barHeight: settings.barHeight,
|
||||
barWidth: settings.barWidth,
|
||||
cursorColor: settings.cursorColor,
|
||||
cursorWidth: settings.cursorWidth,
|
||||
forceDecode: settings.forceDecode,
|
||||
normalize: settings.normalize,
|
||||
progressColor: settings.progressColor,
|
||||
responsive: settings.responsive,
|
||||
waveColor: settings.waveColor
|
||||
});
|
||||
|
||||
wavesurfer.setVolume(settings.volume);
|
||||
@@ -51,24 +75,27 @@
|
||||
|
||||
wavesurfer.load(first.attr('data-src'));
|
||||
|
||||
$(wavecontainer).find('.player-button.playpause').on('click', function () {
|
||||
$(wavecontainer).find('.player-button.playpause').on('click', function (event) {
|
||||
Drupal.AudiofieldWavesurfer.PlayPause(wavecontainer, wavesurfer);
|
||||
});
|
||||
|
||||
$(wavecontainer).find('.player-button.next').on('click', function () {
|
||||
$(wavecontainer).find('.player-button.next').on('click', function (event) {
|
||||
Drupal.AudiofieldWavesurfer.Next(wavecontainer, wavesurfer);
|
||||
});
|
||||
$(wavecontainer).find('.player-button.previous').on('click', function () {
|
||||
$(wavecontainer).find('.player-button.previous').on('click', function (event) {
|
||||
Drupal.AudiofieldWavesurfer.Previous(wavecontainer, wavesurfer);
|
||||
});
|
||||
|
||||
$(wavecontainer).find('.playlist .track').on('click', function () {
|
||||
Drupal.AudiofieldWavesurfer.Load(wavecontainer, wavesurfer, $(event.currentTarget));
|
||||
|
||||
Drupal.AudiofieldWavesurfer.PlayPause(wavecontainer, wavesurfer);
|
||||
$(wavecontainer).find('.playlist .track').on('click', function (event) {
|
||||
if ($(this).hasClass('playing')) {
|
||||
Drupal.AudiofieldWavesurfer.PlayPause(wavecontainer, wavesurfer);
|
||||
}
|
||||
else {
|
||||
Drupal.AudiofieldWavesurfer.Load(wavecontainer, wavesurfer, $(event.currentTarget));
|
||||
}
|
||||
});
|
||||
|
||||
$(wavecontainer).find('.volume').on('change', function () {
|
||||
$(wavecontainer).find('.volume').on('change', function (event) {
|
||||
wavesurfer.setVolume($(event.currentTarget).val() / 10);
|
||||
});
|
||||
|
||||
@@ -76,7 +103,7 @@
|
||||
wavesurfer.on('ready', wavesurfer.play.bind(wavesurfer));
|
||||
}
|
||||
|
||||
wavesurfer.on('finish', function () {
|
||||
wavesurfer.on('finish', function (event) {
|
||||
Drupal.AudiofieldWavesurfer.Next(wavecontainer, wavesurfer);
|
||||
});
|
||||
});
|
||||
@@ -95,13 +122,13 @@
|
||||
};
|
||||
|
||||
Drupal.AudiofieldWavesurfer.Load = function (wavecontainer, wavesurfer, track) {
|
||||
wavesurfer.on('ready', function () {
|
||||
wavesurfer.play();
|
||||
wavesurfer.load(track.attr('data-src'));
|
||||
wavesurfer.on('ready', function (event) {
|
||||
$(wavecontainer).removeClass('playing');
|
||||
$(wavecontainer).addClass('playing');
|
||||
$(wavecontainer).find('.player-button.playpause').html('Pause');
|
||||
wavesurfer.play();
|
||||
});
|
||||
wavesurfer.load(track.attr('data-src'));
|
||||
|
||||
$(wavecontainer).find('.track').removeClass('playing');
|
||||
|
||||
|
||||
@@ -9,11 +9,62 @@ use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Component\Utility\UrlHelper;
|
||||
use Drupal\Component\Utility\Random;
|
||||
use Drupal\Component\Plugin\PluginBase;
|
||||
use Drupal\Core\Asset\LibraryDiscovery;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\Core\Messenger\Messenger;
|
||||
use Drupal\Core\Logger\LoggerChannelFactoryInterface ;
|
||||
|
||||
/**
|
||||
* Base class for audiofield plugins. Includes global functions.
|
||||
*/
|
||||
abstract class AudioFieldPluginBase extends PluginBase {
|
||||
abstract class AudioFieldPluginBase extends PluginBase implements ContainerFactoryPluginInterface {
|
||||
|
||||
/**
|
||||
* Library discovery service.
|
||||
*
|
||||
* @var Drupal\Core\Asset\LibraryDiscovery
|
||||
*/
|
||||
protected $libraryDiscovery;
|
||||
|
||||
/**
|
||||
* Messenger service.
|
||||
*
|
||||
* @var Drupal\Core\Messenger\Messenger
|
||||
*/
|
||||
protected $messenger;
|
||||
|
||||
/**
|
||||
* Messenger service.
|
||||
*
|
||||
* @var Drupal\Core\Logger\LoggerChannelFactoryInterface
|
||||
*/
|
||||
protected $loggerFactory;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, LibraryDiscovery $library_discovery, Messenger $messenger, LoggerChannelFactoryInterface $logger_factory) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
|
||||
$this->libraryDiscovery = $library_discovery;
|
||||
$this->messenger = $messenger;
|
||||
$this->loggerFactory = $logger_factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$container->get('library.discovery'),
|
||||
$container->get('messenger'),
|
||||
$container->get('logger.factory')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the player.
|
||||
@@ -68,7 +119,7 @@ abstract class AudioFieldPluginBase extends PluginBase {
|
||||
*/
|
||||
public function getPluginLibrary() {
|
||||
// Get the main library for this plugin.
|
||||
return \Drupal::service('library.discovery')->getLibraryByName('audiofield', 'audiofield.' . $this->getPluginLibraryName());
|
||||
return $this->libraryDiscovery->getLibraryByName('audiofield', 'audiofield.' . $this->getPluginLibraryName());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -170,8 +221,8 @@ abstract class AudioFieldPluginBase extends PluginBase {
|
||||
'%command' => 'drush audiofield-update',
|
||||
'@status_report' => Link::createFromRoute('status report', 'system.status')->toString(),
|
||||
];
|
||||
\Drupal::logger('audiofield')->warning('Warning: @plugin library is out of date. You should upgrade from version @version to version @newversion. You can manually download the required version here: @download-link or you can install automatically by running the command %command. See the @status_report for more information', $message_data);
|
||||
drupal_set_message(t('Warning: @plugin library is out of date. You should upgrade from version @version to version @newversion. You can manually download the required version here: @download-link or you can install automatically by running the command %command. See the @status_report for more information', $message_data), 'warning');
|
||||
$this->loggerFactory->get('audiofield')->warning('Warning: @plugin library is out of date. You should upgrade from version @version to version @newversion. You can manually download the required version here: @download-link or you can install automatically by running the command %command. See the @status_report for more information', $message_data);
|
||||
$this->messenger->addWarning(t('Warning: @plugin library is out of date. You should upgrade from version @version to version @newversion. You can manually download the required version here: @download-link or you can install automatically by running the command %command. See the @status_report for more information', $message_data));
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
@@ -186,8 +237,8 @@ abstract class AudioFieldPluginBase extends PluginBase {
|
||||
'@library_name' => $this->getPluginLibraryName(),
|
||||
'@status_report' => Link::createFromRoute('status report', 'system.status')->toString(),
|
||||
];
|
||||
\Drupal::logger('audiofield')->error('Error: @library_name library is not currently installed! See the @status_report for more information.', $message_data);
|
||||
drupal_set_message(t('Error: @library_name library is not currently installed! See the @status_report for more information.', $message_data), 'error');
|
||||
$this->loggerFactory->get('audiofield')->error('Error: @library_name library is not currently installed! See the @status_report for more information.', $message_data);
|
||||
$this->messenger->addWarning(t('Error: @library_name library is not currently installed! See the @status_report for more information.', $message_data));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -208,8 +259,8 @@ abstract class AudioFieldPluginBase extends PluginBase {
|
||||
'@player' => $this->getPluginLibraryName(),
|
||||
'%extensions' => implode(', ', $this->pluginDefinition["fileTypes"]),
|
||||
];
|
||||
\Drupal::logger('audiofield')->error('Error playing file %filename: currently selected audio player only supports the following extensions: %extensions', $message_data);
|
||||
drupal_set_message(t('Error playing file %filename: currently selected audio player only supports the following extensions: %extensions', $message_data), 'error');
|
||||
$this->loggerFactory->get('audiofield')->error('Error playing file %filename: currently selected audio player only supports the following extensions: %extensions', $message_data);
|
||||
$this->messenger->addWarning(t('Error playing file %filename: currently selected audio player only supports the following extensions: %extensions', $message_data));
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
@@ -232,8 +283,8 @@ abstract class AudioFieldPluginBase extends PluginBase {
|
||||
$message_data = [
|
||||
'%link' => $link->toString(),
|
||||
];
|
||||
\Drupal::logger('audiofield')->error('Error playing file: invalid link: %link', $message_data);
|
||||
drupal_set_message(t('Error playing file: invalid link: %link', $message_data), 'error');
|
||||
$this->loggerFactory->get('audiofield')->error('Error playing file: invalid link: %link', $message_data);
|
||||
$this->messenger->addWarning(t('Error playing file: invalid link: %link', $message_data));
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
@@ -366,20 +417,19 @@ abstract class AudioFieldPluginBase extends PluginBase {
|
||||
* The source URL of an entity.
|
||||
*/
|
||||
private function getAudioSource($item) {
|
||||
$source_url = '';
|
||||
if ($this->getClassType($item) == 'FileItem') {
|
||||
// Load the associated file.
|
||||
$file = $this->loadFileFromItem($item);
|
||||
// Get the file URL.
|
||||
$source_url = Url::fromUri(file_create_url($file->getFileUri()));
|
||||
return Url::fromUri(file_create_url($file->getFileUri()));
|
||||
}
|
||||
// Handle Link entity.
|
||||
elseif ($this->getClassType($item) == 'LinkItem') {
|
||||
// Get the file URL.
|
||||
$source_url = $item->getUrl();
|
||||
return $item->getUrl();
|
||||
}
|
||||
|
||||
return $source_url;
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -392,7 +442,6 @@ abstract class AudioFieldPluginBase extends PluginBase {
|
||||
* The description of an entity.
|
||||
*/
|
||||
private function getAudioDescription($item) {
|
||||
$entity_description = '';
|
||||
if ($this->getClassType($item) == 'FileItem') {
|
||||
// Get the file description - use the filename if it doesn't exist.
|
||||
$entity_description = $item->get('description')->getString();
|
||||
@@ -400,19 +449,20 @@ abstract class AudioFieldPluginBase extends PluginBase {
|
||||
// Load the associated file.
|
||||
$file = $this->loadFileFromItem($item);
|
||||
|
||||
$entity_description = $file->getFilename();
|
||||
return $file->getFilename();
|
||||
}
|
||||
return $entity_description;
|
||||
}
|
||||
// Handle Link entity.
|
||||
elseif ($this->getClassType($item) == 'LinkItem') {
|
||||
// Get the file description - use the filename if it doesn't exist.
|
||||
$entity_description = $item->get('title')->getString();
|
||||
if (empty($entity_description)) {
|
||||
$entity_description = $item->getUrl()->toString();
|
||||
return $item->getUrl()->toString();
|
||||
}
|
||||
return $entity_description;
|
||||
}
|
||||
|
||||
return $entity_description;
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -476,51 +526,29 @@ abstract class AudioFieldPluginBase extends PluginBase {
|
||||
* A render array containing download links.
|
||||
*/
|
||||
public function createDownloadList($items, array $settings) {
|
||||
$download_links = [];
|
||||
|
||||
// Check if download links are turned on.
|
||||
if ($settings['download_link']) {
|
||||
// Loop over each item.
|
||||
foreach ($items as $item) {
|
||||
// Get the source URL for this item.
|
||||
$source_url = $this->getAudioSource($item);
|
||||
|
||||
// Get the entity description for this item.
|
||||
$entity_description = $this->getAudioDescription($item);
|
||||
|
||||
// Add the link.
|
||||
$download_links[] = [
|
||||
'#markup' => Link::fromTextAndUrl($entity_description, $source_url)->toString(),
|
||||
'#wrapper_attributes' => [
|
||||
'class' => [
|
||||
'audiofield-download-link',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
// Check if download links are turned on and there are items.
|
||||
if (!$settings['download_link'] || count($items) == 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Render links if we have them.
|
||||
$download_render_array = [];
|
||||
if (count($download_links) > 0) {
|
||||
$download_render_array = [
|
||||
'#theme' => 'item_list',
|
||||
'#list_type' => 'ul',
|
||||
'#title' => t('Download files:'),
|
||||
'#wrapper_attributes' => [
|
||||
'class' => [
|
||||
'audiofield-downloads',
|
||||
],
|
||||
],
|
||||
'#attributes' => [],
|
||||
'#empty' => '',
|
||||
'#items' => $download_links,
|
||||
$links = [];
|
||||
// Loop over each item.
|
||||
foreach ($items as $item) {
|
||||
// Get the source URL for this item.
|
||||
$source_url = $this->getAudioSource($item);
|
||||
|
||||
// Get the entity description for this item.
|
||||
$entity_description = $this->getAudioDescription($item);
|
||||
|
||||
// Add the link.
|
||||
$links[] = [
|
||||
'link' => Link::fromTextAndUrl($entity_description, $source_url)->toString(),
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'#theme' => 'audiofield_download_links',
|
||||
'#links' => $download_render_array,
|
||||
'#links' => $links,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,268 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\audiofield\Commands;
|
||||
|
||||
use Drush\Commands\DrushCommands;
|
||||
use Symfony\Component\Filesystem\Filesystem;
|
||||
use Symfony\Component\Finder\Finder;
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\RequestException;
|
||||
use Drupal\audiofield\AudioFieldPlayerManager;
|
||||
|
||||
/**
|
||||
* A Drush commandfile for Audiofield module.
|
||||
*/
|
||||
class AudiofieldCommands extends DrushCommands {
|
||||
|
||||
/**
|
||||
* Library discovery service.
|
||||
*
|
||||
* @var Drupal\audiofield\AudioFieldPlayerManager
|
||||
*/
|
||||
protected $playerManager;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct(AudioFieldPlayerManager $player_manager) {
|
||||
$this->playerManager = $player_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Downloads the suggested Audiofield libraries from their remote repos.
|
||||
*
|
||||
* @param string $installLibrary
|
||||
* The name of the library. If omitted, all libraries will be installed.
|
||||
* @param bool $print_messages
|
||||
* Flag indicating if messages should be displayed.
|
||||
*
|
||||
* @command audiofield:download
|
||||
* @aliases audiofield-download
|
||||
*/
|
||||
public function download($installLibrary = '', $print_messages = TRUE) {
|
||||
|
||||
// Declare filesystem container.
|
||||
$fs = new Filesystem();
|
||||
|
||||
// Get a list of the audiofield plugins.
|
||||
$pluginList = $this->playerManager->getDefinitions();
|
||||
|
||||
// If there is an argument, check to make sure its valid.
|
||||
if (!empty($installLibrary)) {
|
||||
if (!isset($pluginList[$installLibrary . '_audio_player'])) {
|
||||
$this->logger()->error(dt('Error: @library is not a valid Audiofield library.', [
|
||||
'@library' => $installLibrary,
|
||||
], 'error'));
|
||||
return;
|
||||
}
|
||||
// If the argument is valid, we only want to install that plugin.
|
||||
$pluginList = [$installLibrary . '_audio_player' => $pluginList[$installLibrary . '_audio_player']];
|
||||
}
|
||||
|
||||
// Loop over each plugin and make sure it's library is installed.
|
||||
foreach ($pluginList as $pluginName => $plugin) {
|
||||
// Create an instance of this plugin.
|
||||
$pluginInstance = $this->playerManager->createInstance($pluginName);
|
||||
|
||||
// Only check install if there is a library for the plugin.
|
||||
if (!$pluginInstance->getPluginLibrary()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip if the plugin is installed.
|
||||
if ($pluginInstance->checkInstalled()) {
|
||||
if ($print_messages) {
|
||||
$this->logger()->notice(dt('Audiofield library for @library is already installed at @location', [
|
||||
'@library' => $pluginInstance->getPluginTitle(),
|
||||
'@location' => $pluginInstance->getPluginLibraryPath(),
|
||||
], 'success'));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the library install path.
|
||||
$path = DRUPAL_ROOT . $pluginInstance->getPluginLibraryPath();
|
||||
// Create the install directory if it does not exist.
|
||||
if (!is_dir($path)) {
|
||||
$fs->mkdir($path);
|
||||
}
|
||||
|
||||
// Download the file.
|
||||
$client = new Client();
|
||||
$destination = tempnam(sys_get_temp_dir(), 'file.') . "tar.gz";
|
||||
try {
|
||||
$client->get($pluginInstance->getPluginRemoteSource(), ['save_to' => $destination]);
|
||||
}
|
||||
catch (RequestException $e) {
|
||||
// Remove the directory.
|
||||
$fs->remove($path);
|
||||
$this->logger()->error(dt('Error: unable to download @library. @exception', [
|
||||
'@library' => $pluginInstance->getPluginTitle(),
|
||||
'@exception' => $e->getMessage(),
|
||||
], 'error'));
|
||||
continue;
|
||||
}
|
||||
$fs->rename($destination, $path . '/audiofield-dl.zip');
|
||||
if (!file_exists($path . '/audiofield-dl.zip')) {
|
||||
// Remove the directory where we tried to install.
|
||||
$fs->remove($path);
|
||||
if ($print_messages) {
|
||||
$this->logger()->error(dt('Error: unable to download Audiofield library @library', [
|
||||
'@library' => $pluginInstance->getPluginTitle(),
|
||||
], 'error'));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Unzip the file.
|
||||
$zip = new \ZipArchive();
|
||||
$res = $zip->open($path . '/audiofield-dl.zip');
|
||||
if ($res === TRUE) {
|
||||
$zip->extractTo($path);
|
||||
$zip->close();
|
||||
}
|
||||
else {
|
||||
// Remove the directory.
|
||||
$fs->remove($path);
|
||||
$this->logger()->error(dt('Error: unable to unzip @library.', [
|
||||
'@library' => $pluginInstance->getPluginTitle(),
|
||||
], 'error'));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove the downloaded zip file.
|
||||
$fs->remove($path . '/audiofield-dl.zip');
|
||||
|
||||
// If the library still is not installed, we need to move files.
|
||||
if (!$pluginInstance->checkInstalled()) {
|
||||
// Find all folders in this directory and move their
|
||||
// subdirectories up to the parent directory.
|
||||
$directories = Finder::create()
|
||||
->directories()
|
||||
->depth('< 1')
|
||||
->in($path)
|
||||
->ignoreDotFiles(TRUE)
|
||||
->ignoreVCS(TRUE);
|
||||
foreach ($directories as $dirName) {
|
||||
$fs->mirror($dirName, $path, NULL, ['override' => TRUE]);
|
||||
$fs->remove($dirName);
|
||||
}
|
||||
|
||||
// Projekktor source files need to be installed.
|
||||
if ($pluginInstance->getPluginId() == 'projekktor_audio_player') {
|
||||
drush_op('chdir', '..');
|
||||
drush_op('chdir', $path);
|
||||
drush_shell_exec('npm install');
|
||||
drush_shell_exec('grunt --force');
|
||||
}
|
||||
}
|
||||
if ($pluginInstance->checkInstalled()) {
|
||||
if ($print_messages) {
|
||||
$this->logger()->notice(dt('Audiofield library for @library has been successfully installed at @location', [
|
||||
'@library' => $pluginInstance->getPluginTitle(),
|
||||
'@location' => $pluginInstance->getPluginLibraryPath(),
|
||||
], 'success'));
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Remove the directory where we tried to install.
|
||||
$fs->remove($path);
|
||||
if ($print_messages) {
|
||||
$this->logger()->error(dt('Error: unable to install Audiofield library @library', [
|
||||
'@library' => $pluginInstance->getPluginTitle(),
|
||||
], 'error'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates Audiofield libraries from their remote repos if out of date.
|
||||
*
|
||||
* @param string $updateLibrary
|
||||
* The name of the library. If omitted, all libraries will be updated.
|
||||
* @param bool $print_messages
|
||||
* Flag indicating if messages should be displayed.
|
||||
*
|
||||
* @command audiofield:update
|
||||
* @aliases audiofield-update
|
||||
*/
|
||||
public function update($updateLibrary = '', $print_messages = TRUE) {
|
||||
|
||||
// Declare filesystem container.
|
||||
$fs = new Filesystem();
|
||||
|
||||
// Get a list of the audiofield plugins.
|
||||
$pluginList = $this->playerManager->getDefinitions();
|
||||
|
||||
// If there is an argument, check to make sure its valid.
|
||||
if (!empty($updateLibrary)) {
|
||||
if (!isset($pluginList[$updateLibrary . '_audio_player'])) {
|
||||
$this->logger()->error(dt('Error: @library is not a valid Audiofield library.', [
|
||||
'@library' => $updateLibrary,
|
||||
], 'error'));
|
||||
return;
|
||||
}
|
||||
// If the argument is valid, we only want to install that plugin.
|
||||
$pluginList = [$updateLibrary . '_audio_player' => $pluginList[$updateLibrary . '_audio_player']];
|
||||
}
|
||||
|
||||
// Loop over each plugin and make sure it's library is installed.
|
||||
foreach ($pluginList as $pluginName => $plugin) {
|
||||
// Create an instance of this plugin.
|
||||
$pluginInstance = $this->playerManager->createInstance($pluginName);
|
||||
|
||||
// Only check install if there is a library for the plugin.
|
||||
if (!$pluginInstance->getPluginLibrary()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the library install path.
|
||||
$path = DRUPAL_ROOT . $pluginInstance->getPluginLibraryPath();
|
||||
|
||||
// If the library isn't installed at all we just run the install.
|
||||
if (!$pluginInstance->checkInstalled(FALSE)) {
|
||||
$this->download($pluginInstance->getPluginLibraryName());
|
||||
continue;
|
||||
}
|
||||
|
||||
// Don't updating the library if its up to date.
|
||||
if ($pluginInstance->checkVersion(FALSE)) {
|
||||
$this->logger()->notice(dt('Audiofield library for @library is already up to date', [
|
||||
'@library' => $pluginInstance->getPluginTitle(),
|
||||
], 'success'));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Move the current installation to the temp directory.
|
||||
$fs->rename($path, file_directory_temp() . '/temp_audiofield', TRUE);
|
||||
// If the directory failed to move, just delete it.
|
||||
if (is_dir($path)) {
|
||||
$fs->remove($path);
|
||||
}
|
||||
|
||||
// Run the install command now to get the latest version.
|
||||
$this->download($updateLibrary, FALSE);
|
||||
|
||||
// Check if library has been properly installed.
|
||||
if ($pluginInstance->checkInstalled()) {
|
||||
// Remove the temporary directory.
|
||||
$fs->remove(file_directory_temp() . '/temp_audiofield');
|
||||
$this->logger()->notice(dt('Audiofield library for @library has been successfully updated at @location', [
|
||||
'@library' => $pluginInstance->getPluginTitle(),
|
||||
'@location' => $pluginInstance->getPluginLibraryPath(),
|
||||
], 'success'));
|
||||
}
|
||||
else {
|
||||
// Remove the directory where we tried to install.
|
||||
$fs->remove($path);
|
||||
$this->logger()->error(dt('Error: unable to update Audiofield library @library', [
|
||||
'@library' => $pluginInstance->getPluginTitle(),
|
||||
], 'error'));
|
||||
// Restore the original install since we failed to update.
|
||||
$fs->rename(file_directory_temp() . '/temp_audiofield', $path, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+12
@@ -45,6 +45,18 @@ class WavesurferAudioPlayer extends AudioFieldPluginBase {
|
||||
'volume' => ($settings['audio_player_initial_volume'] / 10),
|
||||
'playertype' => ($settings['audio_player_wavesurfer_combine_files'] ? 'playlist' : 'default'),
|
||||
'files' => [],
|
||||
'audioRate' => $settings['audio_player_wavesurfer_audiorate'],
|
||||
'autoCenter' => $settings['audio_player_wavesurfer_autocenter'],
|
||||
'barGap' => $settings['audio_player_wavesurfer_bargap'],
|
||||
'barHeight' => $settings['audio_player_wavesurfer_barheight'],
|
||||
'barWidth' => $settings['audio_player_wavesurfer_barwidth'],
|
||||
'cursorColor' => $settings['audio_player_wavesurfer_cursorcolor'],
|
||||
'cursorWidth' => $settings['audio_player_wavesurfer_cursorwidth'],
|
||||
'forceDecode' => $settings['audio_player_wavesurfer_forcedecode'],
|
||||
'normalize' => $settings['audio_player_wavesurfer_normalize'],
|
||||
'progressColor' => $settings['audio_player_wavesurfer_progresscolor'],
|
||||
'responsive' => $settings['audio_player_wavesurfer_responsive'],
|
||||
'waveColor' => $settings['audio_player_wavesurfer_wavecolor'],
|
||||
'autoplay' => $settings['audio_player_autoplay'],
|
||||
];
|
||||
|
||||
|
||||
+182
@@ -138,6 +138,140 @@ class AudioFieldFieldFormatter extends FormatterBase implements ContainerFactory
|
||||
],
|
||||
],
|
||||
];
|
||||
// Settings for WaveSurfer.
|
||||
$elements['audio_player_wavesurfer_audiorate'] = [
|
||||
'#type' => 'number',
|
||||
'#title' => $this->t('Audio Rate'),
|
||||
'#description' => $this->t("Speed at which to play audio. Lower number is slower."),
|
||||
'#default_value' => $this->getSetting('audio_player_wavesurfer_audiorate'),
|
||||
'#states' => [
|
||||
'visible' => [
|
||||
[':input[name="fields[' . $fieldname . '][settings_edit_form][settings][audio_player]"]' => ['value' => 'wavesurfer_audio_player']],
|
||||
],
|
||||
],
|
||||
];
|
||||
$elements['audio_player_wavesurfer_autocenter'] = [
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t('Auto Center'),
|
||||
'#description' => $this->t("If a scrollbar is present, center the waveform around the progress."),
|
||||
'#default_value' => $this->getSetting('audio_player_wavesurfer_autocenter'),
|
||||
'#states' => [
|
||||
'visible' => [
|
||||
[':input[name="fields[' . $fieldname . '][settings_edit_form][settings][audio_player]"]' => ['value' => 'wavesurfer_audio_player']],
|
||||
],
|
||||
],
|
||||
];
|
||||
$elements['audio_player_wavesurfer_bargap'] = [
|
||||
'#type' => 'number',
|
||||
'#title' => $this->t('Bar Gap'),
|
||||
'#description' => $this->t("The optional spacing between bars of the wave."),
|
||||
'#default_value' => $this->getSetting('audio_player_wavesurfer_bargap'),
|
||||
'#states' => [
|
||||
'visible' => [
|
||||
[':input[name="fields[' . $fieldname . '][settings_edit_form][settings][audio_player]"]' => ['value' => 'wavesurfer_audio_player']],
|
||||
],
|
||||
],
|
||||
];
|
||||
$elements['audio_player_wavesurfer_barheight'] = [
|
||||
'#type' => 'number',
|
||||
'#title' => $this->t('Bar Height'),
|
||||
'#description' => $this->t("Height of the waveform bars. Higher number than 1 will increase the waveform bar heights."),
|
||||
'#default_value' => $this->getSetting('audio_player_wavesurfer_barheight'),
|
||||
'#states' => [
|
||||
'visible' => [
|
||||
[':input[name="fields[' . $fieldname . '][settings_edit_form][settings][audio_player]"]' => ['value' => 'wavesurfer_audio_player']],
|
||||
],
|
||||
],
|
||||
];
|
||||
$elements['audio_player_wavesurfer_barwidth'] = [
|
||||
'#type' => 'number',
|
||||
'#title' => $this->t('Bar Width'),
|
||||
'#description' => $this->t("If specified, the waveform will be drawn like this: ▁ ▂ ▇ ▃ ▅ ▂"),
|
||||
'#default_value' => $this->getSetting('audio_player_wavesurfer_barwidth'),
|
||||
'#states' => [
|
||||
'visible' => [
|
||||
[':input[name="fields[' . $fieldname . '][settings_edit_form][settings][audio_player]"]' => ['value' => 'wavesurfer_audio_player']],
|
||||
],
|
||||
],
|
||||
];
|
||||
$elements['audio_player_wavesurfer_cursorcolor'] = [
|
||||
'#type' => 'color',
|
||||
'#title' => $this->t('Cursor Color'),
|
||||
'#description' => $this->t("The fill color of the cursor indicating the playhead position."),
|
||||
'#default_value' => $this->getSetting('audio_player_wavesurfer_cursorcolor'),
|
||||
'#states' => [
|
||||
'visible' => [
|
||||
[':input[name="fields[' . $fieldname . '][settings_edit_form][settings][audio_player]"]' => ['value' => 'wavesurfer_audio_player']],
|
||||
],
|
||||
],
|
||||
];
|
||||
$elements['audio_player_wavesurfer_cursorwidth'] = [
|
||||
'#type' => 'number',
|
||||
'#title' => $this->t('Cursor Width'),
|
||||
'#description' => $this->t("Width of the cursor indicating the playhead position. Measured in pixels."),
|
||||
'#default_value' => $this->getSetting('audio_player_wavesurfer_cursorwidth'),
|
||||
'#states' => [
|
||||
'visible' => [
|
||||
[':input[name="fields[' . $fieldname . '][settings_edit_form][settings][audio_player]"]' => ['value' => 'wavesurfer_audio_player']],
|
||||
],
|
||||
],
|
||||
];
|
||||
$elements['audio_player_wavesurfer_forcedecode'] = [
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t('Force Decode'),
|
||||
'#description' => $this->t("Force decoding of audio using web audio when zooming to get a more detailed waveform."),
|
||||
'#default_value' => $this->getSetting('audio_player_wavesurfer_forcedecode'),
|
||||
'#states' => [
|
||||
'visible' => [
|
||||
[':input[name="fields[' . $fieldname . '][settings_edit_form][settings][audio_player]"]' => ['value' => 'wavesurfer_audio_player']],
|
||||
],
|
||||
],
|
||||
];
|
||||
$elements['audio_player_wavesurfer_normalize'] = [
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t('Normalize'),
|
||||
'#description' => $this->t("If checked, normalize by the maximum peak instead of 1.0."),
|
||||
'#default_value' => $this->getSetting('audio_player_wavesurfer_normalize'),
|
||||
'#states' => [
|
||||
'visible' => [
|
||||
[':input[name="fields[' . $fieldname . '][settings_edit_form][settings][audio_player]"]' => ['value' => 'wavesurfer_audio_player']],
|
||||
],
|
||||
],
|
||||
];
|
||||
$elements['audio_player_wavesurfer_progresscolor'] = [
|
||||
'#type' => 'color',
|
||||
'#title' => $this->t('Progress Color'),
|
||||
'#description' => $this->t("The fill color of the part of the waveform behind the cursor."),
|
||||
'#default_value' => $this->getSetting('audio_player_wavesurfer_progresscolor'),
|
||||
'#states' => [
|
||||
'visible' => [
|
||||
[':input[name="fields[' . $fieldname . '][settings_edit_form][settings][audio_player]"]' => ['value' => 'wavesurfer_audio_player']],
|
||||
],
|
||||
],
|
||||
];
|
||||
$elements['audio_player_wavesurfer_responsive'] = [
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t('Responsive'),
|
||||
'#description' => $this->t("If checked, resize the waveform, when the window is resized. This is debounced with a 100ms timeout by default."),
|
||||
'#default_value' => $this->getSetting('audio_player_wavesurfer_responsive'),
|
||||
'#states' => [
|
||||
'visible' => [
|
||||
[':input[name="fields[' . $fieldname . '][settings_edit_form][settings][audio_player]"]' => ['value' => 'wavesurfer_audio_player']],
|
||||
],
|
||||
],
|
||||
];
|
||||
$elements['audio_player_wavesurfer_wavecolor'] = [
|
||||
'#type' => 'color',
|
||||
'#title' => $this->t('Wave Color'),
|
||||
'#description' => $this->t("The fill color of the waveform after the cursor."),
|
||||
'#default_value' => $this->getSetting('audio_player_wavesurfer_wavecolor'),
|
||||
'#states' => [
|
||||
'visible' => [
|
||||
[':input[name="fields[' . $fieldname . '][settings_edit_form][settings][audio_player]"]' => ['value' => 'wavesurfer_audio_player']],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
// Settings for WordPress.
|
||||
// Only show when WordPress is the selected audio player.
|
||||
$elements['audio_player_wordpress_combine_files'] = [
|
||||
@@ -291,6 +425,42 @@ class AudioFieldFieldFormatter extends FormatterBase implements ContainerFactory
|
||||
$summary[] = $this->t('Combine files into single player? <strong>@combine</strong>', [
|
||||
'@combine' => ($settings['audio_player_wavesurfer_combine_files'] ? 'Yes' : 'No'),
|
||||
]);
|
||||
$summary[] = $this->t('Audio Rate: <strong>@value</strong>', [
|
||||
'@value' => $settings['audio_player_wavesurfer_audiorate'],
|
||||
]);
|
||||
$summary[] = $this->t('Auto Center? <strong>@value</strong>', [
|
||||
'@value' => ($settings['audio_player_wavesurfer_autocenter'] ? 'Yes' : 'No'),
|
||||
]);
|
||||
$summary[] = $this->t('Bar Gap: <strong>@value</strong>', [
|
||||
'@value' => $settings['audio_player_wavesurfer_bargap'],
|
||||
]);
|
||||
$summary[] = $this->t('Bar Height: <strong>@value</strong>', [
|
||||
'@value' => $settings['audio_player_wavesurfer_barheight'],
|
||||
]);
|
||||
$summary[] = $this->t('Bar Width: <strong>@value</strong>', [
|
||||
'@value' => $settings['audio_player_wavesurfer_barwidth'],
|
||||
]);
|
||||
$summary[] = $this->t('Cursor Color: <span style="border:1px solid black;height:10px;width:10px;display:inline-block;background:@value;"></span>', [
|
||||
'@value' => $settings['audio_player_wavesurfer_cursorcolor'],
|
||||
]);
|
||||
$summary[] = $this->t('Cursor Width: <strong>@value</strong>', [
|
||||
'@value' => $settings['audio_player_wavesurfer_cursorwidth'],
|
||||
]);
|
||||
$summary[] = $this->t('Force Decode? <strong>@value</strong>', [
|
||||
'@value' => ($settings['audio_player_wavesurfer_forcedecode'] ? 'Yes' : 'No'),
|
||||
]);
|
||||
$summary[] = $this->t('Normalize? <strong>@value</strong>', [
|
||||
'@value' => ($settings['audio_player_wavesurfer_normalize'] ? 'Yes' : 'No'),
|
||||
]);
|
||||
$summary[] = $this->t('Progress Color: <span style="border:1px solid black;height:10px;width:10px;display:inline-block;background:@value;"></span>', [
|
||||
'@value' => $settings['audio_player_wavesurfer_progresscolor'],
|
||||
]);
|
||||
$summary[] = $this->t('Responsive? <strong>@value</strong>', [
|
||||
'@value' => ($settings['audio_player_wavesurfer_responsive'] ? 'Yes' : 'No'),
|
||||
]);
|
||||
$summary[] = $this->t('Wave Color: <span style="border:1px solid black;height:10px;width:10px;display:inline-block;background:@value;"></span>', [
|
||||
'@value' => $settings['audio_player_wavesurfer_wavecolor'],
|
||||
]);
|
||||
}
|
||||
// If this is wordpress, add those settings.
|
||||
elseif ($settings['audio_player'] == 'wordpress_audio_player') {
|
||||
@@ -384,6 +554,18 @@ class AudioFieldFieldFormatter extends FormatterBase implements ContainerFactory
|
||||
'audio_player' => 'default_mp3_player',
|
||||
'audio_player_jplayer_theme' => 'none',
|
||||
'audio_player_wavesurfer_combine_files' => FALSE,
|
||||
'audio_player_wavesurfer_audiorate' => 1,
|
||||
'audio_player_wavesurfer_autocenter' => TRUE,
|
||||
'audio_player_wavesurfer_bargap' => 0,
|
||||
'audio_player_wavesurfer_barheight' => 1,
|
||||
'audio_player_wavesurfer_barwidth' => NULL,
|
||||
'audio_player_wavesurfer_cursorcolor' => '#333',
|
||||
'audio_player_wavesurfer_cursorwidth' => 1,
|
||||
'audio_player_wavesurfer_forcedecode' => FALSE,
|
||||
'audio_player_wavesurfer_normalize' => FALSE,
|
||||
'audio_player_wavesurfer_progresscolor' => '#555',
|
||||
'audio_player_wavesurfer_responsive' => FALSE,
|
||||
'audio_player_wavesurfer_wavecolor' => '#999',
|
||||
'audio_player_wordpress_combine_files' => FALSE,
|
||||
'audio_player_wordpress_animation' => TRUE,
|
||||
'audio_player_soundmanager_theme' => 'default',
|
||||
|
||||
+9
-3
@@ -4,10 +4,16 @@
|
||||
* Default theme implementation for AudioField audioplayer download links.
|
||||
*
|
||||
* Available variables:
|
||||
* - links: theme_item_list render array containing the download links for
|
||||
* an audiofield entity.
|
||||
* - links: downloa
|
||||
*
|
||||
* @ingroup themeable
|
||||
*/
|
||||
#}
|
||||
{{ links }}
|
||||
<table class="audiofield-downloads">
|
||||
<caption>{{ 'Download files:'|trans }}</caption>
|
||||
{% for file in links %}
|
||||
<tr>
|
||||
<td class="audiofield-download-link">{{ file.link }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
+18
-16
@@ -16,24 +16,26 @@
|
||||
|
||||
{% if settings.audio_player_jplayer_theme == 'audiofield.jplayer.theme_jplayer_circle' %}
|
||||
{% for file in files %}
|
||||
<div id="jquery_jplayer_{{ file.id }}" class="cp-jplayer"></div>
|
||||
<div class="cp-circle-frame">
|
||||
<div id="cp_container_{{ file.id }}" class="cp-container">
|
||||
<div class="cp-buffer-holder">
|
||||
<div class="cp-buffer-1"></div>
|
||||
<div class="cp-buffer-2"></div>
|
||||
<div class="audiofield-player">
|
||||
<div id="jquery_jplayer_{{ file.id }}" class="cp-jplayer"></div>
|
||||
<div class="cp-circle-frame">
|
||||
<div id="cp_container_{{ file.id }}" class="cp-container">
|
||||
<div class="cp-buffer-holder">
|
||||
<div class="cp-buffer-1"></div>
|
||||
<div class="cp-buffer-2"></div>
|
||||
</div>
|
||||
<div class="cp-progress-holder">
|
||||
<div class="cp-progress-1"></div>
|
||||
<div class="cp-progress-2"></div>
|
||||
</div>
|
||||
<div class="cp-circle-control"></div>
|
||||
<ul class="cp-controls">
|
||||
<li><a class="cp-play" tabindex="1">play</a></li>
|
||||
<li><a class="cp-pause" style="display:none;" tabindex="1">pause</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="cp-progress-holder">
|
||||
<div class="cp-progress-1"></div>
|
||||
<div class="cp-progress-2"></div>
|
||||
</div>
|
||||
<div class="cp-circle-control"></div>
|
||||
<ul class="cp-controls">
|
||||
<li><a class="cp-play" tabindex="1">play</a></li>
|
||||
<li><a class="cp-pause" style="display:none;" tabindex="1">pause</a></li>
|
||||
</ul>
|
||||
<label for="cp_container_{{ file.id }}">{{ file.description }}</label>
|
||||
</div>
|
||||
<label for="cp_container_{{ file.id }}">{{ file.description }}</label>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
+18
-16
@@ -14,24 +14,26 @@
|
||||
#}
|
||||
<div class="audiofield">
|
||||
{% for file in files %}
|
||||
<div id="jquery_jplayer_{{ file.id }}" class="cp-jplayer"></div>
|
||||
<div class="cp-circle-frame">
|
||||
<div id="cp_container_{{ file.id }}" class="cp-container">
|
||||
<div class="cp-buffer-holder">
|
||||
<div class="cp-buffer-1"></div>
|
||||
<div class="cp-buffer-2"></div>
|
||||
<div class="audiofield-player">
|
||||
<div id="jquery_jplayer_{{ file.id }}" class="cp-jplayer"></div>
|
||||
<div class="cp-circle-frame">
|
||||
<div id="cp_container_{{ file.id }}" class="cp-container">
|
||||
<div class="cp-buffer-holder">
|
||||
<div class="cp-buffer-1"></div>
|
||||
<div class="cp-buffer-2"></div>
|
||||
</div>
|
||||
<div class="cp-progress-holder">
|
||||
<div class="cp-progress-1"></div>
|
||||
<div class="cp-progress-2"></div>
|
||||
</div>
|
||||
<div class="cp-circle-control"></div>
|
||||
<ul class="cp-controls">
|
||||
<li><a class="cp-play" tabindex="1">play</a></li>
|
||||
<li><a class="cp-pause" style="display:none;" tabindex="1">pause</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="cp-progress-holder">
|
||||
<div class="cp-progress-1"></div>
|
||||
<div class="cp-progress-2"></div>
|
||||
</div>
|
||||
<div class="cp-circle-control"></div>
|
||||
<ul class="cp-controls">
|
||||
<li><a class="cp-play" tabindex="1">play</a></li>
|
||||
<li><a class="cp-pause" style="display:none;" tabindex="1">pause</a></li>
|
||||
</ul>
|
||||
<label for="cp_container_{{ file.id }}">{{ file.description }}</label>
|
||||
</div>
|
||||
<label for="cp_container_{{ file.id }}">{{ file.description }}</label>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
+8
-6
@@ -14,12 +14,14 @@
|
||||
#}
|
||||
<div class="audiofield">
|
||||
{% for file in files %}
|
||||
<div class="mediaelementaudio_frame">
|
||||
<audio id="mediaelement_player_{{ file.id }}" preload="{% if settings.audio_player_lazyload == 1 %}none{% else %}auto{% endif %}" {% if settings.audio_player_autoplay == 1 %} autoplay="autoplay" {% endif %} controls>
|
||||
<source src="{{ file.url }}">
|
||||
Your browser does not support the audio element.
|
||||
</audio>
|
||||
<div class="audiofield-player">
|
||||
<div class="mediaelementaudio_frame">
|
||||
<audio id="mediaelement_player_{{ file.id }}" preload="{% if settings.audio_player_lazyload == 1 %}none{% else %}auto{% endif %}" {% if settings.audio_player_autoplay == 1 %} autoplay="autoplay" {% endif %} controls>
|
||||
<source src="{{ file.url }}">
|
||||
Your browser does not support the audio element.
|
||||
</audio>
|
||||
</div>
|
||||
<label for="mediaelement_player_{{ file.id }}">{{ file.description }}</label>
|
||||
</div>
|
||||
<label for="mediaelement_player_{{ file.id }}">{{ file.description }}</label>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
+7
-5
@@ -14,10 +14,12 @@
|
||||
#}
|
||||
<div class="audiofield">
|
||||
{% for file in files %}
|
||||
<audio id="{{ file.id }}" preload="{% if settings.audio_player_lazyload == 1 %}none{% else %}auto{% endif %}" class="audiofield-{{ plugin_id }} {{ plugin_id }}" controls>
|
||||
<source src="{{ file.url }}" type="audio/mpeg">
|
||||
Your browser does not support the audio element.
|
||||
</audio>
|
||||
<label>{{ file.description }}</label>
|
||||
<div class="audiofield-player">
|
||||
<audio id="{{ file.id }}" preload="{% if settings.audio_player_lazyload == 1 %}none{% else %}auto{% endif %}" class="audiofield-{{ plugin_id }} {{ plugin_id }}" controls>
|
||||
<source src="{{ file.url }}" type="audio/mpeg">
|
||||
Your browser does not support the audio element.
|
||||
</audio>
|
||||
<label>{{ file.description }}</label>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
+2
-2
@@ -19,7 +19,7 @@
|
||||
<div class="sm2-inline-gradient"></div>
|
||||
<div class="sm2-inline-element sm2-button-element">
|
||||
<div class="sm2-button-bd">
|
||||
<a href="#play" class="sm2-inline-button play-pause">Play / pause</a>
|
||||
<a href="#play" class="sm2-inline-button sm2-icon-play-pause">Play / pause</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sm2-inline-element sm2-inline-status">
|
||||
@@ -47,7 +47,7 @@
|
||||
</div>
|
||||
<div class="sm2-inline-element sm2-button-element sm2-menu">
|
||||
<div class="sm2-button-bd">
|
||||
<a href="#menu" class="sm2-inline-button menu">menu</a>
|
||||
<a href="#menu" class="sm2-inline-button sm2-icon-menu">menu</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -14,10 +14,12 @@
|
||||
#}
|
||||
<div class="audiofield">
|
||||
{% for file in files %}
|
||||
<audio preload="{% if settings.audio_player_lazyload == 1 %}none{% else %}auto{% endif %}" controls {% if settings.audio_player_autoplay == 1 %} autoplay {% endif %} {% if settings.download_button != 1 %} controlsList="nodownload" {% endif %}>
|
||||
<source src="{{ file.url }}" type="audio/mpeg">
|
||||
Your browser does not support the audio element.
|
||||
</audio>
|
||||
<label>{{ file.description }}</label>
|
||||
<div class="audiofield-player">
|
||||
<audio preload="{% if settings.audio_player_lazyload == 1 %}none{% else %}auto{% endif %}" controls {% if settings.audio_player_autoplay == 1 %} autoplay {% endif %} {% if settings.download_button != 1 %} controlsList="nodownload" {% endif %}>
|
||||
<source src="{{ file.url }}" type="audio/mpeg">
|
||||
Your browser does not support the audio element.
|
||||
</audio>
|
||||
<label>{{ file.description }}</label>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
@@ -45,6 +45,8 @@ linkit.matcher.entity:
|
||||
type: boolean
|
||||
substitution_type:
|
||||
type: string
|
||||
limit:
|
||||
type: integer
|
||||
|
||||
linkit.matcher.entity:*:
|
||||
type: linkit.matcher.entity
|
||||
|
||||
@@ -7,8 +7,8 @@ configure: entity.linkit_profile.collection
|
||||
test_dependencies:
|
||||
- imce
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-03-08
|
||||
version: '8.x-5.0-beta7'
|
||||
# Information added by Drupal.org packaging script on 2018-12-28
|
||||
version: '8.x-5.0-beta8'
|
||||
core: '8.x'
|
||||
project: 'linkit'
|
||||
datestamp: 1520552594
|
||||
datestamp: 1545966788
|
||||
|
||||
@@ -28,8 +28,6 @@ class Matcher extends Plugin {
|
||||
/**
|
||||
* The human-readable name of the matcher.
|
||||
*
|
||||
* The string should be wrapped in a @Translation().
|
||||
*
|
||||
* @var \Drupal\Core\Annotation\Translation
|
||||
*/
|
||||
public $label;
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Drupal\linkit\Controller;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\linkit\SuggestionManager;
|
||||
@@ -77,7 +76,7 @@ class AutocompleteController implements ContainerInjectionInterface {
|
||||
$this->linkitProfile = $this->linkitProfileStorage->load($linkit_profile_id);
|
||||
$string = $request->query->get('q');
|
||||
|
||||
$suggestionCollection = $this->suggestionManager->getSuggestions($this->linkitProfile, Unicode::strtolower($string));
|
||||
$suggestionCollection = $this->suggestionManager->getSuggestions($this->linkitProfile, mb_strtolower($string));
|
||||
|
||||
/*
|
||||
* If there are no suggestions from the matcher plugins, we have to add a
|
||||
|
||||
@@ -26,6 +26,7 @@ class Linkit extends FormElement {
|
||||
'#process' => [
|
||||
[$class, 'processLinkitAutocomplete'],
|
||||
[$class, 'processGroup'],
|
||||
[$class, 'processAjaxForm'],
|
||||
],
|
||||
'#pre_render' => [
|
||||
[$class, 'preRenderLinkitElement'],
|
||||
|
||||
@@ -120,7 +120,7 @@ class AddForm extends FormBase {
|
||||
]);
|
||||
}
|
||||
else {
|
||||
drupal_set_message($this->t('Added %label matcher.', ['%label' => $plugin->getLabel()]));
|
||||
$this->messenger()->addMessage($this->t('Added %label matcher.', ['%label' => $plugin->getLabel()]));
|
||||
|
||||
$form_state->setRedirect('linkit.matchers', [
|
||||
'linkit_profile' => $this->linkitProfile->id(),
|
||||
|
||||
@@ -70,7 +70,7 @@ class DeleteForm extends ConfirmFormBase {
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
$this->linkitProfile->removeMatcher($this->linkitMatcher);
|
||||
|
||||
drupal_set_message($this->t('The matcher %label has been deleted.', ['%label' => $this->linkitMatcher->getLabel()]));
|
||||
$this->messenger()->addMessage($this->t('The matcher %label has been deleted.', ['%label' => $this->linkitMatcher->getLabel()]));
|
||||
$this->logger('linkit')->notice('The matcher %label has been deleted in the @profile profile.', [
|
||||
'%label' => $this->linkitMatcher->getLabel(),
|
||||
'@profile' => $this->linkitProfile->label(),
|
||||
|
||||
@@ -74,7 +74,7 @@ class EditForm extends FormBase {
|
||||
$this->linkitMatcher->submitConfigurationForm($form, $plugin_data);
|
||||
$this->linkitProfile->save();
|
||||
|
||||
drupal_set_message($this->t('Saved %label configuration.', ['%label' => $this->linkitMatcher->getLabel()]));
|
||||
$this->messenger()->addMessage($this->t('Saved %label configuration.', ['%label' => $this->linkitMatcher->getLabel()]));
|
||||
$this->logger('linkit')->notice('The matcher %label has been updated in the @profile profile.', [
|
||||
'%label' => $this->linkitMatcher->getLabel(),
|
||||
'@profile' => $this->linkitProfile->label(),
|
||||
|
||||
@@ -7,7 +7,7 @@ use Drupal\Core\Form\FormStateInterface;
|
||||
/**
|
||||
* Controller for profile addition forms.
|
||||
*
|
||||
* @see \Drupal\linkit\Profile\FormBase
|
||||
* @see \Drupal\linkit\Form\Profile\FormBase
|
||||
*/
|
||||
class AddForm extends FormBase {
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ use Drupal\Core\Form\FormStateInterface;
|
||||
/**
|
||||
* Provides an edit form for profile.
|
||||
*
|
||||
* @see \Drupal\linkit\Profile\FormBase
|
||||
* @see \Drupal\linkit\Form\Profile\FormBase
|
||||
*/
|
||||
class EditForm extends FormBase {
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ abstract class FormBase extends EntityForm {
|
||||
$edit_link = $this->entity->toLink($this->t('Edit'), 'edit-form')->toString();
|
||||
switch ($status) {
|
||||
case SAVED_NEW:
|
||||
drupal_set_message($this->t('Created new profile %label.', ['%label' => $linkit_profile->label()]));
|
||||
$this->messenger()->addMessage($this->t('Created new profile %label.', ['%label' => $linkit_profile->label()]));
|
||||
$this->logger('linkit')->notice('Created new profile %label.', ['%label' => $linkit_profile->label(), 'link' => $edit_link]);
|
||||
$form_state->setRedirect('linkit.matchers', [
|
||||
'linkit_profile' => $linkit_profile->id(),
|
||||
@@ -75,7 +75,7 @@ abstract class FormBase extends EntityForm {
|
||||
break;
|
||||
|
||||
case SAVED_UPDATED:
|
||||
drupal_set_message($this->t('Updated profile %label.', ['%label' => $linkit_profile->label()]));
|
||||
$this->messenger()->addMessage($this->t('Updated profile %label.', ['%label' => $linkit_profile->label()]));
|
||||
$this->logger('linkit')->notice('Updated profile %label.', ['%label' => $linkit_profile->label(), 'link' => $edit_link]);
|
||||
$form_state->setRedirectUrl($linkit_profile->toUrl('edit-form'));
|
||||
break;
|
||||
|
||||
@@ -36,6 +36,11 @@ class EntityMatcher extends ConfigurableMatcherBase {
|
||||
|
||||
use MatcherTokensTrait;
|
||||
|
||||
/**
|
||||
* The default limit for matches.
|
||||
*/
|
||||
const DEFAULT_LIMIT = 100;
|
||||
|
||||
/**
|
||||
* The database connection.
|
||||
*
|
||||
@@ -161,6 +166,12 @@ class EntityMatcher extends ConfigurableMatcherBase {
|
||||
$summery[] = $this->t('Group by bundle: @bundle_grouping', [
|
||||
'@bundle_grouping' => $this->configuration['group_by_bundle'] ? $this->t('Yes') : $this->t('No'),
|
||||
]);
|
||||
|
||||
if (!empty($this->configuration['limit'])) {
|
||||
$summery[] = $this->t('Limit: @limit', [
|
||||
'@limit' => $this->configuration['limit'],
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
return $summery;
|
||||
@@ -175,6 +186,7 @@ class EntityMatcher extends ConfigurableMatcherBase {
|
||||
'bundles' => [],
|
||||
'group_by_bundle' => FALSE,
|
||||
'substitution_type' => SubstitutionManagerInterface::DEFAULT_SUBSTITUTION,
|
||||
'limit' => static::DEFAULT_LIMIT,
|
||||
] + parent::defaultConfiguration();
|
||||
}
|
||||
|
||||
@@ -257,6 +269,25 @@ class EntityMatcher extends ConfigurableMatcherBase {
|
||||
'#description' => $this->t('Configure how the selected entity should be transformed into a URL for insertion.'),
|
||||
];
|
||||
|
||||
$form['limit'] = [
|
||||
'#type' => 'details',
|
||||
'#title' => $this->t('Limit'),
|
||||
'#open' => TRUE,
|
||||
];
|
||||
|
||||
$form['limit']['limit'] = [
|
||||
'#type' => 'select',
|
||||
'#options' => [
|
||||
0 => $this->t('Unlimited'),
|
||||
20 => 20,
|
||||
50 => 50,
|
||||
100 => 100,
|
||||
200 => 200,
|
||||
],
|
||||
'#title' => $this->t('Limit search results'),
|
||||
'#description' => $this->t('Limit the amount of results displayed when searching.'),
|
||||
'#default_value' => $this->configuration['limit'],
|
||||
];
|
||||
return $form;
|
||||
}
|
||||
|
||||
@@ -274,6 +305,7 @@ class EntityMatcher extends ConfigurableMatcherBase {
|
||||
$this->configuration['bundles'] = $form_state->getValue('bundles');
|
||||
$this->configuration['group_by_bundle'] = $form_state->getValue('group_by_bundle');
|
||||
$this->configuration['substitution_type'] = $form_state->getValue('substitution_type');
|
||||
$this->configuration['limit'] = $form_state->getValue('limit');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -353,6 +385,9 @@ class EntityMatcher extends ConfigurableMatcherBase {
|
||||
$query->condition($bundle_key, $this->configuration['bundles'], 'IN');
|
||||
}
|
||||
|
||||
if ($this->configuration['limit']) {
|
||||
$query->range(0, $this->configuration['limit']);
|
||||
}
|
||||
$this->addQueryTags($query);
|
||||
|
||||
return $query;
|
||||
|
||||
@@ -190,22 +190,30 @@ class FileMatcher extends EntityMatcher {
|
||||
/** @var \Drupal\file\FileInterface $entity */
|
||||
$file = $entity->getFileUri();
|
||||
|
||||
/** @var \Drupal\Core\Image\ImageInterface $image */
|
||||
$image = \Drupal::service('image.factory')->get($file);
|
||||
if ($image->isValid()) {
|
||||
if ($this->configuration['images']['show_dimensions']) {
|
||||
$description_array[] = $image->getWidth() . 'x' . $image->getHeight() . 'px';
|
||||
}
|
||||
if ($this->configuration['images']['show_dimensions'] || $this->configuration['images']['show_thumbnail']) {
|
||||
$image_factory = \Drupal::service('image.factory');
|
||||
$supported_extensions = $image_factory->getSupportedExtensions();
|
||||
|
||||
if ($this->configuration['images']['show_thumbnail'] && $this->moduleHandler->moduleExists('image')) {
|
||||
$image_element = [
|
||||
'#weight' => -10,
|
||||
'#theme' => 'image_style',
|
||||
'#style_name' => $this->configuration['images']['thumbnail_image_style'],
|
||||
'#uri' => $entity->getFileUri(),
|
||||
];
|
||||
// Check if the file extension is supported by the image toolkit.
|
||||
if (empty(file_validate_extensions($entity, implode(' ', $supported_extensions)))) {
|
||||
/** @var \Drupal\Core\Image\ImageInterface $image */
|
||||
$image = $image_factory->get($file);
|
||||
if ($image->isValid()) {
|
||||
if ($this->configuration['images']['show_dimensions']) {
|
||||
$description_array[] = $image->getWidth() . 'x' . $image->getHeight() . 'px';
|
||||
}
|
||||
|
||||
$description_array[] = (string) \Drupal::service('renderer')->render($image_element);
|
||||
if ($this->configuration['images']['show_thumbnail'] && $this->moduleHandler->moduleExists('image')) {
|
||||
$image_element = [
|
||||
'#weight' => -10,
|
||||
'#theme' => 'image_style',
|
||||
'#style_name' => $this->configuration['images']['thumbnail_image_style'],
|
||||
'#uri' => $entity->getFileUri(),
|
||||
];
|
||||
|
||||
$description_array[] = (string) \Drupal::service('renderer')->render($image_element);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace Drupal\linkit\Plugin\Linkit\Matcher;
|
||||
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\node\NodeInterface;
|
||||
|
||||
/**
|
||||
* Provides specific linkit matchers for the node entity type.
|
||||
@@ -84,9 +85,27 @@ class NodeMatcher extends EntityMatcher {
|
||||
protected function buildEntityQuery($search_string) {
|
||||
$query = parent::buildEntityQuery($search_string);
|
||||
|
||||
$no_access = !$this->currentUser->hasPermission('bypass node access') && !count($this->moduleHandler->getImplementations('node_grants'));
|
||||
if ($this->configuration['include_unpublished'] !== TRUE || $no_access) {
|
||||
$query->condition('status', NODE_PUBLISHED);
|
||||
if ($this->configuration['include_unpublished'] == FALSE) {
|
||||
$query->condition('status', NodeInterface::PUBLISHED);
|
||||
}
|
||||
elseif (count($this->moduleHandler->getImplementations('node_grants')) === 0) {
|
||||
if (($this->currentUser->hasPermission('bypass node access') || $this->currentUser->hasPermission('view any unpublished content'))) {
|
||||
// User can see all content, no check necessary.
|
||||
}
|
||||
elseif ($this->currentUser->hasPermission('view own unpublished content')) {
|
||||
// Users with "view own unpublished content" can see only their own.
|
||||
if ($this->configuration['include_unpublished'] == TRUE) {
|
||||
$or_condition = $query
|
||||
->orConditionGroup()
|
||||
->condition('status', NodeInterface::PUBLISHED)
|
||||
->condition('uid', $this->currentUser->id());
|
||||
$query->condition($or_condition);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// All other users should only get published results.
|
||||
$query->condition('status', NodeInterface::PUBLISHED);
|
||||
}
|
||||
|
||||
return $query;
|
||||
|
||||
@@ -5,7 +5,6 @@ namespace Drupal\linkit\Plugin\Linkit\Substitution;
|
||||
use Drupal\Component\Plugin\PluginBase;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Entity\EntityTypeManager;
|
||||
use Drupal\Core\GeneratedUrl;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\linkit\SubstitutionInterface;
|
||||
@@ -21,30 +20,6 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
*/
|
||||
class Media extends PluginBase implements SubstitutionInterface, ContainerFactoryPluginInterface {
|
||||
|
||||
/**
|
||||
* The entity type manager.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityTypeManager
|
||||
*/
|
||||
protected $entityTypeManager;
|
||||
|
||||
/**
|
||||
* Constructs a Media object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\Core\Entity\EntityTypeManager $entity_type_manager
|
||||
* The entity type manager.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManager $entity_type_manager) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
$this->entityTypeManager = $entity_type_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Drupal\linkit\Tests;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\linkit\Entity\Profile;
|
||||
|
||||
/**
|
||||
@@ -29,7 +28,7 @@ trait ProfileCreationTrait {
|
||||
protected function createProfile(array $settings = []) {
|
||||
// Populate defaults array.
|
||||
$settings += [
|
||||
'id' => Unicode::strtolower($this->randomMachineName()),
|
||||
'id' => mb_strtolower($this->randomMachineName()),
|
||||
'label' => $this->randomMachineName(),
|
||||
];
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@ dependencies:
|
||||
- drupal:field
|
||||
- drupal:text
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-03-08
|
||||
version: '8.x-5.0-beta7'
|
||||
# Information added by Drupal.org packaging script on 2018-12-28
|
||||
version: '8.x-5.0-beta8'
|
||||
core: '8.x'
|
||||
project: 'linkit'
|
||||
datestamp: 1520552594
|
||||
datestamp: 1545966788
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Drupal\Tests\linkit\Functional;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\linkit\Tests\ProfileCreationTrait;
|
||||
|
||||
/**
|
||||
@@ -62,8 +61,8 @@ class ProfileAdminTest extends LinkitBrowserTestBase {
|
||||
|
||||
// Create a profile.
|
||||
$edit = [];
|
||||
$edit['label'] = Unicode::strtolower($this->randomMachineName());
|
||||
$edit['id'] = Unicode::strtolower($this->randomMachineName());
|
||||
$edit['label'] = mb_strtolower($this->randomMachineName());
|
||||
$edit['id'] = mb_strtolower($this->randomMachineName());
|
||||
$edit['description'] = $this->randomMachineName(16);
|
||||
$this->submitForm($edit, t('Save and manage matchers'));
|
||||
|
||||
|
||||
+24
-2
@@ -5,7 +5,6 @@ namespace Drupal\Tests\linkit\Kernel;
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\Component\Serialization\Json;
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\entity_test\Entity\EntityTestMul;
|
||||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
@@ -153,6 +152,29 @@ class LinkitAutocompleteTest extends LinkitKernelTestBase {
|
||||
$this->assertEmpty(count($data), 'Autocomplete did not return any suggestions.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests autocompletion with results limit.
|
||||
*/
|
||||
public function testAutocompletionWithLimit() {
|
||||
/** @var \Drupal\linkit\MatcherInterface $plugin */
|
||||
$plugin = $this->matcherManager->createInstance('entity:entity_test');
|
||||
$configuration = $plugin->getConfiguration();
|
||||
$configuration['settings']['limit'] = 2;
|
||||
|
||||
$this->linkitProfile->addMatcher($configuration);
|
||||
$this->linkitProfile->save();
|
||||
|
||||
$entity_1 = EntityTest::create(['name' => 'foo 1']);
|
||||
$entity_1->save();
|
||||
$entity_2 = EntityTest::create(['name' => 'foo 2']);
|
||||
$entity_2->save();
|
||||
$entity_3 = EntityTest::create(['name' => 'foo 3']);
|
||||
$entity_3->save();
|
||||
|
||||
$data = $this->getAutocompleteResult('foo');
|
||||
$this->assertTrue(count($data) == 2, 'Autocomplete returned the expected amount of suggestions.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests autocompletion with translated entities.
|
||||
*/
|
||||
@@ -221,7 +243,7 @@ class LinkitAutocompleteTest extends LinkitKernelTestBase {
|
||||
protected function createProfile(array $settings = []) {
|
||||
// Populate defaults array.
|
||||
$settings += [
|
||||
'id' => Unicode::strtolower($this->randomMachineName()),
|
||||
'id' => mb_strtolower($this->randomMachineName()),
|
||||
'label' => $this->randomMachineName(),
|
||||
];
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ abstract class LinkitKernelTestBase extends KernelTestBase {
|
||||
if ($permissions) {
|
||||
// Create a new role and apply permissions to it.
|
||||
$role = Role::create([
|
||||
'id' => strtolower($this->randomMachineName(8)),
|
||||
'id' => mb_strtolower($this->randomMachineName(8)),
|
||||
'label' => $this->randomMachineName(8),
|
||||
]);
|
||||
$role->save();
|
||||
|
||||
+25
-2
@@ -18,7 +18,7 @@ class NodeMatcherTest extends LinkitKernelTestBase {
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['field', 'node'];
|
||||
public static $modules = ['field', 'node', 'content_moderation', 'workflows'];
|
||||
|
||||
/**
|
||||
* The matcher manager.
|
||||
@@ -34,6 +34,7 @@ class NodeMatcherTest extends LinkitKernelTestBase {
|
||||
parent::setUp();
|
||||
|
||||
$this->installEntitySchema('node');
|
||||
$this->installSchema('node', ['node_access']);
|
||||
$this->installConfig(['field', 'node']);
|
||||
|
||||
$this->manager = $this->container->get('plugin.manager.linkit.matcher');
|
||||
@@ -74,7 +75,7 @@ class NodeMatcherTest extends LinkitKernelTestBase {
|
||||
]);
|
||||
$node->save();
|
||||
|
||||
// Unpublished node.
|
||||
// Unpublished nodes.
|
||||
$node = Node::create([
|
||||
'title' => 'Lorem unpublishd',
|
||||
'type' => $type1->id(),
|
||||
@@ -82,6 +83,13 @@ class NodeMatcherTest extends LinkitKernelTestBase {
|
||||
]);
|
||||
$node->save();
|
||||
|
||||
$node = Node::create([
|
||||
'title' => 'Lorem unpublishd 2',
|
||||
'type' => $type2->id(),
|
||||
'status' => FALSE,
|
||||
]);
|
||||
$node->save();
|
||||
|
||||
// Set the current user to someone that is not the node owner.
|
||||
\Drupal::currentUser()->setAccount($this->createUser([], ['access content']));
|
||||
}
|
||||
@@ -133,7 +141,22 @@ class NodeMatcherTest extends LinkitKernelTestBase {
|
||||
|
||||
// Test with permissions to see unpublished nodes.
|
||||
$suggestions = $plugin->execute('Lorem');
|
||||
$this->assertEquals(5, count($suggestions->getSuggestions()), 'Correct number of suggestions');
|
||||
|
||||
// Test with permissions to see own unpublished nodes.
|
||||
\Drupal::currentUser()->setAccount($this->createUser([], ['access content', 'view own unpublished content']));
|
||||
$nodes = $this->container->get('entity_type.manager')->getStorage('node')->loadByProperties(['title' => 'Lorem unpublishd']);
|
||||
$node4 = reset($nodes);
|
||||
/** @var \Drupal\node\NodeInterface $node4 */
|
||||
$node4->setOwnerId(\Drupal::currentUser()->id());
|
||||
$node4->save();
|
||||
$suggestions = $plugin->execute('Lorem');
|
||||
$this->assertEquals(4, count($suggestions->getSuggestions()), 'Correct number of suggestions');
|
||||
|
||||
// Test with permissions to see any unpublished nodes.
|
||||
\Drupal::currentUser()->setAccount($this->createUser([], ['access content', 'view any unpublished content']));
|
||||
$suggestions = $plugin->execute('Lorem');
|
||||
$this->assertEquals(5, count($suggestions->getSuggestions()), 'Correct number of suggestions');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+1
-2
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Drupal\Tests\linkit\Kernel\Matchers;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\taxonomy\VocabularyInterface;
|
||||
use Drupal\Tests\linkit\Kernel\LinkitKernelTestBase;
|
||||
@@ -118,7 +117,7 @@ class TermMatcherTest extends LinkitKernelTestBase {
|
||||
$vocabulary = $vocabularyStorage->create([
|
||||
'name' => $name,
|
||||
'description' => $name,
|
||||
'vid' => Unicode::strtolower($name),
|
||||
'vid' => mb_strtolower($name),
|
||||
'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
|
||||
]);
|
||||
$vocabulary->save();
|
||||
|
||||
Reference in New Issue
Block a user