Ciao Italia!

Later this week the 2012 edition of the phpDay conference will take place in Verona, Italy. We have been supporting this conference since the first one (we think), and thanks to this we have made a lot of friends from this part of the world.

We are extremely excited about this year and we are looking forward to meet all our customers and friends. Please look for Pablo and say hi – just look for the guy wearing the ServerGrove shirt. We love to have the chance to get to know our customers and this will be no exception.

Also, don’t miss the talk about Symfony2 and MongoDB that our cofounder Pablo Godel will be giving on Friday. And if you haven’t bought your ticket yet, we heard there are still a handful of them available, so don’t waste another second!

Ci vediamo a Verona!

Obtén tu entrada para deSymfony 2012

En poquito más de un mes, se llevará a cabo la conferencia de Symfony más importante del mundo de habla hispana, deSymfony. El año pasado estuvimos presentes y fue sensacional. Este año ya parece como que será aun mejor, con 2 tracks con muchísimas presentaciones y ponentes, incluído Fabien Potencier, el creador de Symfony y Pablo Godel, fundador de ServerGrove.

Gracias a nuestro patrocinio, disponemos de 2 tickets para ofrecer a nuestros clientes. Así que, si eres cliente de ServerGrove y todavía no has adquirido tu entrada esta es tu oportunidad. Para asignarte la entrada, envíanos un ticket de soporte y confirmanos que podrás asistir al evento. Queremos estar seguros de que la persona que obtenga la entrada la utilice, ya que hay mucho interés en la conferencia.

¡Nos vemos en Castellón!

Control Panel V2 launched with MongoHosting and lots more

We just launched a major upgrade to the control panel with a ton of new features. In many ways we feel our control panel grew up. Here are some of the new features you can expect to use:

0) Lets start with the elephant in the room. MongoHosting Beta has launched! For now it’s available only to our VPS clients and it comes with a free three month trial. Next we will notify those that signed up for the Beta, and then we will make it public.

Give it a spin and let us know what you think.

1) New design has dynamic width and fills the screen to 100%.

2) The navigation was rebuilt from the ground up. Pulldowns were added to easily jump to other parts of the control panel.

3) Charts were redesigned and improved.

4) A new history section allows you to see all the events on your server.

5) Diagnostics page is Ajax enabled . Now it runs the diagnostics on page load so you get fresh information and you can re-run diagnostics without having to reload the page.

6) Applications that support it, have a new test config feature that allows you verify the configuration of your app is correct and won’t fail. It will also display the  error that the application produces so you can fix it quickly without looking at the logs.

7) Connection files are available in the domain section and allow you to download SFTP configurations for the most common SFTP applications to allow you to share with your team or just use them yourself.

8) New search allows you to search for virtually anything in your server. The result will include domains and accounts from all your servers in your account.

9) Lots of small bugs, and UI performance improvements. More to come soon.

14

05 2012

Generate URLs from within a Twig Extension with Symfony2

It’s possible to generate a URL from within a Twig extension in a Symfony2 application. To do this, you need to have access to the Router. If you have a custom Twig extension, this means that you’ll need to inject the router to the extension. Thanks to the Dependency Injection this is very easy to do.

First, edit your services configuration to inject the Router:

<services>
  <service id="name.twig.extension" class="YourNamespaceTwigExtension">
    <tag name="twig.extension" />
    <argument type="service" id="router"/>
  </service>
</services>

The important part here is that you add the <argument type=”service” id=”router”/> line for your extension.

Then, modify your Twig extension class to receive and store the Router:

...
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;

class TwigExtension extends \Twig_Extension
{
  private $generator;

