jump to navigation

Embed Helper for flash & applets May 27, 2006

Posted by rossoft in CakePHP.
7 comments

For inserting flash and Java tags. Examples:

<?=$embed->flash(“http://www.loksalga.net/phpros/plantillas/loksalga/images/logo.swf&#8221;,709,129,false)?>
<?=$embed->applet(“Circle.class”,”http://www.cs.mu.oz.au/371/java/&#8221;,320,240,array(‘sleeptime’=>100))?>

<?php
/**
 * Embed Helper
 * Create <OBJECT> and <EMBED> tags for Flash & Java Applets
 * 
 * @author RosSoft
 * @version 0.1
 * @license MIT 
 */

class EmbedHelper extends Helper
{    

    /**
     * Returns an HTML <object> tag for Flash Movies
     * @param string $url Url to movie
     * @param integer $width Width in pixels
     * @param integer $height Height in pixels
     * @param string $bgcolor Background color in hex like #000000. If null, then the background will be transparent
     * @param boolean $menu Enable flash menu on right click
     * @return string
     */
    function flash($url,$width,$height,$bgcolor=false,$menu=false)
    {
        ob_start();
        ?>
        <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
        width="<?=$width?>" height="<?=$height?>"
        codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab">
            <param name="movie" value="<?=$url?>" />
            <param name="quality" value="high" />
            
            <?php
            if ($bgcolor !== false && $bgcolor !== null)
            {
            ?><param name="bgcolor" value="<?=$bgcolor?>" /><?php
            }
            else
            {
            ?><param name="wmode" value="transparent" /><?php
            }
            ?>
            
            <?php
            $flash_menu=($menu) ? $flash_menu="true" : $flash_menu="false";
            ?>
            <param name="menu" value="<?=$flash_menu?>" />
            
            
            <embed src="<?=$url?>" quality="high"
            <?php
            if ($bgcolor !== false && $bgcolor !== null)
            {
            ?>bgcolor="<?=$bgcolor?>"<?php
            }
            else
            {
            ?>wmode="transparent"<?php
            }
            ?> 
                width="<?=$width?>" height="<?=$height?>" 
                name="detectiontest" aligh="middle"
                play="true" loop="false" quality="high"
                menu="<?=$flash_menu?>"
                allowScriptAccess="sameDomain"
                type="application/x-shockwave-flash"
                pluginspage="http://www.macromedia.com/go/getflashplayer">
            </embed>
        </object>
        <?php
        return ob_get_clean();        
    }
    

    /**
     * Returns an HTML <applet> tag for Java Applets
     * @param string $code Applet Code Class
     * @param string $archive Archive of the applet
     * @param integer $width Width in pixels
     * @param integer $height Height in pixels
     * @param array $params Hash array of parameters (name=>value) 
     * @return string
     */
    
    function applet($code,$archive, $width,$height,$params=array())
    {
        ob_start();
        ?>
        <applet code="<?=$code?>" archive="<?=$archive?>"
          width="<?=$width?>" height="<?=$height?>"> 
          <?php
          foreach ($params as $n=>$v)
          {
              echo "<param name=\"$n\" value=\"$v\" />";                      
          }
        ?>
        </applet>
        <?php
        return ob_get_clean();
    }
}
/*
 * TODO: Call in (window.load):
theObjects = document.getElementsByTagName("object");
for (var i = 0; i < theObjects.length; i++) {
theObjects[i].outerHTML = theObjects[i].outerHTML;
}
*/

 
?>
Advertisements

Cookie Component May 22, 2006

Posted by rossoft in CakePHP.
11 comments

For easy working with cookies. It has encryption support through SimpleEncryption class

Installation:
1) Install the simpleEncryption
2) Copy the component to /app/controllers/components
3) Edit the component and change the $crypt_key to random text.

Usage: include the component in your controller. var $components=array(‘xxxx’,’cookie’);
——-
$value=array($login,$password);
$this->cookie->write(‘login’,$value,’+5 day’);
——-
$array=$this->cookie->read(‘login’);
——-
at logout()
$this->cookie->delete(‘login’);
——-

<?php

/**
* Cookie Component
* @author RosSoft
* @license MIT
* @version 0.13
*/

class CookieComponent extends Object
{
/**
* If not null, then the cookies will be encrypted
* with this key. Change to whatever you want.
*/
var $crypt_key=”CHANGE_THIS_TO_WHATEVER_YOU_WANT”;
var $crypt_engine=’Mcrypt’;

function startup(&$controller)
{
if ($this->crypt_key)
{
vendor(‘crypt’ . DS . ‘simple_crypt’);
$this->crypt=& new SimpleCrypt($this->crypt_engine);
}
}

/**
* Writes a cookie
* @param string $name Name of the cookie
* @param mixed $data Data to be written
* @param string $expires A valid strtotime string: when the data expires.
* @return boolean Success
*/
function write($name,$data=NULL,$expires=’+30 day’)
{
$data=serialize($data);
$time=strtotime($expires);

if ($this->crypt_key)
{
$data=$this->crypt->encrypt($this->crypt_key,$data);
}

if(setcookie($name,$data,$time,’/’))
{
return true;
}
else
{
$this->log(“CookieComponent: Write failed [$name][$data][$time]”);
return false;
}
}

/**
* Deletes a cookie
* @param string $name Name of the cookie
* @return boolean Success
*/
function delete($name)
{
if($this->write($name,”,’-999 day’))
{
return true;
}
else
{
$this->log(“CookieComponent: Delete failed [$name]”);
return false;
}
}

/**
* Reads a cookie
* @param string $name Name of the cookie
* @param boolean $unserialize Unserializes the content.
* Must be false if the cookie was not written through this component
*
* @return mixed Value of the cookie, or NULL if not exists
*/
function read($name,$unserialize=true)
{
if(isset($_COOKIE[$name]))
{
$string=$_COOKIE[$name];
if (get_magic_quotes_gpc())
{
$string=stripslashes($string);
}
if ($unserialize)
{
if ($this->crypt_key)
{
$string=$this->crypt->decrypt($this->crypt_key,$string);
}
$string=@unserialize($string);
return $string;
}
else
{
return $string;
}

}
else
{
return null;
}
}

/**
* Check if a cookie is set
* @param string $name Name of the cookie
* @return boolean The cookie exists
*/
function check($name)
{
return(isset($_COOKIE[$name]));
}

/**
* Removes all the cookies from the domain
* @author support at duggen dot net
*
* @link http://es.php.net/manual/en/function.setcookie.php#52081
*/
function clear()
{
$cookiesSet = array_keys($_COOKIE);
for ($x = 0; $x < count($cookiesSet); $x++)
{
if (is_array($_COOKIE[$cookiesSet[$x]]))
{
$cookiesSetA = array_keys($_COOKIE[$cookiesSet[$x]]);
for ($c = 0; $c < count($cookiesSetA); $c++)
{
$aCookie = $cookiesSet[$x].'[‘.$cookiesSetA[$c].’]’;
$this->delete($aCookie);
}
}
$this->delete($cookiesSet[$x]);
}
}
}

