bolt / core

🧿 Bolt 5 core
https://boltcms.io
MIT License
542 stars 159 forks source link

Type mismatch error when trying to create a new page if none exists already #1734

Open antiftw opened 4 years ago

antiftw commented 4 years ago

Summary:

I just rolled out Bolt to a test domain to play around with it, and I wanted to do it without using the data from the fixtures, because I wanted to see what was needed to get it to run without using that.

I think it is related to the fact there a no existing pages because when I tried it after I ran the fixtures command I had no problems adding a new page.

When trying to add a new page I got a type mismatch error:

Argument 1 passed to Bolt\Twig\ContentExtension::getListTemplates() must be an instance of Bolt\Entity\Field\TemplateselectField, instance of Bolt\Entity\Field given, called in /var/www/bolt/var/cache/prod/twig/b9/b9a603f495ebe0805699952bde34c146cbbcb1453ce1171812c6a0be4681e59e.php on line 45

Specifics

The url:

https://hostname.com/bolt/new/pages

The version (output fron bin/console bolt:info):

Bolt version: 4.0.0 RC 33

Tried it in:

Firefox and Chromium

Steps to reproduce:

1) go to /bolt and login to the backend 2) hover over pages in the left menu 3) click on new page in the menu that appears

Expected result:

I expected to get the webpage to create a new "page".

Actual result:

I got the error as mentioned above and as can be seen in the screenshot:

screenshot_bolt_newpage

I hope my description was clear enough, since it was my first time reporting a bug for anything on Github. If more details are required, please do not hesitate to ask. I also tried finding a similar issue in the list but could not find it skimming the titles.

Kind regards, AntiFTW

bobdenotter commented 4 years ago

Hi @antiftw.

I've moved the issue to the correct repo. I'll see if I can reproduce and fix the issue!

antiftw commented 4 years ago

Hi @bobdenotter,

Okay, I tried looking for the function call but I am quite inexperienced with Bolt still, and with contributing to Github in general, I figure it probably is an issue related to the migration from 3 -> 4, since similar functionality like adding blocks or creating new entries does work like expected.

Hope you can reproduce it.

bobdenotter commented 4 years ago

Hmm, i've not been able yet to reproduce this.. I assume what you did is this, right?

composer create-project bolt/project myprojectname
cd myprojectname

(then configure .env to put in your MySQL db credentials)

and then:

bin/console bolt:setup

And in the last step, you said no to adding the fixtures..

If I do this, it get an empty bolt backend as expected

Schermafbeelding 2020-08-19 om 14 16 52

But no error when trying to create a new page:

Schermafbeelding 2020-08-19 om 14 17 02

Any idea what I might do different than you did?

antiftw commented 4 years ago

Hi @bobdenotter

Almost, I think I did not do the setup but manually created the database and schema, with the doctrine commands, and created an admin user myself, because I thought that the setup also inserted the doctrine fixtures.

edit: Im almost sure I read somewhere to do this, let me try and find it.

Found it:

https://docs.bolt.cm/4.0/configuration/database

bin/console doctrine:database:create bin/console doctrine:schema:create bin/console bolt:add-user --admin bin/console doctrine:fixtures:load

So I did that and skipped the last step (obviously).

antiftw commented 4 years ago

Hi @bobdenotter,

I wanted to let you know that I tried a clean install, doing it using setup and skipping the last step like you said, and now I am able to create a new page as expected.

After looking into the SetupCommand, to try and find out what could've resulted in the error before, I am confused why this might have happened, because it doesn't really do much more than the three steps. In fact, when you skip the fixtures step the only thing it does extra is generate a new secret, so that's not relevant to the error that occurred.

bobdenotter commented 4 years ago

Hi,

I am confused why this might have happened, because it doesn't really do much more than the three steps.

Correct, it's pretty much the same, but it allows people who want this to have more control over what they're doing. The results should be the same, though.

Too bad you also couldn't replicate it, though.. I'll leave the issue open for the time being, and if other people bump into this as well, we can always dig deeper.

antiftw commented 4 years ago

@bobdenotter

That's not exactly what I meant, rather, I wanted to at least get it to work from a clean install (and using the bolt:setup instead of the separate steps), to get a baseline (maybe my PHP installation was bugged, cache, etc. who knows).

