Download - Symfony tips and tricks
PHPers Poznań #323.02.2016
Symfony tips & tricks
http://www.slideshare.net/javier.eguiluz/new-symfony-tips-tricks-symfonycon-paris-2015
Accessing request
parameters
/*** @param Request $request** @return JsonResponse*/public function getCandidateVisitAction(Request $request){ $candidateId = (int) $request->get('id'); $candidates = $this->getDoctrine() ->getRepository('EspeoCommonBundle:CandidateVisit') ->getVisitStatistics($candidateId);
return new JsonResponse($candidates);}
/*** @param Request $request** @return JsonResponse*/public function getCandidateVisitAction(Request $request){ $candidateId = $request->query->getInt('id'); $candidates = $this->getDoctrine() ->getRepository('EspeoCommonBundle:CandidateVisit') ->getVisitStatistics($candidateId);
return new JsonResponse($candidates);}
Namingstrategies
/*** CandidateVisit.** @ORM\Table(name="candidate_visit")* @ORM\Entity(repositoryClass="Espeo\CommonBundle\Entity\Repository\CandidateVisitRepository")*/class CandidateVisit{ /** * @var \DateTime * * @ORM\Column(name="date_visit", type="datetime") */ private $dateVisit;}
# app/config/config.yml
doctrine: dbal: (...) orm: naming_strategy: doctrine.orm.naming_strategy.underscore
<?php
namespace Doctrine\ORM\Mapping;
interface NamingStrategy{ function classToTableName($className);
function propertyToColumnName($propertyName, $className = null);
function referenceColumnName(); function joinColumnName($propertyName); function joinTableName($sourceEntity, $targetEntity, $propertyName); function joinKeyColumnName($entityName, $referencedColumnName = null);}
Twig &app.user
{% if app.user and is_granted('ROLE_ADMIN') %} ...{% endif %}
Email deliverywhitelist
# Swiftmailer Configurationswiftmailer: transport: "%mailer_transport%" host: "%mailer_host%" username: "%mailer_user%" password: "%mailer_password%" spool: type: file path: "%kernel.root_dir%/spool"
# app/config/config_dev.yml
swiftmailer: delivery_address: [email protected] delivery_whitelist: # all email addresses matching these regexes will be delivered # like normal, as well as being sent to [email protected] - '/@specialdomain\.com$/' - '/^admin@mydomain\.com$/'
Automatic "smoke testing"
for services
public function testContainerServices(){ $client = static::createClient(); foreach ($client->getContainer()->getServiceIds() as $serviceId) { $service = $client->getContainer()->get($serviceId); $this->assertNotNull($service); }}
public function testContainerServices(){ $client = static::createClient(); foreach ($client->getContainer()->getServiceIds() as $serviceId) { try { $startedAt = microtime(true); $service = $client->getContainer()->get($serviceId); $elapsed = (microtime(true) - $startedAt) * 1000; $this->assertLessThan(50, $elapsed); } catch(InactiveScopeException $e) { } }}
symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/converters.html
ParamConverter
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
/*** @Route("/blog/{id}")* @ParamConverter("post", class="SensioBlogBundle:Post")*/public function showAction(Post $post){}
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
/*** @Route("/blog/{id}")* @ParamConverter("post", class="SensioBlogBundle:Post", options={"entity_manager" = "foo"})*/public function showAction(Post $post){}
Bundle
http://jmsyst.com/bundles/JMSDiExtraBundle
JMSDiExtraBundle
// composer.json{ // ... require: { // ... "jms/di-extra-bundle": "dev-master" }}
#app/AppKernel.php
$bundles = array( // ... new JMS\DiExtraBundle\JMSDiExtraBundle($this), new JMS\AopBundle\JMSAopBundle(), // ...);
#app/config/config.yml
jms_di_extra: locations: all_bundles: false bundles: [FooBundle, AcmeBlogBundle] directories: ["%kernel.root_dir%/../src"]
<?php
namespace Espeo\CandidateBundle\Controller;
use Espeo\CandidateBundle\Service\CalendarEventProvider;use Espeo\CommonBundle\Controller\Controller;use Espeo\CommonBundle\Entity\Repository\CitiesRepository;use JMS\DiExtraBundle\Annotation as DI;use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;use Symfony\Component\Translation\TranslatorInterface;
class CalendarApiController extends Controller{ /** * @var CalendarEventProvider * @DI\Inject("espeo_candidate.calendar_event_provider") */ private $calendarEventProvider;
/** * @var TokenStorage * @DI\Inject("security.token_storage") */ private $tokenStorage;
/** * @var CitiesRepository * @DI\Inject("espeo_common.cities_repository") */ private $citiesRepository;}
<?php
class CalendarApiController extends Controller{ /** * @var CalendarEventProvider * @DI\Inject("espeo_candidate.calendar_event_provider") */ private $calendarEventProvider;
/** * @var TokenStorage * @DI\Inject("security.token_storage") */ private $tokenStorage;
/** * @var CityRepository * @DI\Inject("espeo_common.city_repository") */ private $cityRepository;}
private function getCoolCities(){ $cities = $this->cityRepository->getSosnowiecAndRadom();
return $cities;}
use JMS\DiExtraBundle\Annotation as DI;
class Controller{ private $em; private $session;
/** * @DI\InjectParams({ * "em" = @DI\Inject("doctrine.orm.entity_manager"), * "session" = @DI\Inject("session") * }) */ public function __construct($em, $session) { $this->em = $em; $this->session = $session; }}
https://github.com/willdurand/BazingaJsTranslationBundle
BazingaJsTranslationBundle
composer require "willdurand/js-translation-bundle"
// app/AppKernel.phppublic function registerBundles(){ return array( // ... new Bazinga\Bundle\JsTranslationBundle\BazingaJsTranslationBundle() );}
#app/config/routing.yml
_bazinga_jstranslation: resource: "@BazingaJsTranslationBundle/Resources/config/routing/routing.yml"
#app/config/assetic/js.yml
bazinga_js_translation_js: inputs: - '%kernel.root_dir%/../web/bundles/bazingajstranslation/js/translator.min.js' - '%kernel.root_dir%/../web/js/translations/config.js' - '%kernel.root_dir%/../web/js/translations/*/*.js'
compile: php app/console bazinga:js-translation:dump php app/console assetic:dump
{% javascripts '@bazinga_js_translation_js' %} <script src="{{ asset_url }}"></script>{% endjavascripts %}
https://github.com/boxuk/angular-symfony-translation
angular-symfony-translation
bower install --save angular-symfony-translation
#app/config/assetic/js.yml
bazinga_js_angular_js: inputs: - '%kernel.root_dir%/../bower_components/angular-symfony-translation/ dist/angular-symfony-translation.js'
var app = angular.module('my_module', [ 'boxuk.translation']);
{% javascripts '@bazinga_js_translation_js' '@bazinga_js_angular_js' %} <script src="{{ asset_url }}"></script>{% endjavascripts %}
[[ ('errand.status.in_progress') | trans ]]
#src/Espeo/CommonBundle/Resources/translations/messages.pl.yml
errand: status: in_progress: W trakcie closed: Zamknięte canceled: Odwołany new: Nowy
ESPEO SOFTWARE
Mariusz Kozł[email protected]