From 3764aead6567285d0df10dc508c6ae745a80cc61 Mon Sep 17 00:00:00 2001 From: Eileen McNaughton Date: Tue, 28 Jun 2022 22:42:47 +1200 Subject: [PATCH] Fix Parser classes to use ClassScanner --- CRM/Activity/Import/Parser/Activity.php | 20 +++++++ CRM/Contact/Import/Parser/Contact.php | 19 +++++++ CRM/Contribute/Import/Parser/Contribution.php | 20 +++++++ CRM/Core/BAO/UserJob.php | 55 ++++++------------- CRM/Custom/Import/Parser/Api.php | 19 +++++++ CRM/Event/Import/Parser/Participant.php | 19 +++++++ CRM/Import/DataSource.php | 1 + CRM/Import/Parser.php | 11 ++-- CRM/Member/Import/Parser/Membership.php | 20 +++++++ Civi/Core/ClassScanner.php | 1 + Civi/UserJob/UserJobInterface.php | 41 ++++++++++++++ tests/phpunit/api/v4/Entity/QueueTest.php | 2 +- 12 files changed, 185 insertions(+), 43 deletions(-) diff --git a/CRM/Activity/Import/Parser/Activity.php b/CRM/Activity/Import/Parser/Activity.php index 6aada017f6..d45940f885 100644 --- a/CRM/Activity/Import/Parser/Activity.php +++ b/CRM/Activity/Import/Parser/Activity.php @@ -21,6 +21,26 @@ */ 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. */ diff --git a/CRM/Contact/Import/Parser/Contact.php b/CRM/Contact/Import/Parser/Contact.php index f5c3d1e169..3b2c0a5af1 100644 --- a/CRM/Contact/Import/Parser/Contact.php +++ b/CRM/Contact/Import/Parser/Contact.php @@ -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. * diff --git a/CRM/Contribute/Import/Parser/Contribution.php b/CRM/Contribute/Import/Parser/Contribution.php index 7784c9d955..e244fe0fc3 100644 --- a/CRM/Contribute/Import/Parser/Contribution.php +++ b/CRM/Contribute/Import/Parser/Contribution.php @@ -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 diff --git a/CRM/Core/BAO/UserJob.php b/CRM/Core/BAO/UserJob.php index 5c2af7d608..789de78b70 100644 --- a/CRM/Core/BAO/UserJob.php +++ b/CRM/Core/BAO/UserJob.php @@ -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; } } diff --git a/CRM/Custom/Import/Parser/Api.php b/CRM/Custom/Import/Parser/Api.php index 0df37ed2a2..6fc4f41a06 100644 --- a/CRM/Custom/Import/Parser/Api.php +++ b/CRM/Custom/Import/Parser/Api.php @@ -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 * diff --git a/CRM/Event/Import/Parser/Participant.php b/CRM/Event/Import/Parser/Participant.php index 86558b7dd5..8afe963e82 100644 --- a/CRM/Event/Import/Parser/Participant.php +++ b/CRM/Event/Import/Parser/Participant.php @@ -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. */ diff --git a/CRM/Import/DataSource.php b/CRM/Import/DataSource.php index 2f5fe4e6c3..744ce5c9fe 100644 --- a/CRM/Import/DataSource.php +++ b/CRM/Import/DataSource.php @@ -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 */ diff --git a/CRM/Import/Parser.php b/CRM/Import/Parser.php index bd68050996..91f20a3fb7 100644 --- a/CRM/Import/Parser.php +++ b/CRM/Import/Parser.php @@ -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) { diff --git a/CRM/Member/Import/Parser/Membership.php b/CRM/Member/Import/Parser/Membership.php index fa70d863f2..45db615fcd 100644 --- a/CRM/Member/Import/Parser/Membership.php +++ b/CRM/Member/Import/Parser/Membership.php @@ -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 diff --git a/Civi/Core/ClassScanner.php b/Civi/Core/ClassScanner.php index e5ed6d67cd..486b91e4db 100644 --- a/Civi/Core/ClassScanner.php +++ b/Civi/Core/ClassScanner.php @@ -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', '\\'); diff --git a/Civi/UserJob/UserJobInterface.php b/Civi/UserJob/UserJobInterface.php index b3d9bbc7f3..bf259bd2f5 100644 --- a/Civi/UserJob/UserJobInterface.php +++ b/Civi/UserJob/UserJobInterface.php @@ -1 +1,42 @@ ['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; + +} diff --git a/tests/phpunit/api/v4/Entity/QueueTest.php b/tests/phpunit/api/v4/Entity/QueueTest.php index a809266fe8..379b34c08c 100644 --- a/tests/phpunit/api/v4/Entity/QueueTest.php +++ b/tests/phpunit/api/v4/Entity/QueueTest.php @@ -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(); -- 2.25.1