Subversion Repositories ezqrcode

Compare Revisions

Ignore whitespace Rev 1 → Rev 5

/tags/1.0-alpha2/handlers/datatypes/ezgmaplocation.php New file
0,0 → 1,29
<?php
/**
* Formats geographical informations from an ezgmaplocation attribute
*
* Output format: "geo:lat,lon"
*/
class eZQRDatatypeGmapLocation extends eZQRDatatype
{
/**
* Get the mapped data in a QR code compatible format
* @return string The barcode data, or an empty string
*/
public function data()
{
if ( $this->contentObjectAttribute->hasContent() )
{
$content = $this->contentObjectAttribute->content();
$return = sprintf( 'geo:%s,%s',
$content->attribute( 'latitude' ), $content->attribute( 'longitude' ) );
}
else
{
$return = '';
}
 
return $return;
}
}
?>
/tags/1.0-alpha2/settings/qrcode.ini New file
0,0 → 1,4
#?ini charset="utf-8"?
 
[Datatypes]
Mapping[ezgmaplocation]=eZQRDatatypeGmapLocation
/tags/1.0-alpha2/settings/site.ini.append.php New file
0,0 → 1,6
<?php /* #?ini charset="utf-8"?
 
[TemplateSettings]
ExtensionAutoloadPath[]=ezqrcode
 
*/ ?>
/tags/1.0-alpha2/tests/suite.php New file
0,0 → 1,11
<?php
class eZQRCodeTestSuite extends ezpTestSuite
{
public function __construct()
{
parent::__construct();
$this->setName( "ezqrcode extension test suite" );
$this->addTestSuite( 'eZQRCodeTest' );
}
}
?>
/tags/1.0-alpha2/tests/qrcode_test.php New file
0,0 → 1,73
<?php
class eZQRCodeTest extends ezpTestCase
{
/**
* Global data provider for generic __set tests
*/
public static function providerForSetTest()
{
return array(
// PROPERTY: size
 
// valid input array/string
array( 'size', '10x10', array( 10, 10 ) ),
array( 'size', array( 20, 20 ), array( 20, 20 ) ),
 
// invalid input array/string
array( 'size', array( 1, 2, 3 ), null, 'ezcBaseValueException' ),
array( 'size', '10x10x10', null, 'ezcBaseValueException' ),
 
// PROPERTY: error_correction_level
// valid input strings
array( 'error_correction_level', 'L', 'L' ),
array( 'error_correction_level', 'M', 'M' ),
array( 'error_correction_level', 'Q', 'Q' ),
array( 'error_correction_level', 'H', 'H' ),
 
// invalid input strings
array( 'error_correction_level', '', null, 'ezcBaseValueException' ),
array( 'error_correction_level', 'A', null, 'ezcBaseValueException' ),
array( 'error_correction_level', 4, null, 'ezcBaseValueException' ),
 
// PROPERTY: margin
array( 'margin', 1, 1 ),
array( 'margin', 5, 5 ),
array( 'margin', '', null, 'ezcBaseValueException' ),
array( 'margin', 'A', null, 'ezcBaseValueException' ),
 
// PROPERTY: encoding
array( 'encoding', 'UTF-8', 'UTF-8' ),
array( 'encoding', 'Shift_JIS', 'Shift_JIS' ),
array( 'encoding', 'ISO-8859-1', 'ISO-8859-1' ),
array( 'encoding', 'somestring', null, 'ezcBaseValueException' ),
 
// PROPERTY: data
array( 'data', 'http://ez.no', 'http://ez.no' ),
);
}
 
/**
* @dataProvider providerForSetTest
*/
function testSet( $property, $value, $expectedValue, $expectedException = null )
{
if ( $expectedException !== null )
$this->setExpectedException( $expectedException );
 
$qr = new eZQRCode();
$qr->$property = $value;
if ( $expectedValue !== null )
$this->assertEquals( $qr->$property, $expectedValue );
}
 
function testGetChartURI()
{
$qr = new eZQRCode();
$qr->size = '100x100';
$qr->data = 'http://ez.no';
 
$this->assertEquals( $qr->getChartURI(), 'http://chart.apis.google.com/chart?cht=qr&chs=100x100&chl=http%3A%2F%2Fez.no' );
}
}
 
?>
/tags/1.0-alpha2/doc/google_charts_api_qrcode_specifications.txt New file
0,0 → 1,38
=========================================================
API Specification for Google charts API QRCode generation
=========================================================
 
Example URL
===========
http://chart.apis.google.com/chart?cht=qr&chs=100x100&chl=http%3A%2F%2Fwww.ez.no
 
Parameters
==========
 
Chart type
----------
cht=qr
Chart type = QRCode
 
Chart size
----------
chs=50x50
Chart size, 50x50 pixels
 
Chart correction level
----------------------
chld=L|1
Chart correction level + margin. L = 7% error correction (default), 1 = margin in rows, default = 4
 
Chart data encoding
-------------------
 
choe=UTF-8
Data encoding. Default = UTF-8
 
Chart data
----------
chl=<data>
Chart data
 
Note: an URL has a max length of 2K. Use POST for larger data set.
/tags/1.0-alpha2/doc/handlers.txt New file
0,0 → 1,43
=====================
QR Code data handlers
=====================
 
QR codes by themselves require strings as input. These strings may vary a *lot*. For instance, URLs can be provided with
at least three different syntax.
 
The main point of this extension is that it should be easy and quick to transfer CMS content to a QR code.
 
This is why handlers are required for datatypes, content classes...
 
Datatype handlers
=================
 
Datatype handlers are easy. Given one content object attribute, a handler will return a string that can be interpreted
by QR aware devices.
 
This is made possible by QRDatatype handlers.
 
Base, abstract class: eZQRDatatype
----------------------------------
 
This class is the base item when it comes to implementing a handler. It has to implement at least one method::
 
public function data();
 
This method returns a string that will be the data for the QR code. The class makes available a member variable named
``contentObjectAttribute``, that contains the currently handled content object attribute.
 
Settings: qrcode.ini
--------------------
 
This handler then needs to be mapped to a datatype. This is done in a very standard way, using an array in qrcode.ini.
 
This code example, in qrcode.ini, would map the eZQRDatatypeStuff handler to the ezstuff datatype::
 
[Datatypes]
Mapping[ezstuff]=eZQRDatatypeStuff
 
Content classes
===============
 
To be determined :)
/tags/1.0-alpha2/README.txt New file
0,0 → 1,42
==========
eZ QR Code
==========
 
Author: Bertrand Dunogier, eZ Systems
 
Synopsis
========
 
This extension provides an API as well as the ezpublish features to generate QR Codes based on content.
 
What are QR Codes
=================
QR Codes are two dimensional bar codes, created by Denso-Wave in 1994 (thank you Wikipedia). These codes can contain a
large variety of data: URLs, vCards, geographical data, etc, and have been picked up by google for Android based
devices. As an example, you can see on http://code.google.com/ that any downloadable file has a QR code image.
 
QR codes can be scanned using a hand held device, which will then propose an action based on the decrypted data:
open an URL, install an app, etc.
 
This extension
==============
 
Google chart API
----------------
 
The current implementation only uses the google chart API. This very simple API allows you to provide an URL with a few
fields regarding the desired chart, and get an image in return. While this is far from perfect when it comes to data
privacy, it does the job.
 
Implementation
--------------
ezqrcode is very simple at the moment.
 
It has a base class, eZQRCode, that can be used to set all the available parameters: size, error correction, data, etc.
Based on this, the class will return the URL for the image on chart.apis.google.com.
 
This class is currently only implemented in a template operator named qrcode::
 
{'http://share.ez.no/'|qrcode( "200x200" )}
 
