Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #17 from jeremiahsmall/development

Add fieldMap and toArray support
  • Loading branch information...
commit 8884bba3555765312cc60d7c21522cf97e19eadb 2 parents 6bac06c + c536c55
@jeremiahsmall jeremiahsmall authored
Showing with 356 additions and 311 deletions.
  1. +84 −84 library/Soliant/SimpleFM/Adapter.php
  2. +11 −11 library/Soliant/SimpleFM/Loader/AbstractLoader.php
  3. +16 −16 library/Soliant/SimpleFM/Loader/Curl.php
  4. +6 −6 library/Soliant/SimpleFM/Loader/FileGetContents.php
  5. +11 −11 library/Soliant/SimpleFM/Loader/FilePostContents.php
  6. +2 −3 library/Soliant/SimpleFM/Loader/LoaderInterface.php
  7. +9 −9 library/Soliant/SimpleFM/Loader/Mock.php
  8. +2 −2 library/Soliant/SimpleFM/Version.php
  9. +1 −1  library/Soliant/SimpleFM/ZF2/AdapterServiceFactory.php
  10. +1 −1  library/Soliant/SimpleFM/ZF2/Authentication/Adapter/Exception/InvalidArgumentException.php
  11. +1 −1  library/Soliant/SimpleFM/ZF2/Authentication/Adapter/Exception/RuntimeException.php
  12. +1 −1  library/Soliant/SimpleFM/ZF2/Authentication/Adapter/Exception/UnexpectedValueException.php
  13. +8 −8 library/Soliant/SimpleFM/ZF2/Authentication/Adapter/SimpleFM.php
  14. +1 −1  library/Soliant/SimpleFM/ZF2/Authentication/Mapper/Exception/InvalidArgumentException.php
  15. +18 −18 library/Soliant/SimpleFM/ZF2/Authentication/Mapper/Identity.php
  16. +1 −1  library/Soliant/SimpleFM/ZF2/Authentication/Storage/Exception/InvalidArgumentException.php
  17. +2 −2 library/Soliant/SimpleFM/ZF2/Authentication/Storage/Session.php
  18. +102 −16 library/Soliant/SimpleFM/ZF2/Entity/AbstractEntity.php
  19. +79 −119 library/Soliant/SimpleFM/ZF2/Gateway/AbstractGateway.php
