Developed with love by KnpLabs Hire us for your project!
59

FPNTagBundle

by FabienPennequin

This bundle allows to tag your Doctrine entities easily

FPNTagBundle

This bundle adds tagging to your Symfony project, with the ability to associate
tags with any number of different entities. This bundle integrates the
DoctrineExtensions-Taggable
library, which handles most of the hard work.

Navigation

  1. Installation
  2. Making an entity taggable
  3. Using Tags

Installation

Use Composer

You can use composer to add the bundle :

``` sh
$ php composer.phar require fpn/tag-bundle
```

Or you can edit your composer.json, and add :

"require": {
    "fpn/tag-bundle":"dev-master",
}

Register the bundle

To start using the bundle, register it in your Kernel. This file is usually
located at app/AppKernel:

public function registerBundles()
{
    $bundles = array(
        // ...
        new FPN\TagBundle\FPNTagBundle(),
    );
)

Create your Tag and Tagging entities

To use this bundle, you'll need to create two new entities: Tag and Tagging.
You place these in any bundle, but each should look like this:

<?php

namespace Acme\TagBundle\Entity;

use FPN\TagBundle\Entity\Tag as BaseTag;

class Tag extends BaseTag
{
}
<?php

namespace Acme\TagBundle\Entity;

use \FPN\TagBundle\Entity\Tagging as BaseTagging;

class Tagging extends BaseTagging
{
}

Next, you'll need to add a little bit of mapping information. One way
to do this is to create the following two XML files and place them in
the Resources/config/doctrine directory of your bundle:

src/Acme/TagBundle/Resources/config/doctrine/Tag.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">

    <entity name="Acme\TagBundle\Entity\Tag" table="acme_tag">

        <id name="id" column="id" type="integer">
            <generator strategy="AUTO" />
        </id>

        <one-to-many field="tagging" target-entity="Acme\TagBundle\Entity\Tagging" mapped-by="tag" fetch="EAGER" />

    </entity>

</doctrine-mapping>

src/Acme/TagBundle/Resources/config/doctrine/Tagging.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">

    <entity name="Acme\TagBundle\Entity\Tagging" table="acme_tagging">

        <id name="id" column="id" type="integer">
            <generator strategy="AUTO" />
        </id>

        <many-to-one field="tag" target-entity="Acme\TagBundle\Entity\Tag">
            <join-columns>
                <join-column name="tag_id" referenced-column-name="id" />
            </join-columns>
        </many-to-one>

        <unique-constraints>
            <unique-constraint columns="tag_id,resource_type,resource_id" name="tagging_idx" />
        </unique-constraints>

    </entity>

</doctrine-mapping>

You can also use Annotations :

src/Acme/TagBundle/Entity/Tag.php:

namespace Acme\TagBundle\Entity;

use \FPN\TagBundle\Entity\Tag as BaseTag;
use Doctrine\ORM\Mapping as ORM;

/**
 * Acme\TagBundle\Entity\Tag
 *
 * @ORM\Table()
 * @ORM\Entity
 */
class Tag extends BaseTag
{
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\OneToMany(targetEntity="Tagging", mappedBy="tag", fetch="EAGER")
     **/
    protected $tagging;
}

src/Acme/TagBundle/Entity/Tagging.php:

namespace Acme\TagBundle\Entity;

use \FPN\TagBundle\Entity\Tagging as BaseTagging;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\UniqueConstraint;

/**
 * Acme\TagBundle\Entity\Tagging
 *
 * @ORM\Table(uniqueConstraints={@UniqueConstraint(name="tagging_idx", columns={"tag_id", "resource_type", "resource_id"})})
 * @ORM\Entity
 */
class Tagging extends BaseTagging
{
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="Tag")
     * @ORM\JoinColumn(name="tag_id", referencedColumnName="id")
     **/
    protected $tag;
}

Define classes on configuration

On your configuration you have to define tag and tagging classes.

Example on yaml:


fpn_tag:
    model:
        tag_class:     Acme\TagBundle\Entity\Tag
        tagging_class: Acme\TagBundle\Entity\Tagging

