propelorm / Propel2

Propel2 is an open-source high-performance Object-Relational Mapping (ORM) for modern PHP
http://propelorm.org/
MIT License
1.26k stars 399 forks source link

Propel error since last upgrade from dev-master 8383788 => dev-master 150556e #1756

Closed phili67 closed 3 years ago

phili67 commented 3 years ago

I've just upgrade propel from to the last version and now I get :

Fatal error: Uncaught Propel\Runtime\Exception\PropelException: Your configuration is outdated. Please rebuild it with the config:convert command. in 
/var/www/CRM/src/vendor/propel/propel/src/Propel/Runtime/ServiceContainer/StandardServiceContainer.php:233 Stack trace: #0 /var/www/CRM/src/EcclesiaCRM/Bootstrapper.php(185): 
Propel\Runtime\ServiceContainer\StandardServiceContainer->checkVersion('dev-master') #1 
/var/www/CRM/src/EcclesiaCRM/Bootstrapper.php(68): EcclesiaCRM\Bootstrapper::initPropel() #2 
/var/www/CRM/src/Include/LoadConfigs.php(33): EcclesiaCRM\Bootstrapper::init('localhost', '3306', 'root', '***', 'crm', '', false, 
Array, false) #3 /var/www/CRM/src/Include/Config.php(62): require_once('/var/www/CRM/sr...') #4 
/var/www/CRM/src/v2/index.php(4): require('/var/www/CRM/sr...') #5 {main} thrown in 
/var/www/CRM/src/vendor/propel/propel/src/Propel/Runtime/ServiceContainer/StandardServiceContainer.php on line 233

Could someone give me an advice ?

mringler commented 3 years ago

Your Propel configuration needs to be rebuild. This is what the first line of the exception says:

Your configuration is outdated. Please rebuild it with the config:convert command.

To update it, you need to run (in your project dir):

./vendor/bin/propel config:convert --config-dir path/to/your/config/folder

Changing configuration was necessary to support preloading in PHP 7.4.

Does that work?

phili67 commented 3 years ago

I'm not using a configuration file but I'm using ConnectionManagerSingle

In my code I'm using :

self::$manager = new ConnectionManagerSingle();
self::$manager->setConfiguration(self::buildConnectionManagerConfig());

The function is :

private static function buildConnectionManagerConfig()
      {
          if (is_null(self::$databasePort)) {
              self::$databasePort = 3306;
          }
          return [
            'dsn' => Bootstrapper::GetDSN(),
            'user' => self::$databaseUser,
            'password' => self::$databasePassword,
            'settings' => [
                'charset' => 'utf8',
                'queries' => ["SET sql_mode=(SELECT REPLACE(REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''),'NO_ZERO_DATE',''))"],
            ],
            'classname' => self::$dbClassName,
            'model_paths' => [
                0 => 'src',
                1 => 'vendor',
            ],
        ];
      }
mringler commented 3 years ago

No problem, you just need to do two things:

Let me know if that works.

phili67 commented 3 years ago

Ok this help me a lot : https://github.com/phili67/ecclesiacrm/pull/1882/files

But I had to include the code in the Boostrapper ... so an upgrade of the schema in some months could be easely forgotten. The code of loadDatabase.php, doesn't have any namespace ...

But it works !

Using propel is ever harder.

Thank's a lot for your advice !

mringler commented 3 years ago

Great! Sorry for the inconvenience. This change was not done because we like it that way, but because it is the only way to keep Propel working with PHP 7.4 preloading. I hope you understand.

Yes, loadDatabase.php does not have a namespace. Reasons are:

You can easily place the file outside of src, if you don't want to have it marked. But please let me know if you prefer a different solution!

Two tips: I think you can simplify your orm-gen target by using the --loader-script-dir parameter, which allows you to specify the location of the script:

"orm-gen": "src/vendor/propel/propel/bin/propel --config-dir=propel --loader-script-dir=src/EcclesiaCRM model:build && cd src/ && composer dump-autoload && cd ..",

And if it is possible, I would simply require_once the generated script, so you don't have to update your code every time you add or remove tables:

    private static function initPropel() {
        // first do your initialization as before
        ...

        // at the end, require the file
        require_once(__DIR__ . '/loadDatabase.php');
    }

Then you don't need self::$serviceContainer->initDatabaseMaps(self::getDBArrayMap());, and a simple call to orm-gen should suffice for an update. Then you never have to worry about loading again (probably). You might need to add an empty dummy file, so you don't get an exception when the loader was not created yet.

Hope that helps, let me know if it doesn't.

phili67 commented 3 years ago

Ok I finally include your solution.

Thank's a lot for all