Laravel 4 Eloquent ORM - Symfony \ Component \ Debug \ Exception \ FatalErrorException Cannot redeclare class WorkProcess - class

Here's the scenario!!!
Schema for (work_processes)
Schema::create('work_processes', function($table){
$table->increments('id');
$table->enum('wp_type',array('M','F','D')); //M => Maintenance, F => Field, D => Drilling
$table->string('wp_name',50);
$table->integer('wp_owner_id');
$table->integer('wp_editor_id');
$table->text('wp_link');
$table->enum('wp_frequency',array('B','M','Q')); //B => Bi-Monthly, M => Monthly, Q => Quarterly
$table->date('wp_startdate');
$table->date('wp_enddate');
$table->enum('wp_active',array('Y','N'));
$table->timestamp('deleted_at')->nullable();
$table->timestamps();
});}
Schema for (wp_audit_questions)
Schema::create('wp_audit_questions', function($table){
$table->increments('id');
$table->integer('wp_id');
$table->text('wp_audit_question');
$table->timestamps();
});
Model 1 as (WorkProcess)
class WorkProcess extends Eloquent
{
protected $table = 'work_processes';
protected $guarded = array('id');
protected $softDelete = true;
public function wpauditquestions()
{
return $this->hasMany('WpAuditQuestion');
}
}
Model 2 as (WpAuditQuestion)
class WpAuditQuestion extends Eloquent
{
protected $table = 'wp_audit_questions';
public function workprocess()
{
return $this->belongsTo('WorkProcess', 'wp_id');
}
}
'Controller as (WorkProcessController)
class WorkProcessController extends BaseController
{
public function ShowWpAuditQuestionEditForm($wpid)
{
$wp = WorkProcess::with(array('wpauditquestions' => function($query){
$query->where('wp_id', $wpid);
}))->get();
return View::make('wpauditquestion')->with(array('edit_mode' => 1, 'wpauditquestion' => $wpauditquestion));
}
}
'Controller as (WpAuditQuestionController)
class WpAuditQuestionController extends BaseController
{
public function ShowWPAuditQuestionForm()
{
$wpauditquestion = new WpAuditQuestion();
return View::make('wpauditquestion', compact('wpauditquestion'));
}
}
Routes.php
//model binding
Route::model('workprocess', 'WorkProcess');
Route::model('wpauditquestion', 'WpAuditQuestion');
Route::get('wpauditquestion/edit/{wpid}', array('uses' => 'WorkProcessController#ShowWpAuditQuestionEditForm', 'as' => 'wpauditquestion.edit'));
Problem:
This script generates this error message. e.g. MY_SERVER/wpauditquestion/edit/1
Symfony \ Component \ Debug \ Exception \ FatalErrorException
Cannot redeclare class WorkProcess
however, when I don't use the get() or any other method like paginate(5) etc, it does dump some data.
I have also tried this but same result.
$wp = WorkProcess::has('wpauditquestions')->get();
can someone please guide me what wrong I'm doing. I'm using laravel 4.0.7 with WAMP.
Also please guide me how to save this model after editing it e.g. if I have a form like this.
{{ Form::open(array('action' => 'WorkProcessController#PostWorkProcessEditForm', 'method' => 'put')) }}
{{-- Work Process Name --}}
{{ Form::hidden('wp_id') }}
<ol>
#for($i = 0; $i < 5; $i++)
<p>
<li>
{{ Form::label('wp_audit_question', 'Audit Question') }}
{{ Form::text('wp_audit_question', Input::old('wp_audit_question')) }}
</p>
#endfor
</ul>
<p>{{ Form::submit('Submit Form', array('id' => 'Submit_Form')) }}</p>
{{ Form::close() }}
Thanks and Regards

Did you name your migration work_process which was turned into WorkProcess? It can be that your migration has same class name as your model.

Issue resolved! The problem was the model name 'WorkProcess' was clashing with something as I've my view name as 'workprocess.blade.php' as well. So I changed model name to 'WPModel' and its working fine now.

in case you did something like changing a class name.
Let's say you changed the class name of your model from 'users' to 'user',
You could try running the command 'composer dump-autoload'.
It worked for me though my case was not exactly the same as yours.

Related

Symfony 4 - performance issue on form with a selectbox with many options

