Creates a reverse entity reference field so that one could find out which fields are being referencing a particular entity.
Similar Module:
https://www.drupal.org/project/entityreference_backreference
Difference:
Uses a computed field rather than a property and is for Drupal 8.

Module:
https://www.drupal.org/sandbox/geraldnda/2847085

Git Clone Command:
git clone --branch 8.x-2.x https://git.drupal.org/sandbox/GeraldNDA/2847085.git reverse_entity_reference

Other Applications:
None

CommentFileSizeAuthor
#9 Screenshot 2017-02-27 13.34.59.png468.88 KBAndre-B
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

GeraldNDA created an issue. See original summary.

PA robot’s picture

Issue summary: View changes

Fixed the git clone URL in the issue summary for non-maintainer users.

We are currently quite busy with all the project applications and we prefer projects with a review bonus. Please help reviewing and put yourself on the high priority list, then we will take a look at your project right away :-)

Also, you should get your friends, colleagues or other community members involved to review this application. Let them go through the review checklist and post a comment that sets this issue to "needs work" (they found some problems with the project) or "reviewed & tested by the community" (they found no major flaws).

I'm a robot and this is an automated message from Project Applications Scraper.

andrew_tspkh’s picture

Status: Active » Needs work

Hi, @GeraldNDA
Please, check using of \Drupal calls in BackReferenceProcessed class [line:23, line:30].
\Drupal::service() calls should be avoided in classes, use dependency injection instead.

Here is example:


/**
   * The query factory.
   *
   * @var \Drupal\Core\Entity\Query\QueryFactory
   */
  protected $queryFactory;

  /**
   * Constructs a BackReferenceProcessed object.
   *
   * @param \Drupal\Core\TypedData\DataDefinitionInterface $definition
   *   The data definition.
   * @param \Drupal\Core\Entity\Query\QueryFactory $query_factory
   *   The query factory.
   */
  public function __construct($definition, QueryFactory $query_factory) {
    parent::__construct($definition);
    $this->queryFactory = $query_factory;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, $definition) {
    return new static(
      $definition,
      $container->get('entity.query')
    );
  }

andrew_tspkh’s picture

And remove unnecessary folder .vscode.
Thanks)

deminy’s picture

This module is something I'm looking for; however, I noticed following errors when trying to install this sandbox module with Drush:

Error: Call to a member function getSetting() on null in reverse_entity_reference_entity_bundle_field_info_alter() (line 24 of /www/modules/contrib/reverse_entity_reference/reverse_entity_reference.module).
Drush command terminated abnormally due to an unrecoverable error. [error]
PHP Fatal error: Uncaught Error: Call to a member function getSetting() on null in /www/modules/contrib/reverse_entity_reference/reverse_entity_reference.module:24
Stack trace:
#0 /www/core/lib/Drupal/Core/Extension/ModuleHandler.php(501): reverse_entity_reference_entity_bundle_field_info_alter(Array, Object(Drupal\Core\Entity\ContentEntityType), 'basic')
#1 /www/core/lib/Drupal/Core/Entity/EntityFieldManager.php(382): Drupal\Core\Extension\ModuleHandler->alter('entity_bundle_f...', Array, Object(Drupal\Core\Entity\ContentEntityType), 'basic')
#2 /www/core/lib/Drupal/Core/Entity/EntityFieldManager.php(298): Drupal\Core\Entity\EntityFieldManager->buildBundleFieldDefinitions('block_content', 'basic', Array)
#3 /www/core/lib/Drupal/Core/Entity/EntityManager.php(145): Drupal\Core\Entity\EntityFieldManager->getFieldDefinitions('block_content', 'basic')
#4 /www/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php(1107): Drup in /www/modules/contrib/reverse_entity_reference/reverse_entity_reference.module on line 24
Drush command terminated abnormally due to an unrecoverable error. [error]
Error: Uncaught Error: Call to a member function getSetting() on null

GeraldNDA’s picture

Status: Needs work » Needs review

@justin. I removed .vscode folder and I also moved the addition of the service to the __construct method. However since EntityReferenceFieldItemList doesn't have a container or a create method, I don't think I can inject the dependency the way you are prescribing.

