protected function loadMessagesFromDb($category, $language)
    {
        $fallbackLanguage = substr($language, 0, 2);
        $fallbackSourceLanguage = substr($this->sourceLanguage, 0, 2);

        $languages = [
            $language,
            $fallbackLanguage,
            $fallbackSourceLanguage
        ];

        $rows = (new Query())
            ->select(['language', 'messages'])
            ->from($this->collection)
            ->andWhere(['category' => $category])
            ->andWhere(['language' => array_unique($languages)])
            ->all($this->db);

        if (count($rows) > 1) {
            $languagePriorities = [
                $language => 1
            ];
            $languagePriorities[$fallbackLanguage] = 2; // language key may be already taken
            $languagePriorities[$fallbackSourceLanguage] = 3; // language key may be already taken

            usort($rows, function ($a, $b) use ($languagePriorities) {
                $languageA = $a['language'];
                $languageB = $b['language'];

                if ($languageA === $languageB) {
                    return 0;
                }
                if ($languagePriorities[$languageA] < $languagePriorities[$languageB]) {
                    return +1;
                }
                return -1;
            });
        }

        $messages = [];
        foreach ($rows as $row) {
            foreach ($row['messages'] as $key => $value) {
                // @todo drop message as key specification at 2.2
                if (is_array($value)) {
                    $messages[$value['message']] = $value['translation'];
                } else {
                    $messages[$key] = $value;
                }
            }
        }

        return $messages;
    }