?>

Simple Encryption Class May 22, 2006

Posted by rossoft in CakePHP.
3 comments

A class for encryption of text (reversible encryption).

Usage:
vendor(‘crypt’ . DS . ‘simple_crypt’);
$this->SimpleCrypt=& new SimpleCrypt();
$encrypted=$this->SimpleCrypt->encrypt(‘a_key’,’the_text’);
$plain=$this->SimpleCrypt->decrypt(‘a_key’,$encrypted);

You can use a different engine if you don’t have Mcrypt:
$this->SimpleCrypt=& new SimpleCrypt(‘Simple’);

Copy to /vendors/crypt/simple_crypt.php
<?php
/**
 * SimpleCrypt Class
 * Simple encryption of strings
 *
 * Usage:
 * $this->SimpleCrypt=& new SimpleCrypt();
 * $encrypted=$this->SimpleCrypt->encrypt(‘a_key’,’the_text’);
 * $plain=$this->SimpleCrypt->decrypt(‘a_key’,$encrypted);
 *
 * The result is $plain equals to ‘the_text’
 *
 * You can use a different engine if you don’t have Mcrypt:
 * $this->SimpleCrypt=& new SimpleCrypt(‘Simple’);
 *
 * A string encrypted with one engine can’t be decrypted with
 * a different one even if the key is the same.
 *
 * @author RosSoft
 * @version 0.2
 * @license MIT
 */

class SimpleCrypt extends Object
{
    /**
     * Constructor
     * @param string $engine_name Engine for encryption. Values: Simple, Mcrypt
     */       
    function __construct($engine_name=’Mcrypt’)
    {
        $engine_name=’SimpleCrypt’ . $engine_name . ‘Engine’;
        $this->_engine=new $engine_name;
        parent::__construct();
    }
   
    /**
     * Encrypts the string with the given key
     * @param string $key
     * @param string $string Plaintext string
     * @return string Ciphered string
     */   
    function encrypt($key, $string)
    {
        return $this->_engine->encrypt($key,$string);       
    }
   

    /**
     * Decrypts the string by the given key
     * @param string $key
     * @param string $string Ciphered string
     * @return string Plaintext string 
     */
    function decrypt($key, $string)
    {
        return $this->_engine->decrypt($key,$string);
    }
}

/**
 * Simple Engine doesn’t need any PHP extension.
 * Every encryption of the same string with the same key
 * will return the same encrypted string
 */
class SimpleCryptSimpleEngine extends Object
{
    function encrypt($key, $string)
    {
        $result = ”;
        for($i=1; $i<=strlen($string); $i++)
        {
            $char = substr($string, $i-1, 1);
            $keychar = substr($key, ($i % strlen($key))-1, 1);
            $char = chr(ord($char)+ord($keychar));
            $result.=$char;
        }
        return $result;       
    }

    function decrypt($key, $string)
    {
        $result = ”;
        for($i=1; $i<=strlen($string); $i++)
        {
            $char = substr($string, $i-1, 1);
            $keychar = substr($key, ($i % strlen($key))-1, 1);
            $char = chr(ord($char)-ord($keychar));
            $result.=$char;
        }
        return $result;
    }       
}

/**
 * McryptEngine requires Mcrypt extension
 * Every encryption of the same string with the same key
 * will return a different encrypted string.
 */
class SimpleCryptMcryptEngine extends Object
{
    var $alg=MCRYPT_BLOWFISH;

    function encrypt($key, $string)
    {
        $td = mcrypt_module_open ($this->alg, ”, ‘ecb’, ”);
        $iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td),MCRYPT_DEV_RANDOM);       
        $encrypted_data = mcrypt_ecb($this->alg, $key,$string,MCRYPT_ENCRYPT,$iv);
        return $iv . $encrypted_data;
    }

    function decrypt($key, $string)
    {
        $td = mcrypt_module_open ($this->alg, ”, ‘ecb’, ”);
        $iv = substr($string,0,mcrypt_enc_get_iv_size($td));
        $string=substr($string,mcrypt_enc_get_iv_size($td));       
        return mcrypt_ecb($this->alg, $key,$string,MCRYPT_DECRYPT,$iv);
    }
}
?>

Cajax Component in CakeForge May 11, 2006

Posted by rossoft in CakePHP.
7 comments

Now it’s packaged in http://cakeforge.org/snippet/detail.php?type=package&id=13

Also all the files and an example can be found at
http://www.ros-soft.net/otros/cakephp_blog/cajax_test.tgz

Uncompress in the root dir of a new cake installation then go to the browser http://your_cake_location/cajax_test/

Strlen on UTF-8 Strings May 8, 2006

Posted by rossoft in CakePHP.
5 comments

If you want to know the length of a UTF-8 string, strlen doesn’t work. You must do a little trick for it:

function utf8_strlen($str)
{
     return strlen(utf8_decode($str));
}

Cajax Component v2 May 7, 2006

Posted by rossoft in CakePHP.
11 comments

First, some examples

<?php
echo $cajax->replace_html('div.mone','Changed by class.Hello world!<br/>Trying things');
echo $cajax->replace_html(array('#mas2','#otro'),'Changed by id');
echo $cajax->effect(array('#mas2','#otro'),'BlindDown',array('duration'=>1));
echo $cajax->effect('#hola','Highlight');
echo $cajax->effect('#mas2','Puff',array('duration'=>1));
//this will call the url "/pruebas/cajax_call" through ajax. it doesn't have the parameter array('update'=>'somediv'), then it will update a special hidden div created by cajax (useful if cajax_call only prints some javascript code like $cajax->replace_html(…)
echo $cajax->periodical_remote('/pruebas/cajax_call',2);
echo $cajax->toggle(array('#xxxx','.haa')); //two toggles for same element
echo $cajax->toggle('#xxxx');
echo $cajax->delay($cajax->toggle('#xxxx',false),10);

