<?php namespace QUI\ERP\Coupons; use QUI; use QUI\Utils\Grid; use QUI\Utils\Security\Orthos; /** * Class Handler * * Main CouponCode Code handler */ class Handler { /** * Permissions */ const PERMISSION_VIEW = 'quiqqer.couponcode.view'; const PERMISSION_CREATE = 'quiqqer.couponcode.create'; const PERMISSION_DELETE = 'quiqqer.couponcode.delete'; /** * CouponCode runtime cache * * @var CouponCode[] */ protected static $couponCodes = []; /** * Get CouponCode * * @param int $id * @return CouponCode * @throws CouponCodeException */ public static function getCouponCode($id) { if (isset(self::$couponCodes[$id])) { return self::$couponCodes[$id]; } self::$couponCodes[$id] = new CouponCode($id); return self::$couponCodes[$id]; } /** * Get CouponCode by its actual code * * @param string $code * @return CouponCode * * @throws CouponCodeException */ public static function getCouponCodeByCode($code) { $result = QUI::getDataBase()->fetch([ 'select' => [ 'id' ], 'from' => self::getTable(), 'where' => [ 'code' => $code ], 'limit' => 1 ]); if (empty($result)) { throw new CouponCodeException([ 'quiqqer/invitecode', 'exception.Handler.code_not_found', [ 'code' => $code ] ], 404); } return self::getCouponCode($result[0]['id']); } /** * Create new CouponCode * * @param array $data * @return CouponCode * * @throws \Exception */ public static function createCouponCode($data) { $Now = new \DateTime(); if (!empty($data['code'])) { if (self::existsCode($data['code'])) { throw new CouponCodeException([ 'quiqqer/coupons', 'exception.Handler.code_already_exists', [ 'code' => $data['code'] ] ]); } $code = $data['code']; } else { $code = CodeGenerator::generate(); } $couponCode = [ 'title' => empty($data['title']) ? '' : $data['title'], 'createDate' => $Now->format('Y-m-d H:i:s'), 'code' => $code, 'isReusable' => !empty($data['reusable']) ]; if (!empty($data['validUntil'])) { $ValidUntil = new \DateTime($data['validUntil']); $couponCode['validUntilDate'] = $ValidUntil->format('Y-m-d H:i:s'); } if (!empty($data['userIds'])) { $couponCode['userIds'] = json_encode($data['userIds']); } if (!empty($data['groupIds'])) { $couponCode['groupIds'] = json_encode($data['groupIds']); } QUI::getDataBase()->insert( self::getTable(), $couponCode ); return self::getCouponCode(QUI::getPDO()->lastInsertId()); } /** * Search CouponCodes * * @param array $searchParams * @param bool $countOnly (optional) - get result count only [default: false] * @return CouponCode[]|int * @throws CouponCodeException */ public static function search($searchParams, $countOnly = false) { $couponCodes = []; $Grid = new Grid($searchParams); $gridParams = $Grid->parseDBParams($searchParams); $binds = []; $where = []; if ($countOnly) { $sql = "SELECT COUNT(*)"; } else { $sql = "SELECT id"; } $sql .= " FROM `".self::getTable()."`"; if (!empty($searchParams['search'])) { $searchColumns = [ 'id', 'code', 'email' ]; $whereOr = []; foreach ($searchColumns as $searchColumn) { $whereOr[] = '`'.$searchColumn.'` LIKE :search'; } if (!empty($whereOr)) { $where[] = '('.implode(' OR ', $whereOr).')'; $binds['search'] = [ 'value' => '%'.$searchParams['search'].'%', 'type' => \PDO::PARAM_STR ]; } } // build WHERE query string if (!empty($where)) { $sql .= " WHERE ".implode(" AND ", $where); } // ORDER if (!empty($searchParams['sortOn']) ) { $sortOn = Orthos::clear($searchParams['sortOn']); $order = "ORDER BY ".$sortOn; if (isset($searchParams['sortBy']) && !empty($searchParams['sortBy']) ) { $order .= " ".Orthos::clear($searchParams['sortBy']); } else { $order .= " ASC"; } $sql .= " ".$order; } else { $sql .= " ORDER BY id DESC"; } // LIMIT if (!empty($gridParams['limit']) && !$countOnly ) { $sql .= " LIMIT ".$gridParams['limit']; } else { if (!$countOnly) { $sql .= " LIMIT ".(int)20; } } $Stmt = QUI::getPDO()->prepare($sql); // bind search values foreach ($binds as $var => $bind) { $Stmt->bindValue(':'.$var, $bind['value'], $bind['type']); } try { $Stmt->execute(); $result = $Stmt->fetchAll(\PDO::FETCH_ASSOC); } catch (\Exception $Exception) { QUI\System\Log::addError( self::class.' :: search() -> '.$Exception->getMessage() ); return []; } if ($countOnly) { return (int)current(current($result)); } foreach ($result as $row) { $couponCodes[] = self::getCouponCode($row['id']); } return $couponCodes; } /** * Check if an invite code already eixsts * * @param string $code * @return bool */ public static function existsCode($code) { $result = QUI::getDataBase()->fetch([ 'select' => 'id', 'from' => self::getTable(), 'where' => [ 'code' => $code ], 'limit' => 1 ]); return !empty($result); } /** * Get Registration site * * @return QUI\Projects\Site|false */ public static function getRegistrationSite() { $Conf = QUI::getPackage('quiqqer/invitecode')->getConfig(); $regSite = $Conf->get('settings', 'registrationSite'); if (empty($regSite)) { return false; } try { return QUI\Projects\Site\Utils::getSiteByLink($regSite); } catch (\Exception $Exception) { return false; } } /** * Deletes all CouponCodes that are expired * * @param int $days (optional) - Delete expired Codes that are older than X days [default: delete all] * @return void * * @throws \Exception */ public static function deleteExpiredCouponCodes($days = null) { $Now = new \DateTime(); $where = [ 'validUntilDate' => [ 'type' => '<=', 'value' => $Now->format('Y-m-d H:i:s') ] ]; if (!is_null($days)) { $days = (int)$days; $OldDate = new \DateTime(); $OldDate->sub(new \DateInterval('P'.$days.'D')); $where['validUntilDate'] = [ 'type' => '<=', 'value' => $OldDate->format('Y-m-d H:i:s') ]; } QUI::getDataBase()->delete( self::getTable(), $where ); } /** * Deletes all CouponCodes that have been redeemed * * @param int $days (optional) - Delete redeemed Codes that are older than X days [default: delete all] * @return void * * @throws \Exception */ public static function deleteRedeemedCouponCodes($days = null) { $where = [ 'useDate' => [ 'type' => 'NOT', 'value' => null ] ]; if (!is_null($days)) { $days = (int)$days; $OldDate = new \DateTime(); $OldDate->sub(new \DateInterval('P'.$days.'D')); $where['useDate'] = [ 'type' => '<=', 'value' => $OldDate->format('Y-m-d H:i:s') ]; } QUI::getDataBase()->delete( self::getTable(), $where ); } /** * Get CouponCode table * * @return string */ public static function getTable() { return QUI::getDBTableName('quiqqer_coupons'); } }