Fix Parser classes to use ClassScanner
authorEileen McNaughton <emcnaughton@wikimedia.org>
Tue, 28 Jun 2022 10:42:47 +0000 (22:42 +1200)
committerEileen McNaughton <emcnaughton@wikimedia.org>
Wed, 29 Jun 2022 10:03:57 +0000 (22:03 +1200)
12 files changed:
CRM/Activity/Import/Parser/Activity.php
CRM/Contact/Import/Parser/Contact.php
CRM/Contribute/Import/Parser/Contribution.php
CRM/Core/BAO/UserJob.php
CRM/Custom/Import/Parser/Api.php
CRM/Event/Import/Parser/Participant.php
CRM/Import/DataSource.php
CRM/Import/Parser.php
CRM/Member/Import/Parser/Membership.php
Civi/Core/ClassScanner.php
Civi/UserJob/UserJobInterface.php
tests/phpunit/api/v4/Entity/QueueTest.php

index 6aada017f6270d911eef9ce5c7ff3dba669252b8..d45940f885e6ad34778ae278267595e4b2c0c173 100644 (file)
  */
 class CRM_Activity_Import_Parser_Activity extends CRM_Import_Parser {
 
+  /**
+   * Get information about the provided job.
+   *  - name
+   *  - id (generally the same as name)
+   *  - label
+   *
+   *  e.g. ['activity_import' => ['id' => 'activity_import', 'label' => ts('Activity Import'), 'name' => 'activity_import']]
+   *
+   * @return array
+   */
+  public static function getUserJobInfo(): array {
+    return [
+      'activity_import' => [
+        'id' => 'activity_import',
+        'name' => 'activity_import',
+        'label' => ts('Activity Import'),
+      ],
+    ];
+  }
+
   /**
    * The initializer code, called before the processing.
    */
index f5c3d1e1693f0eea419e27f2a4dcc729135b7a48..3b2c0a5af12a91aa95b71fad0c93253d282ca670 100644 (file)
@@ -85,6 +85,25 @@ class CRM_Contact_Import_Parser_Contact extends CRM_Import_Parser {
     }
   }
 
+  /**
+   * Get information about the provided job.
+   *
+   *  - name
+   *  - id (generally the same as name)
+   *  - label
+   *
+   * @return array
+   */
+  public static function getUserJobInfo(): array {
+    return [
+      'contact_import' => [
+        'id' => 'contact_import',
+        'name' => 'contact_import',
+        'label' => ts('Contact Import'),
+      ],
+    ];
+  }
+
   /**
    * Get the fields to track the import.
    *
index 7784c9d9551d28d18369bf357976e1dc16311d03..e244fe0fc36dee8609fff99dec1dc025929c0939 100644 (file)
@@ -42,6 +42,26 @@ class CRM_Contribute_Import_Parser_Contribution extends CRM_Import_Parser {
     $this->_mapperKeys = $mapperKeys;
   }
 
+  /**
+   * Get information about the provided job.
+   *  - name
+   *  - id (generally the same as name)
+   *  - label
+   *
+   *  e.g. ['activity_import' => ['id' => 'activity_import', 'label' => ts('Activity Import'), 'name' => 'activity_import']]
+   *
+   * @return array
+   */
+  public static function getUserJobInfo(): array {
+    return [
+      'contribution_import' => [
+        'id' => 'contribution_import',
+        'name' => 'contribution_import',
+        'label' => ts('Contribution Import'),
+      ],
+    ];
+  }
+
   /**
    * Contribution-specific result codes
    * @see CRM_Import_Parser result code constants
index 5c2af7d608d00bb27489ae708a8246ce0c9c8178..789de78b70f7145fa18f8a0f519ed4c27bed9f63 100644 (file)
@@ -15,6 +15,9 @@
  * @copyright CiviCRM LLC https://civicrm.org/licensing
  */
 
+use Civi\Core\ClassScanner;
+use Civi\UserJob\UserJobInterface;
+
 /**
  * This class contains user jobs functionality.
  */
