Merge branch 'master' of github.com:cerebrate-project/cerebrate

remotes/origin/main
Alexandre Dulaunoy 2020-06-04 12:25:59 +02:00
commit b53001654f
No known key found for this signature in database
GPG Key ID: 09E2CD4944E6CBCD
25 changed files with 338 additions and 80 deletions

View File

@ -18,7 +18,6 @@ return [
* Development Mode: * Development Mode:
* true: Errors and warnings shown. * true: Errors and warnings shown.
*/ */
'debug' => filter_var(env('DEBUG', true), FILTER_VALIDATE_BOOLEAN),
/* /*
* Configure basic information about the application. * Configure basic information about the application.

View File

@ -24,6 +24,7 @@ use Cake\Utility\Text;
use Cake\Http\Exception\NotFoundException; use Cake\Http\Exception\NotFoundException;
use Cake\Http\Exception\MethodNotAllowedException; use Cake\Http\Exception\MethodNotAllowedException;
use Cake\Http\Exception\ForbiddenException; use Cake\Http\Exception\ForbiddenException;
use Cake\Error\Debugger;
/** /**
* Application Controller * Application Controller
@ -101,4 +102,30 @@ class AppController extends Controller
$uuid = Text::uuid(); $uuid = Text::uuid();
return $this->RestResponse->viewData(['uuid' => $uuid], 'json'); return $this->RestResponse->viewData(['uuid' => $uuid], 'json');
} }
/*
* Harvest parameters form a request
*
* Requires the request object and a list of keys to filter as input
* Order of precedence:
* ordered uri components (/foo/bar/baz) > query strings (?foo=bar) > posted data (json body {"foo": "bar"})
*/
protected function _harvestParams(\Cake\Http\ServerRequest $request, array $filterList): array
{
$parsedParams = array();
foreach ($filterList as $k => $filter) {
if (isset($request->getAttribute('params')['pass'][$k])) {
$parsedParams[$filter] = $request->getAttribute('params')['pass'][$k];
continue;
}
if (($request->getQuery($filter)) !== null) {
$parsedParams[$filter] = $request->getQuery($filter);
continue;
}
if (($this->request->is('post') || $this->request->is('put')) && $this->request->getData($filter) !== null) {
$parsedParams[$filter] = $this->request->getData($filter);
}
}
return $parsedParams;
}
} }

View File

