0

I'm trying to loop through an array (called "Attributes") in a JSON migration source, but I can't figure out how to do it. Here's a shortened sample of my data source:

[
  {
    "Id": "ST00000002",
    "Title": "Fast & Furious 9",
    "Attributes": [
      "0000000013",
      "0000000015"
    ]
  }
]

My ultimate goal is to check certain checkbox/boolean fields based on those attribute values, but I can't figure out how to handle each of the attributes individually.

Things I have tried so far:

  • Using single_value and multiple_values
  • Using the custom Deepen process plugin (as seen on this issue)
  • Using sub_process
  • Using the static_map plugin (to do something like this:
map:
    '0000000015': 1
default_value: 0
  • Using skip_on_value with not_equals: true

  • Using countless combinations of the above functions

I feel like this can't possibly be as difficult as I'm making it, so I hope someone can help me out. Thank you so much.

2
  • Migrate's YML is not really tailored to contain a lot of logic, I don't think there is anything built-in right now to solve this easily. While some weird logic with concat and str_replace + regex option might do the trick, I would advise to create a process plugin that acts as a wrapper to PHP's in_array
    – Hudri
    Jun 2, 2020 at 7:32
  • Extensive logic should go into process plugin(s), yes.
    – Kevin
    Jun 2, 2020 at 13:05

1 Answer 1

0

Thank you so much. I got it to work by creating a custom process plugin using "in_array", as suggested. If anyone's interested, here's the plugin I created:

namespace Drupal\migrate_veezi\Plugin\migrate\process;

use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\MigrateException;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\Row;

/**
 * Check if value exists in array
 *
 * @MigrateProcessPlugin(
 *   id = "in_array"
 * )
 *
 * To check if value is in array, use the following:
 *
 * @code
 * field_text:
 *   plugin: in_array
 *   source: array
 *   search: 'string'
 * @endcode
 *
 */

class InArray extends ProcessPluginBase {

  /**
   * {@inheritdoc}
   */
  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {

    $search = $this->configuration['search'];

    if ($search) {
      if (is_array($value) || $value instanceof \Traversable) {
        return in_array($search, $value);
      }
      else {
        throw new MigrateException(sprintf('%s is not traversable', var_export($value, TRUE)));
      }
    }
    else {
      throw new MigrateException(sprintf('search value is not set'));
    }
  }

}

And then I used it like this:

field_closed_caption:
    -
      plugin: single_value
      source: attributes
    -
      plugin: in_array
      search: '0000000007'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.