//Creation of proxy object
$mas3=$cajax->e(array('#mas3','#mas4'));
echo $mas3->effect('Fade',array('duration'=>2));

echo $cajax->delay(
//Passing proxy object to for_each
$cajax->for_each($mas3,'alert(_elem.innerHTML);',false)
,5);

echo $cajax->delay(
$cajax->e('.haa2')->effect('Appear',array(),false) //through proxy object
,8);

echo $cajax->delay(
$cajax->e('.haa2')->replace('<p>HI!</p>',false) //through proxy object
,15);

echo $mas3->for_each('_elem.innerHTML+="With for_each"');

 echo $cajax->e('#mas5')->replace_request_action('/sms/enviar');
 
 echo $cajax->e('#otro')->add_classname('x1');
        echo $cajax->e('#mas5')->replace_render_element('pruebas/cajax_test',array('var1'=>'testing'));
        echo $cajax->e('#otro')->remove_classname('x1');

?>

Installation.
1. You need OutputComponent, HeadHelper from this blog
2. dollar_e.js from http://ajaxian.com/archives/dollar-e-a-documentcreateelement-wrapper
3. Prototype >= 1.4.0
4. Copy the following to /app/controller/components/cajax.php

<?php
/**
 *
 * Cajax component
 * Some wrapper functions for prototype + scriptaculous
 * Requires Prototype >= 1.4.0
 *
 * @author      RosSoft
 * @version     0.21
 * @license         MIT
 *
 * @link http://api.rubyonrails.org/classes/ActionView/Helpers/PrototypeHelper/JavaScriptGenerator/GeneratorMethods.html
 * @link http://prototype.conio.net/
 * @link http://ajaxian.com/archives/dollar-e-a-documentcreateelement-wrapper
 *
 * In the API, a css selector can be a string or an array
 * of strings. The format of the string is a prototype css
 * selection.
 * Examples:
 * $css='.cl'   All the elements with class 'cl'
 * $css='#someid'   Element with id 'someid'
 * $css=array('#someid','.cl') All elements with class 'cl' union element with id 'someid'
 * $css='p.cl'  All the <p class="cl"> elements  
 */
 
     /**
      * The DOM ID of a hidden DIV that will
      * be created automatically. Useful when needed a div
      * for flushing javascript code on it.
      */
    define('CAJAX_CONTAINER','cajax_container');    
    class CajaxComponent extends Object
    {
        var $components=array    (
                                    'Output',
                                    'RequestHandler',
                                  );        
        var $helpers=    array    (    'Head',
                                    'Javascript',
                                    'Ajax',
                                );

        /**
         * If true, then all the calls will be attached to
         * an onload function
         */        
        var $enclose_onload=false;
       
        /**
         * Enable enclosing in <script> tags.
         * For enclosing, $enclose_enable and the parameter
         * $enclose of a call must be true both
         */
        var $enclose_enable=true;

       
        function startup(&$controller)
        {
               $this->controller =& $controller;
                          
            $this->_init_helpers();
            $this->Head->register_js('dollar_e');
           
            if (! $this->RequestHandler->isAjax())
            {    
                $this->Head->register_jsblock(                    
                    $this->on_load(
                            $this->new_element('document.body','div',CAJAX_CONTAINER,array(),false)
                            .
                            $this->e('#' . CAJAX_CONTAINER)->hide(false)
                            ,false)
                    );
            }                                    
            // For accessing the component from views (like helpers)
            $this->controller->set('cajax',$this);
        }
       
        /**
         * Creates instances of the helpers used
         */
        function _init_helpers()
        {
            $this->Output->startup($this->controller);
            foreach ($this->helpers as $h)
            {
                $this->{$h}=& $this->Output->returnHelper($h);        
            }
        }

        /**
         * Creates a new DOM element        
         * @param string $tag Type of tag (a,div,span…)
         * @param string $id DOM ID of the element
         * @param array $attr Attributes of the element
         * @param boolean $enclose Enclose the result in <SCRIPT> tags
         * @return string Javscript code
         */
        function new_element($parent,$tag,$id,$attr=array(),$enclose=true)
        {
            $element=array_merge(array('tag'=>$tag,'id'=>$id),$attr);
            $element=$this->Javascript->object($element);
            $js=$parent . '.appendChild($E(' . $element. '));';            
            return $this->_enclose($js,$enclose);
        }

        /**
         * Enclose or not the javascript code
         * @param string $jscode Javascript to be [not] enclosed
         * @param boolean $enclose
         * @return string
         */        
        function _enclose($jscode,$enclose)
        {
            if ($this->enclose_enable && $enclose)
            {
                if ($this->enclose_onload)
                {
                    $jscode=$this->on_load($jscode,false);
                }
                return $this->Javascript->codeBlock($jscode) . "\n";
            }
            else
            {
                return $jscode . "\n"; 
            }
        }
       
        /**
         * Replaces the inner HTML code of some objects
         * @param mixed $css CSS selector of the objects
         * @param string $content The content to be set
         * @param boolean $enclose
         * @return string
         */        
        function replace_html($css,$content,$enclose=true)
        {            
            $js= 'Element.update(_elem,unescape("' . $this->_js_string($content) . '"));';                        
            return $this->for_each($css,$js,$enclose);
           
        }
       
        /**
         * Replaces the inner HTML code of some objects with an element
         * @param mixed $css CSS selector of the objects
         * @param string $element The name of the element
         * @param string $params The params of the element
         * @param boolean $enclose
         * @return string
         */        
        function replace_render_element($css,$element,$params=array(),$enclose=true)
        {
            $content=$this->Output->returnElement($element,$params);
            return $this->replace_html($css,$content,$enclose);            
        }

        /**
         * Replaces the inner HTML code of some objects with a requestAction
         * @param mixed $css CSS selector of the objects
         * @param string $url RequestAction url
         * @param string $params Extra params to RequestAction
         * @param boolean $enclose
         * @return string
         *        
         */        
        function replace_request_action($css,$url,$params=array(),$enclose=true)
        {
            $params['return']=true;
            $content=$this->requestAction($url,$params);
            return $this->replace_html($css,$content,$enclose);        
        }        
       
        /**
         * Replaces the outer HTML code of some objects (replaces the entire object)
         * @param mixed $css CSS selector of the objects
         * @param string $content HTML tag and content to be set        
         * @param boolean $enclose
         * @return string
         */        
        function replace($css,$content,$enclose=true)
        {            
            $js= 'Element.replace(_elem,unescape("' . $this->_js_string($content) . '"));';            
            return $this->for_each($css,$js,$enclose);
        }
       

        /**
         * Returns a reference to javascripts elements
         * @param mixed $css CSS selector / array of selectors
         * @return string Javascript reference
         */        
        function _ref($css)
        {
            if (is_object($css) && strcasecmp(get_class($css),'CajaxProxy')==0)
            {
                /* The parameter is an instance of a cajax proxy
                    get real css selector from it */
                return $css->ref();
            }
            else
            {
                $js="$$('";
                if (is_array($css))
                {
                    $js.=implode("','",$css);
                }
                else
                {
                    $js.=$css;
                }
                $js.="')";        
                return $js;
            }
        }
       
        /**
         * Returns an javascript proxy object to the css selection
         * @param string $css CSS selection
         * @return object Proxy to the object
         */        
        function e($css)
        {
            return new CajaxProxy($this,$css); 
        }
       
        /**
         * Executes the effect to some elements that matches css selection
         * @param mixed $css CSS selection
         * @param string $effect The scriptaculous effect (Fade,Appear,…)   
         * @param boolean $enclose
         * @return string
         *
         * @link http://wiki.script.aculo.us/scriptaculous/show/CombinationEffectsDemo
         */                
        function effect($css,$effect,$params=array(),$enclose=true)
        {            
            $params=$this->Javascript->object($params);
            return $this->for_each($css,"new Effect.$effect(_elem,$params)",$enclose);        
        }

        /**
         * Executes the jscode for each element that matches
         * the css selection. The jscode is executed for each
         * element, the element is referenced by the variable '_elem'
         * @param mixed $css CSS selection
         * @param string $jscode The javascript code using _elem variable 
         * @param boolean $enclose
         * @return string
         */                
        function for_each($css,$jscode,$enclose=true)
        {
            $ref=$this->_ref($css);
            $js="$ref.each(function(_elem) { $jscode });";
            return $this->_enclose($js,$enclose);                        
        }
       
        /**
         * Safe javascript string.
         * Must be decoded with the js function 'unescape'
         * @param string PHP String
         * @return string Javascript-safe string.
         */
        function _js_string($string)
        {
            return rawurlencode(utf8_decode($string));            
        }

        /**
         * Attach an event to an element.
         *
         * @param mixed $css CSS selector to the element to be observed
         * @param string $event event to observe
         * @param string $jscode function to call
         * @param boolean $enclose
         * @return string
         */        
        function event($css, $event, $jscode,$enclose=true)
        {
            $js_event= "Event.observe(_elem, \"$event\", function(event){ $jscode }, false);";
            return $this->for_each($css,$js_event,$enclose);            
        }
       
        /**
         * Attaches an onload function
         * @param string $jscode Javascript code to be executed
         * @paran boolean $enclose
         * @return string
         */
        function on_load($jscode,$enclose=true)
        {
            //Not works with $this->event (I don't know a css selector for window)
            $js= "Event.observe(window, \"load\", function(){ $jscode }, false);";
            return $this->_enclose($js,$enclose);
        }    

        /**
         * Hides an element or an array of elements by css selector
         * @param mixed $css CSS selector
         * @return string
         */
        function hide($css,$enclose=true)
        {
            return $this->for_each($css,"Element.hide(_elem)",$enclose);
        }
       
        /**
         * Shows an element or an array of elements by css selector
         * @param mixed $css CSS Selector
         * @param boolean $enclose
         * @return string
         */
        function show($css,$enclose=true)
        {
            return $this->for_each($css,"Element.show(_elem)",$enclose);
        }
       
        /**
         * Removes an element or an array of elements by css selector
         * @param mixed $css Selector
         * @param boolean $enclose
         * @return string
         */
        function remove($css,$enclose=true)
        {
            return $this->for_each($css,"Element.remove(_elem)",$enclose);
        }            

        /**
         * Toggles the visibility of an element or an array of elements
         * @param mixed $id DOM ID of the object (or array of ids)
         * @param boolean $enclose
         * @return string
         */
        function toggle($css,$enclose=true)
        {
            return $this->for_each($css,"Element.toggle(_elem)",$enclose);        
        }
       
        /**
         * Javascript redirection to the given location
         * @param string $url
         * @param boolean $enclose
         * @return string
         */
        function redirect_to($url,$enclose=true)
        {
            $js="window.location.href='$url'";
            return $this->_enclose($url,$enclose);                    
        }
        /**
         * Periodically calls some javascript code
         * @param string $jscode Javascript to be called
         * @param integer $freq Seconds
         * @return string
         */        
        function periodical($jscode,$freq=10,$enclose=true)
        {            
            $js="new PeriodicalExecuter(function() { $jscode }, $freq)";
            return $this->_enclose($js,$enclose);            
        }
       
        /**
         * Periodically calls a remote url (useful for updating a div)
         * @param string $url Cakeway /controller/action
         * @param integer $freq Frequency in seconds
         * @param array $options @see AjaxHelper
         * @param boolean $enclose
         * @return string 
         */
        function periodical_remote($url,$freq=10,$options=array(),$enclose=true)
        {
            $options['url']=$url;
            if (!isset($options['update']))
            {
                $options['update']=CAJAX_CONTAINER;
            }            
            $js=$this->remote_function($options,false);
            return $this->periodical($js,$freq,$enclose);
        }
       
        /**
         * Calls a remote ajax function
         * @param array $options @see AjaxHelper
         * @param boolean $enclose
         * @retur string
         */        
        function remote_function($options=array(),$enclose=true)
        {
            $js=$this->Ajax->remoteFunction($options);
            return $this->_enclose($js,$enclose);
        }

        /**
         * Executes the jscode after the delay
         * @param string $jscode Javascript to be executed
         * @param integer $delay Delay time in seconds
         * @param boolean $enclose
         * @return string
         *
         */        
        function delay($jscode,$delay,$enclose=true)
        {
            $js="setTimeout(function() {\n$jscode\n}," . ($delay * 1000) . ');';
            return $this->_enclose($js,$enclose);
        }

        /**
         * Converts an array of args to a js-array of args
         * @param array $args
         * @return string
         */        
        function _call_args($args)
        {
            $arr=array();
            foreach ($args as $i)
            {
                $arr[]=$this->_object($i);    
            }            
            return implode(",",$arr);
        }           

        /**
         * Calls a js function with the given array of params
         * @param string $function Name of the function
         * @param array $args Array of params
         * @param boolean $enclose
         * @return string
         */        
        function call($function,$args,$enclose=true)
        {
            $js="$function(" . $this->_call_args($args). ")";
            return $this->_enclose($js,$enclose);
        }
       
        /**
         * Shows an alert box
         * @param string $message Message to be shown
         * @param boolean $enclose
         * @return string
         */        
        function alert($message,$enclose=true)
        {            
            return $this->call('alert',array($message),$enclose);
        }

        /**        
         * Returns a the js-string of a php variable
         * @param mixed $var
         * @return string
         */
        function _object($var)
        {
            if (is_object($var) && get_class($var)=='CajaxProxy')
            {
                return $var->js_object();
            }                     
            else if (is_array($var))
            {
                return $this->Javascript->object($var);
            }
            else
            {
                $var=$this->_js_string($var);
                return "'$var'";
            }            
        }        
       
        /**
         * Assigns a value to a js variable
         * @param string $variable name of the variable
         * @param string $value
         * @param boolean $enclose
         * @return string
         */
        function assign($variable,$value,$enclose=true)
        {
            $js="$variable=" . $this->_object($value);
            return $this->_enclose($js);
        }
       
        /**
         * Adds a CSS class to an element or an array of elements by css selector
         * @param string $css Selector
         * @param string $classname Class to be added
         * @param boolean $enclose
         * @return string
         * 
         */        
        function add_classname($css,$classname,$enclose=true)
        {
            return $this->for_each($css,"Element.addClassName(_elem,'$classname');",$enclose);
        }

        /**
         * Removes a CSS class to an element or an array of elements by css selector
         * @param string $css Selector
         * @param string $classname Class to be removed
         * @param boolean $enclose
         * @return string
         * 
         */        
        function remove_classname($css,$classname,$enclose=true)
        {
            return $this->for_each($css,"Element.removeClassName(_elem,'$classname');",$enclose);
        }                
       
                   
    }    
    
    ////////////////////////////////////////////////////////////
    /**
     * After creating an instance of it through
     * $obj=$cajax->e(css_selection),
     * you can call $obj->hide(), $obj->effect('Appear') ,etc.
     */        
    
    class CajaxProxy extends Object
    {
        /** css selector */
        var $_css;
       
        /**        
         * Reference to the Cajax instance
         */
        var $Cajax;        
        function ref()
        {
            return $this->Cajax->_ref($this->_css);
        }
       
        function add_classname($classname,$enclose=true)
        {
            return $this->Cajax->add_classname($this->_css,$classname,$enclose);
        }
       
        function remove_classname($classname,$enclose=true)
        {
            return $this->Cajax->remove_classname($this->_css,$classname,$enclose);
        }    

        /**
         * Constructor
         * @param object $Cajax Instance of CajaxComponent
         * @param string $css CSS Selector
         */        
        function __construct(&$Cajax,$css)
        {
            $this->Cajax =& $Cajax;
            $this->_css=$css;
        }    
       
        /**
         * Shows the object(s)
         * @param boolean $enclose
         *
         */
        function show($enclose=true)
        {            
            return $this->Cajax->show($this->_css,$enclose);
        }
       
        /**
         * Toggles the object(s)
         * @param boolean $enclose
         *
         */
        function toggle($enclose=true)
        {            
            return $this->Cajax->toggle($this->_css,$enclose);
        }    
           

        /**
         * Hides the object(s)
         * @param boolean $enclose
         *
         */
        function hide($enclose=true)
        {            
            return $this->Cajax->hide($this->_css,$enclose);
        }
       
       
        /**
         * Removes the object(s)
         * @param boolean $enclose
         *
         */
        function remove($enclose=true)
        {            
            return $this->Cajax->remove($this->_css,$enclose);
        }            

        /**        
         * Does an scriptaculous effect
         * @param string $effect Name of effect
         * @param array $params Array of parameters to the effect
         * @param boolean $enclose
         * @link http://wiki.script.aculo.us/scriptaculous/show/CombinationEffectsDemo
         */
        function effect($effect,$params=array(),$enclose=true)
        {
            return $this->Cajax->effect($this->_css,$effect,$params,$enclose);
        }
       
        /**
         * Replaces the HTML code
         * @param string $content The content to be set
         * @param boolean $enclose
         * @return string
         */

        function replace_html($content,$enclose=true)
        {
            return $this->Cajax->replace_html($this->_css,$content,$enclose);
        }
       
        /**
         * Attach an event to an element.
         *
         * @param string $event event to observe
         * @param string $jscode function to call
         * @param boolean $enclose
         * @return string
         */        
        function event($event, $jscode,$enclose=true)
        {
            return $this->Cajax->event($this->_css,$event,$jscode,$enclose);
        }

        /**
         * Executes the jscode for each element that matches
         * the css selection. The jscode is executed for each
         * element, the element is referenced by the variable '_elem'
         * @param string $jscode The javascript code using _elem variable 
         * @param boolean $enclose
         * @return string
         */                
        function for_each($jscode,$enclose=true)
        {
            return $this->Cajax->for_each($this->_css,$jscode,$enclose);            
        }
       
        /**
         * Replaces the outer HTML code of the objects (replaces the entire object)
         * @param string $content HTML tag and content to be set
         * @param boolean $enclose
         * @return string
         */        
        function replace($content,$enclose=true)
        {
            return $this->Cajax->replace($this->_css,$content,$enclose);
        }
       
        /**
         * Replaces the inner HTML code of some objects with an element
         * @param string $element The name of the element
         * @param string $params The params of the element
         * @param boolean $enclose
         * @return string
         */        
        function replace_render_element($element,$params=array(),$enclose=true)
        {
            return $this->Cajax->replace_render_element($this->_css,$element,$params,$enclose);
        }

        /**
         * Replaces the inner HTML code of some objects with a requestAction
         * @param string $url RequestAction url
         * @param string $params Extra params to RequestAction
         * @param boolean $enclose
         * @return string
         *        
         */        
        function replace_request_action($url,$params=array(),$enclose=true)
        {
            return $this->Cajax->replace_request_action($this->_css,$url,$params,$enclose);
        }        
                       
    }        
