fados-produccions/full-calendar-bundle

FullCalendar 在 Symfony2 中的集成

安装: 956

依赖者: 0

建议者: 0

安全性: 0

星标: 1

观察者: 5

分支: 3

开放问题: 1

语言:JavaScript

类型:symfony-bundle

dev-master / 1.0.x-dev 2017-07-12 16:44 UTC

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);
   }