2016-06-24 7 views
0

Я создаю календарь в sonata admin. Я делаю это как услугу блока. Так что я написал CalendarBlockService.phpАргумент 1, переданный :: __ construct() должен быть экземпляром DateTimeInterface

<?php 
 

 
namespace CD\CarsBundle\Block\Service; 
 

 
use Sonata\BlockBundle\Block\BlockContextInterface; 
 
use Sonata\AdminBundle\Form\FormMapper; 
 
use Sonata\AdminBundle\Validator\ErrorElement; 
 
use Sonata\AdminBundle\Admin\Pool; 
 
use Sonata\BlockBundle\Model\BlockInterface; 
 
use Sonata\BlockBundle\Block\BaseBlockService; 
 
use Symfony\Component\HttpFoundation\Response; 
 
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface; 
 
use Symfony\Component\OptionsResolver\OptionsResolverInterface; 
 
use Symfony\Component\Security\Core\SecurityContext; 
 
use Doctrine\ORM\EntityManager; // mis car je vais devoir récupérer les immatriculations disponibles par jour => donc requête bdd dans repository => utilisation de l'entitymanager 
 

 

 

 

 
class CalendrierBlockService extends BaseBlockService 
 
{ 
 
\t // mettre le code des méthodes nécessaires pour le calendrier (block service) avec les données à retrouver dedans 
 

 
\t /** 
 
\t * @var Symfony\Component\Security\Core\SecurityContext 
 
\t */ 
 
\t protected $securityContext; 
 

 
\t /** 
 
\t * @var EntityManager 
 
\t */ 
 
\t protected $em; 
 

 
\t /** 
 
\t * @var \CD\CarsBundle\Service\Calendrier\Calendrier 
 
\t */ 
 
\t private $calendrier; 
 

 
\t /** 
 
\t * @var \CD\CarsBundle\Service\Calendrier\Jour 
 
\t */ 
 
\t private $jour; 
 

 

 

 

 
\t \t // CalendrierBlockService Constructor 
 

 
\t /** 
 
\t * @param string $name 
 
\t * @param EngineInterface $templating 
 
\t * @param Pool $pool 
 
\t * @param EntityManager $em 
 
\t * @param SecurityContext $securityContext 
 
\t * @param Calendrier $calendrier 
 
\t * @param Jour $jour 
 
\t */ 
 
\t public function __construct(
 
\t \t $name, 
 
\t \t EngineInterface $templating, 
 
\t \t Pool $pool, 
 
\t \t EntityManager $em, 
 
\t \t SecurityContext $securityContext, 
 
\t \t Calendrier $calendrier, 
 
\t \t Jour $jour) 
 
\t { 
 
\t \t parent::__construct($name, $templating); 
 

 
\t \t $this->pool   = $pool; 
 
\t \t $this->em    = $em; 
 
\t \t $this->securityContext = $securityContext; 
 
\t \t $this->calendrier  = $calendrier; 
 
\t \t $this->jour   = $jour; 
 
\t } 
 
\t 
 
\t \t // Name 
 

 
\t /** 
 
    * {@inheritdoc} 
 
    */ 
 
\t public function getName() 
 
\t { 
 
\t \t return 'Disponibilités'; 
 
\t } 
 

 
\t \t // Default settings (valid options for a block of this type) 
 

 
\t /** 
 
    * {@inheritdoc} 
 
    */ 
 
\t public function setDefaultSettings(OptionsResolverInterface $resolver) 
 
\t { 
 
\t \t $resolver->setDefaults(array(
 
\t \t \t 'title' => 'Calendrier des disponibilités', 
 
\t \t \t 'template' => 'CDCarsBundle:Block:calendrier.html.twig', 
 
\t \t)); 
 
\t } 
 

 
\t /** 
 
\t * @return array 
 
\t */ 
 
\t public function getDefaultSettings() 
 
\t { 
 
\t \t return array(); 
 
\t } 
 

 
     // Implement the execute method which must return a response object, which is used to render the block 
 
\t \t // The block context knows the defaults settings, but they can be overwritten in the call to render the block 
 

 
\t /** 
 
\t * {@inheritdoc} 
 
\t */ 
 
\t public function execute(BlockContextInterface $blockContext, Response $response = null) 
 
\t { 
 
\t \t // Pick up the instance of the vehicles repository 
 
\t \t $repovehicules = $this->em->getRepository('CDCarsBundle:Vehicules'); 
 

 
\t \t // Get the available plates numbers (an array) which will be render to a template 
 
\t \t $immatriculations = $repovehicules->getAvailables(); 
 

 
\t \t // Pick up the calendar (!!! be careful about the config and the construct if the calendar is declared as a service) 
 
\t \t $calendar = new CD\CarsBundle\Resources\views\Block(); //>>>>> right or not? 
 

 
\t \t // Setup the variables entered into the method "render Response" (the 3 first are required) 
 
\t \t $variable = array(
 
\t \t \t 'block'   => $blockContext->getBlock(), 
 
\t \t \t 'base_template' => $this->pool->getTemplate('CDCarsBundle:Block:calendrier.html.twig'), 
 
\t \t \t 'seetings'   => $blockContext->getSettings(), 
 
\t \t \t 'immatriculations' => $immatriculations, 
 
\t \t \t 'calendrier'  => $calendar 
 
\t \t \t); 
 

 
\t \t // Now execute the template and send a response 
 
\t \t return $this->renderResponse($blockContext->getTemplate(), $variable, $response); 
 
\t } 
 

 
\t \t // To edit in sonata admin 
 

 
\t /** 
 
    * {@inheritdoc} 
 
    */ 
 
\t public function buildEditForm(FormMapper $formMapper, BlockInterface $block) 
 
\t { 
 
\t } 
 

 
\t \t // To validate in sonata admin 
 

 
\t /** 
 
    * {@inheritdoc} 
 
    */ 
 
\t public function validateBlock(ErrorElement $errorElement, BlockInterface $block) 
 
\t { 
 
\t } 
 

 
\t \t 
 
}

