mirror of
https://github.com/claradex/nativegallery.git
synced 2025-04-23 16:43:04 +03:00
Compare commits
7 commits
2918dd347b
...
be85a9531a
Author | SHA1 | Date | |
---|---|---|---|
|
be85a9531a | ||
|
13f06db887 | ||
|
22e0fe0cec | ||
|
b0c8b51fe6 | ||
|
020ec19124 | ||
|
2e5c8ffbb0 | ||
|
8087b7c720 |
28 changed files with 4151 additions and 114 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -13,3 +13,4 @@ views/pages/t.php
|
|||
rules.txt
|
||||
rules.txt
|
||||
/uploads/*
|
||||
t.php
|
31
app/Controllers/Api/Admin/Contests/Create.php
Normal file
31
app/Controllers/Api/Admin/Contests/Create.php
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace App\Controllers\Api\Admin\Contests;
|
||||
|
||||
|
||||
|
||||
use App\Services\{Auth, Router, GenerateRandomStr, DB, Json, EXIF};
|
||||
use App\Models\{User, Vote, Photo};
|
||||
|
||||
|
||||
class Create
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$openprdate = strtotime($_POST['openpretendsdate']);
|
||||
$closeprdate = strtotime($_POST['closepretendsdate']);
|
||||
$opendate = strtotime($_POST['opendate']);
|
||||
$closedate = strtotime($_POST['closedate']);
|
||||
|
||||
if ($_POST['startContestNow'] === "1") {
|
||||
$opendate = $closeprdate;
|
||||
}
|
||||
DB::query('INSERT INTO contests VALUES (\'0\', :themeid, :openprdate, :closeprdate, :opendate, :closedate, 0)', array(':themeid' => $_POST['themeid'], ':openprdate' => $openprdate, ':closeprdate'=>$closeprdate, ':opendate' => $opendate, ':closedate'=>$closedate));
|
||||
echo json_encode(
|
||||
array(
|
||||
'errorcode' => 0,
|
||||
'error' => 0
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
28
app/Controllers/Api/Admin/Contests/CreateTheme.php
Normal file
28
app/Controllers/Api/Admin/Contests/CreateTheme.php
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Controllers\Api\Admin\Contests;
|
||||
|
||||
|
||||
|
||||
use App\Services\{Auth, Router, GenerateRandomStr, DB, Json, EXIF};
|
||||
use App\Models\{User, Vote, Photo};
|
||||
|
||||
|
||||
class CreateTheme
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
if ($_POST['active'] === "1") {
|
||||
$status = 1;
|
||||
} else {
|
||||
$status = 0;
|
||||
}
|
||||
DB::query('INSERT INTO contests_themes VALUES (\'0\', :title, :status)', array(':title' => $_POST['body'], ':status' => $status));
|
||||
echo json_encode(
|
||||
array(
|
||||
'errorcode' => 0,
|
||||
'error' => 0
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -2,69 +2,96 @@
|
|||
|
||||
namespace App\Controllers\Api\Images;
|
||||
|
||||
|
||||
|
||||
use App\Services\{Auth, Router, GenerateRandomStr, DB, Json, EXIF};
|
||||
use App\Models\{User, Vote};
|
||||
|
||||
|
||||
class Rate
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
if (isset($_GET['vote']) && isset($_GET['pid'])) {
|
||||
if (Vote::photo(Auth::userid(), $_GET['pid']) === -1) {
|
||||
DB::query('INSERT INTO photos_rates VALUES (\'0\', :id, :pid, :type, 0)', array(':id'=>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'])));
|
||||
$userId = Auth::userid();
|
||||
$photoId = $_GET['pid'];
|
||||
$voteType = (int) $_GET['vote'];
|
||||
$contest = (isset($_GET['action']) && $_GET['action'] === 'vote-konk') ? 1 : 0;
|
||||
|
||||
if ($contest === 1) {
|
||||
if (Vote::photoContest($userId, $photoId) === -1) {
|
||||
DB::query(
|
||||
'INSERT INTO photos_rates (id, user_id, photo_id, type, contest) VALUES (NULL, :id, :pid, :type, 1)',
|
||||
[':id' => $userId, ':pid' => $photoId, ':type' => $voteType]
|
||||
);
|
||||
if (Vote::photoContest($userId, $photoId) != $voteType) {
|
||||
DB::query(
|
||||
'DELETE FROM photos_rates WHERE user_id=:id AND photo_id=:pid AND type=:type AND contest=1',
|
||||
[':id' => $userId, ':pid' => $photoId, ':type' => Vote::photo($userId, $photoId)]
|
||||
);
|
||||
}
|
||||
} elseif (Vote::photoContest($userId, $photoId) === $voteType) {
|
||||
DB::query(
|
||||
'DELETE FROM photos_rates WHERE user_id=:id AND photo_id=:pid AND contest=1',
|
||||
[':id' => $userId, ':pid' => $photoId]
|
||||
);
|
||||
} else {
|
||||
DB::query(
|
||||
'UPDATE photos_rates SET type=:type WHERE user_id=:id AND photo_id=:pid AND contest=1',
|
||||
[':id' => $userId, ':pid' => $photoId, ':type' => $voteType]
|
||||
);
|
||||
}
|
||||
} 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']));
|
||||
|
||||
if (Vote::photo($userId, $photoId) === -1) {
|
||||
DB::query(
|
||||
'INSERT INTO photos_rates (id, user_id, photo_id, type, contest) VALUES (NULL, :id, :pid, :type, 0)',
|
||||
[':id' => $userId, ':pid' => $photoId, ':type' => $voteType]
|
||||
);
|
||||
if (Vote::photo($userId, $photoId) != $voteType) {
|
||||
DB::query(
|
||||
'DELETE FROM photos_rates WHERE user_id=:id AND photo_id=:pid AND type=:type AND contest=0',
|
||||
[':id' => $userId, ':pid' => $photoId, ':type' => Vote::photo($userId, $photoId)]
|
||||
);
|
||||
}
|
||||
} elseif (Vote::photo($userId, $photoId) === $voteType) {
|
||||
DB::query(
|
||||
'DELETE FROM photos_rates WHERE user_id=:id AND photo_id=:pid AND contest=0',
|
||||
[':id' => $userId, ':pid' => $photoId]
|
||||
);
|
||||
} else {
|
||||
DB::query(
|
||||
'UPDATE photos_rates SET type=:type WHERE user_id=:id AND photo_id=:pid AND contest=0',
|
||||
[':id' => $userId, ':pid' => $photoId, ':type' => $voteType]
|
||||
);
|
||||
}
|
||||
}
|
||||
$votes = DB::query('SELECT * FROM photos_rates WHERE photo_id=:id ORDER BY id DESC', array(':id' => $_GET['pid']));
|
||||
|
||||
$votes = DB::query('SELECT * FROM photos_rates WHERE photo_id=:id ORDER BY id DESC', [':id' => $photoId]);
|
||||
$formattedVotesPos = [];
|
||||
$formattedVotesNeg = [];
|
||||
|
||||
foreach ($votes as $vote) {
|
||||
$user = new User($vote['user_id']);
|
||||
if ($vote['type'] === 0) {
|
||||
$type = 0;
|
||||
$formattedVotesNeg[] = [$vote['user_id'], $user->i('username'), $type];
|
||||
} else if ($vote['type'] === 1) {
|
||||
$type = 1;
|
||||
$formattedVotesPos[] = [$vote['user_id'], $user->i('username'), $type];
|
||||
$formattedVotesNeg[] = [$vote['user_id'], $user->i('username'), 0];
|
||||
} elseif ($vote['type'] === 1) {
|
||||
$formattedVotesPos[] = [$vote['user_id'], $user->i('username'), 1];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (Vote::photo(Auth::userid(), $_GET['pid']) === 0) {
|
||||
$negbtn = true;
|
||||
$posbtn = false;
|
||||
} else if (Vote::photo(Auth::userid(), $_GET['pid']) === 1) {
|
||||
$negbtn = false;
|
||||
$posbtn = true;
|
||||
} else {
|
||||
$negbtn = false;
|
||||
$posbtn = false;
|
||||
}
|
||||
$currentVote = Vote::photo($userId, $photoId);
|
||||
$contCurrentVote = Vote::photoContest($userId, $photoId);
|
||||
$result = [
|
||||
'buttons' => [$negbtn, $posbtn],
|
||||
'buttons' => [
|
||||
'negbtn' => $currentVote === 0,
|
||||
'posbtn' => $currentVote === 1,
|
||||
'negbtn_contest' => $contCurrentVote === 0,
|
||||
'posbtn_contest' => $contCurrentVote === 1,
|
||||
],
|
||||
'errors' => '',
|
||||
'rating' => Vote::count($_GET['pid'])
|
||||
'rating' => Vote::count($photoId),
|
||||
'votes' => [
|
||||
1 => $formattedVotesPos,
|
||||
0 => $formattedVotesNeg
|
||||
]
|
||||
];
|
||||
$votes = [];
|
||||
$votes[1] = $formattedVotesPos;
|
||||
$votes[0] = $formattedVotesNeg;
|
||||
|
||||
if (!empty($votes)) {
|
||||
$result['votes'] = $votes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||
|
|
|
@ -37,7 +37,7 @@ class Upload
|
|||
} else {
|
||||
$moderated = 1;
|
||||
}
|
||||
DB::query('INSERT INTO photos VALUES (\'0\', :userid, :postbody, :photourl, :time, :timeup, :exif, 0, :moderated, :place, 0, :gallery, :entityid, 0, :content)', array(':postbody' => $postbody, ':userid' => Auth::userid(), ':time' => mktime(0, 0, 0, $_POST['month'], $_POST['day'], $_POST['year']), ':content' => $content, ':photourl' => self::$photourl, ':exif' => $exif, ':place' => $_POST['place'], ':timeup' => time(), ':moderated' => $moderated, ':gallery'=>$_POST['gallery'], ':entityid'=>self::$entitydata_id));
|
||||
DB::query('INSERT INTO photos VALUES (\'0\', :userid, :postbody, :photourl, :time, :timeup, :exif, 0, :moderated, :place, 0, :gallery, :entityid, 0, 0, :content)', array(':postbody' => $postbody, ':userid' => Auth::userid(), ':time' => mktime(0, 0, 0, $_POST['month'], $_POST['day'], $_POST['year']), ':content' => $content, ':photourl' => self::$photourl, ':exif' => $exif, ':place' => $_POST['place'], ':timeup' => time(), ':moderated' => $moderated, ':gallery'=>$_POST['gallery'], ':entityid'=>self::$entitydata_id));
|
||||
if (($moderated === 1) && (self::$subsnotify != 'disabled')) {
|
||||
$followers = DB::query('SELECT * FROM followers WHERE user_id=:uid', array(':uid' => Auth::userid()));
|
||||
foreach ($followers as $f) {
|
||||
|
|
|
@ -31,6 +31,8 @@ use \App\Controllers\Api\Admin\GetVehicleInputs as AdminGetVehicleInputs;
|
|||
use \App\Controllers\Api\Admin\GeoDB\Create as AdminGeoDBCreate;
|
||||
use \App\Controllers\Api\Admin\GeoDB\Load as AdminGeoDBLoad;
|
||||
use \App\Controllers\Api\Admin\GeoDB\Delete as AdminGeoDBDelete;
|
||||
use \App\Controllers\Api\Admin\Contests\CreateTheme as AdminContestsCreateTheme;
|
||||
use \App\Controllers\Api\Admin\Contests\Create as AdminContestsCreate;
|
||||
|
||||
class ApiController
|
||||
{
|
||||
|
@ -108,6 +110,12 @@ class ApiController
|
|||
public static function admingetvehicleinputs() {
|
||||
return new AdminGetVehicleInputs();
|
||||
}
|
||||
public static function admincontestscreatetheme() {
|
||||
return new AdminContestsCreateTheme();
|
||||
}
|
||||
public static function admincontestscreate() {
|
||||
return new AdminContestsCreate();
|
||||
}
|
||||
public static function admingeodbcreate() {
|
||||
return new AdminGeoDBCreate();
|
||||
}
|
||||
|
|
|
@ -17,5 +17,15 @@ class ContestsController
|
|||
Page::set('Contests/VotingIndex');
|
||||
|
||||
}
|
||||
public static function waiting()
|
||||
{
|
||||
Page::set('Contests/VotingWaiting');
|
||||
|
||||
}
|
||||
public static function sendpretend()
|
||||
{
|
||||
Page::set('Contests/VotingSendPretend');
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -38,6 +38,7 @@ class Routes
|
|||
Router::get('/article/$id', 'MainController@gallery');
|
||||
Router::get('/voting', 'ContestsController@index');
|
||||
Router::get('/voting/results', 'ContestsController@results');
|
||||
Router::get('/voting/waiting', 'ContestsController@waiting');
|
||||
Router::get('/comments', 'MainController@comments');
|
||||
if (Auth::userid() > 0) {
|
||||
$user = new \App\Models\User(Auth::userid());
|
||||
|
@ -52,6 +53,7 @@ class Routes
|
|||
Router::get('/search', 'SearchController@i');
|
||||
|
||||
Router::get('/fav', 'MainController@fav');
|
||||
Router::get('/voting/sendpretend', 'ContestsController@sendpretend');
|
||||
|
||||
Router::get('/vehicle/edit', 'VehicleController@iedit');
|
||||
Router::get('/vehicle/dbedit', 'VehicleController@dbedit');
|
||||
|
@ -77,6 +79,8 @@ class Routes
|
|||
Router::any('/api/admin/getvehicleinputs/$id', 'ApiController@admingetvehicleinputs');
|
||||
Router::any('/api/admin/geodb/create', 'ApiController@admingeodbcreate');
|
||||
Router::any('/api/admin/geodb/load', 'ApiController@admingeodbload');
|
||||
Router::any('/api/admin/contests/createtheme', 'ApiController@admincontestscreatetheme');
|
||||
Router::any('/api/admin/contests/create', 'ApiController@admincontestscreate');
|
||||
}
|
||||
Router::get('/logout', 'MainController@logout');
|
||||
Router::get('/404', 'ExceptionRegister@notfound');
|
||||
|
|
|
@ -7,7 +7,23 @@ class Vote
|
|||
{
|
||||
public static function photo($user_id, $pid)
|
||||
{
|
||||
$result = DB::query('SELECT type FROM photos_rates WHERE user_id=:uid AND photo_id=:pid', array(':uid' => $user_id, ':pid' => $pid));
|
||||
$result = DB::query('SELECT type FROM photos_rates WHERE user_id=:uid AND photo_id=:pid AND contest=0', array(':uid' => $user_id, ':pid' => $pid));
|
||||
if (!empty($result)) {
|
||||
$type = $result[0]['type'];
|
||||
if ($type < 0) {
|
||||
$type = -1;
|
||||
}
|
||||
return $type;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static function photoContest($user_id, $pid)
|
||||
{
|
||||
$result = DB::query('SELECT type FROM photos_rates WHERE user_id=:uid AND photo_id=:pid AND contest=1', array(':uid' => $user_id, ':pid' => $pid));
|
||||
if (!empty($result)) {
|
||||
$type = $result[0]['type'];
|
||||
if ($type < 0) {
|
||||
|
|
109
app/Services/TaskScheduler.php
Normal file
109
app/Services/TaskScheduler.php
Normal file
|
@ -0,0 +1,109 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
class TaskScheduler {
|
||||
private $taskName;
|
||||
private $command;
|
||||
private $interval;
|
||||
|
||||
public function __construct() {
|
||||
// Конструктор теперь не принимает аргументы
|
||||
}
|
||||
|
||||
private function isWindows() {
|
||||
return strtoupper(substr(PHP_OS, 0, 3)) === 'WIN';
|
||||
}
|
||||
|
||||
// Метод для добавления задачи с параметрами
|
||||
public function addTask($taskName, $command, $interval = "* * * * *") {
|
||||
$this->taskName = $taskName;
|
||||
$this->command = $command;
|
||||
$this->interval = $interval;
|
||||
|
||||
return $this->isWindows() ? $this->addWindowsTask() : $this->addLinuxTask();
|
||||
}
|
||||
|
||||
public function isTaskExists($taskName = null, $command = null) {
|
||||
return $this->isWindows()
|
||||
? $this->isWindowsTaskExists($taskName)
|
||||
: $this->isLinuxTaskExists($command);
|
||||
}
|
||||
|
||||
public function removeTask($taskName = null, $command = null) {
|
||||
return $this->isWindows()
|
||||
? $this->removeWindowsTask($taskName)
|
||||
: $this->removeLinuxTask($command);
|
||||
}
|
||||
|
||||
private function addLinuxTask() {
|
||||
$cronJob = "{$this->interval} {$this->command}";
|
||||
if ($this->isLinuxTaskExists($this->command)) {
|
||||
return "✅ Cron-задача уже установлена.";
|
||||
}
|
||||
|
||||
exec("crontab -l 2>&1", $output, $return_var);
|
||||
if ($return_var !== 0) {
|
||||
$output = [];
|
||||
}
|
||||
|
||||
$output[] = $cronJob;
|
||||
file_put_contents("/tmp/my_cron", implode(PHP_EOL, $output) . PHP_EOL);
|
||||
exec("crontab /tmp/my_cron");
|
||||
unlink("/tmp/my_cron");
|
||||
|
||||
return "✅ Cron-задача добавлена!";
|
||||
}
|
||||
|
||||
private function isLinuxTaskExists($command = null) {
|
||||
exec("crontab -l 2>&1", $output);
|
||||
foreach ($output as $line) {
|
||||
if (strpos($line, $command ?? $this->command) !== false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function removeLinuxTask($command = null) {
|
||||
exec("crontab -l 2>&1", $output, $return_var);
|
||||
if ($return_var !== 0) {
|
||||
return "❌ Нет задач для удаления.";
|
||||
}
|
||||
|
||||
$filteredOutput = array_filter($output, function ($line) use ($command) {
|
||||
return strpos($line, $command ?? $this->command) === false;
|
||||
});
|
||||
|
||||
file_put_contents("/tmp/my_cron", implode(PHP_EOL, $filteredOutput) . PHP_EOL);
|
||||
exec("crontab /tmp/my_cron");
|
||||
unlink("/tmp/my_cron");
|
||||
|
||||
return "✅ Cron-задача удалена!";
|
||||
}
|
||||
|
||||
private function addWindowsTask() {
|
||||
if ($this->isWindowsTaskExists($this->taskName)) {
|
||||
return "✅ Задача уже существует в Windows.";
|
||||
}
|
||||
|
||||
$command = "schtasks /Create /SC MINUTE /MO 1 /TN \"{$this->taskName}\" /TR \"{$this->command}\" /F";
|
||||
exec($command, $output, $return_code);
|
||||
|
||||
return ($return_code === 0) ? "✅ Задача добавлена в Windows!" : "❌ Ошибка при добавлении задачи.";
|
||||
}
|
||||
|
||||
private function isWindowsTaskExists($taskName = null) {
|
||||
exec("schtasks /Query /TN \"". ($taskName ?? $this->taskName) ."\" 2>&1", $output, $return_var);
|
||||
return $return_var === 0;
|
||||
}
|
||||
|
||||
private function removeWindowsTask($taskName = null) {
|
||||
if (!$this->isWindowsTaskExists($taskName)) {
|
||||
return "❌ Задача не найдена в Windows.";
|
||||
}
|
||||
|
||||
exec("schtasks /Delete /TN \"". ($taskName ?? $this->taskName) ."\" /F", $output, $return_code);
|
||||
return ($return_code === 0) ? "✅ Задача удалена из Windows!" : "❌ Ошибка при удалении задачи.";
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -68,3 +68,5 @@ ngallery:
|
|||
allowgif: true
|
||||
comments:
|
||||
premoderation: false
|
||||
contests:
|
||||
enabled: true
|
||||
|
|
|
@ -371,10 +371,10 @@ table.nospaces > tbody > tr > td.lcol { padding:2px 6px 0; }
|
|||
.flag-left { padding-left:26px !important; }
|
||||
.input-flag { margin:-2px -26px 0 5px; position:relative; z-index:11; }
|
||||
|
||||
.contestBtn { display:block; cursor:pointer; width:56px; height:28px; margin:10px; background:url('/img/vote_contest.gif') no-repeat; opacity:0.7; }
|
||||
.contestBtn { display:block; cursor:pointer; width:56px; height:28px; margin:10px; background:url('/static/img/vote_contest.gif') no-repeat; opacity:0.7; }
|
||||
.contestBtn:hover { opacity:1; }
|
||||
.contestBtn.voted { opacity:1; background:url('/img/vote_contest_pressed.gif') no-repeat; }
|
||||
.contestBtn.loading { opacity:1; background:url('/img/vote_contest_loading.gif') no-repeat; }
|
||||
.contestBtn.voted { opacity:1; background:url('/static/img/vote_contest_pressed.gif') no-repeat; }
|
||||
.contestBtn.loading { opacity:1; background:url('/static/img/vote_contest_loading.gif') no-repeat; }
|
||||
|
||||
.died { border:solid 1px black; padding:0 2px; }
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 300 KiB After Width: | Height: | Size: 215 KiB |
BIN
static/img/vote_contest.gif
Normal file
BIN
static/img/vote_contest.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
BIN
static/img/vote_contest_loading.gif
Normal file
BIN
static/img/vote_contest_loading.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
BIN
static/img/vote_contest_pressed.gif
Normal file
BIN
static/img/vote_contest_pressed.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
|
@ -1,21 +1,22 @@
|
|||
function changeTab(id) {
|
||||
const $activeTabs = $('.v-tab-b.v-tab--active');
|
||||
const $activeBlocks = $('.active__block');
|
||||
const $newTab = $('#' + id);
|
||||
|
||||
if ($activeTabs.length) {
|
||||
$activeTabs.removeClass('v-tab--active');
|
||||
}
|
||||
|
||||
$('#' + id).addClass('v-tab--active');
|
||||
$newTab.addClass('v-tab--active');
|
||||
|
||||
if ($activeBlocks.length) {
|
||||
$activeBlocks.animate({
|
||||
$activeBlocks.stop(true, true).animate({
|
||||
opacity: 0,
|
||||
}, 200, function () {
|
||||
$(this).css('display', 'none').removeClass('active__block');
|
||||
|
||||
// Вторая анимация
|
||||
$('#' + id + '__block').css({
|
||||
const $newBlock = $('#' + id + '__block');
|
||||
$newBlock.css({
|
||||
display: 'block',
|
||||
opacity: 0
|
||||
}).animate({
|
||||
|
@ -24,5 +25,15 @@ function changeTab(id) {
|
|||
$(this).addClass('active__block');
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// Если нет активных блоков, сразу показываем новый блок
|
||||
$('#' + id + '__block').css({
|
||||
display: 'block',
|
||||
opacity: 0
|
||||
}).animate({
|
||||
opacity: 1
|
||||
}, 150, function () {
|
||||
$(this).addClass('active__block');
|
||||
});
|
||||
}
|
||||
}
|
|
@ -87,9 +87,8 @@ $(document).ready(function()
|
|||
}
|
||||
|
||||
$('#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');
|
||||
$('.vote[pid="' + pid + '"][vote="1"]')[data.buttons.posbtn ? 'addClass' : 'removeClass']('voted');
|
||||
$('.vote[pid="' + pid + '"][vote="0"]')[data.buttons.negbtn ? 'addClass' : 'removeClass']('voted')
|
||||
|
||||
var rating = parseInt(data.rating);
|
||||
if (rating > 0) $('#rating').html('+' + rating); else
|
||||
|
@ -127,19 +126,19 @@ $(document).ready(function()
|
|||
|
||||
$(this).toggleClass('voted');
|
||||
if ($(this).is('.voted')) $('.vote[pid="' + pid + '"] .konk_btn[vote="' + Number(!Number(vote)) + '"]').removeClass('voted');
|
||||
|
||||
var self_p = 0;
|
||||
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)
|
||||
$.getJSON('/api/photo/vote', { action: 'vote-konk', pid: pid, vote: vote }, function (data)
|
||||
{
|
||||
if (data && !data.errors)
|
||||
{
|
||||
$('.star[pid="' + pid + '"]').html(data.star ? '<img src="/img/star_' + data.star + '.png" alt="" />' : '');
|
||||
$('.vote[pid="' + pid + '"] .konk_btn[vote="1"]')[data.buttons.posbtn_contest ? 'addClass' : 'removeClass']('voted');
|
||||
$('.vote[pid="' + pid + '"] .konk_btn[vote="0"]')[data.buttons.negbtn_contest ? 'addClass' : 'removeClass']('voted');
|
||||
|
||||
$('.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)
|
||||
|
@ -164,14 +163,14 @@ $(document).ready(function()
|
|||
}
|
||||
else // Свои фото
|
||||
{
|
||||
$.getJSON('/api.php', { action: 'vote-author', pid: pid, vote: vote }, function (data)
|
||||
$.getJSON('/api/photo/vote', { action: 'vote-author', pid: pid, vote: vote }, function (data)
|
||||
{
|
||||
if (data && !data.errors)
|
||||
{
|
||||
$('#star[pid="' + pid + '"]').html(data.star ? '<img src="/img/star_' + data.star + '.png" alt="" />' : '');
|
||||
|
||||
$('.konk_btn[vote="1"]')[data.buttons[1] ? 'addClass' : 'removeClass']('voted');
|
||||
$('.konk_btn[vote="0"]')[data.buttons[0] ? 'addClass' : 'removeClass']('voted');
|
||||
$('.vote[pid="' + pid + '"] .konk_btn[vote="1"]')[data.buttons.posbtn_contest ? 'addClass' : 'removeClass']('voted');
|
||||
$('.vote[pid="' + pid + '"] .konk_btn[vote="0"]')[data.buttons.negbtn_contest ? 'addClass' : 'removeClass']('voted');
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -68,10 +68,10 @@ body {
|
|||
<i class="bx bx-news nav__icon"></i>
|
||||
<span class="nav__name">Новости сайта</span>
|
||||
</a>
|
||||
<!--a href="/admin?type=Contests" class="nav__link">
|
||||
<a href="/admin?type=Contests" class="nav__link">
|
||||
<i class="bx bx-party nav__icon"></i>
|
||||
<span class="nav__name">Фотоконкурсы <span class="badge text-bg-warning">BETA</span></span>
|
||||
<-->
|
||||
</a>
|
||||
<a href="/admin?type=Entities" class="nav__link">
|
||||
<i class="bx bx-package nav__icon"></i>
|
||||
<span class="nav__name">Сущности</span>
|
||||
|
|
264
views/pages/Admin/Contests.php
Normal file
264
views/pages/Admin/Contests.php
Normal file
|
@ -0,0 +1,264 @@
|
|||
<?php
|
||||
|
||||
use \App\Services\{Auth, DB, Date, TaskScheduler};
|
||||
use \App\Models\User;
|
||||
|
||||
$task = new TaskScheduler();
|
||||
|
||||
//$userprofile = new User(explode('/', $_SERVER['REQUEST_URI'])[2]);
|
||||
$contestCreate = true;
|
||||
if (!$task->isTaskExists("FinishContests", "php /path/to/finish_contests.php")) {
|
||||
$contestCreate = false;
|
||||
}
|
||||
?>
|
||||
|
||||
|
||||
<tr>
|
||||
<td class="main">
|
||||
<h1><b>Фотоконкурсы</b></h1>
|
||||
<div class="v-header__tabs">
|
||||
<div class="v-tabs">
|
||||
<div class="v-tabs__scroll">
|
||||
<div class="v-tabs__content"><a href="#" onclick="changeTab('contests')" id="contests" class="v-tab v-tab-b v-tab--active"><span class="v-tab__label">
|
||||
Конкурсы
|
||||
</span></a><a href="#" onclick="changeTab('categories')" id="categories" class="v-tab v-tab-b"><span class="v-tab__label">
|
||||
Категории
|
||||
|
||||
</span></a>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="kandle__block active__block" id="contests__block">
|
||||
<div class="p20w" style="display:block">
|
||||
<a data-bs-toggle="modal" data-bs-target="#createContest" href="#" class="btn btn-primary mt-3 <?php if ($contestCreate === false) {
|
||||
echo 'disabled';
|
||||
} ?>">Провести новый</a>
|
||||
<table class="table">
|
||||
<?php
|
||||
/*echo $task->addTask(
|
||||
"FinishContests",
|
||||
"php ".$_SERVER['DOCUMENT_ROOT']."/app/Controllers/Exec/Tasks/FinishContests.php >> ".$_SERVER['DOCUMENT_ROOT'].NGALLERY['root']['logslocation']." 2>&1",
|
||||
"* * * * *" // Каждую минуту (можно менять)
|
||||
);*/
|
||||
if ($contestCreate === false) {
|
||||
echo "<div class='alert alert-warning' role='alert'>У вас не добавлена задача на проведение конкурсов. Без неё, сервер не сможет завершать конкурс и проводить новый автоматически.</div>";
|
||||
}
|
||||
echo $task->removeTask("FinishContests", "php /path/to/finish_contests.php");
|
||||
|
||||
?>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th width="100">ID</th>
|
||||
<th width="25%">Тема</th>
|
||||
<th>Дата начала отбора</th>
|
||||
<th>Дата конца отбора</th>
|
||||
<th>Дата начала</th>
|
||||
<th>Дата конца</th>
|
||||
<th>Статус</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<?php
|
||||
$themes = DB::query('SELECT * FROM contests ORDER BY id DESC');
|
||||
foreach ($themes as $t) {
|
||||
$themetitle = DB::query('SELECT title FROM contests_themes WHERE id=:id', array(':id' => $t['themeid']))[0]['title'];
|
||||
if ($t['status'] === 0) {
|
||||
$status = 'Ещё не проведён';
|
||||
} else if ($t['status'] === 1) {
|
||||
$status = 'Отбор кандидатов';
|
||||
} else if ($t['status'] === 2) {
|
||||
$status = 'Отбор победителей';
|
||||
} else if ($t['status'] === 3) {
|
||||
$status = 'Завершён';
|
||||
} else {
|
||||
$status = 'Сбой';
|
||||
}
|
||||
echo '<tr class="' . $color . '">
|
||||
<td>' . $t['id'] . '</td>
|
||||
<td>' . $themetitle . '</td>
|
||||
<td>' . Date::zmdate($t['openpretendsdate']) . '</td>
|
||||
<td>' . Date::zmdate($t['closepretendsdate']) . '</td>
|
||||
<td>' . Date::zmdate($t['opendate']) . '</td>
|
||||
<td>' . Date::zmdate($t['closedate']) . '</td>
|
||||
<td>' . $status . '</td>
|
||||
</tr>';
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="kandle__block" style="display: none;" id="categories__block">
|
||||
<div class="p20w" style="display:block">
|
||||
<a data-bs-toggle="modal" data-bs-target="#createContestTheme" href="#" class="btn btn-primary mt-3">Создать</a>
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th width="100">ID</th>
|
||||
<th width="50%">Название</th>
|
||||
<th>В автоматическом отборе</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<?php
|
||||
$themes = DB::query('SELECT * FROM contests_themes');
|
||||
foreach ($themes as $t) {
|
||||
if ($t['status'] === 1) {
|
||||
$auto = 'Да';
|
||||
} else {
|
||||
$auto = 'Нет';
|
||||
}
|
||||
echo '<tr class="' . $color . '">
|
||||
<td>' . $t['id'] . '</td>
|
||||
<td>' . $t['title'] . '</td>
|
||||
<td>' . $auto . '</td>
|
||||
</tr>';
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<div class="modal fade" id="createContest" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5" id="exampleModalLabel"><b>Создание конкурса</b></h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form id="contest">
|
||||
<div class="mb-3">
|
||||
<label for="exampleFormControlTextarea1" class="form-label">Тематика</label>
|
||||
<select name="themeid" class="form-select" aria-label="Default select example">
|
||||
<option selected>Open this select menu</option>
|
||||
<option value="1">One</option>
|
||||
<option value="2">Two</option>
|
||||
<option value="3">Three</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="exampleFormControlTextarea1" class="form-label">Дата начала отбора претенднетов</label>
|
||||
<input name="openpretendsdate" type="datetime-local" class="form-select">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="exampleFormControlTextarea1" class="form-label">Дата конца отбора претенднетов</label>
|
||||
<input name="closepretendsdate" type="datetime-local" class="form-select">
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<div class="form-check">
|
||||
<input name="startContestNow" class="form-check-input" type="checkbox" value="1" id="startContestNow">
|
||||
<label class="form-check-label" for="startContestNow">
|
||||
Провести конкурс сразу после конца отбора претендентов
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="contestStart" class="form-label">Дата начала проведения конкурса</label>
|
||||
<input id="contestStartInput" name="opendate" type="datetime-local" class="form-select">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="exampleFormControlTextarea1" class="form-label">Дата конца проведения конкурса</label>
|
||||
<input name="closedate" type="datetime-local" class="form-select">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a type="button" class="btn btn-secondary" data-bs-dismiss="modal">Отмена</a>
|
||||
<a href="#" onclick="createContest(); return false;" data-bs-dismiss="modal" class="btn btn-primary">Добавить</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="createContestTheme" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5" id="exampleModalLabel"><b>Добавление категории конкурса</b></h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form id="contestTheme">
|
||||
<div class="mb-3">
|
||||
<label for="exampleFormControlTextarea1" class="form-label">Название</label>
|
||||
<input class="form-control" id="exampleFormControlTextarea1" name="body">
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="1" name="active" id="flexCheckChecked" checked>
|
||||
<label class="form-check-label" for="flexCheckChecked">
|
||||
Активна для автоматического подбора
|
||||
</label>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a type="button" class="btn btn-secondary" data-bs-dismiss="modal">Отмена</a>
|
||||
<a href="#" onclick="createContestTheme(); return false;" data-bs-dismiss="modal" class="btn btn-primary">Добавить</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('#startContestNow').on('change', function() {
|
||||
$('#contestStartInput').prop('disabled', $(this).is(':checked'));
|
||||
});
|
||||
});
|
||||
function createContestTheme() {
|
||||
var formData = new FormData(document.getElementById("contestTheme"));
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: '/api/admin/contests/createtheme',
|
||||
data: formData,
|
||||
success: function(response) {
|
||||
var jsonData = JSON.parse(response);
|
||||
|
||||
Notify.noty('success', 'OK!');
|
||||
|
||||
|
||||
},
|
||||
cache: false,
|
||||
contentType: false,
|
||||
processData: false
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function createContest() {
|
||||
var formData = new FormData(document.getElementById("contest"));
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: '/api/admin/contests/create',
|
||||
data: formData,
|
||||
success: function(response) {
|
||||
var jsonData = JSON.parse(response);
|
||||
|
||||
Notify.noty('success', 'OK!');
|
||||
|
||||
|
||||
},
|
||||
cache: false,
|
||||
contentType: false,
|
||||
processData: false
|
||||
});
|
||||
|
||||
}
|
||||
</script>
|
|
@ -39,10 +39,10 @@ use \App\Models\User;
|
|||
<div class="v-header__tabs">
|
||||
<div class="v-tabs">
|
||||
<div class="v-tabs__scroll">
|
||||
<div class="v-tabs__content"><a href="#" onclick="changeTab('full')" id="full" class="v-tab v-tab--active"><span class="v-tab__label">
|
||||
<div class="v-tabs__content"><a href="#" onclick="changeTab('full')" id="full" class="v-tab v-tab-b v-tab--active"><span class="v-tab__label">
|
||||
Полный список
|
||||
|
||||
</span></a><a href="#" onclick="changeTab('moderate')" id="moderate" class="v-tab"><span class="v-tab__label">
|
||||
</span></a><a href="#" onclick="changeTab('moderate')" id="moderate" class="v-tab v-tab-b"><span class="v-tab__label">
|
||||
Ожидают модерации
|
||||
|
||||
</span></a>
|
||||
|
|
|
@ -18,60 +18,325 @@ use \App\Models\User;
|
|||
<div id="backgr"></div>
|
||||
<table class="tmain">
|
||||
<?php include($_SERVER['DOCUMENT_ROOT'] . '/views/components/Navbar.php'); ?>
|
||||
<script>
|
||||
|
||||
var kid = 2119;
|
||||
var tipTimeout = null;
|
||||
|
||||
|
||||
function hideTip()
|
||||
{
|
||||
$('#tip').fadeOut('fast', function()
|
||||
{
|
||||
$(this).attr('lock', 0);
|
||||
$('#img').html('');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
$(document).ready(function()
|
||||
{
|
||||
$('.contestBtn').click(function()
|
||||
{
|
||||
var pid = $(this).attr('pid');
|
||||
var savedClass = $(this).attr('class');
|
||||
$(this).addClass('loading');
|
||||
|
||||
$.getJSON('/api.php', { action: 'vote-contest', kid: kid, pid: pid }, function (data)
|
||||
{
|
||||
if (data[0])
|
||||
{
|
||||
for (var pid in data[0])
|
||||
$('.contestBtn[pid="' + pid + '"]').attr('class', 'contestBtn' + (data[0][pid] == 0 ? '' : ' voted'));
|
||||
}
|
||||
else $('.contestBtn[pid="' + pid + '"]').attr('class', savedClass);
|
||||
|
||||
if (data[1]) alert(data[1]);
|
||||
})
|
||||
.fail(function(jx) { alert(jx.responseText); });
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
|
||||
$(document).on('mouseenter', '.f', function()
|
||||
{
|
||||
var hidden_img = $(this).closest('.p20p').prev('img');
|
||||
$('#img').html('<a href="/photo/' + hidden_img.attr('pid') + '/" target="_blank"><img src="' + (hidden_img.length ? hidden_img.attr('src') : this.src.replace('_s', '')) + '"></a>');
|
||||
$('#tip').css('top', $(window).scrollTop() + 20).show();
|
||||
})
|
||||
.on('mouseenter', '.f, #tip', function()
|
||||
{
|
||||
clearTimeout(tipTimeout);
|
||||
var lock = Math.min(parseInt($('#tip').attr('lock')) + 1, 2);
|
||||
$('#tip').attr('lock', lock);
|
||||
})
|
||||
.on('mouseleave', '.f, #tip', function()
|
||||
{
|
||||
var lock = Math.max(parseInt($('#tip').attr('lock')) - 1, 0);
|
||||
$('#tip').attr('lock', lock);
|
||||
tipTimeout = setTimeout(function() { if ($('#tip').attr('lock') == 0) hideTip(); }, 100);
|
||||
})
|
||||
.on('mousemove', '.f, #tip', function(e)
|
||||
{
|
||||
if (e.pageX > $(document).width() * 0.5) hideTip();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<tr>
|
||||
<td class="main">
|
||||
|
||||
<center>
|
||||
<h1>Фотоконкурс</h1>
|
||||
|
||||
<p class="narrow" style="font-size:19px"><b>Голосование</b> · <a href="?show=results">Победители</a> · <a href="?show=rating">Рейтинг</a> · <a href="?show=waiting">Претенденты</a></p>
|
||||
<p class="narrow" style="font-size:19px"><b>Голосование</b> · <a href="results">Победители</a> · <a href="/voting/rating">Рейтинг</a> · <a href="/voting/waiting">Претенденты</a></p>
|
||||
<div style="margin-top:20px">Чтобы проголосовать, отметьте одну, две или три фотографии, которые Вам понравились</div><br><br>
|
||||
<div class="p20">
|
||||
<?php
|
||||
if (DB::query('SELECT status FROM contests WHERE status=2')[0]['status'] != 2) {
|
||||
echo '<div class="p20">
|
||||
<h4>Сейчас конкурс не проводится. Пожалуйста, заходите позже.</h4>
|
||||
</div>
|
||||
<h2>Следующий Фотоконкурс будет через:</h2>
|
||||
<h1 id="countdown"></h1>
|
||||
<br>
|
||||
</div>';
|
||||
} else { ?>
|
||||
<div id="tip" lock="0"><span id="img"></span></div>
|
||||
<img pid="2044756" src="/photo/20/44/75/2044756.jpg?2" style="display:none">
|
||||
<div class="p20p">
|
||||
<table>
|
||||
<tr>
|
||||
<td><a href="#" pid="2044756" class="contestBtn"></a></td>
|
||||
<td class="pb_photo" id="p2044756"><a href="/photo/2044756/" target="_blank" class="prw"><img class="f" src="/img/prw-loader.gif" data-src="/photo/20/44/75/2044756_s.jpg?2" alt="1162 КБ">
|
||||
<div class="hpshade">
|
||||
<div class="eye-icon">353</div>
|
||||
</div>
|
||||
</a></td>
|
||||
<td class="pb_descr">
|
||||
<p><a href="/articles/3/" target="_blank">Фотозарисовки</a></p>
|
||||
<p><b class="pw-place">Линия 5</b> | Линия 5</p>
|
||||
<p class="sm"><b>16 января 2021 г., суббота</b><br>Автор: <a href="/author/17434/">Levis</a></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<img pid="2068176" src="/photo/20/68/17/2068176.jpg" style="display:none">
|
||||
<div class="p20p">
|
||||
<table>
|
||||
<tr>
|
||||
<td><a href="#" pid="2068176" class="contestBtn"></a></td>
|
||||
<td class="pb_photo" id="p2068176"><a href="/photo/2068176/" target="_blank" class="prw"><img class="f" src="/img/prw-loader.gif" data-src="/photo/20/68/17/2068176_s.jpg" alt="630 КБ">
|
||||
<div class="hpshade">
|
||||
<div class="com-icon">2</div>
|
||||
<div class="eye-icon">182</div>
|
||||
</div>
|
||||
</a></td>
|
||||
<td class="pb_descr">
|
||||
<p><span style="word-spacing:-1px"><span class="sec"><span class="nf"><a href="/city/237/" target="_blank">Гота</a></span>, Schindler/Siemens Be 4/8 <span class="nw">№ <span class="nf"><a href="/vehicle/97221/#n586477" target="_blank">222</a></span></span> — маршрут <a href="/search.php?cid=237&type=1&route=4" class="route">4</a></span></span><br><a href="/city/237/" target="_blank">Гота</a> — <a href="/articles/166/" target="_blank">Разные фотографии</a></p>
|
||||
<p><b class="pw-place">Boxberg <img src="/img/place_arrow.gif" alt="/" width="15" height="11" style="position:relative; top:-1px; margin:0 3px"> Leina</b><br><br><span class="pw-descr">Настоящий немецкий Сайлент Хилл!<br />
|
||||
<br />
|
||||
Echtes deutsches Silent Hill!</span></p>
|
||||
<p class="sm"><b>26 декабря 2024 г., четверг</b><br>Автор: <a href="/author/24525/">KIA-Trainz</a></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<img pid="2073198" src="/photo/20/73/19/2073198.jpg" style="display:none">
|
||||
<div class="p20p">
|
||||
<table>
|
||||
<tr>
|
||||
<td><a href="#" pid="2073198" class="contestBtn"></a></td>
|
||||
<td class="pb_photo" id="p2073198"><a href="/photo/2073198/" target="_blank" class="prw"><img class="f" src="/img/prw-loader.gif" data-src="/photo/20/73/19/2073198_s.jpg" alt="526 КБ">
|
||||
<div class="hpshade">
|
||||
<div class="eye-icon">246</div>
|
||||
</div>
|
||||
</a></td>
|
||||
<td class="pb_descr">
|
||||
<p><span style="word-spacing:-1px"><span class="sec"><span class="nf"><a href="/city/2/" target="_blank">Санкт-Петербург</a></span>, <span class="s5"> ЛВС-86К <span class="nw">№ <span class="nf"><a href="/vehicle/4653/#n4758" target="_blank">8200</a></span></span> </span> — маршрут <a href="/search.php?cid=2&type=1&route=52" class="route">52</a></span></span><br><a href="/city/2/" target="_blank">Санкт-Петербург</a> — <a href="/articles/1129/" target="_blank">Трамвайные линии и инфраструктура</a></p>
|
||||
<p><b class="pw-place">Проспект Маршала Жукова</b></p>
|
||||
<p class="sm"><b>18 ноября 2023 г., суббота</b><br>Автор: <a href="/author/19181/">Матвей Батуро</a></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<img pid="2069925" src="/photo/20/69/92/2069925.jpg" style="display:none">
|
||||
<div class="p20p">
|
||||
<table>
|
||||
<tr>
|
||||
<td><a href="#" pid="2069925" class="contestBtn"></a></td>
|
||||
<td class="pb_photo" id="p2069925"><a href="/photo/2069925/" target="_blank" class="prw"><img class="f" src="/img/prw-loader.gif" data-src="/photo/20/69/92/2069925_s.jpg" alt="797 КБ">
|
||||
<div class="hpshade">
|
||||
<div class="com-icon">5</div>
|
||||
<div class="eye-icon">251</div>
|
||||
</div>
|
||||
</a></td>
|
||||
<td class="pb_descr">
|
||||
<p><span style="word-spacing:-1px"><span class="sec"><span class="nf"><a href="/city/2/" target="_blank">Санкт-Петербург</a></span>, 71-931М «Витязь-М» <span class="nw">№ <span class="nf"><a href="/vehicle/562421/#n745611" target="_blank">7903</a></span></span> — перегонка</span></span><br><span style="word-spacing:-1px"><b><a href="/city/2/" target="_blank">Санкт-Петербург</a></b>, ПР (18М) <span class="nw">№ <b><a href="/vehicle/5073/#n5182" target="_blank">С-7116</a></b></span> — перегонка</span></p>
|
||||
<p><b class="pw-place">Улица Куйбышева</b></p>
|
||||
<p class="sm"><b>18 января 2025 г., суббота</b><br>Автор: <a href="/author/36016/">bo1ng10</a></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<img pid="2070488" src="/photo/20/70/48/2070488.jpg" style="display:none">
|
||||
<div class="p20p">
|
||||
<table>
|
||||
<tr>
|
||||
<td><a href="#" pid="2070488" class="contestBtn"></a></td>
|
||||
<td class="pb_photo" id="p2070488"><a href="/photo/2070488/" target="_blank" class="prw"><img class="f" src="/img/prw-loader.gif" data-src="/photo/20/70/48/2070488_s.jpg" alt="656 КБ">
|
||||
<div class="hpshade">
|
||||
<div class="com-icon">5</div>
|
||||
<div class="eye-icon">328</div>
|
||||
</div>
|
||||
</a></td>
|
||||
<td class="pb_descr">
|
||||
<p><span style="word-spacing:-1px"><b><a href="/city/2/" target="_blank">Санкт-Петербург</a></b>, <span class="s5"> 71-134А (ЛМ-99АВ) <span class="nw">№ <b><a href="/vehicle/5784/#n5890" target="_blank">8318</a></b></span> </span> — маршрут <b><a href="/search.php?cid=2&type=1&route=41" class="route">41</a></b></span></p>
|
||||
<p><b class="pw-place">Садовая улица</b></p>
|
||||
<p class="sm"><b>31 января 2025 г., пятница</b><br>Автор: <a href="/author/31083/">Yastrebov Nikolay</a></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<img pid="1456406" src="/photo/14/56/40/1456406.jpg" style="display:none">
|
||||
<div class="p20p">
|
||||
<table>
|
||||
<tr>
|
||||
<td><a href="#" pid="1456406" class="contestBtn"></a></td>
|
||||
<td class="pb_photo" id="p1456406"><a href="/photo/1456406/" target="_blank" class="prw"><img class="f" src="/img/prw-loader.gif" data-src="/photo/14/56/40/1456406_s.jpg" alt="481 КБ">
|
||||
<div class="hpshade">
|
||||
<div class="com-icon">1</div>
|
||||
<div class="eye-icon">582</div>
|
||||
</div>
|
||||
</a></td>
|
||||
<td class="pb_descr">
|
||||
<p><span style="word-spacing:-1px"><span class="sec"><span class="nf"><a href="/city/101/" target="_blank">Харьков</a></span>, T3-ВПСт <span class="nw">№ <span class="nf"><a href="/vehicle/452625/#n558420" target="_blank">3011</a></span></span> — маршрут <a href="/search.php?cid=101&type=1&route=3" class="route">3</a>, СМЕ 3011+3012</span></span><br><span style="word-spacing:-1px"><span class="sec"><span class="nf"><a href="/city/101/" target="_blank">Харьков</a></span>, T3-ВПСт <span class="nw">№ <span class="nf"><a href="/vehicle/452626/#n558421" target="_blank">3012</a></span></span> — маршрут <a href="/search.php?cid=101&type=1&route=3" class="route">3</a>, СМЕ 3011+3012</span></span><br><a href="/city/101/" target="_blank">Харьков</a> — <a href="/articles/5380/" target="_blank">Трамвайные линии</a></p>
|
||||
<p><b class="pw-place">Сергіївський майдан <img src="/img/place_arrow.gif" alt="/" width="15" height="11" style="position:relative; top:-1px; margin:0 3px"> Павлівська площа</b> | Сергиевская площадь <img src="/img/place_arrow.gif" alt="/" width="15" height="11" style="position:relative; top:-1px; margin:0 3px"> Павловская площадь</p>
|
||||
<p class="sm"><b>6 марта 2021 г., суббота</b><br>Автор: <a href="/author/21015/">Moon_Expedition</a></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<img pid="2074014" src="/photo/20/74/01/2074014.jpg" style="display:none">
|
||||
<div class="p20p">
|
||||
<table>
|
||||
<tr>
|
||||
<td><a href="#" pid="2074014" class="contestBtn"></a></td>
|
||||
<td class="pb_photo" id="p2074014"><a href="/photo/2074014/" target="_blank" class="prw"><img class="f" src="/img/prw-loader.gif" data-src="/photo/20/74/01/2074014_s.jpg" alt="555 КБ">
|
||||
<div class="hpshade">
|
||||
<div class="com-icon">16</div>
|
||||
<div class="eye-icon">1286</div>
|
||||
</div>
|
||||
</a></td>
|
||||
<td class="pb_descr">
|
||||
<p><span style="word-spacing:-1px"><b><a href="/city/2/" target="_blank">Санкт-Петербург</a></b>, ЛВС-86К <span class="nw">№ <b><a href="/vehicle/135069/#n130294" target="_blank">5117</a></b></span> — маршрут <b><a href="/search.php?cid=2&type=1&route=19" class="route">19</a></b></span><br><span style="word-spacing:-1px"><b><a href="/city/2/" target="_blank">Санкт-Петербург</a></b>, 71-638-02 «Поларис» <span class="nw">№ <b><a href="/vehicle/604225/#n803377" target="_blank">5810</a></b></span></span></p>
|
||||
<p><b class="pw-place">К/ст "Лахтинский разлив"</b></p>
|
||||
<p class="sm"><b>10 февраля 2025 г., понедельник</b><br>Автор: <a href="/author/26699/">Qwerty_qwertovich</a></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<img pid="2072063" src="/photo/20/72/06/2072063.jpg" style="display:none">
|
||||
<div class="p20p">
|
||||
<table>
|
||||
<tr>
|
||||
<td><a href="#" pid="2072063" class="contestBtn"></a></td>
|
||||
<td class="pb_photo" id="p2072063"><a href="/photo/2072063/" target="_blank" class="prw"><img class="f" src="/img/prw-loader.gif" data-src="/photo/20/72/06/2072063_s.jpg" alt="674 КБ">
|
||||
<div class="hpshade">
|
||||
<div class="eye-icon">224</div>
|
||||
</div>
|
||||
</a></td>
|
||||
<td class="pb_descr">
|
||||
<p><span style="word-spacing:-1px"><b><a href="/city/2/" target="_blank">Санкт-Петербург</a></b>, <span class="s3"> 81-717 (ЛВЗ) <span class="nw">№ <b><a href="/vehicle/258072/#n614988" target="_blank">8451</a></b></span> </span></span></p>
|
||||
<p><b class="pw-place">Электродепо "Московское" (ТЧ-3)</b><br><br><span class="pw-descr">Маневровые передвижения</span></p>
|
||||
<p class="sm"><b>7 февраля 2025 г., пятница</b><br>Автор: <a href="/author/20006/">frunzenecc</a></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<img pid="2068816" src="/photo/20/68/81/2068816.jpg" style="display:none">
|
||||
<div class="p20p">
|
||||
<table>
|
||||
<tr>
|
||||
<td><a href="#" pid="2068816" class="contestBtn"></a></td>
|
||||
<td class="pb_photo" id="p2068816"><a href="/photo/2068816/" target="_blank" class="prw"><img class="f" src="/img/prw-loader.gif" data-src="/photo/20/68/81/2068816_s.jpg" alt="675 КБ">
|
||||
<div class="hpshade">
|
||||
<div class="com-icon">3</div>
|
||||
<div class="eye-icon">322</div>
|
||||
</div>
|
||||
</a></td>
|
||||
<td class="pb_descr">
|
||||
<p><span style="word-spacing:-1px"><b><a href="/city/89/" target="_blank">Брест</a></b>, МАЗ-ЭТОН Т103 <span class="nw">№ <b><a href="/vehicle/54899/#n53610" target="_blank">118</a></b></span> — маршрут <b><a href="/search.php?cid=89&type=2&route=102" class="route">102</a></b></span></p>
|
||||
<p><b class="pw-place">Вуліца Гаўрылава</b> | Улица Гаврилова</p>
|
||||
<p class="sm"><b>29 января 2025 г., среда</b><br>Автор: <a href="/author/28158/">Ivan Tkachenko</a></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<img pid="2060153" src="/photo/20/60/15/2060153.jpg" style="display:none">
|
||||
<div class="p20p">
|
||||
<table>
|
||||
<tr>
|
||||
<td><a href="#" pid="2060153" class="contestBtn"></a></td>
|
||||
<td class="pb_photo" id="p2060153"><a href="/photo/2060153/" target="_blank" class="prw"><img class="f" src="/img/prw-loader.gif" data-src="/photo/20/60/15/2060153_s.jpg" alt="486 КБ">
|
||||
<div class="hpshade">
|
||||
<div class="eye-icon">204</div>
|
||||
</div>
|
||||
</a></td>
|
||||
<td class="pb_descr">
|
||||
<p><span style="word-spacing:-1px"><span class="sec"><span class="nf"><a href="/city/35/" target="_blank">Рига</a></span>, Tatra T3MR (T6B5-R) <span class="nw">№ <span class="nf"><a href="/vehicle/53599/#n101864" target="_blank">35098</a></span></span> — 35098+35108</span></span><br><a href="/city/35/" target="_blank">Рига</a> — <a href="/articles/7271/" target="_blank">Мосты</a></p>
|
||||
<p><b class="pw-place">Slokas iela</b> | Улица Слокас</p>
|
||||
<p class="sm"><b>28 октября 2024 г., понедельник</b><br>Автор: <a href="/author/18598/">Tučňák</a></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<br>Число проголосовавших: <b>3</b><br>Число голосов: <b>6</b><br><br>
|
||||
|
||||
</center>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<?php include($_SERVER['DOCUMENT_ROOT'] . '/views/components/Footer.php'); ?>
|
||||
|
||||
|
||||
</tr>
|
||||
<?php }
|
||||
?>
|
||||
|
||||
<h2>Следующий Фотоконкурс будет через:</h2>
|
||||
<h1 id="countdown"></h1>
|
||||
<br>
|
||||
|
||||
</center>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<?php include($_SERVER['DOCUMENT_ROOT'] . '/views/components/Footer.php'); ?>
|
||||
|
||||
|
||||
</tr>
|
||||
</table>
|
||||
<script>
|
||||
// Установите дату и время, до которого нужно отсчитывать
|
||||
const countdownDate = new Date("Mar 1, 2025 00:00:00").getTime();
|
||||
// Установите дату и время, до которого нужно отсчитывать
|
||||
const countdownDate = new Date("Mar 1, 2025 00:00:00").getTime();
|
||||
|
||||
// Обновляем отсчет каждую секунду
|
||||
const x = setInterval(function() {
|
||||
// Обновляем отсчет каждую секунду
|
||||
const x = setInterval(function() {
|
||||
|
||||
// Получаем текущее время
|
||||
const now = new Date().getTime();
|
||||
// Получаем текущее время
|
||||
const now = new Date().getTime();
|
||||
|
||||
// Вычисляем разницу между целевой датой и текущим временем
|
||||
const distance = countdownDate - now;
|
||||
// Вычисляем разницу между целевой датой и текущим временем
|
||||
const distance = countdownDate - now;
|
||||
|
||||
// Вычисляем дни, часы, минуты и секунды
|
||||
const days = Math.floor(distance / (1000 * 60 * 60 * 24));
|
||||
const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
|
||||
const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
|
||||
const seconds = Math.floor((distance % (1000 * 60)) / 1000);
|
||||
// Вычисляем дни, часы, минуты и секунды
|
||||
const days = Math.floor(distance / (1000 * 60 * 60 * 24));
|
||||
const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
|
||||
const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
|
||||
const seconds = Math.floor((distance % (1000 * 60)) / 1000);
|
||||
|
||||
// Отображаем результат в элементе с id "countdown"
|
||||
document.getElementById("countdown").innerHTML =
|
||||
days + ":" + hours + ":" + minutes + ":" + seconds;
|
||||
// Отображаем результат в элементе с id "countdown"
|
||||
document.getElementById("countdown").innerHTML =
|
||||
days + ":" + hours + ":" + minutes + ":" + seconds;
|
||||
|
||||
// Если отсчет завершен, выводим сообщение
|
||||
if (distance < 0) {
|
||||
clearInterval(x);
|
||||
document.getElementById("countdown").innerHTML = "Время истекло!";
|
||||
}
|
||||
}, 1000);
|
||||
</script>
|
||||
// Если отсчет завершен, выводим сообщение
|
||||
if (distance < 0) {
|
||||
clearInterval(x);
|
||||
document.getElementById("countdown").innerHTML = "Время истекло!";
|
||||
}
|
||||
}, 1000);
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -22,7 +22,7 @@ use \App\Models\User;
|
|||
<td class="main">
|
||||
<center>
|
||||
<h1>Победители фотоконкурса</h1>
|
||||
<p class="narrow" style="font-size:19px"><a href="/voting.php">Голосование</a> · <b>Победители</b> · <a href="?show=rating">Рейтинг</a> · <a href="?show=waiting">Претенденты</a></p>
|
||||
<p class="narrow" style="font-size:19px"><a href="/voting">Голосование</a> · <b>Победители</b> · <a href="/voting/rating">Рейтинг</a> · <a href="/voting/waiting">Претенденты</a></p>
|
||||
<div style="margin:20px">Для вывода подробного отчёта о конкурсе нажмите на интересующую вас дату.</div>
|
||||
<div class="pages"><span class="pg">««</span><span class="ps">1</span><a href="?show=results&st=10" class="pg">2</a><a href="?show=results&st=20" class="pg">3</a><a href="?show=results&st=30" class="pg">4</a> ··· <a href="?show=results&st=2090" class="pg">210</a><a href="?show=results&st=10" class="pg" id="NextLink">»»</a></div>
|
||||
<p><span class="narrow" style="font-size:21px"><b><a href="?show=table&date=2025-02-04" title="Подробный отчёт о конкурсе">04.02.2025</a></b></span><br><span class="sm">Линии и пейзажи</span></p>
|
||||
|
|
287
views/pages/Contests/VotingSendPretend.php
Normal file
287
views/pages/Contests/VotingSendPretend.php
Normal file
|
@ -0,0 +1,287 @@
|
|||
<?php
|
||||
|
||||
use \App\Services\{Auth, DB, Date};
|
||||
use \App\Models\{Vehicle, User};
|
||||
|
||||
function convertUnixToRussianDateTime($unixTime) {
|
||||
// Создаем объект DateTime из Unix-времени
|
||||
$dateTime = new DateTime("@$unixTime");
|
||||
|
||||
// Устанавливаем временную зону (можно изменить на нужную)
|
||||
$dateTime->setTimezone(new DateTimeZone('Europe/Moscow'));
|
||||
|
||||
// Форматируем дату и время с использованием IntlDateFormatter
|
||||
$formatter = new IntlDateFormatter(
|
||||
'ru_RU',
|
||||
IntlDateFormatter::LONG,
|
||||
IntlDateFormatter::NONE,
|
||||
'Europe/Moscow',
|
||||
IntlDateFormatter::GREGORIAN,
|
||||
'd MMMM yyyy года в H:mm'
|
||||
);
|
||||
|
||||
return $formatter->format($dateTime);
|
||||
}
|
||||
?>
|
||||
|
||||
<!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">
|
||||
<h1>Принять участие в Фотоконкурсе</h1>
|
||||
<script src="/js/jquery-ui.js?1633005526"></script>
|
||||
<script src="/js/selector.js?1730197663"></script>
|
||||
<script>
|
||||
addTexts({
|
||||
'VF_MAXLENGTH': 'Буфер обмена содержит %s знаков, но значение в этом поле не может быть длиннее %s знаков!\nВероятно, вы пытаетесь вставить некорректные данные'
|
||||
});
|
||||
|
||||
$(document).ready(function() {
|
||||
$('#mname').autocompleteSelector('mid', '/api.php?action=get-models&type=2', {
|
||||
minLength: 1,
|
||||
defaultLabel: '(модель неизвестна)',
|
||||
defaultValue: 632
|
||||
});
|
||||
$('#chname').autocompleteSelector('chid', '/api.php?action=get-chassis&type=2', {
|
||||
minLength: 1,
|
||||
defaultLabel: '(нет)'
|
||||
});
|
||||
|
||||
$('#state, #service').change(function() {
|
||||
$(this).attr('class', $('option:selected', this).attr('class'));
|
||||
}).change();
|
||||
|
||||
$('#mform').on('submit', function() {
|
||||
var built_y_len = $('#built_y').val().length;
|
||||
var scrap_y_len = $('#scrap_y').val().length;
|
||||
|
||||
if (built_y_len > 1 && built_y_len < 4 ||
|
||||
scrap_y_len > 1 && scrap_y_len < 4) {
|
||||
alert('Неверное значение в поле «год» (0, 1 либо 4 символа).');
|
||||
return false;
|
||||
}
|
||||
|
||||
var source = $('#source');
|
||||
|
||||
if (source.val().trim().length < 4) {
|
||||
alert('Не указан источник сведений. Пожалуйста, заполните соответствующее поле..');
|
||||
source[0].focus();
|
||||
return false;
|
||||
}
|
||||
|
||||
$('input[type="submit"]', this).prop('disabled', true);
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
// Фильтрация вставляемых из буфера данных
|
||||
$('#num, #gos, #zn, #vin, #cn, #start_y, #leave_y, #built_y, #scrap_y').on('paste', function(e) {
|
||||
var field = $(this);
|
||||
var text = e.originalEvent.clipboardData.getData('Text').trim();
|
||||
|
||||
var maxlength = parseInt(field.attr('maxlength'));
|
||||
if (maxlength && text.length > maxlength)
|
||||
alert(_text['VF_MAXLENGTH'].replace('%s', text.length).replace('%s', maxlength) + '.');
|
||||
else field.insertAtCaret(text);
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
// Опции даты
|
||||
$('.approx-aprx').css('font-weight', 'normal').on('change', function() {
|
||||
$(this).attr('class', 'approx-aprx ' + $('option:selected', this).attr('class'))
|
||||
}).change();
|
||||
});
|
||||
|
||||
|
||||
$.fn.insertAtCaret = function(myValue) {
|
||||
return this.each(function() {
|
||||
if (document.selection) {
|
||||
// For browsers like Internet Explorer
|
||||
this.focus();
|
||||
var sel = document.selection.createRange();
|
||||
sel.text = myValue;
|
||||
this.focus();
|
||||
} else
|
||||
if (this.selectionStart || this.selectionStart == '0') {
|
||||
// For browsers like Firefox and Webkit based
|
||||
var startPos = this.selectionStart;
|
||||
var endPos = this.selectionEnd;
|
||||
var scrollTop = this.scrollTop;
|
||||
this.value = this.value.substring(0, startPos) + myValue + this.value.substring(endPos, this.value.length);
|
||||
this.focus();
|
||||
this.selectionStart = startPos + myValue.length;
|
||||
this.selectionEnd = startPos + myValue.length;
|
||||
this.scrollTop = scrollTop;
|
||||
} else {
|
||||
this.value += myValue;
|
||||
this.focus();
|
||||
}
|
||||
})
|
||||
};
|
||||
</script>
|
||||
|
||||
<form method="post" id="mform" action="?action=write">
|
||||
<input type="hidden" name="cid" value="14">
|
||||
<input type="hidden" name="type" value="2">
|
||||
<input type="hidden" name="link_gos" value="0">
|
||||
|
||||
<input type="hidden" name="num" id="num" value="">
|
||||
|
||||
<h4>В каком Фотоконкурсе вы хотите принять участие?</h4>
|
||||
<div class="p20w">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Тематика</th>
|
||||
<th>Старт набора претендентов</th>
|
||||
<th>Закрытие набора претендентов</th>
|
||||
<th>Начало проведения</th>
|
||||
<th>Итоги и победители</th>
|
||||
</tr>
|
||||
|
||||
<?php
|
||||
$entities = DB::query('SELECT * FROM contests WHERE closepretendsdate>=:id', array(':id'=>time()));
|
||||
foreach ($entities as $e) {
|
||||
$theme = DB::query('SELECT * FROM contests_themes WHERE id=:id', array(':id'=>$e['themeid']))[0];
|
||||
echo '<tr>
|
||||
<td class="ds"><input type="radio" name="base_nid" id="n'.$e['id'].'" value="'.$e['id'].'" onclick="fillFields('.$e['id'].')"></td>
|
||||
<td class="n">'.$theme['title'].'</td>
|
||||
<td class="ds">'.convertUnixToRussianDateTime($e['openpretendsdate']).'</td>
|
||||
<td class="ds">'.convertUnixToRussianDateTime($e['closepretendsdate']).'</td>
|
||||
<td class="ds">'.convertUnixToRussianDateTime($e['opendate']).'</td>
|
||||
<td class="ds">'.convertUnixToRussianDateTime($e['closedate']).'</td>
|
||||
|
||||
</tr>';
|
||||
}
|
||||
?>
|
||||
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<br clear="all"><br>
|
||||
|
||||
<div class="p20" style="padding-left:5px; margin-bottom:15px">
|
||||
<table class="nospaces" width="100%">
|
||||
<input type="hidden" name="did" value="27">
|
||||
<tbody>
|
||||
<?php
|
||||
$vehicle = DB::query('SELECT * FROM entities WHERE id=:id', array(':id' => $_GET['type']))[0];
|
||||
$data = json_decode($vehicle['sampledata'], true);
|
||||
$count = 1;
|
||||
foreach ($data as $d) {
|
||||
|
||||
if ($d['important'] === "1") {
|
||||
$imp = 'required';
|
||||
}
|
||||
echo '
|
||||
<tr>
|
||||
<td class="lcol">' . $d['name'] . '</td>
|
||||
<td style="padding-bottom:15px"><input type="text" name="modelinput_'.$count.'" id="num" style="width:80px" maxlength="21" value=""></td>
|
||||
</tr>';
|
||||
$count++;
|
||||
}
|
||||
?>
|
||||
<tr>
|
||||
<td style="width: 10%"></td>
|
||||
|
||||
<script>
|
||||
var vdata = {};
|
||||
|
||||
vdata[0] = [0, '', '', '', 632, '(модель неизвестна)', 0, '(нет)', 0, 1, '', '', '', 0, '', 0, 0, '', 0, '', 0, '', 0, '', 0, '', 0, '', ''];
|
||||
vdata[594939] = [27, '48', '', '', 135, 'ПТЗ-5283', 0, '(нет)', 0, 5, '14', '', '', 11, '2002', 10, 0, '', 10, '2018-11-30', 10, '0000-00-00', 0, '0000-00-00', 0, '2022-00-00', 0, '', ''];
|
||||
|
||||
function setDateByYM(field, y, m, approx) {
|
||||
$('#' + field + '_m').val(m == 0 ? '' : m);
|
||||
$('#' + field + '_y').val(y == '0000' ? '' : y);
|
||||
$('#' + field + '_approx_aprx').val(approx).change();
|
||||
}
|
||||
|
||||
|
||||
function setDateByDate(field, date, approx) {
|
||||
var d = date.substring(8, 10);
|
||||
var m = date.substring(5, 7);
|
||||
var y = date.substring(0, 4);
|
||||
|
||||
$('#' + field + '_d').val(d == 0 ? '' : d);
|
||||
$('#' + field + '_m').val(m == 0 ? '' : m);
|
||||
$('#' + field + '_y').val(y == 0 ? '' : y);
|
||||
$('#' + field + '_approx_aprx').val(approx).change();
|
||||
}
|
||||
|
||||
|
||||
function fillFields(nid) {
|
||||
var i = 0;
|
||||
|
||||
$('#did').val(vdata[nid][i++]);
|
||||
$('#num').val(vdata[nid][i++]);
|
||||
$('#gos').val(vdata[nid][i++]);
|
||||
$('#nu2').val(vdata[nid][i++]);
|
||||
$('#mid').val(vdata[nid][i++]);
|
||||
$('#mname').val(vdata[nid][i++]);
|
||||
$('#chid').val(vdata[nid][i++]);
|
||||
$('#chname').val(vdata[nid][i++]);
|
||||
$('#service').val(vdata[nid][i++]).change();
|
||||
$('#state').val(vdata[nid][i++]).change();
|
||||
$('#zn').val(vdata[nid][i++]);
|
||||
$('#cn').val(vdata[nid][i++]);
|
||||
$('#vin').val(vdata[nid][i++]);
|
||||
|
||||
setDateByYM('built', vdata[nid][i + 1], vdata[nid][i], vdata[nid][i + 2]);
|
||||
i += 3;
|
||||
setDateByYM('scrap', vdata[nid][i + 1], vdata[nid][i], vdata[nid][i + 2]);
|
||||
i += 3;
|
||||
|
||||
setDateByDate('start', vdata[nid][i], vdata[nid][i + 1]);
|
||||
i += 2;
|
||||
setDateByDate('launc', vdata[nid][i], vdata[nid][i + 1]);
|
||||
i += 2;
|
||||
setDateByDate('haltd', vdata[nid][i], vdata[nid][i + 1]);
|
||||
i += 2;
|
||||
setDateByDate('leave', vdata[nid][i], vdata[nid][i + 1]);
|
||||
i += 2;
|
||||
|
||||
$('#note').val(vdata[nid][i++]);
|
||||
$('#history').val(vdata[nid][i++]);
|
||||
}
|
||||
</script>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>
|
||||
<br>
|
||||
<input type="submit" value=" Отправить ">
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
<?php include($_SERVER['DOCUMENT_ROOT'] . '/views/components/Footer.php'); ?>
|
||||
|
||||
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
File diff suppressed because it is too large
Load diff
|
@ -122,6 +122,78 @@ LIMIT 10;');
|
|||
}
|
||||
?>
|
||||
</div>
|
||||
<style>
|
||||
#contestNotify {
|
||||
background-size: 550px 211.2px;
|
||||
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 550 211.2" width="550" height="211.2" style="opacity: 0.3; filter: grayscale(0);"><text x="0em" y="1em" font-size="88" transform="rotate(17 55 52.8)">🎁</text><text x="1.25em" y="2em" font-size="88" transform="rotate(17 165 140.8)">🎈</text><text x="2.5em" y="1em" font-size="88" transform="rotate(17 275 52.8)">🎀</text><text x="3.75em" y="2em" font-size="88" transform="rotate(17 385 140.8)">🎊</text><text x="5em" y="1em" font-size="88" transform="rotate(17 495 52.8)">🎉</text></svg>');
|
||||
}
|
||||
</style>
|
||||
<?php
|
||||
if (DB::query('SELECT status FROM contests WHERE status=2')[0]['status'] === 2) {
|
||||
$contest = DB::query('SELECT * FROM contests WHERE status=2')[0];
|
||||
$theme = DB::query('SELECT * FROM contests_themes WHERE id=:id', array(':id'=>$contest['themeid']))[0];
|
||||
echo ' <div id="contestNotify" style="float:left; border:solid 1px #171022; padding:6px 10px 7px; margin-bottom:13px; background-color:#E5D6FF"><h4>Фотоконкурс!</h4>
|
||||
Закончится через: <b id="countdown"></b><br>
|
||||
Тематика: <b>'.$theme['title'].'</b><br>
|
||||
<b style="color: #412378;">Голосуйте за лучшие фотографии, которые должны стать победителями сегодняшнего конкурса!</b><br><br>
|
||||
<a href="/voting" style="background-color: #37009D; color: #fff;" type="button">Голосовать!</a>';
|
||||
} else if (DB::query('SELECT status FROM contests WHERE status=1')[0]['status'] === 1) {
|
||||
$contest = DB::query('SELECT * FROM contests WHERE status=1')[0];
|
||||
$theme = DB::query('SELECT * FROM contests_themes WHERE id=:id', array(':id'=>$contest['themeid']))[0];
|
||||
echo ' <div id="contestNotify" style="float:left; border:solid 1px #171022; padding:6px 10px 7px; margin-bottom:13px; background-color:#E5D6FF"><h4>Фотоконкурс!</h4>
|
||||
Начнётся через: <b id="countdown"></b><br>
|
||||
Тематика: <b>'.$theme.'</b><br>
|
||||
<b style="color: #412378;">Лучшие фотографии по мнению сообщества '.NGALLERY['root']['title'].' будут отмечены</b><br><br>
|
||||
<a href="/voting/sendpretend" style="background-color: #37009D; color: #fff;" type="button">Участвовать!</a>';
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<script>
|
||||
function startCountdown(unixTimestamp) {
|
||||
function padZero(num) {
|
||||
return num < 10 ? '0' + num : num;
|
||||
}
|
||||
|
||||
function getWord(num, words) {
|
||||
if (num % 10 === 1 && num % 100 !== 11) return words[0];
|
||||
if (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20)) return words[1];
|
||||
return words[2];
|
||||
}
|
||||
|
||||
function updateTimer() {
|
||||
const now = Math.floor(Date.now() / 1000);
|
||||
const diff = unixTimestamp - now;
|
||||
|
||||
if (diff <= 0) {
|
||||
clearInterval(interval);
|
||||
document.getElementById('countdown').textContent = "00 дней 00 часов 00 минут 00 секунд";
|
||||
return;
|
||||
}
|
||||
|
||||
const days = Math.floor(diff / 86400);
|
||||
const hours = Math.floor((diff % 86400) / 3600);
|
||||
const minutes = Math.floor((diff % 3600) / 60);
|
||||
const seconds = diff % 60;
|
||||
|
||||
document.getElementById('countdown').textContent =
|
||||
`${padZero(days)} ${getWord(days, ['день', 'дня', 'дней'])} ` +
|
||||
`${padZero(hours)} ${getWord(hours, ['час', 'часа', 'часов'])} ` +
|
||||
`${padZero(minutes)} ${getWord(minutes, ['минута', 'минуты', 'минут'])} ` +
|
||||
`${padZero(seconds)} ${getWord(seconds, ['секунда', 'секунды', 'секунд'])}`;
|
||||
}
|
||||
|
||||
updateTimer(); // сразу обновляем отображение
|
||||
const interval = setInterval(updateTimer, 1000);
|
||||
}
|
||||
startCountdown(1740607200);
|
||||
</script>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -258,15 +258,24 @@ if ($photo->i('id') !== null) {
|
|||
<a href="#" vote="0" class="vote_btn <?php if (Vote::photo(Auth::userid(), $id) === 0) {
|
||||
echo 'voted';
|
||||
} ?>"><span>Мне не нравится</span></a>
|
||||
<?php
|
||||
if ($photo->content('video') === null && $photo->i('user_id') != Auth::userid()) { ?>
|
||||
<a class="konk_btn <?php if (Vote::photoContest(Auth::userid(), $id) === 1) {
|
||||
echo 'voted';
|
||||
} ?>" vote="1" href="#"><span>Красиво, на конкурс!</span></a>
|
||||
<a href="#" vote="0" class="konk_btn <?php if (Vote::photoContest(Auth::userid(), $id) === 0) {
|
||||
echo 'voted';
|
||||
} ?>"><span>Неконкурсное фото</span></a>
|
||||
<?php } else if ($photo->i('user_id') === Auth::userid()) { ?>
|
||||
|
||||
<!--a class="konk_btn" vote="1" href="#"><span>Красиво, на конкурс!</span></!--a>
|
||||
<a-- href="#" vote="0" class="konk_btn"><span>Неконкурсное фото</span></a-->
|
||||
<a href="#" vote="1" class="konk_btn"><span>Выставить на конкурс</span></a><a href="#" vote="0" class="konk_btn"><span>Не участвовать в конкурсе</span></a></div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<?php } ?>
|
||||
<div id="votes" class="votes">
|
||||
<table class="vblock pro">
|
||||
<?php
|
||||
$votespos = DB::query('SELECT * FROM photos_rates WHERE photo_id=:pid AND type=1 ORDER BY id DESC', array(':pid' => $id));
|
||||
$votespos = DB::query('SELECT * FROM photos_rates WHERE photo_id=:pid AND type=1 AND contest=0 ORDER BY id DESC', array(':pid' => $id));
|
||||
foreach ($votespos as $ps) {
|
||||
$uservote = new User($ps['user_id']);
|
||||
echo ' <tr>
|
||||
|
@ -279,7 +288,7 @@ if ($photo->i('id') !== null) {
|
|||
</table>
|
||||
<table class="vblock coN">
|
||||
<?php
|
||||
$votespos = DB::query('SELECT * FROM photos_rates WHERE photo_id=:pid AND type=0 ORDER BY id DESC', array(':pid' => $id));
|
||||
$votespos = DB::query('SELECT * FROM photos_rates WHERE photo_id=:pid AND type=0 AND contest=0 ORDER BY id DESC', array(':pid' => $id));
|
||||
foreach ($votespos as $ps) {
|
||||
$uservote = new User($ps['user_id']);
|
||||
echo ' <tr>
|
||||
|
|
|
@ -90,7 +90,7 @@ if (Auth::userid() > 0) {
|
|||
</div>
|
||||
<div style="color:#e00" id="err_email"></div>
|
||||
<div class="styled-input">
|
||||
<input name="password" id="password" type="text" required="">
|
||||
<input name="password" id="password" type="password" required="">
|
||||
<label for="password">Ваш пароль</label>
|
||||
</div>
|
||||
<div style="color:#e00" id="err_password"></div>
|
||||
|
|
Loading…
Reference in a new issue