View
168 library/Soliant/SimpleFM/Adapter.php
@@ -1,7 +1,7 @@
<?php
/**
* This source file is subject to the MIT license that is bundled with this package in the file LICENSE.txt.
- *
+ *
* @package Soliant\SimpleFM
* @copyright Copyright (c) 2007-2013 Soliant Consulting, Inc. (http://www.soliantconsulting.com)
* @author jsmall@soliantconsulting.com
@@ -10,78 +10,78 @@
namespace Soliant\SimpleFM;
use Soliant\SimpleFM\Loader\LoaderInterface;
-use Soliant\SimpleFM\Loader\FilePostContents;
+use Soliant\SimpleFM\Loader\FilePostContents;
use Soliant\SimpleFM\Exception\InvalidArgumentException;
use Soliant\SimpleFM\Exception\ReservedWordException;
class Adapter
{
-
+
/**
* @var string
*/
protected $hostname = '127.0.0.1';
-
+
/**
* @var string
*/
protected $dbname = '';
-
+
/**
* @var string
*/
protected $layoutname = '';
-
+
/**
* @var string
*/
protected $commandstring = '-findany';
-
+
/**
* @var array
*/
protected $commandarray = array('-findany' => '');
-
+
/**
* @var string
*/
protected $username = '';
-
+
/**
* @var string
*/
protected $password = '';
-
+
/**
* @var string
*/
protected $protocol = 'http';
-
+
/**
* @var int
*/
protected $port = 80;
-
+
/**
* @var string
*/
protected $fmresultsetUri = '/fmi/xml/fmresultset.xml';
-
+
/**
* @var string
*/
protected $fmpxmllayoutUri = '/fmi/xml/FMPXMLLAYOUT.xml';
-
+
/**
* @var boolean
*/
protected $rowsbyrecid = FALSE;
-
+
/**
* @var string
*/
protected $commandURLdebug;
-
+
/**
* @var LoaderInterface
*/
@@ -110,13 +110,13 @@ public function setHostParams($params=array())
$this->dbname = @$params['dbname'];
$this->username = @$params['username'];
$this->password = @$params['password'];
-
+
if (isset($params['port'])) $this->setPort($params['port']);
if (isset($params['protocol'])) $this->setProtocol($params['protocol']);
-
+
return $this;
}
-
+
/**
* Bulk setter for the credentials
* @param array($username, $password)
@@ -128,7 +128,7 @@ public function setCredentials($params=array())
$this->password = @$params['password'];
return $this;
}
-
+
/**
* Bulk setter for the call args
* @param array($layoutname, $commandstring)
@@ -140,7 +140,7 @@ public function setCallParams($params=array())
$this->commandstring = @$params['commandstring'];
return $this;
}
-
+
/**
* @return string
*/
@@ -158,7 +158,7 @@ public function setHostname($hostname)
$this->hostname = $hostname;
return $this;
}
-
+
/**
* @return string
*/
@@ -176,7 +176,7 @@ public function setUsername($username)
$this->username = $username;
return $this;
}
-
+
/**
* @return string
*/
@@ -184,7 +184,7 @@ public function getPassword ()
{
return $this->password;
}
-
+
/**
* @param string $password
* @return \Soliant\SimpleFM\Adapter
@@ -194,7 +194,7 @@ public function setPassword($password)
$this->password = $password;
return $this;
}
-
+
/**
* @return string
*/
@@ -212,7 +212,7 @@ public function setDbname($dbname)
$this->dbname = $dbname;
return $this;
}
-
+
/**
* @return string
*/
@@ -238,7 +238,7 @@ public function getCommandstring()
{
return $this->commandstring;
}
-
+
/**
* @return array
*/
@@ -257,7 +257,7 @@ public function setCommandstring($commandstring)
$this->commandarray = self::explodeNameValueString($commandstring);
return $this;
}
-
+
/**
* @param array $commandarray
* @return \Soliant\SimpleFM\Adapter
@@ -268,7 +268,7 @@ public function setCommandarray($commandarray)
$this->commandstring = self::repackCommandString($commandarray);
return $this;
}
-
+
/**
* @return the $protocol
*/
@@ -276,7 +276,7 @@ public function getProtocol ()
{
return $this->protocol;
}
-
+
/**
* @param string $protocol
* @throws InvalidArgumentException
@@ -291,7 +291,7 @@ public function setProtocol ($protocol)
}
return $this;
}
-
+
/**
* @return the $port
*/
@@ -299,7 +299,7 @@ public function getPort ()
{
return $this->port;
}
-
+
/**
* @param int $port
* @return \Soliant\SimpleFM\Adapter
@@ -309,7 +309,7 @@ public function setPort ($port)
$this->port = $port;
return $this;
}
-
+
/**
* @return the $fmresultsetUri
*/
@@ -317,7 +317,7 @@ public function getFmresultsetUri ()
{
return $this->fmresultsetUri;
}
-
+
/**
* @param string $fmresultsetUri
* @return \Soliant\SimpleFM\Adapter
@@ -327,7 +327,7 @@ public function setFmresultsetUri ($fmresultsetUri)
$this->fmresultsetUri = $fmresultsetUri;
return $this;
}
-
+
/**
* @return the $fmpxmllayoutUri
*/
@@ -335,7 +335,7 @@ public function getFmpxmllayoutUri ()
{
return $this->fmpxmllayoutUri;
}
-
+
/**
* @param string $fmpxmllayoutUri
* @return \Soliant\SimpleFM\Adapter
@@ -345,7 +345,7 @@ public function setFmpxmllayoutUri ($fmpxmllayoutUri)
$this->fmpxmllayoutUri = $fmpxmllayoutUri;
return $this;
}
-
+
/**
* @return boolean
*/
@@ -363,7 +363,7 @@ public function setRowsbyrecid($rowsByRecId = FALSE)
$this->rowsbyrecid = (boolean)$rowsByRecId;
return $this;
}
-
+
/**
* @return the $commandURLdebug
*/
@@ -372,7 +372,7 @@ public function getCommandURLdebug ()
return $this->commandURLdebug;
}
- /**
+ /**
* @param string $commandURLdebug
*/
public function setCommandURLdebug ($commandURLdebug)
@@ -381,7 +381,7 @@ public function setCommandURLdebug ($commandURLdebug)
return $this;
}
- /**
+ /**
* @return the $loader
*/
public function getLoader ()
@@ -389,7 +389,7 @@ public function getLoader ()
return $this->loader;
}
- /**
+ /**
* @param \Soliant\SimpleFM\Loader\LoaderInterface $loader
*/
public function setLoader ($loader)
@@ -398,42 +398,42 @@ public function setLoader ($loader)
return $this;
}
- /**
+ /**
* @return array
*/
public function execute ()
{
@$xml = $this->loader->load($this);
-
+
if (empty($xml)) {
-
+
$simplexmlerrors['xml'] = libxml_get_errors();
$simplexmlerrors['php'] = error_get_last();
-
+
$phpErrors = self::extractErrorFromPhpMessage($simplexmlerrors['php']['message']);
-
+
$error = $phpErrors['error'];
$errortext = $phpErrors['errortext'];
$errortype = $phpErrors['errortype'];
$count = NULL;
$fetchsize = NULL;
-
+
$rows = NULL;
libxml_clear_errors();
-
+
} else {
-
- $simplexmlerrors = null;
+
+ $simplexmlerrors = null;
$error = (int) $xml->error['code'];
$errortext = self::errorToEnglish($error);
$errortype = 'FileMaker';
$count = (string) $xml->resultset['count'];
$fetchsize = (string) $xml->resultset['fetch-size'];
-
+
$rows = $this->parseResult($xml);
-
+
}
-
+
$sfmresult = array (
'url' => $this->getCommandURLdebug(),
'error' => $error,
@@ -443,11 +443,11 @@ public function execute ()
'fetchsize' => $fetchsize,
'rows' => $rows
);
-
+
return $sfmresult;
-
+
}
-
+
/**
* @param xml $xml
* @return array
@@ -455,12 +455,12 @@ public function execute ()
protected function parseResult ($xml)
{
$result = array();
-
+
/**
* simplexml fmresultset path reference:
* $fmresultset->resultset[0]->record[0]->field[0]->data[0]
*/
-
+
$i=0; // the row index
foreach ($xml->resultset[0]->record as $row){ // handle rows
@@ -469,43 +469,43 @@ protected function parseResult ($xml)
$result[$conditional_id]['index'] = (int) $i;
$result[$conditional_id]['recid'] = (int) $row['record-id'];
$result[$conditional_id]['modid'] = (int) $row['mod-id'];
-
+
foreach ($xml->resultset[0]->record[$i]->field as $field ) { // handle fields
-
+
$fieldname = (string) $field['name'];
$fielddata = (string) $field->data ;
-
+
$fieldnameIsValid = $i===0 ? self::fieldnameIsValid($fieldname) : TRUE; // validate fieldnames on first row
- $result[$conditional_id][$fieldname] = $fielddata;
-
+ $result[$conditional_id][$fieldname] = $fielddata;
+
}
if (isset($xml->resultset[0]->record[0]->relatedset)){ // check if portals exist
-
+
$ii=0; // the portal index
foreach ($xml->resultset[0]->record[0]->relatedset as $portal ) { // handle portals
$portalname = (string) $portal['table'];
-
+
$result[$conditional_id][$portalname]['parentindex'] = (int) $i;
$result[$conditional_id][$portalname]['parentrecid'] = (int) $row['record-id'];
$result[$conditional_id][$portalname]['portalindex'] = (int) $ii;
/**
- * @TODO Verify if next line is a bug where portalrecordcount may be returning same value for all
+ * @TODO Verify if next line is a bug where portalrecordcount may be returning same value for all
* portals. Test for possible issues with $portalname being non-unique.
*/
$result[$conditional_id][$portalname]['portalrecordcount'] = (int) $portal['count'];
-
+
$iii=0; // the portal row index
foreach ($xml->resultset[0]->record[$i]->relatedset[$ii]->record as $portal_row ) { // handle portal rows
$portal_conditional_id = $this->rowsbyrecid === TRUE ? (int) $portal_row['record-id'] : $iii;
-
+
$result[$conditional_id][$portalname]['rows'][$portal_conditional_id]['index'] = (int) $iii;
$result[$conditional_id][$portalname]['rows'][$portal_conditional_id]['modid'] = (int) $portal_row['mod-id'];
$result[$conditional_id][$portalname]['rows'][$portal_conditional_id]['recid'] = (int) $portal_row['record-id'];
-
+
foreach ($xml->resultset[0]->record[$i]->relatedset[$ii]->record[$iii]->field as $portal_field ) { // handle portal fields
$portal_fieldname = (string) str_replace($portalname.'::', '', $portal_field['name']);
$portal_fielddata = (string) $portal_field->data ;
-
+
$fieldnameIsValid = $iii===0 ? self::fieldnameIsValid($portal_fieldname) : TRUE; // validate fieldnames on first row
$result[$conditional_id][$portalname]['rows'][$portal_conditional_id][$portal_fieldname] = $portal_fielddata;
}
@@ -516,10 +516,10 @@ protected function parseResult ($xml)
}
++$i;
}
-
+
return $result;
}
-
+
/**
* @param string $fieldname
* @throws ReservedWordException
@@ -530,13 +530,13 @@ protected function fieldnameIsValid($fieldname)
$reservedNames = array('index','recid','modid');
if(in_array($fieldname, $reservedNames)){
throw new ReservedWordException(
- 'SimpleFM Exception: "' . $fieldname .
+ 'SimpleFM Exception: "' . $fieldname .
'" is a reserved word and cannot be used as a field name on any FileMaker layout used with SimpleFM.',
$fieldname);
}
return TRUE;
}
-
+
/**
* @param libxml_error $error
* @param xml $xml
@@ -546,7 +546,7 @@ public function displayXmlError($error, $xml)
{
$return = $xml[$error->line - 1] . "\n";
$return .= str_repeat('-', $error->column) . "^\n";
-
+
switch ($error->level) {
case LIBXML_ERR_WARNING:
$return .= "Warning $error->code: ";
@@ -558,18 +558,18 @@ public function displayXmlError($error, $xml)
$return .= "Fatal Error $error->code: ";
break;
}
-
+
$return .= trim($error->message) .
"\n Line: $error->line" .
"\n Column: $error->column";
-
+
if ($error->file) {
$return .= "\n File: $error->file";
}
-
+
return "$return\n\n--------------------------------------------\n\n";
}
-
+
/**
* @param http_error $string
* @return string
@@ -601,7 +601,7 @@ public static function extractErrorFromPhpMessage($string)
return $return;
}
}
-
+
/**
* @param int $errornum
* @return string
@@ -875,15 +875,15 @@ public static function errorToEnglish($errornum='-1')
20413 => 'Too Many Files',
20605 => 'No network connection is available',
);
-
+
if (array_key_exists($errornum, $error)){
return $error[$errornum];
} else {
return 'Undefined';
}
-
+
}
-
+
/**
* @todo verify if an SPL function can be used instead
* Can't use native http_build_query because it drops args with empty values like &-find
@@ -927,6 +927,6 @@ protected function repackCommandString()
}
return $commandstring;
}
-
+
}
View
22 library/Soliant/SimpleFM/Loader/AbstractLoader.php
@@ -13,42 +13,42 @@
abstract class AbstractLoader implements LoaderInterface
{
-
+
protected $credentials;
protected $username;
protected $args;
protected $commandURL;
-
+
protected function createCredentials()
{
$username = $this->adapter->getUsername();
$password = $this->adapter->getPassword();
-
+
$this->username = $username;
$this->credentials = empty($username)?'':$username.':'.$password;
return $this->credentials;
}
-
+
protected function createArgs()
{
$dbname = $this->adapter->getDbname();
$layoutname = $this->adapter->getLayoutname();
$commandstring = $this->adapter->getCommandstring();
-
+
$this->args = "-db=$dbname&-lay=$layoutname&$commandstring";
return $this->args;
}
-
+
protected function createCommandURL()
{
$credentials = self::createCredentials();
$args = self::createArgs();
-
+
$protocol = $this->adapter->getProtocol();
$hostname = $this->adapter->getHostname();
$port = $this->adapter->getPort();
$fmresultsetUri = $this->adapter->getFmresultsetUri();
-
+
$this->commandURL = "$protocol://$credentials@$hostname:$port$fmresultsetUri?$args";
return $this->commandURL;
}
@@ -57,7 +57,7 @@ protected function setAdapterCommandURLdebug()
{
$this->adapter->setCommandURLdebug(empty($this->credentials)?$this->commandURL:str_replace($this->credentials, $this->username.':[...]', $this->commandURL));
}
-
+
protected function prepare()
{
self::createCredentials();
@@ -65,5 +65,5 @@ protected function prepare()
self::createCommandURL();
self::setAdapterCommandURLdebug();
}
-
-}
+
+}
View
32 library/Soliant/SimpleFM/Loader/Curl.php
@@ -17,50 +17,50 @@
class Curl extends AbstractLoader
{
-
+
protected function createPostURL()
{
$protocol = $this->adapter->getProtocol();
$hostname = $this->adapter->getHostname();
$port = $this->adapter->getPort();
$fmresultsetUri = $this->adapter->getFmresultsetUri();
-
+
return "$protocol://$hostname:$port$fmresultsetUri";
}
-
+
/**
* @return SimpleXMLElement
*/
public function load(Adapter $adapter)
{
$this->adapter = $adapter;
-
+
self::prepare();
-
-
+
+
$curlHandle = curl_init(self::createPostURL());
-
+
curl_setopt($curlHandle, CURLOPT_USERPWD, $this->credentials);
curl_setopt($curlHandle, CURLOPT_POST, TRUE);
curl_setopt($curlHandle, CURLOPT_POSTFIELDS, $this->args);
-
+
ob_start();
-
+
if (!curl_exec($curlHandle)) {
ob_end_clean();
throw new LoaderException('cURL was unable to connect.');
}
-
+
curl_close($curlHandle);
-
+
$data = trim(ob_get_contents());
-
+
ob_end_clean();
-
+
libxml_use_internal_errors(true);
-
+
return simplexml_load_string($data);
-
+
}
-
+
}
View
12 library/Soliant/SimpleFM/Loader/FileGetContents.php
@@ -16,20 +16,20 @@
class FileGetContents extends AbstractLoader
{
-
+
/**
* @return SimpleXMLElement
*/
public function load(Adapter $adapter)
{
$this->adapter = $adapter;
-
+
self::prepare();
-
+
libxml_use_internal_errors(true);
-
+
return simplexml_load_string(file_get_contents($this->commandURL));
-
+
}
-
+
}
View
22 library/Soliant/SimpleFM/Loader/FilePostContents.php
@@ -16,29 +16,29 @@
class FilePostContents extends AbstractLoader
{
-
+
protected function createPostURL()
{
$protocol = $this->adapter->getProtocol();
$hostname = $this->adapter->getHostname();
$port = $this->adapter->getPort();
$fmresultsetUri = $this->adapter->getFmresultsetUri();
-
+
return "$protocol://$hostname:$port$fmresultsetUri";
}
-
+
/**
* @return SimpleXMLElement
*/
public function load(Adapter $adapter)
{
$this->adapter = $adapter;
-
+
self::prepare();
-
+
libxml_use_internal_errors(true);
$authheader = empty($this->credentials) ? '' : 'Authorization: Basic '.base64_encode($this->credentials) . PHP_EOL;
-
+
$opts = array('http' =>
array(
'method' => 'POST',
@@ -51,12 +51,12 @@ public function load(Adapter $adapter)
'content' => $this->args
)
);
-
+
$context = stream_context_create($opts);
-
-
+
+
return simplexml_load_string(file_get_contents(self::createPostURL(), FALSE , $context));
-
+
}
-
+
}
View
5 library/Soliant/SimpleFM/Loader/LoaderInterface.php
@@ -13,12 +13,11 @@
interface LoaderInterface
{
-
+
/**
* @param array $simpleFMAdapterRow
* @return SimpleXMLElement
*/
public function load(Adapter $adapter);
-
-}
+}
View
18 library/Soliant/SimpleFM/Loader/Mock.php
@@ -20,7 +20,7 @@ class Mock extends AbstractLoader
* @var string
*/
protected $testXml;
-
+
/**
* @return the $testXml
*/
@@ -29,7 +29,7 @@ public function getTestXml ()
return $this->testXml;
}
- /**
+ /**
* @param string $testXml
*/
public function setTestXml ($testXml)
@@ -38,21 +38,21 @@ public function setTestXml ($testXml)
return $this;
}
- /**
+ /**
* @return SimpleXMLElement
*/
public function load(Adapter $adapter, $testXmlOverride=NULL)
{
$this->adapter = $adapter;
-
+
$testXml = $testXmlOverride ? $testXmlOverride : $this->testXml;
-
+
self::prepare();
-
+
libxml_use_internal_errors(true);
-
+
return simplexml_load_string($testXml);
-
+
}
-
+
}
View
4 library/Soliant/SimpleFM/Version.php
@@ -1,7 +1,7 @@
<?php
/**
* This source file is subject to the MIT license that is bundled with this package in the file LICENSE.txt.
- *
+ *
* @package Soliant\SimpleFM
* @copyright Copyright (c) 2007-2013 Soliant Consulting, Inc. (http://www.soliantconsulting.com)
* @author jsmall@soliantconsulting.com
@@ -11,5 +11,5 @@
final class Version
{
- const VERSION = '2.0.0beta5';
+ const VERSION = '2.0.0beta6';
}
View
2  library/Soliant/SimpleFM/ZF2/AdapterServiceFactory.php
@@ -1,7 +1,7 @@
<?php
/**
* This source file is subject to the MIT license that is bundled with this package in the file LICENSE.txt.
- *
+ *
* @package Soliant\SimpleFM
* @copyright Copyright (c) 2007-2013 Soliant Consulting, Inc. (http://www.soliantconsulting.com)
* @author jsmall@soliantconsulting.com
View
2  library/Soliant/SimpleFM/ZF2/Authentication/Adapter/Exception/InvalidArgumentException.php
@@ -4,4 +4,4 @@
class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
{
-}
+}
View
2  library/Soliant/SimpleFM/ZF2/Authentication/Adapter/Exception/RuntimeException.php
@@ -5,4 +5,4 @@
class RuntimeException extends \RuntimeException implements ExceptionInterface
{
-}
+}
View
2  library/Soliant/SimpleFM/ZF2/Authentication/Adapter/Exception/UnexpectedValueException.php
@@ -4,4 +4,4 @@
class UnexpectedValueException extends \UnexpectedValueException implements ExceptionInterface
{
-}
+}
View
16 library/Soliant/SimpleFM/ZF2/Authentication/Adapter/SimpleFM.php
@@ -115,7 +115,7 @@ public function __construct(array $config, Adapter $simpleFmValidateAdapter)
$this->accountNameField = $config['accountNameField'];
}
-
+
/**
* @return Soliant\SimpleFM\ZF2\Authentication\Adapter\Auth
*/
@@ -124,7 +124,7 @@ public function setUsername($username){
$this->credentials['username'] = $username;
return $this;
}
-
+
/**
* @return Soliant\SimpleFM\ZF2\Authentication\Adapter\Auth
*/
@@ -133,7 +133,7 @@ public function setPassword($password){
$this->credentials['password'] = $password;
return $this;
}
-
+
/**
* @return Zend\Authentication\Result
@@ -143,19 +143,19 @@ public function authenticate()
$this->simpleFmValidateAdapter->setLayoutname($this->identityLayout);
$this->simpleFmValidateAdapter->setCredentials($this->credentials);
-
+
$command = array(
$this->accountNameField => "==" . self::escapeStringForFileMakerSearch($this->username),
'-find' => NULL,
);
$this->simpleFmValidateAdapter->setCommandarray($command);
-
+
$result = $this->simpleFmValidateAdapter->execute();
-
+
$error = $result['error'];
$errortext = $result['errortext'];
$errortype = $result['errortype'];
-
+
// Based on the status, return auth result
switch ($error) {
case '0':
@@ -186,7 +186,7 @@ public function authenticate()
);
}
}
-
+
static public function escapeStringForFileMakerSearch($string)
{
return str_replace('@', '\@', $string);
View
2  library/Soliant/SimpleFM/ZF2/Authentication/Mapper/Exception/InvalidArgumentException.php
@@ -4,4 +4,4 @@
class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
{
-}
+}
View
36 library/Soliant/SimpleFM/ZF2/Authentication/Mapper/Identity.php
@@ -19,7 +19,7 @@
class Identity
{
protected $isLoggedIn = FALSE;
-
+
/**
* @Annotation\Type("Zend\Form\Element\Text")
* @Annotation\Required({"required":"true" })
@@ -27,7 +27,7 @@ class Identity
* @Annotation\Options({"label":"Username:"})
*/
public $username;
-
+
/**
* @Annotation\Type("Zend\Form\Element\Password")
* @Annotation\Required({"required":"true" })
@@ -35,13 +35,13 @@ class Identity
* @Annotation\Options({"label":"Password:"})
*/
public $password;
-
+
/**
* @Annotation\Type("Zend\Form\Element\Checkbox")
* @Annotation\Options({"label":"Remember Me:"})
*/
public $rememberme;
-
+
/**
* @Annotation\Type("Zend\Form\Element\Submit")
* @Annotation\Attributes({"value":"Submit"})
@@ -49,23 +49,23 @@ class Identity
public $submit;
public function __construct($username=NULL, $password=NULL, $encryptionKey=NULL, array $simpleFMAdapterRow=NULL){
-
+
$this->setUsername($username);
-
+
if (!empty($password)){
if (empty($encryptionKey)) {
throw new Exception\InvalidArgumentException('The you must provide an encryptionKey with the password.');
}
$this->setPassword($password, $encryptionKey);
}
-
- if (!empty($simpleFMAdapterRow)){
+
+ if (!empty($simpleFMAdapterRow)){
foreach ($simpleFMAdapterRow as $field => $value){
$this->setArbitraryProperty($field, $value);
}
}
}
-
+
/**
* Keep the provided syntax for the property name, but also create one that is only alphanumeric
* in case the field comes with spaces or special characters, so you don't have to do this every
@@ -91,8 +91,8 @@ public function setIsLoggedIn($value){
$this->isLoggedIn = $value;
return $this;
}
-
- /**
+
+ /**
* @return the $username
*/
public function getUsername ()
@@ -100,7 +100,7 @@ public function getUsername ()
return $this->username;
}
- /**
+ /**
* @param field_type $username
*/
public function setUsername ($username)
@@ -109,7 +109,7 @@ public function setUsername ($username)
return $this;
}
- /**
+ /**
* @return the $password
*/
public function getPassword ($encryptionKey)
@@ -117,18 +117,18 @@ public function getPassword ($encryptionKey)
if (empty($encryptionKey)) {
throw new Exception\InvalidArgumentException('The encryptionKey must not be empty');
}
-
+
$blockCipher = BlockCipher::factory('mcrypt', array('algo' => 'aes'));
$blockCipher->setKey($encryptionKey);
return $blockCipher->decrypt($this->password);
}
- /**
+ /**
* @param string $password
*/
public function setPassword ($password, $encryptionKey)
{
-
+
/**
* Password is encrypted so that the identity object is never at rest
* (e.g. in the session file or database) with a password in clear text.
@@ -139,11 +139,11 @@ public function setPassword ($password, $encryptionKey)
if (empty($encryptionKey)) {
throw new Exception\InvalidArgumentException('The encryptionKey must not be empty');
}
-
+
$blockCipher = BlockCipher::factory('mcrypt', array('algo' => 'aes'));
$blockCipher->setKey($encryptionKey);
$this->password = $blockCipher->encrypt($password);
-
+
$this;
}
View
2  library/Soliant/SimpleFM/ZF2/Authentication/Storage/Exception/InvalidArgumentException.php
@@ -4,4 +4,4 @@
class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
{
-}
+}
View
4 library/Soliant/SimpleFM/ZF2/Authentication/Storage/Session.php
@@ -19,9 +19,9 @@ public function setRememberMe($rememberMe = 0, $time = 1209600)
$this->session->getManager()->rememberMe($time);
}
}
-
+
public function forgetMe()
{
$this->session->getManager()->forgetMe();
- }
+ }
}
View
118 library/Soliant/SimpleFM/ZF2/Entity/AbstractEntity.php
@@ -29,6 +29,16 @@
protected $simpleFMAdapterRow;
/**
+ * @var array
+ */
+ protected $fieldMap;
+
+ /**
+ * @var array
+ */
+ protected $entityAsArray;
+
+ /**
* This property is marked TRUE by the constructor and may be updated by unserializeField()
* to allow serialization logic to avoid unintentional nullification of existing field values.
* @var boolean
@@ -38,9 +48,27 @@
/**
* @param array $simpleFMAdapterRow
*/
- public function __construct($simpleFMAdapterRow = array())
+ public function __construct($fieldMap, $simpleFMAdapterRow = array())
{
$this->simpleFMAdapterRow = $simpleFMAdapterRow;
+
+ if (empty($fieldMap)){
+ throw new InvalidArgumentException(get_class($this) . ' is empty or missing.');
+ }
+
+ if (!array_key_exists(get_class($this), $fieldMap)){
+ throw new InvalidArgumentException(get_class($this) . ' is missing from $fieldMap.');
+ }
+
+ $this->fieldMap = $fieldMap;
+ if (!array_key_exists('writeable', $this->fieldMap[get_class($this)])){
+ throw new InvalidArgumentException(get_class($this) . ' fieldMap must contain a "writeable" array.');
+ }
+
+ if (!array_key_exists('readonly', $this->fieldMap[get_class($this)])){
+ throw new InvalidArgumentException(get_class($this) . ' fieldMap must contain a "readonly" array.');
+ }
+
$this->isSerializable = TRUE;
if (!empty($this->simpleFMAdapterRow)) $this->unserialize();
}
@@ -51,7 +79,7 @@ public function __construct($simpleFMAdapterRow = array())
public function __toString()
{
- return (string) $this->getName();
+ return (string) $this->getName();
}
/**
@@ -72,7 +100,7 @@ public function setRecid ($recid)
return $this;
}
- /**
+ /**
* @note FileMaker internal modid
* @return the $modid
*/
@@ -81,7 +109,7 @@ public function getModid()
return (string) $this->modid;
}
- /**
+ /**
* @param number $modid
*/
public function setModid ($modid)
@@ -104,7 +132,7 @@ public function getIsSerializable ()
return $this->isSerializable;
}
- /**
+ /**
* @param boolean $isSerializable
*/
public function setIsSerializable ($isSerializable)
@@ -113,16 +141,16 @@ public function setIsSerializable ($isSerializable)
return $this;
}
- /**
+ /**
* Default FileMaker layout for the Entity which should include all the writable fields
*/
- abstract public static function getDefaultWriteLayoutName();
+ abstract public function getDefaultWriteLayoutName();
/**
* The route segment for the entity controller.
* Example: MyEntity route segment is normally my-entity
*/
- abstract public static function getDefaultControllerRouteSegment();
+ abstract public function getDefaultControllerRouteSegment();
/**
* Maps a SimpleFM\Adapter row onto the Entity.
@@ -130,8 +158,16 @@ public function setIsSerializable ($isSerializable)
*/
public function unserialize()
{
- $this->unserializeField('recid', 'recid');
- $this->unserializeField('modid', 'modid');
+ $this->unserializeField('recid', 'recid');
+ $this->unserializeField('modid', 'modid');
+
+ foreach ($this->fieldMap[get_class($this)]['writeable'] as $property=>$field) {
+ $this->unserializeField($property, $field, true);
+ }
+
+ foreach ($this->fieldMap[get_class($this)]['readonly'] as $property=>$field) {
+ $this->unserializeField($property, $field, false);
+ }
}
/**
@@ -145,17 +181,44 @@ public function serialize()
$this->serializeField('-recid', 'getRecid');
$this->serializeField('-modid', 'getModid');
+
+ foreach ($this->fieldMap[get_class($this)]['writeable'] as $property=>$field) {
+ $this->serializeField($field, $property);
+ }
+
+ foreach ($this->fieldMap[get_class($this)]['readonly'] as $property=>$field) {
+ $this->serializeField($field, $property);
+ }
+
}
+ /**
+ * @return the $entityAsArray
+ */
+ public function toArray() {
+
+ $this->addPropertyToEntityAsArray('recid');
+ $this->addPropertyToEntityAsArray('modid');
+
+ foreach ($this->fieldMap[get_class($this)]['writeable'] as $property=>$field) {
+ $this->addPropertyToEntityAsArray($property);
+ }
+
+ foreach ($this->fieldMap[get_class($this)]['readonly'] as $property=>$field) {
+ $this->addPropertyToEntityAsArray($property);
+ }
+
+ return $this->entityAsArray;
+ }
/**
* For unserialize, optimized layouts are permitted to omit fields defined by the entity.
- * If a required field is omitted, $this->isSerializable is marked FALSE
+ * If a required field is omitted, $this->isSerializable is marked false
* @param string $propertyName
* @param string $fileMakerFieldName
* @throws InvalidArgumentException
*/
- protected function unserializeField($propertyName, $fileMakerFieldName, $isWritable=FALSE)
+ protected function unserializeField($propertyName, $fileMakerFieldName, $isWritable = false)
{
if (!property_exists($this, $propertyName)){
throw new InvalidArgumentException($propertyName . ' is not a valid property.');
@@ -163,7 +226,7 @@ protected function unserializeField($propertyName, $fileMakerFieldName, $isWrita
if (array_key_exists($fileMakerFieldName, $this->simpleFMAdapterRow)){
$this->$propertyName = $this->simpleFMAdapterRow[$fileMakerFieldName];
} elseif ($isWritable) {
- $this->isSerializable = FALSE;
+ $this->isSerializable = false;
}
}
@@ -171,12 +234,14 @@ protected function unserializeField($propertyName, $fileMakerFieldName, $isWrita
* For serialize, all isRequired fields are required except the pseudo-fields recid and modid
* which are always optional to handle force edit (blank modid) and new (blank recid).
* @param string $fileMakerFieldName
- * @param string $getterName
+ * @param string $propertyName
* @throws InvalidArgumentException
* @throws Exception
*/
- protected function serializeField($fileMakerFieldName, $getterName)
+ protected function serializeField($fileMakerFieldName, $propertyName)
{
+ $getterName = 'get' . ucfirst($propertyName);
+
if ($getterName == 'getRecid'){
$value = $this->getRecid();
if (!empty($value)){
@@ -201,5 +266,26 @@ protected function serializeField($fileMakerFieldName, $getterName)
}
}
+ /**
+ * For toArray, all fields should be mapped
+ * @param string $propertyName
+ * @throws InvalidArgumentException
+ * @throws Exception
+ */
+ protected function addPropertyToEntityAsArray($propertyName)
+ {
+ $getterName = 'get' . ucfirst($propertyName);
+
+ try {
+ $this->entityAsArray[$propertyName] = $this->$getterName();
+ } catch (\Exception $e) {
+ if (!is_callable($this, $getterName)){
+ throw new InvalidArgumentException($getterName . ' is not a valid getter.', '', $e);
+ } else {
+ throw $e;
+ }
+ }
+
+ }
-}
+}
View
198 library/Soliant/SimpleFM/ZF2/Gateway/AbstractGateway.php
@@ -9,67 +9,78 @@
namespace Soliant\SimpleFM\ZF2\Gateway;
-use Zend\EventManager\EventManager;
-use Zend\ServiceManager\ServiceManager;
use Doctrine\Common\Collections\ArrayCollection;
use Soliant\SimpleFM\Adapter as SimpleFMAdapter;
use Soliant\SimpleFM\Exception\ErrorException;
use Soliant\SimpleFM\Exception\FileMakerException;
use Soliant\SimpleFM\Exception\HttpException;
use Soliant\SimpleFM\Exception\XmlException;
+use Soliant\SimpleFM\Exception\InvalidArgumentException;
use Soliant\SimpleFM\ZF2\Entity\AbstractEntity;
use Soliant\SimpleFM\ZF2\Authentication\Mapper\Identity;
-abstract class AbstractGateway
+abstract class AbstractGateway
{
/**
- * @var \Zend\EventManager\EventManager
- */
- protected $eventManager;
-
- /**
- * @var \Zend\ServiceManager\ServiceManager
- */
- protected $serviceManager;
-
- /**
* The fully qualified class name for an object that implements
* \Soliant\SimpleFM\ZF2\Entity\AbstractEntity
* @var string
*/
protected $entityName;
-
+
/**
* The FileMaker Layout assigned to the $entityPointerName
* @var string
*/
protected $entityLayout;
-
+
+ /**
+ * @var array
+ */
+ protected $fieldMap;
+
/**
* @var \Soliant\SimpleFM\Adapter
*/
protected $simpleFMAdapter;
-
+
/**
* @param ServiceManager $serviceManager
* @param AbstractEntity $entity
* @param SimpleFMAdapter $simpleFMAdapter
*/
- public function __construct(ServiceManager $serviceManager, AbstractEntity $entity, SimpleFMAdapter $simpleFMAdapter, Identity $identity=NULL, $encryptionKey=NULL )
+ public function __construct($fieldMap, AbstractEntity $entity, SimpleFMAdapter $simpleFMAdapter, Identity $identity=NULL, $encryptionKey=NULL )
{
- $this->setServiceManager($serviceManager);
+ if (!is_array($fieldMap)){
+ throw new InvalidArgumentException('$fieldMap must be an array.');
+ }
+
$this->setSimpleFMAdapter($simpleFMAdapter);
$this->setEntityName(get_class($entity));
- $this->setEntityLayout($entity::getDefaultWriteLayoutName());
-
+ $this->setEntityLayout($entity->getDefaultWriteLayoutName());
+
+ if (!array_key_exists($this->getEntityName(), $fieldMap)){
+ throw new InvalidArgumentException($this->getEntityName() . ' is missing from $fieldMap.');
+ }
+
+ $this->fieldMap = $fieldMap;
+
+ if (!array_key_exists('writeable', $this->fieldMap[$this->getEntityName()])){
+ throw new InvalidArgumentException($this->getEntityName() . ' fieldMap is missing from "writeable" array.');
+ }
+
+ if (!array_key_exists('readonly', $this->fieldMap[$this->getEntityName()])){
+ throw new InvalidArgumentException($this->getEntityName() . ' fieldMap is missing from "readonly" array.');
+ }
+
if (!empty($identity) && !empty($encryptionKey)) {
$this->simpleFMAdapter->setUsername($identity->getUsername());
$this->simpleFMAdapter->setPassword($identity->getPassword($encryptionKey));
}
-
+
}
-
+
/**
* @param AbstractEntity $entity
* @param string $entityLayout
@@ -82,7 +93,7 @@ public function resolveEntity(AbstractEntity $entity, $entityLayout=NULL)
}
return $this->find($entity->getRecid());
}
-
+
public function find($recid)
{
$commandArray = array('-recid' => $recid, '-find' => NULL);
@@ -93,11 +104,11 @@ public function find($recid)
$entity = new $this->entityName($result['rows'][0]);
return $entity;
}
-
+
public function findOneBy(array $search)
{
$commandArray = array_merge(
- $search,
+ $search,
array(
'-max' => '1',
'-find' => NULL
@@ -110,7 +121,7 @@ public function findOneBy(array $search)
$entity = new $this->entityName($result['rows'][0]);
return $entity;
}
-
+
public function findAll(array $sort = array(), $max = NULL, $skip = NULL)
{
$commandArray = array_merge(
@@ -121,10 +132,10 @@ public function findAll(array $sort = array(), $max = NULL, $skip = NULL)
$this->simpleFMAdapter
->setCommandArray($commandArray)
->setLayoutname($this->getEntityLayout());
- $result = $this->handleAdapterResult($this->simpleFMAdapter->execute());
+ $result = $this->handleAdapterResult($this->simpleFMAdapter->execute());
return $this->rowsToArrayCollection($result['rows']);
}
-
+
public function findBy(array $search, array $sort = array(), $max = NULL, $skip = NULL)
{
$commandArray = array_merge(
@@ -136,10 +147,10 @@ public function findBy(array $search, array $sort = array(), $max = NULL, $skip
$this->simpleFMAdapter
->setCommandArray($commandArray)
->setLayoutname($this->getEntityLayout());
- $result = $this->handleAdapterResult($this->simpleFMAdapter->execute());
+ $result = $this->handleAdapterResult($this->simpleFMAdapter->execute());
return $this->rowsToArrayCollection($result['rows']);
}
-
+
public function create(AbstractEntity $entity)
{
$serializedValues = $entity->serialize();
@@ -152,11 +163,11 @@ public function create(AbstractEntity $entity)
$this->simpleFMAdapter
->setCommandArray($commandArray)
->setLayoutname($this->getEntityLayout());
- $result = $this->handleAdapterResult($this->simpleFMAdapter->execute());
+ $result = $this->handleAdapterResult($this->simpleFMAdapter->execute());
$entity = new $this->entityName($result['rows'][0]);
return $entity;
}
-
+
public function edit(AbstractEntity $entity)
{
$commandArray = array_merge(
@@ -168,12 +179,12 @@ public function edit(AbstractEntity $entity)
$this->simpleFMAdapter
->setCommandArray($commandArray)
->setLayoutname($this->getEntityLayout());
- $result = $this->handleAdapterResult($this->simpleFMAdapter->execute());
-
+ $result = $this->handleAdapterResult($this->simpleFMAdapter->execute());
+
$entity = new $this->entityName($result['rows'][0]);
return $entity;
}
-
+
public function delete(AbstractEntity $entity)
{
$commandArray = array(
@@ -184,10 +195,10 @@ public function delete(AbstractEntity $entity)
$this->simpleFMAdapter
->setCommandArray($commandArray)
->setLayoutname($this->getEntityLayout());
- $result = $this->handleAdapterResult($this->simpleFMAdapter->execute());
+ $result = $this->handleAdapterResult($this->simpleFMAdapter->execute());
return true;
}
-
+
/**
* @return SimpleFMAdapter
@@ -196,7 +207,7 @@ public function getSimpleFMAdapter()
{
return $this->simpleFMAdapter;
}
-
+
/**
* @param SimpleFMAdapter $simpleFMAdapter
* @return \Soliant\SimpleFM\ZF2\Gateway\AbstractGateway
@@ -207,7 +218,7 @@ public function setSimpleFMAdapter(SimpleFMAdapter $simpleFMAdapter)
return $this;
}
- /**
+ /**
* @return the $entityLayout
*/
public function getEntityLayout ()
@@ -215,7 +226,7 @@ public function getEntityLayout ()
return $this->entityLayout;
}
- /**
+ /**
* @param string $entityLayout
* @return \Soliant\SimpleFM\ZF2\Gateway\AbstractGateway
*/
@@ -223,36 +234,10 @@ public function setEntityLayout ($entityLayout)
{
$this->entityLayout = $entityLayout;
return $this;
-
- }
- /**
- * @param ServiceManager $serviceManager
- * @return \Soliant\SimpleFM\ZF2\Gateway\AbstractGateway
- */
- public function setServiceManager(ServiceManager $serviceManager)
- {
- $this->serviceManager = $serviceManager;
- return $this;
}
/**
- * @return ServiceManager
- */
- public function getServiceManager()
- {
- return $this->serviceManager;
- }
-
- /**
- * @return \Zend\ServiceManager\ServiceManager
- */
- public function getLocator()
- {
- return $this->getServiceManager();
- }
-
- /**
* Example return: Application\Entity\Entity
* @return string
*/
@@ -261,7 +246,7 @@ public function getEntityName()
return $this->entityName;
}
- /**
+ /**
* @param string $entityName
* @return \Soliant\SimpleFM\ZF2\Gateway\AbstractGateway
*/
@@ -272,44 +257,19 @@ public function setEntityName ($entityName)
}
/**
- * @return the $eventManager
- */
- public function getEventManager ()
- {
- return $this->eventManager;
- }
-
- /**
- * Set the event manager to use with this object
- * @param EventManager $events
- * @return \Soliant\SimpleFM\ZF2\Gateway\AbstractGateway
+ * @return the $fieldMap
*/
- public function setEventManager(EventManager $events)
- {
- $this->eventManager = $events;
- return $this;
+ public function getFieldMap() {
+ return $this->fieldMap;
}
/**
- * Retrieve the currently set event manager
- *
- * If none is initialized, an EventManager instance will be created with
- * the contexts of this class, the current class name (if extending this
- * class), and "bootstrap".
- *
- * @return EventManager
+ * @param multitype: $fieldMap
*/
- public function events()
- {
- if (!$this->eventManager instanceof EventManager) {
- $this->setEventManager(new EventManager(array(
- __CLASS__,
- get_called_class(),
- )));
- }
- return $this->eventManager;
+ public function setFieldMap($fieldMap) {
+ $this->fieldMap = $fieldMap;
}
-
+
/**
* @param int $max
* @param int $skip
@@ -317,30 +277,30 @@ public function events()
*/
protected function maxSkipToCommandArray($max = NULL, $skip = NULL)
{
-
+
$maxCommand = empty($max) ? array() : array('-max' => $max);
$skipCommand = empty($skip) ? array() : array('-skip' => $skip);
-
+
return array_merge($maxCommand, $skipCommand);
}
-
+
/**
* @param array $sort
* @return array
*/
protected function sortArrayToCommandArray(array $sort)
{
-
+
// -sortfield.[1-9] = fully-qualified-field-name
// -sortorder.[1-9] = [ascend|descend|value-list-name]
-
+
if (empty($sort)) return array();
-
+
$i = 1;
$command = array();
foreach ($sort as $field => $method){
if ($i > 9) break; // FileMaker API limited to max 9 fields
-
+
switch ($method) {
case 'dsc':
$sortMethod = 'descend';
@@ -367,16 +327,16 @@ protected function sortArrayToCommandArray(array $sort)
$sortMethod = $method;
break;
}
-
+
$command['-sortfield.' . $i] = $field;
$command['-sortorder.' . $i] = $sortMethod;
$i++;
}
-
+
return $command;
-
+
}
-
+
/**
* @param array $rows
* @return \Doctrine\Common\Collections\ArrayCollection
@@ -386,27 +346,27 @@ protected function rowsToArrayCollection(array $rows)
$collection = new ArrayCollection();
if (!empty($rows)){
foreach($rows as $row){
- $collection[] = new $this->entityName($row);
+ $collection[] = new $this->entityName($this->fieldMap, $row);
}
}
-
+
return $collection;
}
-
+
protected function handleAdapterResult($simpleFMAdapterResult)
{
- $message = $simpleFMAdapterResult['errortype'] . ' Error ' . $simpleFMAdapterResult['error'] . ': ' .
+ $message = $simpleFMAdapterResult['errortype'] . ' Error ' . $simpleFMAdapterResult['error'] . ': ' .
$simpleFMAdapterResult['errortext'] . '. ' . $simpleFMAdapterResult['url'];
-
+
if ($simpleFMAdapterResult['error'] === 0){
return $simpleFMAdapterResult;
-
+
} elseif ($simpleFMAdapterResult['errortype'] == 'FileMaker') {
throw new FileMakerException($message, $simpleFMAdapterResult['error']);
-
+
} elseif ($simpleFMAdapterResult['errortype'] == 'HTTP') {
throw new HttpException($message, $simpleFMAdapterResult['error']);
-
+
} elseif ($simpleFMAdapterResult['errortype'] == 'XML') {
throw new XmlException($message, $simpleFMAdapterResult['error']);
@@ -414,7 +374,7 @@ protected function handleAdapterResult($simpleFMAdapterResult)
throw new ErrorException($message, $simpleFMAdapterResult['error']);
}
}
-
+
}
Please sign in to comment.
Something went wrong with that request. Please try again.