Symfony Resources Central

Web development made simple

I'd like to hear a Kwatuor play nice symfonic music

Today's post is a bit special.

This can be took as a question.

Or a call to developpers that have specific blogging needs.

Since quite a moment I used dotclear for blogging. That suit my needs, in some way, but maybe I'm more adaptating my needs to dotclear's capabilities. Maybe you're using wordpress. or any other. And I guess that must be the same for you, thinking for example of integrating one of those all-in-one blogging/cms platforms cleanly in another website, for example, is being more than utopian...

By clean I mean integrating it without having to duplicate the template. Neither having to use all functionalities if you only need a simple article list somewhere... And without being limited if you need to display the headers of those on another website...

I'd better not speak of blog networks communicating, or taking content from RSS/XML/anything feed in a flexible way.

So today I'd like to announce the birth of Kwatuor. Kwatuor is a blog platform project using symfony and doctrine, that will in the near future use doctrine migrations to get content from an existing dotclear/wordpress project, or any other source platform someone has enough need with he'd take the time to write migration classes for.

Templating system will be different. I'm still hesitating between a generator approach (generated partials from a dynamic skeleton, that all can be customizable) and a real proper template system (but still any part would be customizable). Only major difference with blogging platform would be the total forbidding of DRY-breaks a dotclear-like templating system is doing everyday. And this extends to integrated blogs, in wider projects.

In fact I started developing it for my own needs, but I think this is typically the kind of project everybody would need someday. Maybe you hate being jailed in your obscure, yet very good, but specific and... even more obscure blog platform.

So I'm wondering now, if people (you :p) would be interested in this project. If so, I'll make a public SVN/trac next week, so concerned users will be able to give feedback with code in their hands. Would this be usefull to you? Would you contribute to this open-source project? Do you have good (or bad :p) ideas about concepts to take in consideration from the beginning?

Related links

Complex relations population in propel

Since quite a bit, I've been faced with an annoying problem on every projects I use propel on. Propel builders only generates some specific cases selection methods, which consists of pretty ugly copy paste of the same code to populate the objects, and if your needs are not satisfied by the finite little number of propel handled cases, you'll have to either use pure SQL, or write a custom doSelect method. That seems okay at first sight, but it is not. In fact, you're about copypasting the propel generated method, and that's a rude violation of D.R.Y. principle.

I found no solutions during the two last years, but maybe things will change soon with the new sfPropelImpersonatorPlugin. This plugin is aiming at doing arbitrary object population based on informations provided by propel's introspection methods (DatabaseMap/TableMap/ColumnMap) to link populated objects.

The plugin is currently in very early stage, but is working pretty well for my needs, and I'm looking forward to know what others are thinking about it.

Related links:

sfForms11Plugin: use symfony 1.1 form/validation framework in symfony 1.0 or non-symfony project

The new symfony 1.1 form/validation framework is 100% symfony-independant, and though is not limited to the (very) awaited 1.1 stable release. To use it in your own symfony 1.0 projects, you can use sfForms11Plugin. It's content is very thin: it only sets up externals to symfony 1.1 form/widget/validator libraries.

To use it, simply add the following external to your project:

sfForms11Plugin http://svn.symfony-project.com/plugins/sfForms11Plugin

Or check it out from your project base directory:

svn co http://svn.symfony-project.com/plugins/sfForms11Plugin plugins/sfForms11Plugin

Let's try it...

Now you'll be able to define sfForm sub-classes to materialize forms:

class HelloWorldForm extends sfForm
{
  public function configure()
  {
  }

  public function setup()
  {
    $this->setWidgetSchema(new sfWidgetFormSchema(array(
            'name' => new sfWidgetFormInput(),
            )));

    $this->setValidatorSchema(new sfValidatorSchema(array(
            'name' => new sfValidatorString(array('required'=>true, 'min_length'=>1, 'max_length'=>50)),
            )));

    $this->widgetSchema->setNameFormat('hello[%s]');
    $this->errorSchema = new sfValidatorErrorSchema($this->validatorSchema);

    parent::setup();
  }
}

This class define the model of your HelloWorldForm, and you can now use it in your actions:

class testActions extends sfActions
{
  function executeHelloWorld()
  {
    $this->form = new HelloWorldForm();

    if ($this->getRequest()->getMethod() == sfRequest::POST)
    {
      if (null !== ($hello = $this->getRequestParameter('hello', null)))
      {
        $this->form->bind($hello);

        if ($this->form->isValid())
        {
          $this->redirect('@hello?name='.$this->form->getValue('name'));
        }
      }
    }
  }
}

