Skip to content

Commit

Permalink
Releasing 2.0.3 into master (#548)
Browse files Browse the repository at this point in the history
* wip

* wip

* fixes

* Feature/test1 (#483)

* fixes

* testtisg

* wip

* test

* backmerge master

* normalize everything

* added locale test (#485)

* added locale test

* Apply fixes from StyleCI

* wip

* wip

* Apply fixes from StyleCI

* Update CHANGELOG.md

* Implement #386 (#477)

* Implement #386

* Apply fixes from StyleCI

* Update Field.php

* Update Model.php

* Update Helper.php

* Apply fixes from StyleCI

* move functionality to atk4/core

* Apply fixes from StyleCI

* fix traits

* Apply fixes from StyleCI

* fix typo

* Feature/pgsql test (#486)

* fix one test

* Setting current dependencies

* wip

* wip

* Add matrix testing (#492)

* Test using matrix

* wip

* wip

* wip

* clean up bundler

* clean up bundler (#493)

* wip

* Fix/delete callback (#488)

* fix one test

* Setting current dependencies

* fix/delete callback

* Update composer.json

* Fix/persistence sql condition (#487)

* fix one test

* Setting current dependencies

* fix wrong assignment of value as condition

* Update composer.json

* Update SQL.php

* Feature remove specified action (#489)

* fix one test

* Setting current dependencies

* add method to remove specified action(s) from model

* Update Model.php

* spaces

* Feature/add confirmation callback argument (#491)

* fix one test

* Setting current dependencies

* pass the action object as argument to confirmation callback

* badge

* Feature/set custom edit exec button (#490)

* fix one test

* Setting current dependencies

* use custom exec button on edit action

* Update Model.php

* remove class, use seed

Co-authored-by: Imants Horsts <DarkSide666@users.noreply.github.com>

* model default add field property (#454)

* use the object default add field property

* no need for double brackets.

* force tests

Co-authored-by: Romans Malinovskis <me@nearly.guru>
Co-authored-by: Imants Horsts <DarkSide666@users.noreply.github.com>

* Fix empty array condition (#498)

* more tests

* Apply fixes from StyleCI

* better implementation for addFields() and test cases (#499)

* better implementation for addFields() and test cases

* Apply fixes from StyleCI

* use shorthand method

* simplify code

* implement `exprNow()` method. Rely on dsql PR.

* Apply fixes from StyleCI

* pass

* add docs

Co-authored-by: Romans Malinovskis <me@nearly.guru>

* Fix/ Small Action related fix (#502)

* Fix/ Small Action related fix

- Set Edit action exec button labe lto 'Save' by default
 - Set Edit action exec button colot to blue by default
- Set default description for Add action in model
- Add method to retreive model from Action

* Apply fixes from StyleCI

* fix comment

Co-authored-by: Imants Horsts <DarkSide666@users.noreply.github.com>

* update multiple delete example (#503)

* now supports multiple filter options in getFields()

* Apply fixes from StyleCI

* Accept any DateTimeInterface impl. for datetime (#505)

* Accept any DateTimeInterface impl. for datetime

* Fix DateTime::getTimezone method name

* Fix setTimezone for any instance of DateTimeInterface

* Add microseconds persistence support for datetime/time types + fix normalization/cloning issue (#504)

* Fix datetime normalization cloning

* Add microseconds persistence support for datetime/time types

Co-authored-by: Imants Horsts <DarkSide666@users.noreply.github.com>

* include comment about hooks and example how to execute them (#510)

* update composer

* Update release-drafter.yml

* Update bundler.yml

* Fix hasOne relation seed processing. It should replace not merge. (#512)

* New method $model->getTitles() (#513)

* Implement `getTitles()` method

* Apply fixes from StyleCI

* Update unit-tests.yml

* migration to migrator

* rename addHook to onHook (#514)

* fix #944 (#516)

* allow dots in table names, fix #515, fix #517

* Apply fixes from StyleCI

* Do not fail-fast PHP test matrix (#522)

* Simplify code (#519)

* Update release-drafter.yml

* Update release-drafter.yml

* Fix hook trait usage (#525)

* Hook args must be an array

* Fix hook onHook() usage

* Implement addWith() (#527)

* Implement addWith()

* Apply fixes from StyleCI

* implement `addWith`

* add docs

* add note

* Update unit-tests.yml

* Update unit-tests.yml

* Update unit-tests.yml

* Update unit-tests.yml

* Update unit-tests.yml

* Update unit-tests.yml

* Update unit-tests.yml

* Update unit-tests.yml

* Update unit-tests.yml

* Update unit-tests.yml

* Update unit-tests.yml

* Action should also support `fields===true` value (#531)

* Fix LIKE conditions for Array and SQL persistences (#532)

* Fix LIKE conditions - fix fix (#535)

* fix #533 (#537)

* Fix value trim (#538)

* introduce sql null condition test (#540)

* introduce test on condition with null value

* include mesage in SQL exception details

* Fix typo

* Convert scalar class names to ::class (#544)

* Fix CS - do not import classes without namespace

* Use null coalescing operator instead of isset (#545)

* Use null coalescing operator instead of isset

* Fix tests

* Fix refactorability for "owner" (#543)

* Fix refactorability for "owner"

* Typehint for elements

* Narrow phpdoc for SQL subtypes

* Fix typos

* Setting release dependencies

Co-authored-by: Romans Malinovskis <romans@agiletoolkit.org>
Co-authored-by: Romans Malinovskis <me@nearly.guru>
Co-authored-by: Imants Horsts <DarkSide666@users.noreply.github.com>
Co-authored-by: Georgi Hristov <georgehristov@users.noreply.github.com>
Co-authored-by: Mimo <ddobchev@gmail.com>
Co-authored-by: Alain Belair <belair.alain@gmail.com>
Co-authored-by: DarkSide <imants.horsts@inbox.lv>
Co-authored-by: Michael Voříšek <mvorisek@mvorisek.cz>
Co-authored-by: GitHub Action <noreply@github.com>
  • Loading branch information
10 people committed Apr 8, 2020
1 parent f916c24 commit 79dd35d
Show file tree
Hide file tree
Showing 49 changed files with 739 additions and 436 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/release-drafter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ jobs:
runs-on: ubuntu-latest
steps:
# Drafts your next Release notes as Pull Requests are merged into "master"
- uses: toolmantim/release-drafter@master
- uses: toolmantim/release-drafter@v5.6.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
9 changes: 5 additions & 4 deletions .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,15 @@ jobs:
container:
image: atk4/image:${{ matrix.php }} # https://github.com/atk4/image
strategy:
fail-fast: false
matrix:
php: ['7.2', '7.3', 'latest']
services:
mysql:
image: mysql:5.7
image: mariadb:10.5.1
env:
MYSQL_ROOT_PASSWORD: password
DB_DATABASE: db
MYSQL_DATABASE: db
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=5
postgres:
image: postgres:10-alpine
Expand All @@ -31,7 +32,7 @@ jobs:
POSTGRES_USER: postgres
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- run: php --version
- name: Get Composer Cache Directory
id: composer-cache
Expand All @@ -49,7 +50,7 @@ jobs:
- name: Run Tests
run: |
mkdir -p build/logs
mysql -uroot -ppassword -h mysql -e 'CREATE DATABASE db;'
# mysql -uroot -ppassword -h mysql -e 'CREATE DATABASE db;'
- name: SQLite Testing
run: vendor/bin/phpunit --configuration phpunit.xml --coverage-text --exclude-group dns

Expand Down
2 changes: 2 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
"homepage": "https://nearly.guru/"
}
],
"minimum-stability": "dev",
"prefer-stable": true,
"require": {
"php": ">=7.2.0",
"ext-intl": "*",
Expand Down
43 changes: 35 additions & 8 deletions docs/advanced.rst
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ Another scenario which could benefit by type substitution would be::
ATK Data allow class substitution during load and iteration by breaking "afterLoad"
hook. Place the following inside Transaction::init()::

$this->addHook('afterLoad', function ($m) {
$this->onHook('afterLoad', function ($m) {
if (get_class($this) != $m->getClassName()) {
$cl = '\\'.$this->getClassName();
$cl = new $cl($this->persistence);
Expand All @@ -98,7 +98,7 @@ of the record. Finally to help with performance, you can implement a switch::
..

if ($this->typeSubstitution) {
$this->addHook('afterLoad',
$this->onHook('afterLoad',
..........
)
}
Expand Down Expand Up @@ -166,7 +166,7 @@ which I want to define like this::

$this->owner->addField('updated_dts', ['type'=>'datetime']);

$this->owner->addHook('beforeUpdate', function($m, $data) {
$this->owner->onHook('beforeUpdate', function($m, $data) {
if(isset($this->app->user) and $this->app->user->loaded()) {
$data['updated_by'] = $this->app->user->id;
}
Expand Down Expand Up @@ -343,7 +343,7 @@ before and just slightly modifying it::
$this->owner->addMethod('restore', $this);
} else {
$this->owner->addCondition('is_deleted', false);
$this->owner->addHook('beforeDelete', [$this, 'softDelete'], null, 100);
$this->owner->onHook('beforeDelete', [$this, 'softDelete'], null, 100);
}
}

Expand Down Expand Up @@ -425,7 +425,7 @@ inside your model are unique::
$this->fields = [$this->owner->title_field];
}

$this->owner->addHook('beforeSave', $this);
$this->owner->onHook('beforeSave', $this);
}

function beforeSave($m)
Expand All @@ -448,6 +448,33 @@ As expected - when you add a new model the new values are checked against
existing records. You can also slightly modify the logic to make addCondition
additive if you are verifying for the combination of matched fields.

Using WITH cursors
==================

Many SQL database engines support defining WITH cursors to use in select, update
and even delete statements.

.. php:method:: addWith(Model $model, string $alias, array $fields, bool $recursive = false)
Agile toolkit data models also support these cursors. Usage is like this::

$invoices = new Invoice();

$contacts = new Contact();
$contacts->addWith($invoices, 'inv', ['contact_id'=>'cid', 'ref_no', 'total_net'=>'invoiced'], false);
$contacts->join('inv.cid');

.. code-block:: sql
with
`inv` (`cid`, `ref_no`, `total_net`) as (select `contact_id`, `ref_no`, `total_net` from `invoice`)
select
*
from `contact`
join `inv` on `inv`.`cid`=`contact`.`id`
.. note:: Supported starting from MySQL 8.x. MariaDB supported it earlier.

Creating Many to Many relationship
==================================

Expand Down Expand Up @@ -488,7 +515,7 @@ Next we need to define reference. Inside Model_Invoice add::
$j->hasOne('invoice_id', 'Model_Invoice');
}, 'their_field'=>'invoice_id']);

$this->addHook('beforeDelete',function($m){
$this->onHook('beforeDelete',function($m){
$m->ref('InvoicePayment')->action('delete')->execute();

// If you have important per-row hooks in InvoicePayment
Expand Down Expand Up @@ -623,7 +650,7 @@ Here is how to add them. First you need to create fields::
I have declared those fields with never_persist so they will never be used by
persistence layer to load or save anything. Next I need a beforeSave handler::

$this->addHook('beforeSave', function($m) {
$this->onHook('beforeSave', function($m) {
if(isset($m['client_code']) && !isset($m['client_id'])) {
$cl = $this->refModel('client_id');
$cl->addCondition('code',$m['client_code']);
Expand Down Expand Up @@ -712,7 +739,7 @@ section. Add this into your Invoice Model::
Next both payment and lines need to be added after invoice is actually created,
so::

$this->addHook('afterSave', function($m, $is_update){
$this->onHook('afterSave', function($m, $is_update){
if(isset($m['payment'])) {
$m->ref('Payment')->insert($m['payment']);
}
Expand Down
2 changes: 1 addition & 1 deletion docs/design.rst
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ Hooks can help you perform operations when object is being persisted::
// addField() declaration
// addExpression('is_password_expired')

$this->addHook('beforeSave', function($m) {
$this->onHook('beforeSave', function($m) {
if ($m->isDirty('password')) {
$m['password'] = encrypt_password($m['password']);
$m['password_change_date'] = $m->expr('now()');
Expand Down
14 changes: 7 additions & 7 deletions docs/hooks.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ Example with beforeSave
The next code snippet demonstrates a basic usage of a `beforeSave` hook.
This one will update field values just before record is saved::

$m->addHook('beforeSave', function($m) {
$m->onHook('beforeSave', function($m) {
$m['name'] = strtoupper($m['name']);
$m['surname'] = strtoupper($m['surname']);
});
Expand Down Expand Up @@ -85,7 +85,7 @@ model will assume the operation was successful.

You can also break beforeLoad hook which can be used to skip rows::

$model->addHook('afterLoad', function ($m) {
$model->onHook('afterLoad', function ($m) {
if ($m['date'] < $m->date_from) {
$m->breakHook(false); // will not yield such data row
}
Expand Down Expand Up @@ -136,7 +136,7 @@ of save.

You may actually drop validation exception inside save, insert or update hooks::

$m->addHook('beforeSave', function($m) {
$m->onHook('beforeSave', function($m) {
if ($m['name'] = 'Yagi') {
throw new \atk4\data\ValidationException(['name'=>"We don't serve like you"]);
}
Expand Down Expand Up @@ -193,7 +193,7 @@ and your update() may not actually update anything. This does not normally
generate an error, however if you want to actually make sure that update() was
effective, you can implement this through a hook::

$m->addHook('afterUpdateQuery',function($m, $update, $st) {
$m->onHook('afterUpdateQuery',function($m, $update, $st) {
if (!$st->rowCount()) {
throw new \atk4\core\Exception([
'Update didn\'t affect any records',
Expand All @@ -213,7 +213,7 @@ In some cases you want to prevent default actions from executing.
Suppose you want to check 'memcache' before actually loading the record from
the database. Here is how you can implement this functionality::

$m->addHook('beforeLoad',function($m, $id) {
$m->onHook('beforeLoad',function($m, $id) {
$data = $m->app->cacheFetch($m->table, $id);
if ($data) {
$m->data = $data;
Expand All @@ -239,13 +239,13 @@ This can be used in various situations.

Save information into auditLog about failure:

$m->addHook('onRollback', function($m){
$m->onHook('onRollback', function($m){
$m->auditLog->registerFailure();
});

Upgrade schema:

$m->addHook('onRollback', function($m, $exception) {
$m->onHook('onRollback', function($m, $exception) {
if ($exception instanceof \PDOException) {
$m->schema->upgrade();
$m->breakHook(false); // exception will not be thrown
Expand Down
10 changes: 7 additions & 3 deletions docs/model.rst
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ To invoke code from `init()` methods of ALL models (for example soft-delete logi
you use Persistence's "afterAdd" hook. This will not affect ALL models but just models
which are associated with said persistence::

$db->addHook('afterAdd', function($p, $m) use($acl) {
$db->onHook('afterAdd', function($p, $m) use($acl) {

$fields = $m->getFields();

Expand Down Expand Up @@ -391,7 +391,7 @@ a hook::

$this->addField('name');

$this->addHook('validate', function($m) {
$this->onHook('validate', function($m) {
if ($m['name'] == 'C#') {
return ['name'=>'No sharp objects are allowed'];
}
Expand Down Expand Up @@ -437,7 +437,7 @@ action - `send_gift`.
There are some advanced techniques like "SubTypes" or class substitution,
for example, this hook may be placed in the "User" class init()::

$this->addHook('afterLoad', function($m) {
$this->onHook('afterLoad', function($m) {
if ($m['purchases'] > 1000) {
$this->breakHook($this->asModel(VIPUser::class);
}
Expand Down Expand Up @@ -740,6 +740,10 @@ Title Field
Return title field value of currently loaded record.

.. php:method:: public getTitles
Returns array of title field values of all model records in format [id => title].

.. _caption:

Model Caption
Expand Down
4 changes: 2 additions & 2 deletions docs/overview.rst
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ If your persistence does not support expressions (e.g. you are using Redis or
MongoDB), you would need to define the field differently::

$model->addField('gross');
$model->addHook('beforeSave', function($m) {
$model->onHook('beforeSave', function($m) {
$m['gross'] = $m['net'] + $m['vat'];
});

Expand All @@ -186,7 +186,7 @@ you want it to work with NoSQL, then your solution might be::

// persistence does not support expressions
$model->addField('gross');
$model->addHook('beforeSave', function($m) {
$model->onHook('beforeSave', function($m) {
$m['gross'] = $m['net'] + $m['vat'];
});

Expand Down
12 changes: 6 additions & 6 deletions docs/persistence.rst
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@ this ref, how do you do it?

Start by creating a beforeSave handler for Order::

$this->addHook('beforeSave', function($m) {
$this->onHook('beforeSave', function($m) {
if ($this->isDirty('ref')) {

if (
Expand Down Expand Up @@ -684,11 +684,11 @@ application::
$m = $m->withPersistence($this->mdb)->replace();
}

$m->addHook('beforeSave', function($m){
$m->onHook('beforeSave', function($m){
$m->withPersistence($this->sql)->save();
});

$m->addHook('beforeDelete', function($m){
$m->onHook('beforeDelete', function($m){
$m->withPersistence($this->sql)->delete();
});

Expand Down Expand Up @@ -729,11 +729,11 @@ records.
The last two hooks are in order to replicate any changes into the SQL database
also::

$m->addHook('beforeSave', function($m){
$m->onHook('beforeSave', function($m){
$m->withPersistence($this->sql)->save();
});

$m->addHook('beforeDelete', function($m){
$m->onHook('beforeDelete', function($m){
$m->withPersistence($this->sql)->delete();
});

Expand Down Expand Up @@ -784,7 +784,7 @@ Archive Copies into different persistence
If you wish that every time you save your model the copy is also stored inside
some other database (for archive purposes) you can implement it like this::

$m->addHook('beforeSave', function($m) {
$m->onHook('beforeSave', function($m) {
$arc = $this->withPersistence($m->app->archive_db, false);

// add some audit fields
Expand Down
12 changes: 8 additions & 4 deletions src/Action/Iterator.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public function where($field, $value)
$this->generator = new \CallbackFilterIterator($this->generator, function ($row) use ($field, $value) {

// skip row. does not have field at all
if (!isset($row[$field])) {
if (!array_key_exists($field, $row)) {
return false;
}

Expand Down Expand Up @@ -66,12 +66,13 @@ public function like($field, $value)
$this->generator = new \CallbackFilterIterator($this->generator, function ($row) use ($field, $value) {

// skip row. does not have field at all
if (!isset($row[$field])) {
if (!array_key_exists($field, $row)) {
return false;
}

$clean_value = trim(trim($value), '%');
// the row field exists check the position of th "%"(s)
$value = trim($value);
$clean_value = trim($value, '%');
// the row field exists check the position of the "%"(s)
switch ($value) {
// case "%str%"
case substr($value, -1, 1) == '%' && substr($value, 0, 1) == '%':
Expand All @@ -85,6 +86,9 @@ public function like($field, $value)
case substr($value, 0, 1) == '%':
return substr($row[$field], -strlen($clean_value)) === $clean_value;
break;
// full match
default:
return $row[$field] == $clean_value;
}

return false;
Expand Down

0 comments on commit 79dd35d

Please sign in to comment.