@ -14,15 +14,17 @@ use Cake\Error\Debugger;
class EncryptionKeysController extends AppController class EncryptionKeysController extends AppController
{ {
public function index($owner_type = null, $owner_id = null) public function index()
{ {
$params = $this->_harvestParams($this->request, ['owner_type', 'owner_id']);
$query = $this->EncryptionKeys->find(); $query = $this->EncryptionKeys->find();
if (!empty($owner_type)) { if (!empty($params['owner_type'])) {
$query->where(['owner_type' => $owner_type]); $query->where(['owner_type' => $params['owner_type']]);
} }
if (!empty($owner_id)) { if (!empty($params['owner_id'])) {
$query->where(['owner_id' => $owner_id]); $query->where(['owner_id' => $params['owner_id']]);
} }
$query->contain(['Individuals', 'Organisations']);
if ($this->_isRest()) { if ($this->_isRest()) {
$alignments = $query->all(); $alignments = $query->all();
return $this->RestResponse->viewData($alignments, 'json'); return $this->RestResponse->viewData($alignments, 'json');
@ -37,15 +39,15 @@ class EncryptionKeysController extends AppController
public function delete($id) public function delete($id)
{ {
if (empty($id)) { if (empty($id)) {
throw new NotFoundException(__('Invalid encrpyion keys.')); throw new NotFoundException(__('Invalid encryption key.'));
} }
$individual = $this->Alignments->get($id); $key = $this->EncryptionKeys->get($id);
if ($this->request->is('post') || $this->request->is('delete')) { if ($this->request->is('post') || $this->request->is('delete')) {
if ($this->Alignments->delete($individual)) { if ($this->EncryptionKey->delete($individual)) {
$message = __('Individual deleted.'); $message = __('Encryption key deleted.');
if ($this->_isRest()) { if ($this->_isRest()) {
$individual = $this->Alignments->get($id); $individual = $this->EncryptionKeys->get($id);
return $this->RestResponse->saveSuccessResponse('Alignments', 'delete', $id, 'json', $message); return $this->RestResponse->saveSuccessResponse('EncryptionKeys', 'delete', $id, 'json', $message);
} else { } else {
$this->Flash->success($message); $this->Flash->success($message);
return $this->redirect($this->referer()); return $this->redirect($this->referer());
@ -53,41 +55,50 @@ class EncryptionKeysController extends AppController
} }
} }
$this->set('metaGroup', 'ContactDB'); $this->set('metaGroup', 'ContactDB');
$this->set('scope', 'alignments'); $this->set('scope', 'encryptionKeys');
$this->set('id', $individual['id']); $this->set('id', $key['id']);
$this->set('alignment', $individual); $this->set('key', $key);
$this->viewBuilder()->setLayout('ajax'); $this->viewBuilder()->setLayout('ajax');
$this->render('/genericTemplates/delete'); $this->render('/genericTemplates/delete');
} }
public function add($owner_type = false, $owner_id = false) public function add()
{ {
if (empty($owner_type) && !empty($this->request->getData('owner_type'))) { $params = $this->_harvestParams($this->request, ['owner_type', 'owner_id', 'organisation_id', 'individual_id', 'encryption_key', 'expires', 'uuid', 'revoked', 'type']);
$owner_type = $this->request->getData('owner_type'); $input = $this->request->getData();
}
if (empty($owner_id) && !empty($this->request->getData('owner_id'))) {
$owner_id = $this->request->getData('owner_id');
}
if (empty($owner_type) || empty($owner_id)) {
throw new NotAcceptableException(__('Invalid input. owner_type and owner_id expected as parameters in the format /encryption_keys/add/[owner_type]/[owner_id] or passed as a JSON.'));
}
if ($owner_type === 'individual') {
$this->loadModel('Individuals');
$owner = $this->Individuals->find()->where(['id' => $owner_id])->first();
if (empty($owner)) {
throw new NotFoundException(__('Invalid owner individual.'));
}
} else {
$this->loadModel('Organisations');
$owner = $this->Organisations->find()->where(['id' => $owner_id])->first();
if (empty($owner)) {
throw new NotFoundException(__('Invalid owner individual.'));
}
}
$encryptionKey = $this->EncryptionKeys->newEmptyEntity(); $encryptionKey = $this->EncryptionKeys->newEmptyEntity();
if (!empty($params['owner_type'])) {
if (!empty($params[$params['owner_type'] . '_id'])) {
$params['owner_id'] = $params[$params['owner_type'] . '_id'];
}
$params[$params['owner_type'] . '_id'] = $params['owner_id'];
}
$this->loadModel('Organisations');
$this->loadModel('Individuals');
$dropdownData = [
'organisation' => $this->Organisations->find('list', [
'sort' => ['name' => 'asc']
]),
'individual' => $this->Individuals->find('list', [
'sort' => ['email' => 'asc']
])
];
if ($this->request->is('post')) { if ($this->request->is('post')) {
$this->EncryptionKeys->patchEntity($encryptionKey, $this->request->getData()); if (empty($params['owner_type']) || empty($params['owner_id'])) {
$encrypionKey['owner_type'] = $owner_type; throw new NotAcceptableException(__('Invalid input. owner_type and owner_id expected as parameters in the format /encryption_keys/add/[owner_type]/[owner_id] or passed as a JSON.'));
}
if ($params['owner_type'] === 'individual') {
$owner = $this->Individuals->find()->where(['id' => $params['owner_id']])->first();
if (empty($owner)) {
throw new NotFoundException(__('Invalid owner individual.'));
}
} else {
$owner = $this->Organisations->find()->where(['id' => $params['owner_id']])->first();
if (empty($owner)) {
throw new NotFoundException(__('Invalid owner organisation.'));
}
}
$encryptionKey = $this->EncryptionKeys->patchEntity($encryptionKey, $params);
if ($this->EncryptionKeys->save($encryptionKey)) { if ($this->EncryptionKeys->save($encryptionKey)) {
$message = __('EncryptionKey added.'); $message = __('EncryptionKey added.');
if ($this->_isRest()) { if ($this->_isRest()) {
@ -95,7 +106,7 @@ class EncryptionKeysController extends AppController
return $this->RestResponse->viewData($encryptionKey, 'json'); return $this->RestResponse->viewData($encryptionKey, 'json');
} else { } else {
$this->Flash->success($message); $this->Flash->success($message);
$this->redirect($this->referer()); return $this->redirect(['action' => 'index']);
} }
} else { } else {
$message = __('EncryptionKey could not be added.'); $message = __('EncryptionKey could not be added.');
@ -107,11 +118,8 @@ class EncryptionKeysController extends AppController
} }
} }
} }
$this->set('encryptionKey', $encryptionKey);
$this->set(compact('owner')); $this->set(compact('dropdownData'));
$this->set(compact('encryptionKey'));
$this->set(compact('owner_id'));
$this->set(compact('owner_type'));
$this->set('metaGroup', 'ContactDB'); $this->set('metaGroup', 'ContactDB');
} }
} }

View File

@ -25,6 +25,7 @@ class EncryptionKeysTable extends AppTable
'conditions' => ['owner_type' => 'organisation'] 'conditions' => ['owner_type' => 'organisation']
] ]
); );
$this->setDisplayField('encryption_key');
} }
public function validationDefault(Validator $validator): Validator public function validationDefault(Validator $validator): Validator

