Skip to content

Commit

Permalink
CFM-274_breadcrumbs_sqlsource_flanges (#340)
Browse files Browse the repository at this point in the history
* SqlSource display field

* Deep Server models breadcrumbs
  • Loading branch information
Ioannis authored Sep 17, 2025
1 parent 4972cbd commit 3a7a27e
Show file tree
Hide file tree
Showing 12 changed files with 282 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
msgid "controller.SqlProvisioners"
msgstr "{0,plural,=1{SQL Provisioner} other{SQL Provisioners}}"

msgid "display.SqlSource"
msgstr "{0} Source"

msgid "enumeration.SqlSourceTableModeEnum.FL"
msgstr "Flat"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class SqlSourcesTable extends Table {
use \App\Lib\Traits\LabeledLogTrait;
use \App\Lib\Traits\PermissionsTrait;
use \App\Lib\Traits\PrimaryLinkTrait;
use \App\Lib\Traits\QueryModificationTrait;
use \App\Lib\Traits\TabTrait;
use \App\Lib\Traits\TableMetaTrait;
use \App\Lib\Traits\ValidationTrait;
Expand Down Expand Up @@ -106,6 +107,16 @@ public function initialize(array $config): void {

$this->setPrimaryLink(['external_identity_source_id']);
$this->setRequiresCO(true);

$this->setEditContains([
'Servers' => ['SqlServers'],
'ExternalIdentitySources',
]);

$this->setViewContains([
'Servers' => ['SqlServers'],
'ExternalIdentitySources',
]);

$this->setAutoViewVars([
'addressTypes' => [
Expand Down Expand Up @@ -230,6 +241,18 @@ protected function getChanges(
return false;
}

/**
* Table specific logic to generate a display field.
*
* @since COmanage Registry v5.2.0
* @param \SqlConnector\Model\Entity\SqlSource $entity Entity to generate display field for
* @return string Display field
*/
public function generateDisplayField(\SqlConnector\Model\Entity\SqlSource $entity): string {
return __d('sql_connector', 'display.SqlSource', [$entity->external_identity_source->description]);
}


/**
* Obtain the set of changed records from the source database.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,44 @@
namespace CoreServer\Controller;

use App\Controller\StandardPluginController;
use App\Lib\Util\StringUtilities;
use Cake\Event\EventInterface;

class MatchServerAttributesController extends StandardPluginController {
use \App\Lib\Traits\BreadcrumbsTrait;

protected array $paginate = [
'order' => [
'MatchServerAttributes.attribute' => 'asc'
]
];

/**
* Callback run prior to the request render.
*
* @since COmanage Registry v5.2.0
* @param EventInterface $event Cake Event
* @return \Cake\Http\Response HTTP Response
*/

public function beforeRender(\Cake\Event\EventInterface $event)
{
// Build standard server breadcrumbs from *_server_id
$customParents = $this->buildServerParamBreadcrumbs();

if (!empty($customParents)) {
$vv_bc_parents = (array)$this->viewBuilder()->getVar('vv_bc_parents');
$vv_bc_parents = [...$customParents, ...$vv_bc_parents];
$this->set('vv_bc_parents', $vv_bc_parents);
}

$title = __d('core_server', 'controller.MatchServerAttributes', [99]);
if(in_array($this->request->getParam('action'), ['add', 'edit'])) {
$title = __d('operation', strtolower($this->request->getParam('action')) . '.a', [$title]);
}

$this->set('vv_title', $title);

return parent::beforeRender($event);
}
}
3 changes: 3 additions & 0 deletions app/plugins/EnvSource/resources/locales/en_US/env_source.po
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ msgstr "{0,plural,=1{Env Source} other{Env Sources}}"
msgid "controller.PetitionEnvIdentities"
msgstr "{0,plural,=1{Petition Env Identity} other{Petition Env Identities}}"

msgid "display.EnvSource"
msgstr "{0} Source"

msgid "enumeration.EnvSourceSpModeEnum.O"
msgstr "Other"

Expand Down
20 changes: 20 additions & 0 deletions app/plugins/EnvSource/src/Model/Table/EnvSourcesTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class EnvSourcesTable extends Table {
use \App\Lib\Traits\LabeledLogTrait;
use \App\Lib\Traits\PermissionsTrait;
use \App\Lib\Traits\PrimaryLinkTrait;
use \App\Lib\Traits\QueryModificationTrait;
use \App\Lib\Traits\TabTrait;
use \App\Lib\Traits\TableMetaTrait;
use \App\Lib\Traits\ValidationTrait;
Expand Down Expand Up @@ -97,6 +98,14 @@ public function initialize(array $config): void {
$this->setPrimaryLink(['external_identity_source_id']);
$this->setRequiresCO(true);

$this->setEditContains([
'ExternalIdentitySources',
]);

$this->setViewContains([
'ExternalIdentitySources',
]);

// All the tabs share the same configuration in the ModelTable file
$this->setTabsConfig(
[
Expand Down Expand Up @@ -156,6 +165,17 @@ public function initialize(array $config): void {
]);
}

/**
* Table specific logic to generate a display field.
*
* @since COmanage Registry v5.2.0
* @param \EnvSource\Model\Entity\EnvSource $entity Entity to generate display field for
* @return string Display field
*/
public function generateDisplayField(\EnvSource\Model\Entity\EnvSource $entity): string {
return __d('env_source', 'display.EnvSource', [$entity->external_identity_source->description]);
}

/**
* Obtain the set of changed records from the source database.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

namespace SshKeyAuthenticator\Controller;

use Cake\Event\EventInterface;
use Cake\ORM\TableRegistry;
use App\Controller\MultipleAuthenticatorController;
use App\Lib\Util\StringUtilities;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class SshKeyAuthenticatorsTable extends Table {
use \App\Lib\Traits\LabeledLogTrait;
use \App\Lib\Traits\PermissionsTrait;
use \App\Lib\Traits\PrimaryLinkTrait;
use \App\Lib\Traits\QueryModificationTrait;
use \App\Lib\Traits\TableMetaTrait;
use \App\Lib\Traits\ValidationTrait;

Expand Down Expand Up @@ -74,6 +75,14 @@ public function initialize(array $config): void {
$this->setPrimaryLink('authenticator_id');
$this->setRequiresCO(true);

$this->setEditContains([
'Authenticators',
]);

$this->setViewContains([
'Authenticators',
]);

$this->setPermissions([
// Actions that operate over an entity (ie: require an $id)
'entity' => [
Expand All @@ -89,6 +98,17 @@ public function initialize(array $config): void {
]);
}

/**
* Table specific logic to generate a display field.
*
* @since COmanage Registry v5.2.0
* @param \SshKeyAuthenticator\Model\Entity\SshKeyAuthenticator $entity Entity to generate display field for
* @return string Display field
*/
public function generateDisplayField(\SshKeyAuthenticator\Model\Entity\SshKeyAuthenticator $entity): string {
return $entity->authenticator->description;
}

/**
* Set validation rules.
*
Expand Down
48 changes: 29 additions & 19 deletions app/src/Controller/Component/BreadcrumbComponent.php
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,8 @@ public function injectPrimaryLink(object $link, bool $index = true, string $link
);

return $canEdit ? 'edit' : ($canView ? 'view' : '');
}
},
forChainItem: true
);

$linkTable = \Cake\ORM\TableRegistry::getTableLocator()->get($linkModelFqn);
Expand All @@ -249,11 +250,10 @@ public function injectPrimaryLink(object $link, bool $index = true, string $link
if ($index && method_exists($linkTable, 'findPrimaryLink')) {
$parentLink = $linkTable->findPrimaryLink($linkedEntity->id);

// https://comanage-ioi-dev.workbench.incommon.org/registry-pe/authenticators?co_id=2
$this->injectParents[strtolower($linkModelFqn) . ':index'] = [
'target' => [
'plugin' => $parentLink->plugin ?? null,
'controller' => $linkModelFqn,
'plugin' => $parentLink->plugin ?? StringUtilities::blankToNull(StringUtilities::pluginPlugin($linkModelFqn)) ?? null,
'controller' => StringUtilities::pluginModel($linkModelFqn),
'action' => 'index',
'?' => [
$parentLink->attr => $parentLink->value
Expand Down Expand Up @@ -283,9 +283,9 @@ public function injectPrimaryLink(object $link, bool $index = true, string $link
// Inject the entity breadcrumb (unique per table:id)
$this->injectParents[$this->composeEntityKey($linkTable->getTable(), (int)$linkedEntity->id)] = [
'target' => [
'plugin' => $link->plugin ?? null,
'controller' => $linkModelFqn,
'action' => $breadcrumbAction,
'plugin' => $parentLink->plugin ?? StringUtilities::blankToNull(StringUtilities::pluginPlugin($linkModelFqn)) ?? null,
'controller' => StringUtilities::pluginModel($linkModelFqn),
'action' => $breadcrumbAction,
(int)$linkedEntity->id
],
'label' => $linkLabel ?? $title,
Expand Down Expand Up @@ -391,30 +391,38 @@ private function resolveContainList($table, string $mappedAction): array
* @param int|null $currentId Current entity ID
* @param array $pagePermissions Permissions for the current page
* @param callable $peopleActionOverride Override callback for People actions
* @param bool $forChainItem Explicit call for a chain item (e.g. add)
* @return string Mapped action name
* @since COmanage Registry v5.2.0
*/
private function mapActionForBreadcrumb(
string $requestAction,
?int $currentId,
array $pagePermissions,
callable $peopleActionOverride
callable $peopleActionOverride,
bool $forChainItem
): string {
// Custom override for People if provided
$override = $peopleActionOverride();
if ($override !== '') {
return $override;
}

if (in_array($requestAction, ['index', 'view', 'delete', 'add', 'edit'], true)) {
return $requestAction;
}

if ($currentId !== null) {
return (!empty($pagePermissions['edit'])) ? 'edit' : 'view';
if ($forChainItem) {
// Never render 'add' for chain items
if ($requestAction === 'add') {
return 'index';
}
// If the current page is edit/view/delete (and thus has an entity), prefer edit/view
if (in_array($requestAction, ['edit', 'view', 'delete'], true) && $currentId !== null) {
return (!empty($pagePermissions['edit'])) ? 'edit' : 'view';
}
return in_array($requestAction, ['index', 'view', 'delete', 'edit'], true)
? $requestAction
: 'index';
}

return 'index';
// If you ever reuse this for non-chain items, decide appropriate behavior here
return $requestAction;
}

/**
Expand All @@ -427,15 +435,17 @@ private function mapActionForBreadcrumb(
*/
private function determineEntityAction($entity, string $mappedAction): string
{
if ($mappedAction === 'add' || $mappedAction === 'delete') {
return $mappedAction;
// Only allow 'delete' to pass through; never return 'add' for existing entities
if ($mappedAction === 'delete') {
return 'delete';
}

if (method_exists($entity, 'isReadOnly')) {
return $entity->isReadOnly() ? 'view' : 'edit';
}

return $mappedAction;
// Fall back to mapped action when not 'add'/'delete'
return $mappedAction === 'add' ? 'view' : $mappedAction;
}

/**
Expand Down
9 changes: 7 additions & 2 deletions app/src/Controller/StandardPluginController.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,14 @@ public function beforeFilter(\Cake\Event\EventInterface $event) {
$this->Breadcrumb->skipConfig(['/^\//']);
}

// The authenticator routes have a unique patern. We will not inject the Breadcrumb here but
// The authenticator routes have a unique pattern. We will not inject the Breadcrumb here, but
// we will construct it in the MultipleAuthtenticatorController.
if(!str_ends_with($primaryLink->attr, '_authenticator_id')) {
// For very deep breadcrumbs we need to skip the generic rule
// and allow the controller to handle it.
if(
!str_ends_with($primaryLink->attr, '_authenticator_id')
&& !str_ends_with($primaryLink->attr, '_server_id')
) {
$this->Breadcrumb->injectPrimaryLink($primaryLink);
}
}
Expand Down
Loading

0 comments on commit 3a7a27e

Please sign in to comment.