Exclude some fields in findAll Symfony2 - symfony

I use this code for getting all users in the database
$users= $this->getDoctrine()
->getRepository('AppBundle:Users')
->findAll();
return $this->render('livre/users.html.twig',array(
'users' => $users,
));
But me I want get only some fields sush as name,email and hide fields like password..
Thanks.

You can do it by this way:
1/ Create a specific method in the UserRepository class:
public function findByNameAndEmail()
{
$query = $this->createQueryBuilder('u')
->select('u.name, u.email') // where name & email are properties of your User entity
;
return $query->getQuery()->getResult();
}
2/ And, call it in your controller:
public function someAction()
{
$users = $this->getDoctrine()->getRepository('AppBundle:Users')->findByNameAndEmail();
return $this->render('livre/users.html.twig',array(
'users' => $users,
));
}

Related

How can I call method of entity in a repository querybuilder

I have this scenario:
a entity Person, a repository for Person and a select form type.
I should take in my select form only active person.
In the entity there is a public method "isActive" that check if a Person have the permission to access in my private area. This method return true or false and is not a column in the db table, it is calculated.
I need to access this flag from my querybuilder in the Person repository.
Is it possible?
below the code of my querybuilder in the repository.
public function getQueryBuilderForEventRegistration()
{
$queryBuilder = $this->createQueryBuilder('e')->orderBy('e.surname', 'asc')->addOrderBy('e.name', 'asc');
return $queryBuilder;
}
and the public method in the entity Person tha t i have to access:
public function getIsActive()
{
if (empty($this->getUser()))
{
return false;
}
if (!$this->getUser()->isEnabled())
{
return false;
}
/* #var $service \Siderweb\SubscriptionBundle\Entity\UserService */
foreach ($this->getUser()->getServices() as $service)
{
if (!$service->getIsExpired())
{
return true;
}
}
return false;
}
and my type:
$builder->add('personExist', 'entity', array(
'class' => 'MyAppUserBundle:Person',
'property' => 'name',
'required' => false,
'multiple' => false,
'mapped' => false,
'empty_value' => '-- New person --',
'query_builder' => function(PersonRepository $repo) use ($options) {
return $repo->getQueryBuilderForEventRegistration();
}
))
as suggested I edit my repository like this:
public function getQueryBuilderForEventRegistration(Company $company = null, Event $event = null, $emailFilter = null)
{
$queryBuilder = $this->createQueryBuilder('e')->orderBy('e.surname', 'asc')->addOrderBy('e.name', 'asc');
$people = $queryBuilder->getQuery()->execute();
$peopleToShow = array();
foreach ($people as $person)
{
if ($person->getIsActive())
{
array_push($peopleToShow, $person);
}
}
return $peopleToShow;
}
but now I don't know how to put this array in my typeForm. Any idea?
Okay, so you can't call entity method on the query builder, but you can on the query results. Doctrine will hydrate your entity objects with the data that is returned from the database.
Once you have your results you can call the isActive() method on the hydrated entities.
The way that you're trying to implement this (getting the query builder for the form), you will need an isActive column in your database table and add a 'where' clause like so:
public function getQueryBuilderForEventRegistration()
{
$queryBuilder = $this->createQueryBuilder('e')
->where('e.isActive', true)
->orderBy('e.surname', 'asc')
->addOrderBy('e.name', 'asc');
return $queryBuilder;
}
It is not possible to call a Custom PHP method a SQL query, so Doctrine's QueryBuilder does not allow that. You will need either to have isActive as a database field (or custom method), or to reproduce you getIsActive method with QueryBuilder conditions.
You could use the filter function to filter the array on the template.
In my case I have an entity that has a canBeProcessed method ( which depends on many things ).
So, when I want to show in the index method of the controller only those records that
"canBeProcessed" I use this :
{% for emitted_note in pagination|filter( emitted_note => emitted_note.canBeProcessed == true ) %}
<tr><td>{{emitted_note.data}}</td><tr>
{% endfor %}
Here's the twig documentation.
https://twig.symfony.com/doc/2.x/filters/filter.html
Regards.

Best way to manage filer form and result page