View File

@ -11,7 +11,13 @@ class IndividualsTable extends AppTable
public function initialize(array $config): void public function initialize(array $config): void
{ {
parent::initialize($config); parent::initialize($config);
$this->hasMany('Alignments'); $this->hasMany(
'Alignments',
[
'dependent' => true,
'cascadeCallbacks' => true
]
);
$this->hasMany( $this->hasMany(
'EncryptionKeys', 'EncryptionKeys',
[ [
@ -19,6 +25,7 @@ class IndividualsTable extends AppTable
'conditions' => ['owner_type' => 'individual'] 'conditions' => ['owner_type' => 'individual']
] ]
); );
$this->setDisplayField('email');
} }
public function validationDefault(Validator $validator): Validator public function validationDefault(Validator $validator): Validator

View File

@ -11,7 +11,13 @@ class OrganisationsTable extends AppTable
public function initialize(array $config): void public function initialize(array $config): void
{ {
parent::initialize($config); parent::initialize($config);
$this->hasMany('Alignments'); $this->hasMany(
'Alignments',
[
'dependent' => true,
'cascadeCallbacks' => true
]
);
$this->hasMany( $this->hasMany(
'EncryptionKeys', 'EncryptionKeys',
[ [
@ -19,6 +25,7 @@ class OrganisationsTable extends AppTable
'conditions' => ['owner_type' => 'organisation'] 'conditions' => ['owner_type' => 'organisation']
] ]
); );
$this->setDisplayField('name');
} }
public function validationDefault(Validator $validator): Validator public function validationDefault(Validator $validator): Validator

View File

@ -40,6 +40,7 @@ class AppView extends View
{ {
parent::initialize(); parent::initialize();
$this->loadHelper('Hash'); $this->loadHelper('Hash');
$this->loadHelper('FormFieldMassage');
$this->loadHelper('Paginator', ['templates' => 'cerebrate-pagination-templates']); $this->loadHelper('Paginator', ['templates' => 'cerebrate-pagination-templates']);
} }
} }

View File

@ -0,0 +1,22 @@
<?php
namespace App\View\Helper;
use Cake\View\Helper;
class FormFieldMassageHelper extends Helper
{
public function prepareFormElement(\Cake\View\Helper\FormHelper $form, array $controlParams, array $fieldData): string
{
if (!empty($fieldData['stateDependence'])) {
$controlParams['data-dependence-source'] = h($fieldData['stateDependence']['source']);
$controlParams['data-dependence-option'] = h($fieldData['stateDependence']['option']);
}
$controlParams['id'] = $fieldData['field'] . '-field';
$formFieldElement = $form->control($fieldData['field'], $controlParams);
if (!empty($fieldData['hidden'])) {
$formFieldElement = '<span class="hidden">' . $formFieldElement . '</span>';
}
return $formFieldElement;
}
}

View File