Will return a link to the QR code for the URL share.ez.no.
/tags/1.0-alpha2/autoloads/operators.php New file
0,0 → 1,117
<?php
class eZQRCodeOperators
{
function eZQRCodeOperators()
{
$this->Operators = array( 'qrcode' );
}
 
function &operatorList()
{
return $this->Operators;
}
 
function namedParameterPerOperator()
{
return true;
}
 
function namedParameterList()
{
return array( 'qrcode' => array( 'size' => array( 'type' => 'mixed',
'required' => true ) ) );
}
 
function modify( $tpl, $operatorName, $operatorParameters, $rootNamespace,
$currentNamespace, &$operatorValue, $namedParameters, $placement )
{
switch ( $operatorName )
{
case 'qrcode':
{
$operatorValue = $this->getQRCode( $operatorValue, $namedParameters );
} break;
}
}
 
/**
* Returns the URL for the given parameters
*/
function getQRCode( $data, $parameters )
{
$qr = new eZQRCode();
 
try
{
$qr->size = $parameters['size'];
} catch ( Exception $e ) {
eZDebug::writeError( (string)$e );
return null;
}
 
// basic string
if ( is_string( $data ) )
{
$qr->data = $data;
}
 
// object
elseif( is_object( $data ) )
{
// content object attribute
if ( $data instanceof eZContentObjectAttribute )
{
$datatypeString = $data->attribute( 'data_type_string' );
switch ( $datatypeString )
{
case 'ezstring':
$qr->data = $data->attribute( 'content' );
break;
 
case 'ezemail':
$qr->data = "mailto:" . $data->attribute( 'content' );
break;
 
case 'ezurl':
$qr->data = $data->attribute( 'content' );
break;
 
default:
$handlerOptions = new ezpExtensionOptions();
$handlerOptions->iniFile = 'qrcode.ini';
$handlerOptions->iniSection = 'Datatypes';
$handlerOptions->iniVariable = 'Mapping';
$handlerOptions->handlerIndex = $datatypeString;
$handlerOptions->handlerParams = array( $data );
 
$handler = eZExtension::getHandlerClass( $handlerOptions );
 
if ( is_object( $handler ) )
{
$qr->data = $handler->data();
}
else
{
eZDebug::writeError( "No handler was found for datatype '$datatypeString'", __METHOD__ );
return '';
}
}
}
else
{
eZDebug::writeError( "The qrcode operator only supports eZContentObjectAttribute objects", __METHOD__ );
return '';
}
}
 
try
{
return $qr->getChartURI();
} catch ( Exception $e ) {
eZDebug::writeError( (string)$e );
return null;
}
}
}
 
?>
/tags/1.0-alpha2/autoloads/eztemplateautoload.php New file
0,0 → 1,7
<?php
$eZTemplateOperatorArray = array();
 
$eZTemplateOperatorArray[] = array( 'script' => eZExtension::baseDirectory() . '/ezqrcode/autoloads/operators.php',
'class' => 'eZQRCodeOperators',
'operator_names' => array( 'qrcode' ) );
?>
/tags/1.0-alpha2/extension.xml New file
0,0 → 1,21
<?xml version="1.0" encoding="utf-8" ?>
<software>
<metadata>
<name>eZ QR Code</name>
<version>1.0-alpha</version>
<copyright>Copyright (c) Bertrand Dunogier 2010</copyright>
<license>GNU General Public License v2.0</license>
<info_url>http://projects.ez.no/ezqrcode</info_url>
 
<software>
<uses>
<name>Google chart API</name>
<license>N/A</license>
<copyright>Google, I guess</copyright>
<info_url>http://code.google.com/apis/chart/docs/gallery/chart_gall.html</info_url>
<version>N/A</version>
</uses>
</software>
 
</metadata>
</software>
/tags/1.0-alpha2/classes/qrcode.php New file
0,0 → 1,152
<?php
/**
* QRCode encoder based on the google charts API.
* @see doc/google_charts_api_qrcode_specifications.txt
* @see http://code.google.com/apis/chart/docs/gallery/qr_codes.html
*
* @property string data Required.
* @property size Either a width/height array, or a WIDTHxHEIGHT string. Required.
* @property string encoding Howw to encode data in the chart. Values: UTF-8 (default), Shift_JIS or ISO-8859-1
* @property string error_correction_level L (default, M, Q or H)
* @property int margin Margin rows (not pixels). Default = 4. Optional.
* @property-read string size_string string value for the size, as <width>x<height>
*/
class eZQRCode
{
public function __construct()
{
 
}
 
public function __set( $property, $value )
{
switch( $property )
{
case 'data':
$this->properties[$property] = $value;
break;
 
case 'size':
if ( is_array( $value ) )
{
if ( count( $value ) != 2 || !is_numeric( $value[0] ) || !is_numeric( $value[1] ) )
{
throw new ezcBaseValueException( $property, $value, 'array( (int)width, (int)height )' );
}
else
{
$this->properties[$property] = $value;
}
}
else
{
if ( !preg_match( '/^([0-9]+)x([0-9]+)$/', $value, $matches ) )
{
throw new ezcBaseValueException( $property, $value, '<width>x<height> )' );
}
else
{
$this->properties[$property] = array( $matches[1], $matches[2] );
}
}
break;
 
case 'error_correction_level':
if ( strlen( $value ) != 1 || strstr( 'LMQH', $value ) === false )
{
throw new ezcBaseValueException( $property, $value, 'L, M, Q or H' );
}
else
{
$this->properties[$property] = $value;
}
break;
 
case 'margin':
if ( !is_numeric( $value ) )
{
throw new ezcBaseValueException( $property, $value, 'integer' );
}
else
{
$this->properties[$property] = $value;
}
break;
 
case 'encoding':
if ( !is_string( $value ) )
{
throw new ezcBaseValueException( $property, $value, 'string' );
}
elseif ( !in_array( $value, array( 'UTF-8', 'Shift_JIS', 'ISO-8859-1' ) ) )
{
throw new ezcBaseValueException( $property, $value, 'string( UTF-8, Shift_JIS, ISO-8859-1)' );
}
else
{
$this->properties[$property] = $value;
}
break;
 
default:
throw new ezcBasePropertyNotFoundException( $property );
}
}
 
public function __get( $property )
{
switch( $property )
{
case 'data':
case 'size':
case 'margin':
case 'error_correction_level':
case 'encoding':
return $this->properties[$property];
break;
case 'size_string':
if ( !isset( $this->size ) )
return '';
else
return "{$this->size[0]}x{$this->size[1]}";
 
default:
throw new ezcBasePropertyNotFoundException( $property );
}
}
 
public function __isset( $property )
{
return isset( $this->properties[$property] );
}
 
public function getChartURI()
{
if ( !isset( $this->data ) )
throw new ezcBaseValueException( 'data', 'none', 'data' );
if ( !isset( $this->size ) )
throw new ezcBaseValueException( 'size', 'none', 'size' );
$baseURI = 'http://chart.apis.google.com/chart?cht=qr&';
 
$URIParameters[] = "chs={$this->size_string}";
$URIParameters[] = 'chl=' . urlencode( $this->data );
 
if ( isset( $this->encoding ) )
$URIParameters[] = 'choe=' . urlencode( $this->encoding );
 
if ( isset( $this->error_correction_level ) || isset( $this->margin ) )
{
$URIParameters[] = 'chld=' .
isset( $this->error_correction_level ) ? $this->error_correction_level : self::DefaultErrorCorrectionLevel .
'|' .
isset( $this->margin ) ? $this->margin : self::DefaultMargin;
}
$uri = $baseURI . implode( '&', $URIParameters );
return $uri;
}
 
private $properties = array();
const DefaultErrorCorrectionLevel = 'L';
const DefaultMargin = 4;
}
?>
/tags/1.0-alpha2/classes/qrdatatype.php New file
0,0 → 1,28
<?php
/**
* Abstract class for datatype handlers
*/
abstract class eZQRDatatype
{
/**
* Mapped content object attribute
* @var eZContentObjectAttribute
*/
protected $contentObjectAttribute;
 
/**
* Constructor. Requires the mapped content object attribute
* @param eZContentObjectAttribute $contentObjectAttribute
*/
public function __construct( eZContentObjectAttribute $contentObjectAttribute )
{
$this->contentObjectAttribute = $contentObjectAttribute;
}
 
/**
* Get the mapped data in a QR code compatible format
* @return string The barcode data, or an empty string
*/
abstract public function data();
}
?>