Archive for the ‘Web’ category

pure data patch repository

pdpatchrepo
http://www.pdpatchrepo.info/

Pure Data have a repository for abstractions and externals, but not for patches. Not anymore, I took the time to code one. There’s multiple ways of searching a patch: by platforms, tags (adc~, notein), is audio, is video, is generative…

The site also feature a live stream (video & audio) with networked gui so that multiple visitors can interact with the streaming patch. Of course there’s a latency in the feed when playing with the knobs (betweeen 3-5 seconds) but it is still a fun way to jam with others. The bandwidth is provided by the Institute of Electronic Music and Acoustics.

RSS feeds

Patch (when a new patch is added)
Stream (when a new patch is stream)

Screenshot

31

10 2013

Online Speech Recognition for Dictation

I’m working on the integration of kiku (voice recognition to control your OS) to Vinux (Linux for the visually impaired). For now the feedback about kiku is great, but one thing people wants is a solution for dictation (that is, speech to text). kiku could be use for that task, but sadly there is no good (accurate) acoustic model available under GPL (Voxforge is a good start, but not there yet – please contribute).

So i came up with this online speech recognition for dictation solution to overcome this limitation. Speak in different languages, spell check, translate and text to speech all in one place. You’ll need Google Chrome and a microphone.

16

06 2011

kohana 3.2 tutorial

Below you will find an article / tutorial on Kohana 3.2 – An elegant HMVC PHP5 framework that provides a rich set of components for building web applications.

I am sharing a site template that use authentication & internationalization. You can view the website (not much to see) and download it from github. Any pull request will be more than welcome!

Download via Github:
https://github.com/patricksebastien/kohana-3.2-example


Topics



Install

Using GIT:
http://kohanaframework.org/3.2/guide/kohana/tutorials/git
or
Download:
http://kohanaframework.org/download


Structure of folders:
www/yoursite/site/index.php & .htaccess -> and your assets (css, images, js)
www/yoursite/application -> the very core of your site
www/yoursite/module & system -> core of kohana
or:
www/kohana/version/system & module -> multiple site using kohana
or:
everything in www/yoursite/site (application, module, system, index.php, .htaccess, …)


Test:
127.0.0.1/
If it’s greenish, then remove install.php


index.php
Reflect this structure in www/yoursite/site/index.php:

1
2
3
$application = '../application';
$modules = '../modules';
$system = '../system';

bootstrap.php
Modify application/bootstrap.php

1
date_default_timezone_set('America/Montreal');

Set PRODUCTION vs DEVELOPMENT

1
2
3
4
5
if (isset($_SERVER['KOHANA_ENV'])) {
    Kohana::$environment = constant('Kohana::'.strtoupper($_SERVER['KOHANA_ENV']));
} else {
    Kohana::$environment = ($_SERVER['REMOTE_ADDR'] == '127.0.0.1' ? Kohana::DEVELOPMENT : Kohana::PRODUCTION);
}

Initialize Kohana

1
2
3
4
5
'base_url'   => '/', // or for example: /yoursite/site/mykoapp
'index_file' => FALSE, // SEO (avoid index.php/mycontroller/action)
'profile' => (Kohana::$environment !== Kohana::PRODUCTION), //see how good you are
'caching' => (Kohana::$environment === Kohana::PRODUCTION),
'errors' => TRUE, //for custom 404, 500 FALSE for internal error handling

Enable modules (for example):

1
2
3
'auth'       => MODPATH.'auth',       // Basic authentication
'database'   => MODPATH.'database',   // Database access
'orm'        => MODPATH.'orm',        // Object Relationship Mapping

Many modules are available:
https://github.com/kolanos/kohana-universe
http://kohana-modules.com/

Set the routes (default controller will be login.php in this example)
http://kohanaframework.org/3.2/guide/kohana/routing

The order of your routes are important!

1
2
3
4
5
Route::set('default', '(<controller>(/<action>(/<id>)))')
    ->defaults(array(
        'controller' => 'login', // application/classes/controller/login.php
        'action'     => 'index',
    ));

.htaccess
Add this line at the very top of .htaccess (protect from sniffing directory)

1
Options All -Indexes -Multiviews

and modify (/ or for example: /yoursite/site/mykoapp)

1
2
# Installation directory
RewriteBase /

 
Template
http://kerkness.ca/kowiki/doku.php?id=template-site:create_the_template

Create the template controller (classes/controller/template/website.php) extending Controller_Template

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?php defined('SYSPATH') or die('No direct script access.');
class Controller_Template_Website extends Controller_Template
{
    public $template = 'template/website';

