Laravel user_id forign key not working - foreign-keys

I am new to Laravel and I have multiple registration types I have tried to add a foreign key following the aravel 5.2 documentation and it keeps giving me errors any help would be greatly appreciated. I need to connect the registration of each type of user into the different registration types. Below I will post one of the three registration types that I have. If there is a way to only add the user information to the user table after there email has been verified that would be great. So in other words each registration (3x) I need them to fill out registration and only the user table info goes to the user table the rest would go to the other table but I want to two to be connected.
This is the migration file I am trying to get to work following the laravel 5.2 documents.
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->boolean('active')->default(false);
$table->rememberToken();
$table->timestamps();
$table->foreign('user_id')->references('id')->on('artists');
$table->foreign('user_id')
->references('id')->on('artists')
//->onUpdate('cascade')
->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('users');
//$table->dropForeign('artists_user_id_foreign');
}
}
I also tried doing the same thing on the artists table and it did not work either keep getting a foreign constraint issue.
Ill need to do that process for each type of user account.
The controller is set up like this for artist
<?php
namespace App\Http\Controllers\Artist;
use App\User;
use App\Artist;
use App\Mailers\AppArtMailer;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class RegistrationController extends Controller
{
//protected $redirectTo = 'art';
/** Create a new registration instance.
*/
public function __construct()
{
//$this->middleware('artist');
}
/** show the Register page/
*
* #return \Response
*/
public function register()
{
return view('art.register');
}
/**
* Perform the registration.
*
* #param Request $request
* #param AppMailer $mailer
* #return \Redirect
*/
public function postRegister(Request $request, AppArtMailer $mailer)
{
//Validate
$this->validate($request, [
'name' => 'required',
'email' => 'required|email|unique:artists',
'password' => 'required'
]);
//create artist
$artist = Artist::create($request->all());
$user = User::create($request->all());
//email them
$mailer->sendEmailConfirmationTo($artist);
//$mailer->sendEmailConfirmationTo($user);
//flash
flash('Please confirm your email address.');
// redirect
return redirect()->back();
}
/**
* Confirm a user's email address.
*
* #param string $token
* #return mixed
*/
public function confirmEmail($token)
{
Artist::whereToken($token)->firstOrFail()->confirmEmail();
flash('You are now confirmed. Please login');
return redirect('artist');
}
}
I also followed the laracast ACL Roles and Permissions but am not sure how to integrate that into each of the user registrations so that each type automatically has the set roles.
Here are the different models I have each is a bit different since I am learning and playing.

