qtranslate / qtranslate-xt

qTranslate-XT (eXTended) - reviving qTranslate-X multilingual plugin for WordPress. A new community-driven plugin soon. Built-in modules for WooCommerce, ACF, slugs and others.
GNU General Public License v2.0
545 stars 103 forks source link

Optional arguments are sometimes missing `?` in the type. #1393

Open hirasso opened 5 months ago

hirasso commented 5 months ago

Describe the bug

qtranxf_convertURL causes a fatal error if invoked with a $url of null

To Reproduce Steps to reproduce the behavior:

  1. Put this in your functions.php:
    qtranxf_convertURL(null, 'en');
  2. Reload the site

Expected behavior I'd expect no error

Proposed Fix In PHP >= 8, optional arguments need to be typed using ?string, ?bool and so forth. So we should change qtranxf_convertURL (and many other functions in qtranslate-xt) from this:

function qtranxf_convertURL( string $url = '', ?string $lang = '', ?bool $forceadmin = false, ?bool $showDefaultLanguage = false ): string {
  // ...

...to this:

function qtranxf_convertURL( ?string $url = '', ?string $lang = '', ?bool $forceadmin = false, ?bool $showDefaultLanguage = false ): ?string {
  // ...

ChatGPT can explain the issue much clearer:

The code you provided would be invalid because you are trying to assign null as the default value to an argument with a non-nullable type (string). If you want the $url to be able to accept null, you should use the ? character before the type.

Debug info Go to <YOUR_SITE>/wp-admin/options-general.php?page=qtranslate-xt#troubleshooting. Press Collect information button and copy/paste the output below.

{
  "PHP_VERSION": "8.2.0",
  "WP_VERSION": "6.4.2",
  "QTX_VERSION": "3.15.2",
  "Plugins": [
    "qTranslate-XT 3.15.2",
    "Yoast SEO 21.8"
  ]
}

Additional context

Here's the stack trace where I originally encountered the error. It seems to be related with Yoast SEO somehow.


Fatal error:  Uncaught TypeError: qtranxf_convertURL(): Argument #1 ($url) must be of type string, null given, called in /Users/rah/Sites/examplesite/wwwroot/content/plugins/qtranslate-xt/src/frontend.php on line 830 and defined in /Users/rah/Sites/examplesite/wwwroot/content/plugins/qtranslate-xt/src/url.php:15
--
  | Stack trace:
  | #0 /Users/rah/Sites/examplesite/wwwroot/content/plugins/qtranslate-xt/src/frontend.php(830): qtranxf_convertURL(NULL)
  | #1 /Users/rah/Sites/examplesite/wwwroot/core/wp-includes/class-wp-hook.php(324): qtranxf_checkCanonical(NULL, Object(Yoast\WP\SEO\Presentations\Indexable_Presentation))
  | #2 /Users/rah/Sites/examplesite/wwwroot/core/wp-includes/plugin.php(205): WP_Hook-&gt;apply_filters(NULL, Array)
  | #3 /Users/rah/Sites/examplesite/wwwroot/content/plugins/wordpress-seo/src/presenters/open-graph/url-presenter.php(47): apply_filters('wpseo_opengraph...', NULL, Object(Yoast\WP\SEO\Presentations\Indexable_Presentation))
  | #4 /Users/rah/Sites/examplesite/wwwroot/content/plugins/wordpress-seo/src/presenters/abstract-indexable-tag-presenter.php(37): Yoast\WP\SEO\Presenters\Open_Graph\Url_Presenter-&gt;get()
  | #5 /Users/rah/Sites/examplesite/wwwroot/content/plugins/wordpress-seo/src/integrations/front-end-integration.php(409): Yoast\WP\SEO\Presenters\Abstract_Indexable_Tag_Presenter-&gt;present()
  | #6 /Users/rah/Sites/examplesite/wwwroot/core/wp-includes/class-wp-hook.php(324): Yoast\WP\SEO\Integrations\Front_End_Integration-&gt;present_head('')
  | #7 /Users/rah/Sites/examplesite/wwwroot/core/wp-includes/class-wp-hook.php(348): WP_Hook-&gt;apply_filters('', Array)
  | #8 /Users/rah/Sites/examplesite/wwwroot/core/wp-includes/plugin.php(517): WP_Hook-&gt;do_action(Array)
  | #9 /Users/rah/Sites/examplesite/wwwroot/content/plugins/wordpress-seo/src/integrations/front-end-integration.php(383): do_action('wpseo_head')
  | #10 /Users/rah/Sites/examplesite/wwwroot/core/wp-includes/class-wp-hook.php(324): Yoast\WP\SEO\Integrations\Front_End_Integration-&gt;call_wpseo_head('')
  | #11 /Users/rah/Sites/examplesite/wwwroot/core/wp-includes/class-wp-hook.php(348): WP_Hook-&gt;apply_filters(NULL, Array)
  | #12 /Users/rah/Sites/examplesite/wwwroot/core/wp-includes/plugin.php(517): WP_Hook-&gt;do_action(Array)
  | #13 /Users/rah/Sites/examplesite/wwwroot/core/wp-includes/general-template.php(3052): do_action('wp_head')
  | #14 /Users/rah/Sites/examplesite/wwwroot/content/themes/imd/head.php(6): wp_head()
  | #15 /Users/rah/Sites/examplesite/wwwroot/core/wp-includes/template.php(792): require('/Users/rah/Site...')
  | #16 /Users/rah/Sites/examplesite/wwwroot/core/wp-includes/template.php(725): load_template('/Users/rah/Site...', false, Array)
  | #17 /Users/rah/Sites/examplesite/wwwroot/core/wp-includes/general-template.php(206): locate_template(Array, true, false, Array)
  | #18 /Users/rah/Sites/examplesite/wwwroot/content/themes/imd/base.php(20): get_template_part('head')
  | #19 /Users/rah/Sites/examplesite/wwwroot/core/wp-includes/template-loader.php(106): include('/Users/rah/Site...')
  | #20 /Users/rah/Sites/examplesite/wwwroot/core/wp-blog-header.php(19): require_once('/Users/rah/Site...')
  | #21 /Users/rah/Sites/examplesite/wwwroot/index.php(18): require('/Users/rah/Site...')
  | #22 {main}
  | thrown in /Users/rah/Sites/examplesite/wwwroot/content/plugins/qtranslate-xt/src/url.php on line 15