Skip to content

Commit

Permalink
Fix entity usage (#78)
Browse files Browse the repository at this point in the history
  • Loading branch information
mvorisek authored Oct 19, 2021
1 parent 149b209 commit 3eecdc3
Show file tree
Hide file tree
Showing 10 changed files with 79 additions and 81 deletions.
29 changes: 12 additions & 17 deletions .github/workflows/test-unit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ jobs:
php -r '(new PDO("mysql:host=mysql", "root", "atk4_pass_root"))->exec("ALTER USER '"'"'atk4_test_user'"'"'@'"'"'%'"'"' WITH MAX_USER_CONNECTIONS 5");'
php -r '(new PDO("mysql:host=mariadb", "root", "atk4_pass_root"))->exec("ALTER USER '"'"'atk4_test_user'"'"'@'"'"'%'"'"' WITH MAX_USER_CONNECTIONS 5");'
php -r '(new PDO("pgsql:host=postgres;dbname=atk4_test", "atk4_test_user", "atk4_pass"))->exec("ALTER ROLE atk4_test_user CONNECTION LIMIT 1");'
if [ -n "$LOG_COVERAGE" ]; then mkdir coverage && cp tools/CoverageUtil.php demos; fi
# if [ -n "$LOG_COVERAGE" ]; then mkdir coverage && cp tools/CoverageUtil.php demos; fi
sed -E "s/\(('sqlite:.+)\);/(\$_ENV['DB_DSN'] ?? \\1, \$_ENV['DB_USER'] ?? null, \$_ENV['DB_PASSWORD'] ?? null);/g" -i demos/db.default.php
- name: "Run tests: SQLite"
Expand Down Expand Up @@ -216,7 +216,7 @@ jobs:
name: Behat
runs-on: ubuntu-latest
container:
image: ghcr.io/mvorisek/image-php:${{ matrix.php }}-node
image: ghcr.io/mvorisek/image-php:${{ matrix.php }}-selenium
strategy:
fail-fast: false
matrix:
Expand Down Expand Up @@ -252,12 +252,6 @@ jobs:
image: ghcr.io/mvorisek/docker-oracle-xe-11g
env:
ORACLE_ALLOW_REMOTE: true
selenium-chrome:
image: selenium/standalone-chrome:latest
options: --health-cmd "/opt/bin/check-grid.sh"
selenium-firefox:
image: selenium/standalone-firefox:latest
options: --health-cmd "/opt/bin/check-grid.sh"
steps:
- name: Checkout
uses: actions/checkout@v2
Expand Down Expand Up @@ -310,19 +304,20 @@ jobs:
php -r '(new PDO("mysql:host=mysql", "root", "atk4_pass_root"))->exec("ALTER USER '"'"'atk4_test_user'"'"'@'"'"'%'"'"' WITH MAX_USER_CONNECTIONS 5");'
php -r '(new PDO("mysql:host=mariadb", "root", "atk4_pass_root"))->exec("ALTER USER '"'"'atk4_test_user'"'"'@'"'"'%'"'"' WITH MAX_USER_CONNECTIONS 5");'
php -r '(new PDO("pgsql:host=postgres;dbname=atk4_test", "atk4_test_user", "atk4_pass"))->exec("ALTER ROLE atk4_test_user CONNECTION LIMIT 1");'
if [ -n "$LOG_COVERAGE" ]; then mkdir coverage && cp tools/CoverageUtil.php demos; fi
# if [ -n "$LOG_COVERAGE" ]; then mkdir coverage && cp tools/CoverageUtil.php demos; fi
sed -E "s/\(('sqlite:.+)\);/(\$_ENV['DB_DSN'] ?? \\1, \$_ENV['DB_USER'] ?? null, \$_ENV['DB_PASSWORD'] ?? null);/g" -i demos/db.default.php
sed -i "s~'https://raw.githack.com/atk4/ui/develop/public.*~'/public',~" vendor/atk4/ui/src/App.php
php -S 172.18.0.2:8888 > /dev/null 2>&1 &
sleep 0.2
sed -i "s~'https://raw.githack.com/atk4/ui/develop/public.*~'/vendor/atk4/ui/public',~" vendor/atk4/ui/src/App.php
ci_wait_until () { timeout 30 sh -c "until { $1 2> /dev/null; }; do sleep 0.02; done" || timeout 15 sh -c "$1" || { echo "health timeout: $1"; exit 1; }; }
php -S 127.0.0.1:8888 > /dev/null 2>&1 &
ci_wait_until 'nc -w 1 127.0.0.1 8888'
if [ -f /etc/alpine-release ]; then addgroup browser && adduser browser -G browser -D -s /bin/sh; else adduser browser --gecos "" --disabled-login -shell /bin/sh > /dev/null; fi
{ Xvfb -ac :99 -screen 0 1920x1200x24 2> /dev/null & } && export DISPLAY=:99
ci_wait_until '[ -e /tmp/.X11-unix/X99 ]'
su browser -c 'java -Dwebdriver.chrome.whitelistedIps=127.0.0.1 -jar /opt/selenium-server-standalone.jar -role standalone -host 127.0.0.1 -port 4444 -sessionTimeout 15 -browserTimeout 12 > /dev/null 2>&1 &'
ci_wait_until 'nc -w 1 127.0.0.1 4444'
if [ "${{ matrix.type }}" == "Firefox" ]; then sed -i "s~chrome~firefox~" behat.yml.dist; fi
if [ "${{ matrix.type }}" == "Chrome Slow" ]; then echo 'sleep(1);' >> demos/init-app.php; fi
# remove once https://github.com/minkphp/Mink/pull/801
# and https://github.com/minkphp/MinkSelenium2Driver/pull/322 are released
sed -i 's/usleep(100000)/usleep(5000)/' vendor/behat/mink/src/Element/Element.php
sed -i 's/usleep(100000)/usleep(5000)/' vendor/behat/mink-selenium2-driver/src/Selenium2Driver.php
- name: "Run tests: SQLite"
run: |
php demos/_demo-data/create-db.php
Expand Down
17 changes: 8 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ $app->auth = new \Atk4\Login\Auth();
$app->auth->setModel(new \Atk4\Login\Model\User($app->db));

// The rest of YOUR UI code will now be protected
$app->add([\Atk4\Ui\Crud:class])->setModel(new Client($app->db));
\Atk4\Ui\Crud::addTo($app)->setModel(new Client($app->db));
```

(If you do not have User model yet, you can extend or use \Atk4\Login\Model\User).
Expand Down Expand Up @@ -81,14 +81,14 @@ $app->auth->setModel(new User($app->db));

// Now manually use login logic
if (!$app->auth->user->loaded()) {
$app->add([new \Atk4\Login\LoginForm(), 'auth'=>$app->auth]);
\Atk4\Login\LoginForm::addTo($app, ['auth' => $app->auth]);
}
```

#### Adding sign-up form

``` php
$app->add([\Atk4\Login\RegisterForm::class])
\Atk4\Login\RegisterForm::addTo($app)
->setModel(new \Atk4\Login\Model\User($app->db));
```

Expand All @@ -104,8 +104,7 @@ Displays email and 2 password fields (for confirmation). If filled successfully
![Login](./docs/login-form.png)

``` php
$app->add([
\Atk4\Login\LoginForm::class,
\Atk4\Login\LoginForm::addTo($app, [
'auth'=>$app->auth,
//'successLink'=>['dashboard'],
//'forgotLink'=>['forgot'],
Expand Down Expand Up @@ -143,14 +142,14 @@ You may also access user data like this: `$app->auth->model['name']`; Things to
This form would allow user to change user data (including password) but only if user is authenticated. To implement profile form use:

``` php
$app->add([Form::class])->setModel($app->auth->user);
Form::addTo($app)->setModel($app->auth->user);
```

Demos open profile form in a pop-up window, if you wish to do it, you can use this code:

``` php
$app->add([Button::class, 'Profile', 'primary'])->on('click', $app->add([Modal::class])->set(function($p) {
$p->add([Form::class])->setModel($p->app->auth->user);
Button::addTo($app, ['Profile', 'primary'])->on('click', Modal::addTo($app)->set(function($p) {
Form::addTo($p)->setModel($p->app->auth->user);
})->show());
```

Expand Down Expand Up @@ -185,7 +184,7 @@ Although a basic User model is supplied, you can either extend it or use your ow
We include a slightly extended "Admin" interface which includes page to see user details and change their password. To create admin page use:

``` php
$app->add(new \Atk4\Login\UserAdmin())
\Atk4\Login\UserAdmin::addTo($app)
->setModel(new \Atk4\Login\Model\User($app->db));
```

Expand Down
9 changes: 6 additions & 3 deletions behat.yml.dist
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
default:
suites:
atk4_login:
main:
paths:
features: '%paths.base%/tests-behat'
contexts:
- Behat\MinkExtension\Context\MinkContext
- Atk4\Ui\Behat\Context
extensions:
Behat\MinkExtension:
base_url: 'http://172.18.0.2:8888/demos'
base_url: 'http://127.0.0.1:8888/demos'
sessions:
default:
selenium2:
browser: chrome
wd_host: 'http://selenium-chrome:4444/wd/hub'
wd_host: 'http://127.0.0.1:4444/wd/hub'
capabilities:
extra_capabilities:
chrome:
args:
- '--no-sandbox'
- '--headless'
- '--disable-dev-shm-usage'
- '--disable-gpu'
- '--window-size=1920,1200'
10 changes: 5 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,19 @@
"atk4/ui": "~3.0.0"
},
"require-dev": {
"behat/behat": "^3.8.2 || dev-master#6f38d11",
"behat/gherkin": "^4.8.1 || dev-master#5fbf806",
"behat/mink": "^1.8.2 || dev-master#1ab79d6",
"behat/behat": "^3.9",
"behat/mink": "^1.9",
"behat/mink-extension": "^2.3.1",
"behat/mink-selenium2-driver": "^1.4",
"behat/mink-selenium2-driver": "^1.5",
"ergebnis/composer-normalize": "^2.13",
"friendsofphp/php-cs-fixer": "^3.0",
"instaclick/php-webdriver": "^1.4.7",
"johnkary/phpunit-speedtrap": "^3.3",
"phpstan/phpstan": "^0.12.82",
"phpunit/phpcov": "*",
"phpunit/phpunit": "^9.5.5",
"symfony/contracts": ">=1.1"
"symfony/console": "^4.4.30 || ^5.3.7",
"symfony/css-selector": "^4.4.24 || ^5.2.9"
},
"config": {
"sort-packages": true
Expand Down
32 changes: 20 additions & 12 deletions demos/_demo-data/create-db.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@
/** @var \Atk4\Data\Persistence\Sql $db */
require_once __DIR__ . '/../init-db.php';

$model = new Model($db, ['table' => 'login_role']);
$model->addField('name', ['type' => 'string']);
(new Migration($model))->create();
$model->import([
1 => ['id' => 1, 'name' => 'User Role'],
2 => ['id' => 2, 'name' => 'Admin Role'],
]);

$model = new Model($db, ['table' => 'login_user']);
$model->addField('name', ['type' => 'string']);
$model->addField('email', ['type' => 'string']);
Expand All @@ -29,15 +37,7 @@
2 => ['id' => 2, 'name' => 'Administrator', 'email' => 'admin', 'password' => '$2y$10$p34ciRcg9GZyxukkLIaEnenGBao79fTFa4tFSrl7FvqrxnmEGlD4O', 'role_id' => 2], // admin/admin
]);

$model = new Model($db, ['table' => 'login_role']);
$model->addField('name', ['type' => 'string']);
(new Migration($model))->create();
$model->import([
1 => ['id' => 1, 'name' => 'User Role'],
2 => ['id' => 2, 'name' => 'Admin Role'],
]);

$model = new Model($db, ['table' => 'login_access_role']);
$model = new Model($db, ['table' => 'login_access_rule']);
$model->addField('role_id', ['type' => 'integer']);
$model->addField('model', ['type' => 'string']);
$model->addField('all_visible', ['type' => 'boolean']);
Expand All @@ -50,9 +50,17 @@

(new Migration($model))->create();
$model->import([
1 => ['id' => 1, 'role_id' => 1, 'model' => '\\Atk4\Login\\Model\\User', 'all_visible' => 1, 'visible_fields' => null, 'all_editable' => 0, 'editable_fields' => null, 'all_actions' => 1, 'actions' => null, 'conditions' => null],
2 => ['id' => 2, 'role_id' => 2, 'model' => '\\Atk4\Login\\Model\\User', 'all_visible' => 1, 'visible_fields' => null, 'all_editable' => 1, 'editable_fields' => null, 'all_actions' => 1, 'actions' => null, 'conditions' => null],
3 => ['id' => 3, 'role_id' => 2, 'model' => '\\Atk4\Login\\Model\\Role', 'all_visible' => 1, 'visible_fields' => null, 'all_editable' => 1, 'editable_fields' => null, 'all_actions' => 1, 'actions' => null, 'conditions' => null],
1 => ['id' => 1, 'role_id' => 1, 'model' => \Atk4\Login\Model\User::class, 'all_visible' => 1, 'visible_fields' => null, 'all_editable' => 0, 'editable_fields' => null, 'all_actions' => 1, 'actions' => null, 'conditions' => null],
2 => ['id' => 2, 'role_id' => 2, 'model' => \Atk4\Login\Model\User::class, 'all_visible' => 1, 'visible_fields' => null, 'all_editable' => 1, 'editable_fields' => null, 'all_actions' => 1, 'actions' => null, 'conditions' => null],
3 => ['id' => 3, 'role_id' => 2, 'model' => \Atk4\Login\Model\Role::class, 'all_visible' => 1, 'visible_fields' => null, 'all_editable' => 1, 'editable_fields' => null, 'all_actions' => 1, 'actions' => null, 'conditions' => null],
]);

$model = new Model($db, ['table' => 'demo_client']);
$model->addField('name', ['required' => true]);
$model->addField('vat_number');
$model->addField('balance', ['type' => 'money']);
$model->addField('active', ['type' => 'boolean', 'default' => true]);

(new Migration($model))->create();

echo 'import complete!' . "\n\n";
12 changes: 3 additions & 9 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,6 @@ parameters:
- '~^Unsafe usage of new static\(\)\.$~'

# TODO these rules are generated, this ignores should be fixed in the code
# level 0
-
message: "#^Instantiated class Atk4\\\\Data\\\\Model\\\\AccessRule not found\\.$#"
count: 1
path: src/RoleAdmin.php

# level 1
-
message: "#^Call to an undefined method Atk4\\\\Login\\\\Model\\\\AccessRule\\:\\:setUnique\\(\\)\\.$#"
Expand Down Expand Up @@ -83,11 +77,11 @@ parameters:
count: 1
path: src/RoleAdmin.php
-
message: "#^Call to method addCondition\\(\\) on an unknown class Atk4\\\\Data\\\\Model\\\\AccessRule\\.$#"
message: "#^Call to an undefined method Atk4\\\\Ui\\\\Table\\\\Column\\:\\:addModal\\(\\)\\.$#"
count: 1
path: src/RoleAdmin.php
path: src/UserAdmin.php
-
message: "#^Call to an undefined method Atk4\\\\Ui\\\\Table\\\\Column\\:\\:addModal\\(\\)\\.$#"
message: "#^Call to an undefined method Atk4\\\\Ui\\\\Form\\\\Control\\:\\:addAction\\(\\)\\.$#"
count: 1
path: src/UserAdmin.php
-
Expand Down
2 changes: 1 addition & 1 deletion src/Form/Control/Generic.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public function getModel()

$model = new $class($this->form->model->persistence);
if (!$model instanceof Model) {
throw new Exception('Class should be instance of Atk4\\Data\\Model');
throw new Exception('Class should be instance of ' . Model::class);
}

return $model;
Expand Down
7 changes: 4 additions & 3 deletions src/RoleAdmin.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Atk4\Core\DebugTrait;
use Atk4\Data\Model;
use Atk4\Login\Model\AccessRule;
use Atk4\Ui\Crud;
use Atk4\Ui\Header;
use Atk4\Ui\Table\Column\ActionButtons;
Expand All @@ -30,12 +31,12 @@ public function setModel(Model $role, $fields = null): Model
$column = $this->table->addColumn(null, [ActionButtons::class, 'caption' => '']);

$column->addModal(['icon' => 'cogs'], 'Role Permissions', function (View $v, $id) use ($role) {
$role->load($id);
$v->add([Header::class, $role->getTitle() . ' Permissions']);
$role = $role->load($id);
Header::addTo($v, [$role->getTitle() . ' Permissions']);

$crud = Crud::addTo($v);
//$crud->setModel($role->ref('AccessRules')); // this way it adds wrong table alias in field condition - ATK bug (withTitle + table_alias)
$crud->setModel((new Model\AccessRule($role->persistence))->addCondition('role_id', $id));
$crud->setModel((new AccessRule($role->persistence))->addCondition('role_id', $id));

$crud->onFormAddEdit(function ($f) {
// @todo - these lines below don't work. One reason is that there is no rule isNotChecked :) but still not sure it works
Expand Down
36 changes: 17 additions & 19 deletions src/UserAdmin.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,51 +51,49 @@ public function setModel(Model $user)

// Pop-up for resetting password. Will display button for generating random password
$column->addModal(['icon' => 'key'], 'Change Password', function ($v, $id) {
$this->model->load($id);
$userEntity = $this->model->load($id);

$form = $v->add([Form::class]);
$form = Form::addTo($v);
$f = $form->addControl('visible_password', null, ['required' => true]);
//$form->addControl('email_user', null, ['type'=>'boolean', 'caption'=>'Email user their new password']);

$f->addAction(['icon' => 'random'])->on('click', function () use ($f) {
return $f->jsInput()->val($this->model->getField('password')->suggestPassword());
$f->addAction(['icon' => 'random'])->on('click', function () use ($f, $userEntity) {
return $f->jsInput()->val($userEntity->getField('password')->suggestPassword());
});

$form->onSubmit(function ($form) use ($v) {
$this->model->set('password', $form->model->get('visible_password'));
$this->model->save();
$form->onSubmit(function ($form) use ($v, $userEntity) {
$userEntity->set('password', $form->model->get('visible_password'));
$userEntity->save();

return [
$v->getOwner()->hide(),
new JsToast([
'message' => 'Password for ' . $this->model->get($this->model->title_field) . ' is changed!',
'message' => 'Password for ' . $userEntity->get($userEntity->title_field) . ' is changed!',
'class' => 'success',
]),
];

//return 'Setting '.$form->model['visible_password'].' for '.$this->model['name'];
});
});

/*
$column->addModal(['icon'=>'eye'], 'Details', function($v, $id) {
$this->model->load($id);
$column->addModal(['icon' => 'eye'], 'Details', function($v, $id, $userEntity) {
$userEntity = $this->model->load($id);
$c = $v->add(Columns::class);
$c = Columns::addTo($v);
$left = $c->addColumn();
$right = $c->addColumn();
$left->add([Header::class, 'Role "'.$this->model['role'].'" Access']);
$crud = $left->add([CRUD::class]);
$crud->setModel($this->model->ref('AccessRules'));
Header::addTo($left, ['Role "' . $userEntity['role'] . '" Access']);
$crud = Crud::addTo($left);
$crud->setModel($userEntity->ref('AccessRules'));
$crud->table->onRowClick($right->jsReload(['rule'=>$crud->table->jsRow()->data('id')]));
$right->add([Header::class, 'Role Details']);
Header::addTo($right, ['Role Details']);
$rule = $right->stickyGet('rule');
if (!$rule) {
$right->add([Message::class, 'Select role on the left', 'yellow']);
Message::addTo($right, ['Select role on the left', 'yellow']);
} else {
$right->add([CRUD::class])->setModel($this->model->ref('AccessRules')->load($rule));
Crud::addTo($right)->setModel($userEntity->ref('AccessRules')->load($rule));
}
})->setAttr('title', 'User Details');
*/
Expand Down
6 changes: 3 additions & 3 deletions tests/Generic.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ protected function setupDefaultDb()
2 => ['id' => 2, 'name' => 'Admin Role'],
],
'login_access_rule' => [
1 => ['id' => 1, 'role_id' => 1, 'model' => '\\Atk4\Login\\Model\\User', 'all_visible' => 1, 'visible_fields' => null, 'all_editable' => 0, 'editable_fields' => null, 'all_actions' => 1, 'actions' => null, 'conditions' => null],
2 => ['id' => 2, 'role_id' => 2, 'model' => '\\Atk4\Login\\Model\\User', 'all_visible' => 1, 'visible_fields' => null, 'all_editable' => 1, 'editable_fields' => null, 'all_actions' => 1, 'actions' => null, 'conditions' => null],
3 => ['id' => 3, 'role_id' => 2, 'model' => '\\Atk4\Login\\Model\\Role', 'all_visible' => 1, 'visible_fields' => null, 'all_editable' => 1, 'editable_fields' => null, 'all_actions' => 1, 'actions' => null, 'conditions' => null],
1 => ['id' => 1, 'role_id' => 1, 'model' => \Atk4\Login\Model\User::class, 'all_visible' => 1, 'visible_fields' => null, 'all_editable' => 0, 'editable_fields' => null, 'all_actions' => 1, 'actions' => null, 'conditions' => null],
2 => ['id' => 2, 'role_id' => 2, 'model' => \Atk4\Login\Model\User::class, 'all_visible' => 1, 'visible_fields' => null, 'all_editable' => 1, 'editable_fields' => null, 'all_actions' => 1, 'actions' => null, 'conditions' => null],
3 => ['id' => 3, 'role_id' => 2, 'model' => \Atk4\Login\Model\Role::class, 'all_visible' => 1, 'visible_fields' => null, 'all_editable' => 1, 'editable_fields' => null, 'all_actions' => 1, 'actions' => null, 'conditions' => null],
],
]);
}
Expand Down

0 comments on commit 3eecdc3

Please sign in to comment.