emc/table-bundle 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

emc/table-bundle

Composer 安装命令:

composer require emc/table-bundle

包简介

TableBundle makes dealing with tables easier. This bundle manage the most common needs for tables. It works and flexible as Symfony Forms. For more documentations see http://www.table-bundle.com

README 文档

README

Build Status Latest Stable Version Total Downloads Latest Unstable Version License SensioLabsInsight

Documentation & Demo Homepage : http://www.table-bundle.com/

This bundle gives a simple way to generate and manage tables based on Symfony. It's allow also :

  • Flexibility
  • Pagination (automated)
  • Searching (automated)
  • Sorting (automated)
  • Theming
  • Extensions
  • Sub-tables (automated)
  • Rows selection (automated)
  • Export (PDF, XSL, CSV) (automated)

Installation

  1. Download TableBundle
  2. Enable the Bundle
  3. Create/Custom new column type extension
  4. Sub-tables
  5. Examples
  6. Result & Screenshots

Download TableBundle

This can be done in several ways, depending on your preference. The first method is the standard Symfony2 method.

Using Composer

Add TableBundle in your composer.json:

{
    "require": {
        "emc/table-bundle": "*"
    }
}

Now tell composer to download the bundle by running the command:

$ php composer.phar update emc/table-bundle

Using submodules

If you prefer instead to use git submodules, then run the following:

$ git submodule add https://github.com/chafiq/TableBundle.git vendor/emc/table-bundle/EMC/TableBundle/
$ git submodule update --init

Note that using submodules requires manually registering the EMC namespace to your autoloader:

<?php
// app/autoload.php

$loader->registerNamespaces(array(
    // ...
    'EMC' => __DIR__.'/../vendor/bundles',
));

Enable the bundle

Finally,

Enable the bundle in the kernel:

<?php
// app/AppKernel.php

public function registerBundles()
{
    $bundles = array(
        // ...
        new EMC\TableBundle\EMCTableBundle(),
    );
}

Enable the routing config :

# app/config/routing.yml
emc_table:
    resource: "@EMCTableBundle/Resources/config/routing.yml"
    prefix:   /

Dependances

Create/Custom new column type extension

PHP : Column type class

<?php
namespace Acme\MyBundle\Table\Column;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class CustomType extends ColumnType {
    public function buildView(array &$view, ColumnInterface $column, array $data, array $options) {
        parent::buildView($view, $column, $data, $options);
        /* Add you column data view here. You can access to them in the twig extension widget */
    }
    public function setDefaultOptions(OptionsResolverInterface $resolver) {
        parent::setDefaultOptions($resolver);
        /* define you parameters here */
    }
    public function getName() {
        return 'custom';
    }
}

Twig : Column type template

{# Acme/MyBundle/Resources/views/Table/Column/custom.html.twig #}
{% block custom_widget %}
    {# here you can edit the content of TD element (Cell). #}
{% endblock %}

Config : Column type service

# Acme/MyBundle/Resources/config/services.yml
services:
    ...
    my_custom_column_type:
        class: Acme\MyBundle\Table\Column\CustomType
        tags:
            -  { name: column.type, alias: custom }

Sub-tables

Controller Code

        /* Controller */
        ...
        $table = $factory->create(new MyTableType(), null, array(
                        ...
                        'caption' => 'My sub table example',
                        'subtable'  => new MySubTableType(),
                        'subtable_params'   => array('cityId' => 'c.id'),
                        'subtable_options'  => array( /* can take the same options as the root table */ )
                        ...
      );

Table Type Code

<?php

namespace Acme\MyBundle\Table\Type;

use EMC\TableBundle\Table\Type\TableType;
use EMC\TableBundle\Table\TableBuilderInterface;
use Doctrine\Common\Persistence\ObjectManager;

class MySubTableType extends TableType {
    
    public function buildTable(TableBuilderInterface $builder, array $options) {
        $builder->add('store', 'text', array(
            'params' => array('ci.name'),
            'title' => 'Center of interest',
            'allow_filter' => true,
            'allow_sort' => true
        ));

        $builder->add('address', 'text', array(
            'params' => array('ci.address', 'ci.zipcode', 'c.name'),
            'format' => '%s %s %s',
            'title' => 'Address',
            'allow_filter' => true,
            'allow_sort' => true
        ));
        
        $builder->add('delete', 'button', array(
            'icon' => 'remove',
            'attrs' => class('attrs' => 'btn-xs')
        ));

        $builder->add('add', 'button', array(
            'icon' => 'plus',
            'attrs' => class('attrs' => 'btn-xs')
        ));
    }

    public function getName() {
        return 'my-sub-table';
    }

    public function getQueryBuilder(ObjectManager $entityManager, array $params) {
        return $entityManager
                    ->getRepository('AcmeMyBundle:CenterInterest')
                        ->createQueryBuilder('ci')
                        ->innerJoin('ci.city', 'c')
                        ->where('c.id = :cityId')
                        ->setParameter('cityId', $params['cityId']); /* this parameter was defined in the subtable_options. $params is poputated in the TableType::buildSubtableParams and are passed to this method */
    }
}

    

Examples

Consider that we have two data base tables :

  • city : #id, name, createdAt, stateid
  • state : #id, name

Controller Code

        use Symfony\Component\HttpFoundation\Request;
        use Acme\MyBundle\Table\Type\MyTableType

        public function indexAction(Request $request) {
            
            /* @var $factory \EMC\TableBundle\Table\TableFactory */
            $factory = $this->get('table.factory');
          
            $table = $factory   ->create(
                                    new MyTableType(),
                                    null,
                                    array('caption' => 'My table example')
                                )
                                ->getTable();
          
          return $this->render('AcmeMyBundle:Table:index.html.twig', array('table' => $table));
        }

Template Code

...
    {% stylesheets 'bundles/emctable/css/style.css' filter='cssrewrite' %}
        <link rel="stylesheet" href="{{ asset_url }}" />
    {% endstylesheets %}

    {% javascripts 'bundles/emctable/js/EMCTable.js' %}
        <script type="text/javascript" src="{{ asset_url }}"></script>
    {% endjavascripts %}

    <div class="container">{{ table(table) }}</div>
...

Table Type Code

<?php

namespace Acme\MyBundle\Table\Type;

use EMC\TableBundle\Table\Type\TableType;
use EMC\TableBundle\Table\TableBuilderInterface;
use Doctrine\Common\Persistence\ObjectManager;

class MyTableType extends TableType {
    
    public function buildTable(TableBuilderInterface $builder, array $options) {
        $builder->add('id', 'anchor', array(
            'route' => 'edit_route',
            'params' => array('id' => 'c.id'),
            'format' => '#%s',
            'title' => '#',
            'allow_sort' => true
        ));

        $builder->add('state', 'text', array(
            'params' => array('s.name'),
            'format' => '%s',
            'title' => 'State',
            'allow_filter' => true,
            'allow_sort' => true
        ));

        $builder->add('city', 'text', array(
            'params' => array('c.name', 'c.id'),
            'format' => '%s (#%d)',
            'title' => 'City',
            'allow_filter' => true,
            'allow_sort' => true
        ));

        $builder->add('createdAt', 'datetime', array(
            'params' => array('t.createdAt'),
            'title' => 'Date',
            'allow_sort' => true
        ));

        $builder->add('delete', 'button', array(
            'icon' => 'remove',
            'text' => 'Delete',
            'attrs' => class('attrs' => 'btn-xs')
        ));

        $builder->add('add', 'button', array(
            'icon' => 'plus',
            'attrs' => class('attrs' => 'btn-xs')
        ));

        $builder->add('status', 'icon', array(
            'params' => array('c.id'),
            'format' => function($id) { return $id % 2 ? 'star' : 'star-o'; }
        ));

        $builder->add('pdf', 'image', array(
            'asset_url' => 'bundles/acmesandbox/images/pdf.jpg'
        ));
    }

    public function getName() {
        return 'my-table';
    }

    public function getQueryBuilder(ObjectManager $entityManager, array $options) {
        return $entityManager
                    ->getRepository('AcmeMyBundle:City')
                        ->createQueryBuilder('c')
                        ->innerJoin('t.state', 's');
    }
}

    

Result & Screenshots

Table

Table

WebProfiler toolbar

WebProfiler toolbar

WebProfiler content

WebProfiler content

emc/table-bundle 适用场景与选型建议

emc/table-bundle 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 2.07k 次下载、GitHub Stars 达 6, 最近一次更新时间为 2015 年 09 月 15 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「grid」 「data grid」 「Data Grid bundle」 「table」 「table bundle」 「grid bundle」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 emc/table-bundle 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 emc/table-bundle 我们能提供哪些服务?
定制开发 / 二次开发

基于 emc/table-bundle 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 2.07k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 6
  • 点击次数: 13
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 6
  • Watchers: 3
  • Forks: 3
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2015-09-15