[DC-839] Version classes not built for models using package attribute Created: 24/Aug/10  Updated: 08/Mar/11

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.0
Fix Version/s: None

Type: Bug Priority: Blocker
Reporter: Prasad Gupte Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None
Environment:

PHP 5.2.3 / Symfony 1.4.6



 Description   

For models using the 'package' attribute in the schema definition, the version classes do not get created. However, the version table gets created.

There is no problem during the build, but when loading fixtures, there is a fatal error: Class TaxCodeVersion not found

TaxCode:
package: Masters
tableName: Fin_Tax_Codes
actAs:
Activateable: ~
SoftDelete: ~

  1. Versionable:
  2. tableName: fin_tax_codes_version
    1. versionColumn: version
  3. className: %CLASS%Version
    1. auditLog: true
      Auditable: ~
      Timestampable: ~
      .......


 Comments   
Comment by hetsch [ 08/Mar/11 ]

Same here,

If i use this yaml file:

Page:
actAs:
NestedSet:
hasManyRoots: true
rootColumnName: root_id
Versionable:
versionColumn: version
className: %CLASS%Version
auditLog: true
Timestampable:
created:
name: created_at
type: timestamp
format: Y-m-d H
updated:
name: updated_at
type: timestamp
format: Y-m-d H
I18n:
fields: [name]
columns:
name: string(255)

PageVersion and PageTranslation Models don't get generated if i use 'build-models-yaml'. Have to create the Models manually then it works fine.





[DC-1062] Testing Created: 08/Jan/14  Updated: 08/Jan/14

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.2
Fix Version/s: 1.2.1

Type: Task Priority: Critical
Reporter: Janardan Singh Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None





[DC-922] master-slave replication with i18n behavior Created: 10/Nov/10  Updated: 10/Nov/10

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.0
Fix Version/s: None

Type: Bug Priority: Critical
Reporter: husen mankada Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

php 5.3, doctrine 1.2, Symfony 1.4, mysql



 Description   

I'm trying to use sfDoctrineMasterSlavePlugin for database replication with Symfony 1.4 and PHP 5.3. But facing problem while selecting I18n records and receiving "Unknown relation alias Translation" error.

I've also tried same with implementation solution given in master-slave chapter of doctrine cookbook but no success.

Is anyone facing same problem with sfDoctrineMasterSlavePlugin and i18n behavio? Is there any solution of the problem?






[DC-674] NULL Dates are translated to '0000-00-00' after upgrading to 1.2.2 Created: 10/May/10  Updated: 06/Oct/10

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.1, 1.2.2
Fix Version/s: 1.2.1, 1.2.2

Type: Bug Priority: Critical
Reporter: Ville Itämaa Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Zend Framework, Ubuntu 9.10, MySQL



 Description   

Once the upgrade was done from Doctrine 1.2.1 to 1.2.2 we discovered that date related issues started to appear.
With dates that are persisted in DB as NULL are translated to "0000-00-00" when retrieved from DB. This has occurred in multiple places and is quite worrying as there is a lot of dates in our project. This means that everywhere in our codebase where we check a datevalue in our Models is NULL we need also to check for the string literal "0000-00-00".



 Comments   
Comment by Jonathan H. Wage [ 10/May/10 ]

Are you able to reproduce this in a test case?

Comment by Ville Itämaa [ 11/May/10 ]

We reverted to Doctrine 1.2.1 after realising the bug to confirm it was Doctrine 1.2.2 that was the cause for the problem. And as a result the records with NULL dates in the DB became NULL in the Models.
But when using Doctrine 1.2.2, the NULL dates became '0000-00-00' in the Models.
I don't have any other way to reproduce this error.

Comment by Jonathan H. Wage [ 11/May/10 ]

Were you able to identity which changeset it was? You can read about creating test cases here http://www.doctrine-project.org/documentation/manual/1_2/en/unit-testing

So far I am not able to reproduce the error you described.

Comment by Jonathan H. Wage [ 08/Jun/10 ]

I'd like to fix this. Did you ever figure out which changeset introduced the issue? I've been trying to figure it out myself.

Comment by Roland Huszti [ 06/Oct/10 ]

With 1.2.3 this works for me fine with both TIMESTAMP and DATE fields.

YAML

        date_of_birth:
            type: date

BASE MODEL

        $this->hasColumn('date_of_birth', 'date', null, array(
             'type' => 'date',

             // try these two
             // 'notnull' => false,
             // 'default' => null
         ));
YAML

        exported_at:
            type: timestamp(25)
            notnull: false
            default: null

            # in this model I have everything to make sure it accepts and defaults to NULL

BASE MODEL

        $this->hasColumn('exported_at', 'timestamp', 25, array(
             'type' => 'timestamp',
             'notnull' => false,
             'length' => '25',
             ));

You may try adding these to your YAML and (base) models

YAML

    fieldname:
         . . .
        notnull: false
        default: null

BASE MODEL

        $this->hasColumn('fieldname', . . .
             . . .
             'notnull' => false, // <<<<<<<
             // 'default' => null, // <<< maybe, probably not needed
             ));

I hope it helps.





[DC-659] Sluggable behavior does not check uniqueness on insert if a slug is manually set, causing SQL error/crash Created: 01/May/10  Updated: 05/Oct/10

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.2
Fix Version/s: None

Type: Improvement Priority: Critical
Reporter: Christian Seaman Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

symfony-1.3.4 and doctrine-1.2.2



 Description   

The Sluggable behavior has the following code:

Sluggable.php
    /**
     * Set the slug value automatically when a record is inserted
     *
     * @param Doctrine_Event $event
     * @return void
     */
    public function preInsert(Doctrine_Event $event)
    {
        $record = $event->getInvoker();
        $name = $record->getTable()->getFieldName($this->_options['name']);

        if ( ! $record->$name) {
            $record->$name = $this->buildSlugFromFields($record);
        }
    }

However, this can lead to problems...

If the user incorrectly assigns a duplicate slug to the record then there is no uniqueness checking in doctrine and you get an uncaught SQL error looking something like this:

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'my-slug-en_GB' for key 'foo_i18n_sluggable_idx'

If this kind of "don't do a preInsert check if I manunally set the slug" behavior is a FEATURE then it would be best to have an option to allow it to be disabled. If it is a BUG then I would suggest that the preInsert method should be changed to:

Sluggable.php
    /**
     * Set the slug value automatically when a record is inserted
     *
     * @param Doctrine_Event $event
     * @return void
     */
    public function preInsert(Doctrine_Event $event)
    {
        $record = $event->getInvoker();
        $name = $record->getTable()->getFieldName($this->_options['name']);

        if ( ! $record->$name) {
            $record->$name = $this->buildSlugFromFields($record);
        } else { // Still check for slug uniqueness when you insert
            $record->$name = $this->buildSlugFromSlugField($record);
        }
    }

C



 Comments   