What's the best way to manage filter page and result page in Symfony?
I have a controller that manage filter form and execute query. The result of this query must pass in another controller action. The result must show in another controller action because I used knp_paginator. If I render the result in same controller action of filter form, when change page the controller show filter form and not result.
this is the approach that I used:
Action for create find form:
public function findAction(Request $request)
{
$form = $this->createFindForm($request);
$form->handleRequest($request);
if(($form->isSubmitted() && !$request->isXmlHttpRequest()))
{
if(($this->isValidFindForm($form) && $form->isValid()))
{
$parm = $request->request->get('findForm');
return $this->redirect($this->generateUrl('list_documents',$parm));
}
}
return $this->render(
'myBundle:Documents:document\document_find.html.twig',
array('form' => $form->createView())
);
}
private function createFindForm(Request $request)
{
$form = $this->createForm(
new findDocumentType(
$this->getDoctrine()->getManager(),
$request
),
null,
array(
'action' => $this->generateUrl('find_documents'),
'method' => 'POST',
)
);
return $form;
}
I used $parm = $request->request->get('findForm'); to get the querystring. "findForm" is the name of my filter form.
The redirecting action :
public function listAction(Request $request)
{
$documents = $this->searchDocument($request);
$paginator = $this->get('knp_paginator');
$pagination = $paginator->paginate(
$documents,
$this->get('request')->query->get('page', 1)
);
return $this->render(
'myBundle:Documents:document\document_list.html.twig',
array('pagination' => $pagination)
);
}
The request is passed to search function (request contains querystring)
In search action:
private function searchDocument(Request $request)
{
$parm = $request->query;
$repository = $this->getDoctrine()->getRepository('docliteBundle:Document\\document');
$query = $repository
->createQueryBuilder('d');
....
With $request->query->get() I have access to all parameter.
Hope this help someone.
P.S. for the pagination I used KNP_paginator

Sonata Admin configureListFields show through query

I am using sonata admin bundle for admin panel. I want to show data in configureListFields through query. I have table userChoiceProduct and fields :-
User_Id
Product_Id
These fields automatically fill when user select any product and submit form. But these fields no relationship to other table.and I want to show User Email and Product Name in configureListFields
bases on User_Id and Product_Id.
Thanks!
I solved this:-
In Sonata Admin list :-
->add('User Email', null, array('template' => 'ABCAdminBundle:UserChoiceProduct:user.html.twig'))
->add('Product Name', null, array('template' => 'ABCAdminBundle:UserChoiceProduct:prodcut.html.twig'))
I mentioned one twig file (user.html.twig) for example :
<td>{{object.userId|getUserDetail()}}</td>
And create getUserDetail() in twig extension :-
class ABCExtension extends \Twig_Extension {
private $generator;
private $container;
public function __construct(UrlGeneratorInterface $generator, Container $container) {
$this->generator = $generator;
$this->container = $container;
}
public function getFilters() {
return array(
'getUserDetail' => new \Twig_Filter_Method($this, 'getUserDetail'),
);
}
public function getUserDetail($userId)
{
$em = $this->container->get('doctrine')->getManager();
$user = $em->getRepository('ABCUserBundle:User')->findOneBy(array('id' =>$userId));
if(empty($user)){
$userEmail = 'User does not Exist';
return $userEmail;
}else{
$userEmail = $user->getEmail();
return $userEmail;
}
}
}
And then all work is done successfully.
You can use the createQuery method in your admin to customize the parent query, like that :
public function createQuery($context = 'list') {
$query = parent::createQuery($context);
$query
->addSelect('u')
->leftJoin('Path\To\User\Entity', 'u', \Doctrine\ORM\Query\Expr\Join::ON, 't0_.User_Id = u.id')
;
return $query;
}
By getting and replacing t0_ by the prefix of userChoiceProduct table in main query.

Sorting Object Array in Symfony on the basis of date & time

//Suppose Entity Notes has property 'creationdate' & 'getCreationDate()' method to access.
DefaultController extends Controller {
public function indexAction(){
$em = $this->getDoctrine()->getManager();
$repository = $em->getRepository('Bundle:Notes');
$notes = $repository->findBy(array('userid' => $userId);
//Now I want to sort the notes array as per creation date using usort
usort($notes, array($this,"cmp"));
}
function cmp($a, $b) {
return strtotime($a->getCreationDate()) > strtotime($b->getCreationDate())? -1:1;
}
}
You can set the order in your call to the repository rather than after like so...
$notes = $repository->findBy(
array('userid' => $userId), // search criteria
array('creationdate' => 'ASC') // order criteria
);
I know you said you wanted to use usort but it seems kind of unnecessary.

Symfony2 passing parameters to twig

I'm working with Symfony 2 and I want to pass from my controller to my twig template a simple string and then use it on my template to descriminate the user role.
The controller code has something like :
public function modify_user_asAction(Request $request, $username)
{
$stringtopass="admin";
$um = $this->get('fos_user.user_manager');
$user = $um->findUserByUsername($username);
if($user == null){
//error page here..
}
$form = $this->createForm(new UserForm(), $user);
$form->handleRequest($request);
if ($form->isValid()) {
$um->updateUser($user);
return $this->redirect($this->generateUrl('acme_query_success'));
}
return $this->render('AcmeUserBundle:Default:modifyuserform.html.twig', array(
'form' => $form->createView(),
));
}
I want to pass $stringtopass in the generateUrl (if it's possible).
I can't find anything online.
Thanks
You are almost there!
API: generateUrl
Basically, just pass an array as second param to generateUrl.
return $this->redirect($this->generateUrl('acme_query_success', array('stringToPass' => $stringtopass)));
And also, #Brewal has a very valid point there. Be careful not to pass some sensitive data or leave unrestricted access to that controller's action. You could do more harm than good...
UPDATE:
public function acmeQuerySuccessAction(){
// ... action's logic
$stringToPass = $this->getRequest()->query->get('stringToPass');
// .....
return array(
'stringToPass' => $stringToPass,
// all other elements that you would normally return
);
}

Resources