Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move cap URL to a source plugin #312

Open
wants to merge 2 commits into
base: 9.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,8 @@

use Drupal\config_pages\ConfigPagesLoaderServiceInterface;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\ConfigFactoryOverrideInterface;
use Drupal\Core\Config\StorageInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Url;
use Drupal\stanford_person_importer\CapInterface;

/**
* Configuration overrides for stanford person importer migration entity.
Expand All @@ -18,56 +14,21 @@
*/
class ConfigOverrides implements ConfigFactoryOverrideInterface {

/**
* How many profiles are returned in each url.
*/
const URL_CHUNKS = 15;

/**
* Config pages loader service.
*
* @var \Drupal\config_pages\ConfigPagesLoaderServiceInterface
*/
protected $configPages;

/**
* Entity type manager service.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;

/**
* Cap API service.
*
* @var \Drupal\stanford_person_importer\CapInterface
*/
protected $cap;

/**
* Config factory service.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $configFactory;

/**
* ConfigOverrides constructor.
*
* @param \Drupal\config_pages\ConfigPagesLoaderServiceInterface $config_pages
* Config pages loader service.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* Entity type manager service.
* @param \Drupal\stanford_person_importer\CapInterface $cap
* Cap API service.
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* Config factory service.
*/
public function __construct(ConfigPagesLoaderServiceInterface $config_pages, EntityTypeManagerInterface $entity_type_manager, CapInterface $cap, ConfigFactoryInterface $config_factory) {
public function __construct(protected ConfigPagesLoaderServiceInterface $config_pages) {
$this->configPages = $config_pages;
$this->entityTypeManager = $entity_type_manager;
$this->cap = $cap;
$this->configFactory = $config_factory;
}

/**
Expand Down Expand Up @@ -97,156 +58,13 @@ public function getCacheableMetadata($name) {
public function loadOverrides($names) {
$overrides = [];
if (in_array('migrate_plus.migration.su_stanford_person', $names)) {
$urls = $this->getImporterUrls();

if ($urls === NULL) {
$overrides['migrate_plus.migration.su_stanford_person']['status'] = FALSE;
return $overrides;
}

$overrides['migrate_plus.migration.su_stanford_person']['source']['urls'] = $urls;
$overrides['migrate_plus.migration.su_stanford_person']['source']['plugin'] = 'cap_url';
$overrides['migrate_plus.migration.su_stanford_person']['source']['authentication']['client_id'] = $this->getCapClientId();
$overrides['migrate_plus.migration.su_stanford_person']['source']['authentication']['client_secret'] = $this->getCapClientSecret();
}
return $overrides;
}

/**
* Get a list of urls for the importer.
*
* @return array|null
* Array of urls or NULL if any errors occur.
*/
protected function getImporterUrls(): ?array {
$urls = &drupal_static('cap_source_urls');
if ($urls !== NULL) {
return $urls;
}
try {
$this->cap->setClientId($this->getCapClientId());
$this->cap->setClientSecret($this->getCapClientSecret());

$urls = $this->getOrgsUrls();
$urls = array_merge($urls, $this->getWorkgroupUrls());
$urls = array_merge($urls, $this->getSunetUrls());
}
catch (\Exception $e) {
return NULL;
}

$allowed_fields = $this->getAllowedFields();
foreach ($urls as &$url) {
$url = Url::fromUri($url);
$url->mergeOptions(['query' => ['whitelist' => implode(',', $allowed_fields)]]);
$url = $url->toString(TRUE)->getGeneratedUrl();
}
return $urls;
}

/**
* Get a list of the fields from CAP that should be fetched.
*
* @return string[]
* Array of CAP selectors.
*/
protected function getAllowedFields() {
$allowed_fields = $this->configFactory->getEditable('migrate_plus.migration.su_stanford_person')
->getOriginal('source.fields') ?: [];
foreach ($allowed_fields as &$field) {
$field = $field['selector'];
if ($slash_position = strpos($field, '/')) {
$field = substr($field, 0, $slash_position);
}
}
return $allowed_fields;
}

/**
* Get a list of CAP urls that have an org code specified.
*
* @return string[]
* List of urls.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
protected function getOrgsUrls() {
$org_tids = array_filter($this->configPages->getValue('stanford_person_importer', 'su_person_orgs', [], 'target_id') ?? []);
$include_children = (bool) $this->configPages->getValue('stanford_person_importer', 'su_person_child_orgs', 0, 'value');

// No field values populated.
if (empty($org_tids)) {
return [];
}
$org_codes = [];

// Load the taxonomy term that the field is pointing at and use the org code
// field on the term entity.
$term_storage = $this->entityTypeManager->getStorage('taxonomy_term');
foreach ($org_tids as &$tid) {
if ($term = $term_storage->load($tid)) {
$org_code = $term->get('su_cap_org_code')
->getString();
$org_codes[] = str_replace(' ', '', $org_code);
}
}
return $this->getUrlChunks($this->cap->getOrganizationUrl($org_codes, $include_children));
}

/**
* Get a list of CAP urls that have a workgroup filter.
*
* @return string[]
* List of urls.
*/
protected function getWorkgroupUrls(): array {
$workgroups = array_filter($this->configPages->getValue('stanford_person_importer', 'su_person_workgroup', [], 'value') ?? []);

if ($workgroups) {
return $this->getUrlChunks($this->cap->getWorkgroupUrl($workgroups));
$overrides['migrate_plus.migration.su_stanford_person']['status'] = $this->getCapClientId() && $this->getCapClientSecret();
}
return [];
}

/**
* Get the list of CAP urls for a sunetid filter.
*
* @return string[]
* List of urls.
*/
protected function getSunetUrls(): array {
$sunets = $this->configPages->getValue('stanford_person_importer', 'su_person_sunetid', [], 'value') ?: [];

$urls = [];
foreach (array_chunk($sunets, self::URL_CHUNKS) as $chunk) {
$urls[] = $this->cap->getSunetUrl($chunk)->toString(TRUE)->getGeneratedUrl();
}
return $urls;
}

/**
* Break up the url into multiple urls based on the number of results.
*
* @param \Drupal\Core\Url $url
* Cap API Url.
*
* @return string[]
* Array of Cap API Urls.
*/
protected function getUrlChunks(Url $url): array {
$count = $this->cap->getTotalProfileCount($url);
$number_chunks = ceil($count / self::URL_CHUNKS);
if ($number_chunks <= 1) {
$url->mergeOptions(['query' => ['ps' => self::URL_CHUNKS]]);
return [$url->toString(TRUE)->getGeneratedUrl()];
}

$urls = [];
for ($i = 1; $i <= $number_chunks; $i++) {
$url->mergeOptions(['query' => ['p' => $i, 'ps' => self::URL_CHUNKS]]);
$urls[] = $url->toString(TRUE)->getGeneratedUrl();
}
return $urls;
return $overrides;
}

/**
Expand Down
Loading
Loading