Here’s a Powered by PHPixie icon that you can use if you like, I’ll be adding more of these so they can fit any design. this is the colorful one:
Powered by PHPixie icon
A new authentication and authorization module has been released. It will help you to easily implement user login and access control based on user roles. Currently it allows logging in using the login/password approach and using Facebook login. As for the access control, you can configure roles both as ORM models with relationships to your user model, or by simply having a role column in your users table.
The modules is itself modular, so it’s very easy to add your own login providers or role drivers. The included Facebook lgoin controller can be extended or modified to facilitate almoast any OAuth authorization (e.g. Twitter). there is also a small tutorial for the basic Auth setup included in the module section.
Also PHPixie version is 1.70 now, aside from bugfixes it includes 3 usefull methods:
Note that these methods are all instance methods and not static, the ‘::’ notation is just to show the class they belong to.
It is now possible to pass variables, or any kinda of expression for that matter, to partials. E.g you can now do this:
1
2
- $subview='pixielist'
partial:$subview
Of course you can pass the subview variable from the controller, there is nothing special about it. If you have been using the haml module there is one small change you have to make before updating to this version: since partials are now treated as expressions you have to put template names into quotes, e.g.:
1
2
3
4
5
//Old way
partial:fairy
//New way
partial:'fairy'
I started some work on a blog system that would operate on simple files (using markdown syntax) and not use any database at all. The purpose was to give everyone who wants to write something about web development or actually any topic some space.
You can see the site at http://hollow.phpixie.com and the best part is that you can write your own posts on it, so if you have something to share, like a project you want to showcase, a tutorial, anything really, you just fork Hollow on Github, and write your posts inside the /posts folder, just remember to prfix them with the date like 20130326_Welcome.md. To add a category, just create a subfolder inside it. The really important part is that everyone can edit your post by forking it, so it’s more or less like a wiki. I will accept pull requests as soon as they arrive so you won’t have to wait long for your posts to appear on the site =).
Of course you can always download the code and set it up as your own website if you want to.
In it’s most simple form an XSS attack is passing pieces of HTML along with form input to alter page behavior in a malicios way. Consider someone registering an account on your site and using this as his username:
1
Attack<script>alert('hacked');</script>
Whenever that persons username would be displayed on the site it would be possible for it to trigger an alert, a more cunning attacker can get all sorts of things done this way. Usually you have to filter user input to prevent this, PHPixie does that by default for you now, by executing strip_tags() on all input data you access via post() and get() methods. You can still access the raw input if you wish though.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Home_Controller extends Controller{
//.....
public function action_save(){
//If username is entered to be
//'Pixie<script></script>'
//This will just return 'Pixie'
$safe=$this->post('username');
//Setting the third parameter to false
//returns the raw input
$raw=$this->post('username',null,false);
}
}
If your website actually allows users to enter HTML, for example if you are making a blog, you probably want to get the raw input and then filter it yourself stripping away only the malicious pieces, there are a lot of XSS protection libraries that allow you to do so.
The database module now select subqueries, which means you can use query builder to write practically any query you like. Let’s take a quick look at some new features:
Subqueries in conditional statements
1
2
3
4
5
6
7
8
DB::query('select')
->table('fairies')
//WHERE id in (SELECT fairy_id from trees)
->where('id','IN',DB::query('select')
->fields('fairy_id')
->table('trees')
);
Subqueries as tables
1
2
3
4
5
6
7
8
9
10
$pixies=DB::query('select')
->table('fairies')
->where('type','pixie');
DB::query('select')
//Specifying an alias for the subquery select
->table($pixies,'pixies')
->where('pixies.id','>',7);
It is also possible to pass subqueries into join() in a similar way
UNION queries
1
2
3
4
5
6
7
8
$pixies=DB::query('select')
->table('fairies')
->where('type','pixie');
DB::query('select')
->table('fairies')
->where('type','fairy')
->union($pixies);
To see more examples check out the updated Database Tutorial.
If your site has a lot of links, making changes to URL structure can become really frustrating, as you will have to change links in all your views to reflect the new page locations. Now ou can use reverse routing to generate urls based on parameters like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
//Will generate /fairies/view/7
Route::get('default')->url(array(
'controller'=>'fairies',
'action'=>'view',
'id'=>7
));
//You can ommit default and optional parameters
//so this will generate simply /home/list
//(provided controller defaults to 'home'
Route::get('default')->url(array(
'action'=>'list'
));
You can find more information about routes in the PHPixie Routing tutorial.
Flash messagesare a simple way to set a message to be displayed to a user on a different page. For example after successfully editing an article you may want to redirect the user to a listing page, while also notifying him that his changes have been saved. The important part here is that these messages should appear only once, so when the user refreshes the page he is on the message will not be there anymore. Here is how you can now use them in PHPixie:
1
2
3
4
5
//Setting a flash message
Session::flash('success',"You have added a fairy");
//Retrieving the message and assigning it to a view.
$view->success_message=Session::flash('success');
Inside the view you can then do this:
1
2
3
4
5
<?php if($success_message): ?>
<div id="message">
<?php echo $success_message; ?>
</div>
<?php endif; ?>
Or you may check the session directly inside the view, skipping passing the variable from controller:
1
2
3
4
5
<?php if($message = Session::flash('success')): ?>
<div id="message">
<?php echo $message; ?>
</div>
<?php endif; ?>
As of now PHPixie is fully unit tested, so this ads an additional layer of defense against bugs. While writing these unit tests I also noticeed quite a few places where I could make the code better, so there were some internal changes too. Unit tests of additional modules (e.g. Cache ) are coming soon too.
Caching is a great way to reduce the load on your webserver and make your site run faster. PHPixies’ cache module comes with support of 4 drivers:
Of course APC and XCache will provide you with the most speed, but they require additional plugins to be added to your PHP installation. Caching into files works great for large data like arrays, HTML fragments, etc. Storing into the database is useful if you want to have your cache easily portable (as you can cache into SQLite files) and works best for scenarios where you have to cache a lot of small data, e.g. number of users online etc.
Using this module is very simple, first you need to configure your cache:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// /application/config/cache.php
<?php
return array(
'default' => array(
//Supprted drivers are: apc, database, file, xcache
'driver' => 'file',
//Default liefetime for cached objects in seconds
'default_lifetime' => 3600,
//Cache directory for 'file' driver
'cache_dir' => ROOTDIR.'/modules/cache/cache/',
//Database connection name for 'database' driver
'connecton' => 'default'
)
);
You can define more than one caching profile, but the ‘default’ one can be easily accessed via these methods:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//Caching an array of fairies with 7000 seconds lifetime
Cache::set('fairies',array('Tinkerbell','Trixie'),7000);
//Retrieving fairies from cache. If they are not found
//in cache or have expired return the default value (empty array)
Cache::get('fairies',array());
//Delete a cached object
Cache::delete('fairies');
//Clear all cache
Cache::clear();
//Remove expired objects.
//If you are using database or file cache
//you might want to set up a cron job to call
//this method from time to time to clear expired data.
//APC and XCache remove expired items automatically
Cache::garbage_collect();
If you set up more than one caching profile you can access them in two ways:
1
2
3
4
5
6
//By passing a profile parameter
Cache::set('fairies',array('Tinkerbell','Trixie'),7000,'custom_profile');
//Or by using an instance
$cache=Cache::instance('custom_profile');
$cache->set('fairies',array('Tinkerbell','Trixie'),7000);
Note that not all objects can be cached. Only serializable objects can be cached, that’s why you should convert database and ORM results into arrays or generic objects before storing them (they cannot be serialized as of yet because they depend on having a link to the database), e.g.:
1
2
3
4
5
6
7
8
9
10
//You can use as_array() to convert database result into array
Cache::set('fairies',DB::query('select')
->table('fairies')
->execute()
->as_array());
//Or as_array(true) to convert ORM result into an array
Cache::set('fairies',ORM::factory('fairy')
->find_all()
->as_array(true));
Extended support for caching ORM results without converting them to arrays will be added soon.