Hello, I am writing this to describe a possible bug that I found and to have some help to hit the right spot in the changes to solve this possible bug. I am using ojs version 3.3.0.13.
When I try to access the context /search/authors page in a journal I get a 500 internal server error and the log shows the following stack trace:
PHP Fatal error: Uncaught InvalidArgumentException: Passed value cannot be an array in /var/www/html/ojs/lib/pkp/lib/vendor/danielstjules/stringy/src/Stringy.php:45\nStack trace:\n#0 /var/www/html/ojs/lib/pkp/lib/vendor/danielstjules/stringy/src/Stringy.php(73): Stringy\\Stringy->__construct(Array, NULL)\n#1 /var/www/html/ojs/lib/pkp/classes/core/PKPString.inc.php(164): Stringy\\Stringy::create(Array)\n#2 /var/www/html/ojs/cache/t_compile/34a9c59b4a19f42bae23f8270f7d53d621182573^c2055d14f27582f3361894f4184ce1a4c0497385_0.app.frontendpagessearchAuthor.php(58): PKPString::substr(Array, 0, 1)\n#3 /var/www/html/ojs/lib/pkp/lib/vendor/smarty/smarty/libs/sysplugins/smarty_template_resource_base.php(123): content_641352170cbf36_90450511(Object(Smarty_Internal_Template))\n#4 /var/www/html/ojs/lib/pkp/lib/vendor/smarty/smarty/libs/sysplugins/smarty_template_compiled.php(114): Smarty_Template_Resource_Base->getRenderedTemplateCode(Object(Smarty_Internal_Template))\n#5 /var/www/html/ojs/lib/pkp/lib/vendor/smarty/smarty/libs/sysplugins/smarty_int in /var/www/html/ojs/lib/pkp/lib/vendor/danielstjules/stringy/src/Stringy.php on line 45, referer: https://my-website/ojs/index.php/my-journal
After some digging I found that values in the table author_settings in the ‘familyName’ attribute, where the column setting_value has a value not trimmed (for example ’ Baptista ', 'Baptista ’ or ‘ Baptista ‘) it results in the 500 error.
for debug purpose I add a line in the ojs/lib/pkp/classes/core/PKPString.inc.php to identify the value that is generating the error:
static function substr($string, $start, $length = null) {
error_log(print_r($string, true));
return (string) Stringy\Stringy::create($string)->substr($start, $length);
}
the result of the debug:
Array\n(\n [en_US] => Almeida\n)\n,
other value:
Array\n(\n [en_US] => Chebenova \n [es_ES] => \n [pt_BR] => \n)\n
In this example the author has familyName empty for the locales pt_BR and es_ES, but if I delete the familyName of these locales I am still facing the error because the familyName in the locale en_US looks like ‘ Chebenova’. If I remove the the space before the familyName the error stops (for this author of course :P)
So, I think that if the value has backspaces before or after the value, the value is treated like an array and the function does not accept arrays to create substring.
If I add a trim in the return of the function substr like:
return (string) Stringy\Stringy::create(trim($string))->substr($start, $length);
in the file ojs/lib/pkp/classes/core/PKPString.inc.php the page start working again, but this function is globally used in ojs and I think this may not be a good idea to trim in this function
Other problem is when the familyName is not trimmed and has space before the name, it takes the name with backspace for the top of the alphabetical list.
Another problem is, when the value in the table author_settings is not trimmed (not only in the familyName attribute) the url to view details about the author is not formed right, the search is not successful and fallback to advanced search.
Other two ways that I found to trim this strings and I think is a better way to do this is:
in the file ojs/lib/pkp/classes/submission/PKPAuthor.inc.php line 74 in the function getLocalizedFamilyName trim the return of the function:
from:
return $this->getFamilyName($this->getSubmissionLocale());
to:
return trim($this->getFamilyName($this->getSubmissionLocale()));
or directly in the smarty file ojs/templates/frontend/pages/searchAuthorIndex.tpl in the assing of the var firstLetter line 21
from:
{assign var=firstLetter value=$author->getLocalizedFamilyName()|String_substr:0:1}
to:
{assign var=firstLetter value=$author->getLocalizedFamilyName()|trim|String_substr:0:1}
Is possible to trim the input before it be insert in the database ?
Regards