Code snippets for symfony 1.x

Navigation

Snippets by user Kormany Gabor

Javascript loading optimalization

Hi!

I am using a lot of hand written jscript codes due to the required behavior not found in any javascript framework. I've created my Objects in distinct files, although some of them are quite small ( <1kb ). So to make it fast, I've written a filter class that actually parses the files found in the /js directories having *.js suffix. It does not only parse them together but removes whitespaces, comments, indentations so the sum filesize gets a bit compressed. The filter also includes the final file into the response so there is no need to include any *.js ( inside /js ) in a template.

<?php
 
    class JavascriptParser extends sfFilter
    {
      public function execute($filterChain)
      {
        $filterChain->execute();
 
 
        $fp = fopen( "js/compiled.js", "w" );
 
        JavascriptParser::getJSFiles( "js", $fp );
 
        fclose ( $fp );
 
        $response = $this->getContext()->getResponse();
        $content = $response->getContent();
        if (false !== ($pos = strpos($content, '</head>')))
        {
          $html = "<script type='text/javascript' src='/js/compiled.js'></script>";
 
          if ($html)
          {
            $response->setContent(substr($content, 0, $pos).$html.substr($content, $pos));
          }
        }
 
      }
 
      public function getJSFiles( $dir, &$fp )
      {
        $hDir = opendir( $dir );
        while( ( $filename = readdir( $hDir ) ) !== false )
        {
            if ( is_dir( $filename ) )
            {
            }
            else if ( is_dir( $dir."/".$filename ) )
                JavascriptParser::getJSFiles( $dir."/".$filename, $fp );                
            else if ( strpos( $filename, ".js" ) !== false && $filename != "compiled.js" )
            {
                $tmpFile = fopen( $dir."/".$filename, "r" );
                $data = fread( $tmpFile, filesize( $dir."/".$filename ) );
 
                $data = preg_replace( "'\/\*.*?\*\/'si", "", $data  );
                $data = preg_replace( "'//.*?\n'si", "", $data );
                $data = preg_replace( "'[ \t]+'", " ", $data );
 
                fwrite( $fp, " \n".$data );
                fclose( $tmpFile );
            }
        }
        closedir( $hDir );  
      }
    }
 
?>
 

The same should be done with *.css files, since they are even smaller and loading many small files takes much more time then loading one big.

Best Regards

by Kormany Gabor on 2008-04-13, tagged filter  javascript 
(1 comment)

Simple CAPTCHA

Hi!

This code is about a very simple CAPTCHA validation. I am pretty sure that you all know what CAPTCHA is, so I won't explain it. This CAPTCHA is based on the color-blindness test that operates with various colored balls.

The class:

class Captcha
{
    protected $value;
    protected $image_name;
 
    public function __construct( $image_name )
    {
        $this->image_name = $image_name;
    }
 
    public static function createNumber( $length = 4 )
    {
        $num = "";
        for ( $i = 0; $i < $length; $i++ )
        {
            $r = mt_rand( 0, 9 );
            $num = $num.$r;
        }
        return $num;
    }
 
    public static function createString( $length = 4 )
    {
        $val = "";
        $values = "abcdefghijklmnopqrstuvwyz";
        for ( $i = 0; $i < $length; $i++ )
        {
            $r = mt_rand( 0, 24 );
            $val = $val.$values[$r];
        }
        return $val;        
    }
 
    public function setValue( $value )
    {
        $this->value = $value;
    }
 
    public function getValue( )
    {
        return $this->value;
    }
 