@@ -140,44 +143,20 @@ class CRM_Core_BAO_UserJob extends CRM_Core_DAO_UserJob implements \Civi\Core\Ho
    * @return array
    */
   public static function getTypes(): array {
-    return [
-      [
-        'id' => 'contact_import',
-        'name' => 'contact_import',
-        'label' => ts('Contact Import'),
-        'class' => 'CRM_Contact_Import_Parser_Contact',
-      ],
-      [
-        'id' => 'contribution_import',
-        'name' => 'contribution_import',
-        'label' => ts('Contribution Import'),
-        'class' => 'CRM_Contribute_Import_Parser_Contribution',
-      ],
-      [
-        'id' => 'membership_import',
-        'name' => 'membership_import',
-        'label' => ts('Membership Import'),
-        'class' => 'CRM_Member_Import_Parser_Membership',
-      ],
-      [
-        'id' => 'activity_import',
-        'name' => 'activity_import',
-        'label' => ts('Activity Import'),
-        'class' => 'CRM_Activity_Import_Parser_Activity',
-      ],
-      [
-        'id' => 'participant_import',
-        'name' => 'participant_import',
-        'label' => ts('Participant Import'),
-        'class' => 'CRM_Event_Import_Parser_Participant',
-      ],
-      [
-        'id' => 'custom_field_import',
-        'name' => 'custom_field_import',
-        'label' => ts('Multiple Value Custom Field Import'),
-        'class' => 'CRM_Custom_Import_Parser_Api',
-      ],
-    ];
+    $types = Civi::cache()->get('UserJobTypes');
+    if ($types === NULL) {
+      $types = [];
+      $classes = ClassScanner::get(['interface' => UserJobInterface::class]);
+      foreach ($classes as $class) {
+        $declaredTypes = $class::getUserJobInfo();
+        foreach ($declaredTypes as $index => $declaredType) {
+          $declaredTypes[$index]['class'] = $class;
+        }
+        $types = array_merge($types, $declaredTypes);
+      }
+      Civi::cache()->set('UserJobTypes', $types);
+    }
+    return $types;
   }
 
 }
