SonataAdmin: replace ID in breadcrumbs - symfony

How can I replace Object's ID in SonataAdmin breadcrumbs by some other text?
If I set __toString() in my document, it works only for editing. When I attempt to create new record, there is something like MyDocument:0000000000e09f5c000000006a48ef49 in the last breadcumb.
I'm searching for a method which allows me to set some text as the last breadcump if Document::toString() returns null.

This behaviour is implemented directly in the entity:
public function __toString()
{
return $this->getFoo() ? : '-';
}
Bundles are using variants of this, including return (string)$this->getFoo(); or $this->getFoo() ? : 'n/a'; etc.
Related question: toString method for SonataAdminBundle Listing in Symfony2

BTW something cool to know, you can completely customize the breadcrumb via a Twig template:
{% block sonata_breadcrumb %}
{% set _breadcrumb %}
<li>Home</li>
<li>Library</li>
<li class="active">Data</li>
{% endset %}
{{ parent() }}
{% endblock %}

Related

Using raw Cypher to query Neo4j in Symfony

I am trying to go throught this tutorial: http://www.sitepoint.com/adding-social-network-features-php-app-neo4j/ But using the Symfony Framework instead of Silex.
I have been able to set up Neo4j to run with Symfony and am able to right user data to the graph. Now I would like to display all user email addresses in a list. I have taken this script:
public function home(Application $application, Request $request)
{
$neo = $application['neo'];
$q = 'MATCH (user:User) RETURN user';
$result = $neo->sendCypherQuery($q)->getResult();
$users = $result->get('user');
return $application['twig']->render('index.html.twig', array(
'users' => $users
));
}
And adapted it to read:
public function showUsersAction()
{
$em = $this->container->get('neo4j.manager');
$query = 'MATCH (n:`User`) RETURN n';
$users = $em->cypherQuery($query);
//print_r($users);
return $this->render('UserBundle:Account:showUsers.html.twig', array('users' =>$users));
}
And The twig looks as follows:
{% extends '::base.html.twig' %}
{% block content %}
<h1>get all users:</h1>
<ul>
{% for user in users %}
<li>{{ user.property('email') }}</li>
{% endfor %}
</ul>
{% endblock %}
But something in the twig is wrong, im getting the error:
Method "property" for object "Everyman\Neo4j\Query\Row" does not exist in UserBundle:Account:showUsers.html.twig at line 6
The problem was found in the syntax of the twig file. After consulting this page: https://github.com/jadell/neo4jphp/wiki/Cypher-and-gremlin-queries it became clear, that I had to include user['n'] in my twig template. The twig template now looks as such:
{% extends '::base.html.twig' %}
{% block content %}
<h1>get all users:</h1>
<ul>
{% for user in users %}
<li>{{ user['n'].getProperty('email') }}</li>
{% endfor %}
</ul>
{% endblock %}
I'm the author of the article you mentioned. The thing is that you use a different neo4j library than the one used in the article, hence neoclient, so the methods used in the article are different than the methods provided with neo4jphp.
As NeoClient uses heavily the Symfony components, integrating it in Symfony is really easy, you just need to override the DI. Example here : https://github.com/graphaware/GithubNeo4j/tree/master/src/GraphAware/Neo4jBundle
You'll then be able to use the methods illustrated in the 3 articles I wrote on Sitepoint.
So your problem with the twig template is that he doesn't find the getProperty method of the node object class, which is normal as neo4jphp returns Row object classes.
If you switch back to neoclient, as in the article, in the Twig template you can just write :
{% for user in users %}
<li>{{ user.getProperty('email') }}</li>
{% endfor %}

Activity Log in dashboard sonata admin

I'm trying to implement activity log in the dashboard i.e. a notification in each row that says which entities have a change since the last login of a user.
To do it I'm thinking about overwrite the class AdminListBlockService and the template block_admin_list.html.twig
but i don't have yet clear how do it.
someone know a better way to do it? if that is the better way, how can I achieve it?
thanks a lot!
ok
I found a better way... i have overwritten only the block_admin_list.html.twig so:
//config.yml
sonata_admin:
templates:
list_block: AdminBundle:Block:block_admin_list.html.twig
note the diference "SonataAdminBundle" and "AdminBundle"
next step add in the template:
{% if admin.activityLog() is defined and admin.isGranted('LIST') %}
<a class="btn btn-link" href="{{ admin.generateUrl('list')>admin.activityLog</a>
{% endif %}
and finally create the logic for each Entity where i want the notification
//in the exempleAdmin
public function activityLog(){
// custom code $activity= ....
return $activity;
}
if someone know a better way to do it, please let me know, thanks
Well what you can do is override the template like this:
In your admin class:
// Configure our custom roles for this entity
public function configure() {
parent::configure();
$this->setTemplate('list', 'MyAdminBundle:CRUD:list-myentity.html.twig');
}
Then in your template you can do something like:
{# The default template which provides batch and action cells, with the valid colspan computation #}
{% extends 'SonataAdminBundle:CRUD:list.html.twig' %}
{% block table_body %}
<tbody>
{% for object in admin.datagrid.results %}
<style>
table tr.green-color td {background-color: #2BFF5D !important; }
</style>
<tr {% if changed %} class="green-color" {% endif %}>
{% include admin.getTemplate('inner_list_row') %}
</tr>
{% endfor %}
</tbody>
{% endblock %}

Symfony2 form collection — Show only the newest

I have a form with a Parent (Entity) and Children (Record).
A Parent has many children.
So far so good.
What I need is, that if I edit a Parent I want to show only the newest child as a form collection and not all of them.
Right now with the creation of such I just make it like this:
$entity = new WikiEntity();
$record = new WikiRecord();
$entity->addWikiRecord($record);
And with this I have just one form collection — obviously.
Now I am looking for a method to have only the newest Record (child) to edit and all of the older one shouldnt be there.
Just to say what my goal is (maybe there are other solutions), I want to create something like a wiki, so everytime the Parent gets edited a new revision gets created, so I can get an older version or something. So the people don't need to see all of the versions (what form collection does) but only the newest one (which will be created each time you edit it).
I see there is no option to edit only the newest WikiRecord on symfony2 form collection type. But it can be done by manipulating form output in template.
So, here is how I could do using twig template.
{% for record in edit_form.wikiRecord %}
{% if loop.length > 1 %}
{% if loop.last %}
{{ form_label(record.aFieldName) }}
{{ form_widget(record.aFieldName) }}
{% else %}
{{ form_widget(record.aFieldName, { 'attr': {'style': 'display: none'} }) }}
{% endif %}
{% else %}
{{ form_row(record) }}
{% endif %}
{% endfor %}
I used this for a more or less similar situation where I have to make only the latest children editable. So, this work-around is working. :)
Okay I found an Answer for my problem.
I just manipulate my getWikiRecords() function to only return the newest (In the parent function)
So now in the parent Entity for the children it looks like this:
public function getWikiRecords() {
$oneRecord = new ArrayCollection();
$oneRecord[] = $this->wikiRecords->last();
return $oneRecord;
}
Of course if I want all the Children I now have to use a different get function.

How can I change symfony2 form fields default options globally?

Is there a way to change default options for form fields globally in symfony2?
More specifically, I want to change the render of ALL datetime fields to use single_text instead of the default choice widget.
Can it be done? Or do I need to implement a custom type and set the default in there, like for example the birthdate type?
I prefer an option that leads to minimal changes in the codebase.
The post is old, but you can use an alternative method, overriding the DateType symfony class ...
service.yml
services:
form.type.date:
class: "YourApp\YourBundle\Form\DateType"
tags:
- { name: "form.type", alias: "date" }
DateType.php
<?php
namespace YourApp\YourBundle\Form;
use Symfony\Component\Form\Extension\Core\Type\DateType as SymfonyDateType;
use Symfony\Component\OptionsResolver\OptionsResolver;
class DateType extends SymfonyDateType
{
/**
* {#inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
parent::configureOptions( $resolver );
$resolver->setDefault( 'widget', 'single_text' );
}
}
You can check if the service is taken by container
$ ./app/console debug:container | grep form.type.date
form.type.date YourApp\YourBundle\Form\DateType
form.type.datetime Symfony\Component\Form\Extension\Core\Type\DateTimeType
You have to define a form theme.
It's very easy and requires only a little bit coding time. First of all, you have to know which block to customize; in that case, you can do something like
{% block my_data_widget %}
{% spaceless %}
{% if type is defined and type == 'date' %}
// do all your customization
{% else %}
// don't know ...
{% endif %}
{% endspaceless %}
{% endblock form_widget_simple %}
Now that you have defined this snippet of code, you can use it into your main template (or whatever you use into your form views) in that way
{% form_theme form 'YourBundle:Form:myDataWidget' %}
Last but not least important, you have to place your form theme into Resources/views folder. In my example, your path will be Resources/views/Form/myDataWidget
Update
Did you tried with
{% set type = type|default('single_text') %}
or something like that?

symfony2 - twig - how to render a twig template from inside a twig template

I have a xxx.html.twig file which shows a page, but when I want to refresh the page with different data and just update it with new data, I have a select and a submit button for it.
The thing is that I don't know how do I call an action in the controller which I pass parameters to from my twig and call for new data and then I render the same twig template again with new parameters.
How do I do so?
Here are a few different ways:
{{ render(app.request.baseUrl ~ '/helper/test', {"hostid2": hostid } ) }}
or
{% include 'MyCoreBundle:Helper:test.html.twig' with {"hostid2": hostid } only %}
or
{% render controller("MyCoreBundle:Helper:test", {'hostid2': hostid}) %}
Symfony 2.1:
{% render 'YourBundle:YourController:yourAction' with {'var': value} %}
Symfony 2.6+:
{{ render(controller('YourBundle:YourController:yourAction', {'var': value})) }}
And, of course, read the documentation.
I think some parts are depricated here.
To make the include work in latest Symfony 3.1.10, I solved it like this:
{% extends 'base.html.twig' %}
{% block body %}
{{ include('AppBundle:Default:inner_content.html.twig') }}
{% endblock %}
Note: include() with parentheses.
Then all the variables are included from the parent template. If you like to restrict some variables in the child template, you use with ... only (look over)

Resources