Artikel ini dirunut berdasarkan Jobeet Tutorial, yang dibuat oleh Fabien Potencier, untuk Symfony 1.4.
Web service API dengan Symfony 2
Untuk membantu penyebaran data job yang diposting dari web kita ke web yang ingin menjadi afiliasi maka kita akan membuat fitur API yang mengirimkan data job terupdate agar dapat ditampilkan di website mereka.
Ok sekarang saatnya membuat membuat data fixture untuk memasukan data affiliate. Buat file LoadAffiliateData.php
src/Ibw/JobeetBundle/DataFixtures/ORM/LoadAffiliateData.php
namespace Ibw\JobeetBundle\DataFixtures\ORM;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Ibw\JobeetBundle\Entity\Affiliate;
class LoadAffiliateData extends AbstractFixture implements OrderedFixtureInterface
{
public function load(ObjectManager $em)
{
$affiliate = new Affiliate();
$affiliate->setUrl('http://sensio-labs.com/');
$affiliate->setEmail('address1@example.com');
$affiliate->setToken('sensio-labs');
$affiliate->setIsActive(true);
$affiliate->addCategorie($em->merge($this->getReference('category-programming')));
$em->persist($affiliate);
$affiliate = new Affiliate();
$affiliate->setUrl('/');
$affiliate->setEmail('address2@example.org');
$affiliate->setToken('symfony');
$affiliate->setIsActive(false);
$affiliate->addCategorie($em->merge($this->getReference('category-programming')), $em->merge($this->getReference('category-design')));
$em->persist($affiliate);
$em->flush();
$this->addReference('affiliate', $affiliate);
}
public function getOrder()
{
return 3; // This represents the order in which fixtures will be loaded
}
}
======================================
Kemudian jalankan perintah berikut untuk memasukan data ke dalam tabel:
php app/console doctrine:fixtures:load
Selanjutnya tambahkan method token di model affiliate, tambahkan sintak berikut di file Affiliate.orm.yml
src//Ibw/JobeetBundle/Resources/config/doctrine/Affiliate.orm.yml
# ...
lifecycleCallbacks:
prePersist: [ setCreatedAtValue, setTokenValue ]
lifecycleCallbacks:
prePersist: [ setCreatedAtValue, setTokenValue ]
============================================
Selanjutnya jalankan perintah ini melalui terminal.
php app/console doctrine:generate:entities IbwJobeetBundle
Ok, mari kita tambahkan methodnya:
src/Ibw/JobeetBundle/Entity/Affiliate.php
public function setTokenValue()
src/Ibw/JobeetBundle/Resources/config/routing.yml
{
if(!$this->getToken()) {
$token = sha1($this->getEmail().rand(11111, 99999));
$this->token = $token;
}
return $this;
}
================================================
Reload datanya dengan menjalankan perintah berikut:
php app/console doctrine:fixtures:load
Webservice untuk Job-nya
Ok langkah pertamanya adalah kita tambahkan routingnya terlebih dahulu edit file routingnya:src/Ibw/JobeetBundle/Resources/config/routing.yml
IbwJobeetBundle_api:
pattern: /api/{token}/jobs.{_format}
defaults: {_controller: "IbwJobeetBundle:Api:list"}
requirements:
_format: xml|json|yaml
===============================================
Seperti biasanya setelah kita menambahkan routing baru kita perlu untuk membersihkan cachenya, jalankan perintah berikut untuk melakukannya:
php app/console cache:clear --env=dev
php app/console cache:clear --env=prod
Buat file ApiController.php dan tambahkan kode berikut:
src/Ibw/JobeetBundle/Controller/ApiController.php
namespace Ibw\JobeetBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Ibw\JobeetBundle\Entity\Affiliate;
use Ibw\JobeetBundle\Entity\Job;
use Ibw\JobeetBundle\Repository\AffiliateRepository;
class ApiController extends Controller
{
public function listAction(Request $request, $token)
{
$em = $this->getDoctrine()->getManager();
$jobs = array();
$rep = $em->getRepository('IbwJobeetBundle:Affiliate');
$affiliate = $rep->getForToken($token);
if(!$affiliate) {
throw $this->createNotFoundException('This affiliate account does not exist!');
}
$rep = $em->getRepository('IbwJobeetBundle:Job');
$active_jobs = $rep->getActiveJobs(null, null, null, $affiliate->getId());
foreach ($active_jobs as $job) {
$jobs[$this->get('router')->generate('ibw_job_show', array('company' => $job->getCompanySlug(), 'location' => $job->getLocationSlug(), 'id' => $job->getId(), 'position' => $job->getPositionSlug()), true)] = $job->asArray($request->getHost());
}
$format = $request->getRequestFormat();
$jsonData = json_encode($jobs);
if ($format == "json") {
$headers = array('Content-Type' => 'application/json');
$response = new Response($jsonData, 200, $headers);
return $response;
}
return $this->render('IbwJobeetBundle:Api:jobs.' . $format . '.twig', array('jobs' => $jobs));
}
}
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Ibw\JobeetBundle\Entity\Affiliate;
use Ibw\JobeetBundle\Entity\Job;
use Ibw\JobeetBundle\Repository\AffiliateRepository;
class ApiController extends Controller
{
public function listAction(Request $request, $token)
{
$em = $this->getDoctrine()->getManager();
$jobs = array();
$rep = $em->getRepository('IbwJobeetBundle:Affiliate');
$affiliate = $rep->getForToken($token);
if(!$affiliate) {
throw $this->createNotFoundException('This affiliate account does not exist!');
}
$rep = $em->getRepository('IbwJobeetBundle:Job');
$active_jobs = $rep->getActiveJobs(null, null, null, $affiliate->getId());
foreach ($active_jobs as $job) {
$jobs[$this->get('router')->generate('ibw_job_show', array('company' => $job->getCompanySlug(), 'location' => $job->getLocationSlug(), 'id' => $job->getId(), 'position' => $job->getPositionSlug()), true)] = $job->asArray($request->getHost());
}
$format = $request->getRequestFormat();
$jsonData = json_encode($jobs);
if ($format == "json") {
$headers = array('Content-Type' => 'application/json');
$response = new Response($jsonData, 200, $headers);
return $response;
}
return $this->render('IbwJobeetBundle:Api:jobs.' . $format . '.twig', array('jobs' => $jobs));
}
}
==============================================
Untuk mendapatkan data affiliate berdasarkan tokennya, kita perlu menambahkan method getForToken.
src/Ibw/JobeetBundle/Resources/config/doctrine/Affiliate.orm.yml
Ibw\JobeetBundle\Entity\Affiliate:
type: entity
repositoryClass: Ibw\JobeetBundle\Repository\AffiliateRepository
# ...
type: entity
repositoryClass: Ibw\JobeetBundle\Repository\AffiliateRepository
# ...
Kemudian jalankan perintah berikut ini untuk mengupdate modelnya:
php app/console doctrine:generate:entities IbwJobeetBundle
Selanjutnya tambahkan kode berikut di AffililateRepository.php
src/Ibw/JobeetBundle/Repository/AffiliateRepository.php
namespace Ibw\JobeetBundle\Repository;
use Doctrine\ORM\EntityRepository;
/**
* AffiliateRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class AffiliateRepository extends EntityRepository
{
public function getForToken($token)
{
$qb = $this->createQueryBuilder('a')
->where('a.is_active = :active')
->setParameter('active', 1)
->andWhere('a.token = :token')
->setParameter('token', $token)
->setMaxResults(1)
;
try{
$affiliate = $qb->getQuery()->getSingleResult();
} catch(\Doctrine\Orm\NoResultException $e){
$affiliate = null;
}
return $affiliate;
}
}
use Doctrine\ORM\EntityRepository;
/**
* AffiliateRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class AffiliateRepository extends EntityRepository
{
public function getForToken($token)
{
$qb = $this->createQueryBuilder('a')
->where('a.is_active = :active')
->setParameter('active', 1)
->andWhere('a.token = :token')
->setParameter('token', $token)
->setMaxResults(1)
;
try{
$affiliate = $qb->getQuery()->getSingleResult();
} catch(\Doctrine\Orm\NoResultException $e){
$affiliate = null;
}
return $affiliate;
}
}
============================================
Setelah kita berhasil mengidentifikasi affiliate berdasarkan tokennya selanjutnya kita akan membuat method untuk mengambilkan data untuk affiliate tersebut:
src/Ibw/JobeetBundle/Repository/JobRepository.php
// ...
public function getActiveJobs($category_id = null, $max = null, $offset = null, $affiliate_id = null)
{
$qb = $this->createQueryBuilder('j')
->where('j.expires_at > :date')
->setParameter('date', date('Y-m-d H:i:s', time()))
->andWhere('j.is_activated = :activated')
->setParameter('activated', 1)
->orderBy('j.expires_at', 'DESC');
if($max) {
$qb->setMaxResults($max);
}
if($offset) {
$qb->setFirstResult($offset);
}
if($category_id) {
$qb->andWhere('j.category = :category_id')
->setParameter('category_id', $category_id);
}
// j.category c, c.affiliate a
if($affiliate_id) {
$qb->leftJoin('j.category', 'c')
->leftJoin('c.affiliates', 'a')
->andWhere('a.id = :affiliate_id')
->setParameter('affiliate_id', $affiliate_id)
;
}
$query = $qb->getQuery();
return $query->getResult();
}
// ...
public function getActiveJobs($category_id = null, $max = null, $offset = null, $affiliate_id = null)
{
$qb = $this->createQueryBuilder('j')
->where('j.expires_at > :date')
->setParameter('date', date('Y-m-d H:i:s', time()))
->andWhere('j.is_activated = :activated')
->setParameter('activated', 1)
->orderBy('j.expires_at', 'DESC');
if($max) {
$qb->setMaxResults($max);
}
if($offset) {
$qb->setFirstResult($offset);
}
if($category_id) {
$qb->andWhere('j.category = :category_id')
->setParameter('category_id', $category_id);
}
// j.category c, c.affiliate a
if($affiliate_id) {
$qb->leftJoin('j.category', 'c')
->leftJoin('c.affiliates', 'a')
->andWhere('a.id = :affiliate_id')
->setParameter('affiliate_id', $affiliate_id)
;
}
$query = $qb->getQuery();
return $query->getResult();
}
// ...
Karena data yang dikembalikan dalam bentuk array maka kita akan membuat method asArray() untuk menampung data tersebut:
src/Ibw/JobeetBundle/Entity/Job.php
public function asArray($host)
{
return array(
'category' => $this->getCategory()->getName(),
'type' => $this->getType(),
'company' => $this->getCompany(),
'logo' => $this->getLogo() ? 'http://' . $host . '/uploads/jobs/' . $this->getLogo() : null,
'url' => $this->getUrl(),
'position' => $this->getPosition(),
'location' => $this->getLocation(),
'description' => $this->getDescription(),
'how_to_apply' => $this->getHowToApply(),
'expires_at' => $this->getCreatedAt()->format('Y-m-d H:i:s'),
);
}
{
return array(
'category' => $this->getCategory()->getName(),
'type' => $this->getType(),
'company' => $this->getCompany(),
'logo' => $this->getLogo() ? 'http://' . $host . '/uploads/jobs/' . $this->getLogo() : null,
'url' => $this->getUrl(),
'position' => $this->getPosition(),
'location' => $this->getLocation(),
'description' => $this->getDescription(),
'how_to_apply' => $this->getHowToApply(),
'expires_at' => $this->getCreatedAt()->format('Y-m-d H:i:s'),
);
}
==================================================
src/Ibw/JobeetBundle/Resources/views/Api/jobs.xml.twig
<?xml version="1.0" encoding="utf-8"?>
<jobs>
{% for url, job in jobs %}
<job url="{{ url }}">
{% for key,value in job %}
<{{ key }}>{{ value }}</{{ key }}>
{% endfor %}
</job>
{% endfor %}
</jobs>
==============================================
src/Ibw/JobeetBundle/Resources/views/Api/jobs.json.twig
{% for url, job in jobs %}
{% i = 0, count(jobs), ++i %}
[
"url":"{{ url }}",
{% for key, value in job %} {% j = 0, count(key), ++j %}
"{{ key }}":"{% if j == count(key)%} {{ json_encode(value) }}, {% else %} {{ json_encode(value) }}
{% endif %}"
{% endfor %}]
{% endfor %}
================================================
src/Ibw/JobeetBundle/Resources/views/Api/jobs.yaml.twig
{% for url,job in jobs %}
Url: {{ url }}
{% for key, value in job %}
{{ key }}: {{ value }}
{% endfor %}
{% endfor %}
================================================
Format XML
Buatlah format XML support, dengan membuat format XML seperti berikut ini:src/Ibw/JobeetBundle/Resources/views/Api/jobs.xml.twig
<?xml version="1.0" encoding="utf-8"?>
<jobs>
{% for url, job in jobs %}
<job url="{{ url }}">
{% for key,value in job %}
<{{ key }}>{{ value }}</{{ key }}>
{% endfor %}
</job>
{% endfor %}
</jobs>
==============================================
Format JSON
Buta juga format JSON untuk affiliate API:src/Ibw/JobeetBundle/Resources/views/Api/jobs.json.twig
{% for url, job in jobs %}
{% i = 0, count(jobs), ++i %}
[
"url":"{{ url }}",
{% for key, value in job %} {% j = 0, count(key), ++j %}
"{{ key }}":"{% if j == count(key)%} {{ json_encode(value) }}, {% else %} {{ json_encode(value) }}
{% endif %}"
{% endfor %}]
{% endfor %}
================================================
Format YML
Begitu juga format YML/YAMLsrc/Ibw/JobeetBundle/Resources/views/Api/jobs.yaml.twig
{% for url,job in jobs %}
Url: {{ url }}
{% for key, value in job %}
{{ key }}: {{ value }}
{% endfor %}
{% endfor %}
================================================

No comments:
Post a Comment