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,91 @@
<?php
namespace app\services;
use app\models\UserAdminGlobal;
use app\models\UserPartner;
use app\models\UserSession;
class Auth
{
//region USER ADMIN GLOBAL
public static function userAdminGlobal()
{
if (isset($_SESSION['user_admin_global']))
return UserAdminGlobal::findOne($_SESSION['user_admin_global']);
return null;
}
public static function userAdminGlobalLogin($id, $redirect = null)
{
$_SESSION['user_admin_global'] = $id;
if ($redirect) {
UserSession::log('user_admin_global', 2, $id);
echo json_encode(['redirect' => $redirect]);
exit;
}
}
public static function userAdminGlobalLogout()
{
if (isset($_SESSION['user_admin_global'])) {
unset($_SESSION['user_admin_global']);
}
}
//endregion
//region USER ADMIN CMS
public static function userAdminCms()
{
if (isset($_SESSION['user_admin_cms']))
return UserAdminGlobal::findOne($_SESSION['user_admin_cms']);
return null;
}
public static function userAdminCmsLogin($id, $redirect = null)
{
$_SESSION['user_admin_cms'] = $id;
if ($redirect) {
echo json_encode(['redirect' => $redirect]);
exit;
}
}
public static function userAdminCmsLogout()
{
if (isset($_SESSION['user_admin_cms'])) {
unset($_SESSION['user_admin_cms']);
}
}
//endregion
//region USER PARTNER
public static function userPartner() {
if (isset($_SESSION['user_partner']))
return UserPartner::findOne($_SESSION['user_partner']);
return null;
}
public static function userPartnerLogin($id, $redirect = null)
{
$_SESSION['user_partner'] = $id;
if ($redirect) {
echo json_encode(['redirect' => $redirect]);
exit;
}
}
public static function userPartnerLogout()
{
if (isset($_SESSION['user_partner'])) {
unset($_SESSION['user_partner']);
}
}
//endregion
}
@@ -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 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);
}
public static $key_labels = [
'lib_variant' => 'Тип',
'lib_format' => 'Формат',
'lib_identifier_isbn_print' => 'ISBN (Print)',
'lib_identifier_isbn_online' => 'ISBN (Online)',
'lib_identifier_issn_print' => 'ISSN (Print)',
'lib_identifier_issn_online' => 'ISSN (Online)',
'lib_identifier_doi' => 'DOI',
'lib_identifier_ismn' => 'ISMN',
'lib_identifier_isan' => 'ISAN',
'lib_author_compiler' => 'Съставител',
'lib_author_translator' => 'Преводач',
'lib_author_editor' => 'Редактор',
'lib_author_reviewer' => 'Рецензент',
'lib_author_ilustrator' => 'Илюстратор',
'lib_language' => 'Език',
'lib_title_information' => 'Допълнение към заглавието',
'lib_title_parallel' => 'Паралелно заглавие',
'lib_edition' => 'Издание',
'lib_series' => 'Серия',
'lib_publisher_name' => 'Издател',
'lib_publication_place' => 'Място на публикуване',
'lib_url' => 'Url адрес',
'lib_article_source' => 'Източник на статията',
'lib_article_pages' => 'Страници от - до',
'lib_volume_source' => 'Том, книжка',
'lib_periodical_dimensions' => 'periodical dimensions',
'lib_pages' => 'Страници',
'lib_citation_apa' => 'APA цитиране',
'lib_citation_harvard' => 'Harvard цитиране',
'lib_publication_date' => 'Година на публикуване',
'lib_license' => 'Лиценз',
'lib_rights' => 'Авторски права'
];
}
@@ -0,0 +1,61 @@
<?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, '-');
}
public static function date($str_date, $format = 'd.m.Y H:i:s') {
return date($format, strtotime($str_date));
}
}
+201
View File
@@ -0,0 +1,201 @@
<?php
namespace app\services;
/**
* JSON Web Token implementation, based on this spec:
* http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-06
*
* PHP version 5
*
* @category Authentication
* @package Authentication_JWT
* @author Neuman Vong <neuman@twilio.com>
* @author Anant Narayanan <anant@php.net>
* @license http://opensource.org/licenses/BSD-3-Clause 3-clause BSD
* @link https://github.com/firebase/php-jwt
*/
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,66 @@
<?php
namespace app\services;
use app\controllers\PublicController;
use yii\db\ActiveRecord;
class Validate
{
/**
* @param string $uc
* @param $cb
* @return mixed|null
*/
public static function login(string $uc, $cb)
{
$p = self::getPost();
if (!$p) return null;
$email_login = $p('email_login');
$password = $p('password');
if (!$email_login)
self::error('email_login', 'This field is required');
if (!$password)
self::error('password', 'This field is required');
/** @var \app\models\_Base $uc */
$user = $uc::find()->where(['email_login' => $email_login])->one();
if (!$user)
self::error('email_login', 'Unknown email');
if (!$user->verifyPassword($password))
self::error('password', 'Wrong password');
if($user->is_active != 1)
self::error('email_login', 'This user is not active');
return $cb($user);
}
public static function defaultValidation($validation = null) {
if($validation) {
$key = array_keys($validation)[0];
self::error($key, $validation[$key], $validation[0] ?? []);
}
}
private static function error($field, $message, $params = [])
{
header('Content-type: application/json');
echo json_encode([
'error' => true,
'field' => $field,
'message' => \Yii::t('cms', $message, $params)
]);
exit;
}
private static function getPost()
{
if ($_SERVER['REQUEST_METHOD'] == 'POST')
return function ($param) {
if (isset($_POST[$param]))
return $_POST[$param];
return null;
};
}
}
@@ -0,0 +1,109 @@
<?php
namespace app\services\api;
use app\models\Categories;
use app\models\CategoriesOt;
use app\models\ObjectTemplate;
class NomenclatureService
{
public static function categorySelect()
{
$categories = Categories::find()->where(['IS', 'parent_id', NULL])->all();
$keyList = [];
foreach ($categories as $category) {
foreach ($category->subCategories as $subCategory) {
if ($subCategory->name) {
$keyList[] = [
'id' => $subCategory->id,
'name' => $category->name . ' - ' . $subCategory->name,
'name_en' => $category->ts_en_name . ' - ' . $subCategory->ts_en_name
];
}
}
}
return $keyList;
}
public static function categoryFilterSelect()
{
$heritage_type = null;
if (!empty($_GET['q'])) {
$f = explode('|', $_GET['q']);
foreach ($f as $fkv) {
$filter = explode(':', $fkv);
if($filter[0] == 'heritage_type' && !empty($filter[1]))
$heritage_type = $filter[1];
}
}
if($heritage_type) {
$ids = [];
$objectTemplates = ObjectTemplate::find()->where(['heritage_type' => $heritage_type])->all();
foreach ($objectTemplates as $objectTemplate) {
$ids[] = $objectTemplate->id;
}
}
$categories = Categories::find()->where(['IS', 'parent_id', NULL])->all();
$keyList = [];
foreach ($categories as $category) {
$subCategoryList = $heritage_type ? $category->getSubCategoriesByTemplate($ids) : $category->subCategories;
foreach ($subCategoryList as $subCategory) {
if ($subCategory->name) {
$keyList[$subCategory->id] = $category->name . ' - ' . $subCategory->name;
}
}
}
return $keyList;
}
public static function categoryTree()
{
$categories = Categories::find()->where(['IS', 'parent_id', NULL])->all();
$keyList = [];
foreach ($categories as $category) {
$sub = [];
foreach ($category->subCategories as $subCategory) {
if ($subCategory->name) {
$sub[] = [
'id' => $subCategory->id,
'name' => $subCategory->name,
'name_en' => $subCategory->ts_en_name
];
}
}
$keyList[] = [
'id' => $category->id,
'name' => $category->name,
'name_en' => $category->ts_en_name,
'sub' => $sub
];
}
return $keyList;
}
public static function objectTemplates($sub_category_id = null)
{
$sub = [];
if ($sub_category_id)
$sub['sc_id'] = $sub_category_id;
$retrieve = CategoriesOt::find()->where($sub)->all();
$data = [];
foreach ($retrieve as $item) {
$objectTemplate = $item->objectTemplate;
$objectTemplateFields = [];
foreach ($objectTemplate->objectTemplateFields as $objectTemplateField) {
$objectTemplateFields[] = $objectTemplateField->toArray();
}
$data[] = [
'id' => $objectTemplate->id,
'name' => $objectTemplate->name,
'fields' => $objectTemplateFields
];
}
return $data;
}
}
@@ -0,0 +1,56 @@
<?php
namespace app\services\api;
class Sync
{
public function container($action)
{
if (method_exists($this, $action))
return $this->{$action}($this->parse());
return $this->execError('Wrong action');
}
private function parse()
{
$data = json_decode(\Yii::$app->request->getRawBody());
if ($data) return $data;
return $this->execError('Wrong data format');
}
protected function required($strong_params, $params, $data) {
foreach ($strong_params as $param) {
if(empty($data->{$param}))
if(empty($data->{$param}))
return $this->execError("Missing parameter $param");
}
foreach ($params as $param) {
if(!isset($data->{$param}))
return $this->execError("Missing parameter $param");
}
}
protected function exist($class, $key, $value) {
/** @var \yii\db\ActiveRecord $class */
if($class::find()->where([$key => $value])->exists()) {
return $this->execError("Record already exists with $key:$value");
}
}
protected function notExist($class, $key, $value) {
/** @var \yii\db\ActiveRecord $class */
if(!$class::find()->where([$key => $value])->exists()) {
return $this->execError("Record does not exists $key:$value");
}
}
protected function execError($message)
{
return ['error' => 1, 'message' => $message];
}
protected function execSuccess()
{
return['success' => 1];
}
}
@@ -0,0 +1,100 @@
<?php
namespace app\services\api;
use app\models\Categories;
class SyncCategory extends Sync
{
public function main_create($data)
{
if(!empty($data->{'error'})) return $data;
$missing = $this->required(['rr_category_id', 'name'], ['name_en'], $data);
if($missing) return $missing;
$exits = $this->exist(Categories::class, 'rr_category_id', $data->{'rr_category_id'});
if($exits) return $exits;
$category = new Categories();
$category->rr_category_id = $data->{'rr_category_id'};
$category->name = $data->{'name'};
$category->ts_en_name = $data->{'name_en'};
$category->save();
return $this->execSuccess();
}
public function main_update($data)
{
if(!empty($data->{'error'})) return $data;
$missing = $this->required(['rr_category_id', 'name'], ['name_en'], $data);
if($missing) return $missing;
$category = Categories::find()->where(['rr_category_id' => $data->{'rr_category_id'}])->one();
if($category) {
$category->rr_category_id = $data->{'rr_category_id'};
$category->name = $data->{'name'};
$category->ts_en_name = $data->{'name_en'};
$category->save();
} else {
return $this->execError('Record does not exist rr_category_id:'.$data->{'rr_category_id'});
}
return $this->execSuccess();
}
public function main_delete($data)
{
if(!empty($data->{'error'})) return $data;
$missing = $this->required(['rr_category_id'], [], $data);
if($missing) return $missing;
$category = Categories::find()->where(['rr_category_id' => $data->{'rr_category_id'}])->one();
if($category) {
$category->delete();
} else {
return $this->execError('Record does not exist rr_category_id:'.$data->{'rr_category_id'});
}
return $this->execSuccess();
}
public function sub_create($data) {
if(!empty($data->{'error'})) return $data;
$missing = $this->required(['rr_category_id', 'rr_sub_category_id', 'name'], ['name_en'], $data);
if($missing) return $missing;
$exits = $this->exist(Categories::class, 'rr_sub_category_id', $data->{'rr_sub_category_id'});
if($exits) return $exits;
$category = Categories::find()->where(['rr_category_id' => $data->{'rr_category_id'}])->one();
if($category) {
$sub = new Categories();
$sub->parent_id = $category->id;
$sub->rr_category_id = $category->rr_category_id;
$sub->rr_sub_category_id = $data->{'rr_sub_category_id'};
$sub->name = $data->{'name'};
$sub->ts_en_name = $data->{'name_en'};
$sub->order_index = Categories::getNextOrderIndex($category->id);
$sub->save();
} else {
return $this->execError("Main category record does not exist: rr_category_id':$data->{'rr_category_id'}");
}
return $this->execSuccess();
}
public function sub_update($data) {
if(!empty($data->{'error'})) return $data;
$missing = $this->required(['rr_sub_category_id', 'name'], ['name_en'], $data);
if($missing) return $missing;
$sub = Categories::find()->where(['rr_sub_category_id' => $data->{'rr_sub_category_id'}])->one();
if($sub) {
$sub->name = $data->{'name'};
$sub->ts_en_name = $data->{'name_en'};
$sub->save();
} else {
return $this->execError('Record does not exist rr_sub_category_id:'.$data->{'rr_sub_category_id'});
}
}
public function sub_delete($data) {
if(!empty($data->{'error'})) return $data;
$missing = $this->required(['rr_sub_category_id'], [], $data);
if($missing) return $missing;
$sub = Categories::find()->where(['rr_sub_category_id' => $data->{'rr_sub_category_id'}])->one();
if($sub) {
$sub->delete();
} else {
return $this->execError('Record does not exist rr_sub_category_id:'.$data->{'rr_sub_category_id'});
}
}
}
@@ -0,0 +1,162 @@
<?php
namespace app\services\api;
use app\models\Library;
use app\models\LibraryLog;
use app\models\RegisterObjectFields;
use app\models\RegisterObjectFiles;
use app\models\RegisterObjects;
use yii\base\BaseObject;
class SyncObject extends Sync
{
public function setObject($data)
{
//echo $data->general->ref_num;
//$file = $_SERVER['DOCUMENT_ROOT'].'/new_publication.json';
//file_put_contents($file, $incoming);
$lib_log = new LibraryLog();
$lib_log->log = json_encode($data);
$lib_log->save();
$object = RegisterObjects::find()->where(['ref_num' => $data->general->ref_num])->one();
if (!$object) {
$object = new RegisterObjects();
$object->date_added = date('Y-m-d H:i:s');
$object->publish_date = date('Y-m-d H:i:s');
}
$data->general = $data->general ?? new \stdClass();
$data->bg = $data->bg ?? new \stdClass();
$data->en = $data->en ?? new \stdClass();
$data->fields = $data->fields ?? [];
$data->files = $data->files ?? [];
// General
$object->is_active = 1;
$object->ref_num = $data->general->ref_num;
$object->lib_type = $data->general->lib_type;
if (!empty($data->general->is_payable))
$object->is_payable = $data->general->is_payable == 1 ? 1 : null;
$object->city_id = $data->general->city_id ?? null;
$object->partner_id = $data->general->partner_id ?? null;
$object->infocenter_email = $data->general->infocenter_email ?? null;
$object->infocenter_website = $data->general->infocenter_website ?? null;
$object->administrative_latitude = $data->general->administrative_latitude ?? null;
$object->administrative_longitude = $data->general->administrative_longitude ?? null;
$object->created_year = $data->general->created_year ?? null;
$object->created_by = $data->general->created_by ?? null;
$object->date_updated = date('Y-m-d H:i:s');
$object->object_thumbnail_url = $data->general->object_thumbnail_url ?? null;
//BG
$object->name = $data->bg->name ?? null;
$object->description = $data->bg->description ?? null;
$object->short_description = $data->bg->short_description ?? null;
$object->annotation = $data->bg->annotation ?? null;
$object->location_description = $data->bg->location_description ?? null;
$object->admistrative_address = $data->bg->admistrative_address ?? null;
$object->temporary_address = $data->bg->temporary_address ?? null;
$object->infocenter_name = $data->bg->infocenter_name ?? null;
$object->infocenter_address = $data->bg->infocenter_address ?? null;
//EN
$object->ts_en_name = $data->en->name ?? null;
$object->ts_en_description = $data->en->description ?? null;
$object->ts_en_short_description = $data->en->short_description ?? null;
$object->ts_en_annotation = $data->en->annotation ?? null;
$object->ts_en_location_description = $data->en->location_description ?? null;
$object->ts_en_admistrative_address = $data->en->admistrative_address ?? null;
$object->ts_en_temporary_address = $data->en->temporary_address ?? null;
$object->ts_en_infocenter_name = $data->en->infocenter_name ?? null;
$object->ts_en_infocenter_address = $data->en->infocenter_address ?? null;
$object->save();
list($fieldIds, $fileIds) = [[], []];
foreach ($data->fields as $field) {
$objectField = RegisterObjectFields::find()->where(['ref_num' => $field->object_id, 'field_id' => $field->field_id])->one();
if (!$objectField)
$objectField = new RegisterObjectFields();
$objectField->field_id = $field->field_id;
$objectField->object_id = $object->id;
$objectField->ref_num = $field->object_id;
$objectField->value_id = $field->value_id ?? null;
$objectField->value_text = $field->value_text ?? null;
$objectField->save();
$fieldIds[] = $objectField->field_id;
}
foreach ($data->files as $registerFile) {
$file = RegisterObjectFiles::find()->where(['file_ref_num' => $registerFile->file_ref_num])->one();
if (!$file)
$file = new RegisterObjectFiles();
$file->file_url = $registerFile->file_url ?? null;
$file->streaming_url = $registerFile->streaming_url ?? null;
$file->extension = $registerFile->extension ?? null;
$file->file_ref_num = $registerFile->file_ref_num;
$file->size = $registerFile->size ?? null;
$file->object_id = $object->id;
$file->video_thumbnail = $registerFile->file_thumb_url ?? null;
$file->video_title = $registerFile->title ?? null;
$file->video_duration = $registerFile->duration ?? null;
$file->file_content_type = $registerFile->file_content_type ?? null;
$file->save();
$fileIds[] = $file->file_ref_num;
}
// DELETE FIELDS
foreach ($object->registerObjectFields as $registerObjectField) {
if (!in_array($registerObjectField->field_id, $fieldIds))
$registerObjectField->delete();
}
//DELETE FILES
foreach ($object->registerObjectFiles as $registerObjectFile) {
if (!in_array($registerObjectFile->file_ref_num, $fileIds))
$registerObjectFile->delete();
}
//$library = $object->
if ($data->general->lib_type == 2) {
$lib = $object->library ?? new Library();
//Library
foreach ($data->general as $key => $value) {
if (substr($key, 0, 4) === "lib_") {
if($key == 'lib_language') continue;
if($lib->hasProperty($key) && $value != '') {
$lib->{$key} = $value;
}
}
}
$lib->object_id = $object->id;
if(!empty($data->language) && $data->language->language_ids) {
$lib->lib_language = $data->language->language_ids;
}
$lib->save();
}
return ['success' => true, 'message' => 'Record done!'];
}
public function unsetObject($data)
{
$lib_log = new LibraryLog();
$lib_log->log = json_encode($data);
$lib_log->save();
if (!empty($data->ref_num)) {
$object = RegisterObjects::find()->where(['ref_num' => $data->ref_num])->one();
$object->is_active = null;
$object->save();
return ['success' => true, 'message' => 'The object is already deactivated'];
} else {
return ['error' => 1, 'message' => 'Missing ref_num parameter'];
}
}
}
@@ -0,0 +1,117 @@
<?php
namespace app\services\navigation;
class NavigationAdminGlobal extends NavigationBase
{
public static function top()
{
$bl['index'] = ['Начало', 'dashboard'];
//$bl['nomenclature-register'] = ['Номенклатури', 'nomenclatures'];
//$bl['nomenclature'] = ['Номенклатури', 'categories'];
$bl['web-portal'] = ['Публичен портал', 'expositions'];
$bl['products'] = ['Дигитален магазин', 'subscriptions'];
$bl['tour'] = ['Туристическа информация', 'tour-objects'];
$bl['mobile-app'] = ['Мобилно приложение', 'become-an-explorer-objects'];
$bl['user'] = ['Потребители', 'admin-global'];
$bl['orders'] = ['Поръчки', 'subscriptions'];
return self::stringButtons($bl, 'top');
}
public static function left()
{
$bl['index'] = [
['Начално табло', 'dashboard'],
['Ръководство на потребителя', 'guide-cms'],
['Ръководство портал', 'guide-portal'],
['Въпроси и отговори', 'qa-cms'],
['Въпроси и отговори портал', 'qa-portal'],
['Хронология', 'history'],
['Помощна информация', 'help'],
['Запитвания', 'inquiries'],
['За проекта (текст и лога)', 'about-project'],
['divider', 'Външни връзки'],
['Мрежа знания', 'knowledge-network', 'https://im1.nasledstvo.bg/?option=oauthredirect&app_name=keycloak'],
['Център знания', 'online-education', 'https://el.nasledstvo.bg/index.php/apps/sociallogin/custom_oidc/keycloak'],
['Практическа общност', 'practical-network', 'https://im.nasledstvo.bg/?option=oauthredirect&app_name=Nasledstvo.bg'],
['Е-обучение', 'e-learning', 'https://ed.nasledstvo.bg/auth/oidc/']
];
$bl['web-portal'] = [
['Експозиции', 'expositions'],
//['Обекти cms', 'objects'],
['Обекти', 'objects-register'],
['Колекции', 'collections'],
['Е-библиотека', 'e-library'],
['Проекти', 'projects'],
['Новини', 'news'],
['Събития', 'events'],
['Кампании', 'campaigns'],
['divider'],
['Страници', 'pages'],
['Навигация', 'navigation'],
['Тематични зони', 'positions'],
//['Членсто в Наследство.БГ', 'join-to-us'],
['Слайдер', 'slider'],
['Статични преводи', 'tslist'],
['SEO управление', 'seo']
];
$bl['tour'] = [
['Туристически обекти', 'tour-objects']
];
$bl['mobile-app'] = [
['Стани изследовател обекти', 'become-an-explorer-objects'],
['Потребители', 'users']
];
$bl['nomenclature'] = [
['Категории', 'categories'],
['Общи номенклатури', 'common-fields'],
['Видове обекти', 'object-templates'],
['Колекции на обекти', 'collections']
];
$bl['nomenclature-register'] = [
['Номенклатури', 'nomenclatures'],
];
$bl['products'] = [
['Абонаменти', 'subscriptions'],
['Колекции', 'paid-collections'],
['Публикации', 'paid-publications']
];
$bl['user'] = [
//['Управление на глобален администратор', 'admin-global'],
['Управление администратори публичен портал', 'admin-global'],
['Управление на потребител на партньор', 'partner'],
['Управление на партньори', 'partner-org'],
//['Управление на потребители от регистъра', 'register'],
['Управление на права', 'rights'],
['Управление на роли / групи', 'roles'],
['divider'],
['Управление на потребители публичен портал', 'public']
];
$bl['orders'] = [
['Абонаменти', 'subscriptions'],
['Резервации', 'reservations'],
['Колекции', 'products-collections'],
['Публикации', 'products-publications']
];
return self::stringButtons($bl, 'left');
}
}
@@ -0,0 +1,53 @@
<?php
namespace app\services\navigation;
define('URI', explode('?', $_SERVER['REQUEST_URI'])[0]);
class NavigationBase
{
protected static function stringButtons($bl, $navType)
{
$uri_parts = explode('/', URI);
$uriType = $uri_parts[1] ?? null;
$uriTab = $uri_parts[2] ?? null;
$uriPage = $uri_parts[3] ?? null;
$prepareHtml = '';
if ($uriType && $uriTab && $uriPage) {
if ($navType == 'top') {
foreach ($bl as $tab => $data) {
if (!empty($data[2])) {
$prepareHtml .= '<a target="_blank" href="' . $data[2] . '">' . $data[0] . '</a>';
} else {
$s = $tab == $uriTab ? 'class="selected"' : '';
$b = '/' . $uriType . '/' . $tab . '/' . $data[1] . '/';
$prepareHtml .= '<a ' . $s . ' href="' . $b . '">' . $data[0] . '</a>';
}
}
} else {
if (isset($bl[$uriTab])) {
foreach ($bl[$uriTab] as $data) {
if (isset($data[0])) {
if ($data[0] == 'divider') {
if(!empty($data[1])) {
$prepareHtml .= '<div class="divider-title">'.$data[1].'</div>';
}
$prepareHtml .= '<div class="divider"></div>';
} else {
if (!empty($data[2])) {
$prepareHtml .= '<a href="' . $data[2] . '" target="_blank">' . $data[0] . '</a>';
} else {
$s = $data[1] == $uriPage ? 'class="selected"' : '';
$b = '/' . $uri_parts[1] . '/' . $uriTab . '/' . $data[1] . '/';
$prepareHtml .= '<a ' . $s . ' href="' . $b . '">' . $data[0] . '</a>';
}
}
}
}
}
}
}
return $prepareHtml;
}
}
@@ -0,0 +1,52 @@
<?php
namespace app\services\navigation;
use app\models\UserPartner;
use app\services\Auth;
use app\widgets\services\UserRight;
class NavigationPartner extends NavigationBase
{
public static function top()
{
$bl['index'] = ['Начало', 'dashboard'];
$bl['website'] = ['Публичен портал', 'expositions'];
$bl['knowledge-network'] = ['Мрежа знания', 'knowledge-network', 'https://im1.nasledstvo.bg/?option=oauthredirect&app_name=keycloak'];
$bl['online-education'] = ['Център знания', 'online-education', 'https://el.nasledstvo.bg/index.php/apps/sociallogin/custom_oidc/keycloak'];
$bl['practical-network'] = ['Практическа общност', 'practical-network', 'https://im.nasledstvo.bg/?option=oauthredirect&app_name=Nasledstvo.bg'];
$bl['e-learning'] = ['Е-обучение', 'e-learning', 'https://ed.nasledstvo.bg/auth/oidc/'];
return self::stringButtons($bl, 'top');
}
public static function left()
{
$user = \Yii::$app->controller->partner;
$bl['index'] = [
['Начално табло', 'dashboard'],
['Ръководство на потребителя', 'guide-cms'],
['Въпроси и отговори', 'qa-cms'],
];
$bl['website'] = [
['Експозиции', 'expositions'],
['Колекции', 'collections'],
['Е-библиотека', 'e-library'],
['Обекти', 'objects'],
['Проекти', 'projects'],
['Страници', 'pages'],
['Новини', 'news'],
['Събития', 'events'],
['Кампании', 'campaigns'],
['Данни на партньор', 'partner-data']
];
if(UserRight::isAdmin()) {
$bl['website'][] = ['Потребители партньор', 'users'];
if(Auth::userPartner() && Auth::userPartner()->role_id == 1) {
$bl['website'][] = ['Потребители публичен портал', 'public'];
}
}
return self::stringButtons($bl, 'left');
}
}
@@ -0,0 +1,20 @@
<?php
namespace app\services\openid;
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);
}
}
@@ -0,0 +1,87 @@
<?php
namespace app\services\openid;
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,154 @@
<?php
namespace app\services\openid;
use app\models\CmsRoles;
use app\models\UserAdminGlobal;
use app\models\UserPartner;
use app\models\UserSession;
use app\services\Auth;
class OpenIdService
{
private $client_id;
private $client_secret;
private $redirect_uri;
private $metadata_url;
private $locale_from_portal;
public function __construct()
{
$this->locale_from_portal = !empty($_GET['lg']) ? '?lg=' . $_GET['lg'] : '' ;
$this->redirect_uri = \Yii::$app->params['cms'] . '/partner-register-login/'.$this->locale_from_portal;
$this->metadata_url = \Yii::$app->params['id_server'] . '/realms/nasledstvo.bg/.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($isAdmin = false)
{
if ($isAdmin) {
$this->redirect_uri = \Yii::$app->params['cms'] . '/admin-register-login/'.$this->locale_from_portal;
}
$metadata = $this->http($this->metadata_url);
if (!isset($_GET['code'])) {
$_SESSION['state'] = bin2hex(random_bytes(5));
$_SESSION['code_verifier'] = bin2hex(random_bytes(50));
$code_challenge = $this->base64_urlencode(hash('sha256', $_SESSION['code_verifier'], 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'],
'scope' => 'openid profile',
'code_challenge' => $code_challenge,
'code_challenge_method' => 'S256',
]);
header("Location: $authorize_url");
exit;
} else {
if ($_SESSION['state'] != $_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'],
]);
if (!isset($response->access_token)) {
die('Error fetching access token');
}
$userinfo = $this->http($metadata->userinfo_endpoint, [
'access_token' => $response->access_token,
]);
if (!empty($userinfo->groups_user) && in_array('public_user', $userinfo->groups_user)) {
header('Location: ' . \Yii::$app->params['portal'] . '/bg/user/wrong-user/');
exit;
}
if(!empty($_GET['lg'])) {
setcookie('cookie_lg', $_GET['lg'], time() + (86400 * 30), "/");
} else {
if (!empty($userinfo->locale)) {
if ($userinfo->locale == 'bg' || $userinfo->locale == 'en') {
setcookie('cookie_lg', $userinfo->locale, time() + (86400 * 30), "/");
}
} else {
setcookie('cookie_lg', 'bg', time() + (86400 * 30), "/");
}
}
//echo json_encode($userinfo);
// exit;
if (empty($userinfo->sub))
die('sub is empty');
//echo json_encode($response);
//exit;
if (!empty($userinfo->sub)) {
if (!empty($userinfo->realm_access)) {
if (!empty($userinfo->realm_access->roles)) {
if (in_array('cms-partner-admin', $userinfo->realm_access->roles)) {
//exit;
if (empty($userinfo->partner_id))
die('missing parameter: partner_id');
$_SESSION['id_token_hint'] = $response->id_token;
//Login as partner user
UserSession::log('partner-admin', 2, $userinfo->sub);
UserPartner::prepareRegisterUser($userinfo, 1);
} else if (in_array('cms-partner-editor', $userinfo->realm_access->roles)) {
//exit;
if (empty($userinfo->partner_id))
die('missing parameter: partner_id');
$_SESSION['id_token_hint'] = $response->id_token;
//Login as partner user
UserSession::log('partner-editor', 2, $userinfo->sub);
UserPartner::prepareRegisterUser($userinfo, 2);
} else if (in_array('cms-super-admin', $userinfo->realm_access->roles)) {
$_SESSION['id_token_hint'] = $response->id_token;
//Login as global administrator
UserSession::log('admin', 2, $userinfo->sub);
UserAdminGlobal::prepareRegisterUser($userinfo);
} else {
require_once __DIR__ . '/access_denied_page.php';
exit;
}
}
}
}
echo 'Error: Some parameters are missing';
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,93 @@
<?php
/**
* @var $userinfo ;
*/
$lg = !empty($userinfo->locale) && $userinfo->locale == 'en' ? 'en' : 'bg';
$message = [
'bg' => 'Нямате права да влизате в този модул. За да получите достъп, моля свържете се със системния си администратор. Все още сте влезли в профила си в Nasledstvo.bg',
'en' => 'You do not have permission to enter this module. To gain access, please contact your system administrator. You are still logged in to your Nasledstvo.bg account'
];
$profile_button = [
'bg' => 'Към Вашия профил в Nasledstvo.bg',
'en' => 'To your profile at Nasledstvo.bg',
]
//die('Access denied. for user '. $userinfo->email);
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="/_public/assets/css/cms.css">
<title>CMS</title>
</head>
<style>
body {
background: #847650;
padding: 0;
margin: 0;
}
.panel {
width: 100%;
max-width: 500px;
background: #FFFFFF;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.4);
border-radius: 20px;
margin: 100px auto 0;
padding-top: 20px;
}
.header {
height: 40px;
}
.body {
padding: 50px;
}
.message {
text-align: center;
}
.logo-header {
height: 100%;
display: block;
margin: 0 auto;
}
.link {
text-align: center;
margin-top: 30px;
}
.link a {
display: inline-block;
padding: 10px 20px;
background: #847650;
color: #FFFFFF;
border-radius: 10px;
text-decoration: none;
}
</style>
<body>
<div class="panel">
<div class="header">
<img alt="cms" class="logo-header" src="/_public/assets/images/header-logo-<?= $lg ?>.png">
</div>
<div class="body">
<div class="message"><?= $message[$lg] ?></div>
<div class="link">
<a href="https://id.nasledstvo.bg/" class="profile-button"><?= $profile_button[$lg] ?></a>
</div>
</div>
</div>
</body>
</html>