    public function showImage( $channel = null )
    {
        $im = imageCreate( 160, 60 );
        $white = imagecolorallocate( $im, 255, 255, 255 );
        $black = imagecolorallocate( $im, 0, 0, 0 );
 
        $intensity = rand ( 200, 230 );
 
        if ( !$channel )
        {
            $channel = rand ( 1, 3 );
        }
        $ratio = rand ( 80, 100 );
 
        switch ( $channel )
        {
                case 1:
                        $colorBgR = $intensity * $ratio / 100;
                        $colorBgG = $intensity * ( 100 - $ratio ) / 100;
                        $colorBgB = 0;
 
                        for ( $i = 0; $i < 5; $i++ )
                        {
                                $shift = rand( 100 - ( $i+1)*3, 100 + ( $i+1)*3 );
                                $new = $shift * $colorBgR / 100;    
 
                                $bgColors[] = iMagecolorallocate( $im, $new, $intensity-$new, 0 );
                        }
 
                        for ( $i = 0; $i < 3; $i++ )
                        {
                                $shift = rand( 100 - ( $i+1)*7, 100 + ( $i+1)*7 );
                                $new = $shift * $colorBgR / 100;    
 
                                $bgColors[] = iMagecolorallocate( $im, $intensity-$new, $new, 0 );
                        }
                break;
 
                case 2:
                        $colorBgG = $intensity * $ratio / 100;
                        $colorBgB = $intensity * ( 100 - $ratio ) / 100;
                        $colorBgR = 0;
 
                        for ( $i = 0; $i < 5; $i++ )
                        {
                                $shift = rand( 100 - ( $i+1)*3, 100 + ($i+1)*3 );
                                $new = $shift * $colorBgR / 100;    
 
                                $bgColors[] = iMagecolorallocate( $im, 0, $new, $intensity-$new );
                        }
 
                        for ( $i = 0; $i < 3; $i++ )
                        {
                                $shift = rand( 100 - ( $i+1)*7, 100 + ( $i+1)*7 );
                                $new = $shift * $colorBgR / 100;    
 
                                $bgColors[] = iMagecolorallocate( $im, 0 , $intensity-$new, $new );
                        }
 
                case 3:
                        $colorBgB = $intensity * $ratio / 100;
                        $colorBgR = $intensity * ( 100 - $ratio ) / 100;
                        $colorBgG = 0;
 
                        for ( $i = 0; $i < 5; $i++ )
                        {
                                $shift = rand( 100 - ( $i+1)*3, 100 + ( $i+1)*3 );
                                $new = $shift * $colorBgR / 100;    
 
                                $bgColors[] = iMagecolorallocate( $im, $intensity-$new, 0, $new );
                        }
 
                        for ( $i = 0; $i < 3; $i++ )
                        {
                            // to make it harder do symmetric range ^^ 
                                $shift = rand( 100 , 100 + ( $i+1)*20 );
                                $new = $shift * $colorBgR / 100;    
 
                                $bgColors[] = iMagecolorallocate( $im, $new , 0, $intensity-$new );
                        }
                break;
        }
 
 
 
 
        $bgColor = imagecolorallocate( $im, $colorBgR, $colorBgG, $colorBgB );
 
 
        for ( $i = 0; $i < strlen( $this->value ); $i++ )
        {
            $rotate = rand(-15, 15);
 
            $fontSize = rand(28, 36);
            imagettftext($im, $fontSize ,$rotate , 10+$i*31, 50, $black, "impact.ttf",$this->value[$i] ); 
        }
 
 
 
 
        for ( $i = 0; $i < 160; $i++ )
        {
                for ( $j = 0; $j  < 60; $j++ )
                {
                        $pos = rand( 0, 7 );
 
                        if ( imagecolorat( $im, $i, $j ) == $black )
                        {
                                $pos = rand( 6, 7 );
 
 
 
                                imagesetpixel( $im, $i, $j, $bgColors[$pos] );
                        }
                        else
                        {
                                imagesetpixel( $im, $i, $j, $bgColors[$pos] );
                        }
                }
        }
 
        imagejpeg( $im, "images/".$this->image_name.".jpg" );
        imagedestroy( $im );
        echo" <img src='/images/".$this->image_name.".jpg' style='border: 1px solid #000;' width='160' >";
    }
}

The random string/number generator functions are static, so that they can be used anytime.

The string to be shown is stored in the class member value, this is to be set manually using setValue( $value ).

Function showImage renders and shows the image. It uses the 3 base colors Red Green and Blue ( $channel ) to generate the background color. This can be set as a parameter so images get only green ( $channel = 2 ) background, this my be important to exclude variations that are hard to read.

The logic is the following:

In the action you use to render the template where the CAPCTHA is to be shown, generate a value for it ( you can use the createString or createNumber functions ). Flash this value in the action ( $this->setFlash( 'captcha', $this->value ), and "pass" it to the template ( set the value as a member of the action $this->value = $value ).

In the template create an instance of class Captcha. Set the value by using the setValue function. And call showImage().

Create an input field on the template, and override the validate() function in your action.class.php. The logic is simple we have two strings and we want to know if they match or not. So we make an insatnce of confirm validaor, set the check parameter to the original captcha value ( $this->getFlash( 'captcha' ) ) and execute the validator on the input field's post value ( $this->getRequestParameter('name_of_input_field' ) ).

Many of the parameters that are actually fixed in the code should be members of the class and should have proper set/get functions. I've played with this for a short period of time, so feel free to complement the code.

by Kormany Gabor on 2007-06-30, tagged captcha  validation