SonataUserBundle XML serializer config not working - symfony

I have the SonataUserBundle and JMSSerializerBundle set up and running. Now i am trying to override the serializer configuration for Application\Sonata\UserBundle\Entity\User.
The XML file i am using for this configuration was generated by the SonataEasyExtendsBundle in:
Application\Sonata\UserBundle\Resources\config\serializer\Entity.User.xml and looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<serializer>
<!--
This file has been generated by the EasyExtends bundle
( http://sonata-project.org/bundles/easy-extends )
#author <yourname> <youremail>
-->
<class name="Application\Sonata\UserBundle\Entity\User" exclusion-policy="all" xml-root-name="user">
<property name="id" type="integer" expose="true" since-version="1.0" groups="sonata_api_read,sonata_api_write,sonata_search" />
</class>
</serializer>
I also configured app/config/config.yml to use that XML file:
jms_serializer:
metadata:
auto_detection: true
directories:
ApplicationSonatUserBundle:
path: #ApplicationSonataUserBundle/Resources/config/serializer
namespace_prefix: Application\Sonata\UserBundle\Model
Now according to the configuration i should only see the id field when the object gets serialized. But when i test this all fields are exposed. This is obviously a bad idea.
I am using FOSRestBundle to implement the API layer where this is being used. And if i run:
get_class($this->getUser())
//outputs Application\Sonata\UserBundle\Entity\User
So FOSUserBundle is using the right User entity.
I have been looking at this for a couple of hours and can't find what's going wrong...

finally solved this, apparently you must reference the class where the properties actually reside. In this case i was trying to expose the property id which resides in FOS/UserBundle/Model/Entity. I ended up configuring properties for both Sonata/UserBundle/Model/User and the FOS user class. My XML now looks like this:
<serializer>
<class name="Sonata\UserBundle\Model\User" exclusion-policy="all" xml-root-name="user">
<property name="dateOfBirth" type="DateTime" expose="true" since-version="1.0" groups="profile" />
<property name="firstname" type="string" expose="true" since-version="1.0" groups="profile" />
<property name="lastname" type="string" expose="true" since-version="1.0" groups="profile" />
<property name="website" type="string" expose="true" since-version="1.0" groups="profile" />
<property name="locale" type="string" expose="true" since-version="1.0" groups="profile" />
<property name="phone" type="string" expose="true" since-version="1.0" groups="profile" />
</class>
<class name="FOS\UserBundle\Model\User" exclusion-policy="all" xml-root-name="user">
<property name="id" type="integer" expose="true" since-version="1.0" groups="profile" />
<property name="username" type="string" expose="true" since-version="1.0" groups="profile" />
<property name="email" type="string" expose="true" since-version="1.0" groups="profile" />
<property name="roles" type="array" expose="true" since-version="1.0" groups="profile" />
</class>
</serializer>

Related

How to add cascade argument in XML file format doctrine ORM

as far as I understand I need to add a "cascade" parameter to the mapping. But my mapping is in XML.
I found quite a bit of information about it but there was no result.
Pleace help!
Мy error is:
Multiple non-persisted new entities were found through the given association graph:\n\n * A new entity was found through the relationship 'Domain\Maintenance\Maintenance#affectedRegions' that was not configured to cascade persist operations for entity: Domain\AffectedRegion\AffectedRegion#0000000075384ba200000000535ab7f1. To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example #ManyToOne(..,cascade={"persist"}). If you cannot find out which entity causes the problem implement 'Domain\AffectedRegion\AffectedRegion#__toString()' to get a clue.\n *
XML fails:
<entity name="Domain\Maintenance\Maintenance" table="maintenances" repository-class="Infrastructure\Repositories\MaintenanceRepository">
<id name="id" type="integer" column="id">
<generator strategy="AUTO"/>
</id>
<field name="name" type="string"/>
<one-to-many field="affectedRegions" target-entity="Domain\AffectedRegion\AffectedRegion" mapped-by="Domain\Maintenance\Maintenance" />
<cascade>
<cascade-merge/>
</cascade>
</entity>
<entity name="Domain\AffectedRegion\AffectedRegion" table="affected_regions" repository-class="Infrastructure\Repositories\AffectedRegionRepository">
<id name="id" type="integer" column="id">
<generator strategy="AUTO"/>
</id>
<many-to-one field="region" target-entity="Domain\Region\Region" inversed-by="Domain\AffectedRegion\AffectedRegion">
<join-column name="region_id" referenced-column-name="id" />
<cascade>
<cascade-persist/>
</cascade>
</many-to-one>
<many-to-one field="maintenance" target-entity="Domain\Maintenance\Maintenance" inversed-by="Domain\AffectedRegion\AffectedRegion">
<join-column name="maintenance_id" referenced-column-name="id" />
<cascade>
<cascade-persist/>
</cascade>
</many-to-one>
<field name="vlans" type="string"/>
<field name="olts" type="string"/>
</entity>
<entity name="Domain\Region\Region" table="regions" repository-class="Infrastructure\Repositories\RegionRepository">
<id name="id" type="integer" column="id">
<generator strategy="AUTO"/>
</id>
<field name="name" type="string"/>
<field name="code" type="string"/>
<one-to-many field="affectedRegions" target-entity="Domain\AffectedRegion\AffectedRegion" mapped-by="Domain\Maintenance\Maintenance" />
</entity>
this is my FK:
$affectedRegionTable->addForeignKeyConstraint(
$regionTable,
['region_id'],
['id'],
['onUpdate' => 'CASCADE'],
'fk_affectedRegions_region_id'
);
$affectedRegionTable->addForeignKeyConstraint(
$regionTable,
['maintenance_id'],
['id'],
['onUpdate' => 'CASCADE'],
'fk_affectedRegions_maintenance_id'
);
the relation I want to make is:
Maintenance ← one-to-many → AffectedRegions ← many-to-one → Region
Here is the answer.
Another way to add a cascade argument:
<one-to-many field="affectedRegions" target-entity="Domain\AffectedRegion\AffectedRegion" mapped-by="maintenance">
<cascade>
<cascade-persist/>
<cascade-remove/>
</cascade>
</one-to-many>

fosrestBundle and SonataUserBundle new fields serilalisation

i'm using the SonataUserBundle extended under src/Application/Sonata/UserBundle and i added some extra fields in src/Application/Sonata/UserBundle/Resources/config/doctrine/User.orm.xml
<entity name="Application\Sonata\UserBundle\Entity\User" table="ez_user">
<id name="id" column="id" type="integer">
<generator strategy="AUTO" />
</id>
<many-to-many field="groups" target-entity="Application\Sonata\UserBundle\Entity\Group">
<join-table name="ez_user_group">
<join-columns>
<join-column name="user_id" referenced-column-name="id"/>
</join-columns>
<inverse-join-columns>
<join-column name="group_id" referenced-column-name="id"/>
</inverse-join-columns>
</join-table>
</many-to-many>
<many-to-one field="media" target-entity="Application\Sonata\MediaBundle\Entity\Media">
<cascade>
<cascade-all/>
</cascade>
</many-to-one>
<field name="companyName" column="company_name" type="string" length="255" nullable="true" />
<field name="companyPhone" column="company_phone" type="integer" nullable="true" />
</entity>
getter and setter added in src/Application/Sonata/UserBundle/Entity/User.php
my config.yml is like this
fos_user:
db_driver: orm
firewall_name: main
user_class: Application\Sonata\UserBundle\Entity\User
group:
group_class: Application\Sonata\UserBundle\Entity\Group
group_manager: sonata.user.orm.group_manager
service:
user_manager: sonata.user.orm.user_manager
sonata_user:
security_acl: true
manager_type: orm
class:
user: Application\Sonata\UserBundle\Entity\User
group: Application\Sonata\UserBundle\Entity\Group
jms_serializer:
metadata:
directories:
FOSUB:
namespace_prefix: "FOS\\UserBundle"
path: "%kernel.root_dir%/serializer/FOSUserBundle"
app/serializer/FOSUserBundle/Model.User.xml :
<serializer>
<class name="FOS\UserBundle\Model\User" exclusion-policy="all" xml-root-name="user">
<property name="username" type="string" expose="true" since-version="1.0" groups="sonata_api_read,sonata_api_write,sonata_search" />
<property name="usernameCanonical" type="string" expose="false" since-version="1.0" groups="sonata_api_read,sonata_search" />
<property name="email" type="string" expose="true" since-version="1.0" groups="sonata_api_read,sonata_api_write,sonata_search" />
<property name="emailCanonical" type="string" expose="false" since-version="1.0" groups="sonata_api_read,sonata_search" />
<property name="enabled" type="boolean" expose="false" since-version="1.0" groups="sonata_api_read,sonata_api_write,sonata_search" />
<property name="plainPassword" type="string" expose="false" since-version="1.0" groups="sonata_api_write" />
<property name="lastLogin" type="DateTime" expose="false" since-version="1.0" groups="sonata_api_read,sonata_search" />
<property name="locked" type="boolean" expose="false" since-version="1.0" groups="sonata_api_read,sonata_api_write,sonata_search" />
<property name="expired" type="boolean" expose="false" since-version="1.0" groups="sonata_api_read,sonata_api_write,sonata_search" />
<property name="expiresAt" type="DateTime" expose="false" since-version="1.0" groups="sonata_api_read,sonata_api_write,sonata_search" />
<property name="confirmationToken" type="string" expose="false" since-version="1.0" groups="sonata_api_read,sonata_search" />
<property name="passwordRequestedAt" type="DateTime" expose="false" since-version="1.0" groups="sonata_api_read,sonata_api_write,sonata_search" />
<property name="roles" type="array" expose="false" since-version="1.0" groups="sonata_api_read,sonata_api_write,sonata_search" />
<property name="credentialsExpired" type="boolean" expose="false" since-version="1.0" groups="sonata_api_read,sonata_api_write,sonata_search" />
<property name="credentialsExpireAt" type="DateTime" expose="false" since-version="1.0" groups="sonata_api_read,sonata_api_write,sonata_search" />
<property name="gender" expose="false" />
<property name="createdAt" type="DateTime" expose="false" since-version="1.0" groups="sonata_api_read,sonata_api_write,sonata_search" />
<property name="updatedAt" type="DateTime" expose="false" since-version="1.0" groups="sonata_api_read,sonata_api_write,sonata_search" />
</class>
the jms section in the config is to hide some properties like (password, salt, etc) from api return data
my probleme is in my api a dan't get the new fields added in SonataUserBundles (media, comanyName)
any idea ?

doctrine2 (xml): in a one-to-many bidirectional relationship, can't get the infers side?

i have Banner and Group entities with xml configs
Banner.xml
<mapped-superclass name="Banner" table="luc_banners"
repository-class="BannerRepository">
<id name="id" column="id" type="integer">
<generator strategy="AUTO" />
</id>
<field name="path" column="path" type="string" nullable="true" />
<field name="link" column="link" type="string" nullable="true" />
<field name="position" column="position" type="string" nullable="true" />
<field name="groupId" column="group_id" type="integer" />
<many-to-one field="group" target-entity="Group" inversed-by="banners">
<join-column name="group_id" referenced-column-name="id" nullable="false" on-delete="CASCADE" />
</many-to-one>
</mapped-superclass>
Group.xml
<mapped-superclass name="Group" table="luc_banners_groups" repository-class="GroupRepository">
<id name="id" column="id" type="integer">
<generator strategy="AUTO" />
</id>
<field name="name" column="group_name" type="string" nullable="true" />
<field name="type" column="group_type" type="string" nullable="true" />
<field name="status" column="group_status" type="string" nullable="true" />
<field name="order" column="group_order" type="integer" nullable="true" />
<one-to-many field="banners" target-entity="Banners" mapped-by="group">
<cascade>
<cascade-all />
</cascade>
</one-to-many>
</mapped-superclass>
when trying to get banners form group object i get empty array, and Profiler shows this sql SELECT l0_.group_name AS group_name0, l0_.id AS id4 FROM luc_banners_groups l0_ WHERE l0_.group_status = ? and show not valid entity with this error Banner - The association Banner#group refers to the inverse side field Group#banners which does not exist.
Can you help me with this thing ?
remove <field name="groupId" column="group_id" type="integer" /> from Banner.xml, I think it's overriding the second one..

Doctrine 2 unknown column type requested

I'm trying to update my doctrine schema with the command:
php app/console doctrine:schema:update --force
I'm getting this error:
[Doctrine\DBAL\DBALException]
Unknown column type requested.
I'm getting this error since I've updated the xml mapping of the user entity in the Sonata UserBundle like this:
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="Application\Sonata\UserBundle\Entity\User" table="fos_user_user" repository-class="Application\Sonata\UserBundle\Repository\UserRepository">
<id name="id" column="id" type="integer">
<generator strategy="AUTO" />
</id>
<field name="name" type="string" length="50" />
<field name="birthdate" type="date" />
<field name="natRanking" type="string" length="10" />
<field name="interNatRanking" type="string" length="10" nullable="true" />
<field name="natDoublesRanking" type="string" length="10" />
<field name="interNatDoublesRanking" type="string" length="10" nullable="true" />
<field name="doublesPartner" type="string" length="50" nullable="true" />
<field name="nationality" type="string" length="50" />
<field name="fileName" type="string" length="255" nullable="true" />
<field name="path" type="string" length="255" nullable="true" />
<field name="file" />
<many-to-many field="teams" target-entity="Tennisconnect\DashboardBundle\Entity\Team" mapped-by="players">
<join-table name="team_user">
<join-columns>
<join-column name="team_id" referenced-column-name="id"/>
</join-columns>
<inverse-join-columns>
<join-column name="user_id" referenced-column-name="id"/>
</inverse-join-columns>
</join-table>
</many-to-many>
<one-to-many field="my_friends" target-entity="Friend" mapped-by="friends_of_mine" />
<one-to-many field="friended_me" target-entity="Friend" mapped-by="friends_with_me" />
</entity>
Is the type of the field "file" missing?

Inheritance with POCO entities in Entity Framework 4

I have a Consumer class and a BillableConsumer : Consumer class. When trying to do any operation on my "Consumers" set, I get the error message "Object mapping could not be found for Type with identity Models.BillableConsumer.
From the CSDL:
<EntityType Name="BillableConsumer" BaseType="Models.Consumer">
<Property Type="String" Name="CardExpiratoin" Nullable="false" />
<Property Type="String" Name="CardNumber" Nullable="false" />
<Property Type="String" Name="City" Nullable="false" />
<Property Type="String" Name="Country" Nullable="false" />
<Property Type="String" Name="CVV" Nullable="false" />
<Property Type="String" Name="NameOnCard" Nullable="false" />
<Property Type="String" Name="PostalCode" Nullable="false" />
<Property Type="String" Name="State" />
<Property Type="String" Name="StreetAddress" Nullable="false" />
</EntityType>
From the C-S:
<EntitySetMapping Name="Consumers">
<EntityTypeMapping TypeName="IsTypeOf(Models.Consumer)">
<MappingFragment StoreEntitySet="consumer">
<ScalarProperty Name="LoginID" ColumnName="LoginID" />
<ScalarProperty Name="FirstName" ColumnName="FirstName" />
<ScalarProperty Name="LastName" ColumnName="LastName" />
</MappingFragment>
</EntityTypeMapping>
<EntityTypeMapping TypeName="IsTypeOf(Models.BillableConsumer)">
<MappingFragment StoreEntitySet="billinginformation">
<ScalarProperty Name="CardExpiratoin" ColumnName="CardExpiratoin" />
<ScalarProperty Name="CardNumber" ColumnName="CardNumber" />
<ScalarProperty Name="City" ColumnName="City" />
<ScalarProperty Name="Country" ColumnName="Country" />
<ScalarProperty Name="CVV" ColumnName="CVV" />
<ScalarProperty Name="LoginID" ColumnName="LoginID" />
<ScalarProperty Name="NameOnCard" ColumnName="NameOnCard" />
<ScalarProperty Name="PostalCode" ColumnName="PostalCode" />
<ScalarProperty Name="State" ColumnName="State" />
<ScalarProperty Name="StreetAddress" ColumnName="StreetAddress" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
Is this because I did not specifically add the BillableConsumer entity to the object set? How do I do that in a POCO scenario?
If you notice in my CSDL there is a column called "CardExpiratoin" (spelling mistake in DB column name). Of course my class which was hand-coded did not have this spelling mistake.
The way I found the problem is by generating POCOs from the T4 template, seeing it worked, and working my way back from there. Hope this helps anyone with the same problem. I also wish the error was a bit clearer to begin with.
I was experiencing this problem as well, and in my case it was also because of an error in a hand written POCO class. In most of the cases, you get an informational error messages, but as it seems in some rare cases you get something vague like 'Object mapping could not be found'.
In my particular case, there were columns of type VARCHAR(1) in the database, which I incorrectly mapped to char. I didn't try char?, but mapping to string certainly resolved the problem.

Resources