The reason no autoload error is throw, is because symfony's autoloader loads the class for you, but it does it at the getTable() call, which as seen below from Doctrine_Core::getTable(), it's proxied though the connection - which is created before the gable is instanced, which of when the file is actaully loaded.

Ian P. Christian
added a comment - 16/Jun/10 8:46 AM - edited The reason no autoload error is throw, is because symfony's autoloader loads the class for you, but it does it at the getTable() call, which as seen below from Doctrine_Core::getTable(), it's proxied though the connection - which is created before the gable is instanced, which of when the file is actaully loaded.
return Doctrine_Manager::getInstance()->getConnectionForComponent($componentName)->getTable($componentName);

$_modelsDirectory is never set, and $_loadedModelFiles is an empty array. The $_modelsDirectory, even if set, wouldn't handle loading for plugins, which put their models in places like lib/model/doctrine/sfDoctrineGuardPlugin/sfGuardUser.class.php.

This was not a problem before r7668 (at least, not for most use cases)....

It used to be that null was passed as the first arg in the D_Query::create() method call, causing the query to figure out itself which connection to use, which was done after the component was bound, so that's fine!

Ian P. Christian
added a comment - 16/Jun/10 11:34 AM - edited This was not a problem before r7668 (at least, not for most use cases)....
It used to be that null was passed as the first arg in the D_Query::create() method call, causing the query to figure out itself which connection to use, which was done after the component was bound, so that's fine!
However, the code below is how it is in the current head
public function createQuery($alias = '')
{
if ( ! empty($alias)) {
$alias = ' ' . trim($alias);
}
$class = $ this ->getAttribute(Doctrine_Core::ATTR_QUERY_CLASS);
return Doctrine_Query::create($ this ->_conn, $class)
->from($ this ->getComponentName() . $alias);
}
Here , the connection of the table (as explained above is previously set incorerctly) is passed to the query.

Ian P. Christian
added a comment - 16/Jun/10 12:43 PM I've found a work around to this, not sure if it's a desirable fix though...
In the project configuration class, I've added this to the setup()
$ this ->dispatcher->connect('doctrine.configure', array($ this , 'doctrineBinder'));
and the following method is also added, were I'm manually doing my bindings...
public function doctrineBinder(sfEvent $event)
{
$manager = Doctrine_Manager::getInstance();
$manager->bindComponent('sfGuardUser', 'nosp');
$manager->bindComponent('Incident', 'nosp');
$manager->bindComponent('ServiceIp', 'ip');
}
The overhead here isn't really that high (it just sets an element in the array) - I'd also wonder if a bindComponents($array); should be added to simplify this call, but that's another method.

After a long and hard look at the sfDoctrinePlugin and Doctrine code I can to the same conclusion. The Doctrine autoload is not working in sfDoctrinePlugin. I think this is more a sfDoctrinePlugin bug than a Doctrine bug.

Instead of manual binding, a better way is the actually make sure the intended flow of the code is working like it should be.

To be able to use sfDoctrineGuard with multiple connections you need to ensure that the connection name is added to the Schema of sfDoctrineGuard. Once this is done, rebuilding the model will put a bindComponent in the class files.

This works fine if the autoload is working like it should.

To get the autoload to work, you can extend the autoload function of Doctrine_Core in Doctrine:

The Doctrine.php file is empty by default, so its easy to add your code to it (until the problem is fixed without having to edit Doctrine code)

Marcel Berteler
added a comment - 06/Jul/10 10:41 AM - edited After a long and hard look at the sfDoctrinePlugin and Doctrine code I can to the same conclusion. The Doctrine autoload is not working in sfDoctrinePlugin. I think this is more a sfDoctrinePlugin bug than a Doctrine bug.
Instead of manual binding, a better way is the actually make sure the intended flow of the code is working like it should be.
To be able to use sfDoctrineGuard with multiple connections you need to ensure that the connection name is added to the Schema of sfDoctrineGuard. Once this is done, rebuilding the model will put a bindComponent in the class files.
This works fine if the autoload is working like it should.
To get the autoload to work, you can extend the autoload function of Doctrine_Core in Doctrine:
The Doctrine.php file is empty by default, so its easy to add your code to it (until the problem is fixed without having to edit Doctrine code)
lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine.php:
class Doctrine extends Doctrine_Core
{
public static function modelsAutoload($className)
{
sfAutoload::getInstance()->autoload($className);
parent::modelsAutoload($className);
}
}

Marcel Berteler
added a comment - 06/Jul/10 11:26 AM Oh, and to make sfDoctrineGuard work properly, you might have to ensure the sfBasicSecurityUser is bound to the correct model.
You can do this in plugins\sfDoctrineGuardPlugin\lib\user\sfGuardSecurityUser.class.php or in apps\xxxxx\lib\myUser.class.php
Doctrine_Manager::getInstance()->bindComponent('sfGuardUser', 'connectionName');

Marcel Berteler
added a comment - 07/Jul/10 6:05 AM The patch to Doctrine_Core
This is a hack that only works when used in sfDoctrinePlugin / Symfony
Not intended as the final patch to fix this bug but as a work around to make multiple connections usable.

I found that if I changed the getTable function inside the Core.php file it seemed to work. Basically it forces the autoloader to load the object file, and when it does this it runs the bound connection statement to bind a table to a connection.

Dean de Bree
added a comment - 16/Nov/10 3:08 AM I found that if I changed the getTable function inside the Core.php file it seemed to work. Basically it forces the autoloader to load the object file, and when it does this it runs the bound connection statement to bind a table to a connection.
Core.php
/**
* Get the Doctrine_Table object for the passed model
*
* @param string $componentName
* @ return Doctrine_Table
*/
public static function getTable($componentName)
{
if (!class_exists($componentName)) {
new $componentName();
}
return Doctrine_Manager::getInstance()->getConnectionForComponent($componentName)->getTable($componentName);
}