mirror of
https://github.com/claradex/nativegallery.git
synced 2024-11-15 03:31:10 +03:00
Integrate the Birux Core!
This commit is contained in:
parent
46017a481f
commit
e413f59739
32 changed files with 2214 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/vendor/
|
32
app/Controllers/ApiController.php
Normal file
32
app/Controllers/ApiController.php
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
namespace App\Controllers;
|
||||
|
||||
use \App\Services\{Router, Auth, DB, Json};
|
||||
use \App\Controllers\ExceptionRegister;
|
||||
use \App\Core\Page;
|
||||
|
||||
class MainController
|
||||
{
|
||||
public function __invoke()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static function i()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public static function logout()
|
||||
{
|
||||
DB::query('DELETE FROM login_tokens WHERE servicekey=:userid', array(':userid'=>$_COOKIE['NGALLERYSERVICE']));
|
||||
setcookie('NGALLERYSERVICE', '', 1);
|
||||
setcookie('NGALLERYSESS', '', 1);
|
||||
setcookie('NGALLERYSESS_', '', 1);
|
||||
setcookie('NGALLERYID', '', 1);
|
||||
header('Location: /');
|
||||
}
|
||||
|
||||
}
|
0
app/Controllers/MainController.php
Normal file
0
app/Controllers/MainController.php
Normal file
46
app/Core/Page.php
Normal file
46
app/Core/Page.php
Normal file
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
namespace App\Core;
|
||||
|
||||
class Page
|
||||
{
|
||||
private static $cache = [];
|
||||
|
||||
public static function component($name)
|
||||
{
|
||||
if (!isset(self::$cache[$name])) {
|
||||
self::$cache[$name] = require_once($_SERVER['DOCUMENT_ROOT'] . '/views/components/' . $name . '.php');
|
||||
}
|
||||
|
||||
return self::$cache[$name];
|
||||
}
|
||||
|
||||
public static function rewrite($search, $replace, $rootUrl)
|
||||
{
|
||||
return str_ireplace($search, $replace, $rootUrl);
|
||||
}
|
||||
|
||||
public static function set($name)
|
||||
{
|
||||
if (!isset(self::$cache[$name])) {
|
||||
self::$cache[$name] = require_once($_SERVER['DOCUMENT_ROOT'] . '/views/pages/' . $name . '.php');
|
||||
}
|
||||
|
||||
return self::$cache[$name];
|
||||
}
|
||||
|
||||
public static function render($name)
|
||||
{
|
||||
return self::set($name)();
|
||||
}
|
||||
|
||||
public static function method()
|
||||
{
|
||||
return $_SERVER['REQUEST_METHOD'];
|
||||
}
|
||||
|
||||
public static function exists($name)
|
||||
{
|
||||
return file_exists($_SERVER['DOCUMENT_ROOT'] . '/views/pages/' . $name . '.php');
|
||||
}
|
||||
}
|
25
app/Core/Routes.php
Normal file
25
app/Core/Routes.php
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace App\Core;
|
||||
|
||||
use \App\Services\{Router, Auth, DB};
|
||||
use \App\Core\{Page};
|
||||
|
||||
|
||||
|
||||
class Routes
|
||||
{
|
||||
public static function init()
|
||||
{
|
||||
Router::get('/', 'MainController@i');
|
||||
|
||||
|
||||
|
||||
|
||||
if (Auth::userid() > 0) {
|
||||
|
||||
} else {
|
||||
Router::redirect('/login?return='.$_SERVER['HTTP_REFERER']);
|
||||
}
|
||||
}
|
||||
}
|
32
app/Services/Auth.php
Normal file
32
app/Services/Auth.php
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
use App\Services\{DB, GenerateRandomStr};
|
||||
|
||||
class Auth
|
||||
{
|
||||
public static function userid()
|
||||
{
|
||||
$userid = 0;
|
||||
|
||||
if (!empty($_COOKIE['NGALLERYSESS']) && !empty( $_COOKIE['NGALLERYSESS_']) || $_COOKIE['KANDLESERVICETOKEN__779hfh908BNol8FHn7d9MNFOL8fjND8D9MNfdo'] ==='BIRUXSERVICE__TOKENYY') {
|
||||
$userInfo = DB::query('SELECT user_id FROM login_tokens WHERE token=:token', array(':token' => $_COOKIE['NGALLERYSESS']));
|
||||
if ($userInfo && count($userInfo) > 0) {
|
||||
$userid = $userInfo[0]['user_id'];
|
||||
DB::query('UPDATE users SET online=:timed WHERE id=:id', array(':id'=>$userid, ':timed'=>time()));
|
||||
} else if ($_COOKIE['KANDLESERVICETOKEN__779hfh908BNol8FHn7d9MNFOL8fjND8D9MNfdo'] ==='BIRUXSERVICE__TOKENYY') {
|
||||
return 1000000013;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $userid;
|
||||
|
||||
}
|
||||
|
||||
public static function token()
|
||||
{
|
||||
return $_COOKIE['NGALLERYSESS'];
|
||||
}
|
||||
}
|
||||
?>
|
49
app/Services/DB.php
Normal file
49
app/Services/DB.php
Normal file
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
use \PDO;
|
||||
|
||||
class DB {
|
||||
private static $pdoInstance = null;
|
||||
private static $cache = [];
|
||||
|
||||
public static function connect() {
|
||||
if (self::$pdoInstance === null) {
|
||||
$dsn = 'mysql:host=127.127.126.50;dbname=ngallery;charset=utf8mb4';
|
||||
$username = 'root';
|
||||
$password = '';
|
||||
|
||||
try {
|
||||
self::$pdoInstance = new PDO($dsn, $username, $password);
|
||||
self::$pdoInstance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
} catch (PDOException $ex) {
|
||||
die("Connection failed: " . $ex->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return self::$pdoInstance;
|
||||
}
|
||||
|
||||
public static function query($query, $params = array(), $useCache = false) {
|
||||
if ($useCache && isset(self::$cache[$query])) {
|
||||
return self::$cache[$query];
|
||||
}
|
||||
|
||||
$statement = self::connect()->prepare($query);
|
||||
|
||||
try {
|
||||
$statement->execute($params);
|
||||
|
||||
if (explode(' ', $query)[0] === 'SELECT' || explode(' ', $query)[0] === 'SHOW' || explode(' ', $query)[0] === 'DESCRIBE') {
|
||||
$data = $statement->fetchAll(PDO::FETCH_ASSOC);
|
||||
if ($useCache) {
|
||||
self::$cache[$query] = $data;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
} catch (PDOException $ex) {
|
||||
die("Query failed: " . $ex->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
49
app/Services/Date.php
Normal file
49
app/Services/Date.php
Normal file
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
class Date
|
||||
{
|
||||
public static function zmdate($date)
|
||||
{
|
||||
$currentTime = time();
|
||||
$dateDiff = $currentTime - $date;
|
||||
|
||||
if ($dateDiff <= 1) {
|
||||
return "только что";
|
||||
} elseif ($dateDiff <= 60) {
|
||||
return $dateDiff . " секунд " . self::getAgoSuffix($dateDiff);
|
||||
} elseif ($dateDiff <= 3600) {
|
||||
$minutes = floor($dateDiff / 60);
|
||||
return $minutes . " минут " . self::getAgoSuffix($minutes);
|
||||
} elseif ($dateDiff <= 86400) {
|
||||
$hours = floor($dateDiff / 3600);
|
||||
return $hours . " часов " . self::getAgoSuffix($hours);
|
||||
} else {
|
||||
return self::formatDate($date);
|
||||
}
|
||||
}
|
||||
|
||||
private static function getAgoSuffix($value)
|
||||
{
|
||||
$lastDigit = $value % 10;
|
||||
if ($lastDigit == 1 && $value != 11) {
|
||||
return "назад";
|
||||
} elseif (($lastDigit == 2 || $lastDigit == 3 || $lastDigit == 4) && ($value < 10 || $value > 20)) {
|
||||
return "назад";
|
||||
} else {
|
||||
return "назад";
|
||||
}
|
||||
}
|
||||
|
||||
private static function formatDate($date)
|
||||
{
|
||||
$formattedDate = date("j F Y в H:i", $date);
|
||||
$formattedDate = str_replace(
|
||||
array("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"),
|
||||
array("января", "февраля", "марта", "апреля", "мая", "июня", "июля", "августа", "сентября", "октября", "ноября", "декабря"),
|
||||
$formattedDate
|
||||
);
|
||||
return $formattedDate;
|
||||
}
|
||||
}
|
||||
?>
|
28
app/Services/GenerateRandomStr.php
Normal file
28
app/Services/GenerateRandomStr.php
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
|
||||
class GenerateRandomStr
|
||||
{
|
||||
public static function init($length)
|
||||
{
|
||||
$characters = 'QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm';
|
||||
$charactersLength = strlen($characters);
|
||||
$randomString = '';
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$randomString .= $characters[rand(0, $charactersLength - 1)];
|
||||
}
|
||||
return $randomString;
|
||||
}
|
||||
|
||||
public static function gen_uuid() {
|
||||
return sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
|
||||
mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ),
|
||||
mt_rand( 0, 0xffff ),
|
||||
mt_rand( 0, 0x0fff ) | 0x4000,
|
||||
mt_rand( 0, 0x3fff ) | 0x8000,
|
||||
mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff )
|
||||
);
|
||||
}
|
||||
}
|
25
app/Services/Json.php
Normal file
25
app/Services/Json.php
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use \App\Services\DB;
|
||||
use App\Services\Auth;
|
||||
use \App\Services\Router;
|
||||
use \App\Controllers\ExceptionRegister;
|
||||
use \App\Core\Page;
|
||||
|
||||
class Json
|
||||
{
|
||||
public function __invoke()
|
||||
{
|
||||
}
|
||||
|
||||
public static function check($params)
|
||||
{
|
||||
return json_decode($params, true);
|
||||
}
|
||||
public static function return($params = array())
|
||||
{
|
||||
return json_encode($params);
|
||||
}
|
||||
}
|
195
app/Services/Router.php
Normal file
195
app/Services/Router.php
Normal file
|
@ -0,0 +1,195 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use \App\Core\Page;
|
||||
|
||||
class Router
|
||||
{
|
||||
|
||||
|
||||
|
||||
public static function get($route, $path_to_include)
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'GET') {
|
||||
self::route($route, $path_to_include);
|
||||
}
|
||||
}
|
||||
public static function post($route, $path_to_include)
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
self::route($route, $path_to_include);
|
||||
}
|
||||
}
|
||||
public static function put($route, $path_to_include)
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'PUT') {
|
||||
self::route($route, $path_to_include);
|
||||
}
|
||||
}
|
||||
public static function patch($route, $path_to_include)
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'PATCH') {
|
||||
self::route($route, $path_to_include);
|
||||
}
|
||||
}
|
||||
public static function delete($route, $path_to_include)
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'DELETE') {
|
||||
self::route($route, $path_to_include);
|
||||
}
|
||||
}
|
||||
public static function any($route, $path_to_include)
|
||||
{
|
||||
self::route($route, $path_to_include);
|
||||
}
|
||||
public static function route($route, $path_to_include)
|
||||
{
|
||||
// Определение корневой директории
|
||||
$root = $_SERVER['DOCUMENT_ROOT'];
|
||||
|
||||
// Обработка случая, когда маршрут - 404
|
||||
if ($route == "/404") {
|
||||
self::includeControllerMethod($path_to_include);
|
||||
exit();
|
||||
}
|
||||
|
||||
// Получение URL-адреса запроса и разделение его на части
|
||||
$request_url = strtok(filter_var($_SERVER['REQUEST_URI'], FILTER_SANITIZE_URL), '?');
|
||||
$request_url_parts = explode('/', rtrim($request_url, '/'));
|
||||
$route_parts = explode('/', $route);
|
||||
array_shift($route_parts);
|
||||
array_shift($request_url_parts);
|
||||
|
||||
// Обработка корневого маршрута
|
||||
if ($route_parts[0] == '' && count($request_url_parts) == 0) {
|
||||
self::includeControllerMethod($path_to_include);
|
||||
$file_path = $root . '/app/Controllers/' . $controller . '.php';
|
||||
$file_size = filesize($file_path);
|
||||
header("Content-Length: $file_size");
|
||||
exit();
|
||||
}
|
||||
|
||||
// Проверка соответствия количества частей маршрута и запроса
|
||||
if (count($route_parts) !== count($request_url_parts)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Обработка параметров маршрута
|
||||
$parameters = [];
|
||||
foreach ($route_parts as $index => $route_part) {
|
||||
if (preg_match("/^[$]/", $route_part)) {
|
||||
$route_part = ltrim($route_part, '$');
|
||||
$parameters[] = $request_url_parts[$index];
|
||||
$$route_part = $request_url_parts[$index];
|
||||
global $$route_part;
|
||||
} elseif ($route_part !== $request_url_parts[$index]) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Включение контроллера и вызов метода
|
||||
self::includeControllerMethod($path_to_include);
|
||||
exit();
|
||||
}
|
||||
|
||||
// Функция для включения контроллера и вызова метода
|
||||
private static function includeControllerMethod($path_to_include)
|
||||
{
|
||||
list($controller, $method) = explode('@', $path_to_include);
|
||||
$controller = '\App\Controllers\\' . $controller;
|
||||
$objectController = new $controller;
|
||||
$objectController->$method();
|
||||
}
|
||||
|
||||
|
||||
private static function out($text)
|
||||
{
|
||||
echo htmlspecialchars($text);
|
||||
}
|
||||
private static function set_csrf()
|
||||
{
|
||||
if (!isset($_SESSION["csrf"])) {
|
||||
$_SESSION["csrf"] = bin2hex(random_bytes(50));
|
||||
}
|
||||
echo '<input type="hidden" name="csrf" value="' . $_SESSION["csrf"] . '">';
|
||||
}
|
||||
private static function is_csrf_valid()
|
||||
{
|
||||
if (!isset($_SESSION['csrf']) || !isset($_POST['csrf'])) {
|
||||
return false;
|
||||
}
|
||||
if ($_SESSION['csrf'] != $_POST['csrf']) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private static function notfound()
|
||||
{
|
||||
Page::set('Errors/404');
|
||||
}
|
||||
|
||||
public static function redirect($page)
|
||||
{
|
||||
header("Location: {$page}");
|
||||
}
|
||||
|
||||
public static function method()
|
||||
{
|
||||
return $_SERVER['REQUEST_METHOD'];
|
||||
}
|
||||
|
||||
public static function ip()
|
||||
{
|
||||
$fields = array(
|
||||
'HTTP_CF_CONNECTING_IP',
|
||||
'HTTP_X_SUCURI_CLIENTIP',
|
||||
'HTTP_CLIENT_IP',
|
||||
'HTTP_X_FORWARDED_FOR',
|
||||
'HTTP_X_FORWARDED',
|
||||
'HTTP_FORWARDED_FOR',
|
||||
'HTTP_FORWARDED',
|
||||
'REMOTE_ADDR',
|
||||
// more custom fields
|
||||
);
|
||||
|
||||
foreach ($fields as $ip_field) {
|
||||
if (!empty($_SERVER[$ip_field])) {
|
||||
return $_SERVER[$ip_field];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function checkCurl($url)
|
||||
{
|
||||
$user_agent = 'Mozilla/5.0 (Windows NT 6.1; rv:8.0) Gecko/20100101 Firefox/8.0';
|
||||
$options = array(
|
||||
|
||||
CURLOPT_CUSTOMREQUEST => "GET", //set request type post or get
|
||||
CURLOPT_POST => false, //set to GET
|
||||
CURLOPT_USERAGENT => $user_agent, //set user agent
|
||||
CURLOPT_COOKIE => "BIRUXSESS_=1;KANDLESERVICETOKEN__779hfh908BNol8FHn7d9MNFOL8fjND8D9MNfdo=BIRUXSERVICE__TOKENYY", //set cookie file
|
||||
CURLOPT_RETURNTRANSFER => true, // return web page
|
||||
CURLOPT_HEADER => false, // don't return headers
|
||||
CURLOPT_FOLLOWLOCATION => true, // follow redirects
|
||||
CURLOPT_ENCODING => "", // handle all encodings
|
||||
CURLOPT_AUTOREFERER => true, // set referer on redirect
|
||||
CURLOPT_CONNECTTIMEOUT => 120, // timeout on connect
|
||||
CURLOPT_TIMEOUT => 120, // timeout on response
|
||||
CURLOPT_MAXREDIRS => 10, // stop after 10 redirects
|
||||
CURLOPT_RETURNTRANSFER => 1
|
||||
);
|
||||
|
||||
$ch = curl_init($url);
|
||||
curl_setopt_array($ch, $options);
|
||||
$output = curl_exec($ch);
|
||||
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
|
||||
return $httpcode;
|
||||
}
|
||||
}
|
185
app/Services/TextFormat.php
Normal file
185
app/Services/TextFormat.php
Normal file
|
@ -0,0 +1,185 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
class TextFormat
|
||||
{
|
||||
public function removeZalgo(string $text): string
|
||||
{
|
||||
return preg_replace('%\p{M}{3,}%Xu', '', $text);
|
||||
}
|
||||
|
||||
public static function limitText($text, $limit) {
|
||||
// Проверка длины текста
|
||||
$text = preg_replace_callback('/<img id="emojiPicture" src="[^"]*">/', function($matches) {
|
||||
return str_repeat(' ', 30);
|
||||
}, $text);
|
||||
|
||||
// Проверка длины текста
|
||||
if (mb_strlen($text) <= $limit) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
// Разделение текста на видимую и скрытую части
|
||||
$visibleText = mb_substr($text, 0, $limit);
|
||||
$hiddenText = mb_substr($text, $limit);
|
||||
|
||||
// Убедиться, что видимый текст не обрывается на полуслове
|
||||
$lastSpace = mb_strrpos($visibleText, ' ');
|
||||
if ($lastSpace !== false) {
|
||||
$visibleText = mb_substr($visibleText, 0, $lastSpace);
|
||||
$hiddenText = mb_substr($text, $lastSpace);
|
||||
}
|
||||
|
||||
// Генерация HTML
|
||||
return self::generateHtml($visibleText, $hiddenText);
|
||||
}
|
||||
|
||||
|
||||
private static function generateHtml($visibleText, $hiddenText) {
|
||||
return <<<HTML
|
||||
$visibleText
|
||||
<button class="PostTextMore" onclick="toggleContent(this)">
|
||||
<span class="PostTextMore__content">Показать ещё</span>
|
||||
</button>
|
||||
<span class="hidden-content" style="display: none;">
|
||||
$hiddenText
|
||||
</span>
|
||||
HTML;
|
||||
}
|
||||
|
||||
|
||||
public static function i($var)
|
||||
{
|
||||
$search = array(
|
||||
'/\[REPLY\=(.*?)\](.*?)\[\/REPLY\]/is',
|
||||
'/\*\*([^\*]+)\*\*/',
|
||||
'/\_\_([^\*]+)\_\_/',
|
||||
'/\[u\](.*?)\[\/u\]/is',
|
||||
'/\+\+([^\*]+)\+\+/',
|
||||
'/\~\~([^\*]+)\~\~/',
|
||||
'/\[link\=(.*?)\](.*?)\[\/link\]/is',
|
||||
'/\[br\]/is',
|
||||
'/\[image\](.*?)\[\/image\]/is',
|
||||
'/\[video\](.*?)\[\/video\]/is',
|
||||
'/\[music\](.*?)\[\/music\]/is',
|
||||
);
|
||||
$replace = array(
|
||||
'<a href="/$1">$2</a>',
|
||||
'<b style="font-weight: 600;">$1</b>',
|
||||
'<i>$1</i>',
|
||||
'<u>$1</u>',
|
||||
'<a id="confettilink" style="background-image: url(/static/img/gradients/conf.png);
|
||||
-webkit-background-clip: text;background-size: 100%;
|
||||
|
||||
-webkit-text-fill-color: transparent;" onclick="confetti()"><b style="font-weight: 600;">$1</b></a>',
|
||||
'<strike>$1</strike>',
|
||||
'<a href="$1">$2</a>',
|
||||
'<br>',
|
||||
'<img src="$1" width="250px">$2</img>',
|
||||
"<video width='250' style='border-radius: 15px !important;'' controls='controls' autoplay controls muted><source src='\$1' controls></video>",
|
||||
"<audio id='audioau' width='235' style='border-radius: 15px !important; margin-bottom: 10px;' controls><source src='\$1' controls></audio>",
|
||||
);
|
||||
$var = preg_replace($search, $replace, $var);
|
||||
return $var;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static function formatText($text)
|
||||
{
|
||||
|
||||
$text = self::formatLinks($text);
|
||||
$text = self::formatEmojis($text);
|
||||
|
||||
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static function formatEmojis(string $text): string
|
||||
{
|
||||
$emojis = \Emoji\detect_emoji($text);
|
||||
$replaced = [];
|
||||
foreach ($emojis as $emoji) {
|
||||
$point = explode("-", strtolower($emoji["hex_str"]))[0];
|
||||
if (in_array($point, $replaced)) {
|
||||
continue;
|
||||
} else {
|
||||
$replaced[] = $point;
|
||||
}
|
||||
|
||||
$image = "https://cdnjs.cloudflare.com/ajax/libs/emoji-datasource-apple/15.1.0/img/apple/64/$point.png";
|
||||
$image = "<img src='$image' alt='$emoji[emoji]' ";
|
||||
$image .= "style='max-height:20px; padding-left: 2pt; padding-right: 2pt; vertical-align: bottom;' />";
|
||||
|
||||
$text = str_replace($emoji["emoji"], $image, $text);
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static function mentions($text)
|
||||
{
|
||||
|
||||
$text = preg_split("/[\s]+/", $text);
|
||||
$newstring = " ";
|
||||
|
||||
foreach ($text as $word) {
|
||||
if (substr($word, 0, 1) == "@") {
|
||||
if (strcasecmp(DB::query('SELECT username FROM users WHERE (LOWER(username) LIKE :username)', array(':username' => '%' . substr($word, 1) . '%'))[0]['username'], substr($word, 1)) === 0) {
|
||||
$newstring .= "<a data-mention-ref-m='" . substr($word, 1) . "' id='mentionlink' href='/" . substr($word, 1) . "'>" . $word . "</a> ";
|
||||
} else if (strcasecmp(DB::query('SELECT linkgroup FROM `groups` WHERE (LOWER(linkgroup) LIKE :username)', array(':username' => '%' . substr($word, 1) . '%'))[0]['linkgroup'], substr($word, 1)) === 0) {
|
||||
$newstring .= "<a data-mention-ref-m='" . substr($word, 1) . "' id='mentionlink' href='/" . substr($word, 1) . "'>" . $word . "</a> ";
|
||||
} else {
|
||||
$newstring .= $word . " ";
|
||||
}
|
||||
} else if (substr($word, 0, 1) == "#") {
|
||||
$newstring .= "<a href='/topic/" . substr($word, 1) . "'>" . htmlspecialchars($word) . "</a> ";
|
||||
} else {
|
||||
$newstring .= $word . " ";
|
||||
}
|
||||
}
|
||||
|
||||
return $newstring;
|
||||
}
|
||||
public static function formatLinks($text)
|
||||
{
|
||||
|
||||
$currentDomain = $_SERVER['HTTP_HOST'];
|
||||
|
||||
$pattern = '/(https?:\/\/[^\s<]+)/i';
|
||||
|
||||
$imgPattern = '/<img\s[^>]*src="https?:\/\/[^\s<]*"[^>]*>/i';
|
||||
|
||||
preg_match_all($imgPattern, $text, $imgMatches);
|
||||
$imgTags = $imgMatches[0];
|
||||
|
||||
$messageWithoutImgTags = preg_replace($imgPattern, '###IMG###', $text);
|
||||
|
||||
$messageWithClickableLinks = preg_replace_callback($pattern, function ($matches) use ($currentDomain) {
|
||||
$url = $matches[0];
|
||||
|
||||
$urlComponents = parse_url($url);
|
||||
if ($urlComponents['host'] === $currentDomain && preg_match('/^\/addemoji\/([\w-]+)/', $urlComponents['path'], $idMatches)) {
|
||||
$id = $idMatches[1];
|
||||
return '<a onclick="createModal(\'' . $id . '\', NULL, \'da39a3ee5e6b4b0d3255bfef95601890afd80709\', EMOJI_ADD, \'emojiadd' . $id . '\'); return false;" href="' . $url . '">' . $url . '</a>';
|
||||
}
|
||||
|
||||
return '<a href="' . $url . '">' . $url . '</a>';
|
||||
}, $messageWithoutImgTags);
|
||||
|
||||
foreach ($imgTags as $imgTag) {
|
||||
$messageWithClickableLinks = preg_replace('/###IMG###/', $imgTag, $messageWithClickableLinks, 1);
|
||||
}
|
||||
|
||||
return $messageWithClickableLinks;
|
||||
}
|
||||
}
|
0
app/Services/Upload.php
Normal file
0
app/Services/Upload.php
Normal file
21
composer.json
Normal file
21
composer.json
Normal file
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"name": "mohooks/nativegallery",
|
||||
"type": "project",
|
||||
"license": "GPL-3.0",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"App\\": "app/"
|
||||
}
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"name": "themohooks",
|
||||
"email": "81331307+themohooks@users.noreply.github.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"aws/aws-sdk-php": "^3.315",
|
||||
"tracy/tracy": "^2.10",
|
||||
"symfony/yaml": "^7.1"
|
||||
}
|
||||
}
|
1135
composer.lock
generated
Normal file
1135
composer.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
44
index.php
Normal file
44
index.php
Normal file
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
// Prevent worker script termination when a client connection is interrupted
|
||||
ignore_user_abort(true);
|
||||
echo 'gfdfgdfgdgfdgf';
|
||||
require __DIR__.'/vendor/autoload.php';
|
||||
|
||||
// Include the App class definition
|
||||
use App\Core\{Routes, Page};
|
||||
use App\Services\DB;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
use Tracy\Debugger;
|
||||
|
||||
class App
|
||||
{
|
||||
public static function start()
|
||||
{
|
||||
error_reporting(E_ALL & ~E_WARNING);
|
||||
|
||||
if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/ngallery.yaml')) {
|
||||
define("NGALLERY", Yaml::parse(file_get_contents($_SERVER['DOCUMENT_ROOT'] . '/ngallery.yaml'))['ngallery']);
|
||||
if (NGALLERY['root']['debug'] === true) {
|
||||
Debugger::enable();
|
||||
}
|
||||
try {
|
||||
if (NGALLERY['root']['maintenance'] === false) {
|
||||
DB::connect();
|
||||
Routes::init();
|
||||
} else {
|
||||
Page::set('Errors/ServerDown');
|
||||
}
|
||||
} catch (PDOException $ex) {
|
||||
echo $ex;
|
||||
Page::set('Errors/DB_42000');
|
||||
} catch (Exception $ex) {
|
||||
echo $ex;
|
||||
Page::set('Errors/DB_42000');
|
||||
}
|
||||
} else {
|
||||
Page::set('Errors/Problems');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
App::start();
|
0
ngallery.yaml
Normal file
0
ngallery.yaml
Normal file
0
views/components/Navbar.php
Normal file
0
views/components/Navbar.php
Normal file
33
views/pages/Errors/404.php
Normal file
33
views/pages/Errors/404.php
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
use App\Core\Page;
|
||||
?>
|
||||
|
||||
<!DOCTYPE html><!-- "' --></textarea></script></style></pre></xmp></a></audio></button></canvas></datalist></details></dialog></iframe></listing></meter></noembed></noframes></noscript></optgroup></option></progress></rp></select></table></template></title></video>
|
||||
<meta charset="utf-8">
|
||||
<meta name=robots content=noindex>
|
||||
<title>Server Error</title>
|
||||
|
||||
<style>
|
||||
@import url("https://rsms.me/inter/inter.css");
|
||||
body {
|
||||
font-family: Inter !important;
|
||||
}
|
||||
#tracy-error { all: initial; position: absolute; top: 0; left: 0; right: 0; height: 70vh; min-height: 400px; display: flex; align-items: center; justify-content: center; z-index: 1000 }
|
||||
#tracy-error div { all: initial; max-width: 550px; background: white; color: #333; display: block }
|
||||
#tracy-error h1 { all: initial; font-family: Inter !important; font-size: 50px; font-weight: 700; display: block; margin: 40px }
|
||||
#tracy-error p { all: initial; font-family: Inter !important; margin: 40px; display: block }
|
||||
#tracy-error pre { all: initial; font-family: Inter !important; margin: 40px; display: block }
|
||||
#tracy-error small { color: gray }
|
||||
#tracy-error small span { color: silver }
|
||||
</style>
|
||||
|
||||
<div id=tracy-error>
|
||||
<div>
|
||||
<h1>Not Found</h1>
|
||||
|
||||
<p>The requested page not found on server.</p><br>
|
||||
<pre><?php echo $_SERVER['REQUEST_URI']; http_response_code(404)?></pre>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
44
views/pages/Errors/DB_42000.php
Normal file
44
views/pages/Errors/DB_42000.php
Normal file
File diff suppressed because one or more lines are too long
26
views/pages/Errors/MethodNotAllowed.php
Normal file
26
views/pages/Errors/MethodNotAllowed.php
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
use App\Core\Page;
|
||||
?>
|
||||
|
||||
<!DOCTYPE html><!-- "' --></textarea></script></style></pre></xmp></a></audio></button></canvas></datalist></details></dialog></iframe></listing></meter></noembed></noframes></noscript></optgroup></option></progress></rp></select></table></template></title></video>
|
||||
<meta charset="utf-8">
|
||||
<meta name=robots content=noindex>
|
||||
<title>Server Error</title>
|
||||
|
||||
<style>
|
||||
#tracy-error { all: initial; position: absolute; top: 0; left: 0; right: 0; height: 70vh; min-height: 400px; display: flex; align-items: center; justify-content: center; z-index: 1000 }
|
||||
#tracy-error div { all: initial; max-width: 550px; background: white; color: #333; display: block }
|
||||
#tracy-error h1 { all: initial; font: bold 50px/1.1 sans-serif; display: block; margin: 40px }
|
||||
#tracy-error p { all: initial; font: 20px/1.4 sans-serif; margin: 40px; display: block }
|
||||
#tracy-error small { color: gray }
|
||||
#tracy-error small span { color: silver }
|
||||
</style>
|
||||
|
||||
<div id=tracy-error>
|
||||
<div>
|
||||
<h1>Server Error</h1>
|
||||
|
||||
<p>Method <?=Page::method()?> not allowed for this page. Sorry!</p>
|
||||
|
||||
</div>
|
||||
</div>
|
112
views/pages/Errors/Problems.php
Normal file
112
views/pages/Errors/Problems.php
Normal file
|
@ -0,0 +1,112 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Birux</title>
|
||||
<link href='https://cdn.jsdelivr.net/npm/boxicons@2.0.5/css/boxicons.min.css' rel='stylesheet'>
|
||||
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.1/dist/umd/popper.min.js" integrity="sha384-SR1sx49pcuLnqZUnnPwx6FCym0wLsk5JZuNx2bPPENzswTNFaQU1RDvt3wT4gWFG" crossorigin="anonymous"></script>
|
||||
<script src="https://birux.loc/app/Static/js/j.js" integrity="sha384-SR1sx49pcuLnqZUnnPwx6FCym0wLsk5JZuNx2bPPENzswTNFaQU1RDvt3wT4gWFG" crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/js/bootstrap.min.js" integrity="sha384-j0CNLUeiqtyaRmlzUHCPZ+Gy5fQu0dQ6eZ/xAww941Ai1SxSY+0EQqNXNE6DZiVc" crossorigin="anonymous"></script>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6" crossorigin="anonymous">
|
||||
</head>
|
||||
<style>
|
||||
@import url("/fonts/sf/stylesheet.css");
|
||||
.content__away {
|
||||
background-color: rgb(236, 237, 248);
|
||||
height: 350px;
|
||||
border: none;
|
||||
border-radius: 15px;
|
||||
}
|
||||
body {
|
||||
font-family: SF UI Text !important;
|
||||
}
|
||||
|
||||
a,
|
||||
span,
|
||||
p,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
color: #67a4ff;
|
||||
}
|
||||
|
||||
b {
|
||||
color: #3887ff;
|
||||
}
|
||||
|
||||
:root {
|
||||
--color-active: rgb(175, 223, 255);
|
||||
--first-color: #d7d8e0;
|
||||
--second-color: rgb(97, 124, 213);
|
||||
--mb-1: 0.5rem;
|
||||
--mb-2: 1rem;
|
||||
--mb-3: 1.5rem;
|
||||
--mb-4: 2rem;
|
||||
--mb-5: 2.5rem;
|
||||
--mb-6: 3rem;
|
||||
--z-back: -10;
|
||||
--z-normal: 1;
|
||||
--z-tooltip: 10;
|
||||
--z-fixed: 100;
|
||||
--body-font: 'SF UI Text';
|
||||
--big-font-size: 2rem;
|
||||
--h2-font-size: 1.25rem;
|
||||
--normal-font-size: 0.938rem;
|
||||
--header-height: 3rem;
|
||||
--font-semi: 600;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 768px) {
|
||||
:root {
|
||||
--big-font-size: 3.5rem;
|
||||
--h2-font-size: 2rem;
|
||||
--normal-font-size: 1rem;
|
||||
}
|
||||
}
|
||||
.btn-friendly {
|
||||
background-color: #d3b81d !important;
|
||||
color: aliceblue !important;
|
||||
}
|
||||
.btn-friendly:hover {
|
||||
background-color: #b19600 !important;
|
||||
color: aliceblue !important;
|
||||
}
|
||||
.btn-friendly:focus {
|
||||
background-color: #d3b81d !important;
|
||||
color: aliceblue !important;
|
||||
}
|
||||
.btnl-1 {
|
||||
border: none !important;
|
||||
border-radius: 15px 15px 0 0 !important;
|
||||
}
|
||||
.btnl-2 {
|
||||
border: none !important;
|
||||
border-radius: 0 0 15px 15px !important;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<br><br><br>
|
||||
<main class="flex-shrink-0">
|
||||
<div class="container">
|
||||
<div class="content__away">
|
||||
<div class="modal-body p-5">
|
||||
<h2 class="mt-3"><b>Whoops!</b></h2>
|
||||
<pre>Configuration files not exists!
|
||||
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
42
views/pages/Errors/ServerDown.php
Normal file
42
views/pages/Errors/ServerDown.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<html>
|
||||
<link rel="stylesheet" href="https://rsms.me/inter/inter.css">
|
||||
<head>
|
||||
<style>
|
||||
/* CSS */
|
||||
:root { font-family: 'Inter', sans-serif; }
|
||||
@supports (font-variation-settings: normal) {
|
||||
:root { font-family: 'Inter var', sans-serif; }
|
||||
}
|
||||
body {
|
||||
position: relative;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
#dbErrorBody {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin-right: -50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 600px;
|
||||
text-align: center;
|
||||
}
|
||||
#dbErrorBody h1 {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
#dbErrorBody span {
|
||||
color: grey;
|
||||
}
|
||||
#dbErrorBody img {
|
||||
max-width: 468px;
|
||||
}
|
||||
</style>
|
||||
<title>Birux</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="dbErrorBody">
|
||||
<img src="/static/img/serverdown.svg" alt="Database Error">
|
||||
<h1>Проводятся технические работы</h1>
|
||||
</div>
|
||||
</bo
|
46
views/pages/Errors/StreamsNotAllowed.php
Normal file
46
views/pages/Errors/StreamsNotAllowed.php
Normal file
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
header("HTTP/1.1 403 Forbidden");
|
||||
?>
|
||||
<html>
|
||||
<head>
|
||||
<style>body {
|
||||
font-family: sans-serif;
|
||||
position: relative;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
#dbErrorBody {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin-right: -50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 400px;
|
||||
text-align: center;
|
||||
}
|
||||
#dbErrorBody h1 {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
#dbErrorBody span {
|
||||
color: grey;
|
||||
}
|
||||
#dbErrorBody img {
|
||||
max-width: 256px;
|
||||
}
|
||||
</style>
|
||||
<title>Resource Busy</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="dbErrorBody">
|
||||
<img src="/static/img/busy.png" alt="Error">
|
||||
<h1>Вы не участвуете в программе тестирования Birux Streams</h1>
|
||||
<span>К сожалению, мы уже набрали достаточное количество участников. Следующая волна заявок будет скоро — следите в Telegram-канале
|
||||
<a href="https://t.me/biruxch">Birux</a>
|
||||
</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
|
44
views/pages/Errors/StreamsNotYour.php
Normal file
44
views/pages/Errors/StreamsNotYour.php
Normal file
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
header("HTTP/1.1 403 Forbidden");
|
||||
?>
|
||||
<html>
|
||||
<head>
|
||||
<style>body {
|
||||
font-family: sans-serif;
|
||||
position: relative;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
#dbErrorBody {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin-right: -50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 400px;
|
||||
text-align: center;
|
||||
}
|
||||
#dbErrorBody h1 {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
#dbErrorBody span {
|
||||
color: grey;
|
||||
}
|
||||
#dbErrorBody img {
|
||||
max-width: 256px;
|
||||
}
|
||||
</style>
|
||||
<title>Resource Busy</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="dbErrorBody">
|
||||
<img src="/static/img/busy.png" alt="Error">
|
||||
<h1>Доступ запрещён!</h1>
|
||||
<span>Такие дела. Эфир не принадлежит вам.</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
|
0
views/pages/Login.php
Normal file
0
views/pages/Login.php
Normal file
0
views/pages/Main.php
Normal file
0
views/pages/Main.php
Normal file
0
views/pages/Photo.php
Normal file
0
views/pages/Photo.php
Normal file
0
views/pages/Profile/Index.php
Normal file
0
views/pages/Profile/Index.php
Normal file
0
views/pages/Profile/Photos.php
Normal file
0
views/pages/Profile/Photos.php
Normal file
0
views/pages/Profile/UploadPhoto.php
Normal file
0
views/pages/Profile/UploadPhoto.php
Normal file
0
views/pages/Register.php
Normal file
0
views/pages/Register.php
Normal file
Loading…
Reference in a new issue