fados-produccions / full-calendar-bundle
FullCalendar 在 Symfony2 中的集成
Requires
- doctrine/collections: >=1.0
- friendsofsymfony/jsrouting-bundle: ~1.1
- symfony/framework-bundle: ~2.1|~3.0
- symfony/twig-bundle: ~2.1|~3.0
This package is not auto-updated.
Last update: 2024-09-14 19:25:33 UTC
README
我们希望为 Symfony 2 开发一个可分发的包,允许我们在 fullCalendar.js(《http://fullcalendar.io/》)库、日历和调度器中显示事件。
如何使用它
安装
php composer.phar require fados-produccions/full-calendar-bundle dev-master
在 appKernel.php 中注册包
new fadosProduccions\fullCalendarBundle\fullCalendarBundle(),
此包依赖于 FOSJsRouting 包以公开日历 AJAX 事件加载路由。请确保在继续之前已安装并配置了 FOSJsRouting 包。
用法
配置 config.yml
full_calendar:
class_manager: AppBundle\Entity\CompanyEvents
在 config.yml 中,您需要按以下方式添加映射
orm:
auto_generate_proxy_classes: "%kernel.debug%"
entity_managers:
default:
mappings:
fullCalendarBundle: ~
或者
orm:
auto_generate_proxy_classes: "%kernel.debug%"
naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: true
取决于您的配置文件 config.yml
类参数包含存储事件的实体,此实体必须继承自 BaseEvent。创建一个实体
namespace AppBundle\Entity; use Doctrine\ORM\Mapping as ORM; use fadosProduccions\fullCalendarBundle\Entity\Event as BaseEvent; /** * @ORM\Entity * @ORM\Table(name="companyEvents") */ class CompanyEvents extends BaseEvent { /** * @var int * * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ protected $id; }
在命令行中执行,这将创建日历的实体
php app/console doctrine:schema:update --force
在 app/config/routing.yml
中注册路由
# app/config/routing.yml fados_fullcalendar: resource: "@fullCalendarBundle/Resources/config/routing.xml"
发布资产
$ php app/console assets:install web
将所需的样式表和 JavaScript 添加到您的布局中
样式表
<link rel="stylesheet" href="{{ asset('bundles/fullcalendar/css/fullcalendar.min.css') }}" />
<link rel="stylesheet" href="{{ asset('bundles/fullcalendar/css/fullcalendar.print.css') }}" media="print" />
JavaScript
<script type="text/javascript" src="{{ asset('js/jquery-1.8.1.min.js') }}"></script>
<script type="text/javascript" src="{{ asset('bundles/fullcalendar/js/moment.min.js') }}"></script>
<script type="text/javascript" src="{{ asset('bundles/fullcalendar/js/fullcalendar.min.js') }}"></script>
<script type="text/javascript" src="{{ asset('bundles/fullcalendar/js/init.fullCalendar.js') }}"></script>
然后,在您希望显示日历的模板中,添加以下 twig
{{ fullCalendar() }}
页面示例
{% extends 'base.html.twig' %}
{% block javascripts %}
<script type="text/javascript" src="{{ asset('js/jquery-1.8.1.min.js') }}"></script>
<script src="{{ asset('bundles/fosjsrouting/js/router.js') }}"></script>
<script src="{{ path('fos_js_routing_js', {'callback': 'fos.Router.setData'}) }}"></script>
<script type="text/javascript" src="{{ asset('bundles/fullcalendar/js/moment.min.js') }}"></script>
<script type="text/javascript" src="{{ asset('bundles/fullcalendar/js/fullcalendar.min.js') }}"></script>
<script type="text/javascript" src="{{ asset('bundles/fullcalendar/js/init.fullCalendar.js') }}"></script>
{% endblock %}
{% block body %}
<div id="wrapper">
<div id="container">
<div id="welcome">
<h1><span>Welcome to</span> Symfony {{ constant('Symfony\\Component\\HttpKernel\\Kernel::VERSION') }}</h1>
</div>
</div>
</div>
{{ fullCalendar() }}
{% endblock %}
{% block stylesheets %}
<link rel="stylesheet" href="{{ asset('bundles/fullcalendar/css/fullcalendar.min.css') }}" />
<link rel="stylesheet" href="{{ asset('bundles/fullcalendar/css/fullcalendar.print.css') }}" media="print" />
{% endblock %}
日历 JavaScript
在 bundles/fullcalendar/js/ 目录下的 init.fullCalendar.js 文件包含两个路由,当日历加载时触发的 fullcalendar_loadevents 路由,当调整事件日期时触发的 fullcalendar_resizedate 路由,当事件移动时触发的 fullcalendar_changedate 路由。
events: { url:Routing.generate('fullcalendar_loadevents', { month: moment().format('MM'), year: moment().format('YYYY') }), color: 'blue', textColor:'white', error: function() { alert('Error receving events'); } }, eventDrop: function(event,delta,revertFunc) { var newData = event.start.format('YYYY-MM-DD'); //var end = (event.end == null) ? start : event.end.format('YYYY-MM-DD'); $.ajax({ url: Routing.generate('fullcalendar_changedate'), data: { id: event.id, newDate: newData }, type: 'POST', dataType: 'json', success: function(response){ console.log('ok'); }, error: function(e){ revertFunc(); alert('Error processing your request: '+e.responseText); } }); }, eventResize: function(event, delta, revertFunc) { var newData = event.end.format('YYYY-MM-DD'); $.ajax({ url: Routing.generate('fullcalendar_resizedate'), data: { id: event.id, newDate: newData }, type: 'POST', dataType: 'json', success: function(response){ console.log('ok'); }, error: function(e){ revertFunc(); alert('Error processing your request: '+e.responseText); } }); }, eventClick: function(calEvent, jsEvent, view) { console.log('Event: ' + calEvent.title); console.log('Event: ' + calEvent.id); },
eventClick 是您单击事件时触发的事件。
您可以根据需要覆盖此 init.calendar.js 文件。
如何从头创建一个 FullCalendar 可分发包
创建包
首先,我们必须创建一个 Symfony2 项目,在我们的案例中我们使用 2.7 版本。
php composer.phar create-project symfony/framework-standard-edition bundleFullCalendar "2.7.*
安装完成后,我们必须在 vendor 文件夹中创建一个文件夹,我们将在此文件夹中构建我们的 fullcalendar 包。我们将在路径 vendor/fadosProduccions/fullcalendarbundle/ 中创建它。
创建后,我们将创建一个符合 coockbook best practices 的 Symfony2 文件夹结构。
在 DependencyInjection 文件夹中,我们创建了两个文件,fullCalendarExtension.php 包含所有需要加载的配置文件。
<?php namespace fadosProduccions\fullCalendarBundle\DependencyInjection; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; use Symfony\Component\HttpKernel\DependencyInjection\Extension; use Symfony\Component\Config\FileLocator; class fullCalendarExtension extends Extension { //Carreguem els serveis public function load(array $configs, ContainerBuilder $container) { $loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); $loader->load('services.yml'); } }
和 Configuration.php 文件
class Configuration implements ConfigurationInterface { public function getConfigTreeBuilder() { $treeBuilder = new TreeBuilder(); $rootNode = $treeBuilder->root('fullCalendar'); $rootNode-> children() ->scalarNode('class_manager') ->isRequired() ->cannotBeEmpty() ->end() ->end() ; return $treeBuilder; } }
在此文件中,我们配置了 fullcalendarbundle 将需要的参数,在这种情况下,我们将配置 class_manager,此参数是必须的,因为它是将在日历中显示的实体,此实体必须是 baseEvent 的扩展。此 configure.php 代表在 config.yml 中的配置 Configure your config.yml
full_calendar:
class: appBundle/Entity/CompanyEvents
最后,我们必须创建用于加载包的 fullcalendarbundle.php
<?php namespace fadosProduccions\fullCalendarBundle; use Symfony\Component\HttpKernel\Bundle\Bundle; class fullcalendarbundle extends Bundle { }
Composer.json
composer.json 文件应包括以下元数据
{
"name": "fados-produccions/full-calendar-bundle",
"version":"1.0.0",
"type": "symfony-bundle",
"description": "FullCalendar integration in Symfony2",
"keywords": ["fullCalendar"],
"homepage": "https://github.com/fados-produccions/fullCalendarbundle",
"license": "MIT",
"authors": [
{
"name": "Albert Juhé",
"email": "ajuhe@fadosProduccions.com",
"homepage": "https://github.com/fados-produccions/fullCalendarbundle"
}
],
"minimum-stability": "dev",
"require": {
"symfony/twig-bundle": "~2.1|~3.0",
"symfony/framework-bundle": "~2.1|~3.0",
"friendsofsymfony/jsrouting-bundle": "~1.1",
"doctrine/collections": ">=1.0"
},
"autoload": {
"psr-0": { "fadosProduccions\\fullCalendarBundle\\": "" }
},
"target-dir":"fadosProduccions/fullCalendarBundle",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
}
}
服务
现在我们必须创建一对服务,fados.calendar.service 管理实体,app.fados.twig_extension 允许我们在 twig 中使用扩展组件 {{ fullCalendar() }}
services:
fados.calendar.service:
class: fadosProduccions\fullCalendarBundle\Services\CalendarManagerRegistry
arguments: ["@doctrine","@service_container"]
app.fados.twig_extension:
class: fadosProduccions\fullCalendarBundle\Twig\fullCalendarExtension
public: false
tags:
- { name: twig.extension }
Twig 扩展
现在我们必须创建之前定义的 twig 扩展以在 twig 中使用它 {{ fullCalendar }} 创建文件夹 Twig,在此文件夹中我们将创建扩展
<?php namespace fadosProduccions\fullCalendarBundle\Twig; class fullCalendarExtension extends \Twig_Extension { public function getName() { return 'fullCalendar'; } public function getFunctions() { return array( 'fullCalendar' => new \Twig_SimpleFunction( 'fullCalendar', array($this, 'fullCalendar'), array('is_safe' => array('html')) ), ); } public function fullCalendar() { return "<div id='calendar-place'></div>"; } }
之后,您可以在services.yml中注册它并使用它。如果您想尝试它,不进行常规的bundle install,您必须首先使用以下命令注册bundle:
'fadosProduccions\\fullcalendarbundle\\' => array($vendorDir . '/fadosProduccions/fullcalendarbundle'),
在文件vendor\composer\autoload_psr4.php中
模型和实体
他必须创建一个amin实体
<?php namespace fadosProduccions\fullCalendarBundle\Entity; use fadosProduccions\fullCalendarBundle\Model\CalendarEvents as baseCalendarEvent; abstract class Event extends baseCalendarEvent { /** * Convert calendar event details to an array * * @return array $event */ }
它继承自CalendarEvents,这个模型包含事件的基属性。
namespace fadosProduccions\fullCalendarBundle\Model; class CalendarEvents { /** * @var string Title/label of the calendar event. */ protected $title; /** * @var string URL Relative to current path. */ protected $url; /** * @var string HTML color code for the bg color of the event label. */ protected $bgColor; /** * @var string HTML color code for the foregorund color of the event label. */ protected $fgColor; /** * @var string css class for the event label */ protected $cssClass; /** * @var \DateTime DateTime object of the event start date/time. */ protected $startDatetime; /** * @var \DateTime DateTime object of the event end date/time. */ protected $endDatetime; /** * @var boolean Is this an all day event? */ protected $allDay = false; public function __construct() { } public function setTitle($title) { $this->title = $title; } public function getTitle() { return $this->title; } public function setUrl($url) { $this->url = $url; } public function getUrl() { return $this->url; } public function setBgColor($color) { $this->bgColor = $color; } public function getBgColor() { return $this->bgColor; } public function setFgColor($color) { $this->fgColor = $color; } public function getFgColor() { return $this->fgColor; } public function setCssClass($class) { $this->cssClass = $class; } public function getCssClass() { return $this->cssClass; } public function setStartDatetime(\DateTime $start) { $this->startDatetime = $start; } public function getStartDatetime() { return $this->startDatetime; } public function setEndDatetime(\DateTime $end) { $this->endDatetime = $end; } public function getEndDatetime() { return $this->endDatetime; } public function setAllDay($allDay = false) { $this->allDay = (boolean) $allDay; } public function getAllDay() { return $this->allDay; } public function toArray() { return array( 'id' => $this->id, 'title' => $this->title, 'start' => $this->startDatetime->format("Y-m-d\TH:i:sP"), 'end' => $this->endDatetime->format("Y-m-d\TH:i:sP"), 'url' => $this->url, 'backgroundColor' => $this->bgColor, 'borderColor' => $this->bgColor, 'textColor' => $this->fgColor, 'className' => $this->cssClass, 'allDay' => $this->allDay ); } }
最后,我们必须将其映射到orm,下一个文件包含CalendarEvent的数据库映射。这个文件位于fadosProduccions\fullCalendarBundle\Resources\Config\doctrine\Event.orm.xml
<?xml version="1.0" encoding="UTF-8"?> <doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> <mapped-superclass name="fadosProduccions\fullCalendarBundle\Entity\Event"> <field name="title" column="title" type="string" length="255" nullable="true"/> <field name="url" column="url" type="string" length="255" nullable="true"/> <field name="bgColor" column="bgColor" type="string" length="10" nullable="true"/> <field name="cssClass" column="cssClass" type="string" length="10" nullable="true"/> <field name="startDatetime" column="startDatetime" type="datetime" nullable="false"/> <field name="endDatetime" column="endDatetime" type="datetime" nullable="false"/> <field name="allDay" column="allDay" type="boolean"/> </mapped-superclass> </doctrine-mapping>
这允许我们创建一个扩展自baseEvent的实体,字段映射到数据库,这种映射非常重要,将实体与数据库映射绑定。
在执行此操作之前
php app/console doctrine:schema:update --force
检查您的config.yml中是否设置了auto_mapping: true
orm:
auto_generate_proxy_classes: "%kernel.debug%"
naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: true
实体在数据库中创建,字段已映射。
路由
路由文件存储了init.fullCalendar.js调用的路由。
- Routing.generate('fullcalendar_resizedate')
- Routing.generate('fullcalendar_changedate')
- Routing.generate('fullcalendar_loadevents', { month: moment().format('MM'), year: moment().format('YYYY') })
<?xml version="1.0" encoding="UTF-8" ?> <routes xmlns="https://symfony.com.cn/schema/routing" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://symfony.com.cn/schema/routing https://symfony.com.cn/schema/routing/routing-1.0.xsd"> <route id="fullcalendar_loadevents" pattern="/fullCalendar/load"> <default key="_controller">fullcalendarbundle:Calendar:load</default> <option key="expose">true</option> </route> <route id="fullcalendar_changedate" pattern="/fullCalendar/change"> <default key="_controller">fullcalendarbundle:Calendar:change</default> <option key="expose">true</option> </route> <route id="fullcalendar_resizedate" pattern="/fullCalendar/resize"> <default key="_controller">fullcalendarbundle:Calendar:resize</default> <option key="expose">true</option> </route> </routes>
此routing.xml必须从config.yml中调用才能使用:在app/config/routing.yml
中注册路由
# app/config/routing.yml fados_fullcalendar: resource: "@fullcalendarbundle/Resources/config/routing.xml"
此文件中调用的路由使用CalendarController,这是我们定义每个路由的动作的地方。
控制器
主控制器是fadosProduccions\fullCalendarBundle\Controller\CalendarController
此控制器使用fados.calendar.service服务来管理实体。
services:
fados.calendar.service:
class: fadosProduccions\fullCalendarBundle\Services\CalendarManagerRegistry
arguments: ["@doctrine","@service_container"]
CalendarManagerRegistry接收两个参数
- doctrine: ManagerRegistry (当您不知道哪个entitymanager需要数据库实体时使用)
- service_container: Container (用于获取参数,在这种情况下是class_manager)
class CalendarManagerRegistry { protected $managerRegistry; protected $container; protected $recipient; protected $manager; public function __construct(ManagerRegistry $managerRegistry, Container $container) { $this->container = $container; $this->recipient = $this->container->getParameter( 'class_manager' ); $this->managerRegistry = $managerRegistry; $this->manager = $this->managerRegistry->getManagerForClass($this->recipient); }
Manager包含用于class_manager的entity manager,它从config.yml参数中获取。稍后我们将使用manager属性在数据库中查找或保存实体,例如
public function changeDate($newStartData,$newEndData,$id) { $entity = $this->manager->getRepository($this->recipient)->find($id); $entity->setStartDatetime(new \DateTime($newStartData)); $entity->setEndDatetime(new \DateTime($newEndData)); $this->save($entity); }