  public function __construct(UrlGeneratorInterface $generator)
  {
    $this->generator = $generator;
  }
  ...

Now, in your filter method you can generate the URL easily:

$url = $this->generator->generate('route', array('userId' => $user->getId()));

You can also view the TwigBridge source code for inspiration on how is done in Symfony2.

Tags: , ,

13

05 2012

Free PHP conference tickets

We have a few free conference tickets to give out to our clients. These are going on a first-come-first-serve basis but please don’t ask for one unless you are sure you can go.

Lone Star PHP Conference
1 Ticket gone!
When: June 29 – 30, 2012 in Dallas, Texas
http://lonestarphp.com/

 


 

SfCon Brasil 2012
5 Tickets
When: 23 of Junho, Belo Horizonte – Minas Gerais – Brasil
http://www.sfcon.com.br

10

05 2012

Common problems designers have when working with Symfony

For designers, Symfony2 has been a welcome change from those old flat PHP files. Twig is beautiful, the framework separates the code from the layout, and we no longer have to find our way through lines of PHP code. But if you are a designer working on a symfony project for the first time, these are a few tips that can help you get up and running quickly.

Tips

How do I disable the toolbar at the bottom of the page?
The toolbar at the bottom of the page is useful for developers but a hinderance to designers (especially if you are developing mobile apps). Not only does it cover your footer, but it also slows the page down. Since we don’t need it, most designers will want to get rid of it. To do this just edit: config/config_dev.yml and set the web_profiler to false:

config_dev.yml -> web_profiler: toolbar: false

Errors

Symfony has a lot of moving parts. Learning what the errors are and how to fix them is a useful skill to have.

Symptom: No Javascript or no-css showing up

You need to run:

 ./app/console assetic:dump

Assetic is the part of Symfony that compiles LESS files, combines and compress CSS and JS files, among other things. Sometimes when you download new files the cache needs to be recreated. Running the above command does this. Another useful way to use this command is:

 ./app/console assetic:dump -watch

This automatically recompiles all the css and js every time you modify a css and js file.

Symptom:

Symfony requires a series of libraries to run. Every so often these libraries get updated and you are required to update them on your local server as well. If your libraries are not updated, you will see an error like the one above.

To fix this open your terminal, go navigate to the root of your project and run:

./bin/vendors install

When you do ./bin/vendors install you will download all the latest libraries your application requires to function correctly. Once you run this command you should see a log printing out listing all the libraries that are being installed. Check that log to make sure you don’t have any permissions errors. In case you do run this command and enter your administrator password on prompt:

sudo ./bin/vendors install

Symptom: Blank page

90% of the time when you get a blank page it’s a permission issue. Symfony requires app/cache and app/logs directories to be writable both by the web server and the command line user. Fortunately fixing these is simple enough. In your terminal go to the root directory of your project and type:

rm -rf app/cache/*
rm -rf app/logs/*

sudo chmod +a "www-data allow delete,write,append,file_inherit,directory_inherit" app/cache app/logs
sudo chmod +a "`whoami` allow delete,write,append,file_inherit,directory_inherit" app/cache app/logs

If you are on a Mac and you are using Apache web server that comes with Mac OSX, replace www-data with _www in the above command.

Have more tips? Add them to the comments below!

30

04 2012

Spooling emails with Symfony2 on VPS and Shared Hosting

Sending emails is a very common task in web applications. Signup forms, contact forms, newsletters are among the most used features, but the email send task itself can be a little slow to the eyes of the user. Symfony2 provides us with the tools to send the emails to a buffer, and sending them when the time is proper eliminating the perception of having a lag time. Symfony integrates SwiftMailer through the SwiftMailerBundle.

When you send an email, the mailer communicates with a remote server in charge of receiving the message and of delivering it to the recipient. This process can cause your form to submit slowly as it depends on how fast the mail server responds.

Spooling allows us to decouple the application execution line from the process of the sending one, two, or as many emails as we need. By sending emails this way our application won’t get stuck with background tasks thus improving the user experience of your users.

A simple example of how important setting up Swiftmailer correctly is would be on a Signup form where a confirmation email is sent after the user submits their information. Now suppose there is a communication error between the mailer and the remote server, producing an exception from the mailer. This would be a really bad first impression for this user. Spooling prevents this sort of error.

Configuration

All we need to do is configure the SwiftMailerBundle by adding a few lines to the config.yml file.

# app/config/config.yml
swiftmailer:
    spool:
        type: file
        path: %kernel.root_dir%/spool

Every email sent by your application will now be stored in the spool located in /path/to/project/app/spool.

Sending the messages

Now that we have the emails in the spool, we are ready to sent them. In order to do so, you need to run the following command:

$ php app/console swiftmailer:spool:send

Emails are environment dependent, so we need to specify the environment on the command by adding the option --env=prod, since Symfony2 runs its commands in the dev environment by default.

Cronjob

A good way to process all the messages in buffer, is to set a cronjob running every minute or every two minutes. Sent messages are removed from the buffer, so you don’t have to worry about sending a message twice.

VPS

If you are a VPS user, you have to add the following lines to the crontab:

# /etc/crontab
...
*/2 * * * * root php /path/to/project/app/console --env=prod swiftmailer:spool:send

This way the email buffer will be processed every two minutes.

Shared Hosting

For Shared Hosting users is a little different, but still easy. You have to follow these steps to process the buffer every two minutes:

