laravel 5.7: RedirectResponse::__construct() problem - laravel-5.7

[larvel 5.7] Argument 2 passed to
Symfony\Component\HttpFoundation\RedirectResponse::__construct() must
be of the type int, array given, called in
C:\xampp\htdocs\ecole\vendor\laravel\framework\src\Illuminate\Routing\Redirector.php
on line 203

namespace App\Http\Middleware;
use Illuminate\Http\Request;
use Fideloper\Proxy\TrustProxies as Middleware;
class TrustProxies extends Middleware
{
/**
* The trusted proxies for this application.
*
* #var array
*/
protected $proxies;
/**
* The headers that should be used to detect proxies.
*
* #var string
*/
protected $headers = Request::HEADER_X_FORWARDED_ALL;
}

Related

Get serialization context groups in controller

I have the problem that depending on user rights, there are different context groups used, and I can't find the place where the context groups are set.
For debugging issues I'm searching an possibility to find out which serialization context group an api call is using. This is my code:
<?php
namespace AppBundle\Controller\Api\Upload;
use AppBundle\Entity\Upload\UploadRepository;
use AppBundle\Entity\Upload\UploadType;
use AppBundle\Entity\Upload\UploadTypeRepository;
use Doctrine\ORM\ORMException;
use GuzzleHttp\Psr7\UploadedFile;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
use ApiPlatform\Core\Annotation\ApiResource;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use AppBundle\General\Registry;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Serializer\Normalizer\DataUriNormalizer;
use AppBundle\Entity\Upload\Upload;
use AppBundle\Entity\Application\ApplicationData;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\Serializer\Serializer;
/**
* Class UploadController
*
* #package AppBundle\Controller\Api\Upload
*
* #ApiDoc()
* #ApiResource(attributes={"pagination_enabled"=true})
*/
class UploadController extends Controller
/**
* Get an upload.
*
* #ApiDoc(
* resource=true,
* description="gets an upload",
* )
* #Route(
* name="getUploadSpecial",
* path="/fileuploads/{id}",
* defaults={"_api_resource_class"=Upload::class, "_api_item_operation_name"="getUpload"}
* )
* #Method("GET")
*
* #param Upload $data
*
* #return null|string
*
*/
public function getUploadAction($data)
{
// here I'd like to return the serialization context group
return $data;
}
Is there the possibility to get the serialization context group in the controller?
Well, it seems, the controller isn't the right place to find it.
It is better to dump in
src/Serializer/JsonEncoder.php in function encode, right before the return like this:
/**
* {#inheritdoc}
*/
public function encode($data, $format, array $context = [])
{
dump($data, $context);die;
return $this->jsonEncoder->encode($data, $format, $context);
}

The service X does not implement the EventSubscriberInterface

For some reason I get an exception that my class SerializeListener does not implement the class EventSubscriberInterface. The SerializeListener called as a service on preSerialize.
As you can see the interface is implemented and the function of the interface aswell:
Full exception:
RuntimeException: The service "acme.serializelistener" (class: Acme\DemoBundle\EventListener\SerializeListener) does not implement the EventSubscriberInterface.
Config.yml
services:
json_formatter:
class: Monolog\Formatter\JsonFormatter
acme.serializelistener:
class: Acme\DemoBundle\EventListener\SerializeListener
tags:
- { name: jms_serializer.event_subscriber }
EventSubscriberInterface
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien#symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\EventDispatcher;
/**
* An EventSubscriber knows himself what events he is interested in.
* If an EventSubscriber is added to an EventDispatcherInterface, the manager invokes
* {#link getSubscribedEvents} and registers the subscriber as a listener for all
* returned events.
*
* #author Guilherme Blanco <guilhermeblanco#hotmail.com>
* #author Jonathan Wage <jonwage#gmail.com>
* #author Roman Borschel <roman#code-factory.org>
* #author Bernhard Schussek <bschussek#gmail.com>
*
* #api
*/
interface EventSubscriberInterface
{
/**
* Returns an array of event names this subscriber wants to listen to.
*
* The array keys are event names and the value can be:
*
* * The method name to call (priority defaults to 0)
* * An array composed of the method name to call and the priority
* * An array of arrays composed of the method names to call and respective
* priorities, or 0 if unset
*
* For instance:
*
* * array('eventName' => 'methodName')
* * array('eventName' => array('methodName', $priority))
* * array('eventName' => array(array('methodName1', $priority), array('methodName2'))
*
* #return array The event names to listen to
*
* #api
*/
public static function getSubscribedEvents();
}
SerializeListener:
<?php
namespace Acme\DemoBundle\EventListener;
use JMS\Serializer\EventDispatcher\PreSerializeEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class SerializeListener implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return array(
array('event' => 'serializer.pre_serialize', 'method' => 'onPreSerialize'),
);
}
public function onPreSerialize(PreSerializeEvent $event)
{
var_dump($event);
}
}
You should implement the JMS\Serializer\EventDispatcher\EventSubscriberInterface instead of Symfony\Component\EventDispatcher\EventSubscriberInterface. See the JMSSerializerBundle's RegisterEventListenersAndSubscribers DIC compiler pass.

How to access to Doctrine Document Manager from Doctrine Entity Repository

I have a doctrine entity User and a document Address (stored in mongoDB). I want to set an one to many relation between them by userId property. (the user has many addresses)
My User Entity:
namespace BlaBla\UserBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #var integer
*/
private $id;
/**
* #var string
*/
private $firstName;
... and so on
My Address document:
namespace BlaBla\UserBundle\Document;
/**
* BlaBla\UserBundle\Document\Address
*/
class Address
{
/**
* #var MongoId $id
*/
protected $id;
/**
* #var string $firstName
*/
protected $firstName;
/**
* #var string $lastName
*/
protected $lastName;
/**
* #var int $userId
*/
protected $userId;
... and so on
My goal is to create the getUser() method for the Address object and the getAddresses() method for the User object.
I've decided to place the method getAddresses() to the doctrine UserRepository class and to inject there the necessary document manager to be able to access to the Address Document. I've overriden the constructor of the userRepository and passed to it the necessary document manager object.
Please, look to the UserRepository class:
<?php
namespace BlaBla\UserBundle\Repository;
use Doctrine\ORM\EntityRepository;
class UserRepository extends EntityRepository
{
/**
* #var \Doctrine\ODM\MongoDB\DocumentManager
*/
private $_dm;
/**
* #param \Doctrine\ORM\EntityManager $dm
*/
public function __construct(\Doctrine\ORM\EntityManager $em, $dm) {
$metaData = new \Doctrine\ORM\Mapping\ClassMetadata('BlaBla\UserBundle\Entity\User');
parent::__construct($em, $metaData);
$this->_dm = $dm;
}
/**
* #param $user_id integer
* #return \BlaBla\UserBundle\Document\Address
*/
public function getAddress($user_id) {
$address = $this->_dm->getRepository('BlaBlaUserBundle:Address');
$rt = $address->findByUserId($user_id);
return $rt;
}
public function getAllUsers()
{
return $this->findAll();
}
}
After this I can access to the repository from my controller via:
$em = $this->getDoctrine()->getManager();
$dm = $this->get('doctrine_mongodb')->getManager();
$t = new \BlaBla\UserBundle\Repository\UserRepository($em, $dm);
var_dump($t->getAddress($id));
var_dump($t->getAllUsers());
Both methods work just fine, but now I can't access to the repository using shortcuts like:
$user = $this->getDoctrine()->getRepository('BlaBlaUserBundle:User');
I thought about making the Repository as service with something like this:
user.repository:
class: BlaBla\UserBundle\Repository\UserRepository
arguments: [#doctrine.orm.entity_manager, #doctrine.odm.mongo_db.document_manager]
in my services.yml file, but this only lets me to access the repository with:
$this->get('user.repository');
the default shortcuts doesn't work still.
Please help to find a correct solution for this problem.
Thanks.
Where did you specified the UserRepository? In your User.php with annotation ? Maybe that is the only thing what is missing.
But if you want to use entity and document repository, I advise you to use Doctrine extensions, specifically Reference.

Update another field on slug creation using DoctrineExtensios

I'm using DoctrineExtensions in my Symfony 2 project, i have a simple Entity class where i'm using Sluggable on a property, then i would like to set the value to another property based on the slug, but, even when using Lifecycle Callbacks #ORM\PrePersist, #ORM\PreFlush, at this time the slug property still empty, meaning no slug is generated yet, here is my class, to keep this short, i'm not going to put here the get and set function of each property, just the part of the class that are important for this example(please, read the comments)
<?php
namespace My\LearnBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* Banner
*
* #ORM\Table(name="banner")
* #ORM\HasLifecycleCallbacks()
*/
class Banner {
/**
* #var integer
*
* #ORM\Column(name="id", type="bigint", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=128, nullable=false)
* #Assert\NotBlank()
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="slug", type="string", length=256, nullable=false)
* #Gedmo\Slug(fields={"name"})
*/
private $slug;
/**
* #var string
*
* #ORM\Column(name="tracking_url", type="string", length=256, nullable=false)
*/
private $trackingUrl;
/**
* Set slug
*
* #param string $slug
* #return Banner
*/
public function setSlug($slug) {
$this->slug = $slug;
$this->trackingUrl = $slug."/tracking"; //Doesn't work
return $this;
}
/**
* Set trackingUrl value
*
* #ORM\PreUpdate
*/
public function setTrackingUrlValue() {
//the slug is empty. Doesn't work
$this->trackingUrl = $this->slug."/tracking";
return $this;
}
/**
* Set trackingUrl value
*
* #ORM\PreFlush
*/
public function setTrackingUrlValueOnFlush() {
//the slug is empty. Doesn't work
return $this->setTrackingUrlValue();
}
}
What i've tried? well, using the setSlug function but it doesn't work(note comments on example above), seems it is not called. Using Lifecycle Callbacks #ORM\PrePersist, #ORM\PreFlush and #ORM\PreUpdate, doesn't work neither.
Now i solved this in the controller, after calling flush on the EntityManager, setting the property value based on the slug and calling flush again, so, making 2 database query in a single request, one for insert, one for update. I don't want to use an Event Listener because this behavior is just for this particular entity, or exist a way to attach an event listener to a single entity?.
But right now, i would like to know:
why what i was trying to do using Lifecycle Callbacks didn' work?
Why using the setSlug function didn't work?
A cleaner way to accomplish what i want?
thanks
What's probably happening is that the annotated listeners have a higher priority than the one creating the slug (or they have an equal priority in which case the annotated ones get probably added before).
I'm afraid you have to ditch annotations, create an actual listener and tag it for the event registration compiler pass to pick it up. What's nasty with this one is that the bundle seems to use onFlush for creating the slug (code).
Listener
namespace Acme\DemoBundle\Listener;
use Acme\DemoBundle\Model\TrackingUrlUpdateable;
use Doctrine\ORM\Event\OnFlushEventArgs;
class TrackingUrlUpdater
{
public function onFlush(OnFlushEventArgs $eventArgs)
{
$em = $eventArgs->getEntityManager();
$uof = $em->getUnitOfWork();
// Let's process both types of entities in a single loop.
$entities = array_merge(
$uof->getScheduledEntityInsertions(),
$uof->getScheduledEntityUpdates()
);
foreach ($entities as $entity) {
// Using a fictional interface (e.g. for making testing easier).
if (!($entity instanceof TrackingUrlUpdateable)) {
continue;
}
// `Banner::updateTrackingUrl()` would internally change the
// tracking url to the correct one.
$entity->updateTrackingUrl();
// The change-set must be recomputed as its fields were modified
// in the previous step.
$uof->recomputeSingleEntityChangeSet(
$em->getClassMetadata(get_class($entity)),
$entity
);
}
}
}
Registration
What's left now is to register the listener with a lower priority than the Sluggable listener.
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:doctrine="http://symfony.com/schema/dic/doctrine">
<services>
<service id="acme.listener.tracking_url" class="Acme\DemoBundle\Listener\TrackingUrlUpdater">
<tag name="doctrine.event_listener" event="onFlush" priority="-1" />
</service>
</services>
</container>
Oh, and don't forget to test!
Assuming you're using StofDoctrineExtensionsBundle to integrate the library, the alternative would be to increase the priority of the sluggable listener so that your annotated callbacks would get invoked after the sluggable listener.
A compiler pass would probably do the trick.
namespace Acme\DemoBundle\DependencyInjection\CompilerPass;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class SluggableListenerPriorityChangingPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$id = 'stof_doctrine_extensions.listener.sluggable';
$tag = 'doctrine.event_subscriber';
$definition = $container->getDefintion($id);
$attributes = $definition->getTag($tag);
if (!$attributes) {
throw new \LogicException("The listener (`$id`) must have a `$tag` tag.");
}
$attributes['priority'] = 10;
$definition
->clearTag($tag);
->addTag($tag, $attributes)
;
}
}
The sluggable listener service itself is registered here, if its enabled from the configuration.

