PHPackages                             kdrmklabs/ticket-bundle - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. kdrmklabs/ticket-bundle

ActiveSymfony-bundle[Utility &amp; Helpers](/categories/utility)

kdrmklabs/ticket-bundle
=======================

This bundle provides a customer support system by integrating a ticketing functionality for Symfony2 applications.

v0.9.2(10y ago)1501[1 issues](https://github.com/KdrMkLabs/TicketBundle/issues)MITPHPPHP &gt;=5.3.2

Since May 21Pushed 9y ago1 watchersCompare

[ Source](https://github.com/KdrMkLabs/TicketBundle)[ Packagist](https://packagist.org/packages/kdrmklabs/ticket-bundle)[ Docs](https://github.com/KdrMkLabs/TicketBundle)[ RSS](/packages/kdrmklabs-ticket-bundle/feed)WikiDiscussions master Synced 4w ago

READMEChangelog (3)Dependencies (2)Versions (4)Used By (0)

Getting started with KdrmklabsTicketBundle in Symfony2.
=======================================================

[](#getting-started-with-kdrmklabsticketbundle-in-symfony2)

This bundle allows you to integrate in your Symfony2 project a basic system of customer support by tickets. You can create, edit and respond tickets instantly after installing this bundle .

Needs a minimum configuration and the whole procedure is very simple.

Installation.
-------------

[](#installation)

### I. Installing the bundle in two different ways.

[](#i-installing-the-bundle-in-two-different-ways)

#### a) Automatically.

[](#a-automatically)

You can install the last version of this bundle with composer running the command from your command line:

```
$ composer require kdrmklabs/ticket-bundle

```

#### b) By composer.json .

[](#b-by-composerjson-)

Or you can install this bundle by adding next code line to your project in the composer.json file and after update it with the command `composer update`

file: /composer.json

```
{
    "require": {
        "kdrmklabs/ticket-bundle": "dev-master",
    }
}
```

Now, update the bundle with composer:

```
$ composer update kdrmklabs/ticket-bundle

```

### II. Enable and register the Bundle in the AppKernel

[](#ii-enable-and-register-the-bundle-in-the-appkernel)

```
// file: app/AppKernel.php

public function registerBundles()
{
    $bundles = array(
        // ...
        new Kdrmklabs\Bundle\TicketBundle\KdrmklabsTicketBundle(),
        // ...
        // Your application bundles
    );
}
```

### III. Install Gedmon Doctrine2 extensions

[](#iii-install-gedmon-doctrine2-extensions)

#### Requirements:

[](#requirements)

- [Gedmo Doctrine2 extensions](https://github.com/Atlantic18/DoctrineExtensions/blob/master/doc/symfony2.md)

Check if gedmo doctrine extensions are downloaded.

`/vendor/gedmo/doctrine-extensions/lib/Gedmo`

if not download it:

a. Add dependency to composer.json

*file: /composer.json*

```
{
    "require": {
        ....
        "gedmo/doctrine-extensions": "dev-master"
    }
}
```

b. Update with composer in the command line:

```
$ php composer.phar update gedmo/doctrine-extensions

```

#### Configure Gedmo:

[](#configure-gedmo)

III.I. Create a DoctrineExtensionListener

```
// file: src/AppBundle/Listener/DoctrineExtensionListener.php

namespace AppBundle\Listener;

use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

class DoctrineExtensionListener implements ContainerAwareInterface
{
    /**
     * @var ContainerInterface
     */
    protected $container;

    public function setContainer(ContainerInterface $container = null)
    {
        $this->container = $container;
    }

    public function onLateKernelRequest(GetResponseEvent $event)
    {
        $translatable = $this->container->get('gedmo.listener.translatable');
        $translatable->setTranslatableLocale($event->getRequest()->getLocale());
    }

    public function onKernelRequest(GetResponseEvent $event)
    {
        $securityContext = $this->container->get('security.context', ContainerInterface::NULL_ON_INVALID_REFERENCE);
        if (null !== $securityContext && null !== $securityContext->getToken() && $securityContext->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
            $loggable = $this->container->get('gedmo.listener.loggable');
            $loggable->setUsername($securityContext->getToken()->getUsername());
        }
    }
}
```

III.II. Create file `doctrine_extensions.yml` and locate it in your `app/config` directory

```
# file: app/config/doctrine_extensions.yml

doctrine:
    orm:
        auto_generate_proxy_classes: %kernel.debug%
        auto_mapping: true
# only these lines are added additionally
        mappings:
            translatable:
                type: annotation
                alias: Gedmo
                prefix: Gedmo\Translatable\Entity
                # make sure vendor library location is correct
                dir: "%kernel.root_dir%/../vendor/gedmo/doctrine-extensions/lib/Gedmo/Translatable/Entity"
    # services to handle doctrine extensions
    # import it in config.yml
services:
    # KernelRequest listener
    extension.listener:
        # change this to your DoctrineExtensionListener namespace
        class: AppBundle\Listener\DoctrineExtensionListener
        calls:
            - [ setContainer, [ @service_container ] ]
        tags:
            # translatable sets locale after router processing
            - { name: kernel.event_listener, event: kernel.request, method: onLateKernelRequest, priority: -10 }
            # loggable hooks user username if one is in security context
            - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }

    # Doctrine Extension listeners to handle behaviors
    gedmo.listener.tree:
        class: Gedmo\Tree\TreeListener
        tags:
            - { name: doctrine.event_subscriber, connection: default }
        calls:
            - [ setAnnotationReader, [ @annotation_reader ] ]

    gedmo.listener.translatable:
        class: Gedmo\Translatable\TranslatableListener
        tags:
            - { name: doctrine.event_subscriber, connection: default }
        calls:
            - [ setAnnotationReader, [ @annotation_reader ] ]
            - [ setDefaultLocale, [ %locale% ] ]
            - [ setTranslatableLocale, [ %locale% ]]
            - [ setTranslationFallback, [ false ] ]

    gedmo.listener.timestampable:
        class: Gedmo\Timestampable\TimestampableListener
        tags:
            - { name: doctrine.event_subscriber, connection: default }
        calls:
            - [ setAnnotationReader, [ @annotation_reader ] ]

    gedmo.listener.sluggable:
        class: Gedmo\Sluggable\SluggableListener
        tags:
            - { name: doctrine.event_subscriber, connection: default }
        calls:
            - [ setAnnotationReader, [ @annotation_reader ] ]

    gedmo.listener.sortable:
        class: Gedmo\Sortable\SortableListener
        tags:
            - { name: doctrine.event_subscriber, connection: default }
        calls:
            - [ setAnnotationReader, [ @annotation_reader ] ]

    gedmo.listener.loggable:
        class: Gedmo\Loggable\LoggableListener
        tags:
            - { name: doctrine.event_subscriber, connection: default }
        calls:
            - [ setAnnotationReader, [ @annotation_reader ] ]
```

> Don't forget change 'AppBundle\\Listener\\DoctrineExtensionListener' to your DoctrineExtensionListener namespace.

Finally, Do not forget to import **doctrine\_extensions.yml** in your **app/config/config.yml** :

```
# file: app/config/config.yml
imports:
    - { resource: parameters.yml }
    - { resource: security.yml }
    - { resource: doctrine_extensions.yml }
```

More details of Gedmo Doctrine2 extensions in Symfony2:

### IV. (optional) If you want paginate results with KNPPaginatorBundle you can install and configure it.

[](#iv-optional-if-you-want-paginate-results-with-knppaginatorbundle-you-can-install-and-configure-it)

More details:

### V. Configure the bundle.

[](#v-configure-the-bundle)

V.I. Add `kdrmklabs_ticket` configuration to you config.yml

```
# file: app/config/config.yml

kdrmklabs_ticket:
    user_class: AppBundle\Entity\User
    user_primay_key: id
```

Where `user_primay_key` is the name of your primary key in the user table.

V.II. Add `resolve_target_entities` to your doctrine configuration

```
# file: app/config/config.yml

# Doctrine Configuration
doctrine:
    orm:
        auto_mapping: true
        resolve_target_entities:
            Kdrmklabs\Bundle\TicketBundle\Model\UserInterface: AppBundle\Entity\User
```

> Do not forget change 'AppBundle\\Entity\\User' to your User Entity namespace

More details about resolve\_target\_entities: [http://symfony.com/doc/current/cookbook/doctrine/resolve\_target\_entity.html](http://symfony.com/doc/current/cookbook/doctrine/resolve_target_entity.html)

V.III. Implements `Kdrmklabs\Bundle\TicketBundle\Model\UserInterface` from your User entity.

```
// file:

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * User
 *
 * @ORM\Table(name="user")
 * @ORM\Entity
 */
class User implements \Kdrmklabs\Bundle\TicketBundle\Model\UserInterface
{
    public function getId(){

    }
}
```

### VII. Finally, create database tables and update the schema

[](#vii-finally-create-database-tables-and-update-the-schema)

Update your database schema with the command:

```
$ php app/console doctrine:schema:update --force

```

> Now, you need to populete the database tables `kdrmklabs_ticket_status` and `kdrmklabs_ticket_category`

Example of SQL to populete the tables:

```
INSERT INTO `kdrmklabs_ticket_category` (`id`, `name`, `active`) VALUES ('1', 'Billing', '1');
INSERT INTO `kdrmklabs_ticket_category` (`id`, `name`, `active`) VALUES ('2', 'Cancellations and refunds', '1');
INSERT INTO `kdrmklabs_ticket_category` (`id`, `name`, `active`) VALUES ('3', 'Report a scam or offer false', '1');
INSERT INTO `kdrmklabs_ticket_category` (`id`, `name`, `active`) VALUES ('4', 'Report inappropriate or illegal content', '1');
INSERT INTO `kdrmklabs_ticket_category` (`id`, `name`, `active`) VALUES ('5', 'Security Center and user protection', '1');

INSERT INTO `kdrmklabs_ticket_status` (`id`, `name`, `active`) VALUES ('1', 'Pending', '1');
INSERT INTO `kdrmklabs_ticket_status` (`id`, `name`, `active`) VALUES ('2', 'Invalid', '1');
INSERT INTO `kdrmklabs_ticket_status` (`id`, `name`, `active`) VALUES ('3', 'Solved', '1');
```

Statuses
--------

[](#statuses)

You can add to the database table `kdrmklabs_ticket_status` all states that you want to use to identify the tickets, for example:

[![image](https://cloud.githubusercontent.com/assets/5240279/15417885/18df2e22-1e20-11e6-9d22-55f182e3cc27.png)](https://cloud.githubusercontent.com/assets/5240279/15417885/18df2e22-1e20-11e6-9d22-55f182e3cc27.png)

Categories
----------

[](#categories)

You can add to the database table `kdrmklabs_ticket_category` all categories that you want to use to classify the tickets, for example:

[![image](https://cloud.githubusercontent.com/assets/5240279/15417940/c288fe08-1e20-11e6-973b-070883d98421.png)](https://cloud.githubusercontent.com/assets/5240279/15417940/c288fe08-1e20-11e6-973b-070883d98421.png)

Available services
------------------

[](#available-services)

**Examples of implementation of kdrmklabs\_ticket.ticket\_service from a controller**

### Create a ticket

[](#create-a-ticket)

```
/**
* @Route("/create")
*/
public function createAction() {
   $kdrmklabs_ticket_service = $this->get('kdrmklabs_ticket.ticket_service');
   $ticket = $kdrmklabs_ticket_service->createTicket("message", "subject", 1, 1, 1);

   return $this->redirectToRoute('kdrmklabs_ticket_show', array('id' => $ticket->getId()));
}
```

**createTicket** -&gt; Return a `Kdrmklabs\Bundle\TicketBundle\Entity\Ticket` object

Description

```
createTicket(
    string $initial_message,
    string $subject,
    int|Kdrmklabs\Bundle\TicketBundle\Model\UserInterface|AppBundle\Entity\User $user,
    int|Kdrmklabs\Bundle\TicketBundle\Entity\TicketCategory $category,
    int|Kdrmklabs\Bundle\TicketBundle\Entity\TicketStatus $status
    [, int $dateAdded])
```

### Delete

[](#delete)

```
/**
* @Route("/delete/{id}")
*/
public function deleteAction($id) {
   $kdrmklabs_ticket_service = $this->get('kdrmklabs_ticket.ticket_service');
   $kdrmklabs_ticket_service->deleteTicket($id);

   return $this->redirectToRoute('kdrmklabs_ticket_index');
}
```

**deleteTicket** -&gt; Return boolean

Description:

```
deleteTicket( int|Kdrmklabs\Bundle\TicketBundle\Entity\Ticket $ticket)
```

### Reply

[](#reply)

```
/**
* @Route("/reply/{id}")
*/
public function replyAction($id) {
   $kdrmklabs_ticket_service = $this->get('kdrmklabs_ticket.ticket_service');
   $ticket = $kdrmklabs_ticket_service->replyTicket($id, 1, "reply");

   return $this->redirectToRoute('kdrmklabs_ticket_show', array('id' => $ticket->getId()));
}
```

**replyTicket** -&gt; Return a `Kdrmklabs\Bundle\TicketBundle\Entity\Ticket` object

Description:

```
replyTicket(
    int|Kdrmklabs\Bundle\TicketBundle\Entity\Ticket $ticket,
    int|Kdrmklabs\Bundle\TicketBundle\Model\UserInterface|AppBundle\Entity\User $user,
    string $message
    [, int $dateAdded])
```

### get a ticket

[](#get-a-ticket)

```
/**
* @Route("/show/{id}", name="kdrmklabs_ticket_show")
* @Template()
*/
public function showAction($id) {
   $kdrmklabs_ticket_service = $this->get('kdrmklabs_ticket.ticket_service');
   $ticket = $kdrmklabs_ticket_service->getTicket($id);

   return array('ticket' => $ticket);
}
```

**getTicket** -&gt; Return a `Kdrmklabs\Bundle\TicketBundle\Entity\Ticket` object

Description:

```
getTicket( int|string $id_ticket )
```

### list tickets

[](#list-tickets)

```
/**
* @Route("/", name="kdrmklabs_ticket_index")
* @Template()
*/
public function indexAction(Request $request) {
   $kdrmklabs_ticket_service = $this->get('kdrmklabs_ticket.ticket_service');
   $query = $kdrmklabs_ticket_service->getTickets(); // get all tickets

   $paginator = $this->get('knp_paginator');
   $pagination = $paginator->paginate(
       $query->getQuery(),
       $request->query->get('page', 1),
       10
   );

   return array('pagination' => $pagination);
}
```

**getTickets** -&gt; return DQL QUERY

Description:

```
getTickets(
        [ int|Kdrmklabs\Bundle\TicketBundle\Model\UserInterface|AppBundle\Entity\User $author,
        int|Kdrmklabs\Bundle\TicketBundle\Entity\TicketCategory $category,
        int|Kdrmklabs\Bundle\TicketBundle\Entity\TicketStatus $status
        int $from_datetime,
        int $to_datetime,
        boolean $closed ]
    )
```

### close ticket

[](#close-ticket)

```
/**
* @Route("/close/{id}")
*/
public function closeAction($id){
   $kdrmklabs_ticket_service = $this->get('kdrmklabs_ticket.ticket_service');
   $kdrmklabs_ticket_service->closeTicket($id);

   return $this->redirectToRoute('kdrmklabs_ticket_index');
}
```

**closeTicket** -&gt; Return boolean

Description:

```
closeTicket( id|string $id_ticket )
```

### User repository from UserInterface

[](#user-repository-from-userinterface)

```
// access to UserInterface from controller
$this->get('kdrmklabs_ticket.user_repository')->find($id_user);
```

### Example complete of Controller implementation

[](#example-complete-of-controller-implementation)

```
namespace Kdrmklabs\Bundle\TicketBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\Request;

class DefaultController extends Controller {

    /**
     * @Route("/", name="kdrmklabs_ticket_index")
     * @Template()
     */
    public function indexAction(Request $request) {
        $kdrmklabs_ticket_service = $this->get('kdrmklabs_ticket.ticket_service');
        $query = $kdrmklabs_ticket_service->getTickets();

        $paginator = $this->get('knp_paginator');
        $pagination = $paginator->paginate(
            $query->getQuery(),
            $request->query->get('page', 1),
            10
        );

        return array('pagination' => $pagination);
    }

    /**
     * @Route("/create")
     */
    public function createAction() {
        $id_user = 1;
        $id_category = 1;
        $id_status = 1;
        $kdrmklabs_ticket_service = $this->get('kdrmklabs_ticket.ticket_service');
        $ticket = $kdrmklabs_ticket_service->createTicket("message", "subject", $id_user, $id_category, $id_status);

        return $this->redirectToRoute('kdrmklabs_ticket_show', array('id' => $ticket->getId()));
    }

    /**
     * @Route("/show/{id}", name="kdrmklabs_ticket_show")
     * @Template()
     */
    public function showAction($id) {
        $kdrmklabs_ticket_service = $this->get('kdrmklabs_ticket.ticket_service');
        $ticket = $kdrmklabs_ticket_service->getTicket($id);

        return array('ticket' => $ticket);
    }

    /**
     * @Route("/reply/{id}")
     */
    public function replyAction($id) {
        $id_user = 1;
        $kdrmklabs_ticket_service = $this->get('kdrmklabs_ticket.ticket_service');
        $ticket = $kdrmklabs_ticket_service->replyTicket($id, $id_user, "reply");

        return $this->redirectToRoute('kdrmklabs_ticket_show', array('id' => $ticket->getId()));
    }

    /**
     * @Route("/delete/{id}")
     */
    public function deleteAction($id) {
        $kdrmklabs_ticket_service = $this->get('kdrmklabs_ticket.ticket_service');
        $kdrmklabs_ticket_service->deleteTicket($id);

        return $this->redirectToRoute('kdrmklabs_ticket_index');
    }

    /**
     * @Route("/close/{id}")
     */
    public function closeAction($id){
        $kdrmklabs_ticket_service = $this->get('kdrmklabs_ticket.ticket_service');
        $kdrmklabs_ticket_service->closeTicket($id);

        return $this->redirectToRoute('kdrmklabs_ticket_index');
    }
}
```

###  Health Score

20

—

LowBetter than 13% of packages

Maintenance0

Infrequent updates — may be unmaintained

Popularity11

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity50

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~15 days

Total

3

Last Release

3661d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/5240279?v=4)[Edgar Morales](/maintainers/ingedgarmorales)[@ingedgarmorales](https://github.com/ingedgarmorales)

---

Top Contributors

[![ingedgarmorales](https://avatars.githubusercontent.com/u/5240279?v=4)](https://github.com/ingedgarmorales "ingedgarmorales (9 commits)")

---

Tags

supporthelp deskhelpdeskticketticketingcustomer-support

### Embed Badge

![Health badge](/badges/kdrmklabs-ticket-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/kdrmklabs-ticket-bundle/health.svg)](https://phpackages.com/packages/kdrmklabs-ticket-bundle)
```

###  Alternatives

[hackzilla/ticket-bundle

This Bundle provides multilingual ticketing functionality for Symfony applications.

6429.3k1](/packages/hackzilla-ticket-bundle)[2lenet/crudit-bundle

The easy like Crud'it Bundle.

1615.6k12](/packages/2lenet-crudit-bundle)[binshops/laravel-ticket

A simple ticketing system for Laravel 5.1 – 5.8 and 6.\* - 7.\* - 8.\* - 9.\* - 10.\* -which integrates smoothly with Laravel default users and auth system

261.0k](/packages/binshops-laravel-ticket)[balping/ticketit-app

Ticketit, the simple helpdesk tickets system pre-installed in Laravel

136.6k](/packages/balping-ticketit-app)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
