PhpSelection.php
Same filename in other branches
Namespace
Drupal\Core\Entity\Plugin\EntityReferenceSelectionFile
-
core/
lib/ Drupal/ Core/ Entity/ Plugin/ EntityReferenceSelection/ PhpSelection.php
View source
<?php
namespace Drupal\Core\Entity\Plugin\EntityReferenceSelection;
use Drupal\Component\Utility\Html;
/**
* Defines an alternative to the default Entity Reference Selection plugin.
*
* This selection plugin uses PHP for more advanced cases when the entity query
* cannot filter properly, for example when the target entity type has no
* 'label' key provided in the entity type plugin definition.
*
* @see \Drupal\Core\Entity\Plugin\Derivative\DefaultSelectionDeriver
*/
class PhpSelection extends DefaultSelection {
/**
* {@inheritdoc}
*/
public function getReferenceableEntities($match = NULL, $match_operator = 'CONTAINS', $limit = 0) {
// No input, return everything from the entity query.
if ($match === NULL || $match === '') {
return parent::getReferenceableEntities($match, $match_operator, $limit);
}
// Start with the selection results returned by the entity query. Don't use
// any limit because we have to apply a limit after filtering the items.
$options = parent::getReferenceableEntities($match, $match_operator);
// Always use a case-insensitive, escaped match. Entity labels returned by
// SelectionInterface::getReferenceableEntities() are already escaped, so
// the incoming $match needs to be escaped as well, making the comparison
// possible.
// @see \Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface::getReferenceableEntities()
if (is_string($match)) {
$match = Html::escape(mb_strtolower($match));
}
elseif (is_array($match)) {
array_walk($match, function (&$item) {
$item = Html::escape(mb_strtolower($item));
});
}
$filtered = [];
$count = 0;
// Filter target entities by the output of their label() method.
foreach ($options as $bundle => &$items) {
foreach ($items as $entity_id => $label) {
if ($this->matchLabel($match, $match_operator, $label)) {
$filtered[$bundle][$entity_id] = $label;
$count++;
if ($limit && $count >= $limit) {
break 2;
}
}
}
}
return $filtered;
}
/**
* {@inheritdoc}
*/
public function countReferenceableEntities($match = NULL, $match_operator = 'CONTAINS') {
$count = 0;
foreach ($this->getReferenceableEntities($match, $match_operator) as &$items) {
$count += count($items);
}
return $count;
}
/**
* Matches an entity label to an input string.
*
* @param mixed $match
* The value to compare. This can be any valid entity query condition value.
* @param string $match_operator
* The comparison operator.
* @param string $label
* The entity label to match against.
*
* @return bool
* TRUE when matches, FALSE otherwise.
*/
protected function matchLabel($match, $match_operator, $label) {
// Always use a case-insensitive value.
$label = mb_strtolower($label);
switch ($match_operator) {
case '=':
return $label == $match;
case '>':
return $label > $match;
case '<':
return $label < $match;
case '>=':
return $label >= $match;
case '<=':
return $label <= $match;
case '<>':
return $label != $match;
case 'IN':
return array_search($label, $match) !== FALSE;
case 'NOT IN':
return array_search($label, $match) === FALSE;
case 'STARTS_WITH':
return str_starts_with($label, $match);
case 'CONTAINS':
return str_contains($label, $match);
case 'ENDS_WITH':
return str_ends_with($label, $match);
case 'IS NOT NULL':
return TRUE;
case 'IS NULL':
return FALSE;
default:
// Invalid match operator.
return FALSE;
}
}
}
Classes
Title | Deprecated | Summary |
---|---|---|
PhpSelection | Defines an alternative to the default Entity Reference Selection plugin. |
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.