Importer API endpoints (refs #63)
This commit is contained in:
parent
06df3788e3
commit
8a3a610e22
|
@ -0,0 +1,281 @@
|
|||
<?php
|
||||
|
||||
namespace Tainacan\API\EndPoints;
|
||||
|
||||
use \Tainacan\API\REST_Controller;
|
||||
use Tainacan\Repositories;
|
||||
use Tainacan\Entities;
|
||||
|
||||
/**
|
||||
* Represents the Importers REST Controller
|
||||
*
|
||||
* */
|
||||
class REST_Importers_Controller extends REST_Controller {
|
||||
private $collections_repository;
|
||||
private $collection;
|
||||
|
||||
/**
|
||||
* REST_Importers_Controller constructor.
|
||||
* Define the namespace, rest base and instantiate your attributes.
|
||||
*/
|
||||
public function __construct(){
|
||||
$this->rest_base = 'importers';
|
||||
parent::__construct();
|
||||
add_action('init', array(&$this, 'init_objects'), 11);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize objects after post_type register
|
||||
*/
|
||||
public function init_objects() {
|
||||
//$this->collections_repository = Repositories\Collections::get_instance();
|
||||
//$this->collection = new Entities\Collection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the collections route and their endpoints
|
||||
*/
|
||||
public function register_routes(){
|
||||
register_rest_route($this->namespace, '/' . $this->rest_base, array(
|
||||
array(
|
||||
'methods' => \WP_REST_Server::CREATABLE,
|
||||
'callback' => array($this, 'create_item'),
|
||||
'permission_callback' => array($this, 'import_permissions_check'),
|
||||
'args' => [
|
||||
'importer_slug' => [
|
||||
'type' => 'string',
|
||||
'description' => __( 'The slug of the importer to be initialized', 'tainacan' ),
|
||||
]
|
||||
],
|
||||
),
|
||||
));
|
||||
register_rest_route($this->namespace, '/' . $this->rest_base . '/(?P<session_id>[0-9a-f]+)', array(
|
||||
|
||||
array(
|
||||
'methods' => \WP_REST_Server::EDITABLE,
|
||||
'callback' => array($this, 'update_item'),
|
||||
'permission_callback' => array($this, 'import_permissions_check'),
|
||||
'args' => [
|
||||
'url' => [
|
||||
'type' => 'string',
|
||||
'description' => __( 'The URL to be used by the importer', 'tainacan' ),
|
||||
],
|
||||
'collection' => [
|
||||
'type' => 'array',
|
||||
'description' => __( 'The array describing the destination collectino as expected by the importer', 'tainacan' ),
|
||||
],
|
||||
'options' => [
|
||||
'type' => 'array',
|
||||
'description' => __( 'The importer options', 'tainacan' ),
|
||||
]
|
||||
],
|
||||
),
|
||||
|
||||
));
|
||||
|
||||
register_rest_route($this->namespace, '/' . $this->rest_base . '/(?P<session_id>[0-9a-f]+)/file', array(
|
||||
|
||||
array(
|
||||
'methods' => \WP_REST_Server::CREATABLE,
|
||||
'callback' => array($this, 'add_file'),
|
||||
'permission_callback' => array($this, 'import_permissions_check'),
|
||||
),
|
||||
|
||||
));
|
||||
|
||||
register_rest_route($this->namespace, '/' . $this->rest_base . '/(?P<session_id>[0-9a-f]+)/source_info', array(
|
||||
|
||||
array(
|
||||
'methods' => \WP_REST_Server::READABLE,
|
||||
'callback' => array($this, 'source_info'),
|
||||
'permission_callback' => array($this, 'import_permissions_check'),
|
||||
),
|
||||
|
||||
));
|
||||
|
||||
register_rest_route($this->namespace, '/' . $this->rest_base . '/(?P<session_id>[0-9a-f]+)/run', array(
|
||||
|
||||
array(
|
||||
'methods' => \WP_REST_Server::CREATABLE,
|
||||
'callback' => array($this, 'run'),
|
||||
'permission_callback' => array($this, 'import_permissions_check'),
|
||||
),
|
||||
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param \WP_REST_Request $request
|
||||
*
|
||||
* @return bool|\WP_Error
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function import_permissions_check($request){
|
||||
// TODO
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of the desired importer and returns its ID
|
||||
*
|
||||
* @param \WP_REST_Request $request
|
||||
*
|
||||
* @return array|\WP_Error|\WP_REST_Response
|
||||
*/
|
||||
public function create_item( $request ) {
|
||||
$body = json_decode($request->get_body(), true);
|
||||
|
||||
if(empty($body)){
|
||||
return new \WP_REST_Response([
|
||||
'error_message' => __('Body can not be empty.', 'tainacan'),
|
||||
], 400);
|
||||
}
|
||||
|
||||
$slug = $body['importer_slug'];
|
||||
|
||||
global $Tainacan_Importer_Handler;
|
||||
|
||||
if ($object = $Tainacan_Importer_Handler->initialize_importer($slug)) {
|
||||
$response = $object->_to_Array();
|
||||
return new \WP_REST_Response($response, 201);
|
||||
} else {
|
||||
return new \WP_REST_Response([
|
||||
'error_message' => __('Importer not found', 'tainacan'),
|
||||
], 400);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a collection
|
||||
*
|
||||
* @param \WP_REST_Request $request
|
||||
*
|
||||
* @return string|\WP_Error|\WP_REST_Response
|
||||
*/
|
||||
public function update_item( $request ) {
|
||||
$session_id = $request['session_id'];
|
||||
|
||||
$body = json_decode($request->get_body(), true);
|
||||
|
||||
if(!empty($body)){
|
||||
$attributes = [];
|
||||
|
||||
foreach ($body as $att => $value){
|
||||
$attributes[$att] = $value;
|
||||
}
|
||||
|
||||
$importer = $_SESSION['tainacan_importer'][$session_id];
|
||||
|
||||
if($importer) {
|
||||
|
||||
foreach ($body as $att => $value){
|
||||
$method = 'set_' . $att;
|
||||
if (method_exists($importer, $method)) {
|
||||
$importer->$method($value);
|
||||
}
|
||||
}
|
||||
|
||||
$response = $importer->_to_Array();
|
||||
return new \WP_REST_Response( $response, 200 );
|
||||
|
||||
}
|
||||
|
||||
return new \WP_REST_Response([
|
||||
'error_message' => __('Importer Session not found', 'tainacan' ),
|
||||
'session_id' => $session_id
|
||||
], 400);
|
||||
}
|
||||
|
||||
return new \WP_REST_Response([
|
||||
'error_message' => __('The body can not be empty', 'tainacan'),
|
||||
'body' => $body
|
||||
], 400);
|
||||
}
|
||||
|
||||
|
||||
public function source_info() {
|
||||
$session_id = $request['session_id'];
|
||||
$importer = $_SESSION['tainacan_importer'][$session_id];
|
||||
|
||||
if(!$importer) {
|
||||
return new \WP_REST_Response([
|
||||
'error_message' => __('Importer Session not found', 'tainacan' ),
|
||||
'session_id' => $session_id
|
||||
], 400);
|
||||
}
|
||||
|
||||
$response = [
|
||||
'source_metadata' => false,
|
||||
'source_total_items' => false
|
||||
];
|
||||
|
||||
if ( method_exists($importer, 'get_source_metadata') ) {
|
||||
$response['source_metadata'] = $importer->get_source_metadata();
|
||||
}
|
||||
|
||||
if ( method_exists($importer, 'get_source_number_of_items') ) {
|
||||
$response['source_total_items'] = $importer->get_source_number_of_items();
|
||||
}
|
||||
|
||||
return new \WP_REST_Response( $response, 200 );
|
||||
|
||||
}
|
||||
|
||||
public function add_file() {
|
||||
$session_id = $request['session_id'];
|
||||
$importer = $_SESSION['tainacan_importer'][$session_id];
|
||||
|
||||
if(!$importer) {
|
||||
return new \WP_REST_Response([
|
||||
'error_message' => __('Importer Session not found', 'tainacan' ),
|
||||
'session_id' => $session_id
|
||||
], 400);
|
||||
}
|
||||
|
||||
$files = $request->get_file_params();
|
||||
$headers = $request->get_headers();
|
||||
|
||||
if ( $importer->add_file($files['file']) ) {
|
||||
$response = $importer->_to_Array();
|
||||
return new \WP_REST_Response( $response, 200 );
|
||||
} else {
|
||||
return new \WP_REST_Response([
|
||||
'error_message' => __('Failed to upload file', 'tainacan' ),
|
||||
'session_id' => $session_id
|
||||
], 400);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function run() {
|
||||
$session_id = $request['session_id'];
|
||||
$importer = $_SESSION['tainacan_importer'][$session_id];
|
||||
|
||||
if(!$importer) {
|
||||
return new \WP_REST_Response([
|
||||
'error_message' => __('Importer Session not found', 'tainacan' ),
|
||||
'session_id' => $session_id
|
||||
], 400);
|
||||
}
|
||||
|
||||
global $Tainacan_Importer_Handler;
|
||||
|
||||
$process = $Tainacan_Importer_Handler->add_to_queue($importer);
|
||||
$response = [
|
||||
'bg_process_id' => $process->get_id()
|
||||
];
|
||||
return new \WP_REST_Response( $response, 200 );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -13,6 +13,7 @@ $rest_item_metadata_controller = new \Tainacan\API\EndPoints\REST_Item_Metadat
|
|||
$rest_logs_controller = new \Tainacan\API\EndPoints\REST_Logs_Controller();
|
||||
$rest_metadata_types_controller = new \Tainacan\API\EndPoints\REST_Metadata_Types_Controller();
|
||||
$rest_filter_types_controller = new \Tainacan\API\EndPoints\REST_Filter_Types_Controller();
|
||||
$rest_importers_controller = new \Tainacan\API\EndPoints\REST_Importers_Controller();
|
||||
new \Tainacan\API\EndPoints\REST_Export_Controller();
|
||||
new \Tainacan\API\EndPoints\REST_Metadatum_Mappers_Controller();
|
||||
// Add here other endpoints imports
|
||||
|
|
|
@ -31,6 +31,12 @@ abstract class Background_Process extends \WP_Background_Process {
|
|||
* @var string
|
||||
*/
|
||||
protected $table = '';
|
||||
|
||||
/**
|
||||
* ID of the process in the database
|
||||
* @var false|int
|
||||
*/
|
||||
protected $ID = false;
|
||||
|
||||
/**
|
||||
* Prefix
|
||||
|
@ -60,6 +66,10 @@ abstract class Background_Process extends \WP_Background_Process {
|
|||
global $wpdb;
|
||||
$this->table = $wpdb->prefix . 'tnc_bg_process';
|
||||
}
|
||||
|
||||
public function get_id() {
|
||||
return $this->ID;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
@ -81,6 +91,7 @@ abstract class Background_Process extends \WP_Background_Process {
|
|||
'queued_on' => date('Y-m-d H:i:s')
|
||||
]
|
||||
);
|
||||
$this->ID = $wpdb->insert_id;
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
|
|
@ -55,18 +55,20 @@ class CSV extends Importer {
|
|||
$processedItem[ $header ] = $values[ $index ];
|
||||
}
|
||||
|
||||
$this->set_progress_current($index+1);
|
||||
|
||||
return $processedItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function get_progress_total_from_source(){
|
||||
$file = new \SplFileObject( $this->tmp_file, 'r' );
|
||||
$file->seek(PHP_INT_MAX);
|
||||
// -1 removing header
|
||||
return $this->total_items = $file->key() - 1;
|
||||
public function get_source_number_of_items(){
|
||||
if (isset($this->tmp_file) && file_exists($this->tmp_file)) {
|
||||
$file = new \SplFileObject( $this->tmp_file, 'r' );
|
||||
$file->seek(PHP_INT_MAX);
|
||||
// -1 removing header
|
||||
return $this->total_items = $file->key() - 1;
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
|
@ -4,17 +4,68 @@ namespace Tainacan;
|
|||
|
||||
class Importer_Handler {
|
||||
|
||||
|
||||
private $registered_importers = [];
|
||||
|
||||
function __construct() {
|
||||
|
||||
$this->bg_importer = new Background_Importer();
|
||||
|
||||
add_action('init', array(&$this, 'init'));
|
||||
|
||||
}
|
||||
|
||||
public function init() {
|
||||
|
||||
$this->register_importer([
|
||||
'slug' => 'csv',
|
||||
'class_name' => '\Tainacan\Importer\CSV'
|
||||
]);
|
||||
|
||||
do_action('tainacan_register_importers');
|
||||
|
||||
}
|
||||
|
||||
function add_to_queue($importer_object) {
|
||||
function add_to_queue(\Tainacan\Importer\Importer $importer_object) {
|
||||
$data = $importer_object->_to_Array();
|
||||
$this->bg_importer->data($data)->save()->dispatch();
|
||||
$importer_object = $this->bg_importer->data($data)->save()->dispatch();
|
||||
return $importer_object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register Importer
|
||||
*
|
||||
* @param array $importer
|
||||
* [
|
||||
* 'slug' => 'example-importer',
|
||||
* 'class_name' => '\Tainacan\Importer\Test_Importer'
|
||||
* ]
|
||||
*/
|
||||
public function register_importer(array $importer) {
|
||||
$this->registered_importers[$importer['slug']] = $importer;
|
||||
}
|
||||
|
||||
public function unregister_importer($importer_slug) {
|
||||
unset($this->registered_importers[$importer_slug]);
|
||||
}
|
||||
|
||||
public function get_registered_importers() {
|
||||
return $this->registered_importers;
|
||||
}
|
||||
|
||||
public function get_importer($importer_slug) {
|
||||
$importers = $this->get_registered_importers();
|
||||
if (isset($importers[$importer_slug])) {
|
||||
return $importers[$importer_slug];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function initialize_importer($importer_slug) {
|
||||
$importer = $this->get_importer($importer_slug);
|
||||
if ( is_array($importer) && isset($importer['class_name']) && class_exists($importer['class_name']) ) {
|
||||
return new $importer['class_name']();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -47,17 +47,6 @@ abstract class Importer {
|
|||
protected $manual_collection = true;
|
||||
|
||||
|
||||
/**
|
||||
* The total number of iterations to be imported.
|
||||
*
|
||||
* if not possible to calculate, inform 0 (zero) and no progress bar will be displayed.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $progress_total;
|
||||
|
||||
protected $progress_current;
|
||||
|
||||
/**
|
||||
* This array holds the structure that the default step 'process_collections' will handle.
|
||||
*
|
||||
|
@ -191,7 +180,7 @@ abstract class Importer {
|
|||
}
|
||||
|
||||
public function _to_Array() {
|
||||
$return = [];
|
||||
$return = ['id' => $this->get_id()];
|
||||
foreach ($this->array_attributes as $attr) {
|
||||
$method = 'get_' . $attr;
|
||||
$return[$attr] = $this->$method();
|
||||
|
@ -279,14 +268,6 @@ abstract class Importer {
|
|||
$this->tmp_file = $filepath;
|
||||
}
|
||||
|
||||
public function get_progress_current() {
|
||||
return $this->progress_current;
|
||||
}
|
||||
|
||||
public function set_progress_current($value) {
|
||||
$this->progress_current = $value;
|
||||
}
|
||||
|
||||
public function get_collections() {
|
||||
return $this->collections;
|
||||
}
|
||||
|
@ -332,22 +313,6 @@ abstract class Importer {
|
|||
return $this->steps;
|
||||
}
|
||||
|
||||
/**
|
||||
* return the total progress number to calculate progress
|
||||
*
|
||||
* @return int Total of items
|
||||
*/
|
||||
public function get_progress_total() {
|
||||
if ( !isset( $this->progress_total ) ) {
|
||||
if ( method_exists($this, 'get_progress_total_from_source') ) {
|
||||
$this->progress_total = $this->get_progress_total_from_source();
|
||||
} else {
|
||||
$this->progress_total = 0;
|
||||
}
|
||||
|
||||
}
|
||||
return $this->progress_total;
|
||||
}
|
||||
|
||||
private function get_transients() {
|
||||
return $this->transients;
|
||||
|
@ -565,13 +530,13 @@ abstract class Importer {
|
|||
|
||||
|
||||
/**
|
||||
* Method implemented by the child importer class to return the total number of interations the importer must run
|
||||
* Method implemented by the child importer class to return the total number of items that will be imported
|
||||
*
|
||||
* Used to build the progress bar
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function get_progress_total_from_source() {}
|
||||
public function get_source_number_of_items() {}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -202,20 +202,7 @@ class Old_Tainacan extends Importer{
|
|||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method implemented by the child importer class to return the number of items to be imported
|
||||
* @return int
|
||||
*/
|
||||
public function get_progress_total_from_source(){
|
||||
}
|
||||
|
||||
/**
|
||||
* Method implemented by the child importer class to return the number of items to be imported
|
||||
* @return int
|
||||
*/
|
||||
public function get_source_metadata(){
|
||||
}
|
||||
|
||||
|
||||
// AUX functions
|
||||
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
namespace Tainacan\Tests;
|
||||
|
||||
/**
|
||||
* @group api
|
||||
*/
|
||||
class TAINACAN_REST_Importers_Controller extends TAINACAN_UnitApiTestCase {
|
||||
|
||||
public function test_create(){
|
||||
|
||||
$params = json_encode([
|
||||
'importer_slug' => 'csv'
|
||||
]);
|
||||
|
||||
|
||||
$request = new \WP_REST_Request('POST', $this->namespace . '/importers');
|
||||
$request->set_body($params);
|
||||
|
||||
$response = $this->server->dispatch($request);
|
||||
|
||||
$this->assertEquals(201, $response->get_status());
|
||||
|
||||
$data = $response->get_data();
|
||||
|
||||
|
||||
$this->assertTrue( isset($data['id']) );
|
||||
$this->assertTrue( is_string($data['id']) );
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function test_update() {
|
||||
|
||||
|
||||
$importer = new \Tainacan\Importer\CSV();
|
||||
$session_id = $importer->get_id();
|
||||
|
||||
$params = json_encode([
|
||||
'url' => 'http://test.com',
|
||||
'options' => ['delimiter' => ';']
|
||||
]);
|
||||
|
||||
$request = new \WP_REST_Request('PATCH', $this->namespace . '/importers/' . $session_id);
|
||||
$request->set_body($params);
|
||||
|
||||
$response = $this->server->dispatch($request);
|
||||
$data = $response->get_data();
|
||||
|
||||
$this->assertEquals(200, $response->get_status());
|
||||
|
||||
$__importer = $_SESSION['tainacan_importer'][$session_id];
|
||||
|
||||
$this->assertEquals('http://test.com', $__importer->get_url());
|
||||
$this->assertEquals(';', $__importer->get_option('delimiter'));
|
||||
|
||||
$this->assertEquals($__importer->get_url(), $data['url']);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -175,7 +175,7 @@ class ImporterTests extends TAINACAN_UnitTestCase {
|
|||
$this->assertTrue( !empty( $_SESSION['tainacan_importer'][$id]->get_tmp_file() ) );
|
||||
|
||||
// count size of csv
|
||||
$this->assertEquals( 5, $_SESSION['tainacan_importer'][$id]->get_progress_total_from_source() );
|
||||
$this->assertEquals( 5, $_SESSION['tainacan_importer'][$id]->get_source_number_of_items() );
|
||||
|
||||
// get metadata to mapping
|
||||
$headers = $_SESSION['tainacan_importer'][$id]->get_source_metadata();
|
||||
|
@ -195,7 +195,7 @@ class ImporterTests extends TAINACAN_UnitTestCase {
|
|||
|
||||
$collection_definition = [
|
||||
'id' => $collection->get_id(),
|
||||
'total_items' => $_SESSION['tainacan_importer'][$id]->get_progress_total_from_source(),
|
||||
'total_items' => $_SESSION['tainacan_importer'][$id]->get_source_number_of_items(),
|
||||
];
|
||||
|
||||
// get collection metadata to map
|
||||
|
@ -222,7 +222,7 @@ class ImporterTests extends TAINACAN_UnitTestCase {
|
|||
|
||||
$items = $Tainacan_Items->fetch( [], $collection, 'OBJECT' );
|
||||
|
||||
$this->assertEquals( $_SESSION['tainacan_importer'][$id]->get_progress_total_from_source(), count( $items ) );
|
||||
$this->assertEquals( $_SESSION['tainacan_importer'][$id]->get_source_number_of_items(), count( $items ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue