Buk edit API endpoints #69

This commit is contained in:
Leo Germani 2018-07-05 12:57:31 -03:00
parent ec9c050fc4
commit 379f8c5f04
4 changed files with 433 additions and 28 deletions

View File

@ -0,0 +1,292 @@
<?php
namespace Tainacan\API\EndPoints;
use \Tainacan\API\REST_Controller;
use Tainacan\Entities;
use Tainacan\Repositories;
use Tainacan\Entities\Entity;
class REST_Bulkedit_Controller extends REST_Controller {
public function __construct() {
$this->rest_base = 'bulk-edit';
parent::__construct();
add_action('init', array(&$this, 'init_objects'), 11);
}
public function init_objects() {
$this->metadatum_repository = Repositories\Metadata::get_instance();
$this->collections_repository = Repositories\Collections::get_instance();
}
/**
*
*
* @throws \Exception
*/
public function register_routes() {
register_rest_route($this->namespace, '/collection/(?P<collection_id>[\d]+)/' . $this->rest_base,
array(
array(
'methods' => \WP_REST_Server::CREATABLE,
'callback' => array($this, 'create_item'),
'permission_callback' => array($this, 'bulk_edit_permissions_check'),
'args' => $this->get_create_params()
),
)
);
register_rest_route($this->namespace, '/collection/(?P<collection_id>[\d]+)/' . $this->rest_base . '/(?P<group_id>[0-9a-f]+)/add',
array(
array(
'methods' => \WP_REST_Server::CREATABLE,
'callback' => array($this, 'add_value'),
'permission_callback' => array($this, 'bulk_edit_permissions_check'),
'args' => [
'metadatum_id' => [
'type' => 'integer',
'description' => __( 'The metadatum ID', 'tainacan' ),
],
'value' => [
'type' => 'string',
'description' => __( 'The value to be added', 'tainacan' ),
],
],
),
)
);
register_rest_route($this->namespace, '/collection/(?P<collection_id>[\d]+)/' . $this->rest_base . '/(?P<group_id>[0-9a-f]+)/set',
array(
array(
'methods' => \WP_REST_Server::CREATABLE,
'callback' => array($this, 'set_value'),
'permission_callback' => array($this, 'bulk_edit_permissions_check'),
'args' => [
'metadatum_id' => [
'type' => 'integer',
'description' => __( 'The metadatum ID', 'tainacan' ),
],
'value' => [
'type' => 'string',
'description' => __( 'The value to be added', 'tainacan' ),
],
],
),
)
);
register_rest_route($this->namespace, '/collection/(?P<collection_id>[\d]+)/' . $this->rest_base . '/(?P<group_id>[0-9a-f]+)/remove',
array(
array(
'methods' => \WP_REST_Server::CREATABLE,
'callback' => array($this, 'remove_value'),
'permission_callback' => array($this, 'bulk_edit_permissions_check'),
'args' => [
'metadatum_id' => [
'type' => 'integer',
'description' => __( 'The metadatum ID', 'tainacan' ),
],
'value' => [
'type' => 'string',
'description' => __( 'The value to be added', 'tainacan' ),
],
],
),
)
);
register_rest_route($this->namespace, '/collection/(?P<collection_id>[\d]+)/' . $this->rest_base . '/(?P<group_id>[0-9a-f]+)/replace',
array(
array(
'methods' => \WP_REST_Server::CREATABLE,
'callback' => array($this, 'add_value'),
'permission_callback' => array($this, 'bulk_edit_permissions_check'),
'args' => [
'metadatum_id' => [
'type' => 'integer',
'description' => __( 'The metadatum ID', 'tainacan' ),
],
'old_value' => [
'type' => 'string',
'description' => __( 'The value to search for', 'tainacan' ),
],
'new_value' => [
'type' => 'string',
'description' => __( 'The value to be set', 'tainacan' ),
],
],
),
)
);
}
public function bulk_edit_permissions_check($request) {
$collection = $this->collections_repository->fetch($request['collection_id']);
if ($collection instanceof Entities\Collection) {
return current_user_can($collection->get_items_capabilities()->edit_others_posts);
}
return false;
}
public function create_item($request) {
$body = json_decode($request->get_body(), true);
$args = [];
if (isset($body['items_ids']) && is_array($body['items_ids']) && !empty($body['items_ids'])) {
$args['items_ids'] = $body['items_ids'];
} elseif ( isset($body['use_query']) && $body['use_query'] ) {
unset($request['paged']);
unset($request['offset']);
unset($request['perpage']);
$request['nopaging'] = 1;
$query_args = $this->prepare_filters($request);
$collection_id = $request['collection_id'];
$args = [
'query' => $query_args,
'collection_id' => $collection_id
];
} else {
return new \WP_REST_Response([
'error_message' => __('You mus specify items_ids OR use_query', 'tainacan'),
], 400);
}
$bulk = new \Tainacan\Bulk_Edit($args);
$response = [
'id' => $bulk->get_id()
];
$rest_response = new \WP_REST_Response($response, 200);
$rest_response->header('X-WP-Total', $bulk->count_posts());
return $rest_response;
}
public function add_value($request) {
return $this->generic_action('add_value', $request);
}
public function set_value($request) {
return $this->generic_action('set_value', $request);
}
public function remove_value($request) {
return $this->generic_action('remove_value', $request);
}
public function replace_value($request) {
return $this->generic_action('replace_value', $request, ['old_value', 'new_value']);
}
private function generic_action($method, $request, $keys = ['value']) {
$body = json_decode($request->get_body(), true);
if(empty($body)){
return new \WP_REST_Response([
'error_message' => __('Body can not be empty.', 'tainacan'),
], 400);
}
if(!isset($body['metadatum_id'])){
return new \WP_REST_Response([
'error_message' => __('You must specify a Metadatum ID.', 'tainacan'),
], 400);
}
foreach ($keys as $key) {
if(!isset($body[$key])){
return new \WP_REST_Response([
'error_message' => sprintf(__('%s must be provided', 'tainacan'), $key),
], 400);
}
}
$group_id = $request['group_id'];
var_dump($group_id);
$args = ['id' => $group_id];
$bulk = new \Tainacan\Bulk_Edit($args);
$metadatum = $this->metadatum_repository->fetch($body['metadatum_id']);
if ( $metadatum instanceof Entities\Metadatum ) {
$value = isset($body['new_value']) ? $body['new_value'] : $body['value'];
$old_value = isset($body['old_value']) ? $body['old_value'] : null;
$action = $bulk->$method($metadatum, $value, $old_value);
if ( is_wp_error($action) ) {
return new \WP_REST_Response([
'error_message' => $action->get_error_message(),
], 400);
} else {
return new \WP_REST_Response($action, 200);
}
} else {
return new \WP_REST_Response([
'error_message' => __('Metadatum not found.', 'tainacan'),
], 400);
}
}
/**
* @param null $object_name
*
* @return array|void
*/
public function get_create_params($object_name = null) {
$query_params['context']['default'] = 'view';
array_merge($query_params, parent::get_collection_params('item'));
$query_params['title'] = array(
'description' => __('Limits the result set to items with a specific title'),
'type' => 'string',
);
$query_params['items_ids'] = [
'type' => 'array',
'items' => [
'type' => 'integer'
],
'description' => __( 'Array of items IDs', 'tainacan' ),
];
$query_params['use_query'] = [
'type' => 'bool',
'description' => __( 'Whether to use the current query to select posts', 'tainacan' ),
];
$query_params = array_merge($query_params, parent::get_meta_queries_params());
return $query_params;
}
}
?>

View File

@ -15,6 +15,7 @@ $rest_metadata_types_controller = new \Tainacan\API\EndPoints\REST_Metadata_Type
$rest_filter_types_controller = new \Tainacan\API\EndPoints\REST_Filter_Types_Controller();
$rest_importers_controller = new \Tainacan\API\EndPoints\REST_Importers_Controller();
$rest_background_processes_controller = new \Tainacan\API\EndPoints\REST_Background_Processes_Controller();
$rest_bulkedit_controller = new \Tainacan\API\EndPoints\REST_Bulkedit_Controller();
new \Tainacan\API\EndPoints\REST_Export_Controller();
new \Tainacan\API\EndPoints\REST_Metadatum_Mappers_Controller();
// Add here other endpoints imports

View File

@ -60,7 +60,7 @@ class Bulk_Edit {
if (isset($params['query']) && is_array($params['query'])) {
if (!isset($params['collection_id']) || !is_integer($params['collection_id'])) {
if (!isset($params['collection_id']) || !is_numeric($params['collection_id'])) {
throw new \Exception('Collection ID must be informed when creating a group via query');
}
@ -150,15 +150,15 @@ class Bulk_Edit {
public function add_value(Entities\Metadatum $metadatum, $value) {
if (!$this->get_id()) {
return false;
return new \WP_Error( 'no_id', __( 'Bulk Edit group not initialized', 'tainacan' ) );
}
// Specific validation
if (!$metadatum->is_multiple()) {
return ['error' => __('Unable to add a value to a metadata if it does not accept multiple values', 'tainacan')];
return new \WP_Error( 'invalid_action', __( 'Unable to add a value to a metadata if it does not accept multiple values', 'tainacan' ) );
}
if ($metadatum->is_collection_key()) {
return ['error' => __('Unable to add a value to a metadata set to be a collection key', 'tainacan')];
return new \WP_Error( 'invalid_action', __( 'Unable to add a value to a metadata set to be a collection key', 'tainacan' ) );
}
$dummyItem = new Entities\Item();
@ -168,7 +168,7 @@ class Bulk_Edit {
if ($checkItemMetadata->validate()) {
return $this->_add_value($metadatum, $value);
} else {
return ['error' => __('Invalid value', 'tainacan')];
return new \WP_Error( 'invalid_value', __( 'Invalid Value', 'tainacan' ) );
}
@ -183,13 +183,13 @@ class Bulk_Edit {
public function set_value(Entities\Metadatum $metadatum, $value) {
if (!$this->get_id()) {
return false;
return new \WP_Error( 'no_id', __( 'Bulk Edit group not initialized', 'tainacan' ) );
}
// Specific validation
if ($metadatum->is_collection_key()) {
return ['error' => __('Unable to set a value to a metadata set to be a collection key', 'tainacan')];
return new \WP_Error( 'invalid_action', __( 'Unable to set a value to a metadata set to be a collection key', 'tainacan' ) );
}
$dummyItem = new Entities\Item();
@ -200,7 +200,7 @@ class Bulk_Edit {
$this->_remove_values($metadatum);
return $this->_add_value($metadatum, $value);
} else {
return ['error' => __('Invalid value', 'tainacan')];
return new \WP_Error( 'invalid_value', __( 'Invalid Value', 'tainacan' ) );
}
@ -215,16 +215,16 @@ class Bulk_Edit {
public function remove_value(Entities\Metadatum $metadatum, $value) {
if (!$this->get_id()) {
return false;
return new \WP_Error( 'no_id', __( 'Bulk Edit group not initialized', 'tainacan' ) );
}
// Specific validation
if ($metadatum->is_required()) {
return ['error' => __('Unable to remove a value from a required metadatum', 'tainacan')];
return new \WP_Error( 'invalid_action', __( 'Unable to remove a value from a required metadatum', 'tainacan' ) );
}
if (!$metadatum->is_multiple()) {
return ['error' => __('Unable to remove a value from a metadata if it does not accept multiple values', 'tainacan')];
return new \WP_Error( 'invalid_action', __( 'Unable to remove a value from a metadata if it does not accept multiple values', 'tainacan' ) );
}
return $this->_remove_value($metadatum, $value);
@ -235,16 +235,16 @@ class Bulk_Edit {
/**
* Relplaces a value from one metadata with another value in all items in current group
*/
public function replace_value(Entities\Metadatum $metadatum, $old_value, $new_value) {
public function replace_value(Entities\Metadatum $metadatum, $new_value, $old_value) {
if (!$this->get_id()) {
return false;
return new \WP_Error( 'no_id', __( 'Bulk Edit group not initialized', 'tainacan' ) );
}
// Specific validation
if ($metadatum->is_collection_key()) {
return ['error' => __('Unable to set a value to a metadata set to be a collection key', 'tainacan')];
return new \WP_Error( 'invalid_action', __( 'Unable to set a value to a metadata set to be a collection key', 'tainacan' ) );
}
$dummyItem = new Entities\Item();
@ -255,7 +255,7 @@ class Bulk_Edit {
$this->_remove_value($metadatum, $old_value);
return $this->_add_value($metadatum, $new_value);
} else {
return ['error' => __('Invalid value', 'tainacan')];
return new \WP_Error( 'invalid_value', __( 'Invalid Value', 'tainacan' ) );
}
@ -285,8 +285,8 @@ class Bulk_Edit {
$term = wp_insert_term($value, $tax->get_db_identifier());
}
if (is_wp_error($term) || !isset($term['term_taxonomy_id'])) {
return false;
if (is_\WP_Error($term) || !isset($term['term_taxonomy_id'])) {
return new \WP_Error( 'error', __( 'Error adding term', 'tainacan' ) );
}
$insert_q = $this->_build_select( $wpdb->prepare("post_id, %d", $term['term_taxonomy_id']) );
@ -327,8 +327,6 @@ class Bulk_Edit {
}
return false;
}
/**
@ -354,8 +352,8 @@ class Bulk_Edit {
return 0;
}
if (is_wp_error($term) || !isset($term['term_taxonomy_id'])) {
return false;
if (is_\WP_Error($term) || !isset($term['term_taxonomy_id'])) {
return new \WP_Error( 'error', __( 'Term not found', 'tainacan' ) );
}
$delete_q = $this->_build_select( "post_id" );
@ -380,8 +378,6 @@ class Bulk_Edit {
}
return false;
}
/**
@ -425,8 +421,6 @@ class Bulk_Edit {
}
return false;
}

View File

@ -13,7 +13,7 @@ use Tainacan\Entities;
/**
* Sample test case.
*/
class BulkEdit extends TAINACAN_UnitTestCase {
class BulkEdit extends TAINACAN_UnitApiTestCase {
public $items_ids = [];
@ -105,6 +105,8 @@ class BulkEdit extends TAINACAN_UnitTestCase {
$this->tainacan_item_metadata_factory->create_item_metadata($item, $category, ['good', 'bad']);
}
$this->api_baseroute = $this->namespace . '/collection/' . $collection->get_id() . '/bulk-edit';
}
@ -382,7 +384,7 @@ class BulkEdit extends TAINACAN_UnitTestCase {
]);
$bulk->replace_value($this->category, 'good', 'awesome');
$bulk->replace_value($this->category, 'awesome', 'good');
$items = $Tainacan_Items->fetch([
@ -445,7 +447,7 @@ class BulkEdit extends TAINACAN_UnitTestCase {
]);
$bulk->replace_value($this->metadatum, 'even', 'super');
$bulk->replace_value($this->metadatum, 'super', 'even');
$items = $Tainacan_Items->fetch([
@ -724,6 +726,122 @@ class BulkEdit extends TAINACAN_UnitTestCase {
}
/**
* @group api
*/
function test_api_create_by_items_ids() {
$ids = array_slice($this->items_ids, 2, 17);
$request = new \WP_REST_Request(
'POST', $this->api_baseroute
);
$request->set_body( json_encode(['items_ids' => $ids]) );
$response = $this->server->dispatch($request);
$this->assertEquals(200, $response->get_status());
$data = $response->get_data();
$this->assertTrue(is_string($data['id']));
$this->assertEquals(17, $response->headers['X-WP-Total']);
}
/**
* @group api
*/
function test_api_create_by_query() {
$query = [
'metaquery' => [
[
'key' => $this->metadatum->get_id(),
'value' => 'odd'
]
],
'taxquery' => [
[
'taxonomy' => $this->taxonomy->get_db_identifier(),
'field' => 'name',
'terms' => 'good'
]
],
'perpage' => 4,
'paged' => 2
];
$request = new \WP_REST_Request(
'POST', $this->api_baseroute
);
$request->set_query_params($query);
$request->set_body( json_encode(['use_query' => 1]) );
$response = $this->server->dispatch($request);
$this->assertEquals(200, $response->get_status());
$data = $response->get_data();
$this->assertTrue(is_string($data['id']));
$this->assertEquals(20, $response->headers['X-WP-Total']);
}
/**
* @group api
*/
public function test_api_add_action() {
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
$ids = array_slice($this->items_ids, 2, 14);
$bulk = new \Tainacan\Bulk_Edit([
'items_ids' => $ids,
]);
$body = json_encode([
'metadatum_id' => $this->multiple_meta->get_id(),
'value' => 'superduper'
]);
$request = new \WP_REST_Request(
'POST', $this->api_baseroute . '/' . $bulk->get_id() . '/add'
);
$request->set_body( $body );
$response = $this->server->dispatch($request);
$items = $Tainacan_Items->fetch([
'meta_query' => [
[
'key' => $this->multiple_meta->get_id(),
'value' => 'superduper'
]
],
'posts_per_page' => -1
]);
$this->assertEquals(14, $items->found_posts);
}
}