Api-Platform IriConverter Symfony context - symfony

My service (a console command) is receiving the IRI strings as arguments (I have this requirement, instead using the ids, that would be way more simple). So I have injected the ApiPlatform's IriConverter to my service, but when I call its getItemFromIri method I'm getting this error:
The token storage contains no authentication token. One possible reason may be that there is no firewall configured for this URL.
My Service:
use ApiPlatform\Core\Api\IriConverterInterface;
....
$context= []; // don't know what to include here
$iri= '/api/v4/files/448';
$file = $this->iriConverter->getItemFromIri($iri, $context);
My security.yml
firewalls:
apiV4:
pattern: ^/api/v4
stateless: true
fos_oauth: true
My Class
/**
* File
* #ApiResource(
* attributes={
* "normalization_context"={"groups"={"fileUpload"}}
* },
* collectionOperations = {
* "get",
* "post" ={
* "method"="POST",
* "path"="/files",
* "controller"= UploadFileAction::class,
* "defaults"={"_api_receive"=false},
* }
* }
* )
*
* #ORM\Table(name="UploadedFile")
*
*/
class File
{
/**
* #var int
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #Groups({"fileUpload"})
*/
private $id;
/**
* #var string
* #Assert\NotBlank
* #ORM\Column(name="name", type="string", length=255)
* #Groups({"fileUpload"})
*/
private $name;
....

Related

Api Platform 2.5: execute collectionOperations only when the current entity is nested

I started using API Platform after having a good documentation and watching a professionnel tutoriel, and now I encountered a problem.
I have two entities User & Role, the Role is nested in User.
I want to disable direct operations on Role, I want only when I post a User with Role, the post operation works but when I post directly on Role /api/roles, the post operation have to be disabled.
User:
/**
* #ApiResource(
* normalizationContext={
* "groups"={"get"}
* },
* itemOperations={
* "get"={
* "security"="is_granted('IS_AUTHENTICATED_ANONYMOUSLY')",
* "normalization_context"={
* "groups"={"get"}
* }
* },
* "put"= {
* "security"="is_granted('IS_AUTHENTICATED_ANONYMOUSLY') or is_granted('IS_AUTHENTICATED_FULLY') and object.getAuthor() == user",
* "denormalization_context"={
* "groups"={"put"}
* }
* }
* },
* collectionOperations={
* "get"={
* "security"="is_granted('IS_AUTHENTICATED_ANONYMOUSLY')"
* },
* "post"={
* "security"="is_granted('IS_AUTHENTICATED_ANONYMOUSLY')",
* "denormalization_context"={
* "groups"={"user:post"}
* }
* }
* }
* )
* #ORM\Entity(repositoryClass="App\Repository\UserRepository")
*
* #UniqueEntity(fields={"username","email"})
*/
class User implements UserInterface
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*
* #Groups({"get","get_comment_with_author","get_post_with_comments"})
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*
* #Groups({"get","user:post","get_comment_with_author","get_post_with_comments"})
*/
private $username;
/**
* #ORM\Column(type="string", length=255)
*
* #Groups({"put","user:post","get_comment_with_author","get-to-admin"})
*/
private $email;
/**
* #ORM\ManyToMany(targetEntity="Role", fetch="EAGER")
* #Groups({"put","user:post"})
*/
private $rolesCollection;
Role:
/**
* #ApiResource()
* #ORM\Entity(repositoryClass="App\Repository\RoleRepository")
*/
class Role
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
* #Groups({"user:post"})
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $label;
You can disable operations (but the get operation) like this:
/**
* #ApiResource(
* collectionOperations={"get"},
* itemOperations={"get"}
* )
* #ORM\Entity(repositoryClass="App\Repository\RoleRepository")
*/
class Role
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
* #Groups({"user:post"})
*/
private $id;
...
}
Now you can only read the Roles, but not create or edit them.

Symfony2/FOSRestbundle ignoring serialization groups (for array of results)