@ -4,17 +4,44 @@ echo $this->element('genericElements/Form/genericForm', array(
'form' => $this->Form, 'form' => $this->Form,
'data' => array( 'data' => array(
'entity' => $encryptionKey, 'entity' => $encryptionKey,
'title' => __('Add new encryption key for {0} #{1} ({2})', h($owner_type), h($owner_id), h($owner[$primaryIdentifiers[$owner_type]])), 'title' => __('Add new encryption key'),
'description' => __('Alignments indicate that an individual belongs to an organisation in one way or another. The type of relationship is defined by the type field.'), 'description' => __('Alignments indicate that an individual belongs to an organisation in one way or another. The type of relationship is defined by the type field.'),
'model' => 'Organisations', 'model' => 'Organisations',
'fields' => array( 'fields' => array(
array(
'field' => 'owner_type',
'label' => __('Owner type'),
'options' => array_combine(array_keys($dropdownData), array_keys($dropdownData)),
'type' => 'dropdown'
),
array(
'field' => 'organisation_id',
'label' => __('Owner organisation'),
'options' => $dropdownData['organisation'],
'type' => 'dropdown',
'stateDependence' => [
'source' => '#owner_type-field',
'option' => 'organisation'
]
),
array(
'field' => 'individual_id',
'label' => __('Owner individual'),
'options' => $dropdownData['individual'],
'type' => 'dropdown',
'stateDependence' => [
'source' => '#owner_type-field',
'option' => 'individual'
]
),
array( array(
'field' => 'uuid', 'field' => 'uuid',
'type' => 'uuid' 'type' => 'uuid'
), ),
array( array(
'field' => 'type', 'field' => 'type',
'options' => array('pgp' => 'PGP', 'smime' => 'S/MIME') 'options' => array('pgp' => 'PGP', 'smime' => 'S/MIME'),
'type' => 'dropdown'
), ),
array( array(
'field' => 'encryption_key', 'field' => 'encryption_key',

View File

@ -0,0 +1,89 @@
<?php
echo $this->element('genericElements/IndexTable/index_table', [
'data' => [
'row_modifier' => function(App\Model\Entity\EncryptionKey $row): string {
return !empty($row['revoked']) ? 'text-light bg-secondary' : '';
},
'data' => $data,
'top_bar' => [
'pull' => 'right',
'children' => [
[
'type' => 'simple',
'children' => [
'data' => [
'type' => 'simple',
'text' => __('Add encryption key'),
'class' => 'btn btn-primary',
'popover_url' => '/encryptionKeys/add'
]
]
],
[
'type' => 'search',
'button' => __('Filter'),
'placeholder' => __('Enter value to search'),
'data' => '',
'searchKey' => 'value'
]
]
],
'fields' => [
[
'name' => '#',
'sort' => 'id',
'data_path' => 'id',
],
[
'name' => __('Owner type'),
'sort' => 'owner_type',
'data_path' => 'owner_type',
],
[
'name' => __('Owner ID'),
'sort' => 'owner_id',
'data_path' => 'owner_id',
],
[
'name' => __('Owner'),
'data_path' => 'owner_id',
'owner_type_path' => 'owner_type',
'element' => 'owner'
],
[
'name' => __('Revoked'),
'sort' => 'revoked',
'data_path' => 'revoked',
'element' => 'boolean'
],
[
'name' => __('Expires'),
'sort' => 'expires',
'data_path' => 'expires',
'element' => 'timestamp'
],
[
'name' => __('Key'),
'data_path' => 'encryption_key',
'privacy' => 1
],
],
'title' => __('Encryption key Index'),
'description' => __('A list encryption / signing keys that are bound to an individual or an organsiation.'),
'pull' => 'right',
'actions' => [
[
'url' => '/endcrpyionKeys/view',
'url_params_data_paths' => ['id'],
'icon' => 'eye'
],
[
'onclick' => 'populateAndLoadModal(\'/encryptionKeys/delete/[onclick_params_data_path]\');',
'onclick_params_data_path' => 'id',
'icon' => 'trash'
]
]
]
]);
echo '</div>';
?>

View File

@ -1,8 +1,4 @@
<?php <?php
$params['div'] = false; $params['div'] = false;
$temp = $form->control($fieldData['field'], $params); echo $this->FormFieldMassage->prepareFormElement($this->Form, $params, $fieldData);
if (!empty($fieldData['hidden'])) {
$temp = '<span class="hidden">' . $temp . '</span>';
}
echo $temp;
?> ?>

View File

@ -0,0 +1,6 @@
<?php
$controlParams = [
'options' => $fieldData['options'],
'class' => ($fieldData['class'] ?? '') . ' formDropdown custom-select'
];
echo $this->FormFieldMassage->prepareFormElement($this->Form, $controlParams, $fieldData);

View File

@ -1,9 +1,5 @@
<?php <?php
$params['div'] = false; $params['div'] = false;
$params['class'] .= ' form-control'; $params['class'] .= ' form-control';
$temp = $form->control($fieldData['field'], $params); echo $this->FormFieldMassage->prepareFormElement($this->Form, $params, $fieldData);
if (!empty($fieldData['hidden'])) {
$temp = '<span class="hidden">' . $temp . '</span>';
}
echo $temp;
?> ?>

View File

@ -7,6 +7,7 @@
'formGroup' => '{{input}}', 'formGroup' => '{{input}}',
]); ]);
$label = $fieldData['label']; $label = $fieldData['label'];
$formElement = $this->FormFieldMassage->prepareFormElement($this->Form, $params, $fieldData);
$temp = sprintf( $temp = sprintf(
'<div class="form-group row "> '<div class="form-group row ">
<div class="col-sm-2 col-form-label">%s</div> <div class="col-sm-2 col-form-label">%s</div>
@ -17,7 +18,7 @@
</div> </div>
</div>', </div>',
h($label), h($label),
$form->control($fieldData['field'], $params), $formElement,
sprintf( sprintf(
'<span id="uuid-gen-%s" class="btn btn-secondary">%s</span>', '<span id="uuid-gen-%s" class="btn btn-secondary">%s</span>',
$random, $random,
@ -31,7 +32,7 @@
$('#uuid-gen-<?= h($random) ?>').on('click', function() { $('#uuid-gen-<?= h($random) ?>').on('click', function() {
$.ajax({ $.ajax({
success:function (data, textStatus) { success:function (data, textStatus) {
$('#uuid').val(data["uuid"]); $('#uuid-field').val(data["uuid"]);
}, },
type: "get", type: "get",
cache: false, cache: false,

View File

@ -17,7 +17,7 @@
h($data['model']); h($data['model']);
$fieldsString = ''; $fieldsString = '';
$simpleFieldWhitelist = array( $simpleFieldWhitelist = array(
'default', 'type', 'options', 'placeholder', 'label', 'empty', 'rows', 'div', 'required' 'default', 'type', 'placeholder', 'label', 'empty', 'rows', 'div', 'required'
); );
$fieldsArrayForPersistence = array(); $fieldsArrayForPersistence = array();
if (empty($data['url'])) { if (empty($data['url'])) {
@ -34,7 +34,7 @@
'select' => '<select name="{{name}}" {{attrs}}>{{content}}</select>', 'select' => '<select name="{{name}}" {{attrs}}>{{content}}</select>',
'checkbox' => '<input type="checkbox" name="{{name}}" value="{{value}}"{{attrs}}>', 'checkbox' => '<input type="checkbox" name="{{name}}" value="{{value}}"{{attrs}}>',
'checkboxFormGroup' => '{{label}}', 'checkboxFormGroup' => '{{label}}',
'checkboxWrapper' => '<div class="checkbox">{{label}}</div>', 'select' => '<select name="{{name}}" {{attrs}}>{{content}}</select>',
'formGroup' => '<div class="col-sm-2 col-form-label" {{attrs}}>{{label}}</div><div class="col-sm-10">{{input}}</div>', 'formGroup' => '<div class="col-sm-2 col-form-label" {{attrs}}>{{label}}</div><div class="col-sm-10">{{input}}</div>',
'nestingLabel' => '{{hidden}}<div class="col-sm-2 col-form-label">{{text}}</div><div class="col-sm-10">{{input}}</div>', 'nestingLabel' => '{{hidden}}<div class="col-sm-2 col-form-label">{{text}}</div><div class="col-sm-10">{{input}}</div>',
]; ];
@ -80,15 +80,14 @@
$params['class'] .= ' form-control'; $params['class'] .= ' form-control';
} }
//$params['class'] = sprintf('form-control %s', $params['class']); //$params['class'] = sprintf('form-control %s', $params['class']);
foreach ($simpleFieldWhitelist as $f) { foreach ($fieldData as $k => $fd) {
if (!empty($fieldData[$f])) { if (in_array($k, $simpleFieldWhitelist) || strpos($k, 'data-') === 0) {
$params[$f] = $fieldData[$f]; $params[$k] = $fd;
} }
} }
$temp = $this->element('genericElements/Form/Fields/' . $fieldTemplate, array( $temp = $this->element('genericElements/Form/Fields/' . $fieldTemplate, array(
'fieldData' => $fieldData, 'fieldData' => $fieldData,
'params' => $params, 'params' => $params
'form' => $this->Form
)); ));
if (!empty($fieldData['hidden'])) { if (!empty($fieldData['hidden'])) {
$temp = '<span class="hidden">' . $temp . '</span>'; $temp = '<span class="hidden">' . $temp . '</span>';
@ -158,3 +157,11 @@
); );
} }
?> ?>
<script type="text/javascript">
$(document).ready(function() {
executeStateDependencyChecks();
$('.formDropdown').on('change', function() {
executeStateDependencyChecks('#' + this.id);
})
});
</script>

View File

@ -82,7 +82,7 @@
} }
echo sprintf( echo sprintf(
'<a href="%s" title="%s" aria-label="%s" %s %s><i class="black %s"></i></a> ', '<a href="%s" title="%s" aria-label="%s" %s %s class="link-unstyled"><i class="%s"></i></a> ',
$url, $url,
empty($action['title']) ? '' : h($action['title']), empty($action['title']) ? '' : h($action['title']),
empty($action['title']) ? '' : h($action['title']), empty($action['title']) ? '' : h($action['title']),

View File

@ -0,0 +1,32 @@
<?php
$type = $this->Hash->extract($row, $field['owner_type_path'])[0];
$owner = $row[$type];
$types = [
'individual' => [
'uri' => 'individuals',
'name' => __('Individual'),
'identityField' => 'email'
],
'organisation' => [
'uri' => 'organisations',
'name' => __('Organisation'),
'identityField' => 'name'
]
];
echo sprintf(
'<span class="font-weight-bold">%s</span>: %s',
$types[$type]['name'],
$this->Html->link(
sprintf(
'(%s) %s',
h($owner['id']),
h($owner[$types[$type]['identityField']])
),
['controller' => $types[$type]['uri'], 'action' => 'view', $owner['id']],
[
'class' => 'link-unstyled'
]
)
);
?>

View File

@ -1,7 +1,9 @@
<?php <?php
$timestamp = $this->Hash->extract($row, $field['data_path'])[0]; if (!empty($this->Hash->extract($row, $field['data_path']))) {
if (!empty($field['time_format'])) { $timestamp = $this->Hash->extract($row, $field['data_path'])[0];
$timestamp = date($field['time_format'], $timestamp); if (!empty($field['time_format'])) {
$timestamp = date($field['time_format'], $timestamp);
}
echo h($timestamp);
} }
echo h($timestamp);
?> ?>

View File

@ -68,10 +68,12 @@
$dbclickAction = sprintf("changeLocationFromIndexDblclick(%s)", $k); $dbclickAction = sprintf("changeLocationFromIndexDblclick(%s)", $k);
} }
$rows .= sprintf( $rows .= sprintf(
'<tr data-row-id="%s" %s %s>%s</tr>', '<tr data-row-id="%s" %s %s class="%s %s">%s</tr>',
h($k), h($k),
empty($dbclickAction) ? '' : 'ondblclick="' . $dbclickAction . '"', empty($dbclickAction) ? '' : 'ondblclick="' . $dbclickAction . '"',
empty($primary) ? '' : 'data-primary-id="' . $primary . '"', empty($primary) ? '' : 'data-primary-id="' . $primary . '"',
empty($data['row_modifier']) ? '' : h($data['row_modifier']($data_row)),
empty($data['class']) ? '' : h($data['row_class']),
$this->element( $this->element(
'/genericElements/IndexTable/' . $row_element, '/genericElements/IndexTable/' . $row_element,
array( array(

View File

@ -25,7 +25,8 @@
'data_path' => empty($field['data_path']) ? '' : $field['data_path'], 'data_path' => empty($field['data_path']) ? '' : $field['data_path'],
'k' => $k, 'k' => $k,
'primary' => $primary, 'primary' => $primary,
'tableRandomValue' => $tableRandomValue 'tableRandomValue' => $tableRandomValue,
'stateDependence' => isset($field['stateDependence']) ? $field['stateDependence'] : []
) )
); );
} }

View File

@ -1,6 +1,12 @@
<?php <?php
if (!isset($data['requirement']) || $data['requirement']) { if (!isset($data['requirement']) || $data['requirement']) {
if (!empty($data['onClick']) || empty($data['url'])) { if (!empty($data['popover_url'])) {
$onClick = sprintf(
'onClick="populateAndLoadModal(%s)"',
sprintf("'%s'", h($data['popover_url']))
);
}
if (empty($onClick) && (!empty($data['onClick']) || empty($data['url']))) {
$onClickParams = array(); $onClickParams = array();
if (!empty($data['onClickParams'])) { if (!empty($data['onClickParams'])) {
foreach ($data['onClickParams'] as $param) { foreach ($data['onClickParams'] as $param) {
@ -34,7 +40,7 @@
} }
$dataFields = implode(' ', $dataFields); $dataFields = implode(' ', $dataFields);
echo sprintf( echo sprintf(
'<a class="btn btn-small %s %s" %s href="%s" %s %s %s %s %s>%s%s%s</a>', '<button class="btn btn-small %s %s" %s href="%s" %s %s %s %s %s>%s%s%s</button>',
empty($data['class']) ? '' : h($data['class']), empty($data['class']) ? '' : h($data['class']),
empty($data['active']) ? 'btn-inverse' : 'btn-primary', // Change the default class for highlighted/active toggles here empty($data['active']) ? 'btn-inverse' : 'btn-primary', // Change the default class for highlighted/active toggles here
empty($data['id']) ? '' : 'id="' . h($data['id']) . '"', empty($data['id']) ? '' : 'id="' . h($data['id']) . '"',

View File

@ -138,7 +138,7 @@
); );
echo sprintf( echo sprintf(
'<nav class="navbar navbar-expand-lg navbar-dark fixed-top bg-dark">%s%s%s</nav>', '<nav class="navbar navbar-expand-lg navbar-dark bg-dark">%s%s%s</nav>',
$homeButton, $homeButton,
'<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation"><span class="navbar-toggler-icon"></span></button>', '<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation"><span class="navbar-toggler-icon"></span></button>',
$navdata $navdata

View File

@ -43,7 +43,7 @@ $cakeDescription = 'Cerebrate';
<?= $this->element('genericElements/header') ?> <?= $this->element('genericElements/header') ?>
</header> </header>
<main role="main" class="container-fluid"> <main role="main" class="container-fluid">
<div class="container-fluid" style="padding:0px;padding-top:70px;"> <div class="container-fluid">
<div class="row"> <div class="row">
<div class="col-md-2 d-none d-md-block col-lg-1 bg-light sidebar" style="padding:0px;margin:0px;"> <div class="col-md-2 d-none d-md-block col-lg-1 bg-light sidebar" style="padding:0px;margin:0px;">
<?= $this->element('/genericElements/SideMenu/side_menu') ?> <?= $this->element('/genericElements/SideMenu/side_menu') ?>

View File

@ -109,3 +109,8 @@
.text-black {color:black;} .text-black {color:black;}
.text-white {color:white;} .text-white {color:white;}
.link-unstyled, .link-unstyled:link, .link-unstyled:hover {
color: inherit;
text-decoration: inherit;
}

View File

@ -21,3 +21,19 @@ function executePagination(randomValue, url) {
url:url, url:url,
}); });
} }
function executeStateDependencyChecks(dependenceSourceSelector) {
if (dependenceSourceSelector === undefined) {
var tempSelector = "[data-dependence-source]";
} else {
var tempSelector = '*[data-dependence-source="' + dependenceSourceSelector + '"]';
}
$(tempSelector).each(function(index, dependent) {
var dependenceSource = $(dependent).data('dependence-source');
if ($(dependent).data('dependence-option') === $(dependenceSource).val()) {
$(dependent).parent().parent().removeClass('d-none');
} else {
$(dependent).parent().parent().addClass('d-none');
}
});
}