I want to adding custom type in specific column field. This part is still encrypt-decrypt specific column field used AES-256, here’s below src\Database\Type\CryptedType.php
namespace App\Database\Type;
use Cake\Database\DriverInterface;
use Cake\Database\Type\BaseType;
use Cake\Utility\Security;
use Cake\Database\TypeInterface;
class CryptedType extends BaseType
{
public function toDatabase($value, DriverInterface $driver)
{
return Security::encrypt($value, Security::getSalt());
}
public function toPHP($value, DriverInterface $driver)
{
if($value === null) {
return null;
}
return Security::decrypt($value, Security::getSalt());
}
}
when I run test on http://localhost/baksoganteng/users the error message display below
Fatal error: Class App\Database\Type\CryptedType contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Cake\Database\TypeInterface::marshal) in C:\xampp\htdocs\baksoganteng\src\Database\Type\CryptedType.php on line 10
Warning (512): Unable to emit headers. Headers sent in file=C:\xampp\htdocs\baksoganteng\src\Database\Type\CryptedType.php line=10 [CORE\src\Http\ResponseEmitter.php, line 71]
Warning (2): Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\baksoganteng\src\Database\Type\CryptedType.php:10) [CORE\src\Http\ResponseEmitter.php, line 168]
Warning (2): Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\baksoganteng\src\Database\Type\CryptedType.php:10) [CORE\src\Http\ResponseEmitter.php, line 197]
Error Class App\Database\Type\CryptedType contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Cake\Database\TypeInterface::marshal)
File C:\xampp\htdocs\baksoganteng\src\Database\Type\CryptedType.php
Line 10
4. use Cake\Database\DriverInterface;
5. use Cake\Database\Type\BaseType;
6. use Cake\Utility\Security;
7. use Cake\Database\TypeInterface::marshal;
class CryptedType extends BaseType
{
Error in: ROOT\src\Database\Type\CryptedType.php, line 7
this is basic PHP OOP knowledge so either try learning more about that via googleing it or use an IDE which helps you do those basic OOP things automatically for you like PHPStorm or VSCode (with addons)
so in general you NEED to implement/add every function mentioned in the interface to your class
because the BaseType class (which your CryptedType extends from) implements that interface
thanx for guide, I was follow guide above and added a few line below \src\Database\Type\CryptedType.php
<?php
namespace App\Database\Type;
use Cake\Database\DriverInterface;
use Cake\Utility\Security;
use Cake\Database\TypeInterface;
use PDO;
class CryptedType implements TypeInterface
{
public function toDatabase($value, DriverInterface $driver)
{
return Security::encrypt($value, Security::getSalt());
}
public function toPHP($value, DriverInterface $driver)
{
if($value === null) {
return null;
}
return Security::decrypt($value, Security::getSalt());
}
public function getBaseType(): ?string
{
return $this->_name;
}
public function toStatement($value, DriverInterface $driver)
{
if ($value === null) {
return PDO::PARAM_NULL;
}
return PDO::PARAM_STR;
}
public function marshal($value)
{
if ($value === null || $value === '') {
return null;
}
if (is_string($value) && $this->_useLocaleParser) {
return $this->_parseValue($value);
}
if (is_numeric($value)) {
return (float)$value;
}
if (is_string($value) && preg_match('/^[0-9,. ]+$/', $value)) {
return $value;
}
return null;
}
public function newId()
{
return null;
}
public function getName(): ?string
{
return $this->_name;
}
}
but while run test, there’s error display below
App\Model\Table\UsersTable::beforeFind(): Argument #4 ($primary) must be of type Cake\Table\boolean, bool given, called in C:\xampp\htdocs\baksoganteng\vendor\cakephp\cakephp\src\Event\EventManager.php on line 309
TypeError
where’s the part I should be fix in \Table\UsersTable.php
<?php
declare(strict_types=1);
namespace App\Model\Table;
use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
use Cake\Event\Event;
use ArrayObject;
use Cake\Utility\Security;
use Cake\Database\Schema\Table as Schema;
use Cake\Database\Type\BaseType;
use Cake\Table\boolean;
use Cake\Database\Schema\TableSchemaInterface;
use Cake\Database\Type\ColumnSchemaAwareInterface;
use Cake\Datasource\ResultSetInterface;
use Cake\Datasource\EntityInterface;
use Cake\Collection\CollectionInterface;
class UsersTable extends Table
{
public function beforeFind(Event $event, Query $query, ArrayObject $options, boolean $primary): beforeFind
{
$query->formatResults(
function($results) {
return $results->map(function ($row) {
foreach($this->encryptedFields as $fieldName) {
if(isset($row[$fieldName])) {
$row[$fieldName] = Security::decrypt($row[$fieldName], Security::getSalt());
}
}
return $row;
});
}
);
}
}