Alice Faker library choose random from array - symfony

I am trying to generate a dummy data using AliceBundle for Symfony Framework. Everything seems to be working fine except I am looking for a way to randomly assign data from an array to a property called type. Looking at the faker library I can see that I can generate that using randomElement($array = array ('a','b','c'))
I am trying to convert that into YML and I think that is equivalent of
<randomElement(['a','b','c'])>
But this produces an error
[Nelmio\Alice\Throwable\Exception\FixtureBuilder\ExpressionLanguage\LexException]
Could not lex the value "['a'".
This is my complete yml
AppBundle\Entity\Job:
job{1..5}:
title: <jobTitle()>
description: <paragraph(3)>
length: "3_months_full_time"
type: <randomElement(['a','b','c'])>
bonus: <paragraph(3)>
expired_at: "2016-12-21"
job_user: "#emp*"

This works for me:
parameters:
profileArray: ['PUBLIC', 'PRIVATE', 'AUTHENTICATED']
JobPlatform\AppBundle\Entity\Profile:
profiles_{1..100}:
user: '#user_<current()>'
visibility: <randomElement($profileArray)>

I ended up creating a custom provider
namespace AppBundle\DataFixtures\Faker\Provider;
class JobTypeProvider
{
public static function jobType()
{
$types = array("paid", "unpaid", "contract");
$typeIndex = array_rand($types);
return $types[$typeIndex];
}
}
Add that to services.yml
app.data_fixtures_faker_provider.job_type_provider:
class: AppBundle\DataFixtures\Faker\Provider\JobTypeProvider
tags: [ { name: nelmio_alice.faker.provider } ]
And then use it in yml file
AppBundle\Entity\Job:
job{1..50}:
title: <jobTitle()>
description: <paragraph(3)>
length: <jobLength()>
job_industry: "#title*"
type: <jobType()>
bonus: <paragraph(3)>
expired_at: "2016-12-21"
job_user: "#emp*"
Notice type: , this is being generated from service now.

Related

add a virtual property in easy-admin bundle

I'm currently working with the 2.3 version of the easy-admin bundle in Symfony 4.
I try to create a virtual property for the new view.
I have the following configuration
#config/packages/easy_admin.yaml
easy_admin:
entities:
Field:
class: App\Entity\Field
form:
fields:
- { type: tab, label: initial information, icon: pencil-alt }
- name
new:
fields:
- { property: toto, type: file }
and my entity file:
//src/Entity/Field.php
/**
* #ORM\Entity(repositoryClass="App\Repository\FieldRepository")
*/
class Field
{
public function setToto(?File $file): self
{
$this->setImage(new Image);
$this->getImage()->setImageFile($file);
}
as explain in the documentation the setter should be sufficient.
but when I reach the new page I get the following error:
Neither the property "toto" nor one of the methods "getToto()", "toto()", "isToto()", "hasToto()", "__get()" exist and have public access in class "App\Entity\Field".
which means that the page is looking for getter and not setter. Is it normal or did I make something wrong ?
I have just ran into this issue and I have solved it by adding the getter.
As you said, it is looking for getter but also setter.

Use a reference to the same object inside an object

I'm trying to do something like this:
User:
type: "object"
properties:
id:
type: "integer"
format: "int64"
name:
type: "string"
manager:
$ref: "/definitions/User"
Editor does not throw an exception, but the code generated according to this schema does not work at all.
I generated python-flask server, and on launch, it throws:
ImportError: cannot import name 'User'
Looking through the code I found that 'User' class uses 'User' keyword in __init__ and inside the class.
Also there was the import: from swagger_server.models.user import User
Does python-flask generator know how to implement references like this?

How to use "$ref" reference and declare components from Swagger in API platform?

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"
* }

Empty relations when serializing with JMSSerializer