@deminy I created a new branch called 8.x-2.x-dev. If you could, please download that version and try installing it. And repost your error message. I think what is going in on is somehow a field doesn't have a field storage definition. I assume that there always was. So before I band-aid fix it I'd like to do some more investigation and maybe see if it's not this module or something else.

Thanks for all your help so far.

Andre-B’s picture

Hello,

Manual review:
1.) Some code style violations:

$ phpcs --standard=Drupal,DrupalPractice --extensions=php,module,inc,install,test,profile,theme,css,info,txt,md .

FILE: /reverse_entity_reference/README.md
----------------------------------------------------------------------
FOUND 1 ERROR AND 3 WARNINGS AFFECTING 4 LINES
----------------------------------------------------------------------
  3 | WARNING | [ ] Line exceeds 80 characters; contains 228
    |         |     characters
 11 | WARNING | [ ] Line exceeds 80 characters; contains 112
    |         |     characters
 22 | WARNING | [ ] Line exceeds 80 characters; contains 112
    |         |     characters
 30 | ERROR   | [x] Expected 1 newline at end of file; 2 found
----------------------------------------------------------------------
PHPCBF CAN FIX THE 1 MARKED SNIFF VIOLATIONS AUTOMATICALLY
----------------------------------------------------------------------

2.) short array syntax will be favored in future: https://www.drupal.org/node/2135291
3.) Inline comments would help to understand what's going on. Especially with the nested foreach loops - probably even better to break them up in smaller pieces.
4.) Possible exceeding of maximum length for field names as of https://www.drupal.org/node/2232665

reverse_entity_reference.module:
l36: $new_field_name = $field_name . '_' . $referring_entity . '_eb';

5.) Possible duplication of entries returned:

src/BackReferenceProcessed.php
l54: $entity_ids = array_merge($entity_ids, $result);

can be fixed by adding array_unique() in line 57: return array_unique($entity_ids);

klausi’s picture

@Andre-B: looks like you forgot to change the status. That issues don't look like application blockers, anything else that you found or should this be set to RTBC?

Andre-B’s picture

Andre-B’s picture

Status: Needs review » Reviewed & tested by the community

@klausi I wasn't done - as far as I can tell I don't see application blockers. Looks good.

Andre-B’s picture

Please ignore the uploaded file. attached and changed the wrong comment. Looks good so far.

GeraldNDA’s picture

Update:
Thanks for the reviews. I recently pushed to the main 8.x-2.x branch fixes to most of the issues mentioned. For next time, I'll probably look towards

2.) Especially with the nested foreach loops ... break them up in smaller pieces

and possibly tackling

4.) Possible exceeding of maximum length for field names as of https://www.drupal.org/node/2232665

That particular issue seems pretty difficult to tackle so any input would be appreciated.

deminy’s picture

@GeraldNDA, I played with commit 1e22a68f4efa6fde0d365950b4382d1364a06145 under branch 8.x-2.x-dev, and noticed same issue when installing the module via Drush:

