mirror of
https://github.com/claradex/nativegallery.git
synced 2024-11-15 03:31:10 +03:00
photoext add
This commit is contained in:
parent
f238bf776e
commit
b6c6580b96
10 changed files with 223 additions and 66 deletions
77
app/Controllers/Api/Images/Stats.php
Normal file
77
app/Controllers/Api/Images/Stats.php
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controllers\Api\Images;
|
||||||
|
use \App\Services\{Auth, DB};
|
||||||
|
|
||||||
|
class Stats {
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$imageWidth = 1000;
|
||||||
|
$imageHeight = 700;
|
||||||
|
$image = imagecreatetruecolor($imageWidth, $imageHeight);
|
||||||
|
|
||||||
|
$backgroundColor = imagecolorallocate($image, 40, 40, 40);
|
||||||
|
$axisColor = imagecolorallocate($image, 200, 200, 200);
|
||||||
|
$barColor = imagecolorallocate($image, 30, 144, 255);
|
||||||
|
$textColor = imagecolorallocate($image, 255, 255, 255);
|
||||||
|
|
||||||
|
imagefill($image, 0, 0, $backgroundColor);
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
"22.06.2024" => 0,
|
||||||
|
"23.06.2024" => 0,
|
||||||
|
"24.06.2024" => 0,
|
||||||
|
"25.06.2024" => 0,
|
||||||
|
"26.06.2024" => 0,
|
||||||
|
"27.06.2024" => 0,
|
||||||
|
"28.06.2024" => 0,
|
||||||
|
"29.06.2024" => 0,
|
||||||
|
"30.06.2024" => 0,
|
||||||
|
"01.07.2024" => 0,
|
||||||
|
"02.07.2024" => 0,
|
||||||
|
"03.07.2024" => 0,
|
||||||
|
"04.07.2024" => 0,
|
||||||
|
"05.07.2024" => 0,
|
||||||
|
"06.07.2024" => 0,
|
||||||
|
"07.07.2024" => 0,
|
||||||
|
"08.07.2024" => 0,
|
||||||
|
"09.07.2024" => 0,
|
||||||
|
"10.07.2024" => 0,
|
||||||
|
"11.07.2024" => 0,
|
||||||
|
"12.07.2024" => 0,
|
||||||
|
"13.07.2024" => 0,
|
||||||
|
"14.07.2024" => 0,
|
||||||
|
"15.07.2024" => 292,
|
||||||
|
"16.07.2024" => 292,
|
||||||
|
"17.07.2024" => 154,
|
||||||
|
"18.07.2024" => 892,
|
||||||
|
"19.07.2024" => 606,
|
||||||
|
"20.07.2024" => 0010,
|
||||||
|
"21.07.2024" => 0
|
||||||
|
];
|
||||||
|
|
||||||
|
$barWidth = 20;
|
||||||
|
$barSpacing = 10;
|
||||||
|
$maxBarHeight = $imageHeight - 110;
|
||||||
|
$maxValue = max($data);
|
||||||
|
|
||||||
|
$x = 50;
|
||||||
|
foreach ($data as $date => $value) {
|
||||||
|
$barHeight = ($value / $maxValue) * $maxBarHeight;
|
||||||
|
$y = $imageHeight - 70 - $barHeight;
|
||||||
|
imagefilledrectangle($image, $x, $y, $x + $barWidth, $imageHeight - 70, $barColor);
|
||||||
|
imagettftext($image, 13, 0, $x + 2, $y - 10, $textColor, $_SERVER['DOCUMENT_ROOT'].'/static/TTCommons-Medium.ttf', $value);
|
||||||
|
imagettftext($image, 10, 90, $x + 15, $imageHeight - 0, $textColor, $_SERVER['DOCUMENT_ROOT'].'/static/TTCommons-Medium.ttf', $date); // Rotated date
|
||||||
|
$x += $barWidth + $barSpacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
imageline($image, 50, $imageHeight - 70, $imageWidth - 50, $imageHeight - 70, $axisColor);
|
||||||
|
imageline($image, 50, 50, 50, $imageHeight - 70, $axisColor);
|
||||||
|
|
||||||
|
header('Content-Type: image/png');
|
||||||
|
imagepng($image);
|
||||||
|
imagedestroy($image);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
|
@ -10,6 +10,7 @@ use \App\Controllers\Api\Images\{Upload};
|
||||||
use \App\Controllers\Api\Images\Rate as PhotoVote;
|
use \App\Controllers\Api\Images\Rate as PhotoVote;
|
||||||
use \App\Controllers\Api\Images\Compress as PhotoCompress;
|
use \App\Controllers\Api\Images\Compress as PhotoCompress;
|
||||||
use \App\Controllers\Api\Images\CheckAll as PhotoCheckAll;
|
use \App\Controllers\Api\Images\CheckAll as PhotoCheckAll;
|
||||||
|
use \App\Controllers\Api\Images\Stats as PhotoStats;
|
||||||
use \App\Controllers\Api\Images\Comments\Create as PhotoComment;
|
use \App\Controllers\Api\Images\Comments\Create as PhotoComment;
|
||||||
use \App\Controllers\Api\Images\Comments\Load as PhotoCommentLoad;
|
use \App\Controllers\Api\Images\Comments\Load as PhotoCommentLoad;
|
||||||
use \App\Controllers\Api\Images\Comments\Rate as PhotoCommentVote;
|
use \App\Controllers\Api\Images\Comments\Rate as PhotoCommentVote;
|
||||||
|
@ -55,6 +56,9 @@ class ApiController
|
||||||
public static function checkallphotos() {
|
public static function checkallphotos() {
|
||||||
return new PhotoCheckAll();
|
return new PhotoCheckAll();
|
||||||
}
|
}
|
||||||
|
public static function photostats() {
|
||||||
|
return new PhotoStats();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -62,6 +62,7 @@ class MainController
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static function logout()
|
public static function logout()
|
||||||
{
|
{
|
||||||
DB::query('DELETE FROM login_tokens WHERE token=:userid', array(':userid'=>$_COOKIE['NGALLERYSESS']));
|
DB::query('DELETE FROM login_tokens WHERE token=:userid', array(':userid'=>$_COOKIE['NGALLERYSESS']));
|
||||||
|
|
|
@ -13,6 +13,11 @@ class PhotoController
|
||||||
{
|
{
|
||||||
Page::set('Photo');
|
Page::set('Photo');
|
||||||
}
|
}
|
||||||
|
public static function photoext()
|
||||||
|
{
|
||||||
|
Page::set('PhotoExt');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -18,6 +18,7 @@ class Routes
|
||||||
Router::get('/author/$id', 'ProfileController@i');
|
Router::get('/author/$id', 'ProfileController@i');
|
||||||
Router::post('/api/login', 'ApiController@login');
|
Router::post('/api/login', 'ApiController@login');
|
||||||
Router::post('/api/register', 'ApiController@register');
|
Router::post('/api/register', 'ApiController@register');
|
||||||
|
Router::get('/api/photo/stats', 'ApiController@photostats');
|
||||||
Router::get('/about', 'MainController@about');
|
Router::get('/about', 'MainController@about');
|
||||||
Router::get('/rules', 'MainController@rules');
|
Router::get('/rules', 'MainController@rules');
|
||||||
Router::get('/rules/pub', 'MainController@publicationRules');
|
Router::get('/rules/pub', 'MainController@publicationRules');
|
||||||
|
@ -25,6 +26,7 @@ class Routes
|
||||||
Router::get('/rules/video', 'MainController@videoRules');
|
Router::get('/rules/video', 'MainController@videoRules');
|
||||||
Router::get('/update', 'MainController@update');
|
Router::get('/update', 'MainController@update');
|
||||||
Router::get('/top30', 'MainController@top30');
|
Router::get('/top30', 'MainController@top30');
|
||||||
|
Router::get('/photoext', 'PhotoController@photoext');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
BIN
static/TTCommons-Medium.ttf
Normal file
BIN
static/TTCommons-Medium.ttf
Normal file
Binary file not shown.
|
@ -183,6 +183,9 @@ if ($photo->i('id') !== null) {
|
||||||
<div class="sm">
|
<div class="sm">
|
||||||
<div style="margin-bottom:10px">Лицензия: <b>BY-NC</b></div>
|
<div style="margin-bottom:10px">Лицензия: <b>BY-NC</b></div>
|
||||||
Опубликовано <b><?= Date::zmdate($photo->i('timeupload')) ?></b><br>
|
Опубликовано <b><?= Date::zmdate($photo->i('timeupload')) ?></b><br>
|
||||||
|
Просмотров — <?=DB::query('SELECT COUNT(*) FROM photos_views WHERE photo_id=:id', array(':id'=>$id))[0]['COUNT(*)']?>
|
||||||
|
<br><br>
|
||||||
|
<a href="/photoext?id=<?=$id?>">Подробная информация</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
130
views/pages/PhotoExt.php
Normal file
130
views/pages/PhotoExt.php
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
<?php
|
||||||
|
use \App\Services\DB;
|
||||||
|
$photo = new \App\Models\Photo($_GET['id']);
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="ru">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<?php include($_SERVER['DOCUMENT_ROOT'] . '/views/components/LoadHead.php'); ?>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="backgr"></div>
|
||||||
|
<table class="tmain">
|
||||||
|
<?php include($_SERVER['DOCUMENT_ROOT'] . '/views/components/Navbar.php'); ?>
|
||||||
|
<tr>
|
||||||
|
<td class="main">
|
||||||
|
<center>
|
||||||
|
<h1>Информация об изображении</h1>
|
||||||
|
<div style="display:inline-block"><a href="/photo/<?=$_GET['id']?>/"><img src="/api/photo/compress?url=<?= $photo->i('photourl') ?>" width="250" alt="347 КБ" class="f"></a></div>
|
||||||
|
<br /><br />
|
||||||
|
|
||||||
|
<table class="p20">
|
||||||
|
<tr class="s1 h21">
|
||||||
|
<td class="ds">Идентификатор изображения:</td>
|
||||||
|
<td class="ds"><b><?=$photo->i('id')?></b></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr class="s1 h21">
|
||||||
|
<td class="ds">Автор:</td>
|
||||||
|
<td class="ds"><b><?=(new \App\Models\User($photo->i('user_id')))->i('username')?></b></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="s11 h21">
|
||||||
|
<td class="ds">Опубликовано:</td>
|
||||||
|
<td class="ds"><b><?=gmdate("d.m.Y H:i:s", $photo->i('timeupload'));?></b></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="s1 h21">
|
||||||
|
<td class="ds">Находится на сайте, дней:</td>
|
||||||
|
<td class="ds"><b><?=floor((time() - $photo->i('timeupload')) / 8600)?></b></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="s11 h21">
|
||||||
|
<td class="ds">Уникальных просмотров:</td>
|
||||||
|
<td class="ds"><b><?=DB::query('SELECT COUNT(*) FROM photos_views WHERE photo_id=:id', array(':id'=>$_GET['id']))[0]['COUNT(*)']?></b></td>
|
||||||
|
</tr>
|
||||||
|
<tr class="s1 h21">
|
||||||
|
<td class="ds">Комментариев:</td>
|
||||||
|
<td class="ds"><b><?=DB::query('SELECT COUNT(*) FROM photos_comments WHERE photo_id=:id', array(':id'=>$_GET['id']))[0]['COUNT(*)']?></b></td>
|
||||||
|
</tr>
|
||||||
|
</table><br />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h4>Динамика просмотров по датам</h4>
|
||||||
|
|
||||||
|
<div class="p20w" style="padding:5px">
|
||||||
|
<img width="500" src="/api/photo/stats?id=<?=$_GET['id']?>">
|
||||||
|
</div><br />
|
||||||
|
|
||||||
|
</center>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td id="adframe">
|
||||||
|
<!-- Yandex.RTB R-A-115118-1 -->
|
||||||
|
<div id="yandex_rtb_R-A-115118-1"></div>
|
||||||
|
<script>
|
||||||
|
window.yaContextCb.push(() => {
|
||||||
|
Ya.Context.AdvManager.render({
|
||||||
|
renderTo: 'yandex_rtb_R-A-115118-1',
|
||||||
|
blockId: 'R-A-115118-1'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="footer"><b><a href="/">Главная</a> <a href="/lk/">Личный кабинет</a> <a href="https://forum.transphoto.org">Форум</a> <a href="/rules/">Правила</a> <a href="/admin/">Редколлегия</a></b><br>
|
||||||
|
<a href="/set.php?dark=0" style="display:inline-block; padding:1px 10px; margin-top:5px; background-color:#ddd; color:#333">Светлая тема</a>
|
||||||
|
<div class="sitecopy">© Администрация ТрансФото и авторы материалов, 2002—2024<br>Использование фотографий и иных материалов, опубликованных на сайте, допускается только с разрешения их авторов.</div>
|
||||||
|
<div style="margin:15px 0">
|
||||||
|
<noindex>
|
||||||
|
|
||||||
|
<!-- Yandex.Metrika informer -->
|
||||||
|
<a href="https://metrika.yandex.ru/stat/?id=73971775&from=informer" target="_blank" rel="nofollow"><img src="https://informer.yandex.ru/informer/73971775/3_0_DDDDDDFF_DDDDDDFF_0_pageviews" style="width:88px; height:31px; border:0;" alt="Яндекс.Метрика" title="Яндекс.Метрика: данные за сегодня (просмотры, визиты и уникальные посетители)" class="ym-advanced-informer" data-cid="73971775" data-lang="ru" /></a>
|
||||||
|
<!-- /Yandex.Metrika informer -->
|
||||||
|
|
||||||
|
</noindex>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
function c() {
|
||||||
|
var b = a.contentDocument || a.contentWindow.document;
|
||||||
|
if (b) {
|
||||||
|
var d = b.createElement('script');
|
||||||
|
d.innerHTML = "window.__CF$cv$params={r:'8a660706db3f005f',t:'MTcyMTUxMDc2NC4wMDAwMDA='};var a=document.createElement('script');a.nonce='';a.src='/cdn-cgi/challenge-platform/scripts/jsd/main.js';document.getElementsByTagName('head')[0].appendChild(a);";
|
||||||
|
b.getElementsByTagName('head')[0].appendChild(d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (document.body) {
|
||||||
|
var a = document.createElement('iframe');
|
||||||
|
a.height = 1;
|
||||||
|
a.width = 1;
|
||||||
|
a.style.position = 'absolute';
|
||||||
|
a.style.top = 0;
|
||||||
|
a.style.left = 0;
|
||||||
|
a.style.border = 'none';
|
||||||
|
a.style.visibility = 'hidden';
|
||||||
|
document.body.appendChild(a);
|
||||||
|
if ('loading' !== document.readyState) c();
|
||||||
|
else if (window.addEventListener) document.addEventListener('DOMContentLoaded', c);
|
||||||
|
else {
|
||||||
|
var e = document.onreadystatechange || function() {};
|
||||||
|
document.onreadystatechange = function(b) {
|
||||||
|
e(b);
|
||||||
|
'loading' !== document.readyState && (document.onreadystatechange = e, c())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
|
@ -595,19 +595,7 @@ $user = new User(Auth::userid());
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td class="lcol">Место съёмки:</td>
|
|
||||||
<td style="padding-right:15px">
|
|
||||||
<table width="100%">
|
|
||||||
<tr>
|
|
||||||
<td style="padding:0; vertical-align:middle">
|
|
||||||
<input type="text" name="place" id="place" maxlength="255" style="width:506px" onfocus="showHint('place')" onblur="hideHint('place')" value="">
|
|
||||||
</td>
|
|
||||||
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,53 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="ru">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>Таймер до 12 июля</title>
|
|
||||||
<style>
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Pepperscreen';
|
|
||||||
src: url('/static/PEPPERSCREEN.ttf') format('truetype');
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
height: 100vh;
|
|
||||||
margin: 0;
|
|
||||||
background-color: #f0f0f0;
|
|
||||||
font-family: 'Pepperscreen', sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
#timer {
|
|
||||||
font-size: 100px;
|
|
||||||
color: #000000;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<center><h1 style="color: #f40300; font-size: 65px;">сайт будет захвачен через</h1></center><br>
|
|
||||||
<center><div id="timer">Загрузка...</div></center><br>
|
|
||||||
<center><img width="750" src="/static/img/sttslogo.png"></center>
|
|
||||||
<script>
|
|
||||||
function updateTimer() {
|
|
||||||
const now = new Date();
|
|
||||||
const targetDate = new Date(now.getFullYear(), 6, 12, 12, 0, 0); // 12 июля 12:00 по локальному времени
|
|
||||||
if (now > targetDate) {
|
|
||||||
targetDate.setFullYear(now.getFullYear() + 1); // если уже прошло, тогда следующее 12 июля
|
|
||||||
}
|
|
||||||
const remainingTime = targetDate - now;
|
|
||||||
|
|
||||||
const days = Math.floor(remainingTime / (1000 * 60 * 60 * 24));
|
|
||||||
const hours = Math.floor((remainingTime % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
|
|
||||||
const minutes = Math.floor((remainingTime % (1000 * 60 * 60)) / (1000 * 60));
|
|
||||||
const seconds = Math.floor((remainingTime % (1000 * 60)) / 1000);
|
|
||||||
|
|
||||||
document.getElementById('timer').textContent = `${days}:${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
setInterval(updateTimer, 1000);
|
|
||||||
updateTimer(); // Начальное обновление
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
Loading…
Reference in a new issue