I have the following code that updates SalesOrder Entity.
public function updateAction($id)
{
$securityContext = $this->get('security.context');
$em = $this->getDoctrine()->getEntityManager();
$entity = $em->getRepository('CIInventoryBundle:SalesOrder')->find($id);
$editForm = $this->createForm(new SalesOrderType($securityContext), $entity);
$currentTotal = $entity->getTotal();
$currentStatus = $entity->getStatus();
try {
$entity->isEditable();
} catch (\Exception $e){
$this->get('session')->setFlash('alert-error', $e->getMessage());
return $this->redirect($this->generateUrl('salesorder_show', array('id' => $entity->getId())));
}
$originalItems = array();
foreach ($entity->getItems() as $item) {
$originalItems[] = $item;
}
$request = $this->getRequest();
$editForm->bindRequest($request);
if ($editForm->isValid()) {
try {
$entity->validateStatusChange($currentStatus, $currentTotal);
} catch (\Exception $e) {
$this->get('session')->setFlash('alert-error', $e->getMessage());
return $this->redirect($this->generateUrl('salesorder_show', array('id' => $id)));
}
foreach ($entity->getItems() as $item) {
//adjust the reserved in the inventory
$item->adjustReserved();
foreach ($originalItems as $key => $toDel) {
if ($toDel->getId() === $item->getId()) {
unset($originalItems[$key]);
}
}
}
foreach ($originalItems as $item) {
$em->remove($item);
}
$entity->setUpdatedAt(new \DateTime('now'));
$em->persist($entity);
$em->flush();
$this->get('session')->setFlash('alert-success', 'Record has been updated successfully!');
return $this->redirect($this->generateUrl('salesorder_show', array('id' => $id)));
} else {
$this->get('session')->setFlash('alert-error', 'Please fill in the correct values.');
$variantForm = $this->createForm(new AddVariantSalesOrderType());
}
return array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
'variant_form' => $variantForm->createView(),
);
}
When i run this code i got ""maximum execution time exceeded". I already changed the maximum execution time in php.ini to 2 minutes.
Is there anyway i can optimize my codes ?
Thanks!
Related
I'm trying to show errors validation message with the old The information already entered , but the problém when the form is not valid and it's submitted else if ($form->isSubmitted()&& !$form->isValid()) : the old input content(old The information already entered) will disappear .
By the way i want after avery submition that the url end with #contact that's why i worked with this->redirect .
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$task = $form->getData();
$em = $this->getDoctrine()->getManager();
$em->persist($task);
$em->flush();
$this->get('session')->getFlashBag()->add(
'notice',
'Votre message est bien envoyé !'
);
} else if ($form->isSubmitted() && !$form->isValid()) {
$errors = array();
foreach ($form->all() as $key => $child) {
if (!$child->isValid()) {
foreach ($child->getErrors() as $error) {
$errors[$key] = $error->getMessage();
}
}
}
foreach ($errors as $key => $value) {
$this->get('session')->getFlashBag()->add('error', $value);
}
return $this->redirect($this->generateUrl('index') . '?a#contact');
}
return $this->render('front/index.html.twig', array('form' => $form ->createView()));
}
You should only redirect to your index if the form is valid. Right now that redirect is occurring in } else if ($form->isSubmitted() && !$form->isValid()) {, which means a redirect will occur with invalid data.
Try:
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$task = $form->getData();
$em = $this->getDoctrine()->getManager();
$em->persist($task);
$em->flush();
$this->get('session')->getFlashBag()->add(
'notice',
'Votre message est bien envoyé !'
);
return $this->redirect($this->generateUrl('index') . '?a#contact');
} else if ($form->isSubmitted() && !$form->isValid()) {
$errors = array();
foreach ($form->all() as $key => $child) {
if (!$child->isValid()) {
foreach ($child->getErrors() as $error) {
$errors[$key] = $error->getMessage();
}
}
}
foreach ($errors as $key => $value) {
$this->get('session')->getFlashBag()->add('error', $value);
}
}
return $this->render('front/index.html.twig', array('form' => $form ->createView()));
}
This way, if your form is not valid, it will return the render form again (with your errors included). You can see an example of a controller that follows that flow here.
I'm building a simple task planner. This is a fragment from the file TaskController.php. How can I combine these 3 queries (tasks, notcompleted, completed) to make it work? Should I use DQL?
/**
* Lists all task entities.
*
* #Route("/", name="task_index")
* #Method("GET")
*/
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$tasks = $em->getRepository('TaskBundle:Task')->findByUser($this->getUser()); // all tasks of a specific user
$notcompleted = $em->getRepository('TaskBundle:Task')->findByCompleted(false); //tasks that are not completed
$completed = $em->getRepository('TaskBundle:Task')->findByCompleted(true); // all completed tasks
return $this->render('task/index.html.twig', array(
'notcompleted' => $notcompleted,
'completed' => $completed,
'tasks' => $tasks,
));
}
You can use Doctrine's \Doctrine\Common\Collections\Collection::partition() to split the tasks:
$em = $this->getDoctrine()->getManager();
$tasks = $em->getRepository('TaskBundle:Task')->findByUser($this->getUser());
$collection = new ArrayCollection($tasks);
list($completed, $notcompleted) = $collection->partition(function ($key, Task $task) {
return $task->isCompleted();
});
return $this->render('task/index.html.twig', array(
'notcompleted' => $notcompleted,
'completed' => $completed,
'tasks' => $tasks,
));
The simplest solution could be to filter tasks in the controller:
$em = $this->getDoctrine()->getManager();
$tasks = $em->getRepository('TaskBundle:Task')->findByUser($this->getUser());
$notcompleted = $completed = [];
foreach ($tasks as $task) {
if ($task->isCompleted()) {
$completed[] = $tasK;
} else {
$notcompleted[] = $task;
}
}
return $this->render('task/index.html.twig', array(
'notcompleted' => $notcompleted,
'completed' => $completed,
'tasks' => $tasks,
));
In this solution you are doing only one DB query, instead of three queries.
I am new in testing.I want to test my function.I have successfully installed phpUnit. I check many tutorials on internet.But I could not get the proper information regarding testing. Here is the my function code:
public function loginAction(Request $request)
{
$session = $this->getRequest()->getSession();
if( $session->get('userId') && $session->get('userId') != '' && $session->get('type') == '2')
{
//if user is login then it will be redirect to login page
return $this->redirect($this->generateUrl('registrarGeneral_dashboard'));
}
$em = $this->getDoctrine()->getEntityManager();
$repository = $em->getRepository('DRPAdminBundle:User');
if ($request->getMethod() == 'POST')
{
$session->clear();
$userName = $request->get('username');
$password = md5($request->get('password'));
//find email, password type and status of User
$user = $repository->findOneBy(array('username' => $userName, 'password' => $password,'type'=>2,'status'=>1 ));
$userEmail = $repository->findOneBy(array('email' => $userName, 'password' => $password,'type'=>2,'status'=>1 ));
if ($user)
{
//set session of User login
$session->set('userId', $user->getId());
$session->set('type', 2);
$session->set('nameRegistrar', $user->getFirstName());
$session->set('pictureRegistrar', $user->getPicture());
//echo "<pre>";print_r($session->get('picture'));die;
return $this->redirect($this->generateUrl('registrarGeneral_dashboard'));
}
if ($userEmail)
{
$session->set('type', 2);
$session->set('userId', $userEmail->getId());
$session->set('nameRegistrar', $userEmail->getFirstName());
$session->set('pictureRegistrar', $userEmail->getPicture());
//echo "<pre>";print_r($session->get('picture'));die;
return $this->redirect($this->generateUrl('registrarGeneral_dashboard'));
}
else
{
return $this->render('DRPRegistrarGeneralBundle:Pages:login.html.twig', array('name' => 'Invalid Email/Password'));
}
}
return $this->render('DRPRegistrarGeneralBundle:Pages:login.html.twig');
}
how to test this function? Please help
I don't know what you want to test but here is an exemple of what you can do to test user fonctionnalities :
public function testUserPageDown()
{
$client = static::createClient();
$client->request('GET', '/user/login');
$this->assertTrue($client->getResponse()->isSuccessful());
$client->request('GET', '/user/register');
$this->assertTrue($client->getResponse()->isSuccessful());
}
public function testUserFirewall()
{
$client = static::createClient();
//Trying go to user routes without being logged
$client->request('GET', '/user/profile');
$this->assertTrue($client->getResponse()->isRedirect());
$client->request('GET', '/user/profile/edit');
$this->assertTrue($client->getResponse()->isRedirect());
$client->request('GET', '/user/profile/editpassword');
$this->assertTrue($client->getResponse()->isRedirect());
}
public function testUserFormRegister()
{
$client = static::createClient();
$crawler = $client->request('GET', '/user/register');
$buttonCrawlerNode = $crawler->selectButton('submit_user_register');
$form = $buttonCrawlerNode->form();
$testForm = array(
'wineot_databundle_user[username]' => 'test',
'wineot_databundle_user[firstname]' => 'test',
'wineot_databundle_user[lastname]' => 'test',
'wineot_databundle_user[mail]' => 'test#mail.fr',
'wineot_databundle_user[plain_password][first]' => 'blabla321',
'wineot_databundle_user[plain_password][second]' => 'blabla321'
);
$response = $client->getResponse();
$client->submit($form, $testForm);
//If the submit is true that mean that the register is ok
$this->assertTrue($response->isSuccessful());
}
I hope that will help you do undestand how to test.
I have a working queryBuilder that gets posts by category and excludes the one being shown and sets a max limit.
Question: How can I simplify this queryBuilder?
In the query, I am pretty sure I don't need to join the 2 tables (category/post connected with a OneToMany/ManyToOne relationship) and am setting $category in the controller, is there a better way of refactoring this?
queryBuilder
public function getRelatedPosts($exceptPost, $limit, $category)
{
return $this
->createQueryBuilder('post')
->leftJoin('post.category','category')
->where('post != :exceptPost')
->setParameter('exceptPost', $exceptPost)
->andWhere('category = :category')
->setParameter('category', $category)
->orderBy('post.createdAt', 'DESC')
->setMaxResults($limit)
->getQuery()
->execute();
}
controller
public function showAction($slug)
{
$post = $this->getDoctrine()->getRepository('AcmeDemoBundle:Post')
->findOneBy(array(
'slug' => $slug
));
if (null === $post) {
throw $this->createNotFoundException('Post was not found');
}
$category = $post->getCategory();
$posts = $this->getDoctrine()->getRepository('AcmeDemoBundle:Post')
->getRelatedPosts($post, 4, $category);
return array(
'post' => $post,
'posts' => $posts
);
}
updated queryBuilder
public function getRelatedPosts($exceptPost, $limit, $category)
{
return $this
->createQueryBuilder('post')
->where('post != :exceptPost')
->andWhere('post.category = :category')
->setParameter('exceptPost', $exceptPost)
->setParameter('category', $category)
->orderBy('post.createdAt', 'DESC')
->setMaxResults($limit)
->getQuery()
->execute();
}
I am not sure if this is what you are looking for but you may want something like this:
Controller
public function showAction($slug)
{
$post = $this->getDoctrine()->getRepository('AcmeDemoBundle:Post')
->findOneBy(array(
'slug' => $slug
));
if (null === $post) {
throw $this->createNotFoundException('Post was not found');
}
$posts = $this->getDoctrine()->getRepository('AcmeDemoBundle:Post')
->getRelatedPosts($post, 4);
return array(
'post' => $post,
'posts' => $posts
);
}
Repository
public function getRelatedPosts($exceptPost, $limit)
{
return $this
->createQueryBuilder('post')
->where('post.id != :exceptPost')
->andWhere('post.category = :category')
->setParameter('exceptPost', $exceptPost->getId())
->setParameter('category', $exceptPost->getCategory()->getId())
->orderBy('post.createdAt', 'DESC')
->setMaxResults($limit)
->getQuery()
->getResult();
}
You can also build this in a join query of post table with itself or SELECT ... IN (...); if you are interested
I'm just started working with Symfony2 and I have some problems with Pagination.
I have this code in my Account class:
public function indexAction($page)
{
$session = $this->get('session');
if ($session->get('valid')=='true') {
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('ProjectCRMBundle:Account')->findAll();
$user = new Account();
$form = $this->container->get('form.factory')->create(new AccountType());
$total = $this->getDoctrine()->getRepository('ProjectCRMBundle:Account')->createQueryBuilder('p')->getQuery()->getResult();
/* total of résultat */
$total_users = count($total);
$users_per_page = 1;
$last_page = ceil($total_users / $users_per_page);
$previous_page = $page > 1 ? $page - 1 : 1;
$next_page = $page < $last_page ? $page + 1 : $last_page;
/* résultat à afficher*/
$entities = $this->getDoctrine()->getRepository('ProjectCRMBundle:Account')->createQueryBuilder('p')->setFirstResult(($page * $users_per_page) - $users_per_page)->setMaxResults(1)->getQuery()->getResult();
return $this->render('ProjectCRMBundle:Account:index.html.twig', array(
'entities' => $entities,
'last_page' => $last_page,
'previous_page' => $previous_page,
'current_page' => $page,
'next_page' => $next_page,
'total_users' => $total_users,
'form' => $form->createView(),
'user' => $user,
));
return $this->render('ProjectCRMBundle:Account:index.html.twig');
} else {
return $this->redirect($this->generateUrl('user_login'));
}
}
/**
* Creates a new Account entity.
*
*/
public function createAction(Request $request)
{
$entity = new Account();
$form = $this->createForm(new AccountType(), $entity);
$form->bind($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('account_show', array('id' => $entity->getId())));
}
return $this->render('ProjectCRMBundle:Account:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
without forgetting the path on account.yml
account:
pattern: /{page}
defaults: { _controller: "ProjectCRMBundle:Account:index" , page: 1 }
At first look, it seems to work, but after trying to add a new account, I got this message:
LIMIT argument offset=-1 is not valid
Can anyone solve my problem?