Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
0.00% |
0 / 1 |
|
0.00% |
0 / 4 |
CRAP | |
0.00% |
0 / 64 |
PhpSelection | |
0.00% |
0 / 1 |
|
0.00% |
0 / 4 |
756 | |
0.00% |
0 / 64 |
getReferenceableEntities | |
0.00% |
0 / 1 |
110 | |
0.00% |
0 / 8 |
|||
anonymous function | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 2 |
|||
countReferenceableEntities | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 6 |
|||
matchLabel | |
0.00% |
0 / 1 |
210 | |
0.00% |
0 / 32 |
<?php | |
/** | |
* @file | |
* Contains \Drupal\Core\Entity\Plugin\EntityReferenceSelection\PhpSelection. | |
*/ | |
namespace Drupal\Core\Entity\Plugin\EntityReferenceSelection; | |
use Drupal\Component\Utility\Html; | |
use Drupal\Component\Utility\Unicode; | |
/** | |
* 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(Unicode::strtolower($match)); | |
} | |
elseif (is_array($match)) { | |
array_walk($match, function (&$item) { | |
$item = Html::escape(Unicode::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 = Unicode::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 strpos($label, $match) === 0; | |
case 'CONTAINS': | |
return strpos($label, $match) !== FALSE; | |
case 'ENDS_WITH': | |
return Unicode::substr($label, -Unicode::strlen($match)) === (string) $match; | |
case 'IS NOT NULL': | |
return TRUE; | |
case 'IS NULL': | |
return FALSE; | |
default: | |
// Invalid match operator. | |
return FALSE; | |
} | |
} | |
} |