Browse Source

Coding standards, type hinting.

Frederic G. MARAND 7 years ago
parent
commit
204003e64f

+ 0 - 3
reinstall.drush.inc

@@ -5,9 +5,6 @@
  * Export content into YAML files.
  */
 
-use Drupal\Component\Serialization\Yaml;
-use Symfony\Component\Serializer\Serializer;
-
 /**
  * Implements hook_drush_command().
  */

+ 4 - 4
reinstall.info.yml

@@ -5,7 +5,7 @@ core: 8.x
 package: OSInet
 php: 7.0
 dependencies:
-  - migrate
-  - migrate_plus
-  - migrate_tools
-  - serialization
+  - drupal:migrate
+  - drupal:migrate_plus
+  - drupal:migrate_tools
+  - drupal:serialization

+ 10 - 4
reinstall.install

@@ -1,9 +1,15 @@
 <?php
 
+/**
+ * @file
+ * Reinstall install file.
+ */
+
 /**
  * Remove migration tables.
  *
- * @param $table
+ * @param string $table
+ *   The base name of the table to drop.
  */
 function reinstall_remove_migration_tables($table) {
   $db = \Drupal::database();
@@ -11,17 +17,17 @@ function reinstall_remove_migration_tables($table) {
 
   $db->schema()->dropTable('migrate_map_' . $table);
   $logger->notice('Table migrate_map_@table dropped', [
-      '@table' => $table,
+    '@table' => $table,
   ]);
 
   $db->schema()->dropTable('migrate_message_' . $table);
   $logger->notice('Table migrate_message_@table dropped', [
-      '@table' => $table,
+    '@table' => $table,
   ]);
 }
 
 /**
- * Implements hook_uninstall.
+ * Implements hook_uninstall().
  */
 function reinstall_uninstall() {
   // Get all migrations.

+ 0 - 1
reinstall.services.yml

@@ -25,4 +25,3 @@ services:
     class: 'Drupal\reinstall\EventSubscriber\TermPreDump'
     tags:
       - { name: 'event_subscriber' }
-

+ 8 - 3
src/Dumper.php

@@ -2,14 +2,12 @@
 
 namespace Drupal\reinstall;
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Entity\ContentEntityStorageInterface;
 use Drupal\Core\Entity\ContentEntityTypeInterface;
 use Drupal\Core\Entity\EntityTypeBundleInfo;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Session\AccountSwitcherInterface;
 use Drupal\Core\Session\UserSession;
-use Drupal\file\Entity\File;
 use Symfony\Component\EventDispatcher\EventDispatcherInterface;
 use Symfony\Component\Serializer\Serializer;
 use Symfony\Component\Yaml\Yaml;
@@ -98,6 +96,8 @@ class Dumper {
    *   The value of the app.root "parameter service".
    * @param \Symfony\Component\Serializer\Serializer $serializer
    *   The serializer service.
+   * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $eventDispatcher
+   *   The event_dispatcher service.
    * @param string $path
    *   The import path.
    */
@@ -228,9 +228,12 @@ class Dumper {
    * Prepare the dump destination directory and return the file name within it.
    *
    * @param string $entityTypeName
+   *   The type of the entities to dump.
    * @param string $bundleName
+   *   The bundle of the entities to dump.
    *
    * @return string
+   *   The path of the dump file.
    */
   protected function prepareDestination(string $entityTypeName, string $bundleName): string {
     $importPath = $this->importPath;
@@ -258,7 +261,6 @@ class Dumper {
     if (!is_dir($real)) {
       drupal_set_message("Non-existent base dump directory: $completePath.", "error");
       throw new \InvalidArgumentException("Non-existent base dump directory: $completePath.");
-      return;
     }
 
     $this->importPath = $real;
@@ -268,8 +270,10 @@ class Dumper {
    * Like NormalizerInterface::normalize(), but for an array.
    *
    * @param array $entities
+   *   The entities to convert to arrays.
    *
    * @return mixed
+   *   The array representing the entities.
    */
   protected function toArray(array $entities): array {
     $json_options = [];
@@ -278,4 +282,5 @@ class Dumper {
 
     return $hash;
   }
+
 }

+ 9 - 1
src/DumperEvent.php

@@ -2,7 +2,6 @@
 
 namespace Drupal\reinstall;
 
-
 use Drupal\Core\Entity\EntityStorageInterface;
 use Symfony\Component\EventDispatcher\Event;
 
@@ -15,16 +14,22 @@ use Symfony\Component\EventDispatcher\Event;
 class DumperEvent extends Event {
 
   /**
+   * The name of the bundle for which a dump is being performed.
+   *
    * @var string
    */
   public $bundleName;
 
   /**
+   * The entities to dump.
+   *
    * @var \Drupal\Core\Entity\EntityInterface[]
    */
   public $entities = [];
 
   /**
+   * The storage handler for the entity type of the entities to dump.
+   *
    * @var \Drupal\Core\Entity\EntityStorageInterface
    */
   public $storage;
@@ -33,8 +38,11 @@ class DumperEvent extends Event {
    * DumperEvent constructor.
    *
    * @param \Drupal\Core\Entity\EntityStorageInterface $storage
+   *   The entity storage.
    * @param string $bundleName
+   *   The name of the bundle being dumped.
    * @param array $entities
+   *   The entities to dump.
    */
   public function __construct(EntityStorageInterface $storage, string $bundleName, array $entities) {
     $this->storage = $storage;

+ 4 - 3
src/DumperEvents.php

@@ -15,7 +15,7 @@ final class DumperEvents {
    * This event allows modules to perform an action whenever content entities
    * of a given entity type bundle are exported, usually to perform extra
    * operations, like:
-   * - copying/moving the actual files on file export
+   * - copying/moving the actual files on file export.
    *
    * The event listener method receives a \Drupal\reinstall\SerializeEvent
    * instance, carrying an array of all entites indexed by $entity->id().
@@ -35,8 +35,8 @@ final class DumperEvents {
    * This event allows modules to perform an action whenever content entities
    * of a given entity type bundle are exported, usually to add data to the
    * export, like:
-   * - parent on taxonomy_term
-   * - path on any entity with a canonical path
+   * - parent on taxonomy_term.
+   * - path on any entity with a canonical path.
    *
    * The event listener method receives a \Drupal\reinstall\DumperEvent
    * instance, carrying an array of all entites indexed by $entity->id().
@@ -49,4 +49,5 @@ final class DumperEvents {
    * @var string
    */
   const PRE_DUMP = 'reinstall.dump.pre';
+
 }

+ 24 - 8
src/EventSubscriber/FilePostDump.php

@@ -32,6 +32,8 @@ class FilePostDump implements EventSubscriberInterface {
   /**
    * FilePostDump constructor.
    *
+   * @param \Drupal\Core\File\FileSystemInterface $fileSystem
+   *   The file_system service.
    * @param string $importPath
    *   The reinstall.path parameter.
    */
@@ -49,6 +51,12 @@ class FilePostDump implements EventSubscriberInterface {
     ];
   }
 
+  /**
+   * Callback for POST_DUMP event.
+   *
+   * @param \Drupal\reinstall\DumperEvent $event
+   *   The post-dump event.
+   */
   public function onDumpPost(DumperEvent $event) {
     if ($event->storage->getEntityTypeId() !== 'file') {
       return;
@@ -57,6 +65,14 @@ class FilePostDump implements EventSubscriberInterface {
     $this->dumpFiles($event->bundleName, $event->entities);
   }
 
+  /**
+   * Dump the actual files for a file entity bundle.
+   *
+   * @param string $bundleName
+   *   The bundle name.
+   * @param array $files
+   *   The file URLs.
+   */
   public function dumpFiles(string $bundleName, array $files) {
     $importPath = $this->importPath;
     $dir = "$importPath/$bundleName";
@@ -80,15 +96,12 @@ class FilePostDump implements EventSubscriberInterface {
       ];
     }
 
-    /**
-     * @var int $fid
-     * @var \Drupal\file\Entity\File $file
-     */
-    foreach ($files as $fid => $file) {
+    /** @var \Drupal\file\Entity\File $file */
+    foreach ($files as $file) {
       $uri = $file->getFileUri();
       $target = file_uri_target($uri);
       $ns = $this->fileSystem->uriScheme($uri);
-      fputs($lists[$ns]['handle'], $target . "\n");
+      fwrite($lists[$ns]['handle'], $target . "\n");
       $dest = $lists[$ns]['dir'] . '/' . $target;
 
       $dir = dirname($dest);
@@ -103,14 +116,16 @@ class FilePostDump implements EventSubscriberInterface {
     }
   }
 
-
   /**
-   * array_reduce() callback to collect namespaces from file entities.
+   * An array_reduce() callback to collect namespaces from file entities.
    *
    * @param string[] $accu
+   *   The namespaces accumulator.
    * @param \Drupal\file\Entity\File $fileItem
+   *   A file description.
    *
    * @return string[]
+   *   An array of namespaces used on the site.
    *
    * @see \Drupal\reinstall\Dumper::dumpFiles()
    */
@@ -125,4 +140,5 @@ class FilePostDump implements EventSubscriberInterface {
     $accu[$namespace] = TRUE;
     return $accu;
   }
+
 }

+ 23 - 0
src/EventSubscriber/TermPreDump.php

@@ -8,14 +8,30 @@ use Drupal\taxonomy\TermInterface;
 use Drupal\taxonomy\TermStorageInterface;
 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 
+/**
+ * Class TermPreDump adds the parents target_id values on a term.
+ */
 class TermPreDump implements EventSubscriberInterface {
 
+  /**
+   * {@inheritdoc}
+   */
   public static function getSubscribedEvents() {
     return [
       DumperEvents::PRE_DUMP => 'onDumpPre',
     ];
   }
 
+  /**
+   * Set the parents on the term.
+   *
+   * @param \Drupal\taxonomy\TermInterface $term
+   *   The term to complete.
+   * @param int $tid
+   *   The term id.
+   * @param \Drupal\taxonomy\TermStorageInterface $storage
+   *   The term storage.
+   */
   protected static function setParents(TermInterface $term, $tid, TermStorageInterface $storage) {
     $parents = $storage->loadParents($term->id());
     if (!empty($parents)) {
@@ -23,6 +39,12 @@ class TermPreDump implements EventSubscriberInterface {
     }
   }
 
+  /**
+   * Callback for PRE_DUMP event.
+   *
+   * @param \Drupal\reinstall\DumperEvent $event
+   *   The pre-dump event.
+   */
   public static function onDumpPre(DumperEvent $event) {
     $storage = $event->storage;
     if ($storage->getEntityTypeId() !== 'taxonomy_term') {
@@ -31,4 +53,5 @@ class TermPreDump implements EventSubscriberInterface {
 
     array_walk($event->entities, [__CLASS__, 'setParents'], $storage);
   }
+
 }

+ 40 - 0
src/Plugin/migrate/process/TermParent.php

@@ -0,0 +1,40 @@
+<?php
+
+namespace Drupal\reinstall\Plugin\migrate\process;
+
+use Drupal\migrate\MigrateExecutableInterface;
+use Drupal\migrate\ProcessPluginBase;
+use Drupal\migrate\Row;
+
+/**
+ * Class TermParent works in conjunction with ReinstallTermSource.
+ *
+ * With the latter using the heavy-handed SimpleSource::flattenRow() method,
+ * the parents obtained when migrating hierarchical vocabularies can be wrong,
+ * especially with terms having multiple parents (i.e. non-tree graphs), and
+ * this method allows the migration to obtain proper parent target_id values.
+ *
+ * @MigrateProcessPlugin(
+ *   id = "reinstall_term_parents"
+ * )
+ */
+class TermParent extends ProcessPluginBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function transform(
+    $value,
+    MigrateExecutableInterface $migrate_executable,
+    Row $row,
+    $destination_property
+  ) {
+    if (is_scalar($value)) {
+      return $value;
+    }
+    elseif (isset($value['target_id'])) {
+      return $value['target_id'];
+    }
+  }
+
+}

+ 12 - 1
src/Plugin/migrate/source/ReinstallFileSource.php

@@ -27,7 +27,18 @@ class ReinstallFileSource extends SimpleSource {
     $this->records = array_map([$this, 'flattenRecord'], $this->initialParse($configuration));
   }
 
-  protected function flattenRecord($record) {
+  /**
+   * Flatten the field hierarchy. Not correct for all cases.
+   *
+   * @param array $record
+   *   The raw source values.
+   *
+   * @return array
+   *   The flattened values.
+   *
+   * @see \Drupal\reinstall\Plugin\migrate\process\TermParent
+   */
+  protected function flattenRecord(array $record) {
     $row = new Row($record);
     $this->flattenRow($row);
     return $row->getSource();

+ 12 - 20
src/Plugin/migrate/source/ReinstallTermSource.php

@@ -28,7 +28,18 @@ class ReinstallTermSource extends SimpleSource {
     $this->records = $rawRecords;
   }
 
-  protected function flattenRecord($record) {
+  /**
+   * Flatten the field hierarchy. Not correct for all cases.
+   *
+   * @param array $record
+   *   The raw source values.
+   *
+   * @return array
+   *   The flattened values.
+   *
+   * @see \Drupal\reinstall\Plugin\migrate\process\TermParent
+   */
+  protected function flattenRecord(array $record) {
     $row = new Row($record);
     $this->flattenRow($row);
     return $row->getSource();
@@ -68,23 +79,4 @@ class ReinstallTermSource extends SimpleSource {
     return $ids;
   }
 
-  /**
-   * Obtain the term parents from either of their two formats.
-   *
-   * @param mixed $source
-   *   A parent, from the migration pipeline.
-   *
-   * @return mixed
-   *   The parent, as its target_id.
-   *
-   * @see (reinstall)/README.md
-   */
-  public static function getParent($source) {
-    if (is_scalar($source)) {
-      return $source;
-    }
-    elseif (isset($source['target_id'])) {
-      return $source['target_id'];
-    }
-  }
 }

+ 22 - 2
src/Plugin/migrate/source/ReinstallUserSource.php

@@ -29,13 +29,33 @@ class ReinstallUserSource extends SimpleSource {
     $this->records = $records;
   }
 
-  protected function flattenRecord($record) {
+  /**
+   * Flatten the field hierarchy. Not correct for all cases.
+   *
+   * @param array $record
+   *   The raw source values.
+   *
+   * @return array
+   *   The flattened values.
+   *
+   * @see \Drupal\reinstall\Plugin\migrate\process\TermParent
+   */
+  protected function flattenRecord(array $record) {
     $row = new Row($record);
     $this->flattenRow($row);
     return $row->getSource();
   }
 
-  protected function filter01($record) {
+  /**
+   * Skip users 0 and 1 in imports, as they are core-provided.
+   *
+   * @param array $record
+   *   The description of a user entity.
+   *
+   * @return bool
+   *   Include it (1) or filter it (0).
+   */
+  protected function filter01(array $record) {
     return ($record['uid'] ?? 0) > 1;
   }
 

+ 11 - 4
src/Plugin/migrate/source/SimpleSource.php

@@ -11,6 +11,9 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\Yaml\Exception\ParseException;
 use Symfony\Component\Yaml\Yaml;
 
+/**
+ * Class SimpleSource provides the basic mechanisms to load a YML entity dump.
+ */
 abstract class SimpleSource extends SourcePluginBase implements ContainerFactoryPluginInterface {
 
   /**
@@ -20,6 +23,9 @@ abstract class SimpleSource extends SourcePluginBase implements ContainerFactory
    */
   protected $records;
 
+  /**
+   * {@inheritdoc}
+   */
   public static function create(
     ContainerInterface $container,
     array $configuration,
@@ -94,13 +100,13 @@ abstract class SimpleSource extends SourcePluginBase implements ContainerFactory
    * Load then parse the file requested in configuration and return its records.
    *
    * @param array $configuration
-   *
+   *   The source configuration from the migration source section.
    * @param string $key
    *   Optional. A top-level key for the source document. If empty, items will
    *   be parsed from the root of the source document.
    *
-   *
-   * @return mixed
+   * @return array
+   *   An array of entity descriptions.
    *
    * @throws \Drupal\migrate\MigrateException
    */
@@ -115,7 +121,8 @@ abstract class SimpleSource extends SourcePluginBase implements ContainerFactory
     try {
       $raw = file_get_contents($filePath);
       $data = Yaml::parse($raw);
-    } catch (ParseException $e) {
+    }
+    catch (ParseException $e) {
       throw new MigrateException("Cannot parse the contents of ${filePath}.");
     }