Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cache Autowiring::buildServiceClasses into a transient #440

Merged
merged 7 commits into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 62 additions & 11 deletions src/Cache/AbstractManifestCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,13 @@ abstract class AbstractManifestCache implements ManifestCacheInterface
*/
public const TYPE_GEOLOCATION = 'geolocation';

/**
* Cache key for services.
*
* @var string
*/
public const TYPE_SERVICES = 'services';

/**
* Namespace for blocks.
*
Expand Down Expand Up @@ -151,25 +158,27 @@ public function getDuration(): int
}

/**
* Get manifest cache top item.
* Get an (abstract) cache item.
*
* @param string $key Key of the cache.
* @param string $cacheType Type of the cache.
* @param string $key Cache array key.
* @param string $cacheType Cache type to get.
* @param callable|null $fallback Fallback function for getting a result when not set. Optional.
* @param bool $isJson Determines whether we should try to decode the cached value as JSON.
*
* @throws InvalidManifest If cache item is missing.
*
* @return array<string, mixed> Array of cache item.
* @return array<string, mixed> An array of cached values.
*/
public function getManifestCacheTopItem(string $key, string $cacheType = self::TYPE_BLOCKS): array
public function getCacheTopItem(string $key, string $cacheType = self::TYPE_BLOCKS, callable $fallback = null, bool $isJson = true): array
{
$output = [];

if ((\defined('WP_ENVIRONMENT_TYPE') && \WP_ENVIRONMENT_TYPE !== 'development') && !\defined('WP_CLI')) {
$output = $this->getCache($cacheType)[$key] ?? [];
$output = $this->getCache($cacheType, $isJson)[$key] ?? [];
}

if (!$output) {
$output = $this->getAllManifests($cacheType)[$key] ?? [];
if (!$output && $cacheType !== self::TYPE_SERVICES) {
$output = $fallback ? $fallback($cacheType, $key) ?? [] : [];
}

if (!$output && !\defined('WP_CLI')) {
Expand All @@ -179,6 +188,23 @@ public function getManifestCacheTopItem(string $key, string $cacheType = self::T
return $output;
}

/**
* Get manifest cache top item.
*
* @param string $key Key of the cache.
* @param string $cacheType Type of the cache.
*
* @throws InvalidManifest If cache item is missing.
*
* @return array<string, mixed> Array of cache item.
*/
public function getManifestCacheTopItem(string $key, string $cacheType = self::TYPE_BLOCKS): array
{
return $this->getCacheTopItem($key, $cacheType, function () use ($cacheType, $key) {
return $this->getAllManifests($cacheType)[$key] ?? [];
});
}

/**
* Get manifest cache subitem.
*
Expand Down Expand Up @@ -280,6 +306,11 @@ protected function setAssetsStaticCache(): void
*/
protected function setCache(string $cacheType = self::TYPE_BLOCKS): void
{
if ($cacheType === self::TYPE_SERVICES) {
// Services are set with setCustomCache.
return;
}

$name = self::TRANSIENT_NAME . $this->getCacheName() . "_{$cacheType}";

$cache = \get_transient($name);
Expand All @@ -289,22 +320,41 @@ protected function setCache(string $cacheType = self::TYPE_BLOCKS): void
}
}

/**
* Set a custom (abstract) cache value.
*
* @param string $cacheType Cache type.
* @param array<string, mixed> $data Data to set. Does not get encoded, is set directly to a transient.
* @return void
*/
public function setCustomCache(string $cacheType = self::TYPE_BLOCKS, array $data = []): void
{
$name = self::TRANSIENT_NAME . $this->getCacheName() . "_{$cacheType}";

$cache = \get_transient($name);

if (!$cache) {
\set_transient($name, $data, $this->getDuration());
}
}

/**
* Get cache.
*
* @param string $cacheType Type of the cache.
* @param bool $isJson Determines if we should try to decode the cached value as JSON or not.
*
* @return array<string, array<mixed>> Array of cache.
*/
protected function getCache(string $cacheType = self::TYPE_BLOCKS): array
protected function getCache(string $cacheType = self::TYPE_BLOCKS, bool $isJson = true): array
{
$cache = \get_transient(self::TRANSIENT_NAME . $this->getCacheName() . "_{$cacheType}") ?: ''; // phpcs:ignore WordPress.PHP.DisallowShortTernary.Found
$cache = \get_transient(self::TRANSIENT_NAME . $this->getCacheName() . "_{$cacheType}") ?: ($isJson ? '' : []); // phpcs:ignore WordPress.PHP.DisallowShortTernary.Found

if (!$cache) {
$this->setCache($cacheType);
}

return \json_decode($cache, true) ?? [];
return ($isJson ? \json_decode($cache, true) : $cache) ?? [];
}

/**
Expand Down Expand Up @@ -451,6 +501,7 @@ protected function getCacheBuilder(): array
'fileName' => "src{$sep}Geolocation{$sep}manifest.json",
],
],
self::TYPE_SERVICES => []
];
}

Expand Down
12 changes: 9 additions & 3 deletions src/InitSetup/standard/plugin/eightshift-boilerplate-plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,14 @@ function () {
);
}


/**
* Set all the cache for the plugin.
*/
$manifestCache = null;
if (\class_exists(ManifestCache::class)) {
(new ManifestCache())->setAllCache();
$manifestCache = new ManifestCache();
$manifestCache->setAllCache();
}

/**
Expand All @@ -84,9 +87,12 @@ function () {
* not affect the page life cycle.
*/
if (\class_exists(Main::class)) {
(new Main($loader->getPrefixesPsr4(), __NAMESPACE__))->register();
$main = (new Main($loader->getPrefixesPsr4(), __NAMESPACE__));
if ($manifestCache ?? false) {
$main->setManifestCache($manifestCache);
}
$main->register();
}

/**
* Run all WPCLI commands.
*/
Expand Down
12 changes: 9 additions & 3 deletions src/InitSetup/standard/theme/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,14 @@
require __DIR__ . '/vendor-prefixed/autoload.php';
}


/**
* Set all the cache for the theme.
*/
$manifestCache = null;
if (\class_exists(ManifestCache::class)) {
(new ManifestCache())->setAllCache();
$manifestCache = new ManifestCache();
$manifestCache->setAllCache();
}

/**
Expand All @@ -62,9 +65,12 @@
* not affect the page life cycle.
*/
if (\class_exists(Main::class)) {
(new Main($loader->getPrefixesPsr4(), __NAMESPACE__))->register();
$main = (new Main($loader->getPrefixesPsr4(), __NAMESPACE__));
if ($manifestCache ?? false) {
$main->setManifestCache($manifestCache);
}
$main->register();
}

/**
* Run all WPCLI commands.
*/
Expand Down
11 changes: 9 additions & 2 deletions src/InitSetup/tailwind/plugin/eightshift-boilerplate-plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,14 @@ function () {
);
}


/**
* Set all the cache for the plugin.
*/
$manifestCache = null;
if (\class_exists(ManifestCache::class)) {
(new ManifestCache())->setAllCache();
$manifestCache = new ManifestCache();
$manifestCache->setAllCache();
}

/**
Expand All @@ -84,7 +87,11 @@ function () {
* not affect the page life cycle.
*/
if (\class_exists(Main::class)) {
(new Main($loader->getPrefixesPsr4(), __NAMESPACE__))->register();
$main = (new Main($loader->getPrefixesPsr4(), __NAMESPACE__));
if ($manifestCache ?? false) {
$main->setManifestCache($manifestCache);
}
$main->register();
}

/**
Expand Down
10 changes: 8 additions & 2 deletions src/InitSetup/tailwind/theme/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,10 @@
/**
* Set all the cache for the theme.
*/
$manifestCache = null;
if (\class_exists(ManifestCache::class)) {
(new ManifestCache())->setAllCache();
$manifestCache = new ManifestCache();
$manifestCache->setAllCache();
}

/**
Expand All @@ -62,7 +64,11 @@
* not affect the page life cycle.
*/
if (\class_exists(Main::class)) {
(new Main($loader->getPrefixesPsr4(), __NAMESPACE__))->register();
$main = (new Main($loader->getPrefixesPsr4(), __NAMESPACE__));
if ($manifestCache ?? false) {
$main->setManifestCache($manifestCache);
}
$main->register();
}

/**
Expand Down
43 changes: 42 additions & 1 deletion src/Main/Autowiring.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
use EightshiftLibs\Exception\NonPsr4CompliantClass;
use EightshiftLibs\Services\ServiceInterface;
use EightshiftLibs\Services\ServiceCliInterface;
use EightshiftLibs\Cache\AbstractManifestCache;
use EightshiftLibs\Exception\InvalidManifest;
use Exception;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
Expand All @@ -27,6 +29,13 @@
*/
class Autowiring
{
/**
* The AbstractManifestCache, optionally used for caching service classes.
*
* @var AbstractManifestCache
*/
protected AbstractManifestCache $manifestCache;

/**
* Array of psr-4 prefixes. Should be provided by Composer's ClassLoader. $ClassLoader->getPsr4Prefixes().
*
Expand All @@ -41,6 +50,23 @@ class Autowiring
*/
protected string $namespace;

/**
* A setter method for a instantiated concrete AbstractManifestCache implementation, as it can not be autowired
* at this point.
*
* @param AbstractManifestCache|null $manifestCache The manifest cache implementation.
* @return void
*/
public function setManifestCache(AbstractManifestCache $manifestCache = null): void
{
if (!$manifestCache) {
return;
}

$this->manifestCache = $manifestCache;
}


/**
* Autowiring.
*
Expand All @@ -53,6 +79,17 @@ class Autowiring
*/
public function buildServiceClasses(array $manuallyDefinedDependencies = [], bool $skipInvalid = false): array
{
try {
if (isset($this->manifestCache)) {
$serviceClasses = $this->manifestCache->getCacheTopItem('serviceClasses', AbstractManifestCache::TYPE_SERVICES, isJson: false);
if ($serviceClasses) {
return $serviceClasses;
}
}
} catch (InvalidManifest) {
// ignored, cache is simply not set.
}

$projectReflectionClasses = $this->validateAndBuildClasses(
$this->filterManuallyDefinedDependencies(
$this->getClassesInNamespace($this->namespace, $this->psr4Prefixes),
Expand Down Expand Up @@ -102,7 +139,11 @@ public function buildServiceClasses(array $manuallyDefinedDependencies = [], boo
}

// Convert dependency tree into PHP-DI's definition list.
return \array_merge($this->convertDependencyTreeIntoDefinitionList($dependencyTree), $manuallyDefinedDependencies);
$serviceClasses = \array_merge($this->convertDependencyTreeIntoDefinitionList($dependencyTree), $manuallyDefinedDependencies);
if (isset($this->manifestCache)) {
$this->manifestCache->setCustomCache(AbstractManifestCache::TYPE_SERVICES, ['serviceClasses' => $serviceClasses]);
}
return $serviceClasses;
}

// phpcs:disable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
Expand Down