Comment by Jonathan H. Wage [ 08/Jun/10 ]

Can you provide your changes as a patch/diff with a test case?

Comment by Christian Seaman [ 05/Oct/10 ]

Hi Jonathan,

I'm not so hot at making patches or test cases, but it should be fairly easy if you know what you're doing...

Just try to create and save two records with the same hard-coded slug and the second one will fail with an ugly MySQL crash.

If you add the lines

        } else { // Still check for slug uniqueness when you insert
            $record->$name = $this->buildSlugFromSlugField($record);

to the Sluggable::preInsert() method then this problem is averted and the test cases will pass.

I have been running with this modification in our production version of Doctrine since I first reported this in May and it all seems to work well.

If you really need me to figure out how to make a patch and test case please re-comment on this ticket and I'll see what I can do when I have some free time.

C





[DC-371] Lazy loading - doctrine makes extra queries into db Created: 19/Dec/09  Updated: 23/Dec/10

Status: Open
Project: Doctrine 1
Component/s: Behaviors, Documentation, Query, Record
Affects Version/s: 1.2.0-BETA3
Fix Version/s: None

Type: Bug Priority: Critical
Reporter: Roman Drapeko Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Symfony 1.4, Doctrine Version: 1.2.0-BETA3



 Description   

Just downloaded symfony 1.4

First of all I have a query:

$q = \Doctrine_Query::create()
->select('u., ur.')
->from('UserDb u')
->leftJoin('u.RealUserDetailsDb ur')
->leftJoin('u.MockUserDetailsDb um')
->where('u.id = :user_id')
;
$user = $q->fetchOne(array(':user_id' => $uid));

After that I'm accessing the fields of this object:

$userArray = array(
'id' => $this->getUser()->getId(),
'real_user_details_id' => $this->getUser()->getRealUserDetailsId(),
'mock_user_details_id' => $this->getUser()->getMockUserDetailsId(),
'real_user_details' => array(),
'mock_user_details' => array()
);

This is the actual queries into DB:

NR1:
SELECT u.id AS u_id, u.user_real_id AS uuser_real_id, u.user_mock_id AS uuser_mock_id, u2.id AS u2id, u2.nickname AS u2nickname, u2.email AS u2_email FROM user u LEFT JOIN user_real u2 ON u.user_real_id = u2.id LEFT JOIN user_mock u3 ON u.user_mock_id = u3.id WHERE (u.id = :user_id)

NR2:
SELECT u.id AS u_id, u.user_real_id AS uuser_real_id, u.user_mock_id AS u_user_mock_id FROM user u WHERE (u.id = '1') LIMIT 1

As you can see there are TWO queries however there should be only one query. The problem is that u.user_real_id is NULL in database and when I do 'real_user_details_id' => $this->getUser()->getRealUserDetailsId() doctrine does not have enough intelligence to understand that these fields have been already requested in NR1. If I comment this field, everything works well.

SURPRISE!
And now a surprise... if I modify a little bit my first query: ">select('u.')" instead of , ">select('u., ur.*')" it WON'T make TWO queries. It will make ONLY ONE!

As you understand this a very critical bug and of course our system won't go to production with this bug.

P.S. Is it possible to turn off the lazy loading in doctrine?



 Comments   
Comment by Roman Drapeko [ 17/Jan/10 ]

Any comments? Will it be fixed??

Comment by Jonathan H. Wage [ 01/Mar/10 ]

Hi, I'd like to take a look but can you make a failing test case that I can run so that I can see if I can come up with a patch that fixes your case and doesn't break anything else.

Comment by Luke Winiarski [ 01/Jun/10 ]

Hi

I had similar problem but after several hours i did work it out

Try to make get method in your model for getting field which has NULL value in database

public function getUserRealId()

{ return $this->_get("user_real_id", false); }

by making second argument false u force doctrine not to lazy load value and extra sql query is not created

regards

Comment by Jonathan H. Wage [ 08/Jun/10 ]

Has anyone been able to reproduce this in a test case? I am not having much luck so far.

Comment by Gennady Feldman [ 23/Dec/10 ]

I've seen this a ton of times. Basically when it loads related records through the Hydrator using leftJoin() and gets NULLs back. BUT it doesn't save the fact that the related records are NULL. So when you actually do call to getRelated objects it sees that it doesn't have the value cached and runs the query again.

Let me know if I should show you the problem in the Doctrine code base.





[DC-992] I18n - Translated fields are not deleted when record in master table is deleted Created: 03/Apr/11  Updated: 28/Oct/11

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Thanasis Fotis Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Windows XP, xampp 1.7.3 (PHP 5.3.1)



 Description   

I have used I18n behavior for my application using the following:

public function setTableDefinition()
{
        $this->setTableName('products');

        $this->hasColumn('id', 'integer', 4, 
            array('fixed' => true, 
                  'primary' => true, 
                  'autoincrement' => true));

        $this->hasColumn('permalink', 'string', 255,
            array('notnull' => true));
        
        $this->hasColumn('title', 'string', 255, 
            array('notnull' => true));
            
        $this->hasColumn('teaser', 'string', 255, 
            array('notnull' => true));
            
        $this->hasColumn('content', 'clob', 32767);
}

public function setUp()
{   
        $this->actAs('I18n', array(
                'fields' => array('title', 'teaser', 'content')
            )
        );
}

Doctrine has created two tables db named products and products_translation.

Insert and update of the record is working fine but when i perform a deletion of a record, the record is deleted from the products table but the translations stored in products translation table are not deleted.



 Comments   
Comment by Justinas [ 28/Oct/11 ]

if you are not using transaction type tables like innoDB you need to set 'appLevelDelete' => TRUE option for I18n
it's not documented feature as i found out.

$this->actAs('I18n', array(
'fields' => array('title', 'teaser', 'content'),
'appLevelDelete' => TRUE,
)
);





[DC-974] generateFile = true - problematic implementation, see symfony ticket #4522 Created: 17/Feb/11  Updated: 17/Feb/11

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Georg Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 2
Labels: None
Environment:

symfony



 Description   

see http://trac.symfony-project.org/ticket/4522

When using a behaviour with generateFile=true, som eproblematic issues occur:

Let's take for example i18n:

schema.yml
...
actAs:
fields: [text]
generateFiles: true
generatePath: <?php echo sfConfig::get('sf_lib_dir') ?>/model/doctrine/translations

1) The translation model class and it's base class are not created with generate.php (aka symfony doctrine:build --model), but every time a translation model is used. This is not the expected behaviour, because
a) this makes autoloading these classes impossible.
b) the APC cache always sees a new change time, and recaches the fiels. This results in a quick fragmentation of the cache with segmentation faults in the long run.
2) The permissions for the created files are wrong. Normal executable php scripts should not be writable by the web server (admitting that with the current implementation, this is not problem, because the files are created again for each request)
3) The path is hard coded. This brakes deployment by svn update, and I would prefer not to build models on a production server.