JMS Serializer Deserialize with abstract parent class

I have an abstract parent (mapped super-)class which has several children with different properties which I'd like to deserialize.
I'm storing the data using MongoDB and Doctrine ODM, so I also have a discriminator field which tells doctrine which subclass is used (and also have a custom "type" property ontop which is used elsewhere to determine which class is currently processed).
When deserializing my model, I get an exception telling me that its impossible to create an instance of an abstract class (ofcourse) - now I'm wondering how I can tell the JMS Deserializer which inherited class it should use (that is why I use a custom type instance variable for example - because I have no access to doctrine's discriminator field mapping).
I can successfully hook into the preDeserializeEvent- so maybe it is possible to make some switch/cases there (or using the )?
My Model in short (abstract class):
<?php
namespace VBCMS\Bundle\AdminBundle\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
use JMS\Serializer\Annotation as Serializer;
/**
* abstract Class Module
* #Serializer\AccessType("public_method")
* #MongoDB\MappedSuperclass
* #MongoDB\InheritanceType("SINGLE_COLLECTION")
* #MongoDB\DiscriminatorField(fieldName="_discriminator_field")
* #MongoDB\DiscriminatorMap({
* "module"="Module",
* "text_module"="TextModule",
* "menu_module"="MenuModule",
* "image_module"="ImageModule"
* })
*/
abstract class Module {
const TYPE_MODULE_TEXT = 'module.text';
const TYPE_MODULE_MENU = 'module.menu';
const TYPE_MODULE_MEDIA_ITEM = 'module.media.item';
/**
* #Serializer\Type("string")
* #MongoDB\Field(type="string")
* #var String
*/
protected $type;
/**
* #Serializer\Type("boolean")
* #MongoDB\Field(type="boolean")
* #var boolean
*/
protected $visible;
// getter/setter methods etc..
}
?>
One of the subclasses
<?php
namespace VBCMS\Bundle\AdminBundle\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
use JMS\Serializer\Annotation as Serializer;
/**
* Class TextModule
* #package VBCMS\Bundle\AdminBundle\Document
* #Serializer\AccessType("public_method")
* #MongoDB\EmbeddedDocument
*/
class TextModule extends Module {
const TEXT_TYPE_SPLASH_HEADLINE = 'splashscreen.headline';
const TEXT_TYPE_SPLASH_SUBLINE = 'splashscreen.subline';
/**
* the actual text
*
* #var string
* #Serializer\Type("string")
* #MongoDB\Field(type="string")
*/
protected $text;
/**
* how it is called in the admin interface
*
* #var string
* #Serializer\Type("string")
* #MongoDB\Field(type="string")
*/
protected $label;
/**
* #var string
* #Serializer\Type("string")
* #MongoDB\Field(type="string")
*/
protected $textType;
// getter/setter methods etc..
?>
Another test was to not make the Module class abstract and to create a custom static method
/**
*
* #Serializer\HandlerCallback("json", direction="deserialization")
* #param JsonDeserializationVisitor $visitor
*/
public static function deserializeToObject(JsonDeserializationVisitor $visitor)
{
// modify visitor somehow to return an instance of the desired inherited module class??
}
any ideas?
I found a discriminator mapping in the Tests directory of the plugin, unfortunately, this is not yet documented: https://github.com/schmittjoh/serializer/blob/master/tests/JMS/Serializer/Tests/Fixtures/Discriminator/Vehicle.php
Documentation is updated http://jmsyst.com/libs/serializer/master/reference/annotations#discriminator
namespace JMS\Serializer\Tests\Fixtures\Discriminator;
use JMS\Serializer\Annotation as Serializer;
/**
* #Serializer\Discriminator(field = "type", map = {
* "car": "JMS\Serializer\Tests\Fixtures\Discriminator\Car",
* "moped": "JMS\Serializer\Tests\Fixtures\Discriminator\Moped",
* })
*/
abstract class Vehicle
{
/** #Serializer\Type("integer") */
public $km;
public function __construct($km)
{
$this->km = (integer) $km;
}
}

Resources