mirror of
https://github.com/torrentpier/torrentpier
synced 2025-08-21 05:43:55 -07:00
Zend Framework 2
Добавляем основные файлы ZF2. В будущем запланировано переписывание движка с использованием данного фреймворка.
This commit is contained in:
parent
92172c833b
commit
1ac86c5b0d
2482 changed files with 298793 additions and 0 deletions
71
library/Zend/Authentication/Adapter/AbstractAdapter.php
Executable file
71
library/Zend/Authentication/Adapter/AbstractAdapter.php
Executable file
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication\Adapter;
|
||||
|
||||
abstract class AbstractAdapter implements ValidatableAdapterInterface
|
||||
{
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
protected $credential;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
protected $identity;
|
||||
|
||||
/**
|
||||
* Returns the credential of the account being authenticated, or
|
||||
* NULL if none is set.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getCredential()
|
||||
{
|
||||
return $this->credential;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the credential for binding
|
||||
*
|
||||
* @param mixed $credential
|
||||
* @return AbstractAdapter
|
||||
*/
|
||||
public function setCredential($credential)
|
||||
{
|
||||
$this->credential = $credential;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the identity of the account being authenticated, or
|
||||
* NULL if none is set.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getIdentity()
|
||||
{
|
||||
return $this->identity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the identity for binding
|
||||
*
|
||||
* @param mixed $identity
|
||||
* @return AbstractAdapter
|
||||
*/
|
||||
public function setIdentity($identity)
|
||||
{
|
||||
$this->identity = $identity;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
21
library/Zend/Authentication/Adapter/AdapterInterface.php
Executable file
21
library/Zend/Authentication/Adapter/AdapterInterface.php
Executable file
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication\Adapter;
|
||||
|
||||
interface AdapterInterface
|
||||
{
|
||||
/**
|
||||
* Performs an authentication attempt
|
||||
*
|
||||
* @return \Zend\Authentication\Result
|
||||
* @throws \Zend\Authentication\Adapter\Exception\ExceptionInterface If authentication cannot be performed
|
||||
*/
|
||||
public function authenticate();
|
||||
}
|
17
library/Zend/Authentication/Adapter/DbTable.php
Executable file
17
library/Zend/Authentication/Adapter/DbTable.php
Executable file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication\Adapter;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
class DbTable extends DbTable\CredentialTreatmentAdapter
|
||||
{
|
||||
}
|
378
library/Zend/Authentication/Adapter/DbTable/AbstractAdapter.php
Executable file
378
library/Zend/Authentication/Adapter/DbTable/AbstractAdapter.php
Executable file
|
@ -0,0 +1,378 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication\Adapter\DbTable;
|
||||
|
||||
use stdClass;
|
||||
use Zend\Authentication\Result as AuthenticationResult;
|
||||
use Zend\Authentication\Adapter\AbstractAdapter as BaseAdapter;
|
||||
use Zend\Db\Adapter\Adapter as DbAdapter;
|
||||
use Zend\Db\Sql;
|
||||
|
||||
abstract class AbstractAdapter extends BaseAdapter
|
||||
{
|
||||
/**
|
||||
* Database Connection
|
||||
*
|
||||
* @var DbAdapter
|
||||
*/
|
||||
protected $zendDb = null;
|
||||
|
||||
/**
|
||||
* @var Sql\Select
|
||||
*/
|
||||
protected $dbSelect = null;
|
||||
/**
|
||||
* $tableName - the table name to check
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $tableName = null;
|
||||
|
||||
/**
|
||||
* $identityColumn - the column to use as the identity
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $identityColumn = null;
|
||||
|
||||
/**
|
||||
* $credentialColumns - columns to be used as the credentials
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $credentialColumn = null;
|
||||
|
||||
/**
|
||||
* $authenticateResultInfo
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $authenticateResultInfo = null;
|
||||
|
||||
/**
|
||||
* $resultRow - Results of database authentication query
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $resultRow = null;
|
||||
|
||||
/**
|
||||
* $ambiguityIdentity - Flag to indicate same Identity can be used with
|
||||
* different credentials. Default is FALSE and need to be set to true to
|
||||
* allow ambiguity usage.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $ambiguityIdentity = false;
|
||||
|
||||
/**
|
||||
* __construct() - Sets configuration options
|
||||
*
|
||||
* @param DbAdapter $zendDb
|
||||
* @param string $tableName Optional
|
||||
* @param string $identityColumn Optional
|
||||
* @param string $credentialColumn Optional
|
||||
*/
|
||||
public function __construct(
|
||||
DbAdapter $zendDb,
|
||||
$tableName = null,
|
||||
$identityColumn = null,
|
||||
$credentialColumn = null
|
||||
) {
|
||||
$this->zendDb = $zendDb;
|
||||
|
||||
if (null !== $tableName) {
|
||||
$this->setTableName($tableName);
|
||||
}
|
||||
|
||||
if (null !== $identityColumn) {
|
||||
$this->setIdentityColumn($identityColumn);
|
||||
}
|
||||
|
||||
if (null !== $credentialColumn) {
|
||||
$this->setCredentialColumn($credentialColumn);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* setTableName() - set the table name to be used in the select query
|
||||
*
|
||||
* @param string $tableName
|
||||
* @return self Provides a fluent interface
|
||||
*/
|
||||
public function setTableName($tableName)
|
||||
{
|
||||
$this->tableName = $tableName;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* setIdentityColumn() - set the column name to be used as the identity column
|
||||
*
|
||||
* @param string $identityColumn
|
||||
* @return self Provides a fluent interface
|
||||
*/
|
||||
public function setIdentityColumn($identityColumn)
|
||||
{
|
||||
$this->identityColumn = $identityColumn;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* setCredentialColumn() - set the column name to be used as the credential column
|
||||
*
|
||||
* @param string $credentialColumn
|
||||
* @return self Provides a fluent interface
|
||||
*/
|
||||
public function setCredentialColumn($credentialColumn)
|
||||
{
|
||||
$this->credentialColumn = $credentialColumn;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* setAmbiguityIdentity() - sets a flag for usage of identical identities
|
||||
* with unique credentials. It accepts integers (0, 1) or boolean (true,
|
||||
* false) parameters. Default is false.
|
||||
*
|
||||
* @param int|bool $flag
|
||||
* @return self Provides a fluent interface
|
||||
*/
|
||||
public function setAmbiguityIdentity($flag)
|
||||
{
|
||||
if (is_int($flag)) {
|
||||
$this->ambiguityIdentity = (1 === $flag ? true : false);
|
||||
} elseif (is_bool($flag)) {
|
||||
$this->ambiguityIdentity = $flag;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* getAmbiguityIdentity() - returns TRUE for usage of multiple identical
|
||||
* identities with different credentials, FALSE if not used.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getAmbiguityIdentity()
|
||||
{
|
||||
return $this->ambiguityIdentity;
|
||||
}
|
||||
|
||||
/**
|
||||
* getDbSelect() - Return the preauthentication Db Select object for userland select query modification
|
||||
*
|
||||
* @return Sql\Select
|
||||
*/
|
||||
public function getDbSelect()
|
||||
{
|
||||
if ($this->dbSelect == null) {
|
||||
$this->dbSelect = new Sql\Select();
|
||||
}
|
||||
return $this->dbSelect;
|
||||
}
|
||||
|
||||
/**
|
||||
* getResultRowObject() - Returns the result row as a stdClass object
|
||||
*
|
||||
* @param string|array $returnColumns
|
||||
* @param string|array $omitColumns
|
||||
* @return stdClass|bool
|
||||
*/
|
||||
public function getResultRowObject($returnColumns = null, $omitColumns = null)
|
||||
{
|
||||
if (!$this->resultRow) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$returnObject = new stdClass();
|
||||
|
||||
if (null !== $returnColumns) {
|
||||
$availableColumns = array_keys($this->resultRow);
|
||||
foreach ((array) $returnColumns as $returnColumn) {
|
||||
if (in_array($returnColumn, $availableColumns)) {
|
||||
$returnObject->{$returnColumn} = $this->resultRow[$returnColumn];
|
||||
}
|
||||
}
|
||||
return $returnObject;
|
||||
} elseif (null !== $omitColumns) {
|
||||
$omitColumns = (array) $omitColumns;
|
||||
foreach ($this->resultRow as $resultColumn => $resultValue) {
|
||||
if (!in_array($resultColumn, $omitColumns)) {
|
||||
$returnObject->{$resultColumn} = $resultValue;
|
||||
}
|
||||
}
|
||||
return $returnObject;
|
||||
}
|
||||
|
||||
foreach ($this->resultRow as $resultColumn => $resultValue) {
|
||||
$returnObject->{$resultColumn} = $resultValue;
|
||||
}
|
||||
return $returnObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called to attempt an authentication. Previous to this
|
||||
* call, this adapter would have already been configured with all
|
||||
* necessary information to successfully connect to a database table and
|
||||
* attempt to find a record matching the provided identity.
|
||||
*
|
||||
* @throws Exception\RuntimeException if answering the authentication query is impossible
|
||||
* @return AuthenticationResult
|
||||
*/
|
||||
public function authenticate()
|
||||
{
|
||||
$this->authenticateSetup();
|
||||
$dbSelect = $this->authenticateCreateSelect();
|
||||
$resultIdentities = $this->authenticateQuerySelect($dbSelect);
|
||||
|
||||
if (($authResult = $this->authenticateValidateResultSet($resultIdentities)) instanceof AuthenticationResult) {
|
||||
return $authResult;
|
||||
}
|
||||
|
||||
// At this point, ambiguity is already done. Loop, check and break on success.
|
||||
foreach ($resultIdentities as $identity) {
|
||||
$authResult = $this->authenticateValidateResult($identity);
|
||||
if ($authResult->isValid()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $authResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* _authenticateValidateResult() - This method attempts to validate that
|
||||
* the record in the resultset is indeed a record that matched the
|
||||
* identity provided to this adapter.
|
||||
*
|
||||
* @param array $resultIdentity
|
||||
* @return AuthenticationResult
|
||||
*/
|
||||
abstract protected function authenticateValidateResult($resultIdentity);
|
||||
|
||||
/**
|
||||
* _authenticateCreateSelect() - This method creates a Zend\Db\Sql\Select object that
|
||||
* is completely configured to be queried against the database.
|
||||
*
|
||||
* @return Sql\Select
|
||||
*/
|
||||
abstract protected function authenticateCreateSelect();
|
||||
|
||||
/**
|
||||
* _authenticateSetup() - This method abstracts the steps involved with
|
||||
* making sure that this adapter was indeed setup properly with all
|
||||
* required pieces of information.
|
||||
*
|
||||
* @throws Exception\RuntimeException in the event that setup was not done properly
|
||||
* @return bool
|
||||
*/
|
||||
protected function authenticateSetup()
|
||||
{
|
||||
$exception = null;
|
||||
|
||||
if ($this->tableName == '') {
|
||||
$exception = 'A table must be supplied for the DbTable authentication adapter.';
|
||||
} elseif ($this->identityColumn == '') {
|
||||
$exception = 'An identity column must be supplied for the DbTable authentication adapter.';
|
||||
} elseif ($this->credentialColumn == '') {
|
||||
$exception = 'A credential column must be supplied for the DbTable authentication adapter.';
|
||||
} elseif ($this->identity == '') {
|
||||
$exception = 'A value for the identity was not provided prior to authentication with DbTable.';
|
||||
} elseif ($this->credential === null) {
|
||||
$exception = 'A credential value was not provided prior to authentication with DbTable.';
|
||||
}
|
||||
|
||||
if (null !== $exception) {
|
||||
throw new Exception\RuntimeException($exception);
|
||||
}
|
||||
|
||||
$this->authenticateResultInfo = array(
|
||||
'code' => AuthenticationResult::FAILURE,
|
||||
'identity' => $this->identity,
|
||||
'messages' => array()
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* _authenticateQuerySelect() - This method accepts a Zend\Db\Sql\Select object and
|
||||
* performs a query against the database with that object.
|
||||
*
|
||||
* @param Sql\Select $dbSelect
|
||||
* @throws Exception\RuntimeException when an invalid select object is encountered
|
||||
* @return array
|
||||
*/
|
||||
protected function authenticateQuerySelect(Sql\Select $dbSelect)
|
||||
{
|
||||
$sql = new Sql\Sql($this->zendDb);
|
||||
$statement = $sql->prepareStatementForSqlObject($dbSelect);
|
||||
try {
|
||||
$result = $statement->execute();
|
||||
$resultIdentities = array();
|
||||
// iterate result, most cross platform way
|
||||
foreach ($result as $row) {
|
||||
// ZF-6428 - account for db engines that by default return uppercase column names
|
||||
if (isset($row['ZEND_AUTH_CREDENTIAL_MATCH'])) {
|
||||
$row['zend_auth_credential_match'] = $row['ZEND_AUTH_CREDENTIAL_MATCH'];
|
||||
unset($row['ZEND_AUTH_CREDENTIAL_MATCH']);
|
||||
}
|
||||
$resultIdentities[] = $row;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
throw new Exception\RuntimeException(
|
||||
'The supplied parameters to DbTable failed to '
|
||||
. 'produce a valid sql statement, please check table and column names '
|
||||
. 'for validity.',
|
||||
0,
|
||||
$e
|
||||
);
|
||||
}
|
||||
return $resultIdentities;
|
||||
}
|
||||
|
||||
/**
|
||||
* _authenticateValidateResultSet() - This method attempts to make
|
||||
* certain that only one record was returned in the resultset
|
||||
*
|
||||
* @param array $resultIdentities
|
||||
* @return bool|\Zend\Authentication\Result
|
||||
*/
|
||||
protected function authenticateValidateResultSet(array $resultIdentities)
|
||||
{
|
||||
if (count($resultIdentities) < 1) {
|
||||
$this->authenticateResultInfo['code'] = AuthenticationResult::FAILURE_IDENTITY_NOT_FOUND;
|
||||
$this->authenticateResultInfo['messages'][] = 'A record with the supplied identity could not be found.';
|
||||
return $this->authenticateCreateAuthResult();
|
||||
} elseif (count($resultIdentities) > 1 && false === $this->getAmbiguityIdentity()) {
|
||||
$this->authenticateResultInfo['code'] = AuthenticationResult::FAILURE_IDENTITY_AMBIGUOUS;
|
||||
$this->authenticateResultInfo['messages'][] = 'More than one record matches the supplied identity.';
|
||||
return $this->authenticateCreateAuthResult();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Zend\Authentication\Result object from the information that
|
||||
* has been collected during the authenticate() attempt.
|
||||
*
|
||||
* @return AuthenticationResult
|
||||
*/
|
||||
protected function authenticateCreateAuthResult()
|
||||
{
|
||||
return new AuthenticationResult(
|
||||
$this->authenticateResultInfo['code'],
|
||||
$this->authenticateResultInfo['identity'],
|
||||
$this->authenticateResultInfo['messages']
|
||||
);
|
||||
}
|
||||
}
|
117
library/Zend/Authentication/Adapter/DbTable/CallbackCheckAdapter.php
Executable file
117
library/Zend/Authentication/Adapter/DbTable/CallbackCheckAdapter.php
Executable file
|
@ -0,0 +1,117 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication\Adapter\DbTable;
|
||||
|
||||
use Zend\Authentication\Result as AuthenticationResult;
|
||||
use Zend\Db\Adapter\Adapter as DbAdapter;
|
||||
use Zend\Db\Sql;
|
||||
use Zend\Db\Sql\Predicate\Operator as SqlOp;
|
||||
|
||||
class CallbackCheckAdapter extends AbstractAdapter
|
||||
{
|
||||
/**
|
||||
* $credentialValidationCallback - This overrides the Treatment usage to provide a callback
|
||||
* that allows for validation to happen in code
|
||||
*
|
||||
* @var callable
|
||||
*/
|
||||
protected $credentialValidationCallback = null;
|
||||
|
||||
/**
|
||||
* __construct() - Sets configuration options
|
||||
*
|
||||
* @param DbAdapter $zendDb
|
||||
* @param string $tableName Optional
|
||||
* @param string $identityColumn Optional
|
||||
* @param string $credentialColumn Optional
|
||||
* @param callable $credentialValidationCallback Optional
|
||||
*/
|
||||
public function __construct(
|
||||
DbAdapter $zendDb,
|
||||
$tableName = null,
|
||||
$identityColumn = null,
|
||||
$credentialColumn = null,
|
||||
$credentialValidationCallback = null
|
||||
) {
|
||||
parent::__construct($zendDb, $tableName, $identityColumn, $credentialColumn);
|
||||
|
||||
if (null !== $credentialValidationCallback) {
|
||||
$this->setCredentialValidationCallback($credentialValidationCallback);
|
||||
} else {
|
||||
$this->setCredentialValidationCallback(function ($a, $b) {
|
||||
return $a === $b;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* setCredentialValidationCallback() - allows the developer to use a callback as a way of checking the
|
||||
* credential.
|
||||
*
|
||||
* @param callable $validationCallback
|
||||
* @return self
|
||||
* @throws Exception\InvalidArgumentException
|
||||
*/
|
||||
public function setCredentialValidationCallback($validationCallback)
|
||||
{
|
||||
if (!is_callable($validationCallback)) {
|
||||
throw new Exception\InvalidArgumentException('Invalid callback provided');
|
||||
}
|
||||
$this->credentialValidationCallback = $validationCallback;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* _authenticateCreateSelect() - This method creates a Zend\Db\Sql\Select object that
|
||||
* is completely configured to be queried against the database.
|
||||
*
|
||||
* @return Sql\Select
|
||||
*/
|
||||
protected function authenticateCreateSelect()
|
||||
{
|
||||
// get select
|
||||
$dbSelect = clone $this->getDbSelect();
|
||||
$dbSelect->from($this->tableName)
|
||||
->columns(array(Sql\Select::SQL_STAR))
|
||||
->where(new SqlOp($this->identityColumn, '=', $this->identity));
|
||||
|
||||
return $dbSelect;
|
||||
}
|
||||
|
||||
/**
|
||||
* _authenticateValidateResult() - This method attempts to validate that
|
||||
* the record in the resultset is indeed a record that matched the
|
||||
* identity provided to this adapter.
|
||||
*
|
||||
* @param array $resultIdentity
|
||||
* @return AuthenticationResult
|
||||
*/
|
||||
protected function authenticateValidateResult($resultIdentity)
|
||||
{
|
||||
try {
|
||||
$callbackResult = call_user_func($this->credentialValidationCallback, $resultIdentity[$this->credentialColumn], $this->credential);
|
||||
} catch (\Exception $e) {
|
||||
$this->authenticateResultInfo['code'] = AuthenticationResult::FAILURE_UNCATEGORIZED;
|
||||
$this->authenticateResultInfo['messages'][] = $e->getMessage();
|
||||
return $this->authenticateCreateAuthResult();
|
||||
}
|
||||
if ($callbackResult !== true) {
|
||||
$this->authenticateResultInfo['code'] = AuthenticationResult::FAILURE_CREDENTIAL_INVALID;
|
||||
$this->authenticateResultInfo['messages'][] = 'Supplied credential is invalid.';
|
||||
return $this->authenticateCreateAuthResult();
|
||||
}
|
||||
|
||||
$this->resultRow = $resultIdentity;
|
||||
|
||||
$this->authenticateResultInfo['code'] = AuthenticationResult::SUCCESS;
|
||||
$this->authenticateResultInfo['messages'][] = 'Authentication successful.';
|
||||
return $this->authenticateCreateAuthResult();
|
||||
}
|
||||
}
|
124
library/Zend/Authentication/Adapter/DbTable/CredentialTreatmentAdapter.php
Executable file
124
library/Zend/Authentication/Adapter/DbTable/CredentialTreatmentAdapter.php
Executable file
|
@ -0,0 +1,124 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication\Adapter\DbTable;
|
||||
|
||||
use Zend\Authentication\Result as AuthenticationResult;
|
||||
use Zend\Db\Adapter\Adapter as DbAdapter;
|
||||
use Zend\Db\Sql;
|
||||
use Zend\Db\Sql\Expression as SqlExpr;
|
||||
use Zend\Db\Sql\Predicate\Operator as SqlOp;
|
||||
|
||||
class CredentialTreatmentAdapter extends AbstractAdapter
|
||||
{
|
||||
/**
|
||||
* $credentialTreatment - Treatment applied to the credential, such as MD5() or PASSWORD()
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $credentialTreatment = null;
|
||||
|
||||
/**
|
||||
* __construct() - Sets configuration options
|
||||
*
|
||||
* @param DbAdapter $zendDb
|
||||
* @param string $tableName Optional
|
||||
* @param string $identityColumn Optional
|
||||
* @param string $credentialColumn Optional
|
||||
* @param string $credentialTreatment Optional
|
||||
*/
|
||||
public function __construct(
|
||||
DbAdapter $zendDb,
|
||||
$tableName = null,
|
||||
$identityColumn = null,
|
||||
$credentialColumn = null,
|
||||
$credentialTreatment = null
|
||||
) {
|
||||
parent::__construct($zendDb, $tableName, $identityColumn, $credentialColumn);
|
||||
|
||||
if (null !== $credentialTreatment) {
|
||||
$this->setCredentialTreatment($credentialTreatment);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* setCredentialTreatment() - allows the developer to pass a parametrized string that is
|
||||
* used to transform or treat the input credential data.
|
||||
*
|
||||
* In many cases, passwords and other sensitive data are encrypted, hashed, encoded,
|
||||
* obscured, or otherwise treated through some function or algorithm. By specifying a
|
||||
* parametrized treatment string with this method, a developer may apply arbitrary SQL
|
||||
* upon input credential data.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* 'PASSWORD(?)'
|
||||
* 'MD5(?)'
|
||||
*
|
||||
* @param string $treatment
|
||||
* @return self Provides a fluent interface
|
||||
*/
|
||||
public function setCredentialTreatment($treatment)
|
||||
{
|
||||
$this->credentialTreatment = $treatment;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* _authenticateCreateSelect() - This method creates a Zend\Db\Sql\Select object that
|
||||
* is completely configured to be queried against the database.
|
||||
*
|
||||
* @return Sql\Select
|
||||
*/
|
||||
protected function authenticateCreateSelect()
|
||||
{
|
||||
// build credential expression
|
||||
if (empty($this->credentialTreatment) || (strpos($this->credentialTreatment, '?') === false)) {
|
||||
$this->credentialTreatment = '?';
|
||||
}
|
||||
|
||||
$credentialExpression = new SqlExpr(
|
||||
'(CASE WHEN ?' . ' = ' . $this->credentialTreatment . ' THEN 1 ELSE 0 END) AS ?',
|
||||
array($this->credentialColumn, $this->credential, 'zend_auth_credential_match'),
|
||||
array(SqlExpr::TYPE_IDENTIFIER, SqlExpr::TYPE_VALUE, SqlExpr::TYPE_IDENTIFIER)
|
||||
);
|
||||
|
||||
// get select
|
||||
$dbSelect = clone $this->getDbSelect();
|
||||
$dbSelect->from($this->tableName)
|
||||
->columns(array('*', $credentialExpression))
|
||||
->where(new SqlOp($this->identityColumn, '=', $this->identity));
|
||||
|
||||
return $dbSelect;
|
||||
}
|
||||
|
||||
/**
|
||||
* _authenticateValidateResult() - This method attempts to validate that
|
||||
* the record in the resultset is indeed a record that matched the
|
||||
* identity provided to this adapter.
|
||||
*
|
||||
* @param array $resultIdentity
|
||||
* @return AuthenticationResult
|
||||
*/
|
||||
protected function authenticateValidateResult($resultIdentity)
|
||||
{
|
||||
if ($resultIdentity['zend_auth_credential_match'] != '1') {
|
||||
$this->authenticateResultInfo['code'] = AuthenticationResult::FAILURE_CREDENTIAL_INVALID;
|
||||
$this->authenticateResultInfo['messages'][] = 'Supplied credential is invalid.';
|
||||
return $this->authenticateCreateAuthResult();
|
||||
}
|
||||
|
||||
unset($resultIdentity['zend_auth_credential_match']);
|
||||
$this->resultRow = $resultIdentity;
|
||||
|
||||
$this->authenticateResultInfo['code'] = AuthenticationResult::SUCCESS;
|
||||
$this->authenticateResultInfo['messages'][] = 'Authentication successful.';
|
||||
return $this->authenticateCreateAuthResult();
|
||||
}
|
||||
}
|
16
library/Zend/Authentication/Adapter/DbTable/Exception/ExceptionInterface.php
Executable file
16
library/Zend/Authentication/Adapter/DbTable/Exception/ExceptionInterface.php
Executable file
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication\Adapter\DbTable\Exception;
|
||||
|
||||
use Zend\Authentication\Adapter\Exception\ExceptionInterface as Exception;
|
||||
|
||||
interface ExceptionInterface extends Exception
|
||||
{
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication\Adapter\DbTable\Exception;
|
||||
|
||||
use Zend\Authentication\Adapter\Exception;
|
||||
|
||||
class InvalidArgumentException extends Exception\InvalidArgumentException implements ExceptionInterface
|
||||
{
|
||||
}
|
17
library/Zend/Authentication/Adapter/DbTable/Exception/RuntimeException.php
Executable file
17
library/Zend/Authentication/Adapter/DbTable/Exception/RuntimeException.php
Executable file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication\Adapter\DbTable\Exception;
|
||||
|
||||
use Zend\Authentication\Adapter\Exception;
|
||||
|
||||
class RuntimeException extends Exception\RuntimeException implements
|
||||
ExceptionInterface
|
||||
{
|
||||
}
|
193
library/Zend/Authentication/Adapter/Digest.php
Executable file
193
library/Zend/Authentication/Adapter/Digest.php
Executable file
|
@ -0,0 +1,193 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication\Adapter;
|
||||
|
||||
use Zend\Authentication\Result as AuthenticationResult;
|
||||
use Zend\Stdlib\ErrorHandler;
|
||||
use Zend\Crypt\Utils as CryptUtils;
|
||||
|
||||
class Digest extends AbstractAdapter
|
||||
{
|
||||
/**
|
||||
* Filename against which authentication queries are performed
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $filename;
|
||||
|
||||
/**
|
||||
* Digest authentication realm
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $realm;
|
||||
|
||||
/**
|
||||
* Sets adapter options
|
||||
*
|
||||
* @param mixed $filename
|
||||
* @param mixed $realm
|
||||
* @param mixed $identity
|
||||
* @param mixed $credential
|
||||
*/
|
||||
public function __construct($filename = null, $realm = null, $identity = null, $credential = null)
|
||||
{
|
||||
if ($filename !== null) {
|
||||
$this->setFilename($filename);
|
||||
}
|
||||
if ($realm !== null) {
|
||||
$this->setRealm($realm);
|
||||
}
|
||||
if ($identity !== null) {
|
||||
$this->setIdentity($identity);
|
||||
}
|
||||
if ($credential !== null) {
|
||||
$this->setCredential($credential);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the filename option value or null if it has not yet been set
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getFilename()
|
||||
{
|
||||
return $this->filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the filename option value
|
||||
*
|
||||
* @param mixed $filename
|
||||
* @return Digest Provides a fluent interface
|
||||
*/
|
||||
public function setFilename($filename)
|
||||
{
|
||||
$this->filename = (string) $filename;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the realm option value or null if it has not yet been set
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getRealm()
|
||||
{
|
||||
return $this->realm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the realm option value
|
||||
*
|
||||
* @param mixed $realm
|
||||
* @return Digest Provides a fluent interface
|
||||
*/
|
||||
public function setRealm($realm)
|
||||
{
|
||||
$this->realm = (string) $realm;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the username option value or null if it has not yet been set
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getUsername()
|
||||
{
|
||||
return $this->getIdentity();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the username option value
|
||||
*
|
||||
* @param mixed $username
|
||||
* @return Digest Provides a fluent interface
|
||||
*/
|
||||
public function setUsername($username)
|
||||
{
|
||||
return $this->setIdentity($username);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the password option value or null if it has not yet been set
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getPassword()
|
||||
{
|
||||
return $this->getCredential();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the password option value
|
||||
*
|
||||
* @param mixed $password
|
||||
* @return Digest Provides a fluent interface
|
||||
*/
|
||||
public function setPassword($password)
|
||||
{
|
||||
return $this->setCredential($password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined by Zend\Authentication\Adapter\AdapterInterface
|
||||
*
|
||||
* @throws Exception\ExceptionInterface
|
||||
* @return AuthenticationResult
|
||||
*/
|
||||
public function authenticate()
|
||||
{
|
||||
$optionsRequired = array('filename', 'realm', 'identity', 'credential');
|
||||
foreach ($optionsRequired as $optionRequired) {
|
||||
if (null === $this->$optionRequired) {
|
||||
throw new Exception\RuntimeException("Option '$optionRequired' must be set before authentication");
|
||||
}
|
||||
}
|
||||
|
||||
ErrorHandler::start(E_WARNING);
|
||||
$fileHandle = fopen($this->filename, 'r');
|
||||
$error = ErrorHandler::stop();
|
||||
if (false === $fileHandle) {
|
||||
throw new Exception\UnexpectedValueException("Cannot open '$this->filename' for reading", 0, $error);
|
||||
}
|
||||
|
||||
$id = "$this->identity:$this->realm";
|
||||
$idLength = strlen($id);
|
||||
|
||||
$result = array(
|
||||
'code' => AuthenticationResult::FAILURE,
|
||||
'identity' => array(
|
||||
'realm' => $this->realm,
|
||||
'username' => $this->identity,
|
||||
),
|
||||
'messages' => array()
|
||||
);
|
||||
|
||||
while (($line = fgets($fileHandle)) !== false) {
|
||||
$line = trim($line);
|
||||
if (empty($line)) {
|
||||
break;
|
||||
}
|
||||
if (substr($line, 0, $idLength) === $id) {
|
||||
if (CryptUtils::compareStrings(substr($line, -32), md5("$this->identity:$this->realm:$this->credential"))) {
|
||||
return new AuthenticationResult(AuthenticationResult::SUCCESS, $result['identity'], $result['messages']);
|
||||
}
|
||||
$result['messages'][] = 'Password incorrect';
|
||||
return new AuthenticationResult(AuthenticationResult::FAILURE_CREDENTIAL_INVALID, $result['identity'], $result['messages']);
|
||||
}
|
||||
}
|
||||
|
||||
$result['messages'][] = "Username '$this->identity' and realm '$this->realm' combination not found";
|
||||
return new AuthenticationResult(AuthenticationResult::FAILURE_IDENTITY_NOT_FOUND, $result['identity'], $result['messages']);
|
||||
}
|
||||
}
|
16
library/Zend/Authentication/Adapter/Exception/ExceptionInterface.php
Executable file
16
library/Zend/Authentication/Adapter/Exception/ExceptionInterface.php
Executable file
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication\Adapter\Exception;
|
||||
|
||||
use Zend\Authentication\Exception\ExceptionInterface as Exception;
|
||||
|
||||
interface ExceptionInterface extends Exception
|
||||
{
|
||||
}
|
16
library/Zend/Authentication/Adapter/Exception/InvalidArgumentException.php
Executable file
16
library/Zend/Authentication/Adapter/Exception/InvalidArgumentException.php
Executable file
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication\Adapter\Exception;
|
||||
|
||||
use Zend\Authentication\Exception;
|
||||
|
||||
class InvalidArgumentException extends Exception\InvalidArgumentException implements ExceptionInterface
|
||||
{
|
||||
}
|
17
library/Zend/Authentication/Adapter/Exception/RuntimeException.php
Executable file
17
library/Zend/Authentication/Adapter/Exception/RuntimeException.php
Executable file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication\Adapter\Exception;
|
||||
|
||||
use Zend\Authentication\Exception;
|
||||
|
||||
class RuntimeException extends Exception\RuntimeException implements
|
||||
ExceptionInterface
|
||||
{
|
||||
}
|
17
library/Zend/Authentication/Adapter/Exception/UnexpectedValueException.php
Executable file
17
library/Zend/Authentication/Adapter/Exception/UnexpectedValueException.php
Executable file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication\Adapter\Exception;
|
||||
|
||||
use Zend\Authentication\Exception;
|
||||
|
||||
class UnexpectedValueException extends Exception\UnexpectedValueException implements
|
||||
ExceptionInterface
|
||||
{
|
||||
}
|
818
library/Zend/Authentication/Adapter/Http.php
Executable file
818
library/Zend/Authentication/Adapter/Http.php
Executable file
|
@ -0,0 +1,818 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication\Adapter;
|
||||
|
||||
use Zend\Authentication;
|
||||
use Zend\Http\Request as HTTPRequest;
|
||||
use Zend\Http\Response as HTTPResponse;
|
||||
use Zend\Uri\UriFactory;
|
||||
use Zend\Crypt\Utils as CryptUtils;
|
||||
|
||||
/**
|
||||
* HTTP Authentication Adapter
|
||||
*
|
||||
* Implements a pretty good chunk of RFC 2617.
|
||||
*
|
||||
* @todo Support auth-int
|
||||
* @todo Track nonces, nonce-count, opaque for replay protection and stale support
|
||||
* @todo Support Authentication-Info header
|
||||
*/
|
||||
class Http implements AdapterInterface
|
||||
{
|
||||
/**
|
||||
* Reference to the HTTP Request object
|
||||
*
|
||||
* @var HTTPRequest
|
||||
*/
|
||||
protected $request;
|
||||
|
||||
/**
|
||||
* Reference to the HTTP Response object
|
||||
*
|
||||
* @var HTTPResponse
|
||||
*/
|
||||
protected $response;
|
||||
|
||||
/**
|
||||
* Object that looks up user credentials for the Basic scheme
|
||||
*
|
||||
* @var Http\ResolverInterface
|
||||
*/
|
||||
protected $basicResolver;
|
||||
|
||||
/**
|
||||
* Object that looks up user credentials for the Digest scheme
|
||||
*
|
||||
* @var Http\ResolverInterface
|
||||
*/
|
||||
protected $digestResolver;
|
||||
|
||||
/**
|
||||
* List of authentication schemes supported by this class
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $supportedSchemes = array('basic', 'digest');
|
||||
|
||||
/**
|
||||
* List of schemes this class will accept from the client
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $acceptSchemes;
|
||||
|
||||
/**
|
||||
* Space-delimited list of protected domains for Digest Auth
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $domains;
|
||||
|
||||
/**
|
||||
* The protection realm to use
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $realm;
|
||||
|
||||
/**
|
||||
* Nonce timeout period
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $nonceTimeout;
|
||||
|
||||
/**
|
||||
* Whether to send the opaque value in the header. True by default
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $useOpaque;
|
||||
|
||||
/**
|
||||
* List of the supported digest algorithms. I want to support both MD5 and
|
||||
* MD5-sess, but MD5-sess won't make it into the first version.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $supportedAlgos = array('MD5');
|
||||
|
||||
/**
|
||||
* The actual algorithm to use. Defaults to MD5
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $algo;
|
||||
|
||||
/**
|
||||
* List of supported qop options. My intention is to support both 'auth' and
|
||||
* 'auth-int', but 'auth-int' won't make it into the first version.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $supportedQops = array('auth');
|
||||
|
||||
/**
|
||||
* Whether or not to do Proxy Authentication instead of origin server
|
||||
* authentication (send 407's instead of 401's). Off by default.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $imaProxy;
|
||||
|
||||
/**
|
||||
* Flag indicating the client is IE and didn't bother to return the opaque string
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $ieNoOpaque;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $config Configuration settings:
|
||||
* 'accept_schemes' => 'basic'|'digest'|'basic digest'
|
||||
* 'realm' => <string>
|
||||
* 'digest_domains' => <string> Space-delimited list of URIs
|
||||
* 'nonce_timeout' => <int>
|
||||
* 'use_opaque' => <bool> Whether to send the opaque value in the header
|
||||
* 'algorithm' => <string> See $supportedAlgos. Default: MD5
|
||||
* 'proxy_auth' => <bool> Whether to do authentication as a Proxy
|
||||
* @throws Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct(array $config)
|
||||
{
|
||||
$this->request = null;
|
||||
$this->response = null;
|
||||
$this->ieNoOpaque = false;
|
||||
|
||||
if (empty($config['accept_schemes'])) {
|
||||
throw new Exception\InvalidArgumentException('Config key "accept_schemes" is required');
|
||||
}
|
||||
|
||||
$schemes = explode(' ', $config['accept_schemes']);
|
||||
$this->acceptSchemes = array_intersect($schemes, $this->supportedSchemes);
|
||||
if (empty($this->acceptSchemes)) {
|
||||
throw new Exception\InvalidArgumentException(sprintf(
|
||||
'No supported schemes given in "accept_schemes". Valid values: %s',
|
||||
implode(', ', $this->supportedSchemes)
|
||||
));
|
||||
}
|
||||
|
||||
// Double-quotes are used to delimit the realm string in the HTTP header,
|
||||
// and colons are field delimiters in the password file.
|
||||
if (empty($config['realm']) ||
|
||||
!ctype_print($config['realm']) ||
|
||||
strpos($config['realm'], ':') !== false ||
|
||||
strpos($config['realm'], '"') !== false) {
|
||||
throw new Exception\InvalidArgumentException(
|
||||
'Config key \'realm\' is required, and must contain only printable characters,'
|
||||
. 'excluding quotation marks and colons'
|
||||
);
|
||||
} else {
|
||||
$this->realm = $config['realm'];
|
||||
}
|
||||
|
||||
if (in_array('digest', $this->acceptSchemes)) {
|
||||
if (empty($config['digest_domains']) ||
|
||||
!ctype_print($config['digest_domains']) ||
|
||||
strpos($config['digest_domains'], '"') !== false) {
|
||||
throw new Exception\InvalidArgumentException(
|
||||
'Config key \'digest_domains\' is required, and must contain '
|
||||
. 'only printable characters, excluding quotation marks'
|
||||
);
|
||||
} else {
|
||||
$this->domains = $config['digest_domains'];
|
||||
}
|
||||
|
||||
if (empty($config['nonce_timeout']) ||
|
||||
!is_numeric($config['nonce_timeout'])) {
|
||||
throw new Exception\InvalidArgumentException(
|
||||
'Config key \'nonce_timeout\' is required, and must be an integer'
|
||||
);
|
||||
} else {
|
||||
$this->nonceTimeout = (int) $config['nonce_timeout'];
|
||||
}
|
||||
|
||||
// We use the opaque value unless explicitly told not to
|
||||
if (isset($config['use_opaque']) && false == (bool) $config['use_opaque']) {
|
||||
$this->useOpaque = false;
|
||||
} else {
|
||||
$this->useOpaque = true;
|
||||
}
|
||||
|
||||
if (isset($config['algorithm']) && in_array($config['algorithm'], $this->supportedAlgos)) {
|
||||
$this->algo = $config['algorithm'];
|
||||
} else {
|
||||
$this->algo = 'MD5';
|
||||
}
|
||||
}
|
||||
|
||||
// Don't be a proxy unless explicitly told to do so
|
||||
if (isset($config['proxy_auth']) && true == (bool) $config['proxy_auth']) {
|
||||
$this->imaProxy = true; // I'm a Proxy
|
||||
} else {
|
||||
$this->imaProxy = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the basicResolver property
|
||||
*
|
||||
* @param Http\ResolverInterface $resolver
|
||||
* @return Http Provides a fluent interface
|
||||
*/
|
||||
public function setBasicResolver(Http\ResolverInterface $resolver)
|
||||
{
|
||||
$this->basicResolver = $resolver;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the basicResolver property
|
||||
*
|
||||
* @return Http\ResolverInterface
|
||||
*/
|
||||
public function getBasicResolver()
|
||||
{
|
||||
return $this->basicResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the digestResolver property
|
||||
*
|
||||
* @param Http\ResolverInterface $resolver
|
||||
* @return Http Provides a fluent interface
|
||||
*/
|
||||
public function setDigestResolver(Http\ResolverInterface $resolver)
|
||||
{
|
||||
$this->digestResolver = $resolver;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the digestResolver property
|
||||
*
|
||||
* @return Http\ResolverInterface
|
||||
*/
|
||||
public function getDigestResolver()
|
||||
{
|
||||
return $this->digestResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the Request object
|
||||
*
|
||||
* @param HTTPRequest $request
|
||||
* @return Http Provides a fluent interface
|
||||
*/
|
||||
public function setRequest(HTTPRequest $request)
|
||||
{
|
||||
$this->request = $request;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the Request object
|
||||
*
|
||||
* @return HTTPRequest
|
||||
*/
|
||||
public function getRequest()
|
||||
{
|
||||
return $this->request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the Response object
|
||||
*
|
||||
* @param HTTPResponse $response
|
||||
* @return Http Provides a fluent interface
|
||||
*/
|
||||
public function setResponse(HTTPResponse $response)
|
||||
{
|
||||
$this->response = $response;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the Response object
|
||||
*
|
||||
* @return HTTPResponse
|
||||
*/
|
||||
public function getResponse()
|
||||
{
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticate
|
||||
*
|
||||
* @throws Exception\RuntimeException
|
||||
* @return Authentication\Result
|
||||
*/
|
||||
public function authenticate()
|
||||
{
|
||||
if (empty($this->request) || empty($this->response)) {
|
||||
throw new Exception\RuntimeException(
|
||||
'Request and Response objects must be set before calling authenticate()'
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->imaProxy) {
|
||||
$getHeader = 'Proxy-Authorization';
|
||||
} else {
|
||||
$getHeader = 'Authorization';
|
||||
}
|
||||
|
||||
$headers = $this->request->getHeaders();
|
||||
if (!$headers->has($getHeader)) {
|
||||
return $this->challengeClient();
|
||||
}
|
||||
$authHeader = $headers->get($getHeader)->getFieldValue();
|
||||
if (!$authHeader) {
|
||||
return $this->challengeClient();
|
||||
}
|
||||
|
||||
list($clientScheme) = explode(' ', $authHeader);
|
||||
$clientScheme = strtolower($clientScheme);
|
||||
|
||||
// The server can issue multiple challenges, but the client should
|
||||
// answer with only the selected auth scheme.
|
||||
if (!in_array($clientScheme, $this->supportedSchemes)) {
|
||||
$this->response->setStatusCode(400);
|
||||
return new Authentication\Result(
|
||||
Authentication\Result::FAILURE_UNCATEGORIZED,
|
||||
array(),
|
||||
array('Client requested an incorrect or unsupported authentication scheme')
|
||||
);
|
||||
}
|
||||
|
||||
// client sent a scheme that is not the one required
|
||||
if (!in_array($clientScheme, $this->acceptSchemes)) {
|
||||
// challenge again the client
|
||||
return $this->challengeClient();
|
||||
}
|
||||
|
||||
switch ($clientScheme) {
|
||||
case 'basic':
|
||||
$result = $this->_basicAuth($authHeader);
|
||||
break;
|
||||
case 'digest':
|
||||
$result = $this->_digestAuth($authHeader);
|
||||
break;
|
||||
default:
|
||||
throw new Exception\RuntimeException('Unsupported authentication scheme: ' . $clientScheme);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @see Http::challengeClient()
|
||||
* @return Authentication\Result Always returns a non-identity Auth result
|
||||
*/
|
||||
protected function _challengeClient()
|
||||
{
|
||||
trigger_error(sprintf(
|
||||
'The method "%s" is deprecated and will be removed in the future; '
|
||||
. 'please use the public method "%s::challengeClient()" instead',
|
||||
__METHOD__,
|
||||
__CLASS__
|
||||
), E_USER_DEPRECATED);
|
||||
|
||||
return $this->challengeClient();
|
||||
}
|
||||
|
||||
/**
|
||||
* Challenge Client
|
||||
*
|
||||
* Sets a 401 or 407 Unauthorized response code, and creates the
|
||||
* appropriate Authenticate header(s) to prompt for credentials.
|
||||
*
|
||||
* @return Authentication\Result Always returns a non-identity Auth result
|
||||
*/
|
||||
public function challengeClient()
|
||||
{
|
||||
if ($this->imaProxy) {
|
||||
$statusCode = 407;
|
||||
$headerName = 'Proxy-Authenticate';
|
||||
} else {
|
||||
$statusCode = 401;
|
||||
$headerName = 'WWW-Authenticate';
|
||||
}
|
||||
|
||||
$this->response->setStatusCode($statusCode);
|
||||
|
||||
// Send a challenge in each acceptable authentication scheme
|
||||
$headers = $this->response->getHeaders();
|
||||
if (in_array('basic', $this->acceptSchemes)) {
|
||||
$headers->addHeaderLine($headerName, $this->_basicHeader());
|
||||
}
|
||||
if (in_array('digest', $this->acceptSchemes)) {
|
||||
$headers->addHeaderLine($headerName, $this->_digestHeader());
|
||||
}
|
||||
return new Authentication\Result(
|
||||
Authentication\Result::FAILURE_CREDENTIAL_INVALID,
|
||||
array(),
|
||||
array('Invalid or absent credentials; challenging client')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic Header
|
||||
*
|
||||
* Generates a Proxy- or WWW-Authenticate header value in the Basic
|
||||
* authentication scheme.
|
||||
*
|
||||
* @return string Authenticate header value
|
||||
*/
|
||||
protected function _basicHeader()
|
||||
{
|
||||
return 'Basic realm="' . $this->realm . '"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Digest Header
|
||||
*
|
||||
* Generates a Proxy- or WWW-Authenticate header value in the Digest
|
||||
* authentication scheme.
|
||||
*
|
||||
* @return string Authenticate header value
|
||||
*/
|
||||
protected function _digestHeader()
|
||||
{
|
||||
$wwwauth = 'Digest realm="' . $this->realm . '", '
|
||||
. 'domain="' . $this->domains . '", '
|
||||
. 'nonce="' . $this->_calcNonce() . '", '
|
||||
. ($this->useOpaque ? 'opaque="' . $this->_calcOpaque() . '", ' : '')
|
||||
. 'algorithm="' . $this->algo . '", '
|
||||
. 'qop="' . implode(',', $this->supportedQops) . '"';
|
||||
|
||||
return $wwwauth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic Authentication
|
||||
*
|
||||
* @param string $header Client's Authorization header
|
||||
* @throws Exception\ExceptionInterface
|
||||
* @return Authentication\Result
|
||||
*/
|
||||
protected function _basicAuth($header)
|
||||
{
|
||||
if (empty($header)) {
|
||||
throw new Exception\RuntimeException('The value of the client Authorization header is required');
|
||||
}
|
||||
if (empty($this->basicResolver)) {
|
||||
throw new Exception\RuntimeException(
|
||||
'A basicResolver object must be set before doing Basic authentication'
|
||||
);
|
||||
}
|
||||
|
||||
// Decode the Authorization header
|
||||
$auth = substr($header, strlen('Basic '));
|
||||
$auth = base64_decode($auth);
|
||||
if (!$auth) {
|
||||
throw new Exception\RuntimeException('Unable to base64_decode Authorization header value');
|
||||
}
|
||||
|
||||
// See ZF-1253. Validate the credentials the same way the digest
|
||||
// implementation does. If invalid credentials are detected,
|
||||
// re-challenge the client.
|
||||
if (!ctype_print($auth)) {
|
||||
return $this->challengeClient();
|
||||
}
|
||||
// Fix for ZF-1515: Now re-challenges on empty username or password
|
||||
$creds = array_filter(explode(':', $auth));
|
||||
if (count($creds) != 2) {
|
||||
return $this->challengeClient();
|
||||
}
|
||||
|
||||
$result = $this->basicResolver->resolve($creds[0], $this->realm, $creds[1]);
|
||||
|
||||
if ($result instanceof Authentication\Result && $result->isValid()) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
if (!$result instanceof Authentication\Result
|
||||
&& !is_array($result)
|
||||
&& CryptUtils::compareStrings($result, $creds[1])
|
||||
) {
|
||||
$identity = array('username' => $creds[0], 'realm' => $this->realm);
|
||||
return new Authentication\Result(Authentication\Result::SUCCESS, $identity);
|
||||
} elseif (is_array($result)) {
|
||||
return new Authentication\Result(Authentication\Result::SUCCESS, $result);
|
||||
}
|
||||
|
||||
return $this->challengeClient();
|
||||
}
|
||||
|
||||
/**
|
||||
* Digest Authentication
|
||||
*
|
||||
* @param string $header Client's Authorization header
|
||||
* @throws Exception\ExceptionInterface
|
||||
* @return Authentication\Result Valid auth result only on successful auth
|
||||
*/
|
||||
protected function _digestAuth($header)
|
||||
{
|
||||
if (empty($header)) {
|
||||
throw new Exception\RuntimeException('The value of the client Authorization header is required');
|
||||
}
|
||||
if (empty($this->digestResolver)) {
|
||||
throw new Exception\RuntimeException('A digestResolver object must be set before doing Digest authentication');
|
||||
}
|
||||
|
||||
$data = $this->_parseDigestAuth($header);
|
||||
if ($data === false) {
|
||||
$this->response->setStatusCode(400);
|
||||
return new Authentication\Result(
|
||||
Authentication\Result::FAILURE_UNCATEGORIZED,
|
||||
array(),
|
||||
array('Invalid Authorization header format')
|
||||
);
|
||||
}
|
||||
|
||||
// See ZF-1052. This code was a bit too unforgiving of invalid
|
||||
// usernames. Now, if the username is bad, we re-challenge the client.
|
||||
if ('::invalid::' == $data['username']) {
|
||||
return $this->challengeClient();
|
||||
}
|
||||
|
||||
// Verify that the client sent back the same nonce
|
||||
if ($this->_calcNonce() != $data['nonce']) {
|
||||
return $this->challengeClient();
|
||||
}
|
||||
// The opaque value is also required to match, but of course IE doesn't
|
||||
// play ball.
|
||||
if (!$this->ieNoOpaque && $this->_calcOpaque() != $data['opaque']) {
|
||||
return $this->challengeClient();
|
||||
}
|
||||
|
||||
// Look up the user's password hash. If not found, deny access.
|
||||
// This makes no assumptions about how the password hash was
|
||||
// constructed beyond that it must have been built in such a way as
|
||||
// to be recreatable with the current settings of this object.
|
||||
$ha1 = $this->digestResolver->resolve($data['username'], $data['realm']);
|
||||
if ($ha1 === false) {
|
||||
return $this->challengeClient();
|
||||
}
|
||||
|
||||
// If MD5-sess is used, a1 value is made of the user's password
|
||||
// hash with the server and client nonce appended, separated by
|
||||
// colons.
|
||||
if ($this->algo == 'MD5-sess') {
|
||||
$ha1 = hash('md5', $ha1 . ':' . $data['nonce'] . ':' . $data['cnonce']);
|
||||
}
|
||||
|
||||
// Calculate h(a2). The value of this hash depends on the qop
|
||||
// option selected by the client and the supported hash functions
|
||||
switch ($data['qop']) {
|
||||
case 'auth':
|
||||
$a2 = $this->request->getMethod() . ':' . $data['uri'];
|
||||
break;
|
||||
case 'auth-int':
|
||||
// Should be REQUEST_METHOD . ':' . uri . ':' . hash(entity-body),
|
||||
// but this isn't supported yet, so fall through to default case
|
||||
default:
|
||||
throw new Exception\RuntimeException('Client requested an unsupported qop option');
|
||||
}
|
||||
// Using hash() should make parameterizing the hash algorithm
|
||||
// easier
|
||||
$ha2 = hash('md5', $a2);
|
||||
|
||||
// Calculate the server's version of the request-digest. This must
|
||||
// match $data['response']. See RFC 2617, section 3.2.2.1
|
||||
$message = $data['nonce'] . ':' . $data['nc'] . ':' . $data['cnonce'] . ':' . $data['qop'] . ':' . $ha2;
|
||||
$digest = hash('md5', $ha1 . ':' . $message);
|
||||
|
||||
// If our digest matches the client's let them in, otherwise return
|
||||
// a 401 code and exit to prevent access to the protected resource.
|
||||
if (CryptUtils::compareStrings($digest, $data['response'])) {
|
||||
$identity = array('username' => $data['username'], 'realm' => $data['realm']);
|
||||
return new Authentication\Result(Authentication\Result::SUCCESS, $identity);
|
||||
}
|
||||
|
||||
return $this->challengeClient();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate Nonce
|
||||
*
|
||||
* @return string The nonce value
|
||||
*/
|
||||
protected function _calcNonce()
|
||||
{
|
||||
// Once subtle consequence of this timeout calculation is that it
|
||||
// actually divides all of time into nonceTimeout-sized sections, such
|
||||
// that the value of timeout is the point in time of the next
|
||||
// approaching "boundary" of a section. This allows the server to
|
||||
// consistently generate the same timeout (and hence the same nonce
|
||||
// value) across requests, but only as long as one of those
|
||||
// "boundaries" is not crossed between requests. If that happens, the
|
||||
// nonce will change on its own, and effectively log the user out. This
|
||||
// would be surprising if the user just logged in.
|
||||
$timeout = ceil(time() / $this->nonceTimeout) * $this->nonceTimeout;
|
||||
|
||||
$userAgentHeader = $this->request->getHeaders()->get('User-Agent');
|
||||
if ($userAgentHeader) {
|
||||
$userAgent = $userAgentHeader->getFieldValue();
|
||||
} elseif (isset($_SERVER['HTTP_USER_AGENT'])) {
|
||||
$userAgent = $_SERVER['HTTP_USER_AGENT'];
|
||||
} else {
|
||||
$userAgent = 'Zend_Authenticaion';
|
||||
}
|
||||
$nonce = hash('md5', $timeout . ':' . $userAgent . ':' . __CLASS__);
|
||||
return $nonce;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate Opaque
|
||||
*
|
||||
* The opaque string can be anything; the client must return it exactly as
|
||||
* it was sent. It may be useful to store data in this string in some
|
||||
* applications. Ideally, a new value for this would be generated each time
|
||||
* a WWW-Authenticate header is sent (in order to reduce predictability),
|
||||
* but we would have to be able to create the same exact value across at
|
||||
* least two separate requests from the same client.
|
||||
*
|
||||
* @return string The opaque value
|
||||
*/
|
||||
protected function _calcOpaque()
|
||||
{
|
||||
return hash('md5', 'Opaque Data:' . __CLASS__);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse Digest Authorization header
|
||||
*
|
||||
* @param string $header Client's Authorization: HTTP header
|
||||
* @return array|bool Data elements from header, or false if any part of
|
||||
* the header is invalid
|
||||
*/
|
||||
protected function _parseDigestAuth($header)
|
||||
{
|
||||
$temp = null;
|
||||
$data = array();
|
||||
|
||||
// See ZF-1052. Detect invalid usernames instead of just returning a
|
||||
// 400 code.
|
||||
$ret = preg_match('/username="([^"]+)"/', $header, $temp);
|
||||
if (!$ret || empty($temp[1])
|
||||
|| !ctype_print($temp[1])
|
||||
|| strpos($temp[1], ':') !== false) {
|
||||
$data['username'] = '::invalid::';
|
||||
} else {
|
||||
$data['username'] = $temp[1];
|
||||
}
|
||||
$temp = null;
|
||||
|
||||
$ret = preg_match('/realm="([^"]+)"/', $header, $temp);
|
||||
if (!$ret || empty($temp[1])) {
|
||||
return false;
|
||||
}
|
||||
if (!ctype_print($temp[1]) || strpos($temp[1], ':') !== false) {
|
||||
return false;
|
||||
} else {
|
||||
$data['realm'] = $temp[1];
|
||||
}
|
||||
$temp = null;
|
||||
|
||||
$ret = preg_match('/nonce="([^"]+)"/', $header, $temp);
|
||||
if (!$ret || empty($temp[1])) {
|
||||
return false;
|
||||
}
|
||||
if (!ctype_xdigit($temp[1])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$data['nonce'] = $temp[1];
|
||||
$temp = null;
|
||||
|
||||
$ret = preg_match('/uri="([^"]+)"/', $header, $temp);
|
||||
if (!$ret || empty($temp[1])) {
|
||||
return false;
|
||||
}
|
||||
// Section 3.2.2.5 in RFC 2617 says the authenticating server must
|
||||
// verify that the URI field in the Authorization header is for the
|
||||
// same resource requested in the Request Line.
|
||||
$rUri = $this->request->getUri();
|
||||
$cUri = UriFactory::factory($temp[1]);
|
||||
|
||||
// Make sure the path portion of both URIs is the same
|
||||
if ($rUri->getPath() != $cUri->getPath()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Section 3.2.2.5 seems to suggest that the value of the URI
|
||||
// Authorization field should be made into an absolute URI if the
|
||||
// Request URI is absolute, but it's vague, and that's a bunch of
|
||||
// code I don't want to write right now.
|
||||
$data['uri'] = $temp[1];
|
||||
$temp = null;
|
||||
|
||||
$ret = preg_match('/response="([^"]+)"/', $header, $temp);
|
||||
if (!$ret || empty($temp[1])) {
|
||||
return false;
|
||||
}
|
||||
if (32 != strlen($temp[1]) || !ctype_xdigit($temp[1])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$data['response'] = $temp[1];
|
||||
$temp = null;
|
||||
|
||||
// The spec says this should default to MD5 if omitted. OK, so how does
|
||||
// that square with the algo we send out in the WWW-Authenticate header,
|
||||
// if it can easily be overridden by the client?
|
||||
$ret = preg_match('/algorithm="?(' . $this->algo . ')"?/', $header, $temp);
|
||||
if ($ret && !empty($temp[1])
|
||||
&& in_array($temp[1], $this->supportedAlgos)) {
|
||||
$data['algorithm'] = $temp[1];
|
||||
} else {
|
||||
$data['algorithm'] = 'MD5'; // = $this->algo; ?
|
||||
}
|
||||
$temp = null;
|
||||
|
||||
// Not optional in this implementation
|
||||
$ret = preg_match('/cnonce="([^"]+)"/', $header, $temp);
|
||||
if (!$ret || empty($temp[1])) {
|
||||
return false;
|
||||
}
|
||||
if (!ctype_print($temp[1])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$data['cnonce'] = $temp[1];
|
||||
$temp = null;
|
||||
|
||||
// If the server sent an opaque value, the client must send it back
|
||||
if ($this->useOpaque) {
|
||||
$ret = preg_match('/opaque="([^"]+)"/', $header, $temp);
|
||||
if (!$ret || empty($temp[1])) {
|
||||
// Big surprise: IE isn't RFC 2617-compliant.
|
||||
$headers = $this->request->getHeaders();
|
||||
if (!$headers->has('User-Agent')) {
|
||||
return false;
|
||||
}
|
||||
$userAgent = $headers->get('User-Agent')->getFieldValue();
|
||||
if (false === strpos($userAgent, 'MSIE')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$temp[1] = '';
|
||||
$this->ieNoOpaque = true;
|
||||
}
|
||||
|
||||
// This implementation only sends MD5 hex strings in the opaque value
|
||||
if (!$this->ieNoOpaque &&
|
||||
(32 != strlen($temp[1]) || !ctype_xdigit($temp[1]))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$data['opaque'] = $temp[1];
|
||||
$temp = null;
|
||||
}
|
||||
|
||||
// Not optional in this implementation, but must be one of the supported
|
||||
// qop types
|
||||
$ret = preg_match('/qop="?(' . implode('|', $this->supportedQops) . ')"?/', $header, $temp);
|
||||
if (!$ret || empty($temp[1])) {
|
||||
return false;
|
||||
}
|
||||
if (!in_array($temp[1], $this->supportedQops)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$data['qop'] = $temp[1];
|
||||
$temp = null;
|
||||
|
||||
// Not optional in this implementation. The spec says this value
|
||||
// shouldn't be a quoted string, but apparently some implementations
|
||||
// quote it anyway. See ZF-1544.
|
||||
$ret = preg_match('/nc="?([0-9A-Fa-f]{8})"?/', $header, $temp);
|
||||
if (!$ret || empty($temp[1])) {
|
||||
return false;
|
||||
}
|
||||
if (8 != strlen($temp[1]) || !ctype_xdigit($temp[1])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$data['nc'] = $temp[1];
|
||||
$temp = null;
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
171
library/Zend/Authentication/Adapter/Http/ApacheResolver.php
Executable file
171
library/Zend/Authentication/Adapter/Http/ApacheResolver.php
Executable file
|
@ -0,0 +1,171 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication\Adapter\Http;
|
||||
|
||||
use Zend\Authentication\Result as AuthResult;
|
||||
use Zend\Crypt\Password\Apache as ApachePassword;
|
||||
use Zend\Stdlib\ErrorHandler;
|
||||
|
||||
/**
|
||||
* Apache Authentication Resolver
|
||||
*
|
||||
* @see http://httpd.apache.org/docs/2.2/misc/password_encryptions.html
|
||||
*/
|
||||
class ApacheResolver implements ResolverInterface
|
||||
{
|
||||
/**
|
||||
* Path to credentials file
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $file;
|
||||
|
||||
/**
|
||||
* Apache password object
|
||||
*
|
||||
* @var ApachePassword
|
||||
*/
|
||||
protected $apachePassword;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $path Complete filename where the credentials are stored
|
||||
*/
|
||||
public function __construct($path = '')
|
||||
{
|
||||
if (!empty($path)) {
|
||||
$this->setFile($path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the path to the credentials file
|
||||
*
|
||||
* @param string $path
|
||||
* @return self Provides a fluent interface
|
||||
* @throws Exception\InvalidArgumentException if path is not readable
|
||||
*/
|
||||
public function setFile($path)
|
||||
{
|
||||
if (empty($path) || !is_readable($path)) {
|
||||
throw new Exception\InvalidArgumentException('Path not readable: ' . $path);
|
||||
}
|
||||
$this->file = $path;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path to the credentials file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFile()
|
||||
{
|
||||
return $this->file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Apache Password object
|
||||
*
|
||||
* @return ApachePassword
|
||||
*/
|
||||
protected function getApachePassword()
|
||||
{
|
||||
if (empty($this->apachePassword)) {
|
||||
$this->apachePassword = new ApachePassword();
|
||||
}
|
||||
return $this->apachePassword;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve credentials
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param string $username Username
|
||||
* @param string $realm Authentication Realm
|
||||
* @param string $password The password to authenticate
|
||||
* @return AuthResult
|
||||
* @throws Exception\ExceptionInterface
|
||||
*/
|
||||
public function resolve($username, $realm, $password = null)
|
||||
{
|
||||
if (empty($username)) {
|
||||
throw new Exception\InvalidArgumentException('Username is required');
|
||||
}
|
||||
|
||||
if (!ctype_print($username) || strpos($username, ':') !== false) {
|
||||
throw new Exception\InvalidArgumentException(
|
||||
'Username must consist only of printable characters, excluding the colon'
|
||||
);
|
||||
}
|
||||
|
||||
if (!empty($realm) && (!ctype_print($realm) || strpos($realm, ':') !== false)) {
|
||||
throw new Exception\InvalidArgumentException(
|
||||
'Realm must consist only of printable characters, excluding the colon'
|
||||
);
|
||||
}
|
||||
|
||||
if (empty($password)) {
|
||||
throw new Exception\InvalidArgumentException('Password is required');
|
||||
}
|
||||
|
||||
// Open file, read through looking for matching credentials
|
||||
ErrorHandler::start(E_WARNING);
|
||||
$fp = fopen($this->file, 'r');
|
||||
$error = ErrorHandler::stop();
|
||||
if (!$fp) {
|
||||
throw new Exception\RuntimeException('Unable to open password file: ' . $this->file, 0, $error);
|
||||
}
|
||||
|
||||
// No real validation is done on the contents of the password file. The
|
||||
// assumption is that we trust the administrators to keep it secure.
|
||||
while (($line = fgetcsv($fp, 512, ':')) !== false) {
|
||||
if ($line[0] != $username) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isset($line[2])) {
|
||||
if ($line[1] == $realm) {
|
||||
$matchedHash = $line[2];
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
$matchedHash = $line[1];
|
||||
break;
|
||||
}
|
||||
fclose($fp);
|
||||
|
||||
if (!isset($matchedHash)) {
|
||||
return new AuthResult(AuthResult::FAILURE_IDENTITY_NOT_FOUND, null, array('Username not found in provided htpasswd file'));
|
||||
}
|
||||
|
||||
// Plaintext password
|
||||
if ($matchedHash === $password) {
|
||||
return new AuthResult(AuthResult::SUCCESS, $username);
|
||||
}
|
||||
|
||||
$apache = $this->getApachePassword();
|
||||
$apache->setUserName($username);
|
||||
if (!empty($realm)) {
|
||||
$apache->setAuthName($realm);
|
||||
}
|
||||
|
||||
if ($apache->verify($password, $matchedHash)) {
|
||||
return new AuthResult(AuthResult::SUCCESS, $username);
|
||||
}
|
||||
|
||||
return new AuthResult(AuthResult::FAILURE_CREDENTIAL_INVALID, null, array('Passwords did not match.'));
|
||||
}
|
||||
}
|
19
library/Zend/Authentication/Adapter/Http/Exception/ExceptionInterface.php
Executable file
19
library/Zend/Authentication/Adapter/Http/Exception/ExceptionInterface.php
Executable file
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication\Adapter\Http\Exception;
|
||||
|
||||
use Zend\Authentication\Adapter\Exception\ExceptionInterface as Exception;
|
||||
|
||||
/**
|
||||
* HTTP Auth Resolver Exception
|
||||
*/
|
||||
interface ExceptionInterface extends Exception
|
||||
{
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication\Adapter\Http\Exception;
|
||||
|
||||
use Zend\Authentication\Adapter\Exception;
|
||||
|
||||
class InvalidArgumentException extends Exception\InvalidArgumentException implements
|
||||
ExceptionInterface
|
||||
{
|
||||
}
|
17
library/Zend/Authentication/Adapter/Http/Exception/RuntimeException.php
Executable file
17
library/Zend/Authentication/Adapter/Http/Exception/RuntimeException.php
Executable file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication\Adapter\Http\Exception;
|
||||
|
||||
use Zend\Authentication\Adapter\Exception;
|
||||
|
||||
class RuntimeException extends Exception\RuntimeException implements
|
||||
ExceptionInterface
|
||||
{
|
||||
}
|
124
library/Zend/Authentication/Adapter/Http/FileResolver.php
Executable file
124
library/Zend/Authentication/Adapter/Http/FileResolver.php
Executable file
|
@ -0,0 +1,124 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication\Adapter\Http;
|
||||
|
||||
use Zend\Stdlib\ErrorHandler;
|
||||
|
||||
/**
|
||||
* HTTP Authentication File Resolver
|
||||
*/
|
||||
class FileResolver implements ResolverInterface
|
||||
{
|
||||
/**
|
||||
* Path to credentials file
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $file;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $path Complete filename where the credentials are stored
|
||||
*/
|
||||
public function __construct($path = '')
|
||||
{
|
||||
if (!empty($path)) {
|
||||
$this->setFile($path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the path to the credentials file
|
||||
*
|
||||
* @param string $path
|
||||
* @return FileResolver Provides a fluent interface
|
||||
* @throws Exception\InvalidArgumentException if path is not readable
|
||||
*/
|
||||
public function setFile($path)
|
||||
{
|
||||
if (empty($path) || !is_readable($path)) {
|
||||
throw new Exception\InvalidArgumentException('Path not readable: ' . $path);
|
||||
}
|
||||
$this->file = $path;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path to the credentials file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFile()
|
||||
{
|
||||
return $this->file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve credentials
|
||||
*
|
||||
* Only the first matching username/realm combination in the file is
|
||||
* returned. If the file contains credentials for Digest authentication,
|
||||
* the returned string is the password hash, or h(a1) from RFC 2617. The
|
||||
* returned string is the plain-text password for Basic authentication.
|
||||
*
|
||||
* The expected format of the file is:
|
||||
* username:realm:sharedSecret
|
||||
*
|
||||
* That is, each line consists of the user's username, the applicable
|
||||
* authentication realm, and the password or hash, each delimited by
|
||||
* colons.
|
||||
*
|
||||
* @param string $username Username
|
||||
* @param string $realm Authentication Realm
|
||||
* @return string|false User's shared secret, if the user is found in the
|
||||
* realm, false otherwise.
|
||||
* @throws Exception\ExceptionInterface
|
||||
*/
|
||||
public function resolve($username, $realm, $password = null)
|
||||
{
|
||||
if (empty($username)) {
|
||||
throw new Exception\InvalidArgumentException('Username is required');
|
||||
} elseif (!ctype_print($username) || strpos($username, ':') !== false) {
|
||||
throw new Exception\InvalidArgumentException(
|
||||
'Username must consist only of printable characters, excluding the colon'
|
||||
);
|
||||
}
|
||||
if (empty($realm)) {
|
||||
throw new Exception\InvalidArgumentException('Realm is required');
|
||||
} elseif (!ctype_print($realm) || strpos($realm, ':') !== false) {
|
||||
throw new Exception\InvalidArgumentException(
|
||||
'Realm must consist only of printable characters, excluding the colon.'
|
||||
);
|
||||
}
|
||||
|
||||
// Open file, read through looking for matching credentials
|
||||
ErrorHandler::start(E_WARNING);
|
||||
$fp = fopen($this->file, 'r');
|
||||
$error = ErrorHandler::stop();
|
||||
if (!$fp) {
|
||||
throw new Exception\RuntimeException('Unable to open password file: ' . $this->file, 0, $error);
|
||||
}
|
||||
|
||||
// No real validation is done on the contents of the password file. The
|
||||
// assumption is that we trust the administrators to keep it secure.
|
||||
while (($line = fgetcsv($fp, 512, ':')) !== false) {
|
||||
if ($line[0] == $username && $line[1] == $realm) {
|
||||
$password = $line[2];
|
||||
fclose($fp);
|
||||
return $password;
|
||||
}
|
||||
}
|
||||
|
||||
fclose($fp);
|
||||
return false;
|
||||
}
|
||||
}
|
30
library/Zend/Authentication/Adapter/Http/ResolverInterface.php
Executable file
30
library/Zend/Authentication/Adapter/Http/ResolverInterface.php
Executable file
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication\Adapter\Http;
|
||||
|
||||
/**
|
||||
* Auth HTTP Resolver Interface
|
||||
*
|
||||
* Defines an interface to resolve a username/realm combination into a shared
|
||||
* secret usable by HTTP Authentication.
|
||||
*/
|
||||
interface ResolverInterface
|
||||
{
|
||||
/**
|
||||
* Resolve username/realm to password/hash/etc.
|
||||
*
|
||||
* @param string $username Username
|
||||
* @param string $realm Authentication Realm
|
||||
* @param string $password Password (optional)
|
||||
* @return string|array|false User's shared secret as string if found in realm, or User's identity as array
|
||||
* if resolved, false otherwise.
|
||||
*/
|
||||
public function resolve($username, $realm, $password = null);
|
||||
}
|
466
library/Zend/Authentication/Adapter/Ldap.php
Executable file
466
library/Zend/Authentication/Adapter/Ldap.php
Executable file
|
@ -0,0 +1,466 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication\Adapter;
|
||||
|
||||
use stdClass;
|
||||
use Zend\Authentication\Result as AuthenticationResult;
|
||||
use Zend\Ldap as ZendLdap;
|
||||
use Zend\Ldap\Exception\LdapException;
|
||||
|
||||
class Ldap extends AbstractAdapter
|
||||
{
|
||||
/**
|
||||
* The Zend\Ldap\Ldap context.
|
||||
*
|
||||
* @var ZendLdap\Ldap
|
||||
*/
|
||||
protected $ldap = null;
|
||||
|
||||
/**
|
||||
* The array of arrays of Zend\Ldap\Ldap options passed to the constructor.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $options = null;
|
||||
|
||||
/**
|
||||
* The DN of the authenticated account. Used to retrieve the account entry on request.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $authenticatedDn = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $options An array of arrays of Zend\Ldap\Ldap options
|
||||
* @param string $identity The username of the account being authenticated
|
||||
* @param string $credential The password of the account being authenticated
|
||||
*/
|
||||
public function __construct(array $options = array(), $identity = null, $credential = null)
|
||||
{
|
||||
$this->setOptions($options);
|
||||
if ($identity !== null) {
|
||||
$this->setIdentity($identity);
|
||||
}
|
||||
if ($credential !== null) {
|
||||
$this->setCredential($credential);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array of arrays of Zend\Ldap\Ldap options of this adapter.
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function getOptions()
|
||||
{
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the array of arrays of Zend\Ldap\Ldap options to be used by
|
||||
* this adapter.
|
||||
*
|
||||
* @param array $options The array of arrays of Zend\Ldap\Ldap options
|
||||
* @return Ldap Provides a fluent interface
|
||||
*/
|
||||
public function setOptions($options)
|
||||
{
|
||||
$this->options = is_array($options) ? $options : array();
|
||||
if (array_key_exists('identity', $this->options)) {
|
||||
$this->options['username'] = $this->options['identity'];
|
||||
}
|
||||
if (array_key_exists('credential', $this->options)) {
|
||||
$this->options['password'] = $this->options['credential'];
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the username of the account being authenticated, or
|
||||
* NULL if none is set.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getUsername()
|
||||
{
|
||||
return $this->getIdentity();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the username for binding
|
||||
*
|
||||
* @param string $username The username for binding
|
||||
* @return Ldap Provides a fluent interface
|
||||
*/
|
||||
public function setUsername($username)
|
||||
{
|
||||
return $this->setIdentity($username);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the password of the account being authenticated, or
|
||||
* NULL if none is set.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getPassword()
|
||||
{
|
||||
return $this->getCredential();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the password for the account
|
||||
*
|
||||
* @param string $password The password of the account being authenticated
|
||||
* @return Ldap Provides a fluent interface
|
||||
*/
|
||||
public function setPassword($password)
|
||||
{
|
||||
return $this->setCredential($password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the LDAP Object
|
||||
*
|
||||
* @return ZendLdap\Ldap The Zend\Ldap\Ldap object used to authenticate the credentials
|
||||
*/
|
||||
public function getLdap()
|
||||
{
|
||||
if ($this->ldap === null) {
|
||||
$this->ldap = new ZendLdap\Ldap();
|
||||
}
|
||||
|
||||
return $this->ldap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an Ldap connection
|
||||
*
|
||||
* @param ZendLdap\Ldap $ldap An existing Ldap object
|
||||
* @return Ldap Provides a fluent interface
|
||||
*/
|
||||
public function setLdap(ZendLdap\Ldap $ldap)
|
||||
{
|
||||
$this->ldap = $ldap;
|
||||
|
||||
$this->setOptions(array($ldap->getOptions()));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a domain name for the current LDAP options. This is used
|
||||
* for skipping redundant operations (e.g. authentications).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getAuthorityName()
|
||||
{
|
||||
$options = $this->getLdap()->getOptions();
|
||||
$name = $options['accountDomainName'];
|
||||
if (!$name) {
|
||||
$name = $options['accountDomainNameShort'];
|
||||
}
|
||||
|
||||
return $name ? $name : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticate the user
|
||||
*
|
||||
* @return AuthenticationResult
|
||||
* @throws Exception\ExceptionInterface
|
||||
*/
|
||||
public function authenticate()
|
||||
{
|
||||
$messages = array();
|
||||
$messages[0] = ''; // reserved
|
||||
$messages[1] = ''; // reserved
|
||||
|
||||
$username = $this->identity;
|
||||
$password = $this->credential;
|
||||
|
||||
if (!$username) {
|
||||
$code = AuthenticationResult::FAILURE_IDENTITY_NOT_FOUND;
|
||||
$messages[0] = 'A username is required';
|
||||
return new AuthenticationResult($code, '', $messages);
|
||||
}
|
||||
if (!$password) {
|
||||
/* A password is required because some servers will
|
||||
* treat an empty password as an anonymous bind.
|
||||
*/
|
||||
$code = AuthenticationResult::FAILURE_CREDENTIAL_INVALID;
|
||||
$messages[0] = 'A password is required';
|
||||
return new AuthenticationResult($code, '', $messages);
|
||||
}
|
||||
|
||||
$ldap = $this->getLdap();
|
||||
|
||||
$code = AuthenticationResult::FAILURE;
|
||||
$messages[0] = "Authority not found: $username";
|
||||
$failedAuthorities = array();
|
||||
|
||||
/* Iterate through each server and try to authenticate the supplied
|
||||
* credentials against it.
|
||||
*/
|
||||
foreach ($this->options as $options) {
|
||||
if (!is_array($options)) {
|
||||
throw new Exception\InvalidArgumentException('Adapter options array not an array');
|
||||
}
|
||||
$adapterOptions = $this->prepareOptions($ldap, $options);
|
||||
$dname = '';
|
||||
|
||||
try {
|
||||
if ($messages[1]) {
|
||||
$messages[] = $messages[1];
|
||||
}
|
||||
|
||||
$messages[1] = '';
|
||||
$messages[] = $this->optionsToString($options);
|
||||
|
||||
$dname = $this->getAuthorityName();
|
||||
if (isset($failedAuthorities[$dname])) {
|
||||
/* If multiple sets of server options for the same domain
|
||||
* are supplied, we want to skip redundant authentications
|
||||
* where the identity or credentials where found to be
|
||||
* invalid with another server for the same domain. The
|
||||
* $failedAuthorities array tracks this condition (and also
|
||||
* serves to supply the original error message).
|
||||
* This fixes issue ZF-4093.
|
||||
*/
|
||||
$messages[1] = $failedAuthorities[$dname];
|
||||
$messages[] = "Skipping previously failed authority: $dname";
|
||||
continue;
|
||||
}
|
||||
|
||||
$canonicalName = $ldap->getCanonicalAccountName($username);
|
||||
$ldap->bind($canonicalName, $password);
|
||||
/*
|
||||
* Fixes problem when authenticated user is not allowed to retrieve
|
||||
* group-membership information or own account.
|
||||
* This requires that the user specified with "username" and optionally
|
||||
* "password" in the Zend\Ldap\Ldap options is able to retrieve the required
|
||||
* information.
|
||||
*/
|
||||
$requireRebind = false;
|
||||
if (isset($options['username'])) {
|
||||
$ldap->bind();
|
||||
$requireRebind = true;
|
||||
}
|
||||
$dn = $ldap->getCanonicalAccountName($canonicalName, ZendLdap\Ldap::ACCTNAME_FORM_DN);
|
||||
|
||||
$groupResult = $this->checkGroupMembership($ldap, $canonicalName, $dn, $adapterOptions);
|
||||
if ($groupResult === true) {
|
||||
$this->authenticatedDn = $dn;
|
||||
$messages[0] = '';
|
||||
$messages[1] = '';
|
||||
$messages[] = "$canonicalName authentication successful";
|
||||
if ($requireRebind === true) {
|
||||
// rebinding with authenticated user
|
||||
$ldap->bind($dn, $password);
|
||||
}
|
||||
return new AuthenticationResult(AuthenticationResult::SUCCESS, $canonicalName, $messages);
|
||||
} else {
|
||||
$messages[0] = 'Account is not a member of the specified group';
|
||||
$messages[1] = $groupResult;
|
||||
$failedAuthorities[$dname] = $groupResult;
|
||||
}
|
||||
} catch (LdapException $zle) {
|
||||
/* LDAP based authentication is notoriously difficult to diagnose. Therefore
|
||||
* we bend over backwards to capture and record every possible bit of
|
||||
* information when something goes wrong.
|
||||
*/
|
||||
|
||||
$err = $zle->getCode();
|
||||
|
||||
if ($err == LdapException::LDAP_X_DOMAIN_MISMATCH) {
|
||||
/* This error indicates that the domain supplied in the
|
||||
* username did not match the domains in the server options
|
||||
* and therefore we should just skip to the next set of
|
||||
* server options.
|
||||
*/
|
||||
continue;
|
||||
} elseif ($err == LdapException::LDAP_NO_SUCH_OBJECT) {
|
||||
$code = AuthenticationResult::FAILURE_IDENTITY_NOT_FOUND;
|
||||
$messages[0] = "Account not found: $username";
|
||||
$failedAuthorities[$dname] = $zle->getMessage();
|
||||
} elseif ($err == LdapException::LDAP_INVALID_CREDENTIALS) {
|
||||
$code = AuthenticationResult::FAILURE_CREDENTIAL_INVALID;
|
||||
$messages[0] = 'Invalid credentials';
|
||||
$failedAuthorities[$dname] = $zle->getMessage();
|
||||
} else {
|
||||
$line = $zle->getLine();
|
||||
$messages[] = $zle->getFile() . "($line): " . $zle->getMessage();
|
||||
$messages[] = preg_replace(
|
||||
'/\b'.preg_quote(substr($password, 0, 15), '/').'\b/',
|
||||
'*****',
|
||||
$zle->getTraceAsString()
|
||||
);
|
||||
$messages[0] = 'An unexpected failure occurred';
|
||||
}
|
||||
$messages[1] = $zle->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
$msg = isset($messages[1]) ? $messages[1] : $messages[0];
|
||||
$messages[] = "$username authentication failed: $msg";
|
||||
|
||||
return new AuthenticationResult($code, $username, $messages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the LDAP specific options on the Zend\Ldap\Ldap instance
|
||||
*
|
||||
* @param ZendLdap\Ldap $ldap
|
||||
* @param array $options
|
||||
* @return array of auth-adapter specific options
|
||||
*/
|
||||
protected function prepareOptions(ZendLdap\Ldap $ldap, array $options)
|
||||
{
|
||||
$adapterOptions = array(
|
||||
'group' => null,
|
||||
'groupDn' => $ldap->getBaseDn(),
|
||||
'groupScope' => ZendLdap\Ldap::SEARCH_SCOPE_SUB,
|
||||
'groupAttr' => 'cn',
|
||||
'groupFilter' => 'objectClass=groupOfUniqueNames',
|
||||
'memberAttr' => 'uniqueMember',
|
||||
'memberIsDn' => true
|
||||
);
|
||||
foreach ($adapterOptions as $key => $value) {
|
||||
if (array_key_exists($key, $options)) {
|
||||
$value = $options[$key];
|
||||
unset($options[$key]);
|
||||
switch ($key) {
|
||||
case 'groupScope':
|
||||
$value = (int) $value;
|
||||
if (in_array(
|
||||
$value,
|
||||
array(
|
||||
ZendLdap\Ldap::SEARCH_SCOPE_BASE,
|
||||
ZendLdap\Ldap::SEARCH_SCOPE_ONE,
|
||||
ZendLdap\Ldap::SEARCH_SCOPE_SUB,
|
||||
),
|
||||
true
|
||||
)) {
|
||||
$adapterOptions[$key] = $value;
|
||||
}
|
||||
break;
|
||||
case 'memberIsDn':
|
||||
$adapterOptions[$key] = ($value === true ||
|
||||
$value === '1' || strcasecmp($value, 'true') == 0);
|
||||
break;
|
||||
default:
|
||||
$adapterOptions[$key] = trim($value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$ldap->setOptions($options);
|
||||
return $adapterOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the group membership of the bound user
|
||||
*
|
||||
* @param ZendLdap\Ldap $ldap
|
||||
* @param string $canonicalName
|
||||
* @param string $dn
|
||||
* @param array $adapterOptions
|
||||
* @return string|true
|
||||
*/
|
||||
protected function checkGroupMembership(ZendLdap\Ldap $ldap, $canonicalName, $dn, array $adapterOptions)
|
||||
{
|
||||
if ($adapterOptions['group'] === null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($adapterOptions['memberIsDn'] === false) {
|
||||
$user = $canonicalName;
|
||||
} else {
|
||||
$user = $dn;
|
||||
}
|
||||
|
||||
$groupName = ZendLdap\Filter::equals($adapterOptions['groupAttr'], $adapterOptions['group']);
|
||||
$membership = ZendLdap\Filter::equals($adapterOptions['memberAttr'], $user);
|
||||
$group = ZendLdap\Filter::andFilter($groupName, $membership);
|
||||
$groupFilter = $adapterOptions['groupFilter'];
|
||||
if (!empty($groupFilter)) {
|
||||
$group = $group->addAnd($groupFilter);
|
||||
}
|
||||
|
||||
$result = $ldap->count($group, $adapterOptions['groupDn'], $adapterOptions['groupScope']);
|
||||
|
||||
if ($result === 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return 'Failed to verify group membership with ' . $group->toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* getAccountObject() - Returns the result entry as a stdClass object
|
||||
*
|
||||
* This resembles the feature {@see Zend\Authentication\Adapter\DbTable::getResultRowObject()}.
|
||||
* Closes ZF-6813
|
||||
*
|
||||
* @param array $returnAttribs
|
||||
* @param array $omitAttribs
|
||||
* @return stdClass|bool
|
||||
*/
|
||||
public function getAccountObject(array $returnAttribs = array(), array $omitAttribs = array())
|
||||
{
|
||||
if (!$this->authenticatedDn) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$returnObject = new stdClass();
|
||||
|
||||
$returnAttribs = array_map('strtolower', $returnAttribs);
|
||||
$omitAttribs = array_map('strtolower', $omitAttribs);
|
||||
$returnAttribs = array_diff($returnAttribs, $omitAttribs);
|
||||
|
||||
$entry = $this->getLdap()->getEntry($this->authenticatedDn, $returnAttribs, true);
|
||||
foreach ($entry as $attr => $value) {
|
||||
if (in_array($attr, $omitAttribs)) {
|
||||
// skip attributes marked to be omitted
|
||||
continue;
|
||||
}
|
||||
if (is_array($value)) {
|
||||
$returnObject->$attr = (count($value) > 1) ? $value : $value[0];
|
||||
} else {
|
||||
$returnObject->$attr = $value;
|
||||
}
|
||||
}
|
||||
return $returnObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts options to string
|
||||
*
|
||||
* @param array $options
|
||||
* @return string
|
||||
*/
|
||||
private function optionsToString(array $options)
|
||||
{
|
||||
$str = '';
|
||||
foreach ($options as $key => $val) {
|
||||
if ($key === 'password' || $key === 'credential') {
|
||||
$val = '*****';
|
||||
}
|
||||
if ($str) {
|
||||
$str .= ',';
|
||||
}
|
||||
$str .= $key . '=' . $val;
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
}
|
45
library/Zend/Authentication/Adapter/ValidatableAdapterInterface.php
Executable file
45
library/Zend/Authentication/Adapter/ValidatableAdapterInterface.php
Executable file
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication\Adapter;
|
||||
|
||||
interface ValidatableAdapterInterface extends AdapterInterface
|
||||
{
|
||||
/**
|
||||
* Returns the identity of the account being authenticated, or
|
||||
* NULL if none is set.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getIdentity();
|
||||
|
||||
/**
|
||||
* Sets the identity for binding
|
||||
*
|
||||
* @param mixed $identity
|
||||
* @return ValidatableAdapterInterface
|
||||
*/
|
||||
public function setIdentity($identity);
|
||||
|
||||
/**
|
||||
* Returns the credential of the account being authenticated, or
|
||||
* NULL if none is set.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getCredential();
|
||||
|
||||
/**
|
||||
* Sets the credential for binding
|
||||
*
|
||||
* @param mixed $credential
|
||||
* @return ValidatableAdapterInterface
|
||||
*/
|
||||
public function setCredential($credential);
|
||||
}
|
162
library/Zend/Authentication/AuthenticationService.php
Executable file
162
library/Zend/Authentication/AuthenticationService.php
Executable file
|
@ -0,0 +1,162 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication;
|
||||
|
||||
class AuthenticationService implements AuthenticationServiceInterface
|
||||
{
|
||||
/**
|
||||
* Persistent storage handler
|
||||
*
|
||||
* @var Storage\StorageInterface
|
||||
*/
|
||||
protected $storage = null;
|
||||
|
||||
/**
|
||||
* Authentication adapter
|
||||
*
|
||||
* @var Adapter\AdapterInterface
|
||||
*/
|
||||
protected $adapter = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Storage\StorageInterface $storage
|
||||
* @param Adapter\AdapterInterface $adapter
|
||||
*/
|
||||
public function __construct(Storage\StorageInterface $storage = null, Adapter\AdapterInterface $adapter = null)
|
||||
{
|
||||
if (null !== $storage) {
|
||||
$this->setStorage($storage);
|
||||
}
|
||||
if (null !== $adapter) {
|
||||
$this->setAdapter($adapter);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the authentication adapter
|
||||
*
|
||||
* The adapter does not have a default if the storage adapter has not been set.
|
||||
*
|
||||
* @return Adapter\AdapterInterface|null
|
||||
*/
|
||||
public function getAdapter()
|
||||
{
|
||||
return $this->adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the authentication adapter
|
||||
*
|
||||
* @param Adapter\AdapterInterface $adapter
|
||||
* @return AuthenticationService Provides a fluent interface
|
||||
*/
|
||||
public function setAdapter(Adapter\AdapterInterface $adapter)
|
||||
{
|
||||
$this->adapter = $adapter;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the persistent storage handler
|
||||
*
|
||||
* Session storage is used by default unless a different storage adapter has been set.
|
||||
*
|
||||
* @return Storage\StorageInterface
|
||||
*/
|
||||
public function getStorage()
|
||||
{
|
||||
if (null === $this->storage) {
|
||||
$this->setStorage(new Storage\Session());
|
||||
}
|
||||
|
||||
return $this->storage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the persistent storage handler
|
||||
*
|
||||
* @param Storage\StorageInterface $storage
|
||||
* @return AuthenticationService Provides a fluent interface
|
||||
*/
|
||||
public function setStorage(Storage\StorageInterface $storage)
|
||||
{
|
||||
$this->storage = $storage;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticates against the supplied adapter
|
||||
*
|
||||
* @param Adapter\AdapterInterface $adapter
|
||||
* @return Result
|
||||
* @throws Exception\RuntimeException
|
||||
*/
|
||||
public function authenticate(Adapter\AdapterInterface $adapter = null)
|
||||
{
|
||||
if (!$adapter) {
|
||||
if (!$adapter = $this->getAdapter()) {
|
||||
throw new Exception\RuntimeException('An adapter must be set or passed prior to calling authenticate()');
|
||||
}
|
||||
}
|
||||
$result = $adapter->authenticate();
|
||||
|
||||
/**
|
||||
* ZF-7546 - prevent multiple successive calls from storing inconsistent results
|
||||
* Ensure storage has clean state
|
||||
*/
|
||||
if ($this->hasIdentity()) {
|
||||
$this->clearIdentity();
|
||||
}
|
||||
|
||||
if ($result->isValid()) {
|
||||
$this->getStorage()->write($result->getIdentity());
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if and only if an identity is available from storage
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasIdentity()
|
||||
{
|
||||
return !$this->getStorage()->isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the identity from storage or null if no identity is available
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getIdentity()
|
||||
{
|
||||
$storage = $this->getStorage();
|
||||
|
||||
if ($storage->isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $storage->read();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the identity from persistent storage
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function clearIdentity()
|
||||
{
|
||||
$this->getStorage()->clear();
|
||||
}
|
||||
}
|
44
library/Zend/Authentication/AuthenticationServiceInterface.php
Executable file
44
library/Zend/Authentication/AuthenticationServiceInterface.php
Executable file
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication;
|
||||
|
||||
/**
|
||||
* Provides an API for authentication and identity management
|
||||
*/
|
||||
interface AuthenticationServiceInterface
|
||||
{
|
||||
/**
|
||||
* Authenticates and provides an authentication result
|
||||
*
|
||||
* @return Result
|
||||
*/
|
||||
public function authenticate();
|
||||
|
||||
/**
|
||||
* Returns true if and only if an identity is available
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasIdentity();
|
||||
|
||||
/**
|
||||
* Returns the authenticated identity or null if no identity is available
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getIdentity();
|
||||
|
||||
/**
|
||||
* Clears the identity
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function clearIdentity();
|
||||
}
|
3
library/Zend/Authentication/CONTRIBUTING.md
Executable file
3
library/Zend/Authentication/CONTRIBUTING.md
Executable file
|
@ -0,0 +1,3 @@
|
|||
# CONTRIBUTING
|
||||
|
||||
Please don't open pull requests against this repository, please use https://github.com/zendframework/zf2.
|
14
library/Zend/Authentication/Exception/ExceptionInterface.php
Executable file
14
library/Zend/Authentication/Exception/ExceptionInterface.php
Executable file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication\Exception;
|
||||
|
||||
interface ExceptionInterface
|
||||
{
|
||||
}
|
15
library/Zend/Authentication/Exception/InvalidArgumentException.php
Executable file
15
library/Zend/Authentication/Exception/InvalidArgumentException.php
Executable file
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication\Exception;
|
||||
|
||||
class InvalidArgumentException extends \InvalidArgumentException implements
|
||||
ExceptionInterface
|
||||
{
|
||||
}
|
15
library/Zend/Authentication/Exception/RuntimeException.php
Executable file
15
library/Zend/Authentication/Exception/RuntimeException.php
Executable file
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication\Exception;
|
||||
|
||||
class RuntimeException extends \RuntimeException implements
|
||||
ExceptionInterface
|
||||
{
|
||||
}
|
15
library/Zend/Authentication/Exception/UnexpectedValueException.php
Executable file
15
library/Zend/Authentication/Exception/UnexpectedValueException.php
Executable file
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication\Exception;
|
||||
|
||||
class UnexpectedValueException extends \UnexpectedValueException implements
|
||||
ExceptionInterface
|
||||
{
|
||||
}
|
14
library/Zend/Authentication/README.md
Executable file
14
library/Zend/Authentication/README.md
Executable file
|
@ -0,0 +1,14 @@
|
|||
Authentication Component from ZF2
|
||||
=================================
|
||||
|
||||
This is the Authentication component for ZF2.
|
||||
|
||||
- File issues at https://github.com/zendframework/zf2/issues
|
||||
- Create pull requests against https://github.com/zendframework/zf2
|
||||
- Documentation is at http://framework.zend.com/docs
|
||||
|
||||
LICENSE
|
||||
-------
|
||||
|
||||
The files in this archive are released under the [Zend Framework
|
||||
license](http://framework.zend.com/license), which is a 3-clause BSD license.
|
122
library/Zend/Authentication/Result.php
Executable file
122
library/Zend/Authentication/Result.php
Executable file
|
@ -0,0 +1,122 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication;
|
||||
|
||||
class Result
|
||||
{
|
||||
/**
|
||||
* General Failure
|
||||
*/
|
||||
const FAILURE = 0;
|
||||
|
||||
/**
|
||||
* Failure due to identity not being found.
|
||||
*/
|
||||
const FAILURE_IDENTITY_NOT_FOUND = -1;
|
||||
|
||||
/**
|
||||
* Failure due to identity being ambiguous.
|
||||
*/
|
||||
const FAILURE_IDENTITY_AMBIGUOUS = -2;
|
||||
|
||||
/**
|
||||
* Failure due to invalid credential being supplied.
|
||||
*/
|
||||
const FAILURE_CREDENTIAL_INVALID = -3;
|
||||
|
||||
/**
|
||||
* Failure due to uncategorized reasons.
|
||||
*/
|
||||
const FAILURE_UNCATEGORIZED = -4;
|
||||
|
||||
/**
|
||||
* Authentication success.
|
||||
*/
|
||||
const SUCCESS = 1;
|
||||
|
||||
/**
|
||||
* Authentication result code
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $code;
|
||||
|
||||
/**
|
||||
* The identity used in the authentication attempt
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $identity;
|
||||
|
||||
/**
|
||||
* An array of string reasons why the authentication attempt was unsuccessful
|
||||
*
|
||||
* If authentication was successful, this should be an empty array.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $messages;
|
||||
|
||||
/**
|
||||
* Sets the result code, identity, and failure messages
|
||||
*
|
||||
* @param int $code
|
||||
* @param mixed $identity
|
||||
* @param array $messages
|
||||
*/
|
||||
public function __construct($code, $identity, array $messages = array())
|
||||
{
|
||||
$this->code = (int) $code;
|
||||
$this->identity = $identity;
|
||||
$this->messages = $messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the result represents a successful authentication attempt
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isValid()
|
||||
{
|
||||
return ($this->code > 0) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* getCode() - Get the result code for this authentication attempt
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getCode()
|
||||
{
|
||||
return $this->code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the identity used in the authentication attempt
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getIdentity()
|
||||
{
|
||||
return $this->identity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of string reasons why the authentication attempt was unsuccessful
|
||||
*
|
||||
* If authentication was successful, this method returns an empty array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMessages()
|
||||
{
|
||||
return $this->messages;
|
||||
}
|
||||
}
|
109
library/Zend/Authentication/Storage/Chain.php
Executable file
109
library/Zend/Authentication/Storage/Chain.php
Executable file
|
@ -0,0 +1,109 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication\Storage;
|
||||
|
||||
use Zend\Stdlib\PriorityQueue;
|
||||
|
||||
class Chain implements StorageInterface
|
||||
{
|
||||
/**
|
||||
* Contains all storage that this authentication method uses. A storage
|
||||
* placed in the priority queue with a higher priority is always used
|
||||
* before using a storage with a lower priority.
|
||||
*
|
||||
* @var PriorityQueue
|
||||
*/
|
||||
protected $storageChain;
|
||||
|
||||
/**
|
||||
* Initializes the priority queue.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->storageChain = new PriorityQueue();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param StorageInterface $storage
|
||||
* @param int $priority
|
||||
*/
|
||||
public function add(StorageInterface $storage, $priority = 1)
|
||||
{
|
||||
$this->storageChain->insert($storage, $priority);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loop over the queue of storage until a storage is found that is non-empty. If such
|
||||
* storage is not found, then this chain storage itself is empty.
|
||||
*
|
||||
* In case a non-empty storage is found then this chain storage is also non-empty. Report
|
||||
* that, but also make sure that all storage with higher priorty that are empty
|
||||
* are filled.
|
||||
*
|
||||
* @see StorageInterface::isEmpty()
|
||||
*/
|
||||
public function isEmpty()
|
||||
{
|
||||
$storageWithHigherPriority = array();
|
||||
|
||||
// Loop invariant: $storageWithHigherPriority contains all storage with higher priorty
|
||||
// than the current one.
|
||||
foreach ($this->storageChain as $storage) {
|
||||
if ($storage->isEmpty()) {
|
||||
$storageWithHigherPriority[] = $storage;
|
||||
continue;
|
||||
}
|
||||
|
||||
$storageValue = $storage->read();
|
||||
foreach ($storageWithHigherPriority as $higherPriorityStorage) {
|
||||
$higherPriorityStorage->write($storageValue);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the chain is non-empty then the storage with the top priority is guaranteed to be
|
||||
* filled. Return its value.
|
||||
*
|
||||
* @see StorageInterface::read()
|
||||
*/
|
||||
public function read()
|
||||
{
|
||||
return $this->storageChain->top()->read();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the new $contents to all storage in the chain.
|
||||
*
|
||||
* @see StorageInterface::write()
|
||||
*/
|
||||
public function write($contents)
|
||||
{
|
||||
foreach ($this->storageChain as $storage) {
|
||||
$storage->write($contents);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all storage in the chain.
|
||||
*
|
||||
* @see StorageInterface::clear()
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
foreach ($this->storageChain as $storage) {
|
||||
$storage->clear();
|
||||
}
|
||||
}
|
||||
}
|
67
library/Zend/Authentication/Storage/NonPersistent.php
Executable file
67
library/Zend/Authentication/Storage/NonPersistent.php
Executable file
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication\Storage;
|
||||
|
||||
/**
|
||||
* Non-Persistent Authentication Storage
|
||||
*
|
||||
* Since HTTP Authentication happens again on each request, this will always be
|
||||
* re-populated. So there's no need to use sessions, this simple value class
|
||||
* will hold the data for rest of the current request.
|
||||
*/
|
||||
class NonPersistent implements StorageInterface
|
||||
{
|
||||
/**
|
||||
* Holds the actual auth data
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* Returns true if and only if storage is empty
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEmpty()
|
||||
{
|
||||
return empty($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the contents of storage
|
||||
* Behavior is undefined when storage is empty.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function read()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes $contents to storage
|
||||
*
|
||||
* @param mixed $contents
|
||||
* @return void
|
||||
*/
|
||||
public function write($contents)
|
||||
{
|
||||
$this->data = $contents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears contents from storage
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$this->data = null;
|
||||
}
|
||||
}
|
126
library/Zend/Authentication/Storage/Session.php
Executable file
126
library/Zend/Authentication/Storage/Session.php
Executable file
|
@ -0,0 +1,126 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication\Storage;
|
||||
|
||||
use Zend\Session\Container as SessionContainer;
|
||||
use Zend\Session\ManagerInterface as SessionManager;
|
||||
|
||||
class Session implements StorageInterface
|
||||
{
|
||||
/**
|
||||
* Default session namespace
|
||||
*/
|
||||
const NAMESPACE_DEFAULT = 'Zend_Auth';
|
||||
|
||||
/**
|
||||
* Default session object member name
|
||||
*/
|
||||
const MEMBER_DEFAULT = 'storage';
|
||||
|
||||
/**
|
||||
* Object to proxy $_SESSION storage
|
||||
*
|
||||
* @var SessionContainer
|
||||
*/
|
||||
protected $session;
|
||||
|
||||
/**
|
||||
* Session namespace
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $namespace = self::NAMESPACE_DEFAULT;
|
||||
|
||||
/**
|
||||
* Session object member
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $member = self::MEMBER_DEFAULT;
|
||||
|
||||
/**
|
||||
* Sets session storage options and initializes session namespace object
|
||||
*
|
||||
* @param mixed $namespace
|
||||
* @param mixed $member
|
||||
* @param SessionManager $manager
|
||||
*/
|
||||
public function __construct($namespace = null, $member = null, SessionManager $manager = null)
|
||||
{
|
||||
if ($namespace !== null) {
|
||||
$this->namespace = $namespace;
|
||||
}
|
||||
if ($member !== null) {
|
||||
$this->member = $member;
|
||||
}
|
||||
$this->session = new SessionContainer($this->namespace, $manager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the session namespace
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNamespace()
|
||||
{
|
||||
return $this->namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the session object member
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMember()
|
||||
{
|
||||
return $this->member;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined by Zend\Authentication\Storage\StorageInterface
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEmpty()
|
||||
{
|
||||
return !isset($this->session->{$this->member});
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined by Zend\Authentication\Storage\StorageInterface
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function read()
|
||||
{
|
||||
return $this->session->{$this->member};
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined by Zend\Authentication\Storage\StorageInterface
|
||||
*
|
||||
* @param mixed $contents
|
||||
* @return void
|
||||
*/
|
||||
public function write($contents)
|
||||
{
|
||||
$this->session->{$this->member} = $contents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defined by Zend\Authentication\Storage\StorageInterface
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
unset($this->session->{$this->member});
|
||||
}
|
||||
}
|
48
library/Zend/Authentication/Storage/StorageInterface.php
Executable file
48
library/Zend/Authentication/Storage/StorageInterface.php
Executable file
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication\Storage;
|
||||
|
||||
interface StorageInterface
|
||||
{
|
||||
/**
|
||||
* Returns true if and only if storage is empty
|
||||
*
|
||||
* @throws \Zend\Authentication\Exception\ExceptionInterface If it is impossible to determine whether storage is empty
|
||||
* @return bool
|
||||
*/
|
||||
public function isEmpty();
|
||||
|
||||
/**
|
||||
* Returns the contents of storage
|
||||
*
|
||||
* Behavior is undefined when storage is empty.
|
||||
*
|
||||
* @throws \Zend\Authentication\Exception\ExceptionInterface If reading contents from storage is impossible
|
||||
* @return mixed
|
||||
*/
|
||||
public function read();
|
||||
|
||||
/**
|
||||
* Writes $contents to storage
|
||||
*
|
||||
* @param mixed $contents
|
||||
* @throws \Zend\Authentication\Exception\ExceptionInterface If writing $contents to storage is impossible
|
||||
* @return void
|
||||
*/
|
||||
public function write($contents);
|
||||
|
||||
/**
|
||||
* Clears contents from storage
|
||||
*
|
||||
* @throws \Zend\Authentication\Exception\ExceptionInterface If clearing contents from storage is impossible
|
||||
* @return void
|
||||
*/
|
||||
public function clear();
|
||||
}
|
253
library/Zend/Authentication/Validator/Authentication.php
Executable file
253
library/Zend/Authentication/Validator/Authentication.php
Executable file
|
@ -0,0 +1,253 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Authentication\Validator;
|
||||
|
||||
use Traversable;
|
||||
use Zend\Authentication\Adapter\ValidatableAdapterInterface;
|
||||
use Zend\Authentication\AuthenticationService;
|
||||
use Zend\Authentication\Result;
|
||||
use Zend\Authentication\Exception;
|
||||
use Zend\Stdlib\ArrayUtils;
|
||||
use Zend\Validator\AbstractValidator;
|
||||
|
||||
/**
|
||||
* Authentication Validator
|
||||
*/
|
||||
class Authentication extends AbstractValidator
|
||||
{
|
||||
/**
|
||||
* Error codes
|
||||
* @const string
|
||||
*/
|
||||
const IDENTITY_NOT_FOUND = 'identityNotFound';
|
||||
const IDENTITY_AMBIGUOUS = 'identityAmbiguous';
|
||||
const CREDENTIAL_INVALID = 'credentialInvalid';
|
||||
const UNCATEGORIZED = 'uncategorized';
|
||||
const GENERAL = 'general';
|
||||
|
||||
/**
|
||||
* Error Messages
|
||||
* @var array
|
||||
*/
|
||||
protected $messageTemplates = array(
|
||||
self::IDENTITY_NOT_FOUND => 'Invalid identity',
|
||||
self::IDENTITY_AMBIGUOUS => 'Identity is ambiguous',
|
||||
self::CREDENTIAL_INVALID => 'Invalid password',
|
||||
self::UNCATEGORIZED => 'Authentication failed',
|
||||
self::GENERAL => 'Authentication failed',
|
||||
);
|
||||
|
||||
/**
|
||||
* Authentication Adapter
|
||||
* @var ValidatableAdapterInterface
|
||||
*/
|
||||
protected $adapter;
|
||||
|
||||
/**
|
||||
* Identity (or field)
|
||||
* @var string
|
||||
*/
|
||||
protected $identity;
|
||||
|
||||
/**
|
||||
* Credential (or field)
|
||||
* @var string
|
||||
*/
|
||||
protected $credential;
|
||||
|
||||
/**
|
||||
* Authentication Service
|
||||
* @var AuthenticationService
|
||||
*/
|
||||
protected $service;
|
||||
|
||||
/**
|
||||
* Sets validator options
|
||||
*
|
||||
* @param mixed $options
|
||||
*/
|
||||
public function __construct($options = null)
|
||||
{
|
||||
if ($options instanceof Traversable) {
|
||||
$options = ArrayUtils::iteratorToArray($options);
|
||||
}
|
||||
|
||||
if (is_array($options)) {
|
||||
if (array_key_exists('adapter', $options)) {
|
||||
$this->setAdapter($options['adapter']);
|
||||
}
|
||||
if (array_key_exists('identity', $options)) {
|
||||
$this->setIdentity($options['identity']);
|
||||
}
|
||||
if (array_key_exists('credential', $options)) {
|
||||
$this->setCredential($options['credential']);
|
||||
}
|
||||
if (array_key_exists('service', $options)) {
|
||||
$this->setService($options['service']);
|
||||
}
|
||||
}
|
||||
parent::__construct($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Adapter
|
||||
*
|
||||
* @return ValidatableAdapterInterface
|
||||
*/
|
||||
public function getAdapter()
|
||||
{
|
||||
return $this->adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Adapter
|
||||
*
|
||||
* @param ValidatableAdapterInterface $adapter
|
||||
* @return Authentication
|
||||
*/
|
||||
public function setAdapter(ValidatableAdapterInterface $adapter)
|
||||
{
|
||||
$this->adapter = $adapter;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Identity
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getIdentity()
|
||||
{
|
||||
return $this->identity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Identity
|
||||
*
|
||||
* @param mixed $identity
|
||||
* @return Authentication
|
||||
*/
|
||||
public function setIdentity($identity)
|
||||
{
|
||||
$this->identity = $identity;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Credential
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getCredential()
|
||||
{
|
||||
return $this->credential;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Credential
|
||||
*
|
||||
* @param mixed $credential
|
||||
* @return Authentication
|
||||
*/
|
||||
public function setCredential($credential)
|
||||
{
|
||||
$this->credential = $credential;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Service
|
||||
*
|
||||
* @return AuthenticationService
|
||||
*/
|
||||
public function getService()
|
||||
{
|
||||
return $this->service;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Service
|
||||
*
|
||||
* @param AuthenticationService $service
|
||||
* @return Authentication
|
||||
*/
|
||||
public function setService(AuthenticationService $service)
|
||||
{
|
||||
$this->service = $service;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Valid
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param array $context
|
||||
* @return bool
|
||||
*/
|
||||
public function isValid($value = null, $context = null)
|
||||
{
|
||||
if ($value !== null) {
|
||||
$this->setCredential($value);
|
||||
}
|
||||
|
||||
if (($context !== null) && array_key_exists($this->identity, $context)) {
|
||||
$identity = $context[$this->identity];
|
||||
} else {
|
||||
$identity = $this->identity;
|
||||
}
|
||||
if (!$this->identity) {
|
||||
throw new Exception\RuntimeException('Identity must be set prior to validation');
|
||||
}
|
||||
|
||||
if (($context !== null) && array_key_exists($this->credential, $context)) {
|
||||
$credential = $context[$this->credential];
|
||||
} else {
|
||||
$credential = $this->credential;
|
||||
}
|
||||
|
||||
if (!$this->adapter) {
|
||||
throw new Exception\RuntimeException('Adapter must be set prior to validation');
|
||||
}
|
||||
$this->adapter->setIdentity($identity);
|
||||
$this->adapter->setCredential($credential);
|
||||
|
||||
if (!$this->service) {
|
||||
throw new Exception\RuntimeException('AuthenticationService must be set prior to validation');
|
||||
}
|
||||
$result = $this->service->authenticate($this->adapter);
|
||||
|
||||
if ($result->getCode() != Result::SUCCESS) {
|
||||
switch ($result->getCode()) {
|
||||
case Result::FAILURE_IDENTITY_NOT_FOUND:
|
||||
$this->error(self::IDENTITY_NOT_FOUND);
|
||||
break;
|
||||
case Result::FAILURE_CREDENTIAL_INVALID:
|
||||
$this->error(self::CREDENTIAL_INVALID);
|
||||
break;
|
||||
case Result::FAILURE_IDENTITY_AMBIGUOUS:
|
||||
$this->error(self::IDENTITY_AMBIGUOUS);
|
||||
break;
|
||||
case Result::FAILURE_UNCATEGORIZED:
|
||||
$this->error(self::UNCATEGORIZED);
|
||||
break;
|
||||
default:
|
||||
$this->error(self::GENERAL);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
44
library/Zend/Authentication/composer.json
Executable file
44
library/Zend/Authentication/composer.json
Executable file
|
@ -0,0 +1,44 @@
|
|||
{
|
||||
"name": "zendframework/zend-authentication",
|
||||
"description": "provides an API for authentication and includes concrete authentication adapters for common use case scenarios",
|
||||
"license": "BSD-3-Clause",
|
||||
"keywords": [
|
||||
"zf2",
|
||||
"authentication"
|
||||
],
|
||||
"homepage": "https://github.com/zendframework/zf2",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Zend\\Authentication\\": ""
|
||||
}
|
||||
},
|
||||
"target-dir": "Zend/Authentication",
|
||||
"require": {
|
||||
"php": ">=5.3.23",
|
||||
"zendframework/zend-stdlib": "self.version"
|
||||
},
|
||||
"require-dev": {
|
||||
"zendframework/zend-db": "self.version",
|
||||
"zendframework/zend-crypt": "self.version",
|
||||
"zendframework/zend-http": "self.version",
|
||||
"zendframework/zend-ldap": "self.version",
|
||||
"zendframework/zend-session": "self.version",
|
||||
"zendframework/zend-validator": "self.version",
|
||||
"zendframework/zend-uri": "self.version"
|
||||
},
|
||||
"suggest": {
|
||||
"zendframework/zend-db": "Zend\\Db component",
|
||||
"zendframework/zend-crypt": "Zend\\Crypt component",
|
||||
"zendframework/zend-http": "Zend\\Http component",
|
||||
"zendframework/zend-ldap": "Zend\\Ldap component",
|
||||
"zendframework/zend-session": "Zend\\Session component",
|
||||
"zendframework/zend-uri": "Zend\\Uri component",
|
||||
"zendframework/zend-validator": "Zend\\Validator component"
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.3-dev",
|
||||
"dev-develop": "2.4-dev"
|
||||
}
|
||||
}
|
||||
}
|
304
library/Zend/Barcode/Barcode.php
Executable file
304
library/Zend/Barcode/Barcode.php
Executable file
|
@ -0,0 +1,304 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode;
|
||||
|
||||
use Traversable;
|
||||
use Zend\Stdlib\ArrayUtils;
|
||||
|
||||
/**
|
||||
* Class for generate Barcode
|
||||
*/
|
||||
abstract class Barcode
|
||||
{
|
||||
/**
|
||||
* Default barcode TTF font name
|
||||
*
|
||||
* It's used by standard barcode objects derived from
|
||||
* {@link Object\AbstractObject} class
|
||||
* if corresponding constructor option is not provided.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected static $staticFont = null;
|
||||
|
||||
/**
|
||||
* The parser plugin manager
|
||||
*
|
||||
* @var ObjectPluginManager
|
||||
*/
|
||||
protected static $objectPlugins;
|
||||
|
||||
/**
|
||||
* The renderer plugin manager
|
||||
*
|
||||
* @var RendererPluginManager
|
||||
*/
|
||||
protected static $rendererPlugins;
|
||||
|
||||
/**
|
||||
* Get the parser plugin manager
|
||||
*
|
||||
* @return ObjectPluginManager
|
||||
*/
|
||||
public static function getObjectPluginManager()
|
||||
{
|
||||
if (!static::$objectPlugins instanceof ObjectPluginManager) {
|
||||
static::$objectPlugins = new ObjectPluginManager();
|
||||
}
|
||||
|
||||
return static::$objectPlugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the renderer plugin manager
|
||||
*
|
||||
* @return RendererPluginManager
|
||||
*/
|
||||
public static function getRendererPluginManager()
|
||||
{
|
||||
if (!static::$rendererPlugins instanceof RendererPluginManager) {
|
||||
static::$rendererPlugins = new RendererPluginManager();
|
||||
}
|
||||
|
||||
return static::$rendererPlugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory for Zend\Barcode classes.
|
||||
*
|
||||
* First argument may be a string containing the base of the adapter class
|
||||
* name, e.g. 'code25' corresponds to class Object\Code25. This
|
||||
* is case-insensitive.
|
||||
*
|
||||
* First argument may alternatively be an object of type Traversable.
|
||||
* The barcode class base name is read from the 'barcode' property.
|
||||
* The barcode config parameters are read from the 'params' property.
|
||||
*
|
||||
* Second argument is optional and may be an associative array of key-value
|
||||
* pairs. This is used as the argument to the barcode constructor.
|
||||
*
|
||||
* If the first argument is of type Traversable, it is assumed to contain
|
||||
* all parameters, and the second argument is ignored.
|
||||
*
|
||||
* @param mixed $barcode String name of barcode class, or Traversable object.
|
||||
* @param mixed $renderer String name of renderer class
|
||||
* @param mixed $barcodeConfig OPTIONAL; an array or Traversable object with barcode parameters.
|
||||
* @param mixed $rendererConfig OPTIONAL; an array or Traversable object with renderer parameters.
|
||||
* @param bool $automaticRenderError OPTIONAL; set the automatic rendering of exception
|
||||
* @return Barcode
|
||||
* @throws Exception\ExceptionInterface
|
||||
*/
|
||||
public static function factory(
|
||||
$barcode,
|
||||
$renderer = 'image',
|
||||
$barcodeConfig = array(),
|
||||
$rendererConfig = array(),
|
||||
$automaticRenderError = true
|
||||
) {
|
||||
/*
|
||||
* Convert Traversable argument to plain string
|
||||
* barcode name and separate config object.
|
||||
*/
|
||||
if ($barcode instanceof Traversable) {
|
||||
$barcode = ArrayUtils::iteratorToArray($barcode);
|
||||
if (isset($barcode['rendererParams'])) {
|
||||
$rendererConfig = $barcode['rendererParams'];
|
||||
}
|
||||
if (isset($barcode['renderer'])) {
|
||||
$renderer = (string) $barcode['renderer'];
|
||||
}
|
||||
if (isset($barcode['barcodeParams'])) {
|
||||
$barcodeConfig = $barcode['barcodeParams'];
|
||||
}
|
||||
if (isset($barcode['barcode'])) {
|
||||
$barcode = (string) $barcode['barcode'];
|
||||
} else {
|
||||
$barcode = null;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$barcode = static::makeBarcode($barcode, $barcodeConfig);
|
||||
$renderer = static::makeRenderer($renderer, $rendererConfig);
|
||||
} catch (Exception\ExceptionInterface $e) {
|
||||
if ($automaticRenderError && !($e instanceof Exception\RendererCreationException)) {
|
||||
$barcode = static::makeBarcode('error', array('text' => $e->getMessage()));
|
||||
$renderer = static::makeRenderer($renderer, array());
|
||||
} else {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
$renderer->setAutomaticRenderError($automaticRenderError);
|
||||
return $renderer->setBarcode($barcode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Barcode Constructor
|
||||
*
|
||||
* @param mixed $barcode String name of barcode class, or Traversable object, or barcode object.
|
||||
* @param mixed $barcodeConfig OPTIONAL; an array or Traversable object with barcode parameters.
|
||||
* @throws Exception\InvalidArgumentException
|
||||
* @return Object
|
||||
*/
|
||||
public static function makeBarcode($barcode, $barcodeConfig = array())
|
||||
{
|
||||
if ($barcode instanceof Object\ObjectInterface) {
|
||||
return $barcode;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert Traversable argument to plain string
|
||||
* barcode name and separate configuration.
|
||||
*/
|
||||
if ($barcode instanceof Traversable) {
|
||||
$barcode = ArrayUtils::iteratorToArray($barcode);
|
||||
if (isset($barcode['barcodeParams']) && is_array($barcode['barcodeParams'])) {
|
||||
$barcodeConfig = $barcode['barcodeParams'];
|
||||
}
|
||||
if (isset($barcode['barcode'])) {
|
||||
$barcode = (string) $barcode['barcode'];
|
||||
} else {
|
||||
$barcode = null;
|
||||
}
|
||||
}
|
||||
if ($barcodeConfig instanceof Traversable) {
|
||||
$barcodeConfig = ArrayUtils::iteratorToArray($barcodeConfig);
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify that barcode parameters are in an array.
|
||||
*/
|
||||
if (!is_array($barcodeConfig)) {
|
||||
throw new Exception\InvalidArgumentException(
|
||||
'Barcode parameters must be in an array or a Traversable object'
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify that a barcode name has been specified.
|
||||
*/
|
||||
if (!is_string($barcode) || empty($barcode)) {
|
||||
throw new Exception\InvalidArgumentException(
|
||||
'Barcode name must be specified in a string'
|
||||
);
|
||||
}
|
||||
|
||||
return static::getObjectPluginManager()->get($barcode, $barcodeConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renderer Constructor
|
||||
*
|
||||
* @param mixed $renderer String name of renderer class, or Traversable object.
|
||||
* @param mixed $rendererConfig OPTIONAL; an array or Traversable object with renderer parameters.
|
||||
* @throws Exception\RendererCreationException
|
||||
* @return Renderer\RendererInterface
|
||||
*/
|
||||
public static function makeRenderer($renderer = 'image', $rendererConfig = array())
|
||||
{
|
||||
if ($renderer instanceof Renderer\RendererInterface) {
|
||||
return $renderer;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert Traversable argument to plain string
|
||||
* barcode name and separate config object.
|
||||
*/
|
||||
if ($renderer instanceof Traversable) {
|
||||
$renderer = ArrayUtils::iteratorToArray($renderer);
|
||||
if (isset($renderer['rendererParams'])) {
|
||||
$rendererConfig = $renderer['rendererParams'];
|
||||
}
|
||||
if (isset($renderer['renderer'])) {
|
||||
$renderer = (string) $renderer['renderer'];
|
||||
}
|
||||
}
|
||||
if ($rendererConfig instanceof Traversable) {
|
||||
$rendererConfig = ArrayUtils::iteratorToArray($rendererConfig);
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify that barcode parameters are in an array.
|
||||
*/
|
||||
if (!is_array($rendererConfig)) {
|
||||
throw new Exception\RendererCreationException(
|
||||
'Barcode parameters must be in an array or a Traversable object'
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify that a barcode name has been specified.
|
||||
*/
|
||||
if (!is_string($renderer) || empty($renderer)) {
|
||||
throw new Exception\RendererCreationException(
|
||||
'Renderer name must be specified in a string'
|
||||
);
|
||||
}
|
||||
|
||||
return static::getRendererPluginManager()->get($renderer, $rendererConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxy to renderer render() method
|
||||
*
|
||||
* @param string | Object\ObjectInterface | array | Traversable $barcode
|
||||
* @param string | Renderer\RendererInterface $renderer
|
||||
* @param array | Traversable $barcodeConfig
|
||||
* @param array | Traversable $rendererConfig
|
||||
*/
|
||||
public static function render(
|
||||
$barcode,
|
||||
$renderer,
|
||||
$barcodeConfig = array(),
|
||||
$rendererConfig = array()
|
||||
) {
|
||||
static::factory($barcode, $renderer, $barcodeConfig, $rendererConfig)->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxy to renderer draw() method
|
||||
*
|
||||
* @param string | Object\ObjectInterface | array | Traversable $barcode
|
||||
* @param string | Renderer\RendererInterface $renderer
|
||||
* @param array | Traversable $barcodeConfig
|
||||
* @param array | Traversable $rendererConfig
|
||||
* @return mixed
|
||||
*/
|
||||
public static function draw(
|
||||
$barcode,
|
||||
$renderer,
|
||||
$barcodeConfig = array(),
|
||||
$rendererConfig = array()
|
||||
) {
|
||||
return static::factory($barcode, $renderer, $barcodeConfig, $rendererConfig)->draw();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default font for new instances of barcode
|
||||
*
|
||||
* @param string $font
|
||||
* @return void
|
||||
*/
|
||||
public static function setBarcodeFont($font)
|
||||
{
|
||||
static::$staticFont = $font;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current default font
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getBarcodeFont()
|
||||
{
|
||||
return static::$staticFont;
|
||||
}
|
||||
}
|
3
library/Zend/Barcode/CONTRIBUTING.md
Executable file
3
library/Zend/Barcode/CONTRIBUTING.md
Executable file
|
@ -0,0 +1,3 @@
|
|||
# CONTRIBUTING
|
||||
|
||||
Please don't open pull requests against this repository, please use https://github.com/zendframework/zf2.
|
17
library/Zend/Barcode/Exception/ExceptionInterface.php
Executable file
17
library/Zend/Barcode/Exception/ExceptionInterface.php
Executable file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Exception;
|
||||
|
||||
/**
|
||||
* Exception for Zend\Barcode component.
|
||||
*/
|
||||
interface ExceptionInterface
|
||||
{
|
||||
}
|
17
library/Zend/Barcode/Exception/InvalidArgumentException.php
Executable file
17
library/Zend/Barcode/Exception/InvalidArgumentException.php
Executable file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Exception;
|
||||
|
||||
/**
|
||||
* Exception for Zend\Barcode component.
|
||||
*/
|
||||
class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
|
||||
{
|
||||
}
|
17
library/Zend/Barcode/Exception/OutOfRangeException.php
Executable file
17
library/Zend/Barcode/Exception/OutOfRangeException.php
Executable file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Exception;
|
||||
|
||||
/**
|
||||
* Exception for Zend\Barcode component.
|
||||
*/
|
||||
class OutOfRangeException extends \OutOfRangeException implements ExceptionInterface
|
||||
{
|
||||
}
|
17
library/Zend/Barcode/Exception/RendererCreationException.php
Executable file
17
library/Zend/Barcode/Exception/RendererCreationException.php
Executable file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Exception;
|
||||
|
||||
/**
|
||||
* Exception for Zend\Barcode component.
|
||||
*/
|
||||
class RendererCreationException extends \InvalidArgumentException implements ExceptionInterface
|
||||
{
|
||||
}
|
17
library/Zend/Barcode/Exception/RuntimeException.php
Executable file
17
library/Zend/Barcode/Exception/RuntimeException.php
Executable file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Exception;
|
||||
|
||||
/**
|
||||
* Exception for Zend\Barcode component.
|
||||
*/
|
||||
class RuntimeException extends \RuntimeException implements ExceptionInterface
|
||||
{
|
||||
}
|
17
library/Zend/Barcode/Exception/UnexpectedValueException.php
Executable file
17
library/Zend/Barcode/Exception/UnexpectedValueException.php
Executable file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Exception;
|
||||
|
||||
/**
|
||||
* Exception for Zend\Barcode component.
|
||||
*/
|
||||
class UnexpectedValueException extends \UnexpectedValueException implements ExceptionInterface
|
||||
{
|
||||
}
|
1248
library/Zend/Barcode/Object/AbstractObject.php
Executable file
1248
library/Zend/Barcode/Object/AbstractObject.php
Executable file
File diff suppressed because it is too large
Load diff
77
library/Zend/Barcode/Object/Codabar.php
Executable file
77
library/Zend/Barcode/Object/Codabar.php
Executable file
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Object;
|
||||
|
||||
/**
|
||||
* Class for generate Codabar barcode
|
||||
*/
|
||||
class Codabar extends AbstractObject
|
||||
{
|
||||
/**
|
||||
* Coding map
|
||||
* - 0 = space
|
||||
* - 1 = bar
|
||||
* @var array
|
||||
*/
|
||||
protected $codingMap = array(
|
||||
'0' => "101010011", '1' => "101011001", '2' => "101001011",
|
||||
'3' => "110010101", '4' => "101101001", '5' => "110101001",
|
||||
'6' => "100101011", '7' => "100101101", '8' => "100110101",
|
||||
'9' => "110100101", '-' => "101001101", '$' => "101100101",
|
||||
':' => "1101011011", '/' => "1101101011", '.' => "1101101101",
|
||||
'+' => "1011011011", 'A' => "1011001001", 'B' => "1010010011",
|
||||
'C' => "1001001011", 'D' => "1010011001"
|
||||
);
|
||||
|
||||
/**
|
||||
* Width of the barcode (in pixels)
|
||||
* @return int
|
||||
*/
|
||||
protected function calculateBarcodeWidth()
|
||||
{
|
||||
$quietZone = $this->getQuietZone();
|
||||
$encodedData = 0;
|
||||
$barcodeChar = str_split($this->getText());
|
||||
if (count($barcodeChar) > 1) {
|
||||
foreach ($barcodeChar as $c) {
|
||||
$encodedData += ((strlen($this->codingMap[$c]) + 1) * $this->barThinWidth) * $this->factor;
|
||||
}
|
||||
}
|
||||
$encodedData -= (1 * $this->barThinWidth * $this->factor);
|
||||
return $quietZone + $encodedData + $quietZone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Partial check of Codabar barcode
|
||||
* @return void
|
||||
*/
|
||||
protected function checkSpecificParams()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare array to draw barcode
|
||||
* @return array
|
||||
*/
|
||||
protected function prepareBarcode()
|
||||
{
|
||||
$text = str_split($this->getText());
|
||||
$barcodeTable = array();
|
||||
foreach ($text as $char) {
|
||||
$barcodeChar = str_split($this->codingMap[$char]);
|
||||
foreach ($barcodeChar as $c) {
|
||||
// visible, width, top, length
|
||||
$barcodeTable[] = array($c, $this->barThinWidth, 0, 1);
|
||||
}
|
||||
$barcodeTable[] = array(0, $this->barThinWidth);
|
||||
}
|
||||
return $barcodeTable;
|
||||
}
|
||||
}
|
311
library/Zend/Barcode/Object/Code128.php
Executable file
311
library/Zend/Barcode/Object/Code128.php
Executable file
|
@ -0,0 +1,311 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Object;
|
||||
|
||||
/**
|
||||
* Class for generate Code128 barcode
|
||||
*/
|
||||
class Code128 extends AbstractObject
|
||||
{
|
||||
/**
|
||||
* Drawing of checksum
|
||||
* (even if it's sometime optional, most of time it's required)
|
||||
* @var bool
|
||||
*/
|
||||
protected $withChecksum = true;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $convertedText = array();
|
||||
|
||||
protected $codingMap = array(
|
||||
0 => "11011001100", 1 => "11001101100", 2 => "11001100110",
|
||||
3 => "10010011000", 4 => "10010001100", 5 => "10001001100",
|
||||
6 => "10011001000", 7 => "10011000100", 8 => "10001100100",
|
||||
9 => "11001001000", 10 => "11001000100", 11 => "11000100100",
|
||||
12 => "10110011100", 13 => "10011011100", 14 => "10011001110",
|
||||
15 => "10111001100", 16 => "10011101100", 17 => "10011100110",
|
||||
18 => "11001110010", 19 => "11001011100", 20 => "11001001110",
|
||||
21 => "11011100100", 22 => "11001110100", 23 => "11101101110",
|
||||
24 => "11101001100", 25 => "11100101100", 26 => "11100100110",
|
||||
27 => "11101100100", 28 => "11100110100", 29 => "11100110010",
|
||||
30 => "11011011000", 31 => "11011000110", 32 => "11000110110",
|
||||
33 => "10100011000", 34 => "10001011000", 35 => "10001000110",
|
||||
36 => "10110001000", 37 => "10001101000", 38 => "10001100010",
|
||||
39 => "11010001000", 40 => "11000101000", 41 => "11000100010",
|
||||
42 => "10110111000", 43 => "10110001110", 44 => "10001101110",
|
||||
45 => "10111011000", 46 => "10111000110", 47 => "10001110110",
|
||||
48 => "11101110110", 49 => "11010001110", 50 => "11000101110",
|
||||
51 => "11011101000", 52 => "11011100010", 53 => "11011101110",
|
||||
54 => "11101011000", 55 => "11101000110", 56 => "11100010110",
|
||||
57 => "11101101000", 58 => "11101100010", 59 => "11100011010",
|
||||
60 => "11101111010", 61 => "11001000010", 62 => "11110001010",
|
||||
63 => "10100110000", 64 => "10100001100", 65 => "10010110000",
|
||||
66 => "10010000110", 67 => "10000101100", 68 => "10000100110",
|
||||
69 => "10110010000", 70 => "10110000100", 71 => "10011010000",
|
||||
72 => "10011000010", 73 => "10000110100", 74 => "10000110010",
|
||||
75 => "11000010010", 76 => "11001010000", 77 => "11110111010",
|
||||
78 => "11000010100", 79 => "10001111010", 80 => "10100111100",
|
||||
81 => "10010111100", 82 => "10010011110", 83 => "10111100100",
|
||||
84 => "10011110100", 85 => "10011110010", 86 => "11110100100",
|
||||
87 => "11110010100", 88 => "11110010010", 89 => "11011011110",
|
||||
90 => "11011110110", 91 => "11110110110", 92 => "10101111000",
|
||||
93 => "10100011110", 94 => "10001011110", 95 => "10111101000",
|
||||
96 => "10111100010", 97 => "11110101000", 98 => "11110100010",
|
||||
99 => "10111011110", 100 => "10111101110", 101 => "11101011110",
|
||||
102 => "11110101110",
|
||||
103 => "11010000100", 104 => "11010010000", 105 => "11010011100",
|
||||
106 => "1100011101011");
|
||||
|
||||
/**
|
||||
* Character sets ABC
|
||||
* @var array
|
||||
*/
|
||||
protected $charSets = array(
|
||||
'A' => array(
|
||||
' ', '!', '"', '#', '$', '%', '&', "'",
|
||||
'(', ')', '*', '+', ',', '-', '.', '/',
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', ':', ';', '<', '=', '>', '?',
|
||||
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
|
||||
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
|
||||
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
|
||||
'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
||||
'FNC3', 'FNC2', 'SHIFT', 'Code C', 'Code B', 'FNC4', 'FNC1',
|
||||
'START A', 'START B', 'START C', 'STOP'),
|
||||
'B' => array(
|
||||
' ', '!', '"', '#', '$', '%', '&', "'",
|
||||
'(', ')', '*', '+', ',', '-', '.', '/',
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', ':', ';', '<', '=', '>', '?',
|
||||
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
|
||||
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
|
||||
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
|
||||
'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
|
||||
'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
|
||||
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
|
||||
'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
|
||||
'x', 'y', 'z', '{', '|', '}', '~', 0x7F,
|
||||
'FNC3', 'FNC2', 'SHIFT', 'Code C', 'FNC4', 'Code A', 'FNC1',
|
||||
'START A', 'START B', 'START C', 'STOP',),
|
||||
'C' => array(
|
||||
'00', '01', '02', '03', '04', '05', '06', '07', '08', '09',
|
||||
'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', '47', '48', '49',
|
||||
'50', '51', '52', '53', '54', '55', '56', '57', '58', '59',
|
||||
'60', '61', '62', '63', '64', '65', '66', '67', '68', '69',
|
||||
'70', '71', '72', '73', '74', '75', '76', '77', '78', '79',
|
||||
'80', '81', '82', '83', '84', '85', '86', '87', '88', '89',
|
||||
'90', '91', '92', '93', '94', '95', '96', '97', '98', '99',
|
||||
'Code B', 'Code A', 'FNC1', 'START A', 'START B', 'START C', 'STOP'));
|
||||
|
||||
/**
|
||||
* Width of the barcode (in pixels)
|
||||
* @return int
|
||||
*/
|
||||
protected function calculateBarcodeWidth()
|
||||
{
|
||||
$quietZone = $this->getQuietZone();
|
||||
// Each characters contain 11 bars...
|
||||
$characterLength = 11 * $this->barThinWidth * $this->factor;
|
||||
$convertedChars = count($this->convertToBarcodeChars($this->getText()));
|
||||
if ($this->withChecksum) {
|
||||
$convertedChars++;
|
||||
}
|
||||
$encodedData = $convertedChars * $characterLength;
|
||||
// ...except the STOP character (13)
|
||||
$encodedData += $characterLength + 2 * $this->barThinWidth * $this->factor;
|
||||
$width = $quietZone + $encodedData + $quietZone;
|
||||
return $width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Partial check of code128 barcode
|
||||
* @return void
|
||||
*/
|
||||
protected function checkSpecificParams()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare array to draw barcode
|
||||
* @return array
|
||||
*/
|
||||
protected function prepareBarcode()
|
||||
{
|
||||
$barcodeTable = array();
|
||||
|
||||
$convertedChars = $this->convertToBarcodeChars($this->getText());
|
||||
|
||||
if ($this->withChecksum) {
|
||||
$convertedChars[] = $this->getChecksum($this->getText());
|
||||
}
|
||||
|
||||
// STOP CHARACTER
|
||||
$convertedChars[] = 106;
|
||||
|
||||
foreach ($convertedChars as $barcodeChar) {
|
||||
$barcodePattern = $this->codingMap[$barcodeChar];
|
||||
foreach (str_split($barcodePattern) as $c) {
|
||||
$barcodeTable[] = array($c, $this->barThinWidth, 0, 1);
|
||||
}
|
||||
}
|
||||
return $barcodeTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the next $length chars of $string starting at $pos are numeric.
|
||||
* Returns false if the end of the string is reached.
|
||||
* @param string $string String to search
|
||||
* @param int $pos Starting position
|
||||
* @param int $length Length to search
|
||||
* @return bool
|
||||
*/
|
||||
protected static function _isDigit($string, $pos, $length = 2)
|
||||
{
|
||||
if ($pos + $length > strlen($string)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for ($i = $pos; $i < $pos + $length; $i++) {
|
||||
if (!is_numeric($string[$i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert string to barcode string
|
||||
* @param string $string
|
||||
* @return array
|
||||
*/
|
||||
protected function convertToBarcodeChars($string)
|
||||
{
|
||||
$string = (string) $string;
|
||||
if (!strlen($string)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
if (isset($this->convertedText[md5($string)])) {
|
||||
return $this->convertedText[md5($string)];
|
||||
}
|
||||
|
||||
$currentCharset = null;
|
||||
$result = array();
|
||||
|
||||
$strlen = strlen($string);
|
||||
for ($pos = 0; $pos < $strlen; $pos++) {
|
||||
$char = $string[$pos];
|
||||
|
||||
if (static::_isDigit($string, $pos, 4) && $currentCharset != 'C'
|
||||
|| static::_isDigit($string, $pos, 2) && $currentCharset == 'C') {
|
||||
/**
|
||||
* Switch to C if the next 4 chars are numeric or stay C if the next 2
|
||||
* chars are numeric
|
||||
*/
|
||||
if ($currentCharset != 'C') {
|
||||
if ($pos == 0) {
|
||||
$code = array_search("START C", $this->charSets['C']);
|
||||
} else {
|
||||
$code = array_search("Code C", $this->charSets[$currentCharset]);
|
||||
}
|
||||
$result[] = $code;
|
||||
$currentCharset = 'C';
|
||||
}
|
||||
} elseif (in_array($char, $this->charSets['B']) && $currentCharset != 'B'
|
||||
&& !(in_array($char, $this->charSets['A']) && $currentCharset == 'A')) {
|
||||
/**
|
||||
* Switch to B as B contains the char and B is not the current charset.
|
||||
*/
|
||||
if ($pos == 0) {
|
||||
$code = array_search("START B", $this->charSets['B']);
|
||||
} else {
|
||||
$code = array_search("Code B", $this->charSets[$currentCharset]);
|
||||
}
|
||||
$result[] = $code;
|
||||
$currentCharset = 'B';
|
||||
} elseif (array_key_exists($char, $this->charSets['A']) && $currentCharset != 'A'
|
||||
&& !(array_key_exists($char, $this->charSets['B']) && $currentCharset == 'B')) {
|
||||
/**
|
||||
* Switch to C as C contains the char and C is not the current charset.
|
||||
*/
|
||||
if ($pos == 0) {
|
||||
$code = array_search("START A", $this->charSets['A']);
|
||||
} else {
|
||||
$code = array_search("Code A", $this->charSets[$currentCharset]);
|
||||
}
|
||||
$result[] = $code;
|
||||
$currentCharset = 'A';
|
||||
}
|
||||
|
||||
if ($currentCharset == 'C') {
|
||||
$code = array_search(substr($string, $pos, 2), $this->charSets['C']);
|
||||
$pos++; //Two chars from input
|
||||
} else {
|
||||
$code = array_search($string[$pos], $this->charSets[$currentCharset]);
|
||||
}
|
||||
$result[] = $code;
|
||||
}
|
||||
|
||||
$this->convertedText[md5($string)] = $result;
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set text to encode
|
||||
* @param string $value
|
||||
* @return Code128
|
||||
*/
|
||||
public function setText($value)
|
||||
{
|
||||
$this->text = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve text to encode
|
||||
* @return string
|
||||
*/
|
||||
public function getText()
|
||||
{
|
||||
return $this->text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get barcode checksum
|
||||
*
|
||||
* @param string $text
|
||||
* @return int
|
||||
*/
|
||||
public function getChecksum($text)
|
||||
{
|
||||
$tableOfChars = $this->convertToBarcodeChars($text);
|
||||
|
||||
$sum = $tableOfChars[0];
|
||||
unset($tableOfChars[0]);
|
||||
|
||||
$k = 1;
|
||||
foreach ($tableOfChars as $char) {
|
||||
$sum += ($k++) * $char;
|
||||
}
|
||||
|
||||
$checksum = $sum % 103;
|
||||
|
||||
return $checksum;
|
||||
}
|
||||
}
|
117
library/Zend/Barcode/Object/Code25.php
Executable file
117
library/Zend/Barcode/Object/Code25.php
Executable file
|
@ -0,0 +1,117 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Object;
|
||||
|
||||
/**
|
||||
* Class for generate Interleaved 2 of 5 barcode
|
||||
*/
|
||||
class Code25 extends AbstractObject
|
||||
{
|
||||
/**
|
||||
* Coding map
|
||||
* - 0 = narrow bar
|
||||
* - 1 = wide bar
|
||||
* @var array
|
||||
*/
|
||||
protected $codingMap = array(
|
||||
'0' => '00110',
|
||||
'1' => '10001',
|
||||
'2' => '01001',
|
||||
'3' => '11000',
|
||||
'4' => '00101',
|
||||
'5' => '10100',
|
||||
'6' => '01100',
|
||||
'7' => '00011',
|
||||
'8' => '10010',
|
||||
'9' => '01010',
|
||||
);
|
||||
|
||||
/**
|
||||
* Width of the barcode (in pixels)
|
||||
* @return int
|
||||
*/
|
||||
protected function calculateBarcodeWidth()
|
||||
{
|
||||
$quietZone = $this->getQuietZone();
|
||||
$startCharacter = (2 * $this->barThickWidth + 4 * $this->barThinWidth) * $this->factor;
|
||||
$characterLength = (3 * $this->barThinWidth + 2 * $this->barThickWidth + 5 * $this->barThinWidth)
|
||||
* $this->factor;
|
||||
$encodedData = strlen($this->getText()) * $characterLength;
|
||||
$stopCharacter = (2 * $this->barThickWidth + 4 * $this->barThinWidth) * $this->factor;
|
||||
return $quietZone + $startCharacter + $encodedData + $stopCharacter + $quietZone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Partial check of interleaved 2 of 5 barcode
|
||||
* @return void
|
||||
*/
|
||||
protected function checkSpecificParams()
|
||||
{
|
||||
$this->checkRatio();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare array to draw barcode
|
||||
* @return array
|
||||
*/
|
||||
protected function prepareBarcode()
|
||||
{
|
||||
$barcodeTable = array();
|
||||
|
||||
// Start character (30301)
|
||||
$barcodeTable[] = array(1, $this->barThickWidth, 0, 1);
|
||||
$barcodeTable[] = array(0, $this->barThinWidth, 0, 1);
|
||||
$barcodeTable[] = array(1, $this->barThickWidth, 0, 1);
|
||||
$barcodeTable[] = array(0, $this->barThinWidth, 0, 1);
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, 1);
|
||||
$barcodeTable[] = array(0, $this->barThinWidth);
|
||||
|
||||
$text = str_split($this->getText());
|
||||
foreach ($text as $char) {
|
||||
$barcodeChar = str_split($this->codingMap[$char]);
|
||||
foreach ($barcodeChar as $c) {
|
||||
/* visible, width, top, length */
|
||||
$width = $c ? $this->barThickWidth : $this->barThinWidth;
|
||||
$barcodeTable[] = array(1, $width, 0, 1);
|
||||
$barcodeTable[] = array(0, $this->barThinWidth);
|
||||
}
|
||||
}
|
||||
|
||||
// Stop character (30103)
|
||||
$barcodeTable[] = array(1, $this->barThickWidth, 0, 1);
|
||||
$barcodeTable[] = array(0, $this->barThinWidth, 0, 1);
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, 1);
|
||||
$barcodeTable[] = array(0, $this->barThinWidth, 0, 1);
|
||||
$barcodeTable[] = array(1, $this->barThickWidth, 0, 1);
|
||||
return $barcodeTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get barcode checksum
|
||||
*
|
||||
* @param string $text
|
||||
* @return int
|
||||
*/
|
||||
public function getChecksum($text)
|
||||
{
|
||||
$this->checkText($text);
|
||||
$factor = 3;
|
||||
$checksum = 0;
|
||||
|
||||
for ($i = strlen($text); $i > 0; $i --) {
|
||||
$checksum += intval($text{$i - 1}) * $factor;
|
||||
$factor = 4 - $factor;
|
||||
}
|
||||
|
||||
$checksum = (10 - ($checksum % 10)) % 10;
|
||||
|
||||
return $checksum;
|
||||
}
|
||||
}
|
159
library/Zend/Barcode/Object/Code25interleaved.php
Executable file
159
library/Zend/Barcode/Object/Code25interleaved.php
Executable file
|
@ -0,0 +1,159 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Object;
|
||||
|
||||
/**
|
||||
* Class for generate Interleaved 2 of 5 barcode
|
||||
*/
|
||||
class Code25interleaved extends Code25
|
||||
{
|
||||
/**
|
||||
* Drawing of bearer bars
|
||||
* @var bool
|
||||
*/
|
||||
private $withBearerBars = false;
|
||||
|
||||
/**
|
||||
* Default options for Code25interleaved barcode
|
||||
* @return void
|
||||
*/
|
||||
protected function getDefaultOptions()
|
||||
{
|
||||
$this->barcodeLength = 'even';
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate/deactivate drawing of bearer bars
|
||||
* @param bool $value
|
||||
* @return Code25
|
||||
*/
|
||||
public function setWithBearerBars($value)
|
||||
{
|
||||
$this->withBearerBars = (bool) $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve if bearer bars are enabled
|
||||
* @return bool
|
||||
*/
|
||||
public function getWithBearerBars()
|
||||
{
|
||||
return $this->withBearerBars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Width of the barcode (in pixels)
|
||||
* @return int
|
||||
*/
|
||||
protected function calculateBarcodeWidth()
|
||||
{
|
||||
$quietZone = $this->getQuietZone();
|
||||
$startCharacter = (4 * $this->barThinWidth) * $this->factor;
|
||||
$characterLength = (3 * $this->barThinWidth + 2 * $this->barThickWidth) * $this->factor;
|
||||
$encodedData = strlen($this->getText()) * $characterLength;
|
||||
$stopCharacter = ($this->barThickWidth + 2 * $this->barThinWidth) * $this->factor;
|
||||
return $quietZone + $startCharacter + $encodedData + $stopCharacter + $quietZone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare array to draw barcode
|
||||
* @return array
|
||||
*/
|
||||
protected function prepareBarcode()
|
||||
{
|
||||
if ($this->withBearerBars) {
|
||||
$this->withBorder = false;
|
||||
}
|
||||
|
||||
$barcodeTable = array();
|
||||
|
||||
// Start character (0000)
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, 1);
|
||||
$barcodeTable[] = array(0, $this->barThinWidth, 0, 1);
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, 1);
|
||||
$barcodeTable[] = array(0, $this->barThinWidth, 0, 1);
|
||||
|
||||
// Encoded $text
|
||||
$text = $this->getText();
|
||||
for ($i = 0, $len = strlen($text); $i < $len; $i += 2) { // Draw 2 chars at a time
|
||||
$char1 = substr($text, $i, 1);
|
||||
$char2 = substr($text, $i + 1, 1);
|
||||
|
||||
// Interleave
|
||||
for ($ibar = 0; $ibar < 5; $ibar ++) {
|
||||
// Draws char1 bar (fore color)
|
||||
$barWidth = (substr($this->codingMap[$char1], $ibar, 1))
|
||||
? $this->barThickWidth
|
||||
: $this->barThinWidth;
|
||||
|
||||
$barcodeTable[] = array(1, $barWidth, 0, 1);
|
||||
|
||||
// Left space corresponding to char2 (background color)
|
||||
$barWidth = (substr($this->codingMap[$char2], $ibar, 1))
|
||||
? $this->barThickWidth
|
||||
: $this->barThinWidth;
|
||||
$barcodeTable[] = array(0, $barWidth, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Stop character (100)
|
||||
$barcodeTable[] = array(1, $this->barThickWidth, 0, 1);
|
||||
$barcodeTable[] = array(0, $this->barThinWidth, 0, 1);
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, 1);
|
||||
return $barcodeTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drawing of bearer bars (if enabled)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function postDrawBarcode()
|
||||
{
|
||||
if (!$this->withBearerBars) {
|
||||
return;
|
||||
}
|
||||
|
||||
$width = $this->barThickWidth * $this->factor;
|
||||
$point1 = $this->rotate(-1, -1);
|
||||
$point2 = $this->rotate($this->calculateWidth() - 1, -1);
|
||||
$point3 = $this->rotate($this->calculateWidth() - 1, $width - 1);
|
||||
$point4 = $this->rotate(-1, $width - 1);
|
||||
$this->addPolygon(array(
|
||||
$point1,
|
||||
$point2,
|
||||
$point3,
|
||||
$point4,
|
||||
));
|
||||
$point1 = $this->rotate(
|
||||
0,
|
||||
0 + $this->barHeight * $this->factor - 1
|
||||
);
|
||||
$point2 = $this->rotate(
|
||||
$this->calculateWidth() - 1,
|
||||
0 + $this->barHeight * $this->factor - 1
|
||||
);
|
||||
$point3 = $this->rotate(
|
||||
$this->calculateWidth() - 1,
|
||||
0 + $this->barHeight * $this->factor - $width
|
||||
);
|
||||
$point4 = $this->rotate(
|
||||
0,
|
||||
0 + $this->barHeight * $this->factor - $width
|
||||
);
|
||||
$this->addPolygon(array(
|
||||
$point1,
|
||||
$point2,
|
||||
$point3,
|
||||
$point4,
|
||||
));
|
||||
}
|
||||
}
|
162
library/Zend/Barcode/Object/Code39.php
Executable file
162
library/Zend/Barcode/Object/Code39.php
Executable file
|
@ -0,0 +1,162 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Object;
|
||||
|
||||
/**
|
||||
* Class for generate Code39 barcode
|
||||
*/
|
||||
class Code39 extends AbstractObject
|
||||
{
|
||||
/**
|
||||
* Coding map
|
||||
* @var array
|
||||
*/
|
||||
protected $codingMap = array(
|
||||
'0' => '000110100',
|
||||
'1' => '100100001',
|
||||
'2' => '001100001',
|
||||
'3' => '101100000',
|
||||
'4' => '000110001',
|
||||
'5' => '100110000',
|
||||
'6' => '001110000',
|
||||
'7' => '000100101',
|
||||
'8' => '100100100',
|
||||
'9' => '001100100',
|
||||
'A' => '100001001',
|
||||
'B' => '001001001',
|
||||
'C' => '101001000',
|
||||
'D' => '000011001',
|
||||
'E' => '100011000',
|
||||
'F' => '001011000',
|
||||
'G' => '000001101',
|
||||
'H' => '100001100',
|
||||
'I' => '001001100',
|
||||
'J' => '000011100',
|
||||
'K' => '100000011',
|
||||
'L' => '001000011',
|
||||
'M' => '101000010',
|
||||
'N' => '000010011',
|
||||
'O' => '100010010',
|
||||
'P' => '001010010',
|
||||
'Q' => '000000111',
|
||||
'R' => '100000110',
|
||||
'S' => '001000110',
|
||||
'T' => '000010110',
|
||||
'U' => '110000001',
|
||||
'V' => '011000001',
|
||||
'W' => '111000000',
|
||||
'X' => '010010001',
|
||||
'Y' => '110010000',
|
||||
'Z' => '011010000',
|
||||
'-' => '010000101',
|
||||
'.' => '110000100',
|
||||
' ' => '011000100',
|
||||
'$' => '010101000',
|
||||
'/' => '010100010',
|
||||
'+' => '010001010',
|
||||
'%' => '000101010',
|
||||
'*' => '010010100',
|
||||
);
|
||||
|
||||
/**
|
||||
* Partial check of Code39 barcode
|
||||
* @return void
|
||||
*/
|
||||
protected function checkSpecificParams()
|
||||
{
|
||||
$this->checkRatio();
|
||||
}
|
||||
|
||||
/**
|
||||
* Width of the barcode (in pixels)
|
||||
* @return int
|
||||
*/
|
||||
protected function calculateBarcodeWidth()
|
||||
{
|
||||
$quietZone = $this->getQuietZone();
|
||||
$characterLength = (6 * $this->barThinWidth + 3 * $this->barThickWidth + 1) * $this->factor;
|
||||
$encodedData = strlen($this->getText()) * $characterLength - $this->factor;
|
||||
return $quietZone + $encodedData + $quietZone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set text to encode
|
||||
* @param string $value
|
||||
* @return Code39
|
||||
*/
|
||||
public function setText($value)
|
||||
{
|
||||
$this->text = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve text to display
|
||||
* @return string
|
||||
*/
|
||||
public function getText()
|
||||
{
|
||||
return '*' . parent::getText() . '*';
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve text to display
|
||||
* @return string
|
||||
*/
|
||||
public function getTextToDisplay()
|
||||
{
|
||||
$text = parent::getTextToDisplay();
|
||||
if (substr($text, 0, 1) != '*' && substr($text, -1) != '*') {
|
||||
return '*' . $text . '*';
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare array to draw barcode
|
||||
* @return array
|
||||
*/
|
||||
protected function prepareBarcode()
|
||||
{
|
||||
$text = str_split($this->getText());
|
||||
$barcodeTable = array();
|
||||
foreach ($text as $char) {
|
||||
$barcodeChar = str_split($this->codingMap[$char]);
|
||||
$visible = true;
|
||||
foreach ($barcodeChar as $c) {
|
||||
/* visible, width, top, length */
|
||||
$width = $c ? $this->barThickWidth : $this->barThinWidth;
|
||||
$barcodeTable[] = array((int) $visible, $width, 0, 1);
|
||||
$visible = ! $visible;
|
||||
}
|
||||
$barcodeTable[] = array(0, $this->barThinWidth);
|
||||
}
|
||||
return $barcodeTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get barcode checksum
|
||||
*
|
||||
* @param string $text
|
||||
* @return int
|
||||
*/
|
||||
public function getChecksum($text)
|
||||
{
|
||||
$this->checkText($text);
|
||||
$text = str_split($text);
|
||||
$charset = array_flip(array_keys($this->codingMap));
|
||||
$checksum = 0;
|
||||
foreach ($text as $character) {
|
||||
$checksum += $charset[$character];
|
||||
}
|
||||
return array_search(($checksum % 43), $charset);
|
||||
}
|
||||
}
|
198
library/Zend/Barcode/Object/Ean13.php
Executable file
198
library/Zend/Barcode/Object/Ean13.php
Executable file
|
@ -0,0 +1,198 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Object;
|
||||
|
||||
/**
|
||||
* Class for generate Ean13 barcode
|
||||
*/
|
||||
class Ean13 extends AbstractObject
|
||||
{
|
||||
/**
|
||||
* Coding map
|
||||
* - 0 = narrow bar
|
||||
* - 1 = wide bar
|
||||
* @var array
|
||||
*/
|
||||
protected $codingMap = array(
|
||||
'A' => array(
|
||||
0 => "0001101", 1 => "0011001", 2 => "0010011", 3 => "0111101", 4 => "0100011",
|
||||
5 => "0110001", 6 => "0101111", 7 => "0111011", 8 => "0110111", 9 => "0001011"
|
||||
),
|
||||
'B' => array(
|
||||
0 => "0100111", 1 => "0110011", 2 => "0011011", 3 => "0100001", 4 => "0011101",
|
||||
5 => "0111001", 6 => "0000101", 7 => "0010001", 8 => "0001001", 9 => "0010111"
|
||||
),
|
||||
'C' => array(
|
||||
0 => "1110010", 1 => "1100110", 2 => "1101100", 3 => "1000010", 4 => "1011100",
|
||||
5 => "1001110", 6 => "1010000", 7 => "1000100", 8 => "1001000", 9 => "1110100"
|
||||
));
|
||||
|
||||
protected $parities = array(
|
||||
0 => array('A','A','A','A','A','A'),
|
||||
1 => array('A','A','B','A','B','B'),
|
||||
2 => array('A','A','B','B','A','B'),
|
||||
3 => array('A','A','B','B','B','A'),
|
||||
4 => array('A','B','A','A','B','B'),
|
||||
5 => array('A','B','B','A','A','B'),
|
||||
6 => array('A','B','B','B','A','A'),
|
||||
7 => array('A','B','A','B','A','B'),
|
||||
8 => array('A','B','A','B','B','A'),
|
||||
9 => array('A','B','B','A','B','A')
|
||||
);
|
||||
|
||||
/**
|
||||
* Default options for Postnet barcode
|
||||
* @return void
|
||||
*/
|
||||
protected function getDefaultOptions()
|
||||
{
|
||||
$this->barcodeLength = 13;
|
||||
$this->mandatoryChecksum = true;
|
||||
$this->mandatoryQuietZones = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Width of the barcode (in pixels)
|
||||
* @return int
|
||||
*/
|
||||
protected function calculateBarcodeWidth()
|
||||
{
|
||||
$quietZone = $this->getQuietZone();
|
||||
$startCharacter = (3 * $this->barThinWidth) * $this->factor;
|
||||
$middleCharacter = (5 * $this->barThinWidth) * $this->factor;
|
||||
$stopCharacter = (3 * $this->barThinWidth) * $this->factor;
|
||||
$encodedData = (7 * $this->barThinWidth) * $this->factor * 12;
|
||||
return $quietZone + $startCharacter + $middleCharacter + $encodedData + $stopCharacter + $quietZone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Partial check of interleaved EAN/UPC barcode
|
||||
* @return void
|
||||
*/
|
||||
protected function checkSpecificParams()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare array to draw barcode
|
||||
* @return array
|
||||
*/
|
||||
protected function prepareBarcode()
|
||||
{
|
||||
$barcodeTable = array();
|
||||
$height = ($this->drawText) ? 1.1 : 1;
|
||||
|
||||
// Start character (101)
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, $height);
|
||||
$barcodeTable[] = array(0, $this->barThinWidth, 0, $height);
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, $height);
|
||||
|
||||
$textTable = str_split($this->getText());
|
||||
$parity = $this->parities[$textTable[0]];
|
||||
|
||||
// First part
|
||||
for ($i = 1; $i < 7; $i++) {
|
||||
$bars = str_split($this->codingMap[$parity[$i - 1]][$textTable[$i]]);
|
||||
foreach ($bars as $b) {
|
||||
$barcodeTable[] = array($b, $this->barThinWidth, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Middle character (01010)
|
||||
$barcodeTable[] = array(0, $this->barThinWidth, 0, $height);
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, $height);
|
||||
$barcodeTable[] = array(0, $this->barThinWidth, 0, $height);
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, $height);
|
||||
$barcodeTable[] = array(0, $this->barThinWidth, 0, $height);
|
||||
|
||||
// Second part
|
||||
for ($i = 7; $i < 13; $i++) {
|
||||
$bars = str_split($this->codingMap['C'][$textTable[$i]]);
|
||||
foreach ($bars as $b) {
|
||||
$barcodeTable[] = array($b, $this->barThinWidth, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Stop character (101)
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, $height);
|
||||
$barcodeTable[] = array(0, $this->barThinWidth, 0, $height);
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, $height);
|
||||
return $barcodeTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get barcode checksum
|
||||
*
|
||||
* @param string $text
|
||||
* @return int
|
||||
*/
|
||||
public function getChecksum($text)
|
||||
{
|
||||
$this->checkText($text);
|
||||
$factor = 3;
|
||||
$checksum = 0;
|
||||
|
||||
for ($i = strlen($text); $i > 0; $i --) {
|
||||
$checksum += intval($text{$i - 1}) * $factor;
|
||||
$factor = 4 - $factor;
|
||||
}
|
||||
|
||||
$checksum = (10 - ($checksum % 10)) % 10;
|
||||
|
||||
return $checksum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Partial function to draw text
|
||||
* @return void
|
||||
*/
|
||||
protected function drawText()
|
||||
{
|
||||
if (get_class($this) == 'Zend\Barcode\Object\Ean13') {
|
||||
$this->drawEan13Text();
|
||||
} else {
|
||||
parent::drawText();
|
||||
}
|
||||
}
|
||||
|
||||
protected function drawEan13Text()
|
||||
{
|
||||
if ($this->drawText) {
|
||||
$text = $this->getTextToDisplay();
|
||||
$characterWidth = (7 * $this->barThinWidth) * $this->factor;
|
||||
$leftPosition = $this->getQuietZone() - $characterWidth;
|
||||
for ($i = 0; $i < $this->barcodeLength; $i ++) {
|
||||
$this->addText(
|
||||
$text{$i},
|
||||
$this->fontSize * $this->factor,
|
||||
$this->rotate(
|
||||
$leftPosition,
|
||||
(int) $this->withBorder * 2 + $this->factor * ($this->barHeight + $this->fontSize) + 1
|
||||
),
|
||||
$this->font,
|
||||
$this->foreColor,
|
||||
'left',
|
||||
- $this->orientation
|
||||
);
|
||||
switch ($i) {
|
||||
case 0:
|
||||
$factor = 3;
|
||||
break;
|
||||
case 6:
|
||||
$factor = 4;
|
||||
break;
|
||||
default:
|
||||
$factor = 0;
|
||||
}
|
||||
$leftPosition = $leftPosition + $characterWidth + ($factor * $this->barThinWidth * $this->factor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
38
library/Zend/Barcode/Object/Ean2.php
Executable file
38
library/Zend/Barcode/Object/Ean2.php
Executable file
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Object;
|
||||
|
||||
/**
|
||||
* Class for generate Ean2 barcode
|
||||
*/
|
||||
class Ean2 extends Ean5
|
||||
{
|
||||
protected $parities = array(
|
||||
0 => array('A','A'),
|
||||
1 => array('A','B'),
|
||||
2 => array('B','A'),
|
||||
3 => array('B','B')
|
||||
);
|
||||
|
||||
/**
|
||||
* Default options for Ean2 barcode
|
||||
* @return void
|
||||
*/
|
||||
protected function getDefaultOptions()
|
||||
{
|
||||
$this->barcodeLength = 2;
|
||||
}
|
||||
|
||||
protected function getParity($i)
|
||||
{
|
||||
$modulo = $this->getText() % 4;
|
||||
return $this->parities[$modulo][$i];
|
||||
}
|
||||
}
|
124
library/Zend/Barcode/Object/Ean5.php
Executable file
124
library/Zend/Barcode/Object/Ean5.php
Executable file
|
@ -0,0 +1,124 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Object;
|
||||
|
||||
/**
|
||||
* Class for generate Ean5 barcode
|
||||
*/
|
||||
class Ean5 extends Ean13
|
||||
{
|
||||
protected $parities = array(
|
||||
0 => array('B','B','A','A','A'),
|
||||
1 => array('B','A','B','A','A'),
|
||||
2 => array('B','A','A','B','A'),
|
||||
3 => array('B','A','A','A','B'),
|
||||
4 => array('A','B','B','A','A'),
|
||||
5 => array('A','A','B','B','A'),
|
||||
6 => array('A','A','A','B','B'),
|
||||
7 => array('A','B','A','B','A'),
|
||||
8 => array('A','B','A','A','B'),
|
||||
9 => array('A','A','B','A','B')
|
||||
);
|
||||
|
||||
/**
|
||||
* Default options for Ean5 barcode
|
||||
* @return void
|
||||
*/
|
||||
protected function getDefaultOptions()
|
||||
{
|
||||
$this->barcodeLength = 5;
|
||||
}
|
||||
|
||||
/**
|
||||
* Width of the barcode (in pixels)
|
||||
* @return int
|
||||
*/
|
||||
protected function calculateBarcodeWidth()
|
||||
{
|
||||
$quietZone = $this->getQuietZone();
|
||||
$startCharacter = (5 * $this->barThinWidth) * $this->factor;
|
||||
$middleCharacter = (2 * $this->barThinWidth) * $this->factor;
|
||||
$encodedData = (7 * $this->barThinWidth) * $this->factor;
|
||||
return $quietZone + $startCharacter + ($this->barcodeLength - 1) * $middleCharacter + $this->barcodeLength * $encodedData + $quietZone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare array to draw barcode
|
||||
* @return array
|
||||
*/
|
||||
protected function prepareBarcode()
|
||||
{
|
||||
$barcodeTable = array();
|
||||
|
||||
// Start character (01011)
|
||||
$barcodeTable[] = array(0, $this->barThinWidth, 0, 1);
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, 1);
|
||||
$barcodeTable[] = array(0, $this->barThinWidth, 0, 1);
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, 1);
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, 1);
|
||||
|
||||
$firstCharacter = true;
|
||||
$textTable = str_split($this->getText());
|
||||
|
||||
// Characters
|
||||
for ($i = 0; $i < $this->barcodeLength; $i++) {
|
||||
if ($firstCharacter) {
|
||||
$firstCharacter = false;
|
||||
} else {
|
||||
// Intermediate character (01)
|
||||
$barcodeTable[] = array(0, $this->barThinWidth, 0, 1);
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, 1);
|
||||
}
|
||||
$bars = str_split($this->codingMap[$this->getParity($i)][$textTable[$i]]);
|
||||
foreach ($bars as $b) {
|
||||
$barcodeTable[] = array($b, $this->barThinWidth, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return $barcodeTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get barcode checksum
|
||||
*
|
||||
* @param string $text
|
||||
* @return int
|
||||
*/
|
||||
public function getChecksum($text)
|
||||
{
|
||||
$this->checkText($text);
|
||||
$checksum = 0;
|
||||
|
||||
for ($i = 0; $i < $this->barcodeLength; $i ++) {
|
||||
$checksum += intval($text{$i}) * ($i % 2 ? 9 : 3);
|
||||
}
|
||||
|
||||
return ($checksum % 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $i
|
||||
* @return string
|
||||
*/
|
||||
protected function getParity($i)
|
||||
{
|
||||
$checksum = $this->getChecksum($this->getText());
|
||||
return $this->parities[$checksum][$i];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve text to encode
|
||||
* @return string
|
||||
*/
|
||||
public function getText()
|
||||
{
|
||||
return $this->addLeadingZeros($this->text);
|
||||
}
|
||||
}
|
146
library/Zend/Barcode/Object/Ean8.php
Executable file
146
library/Zend/Barcode/Object/Ean8.php
Executable file
|
@ -0,0 +1,146 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Object;
|
||||
|
||||
use Zend\Validator\Barcode as BarcodeValidator;
|
||||
|
||||
/**
|
||||
* Class for generate Ean8 barcode
|
||||
*/
|
||||
class Ean8 extends Ean13
|
||||
{
|
||||
/**
|
||||
* Default options for Postnet barcode
|
||||
* @return void
|
||||
*/
|
||||
protected function getDefaultOptions()
|
||||
{
|
||||
$this->barcodeLength = 8;
|
||||
$this->mandatoryChecksum = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Width of the barcode (in pixels)
|
||||
* @return int
|
||||
*/
|
||||
protected function calculateBarcodeWidth()
|
||||
{
|
||||
$quietZone = $this->getQuietZone();
|
||||
$startCharacter = (3 * $this->barThinWidth) * $this->factor;
|
||||
$middleCharacter = (5 * $this->barThinWidth) * $this->factor;
|
||||
$stopCharacter = (3 * $this->barThinWidth) * $this->factor;
|
||||
$encodedData = (7 * $this->barThinWidth) * $this->factor * 8;
|
||||
return $quietZone + $startCharacter + $middleCharacter + $encodedData + $stopCharacter + $quietZone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare array to draw barcode
|
||||
* @return array
|
||||
*/
|
||||
protected function prepareBarcode()
|
||||
{
|
||||
$barcodeTable = array();
|
||||
$height = ($this->drawText) ? 1.1 : 1;
|
||||
|
||||
// Start character (101)
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, $height);
|
||||
$barcodeTable[] = array(0, $this->barThinWidth, 0, $height);
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, $height);
|
||||
|
||||
$textTable = str_split($this->getText());
|
||||
|
||||
// First part
|
||||
for ($i = 0; $i < 4; $i++) {
|
||||
$bars = str_split($this->codingMap['A'][$textTable[$i]]);
|
||||
foreach ($bars as $b) {
|
||||
$barcodeTable[] = array($b, $this->barThinWidth, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Middle character (01010)
|
||||
$barcodeTable[] = array(0, $this->barThinWidth, 0, $height);
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, $height);
|
||||
$barcodeTable[] = array(0, $this->barThinWidth, 0, $height);
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, $height);
|
||||
$barcodeTable[] = array(0, $this->barThinWidth, 0, $height);
|
||||
|
||||
// Second part
|
||||
for ($i = 4; $i < 8; $i++) {
|
||||
$bars = str_split($this->codingMap['C'][$textTable[$i]]);
|
||||
foreach ($bars as $b) {
|
||||
$barcodeTable[] = array($b, $this->barThinWidth, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Stop character (101)
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, $height);
|
||||
$barcodeTable[] = array(0, $this->barThinWidth, 0, $height);
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, $height);
|
||||
return $barcodeTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Partial function to draw text
|
||||
* @return void
|
||||
*/
|
||||
protected function drawText()
|
||||
{
|
||||
if ($this->drawText) {
|
||||
$text = $this->getTextToDisplay();
|
||||
$characterWidth = (7 * $this->barThinWidth) * $this->factor;
|
||||
$leftPosition = $this->getQuietZone() + (3 * $this->barThinWidth) * $this->factor;
|
||||
for ($i = 0; $i < $this->barcodeLength; $i ++) {
|
||||
$this->addText(
|
||||
$text{$i},
|
||||
$this->fontSize * $this->factor,
|
||||
$this->rotate(
|
||||
$leftPosition,
|
||||
(int) $this->withBorder * 2 + $this->factor * ($this->barHeight + $this->fontSize) + 1
|
||||
),
|
||||
$this->font,
|
||||
$this->foreColor,
|
||||
'left',
|
||||
- $this->orientation
|
||||
);
|
||||
switch ($i) {
|
||||
case 3:
|
||||
$factor = 4;
|
||||
break;
|
||||
default:
|
||||
$factor = 0;
|
||||
}
|
||||
$leftPosition = $leftPosition + $characterWidth + ($factor * $this->barThinWidth * $this->factor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Particular validation for Ean8 barcode objects
|
||||
* (to suppress checksum character substitution)
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $options
|
||||
* @throws Exception\BarcodeValidationException
|
||||
*/
|
||||
protected function validateSpecificText($value, $options = array())
|
||||
{
|
||||
$validator = new BarcodeValidator(array(
|
||||
'adapter' => 'ean8',
|
||||
'checksum' => false,
|
||||
));
|
||||
|
||||
$value = $this->addLeadingZeros($value, true);
|
||||
|
||||
if (!$validator->isValid($value)) {
|
||||
$message = implode("\n", $validator->getMessages());
|
||||
throw new Exception\BarcodeValidationException($message);
|
||||
}
|
||||
}
|
||||
}
|
83
library/Zend/Barcode/Object/Error.php
Executable file
83
library/Zend/Barcode/Object/Error.php
Executable file
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Object;
|
||||
|
||||
/**
|
||||
* Class for generate Barcode
|
||||
*/
|
||||
class Error extends AbstractObject
|
||||
{
|
||||
/**
|
||||
* All texts are accepted
|
||||
* @param string $value
|
||||
* @return bool
|
||||
*/
|
||||
public function validateText($value)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Height is forced
|
||||
* @param bool $recalculate
|
||||
* @return int
|
||||
*/
|
||||
public function getHeight($recalculate = false)
|
||||
{
|
||||
return 40;
|
||||
}
|
||||
|
||||
/**
|
||||
* Width is forced
|
||||
* @param bool $recalculate
|
||||
* @return int
|
||||
*/
|
||||
public function getWidth($recalculate = false)
|
||||
{
|
||||
return 400;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset precedent instructions
|
||||
* and draw the error message
|
||||
* @return array
|
||||
*/
|
||||
public function draw()
|
||||
{
|
||||
$this->instructions = array();
|
||||
$this->addText('ERROR:', 10, array(5, 18), $this->font, 0, 'left');
|
||||
$this->addText($this->text, 10, array(5, 32), $this->font, 0, 'left');
|
||||
return $this->instructions;
|
||||
}
|
||||
|
||||
/**
|
||||
* For compatibility reason
|
||||
* @return void
|
||||
*/
|
||||
protected function prepareBarcode()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* For compatibility reason
|
||||
* @return void
|
||||
*/
|
||||
protected function checkSpecificParams()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* For compatibility reason
|
||||
* @return void
|
||||
*/
|
||||
protected function calculateBarcodeWidth()
|
||||
{
|
||||
}
|
||||
}
|
17
library/Zend/Barcode/Object/Exception/BarcodeValidationException.php
Executable file
17
library/Zend/Barcode/Object/Exception/BarcodeValidationException.php
Executable file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Object\Exception;
|
||||
|
||||
/**
|
||||
* Exception for Zend\Barcode component.
|
||||
*/
|
||||
class BarcodeValidationException extends InvalidArgumentException
|
||||
{
|
||||
}
|
19
library/Zend/Barcode/Object/Exception/ExceptionInterface.php
Executable file
19
library/Zend/Barcode/Object/Exception/ExceptionInterface.php
Executable file
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Object\Exception;
|
||||
|
||||
use Zend\Barcode\Exception\ExceptionInterface as Exception;
|
||||
|
||||
/**
|
||||
* Base exception interface for barcode objects
|
||||
*/
|
||||
interface ExceptionInterface extends Exception
|
||||
{
|
||||
}
|
17
library/Zend/Barcode/Object/Exception/ExtensionNotLoadedException.php
Executable file
17
library/Zend/Barcode/Object/Exception/ExtensionNotLoadedException.php
Executable file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Object\Exception;
|
||||
|
||||
/**
|
||||
* Exception for Zend\Barcode component.
|
||||
*/
|
||||
class ExtensionNotLoadedException extends RuntimeException
|
||||
{
|
||||
}
|
20
library/Zend/Barcode/Object/Exception/InvalidArgumentException.php
Executable file
20
library/Zend/Barcode/Object/Exception/InvalidArgumentException.php
Executable file
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Object\Exception;
|
||||
|
||||
use Zend\Barcode\Exception;
|
||||
|
||||
/**
|
||||
* Exception for Zend\Barcode component.
|
||||
*/
|
||||
class InvalidArgumentException extends Exception\InvalidArgumentException implements
|
||||
ExceptionInterface
|
||||
{
|
||||
}
|
20
library/Zend/Barcode/Object/Exception/OutOfRangeException.php
Executable file
20
library/Zend/Barcode/Object/Exception/OutOfRangeException.php
Executable file
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Object\Exception;
|
||||
|
||||
use Zend\Barcode\Exception;
|
||||
|
||||
/**
|
||||
* Exception for Zend\Barcode component.
|
||||
*/
|
||||
class OutOfRangeException extends Exception\OutOfRangeException implements
|
||||
ExceptionInterface
|
||||
{
|
||||
}
|
20
library/Zend/Barcode/Object/Exception/RuntimeException.php
Executable file
20
library/Zend/Barcode/Object/Exception/RuntimeException.php
Executable file
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Object\Exception;
|
||||
|
||||
use Zend\Barcode\Exception;
|
||||
|
||||
/**
|
||||
* Exception for Zend\Barcode component.
|
||||
*/
|
||||
class RuntimeException extends Exception\RuntimeException implements
|
||||
ExceptionInterface
|
||||
{
|
||||
}
|
66
library/Zend/Barcode/Object/Identcode.php
Executable file
66
library/Zend/Barcode/Object/Identcode.php
Executable file
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Object;
|
||||
|
||||
/**
|
||||
* Class for generate Identcode barcode
|
||||
*/
|
||||
class Identcode extends Code25interleaved
|
||||
{
|
||||
/**
|
||||
* Default options for Identcode barcode
|
||||
* @return void
|
||||
*/
|
||||
protected function getDefaultOptions()
|
||||
{
|
||||
$this->barcodeLength = 12;
|
||||
$this->mandatoryChecksum = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve text to display
|
||||
* @return string
|
||||
*/
|
||||
public function getTextToDisplay()
|
||||
{
|
||||
return preg_replace('/([0-9]{2})([0-9]{3})([0-9]{3})([0-9]{3})([0-9])/', '$1.$2 $3.$4 $5', $this->getText());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check allowed characters
|
||||
* @param string $value
|
||||
* @return string
|
||||
* @throws Exception\BarcodeValidationException
|
||||
*/
|
||||
public function validateText($value)
|
||||
{
|
||||
$this->validateSpecificText($value, array('validator' => $this->getType()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get barcode checksum
|
||||
*
|
||||
* @param string $text
|
||||
* @return int
|
||||
*/
|
||||
public function getChecksum($text)
|
||||
{
|
||||
$this->checkText($text);
|
||||
$checksum = 0;
|
||||
|
||||
for ($i = strlen($text); $i > 0; $i --) {
|
||||
$checksum += intval($text{$i - 1}) * (($i % 2) ? 4 : 9);
|
||||
}
|
||||
|
||||
$checksum = (10 - ($checksum % 10)) % 10;
|
||||
|
||||
return $checksum;
|
||||
}
|
||||
}
|
26
library/Zend/Barcode/Object/Itf14.php
Executable file
26
library/Zend/Barcode/Object/Itf14.php
Executable file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Object;
|
||||
|
||||
/**
|
||||
* Class for generate Itf14 barcode
|
||||
*/
|
||||
class Itf14 extends Code25interleaved
|
||||
{
|
||||
/**
|
||||
* Default options for Identcode barcode
|
||||
* @return void
|
||||
*/
|
||||
protected function getDefaultOptions()
|
||||
{
|
||||
$this->barcodeLength = 14;
|
||||
$this->mandatoryChecksum = true;
|
||||
}
|
||||
}
|
35
library/Zend/Barcode/Object/Leitcode.php
Executable file
35
library/Zend/Barcode/Object/Leitcode.php
Executable file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Object;
|
||||
|
||||
/**
|
||||
* Class for generate Identcode barcode
|
||||
*/
|
||||
class Leitcode extends Identcode
|
||||
{
|
||||
/**
|
||||
* Default options for Leitcode barcode
|
||||
* @return void
|
||||
*/
|
||||
protected function getDefaultOptions()
|
||||
{
|
||||
$this->barcodeLength = 14;
|
||||
$this->mandatoryChecksum = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve text to display
|
||||
* @return string
|
||||
*/
|
||||
public function getTextToDisplay()
|
||||
{
|
||||
return preg_replace('/([0-9]{5})([0-9]{3})([0-9]{3})([0-9]{2})([0-9])/', '$1.$2.$3.$4 $5', $this->getText());
|
||||
}
|
||||
}
|
337
library/Zend/Barcode/Object/ObjectInterface.php
Executable file
337
library/Zend/Barcode/Object/ObjectInterface.php
Executable file
|
@ -0,0 +1,337 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Object;
|
||||
|
||||
/**
|
||||
* Interface for generate Barcode
|
||||
*/
|
||||
interface ObjectInterface
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
* @param array|\Traversable $options
|
||||
*/
|
||||
public function __construct($options = null);
|
||||
|
||||
/**
|
||||
* Set barcode state from options array
|
||||
* @param array $options
|
||||
* @return ObjectInterface
|
||||
*/
|
||||
public function setOptions($options);
|
||||
|
||||
/**
|
||||
* Set barcode namespace for autoloading
|
||||
*
|
||||
* @param string $namespace
|
||||
* @return ObjectInterface
|
||||
*/
|
||||
public function setBarcodeNamespace($namespace);
|
||||
|
||||
/**
|
||||
* Retrieve barcode namespace
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBarcodeNamespace();
|
||||
|
||||
/**
|
||||
* Retrieve type of barcode
|
||||
* @return string
|
||||
*/
|
||||
public function getType();
|
||||
|
||||
/**
|
||||
* Set height of the barcode bar
|
||||
* @param int $value
|
||||
* @return ObjectInterface
|
||||
*/
|
||||
public function setBarHeight($value);
|
||||
|
||||
/**
|
||||
* Get height of the barcode bar
|
||||
* @return int
|
||||
*/
|
||||
public function getBarHeight();
|
||||
|
||||
/**
|
||||
* Set thickness of thin bar
|
||||
* @param int $value
|
||||
* @return ObjectInterface
|
||||
*/
|
||||
public function setBarThinWidth($value);
|
||||
|
||||
/**
|
||||
* Get thickness of thin bar
|
||||
* @return int
|
||||
*/
|
||||
public function getBarThinWidth();
|
||||
|
||||
/**
|
||||
* Set thickness of thick bar
|
||||
* @param int $value
|
||||
* @return ObjectInterface
|
||||
*/
|
||||
public function setBarThickWidth($value);
|
||||
|
||||
/**
|
||||
* Get thickness of thick bar
|
||||
* @return int
|
||||
*/
|
||||
public function getBarThickWidth();
|
||||
|
||||
/**
|
||||
* Set factor applying to
|
||||
* thinBarWidth - thickBarWidth - barHeight - fontSize
|
||||
* @param int $value
|
||||
* @return ObjectInterface
|
||||
*/
|
||||
public function setFactor($value);
|
||||
|
||||
/**
|
||||
* Get factor applying to
|
||||
* thinBarWidth - thickBarWidth - barHeight - fontSize
|
||||
* @return int
|
||||
*/
|
||||
public function getFactor();
|
||||
|
||||
/**
|
||||
* Set color of the barcode and text
|
||||
* @param string $value
|
||||
* @return ObjectInterface
|
||||
*/
|
||||
public function setForeColor($value);
|
||||
|
||||
/**
|
||||
* Retrieve color of the barcode and text
|
||||
* @return int
|
||||
*/
|
||||
public function getForeColor();
|
||||
|
||||
/**
|
||||
* Set the color of the background
|
||||
* @param int $value
|
||||
* @return ObjectInterface
|
||||
*/
|
||||
public function setBackgroundColor($value);
|
||||
|
||||
/**
|
||||
* Retrieve background color of the image
|
||||
* @return int
|
||||
*/
|
||||
public function getBackgroundColor();
|
||||
|
||||
/**
|
||||
* Activate/deactivate drawing of the bar
|
||||
* @param bool $value
|
||||
* @return ObjectInterface
|
||||
*/
|
||||
public function setWithBorder($value);
|
||||
|
||||
/**
|
||||
* Retrieve if border are draw or not
|
||||
* @return bool
|
||||
*/
|
||||
public function getWithBorder();
|
||||
|
||||
/**
|
||||
* Allow fast inversion of font/bars color and background color
|
||||
* @return ObjectInterface
|
||||
*/
|
||||
public function setReverseColor();
|
||||
|
||||
/**
|
||||
* Set orientation of barcode and text
|
||||
* @param float $value
|
||||
* @return ObjectInterface
|
||||
*/
|
||||
public function setOrientation($value);
|
||||
|
||||
/**
|
||||
* Retrieve orientation of barcode and text
|
||||
* @return float
|
||||
*/
|
||||
public function getOrientation();
|
||||
|
||||
/**
|
||||
* Set text to encode
|
||||
* @param string $value
|
||||
* @return ObjectInterface
|
||||
*/
|
||||
public function setText($value);
|
||||
|
||||
/**
|
||||
* Retrieve text to encode
|
||||
* @return string
|
||||
*/
|
||||
public function getText();
|
||||
|
||||
/**
|
||||
* Retrieve text to encode
|
||||
* @return string
|
||||
*/
|
||||
public function getRawText();
|
||||
|
||||
/**
|
||||
* Retrieve text to display
|
||||
* @return string
|
||||
*/
|
||||
public function getTextToDisplay();
|
||||
|
||||
/**
|
||||
* Activate/deactivate drawing of text to encode
|
||||
* @param bool $value
|
||||
* @return ObjectInterface
|
||||
*/
|
||||
public function setDrawText($value);
|
||||
|
||||
/**
|
||||
* Retrieve if drawing of text to encode is enabled
|
||||
* @return bool
|
||||
*/
|
||||
public function getDrawText();
|
||||
|
||||
/**
|
||||
* Activate/deactivate the adjustment of the position
|
||||
* of the characters to the position of the bars
|
||||
* @param bool $value
|
||||
* @return ObjectInterface
|
||||
*/
|
||||
public function setStretchText($value);
|
||||
|
||||
/**
|
||||
* Retrieve if the adjustment of the position of the characters
|
||||
* to the position of the bars is enabled
|
||||
* @return bool
|
||||
*/
|
||||
public function getStretchText();
|
||||
|
||||
/**
|
||||
* Activate/deactivate the automatic generation
|
||||
* of the checksum character
|
||||
* added to the barcode text
|
||||
* @param bool $value
|
||||
* @return ObjectInterface
|
||||
*/
|
||||
public function setWithChecksum($value);
|
||||
|
||||
/**
|
||||
* Retrieve if the checksum character is automatically
|
||||
* added to the barcode text
|
||||
* @return bool
|
||||
*/
|
||||
public function getWithChecksum();
|
||||
|
||||
/**
|
||||
* Activate/deactivate the automatic generation
|
||||
* of the checksum character
|
||||
* added to the barcode text
|
||||
* @param bool $value
|
||||
* @return ObjectInterface
|
||||
*/
|
||||
public function setWithChecksumInText($value);
|
||||
|
||||
/**
|
||||
* Retrieve if the checksum character is automatically
|
||||
* added to the barcode text
|
||||
* @return bool
|
||||
*/
|
||||
public function getWithChecksumInText();
|
||||
|
||||
/**
|
||||
* Set the font:
|
||||
* - if integer between 1 and 5, use gd built-in fonts
|
||||
* - if string, $value is assumed to be the path to a TTF font
|
||||
* @param int|string $value
|
||||
* @return ObjectInterface
|
||||
*/
|
||||
public function setFont($value);
|
||||
|
||||
/**
|
||||
* Retrieve the font
|
||||
* @return int|string
|
||||
*/
|
||||
public function getFont();
|
||||
|
||||
/**
|
||||
* Set the size of the font in case of TTF
|
||||
* @param float $value
|
||||
* @return ObjectInterface
|
||||
*/
|
||||
public function setFontSize($value);
|
||||
|
||||
/**
|
||||
* Retrieve the size of the font in case of TTF
|
||||
* @return float
|
||||
*/
|
||||
public function getFontSize();
|
||||
|
||||
/**
|
||||
* Quiet zone before first bar
|
||||
* and after the last bar
|
||||
* @return int
|
||||
*/
|
||||
public function getQuietZone();
|
||||
|
||||
/**
|
||||
* Retrieve the set of drawing instructions
|
||||
* @return array
|
||||
*/
|
||||
public function getInstructions();
|
||||
|
||||
/**
|
||||
* Checking of parameters after all settings
|
||||
* @return void
|
||||
*/
|
||||
public function checkParams();
|
||||
|
||||
/**
|
||||
* Get height of the result object
|
||||
* @param bool $recalculate
|
||||
* @return int
|
||||
*/
|
||||
public function getHeight($recalculate = false);
|
||||
|
||||
/**
|
||||
* Get width of the result object
|
||||
* @param bool $recalculate
|
||||
* @return int
|
||||
*/
|
||||
public function getWidth($recalculate = false);
|
||||
|
||||
/**
|
||||
* Calculate the offset from the left of the object
|
||||
* if an orientation is activated
|
||||
* @param bool $recalculate
|
||||
* @return float
|
||||
*/
|
||||
public function getOffsetLeft($recalculate = false);
|
||||
|
||||
/**
|
||||
* Calculate the offset from the top of the object
|
||||
* if an orientation is activated
|
||||
* @param bool $recalculate
|
||||
* @return float
|
||||
*/
|
||||
public function getOffsetTop($recalculate = false);
|
||||
|
||||
/**
|
||||
* Complete drawing of the barcode
|
||||
* @return array Table of instructions
|
||||
*/
|
||||
public function draw();
|
||||
|
||||
/**
|
||||
* Check for invalid characters
|
||||
* @param string $value Text to be checked
|
||||
* @return void
|
||||
*/
|
||||
public function validateText($value);
|
||||
}
|
35
library/Zend/Barcode/Object/Planet.php
Executable file
35
library/Zend/Barcode/Object/Planet.php
Executable file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Object;
|
||||
|
||||
/**
|
||||
* Class for generate Planet barcode
|
||||
*/
|
||||
class Planet extends Postnet
|
||||
{
|
||||
/**
|
||||
* Coding map
|
||||
* - 0 = half bar
|
||||
* - 1 = complete bar
|
||||
* @var array
|
||||
*/
|
||||
protected $codingMap = array(
|
||||
0 => "00111",
|
||||
1 => "11100",
|
||||
2 => "11010",
|
||||
3 => "11001",
|
||||
4 => "10110",
|
||||
5 => "10101",
|
||||
6 => "10011",
|
||||
7 => "01110",
|
||||
8 => "01101",
|
||||
9 => "01011"
|
||||
);
|
||||
}
|
110
library/Zend/Barcode/Object/Postnet.php
Executable file
110
library/Zend/Barcode/Object/Postnet.php
Executable file
|
@ -0,0 +1,110 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Object;
|
||||
|
||||
/**
|
||||
* Class for generate Postnet barcode
|
||||
*/
|
||||
class Postnet extends AbstractObject
|
||||
{
|
||||
/**
|
||||
* Coding map
|
||||
* - 0 = half bar
|
||||
* - 1 = complete bar
|
||||
* @var array
|
||||
*/
|
||||
protected $codingMap = array(
|
||||
0 => "11000",
|
||||
1 => "00011",
|
||||
2 => "00101",
|
||||
3 => "00110",
|
||||
4 => "01001",
|
||||
5 => "01010",
|
||||
6 => "01100",
|
||||
7 => "10001",
|
||||
8 => "10010",
|
||||
9 => "10100"
|
||||
);
|
||||
|
||||
/**
|
||||
* Default options for Postnet barcode
|
||||
* @return void
|
||||
*/
|
||||
protected function getDefaultOptions()
|
||||
{
|
||||
$this->barThinWidth = 2;
|
||||
$this->barHeight = 20;
|
||||
$this->drawText = false;
|
||||
$this->stretchText = true;
|
||||
$this->mandatoryChecksum = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Width of the barcode (in pixels)
|
||||
* @return int
|
||||
*/
|
||||
protected function calculateBarcodeWidth()
|
||||
{
|
||||
$quietZone = $this->getQuietZone();
|
||||
$startCharacter = (2 * $this->barThinWidth) * $this->factor;
|
||||
$stopCharacter = (1 * $this->barThinWidth) * $this->factor;
|
||||
$encodedData = (10 * $this->barThinWidth) * $this->factor * strlen($this->getText());
|
||||
return $quietZone + $startCharacter + $encodedData + $stopCharacter + $quietZone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Partial check of interleaved Postnet barcode
|
||||
* @return void
|
||||
*/
|
||||
protected function checkSpecificParams()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare array to draw barcode
|
||||
* @return array
|
||||
*/
|
||||
protected function prepareBarcode()
|
||||
{
|
||||
$barcodeTable = array();
|
||||
|
||||
// Start character (1)
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, 1);
|
||||
$barcodeTable[] = array(0, $this->barThinWidth, 0, 1);
|
||||
|
||||
// Text to encode
|
||||
$textTable = str_split($this->getText());
|
||||
foreach ($textTable as $char) {
|
||||
$bars = str_split($this->codingMap[$char]);
|
||||
foreach ($bars as $b) {
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0.5 - $b * 0.5, 1);
|
||||
$barcodeTable[] = array(0, $this->barThinWidth, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Stop character (1)
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, 1);
|
||||
return $barcodeTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get barcode checksum
|
||||
*
|
||||
* @param string $text
|
||||
* @return int
|
||||
*/
|
||||
public function getChecksum($text)
|
||||
{
|
||||
$this->checkText($text);
|
||||
$sum = array_sum(str_split($text));
|
||||
$checksum = (10 - ($sum % 10)) % 10;
|
||||
return $checksum;
|
||||
}
|
||||
}
|
137
library/Zend/Barcode/Object/Royalmail.php
Executable file
137
library/Zend/Barcode/Object/Royalmail.php
Executable file
|
@ -0,0 +1,137 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Object;
|
||||
|
||||
/**
|
||||
* Class for generate Royal maim barcode
|
||||
*/
|
||||
class Royalmail extends AbstractObject
|
||||
{
|
||||
/**
|
||||
* Coding map
|
||||
* - 0 = Tracker, Ascender and Descender
|
||||
* - 1 = Tracker and Ascender
|
||||
* - 2 = Tracker and Descender
|
||||
* - 3 = Tracker
|
||||
* @var array
|
||||
*/
|
||||
protected $codingMap = array(
|
||||
'0' => '3300', '1' => '3210', '2' => '3201', '3' => '2310', '4' => '2301', '5' => '2211',
|
||||
'6' => '3120', '7' => '3030', '8' => '3021', '9' => '2130', 'A' => '2121', 'B' => '2031',
|
||||
'C' => '3102', 'D' => '3012', 'E' => '3003', 'F' => '2112', 'G' => '2103', 'H' => '2013',
|
||||
'I' => '1320', 'J' => '1230', 'K' => '1221', 'L' => '0330', 'M' => '0321', 'N' => '0231',
|
||||
'O' => '1302', 'P' => '1212', 'Q' => '1203', 'R' => '0312', 'S' => '0303', 'T' => '0213',
|
||||
'U' => '1122', 'V' => '1032', 'W' => '1023', 'X' => '0132', 'Y' => '0123', 'Z' => '0033'
|
||||
);
|
||||
|
||||
protected $rows = array(
|
||||
'0' => 1, '1' => 1, '2' => 1, '3' => 1, '4' => 1, '5' => 1,
|
||||
'6' => 2, '7' => 2, '8' => 2, '9' => 2, 'A' => 2, 'B' => 2,
|
||||
'C' => 3, 'D' => 3, 'E' => 3, 'F' => 3, 'G' => 3, 'H' => 3,
|
||||
'I' => 4, 'J' => 4, 'K' => 4, 'L' => 4, 'M' => 4, 'N' => 4,
|
||||
'O' => 5, 'P' => 5, 'Q' => 5, 'R' => 5, 'S' => 5, 'T' => 5,
|
||||
'U' => 0, 'V' => 0, 'W' => 0, 'X' => 0, 'Y' => 0, 'Z' => 0,
|
||||
);
|
||||
|
||||
protected $columns = array(
|
||||
'0' => 1, '1' => 2, '2' => 3, '3' => 4, '4' => 5, '5' => 0,
|
||||
'6' => 1, '7' => 2, '8' => 3, '9' => 4, 'A' => 5, 'B' => 0,
|
||||
'C' => 1, 'D' => 2, 'E' => 3, 'F' => 4, 'G' => 5, 'H' => 0,
|
||||
'I' => 1, 'J' => 2, 'K' => 3, 'L' => 4, 'M' => 5, 'N' => 0,
|
||||
'O' => 1, 'P' => 2, 'Q' => 3, 'R' => 4, 'S' => 5, 'T' => 0,
|
||||
'U' => 1, 'V' => 2, 'W' => 3, 'X' => 4, 'Y' => 5, 'Z' => 0,
|
||||
);
|
||||
|
||||
/**
|
||||
* Default options for Postnet barcode
|
||||
* @return void
|
||||
*/
|
||||
protected function getDefaultOptions()
|
||||
{
|
||||
$this->barThinWidth = 2;
|
||||
$this->barHeight = 20;
|
||||
$this->drawText = false;
|
||||
$this->stretchText = true;
|
||||
$this->mandatoryChecksum = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Width of the barcode (in pixels)
|
||||
* @return int
|
||||
*/
|
||||
protected function calculateBarcodeWidth()
|
||||
{
|
||||
$quietZone = $this->getQuietZone();
|
||||
$startCharacter = (2 * $this->barThinWidth) * $this->factor;
|
||||
$stopCharacter = (1 * $this->barThinWidth) * $this->factor;
|
||||
$encodedData = (8 * $this->barThinWidth) * $this->factor * strlen($this->getText());
|
||||
return $quietZone + $startCharacter + $encodedData + $stopCharacter + $quietZone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Partial check of interleaved Postnet barcode
|
||||
* @return void
|
||||
*/
|
||||
protected function checkSpecificParams()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare array to draw barcode
|
||||
* @return array
|
||||
*/
|
||||
protected function prepareBarcode()
|
||||
{
|
||||
$barcodeTable = array();
|
||||
|
||||
// Start character (1)
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, 5/8);
|
||||
$barcodeTable[] = array(0, $this->barThinWidth, 0, 1);
|
||||
|
||||
// Text to encode
|
||||
$textTable = str_split($this->getText());
|
||||
foreach ($textTable as $char) {
|
||||
$bars = str_split($this->codingMap[$char]);
|
||||
foreach ($bars as $b) {
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, ($b > 1 ? 3/8 : 0), ($b % 2 ? 5/8 : 1));
|
||||
$barcodeTable[] = array(0, $this->barThinWidth, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Stop character (1)
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, 1);
|
||||
return $barcodeTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get barcode checksum
|
||||
*
|
||||
* @param string $text
|
||||
* @return int
|
||||
*/
|
||||
public function getChecksum($text)
|
||||
{
|
||||
$this->checkText($text);
|
||||
$values = str_split($text);
|
||||
$rowvalue = 0;
|
||||
$colvalue = 0;
|
||||
foreach ($values as $row) {
|
||||
$rowvalue += $this->rows[$row];
|
||||
$colvalue += $this->columns[$row];
|
||||
}
|
||||
|
||||
$rowvalue %= 6;
|
||||
$colvalue %= 6;
|
||||
|
||||
$rowchkvalue = array_keys($this->rows, $rowvalue);
|
||||
$colchkvalue = array_keys($this->columns, $colvalue);
|
||||
return current(array_intersect($rowchkvalue, $colchkvalue));
|
||||
}
|
||||
}
|
144
library/Zend/Barcode/Object/Upca.php
Executable file
144
library/Zend/Barcode/Object/Upca.php
Executable file
|
@ -0,0 +1,144 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Object;
|
||||
|
||||
/**
|
||||
* Class for generate UpcA barcode
|
||||
*/
|
||||
class Upca extends Ean13
|
||||
{
|
||||
/**
|
||||
* Default options for Postnet barcode
|
||||
* @return void
|
||||
*/
|
||||
protected function getDefaultOptions()
|
||||
{
|
||||
$this->barcodeLength = 12;
|
||||
$this->mandatoryChecksum = true;
|
||||
$this->mandatoryQuietZones = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Width of the barcode (in pixels)
|
||||
* @return int
|
||||
*/
|
||||
protected function calculateBarcodeWidth()
|
||||
{
|
||||
$quietZone = $this->getQuietZone();
|
||||
$startCharacter = (3 * $this->barThinWidth) * $this->factor;
|
||||
$middleCharacter = (5 * $this->barThinWidth) * $this->factor;
|
||||
$stopCharacter = (3 * $this->barThinWidth) * $this->factor;
|
||||
$encodedData = (7 * $this->barThinWidth) * $this->factor * 12;
|
||||
return $quietZone + $startCharacter + $middleCharacter + $encodedData + $stopCharacter + $quietZone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare array to draw barcode
|
||||
* @return array
|
||||
*/
|
||||
protected function prepareBarcode()
|
||||
{
|
||||
$barcodeTable = array();
|
||||
$height = ($this->drawText) ? 1.1 : 1;
|
||||
|
||||
// Start character (101)
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, $height);
|
||||
$barcodeTable[] = array(0, $this->barThinWidth, 0, $height);
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, $height);
|
||||
|
||||
$textTable = str_split($this->getText());
|
||||
|
||||
// First character
|
||||
$bars = str_split($this->codingMap['A'][$textTable[0]]);
|
||||
foreach ($bars as $b) {
|
||||
$barcodeTable[] = array($b, $this->barThinWidth, 0, $height);
|
||||
}
|
||||
|
||||
// First part
|
||||
for ($i = 1; $i < 6; $i++) {
|
||||
$bars = str_split($this->codingMap['A'][$textTable[$i]]);
|
||||
foreach ($bars as $b) {
|
||||
$barcodeTable[] = array($b, $this->barThinWidth, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Middle character (01010)
|
||||
$barcodeTable[] = array(0, $this->barThinWidth, 0, $height);
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, $height);
|
||||
$barcodeTable[] = array(0, $this->barThinWidth, 0, $height);
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, $height);
|
||||
$barcodeTable[] = array(0, $this->barThinWidth, 0, $height);
|
||||
|
||||
// Second part
|
||||
for ($i = 6; $i < 11; $i++) {
|
||||
$bars = str_split($this->codingMap['C'][$textTable[$i]]);
|
||||
foreach ($bars as $b) {
|
||||
$barcodeTable[] = array($b, $this->barThinWidth, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Last character
|
||||
$bars = str_split($this->codingMap['C'][$textTable[11]]);
|
||||
foreach ($bars as $b) {
|
||||
$barcodeTable[] = array($b, $this->barThinWidth, 0, $height);
|
||||
}
|
||||
|
||||
// Stop character (101)
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, $height);
|
||||
$barcodeTable[] = array(0, $this->barThinWidth, 0, $height);
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, $height);
|
||||
return $barcodeTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Partial function to draw text
|
||||
* @return void
|
||||
*/
|
||||
protected function drawText()
|
||||
{
|
||||
if ($this->drawText) {
|
||||
$text = $this->getTextToDisplay();
|
||||
$characterWidth = (7 * $this->barThinWidth) * $this->factor;
|
||||
$leftPosition = $this->getQuietZone() - $characterWidth;
|
||||
for ($i = 0; $i < $this->barcodeLength; $i ++) {
|
||||
$fontSize = $this->fontSize;
|
||||
if ($i == 0 || $i == 11) {
|
||||
$fontSize *= 0.8;
|
||||
}
|
||||
$this->addText(
|
||||
$text{$i},
|
||||
$fontSize * $this->factor,
|
||||
$this->rotate(
|
||||
$leftPosition,
|
||||
(int) $this->withBorder * 2 + $this->factor * ($this->barHeight + $fontSize) + 1
|
||||
),
|
||||
$this->font,
|
||||
$this->foreColor,
|
||||
'left',
|
||||
- $this->orientation
|
||||
);
|
||||
switch ($i) {
|
||||
case 0:
|
||||
$factor = 10;
|
||||
break;
|
||||
case 5:
|
||||
$factor = 4;
|
||||
break;
|
||||
case 10:
|
||||
$factor = 11;
|
||||
break;
|
||||
default:
|
||||
$factor = 0;
|
||||
}
|
||||
$leftPosition = $leftPosition + $characterWidth + ($factor * $this->barThinWidth * $this->factor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
199
library/Zend/Barcode/Object/Upce.php
Executable file
199
library/Zend/Barcode/Object/Upce.php
Executable file
|
@ -0,0 +1,199 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Object;
|
||||
|
||||
use Zend\Validator\Barcode as BarcodeValidator;
|
||||
|
||||
/**
|
||||
* Class for generate UpcA barcode
|
||||
*/
|
||||
class Upce extends Ean13
|
||||
{
|
||||
protected $parities = array(
|
||||
0 => array(
|
||||
0 => array('B','B','B','A','A','A'),
|
||||
1 => array('B','B','A','B','A','A'),
|
||||
2 => array('B','B','A','A','B','A'),
|
||||
3 => array('B','B','A','A','A','B'),
|
||||
4 => array('B','A','B','B','A','A'),
|
||||
5 => array('B','A','A','B','B','A'),
|
||||
6 => array('B','A','A','A','B','B'),
|
||||
7 => array('B','A','B','A','B','A'),
|
||||
8 => array('B','A','B','A','A','B'),
|
||||
9 => array('B','A','A','B','A','B')),
|
||||
1 => array(
|
||||
0 => array('A','A','A','B','B','B'),
|
||||
1 => array('A','A','B','A','B','B'),
|
||||
2 => array('A','A','B','B','A','B'),
|
||||
3 => array('A','A','B','B','B','A'),
|
||||
4 => array('A','B','A','A','B','B'),
|
||||
5 => array('A','B','B','A','A','B'),
|
||||
6 => array('A','B','B','B','A','A'),
|
||||
7 => array('A','B','A','B','A','B'),
|
||||
8 => array('A','B','A','B','B','A'),
|
||||
9 => array('A','B','B','A','B','A'))
|
||||
);
|
||||
|
||||
/**
|
||||
* Default options for Postnet barcode
|
||||
* @return void
|
||||
*/
|
||||
protected function getDefaultOptions()
|
||||
{
|
||||
$this->barcodeLength = 8;
|
||||
$this->mandatoryChecksum = true;
|
||||
$this->mandatoryQuietZones = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve text to encode
|
||||
* @return string
|
||||
*/
|
||||
public function getText()
|
||||
{
|
||||
$text = parent::getText();
|
||||
if ($text[0] != 1) {
|
||||
$text[0] = 0;
|
||||
}
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Width of the barcode (in pixels)
|
||||
* @return int
|
||||
*/
|
||||
protected function calculateBarcodeWidth()
|
||||
{
|
||||
$quietZone = $this->getQuietZone();
|
||||
$startCharacter = (3 * $this->barThinWidth) * $this->factor;
|
||||
$stopCharacter = (6 * $this->barThinWidth) * $this->factor;
|
||||
$encodedData = (7 * $this->barThinWidth) * $this->factor * 6;
|
||||
return $quietZone + $startCharacter + $encodedData + $stopCharacter + $quietZone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare array to draw barcode
|
||||
* @return array
|
||||
*/
|
||||
protected function prepareBarcode()
|
||||
{
|
||||
$barcodeTable = array();
|
||||
$height = ($this->drawText) ? 1.1 : 1;
|
||||
|
||||
// Start character (101)
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, $height);
|
||||
$barcodeTable[] = array(0, $this->barThinWidth, 0, $height);
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, $height);
|
||||
|
||||
$textTable = str_split($this->getText());
|
||||
$system = 0;
|
||||
if ($textTable[0] == 1) {
|
||||
$system = 1;
|
||||
}
|
||||
$checksum = $textTable[7];
|
||||
$parity = $this->parities[$system][$checksum];
|
||||
|
||||
for ($i = 1; $i < 7; $i++) {
|
||||
$bars = str_split($this->codingMap[$parity[$i - 1]][$textTable[$i]]);
|
||||
foreach ($bars as $b) {
|
||||
$barcodeTable[] = array($b, $this->barThinWidth, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Stop character (10101)
|
||||
$barcodeTable[] = array(0, $this->barThinWidth, 0, $height);
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, $height);
|
||||
$barcodeTable[] = array(0, $this->barThinWidth, 0, $height);
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, $height);
|
||||
$barcodeTable[] = array(0, $this->barThinWidth, 0, $height);
|
||||
$barcodeTable[] = array(1, $this->barThinWidth, 0, $height);
|
||||
return $barcodeTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Partial function to draw text
|
||||
* @return void
|
||||
*/
|
||||
protected function drawText()
|
||||
{
|
||||
if ($this->drawText) {
|
||||
$text = $this->getTextToDisplay();
|
||||
$characterWidth = (7 * $this->barThinWidth) * $this->factor;
|
||||
$leftPosition = $this->getQuietZone() - $characterWidth;
|
||||
for ($i = 0; $i < $this->barcodeLength; $i ++) {
|
||||
$fontSize = $this->fontSize;
|
||||
if ($i == 0 || $i == 7) {
|
||||
$fontSize *= 0.8;
|
||||
}
|
||||
$this->addText(
|
||||
$text{$i},
|
||||
$fontSize * $this->factor,
|
||||
$this->rotate(
|
||||
$leftPosition,
|
||||
(int) $this->withBorder * 2 + $this->factor * ($this->barHeight + $fontSize) + 1
|
||||
),
|
||||
$this->font,
|
||||
$this->foreColor,
|
||||
'left',
|
||||
- $this->orientation
|
||||
);
|
||||
switch ($i) {
|
||||
case 0:
|
||||
$factor = 3;
|
||||
break;
|
||||
case 6:
|
||||
$factor = 5;
|
||||
break;
|
||||
default:
|
||||
$factor = 0;
|
||||
}
|
||||
$leftPosition = $leftPosition + $characterWidth + ($factor * $this->barThinWidth * $this->factor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Particular validation for Upce barcode objects
|
||||
* (to suppress checksum character substitution)
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $options
|
||||
* @throws Exception\BarcodeValidationException
|
||||
*/
|
||||
protected function validateSpecificText($value, $options = array())
|
||||
{
|
||||
$validator = new BarcodeValidator(array(
|
||||
'adapter' => 'upce',
|
||||
'checksum' => false,
|
||||
));
|
||||
|
||||
$value = $this->addLeadingZeros($value, true);
|
||||
|
||||
if (!$validator->isValid($value)) {
|
||||
$message = implode("\n", $validator->getMessages());
|
||||
throw new Exception\BarcodeValidationException($message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get barcode checksum
|
||||
*
|
||||
* @param string $text
|
||||
* @return int
|
||||
*/
|
||||
public function getChecksum($text)
|
||||
{
|
||||
$text = $this->addLeadingZeros($text, true);
|
||||
if ($text[0] != 1) {
|
||||
$text[0] = 0;
|
||||
}
|
||||
return parent::getChecksum($text);
|
||||
}
|
||||
}
|
77
library/Zend/Barcode/ObjectPluginManager.php
Executable file
77
library/Zend/Barcode/ObjectPluginManager.php
Executable file
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode;
|
||||
|
||||
use Zend\ServiceManager\AbstractPluginManager;
|
||||
|
||||
/**
|
||||
* Plugin manager implementation for barcode parsers.
|
||||
*
|
||||
* Enforces that barcode parsers retrieved are instances of
|
||||
* Object\AbstractObject. Additionally, it registers a number of default
|
||||
* barcode parsers.
|
||||
*/
|
||||
class ObjectPluginManager extends AbstractPluginManager
|
||||
{
|
||||
/**
|
||||
* @var bool Ensure services are not shared
|
||||
*/
|
||||
protected $shareByDefault = false;
|
||||
|
||||
/**
|
||||
* Default set of barcode parsers
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $invokableClasses = array(
|
||||
'codabar' => 'Zend\Barcode\Object\Codabar',
|
||||
'code128' => 'Zend\Barcode\Object\Code128',
|
||||
'code25' => 'Zend\Barcode\Object\Code25',
|
||||
'code25interleaved' => 'Zend\Barcode\Object\Code25interleaved',
|
||||
'code39' => 'Zend\Barcode\Object\Code39',
|
||||
'ean13' => 'Zend\Barcode\Object\Ean13',
|
||||
'ean2' => 'Zend\Barcode\Object\Ean2',
|
||||
'ean5' => 'Zend\Barcode\Object\Ean5',
|
||||
'ean8' => 'Zend\Barcode\Object\Ean8',
|
||||
'error' => 'Zend\Barcode\Object\Error',
|
||||
'identcode' => 'Zend\Barcode\Object\Identcode',
|
||||
'itf14' => 'Zend\Barcode\Object\Itf14',
|
||||
'leitcode' => 'Zend\Barcode\Object\Leitcode',
|
||||
'planet' => 'Zend\Barcode\Object\Planet',
|
||||
'postnet' => 'Zend\Barcode\Object\Postnet',
|
||||
'royalmail' => 'Zend\Barcode\Object\Royalmail',
|
||||
'upca' => 'Zend\Barcode\Object\Upca',
|
||||
'upce' => 'Zend\Barcode\Object\Upce',
|
||||
);
|
||||
|
||||
/**
|
||||
* Validate the plugin
|
||||
*
|
||||
* Checks that the barcode parser loaded is an instance
|
||||
* of Object\AbstractObject.
|
||||
*
|
||||
* @param mixed $plugin
|
||||
* @return void
|
||||
* @throws Exception\InvalidArgumentException if invalid
|
||||
*/
|
||||
public function validatePlugin($plugin)
|
||||
{
|
||||
if ($plugin instanceof Object\AbstractObject) {
|
||||
// we're okay
|
||||
return;
|
||||
}
|
||||
|
||||
throw new Exception\InvalidArgumentException(sprintf(
|
||||
'Plugin of type %s is invalid; must extend %s\Object\AbstractObject',
|
||||
(is_object($plugin) ? get_class($plugin) : gettype($plugin)),
|
||||
__NAMESPACE__
|
||||
));
|
||||
}
|
||||
}
|
14
library/Zend/Barcode/README.md
Executable file
14
library/Zend/Barcode/README.md
Executable file
|
@ -0,0 +1,14 @@
|
|||
Barcode Component from ZF2
|
||||
==========================
|
||||
|
||||
This is the Barcode component for ZF2.
|
||||
|
||||
- File issues at https://github.com/zendframework/zf2/issues
|
||||
- Create pull requests against https://github.com/zendframework/zf2
|
||||
- Documentation is at http://framework.zend.com/docs
|
||||
|
||||
LICENSE
|
||||
-------
|
||||
|
||||
The files in this archive are released under the [Zend Framework
|
||||
license](http://framework.zend.com/license), which is a 3-clause BSD license.
|
515
library/Zend/Barcode/Renderer/AbstractRenderer.php
Executable file
515
library/Zend/Barcode/Renderer/AbstractRenderer.php
Executable file
|
@ -0,0 +1,515 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Renderer;
|
||||
|
||||
use Traversable;
|
||||
use Zend\Barcode\Barcode;
|
||||
use Zend\Barcode\Exception as BarcodeException;
|
||||
use Zend\Barcode\Object;
|
||||
use Zend\Stdlib\ArrayUtils;
|
||||
|
||||
/**
|
||||
* Class for rendering the barcode
|
||||
*/
|
||||
abstract class AbstractRenderer implements RendererInterface
|
||||
{
|
||||
/**
|
||||
* Namespace of the renderer for autoloading
|
||||
* @var string
|
||||
*/
|
||||
protected $rendererNamespace = 'Zend\Barcode\Renderer';
|
||||
|
||||
/**
|
||||
* Renderer type
|
||||
* @var string
|
||||
*/
|
||||
protected $type = null;
|
||||
|
||||
/**
|
||||
* Activate/Deactivate the automatic rendering of exception
|
||||
* @var bool
|
||||
*/
|
||||
protected $automaticRenderError = false;
|
||||
|
||||
/**
|
||||
* Offset of the barcode from the top of the rendering resource
|
||||
* @var int
|
||||
*/
|
||||
protected $topOffset = 0;
|
||||
|
||||
/**
|
||||
* Offset of the barcode from the left of the rendering resource
|
||||
* @var int
|
||||
*/
|
||||
protected $leftOffset = 0;
|
||||
|
||||
/**
|
||||
* Horizontal position of the barcode in the rendering resource
|
||||
* @var int
|
||||
*/
|
||||
protected $horizontalPosition = 'left';
|
||||
|
||||
/**
|
||||
* Vertical position of the barcode in the rendering resource
|
||||
* @var int
|
||||
*/
|
||||
protected $verticalPosition = 'top';
|
||||
|
||||
/**
|
||||
* Module size rendering
|
||||
* @var float
|
||||
*/
|
||||
protected $moduleSize = 1;
|
||||
|
||||
/**
|
||||
* Barcode object
|
||||
* @var Object\ObjectInterface
|
||||
*/
|
||||
protected $barcode;
|
||||
|
||||
/**
|
||||
* Drawing resource
|
||||
*/
|
||||
protected $resource;
|
||||
|
||||
/**
|
||||
* Show a transparent background
|
||||
* @var Boolean
|
||||
*/
|
||||
protected $transparentBackground = false;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param array|Traversable $options
|
||||
*/
|
||||
public function __construct($options = null)
|
||||
{
|
||||
if ($options instanceof Traversable) {
|
||||
$options = ArrayUtils::iteratorToArray($options);
|
||||
}
|
||||
if (is_array($options)) {
|
||||
$this->setOptions($options);
|
||||
}
|
||||
$this->type = strtolower(substr(
|
||||
get_class($this),
|
||||
strlen($this->rendererNamespace) + 1
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set renderer state from options array
|
||||
* @param array $options
|
||||
* @return AbstractRenderer
|
||||
*/
|
||||
public function setOptions($options)
|
||||
{
|
||||
foreach ($options as $key => $value) {
|
||||
$method = 'set' . $key;
|
||||
if (method_exists($this, $method)) {
|
||||
$this->$method($value);
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set renderer namespace for autoloading
|
||||
*
|
||||
* @param string $namespace
|
||||
* @return AbstractRenderer
|
||||
*/
|
||||
public function setRendererNamespace($namespace)
|
||||
{
|
||||
$this->rendererNamespace = $namespace;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve renderer namespace
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRendererNamespace()
|
||||
{
|
||||
return $this->rendererNamespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether background should be transparent
|
||||
* Will work for SVG and Image (png and gif only)
|
||||
*
|
||||
* @param $bool
|
||||
* @return $this
|
||||
*/
|
||||
public function setTransparentBackground($bool)
|
||||
{
|
||||
$this->transparentBackground = $bool;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function getTransparentBackground()
|
||||
{
|
||||
return $this->transparentBackground;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve renderer type
|
||||
* @return string
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Manually adjust top position
|
||||
* @param int $value
|
||||
* @return AbstractRenderer
|
||||
* @throws Exception\OutOfRangeException
|
||||
*/
|
||||
public function setTopOffset($value)
|
||||
{
|
||||
if (!is_numeric($value) || intval($value) < 0) {
|
||||
throw new Exception\OutOfRangeException(
|
||||
'Vertical position must be greater than or equals 0'
|
||||
);
|
||||
}
|
||||
$this->topOffset = intval($value);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve vertical adjustment
|
||||
* @return int
|
||||
*/
|
||||
public function getTopOffset()
|
||||
{
|
||||
return $this->topOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Manually adjust left position
|
||||
* @param int $value
|
||||
* @return AbstractRenderer
|
||||
* @throws Exception\OutOfRangeException
|
||||
*/
|
||||
public function setLeftOffset($value)
|
||||
{
|
||||
if (!is_numeric($value) || intval($value) < 0) {
|
||||
throw new Exception\OutOfRangeException(
|
||||
'Horizontal position must be greater than or equals 0'
|
||||
);
|
||||
}
|
||||
$this->leftOffset = intval($value);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve vertical adjustment
|
||||
* @return int
|
||||
*/
|
||||
public function getLeftOffset()
|
||||
{
|
||||
return $this->leftOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate/Deactivate the automatic rendering of exception
|
||||
* @param bool $value
|
||||
* @return AbstractRenderer
|
||||
*/
|
||||
public function setAutomaticRenderError($value)
|
||||
{
|
||||
$this->automaticRenderError = (bool) $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Horizontal position of the barcode in the rendering resource
|
||||
* @param string $value
|
||||
* @return AbstractRenderer
|
||||
* @throws Exception\UnexpectedValueException
|
||||
*/
|
||||
public function setHorizontalPosition($value)
|
||||
{
|
||||
if (!in_array($value, array('left', 'center', 'right'))) {
|
||||
throw new Exception\UnexpectedValueException(
|
||||
"Invalid barcode position provided must be 'left', 'center' or 'right'"
|
||||
);
|
||||
}
|
||||
$this->horizontalPosition = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Horizontal position of the barcode in the rendering resource
|
||||
* @return string
|
||||
*/
|
||||
public function getHorizontalPosition()
|
||||
{
|
||||
return $this->horizontalPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Vertical position of the barcode in the rendering resource
|
||||
* @param string $value
|
||||
* @return AbstractRenderer
|
||||
* @throws Exception\UnexpectedValueException
|
||||
*/
|
||||
public function setVerticalPosition($value)
|
||||
{
|
||||
if (!in_array($value, array('top', 'middle', 'bottom'))) {
|
||||
throw new Exception\UnexpectedValueException(
|
||||
"Invalid barcode position provided must be 'top', 'middle' or 'bottom'"
|
||||
);
|
||||
}
|
||||
$this->verticalPosition = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Vertical position of the barcode in the rendering resource
|
||||
* @return string
|
||||
*/
|
||||
public function getVerticalPosition()
|
||||
{
|
||||
return $this->verticalPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the size of a module
|
||||
* @param float $value
|
||||
* @return AbstractRenderer
|
||||
* @throws Exception\OutOfRangeException
|
||||
*/
|
||||
public function setModuleSize($value)
|
||||
{
|
||||
if (!is_numeric($value) || floatval($value) <= 0) {
|
||||
throw new Exception\OutOfRangeException(
|
||||
'Float size must be greater than 0'
|
||||
);
|
||||
}
|
||||
$this->moduleSize = floatval($value);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the size of a module
|
||||
* @return float
|
||||
*/
|
||||
public function getModuleSize()
|
||||
{
|
||||
return $this->moduleSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the automatic rendering of exception
|
||||
* @return bool
|
||||
*/
|
||||
public function getAutomaticRenderError()
|
||||
{
|
||||
return $this->automaticRenderError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the barcode object
|
||||
* @param Object\ObjectInterface $barcode
|
||||
* @return AbstractRenderer
|
||||
*/
|
||||
public function setBarcode(Object\ObjectInterface $barcode)
|
||||
{
|
||||
$this->barcode = $barcode;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the barcode object
|
||||
* @return Object\ObjectInterface
|
||||
*/
|
||||
public function getBarcode()
|
||||
{
|
||||
return $this->barcode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checking of parameters after all settings
|
||||
* @return bool
|
||||
*/
|
||||
public function checkParams()
|
||||
{
|
||||
$this->checkBarcodeObject();
|
||||
$this->checkSpecificParams();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a barcode object is correctly provided
|
||||
* @return void
|
||||
* @throws Exception\RuntimeException
|
||||
*/
|
||||
protected function checkBarcodeObject()
|
||||
{
|
||||
if ($this->barcode === null) {
|
||||
throw new Exception\RuntimeException(
|
||||
'No barcode object provided'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the left and top offset of the barcode in the
|
||||
* rendering support
|
||||
*
|
||||
* @param float $supportHeight
|
||||
* @param float $supportWidth
|
||||
* @return void
|
||||
*/
|
||||
protected function adjustPosition($supportHeight, $supportWidth)
|
||||
{
|
||||
$barcodeHeight = $this->barcode->getHeight(true) * $this->moduleSize;
|
||||
if ($barcodeHeight != $supportHeight && $this->topOffset == 0) {
|
||||
switch ($this->verticalPosition) {
|
||||
case 'middle':
|
||||
$this->topOffset = floor(($supportHeight - $barcodeHeight) / 2);
|
||||
break;
|
||||
case 'bottom':
|
||||
$this->topOffset = $supportHeight - $barcodeHeight;
|
||||
break;
|
||||
case 'top':
|
||||
default:
|
||||
$this->topOffset = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$barcodeWidth = $this->barcode->getWidth(true) * $this->moduleSize;
|
||||
if ($barcodeWidth != $supportWidth && $this->leftOffset == 0) {
|
||||
switch ($this->horizontalPosition) {
|
||||
case 'center':
|
||||
$this->leftOffset = floor(($supportWidth - $barcodeWidth) / 2);
|
||||
break;
|
||||
case 'right':
|
||||
$this->leftOffset = $supportWidth - $barcodeWidth;
|
||||
break;
|
||||
case 'left':
|
||||
default:
|
||||
$this->leftOffset = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw the barcode in the rendering resource
|
||||
*
|
||||
* @throws BarcodeException\ExceptionInterface
|
||||
* @return mixed
|
||||
*/
|
||||
public function draw()
|
||||
{
|
||||
try {
|
||||
$this->checkParams();
|
||||
$this->initRenderer();
|
||||
$this->drawInstructionList();
|
||||
} catch (BarcodeException\ExceptionInterface $e) {
|
||||
if ($this->automaticRenderError && !($e instanceof BarcodeException\RendererCreationException)) {
|
||||
$barcode = Barcode::makeBarcode(
|
||||
'error',
|
||||
array('text' => $e->getMessage())
|
||||
);
|
||||
$this->setBarcode($barcode);
|
||||
$this->resource = null;
|
||||
$this->initRenderer();
|
||||
$this->drawInstructionList();
|
||||
} else {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sub process to draw the barcode instructions
|
||||
* Needed by the automatic error rendering
|
||||
*/
|
||||
private function drawInstructionList()
|
||||
{
|
||||
$instructionList = $this->barcode->draw();
|
||||
foreach ($instructionList as $instruction) {
|
||||
switch ($instruction['type']) {
|
||||
case 'polygon':
|
||||
$this->drawPolygon(
|
||||
$instruction['points'],
|
||||
$instruction['color'],
|
||||
$instruction['filled']
|
||||
);
|
||||
break;
|
||||
case 'text': //$text, $size, $position, $font, $color, $alignment = 'center', $orientation = 0)
|
||||
$this->drawText(
|
||||
$instruction['text'],
|
||||
$instruction['size'],
|
||||
$instruction['position'],
|
||||
$instruction['font'],
|
||||
$instruction['color'],
|
||||
$instruction['alignment'],
|
||||
$instruction['orientation']
|
||||
);
|
||||
break;
|
||||
default:
|
||||
throw new Exception\UnexpectedValueException(
|
||||
'Unkown drawing command'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checking of parameters after all settings
|
||||
* @return void
|
||||
*/
|
||||
abstract protected function checkSpecificParams();
|
||||
|
||||
/**
|
||||
* Initialize the rendering resource
|
||||
* @return void
|
||||
*/
|
||||
abstract protected function initRenderer();
|
||||
|
||||
/**
|
||||
* Draw a polygon in the rendering resource
|
||||
* @param array $points
|
||||
* @param int $color
|
||||
* @param bool $filled
|
||||
*/
|
||||
abstract protected function drawPolygon($points, $color, $filled = true);
|
||||
|
||||
/**
|
||||
* Draw a polygon in the rendering resource
|
||||
* @param string $text
|
||||
* @param float $size
|
||||
* @param array $position
|
||||
* @param string $font
|
||||
* @param int $color
|
||||
* @param string $alignment
|
||||
* @param float $orientation
|
||||
*/
|
||||
abstract protected function drawText(
|
||||
$text,
|
||||
$size,
|
||||
$position,
|
||||
$font,
|
||||
$color,
|
||||
$alignment = 'center',
|
||||
$orientation = 0
|
||||
);
|
||||
}
|
16
library/Zend/Barcode/Renderer/Exception/ExceptionInterface.php
Executable file
16
library/Zend/Barcode/Renderer/Exception/ExceptionInterface.php
Executable file
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Renderer\Exception;
|
||||
|
||||
use Zend\Barcode\Exception\ExceptionInterface as BarcodeException;
|
||||
|
||||
interface ExceptionInterface extends BarcodeException
|
||||
{
|
||||
}
|
20
library/Zend/Barcode/Renderer/Exception/InvalidArgumentException.php
Executable file
20
library/Zend/Barcode/Renderer/Exception/InvalidArgumentException.php
Executable file
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Renderer\Exception;
|
||||
|
||||
use Zend\Barcode\Exception;
|
||||
|
||||
/**
|
||||
* Exception for Zend\Barcode component.
|
||||
*/
|
||||
class InvalidArgumentException extends Exception\InvalidArgumentException implements
|
||||
ExceptionInterface
|
||||
{
|
||||
}
|
20
library/Zend/Barcode/Renderer/Exception/OutOfRangeException.php
Executable file
20
library/Zend/Barcode/Renderer/Exception/OutOfRangeException.php
Executable file
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Renderer\Exception;
|
||||
|
||||
use Zend\Barcode\Exception;
|
||||
|
||||
/**
|
||||
* Exception for Zend\Barcode component.
|
||||
*/
|
||||
class OutOfRangeException extends Exception\OutOfRangeException implements
|
||||
ExceptionInterface
|
||||
{
|
||||
}
|
20
library/Zend/Barcode/Renderer/Exception/RuntimeException.php
Executable file
20
library/Zend/Barcode/Renderer/Exception/RuntimeException.php
Executable file
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Renderer\Exception;
|
||||
|
||||
use Zend\Barcode\Exception;
|
||||
|
||||
/**
|
||||
* Exception for Zend\Barcode component.
|
||||
*/
|
||||
class RuntimeException extends Exception\RuntimeException implements
|
||||
ExceptionInterface
|
||||
{
|
||||
}
|
20
library/Zend/Barcode/Renderer/Exception/UnexpectedValueException.php
Executable file
20
library/Zend/Barcode/Renderer/Exception/UnexpectedValueException.php
Executable file
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Renderer\Exception;
|
||||
|
||||
use Zend\Barcode\Exception;
|
||||
|
||||
/**
|
||||
* Exception for Zend\Barcode component.
|
||||
*/
|
||||
class UnexpectedValueException extends Exception\UnexpectedValueException implements
|
||||
ExceptionInterface
|
||||
{
|
||||
}
|
437
library/Zend/Barcode/Renderer/Image.php
Executable file
437
library/Zend/Barcode/Renderer/Image.php
Executable file
|
@ -0,0 +1,437 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Renderer;
|
||||
|
||||
use Zend\Barcode\Exception\RendererCreationException;
|
||||
use Zend\Stdlib\ErrorHandler;
|
||||
|
||||
/**
|
||||
* Class for rendering the barcode as image
|
||||
*/
|
||||
class Image extends AbstractRenderer
|
||||
{
|
||||
/**
|
||||
* List of authorized output format
|
||||
* @var array
|
||||
*/
|
||||
protected $allowedImageType = array('png',
|
||||
'jpeg',
|
||||
'gif' );
|
||||
|
||||
/**
|
||||
* Image format
|
||||
* @var string
|
||||
*/
|
||||
protected $imageType = 'png';
|
||||
|
||||
/**
|
||||
* Resource for the image
|
||||
* @var resource
|
||||
*/
|
||||
protected $resource = null;
|
||||
|
||||
/**
|
||||
* Resource for the font and bars color of the image
|
||||
* @var int
|
||||
*/
|
||||
protected $imageForeColor = null;
|
||||
|
||||
/**
|
||||
* Resource for the background color of the image
|
||||
* @var int
|
||||
*/
|
||||
protected $imageBackgroundColor = null;
|
||||
|
||||
/**
|
||||
* Height of the rendered image wanted by user
|
||||
* @var int
|
||||
*/
|
||||
protected $userHeight = 0;
|
||||
|
||||
/**
|
||||
* Width of the rendered image wanted by user
|
||||
* @var int
|
||||
*/
|
||||
protected $userWidth = 0;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array|\Traversable $options
|
||||
* @throws RendererCreationException
|
||||
*/
|
||||
public function __construct($options = null)
|
||||
{
|
||||
if (!function_exists('gd_info')) {
|
||||
throw new RendererCreationException(__CLASS__ . ' requires the GD extension');
|
||||
}
|
||||
|
||||
parent::__construct($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set height of the result image
|
||||
*
|
||||
* @param null|int $value
|
||||
* @throws Exception\OutOfRangeException
|
||||
* @return Image
|
||||
*/
|
||||
public function setHeight($value)
|
||||
{
|
||||
if (!is_numeric($value) || intval($value) < 0) {
|
||||
throw new Exception\OutOfRangeException(
|
||||
'Image height must be greater than or equals 0'
|
||||
);
|
||||
}
|
||||
$this->userHeight = intval($value);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get barcode height
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getHeight()
|
||||
{
|
||||
return $this->userHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set barcode width
|
||||
*
|
||||
* @param mixed $value
|
||||
* @throws Exception\OutOfRangeException
|
||||
* @return self
|
||||
*/
|
||||
public function setWidth($value)
|
||||
{
|
||||
if (!is_numeric($value) || intval($value) < 0) {
|
||||
throw new Exception\OutOfRangeException(
|
||||
'Image width must be greater than or equals 0'
|
||||
);
|
||||
}
|
||||
$this->userWidth = intval($value);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get barcode width
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getWidth()
|
||||
{
|
||||
return $this->userWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an image resource to draw the barcode inside
|
||||
*
|
||||
* @param resource $image
|
||||
* @return Image
|
||||
* @throws Exception\InvalidArgumentException
|
||||
*/
|
||||
public function setResource($image)
|
||||
{
|
||||
if (gettype($image) != 'resource' || get_resource_type($image) != 'gd') {
|
||||
throw new Exception\InvalidArgumentException(
|
||||
'Invalid image resource provided to setResource()'
|
||||
);
|
||||
}
|
||||
$this->resource = $image;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the image type to produce (png, jpeg, gif)
|
||||
*
|
||||
* @param string $value
|
||||
* @throws Exception\InvalidArgumentException
|
||||
* @return Image
|
||||
*/
|
||||
public function setImageType($value)
|
||||
{
|
||||
if ($value == 'jpg') {
|
||||
$value = 'jpeg';
|
||||
}
|
||||
|
||||
if (!in_array($value, $this->allowedImageType)) {
|
||||
throw new Exception\InvalidArgumentException(sprintf(
|
||||
'Invalid type "%s" provided to setImageType()',
|
||||
$value
|
||||
));
|
||||
}
|
||||
|
||||
$this->imageType = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the image type to produce
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getImageType()
|
||||
{
|
||||
return $this->imageType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the image resource
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function initRenderer()
|
||||
{
|
||||
$barcodeWidth = $this->barcode->getWidth(true);
|
||||
$barcodeHeight = $this->barcode->getHeight(true);
|
||||
|
||||
if (null === $this->resource) {
|
||||
$width = $barcodeWidth;
|
||||
$height = $barcodeHeight;
|
||||
if ($this->userWidth && $this->barcode->getType() != 'error') {
|
||||
$width = $this->userWidth;
|
||||
}
|
||||
if ($this->userHeight && $this->barcode->getType() != 'error') {
|
||||
$height = $this->userHeight;
|
||||
}
|
||||
|
||||
$this->resource = imagecreatetruecolor($width, $height);
|
||||
|
||||
$white = imagecolorallocate($this->resource, 255, 255, 255);
|
||||
imagefilledrectangle($this->resource, 0, 0, $width - 1, $height - 1, $white);
|
||||
}
|
||||
|
||||
$foreColor = $this->barcode->getForeColor();
|
||||
$this->imageForeColor = imagecolorallocate(
|
||||
$this->resource,
|
||||
($foreColor & 0xFF0000) >> 16,
|
||||
($foreColor & 0x00FF00) >> 8,
|
||||
$foreColor & 0x0000FF
|
||||
);
|
||||
|
||||
$backgroundColor = $this->barcode->getBackgroundColor();
|
||||
$this->imageBackgroundColor = imagecolorallocate(
|
||||
$this->resource,
|
||||
($backgroundColor & 0xFF0000) >> 16,
|
||||
($backgroundColor & 0x00FF00) >> 8,
|
||||
$backgroundColor & 0x0000FF
|
||||
);
|
||||
|
||||
// JPEG does not support transparency, if transparentBackground is true and
|
||||
// image type is JPEG, ignore transparency
|
||||
if ($this->getImageType() != "jpeg" && $this->transparentBackground) {
|
||||
imagecolortransparent($this->resource, $this->imageBackgroundColor);
|
||||
}
|
||||
|
||||
$this->adjustPosition(imagesy($this->resource), imagesx($this->resource));
|
||||
|
||||
imagefilledrectangle(
|
||||
$this->resource,
|
||||
$this->leftOffset,
|
||||
$this->topOffset,
|
||||
$this->leftOffset + $barcodeWidth - 1,
|
||||
$this->topOffset + $barcodeHeight - 1,
|
||||
$this->imageBackgroundColor
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check barcode parameters
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function checkSpecificParams()
|
||||
{
|
||||
$this->checkDimensions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check barcode dimensions
|
||||
*
|
||||
* @throws Exception\RuntimeException
|
||||
* @return void
|
||||
*/
|
||||
protected function checkDimensions()
|
||||
{
|
||||
if ($this->resource !== null) {
|
||||
if (imagesy($this->resource) < $this->barcode->getHeight(true)) {
|
||||
throw new Exception\RuntimeException(
|
||||
'Barcode is define outside the image (height)'
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if ($this->userHeight) {
|
||||
$height = $this->barcode->getHeight(true);
|
||||
if ($this->userHeight < $height) {
|
||||
throw new Exception\RuntimeException(sprintf(
|
||||
"Barcode is define outside the image (calculated: '%d', provided: '%d')",
|
||||
$height,
|
||||
$this->userHeight
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($this->resource !== null) {
|
||||
if (imagesx($this->resource) < $this->barcode->getWidth(true)) {
|
||||
throw new Exception\RuntimeException(
|
||||
'Barcode is define outside the image (width)'
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if ($this->userWidth) {
|
||||
$width = $this->barcode->getWidth(true);
|
||||
if ($this->userWidth < $width) {
|
||||
throw new Exception\RuntimeException(sprintf(
|
||||
"Barcode is define outside the image (calculated: '%d', provided: '%d')",
|
||||
$width,
|
||||
$this->userWidth
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw and render the barcode with correct headers
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
$this->draw();
|
||||
header("Content-Type: image/" . $this->imageType);
|
||||
$functionName = 'image' . $this->imageType;
|
||||
$functionName($this->resource);
|
||||
|
||||
ErrorHandler::start(E_WARNING);
|
||||
imagedestroy($this->resource);
|
||||
ErrorHandler::stop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a polygon in the image resource
|
||||
*
|
||||
* @param array $points
|
||||
* @param int $color
|
||||
* @param bool $filled
|
||||
*/
|
||||
protected function drawPolygon($points, $color, $filled = true)
|
||||
{
|
||||
$newPoints = array($points[0][0] + $this->leftOffset,
|
||||
$points[0][1] + $this->topOffset,
|
||||
$points[1][0] + $this->leftOffset,
|
||||
$points[1][1] + $this->topOffset,
|
||||
$points[2][0] + $this->leftOffset,
|
||||
$points[2][1] + $this->topOffset,
|
||||
$points[3][0] + $this->leftOffset,
|
||||
$points[3][1] + $this->topOffset, );
|
||||
|
||||
$allocatedColor = imagecolorallocate(
|
||||
$this->resource,
|
||||
($color & 0xFF0000) >> 16,
|
||||
($color & 0x00FF00) >> 8,
|
||||
$color & 0x0000FF
|
||||
);
|
||||
|
||||
if ($filled) {
|
||||
imagefilledpolygon($this->resource, $newPoints, 4, $allocatedColor);
|
||||
} else {
|
||||
imagepolygon($this->resource, $newPoints, 4, $allocatedColor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a polygon in the image resource
|
||||
*
|
||||
* @param string $text
|
||||
* @param float $size
|
||||
* @param array $position
|
||||
* @param string $font
|
||||
* @param int $color
|
||||
* @param string $alignment
|
||||
* @param float $orientation
|
||||
* @throws Exception\RuntimeException
|
||||
*/
|
||||
protected function drawText($text, $size, $position, $font, $color, $alignment = 'center', $orientation = 0)
|
||||
{
|
||||
$allocatedColor = imagecolorallocate(
|
||||
$this->resource,
|
||||
($color & 0xFF0000) >> 16,
|
||||
($color & 0x00FF00) >> 8,
|
||||
$color & 0x0000FF
|
||||
);
|
||||
|
||||
if ($font == null) {
|
||||
$font = 3;
|
||||
}
|
||||
$position[0] += $this->leftOffset;
|
||||
$position[1] += $this->topOffset;
|
||||
|
||||
if (is_numeric($font)) {
|
||||
if ($orientation) {
|
||||
/**
|
||||
* imagestring() doesn't allow orientation, if orientation
|
||||
* needed: a TTF font is required.
|
||||
* Throwing an exception here, allow to use automaticRenderError
|
||||
* to informe user of the problem instead of simply not drawing
|
||||
* the text
|
||||
*/
|
||||
throw new Exception\RuntimeException(
|
||||
'No orientation possible with GD internal font'
|
||||
);
|
||||
}
|
||||
$fontWidth = imagefontwidth($font);
|
||||
$positionY = $position[1] - imagefontheight($font) + 1;
|
||||
switch ($alignment) {
|
||||
case 'left':
|
||||
$positionX = $position[0];
|
||||
break;
|
||||
case 'center':
|
||||
$positionX = $position[0] - ceil(($fontWidth * strlen($text)) / 2);
|
||||
break;
|
||||
case 'right':
|
||||
$positionX = $position[0] - ($fontWidth * strlen($text));
|
||||
break;
|
||||
}
|
||||
imagestring($this->resource, $font, $positionX, $positionY, $text, $color);
|
||||
} else {
|
||||
if (!function_exists('imagettfbbox')) {
|
||||
throw new Exception\RuntimeException(
|
||||
'A font was provided, but this instance of PHP does not have TTF (FreeType) support'
|
||||
);
|
||||
}
|
||||
|
||||
$box = imagettfbbox($size, 0, $font, $text);
|
||||
switch ($alignment) {
|
||||
case 'left':
|
||||
$width = 0;
|
||||
break;
|
||||
case 'center':
|
||||
$width = ($box[2] - $box[0]) / 2;
|
||||
break;
|
||||
case 'right':
|
||||
$width = ($box[2] - $box[0]);
|
||||
break;
|
||||
}
|
||||
imagettftext(
|
||||
$this->resource,
|
||||
$size,
|
||||
$orientation,
|
||||
$position[0] - ($width * cos(pi() * $orientation / 180)),
|
||||
$position[1] + ($width * sin(pi() * $orientation / 180)),
|
||||
$allocatedColor,
|
||||
$font,
|
||||
$text
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
215
library/Zend/Barcode/Renderer/Pdf.php
Executable file
215
library/Zend/Barcode/Renderer/Pdf.php
Executable file
|
@ -0,0 +1,215 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Renderer;
|
||||
|
||||
use ZendPdf\Color;
|
||||
use ZendPdf\Font;
|
||||
use ZendPdf\Page;
|
||||
use ZendPdf\PdfDocument;
|
||||
|
||||
/**
|
||||
* Class for rendering the barcode in PDF resource
|
||||
*/
|
||||
class Pdf extends AbstractRenderer
|
||||
{
|
||||
/**
|
||||
* PDF resource
|
||||
* @var PdfDocument
|
||||
*/
|
||||
protected $resource = null;
|
||||
|
||||
/**
|
||||
* Page number in PDF resource
|
||||
* @var int
|
||||
*/
|
||||
protected $page = 0;
|
||||
|
||||
/**
|
||||
* Module size rendering
|
||||
* @var float
|
||||
*/
|
||||
protected $moduleSize = 0.5;
|
||||
|
||||
/**
|
||||
* Set a PDF resource to draw the barcode inside
|
||||
*
|
||||
* @param PdfDocument $pdf
|
||||
* @param int $page
|
||||
* @return Pdf
|
||||
*/
|
||||
public function setResource(PdfDocument $pdf, $page = 0)
|
||||
{
|
||||
$this->resource = $pdf;
|
||||
$this->page = intval($page);
|
||||
|
||||
if (!count($this->resource->pages)) {
|
||||
$this->page = 0;
|
||||
$this->resource->pages[] = new Page(
|
||||
Page::SIZE_A4
|
||||
);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check renderer parameters
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function checkSpecificParams()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw the barcode in the PDF, send headers and the PDF
|
||||
* @return mixed
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
$this->draw();
|
||||
header("Content-Type: application/pdf");
|
||||
echo $this->resource->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the PDF resource
|
||||
* @return void
|
||||
*/
|
||||
protected function initRenderer()
|
||||
{
|
||||
if ($this->resource === null) {
|
||||
$this->resource = new PdfDocument();
|
||||
$this->resource->pages[] = new Page(
|
||||
Page::SIZE_A4
|
||||
);
|
||||
}
|
||||
|
||||
$pdfPage = $this->resource->pages[$this->page];
|
||||
$this->adjustPosition($pdfPage->getHeight(), $pdfPage->getWidth());
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a polygon in the rendering resource
|
||||
* @param array $points
|
||||
* @param int $color
|
||||
* @param bool $filled
|
||||
*/
|
||||
protected function drawPolygon($points, $color, $filled = true)
|
||||
{
|
||||
$page = $this->resource->pages[$this->page];
|
||||
$x = array();
|
||||
$y = array();
|
||||
foreach ($points as $point) {
|
||||
$x[] = $point[0] * $this->moduleSize + $this->leftOffset;
|
||||
$y[] = $page->getHeight() - $point[1] * $this->moduleSize - $this->topOffset;
|
||||
}
|
||||
if (count($y) == 4) {
|
||||
if ($x[0] != $x[3] && $y[0] == $y[3]) {
|
||||
$y[0] -= ($this->moduleSize / 2);
|
||||
$y[3] -= ($this->moduleSize / 2);
|
||||
}
|
||||
if ($x[1] != $x[2] && $y[1] == $y[2]) {
|
||||
$y[1] += ($this->moduleSize / 2);
|
||||
$y[2] += ($this->moduleSize / 2);
|
||||
}
|
||||
}
|
||||
|
||||
$color = new Color\Rgb(
|
||||
(($color & 0xFF0000) >> 16) / 255.0,
|
||||
(($color & 0x00FF00) >> 8) / 255.0,
|
||||
($color & 0x0000FF) / 255.0
|
||||
);
|
||||
|
||||
$page->setLineColor($color);
|
||||
$page->setFillColor($color);
|
||||
$page->setLineWidth($this->moduleSize);
|
||||
|
||||
$fillType = ($filled)
|
||||
? Page::SHAPE_DRAW_FILL_AND_STROKE
|
||||
: Page::SHAPE_DRAW_STROKE;
|
||||
|
||||
$page->drawPolygon($x, $y, $fillType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a polygon in the rendering resource
|
||||
* @param string $text
|
||||
* @param float $size
|
||||
* @param array $position
|
||||
* @param string $font
|
||||
* @param int $color
|
||||
* @param string $alignment
|
||||
* @param float $orientation
|
||||
*/
|
||||
protected function drawText(
|
||||
$text,
|
||||
$size,
|
||||
$position,
|
||||
$font,
|
||||
$color,
|
||||
$alignment = 'center',
|
||||
$orientation = 0
|
||||
) {
|
||||
$page = $this->resource->pages[$this->page];
|
||||
$color = new Color\Rgb(
|
||||
(($color & 0xFF0000) >> 16) / 255.0,
|
||||
(($color & 0x00FF00) >> 8) / 255.0,
|
||||
($color & 0x0000FF) / 255.0
|
||||
);
|
||||
|
||||
$page->setLineColor($color);
|
||||
$page->setFillColor($color);
|
||||
$page->setFont(Font::fontWithPath($font), $size * $this->moduleSize * 1.2);
|
||||
|
||||
$width = $this->widthForStringUsingFontSize(
|
||||
$text,
|
||||
Font::fontWithPath($font),
|
||||
$size * $this->moduleSize
|
||||
);
|
||||
|
||||
$angle = pi() * $orientation / 180;
|
||||
$left = $position[0] * $this->moduleSize + $this->leftOffset;
|
||||
$top = $page->getHeight() - $position[1] * $this->moduleSize - $this->topOffset;
|
||||
|
||||
switch ($alignment) {
|
||||
case 'center':
|
||||
$left -= ($width / 2) * cos($angle);
|
||||
$top -= ($width / 2) * sin($angle);
|
||||
break;
|
||||
case 'right':
|
||||
$left -= $width;
|
||||
break;
|
||||
}
|
||||
$page->rotate($left, $top, $angle);
|
||||
$page->drawText($text, $left, $top);
|
||||
$page->rotate($left, $top, - $angle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the width of a string:
|
||||
* in case of using alignment parameter in drawText
|
||||
* @param string $text
|
||||
* @param Font $font
|
||||
* @param float $fontSize
|
||||
* @return float
|
||||
*/
|
||||
public function widthForStringUsingFontSize($text, $font, $fontSize)
|
||||
{
|
||||
$drawingString = iconv('UTF-8', 'UTF-16BE//IGNORE', $text);
|
||||
$characters = array();
|
||||
for ($i = 0, $len = strlen($drawingString); $i < $len; $i++) {
|
||||
$characters[] = (ord($drawingString[$i ++]) << 8) | ord($drawingString[$i]);
|
||||
}
|
||||
$glyphs = $font->glyphNumbersForCharacters($characters);
|
||||
$widths = $font->widthsForGlyphs($glyphs);
|
||||
$stringWidth = (array_sum($widths) / $font->getUnitsPerEm()) * $fontSize;
|
||||
return $stringWidth;
|
||||
}
|
||||
}
|
161
library/Zend/Barcode/Renderer/RendererInterface.php
Executable file
161
library/Zend/Barcode/Renderer/RendererInterface.php
Executable file
|
@ -0,0 +1,161 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Renderer;
|
||||
|
||||
use Zend\Barcode\Object\ObjectInterface;
|
||||
|
||||
/**
|
||||
* Class for rendering the barcode
|
||||
*/
|
||||
interface RendererInterface
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
* @param array|\Traversable $options
|
||||
*/
|
||||
public function __construct($options = null);
|
||||
|
||||
/**
|
||||
* Set renderer state from options array
|
||||
* @param array $options
|
||||
* @return RendererInterface
|
||||
*/
|
||||
public function setOptions($options);
|
||||
|
||||
/**
|
||||
* Set renderer namespace for autoloading
|
||||
*
|
||||
* @param string $namespace
|
||||
* @return RendererInterface
|
||||
*/
|
||||
public function setRendererNamespace($namespace);
|
||||
|
||||
/**
|
||||
* Retrieve renderer namespace
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRendererNamespace();
|
||||
|
||||
/**
|
||||
* Retrieve renderer type
|
||||
* @return string
|
||||
*/
|
||||
public function getType();
|
||||
|
||||
/**
|
||||
* Manually adjust top position
|
||||
* @param int $value
|
||||
* @return RendererInterface
|
||||
*/
|
||||
public function setTopOffset($value);
|
||||
|
||||
/**
|
||||
* Retrieve vertical adjustment
|
||||
* @return int
|
||||
*/
|
||||
public function getTopOffset();
|
||||
|
||||
/**
|
||||
* Manually adjust left position
|
||||
* @param int $value
|
||||
* @return RendererInterface
|
||||
*/
|
||||
public function setLeftOffset($value);
|
||||
|
||||
/**
|
||||
* Retrieve vertical adjustment
|
||||
* @return int
|
||||
*/
|
||||
public function getLeftOffset();
|
||||
|
||||
/**
|
||||
* Activate/Deactivate the automatic rendering of exception
|
||||
* @param bool $value
|
||||
* @return self
|
||||
*/
|
||||
public function setAutomaticRenderError($value);
|
||||
|
||||
/**
|
||||
* Horizontal position of the barcode in the rendering resource
|
||||
* @param string $value
|
||||
* @return RendererInterface
|
||||
*/
|
||||
public function setHorizontalPosition($value);
|
||||
|
||||
/**
|
||||
* Horizontal position of the barcode in the rendering resource
|
||||
* @return string
|
||||
*/
|
||||
public function getHorizontalPosition();
|
||||
|
||||
/**
|
||||
* Vertical position of the barcode in the rendering resource
|
||||
* @param string $value
|
||||
* @return RendererInterface
|
||||
*/
|
||||
public function setVerticalPosition($value);
|
||||
|
||||
/**
|
||||
* Vertical position of the barcode in the rendering resource
|
||||
* @return string
|
||||
*/
|
||||
public function getVerticalPosition();
|
||||
|
||||
/**
|
||||
* Set the size of a module
|
||||
* @param float $value
|
||||
* @return RendererInterface
|
||||
*/
|
||||
public function setModuleSize($value);
|
||||
|
||||
/**
|
||||
* Set the size of a module
|
||||
* @return float
|
||||
*/
|
||||
public function getModuleSize();
|
||||
|
||||
/**
|
||||
* Retrieve the automatic rendering of exception
|
||||
* @return bool
|
||||
*/
|
||||
public function getAutomaticRenderError();
|
||||
|
||||
/**
|
||||
* Set the barcode object
|
||||
* @param ObjectInterface $barcode
|
||||
* @return RendererInterface
|
||||
*/
|
||||
public function setBarcode(ObjectInterface $barcode);
|
||||
|
||||
/**
|
||||
* Retrieve the barcode object
|
||||
* @return ObjectInterface
|
||||
*/
|
||||
public function getBarcode();
|
||||
|
||||
/**
|
||||
* Checking of parameters after all settings
|
||||
* @return bool
|
||||
*/
|
||||
public function checkParams();
|
||||
|
||||
/**
|
||||
* Draw the barcode in the rendering resource
|
||||
* @return mixed
|
||||
*/
|
||||
public function draw();
|
||||
|
||||
/**
|
||||
* Render the resource by sending headers and drawed resource
|
||||
* @return mixed
|
||||
*/
|
||||
public function render();
|
||||
}
|
380
library/Zend/Barcode/Renderer/Svg.php
Executable file
380
library/Zend/Barcode/Renderer/Svg.php
Executable file
|
@ -0,0 +1,380 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode\Renderer;
|
||||
|
||||
use DOMDocument;
|
||||
use DOMElement;
|
||||
use DOMText;
|
||||
|
||||
/**
|
||||
* Class for rendering the barcode as svg
|
||||
*/
|
||||
class Svg extends AbstractRenderer
|
||||
{
|
||||
/**
|
||||
* Resource for the image
|
||||
* @var DOMDocument
|
||||
*/
|
||||
protected $resource = null;
|
||||
|
||||
/**
|
||||
* Root element of the XML structure
|
||||
* @var DOMElement
|
||||
*/
|
||||
protected $rootElement = null;
|
||||
|
||||
/**
|
||||
* Height of the rendered image wanted by user
|
||||
* @var int
|
||||
*/
|
||||
protected $userHeight = 0;
|
||||
|
||||
/**
|
||||
* Width of the rendered image wanted by user
|
||||
* @var int
|
||||
*/
|
||||
protected $userWidth = 0;
|
||||
|
||||
/**
|
||||
* Flag to determime if drawPolygon has been run once already
|
||||
* @var bool
|
||||
*/
|
||||
protected $drawPolygonExecuted = false;
|
||||
|
||||
/**
|
||||
* Set height of the result image
|
||||
* @param null|int $value
|
||||
* @throws Exception\OutOfRangeException
|
||||
* @return Svg
|
||||
*/
|
||||
public function setHeight($value)
|
||||
{
|
||||
if (!is_numeric($value) || intval($value) < 0) {
|
||||
throw new Exception\OutOfRangeException(
|
||||
'Svg height must be greater than or equals 0'
|
||||
);
|
||||
}
|
||||
$this->userHeight = intval($value);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get barcode height
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getHeight()
|
||||
{
|
||||
return $this->userHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set barcode width
|
||||
*
|
||||
* @param mixed $value
|
||||
* @throws Exception\OutOfRangeException
|
||||
* @return self
|
||||
*/
|
||||
public function setWidth($value)
|
||||
{
|
||||
if (!is_numeric($value) || intval($value) < 0) {
|
||||
throw new Exception\OutOfRangeException(
|
||||
'Svg width must be greater than or equals 0'
|
||||
);
|
||||
}
|
||||
$this->userWidth = intval($value);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get barcode width
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getWidth()
|
||||
{
|
||||
return $this->userWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an image resource to draw the barcode inside
|
||||
*
|
||||
* @param DOMDocument $svg
|
||||
* @return Svg
|
||||
*/
|
||||
public function setResource(DOMDocument $svg)
|
||||
{
|
||||
$this->resource = $svg;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the image resource
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function initRenderer()
|
||||
{
|
||||
$barcodeWidth = $this->barcode->getWidth(true);
|
||||
$barcodeHeight = $this->barcode->getHeight(true);
|
||||
|
||||
$backgroundColor = $this->barcode->getBackgroundColor();
|
||||
$imageBackgroundColor = 'rgb(' . implode(', ', array(($backgroundColor & 0xFF0000) >> 16,
|
||||
($backgroundColor & 0x00FF00) >> 8,
|
||||
($backgroundColor & 0x0000FF))) . ')';
|
||||
|
||||
$width = $barcodeWidth;
|
||||
$height = $barcodeHeight;
|
||||
if ($this->userWidth && $this->barcode->getType() != 'error') {
|
||||
$width = $this->userWidth;
|
||||
}
|
||||
if ($this->userHeight && $this->barcode->getType() != 'error') {
|
||||
$height = $this->userHeight;
|
||||
}
|
||||
if ($this->resource === null) {
|
||||
$this->resource = new DOMDocument('1.0', 'utf-8');
|
||||
$this->resource->formatOutput = true;
|
||||
$this->rootElement = $this->resource->createElement('svg');
|
||||
$this->rootElement->setAttribute('xmlns', "http://www.w3.org/2000/svg");
|
||||
$this->rootElement->setAttribute('version', '1.1');
|
||||
$this->rootElement->setAttribute('width', $width);
|
||||
$this->rootElement->setAttribute('height', $height);
|
||||
|
||||
$this->appendRootElement(
|
||||
'title',
|
||||
array(),
|
||||
"Barcode " . strtoupper($this->barcode->getType()) . " " . $this->barcode->getText()
|
||||
);
|
||||
} else {
|
||||
$this->readRootElement();
|
||||
$width = $this->rootElement->getAttribute('width');
|
||||
$height = $this->rootElement->getAttribute('height');
|
||||
}
|
||||
$this->adjustPosition($height, $width);
|
||||
|
||||
$rect = array('x' => $this->leftOffset,
|
||||
'y' => $this->topOffset,
|
||||
'width' => ($this->leftOffset + $barcodeWidth - 1),
|
||||
'height' => ($this->topOffset + $barcodeHeight - 1),
|
||||
'fill' => $imageBackgroundColor);
|
||||
|
||||
if ($this->transparentBackground) {
|
||||
$rect['fill-opacity'] = 0;
|
||||
}
|
||||
|
||||
$this->appendRootElement('rect', $rect);
|
||||
}
|
||||
|
||||
protected function readRootElement()
|
||||
{
|
||||
if ($this->resource !== null) {
|
||||
$this->rootElement = $this->resource->documentElement;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a new DOMElement to the root element
|
||||
*
|
||||
* @param string $tagName
|
||||
* @param array $attributes
|
||||
* @param string $textContent
|
||||
*/
|
||||
protected function appendRootElement($tagName, $attributes = array(), $textContent = null)
|
||||
{
|
||||
$newElement = $this->createElement($tagName, $attributes, $textContent);
|
||||
$this->rootElement->appendChild($newElement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create DOMElement
|
||||
*
|
||||
* @param string $tagName
|
||||
* @param array $attributes
|
||||
* @param string $textContent
|
||||
* @return DOMElement
|
||||
*/
|
||||
protected function createElement($tagName, $attributes = array(), $textContent = null)
|
||||
{
|
||||
$element = $this->resource->createElement($tagName);
|
||||
foreach ($attributes as $k => $v) {
|
||||
$element->setAttribute($k, $v);
|
||||
}
|
||||
if ($textContent !== null) {
|
||||
$element->appendChild(new DOMText((string) $textContent));
|
||||
}
|
||||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check barcode parameters
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function checkSpecificParams()
|
||||
{
|
||||
$this->checkDimensions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check barcode dimensions
|
||||
*
|
||||
* @throws Exception\RuntimeException
|
||||
* @return void
|
||||
*/
|
||||
protected function checkDimensions()
|
||||
{
|
||||
if ($this->resource !== null) {
|
||||
$this->readRootElement();
|
||||
$height = (float) $this->rootElement->getAttribute('height');
|
||||
if ($height < $this->barcode->getHeight(true)) {
|
||||
throw new Exception\RuntimeException(
|
||||
'Barcode is define outside the image (height)'
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if ($this->userHeight) {
|
||||
$height = $this->barcode->getHeight(true);
|
||||
if ($this->userHeight < $height) {
|
||||
throw new Exception\RuntimeException(sprintf(
|
||||
"Barcode is define outside the image (calculated: '%d', provided: '%d')",
|
||||
$height,
|
||||
$this->userHeight
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($this->resource !== null) {
|
||||
$this->readRootElement();
|
||||
$width = $this->rootElement->getAttribute('width');
|
||||
if ($width < $this->barcode->getWidth(true)) {
|
||||
throw new Exception\RuntimeException(
|
||||
'Barcode is define outside the image (width)'
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if ($this->userWidth) {
|
||||
$width = (float) $this->barcode->getWidth(true);
|
||||
if ($this->userWidth < $width) {
|
||||
throw new Exception\RuntimeException(sprintf(
|
||||
"Barcode is define outside the image (calculated: '%d', provided: '%d')",
|
||||
$width,
|
||||
$this->userWidth
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw the barcode in the rendering resource
|
||||
* @return DOMDocument
|
||||
*/
|
||||
public function draw()
|
||||
{
|
||||
parent::draw();
|
||||
$this->resource->appendChild($this->rootElement);
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw and render the barcode with correct headers
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
$this->draw();
|
||||
header("Content-Type: image/svg+xml");
|
||||
echo $this->resource->saveXML();
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a polygon in the svg resource
|
||||
*
|
||||
* @param array $points
|
||||
* @param int $color
|
||||
* @param bool $filled
|
||||
*/
|
||||
protected function drawPolygon($points, $color, $filled = true)
|
||||
{
|
||||
$color = 'rgb(' . implode(', ', array(($color & 0xFF0000) >> 16,
|
||||
($color & 0x00FF00) >> 8,
|
||||
($color & 0x0000FF))) . ')';
|
||||
$orientation = $this->getBarcode()->getOrientation();
|
||||
$newPoints = array(
|
||||
$points[0][0] + $this->leftOffset,
|
||||
$points[0][1] + $this->topOffset,
|
||||
$points[1][0] + $this->leftOffset,
|
||||
$points[1][1] + $this->topOffset,
|
||||
$points[2][0] + $this->leftOffset + cos(-$orientation),
|
||||
$points[2][1] + $this->topOffset - sin($orientation),
|
||||
$points[3][0] + $this->leftOffset + cos(-$orientation),
|
||||
$points[3][1] + $this->topOffset - sin($orientation),
|
||||
);
|
||||
$newPoints = implode(' ', $newPoints);
|
||||
$attributes = array();
|
||||
$attributes['points'] = $newPoints;
|
||||
$attributes['fill'] = $color;
|
||||
|
||||
// SVG passes a rect in as the first call to drawPolygon, we'll need to intercept
|
||||
// this and set transparency if necessary.
|
||||
if (!$this->drawPolygonExecuted) {
|
||||
if ($this->transparentBackground) {
|
||||
$attributes['fill-opacity'] = '0';
|
||||
}
|
||||
$this->drawPolygonExecuted = true;
|
||||
}
|
||||
|
||||
$this->appendRootElement('polygon', $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a polygon in the svg resource
|
||||
*
|
||||
* @param string $text
|
||||
* @param float $size
|
||||
* @param array $position
|
||||
* @param string $font
|
||||
* @param int $color
|
||||
* @param string $alignment
|
||||
* @param float $orientation
|
||||
*/
|
||||
protected function drawText($text, $size, $position, $font, $color, $alignment = 'center', $orientation = 0)
|
||||
{
|
||||
$color = 'rgb(' . implode(', ', array(($color & 0xFF0000) >> 16,
|
||||
($color & 0x00FF00) >> 8,
|
||||
($color & 0x0000FF))) . ')';
|
||||
$attributes = array();
|
||||
$attributes['x'] = $position[0] + $this->leftOffset;
|
||||
$attributes['y'] = $position[1] + $this->topOffset;
|
||||
//$attributes['font-family'] = $font;
|
||||
$attributes['color'] = $color;
|
||||
$attributes['font-size'] = $size * 1.2;
|
||||
switch ($alignment) {
|
||||
case 'left':
|
||||
$textAnchor = 'start';
|
||||
break;
|
||||
case 'right':
|
||||
$textAnchor = 'end';
|
||||
break;
|
||||
case 'center':
|
||||
default:
|
||||
$textAnchor = 'middle';
|
||||
}
|
||||
$attributes['style'] = 'text-anchor: ' . $textAnchor;
|
||||
$attributes['transform'] = 'rotate('
|
||||
. (- $orientation)
|
||||
. ', '
|
||||
. ($position[0] + $this->leftOffset)
|
||||
. ', ' . ($position[1] + $this->topOffset)
|
||||
. ')';
|
||||
$this->appendRootElement('text', $attributes, $text);
|
||||
}
|
||||
}
|
62
library/Zend/Barcode/RendererPluginManager.php
Executable file
62
library/Zend/Barcode/RendererPluginManager.php
Executable file
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Barcode;
|
||||
|
||||
use Zend\ServiceManager\AbstractPluginManager;
|
||||
|
||||
/**
|
||||
* Plugin manager implementation for barcode renderers.
|
||||
*
|
||||
* Enforces that barcode parsers retrieved are instances of
|
||||
* Renderer\AbstractRenderer. Additionally, it registers a number of default
|
||||
* barcode renderers.
|
||||
*/
|
||||
class RendererPluginManager extends AbstractPluginManager
|
||||
{
|
||||
/**
|
||||
* @var bool Ensure services are not shared
|
||||
*/
|
||||
protected $shareByDefault = false;
|
||||
|
||||
/**
|
||||
* Default set of barcode renderers
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $invokableClasses = array(
|
||||
'image' => 'Zend\Barcode\Renderer\Image',
|
||||
'pdf' => 'Zend\Barcode\Renderer\Pdf',
|
||||
'svg' => 'Zend\Barcode\Renderer\Svg'
|
||||
);
|
||||
|
||||
/**
|
||||
* Validate the plugin
|
||||
*
|
||||
* Checks that the barcode parser loaded is an instance
|
||||
* of Renderer\AbstractRenderer.
|
||||
*
|
||||
* @param mixed $plugin
|
||||
* @return void
|
||||
* @throws Exception\InvalidArgumentException if invalid
|
||||
*/
|
||||
public function validatePlugin($plugin)
|
||||
{
|
||||
if ($plugin instanceof Renderer\AbstractRenderer) {
|
||||
// we're okay
|
||||
return;
|
||||
}
|
||||
|
||||
throw new Exception\InvalidArgumentException(sprintf(
|
||||
'Plugin of type %s is invalid; must extend %s\Renderer\AbstractRenderer',
|
||||
(is_object($plugin) ? get_class($plugin) : gettype($plugin)),
|
||||
__NAMESPACE__
|
||||
));
|
||||
}
|
||||
}
|
35
library/Zend/Barcode/composer.json
Executable file
35
library/Zend/Barcode/composer.json
Executable file
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"name": "zendframework/zend-barcode",
|
||||
"description": "provides a generic way to generate barcodes",
|
||||
"license": "BSD-3-Clause",
|
||||
"keywords": [
|
||||
"zf2",
|
||||
"barcode"
|
||||
],
|
||||
"homepage": "https://github.com/zendframework/zf2",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Zend\\Barcode\\": ""
|
||||
}
|
||||
},
|
||||
"target-dir": "Zend/Barcode",
|
||||
"require": {
|
||||
"php": ">=5.3.23",
|
||||
"zendframework/zend-stdlib": "self.version",
|
||||
"zendframework/zend-validator": "self.version"
|
||||
},
|
||||
"require-dev": {
|
||||
"zendframework/zend-servicemanager": "self.version",
|
||||
"zendframework/zendpdf": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"zendframework/zend-servicemanager": "Zend\\ServiceManager component, required when using the factory methods of Zend\\Barcode.",
|
||||
"zendframework/zendpdf": "ZendPdf component"
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.3-dev",
|
||||
"dev-develop": "2.4-dev"
|
||||
}
|
||||
}
|
||||
}
|
3
library/Zend/Cache/CONTRIBUTING.md
Executable file
3
library/Zend/Cache/CONTRIBUTING.md
Executable file
|
@ -0,0 +1,3 @@
|
|||
# CONTRIBUTING
|
||||
|
||||
Please don't open pull requests against this repository, please use https://github.com/zendframework/zf2.
|
15
library/Zend/Cache/Exception/BadMethodCallException.php
Executable file
15
library/Zend/Cache/Exception/BadMethodCallException.php
Executable file
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Cache\Exception;
|
||||
|
||||
class BadMethodCallException extends \BadMethodCallException implements
|
||||
ExceptionInterface
|
||||
{
|
||||
}
|
14
library/Zend/Cache/Exception/ExceptionInterface.php
Executable file
14
library/Zend/Cache/Exception/ExceptionInterface.php
Executable file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Cache\Exception;
|
||||
|
||||
interface ExceptionInterface
|
||||
{
|
||||
}
|
14
library/Zend/Cache/Exception/ExtensionNotLoadedException.php
Executable file
14
library/Zend/Cache/Exception/ExtensionNotLoadedException.php
Executable file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Cache\Exception;
|
||||
|
||||
class ExtensionNotLoadedException extends RuntimeException
|
||||
{
|
||||
}
|
15
library/Zend/Cache/Exception/InvalidArgumentException.php
Executable file
15
library/Zend/Cache/Exception/InvalidArgumentException.php
Executable file
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Cache\Exception;
|
||||
|
||||
class InvalidArgumentException extends \InvalidArgumentException implements
|
||||
ExceptionInterface
|
||||
{
|
||||
}
|
14
library/Zend/Cache/Exception/LogicException.php
Executable file
14
library/Zend/Cache/Exception/LogicException.php
Executable file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Cache\Exception;
|
||||
|
||||
class LogicException extends \LogicException implements ExceptionInterface
|
||||
{
|
||||
}
|
14
library/Zend/Cache/Exception/MissingDependencyException.php
Executable file
14
library/Zend/Cache/Exception/MissingDependencyException.php
Executable file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Cache\Exception;
|
||||
|
||||
class MissingDependencyException extends RuntimeException
|
||||
{
|
||||
}
|
14
library/Zend/Cache/Exception/MissingKeyException.php
Executable file
14
library/Zend/Cache/Exception/MissingKeyException.php
Executable file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Cache\Exception;
|
||||
|
||||
class MissingKeyException extends RuntimeException
|
||||
{
|
||||
}
|
14
library/Zend/Cache/Exception/OutOfSpaceException.php
Executable file
14
library/Zend/Cache/Exception/OutOfSpaceException.php
Executable file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Cache\Exception;
|
||||
|
||||
class OutOfSpaceException extends \OverflowException implements ExceptionInterface
|
||||
{
|
||||
}
|
14
library/Zend/Cache/Exception/RuntimeException.php
Executable file
14
library/Zend/Cache/Exception/RuntimeException.php
Executable file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Cache\Exception;
|
||||
|
||||
class RuntimeException extends \RuntimeException implements ExceptionInterface
|
||||
{
|
||||
}
|
15
library/Zend/Cache/Exception/UnexpectedValueException.php
Executable file
15
library/Zend/Cache/Exception/UnexpectedValueException.php
Executable file
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Cache\Exception;
|
||||
|
||||
class UnexpectedValueException extends \UnexpectedValueException implements
|
||||
ExceptionInterface
|
||||
{
|
||||
}
|
15
library/Zend/Cache/Exception/UnsupportedMethodCallException.php
Executable file
15
library/Zend/Cache/Exception/UnsupportedMethodCallException.php
Executable file
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Cache\Exception;
|
||||
|
||||
class UnsupportedMethodCallException extends \BadMethodCallException implements
|
||||
ExceptionInterface
|
||||
{
|
||||
}
|
50
library/Zend/Cache/Pattern/AbstractPattern.php
Executable file
50
library/Zend/Cache/Pattern/AbstractPattern.php
Executable file
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Cache\Pattern;
|
||||
|
||||
use Zend\Cache\Exception;
|
||||
|
||||
abstract class AbstractPattern implements PatternInterface
|
||||
{
|
||||
/**
|
||||
* @var PatternOptions
|
||||
*/
|
||||
protected $options;
|
||||
|
||||
/**
|
||||
* Set pattern options
|
||||
*
|
||||
* @param PatternOptions $options
|
||||
* @return AbstractPattern
|
||||
* @throws Exception\InvalidArgumentException
|
||||
*/
|
||||
public function setOptions(PatternOptions $options)
|
||||
{
|
||||
if (!$options instanceof PatternOptions) {
|
||||
$options = new PatternOptions($options);
|
||||
}
|
||||
|
||||
$this->options = $options;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all pattern options
|
||||
*
|
||||
* @return PatternOptions
|
||||
*/
|
||||
public function getOptions()
|
||||
{
|
||||
if (null === $this->options) {
|
||||
$this->setOptions(new PatternOptions());
|
||||
}
|
||||
return $this->options;
|
||||
}
|
||||
}
|
200
library/Zend/Cache/Pattern/CallbackCache.php
Executable file
200
library/Zend/Cache/Pattern/CallbackCache.php
Executable file
|
@ -0,0 +1,200 @@
|
|||
<?php
|
||||
/**
|
||||
* Zend Framework (http://framework.zend.com/)
|
||||
*
|
||||
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
||||
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
|
||||
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||||
*/
|
||||
|
||||
namespace Zend\Cache\Pattern;
|
||||
|
||||
use Zend\Cache\Exception;
|
||||
use Zend\Stdlib\ErrorHandler;
|
||||
|
||||
class CallbackCache extends AbstractPattern
|
||||
{
|
||||
/**
|
||||
* Set options
|
||||
*
|
||||
* @param PatternOptions $options
|
||||
* @return CallbackCache
|
||||
* @throws Exception\InvalidArgumentException if missing storage option
|
||||
*/
|
||||
public function setOptions(PatternOptions $options)
|
||||
{
|
||||
parent::setOptions($options);
|
||||
|
||||
if (!$options->getStorage()) {
|
||||
throw new Exception\InvalidArgumentException("Missing option 'storage'");
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call the specified callback or get the result from cache
|
||||
*
|
||||
* @param callable $callback A valid callback
|
||||
* @param array $args Callback arguments
|
||||
* @return mixed Result
|
||||
* @throws Exception\RuntimeException if invalid cached data
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function call($callback, array $args = array())
|
||||
{
|
||||
$options = $this->getOptions();
|
||||
$storage = $options->getStorage();
|
||||
$success = null;
|
||||
$key = $this->generateCallbackKey($callback, $args);
|
||||
$result = $storage->getItem($key, $success);
|
||||
if ($success) {
|
||||
if (!array_key_exists(0, $result)) {
|
||||
throw new Exception\RuntimeException("Invalid cached data for key '{$key}'");
|
||||
}
|
||||
|
||||
echo isset($result[1]) ? $result[1] : '';
|
||||
return $result[0];
|
||||
}
|
||||
|
||||
$cacheOutput = $options->getCacheOutput();
|
||||
if ($cacheOutput) {
|
||||
ob_start();
|
||||
ob_implicit_flush(false);
|
||||
}
|
||||
|
||||
// TODO: do not cache on errors using [set|restore]_error_handler
|
||||
|
||||
try {
|
||||
if ($args) {
|
||||
$ret = call_user_func_array($callback, $args);
|
||||
} else {
|
||||
$ret = call_user_func($callback);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
if ($cacheOutput) {
|
||||
ob_end_flush();
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
|
||||
if ($cacheOutput) {
|
||||
$data = array($ret, ob_get_flush());
|
||||
} else {
|
||||
$data = array($ret);
|
||||
}
|
||||
|
||||
$storage->setItem($key, $data);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* function call handler
|
||||
*
|
||||
* @param string $function Function name to call
|
||||
* @param array $args Function arguments
|
||||
* @return mixed
|
||||
* @throws Exception\RuntimeException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function __call($function, array $args)
|
||||
{
|
||||
return $this->call($function, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a unique key in base of a key representing the callback part
|
||||
* and a key representing the arguments part.
|
||||
*
|
||||
* @param callable $callback A valid callback
|
||||
* @param array $args Callback arguments
|
||||
* @return string
|
||||
* @throws Exception\RuntimeException
|
||||
* @throws Exception\InvalidArgumentException
|
||||
*/
|
||||
public function generateKey($callback, array $args = array())
|
||||
{
|
||||
return $this->generateCallbackKey($callback, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a unique key in base of a key representing the callback part
|
||||
* and a key representing the arguments part.
|
||||
*
|
||||
* @param callable $callback A valid callback
|
||||
* @param array $args Callback arguments
|
||||
* @throws Exception\RuntimeException if callback not serializable
|
||||
* @throws Exception\InvalidArgumentException if invalid callback
|
||||
* @return string
|
||||
*/
|
||||
protected function generateCallbackKey($callback, array $args)
|
||||
{
|
||||
if (!is_callable($callback, false, $callbackKey)) {
|
||||
throw new Exception\InvalidArgumentException('Invalid callback');
|
||||
}
|
||||
|
||||
// functions, methods and classnames are case-insensitive
|
||||
$callbackKey = strtolower($callbackKey);
|
||||
|
||||
// generate a unique key of object callbacks
|
||||
if (is_object($callback)) { // Closures & __invoke
|
||||
$object = $callback;
|
||||
} elseif (isset($callback[0])) { // array($object, 'method')
|
||||
$object = $callback[0];
|
||||
}
|
||||
if (isset($object)) {
|
||||
ErrorHandler::start();
|
||||
try {
|
||||
$serializedObject = serialize($object);
|
||||
} catch (\Exception $e) {
|
||||
ErrorHandler::stop();
|
||||
throw new Exception\RuntimeException("Can't serialize callback: see previous exception", 0, $e);
|
||||
}
|
||||
$error = ErrorHandler::stop();
|
||||
|
||||
if (!$serializedObject) {
|
||||
throw new Exception\RuntimeException(
|
||||
sprintf('Cannot serialize callback%s', ($error ? ': ' . $error->getMessage() : '')),
|
||||
0,
|
||||
$error
|
||||
);
|
||||
}
|
||||
$callbackKey.= $serializedObject;
|
||||
}
|
||||
|
||||
return md5($callbackKey) . $this->generateArgumentsKey($args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a unique key of the argument part.
|
||||
*
|
||||
* @param array $args
|
||||
* @throws Exception\RuntimeException
|
||||
* @return string
|
||||
*/
|
||||
protected function generateArgumentsKey(array $args)
|
||||
{
|
||||
if (!$args) {
|
||||
return '';
|
||||
}
|
||||
|
||||
ErrorHandler::start();
|
||||
try {
|
||||
$serializedArgs = serialize(array_values($args));
|
||||
} catch (\Exception $e) {
|
||||
ErrorHandler::stop();
|
||||
throw new Exception\RuntimeException("Can't serialize arguments: see previous exception", 0, $e);
|
||||
}
|
||||
$error = ErrorHandler::stop();
|
||||
|
||||
if (!$serializedArgs) {
|
||||
throw new Exception\RuntimeException(
|
||||
sprintf('Cannot serialize arguments%s', ($error ? ': ' . $error->getMessage() : '')),
|
||||
0,
|
||||
$error
|
||||
);
|
||||
}
|
||||
|
||||
return md5($serializedArgs);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue