Important
You are browsing the documentation for version 4.1 of OroCommerce, OroCRM and OroPlatform, which is no longer maintained. Read version 5.1 (the latest LTS version) of the Oro documentation to get up-to-date information.
See our Release Process documentation for more information on the currently supported and upcoming releases.
CRUD Operations¶
To let the users create new tasks and edit existing ones you need to perform several steps:
The Form Type¶
First, you need to create a form type that makes it possible to let the user enter all the data needed to describe a task:
1// src/AppBundle/Form/TaskType.php
2namespace AppBundle\Form;
3
4use Symfony\Component\Form\AbstractType;
5use Symfony\Component\Form\FormBuilderInterface;
6use Symfony\Component\OptionsResolver\OptionsResolver;
7
8class TaskType extends AbstractType
9{
10 public function buildForm(FormBuilderInterface $builder)
11 {
12 $builder
13 ->add('subject')
14 ->add('description')
15 ->add('dueDate')
16 ->add('priority')
17 ;
18 }
19
20 public function configureOptions(OptionsResolver $resolver)
21 {
22 $resolver->setDefaults([
23 'data_class' => 'AppBundle\Entity\Task',
24 ]);
25 }
26}
See also
Learn more about form types in the Symfony documentation.
The Controllers¶
You then need to create a controller class that comes with two actions: one that is called when a new task should be created, and one that is able to fetch an existing task to let the user modify its data:
1// src/AppBundle/Controller/TaskController.php
2namespace AppBundle\Controller;
3
4use AppBundle\Entity\Task;
5use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
6use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
7use Symfony\Bundle\FrameworkBundle\Controller\Controller;
8use Symfony\Component\HttpFoundation\Request;
9
10/**
11 * @Route("/task")
12 */
13class TaskController extends Controller
14{
15 /**
16 * @Route("/create", name="app_task_create")
17 * @Template("AppBundle:Task:update.html.twig")
18 */
19 public function createAction(Request $request)
20 {
21 return $this->update(new Task(), $request);
22 }
23
24 /**
25 * @Route("/edit/{id}", name="app_task_update", requirements={"id"="\d+"})
26 * @Template("AppBundle:Task:update.html.twig")
27 */
28 public function editAction(Task $task, Request $request)
29 {
30 return $this->update($task, $request);
31 }
32
33 private function update(Task $task, Request $request)
34 {
35 $form = $this->createForm(new TaskType(), $task);
36
37 return [
38 'entity' => $task,
39 'form' => $form->createView(),
40 ];
41 }
42}
Then, make sure that the controller is loaded in your routing configuration so that Symfony knows which controller needs to be called for particular routes:
1# src/AppBundle/Resources/config/routing.yml
2app_task:
3 resource: '@AppBundle/Controller/TaskController.php'
4 type: annotation
The Template¶
The template that is responsible to display the form fields should extend the base template
OroUIBundle:actions:update.html.twig
from the OroUIBundle. This templates defines some basic blocks
that you can use. This way your own forms will provide the same look and feel as the ones coming
with OroPlatform:
1{# src/AppBundle/Resources/views/Task/update.html.twig #}
2
3{# extend the base template from the OroUIBundle #}
4{% extends 'OroUIBundle:actions:update.html.twig' %}
5
6{# reuse the form theme provided with OroPlatform #}
7{% form_theme form with 'OroFormBundle:Form:fields.html.twig' %}
8
9{# make the current task accessible with the task variable #}
10{% set task = form.vars.value %}
11
12{# choose the appropriate action depending on whether a task is created or modified #}
13{# this variable needs to be named formAction as this is what the base template expects #}
14{% if task.id %}
15 {% set formAction = path('app_task_update', { 'id': task.id }) %}
16{% else %}
17 {% set formAction = path('app_task_create') %}
18{% endif %}
19
20{% block navButtons %}
21 {# the cancelButton() macro creates a button that discards the
22 entered data and leads the user to the linked controller #}
23 {{ UI.cancelButton(path('app_task_index')) }}
24
25 {# the dropdownSaveButton() macro offers a way to let the user select
26 between different options when saving an entity, the selected option
27 will be passed to the controller handling the request as an additonal
28 parameter #}
29 {{ UI.dropdownSaveButton({
30 'html': UI.saveAndCloseButton() ~ UI.saveAndStayButton()
31 }) }}
32{% endblock navButtons %}
33
34{% block pageHeader %}
35 {% if task.id %}
36 {% set breadcrumbs = {
37 'entity': task,
38 'indexPath': path('app_task_index'),
39 'indexLabel': 'Tasks',
40 'entityTitle': task.subject
41 } %}
42 {{ parent() }}
43 {% else %}
44 {% set title = 'oro.ui.create_entity'|trans({ '%entityName%': 'Task' }) %}
45 {{ include('OroUIBundle::page_title_block.html.twig', { title: title }) %}
46 {% endif %}
47{% endblock pageHeader %}
48
49{% block content_data %}
50 {% set id = 'task-edit' %}
51 {% set dataBlocks = [{
52 'title': 'General'|trans,
53 'class': 'active',
54 'subblocks': [{
55 'title': '',
56 'data': [
57 form_row(form.subject),
58 form_row(form.description),
59 form_row(form.dueDate),
60 form_row(form.priority),
61 ]
62 }]
63 }]
64 %}
65
66 {# the data variable is a special variable that is used in the
67 parent content_data block to render the visual content "blocks"
68 of a page #}
69 {% set data = {
70 'formErrors': form_errors(form) ? form_errors(form) : null,
71 'dataBlocks': dataBlocks,
72 } %}
73
74 {{ parent() }}
75{% endblock content_data %}
Linking the Data Grid¶
Finally, you need to link both actions on the page that displays the list of tasks:
1. Add a link to create new tasks
The base OroUIBundle:actions:index.html.twig
template from the OroUIBundle that you
already used to embed the data grid comes with a
pre-defined navButtons
block which you can use to add a button that links to the create task
action:
1{# src/AppBundle/Resources/views/Task/index.html.twig #}
2{% extends 'OroUIBundle:actions:index.html.twig' %}
3
4{% set gridName = 'app-tasks-grid' %}
5{% set pageTitle = 'Task' %}
6
7{% block navButtons %}
8 <div class="btn-group">
9 {{ UI.addButton({
10 'path': path('app_task_create'),
11 'entity_label': 'Create a task',
12 }) }}
13 </div>
14{% endblock %}
2. Link task rows to the related update action
To make it possible to modify each task you need to define a property that describes how the URL of the update action is built and then add this URL to the list of available actions in your data grid configuration:
1# src/AppBundle/Resources/config/oro/datagrids.yml
2datagrids:
3 app-tasks-grid:
4 # ...
5 properties:
6 id: ~
7 update_link:
8 type: url
9 route: app_task_update
10 params:
11 - id
12 # ...
13 actions:
14 # ...
15 edit:
16 type: navigate
17 label: Edit
18 link: update_link
19 icon: edit
Deleting Entities¶
You can delete a task either through the DELETE
operation available for all entities by default or through the customized one. When running DELETE
, ensure that your entity has a route from the routeName
option of the entity configuration.
You can delete an entity through the DELETE operation which is enabled by default for all entities. To run the operation, you need to ensure that your entity has the routeName
option of the entity configuration which will be used as a route name to redirect a user after the DELETE
operation (as in the example below).
1@Config(
2 routeName="oro_task_index",
3 routeView="oro_task_view",
4 defaultValues={
5 "entity"={
6 "icon"="fa-tasks"
7 },
See the sample configuration of the default DELETE
operation in the Actions topic.
If the default configuration is not valid for your particular case, create your own operation that would inherit from the default one following the example:
1DELETE:
2 exclude_entities:
3 - Oro\Bundle\CatalogBundle\Entity\Category
4
5oro_catalog_category_delete:
6 extends: DELETE
7 replace:
8 - exclude_entities
9 - entities
10 - for_all_datagrids
11 - for_all_entities
12 for_all_datagrids: false
13 for_all_entities: false
14 entities:
15 - Oro\Bundle\CatalogBundle\Entity\Category
16 preconditions:
17 '@and':
18 - '@not_equal': [$.data.parentCategory, null]
Note
When creating your own operation, make sure to exclude the entity from the default operation. See more details on available operations and their configuration in the related article.