Symfony Indonesia
Saturday, March 7, 2015
Symfony 2 hari 25: Form pendaftaran affiliate
Artikel ini dirunut berdasarkan Jobeet Tutorial, yang dibuat oleh Fabien Potencier, untuk Symfony 1.4.
Form pendaftaran untuk affiliate
Setelah service API-nya kita buat maka selanjutnya adalah kita membuat form untuk pendaftaran affiliate. Ok langsung saja kita buta terlebih dahulu AffiliateController.php.src/Ibw/JobeetBundle/Controller/AffiliateController.php
namespace Ibw\JobeetBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Ibw\JobeetBundle\Entity\Affiliate;
use Ibw\JobeetBundle\Form\AffiliateType;
use Symfony\Component\HttpFoundation\Request;
use Ibw\JobeetBundle\Entity\Category;
class AffiliateController extends Controller
{
// Your code goes here
}
===============================================
Dan sesuaikan link Affiliate yang ada di layout:
src/Ibw/JobeetBundle/Resources/views/layout.html.twig
<!-- ... -->
<li class="last"><a href="{{ path('ibw_affiliate_new') }}">Become an affiliate</a></li>
<!-- ... -->
===============================================
Sekarang tambahkan method untuk melakukan proses pendaftaran di AffiliateController.php
src/Ibw/JobeetBundle/Controller/AffiliateController.php
namespace Ibw\JobeetBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Ibw\JobeetBundle\Entity\Affiliate;
use Ibw\JobeetBundle\Form\AffiliateType;
use Symfony\Component\HttpFoundation\Request;
use Ibw\JobeetBundle\Entity\Category;
class AffiliateController extends Controller
{
public function newAction()
{
$entity = new Affiliate();
$form = $this->createForm(new AffiliateType(), $entity);
return $this->render('IbwJobeetBundle:Affiliate:affiliate_new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
}
==============================================
Selanjutnya kita daftarkan routenya ke configurasi bundle kita:
src/Ibw/JobeetBundle/Resources/config/routing/affiliate.yml
ibw_affiliate_new:
pattern: /new
defaults: { _controller: "IbwJobeetBundle:Affiliate:new" }
===============================================
Dan tambahkan juga routing di configuras app kita:
src/Ibw/JobeetBundle/Resources/config/routing.yml
# ...
IbwJobeetBundle_ibw_affiliate:
resource: "@IbwJobeetBundle/Resources/config/routing/affiliate.yml"
prefix: /affiliate
================================================
Berikutnya buat form viewnya, buatlah file AffiliateType.php dan tambahkan kode berikut:
src/Ibw/JobeetBundle/Form/AffiliateType.php
namespace Ibw\JobeetBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Ibw\JobeetBundle\Entity\Affiliate;
use Ibw\JobeetBundle\Entity\Category;
class AffiliateType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('url')
->add('email')
->add('categories', null, array('expanded'=>true))
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Ibw\JobeetBundle\Entity\Affiliate',
));
}
public function getName()
{
return 'affiliate';
}
}
==================================================
Tambahkan juga validasi formnya:
src/Ibw/JobeetBundle/Resources/config/validation.yml
# ...
Ibw\JobeetBundle\Entity\Affiliate:
constraints:
- Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity: email
properties:
url:
- Url: ~
email:
- NotBlank: ~
- Email: ~
=================================================
Dan akhirnya buat template formnya:
src/Ibw/JobeetBundle/Resources/views/Affiliate/affiliate_new.html.twig
{% extends 'IbwJobeetBundle::layout.html.twig' %}
{% set form_themes = _self %}
{% block form_errors %}
{% spaceless %}
{% if errors|length > 0 %}
<ul class="error_list">
{% for error in errors %}
<li>{{ error.messageTemplate|trans(error.messageParameters, 'validators') }}</li>
{% endfor %}
</ul>
{% endif %}
{% endspaceless %}
{% endblock form_errors %}
{% block stylesheets %}
{{ parent() }}
<link rel="stylesheet" href="{{ asset('bundles/ibwjobeet/css/job.css') }}" type="text/css" media="all" />
{% endblock %}
{% block content %}
<h1>Become an affiliate</h1>
<form action="{{ path('ibw_affiliate_create') }}" method="post" {{ form_enctype(form) }}>
<table id="job_form">
<tfoot>
<tr>
<td colspan="2">
<input type="submit" value="Submit" />
</td>
</tr>
</tfoot>
<tbody>
<tr>
<th>{{ form_label(form.url) }}</th>
<td>
{{ form_errors(form.url) }}
{{ form_widget(form.url) }}
</td>
</tr>
<tr>
<th>{{ form_label(form.email) }}</th>
<td>
{{ form_errors(form.email) }}
{{ form_widget(form.email) }}
</td>
</tr>
<tr>
<th>{{ form_label(form.categories) }}</th>
<td>
{{ form_errors(form.categories) }}
{{ form_widget(form.categories) }}
</td>
</tr>
</tbody>
</table>
{{ form_end(form) }}
{% endblock %}
=================================================
Ketika user mensubmit formnya maka kita akan menyimpan datanya sebagai affiliate, untuk itu kita tambahkan method createAction.php dan ketikan kode berikut:
src/Ibw/JobeetBundle/Controller/AffiliateController.php
class AffiliateController extends Controller
{
// ...
public function createAction(Request $request)
{
$affiliate = new Affiliate();
$form = $this->createForm(new AffiliateType(), $affiliate);
$form->bind($request);
$em = $this->getDoctrine()->getManager();
if ($form->isValid()) {
$formData = $request->get('affiliate');
$affiliate->setUrl($formData['url']);
$affiliate->setEmail($formData['email']);
$affiliate->setIsActive(false);
$em->persist($affiliate);
$em->flush();
return $this->redirect($this->generateUrl('ibw_affiliate_wait'));
}
return $this->render('IbwJobeetBundle:Affiliate:affiliate_new.html.twig', array(
'entity' => $affiliate,
'form' => $form->createView(),
));
}
}
================================================
Untuk membuat method createAction bekerja kita harus menambahkannya ke routing bundle kita:
src/Ibw/JobeetBundle/Resources/config/routing/affiliate.yml
# ...
ibw_affiliate_create:
pattern: /create
defaults: { _controller: "IbwJobeetBundle:Affiliate:create" }
requirements: { _method: post }
=================================================
Setelah data pendaftar affiliate tersimpan selanjutnya kita buatkan halaman untuk landing yang menampilkan tulisan terima kasih dan meminta kepada user untuk melakukan kofirmasi email.
src/Ibw/JobeetBundle/Controller/AffiliateController.php
class AffiliateController extends Controller
{
// ...
public function waitAction()
{
return $this->render('IbwJobeetBundle:Affiliate:wait.html.twig');
}
}
==================================================
Dan juga templatenya:
src/Ibw/JobeetBundle/Resources/views/Affiliate/wait.html.twig
{% extends "IbwJobeetBundle::layout.html.twig" %}
{% block content %}
<div class="content">
<h1>Your affiliate account has been created</h1>
<div style="padding: 20px">
Thank you!
You will receive an email with your affiliate token
as soon as your account will be activated.
</div>
</div>
{% endblock %}
==================================================
Berikut juga routingnya :
src/Ibw/JobeetBundle/Resources/config/routing/affiliate.yml
# ...
ibw_affiliate_wait:
pattern: /wait
defaults: { _controller: "IbwJobeetBundle:Affiliate:wait" }
Symfony 2 hari 24: Membuat API web service dengan Symfony 2
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 %}
================================================
Friday, March 6, 2015
Symfony 2 hari 23: Membuat feed RSS di Symfony 2
Artikel ini dirunut berdasarkan Jobeet Tutorial, yang dibuat oleh Fabien Potencier, untuk Symfony 1.4.
Feed RSS dengan Symfony 2
Akan sangat membantu pengguna jika kita menyediakan fitur RSS feed yang dapat memberikan informasi yang update kepada pengunjung. Ok, langkah pertamanya buatlah template terlebih dahulu. Dan untuk feed tersebut kita akan menggunakan template XML. Buat file index.atom.twigsrc/Ibw/JobeetBundle/Resources/views/Job/index.atom.twig
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Jobeet</title>
<subtitle>Latest Jobs</subtitle>
<link href="" rel="self"/>
<link href=""/>
<updated></updated>
<author><name>Jobeet</name></author>
<id>Unique Id</id>
<entry>
<title>Job title</title>
<link href="" />
<id>Unique id</id>
<updated></updated>
<summary>Job description</summary>
<author><name>Company</name></author>
</entry>
</feed>
=======================================
Tambahkan link RSS feed di footer web kita
src/Ibw/JobeetBundle/Resources/views/layout.html.twig
<!-- ... -->
<li class="feed"><a href="{{ path('ibw_job', {'_format': 'atom'}) }}">Full feed</a></li>
<!-- ... -->
=========================================
Tambahkan tag <link> di bagian head yang akan membantu browser untuk mendeteksi keberadaan RSS di web kita.
src/Ibw/JobeetBundle/Resources/views/layout.html.twig
<!-- ... -->
<link rel="alternate" type="application/atom+xml" title="Latest Jobs" href="{{ url('ibw_job', {'_format': 'atom'}) }}" />
<!-- ... -->
============================================
Ubah method index di JobController agar bisa menyesuaikan dengan template yang diminta oleh url.
src/Ibw/JobeetBundle/Controller/JobController.php
// ...
$format = $this->getRequest()->getRequestFormat();
return $this->render('IbwJobeetBundle:Job:index.'.$format.'.twig', array(
'categories' => $categories
));
// ...
============================================
Ubah template header di atom dengan kode berikut:
src/Ibw/JobeetBundle/Resources/views/Job/index.atom.twig
<!-- ... -->
<title>Jobeet</title>
<subtitle>Latest Jobs</subtitle>
<link href="{{ url('ibw_job', {'_format': 'atom'}) }}" rel="self"/>
<link href="{{ url('ibw_jobeet_homepage') }}"/>
<updated>{{ lastUpdated }}</updated>
<author><name>Jobeet</name></author>
<id>{{ feedId }}</id>
<!-- ... -->
===========================================
Kita harus mengirimkin id job yang paling terbaru, untuk itu ubah method indexAction menjadi berikut ini:
src/Ibw/JobeetBundle/Controller/JobController.php
// ...
$latestJob = $em->getRepository('IbwJobeetBundle:Job')->getLatestPost();
if($latestJob) {
$lastUpdated = $latestJob->getCreatedAt()->format(DATE_ATOM);
} else {
$lastUpdated = new \DateTime();
$lastUpdated = $lastUpdated->format(DATE_ATOM);
}
$format = $this->getRequest()->getRequestFormat();
return $this->render('IbwJobeetBundle:Job:index.'.$format.'.twig', array(
'categories' => $categories,
'lastUpdated' => $lastUpdated,
'feedId' => sha1($this->get('router')->generate('ibw_job', array('_format'=> 'atom'), true)),
));
// ...
===========================================
Untuk mendapatkan postingan terakhir dari job kita perlu menambahkan method getLatestPost di JobRepository.php
src/Ibw/JobeetBundle/Repository/JobRepository.php
// ...
public function getLatestPost($category_id = null)
{
$query = $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')
->setMaxResults(1);
if($category_id) {
$query->andWhere('j.category = :category_id')
->setParameter('category_id', $category_id);
}
try{
$job = $query->getQuery()->getSingleResult();
} catch(\Doctrine\Orm\NoResultException $e){
$job = null;
}
return $job;
}
// ...
=====================================
Untuk menggenerate data feednya gunakan kode berikut:
src/Ibw/JobeetBundle/Resources/views/Job/index.atom.twig
{% for category in categories %}
{% for entity in category.activejobs %}
<entry>
<title>{{ entity.position }} ({{ entity.location }})</title>
<link href="{{ url('ibw_job_show', { 'id': entity.id, 'company': entity.companyslug, 'location': entity.locationslug, 'position': entity.positionslug }) }}" />
<id>{{ entity.id }}</id>
<updated>{{ entity.createdAt.format(constant('DATE_ATOM')) }}</updated>
<summary type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
{% if entity.logo %}
<div>
<a href="{{ entity.url }}">
<img src="http://{{ app.request.host }}/uploads/jobs/{{ entity.logo }}" alt="{{ entity.company }} logo" />
</a>
</div>
{% endif %}
<div>
{{ entity.description|nl2br }}
</div>
<h4>How to apply?</h4>
<p>{{ entity.howtoapply }}</p>
</div>
</summary>
<author><name>{{ entity.company }}</name></author>
</entry>
{% endfor %}
{% endfor %}
=====================================
Thursday, March 5, 2015
Symfony 2 hari 22: Aksi logout di Symfony 2
Artikel ini dirunut berdasarkan Jobeet Tutorial, yang dibuat oleh Fabien Potencier, untuk Symfony 1.4.
Logout Symfony 2
Ketika user sudah selesai melakukan aktivitasnya maka ia harus logout agar akunnya tidak disalah gunakan. Untuk melakukan proses logout tersebut edit file config/security.yml dan tambahkan kode berikut:app/config/security.yml
security:
firewalls:
# ...
secured_area:
# ...
logout:
path: /logout
target: /
# ...
======================================
Selanjutnya kita harus menambahkan url /logout di routing aplikasi kita. Untuk itu edit file routing dan tambahkan kode berikut:
src/Ibw/JobeetBundle/Resources/config/routing.yml
# ...
logout:
pattern: /logout
# ...
============================================
Agar user dapat mengakses url /logout mari kita tambahkan link logout di halaman admin, untuk melakukan hal ini kita harus melakukan override Sonata admin bundle dengan menambahkan file user_block.html.twig di dalam folder app/Resources/SonataAdminBundle/views/Core.
app/Resources/SonataAdminBundle/views/Core/user_block.html.twig
{% block user_block %}<a href="{{ path('logout') }}">Logout</a>{% endblock%}
===============================================
Sekarang jika kamu mengakses halaman admin maka kamu akan menemukan link logout di bagian atas halaman.
User session Symfony 2
Symfony 2 mempunyai object yang dapat digunakan untuk menyimpan sesi user ketika mereka sudah login ke dalam aplikasi. Kamu dapat menyimpan session dengan mudah di mana di dalam controller mu dengan menggunakan kode berikut.Cotroller mu di Symfony 2
$session = $this->getRequest()->getSession();
// store an attribute for reuse during a later user request
$session->set('foo', 'bar');
// in another controller for another request
$foo = $session->get('foo');
=================================
Ok kita bisa menggunakan fitur ini untuk membuat histori kunjungan user, untuk melakukan hal tersebut tambahkan kode berikut ini di JobController.php
src/Ibw/JobeetBundle/Controller/JobController.php
// ...
public function showAction($id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('IbwJobeetBundle:Job')->getActiveJob($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Job entity.');
}
$session = $this->getRequest()->getSession();
// fetch jobs already stored in the job history
$jobs = $session->get('job_history', array());
// store the job as an array so we can put it in the session and avoid entity serialize errors
$job = array('id' => $entity->getId(), 'position' =>$entity->getPosition(), 'company' => $entity->getCompany(), 'companyslug' => $entity->getCompanySlug(), 'locationslug' => $entity->getLocationSlug(), 'positionslug' => $entity->getPositionSlug());
if (!in_array($job, $jobs)) {
// add the current job at the beginning of the array
array_unshift($jobs, $job);
// store the new job history back into the session
$session->set('job_history', array_slice($jobs, 0, 3));
}
$deleteForm = $this->createDeleteForm($id);
return $this->render('IbwJobeetBundle:Job:show.html.twig', array(
'entity' => $entity,
'delete_form' => $deleteForm->createView(),
));
}
===============================================
src/Ibw/JobeetBundle/Resources/views/layout.html.twig
<!-- ... -->
<div id="job_history">
Recent viewed jobs:
<ul>
{% for job in app.session.get('job_history') %}
<li>
<a href="{{
path('ibw_job_show', { 'id': job.id, 'company': job.companyslug,
'location': job.locationslug, 'position': job.positionslug }) }}">{{ job.position }} - {{ job.company }}</a>
</li>
{% endfor %}
</ul>
</div>
<div id="content">
<!-- ... -->
Flash message Symfony 2
Flash message merupakan pesan kecil yang memberikan informasi singkat yang dapat membantu pengguna untuk mengtahui proses jalannya aplikasi yang terjadi. Kita akan membuat flash message untuk proses publish, untuk itu tambahkan kode berikut di JobController.phpsrc/Ibw/JobeetBundle/Controller/JobController.php
// ...
public function publishAction($token)
{
// ...
$this->get('session')->getFlashBag()->add('notice', 'Your job is now online for 30 days.');
// ...
}
=============================================
Kemudian tambahkan kode berikut di file template untuk menampilkan pesannya.
src/Ibw/JobeetBundle/Resources/views/layout.html.twig
<!-- ... -->
{% for flashMessage in app.session.flashbag.get('notice') %}
<div>
{{ flassMessage }}
</div>
{% endfor %}
<!-- ... -->
Symfony 2 hari 21: Membuat command line
Artikel ini dirunut berdasarkan Jobeet Tutorial, yang dibuat oleh Fabien Potencier, untuk Symfony 1.4.
Membuat Symfony 2 command
Kita dapat membuat Symfony 2 command untuk dijalankan melalui terminal. Buat file bernama JobeetUsersCommand.php di dalam folder command, lalu tambahkan code berikut.src/Ibw/JobeetBundle/Command/JobeetUsersCommand.php
namespace Ibw\JobeetBundle\Command;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Ibw\JobeetBundle\Entity\User;
class JobeetUsersCommand extends ContainerAwareCommand
{
protected function configure()
{
$this
->setName('ibw:jobeet:users')
->setDescription('Add Jobeet users')
->addArgument('username', InputArgument::REQUIRED, 'The username')
->addArgument('password', InputArgument::REQUIRED, 'The password')
;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$username = $input->getArgument('username');
$password = $input->getArgument('password');
$em = $this->getContainer()->get('doctrine')->getManager();
$user = new User();
$user->setUsername($username);
// encode the password
$factory = $this->getContainer()->get('security.encoder_factory');
$encoder = $factory->getEncoder($user);
$encodedPassword = $encoder->encodePassword($password, $user->getSalt());
$user->setPassword($encodedPassword);
$em->persist($user);
$em->flush();
$output->writeln(sprintf('Added %s user with password %s', $username, $password));
}
}
=========================================
Command tersebut jika dijalankan akan menjalankan perintah untuk menambahkan user baru ke dalam database User. Jalankan perintah berikut untuk menambahkan data user ke dalam database
php app/console ibw:jobeet:users admin admin
Maka ketika kamu membuka tabel User kamu akan menemukan satu user baru yang baru saja kamu masukan.
Symfony 2 hari 20: Hak akses user
Artikel ini dirunut berdasarkan Jobeet Tutorial, yang dibuat oleh Fabien Potencier, untuk Symfony 1.4.
Hak akses pengguna
Pada saat authentifikasi bisanya user akan memasukan username dan password, kemudian jika user berhasil masuk maka sistem akan memberikan hak akses berdasarkan status hak akses yang dimiliki oleh user. Di Symfony 2 kita bisa melakukan pengaturan hak akses melalui data dari database atau melalui konfigurasi file. Nah untuk kali ini kita akan menggunakan setting authentifikasi melalui konfigurasi di file. Pertama seting spesifikasi user di file config/security.ymlapp/config/security.yml
# ...
providers:
in_memory:
memory:
users:
admin: { password: adminpass, roles: 'ROLE_ADMIN' }
# ...
====================================
Tetapi kamu juga dapat meletakan data user di dalam tabel user. Untuk itu mari kita buat table user terlebih dahulu:
src/Ibw/JobeetBundle/Resources/config/doctrine/User.orm.yml
Ibw\JobeetBundle\Entity\User:
type: entity
table: user
id:
id:
type: integer
generator: { strategy: AUTO }
fields:
username:
type: string
length: 255
password:
type: string
length: 255
===========================================
Kemudian jalankan perintah berikut untuk menggenerate tablenya.
php app/console doctrine:generate:entities IbwJobeetBundle
Lakukan update schema di aplikasi kita dengan menjalankan perintah berikut:
php app/console doctrine:schema:update --force
Selanjutnya kita perlu menambahkan user interface untuk melakukan authentifikasi di aplikasi kita, buka model User lalu tambahkan kode berikut:
src/Ibw/JobeetBundle/Entity/User.php
namespace Ibw\JobeetBundle\Entity;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\ORM\Mapping as ORM;
/**
* User
*/
class User implements UserInterface
{
/**
* @var integer
*/
private $id;
/**
* @var string
*/
private $username;
/**
* @var string
*/
private $password;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set username
*
* @param string $username
* @return User
*/
public function setUsername($username)
{
$this->username = $username;
}
/**
* Get username
*
* @return string
*/
public function getUsername()
{
return $this->username;
}
/**
* Set password
*
* @param string $password
* @return User
*/
public function setPassword($password)
{
$this->password = $password;
}
/**
* Get password
*
* @return string
*/
public function getPassword()
{
return $this->password;
}
public function getRoles()
{
return array('ROLE_ADMIN');
}
public function getSalt()
{
return null;
}
public function eraseCredentials()
{
}
public function equals(User $user)
{
return $user->getUsername() == $this->getUsername();
}
}
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\ORM\Mapping as ORM;
/**
* User
*/
class User implements UserInterface
{
/**
* @var integer
*/
private $id;
/**
* @var string
*/
private $username;
/**
* @var string
*/
private $password;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set username
*
* @param string $username
* @return User
*/
public function setUsername($username)
{
$this->username = $username;
}
/**
* Get username
*
* @return string
*/
public function getUsername()
{
return $this->username;
}
/**
* Set password
*
* @param string $password
* @return User
*/
public function setPassword($password)
{
$this->password = $password;
}
/**
* Get password
*
* @return string
*/
public function getPassword()
{
return $this->password;
}
public function getRoles()
{
return array('ROLE_ADMIN');
}
public function getSalt()
{
return null;
}
public function eraseCredentials()
{
}
public function equals(User $user)
{
return $user->getUsername() == $this->getUsername();
}
}
====================================
Kemudian set User provider ke model User tersebut:
app/config/security.yml
...
providers:
main:
entity: { class: Ibw\JobeetBundle\Entity\User, property: username }
encoders:
Ibw\JobeetBundle\Entity\User: sha512
providers:
main:
entity: { class: Ibw\JobeetBundle\Entity\User, property: username }
encoders:
Ibw\JobeetBundle\Entity\User: sha512
=============================
Kita juga mengeset pengkodean user dengan menggunakan algoritma Sha512 untuk mengecrypt password kita.
Subscribe to:
Comments (Atom)
