Skip to content

Commit

Permalink
Merge pull request #49 from xwp/feature/image-processor
Browse files Browse the repository at this point in the history
Add image processor api
  • Loading branch information
pierlon committed Mar 25, 2020
2 parents 06434ae + fd25a07 commit 3a4be88
Show file tree
Hide file tree
Showing 3 changed files with 201 additions and 8 deletions.
17 changes: 9 additions & 8 deletions php/class-import.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -209,14 +209,15 @@ public function create_attachment( $file ) {
*/
public function process_meta() {
$map = [
'color' => 'color',
'original_id' => 'original_id',
'original_url' => 'original_url',
'unsplash_location' => 'unsplash_location',
'unsplash_sponsor' => 'unsplash_sponsor',
'unsplash_exif' => 'unsplash_exif',
'_wp_attachment_metadata' => 'meta',
'_wp_attachment_image_alt' => 'alt',
'color' => 'color',
'original_id' => 'original_id',
'original_url' => 'original_url',
'unsplash_location' => 'unsplash_location',
'unsplash_sponsor' => 'unsplash_sponsor',
'unsplash_exif' => 'unsplash_exif',
'_wp_attachment_metadata' => 'meta',
'unsplash_attachment_metadata' => 'meta',
'_wp_attachment_image_alt' => 'alt',
];
foreach ( $map as $key => $value ) {
update_post_meta( $this->attachment_id, $key, $this->image->get_field( $value ), true );
Expand Down
91 changes: 91 additions & 0 deletions php/class-rest-controller.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,29 @@ public function register_routes() {
'schema' => [ $this, 'get_public_item_schema' ],
]
);

register_rest_route(
$this->namespace,
'/' . $this->rest_base . '/post-process/(?P<id>[\d]+)',
[
'args' => [
'id' => [
'description' => __( 'WordPress attachment ID.', 'unsplash' ),
'type' => 'integer',
'validate_callback' => [ $this, 'validate_get_attachment' ],
],
],
[
'methods' => WP_REST_Server::READABLE,
'callback' => [ $this, 'post_process' ],
'permission_callback' => [ $this, 'create_item_permissions_check' ],
'args' => [
'context' => $this->get_context_param( [ 'default' => 'view' ] ),
],
],
'schema' => [ $this, 'get_public_item_schema' ],
]
);
}

/**
Expand Down Expand Up @@ -245,6 +268,46 @@ public function get_import( $request ) {
return $response;
}

/**
* Process image.
*
* @param WP_REST_Request $request Request.
*
* @return WP_REST_Response|WP_Error Single page of photo results.
*/
public function post_process( $request ) {
$attachment_id = $request->get_param( 'id' );
try {
if ( ! function_exists( 'wp_generate_attachment_metadata' ) ) {
require_once ABSPATH . 'wp-admin/includes/media.php';
require_once ABSPATH . 'wp-admin/includes/file.php';
require_once ABSPATH . 'wp-admin/includes/image.php';
}
$meta = (array) get_post_meta( $attachment_id, 'unsplash_attachment_metadata', true );
$file = get_attached_file( $attachment_id );
$new_meta = wp_generate_attachment_metadata( $attachment_id, $file );
unset( $meta['sizes'], $new_meta['image_meta'] );
$new_meta = wp_parse_args( $new_meta, $meta );
$processed = wp_update_attachment_metadata( $attachment_id, $new_meta );
$data = [ 'processed' => $processed ];
} catch ( \Exception $e ) {
$response = new WP_Error(
'single-photo-process',
/* translators: %d: attachment id */
sprintf( __( 'Unable to process image attachment %d.', 'unsplash' ), $attachment_id ),
[
'attachment_id' => $attachment_id,
'status' => '400',
]
);
$this->plugin->log_error( $e );
return $response;
}
$response = new WP_REST_Response( $data );

return $response;
}

/**
* Retrieve a page of photos filtered by a search term.
*
Expand Down Expand Up @@ -457,6 +520,34 @@ public static function validate_get_search_param( $value, $request, $param ) {
return true;
}

/**
* Check if attachment exists.
*
* @param int $param Attachment ID.
* @return bool|WP_Error
*/
public function validate_get_attachment( $param ) {
$attachment = get_post( (int) $param );

if ( empty( $attachment ) ) {
return new WP_Error(
'rest_post_invalid_id',
__( 'Invalid attachment ID.', 'unsplash' ),
array( 'status' => 400 )
);
}

if ( get_post_type( $attachment ) !== $this->post_type ) {
return new WP_Error(
'rest_invalid_post_type_id',
__( 'Invalid attachment ID.', 'unsplash' ),
array( 'status' => 400 )
);
}

return true;
}

/**
* Retrieves the photo type's schema, conforming to JSON Schema.
*
Expand Down
101 changes: 101 additions & 0 deletions tests/phpunit/php/class-test-rest-controller.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,86 @@ public function test_get_import() {
remove_filter( 'upload_dir', [ $this, 'upload_dir_patch' ] );
}

/**
* Test post_process() auth.
*
* @covers \Unsplash\Rest_Controller::post_process()
* @covers \Unsplash\Rest_Controller::create_item_permissions_check()
*/
public function test_post_process() {
add_filter( 'upload_dir', [ $this, 'upload_dir_patch' ] );
$orig_file = DIR_TESTDATA . '/images/test-image.jpg';
$test_file = get_temp_dir() . 'test-image.jpg';
copy( $orig_file, $test_file );
$second_id = $this->factory->attachment->create_object(
$test_file,
0,
[
'post_mime_type' => 'image/jpeg',
'post_excerpt' => 'A sample caption 2',
]
);
update_post_meta(
$second_id,
'unsplash_attachment_metadata',
[
'width' => 2,
'foo' => 'bar',
'image_meta' => [ 'aperture' => 1 ],
'sizes' => null,
]
);
wp_set_current_user( self::$admin_id );
$request = new WP_REST_Request( 'GET', $this->get_route( '/post-process/' . $second_id ) );
$response = rest_get_server()->dispatch( $request );
$this->assertEquals( 200, $response->get_status() );
$this->assertEquals( $response->get_data(), [ 'processed' => true ] );
$meta = wp_get_attachment_metadata( $second_id );
$this->assertArrayHasKey( 'foo', $meta );
$this->assertArrayHasKey( 'sizes', $meta );
$this->assertArrayHasKey( 'width', $meta );
$this->assertSame( 50, $meta['width'] );
$this->assertSame( [ 'aperture' => 1 ], $meta['image_meta'] );
remove_filter( 'upload_dir', [ $this, 'upload_dir_patch' ] );
}

/**
* Test validate_get_attachment().
*
* @covers \Unsplash\Rest_Controller::post_process()
* @covers \Unsplash\Rest_Controller::validate_get_attachment()
*/
public function test_post_process_invalid() {
$test_page = self::factory()->post->create(
[
'post_type' => 'page',
'post_title' => 'About',
'post_status' => 'publish',
'post_content' => 'hello there',
]
);

wp_set_current_user( self::$admin_id );
$request = new WP_REST_Request( 'GET', $this->get_route( '/post-process/' . $test_page ) );
$response = rest_get_server()->dispatch( $request );
$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
}

/**
* Test validate_get_attachment().
*
* @covers \Unsplash\Rest_Controller::post_process()
* @covers \Unsplash\Rest_Controller::validate_get_attachment()
*/
public function test_post_process_invalid_2() {
$test_page = wp_rand();

wp_set_current_user( self::$admin_id );
$request = new WP_REST_Request( 'GET', $this->get_route( '/post-process/' . $test_page ) );
$response = rest_get_server()->dispatch( $request );
$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
}

/**
* Test get_item() auth.
*
Expand Down Expand Up @@ -433,6 +513,27 @@ public function test_get_import_auth() {
$this->assertErrorResponse( 'rest_cannot_create', $response, 403 );
}

/**
* Test post_process() auth.
*
* @covers \Unsplash\Rest_Controller::post_process()
* @covers \Unsplash\Rest_Controller::create_item_permissions_check()
*/
public function test_post_process_auth() {
$second_id = $this->factory->attachment->create_object(
'/tmp/melon.jpg',
0,
[
'post_mime_type' => 'image/jpeg',
'post_excerpt' => 'A sample caption 2',
]
);
wp_set_current_user( self::$subscriber_id );
$request = new WP_REST_Request( 'GET', $this->get_route( '/post-process/' . $second_id ) );
$response = rest_get_server()->dispatch( $request );
$this->assertErrorResponse( 'rest_cannot_create', $response, 403 );
}

/**
* Test arguments for get_item().
*/
Expand Down

0 comments on commit 3a4be88

Please sign in to comment.