-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
speckmaier
committed
Sep 30, 2024
1 parent
3a3ce30
commit 9b3d2cb
Showing
8 changed files
with
286 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<?php | ||
|
||
namespace VAF\WP\Framework\BulkEdit\Attribute; | ||
|
||
use Attribute; | ||
|
||
/** | ||
* Service tag to autoconfigure bulk edit container. | ||
*/ | ||
#[Attribute(Attribute::TARGET_CLASS)] | ||
class AsBulkEditContainer | ||
{ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<?php | ||
|
||
namespace VAF\WP\Framework\BulkEdit\Attribute; | ||
|
||
use Attribute; | ||
|
||
#[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)] | ||
final class BulkEdit | ||
{ | ||
public function __construct( | ||
public readonly string $title, | ||
public readonly string|array|null $postTypes = null, | ||
public readonly string|null $supporting = null, | ||
) { | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<?php | ||
|
||
namespace VAF\WP\Framework\BulkEdit; | ||
|
||
class EmptySupportingPostTypesException extends \RuntimeException | ||
{ | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
<?php | ||
|
||
namespace VAF\WP\Framework\BulkEdit; | ||
|
||
use VAF\WP\Framework\Kernel\WordpressKernel; | ||
|
||
final class Loader | ||
{ | ||
public function __construct(private readonly WordpressKernel $kernel, private readonly array $bulkeditContainer) | ||
{ | ||
} | ||
|
||
public function registerMetaboxes(): void | ||
{ | ||
foreach ($this->bulkeditContainer as $serviceId => $bulkeditContainer) { | ||
foreach ($bulkeditContainer as $data) { | ||
|
||
add_action('add_meta_boxes', function () use ($data, $serviceId) { | ||
$this->registerBulkEditField($serviceId, $data); | ||
|
||
|
||
try { | ||
} catch (EmptySupportingPostTypesException) { | ||
// should only show up on supporting post types but none are registered and registering with | ||
//empty array would result in showing up on all post types | ||
} | ||
}, 5); | ||
} | ||
|
||
} | ||
} | ||
|
||
public function registerBulkEditField($serviceId, $data) | ||
{ | ||
$methodName = $data['method']; | ||
|
||
add_action('admin_init', function () use ($data) { | ||
$post_types = PostTypeList::fromPostTypes($data['postTypes'])->withSupporting($data['supporting'], fn($feature) => get_post_types_by_support($feature)) | ||
->postTypes(); | ||
|
||
foreach ($post_types as $post_type => $label) { | ||
add_action("manage_{$post_type}_posts_columns", function ($columns) use ($data) { | ||
return [ | ||
...$columns, | ||
$data['name'] => $data['title'], | ||
]; | ||
}); | ||
|
||
add_filter("manage_edit-{$post_type}_columns", function ($columns) use ($data) { | ||
return [ | ||
...$columns, | ||
$data['name'] => $data['title'], | ||
]; | ||
}, 9999); | ||
} | ||
}); | ||
|
||
add_action('bulk_edit_custom_box', function ($columnName, $serviceId, $data) { | ||
if ($columnName !== $data['name']) { | ||
return; | ||
} | ||
|
||
$methodName = $data['method']; | ||
echo $this->kernel->getContainer()->get($serviceId)->$methodName(); | ||
}); | ||
|
||
add_action('hidden_columns', function ($columns, $data) { | ||
return [ | ||
...$columns, | ||
$data['name'], | ||
]; | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
<?php | ||
|
||
namespace VAF\WP\Framework\BulkEdit; | ||
|
||
use ReflectionClass; | ||
use ReflectionMethod; | ||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; | ||
use Symfony\Component\DependencyInjection\ContainerBuilder; | ||
use VAF\WP\Framework\Metabox\Attribute\Metabox; | ||
use VAF\WP\Framework\Slug; | ||
|
||
final class LoaderCompilerPass implements CompilerPassInterface | ||
{ | ||
public function process(ContainerBuilder $container): void | ||
{ | ||
if (!$container->has('bulkedit.loader')) { | ||
return; | ||
} | ||
|
||
$loaderDefinition = $container->findDefinition('bulkedit.loader'); | ||
|
||
$bulkeditContainerServices = $container->findTaggedServiceIds('bulkedit.container'); | ||
|
||
$bulkeditContainerData = []; | ||
foreach ($bulkeditContainerServices as $id => $tags) { | ||
$definition = $container->findDefinition($id); | ||
$definition->setPublic(true); | ||
$bulkeditContainerData[$id] = $this->getBulkEditContainerData($definition->getClass(), $container); | ||
} | ||
$loaderDefinition->setArgument('$bulkeditContainer', $bulkeditContainerData); | ||
} | ||
|
||
private function getBulkEditContainerData(string $class, ContainerBuilder $container): array | ||
{ | ||
$data = []; | ||
|
||
$reflection = new ReflectionClass($class); | ||
foreach ($reflection->getMethods(ReflectionMethod::IS_PUBLIC) as $method) { | ||
$methodName = $method->getName(); | ||
|
||
// Check if the Metabox attribute is present | ||
$attributes = $method->getAttributes(Metabox::class); | ||
if (empty($attributes)) { | ||
continue; | ||
} | ||
|
||
foreach ($attributes as $attribute) { | ||
/** | ||
* @var BulkEdit $instance | ||
*/ | ||
$instance = $attribute->newInstance(); | ||
|
||
$data[] = [ | ||
'method' => $methodName, | ||
'name' => (string)Slug::fromName($instance->title), | ||
'title' => $instance->title, | ||
'postTypes' => $instance->postTypes, | ||
'supporting' => $instance->supporting, | ||
]; | ||
} | ||
} | ||
|
||
return $data; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
<?php | ||
|
||
namespace VAF\WP\Framework\BulkEdit; | ||
|
||
use VAF\WP\Framework\Metabox\EmptySupportingScreensException; | ||
|
||
class PostTypeList | ||
{ | ||
|
||
private string|array|null $postTypes; | ||
private ?string $feature; | ||
private array $supportingPostTypes = []; | ||
|
||
public static function fromPostTypes(string|array|null $screen): self | ||
{ | ||
$screenList = new static(); | ||
|
||
$screenList->postTypes = $screen; | ||
|
||
return $screenList; | ||
} | ||
|
||
public function withSupporting(string|null $feature, callable $postTypesFromFeature): self | ||
{ | ||
$screenList = clone $this; | ||
|
||
$screenList->feature = $feature; | ||
$screenList->supportingPostTypes = $feature === null ? [] : $postTypesFromFeature($feature); | ||
|
||
return $screenList; | ||
} | ||
|
||
public function postTypes(): string|array|null | ||
{ | ||
if ($this->feature === null) { | ||
return $this->postTypes; | ||
} | ||
|
||
if($this->postTypes === null && empty($this->supportingPostTypes)) { | ||
throw new EmptySupportingPostTypesException(); | ||
} | ||
|
||
if($this->postTypes === null) { | ||
return $this->supportingPostTypes; | ||
} | ||
|
||
return [$this->postTypes, ...$this->supportingPostTypes]; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<?php | ||
|
||
namespace VAF\WP\Framework; | ||
|
||
class Slug | ||
{ | ||
|
||
private string $name; | ||
|
||
public static function fromName(string $name): self | ||
{ | ||
$slug = new static(); | ||
|
||
$slug->name = $name; | ||
|
||
return $slug; | ||
} | ||
|
||
public function __toString(): string | ||
{ | ||
return preg_replace( | ||
'~[^a-zA-Z]~', | ||
'-', | ||
strtolower( | ||
$this->name, | ||
), | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<?php | ||
|
||
namespace VAF\WP\FrameworkTests\Unit; | ||
|
||
use VAF\WP\Framework\Slug; | ||
use VAF\WP\FrameworkTests\TestCase; | ||
|
||
class SlutTest extends TestCase | ||
{ | ||
|
||
/** | ||
* @test | ||
*/ | ||
public function should_keep_a_to_z() | ||
{ | ||
$slug = Slug::fromName('abcdefghijklmnopqrstuvwxyz'); | ||
|
||
$this->assertEquals('abcdefghijklmnopqrstuvwxyz', (string)$slug); | ||
} | ||
|
||
/** | ||
* @test | ||
*/ | ||
public function should_keep_capital_a_to_z() | ||
{ | ||
$slug = Slug::fromName('ABCDEFGHIJKLMNOPQRSTUVWXYZ'); | ||
|
||
$this->assertEquals('ABCDEFGHIJKLMNOPQRSTUVWXYZ', (string)$slug); | ||
} | ||
} |