So knowing this, I just tried repeating the steps I did before, so using yet another clean install, using the separate steps to create the database + tables and the user, and now I still did not get an error. (so that's good news I guess, but strange I am not able to reproduce my first attempt)

But because the time I got the error was the first time trying to roll out the CMS on a live environment, I do remember having some permission problems (with the database as well as file permissions) which halted the bolt:setup, so I had to manually delete the tables (or else the setup will fail when retrying) and retry with proper permissions.

I did not mention this at first, because it didn't seem relevant, but it seems more and more likely something went wrong there, since we are both not able to reproduce it with a completely clean install.

I did however, dive a bit deeper in the code and think I found where the error must have occurred. Sadly, the why still remains a mystery to me.

But I agree indeed that it's smarter to let this one be for now unless anyone else runs into it.

For future reference, the relevant files (according to my guess):

antiftw commented 4 years ago

@bobdenotter,

My apologies for the relatively long story, there is a TLDR :)

Something strange is going on. Short version is I think that there is something going on with caching/permissions.

In the progress of testing this all, I now have 2 folders, both with a bolt install (both also using a different database):

After my previous post I decided to switch back to the first folder, because I had already created some pages in that setup. When going to the new pages page I instantly got the same error again. (!) Even though I already had created two pages, so it is not related to the fact that there are no available pages.

Switching back to bolt2 again (just to be sure) instantly solved the error. Switching databases did not influence the error.

To try and confirm where the problem was I tried removing the "template" option from the ContentTypes configuration of the Pages type, this did also work as a test, since the error disappeared, but of course also did the templates-dropdown.

After changing it back by uncommenting the template option again, I noticed that the first time it also loaded without error, but after pressing F5 again it produced the error again.

To confirm this idea I also tried it with bin/console cache:clear, which resulted in one successful page-load and then the error is back again.

So what I'm thinking it has something to do with permissions, since the code is the same, the database doesn't influence it and the only thing that really seems to influence it is the cache, because now the version with the bolt:setup seems broken, and the one with the separate steps does work correctly.

After taking a closer look I notice that the bolt2/ has a setup where both cache and log directories in var/ are writable for everyone (777) and in bolt/ just by my user and the webserver group (775).

I'm not sure how the 777 permissions were set to be honest, because I always try to avoid this, and for that reason used the permission commands as advised in the bolt documentation (https://docs.bolt.cm/4.0/installation/permissions):

for dir in config/ public/files/ public/theme/ public/thumbs/ var/ ; do
    find $dir -type d -print0 | xargs -0 chmod u+rwx,g+rwxs,o+rx-w
    find $dir -type f -print0 | xargs -0 chmod u+rw-x,g+rw-x,o+r-wx > /dev/null 2>&1
done

Next to that I also always do a chown -R antiftw:www-data bolt/, to make sure ownership for all folders is correct (at least this was the way to fix it in plain Symfony)

TLDR:

As a result I do have two questions, before I go on and try and debug it further:

Kind regards and many thanks for the assist,

bobdenotter commented 4 years ago

Hi,

Executing this for loop shouldn't result in 777 on the cache directory if I am not wrong?

Could be. There's a setting in config.yaml for this:

filepermissions:
    folders: 0o775
    files: 0o664

If I read correctly, it shouldn't be needed to put 777 on the cache directory for it to work? 775 should be enough?

In most cases it should be, yes.. The trouble with this is that it's hard to explain properly for people in documentation. Basically it should be "make sure you and the web-user can read an write the files, and set the right appropriate". However for most people this would just be puzzling.. "Can't you just tell me what to set it to?" is what i get most often as a reply.

To get back to your initial problem: You think it's related to the cache, right? Continuing on that thought, I'm now thinking it might be related to the public/theme/ folder instead.. It's where the "templateselect" gets the list of files from, and Bolt not being able to read those might break stuff.

antiftw commented 4 years ago

Hi,

Another long reply, TLDR at the end.

Could be. There's a setting in config.yaml for this:

1) I am a bit confused by this answer, it sounds like you mean that the results of the execution of this for loop depend on the setting in the config.yaml? Reading the file suggests these permissions only affect newly created files and folders, but it is possible I misunderstand this? So that it is rather the other way around, you need to make sure the permissions in the loop fit the settings put in the config file? So if you put 755 in the config.yaml, you also need to edit the for loop, since now it is done for 775?

Nevertheless I checked out the config.yaml, and noticed the sentence:

  • If they're in the same group, use use 0o775 for folders and 0o664 for files.