Artist Model This will actually change since they can only be an artist if they are a viewer.
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Authenticatable;
use Illuminate\Auth\Passwords\CanResetPassword;
use App\Http\Middleware\RedirectIfAuthenticatedArtist;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
class Artist extends Model implements AuthenticatableContract, CanResetPasswordContract
{
protected $table = 'artists';
use Authenticatable, CanResetPassword;
/**
* The database table used by the model.
*
* #var string
*/
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* Boot the model.
*
* #return void
*/
public static function boot()
{
parent::boot();
static::creating(function($artist) {
$artist->token = str_random(30);
});
}
/**
* Set the password attribute.
*
* #param string $password
*/
public function setPasswordAttribute($password)
{
$this->attributes['password'] = bcrypt($password);
}
/**
* Confirm the user.
*
* #return void
*/
public function confirmEmail()
{
$this->verified = true;
$this->token = null;
$this->save();
}
}
This is my users model
<?php
namespace App;
use DB;
use Illuminate\Http\Response;
use App\Http\Controllers;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\File;
use Cmgmyr\Messenger\Traits\Messagable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use HasRoles, Messagable;
//* The attributes that are mass assignable.
//*
// * #var array
// */
protected $fillable = [
'name', 'email', 'password',
];
public function setPasswordAttribute($password)
{
$this->attributes['password'] = bcrypt($password);
}
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
// $user->roles
}
Sponsors Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Authenticatable;
use Illuminate\Auth\Passwords\CanResetPassword;
//use App\Http\Middleware\RedirectIfAuthenticatedSponsor;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
class Sponsor extends Model implements AuthenticatableContract, CanResetPasswordContract
{
protected $table = 'sponsors';
use Authenticatable, CanResetPassword;
/**
* The database table used by the model.
*
* #var string
*/
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* Boot the model.
*
* #return void
*/
public static function boot()
{
parent::boot();
static::creating(function($sponsor) {
$sponsor->token = str_random(30);
});
}
/**
* Set the password attribute.
*
* #param string $password
*/
public function setPasswordAttribute($password)
{
$this->attributes['password'] = bcrypt($password);
}
/**
* Confirm the user.
*
* #return void
*/
public function confirmEmail()
{
$this->verified = true;
$this->token = null;
$this->save();
}
}
Viewer Model
<?php
namespace App;
use Illuminate\Auth\Authenticatable;
use Cmgmyr\Messenger\Traits\Messagable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use App\Http\Middleware\RedirectIfAuthenticatedViewer;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
class Viewer extends Model implements AuthenticatableContract, CanResetPasswordContract
{
protected $redirectTo = 'viewer';
use Authenticatable, CanResetPassword, Messagable;
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'viewers';
//protected $table = 'experience';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function experience()
{
return $this->hasOne('App\Experience');
}
public function awardExperience($points)
{
return $this->experience->award($points);
}
/**
* Boot the model.
*
* #return void
*/
public static function boot()
{
parent::boot();
static::creating(func

Related

How to use Entities Classes from Different Locations in CodeIgniter 4 using Doctrine 2

I am using CodeIgniter 4.x for my project. In my approach, I am using Module system for my project. My Module system is like below structure:
- App
- Modules
- ListMaster
- User
- Models
- Doctrine
- Entities
- User.php
- UserApp.php
- UserGroup
- Models
- Doctrine
- Entities
- Usergroup.php
- Budget
- Models
- Doctrine
- Entities
- Budget.php
In a simple word, I have designed to have my Modules under App/Modules folder. This Folder could consist a Module folder or a folder which will hold Modules. As I created two Modules App/Modules/ListMaster/User and App/Modules/ListMaster/Usergroup. My Entity Class Files will be located under ...Models/Doctrine/Entities folders.
I have downloaded Doctrine using Composer. My Composer is as follow:
{
"require": {
"doctrine/orm": "^2.3.3",
"doctrine/dbal": "^3.2",
"doctrine/annotations": "^1.14",
"symfony/yaml": "^5.4",
"symfony/cache": "^5.4"
},
"autoload": {
"psr-0": {"": "src/"}
},
}
I have created a Library file under App/Libraries which is as follow:
<?php
namespace App\Libraries;
//WE INCLUDING THE AUTOLOAD VENDOR
include_once dirname(__DIR__, 2) . '/vendor/autoload.php';
use Doctrine\Common\ClassLoader;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Tools\Setup;
// TO OBTAIN THE ENTITY MANAGER
class Doctrine
{
public $em;
public function __construct()
{
// Retrieving all paths leading to entities classes
$modulePath = APPPATH."Models/Doctrine/Entities";
$entitiesPath = glob($modulePath, GLOB_ONLYDIR);
$modulePath = APPPATH."Modules/*/Models/Doctrine/Entities";
$entitiesPath = array_merge($entitiesPath, glob($modulePath, GLOB_ONLYDIR));
$modulePath = APPPATH."Modules/*/*/Models/Doctrine/Entities";
$entitiesPath = array_merge($entitiesPath, glob($modulePath, GLOB_ONLYDIR));
$isDevMode = true;
$cache = null;
$useSimpleAnnotationReader = false;
// CONNECTION SETUP
$config = config("Database");
$connection_options = array(
'driver' => strtolower($config->doctrine['DBDriver']),
'user' => $config->doctrine['username'],
'password' => $config->doctrine['password'],
'dbname' => $config->doctrine['database'],
'host' => $config->doctrine['hostname']
);
$proxies_dir = APPPATH . 'Models/Doctrine/Proxies';
$config = Setup::createAnnotationMetadataConfiguration($entitiesPath, $isDevMode, $proxies_dir, $cache, $useSimpleAnnotationReader);
if (ENVIRONMENT === 'development') {
$config->setAutoGenerateProxyClasses(true);
} else {
$config->setAutoGenerateProxyClasses(false);
}
try {
$this->em = EntityManager::create($connection_options, $config);
} catch (\Doctrine\ORM\ORMException $e) {
log_message("Doctrine Exception : ", $e);
}
}
}
As you can see from this, My Entities files will be at Models/Doctrine/Entities, Modules/{any folder}/Models/Doctrine/Entities, Modules/{any folder}/{any folder}/Models/Doctrine/Entities folders.
Now here is my sample Entities Class:
<?php
namespace entities;
use Doctrine\ORM\Mapping as ORM;
/**
* User
*
* #ORM\Table(name="user")
* #ORM\Entity
*/
class User
{
/**
* #var smallint $id
*
* #ORM\Column(name="id", type="smallint", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* #var string $userName
*
* #ORM\Column(name="user_name", type="string", length=150, nullable=true)
*/
protected $userName;
/**
* Constructor
*/
public function __construct()
{
}
/**
* Get id
*
* #return boolean
*/
public function getId()
{
return $this->id;
}
/**
* Set userName
*
* #param string $userName
*/
public function setUserName($userName)
{
$this->userName = $userName;
}
/**
* Get userName
*
* #return string
*/
public function getUserName()
{
return $this->userName;
}
}
Now from my Controller I am executing this Line of code which produces entities\User class not found error. Though this structure can create and update Schema in Database successfully.
$users = $this->em->getRepository('entities\User')->findAll();
Please be noted that I have successfully Generate Proxy, Generate Entities, Crate Schema, Update Schema from this installation.
Thanks in Advance. Please let me know if I missed something to inform you.
So my question is, How to fix the class not found error and got result from Database from any table?

Symfony 4 > filter a list of results, the best way

I'm working on a new Symfony 4 project.
I have a list of Speakers, and a list of Themes, and I have a ManyToMany relations between.
class Speakers
{
// ...
/**
* #ORM\ManyToMany(targetEntity="App\Entity\Themes", inversedBy="speakers")
* #ORM\JoinTable(name="speakers_themes")
*/
private $themes;
/**
* Speakers constructor.
*/
public function __construct()
{
$this->themes = new ArrayCollection();
}
/**
* #return Collection|Themes[]
*/
public function getThemes(): Collection
{
return $this->themes;
}
/**
* #param Themes $theme
* #return Speakers
*/
public function addTheme(Themes $theme): self
{
if (!$this->themes->contains($theme)) {
$this->themes[] = $theme;
}
return $this;
}
/**
* #param Themes $theme
* #return Speakers
*/
public function removeTheme(Themes $theme): self
{
if ($this->themes->contains($theme)) {
$this->themes->removeElement($theme);
}
return $this;
}
}
class Themes
{
// ...
/**
* #ORM\ManyToMany(targetEntity="App\Entity\Speakers", mappedBy="themes")
*/
private $speakers;
/**
* Themes constructor.
*/
public function __construct()
{
$this->speakers = new ArrayCollection();
}
/**
* #return Collection|Speakers[]
*/
public function getSpeakers(): Collection
{
return $this->speakers;
}
/**
* #param Speakers $speaker
* #return Themes
*/
public function addSpeaker(Speakers $speaker): self
{
if (!$this->speakers->contains($speaker)) {
$this->speakers[] = $speaker;
$speaker->addTheme($this);
}
return $this;
}
/**
* #param Speakers $speaker
* #return Themes
*/
public function removeSpeaker(Speakers $speaker): self
{
if ($this->speakers->contains($speaker)) {
$this->speakers->removeElement($speaker);
$speaker->removeTheme($this);
}
return $this;
}
I want to be able to filter the list of speakers, depending of the themes.
Since the list of themes is short (3 items), I thought of a select box, with the possibility of choosing a theme to filter.
But I don't know what's the best way to do this:
Build a specific form, to filter ?
class SpeakersFilterType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('themes', EntityType::class,
[
'class' => Themes::class,
'multiple' => true,
'expanded' => true
])
->add('save', SubmitType::class,
[
'label' => 'Filter'
]);
}
/**
* #param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(
[
'method' => Request::METHOD_GET,
// 'data_class' => null,
'data_class' => Speakers::class,
]
);
}
}
I tried to build a form like you can see below.
In the configureOptions method, I specify the method to GET, and I was hoping that I can pass some get params to filter but it's not working.
I have an error:
The form's view data is expected to be an instance of class App\Entity\Speakers, but is a(n) array. You can avoid this error by setting the "data_class" option to null or by adding a view transformer that transforms a(n) array to an instance of App\Entity\Speakers.
If I follow the advice and put the option 'data_class' to null, I dont have an error but I'm not sure It's working, regarding the strange params it sends to the URL:
http://127.0.0.1:8000/speakers/?speakers_filter%5Bthemes%5D%5B%5D=2&speakers_filter%5Bsave%5D=&speakers_filter%5B_token%5D=ClBi9xzMrkM72niXNnkbMi1i-3gWMQ2sgfIxY0M1Pi8
Can somebody can help ? Thank you so much from a Symfony newbie.

Embedding Relations In Results

I'm using API-Platform to deliver content via API. I have a Potential relationship between users and participants (not all users will have participants but all participants will have at least one user). My main goal is to embed the relationship's User data in the result set of Participants as that result will be consumed by a data table and it would be more efficient to have that data already present within the result opposed to performing an additional request for the data.
e.g.:
{
"#context": "/api/contexts/Participants",
"#id": "/api/participants",
"#type": "hydra:Collection",
"hydra:member": [
{
"#id": "/api/participants/1",
"#type": "Participants",
"id": 1,
"name": "Jeffrey Jones",
"users": [
{
"#id": "/api/users/1",
"#type": "User",
"name": "Jenny Jones"
},
{
"#id": "/api/users/2",
"#type": "User",
"name": "Jessie Jones"
}
]
}
],
"hydra:totalItems": 1
}
However, I'm not sure if this is possible. I have looked at https://api-platform.com/docs/core/serialization#embedding-relations but I am not certain it would work for multiple result sets as the example is one book to one author. However, my scenario is one participant to multiple users.
Also (and I may need to go about this in a more direct manner), I'm using a joining table so that I can assign additional metadata to the relationship. So... participants > joint table (containing additional data) > users (and vice versa). Again, I may need to consider having a direct relationship between participants and users and then using a ParticipantUserMeta table to hold the additional metadata. However, at the moment, I'm leaning towards the join table containing the association as well as the additional metadata.
Here are the basics of my entities (most unnecessary data omitted):
User:
/**
* #ApiResource
* ...
*/
class User implements UserInterface, \Serializable
{
/**
* #var int
*
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #var string
* #ORM\Column(type="string")
* #Assert\NotBlank()
*/
private $name = '';
/**
* #ORM\OneToMany(targetEntity="App\Entity\ParticipantRel", mappedBy="user")
*/
private $participants;
public function __construct()
{
$this->participants = new ArrayCollection();
}
public function getId(): int
{
return $this->id;
}
public function getName(): string
{
return $this->name;
}
/**
* #return Collection|ParticipantRel[]
*/
public function getParticipants(): Collection
{
return $this->participants;
}
}
ParticipantRel:
/**
* #ApiResource
* ...
*/
class ParticipantRel
{
/**
* #var int The Participant Id
*
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #var int
*
* #ORM\Column(type="boolean")
*/
private $primary_contact;
/**
* #var string Relationship notes
*
* #ORM\Column(type="text", nullable=true)
*/
private $notes;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Participants", inversedBy="users")
* #ORM\JoinColumn(nullable=false)
*/
private $participant;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="participants")
* #ORM\JoinColumn(nullable=false)
*/
private $user;
public function getId (): int
{
return $this->id;
}
public function getPrimaryContact(): ?bool
{
return $this->primary_contact;
}
public function getNotes(): ?string
{
return $this->notes;
}
public function getParticipant(): ?Participants
{
return $this->participant;
}
public function getUser(): ?User
{
return $this->user;
}
}
Participants
/**
* #ApiResource
* ...
*/
class Participants
{
/**
* #var int The Participant Id
*
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #var string Participant's first name
*
* #ORM\Column(name="name")
* #Assert\NotBlank
*/
public $name;
/**
* #ORM\OneToMany(targetEntity="App\Entity\ParticipantRel", mappedBy="participant")
*/
private $users;
public function __construct() {
$this->users = new ArrayCollection();
}
public function getId (): int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
/**
* #return Collection|ParticipantRel[]
*/
public function getUsers(): Collection
{
return $this->users;
}
}
My question: Is what I'm attempting possible within an entity and if so, what am I missing? I have researched this a lot before coming here but haven't come up w/ any solution as most of the solutions I see involve a Twig tpl but I'm simply sending the data via api-platform. Any positive direction would be greatly appreciated.
So, it turns out that I just needed to experiment more w/ the Groups option (https://api-platform.com/docs/core/serialization#embedding-relations). Associating all related fields w/ the relative groups on all relative enities did end up returning the results in the desired format.

Doctrine 2 ZF3 self referencing entity is not updating all fields of parent

I have a self referencing entity with parent and children. The strange thing is, when I add the form elements (DoctrineModule ObjectSelect) for parent and children to the form, some other fields of the parent entity doesn't update, when I persist the entity. The child entities are updating fine.
In the update query of the parent aren't these fields which I want to update. It's like doctrine doesn't recognize the changes for the parent (owning side) anymore. Before the persist I get the right entity with the actual changes from the form, but than doctrine doesn't update the changed fields in the query.
When I delete the form elements for parent and children in the form, everything works fine and the parent entity update/persist all fields.
/**
* #var string
*
* #Gedmo\Translatable
* #ORM\Column(type="text")
*/
private $teaser;
/**
* #var string
*
* #Gedmo\Translatable
* #ORM\Column(type="text")
*/
private $description;
/**
* One Category has Many Categories.
* #var Collection
* #ORM\OneToMany(targetEntity="Rental\Entity\Rental", mappedBy="parent")
*/
private $children;
/**
* Many Categories have One Category.
* #ORM\ManyToOne(targetEntity="Rental\Entity\Rental", inversedBy="children")
* #ORM\JoinColumn(name="parent_id", referencedColumnName="houses_id", nullable=true, onDelete="SET NULL")
*/
private $parent;
public function __construct()
{
$this->children = new ArrayCollection();
}
/**
* Get teaser
*
* #return string
*/
public function getTeaser()
{
return $this->teaser;
}
/**
* Set teaser
*
* #param string $teaser
*/
public function setTeaser($teaser)
{
$this->teaser = $teaser;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set description
*
* #param string $description
*/
public function setDescription($description)
{
$this->description = $description;
}
/**
* Add $child
* #param Collection $children
*/
public function addChildren(Collection $children)
{
foreach ($children as $child) {
$this->addChild($child);
}
}
/**
* #param Rental $child
* #return void
*/
public function addChild(Rental $child)
{
if ($this->children->contains($child)) {
return;
}
$child->setParent($this);
$this->children[] = $child;
}
/**
* Remove children
* #param Rental $children
*/
public function removeChildren(Collection $children)
{
foreach ($children as $child) {
$this->removeChild($child);
}
}
/**
* Remove child.
*
* #param \Rental\Entity\Rental $child
*
* #return boolean TRUE if this collection contained the specified element, FALSE otherwise.
*/
public function removeChild(Rental $child)
{
return $this->children->removeElement($child);
}
/**
* Get children.
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getChildren()
{
return $this->children;
}
/**
* Set parent.
*
* #param \Rental\Entity\Rental|null $parent
*/
public function setParent(Rental $parent = null)
{
$this->parent = $parent;
}
/**
* Get parent.
*
* #return \Rental\Entity\Rental|null
*/
public function getParent()
{
return $this->parent;
}
Answer based (and might still change) based on discussion in comments with OP under question.
Simple use case: self-referencing Doctrine Entity does not correctly update parent/child related Entity object properties on on-save action.
OP provided Entity.
I'm assuming you have a Form setup for this Entity. I'm also assuming it's correctly setup, as you did not provide it after being asked (because, rightly so, it would mean a lot of code). However, assuming stuff with code makes for a lot of mistakes, which is why I mention it here.
As such, I'm assuming the handling of your Form in the Controller might be faulty. To check, please use the following simplified addAction function and give it a shot (Factory code below).
/**
* #var RentalForm
*/
protected $form;
/**
* #var ObjectManager
*/
protected $objectManager;
public function __construct(ObjectManager $objectManager, RentalForm $form)
{
$this->form = $form;
$this->objectManager = $objectManager;
}
public function addAction()
{
/** #var RentalForm $form */
$form = $this->getForm();
/** #var Request $request */
$request = $this->getRequest();
if ($request->isPost()) {
$form->setData($request->getPost());
if ($form->isValid()) {
$entity = $form->getObject();
$this->getObjectManager()->persist($entity);
try {
$this->getObjectManager()->flush();
} catch (\Exception $e) {
$message = sprintf(
'Was unable to save the data. Saving threw an error. <br />Code: %s. <br />Message: %s',
$e->getCode(),
$e->getMessage()
);
$this->flashMessenger()->addErrorMessage($message);
return [
'form' => $form,
'validationMessages' => $form->getMessages() ?: '',
];
}
$this->flashMessenger()->addSuccessMessage(
$this->getTranslator()->translate('Successfully created object.')
);
// TODO replace vars with your own: return $this->redirect()->route($route, $routeParams);
}
$this->flashMessenger()->addWarningMessage(
'Your form contains errors. Please correct them and try again.'
);
}
return [
'form' => $form,
'validationMessages' => $form->getMessages() ?: '',
];
}
Factory for class with the above, modify as needed for you situation
class RentalControllerFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
/** #var ObjectManager $objectManager */
$objectManager = $container->get(EntityManager::class);
/** #var FormElementManagerV3Polyfill $formElementManager */
$formElementManager = $container->get('FormElementManager');
/** #var RentalForm $form */
$form = $formElementManager->get(RentalForm::class);
return new RentalController($objectManager, $form);
}
}

upload not running with VichUploaderBundle

I would like to use a VichUploaderBundle for upload files in my symfony 3.2.3 project (PHP 5.6). I try lot of thing but nothing upload run. But the persistance layer run perfeclty with my database.
config.yml
knp_gaufrette:
stream_wrapper: ~
adapters:
fileupload_adapter:
local:
directory: %kernel.root_dir%/../web/
create: true
filesystems:
fileupload_fs:
adapter: fileupload_adapter
# VichUploaderBundle Configuration
vich_uploader:
db_driver: orm
twig: true
storage: gaufrette
mappings:
tgmedia_file:
uri_prefix: web
upload_destination: fileupload_fs
namer: vich_uploader.namer_origname
Entity
namespace MediaBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use TweedeGolf\MediaBundle\Model\AbstractFile;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
/**
* #ORM\Entity
* #Vich\Uploadable
* #ORM\HasLifecycleCallbacks
* #ORM\Table
*/
class FileUpload
{
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* NOTE: This is not a mapped field of entity metadata, just a simple property.
*
* #Vich\UploadableField(mapping="tgmedia_file", fileNameProperty="imageName")
*
* #var File
*/
protected $imageFile;
/**
* #ORM\Column(type="string", length=255)
*
* #var string
*/
private $imageName;
/**
* #ORM\Column(type="datetime")
*
* #var \DateTime
*/
protected $updatedAt;
/**
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* #return File|null
*/
public function getImageFile()
{
return $this->imageFile;
}
/**
* If manually uploading a file (i.e. not using Symfony Form) ensure an instance
* of 'UploadedFile' is injected into this setter to trigger the update. If this
* bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
* must be able to accept an instance of 'File' as the bundle will inject one here
* during Doctrine hydration.
*
* #param File|\Symfony\Component\HttpFoundation\File\UploadedFile $image
*
* #return Product
*/
public function setImageFile(File $image = null)
{
$this->imageFile = $image;
if ($image) {
// It is required that at least one field changes if you are using doctrine
// otherwise the event listeners won't be called and the file is lost
$this->updatedAt = new \DateTimeImmutable();
}
return $this;
}
/**
* #param string $imageName
*
* #return FileUpload
*/
public function setImageName($imageName)
{
$this->imageName = $imageName;
return $this;
}
/**
* #return string|null
*/
public function getImageName()
{
return $this->imageName;
}
/**
* Set updatedAt
*
* #param \DateTime $updatedAt
*
* #return FileUpload
*/
public function setUpdatedAt($updatedAt)
{
$this->updatedAt = $updatedAt;
return $this;
}
/**
* Get updatedAt
*
* #return \DateTime
*/
public function getUpdatedAt()
{
return $this->updatedAt;
}
}
The formType
<?php
namespace MediaBundle\Form;
use MediaBundle\Entity\File;
use MediaBundle\Entity\FileUpload;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Vich\UploaderBundle\Form\Type\VichFileType;
use Vich\UploaderBundle\Form\Type\VichImageType;
class FileUploadType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('imageName')
->add('imageFile', VichImageType::class, [
'required' => false,
'allow_delete' => true,
'download_link' => true,
'mapped' => false,
'data_class' => null
])
->add('submit', SubmitType::class);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => FileUpload::class,
'csrf_protection' => false,
));
}
}
Controller
<?php
namespace MediaBundle\Controller;
use MediaBundle\Entity\File;
use MediaBundle\Entity\FileUpload;
use MediaBundle\Entity\Product;
use MediaBundle\Form\FileType;
use MediaBundle\Form\FileUploadType;
use MediaBundle\Form\ProductType;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
class MainController extends Controller
{
public function indexAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$fileUploaded = new FileUpload();
$form = $this->createForm(FileUploadType::class, $fileUploaded, array(
'action' => $this->generateUrl('media_main')
));
$form->handleRequest($request);
if ($form->isSubmitted())
{
$fileUploaded->setUpdatedAt(new \DateTime());
$fileUploaded->setImageFile($form->get('imageFile')->getData());
$em->persist($fileUploaded);
$em->flush();
}
return $this->render('MediaBundle:main:index.html.twig', array(
'form' => $form->createView()
));
}
}
Where is my error ? What wrong ?
uri_prefix: /project/web/fileupload_fs
upload_destination: '%kernel.root_dir%/../web/fileupload_fs'
uri_prefix begins from www folder.
and change controller like that
if ($form->isSubmitted() && $form->isValid())
{
$em->persist($fileUploaded);
$em->flush();
}