I am having troubles while writing a controller-action inside a Symfony project, that should return data (in this particular case orders of a web-shop). Yeah ... It's a kind of a REST-API. That route just get's called from some JavaScript. And the data has to be visualized on the client-side.
The Problem:
I cannot find out, why the serialization of related entities results in empty objects. In this example it is the user of an order, which is empty.
This is a sample output:
orders: [
{
id: 2,
created: '2016-05-04T11:40:27+00:00',
user: {},
}
]
When I do something like
$orders = $this->getDoctrine()->getRepository('AppBundle:Order')
->findAllCompleted();
$serializationContext->setSerializeNull(true);
$serializationContext->setGroups(['statistics']);
$json = $serializer->serialize($orders, 'json', $serializationContext);
$response = new Response($json, $statusCode, [
'Content-Type' => 'application/json',
]);
return $response;
... i get a nice JSON response from the server, but every related entity of each order, like let's say user is {} (empty).
Even if I dump the related entity before it gets serialized like so:
[...]
$myOrder = array_filter($orders, function($order) {
if ($order->getId() == 2) {
return true;
}
return false;
});
dump($myOrder[0]->getUser());
die();
... it results in an empty (unhydrated) entity.
But if I change this debugging code to:
$myOrder = array_filter($orders, function($order) {
if ($order->getId() == 2) {
return true;
}
return false;
});
dump($myOrder[0]->getUser()->getUsername());
die();
... I get a clear output (string) with the value of the username of that entity.
So I think the issue is about a non hydrated entity, and not the serializer or its wrong configuration.
How can I get the JMSSerializer to take care of the hydration of those related entities?
I didn't find any hint in the docs ...
BTW, this are the JMS entity configs of order and user.
AppBundle\Entity\User:
exclusion_policy: ALL
properties:
userMeta:
expose: true
address:
expose: true
username:
expose: true
email:
expose: true
isReseller:
expose: true
acceptPublicOrders:
expose: true
vatNumber:
expose: true
taxRate:
expose: true
AppBundle\Entity\Order:
exclusion_policy: NONE
properties:
id:
groups: ['statistics']
user:
groups: ['statistics']
configuration:
groups: ['statistics']
created:
groups: ['statistics']
invoiceItems:
groups: ['statistics']
exclude: true
I think your problem is caused by doctrine lazy loading maybe you can try to change the fetch mode of the User association to EAGER in your Order entity
#ManyToOne(targetEntity="Cart", cascade={"all"}, fetch="EAGER")
By default i think it doesn't fetch the associations unless you call it directly like you did here
dump($myOrder[0]->getUser()->getUsername());
https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/annotations-reference.html#annref-onetoone
Or this if you use DQL
14.7.6.6. Temporarily change fetch mode in DQL
http://doctrine-orm.readthedocs.io/en/latest/reference/dql-doctrine-query-language.html#temporarily-change-fetch-mode-in-dql
Edit : i was wrong
I made some tests everything worked fine with lazy loading or eager until i tried with groups, even if the fields are exposed you don't use the Default group so it only take the things with the 'statistics' group on it
Try to add the default group here
$serializationContext->setGroups(['Default','statistics']);
Or add the statistics group on your user fields both worked for me

FOSElasticaBundle: Setting analyzer for custom properties

I am using the FOSElasticaBundle in Symfony 3.3. I have registered an event listener on the POST_TRANSFORM event that computes and adds a custom property like this:
public function addCustomProperty(TransformEvent $event)
{
$document = $event->getDocument();
$custom = $this->anotherService->calculateCustom($event->getObject());
$document->set('custom', $custom);
}
Now I need to set the analyzer to be used for this property. How can I do that?
I already tried to add the custom field name to the type definition in my fos_elastica config but that causes an exception as the bundle then expects that property on my entity as well.
I finally found out that I could use dynamic_templates to set the desired analyzer like this:
fos_elastica:
indexes:
app:
types:
myentity:
dynamic_templates:
custom_field:
path_match: customfield.*
mapping:
analyzer: myanalyzer
properties:
...

Resources