    /**
     * The before() method is called before your controller action.
     * In our template controller we override this method so that we can
     * set up default values. These variables are then available to our
     * controllers if they need to be modified.
     */

    public function before() {
        parent::before();
        if ($this->auto_render) {
            // Initialize empty values
            $this->template->title   = '';
            $this->template->content = '';
            $this->template->styles = array();
            $this->template->scripts = array();
        }
    }
     
    /**
     * The after() method is called after your controller action.
     * In our template controller we override this method so that we can
     * make any last minute modifications to the template before anything
     * is rendered.
     */

    public function after() {
        if ($this->auto_render) {
            $styles = array(
            'assets/css/website.css' => 'screen, projection',
            );
            $scripts = array(
            'http://code.jquery.com/jquery.min.js',
            );
            $this->template->styles = array_merge( $this->template->styles, $styles );
            $this->template->scripts = array_merge( $this->template->scripts, $scripts );
        }
        parent::after();
    }
}

Create the controller (classes/controller/login.php) extending Controller_Template_Website (look at the second action for an example on how to use another template per action):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Controller_Login extends Controller_Template_Website {

    public function action_index()
    {
        $this->template->title = 'Log in';
        $this->template->content = View::factory('login'); // application/views/login.php
    }

        // this action is using another template but using the same Controller_Template_Website
    public function action_showinfooverlay()
    {
        $this->template = 'template/overlay';
        parent::before();
        $this->template->title = 'Log in';
        $this->template->content = View::factory('login'); // application/views/login.php
    }
}

Create the html template (view/template/website.php)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo substr(I18n::$lang, 0, 2); ?>" lang="<?php echo substr(I18n::$lang, 0, 2); ?>">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="language" content="<?php echo I18n::$lang ?>" />
<title><?php echo $title ?></title>
<?php foreach ($styles as $file => $type) echo HTML::style($file, array('media' => $type)), PHP_EOL ?>
<?php foreach ($scripts as $file) echo HTML::script($file), PHP_EOL ?>
</head>
<body>
<div id="wrapper">
<?php echo $content ?>
</div>
</body>
</html>

Finally create your view content application/views/login.php

1
2
3
4
5
6
7
8
9
<?php echo Form::open(); ?>
<dl>
    <dt><?php echo Form::label('username', 'User') ?></dt>
    <dd><?php echo Form::input('username') ?></dd>
    <dt><?php echo Form::label('password', 'Pwd') ?></dt>
    <dd><?php echo Form::password('password') ?></dd>
</dl>
<p><?php echo Form::submit(NULL, 'Log in'); ?></p>
<?php echo Form::close(); ?>

At this point you can point your browser to see the login page:
http://localhost/ -> depending on base_url and .htaccess (could be in a sub-folder)
http://localhost/login -> not defined login as the default controller in bootstrap.php

Someone on #kohana (irc / freenode) made a suggestion of using view classes instead of template controller. Here’s two solutions: https://github.com/zombor/kostache & https://github.com/beautiful/view

 
Configure
Database
Copy modules/database/config/database.php to application/config/database.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'default' => array
(
    'type'       => 'mysql',
    'connection' => array(
        'hostname'   => 'localhost',
        'database'   => 'yourdb',
        'username'   => 'user',
        'password'   => 'pwd',
        'persistent' => FALSE,
    ),
    'table_prefix' => '',
    'charset'      => 'utf8',
    'caching'      => FALSE,
    'profiling'    => FALSE, // if you use profiling turn this on (to see querys)
),

Cookie
in application/bootstrap.php
must be after: spl_autoload_register(array(‘Kohana’, ‘auto_load’));

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
 * Cookie
 */

// Set the magic salt to add to a cookie
Cookie::$salt = 'fjsdijeihrewhbfsugfuyegwufewgwb';
// Set the number of seconds before a cookie expires
Cookie::$expiration = DATE::WEEK; // by default until the browser close
// Restrict the path that the cookie is available to
//Cookie::$path = '/';
// Restrict the domain that the cookie is available to
//Cookie::$domain = 'www.mydomain.com';
// Only transmit cookies over secure connections
//Cookie::$secure = TRUE;
// Only transmit cookies over HTTP, disabling Javascript access
//Cookie::$httponly = TRUE;

Session (stored in database)
http://kohanaframework.org/3.2/guide/kohana/sessions
in application/bootstrap.php add the default session handler:

