The blog of COil : PHP, symfony & Web 2.0

Strangebuzz...?

Réduire au titre / collapse all

13/09/2009

» New 1.2 symfony plugin + tutorial: sfTaskLoggerPlugin

Hi symfonians ! ^^

Again, that's quiet a long i didn't post something on symfony. Well i suppose releasing a new is a good occasion for this. Let me introduce the sfTaskLoggerPlugin plugin:

The sfTaskLoggerPlugin plugin allows you to run tasks and store the results. Results are stored in the database in a specific table and also in a log file. Each task has its own log file, witch is stored in a specific directory depending on its namespace and name. (`/log/tasks/:TASK_NAMESPACE/:TASK_NAME`).

The database record stores the following informations:

  • Options of the task
  • Arguments of the task
  • An error code
  • Start and end time
  • A success flag
  • The log file path
  • Extra comments (for admin)

It's very useful, I've already used on several project i worked on (from 1.0 to 1.2). You to have a clean and "easy to access" historic (through an admin gen module for example) of all run tasks and their results. How to use it ? Well Very easy !!

Note: The plugin is Doctrine and Propel friendly, it you are using Doctrine, the /lib/config/doctrine/schema.yml will be used whereas using Propel the /lib/config/schema.yml will be used.

Installation

  • Install the plugin
       $ symfony plugin:install sfTaskLoggerPlugin


(or download it and unzip in your /plugins directory)

  • Clear you cache
       $ symfony cc


Configuration


The plugin comes with a base task class witch is named sfBaseTaskLoggerTask Therefore your tasks must extend this one. Because there is no autoloading at the task level, one must include the base class manually:

   require_once(dirname(FILE). '/sfBaseTaskLoggerTask.class.php');

Note: Of course you will have to change this path depending on where is located your task. For example if it is located in the `/lib/task` folder of your project, the include directive should look like this:

   require_once(dirname(FILE). '/../../plugins/sfTaskLoggerPlugin/lib/task/sfBaseTaskLoggerTask.class.php');


Usage


1 - Create a new class that extends the plugin base class:


<?php
class sfTaskLoggerSampleTask extends sfBaseTaskLoggerTask
?>


2 - Implement the configure() method as you would do with a standard task:


[php]
<?php
/**
 * Main task configuration.
 */
protected function configure()
{
  $this->addArguments(array(
    new sfCommandArgument('arg_1', sfCommandArgument::OPTIONAL, 'Test argument 1', 'arg_1_value'),
    new sfCommandArgument('arg_2', sfCommandArgument::OPTIONAL, 'Test argument 2', 'arg_2_value'),
  ));

  $this->addOptions(array(
    new sfCommandOption('env', null, sfCommandOption::PARAMETER_REQUIRED, 'Environment used', 'prod'),
    new sfCommandOption('application', null, sfCommandOption::PARAMETER_REQUIRED, 'Application used', 'frontend'),
  ));

  $this->namespace = 'sf_task_logger';
  $this->name      = 'sample';

  $this->briefDescription = 'This is a sample task !';

  $this->detailedDescription = <<<EOF
The task [sf_task_logger:sample|INFO] doesn't do that much.
It logs itself in the database and in the file system:

  [./symfony sf_task_logger:sample --env=prod|INFO]
EOF;
}
?>


Now there are 2 specific methods to implement:

3 - checkParameters()


[php]
<?php

        /**
         * Advanced check of task parameters.
         */
        protected function checkParameters($arguments = array(), $options = array())
        {
          /* // Stupid example test
          if ($this->args['arg_1'] != 'arg_1_value')
          {
            throw new InvalidArgumentException('The value for argument 1 is not valid ! Check the help of the task.');
          }
          */
    
          return true;
        }
?>


Note: This method can be usefull if you have advanced controls to do on task parameters or arguments. Just return `true` if you don't have to use it.

4 - doProcess()


[php]
<?php
        /**
         * Main task process.
         */
        protected function doProcess()
        {
          try
          {
            $this->printAndLog(' - This is a log info !!');
            $this->task->setErrorCode(self::ERROR_CODE_SUCCESS);
            $this->setOk();
          }
          catch (Exception $e)
          {
            $this->task->setErrorCode(self::ERROR_CODE_FAILURE);
            $this->setNOk($e);
          }
        }
?>


Note: This is the main method of your task process. `$this->task` is the database object that will be saved. As you can see the `setOk()` and `setNOk` methods allow to set the flag of the record automatically depending on the success or failure of the task.

If you want more control on the task process you can also re-implement the `execute()` method of the base class witch is responsible for calling all others sub functions:

[php]
<?php
    /**
     * Global process of the task.
     *
     * @see sfTask
     */
    protected function execute($arguments = array(), $options = array())
    {
      $this->setParameters($arguments, $options);
    
      $this->checkParameters($arguments, $options);
    
      $this->initDatabaseManager();
    
      $this->initLogger();
    
      $this->logStart();
    
      $this->doProcess();
    
      $this->logEnd();
    }
