Skip to content

Commit

Permalink
JsCallback always terminates with success (#2195)
Browse files Browse the repository at this point in the history
  • Loading branch information
mvorisek authored Mar 31, 2024
1 parent 1722c8e commit 0d4dc18
Show file tree
Hide file tree
Showing 10 changed files with 37 additions and 29 deletions.
5 changes: 4 additions & 1 deletion docs/callbacks.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,10 @@ $label->link($cb->getUrl());
When you trigger callback, you'll see the output:

```
{"success": true, "message": "Success", "eval": "alert(\"ok\")"}
{
"success": true,
"atkjs": "alert(\"ok\");"
}
```

This is how JsCallback renders actions and sends them back to the browser. In order to retrieve and execute actions,
Expand Down
5 changes: 4 additions & 1 deletion phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -399,4 +399,7 @@ parameters:
message: '~^Parameter #1 \$object of method Atk4\\Ui\\App::add\(\) expects Atk4\\Ui\\AbstractView, array given\.$~'
-
path: 'src/Popup.php'
message: '~^Parameter #1 \$view of method Atk4\\Ui\\Callback::terminateJson\(\) expects Atk4\\Ui\\View, Atk4\\Ui\\AbstractView given\.$~'
message: '~^Parameter #1 \$ of closure expects Atk4\\Ui\\View, Atk4\\Ui\\AbstractView given\.$~'
-
path: 'src/Popup.php'
message: '~^Parameter #1 \$view of method Atk4\\Ui\\Callback::terminateJsonIfCanTerminate\(\) expects Atk4\\Ui\\View, Atk4\\Ui\\AbstractView given\.$~'
2 changes: 1 addition & 1 deletion src/Callback.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public function set($fx = null, $fxArgs = null)
/**
* Terminate this callback by rendering the given view.
*/
public function terminateJson(View $view): void
public function terminateJsonIfCanTerminate(View $view): void
{
if ($this->canTerminate()) {
$this->getApp()->terminateJson($view);
Expand Down
6 changes: 3 additions & 3 deletions src/Form/Control/Multiline.php
Original file line number Diff line number Diff line change
Expand Up @@ -685,9 +685,9 @@ private function outputJson(): void
// no break - expression above always terminate
case 'on-change':
$rowsRaw = $this->getApp()->decodeJson($this->getApp()->getRequestPostParam('rows'));
$response = ($this->onChangeFunction)($this->typeCastLoadValues($rowsRaw), $this->form);
$this->renderCallback->terminateAjax($this->renderCallback->getAjaxec($response));
// TODO JsCallback::terminateAjax() should return never
$this->renderCallback->set(function () use ($rowsRaw) {
return ($this->onChangeFunction)($this->typeCastLoadValues($rowsRaw), $this->form);
});
}
}

Expand Down
16 changes: 6 additions & 10 deletions src/JsCallback.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public function set($fx = null, $args = null)

$ajaxec = $this->getAjaxec($response);

$this->terminateAjax($ajaxec);
$this->terminateAjaxIfCanTerminate($ajaxec);
});

return $this;
Expand All @@ -102,17 +102,13 @@ public function set($fx = null, $args = null)
/**
* A proper way to finish execution of AJAX response. Generates JSON
* which is returned to frontend.
*
* @param ($success is true ? null : string) $msg General message, typically won't be displayed
* @param bool $success Was request successful or not
*/
public function terminateAjax(JsBlock $ajaxec, $msg = null, bool $success = true): void
protected function terminateAjaxIfCanTerminate(JsBlock $ajaxec): void
{
$data = ['success' => $success];
if (!$success) {
$data['message'] = $msg;
}
$data['atkjs'] = $ajaxec->jsRender();
$data = [
'success' => true,
'atkjs' => $ajaxec->jsRender(),
];

if ($this->canTerminate()) {
$this->getApp()->terminateJson($data);
Expand Down
8 changes: 4 additions & 4 deletions src/JsSse.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,13 @@ protected function initSse(): void
/**
* Sending an SSE action.
*/
public function send(JsExpressionable $action, bool $success = true): void
public function send(JsExpressionable $action): void
{
$ajaxec = $this->getAjaxec($action);
$this->sendEvent(
'',
$this->getApp()->encodeJson([
'success' => $success,
'success' => true,
'atkjs' => $ajaxec->jsRender(),
]),
'atkSseAction'
Expand All @@ -100,14 +100,14 @@ public function send(JsExpressionable $action, bool $success = true): void
* @return never
*/
#[\Override]
public function terminateAjax(JsBlock $ajaxec, $msg = null, bool $success = true): void
protected function terminateAjaxIfCanTerminate(JsBlock $ajaxec): void
{
$ajaxecStr = $ajaxec->jsRender();
if ($ajaxecStr !== '') {
$this->sendEvent(
'',
$this->getApp()->encodeJson([
'success' => $success,
'success' => true,
'atkjs' => $ajaxecStr,
]),
'atkSseAction'
Expand Down
3 changes: 2 additions & 1 deletion src/Loader.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ public function set($fx = null)

$this->cb->set(function () use ($fx) {
$fx($this);
$this->cb->terminateJson($this->getShimIfOwner());

$this->cb->terminateJsonIfCanTerminate($this->getShimIfOwner());
});

return $this;
Expand Down
3 changes: 2 additions & 1 deletion src/Modal.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ public function enableCallback(): void

$this->cb->set(function () {
($this->fx)($this->cbView);
$this->cb->terminateJson($this->cbView);

$this->cb->terminateJsonIfCanTerminate($this->cbView);
});
}

Expand Down
3 changes: 2 additions & 1 deletion src/Panel/Content.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ public function onLoad(\Closure $fx): void
{
$this->cb->set(function () use ($fx) {
$fx($this);
$this->cb->terminateJson($this);

$this->cb->terminateJsonIfCanTerminate($this);
});
}

Expand Down
15 changes: 9 additions & 6 deletions src/Popup.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,12 +145,15 @@ public function set($fx = null)
$this->minHeight = '45px';
}

// create content view to pass to callback
$content = $this->add($this->dynamicContent);
$this->cb->set($fx, [$content]);
// only render our content view
// PopupService will replace content with this one
$this->cb->terminateJson($content);
$this->cb->set(function () use ($fx) {
// create content view to pass to callback
$content = $this->add($this->dynamicContent);

$fx($content);

// only render our content view, PopupService will replace content with this one
$this->cb->terminateJsonIfCanTerminate($content);
});

return $this;
}
Expand Down

0 comments on commit 0d4dc18

Please sign in to comment.