mirror of
https://github.com/getgrav/grav.git
synced 2026-07-08 17:32:27 +02:00
Added FlexObjectInterface::search() and FlexCollectionInterface::search() methods
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
* Grav 1.6: Renamed `$grav['users']` service to `$grav['accounts']`
|
||||
* Added `Flex::getObjects()` and `Flex::getMixedCollection()` methods for co-mingled collections
|
||||
* Added support to use single Flex key parameter in `Flex::getObject()` method
|
||||
* Added `FlexObjectInterface::search()` and `FlexCollectionInterface::search()` methods
|
||||
1. [](#improved)
|
||||
* Renamed `Grav\Framework\File\Formatter\FormatterInterface` to `Grav\Framework\File\Interfaces\FileFormatterInterface`
|
||||
* Improved `File::save()` to use a temporary file if file isn't locked
|
||||
|
||||
@@ -61,7 +61,16 @@ class AccountsServiceProvider implements ServiceProviderInterface
|
||||
'object' => User::class, // Use User class for backwards compatibility.
|
||||
'collection' => FlexUser\UserCollection::class,
|
||||
'index' => FlexUser\UserIndex::class,
|
||||
'storage' => $this->getFlexStorage($config->get('system.accounts.storage', 'file'))
|
||||
'storage' => $this->getFlexStorage($config->get('system.accounts.storage', 'file')),
|
||||
'search' => [
|
||||
'options' => [
|
||||
'contains' => true
|
||||
],
|
||||
'fields' => [
|
||||
'key',
|
||||
'email'
|
||||
]
|
||||
]
|
||||
]
|
||||
] + ($config->get('plugins.flex-objects.object') ?: []);
|
||||
|
||||
|
||||
@@ -98,34 +98,4 @@ class UserCollection extends FlexCollection implements UserCollectionInterface
|
||||
|
||||
return $exists;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $text
|
||||
* @param bool $case_sensitive
|
||||
* @param bool $strict
|
||||
* @return UserCollection
|
||||
*/
|
||||
public function search(string $text, bool $case_sensitive = false, bool $strict = false) : UserCollection
|
||||
{
|
||||
$text = trim($text);
|
||||
|
||||
if (!$text) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$matching = [];
|
||||
/**
|
||||
* @var string $key
|
||||
* @var User $object
|
||||
*/
|
||||
foreach ($this as $key => $object) {
|
||||
if ($strict && Utils::startsWith($object->getProperty('email'), $text, $case_sensitive)) {
|
||||
$matching[$key] = $object;
|
||||
} elseif (!$strict && Utils::contains($object->getProperty('email'), $text, $case_sensitive)) {
|
||||
$matching[$key] = $object;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->createFrom($matching);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface
|
||||
|
||||
'render' => false,
|
||||
'isAuthorized' => 'session',
|
||||
'search' => true,
|
||||
'sort' => true,
|
||||
];
|
||||
}
|
||||
@@ -124,6 +125,27 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface
|
||||
return $type . $this->_flexDirectory->getType();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $search
|
||||
* @param string|string[]|null $properties
|
||||
* @param array|null $options
|
||||
* @return FlexCollectionInterface
|
||||
*/
|
||||
public function search(string $search, $properties = null, array $options = null) // : FlexCollectionInterface
|
||||
{
|
||||
$matching = $this->call('search', [$search, $properties, $options]);
|
||||
$matching = array_filter($matching);
|
||||
|
||||
if ($matching) {
|
||||
uksort($matching, function ($a, $b) {
|
||||
return -($a <=> $b);
|
||||
});
|
||||
}
|
||||
|
||||
return $this->select(array_keys($matching));
|
||||
}
|
||||
|
||||
public function sort(array $order) // : FlexCollection
|
||||
{
|
||||
$criteria = Criteria::create()->orderBy($order);
|
||||
|
||||
@@ -108,6 +108,86 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
$this->objectConstruct($elements, $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $search
|
||||
* @param string|string[]|null $properties
|
||||
* @param array|null $options
|
||||
* @return float
|
||||
*/
|
||||
public function search(string $search, $properties = null, array $options = null): float
|
||||
{
|
||||
$options = $options ?? $this->getFlexDirectory()->getConfig('data.search.options', []);
|
||||
$properties = $properties ?? $this->getFlexDirectory()->getConfig('data.search.fields', []);
|
||||
|
||||
$weight = 0;
|
||||
foreach ((array)$properties as $property) {
|
||||
$weight += $this->searchNestedProperty($property, $search, $options);
|
||||
}
|
||||
|
||||
return $weight > 0 ? min($weight, 1) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property
|
||||
* @param string $search
|
||||
* @param array|null $options
|
||||
* @return float
|
||||
*/
|
||||
public function searchProperty(string $property, string $search, array $options = null): float
|
||||
{
|
||||
$options = $options ?? $this->getFlexDirectory()->getConfig('data.search.options', []);
|
||||
$value = $this->getProperty($property);
|
||||
|
||||
return $this->searchValue($property, $value, $search, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property
|
||||
* @param string $search
|
||||
* @param array|null $options
|
||||
* @return float
|
||||
*/
|
||||
public function searchNestedProperty(string $property, string $search, array $options = null): float
|
||||
{
|
||||
$options = $options ?? $this->getFlexDirectory()->getConfig('data.search.options', []);
|
||||
$value = $this->getNestedProperty($property);
|
||||
|
||||
return $this->searchValue($property, $value, $search, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param $value
|
||||
* @param string $search
|
||||
* @param array|null $options
|
||||
* @return float
|
||||
*/
|
||||
protected function searchValue(string $name, $value, string $search, array $options = null): float
|
||||
{
|
||||
$search = trim($search);
|
||||
|
||||
if ($search === '') {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!\is_string($value) || $value === '') {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$tested = false;
|
||||
if (($tested |= !empty($options['starts_with'])) && Utils::startsWith($value, $search, $options['case_sensitive'] ?? false)) {
|
||||
return (float)$options['starts_with'];
|
||||
}
|
||||
if (($tested |= !empty($options['ends_with'])) && Utils::endsWith($value, $search, $options['case_sensitive'] ?? false)) {
|
||||
return (float)$options['ends_with'];
|
||||
}
|
||||
if ((!$tested || !empty($options['contains'])) && Utils::contains($value, $search, $options['case_sensitive'] ?? false)) {
|
||||
return (float)$options['contains'];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @param array $files
|
||||
|
||||
@@ -37,6 +37,14 @@ interface FlexCollectionInterface extends ObjectCollectionInterface, NestedObjec
|
||||
*/
|
||||
public function __construct(array $elements, FlexDirectory $type);
|
||||
|
||||
/**
|
||||
* @param string $search
|
||||
* @param string|string[]|null $properties
|
||||
* @param array|null $options
|
||||
* @return FlexCollectionInterface
|
||||
*/
|
||||
public function search(string $search, $properties = null, array $options = null); // : FlexCollection
|
||||
|
||||
/**
|
||||
* @return FlexDirectory
|
||||
*/
|
||||
|
||||
@@ -31,6 +31,18 @@ interface FlexObjectInterface extends NestedObjectInterface, \ArrayAccess
|
||||
*/
|
||||
public function __construct(array $elements, $key, FlexDirectory $type);
|
||||
|
||||
/**
|
||||
* Search object, returns weight between 0 and 1.
|
||||
*
|
||||
* Note: If you override this function, make sure you return value in range 0...1!
|
||||
*
|
||||
* @param string $search
|
||||
* @param string|string[]|null $properties
|
||||
* @param array|null $options
|
||||
* @return float Weight between 0...1
|
||||
*/
|
||||
public function search(string $search, $properties = null, array $options = null): float;
|
||||
|
||||
/**
|
||||
* Returns the directory where the object belongs into.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user