diff --git a/src/api/endpoints/class-tainacan-rest-exporters-controller.php b/src/api/endpoints/class-tainacan-rest-exporters-controller.php index 63f94593a..3e93d9f2f 100644 --- a/src/api/endpoints/class-tainacan-rest-exporters-controller.php +++ b/src/api/endpoints/class-tainacan-rest-exporters-controller.php @@ -12,68 +12,76 @@ use Tainacan\Entities; * */ class REST_Exporters_Controller extends REST_Controller { - /** - * REST_Exporters_Controller constructor. - * Define the namespace, rest base and instantiate your attributes. - */ - public function __construct() { - $this->rest_base = 'exporters'; - if (session_status() == PHP_SESSION_NONE) { - @session_start(); // @ avoids Warnings when running phpunit tests - } - parent::__construct(); - } + /** + * REST_Exporters_Controller constructor. + * Define the namespace, rest base and instantiate your attributes. + */ + public function __construct() { + $this->rest_base = 'exporters'; + if (session_status() == PHP_SESSION_NONE) { + @session_start(); // @ avoids Warnings when running phpunit tests + } + parent::__construct(); + } - /** - * Register the collections route and their endpoints - */ - public function register_routes() { - register_rest_route($this->namespace, '/' . $this->rest_base . '/available', array( - array( - 'methods' => \WP_REST_Server::READABLE, - 'callback' => array($this, 'get_registered_exporters'), - 'permission_callback' => array($this, 'export_permissions_check'), - ), - )); + /** + * Register the collections route and their endpoints + */ + public function register_routes() { + register_rest_route($this->namespace, '/' . $this->rest_base . '/available', array( + array( + 'methods' => \WP_REST_Server::READABLE, + 'callback' => array($this, 'get_registered_exporters'), + 'permission_callback' => array($this, 'export_permissions_check'), + ), + )); - register_rest_route($this->namespace, '/' . $this->rest_base . '/session', array( - array( - 'methods' => \WP_REST_Server::CREATABLE, - 'callback' => array($this, 'create_item'), - 'permission_callback' => array($this, 'export_permissions_check'), - 'args' => [ - 'importer_slug' => [ - 'type' => 'string', - 'description' => __( 'The slug of the exporter to be initialized', 'tainacan' ), - ] - ], - ), - )); + register_rest_route($this->namespace, '/' . $this->rest_base . '/session', array( + array( + 'methods' => \WP_REST_Server::CREATABLE, + 'callback' => array($this, 'create_item'), + 'permission_callback' => array($this, 'export_permissions_check'), + 'args' => [ + 'importer_slug' => [ + 'type' => 'string', + 'description' => __( 'The slug of the exporter to be initialized', 'tainacan' ), + ] + ], + ), + )); - register_rest_route($this->namespace, '/' . $this->rest_base . '/session/(?P[0-9a-f]+)', array( - array( - 'methods' => \WP_REST_Server::EDITABLE, - 'callback' => array($this, 'update_item'), - 'permission_callback' => array($this, 'export_permissions_check'), - 'args' => [ - 'send_email' => [ - 'type' => 'string', - 'description' => __( 'The e-mail to be used by the export to send a message when the process ends', 'tainacan' ), - ], - 'collection' => [ - 'type' => 'array/object', - 'description' => __( 'The array describing the collection as expected by the exporter', 'tainacan' ), - ], - 'options' => [ - 'type' => 'array/object', - 'description' => __( 'The importer options', 'tainacan' ), - ] - ], - ), - - )); - } + register_rest_route($this->namespace, '/' . $this->rest_base . '/session/(?P[0-9a-f]+)', array( + array( + 'methods' => \WP_REST_Server::EDITABLE, + 'callback' => array($this, 'update_item'), + 'permission_callback' => array($this, 'export_permissions_check'), + 'args' => [ + 'send_email' => [ + 'type' => 'string', + 'description' => __( 'The e-mail to be used by the export to send a message when the process ends', 'tainacan' ), + ], + 'collection' => [ + 'type' => 'array/object', + 'description' => __( 'The array describing the collection as expected by the exporter', 'tainacan' ), + ], + 'options' => [ + 'type' => 'array/object', + 'description' => __( 'The importer options', 'tainacan' ), + ] + ], + ), + )); + + register_rest_route($this->namespace, '/' . $this->rest_base . '/session/(?P[0-9a-f]+)/run', array( + array( + 'methods' => \WP_REST_Server::CREATABLE, + 'callback' => array($this, 'run'), + 'permission_callback' => array($this, 'export_permissions_check'), + ), + )); + + } /** * @@ -86,34 +94,6 @@ class REST_Exporters_Controller extends REST_Controller { return true; } - public function run($request) { - $session_id = $request['session_id']; - $exporter = $_SESSION['tainacan_importer'][$session_id]; - - if(!$exporter) { - return new \WP_REST_Response([ - 'error_message' => __('Exporter Session not found', 'tainacan' ), - 'session_id' => $session_id - ], 400); - } - - global $Tainacan_Exporter_Handler; - $process = $Tainacan_Exporter_Handler->add_to_queue($exporter); - - if (false === $process) { - return new \WP_REST_Response([ - 'error_message' => __('Error starting importer', 'tainacan' ), - 'session_id' => $session_id - ], 400); - } - - $response = [ - 'bg_process_id' => $process->ID - ]; - return new \WP_REST_Response( $response, 200 ); - - } - public function get_registered_exporters() { global $Tainacan_Exporter_Handler; $exporters = $Tainacan_Exporter_Handler->get_registered_exporters(); @@ -201,6 +181,39 @@ class REST_Exporters_Controller extends REST_Controller { 'body' => $body ], 400); } + + /** + * Run a exporter + * + * @param \WP_REST_Request $request + * + * @return string|\WP_Error|\WP_REST_Response + */ + public function run($request) { + $session_id = $request['session_id']; + $exporter = $_SESSION['tainacan_exporter'][$session_id]; + + if(!$exporter) { + return new \WP_REST_Response([ + 'error_message' => __('Exporter Session not found', 'tainacan' ), + 'session_id' => $session_id + ], 400); + } + + global $Tainacan_Exporter_Handler; + $process = $Tainacan_Exporter_Handler->add_to_queue($exporter); + if (false === $process) { + return new \WP_REST_Response([ + 'error_message' => __('Error starting exporter', 'tainacan' ), + 'session_id' => $session_id + ], 400); + } + $response = [ + 'bg_process_id' => $process->ID + ]; + return new \WP_REST_Response( $response, 200 ); + } + } ?> diff --git a/src/exporter/class-tainacan-csv.php b/src/exporter/class-tainacan-csv.php index ed22b8978..3c2955c03 100644 --- a/src/exporter/class-tainacan-csv.php +++ b/src/exporter/class-tainacan-csv.php @@ -2,25 +2,44 @@ namespace Tainacan\Exporter; use Tainacan; +use Tainacan\Entities; class CSV extends Exporter { - public function __construct($attributes = array()) { - parent::__construct($attributes); - } + public function __construct($attributes = array()) { + parent::__construct($attributes); + $this->set_mapping_method('any'); + } - public function process_item( $index, $collection_definition ) { - $this->add_error_log('passou aqui!'); - return false; - } - - public function options_form() { - ob_start(); - ?> -
-

Priemiro teste da construção de um Exporter!

-
- 12, + 'paged' => $index+1, + 'order' => 'DESC' + ]; + + $this->add_log('Proccessing item index ' . $index . ' in collection ' . $collection_definition['id'] ); + $items = $tainacan_items->fetch($filters, $collection_id, 'WP_Query'); + $export_items = ""; + while ($items->have_posts()) { + $items->the_post(); + $item = new Entities\Item($items->post); + $export_items .= json_encode($item); + } + wp_reset_postdata(); + return $export_items; + } + + public function options_form() { + ob_start(); + ?> +
+

Priemiro teste da construção de um Exporter!

+
+ id = uniqid(); + $author = get_current_user_id(); + if($author) { + $this->add_transient('author', $author); + } + } - /** - * The ID for this exporter session - * - * When creating a new exporter session via API, an id is returned and used to access this - * exporter instance in the SESSION array - * - * @var identifier - */ - private $id; - /** - * The path to the temporary file created when user uploads a file - * @var string + * The ID for this importer/exporter session + * + * When creating a new importer/exporter session via API, an id is returned and used to access this + * importer/exporter instance in the SESSION array + * + * @var identifier */ - protected $tmp_file; // NÃO VAI EXISTIR! - - + protected $id; + + /** + * Stores the options for the importer/exporter. Each importer/exporter might use this property to save + * their own specific option + * @var array + */ + protected $options = []; + + /** + * Stores the default options for the importer/exporter options + * @var array + */ + protected $default_options = []; + + /** + * Declares what are the steps the importer/exporter will run, in the right order. + * + * By default, there is only one step, and the callback is the process_collections method + * that process items for the collections in the collections array. + * + * Child classes may declare as many steps as they want and can keep this default step to use + * this method for importer/exporter the items. But it is optional. + * + * @var array + */ + protected $steps = [ + [ + 'name' => 'Process Items', + 'progress_label' => 'Process Items', + 'callback' => 'process_collections' + ] + ]; + /** * This array holds the structure that the default step 'process_collections' will handle. * - * Its an array of the target collections, with their IDs, an identifier from the source, the total number of items to be imported, the mapping array + * Its an array of the target collections, with their IDs, an identifier from the source, the total number of items to be importer/exporter, the mapping array * from the source structure to the ID of the metadata metadata in tainacan * * The format of the map is an array where the keys are the metadata IDs of the destination collection and the - * values are the identifier from the source. This could be an ID or a string or whatever the importer finds appropriate to handle + * values are the identifier from the source. This could be an ID or a string or whatever the importer/exporter finds appropriate to handle * * The source_id can be anyhting you like, that helps you relate this collection to your source. * @@ -50,315 +86,14 @@ abstract class Exporter { * @var array */ protected $collections = []; - - /** - * Stores the options for the importer. Each importer might use this property to save - * their own specific option - * @var array - */ - private $options = []; - - /** - * Stores the default options for the importer options - * @var array - */ - protected $default_options = []; - - private $accepts = [ - 'file' => true, - 'url' => false, - ]; - - /** - * Declares what are the steps the importer will run, in the right order. - * - * By default, there is only one step, and the callback is the process_collections method - * that process items for the collections in the collections array. - * - * Child classes may declare as many steps as they want and can keep this default step to use - * this method for import the items. But it is optional. - * - * @var array - */ - protected $steps = [ - [ - 'name' => 'Import Items', - 'progress_label' => 'Importing Items', - 'callback' => 'process_collections' - ] - ]; - - /** - * Transients is used to store temporary data to be used accross multiple requests - * - * Add and remove transient data using add_transient() and delete_transient() methods - * - * Transitens can be strings, numbers or arrays. Avoid storing objects. - * - * @var array - */ - private $transients = []; - private $current_step = 0; - - private $in_step_count = 0; - - private $current_collection = 0; - - private $current_collection_item = 0; - - private $url = ''; - - private $log = []; - - private $error_log = []; - - /** - * Wether to abort importer execution. - * @var bool - */ - private $abort = false; - - /** - * List of attributes that are saved in DB and that are used to - * reconstruct the object - * @var array - */ - private $array_attributes = [ - 'url', - 'current_collection_item', - 'current_collection', - 'in_step_count', - 'current_step', - 'transients', - 'options', - 'collections', - 'tmp_file' - ]; - - public function __construct($attributess = array()) { - if (!session_id()) { - @session_start(); - } - - $this->id = uniqid(); - $author = get_current_user_id(); - if($author) { - $this->add_transient('author', $author); - } - - $_SESSION['tainacan_exporter'][$this->get_id()] = $this; - if (!empty($attributess)) { - foreach ($attributess as $attr => $value) { - $method = 'set_' . $attr; - if (method_exists($this, $method)) { - $this->$method($value); - } - } - } - } - - public function _to_Array($short = false) { - $return = ['id' => $this->get_id()]; - foreach ($this->array_attributes as $attr) { - $method = 'get_' . $attr; - $return[$attr] = $this->$method(); - } - $return['class_name'] = get_class($this); - - global $Tainacan_Exporter_Handler; - $exporter_definition = $Tainacan_Exporter_Handler->get_exporter_by_object($this); - - if ($short === false) { - $return['manual_collection'] = $exporter_definition['manual_collection']; - $return['manual_mapping'] = $exporter_definition['manual_mapping']; - $return['accepts'] = $this->accepts; - $return['options_form'] = $this->options_form(); - } - - return $return; - } - - ///////////////////// - // Getters and setters - - /** - * @return string - */ - public function get_id(){ - return $this->id; - } - - /** - * Set URL - * @param $url string - * @return bool - */ - public function set_url($url) - { - if(!empty($url) && !is_array($url)) - { - $this->url = rtrim(trim($url), "/"); - return true; - } - - return false; - } - - /** - * @return string or bool - */ - public function get_url() - { - if(!empty($this->url)) - { - return $this->url; - } - - return false; - } - - public function get_current_step() { - return $this->current_step; - } - - public function set_current_step($value) { - $this->current_step = $value; - } - - public function get_in_step_count() { - return $this->in_step_count; - } - - public function set_in_step_count($value) { - $this->in_step_count = $value; - } - - public function get_current_collection() { - return $this->current_collection; - } - - public function set_current_collection($value) { - $this->current_collection = $value; - } - - public function get_current_collection_item() { - return $this->current_collection_item; - } - - public function set_current_collection_item($value) { - $this->current_collection_item = $value; - } - - public function get_tmp_file(){ - return $this->tmp_file; - } - - public function set_tmp_file($filepath){ - $this->tmp_file = $filepath; - } - - public function get_collections() { - return $this->collections; - } - - public function set_collections($value) { - $this->collections = $value; - } - - /** - * Gets the options for this importer, including default values for options - * that were not set yet. - * @return array Importer options - */ - public function get_options() { - return array_merge($this->default_options, $this->options); - } - - /** - * Set the options array - * @param array $options - */ - public function set_options($options) { - $this->options = $options; - } - - /** - * Set the default options values. - * - * Must be called from the __construct method of the child importer class to set default values. - * - * @param array $options - */ - protected function set_default_options($options) { - $this->default_options = $options; - } - - - public function set_steps($steps) { - $this->steps = $steps; - } - - public function get_steps() { - return $this->steps; - } - - - private function get_transients() { - return $this->transients; - } - - private function set_transients(array $data) { - $this->transients = $data; - } - - public function get_log() { - return $this->log; - } - - public function get_error_log() { - return $this->error_log; - } - - //////////////////////////////////// - // Utilities - - - /** - * @param $file File to be managed by importer - * @return bool - */ - public function add_file( $file ){ - $new_file = $this->upload_file( $file ); - if ( is_numeric( $new_file ) ) { - $this->tmp_file = get_attached_file( $new_file ); - return true; - } else { - return false; - } - } - - - /** - * log the actions from importer - * - * @param $type - * @param $messagelog - */ - public function add_log($message ){ - $this->log[] = $message; - } - public function add_error_log($message ){ - $this->error_log[] = $message; - } - public function add_collection(array $collection) { if (isset($collection['id'])) { $this->remove_collection($collection['id']); $this->collections[] = $collection; } } - + public function remove_collection($col_id) { foreach ($this->get_collections() as $index => $col) { if ($col['id'] == $col_id) { @@ -368,81 +103,212 @@ abstract class Exporter { } } - /** - * internal function to upload the file - * - * @param $path_file - * @return array $response - */ - private function upload_file( $file_array ){ - //$name = basename( $path_file ); - //$file_array['name'] = $name; - //$file_array['tmp_name'] = $path_file; - //$file_array['size'] = filesize( $path_file ); - - if ( !function_exists('media_handle_upload') ) { - require_once(ABSPATH . "wp-admin" . '/includes/image.php'); - require_once(ABSPATH . "wp-admin" . '/includes/file.php'); - require_once(ABSPATH . "wp-admin" . '/includes/media.php'); + public function next_item() { + $current_collection = $this->get_current_collection(); + $current_collection_item = $this->get_current_collection_item(); + $collections = $this->get_collections(); + $collection = $collections[$current_collection]; + $current_collection_item ++; + $this->set_current_collection_item($current_collection_item); + if ($current_collection_item >= $collection['total_items']) { + return $this->next_collection(); } - //var_dump(media_handle_sideload( $file_array, 0 )); die; - return media_handle_sideload( $file_array, 0 ); - } + return $current_collection_item; + } - /** - * get the content form url and creates a file - * - * @param $url - * @return array - */ - public function fetch_from_remote( $url ){ - $tmp = wp_remote_get( $url ); - if( !is_wp_error($tmp) && isset( $tmp['body'] ) ){ - $file = fopen( $this->get_id().'.txt', 'w' ); - fwrite( $file, $tmp['body'] ); - fclose( $file ); - return $this->add_file( $this->get_id().'.txt' ); - } - } - - /** - * Gets one option from the options array. - * - * Checks if option exist or if it have a default value. Otherwise return an empty string - * - * @param string $key the desired option - * @return mixed the option value, the default value or an empty string - */ - public function get_option($key) { - $options = $this->get_options(); - return isset($options[$key]) ? $options[$key] : ''; - } + public function next_collection() { + $current_collection = $this->get_current_collection(); + $collections = $this->get_collections(); + $this->set_current_collection_item(0); + $current_collection ++; + if (isset($collections[$current_collection])) { + $this->set_current_collection($current_collection); + return $current_collection; + } + return false; + } + + /** + * Transients is used to store temporary data to be used accross multiple requests + * + * Add and remove transient data using add_transient() and delete_transient() methods + * + * Transitens can be strings, numbers or arrays. Avoid storing objects. + * + * @var array + */ + protected $transients = []; + + /** + * Wether to abort importer/exporter execution. + * @var bool + */ + protected $abort = false; + + protected $current_step = 0; + protected $in_step_count = 0; + + protected $current_collection = 0; + protected $current_collection_item = 0; + + protected $log = []; + protected $error_log = []; + + /** + * List of attributes that are saved in DB and that are used to + * reconstruct the object, this property need be overwrite in custom import/export. + * @var array + */ + protected $array_attributes = [ + 'in_step_count', + 'current_step', + 'transients', + 'options', + 'collections', + ]; + + /** + * @return string + */ + public function get_id(){ + return $this->id; + } + + public function get_current_step() { + return $this->current_step; + } + public function set_current_step($value) { + $this->current_step = $value; + } + + public function get_in_step_count() { + return $this->in_step_count; + } + + public function set_in_step_count($value) { + $this->in_step_count = $value; + } + + public function get_current_collection() { + return $this->current_collection; + } + + public function set_current_collection($value) { + $this->current_collection = $value; + } + + public function get_current_collection_item() { + return $this->current_collection_item; + } + + public function set_current_collection_item($value) { + $this->current_collection_item = $value; + } + + public function get_collections() { + return $this->collections; + } + + public function set_collections($value) { + $this->collections = $value; + } + + /** + * Gets the options for this import/export, including default values for options + * that were not set yet. + * @return array import/export options + */ + public function get_options() { + return array_merge($this->default_options, $this->options); + } + + /** + * Set the options array + * @param array $options + */ + public function set_options($options) { + $this->options = $options; + } + + /** + * Gets one option from the options array. + * + * Checks if option exist or if it have a default value. Otherwise return an empty string + * + * @param string $key the desired option + * @return mixed the option value, the default value or an empty string + */ + public function get_option($key) { + $options = $this->get_options(); + return isset($options[$key]) ? $options[$key] : ''; + } + + /** + * Set the default options values. + * + * Must be called from the __construct method of the child import/export class to set default values. + * + * @param array $options + */ + protected function set_default_options($options) { + $this->default_options = $options; + } + + public function set_steps($steps) { + $this->steps = $steps; + } + + public function get_steps() { + return $this->steps; + } + + protected function get_transients() { + return $this->transients; + } + + protected function set_transients(array $data) { + $this->transients = $data; + } + public function add_transient($key, $data) { $this->transients[$key] = $data; } - + public function delete_transient($key) { if (isset($this->transients[$key])) unset($this->transients[$key]); } - + public function get_transient($key) { if (isset($this->transients[$key])) return $this->transients[$key]; return null; } - public function is_finished() - { - if($this->current_step >= count($this->steps)) - { - return true; - } + public function get_log() { + return $this->log; + } + + public function get_error_log() { + return $this->error_log; + } + + public function add_log($message ) { + $this->log[] = $message; + } + + public function add_error_log($message ) { + $this->error_log[] = $message; + } + + public function is_finished() { + if($this->current_step >= count($this->steps)) { + return true; + } + return false; + } - return false; - } - /** * Cancel Scheduled abortion at the end of run() * @return void @@ -450,7 +316,7 @@ abstract class Exporter { protected function cancel_abort() { $this->abort = false; } - + /** * Schedule importer abortion at the end of run() * @return void @@ -458,7 +324,7 @@ abstract class Exporter { protected function abort() { $this->abort = true; } - + /** * Return wether importer should abort execution or not * @return bool @@ -473,7 +339,7 @@ abstract class Exporter { * * It automatically gets the attribute progress_label from the current step running. * - * Importers may change this label whenever they want + * Importers/Exporters may change this label whenever they want * * @return string */ @@ -500,7 +366,6 @@ abstract class Exporter { } return $label; - } /** @@ -526,14 +391,11 @@ abstract class Exporter { if ( isset($steps[$current_step]) ) { $step = $steps[$current_step]; - if ($step['callback'] == 'process_collections') { - $totalItems = 0; $currentItem = $this->get_current_collection_item(); $current_collection = $this->get_current_collection(); $collections = $this->get_collections(); - foreach ($collections as $i => $col) { if ( isset($col['total_items']) && is_integer($col['total_items']) ) { $totalItems += $col['total_items']; @@ -542,22 +404,15 @@ abstract class Exporter { } } } - if ($totalItems > 0) { $value = round( ($currentItem/$totalItems) * 100 ); } - - } else { - if ( isset($step['total']) && is_integer($step['total']) && $step['total'] > 0 ) { $current = $this->get_in_step_count(); $value = round( ($current/$step['total']) * 100 ); } - } - - } return $value; } @@ -592,36 +447,82 @@ abstract class Exporter { } } + protected function next_step() { + $current_step = $this->get_current_step(); + $steps = $this->get_steps(); + $current_step ++; + $this->set_current_step($current_step); + if (isset($steps[$current_step])) { + return $current_step; + } + return false; + } - /////////////////////////////// // Abstract methods - + abstract public function _to_Array($short = false); - /** - * get the metadata of file/url to allow mapping - * should return an array - * - * Used when $manual_mapping is set to true, to build the mapping interface - * - * @return array $metadata_source the metadata from the source - */ - public function get_source_metadata() {} - - /** - * get values for a single item - * - * @param $index - * @return array with metadatum_source's as the index and values for the - * item - * - * Ex: [ 'Metadatum1' => 'value1', 'Metadatum2' => [ 'value2','value3' ] - */ - abstract public function process_item( $index, $collection_id ); +} - +//////////////////////////////////// +class Exporter extends CommunImportExport { + private $output_files = []; + private $mapping_accept = [ + 'any' => true, + 'list' => false, + 'none' => false, + ]; + private $mapping_list = []; + + public function __construct($attributess = array()) { + $this->array_attributes = array_merge($this->array_attributes, ['current_collection_item', 'current_collection']); + parent::__construct(); + $_SESSION['tainacan_exporter'][$this->get_id()] = $this; + if (!empty($attributess)) { + foreach ($attributess as $attr => $value) { + $method = 'set_' . $attr; + if (method_exists($this, $method)) { + $this->$method($value); + } + } + } + } + + public function _to_Array($short = false) { + $return = ['id' => $this->get_id()]; + foreach ($this->array_attributes as $attr) { + $method = 'get_' . $attr; + $return[$attr] = $this->$method(); + } + $return['class_name'] = get_class($this); + + global $Tainacan_Exporter_Handler; + $exporter_definition = $Tainacan_Exporter_Handler->get_exporter_by_object($this); + + if ($short === false) { + $return['manual_collection'] = $exporter_definition['manual_collection']; + $return['manual_mapping'] = $exporter_definition['manual_mapping']; + $return['mapping_accept'] = $this->mapping_accept; + $return['mapping_list'] = $this->mapping_list; + $return['output_files'] = $this->output_files; + $return['options_form'] = $this->options_form(); + } + + return $return; + } + /** - * Method implemented by the child importer class to return the total number of items that will be imported + * get the metadata of file/url to allow mapping + * should return an array + * + * Used when $manual_mapping is set to true, to build the mapping interface + * + * @return array $metadata_source the metadata from the source + */ + public function get_source_metadata() {} + + /** + * Method implemented by the child importer/exporter class to return the total number of items that will be imported * * Used to build the progress bar * @@ -629,216 +530,92 @@ abstract class Exporter { */ public function get_source_number_of_items() {} - /** - * Method implemented by child importer to return the HTML of the Options Form to be rendered in the Importer page + * Method implemented by child importer/exporter to return the HTML of the Options Form to be rendered in the Importer page */ public function options_form() {} - - - - //////////////////////////////////////// - // Core methods - - /** - * process an item from the collections queue - * - */ - public function process_collections() { - + + /** + * Default methods to Export + * process an item from the collections queue + */ + public function process_collections() { $current_collection = $this->get_current_collection(); $collections = $this->get_collections(); $collection_definition = isset($collections[$current_collection]) ? $collections[$current_collection] : false; $current_collection_item = $this->get_current_collection_item(); + if ( !$collection_definition || !is_array($collection_definition) || !isset($collection_definition['id']) || !isset($collection_definition['mapping']) ) { + $this->add_error_log('Collection misconfigured'); + return false; + } $this->add_log('Processing item ' . $current_collection_item); $processed_item = $this->process_item( $current_collection_item, $collection_definition ); if( $processed_item ) { - - if( is_bool($processed_item) ){ - return $this->next_item(); - } - - $this->add_log('Inserting item ' . $current_collection_item); - $this->insert( $processed_item, $current_collection ); + $this->append_to_file('exporter', $processed_item."\n"); } else { - $this->add_error_log('failed on item '. $current_collection_item ); + $this->add_error_log('failed on item '. $current_collection_item ); } - return $this->next_item(); - } - - protected function next_item() { - - $current_collection = $this->get_current_collection(); - $current_collection_item = $this->get_current_collection_item(); - $collections = $this->get_collections(); - $collection = $collections[$current_collection]; - - $current_collection_item ++; - $this->set_current_collection_item($current_collection_item); - - if ($current_collection_item >= $collection['total_items']) { - return $this->next_collection(); - } - - return $current_collection_item; - - } - - protected function next_collection() { - - $current_collection = $this->get_current_collection(); - $collections = $this->get_collections(); - - $this->set_current_collection_item(0); - - $current_collection ++; - - if (isset($collections[$current_collection])) { - $this->set_current_collection($current_collection); - return $current_collection; - } - - return false; - - - } - - protected function next_step() { - - $current_step = $this->get_current_step(); - $steps = $this->get_steps(); - - $current_step ++; - $this->set_current_step($current_step); - - if (isset($steps[$current_step])) { - return $current_step; - } - - return false; - - - } - - /** - * insert processed item from source to Tainacan - * - * @param array $processed_item Associative array with metadatum source's as index with - * its value or values - * @param integet $collection_index The index in the $this->collections array of the collection the item is beeing inserted into - * - * @return Tainacan\Entities\Item Item inserted - */ - public function insert( $processed_item, $collection_index ) { - - remove_action( 'post_updated', 'wp_save_post_revision' ); - $collections = $this->get_collections(); - $collection_definition = isset($collections[$collection_index]) ? $collections[$collection_index] : false; - if ( !$collection_definition || !is_array($collection_definition) || !isset($collection_definition['id']) || !isset($collection_definition['mapping']) ) { - $this->add_error_log('Collection misconfigured'); - return false; - } - - $collection = \Tainacan\Repositories\Collections::get_instance()->fetch($collection_definition['id']); - - $Tainacan_Metadata = \Tainacan\Repositories\Metadata::get_instance(); - $Tainacan_Item_Metadata = \Tainacan\Repositories\Item_Metadata::get_instance(); - $Tainacan_Items = \Tainacan\Repositories\Items::get_instance(); - - $Tainacan_Items->disable_logs(); - $Tainacan_Metadata->disable_logs(); - $Tainacan_Item_Metadata->disable_logs(); - - $item = new Entities\Item(); - $itemMetadataArray = []; - - if( is_array( $processed_item ) ){ - foreach ( $processed_item as $metadatum_source => $values ){ - $tainacan_metadatum_id = array_search( $metadatum_source, $collection_definition['mapping'] ); - $metadatum = $Tainacan_Metadata->fetch( $tainacan_metadatum_id ); - - if( $metadatum instanceof Entities\Metadatum ){ - $singleItemMetadata = new Entities\Item_Metadata_Entity( $item, $metadatum); // *empty item will be replaced by inserted in the next foreach - $singleItemMetadata->set_value( $values ); - $itemMetadataArray[] = $singleItemMetadata; - } else { - $this->add_error_log('Metadata ' . $metadatum_source . ' not found'); - } - - } - } - - if( !empty( $itemMetadataArray ) && $collection instanceof Entities\Collection ){ - $item->set_collection( $collection ); - - if( $item->validate() ){ - $insertedItem = $Tainacan_Items->insert( $item ); - } else { - $this->add_error_log( 'Error inserting item' ); - $this->add_error_log( $item->get_errors() ); - return false; - } - - foreach ( $itemMetadataArray as $itemMetadata ) { - $itemMetadata->set_item( $insertedItem ); // *I told you - - if( $itemMetadata->validate() ){ - $result = $Tainacan_Item_Metadata->insert( $itemMetadata ); - } else { - $this->add_error_log('Error saving value for ' . $itemMetadata->get_metadatum()->get_name()); - $this->add_error_log($itemMetadata->get_errors()); - continue; - } - - //if( $result ){ - // $values = ( is_array( $itemMetadata->get_value() ) ) ? implode( PHP_EOL, $itemMetadata->get_value() ) : $itemMetadata->get_value(); - // $this->add_log( 'Item ' . $insertedItem->get_id() . - // ' has inserted the values: ' . $values . ' on metadata: ' . $itemMetadata->get_metadatum()->get_name() ); - //} else { - // $this->add_error_log( 'Item ' . $insertedItem->get_id() . ' has an error' ); - //} - } - - $insertedItem->set_status('publish' ); - - if($insertedItem->validate()) { - $insertedItem = $Tainacan_Items->update( $insertedItem ); - - $this->after_inserted_item( $insertedItem, $collection_index ); - } else { - $this->add_error_log( 'Error publishing Item' ); - $this->add_error_log( $insertedItem->get_errors() ); - return false; - } - - return $insertedItem; - - } else { - $this->add_error_log( 'Collection not set'); - return false; - } - } /** - * allow importers executes process after item is insertes - * @param array $insertedItem Associative array with inserted item - * @param integer $collection_index The index in the $this->collections array of the collection the item is beeing inserted into - * + * get values for a single item + * + * @param $index + * @return array with metadatum_source's as the index and values for the + * item + * + * Ex: [ 'Metadatum1' => 'value1', 'Metadatum2' => [ 'value2','value3' ] */ - public function after_inserted_item($insertedItem, $collection_index){} + public function process_item( $index, $collection_id ) { } + + public function add_new_file($key) { + $upload_dir = wp_upload_dir(); + $upload_dir = trailingslashit( $upload_dir['basedir'] ); + $exporter_folder = $upload_dir . 'tainacan/exporter'; - /** - * runs one iteration - */ - public function run(){ + if (!is_dir($exporter_folder)) { + if (!mkdir($exporter_folder)) { + return false; + } + } + $file_name = "$exporter_folder/file_".date('m-d-Y_hia'); + $this->output_files[$key] = $file_name; + } + public function append_to_file($key, $data) { + if ( array_key_exists ( $key , $this->output_files ) ) { + $fp = fopen($this->output_files[$key], 'a'); + fwrite($fp, $data); + fclose($fp); + } else { // será? + $this->add_new_file($key); + $this->append_to_file($key, $data); + } + } + + public function set_mapping_method($method, $list = []) { + if ( array_key_exists($method, $this->mapping_accept) ) { + foreach ($this->mapping_accept as &$value) { + $value = false; + } + $this->mapping_accept[$method] = true; + if(!empty($list)) { + $this->mapping_list = $list; + } + return true; + } + return false; + } + + /** + * runs one iteration + */ + public function run() { if ($this->is_finished()) { return false; } - $steps = $this->get_steps(); $current_step = $this->get_current_step(); $method_name = $steps[$current_step]['callback']; @@ -860,9 +637,6 @@ abstract class Exporter { $this->set_in_step_count($result); $return = $result; } - return $return; - - - } + } } \ No newline at end of file