Similar to #3109722: Entity IDs can be strings in Drupal 8 and documented in #3163562: Convert the entity_legal_document_version entity ID from string to serial Link checker throws an exception when an entity has a string ID, which is rare but allowed in Drupal 8. See also #3057609: Add content moderation support for content entities with string IDs and #2555027: Support non-numeric entity ID's.

Steps to reproduce

1. Have a D9 project.
2. composer require drupal/linkchecker composer require 'drupal/entity_legal:3.0.x-dev@dev'
3. Apply Entity Legal patch from #3182420-5: non-existent service path.alias_storage.
4. Enable Link checker and Entity Legal.
4. Create a legal document version entity, get the following exception:

The website encountered an unexpected error. Please try again later.

Drupal\Core\Entity\EntityStorageException: SQLSTATE[22007]: Invalid datetime format: 1366 Incorrect integer value: 'foobar_1615306631' for column `db`.`linkchecker_index`.`entity_id` at row 1: INSERT INTO {linkchecker_index} ("entity_id", "entity_type", "last_extracted_time") VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2); Array ( [:db_insert_placeholder_0] => foobar_1615306631 [:db_insert_placeholder_1] => entity_legal_document_version [:db_insert_placeholder_2] => 1615306643 ) in Drupal\Core\Entity\Sql\SqlContentEntityStorage->save() (line 810 of core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php).
Drupal\Core\Database\StatementWrapper->execute(Array, Array) (Line: 823)
Drupal\Core\Database\Connection->query('INSERT INTO {linkchecker_index} ("entity_id", "entity_type", "last_extracted_time") VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2)', Array, Array) (Line: 97)
Drupal\Core\Database\Driver\mysql\Connection->query('INSERT INTO {linkchecker_index} ("entity_id", "entity_type", "last_extracted_time") VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2)', Array, Array) (Line: 32)
Drupal\Core\Database\Driver\mysql\Insert->execute() (Line: 390)
Drupal\linkchecker\LinkExtractorService->updateEntityExtractIndex(Object) (Line: 158)
linkchecker_entity_insert(Object)
call_user_func_array('linkchecker_entity_insert', Array) (Line: 403)
Drupal\Core\Extension\ModuleHandler->invokeAll('entity_insert', Array) (Line: 201)
Drupal\Core\Entity\EntityStorageBase->invokeHook('insert', Object) (Line: 800)
Drupal\Core\Entity\ContentEntityStorageBase->invokeHook('insert', Object) (Line: 530)
Drupal\Core\Entity\EntityStorageBase->doPostSave(Object, ) (Line: 685)
Drupal\Core\Entity\ContentEntityStorageBase->doPostSave(Object, ) (Line: 455)
Drupal\Core\Entity\EntityStorageBase->save(Object) (Line: 801)
Drupal\Core\Entity\Sql\SqlContentEntityStorage->save(Object) (Line: 339)
Drupal\Core\Entity\EntityBase->save() (Line: 116)
Drupal\entity_legal\Form\EntityLegalDocumentVersionForm->save(Array, Object)
call_user_func_array(Array, Array) (Line: 113)
Drupal\Core\Form\FormSubmitter->executeSubmitHandlers(Array, Object) (Line: 51)
Drupal\Core\Form\FormSubmitter->doSubmitForm(Array, Object) (Line: 593)
Drupal\Core\Form\FormBuilder->processForm('entity_legal_document_version_foobar_form', Array, Object) (Line: 321)
Drupal\Core\Form\FormBuilder->buildForm(Object, Object) (Line: 48)
Drupal\Core\Entity\EntityFormBuilder->getForm(Object) (Line: 129)
Drupal\entity_legal\Controller\EntityLegalController->documentVersionForm(Object, Object)
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 573)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 124)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 158)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 80)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 106)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 85)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 706)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
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:

Comments

leymannx created an issue. See original summary.

vistree’s picture

Same problem for me. Is there any way to exclude entityqueue from being processed by linkchecker as a "quick workaround"?

norman.lol’s picture

Workaround for now is you manually edit the entity ID to contain just the numeric string.

vistree’s picture

Hi leymannx,
you mean, I have to edit the entityqueue database tabe and make sure the id contains int value only?
Problem is, that you can't create new entityqueue entries as there is an error by linkchecker on entityqueue save. So nothing I can edit afterwards ;-(

vistree’s picture

Is there a way to exclude specific entities from linkchecker check? So, if I create an entityqueue item that linkchecker does not run?

codebymikey’s picture

#3184613: Wrong calculation of extraction status seems to inadvertently workaround this bug for things like webforms, so that might be a way to skip the processing of unsuspecting entities which might be unsupported by linkchecker.

The module still needs to support non-numeric IDs, but that issue's a start at the very least.