# /var/bin/drush.sh pm-enable reverse_entity_reference
The following extensions will be enabled: reverse_entity_reference
Do you really want to continue? (y/n): y
Error: Call to a member function getSetting() on null in /var/www/modules/contrib/reverse_entity_reference/reverse_entity_reference.module on line 36 #0 /var/www/core/lib/Drupal/Core/Extension/ModuleHandler.php(501): reverse_entity_reference_entity_bundle_field_info_alter(Array, Object(Drupal\Core\Entity\ContentEntityType), 'basic')
#1 /var/www/core/lib/Drupal/Core/Entity/EntityFieldManager.php(382): Drupal\Core\Extension\ModuleHandler->alter('entity_bundle_f...', Array, Object(Drupal\Core\Entity\ContentEntityType), 'basic')
#2 /var/www/core/lib/Drupal/Core/Entity/EntityFieldManager.php(298): Drupal\Core\Entity\EntityFieldManager->buildBundleFieldDefinitions('block_content', 'basic', Array)
#3 /var/www/core/lib/Drupal/Core/Entity/EntityManager.php(145): Drupal\Core\Entity\EntityFieldManager->getFieldDefinitions('block_content', 'basic')
#4 /var/www/core/modules/views/views.views.inc(252): Drupal\Core\Entity\EntityManager->getFieldDefinitions('block_content', 'basic')
#5 /var/www/core/modules/views/views.views.inc(419): views_entity_field_label('block_content', 'body')
#6 /var/www/core/modules/views/views.views.inc(185): views_field_default_views_data(Object(Drupal\field\Entity\FieldStorageConfig))
#7 [internal function]: views_views_data()
#8 /var/www/core/lib/Drupal/Core/Extension/ModuleHandler.php(391): call_user_func_array('views_views_dat...', Array)
#9 /var/www/core/modules/views/src/ViewsData.php(245): Drupal\Core\Extension\ModuleHandler->invoke('views', 'views_data')
#10 /var/www/core/modules/views/src/ViewsData.php(162): Drupal\views\ViewsData->getData()
#11 /var/www/core/modules/views/src/Plugin/Derivative/ViewsEntityRow.php(91): Drupal\views\ViewsData->get('block_content')
#12 /var/www/core/lib/Drupal/Component/Plugin/Discovery/DerivativeDiscoveryDecorator.php(100): Drupal\views\Plugin\Derivative\ViewsEntityRow->getDerivativeDefinitions(Array)
#13 /var/www/core/lib/Drupal/Component/Plugin/Discovery/DerivativeDiscoveryDecorator.php(86): Drupal\Component\Plugin\Discovery\DerivativeDiscoveryDecorator->getDerivatives(Array)
#14 /var/www/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php(280): Drupal\Component\Plugin\Discovery\DerivativeDiscoveryDecorator->getDefinitions()
#15 /var/www/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php(175): Drupal\Core\Plugin\DefaultPluginManager->findDefinitions()
#16 /var/www/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryCachedTrait.php(22): Drupal\Core\Plugin\DefaultPluginManager->getDefinitions()
#17 /var/www/core/lib/Drupal/Core/Plugin/Factory/ContainerFactory.php(16): Drupal\Core\Plugin\DefaultPluginManager->getDefinition('data_field')
#18 /var/www/core/lib/Drupal/Component/Plugin/PluginManagerBase.php(84): Drupal\Core\Plugin\Factory\ContainerFactory->createInstance('data_field', Array)
#19 /var/www/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php(810): Drupal\Component\Plugin\PluginManagerBase->createInstance('data_field')
#20 /var/www/core/modules/views/src/Plugin/views/style/StylePluginBase.php(122): Drupal\views\Plugin\views\display\DisplayPluginBase->getPlugin('row')
#21 /var/www/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php(813): Drupal\views\Plugin\views\style\StylePluginBase->init(Object(Drupal\views\ViewExecutable), Object(Drupal\rest\Plugin\views\display\RestExport), Array)
#22 /var/www/core/modules/views/src/ViewExecutable.php(872): Drupal\views\Plugin\views\display\DisplayPluginBase->getPlugin('style')
#23 /var/www/core/modules/views/src/ViewExecutable.php(1829): Drupal\views\ViewExecutable->initStyle()
#24 /var/www/core/modules/views/src/Plugin/views/display/PathPluginBase.php(132): Drupal\views\ViewExecutable->getTitle()
#25 /var/www/core/modules/views/src/Plugin/views/display/PathPluginBase.php(220): Drupal\views\Plugin\views\display\PathPluginBase->getRoute('art_team', 'download_items')
#26 /var/www/core/modules/rest/src/Plugin/views/display/RestExport.php(323): Drupal\views\Plugin\views\display\PathPluginBase->collectRoutes(Object(Symfony\Component\Routing\RouteCollection))
#27 /var/www/core/modules/views/src/EventSubscriber/RouteSubscriber.php(120): Drupal\rest\Plugin\views\display\RestExport->collectRoutes(Object(Symfony\Component\Routing\RouteCollection))
#28 [internal function]: Drupal\views\EventSubscriber\RouteSubscriber->routes()
#29 /var/www/core/lib/Drupal/Core/Routing/RouteBuilder.php(146): call_user_func(Array)
#30 /var/www/core/lib/Drupal/Core/ProxyClass/Routing/RouteBuilder.php(83): Drupal\Core\Routing\RouteBuilder->rebuild()
#31 /var/www/core/lib/Drupal/Core/Extension/ModuleInstaller.php(302): Drupal\Core\ProxyClass\Routing\RouteBuilder->rebuild()
#32 /var/www/core/lib/Drupal/Core/ProxyClass/Extension/ModuleInstaller.php(83): Drupal\Core\Extension\ModuleInstaller->install(Array, true)
#33 /var/www/vendor/drush/drush/commands/core/drupal/environment.inc(131): Drupal\Core\ProxyClass\Extension\ModuleInstaller->install(Array, true)
#34 /var/www/vendor/drush/drush/commands/core/drupal/environment.inc(198): drush_module_install(Array)
#35 /var/www/vendor/drush/drush/commands/pm/pm.drush.inc(1167): drush_module_enable(Array)
#36 /var/www/vendor/drush/drush/includes/command.inc(422): drush_pm_enable('reverse_entity_...')
#37 /var/www/vendor/drush/drush/includes/command.inc(231): _drush_invoke_hooks(Array, Array)
#38 /var/www/vendor/drush/drush/includes/command.inc(199): drush_command('reverse_entity_...')
#39 /var/www/vendor/drush/drush/lib/Drush/Boot/BaseBoot.php(67): drush_dispatch(Array)
#40 /var/www/vendor/drush/drush/includes/preflight.inc(66): Drush\Boot\BaseBoot->bootstrap_and_dispatch()
#41 /var/www/vendor/drush/drush/drush.php(12): drush_main()
#42 {main}
Error: Call to a member function getSetting() on null in reverse_entity_reference_entity_bundle_field_info_alter() (line 36 of /var/www/modules/contrib/reverse_entity_reference/reverse_entity_reference.module).
Drush command terminated abnormally due to an unrecoverable error.

