first commit
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace KupShop\AgeVerifyBundle\Admin\Tabs;
|
||||
|
||||
use KupShop\AdminBundle\Admin\WindowTab;
|
||||
|
||||
class AgeVerifySettingsTab extends WindowTab
|
||||
{
|
||||
protected $title = 'flapAgeVerify';
|
||||
|
||||
protected $template = 'AgeVerifySettingsTab.tpl';
|
||||
|
||||
public static function getTypes()
|
||||
{
|
||||
return [
|
||||
'settings' => 1,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getLabel()
|
||||
{
|
||||
return translate($this->title, 'ageVerifyUsersTab');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace KupShop\AgeVerifyBundle\Admin\Tabs;
|
||||
|
||||
use KupShop\AdminBundle\Admin\WindowTab;
|
||||
use KupShop\AgeVerifyBundle\Utils\AgeVerifyUtil;
|
||||
use Query\Operator;
|
||||
|
||||
class AgeVerifyUsersTab extends WindowTab
|
||||
{
|
||||
protected $title = 'flapAgeVerify';
|
||||
|
||||
protected $template = 'AgeVerifyUsersTab.tpl';
|
||||
|
||||
/** @required */
|
||||
public AgeVerifyUtil $ageVerifyUtil;
|
||||
|
||||
public static function getTypes()
|
||||
{
|
||||
return [
|
||||
'users' => 1,
|
||||
];
|
||||
}
|
||||
|
||||
public function handleUpdate()
|
||||
{
|
||||
parent::handleUpdate();
|
||||
|
||||
$data = getVal('age_verification');
|
||||
|
||||
$this->ageVerifyUtil->setVerificationData($data['legal_age'],
|
||||
$data['verification_type'],
|
||||
null,
|
||||
$this->getID());
|
||||
|
||||
// Smazat OAUTH vazbu, když ruším ověření
|
||||
if ($data['verification_type'] === '' && findModule(\Modules::USER_OAUTH)) {
|
||||
sqlQueryBuilder()->delete('users_provider_ids')
|
||||
->where(Operator::equals(['id_user' => $this->getID(), 'provider' => 'bankid']))
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
|
||||
public function handleRemoveVerificationOrder()
|
||||
{
|
||||
sqlQueryBuilder()->update('users_age_verification')
|
||||
->directValues(['id_order' => null])
|
||||
->where(Operator::equals(['id_user' => $this->getID()]))
|
||||
->execute();
|
||||
|
||||
$this->returnOK('Objednávka odpárována.');
|
||||
}
|
||||
|
||||
public function getVars($smarty_tpl_vars)
|
||||
{
|
||||
$vars = parent::getVars($smarty_tpl_vars);
|
||||
|
||||
$vars['verification_types'] = array_merge([null => '----'], AgeVerifyUtil::$VERIFICATION_TYPES);
|
||||
$vars['age_verification'] = $this->selectSQL('users_age_verification', ['id_user' => $this->getID()])->fetchAssociative();
|
||||
|
||||
if (findModule(\Modules::USER_OAUTH)) {
|
||||
$vars['oauth'] = $this->selectSQL('users_provider_ids', ['id_user' => $this->getID(), 'provider' => 'bankid'])->fetchAssociative();
|
||||
}
|
||||
|
||||
return $vars;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getLabel()
|
||||
{
|
||||
return translate($this->title, 'ageVerifyUsersTab');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace KupShop\AgeVerifyBundle\Admin\Tabs;
|
||||
|
||||
class PosAgeVerifyUsersTab extends AgeVerifyUsersTab
|
||||
{
|
||||
protected $title = 'flapAgeVerify';
|
||||
|
||||
public static function getTypes(): array
|
||||
{
|
||||
return [
|
||||
'PosUsers' => 1];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getLabel()
|
||||
{
|
||||
return translate($this->title, 'ageVerifyUsersTab');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
$txt_str['ageVerifySettingsTab'] = [
|
||||
'flapAgeVerify' => 'Ověření plnoletosti',
|
||||
'enabled' => 'Aktivovat omezení objednávek',
|
||||
'clientId' => 'Client ID',
|
||||
'clientSecret' => 'Client Secret',
|
||||
'ageVerifySettings' => 'Nastavení ověření věku',
|
||||
'bankIdSettings' => 'Nastavení Bankovní identity',
|
||||
'bank_id_enabled' => 'Aktivovat bankovní identitu',
|
||||
'bank_id_sandbox' => 'Použít dev server',
|
||||
'packageSettings' => 'Nastavení ověření zásilky',
|
||||
'product' => 'Produkt',
|
||||
'package_enabled' => 'Aktivovat ověření zásilkou',
|
||||
'verifaceSettings' => 'Nastavení VeriFace',
|
||||
'veriface_enabled' => 'Aktivovat VeriFace',
|
||||
'adultoSettings' => 'Nastavení Adulto',
|
||||
'adulto_enabled' => 'Aktivovat Adulto',
|
||||
'api_key' => 'API klíč',
|
||||
'private_key' => 'Privátní klíč',
|
||||
'public_key' => 'Veřejný klíč',
|
||||
];
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
$txt_str['ageVerifyUsersTab'] = [
|
||||
'flapAgeVerify' => 'Ověření plnoletosti',
|
||||
'birthdate' => 'Datum narození',
|
||||
'legalAge' => 'Plnoletý',
|
||||
'legalAgeUpdated' => 'Aktualizace',
|
||||
'verificationType' => 'Zdroj ověření',
|
||||
];
|
||||
@@ -0,0 +1,108 @@
|
||||
<div id="flapAgeVerify" class="tab-pane fade in boxFlex">
|
||||
<div class="row bottom-space">
|
||||
<div class="col-md-12">
|
||||
<h1 class="h4 main-panel-title">{'ageVerifySettings'|translate:"ageVerifySettingsTab"}</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-md-2 control-label">
|
||||
<label>{'enabled'|translate:"ageVerifySettingsTab"}</label>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
{print_toggle name="age_verify][enabled" value={$body.data.age_verify.enabled}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{* Zásilka *}
|
||||
|
||||
<div class="row bottom-space">
|
||||
<div class="col-md-12">
|
||||
<h1 class="h4 main-panel-title">{'packageSettings'|translate:"ageVerifySettingsTab"}</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-md-2 control-label">
|
||||
<label>{'package_enabled'|translate:"ageVerifySettingsTab"}</label>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
{print_toggle name="age_verify][package][enabled" value={$body.data.age_verify.package.enabled} numeric = 1}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-md-2 control-label">
|
||||
<label>{'product'|translate:"ageVerifySettingsTab"}</label>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<select class="selecter" name="data[age_verify][package][product]"
|
||||
data-type="products" data-preload="products" data-autocomplete="Products">
|
||||
{if $body.data.age_verify.package.product}
|
||||
<option selected value="{$body.data.age_verify.package.product}">{$body.data.age_verify.package.product}</option>
|
||||
{/if}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{* VeriFace *}
|
||||
|
||||
<div class="row bottom-space">
|
||||
<div class="col-md-12">
|
||||
<h1 class="h4 main-panel-title">{'verifaceSettings'|translate:"ageVerifySettingsTab"}</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-md-2 control-label">
|
||||
<label>{'veriface_enabled'|translate:"ageVerifySettingsTab"}</label>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
{print_toggle name="age_verify][veriface][enabled" value={$body.data.age_verify.veriface.enabled} numeric = 1}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-md-2 control-label">
|
||||
<label>{'api_key'|translate:"ageVerifySettingsTab"}</label>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<input type="text" class="form-control input-sm" name="data[age_verify][veriface][api_key]"
|
||||
value="{$body.data.age_verify.veriface.api_key}">
|
||||
</div>
|
||||
</div>
|
||||
{* Adulto *}
|
||||
|
||||
{block "adulto"}
|
||||
<div class="row bottom-space">
|
||||
<div class="col-md-12">
|
||||
<h1 class="h4 main-panel-title">{'adultoSettings'|translate:"ageVerifySettingsTab"}</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-md-2 control-label">
|
||||
<label>{'adulto_enabled'|translate:"ageVerifySettingsTab"}</label>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
{print_toggle name="age_verify][adulto][enabled" value={$body.data.age_verify.adulto.enabled} numeric = 1}
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-md-2 control-label">
|
||||
<label>{'private_key'|translate:"ageVerifySettingsTab"}</label>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<input type="text" class="form-control input-sm" name="data[age_verify][adulto][private_key]"
|
||||
value="{$body.data.age_verify.adulto.private_key}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-md-2 control-label">
|
||||
<label>{'public_key'|translate:"ageVerifySettingsTab"}</label>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<input type="text" class="form-control input-sm" name="data[age_verify][adulto][public_key]"
|
||||
value="{$body.data.age_verify.adulto.public_key}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,46 @@
|
||||
<div id="flapAgeVerify" class="tab-pane fade in boxFlex">
|
||||
<legend>{'flapAgeVerify'|translate: "ageVerifyUsersTab"}</legend>
|
||||
<div class="form-group">
|
||||
<div class="col-md-2 control-label">
|
||||
<label>{'legalAge'|translate: "ageVerifyUsersTab"}</label>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
{print_select name="age_verification[legal_age]" var=[0 => '','N' => 'Ne','Y' => 'Ano'] selected=$tab.data.age_verification.legal_age}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-md-2 control-label">
|
||||
<label>{'legalAgeUpdated'|translate: "ageVerifyUsersTab"}</label>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<input type="text" class="form-control input-sm" value="{$tab.data.age_verification.date_updated|format_datetime:"admin"}" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-md-2 control-label">
|
||||
<label>{'verificationType'|translate: "ageVerifyUsersTab"}</label>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
{print_select name="age_verification[verification_type]" var=$tab.data.verification_types selected=$tab.data.age_verification.verification_type}
|
||||
</div>
|
||||
</div>
|
||||
{if $tab.data.age_verification.id_order}
|
||||
<div class="form-group">
|
||||
<div class="col-md-4 control-label">
|
||||
<label>Uživatel již vytvořil ověřovací <a href="javascript:nw('orders', {$tab.data.age_verification.id_order})">objednávku.</a></label>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<button type="submit" class="btn btn-danger" name="acn" value="removeVerificationOrder">Odpárovat objednávku</button>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{if $tab.data.oauth}
|
||||
<div class="form-group">
|
||||
<div class="col-md-5 control-label">
|
||||
<label>Uživatel má propojený účet na Bankovní identitu.</label>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
9
bundles/KupShop/AgeVerifyBundle/AgeVerifyBundle.php
Normal file
9
bundles/KupShop/AgeVerifyBundle/AgeVerifyBundle.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace KupShop\AgeVerifyBundle;
|
||||
|
||||
class AgeVerifyBundle extends \Symfony\Component\HttpKernel\Bundle\Bundle
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace KupShop\AgeVerifyBundle\Controller;
|
||||
|
||||
use KupShop\AgeVerifyBundle\Utils\AgeVerifyUtil;
|
||||
use KupShop\AgeVerifyBundle\Utils\BankIdUtil;
|
||||
use KupShop\AgeVerifyBundle\Utils\VerifaceUtil;
|
||||
use KupShop\AgeVerifyBundle\View\AdultoView;
|
||||
use KupShop\AgeVerifyBundle\View\AgeVerifyView;
|
||||
use KupShop\AgeVerifyBundle\View\PackageOrderView;
|
||||
use KupShop\KupShopBundle\Context\UserContext;
|
||||
use KupShop\KupShopBundle\Exception\RedirectException;
|
||||
use KupShop\KupShopBundle\Routing\TranslatedRoute;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Contracts\Service\Attribute\Required;
|
||||
|
||||
class AgeVerifyController extends \Symfony\Bundle\FrameworkBundle\Controller\AbstractController
|
||||
{
|
||||
#[Required]
|
||||
public BankIdUtil $bankIdUtil;
|
||||
|
||||
#[Required]
|
||||
public UserContext $userContext;
|
||||
|
||||
#[Required]
|
||||
public AgeVerifyUtil $ageVerifyUtil;
|
||||
|
||||
#[TranslatedRoute(path: '/#account#/#age_verify_url:AgeVerify#', name: 'ageVerify')]
|
||||
public function ageVerifyAction(AgeVerifyView $view)
|
||||
{
|
||||
return $view->getResponse();
|
||||
}
|
||||
|
||||
#[TranslatedRoute(path: '/#account#/#age_verify_url:AgeVerify#/#bank_id_url:AgeVerify#', name: 'ageVerifyBankId')]
|
||||
public function bankIdAction(Request $request)
|
||||
{
|
||||
$url = $this->bankIdUtil->getRedirectUrl();
|
||||
|
||||
return new RedirectResponse($url);
|
||||
}
|
||||
|
||||
#[TranslatedRoute(path: '/#account#/#age_verify_url:AgeVerify#/#package_url:AgeVerify#', name: 'ageVerifyPackage')]
|
||||
public function packageOrderAction(Request $request, PackageOrderView $view)
|
||||
{
|
||||
$userId = $this->userContext->getActiveId();
|
||||
|
||||
if ($this->ageVerifyUtil->isLegalAged($userId)) {
|
||||
throw new RedirectException(path('ageVerify'));
|
||||
}
|
||||
|
||||
if ($request->isMethod('POST')) {
|
||||
if ($order = $view->submitForm()) {
|
||||
return new RedirectResponse(path('kupshop_content_orders_order',
|
||||
['id' => $order->id, 'cf' => $order->getSecurityCode(), 'status' => 1]));
|
||||
}
|
||||
}
|
||||
|
||||
return $view->getResponse();
|
||||
}
|
||||
|
||||
#[TranslatedRoute(path: '/#account#/#age_verify_url:AgeVerify#/#adulto_url:AgeVerify#', name: 'ageVerifyAdulto')]
|
||||
public function adultoOrderAction(Request $request, AdultoView $view): Response
|
||||
{
|
||||
$userId = $this->userContext->getActiveId();
|
||||
|
||||
if ($this->ageVerifyUtil->isLegalAged($userId)) {
|
||||
throw new RedirectException(path('ageVerify'));
|
||||
}
|
||||
|
||||
if ($request->isMethod('POST')) {
|
||||
if ($errorMsg = $view->submitForm()['error'] ?? null) {
|
||||
addUserMessage($errorMsg);
|
||||
}
|
||||
|
||||
return new RedirectResponse(path('ageVerify'));
|
||||
}
|
||||
|
||||
return $view->getResponse();
|
||||
}
|
||||
|
||||
#[Route('/_bankid')]
|
||||
public function webhookBankIdAction(Request $request)
|
||||
{
|
||||
$code = $request->get('code');
|
||||
$this->bankIdUtil->fetchData($code);
|
||||
|
||||
return new RedirectResponse(path('ageVerify'));
|
||||
}
|
||||
|
||||
#[TranslatedRoute(path: '/#age_verify_url:AgeVerify#/#veriface_url:AgeVerify#', name: 'ageVerifyVeriface')]
|
||||
public function verifaceAction(VerifaceUtil $verifaceUtil, SessionInterface $session, Request $request)
|
||||
{
|
||||
if ($request->get('source') == 'cart') {
|
||||
$session->set('redirectToCart', $request->headers->get('referer'));
|
||||
}
|
||||
|
||||
return new RedirectResponse($verifaceUtil->getRedirectUrl());
|
||||
}
|
||||
|
||||
#[Route('/_veriface')]
|
||||
public function webhookVerifaceAction(VerifaceUtil $verifaceUtil, Request $request, SessionInterface $session)
|
||||
{
|
||||
$verifaceUtil->saveData($request->get('sessionId'));
|
||||
|
||||
if ($redirect = $session->remove('redirectToCart')) {
|
||||
return new RedirectResponse($redirect);
|
||||
}
|
||||
|
||||
return new RedirectResponse(path('ageVerify'));
|
||||
}
|
||||
|
||||
#[Route('/_veriface_notification', methods: ['POST'])]
|
||||
public function verifaceNotificationAction(VerifaceUtil $verifaceUtil, Request $request)
|
||||
{
|
||||
$data = json_decode($request->getContent() ?? '', true);
|
||||
$sessionId = $data['sessionId'];
|
||||
$email = $data['referenceId'];
|
||||
|
||||
// Řeším jen v případě, kdy je status konečný - https://docs.veriface.eu/sk/docs/verification-statuses
|
||||
if (in_array($data['status'], ['VERIFIED', 'REFUSED', 'VERIFIED_WARNING', 'CANCELLED', 'VERIFIED_MANUAL', 'REFUSED_MANUAL', 'EXPIRED', 'ERROR'])) {
|
||||
$verifaceUtil->saveData($sessionId, \User::createFromLogin($email));
|
||||
}
|
||||
|
||||
return new Response('OK');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace KupShop\AgeVerifyBundle\EventSubscribers;
|
||||
|
||||
use KupShop\AgeVerifyBundle\Utils\AdultoUtil;
|
||||
use KupShop\KupShopBundle\Context\UserContext;
|
||||
use KupShop\OrderingBundle\Event\CartEvent;
|
||||
use KupShop\OrderingBundle\Exception\CartValidationException;
|
||||
use Query\Operator;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Contracts\Service\Attribute\Required;
|
||||
|
||||
class CartSubscriber implements \Symfony\Component\EventDispatcher\EventSubscriberInterface
|
||||
{
|
||||
#[Required]
|
||||
public UserContext $userContext;
|
||||
#[Required]
|
||||
public AdultoUtil $adultoUtil;
|
||||
|
||||
#[Required]
|
||||
public RequestStack $requestStack;
|
||||
|
||||
protected int $lastStepIndex = 2;
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return [
|
||||
CartEvent::CHECK_CART_ITEMS => [
|
||||
['checkLegalAge', 200],
|
||||
],
|
||||
CartEvent::CHECK_CART => [
|
||||
['checkCartLegalAge', 200],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function checkCartLegalAge(CartEvent $event)
|
||||
{
|
||||
$cfg = \Settings::getDefault();
|
||||
if (($cfg['age_verify']['enabled'] ?? 'N') == 'N') {
|
||||
return;
|
||||
}
|
||||
$cart = $event->getCart();
|
||||
|
||||
if ($cart->getActualStepIndex() != $this->lastStepIndex) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($cart->getData('age_verification')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$mainRequest = $this->requestStack->getMainRequest();
|
||||
|
||||
if (!empty($cfg['age_verify']['adulto']['enabled'])) {
|
||||
$result = $this->adultoUtil->checkAdultoUid($mainRequest->get('adultocz-uid') ?? '');
|
||||
if (!$result['success']) {
|
||||
throw new CartValidationException(translate('registered_with_legal_age', 'AgeVerify'));
|
||||
} else {
|
||||
$cart->setData('age_verification', $result['data']);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$this->checkAgeRegisteredUser($cart);
|
||||
}
|
||||
|
||||
public function checkLegalAge(CartEvent $event)
|
||||
{
|
||||
$cfg = \Settings::getDefault();
|
||||
if (($cfg['age_verify']['enabled'] ?? 'N') == 'N') {
|
||||
return;
|
||||
}
|
||||
|
||||
$cart = $event->getCart();
|
||||
|
||||
if ($cart->getActualStepIndex() != $this->lastStepIndex) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($cart->getData('age_verification')) {
|
||||
return;
|
||||
}
|
||||
if (!empty($cfg['age_verify']['adulto']['enabled'])) {
|
||||
return;
|
||||
}
|
||||
$this->checkAgeRegisteredUser($cart);
|
||||
}
|
||||
|
||||
protected function checkAgeRegisteredUser(\Cart $cart): void
|
||||
{
|
||||
$user = $this->userContext->getActive();
|
||||
|
||||
if (!$user) {
|
||||
throw new CartValidationException(translate('registered_with_legal_age', 'AgeVerify'));
|
||||
}
|
||||
|
||||
$legalAge = sqlQueryBuilder()->select('legal_age')->from('users_age_verification')->where(Operator::equals(['id_user' => $user->id]))->execute()->fetchOne();
|
||||
|
||||
if (empty($legalAge)) {
|
||||
throw new CartValidationException(translate('dont_verify', 'AgeVerify'));
|
||||
} elseif ($legalAge == 'N') {
|
||||
throw new CartValidationException(translate('not_legal_age', 'AgeVerify'));
|
||||
}
|
||||
|
||||
if ($deliveryBirthdate = $cart->getData('delivery_birthdate')) {
|
||||
$date = \DateTime::createFromFormat('Y-m-d', $deliveryBirthdate)->add(\DateInterval::createFromDateString('+18YEARS'));
|
||||
if ($date > (new \DateTime())) {
|
||||
throw new CartValidationException(translate('delivery_legal_age', 'AgeVerify'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace KupShop\AgeVerifyBundle\EventSubscribers;
|
||||
|
||||
use KupShop\OrderingBundle\Event\OrderDeliveryEvent;
|
||||
use Query\Operator;
|
||||
|
||||
class OrderEventSubscriber implements \Symfony\Component\EventDispatcher\EventSubscriberInterface
|
||||
{
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return [
|
||||
OrderDeliveryEvent::class => [
|
||||
['updateLegalAge', 200],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function updateLegalAge(OrderDeliveryEvent $event)
|
||||
{
|
||||
$orderId = $event->getOrder()->id;
|
||||
sqlQueryBuilder()->update('users_age_verification')
|
||||
->directValues(['legal_age' => 'Y'])
|
||||
->where(Operator::equals(['id_order' => $orderId]))
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace KupShop\AgeVerifyBundle\Exception;
|
||||
|
||||
class AgeVerificationException extends \Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace KupShop\AgeVerifyBundle\Exception;
|
||||
|
||||
class BankIdException extends \Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace KupShop\AgeVerifyBundle\Exception;
|
||||
|
||||
class VeriFaceException extends \Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
bankid:
|
||||
resource: "@AgeVerifyBundle/Controller"
|
||||
type: annotation
|
||||
@@ -0,0 +1,7 @@
|
||||
services:
|
||||
_defaults:
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
|
||||
KupShop\AgeVerifyBundle\:
|
||||
resource: ../../{Utils,Controller,View,Admin/Tabs,EventSubscribers}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace KupShop\AgeVerifyBundle\Resources\script;
|
||||
|
||||
use KupShop\AdminBundle\Util\Script\Script;
|
||||
use KupShop\AgeVerifyBundle\Utils\VerifaceUtil;
|
||||
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||
|
||||
class VerifaceDebugScript extends Script
|
||||
{
|
||||
protected static $defaultParameters = [
|
||||
'sessionId' => null,
|
||||
'userId' => null,
|
||||
];
|
||||
|
||||
protected function run(array $arguments)
|
||||
{
|
||||
$verifaceUtil = ServiceContainer::getService(VerifaceUtil::class);
|
||||
|
||||
$verifaceUtil->saveData($arguments['sessionId'], \User::createFromId($arguments['userId']));
|
||||
}
|
||||
}
|
||||
|
||||
return VerifaceDebugScript::class;
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
use KupShop\AgeVerifyBundle\Utils\AgeVerifyUtil;
|
||||
use KupShop\KupShopBundle\Context\UserContext;
|
||||
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||
use KupShop\KupShopBundle\Util\Contexts;
|
||||
|
||||
function smarty_function_get_age_verification($params, &$smarty)
|
||||
{
|
||||
$result = [];
|
||||
|
||||
$userId = Contexts::get(UserContext::class)->getActiveId();
|
||||
if ($userId) {
|
||||
$result = ServiceContainer::getService(AgeVerifyUtil::class)->getVerificationData($userId);
|
||||
}
|
||||
|
||||
if (!empty($params['assign'])) {
|
||||
$smarty->assign($params['assign'], $result);
|
||||
} else {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
{extends "index.tpl"}
|
||||
|
||||
{block content}
|
||||
<div class="page-package-verification">
|
||||
{block "page-content"}
|
||||
<div class="form-verification">
|
||||
<form method="post" action="{path('ageVerifyAdulto')}" id="cart">
|
||||
{block "form"}
|
||||
<div class="adulto-cz" data-sitekey="{$body.adulto_public_key}"></div>
|
||||
<input type="hidden" name="customer_age" value="18" data-adultocz="customer_age">
|
||||
<button type="submit" name="Odeslat">Potvrdit ověření</button>
|
||||
{/block}
|
||||
</form>
|
||||
</div>
|
||||
{/block}
|
||||
</div>
|
||||
{/block}
|
||||
|
||||
{block "body" append}
|
||||
<script async src="https://api.js.m2a.cz/api.js"></script>
|
||||
{/block}
|
||||
@@ -0,0 +1,113 @@
|
||||
{extends "account/account-wrapper.tpl"}
|
||||
|
||||
{block "account-content"}
|
||||
<div class="container">
|
||||
{get_age_verification assign="age_verification"}
|
||||
<div class="age-verification-wrapper">
|
||||
<h3 class="text-center">Možnosti ověření</h3>
|
||||
<div class="banners-verification">
|
||||
<div class="verify-wrapper">
|
||||
{$verified = $age_verification.legal_age == 'Y' or $age_verification.id_order != null}
|
||||
{if $ctrl.active_language == "cs"}
|
||||
{if $dbcfg.age_verify.adulto.enabled}
|
||||
<div
|
||||
class="verify-item verify-adulto {if $age_verification.verification_type|in_array:['adulto'] and $age_verification.legal_age == 'Y'}disabled{/if} {if $verified}account_verified{/if}">
|
||||
{if $age_verification.verification_type == 'adulto' and $age_verification.legal_age == 'Y'}
|
||||
<div class="verified">
|
||||
<span class="fc icons_check-outline">{t}Ověřeno{/t}</span>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="image-wrapper">
|
||||
<div class="image">
|
||||
<img src="{static_url url="/templates/images/veriface-bg.png"}" width="436" height="188" loading="lazy"
|
||||
alt="Adulto"
|
||||
class="img-responsive">
|
||||
</div>
|
||||
</div>
|
||||
<div class="text">
|
||||
<div class="descr">
|
||||
<h5>{t}Dokladem totožnosti{/t}</h5>
|
||||
<p>{t}Využijte možnosti ověření službou Adulto.{/t}</p>
|
||||
</div>
|
||||
<a href="{path("ageVerifyAdulto")}" class="btn btn-primary" {if $verified}disabled{/if}>Službou Adulto</a>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{if $dbcfg.oauth.bank_id.enabled}
|
||||
<div
|
||||
class="verify-item verify-bankid {if $age_verification.verification_type|in_array:['mojeid', 'store', 'package', 'veriface'] and $age_verification.legal_age == 'Y'}disabled{/if} {if $verified}account_verified{/if}">
|
||||
{if $age_verification.verification_type == 'bankId' and $age_verification.legal_age == 'Y'}
|
||||
<div class="verified">
|
||||
<span class="fc icons_check-outline">{t}Ověřeno{/t}</span>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="image-wrapper">
|
||||
<div class="image">
|
||||
<img src="{static_url url="/templates/images/bankid-bg.png"}" width="171" height="35" loading="lazy"
|
||||
alt="BankID"
|
||||
class="bankid img-responsive">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text">
|
||||
<div class="descr">
|
||||
<h5>{t}Bankovní identitou{/t}</h5>
|
||||
<p>{t}Využijte možnosti ověření bankovní identitou.{/t}</p>
|
||||
</div>
|
||||
<a href="/login-bind/bankid" class="btn btn-primary" {if $verified}disabled{/if}>BankID</a>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{if $dbcfg.age_verify.veriface.enabled}
|
||||
<div
|
||||
class="verify-item verify-veriface {if $age_verification.verification_type|in_array:['mojeid', 'store', 'package', 'bankId'] and $age_verification.legal_age == 'Y'}disabled{/if} {if $verified}account_verified{/if}">
|
||||
{if $age_verification.verification_type == 'veriface' and $age_verification.legal_age == 'Y'}
|
||||
<div class="verified">
|
||||
<span class="fc icons_check-outline">{t}Ověřeno{/t}</span>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="image-wrapper">
|
||||
<div class="image">
|
||||
<img src="{static_url url="/templates/images/veriface-bg.png"}" width="436" height="188" loading="lazy"
|
||||
alt="Veriface"
|
||||
class="img-responsive">
|
||||
</div>
|
||||
</div>
|
||||
<div class="text">
|
||||
<div class="descr">
|
||||
<h5>{t}Dokladem totožnosti{/t}</h5>
|
||||
<p>{t}Využijte možnosti ověření dokladem totožnosti.{/t}</p>
|
||||
</div>
|
||||
<a href="{path("ageVerifyVeriface")}" class="btn btn-primary" {if $verified}disabled{/if}>Doklad totožnosti</a>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{if $dbcfg.age_verify.package.enabled}
|
||||
<div
|
||||
class="verify-item verify-package {if $age_verification.verification_type|in_array:['mojeid', 'bankId', 'store', 'veriface'] and $age_verification.legal_age == 'Y'}disabled{/if} {if $verified}account_verified{/if}">
|
||||
{if $age_verification.verification_type == 'package' and $age_verification.legal_age == 'Y'}
|
||||
<div class="verified">
|
||||
<span class="fc icons_check-outline">{t}Ověřeno{/t}</span>
|
||||
</div>
|
||||
{/if}
|
||||
<img src="{static_url url="/templates/images/package.png"}" width="436" height="188" loading="lazy"
|
||||
alt="Ověření zásilkou"
|
||||
class="package img-responsive">
|
||||
<div class="text">
|
||||
<div class="descr">
|
||||
<h5>{t}Ověření zásilkou{/t}</h5>
|
||||
<p>Vaši identitu umíme ověřit také zasláním dárkového poukazu na adresu.</p>
|
||||
</div>
|
||||
<a href="{path('ageVerifyPackage')}" class="btn btn-primary" {if $verified}disabled{/if}>Balíkem</a>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="age-verify-text">
|
||||
{insert_page code="verify"}
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
||||
@@ -0,0 +1,100 @@
|
||||
{extends "index.tpl"}
|
||||
|
||||
{block content}
|
||||
<div class="page-package-verification">
|
||||
{block "page-content"}{/block}
|
||||
|
||||
{get_smarty assign='smarty_object'}
|
||||
|
||||
{foreach $body.deliveries as $id => $delivery}
|
||||
{$delivery->getInitTemplate($smarty_object)}
|
||||
{/foreach}
|
||||
|
||||
<div class="form-verification">
|
||||
<form method="post" action="{path('ageVerifyPackage')}" id="cart">
|
||||
{block "form"}
|
||||
<h5>Dorucovaci adresa</h5>
|
||||
Ulice a čp:
|
||||
<input type="text" name="data[street]" value="{$body.user.street}">
|
||||
<br>
|
||||
Mesto:
|
||||
<input type="text" name="data[city]" value="{$body.user.city}">
|
||||
<br>
|
||||
PSC:
|
||||
<input type="text" name="data[zip]" value="{$body.user.zip}">
|
||||
<br>
|
||||
Tel:
|
||||
<input type="text" name="data[phone]" value="{$body.user.phone}">
|
||||
<br>
|
||||
Email:
|
||||
<input type="text" name="data[email]" value="{$body.user.email}">
|
||||
<br>
|
||||
Datum narození:
|
||||
<input type="date" name="data[birthdate]" value="{$body.user.birthdate}">
|
||||
<div data-box="deliveries" class="deliveries-box">
|
||||
{include "ordering/ordering.delivery.deliveries.tpl" deliveries=$view->getDeliveries() availability=1}
|
||||
</div>
|
||||
<div data-box="payments" class="payments-box" data-reload="payments">
|
||||
{if $body.delivery_id}
|
||||
{include "ordering/ordering.delivery.payments.tpl" payments=$view->getPayments()}
|
||||
{/if}
|
||||
</div>
|
||||
<input type="submit" value="Odeslat" name="submitOrder">
|
||||
{/block}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
||||
|
||||
{block "body" append}
|
||||
<script>
|
||||
{literal}
|
||||
function reloadAgeVerifyParts(id_delivery) {
|
||||
let form = $("#cart");
|
||||
const data = form.serializeArray();
|
||||
const parts = $('[data-reload]');
|
||||
|
||||
$.post(window.location.href, data, (data) => {
|
||||
const newHtml = wpj.domUtils.parseHtml(data);
|
||||
wpj.domUtils.crossFadeParts(parts, newHtml);
|
||||
}, 'html');
|
||||
|
||||
$('.delivery_description').hide();
|
||||
const id = '#delivery_description_' + id_delivery
|
||||
$(id).show();
|
||||
}
|
||||
|
||||
wpj.onReady.push(() => {
|
||||
let form = $("#cart");
|
||||
form.find('input:radio').on('change', (e) => {
|
||||
reloadAgeVerifyParts(e.target.value);
|
||||
}
|
||||
);
|
||||
|
||||
form.find('input[type=hidden]').on('change', (e) => {
|
||||
const match = e.target.name.match(/delivery_data\[(\d+)\]\[.*\]/);
|
||||
const id = match ? match[1] : null;
|
||||
reloadAgeVerifyParts(id);
|
||||
});
|
||||
|
||||
form.find('input[name=delivery_id]').on('click', (e) => {
|
||||
const input = $(e.currentTarget)
|
||||
form.trigger("cartdeliverychange", {delivery_id: input.val()})
|
||||
})
|
||||
|
||||
form.on('submit', (e) => {
|
||||
var $checked_delivery_wrapper = form.find('[name="delivery_id"]:checked').closest('[data-cart="item"]');
|
||||
if ($checked_delivery_wrapper.find('[data-delivery-validity_check]').length) {
|
||||
var $invalid = $checked_delivery_wrapper.find('[data-delivery-invalid]');
|
||||
|
||||
if ($invalid.length) {
|
||||
window.alert($invalid.data('delivery-invalid'));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
{/literal}
|
||||
</script>
|
||||
{/block}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace KupShop\AgeVerifyBundle\Resources\upgrade;
|
||||
|
||||
use KupShop\AgeVerifyBundle\Utils\AgeVerifyUtil;
|
||||
|
||||
class AgeVerifyUpgrade extends \UpgradeNew
|
||||
{
|
||||
public function check_userAgeVerification()
|
||||
{
|
||||
return $this->checkTableExists('users_age_verification');
|
||||
}
|
||||
|
||||
/** Create age verification table */
|
||||
public function upgrade_userAgeVerification()
|
||||
{
|
||||
sqlQuery("create table users_age_verification(
|
||||
id_user int(11) unsigned primary key references users(id) on UPDATE cascade on delete CASCADE ,
|
||||
legal_age ENUM('Y', 'N') NOT NULL DEFAULT 'N',
|
||||
date_updated DATETIME ON UPDATE NOW() default NOW(),
|
||||
verification_type ENUM('bankId'));
|
||||
");
|
||||
|
||||
$this->upgradeOK();
|
||||
}
|
||||
|
||||
public function check_verificationSources()
|
||||
{
|
||||
return $this->checkEnumOptions('users_age_verification', 'verification_type', array_keys(AgeVerifyUtil::$VERIFICATION_TYPES));
|
||||
}
|
||||
|
||||
/** Update verification sources ENUM */
|
||||
public function upgrade_verificationSources()
|
||||
{
|
||||
$this->updateEnumOptions('users_age_verification', 'verification_type', array_keys(AgeVerifyUtil::$VERIFICATION_TYPES));
|
||||
|
||||
$this->upgradeOK();
|
||||
}
|
||||
|
||||
public function check_orderIdField()
|
||||
{
|
||||
return $this->checkColumnExists('users_age_verification', 'id_order');
|
||||
}
|
||||
|
||||
/** Create id_order field on age verification */
|
||||
public function upgrade_orderIdField()
|
||||
{
|
||||
sqlQuery('ALTER TABLE users_age_verification ADD COLUMN id_order INT UNSIGNED NULL
|
||||
REFERENCES orders(id) ON UPDATE CASCADE ON DELETE CASCADE;');
|
||||
|
||||
$this->upgradeOK();
|
||||
}
|
||||
|
||||
public function check_ageVerificationData()
|
||||
{
|
||||
return $this->checkColumnExists('users_age_verification', 'data');
|
||||
}
|
||||
|
||||
/** Add data field to users_age_verification */
|
||||
public function upgrade_ageVerificationData()
|
||||
{
|
||||
sqlQuery('ALTER TABLE users_age_verification ADD COLUMN data LONGTEXT NULL');
|
||||
|
||||
$this->upgradeOK();
|
||||
}
|
||||
}
|
||||
74
bundles/KupShop/AgeVerifyBundle/Utils/AdultoUtil.php
Normal file
74
bundles/KupShop/AgeVerifyBundle/Utils/AdultoUtil.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace KupShop\AgeVerifyBundle\Utils;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Psr\Log\LogLevel;
|
||||
use Symfony\Contracts\Service\Attribute\Required;
|
||||
|
||||
class AdultoUtil
|
||||
{
|
||||
private const API_URL = 'https://api.result.adulto.cz';
|
||||
private const REQUIRED_AGE = 18;
|
||||
|
||||
#[Required]
|
||||
public AgeVerifyUtil $ageVerifyUtil;
|
||||
#[Required]
|
||||
public LoggerInterface $logger;
|
||||
|
||||
public function checkAdultoUid(string $adultoUid = ''): array
|
||||
{
|
||||
// na lokálu nechci ověřovat přes Adulto protože na to nemaj žádnej sandbox
|
||||
if (isLocalDevelopment()) {
|
||||
return ['success' => true, 'data' => 'Verification skipped in local development.'];
|
||||
}
|
||||
|
||||
if (empty($adultoUid)) {
|
||||
return ['success' => false, 'message' => 'Váš věk nebyl ověřen.'];
|
||||
}
|
||||
|
||||
$klic = \Settings::getDefault()['age_verify']['adulto']['private_key'] ?? '';
|
||||
|
||||
$api_url = self::API_URL.'/?secret='.$klic.'&response='.$adultoUid;
|
||||
|
||||
// Volání API
|
||||
$response = file_get_contents($api_url);
|
||||
// $response = '{"adultocz-verify-id":"2024378270","adultocz-verify-uid":"454686ff2e5b6df020ccbc9242497aa587201319674d","adultocz-visit-cookie":"1548674d-79a7-4edf-9c48-3b25893c348c-1733484546544","adultocz-visit-time":"2024-12-06 12:29:06","adultocz-verify-time":"2024-12-06 12:32:40","adultocz-verify-method":"bankid","adultocz-verify-status":"true","adultocz-verify-age":"18","adultocz-verify-adult":"true"}';
|
||||
|
||||
$this->logger->log(LogLevel::INFO, $response);
|
||||
|
||||
// Ověření API komunikace
|
||||
if ($response === false) {
|
||||
return ['success' => false, 'message' => 'Chyba při komunikaci s Adulto.'];
|
||||
}
|
||||
|
||||
// JSON odpověď API
|
||||
$adultocz = json_decode($response);
|
||||
|
||||
// Podmínka pro úspěšné ověření
|
||||
if (
|
||||
$adultocz // Existuje JSON odpověď
|
||||
&& isset($adultocz->{'adultocz-verify-adult'})
|
||||
&& $adultocz->{'adultocz-verify-adult'} === 'true'
|
||||
&& isset($adultocz->{'adultocz-verify-age'})
|
||||
&& $adultocz->{'adultocz-verify-age'} == self::REQUIRED_AGE
|
||||
) {
|
||||
$this->ageVerifyUtil->setVerificationData('Y', 'adulto', data: $response);
|
||||
// Smazání cookie pro zapomenutí ověření
|
||||
setcookie('adultocz_local', '', time() - 3600, '/', '', true, true);
|
||||
|
||||
return ['success' => true, 'data' => $adultocz];
|
||||
} elseif ($adultocz
|
||||
&& isset($adultocz->{'adultocz-verify-age'})
|
||||
&& $adultocz->{'adultocz-verify-age'} != self::REQUIRED_AGE
|
||||
) {
|
||||
// Ověřený věk není dostatečný
|
||||
return ['success' => false, 'message' => 'Nemůžeme prodávat osobám mladším '.self::REQUIRED_AGE.' let.'];
|
||||
} else {
|
||||
// Ověřený věk není dostatečný
|
||||
return ['success' => false, 'message' => 'Neplatná odpověď při komunikaci s API.'];
|
||||
}
|
||||
}
|
||||
}
|
||||
98
bundles/KupShop/AgeVerifyBundle/Utils/AgeVerifyUtil.php
Normal file
98
bundles/KupShop/AgeVerifyBundle/Utils/AgeVerifyUtil.php
Normal file
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace KupShop\AgeVerifyBundle\Utils;
|
||||
|
||||
use Doctrine\DBAL\Exception;
|
||||
use KupShop\KupShopBundle\Context\UserContext;
|
||||
use KupShop\KupShopBundle\Views\Traits\MessagesTrait;
|
||||
use Query\Operator;
|
||||
|
||||
class AgeVerifyUtil
|
||||
{
|
||||
use MessagesTrait;
|
||||
|
||||
/** @required */
|
||||
public UserContext $userContext;
|
||||
|
||||
public static array $VERIFICATION_TYPES = [
|
||||
'bankId' => 'Bankovní identita',
|
||||
'store' => 'Prodejna',
|
||||
'package' => 'Balík',
|
||||
'veriface' => 'Veriface',
|
||||
'mojeid' => 'MojeID',
|
||||
'adulto' => 'Adulto',
|
||||
];
|
||||
|
||||
/**
|
||||
* @param $legalAge string Y/N
|
||||
* @param string $type bankId/store/package/veriface/adulto
|
||||
* @param int|null $userId \User
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function setVerificationData(string $legalAge, string $type, ?string $birthdate = null, ?int $userId = null, ?string $data = null): bool
|
||||
{
|
||||
if (empty($userId) && empty($userId = $this->userContext->getActiveId())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!empty($birthdate)) {
|
||||
sqlQueryBuilder()->update('users')
|
||||
->directValues([
|
||||
'birthdate' => $birthdate,
|
||||
'figure' => 'Y',
|
||||
])
|
||||
->where(Operator::equals(['id' => $userId]))
|
||||
->execute();
|
||||
}
|
||||
|
||||
sqlQueryBuilder()->insert('users_age_verification')
|
||||
->directValues([
|
||||
'id_user' => $userId,
|
||||
'legal_age' => $legalAge,
|
||||
'verification_type' => $type,
|
||||
'data' => $data,
|
||||
])
|
||||
->onDuplicateKeyUpdate([
|
||||
'id_user',
|
||||
'legal_age',
|
||||
'verification_type',
|
||||
'data',
|
||||
])
|
||||
->execute();
|
||||
|
||||
if (!isAdministration()) {
|
||||
if ($legalAge == 'Y') {
|
||||
$this->addSuccessMessage('Ověření plnoletosti proběhlo úspěšně.');
|
||||
} else {
|
||||
$this->addErrorMessage('Ověření plnoletosti se nezdařilo.'); // TODO: uživatel není plnoletý??
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isLegalAged($userId): bool
|
||||
{
|
||||
if (empty($userId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$data = sqlQueryBuilder()->select('legal_age')->from('users_age_verification')
|
||||
->where(Operator::equals(['id_user' => $userId]))->execute()->fetchOne();
|
||||
|
||||
return $data == 'Y';
|
||||
}
|
||||
|
||||
public function getVerificationData($userId)
|
||||
{
|
||||
return sqlQueryBuilder()->select('legal_age, verification_type, id_order')
|
||||
->from('users_age_verification')
|
||||
->where(Operator::equals(['id_user' => $userId]))
|
||||
->execute()->fetchAllAssociative()[0] ?? [];
|
||||
}
|
||||
}
|
||||
123
bundles/KupShop/AgeVerifyBundle/Utils/BankIdUtil.php
Normal file
123
bundles/KupShop/AgeVerifyBundle/Utils/BankIdUtil.php
Normal file
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace KupShop\AgeVerifyBundle\Utils;
|
||||
|
||||
use KupShop\AgeVerifyBundle\Exception\BankIdException;
|
||||
use KupShop\KupShopBundle\Config;
|
||||
use KupShop\KupShopBundle\Util\System\CurlUtil;
|
||||
use Symfony\Component\HttpClient\Exception\ClientException;
|
||||
|
||||
class BankIdUtil
|
||||
{
|
||||
/** @required */
|
||||
public AgeVerifyUtil $ageVerifyUtil;
|
||||
|
||||
/** @required */
|
||||
public CurlUtil $curlUtil;
|
||||
|
||||
public const SCOPES = [
|
||||
'openid',
|
||||
'profile.birthdate',
|
||||
];
|
||||
|
||||
public const BANKID = 'bankId';
|
||||
|
||||
public const SANDBOX_URL = 'https://oidc.sandbox.bankid.cz/';
|
||||
public const PROD_URL = '/'; // TODO
|
||||
|
||||
public function fetchData($code)
|
||||
{
|
||||
$query = [
|
||||
'grant_type' => 'authorization_code',
|
||||
'client_id' => $this->getClientId(),
|
||||
'client_secret' => $this->getClientSecret(),
|
||||
'redirect_uri' => $this->getRedirectUri(),
|
||||
'code' => $code,
|
||||
];
|
||||
|
||||
$client = $this->curlUtil->getClient(headers: ['Content-Type' => 'application/x-www-form-urlencoded'])
|
||||
->request('POST', $this->getUrl('token'), ['body' => $query]);
|
||||
|
||||
try {
|
||||
$response = $client->getContent();
|
||||
$response = json_decode($response, true);
|
||||
} catch (ClientException $e) {
|
||||
throw new BankIdException('Unable to fetch access token');
|
||||
}
|
||||
|
||||
if (!isset($response['access_token'])) {
|
||||
throw new BankIdException('Unable to fetch access token');
|
||||
}
|
||||
|
||||
$client = $this->curlUtil->getClient(['Authorization' => "Bearer {$response['access_token']}"])
|
||||
->request('POST', $this->getUrl('userinfo'));
|
||||
|
||||
try {
|
||||
$data = $client->getContent();
|
||||
} catch (ClientException $e) {
|
||||
throw new BankIdException('Unable to fetch verified birthdate');
|
||||
}
|
||||
|
||||
$data = json_decode($data, true);
|
||||
|
||||
if (!isset($data['verified_claims']['claims']['birthdate'])) {
|
||||
throw new BankIdException('Unable to fetch verified birthdate');
|
||||
}
|
||||
|
||||
$birthdate = $data['verified_claims']['claims']['birthdate'];
|
||||
|
||||
$date = \DateTime::createFromFormat('Y-m-d', $birthdate)->add(\DateInterval::createFromDateString('+18YEARS'));
|
||||
|
||||
$this->ageVerifyUtil->setVerificationData($date <= (new \DateTime()) ? 'Y' : 'N', self::BANKID, $birthdate);
|
||||
}
|
||||
|
||||
public function getRedirectUrl()
|
||||
{
|
||||
$query = http_build_query([
|
||||
'client_id' => $this->getClientId(),
|
||||
'redirect_uri' => $this->getRedirectUri(),
|
||||
'scope' => implode(' ', self::SCOPES),
|
||||
'response_type' => 'code',
|
||||
'state' => 'BankID',
|
||||
'prompt' => 'login',
|
||||
'display' => 'page',
|
||||
'acr_values' => 'loa2',
|
||||
]);
|
||||
|
||||
return "{$this->getUrl('auth')}?{$query}";
|
||||
}
|
||||
|
||||
protected function getUrl($path)
|
||||
{
|
||||
if (isDevelopment() || \Settings::getDefault()['oauth']['bank_id']['sandbox']) {
|
||||
return self::SANDBOX_URL.$path;
|
||||
}
|
||||
|
||||
return self::PROD_URL.$path;
|
||||
}
|
||||
|
||||
protected function getClientId()
|
||||
{
|
||||
$settings = \Settings::getDefault();
|
||||
|
||||
return $settings['oauth']['bank_id']['client_id'] ?? '';
|
||||
}
|
||||
|
||||
protected function getClientSecret()
|
||||
{
|
||||
$settings = \Settings::getDefault();
|
||||
|
||||
return $settings['oauth']['bank_id']['client_secret'] ?? '';
|
||||
}
|
||||
|
||||
protected function getRedirectUri()
|
||||
{
|
||||
if (isDevelopment()) {
|
||||
return Config::get()['Addr']['full_original'].'_bankid';
|
||||
}
|
||||
|
||||
return Config::get()['Addr']['full'].'_bankid';
|
||||
}
|
||||
}
|
||||
213
bundles/KupShop/AgeVerifyBundle/Utils/VerifaceUtil.php
Normal file
213
bundles/KupShop/AgeVerifyBundle/Utils/VerifaceUtil.php
Normal file
@@ -0,0 +1,213 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace KupShop\AgeVerifyBundle\Utils;
|
||||
|
||||
use KupShop\AdminBundle\Util\ActivityLog;
|
||||
use KupShop\AgeVerifyBundle\Exception\VeriFaceException;
|
||||
use KupShop\GraphQLBundle\EventListener\JsShopRefreshListener;
|
||||
use KupShop\KupShopBundle\Context\DomainContext;
|
||||
use KupShop\KupShopBundle\Context\UserContext;
|
||||
use Query\Operator;
|
||||
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
||||
use Symfony\Contracts\Service\Attribute\Required;
|
||||
use veriface\Dto\IndicatorDto;
|
||||
use veriface\VeriFace;
|
||||
|
||||
class VerifaceUtil
|
||||
{
|
||||
protected ?VeriFace $veriFace = null;
|
||||
#[Required]
|
||||
public AgeVerifyUtil $ageVerifyUtil;
|
||||
#[Required]
|
||||
public DomainContext $domainContext;
|
||||
#[Required]
|
||||
public UserContext $userContext;
|
||||
#[Required]
|
||||
public SessionInterface $session;
|
||||
|
||||
public const MESSAGE = 'Veriface - Ověření plnoletosti se nezdařilo.';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$dbcfg = \Settings::getDefault();
|
||||
|
||||
$apiKey = $dbcfg['age_verify']['veriface']['api_key'] ?? false;
|
||||
|
||||
if ($apiKey) {
|
||||
$this->veriFace = VeriFace::byApiKey($apiKey);
|
||||
}
|
||||
}
|
||||
|
||||
protected function getMessage()
|
||||
{
|
||||
if ($user = $this->userContext->getActive()) {
|
||||
return self::MESSAGE.': '.$user->email;
|
||||
}
|
||||
|
||||
return self::MESSAGE;
|
||||
}
|
||||
|
||||
public function getRedirectUrl(): string
|
||||
{
|
||||
$this->checkVeriface();
|
||||
|
||||
if (!($email = $this->userContext->getActive()?->email)) {
|
||||
$data = $this->session->get('verifaceData');
|
||||
$email = $data['email'] ?? '';
|
||||
}
|
||||
|
||||
$verification = $this->veriFace->createVerification(type: 'LINK_LONG', referenceId: $email);
|
||||
|
||||
return 'https://app.veriface.eu/?oc='.$verification->openCode.'&redirectUri='.$this->getRedirectUri();
|
||||
}
|
||||
|
||||
public function saveData($sessionId, $user = null): bool
|
||||
{
|
||||
$this->checkVeriface();
|
||||
|
||||
$verification = $this->veriFace->getVerification($sessionId);
|
||||
|
||||
if ($verification === null) {
|
||||
$this->ageVerifyUtil->addErrorMessage('Ověření plnoletosti se nezdařilo.');
|
||||
addActivityLog(ActivityLog::SEVERITY_WARNING,
|
||||
ActivityLog::TYPE_COMMUNICATION,
|
||||
$this->getMessage(),
|
||||
['message' => 'Nepodařilo se získat data z Veriface.', 'sessionId' => $sessionId]);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Pro zalogování
|
||||
$status = [
|
||||
'verifaceStatus' => $verification->status,
|
||||
'endUserStatus' => $verification->verificationEndUserStatus ?? '',
|
||||
'sessionId' => $sessionId,
|
||||
'documentStatus' => $verification->documentStatus,
|
||||
'selfieStatus' => $verification->selfieStatus,
|
||||
'livenessCheckStatus' => $verification->livenessCheckStatus,
|
||||
'extractedData' => json_encode($verification->extractedData),
|
||||
];
|
||||
|
||||
// Uložení průběhu v čitelnější formě
|
||||
foreach ($verification->indicators as $key => $indicator) {
|
||||
$status["indicator_{$key}"] = json_encode($indicator);
|
||||
}
|
||||
|
||||
// Ověření chcíplo na straně uživatele
|
||||
if ($verification->verificationEndUserStatus != 'SUCCESS') {
|
||||
$this->ageVerifyUtil->addErrorMessage('Ověření plnoletosti se nezdařilo.');
|
||||
$status['message'] = 'Chyba v procesu ověření.';
|
||||
addActivityLog(ActivityLog::SEVERITY_WARNING, ActivityLog::TYPE_COMMUNICATION, $this->getMessage(), $status);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$verifaceName = $verification->name;
|
||||
|
||||
if ($verifaceName) {
|
||||
$nameParts = explode(' ', $verifaceName);
|
||||
$firstname = reset($nameParts);
|
||||
$surname = end($nameParts);
|
||||
if (str_contains($firstname, '/')) {
|
||||
$firstname = explode('/', $firstname)[1];
|
||||
}
|
||||
|
||||
if (str_contains($surname, '/')) {
|
||||
$surname = explode('/', $surname)[1];
|
||||
}
|
||||
|
||||
$verifaceName = "{$firstname} {$surname}";
|
||||
}
|
||||
|
||||
$age = array_filter($verification->indicators, function ($dto) {
|
||||
return $dto->code == 'document_age.age' && $dto->status == 'OK';
|
||||
});
|
||||
|
||||
if (empty($age)) {
|
||||
$this->ageVerifyUtil->addErrorMessage('Ověření plnoletosti se nezdařilo.');
|
||||
$status['message'] = 'Nepodařilo se získat věk.';
|
||||
addActivityLog(ActivityLog::SEVERITY_WARNING, ActivityLog::TYPE_COMMUNICATION, $this->getMessage(), $status);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @var IndicatorDto $age */
|
||||
$age = reset($age);
|
||||
|
||||
// Registrace z košíku
|
||||
if ($data = $this->session->get('verifaceData')) {
|
||||
/** @var \User $user */
|
||||
$user = sqlGetConnection()->transactional(function () use ($data) {
|
||||
$idUser = addUserEmail(email: $data['email'], fields: ['figure' => 'Y', 'phone' => $data['phone']]);
|
||||
|
||||
return \User::createFromId($idUser);
|
||||
});
|
||||
|
||||
$user->login(getUserKey());
|
||||
$user->updatePassword($data['password']);
|
||||
|
||||
$this->session->remove('verifaceData');
|
||||
if (findModule(\Modules::JS_SHOP)) {
|
||||
$this->session->set(JsShopRefreshListener::SESSION_NAME, true);
|
||||
}
|
||||
|
||||
if ($firstname && $surname) {
|
||||
sqlQueryBuilder()->update('users')
|
||||
->directValues([
|
||||
'name' => ucfirst(mb_strtolower($firstname)),
|
||||
'surname' => ucfirst(mb_strtolower($surname)),
|
||||
])
|
||||
->where(Operator::equals(['id' => $user->id]))
|
||||
->execute();
|
||||
}
|
||||
} else {
|
||||
// Když si nepošlu usera ze shora (webhook) tak zkusím přihlášeného
|
||||
if (!$user) {
|
||||
$user = $this->userContext->getActive();
|
||||
}
|
||||
|
||||
if ($user) {
|
||||
$transliterator = \Transliterator::createFromRules(':: Any-Latin; :: Latin-ASCII; :: NFD; :: [:Nonspacing Mark:] Remove; :: Lower(); :: NFC;',
|
||||
\Transliterator::FORWARD);
|
||||
$eshopName = "{$user->name} {$user->surname}";
|
||||
similar_text($transliterator->transliterate($eshopName), $transliterator->transliterate($verifaceName), $percent);
|
||||
if ($percent < 80) {
|
||||
$this->ageVerifyUtil->addErrorMessage('Ověření plnoletosti se nezdařilo: jméno a přijmení se neshoduje s údaji v e-shopu.');
|
||||
$status['message'] = 'Jméno a příjmení v eshopu se neshoduje s údaji z dokladu.';
|
||||
addActivityLog(ActivityLog::SEVERITY_WARNING, ActivityLog::TYPE_COMMUNICATION, $this->getMessage(), $status);
|
||||
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$this->ageVerifyUtil->addErrorMessage('Ověření plnoletosti se nezdařilo.');
|
||||
$status['message'] = 'Není přihlašený uživatel.';
|
||||
addActivityLog(ActivityLog::SEVERITY_WARNING, ActivityLog::TYPE_COMMUNICATION, $this->getMessage(), $status);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Plnoletý = 18+ a validní status
|
||||
$this->ageVerifyUtil->setVerificationData($age->params >= 18 && in_array($verification->status,
|
||||
['VERIFIED', 'VERIFIED_WARNING', 'VERIFIED_MANUAL']) ? 'Y' : 'N',
|
||||
'veriface',
|
||||
\DateTime::createFromFormat('d.m.Y', $verification->birthDate)->format('Y-m-d'),
|
||||
$user->id);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function checkVeriface(): void
|
||||
{
|
||||
if ($this->veriFace === null) {
|
||||
throw new VeriFaceException('Veriface není inicializován. Je vyplněný API klíč?');
|
||||
}
|
||||
}
|
||||
|
||||
protected function getRedirectUri()
|
||||
{
|
||||
return "{$this->domainContext->getActiveWithScheme()}/_veriface";
|
||||
}
|
||||
}
|
||||
45
bundles/KupShop/AgeVerifyBundle/View/AdultoView.php
Normal file
45
bundles/KupShop/AgeVerifyBundle/View/AdultoView.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace KupShop\AgeVerifyBundle\View;
|
||||
|
||||
use KupShop\AgeVerifyBundle\Utils\AdultoUtil;
|
||||
use KupShop\KupShopBundle\Context\UserContext;
|
||||
use KupShop\KupShopBundle\Util\Contexts;
|
||||
use KupShop\KupShopBundle\Views\View;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Contracts\Service\Attribute\Required;
|
||||
|
||||
class AdultoView extends View
|
||||
{
|
||||
protected $template = 'ageverify/adulto.tpl';
|
||||
protected $title = 'Ověření pomocí Adulto';
|
||||
|
||||
#[Required]
|
||||
public RequestStack $requestStack;
|
||||
|
||||
#[Required]
|
||||
public AdultoUtil $adultoUtil;
|
||||
|
||||
public function getBreadcrumbs(): ?array
|
||||
{
|
||||
return getReturnNavigation(-1, 'USER', [$this->getTitle()]);
|
||||
}
|
||||
|
||||
public function getBodyVariables(): array
|
||||
{
|
||||
$vars = parent::getBodyVariables();
|
||||
$vars['adulto_public_key'] = \Settings::getDefault()['age_verify']['adulto']['public_key'] ?? '';
|
||||
$vars['user'] = Contexts::get(UserContext::class)->getActive();
|
||||
|
||||
return $vars;
|
||||
}
|
||||
|
||||
public function submitForm(): array
|
||||
{
|
||||
$mainRequest = $this->requestStack->getMainRequest();
|
||||
|
||||
return $this->adultoUtil->checkAdultoUid($mainRequest->get('adultocz-uid') ?? '');
|
||||
}
|
||||
}
|
||||
38
bundles/KupShop/AgeVerifyBundle/View/AgeVerifyView.php
Normal file
38
bundles/KupShop/AgeVerifyBundle/View/AgeVerifyView.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace KupShop\AgeVerifyBundle\View;
|
||||
|
||||
use KupShop\AgeVerifyBundle\Utils\AgeVerifyUtil;
|
||||
use KupShop\KupShopBundle\Context\UserContext;
|
||||
|
||||
class AgeVerifyView extends \KupShop\KupShopBundle\Views\View
|
||||
{
|
||||
/** @required */
|
||||
public UserContext $userContext;
|
||||
|
||||
/** @required */
|
||||
public AgeVerifyUtil $ageVerifyUtil;
|
||||
|
||||
protected $template = 'ageverify/ageverify.tpl';
|
||||
|
||||
public function getBodyVariables()
|
||||
{
|
||||
$vars = parent::getBodyVariables();
|
||||
|
||||
$vars['user'] = $this->userContext->getActive();
|
||||
|
||||
return $vars;
|
||||
}
|
||||
|
||||
public function getBreadcrumbs()
|
||||
{
|
||||
return getReturnNavigation(-1, 'USER', [$this->getTitle()]);
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return translate('age_verify', 'AgeVerify');
|
||||
}
|
||||
}
|
||||
290
bundles/KupShop/AgeVerifyBundle/View/PackageOrderView.php
Normal file
290
bundles/KupShop/AgeVerifyBundle/View/PackageOrderView.php
Normal file
@@ -0,0 +1,290 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace KupShop\AgeVerifyBundle\View;
|
||||
|
||||
use KupShop\AgeVerifyBundle\Exception\AgeVerificationException;
|
||||
use KupShop\AgeVerifyBundle\Utils\AgeVerifyUtil;
|
||||
use KupShop\KupShopBundle\Context\ContextManager;
|
||||
use KupShop\KupShopBundle\Context\UserContext;
|
||||
use KupShop\KupShopBundle\Exception\RedirectException;
|
||||
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||
use KupShop\KupShopBundle\Util\Price\Price;
|
||||
use KupShop\KupShopBundle\Util\Price\PriceCalculator;
|
||||
use KupShop\KupShopBundle\Views\View;
|
||||
use KupShop\KupShopBundle\Wrapper\PriceWrapper;
|
||||
use KupShop\OrderingBundle\Entity\Purchase\ProductPurchaseItem;
|
||||
use KupShop\OrderingBundle\Entity\Purchase\PurchaseState;
|
||||
use KupShop\OrderingBundle\Event\OrderEvent;
|
||||
use KupShop\OrderingBundle\Util\Purchase\PurchaseUtil;
|
||||
use Query\Operator;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Contracts\Service\Attribute\Required;
|
||||
|
||||
class PackageOrderView extends View
|
||||
{
|
||||
protected $template = 'ageverify/packageOrder.tpl';
|
||||
protected $title = 'Ověření přes zásilkovnu';
|
||||
|
||||
#[Required]
|
||||
public ContextManager $contextManager;
|
||||
|
||||
#[Required]
|
||||
public UserContext $userContext;
|
||||
|
||||
#[Required]
|
||||
public RequestStack $requestStack;
|
||||
|
||||
#[Required]
|
||||
public AgeVerifyUtil $ageVerifyUtil;
|
||||
|
||||
#[Required]
|
||||
public PurchaseUtil $purchaseUtil;
|
||||
|
||||
#[Required]
|
||||
public EventDispatcherInterface $eventDispatcher;
|
||||
|
||||
protected array $deliveries = [];
|
||||
protected array $payments = [];
|
||||
|
||||
protected $id_delivery;
|
||||
protected $id_payment;
|
||||
protected ?Price $product_price = null;
|
||||
|
||||
public function getBreadcrumbs(): ?array
|
||||
{
|
||||
return getReturnNavigation(-1, 'USER', [$this->getTitle()]);
|
||||
}
|
||||
|
||||
public function getBodyVariables(): array
|
||||
{
|
||||
$vars = parent::getBodyVariables();
|
||||
|
||||
$vars['user'] = $this->userContext->getActive();
|
||||
|
||||
$mainRequest = $this->requestStack->getMainRequest();
|
||||
|
||||
$this->id_delivery = $mainRequest->get('delivery_id') ?? false;
|
||||
$this->id_payment = $mainRequest->get('payment_id') ?? false;
|
||||
|
||||
$vars['deliveries'] = $this->getDeliveries();
|
||||
$vars['payments'] = $this->getPayments();
|
||||
|
||||
if ($this->id_delivery) {
|
||||
$vars['deliveries'][$this->id_delivery]->storeDeliveryInfo(getVal($this->id_delivery, $mainRequest->get('delivery_data')));
|
||||
}
|
||||
|
||||
$vars['payment_id'] = $this->id_payment;
|
||||
$vars['delivery_id'] = $this->id_delivery;
|
||||
|
||||
return $vars;
|
||||
}
|
||||
|
||||
public function submitForm()
|
||||
{
|
||||
$user = $this->userContext->getActive();
|
||||
$userId = $user->id;
|
||||
|
||||
$userVerification = sqlQueryBuilder()->select('*')->from('users_age_verification')->where(Operator::equals(['id_user' => $userId]))
|
||||
->execute()->fetchAssociative();
|
||||
|
||||
$mainRequest = $this->requestStack->getMainRequest();
|
||||
|
||||
if ($mainRequest->get('submitOrder') === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$data = $mainRequest->get('data');
|
||||
$id_delivery = $mainRequest->get('delivery_id');
|
||||
$id_payment = explode('-', $mainRequest->get('payment_id', ''))[0] ?? false;
|
||||
|
||||
if ($data['email'] ?? false) {
|
||||
$data['name'] ??= $user->invoice['name'] ?? '';
|
||||
$data['surname'] ??= $user->invoice['surname'] ?? '';
|
||||
}
|
||||
|
||||
$order = null;
|
||||
$id_product = \Settings::getDefault()['age_verify']['package']['product'];
|
||||
if ($userVerification === false || (empty($userVerification['id_order']) && $userVerification['legal_age'] != 'Y')) {
|
||||
$deliveryType = $this->getDeliveryType($id_delivery, $id_payment);
|
||||
if (!$deliveryType) {
|
||||
return;
|
||||
}
|
||||
|
||||
$purchaseState = $this->createPurchaseState();
|
||||
|
||||
$product = new \Product($id_product);
|
||||
$product->createFromDB();
|
||||
|
||||
$purchaseItem = new ProductPurchaseItem(
|
||||
$id_product,
|
||||
null,
|
||||
1,
|
||||
PriceCalculator::toPrice($product->getProductPrice())
|
||||
);
|
||||
$purchaseItem->setProduct($product);
|
||||
|
||||
$purchaseState->addProduct($purchaseItem)
|
||||
->setDeliveryTypeId($deliveryType->id);
|
||||
|
||||
$delivery_data = $mainRequest->get('delivery_data');
|
||||
|
||||
$deliveryInfo = [];
|
||||
|
||||
if ($delivery_data[$id_delivery] ?? false) {
|
||||
$deliveryInfo = $purchaseState->getDeliveryType()->getDelivery()->storeDeliveryInfo($delivery_data[$id_delivery]);
|
||||
}
|
||||
|
||||
$purchaseState->setCustomData([
|
||||
'order' => [
|
||||
'id_user' => $user->id,
|
||||
'invoice_name' => $user->invoice['name'] ?? '',
|
||||
'invoice_surname' => $user->invoice['surname'] ?? '',
|
||||
'invoice_firm' => $user->invoice['firm'] ?? '',
|
||||
'invoice_ico' => $user->invoice['ico'] ?? '',
|
||||
'invoice_dic' => $user->invoice['dic'] ?? '',
|
||||
'invoice_street' => $user->invoice['street'] ?? '',
|
||||
'invoice_city' => $user->invoice['city'] ?? '',
|
||||
'invoice_zip' => $user->invoice['zip'] ?? '',
|
||||
'invoice_country' => $user->invoice['country'] ?? '',
|
||||
'invoice_phone' => $user->invoice['phone'] ?? '',
|
||||
'invoice_email' => $user->invoice['email'] ?? '',
|
||||
'invoice_state' => $user->invoice['state'] ?? '',
|
||||
|
||||
'delivery_name' => $data['name'] ?? '',
|
||||
'delivery_surname' => $data['surname'] ?? '',
|
||||
'delivery_street' => $data['street'] ?? '',
|
||||
'delivery_city' => $data['city'] ?? '',
|
||||
'delivery_zip' => $data['zip'] ?? '',
|
||||
'delivery_phone' => $data['phone'] ?? '',
|
||||
'date_created' => date('Y-m-d H:i:s'),
|
||||
'date_updated' => date('Y-m-d H:i:s'),
|
||||
'note_admin' => json_encode(['delivery_data' => $deliveryInfo]),
|
||||
],
|
||||
'age_verification' => true,
|
||||
]);
|
||||
|
||||
$order = $this->purchaseUtil->createOrderFromPurchaseState($purchaseState);
|
||||
|
||||
$orderEvent = new OrderEvent($order);
|
||||
|
||||
$this->eventDispatcher->dispatch($orderEvent, OrderEvent::ORDER_FINISHED);
|
||||
|
||||
if (!empty($order)) {
|
||||
sqlQueryBuilder()->insert('users_age_verification')
|
||||
->directValues([
|
||||
'id_user' => $userId,
|
||||
'verification_type' => 'package',
|
||||
'id_order' => $order->id,
|
||||
])
|
||||
->onDuplicateKeyUpdate(['id_user' => 'id_user', 'id_order'])
|
||||
->execute();
|
||||
if ($birthdate = $mainRequest->get('cart_data')['birthdate'] ?? false) {
|
||||
sqlQueryBuilder()->update('users')->directValues([
|
||||
'birthdate' => $birthdate,
|
||||
])->where(Operator::equals(['id' => $userId]))->execute();
|
||||
}
|
||||
} else {
|
||||
throw new AgeVerificationException('Failed to create order.');
|
||||
}
|
||||
} elseif (!empty($userVerification['id_order'])) {
|
||||
addUserMessage(translate('orderAlreadyCreated', 'AgeVerify'));
|
||||
throw new RedirectException(path('ageVerify'));
|
||||
}
|
||||
|
||||
return $order;
|
||||
}
|
||||
|
||||
public function getDeliveries(): array
|
||||
{
|
||||
if (empty($this->deliveries)) {
|
||||
$deliveryTypes = array_filter(\DeliveryType::getAll(), function ($deliveryType) {
|
||||
return $deliveryType->getDelivery()->getCustomData()['balikobot']['require_full_age'] ?? false;
|
||||
});
|
||||
|
||||
foreach ($deliveryTypes as $deliveryType) {
|
||||
$delivery = $deliveryType->getDelivery();
|
||||
if ($delivery->accept($this->getProductPrice(), false)) {
|
||||
$this->deliveries[$deliveryType->id_delivery] = $delivery;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->deliveries;
|
||||
}
|
||||
|
||||
public function getPayments(): array
|
||||
{
|
||||
if (empty($this->payments)) {
|
||||
$deliveryTypes = array_filter(\DeliveryType::getAll(true), function ($deliveryType) {
|
||||
return ($deliveryType->getDelivery()->getCustomData()['balikobot']['require_full_age'] ?? false) && $deliveryType->id_delivery == $this->id_delivery;
|
||||
});
|
||||
|
||||
foreach ($deliveryTypes as $deliveryType) {
|
||||
$payment = $deliveryType->getPayment();
|
||||
if ($payment->accept($this->getProductPrice(), false)) {
|
||||
$this->payments[$deliveryType->id_payment] = [
|
||||
'class' => $payment,
|
||||
'name' => $payment->getName(),
|
||||
'exception' => $payment->exception,
|
||||
'photo' => $payment->getPhoto(null),
|
||||
'enabled' => \Payment::isEnabled($payment->class),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->payments;
|
||||
}
|
||||
|
||||
public function getDeliveryPrice($id)
|
||||
{
|
||||
/** @var Price $price */
|
||||
$price = $this->getDeliveries()[$id]->getPrice();
|
||||
|
||||
return ServiceContainer::getService(PriceWrapper::class)->setObject($price);
|
||||
}
|
||||
|
||||
public function getPaymentPrice($id)
|
||||
{
|
||||
foreach (\DeliveryType::getAll() as $deliveryType) {
|
||||
if ($deliveryType->id_payment == $id) {
|
||||
$price = $deliveryType->price_payment;
|
||||
}
|
||||
}
|
||||
|
||||
return ServiceContainer::getService(PriceWrapper::class)->setObject($price);
|
||||
}
|
||||
|
||||
protected function getProductPrice()
|
||||
{
|
||||
if (!$this->product_price) {
|
||||
$product = new \Product();
|
||||
$product->createFromDB(\Settings::getDefault()['age_verify']['package']['product']);
|
||||
$this->product_price = $product->getProductPrice();
|
||||
}
|
||||
|
||||
return $this->product_price;
|
||||
}
|
||||
|
||||
protected function getDeliveryType($id_delivery, $id_payment): ?\DeliveryType
|
||||
{
|
||||
foreach (\DeliveryType::getAll(false) as $deliveryType) {
|
||||
if ($deliveryType->id_delivery == $id_delivery && $deliveryType->id_payment == $id_payment) {
|
||||
$delivery = $deliveryType->getDelivery();
|
||||
$delivery->accept($this->getProductPrice(), false);
|
||||
|
||||
return $deliveryType;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function createPurchaseState(): PurchaseState
|
||||
{
|
||||
return new PurchaseState([]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user