diff --git a/src/api/endpoints/class-tainacan-rest-fields-controller.php b/src/api/endpoints/class-tainacan-rest-fields-controller.php index 578d07ea3..8e2630e35 100644 --- a/src/api/endpoints/class-tainacan-rest-fields-controller.php +++ b/src/api/endpoints/class-tainacan-rest-fields-controller.php @@ -4,7 +4,6 @@ use Tainacan\Entities; use Tainacan\Repositories; class TAINACAN_REST_Fields_Controller extends TAINACAN_REST_Controller { - private $field; private $item_metadata_repository; private $item_repository; private $collection_repository; @@ -20,9 +19,10 @@ class TAINACAN_REST_Fields_Controller extends TAINACAN_REST_Controller { /** * Initialize objects after post_type register + * + * @throws Exception */ public function init_objects() { - $this->field = new Entities\Field(); $this->field_repository = new Repositories\Fields(); $this->item_metadata_repository = new Repositories\Item_Metadata(); $this->item_repository = new Repositories\Items(); @@ -41,16 +41,17 @@ class TAINACAN_REST_Fields_Controller extends TAINACAN_REST_Controller { public function register_routes() { register_rest_route($this->namespace, '/collection/(?P[\d]+)/' . $this->rest_base . '/(?P[\d]+)', array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array($this, 'update_item'), + 'permission_callback' => array($this, 'update_item_permissions_check') + ), + // ENDPOINT X. THIS ENDPOINT DO THE SAME THING OF ENDPOINT Z. I hope that in a brief future it function changes. array( 'methods' => WP_REST_Server::DELETABLE, 'callback' => array($this, 'delete_item'), 'permission_callback' => array($this, 'delete_item_permissions_check') ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array($this, 'update_item'), - 'permission_callback' => array($this, 'update_item_permissions_check') - ) ) ); register_rest_route($this->namespace, '/collection/(?P[\d]+)/' . $this->rest_base, @@ -68,43 +69,85 @@ class TAINACAN_REST_Fields_Controller extends TAINACAN_REST_Controller { ), ) ); + register_rest_route($this->namespace, '/' . $this->rest_base, + array( + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array($this, 'create_item'), + 'permission_callback' => array($this, 'create_item_permissions_check') + ) + ) + ); + register_rest_route($this->namespace, '/'. $this->rest_base . '/(?P[\d]+)', + array( + // ENDPOINT Z. + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array($this, 'delete_item'), + 'permission_callback' => array($this, 'delete_item_permissions_check') + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array($this, 'update_item'), + 'permission_callback' => array($this, 'update_item_permissions_check') + ) + ) + ); } /** * @param WP_REST_Request $request * + * @param null $collection_id + * * @return object|void|WP_Error + * @throws Exception */ - public function prepare_item_for_database( $request ) { - $meta = json_decode($request[0]->get_body(), true); + public function prepare_item_for_database( $request, $collection_id = null ) { + $field = new Entities\Field(); - foreach ($meta as $key => $value){ - $set_ = 'set_' . $key; - $this->field->$set_($value); + if($collection_id) { + $meta = json_decode( $request, true ); + + foreach ( $meta as $key => $value ) { + $set_ = 'set_' . $key; + $field->$set_( $value ); + } + + $collection = new Entities\Collection( $collection_id ); + + $field->set_collection( $collection ); } - $collection = new Entities\Collection($request[1]); + $meta = json_decode($request, true); + foreach ( $meta as $key => $value ) { + $set_ = 'set_' . $key; + $field->$set_( $value ); + } - $this->field->set_collection($collection); + $field->set_collection_id('default'); + + return $field; } /** * @param WP_REST_Request $request * * @return WP_Error|WP_REST_Response + * @throws Exception */ public function create_item( $request ) { - if(!empty($request->get_body())){ + if(!empty($request->get_body()) && isset($request['collection_id'])){ $collection_id = $request['collection_id']; try { - $this->prepare_item_for_database( [ $request, $collection_id ] ); + $prepared = $this->prepare_item_for_database( $request->get_body(), $collection_id ); } catch (\Error $exception){ return new WP_REST_Response($exception->getMessage(), 400); } - if($this->field->validate()) { - $this->field_repository->insert( $this->field ); + if($prepared->validate()) { + $field = $this->field_repository->insert( $prepared); $items = $this->item_repository->fetch([], $collection_id, 'WP_Query'); @@ -114,7 +157,7 @@ class TAINACAN_REST_Fields_Controller extends TAINACAN_REST_Controller { $items->the_post(); $item = new Entities\Item($items->post); - $item_meta = new Entities\Item_Metadata_Entity($item, $this->field); + $item_meta = new Entities\Item_Metadata_Entity($item, $field); $field_added = $this->item_metadata_repository->insert($item_meta); } @@ -124,10 +167,30 @@ class TAINACAN_REST_Fields_Controller extends TAINACAN_REST_Controller { return new WP_REST_Response($response, 201); } else { - $response = $this->prepare_item_for_response($this->field, $request); + $response = $this->prepare_item_for_response($prepared, $request); return new WP_REST_Response($response, 201); } + } else { + return new WP_REST_Response([ + 'error_message' => __('One or more values are invalid.', 'tainacan'), + 'errors' => $prepared->get_errors(), + 'field' => $this->prepare_item_for_response($prepared, $request), + ], 400); + } + } elseif (!empty($request->get_body())) { + try { + $prepared = $this->prepare_item_for_database( $request->get_body() ); + } catch ( \Error $exception ) { + return new WP_REST_Response( $exception->getMessage(), 400 ); + } + + if ( $prepared->validate() ) { + $field = $this->field_repository->insert( $prepared ); + + $response = $this->prepare_item_for_response($field, $request); + + return new WP_REST_Response($response, 201); } else { return new WP_REST_Response([ 'error_message' => __('One or more values are invalid.', 'tainacan'), @@ -135,6 +198,7 @@ class TAINACAN_REST_Fields_Controller extends TAINACAN_REST_Controller { 'field' => $this->prepare_item_for_response($this->field, $request), ], 400); } + } return new WP_REST_Response([ @@ -151,7 +215,11 @@ class TAINACAN_REST_Fields_Controller extends TAINACAN_REST_Controller { * @throws Exception */ public function create_item_permissions_check( $request ) { - return $this->collection_repository->can_edit(new Entities\Collection()); + if(isset($request['collection_id'])) { + return $this->collection_repository->can_edit( new Entities\Collection() ); + } + + return $this->field_repository->can_edit(new Entities\Field()); } /** @@ -254,7 +322,7 @@ class TAINACAN_REST_Fields_Controller extends TAINACAN_REST_Controller { } } - return false; + return $this->field_repository->can_edit(new Entities\Field()); } /** @@ -266,7 +334,7 @@ class TAINACAN_REST_Fields_Controller extends TAINACAN_REST_Controller { $collection_id = $request['collection_id']; $body = json_decode($request->get_body(), true); - if(!empty($body)){ + if(!empty($body) && $collection_id){ $attributes = []; $field_id = $request['field_id']; @@ -318,6 +386,40 @@ class TAINACAN_REST_Fields_Controller extends TAINACAN_REST_Controller { 'error_message' => __('Field with that ID not found', 'tainacan'), 'field_id' => $field_id ], 400); + } elseif (!empty($body)){ + $attributes = []; + + $field_id = $request['field_id']; + + foreach ($body['values'] as $att => $value){ + $attributes[$att] = $value; + } + + $field = $this->field_repository->fetch($field_id); + + if($field && $field->get_collection_id() === 'default') { + + $prepared_metadata = $this->prepare_item_for_updating( $field, $attributes ); + + if ( $prepared_metadata->validate() ) { + $updated_metadata = $this->field_repository->update( $prepared_metadata ); + + $response = $this->prepare_item_for_response($updated_metadata, $request); + + return new WP_REST_Response($response, 200); + } + + return new WP_REST_Response([ + 'error_message' => __('One or more values are invalid.', 'tainacan'), + 'errors' => $prepared_metadata->get_errors(), + 'metadata' => $this->prepare_item_for_response($prepared_metadata, $request) + ], 400); + } + + return new WP_REST_Response([ + 'error_message' => __('Field with that ID not found or that field is not a default field', 'tainacan'), + 'field_id' => $field_id + ], 400); } return new WP_REST_Response([ @@ -342,7 +444,7 @@ class TAINACAN_REST_Fields_Controller extends TAINACAN_REST_Controller { } - return false; + return $this->field_repository->can_edit(new Entities\Field()); } } diff --git a/src/classes/repositories/class-tainacan-repository.php b/src/classes/repositories/class-tainacan-repository.php index 681191068..a7c25f6e1 100644 --- a/src/classes/repositories/class-tainacan-repository.php +++ b/src/classes/repositories/class-tainacan-repository.php @@ -74,7 +74,7 @@ abstract class Repository { // First iterate through the native post properties foreach ($map as $prop => $mapped) { - if ($mapped['map'] != 'meta' && $mapped['map'] != 'meta_multi' && $mapped['map'] != 'terms') { + if ($mapped['map'] != 'meta' && $mapped['map'] != 'meta_multi') { $obj->WP_Post->{$mapped['map']} = $obj->get_mapped_property($prop); } } diff --git a/tests/test-api-metadata.php b/tests/test-api-metadata.php index 793ee6b9b..aea110d87 100644 --- a/tests/test-api-metadata.php +++ b/tests/test-api-metadata.php @@ -9,10 +9,10 @@ use Tainacan\Repositories; */ class TAINACAN_REST_Metadata_Controller extends TAINACAN_UnitApiTestCase { - public function test_insert_metadata() { + public function test_create_field_in_a_collection() { $collection = $this->tainacan_entity_factory->create_entity('collection', '', true); - $item = $this->tainacan_entity_factory->create_entity( + $this->tainacan_entity_factory->create_entity( 'item', array( 'title' => 'No name', @@ -44,6 +44,27 @@ class TAINACAN_REST_Metadata_Controller extends TAINACAN_UnitApiTestCase { } + public function test_create_default_field(){ + $field = json_encode( + array( + 'name' => 'Ano de Publicação', + 'description' => 'Uma data no formato dd/mm/aaaa.', + 'field_type' => 'Tainacan\Field_Types\Text', + ) + ); + + $request = new \WP_REST_Request( + 'POST', + $this->namespace . '/fields' + ); + $request->set_body($field); + + $response = $this->server->dispatch($request); + $field_added = $response->get_data(); + + $this->assertTrue(is_array($field_added) && array_key_exists('name', $field_added), sprintf('cannot create field, response: %s', print_r($field_added, true))); + $this->assertEquals('Ano de Publicação', $field_added['name']); + } public function test_get_item_and_collection_metadata(){ global $Tainacan_Item_Metadata; @@ -210,7 +231,7 @@ class TAINACAN_REST_Metadata_Controller extends TAINACAN_UnitApiTestCase { } - public function test_trash_field(){ + public function test_trash_field_in_collection(){ $collection = $this->tainacan_entity_factory->create_entity( 'collection', array( @@ -247,6 +268,70 @@ class TAINACAN_REST_Metadata_Controller extends TAINACAN_UnitApiTestCase { $this->assertEquals('trash', $field_trashed->post_status); } + public function test_trash_default_field(){ + $field = $this->tainacan_entity_factory->create_entity( + 'field', + array( + 'name' => 'Field Statement', + 'description' => 'No Statement', + 'collection_id' => 'default', + 'status' => 'publish', + 'field_type' => 'Tainacan\Field_Types\Text', + 'multiple' => 'yes' + ), + true + ); + + $trash_field_request = new \WP_REST_Request( + 'DELETE', + $this->namespace . '/fields/' . $field->get_id() + ); + + $trash_field_response = $this->server->dispatch($trash_field_request); + $data1 = $trash_field_response->get_data(); + + $this->assertEquals($field->get_id(), $data1['id']); + + $field_trashed = get_post($data1['id']); + $this->assertEquals('trash', $field_trashed->post_status); + } + + public function test_update_default_field(){ + $field = $this->tainacan_entity_factory->create_entity( + 'field', + array( + 'name' => 'Field Statement', + 'description' => 'No Statement', + 'collection_id' => 'default', + 'status' => 'publish', + 'field_type' => 'Tainacan\Field_Types\Text', + 'multiple' => 'no' + ), + true + ); + + $new_attributes = json_encode([ + 'values' => [ + 'name' => 'No name', + 'description' => 'NOP!' + ] + ]); + + $request = new \WP_REST_Request( + 'PATCH', + $this->namespace . '/fields/' . $field->get_id() + ); + + $request->set_body($new_attributes); + + $response = $this->server->dispatch($request); + + $data = $response->get_data(); + + $this->assertEquals($field->get_id(), $data['id']); + $this->assertEquals('No name', $data['name']); + } + } ?> \ No newline at end of file