TineMCE refactoring

Unified all tinyMCE instances used across AAC, now they are initiated in one single file
+ added option to upload images within editor (CTRL-C CTRL-V)
+ there is new folder: user/, which will be used for all user generated data, like image uploads, guild images, etc.
This commit is contained in:
slawkens 2023-02-02 15:41:33 +01:00
parent 77460b0832
commit 9de8145f82
7 changed files with 133 additions and 85 deletions

3
.gitignore vendored
View File

@ -54,5 +54,8 @@ landing
# system
system/functions_custom.php
user/*
!user/index.html
# others/rest
system/pages/downloads.php

View File

@ -0,0 +1,53 @@
<?php
define('MYAAC_ADMIN', true);
require '../../common.php';
require SYSTEM . 'functions.php';
require SYSTEM . 'init.php';
require SYSTEM . 'login.php';
if(!admin())
die('Access denied.');
// Don't attempt to process the upload on an OPTIONS request
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
header('Access-Control-Allow-Methods: POST, OPTIONS');
return;
}
$imageFolder = USER . 'image_uploads/';
reset ($_FILES);
$temp = current($_FILES);
if (is_uploaded_file($temp['tmp_name'])) {
header('Access-Control-Allow-Credentials: true');
header('P3P: CP="There is no P3P policy."');
// Sanitize input
if (preg_match("/([^\w\s\d\-_~,;:\[\]\(\).])|([\.]{2,})/", $temp['name'])) {
header('HTTP/1.1 400 Invalid file name.');
return;
}
// Verify extension
$ext = strtolower(pathinfo($temp['name'], PATHINFO_EXTENSION));
if (!in_array($ext, ['gif', 'jpg', 'png'])) {
header('HTTP/1.1 400 Invalid extension.');
return;
}
do {
$randomName = generateRandomString(8). ".$ext";
$fileToWrite = $imageFolder . $randomName;
} while (file_exists($fileToWrite));
move_uploaded_file($temp['tmp_name'], $fileToWrite);
$returnPathToImage = BASE_URL . 'user/image_uploads/' . $randomName;
echo json_encode(['location' => $returnPathToImage]);
} else {
// Notify editor that the upload failed
header('HTTP/1.1 500 Server Error');
}

View File

@ -67,6 +67,7 @@ const PLUGINS = BASE . 'plugins/';
const TEMPLATES = BASE . 'templates/';
const TOOLS = BASE . 'tools/';
const VENDOR = BASE . 'vendor/';
const USER = BASE . 'user/';
// menu categories
const MENU_CATEGORY_NEWS = 1;
@ -99,7 +100,7 @@ $size = count($tmp) - 1;
for($i = 1; $i < $size; $i++)
$basedir .= '/' . $tmp[$i];
$basedir = str_replace(array('/admin', '/install'), '', $basedir);
$basedir = str_replace(['/admin', '/install', '/tools'], '', $basedir);
define('BASE_DIR', $basedir);
if(!IS_CLI) {

View File

@ -1,34 +1,28 @@
<script type="text/javascript" src="{{ constant('BASE_URL') }}tools/tinymce/tinymce.min.js"></script>
{{ include('tinymce.html.twig') }}
<script type="text/javascript">
tinymce.init({
selector: "textarea",
theme: "modern",
plugins: 'print preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template codesample table charmap hr pagebreak nonbreaking anchor toc insertdatetime advlist lists textcolor wordcount spellchecker imagetools contextmenu colorpicker textpattern help code emoticons',
toolbar1: 'formatselect | bold italic strikethrough forecolor backcolor | emoticons link | alignleft aligncenter alignright alignjustify | numlist bullist outdent indent | removeformat code',
image_advtab: true,
relative_urls: false,
remove_script_host: false,
document_base_url: "{{ constant('BASE_URL') }}"
});
tinymceInit();
</script>
<div align="center" class="text-center"><p class="note">Sending mails may take some time if there are many users in db.</p></div>
<div class="card card-info card-outline">
<div class="card-header">
<h5 class="m-0">Mailer</h5>
</div>
<form method="post">
<form id="form" method="post">
<div class="card-body">
<div class="form-group row">
<label for="mail_to">To: (enter email, or leave empty to all)</label>
<input class="form-control" type="text" id="mail_to" name="mail_to" value="{{ mail_to }}"/>
</div>
<div class="form-group row">
<label for="mail_subject">Subject:</label>
<input class="form-control" type="text" id="mail_subject" name="mail_subject" value="{{ mail_subject }}" maxlength="30"/>
</div>
<label for="editor" class="control-label">Content:</label>
<div class="form-group row">
<label for="mail_content" class="control-label">Content:</label>
<textarea id="mail_content" name="mail_content" style="width: 100%" class="tinymce">{{ mail_content }}</textarea>
<textarea id="editor" name="mail_content" style="width: 100%" class="tinymce">{{ mail_content }}</textarea>
</div>
</div>
<div class="card-footer">

View File

@ -3,7 +3,7 @@
<div class="card-header">
<h5 class="m-0">{% if action == 'edit' %}Edit{% else %}Add{% endif %} news</h5>
</div>
<form role="form" method="post" action="{{ news_link_form }}" id="news-edit-form">
<form id="form" role="form" method="post" action="{{ news_link_form }}">
<div class="card-body " id="page-edit-table">
{% if action == 'edit' %}
<input type="hidden" name="id" value="{{ news_id }}"/>
@ -14,9 +14,9 @@
<input type="text" id="title" name="title" class="form-control" autocomplete="off" style="cursor: auto;" value="{{ title }}">
</div>
<div class="form-group row">
<label for="body">Content</label>
<textarea class="form-control" id="body" name="body" maxlength="65000" cols="50" rows="5">{{ body|raw }}</textarea>
<label for="editor">Content</label>
<div class="form-group">
<textarea class="form-control" id="editor" name="body" maxlength="65000" cols="50" rows="5">{{ body|raw }}</textarea>
</div>
<div class="form-group row">
@ -116,44 +116,8 @@
</script>
{% endif %}
<script type="text/javascript" src="{{ constant('BASE_URL') }}tools/tinymce/tinymce.min.js"></script>
{{ include('tinymce.html.twig') }}
<script type="text/javascript">
let unsaved = false;
let lastContent = '';
tinymce.init({
selector: "#body",
theme: "modern",
plugins: 'preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template codesample table charmap hr pagebreak nonbreaking anchor toc insertdatetime advlist lists textcolor wordcount spellchecker imagetools contextmenu colorpicker textpattern help code emoticons',
toolbar1: 'formatselect | bold italic strikethrough forecolor backcolor | emoticons link | alignleft aligncenter alignright alignjustify | numlist bullist outdent indent | removeformat code',
image_advtab: true,
setup: function (ed) {
ed.on('NodeChange', function (e) {
if (ed.getContent() !== lastContent) {
unsaved = true;
}
});
}
});
$(document).ready(function () {
$(":input").change(function () { //triggers change in all input fields including text type
unsaved = true;
});
$("#news-edit-form").submit(function (event) {
unsaved = false;
});
lastContent = $("#body").val();
});
function unloadPage() {
if (unsaved) {
return "You have unsaved changes on this page. Do you want to leave this page and discard your changes or stay on this page?";
}
}
window.onbeforeunload = unloadPage;
tinymceInit();
</script>
{% endif %}

View File

@ -3,8 +3,7 @@
<div class="card-header">
<h5 class="m-0">{% if action == 'edit' %}Edit{% else %}Add{% endif %} page</h5>
</div>
<form class="form-horizontal" method="post"
action="?p=pages&action={% if action == 'edit' %}edit{% else %}add{% endif %}">
<form id="form" class="form-horizontal" method="post" action="?p=pages&action={% if action == 'edit' %}edit{% else %}add{% endif %}">
{% if action == 'edit' %}
<input type="hidden" name="id" value="{{ id }}"/>
{% endif %}
@ -41,65 +40,51 @@
{% if not php %}
<div class="form-group row">
<label for="enable_tinymce">Enable TinyMCE
<input type="checkbox" id="enable_tinymce" name="enable_tinymce"
title="Check if you want to use TinyMCE Editor"
value="1"{% if enable_tinymce %} checked{% endif %}{% if action == 'edit' %} disabled{% endif %}/>
<input type="checkbox" id="enable_tinymce" name="enable_tinymce" title="Check if you want to use TinyMCE Editor" value="1"{% if enable_tinymce %} checked{% endif %}{% if action == 'edit' %} disabled{% endif %}/>
{% if action == 'edit' %}
<input type="hidden" name="enable_tinymce" value="{% if enable_tinymce %}1{% else %}0{% endif %}"/>
{% endif %}
</label>
</div>
{% endif %}
<label for="editor">Content</label>
<div class="form-group row">
<label for="body">Content</label>
<textarea class="form-control" id="body" name="body" maxlength="65000" cols="50"
rows="10">{{ body|raw }}</textarea>
<textarea class="form-control" id="editor" name="body" maxlength="65000" cols="50" rows="10">{{ body|raw }}</textarea>
</div>
</div>
<div class="card-footer">
<button type="submit" class="btn btn-info"><i class="fas fa-update"></i> Update</button>
<button type="button" onclick="window.location = '{{ constant('ADMIN_URL') }}?p=pages';" class="btn btn-danger float-right"><i class="fas fa-cancel"></i> Cancel</button>
</div>
</form>
</div>
<script type="text/javascript" src="{{ constant('BASE_URL') }}tools/tinymce/tinymce.min.js"></script>
{{ include('tinymce.html.twig') }}
<script type="text/javascript">
$(function () {
$('#enable_tinymce').on('change', function (e) {
if (!this.checked) {
tinymce.remove('#body');
tinymce.remove('#editor');
} else {
if (tinymce.editors.length > 0) {
if (tinymce.get('#editor')!== null){
tinymce.activeEditor.show();
} else {
init_tinymce();
tinymceInit();
}
}
});
{% if not php and enable_tinymce %}
init_tinymce();
tinymceInit();
{% endif %}
function init_tinymce() {
tinymce.init({
selector: "#body",
theme: "modern",
plugins: 'code print preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template codesample table charmap hr pagebreak nonbreaking anchor toc insertdatetime advlist lists textcolor wordcount spellchecker imagetools contextmenu colorpicker textpattern help emoticons',
toolbar1: 'formatselect | bold italic strikethrough forecolor backcolor | emoticons link | alignleft aligncenter alignright alignjustify | numlist bullist outdent indent | removeformat code',
image_advtab: true,
relative_urls: false,
remove_script_host: false,
document_base_url: "{{ constant('BASE_URL') }}"
});
}
function decodeHtml(html) {
var txt = document.createElement("textarea");
txt.innerHTML = html;
return txt.value;
}
});
</script> {% endif %}
</script>
{% endif %}

View File

@ -0,0 +1,48 @@
<script type="text/javascript" src="{{ constant('BASE_URL') }}tools/js/tinymce/tinymce.min.js"></script>
<script type="text/javascript">
let unsaved = false;
let lastContent = '';
function tinymceInit() {
tinymce.init({
selector: "#editor",
theme: "silver",
plugins: 'preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template codesample table charmap pagebreak nonbreaking anchor insertdatetime advlist lists wordcount help code emoticons',
toolbar1: 'formatselect | bold italic strikethrough forecolor backcolor | emoticons link | alignleft aligncenter alignright alignjustify | numlist bullist outdent indent | removeformat code',
image_advtab: true,
images_upload_url: '{{ constant('BASE_URL') }}admin/tools/upload_image.php',
images_upload_credentials: true,
// not really sure - do we need those 3 options below?
//relative_urls: false,
//remove_script_host: false,
//document_base_url: "{{ constant('BASE_URL') }}"
setup: function (ed) {
ed.on('NodeChange', function (e) {
if (ed.getContent() !== lastContent) {
unsaved = true;
}
});
}
});
}
$(document).ready(function () {
$(":input").change(function () { //triggers change in all input fields including text type
unsaved = true;
});
$("#form").submit(function (event) {
unsaved = false;
});
lastContent = $("#editor").val();
});
function unloadPage() {
if (unsaved) {
return "You have unsaved changes on this page. Do you want to leave this page and discard your changes or stay on this page?";
}
}
window.onbeforeunload = unloadPage;
</script>