?>


Notes:

The plugin is bundled with a sample task: `/lib/task/sfTaskLoggerSampleTask.class` witch can be run with the following command:

   ./symfony sf_task_logger:sample


TODO

  • Include Propel and Doctrine admin generator module

Support


Please report bugs or feature request on this post.

Changelog


See you. COil ^^

PS: I have published this tutorial quiet quickly, please help me by reporting typos and errors.
PS2: The official README file is far more readable
PS3: As always, any contribution will be welcome !

03/05/2009

» sfTCPDFPlugin v1.6.1 released

This new release for symfony 1.2 is quiet interesting as it introduces a new custom configuration handler witch allows you to manage all the TCPDF constants through YAML files and you can also manage multiple configurations. If you are using the plugin don't forget to use the "I USE AND LIKE THIS PLUGIN" on the symfony plugin website. ^^


Changelog:

  • Corrected config loader
  • Converted README to Markdown syntax
  • Added a method to get the final TCPDF configuration
  • New plugin configuration handler that allows you to use multiple configugurations for different actions and pdf
  • Reorganized svn structure of the plugin, created 1.0, 1.1 and 1.2 branch
  • New version for symfony 1.2


12/04/2009

» Writing symfony plugins is great... maintaining them is better !

Wow, that's quiet a long time i didn't blogged !! Let see if i can write something interesting ! :) As you have probably noticed, the symfony plugin count has recently reached the 500. This is really huge ! To celebrate this, Fabien has added an interesting functionality "I use this plugin" witch allows you to tell the plugins you use in yours projects. This "plugin users count" will show witch are used and work, so you don't have to waste time on a plugin witch does not work at all... Like the sfNadaPlugin... :p Moreover i think there will be another good side effect of this new functionality, is to encourage the plugins authors to update their plugin more frequently or to convert them for the different major versions of symfony. That's what i did the last week.

sfDB4toPropelPlugin

sfDB4toPropelPlugin


sDB4toPropelPlugin is a plugin that adds to symfony a new task: propel:db4-to-propel that allows you to convert a DB4 schema (a DBDesigner4 schema) into a valid Propel schema.yml file, with this plugin you can just forget the boring work of building your schema.yml by hand. ;)
This is probably the most interesting of my plugins and i am quiet surprised there is only 3 guys who use it :/ (including me). The last interesting functionality that was added with the 1.0.3 version is that you can declare tables as "external", that means that inside your DB4 schema you can make links to plugins tables, like sf_guard_user. This is very practical, i used it since more than 2 years (the 1.0 and 1.1 versions were never published) so that why i am quiet surprised this plugin doesn't have more success... Perhaps it just get lost among the 500 others. ;) If you use and like this plugin and want to help me in giving it more visibility on the symfony website, click on the following link :D

website)



I will start soon the development of the worthy successor of this plugin, the sfWorkbenchPlugin, any help will be welcome ! :) This time i'd like to make the plugin Propel and Doctrine friendly, witch would be very interesting for all symfony users.

sfLightboxPlugin

sfLightboxPlugin


sfLightboxPlugin is a symfony plugin that provides an easy to use wrapper for the Lightbox2 javascript library.



sfTCPDFPlugin

sfTCPDFPlugin

The sfTCPDFPlugin provides abstraction for the TCPDF library. The main interest of this FPDF "fork" resides in the fact that it handles any UTF8 strings witch the native encoding format used by symfony.

I have just updated this plugin, this new version for symfony 1.2 introduces a new interesting functionality , it's a handy config handler to manage several TCPDF configurations with a YAML file, so you don't have to set the TCPDF constants. So this version is far more practical that the old one.



sfJoomlaBridgePlugin

sfTCPDFPlugin


This was an experimental plugin, but i shamefully abandoned it... But there's a reason; it's because this old plugin was for symfony 1.0 and the old Joomla 1.0 version. Now there is a new plugin the sfJoomla15BridgePlugin for symfony 1.2 and Joomla 1.5.x witch is based on my previous code, so i have joined the dev team of this plugin. Even if have abandoned the plugin i have updated its description to invite the users not to use this one but the new one, so they don't waste their time on it. (i have received several mails about it from users who didn't saw the new 1.5 plugin... :x)



sfMyNextSymfonyPlugin


I already have several ideas for my next plugins. One that was never published and one about tests... But this will be part of another post. I wish i could find some time to post a little more frequently.

  • You can find all my plugins here


See you. symfoniquement votre. ++ COil :)

07/12/2008

» Jobeet: An alternative tutorial for Day 3

Hi symfonians ! ^^

