mirror of
https://github.com/sruupl/batflat.git
synced 2026-01-14 01:42:04 +01:00
473 lines
16 KiB
PHP
473 lines
16 KiB
PHP
<?php
|
|
/**
|
|
* This file is part of Batflat ~ the lightweight, fast and easy CMS
|
|
*
|
|
* @author Paweł Klockiewicz <klockiewicz@sruu.pl>
|
|
* @author Wojciech Król <krol@sruu.pl>
|
|
* @copyright 2017 Paweł Klockiewicz, Wojciech Król <Sruu.pl>
|
|
* @license https://batflat.org/license
|
|
* @link https://batflat.org
|
|
*/
|
|
|
|
namespace Inc\Modules\Blog;
|
|
|
|
use Inc\Core\AdminModule;
|
|
|
|
class Admin extends AdminModule
|
|
{
|
|
private $assign = [];
|
|
|
|
public function navigation()
|
|
{
|
|
return [
|
|
$this->lang('manage', 'general') => 'manage',
|
|
$this->lang('add_new') => 'add',
|
|
$this->lang('settings') => 'settings'
|
|
];
|
|
}
|
|
|
|
/**
|
|
* list of posts
|
|
*/
|
|
public function anyManage($page = 1)
|
|
{
|
|
if (isset($_POST['delete'])) {
|
|
if (isset($_POST['post-list']) && !empty($_POST['post-list'])) {
|
|
foreach ($_POST['post-list'] as $item) {
|
|
$row = $this->db('blog')->where('id', $item)->oneArray();
|
|
if ($this->db('blog')->delete($item) === 1) {
|
|
if (!empty($row['cover_photo']) && file_exists(UPLOADS."/blog/".$row['cover_photo'])) {
|
|
unlink(UPLOADS."/blog/".$row['cover_photo']);
|
|
}
|
|
|
|
$this->notify('success', $this->lang('delete_success'));
|
|
} else {
|
|
$this->notify('failure', $this->lang('delete_failure'));
|
|
}
|
|
}
|
|
|
|
redirect(url([ADMIN, 'blog', 'manage']));
|
|
}
|
|
}
|
|
|
|
// lang
|
|
if (!empty($_GET['lang'])) {
|
|
$lang = $_GET['lang'];
|
|
$_SESSION['blog']['last_lang'] = $lang;
|
|
} elseif (!empty($_SESSION['blog']['last_lang'])) {
|
|
$lang = $_SESSION['blog']['last_lang'];
|
|
} else {
|
|
$lang = $this->settings('settings.lang_site');
|
|
}
|
|
|
|
// pagination
|
|
$totalRecords = count($this->db('blog')->where('lang', $lang)->toArray());
|
|
$pagination = new \Inc\Core\Lib\Pagination($page, $totalRecords, 10, url([ADMIN, 'blog', 'manage', '%d']));
|
|
$this->assign['pagination'] = $pagination->nav();
|
|
|
|
// list
|
|
$this->assign['newURL'] = url([ADMIN, 'blog', 'add']);
|
|
$this->assign['postCount'] = 0;
|
|
$rows = $this->db('blog')
|
|
->where('lang', $lang)
|
|
->limit($pagination->offset().', '.$pagination->getRecordsPerPage())
|
|
->desc('published_at')->desc('created_at')
|
|
->toArray();
|
|
|
|
$this->assign['posts'] = [];
|
|
if ($totalRecords) {
|
|
$this->assign['postCount'] = $totalRecords;
|
|
foreach ($rows as $row) {
|
|
$row['editURL'] = url([ADMIN, 'blog', 'edit', $row['id']]);
|
|
$row['delURL'] = url([ADMIN, 'blog', 'delete', $row['id']]);
|
|
$row['viewURL'] = url(['blog', 'post', $row['slug']]);
|
|
|
|
|
|
$fullname = $this->core->getUserInfo('fullname', $row['user_id'], true);
|
|
$username = $this->core->getUserInfo('username', $row['user_id'], true);
|
|
$row['user'] = !empty($fullname) ? $fullname.' ('.$username.')' : $username;
|
|
|
|
$row['comments'] = $row['comments'] ? $this->lang('comments_on') : $this->lang('comments_off');
|
|
|
|
switch ($row['status']) {
|
|
case 0:
|
|
$row['type'] = $this->lang('post_sketch');
|
|
break;
|
|
case 1:
|
|
$row['type'] = $this->lang('post_hidden');
|
|
break;
|
|
case 2:
|
|
$row['type'] = $this->lang('post_published');
|
|
break;
|
|
default:
|
|
case 0:
|
|
$row['type'] = "Unknown";
|
|
}
|
|
|
|
$row['created_at'] = date("d-m-Y", $row['created_at']);
|
|
$row['published_at'] = date("d-m-Y", $row['published_at']);
|
|
|
|
$row = htmlspecialchars_array($row);
|
|
$this->assign['posts'][] = $row;
|
|
}
|
|
}
|
|
|
|
$this->assign['langs'] = $this->_getLanguages($lang);
|
|
|
|
return $this->draw('manage.html', ['blog' => $this->assign]);
|
|
}
|
|
|
|
/**
|
|
* add new post
|
|
*/
|
|
public function getAdd()
|
|
{
|
|
return $this->getEdit(null);
|
|
}
|
|
|
|
|
|
/**
|
|
* edit post
|
|
*/
|
|
public function getEdit($id = null)
|
|
{
|
|
$this->assign['manageURL'] = url([ADMIN, 'blog', 'manage']);
|
|
$this->assign['coverDeleteURL'] = url([ADMIN, 'blog', 'deleteCover', $id]);
|
|
$this->assign['editor'] = $this->settings('settings.editor');
|
|
$this->_addHeaderFiles();
|
|
|
|
if ($id === null) {
|
|
$blog = [
|
|
'id' => null,
|
|
'title' => '',
|
|
'content' => '',
|
|
'slug' => '',
|
|
'intro' => '',
|
|
'lang' => $this->settings('settings.lang_site'),
|
|
'user_id' => $this->core->getUserInfo('id'),
|
|
'comments' => 1,
|
|
'cover_photo' => null,
|
|
'status' => 0,
|
|
'markdown' => 0,
|
|
'tags' => '',
|
|
'published_at' => time(),
|
|
];
|
|
} else {
|
|
$blog = $this->db('blog')->where('id', $id)->oneArray();
|
|
}
|
|
|
|
if (!empty($blog)) {
|
|
$this->assign['langs'] = $this->_getLanguages($blog['lang'], 'selected');
|
|
$this->assign['form'] = htmlspecialchars_array($blog);
|
|
$this->assign['form']['content'] = $this->tpl->noParse($this->assign['form']['content']);
|
|
$this->assign['form']['date'] = date("Y-m-d\TH:i", $blog['published_at']);
|
|
|
|
$tags_array = $this->db('blog_tags')->leftJoin('blog_tags_relationship', 'blog_tags.id = blog_tags_relationship.tag_id')->where('blog_tags_relationship.blog_id', $blog['id'])->select(['blog_tags.name'])->toArray();
|
|
|
|
$this->assign['form']['tags'] = $tags_array;
|
|
$this->assign['users'] = $this->db('users')->toArray();
|
|
$this->assign['author'] = $this->core->getUserInfo('id', $blog['user_id'], true);
|
|
|
|
$this->assign['title'] = ($blog['id'] === null) ? $this->lang('new_post') : $this->lang('edit_post');
|
|
|
|
return $this->draw('form.html', ['blog' => $this->assign]);
|
|
} else {
|
|
redirect(url([ADMIN, 'blog', 'manage']));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Save post
|
|
*
|
|
* @param int $id
|
|
* @return void
|
|
*/
|
|
public function postSave($id = null)
|
|
{
|
|
unset($_POST['save'], $_POST['files']);
|
|
|
|
if (!empty($_POST['tags'])) {
|
|
$tags = array_unique($_POST['tags']);
|
|
} else {
|
|
$tags = [];
|
|
}
|
|
|
|
unset($_POST['tags']);
|
|
|
|
// redirect location
|
|
if (!$id) {
|
|
$location = url([ADMIN, 'blog', 'add']);
|
|
} else {
|
|
$location = url([ADMIN, 'blog', 'edit', $id]);
|
|
}
|
|
|
|
if (checkEmptyFields(['title', 'content'], $_POST)) {
|
|
$this->notify('failure', $this->lang('empty_inputs', 'general'));
|
|
$this->assign['form'] = htmlspecialchars_array($_POST);
|
|
$this->assign['form']['content'] = $this->tpl->noParse($this->assign['form']['content']);
|
|
redirect($location);
|
|
}
|
|
|
|
// slug
|
|
if (empty($_POST['slug'])) {
|
|
$_POST['slug'] = createSlug($_POST['title']);
|
|
} else {
|
|
$_POST['slug'] = createSlug($_POST['slug']);
|
|
}
|
|
|
|
// check slug and append with iterator
|
|
$oldSlug = $_POST['slug'];
|
|
$i = 2;
|
|
|
|
if ($id === null) {
|
|
$id = 0;
|
|
}
|
|
|
|
while ($this->db('blog')->where('slug', $_POST['slug'])->where('id', '!=', $id)->oneArray()) {
|
|
$_POST['slug'] = $oldSlug.'-'.($i++);
|
|
}
|
|
|
|
// format conversion date
|
|
$_POST['updated_at'] = strtotime(date('Y-m-d H:i:s'));
|
|
$_POST['published_at'] = strtotime($_POST['published_at']);
|
|
if (!isset($_POST['comments'])) {
|
|
$_POST['comments'] = 0;
|
|
}
|
|
if (!isset($_POST['markdown'])) {
|
|
$_POST['markdown'] = 0;
|
|
}
|
|
|
|
if (isset($_FILES['cover_photo']['tmp_name'])) {
|
|
$img = new \Inc\Core\Lib\Image;
|
|
|
|
if ($img->load($_FILES['cover_photo']['tmp_name'])) {
|
|
if ($img->getInfos('width') > 1000) {
|
|
$img->resize(1000);
|
|
} elseif ($img->getInfos('width') < 600) {
|
|
$img->resize(600);
|
|
}
|
|
|
|
$_POST['cover_photo'] = $_POST['slug'].".".$img->getInfos('type');
|
|
}
|
|
}
|
|
|
|
if (!$id) { // new
|
|
$_POST['created_at'] = strtotime(date('Y-m-d H:i:s'));
|
|
|
|
$query = $this->db('blog')->save($_POST);
|
|
$location = url([ADMIN, 'blog', 'edit', $this->db()->pdo()->lastInsertId()]);
|
|
} else { // edit
|
|
$query = $this->db('blog')->where('id', $id)->save($_POST);
|
|
}
|
|
|
|
// detach tags from post
|
|
if ($id) {
|
|
$this->db('blog_tags_relationship')->delete('blog_id', $id);
|
|
$blogId = $id;
|
|
} else {
|
|
$blogId = $id ? $id : $this->db()->pdo()->lastInsertId();
|
|
}
|
|
|
|
|
|
// Attach or create new tag
|
|
foreach ($tags as $tag) {
|
|
if (preg_match("/[`~!@#$%^&*()_|+\-=?;:\'\",.<>\{\}\[\]\\\/]+/", $tag)) {
|
|
continue;
|
|
}
|
|
|
|
$slug = createSlug($tag);
|
|
if ($e = $this->db('blog_tags')->like('slug', $slug)->oneArray()) {
|
|
$this->db('blog_tags_relationship')->save(['blog_id' => $blogId, 'tag_id' => $e['id']]);
|
|
} else {
|
|
$tagId = $this->db('blog_tags')->save(['name' => $tag, 'slug' => $slug]);
|
|
$this->db('blog_tags_relationship')->save(['blog_id' => $blogId, 'tag_id' => $tagId]);
|
|
}
|
|
}
|
|
|
|
if ($query) {
|
|
if (!file_exists(UPLOADS."/blog")) {
|
|
mkdir(UPLOADS."/blog", 0777, true);
|
|
}
|
|
|
|
if ($p = $img->getInfos('width')) {
|
|
$img->save(UPLOADS."/blog/".$_POST['cover_photo']);
|
|
}
|
|
|
|
$this->notify('success', $this->lang('save_success'));
|
|
} else {
|
|
$this->notify('failure', $this->lang('save_failure'));
|
|
}
|
|
|
|
redirect($location);
|
|
}
|
|
|
|
/**
|
|
* Remove post
|
|
*
|
|
* @param int $id
|
|
* @return void
|
|
*/
|
|
public function getDelete($id)
|
|
{
|
|
if ($post = $this->db('blog')->where('id', $id)->oneArray() && $this->db('blog')->delete($id)) {
|
|
if ($post['cover_photo']) {
|
|
unlink(UPLOADS."/blog/".$post['cover_photo']);
|
|
}
|
|
$this->notify('success', $this->lang('delete_success'));
|
|
} else {
|
|
$this->notify('failure', $this->lang('delete_failure'));
|
|
}
|
|
|
|
redirect(url([ADMIN, 'blog', 'manage']));
|
|
}
|
|
|
|
/**
|
|
* remove post cover
|
|
*/
|
|
public function getDeleteCover($id)
|
|
{
|
|
if ($post = $this->db('blog')->where('id', $id)->oneArray()) {
|
|
unlink(UPLOADS."/blog/".$post['cover_photo']);
|
|
$this->db('blog')->where('id', $id)->save(['cover_photo' => null]);
|
|
$this->notify('success', $this->lang('cover_deleted'));
|
|
|
|
redirect(url([ADMIN, 'blog', 'edit', $id]));
|
|
}
|
|
}
|
|
|
|
public function getSettings()
|
|
{
|
|
$assign = htmlspecialchars_array($this->settings('blog'));
|
|
$assign['dateformats'] = [
|
|
[
|
|
'value' => 'd-m-Y',
|
|
'name' => '01-01-2016'
|
|
],
|
|
[
|
|
'value' => 'd/m/Y',
|
|
'name' => '01/01/2016'
|
|
],
|
|
[
|
|
'value' => 'd Mx Y',
|
|
'name' => '01 '.$this->lang('janx').' 2016'
|
|
],
|
|
[
|
|
'value' => 'M d, Y',
|
|
'name' => $this->lang('jan').' 01, 2016'
|
|
],
|
|
[
|
|
'value' => 'd-m-Y H:i',
|
|
'name' => '01-01-2016 12:00'
|
|
],
|
|
[
|
|
'value' => 'd/m/Y H:i',
|
|
'name' => '01/01/2016 12:00'
|
|
],
|
|
[
|
|
'value' => 'd Mx Y, H:i',
|
|
'name' => '01 '.$this->lang('janx').' 2016, 12:00'
|
|
],
|
|
];
|
|
return $this->draw('settings.html', ['settings' => $assign]);
|
|
}
|
|
|
|
public function postSaveSettings()
|
|
{
|
|
foreach ($_POST['blog'] as $key => $val) {
|
|
$this->settings('blog', $key, $val);
|
|
}
|
|
$this->notify('success', $this->lang('settings_saved'));
|
|
redirect(url([ADMIN, 'blog', 'settings']));
|
|
}
|
|
|
|
/**
|
|
* image upload from WYSIWYG
|
|
*/
|
|
public function postEditorUpload()
|
|
{
|
|
header('Content-type: application/json');
|
|
$dir = UPLOADS.'/blog';
|
|
$error = null;
|
|
|
|
if (!file_exists($dir)) {
|
|
mkdir($dir, 0777, true);
|
|
}
|
|
|
|
if (isset($_FILES['file']['tmp_name'])) {
|
|
$img = new \Inc\Core\Lib\Image;
|
|
|
|
if ($img->load($_FILES['file']['tmp_name'])) {
|
|
$imgPath = $dir.'/'.time().'.'.$img->getInfos('type');
|
|
$img->save($imgPath);
|
|
echo json_encode(['status' => 'success', 'result' => url($imgPath)]);
|
|
} else {
|
|
$error = $this->lang('editor_upload_fail');
|
|
}
|
|
|
|
if ($error) {
|
|
echo json_encode(['status' => 'failure', 'result' => $error]);
|
|
}
|
|
}
|
|
exit();
|
|
}
|
|
|
|
/**
|
|
* module JavaScript
|
|
*/
|
|
public function getJavascript()
|
|
{
|
|
header('Content-type: text/javascript');
|
|
echo $this->draw(MODULES.'/blog/js/admin/blog.js');
|
|
exit();
|
|
}
|
|
|
|
public function getJsonTags($query = null)
|
|
{
|
|
header('Content-type: application/json');
|
|
|
|
if (!$query) {
|
|
exit(json_encode([]));
|
|
}
|
|
|
|
$query = urldecode($query);
|
|
$tags = $this->db('blog_tags')->like('name', $query.'%')->toArray();
|
|
|
|
if (array_search($query, array_column($tags, 'name')) === false) {
|
|
$tags[] = ['id' => 0, 'slug' => createSlug($query), 'name' => $query];
|
|
}
|
|
|
|
exit(json_encode($tags));
|
|
}
|
|
|
|
private function _addHeaderFiles()
|
|
{
|
|
// WYSIWYG
|
|
$this->core->addCSS(url('inc/jscripts/wysiwyg/summernote.min.css'));
|
|
$this->core->addJS(url('inc/jscripts/wysiwyg/summernote.min.js'));
|
|
|
|
if ($this->settings('settings.lang_admin') != 'en_english') {
|
|
$this->core->addJS(url('inc/jscripts/wysiwyg/lang/'.$this->settings('settings.lang_admin').'.js'));
|
|
}
|
|
|
|
// HTML & MARKDOWN EDITOR
|
|
$this->core->addCSS(url('/inc/jscripts/editor/markitup.min.css'));
|
|
$this->core->addCSS(url('/inc/jscripts/editor/markitup.highlight.min.css'));
|
|
$this->core->addCSS(url('/inc/jscripts/editor/sets/html/set.min.css'));
|
|
$this->core->addCSS(url('/inc/jscripts/editor/sets/markdown/set.min.css'));
|
|
$this->core->addJS(url('/inc/jscripts/editor/highlight.min.js'));
|
|
$this->core->addJS(url('/inc/jscripts/editor/markitup.min.js'));
|
|
$this->core->addJS(url('/inc/jscripts/editor/markitup.highlight.min.js'));
|
|
$this->core->addJS(url('/inc/jscripts/editor/sets/html/set.min.js'));
|
|
$this->core->addJS(url('/inc/jscripts/editor/sets/markdown/set.min.js'));
|
|
|
|
// ARE YOU SURE?
|
|
$this->core->addJS(url('inc/jscripts/are-you-sure.min.js'));
|
|
|
|
// MODULE SCRIPTS
|
|
$this->core->addJS(url([ADMIN, 'blog', 'javascript']));
|
|
|
|
// MODULE CSS
|
|
$this->core->addCSS(url(MODULES.'/blog/css/admin/blog.css'));
|
|
}
|
|
}
|