Proposal:

  • generate the files at build model time
  • hopefully find a solution with the path

I realize that most development resources are now in the new doctrine, but this issue (especially the apc fragmentation) is a huge problem for me. If you won't fix it, let me know, then I would try to propose a patch. I checked the code, and the building and behaviour internal part of doctrine are not too well documented, and my patch would be far from perfect.






Non-Equal Nest Relations Not Working - from "Children" side (DC-952)

[DC-958] updating Models with Intra-Table Relations cascades strangely Created: 24/Jan/11  Updated: 27/Jan/11

Status: Open
Project: Doctrine 1
Component/s: Behaviors, Documentation, Nested Set, Relations
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Sub-task Priority: Major
Reporter: Daniel Reiche Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

PHP 5.3 / symfony 1.4.9



 Description   

Sorry for the lengthy explanation, couldn't make it more straight forward:

I have a model which is similiar to a nestet set but the tree structure needs to overlap:

For Model A, every Object A1 can have multiple descendant objects A2 and in turn can be a descendant of multiple objects A0.

Since I saw no way to do this with Nested-Set Relations (or Equal-Nested-Sets) I have set up my Model like this:

modules:
columns: ..<do not matter>
relations:
Children:
class: modules
refClass: modules_required
Parents:
class: modules
refClass: modules_required

modules_required:
columns: <do not matter here, just 2 foreign key columns>
relations:
Children:
Parents:

I needed to specify the Relations on both tables, to use onDelete/onUpdate CASCADE rules. Generated Models look fine, just as intended.
(Every Class has many Children and has many Parents...)

Now the strange part:
When I update an object of modules (say id=18), Doctrine issues the following queries:
DELETE FROM modules_required WHERE (required_id = ? AND module_id IN (?, ?, ?, ?, ?)) - (18, 25, 26, 32, 34, 35)
// where 25 to 35 are CHILDREN of 18
UPDATE modules_required SET required_id = ? WHERE module_id = ? AND required_id = ? - (25, 25, 10)
UPDATE modules_required SET required_id = ? WHERE module_id = ? AND required_id = ? - (26, 26, 10)
UPDATE modules_required SET required_id = ? WHERE module_id = ? AND required_id = ? - (32, 32, 10)
UPDATE modules_required SET required_id = ? WHERE module_id = ? AND required_id = ? - (34, 34, 10)
UPDATE modules_required SET required_id = ? WHERE module_id = ? AND required_id = ? - (35, 35, 10)
UPDATE modules_required SET required_id = ? WHERE module_id = ? AND required_id = ? - (25, 25, 12)
//where 10 and 12 are PARENTS of 18
and somewhen, Doctrine encounters an MySQL ERROR because of the previous update marathon:
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '25-25' for key 'PRIMARY'

The point is:
1. why is Doctrine trying to create self-referencing relations, and
2. why is it touching the relation at all, when i only did change some text fields in the object?

Is there a better way to solve my problem?



 Comments   
Comment by Daniel Reiche [ 25/Jan/11 ]

forgot to add something: I have done a debug run, to see why these queries are created, when there was no data modified that related to these tables:

Doctrine seems to handle my structure internally as a Nested-Set, although I have not specified an actAs: NestedSet or relations: equal: true statement in the model definition.
Is there a way to prevent symfony from misinterpreting this?

This is not a nested set, as each object can have virtually any other object either as parent or as a child, and additionaly, parent relations can span multiple tree-levels:
Object 2 is parent of Object 3 and 6
Object 3 is parent of Object 4 and 5
Object 4 is parent of Object 6

results in: Object 6 has parents 2 and 4 (where 4 has parent 3 and 3 has parent 2 in turn)

This spanning relations seems to cause the guessed nested set to fail.

I simply wanted to create an m:n Relation using a Reference table and the fact that both m and n are of the same class should not consider doctrine.

Comment by Daniel Reiche [ 26/Jan/11 ]

related to #DC-329:
seems to be the same general problem as described there. Only in DC 1.2.3, doctrine tries to delete every child-relation for some unknown reason.

also the h2aEqualable mentioned there does not work, because it does not prevent symfony from issueing the delete queries. It prevents only the UPDATE-Queries, and thus circumvents the MySQL-Error.

Nevertheless, data is still corrupted after object save, thus not useable in production.





[DC-955] Loading fixtures containing data for Versionable/Searchable Models fails due to Duplicate-Key errors Created: 14/Jan/11  Updated: 14/Jan/11

Status: Open
Project: Doctrine 1
Component/s: Behaviors, Data Fixtures, Import/Export, Searchable
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Daniel Reiche Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None
Environment:

PHP 5.3.3 / symfony 1.4.9-dev / MySQL 5.0



 Description   

Sample schema:

Blog:
actAs: [Versionable, Searchable]
columns:
id:

{ type: integer, primary: true, autoincrement: true }

name: string
text: text

When dumping data of a schema with Versionable and/or Searchable Behaviour, the dump.yml will contain all data, including the *_version and *_index tables.

Trying to load the same .yml file results in Duplicate-Key constraint violations, as long as the data for the *_version and *_index tables is present.
The import is only successfull, when the data for these tables is discarded.
This leads to the issue, that one can only do a dump-load cycle, when the complete version history of a Model is discarded. Which makes dump-load for such models rather useless.






[DC-899] Expose hardDelete method on node object when SoftDelete behavior is used Created: 22/Oct/10  Updated: 22/Oct/10

Status: Open
Project: Doctrine 1
Component/s: Behaviors, Nested Set
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: Fernando Varesi Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

MySQL



 Description   

When combining SoftDelete and NestedSet behavior, there's no way of calling hardDelete method on node object. According to documentation, to peform a delete on a nested set, delete should be called in node object, which will call delete method on the object itself.






[DC-880] Versionable + I18n creates additional migration with irrelevant data Created: 06/Oct/10  Updated: 17/Apr/14

Status: Open
Project: Doctrine 1
Component/s: Behaviors, I18n, Migrations, Relations
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Thomas Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None
Environment:

PHP 5.2, Symfony 1.4, Diem 5.1, Doctrine 1.2.2



 Description   

First run of generate-migrations-diff and migrate creates 2 migration diff files. First one for new tables, second one for new indexes and foreign keys. Than if I run generate-migrations-diff again another version is created although nothing was changed and following is inside:

  • 1st entry tries to drop a foreign key never been created and not existing in file
  • next entry tries to create a foreign key already existing
  • 3rd entry tries to create an existing index

After a long try and errorI found out that it's only happening with I18n plus Versionable behavior.

As I already have spent much time for a report please have also a look at: http://forum.diem-project.org/viewtopic.php?f=2&t=173&sid=5e0e3349c0e15a169bc9990a3104b3f6#p465

As I'm quite new to Doctrine and Symfony systems I cannot get further, but willing for more investigation if just one could give me a hint where to start.



 Comments   
