Favourite Kohana Tips & Features? [closed]
Asked Answered
P

12

61

Inspired from the other community wikis, I'm interested in hearing about the lesser known Kohana tips, tricks and features.

  • Please, include only one tip per answer.
  • Add Kohana versions if necessary.

This is a community wiki.

Predial answered 6/3, 2010 at 15:49 Comment(0)
B
23

Generating Form::select() options from database result

Kohana 3.1 and 3.0

$options = ORM::factory('model')
 ->order_by('title','ASC')
 ->find_all()
 ->as_array('id','title');

$select = Form::select('name', $options);

It should be noted this is not restricted to the ORM and can be used on all database results (they all support as_array). See the database results information for more details.

If you want to add a default option:

$options = Arr::merge(array('Please select a value.'), $options);
Boardman answered 6/3, 2010 at 15:49 Comment(0)
B
17

Set Kohana::$environment

Paste these lines to your .htaccess:

SetEnvIf SERVER_ADDR "^(127\.0\.0\.1|::1)$" KOHANA_ENV=development
SetEnvIf SERVER_ADDR "^((?!127\.0\.0\.1|::1).)*$" KOHANA_ENV=production

now, if you're on localhost, you are in development mode, otherwise you're in production mode

Edit: Added support for IPv6

Bohs answered 6/3, 2010 at 15:49 Comment(0)
B
17

Show last query executed

Kohana 3.1 and 3.0

echo Database::instance()->last_query

Taken from In Kohana 3, how do you figure out errors made during a query?.

Bestrew answered 6/3, 2010 at 15:49 Comment(0)
B
15

The difference between this->request->route->uri() and this->request->uri() (Kohana 3)

// Current URI = welcome/test/5 
// Using default route ":controller/:action/:id"

// This returns "welcome/test/5"
echo $this->request->uri(); 

// This returns "welcome/test1/5"
echo $this->request->uri(array( 'action' => 'test1' )); 

// This returns "welcome/index"
echo $this->request->route->uri();

// This returns "welcome/test1"
echo $this->request->route->uri(array( 'action' => 'test1' ));

As you can see, $this->request->route->uri() uses current route defaults (id is null), while $this->request->uri() applies current uri segments.

Blinders answered 6/3, 2010 at 15:49 Comment(0)
P
15

Add data to pivot tables using ORM

ORMs add function accepts a third parameter where you can specify additional data to be saved on the 1pivot table1.

For example, if a user has many roles and a role has many users (through a table named 1roles_users1), you can save information to the 1pivot table1 by passing an array of column keys and data values as the 3rd argument to the add method.

Kohana 3.1

Not supported. The alternative would be to load the pivot table and add the data as you would with any other table.

Kohana 3.0

$user->add('role', $role, array('date_role_added' => time()));

where $role is ORM::factory('role', array('name' => 'user'));

Predial answered 6/3, 2010 at 15:49 Comment(6)
Learnt something new already. Thank You.Predial
you can also do that by defining $_created_column in the model :)Boardman
@Kemo; Not on pivot tables (unless you have a Model defined for them). @dusan; How do you go about reading the data back from the pivot? I haven't found a way of doing this using ORM.Lecky
@Lecky $table->pivots->select('pivots.field')->find_all() ? :)Boardman
@Lecky I also haven't found a way to reading that data back using ORM =(Bestrew
Notice that this was removed from 3.1Boardman
F
12

Turn off auto_rendering for AJAX requests

These code samples assume you're extending from the template controller.

Kohana 3.1

public function before()
{
    parent::before();

    if (Request::current()->is_ajax())
    {
      $this->auto_render = FALSE;
    }
}

Kohana 3.0

public function before()
{
    parent::before();

    if (Request::$is_ajax)
    {
      $this->auto_render = FALSE;
    }
}
Force answered 6/3, 2010 at 15:49 Comment(2)
It is probably better to use Request::is_ajax(), rather than a site specific regex. is_ajax() checks "the X-Requested-With HTTP request header that most popular JS frameworks now set for AJAX calls." and is available in both KO2 and KO3.Jonellejones
Actually, isn't that Request::$is_ajax ?Tendency
T
11