1
Session::$default = 'database';

Copy system/config/encrypt.php to application/config/encrypt.php

1
2
3
4
5
6
7
8
9
return array(

    'default' => array(
        'key'   => 'fjdsjkfdskjfurew',
        'cipher' => MCRYPT_RIJNDAEL_128,
        'mode'   => MCRYPT_MODE_NOFB,
    ),

);

Create a table if you want to use database session

1
2
3
4
5
6
7
CREATE TABLE  `sessions` (
            `session_id` VARCHAR(24) NOT NULL,
            `last_active` INT UNSIGNED NOT NULL,
            `contents` TEXT NOT NULL,
        PRIMARY KEY (`session_id`),
        INDEX (`last_active`)
        ) ENGINE = MYISAM;

Copy system/config/session.php to application/config/session.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
return array(
    'database' => array(
        'name' => 'session',
        'encrypted' => TRUE, // need a key in config/encrypt.php
        'lifetime' => DATE::HOUR, // 0 = expire when the browser close
        'group' => 'default',
        'table' => 'sessions',
        'columns' => array(
            'session_id'  => 'session_id',
            'last_active' => 'last_active',
            'contents'    => 'contents'
        ),
        'gc' => 500,
    ),
);

Use it in your controller:

1
2
Session::instance()->set('key', 'value');
Session::instance()->get('key');

yoursite
Create a file in application/config/yoursite.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php defined('SYSPATH') or die('No direct access allowed.');
return array(
    'myconfig1' => 'fjdsjkfdskjfurew',
       'playlists' => array
    (
        1478363 => 10171,
        22857234 => 10171,
        386 => 10171,
        722 => 10171,
        893 => 10171,
        237 => 10171,
    ),
   
);

Then you can call a config like this:

1
2
$playlists = Kohana::$config->load('yoursite.playlists');
Kohana::$config->load('yoursite.myconfig1 ');

Message
(might be better to use I18N directly)

Create a file in application/message/yoursite.php for you project

1
2
3
4
5
<?php defined('SYSPATH') or die('No direct script access.');
return array(
    'permission'         => 'You don\'t have the permission',
    'wrong'         => 'Wrong username or password',
);

Then you can use it like this:

1
Kohana::message('yoursite', 'permission');

Translation
http://blog.mixu.net/2010/11/11/kohana-3-i18n-tutorial/

1
<?php echo __('Dear :firstname, your username is: :user', array(':firstname' => 'gfdgfdg', ':user' => 'gfdgfd')); ?>

 
Validation
http://kohanaframework.org/3.2/guide/kohana/security/validation
Copy system/messages/validation to application/message/validation.php if you want to change the error message