Well, i didn't post very often during these last months. So let's try to write something interesting. In this post i will show you an alternative way to build your database with symfony, propel and the DB4 tool. This tutorial is not really an "alternative" to the official tutorial. :) Let's say that we will just see another way to build our database, i won't be as exhaustive as Fabien did in the Jobeet Day 3 tutorial, therefore, for all details please refer to the official Jobeet tutorial.

Pre-requisites:

  • Having done at least day 1 and 2 of the Jobeet tutorial. (or you already know symfony, in this case you will need a fresh symfony 1.2 project)
  • Not being too angry with Propel :p

What you will learn:

  • Using the sfDB4toPropelPlugin to build your schema.yml without writing a single line of this file.


What you will NOT learn:

  • How wonderful symfony is. For this, read the official Jobeet tutorial of Fabien. :)


So let's go... We will start at this part of the Jobeet 3 tutorial.

Start


1 - Plugin installation


First we will install the sfDB4toPropel plugin, i did not released any package for the symfony 1.2 version yet, so we will install it via SVN. (edit: i've just released the 1.0.2 version for sf 1.2.0)

   $ cd plugins
   $ mkdir sfDB4toPropelPlugin
   $ cd sfDB4toPropelPlugin
   $ svn co http://svn.symfony-project.com/plugins/sfDB4toPropelPlugin/branches/1.2


Be careful not to check out the root of the plugin but the branch related to the symfony version you want to use, actually 1.1 or 1.2)

(PS: You can also set an svn external to the plugin if your project already uses a svn repository)

...

» Lire la suite / read all «

09/09/2008

» new symfony 1.1 / 1.2 plugin + tutorial : sfDB4toPropelPlugin

1 - sfDB4toPropelPlugin presentation


I've just released a new plugin, it is called sfDB4toPropelPlugin, what is this ? Can it make coffee ? Not yet. ;) Well this one add to symfony a new task: propel:db4-to-propel that allows you to convert a DB4 schema (A DBDesigner 4 schema) into a valid propel schema.yml file. It can handle:

  • I18n tables
  • Foreign keys
  • phpNames of tables
  • Name of propel connection
  • Comments for all fields
  • Name of target schema
  • Lib package name
  • And several other options...


You can read a complete tutorial for this plugin in the full version of this post.
Of course, i'll be glad to have some feedback here, to know what you like / dislike and what could be improved.

See you. COil ;)



Related posts:


PS: Reading the related posts, it seems that i did not use the "last version", so i'll check what can be included in the next version of the plugin.

...

» Lire la suite / read all «

18/06/2008

» Allomatch V3 powered by symfony !

Well the V2 was also powered by symfony (V1.0) and the V1 was powered by Joomla. ;) What is Allomatch ? It's a website where you can see the pubs where you can see sports events on television, like actually with the Eurocup 2008. You've got a match, then you have the google map of France, you just have to click on the region or to enter your address to see what is the closest pub were you will be sure to be able to see the match. This V3 mainly adds some "community features", for example you can tell to others members where you will see the match, give you thought on the "match wall", if you like a bar... and so on.

It was a pleasure to work with you, thanks to Fabrice and Benoit and i wish you the best for the future. :)

PS: The Hall's beer tavern the pub of the Paris "sfPot" is one of the Allomatch pubs ! ;)
PS2: Try and test the "Pouet" feature (the counters), one of the most addictive of the site ! ;)

allomatch

02/05/2008

» PHP_Debug V2.1.3 released

This is just a small update to correct and close minor bugs that were on the Pear bug tracker. I have also finally added the sources on the php csv server. The last step will be to do the end user documentation in the DocBook format so it can be available in the official pear documentation.

:)

03/04/2008

» symfony 1.0 tutorial : Extending the admin generator

[En] Tutorial content:

  • Creating a plugin with a custom admin generator theme
  • Extending the sfActions class
  • Extending the sfPropelAdminGenerator class


Here is little contribution for the symfony code sprint, a symfony tutorial about the admin generator. :) Do you know about it ? I think it's one of my favourite symfony tool, i have developed several applications with symfony and for 75% of them i have made a custom admin generator theme. And as said in the symfony documentation, the admin generator is very very very powerful. ;)
In this tutorial we will see a concrete example on how to extend it to provide a useful new feature. Witch feature ? Well it was one of the things a customer asked me, "I want to be able to delete several rows at a time with check boxes" ... Ahhhhh indeed, it's not a native feature of the admin generator. So.... let's do it... :)

::: Pre-requisite :::


Well i will not explain here how to install symfony as there are lots of tutorials about this on the symfony website and in the wiki. So i will assume you have a clean symfony installation so you can type the symfony command in cli. I used the 1.0.13 version for this tutorial.

::: Creating and setting a new project :::


:: Creating the new project ::


