doctrine-extensions / doctrineextensions Goto Github PK
View Code? Open in Web Editor NEWDoctrine2 behavioral extensions, Translatable, Sluggable, Tree-NestedSet, Timestampable, Loggable, Sortable
License: MIT License
Doctrine2 behavioral extensions, Translatable, Sluggable, Tree-NestedSet, Timestampable, Loggable, Sortable
License: MIT License
edit: I'm using the Doctrine 2.0.x branch.
In Beta 2, Symfony updated the filename and location of the YAML mappings:
The Doctrine metadata files has moved from
Resources/config/doctrine/metadata/orm/
to Resources/config/doctrine
,
the extension from .dcm.yml
to .orm.yml
, and the file name has been
changed to the short class name.
Before:
Resources/config/doctrine/metadata/orm/Bundle.Entity.dcm.xml
Resources/config/doctrine/metadata/orm/Bundle.Entity.dcm.yml
After:
Resources/config/doctrine/Entity.orm.xml
Resources/config/doctrine/Entity.orm.yml
I get the following error when trying to generate entities:
`[Gedmo\Exception\UnexpectedValueException]
No mapping file found named 'HBK.TestBundle.Entity.Activity.dcm.yml' for class 'HBK\TestBundle\Entity\Activity'.
It seems like the extension of dcm.yml is hardcoded into these extensions. Is this a bug or something I'm doing wrong?
Currently, "loggable+versioned" behavior must be enabled for class before you persist your document for the first time.
Imagine there is a mongodb collection with existing document, defined by class "A". There are two issues, when trying to apply loggable behavior:
I've been using Tree for a while and wanted to plug sluggable into the same object, however I can't because my current "slug" looks like, "child-parent-parentsparent".. etc, etc.
I think a good feature would be to have the ability to have Sluggable go inline with Tree.
A real time example would be:
Entity Location:
City Los Angeles belongs to state California (ca) which belongs to country United States (us). A sluggable extension would be:
los-angeles-ca-us.
Perhaps an easy way to go about this would be to have (sudo code):
/**
/**
@gedmo\SlugSetter
*/
private function setSlug()
{
$preSlug = $this->getName();
foreach ($this->getParents() as $parent) {
$preSlug .= ' ' . $parent->getName();
}
return $preSlug;
}
.... But I'm not sure ???
Hi,
i'm getting the above exception when persisting an Entity which has the following annotations:
/**
* @orm:Entity
*/
class Server {
/**
* @gedmo:Sluggable
* @orm:Column(type="string", length="255")
* @assert:NotBlank()
*/
protected $name;
/**
* @gedmo:Slug
* @orm:Column(type="string", length=128, unique=true)
*/
protected $slug;
public function getSlug() {
return $this->slug;
}
}
When saving it like this, i get the exception:
$server = new Server();
$server->setName('test');
$server->setIpAdress('foobar');
$em->persist($server);
$em->flush();
Has anyone a hint how to solve/debug this?
I'm on doctrine 2.0.x.
Hi,
Using extensions from master branch (updated a week ago or so) and enabling APC Cache I get the following exception, which is not thrown if I disable it:
[Semantical Error] line 0, col 103 near 'descendant WHERE': Error: Class Entity\EntityClosure has no association named descendant
Am I doing something wrong here? or maybe I'm missing something?
Thanks in advance.
Hello. I don't know: is this bug of extension or doctrine?
What I have:
DoctrineExtensions 56e4f69
Doctrine doctrine@doctrine2/93521217a6a35347dee82d6ee0bf665ecf314d6d
Symfony beta 3
Entities
<?php
namespace Foo\Bundle\FooTerritorialBundle\Entity;
use Doctrine\ORM\Mapping as Orm;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* @Orm\Entity(repositoryClass="Gedmo\Tree\Entity\Repository\ClosureTreeRepository")
* @Orm\Table(name = "territorial_area")
* @Orm\InheritanceType("JOINED")
* @Orm\DiscriminatorColumn(name="kind", type="string")
* @Orm\DiscriminatorMap({"world" = "World", "country" = "Country", "federal_district" = "FederalDistrict", "region" = "Region", "city" = "City", "administrative_district" = "AdministrativeDistrict", "district" = "District"})
*
* @Gedmo\Tree(type="closure")
* @Gedmo\TreeClosure(class="Foo\Bundle\FooTerritorialBundle\Entity\AbstractAreaClosure")
*/
abstract class AbstractArea
{
/**
* @Orm\Id
* @Orm\GeneratedValue
* @Orm\Column(type="integer")
*/
protected $id;
/** @Orm\Column(type="string") */
protected $title;
/**
* @Gedmo\TreeParent
* @Orm\JoinColumn(name="parent_id", referencedColumnName="id", onDelete="CASCADE")
* @Orm\ManyToOne(targetEntity="AbstractArea", inversedBy="children", cascade={"persist"})
*/
protected $parent;
public function getId()
{
return $this->id;
}
public function setTitle($title)
{
$this->title = $title;
return $this;
}
public function getTitle()
{
return $this->title;
}
public function setParent(AbstractArea $parent = null)
{
$this->parent = $parent;
return $this;
}
public function getParent()
{
return $this->parent;
}
public function addClosure(AbstractAreaClosure $closure)
{
$this->closures[] = $closure;
return $this;
}
}
// ----------------------------------------------------------------------------
namespace Foo\Bundle\FooTerritorialBundle\Entity;
use Doctrine\ORM\Mapping as Orm;
/**
* @Orm\Entity
* @Orm\Table(name = "territorial_world")
*/
class World extends AbstractArea
{
}
// ----------------------------------------------------------------------------
namespace Foo\Bundle\FooTerritorialBundle\Entity;
use Doctrine\ORM\Mapping as Orm;
/**
* @Orm\Entity
* @Orm\Table(name = "territorial_country")
*/
class Country extends AbstractArea
{
}
// ----------------------------------------------------------------------------
namespace Foo\Bundle\FooTerritorialBundle\Entity;
use Doctrine\ORM\Mapping as Orm;
/**
* @Orm\Entity
* @Orm\Table(name = "territorial_city")
*/
class City extends AbstractArea
{
}
Controller
<?php
// populate
$world = new Entity\World();
$world->setTitle("World");
$countryUkraine = new Entity\Country();
$countryUkraine->setTitle("Ukraine");
$countryRussia = new Entity\Country();
$countryRussia->setTitle("Russia");
$cityDnepropetrovsk = new Entity\City();
$cityDnepropetrovsk->setTitle("Dnepropetrovsk");
$cityDnepropetrovsk->setParent($countryUkraine);
$countryRussia->setParent($world);
$countryUkraine->setParent($world);
$em->persist($world);
$em->persist($countryUkraine);
$em->persist($countryRussia);
$em->persist($cityDnepropetrovsk);
$em->flush();
// find
$rep = $em->getRepository("FooTerritorialBundle:AbstractArea");
$country = $em->find("FooTerritorialBundle:Country", 2);
var_dump($country);
exit;
And got the notice and fatal error:
Notice: Undefined index: children in Z:\home\dev\Foo\code\vendors\Doctrine\Orm\lib\Doctrine\ORM\Persisters\BasicEntityPersister.php on line 628
Fatal error: Call to a member function setValue() on a non-object in Z:\home\dev\Foo\code\vendors\Doctrine\Orm\lib\Doctrine\ORM\Persisters\BasicEntityPersister.php on line 628
Is there some possibility to force load entity with certain locale
despide of global locale settings in listener ? Or switch already
loaded entity to another locale ?
I'm creating backend application where I need to be little bit more in
control of languages and entities as it is in frontend where it is
plain easy (set language to listener by url route and doctrine and
translatable handles the rest).
Your code as you suggested in email seems not working:
$entity->setLocale('de_DE'); //or whatever
$em->refresh($entity);
My entity looks like this:
class PersonCategory implements Translatable {
/**
* @id
* @column(type="integer")
* @generatedValue(strategy="SEQUENCE")
*/
private $id;
/**
* @gedmo:Translatable
* @column(type="string", length=50, nullable=false)
*/
private $name;
/**
* @oneToMany(targetEntity="Person", mappedBy="category")
*/
private $persons;
/**
* @gedmo:Locale
*/
private $locale;
function __construct() {
$this->persons = new \Doctrine\Common\Collections\ArrayCollection();
}
public function getId() {
return $this->id;
}
public function setName($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
public function getPersons() {
return $this->persons;
}
public function addPerson(Person $person) {
$this->getPersons()->add($person);
}
public function setLocale($locale) {
$this->locale = $locale;
}
}
Fatal error: Uncaught exception 'Doctrine\Common\Annotations\AnnotationException' with message '[Semantical Error] Annotation class "Gedmo\Timestampable\Mapping\Sluggable" does not exist.' in /Library/WebServer/fer/vendor/doctrine-common/lib/Doctrine/Common/Annotations/AnnotationException.php on line 52 Doctrine\Common\Annotations\AnnotationException: [Semantical Error] Annotation class "Gedmo\Timestampable\Mapping\Sluggable" does not exist. in /Library/WebServer/fer/vendor/doctrine-common/lib/Doctrine/Common/Annotations/AnnotationException.php on line 52
Hello,
i copied the category tree example from your blog. But i can't get it running.
I't's throwing the Exception:
TreeNodeRepository: this repository cannot be used on Entities\Category without Tree metadata. The exception is triggered by getConfiguration().
Are there changes between the current tree functionality and the descriptions on your blog?
In TreeNodeRepository class you provide several methods to fetch childs and count them.
There is also getLeafs() and getPath(). What do you mean by getPath()? Does it fetch the whole Tree? If yes, i would suggest renaming the method to getTree().
Best regards, Jens
Updated from the 2/28 commit on the repo to the 3/5 commit and am receiving the following error. I'm downgrading until the issue is resolved.
Catchable fatal error: Argument 1 passed to Gedmo\Mapping\MappedEventSubscriber::loadMetadataForObjectClass() must be an instance of Doctrine\Common\Persistence\ObjectManager, instance of Doctrine\ORM\EntityManager given, called in D:\Workspace\vladmin\vendor\vllib\library\DoctrineExtensions\Gedmo\Sluggable\AbstractSluggableListener.php on line 61 and defined in D:\Workspace\vladmin\vendor\vllib\library\DoctrineExtensions\Gedmo\Mapping\MappedEventSubscriber.php on line 91
I have a problem using tree "behaviour" with class table inheritance: some left and right value are going to be wrong after inserting a new record.
I tried to insert a new user ([email protected]) below Administrator group (so I called $user->setParent($administratorGroup)). I don't want to allow to insert a role below a user, so parent entity could be only a UserGroup object.
The initial, hand corrected database:
http://img690.imageshack.us/img690/1028/roletablebefore.png
After insertion:
http://img23.imageshack.us/img23/9790/roletableafter.png
I'm using the folowing entities:
Role:
<?php
namespace entities;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Abstract Role class to handle roles (users, groups hierarchy)
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link $Link$
* @since 2.0
* @version $Revision$
* @author Szurovecz János <[email protected]>
*
* @Entity(repositoryClass="Gedmo\Tree\Repository\TreeNodeRepository")
* @Table(name="`role`")
* @InheritanceType("JOINED")
* @DiscriminatorColumn(name="discr", type="string")
* @DiscriminatorMap({"user" = "User", "usergroup" = "UserGroup"})
*/
abstract class Role extends \Equ\Entity implements \Zend_Acl_Role_Interface {
/**
* @Column(name="id", type="integer")
* @Id
* @GeneratedValue
* @var int
*/
private $id;
/**
* @gedmo:TreeParent
* @ManyToOne(targetEntity="UserGroup", inversedBy="children")
* @var UserGroup
*/
private $parent;
/**
* @OneToMany(targetEntity="Role", mappedBy="parent")
* @var Doctrine\Common\Collections\ArrayCollection
*/
protected $children;
/**
* @gedmo:TreeLeft
* @Column(name="lft", type="integer")
*/
private $lft;
/**
* @gedmo:TreeRight
* @Column(name="rgt", type="integer")
*/
private $rgt;
/**
* @OneToMany(targetEntity="RoleResource", mappedBy="role")
* @var ArrayCollection
*/
private $roleResources;
/**
* @gedmo:TreeLevel
* @Column(name="lvl", type="integer")
*/
private $lvl;
/**
* @Column(name="role", type="string", length=255, nullable=false)
* @var string
*/
private $role;
public function __construct() {
parent::__construct();
$this->roleResources = new ArrayCollection();
$this->children = new ArrayCollection();
}
/**
* @return UserGroup
*/
public function getParent() {
return $this->parent;
}
/**
* @param UserGroup $parent
* @return Role
*/
public function setParent(UserGroup $parent) {
$this->parent = $parent;
return $this;
}
/**
* @return ArrayCollection
*/
public function getRoleResources() {
return $this->roleResources;
}
public function getRoleId() {
return $this->role;
}
protected function setRoleId($roleId) {
$this->role = (string)$roleId;
return $this;
}
public function __toString() {
return $this->getRoleId();
}
public function getId() {
return $this->id;
}
}
User:
<?php
namespace entities;
/**
* User entity
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link $Link$
* @since 2.0
* @version $Revision$
* @author Szurovecz János <[email protected]>
*
* @Entity(repositoryClass="Gedmo\Tree\Repository\TreeNodeRepository")
* @Table(name="`user`")
*/
class User extends Role {
const PASSWORD_SALT = 'dfJko$~346958rg!DFT]AEtzserf9giq)3/TAeg;aDFa43';
/**
* @Column(name="email", type="string", unique="true")
* @var string
*/
private $email;
/**
* @Column(name="password_hash", type="string", length=32)
* @var string
*/
private $passwordHash;
/**
* @Column(name="activation_code", type="string", length=12)
* @var string
*/
private $activationCode;
/**
* @param string $email
* @param string $password
*/
public function __construct($email, $password) {
parent::__construct();
$this
->setEmail($email)
->setPassword($password);
}
public function init() {
$emailValidator = new \Zend_Validate_EmailAddress();
try {
$emailValidator->setValidateMx(true);
} catch (\Zend_Validate_Exception $e) {}
$this
->setActivationCode($this->generateString(12))
->addFieldValidator('email', $emailValidator);
}
/**
* Generates a random password
*
* @param int $length
* @return string
*/
public function generateString($length = 8) {
$length = (int) $length;
if ($length < 0) {
throw new Exception("Invalid password length '$length'");
}
$set = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$num = strlen($set);
$ret = '';
for ($i = 0; $i < $length; $i++) {
$ret .= $set[rand(0, $num - 1)];
}
return $ret;
}
/**
* Generates a password hash
*
* @param string $password
* @return string
*/
public function generatePasswordHash($password) {
return md5($password . self::PASSWORD_SALT);
}
/**
* @return string
*/
public function getEmail() {
return $this->email;
}
/**
* @param string $email
* @return User
*/
public function setEmail($email) {
$this->email = $email;
$this->setRoleId($email);
return $this;
}
/**
* @return string
*/
public function getPasswordHash() {
return $this->passwordHash;
}
/**
* @param string $password
* @return User
*/
public function setPassword($password) {
$this->passwordHash = $this->generatePasswordHash(trim($password));
return $this;
}
/**
* @return string
*/
public function getActivationCode() {
return $this->activationCode;
}
/**
* @param string $activationCode
* @return User
*/
public function setActivationCode($activationCode) {
$this->activationCode = $activationCode;
return $this;
}
}
UserGroup:
<?php
namespace entities;
/**
* Group entity
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link $Link$
* @since 2.0
* @version $Revision$
* @author Szurovecz János <[email protected]>
*
* @Entity(repositoryClass="Gedmo\Tree\Repository\TreeNodeRepository")
* @Table(name="`user_group`")
*/
class UserGroup extends Role {
/**
* @Column(name="name", type="string", length=255)
* @var string
*/
private $name;
public function __construct($name) {
parent::__construct();
$this->setName($name);
}
/**
* @return string
*/
public function getRoleId() {
return $this->name;
}
public function getName() {
return $this->name;
}
public function setName($name) {
$this->name = $name;
$this->setRoleId($name);
return $this;
}
}
I have an issue with moveUp() not working. moveDown() appears to be functioning correctly.
My Tree:
title: Root lft: 1 rgt: 6 lvl: 0 parent: null
title: Child1 lft: 2 rgt: 3 lvl: 1 parent: Root
title: Child2 lft: 4 rgt: 5 lvl: 1 parent: Root
moveDown(Child1) produces (correct):
title: Root lft: 1 rgt: 6 lvl: 0 parent: null
title: Child1 lft: 4 rgt: 5 lvl: 1 parent: Root
title: Child2 lft: 2 rgt: 3 lvl: 1 parent: Root
moveUp(Child1) produces (incorrect):
title: Root lft: 1 rgt: 6 lvl: 0 parent: null
title: Child1 lft: 6 rgt: 7 lvl: 1 parent: Root
title: Child2 lft: 4 rgt: 5 lvl: 1 parent: Root
Here's my service mover method:
/**
* Generic mover for menu items.
*
* @param Models\Website\Menu $model The menu to move.
* @param integer $dir The direction to move the menu.
*/
public static function moveIt($model, $dir)
{
$repo = self::getRepository('Website\Menu');
if ($dir == self::MOVE_UP) {
$repo->moveUp($model);
} else {
$repo->moveDown($model);
}
}
When using Sluggable extension, slug aren't created, i have an empty value ' '
.
phpunit result:
macbook-julbou:tests julbou$ phpunit Gedmo/Sluggable/SluggableDocumentTest.php PHPUnit 3.5.13 by Sebastian Bergmann. FF Time: 1 second, Memory: 12.00Mb There were 2 failures: 1) Gedmo\Sluggable\SluggableDocumentTest::testSlugGeneration Failed asserting that two strings are equal. --- Expected +++ Actual @@ @@ -my-title-the-code + /Users/julbou/Sites/resowl2/src/vendor/DoctrineExtensions/tests/Gedmo/Sluggable/SluggableDocumentTest.php:72 2) Gedmo\Sluggable\SluggableDocumentTest::testUniqueSlugGeneration Failed asserting that two strings are equal. --- Expected +++ Actual @@ @@ --1 +my-title-the-code-1 /Users/julbou/Sites/resowl2/src/vendor/DoctrineExtensions/tests/Gedmo/Sluggable/SluggableDocumentTest.php:95 FAILURES! Tests: 2, Assertions: 2, Failures: 2.
If I remember correctly, the Sluggable ODM library used to look up slugs by exact match and if the slug was taken then "-1" was appended. (This maybe inaccurate, but Im just trying to give some context, as I remember it)
There was a case where the same prefix was intended to be used with multiple suffixes so the intent was like this
my-slug
my-slug-1
my-slug-2
But in application of this original strategy the experience became
my-slug
my-slug-1
my-slug-1-1
So the sluggable library was updated to target prefix match.
Now it operates as
my-slug
my-slug-1
my-slug-2
This now produces this problem
my-slug (is an existing slug)
Now I want a slug like this
my
Since "my" is a prefex match against "my-slug", the sluggable generator returns
my-1
As an available slug even though "my" is not actually taken
So I think the best case would be look up by a regex that matches a prefix and optionally matches the configured separator and a decimal
Possibly like this
new \MongoRegex("/^{$slug}({$config['separator']}\d+)?$/")
Example:
"/^my-slug(-\d+)?$/"
Please let me know your thoughts
Hi,
I am using doctrine extensions 2.0.x on symfony2 and I get the following error when I try to insert my object into DB :
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'root' cannot be null
You can find the discussion about this topic here:
http://groups.google.com/group/symfony-users/browse_thread/thread/311e6486bda3f5e1/9a285abb6a7e520e?show_docid=9a285abb6a7e520e
Thanks allot in advance !
Before updating gedmo tree worked like a charm! :)
After updating the code (gedmo & other vendors) and using new annotations in entity files I got 500 Internal Server Error - ErrorException:
Notice: Undefined index: strategy in D:\My Dropbox\Symfony\vendor\gedmo-doctrine-extensions\lib\Gedmo\Tree\TreeListener.php line 72
It does not look like a bug on my side :)
Part of the stack trace:
in D:\My Dropbox\Symfony\app\bootstrap.php.cache at line 382
at ErrorHandler ->handle ('8', 'Undefined index: strategy', 'D:\My Dropbox\Symfony\vendor\gedmo-doctrine-extensions\lib\Gedmo\Tree\TreeListener.php', '72', array('om' => object(EntityManager), 'class' => 'Company\ProjectBundle\Entity\Category', 'config' => array('left' => 'lft', 'level' => 'lvl', 'right' => 'rgt', 'parent' => 'parent', 'useObjectClass' => 'Company\ProjectBundle\Entity\Category'), 'managerName' => 'ORM', 'this' => object(TreeListener)))
in D:\My Dropbox\Symfony\vendor\gedmo-doctrine-extensions\lib\Gedmo\Tree\TreeListener.php at line 72
at TreeListener ->getStrategy (object(EntityManager), 'Company\ProjectBundle\Entity\Category')
in D:\My Dropbox\Symfony\vendor\gedmo-doctrine-extensions\lib\Gedmo\Tree\TreeListener.php at line 197
at TreeListener ->loadClassMetadata (object(LoadClassMetadataEventArgs))
in D:\My Dropbox\Symfony\vendor\doctrine-common\lib\Doctrine\Common\EventManager.php at line 64
(...)
Btw. thanks for great work!
I have a problem with Sluggable behaviour when using certain special character in a slug (for instance if my title that has to be slugged contains É).
I get the following error :
Warning: Cannot modify header information - headers already sent by (output started at /Library/WebServer/fer/vendor/doctrine-extensions/lib/Gedmo/Sluggable/Util/data/x00.php:1) in /Library/WebServer/fer/vendor/symfony/src/Symfony/Component/HttpFoundation/Response.php on line 126
I can solve the problem by deleting the "space" (it's not a space, it's some other ASCII character I guess) which is the first element in the array in x00.php
Where is some work done in xml-driver branch. And hopefully soon it will be merged into master. So far it is in development process. Any concerns or ideas regarding the xml driver are very welcome.
Hi, since commit f76da9a it is not possible to remove an entity if it has any dependant association - Gedmo tries to remove only the entity I want to get rid of, but not its associations marked by
cascade={"all"}.
This action leads to an error on database side (integrity constraint violation on mysql).
If we use single table inheritance like this:
/** * @orm:DiscriminatorMap({ * "type1" = "NodeType1", * "type2" = "NodeType2" * }) */ abstract class BaseNode {}
and call childCount() method with a NodeType1, we have the following query:
SELECT COUNT(node.id) FROM Entity\SubFolder\NodeType1 node WHERE node.parent = 1
The result is wrong because all NodeType2 are ignored
The query should be:
SELECT COUNT(node.id) FROM Entity\SubFolder\BaseNode node WHERE node.parent = 1
It would be nice if the tree would implement the SPL RecursiveIterator. This would make it easier to iterate the tree.
In Doctrine 1 when entity has no translation in some locale, the value returned was empty string.
Bu now, thi value is the last saved value for an entity. For example if i save some entity in en locale and it has no translation in de locale, then in de locale the value of this field will be the value in en locale...
Am i wrong? Is there any ways to change this behaviour?
Thanks a lot
I got this error when using $repository->translate:
Fatal error: Call to a member function setObjectClass() on a non-object in gedmo-doctrine-extensions\lib\Gedmo\Translatable\TranslationListener.php on line 314.
It's because setField method don't return the current object instance.
There is a use-case when you want to keep the log for last week / month / year, etc and clean-up old revisions.
But with this approach "revert" fails to work sometimes and may throw an exception: 'Cound not fully revert the document to version: X'
Does it mean that log cannot be touched or is it possible to workaround / fix it somehow?
NestedTreeRepository::moveAsLastChildOf($source, $target);
NestedTreeRepository::moveAsFirstChildOf($source, $target);
NestedTreeRepository::moveAsPrevSiblingOf($source, $target);
NestedTreeRepository::moveAsNextSiblingOf($source, $target);
The first two are easy, you only need to call moveUp($source, true) or moveDown($source, true) after reparenting of the $source.
But I am not sure how would I achieve the second two methods?
These methods are available in the Doctrine1 Nested Set extension, and providing them would probably help a lot of people in the transition from Doctrine 1 to 2.
The problem seems to happen when :
The error I get is a "Integrity constraint violation", as the entity manager attempts to re-insert the record in the join table.
I don't get the error without setting the default locale, or without changing the many-to-many property.
I think that the problem is somewhere in the handleTranslatableObjectUpdate method of the TranslationListener class, in the last if clause (line 471 in the current doctrine 2.0.x branch).
I'm using Doctrine 2.0.5 and the last version of the TranslationListener for Doctrine 2.0.x (I tried to use Doctrine 2.1 beta and the master branch of the Translation Listener extension but I got the exact same problem).
I tried very hard to fix the issue myself but I'm afraid I'm not familiar enough with Doctrine internals to grasp all the subtleties of changeset alterations - but if you can point me in the right direction, maybe I could provide some help.
Hi,
I have an entity in a subfolder (Bundle\MyBundle\Entity\SubFolder\EntityName),
when i create the entity in the database, the annotation reader never reads my class.
during the _readAnnotations function in the listener, when adding the following code, nothing happened:
if (strpos($class->getNamespaceName(), 'SubFolder') !== false) { die('class has been parsed !'); }
so i'm sure my entity doesn't get parsed.
Is it a know issue ? Should i move my entity out of the subfolder to get it work ?
ps: i have do everything to find the solution (clear cache, regenerate proxies, ..), i'm also using the DoctrineExtensionsBundle so everything should be correctly configured
I want to retreive translatable fields from an entity. I found this way:
$config = $em->getRepository('Gedmo\Translatable\Entity\Translation')
->getTranslationListener()
->getConfiguration($em, $class)
$fields = $config['fields'];
But getTranslationListener is private. Could it be changed to public?
I have the following entity :
http://pastie.textmate.org/private/9gkqfjfqnucx0a5rh6sg
When addind a new User I end up with that in the slug field :
notice-undefined-offset-0-in-library-webserver-fer-vendor-doctrine-extensions-lib-gedmo-sluggable-util-urlizer-php-on-line-304-c
There are two classes (Gedmo/Tree/TreeListener.php and Gedmo/Tree/ODM/MongoDB/TreeListener.php) which have the same name Gedmo\Tree\TreeListener.
The updatedAt field (mapped with @gedmo:Timestampable(on="update")
) is no more set when the entity is created. This worked well a month ago but it seems that the refactoring breaks it.
Hi, how difficult would it be to add multiple root support? Is it just a matter of adding a "TreeId" metadata field and adding that to all the queries? Sounds too easy ...
Hi,
I use in my project both doctrine ORM and ODM, when I try to get metadata for a Document I get en exception :
Class myBundle\Document\BaseDocument is not a valid entity or mapped super class
I look at source code Gedmo/Mapping/Driver/Chain.php at line 67 and dump $this->_drivers and find that it try to validate my Document namespace against my Entity namespace.
If I bypass the exception everything work as expected.
Currently I use third-party bundles which use the XML mapping for their entities (which don't use any of the DoctrineExtensions behaviors). Since the implementation of drivers it raises an exception as the XmlDriver is not yet implemented.
I think you should ignore XML-mapped entities instead of raising an exception as XML is the best practice for Sf2 third-party bundles and the current implementation makes your extension incompatible with them.
in some cases the order of persisted nodes are changed in the commit, this causes any kind of tree(which depends on some additional calculations on post insert) to fail, this mostly relates to path and nestedset trees. It requires some analysis on core operations
The 3.0.x branch of Doctrine Common changes the way annotations are handled. Symfony switches to this branch today which means that your extension will not work anymore (having 2 versions of the Common library is not possible).
translations are not created in case if none of translatable field changed, this issue relates to translations which has same translation in few langueges for instance
There are some other good models for store hierarchical structures, like closure table
http://www.slideshare.net/billkarwin/sql-antipatterns-strike-back - slide 68. I think that tree-extension may support differ models.
Hi, i have some problem with changing parent for nodes. I have this data:
rgtID | Name | parent_id | lft | level | |
---|---|---|---|---|---|
1 | Root node | NULL | 1 | 8 | 0 |
2 | Node 1 | 1 | 2 | 3 | 1 |
3 | Node 2 | 1 | 4 | 7 | 1 |
4 | SubNode 1 | 3 | 5 | 6 | 2 |
move SubNode 1 from parent Node 2 to parent Node 1 generate this inconsistant data:
rgtID | Name | parent_id | lft | level | |
---|---|---|---|---|---|
1 | Root node | NULL | 1 | 8 | 0 |
2 | Node 1 | 1 | 2 | 5 | 1 |
3 | Node 2 | 1 | 6 | 7 | 1 |
4 | SubNode 1 | 2 | 7 | 8 | 2 |
First I just want to say thank you for your work on this project. It's really quite excellent. :)
I may have found a flaw in the design of the SluggableListener (or perhaps I'm making a mistake, myself)
Given:
A Person entity with fields 'slug' and 'name'
where the slug is unique and created by using the value of the name field.
The following fails:
$person1 = new Person();
$person1->setName('Joe');
$person2 = new Person();
$person2->setName('Joe');
$em->persist($person1); // prePersist event fires, the listener checks the database for a person with a slug like '%joe%' and finds none
$em->persist($person2); // prePersist event fires, the listener checks the database for a person with a slug like '%joe%' and finds none
$em->flush(); // the first Person saves correctly with slug 'joe', the second fails because a slug of 'joe' already exists
The database check for like slugs really needs to occur on preInsert rather than prePersist...but there's no perInsert event in Doctrine 2 (as far as I know). You can use the onFlush event, though, and iterate over the unit of work's collection of scheduled insertions, which is what I've been able to do successfully in my own SluggableListener, but it's quite a hack job at the moment.
I think the best solution might be to merge the prePersist handler's functionality into the onFlush handler, and the onFlush handler should check for like slugs in the unit of work's insertion collection as well as the database
There is support of sorting nodes in Tree. Is there way to move it to separate extension?
i have an exception:
TreeNodeRepository: this repository cannot be used on MyEntity without Tree metadata
metadata arent't loaded
is there any way to activate the parsing of all my classes ?
I think the folders have to be removed or doing git submodule update --recursive fails at this extension.
The performances of the Translatable extension should be optimized when loading a collection.
Generating my page uses currently 24 requests and 20 of them are done by the extension to load the translations for the loaded collection.
Considered features:
1, 3 will require personalized translation entity, with a composite constraint.
Hi,
Have you planned to add a geographical extension like there was in doctrine 1.x ?
Thanks :-)
This issue was reported by M4d3L on my blog, in general the case is that entity generator uses the DisconnectedMetadataFactory which does not let to search for parent classes since they are not available, this causes the extension metadata reader to fail autoloading parent classes
It would be cool if we can have a method like this:
$nodeParent = new Node(); $nodeParent->setChildren(array(new Node, new Node, new Node)); $node = new Node(); $node->setParent($nodeParent); $treeRepo->setPosition($node, 2);
result:
- - - node -
When using a default translation and adding a new translation other than the default one, the listener will reset the object to its previous state which throws an exception in the UnitOfWork when creating the preUpdateEventArgs
instance because there is no change set anymore.
I think it is more a Doctrine bug than a bug of the extension but I report it here too so that users will be able to know what the issue is.
The Doctrine issue is here: http://www.doctrine-project.org/jira/browse/DDC-1173
Shouldn't childrenQuery use the rootNode of the tree? I have a table called website_menu with a menu for every website (TreeRoot is websiteId). The childrenQuery() returns:
SELECT node FROM Models\Website\Menu node WHERE (node.rgt < 20) AND (node.lft > 1) ORDER BY node.lft ASC
when it should be:
SELECT node FROM Models\Website\Menu node WHERE (node.rgt < 20) AND (node.lft > 1) AND websiteId = SOME_ID ORDER BY node.lft ASC
Otherwise, what's the point of the tree root?
Hi again,
Now, trying to create a simple DQL selecting either descendant or ancestor properties, I get this exception:
Doctrine\ORM\Query\QueryException: [Semantical Error] line 0, col 9 near 'descendant FROM': Error: Invalid PathExpression. Must be a StateFieldPathExpression.
I can confirm this was working before the refactoring of the closure implementation. I uploaded a failing unit test just in case:
https://github.com/comfortablynumb/DoctrineExtensions/tree/closure-mapping-issue
So far I was not able to find the problem. I know that it has something to do with the dynamic mapping of these properties, but I don't know why it happens yet.
Thanks!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.