Comment by Andrew Coulton [ 10/Oct/10 ]

I think this is because the versionable behaviour doesn't define a table name in the Doctrine_Template_Versionable class. As a result, if using model prefixes, the prefixes are not discarded from the table names when the behaviour model classes are built. This means that the tables have different names to what is expected, so they have different index keys, so the indexes are dropped and recreated as part of the migration.

I have committed unit tests and patch for this issue (which applies to Searchable also) to http://github.com/acoulton/doctrine1/tree/DC-880

Comment by Daniele Dore [ 19/Sep/11 ]

I experienced the same problem in the latest version 1.2.4, and the patch proposed by Andrew Coulton solves the problem.
Why the fix is not included in official release?





[DC-878] cannot access the version models using object->CLASSNAMEVersion in v1.2.3 Created: 30/Sep/10  Updated: 07/Oct/10

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Roland Huszti Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

PHP Version 5.2.10-2ubuntu6.5 ; Suhosin Patch 0.9.7 ; Ubuntu 9.10 2.6.31-22-generic x86_64 ; Apache/2.2.12 (Ubuntu) PHP/5.2.10-2ubuntu6.5 with Suhosin-Patch ; Doctrine 1.2.3



 Description   

In Doctrine 1.1 if I said

$vAaaaa = Doctrine::getTable('Aaaaa')->find(1);
print_r( $vAaaaa->AaaaaVersion ); // print_r( $vAaaaa->AaaaaVersion[0]->toArray() );

then I got the corresponding version model/array. Our application is using this nice behaviour at several places. But then the project got upgraded to Doctrine 1.2.3, and since then it dies saying

Unknown record property / related component "UserVersion" on "User" on line 55 of file /home/roland/www/cabcall/library/Doctrine/Doctrine/Record/Filter/Standard.php
#0 /home/roland/www/cabcall/library/Doctrine/Doctrine/Record.php(1395): Doctrine_Record_Filter_Standard->filterGet(Object(User), 'UserVersion')
#1 /home/roland/www/cabcall/library/Doctrine/Doctrine/Record.php(1350): Doctrine_Record->_get('UserVersion', true)
#2 /home/roland/www/cabcall/library/Doctrine/Doctrine/Access.php(72): Doctrine_Record->get('UserVersion')
#3 /home/roland/www/cabcall/application/controllers/TestController.php(12): Doctrine_Access->__get('UserVersion')
#4 /home/roland/www/cabcall/library/Zend/Controller/Action.php(513): TestController->indexAction()
#5 /home/roland/www/cabcall/library/Zend/Controller/Dispatcher/Standard.php(295): Zend_Controller_Action->dispatch('indexAction')
#6 /home/roland/www/cabcall/library/Zend/Controller/Front.php(954): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http))
#7 /home/roland/www/cabcall/library/Zend/Application/Bootstrap/Bootstrap.php(97): Zend_Controller_Front->dispatch()
#8 /home/roland/www/cabcall/library/Zend/Application.php(366): Zend_Application_Bootstrap_Bootstrap->run()
#9 /home/roland/www/cabcall/public/index.php(64): Zend_Application->run()
#10

{main}

Here is the exact example I tried before posting:

Aaaaa:
    tableName: aaaaa
    columns:
        something:
            type: integer(8)
            unsigned: false
            notnull: true
            default: 0
    actAs:
        Versionable:
            versionColumn: version
            className: %CLASS%Version
            auditLog: true
            deleteVersions: true


class AaaaaTable extends Doctrine_Table
{
    /**
     * Returns an instance of this class.
     *
     * @return object AaaaaTable
     */
    public static function getInstance()
    {
        return Doctrine_Core::getTable('Aaaaa');
    }
}


abstract class BaseAaaaa extends Doctrine_Record
{

    public function setTableDefinition()
    {
        $this->setTableName('aaaaa');
        $this->hasColumn('something', 'integer', 8, array(
             'type' => 'integer',
             'unsigned' => false,
             'notnull' => true,
             'default' => 0,
             'length' => '8',
             ));

        $this->option('type', 'INNODB');
        $this->option('collate', 'utf8_general_ci');
        $this->option('charset', 'utf8');
    }

    public function setUp()
    {
        parent::setUp();
        $versionable0 = new Doctrine_Template_Versionable(array(
             'versionColumn' => 'version',
             'className' => '%CLASS%Version',
             'auditLog' => true,
             'deleteVersions' => true
             ));

        $this->actAs($versionable0);
    }

}


class Aaaaa extends BaseAaaaa
{

}


/*
$vAaaaa = New Aaaaa;
$vAaaaa->something = 1;
$vAaaaa->save();
*/

$vAaaaa = Doctrine::getTable('Aaaaa')->find(1);

print_r( $vAaaaa->AaaaaVersion );



 Comments   
Comment by Roland Huszti [ 01/Oct/10 ]
<?php

class OSS_Resource_Doctrine extends Zend_Application_Resource_ResourceAbstract
{
    /**
     * Holds the Doctrine instance
     *
     * @var
     */
    protected $_doctrine;


    public function init()
    {
        // Return Doctrine so bootstrap will store it in the registry
        return $this->getDoctrine();
    }


    public function getDoctrine()
    {
        if ( null === $this->_doctrine )
        {
            // Get Doctrine configuration options from the application.ini file
            $doctrineConfig = $this->getOptions();

            require_once 'Doctrine.php';

            $loader = Zend_Loader_Autoloader::getInstance();
            $loader->pushAutoloader( array( 'Doctrine', 'autoload' ) );
            $loader->pushAutoloader( array( 'Doctrine', 'modelsAutoload' ) );

            $manager = Doctrine_Manager::getInstance();

            $manager->setAttribute( Doctrine::ATTR_MODEL_LOADING, Doctrine::MODEL_LOADING_CONSERVATIVE );
            $manager->setAttribute( Doctrine::ATTR_AUTOLOAD_TABLE_CLASSES, true );
            $manager->setAttribute( Doctrine::ATTR_USE_DQL_CALLBACKS, true );

            $manager->setCollate( 'utf8_unicode_ci' );
            $manager->setCharset( 'utf8' );

            Doctrine::loadModels( $doctrineConfig['models_path'] );

            $db_profiler = new Doctrine_Connection_Profiler();

            $manager->openConnection( $doctrineConfig['connection_string'] );
            $manager->connection()->setListener( $db_profiler );

            $manager->connection()->setCollate('utf8_unicode_ci');
            $manager->connection()->setCharset('utf8');

            Zend_Registry::set( 'db_profiler', $db_profiler );

            $this->_doctrine = $manager;
        }

        return $this->_doctrine;
    }

    /**
     * Set the classes $_doctrine member
     *
     * @param $doctrine The object to set
     */
    public function setDoctrine( $doctrine )
    {
        $this->_doctrine = $doctrine;
    }

}

Comment by Roland Huszti [ 07/Oct/10 ]