1
2
3
4
5
6
7
8
9
10
11
12
13
// Validate a form ($_POST)
if (isset($_POST) && Valid::not_empty($_POST)) {       
    // Validate the login form
    $post = Validation::factory($_POST)
    ->rule('username', 'not_empty')
    ->rule('username', 'regex', array(':value', '/^[a-z_.]++$/iD'))
    ->rule('password', 'not_empty')
    ->rule('password', 'min_length', array(':value', 3));
           
    // If the form is valid and the username and password matches
    if ($post->check()) {
        echo 'Validated';
    }

Using a callback for custom validation & error message

1
2
3
4
5
6
7
8
9
// form post handling
if (isset($_POST) && Valid::not_empty($_POST)) {           
    // validate
    $post = Validation::factory($_POST)
    ->rule('username', 'alpha_numeric')
    ->rule('password', array($this, 'pwdneusr'), array(':validation', ':field', 'username'));              
    if ($post->check()) {
        }
}
1
2
3
4
5
6
7
8
9
// CALLBACK
// validation rule: password != username
public function pwdneusr($validation, $password, $username)
{
    if ($validation[$password] === $validation[$username])
    {
        $validation->error($password, 'pwdneusr');
    }
}

 
Error page

http://kohanaframework.org/3.2/guide/kohana/tutorials/error-pages

Create the views
views/error/404.php / 500.php etc…

Extend the exception handler of Kohana
classes/kohana/exception.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<?php defined('SYSPATH') or die('No direct script access.');
class Kohana_Exception extends Kohana_Kohana_Exception {
    public static function handler(Exception $e)
    {
        if (Kohana::DEVELOPMENT === Kohana::$environment)
        {
            parent::handler($e);
        }
        else
        {
            try
            {
                Kohana::$log->add(Log::ERROR, parent::text($e));
 
                $attributes = array
                (
                    'controller' => 'error',
                    'action'  => 500,
                    'message' => rawurlencode($e->getMessage())
                );
 
                if ($e instanceof HTTP_Exception)
                {
                    $attributes['action'] = $e->getCode();
                }
 
                // Error sub-request.
                echo Request::factory(Route::get('error')->uri($attributes))
                ->execute()
                ->send_headers()
                ->body();
            }
            catch (Exception $e)
            {
                // Clean the output buffer if one exists
                ob_get_level() and ob_clean();
 
                // Display the exception text
                echo parent::text($e);
 
                // Exit with an error status
                exit(1);
            }
        }
    }
}

Create the controller:
classes/controller/error.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php defined('SYSPATH') or die('No direct script access.');
class Controller_Error extends Controller_Template_Nobrand {
    public function before()
    {
        parent::before();
        // Internal request only!
        if (Request::$initial !== Request::$current) {
            if ($message = rawurldecode($this->request->param('message'))) {
                $this->template->message = $message;
            }
        } else {
            $this->request->action(404);
        }
        $this->response->status((int) $this->request->action());
    }
    public function action_404()
    {
        $this->template->title = '404 Not Found';
        $this->template->content = View::factory('error/404' );
    }
    public function action_500()
    {
        $this->template->title = 'Internal Server Error';
        $this->template->content = View::factory('error/500' );
    }
    public function action_503()
    {
        $this->template->title = 'Maintenance Mode';
        $this->template->content = View::factory('error/503' );
    }
}

Edit application/bootstrap.php to add the route:

1
2
3
4
Route::set('error', 'error/<action>(/<message>)', array('action' => '[0-9]++', 'message' => '.+'))
    ->defaults(array(
        'controller' => 'error'
    ));

 
Authentication
Copy modules/auth/config/auth.php to application/config/auth.php

1
2
3
4
5
6
7
return array(
    'driver'       => 'orm',
    'hash_method'  => 'sha256',
    'hash_key'     => 'wigbble',
    'lifetime'     => Date::HOUR * 2,
    'session_key'  => 'auth_user',
);

Schema for mysql / postgresql located:
modules/orm/auth-schema-mysql.sql

Change the rules if you don’t want to required an email (you will also need to remove the index in mysql: uniq_email – BTREE)
Copy modules/orm/classes/model/auth/user.php to application/classes/model/auth/user.php and change the public function rules() to your needs

It’s a good idea to add a new role for your normal user, that way you can list them easily:

1
$p = ORM::factory('role', array('name' => 'participant'))->users->find_all();

Create application/messages/models/user.php

1
2
3
4
5
<?php defined('SYSPATH') or die('No direct script access.');
return array(
    'username.unique'         => 'Username must be unique',
    'email.unique'         => 'Email must be unique',
);

If you want to use the remember feature:

1
2
$remember = isset($post['remember']);
Auth::instance()->login($post['username'], $post['password'], $remember)

then you need to be sure to have a cookie salt in application/bootstrap.php

1
2
3
4
/**
* Cookie salt for remember user info
*/

Cookie::$salt = 'fdsh-tretgd-re-gfds-gt-erg-fdg-';

Some useful stuff:

1
2
3
4
5
6
7
8
9
10
11
12
13
// Add an administrator (in a temporary controller)
$model = ORM::factory('user');
$model->values(array(
    'username' => 'admin',
    'password' => 'admin',
    'password_confirm' => 'admin',
        'email' => 'your@email.com',
));
$model->save();
// remember to add the login role AND the admin role
// add a role; add() executes the query immediately
$model->add('roles', ORM::factory('role')->where('name', '=', 'login')->find());
$model->add('roles', ORM::factory('role')->where('name', '=', 'admin')->find());
1
2
3
4
5
6
7
8
9
// If this user doesn't have the admin role, and is not trying to login, redirect to login
public function before()
{
  parent::before();
  if ( ! Auth::instance()->logged_in('admin') AND Request::current()->uri() !== 'manage')
  {
    $this->request->redirect('/manage');
  }
}
1
2
3
4
// Administrator already logged in, redirect to dashboard
if (Auth::instance()->logged_in('admin')) {
    $this->request->redirect('manage/dashboard');
}
1
2
// Log the user
Auth::instance()->login($post['username'], $post['password'], FALSE)
1
2
// Check if the user have the admin permission
if(!Auth::instance()->logged_in('admin')) {
1
2
// Log user out
Auth::instance()->logout();
1
2
3
4
// check if email or username (automagic) is already taken
if(ORM::factory('user')->unique_key_exists($_POST['username'])) {
       echo "FOUND";
}

 
ORM
http://kohanaframework.org/3.2/guide/orm/
http://karlsheen.com/kohana/kohana-3-orm-tutorial-and-samples/
http://kohanaframework.blogspot.com/2010/12/kohana-3-orm-simple-example.html
http://www.geekgumbo.com/2011/05/24/kohana-3-orm-a-working-example/
http://kohanaframework.org/3.2/guide/api/ORM

ORM is included with the Kohana 3.x install but needs to be enabled before you can use it. In your application/bootstrap.php file modify the call to Kohana::modules and include the ORM modules:

1
'orm' => MODPATH.'orm',

The table name must be in plural;
The table must have an id with auto increment (required);
You must create a Model that extends ORM class (this one not in plural)

1)
Create a table with a “s” as the end:

tracking -> trackings
category -> categories

2)
Create a model (application/classes/model) without the “s”

