1

I maintain a plugin. Inside this plugin's composer.json, extra>handle is set to pizza (not the real name).

In one of the controllers, the following code is executed:

$apiKey = Plugin::$plugin->getSettings()->apiKey;

Prior to upgrading to Craft 4 (specifically, 4.3.1), this worked fine on Craft 3. Now, on Craft 4: Typed property pizza\models\Settings::$apiKey must not be accessed before initialization.

I have read through this article and as far as I know we follow everything.

There exists a model:

<?php

namespace pizza\models;

use Craft;
use craft\base\Model;

class Settings extends Model
{
    public string $apiKey;
}

Which is provided by the plugin class:

    protected function createSettingsModel(): ?Model
    {
        return new Settings();
    }

Furthermore, there exists a file config/pizza.php with the following:

<?php

use craft\helpers\App;

return [
    'apiKey' => App::env('PIZZA_API_KEY'),
];

On the admin page example.com/admin/utilities/php-info it shows that $_ENV['PIZZA_API_KEY'] is set to a value, it is not null or empty.

I'm lost as to why this property is not initialized. The same plugin, same version does not throw this error on another site that is Craft 4 (albeit 4.2.3, so perhaps there has been a change that breaks this?).

1 Answer 1

3

This:

class Settings extends Model
{
    public string $apiKey;
}

Should look like this:

class Settings extends Model
{
    public string $apiKey = '';
}

What's happening is due to the way Yii2 models work, they interrogate a class for its properties in such a way that it accesses their values before the rest of your code even runs.

So you need to initialize any typed values with some kind of default value, as per the above.

You can also declare them as nullable, but you still have to explicitly initialize there, too. e.g.:

class Settings extends Model
{
    public ?string $apiKey = null;
}

It's due to Craft CMS using types (made available more fully in PHP 8) in their base classes, and method & property signatures must match in child classes. This is a positive thing overall, but yes, requires some work to convert things over.

We did a few videos on this on CraftQuest.io:

3
  • This indeed resolved it, thank you. However, I'm curious why this broke when upgrading to Craft 4. Is it because of something Craft 4 changed, or implicitly due to PHP8 being required? Nov 17, 2022 at 17:53
  • It's due to Craft CMS using types (made available more fully in PHP 8) in their base classes, and method & property signatures must match in child classes. This is a positive thing overall, but yes, requires some work to convert things over. Nov 18, 2022 at 20:09
  • I updated the original answer with links to videos showing how to update plugins from Craft 3 to Craft 4. Nov 18, 2022 at 20:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.