  1. Head to the Scheduled Tasks sections
  2. Select your user
  3. Click on Schedule New Task
  4. Configure your task as you can see in the screenshot
  5. Click Ok to finalize

Now, our mailer sends the emails in a background process, completely transparent for the user.

You can find more information about this in the Symfony Cookbook

27

04 2012

How to fix “Kernel pid terminated” when starting Rabbitmq

Today we installed RabbitMQ in a brand new server running Scientific Linux (SL) 6.2. SL is a relatively new Linux distribution based on RedHat Enterprise Linux, similar to CentOS, that lately has been gaining a lot of popularity.

The RabbitMQ installation on RHEL based servers is quite easy and well documented. So it was a surprise when RabbitMQ failed to start.

[root@dev]# /etc/init.d/rabbitmq-server start
Starting rabbitmq-server: FAILED – check /var/log/rabbitmq/startup_{log, _err}
rabbitmq-server.

The startup_err file included this error:

Crash dump was written to: erl_crash.dump
Kernel pid terminated (application_controller) ({application_start_failure,rabbit,{bad_return,{{rabbit,start,[normal,[]]},{‘EXIT’,{rabbit,failure_during_boot}}}}})

The message is quite cryptic. After looking around, some comments suggested issues with the hostname setup of our server, and others said it was an indication that something else was using the TCP port 5672 that RabbitMQ uses. The latter was the issue. A program called qpidd (Qpid AMQP Message Broker Daemon) was running and using the port. After stopping it, RabbitMQ started happily.

25

04 2012

Cómo crear un Cache Warmer en Symfony2

Por Ismael Ambrosi @iambrosi

El cache es una parte muy importante de tu aplicación, ya que ayuda a mejorar la performance del servidor al no ejecutar código innecesario en cada petición. Esto es especialmente cierto si el servidor se está corriendo con recursos limitados. El calentamiento del cache (o warmup) permite guardar datos específicos de tu aplicación en cache por medio del CacheWarmer. Symfony2 incluye un calentador de cache que te ayuda a guardar partes de tu aplicación en cache, antes de que la aplicación quede disponible para el usuario.

El CacheWarmer es ejecutado automáticamente si el cache no existe o ha caducado, creando así el cache de tu aplicación. También puede ser ejecutado manualmente con el comando cache:warmup o en el momento de limpiar el cache con cache:clear (!!! sin la opción --no-warmup).

Creando el “Warmer”

El Cache Warmer debe ser creado como un servicio que implementa la interface CacheWarmerInterface. Puedes ver en la sección de Service Container como crear servicios en Symfony2.

La interface CacheWarmerInterface nos permite implementar dos métodos, warmup y isOptional. El primero creará el cache y el segundo indicará si el warmer puede ser ignorado bajo ciertas condiciones o si debe ejecutarse siempre sin excepciones.

# src/Acme/DemoBundle/CacheWarmer/MyCacheWarmer.php
namespace Acme\DemoBundle\CacheWarmer;

use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;

class MyCacheWarmer implements CacheWarmerInterface
{
    /**
     * Warms up the cache.
     *
     * @param string $cacheDir The cache directory
     */
    public function warmUp($cacheDir)
    {
        // Process your cache content
        $cacheContent = 'Content to be cached';

        // Stores the cache
        file_put_contents($cacheDir.'/file.php', $cacheContent);
    }

    /**
     * Checks whether this warmer is optional or not.
     *
     * Optional warmers can be ignored on certain conditions.
     *
     * A warmer should return true if the cache can be
     * generated incrementally and on-demand.
     *
     * @return Boolean true if the warmer is optional, false otherwise
     */
    public function isOptional()
    {
        return true;
    }
}

También puedes extender la clase CacheWarmer la cual contiene un método para manejar la creación de los archivos de cache. Al extender esta clase, ya estarás implementando la interface mencionada anteriormente.

# src/Acme/DemoBundle/CacheWarmer/MyCacheWarmer.php
namespace Acme\DemoBundle\CacheWarmer;

use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmer;

class MyCacheWarmer extends CacheWarmer
{

