Skip to content

Commit 49a8874

Browse files
committed
toolcollection
1 parent fb6e5ea commit 49a8874

File tree

7 files changed

+221
-1
lines changed

7 files changed

+221
-1
lines changed

ai-command.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,11 @@
1414
require_once $ai_command_autoloader;
1515
}
1616

17-
WP_CLI::add_command( 'ai', AiCommand::class );
17+
WP_CLI::add_command( 'ai', function ( $args, $assoc_args ) {
18+
$tools = new ToolCollection();
19+
20+
// TODO Register your tool here and add it to the collection
21+
22+
$ai_command = new AiCommand( $tools );
23+
$ai_command( $args, $assoc_args );
24+
} );

src/AiCommand.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@
2323
*/
2424
class AiCommand extends WP_CLI_Command {
2525

26+
public function __construct(
27+
private ToolCollection $tools,
28+
) {
29+
parent::__construct();
30+
}
31+
2632
/**
2733
* Greets the world.
2834
*

src/Collection.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace WP_CLI\AiCommand;
6+
7+
use Countable;
8+
use Iterator;
9+
10+
abstract class Collection implements Iterator, Countable
11+
{
12+
13+
protected array $data = [];
14+
15+
public function next(): void
16+
{
17+
next($this->data);
18+
}
19+
20+
public function key(): int
21+
{
22+
return (int)key($this->data);
23+
}
24+
25+
public function valid(): bool
26+
{
27+
return key($this->data) !== null;
28+
}
29+
30+
public function rewind(): void
31+
{
32+
reset($this->data);
33+
}
34+
35+
public function count(): int
36+
{
37+
return count($this->data);
38+
}
39+
40+
}

src/Entity/Tool.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
final class Tool
6+
{
7+
8+
public function __construct(
9+
private array $data,
10+
private array $tags = []
11+
) {
12+
$this->validate();
13+
}
14+
15+
private function validate(): void
16+
{
17+
foreach ($this->tags as $tag) {
18+
if ( ! preg_match('/^[a-z][a-z-]+$/', $tag)) {
19+
throw new InvalidArgumentException('Tags can only contain [a-z] and -.');
20+
}
21+
}
22+
}
23+
24+
public function get_name(): string
25+
{
26+
return $this->data['name'];
27+
}
28+
29+
public function get_tags(): array
30+
{
31+
return $this->tags;
32+
}
33+
34+
public function get_data(): array
35+
{
36+
return $this->data;
37+
}
38+
39+
}

src/ToolCollection.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace WP_CLI\AiCommand;
6+
7+
use Tool;
8+
9+
final class ToolCollection extends Collection
10+
{
11+
12+
public function __construct(array $data = [])
13+
{
14+
foreach ($data as $tool) {
15+
$this->add($tool);
16+
}
17+
}
18+
19+
public function add(Tool $tool): void
20+
{
21+
$this->data[] = $tool;
22+
}
23+
24+
public function current(): Tool
25+
{
26+
return current($this->data);
27+
}
28+
29+
}

src/ToolRepository.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace WP_CLI\AiCommand;
6+
7+
use Tool;
8+
9+
interface ToolRepository
10+
{
11+
12+
public function find(string $name): ?Tool;
13+
14+
/**
15+
* Controls which tags are included or excluded from processing.
16+
*
17+
* Keys allowed:
18+
* - `include`: Defines which tags to include. Accepts:
19+
* - `'all'` (default): includes all available tags.
20+
* - an empty string or empty array: includes nothing.
21+
* - a string of comma-separated tag names or an array of tag names: includes only those.
22+
*
23+
* - `exclude`: Removes tags from the resolved include list. Can be a string or array of tag names.
24+
*
25+
* Behavior:
26+
* - Inclusion is resolved first.
27+
* - Exclusion is applied afterward to filter out specific tags from the inclusion list.
28+
*/
29+
public function find_all(array $filters = []): ToolCollection;
30+
31+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use WP_CLI\AiCommand\ToolCollection;
6+
use WP_CLI\AiCommand\ToolRepository;
7+
8+
class CollectionToolRepository implements ToolRepository
9+
{
10+
11+
public function __construct(
12+
private ToolCollection $collection
13+
) {
14+
}
15+
16+
public function find(string $name): ?Tool
17+
{
18+
foreach ($this->find_all() as $tool) {
19+
if ($tool->get_name() === $name) {
20+
return $tool;
21+
}
22+
}
23+
24+
return null;
25+
}
26+
27+
public function find_all(array $filters = []): ToolCollection
28+
{
29+
$defaults = [
30+
'include' => 'all',
31+
'exclude' => [],
32+
];
33+
34+
$filters = array_merge($defaults, $filters);
35+
36+
$all = iterator_to_array($this->collection);
37+
$filtered = [];
38+
39+
if ($filters['include'] !== 'all') {
40+
foreach ($filters['include'] as $tag_to_include) {
41+
foreach ($all as $tool) {
42+
foreach ($tool->get_tags() as $tag_to_check) {
43+
if ($tag_to_include === $tag_to_check) {
44+
$filtered[$tool->get_name()] = $tool;
45+
46+
continue 2;
47+
}
48+
}
49+
}
50+
}
51+
}
52+
53+
if ($filters['exclude']) {
54+
foreach ($filters['exclude'] as $tag_to_exclude) {
55+
foreach ($filtered as $tool) {
56+
foreach ($tool->get_tags() as $tag_to_check) {
57+
if ($tag_to_exclude === $tag_to_check) {
58+
unset($filtered[$tool->get_name()]);
59+
}
60+
}
61+
}
62+
}
63+
}
64+
65+
return new ToolCollection($filtered);
66+
}
67+
68+
}

0 commit comments

Comments
 (0)