I have an entity Customer that i want to have both Hatoas Links and custom serialization
/**
* Customer ORM Entity
*
* #package AppBundle\Entity
*
* #Hateoas\Relation("self", href = #Hateoas\Route("get_customers", parameters = { "customer" = "expr(object.getId())" }))
* #Hateoas\Relation("customers", href = #Hateoas\Route("cget_customers"))))
*/
That is the annotation for the hateoas links
AppBundle\Entity\Customer:
exclusion_policy: ALL
virtual_properties:
getFullName:
serialized_name: full_name
type: string
That is my yaml configuration for the jms serialization but for some reason it also remove the hateoas links.
How can i get it back? Tell to the serializer to not remove the _links property?
In Hateoas documentation it says:
Important: you must configure both the Serializer and Hateoas the same way. E.g. if you use YAML for configuring Serializer, use YAML for configuring Hateoas.
For example, use the YAML format for configuration and your issue should be solved.
As #takeit say, you should use the same configuration used with the serializer. For your example try this:
AppBundle\Entity\Customer:
exclusion_policy: ALL
virtual_properties:
getFullName:
serialized_name: full_name
type: string
relations:
-
href:
route: get_customers
parameters:
customer: expr(object.getId())
# absolute: 0
customers:
route: cget_customers
Hope this help
Related
We can define components in Swagger:
components:
schemas:
User:
properties:
id:
type: integer
name:
type: string
And use this component later:
responses:
'200':
description: The response
schema:
$ref: '#/components/schemas/User'
I want to use this in order to avoid duplicating content.
I try to use this syntax in API Platform:
components:
schemas:
Part:
description: Array of Part
type: array
items:
type: object
properties:
name:
type: string
App\Entity\Item:
collectionOperations:
post:
method: 'POST'
swagger_context:
parameters:
- name: body
description: Item data
in: body
schema:
type: object
properties:
name:
description: Part
type: string
required: true
part:
$ref: '#/components/schemas/Part'
It gives me an error:
Exception thrown when handling an exception (Symfony\Component\Config\Exception\FileLoaderLoadException: Resource "components" not found in . (which is being imported from "/app/config/routes/api_platform.yaml"). Make sure there is a loader supporting the "api_platform" type.)
It looks like the YAML loader doesn't recognize the components item.
How can I define and use references in API Platform? How can I define a reference and use it in several YAML files?
You cannot do that like this.
The components key belongs to the Swagger/OpenAPI format, not to the API Platform configuration (mapping) format. Both API Platform configuration files and Swagger definitions can be written in YAML, but they are not related.
So, as the error message describes, Swagger components cannot be injected in API Platform's configuration files directly, as you try to do.
API Platform's configuration does allow allows to inject some context in the generated Swagger file using the swagger_context key, but you cannot write random Swagger definitions (such as your component key) outside of this structure.
To do what you want to achieve the swagger_context key will not be enough (components must be injected at the root of the Swagger file, and it's not possible with swagger_context).
Instead of using this key, you'll have to create a decorator for the Swagger documentation generator, as explained in this documentation entry: https://api-platform.com/docs/core/swagger/#overriding-the-swagger-documentation
Decorator allows to access to the whole Swagger structure, and to modify it. So you'll be able to add your components structure.
It possible ... See How can I annotate my attribute which is Value Object in order that API Platform would generate its fields for swagger documentation?
In my exemple, I have the entity Checker, I created two groups :
* #ApiResource(
* attributes={
* "normalization_context"={"groups"={"read"}},
* "denormalization_context"={"groups"={"write"}},
* },
Then in the swagger_context responses :
* "responses" = {
* "201" = {
* "description" = "....",
* "schema" = {
* "type" = "object",
* "properties" = {
* "myresult" = {
* "$ref"="#/definitions/Checker-read"
* }
I am using this in config.yml:
# JMSSerializer Configuration
jms_serializer:
#parameters:
#jms_serializer.camel_case_naming_strategy.class: JMS\Serializer\Naming\IdenticalPropertyNamingStrategy
metadata:
cache: file
debug: "%kernel.debug%"
file_cache:
dir: "%kernel.cache_dir%/serializer"
auto_detection: true
directories:
AppBundle:
namespace_prefix: "AppBundle"
path: "%kernel.root_dir%/config/serializer/AppBundle"
And this in Entity.Category.yml:
AppBundle\Entity\Category:
exclusion_policy: ALL
But when i try to send request, i receive this error:
Expected metadata for class AppBundle\Entity\Category to be defined
in /var/www/test/app/config/serializer/AppBundle/Entity.Category.yml.
How can I solve this issue?
You forgot about TAB at 2 line.
It looks like you are getting an incorrect path to your project files with %kernel.root_dir%. Make sure that /var/www/test/app is the correct path to your project. Check your PHP __DIR__ constant and try replacing `%kernel.root_dir% with what that says as well as what you think the path should be.
Also, instead of defining your exclusion policy in a config file you should just be able to annotate your entity like so and expose things as needed:
use JMS\Serializer\Annotation as JMS;
/**
* Class ExampleEntity
*
* #JMS\ExclusionPolicy("all")
* #ORM\Entity()
*/
class ExampleEntity
{
}
JMS annotations are found here.
I want to split up my documentation for the api I am building. I am using NelmioApiDocBundle and they have a perfect way with the view annotation. Nelmio view The problem is my method stays in default view and not in the suggested oauth view:
So /doc/api/oauth/ or /api/doc/oauth ends in 404
//config.yml
# app/config/config.yml
nelmio_api_doc: ~
// app/config/routing.yml
NelmioApiDocBundle:
resource: "#NelmioApiDocBundle/Resources/config/routing.yml"
prefix: /api/doc
// routing.yml
profile_rest_oauth:
resource: "#ProfileBundle/Rest/Oauth/RestController.php"
type: rest
prefix: /api/oauth
profile_rest:
resource: "#ProfileBundle/Rest/Xwsse/RestController.php"
type: rest
prefix: /api
//RestController
use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\Controller\Annotations;
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
use Symfony\Component\HttpFoundation\Request;
class RestController extends FOSRestController
{
/**
* #ApiDoc(
* description="Update profile for user",
* section="profile",
* https=true,
* statusCodes={
* 200="OK, user profile updated",
* 400="Wrong input, no update"
* },
* views = { "oauth" }
* )
*/
public function putProfileAction(Request $request)
{
}
//composer.json
"nelmio/api-doc-bundle": "2.7.0",
To answer my own question: the version "2.7.0" in not compatible with the view parameter you need atleast 2.9.0". It's hard to understand it from the symfony documentation because it show version 2.x symfony documentation
Looks good man. At least i can say if you set up everything right - the /api/doc/oauth should never give you 404.
Try to change both your
resource: "#ProfileBundle/Rest/Xwsse/RestController.php"
to this like
resource: "#ProfileBundle/Resources/config/routing.yml"
I have got logging working on my entity so that when I make a change to a product field with the #Gedmo\Versioned annotation a new version is created. However the only problem is that the username field remains NULL. There is an authenticated user as the update is performed in Sonata Admin backend.
<?php
namespace MyApp\CmsBundle\Entity\Log;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Loggable\Entity\MappedSuperclass\AbstractLogEntry;
use Gedmo\Loggable\Entity\Repository\LogEntryRepository;
/**
* #ORM\Entity(repositoryClass="Gedmo\Loggable\Entity\Repository\LogEntryRepository", readOnly=true)
* #ORM\Table(
* name="log_product",
* indexes={
* #ORM\Index(name="log_class_lookup_idx", columns={"object_class"}),
* #ORM\Index(name="log_date_lookup_idx", columns={"logged_at"}),
* #ORM\Index(name="log_user_lookup_idx", columns={"username"}),
* }
* )
*/
class ProductLog extends AbstractLogEntry
{
}
So it would appear the log_user_lookup_idx isn't working correctly, is there a particular bit of config I require for this?
It appears I was missing a bit of config, adding the following to the main app/config/config.yml file did the trick.
stof_doctrine_extensions:
default_locale: en
orm:
default:
loggable: true
I did originally have this in my bundles' services.yml config:
gedmo.listener.loggable:
class: Gedmo\Loggable\LoggableListener
tags:
- { name: doctrine.event_subscriber, connection: default }
calls:
- [ setAnnotationReader, [ "#annotation_reader" ] ]
This managed to track the entity being modified but not the user, I have since removed this config and the logging remains to work with just the stof_doctrine_extensions config setting.
If you have both in your code base then everything will be logged twice I found.
In a nutshell
I'm writing a Symfony2 / Doctrine2 app and have installed and configured the Translatable extension provided by StofDoctrineExtensionsBundle using YAML, however no additional translation table(s) are generated and the following exception is thrown when attempting to work with entities that have translatable properties:
No mapping file found named '/var/www/my-project/vendor/gedmo/doctrine-extensions/lib/Gedmo/Translatable/Entity/Translation.orm.yml' for class 'Gedmo\Translatable\Entity\Translation'.
In more detail
I'm trying to get the Translatable extension working in my Symfony2 / Doctrine2 application that is provided by the StofDoctrineExtensionsBundle, however most of the available documentation I can find mainly targets the usage of annotations for configuration, but I'm going with YAML because that's how I have configured everything else.
My configuration
I have added the following to my composer.json file and have ran the composer update command: "stof/doctrine-extensions-bundle": "dev-master" and the bundle is registered in my app/AppKernel.php file.
My app/config/config.yml file has the following configuration:
doctrine:
orm:
auto_generate_proxy_classes: %kernel.debug%
auto_mapping: true
mappings:
gedmo_translatable:
type: yml
prefix: Gedmo\Translatable\Entity
dir: "%kernel.root_dir%/../vendor/gedmo/doctrine-extensions/lib/Gedmo/Translatable/Entity"
alias: GedmoTranslatable
is_bundle: false
stof_doctrine_extensions:
default_locale: en_GB
translation_fallback: true
orm:
default:
timestampable: true
translatable: true
I have then defined an entity in YAML:
Foo\ContentBundle\Entity\Article:
type: entity
repositoryClass: Foo\ContentBundle\Repository\ArticleRepository
table: article
gedmo:
translation:
locale: locale
id:
id:
type: integer
generator: { strategy: AUTO }
fields:
name:
type: string
length: 64
gedmo:
- translatable
content:
type: text
gedmo:
- translatable
# ... #
oneToMany:
# ... #
I have then ran the console command php app/console doctrine:generate:entities FooContentBundle to generate the entity classes, and have manually added the locale property and setter:
class Article
{
/* ... */
private $locale;
public function setTranslatableLocale($locale)
{
$this->locale = $locale;
}
/* ... */
}
After running php app/console doctrine:schema:update --force, my article table is created along with its associations, but nothing relating to translations (I'm assuming a table is supposed to be created for this...)
Then, when working with an entity that is translatable, I'm getting the exception:
No mapping file found named '/var/www/my-project/vendor/gedmo/doctrine-extensions/lib/Gedmo/Translatable/Entity/Translation.orm.yml' for class 'Gedmo\Translatable\Entity\Translation'.
The YAML file that the exception is referencing does not exist in the path that it's looking for it within, neither could I find it anywhere else.
Does anyone have any ideas as to where I'm going wrong?
Update: After further investigation...
Running php app/console doctrine:mapping:info displays all of my entities and nothing relating to translations, however, if I update the gedmo_translatable: part of my app/config/config.yml file and change type: yml to type: annotation then run the command again, I get the following listed:
[OK] Gedmo\Translatable\Entity\MappedSuperclass\AbstractTranslation
[OK] Gedmo\Translatable\Entity\Translation
[OK] Gedmo\Translatable\Entity\MappedSuperclass\AbstractPersonalTranslation
At which point, I can update my schema, and I have a new ext_translations table. However, nothing is being inserted into it when working with my entities, presumably because it's now expecting configuration by annotation rather than YAML, changing my config back to type: yml starts throwing the exception again, as expected.
After trying things that the documentation suggests will not work, i.e. mixing both annotation and YAML configurations in the same bundle, it would appear I have things working. The whole thing feels like a bug or an incomplete implementation, however I may be doing something incorrectly. Here's what's working...
Setting the following in app/config/config.yml: doctrine.orm.mappings.gedmo_translatable.type: annotation
Setting the translatable configuration in my YAML schema definition as outlined in my original question, as well as as an annotation in my class file:
/* ... */
use Gedmo\Mapping\Annotation as Gedmo;
/* ... */
class Article
{
/* ... */
/**
* #Gedmo\Translatable
* #var string $name
*/
private $name;
/**
* #Gedmo\Locale
*/
private $locale;
public function setTranslatableLocale($locale)
{
$this->locale = $locale;
}
/* ... */
}
After doing this, the additional table is created and translations are being inserted into it when persisting the entity.