First we will create the new project that we will call tutorial, create a new folder tutorial and launch the init-project task into it.

symfony init-project tutorial

Now let's create the backend application:

symfony init-app backend

As it is always better to have a submain for our application add the following in you apache httpd.conf file and change it with your own path

## COil symfony tutorial n°1 : Extending the admin generator ##

<VirtualHost *:80>
  ServerName dev.tutorial.com
  DocumentRoot "C:\wamp\www\tutorial\web"
  DirectoryIndex index.php
  Alias /sf "c:\wamp\bin\php\php5.2.5\PEAR\data\symfony\web\sf"
  
  <Directory "C:\wamp\www\tutorial\web">
    AllowOverride All
  </Directory>
</VirtualHost>

Add the sub-domain in you hosts file:

127.0.0.1 dev.tutorial.com

Ok, at this point we should have our "Project created!" page. So Let's try to browse http://dev.tutorial.com/backend_dev.php

tuto1-1


:: The database ::


Create a local database, let's call it tutorial again. (same as the project name)
Modify the database settings in the config/database.yml and config/propel.ini file, your database.yml file should look like this:

all:
  propel:
    class:          sfPropelDatabase
    param:
      dsn:          mysql://root@localhost/tutorial


Now we need a schema, let's take the one of Askeet


Ok now let's try to build the database:

symfony.bat propel-build-all-load backend

Oops, it seems there are some errors. :) As we are quite lazy just delete the password columns and the QuestionTag section of the /datas/fixtures/test_data.yml file.
Let's try again to run the last command. If your are successful you should now have some tables and data in your tutorial database. If not, you probably missed something. ;) At this point we have a valid application with a database, some tables and fixtures. Settings are ok, so can go to the next step.

...

» Lire la suite / read all «

25/03/2008

» symfony 1.0 : traduction FR de la cheatsheet Ajax

[FR] J'avais traduis il y a quelque temps la cheatsheet sur les helpers ajax realisée par Andréia Bohner. En fait il ne m'avait pas répondu très vite donc elle était un peu tombée aux oubliettes. J'avais fais cette traduction un peu vite fait et mot à mot donc le résultat n'est pas tip-top. :/ Donc si vous avez des propositions de modifications à n'hésitez pas, je peux les regrouper et envoyer la mise à jour à Andréia. Sinon ça pourra toujours servir à quelqu'un ne parlant pas un mot d'anglais ni de portugais. ;)

Traduction française de la cheatsheet ajax symfony



18/03/2008

» Symfony 1.0 tip : Registration of plugin routes

[En] Here is a little tip Fabien gave me. I am actually developing a plugin witch has quiet a lot of routes (about 40). Normally you can add the routes with the prependRoute function, like does the sfGuardplugin.

<?php
if (sfConfig::get('app_sf_guard_plugin_routes_register', true) && in_array('sfGuardAuth', sfConfig::get('sf_enabled_modules', array())))
{
  $r = sfRouting::getInstance();
 	
  // preprend our routes
  $r->prependRoute('sf_guard_signin', '/login', array('module' => 'sfGuardAuth', 'action' => 'signin'));
  $r->prependRoute('sf_guard_signout', '/logout', array('module' => 'sfGuardAuth', 'action' => 'signout'));
  $r->prependRoute('sf_guard_password', '/request_password', array('module' => 'sfGuardAuth', 'action' => 'password'));
}
?>


But for each prependRoute call an array_merge is done on all existing routes.

<?php
  /**
   * Adds a new route at the beginning of the current list of routes.
   *
   * @see connect
   */
  public function prependRoute($name, $route, $default = array(), $requirements = array())
  {
    $routes = $this->routes;
    $this->routes = array();
    $newroutes = $this->connect($name, $route, $default, $requirements);
    $this->routes = array_merge($newroutes, $routes);
 
    return $this->routes;
  }
?>


So the tip here is to save all routes, clear them, add the routes of the plugin and then append the saved routes. Witch can be done like this:

<?php
  // Save and clear all routes
  $r = sfRouting::getInstance();
  $routes = $r->getRoutes();
  $r->clearRoutes();
  
  // Plugin home
  $r->connect('plugin_home', '/my_super_plugin/homepage', array(
    'module' => 'my_plugin_module', 
    'action' => 'my_plugin_action',
    'additional_parameter'   => 1
    ));
 
  // Another route
  $r->connect('plugin_home', '/my_super_plugin/section1', array(
    'module' => 'my_plugin_module', 
    'action' => 'my_plugin_action_section1',
    'additional_parameter'   => 2
    ));
 
  // ... other routes
 
  // Then merge new routes with the saved one
  $r->setRoutes($r->getRoutes() + $routes);
?>


That's it. :) Of course it is always better to have all routes of the application in the routing.yml but in my case it was not possible.

» Autres billets / Other post

1 2 3 4 >