Skip to content

Instantly share code, notes, and snippets.

@kellymears
Last active May 14, 2020 09:11
Show Gist options
  • Select an option

  • Save kellymears/75dbad492fb241e1bd031b04fc8d811d to your computer and use it in GitHub Desktop.

Select an option

Save kellymears/75dbad492fb241e1bd031b04fc8d811d to your computer and use it in GitHub Desktop.
<?php
/**
* Plugin Name: acme-project
* Plugin URI: https://acme.co
* Description: Anvil drop-shipping application
* Author: Wiley C. <wiley@gmail.com>
* License: MIT
* Text Domain: acme-co
*
* @package acme-co
*/
namespace AcmeCo;
/**
* Register acme-co/acme-project block assets
*
* @see Enqueueing Editor Assets <https://git.io/JvPHy>
* @see Dependency Extraction Webpack Plugin <https://git.io/Jv1ll>
*/
add_action('init', function () {
(new class {
/** @var \Psr\Container\ContainerInterface */
public $bud;
/** @var \Illuminate\Support\Collection */
public $collection;
/** @var \AcmeCo\Plugin\BlockRepository */
public $blocks;
/** @var \AcmeCo\Plugin\Manifest */
public $manifest;
/**
* Class constructor.
*/
public function __construct()
{
$this->bud = require __DIR__ . '/app/bootstrap.php';
$this->collection = $this->bud->get('collection');
$this->blocks = $this->bud->get('blocks');
$this->manifest = $this->bud->get('manifest');
}
/**
* Class invocation.
*
* @throws \WP_Error
* @return void
*/
public function __invoke(): void
{
$this->load();
$this->register();
}
/**
* Load blocks and assets.
*
* @return void
*/
protected function load(): void
{
$this->bud->get('plugin.blocks')->each(function ($name) {
/** @var \AcmeCo\Plugin\BlockInterface */
$block = $this->bud->make('block');
$block->setName($name);
$this->collection::make([
$this->manifest->getAsset($block->getName(), 'editor', 'js'),
$this->manifest->getAsset($block->getName(), 'editor', 'css'),
])->each(function (\AcmeCo\Plugin\AssetInterface $asset) use ($block) {
if (! $asset) return;
$block->setEditorAsset($asset);
});
$this->collection::make([
$this->manifest->getAsset($block->getName(), 'public', 'js'),
$this->manifest->getAsset($block->getName(), 'public', 'css'),
])->each(function (\AcmeCo\Plugin\AssetInterface $asset) use ($block) {
if (! $asset) return;
$block->setPublicAsset($asset);
});
$this->blocks->add($block);
});
}
/**
* Register blocks and assets.
*
* @return void
*/
protected function register(): void
{
$this->blocks->all()->each(function (\AcmeCo\Plugin\BlockInterface $block) {
$block->getAssets()->each(function (\AcmeCo\Plugin\AssetInterface $asset) {
$registerAssetCallable = "wp_register_{$asset->getType()}";
$registerAssetCallable(
$asset->getName(),
$asset->getUrl(),
$asset->getDependencies(),
null
);
});
register_block_type($block);
});
}
})();
});
<?php
namespace AcmeCo\Plugin;
use AcmeCo\Plugin\AssetInterface;
use Psr\Container\ContainerInterface;
/**
* Asset class.
*/
class Asset implements AssetInterface
{
/** @var string */
public $name;
/** @var string */
public $type;
/** @var string */
public $url;
/** @var array */
public $dependencies;
/**
* Constructor.
*/
public function __construct(ContainerInterface $bud)
{
$this->bud = $bud;
}
/**
* Get name.
*
* @return string
*/
public function getName(): string
{
return $this->name;
}
/**
* Set name.
*
* @param string
* @return void
*/
public function setName(string $name): void
{
$this->name = $name;
}
/**
* Get url
*
* @return string
*/
public function getUrl(): string
{
return $this->url;
}
/**
* Set url
*
* @return string
*/
public function setUrl(string $url): void
{
$this->url = $url;
}
/**
* Get type
*
* @return string
*/
public function getType(): string
{
return $this->type;
}
/**
* Set url
*
* @return string
*/
public function setType(string $type): void
{
$this->type = $type;
}
/**
* Get dependencies
*
* @param string
* @return void
*/
public function getDependencies(): array
{
if ($this->getType() == 'style') {
return [];
}
return $this->dependencies ?? [];
}
/**
* Set dependencies
*
* @param string
* @param string
* @return void
*/
public function setDependencies(array $dependencies): void
{
$this->dependencies = $dependencies;
}
}
<?php
namespace AcmeCo\Plugin;
interface AssetInterface
{
public function getName(): string;
public function setName(string $name): void;
public function getUrl(): string;
public function setUrl(string $url): void;
public function getDependencies(): array;
public function setDependencies(array $dependencies): void;
}
<?php
namespace AcmeCo\Plugin;
use \WP_Block_Type;
use AcmeCo\Plugin\AssetInterface;
use AcmeCo\Plugin\BlockInterface;
use Psr\Container\ContainerInterface;
use Illuminate\Support\Collection;
/**
* Block class.
*/
class Block extends WP_Block_Type implements BlockInterface
{
/** @var string */
public $name;
/** @var string */
public $editor_script;
/** @var string */
public $editor_style;
/** @var string */
public $script;
/** @var string */
public $style;
/** @var Collection */
public $assets;
/** @var Collection */
public $attributes;
/**
* Constructor.
*/
public function __construct(ContainerInterface $bud)
{
$this->bud = $bud;
$this->assets = $this->bud->get('collection')::make([]);
}
/**
* Get name.
*
* @return string
*/
public function getName(): string
{
return $this->name;
}
/**
* Set the block name.
*
* @param string
* @return void
*/
public function setName(string $name): void
{
$this->name = "{$this->bud->get('plugin.namespace')}/{$name}";
}
/**
* Get attributes.
*
* @return \Illuminate\Support\Collection
*/
public function getAttributes(): Collection
{
return $this->attributes;
}
/**
* Set attributes.
*
* @param string $attributesPath
* @return Block
*/
public function setAttributes(Collection $attributes): void
{
$this->attributes = $attributes;
}
/**
* Get editor script
*
* @return string
*/
public function getEditorScript(): string
{
return $this->editor_script;
}
/**
* Get editor style
*
* @return string
*/
public function getEditorStyle(): string
{
return $this->editor_style;
}
/**
* Get editor script
*
* @param string
* @return string
*/
public function getPublicScript(): string
{
return $this->script;
}
/**
* Set editor style
*
* @param string
* @return string
*/
public function getPublicStyle(): string
{
return $this->style;
}
/**
* Set editor asset
*
* @param Asset
* @return void
*/
public function setEditorAsset(AssetInterface $asset): void
{
$this->assets->push($asset);
$property = "editor_{$asset->getType()}";
$this->{$property} = $asset->getName();
}
/**
* Set public asset
*
* @param string
* @return void
*/
public function setPublicAsset(AssetInterface $asset): void
{
$this->assets->push($asset);
$this->{$asset->getType()} = $asset->getName();
}
/**
* Get assets.
*
* @return Collection
*/
public function getAssets(): Collection
{
return $this->assets;
}
}
<?php
namespace AcmeCo\Plugin;
use AcmeCo\Plugin\AssetInterface;
use Illuminate\Support\Collection;
/**
* Block class interface.
*/
interface BlockInterface
{
public function getName(): string;
public function setName(string $name): void;
public function getAttributes(): Collection;
public function setAttributes(Collection $attributes): void;
public function getEditorScript(): string;
public function getEditorStyle(): string;
public function setEditorAsset(AssetInterface $asset): void;
public function getPublicScript(): string;
public function getPublicStyle(): string;
public function setPublicAsset(AssetInterface $asset): void;
}
<?php
namespace AcmeCo\Plugin;
use Psr\Container\ContainerInterface;
use Illuminate\Support\Collection;
use AcmeCo\Plugin\Block;
use AcmeCo\Plugin\BlockRepositoryInterface;
/**
* Block repository implementation class.
*/
class BlockRepository implements BlockRepositoryInterface
{
/** @var Collection */
private $blocks;
/**
* Construct.
*/
public function __construct(ContainerInterface $bud)
{
$this->blocks = $bud->get('collection')::make([]);
}
/**
* Get block.
*
* @param string
* @return Block
*/
public function get(string $handle): Block
{
return $this->blocks->get($handle);
}
/**
* Get blocks.
*
* @return Collection
*/
public function all(): Collection
{
return $this->blocks;
}
/**
* Add block.
*
* @param Block
* @return void
*/
public function add(Block $block): void
{
$this->blocks->put($block->getName(), $block);
}
/**
* Remove block.
*
* @param string
* @return void
*/
public function remove(string $handle): void
{
$this->blocks->forget($handle);
}
}
<?php
namespace AcmeCo\Plugin;
use AcmeCo\Plugin\Block;
use Illuminate\Support\Collection;
/**
* Block repository.
*/
interface BlockRepositoryInterface
{
/**
* Get block.
*
* @param string $handle
* @return Block
*/
public function get(string $handle): Block;
/**
* Get blocks.
*
* @return Collection
*/
public function all(): Collection;
}
<?php
namespace AcmeCo\Plugin;
use AcmeCo\Plugin\AssetInterface;
use Psr\Container\ContainerInterface;
use Illuminate\Support\Collection;
/**
* Manifest class.
*/
class Manifest
{
/** @var ContainerInterface */
protected $bud;
/** @var Collection */
protected $assets;
/** @var array */
protected $types = [
'js' => 'script',
'css' => 'style',
];
/**
* Class constructor.
*
* @param ContainerInterface
* @param Collection
* @param Collection
*/
public function __construct(
ContainerInterface $bud,
Collection $assets,
Collection $collection
) {
$this->bud = $bud;
$this->assets = $assets;
$this->collection = $collection;
}
/**
* Return asset
*
* @return AssetInterface
*/
public function getAsset($name, $context, $ext): AssetInterface
{
$blockName = str_replace($this->bud->get('plugin.namespace') . '/', '', $name);
$entry = $this->assets->get("{$blockName}/{$context}")->{$ext};
$uri = str_replace($this->bud->get('plugin.path.dist'), '', $entry);
$asset = $this->bud->make('asset');
$asset->setName(join('/', [$name, $context, $this->types[$ext]]));
$asset->setType($this->types[$ext]);
$asset->setUrl($this->bud->get('plugin.url') . $uri);
if ($this->types[$ext] !== 'style'
&& $dependencies = $this->getDependencies($blockName, $context)) {
$asset->setDependencies($dependencies);
}
return $asset;
}
/**
* Return dependency manifest
*/
public function getDependencies($name, $context)
{
$manifestPath = $this->bud->get('plugin.path') . $this->assets->get("{$name}/{$context}")->json;
return $this->collection::make(
(object) json_decode(file_get_contents($manifestPath))
)->get('dependencies');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment