Open Power Classes 2.0

Copyright © Invenzzia Group 2008-2009
Available under the terms of license: GNU Free Documentation License 1.2
Generated: 10.08.2009

Table of Contents

Table of Contents
1. Preface
2. Installation
Next »

1. Preface

Open Power Libs project aims to provide a set of well-designed and specialized PHP libraries. The libraries usually provide several ways to extend them with new features and different interfaces to connect with external components. Open Power Classes contains a collection of utility classes for other OPL libraries that are too small to be released as a separate library, but may be useful for many programmers.

Features

Currently, Open Power Classes provides the following components:

Documentation

This document covers Open Power Classes library only. More details about other mentioned libraries can be found in their documentations.

Table of Contents
2. Installation
1. Preface
« Previous
2.1. Standard installation
Next »

2. Installation

OPC can be installed in the same way, as the other OPL libraries, however here we are going to describe this process briefly. You can choose one of two types of install: as a set of files and as PHAR archive (PHP Archive).

Requirements

OPC requires at least PHP 5.2 (we recommend PHP 5.3, because it contains some extra classes that must be emulated on earlier versions). The necessary modules are:

  1. PCRE
  2. SPL
  3. PHAR (only for PHAR version)

All of them are enabled by default since PHP 5.3.

2. Installation
2.1. Standard installation
2. Installation
« Previous
2.2. PHAR installation
Next »

2.1. Standard installation

This chapter describes the installation as a set of PHP files.

Directory structure

In the downloaded archive you can find a directory called /lib with all the necessary OPC and OPL source code. Create in your project directory tree a new directory and copy there the contents of /lib. If you already use other OPL libraries, copy OPC into the existing directory. Do not be afraid to overwrite the files if you are asked to do so. Unless they are modified, there is nothing to worry.

PHP code and the configuration

In the beginning, you must load the OPL core, configure the path to the libraries and set the autoloader. The following code is used then:

<?php
require('./libs/Opl/Base.php'); // 1
Opl_Loader::setDirectory('./libs/'); // 2
Opl_Loader::register(); // 3
 
$opc = new Opc_Class; // 4
// your script
  1. We load the OPL core.
  2. We set the library path. It should end with /, but it is not necessary. We recommend to set the absolute path, because OPL does not use include_path by default. In case of PHP 5.2 this method is required, because it also loads the emulation code for some extra classes from PHP 5.3.
  3. We register the autoloader that will automatically locate and load the classes.
  4. We create the main Open Power Classes object, which is required to be initiated by some classes.

All the OPL libraries report the errors as exceptions. For OPL, the base exception class is Opl_Exception and for OPC - Opc_Exception.

2. Installation
2.2. PHAR installation
2.1. Standard installation
« Previous
3. Classes
Next »

2.2. PHAR installation

This chapter describes installing OPC as PHAR. It is recommended to read the previous chapter, too, because here we will only explain the differences.

PHARs

PHARs (PHP Archives) are special files similar to JAR in Java. In other words, they group several files as one bigger archive. PHP supports PHAR since PHP 5.2.0 after installing the necessary module, and since PHP 5.3.0, PHAR extension is enabled by default.

OPL as PHAR

Because PHARs can do the initial configuration on their own, the startup code is a bit simpler here. All we have to do is to put somewhere the downloaded archives and to include them:

<?php
require('./opl.phar');
require('./opc.phar');
 
try
{
    $opc = new Opc_Class;
 
    // your script
}
catch(Opc_Exception $exception)
{
    Opl_Error_Handler($exception);
}

Even with PHARs, there may be a need to keep additional directory structure for OPL. For example, if an add-on is not available as PHAR, you must put it in the filesystem and inform OPL, where it can find it.

<?php
require('./opl.phar');
require('./opc.phar');
Opl_Loader::setDirectory('./libs/');

The details can be found in OPL documentation.

Table of Contents
3. Classes
2.2. PHAR installation
« Previous
3.1. Opc_Class
Next »

3. Classes

This chapter describes all classes included in OPC.

3. Classes
3.1. Opc_Class
3. Classes
« Previous
3.2. Opc_DoctrineModels
Next »

3.1. Opc_Class

The main class for Open Power Classes. It contains few factories for some classes and some default configuration options for them.

Some of OPC classes also require the existance of Opc_Class instance in the code.

$opc = new Opc_Class;

It is suggested to create an instance of Opc_Class even you use a class which does not require it.

Default configurations

With $opc instance we can now configure some default option values for some classes.

For Opc_View_Cache

cacheDir
Default cache directory.
expiryTime
Cache expiry time. Default: 3600.

For Opc_Paginator

itemsPerPage
Default value for Opc_Paginator_Range->limit - the items per page number. Default: 10.
paginatorDecorator
Default paginator decorator. Defualt: all.
paginatorDecoratorOptions
Default options for default decorator.

Example usage

$opc->cacheDir = dirname(__FILE__).'/cache/';
$opc->expiryTime = 86400;
 
$opc->itemsPerPage = 15;
$opc->paginatorDecorator = 'slider';
$opc->paginatorDecoratorOptions = array(
        'chunk' => 5,
        'around' => 3
);
3. Classes
3.2. Opc_DoctrineModels
3.1. Opc_Class
« Previous
3.3. Opc_Paginator
Next »

3.2. Opc_DoctrineModels

3. Classes
3.3. Opc_Paginator
3.2. Opc_DoctrineModels
« Previous
3.3.1. Usage
Next »

3.3. Opc_Paginator

Opc_Paginator is a class for paginating on data sets.

  1. Opc_Paginator is datasource-independent - no need to create any adapters for arrays, iterators, database etc.
  2. The class provides 6 built-in page range decorators.
  3. Paging outputs are fully customizable.
  4. The class can be easily integrated with Open Power Template 2.
3.3. Opc_Paginator
3.3.1. Usage
3.3. Opc_Paginator
« Previous
3.3.2. Decorators overview
Next »

3.3.1. Usage

As the most of OPC classes, Opc_Paginator requires to have a generic Opc_Class instanted at the beginning of the script.

$opc = new Opc_Class;

Remember to do this only once in whole your script. Otherwise another instances will throw Opc_CannotCreateAnotherInstance_Exception exception.

To create an instance of Opc_Paginator you can use a static factory:

$pager = Opc_Paginator::create($allItemsCount, $itemsPerPage); 

This factory returns a Opc_Paginator_Range object - and it is also allowed to create a direct instance of it:

$pager = new Opc_Paginator_Range($allItemsCount, $itemsPerPage); 

Both methods take as parameters the amount of all items to paginate and items per page number. They are optional and can be provided later.

The second parameter (items per page) when not provided takes a default value from Opc_Class instance configuration. More details can be found here.

Then you should tell your $pager what page number is requested.

$pager->page = isset($_GET['page']) ? $_GET['page'] : 1;

Instead of requested page, you can also provide an offset. It is a number of item to be shown as first in current resultset.

$pager->offset = isset($_GET['offset']) ? $_GET['offset'] : 0;

It is better to use pages instead of an offset. However, both methods are fully supported. Also, don't set both page and offset for your pager, because they overwrite each other.

Now, your pager is ready to work.

Limiting the datasource

All alone pager is nothing without displaying items we paginate. Opc_Paginator does not provide any automatic adapters to limit the datasource but it allows to use offset, page and limit values, which can be used for example in a SQL query.

$result = $conn->query('SELECT * FROM news LIMIT '.$pager->offset.','.$pager->limit);

It is an example of PDO query, but offset and limit can be also used with iterators and LimitIterator:

foreach(new LimitIterator($ItemIterator, $pager->offset, $pager->limit) as $item)
{
    echo $item;
}

The page range

Once we have the pager and limited resultset we can display the page range.

Opc_Paginator uses decorators to create different styles of page ranges. All details about configuring them can be found in this chapter, here we will just present only one of them for this tutorial.

A default decorator is called "All" and it returns all page numbers. Here, we will change it to "Slider".

A default decorator and its options can be defined in global configuration of Opc_Class instance configuration. More details can be found here.

$pager->decorator = 'slider';

decorator option can take three kind of options:

  1. A string alias of registered decorators,
  2. A string class name of a decorator,
  3. An object of decorator.

After providing a one of these values $pager->decorator becomes an object of chosen decorator and allows to be configured. Not every decorrator requires configuring, they also have their default values.

"Slider" is a decorator which returns pages around current page and at the beginning and the end of the range, with a gap between.

$pager->decorator->chunk = 2;
$pager->decorator->around = 1;

Displaying

With decorator defined and configured we can finally display pages. Opc_Paginator_Range is an iterator which returns an array value from decorator. The type of returned value is stored in item array key.

echo '<p>';
foreach($pager as $page)
{
    switch($page['item'])
    {
        case 'current': echo ' <strong>['.$page['number'].']</strong> '; break;
        case 'number': echo ' <a href="?page='.$page['number'].'">'.$page['number'].'</a> '; break;
        case 'gap': echo ' ... '; break;
    }
}
echo '</p>';  

"Slider" returns three value items:

  1. number, which is a page number from "chunk" and "around",
  2. current, which is a current page number,
  3. gap, which is displayed between "chunk" and "around".

The result of above code will look like this:

1 2 ... 6 [7] 8 ... 12 13

We can also display a short info for current page:

echo '<p>Page '.$pager->page.' of '.$pager->pageCount.'</p>';

Navigation links

To make it easier to navigate through all pages, we should also create "previous", "next", "first" and "last" links. They are stored in $pager instance:

if($pager->first)
{
    echo ' <a href="?page='.$pager->first['number'].'">&lArr; first</a> ';
}
if($pager->previous)
{
    echo ' <a href="?page='.$pager->previous['number'].'">&larr; previous</a> ';
}
if($pager->next)
{
    echo ' <a href="?page='.$pager->next['number'].'">next &rarr;</a> ';
}
if($pager->last)
{
    echo ' <a href="?page='.$pager->last['number'].'">last &rArr;</a> ';
}

Navigation links and all decorators items with number value return also an offset, so it is possible to create a pager with offset instead page navigation.

3.3. Opc_Paginator
3.3.2. Decorators overview
3.3.1. Usage
« Previous
3.3.2.1. All
Next »

3.3.2. Decorators overview

Decorator is a class, which is used by the paginator to create a range pages.

Opc_Paginator provides 6 built-in decorators.

Name Alias Class name
All all Opc_Paginator_Decorator_All
Jumper jumper Opc_Paginator_Decorator_Jumper
Slider slider Opc_Paginator_Decorator_Slider
Dotting Slider dotting_slider Opc_Paginator_Decorator_DottingSlider
Range Slider range_slider Opc_Paginator_Decorator_RangeSlider
Stepping Slider stepping_slider Opc_Paginator_Decorator_SteppingSlider

Registering an alias of custom decorator

Opc_Paginator::registerDecorator($aliasName, $className);
3.3.2. Decorators overview
3.3.2.1. All
3.3.2. Decorators overview
« Previous
3.3.2.2. Jumper
Next »

3.3.2.1. All

The simpliest decorator. It returns all page numbers, does not need to be configured.

Returned elements

Item Keys Description
current number Current page number.
offset The offset of current number.
number number Current page number.
offset The offset of current number.

Sample usage

$pager->decorator = 'all';
 
echo '<p>';
foreach($pager as $page)
{
    switch($page['item'])
    {
        case 'current': 
            echo ' <strong>['.$page['number'].']</strong> '; break;
        case 'number': 
            echo ' <a href="?page='.$page['number'].'">'.$page['number'].'</a> '; break;
    }
}
echo '</p>';
The result:

1 2 3 [4] 5 6 7 8

3.3.2. Decorators overview
3.3.2.2. Jumper
3.3.2.1. All
« Previous
3.3.2.3. Slider
Next »

3.3.2.2. Jumper

This decorator "jumps" through steps, returning a range between neighbouring steps.

Settings

Name Type Default Description
stepping integer 10 Number of pages per one step (and in a range)
steps boolean true This setting on "false" makes decorator not return step item.

Returned elements

Item Keys Description
current number Current page number.
offset The offset of current number.
number number Current page number.
offset The offset of current number.
step number Step number. Only with steps setting turned on.
offset The offset of that step.

Sample usage

$pager->decorator = 'jumper';
$pager->decorator->stepping = 10;
$pager->decorator->steps = true;
 
echo '<p>';
foreach($pager as $page)
{
    switch($page['item'])
    {
        case 'current':
            echo ' <strong>['.$page['number'].']</strong> '; break;
        case 'number':
            echo ' <a href="?page='.$page['number'].'">'.$page['number'].'</a> '; break;
        case 'step':
            echo ' <a href="?page='.$page['number'].'"><small>'.$page['number'].'</small></a> '; break;
    }   
}
echo '</p>';
The result:

1 11 21 31 [32] 33 34 35 36 37 38 39 40 41 51 61 71

3.3.2. Decorators overview
3.3.2.3. Slider
3.3.2.2. Jumper
« Previous
3.3.2.4. Dotting Slider
Next »

3.3.2.3. Slider

"Slider", as its name says, slides through all pages, displaying numerical pages at the beginning and the end and around the current page. It also returns a "gap" between those ranges.

Settings

Name Type Default Description
around integer 2 Number of pages around current
chunk integer 3 Number of pages at the begin and the end

Returned elements

Item Keys Description
current number Current page number.
offset The offset of current number.
number number Current page number.
offset The offset of current number.
gap Item for displaying the gap between number ranges.

Sample usage

$pager->decorator = 'slider';
$pager->decorator->chunk = 3;
$pager->decorator->around = 2;
 
echo '<p>';
foreach($pager as $page)
{
    switch($page['item'])
    {
        case 'current':
            echo ' <strong>['.$page['number'].']</strong> '; break;
        case 'number':
            echo ' <a href="?page='.$page['number'].'">'.$page['number'].'</a> '; break;
        case 'gap': 
            echo " ... "; break;
    }   
}
echo '</p>';  
The result:

1 2 3 ... 29 30 [31] 32 33 ... 75 76 77

3.3.2. Decorators overview
3.3.2.4. Dotting Slider
3.3.2.3. Slider
« Previous
3.3.2.5. Range Slider
Next »

3.3.2.4. Dotting Slider

Dotting slider is a combination of "all" and "slider" decorators. Current page slides through all numbers but dotting slider returns also a "dot" item on every page number out of "around" and "chunk", which can be displayed as a clickable link.

Settings

Name Type Default Description
around integer 2 Number of pages around current
chunk integer 3 Number of pages at the begin and the end

Returned elements

Item Keys Description
current number Current page number.
offset The offset of current number.
number number Current page number.
offset The offset of current number.
dot number Page number under the dot.
offset The offset of that dot.

Sample usage

$pager->decorator = 'dotting_slider';
$pager->decorator->chunk = 3;
$pager->decorator->around = 2;
 
echo '<p>';
foreach($pager as $page)
{
    switch($page['item'])
    {
        case 'current':
            echo ' <strong>['.$page['number'].']</strong> '; break;
        case 'number':
            echo ' <a href="?page='.$page['number'].'">'.$page['number'].'</a> '; break;
        case 'dot':
            echo '<a href="?page='.$page['number'].'">.</a>'; break;
    }   
}
echo '</p>';
The result:

1 2 3 ........ 12 13 [14] 15 16 ..... 22 23 24

All dots are links to pages.

3.3.2. Decorators overview
3.3.2.5. Range Slider
3.3.2.4. Dotting Slider
« Previous
3.3.2.6. Stepping Slider
Next »

3.3.2.5. Range Slider

Range slider is a next variation of "slider" decorator. It allways returns a defined number of pages, even if the current is at the beginning, in the middle or at the end.

Settings

Name Type Default Description
range integer 9 Number of pages in range.

Returned elements

Item Keys Description
current number Current page number.
offset The offset of current number.
number number Current page number.
offset The offset of current number.

Sample usage

$pager->decorator = 'range_slider';
$pager->decorator->range = 9;
 
echo '<p>';
foreach($pager as $page)
{
    switch($page['item'])
    {
        case 'current':
            echo ' <strong>['.$page['number'].']</strong> '; break;
        case 'number':
            echo ' <a href="?page='.$page['number'].'">'.$page['number'].'</a> '; break;
    }
}
echo '</p>';
The results:

1 [2] 3 4 5 6 7 8 9

27 28 29 30 [31] 32 33 34 35

3.3.2. Decorators overview
3.3.2.6. Stepping Slider
3.3.2.5. Range Slider
« Previous
3.3.3. Integration with Open Power Template 2
Next »

3.3.2.6. Stepping Slider

"Stepping slider" is similar to "slider", but instead of a "gap" it returns a page "step" item.

Settings

Name Type Default Description
around integer 2 Number of pages around current
chunk integer 3 Number of pages at the begin and the end
stepping integer 10 Number of pages per one step

Returned elements

Item Keys Description
current number Current page number.
offset The offset of current number.
number number Current page number.
offset The offset of current number.
step number Step number.
offset The offset of that step.

Sample usage

$pager->decorator = 'stepping_slider';
$pager->decorator->chunk = 3;
$pager->decorator->around = 2;
$pager->decorator->stepping = 10;
 
echo '<p>';
foreach($pager as $page)
{
    switch($page['item'])
    {
        case 'current':
            echo ' <strong>['.$page['number'].']</strong> '; break;
        case 'number':
            echo ' <a href="?page='.$page['number'].'">'.$page['number'].'</a> '; break;
        case 'step':
            echo ' <a href="?page='.$page['number'].'"><small>'.$page['number'].'</small></a> '; break;
    }   
}
echo '</p>';
The result:

1 2 3 10 20 29 30 [31] 32 33 40 50 60 70 75 76 77

3.3. Opc_Paginator
3.3.3. Integration with Open Power Template 2
3.3.2.6. Stepping Slider
« Previous
3.4. Opc_Translate
Next »

3.3.3. Integration with Open Power Template 2

Using Opc_Paginator with Open Power Template 2 is really easy. You don't need to add any adapter of change the class. The only work you need to do in the PHP side is to define data formats:

$view = new Opt_View('news.tpl');
 
$pager = Opc_Paginator::create(1000, 13);
$pager->page = isset($_GET['page']) ? $_GET['page'] : 1;
 
$view->pager = $pager;
$view->setFormat('pager', 'Objective/Array'); 
$view->setFormat('pager.decorator', 'Objective'); 

As OPC is in early development stage, setting dataformats isn't "user-friendly". We will later work on custom "Paginator" dataformat. But by now it must be defined in this way.

On the template side Opc_Paginator excellently works with opt:selector instruction. It is also easy to change a decorator and set it's options.

<p>
{$pager.decorator is 'slider'}
{$pager.decorator.chunk is 5}
<opt:selector name="pager">
    <opt:number> <a parse:href="'?page='~$pager.number">{$pager.number}</a> </opt:number>
    <opt:current> <strong>[{$pager.number}]</strong> </opt:current>
    <opt:gap> ... </opt:gap>
</opt:selector>
</p>

Item types become <opt:itemName> nodes.

Working with snippets

It isn't necessary to repeat the design for decorators all the time, because OPT2 provides a system called "snippets". Snippets are pieces of code which can be reused in different contextes.

<opt:snippet name="pagerSlider">
    <opt:number> <a parse:href="'?page='~$pagerSlider.number">{$pagerSlider.number}</a> </opt:number>
    <opt:current> <strong>[{$pagerSlider.number}]</strong> </opt:current>
    <opt:gap> ... </opt:gap>
</opt:snippet>
 
<opt:snippet name="pagerSteppingSlider">
    <opt:number> <a parse:href="'?page='~$pagerSteppingSlider.number">{$pagerSteppingSlider.number}</a> </opt:number>
    <opt:current> <strong>[{$pagerSteppingSlider.number}]</strong> </opt:current>
    <opt:step> <a parse:href="'?page='~$pagerSteppingSlider.number"><small>{$pagerSteppingSlider.number}</small></a> </opt:step>
</opt:snippet>

Then we can use those snippets with pagers:

{$pager1.decorator is 'slider'}
<p><opt:selector name="pager1" opt:use="pagerSlider" /></p>
 
{$pager2.decorator is 'stepping_slider'}
<p><opt:selector name="pager2" opt:use="pagerSteppingSlider" /></p>
3. Classes
3.4. Opc_Translate
3.3.3. Integration with Open Power Template 2
« Previous
3.5. Opc_View_Cache
Next »

3.4. Opc_Translate

3. Classes
3.5. Opc_View_Cache
3.4. Opc_Translate
« Previous
3.6. Opc_Visit
Next »

3.5. Opc_View_Cache

3. Classes
3.6. Opc_Visit
3.5. Opc_View_Cache
« Previous
3.7. Opc_Visit_UserAgent
Next »

3.6. Opc_Visit

Opc_Visit is a class which provides unified data about some request parameters.

Opc_Visit requires to have a generic Opc_Class instanted at the beginning of the script.

$opc = new Opc_Class;

Remember to do this only once in whole your script. Otherwise another instances will throw Opc_CannotCreateAnotherInstance_Exception exception.

This class implements singleton, so to have the access to its instance you have to write:

$visit = Opc_Visit::getInstance();

Now you can read values:

echo $visit->ip;
 
if($visit->secure)
{
    echo 'secure connection';
}
 
setcookie('cookie_name', 'value', time()+3600, $visit->cookiePath, $visit->cookieServer);

You can retrieve all data with toArray() method:

echo '<pre>';
var_dump($visit->toArray());
echo '</pre>';

Available data

Name Description
ip Dot-decimal client's IP.
numericIp Decimal client's IP.
host Client's host.
protocol Current request protocol.
referrer The referring page.
port Server's port.
secure Is secure connection? It checks if port == 443.
requestMethod Current request method.
userAgentString Client's user agent string.
userAgent Client's detected browser and OS. See Opc_Visit_UserAgent.
languages Array of accepted languages, sorted by quality.
mimeTypes Array of supported mime types.
cookieServer Server name for cookies.
cookiePath Path for cookies.
currentAddress Full request address.
currentFile Executed file.
currentParams Path info + query string or full address from rewriting.
currentPath Full path with host.
basePath Full path minus the host.
pathInfo Current path info.
queryString Current query string.
fileName Executed file's name.
3. Classes
3.7. Opc_Visit_UserAgent
3.6. Opc_Visit
« Previous
4. API reference
Next »

3.7. Opc_Visit_UserAgent

Opc_Visit_UserAgent is an user agent string analyzer. It detects most of popular web browsers and operating systems.

Example code:
$userAgentString = 'Opera/9.80 (Windows NT 5.1; U; pl) Presto/2.2.15 Version/10.00';
$agent = Opc_Visit_UserAgent::analyze($userAgentString);
 
print_r($agent);
The result:
Array
(
    [browser] => Array
        (
            [name] => Opera
            [version] => 10.00
            [extra] => 
        )

    [os] => Array
        (
            [system] => Windows
            [name] => XP
            [version] => 
            [extra] => 
        )

)

When Opc_Visit_UserAgent can't recognize a browser or an OS it returns unknown value under [browser][name] and [os][system].

Table of Contents
4. API reference
3.7. Opc_Visit_UserAgent
« Previous
5. Appendix
Next »

4. API reference

This chapter provides the core API reference.

Table of Contents
5. Appendix
4. API reference
« Previous
A. Support
Next »

5. Appendix

This chapter contains some extra information about the project.

5. Appendix
A. Support
5. Appendix
« Previous
B. Reporting bugs
Next »

Appendix A. Support

If you have a problem with the OPL library and do not know how to solve it, take a look at our discussion board, forums.invenzzia.org - we will try to help you find the solution and talk about many other things.

Support rules

5. Appendix
B. Reporting bugs
A. Support
« Previous
C. License and authors
Next »

Appendix B. Reporting bugs

If you found a bug, please visit our bugtracker: bugs.invenzzia.org and report it. You will help developing the library.

How to use the bugtracker?

  1. We use the same bugtracker for various projects. Be sure that you add the report to the correct project.
  2. If it is possible, the report should contain a standalone test case that is ready to run. This will speed up reproducing the bug on our computers and creating the patch. If we cannot reproduce the bug, probably it will not be fixed.
  3. Include the information on OPL and PHP versions, as well as other projects that could interfere with the library.
  4. Please describe the expected behavior and the actual result.
  5. We include the full error message, if it is provided.
  6. The report must be written in English.
  7. Remember: if we need extra information, we will ask for them.
5. Appendix
C. License and authors
B. Reporting bugs
« Previous

Appendix C. License and authors

Open Power Classes was designed and created by the Invenzzia programming group which is also the holder of the copyrights. The people that worked on this:

Copyright © Invenzzia Group 2008-2009 - www.invenzzia.org

License

Open Power Classes 2.0 is available under the terms of new BSD license. It is included in the library archives.

This documentation is available under the terms of GNU Free Documentation License 1.2. Its content is included in the library archives and the source files are available to download on the Invenzzia website.