Looks like some issue with entity type "basic" which I don't use directly in my installation of Drupal 8.

GeraldNDA’s picture

@deminy Try again with the most recent commit and tell me what you get in your database log. I'm starting to think it may be a deleted field that wasn't finalized so it still gets loaded as connected to the entity or something like that. But I modified the code so that it should skip the one causing the issue.

deminy’s picture

@GeraldNDA I tried to install the module via Drush with latest commit ( 73de02c ) that you pushed out yesterday. The PHP error disappeared, however, the Drush command hang over there forever, which also blocked other HTTP requests to same Drupal site.

At first I thought it might be a memory limit issue; however, same issue happened when I tried to install the module on another server with enough amount of memory. Based on what I checked, it happens inside function reverse_entity_reference_entity_bundle_field_info_alter() or classes/methods called inside that function.

GeraldNDA’s picture

@deminy That's really peculiar and I'll look into the issue. I suggest opening an issue on the project issues page: https://www.drupal.org/node/add/project-issue/reverse_entity_reference . I'm currently trying to working through this issue and also planning to integrate a service and options so you don't have to add fields by default but can still have reverse referencing.

deminy’s picture

@GeraldNDA I just created a first issue under project "Reverse Entity Reference", as you can see from https://www.drupal.org/node/2860598

Thanks

apaderno’s picture

Assigned: Unassigned » apaderno
Status: Reviewed & tested by the community » Fixed

Thank you for your contribution!

I am going to update your account so you can opt into security advisory coverage now.

These are some recommended readings to help with excellent maintainership:

You can find more contributors chatting on the IRC #drupal-contribute channel. So, come hang out and stay involved.

Thank you, also, for your patience with the review process.
Anyone is welcome to participate in the review process. Please consider reviewing other projects that are pending review. I encourage you to learn more about that process and join the group of reviewers.

I thank all the dedicated reviewer(s) as well.

apaderno’s picture

Status: Fixed » Closed (fixed)

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