?>

Javascript easy: Cajax Component (alpha version) May 6, 2006

Posted by rossoft in CakePHP.
add a comment

Useful for  AJAX –  Scriptaculous effects
I want to replicate RJS but it lacks the great javascript object proxy and some other things

<div id=”hola”>
</div>

<div id=”otro”>
    <table border=”1″>
        <tr><td>hola</td></tr>
        <tr><td>hola2</td></tr>
        <tr><td>hola</td></tr>
        <tr><td>hola2</td></tr>       
    </table>
</div>

<div id=”mas”>
    <table border=”2″>
        <tr><td>asdfasdfasdsad</td></tr>
        <tr><td>sdfsafs</td></tr>
        <tr><td>asdfasdfasdsad</td></tr>
        <tr><td>sdfsafs</td></tr>       
    </table>
</div>

<div id=”mas2″>
    <table border=”2″>
        <tr><td>xxxxx</td></tr>
        <tr><td>yyyyyy</td></tr>
        <tr><td>zzzz</td></tr>
       
    </table>
</div>

<?= $cajax->replace_html(‘hola’,’que pasa<br />nennng!’)?>
<?= $cajax->visual_effect(‘otro’,’BlindUp’,array(‘duration’=>1));?>
<?= $cajax->visual_effect(‘mas’,’Puff’,array(‘duration’=>1));?>
<?= $cajax->toggle(array(‘mas2′,’mas2’));?>
<?= $cajax->toggle(‘mas2’);?>
<?= $cajax->show(‘mas2’);?>
<?= $cajax->periodical_remote(‘/pruebas/cajax_call’,array(‘update’=>’hola’),5)?>
<?= $cajax->delay($cajax->alert(‘Hi!!’,false),10)?>

<?php
/**
 *
 * Cajax component
 * Some wrapper functions for prototype + scriptaculous
 *
 *
 * @author      RosSoft
 * @version     0.1
 * @license         MIT
 *
 * @link http://api.rubyonrails.org/classes/ActionView/Helpers/PrototypeHelper/JavaScriptGenerator/GeneratorMethods.html
 *
 */
    //define(‘CAJAX_DOMID’,’cajax_container’);    
    class CajaxComponent extends Object
    {
        var $components=array(‘Output’,’RequestHandler’);        
        var $helpers=array(‘Head’,’Javascript’,’Ajax’);

        /**
         * If true, then all the calls will be attached to
         * an onload function
         */        
        var $enclose_onload=true;

        /**
         * Array of javascript variable names
         */        
//        var $_js_objects;
        
        function startup(&$controller)
        {
/*            static $js_objects=array();  //for php4 compat
            $this->_js_objects=& $js_objects;
*/
             
               $this->controller =& $controller;
                           
            $this->_init_helpers();
            $this->Head->register_js(‘dollar_e’);
            
            /*if (! $this->RequestHandler->isAjax())
            {
                $this->Head->register_raw(                    
                    $this->on_load(
                            $this->new_element(‘document.body’,’div’,CAJAX_DOMID,array(),false))
                    );
            $this->Head->register_raw(
                    $this->on_load(
                        $this->replace_html(CAJAX_DOMID,’Hola que tal e
                                
                                stás!’,false))
                    );                                
            }*/        
            
            $this->controller->set(‘cajax’,$this);
        }
        
        /**
         * Creates instances of the helpers used
         */
        function _init_helpers()
        {
            $this->Output->startup($this->controller);
            foreach ($this->helpers as $h)
            {
                $this->{$h}=& $this->Output->returnHelper($h);        
            }
        }

        /**
         * Creates a new DOM element        
         * @param string $tag Type of tag (a,div,span…)
         * @param string $id DOM ID of the element
         * @param array $attr Attributes of the element
         * @param boolean $enclose Enclose the result in <SCRIPT> tags
         * @return string Javscript code
         */
        function new_element($parent,$tag,$id,$attr=array(),$enclose=true)
        {
            $element=array_merge(array(‘tag’=>$tag,’id’=>$id),$attr);
            $element=$this->Javascript->object($element);
            $js=$parent . ‘.appendChild($E(‘ . $element. ‘));’;            
            return $this->_enclose($js,$enclose);
        }

        /**
         * Enclose or not the javascript code
         * @param string $jscode Javascript to be [not] enclosed
         * @param boolean $enclose
         * @return string
         */        
        function _enclose($jscode,$enclose)
        {
            //return ($enclose) ? $this->Javascript->codeBlock($jscode) : $jscode;
            if ($enclose)
            {
                if ($this->enclose_onload)
                {
                    $jscode=$this->on_load($jscode,false);
                }
                return $this->Javascript->codeBlock($jscode);
            }
            else
            {
                return $jscode;
            }
        }            
        
        function replace_html($id,$content,$enclose=true)
        {
            $js=’$(“‘ . $id. ‘”).innerHTML=”‘ . $this->_multiline($content) . ‘”‘;
            return $this->_enclose($js,$enclose);
        }

        /**
         * Returns a reference to a javascript element
         * @param string $id DOM id
         * @return string Javascript reference
         */        
        function element($id)
        {
            return ‘$(“‘ . $id . ‘”)’;
        }
        
        function visual_effect($id,$effect,$params=array(),$enclose=true)
        {
            $elem=$this->element($id);
            $params=$this->Javascript->object($params);        
            $js=”Effect.$effect($elem, $params);”;
            return $this->_enclose($js,$enclose);
        }
        
        /**
         * Safe replacement of string with carriage-returns
         * to \n literal
         * @param string
         * @return string
         */
        function _multiline($string)
        {
            return str_replace(“\n”,’\n’,$string);
        }

        /**
         * Attach an event to an element.
         *
         * @param string $id Object to be observed
         * @param string $event event to observe
         * @param string $jscode function to call
         * @param boolean $enclose
         * @return string
         */        
        function event($id, $event, $jscode,$enclose=true)
        {
            $js = “Event.observe($id, ‘$event’, function(event){ $jscode }, false);”;
            return $this->_enclose($js,$enclose);
        }
        
        /**
         * Attaches an onload function
         * @param string $jscode Javascript code to be executed
         * @paran boolean $enclose
         * @return string
         */
        function on_load($jscode,$enclose=true)
        {
            return $this->event(‘window’,’load’,$jscode,$enclose);
        }    

        /**
         * Hides an element or an array of elements
         * @param mixed $id DOM ID of the object (or array of ids)
         * @return string
         */
        function hide($id,$enclose=true)
        {
            if (is_array($id))
            {
                $js=”;                
                foreach ($id as $i)
                {
                    $js.=”Element.hide(‘$i’);”;                
                }
            }
            else
            {
                $js=”Element.hide(‘$id’);”;
            }            
            return $this->_enclose($js,$enclose);
        }            
        
        /**
         * Shows an element or an array of elements
         * @param mixed $id DOM ID of the object (or array of ids)
         * @param boolean $enclose
         * @return string
         */
        function show($id,$enclose=true)
        {
            if (is_array($id))
            {
                $js=”;                
                foreach ($id as $i)
                {
                    $js.=”Element.show(‘$i’);”;                
                }
            }
            else
            {
                $js=”Element.show(‘$id’);”;
            }            
            return $this->_enclose($js,$enclose);
        }            
        
        /**
         * Removes an element or an array of elements
         * @param mixed $id DOM ID of the object (or array of ids)
         * @param boolean $enclose
         * @return string
         */
        function remove($id,$enclose=true)
        {
            if (is_array($id))
            {
                $js=”;                
                foreach ($id as $i)
                {
                    $js.=”Element.remove(‘$i’);”;                
                }
            }
            else
            {
                $js=”Element.remove(‘$id’);”;
            }            
            return $this->_enclose($js,$enclose);
        }            

        /**
         * Toggles the visibility of an element or an array of elements
         * @param mixed $id DOM ID of the object (or array of ids)
         * @param boolean $enclose
         * @return string
         */
        function toggle($id,$enclose=true)
        {
            if (is_array($id))
            {
                $js=”;                
                foreach ($id as $i)
                {
                    $js.=”Element.toggle(‘$i’);”;                
                }
            }
            else
            {
                $js=”Element.toggle(‘$id’);”;
            }            
            return $this->_enclose($js,$enclose);
        }    
        
        /**
         * Javascript redirection to the given location
         * @param string $url
         * @param boolean $enclose
         * @return string
         */
        function redirect_to($url,$enclose=true)
        {
            $js=”window.location.href=’$url'”;
            return $this->_enclose($url,$enclose);                    
        }

        /**
         * Periodically calls some javascript code
         * @param string $jscode Javascript to be called
         * @param integer $freq Seconds
         * @return string
         */        
        function periodical($jscode,$freq=10,$enclose=true)
        {            
            $js=”new PeriodicalExecuter(function() { $jscode }, $freq)”;
            return $this->_enclose($js,$enclose);            
        }
        
        /**
         * Periodically calls a remote url (useful for updating a div)
         * @param string $url Cakeway /controller/action
         * @param array $options @see AjaxHelper
         * @param integer $freq Seconds of refresh
         * @param boolean $enclose
         * @return string  
         */
        function periodical_remote($url,$options=array(),$freq=10,$enclose=true)
        {
            $options[‘url’]=$url;
            $js=$this->remote_function($options,false);
            return $this->periodical($js,$freq,$enclose);
        }
        
        /**
         * Calls a remote ajax function
         * @param array $options @see AjaxHelper
         * @param boolean $enclose
         * @retur string
         */        
        function remote_function($options=array(),$enclose=true)
        {
            $js=$this->Ajax->remoteFunction($options);
            return $this->_enclose($js,$enclose);
        }

        /**
         * Executes the jscode after the delay
         * @param string $jscode Javascript to be executed
         * @param integer $delay Delay time in seconds
         * @param boolean $enclose
         * @return string
         *
         */        
        function delay($jscode,$delay,$enclose=true)
        {
            $js=”setTimeout(function() {\n$jscode\n},” . ($delay * 1000) . ‘);’;
            return $this->_enclose($js,$enclose);
        }

        /**
         * Converts an array of args to a js-array of args
         * @param array $args
         * @return string
         */        
        function _call_args($args)
        {
            return “‘” . implode(“‘,'”,$args) . “‘”;
        }            

        /**
         * Calls a js function with the given array of params
         * @param string $function Name of the function
         * @param array $args Array of params
         * @param boolean $enclose
         * @return string
         */        
        function call($function,$args,$enclose=true)
        {
            $js=”$function(” . $this->_call_args($args). “)”;
            return $this->_enclose($js,$enclose);
        }
        
        /**
         * Shows an alert box
         * @param string $message Message to be shown
         * @param boolean $enclose
         * @return string
         */        
        function alert($message,$enclose=true)
        {            
            return $this->call(‘alert’,array($this->_object($message)),$enclose);
        }

        /**        
         * Returns a the js-string of a php variable
         * @param mixed $var
         * @return string
         */
        function _object($var)
        {
            if (is_array($var))
            {
                return $this->Javascript->Object($var);
            }
            else
            {
                $var=$this->_multiline($var);
                return “‘$var'”;
            }            
        }        
        
        /**
         * Assigns a value to a js variable
         * @param string $variable name of the variable
         * @param string $value
         * @param boolean $enclose
         * @return string
         */
        function assign($variable,$value,$enclose=true)
        {
            $js=”$variable=” . $this->_object($value);
            return $this->_enclose($js);
        }                
    }        
?>

combobox helper (Editable Selectbox) May 4, 2006

Posted by rossoft in CakePHP.
6 comments

Usage:
Include the helper var $helpers=array('xxxx','combobox');

$telephones=array('959955'=>'Mark', '323223'=>'Steve');

echo $combobox->combobox('User/telephone',$telephones);

Then a combobox will be shown, if you select Mark or Steve, then in the input box the telephone value will appear. The user can select the telephone from the selectbox or enter one manually (this field is an integer)

Other example is that after selecting Mark, the value 'Mark' will be at the input field ( this field is a string )

$names=array('Mark'=>'Mark', 'Steve'=>'Steve');

echo $combobox->combobox('User/name',$names);

1. Copy this to /webroot/js/combobox/
2. Copy the helpers HeadHelper, UtilHelper from this blog to helpers/ (search the blog)
3. Copy that code to helpers/combobox.php

<?
/**
 * Combobox Helper
 * Creates an editable select tag
 * @author RosSoft
 * @version 0.1
 * @link http://www.metabuilders.com/Tools/ComboBox.aspx
 */
class ComboboxHelper extends Helper
{
    var $helpers=array('Head','Javascript','Util');

    /**
     * Creates the combobox
     * @param string $fieldName Name of the field in cake form (Model/field)
     * @param array $optionsElements Hash array with option key->value to be displayed
     * @param string $value The initial value to be shown. If null, then it will be fetched from data array
     * @param array $htmlOptions Html options to be appended to the textbox
     */    
    function combobox($fieldName,$optionElements,$value=null,$htmlOptions=null)
    {        
        $id=str_replace('/','_',$fieldName);
        
        if ($value===null)
        {
            $value=$this->Util->retrieve_value($fieldName);
            if ($value===null) $value='';
        }
        $fieldName=$this->Util->translate_fieldname($fieldName);        
        
        $htmlOptions=$this->Util->parse_attributes($htmlOptions);

        $this->Head->register_js('combobox/combobox');        
        $this->Head->register_jsblock("var ComboBoxes= new Array();");
        $this->Head->register_jsblock("ComboBoxes.push('$id');");
        $this->Head->register_jsblock("Event.observe(window, 'load', ComboBox_Init, false);");
        ob_start();
        ?>
        <span id="<?=$id?>_container">
            <input name="<?=$fieldName?>" type="text"
              id="<?=$id?>" autocomplete="off" <?=$htmlOptions?> value="<?=$value?>" />
            
            <span id="<?=$id?>_button" />
        </span>
        
        <select name="<?=$id?>_select"
        onchange="ComboBox_SimpleAttach(this, this.form['<?=$id?>']);"
        listSize="4" id="<?=$id?>_select">
        <? foreach ($optionElements as $id=>$value):?>
            <option value="<?=$id?>"><?=$value?></option>
        <? endforeach; ?>
        </select>

        <? return ob_get_clean();
        }
}
?>

Helper with common utilities for helpers May 4, 2006

Posted by rossoft in CakePHP.
add a comment

While creating helpers, there’re some common functions that I’ve  packed in one helper

<?php
/**
 * Common utilities for helpers
 * @author RosSoft
 * @version 0.1
 */
class UtilHelper extends Helper
{       
    /**
     * Converts a string like Model/field to
     * the string data[Model][field]
     * @param string $fieldName Model/field
     * @return string
     */
    function translate_fieldname($fieldName)
    {   
        if (strpos($fieldName,’/’))
        {
            $arr=split(‘/’,$fieldName);
            $model=$arr[0];
            $field=$arr[1];
            return “data[$model][$field]”;
        }
        else
        {
            return $fieldName;
        }
    }           

    /**
     * Retrieves the value from data array of field passed
     * @param string $fieldName Model/field
     * @return string The value from the data array
     */   
    function retrieve_value($fieldName)
    {
        if (strpos($fieldName,’/’))
        {
            $arr=split(‘/’,$fieldName);
            $model=$arr[0];
            $field=$arr[1];
            if (isset($this->params[‘data’][$model][$field]))
            {
                return $this->params[‘data’][$model][$field];
            }
            else
            {
                return null;
            }
        }                   
    }
   
    /**
     * This is a copy of the same function in HtmlHelper
     * Returns a space-delimited string with items of the $options array. If a
     * key of $options array happens to be one of:
     *    + ‘compact’
     *    + ‘checked’
     *    + ‘declare’
     *    + ‘readonly’
     *    + ‘disabled’
     *    + ‘selected’
     *    + ‘defer’
     *    + ‘ismap’
     *    + ‘nohref’
     *    + ‘noshade’
     *    + ‘nowrap’
     *    + ‘multiple’
     *    + ‘noresize’
     *
     * And its value is one of:
     *    + 1
     *    + true
     *    + ‘true’
     *
     * Then the value will be reset to be identical with key’s name.
     * If the value is not one of these 3, the parameter is not output.
     *
     * @param  array  $options      Array of options.
     * @param  array  $exclude      Array of options to be excluded.
     * @param  string $insertBefore String to be inserted before options.
     * @param  string $insertAfter  String to be inserted ater options.
     * @return string
     */   
    function parse_attributes($options, $exclude = null, $insertBefore = ‘ ‘,
    $insertAfter = null)
    {
        $minimizedAttributes = array(
        ‘compact’,
        ‘checked’,
        ‘declare’,
        ‘readonly’,
        ‘disabled’,
        ‘selected’,
        ‘defer’,
        ‘ismap’,
        ‘nohref’,
        ‘noshade’,
        ‘nowrap’,
        ‘multiple’,
        ‘noresize’);

        if (!is_array($exclude))
        {
            $exclude = array();
        }

        if (is_array($options))
        {
            $out = array();

            foreach ($options as $key => $value)
            {
                if (!in_array($key, $exclude))
                {
                    if (in_array($key, $minimizedAttributes) && ($value === 1 ||
                    $value === true || $value === ‘true’ || in_array($value,
                    $minimizedAttributes)))
                    {
                        $value = $key;
                    }
                    elseif (in_array($key, $minimizedAttributes))
                    {
                        continue;
                    }
                    $out[] = “{$key}=\”{$value}\””;
                }
            }
            $out = join(‘ ‘, $out);
            return $out? $insertBefore.$out.$insertAfter: null;
        }
        else
        {
            return $options? $insertBefore.$options.$insertAfter: null;
        }
    }
   
           
}   
       
?>

Version 1.0 of CakePHP May 2, 2006

Posted by rossoft in CakePHP.
add a comment

Finally, the 1.0 version of CakePHP is available. Also the website has changed a lot, now it has a very cool design. Congratulations to all that have made this possible!