From ebec3a17d44b8eb28f5eb6eca8e1d97519a23f3d Mon Sep 17 00:00:00 2001 From: Mike Decker Date: Fri, 27 Oct 2023 10:37:23 -0700 Subject: [PATCH] Use migration to import cap org codes --- .../migrations/cap_orgs.yml | 79 ++++ .../src/Plugin/migrate/OrgCodeDeriver.php | 85 ++++ .../src/Plugin/migrate/test.json | 403 ++++++++++++++++++ .../stanford_person_importer.module | 8 +- 4 files changed, 571 insertions(+), 4 deletions(-) create mode 100644 modules/stanford_person/modules/stanford_person_importer/migrations/cap_orgs.yml create mode 100644 modules/stanford_person/modules/stanford_person_importer/src/Plugin/migrate/OrgCodeDeriver.php create mode 100644 modules/stanford_person/modules/stanford_person_importer/src/Plugin/migrate/test.json diff --git a/modules/stanford_person/modules/stanford_person_importer/migrations/cap_orgs.yml b/modules/stanford_person/modules/stanford_person_importer/migrations/cap_orgs.yml new file mode 100644 index 00000000..80111dce --- /dev/null +++ b/modules/stanford_person/modules/stanford_person_importer/migrations/cap_orgs.yml @@ -0,0 +1,79 @@ +id: cap_orgs +migration_tags: {} +label: 'CAP Organizations' +deriver: Drupal\stanford_person_importer\Plugin\migrate\OrgCodeDeriver +migration_group: su_stanford_person +source: + authentication: + plugin: oauth2 + base_uri: 'https://authz.stanford.edu' + token_url: /oauth/token + grant_type: client_credentials + client_id: '[client_id]' + client_secret: '[client_secret]' + urls: + - https://api.stanford.edu/cap/v1/orgs/AA00 + track_changes: true + plugin: url + data_fetcher_plugin: http + data_parser_plugin: json + headers: + Accept: 'application/json; charset=utf-8' + Content-Type: application/json + orphan_action: delete + ids: + alias: + type: string + item_selector: children + constants: + vid: cap_org_codes + code_beginning: '(' + code_ending: ')' + fields: + - + name: alias + label: alias + selector: alias + - + name: children + label: children + selector: children + - + name: name + label: name + selector: name + - + name: orgCodes + label: orgCodes + selector: orgCodes + - + name: type + label: type + selector: type +process: + codes: + - + plugin: skip_on_empty + method: process + source: orgCodes + - + plugin: concat + source: orgCodes + delimiter: ', ' + code_title: + plugin: concat + source: + - constants/code_beginning + - '@codes' + - constants/code_ending + name: + plugin: concat + source: + - name + - '@code_title' + delimiter: ' ' + vid: constants/vid + su_cap_org_code: orgCodes +destination: + plugin: 'entity:taxonomy_term' +migration_dependencies: null diff --git a/modules/stanford_person/modules/stanford_person_importer/src/Plugin/migrate/OrgCodeDeriver.php b/modules/stanford_person/modules/stanford_person_importer/src/Plugin/migrate/OrgCodeDeriver.php new file mode 100644 index 00000000..6d268261 --- /dev/null +++ b/modules/stanford_person/modules/stanford_person_importer/src/Plugin/migrate/OrgCodeDeriver.php @@ -0,0 +1,85 @@ +getValue('stanford_person_importer', 'su_person_cap_username', 0, 'value') ?? '';; + $client_secret = $config_pages->getValue('stanford_person_importer', 'su_person_cap_password', 0, 'value') ?? '';; + if (!$client_id || !$client_secret) { + return $this->derivatives; + } + + $base_plugin_definition['source']['authentication']['client_id'] = $client_id; + $base_plugin_definition['source']['authentication']['client_secret'] = $client_secret; + + /** @var \Drupal\migrate\Plugin\Migration $migration */ + $migration = \Drupal::service('plugin.manager.migration') + ->createStubMigration($base_plugin_definition); + $source = $migration->getSourcePlugin(); + $all_data = []; + $source->rewind(); + while ($source->valid()) { + /** @var \Drupal\migrate\Row $row */ + $row = $source->current(); + $all_data[] = $row->getSource(); + $source->next(); + } + $this->derivatives['base'] = $base_plugin_definition; + $this->createDerivatives($all_data, $base_plugin_definition, 'children', 'base'); + return $this->derivatives; + } + + protected function createDerivatives($data, $base_definition, $path, $parent_code = NULL) { + foreach ($data as $key => $item_data) { + if (empty($item_data['children'])) { + continue; + } + + $plugin = $base_definition; + asort($item_data['orgCodes']); + $code = reset($item_data['orgCodes']); + + $plugin['source']['urls'][0] = "https://api.stanford.edu/cap/v1/orgs/$code"; + $plugin['process']['parent/target_id'] = [ + [ + 'plugin' => 'default_value', + 'default_value' => $item_data['alias'], + ], + [ + 'plugin' => 'migration_lookup', + 'migration' => "cap_orgs:$parent_code", + ], + ]; + + if ($parent_code) { + $plugin['migration_dependencies']['required'] = [ + "cap_orgs:$parent_code", + ]; + } + + $this->derivatives[strtolower($code)] = $plugin; + $this->createDerivatives($item_data['children'], $base_definition, "$path/$key/children", strtolower($code)); + } + } + +} diff --git a/modules/stanford_person/modules/stanford_person_importer/src/Plugin/migrate/test.json b/modules/stanford_person/modules/stanford_person_importer/src/Plugin/migrate/test.json new file mode 100644 index 00000000..5e6577a9 --- /dev/null +++ b/modules/stanford_person/modules/stanford_person_importer/src/Plugin/migrate/test.json @@ -0,0 +1,403 @@ +[ + { + "alias": "department-of-athletics-physical-education-and-recreation", + "children": [ + { + "alias": "department-of-athletics-physical-education-and-recreation\/external-relations", + "browsable": false, + "children": [ + { + "alias": "department-of-athletics-physical-education-and-recreation\/external-relations\/student-affairs", + "browsable": false, + "name": "Student Affairs", + "onboarding": false, + "orgCodes": [ + "LLDL" + ], + "type": "DIVISION" + } + ], + "name": "External Relations", + "onboarding": false, + "orgCodes": [ + "LKJG", + "LKPZ", + "LLKE" + ], + "type": "DEPARTMENT" + }, + { + "alias": "department-of-athletics-physical-education-and-recreation\/daper-departmentwide-operations", + "browsable": false, + "name": "DAPER Departmentwide Operations", + "onboarding": true, + "orgCodes": [ + "LAGT" + ], + "type": "DEPARTMENT" + }, + { + "alias": "department-of-athletics-physical-education-and-recreation\/mens-sport-programs", + "browsable": false, + "name": "Men's Sport Programs", + "onboarding": false, + "orgCodes": [ + "LCWB", + "LBHR", + "LAUF", + "LBVD", + "LDCU", + "LEDS", + "LDQG", + "LBAY", + "LCBW", + "LERE", + "LCPM", + "LDWZ", + "LCIP", + "LDJN" + ], + "type": "DEPARTMENT" + }, + { + "alias": "department-of-athletics-physical-education-and-recreation\/other-daper-administration", + "browsable": false, + "name": "Other DAPER Administration", + "onboarding": false, + "orgCodes": [ + "LAJE" + ], + "type": "DEPARTMENT" + }, + { + "alias": "department-of-athletics-physical-education-and-recreation\/business-and-operations", + "browsable": false, + "children": [ + { + "alias": "department-of-athletics-physical-education-and-recreation\/business-and-operations\/driving-range", + "browsable": false, + "name": "Driving Range", + "onboarding": false, + "orgCodes": [ + "LULT" + ], + "type": "DIVISION" + }, + { + "alias": "department-of-athletics-physical-education-and-recreation\/business-and-operations\/home-game-management", + "browsable": false, + "name": "Home Game Management", + "onboarding": false, + "orgCodes": [ + "LSQQ" + ], + "type": "DIVISION" + }, + { + "alias": "department-of-athletics-physical-education-and-recreation\/business-and-operations\/golf-training-complex", + "browsable": false, + "name": "Golf Training Complex", + "onboarding": false, + "orgCodes": [ + "LUTC" + ], + "type": "DIVISION" + } + ], + "name": "Business and Operations", + "onboarding": false, + "orgCodes": [ + "LTKV", + "LOGF", + "LTYH", + "LTEC", + "LSJX", + "LORC", + "LTAA", + "LTAE" + ], + "type": "DEPARTMENT" + }, + { + "alias": "department-of-athletics-physical-education-and-recreation\/coed-sports", + "browsable": false, + "name": "Coed Sports", + "onboarding": false, + "orgCodes": [ + "LJVU" + ], + "type": "DEPARTMENT" + }, + { + "alias": "department-of-athletics-physical-education-and-recreation\/directors-office", + "browsable": false, + "name": "Director's Office", + "onboarding": false, + "orgCodes": [ + "LAHO" + ], + "type": "DEPARTMENT" + }, + { + "alias": "department-of-athletics-physical-education-and-recreation\/athletic-services", + "browsable": false, + "name": "Athletic Services", + "onboarding": false, + "orgCodes": [ + "LXHU", + "LXBB" + ], + "type": "DEPARTMENT" + }, + { + "alias": "department-of-athletics-physical-education-and-recreation\/swa", + "browsable": false, + "name": "SWA", + "onboarding": false, + "orgCodes": [ + "LAIJ" + ], + "type": "DEPARTMENT" + }, + { + "alias": "department-of-athletics-physical-education-and-recreation\/physical-education-and-recreation", + "browsable": false, + "children": [ + { + "alias": "department-of-athletics-physical-education-and-recreation\/physical-education-and-recreation\/wellness-programs", + "browsable": false, + "name": "Wellness Programs", + "onboarding": false, + "orgCodes": [ + "LVBW" + ], + "type": "DIVISION" + }, + { + "alias": "department-of-athletics-physical-education-and-recreation\/physical-education-and-recreation\/competitive-sports", + "browsable": false, + "name": "Competitive Sports", + "onboarding": false, + "orgCodes": [ + "LCOM" + ], + "type": "DIVISION" + }, + { + "alias": "department-of-athletics-physical-education-and-recreation\/physical-education-and-recreation\/rec-wellness-general", + "browsable": false, + "name": "Rec & Wellness General", + "onboarding": false, + "orgCodes": [ + "LREC" + ], + "type": "DIVISION" + }, + { + "alias": "department-of-athletics-physical-education-and-recreation\/physical-education-and-recreation\/rec-programs-general", + "browsable": false, + "name": "Rec Programs General", + "onboarding": false, + "orgCodes": [ + "LRGE" + ], + "type": "DIVISION" + }, + { + "alias": "department-of-athletics-physical-education-and-recreation\/physical-education-and-recreation\/recreation-services", + "browsable": false, + "name": "Recreation Services", + "onboarding": false, + "orgCodes": [ + "LRSV" + ], + "type": "DIVISION" + }, + { + "alias": "department-of-athletics-physical-education-and-recreation\/physical-education-and-recreation\/summer-camp-administration", + "browsable": false, + "name": "Summer Camp Administration", + "onboarding": false, + "orgCodes": [ + "LWNP" + ], + "type": "DIVISION" + }, + { + "alias": "department-of-athletics-physical-education-and-recreation\/physical-education-and-recreation\/fitness-centers", + "browsable": false, + "name": "Fitness Centers", + "onboarding": false, + "orgCodes": [ + "LVAF" + ], + "type": "DIVISION" + }, + { + "alias": "department-of-athletics-physical-education-and-recreation\/physical-education-and-recreation\/hhp-general", + "browsable": false, + "name": "HHP General", + "onboarding": false, + "orgCodes": [ + "LHGE" + ], + "type": "DIVISION" + }, + { + "alias": "department-of-athletics-physical-education-and-recreation\/physical-education-and-recreation\/adventure-programs", + "browsable": false, + "name": "Adventure Programs", + "onboarding": false, + "orgCodes": [ + "LADV" + ], + "type": "DIVISION" + }, + { + "alias": "department-of-athletics-physical-education-and-recreation\/physical-education-and-recreation\/leadership-institute", + "browsable": false, + "name": "Leadership Institute", + "onboarding": false, + "orgCodes": [ + "LLED" + ], + "type": "DIVISION" + } + ], + "name": "Physical Education and Recreation", + "onboarding": false, + "orgCodes": [ + "LVTK", + "LVRC", + "LWGW", + "LVMR", + "LWAD" + ], + "type": "DEPARTMENT" + }, + { + "alias": "department-of-athletics-physical-education-and-recreation\/womens-sport-programs", + "browsable": false, + "children": [ + { + "alias": "department-of-athletics-physical-education-and-recreation\/womens-sport-programs\/womens-fencing-program", + "browsable": false, + "name": "Women's Fencing Program", + "onboarding": false, + "orgCodes": [ + "LIAS" + ], + "type": "DIVISION" + }, + { + "alias": "department-of-athletics-physical-education-and-recreation\/womens-sport-programs\/womens-squash-program", + "browsable": false, + "name": "Women's Squash Program", + "onboarding": false, + "orgCodes": [ + "LJWS" + ], + "type": "DIVISION" + } + ], + "name": "Women's Sport Programs", + "onboarding": false, + "orgCodes": [ + "LFEQ", + "LFLJ", + "LFSC", + "LFYV", + "LGFO", + "LGMH", + "LGTA", + "LGZT", + "LHGM", + "LHNF", + "LHTY", + "LIHK", + "LIOD", + "LIUW", + "LJII" + "LJKA", + ], + "type": "DEPARTMENT" + }, + { + "alias": "department-of-athletics-physical-education-and-recreation\/intercollegiate-sports", + "browsable": false, + "name": "Intercollegiate Sports", + "onboarding": false, + "orgCodes": [ + "LYIS", + "LYBZ" + ], + "type": "DEPARTMENT" + } + ], + "name": "Department of Athletics, Physical Education and Recreation", + "orgCodes": [ + "LAAA" + ], + "type": "SCHOOL", + "authentication": { + "plugin": "oauth2", + "base_uri": "https:\/\/authz.stanford.edu", + "token_url": "\/oauth\/token", + "grant_type": "client_credentials", + "client_id": "drupal-hackathon", + "client_secret": "WP3q9Cdytt2K@SD" + }, + "urls": [ + "https:\/\/api.stanford.edu\/cap\/v1\/orgs\/AA00" + ], + "track_changes": true, + "plugin": "url", + "data_fetcher_plugin": "http", + "data_parser_plugin": "json", + "headers": { + "Accept": "application\/json; charset=utf-8", + "Content-Type": "application\/json" + }, + "orphan_action": "delete", + "ids": { + "alias": { + "type": "string" + } + }, + "item_selector": "children", + "constants": { + "vid": "cap_org_codes", + "code_beginning": "(", + "code_ending": ")" + }, + "fields": [ + { + "name": "alias", + "label": "alias", + "selector": "alias" + }, + { + "name": "children", + "label": "children", + "selector": "children" + }, + { + "name": "name", + "label": "name", + "selector": "name" + }, + { + "name": "orgCodes", + "label": "orgCodes", + "selector": "orgCodes" + }, + { + "name": "type", + "label": "type", + "selector": "type" + } + ], + "current_feed_url": "https:\/\/api.stanford.edu\/cap\/v1\/orgs\/AA00", + "target_bundles": [] + } +] diff --git a/modules/stanford_person/modules/stanford_person_importer/stanford_person_importer.module b/modules/stanford_person/modules/stanford_person_importer/stanford_person_importer.module index e10043be..2f84e04a 100644 --- a/modules/stanford_person/modules/stanford_person_importer/stanford_person_importer.module +++ b/modules/stanford_person/modules/stanford_person_importer/stanford_person_importer.module @@ -84,10 +84,10 @@ function stanford_person_importer_config_pages_presave(ConfigPagesInterface $ent // No org codes exist, lets load them up. if (empty($terms)) { - \Drupal::service('stanford_person_importer.cap') - ->setClientId($entity->get('su_person_cap_username')->getString()) - ->setClientSecret($entity->get('su_person_cap_password')->getString()) - ->updateOrganizations(); +// \Drupal::service('stanford_person_importer.cap') +// ->setClientId($entity->get('su_person_cap_username')->getString()) +// ->setClientSecret($entity->get('su_person_cap_password')->getString()) +// ->updateOrganizations(); } // Invalidate the migration cache since some of the org codes or workgroups