I am new to Symfony, I have a table users with two columns: user_name and first_name, I want to display all users whose names (user_name & first_name) contains $search:
<?php
namespace Login\LoginBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Login\LoginBundle\Entity\Users;
use Login\LoginBundle\Modals\Login;
use Doctrine\DBAL\DriverManager;
public function homeAction(Request $request) {
$session = $this->getRequest()->getSession();
if ($request->getMethod() == 'POST') {
$search_for = $request->get('search');
//what to write here --save my life guys
}
return $this->render('LoginLoginBundle:Default:home.html.twig');
}
It's like a full process of querying and fetching data, passing the results to the template. What you need to do is following below steps:
1) Get the repository of your entity (table) and call your custom search function which is created in the repository (of course you can merge this step and next one to have all in your controller homeAction function) I assume your entity name is Users
public function homeAction(Request $request) {
$session = $this->getRequest()->getSession();
$results = array();
if ($request->getMethod() == 'POST') {
$search_for = $request->get('search');
$em = $this->getDoctrine()->getManager();
$results = $em->getRepository('LoginLoginBundle:Users')->searchPhrase($search_for);
}
return $this->render('LoginLoginBundle:Default:home.html.twig', array(
'results' => $results
));
}
2) Now you need to build a repository class for you entity and implement below function in it Entity Repository in Symfony (or merge the code below to your controller)
public function searchPhrase($phrase) {
$query = $this->createQueryBuilder('U');
$result = $query->where(
$query->expr()->like('U.username', $query->expr()->literal("%$phrase%"))
)
->andWhere(
$query->expr()->like('U.firstName', $query->expr()->literal("%$phrase%"))
)
->getQuery()
->getResult();
return $results;
}
Keep in mind because you mention "AND" I used andWhere whereas you can use orWhere; because you said "CONTAIN" I used like expression with % and that's the way you can create expression in DQL Here is a full list of Doctrine2 expressions
3) last step is to show the results in your twig template; I assume you want to show them in table rows
<table>
<tr>
<th>Username</th><th>First Name</th>
</tr>
{% if results|length > 0%}
{% for item in results %}
<tr>
<td>{{ item.getUsername }}</td><td>{{ item.getFirstName }}</td>
</tr>
{% endfor %}
{% else %}
<tr>
<td colspan="2">No matching results found!</td>
</tr>
{% endif %}
</table>
Hopefully this helps
Thank you guys, But I this worked for me:
$repository = $this->getDoctrine()->getRepository('LoginLoginBundle:Users');
$query = $repository->createQueryBuilder('u')
->where("u.userName LIKE '%".$search_for."%' or u.firstName LIKE '%".$search_for."%'")
->getQuery();
$Myusers = $query->getResult();
if ($Myusers) //test if there are results returned
{
foreach ($Myusers as $user)
{
echo "E-mail : ".$user->getUserName()." -- Name : ". $user->getFirstName()."<br>";
}
}
else
{
echo "No matching results found!!";
}
//end-display
Related
I have a manyToOne relation of my entity ticket to my entity command. I store my tickets and my order in session. I can retrieve the command information by doing for example: {{app.request.session.get("command").Nom}}
But I can not view the ticket information. For example, if I want to get the ticket price 107 with twig?
session
Function of my service :
public function startCommande(Request $request)
{
$commande = new Commande();
$form = $this->form->create(CommandeBilletType::class, $commande);
if ($request->isMethod('POST') && $form->handleRequest($request)->isValid()){
$data = $form->getData();
$this->session->set('commande', $data);
}
return $form;
}
public function coordonneesCommande(Request $request)
{
$commande= $this->session->get('commande');
$form = $this->form->create(CommandeType::class, $commande);
if ($request->isMethod('POST') && $form->handleRequest($request)->isValid()) {
$this->price->tarifBillet($commande);
$response = new RedirectResponse('paiement');
$response->send();
}
return $form;
}
I tried {{app.request.session.get ("commande").Billet().Nom}}
{{app.request.session.get('Billet.nom')}}
...
You're trying to access a collection, you should iterate over it.
First set your "commande".
{% set commande = app.session.get('commande') %}
Now, you should be able to access the entity information and get your "billets" like this, (if i understand well you have a collection of billet):
{% for billet in commande.getBillet() %}
{{ billet.prix }}
{% endfor %}
First I've read documents for both Collection Field Type and How to Embed a Collection of Forms ... The example is about one entity (Task) that has one-to-many relation with another entity (Tag), and I understand it, but I can not adapt it to what I want!
To make it simpler, let say I have a Task entity, this task entity has some relations with other objects like user and project (each task can have one user and one project)
I want to make one form, inside this form a list of Tasks, each task in one row of a table that shows information like task.title, task.startdate, task.user.name, task.user.company.name, task.project.name, And it has 2 fields editable, textbox "Description" and checkbox "active". You can edit multiple tasks and submit the form using one button at the bottom of the table in the main form, so basically you should be able to update multiple records in one transaction (instead of making one form and one submit button per row and therefor one record update per submit).
I have many issues with this complicated design:
First I wanted to follow the sample to embed a collection of forms inside the main form, So I made a Form Type for my Task that should be like one form per row. I made these files:
Form Type for Task:
// src/Acme/TaskBundle/Form/Type/TaskType.php
namespace Acme\TaskBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class TaskType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('description', 'text', ['label' => false, 'required' => false, 'attr' => ['placeholder' => 'description']]);
$builder->add('active', 'checkbox', ['label' => false, 'required' => false, 'data' => true]);
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Acme\TaskBundle\Entity\Task',
));
}
public function getName()
{
return 'taskType';
}
}
Form Type for main form:
// src/Acme/TaskBundle/Form/Type/SaveTasksType.php
namespace Acme\TaskBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Acme\TaskBundle\Form\Type\TaskType.php;
class SaveTasksType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('tasksCollection', 'collection', ['type' => new TaskType()]);
$builder->add('tasksSubmit', 'submit', ['label' => 'Save']);
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults([
'attr' => ['class' => 'form-horizontal'],
'method' => 'POST'
]);
}
public function getName()
{
return 'saveTasksType';
}
}
Tasks Form Controller:
// src/Acme/TaskBundle/Controller/ManageTasksController.php
namespace Acme\TaskBundle\Controller;
use Acme\TaskBundle\Entity\Task;
use Acme\TaskBundle\Form\Type\SaveTaskType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class ManageTasksController extends Controller
{
public function showListAction(Request $request)
{
$repository = $this->getDoctrine()->getRepository('ExampleBundle:Task');
$tasks = $repository->findAll();
$taskSaveForm = $this->createForm(new SaveTasksType(['tasks' => $tasks]));
return $this->render('AcmeTaskBundle:Task:list.html.twig', array(
'taskSaveForm' => $taskSaveForm->createView(),
));
}
}
Task Form Twig Template (just related part):
<div class="innerAll">
{{ form_start(taskSaveForm) }}
{{ form_errors(taskSaveForm) }}
<table class="table table-bordered table-striped table-primary list-table">
<thead>
<tr>
<th>Task ID</th>
<th>Title</th>
<th>Start Date</th>
<th>User</th>
<th>Company</th>
<th>Project</th>
<th>Description</th>
<th>Active</th>
</tr>
</thead>
<tbody>
{% for task in taskSaveForm.tasksCollection %}
<tr>
<td>{{ task.id }}</td>
<td>{{ task.title }}</td>
<td>{{ task.startDate }}</td>
<td>{{ task.userName }}</td>
<td>{{ task.companyName }}</td>
<td>{{ task.projectName }}</td>
<td>{{ form_widget(task.description) }}</td>
<td>{{ form_widget(task.active) }}</td>
<td></td>
</tr>
{% endfor %}
</tbody>
</table>
<div>{{ form_row(taskSaveForm.tasksSubmit) }}</div>
{{ form_end(taskSaveForm) }}
</div>
BUT there is an issue here, when I get the result from query builder it is a mess of arrays containing objects in them, I get an error about
The form's view data is expected to be an instance of class Acme\TaskBundle\Entity\Task, 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 Acme\TaskBundle\Entity\Task.
This is the query:
createQueryBuilder()
->select(
"
task.id,
task.title,
task.startDate,
task.description,
user.name as userName,
company.name as companyName,
project.name as projectName,
"
)
->from('Acme\TaskBundle\Entity\Task', 'task')
->innerJoin('task.project', 'project')
->innerJoin('task.user', 'user')
->innerJoin('Acme\TaskBundle\Entity\Company', 'company', 'with', 'store.company = company')
->where('task.active = :isActive')->setParameter('isActive', true);
Soooo, I used Partial Objects guide to see if it can help, it helps to make the task object in the query result and I could extract it and send it to form, but still it seems the rest of form is unaware of the rest of objects...
Ok, so maybe I'm choosing the wrong approach, I'm not sure! please if you have any suggestions about what should I do, put a note here... I'm struggling with this for more than a week! Thanks in advance for your time! Even if you don't put any note, I appreciate that you spend time reading my very long question! Thanks! :)
Here's a start on a possible solution. The example below takes a single entity Skills and presents all of them on a single page. What I don't know is whether this technique can be used to persist children objects. I would expect one could loop through the returned data and persist as required.
The code below results in a page with a list of all possible Skills and a checkbox for declaring each enabled or enabled.
In a controller:
$skills = $em->getRepository("TruckeeMatchingBundle:Skill")->getSkills();
$formSkills = $this->createForm(new SkillsType(), array('skills' => $skills));
...
if ($request->getMethod() == 'POST') {
$formSkills->handleRequest($request);
foreach ($skills as $existingSkill) {
$em->persist($existingSkill);
}
}
...
return ['formSkills' => $formSkills->createView(),...]
In a template:
{% for skill in formSkills.skills %}
{{ skill.vars.value.skill }}
<input type="hidden" name="skills[skills][{{ loop.index0 }}][skill]" value="{{ skill.vars.value.skill }}">
<input type="checkbox" name="skills[skills][{{ loop.index0 }}][enabled]"
{%if skill.vars.value.enabled %}checked="checked"{%endif%}
{% endfor %}
I use a different strategy. My TWIG file is similar to that of Monica's question. But has a few but very useful differences. Here your code:
{{ form_start(form) }}
{% for docente in docentes %}
Id: <input type="integer" name="{{ docente.id }}" required="required" style="width:30px" value="{{ docente.id }}" readonly>
Apellido: <input type="text" name="{{ docente.apellido }}" required="required" style="width: 80px" value="{{ docente.apellido }}" readonly>
Nombres: <input type="text" name="{{ docente.nombres }}" required="required" style="width: 80px" value="{{ docente.nombres }}" readonly>
Discrecional: <input type="checkbox" name="D{{ docente.id }}" value="{{ docente.discrecional }}" {% if docente.discrecional==1 %}checked{% endif %}> <br>
<br>
{% endfor %}
<input type="submit" value="Grabar" />
{{ form_end(form) }}
In TWIG file, I proceed to create a different name for each record in the form for the "discrecional" field. This will help me to identify each record in the controller. Watch up.
Once the user presses the "submit" button I perform an iteration in my Controller file, as shown below:
if ($form->isSubmitted() && $form->isValid()) {
$i=0;
foreach ($defaultData as $value) {
$data2= array('id' =>$request->request->get($defaultData[$i]['id']),
'discrecional' =>$request->request->get('D'.$defaultData[$i]['id']));
if (($request->request->get('D'.$defaultData[$i]['id'])== '0' and $defaultData[$i]['discrecional']=='0') or
($request->request->get('D'.$defaultData[$i]['id'])== NULL and $defaultData[$i]['discrecional']=='1'))
{
$em->getRepository('BackendBundle:Docentes')->findDocenteFiltId2($data2);
}
$i=$i+1;
}
But the update of registers, is a work that is done in my Repository file through a query using UPDATE, instead of doing it in the Controller file. To avoid unnecessary queries and a server overload, I only do an UPDATE of records that have previously changed. In the example, the following lines in my controller check if there has been a change in the record (in my case, I'm just editing a field called "discrecional". If the field has changed, then I call the query and update the record):
if (($request->request->get('D'.$defaultData[$i]['id'])== '0' and $Data[$i]['discrecional']=='0') or
($request->request->get('D'.$defaultData[$i]['id'])== NULL and $defaultData[$i]['discrecional']=='1'))
{
$em->getRepository('BackendBundle:Docentes')->findDocenteFiltId2($data2);
}
My complete Controller file is here:
public function discrecionalAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$defaultData= $em->getRepository('BackendBundle:Docentes')->buscarDocentesActivos2();
// construimos un formulario "vacĂo" sin campos definido
$form = $this->createFormBuilder($defaultData);
$form = $form->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$i=0;
foreach ($defaultData as $value) {
$data2= array('id' =>$request->request->get($defaultData[$i]['id']),
'discrecional' =>$request->request->get('D'.$defaultData[$i]['id']));
if (($request->request->get('D'.$defaultData[$i]['id'])== '0' and $defaultData[$i]['discrecional']=='0') or
($request->request->get('D'.$defaultData[$i]['id'])== NULL and $defaultData[$i]['discrecional']=='1'))
{
$em->getRepository('BackendBundle:Docentes')->findDocenteFiltId2($data2);
}
$i=$i+1;
}
return $this->redirectToRoute('docentes_discrecional');
}
return $this->render('docentes/discrecional.html.twig', array(
'docentes' =>$defaultData,
'form' => $form->createView() ));
}
My complete first Repository query is here:
public function buscarDocentesActivos2()
{
$fields = array('d.id', 'd.apellido', 'd.nombres', 'd.discrecional');
$query = $this->getEntityManager()->createQueryBuilder();
$query
->select($fields)
->from('BackendBundle:Docentes', 'd')
->where('d.activo=true')
->orderBy('d.apellido, d.nombres');
$consulta = $query->getQuery()->getResult();
return $consulta;
}
My complete final Repository query with the UPDATE function is here:
public function findDocenteFiltId2($filtro)
{
if (is_null($filtro['discrecional'])){
$discrec= '0';
};
if ($filtro['discrecional']=='0'){
$discrec= '1';
};
$em = $this->getEntityManager();
$consulta = $em->createQuery('
UPDATE BackendBundle:Docentes d
SET d.discrecional = :disc
WHERE d.id = :idver
');
$consulta->setParameters(array(
'idver' => $filtro['id'],
'disc' => $discrec,
));
return $consulta->getArrayResult();
}
I'm building a page in Symfony2 that permits me to search a term (e.g. a name of a person) in my Database and show in the same page (even after a page reload) all matching records (e.g. all the person with this name).
This is my anagrafica.html.twig
{# src/Acme/MyBundle/Resources/views/Page/anagrafica.html.twig #}
{% extends 'AcmeMyBundle::layout.html.twig' %}
{% block body %}
<form id="formsearch" name="p" method="get" action="anagrafica">
<span>
<input type="text" name="search_name" id="search_name" />
</span>
<input type="image" name="button_search" />
</form>
{% for anagrafica in anagrafiche %}
<article class="blog">
<div class="date">{{ anagrafica.DataNascita|date('c') }}</div>
<header>
<h2>{{ anagrafica.nome }}</h2>
</header>
<div class="snippet">
<p>{{ anagrafica.cognome }}</p>
<p class="show_complete">Show all data</p>
</div>
</article>
{% else %}
<p>There are no entries</p>
{% endfor %}
{% endblock %}
This is my PageController.php
<?php // src/Acme/MyBundle/Controller/PageController.php
namespace Acme\MyBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class PageController extends Controller {
//...
public function anagraficaAction() {
$em = $this->getDoctrine()
->getEntityManager();
$anagrafiche = $em->createQueryBuilder()
->select('b')
->from('AcmeMyBundle:Anagrafiche', 'b')
->where("b.nome = :nome")
->setParameter('nome', 'Alex' )
->addOrderBy('b.id', 'DESC')
->getQuery()
->getResult();
return $this->render('AcmeMyBundle:Page:anagrafica.html.twig', array('anagrafiche' => $anagrafiche));
}
}
I think I only need to update my PageController.php and replace the name 'Alex' in :
->setParameter('nome', 'Alex' )
with a variable that refers to the entry in my form definied in anagrafica.html.twig.
Anyway I have no idea of how to do this, and a quick search on google and forums do not helped me.
Any suggestion?
You get GET-parameters via
$searchName = $request->query->get('search_name');
But for this you still need the $request variable. You can use it as parameter and change your method signature to this:
public function anagraficaAction(Request $request)
This way, you can call the $request parameter in your method.
The other way is to get the request of the current controller inside your method.
$request = $this->get('request');
Using this you can change your setParameter to this:
setParameter('nome', $searchName)
change this setParameter('nome', 'Alex') to something like setParameter('nome', $_GET['search_name']) since this form passing data by using get method.
I found the solution. I edited my PageController.php such this:
<?php
// src/Acme/MyBundle/Controller/PageController.php
namespace Acme\MyBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
class PageController extends Controller
{
public function indexAction()
{
return $this->render('AcmeMyBundle:Page:index.html.twig');
}
public function infoAction()
{
return $this->render('AcmeMyBundle:Page:info.html.twig');
}
public function anagraficaAction(Request $request)
{
$em = $this->getDoctrine()
->getEntityManager();
$title = $request->get('search_name');
$anagrafiche = $em->createQueryBuilder()
->select('b')
->from('AcmeMyBundle:Anagrafiche', 'b')
->where("b.nome = :nome")
->setParameter('nome', $title )
->addOrderBy('b.id', 'DESC')
->getQuery()
->getResult();
return $this->render('AcmeMyBundle:Page:anagrafica.html.twig', array('anagrafiche' => $anagrafiche));
}
}
I have a table of data I want to be able to edit row-by-row. The most sensible thing do do would be to have each row be its own form. Can I do that in Symfony2 without a linked parent entity? The documentation only shows how to do it with a parent.
Your controller action:
public function gridAction( $criteria ) {
$entities = $this->getDoctrine()
->getManager()
->getRepository( 'Bundle:Entity' )
->findbyCriteria( $criteria );
// criteria presumably involves some gneration from routing
// and may not be a parameter at all
if ( array() != $entities->toArray() ) {
throw
$this->createNotFoundException( 'Unable to find any entities.' );
}
$forms = array_map(function($element) use ($this) {
return $this->createForm(new EntityType()
, $element
, array() // form parameters here
);
});
return $this->render( 'Bundle:Entity:grid.html.twig'
, array(
'forms' => $forms
) );
}
And your twig:
<table class="records_list dataTable" id="CaseloadTable">
<thead>
<tr>
</tr>
</thead>
<tbody>
{% for form in forms %}
<tr>
{{form_widget(form)}}
</tr>
{% endfor %}
</tbody>
</table>
However, you might be better served looking at this:
https://github.com/Abhoryo/APYDataGridBundle
I have a list of friends which should be displayed 3 in a page. Each friend has a category and I also have a drop down menu to choose to view only the friends which are from the chosen category. They should also be display 3 in a page. The way in which filtered and not filtered friends are displayed is the same so I didn't want to have two almost actions in my controller and two identic templates, so I tried to make this in one controller's action and template, but there is a problem. I can't make the pagination for the second and following pages of the filtered friends. Pleae help! :( The problem is that I use a form and when I click on the second page, the variable which was filled in the form and binded, become undefined. Here is the code:
Controller's action
public function displayAction($page, Request $request)
{
$em = $this->getDoctrine()->getEntityManager();
$user = $this->get('security.context')->getToken()->getUser();
$cat = new Category();
$dd_form = $this->createForm(new ChooseCatType($user->getId()), $cat);
if($request->get('_route')=='filter')
{
if($request->getMethod() == 'POST')
{
$dd_form->bindRequest($request);
if($cat->getName() == null)
{
return $this->redirect($this->generateUrl('home_display'));
}
$filter = $cat->getName()->getId();
if ($dd_form->isValid())
{
$all_friends = $em->getRepository('EMMyFriendsBundle:Friend')
->filterFriends($filter);
$result = count($all_friends);
$FR_PER_PAGE = 3;
$pages = $result/$FR_PER_PAGE;
$friends = $em->getRepository('EMMyFriendsBundle:Friend')
->getFilteredFriendsFromTo($filter, $FR_PER_PAGE, ($page-1)*$FR_PER_PAGE);
$link = 'filter';
}
}
}
else
{
$all_friends = $user->getFriends();
$result = count($all_friends);
$FR_PER_PAGE = 3;
$pages = $result/$FR_PER_PAGE;
$friends = $em->getRepository('EMMyFriendsBundle:Friend')
->getFriendsFromTo($user->getId(), $FR_PER_PAGE, ($page-1)*$FR_PER_PAGE);
$link = 'home_display';
}
// Birthdays
$birthdays = null;
$now = new \DateTime();
$now_day = $now->format('d');
$now_month = $now->format('m');
foreach ($all_friends as $fr)
{
if($fr->getBirthday() != null)
{
if($fr->getBirthday()->format('d') == $now_day && $fr->getBirthday()->format('m') == $now_month)
{
$birthdays[]=$fr;
$fr->setYears();
}
}
}
// Search
$search = new Search();
$s_form = $this->createFormBuilder($search)
->add('words', 'text', array(
'label' => 'Search: ',
'error_bubbling' => true))
->getForm();
// Renders the template
return $this->render('EMMyFriendsBundle:Home:home.html.twig', array(
'name' => $name, 'friends' => $friends, 'user' => $user, 'birthdays' => $birthdays, 'pages' => $pages, 'page' => $page, 'link' => $link,
'dd_form' => $dd_form->createView(), 's_form' => $s_form->createView()));
}
Template
{% if birthdays != null %}
<div>
<img class="birthday" src="http://www.clker.com/cliparts/1/d/a/6/11970917161615154558carlitos_Balloons.svg.med.png">
<div class="try">
This friends have birthday today:
{% for bd in birthdays %}
<p>
{{ bd.name }}
<span class="years">
({{ bd.years }} years)
</span>
</p>
{% endfor %}
</div>
</div>
{% endif %}
{% for fr in friends %}
{# TODO: Fix where are shown #}
{% if fr.getWebPath()!=null %}
<a href="{{ path('friend_id', {'id': fr.id}) }}">
<img class="avatar" src="{{ fr.getWebPath }}">
</a>
{% endif %}
{% if loop.index is odd %}
<p class="list1">
{% else %}
<p class="list2">
{% endif %}
<a class="friends" href="{{ path('friend_id', {'id': fr.id}) }}">{{ fr.name }}</a>
</p>
{% endfor %}
{# TODO: Pagination #}
{% if pages>1 %}
<p>
{% for i in 0..pages %}
{% if page == loop.index %}
<span class="pagination">{{ loop.index }}</span>
{% else %}
<span class="pagination">{{ loop.index }}</span>
{% endif %}
{% endfor %}
</P>
{% endif %}
<p>Choose category:</p>
<form class="search" action="{{ path('filter') }}" method="post" {{ form_enctype(s_form) }}>
{{ form_widget(dd_form.name) }}
{{ form_rest(dd_form) }}
<input type="submit" value="Show friends" />
</form>
Repository
class FriendRepository extends EntityRepository
{
public function getFriendsFromTo ($user, $limit, $offset)
{
return $this->getEntityManager()
->createQuery('SELECT f FROM EMMyFriendsBundle:Friend f WHERE f.user='.$user. 'ORDER BY f.name ASC')
->setMaxResults($limit)
->setFirstResult($offset)
->getResult();
}
public function filterFriends ($filter)
{
$q = $this->createQueryBuilder('f');
$q->select('f')
->where('f.category = :filter')
->setParameter('filter', $filter);
return $q->getQuery()->getResult();
}
public function getFilteredFriendsFromTo ($filter, $limit, $offset)
{
$q = $this->createQueryBuilder('f');
$q->select('f')
->where('f.category = :filter')
->setMaxResults($limit)
->setFirstResult($offset)
->setParameter('filter', $filter);
return $q->getQuery()->getResult();
}
}
I tried a lot of things, but there is always a problem. In this code it says that the variable $all_friends in the birthday for loop is not defined - and yes, it isn't. Maybe I have to store it in session and I tried this:
$session = $this->getRequest()->getSession();
$session->set('all_friends');
and then passing $friends=$session->get('all_friends'); to the for loop, but it doesn't work and isn't the variable $all_friends too big to store it?
Any ideas will be apreciated! Thank you for your time and effort!
EDIT
When I use the way with the session and
$session = $this->getRequest()->getSession();
$session->set('all_friends');
$fri=$session->get('all_friends');
foreach ($fri as $fr)
{ .... }
the error I get is
Warning: Invalid argument supplied for foreach() in C:\xampp\htdocs\MyFriends\src\EM\MyFriendsBundle\Controller\HomeController.php line 100
and also
Warning: Missing argument 2 for Symfony\Component\HttpFoundation\Session::set(), called in C:\xampp\htdocs\MyFriends\src\EM\MyFriendsBundle\Controller\HomeController.php on line 71 and defined in C:\xampp\htdocs\MyFriends\app\cache\dev\classes.php line 148
When I don't use session I get
Notice: Undefined variable: all_friends in C:\xampp\htdocs\MyFriends\src\EM\MyFriendsBundle\Controller\HomeController.php line 100
when I choose a category to show the friends from it, and I click its second page.
P.S. The lines from the errors don't corespond to the lines in the code I pasted, bacause I skipped some parts of the action, repository and template, because they don't have a part in this problem and they work correctly. If someone wishes, I can send him or update here all the code.
You are setting nothing on session :
$session->set('all_friends');
You should be doing this instead:
$session->set('all_friends', $data);
You should really start respecting Symfony2 coding standards too.
My eyes are melting when I try to read your code. You should read this and don't forget to create form class instead of creating form in your controller.
EDIT: If your $data is a result from a Doctrine2 query, I suggest that you store only the entity id and the entity class in order to fetch them later when you need it.
EDIT2: Here's some code that might help you saving on session filters data. PS, don't forget to add the missing use ....
/**
* Set filters
*
* #param array $filters Filters
* #param string $type Type
*/
public function setFilters($name, array $filters = array())
{
foreach ($filters as $key => $value) {
// Transform entities objects into a pair of class/id
if (is_object($value)) {
if ($value instanceof ArrayCollection) {
if (count($value)) {
$filters[$key] = array(
'class' => get_class($value->first()),
'ids' => array()
);
foreach ($value as $v) {
$identifier = $this->getDoctrine()->getManager()->getUnitOfWork()->getEntityIdentifier($v);
$filters[$key]['ids'][] = $identifier['id'];
}
} else {
unset($filters[$key]);
}
} elseif (!$value instanceof \DateTime) {
$filters[$key] = array(
'class' => get_class($value),
'id' => $this->getDoctrine()->getManager()->getUnitOfWork()->getEntityIdentifier($value)
);
}
}
}
$this->getRequest()->getSession()->set(
$name,
$filters
);
}
/**
* Get Filters
*
* #param array $filters Filters
* #param type $type Type
*
* #return array
*/
public function getFilters($name, array $filters = array())
{
$filters = array_merge(
$this->getRequest()->getSession()->get(
$name,
array()
),
$filters
);
foreach ($filters as $key => $value) {
// Get entities from pair of class/id
if (is_array($value) && isset($value['class'])) {
if (isset($value['id'])) {
$filters[$key] = $this->getDoctrine()->getManager()->find($value['class'], $value['id']);
} elseif (isset($value['ids'])) {
$data = $this->getDoctrine()->getManager()->getRepository($value['class'])->findBy(array('id' => $value['ids']));
$filters[$key] = new ArrayCollection($data);
}
}
}
return $filters;
}
EDIT3: Why you're not using KnpPaginatorBundle for pagination ?