Zf2 and Doctrine Annotations give trouble to make a 'new' form - php

I am trying to create a form to create a new product.
In my Controller I have the follwoing code:
public function newAction() {
$repo = $this->getEntityManager()->getRepository('Swap\Entity\Product');
$builder = new AnnotationBuilder($this->getEntityManager());
$form = $builder->createForm($repo);
$config = $this->getModuleConfig();
if (isset($config['swap_form_extra'])) {
foreach ($config['swap_form_extra'] as $field) {
$form->add($field);
}
}
$form->setHydrator(new DoctrineHydrator($this->getEntityManager(), 'Swap\Entity\Product'));
$form->bind($repo);
return new ViewModel(array('form' => $form));
}
Now this gives me the follwing error:
Class "Swap\EntityRepository\Product" sub class of "Doctrine\ORM\EntityRepository" is not a valid entity or mapped super class.
I am not sure if this has anything to do with it: But when you want to edit an object in a form you can do:
$repo = $this->getEntityManager()->getRepository('Swap\Entity\Product');
$id = (int) $this->getEvent()->getRouteMatch()->getParam('id', '0');
$product = $repo->find(1);
$productNames = $this->getEntityManager()->getRepository('Swap\Entity\ProductGroup')->findAll();
$product->SetProductGroup($productNames);
$builder = new AnnotationBuilder($this->getEntityManager());
$form = $builder->createForm($product);
But not sure how to get the product in a form to create a new entity.
Any suggestions?

Forms are build around entities, not with repositories. There is a clear distinction between them in Doctrine: entities are objects that hold state, that are related to database tables and where you can create new ones, update existing ones and remove ones for. Repositories are helper classes. They help you to find entities. Usually you find one by id or find them all, but repositories help you also to find one or multiple entities via a specific property.
That said, the form builder requires entities. In both the edit as the new action, you want to build based on the entity. In the editAction, you do this (pseudo):
$product = findMyProductEntity();
$form = $builder->createForm($product);
In the newAction, you do this (pseudo):
$repository = findMyProductRepository();
$form = $builder->buildForm($repository);
In this case, you also need to inject the entity and not the repository. How? Simply, just use new:
public function newAction()
{
$product = new Swap\Entity\Product;
$builder = new AnnotationBuilder($this->getEntityManager());
$form = $builder->createForm($product);
// Rest of your code
}

You told it to build the form from an entity repository instance, and not an entity itself.
$form = $builder->createForm($repo); // $repo is not an entity!

Related

Phalcon framework, can't get data from modal to controller

public function searchStudent($student)
{
$db = Di::getDefault()->get('db');
$sql = 'SELECT * FROM students WHERE insurance_number = "'.$student['searchInsurenceNum'].'"';
$sth = $db->prepare($sql);
$sth->execute();
When i check here die(var_dump($sth->fetchAll())), i am getting array with data from database.
return $sth->fetchAll();
}
public function searchAction()
{
$request = new Request();
$response = new Response();
if ($request->isPost()) {
(new ContactsStorage())->searchStudent($request->getPost());
}
But in controller when i call fuction die(var_dump((new ContactsStorage())->searchStudent())), i am getting empty array .
$this->view->setVar('findData', (new ContactsStorage())->searchStudent());
}
Maybe your request is not a POST ? ($request->isPost())
by using this method you're allow to find your students only on POST request. Remove condition and try again.
If you have model Student which extends \Phalcon\Mvc\Model you can use magic static methods findBy{$FeildCamelCasedName} so there is no need to create extra repositories and even methods if you want to ge tsome entity by simple criteria:
$findData = Student::findByInsuranceNumber($in);
also you can find one element by such criteria by simply using magic method findFirstBy{$Field}

ZF2 Forms Standalone - How can I get access to my custom view helpers?

We are using the ZF2 forms as a standalone plugin inside another PHP application. This is working fine, except I'm not able to use some custom view helpers. The ServiceManager (?) doesn't know where my helpers are located and crashes with a fatal error.
Is there a way to register some custom view helpers without a modules.config.php? I haven't found a way to pass an array/config to the HelperConfig below. As a ZF2 rookie I'm a bit lost here.
$form = new \My\Custom\Form\ContactForm();
$renderer = new \Zend\View\Renderer\PhpRenderer();
$config = new \Zend\Form\View\HelperConfig();
$config->configureServiceManager($renderer->getHelperPluginManager());
if(isset($_POST['submit'])) {
$form->setData($_POST);
if($form->isValid()) {
$data = (OBJECT) $form->getData();
// ...
} else {
return $form->render($renderer); // Inside the render() method we use the form-view-helpers to render the form.
}
} else {
return $form->render($renderer);
}
I have also tried to use the HelperPluginManager (Btw. whats the difference between these two?). But there isn't a method to pass a config-array either.
$renderer = new \Zend\View\Renderer\PhpRenderer();
$plugins = $renderer->getHelperPluginManager();
$renderer->setHelperPluginManager($plugins);

Tidy up controller in Laravel 5.1

