From bb0db591b251915e34cf605a42856a63fa802226 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20St=C3=B6ckler?= <tstoeckler@gmail.com> Date: Fri, 16 Oct 2015 14:31:22 +0200 Subject: [PATCH] Make it possible for asset libraries to return more than one core library --- libraries.module | 8 +- src/ExternalLibrary/Asset/AssetLibrary.php | 2 +- .../Asset/AssetLibraryInterface.php | 17 ++--- ...yTrait.php => SingleAssetLibraryTrait.php} | 74 +++++++++++-------- .../InvalidLibraryDependencyException.php | 49 ++++++++++++ .../LibraryClassNotFoundException.php | 3 +- .../LibraryDefinitionNotFoundException.php | 3 +- .../Utility/DependencyAccessorTrait.php | 32 ++++++++ .../Utility/LibraryAccessorTrait.php | 32 ++++++++ .../LibraryIdAccessorTrait.php} | 8 +- 10 files changed, 175 insertions(+), 53 deletions(-) rename src/ExternalLibrary/Asset/{AssetLibraryTrait.php => SingleAssetLibraryTrait.php} (54%) create mode 100644 src/ExternalLibrary/Exception/InvalidLibraryDependencyException.php create mode 100644 src/ExternalLibrary/Utility/DependencyAccessorTrait.php create mode 100644 src/ExternalLibrary/Utility/LibraryAccessorTrait.php rename src/ExternalLibrary/{Exception/LibraryExceptionTrait.php => Utility/LibraryIdAccessorTrait.php} (62%) diff --git a/libraries.module b/libraries.module index 4241a92..4e5cc39 100644 --- a/libraries.module +++ b/libraries.module @@ -19,13 +19,7 @@ function libraries_library_info_build() { $core_libraries = []; foreach ($library_manager->getRequiredLibraries() as $external_library) { if ($external_library instanceof AssetLibraryInterface) { - // Do not use AssetLibraryInterface::getAttachableAssetLibraryId() here - // because the module name is automatically prepended. - // - // The following means that the library namespace of this module is - // completely exhausted by the external library space. It should never - // provide any core asset libraries of its own. - $core_libraries[$external_library->getId()] = $external_library->toAttachableAssetLibrary(); + $core_libraries += $external_library->getAttachableAssetLibraries(); } } return $core_libraries; diff --git a/src/ExternalLibrary/Asset/AssetLibrary.php b/src/ExternalLibrary/Asset/AssetLibrary.php index 5cbfc20..55bab67 100644 --- a/src/ExternalLibrary/Asset/AssetLibrary.php +++ b/src/ExternalLibrary/Asset/AssetLibrary.php @@ -15,7 +15,7 @@ use Drupal\libraries\ExternalLibrary\ExternalLibraryTrait; class AssetLibrary implements AssetLibraryInterface { use ExternalLibraryTrait; - use AssetLibraryTrait; + use SingleAssetLibraryTrait; /** * {@inheritdoc} diff --git a/src/ExternalLibrary/Asset/AssetLibraryInterface.php b/src/ExternalLibrary/Asset/AssetLibraryInterface.php index dc37651..97aac92 100644 --- a/src/ExternalLibrary/Asset/AssetLibraryInterface.php +++ b/src/ExternalLibrary/Asset/AssetLibraryInterface.php @@ -18,22 +18,19 @@ use Drupal\libraries\ExternalLibrary\ExternalLibraryInterface; */ interface AssetLibraryInterface extends ExternalLibraryInterface { - /** - * Gets the ID of the respective core asset library. - * - * @return string - * - * @todo Reconsider this method. - */ - public function getAttachableAssetLibraryId(); - /** * Returns a core asset library array structure for this library. * * @return array * + * @see libraries_library_info_build() + * @see \Drupal\libraries\ExternalLibrary\Asset\SingleAssetLibraryTrait + * + * @throws \Drupal\libraries\ExternalLibrary\Exception\InvalidLibraryDependencyException + * @throws \LogicException + * * @todo Document the return value. */ - public function toAttachableAssetLibrary(); + public function getAttachableAssetLibraries(); } diff --git a/src/ExternalLibrary/Asset/AssetLibraryTrait.php b/src/ExternalLibrary/Asset/SingleAssetLibraryTrait.php similarity index 54% rename from src/ExternalLibrary/Asset/AssetLibraryTrait.php rename to src/ExternalLibrary/Asset/SingleAssetLibraryTrait.php index c73d3cb..9bc44ef 100644 --- a/src/ExternalLibrary/Asset/AssetLibraryTrait.php +++ b/src/ExternalLibrary/Asset/SingleAssetLibraryTrait.php @@ -7,51 +7,69 @@ namespace Drupal\libraries\ExternalLibrary\Asset; +use Drupal\libraries\ExternalLibrary\Exception\InvalidLibraryDependencyException; use Drupal\libraries\ExternalLibrary\ExternalLibraryInterface; /** - * Provides a trait for asset libraries. + * Provides a trait for external libraries that contain a single asset library. * * @see \Drupal\libraries\ExternalLibrary\Asset\AssetLibraryInterface * @see \Drupal\libraries\ExternalLibrary\ExternalLibraryInterface */ -trait AssetLibraryTrait { - - /** - * Gets the ID of the respective core asset library. - * - * @return string - * - * @see \Drupal\libraries\ExternalLibrary\Asset\AssetLibraryInterface::getAttachableAssetLibraryId() - */ - public function getAttachableAssetLibraryId() { - return 'libraries/' . $this->getId(); - } +trait SingleAssetLibraryTrait { /** * Returns a core library array structure for this library. * * @return array * - * @see \Drupal\libraries\ExternalLibrary\Asset\AssetLibraryInterface::toAttachableAssetLibrary() + * @see \Drupal\libraries\ExternalLibrary\Asset\getAttachableAssetLibraries::getAttachableAssetLibraries() + * + * @throws \Drupal\libraries\ExternalLibrary\Exception\InvalidLibraryDependencyException + * @throws \LogicException * * @todo Document the return value. */ - public function toAttachableAssetLibrary() { - $dependencies = array_map(function (ExternalLibraryInterface $dependency) { - // Asset libraries depending on PHP file libraries, for example, are not - // compatible with Drupal's render pipeline. - // @todo Consider doing something other than an assertion. - assert('$dependency instanceof \Drupal\libraries\ExternalLibrary\Asset\AssetLibraryInterface'); - /** @var \Drupal\libraries\ExternalLibrary\Asset\AssetLibraryInterface $dependency */ - return $dependency->getAttachableAssetLibraryId(); - }, $this->getDependencies()); - return [ + public function getAttachableAssetLibraries() { + return [$this->getId() => [ 'version' => $this->getVersion(), 'css' => $this->getCssAssets(), 'js' => $this->getJsAssets(), - 'dependencies' => $dependencies, - ]; + 'dependencies' => $this->processDependencies($this->getDependencies()), + ]]; + } + + /** + * Processes a list of dependencies into a list of attachable library IDs. + * + * @param \Drupal\libraries\ExternalLibrary\ExternalLibraryInterface[] $dependencies + * An list of external libraries. + * + * @return string[] + * A list of attachable asset library IDs. + * + * @throws \Drupal\libraries\ExternalLibrary\Exception\InvalidLibraryDependencyException + * @throws \LogicException + */ + protected function processDependencies(array $dependencies) { + $attachable_dependency_ids = []; + foreach ($dependencies as $dependency) { + if (!$dependency instanceof AssetLibraryInterface) { + if (!$this instanceof ExternalLibraryInterface) { + $trait = self::class; + $interface = ExternalLibraryInterface::class; + throw new \LogicException("$trait may only be used in classes implementing $interface"); + } + /** @var \Drupal\libraries\ExternalLibrary\ExternalLibraryInterface $this */ + throw new InvalidLibraryDependencyException($this, $dependency); + } + + foreach (array_keys($dependency->getAttachableAssetLibraries()) as $attachable_dependency_id) { + // @todo It is not very elegant to hard-code the namespace here. + $attachable_dependency_ids[] = 'libraries/' . $attachable_dependency_id; + } + } + return $attachable_dependency_ids; } /** @@ -97,7 +115,7 @@ trait AssetLibraryTrait { * @see https://smacss.com/ * * @todo Expand documentation. - * @todo Consider moving this back to AssetLibraryInterface + * @todo Consider adding separate methods for the CSS categories. */ abstract protected function getCssAssets(); @@ -110,9 +128,7 @@ trait AssetLibraryTrait { * options. * * @todo Expand documentation. - * @todo Consider moving this back to AssetLibraryInterface */ abstract protected function getJsAssets(); } - diff --git a/src/ExternalLibrary/Exception/InvalidLibraryDependencyException.php b/src/ExternalLibrary/Exception/InvalidLibraryDependencyException.php new file mode 100644 index 0000000..a3c3353 --- /dev/null +++ b/src/ExternalLibrary/Exception/InvalidLibraryDependencyException.php @@ -0,0 +1,49 @@ +<?php + +/** + * @file + * Contains \Drupal\libraries\ExternalLibrary\Exception\InvalidLibraryDependencyException. + */ + +namespace Drupal\libraries\ExternalLibrary\Exception; +use Drupal\libraries\ExternalLibrary\DependencyAccessorTrait; +use Drupal\libraries\ExternalLibrary\ExternalLibraryInterface; +use Drupal\libraries\ExternalLibrary\LibraryAccessorTrait; + +/** + * + */ +class InvalidLibraryDependencyException extends \UnexpectedValueException { + + use LibraryAccessorTrait; + use DependencyAccessorTrait; + + /** + * Constructs a library exception. + * + * @param \Drupal\libraries\ExternalLibrary\ExternalLibraryInterface $library + * The library with the invalid dependency. + * @param \Drupal\libraries\ExternalLibrary\ExternalLibraryInterface $dependency + * The dependency. + * @param string $message + * (optional) The exception message. + * @param int $code + * (optional) The error code. + * @param \Exception $previous + * (optional) The previous exception. + */ + public function __construct( + ExternalLibraryInterface $library, + ExternalLibraryInterface $dependency, + $message = '', + $code = 0, + \Exception $previous = NULL + ) { + $this->library = $library; + $this->dependency = $dependency; + $message = $message ?: "The library '{$this->library->getId()}' cannot depend on the library '{$this->dependency->getId()}'."; + parent::__construct($message, $code, $previous); + } + +} + diff --git a/src/ExternalLibrary/Exception/LibraryClassNotFoundException.php b/src/ExternalLibrary/Exception/LibraryClassNotFoundException.php index 15f1b6e..aadfaef 100644 --- a/src/ExternalLibrary/Exception/LibraryClassNotFoundException.php +++ b/src/ExternalLibrary/Exception/LibraryClassNotFoundException.php @@ -6,6 +6,7 @@ */ namespace Drupal\libraries\ExternalLibrary\Exception; +use Drupal\libraries\ExternalLibrary\LibraryIdAccessorTrait; use Exception; /** @@ -13,7 +14,7 @@ use Exception; */ class LibraryClassNotFoundException extends \RuntimeException { - use LibraryExceptionTrait; + use LibraryIdAccessorTrait; /** * Constructs a library exception. diff --git a/src/ExternalLibrary/Exception/LibraryDefinitionNotFoundException.php b/src/ExternalLibrary/Exception/LibraryDefinitionNotFoundException.php index 7970658..53ebfe0 100644 --- a/src/ExternalLibrary/Exception/LibraryDefinitionNotFoundException.php +++ b/src/ExternalLibrary/Exception/LibraryDefinitionNotFoundException.php @@ -6,6 +6,7 @@ */ namespace Drupal\libraries\ExternalLibrary\Exception; +use Drupal\libraries\ExternalLibrary\LibraryIdAccessorTrait; use Exception; /** @@ -13,7 +14,7 @@ use Exception; */ class LibraryDefinitionNotFoundException extends \RuntimeException { - use LibraryExceptionTrait; + use LibraryIdAccessorTrait; /** * Constructs a library exception. diff --git a/src/ExternalLibrary/Utility/DependencyAccessorTrait.php b/src/ExternalLibrary/Utility/DependencyAccessorTrait.php new file mode 100644 index 0000000..a64dd47 --- /dev/null +++ b/src/ExternalLibrary/Utility/DependencyAccessorTrait.php @@ -0,0 +1,32 @@ +<?php + +/** + * @file + * Contains \Drupal\libraries\ExternalLibrary\Utility\DependencyAccessorTrait. + */ + +namespace Drupal\libraries\ExternalLibrary; + +/** + * Provides a trait for classes giving access to a library dependency. + */ +trait DependencyAccessorTrait { + + /** + * The dependency. + * + * @var \Drupal\libraries\ExternalLibrary\ExternalLibraryInterface + */ + protected $dependency; + + /** + * Returns the dependency. + * + * @return \Drupal\libraries\ExternalLibrary\ExternalLibraryInterface + * The library. + */ + public function getLibrary() { + return $this->dependency; + } + +} diff --git a/src/ExternalLibrary/Utility/LibraryAccessorTrait.php b/src/ExternalLibrary/Utility/LibraryAccessorTrait.php new file mode 100644 index 0000000..3678325 --- /dev/null +++ b/src/ExternalLibrary/Utility/LibraryAccessorTrait.php @@ -0,0 +1,32 @@ +<?php + +/** + * @file + * Contains \Drupal\libraries\ExternalLibrary\Utility\LibraryAccessorTrait. + */ + +namespace Drupal\libraries\ExternalLibrary; + +/** + * Provides a trait for classes giving access to a library. + */ +trait LibraryAccessorTrait { + + /** + * The library. + * + * @var \Drupal\libraries\ExternalLibrary\ExternalLibraryInterface + */ + protected $library; + + /** + * Returns the library. + * + * @return \Drupal\libraries\ExternalLibrary\ExternalLibraryInterface + * The library. + */ + public function getLibrary() { + return $this->library; + } + +} diff --git a/src/ExternalLibrary/Exception/LibraryExceptionTrait.php b/src/ExternalLibrary/Utility/LibraryIdAccessorTrait.php similarity index 62% rename from src/ExternalLibrary/Exception/LibraryExceptionTrait.php rename to src/ExternalLibrary/Utility/LibraryIdAccessorTrait.php index 57eca28..24dcb2e 100644 --- a/src/ExternalLibrary/Exception/LibraryExceptionTrait.php +++ b/src/ExternalLibrary/Utility/LibraryIdAccessorTrait.php @@ -2,15 +2,15 @@ /** * @file - * Contains \Drupal\libraries\ExternalLibrary\Exception\LibraryExceptionTrait. + * Contains \Drupal\libraries\ExternalLibrary\Utility\LibraryIdAccessorTrait. */ -namespace Drupal\libraries\ExternalLibrary\Exception; +namespace Drupal\libraries\ExternalLibrary; /** - * Provides a trait for library-related exceptions. + * Provides a trait for classes giving access to a library ID. */ -trait LibraryExceptionTrait { +trait LibraryIdAccessorTrait { /** * The library ID of the library that caused the exception. -- GitLab