diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..58ee6a60554b4522d120e4c30805040a1170403c --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.dropwhale +.idea/ +docker-compose.yml +dropwhale.settings +*.patch +interdiff*.txt diff --git a/README.md b/README.md new file mode 100644 index 0000000000000000000000000000000000000000..7ee4fafe85646e2bc5e28f8bf3d6918f20a27796 --- /dev/null +++ b/README.md @@ -0,0 +1,73 @@ +# Migrate Process Array + +When migrating content, sometimes you have an array of values you need to filter against known items. In PHP, you would use `array_intersect()` or `array_diff()`. + +This module provides migration process plugins for each: + +```yaml + field_of_array_values: + plugin: array_intersect + source: some_array_field + match: + - values + - to + - match + field_of_array_values: + plugin: array_diff + source: some_array_field + exclude: + - values + - to + - match +``` + +For a given field value: + +``` +[ + 'a', + 'bunch', + 'of', + 'values', +]; +``` + +The `array_intersect` plugin would return: + +``` +[ + 'values', +]; +``` + +Whereas the `array_diff` plugin would return: + +``` +[ + 'a', + 'bunch', + 'of', +]; +``` + +## Using custom filtering + +Sometimes you'd rather write your own custom filer. In PHP, you'd use `array_filter()`, and provide your own custom callback. This module also provides a process plugin: + +``` + field_of_array_values: + plugin: array_filter + source: some_array_field + callable: 'my_function' +``` + +The `callable` parameter works just like it does in core's `callback` process plugin. You can specify a static class function like so: + +``` + field_of_array_values: + plugin: array_filter + source: some_array_field + callable: + - '\Drupal\my_module\MyClass' + - myMethod +``` diff --git a/README.txt b/README.txt deleted file mode 100644 index c05cba629d63e1794d95faa736b23e1b59d097a5..0000000000000000000000000000000000000000 --- a/README.txt +++ /dev/null @@ -1 +0,0 @@ -Migrate Process Array diff --git a/composer.json b/composer.json new file mode 100644 index 0000000000000000000000000000000000000000..e5ae4348490689c57793c9861e45d7cc36019fbf --- /dev/null +++ b/composer.json @@ -0,0 +1,14 @@ +{ + "name": "drupal/migrate_process_array", + "type": "drupal-module", + "description": "Array-centric utilties for Migrations", + "keywords": ["Drupal"], + "license": "GPL-2.0+", + "homepage": "https://www.drupal.org/project/migrate_process_array", + "minimum-stability": "dev", + "support": { + "issues": "https://www.drupal.org/project/issues/migrate_process_array", + "source": "http://cgit.drupalcode.org/migrate_process_array" + }, + "require": { } +} diff --git a/migrate_process_array.info.yml b/migrate_process_array.info.yml new file mode 100644 index 0000000000000000000000000000000000000000..d6d589989c93b7b552dd2d73154b0fe64124753e --- /dev/null +++ b/migrate_process_array.info.yml @@ -0,0 +1,5 @@ +name: 'Migrate Process Array' +type: module +description: 'Array-centric utilties for Migrations' +core: 8.x +package: 'Migration' diff --git a/migrate_process_array.module b/migrate_process_array.module new file mode 100644 index 0000000000000000000000000000000000000000..4a3843da0bf165330883c09604ac9c4c3e688007 --- /dev/null +++ b/migrate_process_array.module @@ -0,0 +1,24 @@ +<?php + +/** + * @file + * Contains migrate_process_array.module. + */ + +use Drupal\Core\Routing\RouteMatchInterface; + +/** + * Implements hook_help(). + */ +function migrate_process_array_help($route_name, RouteMatchInterface $route_match) { + switch ($route_name) { + // Main module help for the migrate_process_array module. + case 'help.page.migrate_process_array': + $output = ''; + $output .= '<h3>' . t('About') . '</h3>'; + $output .= '<p>' . t('Array-centric utilties for Migrations') . '</p>'; + return $output; + + default: + } +} diff --git a/src/Plugin/migrate/process/ArrayDiff.php b/src/Plugin/migrate/process/ArrayDiff.php new file mode 100644 index 0000000000000000000000000000000000000000..0af1031d1462c1ae3e545e4ccc5c65c5fb79093f --- /dev/null +++ b/src/Plugin/migrate/process/ArrayDiff.php @@ -0,0 +1,69 @@ +<?php + +namespace Drupal\migrate_process_array\Plugin\migrate\process; + +use Drupal\migrate\MigrateExecutableInterface; +use Drupal\migrate\ProcessPluginBase; +use Drupal\migrate\Row; + +/** + * Enables use of array_diff within a migration. + * + * @MigrateProcessPlugin( + * id = "array_diff" + * ) + */ +class ArrayDiff extends ProcessPluginBase { + + /** + * {@inheritdoc} + */ + public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { + // Only process non-empty values. + if (empty($value)) { + return NULL; + } + + // The input must be an array. + if (!is_array($value)) { + $value = [$value]; + } + + // As well as the array to match against. + $exclude = $this->configuration['exclude']; + if (!is_array($exclude)) { + $exclude = [$exclude]; + } + + // Get the method and callable, if any. + $method = empty($this->configuration['method']) ? '' : $this->configuration['method']; + $callable = empty($this->configuration['callable']) ? NULL : $this->configuration['callable']; + + // Return results by method. + $out = []; + if ($method == 'assoc') { + $out = array_diff_assoc($value, $exclude); + } + elseif ($method == 'key') { + $out = array_diff_key($value, $exclude); + } + elseif ($method == 'uassoc' && !empty($callable)) { + $out = array_diff_uassoc($value, $exclude, $callable); + } + elseif ($method == 'ukey') { + $out = array_diff_ukey($value, $exclude, $callable); + } + else { + $out = array_diff($value, $exclude); + } + + // Migrate treats NULL as empty not not empty arrays. + if (empty($out)) { + return NULL; + } + + echo "Diff : "; + var_dump($out); + return $out; + } +} diff --git a/src/Plugin/migrate/process/ArrayFilter.php b/src/Plugin/migrate/process/ArrayFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..8233a197983c7c36e7ac4892f740e9faad41015d --- /dev/null +++ b/src/Plugin/migrate/process/ArrayFilter.php @@ -0,0 +1,40 @@ +<?php + +namespace Drupal\migrate_process_array\Plugin\migrate\process; + +use Drupal\migrate\MigrateExecutableInterface; +use Drupal\migrate\ProcessPluginBase; +use Drupal\migrate\Row; + +/** + * Enables use of array_filter within a migration. + * + * @MigrateProcessPlugin( + * id = "array_filter" + * ) + */ +class ArrayFilter extends ProcessPluginBase { + + /** + * {@inheritdoc} + */ + public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { + // Only process non-empty values. + if (empty($value)) { + return NULL; + } + + // The input must be an array. + if (!is_array($value)) { + $value = [$value]; + } + + // Return using a custom callable, if provided. + if (!empty($this->configuration['callable'])) { + return array_filter($value, $this->configuration['callable']); + } + + // Otherwise, just use the default filter. + return array_filter($value); + } +} diff --git a/src/Plugin/migrate/process/ArrayIntersect.php b/src/Plugin/migrate/process/ArrayIntersect.php new file mode 100644 index 0000000000000000000000000000000000000000..97f8e5ad88592ce40c55f5180aedf32e5551d422 --- /dev/null +++ b/src/Plugin/migrate/process/ArrayIntersect.php @@ -0,0 +1,69 @@ +<?php + +namespace Drupal\migrate_process_array\Plugin\migrate\process; + +use Drupal\migrate\MigrateExecutableInterface; +use Drupal\migrate\ProcessPluginBase; +use Drupal\migrate\Row; + +/** + * Enables use of array_intersect within a migration. + * + * @MigrateProcessPlugin( + * id = "array_intersect" + * ) + */ +class ArrayIntersect extends ProcessPluginBase { + + /** + * {@inheritdoc} + */ + public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { + // Only process non-empty values. + if (empty($value)) { + return NULL; + } + + // The input must be an array. + if (!is_array($value)) { + $value = [$value]; + } + + // As well as the array to match against. + $match = $this->configuration['match']; + if (!is_array($match)) { + $match = [$match]; + } + + // Get the method and callable, if any. + $method = empty($this->configuration['method']) ? '' : $this->configuration['method']; + $callable = empty($this->configuration['callable']) ? NULL : $this->configuration['callable']; + + // Return results by method. + $out = []; + if ($method == 'assoc') { + $out = array_intersect_assoc($value, $match); + } + elseif ($method == 'key') { + $out = array_intersect_key($value, $match); + } + elseif ($method == 'uassoc' && !empty($callable)) { + $out = array_intersect_uassoc($value, $match, $callable); + } + elseif ($method == 'ukey') { + $out = array_intersect_ukey($value, $match, $callable); + } + else { + $out = array_intersect($value, $match); + } + + // Migrate treats NULL as empty not not empty arrays. + if (empty($out)) { + return NULL; + } + + echo "Intersect: "; + var_dump($out); + return $out; + } +}