Skip to content
This repository has been archived by the owner on Aug 25, 2022. It is now read-only.

Graph refactoring #13

Merged
merged 30 commits into from
Jan 23, 2018
Merged

Graph refactoring #13

merged 30 commits into from
Jan 23, 2018

Conversation

claudiu-cristea
Copy link
Contributor

@claudiu-cristea claudiu-cristea commented Jan 9, 2018

Working on this refactor, I've also opened next issues: #14, #15, #16, #17, #18, #19.

API.md Outdated

Entities using the SPARQL storage can be stored in different graphs, which are
actually versions of the same entity, You can use graphs, for example, to store
a draft version of the entity.
Copy link
Contributor

Choose a reason for hiding this comment

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

In reality, this is a Joinup feature and it is going against the philosophy of the RDF. A graph is a group of triples that are supposed to describe entities belonging to a certain thematic group, e.g. collections, movies, authors etc.

Copy link
Contributor

Choose a reason for hiding this comment

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

This small piece could refer to the rdf draft module that uses the graphs as states to store versions of the same entity.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So graphs are in fact bundles (entities belonging to a certain thematic group, e.g. collections, movies, authors etc.) ? :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

And the "draft" thing was only to give an example. Of course, based on our use case.

API.md Outdated

### Graphs CRUD

Graphs are config entities of type `rdf_entity_graph` and are supporting the
Copy link
Contributor

Choose a reason for hiding this comment

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

did you mean 'are supported by'?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I said "are supporting". That means they are subject of the whole config entity API.


// Load from the first graph where the entity exists. First, the storage will
// attempt to load the entity from the 'draft' graph. If this entity doesn't
// exist in the 'draft' graph, will fallback to the next one which is 'sync' and
Copy link
Contributor

Choose a reason for hiding this comment

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

Marking to be commented: I haven't looked into all the changes yet, but last time I checked, all triples were returned from the database from all available graphs. The triples were the processed by the RdfEntitySparqlStorage class and the appropriate entity was returned instead.

To be checked later on.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

he triples were the processed by the RdfEntitySparqlStorage

Yes. this ($storage) is actually a RdfEntitySparqlStorage class. So, it returns a single entity, not all.

API.md Outdated
// Load from the first graph where the entity exists. First, the storage will
// attempt to load the entity from the 'draft' graph. If this entity doesn't
// exist in the 'draft' graph, will fallback to the next one which is 'sync' and
// so on. If fails with all, the normal behaviour is in place: will return NULL.
Copy link
Contributor

Choose a reason for hiding this comment

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

'If the entity is not found in any graph' or 'If searching in all graphs fail' is more appropriate here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK. Changed.

core: 8.x
package: Joinup
package: Custom
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we could have our own name since all of these modules are related to RDF data. 'RDF Entity' could do for now.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're right but I expanded too much the initial scope of this issue. Opened #14 to do this change.

$mapping = $form_state->get('rdf_entity_mapping');
$values = $form_state->getValue('rdf_entity');

