Skip to content

Commit

Permalink
✨ Add acf:usage to search/show field type usage examples (#285)
Browse files Browse the repository at this point in the history
  • Loading branch information
Log1x authored Oct 24, 2024
2 parents 0863a80 + d4db425 commit 1ae59bb
Show file tree
Hide file tree
Showing 5 changed files with 196 additions and 2 deletions.
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,17 @@ class ExampleField extends Field
}
```

Proceed by checking the `Add Post` for the field to ensure things are working as intended – and then [get to work](https://github.com/Log1x/acf-builder-cheatsheet).
Proceed by checking the `Add Post` for the field to ensure things are working as intended.

### Field Builder Usage

To assist with development, ACF Composer comes with a `usage` command that will let you search for registered field types. This will provide basic information about the field type as well as a usage example containing all possible options.

```sh
$ wp acorn acf:usage
```

For additional usage, you may consult the [ACF Builder Cheatsheet](https://github.com/Log1x/acf-builder-cheatsheet).

### Generating a Field Partial

Expand Down
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
},
"require": {
"php": "^8.0",
"stoutlogic/acf-builder": "^1.11"
"stoutlogic/acf-builder": "^1.11",
"laravel/prompts": "*"
},
"require-dev": {
"laravel/pint": "^1.14",
Expand Down
13 changes: 13 additions & 0 deletions resources/views/field-usage.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
@props([
'name',
'label',
'options' => '',
'native' => null,
])

@php($field = $native ? "{$native}('<fg=blue>{$label}</>'" : "addField('<fg=blue>{$name}</>', '<fg=blue>{$label}</>'")

<fg=gray>$fields
->{!! $field !!}, [
{!! $options !!}
]);</>
165 changes: 165 additions & 0 deletions src/Console/UsageCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
<?php

namespace Log1x\AcfComposer\Console;

use Illuminate\Console\Command;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;

use function Laravel\Prompts\search;
use function Laravel\Prompts\table;

class UsageCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'acf:usage {field? : The field type to show}';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Show the usage of a registered field type';

/**
* The registered field types.
*/
protected Collection $types;

/**
* Execute the console command.
*/
public function handle()
{
if (! function_exists('acf_get_field_types')) {
return $this->components->error('Advanced Custom Fields must be installed and activated to use this command.');
}

$this->types = $this->types();

$field = $this->argument('field') ?: search(
label: "<fg=gray>Search</> <fg=blue>{$this->types->count()}</> <fg=gray>registered field types</>",
options: fn (string $value) => $this->search($value)->all(),
hint: '<fg=blue>*</> <fg=gray>indicates a custom field type</>',
scroll: 8,
);

$type = $this->type($field);

if (! $type) {
return $this->components->error("The field type [<fg=red>{$field}</>] could not be found.");
}

$options = collect([
...$type->defaults ?? [],
...$type->supports ?? [],
])->except('escaping_html');

table(['<fg=blue>Label</>', '<fg=blue>Name</>', '<fg=blue>Category</>', '<fg=blue>Options #</>', '<fg=blue>Source</>'], [[
$type->label,
$type->name,
Str::title($type->category),
$options->count(),
$type->source,
]]);

$method = Str::of($type->name)
->studly()
->start('add')
->toString();

$native = method_exists('Log1x\AcfComposer\Builder', $method) ? $method : null;

$options = collect($options)->map(fn ($value) => match (true) {
is_string($value) => "'{$value}'",
is_array($value) => '[]',
is_bool($value) => $value ? 'true' : 'false',
default => $value,
})->map(fn ($value, $key) => "\t '<fg=blue>{$key}</>' => <fg=blue>{$value}</>,");

$usage = view('acf-composer::field-usage', [
'name' => $type->name,
'label' => "{$type->label} Example",
'options' => $options->implode("\n"),
'native' => $native,
]);

$usage = collect(explode("\n", $usage))
->map(fn ($line) => rtrim(" {$line}"))
->filter()
->implode("\n");

$this->line($usage);
}

/**
* Search for a field type.
*/
protected function search(?string $search = null): Collection
{
if (filled($search)) {
return $this->types
->filter(fn ($type) => Str::contains($type->label, $search, ignoreCase: true) || Str::contains($type->name, $search, ignoreCase: true))
->map(fn ($type) => $type->label)
->values();
}

return $this->types->map(fn ($type) => $type->label);
}

/**
* Retrieve a field type by label or name.
*/
protected function type(string $field): ?object
{
return $this->types->first(fn ($type) => Str::contains($type->label, $field, ignoreCase: true) || Str::contains($type->name, $field, ignoreCase: true));
}

/**
* Retrieve all registered field types.
*/
protected function types(): Collection
{
return collect(
acf_get_field_types()
)->map(function ($type) {
if (Str::startsWith($type->doc_url, 'https://www.advancedcustomfields.com')) {
$type->source = 'Official';

return $type;
}

$type->label = "{$type->label} <fg=blue>*</>";
$type->source = $this->source($type);

return $type;
})->sortBy('label');
}

/**
* Attempt to retrieve the field type source.
*/
protected function source(object $type): string
{
$paths = [WPMU_PLUGIN_DIR, WP_PLUGIN_DIR];

$plugin = (new \ReflectionClass($type))->getFileName();

if (! Str::contains($plugin, $paths)) {
return 'Unknown';
}

$source = Str::of($plugin)->replace($paths, '')
->trim('/')
->explode('/')
->first();

return Str::of($source)
->headline()
->replace('Acf', 'ACF');
}
}
5 changes: 5 additions & 0 deletions src/Providers/AcfComposerServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ class AcfComposerServiceProvider extends ServiceProvider
public function register()
{
$this->app->singleton('AcfComposer', fn () => AcfComposer::make($this->app));

if (! defined('PWP_NAME')) {
define('PWP_NAME', 'ACF Composer');
}
}

/**
Expand Down Expand Up @@ -49,6 +53,7 @@ public function boot()
Console\PartialMakeCommand::class,
Console\StubPublishCommand::class,
Console\UpgradeCommand::class,
Console\UsageCommand::class,
Console\WidgetMakeCommand::class,
]);

Expand Down

0 comments on commit 1ae59bb

Please sign in to comment.