TYPO3 v15 dev-main snapshot ()
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Core\Resource\Search\Result;
|
||||
|
||||
use TYPO3\CMS\Core\Resource\Driver\DriverInterface;
|
||||
use TYPO3\CMS\Core\Resource\File;
|
||||
use TYPO3\CMS\Core\Utility\PathUtility;
|
||||
|
||||
/**
|
||||
* Decorator for a search result with files, which filters
|
||||
* the result based on given filters.
|
||||
*/
|
||||
class DriverFilteredSearchResult implements FileSearchResultInterface
|
||||
{
|
||||
private ?array $result = null;
|
||||
|
||||
public function __construct(
|
||||
private readonly FileSearchResultInterface $searchResult,
|
||||
private readonly DriverInterface $driver,
|
||||
/**
|
||||
* @var callable[]
|
||||
*/
|
||||
private readonly array $filters
|
||||
) {}
|
||||
|
||||
/**
|
||||
* @see Countable::count()
|
||||
*/
|
||||
public function count(): int
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
return count($this->result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Iterator::current()
|
||||
*/
|
||||
public function current(): File
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
return current($this->result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Iterator::key()
|
||||
*/
|
||||
public function key(): int
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
return key($this->result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Iterator::next()
|
||||
*/
|
||||
public function next(): void
|
||||
{
|
||||
$this->initialize();
|
||||
next($this->result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Iterator::rewind()
|
||||
*/
|
||||
public function rewind(): void
|
||||
{
|
||||
$this->initialize();
|
||||
reset($this->result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Iterator::valid()
|
||||
*/
|
||||
public function valid(): bool
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
return current($this->result) !== false;
|
||||
}
|
||||
|
||||
private function initialize(): void
|
||||
{
|
||||
if ($this->result === null) {
|
||||
$this->result = $this->applyFilters(...iterator_to_array($this->searchResult));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter out identifiers by calling all attached filters
|
||||
*
|
||||
* @return array<int, File>
|
||||
*/
|
||||
private function applyFilters(File ...$files): array
|
||||
{
|
||||
$filteredFiles = [];
|
||||
foreach ($files as $file) {
|
||||
$itemIdentifier = $file->getIdentifier();
|
||||
$itemName = PathUtility::basename($itemIdentifier);
|
||||
$parentIdentifier = PathUtility::dirname($itemIdentifier);
|
||||
$matches = true;
|
||||
foreach ($this->filters as $filter) {
|
||||
if (!is_callable($filter)) {
|
||||
continue;
|
||||
}
|
||||
$result = $filter($itemName, $itemIdentifier, $parentIdentifier, [], $this->driver);
|
||||
// We use -1 as the "don't include“ return value, for historic reasons,
|
||||
// as call_user_func() used to return FALSE if calling the method failed.
|
||||
if ($result === -1) {
|
||||
$matches = false;
|
||||
}
|
||||
if ($result === false) {
|
||||
throw new \RuntimeException(
|
||||
'Could not apply file/folder name filter ' . $filter[0] . '::' . $filter[1],
|
||||
1543617278
|
||||
);
|
||||
}
|
||||
}
|
||||
if ($matches) {
|
||||
$filteredFiles[] = $file;
|
||||
}
|
||||
}
|
||||
|
||||
return $filteredFiles;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Core\Resource\Search\Result;
|
||||
|
||||
/**
|
||||
* Represents an empty search result (no matches found)
|
||||
*/
|
||||
class EmptyFileSearchResult implements FileSearchResultInterface
|
||||
{
|
||||
public function count(): int
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-return null
|
||||
*/
|
||||
public function current(): mixed
|
||||
{
|
||||
// Noop
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-return null
|
||||
*/
|
||||
public function key(): mixed
|
||||
{
|
||||
// Noop
|
||||
return null;
|
||||
}
|
||||
|
||||
public function next(): void
|
||||
{
|
||||
// Noop
|
||||
}
|
||||
|
||||
public function rewind(): void
|
||||
{
|
||||
// Noop
|
||||
}
|
||||
|
||||
/**
|
||||
* @return false
|
||||
*/
|
||||
public function valid(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Core\Resource\Search\Result;
|
||||
|
||||
use TYPO3\CMS\Core\Resource\File;
|
||||
use TYPO3\CMS\Core\Resource\ResourceFactory;
|
||||
use TYPO3\CMS\Core\Resource\Search\FileSearchDemand;
|
||||
use TYPO3\CMS\Core\Resource\Search\FileSearchQuery;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Represents a search result for a given search query
|
||||
* being an iterable and countable list of file objects.
|
||||
*/
|
||||
class FileSearchResult implements FileSearchResultInterface
|
||||
{
|
||||
/**
|
||||
* @var FileSearchDemand
|
||||
*/
|
||||
private $searchDemand;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $result;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $resultCount;
|
||||
|
||||
public function __construct(FileSearchDemand $searchDemand)
|
||||
{
|
||||
$this->searchDemand = $searchDemand;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Countable::count()
|
||||
*/
|
||||
public function count(): int
|
||||
{
|
||||
if ($this->resultCount !== null) {
|
||||
return $this->resultCount;
|
||||
}
|
||||
|
||||
$this->resultCount = (int)FileSearchQuery::createCountForSearchDemand($this->searchDemand)->execute()->fetchOne();
|
||||
|
||||
return $this->resultCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Iterator::current()
|
||||
*/
|
||||
public function current(): File
|
||||
{
|
||||
$this->initialize();
|
||||
return current($this->result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Iterator::key()
|
||||
*/
|
||||
public function key(): int
|
||||
{
|
||||
$this->initialize();
|
||||
return key($this->result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Iterator::next()
|
||||
*/
|
||||
public function next(): void
|
||||
{
|
||||
$this->initialize();
|
||||
next($this->result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Iterator::rewind()
|
||||
*/
|
||||
public function rewind(): void
|
||||
{
|
||||
$this->initialize();
|
||||
reset($this->result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Iterator::valid()
|
||||
*/
|
||||
public function valid(): bool
|
||||
{
|
||||
$this->initialize();
|
||||
return current($this->result) !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the SQL query and apply filters on the resulting identifiers
|
||||
*/
|
||||
private function initialize(): void
|
||||
{
|
||||
if ($this->result !== null) {
|
||||
return;
|
||||
}
|
||||
$this->result = FileSearchQuery::createForSearchDemand($this->searchDemand)->execute()->fetchAllAssociative();
|
||||
$this->resultCount = count($this->result);
|
||||
$this->result = array_map(
|
||||
static function (array $fileRow): File {
|
||||
return GeneralUtility::makeInstance(ResourceFactory::class)->getFileObject($fileRow['uid'], $fileRow);
|
||||
},
|
||||
$this->result
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Core\Resource\Search\Result;
|
||||
|
||||
/**
|
||||
* Representation of a result for a search for files performed by FileSearchQuery,
|
||||
* which is a collection of matching files.
|
||||
*/
|
||||
interface FileSearchResultInterface extends \Countable, \Iterator {}
|
||||
Reference in New Issue
Block a user