Serialization groups work for me fine when i fetch one entity but
when i try fetch array of results i got empty result set.
I do this like that:
* #\FOS\RestBundle\Controller\Annotations\View(serializerGroups={"client"})
but also tried manually set context on view object, and same situation.
When i don't set group or set to "Default":
* #\FOS\RestBundle\Controller\Annotations\View(serializerGroups={"Default"})
i got proper serialized result set.
My entity:
use JMS\Serializer\Annotation as JMS;
[...]
/**
* Document
*
* #ORM\Table(name="documents")
* #ORM\Entity(repositoryClass="AppBundle\Entity\DocumentRepository")
* #ORM\EntityListeners({"DocumentListener"})
* #JMS\ExclusionPolicy("all")
* #JMS\AccessorOrder("custom", custom = {"id", "folderId", "title"})
*/
class Document implements ResourceInterface
{
/**
* #var integer
*
* #ORM\Column(type="integer", name="id")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #JMS\Groups({"client"})
* #JMS\Expose()
*/
protected $id;
/**
* #var string
*
* #ORM\Column(type="text", name="description")
* #JMS\Groups({"client"})
* #JMS\Expose()
*/
protected $description;
[...]
and my controller:
// not working
/**
* #\FOS\RestBundle\Controller\Annotations\View(serializerGroups={"client"})
* #return Paginator
* #Get("/documents")
*/
public function documentsAction(ParamFetcher $params)
{
[...]
return ($this->getPaginator(
$params,
$documentBundle->get()
));
}
//works fine
/**
* Get document
*
* #QueryParam(name="id", requirements="\d+", nullable=false)
* #param ParamFetcher $params
* #\FOS\RestBundle\Controller\Annotations\View(serializerGroups={"client"})
*/
public function documentAction(ParamFetcher $params)
{
/** #var DocumentRepository $documentBundle */
$documentBundle = $this->getDoctrine()->getRepository('AppBundle:Document');
return $documentBundle->findByDocumentId($params->get('id'));
}
PS.
fosrestbundle 1.7.9
jmsserializer 0.16.0

payum symfony 2 bundle - basic configuration - storage

I need to configure the payum bundle in order to let clients process paypal payments.
I just followed the getting started official recomendations, but need to configure something more, I guess (maybe I am missing to configure the storage for PaymentDetails somewhere).
my config files are as follows:
**app/config.yml**
doctrine:
orm:
auto_generate_proxy_classes: true
entity_managers:
default:
mappings:
WebsiteDeviceBundle: ~
WebsiteOnePageBundle: ~
payum:
is_bundle: false
type: xml
dir: %kernel.root_dir%/../vendor/payum/payum/src/Payum/Core/Bridge/Doctrine/Resources/mapping
prefix: Payum\Core\Model
payum:
security:
token_storage:
Website\Bundle\DeviceBundle\Entity\PaymentToken: { doctrine: orm }
storages:
Website\Bundle\DeviceBundle\Entity\PaymentDetails: { doctrine: orm }
contexts:
express_euro:
paypal_express_checkout_nvp:
username: ''
password: ''
signature: ''
sandbox: true
this is my controller action to start the payment process
public function prepareAction(){
$paymentName = 'express_euro';
$storage = $this->get('payum')->getStorage('Website\DeviceBundle\Entity\PaymentDetails');
$order = $storage->createModel();
$order->setNumber(uniqid());
$order->setCurrencyCode('EUR');
$order->setTotalAmount($this->view['user']->money);
$order->setDescrizione('annual account subscription');
$order->setUser($this->view['user']->getId());
$order->setCreatedAt(new \DateTime());
$order->setClientEmail($this->view['user']->getEmail());
$storage->updateModel($order);
$captureToken = $this->get('payum.security.token_storage')->createCaptureToken(
$paymentName,
$order,
'done' // the route to redirect after capture;
);
return $this->redirect($captureToken->getTargetUrl());
}
and this is PaymentDetails class
<?php
namespace Website\Bundle\DeviceBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Payum\Core\Model\ArrayObject;
/**
* PaymentDetails
*
* #ORM\Table(name="PaymentDetails", indexes={#ORM\Index(name="user", columns={"user"})})
* #ORM\Entity(repositoryClass="Website\Bundle\DeviceBundle\Entity\PaymentsDetailsRepository")
*/
class PaymentDetails extends ArrayObject
{
/**
* #var string
*
* #ORM\Column(name="currency_code", type="string", length=255, nullable=false)
*/
private $currencyCode;
/**
* #var string
*
* #ORM\Column(name="description", type="text", nullable=true)
*/
private $description;
/**
* #var \DateTime
*
* #ORM\Column(name="created_at", type="datetime", nullable=true)
*/
private $createdAt;
/**
* #var integer
*
* #ORM\Column(name="number", type="integer", nullable=false)
*/
private $number;
/**
* #var integer
*
* #ORM\Column(name="total_amount", type="integer", nullable=false)
*/
private $totalAmount;
/**
* #var string
*
* #ORM\Column(name="client_email", type="text", nullable=false)
*/
private $clientEmail;
/**
* #var integer
*
* #ORM\Column(name="id", type="bigint")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var \Website\Bundle\DeviceBundle\Entity\Users
*
* #ORM\ManyToOne(targetEntity="Website\Bundle\DeviceBundle\Entity\Users")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="user", referencedColumnName="id")
* })
*/
private $user;
and the error it comes when I GET the doneAction() url, is this
A storage for model Website\DeviceBundle\Entity\PaymentDetails was not registered. There are storages for next models: Website\Bundle\DeviceBundle\Entity\PaymentDetails.
any helps or suggestions?
thank you in advance
just changed this line
$storage = $this->get('payum')->getStorage('Website\DeviceBundle\Entity\PaymentDetails');
into
$storage = $this->get('payum')->getStorage('Website\Bundle\DeviceBundle\Entity\PaymentDetails');
and now it works.

JMS Serializer doesn't expose one property

I making a RESTful app with Symfony and FOSRestBundle. FOSRestBundle uses JMS Serializer to serialize data to json format. I have everything working with one little issue.
This is my Entity class
/**
* Post
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="Tomalo\AdminBundle\Entity\PostRepository")
* #ExclusionPolicy("none")
*/
class Post
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="content", type="text")
* #Assert\NotBlank()
*/
private $content;
/**
* #var float
*
* #ORM\Column(name="lat", type="float")
* #Assert\NotBlank()
*/
private $lat;
/**
* #var float
*
* #ORM\Column(name="lon", type="float")
* #Assert\NotBlank()
*/
private $lon;
/**
* #var \DateTime
*
* #ORM\Column(name="date", type="datetime")
*/
private $date;
/**
* #var string
*
* #ORM\Column(name="sign", type="string", length=50, nullable=true)
* #Expose
*/
private $sign;
/**
* #var integer
*
* #ORM\Column(name="status", type="integer")
*/
private $status=0;
/**
* #var integer
*
* #ORM\Column(name="points", type="integer")
*/
private $points=0;
/**
* #var string
*
* #ORM\Column(name="uuid", type="string", length=43)
* #Assert\NotBlank()
* #Exclude
*/
private $uuid;
private $owner;
//get/set method continue
and this is json I get:
{
"id": 5,
"content": "zxcvzxcvzxc",
"lat": 37.422005,
"lon": -122.084095,
"date": "2013-05-20T05:06:57+0100",
"status": 0,
"points": 0,
"owner": 0
}
In my entity $uuid is the only property haveing #Exclude annotation and is not there as expected but there is $sign property missing as well. As You see I put #Expose annotation to $sign but changed nothing. I tried using #ExclusionPolicy("all") and expose all except for uuid but I'm getting
Warning: json_encode(): recursion detected in E:\workspace\htdocs\tomalo\vendor\jms\serializer\src\JMS\Serializer\JsonSerializationVisitor.php line 29
I found some information as it is some php bug
any idea what is wrong and how to fix it?
You can serialize nulls as empty strings. Guess it help you a bit
$context = new SerializationContext();
$context->setSerializeNull(true);
$objectData = $serializer->serialize($object, 'json', $context);
For FOSRestBundle you can define it in settings
fos_rest:
view:
serialize_null: true
forgottenbas'es solution for FOSRestBundle didn't work for me. I have found a solution here https://github.com/FriendsOfSymfony/FOSRestBundle/pull/480
Use serializer section in your config, not view:
fos_rest:
serializer:
serialize_null: true

How to display data for particular username from database?

On my index page are displayed different users. What i want to achieve is when someone click on the username to be redirected on other page where are displayed informations for the user.
Here is part of the twig code which will redirect the user to the hello route.
{% for user in users %}
<strong><em> {{ user.username}}
And this is hello route :
hello:
pattern: /hello
defaults: {_controller:AcmeWebBundle:Default:hello }
I have no idea how to implement this in the contoroler. Can i use variable in which are stored informations for the users from other function or i need to make db query? And how that query to be for particular user who is displayed? In addition is part from the entity. Thanks.
<?php
namespace Acme\Bundle\WebBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* baza
*
* #ORM\Table()
* #ORM\Entity
*/
class baza
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="username", type="string", length=30)
*/
private $username;
/**
* #var string
*
* #ORM\Column(name="password", type="string", length=30)
*/
private $password;
/**
* #var string
*
* #ORM\Column(name="od", type="string", length=30)
*/
private $od;
/**
* #var string
*
* #ORM\Column(name="do", type="string", length=30)
*/
private $do;
/**
* #var float
*
* #ORM\Column(name="cena", type="float")
*/
private $cena;
/**
* #var string
*
* #ORM\Column(name="comment", type="text")
*/
private $comment;
/**
* #var integer
*
* #ORM\Column(name="rating", type="integer")
*/
private $rating;
/**
* #var \DateTime
*
* #ORM\Column(name="date", type="date")
*/
private $date;
/**
* #var string
*
* #ORM\Column(name="car", type="string", length=20)
*/
private $car;
Try this in your template:
{% for user in users %}
<strong><em><a href="{{ path('hello', {"id": user.id}</a>
and this in your routing:
hello:
pattern: /hello/{id}
and your controller will have something like:
public function helloAction(Request $request, $id)
then in your controller retrieve the user by id. This and the rest of it is can be inferred in the book.
Hope this helps

Resources