Newer
Older
use DateInterval;
use DateTime;
use Exception;
use PDO;
use QUI\ERP\Discount\Handler as DiscountHandler;
use function current;
use function explode;
use function implode;
use function is_null;
use function json_encode;
use function preg_replace;
/**
* Class Handler
*
* Main CouponCode Code handler
*/
class Handler
{
/**
* Permissions
*/
const PERMISSION_VIEW = 'quiqqer.couponcode.view';
const PERMISSION_EDIT = 'quiqqer.couponcode.edit';
/**
* Valur for `maxUsage`
*/
const MAX_USAGE_ONCE_PER_USER = 'oncePerUser';
const MAX_USAGE_ONCE = 'once';
const MAX_USAGE_UNLIMITED = 'unlimited';
public static function getCouponCode(int $id): CouponCode
if (isset(self::$couponCodes[$id])) {
return self::$couponCodes[$id];
public static function getCouponCodeByCode(string $code): CouponCode
* @param array $discountIds - IDs of the discounts that are linked to this CouponCode
* @param array $settings (optional) - If omitted a random default CouponCode is generated
public static function createCouponCode(array $discountIds, array $settings = []): CouponCode
$DiscountHandler = DiscountHandler::getInstance();
if (empty($discountIds)) {
throw new CouponCodeException([
'quiqqer/coupons',
'exception.Handler.no_discounts_linked'
]);
}
// check if all given discounts exist
foreach ($discountIds as $discountId) {
try {
$DiscountHandler->getChild($discountId);
throw new CouponCodeException([
'quiqqer/coupons',
'exception.Handler.discount_error',
[
'discountId' => $discountId,
if (!empty($settings['code'])) {
if (self::existsCode($settings['code'])) {
throw new CouponCodeException([
'quiqqer/coupons',
'exception.Handler.code_already_exists',
[
if (empty($settings['maxUsages'])) {
$maxUsages = self::MAX_USAGE_ONCE_PER_USER;
} else {
$maxUsages = $settings['maxUsages'];
}
'title' => empty($settings['title']) ? null : $settings['title'],
'createDate' => $Now->format('Y-m-d H:i:s'),
'code' => $code,
'maxUsages' => $maxUsages,
'discountIds' => json_encode($discountIds)
$ValidUntil = new DateTime($settings['validUntilDate']);
$couponCode['validUntilDate'] = $ValidUntil->format('Y-m-d H:i:s');
$couponCode['userIds'] = json_encode(explode(",", $settings['userIds']));
$couponCode['groupIds'] = json_encode(explode(",", $settings['groupIds']));
try {
QUI::getDataBase()->insert(
self::getTable(),
$couponCode
);
} catch (QUI\Database\Exception $e) {
throw new CouponCodeException([
$e->getMessage(),
$e->getCode()
]);
}
return self::getCouponCode((int)QUI::getPDO()->lastInsertId());
/**
* Edit a CouponCode
*
* @param int $id - CouponCode ID
* @param array $discountIds - IDs of the discounts that are linked to this CouponCode
* @param array $settings (optional) - If omitted a random default CouponCode is generated
* @return CouponCode
*
public static function editCouponCode(int $id, array $discountIds, array $settings = []): CouponCode
{
QUI\Permissions\Permission::checkPermission(self::PERMISSION_EDIT);
// check if CouponCode exists
$CouponCode = self::getCouponCode($id);
// Check settings
$DiscountHandler = DiscountHandler::getInstance();
if (empty($discountIds)) {
throw new CouponCodeException([
'quiqqer/coupons',
'exception.Handler.no_discounts_linked'
]);
}
// check if all given discounts exist
foreach ($discountIds as $discountId) {
try {
$DiscountHandler->getChild($discountId);
throw new CouponCodeException([
'quiqqer/coupons',
'exception.Handler.discount_error',
[
'discountId' => $discountId,
if (
$CouponCode->getCode() !== $settings['code']
&& self::existsCode($settings['code'])
) {
throw new CouponCodeException([
'quiqqer/coupons',
'exception.Handler.code_already_exists',
[
'code' => $settings['code']
]
]);
}
} else {
$code = CodeGenerator::generate();
}
if (empty($settings['maxUsages'])) {
$maxUsages = self::MAX_USAGE_ONCE_PER_USER;
} else {
$maxUsages = $settings['maxUsages'];
}
'title' => empty($settings['title']) ? null : $settings['title'],
'createDate' => $Now->format('Y-m-d H:i:s'),
'code' => $code,
'maxUsages' => $maxUsages,
'discountIds' => json_encode($discountIds)
];
if (!empty($settings['validUntilDate'])) {
$ValidUntil = new DateTime($settings['validUntilDate']);
$couponCode['validUntilDate'] = $ValidUntil->format('Y-m-d H:i:s');
} else {
$couponCode['validUntilDate'] = null;
}
if (!empty($settings['userIds'])) {
$couponCode['userIds'] = json_encode(explode(",", $settings['userIds']));
} else {
$couponCode['userIds'] = null;
}
if (!empty($settings['groupIds'])) {
$couponCode['groupIds'] = json_encode(explode(",", $settings['groupIds']));
} else {
$couponCode['groupIds'] = null;
}
QUI::getDataBase()->update(
self::getTable(),
$couponCode,
);
return self::getCouponCode($id);
}
*
* @param array $searchParams
* @param bool $countOnly (optional) - get result count only [default: false]
* @throws CouponCodeException|QUI\Exception
public static function search(array $searchParams, bool $countOnly = false): array | int
$Grid = new Grid($searchParams);
$gridParams = $Grid->parseDBParams($searchParams);
if ($countOnly) {
$sql = "SELECT COUNT(*)";
} else {
$sql = "SELECT id";
}
$sql .= " FROM `" . self::getTable() . "`";
$whereOr[] = '`' . $searchColumn . '` LIKE :search';
$binds['search'] = [
'value' => '%' . $searchParams['search'] . '%',
'type' => PDO::PARAM_STR
];
}
// build WHERE query string
if (!empty($where)) {
$sql .= " WHERE " . implode(" AND ", $where);
if (!empty($searchParams['sortBy'])) {
$order .= " " . Orthos::clear($searchParams['sortBy']);
} else {
$sql .= " ORDER BY id DESC";
}
// LIMIT
if (!empty($gridParams['limit']) && !$countOnly) {
}
}
$Stmt = QUI::getPDO()->prepare($sql);
// bind search values
foreach ($binds as $var => $bind) {
$Stmt->bindValue(':' . $var, $bind['value'], $bind['type']);
$result = $Stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (Exception $Exception) {
self::class . ' :: search() -> ' . $Exception->getMessage()
* @param string $code The code of the CouponCode
* @return bool Returns true if the CouponCode exists, false otherwise
*
* @throws QUI\Database\Exception
public static function existsCode(string $code): bool
'from' => self::getTable(),
'where' => [
return !empty($result);
}
/**
* Get Registration site
*
* @return QUI\Projects\Site|false
*/
public static function getRegistrationSite(): bool | QUI\Projects\Site
$Conf = QUI::getPackage('quiqqer/coupons')->getConfig();
$regSite = $Conf->get('settings', 'registrationSite');
} catch (QUI\Exception $Exception) {
QUI\System\Log::writeDebugException($Exception);
return false;
}
if (empty($regSite)) {
return false;
}
try {
return QUI\Projects\Site\Utils::getSiteByLink($regSite);
} catch (Exception) {
* @param int|null $days (optional) - Delete expired Codes that are older than X days [default: delete all]
public static function deleteExpiredCouponCodes(null | int $days = null): void
if (!is_null($days)) {
$OldDate = new DateTime();
$OldDate->sub(new DateInterval('P' . $days . 'D'));
}
QUI::getDataBase()->delete(
self::getTable(),
$where
);
}
/**
* @param int|null $days (optional) - Delete redeemed Codes that are older than X days [default: delete all]
public static function deleteRedeemedCouponCodes(null | int $days = null): void
if (!is_null($days)) {
$OldDate = new DateTime();
$OldDate->sub(new DateInterval('P' . $days . 'D'));
}
QUI::getDataBase()->delete(
self::getTable(),
$where
);
}
/**
* Sanitize coupon code and allow only certain characters
*
* @param string $code
* @return string
*/
public static function sanitizeCode(string $code): string
return preg_replace('#[^A-Za-z0-9\.\-_\*&$% ]#i', '', $code);