1: Indicate if an entity already exists
2: Be able to see a diff between the remote values and the local entity.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Grimreaper created an issue. See original summary.

Grimreaper’s picture

Assigned: Unassigned » Grimreaper
Priority: Minor » Major

Before making a nice diff feature.

Indicating on the pull form if the content is a new content or will be updated.

  • Grimreaper authored 6afbe4f on 8.x-1.x
    Issue #2856719 by Grimreaper: Add a basic diff indicator on entities?
    
Grimreaper’s picture

Assigned: Grimreaper » Unassigned
Priority: Major » Minor

Back to minor has a basic diff has been implemented.

Grimreaper’s picture

Title: [D8] Diff on entities » Diff on entities
Version: » 8.x-1.x-dev

  • Grimreaper authored 40a6501 on 8.x-1.x
    Issue #2856719 by Grimreaper: Fix diff on translation
    
Grimreaper’s picture

Using the diff module https://www.drupal.org/project/diff. Maybe it will be possible to use:

diff/src/Controller/NodeRevisionController.php, compareNodeRevisions:

$build = $this->compareEntityRevisions($route_match, $left_revision, $right_revision, $filter);

But the problem is the route_match parameter that we may don't want.

Discussed with @friera, @richardrodriguez21, and others at Werfen.

Grimreaper’s picture

Version: 8.x-1.x-dev » 8.x-2.x-dev
Grimreaper’s picture

Category: Task » Feature request
Grimreaper’s picture

Assigned: Unassigned » Grimreaper

Grimreaper credited friera.

Grimreaper’s picture

Crediting people at Werfen to not forget.

Grimreaper’s picture

Status: Active » Needs work
FileSize
11.42 KB

Here is a POC I made.

It requires to have patch on diff module: #3088227-2: Use diff in another context

And a discussion with diff's maintainers to have something maintainable.

Grimreaper’s picture

I am removing the options to only get the split_fields layout.

So a lot less modifications in the diff module will be required.

Grimreaper’s picture

Assigned: Grimreaper » Unassigned
Status: Needs work » Needs review
FileSize
22.94 KB
25.3 KB

After simplifying the diff, I had been able to obtain a default implementation that requires only the following patch in diff module:

#3088274-2: Prevent fatal error if the revision has no author

jsonapiHelper and stateInformation services are more complex, and will be required to be rethought as part of #3060694: Rework service and tests.

I am waiting for feedbacks before merging.

Grimreaper’s picture

Grimreaper’s picture

Priority: Minor » Normal
quicksketch’s picture

FileSize
6.67 KB

I'm having a few issues testing this so far.

First, for some reason the Diff links do not respect the config override settings on the Remote URLs. In our settings.php files, we override the URL based on the environment. For example for localhost testing on Lando:

$config['entity_share_client.remote.site1']['url'] = 'http://cmu.lndo.site/news';
$config['entity_share_client.remote.site2']['url'] = 'http://cmu.lndo.site/mcs';

But the Diff links do not respect these. instead they use the original URLs when attempting to fetch information about the remote, and Guzzle throws a 500 error because the original URLs are inaccessible.

Oddly every other place in Entity Share uses the config overrides, I'm not sure what's happening here.

Another small issue so far is that the "Diff" link shows up even when entities are 100% in sync.

screenshot

For improving the UI, I think it would be better if the entire "Diff" column were removed so it doesn't show up unnecessarily. Where it says "Entities not synchronized" it added a link for "(Diff)" after it within the same column

quicksketch’s picture

FileSize
39.11 KB

Doing the following I was able to get a diff:

I synced one piece of content and then modified a single field on it (adding a "Subheading"). The diff result is close, but I'm seeing completely different rows instead of each comparison being made against the same field. And I'm not sure why "Language", "Authored by", and "Title" show up as modified at all, when they're all the same values.

Diff screenshot

Grimreaper’s picture

