From 38dacd9235e3ba9536e35d369fc7222a1cfa9672 Mon Sep 17 00:00:00 2001
From: themohooks <81331307+themohooks@users.noreply.github.com>
Date: Fri, 5 Jul 2024 11:13:28 +0300
Subject: [PATCH] Add Photos Rating
---
app/Controllers/Api/Images/Rate.php | 62 +++++++
app/Controllers/ApiController.php | 5 +
app/Core/Routes.php | 1 +
app/Models/Vote.php | 44 +++++
static/js/photo.js | 261 ++++++++++++++++++++++++++++
views/components/LoadHead.php | 1 +
views/pages/Photo.php | 227 ++++--------------------
7 files changed, 406 insertions(+), 195 deletions(-)
create mode 100644 app/Controllers/Api/Images/Rate.php
create mode 100644 app/Models/Vote.php
create mode 100644 static/js/photo.js
diff --git a/app/Controllers/Api/Images/Rate.php b/app/Controllers/Api/Images/Rate.php
new file mode 100644
index 0000000..cce28c5
--- /dev/null
+++ b/app/Controllers/Api/Images/Rate.php
@@ -0,0 +1,62 @@
+Auth::userid(), ':pid' => $_GET['pid'], ':type'=>$_GET['vote']));
+ if (Vote::photo(Auth::userid(), $_GET['pid']) != $_GET['vote']) {
+ DB::query('DELETE FROM photos_rates WHERE user_id=:id AND photo_id=:pid AND type=:type', array(':id'=>Auth::userid(), ':pid' => $_GET['pid'], ':type'=>Vote::photo(Auth::userid(), $_GET['pid'])));
+ }
+ } else if (Vote::photo(Auth::userid(), $_GET['pid']) === (int)$_GET['vote']) {
+ DB::query('DELETE FROM photos_rates WHERE user_id=:id AND photo_id=:pid', array(':id'=>Auth::userid(), ':pid' => $_GET['pid']));
+ } else {
+ DB::query('UPDATE photos_rates SET type=:type WHERE user_id=:id AND photo_id=:pid', array(':id'=>Auth::userid(), ':pid' => $_GET['pid'], ':type'=>$_GET['vote']));
+
+ }
+ $votes = DB::query('SELECT * FROM photos_rates WHERE photo_id=:id ORDER BY id DESC', array(':id' => $_GET['pid']));
+
+ $formattedVotesPos = [];
+ $formattedVotesNeg = [];
+ foreach ($votes as $vote) {
+ $user = new User($vote['user_id']);
+ if ($vote['type'] === 0) {
+ $type = -1;
+ $formattedVotesNeg[] = [$vote['user_id'], $user->i('username'), $type];
+ } else {
+ $type = 1;
+ $formattedVotesPos[] = [$vote['user_id'], $user->i('username'), $type];
+ }
+
+ }
+
+ if (Vote::photo(Auth::userid(), $_GET['pid']) === 0) {
+ $negbtn = true;
+ $posbtn = false;
+ } else {
+ $negbtn = false;
+ $posbtn = true;
+ }
+ $result = [
+ 'votes' => [$formattedVotesNeg, $formattedVotesPos],
+ 'buttons' => [$negbtn, $posbtn],
+ 'errors' => '',
+ 'rating' => Vote::count($_GET['pid'])
+ ];
+
+ header('Content-Type: application/json');
+ echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
+ }
+ }
+}
diff --git a/app/Controllers/ApiController.php b/app/Controllers/ApiController.php
index cf0c9cd..0545a00 100644
--- a/app/Controllers/ApiController.php
+++ b/app/Controllers/ApiController.php
@@ -6,6 +6,7 @@ use \App\Controllers\ExceptionRegister;
use \App\Core\Page;
use \App\Controllers\Api\{Login, Register};
use \App\Controllers\Api\Images\{Upload};
+use \App\Controllers\Api\Images\Rate as PhotoVote;
class ApiController
{
@@ -19,5 +20,9 @@ class ApiController
public static function upload() {
return new Upload();
}
+ public static function photovote() {
+ return new PhotoVote();
+ }
+
}
\ No newline at end of file
diff --git a/app/Core/Routes.php b/app/Core/Routes.php
index c67f955..d4c94ab 100644
--- a/app/Core/Routes.php
+++ b/app/Core/Routes.php
@@ -18,6 +18,7 @@ class Routes
Router::get('/photo/$id', 'PhotoController@i');
Router::get('/author/$id', 'ProfileController@i');
Router::post('/api/login', 'ApiController@login');
+ Router::get('/api/photo/vote', 'ApiController@photovote');
Router::post('/api/register', 'ApiController@register');
diff --git a/app/Models/Vote.php b/app/Models/Vote.php
new file mode 100644
index 0000000..e2a14dc
--- /dev/null
+++ b/app/Models/Vote.php
@@ -0,0 +1,44 @@
+ $user_id, ':pid' => $pid));
+ if (!empty($result)) {
+ $type = $result[0]['type'];
+
+ if ($type < 0) {
+ $type = -1;
+ }
+
+ return $type;
+ } else {
+ return -1;
+ }
+
+
+ }
+
+ public static function count( $pid) {
+ $result = DB::query('SELECT * FROM photos_rates WHERE photo_id=:pid', array(':pid' => $pid));
+ $votes = 0;
+ foreach ($result as $r) {
+ if ($r['type'] === 1) {
+ $votes++;
+ } else {
+ $votes--;
+ }
+ }
+ return $votes;
+ }
+
+ public static function token()
+ {
+ return $_COOKIE['NGALLERYSESS'];
+ }
+}
+?>
diff --git a/static/js/photo.js b/static/js/photo.js
new file mode 100644
index 0000000..e524280
--- /dev/null
+++ b/static/js/photo.js
@@ -0,0 +1,261 @@
+$(document).ready(function()
+{
+ // Убираем лишние параметры
+ var url = document.location.toString();
+ url = url.replace(/\?vid=\d+$/, '');
+ url = url.replace(/\?gid=\d+$/, '');
+ url = url.replace(/\?aid=\d+$/, '');
+ url = url.replace(/\?upd=\d+$/, '');
+ url = url.replace(/\?top=\d+$/, '');
+ history.replaceState({}, '', url);
+
+
+ // Переход к следующему фото
+ $('#prev, #next').click(function()
+ {
+ var next = (this.id == 'prev' ? 0 : 1);
+
+ $.get('/api.php', { action: 'move', pid: pid, vid: vid, gid: gid, aid: aid, next: next }, function(pid)
+ {
+ if (pid == 0)
+ {
+ if (!vid && !gid)
+ {
+ if (next)
+ alert(_text['P_MOVE_FIRST'] + '.');
+ else alert(_text['P_MOVE_LAST'] + '.');
+ }
+ else alert(_text[vid ? 'P_MOVE_ALONE_V' : 'P_MOVE_ALONE_G'] + '.');
+ }
+ else window.location = '/photo/' + pid + '/' + (vid ? '?vid=' + vid : (gid ? '?gid=' + gid : (aid ? '?aid=' + aid : (upd ? '?upd=1' : ''))));
+ });
+ });
+
+
+ // Показ карты
+ $('#showmap a').click(function()
+ {
+ $('#map').show();
+ $('#showmap').hide();
+
+ initMap(lat, lng, {
+ showNearMarkers: true,
+ showCenterMarker: true,
+ draggable: false,
+ dir: dir
+ });
+
+ return false;
+ });
+
+
+ // Голосование за фото
+ $('.vote_btn').click(function()
+ {
+ var vote = $(this).attr('vote');
+ if (vote != 0 && vote != 1) return false;
+ if (vote && subscr_pro) $('.toggle').attr('class', 'toggle on');
+
+ var pid = $(this).closest('.vote').attr('pid');
+
+ var savedClass1 = $('.vote_btn[vote="1"]').attr('class');
+ var savedClass0 = $('.vote_btn[vote="0"]').attr('class');
+
+ $(this).toggleClass('voted');
+ if ($(this).is('.voted')) $('.vote_btn[vote="' + Number(!Number(vote)) + '"]').removeClass('voted');
+
+ $('.loader[pid="' + pid + '"]').css('visibility', 'visible');
+
+ $.getJSON('/api/photo/vote', { action: 'vote-photo', pid: pid, vote: vote }, function(data)
+ {
+ if (data && !data.errors)
+ {
+ var signs, html = '', i, j;
+
+ for (i = 1; i >= 0; i--)
+ {
+ if (data.votes[i] && data.votes[i].length != 0)
+ {
+ console.log(i);
+ html += '
';
+
+ for (j = 0; j < data.votes[i].length; j++)
+ html += '' + data.votes[i][j][1] + ' | ' + (data.votes[i][j][2] > 0 ? '+' : '–') + '1 |
';
+
+ html += '
';
+ }
+ }
+
+ $('#votes').html(html)[html == '' ? 'hide' : 'show']();
+
+ $('.vote_btn[vote="1"]')[data.buttons[1] ? 'addClass' : 'removeClass']('voted');
+ $('.vote_btn[vote="0"]')[data.buttons[0] ? 'addClass' : 'removeClass']('voted');
+
+ var rating = parseInt(data.rating);
+ if (rating > 0) $('#rating').html('+' + rating); else
+ if (rating < 0) $('#rating').html('–' + parseInt(-rating));
+ else $('#rating').html('0');
+ }
+ else
+ {
+ $('.vote_btn[vote="1"]').attr('class', savedClass1);
+ $('.vote_btn[vote="0"]').attr('class', savedClass0);
+
+ if (data.errors) alert(data.errors);
+ }
+
+ $('.loader[pid="' + pid + '"]').css('visibility', 'hidden');
+ })
+ .fail(function(jx) { if (jx.responseText != '') alert(jx.responseText); });
+
+ return false;
+ });
+
+
+ // Конкурсное голосование
+ $('.konk_btn').click(function()
+ {
+ var vote = $(this).attr('vote');
+ if (vote != 0 && vote != 1 || $(this).is('.locked')) return false;
+
+ var pid = $(this).closest('.vote').attr('pid');
+
+ var savedClass1 = $('.vote[pid="' + pid + '"] .konk_btn[vote="1"]').attr('class');
+ var savedClass0 = $('.vote[pid="' + pid + '"] .konk_btn[vote="0"]').attr('class');
+
+ $('.loader[pid="' + pid + '"]').css('visibility', 'visible');
+
+ $(this).toggleClass('voted');
+ if ($(this).is('.voted')) $('.vote[pid="' + pid + '"] .konk_btn[vote="' + Number(!Number(vote)) + '"]').removeClass('voted');
+
+ if (!self_p) // Чужие фото
+ {
+ $(this).closest('.p20p').removeAttr('class').css('padding', '6px 6px 5px');
+
+ $.getJSON('/api.php', { action: 'vote-konk', pid: pid, vote: vote }, function (data)
+ {
+ if (data && !data.errors)
+ {
+ $('.star[pid="' + pid + '"]').html(data.star ? '' : '');
+
+ $('.vote[pid="' + pid + '"] .konk_btn[vote="1"]')[data.buttons[1] ? 'addClass' : 'removeClass']('voted');
+ $('.vote[pid="' + pid + '"] .konk_btn[vote="0"]')[data.buttons[0] ? 'addClass' : 'removeClass']('voted');
+
+ var rat = $('.s_rating[pid="' + pid + '"]');
+ if (rat.length)
+ {
+ var rating = parseInt(data.rating);
+ if (rating > 0) rat.html('+' + rating); else
+ if (rating < 0) rat.html('–' + parseInt(-rating));
+ else rat.html('0');
+ }
+ }
+ else
+ {
+ $('.vote[pid="' + pid + '"] .konk_btn[vote="1"]').attr('class', savedClass1);
+ $('.vote[pid="' + pid + '"] .konk_btn[vote="0"]').attr('class', savedClass0);
+
+ if (data.errors) alert(data.errors);
+ }
+
+ $('.loader[pid="' + pid + '"]').css('visibility', 'hidden');
+ })
+ .fail(function(jx) { if (jx.responseText != '') alert(jx.responseText); });
+ }
+ else // Свои фото
+ {
+ $.getJSON('/api.php', { action: 'vote-author', pid: pid, vote: vote }, function (data)
+ {
+ if (data && !data.errors)
+ {
+ $('#star[pid="' + pid + '"]').html(data.star ? '' : '');
+
+ $('.konk_btn[vote="1"]')[data.buttons[1] ? 'addClass' : 'removeClass']('voted');
+ $('.konk_btn[vote="0"]')[data.buttons[0] ? 'addClass' : 'removeClass']('voted');
+ }
+ else
+ {
+ $('.konk_btn[vote="0"]').attr('class', savedClass0);
+ $('.konk_btn[vote="1"]').attr('class', savedClass1);
+
+ if (data.errors) alert(data.errors);
+ }
+
+ $('.loader[pid="' + pid + '"]').css('visibility', 'hidden');
+ })
+ .fail(function(jx) { if (jx.responseText != '') alert(jx.responseText); });
+ }
+
+ return false;
+ });
+
+
+ // Быстрый переход по фото
+ $(document).keydown(function(e)
+ {
+ if ($(e.target).is('input, textarea')) return;
+
+ if (e.ctrlKey)
+ {
+ switch (e.which)
+ {
+ case 0x25: window.location = '/ph.php?pid=' + pid + '&pub=0'; break;
+ case 0x27: window.location = '/ph.php?pid=' + pid + '&pub=1'; break;
+ }
+ }
+ });
+
+
+ // Избранное
+ $('#favLink').click(function()
+ {
+ var faved = parseInt($(this).attr('faved'));
+ $(this).html(_text[faved ? 'P_ADDFAV' : 'P_DELFAV']).attr('faved', faved ? 0 : 1);
+ if (!faved && subscr_fav) $('.toggle').attr('class', 'toggle on');
+
+ $.get('/api.php', { action: 'fav-photo', pid : pid }, function (r) { if (r != 0 && r != 1) alert(r); }).fail(function(jx) { if (jx.responseText != '') alert(jx.responseText); });
+ return false;
+ });
+
+
+ // Показ всего EXIF
+ var showexif = $('#showexif');
+ if (showexif.length > 0)
+ {
+ showexif.on('click', function()
+ {
+ $('#exif tr').show();
+ $('#exif tr:even').attr('class', 's11 h21');
+ $('#exif tr:odd').attr('class', 's1 h21');
+ $(this).closest('tr').hide();
+ return false;
+ });
+
+ if ($('#exif tr:visible').length == 1) showexif.click();
+ }
+
+
+ // Свёрнутые блоки в мобильной версии
+ $('.pp-item-header').on('click', function()
+ {
+ var header = $(this);
+ $('.chevron', header).toggleClass('active');
+ header.siblings('.pp-item-body').slideToggle('fast');
+ });
+
+
+ if ($('#pmain').is('.hidden')) $('.footer').addClass('hidden');
+
+
+ $('.top-disclaimer-close').on('click', function()
+ {
+ document.cookie = 'nodisclaim=1;max-age=' + (86400 * 35) + ';path=/';
+ $('.top-disclaimer').slideUp();
+ return false;
+ });
+});
+
+
+function showGrid() { $('#grid, #sh_gr, #hd_gr').toggle(); }
+
+function showReasons() { $('#reasons').toggle(); }
\ No newline at end of file
diff --git a/views/components/LoadHead.php b/views/components/LoadHead.php
index 0759126..95894bb 100644
--- a/views/components/LoadHead.php
+++ b/views/components/LoadHead.php
@@ -19,6 +19,7 @@
+
diff --git a/views/pages/Photo.php b/views/pages/Photo.php
index 66aa484..ec0e49d 100644
--- a/views/pages/Photo.php
+++ b/views/pages/Photo.php
@@ -1,8 +1,10 @@
i('user_id'));
?>
@@ -153,202 +155,37 @@ $photouser = new \App\Models\User($photo->i('user_id'));
-
Рейтинг: +48
+
Рейтинг: =Vote::count($id)?>
+
+
+ $id));
+ foreach ($votespos as $ps) {
+ $uservote = new User($ps['user_id']);
+ echo '
+ '.$uservote->i('username').' |
+ -1 |
+
';
+ }
+ ?>
+
@@ -378,13 +215,13 @@ $photouser = new \App\Models\User($photo->i('user_id'));
if ($key === 'FILE.FileDateTime') {
$value = Date::zmdate($value);
}
-
+
echo '
' . htmlspecialchars($key) . ': |
' . htmlspecialchars($value) . ' |
';
- }
+ }
?>