tracking.php
category.php

1
2
3
4
5
<?php defined('SYSPATH') or die('No direct access allowed.');
class Model_Tracking extends ORM
{
    ...
}
1
2
3
4
5
<?php defined('SYSPATH') or die('No direct access allowed.');
class Model_Category extends ORM
{
    ...
}

3)
Establish your relation (one-to-one, one-to-many etc…)
http://kohanaframework.org/3.2/guide/orm/relationships

4)
Use your model / ORM

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
try
{
    $tracking = ORM::factory('tracking');
    $tracking->user_id = Auth::instance()->get_user()->id;
    $tracking->session_id = Session::instance()->id();
    $tracking->title = ' fdsfdsf ';
    if($tracking->save()) {
        echo "save";
    } else {
        echo "for some reason, there's an error";
    }
  }
catch (ORM_Validation_Exception $e) {
    echo "error";
    var_dump($e->errors());
}

Some useful stuff:

1
2
3
$user = ORM::factory('user');
echo $user->count_all();
echo $user->last_query();
1
2
3
4
$playlists = ORM::factory('playlist')->where('week_id', '=', 1)->find_all();
foreach ($playlists as $playlist) {
    echo $playlist->url;
}

Last ID from ->save();

1
2
$myormmodel->save();
echo $myormmodel->id();

Dynamic ORM query builder

1
2
3
4
5
6
7
8
public function search_keywords(array $keywords)
    {
            foreach($keywords as $keyword)
            {
                    $this->or_where('title', 'like', '%'.$keyword.'%');
            }
            return $this->find_all();
    }

ORM Validation
http://kohanaframework.org/3.2/guide/orm/examples/validation
http://kohanaframework.org/3.2/guide/kohana/security/validation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?php defined('SYSPATH') or die('No direct access allowed.');
class Model_Member extends ORM {
    public function rules()
    {
        return array(
            'username' => array(
                array('not_empty'),
                array('min_length', array(':value', 4)),
                array('max_length', array(':value', 32)),
                array(array($this, 'username_available')),
            ),
            'password' => array(
                array('not_empty'),
            ),
        );
    }
    public function filters()
    {
        return array(
            'password' => array(
                array(array($this, 'hash_password')),
            ),
        );
    }
    public function username_available($username)
    {
        // There are simpler ways to do this, but I will use ORM for the sake of the example
        return ORM::factory('member', array('username' => $username))->loaded();
    }
 
    public function hash_password($password)
    {
        // Do something to hash the password
    }
}

 
Database:
http://kohanaframework.org/3.2/guide/database/
http://kohanaframework.org/3.2/guide/api/Database

There’s 2 ways to query a database: prepared (normal SQL) and query builder (dynamic)

Prepared:

1
2
3
4
5
6
$query = DB::query(Database::SELECT, 'SELECT * FROM users WHERE username = :user AND status = :status');
 
$query->parameters(array(
    ':user' => 'john',
    ':status' => 'active',
));

Query builder:

1
2
3
4
$query = DB::select()->from('users')->where('username', '=', 'john');
$query = DB::select('username')->distinct(TRUE)->from('posts');
$query = DB::select()->from(`posts`)->limit(10)->offset(30);

Results:

1
2
3
4
5
6
$results = DB::select()->from('users')->where('verified', '=', 0)->execute();
foreach($results as $user)
{
    // Send reminder email to $user['email']
    echo $user['email']." needs to verify his/her account\n";
}
1
2
3
4
5
6
$results = DB::select()->from('users')->where('verified', '=', 0)->as_object()->execute();
foreach($results as $user)
{
    // Send reminder email to $user->email
    echo $user->email." needs to verify his/her account\n";
}

