diff --git a/src/classes/class-tainacan-media.php b/src/classes/class-tainacan-media.php index 393f010f0..e8679da87 100644 --- a/src/classes/class-tainacan-media.php +++ b/src/classes/class-tainacan-media.php @@ -120,6 +120,8 @@ class Media { */ public function insert_attachment_from_blob($blob, $filename, $post_id = null) { + do_action('tainacan-pre-insert-attachment', $blob, $filename, $post_id); + $upload = wp_upload_bits( $filename, null, $blob ); if( !empty( $upload['error'] ) ) { return false; @@ -157,7 +159,9 @@ class Media { // Assign metadata to attachment wp_update_attachment_metadata( $attach_id, $attach_data ); - + + do_action('tainacan-post-insert-attachment', $attach_id, $attach_data, $post_id); + return $attach_id; } diff --git a/src/classes/class-tainacan-private-files.php b/src/classes/class-tainacan-private-files.php index 78c4c44a8..15251280a 100644 --- a/src/classes/class-tainacan-private-files.php +++ b/src/classes/class-tainacan-private-files.php @@ -21,8 +21,12 @@ class Private_Files { protected function __construct() { add_filter('wp_handle_upload_prefilter', [$this, 'pre_upload']); + add_filter('wp_handle_sideload_prefilter', [$this, 'pre_upload']); add_filter('wp_handle_upload', [$this, 'post_upload']); + add_action('tainacan-pre-insert-attachment', [$this, 'pre_tainacan_upload'], 10, 3); + add_action('tainacan-post-insert-attachment', [$this, 'post_tainacan_upload'], 10, 3); + add_action('template_redirect', [$this, 'template_redirect']); add_filter('image_get_intermediate_size', [$this, 'image_get_intermediate_size'], 10, 3); add_filter('wp_get_attachment_url', [$this, 'wp_get_attachment_url'], 10, 2); @@ -33,7 +37,19 @@ class Private_Files { } - + + function pre_tainacan_upload($blob, $filename, $post_id) { + if (is_numeric($post_id)) { + global $TAINACAN_UPLOADING_ATTACHMENT_TO_POST; + $TAINACAN_UPLOADING_ATTACHMENT_TO_POST = $post_id; + add_filter('upload_dir', [$this, 'change_upload_dir']); + } + } + + function post_tainacan_upload($attach_id, $attach_data, $post_id) { + remove_filter('upload_dir', [$this, 'change_upload_dir']); + } + /** * Adds a filter to the upload_dir hook when uploading a new file * @@ -90,7 +106,25 @@ class Private_Files { * */ function change_upload_dir($path) { - $post_id = isset($_REQUEST['post_id']) ? $_REQUEST['post_id'] : false; + $post_id = false; + + // regular ajax uploads via Admin Panel will send post_id + if ( isset($_REQUEST['post_id']) && $_REQUEST['post_id'] ) { + $post_id = $_REQUEST['post_id']; + } + + // API requests to media endpoint will send post + if ( false === $post_id && isset($_REQUEST['post']) && is_numeric($_REQUEST['post']) ) { + $post_id = $_REQUEST['post']; + } + + // tainacan internals, scripts and tests, will set this global + if (false === $post_id) { + global $TAINACAN_UPLOADING_ATTACHMENT_TO_POST; + if ( isset($TAINACAN_UPLOADING_ATTACHMENT_TO_POST) && is_numeric($TAINACAN_UPLOADING_ATTACHMENT_TO_POST) ) { + $post_id = $TAINACAN_UPLOADING_ATTACHMENT_TO_POST; + } + } if (false === $post_id) { return $path; diff --git a/tests/attachment/codeispoetrywp.jpg b/tests/attachment/codeispoetrywp.jpg new file mode 100644 index 000000000..3c7925404 Binary files /dev/null and b/tests/attachment/codeispoetrywp.jpg differ diff --git a/tests/test-api-private-files.php b/tests/test-api-private-files.php new file mode 100644 index 000000000..3e21024e9 --- /dev/null +++ b/tests/test-api-private-files.php @@ -0,0 +1,108 @@ +test_file = '/tmp/codeispoetrywp.jpg'; + copy( $orig_file, $this->test_file ); + + $this->collection = $this->tainacan_entity_factory->create_entity( + 'collection', + array( + 'name' => 'Agile', + 'description' => 'Agile methods', + 'status' => 'publish' + ), + true + ); + + $this->item = $this->tainacan_entity_factory->create_entity( + 'item', + array( + 'title' => 'Lean Startup', + 'description' => 'Um processo ágil de criação de novos negócios.', + 'collection' => $this->collection, + 'status' => 'publish' + ), + true + ); + + $request = new \WP_REST_Request( 'POST', '/wp/v2/media' ); + $request->set_header( 'Content-Type', 'image/jpeg' ); + $request->set_header( 'Content-Disposition', 'attachment; filename=codeispoetrywp.jpg' ); + $request->set_param( 'post', $this->item->get_id() ); + + global $TAINACAN_UPLOADING_ATTACHMENT_TO_POST; + $TAINACAN_UPLOADING_ATTACHMENT_TO_POST = $this->item->get_id(); + + $request->set_body( file_get_contents( $this->test_file ) ); + $response = rest_get_server()->dispatch( $request ); + $data = $response->get_data(); + + unset($TAINACAN_UPLOADING_ATTACHMENT_TO_POST); + + $this->assertEquals( 201, $response->get_status() ); + $this->assertEquals( 'image', $data['media_type'] ); + + $attachment = get_post( $data['id'] ); + + $this->assertEquals( $this->item->get_id(), $attachment->post_parent ); + + $attachment_data = wp_get_attachment_metadata($attachment->ID); + + $folder = 'tainacan-items/' . $this->collection->get_id() . '/' . $this->item->get_id(); + + $this->assertContains( $folder, $attachment_data['file'] ); + + + } + + function test_internal_api() { + + $orig_file = './tests/attachment/codeispoetrywp.jpg'; + $this->test_file = '/tmp/codeispoetrywp.jpg'; + copy( $orig_file, $this->test_file ); + + $this->collection = $this->tainacan_entity_factory->create_entity( + 'collection', + array( + 'name' => 'Agile', + 'description' => 'Agile methods', + 'status' => 'publish' + ), + true + ); + + $this->item = $this->tainacan_entity_factory->create_entity( + 'item', + array( + 'title' => 'Lean Startup', + 'description' => 'Um processo ágil de criação de novos negócios.', + 'collection' => $this->collection, + 'status' => 'publish' + ), + true + ); + + $attachment_id = \Tainacan\Media::get_instance()->insert_attachment_from_file($this->test_file, $this->item->get_id()); + + $attachment_data = wp_get_attachment_metadata($attachment_id); + + $folder = 'tainacan-items/' . $this->collection->get_id() . '/' . $this->item->get_id(); + + $this->assertContains( $folder, $attachment_data['file'] ); + + } + +} + +?> \ No newline at end of file