Tag archives for cakepower

PowerString Class API

PowerString extends CakePHP’s String utility library providing some new methods to the framework.

Go back to CakePower’s Documentation Page

Posted in CakePOWER | Leave a comment

Ajax / REST HTTP Status Response Code

Today I was playing with BackboneJS save/destroy methods on data models.

My JS app was binded to a MySQL db by a CakePHP (CakePower) REST layer so I have a controller implementing the CRUD methods.

This controller sends notifications using the CakePower notification system but I found a problem with this interface: no error http status was given to the response!

// the simple CakePower error notification:
$this->Session->error( 'user not found' );

This code drives standard CakePHP requests (forms, links) setting up a flashMessage, ajax and REST requests setting up a JSON response object.

The problem was all responses was given with the 200 HTTP Status code! This was a very bad mistake!

If errors was found in controller’s logic then HTTP Status needs to be configured according to the error: 404 if resource was not found or, at least, a generic 500 – Internal Server Error.

Dealing with jQuery::ajax()

The real world problem was that with 200 response status jQuery::ajax()’s error callback was never thrown!

BackboneJS Model::destroy() method implements an automation to remove destroyed model from related collections… But this automation fails without correct HTTP status!

NOW THIS BUG IS FIXED AND ALL THINGS WORKS FINE!

Customize HTTP Status Code

Default HTTP Status is 200 for: message(), confirm(), warning() methods and 404 for error() method.

You can customize this information with the status option:

$this->error( 'bad request!', null, array( 'status'=>400 ) );
$this->confirm( 'updated!', null, array( 'status'=>204 ) );

Have a nice developing experience with CakePower and BackboneJS!

Posted in CakePHP, CakePOWER | Leave a comment

HtmlHelper::tag() method in CakePower

CakePower extends CakePHP’s HtmlHelper without change it’s API. This way you can enjoy powerful functionalities without to change helper names in your sources.

The standard CakePHP code:

$p1 = $this->Html->tag( 'p', 'content of first P' );
$p2 = $this->Html->tag( 'p', 'content of second P', array( 'class'=>'second' ));
echo $this->Html->tag( 'div', $p1.$p2, array( 'class'=>'container' ));

Enjoy CakePower:

echo $this->Html->tag(array(
    'name' => 'div',
    'class' => 'container',
    'content' => array(
        array(
            'name' => 'p',
            'content' => 'content of first P'
        ),array(
            'name' => 'p',
            'class' => 'second',
            'content' => 'content of second P'
        )
    )
));

Continue reading »

Posted in CakePHP | 2 Comments

PowerMenu Helper – how to build menus with CakePower

PowerMenuHelper offers an easy way to generate HTML from PowerMenu‘s data:

// PowerMenu Helper in Action:
echo $this->PowerMenu->generate('sidebar.menu');

Continue reading »

Posted in CakePHP | 1 Comment

CakePHP: Using View Blocks – The CakePOWER way!

View Blocks allow to add content to a logic container during page rendering.

At the end of the story a layout, a view or an element may display some contents fetching it from a container using container’s name.

CakePOWER supplies an helper method to quickly create DOM blocks form View Blocks:

echo $this->Html->block( 'block_name' );

Continue reading »

Posted in CakePHP | 3 Comments

CakePower Events API

CakePower triggers lots of events while performing it’s logic so you can write some listeners and inject logic and code into altering the standard flow of the application.

This post describe each event triggered by CakePower, it’s properties and available returning values.

Continue reading »

Posted in CakePHP | Leave a comment

How to use RequireJS with CakePHP – CakePOWER

RequireJS is a library created to load js files asynchronous. It’s objective is to optimize developement and speed up the web page.

I do not cover any RequireJS documentation here. Let me say it ask you to write a piece of code like this in your HTML:

<script src="path/to/require.js" data-main="path/to/script"></script>

where the “src” attribute points to the RequireJS library and the “data-main” attribute points to the main script to be loaded. This is the entry point of your js app and here you can load other modules (AMD).

The problem: “data-main” needs a relative path to the document so you need to write a CakePHP piece of code like that:

// do you really want to write this code??
echo $this->Html->script( 'path/to/require', array(
    'data-main' => $this->Html->assetUrl( 'path/to/script', array(
        'pathPrefix' => JS_URL, 
        'ext' => '.js'
    ))
));

this way the data-main attribute will contain the correct url to the js folder.

CakePower supplies a really easy solution to write above code in a compact and simple way:

// With CakePower loaded into your CakePHP app:
echo $this->Html->script( 'path/to/require', array(
    'data-main' => 'path/to/script'
));

Easy, isn’t it?

Posted in CakePHP | Leave a comment

CakePOWER :: PowerAuthComponent

PowerAuthComponent extends CakePHP’s AuthComponent adding a $accessDeniedRedirect property to allow define a static redirect when an access deny happen to an authenticated user.

Usage:

You can use this class by aliasing the standard AuthComponent inclusion in your AppController (or wherever you plan to use Authentication and Authorization):

public $components = array(
    'Auth' => array(
        'className' => 'CakePower.PowerAuth',
        'loginAction' => ...
    );
);

You don’t need anything else code to implement this CakePower component!

NOTICE: if you are extending CakePowerController in your AppController you do not need to set up the “className” property. CakePower sets up the alias for you!

Why do I need PowerAuth?

CakePHP’s AuthComponent redirects to the referral url (fallback to the root url) when access is denied to an authenticated user but this behavior may falls into infinite loop if booth referral url and root action are denied to the user.

The stage:

Figure you have a fully protected app where even the root url (/) belong to authentication and authorization.

If your app is a private blog (like in CakePHP tutorials) you may have these controllers:

  • posts – display and manage posts
  • users – manage users
  • info – display some analytics about the blog.

Authentication uses UsersController::login() and UsersController::logout() methods to handle users authentication so these actions are allowed in the AppController rules:

class AppController extends Controller {

    public $components = array(
        'Session',
        'Auth' => array(
            'loginAction' => array( 'controller'=>'users', 'action'=>'login' ),
            'authorize' => 'Controller'
    );

    public beforeFilter() {
        // All app actions are protected except login/logout.
        $this->Auth->allow( 'login', 'logout' );
    }

}

Users Access Policies:

  • User “Marco Sheeptaker” has an “admin” role so hes access is unlimitet.
  • User “Analytics Hero” can access only the AnalyticsController in the app.

These rules are coded as follow in AppController::isAuthorized() method:

public function isAuthorized( $user ) {

    if ( $user['role'] == 'admin' ) return true;

    if ( $this->request->params['controller'] == 'analytics' ) return true;

    return false;

}

When Authorization will cause a loop?

When “Marco Sheeptaker” login to the app no error happen: when authenticated his profile will know no restrictions in the app.

But what happen when an Analytics Hero user try to login?

  • access the root url (/) via browser’s url bar
  • authentication redirects to the login action
  • when login success Auth redirects to the url requested before the login: the root url
  • user is not allowed to view this url so he is redirected to the login another time!

Each login will redirect back… to the login! This is a loop!

Now the user understand he can’t go out this loop so he go to the root url by digit it into the browser’s url bar:

  • access the root url (/) via browser’s url bar – user is already authenticated
  • authentication return “true” so there is no login redirection rules
  • authorization return false so user is redirected to the referral
  • referral does not exists because of user has directly accessed the root url
  • AuthComponent fallback for the referral url is… the root url!!!
  • user is redirected to the root!

This will cause a “bad redirection error” in (modern) browser! In ancient browsers (aka IE<9) it will crash down the client because of an infinite loop!!!

What do PowerAuthComponent does for me?

In simplest configuration (as shown at the beginning of this page) PowerAuthComponent replace fallback url for the referral url when redirecting after an access denied event. In place of the root url (/) it will use the loginAction property.

This way every infinite loops are kicked out of the application! If an action is denied and even the root action is denied PowerAuthComponent will redirect to the login page!

$accessDeniedRedirect

You can customize this behavior by setting an $accessDeniedRedirect. This property will be used in place of the $loginAction when configuring the referral’s fallback url:

public $components = array(
    'Auth' => array(
        'className' => 'CakePower.PowerAuth',
        'loginAction' => ...
        'accessDeniedRedirect' => array( 'controller'=>'pages', 'action'=>'access_denied_error' )
    );
);

$accessDeniedHardRedirect

If you want to skip the referral url and force redirection to an error page you can set the $accessDeniedHardRedirect propety.

This way when an action is not allowed the PowerAuthComponent will always redirect to defined url:

public $components = array(
    'Auth' => array(
        'className' => 'CakePower.PowerAuth',
        'loginAction' => ...
        'accessDeniedHardRedirect' => array( 'controller'=>'pages', 'action'=>'access_denied_error' )
    );
);

Bibliography & Resources:

 

Posted in CakePHP, Script | Leave a comment

Swedish Greys - a WordPress theme from Nordic Themepark.