    /**
     * Warms up the cache.
     *
     * @param string $cacheDir The cache directory
     */
    public function warmUp($cacheDir)
    {
        // Process your cache content
        $cacheContent = 'Content to be cached';

        // Stores the cache
        $this->writeCacheFile($cacheDir.'/file.php', $cacheContent);
    }

Creando el servicio

Una vez creada la clase, debes notificarle al Service Container que un nuevo Cache Warmer ha sido creado, para que pueda ser ejecutado. Puedes hacerlo agregando tu clase como servicio, incluyendo el tag kernel.cache_warmer.

<!-- src/Acme/DemoBundle/Resources/config/services.xml -->
<parameters>
    <!-- ... -->
    <parameter key="my_cache_warmer.class">Acme\DemoBundle\CacheWarmer\MyCacheWarmer</parameter>
</parameters>

<services>
    <service id="my_cache_warmer" class="%my_cache_warmer.class%">
        <tag name="kernel.cache_warmer">
    </service>
</services>

Ahora, cada vez que Symfony prepare el cache, tu Warmer va a ser ejecutado, creando tu propio cache.

24

04 2012

How to create a Cache Warmer in Symfony2

By Ismael Ambrosi @iambrosi

The cache is a very important part of your Symfony application as it helps your web server to perform better by not executing unnecessary code on every request, this is especially true if your server is running with limited resources. Cache warming allows you to cache specific data in your application through the use of a CacheWarmer. Symfony 2 includes a cache warmer that helps you to store parts of your application in cache, before the application becomes available to the user.

The CacheWarmer must implement a warmup, which will be ran by Symfony and will automatically re-create a cache of your app. It can also be manually executed with the command cache:warmup or when you clear your cache with cache:clear (!!! without the --no-warmup option).

Creating the Warmer

A CacheWarmer must be created as a service that implements the interface Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface. Take a look at the Service Container section of the Symfony manual on how to create services in Symfony2.

The CacheWarmerInterface interface allows us to implement two methods, warmUp and isOptional. The first method will create the cache and the second method tells the warmer if it can be ignored under certain conditions or it has to be executed without any exceptions.

# src/Acme/DemoBundle/CacheWarmer/MyCacheWarmer.php
namespace Acme\DemoBundle\CacheWarmer;

use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;

class MyCacheWarmer implements CacheWarmerInterface
{
    /**
     * Warms up the cache.
     *
     * @param string $cacheDir The cache directory
     */
    public function warmUp($cacheDir)
    {
        // Process your cache content
        $cacheContent = 'Content to be cached';

        // Stores the cache
        file_put_contents($cacheDir.'/file.php', $cacheContent);
    }

    /**
     * Checks whether this warmer is optional or not.
     *
     * Optional warmers can be ignored on certain conditions.
     *
     * A warmer should return true if the cache can be
     * generated incrementally and on-demand.
     *
     * @return Boolean true if the warmer is optional, false otherwise
     */
    public function isOptional()
    {
        return true;
    }
}

You can also extend the class Symfony\Component\HttpKernel\CacheWarmer\CacheWarmer, which already has a method for managing the creation of cache file or files. By extending this class, you are implementing the previous mentioned interface.

# src/Acme/DemoBundle/CacheWarmer/MyCacheWarmer.php
namespace Acme\DemoBundle\CacheWarmer;

use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmer;

class MyCacheWarmer extends CacheWarmer
{

    /**
     * Warms up the cache.
     *
     * @param string $cacheDir The cache directory
     */
    public function warmUp($cacheDir)
    {
        // Process your cache content
        $cacheContent = 'Content to be cached';

        // Stores the cache
        $this->writeCacheFile($cacheDir.'/file.php', $cacheContent);
    }

Creating the service

Once you create your class, you have to notify the Service Container that a new Cache Warmer has been created, so it can be executed. You can do so by adding your class as a service, including the tag kernel.cache_warmer.

<!-- src/Acme/DemoBundle/Resources/config/services.xml -->
<parameters>
    <!-- ... -->
    <parameter key="my_cache_warmer.class">Acme\DemoBundle\CacheWarmer\MyCacheWarmer</parameter>
</parameters>

<services>
    <service id="my_cache_warmer" class="%my_cache_warmer.class%">
        <tag name="kernel.cache_warmer">
    </service>
</services>

Now, every time your Symfony project warms the cache, your Warmer will be executed, creating your own cache.

18

04 2012