diff --git a/.gitignore b/.gitignore
index dc5ccc3..f0fda76 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,5 @@
composer.phar
composer.lock
vendor/
+build/
+.phpunit.result.cache
diff --git a/.travis.yml b/.travis.yml
index 4e602a8..5341408 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,8 +1,7 @@
language: php
php:
- - 5.5
- - 5.6
- - 7.0
+ - 7.1
+ - 7.4
addons:
code_climate:
repo_token: d2e633c11ce9b2f6cdd21d775d295c9836064eaebe96590c2cb3b2370f893555
@@ -14,4 +13,4 @@ script:
- ./vendor/bin/phpcs --ignore=*/vendor/* --standard=PSR2 .
- ./vendor/bin/phpcs --standard=./vendor/athens/standard/ruleset.xml src
after_script:
- - vendor/bin/test-reporter
\ No newline at end of file
+ - vendor/bin/test-reporter
diff --git a/README.md b/README.md
index e59cf10..0395de1 100644
--- a/README.md
+++ b/README.md
@@ -17,10 +17,13 @@ For example:
-
+
+
+
+
@@ -76,7 +79,7 @@ Use
This client library provides a `Cipher` class and one Propel2 Behavior class.
-To designate a field as encrypted in your Propel schema, set its type as `varbinary` and include the `encryption` behavior. You may include multiple columns in the `encryption` behavior:
+To designate a field as encrypted in your Propel schema, set its type as `VARBINARY`, `LONGVARBINARY` or `BLOB` and include the `encryption` behavior. You may include multiple columns in the `encryption` behavior:
```
@@ -109,11 +112,40 @@ That's it! The class setters for `MySecretData` and `MySecretData2` now seamless
Remember that search/find and sort are now *broken* for `MySecretData` and `MySecretData2`, for reasons discussed above.
+## Filtering
+By default all encrypted columns are not searchable. It's possible to make all encrypted columns of a table searchable by setting a parameter `searchable` to `true`
+```
+
+```
+It's also possible to make a particular column as searchable using `column_name_searchable_*` prefix
+```
+
+```
+> **Be aware:** For the searchable columns will be used a fixed IV. It looses data security.
Compatibility
=============
-* PHP 5.5, 5.6, 7.0
+* PHP >=7.1
* Propel2
Todo
diff --git a/composer.json b/composer.json
index c5a27c9..d3fbe4a 100644
--- a/composer.json
+++ b/composer.json
@@ -12,11 +12,11 @@
]
},
"require": {
+ "php": ">=7.1",
"propel/propel": "~2.0@dev"
},
"require-dev": {
- "phpdocumentor/phpdocumentor": "2.7.*",
- "phpunit/phpunit": "4.5.*",
+ "phpunit/phpunit": ">=7.0",
"codeclimate/php-test-reporter": "dev-master",
"athens/standard": "*"
},
diff --git a/src/Cipher.php b/src/Cipher.php
index 12f9985..116643d 100644
--- a/src/Cipher.php
+++ b/src/Cipher.php
@@ -11,14 +11,18 @@
*/
class Cipher
{
-
const IV_SIZE = 16;
+
const ENCRYPTION_METHOD = "aes-256-cbc";
- /** @var Cipher */
+ /**
+ * @var Cipher
+ */
protected static $instance;
- /** @var string */
+ /**
+ * @var string
+ */
protected $passphrase;
/**
@@ -32,12 +36,18 @@ protected function __construct($passphrase)
/**
* Converts a plain-text string into an encrypted string
*
- * @param string $string Plain-text to encrypt.
- * @return string The encrypted string.
+ * @param string|null $string Plain-text to encrypt.
+ *
+ * @return string|null The encrypted string.
*/
- public function encrypt($string)
+ public function encrypt(?string $string): ?string
{
- $iv = mcrypt_create_iv(self::IV_SIZE, MCRYPT_RAND);
+ if ($string === null) {
+ return $string;
+ }
+
+ $iv = random_bytes(self::IV_SIZE);
+
return $this->doEncrypt($string, $iv);
}
@@ -58,21 +68,33 @@ public function encrypt($string)
* This method is employed for encrypting Propel columns that are designated as 'searchable'
* in the included EncryptionBehavior.
*
- * @param string $string Plain-text to encrypt.
- * @return string The encrypted string.
+ * @param string|null $string Plain-text to encrypt.
+ *
+ * @return string|null The encrypted string.
*/
- public function deterministicEncrypt($string)
+ public function deterministicEncrypt(?string $string): ?string
{
+ if ($string === null) {
+ return $string;
+ }
+
$iv = str_repeat("0", self::IV_SIZE);
+
+ // prevent second encryption during ModelCriteria::findOneOrCreate()
+ if (strpos($string, $iv) === 0) {
+ return $string;
+ }
+
return $this->doEncrypt($string, $iv);
}
/**
* @param string $string
* @param string $iv
+ *
* @return string
*/
- protected function doEncrypt($string, $iv)
+ protected function doEncrypt(string $string, string $iv): string
{
return $iv.openssl_encrypt($string, self::ENCRYPTION_METHOD, $this->passphrase, 0, $iv);
}
@@ -81,11 +103,13 @@ protected function doEncrypt($string, $iv)
* Converts an encrypted string into a plain-text string
*
* @param string $encryptedMessage The encrypted string.
+ *
* @return string The plaint-text string.
*/
- public function decrypt($encryptedMessage)
+ public function decrypt(string $encryptedMessage): string
{
$iv = substr($encryptedMessage, 0, self::IV_SIZE);
+
return openssl_decrypt(
substr($encryptedMessage, self::IV_SIZE),
self::ENCRYPTION_METHOD,
@@ -98,9 +122,10 @@ public function decrypt($encryptedMessage)
/**
* @param resource $encryptedStream
+ *
* @return null|string
*/
- public function decryptStream($encryptedStream)
+ public function decryptStream($encryptedStream): ?string
{
if ($encryptedStream === null) {
return null;
@@ -111,11 +136,13 @@ public function decryptStream($encryptedStream)
/**
* @param string $passphrase The passphrase to be used to encrypt/decrypt data.
+ *
* @return void
+ *
* @throws \Exception If you attempt to initialize the cipher more than one time
* in a page-load via ::createInstance.
*/
- public static function createInstance($passphrase)
+ public static function createInstance(string $passphrase): void
{
if (self::$instance !== null) {
throw new \Exception(
@@ -128,9 +155,10 @@ public static function createInstance($passphrase)
/**
* @return Cipher
+ *
* @throws \Exception if ::getInstance is called before cipher is initialized via ::createInstance.
*/
- public static function getInstance()
+ public static function getInstance(): self
{
if (self::$instance === null) {
throw new \Exception(
@@ -138,6 +166,7 @@ public static function getInstance()
'Call Cipher::createInstance($passphrase) before ::getInstance().'
);
}
+
return self::$instance;
}
}
diff --git a/src/EncryptionBehavior.php b/src/EncryptionBehavior.php
index e9f7ad6..1d64395 100644
--- a/src/EncryptionBehavior.php
+++ b/src/EncryptionBehavior.php
@@ -11,10 +11,11 @@
*/
class EncryptionBehavior extends Behavior
{
-
- /** @var array */
+ /**
+ * @var array
+ */
protected $parameters = [
- 'searchable' => false
+ 'searchable' => false,
];
/**
@@ -29,36 +30,37 @@ public function allowMultiple()
/**
* @param string $script
+ *
* @return void
+ *
* @throws \Exception If the schema specifies encryption on fields which are not
* VARBINARY.
*/
public function tableMapFilter(&$script)
{
+ if (static::encryptedColumnsDeclarationExists($script) === false) {
+ $insertLocation = strpos($script, ";", strpos($script, "const TABLE_NAME")) + 1;
+ static::insertEncryptedColumnsDeclaration($script, $insertLocation);
+ static::insertEncryptedColumnNameAccessMethods($script);
+ }
+
$table = $this->getTable();
+ $columnNames = $this->getColumnNames();
+ $searchableColumnNames = $this->getSearchableColumnNames();
- foreach ($this->getColumnNames() as $columnName) {
+ foreach ($columnNames as $columnName) {
$column = $table->getColumn($columnName);
- $columnIsVarbinary = $column->getType() === "VARBINARY";
-
- if ($columnIsVarbinary === false) {
- throw new \Exception("Encrypted columns must be of type VARBINARY. " .
+ if ($column->isLobType() === false) {
+ throw new \Exception("Encrypted columns must be of a binary type. " .
"Encrypted column '{$column->getName()}' of type '{$column->getType()}' found. " .
"Revise your schema.");
}
- }
- if (static::encryptedColumnsDeclarationExists($script) === false) {
- $insertLocation = strpos($script, ";", strpos($script, "const TABLE_NAME")) + 1;
- static::insertEncryptedColumnsDeclaration($script, $insertLocation);
- static::insertEncryptedColumnNameAccessMethods($script);
- }
-
- foreach ($this->getColumnRealNames() as $realColumnName) {
+ $realColumnName = $this->createRealColumnName($columnName, $table->getName());
static::insertEncryptedColumnName($script, $realColumnName);
- if ($this->isSearchable() === true || strtolower($this->isSearchable()) === 'true') {
+ if ($this->isSearchable($columnName, $searchableColumnNames)) {
static::insertSearchableEncryptedColumnName($script, $realColumnName);
}
}
@@ -66,20 +68,27 @@ public function tableMapFilter(&$script)
/**
* @param string $script
+ *
* @return void
*/
public function objectFilter(&$script)
{
- $phpColumnNames = $this->getColumnPhpNames();
+ $columnNames = $this->getColumnNames();
+ $searchableColumnNames = $this->getSearchableColumnNames();
+ $table = $this->getTable();
- foreach ($phpColumnNames as $columnPhpName) {
- $this->addEncryptionToSetter($script, $columnPhpName);
+ foreach ($columnNames as $columnName) {
+ $isSearchable = $this->isSearchable($columnName, $searchableColumnNames);
+ $columnPhpName = $table->getColumn($columnName)->getPhpName();
+
+ $this->addEncryptionToSetter($script, $columnPhpName, $isSearchable);
$this->addDecryptionToGetter($script, $columnPhpName);
}
}
/**
* @param string $script
+ *
* @return void
*/
public function queryFilter(&$script)
@@ -92,7 +101,6 @@ public function queryFilter(&$script)
public function addUsingOperator($p1, $value = null, $operator = null, $preferColumnCondition = true)
{
- /** @var StudentTableMap $tableMap */
$tableMap = $this->getTableMap();
/** @var boolean $isCriterion */
@@ -131,71 +139,114 @@ public function addUsingOperator($p1, $value = null, $operator = null, $preferCo
}
/**
- * @return string[]
+ * @param string $script
+ * @param string $realColumnName
+ *
+ * @return void
*/
- protected function getColumnNames()
+ public static function insertEncryptedColumnName(&$script, $realColumnName)
{
- $columnNames = [];
- foreach ($this->getParameters() as $key => $columnName) {
- if (strpos($key, "column_name") !== false && empty($columnName) !== true) {
- $columnNames[] = $columnName;
- }
- }
- return $columnNames;
+ $insertContent = "\n '$realColumnName', ";
+
+ $insertLocation = strpos($script, '$encryptedColumns = array(') + strlen('$encryptedColumns = array(');
+ $script = substr_replace($script, $insertContent, $insertLocation, 0);
}
/**
- * @return string[]
+ * @param string $script
+ * @param string $realColumnName
+ *
+ * @return void
*/
- protected function getColumnPhpNames()
+ public static function insertSearchableEncryptedColumnName(&$script, $realColumnName)
{
- $table = $this->getTable();
+ $insertContent = "\n '$realColumnName', ";
- return array_map(
- function ($columnName) use ($table) {
- return $table->getColumn($columnName)->getPhpName();
- },
- $this->getColumnNames()
- );
+ $insertLocation = strpos($script, '$encryptedSearchableColumns = array(')
+ + strlen('$encryptedSearchableColumns = array(');
+
+ $script = substr_replace($script, $insertContent, $insertLocation, 0);
}
/**
* @return string[]
*/
- protected function getColumnRealNames()
+ protected function getColumnNames(): array
{
- $tableName = $this->getTable()->getName();
+ return $this->getParameterValuesByPrefix('column_name');
+ }
- return array_map(
- function ($columnName) use ($tableName) {
- return "$tableName.$columnName";
- },
- $this->getColumnNames()
- );
+ /**
+ * @return string[]
+ */
+ protected function getSearchableColumnNames(): array
+ {
+ return $this->getParameterValuesByPrefix('column_name_searchable');
+ }
+
+ /**
+ * @param string $prefix
+ *
+ * @return array
+ */
+ protected function getParameterValuesByPrefix(string $prefix): array
+ {
+ $parameterValues = [];
+ foreach ($this->getParameters() as $parameterName => $parameterValue) {
+ if (strpos($parameterName, $prefix) !== false && !empty($parameterValue)) {
+ $parameterValues[] = $parameterValue;
+ }
+ }
+ return $parameterValues;
}
/**
+ * @param string $columnName
+ * @param string $tableName
+ *
+ * @return string
+ */
+ protected function createRealColumnName(string $columnName, string $tableName): string
+ {
+ return sprintf('%s.%s', $tableName, $columnName);
+ }
+
+ /**
+ * @param string $columnName
+ * @param array $searchableColumnNames
+ *
* @return boolean
*/
- protected function isSearchable()
+ protected function isSearchable(string $columnName, array $searchableColumnNames = []): bool
{
- return $this->getParameter('searchable');
+ $searchableParameter = $this->getParameter('searchable');
+
+ if ($searchableParameter === true
+ || strtolower($searchableParameter) === 'true'
+ || array_search($columnName, $searchableColumnNames) !== false
+ ) {
+ return true;
+ }
+
+ return false;
}
/**
* @param string $script
+ *
* @return boolean
*/
- protected static function encryptedColumnsDeclarationExists($script)
+ protected static function encryptedColumnsDeclarationExists(string $script): bool
{
return strpos($script, 'protected static $encryptedColumns') !== false;
}
/**
* @param string $script
+ *
* @return void
*/
- protected static function insertEncryptedColumnNameAccessMethods(&$script)
+ protected static function insertEncryptedColumnNameAccessMethods(string &$script): void
{
$useString = <<<'EOT'
@@ -230,11 +281,11 @@ public static function isEncryptedSearchableColumnName($columnName)
/**
* @param string $script
* @param integer $position
+ *
* @return void
*/
- protected static function insertEncryptedColumnsDeclaration(&$script, $position)
+ protected static function insertEncryptedColumnsDeclaration(string &$script, int $position): void
{
-
$content = <<<'EOT'
@@ -254,40 +305,14 @@ protected static function insertEncryptedColumnsDeclaration(&$script, $position)
$script = substr_replace($script, $content, $position, 0);
}
- /**
- * @param string $script
- * @param string $realColumnName
- * @return void
- */
- public static function insertEncryptedColumnName(&$script, $realColumnName)
- {
- $insertContent = "\n '$realColumnName', ";
-
- $insertLocation = strpos($script, '$encryptedColumns = array(') + strlen('$encryptedColumns = array(');
- $script = substr_replace($script, $insertContent, $insertLocation, 0);
- }
-
- /**
- * @param string $script
- * @param string $realColumnName
- * @return void
- */
- public static function insertSearchableEncryptedColumnName(&$script, $realColumnName)
- {
- $insertContent = "\n '$realColumnName', ";
-
- $insertLocation = strpos($script, '$encryptedSearchableColumns = array(')
- + strlen('$encryptedSearchableColumns = array(');
-
- $script = substr_replace($script, $insertContent, $insertLocation, 0);
- }
-
/**
* @param string $script
* @param string $columnPhpName
+ * @param bool $isSearchable
+ *
* @return void
*/
- protected function addEncryptionToSetter(&$script, $columnPhpName)
+ protected function addEncryptionToSetter(string &$script, string $columnPhpName, bool $isSearchable): void
{
$setterLocation = strpos($script, "set$columnPhpName");
@@ -295,7 +320,7 @@ protected function addEncryptionToSetter(&$script, $columnPhpName)
$length = strpos($script, ")", $setterLocation) - $start;
$variableName = substr($script, $start, $length);
- $encryptionMethod = $this->isSearchable() ? "deterministicEncrypt" : "encrypt";
+ $encryptionMethod = $isSearchable ? "deterministicEncrypt" : "encrypt";
$content = <<columns = [
- "VarBinaryColumn1" => new MockColumn("VarBinaryColumn1", "VARBINARY"),
- "VarBinaryColumn2" => new MockColumn("VarBinaryColumn2", "VARBINARY"),
- "NotVarBinaryColumn" => new MockColumn("NotVarBinaryColumn", "NOTVARBINARY")
- ];
-
- parent::__construct();
- }
-
- protected function normalizeWhitespace($string)
- {
- $string = trim($string);
- $string = str_replace("\r", "", $string);
-
- $string = join("\n", array_map("rtrim", explode("\n", $string)));
-
- return $string;
- }
-
- public function testObjectFilter()
- {
- $behavior = new MockEncryptionBehavior(
- $this->columns,
- [
- 'column_name' => "VarBinaryColumn1",
- 'searchable' => false
- ]
- );
-
- $behavior->objectFilter($this->objectFilterInput);
-
- $this->assertEquals(
- $this->normalizeWhitespace($this->objectFilterExpected),
- $this->normalizeWhitespace($this->objectFilterInput)
- );
- }
-
- public function testMapFilter()
- {
- $behavior = new MockEncryptionBehavior(
- $this->columns,
- [
- 'column_name' => "VarBinaryColumn1",
- 'searchable' => false
- ]
- );
-
- // Run table map filter once, and an encrypted columns declaration is created
- $behavior->tableMapFilter($this->mapFilterInput);
- $this->assertEquals(
- $this->normalizeWhitespace($this->mapFilterExpected),
- $this->normalizeWhitespace($this->mapFilterInput)
- );
-
- // Run it twice, and the new column name is inserted beside the old
- $behavior->tableMapFilter($this->mapFilterInput);
- $this->assertEquals(
- $this->normalizeWhitespace($this->mapFilterExpectedSecond),
- $this->normalizeWhitespace($this->mapFilterInput)
- );
- }
-
/**
- * @expectedException \Exception
- * @expectedExceptionMessageRegExp #Encrypted columns must be of type VARBINARY.*#
+ * @var string
*/
- public function testBehaviorExceptionOnNonVarBinaryColumn()
- {
- $behavior = new MockEncryptionBehavior(
- $this->columns,
- [
- 'column_name' => "NotVarBinaryColumn",
- 'searchable' => false,
- ]
- );
-
- // Run table map filter once, and an encrypted columns declaration is created
- $input = "";
- $behavior->tableMapFilter($input);
- }
-
protected $objectFilterInput = <<<'EOT'
public function getVarBinaryColumn1()
{
@@ -119,6 +40,9 @@ public function setVarBinaryColumn1($v)
} // setVarBinaryColumn1()
EOT;
+ /**
+ * @var string
+ */
protected $objectFilterExpected = <<<'EOT'
public function getVarBinaryColumn1()
{
@@ -151,6 +75,9 @@ public function setVarBinaryColumn1($v)
} // setVarBinaryColumn1()
EOT;
+ /**
+ * @var string
+ */
protected $mapFilterInput = <<columns = [
+ "VarBinaryColumn1" => new MockColumn("VarBinaryColumn1", "VARBINARY"),
+ "VarBinaryColumn2" => new MockColumn("VarBinaryColumn2", "VARBINARY"),
+ "BlobColumn" => new MockColumn("BlobColumn", "BLOB"),
+ "LongVarBinaryColumn" => new MockColumn("BlobColumn", "LONGVARBINARY"),
+ "NotVarBinaryColumn" => new MockColumn("NotVarBinaryColumn", "NOTVARBINARY"),
+ ];
+
+ parent::setUp();
+ }
+
+ /**
+ * @return void
+ */
+ public function testObjectFilter(): void
+ {
+ $behavior = new MockEncryptionBehavior(
+ $this->columns,
+ [
+ 'column_name' => "VarBinaryColumn1",
+ 'searchable' => false
+ ]
+ );
+
+ $behavior->objectFilter($this->objectFilterInput);
+
+ $this->assertEquals(
+ $this->normalizeWhitespace($this->objectFilterExpected),
+ $this->normalizeWhitespace($this->objectFilterInput)
+ );
+ }
+
+ /**
+ * @throws \Exception
+ *
+ * @return void
+ */
+ public function testMapFilter(): void
+ {
+ $behavior = new MockEncryptionBehavior(
+ $this->columns,
+ [
+ 'column_name' => "VarBinaryColumn1",
+ 'searchable' => false
+ ]
+ );
+
+ // Run table map filter once, and an encrypted columns declaration is created
+ $behavior->tableMapFilter($this->mapFilterInput);
+ $this->assertEquals(
+ $this->normalizeWhitespace($this->mapFilterExpected),
+ $this->normalizeWhitespace($this->mapFilterInput)
+ );
+
+ // Run it twice, and the new column name is inserted beside the old
+ $behavior->tableMapFilter($this->mapFilterInput);
+ $this->assertEquals(
+ $this->normalizeWhitespace($this->mapFilterExpectedSecond),
+ $this->normalizeWhitespace($this->mapFilterInput)
+ );
+ }
+
+ /**
+ * @throws \Exception
+ *
+ * @return void
+ */
+ public function testBehaviorExceptionOnNonVarBinaryColumn(): void
+ {
+ $this->expectException(\Exception::class);
+ $this->expectExceptionMessage('Encrypted columns must be of a binary type. Encrypted column \'NotVarBinaryColumn\' of type \'NOTVARBINARY\' found. Revise your schema.');
+
+ $behavior = new MockEncryptionBehavior(
+ $this->columns,
+ [
+ 'column_name' => "NotVarBinaryColumn",
+ 'searchable' => false,
+ ]
+ );
+
+ // Run table map filter once, and an encrypted columns declaration is created
+ $input = "";
+ $behavior->tableMapFilter($input);
+ }
+
+ /**
+ * @param $string
+ *
+ * @return string
+ */
+ protected function normalizeWhitespace($string): string
+ {
+ $string = trim($string);
+ $string = str_replace("\r", "", $string);
+
+ $string = join("\n", array_map("rtrim", explode("\n", $string)));
+
+ return $string;
+ }
}
diff --git a/test/CipherTest.php b/test/CipherTest.php
index e929ede..1891335 100644
--- a/test/CipherTest.php
+++ b/test/CipherTest.php
@@ -2,37 +2,55 @@
namespace Athens\Encryption\Test;
-use PHPUnit_Framework_TestCase;
-
+use PHPUnit\Framework\TestCase;
use Athens\Encryption\Cipher;
-class CipherTest extends PHPUnit_Framework_TestCase
+class CipherTest extends TestCase
{
-
/**
- * @expectedException Exception
- * @expectedExceptionMessageRegExp #called before initialization.*#
+ * @throws \Exception
+ *
+ * @return void
*/
- public function testGetInstanceBeforeCreate()
+ public function testGetInstanceBeforeCreate():void
{
+ $this->expectException(\Exception::class);
+ $this->expectExceptionMessage('called before initialization.');
+
Cipher::getInstance();
}
- public function testCipherCreation()
+ /**
+ * @throws \Exception
+ *
+ * @return void
+ */
+ public function testCipherCreation(): void
{
Cipher::createInstance("blaksjdfoiuwer");
+
+ $this->assertTrue(true);
}
/**
- * @expectedException Exception
- * @expectedExceptionMessageRegExp #Only one cipher instance may be created.*#
+ * @throws \Exception
+ *
+ * @return void
*/
- public function testCreateInstanceTwice()
+ public function testCreateInstanceTwice(): void
{
+ $this->expectException(\Exception::class);
+ $this->expectExceptionMessage('Only one cipher instance may be created.');
+
Cipher::createInstance("blaksjdfoiuwer");
}
- public function testEncrypt()
+ /**
+ * @throws \Exception
+ *
+ * @return void
+ */
+ public function testEncrypt(): void
{
$plainText = "plaintext";
@@ -43,7 +61,12 @@ public function testEncrypt()
$this->assertNotEquals($encryptedText1, $encryptedText2);
}
- public function testEncryptDecrypt()
+ /**
+ * @throws \Exception
+ *
+ * @return void
+ */
+ public function testEncryptDecrypt(): void
{
$plainText = "plaintext";
diff --git a/test/mock/MockColumn.php b/test/mock/MockColumn.php
index 6abd902..b86123a 100644
--- a/test/mock/MockColumn.php
+++ b/test/mock/MockColumn.php
@@ -8,6 +8,8 @@
namespace Athens\Encryption\Test\Mock;
+use Propel\Generator\Model\PropelTypes;
+
class MockColumn
{
protected $phpName;
@@ -33,4 +35,9 @@ public function getName()
{
return $this->phpName;
}
+
+ public function isLobType()
+ {
+ return PropelTypes::isLobType($this->getType());
+ }
}
diff --git a/test/mock/MockEncryptionBehavior.php b/test/mock/MockEncryptionBehavior.php
index 2341dd8..65581a1 100644
--- a/test/mock/MockEncryptionBehavior.php
+++ b/test/mock/MockEncryptionBehavior.php
@@ -13,7 +13,6 @@ public function __construct($columns, $parameters)
{
$this->parameters = $parameters;
$this->table = new MockTable($columns);
- parent::__construct();
}
public function getTable()
diff --git a/test/phpunit.xml b/test/phpunit.xml
index 2f5b22d..1840034 100644
--- a/test/phpunit.xml
+++ b/test/phpunit.xml
@@ -10,4 +10,4 @@
../src/
-
\ No newline at end of file
+