Skip to content

Commit f960e9b

Browse files
committed
✨ smartly delaying query language with {( query )}
Signed-off-by: bnomei <[email protected]>
1 parent 3176614 commit f960e9b

File tree

6 files changed

+148
-73
lines changed

6 files changed

+148
-73
lines changed

README.md

Lines changed: 63 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,11 @@ fields:
6363
6464
Janitor will automatically fill in the current model.
6565
66-
- So for example if you press the panel button on a page you will have `--page` argument set.
67-
- If you call it on a user then `--user` arg will be set.
68-
- On a panel file view... `--file`.
69-
- And lastly `--site` will be automatically set when you had the button in the `site/blueprints/site.yml` blueprint.
66+
- The `--model` argument will have the UUID or ID of the current model. You can use `janitor()->model($cli->arg('model))` to get the object.
67+
- But if for example you press the panel button on a page you will have `--page` argument set to the UUID or ID of that page. Use `$cli->kirby()->page($cli->arg('page'))` to get the object.
68+
- If you call it on a file view then `--file` arg will be set. Use `$cli->kirby()->file($cli->arg('file'))` to get the object.
69+
- On a panel user view... `--user`. Use `$cli->kirby()->user($cli->arg('user'))` to get the object.
70+
- And lastly `--site` (boolean) will be automatically set when you had the button in the `site/blueprints/site.yml` blueprint. `if($cli->arg('site')) { $cli->kirby()->site(); }`
7071

7172
Create a Kirby CLI command [via a custom plugin](https://getkirby.com/docs/reference/plugins/extensions/commands) or put them into `site/commands`.
7273

@@ -185,57 +186,72 @@ In either the command or the callback you will be setting/returning data to the
185186
Again... check out the [built-in commands](https://github.com/bnomei/kirby3-janitor/tree/master/commands) and plugin [example commands](https://github.com/bnomei/kirby3-janitor/tree/master/tests/site/commands) to learn how to use the field and api options yourself.
186187

187188
```yml
188-
test_ping:
189-
type: janitor
190-
command: 'ping' # see tests/site/commands/ping.php
191-
label: Ping
192-
progress: ....
193-
success: Pong
194-
error: BAMM
189+
test_ping:
190+
type: janitor
191+
command: 'ping' # see tests/site/commands/ping.php
192+
label: Ping
193+
progress: ....
194+
success: Pong
195+
error: BAMM
196+
197+
janitor_open:
198+
type: janitor
199+
command: 'janitor:open --data {{ user.panel.url }}'
200+
intab: true
201+
label: Open current user URL in new tab
202+
icon: open
203+
# the open command will forward the `data` arg to `open` and open that URL
204+
205+
janitor_clipboarddata:
206+
type: janitor
207+
command: 'janitor:clipboard --data {{ page.title }}'
208+
label: 'Copy "{{ page.title }}" to Clipboard'
209+
progress: Copied!
210+
icon: copy
211+
# the clipboard command will forward the `data` arg to `clipboard` and copy that
212+
213+
janitor_download:
214+
type: janitor
215+
command: 'janitor:download --data {{ site.index.files.first.url }}'
216+
label: Download File Example
217+
icon: download
218+
# the download command will forward the `data` arg to `download` and start downloading that
219+
220+
janitor_backupzip:
221+
type: janitor
222+
command: 'janitor:backupzip'
223+
cooldown: 5000
224+
label: Generate Backup ZIP
225+
icon: archive
226+
227+
janitor_render:
228+
type: janitor
229+
command: 'janitor:render'
230+
label: Render pages to create missing thumb jobs
231+
232+
janitor_thumbssite:
233+
type: janitor
234+
command: 'janitor:thumbs --site'
235+
label: Generate thumbs from existing thumb jobs (full site)
236+
```
195237
196-
janitor_open:
197-
type: janitor
198-
command: 'janitor:open --data {{ user.panel.url }}'
199-
intab: true
200-
label: Open current user URL in new tab
201-
icon: open
202-
# the open command will forward the `data` arg to `open` and open that URL
238+
If you want you can also call any of [the core shipping with the CLI](https://github.com/getkirby/cli#available-core-commands) like `clear:cache`.
203239

204-
janitor_clipboarddata:
205-
type: janitor
206-
command: 'janitor:clipboard --data {{ page.title }}'
207-
label: 'Copy "{{ page.title }}" to Clipboard'
208-
progress: Copied!
209-
icon: copy
210-
# the clipboard command will forward the `data` arg to `clipboard` and copy that
240+
### Smartly delaying resolution of an command argument
211241

212-
janitor_download:
213-
type: janitor
214-
command: 'janitor:download --data {{ site.index.files.first.url }}'
215-
label: Download File Example
216-
icon: download
217-
# the download command will forward the `data` arg to `download` and start downloading that
242+
In some cases you do not want to resolve the query language of a commands argument(s) **every time** when the button is shown in the panel but delay that until the api call is received by Janitor. Janitor will then resolve it **once** and forward the updated argument(s) to your command. This is useful for process-intensive calls or when the string of the data would be very long, like when the data is HTML.
218243

219-
janitor_backupzip:
220-
type: janitor
221-
command: 'janitor:backupzip'
222-
cooldown: 5000
223-
label: Generate Backup ZIP
224-
icon: archive
244+
To achieve this you need to change the query language bounds for that argument from `{{ query }}` to `{( query )}`.
225245

226-
janitor_render:
227-
type: janitor
228-
command: 'janitor:render'
229-
label: Render pages to create missing thumb jobs
246+
> Note: This only works inside the Janitor fields `command`-property.
230247

231-
janitor_thumbssite:
232-
type: janitor
233-
command: 'janitor:thumbs --site'
234-
label: Generate thumbs from existing thumb jobs (full site)
248+
```yml
249+
test_sendmail:
250+
type: janitor
251+
command: 'sendmail --to {{ user.email }} --data {( page.htmlOfEmail )}'
252+
label: send mail
235253
```
236254

237-
If you want you can also call any of [the core shipping with the CLI](https://github.com/getkirby/cli#available-core-commands) like `clear:cache`.
238-
239255
### Running commands in your code
240256

241257
You can run any command in you own code as well like in a model, template, controller or hook. Since commands do not return data directly you need to retrieve data stored for Janitor using a helper `janitor()->data($commandName)`.

classes/Janitor.php

Lines changed: 72 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,12 @@ final class Janitor
4242
'prefix' => 'd',
4343
'longPrefix' => 'data',
4444
'description' => 'Data',
45-
]
45+
],
46+
'model' => [
47+
'prefix' => 'm',
48+
'longPrefix' => 'model',
49+
'description' => 'Model (Page, File, User, Site) UUID or ID',
50+
],
4651
];
4752

4853
private static array $data;
@@ -85,6 +90,7 @@ public function option(?string $key = null): mixed
8590
public function command(string $command): array
8691
{
8792
list($name, $args) = Janitor::parseCommand($command);
93+
$args = Janitor::resolveQueriesInCommand($args); // like a "lazy/smart" `{( page.callme )}`
8894

8995
CLI::command($name, ...$args);
9096

@@ -94,6 +100,11 @@ public function command(string $command): array
94100
];
95101
}
96102

