Problem/Motivation

Deprecated function: strpos(): Passing null to parameter #1 ($haystack) of type string is deprecated in Drupal\search_api\Utility\Utility::splitPropertyPath() (line 142 of modules/contrib/search_api/src/Utility/Utility.php).

Steps to reproduce

Use PHP8.1 with the latest search_api

Proposed resolution

Patch supplied by Michele Bertani on issue 3253738: https://www.drupal.org/files/issues/2022-08-17/searchapi-php81.patch
https://www.drupal.org/project/search_api/issues/3253738#comment-14655392

Remaining tasks

Incorporate patch into release

Issue fork search_api-3308184

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

indefinitedevil created an issue. See original summary.

indefinitedevil’s picture

StatusFileSize
new531 bytes

On further inspection of the issue, I can see the issue continues with the following substr functions. As such, I have amended the patch to account for those issues.

phannphong’s picture

The patch file seems ok with me. Thanks indefinitedevil

szato’s picture

Version: 8.x-1.25 » 8.x-1.x-dev
Status: Active » Reviewed & tested by the community

Thank you, patch solved the issue.

drunken monkey’s picture

Thanks a lot for posting this issue and patch!
However, the docs for \Drupal\search_api\Utility\Utility::splitPropertyPath() already specify that $property_path has to be a string, even though we apparently didn’t have scalar type hints available at the time to write this directly into the method signature.
It would therefore be interesting to know what code calls this method with $property_path = NULL, so we might instead just fix that code. Would you be able to get the backtrace for these calls?

drunken monkey’s picture

Is anyone running into this able to provide a backtrace?

kleiton_rodrigues’s picture

The patch #2 looks good!
+1 RTBC

drunken monkey’s picture

As said, please provide a backtrace so we can get to the real root cause here. Just masking the problem is usually not the wisest approach.

drunken monkey’s picture

Status: Reviewed & tested by the community » Postponed (maintainer needs more info)
admirlju’s picture

Status: Postponed (maintainer needs more info) » Needs work

@drunken monkey hope this helps. What I've noticed anytime the cache is cleared this error pops up.

Deprecated function: strpos(): Passing null to parameter #1 ($haystack) of type string is deprecated in Drupal\search_api\Utility\Utility::splitPropertyPath() (line 142 of modules/contrib/search_api/src/Utility/Utility.php).

Drupal\search_api\Utility\Utility::splitPropertyPath(NULL, ) (Line: 355)
Drupal\search_api\Utility\FieldsHelper->retrieveNestedProperty(Array, NULL) (Line: 478)
Drupal\search_api\Item\Field->getDataDefinition() (Line: 201)
_search_api_views_get_handlers(Object) (Line: 61)
search_api_views_data() (Line: 236)
Drupal\views\ViewsData->Drupal\views\{closure}(Object, 'search_api') (Line: 405)
Drupal\Core\Extension\ModuleHandler->invokeAllWith('views_data', Object) (Line: 244)
Drupal\views\ViewsData->getData() (Line: 154)
Drupal\views\ViewsData->get('search_api_index_dev_content_index') (Line: 85)
Drupal\views\Plugin\ViewsHandlerManager->getHandler(Array, NULL) (Line: 888)
Drupal\views\Plugin\views\display\DisplayPluginBase->getHandlers('field') (Line: 1045)
Drupal\views\ViewExecutable->_initHandler('field', Array) (Line: 903)
Drupal\views\ViewExecutable->initHandlers() (Line: 2318)
Drupal\views\Plugin\views\display\DisplayPluginBase->preExecute() (Line: 1697)
Drupal\views\ViewExecutable->preExecute(Array) (Line: 1632)
Drupal\views\ViewExecutable->executeDisplay('page_1', Array) (Line: 81)
Drupal\views\Element\View::preRenderViewElement(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 243)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
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: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 718)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
admirlju’s picture

So looking a bit into it, right after the php error search API I also get:

