feat: moneta 2.0, MONETA.Assistant payment module for PHPShop 6.7+
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace MonetaPhpShop\host;
|
||||
|
||||
use MonetaPhpShop\callback\LogThrottle;
|
||||
use MonetaPhpShop\ModuleInfo;
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* {@see LogThrottle} â îòäåëüíîé òàáëèöå `[base] moneta_log_throttle` (îäíà ñòðîêà): `logged_at` —
|
||||
* âðåìÿ ïîñëåäíåé çàïèñàííîé ñòðîêè, `skipped` — ñêîëüêî ïðîïóùåíî ïîñëå íå¸. Íå â òàáëèöå
|
||||
* íàñòðîåê: çàïèñü â MyISAM áëîêèðóåò òàáëèöó öåëèêîì, à íàñòðîéêè ÷èòàåò êàæäûé êîëáýê è êàæäàÿ
|
||||
* ñòðàíèöà ñ ôîðìîé îïëàòû — ïîòîê ìóñîðíûõ çàïðîñîâ çàäåðæèâàë áû íàñòîÿùèå óâåäîìëåíèÿ.
|
||||
*
|
||||
* Çàõâàò ìåòêè — îäèí àòîìàðíûé çàïðîñ, ïîýòîìó èç îäíîâðåìåííûõ çàïðîñîâ ñòðîêó ïèøåò îäèí;
|
||||
* ñ÷¸ò÷èê ïðîïóñêîâ ïðè ãîíêå ìîæåò ñáèòüñÿ íà åäèíèöó. Ñòðîêè íåò
|
||||
* (óäàëèëè ðóêàìè, ìèãðàöèÿ íå âñòàâèëà) — òîò æå çàïðîñ å¸ ñîçäà¸ò: èíà÷å îáà UPDATE
|
||||
* çàòðàãèâàëè áû 0 ñòðîê è îòêàçû ìîë÷à ïðîïàäàëè áû èç æóðíàëà.
|
||||
*/
|
||||
final class MysqlLogThrottle implements LogThrottle
|
||||
{
|
||||
/** Åäèíñòâåííàÿ ñòðîêà ñ÷¸ò÷èêà (`install/module.sql`). */
|
||||
private const ROW_ID = 1;
|
||||
|
||||
/** @var Database */
|
||||
private $database;
|
||||
|
||||
public function __construct(Database $database)
|
||||
{
|
||||
$this->database = $database;
|
||||
}
|
||||
|
||||
public function pass(int $now, int $interval): ?int
|
||||
{
|
||||
$table = self::table();
|
||||
|
||||
// Çàòðîíóòûå ñòðîêè: 1 — ñòðîêè íå áûëî è îíà âñòàâëåíà, 2 — ìåòêà îáíîâëåíà,
|
||||
// 0 — îêíî åù¸ îòêðûòî è ñòðîêà íå èçìåíèëàñü. Âðåìÿ â áóäóùåì (÷àñû ñåðâåðà ïåðåâåëè
|
||||
// íàçàä) — íå æäàòü, ïîêà äîãîíÿò.
|
||||
$claimed = $this->database->execute(
|
||||
'INSERT INTO `' . $table . '` (`id`, `logged_at`, `skipped`) VALUES (' . self::ROW_ID . ', ?, 0)'
|
||||
. ' ON DUPLICATE KEY UPDATE `logged_at` = IF(`logged_at` <= ? OR `logged_at` > ?, ?, `logged_at`)',
|
||||
[$now, $now - $interval, $now, $now],
|
||||
);
|
||||
if ($claimed === 0) {
|
||||
$this->database->execute('UPDATE `' . $table . '` SET `skipped` = `skipped` + 1');
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
$skipped = (int) $this->database->fetchValue('SELECT `skipped` FROM `' . $table . '` LIMIT 1');
|
||||
if ($skipped > 0) {
|
||||
$this->database->execute(
|
||||
'UPDATE `' . $table . '` SET `skipped` = GREATEST(`skipped` - ?, 0)',
|
||||
[$skipped],
|
||||
);
|
||||
}
|
||||
|
||||
return $skipped;
|
||||
}
|
||||
|
||||
public static function table(): string
|
||||
{
|
||||
$table = $GLOBALS['SysValue']['base'][ModuleInfo::PATH]['moneta_log_throttle'] ?? null;
|
||||
// ßâíûé êëàññ, à íå \w: â cp1251-ëîêàëè PHPShop \w ïðîïóñòèë áû êèðèëëèöó (êàê â OperationRepository).
|
||||
if (!is_string($table) || preg_match('/\A[0-9A-Za-z_]+\z/', $table) !== 1) {
|
||||
throw new RuntimeException('Íåò òàáëèöû ñ÷¸ò÷èêà æóðíàëà â êîíôèãóðàöèè ìîäóëÿ.');
|
||||
}
|
||||
|
||||
return $table;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user