vistree’s picture

I tried patch from https://www.drupal.org/project/linkchecker/issues/3184613 - but error is still the same:

Drupal\Core\Database\DatabaseExceptionWrapper: SQLSTATE[22P02]: Invalid text representation: 7 ERROR: invalid input syntax for integer: "teaser" LINE 4: WHERE (entity_id = 'teaser') AND (entity_type = 'entity_subq... ^: SELECT i.* FROM {linkchecker_index} i WHERE (entity_id = :db_condition_placeholder_0) AND (entity_type = :db_condition_placeholder_1) LIMIT 1 OFFSET 0; Array ( [:db_condition_placeholder_0] => teaser [:db_condition_placeholder_1] => entity_subqueue ) in Drupal\linkchecker\LinkExtractorService->updateEntityExtractIndex() (Zeile 380 in /var/www/drupal/web/modules/contrib/linkchecker/src/LinkExtractorService.php).
Drupal\Core\Entity\EntityStorageException: SQLSTATE[22P02]: Invalid text representation: 7 ERROR: invalid input syntax for integer: "teaser" LINE 4: WHERE (entity_id = 'teaser') AND (entity_type = 'entity_subq... ^: SELECT i.* FROM {linkchecker_index} i WHERE (entity_id = :db_condition_placeholder_0) AND (entity_type = :db_condition_placeholder_1) LIMIT 1 OFFSET 0; Array ( [:db_condition_placeholder_0] => teaser [:db_condition_placeholder_1] => entity_subqueue ) in Drupal\Core\Entity\Sql\SqlContentEntityStorage->save() (Zeile 846 in /var/www/drupal/web/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php).

el7cosmos made their first commit to this issue’s fork.

el7cosmos’s picture

Status: Active » Needs review
eiriksm’s picture

This is great! 👌

Would love to see testing from the people who has experienced this. Plus, would be great to have a test for the update hook. Not a blocker, but nice to have 🤓

el7cosmos’s picture

@eiriksm update path test added.

Is it good enough? I don't have much experience with update path tests.

eiriksm’s picture

StatusFileSize
new71.03 KB

That looks good for sure. But very hard to say just by looking at gitlab :)

Let's try to run a test-only patch for it.

eiriksm’s picture

Also: If the people reporting this issue could test the patch for their sites, that would help greatly! 🙌️

Status: Needs review » Needs work

The last submitted patch, 13: 3203329.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

eiriksm’s picture

Ok so that test only patch did not really prove anything beyond the fact that there were no updates.

Can we add 2 assertions? First assert that inserting an entity with a non numeric Id fails before the update has run. Then try/catch the update so a test only patch fails. And then an assertion about inserting the same entity does not fail after the update

el7cosmos’s picture

Assigned: Unassigned » el7cosmos

I guess I can do that

eiriksm’s picture

Awesome! And fantastic work on this generally! 🙏🙏

Just noticed there is also a coding standard error in the new test. Great if you can fix that up as well 🤓

el7cosmos’s picture

StatusFileSize
new71.54 KB
el7cosmos’s picture

Assigned: el7cosmos » Unassigned
Status: Needs work » Needs review
eiriksm’s picture

Amazing, thanks!

If any of the people who experienced this on their site can verify that this patch fixes their problem that would also be helpful.

Otherwise this looks good to me. Thanks alot for the great work!

vistree’s picture

Is #13 we should test?

eiriksm’s picture

vistree’s picture

Thanx @eiriksm - I was able to apply the diff to my local Linkchecker installation. Since I already had Linkchecker installed, drush updb did an update of the database schema - which worked fine ;-).
But unfortunately I am still not able to add entries to the entityqueue when the patched linkchecker is activated:
Error 1:
Drupal\Core\Database\DatabaseExceptionWrapper: SQLSTATE[22P02]: Invalid text representation: 7 ERROR: invalid input syntax for integer: "startpage_slider_news_teaser" LINE 5: WHERE (linkchecker_link.entity_id__target_id = 'startpage_sl... ^: SELECT base_table.lid AS lid, base_table.lid AS base_table_lid FROM {linkchecker_link} base_table INNER JOIN {linkchecker_link} linkchecker_link ON linkchecker_link.lid = base_table.lid WHERE (linkchecker_link.entity_id__target_id = :db_condition_placeholder_0) AND (linkchecker_link.entity_id__target_type = :db_condition_placeholder_1); Array ( [:db_condition_placeholder_0] => startpage_slider_news_teaser [:db_condition_placeholder_1] => entity_subqueue ) in Drupal\linkchecker\LinkCleanUp->cleanUpForEntity() (line 149 of /var/www/html/web/modules/contrib/linkchecker/src/LinkCleanUp.php).
Error 2:
Drupal\Core\Entity\EntityStorageException: SQLSTATE[22P02]: Invalid text representation: 7 ERROR: invalid input syntax for integer: "startpage_slider_news_teaser" LINE 5: WHERE (linkchecker_link.entity_id__target_id = 'startpage_sl... ^: SELECT base_table.lid AS lid, base_table.lid AS base_table_lid FROM {linkchecker_link} base_table INNER JOIN {linkchecker_link} linkchecker_link ON linkchecker_link.lid = base_table.lid WHERE (linkchecker_link.entity_id__target_id = :db_condition_placeholder_0) AND (linkchecker_link.entity_id__target_type = :db_condition_placeholder_1); Array ( [:db_condition_placeholder_0] => startpage_slider_news_teaser [:db_condition_placeholder_1] => entity_subqueue ) in Drupal\Core\Entity\Sql\SqlContentEntityStorage->save() (line 846 of /var/www/html/web/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php).

Do I have to uninstall Linkchecker first and then reinstall it to be able to perform the test correctly?

el7cosmos’s picture

I think we also need to use dynamic entity reference 8.x-2.x, because 8.x-1.x also only support integer entity ID.

eiriksm’s picture

...which in turn will not be a requirement because of #3193254: using dynamic_entity_reference brings in triggers and uninstalling does not get rid of them

But these things sounds like we can add in the readme and project page?

Are you able to upgrade to 2.x on your project, @vistree, and test this there?

vistree’s picture

Sure, I can test! Do I need to clone a git repo? Seems that there is no release for 2.x??

jeroent’s picture

cgoffin made their first commit to this issue’s fork.

cgoffin’s picture

I altered the specs of the entity id field changed by the update hook. The update hook didn't work because the field would be changed as NULLABLE and this isn't possible for fields belonging to a primary key. Here also a patch to use.

c-logemann’s picture

Status: Needs review » Needs work

Even if I currently didn't see a reason to use link extraction on entityqueue entities on a customer system which I currently need to patch. But maybe I see a reason in future or there are other entity types with non numeric IDs I like to scan. So this should be fixed. But for this I don't see a solution based on dynamic entity reference (DER) 8.x-2.x as Erik already pointed out at #26. Or with other words: If someone wants to get this fixed on DER 8.x-2.x or 4.x should introduce a complete contribution to this module to maintain a second module version of linkchecker because I will not support this new branch. I will only support solutions where we can remove our dependency on DER.

Currently for me it's more important to get a configuration and/or hook_solution to switch entity types in linkchecker and opened an issue for that: #3272008: Provide a config to control which entity type to check

eiriksm’s picture

I think the way forward is to get rid of the DER dependency. It's a pretty small dependency for us, we only use it for its field type if i remember correctly.

If someone can update the issue summary with the work so far, that would also help. And add there that this issue needs to also remove the DER dependency.

cgoffin’s picture

Here an updated version of the patch to work with the latest version (fixed merge conflict).

aiphes’s picture

I try to patch the module with this patch but it's not working on boths Upgrading drupal/linkchecker (1.0.0-beta4 => 1.0.0-beta5)

/modules/contrib/linkchecker$ curl https://www.drupal.org/files/issues/2022-04-29/linkchec ker-support_entities_with_non_numeric_ids-3203329-33.patch | git apply
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  5108  100  5108    0     0  59395      0 --:--:-- --:--:-- --:--:-- 59395
error: corrupt patch at line 154

does it only works with the dev version ?

norman.lol’s picture

I see a space in the patch URL that probably caused that error.

aiphes’s picture

No issue with the URL or syntax. It's an issue into the file.

aiphes’s picture

So, what can I do to get it work with entityqueue ? Take the dev version or waiting for a beta6 ?

eiriksm’s picture

The dev version and the latest beta are identical. However, I have a feeling you don't need a patch to make it work with entity queue now, unless you are extracting links from the actual queue entity, which would be quite uncommon.

Did you try the latest beta to see if that fixes your issue? 🤓🤞

aiphes’s picture

I just enable the 8.x-1.0-beta5 and it seem to be good, I can create a queue as designed. :)

joel_osc’s picture

Status: Needs work » Needs review
StatusFileSize
new11.06 KB

Ran into the same issue when enabling workspaces, patch was not working as it was missing "use Drupal\Core\Database\Database;" in the .install file. Here is the patch re-rolled with the one additional line.

rp7 changed the visibility of the branch 3203329-support-entities-with to hidden.

rp7 changed the visibility of the branch 3203329-support-entities-with to active.

rp7’s picture

Merged 2.0.x into the branch.
Since I couldn't change the target branch to 2.0.x, I created a new merge request (https://git.drupalcode.org/project/linkchecker/-/merge_requests/113).

gugalamaciek made their first commit to this issue’s fork.