forked from projects/fipamo
page editing cleaned up, fixed date formatting, fixed page filtering, add Image API path
This commit is contained in:
parent
395850adb8
commit
1b9252fef0
14 changed files with 627 additions and 311 deletions
30
brain/api/v1/ImagesAPI.inc.php
Normal file
30
brain/api/v1/ImagesAPI.inc.php
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class ImagesAPI
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function uploadImage($request)
|
||||||
|
{
|
||||||
|
$image = $request->getUploadedFiles();
|
||||||
|
$path = date("Y") . "/" . date("m");
|
||||||
|
|
||||||
|
$uploadPath = "../public/assets/images/blog/" . $path;
|
||||||
|
|
||||||
|
FileUploader::uploadFile($uploadPath, $image["post_image"]);
|
||||||
|
|
||||||
|
$response = [
|
||||||
|
"message" => "Image Added. Very slick",
|
||||||
|
"type" => "postImageAdded",
|
||||||
|
"url" =>
|
||||||
|
"/assets/images/blog/" .
|
||||||
|
$path .
|
||||||
|
"/" .
|
||||||
|
$image["post_image"]->getClientFileName(),
|
||||||
|
];
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,7 @@
|
||||||
use Psr\Http\Message\ResponseInterface;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
|
||||||
//include "brain/data/Auth.inc.php";
|
include "../brain/api/v1/ImagesAPI.inc.php";
|
||||||
|
|
||||||
class APIControl
|
class APIControl
|
||||||
{
|
{
|
||||||
|
@ -18,7 +18,6 @@ class APIControl
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$response->getBody()->write(json_encode($result));
|
$response->getBody()->write(json_encode($result));
|
||||||
return $response->withHeader("Content-Type", "application/json");
|
return $response->withHeader("Content-Type", "application/json");
|
||||||
}
|
}
|
||||||
|
@ -43,6 +42,33 @@ class APIControl
|
||||||
break;
|
break;
|
||||||
case "logout":
|
case "logout":
|
||||||
$result = Auth::logout($body);
|
$result = Auth::logout($body);
|
||||||
|
break;
|
||||||
|
case "page":
|
||||||
|
//move methdology to its own API class
|
||||||
|
$task = $args["fourth"];
|
||||||
|
$token = $request->getHeader("fipamo-access-token");
|
||||||
|
if (Session::verifyToken($token[0])) {
|
||||||
|
switch ($task) {
|
||||||
|
case "delete":
|
||||||
|
case "add":
|
||||||
|
case "edit":
|
||||||
|
$result = (new Book("../content/pages"))->editPage(
|
||||||
|
$task,
|
||||||
|
$request
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "add-entry-image":
|
||||||
|
$result = ImagesAPI::uploadImage($request);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$result = [
|
||||||
|
"message" => "API access denied, homie",
|
||||||
|
"type" => "API_ERROR",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$result = [
|
$result = [
|
||||||
|
|
|
@ -18,7 +18,12 @@ class DashControl
|
||||||
switch (isset($args["second"]) ? $args["second"] : "index") {
|
switch (isset($args["second"]) ? $args["second"] : "index") {
|
||||||
case "pages":
|
case "pages":
|
||||||
$currentPage = isset($args["fourth"]) ? $args["fourth"] : 1;
|
$currentPage = isset($args["fourth"]) ? $args["fourth"] : 1;
|
||||||
$data = (new Book("../content/pages"))->getPages($currentPage, 4);
|
$filter = isset($args["third"]) ? $args["third"] : "all";
|
||||||
|
$data = (new Book("../content/pages"))->getPages(
|
||||||
|
$currentPage,
|
||||||
|
4,
|
||||||
|
$filter
|
||||||
|
);
|
||||||
$template = "dash/book.twig";
|
$template = "dash/book.twig";
|
||||||
$pageOptions = [
|
$pageOptions = [
|
||||||
"entryCount" => $data["entryCount"],
|
"entryCount" => $data["entryCount"],
|
||||||
|
|
|
@ -33,23 +33,157 @@ class Book
|
||||||
return $page;
|
return $page;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function editPage($task, $request)
|
||||||
|
{
|
||||||
|
$content = $this->getContents();
|
||||||
|
if ($task == "delete") {
|
||||||
|
$parsed = json_decode(file_get_contents("php://input"), true);
|
||||||
|
$body = find($content, ["uuid" => $parsed["id"]]);
|
||||||
|
} else {
|
||||||
|
$body = $request->getParsedBody();
|
||||||
|
}
|
||||||
|
|
||||||
|
$page = find($content, ["uuid" => $body["uuid"]]);
|
||||||
|
$image = $request->getUploadedFiles();
|
||||||
|
$member = Session::get("member");
|
||||||
|
|
||||||
|
if ($task != "add") {
|
||||||
|
$path =
|
||||||
|
date("Y", date($page["rawCreated"])) .
|
||||||
|
"/" .
|
||||||
|
date("m", date($page["rawCreated"]));
|
||||||
|
} else {
|
||||||
|
$path = date("Y", date()) . "/" . date("m");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($image["feature_image"])) {
|
||||||
|
$feature = $image["feature_image"]->getClientFileName();
|
||||||
|
FileUploader::uploadFile(
|
||||||
|
"../public/assets/images/blog/" . $path . "/",
|
||||||
|
$image["feature_image"]
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
if (isset($body["feature_image"])) {
|
||||||
|
$url = explode("/", $body["feature_image"]);
|
||||||
|
$feature =
|
||||||
|
"/" .
|
||||||
|
$url[3] .
|
||||||
|
"/" .
|
||||||
|
$url[4] .
|
||||||
|
"/" .
|
||||||
|
$url[5] .
|
||||||
|
"/" .
|
||||||
|
$url[6] .
|
||||||
|
"/" .
|
||||||
|
$url[7] .
|
||||||
|
"/" .
|
||||||
|
$url[8];
|
||||||
|
} else {
|
||||||
|
$feature = $body["feature"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($task == "delete") {
|
||||||
|
$deleted = "true";
|
||||||
|
$body["menu"] ? ($body["menu"] = "true") : ($body["menu"] = "false");
|
||||||
|
$body["published"]
|
||||||
|
? ($body["published"] = "true")
|
||||||
|
: ($body["published"] = "false");
|
||||||
|
$body["featured"]
|
||||||
|
? ($body["featured"] = "true")
|
||||||
|
: ($body["featured"] = "false");
|
||||||
|
} else {
|
||||||
|
$deleted = !$page["deleted"] ? "false" : $page["deleted"];
|
||||||
|
}
|
||||||
|
|
||||||
|
$created =
|
||||||
|
$task != "add"
|
||||||
|
? new \Moment\Moment($page["rawCreated"])
|
||||||
|
: new \Moment\Moment();
|
||||||
|
$updated = new \Moment\Moment();
|
||||||
|
|
||||||
|
$write =
|
||||||
|
"---\n" .
|
||||||
|
"id: " .
|
||||||
|
$body["id"] .
|
||||||
|
"\n" .
|
||||||
|
"uuid: " .
|
||||||
|
$body["uuid"] .
|
||||||
|
"\n" .
|
||||||
|
"title: " .
|
||||||
|
$body["title"] .
|
||||||
|
"\n" .
|
||||||
|
"feature: " .
|
||||||
|
$feature .
|
||||||
|
"\n" .
|
||||||
|
"path: " .
|
||||||
|
$path .
|
||||||
|
"\n" .
|
||||||
|
"layout: " .
|
||||||
|
$body["layout"] .
|
||||||
|
"\n" .
|
||||||
|
"tags: " .
|
||||||
|
$body["tags"] .
|
||||||
|
"\n" .
|
||||||
|
"author: " .
|
||||||
|
$member["handle"] .
|
||||||
|
"\n" .
|
||||||
|
"created: " .
|
||||||
|
$created->format("Y-m-d\TH:i:sP") .
|
||||||
|
"\n" .
|
||||||
|
"updated: " .
|
||||||
|
$updated->format("Y-m-d\TH:i:sP") .
|
||||||
|
"\n" .
|
||||||
|
"deleted: " .
|
||||||
|
$deleted .
|
||||||
|
"\n" .
|
||||||
|
"slug: " .
|
||||||
|
$body["slug"] .
|
||||||
|
"\n" .
|
||||||
|
"menu: " .
|
||||||
|
$body["menu"] .
|
||||||
|
"\n" .
|
||||||
|
"published: " .
|
||||||
|
$body["published"] .
|
||||||
|
"\n" .
|
||||||
|
"featured: " .
|
||||||
|
$body["featured"] .
|
||||||
|
"\n---\n" .
|
||||||
|
$body["content"];
|
||||||
|
|
||||||
|
// if layout is index, change path to file
|
||||||
|
|
||||||
|
if ($body["layout"] == "index") {
|
||||||
|
$writePath = "../content/start/index.md";
|
||||||
|
} else {
|
||||||
|
$writePath = "../content/pages/" . $path . "/" . $body["slug"] . ".md";
|
||||||
|
}
|
||||||
|
|
||||||
|
($new = fopen($writePath, "w")) or die("Unable to open file!");
|
||||||
|
fwrite($new, $write);
|
||||||
|
fclose($new);
|
||||||
|
|
||||||
|
$response = [
|
||||||
|
"message" => "File edited. Nice work",
|
||||||
|
"type" => $task == "write" ? "postUpdated" : "postAdded",
|
||||||
|
];
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
public function getPages(int $page, int $limit, string $sort = null)
|
public function getPages(int $page, int $limit, string $sort = null)
|
||||||
{
|
{
|
||||||
$content = $this->getContents();
|
$content = $this->getContents();
|
||||||
|
|
||||||
$published = filter($content, function ($item) {
|
$published = filter($content, function ($item) {
|
||||||
return $item["published"] == "true";
|
return $item["published"] == true && $item["deleted"] == false;
|
||||||
});
|
});
|
||||||
$deleted = filter($content, function ($item) {
|
$deleted = filter($content, function ($item) {
|
||||||
return $item["deleted"];
|
return $item["deleted"] == true;
|
||||||
});
|
});
|
||||||
|
|
||||||
$all = $content;
|
$all = $content;
|
||||||
|
|
||||||
$filter = isset($sort) ? $sort : "all";
|
$filter = isset($sort) ? $sort : "all";
|
||||||
|
|
||||||
//echo $filter;
|
|
||||||
$filtered = [];
|
|
||||||
switch ($filter) {
|
switch ($filter) {
|
||||||
case "published":
|
case "published":
|
||||||
$filtered = $published;
|
$filtered = $published;
|
||||||
|
@ -61,9 +195,7 @@ class Book
|
||||||
$filtered = $content;
|
$filtered = $content;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$numOfPages = ceil(count($filtered) / $limit);
|
$numOfPages = ceil(count($filtered) / $limit);
|
||||||
|
|
||||||
$folder = [];
|
$folder = [];
|
||||||
|
|
||||||
if (count($filtered) != 0) {
|
if (count($filtered) != 0) {
|
||||||
|
@ -99,7 +231,7 @@ class Book
|
||||||
"numOfPages" => $numOfPages,
|
"numOfPages" => $numOfPages,
|
||||||
"entryCount" => count($filtered),
|
"entryCount" => count($filtered),
|
||||||
"paginate" => [
|
"paginate" => [
|
||||||
"sort" => $filter,
|
"sort" => $sort,
|
||||||
"nextPage" => $next,
|
"nextPage" => $next,
|
||||||
"prevPage" => $prev,
|
"prevPage" => $prev,
|
||||||
],
|
],
|
||||||
|
@ -116,7 +248,6 @@ class Book
|
||||||
$contents = [];
|
$contents = [];
|
||||||
foreach ($this->files as $file) {
|
foreach ($this->files as $file) {
|
||||||
$doc = $parser->parse(file_get_contents($file), false);
|
$doc = $parser->parse(file_get_contents($file), false);
|
||||||
|
|
||||||
$meta = $doc->getYAML();
|
$meta = $doc->getYAML();
|
||||||
$page = [
|
$page = [
|
||||||
"id" => $meta["id"],
|
"id" => $meta["id"],
|
||||||
|
@ -129,6 +260,8 @@ class Book
|
||||||
"author" => $meta["author"],
|
"author" => $meta["author"],
|
||||||
"created" => date("Y M D d", $meta["created"]),
|
"created" => date("Y M D d", $meta["created"]),
|
||||||
"updated" => date("Y M D d", $meta["updated"]),
|
"updated" => date("Y M D d", $meta["updated"]),
|
||||||
|
"rawCreated" => $meta["created"],
|
||||||
|
"rawUpdated" => $meta["updated"],
|
||||||
"deleted" => $meta["deleted"],
|
"deleted" => $meta["deleted"],
|
||||||
"menu" => $meta["menu"],
|
"menu" => $meta["menu"],
|
||||||
"featured" => $meta["featured"],
|
"featured" => $meta["featured"],
|
||||||
|
@ -137,7 +270,6 @@ class Book
|
||||||
"filePath" => $file,
|
"filePath" => $file,
|
||||||
"content" => $doc->getContent(),
|
"content" => $doc->getContent(),
|
||||||
];
|
];
|
||||||
|
|
||||||
//checks for duplicates
|
//checks for duplicates
|
||||||
$uuid = $meta["uuid"];
|
$uuid = $meta["uuid"];
|
||||||
$found = current(
|
$found = current(
|
||||||
|
|
|
@ -38,6 +38,24 @@ class Session
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function verifyToken($token)
|
||||||
|
{
|
||||||
|
$data = json_decode(file_get_contents(self::$file), true);
|
||||||
|
if ($data["member"] != null) {
|
||||||
|
$secret = (new Settings())->getFolks("secret");
|
||||||
|
if (
|
||||||
|
Token::validate($token, $secret) &&
|
||||||
|
Token::validateExpiration($token, $secret)
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static function set($key, $value)
|
public static function set($key, $value)
|
||||||
{
|
{
|
||||||
$data = json_decode(file_get_contents(self::$file), true);
|
$data = json_decode(file_get_contents(self::$file), true);
|
||||||
|
|
29
brain/utility/FileUploader.inc.php
Normal file
29
brain/utility/FileUploader.inc.php
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<?php
|
||||||
|
use Psr\Http\Message\UploadedFileInterface;
|
||||||
|
//include "brain/data/Auth.inc.php";
|
||||||
|
|
||||||
|
class FileUploader
|
||||||
|
{
|
||||||
|
public static function uploadFile(
|
||||||
|
string $directory,
|
||||||
|
UploadedFileInterface $file
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
if (!is_dir($directory)) {
|
||||||
|
//Directory does not exist, so lets create it.
|
||||||
|
mkdir($directory, 0755, true);
|
||||||
|
}
|
||||||
|
//$upload = move_uploaded_file($file->getClientFileName(), $directory);
|
||||||
|
//$extension = pathinfo($file->getClientFilename(), PATHINFO_EXTENSION);
|
||||||
|
|
||||||
|
// see http://php.net/manual/en/function.random-bytes.php
|
||||||
|
//$basename = bin2hex(random_bytes(8));
|
||||||
|
//$filename = sprintf("%s.%0.8s", $basename, $extension);
|
||||||
|
|
||||||
|
$file->moveTo($directory . "/" . $file->getClientFileName());
|
||||||
|
} catch (Error $e) {
|
||||||
|
echo "failed to upload image: " . $e->getMessage();
|
||||||
|
throw new Error("Failed to upload image file");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,7 @@
|
||||||
{% set id = page['id'] %}
|
{% set id = page['id'] %}
|
||||||
{% set uuid = page['uuid'] %}
|
{% set uuid = page['uuid'] %}
|
||||||
{% set slug = page['slug'] %}
|
{% set slug = page['slug'] %}
|
||||||
|
{% set layout = page['layout'] %}
|
||||||
{% set feature = page['feature'] %}
|
{% set feature = page['feature'] %}
|
||||||
{% set _title = page['title'] %}
|
{% set _title = page['title'] %}
|
||||||
{% set tags = page['tags'] %}
|
{% set tags = page['tags'] %}
|
||||||
|
@ -16,6 +17,7 @@
|
||||||
{% set id = '' %}
|
{% set id = '' %}
|
||||||
{% set uuid = '' %}
|
{% set uuid = '' %}
|
||||||
{% set slug = '' %}
|
{% set slug = '' %}
|
||||||
|
{% set layout = 'pages' %}
|
||||||
{% set feature = '' %}
|
{% set feature = '' %}
|
||||||
{% set title = '' %}
|
{% set title = '' %}
|
||||||
{% set tags = '' %}
|
{% set tags = '' %}
|
||||||
|
@ -32,7 +34,7 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block mainContent %}
|
{% block mainContent %}
|
||||||
<div id="post-edit-index" data-index="{{ id }}" data-uuid="{{ uuid }}" data-slug="{{ slug }}">
|
<div id="post-edit-index" data-index="{{ id }}" data-uuid="{{ uuid }}" data-slug="{{ slug }}" data-layout="{{ layout }}">
|
||||||
<div id="post-edit-index-wrapper">
|
<div id="post-edit-index-wrapper">
|
||||||
<div id="post-feature">
|
<div id="post-feature">
|
||||||
{% if page['feature'] == null %}
|
{% if page['feature'] == null %}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
"slim/twig-view": "^3.0",
|
"slim/twig-view": "^3.0",
|
||||||
"mnapoli/front-yaml": "^1.8",
|
"mnapoli/front-yaml": "^1.8",
|
||||||
"lodash-php/lodash-php": "^0.0.7",
|
"lodash-php/lodash-php": "^0.0.7",
|
||||||
"rbdwllr/reallysimplejwt": "^4.0"
|
"rbdwllr/reallysimplejwt": "^4.0",
|
||||||
|
"fightbulc/moment": "^1.33"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
59
composer.lock
generated
59
composer.lock
generated
|
@ -4,7 +4,7 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "0e243f32e05cb4ef6265ce19f141fdae",
|
"content-hash": "d5ef6d43f774049d093af6375d20ac11",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "erusev/parsedown",
|
"name": "erusev/parsedown",
|
||||||
|
@ -112,6 +112,63 @@
|
||||||
},
|
},
|
||||||
"time": "2020-11-24T22:02:12+00:00"
|
"time": "2020-11-24T22:02:12+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "fightbulc/moment",
|
||||||
|
"version": "1.33.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/fightbulc/moment.php.git",
|
||||||
|
"reference": "435d68e481ab0a716358926fb51966e696d297e3"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/fightbulc/moment.php/zipball/435d68e481ab0a716358926fb51966e696d297e3",
|
||||||
|
"reference": "435d68e481ab0a716358926fb51966e696d297e3",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^4.8.36 || ^5.5 || ^6.5 || ^7.5 || ^9.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Moment\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Tino Ehrich",
|
||||||
|
"email": "tino@bigpun.me",
|
||||||
|
"role": "developer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Parse, validate, manipulate, and display dates in PHP w/ i18n support. Inspired by moment.js",
|
||||||
|
"keywords": [
|
||||||
|
"date",
|
||||||
|
"display",
|
||||||
|
"format",
|
||||||
|
"i18n",
|
||||||
|
"locale",
|
||||||
|
"manipulate",
|
||||||
|
"moment",
|
||||||
|
"parse",
|
||||||
|
"time",
|
||||||
|
"translation",
|
||||||
|
"validate"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/fightbulc/moment.php/issues",
|
||||||
|
"source": "https://github.com/fightbulc/moment.php/tree/1.33.0"
|
||||||
|
},
|
||||||
|
"time": "2021-03-27T13:10:08+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "lodash-php/lodash-php",
|
"name": "lodash-php/lodash-php",
|
||||||
"version": "0.0.7",
|
"version": "0.0.7",
|
||||||
|
|
|
@ -11,13 +11,14 @@ include "../brain/controller/RouteControl.inc.php";
|
||||||
include "../brain/data/Auth.inc.php";
|
include "../brain/data/Auth.inc.php";
|
||||||
include "../brain/utility/StringTools.inc.php";
|
include "../brain/utility/StringTools.inc.php";
|
||||||
include "../brain/data/Session.inc.php";
|
include "../brain/data/Session.inc.php";
|
||||||
|
include "../brain/utility/FileUploader.inc.php";
|
||||||
|
|
||||||
$app = AppFactory::create();
|
$app = AppFactory::create();
|
||||||
$twig = Twig::create("../brain/views/");
|
$twig = Twig::create("../brain/views/");
|
||||||
$app->add(TwigMiddleware::create($app, $twig));
|
$app->add(TwigMiddleware::create($app, $twig));
|
||||||
//set up routing
|
//set up routing
|
||||||
$app->get("/[{first}[/{second}[/{third}[/{fourth}]]]]", "\RouteControl:get");
|
$app->get("/[{first}[/{second}[/{third}[/{fourth}]]]]", "\RouteControl:get");
|
||||||
$app->post("/[{first}[/{second}[/{third}[/{fourt}]]]]", "\RouteControl:post");
|
$app->post("/[{first}[/{second}[/{third}[/{fourth}]]]]", "\RouteControl:post");
|
||||||
//start the app
|
//start the app
|
||||||
|
|
||||||
$app->run();
|
$app->run();
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
import PostIndex from './PostIndex';
|
import PostIndex from "./PostIndex";
|
||||||
import SettingsIndex from './SettingsIndex';
|
import SettingsIndex from "./SettingsIndex";
|
||||||
import NaviIndex from './NavIndex';
|
import NaviIndex from "./NavIndex";
|
||||||
|
|
||||||
export default class DashManager {
|
export default class DashManager {
|
||||||
//--------------------------
|
//--------------------------
|
||||||
// constructor
|
// constructor
|
||||||
//--------------------------
|
//--------------------------
|
||||||
constructor() {
|
constructor() {
|
||||||
this.currentDisplay = '';
|
this.currentDisplay = "";
|
||||||
this.urlPieces = document.URL.split('/');
|
this.urlPieces = document.URL.split("/");
|
||||||
this.chooseDisplay(this.urlPieces[5], this.urlPieces[6]);
|
this.chooseDisplay(this.urlPieces[4], this.urlPieces[5]);
|
||||||
}
|
}
|
||||||
//--------------------------
|
//--------------------------
|
||||||
// methods
|
// methods
|
||||||
|
@ -17,15 +17,15 @@ export default class DashManager {
|
||||||
start() {}
|
start() {}
|
||||||
|
|
||||||
chooseDisplay(section, page) {
|
chooseDisplay(section, page) {
|
||||||
this.currentDisplay = '';
|
this.currentDisplay = "";
|
||||||
switch (section) {
|
switch (section) {
|
||||||
case 'page':
|
case "page":
|
||||||
this.currentDisplay = new PostIndex(page);
|
this.currentDisplay = new PostIndex(page);
|
||||||
break;
|
break;
|
||||||
case 'settings':
|
case "settings":
|
||||||
this.currentDisplay = new SettingsIndex();
|
this.currentDisplay = new SettingsIndex();
|
||||||
break;
|
break;
|
||||||
case 'navigation':
|
case "navigation":
|
||||||
this.currentDisplay = new NaviIndex();
|
this.currentDisplay = new NaviIndex();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -2,14 +2,14 @@
|
||||||
import FipamoAdminAPI, {
|
import FipamoAdminAPI, {
|
||||||
TASK_PAGE_CREATE,
|
TASK_PAGE_CREATE,
|
||||||
TASK_PAGE_EDIT,
|
TASK_PAGE_EDIT,
|
||||||
TASK_PAGE_DELETE
|
TASK_PAGE_DELETE,
|
||||||
} from '../../libraries/FipamoAdminAPI';
|
} from "../../libraries/FipamoAdminAPI";
|
||||||
import * as DataEvent from '../events/DataEvent';
|
import * as DataEvent from "../events/DataEvent";
|
||||||
import PageActions from '../actions/PageActions';
|
import PageActions from "../actions/PageActions";
|
||||||
import * as EditorEvent from '../events/EditorEvent';
|
import * as EditorEvent from "../events/EditorEvent";
|
||||||
//import TinyDatePicker from 'tiny-date-picker';
|
//import TinyDatePicker from 'tiny-date-picker';
|
||||||
import TextEditor from '../ui/TextEditor';
|
import TextEditor from "../ui/TextEditor";
|
||||||
import Notfications from '../ui/Notifications';
|
import Notfications from "../ui/Notifications";
|
||||||
const admin = new FipamoAdminAPI();
|
const admin = new FipamoAdminAPI();
|
||||||
const notify = new Notfications();
|
const notify = new Notfications();
|
||||||
export default class PostEditor {
|
export default class PostEditor {
|
||||||
|
@ -18,24 +18,28 @@ export default class PostEditor {
|
||||||
//--------------------------
|
//--------------------------
|
||||||
constructor() {
|
constructor() {
|
||||||
let self = this;
|
let self = this;
|
||||||
this.urlPieces = document.URL.split('/');
|
this.urlPieces = document.URL.split("/");
|
||||||
this.post = [];
|
this.post = [];
|
||||||
this.postID = null;
|
this.postID = null;
|
||||||
this.postUUID = null;
|
this.postUUID = null;
|
||||||
this.postLayout = null;
|
this.postLayout = null;
|
||||||
if (document.getElementById('post-edit-index').getAttribute('data-index')) {
|
if (document.getElementById("post-edit-index").getAttribute("data-index")) {
|
||||||
this.postID = document.getElementById('post-edit-index').getAttribute('data-index');
|
this.postID = document
|
||||||
this.postUUID = document.getElementById('post-edit-index').getAttribute('data-uuid');
|
.getElementById("post-edit-index")
|
||||||
|
.getAttribute("data-index");
|
||||||
|
this.postUUID = document
|
||||||
|
.getElementById("post-edit-index")
|
||||||
|
.getAttribute("data-uuid");
|
||||||
this.postLayout = document
|
this.postLayout = document
|
||||||
.getElementById('post-edit-index')
|
.getElementById("post-edit-index")
|
||||||
.getAttribute('data-layout');
|
.getAttribute("data-layout");
|
||||||
}
|
}
|
||||||
if (document.getElementById('edit-post-text')) {
|
if (document.getElementById("edit-post-text")) {
|
||||||
this.editor = new TextEditor(
|
this.editor = new TextEditor(
|
||||||
document.getElementById('edit-post-text'),
|
document.getElementById("edit-post-text"),
|
||||||
document.getElementById('header').offsetHeight +
|
document.getElementById("header").offsetHeight +
|
||||||
document.getElementById('post-header').offsetHeight +
|
document.getElementById("post-header").offsetHeight +
|
||||||
document.getElementById('post-feature').offsetHeight
|
document.getElementById("post-feature").offsetHeight
|
||||||
);
|
);
|
||||||
this.editor.addListener(
|
this.editor.addListener(
|
||||||
EditorEvent.EDITOR_DELETE,
|
EditorEvent.EDITOR_DELETE,
|
||||||
|
@ -57,9 +61,9 @@ export default class PostEditor {
|
||||||
() => this.handleEditorOptions(EditorEvent.EDITOR_SAVE),
|
() => this.handleEditorOptions(EditorEvent.EDITOR_SAVE),
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
document.getElementById('post-image-upload').addEventListener(
|
document.getElementById("post-image-upload").addEventListener(
|
||||||
'change',
|
"change",
|
||||||
e => {
|
(e) => {
|
||||||
self.handleImageUpload(e.target.id, e.target.files);
|
self.handleImageUpload(e.target.id, e.target.files);
|
||||||
},
|
},
|
||||||
false
|
false
|
||||||
|
@ -80,24 +84,30 @@ export default class PostEditor {
|
||||||
// methods
|
// methods
|
||||||
//--------------------------
|
//--------------------------
|
||||||
start() {
|
start() {
|
||||||
if (document.getElementById('featured-image-drop')) {
|
if (document.getElementById("featured-image-drop")) {
|
||||||
document
|
document
|
||||||
.getElementById('featured-image-drop')
|
.getElementById("featured-image-drop")
|
||||||
.addEventListener('dragover', this.handleImageActions, false);
|
.addEventListener("dragover", this.handleImageActions, false);
|
||||||
document
|
document
|
||||||
.getElementById('featured-image-drop')
|
.getElementById("featured-image-drop")
|
||||||
.addEventListener('drop', this.handleImageActions, false);
|
.addEventListener("drop", this.handleImageActions, false);
|
||||||
document
|
document
|
||||||
.getElementById('featured-image-upload')
|
.getElementById("featured-image-upload")
|
||||||
.addEventListener('change', e => this.handleImageActions(e), false);
|
.addEventListener("change", (e) => this.handleImageActions(e), false);
|
||||||
if (document.getElementById('new-feature-upload')) {
|
if (document.getElementById("new-feature-upload")) {
|
||||||
document.getElementById('new-feature-upload').addEventListener('click', () => {
|
document
|
||||||
document.getElementById('featured-image-upload').click();
|
.getElementById("new-feature-upload")
|
||||||
|
.addEventListener("click", () => {
|
||||||
|
document.getElementById("featured-image-upload").click();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
var optionButtons = document.querySelectorAll('.post-option-btn');
|
var optionButtons = document.querySelectorAll(".post-option-btn");
|
||||||
for (var i = 0, length = optionButtons.length; i < length; i++) {
|
for (var i = 0, length = optionButtons.length; i < length; i++) {
|
||||||
optionButtons[i].addEventListener('click', e => this.handlePostOptions(e), false);
|
optionButtons[i].addEventListener(
|
||||||
|
"click",
|
||||||
|
(e) => this.handlePostOptions(e),
|
||||||
|
false
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -107,37 +117,41 @@ export default class PostEditor {
|
||||||
handlePostOptions(e) {
|
handlePostOptions(e) {
|
||||||
let currentOption;
|
let currentOption;
|
||||||
switch (e.target.id) {
|
switch (e.target.id) {
|
||||||
case 'option-page-icon':
|
case "option-page-icon":
|
||||||
case 'option-menu-pin':
|
case "option-menu-pin":
|
||||||
currentOption = document.getElementById('option-menu-pin');
|
currentOption = document.getElementById("option-menu-pin");
|
||||||
break;
|
break;
|
||||||
case 'option-feature-icon':
|
case "option-feature-icon":
|
||||||
case 'option-feature':
|
case "option-feature":
|
||||||
currentOption = document.getElementById('option-feature');
|
currentOption = document.getElementById("option-feature");
|
||||||
break;
|
break;
|
||||||
case 'option-published-icon':
|
case "option-published-icon":
|
||||||
case 'option-published':
|
case "option-published":
|
||||||
currentOption = document.getElementById('option-published');
|
currentOption = document.getElementById("option-published");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let active = currentOption.getAttribute('data-active');
|
let active = currentOption.getAttribute("data-active");
|
||||||
active == 'false'
|
active == "false"
|
||||||
? currentOption.setAttribute('data-active', 'true')
|
? currentOption.setAttribute("data-active", "true")
|
||||||
: currentOption.setAttribute('data-active', 'false');
|
: currentOption.setAttribute("data-active", "false");
|
||||||
}
|
}
|
||||||
handleEditorOptions(e) {
|
handleEditorOptions(e) {
|
||||||
switch (e) {
|
switch (e) {
|
||||||
case EditorEvent.EDITOR_SAVE:
|
case EditorEvent.EDITOR_SAVE:
|
||||||
case EditorEvent.EDITOR_UPDATE:
|
case EditorEvent.EDITOR_UPDATE:
|
||||||
var task = '';
|
var task = "";
|
||||||
e === EditorEvent.EDITOR_SAVE ? (task = TASK_PAGE_CREATE) : (task = TASK_PAGE_EDIT);
|
e === EditorEvent.EDITOR_SAVE
|
||||||
|
? (task = TASK_PAGE_CREATE)
|
||||||
|
: (task = TASK_PAGE_EDIT);
|
||||||
new PageActions()
|
new PageActions()
|
||||||
.collectInfo(document.getElementById('featured-image-upload').files[0])
|
.collectInfo(
|
||||||
.then(page => {
|
document.getElementById("featured-image-upload").files[0]
|
||||||
notify.alert('Writing down changes', null);
|
)
|
||||||
|
.then((page) => {
|
||||||
|
notify.alert("Writing down changes", null);
|
||||||
admin
|
admin
|
||||||
.pageActions(task, page)
|
.pageActions(task, page)
|
||||||
.then(r => {
|
.then((r) => {
|
||||||
if (
|
if (
|
||||||
r.type === DataEvent.PAGE_ERROR ||
|
r.type === DataEvent.PAGE_ERROR ||
|
||||||
r.type === DataEvent.API_REQUEST_LAME
|
r.type === DataEvent.API_REQUEST_LAME
|
||||||
|
@ -148,18 +162,18 @@ export default class PostEditor {
|
||||||
notify.alert(r.message, true);
|
notify.alert(r.message, true);
|
||||||
} else {
|
} else {
|
||||||
notify.alert(r.message, true);
|
notify.alert(r.message, true);
|
||||||
window.location = '/@/dashboard/page/edit/' + r.id;
|
window.location = "/@/dashboard/page/edit/" + r.id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch((err) => {
|
||||||
notify.alert(err, false);
|
notify.alert(err, false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case EditorEvent.EDITOR_DELETE:
|
case EditorEvent.EDITOR_DELETE:
|
||||||
if (this.postLayout === 'index') {
|
if (this.postLayout === "index") {
|
||||||
notify.alert('Index cannot be deleted', false);
|
notify.alert("Index cannot be deleted", false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (confirm("AYE! You know you're deleting this post, right?")) {
|
if (confirm("AYE! You know you're deleting this post, right?")) {
|
||||||
|
@ -167,9 +181,9 @@ export default class PostEditor {
|
||||||
admin
|
admin
|
||||||
.pageActions(TASK_PAGE_DELETE, id)
|
.pageActions(TASK_PAGE_DELETE, id)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
window.location = '/@/dashboard/page/list/';
|
window.location = "/dashboard/pages";
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch((err) => {
|
||||||
notify.alert(err, false);
|
notify.alert(err, false);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -177,7 +191,7 @@ export default class PostEditor {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EditorEvent.EDITOR_UPLOAD_POST_IMAGE:
|
case EditorEvent.EDITOR_UPLOAD_POST_IMAGE:
|
||||||
document.getElementById('post-image-upload').click();
|
document.getElementById("post-image-upload").click();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -185,17 +199,17 @@ export default class PostEditor {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
switch (e.type) {
|
switch (e.type) {
|
||||||
case 'dragover':
|
case "dragover":
|
||||||
e.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.
|
e.dataTransfer.dropEffect = "copy"; // Explicitly show this is a copy.
|
||||||
break;
|
break;
|
||||||
case 'change':
|
case "change":
|
||||||
case 'drop':
|
case "drop":
|
||||||
e.type == 'drop'
|
e.type == "drop"
|
||||||
? (PostEditor.uploadFiles = e.dataTransfer.files)
|
? (PostEditor.uploadFiles = e.dataTransfer.files)
|
||||||
: (PostEditor.uploadFiles = e.target.files);
|
: (PostEditor.uploadFiles = e.target.files);
|
||||||
for (var i = 0, f; (f = PostEditor.uploadFiles[i]); i++) {
|
for (var i = 0, f; (f = PostEditor.uploadFiles[i]); i++) {
|
||||||
// Only process image files.
|
// Only process image files.
|
||||||
if (!f.type.match('image.*')) {
|
if (!f.type.match("image.*")) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
var reader = new FileReader();
|
var reader = new FileReader();
|
||||||
|
@ -203,19 +217,19 @@ export default class PostEditor {
|
||||||
reader.onload = (function (theFile) {
|
reader.onload = (function (theFile) {
|
||||||
return function (f) {
|
return function (f) {
|
||||||
// Render thumbnail.
|
// Render thumbnail.
|
||||||
var image = document.createElement('img');
|
var image = document.createElement("img");
|
||||||
image.src = f.target.result;
|
image.src = f.target.result;
|
||||||
image.title = escape(theFile.name);
|
image.title = escape(theFile.name);
|
||||||
var span = document.createElement('div');
|
var span = document.createElement("div");
|
||||||
span.innerHTML = [
|
span.innerHTML = [
|
||||||
'<img src="',
|
'<img src="',
|
||||||
f.target.result,
|
f.target.result,
|
||||||
'" title="',
|
'" title="',
|
||||||
escape(theFile.name),
|
escape(theFile.name),
|
||||||
'"/>'
|
'"/>',
|
||||||
].join('');
|
].join("");
|
||||||
document.getElementById('featured-image-drop').innerHTML = '';
|
document.getElementById("featured-image-drop").innerHTML = "";
|
||||||
document.getElementById('featured-image-drop').appendChild(image);
|
document.getElementById("featured-image-drop").appendChild(image);
|
||||||
};
|
};
|
||||||
})(f);
|
})(f);
|
||||||
// Read in the image file as a data URL.
|
// Read in the image file as a data URL.
|
||||||
|
@ -225,16 +239,16 @@ export default class PostEditor {
|
||||||
}
|
}
|
||||||
handleImageUpload(type, files) {
|
handleImageUpload(type, files) {
|
||||||
let self = this;
|
let self = this;
|
||||||
notify.alert('Uploading Image', null);
|
notify.alert("Uploading Image", null);
|
||||||
admin
|
admin
|
||||||
.imageUpload(type, files)
|
.imageUpload(type, files)
|
||||||
.then(r => {
|
.then((r) => {
|
||||||
if (r.type == DataEvent.POST_IMAGE_ADDED)
|
if (r.type == DataEvent.POST_IMAGE_ADDED)
|
||||||
self.editor.notify(EditorEvent.EDITOR_UPLOAD_POST_IMAGE, r.url);
|
self.editor.notify(EditorEvent.EDITOR_UPLOAD_POST_IMAGE, r.url);
|
||||||
notify.alert('Image Added to Entry', true);
|
notify.alert("Image Added to Entry", true);
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
notify.alert('Uh oh. Image not added', false);
|
notify.alert("Uh oh. Image not added", false);
|
||||||
//console.log('ERROR', err);
|
//console.log('ERROR', err);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import PageEditor from './PageEditor';
|
import PageEditor from "./PageEditor";
|
||||||
export default class PostIndex {
|
export default class PostIndex {
|
||||||
//--------------------------
|
//--------------------------
|
||||||
// constructor
|
// constructor
|
||||||
|
@ -13,10 +13,10 @@ export default class PostIndex {
|
||||||
//--------------------------
|
//--------------------------
|
||||||
start() {}
|
start() {}
|
||||||
choosePage(page) {
|
choosePage(page) {
|
||||||
this.currentPage = '';
|
this.currentPage = "";
|
||||||
switch (page) {
|
switch (page) {
|
||||||
case 'edit':
|
case "edit":
|
||||||
case 'add':
|
case "add":
|
||||||
this.currentPage = new PageEditor();
|
this.currentPage = new PageEditor();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -9,10 +9,10 @@ export const CONTENT_TYPE_JSON = "json";
|
||||||
export const CONTENT_TYPE_FORM = "x-www-form-urlencoded";
|
export const CONTENT_TYPE_FORM = "x-www-form-urlencoded";
|
||||||
export const API_STATUS = "/api/v1/status";
|
export const API_STATUS = "/api/v1/status";
|
||||||
export const API_GET_NAV = "/api/settings/nav";
|
export const API_GET_NAV = "/api/settings/nav";
|
||||||
export const API_NEW_PAGE = "/api/v1/page/write/new";
|
export const API_NEW_PAGE = "/api/v1/page/create";
|
||||||
export const API_EDIT_PAGE = "/api/v1/page/write";
|
export const API_EDIT_PAGE = "/api/v1/page/write";
|
||||||
export const API_DELETE_PAGE = "/api/v1/page/delete";
|
export const API_DELETE_PAGE = "/api/v1/page/delete";
|
||||||
export const API_IMAGE_UPLOAD = "/api/v1/page/add-post-image";
|
export const API_IMAGE_UPLOAD = "/api/v1/page/add-entry-image";
|
||||||
export const API_SETTINGS_SYNC = "/api/v1/settings/sync";
|
export const API_SETTINGS_SYNC = "/api/v1/settings/sync";
|
||||||
export const API_UPLOAD_AVATAR = "/api/v1/settings/add-avatar";
|
export const API_UPLOAD_AVATAR = "/api/v1/settings/add-avatar";
|
||||||
export const API_UPLOAD_BACKGROUND = "/api/v1/settings/add-feature-background";
|
export const API_UPLOAD_BACKGROUND = "/api/v1/settings/add-feature-background";
|
||||||
|
@ -280,6 +280,7 @@ export default class APIUtils {
|
||||||
request.open(requestType, requestURL, true);
|
request.open(requestType, requestURL, true);
|
||||||
request.onload = () => {
|
request.onload = () => {
|
||||||
if (request.status == 200) {
|
if (request.status == 200) {
|
||||||
|
//console.log("RESPONSE", request);
|
||||||
let response = JSON.parse(request["response"]);
|
let response = JSON.parse(request["response"]);
|
||||||
resolve(response);
|
resolve(response);
|
||||||
} else {
|
} else {
|
||||||
|
@ -298,7 +299,7 @@ export default class APIUtils {
|
||||||
eventType === DataEvent.API_BACKUP_RESTORE ||
|
eventType === DataEvent.API_BACKUP_RESTORE ||
|
||||||
eventType === DataEvent.API_REINDEX_PAGES
|
eventType === DataEvent.API_REINDEX_PAGES
|
||||||
)
|
)
|
||||||
request.setRequestHeader("x-access-token", self.token);
|
request.setRequestHeader("fipamo-access-token", self.token);
|
||||||
|
|
||||||
switch (contentType) {
|
switch (contentType) {
|
||||||
case CONTENT_TYPE_JSON:
|
case CONTENT_TYPE_JSON:
|
||||||
|
|
Loading…
Reference in a new issue