i make a setting action in which i used doctrine query for getting single result but it returns null while data exist in database,how i get single result?here is my code:
public function settingsAction()
{
$id = (int) $this->params()->fromRoute('id', 0);
if (!$id) {
return $this->redirect()->toRoute('calendar', array(
'action' => 'create'
));
}
//echo $id;
//$calendar = $id;//$this->getCalendarTable()->getCalendar($id);
$calendar = $documentManager->getRepository('Calendar\Document\Calendar')->find($id);
$form = new CalendarForm();
$form->bind($calendar);
$form->get('submit')->setAttribute('value', 'Save');
$request = $this->getRequest();
if ($request->isPost()) {
$form->setInputFilter($calendar->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) {
//$this->getCalendarTable()->saveCalendar($form->getData());
return $this->redirect()->toRoute('calendar', array('action' => 'show', 'id' => $id));
}
}
return array(
'id' => $id,
'form' => $form,
);
}
You don't need to create a query to fetch by id as the DocumentRepository already provides this via it's find($id) method.
Just use the document manager to fetch the repository
$document = $documentManager->getRepository('FooDocument')->find($id);
You can also use the convenience method find($documentName, $id) directly on the document manager.
$document = $documentManager->find('FooDocument', $id);
Related
Hi I just started a project with Symfony and I think I am doing something wrong. Right now I want to a create simple page with table and filters so I created controller for it.
/**
* #Route("/")
*/
class HomeController extends Controller {
public function index(Request $request) {
//Form to add new documents
$form = $this->newForm();
$form->handleRequest($request);
$user = $this->getDoctrine()->getRepository(User::class)->find($this->getUser());
//Gets all user documents
$files = $user->getDocuments();
//Gets all categories
$categories = $this->getDoctrine()->getRepository(Category::class)->findAll();
//Adds new document to database
if($form->isSubmitted() && $form->isValid()) {
$article = $form->getData();
$article->setUser($this->getUser());
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($article);
$entityManager->flush();
return $this->redirectToRoute('index');
}
return $this->render('home/home.html.twig', [
'files' => $files,
'categories' => $categories,
'form' => $form->createView(),
]);
}
}
This controller just displays documents in table and categories in navigaton. So then to add category filters I just made new function:
/**
* #Route("/{categoryId}")
*/
public function categories(request $request, $categoryId)
{
$form = $this->newForm();
$form->handleRequest($request);
$user = $this->getDoctrine()->getRepository(User::class)->find($this->getUser());
$categories = $this->getDoctrine()->getRepository(Category::class)->findAll();
$category = $this->getDoctrine()->getRepository(Category::class)->findOneBy(["id" => $categoryId]);
$categoryFiles = $this->getDoctrine()->getRepository(Document::class)->categoryFiles($category, $user);
if($form->isSubmitted() && $form->isValid()) {
$article = $form->getData();
$article->setUser($this->getUser());
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($article);
$entityManager->flush();
return $this->redirectToRoute('index');
}
return $this->render('home/home.html.twig', [
'files' => $categoryFiles,
'categories' => $categories,
'form' => $form->createView(),
]);
}
Everything works, but I have to repeat same code for categories and forms in all of my functions. Thank you for your help.
I suggest you use services, a Service can be (Business Rules, Helpers, MicroServices, etc.), the most import is the Business Rules, generally should exists a service by entity
$user = $this->getUser();
$info = $this->get(HomeService::class)->getInfo($user, null);
// TODO FORM
return $this->render('home/home.html.twig', [
'files' => $info['files'],
'categories' => $info['categories'],
'form' => $form->createView()
]);
Second Action
$user = $this->getUser();
$info = $this->get(HomeService::class)->getInfo($user, $categoryId);
// TODO FORM
return $this->render('home/home.html.twig', [
'files' => $info['category_files'],
'categories' => $info['categories'],
'form' => $form->createView()
]);
HomeService->info(), it will process all
Symfony Service
Create abstract class, then extend from child controllers. You can read also: http://php.net/manual/en/language.oop5.late-static-bindings.php
It's just one way, can be more ways!
I have a search form that works with the method POST, but the method POST doesn't display the requested data in the url.
With method POST the url look like this:
/search_flight
with the method GET no results found, the url look like this:
/search_flight?from=Cape+Town%2C+International+CPT&to=Johannesburg%2C+O.R.+Tambo+International+JNB&departuredate=2016%2F01%2F08&arrivaldate=2016%2F10%2F04&price=57.5%2C1000
I also noticed that with the method GET the data is reset in each input of the form.
routing.yml
searchFlight:
path: /search_flight
defaults: { _controller: FLYBookingsBundle:Post:searchtabflightResult }
requirements:
_method: GET|POST
controller
This method send the requested data to the method searchtabflightResultAction that will handle the query.
public function searchtabflightAction()
{
//$form = $this->createForm(new SearchflightType(),null, array('action' => $this->generateUrl('searchFlight'),'method' => 'GET',));
$form = $this->get('form.factory')->createNamed(null, new SearchflightType());
return $this->render('FLYBookingsBundle:Post:searchtabflight.html.twig', array(
'form' => $form->createView(),
));
}
.
<form action="{{ path ('searchFlight') }}" method="GET">
{# here I have my forms #}
</form>
.
public function searchtabflightResultAction(Request $request)
{
//$form = $this->createForm(new SearchflightType());
$form = $this->get('form.factory')->createNamed(null, new SearchflightType());
$form->handleRequest($request);
$em = $this->getDoctrine()->getManager();
$airport1 = $form["to"]->getData();
$airport = $form["from"]->getData();
$departureDateObj = $form["departuredate"]->getData();
$arrivalDateObj = $form["arrivaldate"]->getData();
$price = $form["price"]->getData();
$entities = $em->getRepository('FLYBookingsBundle:Post')->searchflight($airport1,$airport,$departureDateObj,$arrivalDateObj,$price);
return $this->render('FLYBookingsBundle:Post:searchtabflightResult.html.twig', array(
'entities' => $entities,
'form' => $form->createView(),
));
}
How can I make my search filter works with method get ?
Everything should be done within two actions, the basic concept is:
SearchFlightType has with/wo price option:
class SearchFlightType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('from', FormType\TextType::class)
->add('to', FormType\TextType::class)
->add('departuredate', FormType\TextType::class)
->add('arrivaldate', FormType\TextType::class);
if ($options['price']) {
$builder->add( 'price', FormType\TextType::class );
}
$builder
->add('submit', FormType\SubmitType::class);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'price' => false,
));
}
}
Controller.php
class PostController extends Controller
{
/**
* #Route("/index", name="index")
*/
public function indexAction(Request $request)
{
$defaultData = array();
$form = $this->createForm(SearchFlightType::class, $defaultData, array(
// action is set to the specific route, so the form will
// redirect it's submission there
'action' => $this->generateUrl('search_flight_result'),
// method is set to desired GET, so the data will be send
//via URL params
'method' => 'GET',
));
return $this->render('Post/searchtabflight.html.twig', array(
'form' => $form->createView(),
));
}
/**
* #Route("/search_flight_result", name="search_flight_result")
*/
public function searchTabFlightResultAction(Request $request)
{
$defaultData = array();
$entities = null;
$form = $this->createForm(SearchFlightType::class, $defaultData, array(
// again GET method for data via URL params
'method' => 'GET',
// option for price form field present
'price' => true,
));
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// get data from form
$data = $form->getData();
// process the data and get result
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('FLYBookingsBundle:Post')->searchflight($data['from'], $data['to'], ...);
}
return $this->render('Post/searchtabflight.html.twig', array(
'form' => $form->createView(),
// present the result
'entities' => $entites,
));
}
}
In ZF2, I have a custom form element factory. It creates a custom MultiCheckbox and fills the checkbox values and labels from a db query.
class MyMultiCheckboxFactory
{
public function __invoke(FormElementManager $formElementManager)
{
$multiCheck = new \Zend\Form\Element\MultiCheckbox();
$serviceManager = $formElementManager->getServiceLocator();
$mapper = $serviceManager->get('Path\To\Mapper\To\Query\DB');
$descriptions = $mapper->findDescriptions($id);
// some processing to prepare $value_options array
$multiCheck->setOptions([
'label' => 'blah-blah',
'value_options' => $value_options
]);
return $multiCheck;
}
}
My problem is as follows. The method findDescriptions($id) depends on the $id which I can get from the route. But when I use MyMultiCheckbox in the form like this:
public function init()
{
$this->add([
'type' => 'Path\To\MyMultiCheckbox',
'name' => 'someName'
]);
}
I don't know how to pass the $id into the MyMultiCheckbox.
Could anyone help pleeeeeeeeeease?
You can fetch the id via the 'route match' instance inside the factory.
$event = $serviceManager->get('Application')->getMvcEvent();
$id = $event->getRouteMatch()->getParam('id', false);
if (empty($id)) {
throw new ServiceNotCreatedException('id not set!');
}
$descriptions = $mapper->findDescriptions($id);
I am new in zf2. I make a create action and want to get last inserted id but calender_id always equal to zero. How can I get the last insert id in create action ?
Here is my code:
public function createAction()
{
if ($this->zfcUserAuthentication()->hasIdentity())
{
$form = new CalendarForm();
$form->get('user_id')->setValue($this->zfcUserAuthentication()->getIdentity()->getId());
$form->get('submit')->setValue('Add');
$request = $this->getRequest();
if ($request->isPost()) {
$calendar = new Calendar();
$form->setInputFilter($calendar->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) {
$calendar->exchangeArray($form->getData());
$this->getCalendarTable()->saveCalendar($calendar);
if($request->isXmlHttpRequest()) {
//$dm = $this->getServiceLocator()->get('doctrine.documentmanager.odm_default');
//$calender = new \Calendar\Model\Calendar($dm);
$response = new Response();
$calender_id = $calendar->calendar_id;
$userid =$calendar->user_id;
$title=$calendar->title;
$description=$calendar->description;
$output = array('success' => true, 'calendar_id' => $calender_id, 'user_id' => $userid, 'title' => $title, 'description' => $description);
//$response->headers->set('Content-Type', 'application/json');
$response->setContent(json_encode($output));
return $response;
}
return $this->redirect()->toRoute('calendar');
}
}
return array('form' => $form);
}
else
{
$this->redirect()->toRoute('zfcuser/login');
}
}
how i get last inserted id?
If your calendarTable extends TableGateway you can use $calendarTable->getLastInsertValue() to get the last insert id. You can also use this method in your saveCalendar method.
Other modules in the application are updating, besides this one.
Here, I am using a model mapper in attempts to update a row set, as found in http://framework.zend.com/manual/en/learning.quickstart.create-model.html
public function SomeAction()
{
$mapper = new Application_Model_SomeMapper();
$model = new Application_Model_SomeModel(); //getters and setters
// action body
$request = $this->getRequest();
$data = $this->_request->getParams();
$someId = $data['someid'];
$get = $mapper->find($someId, new Application_Model_SomeModel, true); //find the row by id, and return array
/*
instantiating a form object and adding "submit"
*/
$form = new Module_Form_FormName();
$form->setAction("/module/controller/action/params/$someId");
$form->setMethod('post');
$form->setName('some_edit');
$submit = $form->createElement('button', 'submit');
$submit->setAttrib('ignore',true);
$submit->setLabel('Edit Something');
$form->addElement($submit);
if ($this->_request->isPost())
{
if($form->isValid($request->getPost()))
{
$data = $this->_request->getPost();
if(empty($data['some_id' ]))
{
$data['tier_models_id'] = NULL;
}
unset($data['submit']);
$setters = $model->setId($data['id'])
->setField1($data['field_1']);
if ($mapper->save($someId, $setters))
{
$this->_redirect("/index/");
}
}
}
$form->populate($tier);
$this->view->form = $get;
}
Here is an example of the save mapper function, except I've included an additional $id parameter
public function save(Application_Model_Guestbook $guestbook)
{
$data = array(
'email' => $guestbook->getEmail(),
'comment' => $guestbook->getComment(),
'created' => date('Y-m-d H:i:s'),
);
if (null === ($id = $guestbook->getId())) {
unset($data['id']);
$this->getDbTable()->insert($data);
} else {
$this->getDbTable()->update($data, array('id = ?' => $id)); //not happening, although the 'id' is passed as a param
}
}
Is there something missing?
Try this instead
$where = $this->getDbTable()->getAdapter()->quoteInto('id = ?', $id);
$this->getDbTable()->update($data, $where);