To have this very nice and useful feature, I had to add these lines by hand to my audited table's models. Not to the base models, those are overwritten every time you migrate to a new version! Also, in the YAML file you can set the classname to whatever you want, so you need to use the same name in the model, too!

MODEL

class XYZ extends BaseXYZ

{


    public function setUp()

    {

        parent::setUp();

        $this->hasMany('XYZVersion', array( 'local' => 'id', 'foreign' => 'id'));

        // you may get the classname from the model, so then you only need to copy-paste the exact same piece of setUp() code into every model you want to
    }


    . . .

YAML

    actAs:
        Versionable:
            versionColumn: version
            className: %CLASS%Version    # this is the default, User -> UserVersion , Address -> AddressVersion, etc.
            auditLog: true
            deleteVersions: true




[DC-858] Custom Behaviors/Templates cause autoloader errors Created: 04/Sep/10  Updated: 04/Sep/10

Status: Open
Project: Doctrine 1
Component/s: Behaviors, Schema Files
Affects Version/s: 1.2.1, 1.2.2, 1.2.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: apric Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Windows Vista/7
PHP 5.3.1 - 5.3.3
Zend autoloader
not occuring under Ubuntu 10.05 / MacOSX



 Description   

When emitting Behaviors from schema files (YAML in our case),
Doctrine expects a shortened class name of the behavior (e.g. 'Timestampable') instead of the full class name:
The string 'Doctrine_Template_' is automatically prepended and a check (class_exists()) is made.

This is leading to possible autoloader errors (in our case: Zend autoloader does not find our custom behavior):

YAML:

{{
Person:
actAs: [SoftDelete, My_Doctrine_Template_CustomBehavior]
...
}}

'SoftDelete' is the short class name of 'Doctrine_Template_SoftDelete'.
'My_Doctrine_Template_CustomBehavior' is the full class name and shall not be prefixed with 'Doctrine_Template_'.

The corresponding section responsible for this bug:

File: Doctrine/Import/Builder.php
Lines: 702-704, function emitAssign()

{{
if (class_exists("Doctrine_Template_$name", true))

{ $classname = "Doctrine_Template_$name"; } }}

There is no test whether a full class name is given as $name, so there is no way to add custom behaviors to records without the autoloader checking for a non-existing class and spilling errors/notices.
With the above YAML schema file it would test for class_exists('Doctrine_Template_My_Doctrine_Template_CustomBehavior'), which is obviously not existing.

a quick fix could look like this:

{{
if (strpos($name, '_') === false // is this a shortened name of an original Doctrine behaviour class?
&& class_exists("Doctrine_Template_$name", true)) { $classname = "Doctrine_Template_$name";}}}

Another alternative (but breaking compatability with existing schema files) would be to always use full class names instead of fancy short names.

Interestingly enough, this error is only occuring with Zend autoloader on Windows systems, but can be easily avoided with the fix like suggested above.



 Comments   
Comment by Jonathan H. Wage [ 04/Sep/10 ]

I believe this is because the Zend autoloader does not fail silently by default. I think it can be configured to check if the file exists and not throw any errors.





[DC-825] Versionable does not work with column alias on primary keys [+patch] Created: 13/Aug/10  Updated: 17/Apr/14

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.2
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Enrico Stahn Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None

Attachments: Text File 0001-TestCase-for-issue-DC-825.patch     Text File 0002-DC-825-fix-generation-of-the-versionable-table.patch     Text File 0003-DC-825-fix-generation-of-model-classes-with-column-a.patch    

 Description   

Using the Versionable behavior on a model which has a column with an alias and which is also primary causes the generation of a wrong version of the versionable table.

Example:

 
ModelFoo:
  model_id as id
  username
  password

Generates tables:
model_foo (model_id, username, password, version)
model_foo_version (id, model_id, userrname, password, version)

It should be:
model_foo (model_id, username, password, version)
model_foo_version (model_id, userrname, password, version)



 Comments   
Comment by Enrico Stahn [ 13/Aug/10 ]

TestCase and Fix
http://github.com/estahn/doctrine1/tree/DC-825

Comment by Enrico Stahn [ 18/Aug/10 ]

The supplied patches are not up-to-date. Pls use http://github.com/estahn/doctrine1/tree/DC-825





[DC-801] Multiple template implementation (setImpl) Created: 28/Jul/10  Updated: 28/Apr/12

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.2
Fix Version/s: None

Type: Bug Priority: Major
Reporter: B. Ariston Darmayuda Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None


 Description   

I feel curios when looking setImpl code on Doctrine. It set like this:

public function setImpl($template, $class)
{
    $this->_impl[$template] = $class;

    return $this;
}

I've made a template:

class PersonTemplate extends Doctrine_Template
{
    public function setTableDefinition() 
    {
        //... Person fields (e.g. name, address, etc.)
    }
}

Now I create 2 class that implement PersonTemplate

class Student extends Doctrine_Record
{
    public function setUp()
    {
        $this->actAs('PersonTemplate');
    }
}
class Teacher extends Doctrine_Record
{
    public function setUp()
    {
        $this->actAs('PersonTemplate');
    }
}

Then I set implementation on Doctrine_Manager:

Doctrine_Manager::getInstance()->setImpl('PersonTemplate', 'Student')->setImpl('PersonTemplate', 'Teacher');

Now isn't it only Teacher record recognized as implementation of PersonTemplate ( when we see from this code: $this->_impl[$template] = $class; )

So how we can implement a template into seperated different doctrine record?



 Comments   
Comment by Richard C. Hidalgo [ 28/Apr/12 ]

As the doc says "Tip The implementations for the templates can be set at manager, connection and even at the table level." it is supposed one can do:

Doctrine_Manager::getInstance()->getTable('Student')->setImpl('PersonTemplate', 'Student');
Doctrine_Manager::getInstance()->getTable('Teacher')->setImpl('PersonTemplate', 'Teacher');

but for me it throws an exception:

"Couldn't find concrete implementation for template PersonTemplate"

thx





[DC-795] Can't mix Soft and Hard deletes. Fix with patch provided. Created: 21/Jul/10  Updated: 21/Jul/10

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.2
Fix Version/s: 1.2.2

Type: Bug Priority: Major
Reporter: John Wards Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None
Environment:

Mac



