Skip to content

Commit

Permalink
DEVEL strict ID typecasting
Browse files Browse the repository at this point in the history
  • Loading branch information
mvorisek committed Feb 14, 2024
1 parent 1a08707 commit 1a35de8
Show file tree
Hide file tree
Showing 24 changed files with 85 additions and 34 deletions.
2 changes: 1 addition & 1 deletion demos/_unit-test/modal-error.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
$button = Button::addTo($p)->set('Test ModalExecutor load PHP error');
$executor = ModalExecutor::assertInstanceOf($p->getExecutorFactory()->createExecutor($country->getUserAction('edit'), $button));
if (\Closure::bind(static fn () => $executor->loader, null, ModalExecutor::class)()->cb->isTriggered()) {
$executor->stickyGet($executor->name, '99000'); // no such record so load will fail
$executor->stickyGet($executor->name, '218099000');
}
$button->on('click', $executor);
});
Expand Down
2 changes: 1 addition & 1 deletion demos/basic/breadcrumb.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
$model = new Country($app->db);
$model->setLimit(15);

$id = $app->uiPersistence->typecastLoadField($model->getField($model->idField), $crumb->stickyGet('country_id'));
$id = $app->uiPersistence->typecastAttributeLoadField($model->getField($model->idField), $crumb->stickyGet('country_id'));
if ($id !== null) {
// perhaps we edit individual country?
$model = $model->load($id);
Expand Down
8 changes: 4 additions & 4 deletions demos/collection/multitable.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ private function explodeSelectionValue(string $value): array
{
$res = [];
foreach ($value === '' ? [] : explode(',', $value) as $v) {
$res[] = $this->getApp()->uiPersistence->typecastLoadField($this->model->getField($this->model->idField), $v);
$res[] = $this->getApp()->uiPersistence->typecastAttributeLoadField($this->model->getField($this->model->idField), $v);
}

return $res;
Expand All @@ -50,7 +50,7 @@ public function setModel(Model $model, array $route = []): void
$selections = $this->explodeSelectionValue($this->getApp()->tryGetRequestQueryParam($this->name) ?? '');

if ($selections !== []) {
$table->js(true)->find('tr[data-id=' . $this->getApp()->uiPersistence->typecastSaveField($this->model->getField($this->model->idField), $selections[0]) . ']')->addClass('active');
$table->js(true)->find('tr[data-id=' . $this->getApp()->uiPersistence->typecastAttributeSaveField($this->model->getField($this->model->idField), $selections[0]) . ']')->addClass('active');
}

$makeJsReloadFx = function (array $path): JsReload {
Expand All @@ -65,7 +65,7 @@ public function setModel(Model $model, array $route = []): void
$table->on('click', 'tr', $jsReload);

while ($id = array_shift($selections)) {
$path[] = $this->getApp()->uiPersistence->typecastSaveField($this->model->getField($this->model->idField), $id);
$path[] = $this->getApp()->uiPersistence->typecastAttributeSaveField($this->model->getField($this->model->idField), $id);
$pushModel = new $model($model->getPersistence());
$pushModel = $pushModel->tryLoad($id);
if ($pushModel === null) {
Expand All @@ -87,7 +87,7 @@ public function setModel(Model $model, array $route = []): void
$table->setModel($pushModel->setLimit(10), [$pushModel->titleField]);

if ($selections !== []) {
$table->js(true)->find('tr[data-id=' . $this->getApp()->uiPersistence->typecastSaveField($this->model->getField($this->model->idField), $selections[0]) . ']')->addClass('active');
$table->js(true)->find('tr[data-id=' . $this->getApp()->uiPersistence->typecastAttributeSaveField($this->model->getField($this->model->idField), $selections[0]) . ']')->addClass('active');
}

$jsReload = $makeJsReloadFx($path);
Expand Down
2 changes: 1 addition & 1 deletion demos/form-control/multiline.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
return $multiline->saveRows()->model->export();
});

$rows = array_map(static fn ($row) => $form->getApp()->uiPersistence->typecastSaveRow($multiline->model, $row), $rows);
$rows = array_map(static fn ($row) => $form->getApp()->uiPersistence->typecastAttributeSaveRow($multiline->model, $row), $rows);

Check failure on line 64 in demos/form-control/multiline.php

View workflow job for this annotation

GitHub Actions / Smoke (latest, StaticAnalysis)

Call to an undefined method Atk4\Ui\Persistence\Ui::typecastAttributeSaveRow().

Check failure on line 64 in demos/form-control/multiline.php

View workflow job for this annotation

GitHub Actions / Smoke (latest, StaticAnalysis)

Call to an undefined method Atk4\Ui\Persistence\Ui::typecastAttributeSaveRow().

return new JsToast($form->getApp()->encodeJson($rows));
});
2 changes: 1 addition & 1 deletion demos/interactive/loader2.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@

$countryLoader->set(static function (Loader $p) {
$country = new Country($p->getApp()->db);
$id = $p->getApp()->uiPersistence->typecastLoadField($country->getField($country->idField), $p->getApp()->getRequestQueryParam('id'));
$id = $p->getApp()->uiPersistence->typecastAttributeLoadField($country->getField($country->idField), $p->getApp()->getRequestQueryParam('id'));
Form::addTo($p)->setModel($country->load($id));
});
2 changes: 1 addition & 1 deletion demos/layout/layout-panel.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@
Header::addTo($app, ['UserAction Friendly', 'size' => 4, 'subHeader' => 'Panel can run model action.']);

$panel3 = Panel\Right::addTo($app);
$countryId = $app->uiPersistence->typecastLoadField($country->getField($country->idField), $panel3->stickyGet('id'));
$countryId = $app->uiPersistence->typecastAttributeLoadField($country->getField($country->idField), $panel3->stickyGet('id'));
$msg = Message::addTo($panel3, ['Run Country model action below.']);

$deck = View::addTo($app, ['ui' => 'cards']);
Expand Down
2 changes: 1 addition & 1 deletion src/Card.php
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ public function setModel(Model $entity, array $fields = null): void
$fields = array_keys($this->model->getFields(['editable', 'visible']));
}

$this->template->trySet('dataId', $this->getApp()->uiPersistence->typecastSaveField($this->model->getField($this->model->idField), $this->model->getId()));
$this->template->trySet('dataId', $this->getApp()->uiPersistence->typecastAttributeSaveField($this->model->getField($this->model->idField), $this->model->getId()));

View::addTo($this->getSection(), [$entity->getTitle(), 'class.header' => true]);
$this->getSection()->addFields($entity, $fields, $this->useLabel, $this->useTable);
Expand Down
2 changes: 1 addition & 1 deletion src/Crud.php
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ protected function getJsGridAction(Model\UserAction $action): ?JsExpressionable
case Model\UserAction::MODIFIER_DELETE:
// use deleted record ID to remove row, fallback to closest tr if ID is not available
$js = $this->deletedId
? $this->js(false, null, 'tr[data-id="' . $this->getApp()->uiPersistence->typecastSaveField($this->model->getField($this->model->idField), $this->deletedId) . '"]')
? $this->js(false, null, 'tr[data-id="' . $this->getApp()->uiPersistence->typecastAttributeSaveField($this->model->getField($this->model->idField), $this->deletedId) . '"]')
: (new Jquery())->closest('tr');
$js = $js->transition('fade left', new JsFunction([], [new JsExpression('this.remove()')]));

Expand Down
6 changes: 5 additions & 1 deletion src/Form.php
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,11 @@ protected function loadPost(): void
}

try {
$control->set($this->getApp()->uiPersistence->typecastLoadField($control->entityField->getField(), $postRawValue));
if ($control instanceof Control\Dropdown || $control instanceof Control\Lookup) { // this condition is definitely unacceptable, also should Control::set() be in the catch?
$control->set($this->getApp()->uiPersistence->typecastAttributeLoadField($control->entityField->getField(), $postRawValue));
} else {
$control->set($this->getApp()->uiPersistence->typecastLoadField($control->entityField->getField(), $postRawValue));
}
} catch (\Exception $e) {
if ($e instanceof \ErrorException) {
throw $e;
Expand Down
4 changes: 2 additions & 2 deletions src/Form/Control/Dropdown.php
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ protected function _renderItemsForModel(): void
{
foreach ($this->model as $id => $row) {
$title = $row->getTitle();
$this->_tItem->set('value', $this->getApp()->uiPersistence->typecastSaveField($this->model->getField($this->model->idField), $id));
$this->_tItem->set('value', $this->getApp()->uiPersistence->typecastSaveAttributeField($this->model->getField($this->model->idField), $id));

Check failure on line 235 in src/Form/Control/Dropdown.php

View workflow job for this annotation

GitHub Actions / Smoke (latest, StaticAnalysis)

Call to an undefined method Atk4\Ui\Persistence\Ui::typecastSaveAttributeField().

Check failure on line 235 in src/Form/Control/Dropdown.php

View workflow job for this annotation

GitHub Actions / Smoke (latest, StaticAnalysis)

Call to an undefined method Atk4\Ui\Persistence\Ui::typecastSaveAttributeField().
$this->_tItem->set('title', $title || is_numeric($title) ? (string) $title : '');
// add item to template
$this->template->dangerouslyAppendHtml('Item', $this->_tItem->renderToHtml());
Expand Down Expand Up @@ -274,7 +274,7 @@ protected function _addCallBackRow($row, $key = null): void
{
if ($this->model !== null) {
$res = ($this->renderRowFunction)($row);
$this->_tItem->set('value', $this->getApp()->uiPersistence->typecastSaveField($this->model->getField($this->model->idField), $row->getId()));
$this->_tItem->set('value', $this->getApp()->uiPersistence->typecastAttributeSaveField($this->model->getField($this->model->idField), $row->getId()));
} else {
$res = ($this->renderRowFunction)($row, $key); // @phpstan-ignore-line https://github.com/phpstan/phpstan/issues/10283#issuecomment-1850438891
$this->_tItem->set('value', (string) $res['value']); // @phpstan-ignore-line https://github.com/phpstan/phpstan/issues/10283
Expand Down
2 changes: 1 addition & 1 deletion src/Form/Control/DropdownCascade.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ protected function init(): void
}

$cascadeFromValue = $this->getApp()->hasRequestPostParam($this->cascadeFrom->name)
? $this->getApp()->uiPersistence->typecastLoadField($this->cascadeFrom->entityField->getField(), $this->getApp()->getRequestPostParam($this->cascadeFrom->name))
? $this->getApp()->uiPersistence->typecastAttributeLoadField($this->cascadeFrom->entityField->getField(), $this->getApp()->getRequestPostParam($this->cascadeFrom->name))
: $this->cascadeFrom->entityField->get();

$this->model = $this->cascadeFrom->model ? $this->cascadeFrom->model->ref($this->reference) : null;
Expand Down
3 changes: 2 additions & 1 deletion src/Form/Control/Lookup.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Atk4\Data\Model;
use Atk4\Ui\Button;
use Atk4\Ui\CallbackLater;
use Atk4\Ui\Demos\WrappedId;
use Atk4\Ui\Form;
use Atk4\Ui\Js\Jquery;
use Atk4\Ui\Js\JsBlock;
Expand Down Expand Up @@ -230,7 +231,7 @@ protected function defaultRenderRow(Model $row)
$titleField = $this->titleField ?? $row->titleField;

return [
'value' => $this->getApp()->uiPersistence->typecastSaveField($row->getField($idField), $row->get($idField)),
'value' => $this->getApp()->uiPersistence->typecastAttributeSaveField($row->getField($idField), $row->get($idField)),
'title' => $row->get($titleField),
];
}
Expand Down
13 changes: 9 additions & 4 deletions src/Form/Control/Multiline.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Atk4\Data\Model;
use Atk4\Data\Persistence;
use Atk4\Data\ValidationException;
use Atk4\Ui\Demos\WrappedId;
use Atk4\Ui\Exception;
use Atk4\Ui\Form;
use Atk4\Ui\HtmlTemplate;
Expand Down Expand Up @@ -252,7 +253,9 @@ protected function typeCastLoadValues(array $values): array
if ($fieldName === '__atkml') {
$dataRows[$k][$fieldName] = $value;
} else {
$dataRows[$k][$fieldName] = $this->getApp()->uiPersistence->typecastLoadField($this->model->getField($fieldName), $value);
$dataRows[$k][$fieldName] = $fieldName === $this->model->idField
? $this->getApp()->uiPersistence->typecastAttributeLoadField($this->model->getField($fieldName), $value)
: $this->getApp()->uiPersistence->typecastLoadField($this->model->getField($fieldName), $value);
}
}
}
Expand Down Expand Up @@ -288,7 +291,9 @@ public function getValue(): string
$cols = [];
foreach ($this->rowFields as $fieldName) {
$field = $this->model->getField($fieldName);
$value = $this->getApp()->uiPersistence->typecastSaveField($field, $row->get($field->shortName));
$value = $field->shortName === $this->model->idField
? $this->getApp()->uiPersistence->typecastAttributeSaveField($field, $row->get($field->shortName))
: $this->getApp()->uiPersistence->typecastSaveField($field, $row->get($field->shortName));
$cols[$fieldName] = $value;
}
$rows[] = $cols;
Expand Down Expand Up @@ -556,7 +561,7 @@ protected function getLookupProps(Field $field): array
public function setLookupOptionValue(Field $field, string $value): void
{
$model = $field->getReference()->refModel($this->model);
$entity = $model->tryLoadBy($field->getReference()->getTheirFieldName($model), $this->getApp()->uiPersistence->typecastLoadField($field, $value));
$entity = $model->tryLoadBy($field->getReference()->getTheirFieldName($model), $this->getApp()->uiPersistence->typecastAttributeLoadField($field, $value));
if ($entity !== null) {
$option = ['key' => $value, 'text' => $entity->get($model->titleField), 'value' => $value];
foreach ($this->fieldDefs as $key => $component) {
Expand Down Expand Up @@ -617,7 +622,7 @@ protected function getFieldItems(Field $field, ?int $limit = 10): array

$theirFieldName = $field->getReference()->getTheirFieldName($model);
foreach ($model as $item) {
$theirValue = $this->getApp()->uiPersistence->typecastSaveField($model->getField($theirFieldName), $item->get($theirFieldName));
$theirValue = $this->getApp()->uiPersistence->typecastSaveAttributeField($model->getField($theirFieldName), $item->get($theirFieldName));

Check failure on line 625 in src/Form/Control/Multiline.php

View workflow job for this annotation

GitHub Actions / Smoke (latest, StaticAnalysis)

Call to an undefined method Atk4\Ui\Persistence\Ui::typecastSaveAttributeField().

Check failure on line 625 in src/Form/Control/Multiline.php

View workflow job for this annotation

GitHub Actions / Smoke (latest, StaticAnalysis)

Call to an undefined method Atk4\Ui\Persistence\Ui::typecastSaveAttributeField().
$items[$theirValue] = $item->get($model->titleField);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Grid.php
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,7 @@ private function explodeSelectionValue(string $value): array
{
$res = [];
foreach ($value === '' ? [] : explode(',', $value) as $v) {
$res[] = $this->getApp()->uiPersistence->typecastLoadField($this->model->getField($this->model->idField), $v);
$res[] = $this->getApp()->uiPersistence->typecastAttributeLoadField($this->model->getField($this->model->idField), $v);
}

return $res;
Expand Down
8 changes: 8 additions & 0 deletions src/Js/JsExpression.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@
namespace Atk4\Ui\Js;

use Atk4\Core\DiContainerTrait;
use Atk4\Data\Field;
use Atk4\Data\Persistence;
use Atk4\Ui\Demos\WrappedId;
use Atk4\Ui\Demos\WrappedIdType;
use Atk4\Ui\Exception;
use Atk4\Ui\Persistence\Ui as UiPersistence;
use Atk4\Ui\View;

class JsExpression implements JsExpressionable
Expand Down Expand Up @@ -107,6 +111,10 @@ protected function _jsEncode($value): string
$res = Persistence\Sql\Expression::castFloatToString($value);
} elseif ($value === null) {
$res = 'null';
} elseif ($value instanceof WrappedId) {
// HACK for debug
$uiPersistence = new UiPersistence();
$res = $this->_jsEncode($uiPersistence->typecastAttributeSaveField(new Field(['type' => WrappedIdType::NAME]), $value));
} else {
throw (new Exception('Argument is not renderable to JS'))
->addMoreInfo('arg', $value);
Expand Down
2 changes: 1 addition & 1 deletion src/JsSortable.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public function onReorder(\Closure $fx, Field $idField): void
$newIndex = (int) $this->getApp()->getRequestPostParam('newIndex');
$origIndex = (int) $this->getApp()->getRequestPostParam('origIndex');

$typecastLoadIdFx = fn ($v) => $this->getApp()->uiPersistence->typecastLoadField($idField, $v);
$typecastLoadIdFx = fn ($v) => $this->getApp()->uiPersistence->typecastAttributeLoadField($idField, $v);
$orderedIds = array_map($typecastLoadIdFx, $orderedIds);
$sourceId = $typecastLoadIdFx($sourceId);

Expand Down
2 changes: 1 addition & 1 deletion src/Lister.php
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ public function renderRow(): void
if ($this->tRow->hasTag('_title')) {
$this->tRow->set('_title', $this->currentRow->getTitle());
}
$idStr = $this->getApp()->uiPersistence->typecastSaveField($this->currentRow->getField($this->currentRow->idField), $this->currentRow->getId());
$idStr = $this->getApp()->uiPersistence->typecastAttributeSaveField($this->currentRow->getField($this->currentRow->idField), $this->currentRow->getId());
if ($this->tRow->hasTag('_href')) {
$this->tRow->set('_href', $this->url(['id' => $idStr]));
}
Expand Down
33 changes: 33 additions & 0 deletions src/Persistence/Ui.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Atk4\Data\Model;
use Atk4\Data\Persistence;
use Atk4\Data\Persistence\Sql\Expression;
use Atk4\Ui\Demos\WrappedId;
use Atk4\Ui\Exception;

/**
Expand Down Expand Up @@ -280,4 +281,36 @@ public function typecastSaveRow(Model $model, array $row): array

return $result;
}

/**
* @param mixed $value
*
* @return scalar|null
*/
public function typecastAttributeSaveField(Field $field, $value)
{
if ($field->type === 'atk4_ui_demos_id' && $value !== null) {
return (string) ($value->getId() + 218_000_000);
}

return $this->typecastSaveField($field, $value);
}

/**
* @param scalar|null $value
*
* @return mixed
*/
public function typecastAttributeLoadField(Field $field, $value)
{
if ($field->type === 'atk4_ui_demos_id') {
$value = $this->typecastLoadField(new Field(['type' => 'integer']), $value);

return $value === null
? null
: new WrappedId($value - 218_000_000);
}

return $this->typecastLoadField($field, $value);
}
}
2 changes: 1 addition & 1 deletion src/Table.php
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ public function renderRow(): void

// render row and add to body
$this->tRow->dangerouslySetHtml($htmlTags);
$this->tRow->set('dataId', $this->getApp()->uiPersistence->typecastSaveField($this->model->getField($this->model->idField), $this->currentRow->getId()));
$this->tRow->set('dataId', $this->getApp()->uiPersistence->typecastAttributeSaveField($this->model->getField($this->model->idField), $this->currentRow->getId()));
$this->template->dangerouslyAppendHtml('Body', $this->tRow->renderToHtml());
$this->tRow->del(array_keys($htmlTags));
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/Table/Column/ActionButtons.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ public function addModal($button, $defaults, \Closure $callback, $owner = null,
$modal = Modal::addTo($owner, $defaults);

$modal->set(function (View $t) use ($callback) {
$id = $this->getApp()->uiPersistence->typecastLoadField($this->table->model->getField($this->table->model->idField), $t->stickyGet($this->name));
$id = $this->getApp()->uiPersistence->typecastAttributeLoadField($this->table->model->getField($this->table->model->idField), $t->stickyGet($this->name));
$callback($t, $id);
});

Expand Down
2 changes: 1 addition & 1 deletion src/Table/Column/Link.php
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ public function getHtmlTags(Model $row, ?Field $field): array
$key = $val;
}

$page[$key] = $this->getApp()->uiPersistence->typecastSaveField($row->getField($val), $row->get($val));
$page[$key] = $this->getApp()->uiPersistence->typecastAttributeSaveField($row->getField($val), $row->get($val));
}

return ['c_' . $this->shortName => $this->table->url($page)];
Expand Down
2 changes: 1 addition & 1 deletion src/UserAction/CommonExecutorTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ protected function executeModelActionLoad(Model\UserAction $action): Model\UserA
{
$model = $action->getModel();

$id = $this->getApp()->uiPersistence->typecastLoadField(
$id = $this->getApp()->uiPersistence->typecastAttributeLoadField(
$model->getField($model->idField),
$this->stickyGet($this->name)
);
Expand Down
2 changes: 1 addition & 1 deletion src/UserAction/JsCallbackExecutor.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public function executeModelAction(): void
{
$this->invokeFxWithUrlArgs(function () { // backup/restore $this->args mutated in https://github.com/atk4/ui/blob/8926412a31/src/JsCallback.php#L71
$this->set(function (Jquery $j, ...$values) {
$id = $this->getApp()->uiPersistence->typecastLoadField(
$id = $this->getApp()->uiPersistence->typecastAttributeLoadField(
$this->action->getModel()->getField($this->action->getModel()->idField),
$this->getApp()->tryGetRequestPostParam($this->name)
);
Expand Down
Loading

0 comments on commit 1a35de8

Please sign in to comment.