-
Add the following to your composer.json
file:, (*2)
// composer.json
{
// ...
require: {
// ...
"cunningsoft/achievement-bundle": "~0.2"
}
}
-
Run composer update cunningsoft/achievement-bundle
to install the new dependencies., (*3)
-
Register the new bundle in your AppKernel.php
:, (*4)
<?php
// in AppKernel::registerBundles()
$bundles = array(
// ...
new Cunningsoft\AchievementBundle\CunningsoftAchievementBundle(),
// ...
);
-
Let your user entity implement the Cunningsoft\AchievementBundle\Entity\UserInterface
:, (*5)
// Acme\ProjectBundle\Entity\User.php
<?php
namespace Acme\ProjectBundle\Entity;
use Cunningsoft\AchievementBundle\Entity\UserInterface as AchievementUserInterface;
use Cunningsoft\AchievementBundle\Entity\Achievement;
class User implements AchievementUserInterface
{
/**
* @var int
*/
protected $id;
/**
* @var Achievement[]
*
* @ORM\OneToMany(targetEntity="Cunningsoft\AchievementBundle\Entity\Achievement", mappedBy="user")
* @ORM\OrderBy({"insertDate" = "DESC"})
*/
protected $achievements;
/**
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* @return Achievement[]
*/
public function getAchievements()
{
return $this->achievements;
}
// ...
-
Map the interface to your user entity in your config.yml
:, (*6)
// app/config/config.yml
// ...
doctrine:
orm:
resolve_target_entities:
Cunningsoft\AchievementBundle\Entity\UserInterface: Acme\ProjectBundle\Entity\User
-
Update your database schema:, (*7)
$ app/console doctrine:schema:update
-
Import routes:, (*8)
// app/config/routing.yml
// ...
cunningsoft_achievement_bundle:
resource: "@CunningsoftAchievementBundle/Controller"
type: annotation
-
Render the achievement list in your template:, (*9)
// src/Acme/ProjectBundle/Resources/views/Default/index.html.twig
// ...
{% render(controller('CunningsoftAchievementBundle:Default:achievements', { 'user': app.user } )) %}
// ...
-
Render the "achievement unlocked" layer at the bottom of your template:, (*10)
// src/Acme/ProjectBundle/Resources/views/Default/index.html.twig
// ...
{% render(controller('CunningsoftAchievementBundle:Default:achievementMessages')) %}
// ...
-
Import js and css files:, (*11)
// app/Resources/views/base.html.twig
// ...
{% block javascripts %}
// ...
{% javascripts '@CunningsoftAchievementBundle/Resources/public/js/*.js' output='js/achievements.js' %}
<script type="text/javascript" src="{{ asset_url }}"></script>
{% endjavascripts %}
// ...
{% endblock %}
// ...
{% block stylesheets %}
// ...
{% stylesheets '@CunningsoftAchievementBundle/Resources/public/css/*.scss' output='css/achievements.css' filter='compass' %}
<link href="{{ asset_url }}" rel="stylesheet" />
{% endstylesheets %}
// ...
{% endblock %}
// ...
-
Create a child bundle which holds all informations about your achievements, (*12)
mkdir src/Acme/AchievementBundle
// src/Acme/AchievementBundle/AcmeAchievementBundle.php
<?php
namespace Acme\AchievementBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class AcmeAchievementBundle extends Bundle
{
public function getParent()
{
return 'CunningsoftAchievementBundle';
}
}
// src/Acme/AchievementBundle/Listener/AchievementListener.php
<?php
namespace Acme\AchievementBundle\Listener;
use Cunningsoft\AchievementBundle\Services\AchievementService;
use Doctrine\ORM\EntityManager;
class AchievementListener
{
/**
* @var AchievementService
*/
private $achievementService;
/**
* @var EntityManager
*/
private $entityManager;
/**
* @param AchievementService $achievementService
* @param EntityManager $entityManager
*/
public function __construct(AchievementService $achievementService, EntityManager $entityManager)
{
$this->achievementService = $achievementService;
$this->entityManager = $entityManager;
}
}
-
Tell twig where to find your assets, (*13)
// app/config/config.yml
// ...
twig:
globals:
achievement_bundle_name: acmeachievement
For every achievement you want to use, go through these steps. This is an example showing how to give an achievement for posting a comment with at least 100 characters., (*14)
-
Add it to your achievement list, (*15)
// app/config/achievements.yml
// ...
community: // this is the category name
comment_100_characters: // this is an unique identifier
name: Verbosity // this is your custom name, shown to the user
event: comment_posted // this is the event that is listened for
class: Acme\AchievementBundle\Listener\AchievementListener // the class you handle all events in
method: onCommentPosted // the method that is triggered when the event is dispatched
-
Create an event class as a container for the informations about the event, (*16)
// src/Acme/ProjectBundle/Event/CommentEvent.php
<?php
namespace Acme\ProjectBundle\Event;
use Acme\ProjectBundle\Entity\Comment;
use Symfony\Component\EventDispatcher\Event;
class CommentEvent extends Event
{
/**
* @var Comment
*/
protected $comment;
public function __construct(Comment $comment)
{
$this->comment = $comment;
}
/**
* @return Comment
*/
public function getComment()
{
return $this->comment;
}
}
-
Create method to check for the achievement, (*17)
// src/Acme/AchievementBundle/Listener/AchievementListener.php
// ...
public function onCommentPosted(CommentEvent $event)
{
if (mb_strlen($event->getComment()->getMessage()) >= 100) {
$this->achievementService->trigger('community', 'comment_100_characters', $event->getComment()->getAuthor());
}
}
// ...
-
Create achievement image, (*18)
// src/Acme/AchievementBundle/Resources/public/images/achievements/community/comment_100_characters.png
-
Add achievement description, (*19)
// src/Acme/AchievementBundle/Resources/translations/achievements.en.yml
description_community_comment_100_characters: Write a comment with at least 100 characters!
-
Create event, (*20)
```php
// src/Acme/MainBundle/Controller/Comment.php
// ...
public function create()
{
// ...
$this->get('event_dispatcher')->dispatch('comment_posted', new CommentEvent($comment));
}
// ..., (*21)
Now every time a comment is created (in your business logic) an event is triggered. Because of your achievements.yml the achievement system knows to listen for that event and trigger the according method in your AchievementListener. Now the method in your listener can check whether or not the requirements for one or more achievements are met and if so it triggers the booking of the achievement. Of course you may also utilize existing events or use the events for other purposes as well., (*22)