 Description   

I reported this bug on the symfony site, but after investigation i have found that it is actually a doctrine SoftDelete issue. http://trac.symfony-project.org/ticket/8898

I have a sandbox replicating the problem here:
http://dl.dropbox.com/u/8354765/sf_sandbox.zip

Run the test:
./symfony test:unit Contact

The issue is I want to hard delete my M-M link table and soft delete the parents. This fails. I believe it is to do with the fact that the relations to the parent are marked as Doctrine_Record::STATE_TCLEAN which when the SoftDelete calls save on the parent object this flag trys to reinsert the relations that it has deleted. Things go very wrong at this point and the connection is rolled back.

The fix I have is the following, not sure what this would do to other things or not as I am not overly familiar with Doctrine internals...

Index: Doctrine/Template/Listener/SoftDelete.php
===================================================================
--- Doctrine/Template/Listener/SoftDelete.php	(revision 12962)
+++ Doctrine/Template/Listener/SoftDelete.php	(working copy)
@@ -95,6 +95,7 @@
     public function postDelete(Doctrine_Event $event)
     {
         if ( ! $this->_options['hardDelete']) {
+            $event->getInvoker()->clearRelated();
             $event->getInvoker()->save();
         }
     }

This works even if the relations have been marked as SoftDelete.



 Comments   
Comment by John Wards [ 21/Jul/10 ]

Formatting

Comment by Jonathan H. Wage [ 21/Jul/10 ]

Does this patch pass the test suite?

Comment by John Wards [ 21/Jul/10 ]

I have run the test suite and got the same 8 failures with and without the patch.

These are the failing tests:
Doctrine_Cache_Apc_TestCase
Doctrine_Cache_Abstract_TestCase
Doctrine_Ticket_1783_TestCase

Anything obvious I need to do to get these working, other than enabling apc...

Comment by John Wards [ 21/Jul/10 ]

It seems to be passing all the tests that have SoftDelete in them however, so I would say that it is working as expected.





[DC-758] CascadeDelete not work properly on Versionable and on the AuditLog Created: 21/Jun/10  Updated: 17/Apr/14

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Jaime Suez Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Mac OS X Snow Leopard, LAMP and Macports



 Description   
 
Schema:

Personal:
  actAs:
    Versionable:
      deleteVersions: false
      cascadeDelete: false

When you use this configuration and try to delete one of the record linked with the versionned one, an exception about foreign key is raised because the id of the versioned record has a foreign key to the id of the record.

It's necessary to could work with cascadeDelete: false... because like that it's needed to use softDelete and the deleted record's will be stored on the version table, but with the advantage that you don't have the performance problem of soft delete behaviour.

Thanks!






[DC-648] Behavior geographical generates latitude DOUBLE(18, 2), longitude DOUBLE(18, 2) - it's not exact Created: 24/Apr/10  Updated: 19/Jan/11

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.2
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Malcolm Hall Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None
Environment:

Doctrine 1.2.2


Attachments: File patch.diff    

 Description   

The problem was already described by another person at http://www.doctrine-project.org/jira/browse/DC-385
and was fixed but now is broken again.

When using the Geographical behaviour in a YML schema the latitude is stored in Mysql as a Double(18,2) instead of a Double as it was in the previous versions. It appears that all doubles in yml are defaulting to (18,2).



 Comments   
Comment by Malcolm Hall [ 24/Apr/10 ]

The problem lies in DataDict/Mysql.php

Previously it was:

case 'double':
return 'DOUBLE';

now it's:

case 'double':
$length = !empty($field['length']) ? $field['length'] : 18;
$scale = !empty($field['scale']) ? $field['scale'] : $this->conn->getAttribute(Doctrine_Core::ATTR_DECIMAL_PLACES);
return 'DOUBLE('.$length.', '.$scale.')';

Perhaps this could be improved so that if there is no length specified it returns just double with no length or scale instead of defaulting to 18, ATTR_DECIMAL_PLACES? I expect that most people that use the double type in yaml wouldn't want only 2 decimals.

Comment by Jonathan H. Wage [ 08/Jun/10 ]

Can you provide a patch that fixes the situation for you? we'll see if that has any breakage of current tests.

Comment by khim tieu-philippe [ 26/Jul/10 ]

I have the same trouble, and I fix it by specified directly the precision of the double into Doctrine_Template_Geographical class.

'type' => 'double(18,8)',

Comment by Janusz Slota [ 08/Nov/10 ]

You can fix it with:
Geographical:
  latitude:
    type: float(18,8)
  longitude:
    type: float(18,8)

instead of:
Geographical: ~

Comment by khim tieu-philippe [ 19/Jan/11 ]

diff on Template/Geographical.php

Hope that could help





[DC-630] Add Undelete functionality to SoftDelete behaviour Created: 15/Apr/10  Updated: 15/Apr/10

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: Harry Birrell Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Can an undelete function be added to the Doctrine ORM which will reset deleted_at fields to null and conform to cascade rules (just as the original delete did)?






[DC-553] issue when changing the connection inside Doctrine_Query::preQuery() on a model using a behavior Created: 08/Mar/10  Updated: 19/Jul/10

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: None
Fix Version/s: 1.2.1

Type: Bug Priority: Major
Reporter: Lukas Kahwe Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None


 Description   

We were following:
http://www.doctrine-project.org/documentation/cookbook/1_1/en/master-and-slave-connections

class MyQuery extends Doctrine_Query
{
// Since php doesn't support late static binding in 5.2 we need to override
// this method to instantiate a new MyQuery instead of Doctrine_Query
public static function create($conn = null)

{ return new MyQuery($conn); }

public function preQuery()
{
// If this is a select query then set connection to one of the slaves
if ($this->getType() == Doctrine_Query::SELECT)

{ $this->_conn = Doctrine_Manager::getInstance()->getConnection('slave_' . rand(1, 4)); // All other queries are writes so they need to go to the master }

else

{ $this->_conn = Doctrine_Manager::getInstance()->getConnection('master'); }

}
}

However we are actually forcing all queries after the first access to the master to be run against the master (including selects). Note the example should probably be changed to use setConnection(). However even when using setConnection() it seems like changing the connection can cause issues when running a select on a model with a behavior (in our case we were using i18n). Therefore we believe there is some issue that is caused through the event system, because otherwise queries work just fine even when changing the connection as per the above described code.

We managed to fix things, by not setting the connection explicitly and instead simply using setCurrentConnection('master'), so the bug does not affect us anymore. However this seems to indicate some issues deep inside the event-behavior-template code.