Only get 1 result:

1
$total_users = DB::select(array('COUNT("username")', 'total_users'))->from('users')->execute()->get('total_users', 0);
1
2
3
// Get the total number of records in the "users" table
$db = Database::instance();
$count = $db->count_records('testi');

 
3rd party libraries
The convention is to place 3rd party files in application/vendor. For instance, if you had an installation of Doctrine, you would place it in application/vendor/doctrine.

1
2
require Kohana::find_file('vendor', 'Swift-4.0.5/lib/swift_required');
$transport = Swift_SmtpTransport::newInstance(...); // This is autoloaded for me by Swiftmailer

PHPExcel – create PDF, CSV, Excel:
application/vendor/phpexcel/PHPExcel.php & PHPExcel
then in your controller:

1
2
require Kohana::find_file('vendor', 'phpexcel/PHPExcel');
$objPHPExcel = new PHPExcel();

Email – you can use this module:
https://github.com/Luwe/Kohana-Email
or directly use swiftmailer:
http://swiftmailer.org/

1
2
3
4
5
6
7
8
9
10
11
12
require Kohana::find_file('vendor', 'swift/swift_required');
//Create the Transport
$transport = Swift_SmtpTransport::newInstance('localhost', 25);
//Create the Mailer using your created Transport
$mailer = Swift_Mailer::newInstance($transport);
//Create a message
$message = Swift_Message::newInstance('Email')
->setFrom(array('from@email.net' => 'From'))
->setTo(array('to@email.net'))
->setBody('An email');
//Send the message
$result = $mailer->send($message);

 
Helper
http://kohanaframework.org/3.2/guide/api/Arr
If you want to add some custom helper (generally used statically) or library (instantiated / object), for example: application/classes/participants.php

1
2
3
4
5
<?php defined('SYSPATH') or die('No direct script access.');
class Participant {
    static function currentweek() {
    }
}

in your controller:

1
$weektodisplay = Participant::currentweek();

 
Tips
To get the params in a controller (depending on your routes in application/bootstrap.php)

1
$this->request->param('id')

Debug:

1
echo Debug::vars();

To get the current controller:

1
echo Request::current()->uri();

To point at the right directory use:

1
<?php echo URL::base(); ?>

To get a custom column from users (auth):

1
echo Auth::instance()->get_user()->week;

Date:

1
2
Date::formatted_time('now', 'm-d-Y');
//constant Date::WEEK Date::YEAR

Way to use the model and the post for edition in form:

1
2
3
4
5
// Received the POST
if (isset($_POST) && Valid::not_empty($_POST)) {
    // keep but not saved
    $participant->values($_POST, array('email', 'username','password'))
}

To redirect use:

1
$this->request->redirect('manage/dashboard');

To make a link use:

1
<?php echo HTML::anchor('playlist', 'Playlist', array('style' => 'color: #FFF')); ?>

Function inside controller:
inside action_x():

1
array_walk($trackings, array($this, '_replaceplaylistendtime'), $params);

outside action_x():

1
2
3
static function _replaceplaylistendtime(&$value, $key, $p) {
    ...
}

 
Jquery
Use the latest minified version on google server:
http://code.jquery.com/jquery.min.js

User interface:
http://ninjaui.com/
http://jqueryui.com/
http://flowplayer.org/tools/index.html

Ajax:
In your “ajax” controller / action

1
2
3
4
5
if ($this->request->is_ajax()) {
    $id = json_decode($_POST['refresh']);
    $this->auto_render = FALSE;
    echo json_encode(array('result' => $id));
}

In your jquery:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$.ajax({
                type: "POST",
                url: "<?php echo URL::base(); ?>home/refresh",
                data: "refresh=1",
                async: true,
                dataType: "json",
                success: function(resultArray, textStatus, XMLHttpRequest)
                {
                    var result = parseInt(resultArray['result']);
                    alert(result);
                },
                error: function(request, textStatus, errorThrown)
                {
                    alert('error refreshing the session');
                }
});

 
Bookmarks
http://kohanaframework.org/3.2/guide/kohana/tutorials/
http://kohanaframework.org/3.2/guide/api or http://kohana.nerdblog.pl/api/

 
Deploying:
See this for more information about deploying Kohana application
http://nerdblog.pl/2011/09/05/deploying-kohana-3-2-application-in-production/

04

04 2010