admin contest pages

This commit is contained in:
themohooks 2025-02-15 04:54:22 +03:00
parent 22e0fe0cec
commit 13f06db887
4 changed files with 377 additions and 4 deletions

View 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!" : "❌ Ошибка при удалении задачи.";
}
}
?>

View file

@ -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>

View 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>

View file

@ -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>