103+
public function model(string $uuid): mixed
104+
{
105+
return Janitor::resolveModel($uuid);
106+
}
107+
97108
private static $singleton;
98109

99110
public static function singleton(array $options = []): Janitor
@@ -107,6 +118,32 @@ public static function singleton(array $options = []): Janitor
107118
return self::$singleton;
108119
}
109120

121+
public static function isTrue($val, bool $return_null = false): bool
122+
{
123+
$boolval = (is_string($val) ? filter_var($val, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) : (bool) $val);
124+
125+
return ($boolval === null && !$return_null ? false : $boolval);
126+
}
127+
128+
public static function parseCommand(string $command)
129+
{
130+
$groups = explode(' ', $command);
131+
$name = array_shift($groups);
132+
$groups = explode(' --', ' ' . implode(' ', $groups));
133+
array_shift($groups); // remove empty first value
134+
$args = [];
135+
136+
foreach ($groups as $group) {
137+
$parts = explode(' ', $group);
138+
$args[] = '--' . array_shift($parts);
139+
// remove enclosing " or ' from string like it would happen
140+
// in terminal so commands in blueprint can be used vice versa
141+
$args[] = trim(trim(implode(' ', $parts), '"'), "'");
142+
}
143+
144+
return [$name, $args];
145+
}
146+
110147
public static function query(string $template = null, mixed $model = null): string
111148
{
112149
$page = null;
@@ -130,13 +167,6 @@ public static function query(string $template = null, mixed $model = null): stri
130167
]);
131168
}
132169

133-
public static function isTrue($val, bool $return_null = false): bool
134-
{
135-
$boolval = (is_string($val) ? filter_var($val, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) : (bool) $val);
136-
137-
return ($boolval === null && !$return_null ? false : $boolval);
138-
}
139-
140170
public static function requestBlockedByMaintenance(): bool
141171
{
142172
$request = kirby()->request()->url()->toString();
@@ -152,22 +182,43 @@ public static function requestBlockedByMaintenance(): bool
152182
return true;
153183
}
154184

