10 Commits
0.1.0 ... 1.1.0

Author SHA1 Message Date
60884ab2ed from perm to site renamed 2026-04-19 16:54:39 +05:00
16b0361268 submodules fix 2026-04-19 12:58:59 +05:00
5a7edafee2 created 2026-04-19 12:39:16 +05:00
c631428699 dots replaced with three.js shader 2026-01-08 18:04:40 +05:00
d26b0ca9ea популярные заказы 2026-01-02 00:27:47 +05:00
7fb037d155 footer 2025-12-01 00:11:20 +07:00
db3a515aaa icons and started on description section 2025-11-24 01:37:35 +07:00
1ee70ba8d6 introdution, workload, statistics and desctiption 2025-11-24 01:17:59 +07:00
d70791aff2 after Ksenia 2025-11-22 10:25:53 +03:00
f53840c125 after Ksenia 2025-11-18 20:50:54 +03:00
471 changed files with 10003 additions and 762 deletions

16
.gitmodules vendored Executable file
View File

@@ -0,0 +1,16 @@
[submodule "hotline.mjs"]
path = hotline.mjs
url = https://git.svoboda.works/mirzaev/hotline.mjs
branch = stable
[submodule "damper.mjs"]
path = damper.mjs
url = https://git.svoboda.works/mirzaev/damper.mjs.git
branch = stable
[submodule "icons"]
path = icons
url = https://git.svoboda.works/mirzaev/icons
branch = stable
[submodule "womb3-simplex.mjs"]
path = womb3-simplex.mjs
url = https://git.svoboda.works/mirzaev/womb3-simplex.mjs
branch = stable

View File