2) And after re-reading the sentence I noticed the typo (use use :)), is it appropriate to create a pullrequest for this or is that a bit over the top? For reference: config/bolt/config.yaml:140

I've never put my personal linux user in the www-data group before, but have always configured Symfony using:

chown myuser:www-data -R project_directory/ setfacl -R -m u:www-data:rwX -m u:whoami:rwX app/cache app/logs setfacl -dR -m u:www-data:rwx -m u:whoami:rwx app/cache app/logs

So that I was able to run commands from the command line to clear the cache for example, but my web-server is also allowed to do so when required. (not saying this is best practice, but it always worked for me after a lot of struggle with the clearing the cache in Symfony)

But because I am using the 775 (directory) and 664 (file) permissions I tried adding my personal user to the www-data group, but this didn't fix the error. (It didn't make sense that it would, but I just did it to confirm it)

3) What's also a bit unclear to me is what is meant by "the user who owns the actual folders/files, does this mean my personal user used to create the Linux install, or is this referring to users in the sense of actual users of the CMS? So if I login with another user in the Bolt backend, and upload files or something, these files get another user as owner? This seems unlikely, but I just ask to make sure we are talking about the same thing.

I also checked the permissions on the theme directory and underlying folders/files and these look exactly the same in both projects: files are 664 and directories are 775, so this shouldn't result in any problems.

The main reason I mentioned permissions is because the first load it seems to work (so when executing the code to actually build the dropdown for the templates it does work). It seems when loading the cached version of this page does not work.

So, to test out a theory, I tried putting 777 on the cache directory but unfortunately this did not help either. (sudo chmod 777 -R var/cache)

Because this didn't work I took a closer look into the cache directory, and the file that actually produces the error. What stood out to me is that the permissions of the cache file that is created is 666, which shouldn't give any permission problems since it is readable/writable by anyone. However to make sure I also tried putting this specific file to 777, which did not fix the error.

Also looked up the exact line (r44 in the cache file) that gives the error:

