Skip to content

Commit bb1fb77

Browse files
committed
Merge remote-tracking branch 'refs/remotes/origin/master' into feature/wp-modules-and-webpack-autoloader
2 parents 7f4753d + b5def07 commit bb1fb77

8 files changed

Lines changed: 398 additions & 114 deletions

File tree

docs/assets.md

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,22 @@ Each instance requires a `string $handle`, `string $url` and `int $location`.
2121

2222
Following configurations are available:
2323

24-
|property|type| default |`Script`|`ScriptModule`|`Style`|description|
25-
|----|----|------------------------------------------------------------------------------|----|----|----|----|
26-
|filePath|string| `''` |x|x|x|optional path which can be set to autodiscover the Asset version|
27-
|dependencies|array| `[]` |x|x|x|all defined depending handles|
28-
|location|int| falls back to `Asset::FRONTEND` |x|x|x|depending on location of the `Asset`, it will be enqueued with different hooks|
29-
|version|string| `null` |x|x|x|version of the given asset|
30-
|enqueue|bool/callable| `true` |x|x|x|is the asset only registered or also enqueued|
31-
|data|array/callable| `[]` |x| |x|additional data assigned to the asset via `WP_Script::add_data` or `WP_Style::add_data`|
32-
|filters|callable[]| `[]` |x| |x|an array of `Inpsyde\Assets\OutputFilter` or callable values to manipulate the output|
33-
|handler|string| `ScriptHandler::class`, `StyleHandler::class`, `ScriptModuleHandler::class` |x|x|x|The handler which will be used to register/enqueue the Asset|
34-
|attributes|array| `[]` |x| |x|Allows to set additional attributes to the `script`- or `link`-tag|
35-
|media|string| `'all'` | | |x|type of media for the `Style`|
36-
|localize|array| `[]` |x| | |localized array of data attached to `Script`|
37-
|inFooter|bool| `true` |x| | |defines if the current `Script` is printed in footer|
38-
|inline|array| `[]` |x| | |allows you to add inline scripts to `Script`-class via `['before' => [], 'after' => []]`|
39-
|translation|array| `[]` |x| | |Load translation for `Script`-class via `['path' => string, 'domain' => string]`|
24+
| property | type | default | `Script` | `ScriptModule` | `Style` | description |
25+
|--------------|----------------|------------------------------------------------------------------------------|----------|----------------|---------|------------------------------------------------------------------------------------------|
26+
| filePath | string | `''` | x | x | x | optional path which can be set to autodiscover the Asset version |
27+
| dependencies | array | `[]` | x | x | x | all defined depending handles |
28+
| location | int | falls back to `Asset::FRONTEND` | x | x | x | depending on location of the `Asset`, it will be enqueued with different hooks |
29+
| version | string | `null` | x | x | x | version of the given asset |
30+
| enqueue | bool/callable | `true` | x | x | x | is the asset only registered or also enqueued |
31+
| data | array/callable | `[]` | x | | x | additional data assigned to the asset via `WP_Script::add_data` or `WP_Style::add_data` |
32+
| filters | callable[] | `[]` | x | | x | an array of `Inpsyde\Assets\OutputFilter` or callable values to manipulate the output |
33+
| handler | string | `ScriptHandler::class`, `StyleHandler::class`, `ScriptModuleHandler::class` | x | x | x | The handler which will be used to register/enqueue the Asset |
34+
| attributes | array | `[]` | x | | x | Allows to set additional attributes to the `script`- or `link`-tag |
35+
| media | string | `'all'` | | | x | type of media for the `Style` |
36+
| localize | array | `[]` | x | | | localized array of data attached to `Script` |
37+
| inFooter | bool | `true` | x | | | defines if the current `Script` is printed in footer |
38+
| inline | array | `[]` | x | | | allows you to add inline scripts to `Script`-class via `['before' => [], 'after' => []]` |
39+
| translation | array | `[]` | x | | | Load translation for `Script`-class via `['path' => string, 'domain' => string]` |
4040

4141
## Using the public API (methods)
4242

docs/getting-started.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,55 @@ add_action(
2828
}
2929
);
3030
```
31+
32+
# Extending Assets
33+
34+
In some cases, when loading multiple Assets through a Loader like `Inpsyde\Assets\Loader\WebpackManifestLoader`, you will have the need to also extend one or multiple Assets loaded.
35+
Since the output of the `manifest.json` is fixed, we're limited with the Loader. In this case, we can make use of the `AssetManager::extendAsset()` method, which will allow us to add additional data to an Asset _before_ it is processed.
36+
37+
**manifest.json**
38+
```json
39+
{
40+
"script-handle": "/public/path/script.23dafsf2138d.js",
41+
"style-handle": "style.23dafsf2138d.css"
42+
}
43+
```
44+
45+
```php
46+
<?php
47+
use Inpsyde\Assets\AssetManager;
48+
use Inpsyde\Assets\Script;
49+
use Inpsyde\Assets\ScriptModule;
50+
use Inpsyde\Assets\Style;
51+
use Inpsyde\Assets\Loader\WebpackManifestLoader;
52+
53+
add_action(
54+
AssetManager::ACTION_SETUP,
55+
function(AssetManager $assetManager) {
56+
$assetManager->extendAsset(
57+
'style-handle',
58+
Style::class,
59+
[
60+
'inline' => ['before' => ':root { --black: #000; }']
61+
'enqueue' => false,
62+
]
63+
);
64+
$assetManager->extendAsset(
65+
'script-handle',
66+
Script::class,
67+
[
68+
'enqueue' => static fn(): bool => is_user_logged_in(),
69+
'inFooter' => true,
70+
]
71+
);
72+
73+
$loader = new WebpackManifestLoader();
74+
/** @var \Inpsyde\Assets\Asset[] $assets */
75+
$assets = $loader->load('manifest.json');
76+
77+
$assetManager->register(...$assets);
78+
}
79+
);
80+
```
81+
82+
> :information_source: **Via `array $extension`, you cannot change the `type` and `handle` and `url` of the Asset. Have a closer look into [Assets](./assets.md) documentation about the "Configuration API".**

phpstan.neon.dist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ parameters:
1111
treatPhpDocTypesAsCertain: false
1212
ignoreErrors:
1313
-
14-
message: '#Fetching class constant class of deprecated class#'
14+
message: '#Access to constant on deprecated class#'
1515
path: src/*
1616
-
1717
message: '#Instantiation of deprecated class#'

src/Asset.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66

77
use Inpsyde\Assets\Handler\AssetHandler;
88

9+
/**
10+
* @internal use BaseAsset to start your custom implementation.
11+
*/
912
interface Asset
1013
{
1114
// Location types

src/AssetCollection.php

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Inpsyde\Assets;
6+
7+
/**
8+
* @phpstan-type Assets array<Style::class|Script::class|ScriptModule::class, array<string, Asset>>
9+
*/
10+
class AssetCollection
11+
{
12+
/**
13+
* @var Assets
14+
*/
15+
protected array $assets = [];
16+
17+
/**
18+
* @param Asset $asset
19+
*
20+
* @return void
21+
*/
22+
public function add(Asset $asset): void
23+
{
24+
$type = get_class($asset);
25+
$handle = $asset->handle();
26+
$this->assets[$type][$handle] = $asset;
27+
}
28+
29+
/**
30+
* @param string $handle
31+
* @param class-string $type
32+
*
33+
* @return Asset|null
34+
*/
35+
public function get(string $handle, string $type): ?Asset
36+
{
37+
$found = null;
38+
foreach ($this->assets as $assets) {
39+
foreach ($assets as $asset) {
40+
if ($asset->handle() !== $handle) {
41+
continue;
42+
}
43+
if (is_a($asset, $type)) {
44+
$found = $asset;
45+
break 2;
46+
}
47+
}
48+
}
49+
50+
return $found;
51+
}
52+
53+
/**
54+
* @param string $handle
55+
*
56+
* @return Asset|null
57+
*
58+
* phpcs:disable Syde.Classes.DisallowGetterSetter.GetterFound
59+
*/
60+
public function getFirst(string $handle): ?Asset
61+
{
62+
$found = null;
63+
foreach ($this->assets as $assets) {
64+
foreach ($assets as $asset) {
65+
if ($asset->handle() === $handle) {
66+
$found = $asset;
67+
break 2;
68+
}
69+
}
70+
}
71+
72+
return $found;
73+
}
74+
75+
/**
76+
* @param string $handle
77+
* @param class-string $type
78+
*
79+
* @return bool
80+
*/
81+
public function has(string $handle, string $type): bool
82+
{
83+
return $this->get($handle, $type) !== null;
84+
}
85+
86+
/**
87+
* @return Assets
88+
*/
89+
public function all(): array
90+
{
91+
return $this->assets;
92+
}
93+
}

src/AssetFactory.php

Lines changed: 45 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -15,38 +15,50 @@
1515
*
1616
* phpcs:disable Syde.Files.LineLength.TooLong
1717
*
18+
* @phpstan-type AssetLocation Asset::FRONTEND|Asset::BACKEND|Asset::CUSTOMIZER|Asset::LOGIN|Asset::BLOCK_EDITOR_ASSETS|Asset::BLOCK_ASSETS|Asset::CUSTOMIZER_PREVIEW|Asset::ACTIVATE
1819
* @phpstan-type AssetConfig array{
1920
* type: class-string<Style>|class-string<Script>|class-string<ScriptModule>,
2021
* handle: string,
2122
* url: string,
22-
* location?: Asset::FRONTEND|Asset::BACKEND|Asset::CUSTOMIZER|Asset::LOGIN|Asset::BLOCK_EDITOR_ASSETS|Asset::BLOCK_ASSETS|Asset::CUSTOMIZER_PREVIEW|Asset::ACTIVATE,
23-
* filePath?: string,
24-
* version?: string,
25-
* enqueue?: bool,
26-
* handler: class-string<Handler\ScriptHandler>|class-string<Handler\StyleHandler>|class-string<Handler\ScriptModuleHandler>,
27-
* condition?: string,
28-
* attributes?: array<string, string|bool>,
29-
* translation?: array{ domain: string, path?: string},
30-
* localize?: array<string, mixed>,
31-
* inFooter?: bool,
32-
* inline?: array{before: string, after: string},
33-
* dependencies?: string[],
23+
* }
24+
* @phpstan-type AssetExtensionConfig array{
25+
* filePath?: string,
26+
* version?: string,
27+
* enqueue?: bool,
28+
* version?: string,
29+
* handler?: class-string<Handler\ScriptHandler>|class-string<Handler\StyleHandler>|class-string<Handler\ScriptModuleHandler>,
30+
* location?: AssetLocation,
31+
* condition?: string,
32+
* attributes?: array<string, string|bool>,
33+
* translation?: array{domain: string, path?:string},
34+
* localize?: array<string, mixed>, inFooter?: bool,
35+
* inline?: array{before: string, after: string},
36+
* dependencies?: string[],
3437
* }
3538
*
3639
* phpcs:enable Syde.Files.LineLength.TooLong
3740
*/
3841
final class AssetFactory
3942
{
43+
public const PROPERTIES_TO_METHOD = [
44+
'filePath' => 'withFilePath',
45+
'version' => 'withVersion',
46+
'location' => 'forLocation',
47+
'enqueue' => 'canEnqueue',
48+
'handler' => 'useHandler',
49+
'condition' => 'withCondition',
50+
'attributes' => 'withAttributes',
51+
];
52+
4053
/**
41-
* @param AssetConfig $config
54+
* @param AssetConfig&AssetExtensionConfig $config
4255
*
4356
* @return Asset
4457
* @throws Exception\MissingArgumentException
4558
* @throws Exception\InvalidArgumentException
4659
*
4760
* phpcs:disable SlevomatCodingStandard.Complexity.Cognitive.ComplexityTooHigh
4861
* phpcs:disable Syde.Functions.FunctionLength.TooLong
49-
* @psalm-suppress MixedArgument, MixedMethodCall
5062
*/
5163
public static function create(array $config): Asset
5264
{
@@ -77,22 +89,24 @@ public static function create(array $config): Asset
7789
);
7890
}
7991

80-
$propertiesToMethod = [
81-
'filePath' => 'withFilePath',
82-
'version' => 'withVersion',
83-
'location' => 'forLocation',
84-
'enqueue' => 'canEnqueue',
85-
'handler' => 'useHandler',
86-
'condition' => 'withCondition',
87-
'attributes' => 'withAttributes',
88-
];
92+
return self::configureAsset($asset, $config);
93+
}
8994

95+
/**
96+
* @param Asset $asset
97+
* @param AssetExtensionConfig $config
98+
*
99+
* @return Asset
100+
*/
101+
public static function configureAsset(Asset $asset, array $config): Asset
102+
{
90103
if ($asset instanceof Script) {
91-
foreach ($config['localize'] as $objectName => $data) {
104+
$localize = $config['localize'] ?? [];
105+
foreach ($localize as $objectName => $data) {
92106
$asset->withLocalize((string) $objectName, $data);
93107
}
94108

95-
if (isset($config['translation'])) {
109+
if (isset($config['translation']) && isset($config['translation']['domain'])) {
96110
/** @var array{domain:string, path:?string} $translations */
97111
$translations = $config['translation'];
98112
$asset->withTranslation(
@@ -119,17 +133,20 @@ public static function create(array $config): Asset
119133
}
120134
}
121135

136+
$propertiesToMethod = self::PROPERTIES_TO_METHOD;
122137

123138
if ($asset instanceof Style) {
124139
$propertiesToMethod['media'] = 'forMedia';
125140
$propertiesToMethod['inlineStyles'] = 'withInlineStyles';
126-
$propertiesToMethod['media'] = 'forMedia';
127141
}
128142

129143
foreach ($propertiesToMethod as $key => $methodName) {
130144
if (!isset($config[$key])) {
131145
continue;
132146
}
147+
if (!method_exists($asset, $methodName)) {
148+
continue;
149+
}
133150
$asset->{$methodName}($config[$key]);
134151
}
135152

@@ -146,7 +163,7 @@ public static function create(array $config): Asset
146163
/**
147164
* @param AssetConfig $config
148165
*
149-
* @return AssetConfig
166+
* @return AssetConfig|AssetExtensionConfig
150167
*
151168
* @throws Exception\MissingArgumentException
152169
*/
@@ -242,7 +259,7 @@ private static function normalizeTranslationConfig(array $config): array
242259
/**
243260
* @param AssetConfig $config
244261
*
245-
* @return AssetConfig&array{localize:array<string,mixed>}
262+
* @return array{localize:array<string,mixed>}
246263
*/
247264
private static function normalizeLocalizeConfig(array $config): array
248265
{

0 commit comments

Comments
 (0)