I built a form with a selectbox (EntityType) with a big amount of choices (about 50 000) :
->add(
'destination', EntityType::class, array(
'label' => 'à',
'multiple' => false,
'required' => false,
'class' => Stop::class,
'attr' => array(
'class' => 'form-control',
)
)
);
I am facing a big performance issue : dozens of seconds before the list is displayed when I click on it.
I guess the solution would be to initially only load a few elements (e.g. a hundred), and then use Ajax to request the DB when the user starts typing (I am using a select2 box with search field).
Problem is that I cannot figure out the most efficient way to do it through Symfony.
I have seen that the choice_loader functionality could do it, but there is no detailed documentation available : https://symfony.com/blog/new-in-symfony-3-2-lazy-loading-of-form-choices
Would be great if somebody can help on this,
Thanks for your support,
When I face this kind of trouble, I use another approach.
If the select option will have more than 20 entries, so I change it to a Input Text with autocomplete.
The Steps are:
Install a good autocomplete Javascript lib like jquery-typeahead
I like to use Wepack Encore in Symfony. With Webpack, Npm and Yarn the installation is easy like
yarn add jquery-typeahead --dev
You would need to run yarn run encore dev after installation.
Create a new FieldType for your form to replace the EntityType
Lets suppose that we need to create a register form with city field. The default behaviour will use EntityType and show a Select Option with all cities.
To change it to autocomplete lets create another FieldType.
<?php
// src/Form/Type/AutocompleteCityType.php
namespace App\Form\Type;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\SearchType;
use Symfony\Component\OptionsResolver\OptionsResolver;
class AutocompleteCityType extends AbstractType
{
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'attr' => ['autocomplete' => 'off']
));
}
public function getParent()
{
return SearchType::class;
}
}
NOTE: On the code above, I am extending SearchType::class that is a Input Type Search (HTML 5).
Our new field type can be used on our forms but it is just another string field. Won't work correctly to replace EntityType. We need to convert this string to an Entity. So we need a DataTransformer
Create a City to String DataTransformer
<?php
// src/Form/DataTransformer/CityToStringTransformer.php
namespace App\Form\DataTransformer;
use App\Entity\City; // Pay attention to use your Entities correctly
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;
class CityToStringTransformer implements DataTransformerInterface
{
private $entityManager;
public function __construct(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
}
/**
* Transforms an object (City) to a string.
*
* #param City|null $city
* #return string
*/
public function transform($city)
{
if (null === $city) {
return '';
}
return $city->getSomethingUnique();
}
/**
* Transforms a string to an object (city).
*
* #param string $somethingUnique
* #return City|null
* #throws TransformationFailedException if object (city) is not found.
*/
public function reverseTransform($somethingUnique)
{
// empty City? It's optional, so that's ok
if (!$somethingUnique) {
return;
}
$city = $this->entityManager
->getRepository(City::class)
->findByThatSomethingUnique($somethingUnique);
if (null === $city) {
// causes a validation error
// this message is not shown to the user
// see the invalid_message option
throw new TransformationFailedException(sprintf(
'The city "%s" cannot be found!',
$somethingUnique
));
}
return $city;
}
}
Note: The string must be some kind of unique key to work correctly and need to be good to show on Autocomplete and fill the field (Like [CityCode] CityName). The DataTransformation cannot return more than one result on findByThatSomethingUnique() method.
Note 2 : For exemple, $city->getSomethingUnique() cant be $city->getId()."-".$city->getName() and ->findByThatSomethingUnique($somethingUnique) can be ->findOneById(explode("-", $somethingUnique)[0])
Almost done. We can use both classes on our FormType to replace EntityType.
Using on the FormType
// src/Form/MyFormType.php
// (...) Other declarations(...)
use App\Form\DataTransformer\ContactToStringTransformer;
use App\Form\Type\AutocompleteContactType;
class MyFormType extends AbstractType
{
private $cityTransformer;
public function __construct(CityToStringTransformer $cityTransformer)
{
$this->cityTransformer = $cityTransformer;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
/* #var $myEntity MyEntity */
$myEntity = $builder->getData();
$builder
->add('city', AutocompleteCityType::class, [
'label' => 'Custom City Label',
])
// (...) Other fields (...)
;
$builder->get('city')
->addModelTransformer($this->cityTransformer);
}
With the code until here, the form will be shown correctly, but the typeahead must be configured properly.
You can create a new twig block type for this new field type. The code below must reside in the your custom form_theme
The Twig block
{% block autocomplete_city_widget %}
{% spaceless %}
<div class="typeahead__container">
<div class="typeahead__field">
<div class="typeahead__query">
{{ form_widget(form) }}
</div>
</div>
</div>
{% endspaceless %}
{% endblock %}
NOTE: The Twig code above is related to jquery-typeahead and only works with a field called AutocompleteCityType. If you install another lib or change the name of FieldType class, change it properly. Also pay attention to form names that change the block name to be rendered.
The last thing is to write the javascript for typeahead get the entries.
The Typeahead Javascript
jQuery.typeahead({
input: "#myForm_city", // Related to FormName and Autocomplete Field Name
minLength: 1,
maxItem: 20,
order: "asc",
dynamic: true,
delay: 500,
backdrop: { "background-color": "#eeeeee" },
template: "<small style='color:#999;'>{{ '[{{citycode}}] {{cityname}}' }}</small>", // remember that this is a Twig template...
emptyTemplate: "No results for typed string",
source: {
city: {
display: ["citycode", "cityname"],
ajax: function (query) {
return {
type: "POST",
url: '{{ path('controller_with_city_list_json_response') }}',
path: "city",
data: {
"q": "{{ '{{query}}' }}",
"length" : "40",
},
callback: {
done: function (res) {
var d = {};
d.city = [];
jQuery(res.data).each(function(index, value) {
d.city.push(value.city);
});
return d;
}
}
}
}
}
},
callback: {
onClickAfter: function (node, a, item, event) {
event.preventDefault();
jQuery(node).val("[" + item.citycode + "] " + item.cityname);
}
},
debug: false
});
NOTE: The Typeahead code above want a json response in format
{"data":
[
{"city":
{"cityname":"City Name X", "citycode": "NXNX"}
},
{"city":
{"cityname":"City Name Y", "citycode": "NYNY"}
}
]
}

Laravel From Request Validaton doesn't show errors

My Laravel Framework is 5.4.19
I have followed the tutorial:
http://www.easylaravelbook.com/blog/2015/08/17/creating-and-validating-a-laravel-5-form-the-definitive-guide/
and created form request file tours2_create_tableRequest.php:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class tours2_create_tableRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'doc_fullnumber' => 'unique:tourists'
];
}
}
(it tests if "doc_fullnumber" from request has no duplicates in 'tourists" model)
I have added this code to the form blade.php file:
#if($errors->count() > 0 )
<div>
#foreach ($errors->all() as $error)
{{ $error }}
#endforeach
</div>
#endif
it seems to me that validation works fine (it redirects the user back to create form page when "doc_fullnumber" is not unique), but it doesn't pass $errors variable.
I've browsed Stackoverflow and found several topics with the same problem. They suggest to wrap all my routes (in web.php) in:
Route::group(['middleware' => ['web']], function () {
});
I've done it, but it doesn't help...
here is the form page, actually (temporary): http://f832ee57.ngrok.io/tours_2/create
(the "doc_fullnumber" field is the last one. You can add "2001" there to check validation).
my project on git: https://github.com/Sergey1983/first
Appreciate any help!
To make the unique rule work, you need to have `'doc_fullnumber' field in DB or you need to specify a custom name field:
'doc_fullnumber' => 'unique:tourists,custom_fullnumber_field'

Laravel 4 change form open with if else statement

I'm new to Laravel and trying some stuff out. Hope you guys can point me in the right direction.
I have a form to add categories on a the page with the overview of all the categories. Now I'm routing to the same page when you want to add or edit a category. Problem is, I want the normal add form to show when the url is category/add and when the url is category/edit/id I want it to show the form to edit (with form model binding). I placed the code in an if else statement, but it always shows the edit form, therefore if I want to add a new category on the url categories I get an error because it's the edit form.
Here's the code in the index.bade.php:
#if(Request::url() === 'categories' )
{{ Form::open(array('url' => 'category/add', 'class' => 'form-horizontal')) }}
#else
{{ Form::model($category, array(
'url' => 'category/edit/'.$category->id ,
$category->id,
'class' => 'form-horizontal'))
}}
#endif
My controller:
public function index()
{
$categories = Category::get();
$category = new Category();
View::share('title', 'Mini Blog - Categories');
$view = View::make('category.index')->with('category', $category);
$view->categories = $categories;
return $view;
}
public function edit($id)
{
$categories = Category::get();
$category = Category::find($id);
View::share('title', 'Mini Blog - Edit category');
return View::make('category.index')->with(array('category' => $category, 'categories' => $categories));
}
Is this the way to go? Or is there a better way?
Instead of checking the URL I suggest you depend on the model variable. Ever Eloquent model has a property exists that tells you if the model has been loaded from the DB or it's a new instance.
#if( ! $category->exists)
{{ Form::open(array('url' => 'category/add', 'class' => 'form-horizontal')) }}
#else
{{ Form::model($category, array(
'url' => 'category/edit/'.$category->id ,
$category->id,
'class' => 'form-horizontal'))
}}
#endif
Actually you can use Form::model with an empty model as well, so you should be able to reduce it to this:
{{ Form::model($category, array(
'url' => ($category->exists ? 'category/edit/'.$category->id : 'category/add'),
'class' => 'form-horizontal'))
}}
There is a much better way.
In your controller do this:
public function create()
{
return View::make('create');
}
public function edit($id)
{
return View::make('edit')->withId($id);
}
Then in your views you have
Create.blade.php
{{ Form::open(array('url' => 'category/add', 'class' => 'form-horizontal')) }}
#include ('form')
{{ Form::close() }}
Edit.blade.php
{{ Form::model($category, array('url' => 'category/edit/'.$category->id, category->id, 'class' => 'form-horizontal')) }}
#include ('form')
{{ Form::close() }}
Form.blade.php
//Put your HTML form stuff here

Laravel, Form::select unable to update many to many relationship

I'm new to Laravel, and I'm being dumb on this for sure, cause i've read the documentation and i've searched all over google but i'm not getting how to go over this. I have a M:M relationship between galleries and artist. Inside each gallery edit page I have a form to update the name and url for the gallery that is working fine. In the same page I have 2 other select forms, one for adding artists to the gallery and another to remove artists, that need to update a pivot table called "galleries_artists". I created 2 custom methods for both these forms called "postAdd" and "postRemove" but I can't put them to work regardless of what I try.
Below is the code i have so far. Hope somebody can help me understand the dumb mistakes i'm making.
Model - Artist.php
class Artist extends Eloquent {
protected $fillable = array('name');
public static $rules = array(
'name'=>'required|min:2'
);
public function galeries() {
return $this->belongsToMany('Gallery', 'galeries_artists', 'artist_id', 'gallery_id', 'stand_id');
}
}
Model - Gallery.php
class Gallery extends Eloquent {
protected $fillable = array('name', 'stand_id', 'url');
public static $rules = array(
'stand_id'=>'required|integer'
);
public function stand() {
return $this->belongsTo('Stand');
}
public function artist() {
return $this->belongsToMany('Artist', 'galleries_artists', 'gallery_id', 'artist_id', 'stand_id');
}
}
Controller - GalleriesController.php
public function postAdd($id, $aid) {
$input = array_except(Input::all(), '_method');
$v = Validator::make(Input::all(), Artist::$rules);
if ($v->passes()) {
$gallery = Gallery::find($id);
$add_artist = Input::get();
$add_artist->galleries()->attach(Input::get('add_artist'));
$add_artist->save();
return Redirect::route('admin.galleries.edit')
->with('message', 'Artist added successfully.');
}
return Redirect::route('admin.galleries.edit')
->with('message', 'Something went wrong')
->withErrors($v)
->withInput();
}
public function postRemove($id, $aid) {
$input = array_except(Input::all(), '_method');
$v = Validator::make(Input::all(), Artist::$rules);
if ($v->passes()) {
$gallery = Gallery::find($id);
$remove_artist = Input::get();
$remove_artist->galleries()->detach(Input::get('remove_artist'));
$remove_artist->save();
return Redirect::route('admin.galleries.edit')
->with('message', 'Artist removed successfully.');
}
return Redirect::route('admin.galleries.edit')
->with('message', 'Something went wrong')
->withErrors($v)
->withInput();
}
edit.blade.php
Add Form
{{ Form::open(array('class' => '', 'method' => 'put', 'action'=> array('GalleriesController#postAdd', $gallery->id , $add_artist->id ))) }}
<div class="form-group">
{{ Form::label('Add Artist:') }}
{{ Form::select('add_artist', $other_artists_name, null, array('class'=>'form-control')) }}
</div>
{{ Form::button('Add Artist', array('type' => 'submit', 'class'=>'btn btn-primary')) }}
{{ Form::close() }}
edit.blade.php
Remove Form
{{ Form::open(array('class' => '', 'method' => 'put', 'action'=>array('GalleriesController#postRemove', $id , 'aid'))) }}
<div class="form-group">
{{ Form::label('Remove Artist:') }}
{{ Form::select('remove_artist', $gallery_artists_name, null, array('class'=>'form-control')) }}
</div>
{{ Form::button('Remove Artist', array('type' => 'submit', 'class'=>'btn btn-danger')) }}
{{ Form::close() }}
Routes.php
Route::post('admin/galleries/{galleries}/add/{aid}', 'GalleriesController#postAdd');
Route::post('admin/galleries/{galleries}/remove/{aid}', 'GalleriesController#postRemove');
Route::resource('admin/galleries', 'GalleriesController');
I've been doing so many changes to the code that a lot of things might be mixed up. Sorry if that's the case.
You are making it pretty difficult. Here is what I did, but with checkboxes, which allowed me to cut down on the number of functions and forms I needed to work with. I've skipped the validation, but what I do have was tested and seems to work fine.
Swapping out the checkboxes for a select shouldn't be too much additional work, but I'd suggest going with a multi-select in that case, because again, it would be much simpler to work with for you and much easier to use from the user's standpoint. Let me know if I should modify my answer if it has to be selects.
Controller
class ArtController extends BaseController {
public function getIndex($artist_id)
{
// Get our artist with associated galleries
$artist = Artist::find($artist_id);
$artist->load('galleries');
// Get all galleries to populate our checkboxes
$galleries = Gallery::all();
// Show form
return View::make('art.gallery_update_form')->with('artist', $artist)->with('galleries', $galleries);
}
public function postIndex($artist_id)
{
// Grab our artist
$artist = Artist::find($artist_id);
// Sync the galleries. If no galleries were chosen, send it an empty array. Sync will perform both write and delete operations for you in one shot. Very handy.
$artist->galleries()->sync(Input::get('galleries', array()));
// Reshow the form
return $this->getIndex($artist_id);
}
}
View
#section('content')
{{ Form::open() }}
<!-- Get a list of our ID's so we can check/uncheck the checkboxes as we go -->
<?php $artist_galleries = $artist->galleries->lists('id'); ?>
<!-- Create checkbox for each gallery -->
#foreach($galleries as $gallery)
{{ Form::label($gallery->id, $gallery->name) }}
<!-- 3rd parameter is where the magic happens, it's looking in our list of galleries
we created a few lines up for the id to see if the artist belongs to that gallery or not -->
{{ Form::checkbox('galleries[]', $gallery->id, in_array($gallery->id, $artist_galleries), array('id' => $gallery->id)) }}
<br />
#endforeach
{{ Form::submit() }}
{{ Form::close() }}
#stop
Routes
Route::get('art/{artist_id}', array('uses' => 'ArtController#getIndex'));
Route::post('art/{artist_id}', array('uses' => 'ArtController#postIndex'));
Edit
Just getting your postAdd() method to work, all that should be required is something like this...
public function postAdd($id, $aid)
{
$input = array_except(Input::all(), '_method');
$v = Validator::make(Input::all(), Artist::$rules);
if ($v->passes()) {
$gallery = Gallery::find($id);
$gallery->artists()->attach($aid);
return Redirect::route('admin.galleries.edit')
->with('message', 'Artist added successfully.');
}
return Redirect::route('admin.galleries.edit')
->with('message', 'Something went wrong')
->withErrors($v)
->withInput();
}
I may be a little confused on the purpose of this function. As I wrote it, it will attach a selected artist to a gallery. I'm not sure of the purpose of using input. It looks as though you may also be attempting to save a new artist as though you wish your users to be able to create a new artist and assign that artist to a gallery when the artist is created? If you are passing in the artist id and the gallery id, that should be all you need and there is no need for the Input class.
Usually though, you'd be only passing in the gallery id which you would have generated a link for and it would be in the URI and the artist would be passed in via the form, in which case you would need to use Input::get('add_artist') and that would keep your URI much cleaner as well.
The postRemove() function would be the exact same, except you'd want to use detach() instead. This is all assuming of course all the rest of the functionality which is responsible for passing in the gallery id and artist id are working as well as the relationships themselves you've already setup in your models.

Symfony2: my form returns false from isValid() but empty array for getErrors() from unique constraint condition

I have a Customer entity that only has a unique Email field to it. I am trying to edit a customer's email and the validation works fine. However I have this in my controller:
public function updateAction(Request $request, $id) {
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('AcmeDemoBundle:Customer')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Customer entity.');
}
$editForm = $this->createForm(new CustomerType(), $entity);
$editForm->bind($request);
if ($editForm->isValid()) {
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('ticket_result'));
}
var_dump($editForm->getErrors());
return $this->render('AcmeDemoBundle:Customer:edit.html.twig', array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
));
}
The var_dump returns an empty array but the validator sets a unique error and the $editForm->isValid() returns false. Is there a way to check for that specific error in the controller during validation, also can you explain why it returns an empty error array? Basically, I would like to provide the "merge" option if that error comes up.
EDIT: here is the formtype:
namespace Acme\DemoBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class CustomerType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('email', 'email', array('required'=>true))
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver) {
$resolver->setDefaults(array(
'data_class' => 'Acme\DemoBundle\Entity\Customer',
'cascade_validation' => true,
));
}
public function getName() {
return 'acme_demobundle_customertype';
}
}
And the twig template:
{% extends 'AcmeDemoBundle::layout.html.twig' %}
{% block body -%}
<h1>Customer edit</h1>
<form action="{{ path('customer_update', { 'id': entity.id }) }}" method="post" {{ form_enctype(edit_form) }}>
<input type="hidden" name="_method" value="PUT" />
{{ form_widget(edit_form) }}
<p>
<button type="submit">Edit</button>
</p>
</form>
{% endblock %}
Here is my validation:
Acme\DemoBundle\Entity\Customer:
constraints:
- Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity:
fields: email
message: "A customer under that email address already exists"
properties:
email:
- Email: ~
For debug purposes you can use $form->getErrorsAsString() instead of $form->getErrors() if you use Symfony 2.*
Quoted from this answer:
$form->getErrorsAsString() should only be used to debug the form...it
will contain the errors of each child elements which is not the case
of $form->getErrors().
UPDATE 1:
"With more recent Symfony versions, you must use $form->getErrors(true, false); instead. First param corresponds to deep and second to flatten" (see the comment by #Roubi)
Ok, found an answer here:
Symfony2 invalid form without errors
It turns out each form child has it's own separate errors. When doing a var_dump of
$editForm->getChildren()['email']->getErrors()
I get:
array (size=1)
0 =>
object(Symfony\Component\Form\FormError)[531]
private 'message' => string 'A customer under that email address already exists' (length=50)
protected 'messageTemplate' => string 'A customer under that email address already exists' (length=50)
protected 'messageParameters' =>
array (size=0)
empty
protected 'messagePluralization' => null
I am still wondering how to determine that the error is because of a unique conflict without parsing the error message string.
The following solutions works for me:
$form->getErrors(true)
You can use error_bubbling on each field to bubble the error up to your $form.
If not, you can also foreach through the errors
foreach ($children as $child) {
if ($child->hasErrors()) {
$vars = $child->createView()->getVars();
$errors = $child->getErrors();
foreach ($errors as $error) {
$this->allErrors[$vars["name"]][] = $this->convertFormErrorObjToString($error);
}
}
}
In Symfony 2.3, you can use this one :
if ($form->isValid()){
# Code...
} else {
foreach ($form->getIterator() as $key => $child) {
if ($child instanceof Form) {
foreach ($child->getErrors() as $error) {
$errors[$key] = $error->getMessage();
}
}
}
}
This will get you an array ($errors) with the errors from the children.
You could try to use the dump function when the form is submited and not valid. I use it like this
if($form->isSubmited() && $form->isValid()){
//SAVE TO DATABASE AND DO YOUR STUFF
}else if($form->isSubmited()){
//SUBMITED BUT WITH ERRORS
dump($form->getErrors(true));
die();
}
Note this is for debugging purposes only, It will show you your form, the data in it and all the errors any field could have.
In production mode you should return the error to the view and show them to the user.