Making an Entity Taggable

Suppose we have a Post entity, and we want to make it "taggable". The setup
is simple: just add the Taggable interface and add the necessary 3 methods:

<?php

namespace Acme\BlogBundle\Entity;

use DoctrineExtensions\Taggable\Taggable;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="acme_post")
 */
class Post implements Taggable
{
    private $tags;

    public function getTags()
    {
        $this->tags = $this->tags ?: new ArrayCollection();

        return $this->tags;
    }

    public function getTaggableType()
    {
        return 'acme_tag';
    }

    public function getTaggableId()
    {
        return $this->getId();
    }
}

That's it! As you'll see in the next section, the tag manager can now manage
the tags that are associated with your entity.

Using Tags

The bundle works by using a "tag manager", which is responsible for creating
tags and adding them to your entities. For some really good usage instructions,
see Using TagManager.

Basically, the idea is this. Instead of setting tags directly on your entity
(e.g. Post), you'll use the tag manager to set the tags for you. Let's see
how this looks from inside a controller. The tag manager is available as
the fpn_tag.tag_manager service:

use Acme\BlogBundle\Entity\Post;

public function createTagsAction()
{
    // create your entity
    $post = new Post();
    $post->setTitle('foo');

    $tagManager = $this->get('fpn_tag.tag_manager');

    // ask the tag manager to create a Tag object
    $fooTag = $tagManager->loadOrCreateTag('foo');

    // assign the foo tag to the post
    $tagManager->addTag($fooTag, $post);

    $em = $this->getDoctrine()->getEntityManager();

    // persist and flush the new post
    $em->persist($post);
    $em->flush();

    // after flushing the post, tell the tag manager to actually save the tags
    $tagManager->saveTagging($post);

    // ...

    // Load tagging ...
    $tagManager->loadTagging($post);
}
Copyright (C) 2011-2012 by Fabien Pennequin <fabien@pennequin.me>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
fpn_tag:
model: # Required
tag_class: ~ # Required
tagging_class: ~ # Required
service:
slugifier: fpn_tag.slugifier.default
  • Use doctrine taggable extension v0.9.0
    By FabienPennequin, 4 months ago
  • Merge pull request #13 from mweimerskirch/patch-2
    By FabienPennequin, 2 years ago
  • Added toString method
    By mweimerskirch, 2 years ago
  • Merge pull request #12 from mweimerskirch/patch-1
    By FabienPennequin, 2 years ago
  • Fixed typo in readme
    By mweimerskirch, 2 years ago
  • Merge pull request #11 from ternel/master
    By FabienPennequin, 2 years ago
  • Update README.md
    By ternel, 2 years ago
  • Update doc and composer.json : Require symfony/framework-bundle >=2.0
    By ternel, 2 years ago
  • Merge pull request #9 from benjamindulau/composer
    By FabienPennequin, 2 years ago
  • Added composer.json file
    By benjamindulau, 2 years ago
  • Add license (closes #8)
    By FabienPennequin, 2 years ago
  • Merge pull request #6 from tonypiper/patch-1
    By FabienPennequin, 2 years ago
  • Fix typo in configuration.
    By tonypiper, 2 years ago
  • Explain how to get tags
    By stephpy, 2 years ago
  • Add DoctrineExtensions to autoload
    By stephpy, 2 years ago
  • Add part of define entities class on readme
    By stephpy, 2 years ago
  • Merge pull request #1 from weaverryan/readme
    By FabienPennequin, 3 years ago
  • Adding missing annotation import
    By weaverryan, 3 years ago
  • [README] Making a few minor changes per @FabienPennequin
    By weaverryan, 3 years ago
  • [README] Adding a bsic README file for the bundle
    By weaverryan, 3 years ago
  • Fixed typo
    By FabienPennequin, 3 years ago
  • Allowed to customize Tag and Tagging entities
    By FabienPennequin, 3 years ago
  • Added Slugifier service
    By FabienPennequin, 3 years ago
  • Created FPNTagBundle
    By FabienPennequin, 3 years ago
  • Initial commit
    By FabienPennequin, 3 years ago