Symfony 2.8 Jobeet Day 12: The Admin Bundle
With the addition we made in day 11 on Jobeet, the application is now fully usable by job seekers and job posters. It’s time to talk a bit about the admin section of our application. Today, thanks to the Sonata Admin Bundle, we will develop a complete admin interface for Jobeet in less than an hour.
Installation of the Admin Bundle
First we need to download the bundle using composer:
composer require sonata-project/admin-bundle
We also need a related storage bundle, we will use the SonataDoctrineORMAdminBundle:
composer require sonata-project/doctrine-orm-admin-bundle
As always, the next step is to enable the two bundles in the AppKernel.php
file:
Now let’s configure the installed bundles (add the following to the config.yml
file):
Also, uncomment the translator
line from the same config.yml
file:
translator: { fallbacks: ['%locale%'] }
Import the routing:
Finally, clear the cache and install the assets:
php app/console cache:clear
php app/console assets:install web --symlink
Now if you visit http://jobeet.local/app_dev.php/admin/dashboard you will find the empty admin dashboard:
Creating the Admin class
The Admin class represents the mapping of your model and administration sections (forms, list, show). The easiest way to create an admin class for your model is to extend the Sonata\AdminBundle\Admin\AbstractAdmin
class. We will create the admin classes in the admin folder of our bundle.
For categories (src/AppBundle/Admin/CategoryAdmin.php
):
And for jobs (src/AppBundle/Admin/JobAdmin.php
):
Now we need to add each admin class in the services.yml
configuration file:
At this point we can see in the dashboard the Job and Category modules, with their respective add and list links.
Configuration of Admin Classes
At this point, if we follow any link it will not work. That’s because we haven’t configure the fields that belong to the list and the form. Let’s do a basic configuration, first for the categories:
For this to work we need to make a small change to the __toString
method of the Category
entity:
And now for the jobs:
For the show action we used a custom template to show the logo of the company (app/Resources/views/jobAdmin/list_image.html.twig
):
In the form we need a new Job property, file
to use it as a placeholder for the logo uploaded file. We will use this instead of the logo
property when uploading images so we need to make some changes.
First, in the Job.php
file, add the new property and remove the Image
validator from the logo
:
Now change the JobUploadListener
to use this new field:
In the JobController
, remove the code from the edit action that was changing the logo
from a string
to a File
object:
Finally, in the JobControllerTest.php file, replace the logo
field with file
when testing the job form:
Everything should be working fine now.
With this, we created a basic administration module with CRUD operations for our jobs and categories. Some of the features you will find when using it are:
- The list of objects is paginated
- The list is sortable
- The list can be filtered
- Objects can be created, edited, and deleted
- Selected objects can be deleted in a batch
- The form validation is enabled
- Flash messages give immediate feedback to the user
Batch Actions
Batch actions are actions triggered on a set of selected models (all of them or only a specific subset). You can easily add some custom batch action in the list view. By default the delete
action allows you to remove several entries at once.
To add a new batch action we have to override the getBatchActions
from the Admin class. We will define here a new extend
action:
The method batchActionExtend
, form a newJobAdminController
, will be executed to achieve the core logic. The selected models are passed to the method through a query argument retrieving them. If for some reason it makes sense to perform your batch action without the default selection method (for example you defined another way, at template level, to select model at a lower granularity), the passed query is null.
To make this work you have to add it as an argument to the app.admin.job
service definition in the services.yml
file:
Let’s add a new batch action that will delete all jobs that have not been activated by the poster for more than 60 days. For this action we don’t need to select any jobs from the list because the logic of the action will search for the matching records and delete them.
In addition to create the batchActionDeleteNeverActivated
action, we will create a new method in our JobAdminController
, batchActionDeleteNeverActivatedIsRelevant
, that gets executed before any confirmation, to make sure there is actually something to confirm (in our case it will always return true because the selection of the jobs to be deleted is handled by the logic found in the JobRepository::cleanup()
method.
That’s all for today! Next time, we will see how to secure the admin section with a username and a password. This will be the occasion to talk about the Symfony security. The code from today can be found here: https://github.com/dragosholban/jobeet-sf2.8/tree/day12.
About the Author
Passionate about web & mobile development. Doing this at IntelligentBee for the last 5 years. If you are looking for custom web and mobile app development, please contact us here and let’s have a talk.