fix: media search also matches file names
This commit is contained in:
@@ -208,7 +208,7 @@ final class MediaSearchAbility implements Ability
|
|||||||
*/
|
*/
|
||||||
private function searchPage(array $args, int $limit, int $offset): array
|
private function searchPage(array $args, int $limit, int $offset): array
|
||||||
{
|
{
|
||||||
$rows = get_posts(array_merge($args, ['posts_per_page' => $limit + 1, 'offset' => $offset]));
|
$rows = self::query(array_merge($args, ['posts_per_page' => $limit + 1, 'offset' => $offset]));
|
||||||
$page = Cursor::page(array_values($rows), $limit, $offset);
|
$page = Cursor::page(array_values($rows), $limit, $offset);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
@@ -230,7 +230,7 @@ final class MediaSearchAbility implements Ability
|
|||||||
*/
|
*/
|
||||||
private function unusedPage(array $args, int $limit, int $offset): array
|
private function unusedPage(array $args, int $limit, int $offset): array
|
||||||
{
|
{
|
||||||
$candidates = array_values(get_posts(array_merge($args, [
|
$candidates = array_values(self::query(array_merge($args, [
|
||||||
'posts_per_page' => self::MAX_SCAN + 1,
|
'posts_per_page' => self::MAX_SCAN + 1,
|
||||||
'offset' => $offset,
|
'offset' => $offset,
|
||||||
])));
|
])));
|
||||||
@@ -282,4 +282,22 @@ final class MediaSearchAbility implements Ability
|
|||||||
{
|
{
|
||||||
return current_user_can('edit_post', (int) $attachment->ID);
|
return current_user_can('edit_post', (int) $attachment->ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get_posts() with file-name matching for a search term, as in the media library screen:
|
||||||
|
* WordPress only searches _wp_attached_file when wp_allow_query_attachment_by_filename is
|
||||||
|
* true. WP_Query reads that filter once per query and then calls remove_all_filters() on it
|
||||||
|
* itself, so it applies to this query only.
|
||||||
|
*
|
||||||
|
* @param array<string, mixed> $args
|
||||||
|
* @return array<int|string, mixed>
|
||||||
|
*/
|
||||||
|
private static function query(array $args): array
|
||||||
|
{
|
||||||
|
if (isset($args['s'])) {
|
||||||
|
add_filter('wp_allow_query_attachment_by_filename', '__return_true');
|
||||||
|
}
|
||||||
|
|
||||||
|
return get_posts($args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace LIT\MCP\Tests\Unit\Integrations\Media;
|
namespace LIT\MCP\Tests\Unit\Integrations\Media;
|
||||||
|
|
||||||
|
use Brain\Monkey\Filters;
|
||||||
use Brain\Monkey\Functions;
|
use Brain\Monkey\Functions;
|
||||||
use LIT\MCP\Abilities\Cursor;
|
use LIT\MCP\Abilities\Cursor;
|
||||||
use LIT\MCP\Integrations\Media\MediaPresenter;
|
use LIT\MCP\Integrations\Media\MediaPresenter;
|
||||||
@@ -149,6 +150,39 @@ final class MediaSearchAbilityTest extends TestCase
|
|||||||
(new MediaSearchAbility($this->presenter(), Mockery::mock(MediaUsageFinder::class)))->execute([]);
|
(new MediaSearchAbility($this->presenter(), Mockery::mock(MediaUsageFinder::class)))->execute([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testASearchTermAlsoMatchesFileNames(): void
|
||||||
|
{
|
||||||
|
$this->unrestrictedPostType();
|
||||||
|
Functions\when('current_user_can')->justReturn(true);
|
||||||
|
Filters\expectAdded('wp_allow_query_attachment_by_filename')->once()->with('__return_true');
|
||||||
|
Functions\expect('get_posts')->once()->with(
|
||||||
|
Mockery::on(static fn (array $args): bool => ($args['s'] ?? null) === 'logo')
|
||||||
|
)->andReturn([]);
|
||||||
|
|
||||||
|
(new MediaSearchAbility($this->presenter(), Mockery::mock(MediaUsageFinder::class)))->execute(['search' => 'logo']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testTheUnusedScanAlsoMatchesFileNames(): void
|
||||||
|
{
|
||||||
|
$this->unrestrictedPostType();
|
||||||
|
Functions\when('current_user_can')->justReturn(true);
|
||||||
|
Filters\expectAdded('wp_allow_query_attachment_by_filename')->once()->with('__return_true');
|
||||||
|
Functions\when('get_posts')->justReturn([]);
|
||||||
|
|
||||||
|
(new MediaSearchAbility($this->presenter(), Mockery::mock(MediaUsageFinder::class)))
|
||||||
|
->execute(['search' => 'logo', 'unused' => true]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testNoFileNameFilterWithoutASearchTerm(): void
|
||||||
|
{
|
||||||
|
$this->unrestrictedPostType();
|
||||||
|
Functions\when('current_user_can')->justReturn(true);
|
||||||
|
Filters\expectAdded('wp_allow_query_attachment_by_filename')->never();
|
||||||
|
Functions\when('get_posts')->justReturn([]);
|
||||||
|
|
||||||
|
(new MediaSearchAbility($this->presenter(), Mockery::mock(MediaUsageFinder::class)))->execute([]);
|
||||||
|
}
|
||||||
|
|
||||||
public function testUnusedFiltersThroughTheUsageFinder(): void
|
public function testUnusedFiltersThroughTheUsageFinder(): void
|
||||||
{
|
{
|
||||||
Functions\when('get_posts')->justReturn($this->attachments(1, 2, 3));
|
Functions\when('get_posts')->justReturn($this->attachments(1, 2, 3));
|
||||||
|
|||||||
Reference in New Issue
Block a user