If you attempt to create a custom block with the same name (machine name) as another existing block, an error occurs. If you're using the overlay to create the block, the page has almost no information, but with the overlay turned off you get the following error:

Error message
Drupal\Core\Entity\EntityStorageException: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'Test Block 1' for key 'info': INSERT INTO {custom_block} (id, uuid, info, revision_id, type, langcode) VALUES (default, :db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4); Array ( [:db_insert_placeholder_0] => 055d4dde-8b0b-4b47-a900-ec61bd1c32a8 [:db_insert_placeholder_1] => Test Block 1 [:db_insert_placeholder_2] => [:db_insert_placeholder_3] => basic [:db_insert_placeholder_4] => und ) in Drupal\Core\Entity\DatabaseStorageControllerNG->save() (line 339 of /home/trevor/drupal/core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php).
The website has encountered an error. Please try again later. 

Presumably you'd want to check that a block existed before attempting to insert it.

Update by benjy
Steps to Reproduce

  1. Install D8
  2. Visit examples.com/block/add/basic
  3. Add a block called "test"
  4. Repeat steps 2 and 3, using the same name for the block

Comments

larowlan’s picture

Assigned: Unassigned » larowlan

Adding to my list, feel free to reassign

benjy’s picture

Status: Active » Closed (cannot reproduce)

This seems to be fixed in HEAD. Please re-open if you think it's still an issue.

larowlan’s picture

Priority: Normal » Major
Status: Closed (cannot reproduce) » Active

berdir reported seeing this again.
will tackle this afternoon time permitting

larowlan’s picture

Assigned: larowlan » Unassigned
Status: Active » Needs review
StatusFileSize
new2.04 KB
new1.06 KB

Should be red/green

larowlan’s picture

Follow up to remove procedural wrappers is here #2060865: Modernize custom_block.module forms

Status: Needs review » Needs work

The last submitted patch, custom-block-info-validate-1998658.pass_.patch, failed testing.

larowlan’s picture

Status: Needs work » Needs review
StatusFileSize
new2.19 KB
new1.29 KB

Doh! Of course you only validate the value if its a new block.
Also removed call to entity_load_multiple_by_properties in favour of EntityStorageControllerInterace::loadByProperties().

jibran’s picture

Status: Needs review » Reviewed & tested by the community

It is green. It is major. It has tests. RTBC.

webchick’s picture

Status: Reviewed & tested by the community » Needs review
+      $exists = \Drupal::entityManager()->getStorageController('custom_block')->loadByProperties(array('info' => $form_state['values']['info']));

Ouch. :( I actually find:

+    $exists = entity_load_multiple_by_properties('custom_block', array('info' => $form_state['values']['info']));

...much more readable. Is there a reason not to do it that way?

benjy’s picture

We shouldn't be using any of them really. It would be better if we injected $entityManager so we had:

$this->entityManager->getStorageController('custom_block')->loadByProperties(array('info' => $form_state['values']['info']));

I noticed we do have another issue here to clean up the procedural code. #2060865: Modernize custom_block.module forms so either way, it's going to change when that lands.

In general we don't want to use global function calls in classes at all if we can help it.

webchick’s picture

Status: Needs review » Fixed

Yeeeeeahhhhh, that is not an improvement. :)

In the interest of making progress here, I've opened #2061887: It requires 4 levels of nested methods to figure out if a content entity exists as a follow-up issue, since the current situation is not this patch's fault.

At any rate, thanks for the bug fix and the test!

Committed and pushed to 8.x. Thanks!

larowlan’s picture

Status: Fixed » Needs review

Another reason

$this->storageController->loadByProperties()

is better is in the long run it lets us write UnitTests, eg see the test added here #1951268-93: Convert /forum and /forum/% to new router, remove forum_forum_load(), forum_get_topics(), create Forum service we would need a full-webtest and a use case for that code path if we used (for example) entity_load_multiple_by_properties() because we need a fully bootstrapped Drupal to access that function. This would take up to 2min locally to test (thats about the min for a Simpletest WebTestCase on my local). A phpunit test is done in < 15sec.
It takes getting used to, but the end result is cleaner in my opinion.
FWIW I'm not a trained CS student. I have no computing training, purely self taught from trial and error.
I started with mysql_connect (non Drupal), learnt Drupal and graduated to db_query(), then db_select() and PDO. The next step in my progression is $this->database->select(). So basically I'm getting a free CS education from the Drupal community ;).

webchick’s picture

Status: Needs review » Fixed

Think that was a cross-post.

The reasons against procedural functions in classes make sense. I want to be clear that I'm fine with OO code. I'm not fine with so many levels of abstraction as to render a given line of code meaningless without the reader having an in-depth understanding of the entire stack of technology underpinning that led to it. But that's an argument for #2061887: It requires 4 levels of nested methods to figure out if a content entity exists. ;)

larowlan’s picture

Thanks

Status: Fixed » Closed (fixed)

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

Anonymous’s picture

Issue summary: View changes

Updated issue summary.