155-
public static function parseCommand(string $command)
185+
public static function resolveModel(string $uuid): mixed
156186
{
157-
$groups = explode(' ', $command);
158-
$name = array_shift($groups);
159-
$groups = explode(' --', ' ' . implode(' ', $groups));
160-
array_shift($groups); // remove empty first value
161-
$args = [];
187+
if(Str::startsWith($uuid, 'page://')) {
188+
return kirby()->page($uuid);
189+
} elseif(Str::startsWith($uuid, 'file://')) {
190+
return kirby()->file($uuid);
191+
} elseif(Str::startsWith($uuid, 'user://') || Str::contains($uuid, '@')) {
192+
return kirby()->user($uuid);
193+
} elseif(Str::startsWith($uuid, 'site://') || $uuid === '$') {
194+
return kirby()->site();
195+
}
162196

163-
foreach ($groups as $group) {
164-
$parts = explode(' ', $group);
165-
$args[] = '--' . array_shift($parts);
166-
// remove enclosing " or ' from string like it would happen
167-
// in terminal so commands in blueprint can be used vice versa
168-
$args[] = trim(trim(implode(' ', $parts), '"'), "'");
197+
foreach(['page', 'file', 'user'] as $finder) {
198+
if($model = kirby()->{$finder}($uuid)) {
199+
return $model;
200+
}
169201
}
170202

171-
return [$name, $args];
203+
return null;
204+
}
205+
206+
public static function resolveQueriesInCommand(array $args): array
207+
{
208+
$modelKey = array_search('--model', $args);
209+
$model = $modelKey !== false && $modelKey + 1 < count($args) ? $args[$modelKey + 1] : null;
210+
$model = Janitor::resolveModel($model);
211+
212+
$args = array_map(function($value) use ($model) {
213+
// allows for html even without {< since it is not a blueprint query
214+
// but just a string inside the command
215+
$value = str_replace(['{(',')}'], ['{{', '}}'], $value, $count);
216+
if ($count > 0) {
217+
$value = Janitor::query($value, $model);
218+
}
219+
return $value;
220+
}, $args);
221+
222+
return $args;
172223
}
173224
}

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "bnomei/kirby3-janitor",
33
"type": "kirby-plugin",
4-
"version": "3.1.0",
4+
"version": "3.2.0",
55
"license": "MIT",
66
"description": "Kirby 3 Plugin for running commands like cleaning the cache from within the Panel, PHP code or a cronjob",
77
"authors": [

index.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@
4949
} elseif ($this->model() instanceof \Kirby\Cms\Site) {
5050
$command .= ' --site'; // boolean argument
5151
}
52+
$command .= ' --model '. $this->model()->uuid()->toString() ??
53+
($this->model() instanceof \Kirby\Cms\Site ? 'site://' : $this->model()->id());
5254
return $command;
5355
},
5456
'confirm' => function ($confirm = '') {

tests/site/blueprints/pages/default.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,3 +152,9 @@ fields:
152152
type: janitor
153153
command: 'janitor:thumbs' # NOTE: without --site
154154
label: Generate thumbs from existing thumb jobs (only this page)
155+
156+
janitor_smart:
157+
label: 'Resolve Arg smart/lazy using {( instead of {{'
158+
type: janitor
159+
command: 'janitor:pipe --data {( model.text.kirbytext )} --to message'
160+
# pipe will show lazy/smart resolved data on button (aka the message)

vendor/composer/installed.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<?php return array(
22
'root' => array(
33
'name' => 'bnomei/kirby3-janitor',
4-
'pretty_version' => '3.1.0',
5-
'version' => '3.1.0.0',
4+
'pretty_version' => '3.2.0',
5+
'version' => '3.2.0.0',
66
'reference' => NULL,
77
'type' => 'kirby-plugin',
88
'install_path' => __DIR__ . '/../../',
@@ -11,8 +11,8 @@
1111
),
1212
'versions' => array(
1313
'bnomei/kirby3-janitor' => array(
14-
'pretty_version' => '3.1.0',
15-
'version' => '3.1.0.0',
14+
'pretty_version' => '3.2.0',
15+
'version' => '3.2.0.0',
1616
'reference' => NULL,
1717
'type' => 'kirby-plugin',
1818
'install_path' => __DIR__ . '/../../',

0 commit comments

Comments
 (0)