Monday, October 29, 2012

Using Symfony2 with Backbone.js

Symfony2 with Backbone.js
Inspired by some of the Symfony Live San Francisco talks , I decided to create this bundle and become a better OSS contributor.

This bundle allows you to easily start a backbone.js project with Symfony2, it creates a basic structure for your backbone files and also includes a generator to scaffold your backbone classes.

All the installation steps can be found in the README: https://github.com/gigo6000/DevtimeBackboneBundle

A simple Raffler app created with this bundle can be found here: https://github.com/gigo6000/DevtimeRafflerBundle


Wednesday, November 09, 2011

Symfony2 FOSTwitterBundle TwitterProvider

Symfony2 and Twittter


If you are trying to integrate Symfony2 with Twitter, you're probably trying to install FOSTwitterBundle, and you may have faced two problems, one is that you can't create a user session after you login with Twitter and the other one is that there is no TwitterProvider class available as example in the instructions.

To help you with the second one here is a TwitterProvider class I made based on FacabookProvider.php



To solve the authentication problem on Symfony what I found is that Twitter anywhere only works at client level, so I decided to create a custom login button and built the authorization URL.

Controller action:



Twig template:



Then after the user authenticates with Twitter, the custom TwitterProvider can get the authentication tokens from the session and authenticate the user in Symfony.

Tuesday, June 28, 2011

Capifony: Send an email after deployment


First, thanks to @cordoval at the #symfony channel for suggesting me to use a symfony2 command to do this.

To use this command you must have the SwiftmailerBundle enabled. More info here.

This is a simple Symfony2 command to send an email, you should add it to a "Command" directory inside your bundle and replace the namespace to fit your project bundle:





The email body is just "test" but you can probably modified it you need to.


Test the new command by running the following:

php app/console capifony:sendemail emailfrom@server.com emailto@server.com subject


Finally, this task will run the capifony:sendemail command after the deployment is complete, be sure to add it to your Capifony script:




Want to learn more about Symfony2 console/command-line commands?

http://symfony.com/doc/current/cookbook/console.html


http://www.craftitonline.com/2011/06/calling-commands-within-commands-in-symfony2/

Sunday, June 19, 2011

How to enable the twig truncate filter (Text extension) in Symfony2 beta5


Problem ?


In previous versions of Symfony2, to enable a extension you needed to add the Text and/or Debug extensions to an "extensions" array in your config.yml

//app/config/config.yml
# Twig Configuration
twig:
debug: %kernel.debug%
strict_variables: %kernel.debug%
extensions:
- twig.extension.debug
- twig.extension.text



This was because the extensions were added to the twig.xml file


//vendor/symfony/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml
...
<service id="twig.extension.text" class="Twig_Extensions_Extension_Text" public="false">

<service id="twig.extension.debug" class="Twig_Extensions_Extension_Debug" public="false">
...




But, this is the way to do it now :

// app/config/config.yml
...
services:
twig.extension.text:
class: Twig_Extensions_Extension_Text
tags:
- { name: twig.extension }


I spent some time trying to figure out how to do it, so I hope it helps someone.

Monday, May 23, 2011

Symfony2 + Twig pagination class

I was looking for some pagination class to use with Symfony2, but most of the scripts that I found included html in the class, after some googling I found this post, and it was very helpful to get what I was looking for. I wanted something like the old digg pagination so I modified this class a little bit to get something like this:





The modifications I made:

- Show a range of pages around the current page as in the old digg.
- Parameters can be passed in a route, so you get a nice URL.



This is the class after the modifications:

<?php
/**
* Class to paginate a list of items in a old digg style
*
* @author Darko Gole%u0161
* @author Carlos Mafla <gigo6000@hotmail.com>
* @www.inchoo.net
*/
namespace Paginator;