At this point, the only little detail still missing is the view, containing actual form display:

<form method="POST">
<table>
<?php echo $form; ?>
<tr>
  <td colspan="2" align="right">
    <input type="submit" value="Greetings, Mr Computer!" />
  </td>
</tr>
</table>
</form>

That's it! You now have a simple form, self-validating, protected against CSRF attacks and redirecting to some place if values entered matched our sfValidatorSchema.

Tired of spam? Try dkAntispamPlugin

After last week hashbin's new release, I decided to publish dkAntispamPlugin. That's an early release, and by now it is not very feature-full, but it's doing the job we ask it, and since now, proved efficient on HashBin to make not public the pretty large amount of spam I get on it.

In One week, we got 40 messages with spam_value<10 (all checked, no spam), 14 more with spam_value<20, some of those were not spam but either inconsistent, or URL-full, 97 more between 20 and 50 (100% spam) and 498 more over this, which i'll consider as spam (don't really feel like reviewing all those).

For now, the plug-in only makes some reg-exp check, length check and URL count checks, but I'm planning in adding IP check and refining reg-exps to be less CPU eating. If any of you have anymore ideas to improve it... You're all welcome :-)

At the same time, I refactored sfGeshiPlugin to dkGeshiPlugin, to leave sf prefix for official symfony plugins, so be sure to check the wiki or documentation if you're using it.

Creating custom config handlers in symfony 1.0

When writing plugins, you often want to do it the symfony way, by putting configuration stuff in YAML files to allow the final user to override your default values in a harmless way.

To do this, the correct way is to create a config handler, extending sfConfigHandler, or its child class sfYamlConfigHandler.

Here is a simple one, just dumping YAML data found in your config file into an sfConfig::get()-able PHP dataset.

class myStupidConfigHandler extends sfYamlConfigHandler
{
  public function execute($configFiles)
  {
    // retrieve yaml data
    $config = $this->parseYamls($configFiles);

    $code = sprintf("<?php\n" .
                    "// auto-generated by myStupidConfigHandler\n" .
                    "// date: %s\n" .
                    "sfConfig::set('my_stupid_config_entry', %s);",
                    date('Y-m-d H:i:s'), var_export($config, 1));

    return $code;
  }
}

We could enhance it a bit, to take advantage of symfony's environments and permit an 'all' (as a default section) and as many environment specific sections as you want. Here is it.

class myStupidConfigHandler extends sfYamlConfigHandler
{
  public function execute($configFiles)
  {
    // retrieve yaml data
    $config = $this->parseYamls($configFiles);

    // get current environment
    $environment = sfConfig::get('sf_environment');

    // merge default and environment specific config
    $config = sfToolKit::arrayDeepMerge(isset($config['all'])?$config['all']:array(), isset($config[$environment])?$config[$environment]:array());

    $code = sprintf("<?php\n" .
                    "// auto-generated by myStupidConfigHandler\n" .
                    "// date: %s\n" .
                    "sfConfig::set('my_stupid_config_entry', %s);",
                    date('Y-m-d H:i:s'), var_export($config, 1));

    return $code;
  }
}

Next step will be to tell symfony which configuration file patterns should be loaded using our class. To do this, add the following entry to config/config_handlers.yml (whether in your app, plugin or module, depending on the scope of your config handler)

config/stupid.yml:
  class:    myStupidConfigHandler

Once this is done, the very little remaining last step is to mak sure you include the compiled yml.php file with the following magic command, that will rebuild it when unexistant or outdated:

require_once(sfConfigCache::getInstance()->checkConfig('config/stupid.yml'));
/* ... */
$stupid_config = sfConfig::get('my_stupid_config_entry');

easy one :-)

Hashbin v3 just went to public beta

I'm proud to annouce that HashBin v3 is out, using the latest improvements to dkGeshi (old sfGeshi, soon public) and the brand new dkAntispamPlugin, which can give a text a note about its probability of being spam, or junk. If everything goes well with hashbin, and after some required (i guess) tuning to the plugin, it will go opensource to let you take advantage of it.

For thoose who never used it, HashBin is a free PasteBin service, a collaborative debugging tool allowing developpers to share source code snippets. Hashbin is powered by the Symfony Framework and PHP Doctrine ORM.

- page 2 of 3 -

© Copyright 2007-2008 daKrazy. All rights reserved.

Design and template by hartym