diff --git a/src/api/endpoints/class-tainacan-rest-bulkedit-controller.php b/src/api/endpoints/class-tainacan-rest-bulkedit-controller.php index 4a8bd23c5..ccc94bc3d 100644 --- a/src/api/endpoints/class-tainacan-rest-bulkedit-controller.php +++ b/src/api/endpoints/class-tainacan-rest-bulkedit-controller.php @@ -158,6 +158,15 @@ class REST_Bulkedit_Controller extends REST_Controller { ], ), ) + ); + register_rest_route($this->namespace, '/collection/(?P[\d]+)/' . $this->rest_base . '/(?P[0-9a-f]+)/sequence/(?P[\d]+)', + array( + array( + 'methods' => \WP_REST_Server::READABLE, + 'callback' => array($this, 'get_item_in_sequence'), + 'permission_callback' => array($this, 'bulk_edit_permissions_check'), + ), + ) ); } @@ -181,6 +190,7 @@ class REST_Bulkedit_Controller extends REST_Controller { if (isset($body['items_ids']) && is_array($body['items_ids']) && !empty($body['items_ids'])) { $args['items_ids'] = $body['items_ids']; + // TODO: recieve and pass sort options } elseif ( isset($body['use_query']) && $body['use_query'] ) { unset($body['use_query']['paged']); @@ -377,6 +387,25 @@ class REST_Bulkedit_Controller extends REST_Controller { } } + public function get_item_in_sequence($request) { + $group_id = $request['group_id']; + $index = $request['sequence_index']; + + $args = ['id' => $group_id]; + + $bulk = new \Tainacan\Bulk_Edit($args); + + $item_id = $bulk->get_item_id_by_index( (int) $index ); + + if ( !$item_id ) { + return new \WP_REST_Response([ + 'error_message' => __('Item not found.', 'tainacan'), + ], 404); + } else { + return new \WP_REST_Response($item_id, 200); + } + + } /** diff --git a/src/classes/class-tainacan-bulk-edit.php b/src/classes/class-tainacan-bulk-edit.php index a3091c83f..7f769f376 100644 --- a/src/classes/class-tainacan-bulk-edit.php +++ b/src/classes/class-tainacan-bulk-edit.php @@ -42,6 +42,7 @@ class Bulk_Edit { * @type int $collection_id The items collection ID. Required if initializing using a query search * @type array $query The query paramaters used to fetch items that will be part of this bulk edit group * @type array $items_ids an array containing the IDs of items that will be part of this bulk edit group + * @type array $options an array containing additional options for this bulk edit group (currently used to store sorting information) * @type string $id The ID of the Bulk edit group. * * } @@ -87,7 +88,10 @@ class Bulk_Edit { $wpdb->query( "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) {$items_query->request}" ); - return; + $bulk_params = [ + 'orderby' => isset($params['query']['orderby']) ? $params['query']['orderby'] : 'post_date', + 'order' => isset($params['query']['order']) ? $params['query']['order'] : 'DESC' + ]; } elseif (isset($params['items_ids']) && is_array($params['items_ids'])) { $items_ids = array_filter($params['items_ids'], 'is_integer'); @@ -100,10 +104,23 @@ class Bulk_Edit { $wpdb->query( "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) VALUES $insert_q" ); - return; + $bulk_params = [ + 'orderby' => isset($params['options']['orderby']) ? $params['options']['orderby'] : 'post_date', + 'order' => isset($params['options']['order']) ? $params['options']['order'] : 'DESC' + ]; } + /** + * This is stored to be used by the get_sequence_item_by_index() method, which is used + * by the sequence edit routine. + * + * For everything else, the order does not matter... + */ + $this->save_options($bulk_params); + + return; + } /** @@ -135,6 +152,46 @@ class Bulk_Edit { } return 0; } + + /** + * Gets the id of the item in a given position inside the group + * + * @param int $index THe position of the index to search for. From 1 to the length of the group + * @return int|bool Returns the ID of the item or false if the index is out of range + */ + public function get_item_id_by_index(int $index) { + $options = $this->get_options(); + $query = [ + 'meta_query' => [ + [ + 'key' => $this->meta_key, + 'value' => $this->get_id() + ] + ], + 'fields' => 'ids', + 'post_type' => \Tainacan\Repositories\Repository::get_collections_db_identifiers(), + 'posts_per_page' => 1, + 'paged' => $index, + 'orderby' => $options['orderby'], + 'order' => $options['order'] + ]; + + $object = new \WP_Query($query); + + if ( $object->have_posts() && isset($object->posts) && is_array($object->posts) && isset($object->posts[0]) && is_integer($object->posts[0]) ) { + return $object->posts[0]; + } + + return false; + } + + private function save_options($value) { + update_option('tainacan_bulk_' . $this->get_id(), $value); + } + + private function get_options() { + return get_option('tainacan_bulk_' . $this->get_id()); + } private function _build_select($fields) { global $wpdb; diff --git a/tests/test-bulkedit.php b/tests/test-bulkedit.php index fbb8934cf..85228943a 100644 --- a/tests/test-bulkedit.php +++ b/tests/test-bulkedit.php @@ -89,10 +89,12 @@ class BulkEdit extends TAINACAN_UnitApiTestCase { for ($i = 1; $i<=40; $i++) { + $title = 'testeItem ' . str_pad($i, 2, "0", STR_PAD_LEFT); + $item = $this->tainacan_entity_factory->create_entity( 'item', array( - 'title' => 'testeItem ' . $i, + 'title' => $title, 'collection' => $collection, 'status' => 'publish' ), @@ -103,7 +105,7 @@ class BulkEdit extends TAINACAN_UnitApiTestCase { $this->tainacan_item_metadata_factory->create_item_metadata($item, $metadatum, $i % 2 == 0 ? 'even' : 'odd'); $this->tainacan_item_metadata_factory->create_item_metadata($item, $category, ['good', 'bad']); - $this->tainacan_item_metadata_factory->create_item_metadata($item, $collection->get_core_title_metadatum(), 'testeItem ' . $i); + $this->tainacan_item_metadata_factory->create_item_metadata($item, $collection->get_core_title_metadatum(), $title); } @@ -1302,6 +1304,94 @@ class BulkEdit extends TAINACAN_UnitApiTestCase { } + + /** + * @group sequence + */ + function test_get_item_in_sequence() { + $Tainacan_Items = \Tainacan\Repositories\Items::get_instance(); + + $query = [ + 'posts_per_page' => 22, + 'orderby' => 'title' + ]; + + $bulk = new \Tainacan\Bulk_Edit([ + 'query' => $query, + 'collection_id' => $this->collection->get_id() + ]); + + $item_id = $bulk->get_item_id_by_index(7); + + $item = $Tainacan_Items->fetch($item_id); + + $this->assertEquals('testeItem 34', $item->get_title()); + + $item_id = $bulk->get_item_id_by_index(15); + + $item = $Tainacan_Items->fetch($item_id); + + $this->assertEquals('testeItem 26', $item->get_title()); + + $query = [ + 'posts_per_page' => 22, + 'orderby' => 'title', + 'order' => 'ASC' + ]; + + $bulk = new \Tainacan\Bulk_Edit([ + 'query' => $query, + 'collection_id' => $this->collection->get_id() + ]); + + $item_id = $bulk->get_item_id_by_index(19); + + $item = $Tainacan_Items->fetch($item_id); + + $this->assertEquals('testeItem 19', $item->get_title()); + + $item_id = $bulk->get_item_id_by_index(30); + + $this->assertFalse($item_id); + + + } + + /** + * @group sequence + */ + function test_api_get_item_in_sequence() { + + $Tainacan_Items = \Tainacan\Repositories\Items::get_instance(); + + $query = [ + 'posts_per_page' => 22, + 'orderby' => 'title', + 'order' => 'ASC' + ]; + + $bulk = new \Tainacan\Bulk_Edit([ + 'query' => $query, + 'collection_id' => $this->collection->get_id() + ]); + + + $request = new \WP_REST_Request( + 'GET', $this->api_baseroute . '/' . $bulk->get_id() . '/sequence/7' + ); + + $response = $this->server->dispatch($request); + + $id = $response->get_data(); + + $item = $Tainacan_Items->fetch($id); + + $this->assertEquals('testeItem 07', $item->get_title()); + + + } + + } \ No newline at end of file