$context["options"] = $this->extensions['Bolt\Twig\ContentExtension']->getListTemplates((isset($context["field"]) || array_k$

So it seems that the $context['field'] variable contains a value that has a different type than expected. When dumping this variable

dd($context['field']);

I get the following result :

^ Bolt\Entity\Field {#1623 ▶}

However when dumping the variable in the non cached file (\Bolt\Twig\ContentExtension::getListTemplates (r440)):

dd($field);

I get

^ Bolt\Entity\Field\TemplateselectField {#2546 ▶}

Comparing the rest of the fields in the variable, all the values are exactly the same, so it seems the only difference is the actual type of the variable. Even in the FieldType variable, both of them even have "template" as slug, "templateselect" as type and "template" as name.

TLDR:

Could you answer my questions 1), 2) and 3) please?

Wieter commented 3 years ago

I also just encountered this exact same issue (although in prod env). Indeed no page exists, nor textures are loaded. Although I was able to set the homepage initially, once I tried adding a normal page this error came.

When I clear the cache using php bin/console cache:clear (and subsequently set the permissions of ./var back to their correct values!), I can load the https://www.hidden.hide/bolt/new/pages exactly 1 time. Once I refresh: boom, 500.

relevant info from ./www # tail -f var/log/prod.log:

[2020-10-30T20:03:08.393786+00:00] php.CRITICAL: Uncaught Error: Argument 1 passed to Bolt\Twig\ContentExtension::getListTemplates() must be an instance of Bolt\Entity\Field\TemplateselectField, instance of Bolt\Entity\Field given, called in /usr/local/www/apache24/data/www.hidden.hide/www/var/cache/prod/twig/5d/5d64d36b7da1df74af71f41481b777da402f1f3e77046442e8ff0c8196e82bf6.php on line 42 {"exception":"[object] (TypeError(code: 0): Argument 1 passed to Bolt\\Twig\\ContentExtension::getListTemplates() must be an instance of Bolt\\Entity\\Field\\TemplateselectField, instance of Bolt\\Entity\\Field given, called in /usr/local/www/apache24/data/www.hidden.hide/www/var/cache/prod/twig/5d/5d64d36b7da1df74af71f41481b777da402f1f3e77046442e8ff0c8196e82bf6.php on line 42 at /usr/local/www/apache24/data/www.hidden.hide/www/vendor/bolt/core/src/Twig/ContentExtension.php:480)"} []
[2020-10-30T20:03:08.402858+00:00] request.CRITICAL: Uncaught PHP Exception TypeError: "Argument 1 passed to Bolt\Twig\ContentExtension::getListTemplates() must be an instance of Bolt\Entity\Field\TemplateselectField, instance of Bolt\Entity\Field given, called in /usr/local/www/apache24/data/www.hidden.hide/www/var/cache/prod/twig/5d/5d64d36b7da1df74af71f41481b777da402f1f3e77046442e8ff0c8196e82bf6.php on line 42" at /usr/local/www/apache24/data/www.hidden.hide/www/vendor/bolt/core/src/Twig/ContentExtension.php line 480 {"exception":"[object] (TypeError(code: 0): Argument 1 passed to Bolt\\Twig\\ContentExtension::getListTemplates() must be an instance of Bolt\\Entity\\Field\\TemplateselectField, instance of Bolt\\Entity\\Field given, called in /usr/local/www/apache24/data/www.hidden.hide/www/var/cache/prod/twig/5d/5d64d36b7da1df74af71f41481b777da402f1f3e77046442e8ff0c8196e82bf6.php on line 42 at /usr/local/www/apache24/data/www.hidden.hide/www/vendor/bolt/core/src/Twig/ContentExtension.php:480)"} []
[2020-10-30T20:03:08.427742+00:00] php.INFO: User Deprecated: Since pagerfanta/pagerfanta 2.4: The "Pagerfanta\Adapter\DoctrineORMAdapter" class is deprecated and will be removed in 3.0. Use the "Pagerfanta\Doctrine\ORM\QueryAdapter" class from the "pagerfanta/doctrine-orm-adapter" package instead. {"exception":"[object] (ErrorException(code: 0): User Deprecated: Since pagerfanta/pagerfanta 2.4: The \"Pagerfanta\\Adapter\\DoctrineORMAdapter\" class is deprecated and will be removed in 3.0. Use the \"Pagerfanta\\Doctrine\\ORM\\QueryAdapter\" class from the \"pagerfanta/doctrine-orm-adapter\" package instead. at /usr/local/www/apache24/data/www.hidden.hide/www/vendor/pagerfanta/pagerfanta/src/Adapter/DoctrineORMAdapter.php:7)"} []
[2020-10-30T20:03:08.497779+00:00] security.DEBUG: Stored the security token in the session. {"key":"_security_main"} []
Wieter commented 3 years ago

Sidenote: in prod environment the command php bin/console doctrine:fixtures:load does not exist. Doctrine fixtures load is only valid in a dev env.

Wieter commented 3 years ago

A quick-fix for who wants to rush into production without fixtures, is the following:

  1. perform the usual composer install
  2. set up a valid .env.local with APP_ENV=dev (because the fixtures are not available for prod env)
  3. run php bin/console doctrine:schema:create
  4. load fixtures php bin/console doctrine:fixtures:load without images, run: php bin/console doctrine:fixtures:load --no-interaction --group=without-images
  5. change the .env.local to contain the desired APP_ENV=prod
  6. clear loaded static data by running rm -r ./public/files/{animal,people,stock}
  7. drop the database structure, run php bin/console doctrine:schema:drop --force
  8. re-initialize the database, run php bin/console doctrine:schema:create
  9. add superuser, run php bin/console bolt:add-user --admin
  10. ensure default themes are present, run php bin/console bolt:copy-themes
  11. ensure proper permissions as described here (personally I additionally had to chown the config,var,public/files,public/theme,public/thumbs dirs to www)

Basically this loads and purges the fixtures. Not very fancy but it worked perfectly for my needs.

bobdenotter commented 3 years ago

@Wieter If you don't wish the fixtures to fetch images, you could perhaps also run doctrine:fixtures:load --no-interaction --group=without-images ?

Wieter commented 3 years ago

@Wieter If you don't wish the fixtures to fetch images, you could perhaps also run doctrine:fixtures:load --no-interaction --group=without-images ?

@bobdenotter Oh, yes. How did I miss that one? (note to self: need to enhance caffeine intake.. ). I'll edit above post accordingly. On a side-note, during all things above I might have encountered a security issue. As suggested there, I sent an email yesterday. However, I think the stated email address there is incorrect, as I received the following:

Final-Recipient: rfc822;security@bolt.cm
Action: failed
Status: 5.5.0
Diagnostic-Code: smtp;550 No such recipient here

Where can I forward this issue to? Perhaps here publicly is not too bad actually, because it concerns a configuration step during setup.