Maintainable routes

Instead of hardcoding anchor locations in your HTML and PHP, it's a good idea to reverse routing. This essentially means you define route locations and then use those; If you ever need to change the location it's done in one place and not hundreds.

Routes can be defined anywhere, but it's good practice to put them into the application bootstrap or your modules bootstrap (init.php).

They are set as follows:

Route::set('name', '<controller>(/<action>)', array('action' => 'login|logout');
  1. Route name
  2. The URL path to match against.
  3. A regular expression to limit what the <part> is matched against.

When a part is surrounded by brackets, that part is optional. If a user has not provided a part and you want to provide a default value, then use the defaults method to specify values.

->defaults(array('action' => 'login'));

Kohana 3.1 and 3.0

The following code is now used for having reversable routes. The URL path can be updated and all your URLs should work as before.

Route::url('name', array('controller' => 'user', 'action' => 'login'));
Tendency answered 6/3, 2010 at 15:49 Comment(2)
perhaps another idea: URL::site(Route::get('route_name')->uri(array('controller' => 'somecontroller', 'arg' => 'somearg')));Impressive
Or perhaps Route::url('route_name', array('param' => 'value')); I'd also recommend passing the links to your view rather than expect the view to make them - helps keep logic out of the view.Illnatured
B
9

Set base_url automatically:

Kohana::init(array(
    // ...
    'base_url' => dirname($_SERVER['SCRIPT_NAME']),
    // ...
));

If your site is hosted at 1&1, you should use:

Kohana::init(array(
    // ...
    'base_url' => substr($_SERVER["SCRIPT_NAME"], 0, strpos($_SERVER["SCRIPT_NAME"], basename($_SERVER["SCRIPT_FILENAME"])));
    // ...
));

(taken from Gallery3 config file )

Bohs answered 6/3, 2010 at 15:49 Comment(0)
P
9

Checking for an internal request

These are known as sub-requests. Take a look at Sam de Freyssinets article: Scaling Web Applications with HMVC for a more indepth explanation. Notice the initial vs instance difference between versions.

Kohana 3.1

if (Request::initial() !== Request::current())
{
    print 'Internal called made with Request::factory';
}

Kohana 3.0

if (Request::instance() !== Request::current())
{
    print 'Internal called made with Request::factory';
}
Predial answered 6/3, 2010 at 15:49 Comment(1)
Or now you can use $this->request->is_initial() to check.Myotome
E
7

HMVC + AJAX = is_remote()

This function checks both - the internal and AJAX requests. It might be handy if some parts of the page are initially loaded using HMVC technique, and can be then reloaded with AJAX. Place it withing some base controller, from which you extend all your proper controllers (I call it 'base controller'):

public function is_remote()
{
    if ($this->request->is_initial())
    {
        if ($this->request->is_ajax())
        {
            return TRUE;
        }
        else
        {
            return FALSE;
        }
    }
    else
    {
        return TRUE;
    }
}

A shorter (equivalent) way of writing this:

public function is_remote()
{
    return ( ! $this->request->is_initial() || $this->request->is_ajax());
}

Hope this helps.

Egad answered 6/3, 2010 at 15:49 Comment(0)
P
6

Display an error page

If you need to display an error page, Kohana has built in exceptions for it. Once you've thrown an exception, you can create a custom exception handler and have a HTML error page shown. You'll want a switch to show the real error in development.

Kohana 3.1

throw new HTTP_Exception_404('The article :article was not found', 
    array(':article' => $article->name));

The 2nd argument provides a way for you to replace strings in the error message.

Kohana 3.0

Doesn't have HTTP exceptions bundled. You should create your own exceptions and handle them. Kohana has a tutorial for this: Kohana - Custom Error Pages

Predial answered 6/3, 2010 at 15:49 Comment(0)
D
4

To execute SQL query like TRUNCATE mytable with prepared statements, pass null as first param to DB::query() method. Useful, when query doesn't fit for any of CRUD operations.

Dysphasia answered 6/3, 2010 at 15:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.