Issue #3471932 by mstrelan, bbrala, quietone: Fix callables that are expected to return bool but don't
parent
c5193b30d0
commit
3a3c8164c0
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Drupal\Component\Utility;
|
||||
|
||||
/**
|
||||
* Provides methods to filter arrays.
|
||||
*
|
||||
* @ingroup utility
|
||||
*/
|
||||
class FilterArray {
|
||||
|
||||
/**
|
||||
* Removes empty strings from an array.
|
||||
*
|
||||
* This method removes all empty strings from the input array. This is
|
||||
* particularly useful to preserve 0 whilst filtering other falsy values. The
|
||||
* values are first cast to a string before comparison.
|
||||
*
|
||||
* @param array $value
|
||||
* The array to filter.
|
||||
*
|
||||
* @return array
|
||||
* The filtered array.
|
||||
*/
|
||||
public static function removeEmptyStrings(array $value): array {
|
||||
return array_filter($value, static fn ($item) => (string) $item !== '');
|
||||
}
|
||||
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Drupal\Core\Datetime\Element;
|
||||
|
||||
use Drupal\Component\Utility\FilterArray;
|
||||
use Drupal\Component\Utility\NestedArray;
|
||||
use Drupal\Component\Utility\Variable;
|
||||
use Drupal\Core\Datetime\DateHelper;
|
||||
|
@ -345,7 +346,7 @@ class Datelist extends DateElementBase {
|
|||
// \Drupal\Core\Datetime\Element\Datelist::valueCallback().
|
||||
unset($input['object']);
|
||||
// Filters out empty array values, any valid value would have a string length.
|
||||
$filtered_input = array_filter($input, 'strlen');
|
||||
$filtered_input = FilterArray::removeEmptyStrings($input);
|
||||
return array_diff($parts, array_keys($filtered_input));
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Drupal\Core\TypedData\Plugin\DataType;
|
||||
|
||||
use Drupal\Component\Utility\FilterArray;
|
||||
use Drupal\Core\StringTranslation\TranslatableMarkup;
|
||||
use Drupal\Core\TypedData\Attribute\DataType;
|
||||
use Drupal\Core\TypedData\ComplexDataInterface;
|
||||
|
@ -92,7 +93,7 @@ class ItemList extends TypedData implements \IteratorAggregate, ListInterface {
|
|||
$strings[] = $item->getString();
|
||||
}
|
||||
// Remove any empty strings resulting from empty items.
|
||||
return implode(', ', array_filter($strings, 'mb_strlen'));
|
||||
return implode(', ', FilterArray::removeEmptyStrings($strings));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Drupal\Core\TypedData\Plugin\DataType;
|
||||
|
||||
use Drupal\Component\Utility\FilterArray;
|
||||
use Drupal\Core\StringTranslation\TranslatableMarkup;
|
||||
use Drupal\Core\TypedData\Attribute\DataType;
|
||||
use Drupal\Core\TypedData\ComplexDataInterface;
|
||||
|
@ -106,7 +107,7 @@ class Map extends TypedData implements \IteratorAggregate, ComplexDataInterface
|
|||
$strings[] = $property->getString();
|
||||
}
|
||||
// Remove any empty strings resulting from empty items.
|
||||
return implode(', ', array_filter($strings, 'mb_strlen'));
|
||||
return implode(', ', FilterArray::removeEmptyStrings($strings));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Drupal\field\Plugin\migrate\process\d6;
|
||||
|
||||
use Drupal\Component\Utility\FilterArray;
|
||||
use Drupal\migrate\Attribute\MigrateProcess;
|
||||
use Drupal\migrate\MigrateExecutableInterface;
|
||||
use Drupal\migrate\ProcessPluginBase;
|
||||
|
@ -27,7 +28,7 @@ class FieldInstanceOptionTranslation extends ProcessPluginBase {
|
|||
if (isset($global_settings['allowed_values'])) {
|
||||
$list = explode("\n", $global_settings['allowed_values']);
|
||||
$list = array_map('trim', $list);
|
||||
$list = array_filter($list, 'strlen');
|
||||
$list = FilterArray::removeEmptyStrings($list);
|
||||
switch ($field_type) {
|
||||
case 'boolean';
|
||||
$option = preg_replace('/^option_/', '', $row->getSourceProperty('property'));
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Drupal\field\Plugin\migrate\process\d6;
|
||||
|
||||
use Drupal\Component\Utility\FilterArray;
|
||||
use Drupal\migrate\Attribute\MigrateProcess;
|
||||
use Drupal\migrate\MigrateExecutableInterface;
|
||||
use Drupal\migrate\ProcessPluginBase;
|
||||
|
@ -29,7 +30,7 @@ class FieldOptionTranslation extends ProcessPluginBase {
|
|||
if (isset($global_settings['allowed_values'])) {
|
||||
$list = explode("\n", $global_settings['allowed_values']);
|
||||
$list = array_map('trim', $list);
|
||||
$list = array_filter($list, 'strlen');
|
||||
$list = FilterArray::removeEmptyStrings($list);
|
||||
switch ($field_type) {
|
||||
case 'list_string':
|
||||
case 'list_integer':
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Drupal\field\Plugin\migrate\process\d6;
|
||||
|
||||
use Drupal\Component\Utility\FilterArray;
|
||||
use Drupal\migrate\Attribute\MigrateProcess;
|
||||
use Drupal\migrate\MigrateExecutableInterface;
|
||||
use Drupal\migrate\ProcessPluginBase;
|
||||
|
@ -50,7 +51,7 @@ class FieldSettings extends ProcessPluginBase {
|
|||
if (isset($global_settings['allowed_values'])) {
|
||||
$list = explode("\n", $global_settings['allowed_values']);
|
||||
$list = array_map('trim', $list);
|
||||
$list = array_filter($list, 'strlen');
|
||||
$list = FilterArray::removeEmptyStrings($list);
|
||||
switch ($field_type) {
|
||||
case 'list_string':
|
||||
case 'list_integer':
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Drupal\sqlite\Driver\Database\sqlite;
|
||||
|
||||
use Drupal\Component\Utility\FilterArray;
|
||||
use Drupal\Core\Database\Connection as DatabaseConnection;
|
||||
use Drupal\Core\Database\DatabaseNotFoundException;
|
||||
use Drupal\Core\Database\ExceptionHandler;
|
||||
|
@ -246,7 +247,7 @@ class Connection extends DatabaseConnection implements SupportsTemporaryTablesIn
|
|||
*/
|
||||
public static function sqlFunctionLeast() {
|
||||
// Remove all NULL, FALSE and empty strings values but leaves 0 (zero) values.
|
||||
$values = array_filter(func_get_args(), 'strlen');
|
||||
$values = FilterArray::removeEmptyStrings(func_get_args());
|
||||
|
||||
return count($values) < 1 ? NULL : min($values);
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Drupal\user\Plugin\migrate\process\d6;
|
||||
|
||||
use Drupal\Component\Utility\FilterArray;
|
||||
use Drupal\migrate\Attribute\MigrateProcess;
|
||||
use Drupal\migrate\MigrateExecutableInterface;
|
||||
use Drupal\migrate\ProcessPluginBase;
|
||||
|
@ -27,7 +28,7 @@ class ProfileFieldOptionTranslation extends ProcessPluginBase {
|
|||
$allowed_values = [];
|
||||
$list = explode("\n", $translation);
|
||||
$list = array_map('trim', $list);
|
||||
$list = array_filter($list, 'strlen');
|
||||
$list = FilterArray::removeEmptyStrings($list);
|
||||
if ($field_type === 'list_string') {
|
||||
foreach ($list as $value) {
|
||||
$allowed_values[] = ['label' => $value];
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Drupal\views\Plugin\views;
|
||||
|
||||
use Drupal\Component\Utility\FilterArray;
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Component\Utility\UrlHelper;
|
||||
|
@ -758,7 +759,7 @@ abstract class HandlerBase extends PluginBase implements ViewsHandlerInterface {
|
|||
// Filter any empty matches (Like from '++' in a string) and reset the
|
||||
// array keys. 'strlen' is used as the filter callback so we do not lose
|
||||
// 0 values (would otherwise evaluate == FALSE).
|
||||
$value = array_values(array_filter($value, 'strlen'));
|
||||
$value = array_values(FilterArray::removeEmptyStrings($value));
|
||||
|
||||
if ($force_int) {
|
||||
$value = array_map('intval', $value);
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Drupal\Tests\Component\Utility;
|
||||
|
||||
use Drupal\Component\Utility\FilterArray;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* Test filter array functions.
|
||||
*
|
||||
* @group Utility
|
||||
*
|
||||
* @coversDefaultClass \Drupal\Component\Utility\FilterArray
|
||||
*/
|
||||
class FilterArrayTest extends TestCase {
|
||||
|
||||
/**
|
||||
* Tests removing empty strings.
|
||||
*
|
||||
* @dataProvider providerRemoveEmptyStrings
|
||||
* @covers ::removeEmptyStrings
|
||||
*/
|
||||
public function testRemoveEmptyStrings(array $values, array $expected): void {
|
||||
$this->assertEquals($expected, array_values(FilterArray::removeEmptyStrings($values)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testRemoveEmptyStrings().
|
||||
*
|
||||
* @see testRemoveEmptyStrings()
|
||||
*/
|
||||
public static function providerRemoveEmptyStrings(): \Generator {
|
||||
yield 'strings' => [
|
||||
['', ' ', '0', 'true', 'false'],
|
||||
[' ', '0', 'true', 'false'],
|
||||
];
|
||||
yield 'integers' => [
|
||||
[-1, 0, 1],
|
||||
[-1, 0, 1],
|
||||
];
|
||||
yield 'null, true, false' => [
|
||||
[NULL, TRUE, FALSE],
|
||||
[TRUE],
|
||||
];
|
||||
|
||||
$stringable = new class implements \Stringable {
|
||||
|
||||
public function __toString(): string {
|
||||
return 'foo';
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
yield 'non-scalar' => [
|
||||
[new $stringable()],
|
||||
[new $stringable()],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue