Merge branch 'main' into develop
commit
6e33d78996
|
@ -0,0 +1,116 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Migrations\AbstractMigration;
|
||||||
|
use Phinx\Db\Adapter\MysqlAdapter;
|
||||||
|
|
||||||
|
final class Enumerations extends AbstractMigration
|
||||||
|
{
|
||||||
|
public $autoId = false; // turn off automatic `id` column create. We want it to be `int(10) unsigned`
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change Method.
|
||||||
|
*
|
||||||
|
* Write your reversible migrations using this method.
|
||||||
|
*
|
||||||
|
* More information on writing migrations is available here:
|
||||||
|
* https://book.cakephp.org/phinx/0/en/migrations.html#the-change-method
|
||||||
|
*
|
||||||
|
* Remember to call "create()" or "update()" and NOT "save()" when working
|
||||||
|
* with the Table class.
|
||||||
|
*/
|
||||||
|
public function change(): void
|
||||||
|
{
|
||||||
|
$exists = $this->hasTable('enumeration_collections');
|
||||||
|
if (!$exists) {
|
||||||
|
$enumerationCollectionsTable = $this->table('enumeration_collections', [
|
||||||
|
'signed' => false,
|
||||||
|
'collation' => 'utf8mb4_unicode_ci'
|
||||||
|
]);
|
||||||
|
$enumerationCollectionsTable
|
||||||
|
->addColumn('id', 'integer', [
|
||||||
|
'autoIncrement' => true,
|
||||||
|
'limit' => 10,
|
||||||
|
'signed' => false,
|
||||||
|
])
|
||||||
|
->addPrimaryKey('id')
|
||||||
|
->addColumn('uuid', 'string', [
|
||||||
|
'null' => false,
|
||||||
|
'limit' => 40,
|
||||||
|
'collation' => 'ascii_general_ci',
|
||||||
|
'encoding' => 'ascii',
|
||||||
|
])
|
||||||
|
->addColumn('name', 'string', [
|
||||||
|
'null' => false,
|
||||||
|
'limit' => 191,
|
||||||
|
'collation' => 'utf8mb4_unicode_ci',
|
||||||
|
'encoding' => 'utf8mb4',
|
||||||
|
])
|
||||||
|
->addColumn('description', 'text', [
|
||||||
|
'default' => null,
|
||||||
|
'null' => true
|
||||||
|
])
|
||||||
|
->addColumn('target_model', 'string', [
|
||||||
|
'null' => false,
|
||||||
|
'limit' => 255,
|
||||||
|
'collation' => 'ascii_general_ci',
|
||||||
|
'encoding' => 'ascii',
|
||||||
|
])
|
||||||
|
->addColumn('target_field', 'string', [
|
||||||
|
'null' => false,
|
||||||
|
'limit' => 255,
|
||||||
|
'collation' => 'ascii_general_ci',
|
||||||
|
'encoding' => 'ascii',
|
||||||
|
])
|
||||||
|
->addColumn('enabled', 'boolean', [
|
||||||
|
'default' => 0,
|
||||||
|
])
|
||||||
|
->addColumn('deleted', 'boolean', [
|
||||||
|
'default' => 0,
|
||||||
|
])
|
||||||
|
->addColumn('created', 'datetime', [
|
||||||
|
'null' => false
|
||||||
|
])
|
||||||
|
->addColumn('modified', 'datetime', [
|
||||||
|
'null' => false
|
||||||
|
])
|
||||||
|
->addIndex('name')
|
||||||
|
->addIndex('target_model')
|
||||||
|
->addIndex('target_field')
|
||||||
|
->addIndex('uuid', ['unique' => true]);
|
||||||
|
|
||||||
|
$enumerationCollectionsTable->create();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$exists = $this->hasTable('enumerations');
|
||||||
|
if (!$exists) {
|
||||||
|
$enumerationsTable = $this->table('enumerations', [
|
||||||
|
'signed' => false,
|
||||||
|
'collation' => 'utf8mb4_unicode_ci'
|
||||||
|
]);
|
||||||
|
$enumerationsTable
|
||||||
|
->addColumn('id', 'integer', [
|
||||||
|
'autoIncrement' => true,
|
||||||
|
'limit' => 10,
|
||||||
|
'signed' => false,
|
||||||
|
])
|
||||||
|
->addPrimaryKey('id')
|
||||||
|
->addColumn('value', 'string', [
|
||||||
|
'null' => false,
|
||||||
|
'limit' => 191,
|
||||||
|
'collation' => 'utf8mb4_unicode_ci',
|
||||||
|
'encoding' => 'utf8mb4',
|
||||||
|
])
|
||||||
|
->addColumn('enumeration_collection_id', 'integer', [
|
||||||
|
'limit' => 10,
|
||||||
|
'signed' => false,
|
||||||
|
'null' => false
|
||||||
|
])
|
||||||
|
->addIndex('value')
|
||||||
|
->addIndex('enumeration_collection_id');
|
||||||
|
$enumerationsTable->create();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -75,6 +75,17 @@ class ACLComponent extends Component
|
||||||
'delete' => ['*'],
|
'delete' => ['*'],
|
||||||
'index' => ['*']
|
'index' => ['*']
|
||||||
],
|
],
|
||||||
|
'Enumerations' => [
|
||||||
|
'delete' => ['perm_admin'],
|
||||||
|
'index' => ['*']
|
||||||
|
],
|
||||||
|
'EnumerationCollections' => [
|
||||||
|
'view' => ['*'],
|
||||||
|
'add' => ['perm_admin'],
|
||||||
|
'edit' => ['perm_admin'],
|
||||||
|
'delete' => ['perm_admin'],
|
||||||
|
'index' => ['*']
|
||||||
|
],
|
||||||
'Inbox' => [
|
'Inbox' => [
|
||||||
'createEntry' => ['OR' => ['perm_admin', 'perm_sync']],
|
'createEntry' => ['OR' => ['perm_admin', 'perm_sync']],
|
||||||
'delete' => ['perm_admin'],
|
'delete' => ['perm_admin'],
|
||||||
|
|
|
@ -50,7 +50,6 @@ class CRUDComponent extends Component
|
||||||
if ($this->taggingSupported()) {
|
if ($this->taggingSupported()) {
|
||||||
$options['filters'][] = 'filteringTags';
|
$options['filters'][] = 'filteringTags';
|
||||||
}
|
}
|
||||||
|
|
||||||
$optionFilters = [];
|
$optionFilters = [];
|
||||||
$optionFilters += empty($options['filters']) ? [] : $options['filters'];
|
$optionFilters += empty($options['filters']) ? [] : $options['filters'];
|
||||||
foreach ($optionFilters as $i => $filter) {
|
foreach ($optionFilters as $i => $filter) {
|
||||||
|
@ -85,9 +84,22 @@ class CRUDComponent extends Component
|
||||||
$this->Controller->paginate['order'] = $options['order'];
|
$this->Controller->paginate['order'] = $options['order'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!empty($this->request->getQuery('sort'))) {
|
||||||
|
$sort = $this->request->getQuery('sort');
|
||||||
|
$direction = $this->request->getQuery('direction');
|
||||||
|
if ($this->_validOrderFields($sort) && ($direction === 'asc' || $direction === 'desc')) {
|
||||||
|
$sort = explode('.', $sort);
|
||||||
|
if (count($sort) > 1) {
|
||||||
|
$sort[0] = Inflector::camelize(Inflector::pluralize($sort[0]));
|
||||||
|
}
|
||||||
|
$sort = implode('.', $sort);
|
||||||
|
$query->order($sort . ' ' . $direction);
|
||||||
|
}
|
||||||
|
}
|
||||||
if ($this->metaFieldsSupported() && !$this->Controller->ParamHandler->isRest()) {
|
if ($this->metaFieldsSupported() && !$this->Controller->ParamHandler->isRest()) {
|
||||||
$query = $this->includeRequestedMetaFields($query);
|
$query = $this->includeRequestedMetaFields($query);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$this->Controller->ParamHandler->isRest()) {
|
if (!$this->Controller->ParamHandler->isRest()) {
|
||||||
$this->setRequestedEntryAmount();
|
$this->setRequestedEntryAmount();
|
||||||
}
|
}
|
||||||
|
@ -387,6 +399,14 @@ class CRUDComponent extends Component
|
||||||
if (!empty($params['fields'])) {
|
if (!empty($params['fields'])) {
|
||||||
$this->Controller->set('fields', $params['fields']);
|
$this->Controller->set('fields', $params['fields']);
|
||||||
}
|
}
|
||||||
|
$EnumerationCollections = TableRegistry::getTableLocator()->get('EnumerationCollections');
|
||||||
|
$modelAlias = $this->Table->getAlias();
|
||||||
|
if (in_array($this->Table->getAlias(), $EnumerationCollections->getValidModelList())) {
|
||||||
|
$enumerations = $EnumerationCollections->getFieldValues($modelAlias);
|
||||||
|
if (!empty($enumerations)) {
|
||||||
|
$this->Controller->set('enumerations', $enumerations);
|
||||||
|
}
|
||||||
|
}
|
||||||
$this->Controller->entity = $data;
|
$this->Controller->entity = $data;
|
||||||
$this->Controller->set('entity', $data);
|
$this->Controller->set('entity', $data);
|
||||||
}
|
}
|
||||||
|
@ -1673,7 +1693,7 @@ class CRUDComponent extends Component
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$association = $this->Table->associations()->get($model);
|
$association = $this->Table->associations()->get(Inflector::camelize(Inflector::pluralize($model)));
|
||||||
$associatedTable = $association->getTarget();
|
$associatedTable = $association->getTarget();
|
||||||
if (empty($associatedTable->getSchema()->typeMap()[$subField])) {
|
if (empty($associatedTable->getSchema()->typeMap()[$subField])) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -128,6 +128,11 @@ class Sidemenu {
|
||||||
'url' => '/permissionLimitations/index',
|
'url' => '/permissionLimitations/index',
|
||||||
'icon' => 'jedi',
|
'icon' => 'jedi',
|
||||||
],
|
],
|
||||||
|
'Enumerations' => [
|
||||||
|
'label' => __('Collections'),
|
||||||
|
'url' => '/enumerationCollections/index',
|
||||||
|
'icon' => 'list',
|
||||||
|
],
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'API' => [
|
'API' => [
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller;
|
||||||
|
|
||||||
|
use App\Controller\AppController;
|
||||||
|
use Cake\Utility\Hash;
|
||||||
|
use Cake\Utility\Text;
|
||||||
|
use \Cake\Database\Expression\QueryExpression;
|
||||||
|
use Cake\Http\Exception\NotFoundException;
|
||||||
|
use Cake\Http\Exception\MethodNotAllowedException;
|
||||||
|
use Cake\Http\Exception\ForbiddenException;
|
||||||
|
|
||||||
|
class EnumerationCollectionsController extends AppController
|
||||||
|
{
|
||||||
|
public $filterFields = ['name', 'target_model', 'target_field'];
|
||||||
|
public $quickFilterFields = ['name', 'target_model', 'target_field'];
|
||||||
|
public $containFields = [];
|
||||||
|
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$this->CRUD->index([
|
||||||
|
'filters' => $this->filterFields,
|
||||||
|
'quickFilters' => $this->quickFilterFields,
|
||||||
|
'contain' => ['Enumerations'],
|
||||||
|
'afterFind' => function($data) {
|
||||||
|
$data->value_count = isset($data->enumerations) ? count($data->enumerations) : 0;
|
||||||
|
$data->values = Hash::extract($data, 'enumerations.{n}.value');
|
||||||
|
unset($data->enumerations);
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
$responsePayload = $this->CRUD->getResponsePayload();
|
||||||
|
if (!empty($responsePayload)) {
|
||||||
|
return $responsePayload;
|
||||||
|
}
|
||||||
|
$this->set('metaGroup', 'Enumerations');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function add()
|
||||||
|
{
|
||||||
|
$this->CRUD->add([
|
||||||
|
'afterSave' => function($data) {
|
||||||
|
$this->EnumerationCollections->captureValues($data);
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
$responsePayload = $this->CRUD->getResponsePayload();
|
||||||
|
if (!empty($responsePayload)) {
|
||||||
|
return $responsePayload;
|
||||||
|
}
|
||||||
|
$this->set(compact('enumerations'));
|
||||||
|
$this->set('metaGroup', 'Enumerations');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function view($id)
|
||||||
|
{
|
||||||
|
$this->CRUD->view($id);
|
||||||
|
$responsePayload = $this->CRUD->getResponsePayload();
|
||||||
|
if (!empty($responsePayload)) {
|
||||||
|
return $responsePayload;
|
||||||
|
}
|
||||||
|
$this->set('metaGroup', 'Enumerations');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function edit($id)
|
||||||
|
{
|
||||||
|
$this->CRUD->edit($id, [
|
||||||
|
'afterSave' => function($data) {
|
||||||
|
$this->EnumerationCollections->purgeValues($data);
|
||||||
|
$this->EnumerationCollections->captureValues($data);
|
||||||
|
},
|
||||||
|
'contain' => ['Enumerations'],
|
||||||
|
'afterFind' => function($data) {
|
||||||
|
$values = [];
|
||||||
|
foreach ($data['enumerations'] as $enumeration) {
|
||||||
|
$values[] = $enumeration['value'];
|
||||||
|
}
|
||||||
|
$data->values = implode(PHP_EOL, $values);
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
$responsePayload = $this->CRUD->getResponsePayload();
|
||||||
|
if (!empty($responsePayload)) {
|
||||||
|
return $responsePayload;
|
||||||
|
}
|
||||||
|
$this->set('metaGroup', 'Enumerations');
|
||||||
|
$this->render('add');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete($id)
|
||||||
|
{
|
||||||
|
$this->CRUD->delete($id);
|
||||||
|
$responsePayload = $this->CRUD->getResponsePayload();
|
||||||
|
if (!empty($responsePayload)) {
|
||||||
|
return $responsePayload;
|
||||||
|
}
|
||||||
|
$this->set('metaGroup', 'Enumerations');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller;
|
||||||
|
|
||||||
|
use App\Controller\AppController;
|
||||||
|
use Cake\Utility\Hash;
|
||||||
|
use Cake\Utility\Text;
|
||||||
|
use \Cake\Database\Expression\QueryExpression;
|
||||||
|
use Cake\Http\Exception\NotFoundException;
|
||||||
|
use Cake\Http\Exception\MethodNotAllowedException;
|
||||||
|
use Cake\Http\Exception\ForbiddenException;
|
||||||
|
|
||||||
|
class EnumerationsController extends AppController
|
||||||
|
{
|
||||||
|
public $filterFields = ['value'];
|
||||||
|
public $quickFilterFields = ['value'];
|
||||||
|
public $containFields = [];
|
||||||
|
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$this->CRUD->index([
|
||||||
|
'filters' => $this->filterFields,
|
||||||
|
'quickFilters' => $this->quickFilterFields
|
||||||
|
]);
|
||||||
|
$responsePayload = $this->CRUD->getResponsePayload();
|
||||||
|
if (!empty($responsePayload)) {
|
||||||
|
return $responsePayload;
|
||||||
|
}
|
||||||
|
$this->set('metaGroup', 'Enumerations');
|
||||||
|
}
|
||||||
|
public function delete($id)
|
||||||
|
{
|
||||||
|
$this->CRUD->delete($id);
|
||||||
|
$responsePayload = $this->CRUD->getResponsePayload();
|
||||||
|
if (!empty($responsePayload)) {
|
||||||
|
return $responsePayload;
|
||||||
|
}
|
||||||
|
$this->set('metaGroup', 'Enumerations');
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,7 +11,7 @@ use Cake\Http\Exception\NotFoundException;
|
||||||
|
|
||||||
class UsersController extends AppController
|
class UsersController extends AppController
|
||||||
{
|
{
|
||||||
public $filterFields = ['Individuals.uuid', 'username', 'Individuals.email', 'Individuals.first_name', 'Individuals.last_name', 'Organisations.name'];
|
public $filterFields = ['Individuals.uuid', 'username', 'Individuals.email', 'Individuals.first_name', 'Individuals.last_name', 'Organisations.name', 'Organisation.nationality'];
|
||||||
public $quickFilterFields = ['Individuals.uuid', ['username' => true], ['Individuals.first_name' => true], ['Individuals.last_name' => true], 'Individuals.email'];
|
public $quickFilterFields = ['Individuals.uuid', ['username' => true], ['Individuals.first_name' => true], ['Individuals.last_name' => true], 'Individuals.email'];
|
||||||
public $containFields = ['Individuals', 'Roles', 'UserSettings', 'Organisations'];
|
public $containFields = ['Individuals', 'Roles', 'UserSettings', 'Organisations'];
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Model\Entity;
|
||||||
|
|
||||||
|
use App\Model\Entity\AppModel;
|
||||||
|
use Cake\ORM\Entity;
|
||||||
|
|
||||||
|
class Enumeration extends AppModel
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Model\Entity;
|
||||||
|
|
||||||
|
use App\Model\Entity\AppModel;
|
||||||
|
use Cake\ORM\Entity;
|
||||||
|
|
||||||
|
class EnumerationCollection extends AppModel
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,118 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Model\Table;
|
||||||
|
|
||||||
|
use App\Model\Table\AppTable;
|
||||||
|
use Cake\ORM\Table;
|
||||||
|
use Cake\Validation\Validator;;
|
||||||
|
use Cake\Datasource\EntityInterface;
|
||||||
|
use Cake\Event\Event;
|
||||||
|
use Cake\Event\EventInterface;
|
||||||
|
use Cake\Utility\Text;
|
||||||
|
use ArrayObject;
|
||||||
|
|
||||||
|
class EnumerationCollectionsTable extends AppTable
|
||||||
|
{
|
||||||
|
private $fieldMapping = [
|
||||||
|
'Organisations' => [
|
||||||
|
'country',
|
||||||
|
'sector',
|
||||||
|
'type'
|
||||||
|
]
|
||||||
|
];
|
||||||
|
public function initialize(array $config): void
|
||||||
|
{
|
||||||
|
parent::initialize($config);
|
||||||
|
$this->addBehavior('UUID');
|
||||||
|
$this->addBehavior('AuditLog');
|
||||||
|
$this->addBehavior('Timestamp');
|
||||||
|
$this->hasMany(
|
||||||
|
'Enumerations',
|
||||||
|
[
|
||||||
|
'dependent' => true
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$this->setDisplayField('name');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function beforeMarshal(EventInterface $event, ArrayObject $data, ArrayObject $options)
|
||||||
|
{
|
||||||
|
if (empty($data['uuid'])) {
|
||||||
|
$data['uuid'] = Text::uuid();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function validationDefault(Validator $validator): Validator
|
||||||
|
{
|
||||||
|
$validator
|
||||||
|
->notEmptyString('name')
|
||||||
|
->requirePresence(['name'], 'create')
|
||||||
|
->notEmptyString('uuid')
|
||||||
|
->requirePresence(['uuid'], 'create')
|
||||||
|
->notEmptyString('target_model')
|
||||||
|
->requirePresence(['target_model'], 'create')
|
||||||
|
->notEmptyString('target_field')
|
||||||
|
->requirePresence(['target_field'], 'create');
|
||||||
|
return $validator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getValidFieldList(?string $model = null): array
|
||||||
|
{
|
||||||
|
if (!empty($model)) {
|
||||||
|
if (empty($this->fieldMapping[$model])) {
|
||||||
|
return [];
|
||||||
|
} else {
|
||||||
|
return $this->fieldMapping[$model];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return $this->fieldMapping;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getValidModelList(?string $model = null): array
|
||||||
|
{
|
||||||
|
|
||||||
|
return array_keys($this->fieldMapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFieldValues($model): array
|
||||||
|
{
|
||||||
|
$collections = $this->find('all')->where(['target_model' => $model, 'enabled' => 1, 'deleted' => 0])->contain(['Enumerations'])->disableHydration()->all()->toArray();
|
||||||
|
$options = [];
|
||||||
|
foreach ($collections as $collection) {
|
||||||
|
if (empty($collection['target_field'])) {
|
||||||
|
$options[$collection['target_field']] = [];
|
||||||
|
}
|
||||||
|
foreach ($collection['enumerations'] as $enumeration) {
|
||||||
|
$options[$collection['target_field']][$enumeration['value']] = $enumeration['value'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $options;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function purgeValues(\App\Model\Entity\EnumerationCollection $entity): void
|
||||||
|
{
|
||||||
|
$this->Enumerations->deleteAll([
|
||||||
|
'enumeration_collection_id' => $entity->id
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function captureValues(\App\Model\Entity\EnumerationCollection $entity): void
|
||||||
|
{
|
||||||
|
if (!empty($entity->values)) {
|
||||||
|
$values = $entity->values;
|
||||||
|
$collection_id = $entity->id;
|
||||||
|
if (!is_array($values)) {
|
||||||
|
$values = explode("\n", $values);
|
||||||
|
}
|
||||||
|
foreach ($values as $value) {
|
||||||
|
$enumeration = $this->Enumerations->newEntity([
|
||||||
|
'value' => trim($value),
|
||||||
|
'enumeration_collection_id' => $entity->id
|
||||||
|
]);
|
||||||
|
$this->Enumerations->save($enumeration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Model\Table;
|
||||||
|
|
||||||
|
use App\Model\Table\AppTable;
|
||||||
|
use Cake\ORM\Table;
|
||||||
|
use Cake\Validation\Validator;
|
||||||
|
|
||||||
|
class EnumerationsTable extends AppTable
|
||||||
|
{
|
||||||
|
public function initialize(array $config): void
|
||||||
|
{
|
||||||
|
parent::initialize($config);
|
||||||
|
$this->belongsTo(
|
||||||
|
'EnumerationCollection'
|
||||||
|
);
|
||||||
|
$this->setDisplayField('value');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function validationDefault(Validator $validator): Validator
|
||||||
|
{
|
||||||
|
$validator
|
||||||
|
->notEmptyString('value')
|
||||||
|
->requirePresence(['value'], 'create')
|
||||||
|
->notEmptyString('enumeration_collection_id')
|
||||||
|
->requirePresence(['enumeration_collection_id'], 'create');
|
||||||
|
return $validator;
|
||||||
|
}
|
||||||
|
}
|
|
@ -47,7 +47,8 @@ class UsersTable extends AppTable
|
||||||
'Organisations',
|
'Organisations',
|
||||||
[
|
[
|
||||||
'dependent' => false,
|
'dependent' => false,
|
||||||
'cascadeCallbacks' => false
|
'cascadeCallbacks' => false,
|
||||||
|
'strategy' => 'join'
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
$this->hasMany(
|
$this->hasMany(
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
echo $this->element('genericElements/Form/genericForm', [
|
||||||
|
'data' => [
|
||||||
|
'description' => __('Roles define global rules for a set of users, including first and foremost access controls to certain functionalities.'),
|
||||||
|
'model' => 'EnumerationCollections',
|
||||||
|
'fields' => [
|
||||||
|
[
|
||||||
|
'field' => 'name',
|
||||||
|
'label' => __('Name')
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'field' => 'enabled',
|
||||||
|
'label' => __('Enabled'),
|
||||||
|
'type' => 'checkbox',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'field' => 'target_model',
|
||||||
|
'label' => __('Model'),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'field' => 'target_field',
|
||||||
|
'label' => __('Field'),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'field' => 'description',
|
||||||
|
'label' => __('Description'),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'field' => 'values',
|
||||||
|
'label' => __('Values'),
|
||||||
|
'type' => 'textarea'
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'submit' => [
|
||||||
|
'action' => $this->request->getParam('action')
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
?>
|
||||||
|
</div>
|
|
@ -0,0 +1,96 @@
|
||||||
|
<?php
|
||||||
|
$topbarChildren = [];
|
||||||
|
if (!empty($loggedUser->role->perm_admin)) {
|
||||||
|
$topbarChildren[] = [
|
||||||
|
'type' => 'simple',
|
||||||
|
'children' => [
|
||||||
|
'data' => [
|
||||||
|
'type' => 'simple',
|
||||||
|
'text' => __('Add Enumeration Collection'),
|
||||||
|
'class' => 'btn btn-primary',
|
||||||
|
'popover_url' => '/enumerationCollections/add'
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
$topbarChildren[] = [
|
||||||
|
'type' => 'search',
|
||||||
|
'button' => __('Search'),
|
||||||
|
'placeholder' => __('Enter value to search'),
|
||||||
|
'data' => '',
|
||||||
|
'searchKey' => 'value'
|
||||||
|
];
|
||||||
|
|
||||||
|
echo $this->element('genericElements/IndexTable/index_table', [
|
||||||
|
'data' => [
|
||||||
|
'data' => $data,
|
||||||
|
'top_bar' => [
|
||||||
|
'children' => $topbarChildren,
|
||||||
|
],
|
||||||
|
'fields' => [
|
||||||
|
[
|
||||||
|
'name' => '#',
|
||||||
|
'sort' => 'id',
|
||||||
|
'data_path' => 'id',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => __('Name'),
|
||||||
|
'sort' => 'name',
|
||||||
|
'data_path' => 'name',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => __('Enabled'),
|
||||||
|
'sort' => 'enabled',
|
||||||
|
'data_path' => 'enabled',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => __('UUID'),
|
||||||
|
'sort' => 'uuid',
|
||||||
|
'data_path' => 'uuid',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => __('Model'),
|
||||||
|
'sort' => 'target_model',
|
||||||
|
'data_path' => 'target_model',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => __('Field'),
|
||||||
|
'sort' => 'target_field',
|
||||||
|
'data_path' => 'target_field',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => __('Values'),
|
||||||
|
'sort' => 'value_count',
|
||||||
|
'data_path' => 'value_count',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => __('Description'),
|
||||||
|
'data_path' => 'description',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'title' => __('Enumeration Collections Index'),
|
||||||
|
'description' => __('A list collections that can be used to convert string input fields into selections wherever it makes sense.'),
|
||||||
|
'pull' => 'right',
|
||||||
|
'actions' => [
|
||||||
|
[
|
||||||
|
'url' => '/enumerationCollections/view',
|
||||||
|
'url_params_data_paths' => ['id'],
|
||||||
|
'icon' => 'eye'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'open_modal' => '/enumerationCollections/edit/[onclick_params_data_path]',
|
||||||
|
'modal_params_data_path' => 'id',
|
||||||
|
'icon' => 'edit',
|
||||||
|
'requirement' => !empty($loggedUser['role']['perm_admin'])
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'open_modal' => '/enumerationCollections/delete/[onclick_params_data_path]',
|
||||||
|
'modal_params_data_path' => 'id',
|
||||||
|
'icon' => 'trash',
|
||||||
|
'requirement' => !empty($loggedUser['role']['perm_admin'])
|
||||||
|
],
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
echo '</div>';
|
||||||
|
?>
|
|
@ -0,0 +1,46 @@
|
||||||
|
<?php
|
||||||
|
echo $this->element(
|
||||||
|
'/genericElements/SingleViews/single_view',
|
||||||
|
[
|
||||||
|
'data' => $entity,
|
||||||
|
'fields' => [
|
||||||
|
[
|
||||||
|
'key' => __('ID'),
|
||||||
|
'path' => 'id'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'key' => __('Name'),
|
||||||
|
'path' => 'name'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'key' => __('Enabled'),
|
||||||
|
'path' => 'enabled',
|
||||||
|
'type' => 'boolean'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'key' => __('UUID'),
|
||||||
|
'path' => 'uuid'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'key' => __('Model'),
|
||||||
|
'path' => 'target_model'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'key' => __('Field'),
|
||||||
|
'path' => 'target_field'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'key' => __('Description'),
|
||||||
|
'path' => 'description'
|
||||||
|
],
|
||||||
|
|
||||||
|
],
|
||||||
|
'children' => [
|
||||||
|
[
|
||||||
|
'url' => '/Enumerations/index?EnumerationCollection.id={{0}}',
|
||||||
|
'url_params' => ['id'],
|
||||||
|
'title' => __('Values')
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
);
|
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
echo $this->element('genericElements/IndexTable/index_table', [
|
||||||
|
'data' => [
|
||||||
|
'data' => $data,
|
||||||
|
'top_bar' => [
|
||||||
|
'children' => [
|
||||||
|
[
|
||||||
|
'type' => 'search',
|
||||||
|
'button' => __('Search'),
|
||||||
|
'placeholder' => __('Enter value to search'),
|
||||||
|
'data' => '',
|
||||||
|
'searchKey' => 'value'
|
||||||
|
]
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'fields' => [
|
||||||
|
[
|
||||||
|
'name' => '#',
|
||||||
|
'sort' => 'id',
|
||||||
|
'data_path' => 'id',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => __('Value'),
|
||||||
|
'sort' => 'value',
|
||||||
|
'data_path' => 'value',
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'title' => __('Enumerations Index'),
|
||||||
|
'description' => null,
|
||||||
|
'pull' => 'right',
|
||||||
|
'actions' => [
|
||||||
|
[
|
||||||
|
'open_modal' => '/enumerations/delete/[onclick_params_data_path]',
|
||||||
|
'modal_params_data_path' => 'id',
|
||||||
|
'icon' => 'trash',
|
||||||
|
'requirement' => !empty($loggedUser['role']['perm_admin'])
|
||||||
|
],
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
echo '</div>';
|
||||||
|
?>
|
|
@ -2,7 +2,7 @@
|
||||||
echo $this->element('genericElements/Form/genericForm', array(
|
echo $this->element('genericElements/Form/genericForm', array(
|
||||||
'data' => array(
|
'data' => array(
|
||||||
'description' => __('Organisations can be equivalent to legal entities or specific individual teams within such entities. Their purpose is to relate individuals to their affiliations and for release control of information using the Trust Circles.'),
|
'description' => __('Organisations can be equivalent to legal entities or specific individual teams within such entities. Their purpose is to relate individuals to their affiliations and for release control of information using the Trust Circles.'),
|
||||||
'model' => 'Organisations',
|
'model' => 'Organisation',
|
||||||
'fields' => array(
|
'fields' => array(
|
||||||
array(
|
array(
|
||||||
'field' => 'name'
|
'field' => 'name'
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Cake\Core\Configure;
|
use Cake\Core\Configure;
|
||||||
|
|
||||||
echo $this->element('genericElements/IndexTable/index_table', [
|
echo $this->element('genericElements/IndexTable/index_table', [
|
||||||
'data' => [
|
'data' => [
|
||||||
'data' => $data,
|
'data' => $data,
|
||||||
|
@ -88,6 +87,11 @@ echo $this->element('genericElements/IndexTable/index_table', [
|
||||||
'url' => '/roles/view/{{0}}',
|
'url' => '/roles/view/{{0}}',
|
||||||
'url_vars' => ['role.id']
|
'url_vars' => ['role.id']
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
'name' => __('Country'),
|
||||||
|
'sort' => 'organisation.nationality',
|
||||||
|
'data_path' => 'organisation.nationality'
|
||||||
|
],
|
||||||
[
|
[
|
||||||
'name' => __('# User Settings'),
|
'name' => __('# User Settings'),
|
||||||
'element' => 'count_summary',
|
'element' => 'count_summary',
|
||||||
|
|
|
@ -44,6 +44,10 @@ $fields = [
|
||||||
'key' => __('Last name'),
|
'key' => __('Last name'),
|
||||||
'path' => 'individual.last_name'
|
'path' => 'individual.last_name'
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
'key' => __('Country'),
|
||||||
|
'path' => 'organisation.nationality'
|
||||||
|
],
|
||||||
[
|
[
|
||||||
'key' => __('Alignments'),
|
'key' => __('Alignments'),
|
||||||
'type' => 'alignment',
|
'type' => 'alignment',
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php
|
<?php
|
||||||
if (is_array($fieldData)) {
|
if (is_array($fieldData)) {
|
||||||
|
// Don't barf if the model is not explicitly passed
|
||||||
|
$modelForForm = empty($data['model']) ?
|
||||||
|
h(\Cake\Utility\Inflector::singularize(\Cake\Utility\Inflector::classify($this->request->getParam('controller')))) :
|
||||||
|
h($data['model']);
|
||||||
$fieldTemplate = 'genericField';
|
$fieldTemplate = 'genericField';
|
||||||
if (!empty($fieldData['type'])) {
|
if (!empty($fieldData['type'])) {
|
||||||
if (file_exists(ROOT . '/templates/element/genericElements/Form/Fields/' . $fieldData['type'] . 'Field.php')) {
|
if (file_exists(ROOT . '/templates/element/genericElements/Form/Fields/' . $fieldData['type'] . 'Field.php')) {
|
||||||
|
|
|
@ -26,6 +26,14 @@
|
||||||
}
|
}
|
||||||
$formRandomValue = Cake\Utility\Security::randomString(8);
|
$formRandomValue = Cake\Utility\Security::randomString(8);
|
||||||
$initSelect2 = false;
|
$initSelect2 = false;
|
||||||
|
|
||||||
|
if (!empty($enumerations)) {
|
||||||
|
foreach ($data['fields'] as $k => $field) {
|
||||||
|
if (isset($enumerations[$field['field']])) {
|
||||||
|
$data['fields'][$k]['options'] = $enumerations[$field['field']];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
$formCreate = $this->Form->create($entity, ['id' => 'form-' . $formRandomValue]);
|
$formCreate = $this->Form->create($entity, ['id' => 'form-' . $formRandomValue]);
|
||||||
$default_template = [
|
$default_template = [
|
||||||
'inputContainer' => '<div class="row mb-3">{{content}}</div>',
|
'inputContainer' => '<div class="row mb-3">{{content}}</div>',
|
||||||
|
|
Loading…
Reference in New Issue