index 0df37ed2a255d84e7ab7abe1a225dbec93afa6ad..6fc4f41a06cafc9b231ca5ffcf6b78fe3a13b3bb 100644 (file)
@@ -10,6 +10,25 @@ class CRM_Custom_Import_Parser_Api extends CRM_Import_Parser {
   protected $_fields = [];
   protected $_multipleCustomData = '';
 
+  /**
+   * Get information about the provided job.
+   *
+   *  - name
+   *  - id (generally the same as name)
+   *  - label
+   *
+   * @return array
+   */
+  public static function getUserJobInfo(): array {
+    return [
+      'custom_field_import' => [
+        'id' => 'custom_field_import',
+        'name' => 'custom_field_import',
+        'label' => ts('Multiple Value Custom Field Import'),
+      ],
+    ];
+  }
+
   /**
    * The initializer code, called before the processing
    *
index 86558b7dd5db47a43cf3f03e60a8520cf019cae4..8afe963e82de27ee09de6a99411de77b08bb86fd 100644 (file)
@@ -71,6 +71,25 @@ class CRM_Event_Import_Parser_Participant extends CRM_Import_Parser {
     $this->_mapperKeys = &$mapperKeys;
   }
 
+  /**
+   * Get information about the provided job.
+   *
+   *  - name
+   *  - id (generally the same as name)
+   *  - label
+   *
+   * @return array
+   */
+  public static function getUserJobInfo(): array {
+    return [
+      'participant_import' => [
+        'id' => 'participant_import',
+        'name' => 'participant_import',
+        'label' => ts('Participant Import'),
+      ],
+    ];
+  }
+
   /**
    * The initializer code, called before the processing.
    */
index 2f5fe4e6c3faa4bef4b40538d3acc2f7ad59fd6f..744ce5c9fe0f9fdb0f0eb7a806bb92b0c4dc0642 100644 (file)
@@ -562,6 +562,7 @@ abstract class CRM_Import_DataSource {
     foreach (CRM_Core_BAO_UserJob::getTypes() as $type) {
       if ($this->getUserJob()['job_type'] === $type['id']) {
         $parserClass = $type['class'];
+        break;
       }
     }
     /* @var \CRM_Import_Parser */
index bd68050996e670069a333c8c0c2c03fe3822efec..91f20a3fb7c2938a44b3fd8370c703f1c9f21013 100644 (file)
@@ -13,13 +13,14 @@ use Civi\Api4\Campaign;
 use Civi\Api4\CustomField;
 use Civi\Api4\Event;
 use Civi\Api4\UserJob;
+use Civi\UserJob\UserJobInterface;
 
 /**
  *
  * @package CRM
  * @copyright CiviCRM LLC https://civicrm.org/licensing
  */
-abstract class CRM_Import_Parser {
+abstract class CRM_Import_Parser implements UserJobInterface {
   /**
    * Settings
    */
@@ -699,8 +700,9 @@ abstract class CRM_Import_Parser {
         $batchSize = $totalRows;
       }
       $task = new CRM_Queue_Task(
-        [get_class($this), 'runImport'],
-        ['userJobID' => $this->getUserJobID(), 'limit' => $batchSize],
+        [get_class($this), 'runJob'],
+        // Offset is unused by our import classes, but required by the interface.
+        ['userJobID' => $this->getUserJobID(), 'limit' => $batchSize, 'offset' => 0],
         ts('Processed %1 rows out of %2', [1 => $offset + $batchSize, 2 => $totalRowCount])
       );
       $queue->createItem($task);
@@ -1884,12 +1886,13 @@ abstract class CRM_Import_Parser {
    *
    * @param int $userJobID
    * @param int $limit
+   * @param int $offset
    *
    * @return bool
    * @throws \API_Exception
    * @throws \CRM_Core_Exception
    */
-  public static function runImport($taskContext, $userJobID, $limit) {
+  public static function runJob(\CRM_Queue_TaskContext $taskContext, int $userJobID, int $limit, int $offset): bool {
     $userJob = UserJob::get()->addWhere('id', '=', $userJobID)->addSelect('job_type')->execute()->first();
     $parserClass = NULL;
     foreach (CRM_Core_BAO_UserJob::getTypes() as $userJobType) {
index fa70d863f29b17bdb934beaf278e1722962d85f8..45db615fcdf5209b14cf72e8735165636639c2bf 100644 (file)
@@ -54,6 +54,26 @@ class CRM_Member_Import_Parser_Membership extends CRM_Import_Parser {
    */
   protected $_lineCount;
 
+  /**
+   * Get information about the provided job.
+   *  - name
+   *  - id (generally the same as name)
+   *  - label
+   *
+   *  e.g. ['activity_import' => ['id' => 'activity_import', 'label' => ts('Activity Import'), 'name' => 'activity_import']]
+   *
+   * @return array
+   */
+  public static function getUserJobInfo(): array {
+    return [
+      'membership_import' => [
+        'id' => 'membership_import',
+        'name' => 'membership_import',
+        'label' => ts('Membership Import'),
+      ],
+    ];
+  }
+
   /**
    * @param string $name
    * @param $title
index e5ed6d67cdcbad8499502debd1a0357f91560bd4..486b91e4dbd7cd7c0b5927139a5be07ed6885492 100644 (file)
@@ -135,6 +135,7 @@ class ClassScanner {
     static::scanFolders($classes, $civicrmRoot, 'CRM/*/WorkflowMessage', '_');
     static::scanFolders($classes, $civicrmRoot, 'Civi/*/WorkflowMessage', '\\');
     static::scanFolders($classes, $civicrmRoot, 'Civi/WorkflowMessage', '\\');
+    static::scanFolders($classes, $civicrmRoot, 'CRM/*/Import', '_');
     if (\CRM_Utils_Constant::value('CIVICRM_UF') === 'UnitTests') {
       static::scanFolders($classes, $civicrmRoot . 'tests/phpunit', 'CRM/*/WorkflowMessage', '_');
       static::scanFolders($classes, $civicrmRoot . 'tests/phpunit', 'Civi/*/WorkflowMessage', '\\');
index b3d9bbc7f3711e882119cd6b3af051245d859d04..bf259bd2f5368262203f2ecb5f5d9f4f8a548cf9 100644 (file)
@@ -1 +1,42 @@
 <?php
+/*
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC. All rights reserved.                        |
+ |                                                                    |
+ | This work is published under the GNU AGPLv3 license with some      |
+ | permitted exceptions and without any warranty. For full license    |
+ | and copyright information, see https://civicrm.org/licensing       |
+ +--------------------------------------------------------------------+
+ */
+
+namespace Civi\UserJob;
+
+interface UserJobInterface {
+
+  /**
+   * Get information about the provided job.
+   *  - name
+   *  - id (generally the same as name)
+   *  - label
+   *
+   *  e.g. ['activity_import' => ['id' => 'activity_import', 'label' => ts('Activity Import'), 'name' => 'activity_import']]
+   *
+   * @return array
+   */
+  public static function getUserJobInfo(): array;
+
+  /**
+   * Run import.
+   *
+   * @param \CRM_Queue_TaskContext $taskContext
+   * @param int $userJobID
+   *   The id in the civicrm_user_job table.
+   * @param int $limit
+   *   A value of zero means no limit
+   * @param int $offset
+   *
+   * @return bool
+   */
+  public static function runJob(\CRM_Queue_TaskContext $taskContext, int $userJobID, int $limit, int $offset): bool;
+
+}
index a809266fe8a9937af3729d8800625023137e428d..379b34c08c0ae8569f5b18daa0cda5295c253a06 100644 (file)
@@ -381,7 +381,7 @@ class QueueTest extends Api4TestBase {
     $this->assertEquals(0, $queue->numberOfItems());
 
     $userJob = \Civi\Api4\UserJob::create(FALSE)->setValues([
-      'job_type:label' => 'Contact Import',
+      'job_type:name' => 'contact_import',
       'status_id:name' => 'in_progress',
       'queue_id.name' => $queue->getName(),
     ])->execute()->single();