try {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why try? Normally we should have a stable version. Try won't do any good here as it is only 'debugging' it.

If something breaks we should allow it to break because it means we have a bug in our code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK, let's propagate the exception but I still want to log it.

use Drupal\rdf_entity\RdfEntityGraphInterface;

/**
* Toggles a RDf entity graph to enable or disable.
Copy link
Contributor

Choose a reason for hiding this comment

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

'Toggles an' is correct here. The 'a' or 'an' follows the pronunciation of the next word and in the case of an acronym, the sound is taken into an account. In the current example, it's read as 'Ar Di Ef' so it is 'an Ar Di Ef entity'.

Copy link
Contributor

Choose a reason for hiding this comment

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

Disclaimer: I am not a language expert, it just happened that we had the exact same issue for the 'RDF' word and we looked it up :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok :)

* Used to store basic information about each RDF entity graph.
*
* @ConfigEntityType(
* id = "rdf_entity_graph",
Copy link
Contributor

Choose a reason for hiding this comment

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

This can probably be rdf_graph.

Copy link
Contributor Author

@claudiu-cristea claudiu-cristea Jan 22, 2018

Choose a reason for hiding this comment

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

No. I like (and it's a good practice) to fully namespace the identifiers. So "rdf_entity" is the module name and "graph" the entity type itself. The same I did for rdf_entity_mapping.

@@ -29,6 +36,8 @@ function rdf_entity_entity_base_field_info_alter(&$fields, EntityTypeInterface $
return;
}

// @todo Now that graphs are entities, transform this field into an entity
Copy link
Contributor

Choose a reason for hiding this comment

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

I checked all the bundles and this properties is now empty. Isn't this replaced by the graph entities?

Copy link
Contributor Author

@claudiu-cristea claudiu-cristea Jan 22, 2018

Choose a reason for hiding this comment

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

I checked all the bundles and this properties is now empty. Isn't this replaced by the graph entities?

Not sure I understand your question. This is a base field added to all rdf_entity entities. The field is a URI (basically a string) and it's stored in the 'value' column. Now that the graphs are config entities we could transform this field into a entity reference because now it stores the ID of an rdf_entity_graph entity. I've opened a follow-up in #15.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh $&#* I totally understood wrong here.. I got confused by the label of the field. Sorry. This is wrong by me.

*/
public function __construct(EntityTypeManagerInterface $entity_type_manager, ModuleHandlerInterface $module_handler) {
public function __construct(EntityTypeManagerInterface $entity_type_manager) {
Copy link
Contributor

Choose a reason for hiding this comment

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

You can always initiate the $rdfEntityGraphStorage in the constructor as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I prefer the lazy-loading method

$storage = \Drupal::entityTypeManager()->getStorage($entity->getEntityTypeId());
}
catch (\Exception $exception) {
return [];
Copy link
Contributor

Choose a reason for hiding this comment

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

Is masking the exception intended here?

// RdfEntitySparqlStorage and move their 3rd party settings belonging to
// rdf_entity module into their dedicated rdf_entity_mapping config entities.
foreach ($entity_type_manager->getDefinitions() as $entity_type_id => $entity_type) {
if ($storage = $entity_type_manager->getStorage($entity_type_id)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe it is just esthetic, but the cyclomatic complexity could be decreased here by inverting the check and issuing a continue; after each check. e.g.
if ( !($storage instanceof RdfEntitySparqlStorage) ) {
continue;
}

$graph_uri = $form_state->getValue('graph_' . $definedGraphName);
$third_party_settings[$definedGraphName] = $graph_uri;
catch (\Exception $exception) {
\Drupal::logger('rdf_entity')->critical(t('Could not save RDF entity mapping'), ['exception' => $exception]);
Copy link
Contributor

Choose a reason for hiding this comment

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

I think all non-caught runtime exceptions are logged anyway...

}
}
catch (\Exception $exception) {
// Fail silently to allow the next graphs to be added.
Copy link
Contributor

Choose a reason for hiding this comment

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

It looks like we're using exceptions here for flow control.

*
* @throws \Exception
* Thrown when the entity graph is empty.
*/
protected function processGraphResults($results) {
protected function processGraphResults($results, array $graph_ids): ?array {
Copy link
Contributor

Choose a reason for hiding this comment

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

Would be great if this could get some 'extract method' love...

@@ -0,0 +1,114 @@
<?php
Copy link
Contributor

Choose a reason for hiding this comment

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

❤️ ❤️ ❤️ ❤️ ❤️ ❤️

Copy link
Contributor Author

@claudiu-cristea claudiu-cristea left a comment

Choose a reason for hiding this comment

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

ops

Copy link
Contributor Author

@claudiu-cristea claudiu-cristea left a comment

Choose a reason for hiding this comment

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

aaa

$storage = \Drupal::entityTypeManager()->getStorage($entity->getEntityTypeId());
}
catch (\Exception $exception) {
return [];
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok. Let's unleash the daemons!

// RdfEntitySparqlStorage and move their 3rd party settings belonging to
// rdf_entity module into their dedicated rdf_entity_mapping config entities.
foreach ($entity_type_manager->getDefinitions() as $entity_type_id => $entity_type) {
if ($storage = $entity_type_manager->getStorage($entity_type_id)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

+1 for this. Also if ($storage = .... ->getStorage(...)) {...} doesn't make any sense because ::getStorage() doesn't return anything. It only throws an exception if fails the return the storage.

$graph_uri = $form_state->getValue('graph_' . $definedGraphName);
$third_party_settings[$definedGraphName] = $graph_uri;
catch (\Exception $exception) {
\Drupal::logger('rdf_entity')->critical(t('Could not save RDF entity mapping'), ['exception' => $exception]);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Never thought. But, yes, it makes sense. Let's simplify then.

}
}
catch (\Exception $exception) {
// Fail silently to allow the next graphs to be added.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's more to satisfy the IDE. Let's drop that too.

*
* @throws \Exception
* Thrown when the entity graph is empty.
*/
protected function processGraphResults($results) {
protected function processGraphResults($results, array $graph_ids): ?array {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't get it. Could you explain?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Discussed with @sandervd to move this change in #19 followup.

@idimopoulos
Copy link
Contributor

Merging :) Good job :)

@idimopoulos idimopoulos merged commit cf357d4 into 8.x-1.x Jan 23, 2018
@idimopoulos idimopoulos deleted the graph-refactor branch January 23, 2018 14:59
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants