feat: add metadata section order

This commit is contained in:
vnmedeiros 2022-04-29 11:38:03 -03:00
parent 4755fe43b5
commit 005d69d0dd
8 changed files with 332 additions and 116 deletions

View File

@ -81,14 +81,29 @@ class REST_Collections_Controller extends REST_Controller {
),
'schema' => [$this, 'get_schema'],
));
register_rest_route($this->namespace, '/' . $this->rest_base . '/(?P<collection_id>[\d]+)/metadata_order', array(
register_rest_route($this->namespace, '/' . $this->rest_base . '/(?P<collection_id>[\d]+)/metadata_section_order', array(
array(
'methods' => \WP_REST_Server::EDITABLE,
'callback' => array($this, 'update_metadata_section_order'),
'permission_callback' => array($this, 'update_metadata_section_order_permissions_check'),
'args' => [
'metadata_section_order' => [
'description' => __( 'The order of the metadata section in the collection, an array of objects with integer ID and bool enabled.', 'tainacan' ),
'required' => true,
'validate_callback' => [$this, 'validate_metadata_section_order']
]
],
),
'schema' => [$this, 'get_schema'],
));
register_rest_route($this->namespace, '/' . $this->rest_base . '/(?P<collection_id>[\d]+)/metadata_section/(?P<metadata_section_id>[\d]+)/metadata_order', array(
array(
'methods' => \WP_REST_Server::EDITABLE,
'callback' => array($this, 'update_metadata_order'),
'permission_callback' => array($this, 'update_metadata_order_permissions_check'),
'args' => [
'metadata_order' => [
'description' => __( 'The order of the metadata in the collection, an array of objects with integer ID and bool enabled.', 'tainacan' ),
'description' => __( 'The order of the metadata in the section, an array of objects with integer ID and bool enabled.', 'tainacan' ),
'required' => true,
'validate_callback' => [$this, 'validate_filters_metadata_order']
]
@ -586,6 +601,27 @@ class REST_Collections_Controller extends REST_Controller {
}
public function validate_metadata_section_order($value, $request, $param) {
if ( is_array($value) ) {
foreach ($value as $val) {
if ( !is_array($val) ) {
return false;
}
if ( !isset($val['id']) || !is_numeric($val['id'])) {
return false;
}
if ( !isset($val['enabled']) || !is_bool($val['enabled']) ) {
return false;
}
if ( !isset($val['metadata_order']) || !is_array($val['metadata_order']) ) {
return false;
}
}
return true;
}
return false;
}
/**
* Update a collection metadata order
*
@ -595,6 +631,7 @@ class REST_Collections_Controller extends REST_Controller {
*/
public function update_metadata_order( $request ) {
$collection_id = $request['collection_id'];
$metadata_section_id = $request['metadata_section_id'];
$body = json_decode($request->get_body(), true);
@ -603,7 +640,60 @@ class REST_Collections_Controller extends REST_Controller {
$collection = $this->collections_repository->fetch($collection_id);
if( $collection instanceof Entities\Collection) {
$collection->set_metadata_order( $body['metadata_order'] );
$metadata_section_order = $collection->get_metadata_section_order();
foreach($metadata_section_order['metadata_section_order'] as $section) {
if ($section['id'] == $metadata_section_id) {
$section['metadata_order'] = $body['metadata_order'];
break;
}
}
$collection->set_metadata_section_order( $metadata_section_order );
if ( $collection->validate() ) {
$updated_collection = $this->collections_repository->update( $collection );
$response = $this->prepare_item_for_response($updated_collection, $request);
return new \WP_REST_Response( $response, 200 );
}
return new \WP_REST_Response([
'error_message' => __('One or more values are invalid.', 'tainacan'),
'errors' => $collection->get_errors(),
'collection' => $this->prepare_item_for_response($collection, $request)
], 400);
}
return new \WP_REST_Response([
'error_message' => __('Collection with this ID was not found', 'tainacan' ),
'collection_id' => $collection_id
], 400);
}
return new \WP_REST_Response([
'error_message' => __('The body could not be empty', 'tainacan'),
'body' => $body
], 400);
}
/**
* Update a collection metadata section order
*
* @param \WP_REST_Request $request
*
* @return string|\WP_Error|\WP_REST_Response
*/
public function update_metadata_section_order( $request ) {
$collection_id = $request['collection_id'];
$body = json_decode($request->get_body(), true);
if( !empty($body) && isset($body['metadata_section_order']) ) {
$collection = $this->collections_repository->fetch($collection_id);
if( $collection instanceof Entities\Collection) {
$collection->set_metadata_section_order( $body['metadata_section_order'] );
if ( $collection->validate() ) {
$updated_collection = $this->collections_repository->update( $collection );
@ -651,6 +741,25 @@ class REST_Collections_Controller extends REST_Controller {
return false;
}
/**
* Verify if current user has permission to update metadata section order
*
* @param \WP_REST_Request $request
*
* @return bool|\WP_Error
* @throws \Exception
*/
public function update_metadata_section_order_permissions_check( $request ) {
$collection = $this->collections_repository->fetch($request['collection_id']);
if($collection instanceof Entities\Collection) {
return $collection->user_can( 'edit_metadata' ); // && $collection->user_can( 'edit_metadata_section' );
}
return false;
}
/**
* Update a collection metadata order
*

View File

@ -449,14 +449,14 @@ class REST_Metadata_Sections_Controller extends REST_Controller {
], 400);
}
public function add_metadatum( $request ) {
public function add_metadata( $request ) {
if( !empty($request->get_body()) && isset($request['metadata_section_id']) ){
$body = json_decode($request->get_body(), true);
$metadata_section_id = $request['metadata_section_id'];
$metadata_list = $body['metadata_list'];
try {
$metadata_section = $this->metadata_sections_repository->add_metadatum($metadata_section_id, $metadata_list);
$metadata_section = $this->metadata_sections_repository->add_metadata($metadata_section_id, $metadata_list);
if($metadata_section == false) {
return new \WP_REST_Response([
'error_message' => __('One or more values are invalid.', 'tainacan'),
@ -475,14 +475,14 @@ class REST_Metadata_Sections_Controller extends REST_Controller {
], 400);
}
public function delete_metadatum( $request ) {
public function delete_metadata( $request ) {
if( !empty($request->get_body()) && isset($request['metadata_section_id']) ){
$body = json_decode($request->get_body(), true);
$metadata_section_id = $request['metadata_section_id'];
$metadata_list = $body['metadata_list'];
try {
$metadata_section = $this->metadata_sections_repository->delete_metadatum($metadata_section_id, $metadata_list);
$metadata_section = $this->metadata_sections_repository->delete_metadata($metadata_section_id, $metadata_list);
if($metadata_section == false) {
return new \WP_REST_Response([
'error_message' => __('One or more values are invalid.', 'tainacan'),

View File

@ -28,6 +28,7 @@ class Collection extends Entity {
$default_view_mode,
$enabled_view_modes,
$metadata_order,
$metadata_section_order,
$filters_order,
$enable_cover_page,
$cover_page_id,
@ -405,12 +406,21 @@ class Collection extends Entity {
/**
* Get collection metadata ordination
*
* @return string
* @return Object | string
*/
function get_metadata_order() {
return $this->get_mapped_property( 'metadata_order' );
}
/**
* Get collection metadata section ordination
*
* @return Array | Object | string
*/
function get_metadata_section_order() {
return $this->get_mapped_property( 'metadata_section_order' );
}
/**
* Get enable cover page attribute
*
@ -721,6 +731,25 @@ class Collection extends Entity {
$this->set_mapped_property( 'metadata_order', $value );
}
/**
* Set collection metadata section ordination
*
* @param [string] $value
*
* @return void
*/
function set_metadata_section_order( $value ) {
if ( isset($value['metadata_section_order']) ) {
$metadata_section_order = $value['metadata_section_order'];
$metadata_order = array('metadata_order' => array( ) );
foreach($metadata_section_order as $section) {
$metadata_order['metadata_order'] = $section['metadata_order'];
}
$this->set_metadata_order($metadata_order);
}
$this->set_mapped_property( 'metadata_section_order', $value );
}
/**
* Set collection filters ordination
*
@ -857,6 +886,20 @@ class Collection extends Entity {
return false;
}
$metadata_section_order = $this->get_metadata_section_order();
if ( isset($metadata_section_order['metadata_section_order']) ) {
$section_order = $metadata_section_order['metadata_section_order'];
$metadata_order = $this->get_metadata_order();
$order_general = array();
foreach($section_order as $section) {
$order_general = array_merge($order_general, $section['metadata_order']);
}
if( count($order_general) != count($metadata_order) ) {
return false;
}
}
return parent::validate();
}

View File

@ -25,6 +25,8 @@ class Metadata_Section extends Entity {
*/
protected $repository = 'Metadata_Sections';
public $enabled_for_collection = true;
public function __toString() {
return apply_filters("tainacan-metadata-section-to-string", $this->get_name(), $this);
}
@ -112,6 +114,20 @@ class Metadata_Section extends Entity {
$this->set_mapped_property('metadata_list', array_unique($value));
}
/**
* Transient property used to store the status of the metadatum section for a particular collection
*
* Used by the API to tell front end when a metadatum section is disabled
*
*/
public function get_enabled_for_collection() {
return $this->enabled_for_collection;
}
public function set_enabled_for_collection($value) {
$this->enabled_for_collection = $value;
}
/**
* {@inheritdoc }
*

View File

@ -131,6 +131,13 @@ class Collections extends Repository {
'items' => [ 'type' => 'string' ],
//'validation' => v::stringType(),
],
'metadata_section_order' => [
'map' => 'meta',
'title' => __( 'Metadata order', 'tainacan' ),
'type' => ['array', 'object', 'string'],
'items' => [ 'type' => ['array', 'string', 'integer', 'object'] ],
'description' => __( 'The order of the metadata section in the collection', 'tainacan' ),
],
'metadata_order' => [
'map' => 'meta',
'title' => __( 'Metadata order', 'tainacan' ),
@ -429,6 +436,7 @@ class Collections extends Repository {
function handle_parent_order_clone( &$collection ) {
if ($collection instanceof Entities\Collection && $collection->get_parent() != 0) {
$parent_collection = $this->fetch( $collection->get_parent() );
$collection->set_metadata_section_order($parent_collection->get_metadata_section_order());
$collection->set_metadata_order($parent_collection->get_metadata_order());
$collection->set_filters_order($parent_collection->get_filters_order());

View File

@ -263,12 +263,11 @@ class Metadata_Sections extends Repository {
$results = $this->fetch( $args, 'OBJECT' );
}
return $results;
// return $this->order_result(
// $results,
// $collection,
// isset( $args['include_disabled'] ) ? $args['include_disabled'] : false
// );
return $this->order_result(
$results,
$collection,
isset( $args['include_disabled'] ) ? $args['include_disabled'] : false
);
}
/**
@ -294,7 +293,7 @@ class Metadata_Sections extends Repository {
return $this->insert( $object );
}
public function add_metadatum($metadata_section_id, $metadata_list) {
public function add_metadata($metadata_section_id, $metadata_list) {
$metadata_section = $this->fetch($metadata_section_id);
if ($metadata_section) {
$list = $metadata_section->get_metadata_list();
@ -308,7 +307,7 @@ class Metadata_Sections extends Repository {
return false;
}
public function delete_metadatum($metadata_section_id, $metadata_list) {
public function delete_metadata($metadata_section_id, $metadata_list) {
$metadata_section = $this->fetch($metadata_section_id);
if ($metadata_section) {
$list = $metadata_section->get_metadata_list();
@ -338,4 +337,45 @@ class Metadata_Sections extends Repository {
//test if not exist a metadata using this section
return parent::delete($entity, $permanent);
}
public function order_result( $result, Entities\Collection $collection, $include_disabled = false ) {
$order = $collection->get_metadata_section_order();
if ( $order ) {
$order = ( is_array( $order ) ) ? $order : unserialize( $order );
if ( is_array( $result ) ) {
$result_ordinate = [];
$not_ordinate = [];
foreach ( $result as $item ) {
$id = $item->WP_Post->ID;
$index = array_search( $id, array_column( $order, 'id' ) );
if ( $index !== false ) {
// skipping metadata disabled if the arg is set
if ( ! $include_disabled && isset( $order[ $index ]['enabled'] ) && ! $order[ $index ]['enabled'] ) {
continue;
}
$enable = ( isset( $order[ $index ]['enabled'] ) ) ? $order[ $index ]['enabled'] : true;
$item->set_enabled_for_collection( $enable );
$result_ordinate[ $index ] = $item;
} else {
$not_ordinate[] = $item;
}
}
ksort( $result_ordinate );
$result_ordinate = array_merge( $result_ordinate, $not_ordinate );
return $result_ordinate;
}
}
return $result;
}
}

View File

@ -1727,9 +1727,9 @@ class Metadata extends Repository {
public function update_metadata_section( Entities\Metadatum $metadatum, $remove = false ) {
$metadata_section_repository = Metadata_Sections::get_instance();
if (!$remove) {
$metadata_section_repository->add_metadatum($metadatum->get_metadata_section_id(), [$metadatum->get_id()]);
$metadata_section_repository->add_metadata($metadatum->get_metadata_section_id(), [$metadatum->get_id()]);
} else {
$metadata_section_repository->delete_metadatum($metadatum->get_metadata_section_id(), [$metadatum->get_id()]);
$metadata_section_repository->delete_metadata($metadatum->get_metadata_section_id(), [$metadatum->get_id()]);
}
}

View File

@ -95,168 +95,168 @@ class Collections extends TAINACAN_UnitTestCase {
true
);
$Tainacan_Collections = \Tainacan\Repositories\Collections::get_instance();
$Tainacan_Collections = \Tainacan\Repositories\Collections::get_instance();
$this->assertEquals('Tainacan\Entities\Collection', get_class($x));
$this->assertEquals('Tainacan\Entities\Collection', get_class($x));
$test = $Tainacan_Collections->fetch($x->get_id());
$test = $Tainacan_Collections->fetch($x->get_id());
$this->assertEquals('teste', $test->get_name());
$this->assertEquals('adasdasdsa', $test->get_description());
$this->assertEquals('DESC', $test->get_default_order());
$this->assertEquals('draft', $test->get_status());
}
$this->assertEquals('teste', $test->get_name());
$this->assertEquals('adasdasdsa', $test->get_description());
$this->assertEquals('DESC', $test->get_default_order());
$this->assertEquals('draft', $test->get_status());
}
function test_unique_slugs() {
function test_unique_slugs() {
$x = $this->tainacan_entity_factory->create_entity(
'collection',
array(
'name' => 'teste',
'description' => 'adasdasdsa',
'default_order' => 'DESC',
'slug' => 'duplicated_slug',
'status' => 'publish'
'slug' => 'duplicated_slug',
'status' => 'publish'
),
true
);
$y = $this->tainacan_entity_factory->create_entity(
$y = $this->tainacan_entity_factory->create_entity(
'collection',
array(
'name' => 'teste',
'description' => 'adasdasdsa',
'default_order' => 'DESC',
'slug' => 'duplicated_slug',
'status' => 'publish'
'slug' => 'duplicated_slug',
'status' => 'publish'
),
true
);
$this->assertNotEquals($x->get_slug(), $y->get_slug());
$this->assertNotEquals($x->get_slug(), $y->get_slug());
// Create as draft and publish later
$x = $this->tainacan_entity_factory->create_entity(
// Create as draft and publish later
$x = $this->tainacan_entity_factory->create_entity(
'collection',
array(
'name' => 'teste',
'description' => 'adasdasdsa',
'default_order' => 'DESC',
'slug' => 'duplicated_slug',
'slug' => 'duplicated_slug',
),
true
);
$y = $this->tainacan_entity_factory->create_entity(
$y = $this->tainacan_entity_factory->create_entity(
'collection',
array(
'name' => 'teste',
'description' => 'adasdasdsa',
'default_order' => 'DESC',
'slug' => 'duplicated_slug',
'slug' => 'duplicated_slug',
),
true
);
$this->assertEquals($x->get_slug(), $y->get_slug());
$this->assertEquals($x->get_slug(), $y->get_slug());
$Tainacan_Collections = \Tainacan\Repositories\Collections::get_instance();
$x->set_status('publish');
$x->validate();
$x = $Tainacan_Collections->insert($x);
$y->set_status('private'); // or publish shoud behave the same
$y->validate();
$y = $Tainacan_Collections->insert($y);
$Tainacan_Collections = \Tainacan\Repositories\Collections::get_instance();
$x->set_status('publish');
$x->validate();
$x = $Tainacan_Collections->insert($x);
$y->set_status('private'); // or publish shoud behave the same
$y->validate();
$y = $Tainacan_Collections->insert($y);
$this->assertNotEquals($x->get_slug(), $y->get_slug());
$this->assertNotEquals($x->get_slug(), $y->get_slug());
}
}
function test_item() {
$x = $this->tainacan_entity_factory->create_entity(
'collection',
array(
'name' => 'teste',
'description' => 'adasdasdsa',
'default_order' => 'DESC'
),
true
);
function test_item() {
$x = $this->tainacan_entity_factory->create_entity(
'collection',
array(
'name' => 'teste',
'description' => 'adasdasdsa',
'default_order' => 'DESC'
),
true
);
$Tainacan_Collections = \Tainacan\Repositories\Collections::get_instance();
$collection = $Tainacan_Collections->fetch($x->get_id());
$Tainacan_Collections = \Tainacan\Repositories\Collections::get_instance();
$collection = $Tainacan_Collections->fetch($x->get_id());
$i = $this->tainacan_entity_factory->create_entity(
'item',
array(
'title' => 'item test',
'description' => 'adasdasdsa',
'order' => 'DESC',
'collection' => $collection
),
true
);
$i = $this->tainacan_entity_factory->create_entity(
'item',
array(
'title' => 'item test',
'description' => 'adasdasdsa',
'order' => 'DESC',
'collection' => $collection
),
true
);
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
$item = $Tainacan_Items->fetch( $i->get_id() );
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
$item = $Tainacan_Items->fetch( $i->get_id() );
$this->assertEquals($item->get_title(), 'item test');
$this->assertEquals($item->get_description(), 'adasdasdsa');
$this->assertEquals($item->get_collection_id(), $collection->get_id());
$this->assertEquals($item->get_title(), 'item test');
$this->assertEquals($item->get_description(), 'adasdasdsa');
$this->assertEquals($item->get_collection_id(), $collection->get_id());
}
}
function test_validation() {
$x = $this->tainacan_entity_factory->create_entity(
'collection',
array(
'name' => 'teste',
'description' => 'adasdasdsa',
'default_order' => 13,
'status' => 'publish'
)
);
function test_validation() {
$x = $this->tainacan_entity_factory->create_entity(
'collection',
array(
'name' => 'teste',
'description' => 'adasdasdsa',
'default_order' => 13,
'status' => 'publish'
)
);
$this->assertFalse($x->validate());
$this->assertTrue(sizeof($x->get_errors()) > 0);
$this->assertFalse($x->validate());
$this->assertTrue(sizeof($x->get_errors()) > 0);
$x->set_default_order('ASDASD');
$x->set_default_order('ASDASD');
$this->assertFalse($x->validate());
$this->assertTrue(sizeof($x->get_errors()) > 0);
$this->assertFalse($x->validate());
$this->assertTrue(sizeof($x->get_errors()) > 0);
$x->set_default_order('DESC');
$this->assertTrue($x->validate());
$this->assertTrue(empty($x->get_errors()));
}
$x->set_default_order('DESC');
$this->assertTrue($x->validate());
$this->assertTrue(empty($x->get_errors()));
}
function test_hooks() {
$Tainacan_Collections = \Tainacan\Repositories\Collections::get_instance();
$this->assertTrue(has_action('init', array($Tainacan_Collections, 'register_post_type')) !== false, 'Collections Init is not registred!');
}
function test_hooks() {
$Tainacan_Collections = \Tainacan\Repositories\Collections::get_instance();
$this->assertTrue(has_action('init', array($Tainacan_Collections, 'register_post_type')) !== false, 'Collections Init is not registred!');
}
function test_create_child_collection() {
$x = $this->tainacan_entity_factory->create_entity(
'collection',
array(
'name' => 'test',
'description' => 'adasdasdsa',
'default_order' => 'DESC',
),
true
);
'collection',
array(
'name' => 'test',
'description' => 'adasdasdsa',
'default_order' => 'DESC',
),
true
);
$col = $this->tainacan_entity_factory->create_entity(
'collection',
array(
'name' => 'test',
'description' => 'adasdasdsa',
'default_order' => 'DESC',
'collection',
array(
'name' => 'test',
'description' => 'adasdasdsa',
'default_order' => 'DESC',
'status' => 'auto-draft'
),
true
);
),
true
);
$Collections = \Tainacan\Repositories\Collections::get_instance();