И Calendrier.php (не завершен)

<?php 
 

 
namespace CD\CarsBundle\Service\Calendrier; 
 

 
class Calendrier 
 
{ 
 
\t // With this file, I collect all the informations of each days of each month of the year 
 

 
\t // Pick up the days of a month (array with days which are numbered) 
 

 
\t /** 
 
\t * @param string | interger $month 
 
\t * @return CD\CarsBundle\Service\Calendrier\Jour 
 
\t */ 
 
\t public function getDays($month) 
 
\t { 
 
\t \t return $this->days[$month]; 
 
\t } 
 

 
}

И Jour.php

<?php 
 

 
namespace CD\CarsBundle\Service\Calendrier; 
 

 
class Jour 
 
{ 
 
\t // With this file, I collect all the informations about one day (example: 21-09-2016) 
 

 
\t // Days are defined with constants values (reusable everywhere in the app) 
 

 
\t const WEEK_MONDAY = "1"; 
 
\t const WEEK_TUESDAY = "2"; 
 
\t const WEEK_WEDNESDAY = "3"; 
 
\t const WEEK_THURSDAY = "4"; 
 
\t const WEEK_FRIDAY = "5"; 
 
\t const WEEK_SATURDAY = "6"; 
 
\t const WEEK_SUNDAY = "7"; 
 

 
\t /** 
 
\t * Then the date is build (format year-month-day) with a constructor 
 
\t * @param \DateTimeInterface $day 
 
\t */ 
 
\t public function __construct(\DateTimeInterface $day) 
 
\t { 
 
\t \t $this->year = $day->format('Y'); 
 
\t \t $this->month = $day->format('m'); 
 
\t \t $this->day  = $day->format('Y-m-d'); 
 
\t \t $this->dayWeek = $day->getDayWeek($day); 
 
\t } 
 

 
\t /** 
 
\t * Transform date from DateTime format to String format 
 
\t * 
 
\t * @return string 
 
\t */ 
 
\t public function __toString() 
 
\t { 
 
\t \t return $this->getDateString(); 
 
\t } 
 

 
\t /** 
 
\t * Pick up the date in string 
 
\t * @return string 
 
\t */ 
 
\t public function getDateString() 
 
\t { 
 
\t \t return $this->year .''. $this->month .''. $this->day; 
 
\t } 
 

 
\t /** 
 
\t * Pick up the year 
 
\t * @return string 
 
\t */ 
 
\t public function getYear() 
 
\t { 
 
\t \t return $this->year; 
 
\t } 
 

 
\t /** 
 
\t * Pick up the month 
 
\t * @return string 
 
\t */ 
 
\t public function getMonth() 
 
\t { 
 
\t \t return $this->month; 
 
\t } 
 

 
\t /** 
 
\t * Pick up the day 
 
\t * @return string 
 
\t */ 
 
\t public function getDay() 
 
\t { 
 
\t \t return $this->day; 
 
\t } 
 

 
\t /** 
 
\t * Pick up the day week (number of the day -> example: monday = 1) 
 
\t * @return string 
 
\t */ 
 
\t public function getDayWeek() 
 
\t { 
 
\t \t return $this->dayWeek; 
 
\t } 
 

 
\t /** 
 
\t * Saturdays and Sundays are days off (days without bookings, so no need to have the list of available vehicles for those 2 days) -> DayWithout 
 
\t * @return boolean 
 
\t */ 
 
\t public function getDayWithout() 
 
\t { 
 
\t \t return $this->dayWithout; 
 
\t } 
 

 
\t // Only the current class will have access to the field or method. 
 

 
\t private $day; 
 
\t private $month; 
 
\t private $year; 
 
\t private $dayWeek; 
 
\t private $dayWithout; 
 
}