Assigned: Unassigned » Grimreaper
Status: Needs review » Needs work
  1. +++ b/modules/entity_share_client/src/Controller/DiffController.php
    @@ -0,0 +1,170 @@
    +    $channels_infos = $this->remoteManager->getChannelsInfos($remote);
    

    I found that when a config entity is created with parameter upcasting, the overrides are not applied. I found some issues in search_api about that but not core (I admit that I searched only two minutes).

    I will upload a quick fix.

  2. +++ b/modules/entity_share_client/src/Service/JsonapiHelper.php
    @@ -587,18 +602,40 @@ class JsonapiHelper implements JsonapiHelperInterface {
    +        StateInformationInterface::INFO_ID_SYNCHRONIZED,
    

    I have allowed to have a diff link even when the entity is marked has synchronized, because currently only the changed timestamp is used to check if there is a diff and also in DiffLayoutInterface, there is only one method "build".

    So to avoid relying only on the changed timestamp, the diff should be calculated on each row and then parse the renderable array to see if there is a diff. That adds too many calculation in my opinion, and so in case, the change timestamp is the same but there is a change it allows to see if there is a diff.

    If after a lot of usage, this case can be removed easily I think.

Also I will apply your suggestion on removing diff column.

Patch incoming.

Grimreaper’s picture

Assigned: Grimreaper » Unassigned
Status: Needs work » Needs review
FileSize
3.53 KB
23.23 KB
110.71 KB

I forgot: Thanks @quicksketch for the tests and feedbacks!

Here is the patch.

Also I am not able to reproduce the screenshot from comment 20. I attached a screenshot to show my results.

I use the default diff settings, maybe you have some different config?

If you can give me more steps to reproduce the behavior.

quicksketch’s picture

Status: Needs review » Needs work
FileSize
8.67 KB
26.36 KB

Thanks @GrimReaper! The table looks better:

Diff table screenshot

However, note that there is still a "Diff" link even when two items are already synchronized. Clicking on the Diff link yields the predictable result, "No visible changes." We should remove that link if it's always an empty Diff.

I'm still seeing the problem where diffing changed entities results in a complete set of subtractions and replaced with all additions.

Digging into Diff module, it appears that this is due to the Node (or whatever entity) IDs differing. On my remote site, the NID is 1, but on my local it's NID 5. When Diff assembles the keys for comparison, it includes the Entity ID:

From \Drupal\diff\DiffEntityParser::parseEntity():

$result[$entity->id() . ':' . $entity_type_id . '.' . $field_items->getName()] = $build;

So if the entity IDs differ, you end up with this display where the entire contents are removed/added like my screenshot above.

Here's a partial dump of the Diff $build as dumped in \Drupal\entity_share_client\Controller\DiffController::compareEntityRevisions():

Diff output

So looks like either we need to make Diff module learn how to compare two entities with different IDs, or we need to modify the entities to have the same IDs before asking them to be compared.

Grimreaper’s picture

Status: Needs work » Needs review
FileSize
24.16 KB
3.88 KB

Thanks @Quicksketch for testing.

Great to find out it was mismatching entity ids!

Here is a patch that will resolve this case too.

Also for the diff appearing on "synchronized" entities it was still there so normal that you still saw the link. It is removed now.

Is the last patch ok for you?

quicksketch’s picture

Status: Needs review » Reviewed & tested by the community

The diff is now working properly and the unnecessary link to the empty diff is removed.

This looks really good and works great! Seems like it's ready to me.

  • Grimreaper authored 72707f2 on 8.x-2.x
    Issue #2856719 by Grimreaper, quicksketch, friera, richardrodriguez21:...
Grimreaper’s picture

Status: Reviewed & tested by the community » Fixed

Thanks!

This is merged now.

quicksketch’s picture

Status: Fixed » Needs work
FileSize
56.28 KB

Hi @Grimreaper, on further testing we found there is an issue with reference fields, in particular when dealing with Paragraphs.

Because paragraphs are also entities, and also have entity IDs, it seems that just forcing the top-level entity to have the same ID is not sufficient.

To test:

- Have a paragraph type with a single text field in it.
- Add a paragraph field to a sync-able content type.
- Create and delete a paragraph on one site to increment the paragraph ID on one site only.
- Create a piece of content containing a paragraph.
- Sync it to the other site.
- Make a change on the original site to the paragraph content.
- View the diff via Entity Share. See the following problem:

The diff ends up any paragraph fields showing as only existing on one site but not the other, even though values are specified (but different) on each site's copy of the content.

Screenshot of diff only on one side.

Grimreaper’s picture

Assigned: Unassigned » Grimreaper
Grimreaper’s picture

Assigned: Grimreaper » Unassigned

Here are the results of my investigations.

I reproduced the problem.

There is also the problem in the case of taxonomy term for example.

Seeing the options on admin/config/content/diff/fields and on https://git.drupalcode.org/project/diff/blob/8.x-1.x/src/Plugin/diff/Fie..., for entity reference field, there is only the option of a diff on the entity id or on the label.

For entity reference revisions, there is a dedicated plugin https://git.drupalcode.org/project/entity_reference_revisions/blob/8.x-1... which compare the entities:

$parsed_text = $this->entityParser->parseEntity($field_item->entity);

The problem is that the workaround of injecting the entity ID:

 // Force the remote entity id to be the same as the local entity otherwise
      // the diff is not helpful.
      $entity_data['attributes'][$id_public_name] = $left_revision->id();
      $right_revision = $this->jsonapiHelper->extractEntity($entity_data);

can't be done for referenced entities because the Diff module is thought to be used on one website and so in diff/src/Controller/NodeRevisionController.php:

  public function compareNodeRevisions(NodeInterface $node, $left_revision, $right_revision, $filter) {
    $storage = $this->entityTypeManager()->getStorage('node');
    $route_match = \Drupal::routeMatch();
    $left_revision = $storage->loadRevision($left_revision);
    $right_revision = $storage->loadRevision($right_revision);
    $build = $this->compareEntityRevisions($route_match, $left_revision, $right_revision, $filter);
    return $build;
  }

$right_revision has values loaded and for the entity reference fields there are values, they are populated. So when loading a referenced it is ok, the entity exists on the website.

But in the Entity share implementation, entity_share/modules/entity_share_client/src/Controller/DiffController.php, when extracting JSON data to create $right_revision, the entity has the fields, but there is no value for the entity referenced fields.

So I don't know how to go further with Diff. And I am thinking that it will require to have a custom diff implementation in Entity share.

Maybe getting JSON:API and/or Diff maintainers will be helpful.

quicksketch’s picture

I think you're right this needs to be fixed in Diff. I haven't been able to produce a working result, but I think it should be possible to fix this if instead of using the entity ID, it used a combination of the field name plus the field value delta in the keys. Then it wouldn't matter if the paragraph or file IDs were mismatched, they'd be keyed by their value position, not ID. That might have benefits for Diff itself, as there could be situations where a replacement reference is used where most of the values within the reference are the same.

Grimreaper’s picture

Thanks @quickstketch for the feedback.

Yes that could be interesting, but that will require Diff maintainers help.

And there is still the second problem.

When doing diff, the way it has been intended, on one website, you have access to all the entities.

When extracting an entity in Entity Share, the entity reference fields are empty. I will take a look into the tests of JSON:API if there is a case of inclusion allowing to get those entities when extracting.

Grimreaper’s picture

I have searched in JSON:API tests and asked on Slack if it is possible to extract an entity with entity reference values set.

In JSON:API tests, core/modules/jsonapi/tests/src/Kernel/Normalizer/JsonApiDocumentTopLevelNormalizerTest.php, there are only tests for normalization involving the inclusion feature https://www.drupal.org/docs/8/modules/jsonapi/includes.

I also put a comment on #3088227-4: Use diff in another context.

Grimreaper’s picture

Before forgetting.

Maybe a light custom solution using https://www.previousnext.com.au/blog/using-drupal-diff-component-custom-... can be tested.

harpreet16’s picture

Assigned: Unassigned » harpreet16
harpreet16’s picture

Assigned: harpreet16 » Unassigned

Maybe before using the custom solution for diff we need to get the correct "right revision entity"(remote entity) loaded for further comparison as entity reference fields are not available in the right revision. Something similar to the "public function updateRelationships(ContentEntityInterface $entity, array $data)" present in "entity_share/modules/entity_share_client/src/Service/JsonapiHelper.php" could be implemented here that will just return the data set and not import it. I have started writing a piece of code for the same but need to switch to some other work on priority. I Will update the issue as soon as I find a solution.

In my opinion loading the correct right revision needs to be taken on priority. @grimreaper should we create a new issue for addressing this?

Grimreaper’s picture

Hello,

@harpreet16: first, thanks a lot for the article https://www.srijan.net/blog/entity-share-a-cost-effective-solution-to-ma....

Second, thanks for your dedication on this issue. The custom solution of comment 34 is only a proposition in case fixing "right revision entity" would be impossible. So yes, if it will be possible to fix "right revision entity", let's go for it for sure.

I think we can stay in this issue, as it has been reopened on comment 28.

I have started writing a piece of code for the same but need to switch to some other work on priority.

: no problem, I understand completly being staffed on something else. No pressure.

harpreet16’s picture

Thanks, @grimreaper for reading the article.

harpreet16’s picture

Assigned: Unassigned » harpreet16
harpreet16’s picture

Assigned: harpreet16 » Unassigned
harpreet16’s picture

Hello @Grimreaper,

Hope you're doing well. First of all sorry for taking so much time in getting some sort of solution for the issue we are facing here.
Secondly, thanks for your suggestion of a light custom solution in #34.
I have written down some code quickly using your suggestion after going through the details of how the diff module works. Please note that I might have missed a certain edge case here. But the main motive is to get started with at least an idea as to finalize an approach.

Changes to be noted:
1. Diff won't work in our case as it has no means to load entities(referenced) from a remote site. Hence I have created Diff Plugins in the entity_share_client module that does not use target_id for comparison and builds a list of comparable attributes from the data provided.

2. In the case of remote entities, the idea is to pass the UUID of the entity (that is not there on client site) that can be used further to load attributes from its JSON endpoint. This is done as target_id for the newly created entity will not be the same as a remote one. This module works on UUID matching, hence the logic.

3. I have also made changes to few functions like- Converting one named "relationshipHandleable"(modules/entity_share_client/src/Service/JsonapiHelper.php) from "protected to public" and created getURL function in /modules/entity_share_client/src/Entity/Remote.php.

4. With new Diff plugins in place meant specifically to be used with entity_share; there is no need for enabling diff at all. Hence dependencies have been removed as well.

Please let me know if this works. The visibility of difference is not as convenient as provided by diff.

Grimreaper’s picture

Assigned: Unassigned » Grimreaper

Hello @harpreet16,

Hope you're doing well. First of all sorry for taking so much time in getting some sort of solution for the issue we are facing here.

Thanks! Thanks a lot for your patch. And no problem for the delay. I know it is hard to get time to contribute.

Thanks for the detailed explainations, I will give a look to the patch.

Grimreaper’s picture

Assigned: Grimreaper » Unassigned

Here is my review.

  1. +++ b/modules/entity_share_client/src/Controller/DiffController.php
    @@ -134,68 +164,133 @@ class DiffController extends PluginRevisionController {
    +                if (sizeof($existing_entities) != 0) {
    +                  foreach ($existing_entities as $value_id) {
    +                    $key_id = $value_id->id();
    +                    $field_data = [$main_property => $key_id];
    +                    if (isset($field_value['meta'])) {
    +                      $field_data += $field_value['meta'];
    +                    }
    +                  }
    +                }
    +                else {
    +                  $field_data = [$main_property => $value['links']['related']['href']];
    +                  if (isset($field_value['meta'])) {
    +                    $field_data += $field_value['meta'];
    +                  }
    

    Why don't you request the related entity to be able to provide a complete diff?

    Infinite loop? Or maybe too many requests?

  2. +++ b/modules/entity_share_client/src/Controller/DiffController.php
    @@ -134,68 +164,133 @@ class DiffController extends PluginRevisionController {
    +            ['data' => t('Removal'), 'colspan' => '2'],
    +            ['data' => t('Additions'), 'colspan' => '2'],
    

    I would have named the headers as before, to be clear of what represents the remote entity and what represents the local entity.

  3. +++ b/modules/entity_share_client/src/DiffManager.php
    @@ -0,0 +1,96 @@
    +    'Plugin/diff',
    

    Plugin/EntityShareClient/diff to be sure to not interfere with the diff module.

  4. +++ b/modules/entity_share_client/src/DiffManagerBase.php
    @@ -0,0 +1,71 @@
    +abstract class DiffManagerBase extends PluginBase implements DiffGeneratorInterface, ContainerFactoryPluginInterface {
    

    I would have named it DiffParserBase.

  5. +++ b/modules/entity_share_client/src/Entity/Remote.php
    @@ -97,4 +97,14 @@ class Remote extends ConfigEntityBase implements RemoteInterface {
    +  public function getUrl() {
    

    Same as #3139150-3: Get the remote Entity ID, I think you don't need this method.

Beyond the review, great work, but...

  1. The way it is done, maybe it can now be a dedicated sub-module or a module.
  2. If you can, please make a patch for the 8.x-3.x branch. As I doubt I will merge any new features on the 8.x-2.x
  3. Yes, the UI is less convenient than with the Diff module.
  4. main point: The main problem of referenced entities is still there. Maybe @quicksketch who reopened the issue comment 28 can give feedback on your work too.

1. Diff won't work in our case as it has no means to load entities(referenced) from a remote site.

I think we can, by making a GET on $value['links']['related']['href'], and then JsonapiHelper::extractEntity, we can have an entity object that can be injected in the entity we wan't to see the diff.

This would be the approach I would try.

And/Or, changing diff on referenced entities into a link to a new custom controller page, where the diff of this new entity will be done, etc.

Is it ok for you?

Regards,

Grimreaper’s picture

Version: 8.x-2.x-dev » 8.x-3.x-dev
harpreet16’s picture

Thanks a lot @grimreaper for your valuable feedback. I will work on your feedback and come back with a separate module.
Also look forward to feedbacks/suggestions from @quicksketch.

ivan.vujovic’s picture

Assigned: Unassigned » ivan.vujovic
ivan.vujovic’s picture

Assigned: ivan.vujovic » Grimreaper
Status: Needs work » Needs review
FileSize
55.29 KB

Hello,

I added the patch which should solve the issue of referenced entities (and some other issues).
Referenced entity can now be either embedded into Diff (paragraphs, media) or just its UUID can be listed (all other cases - nodes, terms...).

I couldn't provide the interdiff to the patch of @harpreet16 because of conflicts I had rebasing (in the meantime two big features have been merged).

What may still be needed to do:

  • Rename classes related to Diff plugins (DiffManagerBase for example)
  • For referenced entity we may provide a title (label) along with the UUID
  • Although I enabled Dynamic entity references to work in Diff, I had some issues synchronizing them, need to check it
  • Some code refactoring: I think I added too many parameters to parseEntity() and parseField() etc.
  • Ideally, make indentation visible in the Diff: right now in HTML source multiple padding spaces exist ( ) and it would be nice if they could be actually visible
Grimreaper’s picture

Hello,

@ivan.vujovic, Thanks a lot for the patch!

Here is a summary of our discussion.

I will test with recursive paragraphs to see the real effect of the patch. And I will test with the approach I mentioned in my comment 43:

I think we can, by making a GET on $value['links']['related']['href'], and then JsonapiHelper::extractEntity, we can have an entity object that can be injected in the entity we wan't to see the diff.

And post the screenshots of the results.

Because the suggestion I made on comment 37 which led to using core diff system was only in a first time for experiment.

And even if this not much code, if we can avoid reinventing what the Diff module does that would be nice.

So I am testing what I have in mind and then, we will be able to compare and take a decision.

For Dynamic Entity Reference fields, it is "normal" that sharing is not working, there is a dedicated issue #3056102: Support dynamic entity reference fields.

Cheers :)

Grimreaper’s picture

I have tested the custom diff with subparagraphs and it works. Nice @Ivan.vujovic!

The screenshots are from the Diff module on a revision comparaison on the same site, native Diff usage, and it also works recursively with paragraphs.

I have tested the approach I wanted to test on comment 37, and now I know why it won't work. When unserializing the referenced content, and injecting it into the $right_revision, the problem is that it does not work. the values in the entity reference fields are target_id which changes between the local and remote entities. So impossible to use Diff module properly on Entity Share when dealing with Entity Reference fields.

Except if someone else has an idea on that?

I agree now that the approach with custom diff plugin is the only one remaining.

In addition (may be redundant) to what @ivan.vujovic wrote in comment 47, this is what I think needs to be done:

  • Decide if this should be a sub-module, entity_share_diff, or part of entity_share_client
  • Uniformize with the other plugin system in terms of class names and position in codebase, dedicated folder, etc.
  • Refactor some parts to avoid duplicated code (will point it out in review)
  • Keep the table header like it is currently, so it clearer what is local and what is remote
  • Improve the diff table to look the more similar as possible as what the Diff module provides because otherwise it is hard to distinguish field names of field values and referenced entities
  • Similar to /admin/config/content/diff/fields, if possible have a way to choose what field we want to diff or not so it will avoid to have hardcoded list of ignored field, etc. This may justify having a sub-module.

Any opinion on that?

  1. +++ b/modules/entity_share_client/src/Service/EntityParser.php
    @@ -0,0 +1,360 @@
    +    $resource_type = $this->resourceTypeRepository->get(
    +      $entity->getEntityTypeId(),
    +      $entity->bundle()
    +    );
    +    return $resource_type;
    

    I wonder if this can be refactored, or it is worth refactoring.

  2. +++ b/modules/entity_share_client/src/Service/EntityParser.php
    @@ -0,0 +1,360 @@
    +  public function referencedTypesHandlable(array $entity_type_ids) {
    +    if (empty($entity_type_ids)) {
    +      return FALSE;
    +    }
    +    // All referenced entity types must be supported.
    +    foreach ($entity_type_ids as $entity_type_id) {
    +      if ($entity_type_id == 'user') {
    +        return FALSE;
    +      }
    +      if ($this->entityDefinitions[$entity_type_id]->getGroup() == 'configuration') {
    +        return FALSE;
    +      }
    +    }
    +    return TRUE;
    +  }
    

    Need to refactor with modules/entity_share_client/src/Plugin/EntityShareClient/Processor/EntityReference.php::isUserOrConfigEntity()

ivan.vujovic’s picture

Assigned: ivan.vujovic » Grimreaper
Status: Needs work » Needs review
FileSize
75.28 KB
58.97 KB

Hello @grimreaper,

The new patch contains the fixes for the most of the issues that you and I raised for the patch of #47.

What I didn't do:

  • Add a Back-office page with ability to configure plugins (set if a field should be skipped, show as embedded, shown as UUID...). I didn't want to do this now, mostly because it would take too much time.

What I did, among other things:

  • Separated the Diff-related functionality into a module.
  • Added a new helper function getPublicFieldName(string $field_name, array $entity_json_data) instead of not-so-useful getResourceType(ContentEntityInterface $entity); I also think that this new helper can be used in several other cases.

As for the look-and-feel of the Diff output: currently it depends on website configuration - when you do drush cset system.diff context.lines_trailing 100 it looks good, but if the number of context lines is too small, it might not be possible to see the name of the embedded field.
I think we should manipulate this config for our needs, but without affecting the other cases where core Diff is used, such as at /admin/config/development/configuration.

ivan.vujovic’s picture

@grimraper I forgot to update README.txt and section "RECOMMENDED MODULES" where Diff module is mentioned.

Grimreaper’s picture

Assigned: Grimreaper » Unassigned
Status: Needs review » Needs work
FileSize
203.3 KB

Hello,

@ivan.vujovic, really good work! Thanks a lot for your patch!

Before going further, I would like to get some feedbacks from @harpreet16 and @quicksketch.

So do not take my review points into account please. Especially the coding standards/unused variables, I can handle it when merging if no other patch has to be provided.

  1. +++ b/modules/entity_share_client/src/Form/PullForm.php
    @@ -660,7 +660,7 @@ class PullForm extends FormBase {
    +    if ($this->moduleHandler->moduleExists('entity_share_diff')) {
    

    Now that we depend of a sub-module of our own and not a contrib module, would it be possible to do like in entity_share_async, with a hook_form_FORM_ID_alter?

    If yes, we can remove the moduleHandler service because it is no more used.

    (Also, maybe we will have to think on an approach to not have entity_share_async removing the diff link)

  2. +++ b/modules/entity_share_client/src/Service/EntityReferenceHelper.php
    @@ -0,0 +1,106 @@
    +class EntityReferenceHelper {
    

    I really like this idea!

    Can we introduce an interface for that service please?

  3. +++ b/modules/entity_share_client/src/Service/FormHelper.php
    @@ -192,32 +192,34 @@ class FormHelper implements FormHelperInterface {
    +    if ($this->moduleHandler->moduleExists('entity_share_diff')) {
    

    Same as for the PullForm, if possible, move that in hook_form_FORM_ID_alter into entity_share_diff.

  4. +++ b/modules/entity_share_diff/entity_share_diff.services.yml
    @@ -0,0 +1,20 @@
    +    arguments: ['@config.factory']
    

    If you want to override the diff.formatter service. You can avoid to have ro redeclare the arguments (and so if diff.formatter will change it will be automatically taken into account) by adding "parent: diff.formatter".

    See modules/entity_share_client/tests/modules/entity_share_client_remote_manager_test/entity_share_client_remote_manager_test.services.yml

  5. +++ b/modules/entity_share_diff/src/Annotation/DiffGenerator.php
    @@ -0,0 +1,42 @@
    +
    

    Missing "declare(strict_types = 1);". I will do a check when commiting.

  6. +++ b/modules/entity_share_diff/src/Annotation/DiffGenerator.php
    @@ -0,0 +1,42 @@
    + * Note that the "@ Annotation" line below is required and should be the last
    + * line in the docblock. It's used for discovery of Annotation definitions.
    

    I think this line can be removed.

  7. +++ b/modules/entity_share_diff/src/Controller/DiffController.php
    @@ -0,0 +1,181 @@
    +    $build = [];
    

    Unused variable.

  8. +++ b/modules/entity_share_diff/src/Controller/DiffController.php
    @@ -0,0 +1,181 @@
    +    $build = $this->diffGenerator($left_yaml, $right_yaml, $header);
    +    return $build;
    

    I think you can just do "return $this->..."

  9. +++ b/modules/entity_share_diff/src/Controller/DiffController.php
    @@ -0,0 +1,181 @@
    +    $left_changed = '';
    

    Unused variable.

  10. +++ b/modules/entity_share_diff/src/Controller/DiffController.php
    @@ -0,0 +1,181 @@
    +   * Helper.
    

    PHPDoc to complete.

  11. +++ b/modules/entity_share_diff/src/Diff/DiffFormatter.php
    @@ -0,0 +1,67 @@
    +    if (empty($this->htmlOutput)) {
    

    Is "if (!$this->htmlOutput) {" ok? Because htmlOutput is a boolean

  12. +++ b/modules/entity_share_diff/src/Plugin/DiffGenerator/EntityReferenceFieldDiffParser.php
    @@ -0,0 +1,87 @@
    +      $data = $entities_json['data'] ?? [];
    

    Unused variable.

  13. +++ b/modules/entity_share_diff/src/Plugin/DiffGenerator/FileFieldDiffParser.php
    @@ -0,0 +1,100 @@
    +            $label = $label;
    

    ?

  14. +++ b/modules/entity_share_diff/src/Plugin/DiffGenerator/FileFieldDiffParser.php
    @@ -0,0 +1,100 @@
    +      $data = $entities_json['data'] ?? [];
    

    Unused variable.

    And some small code duplication.

  15. +++ b/modules/entity_share_diff/src/Service/EntityParser.php
    @@ -0,0 +1,370 @@
    +    $embeddable_types = [
    +      'paragraph',
    +      'media',
    +    ];
    

    Can we put this list into a constant in the class please? so if someone wants to override it he/she, only have to override the service and replace the constant.

    This would be a compromise between having a config form and the availability to override it.

    Or this can stay as it is and people overriding the service only have to override this method. As for the getFieldsIrrelevantForDiff it is impossible to put the list into a constant.

    Forget my comment.

  16. +++ b/modules/entity_share_diff/src/Service/EntityParser.php
    @@ -0,0 +1,370 @@
    +    $field_names = [];
    

    Unused variable.

What I didn't do:

Add a Back-office page with ability to configure plugins (set if a field should be skipped, show as embedded, shown as UUID...). I didn't want to do this now, mostly because it would take too much time.

Absolutely no problem with that. This is already a very big patch and feature. If people want to push further they will have to open a new issue. No need to over-engineer the stuff.

About the dependence on the diff configuration:

  • I tried to change it with the provided Drush command, I didn't see any change, also after clearing the cache. I also change the other setting "lines_leading", also no effect
  • I have attached a screenshot with a paragraph. I wonder if this is because the diff component is seeing the timestamp field as change that the 'Text plain' field from the paragraph is not indented.
  • Also about the diff config, if it has an effect, to avoid impacting other parts of the website, we can provide a small config form and use it to override diff settings injected in the service used to override core service.

As of the introduction of a new sub-module for something inside the "main" module. I wonder if we should add a hook_update to enable it.

PS: ok about Readme.

Thanks again @ivan.vujovic! I think we are really near the end of this issue.

Regards,

ivan.vujovic’s picture

Hello @grimreaper, thank you for your review and the feedback!

Some answers:
- The timestamp problem: actually we need the separate plugin for datetime fields, but the issue is the same as in CoreFieldDiffParser:

          // For some reason local numbers are represented as strings,
          // while remote numbers are indeed numbers. In order to avoid fake
          // differences, simply cast all numbers to strings.
          elseif (in_array($type, ['float', 'integer', 'decimal'])) {
            $result[$field_key] = (string) $result[$field_key];
          }

- A hook_update to enable the new submodule: absolutely! I failed to see that diff functionality exists in 8.x-3.x :)
- Using hook_form_FORM_ID_alter() of the PullForm: yes, that was my idea as well. However I was hesitating to do so, because of the way FormHelper::addOptionFromJson() was done - it would mean we would have to repeat a lot of code to get variables needed to generate the Diff URL. So my idea is to add a new helper service which would treat a single row of the import table, and which could cache the needed variables as class properties.
- EntityReferenceHelperInterface.php - sure, let's add it!
- Configuration of the number of Diff context lines: maybe some cache needs to be cleared, but this setting definitely has effect on the diff. Also it affects other Diff core usages, so I suggest a flag in our decorated service: we can either introduce a new Setting to use just with diff, or simply hardcode these values in our service - but only if this flag is on (similar to what I did with if (empty($this->htmlOutput))...)

ivan.vujovic’s picture

Assigned: Unassigned » ivan.vujovic
ivan.vujovic’s picture

Assigned: ivan.vujovic » Grimreaper
Status: Needs work » Needs review
FileSize
82.13 KB
16.04 KB

Hello @grimreaper,

I am adding the fixes for your feedback in comment #52.

I only didn't do anything about your hook_form_FORM_ID_alter suggestion, we still have the not-so-good condition $this->moduleHandler->moduleExists('diff').

Grimreaper’s picture

Aout the review points from comment 52:
1: ok, postponed
2: ok
3: ok, postponed
4: ok
5: ok
6: ok
7: ok
8: ok
9: ok
10: ok
11: ok
12: ok
13: ko
14: ok
15: ok
16: ok

I will fix 13

Will do a new code review and manual testing.

I have created a PR for easier code review.

Thanks a lot @ivan.vujovic!!!

Grimreaper’s picture

I will fix the small adjustments then manual testing.

  • ivan.vujovic authored 68958f9 on 8.x-3.x
    Issue #2856719 by Grimreaper, ivan.vujovic, harpreet16, quicksketch,...
  • harpreet16 authored 68eb8b2 on 8.x-3.x
    Issue #2856719 by Grimreaper, ivan.vujovic, harpreet16: Diff on entities
    
  • Grimreaper authored cb693bb on 8.x-3.x
    Issue #2856719 by Grimreaper, ivan.vujovic, harpreet16: Diff on entities
    
Grimreaper’s picture

Assigned: Grimreaper » Unassigned
Status: Needs review » Fixed

Manual test ok. I manually re-do the commits for proper credit attribution.

Thanks everyone!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.