class InstallableRequirement in Markdown 8.2
Markdown Requirement Annotation.
@Target("ANNOTATION")
@property \Drupal\markdown\Annotation\Identifier $id Optional. Note: if this contains a colon (:), it will be treated as a type based identifier, where everything prior to the colon is considered the type and everything following the colon is considered the identifier, relative in context with the type. Available types are:
- parser:<parserPluginId>
- extension<extensionPluginId>
- filter:<filterPluginId>
- service:<service.id>
@todo Move upstream to https://www.drupal.org/project/installable_plugins.
Hierarchy
- class \Drupal\Component\Annotation\AnnotationBase implements AnnotationInterface
- class \Drupal\markdown\Annotation\AnnotationObject implements \Drupal\markdown\Annotation\ArrayAccess, \Drupal\markdown\Annotation\IteratorAggregate, PluginDefinitionInterface uses DependencySerializationTrait
- class \Drupal\markdown\Annotation\InstallableRequirement
- class \Drupal\markdown\Annotation\AnnotationObject implements \Drupal\markdown\Annotation\ArrayAccess, \Drupal\markdown\Annotation\IteratorAggregate, PluginDefinitionInterface uses DependencySerializationTrait
Expanded class hierarchy of InstallableRequirement
5 files declare their use of InstallableRequirement
- AllowedHtmlManager.php in src/
PluginManager/ AllowedHtmlManager.php - ExtensionManager.php in src/
PluginManager/ ExtensionManager.php - FilterAlign.php in src/
Plugin/ Markdown/ AllowedHtml/ FilterAlign.php - InstallablePluginManager.php in src/
PluginManager/ InstallablePluginManager.php - TableOfContentsExtension.php in src/
Plugin/ Markdown/ CommonMark/ Extension/ TableOfContentsExtension.php
File
- src/
Annotation/ InstallableRequirement.php, line 39
Namespace
Drupal\markdown\AnnotationView source
class InstallableRequirement extends AnnotationObject {
/**
* An array of arguments to be passed to the callback.
*
* @var array
*/
public $arguments = [];
/**
* A callback invoked to retrieve the value used to validate the requirement.
*
* Note: this is only used if there have been constraints set to validate.
*
* If a value is not supplied, then the requirement will simply check whether
* the provider is installed.
*
* If the value is supplied and it isn't callable, it will check whether
* the provider type is a filter, service, markdown-extension,
* markdown-library, or markdown-parser and then see if it is a publicly
* accessible method on the provider's object. Optionally, a method name
* can be prefixed with a double-colon (::) to ensure no matching static
* callable function with a similar name is used.
*
* @var string
*/
public $callback;
/**
* An array of validation constraints used to validate the callable value.
*
* @var array
*
* @see \Drupal\Core\TypedData\TypedData::getConstraints().
*/
public $constraints = [];
/**
* The name of the constraint, if any.
*
* Note: this will automatically be determined if using a typed identifier
* and not already provided.
*
* @var string
*/
public $name;
/**
* The value used for constraints.
*
* Note: If this value is explicitly provided, then any callback set will
* be ignored.
*
* @var mixed
*/
public $value;
/**
* Retrieves the object defined by id/type.
*
* @return mixed|void
* The object defined by id/type.
*
* @noinspection PhpDocMissingThrowsInspection
*/
public function getObject() {
if ($this
->isTyped()) {
$container = \Drupal::getContainer();
list($type, $id) = $this
->listTypeId();
switch ($type) {
case 'parser':
if (($parserManager = ParserManager::create($container)) && $parserManager
->hasDefinition($id)) {
if (!isset($this->name)) {
$definition = $parserManager
->getDefinition($id);
if ($library = $definition
->getInstalledLibrary() ?: $definition
->getPreferredLibrary()) {
$this->name = $library
->getLink();
}
}
return $parserManager
->createInstance($id);
}
break;
case 'extension':
if (($extensionManager = ExtensionManager::create($container)) && $extensionManager
->hasDefinition($id)) {
if (!isset($this->name)) {
$definition = $extensionManager
->getDefinition($id);
if ($library = $definition
->getInstalledLibrary() ?: $definition
->getPreferredLibrary()) {
$this->name = $library
->getLink();
}
}
return $extensionManager
->createInstance($id);
}
break;
case 'filter':
/** @var \Drupal\filter\FilterPluginManager $filterManager */
if (($filterManager = $container
->get('plugin.manager.filter')) && $filterManager
->hasDefinition($id)) {
if (!isset($this->name)) {
$this->name = t('Filter "@id"', [
'@id' => $id,
]);
}
/* @noinspection PhpUnhandledExceptionInspection */
return $filterManager
->createInstance($id);
}
break;
case 'service':
if ($container
->has($id)) {
if (!isset($this->name)) {
$this->name = t('Service "@id"', [
'@id' => $id,
]);
}
return $container
->get($id);
}
break;
}
}
}
/**
* Retrieves the identifier type, if any.
*
* @return string|void
* The identifier type, if any.
*/
public function getType() {
if ($this
->isTyped() && ($type = $this
->listTypeId()[0])) {
return $type;
}
}
/**
* Retrieves the typed identifier, if any.
*
* @return string|void
* The typed identifier, if any.
*/
public function getTypeId() {
if ($this
->isTyped() && ($type = $this
->listTypeId()[1])) {
return $type;
}
}
/**
* Indicates whether the plugin has a typed identifier.
*
* @return bool
* TRUE or FALSE
*/
public function isTyped() {
return $this->id && strpos($this->id, ':') !== FALSE;
}
/**
* Retrieves the split typed identifier.
*
* @return string[]|void
* An indexed array with type values: type, id; intended to be
* used with list().
*/
public function listTypeId() {
if ($this
->isTyped()) {
return explode(':', $this->id, 2);
}
}
/**
* Validates the requirement.
*
* @return \Symfony\Component\Validator\ConstraintViolationListInterface
* A list of constraint violations. If the list is empty, validation
* succeeded.
*/
public function validate() {
$object = $this
->getObject();
if (isset($this->name)) {
foreach ($this->constraints as $name => &$constraint) {
if ($name !== 'Version') {
continue;
}
if (!is_array($constraint)) {
$constraint = [
'value' => $constraint,
];
}
if (!isset($constraint['name'])) {
$constraint['name'] = $this->name;
}
}
}
if (!isset($this->value)) {
if ($this->callback) {
if ($object) {
$callback = [
$object,
ltrim($this->callback, ':'),
];
$this->value = call_user_func_array($callback, $this->arguments);
}
else {
$this->value = call_user_func_array($this->callback, $this->arguments);
}
if (!$this->constraints) {
$this->constraints = [
'NotNull' => [],
];
}
}
else {
$this->value = $object ? [
$this
->getId(),
] : [];
if (!$this->constraints) {
$this->constraints = [
'Count' => [
'min' => 1,
'max' => 1,
],
];
}
}
}
// If returned value is typed data, add the conditions to its definition.
if (($value = $this->value) instanceof TypedDataInterface) {
$typed = $this->value;
$definition = $typed
->getDataDefinition();
foreach ($this->constraints as $name => $options) {
$definition
->addConstraint($name, $options);
}
}
elseif (is_array($value) || $value instanceof \Traversable) {
// Don't use config based types. Bug in earlier versions of core.
// @see https://www.drupal.org/project/drupal/issues/1928868.
$valueType = is_scalar(current($value)) ? gettype(current($value)) : 'string';
$itemDefinition = \Drupal::typedDataManager()
->createDataDefinition($valueType);
$definition = new ListDataDefinition([], $itemDefinition);
$definition
->setConstraints($this->constraints);
$typed = ItemList::createInstance($definition);
$typed
->setValue($value);
}
else {
$valueType = is_scalar($value) ? gettype($value) : 'string';
$definition = DataDefinition::create($valueType)
->setConstraints($this->constraints);
switch ($valueType) {
case 'boolean':
$typed = BooleanData::createInstance($definition);
break;
case 'float':
$typed = FloatData::createInstance($definition);
break;
case 'integer':
$typed = IntegerData::createInstance($definition);
break;
case 'string':
default:
$typed = StringData::createInstance($definition);
$value = (string) $value;
break;
}
$typed
->setValue($value);
}
// Attempt to validate the requirement constraints.
try {
return $typed
->validate();
} catch (PluginNotFoundException $exception) {
// See if a global was set in markdown_requirements().
// @todo This is currently only needed because its bundled with the
// markdown module; remove when moved to a standalone upstream project
// https://www.drupal.org/project/installable_plugins
global $_markdown_requirements;
$message = $exception
->getMessage();
$violationList = new ConstraintViolationList();
// The exception to this exception is when it is attempting to find
// constraints provided by this module, which may not yet be installed.
// In this case, the constraints must be validated manually.
// @see markdown_requirements()
// @todo This is currently only needed because its bundled with the
// markdown module; remove when moved to a standalone upstream project
// https://www.drupal.org/project/installable_plugins
$markdownConstraints = [
'Installed',
'Exists',
'Version',
];
if ($_markdown_requirements === 'install' && preg_match('/(?:Plugin ID |The )\\s*[\'"]([^\'"]+)[\'"]\\s*(?:was not found|plugin does not exist)/i', $message, $matches) && in_array($matches[1], $markdownConstraints)) {
$pluginId = $matches[1];
if (($class = '\\Drupal\\markdown\\Plugin\\Validation\\Constraint\\' . $pluginId) && class_exists($class)) {
$value = $typed
->getValue();
$context = new ExecutionContext($typed
->getTypedDataManager()
->getValidator(), $value, new DrupalTranslator());
foreach ($this->constraints as $name => $options) {
if ($name === $pluginId) {
/** @var \Symfony\Component\Validator\Constraint $constraint */
$constraint = new $class($options);
if (($validatorClass = $constraint
->validatedBy()) && class_exists($validatorClass)) {
/** @var \Symfony\Component\Validator\ConstraintValidatorInterface $constraintValidator */
$constraintValidator = new $validatorClass();
$constraintValidator
->initialize($context);
$constraintValidator
->validate($value, $constraint);
}
}
}
$violationList
->addAll($context
->getViolations());
return $violationList;
}
}
// Add the exception message to the violations list.
$violationList
->add(new ConstraintViolation($message, '', [], '', '', ''));
return $violationList;
}
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
AnnotationBase:: |
protected | property | The class used for this annotated class. | |
AnnotationBase:: |
public | property | The annotated class ID. | 1 |
AnnotationBase:: |
protected | property | The provider of the annotated class. | |
AnnotationBase:: |
public | function |
Gets the class of the annotated class. Overrides AnnotationInterface:: |
|
AnnotationBase:: |
public | function |
Gets the name of the provider of the annotated class. Overrides AnnotationInterface:: |
|
AnnotationBase:: |
public | function |
Sets the class of the annotated class. Overrides AnnotationInterface:: |
|
AnnotationBase:: |
public | function |
Sets the name of the provider of the annotated class. Overrides AnnotationInterface:: |
|
AnnotationObject:: |
public | property | The description of the plugin. | |
AnnotationObject:: |
public | property | A human-readable label. | |
AnnotationObject:: |
public | property | The weight of the plugin. | |
AnnotationObject:: |
protected | property | Stores deprecated values. | |
AnnotationObject:: |
protected | property | A list of deprecation messages, keyed by the deprecated property name. | |
AnnotationObject:: |
private | property | A list of triggered deprecations. | |
AnnotationObject:: |
public static | function | Allows the creation of new objects statically, for easier chainability. | |
AnnotationObject:: |
constant | |||
AnnotationObject:: |
protected | function | Merges values with this plugin. | |
AnnotationObject:: |
public | function |
Gets the value of an annotation. Overrides AnnotationInterface:: |
|
AnnotationObject:: |
public | function |
Gets the unique ID for this annotated class. Overrides AnnotationBase:: |
|
AnnotationObject:: |
public | function | ||
AnnotationObject:: |
public | function |
Gets the unique identifier of the plugin. Overrides PluginDefinitionInterface:: |
|
AnnotationObject:: |
public | function | Merges values with this plugin. | |
AnnotationObject:: |
protected | function | Normalizes a value to ensure its ready to be merged with the definition. | |
AnnotationObject:: |
public | function | ||
AnnotationObject:: |
public | function | ||
AnnotationObject:: |
public | function | ||
AnnotationObject:: |
public | function | ||
AnnotationObject:: |
protected | function | Indicates properties that should never be overridden after instantiation. | 1 |
AnnotationObject:: |
private | function | Triggers a deprecation notice for a given property. | |
AnnotationObject:: |
protected | function | Helper method for validating the definition identifier. | 2 |
AnnotationObject:: |
public | function | AnnotationObject constructor. | 1 |
AnnotationObject:: |
public | function | ||
AnnotationObject:: |
public | function | ||
AnnotationObject:: |
public | function | ||
AnnotationObject:: |
public | function | ||
AnnotationObject:: |
public | function | ||
AnnotationObject:: |
public | function | ||
DependencySerializationTrait:: |
protected | property | An array of entity type IDs keyed by the property name of their storages. | |
DependencySerializationTrait:: |
protected | property | An array of service IDs keyed by property name used for serialization. | |
DependencySerializationTrait:: |
public | function | Aliased as: __sleepTrait | 1 |
DependencySerializationTrait:: |
public | function | Aliased as: __wakeupTrait | 2 |
InstallableRequirement:: |
public | property | An array of arguments to be passed to the callback. | |
InstallableRequirement:: |
public | property | A callback invoked to retrieve the value used to validate the requirement. | |
InstallableRequirement:: |
public | property | An array of validation constraints used to validate the callable value. | |
InstallableRequirement:: |
public | property | The name of the constraint, if any. | |
InstallableRequirement:: |
public | property | The value used for constraints. | |
InstallableRequirement:: |
public | function | Retrieves the object defined by id/type. | |
InstallableRequirement:: |
public | function | Retrieves the identifier type, if any. | |
InstallableRequirement:: |
public | function | Retrieves the typed identifier, if any. | |
InstallableRequirement:: |
public | function | Indicates whether the plugin has a typed identifier. | |
InstallableRequirement:: |
public | function | Retrieves the split typed identifier. | |
InstallableRequirement:: |
public | function | Validates the requirement. |