Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Project config values changing between strings and boolean values in different environments #3695

Closed
aaronbushnell opened this issue Jan 23, 2019 · 15 comments
Assignees

Comments

@aaronbushnell
Copy link
Contributor

aaronbushnell commented Jan 23, 2019

Description

I've updated a project to the latest version of Craft and enabled project config control. When I make changes locally I'm seeing values such as...

siteSettings:
  215a576d-d6b9-41cf-bff5-d7306aa1d646:
    hasUrls: '1'

But when I apply this config to our staging environment these are changed to

siteSettings:
  215a576d-d6b9-41cf-bff5-d7306aa1d646:
    hasUrls: true

Because this change occurs I'm unable to set "allowAdminChanges" => false as I receive an error saying changes to the project config are "read-only".

Additional info

  • Craft version: 3.1.3
  • PHP version: 7.2.14
  • Database driver & version: MySQL 5.7.24
  • Plugins & versions:
@brandonkelly
Copy link
Member

Can you look for the read-only error in your staging server’s storage/logs/ folder and post the stack trace?

@aaronbushnell
Copy link
Contributor Author

aaronbushnell commented Jan 23, 2019

Sure! So when I first apply the project config I get this error in staging:

screen shot 2019-01-23 at 11 12 02 am

Then I receive the "Changes to the project config are not possible while in read-only mode" error when I choose "Use project.yaml"

And here's the stack trace:

2019-01-23 11:12:43 [-][1][-][error][yii\base\NotSupportedException] yii\base\NotSupportedException: Changes to the project config are not possible while in read-only mode. in /ROOT/vendor/craftcms/cms/src/services/ProjectConfig.php:330
Stack trace:
#0 /ROOT/vendor/craftcms/cms/src/services/Matrix.php(285): craft\services\ProjectConfig->set('matrixBlockType...', Array)
#1 /ROOT/vendor/craftcms/cms/src/services/Matrix.php(601): craft\services\Matrix->saveBlockType(Object(craft\models\MatrixBlockType), false)
#2 /ROOT/vendor/craftcms/cms/src/fields/Matrix.php(715): craft\services\Matrix->saveSettings(Object(craft\fields\Matrix), false)
#3 /ROOT/vendor/craftcms/cms/src/services/Fields.php(1519): craft\fields\Matrix->afterSave(false)
#4 /ROOT/vendor/craftcms/cms/src/services/Fields.php(817): craft\services\Fields->applyFieldSave('e6640bd5-e054-4...', Array, 'global')
#5 /ROOT/vendor/craftcms/cms/src/services/ProjectConfig.php(815): craft\services\Fields->handleChangedField(Object(craft\events\ConfigEvent))
#6 [internal function]: craft\services\ProjectConfig->craft\services\{closure}(Object(craft\events\ConfigEvent))
#7 /ROOT/vendor/yiisoft/yii2/base/Component.php(627): call_user_func(Object(Closure), Object(craft\events\ConfigEvent))
#8 /ROOT/vendor/craftcms/cms/src/services/ProjectConfig.php(517): yii\base\Component->trigger('updateItem', Object(craft\events\ConfigEvent))
#9 /ROOT/vendor/craftcms/cms/src/helpers/ProjectConfig.php(63): craft\services\ProjectConfig->processConfigChanges('fields.e6640bd5...')
#10 /ROOT/vendor/craftcms/cms/src/services/Matrix.php(305): craft\helpers\ProjectConfig::ensureAllFieldsProcessed()
#11 /ROOT/vendor/craftcms/cms/src/services/ProjectConfig.php(815): craft\services\Matrix->handleChangedBlockType(Object(craft\events\ConfigEvent))
#12 [internal function]: craft\services\ProjectConfig->craft\services\{closure}(Object(craft\events\ConfigEvent))
#13 /ROOT/vendor/yiisoft/yii2/base/Component.php(627): call_user_func(Object(Closure), Object(craft\events\ConfigEvent))
#14 /ROOT/vendor/craftcms/cms/src/services/ProjectConfig.php(517): yii\base\Component->trigger('updateItem', Object(craft\events\ConfigEvent))
#15 /ROOT/vendor/craftcms/cms/src/services/ProjectConfig.php(846): craft\services\ProjectConfig->processConfigChanges('matrixBlockType...')
#16 /ROOT/vendor/craftcms/cms/src/services/ProjectConfig.php(402): craft\services\ProjectConfig->_applyChanges(Array)
#17 /ROOT/vendor/craftcms/cms/src/controllers/ConfigSyncController.php(57): craft\services\ProjectConfig->applyYamlChanges()
#18 [internal function]: craft\controllers\ConfigSyncController->actionApplyYamlChanges()
#19 /ROOT/vendor/yiisoft/yii2/base/InlineAction.php(57): call_user_func_array(Array, Array)
#20 /ROOT/vendor/yiisoft/yii2/base/Controller.php(157): yii\base\InlineAction->runWithParams(Array)
#21 /ROOT/vendor/craftcms/cms/src/web/Controller.php(109): yii\base\Controller->runAction('apply-yaml-chan...', Array)
#22 /ROOT/vendor/yiisoft/yii2/base/Module.php(528): craft\web\Controller->runAction('apply-yaml-chan...', Array)
#23 /ROOT/vendor/craftcms/cms/src/web/Application.php(297): yii\base\Module->runAction('config-sync/app...', Array)
#24 /ROOT/vendor/craftcms/cms/src/web/Application.php(722): craft\web\Application->runAction('config-sync/app...')
#25 /ROOT/vendor/craftcms/cms/src/web/Application.php(248): craft\web\Application->_processConfigSyncLogic(Object(craft\web\Request))
#26 /ROOT/vendor/yiisoft/yii2/base/Application.php(386): craft\web\Application->handleRequest(Object(craft\web\Request))
#27 /ROOT/public/index.php(23): yii\base\Application->run()
#28 {main}
2019-01-23 11:12:43 [-][1][-][info][application] $_GET = [
    'p' => 'admin/actions/config-sync/apply-yaml-changes'
]

