From cbff9aadd2b786ff3fa4bf674ca584d0f15dca0c Mon Sep 17 00:00:00 2001 From: vnmedeiros Date: Tue, 9 Oct 2018 16:17:09 -0300 Subject: [PATCH] add export CSV for items of collections using mappers --- ...ass-tainacan-rest-exporters-controller.php | 82 ++++++++++++++++++ src/exporter/class-tainacan-csv.php | 84 ++++++++++++++++++- src/exporter/class-tainacan-exporter.php | 36 +++++--- 3 files changed, 185 insertions(+), 17 deletions(-) diff --git a/src/api/endpoints/class-tainacan-rest-exporters-controller.php b/src/api/endpoints/class-tainacan-rest-exporters-controller.php index 3e93d9f2f..4f15396a6 100644 --- a/src/api/endpoints/class-tainacan-rest-exporters-controller.php +++ b/src/api/endpoints/class-tainacan-rest-exporters-controller.php @@ -5,6 +5,7 @@ namespace Tainacan\API\EndPoints; use \Tainacan\API\REST_Controller; use Tainacan\Repositories; use Tainacan\Entities; +use \Tainacan\Exposers\Mappers\Value; /** * Represents the Exporters REST Controller @@ -36,6 +37,14 @@ class REST_Exporters_Controller extends REST_Controller { 'permission_callback' => array($this, 'export_permissions_check'), ), )); + + register_rest_route($this->namespace, '/' . $this->rest_base . '/teste', array( + array( + 'methods' => \WP_REST_Server::READABLE, + 'callback' => array($this, 'teste'), + 'permission_callback' => array($this, 'export_permissions_check'), + ), + )); register_rest_route($this->namespace, '/' . $this->rest_base . '/session', array( array( @@ -213,6 +222,79 @@ class REST_Exporters_Controller extends REST_Controller { ]; return new \WP_REST_Response( $response, 200 ); } + + protected function map($item_arr, $mapper) { + $ret = $item_arr; + if(array_key_exists('metadatum', $item_arr)) { // getting a unique metadatum + $ret = $this->map_metadatum($item_arr, $mapper); + } else { // array of elements + $ret = []; + foreach ($item_arr as $item) { + if(array_key_exists('metadatum', $item)) { + $ret = array_merge($ret, $this->map($item, $mapper) ); + } else { + $ret[] = $this->map($item, $mapper); + } + } + } + return $ret; + } + + protected function map_metadatum($item_arr, $mapper) { + $ret = $item_arr; + $metadatum_mapping = $item_arr['metadatum']['exposer_mapping']; + if(array_key_exists($mapper->slug, $metadatum_mapping)) { + if( + is_string($metadatum_mapping[$mapper->slug]) && is_array($mapper->metadata) && !array_key_exists( $metadatum_mapping[$mapper->slug], $mapper->metadata) || + is_array($metadatum_mapping[$mapper->slug]) && $mapper->allow_extra_metadata != true + ) { + throw new \Exception('Invalid Mapper Option'); + } + $slug = ''; + if(is_string($metadatum_mapping[$mapper->slug])) { + $slug = $metadatum_mapping[$mapper->slug]; + } else { + $slug = $metadatum_mapping[$mapper->slug]['slug']; + } + $ret = [$mapper->prefix.$slug.$mapper->sufix => $item_arr['value']]; //TODO Validate option + } elseif($mapper->slug == 'value') { + $ret = [$item_arr['metadatum']['name'] => $item_arr['value']]; + } else { + $ret = []; + } + return $ret; + } + + public function teste() { + $filters = [ + 'posts_per_page' => 1, + 'paged' => $index+1, + 'order' => 'DESC' + ]; + $tainacan_items = \Tainacan\Repositories\Items::get_instance(); + $items = $tainacan_items->fetch($filters, 6, 'WP_Query'); + + $export_items = ""; + if ($items->have_posts()) { + $items->the_post(); + $item = new Entities\Item($items->post); + $items_metadata = $item->get_metadata(); + $prepared_item = []; + foreach ($items_metadata as $item_metadata) { + array_push($prepared_item, $item_metadata->_toArray()); + //array_push($prepared_item, $item_metadata); + } + + $mapper = 'Tainacan\\Exposers\\Mappers\\Value'; + $instance_mapper = new $mapper(); + //$instance_mapper = new Tainacan\Exposers\Mappers\Value; + //$instance_mapper = new \Tainacan\Exposers\Mappers\Value(); + + $response = $this->map($prepared_item, $instance_mapper); + //$response = $this->map($prepared_item, ['slug' => 'value']); + return new \WP_REST_Response( $response, 200 ); + } + } } diff --git a/src/exporter/class-tainacan-csv.php b/src/exporter/class-tainacan-csv.php index 3c2955c03..e3f267736 100644 --- a/src/exporter/class-tainacan-csv.php +++ b/src/exporter/class-tainacan-csv.php @@ -8,7 +8,8 @@ class CSV extends Exporter { public function __construct($attributes = array()) { parent::__construct($attributes); - $this->set_mapping_method('any'); + $this->set_mapping_method('any'); // set all method to mapping + //$this->set_mapping_method('list', [ "dublin-core" => "Tainacan\\Exposers\\Mappers\\Dublin_Core" ]); // set specific list of methods to mapping } public function process_item( $index, $collection_definition ) { @@ -16,23 +17,98 @@ class CSV extends Exporter { $tainacan_items = \Tainacan\Repositories\Items::get_instance(); $filters = [ - 'posts_per_page' => 12, + 'posts_per_page' => 1, '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); + $printCol = $index == 0; + $export_items .= $this->get_item_csv($item, $printCol); + $this->add_log('export_items ' . $export_items ); } wp_reset_postdata(); return $export_items; } + private function get_item_csv($item, $printCol) { + $items_metadata = $item->get_metadata(); + $prepared_item = []; + foreach ($items_metadata as $item_metadata) { + array_push($prepared_item, $item_metadata->_toArray()); + } + $mapper = $this->mapping_list[$this->mapping_selected]; + $instance_mapper = new $mapper(); + $data = $this->map($prepared_item, $instance_mapper); + return $this->str_putcsv($data, ',', '"', $printCol); + } + + protected function map($item_arr, $mapper) { + $ret = $item_arr; + if(array_key_exists('metadatum', $item_arr)) { // getting a unique metadatum + $ret = $this->map_metadatum($item_arr, $mapper); + } else { // array of elements + $ret = []; + foreach ($item_arr as $item) { + if(array_key_exists('metadatum', $item)) { + $ret = array_merge($ret, $this->map($item, $mapper) ); + } else { + $ret[] = $this->map($item, $mapper); + } + } + } + return $ret; + } + + protected function map_metadatum($item_arr, $mapper) { + $ret = $item_arr; + $metadatum_mapping = $item_arr['metadatum']['exposer_mapping']; + if(array_key_exists($mapper->slug, $metadatum_mapping)) { + if( + is_string($metadatum_mapping[$mapper->slug]) && is_array($mapper->metadata) && !array_key_exists( $metadatum_mapping[$mapper->slug], $mapper->metadata) || + is_array($metadatum_mapping[$mapper->slug]) && $mapper->allow_extra_metadata != true + ) { + throw new \Exception('Invalid Mapper Option'); + } + $slug = ''; + if(is_string($metadatum_mapping[$mapper->slug])) { + $slug = $metadatum_mapping[$mapper->slug]; + } else { + $slug = $metadatum_mapping[$mapper->slug]['slug']; + } + $ret = [$mapper->prefix.$slug.$mapper->sufix => $item_arr['value']]; + } elseif($mapper->slug == 'value') { + $ret = [$item_arr['metadatum']['name'] => $item_arr['value']]; + } else { + $ret = []; + } + return $ret; + } + + function str_putcsv($item, $delimiter = ',', $enclosure = '"', $printCol = false) { + // Open a memory "file" for read/write... + $fp = fopen('php://temp', 'r+'); + $out=[]; + $col=[]; + foreach ($item as $key => $value) { + $col[] = $key; + $out[] = $value; + } + if ($printCol) { + fputcsv($fp, $col, $delimiter, $enclosure); + } + fputcsv($fp, $out, $delimiter, $enclosure); + rewind($fp); + $data = fread($fp, 1048576); + fclose($fp); + return rtrim($data, "\n"); + } + public function options_form() { ob_start(); ?> diff --git a/src/exporter/class-tainacan-exporter.php b/src/exporter/class-tainacan-exporter.php index dddb2b5b3..e85befa94 100644 --- a/src/exporter/class-tainacan-exporter.php +++ b/src/exporter/class-tainacan-exporter.php @@ -469,10 +469,10 @@ class Exporter extends CommunImportExport { private $output_files = []; private $mapping_accept = [ 'any' => true, - 'list' => false, - 'none' => false, + 'list' => false ]; - private $mapping_list = []; + protected $mapping_list = []; + public $mapping_selected = ""; public function __construct($attributess = array()) { $this->array_attributes = array_merge($this->array_attributes, ['current_collection_item', 'current_collection']); @@ -488,6 +488,7 @@ class Exporter extends CommunImportExport { } } + //"Tainacan\\Exposers\\Mappers\\Value" public function _to_Array($short = false) { $return = ['id' => $this->get_id()]; foreach ($this->array_attributes as $attr) { @@ -500,12 +501,12 @@ class Exporter extends CommunImportExport { $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['manual_collection'] = $exporter_definition['manual_collection']; + $return['mapping_selected'] = $this->mapping_selected; + $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; @@ -594,21 +595,30 @@ class Exporter extends CommunImportExport { $this->append_to_file($key, $data); } } - - public function set_mapping_method($method, $list = []) { + + public function set_mapping_method($method, $default_mapping = 'value', $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)) { + if($method == 'any') { + $Tainacan_Exposers = \Tainacan\Exposers\Exposers::get_instance(); + $metadatum_mappers = $Tainacan_Exposers->get_mappers(); + $this->mapping_list = $metadatum_mappers; + } else if(!empty($list)) { $this->mapping_list = $list; } + $this->mapping_selected = $default_mapping; return true; } return false; } - + + public function set_mapping_selected($mapping_selected) { + $this->mapping_selected = $mapping_selected; + } + /** * runs one iteration */