Skip to content

Commit

Permalink
Video Cropping: Add post meta for original (#12349)
Browse files Browse the repository at this point in the history
Co-authored-by: Pascal Birchler <pascalb@google.com>
  • Loading branch information
spacedmonkey and swissspidy committed Sep 23, 2022
1 parent 8b61ff5 commit c07eccc
Show file tree
Hide file tree
Showing 11 changed files with 200 additions and 43 deletions.
1 change: 1 addition & 0 deletions .phpstorm.meta.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
'media.image_sizes' => \Google\Web_Stories\Media\Image_Sizes::class,
'media.media_source' => \Google\Web_Stories\Media\Media_Source_Taxonomy::class,
'media.video.captions' => \Google\Web_Stories\Media\Video\Captions::class,
'media.cropping' => \Google\Web_Stories\Media\Cropping::class,
'media.video.muting' => \Google\Web_Stories\Media\Video\Muting::class,
'media.video.optimization' => \Google\Web_Stories\Media\Video\Optimization::class,
'media.video.poster' => \Google\Web_Stories\Media\Video\Poster::class,
Expand Down
83 changes: 83 additions & 0 deletions includes/Media/Cropping.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php
/**
* Class Cropping
*
* @link https://github.com/googleforcreators/web-stories-wp
*
* @copyright 2022 Google LLC
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
*/

/**
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

namespace Google\Web_Stories\Media;

use Google\Web_Stories\Infrastructure\HasMeta;
use Google\Web_Stories\Service_Base;

/**
* Class Cropping
*/
class Cropping extends Service_Base implements HasMeta {

/**
* The cropped video id post meta key.
*/
public const CROPPED_ID_POST_META_KEY = 'web_stories_cropped_origin_id';

/**
* Init.
*
* @since 1.26.0
*/
public function register(): void {
$this->register_meta();
add_action( 'delete_attachment', [ $this, 'delete_video' ] );
}

/**
* Register meta
*
* @since 1.26.0
*/
public function register_meta(): void {
register_meta(
'post',
self::CROPPED_ID_POST_META_KEY,
[
'sanitize_callback' => 'absint',
'type' => 'integer',
'description' => __( 'Parent ID if this is a cropped attachment', 'web-stories' ),
'show_in_rest' => true,
'default' => 0,
'single' => true,
'object_subtype' => 'attachment',
]
);
}

/**
* Deletes associated meta data when a video is deleted.
*
* @since 1.26.0
*
* @param int $attachment_id ID of the attachment to be deleted.
*/
public function delete_video( int $attachment_id ): void {
delete_metadata( 'post', 0, self::CROPPED_ID_POST_META_KEY, $attachment_id, true );
}
}
1 change: 1 addition & 0 deletions includes/Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ class Plugin extends ServiceBasedPlugin {
'media.image_sizes' => Media\Image_Sizes::class,
'media.media_source' => Media\Media_Source_Taxonomy::class,
'media.video.captions' => Media\Video\Captions::class,
'media.cropping' => Media\Cropping::class,
'media.video.muting' => Media\Video\Muting::class,
'media.video.optimization' => Media\Video\Optimization::class,
'media.video.poster' => Media\Video\Poster::class,
Expand Down
2 changes: 2 additions & 0 deletions includes/uninstall.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

use Google\Web_Stories\Media\Base_Color;
use Google\Web_Stories\Media\Blurhash;
use Google\Web_Stories\Media\Cropping;
use Google\Web_Stories\Media\Media_Source_Taxonomy;
use Google\Web_Stories\Media\Video\Is_Gif;
use Google\Web_Stories\Media\Video\Muting;
Expand Down Expand Up @@ -127,6 +128,7 @@ function delete_stories_post_meta(): void {
delete_post_meta_by_key( Optimization::OPTIMIZED_ID_POST_META_KEY );
delete_post_meta_by_key( Muting::MUTED_ID_POST_META_KEY );
delete_post_meta_by_key( Muting::IS_MUTED_POST_META_KEY );
delete_post_meta_by_key( Cropping::CROPPED_ID_POST_META_KEY );
delete_post_meta_by_key( Trimming::TRIM_POST_META_KEY );
delete_post_meta_by_key( Blurhash::BLURHASH_POST_META_KEY );
delete_post_meta_by_key( Is_Gif::IS_GIF_POST_META_KEY );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,10 +256,6 @@ function useMediaUploadQueue() {
return;
}

additionalData.meta = {
...additionalData.meta,
trimData,
};
finishTrimming({ id, file: newFile, additionalData });
} catch (error) {
// Cancel uploading if there were any errors.
Expand Down Expand Up @@ -318,7 +314,6 @@ function useMediaUploadQueue() {
return;
}

additionalData.isCropped = true;
finishCropping({ id, file: newFile, posterFile, additionalData });
} catch (error) {
// Cancel uploading if there were any errors.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export function addItem(
onUploadProgress,
onUploadError,
onUploadSuccess,
additionalData: _additionalData = {},
additionalData = {},
posterFile,
muteVideo,
cropVideo,
Expand All @@ -74,13 +74,6 @@ export function addItem(
resource.id = uuidv4();
}

const additionalData = {
..._additionalData,
meta: {
...(_additionalData.meta || {}),
},
};

if (
resource.type === 'video' &&
resource.isMuted !== null &&
Expand All @@ -90,13 +83,13 @@ export function addItem(
}

if (resource?.baseColor) {
additionalData.meta.baseColor = resource.baseColor;
additionalData.baseColor = resource.baseColor;
}

// Do not copy over BlurHash for new trimmed videos
// Do not copy over BlurHash for new trimmed and cropped videos
// since the poster (and thus the BlurHash) might be different.
if (resource?.blurHash && !resource?.trimData) {
additionalData.meta.blurHash = resource.blurHash;
if (resource?.blurHash && !trimData && !cropVideo) {
additionalData.blurHash = resource.blurHash;
}

const newItem = {
Expand Down Expand Up @@ -433,10 +426,6 @@ export function finishCropping(
file,
posterFile,
state: ITEM_STATUS.CROPPED,
resource: {
...item.resource,
isCropped: true,
},
additionalData: {
...item.additionalData,
...additionalData,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,7 @@ describe('useMediaUploadQueue', () => {
id: 456,
foo: 'bar',
}),
additionalData: {
meta: {},
},
additionalData: {},
}),
],
});
Expand Down Expand Up @@ -113,7 +111,6 @@ describe('useMediaUploadQueue', () => {
isMuted: false,
}),
additionalData: {
meta: {},
isMuted: false,
},
}),
Expand Down Expand Up @@ -151,9 +148,7 @@ describe('useMediaUploadQueue', () => {
baseColor: 'barbaz',
}),
additionalData: {
meta: {
baseColor: 'barbaz',
},
baseColor: 'barbaz',
},
}),
],
Expand Down Expand Up @@ -190,9 +185,7 @@ describe('useMediaUploadQueue', () => {
blurHash: 'barbaz',
}),
additionalData: {
meta: {
blurHash: 'barbaz',
},
blurHash: 'barbaz',
},
}),
],
Expand Down
2 changes: 2 additions & 0 deletions packages/story-editor/src/app/media/utils/useProcessMedia.js
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ function useProcessMedia({
additionalData: {
originalId: resourceId,
isMuted,
trimData,
mediaSource: isOptimized ? 'video-optimization' : 'editor',
},
elementId,
Expand Down Expand Up @@ -541,6 +542,7 @@ function useProcessMedia({
cropVideo: true,
additionalData: {
original_id: resourceId,
cropOriginId: resourceId,
cropParams,
mediaSource: isOptimized ? 'video-optimization' : 'editor',
},
Expand Down
29 changes: 21 additions & 8 deletions packages/wp-story-editor/src/api/media.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ export function uploadMedia(config, file, additionalData) {
mediaId,
storyId,
templateId,
optimizedId,
cropOriginId,
mutedId,
posterId,
isMuted,
mediaSource,
trimData,
Expand All @@ -180,17 +184,24 @@ export function uploadMedia(config, file, additionalData) {
web_stories_is_muted: isMuted,
post: templateId || storyId || mediaId,
original_id: originalId,
web_stories_trim_data: trimData,
web_stories_base_color: baseColor,
web_stories_blurhash: blurHash,
meta: {
web_stories_base_color: baseColor,
web_stories_blurhash: blurHash,
web_stories_cropped_origin_id: cropOriginId,
web_stories_optimized_id: optimizedId,
web_stories_muted_id: mutedId,
web_stories_poster_id: posterId,
web_stories_trim_data: trimData,
web_stories_is_gif: isGif,
},
alt_text: altText,
};

if (isGif !== undefined) {
wpKeysMapping.meta = {
web_stories_is_gif: isGif,
};
}
Object.entries(wpKeysMapping.meta).forEach(([key, value]) => {
if (value === undefined) {
delete wpKeysMapping.meta[key];
}
});

Object.entries(wpKeysMapping).forEach(([key, value]) => {
if (value === undefined) {
Expand Down Expand Up @@ -228,6 +239,7 @@ export function updateMedia(config, mediaId, data) {
isMuted,
mediaSource,
optimizedId,
cropOriginId,
mutedId,
posterId,
storyId,
Expand All @@ -240,6 +252,7 @@ export function updateMedia(config, mediaId, data) {
web_stories_blurhash: blurHash,
web_stories_optimized_id: optimizedId,
web_stories_muted_id: mutedId,
web_stories_cropped_origin_id: cropOriginId,
web_stories_poster_id: posterId,
},
web_stories_is_muted: isMuted,
Expand Down
76 changes: 76 additions & 0 deletions tests/phpunit/integration/tests/Media/Cropping.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php
/**
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

namespace Google\Web_Stories\Tests\Integration\Media;

use Google\Web_Stories\Tests\Integration\TestCase;

/**
* @coversDefaultClass \Google\Web_Stories\Media\Cropping
*/
class Cropping extends TestCase {
/**
* Test instance.
*
* @var \Google\Web_Stories\Media\Cropping
*/
protected $instance;

public function set_up(): void {
parent::set_up();

$this->instance = new \Google\Web_Stories\Media\Cropping();
}

/**
* @covers ::register
*/
public function test_register(): void {
$this->instance->register();

$this->assertTrue( registered_meta_key_exists( 'post', $this->instance::CROPPED_ID_POST_META_KEY, 'attachment' ) );
$this->assertSame( 10, has_action( 'delete_attachment', [ $this->instance, 'delete_video' ] ) );
}

/**
* @covers ::delete_video
*/
public function test_delete_video_meta_attachment_is_deleted(): void {
$video_attachment_id = self::factory()->attachment->create_object(
[
'file' => DIR_TESTDATA . '/uploads/test-video.mp4',
'post_parent' => 0,
'post_mime_type' => 'video/mp4',
'post_title' => 'Test Video',
]
);

$cropped_attachment_id = self::factory()->attachment->create_object(
[
'file' => DIR_TESTDATA . '/uploads/test-video.mp4',
'post_parent' => 0,
'post_mime_type' => 'image/jpeg',
'post_title' => 'Test Image',
]
);

add_post_meta( $video_attachment_id, $this->instance::CROPPED_ID_POST_META_KEY, $cropped_attachment_id );
$this->assertSame( $cropped_attachment_id, (int) get_post_meta( $video_attachment_id, $this->instance::CROPPED_ID_POST_META_KEY, true ) );
wp_delete_attachment( $cropped_attachment_id );
$this->assertEmpty( get_post_meta( $video_attachment_id, $this->instance::CROPPED_ID_POST_META_KEY, true ) );
}
}
Loading

0 comments on commit c07eccc

Please sign in to comment.