Skip to content

Introduced MediaContent and MediaContentApi modules #27536

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 36 commits into from
Apr 20, 2020
Merged

Introduced MediaContent and MediaContentApi modules #27536

merged 36 commits into from
Apr 20, 2020

Conversation

sivaschenko
Copy link
Member

@sivaschenko sivaschenko commented Apr 1, 2020

Depends on:

Description (*)

The Magento_MediaContent module provides implementations for managing relations between content and media files used in that content.

Additionally observers have been added to Cms and Catalog modules to save the relation of corresponding entities to MediaContent storage

Story

magento/adobe-stock-integration#717: User sees pages the image is used in Magento

Related Pull Requests

magento/adobe-stock-integration#1235

Contribution checklist (*)

  • Pull request has a meaningful description of its purpose
  • All commits are accompanied by meaningful commit messages
  • All new or changed code is covered with unit/integration tests (if applicable)
  • All automated tests passed successfully (all builds are green)

@m2-assistant
Copy link

m2-assistant bot commented Apr 1, 2020

Hi @sivaschenko. Thank you for your contribution
Here is some useful tips how you can test your changes using Magento test environment.
Add the comment under your pull request to deploy test or vanilla Magento instance:

  • @magento give me test instance - deploy test instance based on PR changes
  • @magento give me 2.4-develop instance - deploy vanilla Magento instance

For more details, please, review the Magento Contributor Guide documentation.

