Recent Updates RSS Toggle Comment Threads | Keyboard Shortcuts

  • endyourif 9:00 am on April 24, 2012 Permalink | Log in to leave a Comment
    Tags:   

    AWS SES component for CakePHP2.0 + 

    We use Amazon services for our day today applications we use their SDK write normal code to required controllers, So we planned to create a component for AWS service.

    Amazon Simple Email Service (Amazon SES) is a very popular email SMTP service by Amazon. It has lots of advantages like,

    Easy to use
    Good documentation
    Good fault tolerance
    Easy to integrate with existing architecture
    Detailed reporting about email deliveries
    Highly scalable

    Once you go with AWS services, it is advised to use their services throughout your application. like EC2 for hosting your application, SES for sending email via authenticated trusted SMTP server. You can use AWS SES service alone also.

    So for using Amazon Simple Email Service (Amazon SES) service use following steps,
    1. You need an AWS account. http://aws.amazon.com/ 2. Login to the account go to the SES dashboard.
    3. Add email address to verify. Which can be used in From header of outgoing emails.
    4. After adding email, AWS sends an verification email to the email address. You need to verify this email address. Then it will appear in the verified email list.

    http://docs.amazonwebservices.com/ses/latest/DeveloperGuide/InitialSetup.EmailVerification.html

    By default in the 1st go AWS gives you a sandbox testing account. In this mode it will only send emails to from the verified email addresses only.

    For using SES with your application you need production access. So first up all request to activate the production mode. It will take one business day to activate. After this activation you can send emails through your application.

    Now there is a Verified email address section in the SES dashboard. These email addresses you can use in the From header of your outgoing email. If the email address is not verified you can not use that email address.

    Now the Implementation part comes in the picture with CakePHP app. It’s very easy to integrate SES with the application.

    Download the SDK (PHP) from AWS. http://aws.amazon.com/code
    Extract the sdk to your ‘app/Vendor’ directory.
    Rename it as ‘aws’ from ‘aws-sdk’
    Create a component file in the components directory. name : AWSSESComponent.php
    Copy paste the code to this file
    Add the line to Appcontroller :

    include_once(APP.DS.’Vendor’.DS.’aws/sdk.class.php’); or App::import(‘Vendor’, ‘aws/sdk.class’);

    Add ‘AWSSES’ in the public $components = array('AWSSES');
    Now you can use this in any controller. If you want to use this controller specific then in every controller you can add the component array.

    Currently this component only supports the HTML email formats, but we are going to improve this further.

    This is the inspiration from Swiftmailer component SES,

    ?php
    App::import(‘Vendor’, ‘aws/sdk.class.php’);
    App::import(‘Vendor’, ‘aws/services/ses.class.php’);

    class AWSSESComponent extends Object
    {

    public $ses;
    public $emailViewPath = '/Emails';
    public $emailLayouts = 'Emails';
    public $htmlMessage;
    public $from = 'from_email_address';
    public $to;
    
    public function initialize($controller)
    {
    
    }
    
    function startup($controller)
    {
       $this-controller = $controller;
    
       $this-ses = new AmazonSES(array('certificate_authority' = false,
           'key' = 'AWS_Key',
           'secret' = 'AWS_secrete'));
    
    }
    
    public function beforeRender()
    {
    }
    
    public function shutdown()
    {
    }
    
    public function beforeRedirect()
    {
    }
    
    public function _aws_ses($viewTemplate, $mailContent = null)
    {
           if(!empty($this-controller-request-data)  $mailContent == null){
           $mailContent = $this-controller-request-data[$this-controller-modelClass];
       }
    
       $mail = $this-email_templates($viewTemplate);
    
       $destination = array(
           'ToAddresses' = explode(',', $this-to)
       );
       $message = array(
           'Subject' = array(
               'Data' = $mail['Subject']
           ),
           'Body' = array()
       );
    
       $this-controller-set('data', $mailContent);
    
       $this-htmlMessage = $this-_getHTMLBodyFromEmailViews($mail['ctp']);
    
       if ($this-htmlMessage != NULL) {
           $message['Body']['Html'] = array(
               'Data' = $this-htmlMessage
           );
       }
    
       $response = $this-ses-send_email($this-from, $destination, $message);
    
       $ok = $response-isOK();
    
       if (!$ok) {
           $this-log('Error sending email from AWS SES: ' . $response-body-asXML(), 'debug');
       }
       return $ok;
    }
    
    public function email_templates($name)
    {
       $this-templates = array('email_name' = array(
           'ctp' = 'ctp_file_name', 'Subject' = 'email_subject'
       ),'email_name' = array('ctp' = 'reset_passwordctp_file_name 'Subject' = 'email_subject'));
    
       return $this-templates[$name];
    }
    
    public function _getHTMLBodyFromEmailViews($view)
    {
       $currentLayout = $this-controller-layout;
       $currentAction = $this-controller-action;
       $currentView = $this-controller-view;
       $currentOutput = $this-controller-output;
    
       ob_start();
       $this-controller-output = null;
    
       $viewPath = $this-emailViewPath . DS . 'html' . DS . $view;
       $layoutPath = $this-emailLayouts . DS . 'html' . DS . 'default';
    
       $bodyHtml = $this-controller-render($viewPath, $layoutPath);
    
       ob_end_clean();
    
       $this-controller-layout = $currentLayout;
       $this-controller-action = $currentAction;
       $this-controller-view = $currentView;
       $this-controller-output = $currentOutput;
    
       return $bodyHtml;
    }

    }

    So CakePHP 2.0 + uses an Email views to store all the email templates. You can change the location you can use your own too.

    Template views from View/Emails/html/email.ctp’ as defined in the component : $emailViewPath
    Layouts from your ‘View/Layouts/Emails/default.ctp’ as defined in the component : $emailLayouts

    This component catches the post data itself you can use that data in your emails. If you don’t want to capture the data from post request you want to set your data that is also possible, only add the second param as array you can get that in your email view as ‘$data’ array.

    How to use n controller :
    ?php
    //email to //you can send comma separated email addresses if you want to send email to multiple people.

    $this-AWSSES-to = $this-request-data['User']['username'];

    if ($this-AWSSES-_aws_ses(‘email tempate name’, ‘optional param’)) {
    //optional param : can be an array of the data that you want to access in email view.

    //your code
    }
    ?

    Article source: http://bakery.cakephp.org/articles/kvijay/2012/04/24/aws_ses_component_for_cakephp2_0

     
  • endyourif 8:51 pm on April 23, 2012 Permalink | Log in to leave a Comment
    Tags:   

    Breadcrumbs trail for unordered pages 

    ?php
    /**
    * NavigationComponent
    **
    *
    * @author Rene Weber
    * @website http://www.webrene.com * @modified by Rene Weber, 23.04.2012
    * @version 1.0
    * @cakephp 1.3
    *
    **
    * Purpose
    * ———
    * Track your way and allow Backwards movement.
    * The Idea is to create a trail of visited pages, allowing you always jump back.
    * This can help if a breadcrumb logical can not be used, since there is no clean hierachical structure
    * with parent/child structure
    * I also played with referer variable, back button usage and javascript back but in the end the trac was
    * always getting messed by functions / methods like save, edit, etc.
    *
    * This Component/Helper pack will allow you to customize methods and controllers to be ignored and to
    * display a nice, linked trail in the form of
    * Component ( index ) Component ( view) Component2 ( index )
    *
    *
    * What does it constis of
    * ————————-
    * 1. NavigationComponent ( this file )
    * The component constists of 4 Functions:
    * – process: The main function to be called from appController: Stores current page,
    * handles clicks on links,
    * keeps trail short
    * – storeTrail : Stroes current trail to session ussing $sessionVarName
    * – walkBack : If a Link was clicked in our trail, remove all visited pages behind this link
    * This only happens for links passing $navpointUrl and the index.
    * See corresponding NavigationHelper to created correct links
    * – shrinkTrail: Shift trail until it’s length reaches $maxItems or the given length
    *
    *
    * 2. NavigationHelper
    * Meant to create correct Links to jump back in time. These links also include the index in our trail
    * and therefor the trail will be adjusted after clicking such a link.
    *
    *
    * Installation
    * —————-
    *
    * 1. Add Component to app/controllers/components/
    * 2. Add Helper to app/views/helpers/
    * 3. Add Helper to AppController ( nessecary to use in layout) in app/app_controller.php:
    *
    * var $helpers = array(… , ‘Navigation’);
    * — If $helpers was not defined yet, you will have to add all used helpers like ‘Html’ etc.
    *
    * 4. Call ‘process’ in app_controller.php directly at the beginning of beforeFilter and set variable
    *
    * $this-Navigation-Process( $this );
    * $this-set(‘trail’, $this-Navigation-trail );
    *
    * 5. In your Layout or in your desired View, call the trail creator or only read the link:
    *
    * $this-Navigation-printBacklinks( $trail, 8 )
    * or
    * echo $this-Html-link(“Back”, $this-Navigation-getBacklinkForView( $trail ) );
    *
    * 6. Possibly you want to enclose ‘printBacklinks’ into a div and adjust its hover and look.
    * i.e.
    * div class=’crumb’$this-Navigation-printBacklinks( $trail, 8 )/div
    * and
    * .crumbs { color: }
    * .crumbs a { color: font: 0.9em arial; }
    * .crumbs a:hover { font-size: 1em; color: font-weight: bold; }
    *
    *
    *
    */

    class NavigationComponent extends Object {

    /************************************** GLOBAL VARIABLES MAY BE ADJUSTED ***************************************/
    
        /**
     * Methods that shall not be stored. I.e. going from Index to View to Edit to Save
     * forwarding you to View again, a back button should ignore the Edit but push you back to Index.
     */
    
    var $ignoreMethods     = array( 'edit', 'save' );
    var $ignoreControllers = array( 'CakeError', 'Users' );
    
    /**
     * Keyname to store session variable in
     */
    
       var $sessionVarName        = 'Navigation';
    
       /**
        * This is the key we will use in URL to pass the index to our component.
        * Default is 'navpoint' and MUST BE THE SAME IN HELPER!
        * i.e. http://myhost/posts/123?navpoint=3  - Will jump to 3rd point and delete the rest behind
        */
    
       var $navpointUrl            = 'navpoint';
    
       /**
        *  Maximum entries in our trail variable. Default: 8
        */
    
       var $maxItems = 8;
    
       /******************************** END OF GLOBAL VARIABLES. DO NOT CHANGE BELOW ***********************************/
    
       /**
        *  Array holding the Trail we are Moving in
        */
    
       var $trail = array();
    
       /**
         * Write Trail to Session
        */ 
    
       function storeTrail(){               
    
           $this-Session-write( $this-sessionVarName, $this-trail );
    
       }

    var $components = array(‘RequestHandler’, ‘Session’);

    /**
    * If a navigation click brought us here, let’s clean all other items
    * This happens if we came here via helper. This can be parsed from the params.
    * e.g. /posts/view/1/navpoint/3 — Navpoint = 3, clean everything behind
    * It will be next value behind navpoint
    */

    function walkBack( $controller ){

    if( isset( $controller-params['url'][$this-navpointUrl] ) ){

    for ( $i=sizeof($this-trail); $i$controller-params['url'][$this-navpointUrl]; $i– ){
    unset( $this-trail[$i] );
    }

    }

    }

    function process( $controller ) {

    $skipThis = 0;

    $controllerName = $controller-name;

    /* Restore from Session if exists */
    if( ( $sessionVar = $this-Session-read( $this-sessionVarName ) ) )
    $this-trail = $sessionVar;

    /* Check if one of our crumbs was clicked ( will be passed via URL ) */
    $this-walkBack( $controller );

    /* Check if current Method is included in our Ignore List */

    if( in_array( $controller-params['action'], $this-ignoreMethods ) )
    $skipThis = 1;

    /* Check if current Controller is included in our Ignore List */
    if( in_array( $controller-name, $this-ignoreControllers ) )
    $skipThis = 1;

    /* Ignore reload of same controller and same action */

    if( sizeof( $this-trail ) 0 ){

    $lastElement = $this-trail[sizeof( $this-trail ) -1 ];

    if ( !empty( $lastElement['url'] )
    $lastElement['url'] == $controller-params['url']['url'] ) {

    $skipThis = 1;
    }
    }

    /* Add current Page to trail */
    if( $skipThis != 1 )
    $this-trail[] = array( ‘url’ = $controller-params['url']['url'],
    ‘action’ = $controller-params['action'],
    ‘controller’ = $controllerName,
    );

    /* Shorten Trail to maximum lenght */
    $this-shrinkTrail();

    /* Store trail to session */
    $this-storeTrail();

    }

    function shrinkTrail( $length=-1 ){
    
          if( $length == -1 ){
              $length = $this-maxItems;
          }
    
          while( sizeof( $this-trail )  $length ){
              array_shift( $this-trail);
          }             
    
      }
    
       function cleanTrail() {
    
              $this-trail = array();
               $this-Session-delete( $this-sessionVarName );
    
       }

    }


    ?php
    /**
    * NavigationHelper
    **
    *
    * @author Rene Weber
    * @website http://www.webrene.com * @modified by Rene Weber, 23.04.2012
    * @version 1.0
    * @cakephp 1.3
    *
    **
    *
    * Purpose
    * ———
    * Create Links for jumping back in trail and add Information for NavigationComponent to adjust its trail
    *
    *
    * Which files are needed?
    * ————————-
    * 1. NavigationHelper ( This file )
    * Meant to create correct Links to jump back in time. These links also include the index in our trail
    * and therefor the trail will be adjusted after clicking such a link.
    * – printBackLinks: Need trail variable and length
    * Will print length amount of the last visited pages with links in one row seperated
    * by $this-seperator ( see global variables )
    * – getBacklinkForView: Yes, this is a long function name. It will return only an URL to be used.
    *
    * 2. NavigationComponent
    * The component constists of 4 Functions:
    * – process: The main function to be called from appController: Stores current page,
    * handles clicks on links,
    * keeps trail short
    * – storeTrail : Stroes current trail to session ussing $sessionVarName
    * – walkBack : If a Link was clicked in our trail, remove all visited pages behind this link
    * This only happens for links passing $navpointUrl and the index.
    * See corresponding NavigationHelper to created correct links
    * – shrinkTrail: Shift trail until it’s length reaches $maxItems or the given length
    *
    *
    *
    *
    * Installation
    * —————-
    *
    * See Component!
    *
    **
    * @author Rene Weber
    * @website http://www.webrene.com * @modified by Rene Weber, 23.04.2012
    * @version 1.0
    * @cakephp 1.3
    *
    */

    class NavigationHelper extends AppHelper {

    /************************************** GLOBAL VARIABLES MAY BE ADJUSTED ***************************************/
    
    /**
     * This array allows you to define aliases for printBackLinks function. Simple example:
     * Without aliases:  Posts ( indexEditor )  Messages( indexNoNews )  ...
     * With aliases:         Posts ( Mine )               Messages( Read )              ...
     */ 
    
    var $actionAliases        = array(    'indexSelection'     = 'Type Selection',
                                                                    'indexGrouped'       = 'Grouped',
                                                                    'indexEditor'             = 'My Edits',
                                                                    'index'                        = '',
                                                                    'indexNoNews'            = 'No News',
                                                                    'indexOldVersion' = 'Old Version',
                                                                );
    
    /**
     * Seperator for function printBackLinks
     */
    
    var $seperator = " nbsp;  nbsp; ";

    /**
    * This is the key we will use in URL to pass the index to our component.
    * Default is ‘navpoint’ and MUST BE THE SAME IN HELPER!
    * i.e. http://myhost/posts/123?navpoint=3 – Will jump to 3rd point and delete the rest behind
    */

    var $navpointUrl = ‘navpoint’;

    /**************** END OF GLOBAL VARIABLES. DO NOT CHANGE BELOW *******************/

    var $helpers = array( ‘Html’ );
    var $controllerAliases = array();

    function printBackLinks( $trail, $count = 1 ) {

    for ( $i=$count; $i0; $i– ){

    if( sizeof( $trail ) $i )
    continue;

    $lastElement = $trail[sizeof( $trail ) - $i ];

    $displayController = $lastElement['controller'];
    $displayAction = $lastElement['action'];

    if( isset( $this-actionAliases[ $lastElement['action'] ] ) )
    $displayAction = $this-actionAliases[ $lastElement['action']];

    if( isset( $this-controllerAliases[ $lastElement['controller'] ] ) )
    $displayController = $this-controllerAliases[ $lastElement['controller'] ];

    if( !empty( $displayAction ) )
    $displayAction = ‘( ‘.$displayAction.’ )’;

    $url = ‘/’.$lastElement['url'].’?’.$this-navpointUrl.’=’.(sizeof( $trail ) – $i);
    echo $this-Html-Link( $displayController.$displayAction, $url );
    echo $this-seperator;
    }

    }

    function getBacklinkForView( $trail ) {

    $url = ”;

    if( isset( $trail[sizeof( $trail ) - 2 ] ) ){
    $lastElement = $trail[sizeof( $trail ) - 2 ];

    $url = ‘/’.$lastElement['url'].’?’.$this-navpointUrl.’=’.(sizeof( $trail ) – 2);
    }

    return $url;

    }

    }

    ?

    Article source: http://bakery.cakephp.org/articles/webrene/2012/04/23/breadcrumbs_trail_for_unordered_pages

     
  • endyourif 8:40 am on April 23, 2012 Permalink | Log in to leave a Comment
    Tags:   

    GoogleChart helper 

    I needed simple access to Google Chart API for generating images. Please see examples below and method comments in source file to see how it works.

    This plugin is for CakePHP 2.x

    Example:



    // Controller:
    public $helpers = array('GoogleChart.GoogleChart');

     



    // View:
    // example of bar chart
    echo $this-GoogleChart-create()
        -setType('bar', array('horizontal', 'grouped'))
        -setSize(500, 400)
        -setMargins(5, 5, 5, 5)
        -addData(array(1200.48, 432.3, 647.21, 635.2))
        -addMarker('value', array('format' = 'f1', 'placement' = 'c'))
        -addData(array(20, 42.3, 65.21, 95.2))
        -addMarker('value', array('size' = 14, 'color' = '000000'))
        -addAxis('x', array('labels' = array('jan 2012', 'feb 2012')))
        -addAxis('y', array('axis_or_tick' = 'l', 'size' = 12));
        
    // example of pie chart
    echo $this-GoogleChart-create()
        -setTitle('CHART TITLE', array('size' = 14, 'color' = '000000'))
        -setType('pie', array('3d'))
        -setSize(600, 300)
        -setMargins(10, 10, 10, 10)
        -addData(array(20, 35, 50, 10))
        -setPieChartLabels(array('first', 'second', 'third', 'and so on...'));

    Download the code from https://github.com/segy/GoogleChart

    Article source: http://bakery.cakephp.org/articles/segy/2012/04/23/googlechart_helper

     
  • endyourif 8:38 pm on April 22, 2012 Permalink | Log in to leave a Comment
    Tags:   

    from Cake to Bake 

    1. Download the latest version of Cake from http://cakephp.org/
    2. Go to your Download folder (or where ever you downloaded your folder), Extract the folder in the same location.
    3. Move the folder to your application root. (In my case /var/www/ )if you face permission denied while copy/paste, use “gksu nautilus” to open the target location.
    4. Rename the folder, MyCake
    5. Use this to change permissions, “sudo chmod -R 777 /var/www/MyCake/”
    6. Delete the folder named “app” from /var/www/MyCake/ , we will be using folder that will be created by bake
    7. So far you have downloaded and set up Cake, now lets install cake bake utility.
      Run this in your terminal to install cake, ” sudo apt-get install cakephp-scripts ” this will help in baking later. This will also create new folder in “/usr/share/php” named cake

    Important:
    Use
    sudo gedit /etc/apache2/sites-available/default
    to edit the contents to follow:

    Directory /var/www/
    Options Indexes FollowSymLinks MultiViews
    AllowOverride All
    Order allow,deny
    allow from all
    /Directory

    1. Run this in your terminal. This command will create a folder named app in your MyCake folder
      cake bake -app /var/www/MyCake/app/
      This will ask you below:

    What is the full path for this app including the app directory name?
    Example:/var/www/MyCake/app/myapp
    [/var/www/My-CakePHP/aapp/myapp]

    You must give it path to where you want app folder created, in this case type below:

    /var/www/MyCake/app/

    This will create new folder named app and new files under it.

    1. Again run the same command, this time we want to use its CRUD functionality called Bake.

    after running this command below:
    cake bake -app /var/www/MyCake/app/

    it might tell you that your database.php file cannot be found and that if you want to create the same, tell it yes and provide all the details, do not modify first option ($default), this is a variable that should be left untouched.

    or it will ask you what you want to do?

    Welcome to CakePHP v1.3.7 Console


    App : app
    Path: /var/www/My-CakePHP/app

    B0x1A0

    Interactive Bake Shell

    B0x1A0

    [D]atabase Configuration
    [M]odel
    [V]iew
    [C]ontroller
    [P]roject
    [F]ixture
    [T]est case
    [Q]uit
    What would you like to Bake? (D/M/V/C/P/F/T/Q)

    tell it that you want to create Model by typing M

    Bake Model
    Path: /var/www/My-CakePHP/app/models/

    B0x1A0

    Use Database Config: (default/database)
    [default]

    enter “database”

    and so on….

    Rest is very intutive and help you create controllers and view.

    You can then access your site using http://localhost/MyCake/ or if you created controller by the name, posts, use http://localhost/MyCake/posts.

    Article source: http://bakery.cakephp.org/articles/mainiabhay/2012/04/22/from_cake_to_bake

     
  • endyourif 7:25 pm on April 20, 2012 Permalink | Log in to leave a Comment
    Tags:   

    Fixing and improving the TextHelper 

    General

    I created a new helper which the following file in “/app/view/helpers/Text2Helper.php”:


    ?php
    App
    ::import('Helper''Text');

    class 

    Text2Helper extends TextHelper {
        public function 
    function_name($parameters) {
            
    // some code

            // if you want to extend functionality, maybe you want
            // to call the parent function
            

    parent::function_name($parameters);
        }
    }
    ?




    You can overwrite and create new functions in this file.
    (See: http://ask.cakephp.org/questions/view/how_can_i_extend_the_core_helpers)

    Note that you can not use the helper with adding “Text2″ to the $helpers array inside a controller.
    Unfortunately you cannot globally specify to always use the Text2Helper instead of the TextHelper!
    The only thing you can do is to add the following to your view:


    $this-Text = $this-Text2;



    I would like to see a functionality to alias helpers! This would make the job easier and prettier.
    (http://cakebaker.42dh.com/2008/10/18/dont-abuse-the-apphelper-to-extend-the-core-helpers/#comment-110649)

    So let’s start with my modifications:

    1.) Increasing toList() functionality

    I added the functionality to specify who each item should be displayed (some sourrounding code and so on).
    Therefore I added the parameter $phrase. _key_ will be replaced by the current element’s key and _item_ will be replaced by the current element’s value.



    ?php
        
    public function toList($list$and 'and'$separator ', '$phrase '_item_') {
            foreach(
    $list as $key $item
                
    $item str_replace(array('_key_''_item_'), array($key$item), $phrase);
            return 
    parent::toList($list$and$separator);
        }
    ?


    2.) Fixing truncate()

    Currently the truncate() function only breaks on spaces. So when you only have newline characters or tabs, the code won’t break. That’s why even very long strings may result in “…”.
    Therefore I added 3 fixes.

    2.1.) Fixing punctuation

    Some people don’t add spaces after dots, commas and so on. That’s why I added exactly one space after each of these characters:


    ?php
        
    // 1. fix punctuation
        
    if ($options['fix_punctuation']) {
            
    $punctuation ',.;:';
            
    $text preg_replace('/(['.$punctuation.'])[s]*/''1 '$text);
        }    
    ?




    2.2.) Fixing spaces

    All possible space symbols (like newline, tab, …) are replaced by one space character:


    ?php
        
    // 2. fix spaces
        
    if ($options['fix_spaces']) {
            
    //$spaces = " trn";        // use preg_replace() or str_replace() or strtr()
            
    $text preg_replace('/[[:space:]]+/'' '$text);        // [:space:] equal s
        
    }
    ?




    2.3.) Switch to cut instead of clear

    When the returned string is still only ‘…’ then set ‘exact’ = true (cutting instead of searching for spaces):


    ?php
        
    // get truncated string
        
    $result parent::truncate($text$length$options);
        
        
    // 3. fix long strings: cut instead of clear
        
    if ($options['fix_longStr']) {
            if (
    $result === $options['ending']) {
                
    $options['exact'] = true;
                
    $result parent::truncate($text$length$options);
            }
        }
    ?




    So here is the whole code of my truncate function:


    ?php
        
    public function truncate($text$length 100$options = array()) {
            
    $default = array(
                
    'fix_punctuation' true
                
    'fix_spaces' true
                
    'fix_longStr' true'ending' '...'
            
    );
            
    $options array_merge($default$options);
            
            
    // 1. fix punctuation
            
    if ($options['fix_punctuation']) {
                
    $punctuation ',.;:';
                
    $text preg_replace('/(['.$punctuation.'])[s]*/''1 '$text);
            }    
            
            
    // 2. fix spaces
            
    if ($options['fix_spaces']) {
                
    //$spaces = " trn";        // use preg_replace() or str_replace() or strtr()
                
    $text preg_replace('/[[:space:]]+/'' '$text);        // [:space:] equal s
            
    }
            
            
    // get truncated string
            
    $result parent::truncate($text$length$options);
            
            
    // 3. fix long strings: cut instead of clear
            
    if ($options['fix_longStr']) {
                if (
    $result === $options['ending']) {
                    
    $options['exact'] = true;
                    
    $result parent::truncate($text$length$options);
                }
            }
            
            
    // return truncated string
            
    return $result;
        }
    ?


    3.) Add wordwrap()

    This function automatically inserts a newline after a maximum number or characters.
    Please not that this mostly only useful when you have “text-align: justify;” in your css style.
    Otherwise it’s often better to set “word-wrap: break-word;” in your css to let the browser do the work. That’s because of the different widths for the different characters for most fonts.

    So here is my code:


    ?php
    /**
     * Splits string in lines of given length.
     * Note: Perhaps it's better to set the following css option: "word-wrap: break-word;"
     *         because it handles the different widths of the characters correctly
     *
     * @param string $text String to wrap.
     * @param integer $length Maximum length (number of characters) of returned lines.
     * @param bool $cut If the cut is set to TRUE, the string is always wrapped at or before the specified width. So only if you have a word that is larger than the given width, it is broken apart.
     * @param bool $htmlBreak Inserts 'br /' on every newline.
     * @return string Wrapped string.
     */
        
    public function wordwrap($text$length 100$cut true$htmlBreak true) {
            
    $text wordwrap($text$length"n"$cut);
            return ((
    $htmlBreak)?nl2br($text):$text);
        }
    ?


    I hope you find this information useful.
    When you are of the CakePHP team, consider implementing these fixes into the original TextHelper ;)

    Article source: http://bakery.cakephp.org/articles/darkdragon/2012/04/20/fixing_and_improving_the_texthelper

     
  • endyourif 7:18 am on April 20, 2012 Permalink | Log in to leave a Comment
    Tags:   

    Prevent render layout elements with the render of some views! 

    Consider the following example, there is an element that displays the top searched keywords and it is named top_searches.ctp. This element is placed in the layout to be rendered under the search box element.

    Suppose now, we have an index view that lists all searched keywords and we don’t want to make the top_searches elements to be rendered while we call the index view.

    We should add the following code snippet into the most upper line of top_searches, i.e line 1.

    ?php
    $e = explode('views/elements/',__FILE__);
    $e[1] = str_replace('.ctp', '', $e[1]);
    if (isset($this-preventElement)  $e[1] == $this-preventElement[$e[1]]) return false;
    ?

    Simply the above code extracts the path and name of the element’s ctp file relative to the elements directory, then, it asks for an array property of the View object called preventElement, if it find the name of the element is set as a key valued by its name too, it will return false to prevent the rest of the element to be rendered.

    Now in the index.ctp we should add the following code:

    ?php $this-preventElement['top_searches'] = 'top_searches';?

    I placed the above line of code on the first line too, it is, obviously, that we defined the preventElement property and we set the name of the element we want to stop or prevent its render.

    There is a working example of this snippet at:
    http://quran.2index.net
    You will see a list for top searched keywords, you will see the last item is red button that linked to the full index of all searched keywords, at this linked page, you will not see the to searched keywords list.
    Notice: The working example website in Arabic language.

    Article source: http://bakery.cakephp.org/articles/saidbakr/2012/04/20/prevent_render_layout_elements_with_the_render_of_some_views

     
  • endyourif 6:53 am on April 19, 2012 Permalink | Log in to leave a Comment
    Tags:   

    Dynamic Url 

    Guys,
    i want to create a dynamic url like.

    1 – http://www.domain.com/web-designing 2 – http://www.domain.com/web-development 1.1 – http://www.domain.com/web-designing/flash 2 – http://www.domain.com/web-development/php

    http://www.domain.com/value – will come here from database.

    Please write here your code, how you will resolve the issue. Please write: model, controller,routes all the codes here.

    Thanks!

    Article source: http://bakery.cakephp.org/articles/abdulkhaliq/2012/04/19/dynamic_url

     
  • endyourif 5:58 pm on April 16, 2012 Permalink | Log in to leave a Comment
    Tags:   

    User Management Premium Plugin for cakephp 2.x 

    I have launched premium version of User Management Plugin

    Demo at http://umpremium.ektasoftwares.com

    There are lots of features and you will like them definitely……

    So guys don’t go here and there just look these features at demo site.

    Article source: http://bakery.cakephp.org/articles/chetanvarshney/2012/04/16/user_management_premium_plugin_for_cakephp_2_x

     
  • endyourif 5:34 am on April 15, 2012 Permalink | Log in to leave a Comment
    Tags:   

    SELECT FOR UPDATE (hack) (kind of ugly but it works) (PostgreSQL and MySql) 

    Sometimes one needs to do a SELECT … FOR UPDATE in order to preserve the integrity of our transactions. The problem can be seen easily with the following example:

    Suppose we have a user, an account table with the account.available_money field on it. Suppose the user has initially $100.

    The problem arrives if the hacker manages to concurrently run two processes:

    One process does:
    BEGIN
    SELECT available_money from account where user_id = ’1′ ; // $money = $100
    UPDATE account SET available_money = 0 where user_id = ’1′;
    COMMIT

    While another concurrent process does
    — php process also finds $100 money and uses it all again
    BEGIN
    SELECT available_money from account where user_id = ’1′; // $money = $100
    UPDATE account SET available_money = 0 where user_id = ’1′; //the user buy $100 and he depletes his account
    COMMIT

    If this happens, then the user could use more money than he is entitled to. SELECT FOR UPDATE comes to the rescue. Following the previous example

    One process does:
    BEGIN
    SELECT available_money from account where user_id = ’1′ FOR UPDATE; // $money = $100
    UPDATE account SET available_money = 0 where user_id = ’1′;
    COMMIT

    While another concurrent process does
    BEGIN
    SELECT available_money from account where user_id = ’1′; // now this second process must wait the first process to finish, so $money = $0
    — the user doest not have money to buy anything
    COMMIT

    Now, how to achieve this using CakePHP ?

    CakePHP’s dbo doesn’t currently support FOR UPDATE syntax. BUT there is a litlle quick and dirty (maybe too dirty for some) hack you can do without doing any modifications to the core …

    Since in the dbo_source, in the SELECTstatement, the LIMIT clause gets parsed at last (see line 1497 from cake/libs/models/dbo_source.php):

    switch (strtolower($type)) {
        case 'select':
            return "SELECT {$fields} FROM {$table} {$alias} {$joins} {$conditions} {$group} {$order} {$limit}";
        break;
        //...

    If in a need, and if using PostgreSQL (mysql later), you could do
    $transac = $this-AccountModel-find(‘all’, array(
    ‘conditions’ = array(
    ‘user_id’ =$id
    ),
    ‘fields’ = array(‘available_money’),
    ‘limit’ = ‘ALL FOR UPDATE’
    ));`

    … and this would generate the SELECT available_money from account where user_id = '1' FOR UPDATE clause we are looking for… The trick is in the 'limit' = 'ALL FOR UPDATE'. This selects ALL records that match the conditions FOR UPDATE.

    For MySql you would have to do something a lot uglier. Since MySql doesn’t support LIMIT ALL, you would have to use LIMIT 0,18446744073709551615. This is pretty horrible, I know… The other options are to code a behavior for all of us : )

    Just remember to put you find inside a transaction !

    Watch out, there is a little (but important) catch… You can’t do find('first), since the LIMIT clause would be overwritten by Cake as LIMIT 1, instead you can do find(‘all’, … ‘limit’ = ’1 FOR UPDATE’ …)

    Article source: http://bakery.cakephp.org/articles/arod/2012/04/14/select_for_update_hack_kind_of_ugly_but_it_works_postgresql_and_mysql

     
  • endyourif 5:01 am on April 14, 2012 Permalink | Log in to leave a Comment
    Tags:   

    CakeApp with TwitterBootstrap 

    Twitter Bootstrap appears to be a very successful CSS framework, and I must agree. There is a js library that you can include which will help you get TB (Twitter Bootstrap) setup, but I wanted to take it one step further.

    I created “CakeApp” Which is a CakeApp with some niceties already added in there for you. Including Jquery and a pre-configured TB, which should have everything as of 4/13/12. Also, the homepage has been updated to use TB, so you are running right out of the gate.

    Here is a link to that: https://github.com/alairock/CakeApp

    Enjoy, and fork if you want to contribute!
    -alairock

    Article source: http://bakery.cakephp.org/articles/alairock/2012/04/13/cakeapp_with_twitterbootstrap

     
c
compose new post
j
next post/next comment
k
previous post/previous comment
r
reply
e
edit
o
show/hide comments
t
go to top
l
go to login
h
show/hide help
esc
cancel