I'm setting up a Laravel 5.1 project and I've been making good progress with it but have run in to something that I'm struggling to figure out.
Basically, I have been creating objects to insert in to the database in my controller methods. This hasn't been too bad because they're usually one-liners.
However, I've run in to a more complex db entry and my controller has become a little muddied. Let me show you:
/**
* Store a new ticket for the specified project.
*
* #param int $id
* #param TicketsRequest $request
* #return Response
*/
public function store_ticket($id, TicketsRequest $request)
{
$user_id = Auth::user()->id;
$project_id = $id;
$project_tickets = Ticket::whereProjectId($id);
$project_ticket_id = $project_tickets->count() + 1;
$ticket = new Ticket;
$ticket->user_id = $user_id;
$ticket->project_id = $project_id;
$ticket->project_ticket_id = $project_ticket_id;
$ticket->title = $request->title;
$ticket->save();
$ticket_update = new TicketUpdate;
$ticket_update->user_id = $user_id;
$ticket_update->ticket_id = $ticket->id;
$ticket_update->status_id = $request->status_id;
$ticket_update->priority_id = $request->priority_id;
$ticket_update->assigned_to = $request->assigned_to;
$ticket_update->description = $request->description;
$ticket_update->save();
return redirect('/projects');
}
So as you can see, I'm creating a ticket which gets saved to the database, then also creating a ticket update which is also saved to the database.
What I'd like to do is extract this code in to 'something' to clean up my controller.
On my travels, I've found that maybe creating repositories might be the way forward. Otherwise I was thinking about some kind of service but I'm not really convinced that that is the way forward.
I have a subscription to Laracasts and found the following video but it's a little outdated and I was sure if this would still be the 'right' way to do this in Laravel 5.1 (I've found that things seem to have a natural home in 5.1 compared to older versions).
https://laracasts.com/lessons/repositories-simplified
Any suggestions/links etc would be great. Thanks!
If you instantiate your objects often/always using the same set of attributes, you could easily extract that code into models constructors, e.g:
//in your model
public function __construct($user_id, $ticket_id, $request) {
$this->user_id = $user_id;
$this->ticket_id = $ticket_id;
$this->status_id = $request->status_id;
$this->priority_id = $request->priority_id;
$this->assigned_to = $request->assigned_to;
$this->description = $request->description;
}
// in your controller
$ticket_update = new TicketUpdate($user_id, $ticket->id, $request);
$ticket_update->save();
Nothing wrong with your implementation. I suggest you use try catch when calling the save() method in case something goes wrong and send a nice error to the user saying something like "something went wrong, contact your admin".

My form is not getting validated in Zend Famework. Why?

I am creating a rest Module for album module of zf2
My Code Snippet for create method :
public function create($data) {
$form=new AlbumForm();
$album = new Album();
$form->setInputFilter($album->getInputFilter());
$form->setData($data);
if ($form->isValid()) {
$album->exchangeArray($form->getData());
$id = $this->getAlbumTable()->saveAlbum($album);
return new JsonModel(array(
'data' => $this->get($id),
));
}
All the functionalities like update,select all,delete are working properly but insertion is not working.
I have selected post method through my Advanced rest client application and passing arguments like title=some&artist=someone its not validating form.
The form having values like
id Auto-incremented,
artist varchar,
title varchar,
Please Help for this problem
just got the answer that you have to add this lines to the top of the create method.
if (empty($data['id'])) $data['id'] = 0;
Its working properly.

I just can't extend the Symfony2 Form class. Tried everything

I have literally tried everything to try and extend the Symfony2 Form class.
I want to add a new method to Form and call it in a controller:
$form = $this->createForm($this->get('my_form_service'), $entity);
$form->myNewMethod();
Because the Form class isn't defined as a service and is instantiated in another class (FormBuilder, line 221) then I can't see what I can do. I don't want to hack the core.
I could extend the controller class, e.g. the createForm() method returns the instantiated Form object:
// Extend Controller and do something with Form before returning
public function createForm($type, $data = null, array $options = array())
{
return $this->container->get('form.factory')->create($type, $data, $options);
In fact How to add a new method to a php object on the fly? shows how I could do the above and add my new method that way, but my understanding is that you need to at least add __call to the Form class - which I can't do - or the added method won't be able to use $this (which I need).
I only need to add this for when the form is used in a controller. I don't need it for any CLI processing.
Any ideas how I can add a method to the Form class without hacking the core?
====================================================================
EDIT: Why am I doing this?
I want to 'silently fail' a form submit if a certain criteria is met. I believe the best way to do this would be to do this in a controller:
if ($form->isValid()) {
if ($form->requiresSilentFail()) {
// Silently fail
} else {
// As normal, add to DB etc.
}
}
I suppose I could just do something like this:
if ($form->isValid()) {
if ($this->get('check_my_form')->requiresSilentFail($form)) {
// Silently fail
} else {
// As normal, add to DB etc.
}
}
.... but I need to also perform a little bit of extra logic in Form::handleRequest() first, so I believe extending Form is the only option.
I don't really understand why you need to extend the form class simply on your controller/service where you process the form call your method under is valid check, see below:
$form->handleRequest($request);
if ($form->isValid()) {
$this->get($apiResource->getResourceHandlerName())->update($resourceData);
$response = new Response();
$response->setStatusCode($statusCode);
if ($this->isSuccessFullStatusCode($statusCode)) {
$serializedObject = $this->getSerializer()->serialize($resourceData, 'json',$serializationContext);
$response->setStatusCode($responseStatusCode);
$response->setContent($serializedObject);
return $response;
}
}

Categories