AdminPanel updates - changelog

-Admin menu updates
-Moved getchangelogtype/where to functions file and added to twig
-Added changelog editor to admin panel and updated changelog page
-Renamed the changelog md reader to clmd and edited the version file.
This commit is contained in:
Lee 2021-01-04 12:23:36 +00:00
parent 6c6af59b22
commit bb3602073c
11 changed files with 477 additions and 50 deletions

View File

@ -2,12 +2,25 @@
return [
['name' => 'Dashboard', 'icon' => 'tachometer-alt', 'link' => 'dashboard'],
['name' => 'News', 'icon' => 'newspaper', 'link' => 'news'],
['name' => 'News', 'icon' => 'newspaper', 'link' =>
[
['name' => 'View', 'link' => 'news'],
['name' => 'Add news', 'link' => 'news&action=new&type=1'],
['name' => 'Add ticker', 'link' => 'news&action=new&type=2'],
['name' => 'Add article', 'link' => 'news&action=new&type=3'],
],
],
['name' => 'Changelogs', 'icon' => 'newspaper', 'link' =>
[
['name' => 'View', 'link' => 'changelog'],
['name' => 'Add', 'link' => 'changelog&action=new'],
],
],
['name' => 'Mailer', 'icon' => 'envelope', 'link' => 'mailer', 'disabled' => !config('mail_enabled')],
['name' => 'Pages', 'icon' => 'book', 'link' =>
[
['name' => 'All Pages', 'link' => 'pages'],
['name' => 'Add new', 'link' => 'pages&action=new'],
['name' => 'View', 'link' => 'pages'],
['name' => 'Add', 'link' => 'pages&action=new'],
],
],
['name' => 'Menus', 'icon' => 'list', 'link' => 'menus'],
@ -32,4 +45,4 @@ return [
['name' => 'Visitors', 'icon' => 'user', 'link' => 'visitors'],
],
],
];
];

View File

