diff --git a/app/plugins/Transmogrify/config/schema/tables.json b/app/plugins/Transmogrify/config/schema/tables.json index 294f4ffe..d4103fba 100644 --- a/app/plugins/Transmogrify/config/schema/tables.json +++ b/app/plugins/Transmogrify/config/schema/tables.json @@ -574,5 +574,22 @@ "co_enrollment_flow_id": null, "co_pipeline_id": "pipeline_id" } + }, + "external_identity_sources": { + "source": "cm_org_identity_sources", + "displayField": "description", + "booleans": ["hash_source_record"], + "cache": ["co_id"], + "fieldMap": { + "plugin": "&mapExternalIdentitySourcePlugin", + "co_pipeline_id": "pipeline_id", + "sync_mode": null, + "sync_query_mismatch_mode": null, + "sync_query_skip_known": null, + "sync_on_user_login": null, + "eppn_identifier_type": null, + "eppn_suffix": null, + "org_identity_source_id": "external_identity_source_id" + } } } diff --git a/app/plugins/Transmogrify/src/Command/TransmogrifyCommand.php b/app/plugins/Transmogrify/src/Command/TransmogrifyCommand.php index 35e9965d..acc1cfc4 100644 --- a/app/plugins/Transmogrify/src/Command/TransmogrifyCommand.php +++ b/app/plugins/Transmogrify/src/Command/TransmogrifyCommand.php @@ -451,6 +451,9 @@ public function execute(Arguments $args, ConsoleIo $io): int } catch(\Exception $e) { $this->cache['error'] += 1; + if (isset($row['id'])) { + $this->cache['rejected'][$outboundQualifiedTableName][$row['id']] = $row; + } $rowIdLabel = $row['id'] ?? ($this->tables[$t]['displayField'] ?? 'n/a'); $this->cmdPrinter->error("$t record " . (string)$rowIdLabel . ": " . $e->getMessage()); $this->cmdPrinter->pause(); diff --git a/app/plugins/Transmogrify/src/Lib/Traits/TypeMapperTrait.php b/app/plugins/Transmogrify/src/Lib/Traits/TypeMapperTrait.php index a65a7ded..47b15b49 100644 --- a/app/plugins/Transmogrify/src/Lib/Traits/TypeMapperTrait.php +++ b/app/plugins/Transmogrify/src/Lib/Traits/TypeMapperTrait.php @@ -30,6 +30,7 @@ namespace Transmogrify\Lib\Traits; use App\Lib\Enum\PetitionStatusEnum; +use Cake\ORM\TableRegistry; use Doctrine\DBAL\Exception; use Doctrine\DBAL\Exception\UniqueConstraintViolationException; use Transmogrify\Lib\Util\RawSqlQueries; @@ -38,7 +39,7 @@ /** * Encapsulates all type mapping logic and helpers (map_type + specific wrappers). * - * @since COmanage Registry v5.0.0 + * @since COmanage Registry v5.2.0 */ trait TypeMapperTrait { @@ -143,6 +144,68 @@ protected function mapAffiliationType(array $row, ?int $coId = null): ?int } /** + * Map v4 External Identity Source plugin name to v5 plugin model path. + * + * Generic logic: + * - If a plugin exists with the same name as the v4 Source (ends with "Source"), + * return "Plugin.PluralTable" (eg: EnvSource -> EnvSource.EnvSources). + * - Else, if a "Connector" plugin exists for a "BaseSource", return + * "BaseConnector.PluralTable" (eg: FileSource -> FileConnector.FileSources). + * + * @param array $row A row from cm_org_identity_sources containing 'plugin' + * @return string|null The v5 Plugin.Table string or null if unmapped/empty + * @since COmanage Registry v5.2.0 + */ + protected function mapExternalIdentitySourcePlugin(array $row): ?string + { + $v4 = $row['plugin'] ?? null; + if (!$v4) { + return null; + } + + $pluginsTable = TableRegistry::getTableLocator()->get('Plugins'); + + $pluginRows = $pluginsTable + ->find() + ->select(['plugin']) + ->where(fn($exp) => $exp->isNotNull('plugin')) + ->distinct() + ->disableHydration() + ->all(); + + $available = array_map(static fn(array $r) => (string)$r['plugin'], $pluginRows->toList()); + + // Only process names that end with "Source" + if (!str_ends_with($v4, 'Source')) { + return null; + } + + // Pluralized Table name for the model side (eg, EnvSource -> EnvSources) + $pluralTable = Inflector::pluralize($v4); + + // 1) Direct plugin exists with same name as the Source + // Example: EnvSource -> EnvSource.EnvSources + if (in_array($v4, $available, true)) { + return $v4 . '.' . $pluralTable; + } + + // 2) If it's a "Source", check for "Connector" + // Example: FileSource -> FileConnector.FileSources + $base = substr($v4, 0, -strlen('Source')); + $connector = $base . 'Connector'; + + if (in_array($connector, $available, true)) { + return $connector . '.' . $pluralTable; + } + + // No mapping found +// return null; + throw new \InvalidArgumentException("Unable to map External Identity Source plugin: $v4. Plugin not implemented in COmanage Registry v5."); + } + + + + /** * Map email type to corresponding type ID * * @param array $row Row data containing email type