Having been away from Concrete for a while (cause I still have to convince my client that Concrete is their ultimate replacement of both WordPress and Magento) I’m finally trying to set up a new project in ConcreteCMS. Following the docs, I started with a composer create-project then ran vendor/bin/concrete5 c5:install -i .
It all goes through the questions nicely, then as soon as the actual installation begins, it crashes as follows:
—x8 begin copypaste
5%: Starting installation and creating directories.
19%: Creating database tables.
In StartingPointPackage.php line 461:
Unable to install database: [Semantical Error] The annotation “@Doctrine\ORM\Mapping\MappedSuperClass” in class Concrete\Core\Entity\Attribute\Key\Setti
ngs\Settings was never imported. Did you maybe forget to add a “use” statement for this annotation?
—x8 end of copypaste
I tried this on a Centos 7 webserver running nginx (but that didn’t yet do anything) that is already successfully running a Concrete 8.5.5 website on another vhost. So all the basic necessities are there. I tried the create and install process using php81 and then again from scratch in php74 but both end in the same error.
On a side note, here are a few weird things I noticed:
If I install it exactly according to the docs this fails, because I need to enable plugins first. So the actual way I created and installed the project was with:
composer create-project --no-install concretecms/composer
And then inside the project:
composer config --no-plugins allow-plugins.composer/installers true
composer update
(And then answering yes when permission for a plugin is asked).
Furthermore, I get warnings about concrete5-* packages being deprecated and having to use concretecms-* instead. I’m aware that ConcreteCMS is in the process of changing its repo names but even though I use “concretecms” as root project, it still seems to install deprecated concrete5-packages and then complain about it. I’m guessing there’s no real difference except the name, but if there’s something I need to do differently to be fully in ConcreteCMS-space then I’ll be glad to hear it.
I got desperate and started to dig around the core sources myself, and I managed to get it running, by applying two changes, one of which really fixes a fatal error that makes me wonder how anyone can use this out of the box.
First, as interpreting @ORM\MappedSuperclass seemed to go wrong even if I added a specific use statement for that annotation, I changed the phpdoc-comment to:
#[MappedSuperclass]
…in all the files this occurred in, as this seems to be the way to annotate this according to (new?) Doctrine docs.
When I changed that, the installer got a bit further, and then crashed on this line in public/concrete/src/Database/EntityManagerConfigFactory.php:
It turns out that registerFile is deprecated since Doctrine 2, and in the current version of Doctrine that ships with Concrete9.1.3, the file registered here doesn’t exist at all anymore so there was no way this was ever going to work. Following a StackOverflow-suggestion, I changed this line to:
And I have no idea if it’s now doing what it should be doing, but the installer ran successfully and the site is working as far as I can tell at first glance.
Especially the last thing seems to be a pretty serious bug; I guess people upgrading to the current version with an already running site won’t be troubled by it, but as far as I can tell it’s completely impossible to run the installer for a new site in the current version of ConcreteCMS without these changes.
# sudo -u www-data ./public/concrete/bin/concrete c5:update
PHP Warning: Uncaught Whoops\Exception\ErrorException: require_once(doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php): failed to open stream: No such file or directory in /var/www/Le/I-am-Le.se/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationRegistry.php:69
Stack trace:
#0 /var/www/Le/I-am-Le.se/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationRegistry.php(69): Whoops\Run->handleError()
#1 /var/www/Le/I-am-Le.se/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationRegistry.php(69): require_once()
#2 /var/www/Le/I-am-Le.se/public/concrete/src/Database/EntityManagerConfigFactory.php(88): Doctrine\Common\Annotations\AnnotationRegistry::registerFile()
#3 /var/www/Le/I-am-Le.se/public/concrete/src/Database/EntityManagerConfigFactory.php(75): Concrete\Core\Database\EntityManagerConfigFactory->getMetadataDriverImpl()
#4 /var/www/Le/I-am-Le.se/public/concrete/src/Database/EntityManagerFactory.php(56): Concrete\Core\Database\EntityManagerConfigFactory- in /var/www/Le/I-am-Le.se/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationRegistry.php on line 69
PHP Fatal error: Doctrine\Common\Annotations\AnnotationRegistry::registerFile(): Failed opening required 'doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php' (include_path='/var/www/Le/I-am-Le.se/public/application/bootstrap/../../../vendor:/var/www/Le/I-am-Le.se/public/concrete/vendor:.:/usr/share/php') in /var/www/Le/I-am-Le.se/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationRegistry.php on line 69
Whoops\Exception\ErrorException: Doctrine\Common\Annotations\AnnotationRegistry::registerFile(): Failed opening required 'doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php' (include_path='/var/www/Le/I-am-Le.se/public/application/bootstrap/../../../vendor:/var/www/Le/I-am-Le.se/public/concrete/vendor:.:/usr/share/php') in file /var/www/Le/I-am-Le.se/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationRegistry.php on line 69
Stack trace:
1. Whoops\Exception\ErrorException->() /var/www/Le/I-am-Le.se/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationRegistry.php:69
| array(1) {
| [0]=>
| string(306) "Doctrine\Common\Annotations\AnnotationRegistry::registerFile(): Failed opening required 'doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php' (include_path='/var/www/Le/I-am-Le.se/public/application/bootstrap/../../../vendor:/var/www/Le/I-am-Le.se/public/concrete/vendor:.:/usr/share/php')"
| }
2. Whoops\Run->handleError() /var/www/Le/I-am-Le.se/vendor/filp/whoops/src/Whoops/Run.php:514
| array(0) {
| }
3. Whoops\Run->handleShutdown() [internal]:0
| array(0) {
| }
One thing that worries me in this is the warnings about abandoned packages:
Package concrete5/dependency-patches is abandoned, you should avoid using it. Use concretecms/dependency-patches instead.
Package concrete5/doctrine-xml is abandoned, you should avoid using it. Use concretecms/doctrine-xml instead.
Package concrete5/monolog-cascade is abandoned, you should avoid using it. Use concretecms/monolog-cascade instead.
Ah, well that’s the same error I got (I noticed the @ORM error doesn’t happen on all environments).
You can fix this with the manual edit I suggested above (or create a composer patch for it to make it repeatable, but I’m hoping this will be fixed in the next update). (So in your case you only need the second edit, replacing registerFile(…) with registerLoader(‘class_exists’);
The abandoned packages don’t seem to be a problem for now, the concretecms-packages seem to be at the same versions as the concrete5-packages, I hope that by the time those packages require new versions the references to the old concrete5-packages will be fixed too.
# sudo -u www-data ./public/concrete/bin/concrete c5:update
In AnnotationException.php line 40:
[Semantical Error] The annotation "@Doctrine\ORM\Mapping\MappedSuperClass" in class Concrete\Core\Entity\Attribute\Value\AbstractValue was never imported. Did you maybe forget to add a "use" statement for this annotatio
n?
c5:update [--env ENV] [--allow-as-root] [--rerun] [-a|--after AFTER] [-s|--since SINCE]
Aaaaaah yes! THAT was the real problem with the ORM tag… I just “accidentally” fixed it using the other notation ( #[MappedSuperclass] ). (Ironically, I remember also writing Class instead of class once at first there as well).
I’ll update my patches and will watch out of the next update fixes all this so I can remove them again.
Haha yes that’s been a bit of a slippery slope… I mean it started with structured comments (/**) to document variable types, and then along comes Doctrine and says “well if you document them even more specifically, I can automatically attach your classes to a database” and here we are.
I can live with it by considering that comments are used to document stuff to others outside the interpreter. Usually that’s humans but not always.
Unfortunately, this got messed up in the 9.1.3 release. It should be MappedSuperclass.
The easiest solution is to use 9.1.2 until 9.2 is released (release candidate is out now if you want to try it here: Concrete CMS 9.2.0RC2 Now Available!
… and if you’re already installed 9.1.3 with composer, for the love of all the gods do notcomposer upgrade your site!…
EDIT: Maybe I misunderstand… MappedSuperClass is there in a working 9.1.3 installation that I did in what, December last year? This was a composer upgrade, BTW. How did that work out? What else do I need to be careful with to not trip the issue we’ve seen here? No frivolous c5:update?
For the benefit of anyone else that stumbles into this issue, I’m sharing my patch, which includes documentation.
Subject: Installing ConcreteCMS 9.1.3 with composer may fail
When installing or upgrading to ConcreteCMS 9.1.3 with composer as documented,
you may find yourself with a failing site, or failure when trying to perform
post-install/post-upgrade actions... such as updating the database:
./public/concrete/bin/concrete c5:update
A typical error is:
PHP Fatal error: Doctrine\Common\Annotations\AnnotationRegistry::registerFile(): Failed opening required 'doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php' (include_path=...) in /var/www/Le/I-am-Le.se/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationRegistry.php on line 69
In that case, this patch is for you. Save it as patch.txt, locate yourself
in the parent directory of your site (i.e. the directory that contains the
'public' subdirectory), and apply like this:
patch < patch.txt
After that, you should be able to perform the actions that failed previously.
--- public/concrete/src/Database/EntityManagerConfigFactory.php.orig 2022-10-26 22:21:05.000000000 +0200
+++ public/concrete/src/Database/EntityManagerConfigFactory.php 2023-04-07 17:00:21.094105443 +0200
@@ -85,7 +85,7 @@
public function getMetadataDriverImpl()
{
// Register the doctrine Annotations
- \Doctrine\Common\Annotations\AnnotationRegistry::registerFile('doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php');
+ \Doctrine\Common\Annotations\AnnotationRegistry::registerUniqueLoader('class_exists');
$legacyNamespace = $this->getConfigRepository()->get('app.enable_legacy_src_namespace');
if ($legacyNamespace) {
--- public/concrete/src/Entity/Attribute/Value/Value/AbstractValue.php.orig 2022-10-26 22:21:05.000000000 +0200
+++ public/concrete/src/Entity/Attribute/Value/Value/AbstractValue.php 2023-04-07 17:07:59.251746130 +0200
@@ -4,7 +4,7 @@
use Doctrine\ORM\Mapping as ORM;
/**
- * @ORM\MappedSuperClass
+ * @ORM\MappedSuperclass
*/
abstract class AbstractValue
{
--- public/concrete/src/Entity/Attribute/Value/AbstractValue.php.orig 2022-10-26 22:21:05.000000000 +0200
+++ public/concrete/src/Entity/Attribute/Value/AbstractValue.php 2023-04-07 17:07:59.755743519 +0200
@@ -8,7 +8,7 @@
use Doctrine\ORM\Mapping as ORM;
/**
- * @ORM\MappedSuperClass
+ * @ORM\MappedSuperclass
*/
abstract class AbstractValue implements AttributeValueInterface
{
--- public/concrete/src/Entity/Attribute/Key/Settings/Settings.php.orig 2022-10-26 22:21:05.000000000 +0200
+++ public/concrete/src/Entity/Attribute/Key/Settings/Settings.php 2023-04-07 17:07:44.295823616 +0200
@@ -6,7 +6,7 @@
use Doctrine\ORM\Mapping as ORM;
/**
- * @ORM\MappedSuperClass
+ * @ORM\MappedSuperclass
*/
abstract class Settings
{
--- public/concrete/src/Entity/Page/Relation/Relation.php.orig 2022-10-26 22:21:05.000000000 +0200
+++ public/concrete/src/Entity/Page/Relation/Relation.php 2023-04-07 17:07:58.663749173 +0200
@@ -4,7 +4,7 @@
use Doctrine\ORM\Mapping as ORM;
/**
- * @ORM\MappedSuperClass
+ * @ORM\MappedSuperclass
*/
abstract class Relation
{
--- public/concrete/src/Entity/Search/SavedSearch.php.orig 2022-10-26 22:21:05.000000000 +0200
+++ public/concrete/src/Entity/Search/SavedSearch.php 2023-04-07 17:07:58.159751789 +0200
@@ -4,7 +4,7 @@
use Doctrine\ORM\Mapping as ORM;
/**
- * @ORM\MappedSuperClass
+ * @ORM\MappedSuperclass
*/
abstract class SavedSearch
{