Agile Data is only the beginning. With it, you will be able to define a unified API for your business logic and data. Because of the unification it makes it easy to implement add-ons.
This extension makes your models automatically keep change history inside external model with ability to undo actions. Integration with the audit features is extremely simple:
$user->add(new AuditController(new AuditLog()));
This extension allows you to define a full-featured models that combine multiple other extensions:
$multi_table_search = \atk4\report\UnionModel($db);
$multi_table_search->addNestedModel(new Article())
$multi_table_search->addNestedModel(new Blog())
$multi_table_search->addNestedModel(new ShopItem())
$multi_table_search->addCondition('is_public', true);
$multi_table_search->addCondition('published', '>', new DateTime("2015-01-01"));
$multi_table_search->search("foo bar");
$multi_table_search->setLimit(20);
$results = $multi_table_search->export();
You might want to store your data encrypted in the database and keep a super-secret decryption key in the config file.
Encryption extension adds new 'Field' class that natively supports
encryption based on PHP mcrypt
extension. The secret can be either
supplied on per-field basis or stored in your API.
$user->addField('surname');
$user->add(new Field_Encrypted('secret-key'), 'bank_account');
The rest of your application can continue to work normally, but the data will be stored encrypted for this individual field. Additional features:
The PHP applications are usually pretty transparent which makes it quite risky to use 3rd party code in many cases. Often you would need to isolate and feed data into 3rd party plugin for safety.
Agile Data's Secure Enclave extension allows you to pass your Models to 3rd party code without risk of it being able to access more that you let them. Use of Enclave is transparent and is recommended in all applications.
// before
$user = new User($db);
$user->load(20);
$grid->setModel($user->ref('Order'));
// with enclave
$user = new User($db);
$user->load(20);
$grid->setModel(new Enclave($user->ref('Order')));
By defaut Enclave allows $grid
to transparently work with all the records
inside the supplied DataSet and perform limited traversal:
Enclave will wrap around all traversals and will integrate with Agile Data models tightly.
$grid->setModel(new Enclave($user, $enclave_config));
You can supply enclave_config
parameter to further specify permissions:
sendReminder()
Enclave has a minimum performance degradation and can define system-wide policies that you can adjust for your use-case. As long as you don't make any global variables, Enclave makes it impossible to access more data than you allow.
Enclave cannot stop ability to manually load files.
Similarly to Enclave, proxy hides away code execution behind the RestAPI interface.
$u = new Proxy(new User(), $endpoint);
$u->load(20);
$o = $u->ref('Order');
echo $o->action('fx', ['sum', 'total']); // 3000
The proxy is actually a quite transparent class that is able to replicate Agile Data code execution through an endpoint API.
For the endpoint you'll need to run App_AgileDataAPI class:
$e = new App_AgileDataAPI();
$e->register('User', new User());
$e->execute();
This will expose list of your users through the API. Of course there is also a security mechanism and you can also use App in conjunction with Secure Enclave to further limit access to your models.
There are many situations when you might have your data across multiple models, but you want them joined together for some reason:
Aggregate model allows you to unite two separate Models that can come either from the same SQL table or from entirely different database engines. Apply conditions, set order and decide which fields you want in your aggregate table and it will always make a right decision when it comes to optimizing queries. Aggregate model will perform UNION if it's possible. Finally you get an opportunity to perform grouping or analytical operations on your data or even some map-reduce magic.
$m = new Aggregate\Model($db));
$m->addModel(new Purchase(), ['amount' => 'purchase_amount']);
$m->addModel(new Sales());
$m->addModel(new ArchivedSales($archive_db));
$m->groupByMonth('date');
$m->aggregateField('amount');
$m->setOrder('amount desc');
$m->setLimit(20);
$m->export();
The above code will perform UNION between Pruchase and Sales models, while ArchivedSales will be added on top using a separate aggregation query on an $archive_db vendor. Results will be grouped by date and amounts will be added up. Only the first 20 results will be presented and by default only the fields will be included that appear in all models. Purchase model used column mapping, beacuse a physical one is called 'purchase_amount' and not 'amount':
[
[{date: '08-12-2015', amount: 294.88}],
[{date: '09-12-2015', amount: 4993.29}],
[{date: '10-12-2015', amount: 0.00}],
]
This is a high-level extension that adds the following funcitonality:
$im = $user->add(Filestore\Image(), 'thumb_id');
$im->setCDN('S3');
// later
$im = $user->ref('thumb_id');
$im->importImage($file);
$user->save();
// later
$user->uploadAssets();
There are multiple minor extensions available:
All of the above extensions will work with YOUR data structure!
Contact us if you wish to get early access to those extensions.
Somehow we forgot to implement "or" conditions. Spotted and implemented in version 1.1.11.
For all your aggregation needs. Use your Domain Models to GROUP and UNION without hardcore queries.
We are now officially in the "stable" mode. Expect less releases and more focus on stability.
Practical event sourcing for your PHP project. Full audit trail and UNDO functionality.
Added a strong type support as well as many bugfixes and improvements.