@brandonkelly
Copy link
Member

brandonkelly commented Jan 23, 2019

Thanks! Just fixed this for the next release.

You can patch your local install by changing your craftcms/cms requirement in composer.json to:

"require": {
  "craftcms/cms": "dev-develop#6733f86f8a56f0dba61d84d2fa1124b3fad87aee as 3.1.3",
  "...": "..."
}

and then run composer update.

@aaronbushnell
Copy link
Contributor Author

You guys are so dang fast, thanks a ton!

@smcyr
Copy link

smcyr commented Jan 23, 2019

When migrating from Craft 3 to 3.1, the values in project,yaml were like that:

required: '0'
sortOrder: '2'

But if I save a section, field or anything in the control panel in local, the values change to that:

required: false
sortOrder: 2

Why is there this inconsistency? Also, is there a way to regenerate all the project.yaml to have the same format everywhere in the file (boolean and int instead of strings)?
Thanks!

@brandonkelly
Copy link
Member

It changes based on where the data is coming from. In the initial config generation it’s coming from the database, and if you’re using MySQL, then “boolean” values will be represented as '1' or '0' (as MySQL doesn’t have a boolean column type), and other numeric values will also come back as strings, despite having numeric column types.

If the data is coming from a POST request, then we tend to typecast the post data to actual booleans/numbers.

We have considered normalizing DB data when querying it, but it would be a ton of effort and/or it would slow everything down, depending on how we implemented it. (Active Record classes do a decent job of auto-typecasting for example, but it does so by running additional queries to the DB to learn about the schema, and storing all that data, so it comes at a performance cost.)

It’s only an issue for MySQL, whereas PostgreSQL always has the correct types, both because it does support a boolean column type, and because the PostgreSQL PDO implementation auto-typecasts the values as they’re sent to PHP, based on the column type.

And there’s good news on the horizon for MySQL installs: PHP 7.4 is going to have typed property support, which means that we will be able to normalize the values right at the property level, e.g.

public bool $required;
public int $sortOrder;

Which means the values will be typecasted correctly right as they are assigned to objects, regardless of what the PDO layer gave us.

@smcyr
Copy link

smcyr commented Jan 23, 2019

Ok, thanks a lot for the explanation!
From this and other comments you made on Github, it seems that PostgreSQL would be a good choice for new projects. I'm also excited for typed property support in PHP 7.4!

@andris-sevcenko
Copy link
Contributor

andris-sevcenko commented Jan 24, 2019

@aaronbushnell head ups - I just edited @brandonkelly's comment above with the composer.json snippet to use Craft version "3.1.3" instead to "3.0.3", just FYI in case you already used the snippet.

@aaronbushnell
Copy link
Contributor Author

Ah, thanks @andris-sevcenko!

@brandonkelly
Copy link
Member

Just merged in #4167 which properly typecasts all core integer and boolean values as they’re saved to the project config. Up to plugin developers to follow suit, but this should take care of most of the awkwardness.

@smcyr
Copy link

smcyr commented Apr 23, 2019

@brandonkelly Thanks for the update, but it seems that some values are still string instead of boolean or integer. For example, after running php craft project-config/rebuild, for the settings for my fields (Assets, Redactor, PlainText, etc.), I have useSingleFolder: '1' or initialRows: '4'. Also, my plugins have enabled: '1'.

@brandonkelly
Copy link
Member

Yeah good point, this change won’t affect custom field settings, plugin settings, etc.

@andris-sevcenko andris-sevcenko self-assigned this Apr 24, 2019
andris-sevcenko added a commit that referenced this issue Apr 24, 2019
andris-sevcenko added a commit to craftcms/redactor that referenced this issue Apr 24, 2019
andris-sevcenko added a commit that referenced this issue Apr 24, 2019
This reverts commit c7d56db.
@andris-sevcenko
Copy link
Contributor

Turns out the added complexity is not really worth it. The settings are stored as a json string, so it wouldn't suddenly change from 0 to false between environments or usage scenarios.

andris-sevcenko added a commit to craftcms/redactor that referenced this issue Apr 24, 2019
@smcyr
Copy link

smcyr commented Apr 24, 2019

I did a project-config/rebuild and the sections still had:

enableVersioning: '1'
propagateEntries: '1'

So maybe the rebuild didn't do the sections or these values are not always typecasted.

andris-sevcenko added a commit that referenced this issue Apr 24, 2019
@andris-sevcenko
Copy link
Contributor

@smcyr Doh. Should be all better with the next release

angrybrad pushed a commit that referenced this issue May 6, 2019
angrybrad pushed a commit that referenced this issue May 6, 2019
This reverts commit c7d56db.
angrybrad pushed a commit that referenced this issue May 6, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants