TYPO3: Remove validation from ObjectStorage property in model - typo3

Does anyone knows if it is possible to remove recursive validation from model in extbase TYPO3?
Let's say I have model with following properties:
/**
* #var string
* #validate NotEmpty
*/
protected $title;
/**
* #var string
* #validate NotEmpty
*/
protected $city;
/**
* #lazy
* #var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<my/model/classname>
*/
protected $categories;
When passing my object to controller action I want only title and city to be validated. I would like categories not to be validated. Extbase is validating all relations in ObjectStorage recursively - so if my/model/classname has also another ObjectStorage relations they will be validated too.

Here is similar thread from TYPO3 forum https://forum.typo3.org/index.php/t/204874/-typo3-mvc-disable-recursive-validation-objectstorage

Related

Symfony 4 MongoDB ODM One to ONe relationship is not working

I am facing an error with symfony and mongoDB odm on one to one relationship
for example i have a user that has Work .
User Class:
/**
* #MongoDB\Document
* #MongoDBUnique(fields="email")
*/
class User implements UserInterface
{
/**
* #MongoDB\Id
*/
private $id;
/**
* #MongoDB\Field(type="string")
*/
private $firstName;
/**
* #MongoDB\Field(type="string")
*/
private $lastName;
/**
* #MongoDB\Field(type="string")
* #Assert\NotBlank()
* #Assert\Email()
*/
private $email;
/**
* #MongoDB\ReferenceOne(targetDocument=Work::class)
*/
private $work;
//getter setter
Work Class:
class Work
{
/**
* #MongoDB\Id()
*/
private $id;
/**
* #MongoDB\ReferenceOne(targetDocument=User::class)
*/
private $user;
//getter setter
}
Controller:
class TestingController extends AbstractController
{
/**
* #Route("/testing", name="testing")
* #param DocumentManager $documentManager
* #return Response
* #throws MongoDBException
*/
public function index(DocumentManager $documentManager)
{
$user = new User();
$user->setFirstName('test1');
$user->setLastName('test2');
$user->setEmail('test123#gmail.com');
$documentManager->persist($user);
$work= new Work();
$work->setUser($user);
$documentManager->persist($work);
$documentManager->flush();
return new Response("test");
}
/**
* #Route("/test", name="test")
* #param DocumentManager $documentManager
* #return Response
*/
public function test(DocumentManager $documentManager){
$user = $documentManager->getRepository(User::class)->findAll();
dump($user);
return new Response("test test");
}
}
So I created 2 classes one as user that has one work, I created the user , then I created a work and i assigned the user from the work class.
in MongoDB compass I got under Work collection a reference for the user.
now in the test method in the controller i try to find the users and dump the data.
The problem is whenever i want to find $user->getWork() i get a null value, while the user exists. but the inverse is working fine . whenever i try $work->getUser() i can find the user.
is there anything wrong in my code ? I want to use both methods : $user->getWork() and $work->getUser(),
I have tried adding to the ReferenceOne mappedBy and inversedBy but its always one of the two methods returns null value.
I think you forgot the mappedBy and inversedBy arguments in the annotation. See the documentation: https://www.doctrine-project.org/projects/doctrine-mongodb-odm/en/2.1/reference/bidirectional-references.html#one-to-one

Symfony: entity and sub-entity in a single form

I have an entity, studyInformation which has a repetitive information for languages with language + level + hasCertificate. This is defined in 2 entities.
I define form type for both entities (using CRUD generator) and can include language form type inside studyInformation form type (see form code).
But my problem is, languageInformationType has an entity field to select its studyInformation. I don't want this to be visible as for the user this association is invisible. When editing it's easy to hide the languageInformationType selector, but, how to handle it on new studyInformation form? how to under the table relate both entities? I guess I can do all work in controller by hand, getting all request parameters and instantiating and persisting entity by hand, but, is there a way to relay in tha magic of doctrine to do it? (studyInformation has MANY fields to process them by hand)
ENTITIES
/**
* studyInformation
*
* #ORM\Table()
* #ORM\Entity
*/
class studyInformation
{
/**
* #var languageInformation
*
* #ORM\OneToMany(targetEntity="languageInformation", mappedBy="studyInformation", cascade={"persist", "remove"})
* #ORM\JoinColumn(name="languages", referencedColumnName="id")
**/
private $languages;
And
/**
* languageInformation
*
* #ORM\Table()
* #ORM\Entity
*/
class languageInformation
{
/**
* #var boolean
*
* #ORM\Column(name="hasCertificate", type="boolean")
*/
private $hasCertificate;
/**
* #var integer
*
* #ORM\Column(name="level", type="integer")
*/
private $level;
/**
* #var ListOfLanguages
*
* #ORM\ManyToOne(targetEntity="ListOfLanguages")
* #ORM\JoinColumn(name="languages", referencedColumnName="id")
**/
private $languages;
/**
* #var studyInformation
*
* #ORM\ManyToOne(targetEntity="studyInformation", inversedBy="languages")
* #ORM\JoinColumn(name="studyInformation", referencedColumnName="id")
**/
private $studyInformation;
FORM
class studyInformationType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('languages', 'collection', array('type' => new languageInformationType()))
;
}

I'm trying to serialize embedded mongodb documents with JMSSerizial Bundle

I'm try to serialize a MongoDB document with embedded documents within Symfony 2.1. I am using the JMSserializer and Mongodb-odm bundles.
I have the following Documents entities.
// Blog
namespace App\DocumentBundle\Document;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
use JMS\SerializerBundle\Annotation\Type;
/**
* #MongoDB\Document(repositoryClass="App\DocumentBundle\Repository\BlogRepository")
*/
class Blog {
/**
* #MongoDB\Id
*/
protected $id;
/**
* #MongoDB\String
* #Assert\NotBlank()
*/
protected $title;
/**
* #MongoDB\string
* #Assert\NotBlank()
*/
protected $blog;
/**
* #MongoDB\EmbedMany(targetDocument="Tag")
*/
private $tags;
/**
* #MongoDB\Timestamp
*/
protected $created;
/**
* #MongoDB\Timestamp
*/
protected $updated;
}
and
// Tag
namespace App\DocumentBundle\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
/**
* #MongoDB\EmbeddedDocument
*/
class Tag {
/**
* #MongoDB\String
*/
protected $name;
}
An ArrayCollection type is generated for the tag attribute, but the JMSSerializer bundle doesn't like it. If I change the tag to #MongoDB\String and regenerate the Blog document,
then serialization occurs, but not with #MongoDB\EmbedMany(targetDocument="Tag") set.
Do I need to specify some of the JMSSerializer annotated attributes allow embedded document to also be serialized?
You have to configure the expected type for JMSSerializer
Annotation :
/**
* #MongoDB\EmbedMany(targetDocument="Tag")
* #Type(ArrayCollection<App\DocumentBundle\Document\Tag>)
*/
private $tags;
Yaml :
tags:
expose: true
type: ArrayCollection<App\DocumentBundle\Document\Tag>

Joining-Table with Metadata Impairs Getters/Setters - Doctrine 2

I'm writing a feature which calls for the records of my joining table to carry extra metadata (Joining-Table with Metadata). I've attempted to implement this in accordance with this section of the Doctrine documentation.
See below for example Entity definitions.
The challenge now is that getGroups and setGroups do not yield/set Group entities (& the same is true from the Group instance perspective), but they yield GroupUser entities.
This adds a substantial delay to process of managing this relationships, which so far have been extremely smooth - for example, I cannot simply add, remove, or check for the existence of a Group to the collection which getGroups yields.
Can anyone identity any errors in my implementation, or else recommend a more fluid way of implementing this concept?
Thanks in advance for any input.
EDIT:
My main concern is this: using this implementation, retrieving a collection of Users from a Group entity requires this Entity method's mediation:
public function getUsers() {
return $this->users->map(function($groupUser){
return $groupUser->getUser();
});
}
I'm concerned that this could imply a major performance hit down the road. Am I incorrect?
Furthermore, how does one re-implement the setUsers method?
Group entity:
<?php
/**
* #Entity
* #Table(name="group")
*/
class Group {
/**
* #Column(type="integer", nullable=false)
* #Id
*/
protected $id = null;
/**
* #OneToMany(targetEntity="GroupUser", mappedBy="group")
* #var \Doctrine\Common\Collections\Collection
*/
protected $users;
}
User entity:
<?php
/**
* #Entity
* #Table(name="user")
*/
class User {
/**
* #Column(type="integer", nullable=false)
* #Id
*/
protected $id = null;
/**
* #OneToMany(targetEntity="GroupUser", mappedBy="user")
* #var \Doctrine\Common\Collections\Collection
*/
protected $groups;
}
Joining entity:
<?php
/**
* #Entity
* #Table(name="group_user")
*/
class GroupUser {
/**
* #Id
* #ManyToOne(targetEntity="User", inversedBy="groups")
* #JoinColumn(name="userId", referencedColumnName="id")
*/
protected $user;
/**
* #Id
* #ManyToOne(targetEntity="Group", inversedBy="users")
* #JoinColumn(name="groupId", referencedColumnName="id")
*/
protected $group;
/**
* #Column(type="integer")
*/
protected $relationship;
}
Related -
Same goal, slightly different approach, which consistently produced errors once the resulting collections were manipulated: http://www.doctrine-project.org/jira/browse/DDC-1323
Supports the approach, no technical details: Doctrine 2 join table + extra fields
I've found just two examples (see question) of entity definitions for this specific type of relationship, however no example code for how they're used. As such it was fairly unclear how fluid (or otherwise) the resulting setters & getters could be expected to be. Hopefully this code will help clear up the approach for anyone else making a similar attempt.
The ideal solution under the circumstances (thanks #doctrine # freenode) was to implement a custom repository - a more flexible & efficient place for creating & managing the association.
Example Custom Repository for Join-Table with Metadata Class - Solution accompanies code in original question
<?php
use Doctrine\ORM\EntityRepository;
class GroupUserRepository extends EntityRepository {
/**
* #param \User $user
* #param \Group $group
* #param integer $type One of the integer class constants defined by GroupUser
* #param string $role Optional string defining user's role in the group.
* #return \GroupUser
*/
public function addUserToGroup(User $user, Group $group, $relationship, $role = '') {
$groupUser = $this->findOneBy(array('user' => $user->getId(), 'group' => $group->getId()));
if(!$groupUser) {
$groupUser = new GroupUser();
$groupUser->setGroup($group);
$groupUser->setUser($user);
$groupUser->setRole($role);
$groupUser->setRelationship($relationship);
$this->_em->persist($groupUser);
}
return $groupUser;
}
/**
* #param \User $user
* #param \Group $group
* #return null
*/
public function removeUserFromGroup(User $user, Group $group) {
$groupUser = $this->findOneBy(array('user' => $user->getId(), 'group' => $group->getId()));
if($groupUser)
$this->_em->remove($groupUser);
}
}
Then, from the join-table class, modify the Entity meta-data accordingly to specify the custom repository.
<?php
/**
* #Entity(repositoryClass="\Path\To\GroupUserRepository")
*/
class GroupUser {
// ...
}
This causes the custom repository to yield in place of the default one, making a proxy method from the Entity class simple.
<?php
/**
* #Entity
*/
class Group {
/**
* #param \User $user
* #param integer $relationship One of the integer class constants defined by GroupUser
* #param string $role Optional string defining user's role in the group.
* #return \GroupUser
*/
public function addUser(User $user, $relationship, $role = '') {
return $this->_em->getRepository('GroupUser')
->addUserToGroup($user, $this, $relationship, $role);
}
}
And things are about as manageable as they were before.

Symfony2: How to import existing database into different bundles

I've seen a lot of posts here which describes the separation of concerns regarding organizing your app in bundles which work on their containing entities. But none of them states the point that these entities are related through different bundles.
As I already have an existing database which contains tables for posts, comments, tags, users, roles and some more I want to import this definition into my new symfony2 project.
My problem is that I would like to have that in different bundles like BlogBundle, UserBundle, StaticBundle, ..., but I do not know how to import the respective entities into the right bundle.
Further problem is that the user entity is referenced inside the post and comment entity so how should I do that. When I import the post, comment, tag into the BlogBundle, the user entity does not exist yet.
Can anyone guide me with a hint on how to go on with that process?
Entities are shared between bundles (of course).
If you want to do a blog, you can create a UserBundle (which could override the awesome FOSUserBundle for example), and a BlogBundle.
UserBundle will contain your User entity, BlogBundle will contain your Post and Comment entities.
Now an example of code:
In your UserBundle:
<?php
namespace YourVendorName\UserBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Table(name="my_user_table")
* #ORM\Entity(repositoryClass="YourVendorName\UserBundle\Entity\UserRepository")
*/
class User
{
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(name="name")
*/
private $name;
// Getters and setters...
}
In your BlogBundle:
<?php
namespace YourVendorName\BlogBundle\Entity;
class Post
{
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(name="title", type="string", length=255)
*/
private $title;
/**
* #ORM\Column(name="body", type="text")
*/
private $body;
/**
* #ORM\Column(name="created_at", type="datetime")
*/
private $createdAt;
/**
* #ORM\ManyToOne(targetEntity="YourVendorName\UserBundle\Entity\User")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $author;
// Getters and setters
}
So you reference an entity in another bundle thanks to such annotations:
#ORM\ManyToOne(targetEntity="YourVendorName\UserBundle\Entity\User")
Anyway, you should really read the Symfony2 documentation, it might help you understand everything.