@sivaschenko sivaschenko requested review from angelgonzalezi4 and VladimirZaets and removed request for angelgonzalezi4 April 1, 2020 16:23
{
/** @var CatalogProduct $model */
$model = $observer->getEvent()->getData('product');
if ($model instanceof AbstractModel) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if ($model instanceof AbstractModel) {
if ($model instanceof \Magento\Catalog\Model\Product) {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sivaschenko will this work if this preference will be changed <preference for="Magento\Catalog\Api\Data\ProductInterface" type="Magento\Catalog\Model\Product" /> and Magento\Catalog\Api\Data\ProductInterface will have another implementation?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If not can we leave AbstractModel instance identification? I can hardly imagine the case when the Magento\Catalog\Api\Data\ProductInterface can have another implementation but if this possible from the di perspective it can break the process. Or I missed something?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@naydav can you please address this question?

@ghost ghost assigned sivaschenko Apr 2, 2020
Copy link
Contributor

@maghamed maghamed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we expect to expose any of those newly created APIs via WEB API ?

* @param string $content
* @return AssetInterface[]
*/
public function execute(string $content): array;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's $content in this case?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A "content" in the scope of the MediaContent domain is an alias to any kind of an object property which possibly contains a media asset. For example, a product object has a description which probably includes a media asset. A category object description and image also can have a media asset as a part of storage data.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How somebody (a developer) knows what to put in this property? Where to find list of supported aliases?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Data, selected for this property, is a developer choice made on next conclusion: if an object has a property which possibly contains a media asset, to get it from this property it needs to be sent to this Interface implementation. For example, currently, we represented a declaration of content properties in di:
https://github.com/magento/magento2/pull/27536/files/b6e79cf870273936cb70ffc05add1fa73a9e3334#diff-bcf67dbc51c19997838fdb60cee182abR9-R16

List of aliases, in that case, is a list of properties declared manually based on data structure and a possibility to have a media asset in properties.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@buskamuza that's a parser that looks for image mentions in any content/text/string. Should we change the naming to make it better understandable or improving comments would be enough?

/**
* @param int $assetId
*
* @return array
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's the format of return result ? Not looking at implementation it's not clear

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's ContentIdentityInterface[] (introduced data interface), the code is updated

@ghost ghost assigned maghamed Apr 2, 2020
<preference for="Magento\MediaContentApi\Api\UnassignAssetInterface" type="Magento\MediaContent\Model\UnassignAsset"/>
<preference for="Magento\MediaContentApi\Api\GetAssetsUsedInContentInterface" type="Magento\MediaContent\Model\GetAssetsUsedInContent"/>
<preference for="Magento\MediaContentApi\Api\GetContentWithAssetInterface" type="Magento\MediaContent\Model\GetContentWithAsset"/>
<preference for="Magento\MediaContentApi\Api\ExtractAssetFromContentInterface" type="Magento\MediaContent\Model\ExtractAssetFromContent"/>
Copy link
Contributor

@sidolov sidolov Apr 2, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why interface and implementation located in one module and marked as API? It does not make sense for me. It would be better to leave the interface only.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The interface is used for injecting the service, the model is used for di configuration

That change was requested by @naydav at the online review

@buskamuza
Copy link
Contributor

Looks like domain model has such entity as "content". There are several places with string $contentType, string $contentEntityId, string $contentField interface. It would help to have this entity defined explicitly in a data interface.

Also, I'd suggest to define more clearly purpose of the MediaContent domain and make sure public APIs don't include interfaces/classes which are just details of implementation.

Public API should be useful for developers from unrelated domains. For example, if somebody would like to use MediaContent for order details or for emails, which methods would be needed? Things like "relations" sound too technical (low level) and don't help understand domain model.
I would even think about not exposing any public API for MediaContent, as it looks like necessary for MediaGallery only.

*
* @throws \Magento\Framework\Exception\CouldNotSaveException
*/
public function execute(int $assetId, string $contentType, string $contentEntityId, string $contentField): void;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$contentEntityId - what is "content entity"? In the implementation I see no relation of the ID to anything https://github.com/sivaschenko/magento2/blob/media-content/app/code/Magento/MediaContent/Model/AssignAsset.php#L51 , so it's not clear what does this ID mean.

Is it "CMS", "Product Page", etc? Why $contentType is a string? I'd assume there is limited set of content types supported. Looks like implementation doesn't limit any input as well.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

content entity id is an id of an entity which has content where an asset is used. For example, if we store a relation between asset and content of the product entity the catalog_product_entity.entity_id will be used for this.
In a provided implementation this is used here: https://github.com/magento/magento2/pull/27536/files#diff-425fc7fd56cadd0cbbf4f2b600c74771R107

The implementation doesn't limit supported types of object with content to provide extensibility. From the box, the cms_page, cms_block, catalog_product, catalog_category provided as a basic content type. If someone will need to store information about media asset usage in the content of a custom object it will create its own content type and this automatically be used for all other features such as showing where and how an asset is used.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@buskamuza we've introduced ContentIdentityInterface, please see the updated code

namespace Magento\MediaContentApi\Api;

/**
* Saving data represents relation between the media asset and media content
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Assign asset to media content" would sound less technical and would explain the domain better, IMO. Or "Assign content to asset", depending on what is happening.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment updated

* Used for extracting media asset list from a media content by the search pattern.
* @api
*/
interface ExtractAssetFromContentInterface
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should it be plural then? ExtractAssetsFromContentInterface

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed

* @param string $content
* @return AssetInterface[]
*/
public function execute(string $content): array;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How somebody (a developer) knows what to put in this property? Where to find list of supported aliases?

* @return int[]
* @throws \Magento\Framework\Exception\IntegrationException
*/
public function execute(string $contentType, string $contentEntityId = null, string $contentField = null): array;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there are content aliases (as in the previous interface), why there is also this method? Is it that in some cases alias is not known or doesn't exist? And in some cases an alias is all you know (and don't know about content type and all the input for this method)?

*
* This class should be used for DI configuration only, please use the interface in the code
*
* @api
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably marking the interface with @api should be enough.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this class should be used for DI configuration

Copy link
Member Author

@sivaschenko sivaschenko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review with Valerii

/**
* @inheritdoc
*/
public function setExtensionAttributes(ContentIdentityExtensionInterface $extensionAttributes): void
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delete all setExtensionAttributes if it works with webapi

* @param string $path
* @return int[]
*/
private function getAssetIdsByDirectoryPath(string $path): array
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update after MediaGallery PR is merged

\Closure $proceed,
string $mediaAssetPath
) : void {
$asset = $this->getByPath->execute($mediaAssetPath);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update after merge of MediaGallery PR

*
* @param Observer $observer
*/
public function execute(Observer $observer): void
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Observers appear to be deprecated (but not documented)

@lenaorobei
Copy link
Contributor

@VladimirZaets
Copy link
Contributor

@magento run tests

@VladimirZaets
Copy link
Contributor

@magento run all tests

@VladimirZaets
Copy link
Contributor

@magento run all tests

@VladimirZaets
Copy link
Contributor

@magento run all tests

@sivaschenko
Copy link
Member Author

The pull request was tested with Used In functionality on Adobe Stock Integration

@magento-engcom-team magento-engcom-team merged commit 1e28f35 into magento:2.4-develop Apr 20, 2020
@m2-assistant
Copy link

m2-assistant bot commented Apr 20, 2020

Hi @sivaschenko, thank you for your contribution!
Please, complete Contribution Survey, it will take less than a minute.
Your feedback will help us to improve contribution process.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants