i need to display the list of users where they registred after fixed date for example i need to replay the list of users after 2014-03-01 17:34:04 and the the custom 's type in my table User is datetime.
$user = $em->getRepository('UserUserBundle:user')->findBy();
Here is an example of query to get the users after a chosen datetime (assuming that the field containing the datetime is named datetime):
public function yourControllerAction()
{
$dt = new \Datetime('2014-03-01 17:34:04');
$qb = $this->getDoctrine()
->getRepository('UserUserBundle:user')
->createQueryBuilder('u');
$users = $qb
->where(
$qb->expr()->gte('u.datetime',
$qb->expr()->literal($dt->format('Y-m-d H:i:s'))
)
)
->getQuery()
->getResult()
;
return $this->render(
'UserUserBundle:Default:index.html.twig',
array(
'users' => $users
)
);
}
I don't know if it's the best way by calling literal() but it works for me.
Then you'll have to display the users in your Twig template:
{% for user in users %}
{% user.id %}
...
{% endfor %}
Related
What is best practice to include another info in form from another entity?
I have Student Entity, Group Entity, StudentsGroup and Attendance Entity.
Student have id, code, and name.
Group have id and name.
StudentsGroup have id, group_id, and student_id.
Attendance have id, students_group_id, date and status.
Group can have many Student which saved in StudentsGroup. Why I make StudentsGroup? Because actually 1 Group can have some sub groups like SubjectsGroup etc. And Attendance save student information by StudentsGroup Id which same student can have different students_group_id.
Now, the problem is : How to show Student information in collection form of attendance?
All Entity relationship is declared as object, so actually we can access em freely from any entity. But I don't know how to do that in form. Here my form :
<?php
/* Collection Form */
$tanggal = new \DateTime($request->request->get('sifo_adminbundle_studentsgrouping')['tanggal']);
$attendances = new StudentsGrouping();
foreach ($entities as $temp) {
$entity = new Attendance();
$entity = $em->getRepository('SifoAdminBundle:Attendance')->findOneBy(array('studentsGrouping' => $temp, 'date' => $tanggal));
if ($entity){
$attendances->getAttendances()->add($entity);
}
}
$form = $this->createCollectionForm($attendances, $id, $tanggal);
return $this->render('SifoAdminBundle:DftAbsensi:manage.html.twig', array(
'form' => $form->createView(),
));
This is how I render it in twig :
{{ form_start(form_collection) }}
{{ form_row(form_collection.tanggal) }}
{% for attendance in form_collection.attendances %}
{{ form_row(attendance.status) }}
{% endfor %}
{{ form_end(form_collection) }}
## Concept ##
I'm thinking about creating entity and pass it into form like this :
foreach ($entities as $temp) {
$entity = new Student();
$entity = $em->getRepository('SifoAdminBundle:Student')->find($temp->getId());
if ($entity){
$entities[i] = $entity;
}
$i++
}
and then in twig show it like this :
{{ form_start(form_collection) }}
{{ form_row(form_collection.tanggal) }}
{% for key, attendance in form_collection.attendances %}
{{ entities[key].code }}
{{ entities[key].name }}
{{ form_row(attendance.status) }}
{% endfor %}
{{ form_end(form_collection) }}
But I feel not comfort with this. Am I really need to make new entity just for showing name and code from Student Entity? Is there a best practice to do this?
You can use entity field.
$builder->add('users', 'entity', array(
'class' => 'AcmeHelloBundle:User',
'multiple' => true, /* you can choose more than one */
'mapped' => false, /* if you are using the form with an entity */
'query_builder' => function(EntityRepository $er) {
/* use query builder to get correct results */
return $er->createQueryBuilder('u')->orderBy('u.username', 'ASC');
},
));
There are two important keys in above.
'multiple' => true ----- you can able to choose more than one
'mapped' => false ----- if you are using form with an entity, your form will automatically looks for a connection between these entities and if can not found, throws exception. to avoid of that problem you should set this option to false
http://symfony.com/doc/current/reference/forms/types/entity.html
Stumped on this. I want to link my post tags so that when it's clicked it lists all post to that tag, similar to a tag cloud---adding that functionality to the individual tags under the post.
Currently, I have it set it up to use the same function as my tag cloud but when I hover over one tag it shows all tags as I've used the blog results (blog.tags) in the for loop. See screen shot: (hovering over one tag shows all tags in the blog post)
When I use a get all tags and a for loop through those it works (gives me all posts by tags when I select on a specific tag), but it also lists all the tags and not the ones specific to the post which I don't want. (tags are stored as strings) See in screen.
How do I set it up to where it only shows me the specific tag I'm hovering over and not all tags in the post?
Twig
{% for blog in pagination %}
<p>Tags: <span class="highlight">{{ blog.tags }}</span></p><br><br>
{% endfor %}
Controller
public function indexAction($tag = null)
{
// Search function using code from Services/Search.php
$query = $this->get('search');
$results = $query->search();
$em = $this->getDoctrine()->getManager();
$blogs = $em->getRepository('AcmeDemoBundle:Blog')
->getBlogs();
// Get all tags
$tags = $em->getRepository('AcmeDemoBundle:Blog')
->getTags();
// Get all posts by tag
$postTags = $em->getRepository('AcmeDemoBundle:Blog')
->getPostsByTags($tag);
$paginator = $this->get('knp_paginator');
$pagination = $paginator->paginate(
$blogs,
$this->get('request')->query->get('page', 1)/*page number*/,
5/*limit per page*/
);
return array(
'blogs' => $blogs,
'query' => $query,
'results' => $results,
'tags' => $tags,
'postTags' => $postTags,
'pagination' => $pagination,
);
}
public function tagAction($tag = null)
{
$em = $this->getDoctrine()->getManager();
$tags = $em->getRepository('AcmeDemoBundle:Blog')
->getPostsByTags($tag);
if (!$tags) {
throw $this->createNotFoundException('Unable to find blog posts');
}
return array(
'tags' => $tags,
);
}
Noticed the code you use:
{% for blog in pagination %}
Tags: {{ blog.tags }}
{% endfor %}
It is not a recommended way.
The correct way is you have to use a nested loop and the tag links should be presented something like:
tag1
tag2
...
It is never a good idea to store all the tags in just one field and separated with comma or whatever:
Book1 | tag1, tag2, tag3,...
But it is recommended to do like this:
Book1 | tag1
Book2 | tag2
...
Hope this helps.
There is the following code
$form->with('Item')->add('parent', null, array(
'label' => 'Category',
'required' => true,
'query_builder' =>
function($er) use ($id) {
$qb = $er->createQueryBuilder('p');
if ($id){
$qb->where('p.id <> :id')
->setParameter('id', $id);
}
$qb->orderBy('p.root, p.lft', 'ASC');
return $qb;
}
.........
Result is the entity-objects collection which is given to the string (__toString method).
It return name-field.
But I need get the another field - url.
How to get url value instead the name in the select-list form?
The query_builder type return object => how to change this form that it works likewise query_builder?
I didn't work with SonataAdminBundle forms, but I think that it works absolutely like symfony forms. All that you need here is to add 'class' and 'property' values to your options list:
$form->with('Item')->add('parent', null, array(
'class' => 'Acme\DemoBundle\Entity\Category',
'property' => 'url',
'label' => 'Category',
'required' => true,
'query_builder' =>
function($er) use ($id) {
$qb = $er->createQueryBuilder('p');
if ($id){
$qb->where('p.id <> :id')
->setParameter('id', $id);
}
$qb->orderBy('p.root, p.lft', 'ASC');
return $qb;
}
property - is the name of the field in your entity that will represent your Entity's value instead of calling __toString().
But also... If you need always represent your Entity as URL you can simply override __toString() method in the Entity class to something like that:
public function __toString() {
return $this->url;
}
In my case, ->orderBy() used in query_builder worked, but was overwritten for unknown reasons "somewhere" later. Fun fact: when I used extended => true, everything was rendered like sorted in the query_builder. But by using extended => false my <option>s are re-sorted before select2 touched it.
As a workaround I did this:
config/packages/twig.yaml
twig:
paths:
'%kernel.project_dir%/templates': '%kernel.project_dir%/templates'
# This is to prevent a infinite loop when extending the parent template
'vendor/sonata-project/admin-bundle/src/Resources/views': SonataAdminBundleOriginal
And then I done the sorting I wanted again in twig for the project entity:
templates/bundles/SonataAdminBundle/Form/form_admin_fields.html.twig:
{% extends '#SonataAdminBundleOriginal/Form/form_admin_fields.html.twig' %}
{%- block choice_widget_options -%}
{% if name == 'project' %}
{% set options = options|sort((a, b) => a.data.numberSortable <=> b.data.numberSortable)|reverse %}
{% endif %}
{{ parent() }}
{%- endblock choice_widget_options -%}
Just in case if someone needs to "filter" an entity by a FK (foreign key) just like i needed (and searched for 3 days), here is the solution:
In the __construct you can set/find what you need. In my case i work this "sessions" (year). So i find the session->status=true:
$this->sessionActive = $this->sessionRepository->findOneBy(['status'=>true]);
Then in the QueryBuilder:
protected function configureQuery(ProxyQueryInterface $query): ProxyQueryInterface
{
$rootAlias = current($query->getRootAliases());
$query
->select($rootAlias)
->where($rootAlias.'.session = :id')
->addOrderBy($rootAlias.'.dateStart', 'ASC')
->setParameter('id', $this->sessionActive->getId());
return $query;
}
Note: I have always one Session->status set to "true". If you might have null values don't forget to make a condition so that it doesn't give you an error!
Regards.
I'm trying to make a count request on an id field.
I have the following code in my controller:
$qb = $em->createQueryBuilder();
$qb->select('count(c.id)')
->from('MyBundle:Category', 'c')
->where('c.author = :aut')
->setParameter('aut', $author);
$result = $qb->getQuery()->getResult();
return $this->render('MyCategoryBundle:Category:categories.html.twig', array(
'categories' => $categories,
'result' => $result
));
And in my view.html.twig :
{% for category in categories %}
<li>
{{ category.title }}
{% for total in result %}
{{ total }}
{% endfor %}
</li>
{% endfor %}
It returns the category title and the string "Array" just besides. What am I doing wrong ?
The getResult() returns an array (collection) of objects. You have to use the getSingleScalarResult() function in order to get the result as a simple number.
Anyway, what is the goal of your code? If you want to display the number of categories for each author, your code may not work since you display a list of categories but you only count the categories from one author.
Try this:
$qb = $em->createQueryBuilder();
$qb->select('count(c.id) AS cnt')
->from('MyBundle:Category', 'c')
->where('c.author = :aut')
->setParameter('aut', $author);
$result = $qb->getQuery()->getResult();
and then in twig {{result.cnt}}
I have a problem with Symfony2 and Twig: I don't know how to display all fields of my entity which is loaded dynamically. Here is my code (displays nothing!!)
Controller :
public function detailAction($id)
{
$em = $this->container->get('doctrine')->getEntityManager();
$node = 'testEntity'
$Attributes = $em->getRepository('TestBetaBundle:'.$node)->findOneById($id);
return $this->container->get('templating')->renderResponse('TestBetaBundle:test:detail.html.twig',
array(
'attributes' => $Attributes
));
}
detail.html.twig :
{% for key in attributes %}
<p>{{ value }} : {{ key }}</p>
{% endfor %}
Don't settle for just the public properties! Get the private/protected as well!
public function detailAction($id){
$em = $this->container->get('doctrine')->getEntityManager();
$node = 'testEntity'
$Attributes = $em->getRepository('TestBetaBundle:'.$node)->findOneById($id);
// Must be a (FQCN) Fully Qualified ClassName !!!
$MetaData = $em->getClassMetadata('Test\Beta\Bundle\Entity\'. $node);
$fields = array();
foreach ($MetaData->fieldNames as $value) {
$fields[$value] = $Attributes->{'get'.ucfirst($value)}();
}
return $this->container
->get('templating')
->renderResponse('TestBetaBundle:test:detail.html.twig',
array(
'attributes' => $fields
));
}
OK. What you are trying to do cannot be done with a Twig for loop over your attributes object. Let me try to explain:
The Twig for loop iterates over an ARRAY of objects, running the inside of the loop for each of the objects in the array. In your case, $attributes is NOT an array, it is an OBJECT which you retrived with your findOneById call. So the for loop finds that this is not an array and does not run the inside of the loop, not even once, that is why you get no output.
The solution proposed by #thecatontheflat does not work either, as it is just the same iteration over an array, only that you have access to both the keys and values of the array, but since $attributes is not an array, nothing is accomplished.
What you need to do is pass the template an array with the properties of the $Attributes object. You can use the php get_object_vars() function for this. Do something like:
$properties = get_object_vars ($Attributes);
return $this->container->get('templating')->renderResponse('TestBetaBundle:test:detail.html.twig',
array(
'attributes' => $Attributes
'properties' => $properties
));
And in the Twig template:
{% for key, value in properties %}
<p>{{ value }} : {{ key }}</p>
{% endfor %}
Take into account that this will only show the public properties of your object.
For Symfony3
$em = $this->getDoctrine()->getEntityManager();
$MetaData = $em->getClassMetadata('TestBetaBundle:Node');
$fields = $MetaData->getFieldNames();
return $this->render('test/detail.html.twig', array('fields'=>fields));
You should change it to
{% for key, value in attributes %}
<p>{{ value }} : {{ key }}</p>
{% endfor %}