@ -1299,6 +1299,33 @@ function getBanType($typeId)
return "Unknown Type";
}
function getChangelogType($v)
{
switch($v) {
case 1:
return 'added';
case 2:
return 'removed';
case 3:
return 'changed';
case 4:
return 'fixed';
}
return 'unknown';
}
function getChangelogWhere($v)
{
switch($v) {
case 1:
return 'server';
case 2:
return 'website';
}
return 'unknown';
}
function getPlayerNameByAccount($id)
{
global $vowels, $ots, $db;

125
system/libs/changelog.php Normal file
View File

@ -0,0 +1,125 @@
<?php
class Changelog
{
static public function verify($body,$date, &$errors)
{
if(!isset($date) || !isset($body[0])) {
$errors[] = 'Please fill all inputs.';
return false;
}
if(strlen($body) > CL_LIMIT) {
$errors[] = 'Changelog content cannot be longer than ' . CL_LIMIT . ' characters.';
return false;
}
return true;
}
static public function add($body, $type, $where, $player_id, $cdate, &$errors)
{
global $db;
if(!self::verify($body,$cdate, $errors))
return false;
$db->insert(TABLE_PREFIX . 'changelog', array('body' => $body, 'type' => $type, 'date' => $cdate, 'where' => $where, 'player_id' => isset($player_id) ? $player_id : 0));
self::clearCache();
return true;
}
static public function get($id) {
global $db;
return $db->select(TABLE_PREFIX . 'changelog', array('id' => $id));
}
static public function update($id, $body, $type, $where, $player_id, $date, &$errors)
{
global $db;
if(!self::verify($body,$date, $errors))
return false;
$db->update(TABLE_PREFIX . 'changelog', array('body' => $body, 'type' => $type, 'where' => $where, 'player_id' => isset($player_id) ? $player_id : 0, 'date' => $date), array('id' => $id));
self::clearCache();
return true;
}
static public function delete($id, &$errors)
{
global $db;
if(isset($id))
{
if($db->select(TABLE_PREFIX . 'changelog', array('id' => $id)) !== false)
$db->delete(TABLE_PREFIX . 'changelog', array('id' => $id));
else
$errors[] = 'Changelog with id ' . $id . ' does not exist.';
}
else
$errors[] = 'Changelog id not set.';
if(count($errors)) {
return false;
}
self::clearCache();
return true;
}
static public function toggleHidden($id, &$errors, &$status)
{
global $db;
if(isset($id))
{
$query = $db->select(TABLE_PREFIX . 'changelog', array('id' => $id));
if($query !== false)
{
$db->update(TABLE_PREFIX . 'changelog', array('hidden' => ($query['hidden'] == 1 ? 0 : 1)), array('id' => $id));
$status = $query['hidden'];
}
else
$errors[] = 'Changelog with id ' . $id . ' does not exists.';
}
else
$errors[] = 'Changelog id not set.';
if(count($errors)) {
return false;
}
self::clearCache();
return true;
}
static public function getCached($type)
{
global $template_name;
$cache = Cache::getInstance();
if ($cache->enabled())
{
$tmp = '';
if ($cache->fetch('changelog_' . $template_name, $tmp) && isset($tmp[0])) {
return $tmp;
}
}
return false;
}
static public function clearCache()
{
global $template_name;
$cache = Cache::getInstance();
if (!$cache->enabled()) {
return;
}
$tmp = '';
foreach (get_templates() as $template) {
if ($cache->fetch('changelog_' . $template_name, $tmp)) {
$cache->delete('changelog_' . $template_name);
}
}
}
}

View File

@ -1,26 +1,140 @@
<?php
/**
* CHANGELOG viewer
* CHANGELOG modifier
*
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @copyright 2019 MyAAC
* @author Lee
* @copyright 2020 MyAAC
* @link https://my-aac.org
*/
defined('MYAAC') or die('Direct access not allowed!');
$title = 'MyAAC Changelog';
if (!file_exists(BASE . 'CHANGELOG.md')) {
echo 'File CHANGELOG.md doesn\'t exist.';
if (!hasFlag(FLAG_CONTENT_PAGES) && !superAdmin()) {
echo 'Access denied.';
return;
}
require LIBS . 'Parsedown.php';
$title = 'Changelog';
$use_datatable = true;
define('CL_LIMIT', 600); // maximum changelog body length
?>
$changelog = file_get_contents(BASE . 'CHANGELOG.md');
<link rel="stylesheet" type="text/css" href="<?php echo BASE_URL; ?>tools/css/jquery.datetimepicker.css"/ >
<script src="<?php echo BASE_URL; ?>tools/js/jquery.datetimepicker.js"></script>
<?php
$id = isset($_GET['id']) ? $_GET['id'] : 0;
require_once LIBS . 'changelog.php';
$Parsedown = new Parsedown();
if(!empty($action))
{
$id = isset($_REQUEST['id']) ? $_REQUEST['id'] : null;
$body = isset($_REQUEST['body']) ? stripslashes($_REQUEST['body']) : null;
$create_date = isset($_REQUEST['createdate']) ? (int)strtotime($_REQUEST['createdate'] ): null;
$player_id = isset($_REQUEST['player_id']) ? (int)$_REQUEST['player_id'] : null;
$type = isset($_REQUEST['type']) ? (int)$_REQUEST['type'] : null;
$where = isset($_REQUEST['where']) ? (int)$_REQUEST['where'] : null;
$changelog = $Parsedown->text($changelog); # prints: <p>Hello <em>Parsedown</em>!</p>
$errors = array();
echo '<div>' . $changelog . '</div>';
if($action == 'add') {
if(Changelog::add($body, $type, $where, $player_id, $create_date, $errors)) {
$body = '';
$type = $where = $player_id = $create_date = 0;
success("Added successful.");
}
}
else if($action == 'delete') {
Changelog::delete($id, $errors);
success("Deleted successful.");
}
else if($action == 'edit')
{
if(isset($id) && !isset($body)) {
$cl = Changelog::get($id);
$body = $cl['body'];
$type = $cl['type'];
$where = $cl['where'];
$create_date = $cl['date'];
$player_id = $cl['player_id'];
}
else {
if(Changelog::update($id, $body, $type, $where, $player_id, $create_date,$errors)) {
$action = $body = '';
$type = $where = $player_id = $create_date = 0;
success("Updated successful.");
}
}
}
else if($action == 'hide') {
Changelog::toggleHidden($id, $errors, $status);
success(($status == 1 ? 'Show' : 'Hide') . " successful.");
}
if(!empty($errors))
error(implode(", ", $errors));
}
$changelogs = $db->query('SELECT * FROM `' . TABLE_PREFIX . 'changelog' . '` ORDER BY `id` DESC')->fetchAll();
$i = 0;
$log_type = [
['id' => 1, 'icon' => 'added'],
['id' => 2, 'icon' => 'removed'],
['id' => 3, 'icon' => 'changed'],
['id' => 4, 'icon' => 'fixed'],
];
$log_where = [
['id' => 1, 'icon' => 'server'],
['id' => 2, 'icon' => 'website'],
];
foreach($changelogs as $key => &$log)
{
$log['type'] = getChangelogType($log['type']);
$log['where'] = getChangelogWhere($log['where']);
}
if($action == 'edit' || $action == 'new') {
if($action == 'edit') {
$player = new OTS_Player();
$player->load($player_id);
}
$account_players = $account_logged->getPlayersList();
$account_players->orderBy('group_id', POT::ORDER_DESC);
$twig->display('admin.changelog.form.html.twig', array(
'action' => $action,
'cl_link_form' => constant('ADMIN_URL').'?p=changelog&action=' . ($action == 'edit' ? 'edit' : 'add'),
'cl_id' => isset($id) ? $id : null,
'body' => isset($body) ? htmlentities($body, ENT_COMPAT, 'UTF-8') : '',
'create_date' => isset($create_date) ? $create_date : '',
'player' => isset($player) && $player->isLoaded() ? $player : null,
'player_id' => isset($player_id) ? $player_id : null,
'account_players' => $account_players,
'type' => isset($type) ? $type : 0,
'where' => isset($where) ? $where : 0,
'log_type' => $log_type,
'log_where' => $log_where,
));
}
$twig->display('admin.changelog.html.twig', array(
'changelogs' => $changelogs,
));
?>
<script>
$(document).ready(function () {
$('#createdate').datetimepicker({format: "M d Y, H:i:s",});
$('.tb_datatable').DataTable({
"order": [[0, "desc"]],
"columnDefs": [{targets: [1, 2,4,5],orderable: false}]
});
});
</script>

View File

@ -0,0 +1,27 @@
<?php
/**
* CHANGELOG viewer
*
* @package MyAAC
* @author Slawkens <slawkens@gmail.com>
* @author Lee
* @copyright 2020 MyAAC
* @link https://my-aac.org
*/
defined('MYAAC') or die('Direct access not allowed!');
$title = 'MyAAC Changelog';
if (!file_exists(BASE . 'CHANGELOG.md')) {
echo 'File CHANGELOG.md doesn\'t exist.';
return;
}
require LIBS . 'Parsedown.php';
$changelog = file_get_contents(BASE . 'CHANGELOG.md');
$Parsedown = new Parsedown();
$changelog = $Parsedown->text($changelog); # prints: <p>Hello <em>Parsedown</em>!</p>
echo '<div>' . $changelog . '</div>';

View File

@ -24,10 +24,10 @@ if (!$myaac_version) {
$version_compare = version_compare($myaac_version, MYAAC_VERSION);
if ($version_compare == 0) {
success('MyAAC latest version is ' . $myaac_version . '. You\'re using the latest version.
<br/>View CHANGELOG ' . generateLink(ADMIN_URL . '?p=changelog', 'here'));
<br/>View CHANGELOG ' . generateLink(ADMIN_URL . '?p=clmd', 'here'));
} else if ($version_compare < 0) {
success('Woah, seems you\'re using newer version as latest released one! MyAAC latest released version is ' . $myaac_version . ', and you\'re using version ' . MYAAC_VERSION . '.
<br/>View CHANGELOG ' . generateLink(ADMIN_URL . '?p=changelog', 'here'));
<br/>View CHANGELOG ' . generateLink(ADMIN_URL . '?p=clmd', 'here'));
} else {
warning('You\'re using outdated version.<br/>
Your version: <b>' . MYAAC_VERSION . '</b><br/>

View File

@ -16,7 +16,9 @@ $limit = 30;
$offset = $_page * $limit;
$next_page = false;
$changelogs = $db->query('SELECT * FROM `' . TABLE_PREFIX . 'changelog' . '` WHERE `hidden` = 0 ORDER BY `id` DESC LIMIT ' . ($limit + 1) . ' OFFSET ' . $offset)->fetchAll();
$canEdit = hasFlag(FLAG_CONTENT_NEWS) || superAdmin();
$changelogs = $db->query('SELECT * FROM `' . TABLE_PREFIX . 'changelog` ' . ($canEdit ? '' : 'WHERE `hidden` = 0').' ORDER BY `id` DESC LIMIT ' . ($limit + 1) . ' OFFSET ' . $offset)->fetchAll();
$i = 0;
foreach($changelogs as $key => &$log)
@ -39,33 +41,6 @@ $twig->display('changelog.html.twig', array(
'changelogs' => $changelogs,
'page' => $_page,
'next_page' => $next_page,
'canEdit' => $canEdit,
));
function getChangelogType($v)
{
switch($v) {
case 1:
return 'added';
case 2:
return 'removed';
case 3:
return 'changed';
case 4:
return 'fixed';
}
return 'unknown';
}
function getChangelogWhere($v)
{
switch($v) {
case 1:
return 'server';
case 2:
return 'website';
}
return 'unknown';
}
?>

View File

@ -0,0 +1,59 @@
{% if action %}
<div class="card card-info card-outline">
<div class="card-header">
<h5 class="m-0">{{ (action == 'edit') ? 'Edit' : 'Add' }}</h5>
</div>
<form role="form" method="post" action="{{ cl_link_form }}" id="cl-edit-form">
<div class="card-body">
{% if action == 'edit' %}
<input type="hidden" name="id" value="{{ cl_id }}"/>
{% endif %}
<div class="form-group row">
<label for="body">Content</label>
<textarea class="form-control" id="body" name="body" maxlength="600" cols="50" rows="5">{{ body|raw }}</textarea>
</div>
<div class="form-group row">
<div class="col-12 col-sm-12 col-lg-6">
<label for="createdate" class="control-label">Date:</label>
<input type="text" class="form-control" id="createdate" name="createdate" autocomplete="off" maxlength="20" value="{{ create_date|date("M d Y, H:i:s") }}"/>
</div>
<div class="col-sm-6 pl-0">
<label for="player_id">Author</label>
<select class="form-control" name="player_id" id="player_id">
{% for player in account_players %}
<option value="{{ player.getId() }}"{% if player_id is defined and player.getId() == player_id %} selected="selected"{% endif %}>{{ player.getName() }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group row">
<div class="col-sm-6 pl-0">
<label for="select-where">Where</label>
<select class="form-control" name="where" id="select-where">
{% for id, cat in log_where %}
<option value="{{ cat.id }}"
{% if (where == 0 and id == 1) or (where == cat.id) %}selected="selected"{% endif %}>{{ cat.icon|capitalize }}</option>
{% endfor %}
</select>
</div>
<div class="col-sm-6 pl-0">
<label for="select-type">Type</label>
<select class="form-control" name="type" id="select-type">
{% for id, cat in log_type %}
<option value="{{ cat.id }}"
{% if (type == 0 and id == 1) or (type == cat.id) %}selected="selected"{% endif %}>{{ cat.icon|capitalize }}</option>
{% endfor %}
</select>
</div>
</div>
</div>
<div class="card-footer">
<button type="submit" class="btn btn-info"><i class="fas fa-update"></i> {{ (action == 'edit') ? 'Update' : 'Add' }}</button>
<button type="button" onclick="window.location = '{{ constant('ADMIN_URL') }}?p=changelog';"
class="btn btn-danger float-right"><i class="fas fa-cancel"></i> Cancel
</button>
</div>
</form>
</div>
{% endif %}

View File

@ -0,0 +1,55 @@
<div class="card card-info card-outline">
<div class="card-header">
<h5 class="m-0">News:
<a href="{{ constant('ADMIN_URL') }}?p=changelog&action=new" class="float-right"><span
class="btn btn-sm btn-success">New</span></a>
</h5>
</div>
<div class="card-body">
<table class="tb_datatable table table-striped table-bordered">
<thead>
<tr>
<th width="5%">ID</th>
<th>Date</th>
<th>Description</th>
<th>Type</th>
<th>Where</th>
<th></th>
</tr>
</thead>
<tbody>
{% if changelogs|length > 0 %}
{% set i = 0 %}
{% for log in changelogs %}
<tr>
<td>{{ log.id }}</td>
<td>{{ log.date|date("j.m.Y") }}</td>
<td>{{ truncate(log.body|raw,20) }}</td>
<td><img src="{{ constant('BASE_URL') }}images/changelog/{{ log.type }}.png" title="{{ log.type|capitalize }}"/> {{ log.type|capitalize }}</td>
<td><img src="{{ constant('BASE_URL') }}images/changelog/{{ log.where }}.png" title="{{ log.where|capitalize }}"/> {{ log.where|capitalize }}</td>
<td>
<div class="btn-group">
<a href="{{ constant('ADMIN_URL') }}?p=changelog&action=edit&id={{ log.id }}" class="btn btn-success btn-sm" title="Edit">
<i class="fas fa-pencil-alt"></i>
</a>
<a href="{{ constant('ADMIN_URL') }}?p=changelog&action=delete&id={{ log.id }}" class="btn btn-danger btn-sm" onclick="return confirm('Are you sure?');" title="Delete">
<i class="fas fa-trash"></i>
</a>
<a href="{{ constant('ADMIN_URL') }}?p=changelog&action=hide&id={{ log.id }}" class="btn btn-{{ (log.hidden != 1) ? 'info' : 'default' }} btn-sm" title="{% if log.hidden != 1 %}Hide{% else %}Show{% endif %}">
<i class="fas fa-eye{{ (log.hidden != 1) ? '' : '-slash' }}"></i>
</a>
</div>
</td>
</tr>
{% set i = i + 1 %}
{% endfor %}
{% else %}
<tr>
<td colspan="6">There are no changelogs for the moment.</td>
</tr>
{% endif %}
</tbody>
</table>
</div>
</div>

View File

@ -1,23 +1,41 @@
<br/>
{% if canEdit %}
<a href="{{ constant('ADMIN_URL') }}?p=changelog&action=new" class="btn btn-success btn-sm" title="Add New" target="_blank">Add New</a>
{% endif %}
<table border="0" cellspacing="1" cellpadding="4" width="100%">
<tr bgcolor="{{ config.vdarkborder }}">
<td width="22"><span class="white"><b>Type</b></span></td>
<td width="22"><span class="white"><b>Where</b></span></td>
<td width="50"><span class="white"><b>Date</b></span></td>
<td><span class="white"><b>Description</b></span></td>
{% if canEdit %}
<td></td>
{% endif %}
</tr>
{% if changelogs|length > 0%}
{% set i = 0 %}
{% for log in changelogs %}
<tr bgcolor="{{ getStyle(i) }}">
<td align="center">
<img src="images/changelog/{{ log.type }}.png" title="{{ log.type|capitalize }}"/>
<img src="{{ constant('BASE_URL') }}images/changelog/{{ log.type }}.png" title="{{ log.type|capitalize }}"/>
</td>
<td align="center">
<img src="images/changelog/{{ log.where }}.png" title="{{ log.where|capitalize }}"/>
<img src="{{ constant('BASE_URL') }}images/changelog/{{ log.where }}.png" title="{{ log.where|capitalize }}"/>
</td>
<td>{{ log.date|date("j.m.Y") }}</td>
<td>{{ log.body|raw }}</td>
<td>{{ log.body|nl2br}}</td>
{% if canEdit %}
<td>
<a href="{{ constant('ADMIN_URL') }}?p=changelog&action=edit&id={{ log.id }}" title="Edit in Admin Panel" target="_blank">
<img src="images/edit.png"/>Edit
</a>
<a href="{{ constant('ADMIN_URL') }}?p=changelog&action=delete&id={{ log.id }}" onclick="return confirm('Are you sure?');" title="Delete in Admin Panel" target="_blank">
<img src="images/del.png"/>Delete
</a>
<a href="{{ constant('ADMIN_URL') }}?p=changelog&action=hide&id={{ log.id }}" title="{% if log.hidden != 1 %}Hide{% else %}Show{% endif %} in Admin Panel" target="_blank">
<img src="images/{{ (log.hidden != 1 ? 'success' : 'error') }}.png"/>{{ (log.hidden != 1) ? 'Hide' : 'Show' }}
</a>
</td>
{% endif %}
</tr>
{% set i = i + 1 %}
{% endfor %}
@ -35,4 +53,4 @@
<tr><td width="100%" align="right" valign="bottom"><a href="{{ getLink('changelog/' ~ (page + 1)) }}" class="size_xxs">Next Page</a></td></tr>
{% endif %}
</table>
</table>
</table>

View File

@ -54,6 +54,20 @@ $function = new TwigFunction('getGuildLink', function ($s, $p) {
});
$twig->addFunction($function);
$function = new TwigFunction('truncate', function ($s, $n) {
return truncate($s, $n);
});
$twig->addFunction($function);
$function = new TwigFunction('getChangelogType', function ($n) {
return getChangelogType($n);
});
$twig->addFunction($function);
$function = new TwigFunction('getChangelogWhere', function ($n) {
return getChangelogWhere($n);
});
$twig->addFunction($function);
$function = new TwigFunction('hook', function ($hook) {
global $hooks;