@@ -1,13 +1,13 @@
{
"name": "kodorvan/perm",
"description": "Лендинг для Перми от Ксении",
"homepage": "https://git.svoboda.works/kodorvan/perm",
"name": "kodorvan/site",
"description": "The kodorvan team main site",
"homepage": "https://git.svoboda.works/kodorvan/site",
"type": "site",
"keywords": [
"minimal",
"baza",
"landing",
"perm"
"site"
],
"readme": "README.md",
"license": "WTFPL",
@@ -17,25 +17,22 @@
"email": "arsen@mirzaev.sexy",
"homepage": "https://mirzaev.sexy",
"role": "Programmer"
},
{
"name": "Hollspae",
"email": "ksena.vilkova79@gmail.om",
"role": "Creator-Programmer"
}
],
"support": {
"wiki": "https://git.svoboda.works/kodorvan/perm/wiki",
"issues": "https://git.svoboda.works/kodorvan/perm/issues"
"wiki": "https://git.svoboda.works/kodorvan/site/wiki",
"issues": "https://git.svoboda.works/kodorvan/site/issues"
},
"require": {
"php": "^8.4",
"php": "^8.5",
"ext-blake3": "^0.1",
"mirzaev/minimal": "^3.8",
"mirzaev/baza": "^3.4",
"mirzaev/languages": "^1",
"twig/twig": "^3.2",
"twig/extra-bundle": "^3.7",
"twig/intl-extra": "^3.10"
"twig/intl-extra": "^3.10",
"phpmailer/phpmailer": "^7.0"
},
"suggest": {
"mirzaev/files": "Easy working with files",
@@ -44,12 +41,12 @@
},
"autoload": {
"psr-4": {
"kodorvan\\perm\\": "kodorvan/perm/system"
"kodorvan\\site\\": "kodorvan/site/system"
}
},
"autoload-dev": {
"psr-4": {
"kodorvan\\perm\\tests\\": "kodorvan/perm/tests"
"kodorvan\\site\\tests\\": "kodorvan/site/tests"
}
},
"scripts": {

1032
composer.lock generated Normal file → Executable file

File diff suppressed because it is too large Load Diff

1
damper.mjs Submodule

Submodule damper.mjs added at 81d208b964

1
hotline.mjs Submodule

Submodule hotline.mjs added at c25963fca8

1
icons Submodule

Submodule icons added at c4dedad538

View File

@@ -1,15 +1,43 @@
#!/bin/bash
git submodule update --init --recursive
if [ -d author/project ]; then
mv author/project author/perm
mv author/project author/site
fi
if [ -d author ]; then
mv author kodorvan
fi
if [ -e kodorvan/perm/system/settings/*.sample ]; then
for i in kodorvan/perm/system/settings/*.sample; do
cp "$i" "${i/.sample/}";
done
for i in kodorvan/site/system/settings/*.sample; do
echo $i;
if [ ! -f "${i/.sample/}" ]; then
cp -n "$i" "${i/.sample/}";
echo ${i/.sample/};
fi
done
if ! [ -d kodorvan/site/system/public/js/modules ]; then
mkdir kodorvan/site/system/public/js/modules -p
fi
if ! [ -L kodorvan/site/system/public/js/modules/damper.mjs ]; then
ln -s ../../../../../../damper.mjs/damper.mjs kodorvan/site/system/public/js/modules/damper.mjs;
fi
if ! [ -L kodorvan/site/system/public/js/modules/hotline.mjs ]; then
ln -s ../../../../../../hotline.mjs/hotline.mjs kodorvan/site/system/public/js/modules/hotline.mjs;
fi
if ! [ -L kodorvan/site/system/public/js/modules/womb3-simplex.mjs ]; then
ln -s ../../../../../../womb3-simplex.mjs/womb3-simplex.mjs kodorvan/site/system/public/js/modules/womb3-simplex.mjs;
fi
if ! [ -L kodorvan/site/system/public/js/modules/simplex-noise.mjs ]; then
ln -s ../../../../../../womb3-simplex.mjs/simplex-noise.mjs kodorvan/site/system/public/js/modules/simplex-noise.mjs;
fi
if ! [ -L kodorvan/site/system/public/css/icons ]; then
ln -s ../../../../../icons/css kodorvan/site/system/public/css/icons;
fi

View File

@@ -1,7 +0,0 @@
@charset "UTF-8";
aside {
&:not(:has(*)) {
display: none;
}
}

View File

@@ -1,45 +0,0 @@
@charset "UTF-8";
@media (prefers-color-scheme: dark) {
:root {
--text-color: #fff;
--text-color-inverted: #000;
--button-background-color-inverted: #fff;
--button-background-color: #000;
--section-background-color-inverted: #fff;
--section-background-color: #000;
--background-color: #000;
--background-color-inverted: #fff;
--interface-top-background-color: var(--background-color, #000);
--interface-background-color: var(--background-color, #000);
--interface-bottom-background-color: var(--background-color, #000);
--red: red;
--white: #fff;
--paper: var(--white);
}
}
@media (prefers-color-scheme: light) {
:root {
--text-color: #fff;
--text-color-inverted: #000;
--button-background-color-inverted: #fff;
--button-background-color: #000;
--section-background-color-inverted: #fff;
--section-background-color: #000;
--background-color: #000;
--background-color-inverted: #fff;
--interface-top-background-color: var(--background-color, #000);
--interface-background-color: var(--background-color, #000);
--interface-bottom-background-color: var(--background-color, #000);
--red: red;
--white: #fff;
--paper: var(--white);
}
}

View File

@@ -1,10 +0,0 @@
@import url('/css/fonts/fira.css');
@import url('/css/fonts/hack.css');
@import url('/css/fonts/dejavu.css');
@import url('/css/fonts/bahnschrift.css');
@font-face {
font-family: 'Commissioner';
src: url('/fonts/commissioner.ttf');
font-weight: 400;
}

View File

@@ -1,7 +0,0 @@
@charset "UTF-8";
footer {
&:not(:has(*)) {
display: none;
}
}

View File

@@ -1,68 +0,0 @@
@charset "UTF-8";
header {
top: 0;
left: 0;
position: fixed;
width: 100vw;
height: 70px;
box-sizing: border-box;
padding: 0 20%;
display: flex;
justify-content: space-between;
background-color: #931919;
&:not(:has(*)) {
display: none;
}
>span#logotype {
display: flex;
flex-direction: column;
font-size: 1.1rem;
>h4:only-of-type:first-child {
margin: unset;
font-family: "Cascadia Code";
font-size: 2.8em;
}
>small:only-of-type:last-child {
justify-self: end;
align-self: end;
margin-top: -0.8em;
font-family: 'Bahnschrift';
font-size: 0.7em;
font-weight: 800;
text-transform: uppercase;
}
}
>nav#menu {
display: flex;
justify-content: center;
align-items: center;
gap: 1rem;
font-family: 'Geologica';
>a {
text-decoration: none;
font-weight: 600;
font-size: 1rem;
text-transform: uppercase;
color: #fff;
}
}
>a#order {
align-self: center;
background-color: #660909;
padding: 0.5em 1.3em;
border-radius: 1.125em;
color: #fff;
font-family: 'Cascadia Code';
font-weight: 400;
text-decoration: none;
border: 2px solid;
}
}

View File

@@ -1,21 +0,0 @@
@charset "UTF-8";
@import url("https://fonts.googleapis.com/css2?family=Commissioner:wght@100;200;300;400;500;600;700;800;900&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Cascadia+Code:ital,wght@0,200..700;1,200..700&family=Rubik:ital,wght@0,300..900;1,300..900&family=Wix+Madefor+Display:wght@400..800&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Share+Tech+Mono&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Montserrat:wght@900&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Geologica:wght@100..900&family=Pochaevsk&display=swap");
body {
margin: unset;
}
main {
flex-grow: 1;
display: flex;
flex-direction: column;
align-items: center;
gap: var(--gap);
transition: 0s;
}

View File

@@ -1,34 +0,0 @@
@charset "UTF-8";
:root {
--gap: min(12px, 1rem);
/* font-family: , system-ui, sans-serif; */
font-family: "dejavu";
text-decoration: none;
outline: none;
border: none;
transition: 0.1s ease-out;
}
/* Selection */
::selection {
color: var(--text-selected-color);
background: var(--text-selected-background-color);
}
::-moz-selection {
color: var(--text-selected-color);
background: var(--text-selected-background-color);
}
.unselectable {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}

View File

@@ -1,4 +0,0 @@
<?php
// Initializing default theme for the views templater
define('THEME', 'default');

View File

@@ -1,10 +0,0 @@
{% block css %}
{% endblock %}
{% block body %}
<aside>
</aside>
{% endblock %}
{% block js %}
{% endblock %}

View File

@@ -1,26 +0,0 @@
{% block title %}
<title>{% if head.title != empty %}{{ head.title }}{% else %}perm by kodorvan{% endif %}</title>
{% endblock %}
{% block meta %}
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
{% for meta in head.metas %}
<meta {% for name, value in meta.attributes %}{{ name }}="{{ value }}" {% endfor %}>
{% endfor %}
{% endblock %}
{% block css %}
{% for element in css %}
<link type="text/css" rel="stylesheet"{% if element.href %} href="{{ element.href }}"{% endif %} />
{% endfor %}
<link type="text/css" rel="stylesheet" href="/themes/default/css/fonts.css" />
<link type="text/css" rel="stylesheet" href="/themes/default/css/system.css" />
<link type="text/css" rel="stylesheet" href="/themes/default/css/header.css" />
<link type="text/css" rel="stylesheet" href="/themes/default/css/main.css" />
<link type="text/css" rel="stylesheet" href="/themes/default/css/aside.css" />
<link type="text/css" rel="stylesheet" href="/themes/default/css/footer.css" />
<style id="theme">
@import url('/themes/default/css/themes/default/colorscheme.css');
</style>
{% endblock %}

View File

@@ -1,22 +0,0 @@
{% block css %}
{% endblock %}
{% block body %}
<header>
<span id="logotype" class="unselectable">
<h4>КОДОРВАНЬ</h4>
<small>реальных программистов</small>
</span>
<nav id="menu" class="unselectable">
<a href="/project">Проекты</a>
<a href="/contacts">Контакты</a>
<a href="/comand">Команда</a>
</nav>
<a id="order" class="unselectable" href="https:/t.me/kodorvan?direct"><i class="icon letter"></i>Заказать</a>
</header>
{% endblock %}
{% block js %}
{% endblock %}

View File

@@ -1,5 +0,0 @@
{% block js %}
{% for element in js %}
<script {% if element.src %}src="{{ element.src }}"{% endif %} {% if element.type %}type="{{ element.type }}"{% endif %}>{{ element.innerText }}</script>
{% endfor %}
{% endblock %}

View File

@@ -2,11 +2,11 @@
declare(strict_types=1);
namespace kodorvan\perm\controllers;
namespace kodorvan\site\controllers;
// Files of the project
use kodorvan\perm\views\templater,
kodorvan\perm\models\core as models;
use kodorvan\site\views\templater,
kodorvan\site\models\core as models;
// Library for languages support
use mirzaev\languages\language;
@@ -20,7 +20,7 @@ use mirzaev\minimal\core as minimal,
/**
* Controllers core
*
* @package kodorvan\perm\controllers
* @package kodorvan\site\controllers
*
* @param language $language Language
* @param response $response Response

View File

@@ -0,0 +1,296 @@
<?php
declare(strict_types=1);
namespace kodorvan\site\controllers;
// Files of the project
use kodorvan\site\controllers\core;
// Framework for PHP
use mirzaev\minimal\http\enumerations\content,
mirzaev\minimal\http\enumerations\status;
/**
* Index
*
* @package kodorvan\site\controllers
*
* @param array $errors Registry of errors
*
* @method null index() Main page
*
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
*/
final class index extends core
{
/**
* Errors
*
* @var array $errors Registry of errors
*/
protected array $errors = [
'system' => []
];
/**
* Main page
*
* @return null
*/
public function index(): null
{
if (str_contains($this->request->headers['accept'] ?? '', content::html->value)) {
// Request for HTML response
// Initializing the team workload
$this->view->workload = (string) ($_COOKIE['workload'] ?? rand(20, 80));
// Initializing services
$this->view->services = [
[
'class' => 'telegram voronka',
'title' => 'Телеграм воронка',
'icon_left' => '',
/* 'icon_center' => 'import', */
'icon_center' => 'crown',
'icon_right' => '',
'description' => <<<TXT
Поступательно запросит данные пользователя, скомпонует, запишет в базу данных и синхронизирует в CRM
<br><br>
Используя иммерсивные технологии и многофакторный сбор обеспечивает максимальное удержание пользователя
TXT,
'howto' => 'Направьте к нему клиентов и ждите новых заказов в вашей CRM, на сайте или в чате',
'buttons' => [
[
'icon' => 'comment',
'href' => 'https://t.me/' . TELEGRAM_ROBOT['domain'] . '?start=telegram voronka'
]
],
'theses' => [
[
'class' => 'yellow',
'characteristic' => '-80%',
'text' => 'НАГРУЗКА'
],
[
'class' => 'blue',
'colored' => true,
'characteristic' => '+5%',
'text' => 'КОНВЕРСИИ'
],
[
'class' => 'green',
'characteristic' => '0₽',
'text' => 'НИКАКОЙ АРЕНДЫ'
]
],
'background_image_src' => '/themes/default/images/telegram_voronka.png',
'background_image_alt' => 'Телеграм воронка КОДОРВАНЬ',
'cost' => '2000',
'canceled' => 'ЗАБЛОКИРОВАН'
],
[
'class' => 'parser',
'title' => 'Парсер',
'icon_left' => '',
'icon_center' => 'search',
'icon_right' => '',
'description' => <<<TXT
Любая работа за компьютером может быть автоматизирована
<br><br>
Парсер берёт данные с сайтов через API, либо эмулируя пользователя, а так же из excel-документов, CRM и бухгалтерии, затем просчитывает, анализирует и записывает результат
TXT,
'howto' => 'Подключите источники и снизьте нагрузку на операторов, оптимизируйте процессы',
'extra' => [
'Wildberries',
'OZON',
'Yandex Market',
'Avito',
'CDEK',
'1C',
'Bitrix',
'Мой Склад'
],
'buttons' => [
[
'icon' => 'comment',
/* 'href' => 'https://t.me/' . TELEGRAM_ROBOT['domain'] . '?start=parser' */
'href' => 'https://t.me/' . TELEGRAM_ROBOT['domain'] . '?start=parser'
]
],
'theses' => [
[
'class' => 'yellow',
'colored' => true,
'characteristic' => '-100%',
'text' => 'НАГРУЗКА'
],
[
'class' => 'cyan',
'icon' => 'infinity',
'text' => 'ВЕЧНАЯ ПОДДЕРЖКА'
],
[
'class' => 'green',
'icon' => 'play forwards',
'text' => 'РЕКОРД СКОРОСТИ'
]
],
'background_image_src' => '/themes/default/images/excel_small_compressed.jpg',
'background_image_alt' => 'Парсеры КОДОРВАНЬ',
'cost' => '3000'
],
[
'class' => 'calculator',
'title' => 'Калькулятор',
'icon_left' => '',
'icon_center' => 'calculator',
'icon_right' => '',
'description' => <<<TXT
Составление алгоритма обработки большого объёма данных с использованием нейросетей и грамотно выбранной сортировки
<br><br>
Оператор вводит данные, нажимает на кнопки, двигает ползунки и мгновенно получает точный результат вычислений
TXT,
'howto' => 'Настройте параметры в панели управления и в долгосрочной перспективе сэкономьте тысячи часов рабочего времени',
'extra' => [],
'buttons' => [
[
'icon' => 'comment',
'href' => 'https://t.me/' . TELEGRAM_ROBOT['domain'] . '?start=calculator'
]
],
'theses' => [
[
'class' => 'yellow',
'characteristic' => '-95%',
'text' => 'НАГРУЗКА'
],
[
'class' => 'green',
'characteristic' => '-80%',
'text' => 'ОШИБОК ВЫЧИСЛЕНИЙ'
],
[
'class' => 'red',
'colored' => true,
'characteristic' => '+20%',
'text' => 'ОБУЧАЕМОСТЬ'
]
],
'background_image_src' => '/themes/default/images/tordv_compressed.jpg',
'background_image_alt' => 'Калькулятор КОДОРВАНЬ',
'cost' => '10 000'
]
];
// Sending the cookie with the team workload (1800 = 30min)
setcookie('workload', $this->view->workload, time() + 1800, '/');
// Initializing the project constructor data
$this->view->project = [
'architectures' => [
'site' => 'Сайт',
'chat_robot' => 'Чат-робот',
'program' => 'Программа',
'module' => 'Модуль',
'parser' => 'Парсер',
'script' => 'Скрипт',
'game' => 'Видеоигра',
/* 'site' => 'Сайты и браузерные расширения',
'chat_robot' => 'Чат-роботы (любой мессенджер)',
'program' => 'Программа (Android, iOS, Windows)',
'module' => 'Модуль для любой программы',
'parser' => 'Парсер данных API, HTTP и эмуляция',
'script' => 'Скрипт (автоматизация процессов)',
'game' => 'Видеоигра (Android, iOS, Windows)' */
],
'purposes' => [
'funnel' => 'Воронка',
'contacts' => 'Контакты',
'neural_network' => 'Нейросети',
'gallery' => 'Галерея',
'crm' => 'CRM',
'landing' => 'Лендинг',
'marketplace' => 'Маркетплейс',
'search' => 'Поиск',
'calculate' => 'Расчёты',
'logic' => 'Логика',
'game' => 'Игра',
'special' => 'Особенный',
],
'integrations' => [
'one_c' => '1C',
'bitrix24' => 'Битрикс24',
'moy_sklad' => 'Мой Склад',
'telegram' => 'Телеграм',
'mail' => 'Почта',
'excel' => 'Excel'
]
];
// Initializing contacts data
$this->view->contacts = [
'sim' => [
'requests' => [
'full' => PROJECT_CONTACTS_SIM_REQUESTS ?? 'Ошибка',
'country' => PROJECT_CONTACTS_SIM_REQUESTS_COUNTRY ?? 'Ошибка',
'operator' => PROJECT_CONTACTS_SIM_REQUESTS_OPERATOR ?? 'Ошибка',
'number' => [
PROJECT_CONTACTS_SIM_REQUESTS_NUMBER_1 ?? 'Ошибка',
PROJECT_CONTACTS_SIM_REQUESTS_NUMBER_2 ?? 'Ошибка',
PROJECT_CONTACTS_SIM_REQUESTS_NUMBER_3 ?? 'Ошибка'
]
]
]
];
// Initializing contacts data
$this->view->integrations = [
'Мой Склад' => 'moy_sklad',
'1С Предприятие' => '1c',
'Битрикс 24' => 'bitrix24',
'ВКонтакте' => 'vk',
'МАКС' => 'max',
/* 'yandex_direct', */
'Яндекс Директ' => 'yandex_market',
'ОЗОН' => 'ozon',
'Вайлдберриз' => 'wildberries',
'Авито' => 'avito',
'YClients' => 'yclients',
'ЮКасса' => 'yookassa',
'OpenAI' => 'openai'
];
// Render page
$page = $this->view->render(
'main/index.html',
[
'smartphone' => $this->request->smartphone,
'tablet' => $this->request->tablet
]
);
// Sending response
$this->response
->start()
->clean()
->sse()
->write($page)
->validate($this->request)
?->body()
->end();
// Deinitializing rendered page
unset($page);
// Exit (success)
return null;
}
// Exit (fail)
return null;
}
}

View File

@@ -2,19 +2,19 @@
declare(strict_types=1);
namespace kodorvan\perm\controllers;
namespace kodorvan\site\controllers;
// Files of the project
use kodorvan\perm\controllers\core;
use kodorvan\site\controllers\core;
// Framework for PHP
use mirzaev\minimal\http\enumerations\content,
mirzaev\minimal\http\enumerations\status;
/**
* Index
* Offer
*
* @package kodorvan\perm\controllers
* @package kodorvan\site\controllers
*
* @param array $errors Registry of errors
*
@@ -23,7 +23,7 @@ use mirzaev\minimal\http\enumerations\content,
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
*/
final class index extends core
final class offer extends core
{
/**
* Errors
@@ -35,7 +35,7 @@ final class index extends core
];
/**
* Main page
* Page: offer
*
* @return null
*/
@@ -44,8 +44,30 @@ final class index extends core
if (str_contains($this->request->headers['accept'] ?? '', content::html->value)) {
// Request for HTML response
// Initializing contacts data
$this->view->contacts = [
'sim' => [
'requests' => [
'full' => PROJECT_CONTACTS_SIM_REQUESTS ?? 'Ошибка',
'country' => PROJECT_CONTACTS_SIM_REQUESTS_COUNTRY ?? 'Ошибка',
'operator' => PROJECT_CONTACTS_SIM_REQUESTS_OPERATOR ?? 'Ошибка',
'number' => [
PROJECT_CONTACTS_SIM_REQUESTS_NUMBER_1 ?? 'Ошибка',
PROJECT_CONTACTS_SIM_REQUESTS_NUMBER_2 ?? 'Ошибка',
PROJECT_CONTACTS_SIM_REQUESTS_NUMBER_3 ?? 'Ошибка'
]
]
]
];
// Render page
$page = $this->view->render('index.html');
$page = $this->view->render(
'main/offer.html',
[
'smartphone' => $this->request->smartphone,
'tablet' => $this->request->tablet
]
);
// Sending response
$this->response

View File

@@ -0,0 +1,126 @@
<?php
declare(strict_types=1);
namespace kodorvan\site\controllers;
// Files of the project
use kodorvan\site\controllers\core;
// PHP framework
use mirzaev\minimal\http\enumerations\content,
mirzaev\minimal\http\enumerations\status;
// Mail server
use PHPMailer\PHPMailer\PHPMailer as mail,
PHPMailer\PHPMailer\SMTP as smtp,
PHPMailer\PHPMailer\Exception as mail_exception;
/**
* Index
*
* @package kodorvan\site\controllers
*
* @param array $errors Registry of errors
*
* @method null index() Main page
*
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
*/
final class project extends core
{
/**
* Errors
*
* @var array $errors Registry of errors
*/
protected array $errors = [
'system' => []
];
/**
*
*
* @return null
*/
public function request(string $request): null
{
// Initializing the project identifier (temporary solution)
$identifier = blake3($request, 20);
// Initializing the project storage path
$path = STORAGE . DIRECTORY_SEPARATOR . 'projects' . DIRECTORY_SEPARATOR . $identifier;
// Initializing the project storage directory in the storage
if (!file_exists($path)) mkdir($path, 0775, true);
// Declaring the project storage files registry
$files = [];
foreach ($this->request->files as $file) {
// Iterating over files
// Initializing the file destination path
$destination = $path . DIRECTORY_SEPARATOR . $file['name'];
// Writing the file into the project storage
copy($file['tmp_name'], $destination);
// Writing the file destination path into the project storage files registry
$files[$file['name']] = $destination;
}
// Decoding the request JSON argument
$request = json_decode(json: $request, associative: true, depth: 5);
// Initializing the mail server
$mail = new mail(true);
try {
// Writing the mail server parameters
/* $mail->SMTPDebug = smtp::DEBUG_SERVER; */
$mail->setLanguage('ru');
$mail->CharSet = mail::CHARSET_UTF8;
$mail->isSMTP();
$mail->Host = 'smtp.mail.ru';
$mail->SMTPAuth = true;
$mail->Username = 'system@kodorvan.tech';
$mail->Password = 'c6oQF2nY0javI312eDS0';
$mail->SMTPSecure = mail::ENCRYPTION_SMTPS;
$mail->Port = 465;
$mail->setFrom('system@kodorvan.tech', 'Система');
$mail->addAddress('request@kodorvan.tech', 'Заявки');
// The message
$mail->isHTML(true);
$mail->Subject = empty($request['project']['name']) ? 'Заказ' : 'Заказ: ' . $request['project']['name'];
$mail->Body = $this->view->render('messages/request.html', $request);
$mail->AltBody = 'This is the body in plain text for non-HTML mail clients';
// Attachments
foreach ($files as $name => $file) {
// Iterating of project storage files registry
// Writing the attachment into the message
$mail->addAttachment($file, $name);
}
// Sending the message
$mail->send();
} catch (mail_exception $exception) {
}
// Sending response
$this->response
->start()
->clean()
->sse()
->validate($this->request)
?->body()
->end();
// Exit (fail)
return null;
}
}

View File

@@ -2,7 +2,7 @@
declare(strict_types=1);
namespace kodorvan\perm\models;
namespace kodorvan\site\models;
// Framework for PHP
use mirzaev\minimal\model,
@@ -14,7 +14,7 @@ use exception;
/**
* Models core
*
* @package kodorvan\perm\models
* @package kodorvan\site\models
*
* @method void __construct() Constructor
*

View File

@@ -0,0 +1,8 @@
@charset "UTF-8";
@font-face {
font-family: 'Akony';
src: url("/fonts/akony/AKONY.ttf");
font-weight: normal;
font-style: normal;
}

View File

@@ -0,0 +1,50 @@
@charset "UTF-8";
@font-face {
font-family: 'Cascadia Code';
src: url("/fonts/cascadia_code/CascadiaCode-ExtraLight.woff2");
font-weight: 100;
font-style: normal;
}
@font-face {
font-family: 'Cascadia Code';
src: url("/fonts/cascadia_code/CascadiaCode-Light.woff2");
font-weight: 200;
font-style: normal;
}
@font-face {
font-family: 'Cascadia Code';
src: url("/fonts/cascadia_code/CascadiaCode-SemiLight.woff2");
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: 'Cascadia Code';
src: url("/fonts/cascadia_code/CascadiaCode-Regular.woff2");
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'Cascadia Code';
src: url("/fonts/cascadia_code/CascadiaCode-Regular.woff2");
font-weight: 500;
font-style: normal;
}
@font-face {
font-family: 'Cascadia Code';
src: url("/fonts/cascadia_code/CascadiaCode-SemiBold.woff2");
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: 'Cascadia Code';
src: url("/fonts/cascadia_code/CascadiaCode-Bold.woff2");
font-weight: 700;
font-style: normal;
}

View File

@@ -0,0 +1,6 @@
@charset "UTF-8";
@font-face {
font-family: 'Commissioner';
src: url('/fonts/commissioner.ttf');
}

View File

@@ -0,0 +1,6 @@
@charset "UTF-8";
@font-face {
font-family: 'Compacta';
src: url("/fonts/compacta/compacta_lt_light_compress.otf");
}

View File

@@ -0,0 +1,8 @@
@charset "UTF-8";
@font-face {
font-family: 'Eitai';
src: url("/fonts/eitai/eitai.otf");
font-weight: normal;
font-style: normal;
}

View File

@@ -0,0 +1,15 @@
@charset "UTF-8";
@font-face {
font-family: 'GOST';
src: url("/fonts/gost/GOST 2.304-81 type A.ttf");
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: 'GOST';
src: url("/fonts/gost/GOST 2.304-81 type B.ttf");
font-weight: 400;
font-style: normal;
}

View File

@@ -0,0 +1,8 @@
@charset "UTF-8";
@font-face {
font-family: 'Industry';
src: url("/fonts/industry/Industry-Bold_RUS.ttf");
font-weight: normal;
font-style: normal;
}

View File

@@ -0,0 +1,63 @@
@charset "UTF-8";
@font-face {
font-family: 'MT Sans';
src: url("/fonts/mt_sans/MTSans-LightCondensed.ttf");
font-weight: 100;
font-style: normal;
}
@font-face {
font-family: 'MT Sans';
src: url("/fonts/mt_sans/MTSans-LightCondensed.ttf");
font-weight: 200;
font-style: normal;
}
@font-face {
font-family: 'MT Sans';
src: url("/fonts/mt_sans/MTSans-LightCondensed.ttf");
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: 'MT Sans';
src: url("/fonts/mt_sans/MTSans-RegularCondensed.ttf");
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'MT Sans';
src: url("/fonts/mt_sans/MTSans-RegularCondensed.ttf");
font-weight: 500;
font-style: normal;
}
@font-face {
font-family: 'MT Sans';
src: url("/fonts/mt_sans/MTSans-Bold.ttf");
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: 'MT Sans';
src: url("/fonts/mt_sans/MTSans-BoldCondensed.ttf");
font-weight: 700;
font-style: normal;
}
@font-face {
font-family: 'MT Sans';
src: url("/fonts/mt_sans/MTSans-BlackCondensed.ttf");
font-weight: 800;
font-style: normal;
}
@font-face {
font-family: 'MT Sans';
src: url("/fonts/mt_sans/MTSans-BlackExtended.ttf");
font-weight: 900;
font-style: normal;
}

View File

@@ -0,0 +1,64 @@
@charset "UTF-8";
@font-face {
font-family: 'Nunito';
src: url("/fonts/nunito/Nunito-ExtraLight.ttf");
font-weight: 100;
font-style: normal;
}
@font-face {
font-family: 'Nunito';
src: url("/fonts/nunito/Nunito-Light.ttf");
font-weight: 200;
font-style: normal;
}
@font-face {
font-family: 'Nunito';
src: url("/fonts/nunito/Nunito-Regular.ttf");
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: 'Nunito';
src: url("/fonts/nunito/Nunito-Regular.ttf");
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'Nunito';
src: url("/fonts/nunito/Nunito-Medium.ttf");
font-weight: 500;
font-style: normal;
}
@font-face {
font-family: 'Nunito';
src: url("/fonts/nunito/Nunito-Bold.ttf");
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: 'Nunito';
src: url("/fonts/nunito/Nunito-ExtraBold.ttf");
font-weight: 700;
font-style: normal;
}
@font-face {
font-family: 'Nunito';
src: url("/fonts/nunito/Nunito-Black.ttf");
font-weight: 800;
font-style: normal;
}
@font-face {
font-family: 'Nunito';
src: url("/fonts/nunito/Nunito-Black.ttf");
font-weight: 900;
font-style: normal;
}

View File

@@ -0,0 +1,8 @@
@charset "UTF-8";
@font-face {
font-family: 'Palui';
src: url("/fonts/palui/PaluiSPDemo-Bold.otf");
font-weight: normal;
font-style: normal;
}

View File

@@ -0,0 +1,6 @@
@charset "UTF-8";
@font-face {
font-family: 'Slifted';
src: url("/fonts/slifted/slifted.otf");
}

View File

@@ -0,0 +1,6 @@
@charset "UTF-8";
@font-face {
font-family: 'Urban Slavic';
src: url("/fonts/urban_slavic/UrbanSlavic.otf");
}

View File

@@ -0,0 +1,6 @@
@charset "UTF-8";
@font-face {
font-family: 'Vredina';
src: url("/fonts/vredina/SAVredina-ThinUltraCondensed.woff");
}

View File

@@ -0,0 +1 @@
../../../../../icons/css

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More