Я объявил в качестве службы в моей пачке/Ресурсы/конфигурации/services.yml

sonata.block.service.calendrier: 
 
     class: CD\CarsBundle\Block\Service\CalendrierBlockService 
 
     arguments: 
 
      - "sonata.block.service.calendrier" 
 
      - '@templating' 
 
      - '@doctrine.orm.entity_manager' 
 
      - '@security.context' 
 
      - '@cd_cars.calendrier' 
 
      - '@cd_cars.jour' 
 
     tags: 
 
      - { name: sonata.block } 
 

 
    cd_cars.calendrier: 
 
     class: CD\CarsBundle\Service\Calendrier\Calendrier 
 

 
    cd_cars.jour: 
 
     class: CD\CarsBundle\Service\Calendrier\Jour

При обновлении страницы, у меня есть следующее сообщение об ошибке сообщение:

An exception has been thrown during the rendering of a template ("Catchable Fatal Error: Argument 1 passed to CD\CarsBundle\Service\Calendrier\Jour::__construct() must be an instance of DateTimeInterface, none given, called in E:\www\flotte\app\cache\dev\appDevDebugProjectContainer.php on line 815 and defined") in SonataAdminBundle:Core:dashboard.html.twig at line 42.

Итак, я понимаю, что аргумент 1 отсутствует и что он должен быть экземпляром интерфейса DateTime. Однако я не могу найти, как я могу это написать.

Любой, кто поможет мне, пожалуйста.

+0

Hi Coralie, в начале я использовал код на французском языке тоже (комментарии и названия классов). Я могу просто предложить вам код на английском языке, на случай, если ваша программа должна быть отлажена кем-то другим. Представьте, что вы должны отлаживать что-то прокомментированное на польском языке ... Очень сложно (это было мое дело ...) ... [просто комментарий] – pbenard

+0

Я прекрасно понимаю, не волнуйтесь. Для моих личных проектов я код на английском языке. Однако этот проект стажировки должен быть закодирован на французском языке (задан клиентом). Поэтому я должен это уважать. – CoralieS

ответ

0

У вас есть ошибка в вашей архитектуре - услуги должны быть объектами, которые будут инициализированы (построены) только один раз, а затем повторно использованы в каждом другом прецеденте. Таким образом, вы не можете инициализировать свой класс Jour параметром datetime, потому что тогда ваш класс не будет повторно использоваться. Jour, похоже, не является сервисом.

Вы можете

  • набор DateTime для класса Jour каждый раз, когда вы используете его
  • или предоставить DateTime методам Jour при необходимости
  • или (и я рекомендую это решение) не делают ваш Jour класса A сервис и инициализировать его самостоятельно в CalendrierBlockService :: _ construct (или где-либо еще, что вы найдете оптимальным)