Drupal\search_api\SearchApiException while adding Views handlers for field on index Content index dev: Could not retrieve data definition for field '' on index 'Content index dev'. in Drupal\search_api\Item\Field->getDataDefinition() (line 482 of /var/www/html/web/modules/contrib/search_api/src/Item/Field.php).

Now the weird part is I have no clue where I'm getting a field with an empty string label.

admirlju’s picture

Okay, so even more digging it looks like this happens with 3 special fields search_api_id, search_api_language, and search_api_datasource and it could potentially happen because of the backend I'm using Search API Meilisearch. But I'm not sure what the original issue was using, so hard to tell if it's down to the backend.

Edit: To clarify these 3 fields are automatically being indexed by that backend. Drupal\search_api\Item\Field->getDataDefinition() gets called only every field after clearing the cache. This is when the mentioned special fields show up here. Looking at Drupal\search_api\Backend::getSpecialFields() this is when they are created and in the $field_info only type and original type are provided. I assume this is normal since these fields are not mapped to anything.

sarwan_verma’s picture

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

Hello @indefinitedevil,
I have fixed this issue PHP 8.1 Deprecated Function , some other issues resolve and also created patch,
please review and verify.

Status: Needs review » Needs work

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

admirlju’s picture

@sarwan_verma So for some reason the tests are failing, but that said the specific fix meant for this issue is the same as the original patch file, and that does work. But the maintainer wants to fix this problem at the root cause, method docs requires that parameter to already be a string and not NULL.

admirlju’s picture

StatusFileSize
new665 bytes

So the NULL check is not a good solution, if you just do that you'll still get this in the dblog:
Drupal\search_api\SearchApiException while adding Views handlers for field on index Content index dev: Could not retrieve data definition for field '' on index 'Content index dev'. in Drupal\search_api\Item\Field->getDataDefinition() (line 482 of /var/www/html/web/modules/contrib/search_api/src/Item/Field.php).

While it fixes the depreciation error, you are still getting a SearchApiException that is correctly handled and logged.

Here I've made a small change in the search_api.views.inc file at least for my case it fixes it, could someone please test the patch file? Thanks.

admirlju’s picture

StatusFileSize
new673 bytes
admirlju’s picture

Status: Needs work » Needs review
drunken monkey’s picture

StatusFileSize
new2.27 KB

Thanks for the backtrace and the additional information!
The problem indeed seems to come from the Meilisearch backend. I don’t think it’s smart to include those special fields there, since it might confuse users.
That being said, it seems search_api_views_data() already guards against fields with no property path, and _search_api_views_get_handlers() just fails to do the same. So I think this is still also a bug in this module.

The attached patch should fix it, please test/review! It also adds a check in \Drupal\search_api\Item\Field::getDataDefinition() to avoid calling retrieveNestedProperty() with a NULL property path, which should help debug if this problem ever arises again.

Note: The patch requires PHP 8.0, but that should really be required at this point. (It apparently even is for Drupal 9, without me noticing it.)

admirlju’s picture

Status: Needs review » Reviewed & tested by the community

The provided patch fixes the deprecation issue, so this can probably be merged. So now with the meilisearch, this error pops up since the special fields are indexed there, so I guess the added debugging code also works:

Drupal\search_api\SearchApiException while adding Views handlers for field on index Content index: Field 'search_api_language' on index 'Content index' has no property path set. in Drupal\search_api\Item\Field->getDataDefinition() (line 479 of /var/www/html/web/modules/custom/search_api/src/Item/Field.php).

I will be opening an issue on the Search API Meilisearch module about this, but I'm not sure if is it ok to index these fields or not. If it's ok what would be the correct approach? (Fixed it there)

That said I'm setting this issue as RTBC.

  • drunken monkey committed 47ccf060 on 8.x-1.x
    Issue #3308184 by drunken monkey, admirlju: Fixed handling of incomplete...
drunken monkey’s picture

Status: Reviewed & tested by the community » Fixed

Good to hear, thanks for testing!
Merged. Thanks again!

Status: Fixed » Closed (fixed)

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