class Paginator {

//current displayed page
protected $currentpage;
//limit items on one page
protected $limit;
//total number of pages that will be generated
protected $numpages;
//total items loaded from database
protected $itemscount;
//starting item number to be shown on page
protected $offset;
//pages to show at left and right of current page
protected $mid_range;
//range initial page
protected $start_range;
//range end page
protected $end_range;


function __construct($itemscount, $currentpage = 1,$limit = 20,$mid_range = 7) {
//set total items count from controller
$this->itemscount = $itemscount;

$this->currentpage = $currentpage;

$this->limit = $limit;

$this->mid_range= $mid_range;

//Set defaults
$this->setDefaults();

//Calculate number of pages total
$this->getInternalNumPages();
//Calculate first shown item on current page
$this->calculateOffset();


$this->calculateRange();

}


private function calculateRange() {

$this->start_range = $this->currentpage - floor($this->mid_range/2);
$this->end_range = $this->currentpage floor($this->mid_range/2);

if($this->start_range <= 0)
{
$this->end_range = abs($this->start_range) 1;
$this->start_range = 1;
}
if($this->end_range > $this->numpages)
{
$this->start_range -= $this->end_range-$this->numpages;
$this->end_range = $this->numpages;
}
$this->range = range($this->start_range,$this->end_range);


}

private function setDefaults() {
//If currentpage is set to null or is set to 0 or less
//set it to default (1)
if (($this->currentpage == null) || ($this->currentpage < 1)) {
$this->currentpage = 1;
}
//if limit is set to null set it to default (20)
if (($this->limit == null)) {
$this->limit = 20;
//if limit is any number less than 1 then set it to 0 for displaying
//items without limit
} else if ($this->limit < 1) {
$this->limit = 0;
}
}

public function getNumpages() {
return $this->numpages;
}

private function getInternalNumPages() {
//If limit is set to 0 or set to number bigger then total items count
//display all in one page
if (($this->limit < 1) || ($this->limit > $this->itemscount)) {
$this->numpages = 1;
} else {
//Calculate rest numbers from dividing operation so we can add one
//more page for this items
$restItemsNum = $this->itemscount % $this->limit;
//if rest items > 0 then add one more page else just divide items
//by limit
$restItemsNum > 0 ? $this->numpages = intval($this->itemscount / $this->limit) 1 : $this->numpages = intval($this->itemscount / $this->limit);
}
}



private function calculateOffset() {
//Calculet offset for items based on current page number
$this->offset = ($this->currentpage - 1) * $this->limit;
}

public function getCurrentpage() {
return $this->currentpage;
}

public function getCurrentUrl() {
return $this->currentUrl;
}

//For using from controller
public function getLimit() {
return $this->limit;
}
//For using from controller
public function getOffset() {
return $this->offset;
}

public function getRange()
{
return $this->range;
}

public function getMidRange()
{
return $this->mid_range;
}

}







And this is how you can implement it in the controller:

use Path\to\class\Paginator;

class ListController extends SiteController
{
/**
* @extra:Route("/{offset}", name="_items")
* @extra:Template()
*/
public function listAction( $offset = 1)
{
$repository = new ListRepository();

$limit = 20;
$midrange = 7;

$itemsCount = $repository->getListCount();


$paginator = new Paginator($itemsCount, $offset , $limit, $midrange);

$items = $repository->getList ($offset);

.
.
.
return array('items' => $items, 'paginator' => $paginator);
}
}



And this is an example of a twig template you can use:


<div class="paginator">
<ul>
{% if paginator.currentpage != 1 %}
<li> <a class="previous" href="{{ path('_items', { 'offset': paginator.currentpage-1 }) }}">Previous</a>

{% endif %}
{% for i in 1..paginator.numpages%}

{% if paginator.range.0 > 2 and i == paginator.range.0 %}
...
{% endif %}


{% if(i==1 or i==paginator.numpages or i in paginator.range) %}

{% if i==paginator.currentpage %}
<li><a class="active" href="{{ path('_items', { 'offset': i })}}">{{i}}</a></li>
{% else %}
<li><a href="{{ path('_items', { 'offset': i }) }}"> {{i}}</a></li>
{% endif %}
{% endif %}

{% if paginator.range[paginator.midrange -1] < paginator.numpages -1 and i == paginator.range[paginator.midrange-1] %}
...
{% endif %}

{% endfor %}


<li> <a class="next" href="{{ path('_items', { 'offset': paginator.currentpage 1 }) }}">Next</a>
</ul>
</div>






I'm sure there are many improvements to be made, but it may help someone to have an idea.

You can find the files on git:

https://github.com/gigo6000/Symfony2-Pagination-Class

Wednesday, February 09, 2011

Symfony live 2011 interesting links - Symfony2 (day 2)

Fabien Potencier presentations:

http://www.slideshare.net/fabpot

Symfony2 from the trenches:

http://www.slideshare.net/jwage/symfony2-from-the-trenches



Being dangerous with Twig:


http://www.slideshare.net/weaverryan/being-dangerous-with-twig


Comment tag (do nothing): {# Comment #}

Print tag (show something): {{ 'print me' }}

Block tag (do something): {% set foo = 'hola' %}


Introducing Assetic: Asset Management for PHP 5.3: