diff --git a/app/availableplugins/PipelineToolkit/src/Model/Table/IdentifierMappersTable.php b/app/availableplugins/PipelineToolkit/src/Model/Table/IdentifierMappersTable.php index 5cb331933..95ea8c9af 100644 --- a/app/availableplugins/PipelineToolkit/src/Model/Table/IdentifierMappersTable.php +++ b/app/availableplugins/PipelineToolkit/src/Model/Table/IdentifierMappersTable.php @@ -38,6 +38,7 @@ class IdentifierMappersTable 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; @@ -68,6 +69,19 @@ public function initialize(array $config): void { $this->setPrimaryLink(['flange_id']); $this->setRequiresCO(true); + $this->setViewContains([ + 'Flanges', + ]); + + $this->setEditContains([ + 'Flanges', + ]); + + // Required for deep Breadcrumb calculations + $this->setIndexContains([ + 'Flanges', + ]); + $this->setPermissions([ // Actions that operate over an entity (ie: require an $id) 'entity' => [ @@ -135,6 +149,17 @@ public function buildRelatedAttributes( return $retdata; } + /** + * Table specific logic to generate a display field. + * + * @since COmanage Registry v5.2.0 + * @param \PipelineToolkit\Model\Entity\IdentifierMapper $entity Entity to generate display field for + * @return string Display field + */ + public function generateDisplayField(\PipelineToolkit\Model\Entity\IdentifierMapper $entity): string { + return $entity->flange->description; + } + /** * Set validation rules. * diff --git a/app/availableplugins/PipelineToolkit/src/Model/Table/LoginIdentifierTypesTable.php b/app/availableplugins/PipelineToolkit/src/Model/Table/LoginIdentifierTypesTable.php index a32eded1d..a207b9587 100644 --- a/app/availableplugins/PipelineToolkit/src/Model/Table/LoginIdentifierTypesTable.php +++ b/app/availableplugins/PipelineToolkit/src/Model/Table/LoginIdentifierTypesTable.php @@ -40,6 +40,7 @@ class LoginIdentifierTypesTable 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; @@ -75,6 +76,14 @@ public function initialize(array $config): void { ] ]); + $this->setViewContains([ + 'IdentifierMappers' => ['Flanges'], + ]); + + $this->setEditContains([ + 'IdentifierMappers' => ['Flanges'], + ]); + $this->setPermissions([ // Actions that operate over an entity (ie: require an $id) 'entity' => [ diff --git a/app/src/Controller/StandardPluginController.php b/app/src/Controller/StandardPluginController.php index 0bab00bc6..5e18af44d 100644 --- a/app/src/Controller/StandardPluginController.php +++ b/app/src/Controller/StandardPluginController.php @@ -37,6 +37,8 @@ use \App\Lib\Enum\SuspendableStatusEnum; class StandardPluginController extends StandardController { + use \App\Lib\Traits\BreadcrumbsTrait; + /** * Callback run prior to the request action. * @@ -111,6 +113,18 @@ public function beforeRender(\Cake\Event\EventInterface $event) { $this->set('vv_title', $title); } + // Check for missing Breadcrumbs + if ($this->viewBuilder()->getVar('vv_obj')) { + // Check if this is a PipelineToolkit Mapper controller + if (str_ends_with($this->getName(), 'Mappers') + && $this->getPlugin() == 'PipelineToolkit') { + $obj = $this->viewBuilder()->getVar('vv_obj'); + $breadcrumbs = $this->buildPipelineBreadcrumbs($obj); + $vv_bc_parents = (array)$this->viewBuilder()->getVar('vv_bc_parents'); + $this->set('vv_bc_parents', [...$breadcrumbs, ...$vv_bc_parents]); + } + } + return parent::beforeRender($event); } diff --git a/app/src/Lib/Traits/BreadcrumbsTrait.php b/app/src/Lib/Traits/BreadcrumbsTrait.php index 2432812da..c0b2d27a7 100644 --- a/app/src/Lib/Traits/BreadcrumbsTrait.php +++ b/app/src/Lib/Traits/BreadcrumbsTrait.php @@ -30,6 +30,7 @@ namespace App\Lib\Traits; use App\Lib\Util\StringUtilities; +use Cake\Datasource\EntityInterface; trait BreadcrumbsTrait { /** @@ -43,6 +44,7 @@ trait BreadcrumbsTrait { * - oauth2_server_id → CoreServer.Oauth2Servers * * @return array Breadcrumb parents to prepend + * @since COmanage Registry v5.2.0 */ protected function buildServerParamBreadcrumbs(): array { @@ -137,6 +139,7 @@ protected function buildServerParamBreadcrumbs(): array * @param int $personId The person ID to build crumbs for. * @param bool $includePeopleIndex Whether to include the People index crumb. * @return array + * @since COmanage Registry v5.2.0 */ protected function buildPersonBreadcrumbs(int $personId, bool $includePeopleIndex = true): array { @@ -179,4 +182,81 @@ protected function buildPersonBreadcrumbs(int $personId, bool $includePeopleInde return $parents; } + + + /** + * Build the pipeline-related breadcrumb parents. + * + * Returns only the parents to prepend (does not overwrite existing `vv_bc_parents`). + * Safely de-duplicates by checking currently set parents. + * + * @param \Cake\Datasource\EntityInterface $entity The entity containing flange information + * @return array Breadcrumb parents to prepend + * @since COmanage Registry v5.2.0 + */ + protected function buildPipelineBreadcrumbs(EntityInterface $entity): array + { + // 1) Get the flange id + $flangeId = $entity->get('flange')->id + ?? $entity->get('flange_id') + ?? null; + + if (!$flangeId) { + return []; + } + + $coId = method_exists($this, 'getCOID') ? (int)$this->getCOID() : 0; + + try { + // 2) Get the Flange to obtain pipeline_id + $Flanges = $this->fetchTable('Flanges'); + $flange = $Flanges->get($flangeId); + $pipelineId = (int)($flange->pipeline_id ?? 0); + + if ($pipelineId <= 0) { + return []; + } + + $vv_bc_parents = (array)$this->viewBuilder()->getVar('vv_bc_parents'); + $parents = []; + + // 3) Pipelines index + $pipelinesIndexKey = 'pipelines:' . $coId; + if ($coId > 0 && empty($vv_bc_parents[$pipelinesIndexKey])) { + $parents[$pipelinesIndexKey] = [ + 'label' => __('Pipelines'), + 'target' => [ + 'plugin' => null, + 'controller' => 'Pipelines', + 'action' => 'index', + '?' => ['co_id' => $coId], + ], + ]; + } + + // 4) Current Pipeline + $Pipelines = $this->fetchTable('Pipelines'); + $pipeline = $Pipelines->get($pipelineId); + $pipelineKey = 'pipelines:' . $pipelineId; + + if (empty($vv_bc_parents[$pipelineKey])) { + $parents[$pipelineKey] = [ + 'label' => method_exists($Pipelines, 'generateDisplayField') + ? $Pipelines->generateDisplayField($pipeline) + : ($pipeline->{$Pipelines->getDisplayField()} ?? ('Pipeline #' . $pipelineId)), + 'target' => [ + 'plugin' => null, + 'controller' => 'Pipelines', + 'action' => 'edit', + $pipelineId, + ], + ]; + } + } catch (\Throwable $e) { + // Fail-soft: no pipeline → no crumbs + return []; + } + + return $parents; + } } \ No newline at end of file