Initial import

This commit is contained in:
Admin Nasledstvo
2026-05-01 20:52:04 +03:00
commit ac168868ee
10028 changed files with 2337954 additions and 0 deletions
@@ -0,0 +1,57 @@
<?php
namespace app\services;
use app\models\UserPublic;
class Auth
{
/**
* @return \app\models\UserPublic|null
*/
public static function getUser()
{
if (isset($_SESSION['public_user']))
return UserPublic::find()->where(['email' => $_SESSION['public_user']])->one();
return null;
}
public static function checkUserExists($user)
{
$exists = UserPublic::find()->where(['email' => $user])->one();
if (!$exists) {
header('Location: ' . \Yii::$app->params['portal']);
exit;
}
}
public static function setUser($username = null)
{
if ($username) {
$_SESSION['public_user'] = $username;
} else {
if (!empty($_SESSION['public_user'])) {
unset($_SESSION['public_user']);
}
}
}
public static function getUserByToken($get_token = null)
{
if ($get_token) {
$token = $get_token;
} else {
$headers = getallheaders();
$token = !empty($headers['Auth']) && $headers['Auth'] != 'undefined' ? $headers['Auth'] : null;
}
if ($token) {
$decode = JWT::decode($token, JWT::SECRET_KEY);
if ($decode->id) {
return UserPublic::findOne($decode->id);
}
}
return null;
}
}
@@ -0,0 +1,233 @@
<?php
namespace app\services;
use app\models\Events;
use app\models\OrderBooking;
use app\models\parsed\CartModel;
use app\models\PriceObject;
use app\models\Subscriptions;
use app\models\Ts;
use phpDocumentor\Reflection\Types\Self_;
use yii\base\BaseObject;
class Cart
{
const EXP_DAYS = 2;
public static function encodeKey($model, $id)
{
/*return JWT::encode([
'model' => $model,
'id' => $id
], JWT::SECRET_KEY); */
return $model . '_' . $id;
}
public static function decodeKey($key)
{
$result = explode('_', $key);
$decode = ['model' => 'app\\models\\' . $result[0], 'id' => $result[1]];
return (object)$decode;
//return JWT::decode($key, JWT::SECRET_KEY);
}
public static function add()
{
$cart_data = 'cart_data';
$cart_key = 'cart_key';
if (empty($_COOKIE[$cart_key])) {
setcookie($cart_key, uniqid('.' . $_SERVER['REMOTE_ADDR'] . '.' . time()), time() + (86400 * self::EXP_DAYS), "/");
}
$data = json_decode(\Yii::$app->request->getRawBody());
$newCartElement = $data->cart;
$cartData = !empty($_COOKIE[$cart_data]) ? json_decode($_COOKIE['cart_data']) : [];
$duplicatesCount = 0;
foreach ($cartData as $element) {
if ($element == $data->cart)
$duplicatesCount++;
}
$allow = true;
if (!empty($data->max) && $data->max <= $duplicatesCount) $allow = false;
if ($allow) {
$cartData[] = $newCartElement;
setcookie($cart_data, json_encode($cartData), time() + (86400 * self::EXP_DAYS), "/");
if (!empty($_COOKIE[$cart_key])) {
setcookie($cart_key, $_COOKIE[$cart_key], time() + (86400 * self::EXP_DAYS), "/");
}
} else {
echo json_encode(['message' => Ts::get(122), 'error' => 1]);
exit;
}
}
public static function addBooking()
{
$cart_data = 'cart_data';
$cart_key = 'cart_key';
$key = uniqid($_SERVER['REMOTE_ADDR'] . '_' . time());
if (empty($_COOKIE[$cart_key])) {
setcookie($cart_key, $key, time() + (86400 * self::EXP_DAYS), "/");
}
$data = json_decode(\Yii::$app->request->getRawBody());
$allTickets = explode(',', $data->{'tickets'});
$tickets = PriceObject::find()->where(['IN', 'id', $allTickets])->all();
$data_to_cart = [];
/** @var PriceObject $ticket */
foreach ($tickets as $ticket) {
$ticketsCount = array_count_values($allTickets)[$ticket->id];
$booking = OrderBooking::find()->where(['ticket_id' => $ticket->id, 'datetime' => $data->{'date_time'}, 'cart_key' => $_COOKIE[$cart_key] ?? $key])->one();
if ($booking) {
$booking->tickets_count = $booking->tickets_count + $ticketsCount;
} else {
$booking = new OrderBooking();
$booking->datetime = $data->{'date_time'};
$booking->name_bg = $ticket->text_bg;
$booking->name_en = $ticket->text_en;
$booking->description_bg = $ticket->event->title('bg');
$booking->description_en = $ticket->event->title('en');
$booking->single_price = $ticket->price;
$booking->tickets_count = $ticketsCount;
$booking->event_id = $ticket->event_id;
$booking->ticket_id = $ticket->id;
$booking->cart_key = $_COOKIE[$cart_key] ?? $key;
}
$booking->save();
for ($i = 0; $i < $ticketsCount; $i++) {
$data_to_cart[] = $booking->getCartKey();
}
}
$cartData = !empty($_COOKIE[$cart_data]) ? json_decode($_COOKIE[$cart_data]) : [];
foreach ($data_to_cart as $element)
$cartData[] = $element;
setcookie($cart_data, json_encode($cartData), time() + (86400 * self::EXP_DAYS), "/");
if (!empty($_COOKIE[$cart_data])) {
setcookie($cart_key, $_COOKIE[$cart_key], time() + (86400 * self::EXP_DAYS), "/");
}
}
public static function remove()
{
$cart_data = 'cart_data';
$cart_key = 'cart_key';
$data = json_decode(\Yii::$app->request->getRawBody());
$cartData = !empty($_COOKIE[$cart_data]) ? json_decode($_COOKIE['cart_data']) : [];
$reCountCartData = [];
foreach ($cartData as $cartKey) {
if ($cartKey == $data->cart) continue;
$reCountCartData[] = $cartKey;
}
$cartItem = explode('_', $data->cart);
if ($cartItem[0] == 'OrderBooking') {
$booking = OrderBooking::findOne($cartItem[1]);
if ($booking) {
$booking->delete();
}
}
setcookie($cart_data, json_encode($reCountCartData), time() + (86400 * 30), "/");
if (sizeof($reCountCartData) > 0) {
if (!empty($_COOKIE[$cart_key]))
setcookie($cart_key, $_COOKIE[$cart_key], time() + (86400 * self::EXP_DAYS), "/");
} else {
setcookie('cart_data', '', time() - 3600, "/");
setcookie('cart_key', time() - 3600, "/");
}
}
public static function clear()
{
setcookie('cart_data', '', time() - 3600, "/");
setcookie('invoice_data', '', time() - 3600, "/");
setcookie('payment_method', '', time() - 3600, "/");
setcookie('cart_key', '', time() - 3600, "/");
}
public static function clearCartOnly()
{
setcookie('cart_data', '', time() - 3600, "/");
setcookie('cart_key', '', time() - 3600, "/");
}
public static function getData()
{
return !empty($_COOKIE['cart_data']) ? json_decode($_COOKIE['cart_data']) : [];
}
public static function getGroupedData()
{
$groupedData = [];
foreach (self::getData() as $cartKey)
$groupedData[$cartKey] = empty($groupedData[$cartKey]) ? 1 : ++$groupedData[$cartKey];
return $groupedData;
}
public static function getFormatedData()
{
/** @var \app\models\parsed\CartModel[] $cartModels */
$cartModels = [];
$total = 0;
foreach (self::getGroupedData() as $cartKey => $quantity) {
$data = self::decodeKey($cartKey);
/** @var Subscriptions | Events $modelClass */
$modelClass = $data->model;
$model = $modelClass::findOne($data->id);
if ($model) {
$cartModel = new CartModel();
$cartModel->quantity = $quantity;
$cartModel->cartKey = $cartKey;
$cm = $model->setCart($cartModel);
$cartModels[] = $cm;
$total += $quantity * $cm->price;
}
}
return ['models' => $cartModels, 'total' => number_format($total, 2, ' . ', '')];
}
public static function updateItemQuantity()
{
$cart_data = 'cart_data';
$cart_key = 'cart_key';
$data = json_decode(\Yii::$app->request->getRawBody());
$updatedData = [];
foreach (self::getGroupedData() as $cartKey => $q) {
if ($cartKey == $data->cart)
$q = $data->quantity;
for ($i = 0; $i < $q; $i++) {
$updatedData[] = $cartKey;
}
}
$cartItem = explode('_', $data->cart);
if ($cartItem[0] == 'OrderBooking') {
$booking = OrderBooking::findOne($cartItem[1]);
if ($booking) {
$booking->tickets_count = $data->quantity;
$booking->save();
}
}
setcookie($cart_data, json_encode($updatedData), time() + (86400 * 30), "/");
if (!empty($_COOKIE[$cart_key]))
setcookie($cart_key, $_COOKIE[$cart_key], time() + (86400 * self::EXP_DAYS), "/");
}
}
@@ -0,0 +1,105 @@
<?php
namespace app\services;
class ELibraryModels
{
public static $lib_format_opt = [
"1" => ['Електронно', 'Digital'],
"3" => ['Печатно', 'Printed'],
"2" => ['Електронно и печатно', 'Digital and Printed'],
];
public static $lib_types = [
"1" => ["Книга", "Book"],
"3" => ["Периодично издание", "Periodical edition"],
"2" => ["Статия", "Article"]
];
public static $lib_language_opt = [
"1" => ['Български', 'Bulgarian'],
"2" => ['Английски', 'English'],
"3" => ['Немски', 'German'],
"4" => ['Испански', 'Spanish'],
"5" => ['Португалски', 'Portuguese'],
"6" => ['Гръцки', 'Greek'],
"7" => ['Турски', 'Turkish'],
"8" => ['Румънски', 'Romanian'],
"9" => ['Руски', 'Russian'],
];
public static $lib_licenses = [
"1" => ["Признание (CC BY)", "Recognition (CC BY)"],
"3" => ["Признание-Без производни (CC BY-ND)", "Acknowledgment-No Derivatives (CC BY-ND)"],
"4" => ["Признание-Некомерсиално (CC BY-NC)", "Acknowledgment-Noncommercial (CC BY-NC)"],
"6" => ["Признание-Некомерсиално-Без производни (CC BY-NC-ND)", "Attribution-Non-Commercial-No Derivatives (CC BY-NC-ND)"],
"5" => ["Признание-Некомерсиално-Споделяне на споделеното (CC BY-NC-SA)", "Attribution-NonCommercial-ShareAlike (CC BY-NC-SA)"],
"2" => ["Признание-Споделяне на споделеното (CC BY-SA)", "Acknowledgment-Sharing the shared (CC BY-SA)"]
];
public static $lib_rights = [
"12" => ["Авторското право е неизвестно", "Copyright unknown"],
"11" => ["Авторското право е неопределено", "Copyright is indefinite"],
"10" => ["Авторското право не е установено", "Copyright not established"],
"8" => ["Без авторски права – други известни правни ограничения", "No Copyright - Other Known Legal Restrictions"],
"7" => ["Без авторски права – разрешени за ползване без търговски цели", "Copyright free - non-commercial use permitted"],
"6" => ["Без авторски права – с ограничения в ползването на базата на договор", "No copyright - with restrictions on use based on contract"],
"9" => ["Без авторски права – САЩ", "Copyright Free - USA"],
"1" => ["С авторски права", "Copyrighted"],
"5" => ["С авторски права – неоткриваем или неидентифициран носител на авторските права", "Copyrighted - untraceable or unidentified copyright holder"],
"2" => ["С авторски права – Осиротяло произведение в рамките на Европейския съюз", "Copyrighted - Orphan work within the European Union"],
"4" => ["С авторски права – разрешено за ползване без търговски цели", "Copyrighted - non-commercial use permitted"],
"3" => ["С авторски права – разрешено за ползване за образователни цели", "Copyrighted - permitted for educational use"],
];
public static $key_labels = [
'lib_variant' => ['Тип', 'Type'],
'lib_format' => ['Формат', 'Format'],
'lib_identifier_isbn_print' => ['ISBN (Print)', 'ISBN (Print)'],
'lib_identifier_isbn_online' => ['ISBN (Online)', 'ISBN (Online)'],
'lib_identifier_issn_print' => ['ISSN (Print)', 'ISSN (Print)'],
'lib_identifier_issn_online' => ['ISSN (Online)', 'ISSN (Online)'],
'lib_identifier_doi' => ['DOI', 'DOI'],
'lib_identifier_ismn' => ['ISMN', 'ISMN'],
'lib_identifier_isan' => ['ISAN', 'ISAN'],
'lib_author_compiler' => ['Съставител', 'Compiler'],
'lib_author_translator' => ['Преводач', 'Translator'],
'lib_author_editor' => ['Редактор', 'Editor'],
'lib_author_reviewer' => ['Рецензент', 'Reviewer'],
'lib_author_ilustrator' => ['Илюстратор', 'Illustrator'],
'lib_language' => ['Език', 'Language'],
'lib_title_information' => ['Допълнение към заглавието', 'Addendum to title'],
'lib_title_parallel' => ['Паралелно заглавие', 'Parallel title'],
'lib_edition' => ['Издание', 'Edition'],
'lib_series' => ['Серия', 'Series'],
'lib_publisher_name' => ['Издател', 'Publisher'],
'lib_publication_place' => ['Място на публикуване', 'Place of publication'],
'lib_url' => ['Url адрес'],
'lib_article_source' => ['Източник на статията', 'Article source'],
'lib_article_pages' => ['Страници от - до', 'Article pages'],
'lib_volume_source' => ['Том, книжка', 'Volume source'],
'lib_periodical_dimensions' => ['Периодично издание', 'periodical dimensions'],
'lib_pages' => ['Страници', 'Pages'],
'lib_citation_apa' => ['APA цитиране', 'APA citation'],
'lib_citation_harvard' => ['Harvard цитиране', 'Harvard citation'],
'lib_publication_date' => ['Година на публикуване', 'Publish year'],
'lib_rights' => ['Авторски права', 'Copyright'],
'lib_license' => ['Лиценз', 'License'],
];
public static function getLanguages($value)
{
$lg = \Yii::$app->language;
$index = $lg == 'en' ? 1 : 0;
$ids = explode('|', $value);
$lg = [];
foreach ($ids as $id) {
if(!empty(self::$lib_language_opt[$id])) {
$lg[] = self::$lib_language_opt[$id][$index];
}
}
return implode(', ', $lg); //implode(', ', $lg);
}
}
@@ -0,0 +1,88 @@
<?php
namespace app\services;
class Formatter
{
public static function cyrillicTrans($phrase)
{
$phrase = mb_strtolower($phrase, 'UTF-8');
$phrase = trim($phrase);
$phrase = str_replace('а', 'a', $phrase);
$phrase = str_replace('б', 'b', $phrase);
$phrase = str_replace('в', 'v', $phrase);
$phrase = str_replace('г', 'g', $phrase);
$phrase = str_replace('д', 'd', $phrase);
$phrase = str_replace('е', 'e', $phrase);
$phrase = str_replace('ж', 'g', $phrase);
$phrase = str_replace('з', 'z', $phrase);
$phrase = str_replace('и', 'i', $phrase);
$phrase = str_replace('й', 'j', $phrase);
$phrase = str_replace('к', 'k', $phrase);
$phrase = str_replace('л', 'l', $phrase);
$phrase = str_replace('м', 'm', $phrase);
$phrase = str_replace('н', 'n', $phrase);
$phrase = str_replace('о', 'o', $phrase);
$phrase = str_replace('п', 'p', $phrase);
$phrase = str_replace('р', 'r', $phrase);
$phrase = str_replace('с', 's', $phrase);
$phrase = str_replace('т', 't', $phrase);
$phrase = str_replace('у', 'u', $phrase);
$phrase = str_replace('ф', 'f', $phrase);
$phrase = str_replace('х', 'h', $phrase);
$phrase = str_replace('ц', 'ts', $phrase);
$phrase = str_replace('ш', 'sh', $phrase);
$phrase = str_replace('щ', 'sht', $phrase);
$phrase = str_replace('ч', 'ch', $phrase);
$phrase = str_replace('ь', 'j', $phrase);
$phrase = str_replace('ъ', 'a', $phrase);
$phrase = str_replace('ю', 'yu', $phrase);
$phrase = str_replace('я', 'ya', $phrase);
$phrase = str_replace(', ', '-', $phrase);
$phrase = str_replace(',', '-', $phrase);
$phrase = str_replace(' ', '-', $phrase);
$phrase = str_replace('`', '-', $phrase);
$phrase = str_replace("'", '-', $phrase);
$phrase = str_replace('?', '', $phrase);
$phrase = str_replace('%', '', $phrase);
$phrase = str_replace('/', '-', $phrase);
$phrase = str_replace('.', '', $phrase);
$phrase = str_replace('„', '', $phrase);
$phrase = str_replace('“', '', $phrase);
$phrase = str_replace('”', '', $phrase);
$phrase = str_replace('"', '', $phrase);
$phrase = ltrim($phrase, '-');
return rtrim($phrase, '-');
}
private static $hashModel = 'zgbctefkhx';
public static function encodeId($number)
{
list($hashArr, $encoded) = [str_split(self::$hashModel), ''];
foreach (str_split($number) as $index)
$encoded .= $hashArr[$index];
return $encoded;
}
public static function decodeId($hash)
{
list($hashArr, $decoded) = [str_split(self::$hashModel), ''];
foreach (str_split($hash) as $l)
$decoded .= array_search($l, $hashArr);
return $decoded;
}
public static function dates($from, $to)
{
$date = '';
if ($from)
$date = date('d.m.Y', strtotime($from));
if ($from && $to)
$date .= ' - ' . date('d.m.Y', strtotime($to));
return $date;
}
}
@@ -0,0 +1,97 @@
<?php
namespace app\services;
use app\models\ExplorerObjects;
use app\models\UserPublic;
class GeoService
{
public static function getNearestObjects($latitude, $longitude, $DISTANCE_KILOMETERS = 600, $table = 'tour_objects')
{
$lg = \Yii::$app->language;
$sql_distance = "(((acos(sin((" . $latitude . "*pi()/180)) * sin((`latitude`*pi()/180))+cos((" . $latitude . "*pi()/180)) * cos((`latitude`*pi()/180)) * cos(((" . $longitude . "-`longitude`)*pi()/180))))*180/pi())*60*1.1515*1.609344) as distance ";
$having = " HAVING (distance <= $DISTANCE_KILOMETERS)";
$order_by = 'ORDER BY distance ASC';
$sql = "SELECT *, $sql_distance FROM $table $having $order_by";
$res = \Yii::$app->db->createCommand($sql);
$result = $res->queryAll();
$resultArray = [];
$bindData = [];
$ids = [];
foreach ($result as $r) {
$resultArray[] = [
'id' => $r['id'],
'dist' => $r['distance'],
'latitude' => $r['latitude'],
'longitude' => $r['longitude']
];
$bindData['id_'. $r['id']] = [
'id' => $r['id'],
'dist' => $r['distance'],
'latitude' => $r['latitude'],
'longitude' => $r['longitude'],
'name' => $r['name'],
'name_en' => $r['name_en']
];
$ids[] = $r['id'];
}
return ['data' => $resultArray, 'bindData' => $bindData, 'ids' => $ids];
}
public static function orderList($nearest) {
$ids = $nearest['ids'];
$exploreObjectList = ExplorerObjects::find()->where(['IN','tour_object_id', $ids])->all();
$exploreObjectListBuffer = [];
foreach ($exploreObjectList as $explorerObject) {
$exploreObjectListBuffer[$explorerObject->tour_object_id] = $explorerObject;
}
$lang = \Yii::$app->language;
$data = [];
$explorerObjectIds = [];
$pointSystemActive = false;
if(!empty($_GET['tn'])) {
$user = Auth::getUserByToken($_GET['tn']);
if($user && $user->club_card) {
$pointSystemActive = true;
$explorerObjectIds = $user->getExplorerObjectsIds();
}
}
foreach ($nearest['bindData'] as $key => $objectBuffer) {
if(isset($exploreObjectListBuffer[$objectBuffer['id']])) {
$object = $exploreObjectListBuffer[$objectBuffer['id']];
$dist = number_format($objectBuffer['dist'], 1, '.', '');
$dec = explode('.', $dist);
$dist = $dec[1] == '0' ? $dec[0] : $dist;
$data[] = [
'id' => $object->id,
'name' => $lang == 'en' ? $object->tourObject->name_en : $object->tourObject->name,
'points' => $object->points,
'img' => $object->getSrcOfSingleImage('explorer_object_image', '1:1'),
'distance' => $dist,
'can_visit' => $dist < 1,
'visited' => in_array($object->id, $explorerObjectIds),
'point_system' => $pointSystemActive,
'latitude' => $object->tourObject->latitude,
'longitude' => $object->tourObject->longitude
];
}
}
return $data;
}
}
@@ -0,0 +1,144 @@
<?php
namespace app\services;
use app\models\RegisterObjectFiles;
use app\services\base\IdServerBase;
class IdServer extends IdServerBase
{
public function __construct()
{
$this->auth();
}
public function customGetRequest($req)
{
return $this->secureGetRequest($req);
}
public function customPostRequest($req, $data = [])
{
return $this->securePostRequest($req, $data);
}
public function updatePassword($userId, $password)
{
$url = \Yii::$app->params['id_server'] . '/admin/realms/' . \Yii::$app->params['realm'] . '/users/' . $userId . '/reset-password';
$data = [
'type' => 'password',
'temporary' => false,
'value' => $password,
];
$options = [
'http' => [
'header' => "Authorization: Bearer $this->accessToken\r\n" .
"Content-type: application/json\r\n",
'method' => 'PUT',
'content' => json_encode($data),
],
];
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
//get the http status code
$status = $http_response_header[0];
$status = explode(' ', $status);
$status = $status[1];
//$result = json_decode($result, true);
//check if $status is a success http status code - store the result in var is_success
$is_success = $status >= 200 && $status < 300;
return ['code' => $status, 'result' => $result, 'is_success' => $is_success];
}
//get the user's credentials
public function getCredentials($accessToken, $userId)
{
$url = \Yii::$app->params['id_server'] . '/admin/realms/' . \Yii::$app->params['realm'] . '/users/' . $userId . '/credentials';
$options = [
'http' => [
'header' => "Authorization: Bearer $accessToken\r\n" .
"Content-type: application/json\r\n",
'method' => 'GET',
],
];
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
$result = json_decode($result, true);
return $result;
}
//remove a credential
public function removeCredential($accessToken, $userId, $credentialId)
{
$url = \Yii::$app->params['id_server'] . '/admin/realms/' . \Yii::$app->params['realm'] . '/users/' . $userId . '/credentials/' . $credentialId;
$options = [
'http' => [
'header' => "Authorization: Bearer $accessToken\r\n" .
"Content-type: application/json\r\n",
'method' => 'DELETE',
],
];
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
//get the http status code
$status = $http_response_header[0];
$status = explode(' ', $status);
$status = $status[1];
//$result = json_decode($result, true);
//check if $status is a success http status code - store the result in var is_success
$is_success = $status >= 200 && $status < 300;
return ['code' => $status, 'result' => $result, 'is_success' => $is_success];
}
public function turnTFA($userId)
{
$credentials = $this->getCredentials($this->accessToken, $userId);
//now loop over $credentials, looking for 'otp' type
foreach ($credentials as $credential) {
if ($credential['type'] == 'otp') {
$result = $this->removeCredential($this->accessToken, $userId, $credential['id']);
}
}
//now get the credentials again to confirm it's been deleted
$credentials = $this->getCredentials($this->accessToken, $userId);
}
public static function url($url)
{
$idServer = new IdServer();
$opts = array(
'http' =>
array(
'method' => 'GET',
'header' => 'Authorization: Bearer ' . $idServer->accessToken,
)
);
$context = stream_context_create($opts);
$hdrs = get_headers($url, true, $context);
header('Content-Type: ' . $hdrs['Content-Type']);
readfile($url, false, $context);
}
public static function getImg($id)
{
return \Yii::$app->params['portal'] . '/file-system/delivery/' . $id . '/';
}
public static function getVideoThumb($id)
{
return \Yii::$app->params['portal'] . '/file-system/video-thumb/' . $id . '/';
}
public static function getStreaming($id)
{
return \Yii::$app->params['portal'] . '/file-system/stream/' . $id . '/';
}
public static function getImgToResize($id) {
return \Yii::$app->params['portal'] . '/file-system/delivery-img/'.$id.'/';
}
}
@@ -0,0 +1,34 @@
<?php
namespace app\services;
class JR
{
const not_authenticated = 'not_authenticated';
const done = 'done';
const error = 'false';
public static function message($key, $data = [])
{
header('Content-type: application/json');
$message = '';
$success = false;
switch ($key) {
case self::not_authenticated:
$message = 'User is not authenticated';
break;
case self::done:
$message = 'Response is OK';
$success = true;
break;
case self::error:
$message = 'Something went wrong';
}
echo json_encode(array_merge(['success' => $success, 'message' => $message], $data));
exit;
}
}
@@ -0,0 +1,192 @@
<?php
namespace app\services;
/**
* Class JWT
* @package app\services
*/
class JWT
{
const SECRET_KEY = '@#dk54!3fer';
/**
* Decodes a JWT string into a PHP object.
*
* @param string $jwt The JWT
* @param string|null $key The secret key
* @param bool $verify Don't skip verification process
*
* @return object The JWT's payload as a PHP object
* @throws \UnexpectedValueException Provided JWT was invalid
* @throws \DomainException Algorithm was not provided
*
* @uses jsonDecode
* @uses urlsafeB64Decode
*/
public static function decode($jwt, $key = null, $verify = true)
{
$tks = explode('.', $jwt);
if (count($tks) != 3) {
throw new \UnexpectedValueException('Wrong number of segments');
}
list($headb64, $bodyb64, $cryptob64) = $tks;
if (null === ($header = JWT::jsonDecode(JWT::urlsafeB64Decode($headb64)))) {
throw new \UnexpectedValueException('Invalid segment encoding');
}
if (null === $payload = JWT::jsonDecode(JWT::urlsafeB64Decode($bodyb64))) {
throw new \UnexpectedValueException('Invalid segment encoding');
}
$sig = JWT::urlsafeB64Decode($cryptob64);
if ($verify) {
if (empty($header->alg)) {
throw new \DomainException('Empty algorithm');
}
if ($sig != JWT::sign("$headb64.$bodyb64", $key, $header->alg)) {
throw new \UnexpectedValueException('Signature verification failed');
}
}
return $payload;
}
/**
* Converts and signs a PHP object or array into a JWT string.
*
* @param object|array $payload PHP object or array
* @param string $key The secret key
* @param string $algo The signing algorithm. Supported
* algorithms are 'HS256', 'HS384' and 'HS512'
*
* @return string A signed JWT
* @uses jsonEncode
* @uses urlsafeB64Encode
*/
public static function encode($payload, $key, $algo = 'HS256')
{
$header = array('typ' => 'JWT', 'alg' => $algo);
$segments = array();
$segments[] = JWT::urlsafeB64Encode(JWT::jsonEncode($header));
$segments[] = JWT::urlsafeB64Encode(JWT::jsonEncode($payload));
$signing_input = implode('.', $segments);
$signature = JWT::sign($signing_input, $key, $algo);
$segments[] = JWT::urlsafeB64Encode($signature);
return implode('.', $segments);
}
/**
* Sign a string with a given key and algorithm.
*
* @param string $msg The message to sign
* @param string $key The secret key
* @param string $method The signing algorithm. Supported
* algorithms are 'HS256', 'HS384' and 'HS512'
*
* @return string An encrypted message
* @throws \DomainException Unsupported algorithm was specified
*/
public static function sign($msg, $key, $method = 'HS256')
{
$methods = array(
'HS256' => 'sha256',
'HS384' => 'sha384',
'HS512' => 'sha512',
);
if (empty($methods[$method])) {
throw new \DomainException('Algorithm not supported');
}
return hash_hmac($methods[$method], $msg, $key, true);
}
/**
* Decode a JSON string into a PHP object.
*
* @param string $input JSON string
*
* @return object Object representation of JSON string
* @throws \DomainException Provided string was invalid JSON
*/
public static function jsonDecode($input)
{
$obj = json_decode($input);
if (function_exists('json_last_error') && $errno = json_last_error()) {
JWT::_handleJsonError($errno);
} else if ($obj === null && $input !== 'null') {
throw new \DomainException('Null result with non-null input');
}
return $obj;
}
/**
* Encode a PHP object into a JSON string.
*
* @param object|array $input A PHP object or array
*
* @return string JSON representation of the PHP object or array
* @throws \DomainException Provided object could not be encoded to valid JSON
*/
public static function jsonEncode($input)
{
$json = json_encode($input);
if (function_exists('json_last_error') && $errno = json_last_error()) {
JWT::_handleJsonError($errno);
} else if ($json === 'null' && $input !== null) {
throw new \DomainException('Null result with non-null input');
}
return $json;
}
/**
* Decode a string with URL-safe Base64.
*
* @param string $input A Base64 encoded string
*
* @return string A decoded string
*/
public static function urlsafeB64Decode($input)
{
$remainder = strlen($input) % 4;
if ($remainder) {
$padlen = 4 - $remainder;
$input .= str_repeat('=', $padlen);
}
return base64_decode(strtr($input, '-_', '+/'));
}
/**
* Encode a string with URL-safe Base64.
*
* @param string $input The string you want encoded
*
* @return string The base64 encode of what you passed in
*/
public static function urlsafeB64Encode($input)
{
return str_replace('=', '', strtr(base64_encode($input), '+/', '-_'));
}
/**
* Helper method to create a JSON error.
*
* @param int $errno An error number from json_last_error()
*
* @return void
*/
private static function _handleJsonError($errno)
{
$messages = array(
JSON_ERROR_DEPTH => 'Maximum stack depth exceeded',
JSON_ERROR_CTRL_CHAR => 'Unexpected control character found',
JSON_ERROR_SYNTAX => 'Syntax error, malformed JSON'
);
throw new \DomainException(
isset($messages[$errno])
? $messages[$errno]
: 'Unknown JSON error: ' . $errno
);
}
}
@@ -0,0 +1,91 @@
<?php
namespace app\services;
require $_SERVER['DOCUMENT_ROOT'] . '/extensions/phpmailer/PHPMailer.php';
require $_SERVER['DOCUMENT_ROOT'] . '/extensions/phpmailer/SMTP.php';
require $_SERVER['DOCUMENT_ROOT'] . '/extensions/phpmailer/Exception.php';
use extensions\phpmailer\PHPMailer;
use extensions\phpmailer\SMTP;
use extensions\phpmailer\Exception;
class MailService
{
public static function mail($email, $subject, $body)
{
/*$mail = new PHPMailer(true);
try {
//Server settings
$mail->SMTPDebug = SMTP::DEBUG_SERVER; //Enable verbose debug output
$mail->isSMTP(); //Send using SMTP
$mail->Host = '172.16.1.3'; //Set the SMTP server to send through
$mail->SMTPAuth = false; //Enable SMTP authentication
//$mail->Username = 'user@example.com'; //SMTP username
//$mail->Password = 'secret'; //SMTP password
$mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS; //Enable implicit TLS encryption
$mail->Port = 465; //TCP port to connect to; use 587 if you have set `SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS`
//Recipients
$mail->setFrom('coe@nasledstvo.bg', 'Mailer');
$mail->addAddress($email, 'Heritage BG'); //Add a recipient
//$mail->addAddress('ellen@example.com'); //Name is optional
//$mail->addReplyTo('info@example.com', 'Information');
//$mail->addCC('cc@example.com');
//$mail->addBCC('bcc@example.com');
//Attachments
//$mail->addAttachment('/var/tmp/file.tar.gz'); //Add attachments
//$mail->addAttachment('/tmp/image.jpg', 'new.jpg'); //Optional name
//Content
$mail->isHTML(true); //Set email format to HTML
$mail->Subject = $subject;
$mail->Body = $body;
$mail->AltBody = strip_tags($body);
$mail->send();
echo 'Message has been sent';
exit;
} catch (Exception $e) {
echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
exit;
}*/
//ini_set("SMTP", "172.16.1.3");
//ini_set("sendmail_from", "coe@nasledstvo.bg");
//ini_set("smtp_port", "25");
// The message
$message = "This is a test email";
$subject = "Heritage BG";
$headers = "From: coe@nasledstvo.bg";
$email = "mdkrustev@gmail.com";
//mail($email, $subject, $message, $headers);
}
public static function mailer($email, $sendEmail, $body, $subject)
{
if ($sendEmail) {
$headers = 'Content-type: text/html; charset=UTF-8' . "\r\n";
$headers .= 'From: ' . $email . "\r\n";
$headers .= 'Reply-To: ' . $email . "\r\n";
$headers .= 'X-Mailer: PHP/' . phpversion();
$headers .= "X-Priority: 3\r\n";
if (is_array($sendEmail)) {
foreach ($sendEmail as $to)
$headers .= 'Cc: ' . $to . "\r\n";
} else {
$headers .= 'Cc: ' . $sendEmail . "\r\n";
}
}
try {
mail($to, 'Re: ' . $subject, $body, $headers);
} catch (\Exception $exception) {
die('Message not sent');
}
}
}
@@ -0,0 +1,122 @@
<?php
namespace app\services;
use app\models\Ts;
use app\models\UserSession;
class OpenIdService
{
private $client_id;
private $client_secret;
private $redirect_uri;
private $metadata_url;
public function __construct()
{
$this->redirect_uri = \Yii::$app->params['portal'] . '/' . \Yii::$app->language . '/user/checkout/';
$this->metadata_url = \Yii::$app->params['id_server'] . '/realms/' . \Yii::$app->params['realm'] . '/.well-known/openid-configuration';
$this->client_id = \Yii::$app->params['id_server_client_id'];
$this->client_secret = \Yii::$app->params['id_server_client_secret'];
}
public function authenticationServerCheckout()
{
$metadata = $this->http($this->metadata_url);
if (!isset($_GET['code'])) {
$_SESSION['state_public'] = bin2hex(random_bytes(5));
$_SESSION['code_verifier_public'] = bin2hex(random_bytes(50));
$code_challenge = $this->base64_urlencode(hash('sha256', $_SESSION['code_verifier_public'], true));
$authorize_url = $metadata->authorization_endpoint . '?' . http_build_query([
'response_type' => 'code',
'client_id' => $this->client_id,
'redirect_uri' => $this->redirect_uri,
'state' => $_SESSION['state_public'],
'scope' => 'openid profile',
'code_challenge' => $code_challenge,
'code_challenge_method' => 'S256',
]);
header("Location: $authorize_url");
exit;
} else {
if ($_SESSION['state_public'] != $_GET['state']) {
die('Authorization server returned an invalid state parameter');
}
if (isset($_GET['error'])) {
die('Authorization server returned an error: ' . htmlspecialchars($_GET['error']));
}
$response = $this->http($metadata->token_endpoint, [
'grant_type' => 'authorization_code',
'code' => $_GET['code'],
'redirect_uri' => $this->redirect_uri,
'client_id' => $this->client_id,
'client_secret' => $this->client_secret,
'code_verifier' => $_SESSION['code_verifier_public'],
]);
if (!isset($response->access_token)) {
die('Error fetching access token');
}
$userinfo = $this->http($metadata->userinfo_endpoint, [
'access_token' => $response->access_token,
]);
if (isset($userinfo->group_membership)) {
if (in_array('/public_user', $userinfo->group_membership)) {
if ($userinfo->sub) {
Auth::checkUserExists($userinfo->preferred_username);
$_SESSION['sub'] = $userinfo->sub;
$_SESSION['profile'] = $userinfo;
Auth::setUser($userinfo->preferred_username);
$user = Auth::getUser();
if ($user) {
$user->open_id = $userinfo->sub;
$user->save();
UserSession::log('public', 1, $userinfo->sub);
}
$_SESSION['id_token_hint'] = $response->id_token;
header('Location: ' . \Yii::$app->goToAction('user'));
exit;
}
} else {
Ts::set([202, 218, 73]);
$roles = !empty($userinfo->realm_access) && $userinfo->realm_access->roles ? $userinfo->realm_access->roles : [];
$session_type = (in_array('superAdmin', $roles)) ? 'admin' : 'partner';
UserSession::log($session_type, 2, $userinfo->sub);
$_SESSION['register_user'] = $userinfo->sub;
$_SESSION['id_token_hint'] = $response->id_token;
header('Location: ' . \Yii::$app->goHome());
exit;
}
} else {
Ts::set([203]);
\Yii::$app->flash('error', Ts::get(203));
header('Location: ' . \Yii::$app->goHome());
exit;
}
}
}
private function http($url, $params = false)
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
if ($params)
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
return json_decode(curl_exec($ch));
}
private function base64_urlencode($string)
{
return rtrim(strtr(base64_encode($string), '+/', '-_'), '=');
}
}
@@ -0,0 +1,17 @@
<?php
namespace app\services;
class UrlReg {
public static function generate() {
if(!empty(\Yii::$app->params['locale_switch'])){
$localeSwitch = \Yii::$app->params['locale_switch'];
return (object)[
'locale' => \Yii::$app->language == 'bg' ? 'en' : 'bg',
'uri' => $localeSwitch[\Yii::$app->language]
];
} else {
echo 'Local switch is empty';
exit;
}
}
}
@@ -0,0 +1,170 @@
<?php
namespace app\services;
use app\models\Inquiries;
use app\models\register\PhplistUserUser;
use app\models\UserPublic;
use app\services\base\UserRequestBase;
use app\models\Ts;
use yii\base\BaseObject;
class UserRequest extends UserRequestBase
{
protected function signUp()
{
Ts::set([63, 64, 65, 66, 67, 68, 69, 70, 71]);
$this->isEmpty('full_name', Ts::get(63));
$this->isEmpty('email', Ts::get(64));
$this->isNotEmail('email', Ts::get(65));
$this->isExists('email', UserPublic::class, Ts::get(66));
$this->isNotSecurePassword('password', Ts::get(67));
$this->isNotMatch('cPassword', 'password', Ts::get(68));
$this->isNotChecked('has_terms', Ts::get(69));
$this->isNotChecked('has_privacy', Ts::get(197));
//$this->isNotChecked('has_cookies', Ts::get(70));
//$this->isEmpty('g-recaptcha-response', Ts::get(71));
//reCaptcha
//$secret = '6LcD2C4hAAAAAMZNC8E0XAoB2nbW29DrFlWPU5vJ';
//$response = $this->data->{'g-recaptcha-response'};
//$remoteip = $_SERVER['REMOTE_ADDR'];
//$url = "https://www.google.com/recaptcha/api/siteverify?secret=$secret&response=$response&remoteip=$remoteip";
//$data = file_get_contents($url);
//$row = json_decode($data, true);
$full_name = explode(' ', $this->data->{'full_name'});
$firstName = $full_name[0];
$lastName = $full_name[1] ?? $firstName;
//if ($row['success'] == "true") {
//Create user into cms database
$user = new UserPublic();
$user->email = $this->data->{'email'};
$user->full_name = $this->data->{'full_name'};
//$user->password = $this->data->{'password'};
$user->setPasswordHash($this->data->{'password'});
if ($this->data->{'has_club_card'} == true)
$user->club_card = 1;
if (!empty($this->data->{'has_double_auth'}) && $this->data->{'has_double_auth'} == true)
$user->has_double_auth = 1;
if (!empty($this->data->{'has_newsletter'}) && $this->data->{'has_newsletter'} == true) {
$user->has_newsletter = 1;
PhplistUserUser::add($user->email);
}
$user->user_agent = $_SERVER['HTTP_USER_AGENT'];
if (!empty($_GET['device_id']))
$user->device_id = $_GET['device_id'];
$user->date_registered = date('Y-m-d H:i:s');
$user->save();
$requiredActions = [];
if (!empty($this->data->{'has_double_auth'}) && $this->data->{'has_double_auth'} == true) {
$requiredActions[] = 'CONFIGURE_TOTP';
}
$requiredActions[] = 'VERIFY_EMAIL';
//Create user into Identity server
$idServer = new IdServer();
$idsResponse = $idServer->customPostRequest('/users', [
'enabled' => true,
'username' => $this->data->{'email'},
'email' => $this->data->{'email'},
'firstName' => $firstName,
'lastName' => $lastName,
'credentials' => [
[
'type' => 'password',
'value' => $this->data->{'password'},
'temporary' => false
],
],
'requiredActions' => $requiredActions,
//'requiredActions' => [
// 'CONFIGURE_TOTP',
// 'VERIFY_EMAIL'
//],
'groups' => ['public_user'],
'attributes' => [
'locale' => 'bg'
]
]);
return ['recaptcha-validated' => 1, 'id-server-response' => $idsResponse];
//}
}
protected function contact()
{
Ts::set([63, 64, 65]);
$this->isEmpty('full_name', Ts::get(63));
$this->isEmpty('email', Ts::get(64));
$this->isNotEmail('email', Ts::get(65));
$html = "<div>Име: " . $this->data->{'full_name'} . "</div>";
$html .= "<div>Е-mail: " . $this->data->{'email'} . "</div>";
if ($this->data->{"koo"})
$html .= "<div>" . $this->data->{"koo"} . "</div>";
if ($this->data->{"wwr"})
$html .= "<div>" . $this->data->{"wwr"} . "</div>";
$inq = new Inquiries();
$inq->email = $this->data->{'email'};
$inq->name = $this->data->{'full_name'};
$inq->operation = $this->data->{'koo'};
$inq->error = $this->data->{'wwr'};
$inq->date_time = date('Y-m-d H:i:s');
$inq->save();
//MailService::mailer($this->data->{'email'}, "coe@nasledstvo.bg", $html, 'Heritage BG Inquiry');
}
protected function editProfile()
{
Ts::set([63]);
$this->isEmpty('full_name', Ts::get(63));
$user = Auth::getUser();
$user->full_name = $this->data->{'full_name'};
$user->save();
}
function changePassword()
{
$this->isEmpty('old_password', Ts::get(212));
$this->wrongOldPassword('old_password', Ts::get(215));
$this->isEmpty('password', Ts::get(213));
$this->isNotSecurePassword('password', Ts::get(67));
$this->isEmpty('password_confirm', Ts::get(216));
$this->isNotMatch('password_confirm', 'password', Ts::get(68));
$password = $this->data->{'password'};
$user = Auth::getUser();
$user->password = $password;
$user->password_hash = password_hash($password, PASSWORD_DEFAULT);
$idServer = new IdServer();
$result = $idServer->updatePassword($user->open_id, $password);
if (!empty($result['is_success']) && $result['is_success']) {
$user->save();
}
$this->sendSuccess(Ts::get(214));
}
protected function setInvoiceData()
{
switch ($this->data->invoice_data_type) {
case 1:
$this->isEmpty('first_name', 'Моля попълнете име');
$this->isEmpty('last_name', 'Моля попълнете фамилия');
$this->isEmpty('country', 'Моля попълнете страна');
$this->isEmpty('city', 'Моля попълнете град или село');
$this->isEmpty('address', 'Моля попълнете адрес');
break;
case 2:
$this->isEmpty('company_name', 'Моля попълнете име на фирма');
$this->isEmpty('eik', 'Моля попълнете ЕИК');
$this->isEmpty('mol', 'Моля попълнете МОЛ');
}
setcookie('invoice_data', json_encode($this->data), time() + (86400 * 30), "/");
}
}
@@ -0,0 +1,203 @@
<?php
namespace app\services;
use app\models\Articles;
use app\models\Pages;
use app\models\parsed\ArticleParsedInterface;
use app\models\register\Partner;
class ViewReg
{
public static $pages = [
'news' => 'novini',
'events' => 'sabitia',
'campaigns' => 'kampanii',
'projects' => 'proekti',
'collections' => 'kolektsii',
'expositions' => 'ekspozitsii',
'objects' => 'obekti',
'partners' => 'partnjori',
'kolektsii-obekti' => 'collections-objects',
'collections-objects' => 'kolektsii-obekti',
'ekspozitsii-obekti' => 'expositions-objects',
'expositions-objects' => 'ekspozitsii-obekti',
'obekti' => 'objects',
'about-the-project' => 'otnosno-proekta',
'e-library' => 'e-biblioteka'
];
/**
* @param Pages | null $model
*/
public static function localeSwitch($model = null)
{
\Yii::$app->params['locale_switch'] = [
'bg' => '/en/' . ($model ? $model->slug_en . '/' : '') . self::appendQueryStr(),
'en' => '/bg/' . ($model ? $model->slug . '/' : '') . self::appendQueryStr(),
];
}
public static function localeSwitchArticle($table, Articles $model)
{
\Yii::$app->params['locale_switch'] = [
'bg' => '/en/' . $table . '/' . Formatter::encodeId($model->id) . '-' . Formatter::cyrillicTrans($model->article->title('en')) . '/' . self::appendQueryStr(),
'en' => '/bg/' . self::$pages[$table] . '/' . Formatter::encodeId($model->id) . '-' . Formatter::cyrillicTrans($model->article->title('bg')) . '/' . self::appendQueryStr(),
];
}
public static function localeSwitchPartnerArticle($table, Articles $model, $partnerSlug)
{
\Yii::$app->params['locale_switch'] = [
'bg' => '/en/partner/' . $partnerSlug . '/' . $table . '/' . Formatter::encodeId($model->id) . '-' . Formatter::cyrillicTrans($model->article->title('en')) . '/' . self::appendQueryStr(),
'en' => '/bg/partnjor/' . $partnerSlug . '/' . self::$pages[$table] . '/' . Formatter::encodeId($model->id) . '-' . Formatter::cyrillicTrans($model->article->title('bg')) . '/' . self::appendQueryStr(),
];
}
public static function localeSwitchUser()
{
$controllerAction = \Yii::$app->controller->id . '/' . \Yii::$app->controller->action->id . '/';
\Yii::$app->params['locale_switch'] = [
'bg' => '/en/' . $controllerAction,
'en' => '/bg/' . $controllerAction
];
}
public static function localeSwitchPage($table, $id, $title, $title_en)
{
\Yii::$app->params['locale_switch'] = [
'bg' => '/en/' . $table . '/' . Formatter::encodeId($id) . '-' . Formatter::cyrillicTrans($title_en) . '/' . self::appendQueryStr(),
'en' => '/bg/' . self::$pages[$table] . '/' . Formatter::encodeId($id) . '-' . Formatter::cyrillicTrans($title) . '/' . self::appendQueryStr(),
];
}
public static function localePartnerSwitchPage($table, $id, $title, $title_en)
{
\Yii::$app->params['locale_switch'] = [
'bg' => '/en/' . self::partnerSite('partner') . $table . '/' . Formatter::encodeId($id) . '-' . Formatter::cyrillicTrans($title_en) . '/' . self::appendQueryStr(),
'en' => '/bg/' . self::partnerSite('partnjor') . self::$pages[$table] . '/' . Formatter::encodeId($id) . '-' . Formatter::cyrillicTrans($title) . '/' . self::appendQueryStr(),
];
}
/* [Partner locale switches] */
/**
* @param Pages | null $model
*/
// Locale switch for index page
public static function partnerLocaleSwitch($partnerSlug, $model = null)
{
\Yii::$app->params['locale_switch'] = [
'bg' => '/en/' . self::partnerSite('partner') . ($model ? $model->slug_en . '/' : '') . self::appendQueryStr(),
'en' => '/bg/' . self::partnerSite('partnjor') . ($model ? $model->slug . '/' : '') . self::appendQueryStr(),
];
}
public static function find($page)
{
$slug = \Yii::$app->language == 'en' ? 'slug_en' : 'slug';
$foundPage = Pages::find()->where([$slug => $page])->one();
if ($foundPage) {
$file = $_SERVER['DOCUMENT_ROOT'] . '/views/site/inner-pages/' . $foundPage->slug . '.php';
if (file_exists($file)) {
return (object)[
'view' => "inner-pages/" . $foundPage->slug,
'model' => $foundPage
];
} else {
return (object)[
'view' => "template-pages/page",
'model' => $foundPage
];
}
}
return null;
}
public static function generateDetailPageUrl(Articles $article, $partner_id = null)
{
$lg = \Yii::$app->language;
$table = $lg == 'en' ? $article->art_table : self::$pages[$article->art_table];
if ($article->article) {
$slug = Formatter::cyrillicTrans($article->article->title());
return "/$lg/" . ViewReg::partnerSite() . "$table/" . Formatter::encodeId($article->id) . "-$slug/";
}
}
public static function generateDefaultDetailUrl($pagePart, $id, $title)
{
$part = self::$pages[$pagePart];
$lg = \Yii::$app->language;
if ($lg == 'en') {
$part = $pagePart;
}
$slug = Formatter::cyrillicTrans($title);
return "/$lg/" . ViewReg::partnerSite() . "$part/" . Formatter::encodeId($id) . "-$slug/";
}
public static function generateDirectDetailPageUrl(ArticleParsedInterface $article, $table)
{
$lg = \Yii::$app->language;
$table = $lg == 'en' ? $table : self::$pages[$table];
$slug = Formatter::cyrillicTrans($article->title());
return "/$lg/$table/" . Formatter::encodeId($article->id) . "-$slug/";
}
public static function goToPage($id, $query = '')
{
$lg = \Yii::$app->language;
$page = Pages::findOne($id);
if ($page) {
switch ($lg) {
default:
return '/' . $lg . '/' . self::partnerSite() . $page->slug . '/' . $query;
case 'en':
return '/' . $lg . '/' . self::partnerSite() . $page->slug_en . '/' . $query;
}
}
}
public static function generateListUrl($page)
{
$lg = \Yii::$app->language;
$table = $lg == 'en' ? $page : self::$pages[$page];
return "/$lg/" . ViewReg::partnerSite() . "$table/";
}
public static function generateArticleListUrl($partnerSlug = null)
{
$lg = \Yii::$app->language;
$partnerPage = $lg == 'en' ? 'partner' : 'partnjor';
$articlesPage = $lg == 'en' ? 'what-s-new' : 'kakvo-novo';
if ($partnerSlug)
return "/$lg/$partnerPage/$partnerSlug/$articlesPage/";
return "/$lg/$articlesPage/";
}
public static function partnerSite($p = null)
{
$partnerSite = '';
if (\Yii::$app->controller->partnerSlug) {
$partner = \Yii::$app->language == 'en' ? 'partner' : 'partnjor';
if ($p)
$partner = $p;
$partnerSite = $partner . '/' . \Yii::$app->controller->partnerSlug . '/';
}
return $partnerSite;
}
public static function appendQueryStr()
{
$q = $_SERVER['QUERY_STRING'] ?? '';
return $q ? '?' . $q : '';
}
}
@@ -0,0 +1,152 @@
<?php
namespace app\services;
use app\models\register\Collections;
use app\models\RegisterObjects;
class ZipCollection
{
public static function zipByCollectionId()
{
if (!empty(empty($_GET['id']))) {
echo json_encode(['error' => true, 'missing token_id']);
exit;
}
if (!Auth::getUser()) {
echo json_encode(['error' => true, 'User is not authorised']);
exit;
}
$decode = JWT::decode($_GET['id'], JWT::SECRET_KEY);
$user_id = Auth::getUser()->id;
$cDir = $_SERVER['DOCUMENT_ROOT'] . '/_temp_files';
$object = RegisterObjects::findOne($decode->object_id);
$object_name = $user_id . '-' . $object->id;
$object_dir = $cDir . '/' . $object_name;
$files_to_remove_later = [];
if (!file_exists($object_dir))
mkdir($object_dir, 0777, true);
$object_path = $object_dir . '/' . Formatter::cyrillicTrans($object->name);
if (!file_exists($object_path))
mkdir($object_path, 0777, true);
if ($object) {
foreach ($object->registerObjectImages as $image) {
$files_to_remove_later[] = $image->getCopyImg($object_path);
}
}
$zipFile = $object_path . '.zip';
$zipName = Formatter::cyrillicTrans($object->name) . '.zip';
$zip = new \ZipArchive();
if ($zip->open($zipFile, \ZipArchive::CREATE) === TRUE) {
// Add all files and subdirectories to the zip file
$files = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($object_dir));
foreach ($files as $file) {
if (!$file->isDir()) {
$filePath = $file->getRealPath();
$relativePath = substr($filePath, strlen($object_path) + 1);
$zip->addFile($filePath, $relativePath);
}
}
// Close the zip file
$zip->close();
}
echo json_encode(['success' => true, 'zipName' => $zipName, 'zipFile' => $zipFile, 'object_dir' => $object_dir]);
exit;
}
public static function downloadZip() {
foreach (['zipName', 'zipFile', 'object_dir'] as $param) {
if(empty($_GET[$param])) {
echo 'missing: '. $param;
exit;
}
}
$zipFile = $_GET['zipFile'];
$zipName = $_GET['zipName'];
$object_dir = $_GET['object_dir'];
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="' . $zipName . '"');
header('Content-Length: ' . filesize($zipFile));
readfile($zipFile);
if(file_exists($zipFile))
unlink($zipFile);
if (is_dir($object_dir)) {
$files = array_diff(scandir($object_dir), array('.', '..'));
foreach ($files as $file) {
$path = $object_dir . '/' . $file;
if (is_dir($path)) {
self::rrmdir($path);
} else {
unlink($path);
}
}
rmdir($object_dir);
}
echo json_encode(['success' => true]);
exit;
}
private static function compressImage($tempPath, $originalPath, $imageQuality)
{
//return $tempPath. '<br>'. $originalPath . '<br>';
// Get image info
$imgInfo = getimagesize($tempPath);
$mime = $imgInfo['mime'];
// Create a new image from file
switch ($mime) {
case 'image/jpeg':
$image = imagecreatefromjpeg($tempPath);
break;
case 'image/png':
$image = imagecreatefrompng($tempPath);
break;
case 'image/gif':
$image = imagecreatefromgif($tempPath);
break;
default:
$image = imagecreatefromjpeg($tempPath);
}
//$imgResized = imagescale($image, 350);
// Save image
imagejpeg($image, $originalPath, $imageQuality);
//imagedestroy($image);
// Return compressed image
//return $originalPath;
}
// Recursive function to delete a directory and its contents
private static function rrmdir($dir)
{
if (is_dir($dir)) {
$files = array_diff(scandir($dir), array('.', '..'));
foreach ($files as $file) {
$path = $dir . '/' . $file;
if (is_dir($path)) {
self::rrmdir($path);
} else {
unlink($path);
}
}
rmdir($dir);
}
}
}
@@ -0,0 +1,88 @@
<?php
namespace app\services\base;
class IdServerBase
{
public $accessToken;
protected function securePostRequest($path, $data)
{
if ($this->accessToken) {
$root = \Yii::$app->params['id_server']."/admin/realms/nasledstvo.bg";
$url = $root . $path;
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$headers = array(
"content-type: application/json",
"Authorization: bearer $this->accessToken",
);
$data = json_encode($data);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
$resp = curl_exec($curl);
curl_close($curl);
return json_decode($resp);
}
}
protected function secureGetRequest($path)
{
if ($this->accessToken) {
$root = \Yii::$app->params['id_server']."/admin/realms/nasledstvo.bg";
$url = $root . $path;
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$headers = array(
"Authorization: bearer $this->accessToken",
);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
$resp = curl_exec($curl);
curl_close($curl);
return json_decode($resp);
}
}
protected function auth()
{
$url = \Yii::$app->params['id_server']."/realms/nasledstvo.bg/protocol/openid-connect/token";
$clint_id = \Yii::$app->params['id_server_client_id'];
$clint_secret = \Yii::$app->params['id_server_client_secret'];
$username = \Yii::$app->params['id_server_admin_user'];
$password = \Yii::$app->params['id_server_admin_password'];
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$headers = array(
"Content-Type: application/x-www-form-urlencoded",
);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
$data = "client_id=$clint_id&client_secret=$clint_secret&username=$username&password=$password&grant_type=password";
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
$resp = curl_exec($curl);
curl_close($curl);
$respData = json_decode($resp);
if (!empty($respData->access_token))
$this->accessToken = $respData->access_token;
}
}
@@ -0,0 +1,81 @@
<?php
namespace app\services\base;
use app\services\Auth;
class UserRequestBase
{
protected $data;
protected function isEmpty($key, $message)
{
if (empty($this->data->{$key})) $this->sendError($key, $message);
}
protected function isNotEmail($key, $message)
{
if (!filter_var($this->data->{$key}, FILTER_VALIDATE_EMAIL)) $this->sendError($key, $message);
}
protected function isExists($key, $classModel, $message)
{
$exists = $classModel::find()->where([$key => $this->data->{$key}])->one();
if ($exists) $this->sendError($key, $message);
}
protected function isNotSecurePassword($key, $message)
{
$value = $this->data->{$key};
if (mb_strlen($value) < 6)
$this->sendError($key, $message);
}
protected function wrongOldPassword($key, $message)
{
$value = $this->data->{$key};
$user = Auth::getUser();
if (!password_verify($value, $user->password_hash))
$this->sendError($key, $message);
}
protected function isNotMatch($key, $matchKey, $message)
{
if ($this->data->{$key} != $this->data->{$matchKey})
$this->sendError($key, $message);
}
protected function isNotChecked($key, $message)
{
if ($this->data->{$key} != true)
$this->sendError($key, $message);
}
public function call($method)
{
if (method_exists($this, $method)) {
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$this->data = json_decode(\Yii::$app->request->getRawBody());
$result = $this->{$method}();
$result = $result ?? (object)[];
echo json_encode(['success' => 1, 'data' => $result]);
exit;
}
}
}
private function sendError($key, $message)
{
header('Content-type: application/json');
echo json_encode(['error' => ['key' => $key, 'message' => $message]]);
exit;
}
public function sendSuccess($message)
{
header('Content-type: application/json');
echo json_encode(['success' => ['message' => $message]]);
exit;
}
}
@@ -0,0 +1,217 @@
<?php
namespace app\services\epay;
class EPay
{
const API_MODE_DEMO = 'demo';
const API_MODE_LIVE = 'live';
/**
* @var string
*/
private $apiMode;
/**
* @var string
*/
private $ePayDemoEnvironmentUrl;
/**
* @var string
*/
private $ePayLiveEnvironmentUrl;
/**
* @var string
*/
private $apiClientEmail;
/**
* @var array
*/
private $authenticationDemo;
/**
* @var array
*/
private $authenticationLive;
/**
* @var array
*/
private $postFields = [];
/**
* EPayHelper set method.
* @param string $apiMode
* @param string $ePayDemoEnvironmentUrl
* @param string $ePayLiveEnvironmentUrl
* @param string $apiClientEmail
* @param array $authenticationDemo
* @param array $authenticationLive
*/
public function setData($apiMode, $ePayDemoEnvironmentUrl, $ePayLiveEnvironmentUrl, $apiClientEmail, array $authenticationDemo, array $authenticationLive)
{
$this->apiMode = $apiMode;
$this->ePayDemoEnvironmentUrl = $ePayDemoEnvironmentUrl;
$this->ePayLiveEnvironmentUrl = $ePayLiveEnvironmentUrl;
$this->apiClientEmail = $apiClientEmail;
$this->authenticationDemo = $authenticationDemo;
$this->authenticationLive = $authenticationLive;
}
public function getEPayUrl()
{
if ($this->apiMode == self::API_MODE_DEMO) {
return $this->ePayDemoEnvironmentUrl;
} else {
return $this->ePayLiveEnvironmentUrl;
}
}
/**
* @param EPayPayment $ePayPayment
* @param bool $directCard
* @param array $order
* @return void
* @throws \Exception
*/
public function prepareEPayPaymentFormFields($ePayPayment, $directCard = false)
{
$now = new \DateTime("+5 min");
$dataFields = [];
$postFields = [];
$dataFields['MIN'] = $this->getApiClientId();
$dataFields['INVOICE'] = (string)$ePayPayment->getInvoiceNumber();
$amount = (float)$ePayPayment->getAmount();
$paymentAmount = $amount;
$dataFields['AMOUNT'] = number_format($paymentAmount, 2);
$dataFields['CURRENCY'] = 'BGN';
$dataFields['EXP_TIME'] = $now->format('d.m.Y H:i:s');
$dataFields['DESCR'] = $ePayPayment->getDescription();
$dataFields['ENCODING'] = 'utf-8';
$dataFields['ORDERID'] = $ePayPayment->getOrderId();
$data = $this->getDataFieldsAsString($dataFields);
$encodedData = base64_encode($data);
//$checksum = $this->getHash($encodedData);
$checksum = $this->generateChecksum($encodedData);
if (!$directCard) {
$postFields['PAGE'] = 'paylogin';
} else {
$postFields['PAGE'] = 'credit_paydirect';
}
if($directCard) {
$postFields['LANG'] = 'bg';
}
$postFields['ENCODED'] = $encodedData;
$postFields['CHECKSUM'] = $checksum;
$postFields['URL_OK'] = $ePayPayment->getUrlOk();
$postFields['URL_CANCEL'] = $ePayPayment->getUrlCancel();
$this->postFields = $postFields;
}
public function postSubmit()
{
//echo json_encode($this->postFields);
//exit;
if (sizeof($this->postFields) > 0) {
$form = '<html><body onload="document.forms[\'ePay\'].submit()">';
$form .= '<form action="' . $this->getEPayUrl() . '" name="ePay" method="post">';
foreach ($this->postFields as $key => $value) {
$form .= '<input type="hidden" name="' . $key . '" value="' . $value . '">';
}
$form .= '</form>';
$form .= '</body></html>';
echo $form;
}
}
/**
* @param array $dataFields
* @return string
*/
private function getEncodedDataFieldsAsString($dataFields)
{
return JWT::encode($dataFields, JWT::SECRET_KEY);
}
private function getDataFieldsAsString($dataFields)
{
$data = '';
foreach ($dataFields as $key => $value) {
$data .= "$key=$value" . PHP_EOL;
}
return $data;
}
/**
* @param string $data
* @return string
*/
private function generateChecksum($data)
{
$algorithm = 'sha1';
$password = $this->getApiClientSecret();
$p = ['md5' => 'H32', 'sha1' => 'H40'];
if (strlen($password) > 64) {
$password = pack($p[$algorithm], $algorithm($password));
}
if (strlen($password) < 64) {
$password = str_pad($password, 64, chr(0));
}
$iPad = substr($password, 0, 64) ^ str_repeat(chr(0x36), 64);
$oPad = substr($password, 0, 64) ^ str_repeat(chr(0x5C), 64);
return ($algorithm($oPad . pack($p[$algorithm], $algorithm($iPad . $data))));
}
private function getHash($data) {
$algorithm = 'sha1';
$password = $this->getApiClientSecret();
return hash_hmac($algorithm, $data, $password);
}
private function getApiClientSecret()
{
if ($this->apiMode == self::API_MODE_DEMO) {
return $this->authenticationDemo['client_secret'];
} else {
return $this->authenticationLive['client_secret'];
}
}
private function getApiClientId()
{
if ($this->apiMode == self::API_MODE_DEMO) {
return $this->authenticationDemo['client_identifier'];
} else {
return $this->authenticationLive['client_identifier'];
}
}
public function getOrder($encoded)
{
$decodeArray = explode(':', base64_decode($encoded));
$responseData = [];
foreach ($decodeArray as $keyValueStr) {
$keyValueArray = explode('=', $keyValueStr);
if (sizeof($keyValueArray) == 2)
$responseData[$keyValueArray[0]] = $keyValueArray[1];
}
if (isset($responseData['INVOICE']) && isset($responseData['STATUS'])) {
return $responseData;
}
return null;
}
}
@@ -0,0 +1,179 @@
<?php
namespace app\services\epay;
class EPayPayment
{
/**
* This is int.
* Cast it to string when sending data to EPay!
* @var int
*/
private $invoiceNumber;
private $orderId;
/**
* @var float
*/
private $amount;
/**
* @var string
*/
private $currency;
/**
* @var string
*/
private $description;
/**
* @var string
*/
private $encoding = 'utf-8';
/**
* URL where the client should be redirected
* when payment is processed successfully.
* @var string
*/
private $urlOk;
/**
* URL where the client should be redirected
* in case they rejected payment.
* @var string
*/
private $urlCancel;
/**
* @return int
*/
public function getInvoiceNumber()
{
return $this->invoiceNumber;
}
/**
* @param int $invoiceNumber
*/
public function setInvoiceNumber($invoiceNumber)
{
$this->invoiceNumber = $invoiceNumber;
}
/**
* @return float
*/
public function getAmount()
{
return $this->amount;
}
/**
* @param float $amount
*/
public function setAmount($amount)
{
$this->amount = $amount;
}
/**
* @return string
*/
public function getCurrency()
{
return $this->currency;
}
/**
* @param string $currency
*/
public function setCurrency($currency)
{
$this->currency = $currency;
}
/**
* @return string
*/
public function getDescription()
{
return $this->description;
}
/**
* @param string $description
*/
public function setDescription($description)
{
$this->description = $description;
}
/**
* @return string
*/
public function getEncoding()
{
return $this->encoding;
}
/**
* @param string $encoding
*/
public function setEncoding($encoding)
{
$this->encoding = $encoding;
}
/**
* @return string
*/
public function getUrlOk()
{
return $this->urlOk;
}
/**
* @param string $urlOk
*/
public function setUrlOk($urlOk)
{
$this->urlOk = $urlOk;
}
/**
* @return string
*/
public function getUrlCancel()
{
return $this->urlCancel;
}
/**
* @param string $urlCancel
*/
public function setUrlCancel($urlCancel)
{
$this->urlCancel = $urlCancel;
}
/**
* @return mixed
*/
public function getOrderId()
{
return $this->orderId;
}
/**
* @param mixed $orderId
*/
public function setOrderId($orderId)
{
$this->orderId = $orderId;
}
}
@@ -0,0 +1,62 @@
<?php
namespace app\services\payment;
use app\models\Order;
use app\models\OrderPayment;
use app\services\payment\providers\epay\EPay;
class Payment
{
public static function getCheckOut(Order $order, $payment_method)
{
$payment = new OrderPayment();
$payment->order_id = $order->id;
$payment->payment_method = $payment_method;
$payment->amount = $order->total_price;
if ($order->user)
$payment->client_email = $order->user->email;
$payment->save();
switch ($payment->payment_method) {
case 'epay':
case 'card':
$directCard = $payment_method == 'card' ? true : false;
/** [ 3 February 2023 10:59 ] TodoR: Nasl
* [ 3 February 2023 11:00 ] TodoR: Naslk
* [ 3 February 2023 11:00 ] TodoR: 123456
*/
$epay = new EPay();
$epay->setData(EPay::API_MODE_LIVE, 'https://demo.epay.bg/', 'https://www.epay.bg/', $payment->client_email,
[
// DEMO DATA
'client_secret' => 'C6OCA0SZ8LYJN5E3UOE6PJD0ELMW9JL9BRNHEO1TI6M54H9K7JI69H4YZELASABA',
'client_identifier' => 'D727935809'
],
[
//REAL DATA
'client_secret' => 'HPLP2D7MA15NGXR5ZL85Y05P90VGW6S3XB6XBV2Q3UQ3V2HDIZB3Q6EYL0XFHNDD',
'client_identifier' => '1921938405'
]);
$epay->prepareEPayPaymentFormFields($epay->getEpayPaymentDetails($payment), $directCard);
$epay->postSubmit();
break;
}
return '';
}
public static function setPaymentNotification()
{
if (!empty($_GET['type'])) {
switch ($_GET['type']) {
case 'epay':
$epay = new EPay();
$epay->setNotification();
break;
}
}
exit;
}
}
@@ -0,0 +1,259 @@
<?php
namespace app\services\payment\providers\epay;
use app\models\OrderPayment;
use app\models\OrderPaymentNotification;
use app\services\JWT;
use yii\base\BaseObject;
class EPay
{
const API_MODE_DEMO = 'demo';
const API_MODE_LIVE = 'live';
private $apiMode;
private $ePayDemoEnvironmentUrl;
private $ePayLiveEnvironmentUrl;
private $authenticationDemo;
/**
* @var array
*/
private $authenticationLive;
/**
* @var array
*/
private $postFields = [];
/**
* EPayHelper set method.
* @param string $apiMode
* @param string $ePayDemoEnvironmentUrl
* @param string $ePayLiveEnvironmentUrl
* @param string $apiClientEmail
* @param array $authenticationDemo
* @param array $authenticationLive
*/
public function setData($apiMode, $ePayDemoEnvironmentUrl, $ePayLiveEnvironmentUrl, $apiClientEmail, array $authenticationDemo, array $authenticationLive)
{
$this->apiMode = $apiMode;
$this->ePayDemoEnvironmentUrl = $ePayDemoEnvironmentUrl;
$this->ePayLiveEnvironmentUrl = $ePayLiveEnvironmentUrl;
$this->apiClientEmail = $apiClientEmail;
$this->authenticationDemo = $authenticationDemo;
$this->authenticationLive = $authenticationLive;
}
public function getEPayUrl()
{
if ($this->apiMode == self::API_MODE_DEMO) {
return $this->ePayDemoEnvironmentUrl;
} else {
return $this->ePayLiveEnvironmentUrl;
}
}
/**
* @param EPayPayment $ePayPayment
* @param bool $directCard
* @param array $order
* @return void
* @throws \Exception
*/
public function prepareEPayPaymentFormFields($ePayPayment, $directCard = false)
{
$now = new \DateTime("+20 min");
$dataFields = [];
$postFields = [];
$dataFields['MIN'] = $this->getApiClientId();
$dataFields['INVOICE'] = (string)$ePayPayment->getInvoiceNumber();
$amount = (float)$ePayPayment->getAmount();
$paymentAmount = $amount;
$dataFields['AMOUNT'] = number_format($paymentAmount, 2);
$dataFields['CURRENCY'] = 'BGN';
$dataFields['EXP_TIME'] = $now->format('d.m.Y H:i:s');
$dataFields['DESCR'] = $ePayPayment->getDescription();
$dataFields['ENCODING'] = 'utf-8';
$dataFields['ORDERID'] = $ePayPayment->getOrderId();
$data = $this->getDataFieldsAsString($dataFields);
$encodedData = base64_encode($data);
//$checksum = $this->getHash($encodedData);
$checksum = $this->generateChecksum($encodedData);
if (!$directCard) {
$postFields['PAGE'] = 'paylogin';
} else {
$postFields['PAGE'] = 'credit_paydirect';
}
if ($directCard) {
$postFields['LANG'] = 'bg';
}
//echo $data;
//exit;
$postFields['ENCODED'] = $encodedData;
$postFields['CHECKSUM'] = $checksum;
$postFields['URL_OK'] = $ePayPayment->getUrlOk();
$postFields['URL_CANCEL'] = $ePayPayment->getUrlCancel();
//echo json_encode($dataFields);
//exit;
$this->postFields = $postFields;
}
public function postSubmit()
{
//echo json_encode($this->postFields);
//exit;
if (sizeof($this->postFields) > 0) {
$form = '<html><body onload="document.forms[\'ePay\'].submit()">';
$form .= '<form action="' . $this->getEPayUrl() . '" name="ePay" method="post">';
foreach ($this->postFields as $key => $value) {
$form .= '<input type="hidden" name="' . $key . '" value="' . $value . '">';
}
$form .= '</form>';
$form .= '</body></html>';
echo $form;
exit;
}
}
/**
* @param array $dataFields
* @return string
*/
private function getEncodedDataFieldsAsString($dataFields)
{
return JWT::encode($dataFields, JWT::SECRET_KEY);
}
private function getDataFieldsAsString($dataFields)
{
$data = '';
foreach ($dataFields as $key => $value) {
$data .= "$key=$value" . PHP_EOL;
}
return $data;
}
/**
* @param string $data
* @return string
*/
private function generateChecksum($data)
{
$algorithm = 'sha1';
$password = $this->getApiClientSecret();
$p = ['md5' => 'H32', 'sha1' => 'H40'];
if (strlen($password) > 64) {
$password = pack($p[$algorithm], $algorithm($password));
}
if (strlen($password) < 64) {
$password = str_pad($password, 64, chr(0));
}
$iPad = substr($password, 0, 64) ^ str_repeat(chr(0x36), 64);
$oPad = substr($password, 0, 64) ^ str_repeat(chr(0x5C), 64);
return ($algorithm($oPad . pack($p[$algorithm], $algorithm($iPad . $data))));
}
private function getHash($data)
{
$algorithm = 'sha1';
$password = $this->getApiClientSecret();
return hash_hmac($algorithm, $data, $password);
}
private function getApiClientSecret()
{
if ($this->apiMode == self::API_MODE_DEMO) {
return $this->authenticationDemo['client_secret'];
} else {
return $this->authenticationLive['client_secret'];
}
}
private function getApiClientId()
{
if ($this->apiMode == self::API_MODE_DEMO) {
return $this->authenticationDemo['client_identifier'];
} else {
return $this->authenticationLive['client_identifier'];
}
}
public function getOrder($encoded)
{
$decodeArray = explode(':', base64_decode($encoded));
$responseData = [];
foreach ($decodeArray as $keyValueStr) {
$keyValueArray = explode('=', $keyValueStr);
if (sizeof($keyValueArray) == 2)
$responseData[$keyValueArray[0]] = $keyValueArray[1];
}
if (isset($responseData['INVOICE']) && isset($responseData['STATUS'])) {
return $responseData;
}
return null;
}
public function getEpayPaymentDetails(OrderPayment $orderPayment)
{
$epayPayment = new EPayPayment();
$epayPayment->setEpayPayment($orderPayment);
return $epayPayment;
}
public function setNotification()
{
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (!empty($_POST['encoded'])) {
$paymentNotification = new OrderPaymentNotification();
$paymentNotification->message = base64_decode($_POST['encoded']);
$paymentNotification->date = date('Y-m-d H:i:s');
$paymentNotification->save();
$responseData = $this->encodedOrder($_POST['encoded']);
if($responseData) {
$response_message = 'INVOICE=' . $responseData['INVOICE'] . ':STATUS=OK';
$order_payment = OrderPayment::find()->where(['order_id' => (int)$responseData['INVOICE']])->one();
$order_payment->status = $responseData['STATUS'];
$order_payment->response_message = $response_message;
$order_payment->response_time = date('Y-m-d H:i:s');
$order_payment->save();
echo $response_message;
}
}
}
exit;
}
public function encodedOrder($encoded)
{
$decodeArray = explode(':', base64_decode($encoded));
$responseData = [];
foreach ($decodeArray as $keyValueStr) {
$keyValueArray = explode('=', $keyValueStr);
if (sizeof($keyValueArray) == 2)
$responseData[$keyValueArray[0]] = $keyValueArray[1];
}
if (isset($responseData['INVOICE']) && isset($responseData['STATUS'])) {
return $responseData;
}
return null;
}
}
@@ -0,0 +1,194 @@
<?php
namespace app\services\payment\providers\epay;
use app\models\OrderPayment;
class EPayPayment
{
/**
* This is int.
* Cast it to string when sending data to EPay!
* @var int
*/
private $invoiceNumber;
private $orderId;
/**
* @var float
*/
private $amount;
/**
* @var string
*/
private $currency;
/**
* @var string
*/
private $description;
/**
* @var string
*/
private $encoding = 'utf-8';
/**
* URL where the client should be redirected
* when payment is processed successfully.
* @var string
*/
private $urlOk;
/**
* URL where the client should be redirected
* in case they rejected payment.
* @var string
*/
private $urlCancel;
/**
* @return int
*/
public function getInvoiceNumber()
{
return $this->invoiceNumber;
}
/**
* @param int $invoiceNumber
*/
public function setInvoiceNumber($invoiceNumber)
{
$this->invoiceNumber = $invoiceNumber;
}
/**
* @return float
*/
public function getAmount()
{
return $this->amount;
}
/**
* @param float $amount
*/
public function setAmount($amount)
{
$this->amount = $amount;
}
/**
* @return string
*/
public function getCurrency()
{
return $this->currency;
}
/**
* @param string $currency
*/
public function setCurrency($currency)
{
$this->currency = $currency;
}
/**
* @return string
*/
public function getDescription()
{
return $this->description;
}
/**
* @param string $description
*/
public function setDescription($description)
{
$this->description = $description;
}
/**
* @return string
*/
public function getEncoding()
{
return $this->encoding;
}
/**
* @param string $encoding
*/
public function setEncoding($encoding)
{
$this->encoding = $encoding;
}
/**
* @return string
*/
public function getUrlOk()
{
return $this->urlOk;
}
/**
* @param string $urlOk
*/
public function setUrlOk($urlOk)
{
$this->urlOk = $urlOk;
}
/**
* @return string
*/
public function getUrlCancel()
{
return $this->urlCancel;
}
/**
* @param string $urlCancel
*/
public function setUrlCancel($urlCancel)
{
$this->urlCancel = $urlCancel;
}
/**
* @return mixed
*/
public function getOrderId()
{
return $this->orderId;
}
/**
* @param mixed $orderId
*/
public function setOrderId($orderId)
{
$this->orderId = $orderId;
}
public function setEpayPayment(OrderPayment $orderPayment) {
$this->setAmount($orderPayment->amount);
$isMobile = !empty($_GET['webview_mode']) ? '?webview_mode=1' : '';
$this->setUrlOk(\Yii::$app->params['portal'].'/'.\Yii::$app->language.'/user/finalize-order/'.$isMobile);
$this->setUrlCancel(\Yii::$app->params['portal'].'/'.\Yii::$app->language.'/user/finalize-order-cancel/'. $isMobile);
$this->setOrderId($orderPayment->order->id);
$this->setEncoding('utf-8');
$this->setCurrency('BGN');
$this->setDescription($orderPayment->order->getDescription());
$this->setInvoiceNumber($orderPayment->order_id);
$this->setOrderId($orderPayment->order_id);
}
}