Skip to content

Commit

Permalink
Add civiimport with Import api code for viewing import tables
Browse files Browse the repository at this point in the history
  • Loading branch information
eileenmcnaughton committed Aug 17, 2022
1 parent d71d6a8 commit 2a3bf6d
Show file tree
Hide file tree
Showing 19 changed files with 2,050 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
!/ext/payflowpro
!/ext/ckeditor4
!/ext/legacycustomsearches
!/ext/civiimport
backdrop/
bower_components
CRM/Case/xml/configuration
Expand Down
7 changes: 7 additions & 0 deletions Civi/Api4/Service/Spec/RequestSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ class RequestSpec implements \Iterator {
*/
protected $entityTableName;

/**
* @return string
*/
public function getEntityTableName(): ?string {
return $this->entityTableName;
}

/**
* @var FieldSpec[]
*/
Expand Down
2 changes: 1 addition & 1 deletion bin/regen.sh
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ php GenerateData.php

## Prune local data
$MYSQLCMD -e "DROP TABLE IF EXISTS civicrm_install_canary; DELETE FROM civicrm_cache; DELETE FROM civicrm_setting;"
$MYSQLCMD -e "DELETE FROM civicrm_extension WHERE full_name NOT IN ('sequentialcreditnotes', 'eventcart', 'greenwich', 'search', 'org.civicrm.flexmailer', 'financialacls', 'contributioncancelactions', 'recaptcha', 'ckeditor4', 'legacycustomsearches');"
$MYSQLCMD -e "DELETE FROM civicrm_extension WHERE full_name NOT IN ('sequentialcreditnotes', 'eventcart', 'greenwich', 'search', 'org.civicrm.flexmailer', 'financialacls', 'contributioncancelactions', 'recaptcha', 'ckeditor4', 'legacycustomsearches', 'civiimport');"
TABLENAMES=$( echo "show tables like 'civicrm_%'" | $MYSQLCMD | grep ^civicrm_ | xargs )

cd $CIVISOURCEDIR/sql
Expand Down
1 change: 1 addition & 0 deletions distmaker/core-ext.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ afform
authx
civicrm_admin_ui
civigrant
civiimport
contributioncancelactions
ckeditor4
eventcart
Expand Down
100 changes: 100 additions & 0 deletions ext/civiimport/Civi/Api4/Event/Subscriber/ImportSubscriber.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<?php

/**
*
* @package CRM
* @copyright CiviCRM LLC https://civicrm.org/licensing
*/
namespace Civi\Api4\Event\Subscriber;

use Civi;
use Civi\API\Event\AuthorizeEvent;
use Civi\API\Events;
use Civi\Api4\UserJob;
use Civi\Core\Event\PostEvent;
use Civi\Core\Event\GenericHookEvent;
use CRM_Core_DAO_AllCoreTables;
use Civi\Api4\Import;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Civi\API\Exception\UnauthorizedException;

/**
* Listening class that registers each Import table as an entity.
*/
class ImportSubscriber implements EventSubscriberInterface {

/**
* Get the events this class listens to.
*
* @return string[]
*/
public static function getSubscribedEvents(): array {
return [
'hook_civicrm_post' => 'on_hook_civicrm_post',
'civi.api4.entityTypes' => 'on_civi_api4_entityTypes',
'civi.api.authorize' => [['onApiAuthorize', Events::W_EARLY]],
];
}

/**
* Register each valid import as an entity
*
* @param \Civi\Core\Event\GenericHookEvent $event
*/
public static function on_civi_api4_entityTypes(GenericHookEvent $event): void {
$importEntities = Civi\BAO\Import::getImportTables();
foreach ($importEntities as $userJobID => $table) {
/** @noinspection PhpUndefinedFieldInspection */
$event->entities['Import_' . $userJobID] = [
'name' => 'Import_' . $userJobID,
'title' => ts('Import Data') . ' ' . $userJobID . (empty($table['created_by']) ? '' : '(' . $table['created_by'] . ')'),
'title_plural' => ts('Import Data') . ' ' . $userJobID,
'description' => ts('Import Job temporary data'),
'primary_key' => ['_id'],
'type' => ['Import'],
'table_name' => $table['table_name'],
'class_args' => [$userJobID],
'label_field' => '_id',
'searchable' => 'secondary',
'paths' => [
// 'browse' => "civicrm/eck/entity/list/{$entity_type['name']}",
// 'view' => "civicrm/eck/entity?reset=1&action=view&type={$entity_type['name']}&id=[id]",
// 'update' => "civicrm/eck/entity/edit/{$entity_type['name']}/[subtype:name]#?{$entity_type['entity_name']}=[id]",
// 'add' => "civicrm/eck/entity/edit/{$entity_type['name']}/[subtype:name]",
],
'class' => Import::class,
'icon' => 'fa-upload',
];
}
}

/**
* Callback for hook_civicrm_post().
*/
public function on_hook_civicrm_post(PostEvent $event): void {
if ($event->entity === 'UserJob' && $event->action === 'create') {
// Flush entities cache key so our new Import will load as an entity.
Civi::cache('metadata')->set('api4.entities.info', NULL);
CRM_Core_DAO_AllCoreTables::flush();
}
}

/**
* @param \Civi\API\Event\AuthorizeEvent $event
* API authorization event.
*
* @throws \CRM_Core_Exception
* @throws \Civi\API\Exception\UnauthorizedException
*/
public function onApiAuthorize(AuthorizeEvent $event): void {
$apiRequest = $event->getApiRequest();
$entity = $apiRequest['entity'];
if (strpos($entity, 'Import_') === 0) {
$userJobID = (int) (str_replace('Import_', '', $entity));
if (!UserJob::get(TRUE)->addWhere('id', '=', $userJobID)->selectRowCount()->execute()->count()) {
throw new UnauthorizedException('Import access not permitted');
}
}
}

}
137 changes: 137 additions & 0 deletions ext/civiimport/Civi/Api4/Import.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
<?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\Api4;

use Civi\Api4\Generic\BasicReplaceAction;
use Civi\Api4\Generic\CheckAccessAction;
use Civi\Api4\Generic\DAOCreateAction;
use Civi\Api4\Generic\DAODeleteAction;
use Civi\Api4\Generic\DAOGetAction;
use Civi\Api4\Generic\DAOGetFieldsAction;
use Civi\Api4\Action\GetActions;
use Civi\Api4\Import\Save;
use Civi\Api4\Import\Update;

/**
* Import entity.
*
* @searchable secondary
* @since 5.54
* @package Civi\Api4
*/
class Import {

/**
* @param int $userJobID
* @param bool $checkPermissions
*
* @return \Civi\Api4\Generic\DAOGetFieldsAction
*/
public static function getFields(int $userJobID, bool $checkPermissions = TRUE): DAOGetFieldsAction {
return (new DAOGetFieldsAction('Import_' . $userJobID, __FUNCTION__))
->setCheckPermissions($checkPermissions);
}

/**
* @param int $userJobID
* @param bool $checkPermissions
* @return \Civi\Api4\Generic\DAOGetAction
* @throws \CRM_Core_Exception
*/
public static function get(int $userJobID, bool $checkPermissions = TRUE): DAOGetAction {
return (new DAOGetAction('Import_' . $userJobID, __FUNCTION__))
->setCheckPermissions($checkPermissions);
}

/**
* @param int $userJobID
* @param bool $checkPermissions
* @return \Civi\Api4\Import\Save
* @throws \API_Exception
*/
public static function save(int $userJobID, bool $checkPermissions = TRUE): Save {
return (new Save('Import_' . $userJobID, __FUNCTION__))
->setCheckPermissions($checkPermissions);
}

/**
* @param int $userJobID
* @param bool $checkPermissions
* @return \Civi\Api4\Generic\DAOCreateAction
* @throws \API_Exception
*/
public static function create(int $userJobID, bool $checkPermissions = TRUE): DAOCreateAction {
return (new DAOCreateAction('Import_' . $userJobID, __FUNCTION__))
->setCheckPermissions($checkPermissions);
}

/**
* @param int $userJobID
* @param bool $checkPermissions
* @return \Civi\Api4\Import\Update
* @throws \API_Exception
*/
public static function update(int $userJobID, bool $checkPermissions = TRUE): Update {
return (new Update('Import_' . $userJobID, __FUNCTION__))
->setCheckPermissions($checkPermissions);
}

/**
* @param int $userJobID
* @param bool $checkPermissions
* @return \Civi\Api4\Generic\DAODeleteAction
* @throws \API_Exception
*/
public static function delete(int $userJobID, bool $checkPermissions = TRUE): DAODeleteAction {
return (new DAODeleteAction('Import_' . $userJobID, __FUNCTION__))
->setCheckPermissions($checkPermissions);
}

/**
* @param int $userJobID
* @param bool $checkPermissions
* @return \Civi\Api4\Generic\BasicReplaceAction
* @throws \API_Exception
*/
public static function replace(int $userJobID, bool $checkPermissions = TRUE): BasicReplaceAction {
return (new BasicReplaceAction('Import_' . $userJobID, __FUNCTION__))
->setCheckPermissions($checkPermissions);
}

/**
* @param int $userJobID
* @param bool $checkPermissions
* @return \Civi\Api4\Action\GetActions
*/
public static function getActions(int $userJobID, bool $checkPermissions = TRUE): GetActions {
return (new GetActions('Import_' . $userJobID, __FUNCTION__))
->setCheckPermissions($checkPermissions);
}

/**
* @param int $userJobID
* @return \Civi\Api4\Generic\CheckAccessAction
* @throws \API_Exception
*/
public static function checkAccess(int $userJobID): CheckAccessAction {
return new CheckAccessAction('Import_' . $userJobID, __FUNCTION__);
}

/**
* We need to implement these elsewhere as we permit based on 'created_id'.
*
* @return array
*/
public static function permissions(): array {
return [];
}

}
50 changes: 50 additions & 0 deletions ext/civiimport/Civi/Api4/Import/Save.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?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\Api4\Import;

use Civi\Api4\Generic\Traits\DAOActionTrait;
use Civi\Api4\Generic\AbstractSaveAction;
use Civi\Api4\Generic\Result;

class Save extends AbstractSaveAction {
use DAOActionTrait;

/**
* Import save action.
*
* This is copied from `DAOSaveAction` to add the user_job_id to the array & to
* the reference to '_id' not 'id'.
*
* @inheritDoc
* @throws \CRM_Core_Exception
*/
public function _run(Result $result): void {
$userJobID = str_replace('Import_', '', $this->_entityName);
$this->defaults['user_job_id'] = (int) $userJobID;
/** @noinspection AlterInForeachInspection */
foreach ($this->records as &$record) {
$record += $this->defaults;
$this->formatWriteValues($record);
$this->matchExisting($record);
if (empty($record['_id'])) {
$this->fillDefaults($record);
}
}
$this->validateValues();

$resultArray = $this->writeObjects($this->records);

$result->exchangeArray($resultArray);
}

}
24 changes: 24 additions & 0 deletions ext/civiimport/Civi/Api4/Import/Update.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php
namespace Civi\Api4\Import;

use Civi\Api4\Generic\DAOUpdateAction;

class Update extends DAOUpdateAction {

/**
* Update import table records.
*
* @param array $items
* @return array
* @throws \API_Exception
* @throws \CRM_Core_Exception
*/
protected function updateRecords(array $items): array {
$userJobID = str_replace('Import_', '', $this->_entityName);
foreach ($items as &$item) {
$item['user_job_id'] = (int) $userJobID;
}
return parent::updateRecords($items);
}

}
Loading

0 comments on commit 2a3bf6d

Please sign in to comment.