1

the plugin I'm currently working on has to store user inputs which might contain 4 byte unicode characters like emojis. MySQL is not able to handle this with a utf-8 charset. It works if the charset of my tables is set to utf8mb4 and if I add 'charset' => 'utf8mb4' to config/db.php. Since the file config/db.php does not belong to my plugin, but to the installation of Craft itself, I'd like to not modify it.

Alternatively, I can convert the inputs with StringHelper::encodeMb4() but then I would have to do that at every place where something from the outside enters my tables.

Is there any pragmatic way of handling this?

Greetings Jus

2
  • Would it be an option to use your records beforeSave event to convert the string automatically when you do $record->save()? Jun 28 '18 at 8:05
  • Yes, that solves the issue. Thanks @RobinSchambach
    – Justus M.
    Jun 28 '18 at 8:14
1

Crafts ActiveRecord has a function beforeSave

/**
 * @inheritdoc
 */
public function beforeSave($insert)
{
    foreach ($this->fields() as $attribute) {
        $this->$attribute = Db::prepareValueForDb($this->$attribute);
    }

    // Prepare the values
    $now = Db::prepareDateForDb(new \DateTime());

    if ($this->getIsNewRecord()) {
        if ($this->hasAttribute('dateCreated')) {
            $this->dateCreated = $now;
        }

        if ($this->hasAttribute('uid')) {
            $this->uid = StringHelper::UUID();
        }
    }

    if ($this->hasAttribute('dateUpdated')) {
        $this->dateUpdated = $now;
    }

    return parent::beforeSave($insert);
}

You can overwrite this method and include your StringHelper::encodeMb4() into it so every time $record->save() is executed your string will be converted

1
  • Just make sure you convert them back before displaying them, via: html_entity_decode($value, ENT_NOQUOTES, 'UTF-8'); Jun 28 '18 at 15:25

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.