 Comments   
Comment by Jordi Boggiano [ 08/Mar/10 ]

In case the above post is confusing, note that doing $this->_conn = masterconn worked fine for the INSERT, it just broke when doing a subsequent SELECT of a translateable (I18n behavior) model and its Translation table with the following exception:

Exception (Exception): Unknown relation alias Translation (#0)</h1>thrown in file /Library/WebServer/Documents/liip/infocube/ext/db-doctrine/lib/Doctrine/Relation/Parser.php at line 237
backtrace:
#1 Doctrine_Relation_Parser->getRelation called in file /Library/WebServer/Documents/liip/infocube/ext/db-doctrine/lib/Doctrine/Relation/Parser.php at line 235

Comment by Jonathan H. Wage [ 15/Mar/10 ]

It is hard to understand the issue, can you provide a test case?

Comment by Lukas Kahwe [ 15/Mar/10 ]

We already spend well over 2 hours together on project time to find a work around as noted above and I must admit now our motivation is not so big to dig deeper, especially since we didn't find the cause in this time and have the feeling its pretty impossible to fix without huge risks.

Essentially I think all you need to do to reproduce the issue is use the cookbook code and issue some write query and afterwards do a select on a model that has the translatable behavior. It then gave us the above Exception.

Our code worked slightly different since we did not use a random slave, instead we always used a local slave by default, but the first write and any queries thereafter would get send to the master. The code is public and the diff's show what we had to change to get things working. Note that the slave "localhost" connection was the default connection:
http://fisheye.liip.ch/browse/PUB/okapi2/ext/db-doctrine/trunk/inc/DQ.php?r1=13118&r2=
http://fisheye.liip.ch/browse/PUB/okapi2/ext/db-doctrine/trunk/inc/DR.php?r1=13118&r2=

Comment by Lukas Kahwe [ 17/Jun/10 ]

we thought we had the issue fixed but ran into another issue today. we then noticed that the issue goes away if we just copy the $tables property from the old connection to the new connection. there is a getTables() method, but there is only a addTable() method, would be nice to have a addTables() method that is faster. or maybe a switchFrom() method that accepts the old connection and does whatever it needs to.

And again it would be nice to update the cookbook entry.
Here are our updated Doctrine_Query and Doctrine_Record classes:
http://fisheye.liip.ch/browse/PUB/okapi2/ext/db-doctrine/trunk/inc/DQ.php
http://fisheye.liip.ch/browse/PUB/okapi2/ext/db-doctrine/trunk/inc/DR.php

Comment by Jordi Boggiano [ 19/Jul/10 ]

We just had another funny debugging session related to this. It turns out that the Table objects have a relation to the connection, and if you query a new model that wasn't initialized yet using ->from(), it works because it just gets the current connection passed. However, if you query a new model within a JOIN, then it apparently takes the connection from the related model you're joining from. In our case, the related model was already initialized but had an instance of the old (slave) connection, and so the new model was initialized using the wrong connection, and then the DQL parser exploded trying to resolve relations.

Long story short, adding $table->setConnection($conn); to all tables while switching to the master connection resolved it. The code is updated and you can still view it at the above URLs, or straight in the SVN repo at http://svn.liip.ch/repos/public/okapi2/ext/db-doctrine/trunk/inc/DQ.php





[DC-485] Limit gets lost when doing self join Created: 08/Feb/10  Updated: 08/Feb/10

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.1
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Pascal Helfenstein Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None
Environment:

os x, snow leopard,


Attachments: File schema.yml    

 Description   

hi doctrine team,
today I encountered a very weird problem when I tried to do a selfjoin on a table. the goal was to list all people that have the same addresses but limit the result to 5

the problem was, that the doctrine split it into 2 querys and first selected the correct address ids with the Limit 5. but in the second query the limit is lost. which gives me more than 5 results if a few people have the same address

the DQL looks like this

$q = DQ::create()
->from('address a INNER JOIN a.shared b ON a.city = b.city AND a.street = b.street')
->innerJoin('b.entity e')
->where('a.entity_id = ? AND a.is_active = ?', array($id, $is_active))
->limit(5)
->offset(0);

SQL looks like this:

SELECT * FROM address a
INNER JOIN address a2 ON ((a.city = a2.city AND a.street = a2.street))
INNER JOIN entity e ON a2.entity_id = e.id
WHERE a.id IN ('5689677') AND (a.entity_id = ? AND a.is_active = ?)

Problem: Limit 5 is gone

expected was something like this:

SELECT *
FROM address a
INNER JOIN address b ON a.city = b.city AND a.street = b.street
INNER JOIN entity e ON b.entity_id = e.id
where a.entity_id = 104294414
limit 5

my temporary solution:

$q = new Doctrine_RawSql();
$q->select('

{b.*}

,

{e.*}

,

{p.*}

');
$q->from('address a INNER JOIN address b ON a.city = b.city AND a.street = b.street
INNER JOIN entity e ON b.entity_id = e.id
INNER JOIN person p ON e.id = p.entity_id');
$q->where('a.entity_id = ? AND a.is_active = ?', array($id, $isActive));
$q->addComponent('a', 'address a');
$q->addComponent('b', 'a.shared b');
$q->addComponent('e', 'b.entity e');
$q->addComponent('p', 'e.person p');
$q->limit($limit);
$q->offset($offset);

my schema.yml is attached, do you need anything else?






[DC-430] I18n and inheritance Created: 15/Jan/10  Updated: 15/Jan/10

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.0
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Julien Wadin Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Doctrine 1.2 with Symfony 1.4



 Description   

When using i18n with inheritance, the localizables fields are overrinden by the second deriving class.
So, the translation table is containing only fields from one of the two descending classes.

The yml is below:

User:
columns:
email: string(255)
...

Employer:
inheritance:
extends: User
type: column_aggregation
actAs:
I18n:
fields: [description, company]
columns:
company: string(255)
description: text

Recruiter:
actAs:
I18n:
fields: [position]
inheritance:
extends: User
type: column_aggregation
columns:
position: string(255)






[DC-362] Doctrine fails to create correct table structure if model is named "User" Created: 16/Dec/09  Updated: 08/Jan/10

Status: Open
Project: Doctrine 1
Component/s: Behaviors, Query, Relations
Affects Version/s: 1.2.0-RC1
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Michael Henriksen Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None
Environment:

Mac OS X 10.6.2 (10C540) (Snow Leopard) with MAMP 1.8 bundle:
PHP Version: 5.2.10,
MySQL Version: 5.1.37



 Description   

When building models and database structure from YAML schema, Doctrine ignores the behaviors and relations on models if it is named "User":

...

User:  
  actAs:
    Timestampable:
    Sluggable:
      unique: true
      fields: username
      canUpdate: true
  columns:
    id:
      type: integer(4)
      primary: true
      autoincrement: true
    company_id
      type: integer(4)
    timezone_id:
      type: integer(1)
    role_id:
      type: integer(1)
    email:
      type: string(255)
    username:
      type: string(255)
      unique: true
    password:
      type: string(40)
    firstname:
      type: string(255)
    lastname:
      type: string(255)
    last_login:
      type: datetime
  relations:
    Company:
      local: company_id
      foreign: id
    Timezone:
      local: timezone_id
      foreign: id
    Role:
      local: role_id
      foreign: id

...

This creates the following table structure:

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `company_id` int(11) DEFAULT NULL,
  `timezone_id` tinyint(4) DEFAULT NULL,
  `role_id` tinyint(4) DEFAULT NULL,
  `email` varchar(255) DEFAULT NULL,
  `username` varchar(255) DEFAULT NULL,
  `password` varchar(40) DEFAULT NULL,
  `firstname` varchar(255) DEFAULT NULL,
  `lastname` varchar(255) DEFAULT NULL,
  `last_login` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

The table structure is both missing foreign key constraints to Company, Timezone and Role. It is also missing columns updated_at and created_at for Timestampable behavior. The slug column for Sluggable behavior is missing, as well.

When looking at the BaseUser::setUp() method it looks as it is supposed to:

class BaseUser extends Doctrine_Record
{

    ....

    public function setUp()
    {
        parent::setUp();
        $this->hasOne('Company', array(
             'local' => 'company_id',
             'foreign' => 'id'));

        $this->hasOne('Timezone', array(
             'local' => 'timezone_id',
             'foreign' => 'id'));

        $this->hasOne('Role', array(
             'local' => 'role_id',
             'foreign' => 'id'));

        $timestampable0 = new Doctrine_Template_Timestampable();
        $sluggable0 = new Doctrine_Template_Sluggable(array(
             'unique' => true,
             'fields' => 'username',
             'canUpdate' => true,
        ));
        $this->actAs($timestampable0);
        $this->actAs($sluggable0);
    }

    ....

}

So the only area where it goes wrong, is when generating the queries for creating the model tables. I don't know if the same problem appears with other model names, but it doesn't like models named "User".

If I rename the model to "Person" and rebuild, it all works perfectly as it should.



 Comments   
Comment by Michael Henriksen [ 16/Dec/09 ]

Forgot to mention, that it works perfectly when renaming model to something else than "User"

Comment by Sander [ 08/Jan/10 ]

Have the same problem in 1.2.1 at PostgreSQL 8.4





[DC-325] doctrine pager class with sql server stored procedure Created: 04/Dec/09  Updated: 04/Dec/09

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.0
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: khurram Ali Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None
Environment:

php 5.3.0 sql server 2000 symfony 1.2.9



 Description   

i am using doctrine pager class for pagination in symfony but not able to find any help how i can i use it

i am using sql server stored procedures for fetching databasae .

Thnaks

Khurram






[DC-1047] hardDelete not resetting flag if exception is thrown Created: 06/Jan/12  Updated: 06/Jan/12

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: Lone Wolf Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 0
Labels: None

Attachments: Text File softdelete_exception.patch    

 Description   

To be honest I don't know wich version I have but I believe it to be 1.2.3

The problem is pretty simple, I was trying to do a hardDelete and if it fails I would do a softDelete.
Example

try {
    $record->hardDelete();
}
catch (Exception $e) {
    if ($e instanceof Doctrine_Connection_Mysql_Exception && $e->getPortableCode() == Doctrine_Core::ERR_CONSTRAINT) {
        try {
            $record->delete();
        }
        catch (Exception $e1) {
            throw $e1;
        }
    }
    else {
        throw $e;
    }
}

But when the first exception is thrown from hardDelete() in Doctrine_Template_SoftDelete(line 84) the listener flag for hardDelete is not set to false, so if I try to do the delete, it will still behave as if it was a hardDelete.

The solution would be catch the exception, reset the flag and rethrow it.
Patch attached

Hope this info is enough.






[DC-746] Sluggable canUpdate overridden after subsequent updates Created: 17/Jun/10  Updated: 17/Apr/14

Status: Open
Project: Doctrine 1
Component/s: Behaviors
Affects Version/s: 1.2.0, 1.2.1, 1.2.2, 1.2.3
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: Adam Benson Assignee: Jonathan H. Wage
Resolution: Unresolved Votes: 1
Labels: None
Environment:

WAMP stack - PHP 5.3



 Description   

When allowing the user to manually change a slug using 'canUpdate' the slug reverts back to it's default generated value upon subsequent saves. Pre-Update on the Sluggable Listener Template seems to incorrectly decide to regenerate the default value.

Example:

$this->actAs('Sluggable', array('unique'=>true, 'fields'=>array('title'), 'canUpdate'=>true));
$record->description = "An example Item";
$record->title = "Example Title";
$record->save();

echo $record->slug; //"example-title" (Correct)

$record->description = "An example Item";
$record->title = "Example Title";
$record->slug = "custom-slug";
$record->save();

echo $record->slug; //"custom-slug" (Correct - First Save)

$record->description = "An example Item";
$record->title = "Example Title";
$record->slug = "custom-slug";
$record->save();
echo $record->slug; //"example-title" (Incorrect - Subsequent Save. Has regenerated it's default slug and lost the user defined one - even though we have passed the users custom one to the object prior to saving it.).


 Comments   
Comment by Christian Seaman [ 05/Oct/10 ]

As far as I can see this is a problem with the logic in Sluggable::preUpdate() , I recently posted a comment about this here:
http://groups.google.com/group/doctrine-user/browse_thread/thread/d40c6ac733738d4a

In short, I think that the code should be changed from:

Sluggable.php
    public function preUpdate(Doctrine_Event $event)
    {
        if (false !== $this->_options['unique']) {
            $record = $event->getInvoker();
            $name = $record->getTable()->getFieldName($this->_options['name']);

            if ( ! $record->$name || (
                false !== $this->_options['canUpdate'] &&
                ! array_key_exists($name, $record->getModified())
            )) {
                $record->$name = $this->buildSlugFromFields($record);
            } else if ( ! empty($record->$name) &&
                false !== $this->_options['canUpdate'] &&
                array_key_exists($name, $record->getModified()
            )) {
                $record->$name = $this->buildSlugFromSlugField($record);
            }
        }
    }

To this (i.e. remove the canUpdate conditions from the first inner if):

Sluggable.php (modified)
    public function preUpdate(Doctrine_Event $event)
    {
        if (false !== $this->_options['unique']) {
            $record = $event->getInvoker();
            $name = $record->getTable()->getFieldName($this->_options['name']);

            if ( ! $record->$name) { // i.e. remove the other conditions - you should only build the slug from other fields if it's empty
                $record->$name = $this->buildSlugFromFields($record);
            // possibly add an "else if !canUpdate then make sure the old value is preserved" here
            } else if ( ! empty($record->$name) &&
                false !== $this->_options['canUpdate'] &&
                array_key_exists($name, $record->getModified()
            )) {
                $record->$name = $this->buildSlugFromSlugField($record);
            }
        }
    }

I have modified my local version of the Doctrine code to use this modification and it seems to (a) not have the problem you reported above and (b) generally work ok. However, I have not run the test suite against it.

C

Comment by Adam Benson [ 19/Nov/10 ]

Updated affected versions

Comment by Adam Benson [ 19/Nov/10 ]

Thanks for the update Christian, perhaps you could share your fix as a patch?

Comment by Jean-Sébastien GERARD [ 21/Jan/11 ]

Hi, I'm working on a multilingue web portal with Symfony 1.4 and Doctrine 1.2.3, and man, your fix saves my life
I use Sluggable slaved by i18n and without your fix Sluggable simply does not do the job, instead it messes up all slugs when updating, eventually you can't retrieve object anymore based on it. I would not set it as only minor bug ?
thanks, anyway.





Generated at Sat Dec 20 16:42:32 UTC 2014 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.