-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a transaction id generation by date #7
base: 1.6
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<?php | ||
|
||
namespace Ekyna\Component\Payum\Payzen\Api; | ||
|
||
use Exception; | ||
|
||
class IdGeneratedByDate implements TransactionIdInterface | ||
{ | ||
/** | ||
* @throws Exception | ||
*/ | ||
public function getTransactionId(): array | ||
{ | ||
$diff = (new \DateTimeImmutable('midnight', new \DateTimeZone('UTC'))) | ||
->diff(new \DateTimeImmutable('now', new \DateTimeZone('UTC'))); | ||
return [ | ||
'vads_trans_date' => (new \DateTime('now', new \DateTimeZone('UTC')))->format('YmdHis'), | ||
'vads_trans_id' => sprintf('%06d', random_int(0, 9) + (($diff->h * 3600 + $diff->i * 60 + $diff->s) * 10)) | ||
]; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
<?php | ||
|
||
namespace Ekyna\Component\Payum\Payzen\Api; | ||
|
||
use Exception; | ||
use Payum\Core\Exception\RuntimeException; | ||
|
||
class IdGeneratedByFile implements TransactionIdInterface | ||
{ | ||
private $path; | ||
private $debug; | ||
|
||
public function __construct( | ||
string $path, | ||
bool $debug = false | ||
) { | ||
$this->path = $path; | ||
$this->debug = $debug; | ||
} | ||
|
||
/** | ||
* @throws Exception | ||
*/ | ||
public function getTransactionId(): array | ||
{ | ||
$this->createDirectoryPath(); | ||
$this->path = rtrim($this->path,DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; | ||
$path = $this->path . 'transaction_id'; | ||
|
||
// Create file if not exists | ||
if (!file_exists($path)) { | ||
touch($path); | ||
chmod($path, 0600); | ||
} | ||
|
||
$date = (new \DateTime())->format('Ymd'); | ||
$fileDate = date('Ymd', filemtime($path)); | ||
$isDailyFirstAccess = ($date != $fileDate); | ||
|
||
// Open file | ||
$handle = fopen($path, 'r+'); | ||
if (false === $handle) { | ||
throw new RuntimeException('Failed to open the transaction ID file.'); | ||
} | ||
// Lock File | ||
if (!flock($handle, LOCK_EX)) { | ||
throw new RuntimeException('Failed to lock the transaction ID file.'); | ||
} | ||
|
||
$id = 1; | ||
// If not daily first access, read and increment the id | ||
if (!$isDailyFirstAccess) { | ||
$id = (int)fread($handle, 6); | ||
$id++; | ||
} | ||
|
||
// Truncate, write, unlock and close. | ||
fseek($handle, 0); | ||
ftruncate($handle, 0); | ||
fwrite($handle, (string)$id); | ||
fflush($handle); | ||
flock($handle, LOCK_UN); | ||
fclose($handle); | ||
|
||
if ($this->debug) { | ||
$id += 89000; | ||
} | ||
|
||
return [ | ||
'vads_trans_date' => (new \DateTime('now', new \DateTimeZone('UTC')))->format('YmdHis'), | ||
'vads_trans_id' => str_pad($id, 6, '0', STR_PAD_LEFT) | ||
]; | ||
} | ||
|
||
/** | ||
* Returns the directory path and creates it if not exists. | ||
*/ | ||
public function createDirectoryPath(): void | ||
{ | ||
// Create directory if not exists | ||
if (!is_dir($this->path)) { | ||
if (!mkdir($this->path, 0755, true)) { | ||
throw new RuntimeException('Failed to create cache directory'); | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<?php | ||
|
||
namespace Ekyna\Component\Payum\Payzen\Api; | ||
|
||
interface TransactionIdInterface | ||
{ | ||
/** @return array{vads_trans_date: string, vads_trans_id: string} */ | ||
public function getTransactionId(): array; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,8 @@ | |
|
||
namespace Ekyna\Component\Payum\Payzen; | ||
|
||
use Ekyna\Component\Payum\Payzen\Api\IdGeneratedByFile; | ||
use Ekyna\Component\Payum\Payzen\Api\TransactionIdInterface; | ||
use Payum\Core\Bridge\Spl\ArrayObject; | ||
use Payum\Core\GatewayFactory; | ||
use Payum\Core\GatewayFactoryInterface; | ||
|
@@ -13,17 +15,28 @@ | |
*/ | ||
class PayzenGatewayFactory extends GatewayFactory | ||
{ | ||
private $transactionId; | ||
|
||
public function __construct( | ||
array $defaultConfig = array(), | ||
GatewayFactoryInterface $coreGatewayFactory = null, | ||
TransactionIdInterface $transactionId = null | ||
) { | ||
parent::__construct($defaultConfig, $coreGatewayFactory); | ||
$this->transactionId = $transactionId ?? new IdGeneratedByFile($defaultConfig['directory'] ?? sys_get_temp_dir()); | ||
} | ||
|
||
/** | ||
* Builds a new factory. | ||
* | ||
* @param array $defaultConfig | ||
* @param array $defaultConfig | ||
* @param GatewayFactoryInterface|null $coreGatewayFactory | ||
* | ||
* @param TransactionIdInterface|null $transactionId | ||
* @return PayzenGatewayFactory | ||
*/ | ||
public static function build(array $defaultConfig, GatewayFactoryInterface $coreGatewayFactory = null): PayzenGatewayFactory | ||
public static function build(array $defaultConfig, GatewayFactoryInterface $coreGatewayFactory = null, TransactionIdInterface $transactionId = null): PayzenGatewayFactory | ||
{ | ||
return new static($defaultConfig, $coreGatewayFactory); | ||
return new static($defaultConfig, $coreGatewayFactory, $transactionId); | ||
} | ||
|
||
/** | ||
|
@@ -42,7 +55,7 @@ protected function populateConfig(ArrayObject $config) | |
'payum.action.refund' => new Action\RefundAction(), | ||
'payum.action.status' => new Action\StatusAction(), | ||
'payum.action.notify' => new Action\NotifyAction(), | ||
'payum.action.api.request' => new Action\Api\ApiRequestAction(), | ||
'payum.action.api.request' => new Action\Api\ApiRequestAction($this->transactionId), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Inject transaction id generator into Api instance (see next comment) instead of ApiRequestAction . |
||
'payum.action.api.response' => new Action\Api\ApiResponseAction(), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might be possible to configure transaction id generator here. Something like: 'payum.action.api.directory' => sys_get_temp_dir(),
'payum.action.api.id_generator' => function(array $config) {
return new IdGeneratedByFile($config['payum.action.api.directory'])
}, then, when configuring api (around line 92), maybe you can do something like this: $config['payum.api'] = function (ArrayObject $config) {
$api = new Api\Api();
$api->setConfig($payzenConfig);
$api->setIdGenerator($config['payum.action.api.id_generator']);
return $api;
}; There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree too, when you are using Payum, it's better to inject what you need on the Action or on the Api services. Here it's better to just inject it into |
||
]); | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not compatible with Payum/Core:
PayumBuilder::buildAddedGatewayFactories() won't give a value to $transationId argument.
I think default translation id generator should be defined in the default config.