2.5.0 commit part 1, whew
commit
7cefc12692
@ -1,70 +1,70 @@
|
|||||||
{
|
{
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"ecmaVersion": 7,
|
"ecmaVersion": 7,
|
||||||
"sourceType": "module",
|
"sourceType": "module",
|
||||||
"ecmaFeatures": {}
|
"ecmaFeatures": {}
|
||||||
},
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
"constructor-super": 2,
|
"constructor-super": 2,
|
||||||
"for-direction": 2,
|
"for-direction": 2,
|
||||||
"getter-return": 2,
|
"getter-return": 2,
|
||||||
"no-case-declarations": 2,
|
"no-case-declarations": 2,
|
||||||
"no-class-assign": 2,
|
"no-class-assign": 2,
|
||||||
"no-compare-neg-zero": 2,
|
"no-compare-neg-zero": 2,
|
||||||
"no-cond-assign": 2,
|
"no-cond-assign": 2,
|
||||||
"no-console": 1,
|
"no-console": 1,
|
||||||
"no-const-assign": 2,
|
"no-const-assign": 2,
|
||||||
"no-constant-condition": 2,
|
"no-constant-condition": 2,
|
||||||
"no-control-regex": 1,
|
"no-control-regex": 1,
|
||||||
"no-debugger": 2,
|
"no-debugger": 2,
|
||||||
"no-delete-var": 2,
|
"no-delete-var": 2,
|
||||||
"no-dupe-args": 2,
|
"no-dupe-args": 2,
|
||||||
"no-dupe-class-members": 2,
|
"no-dupe-class-members": 2,
|
||||||
"no-dupe-keys": 2,
|
"no-dupe-keys": 2,
|
||||||
"no-duplicate-case": 2,
|
"no-duplicate-case": 2,
|
||||||
"no-empty": 2,
|
"no-empty": 2,
|
||||||
"no-empty-character-class": 2,
|
"no-empty-character-class": 2,
|
||||||
"no-empty-pattern": 2,
|
"no-empty-pattern": 2,
|
||||||
"no-ex-assign": 2,
|
"no-ex-assign": 2,
|
||||||
"no-extra-boolean-cast": 2,
|
"no-extra-boolean-cast": 2,
|
||||||
"no-extra-semi": 2,
|
"no-extra-semi": 2,
|
||||||
"no-fallthrough": 2,
|
"no-fallthrough": 2,
|
||||||
"no-func-assign": 2,
|
"no-func-assign": 2,
|
||||||
"no-global-assign": 2,
|
"no-global-assign": 2,
|
||||||
"no-inner-declarations": 2,
|
"no-inner-declarations": 2,
|
||||||
"no-invalid-regexp": 2,
|
"no-invalid-regexp": 2,
|
||||||
"no-irregular-whitespace": 2,
|
"no-irregular-whitespace": 2,
|
||||||
"no-mixed-spaces-and-tabs": 2,
|
"no-mixed-spaces-and-tabs": 2,
|
||||||
"no-new-symbol": 2,
|
"no-new-symbol": 2,
|
||||||
"no-obj-calls": 2,
|
"no-obj-calls": 2,
|
||||||
"no-octal": 2,
|
"no-octal": 2,
|
||||||
"no-redeclare": 2,
|
"no-redeclare": 2,
|
||||||
"no-regex-spaces": 2,
|
"no-regex-spaces": 2,
|
||||||
"no-self-assign": 2,
|
"no-self-assign": 2,
|
||||||
"no-sparse-arrays": 2,
|
"no-sparse-arrays": 2,
|
||||||
"no-this-before-super": 2,
|
"no-this-before-super": 2,
|
||||||
"no-undef": 2,
|
"no-undef": 2,
|
||||||
"no-unexpected-multiline": 2,
|
"no-unexpected-multiline": 2,
|
||||||
"no-unreachable": 2,
|
"no-unreachable": 2,
|
||||||
"no-unsafe-finally": 2,
|
"no-unsafe-finally": 2,
|
||||||
"no-unsafe-negation": 2,
|
"no-unsafe-negation": 2,
|
||||||
"no-unused-labels": 2,
|
"no-unused-labels": 2,
|
||||||
"no-unused-vars": 2,
|
"no-unused-vars": 1,
|
||||||
"no-useless-escape": 1,
|
"no-useless-escape": 1,
|
||||||
"require-yield": 2,
|
"require-yield": 2,
|
||||||
"use-isnan": 2,
|
"use-isnan": 2,
|
||||||
"valid-typeof": 2,
|
"valid-typeof": 2,
|
||||||
"no-duplicate-imports": 2
|
"no-duplicate-imports": 2
|
||||||
},
|
},
|
||||||
"env": {
|
"env": {
|
||||||
"node": true,
|
"node": true,
|
||||||
"browser": true,
|
"browser": true,
|
||||||
"es6": true
|
"es6": true
|
||||||
},
|
},
|
||||||
"globals": {
|
"globals": {
|
||||||
"_": false,
|
"_": false,
|
||||||
"hljs": false,
|
"hljs": false,
|
||||||
"Sortable": false,
|
"Sortable": false,
|
||||||
"Prism": false
|
"Prism": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
.babelrc
|
||||||
|
README.md
|
||||||
|
*.twig
|
||||||
|
*.sass
|
||||||
|
*.json
|
||||||
|
*.php
|
||||||
|
*.md
|
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"arrowParens": "avoid",
|
||||||
|
"bracketSpacing": true,
|
||||||
|
"htmlWhitespaceSensitivity": "css",
|
||||||
|
"insertPragma": false,
|
||||||
|
"bracketSameLine": false,
|
||||||
|
"jsxSingleQuote": true,
|
||||||
|
"parser": "babel",
|
||||||
|
"proseWrap": "preserve",
|
||||||
|
"requirePragma": false,
|
||||||
|
"semi": true,
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "none",
|
||||||
|
"useTabs": true,
|
||||||
|
"tabWidth": 4,
|
||||||
|
"printWidth": 90
|
||||||
|
}
|
@ -1,48 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Psr\Http\Message\ResponseInterface as Response;
|
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
|
||||||
use Slim\Factory\AppFactory;
|
|
||||||
use Slim\Views\Twig;
|
|
||||||
use Slim\Views\TwigMiddleware;
|
|
||||||
|
|
||||||
include "../brain/controller/RouteControl.inc.php";
|
|
||||||
include "../brain/data/Settings.inc.php";
|
|
||||||
include "../brain/data/Session.inc.php";
|
|
||||||
include "../brain/data/Member.inc.php";
|
|
||||||
include "../brain/data/Auth.inc.php";
|
|
||||||
include "../brain/data/Render.inc.php";
|
|
||||||
include "../brain/data/Themes.inc.php";
|
|
||||||
include "../brain/data/Contents.inc.php";
|
|
||||||
include "../brain/utility/StringTools.inc.php";
|
|
||||||
include "../brain/utility/FileUploader.inc.php";
|
|
||||||
include "../brain/utility/DocTools.inc.php";
|
|
||||||
include "../brain/utility/Sorting.inc.php";
|
|
||||||
include "../brain/utility/Setup.inc.php";
|
|
||||||
include "../brain/utility/Maintenance.inc.php";
|
|
||||||
include "../brain/utility/Mailer.inc.php";
|
|
||||||
include "../brain/utility/HandleCors.inc.php";
|
|
||||||
|
|
||||||
class App
|
|
||||||
{
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
// set up cors
|
|
||||||
new HandleCors();
|
|
||||||
$app = AppFactory::create();
|
|
||||||
$twig = Twig::create("../brain/views/");
|
|
||||||
$app->add(TwigMiddleware::create($app, $twig));
|
|
||||||
//set up routing
|
|
||||||
$app->get(
|
|
||||||
"/[{first}[/{second}[/{third}[/{fourth}[/{fifth}]]]]]",
|
|
||||||
"\RouteControl:get"
|
|
||||||
);
|
|
||||||
$app->post(
|
|
||||||
"/[{first}[/{second}[/{third}[/{fourth}]]]]",
|
|
||||||
"\RouteControl:post"
|
|
||||||
);
|
|
||||||
//start the app
|
|
||||||
|
|
||||||
$app->run();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,74 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class AuthAPI
|
|
||||||
{
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function status()
|
|
||||||
{
|
|
||||||
$result = [];
|
|
||||||
//internal check for admin action
|
|
||||||
if (Auth::status()) {
|
|
||||||
$result = [
|
|
||||||
"message" => "Authorized",
|
|
||||||
"type" => "apiUseAuthorized",
|
|
||||||
"token" => Session::get("token"),
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
$result = [
|
|
||||||
"message" => "Not Authorized",
|
|
||||||
"type" => "apiUseNotAuthorized",
|
|
||||||
];
|
|
||||||
}
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function login($body)
|
|
||||||
{
|
|
||||||
$result = [];
|
|
||||||
switch (Auth::login($body)) {
|
|
||||||
case "no_name":
|
|
||||||
$result = [
|
|
||||||
"message" => "Need to see some id, champ",
|
|
||||||
"type" => "requestLame",
|
|
||||||
];
|
|
||||||
break;
|
|
||||||
case "bad_pass":
|
|
||||||
$result = [
|
|
||||||
"message" => "Check your password, sport",
|
|
||||||
"type" => "requestLame",
|
|
||||||
];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$result = [
|
|
||||||
"message" => "Welcome back",
|
|
||||||
"type" => "requestGood",
|
|
||||||
];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function logout($body)
|
|
||||||
{
|
|
||||||
Auth::logout($body);
|
|
||||||
$result = [
|
|
||||||
"message" => "Till next time, g.",
|
|
||||||
"type" => "TASK_LOGOUT",
|
|
||||||
];
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
public static function requestSecret($body)
|
|
||||||
{
|
|
||||||
$result = Auth::findSecret($body);
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
public static function resetPassword($body)
|
|
||||||
{
|
|
||||||
$result = Auth::makeNewPassword($body);
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,79 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace brain\api\v1;
|
||||||
|
|
||||||
|
use brain\data\Auth;
|
||||||
|
use brain\data\Session;
|
||||||
|
|
||||||
|
class AuthAPI
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function status()
|
||||||
|
{
|
||||||
|
$result = [];
|
||||||
|
//internal check for admin action
|
||||||
|
if (Auth::status()) {
|
||||||
|
$result = [
|
||||||
|
"message" => "Authorized",
|
||||||
|
"type" => "apiUseAuthorized",
|
||||||
|
"token" => Session::get("token"),
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
$result = [
|
||||||
|
"message" => "Not Authorized",
|
||||||
|
"type" => "apiUseNotAuthorized",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function login($body)
|
||||||
|
{
|
||||||
|
$result = [];
|
||||||
|
switch (Auth::login($body)) {
|
||||||
|
case "no_name":
|
||||||
|
$result = [
|
||||||
|
"message" => "Need to see some id, champ",
|
||||||
|
"type" => "requestLame",
|
||||||
|
];
|
||||||
|
break;
|
||||||
|
case "bad_pass":
|
||||||
|
$result = [
|
||||||
|
"message" => "Check your password, sport",
|
||||||
|
"type" => "requestLame",
|
||||||
|
];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$result = [
|
||||||
|
"message" => "Welcome back",
|
||||||
|
"type" => "requestGood",
|
||||||
|
];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function logout($body)
|
||||||
|
{
|
||||||
|
Auth::logout($body);
|
||||||
|
$result = [
|
||||||
|
"message" => "Till next time, g.",
|
||||||
|
"type" => "TASK_LOGOUT",
|
||||||
|
];
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
public static function requestSecret($body)
|
||||||
|
{
|
||||||
|
$result = Auth::findSecret($body);
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
public static function resetPassword($body)
|
||||||
|
{
|
||||||
|
$result = Auth::makeNewPassword($body);
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
}
|
@ -1,76 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class ImagesAPI
|
|
||||||
{
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function uploadImage($request, $type = null)
|
|
||||||
{
|
|
||||||
$file = $request->getUploadedFiles();
|
|
||||||
$uploadPath = "";
|
|
||||||
$path = date("Y") . "/" . date("m");
|
|
||||||
$response = [];
|
|
||||||
switch ($type) {
|
|
||||||
case "avatar":
|
|
||||||
$image = $file["avatar_upload"];
|
|
||||||
$uploadPath = "../public/assets/images/user/" . $path;
|
|
||||||
break;
|
|
||||||
case "background":
|
|
||||||
$image = $file["background_upload"];
|
|
||||||
$uploadPath = "../public/assets/images/user/" . $path;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$image = $file["post_image"];
|
|
||||||
$path = date("Y") . "/" . date("m");
|
|
||||||
$uploadPath = "../public/assets/images/blog/" . $path;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = FileUploader::uploadFile($uploadPath, $image);
|
|
||||||
|
|
||||||
switch ($type) {
|
|
||||||
case "avatar":
|
|
||||||
$response = [
|
|
||||||
"message" => "Avatar Added. You look great!",
|
|
||||||
"type" => "avatarUploaded",
|
|
||||||
"url" =>
|
|
||||||
"/assets/images/user/" . $path . "/" . $image->getClientFileName(),
|
|
||||||
];
|
|
||||||
|
|
||||||
//update member data
|
|
||||||
Member::updateData(
|
|
||||||
"avi",
|
|
||||||
"/assets/images/user/" . $path . "/" . $image->getClientFileName()
|
|
||||||
);
|
|
||||||
|
|
||||||
break;
|
|
||||||
case "background":
|
|
||||||
$response = [
|
|
||||||
"message" => "Background plugged in. That's nice!",
|
|
||||||
"type" => "siteBackgroundUploaded",
|
|
||||||
"url" =>
|
|
||||||
"/assets/images/user/" . $path . "/" . $image->getClientFileName(),
|
|
||||||
];
|
|
||||||
|
|
||||||
//update settings file
|
|
||||||
Settings::updateGlobalData(
|
|
||||||
"background",
|
|
||||||
"/assets/images/user/" . $path . "/" . $image->getClientFileName()
|
|
||||||
);
|
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$response = [
|
|
||||||
"message" => "Image Added. Very slick",
|
|
||||||
"type" => "postImageAdded",
|
|
||||||
"url" =>
|
|
||||||
"/assets/images/blog/" . $path . "/" . $image->getClientFileName(),
|
|
||||||
];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,81 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace brain\api\v1;
|
||||||
|
|
||||||
|
use brain\data\Member;
|
||||||
|
use brain\data\Settings;
|
||||||
|
|
||||||
|
class ImagesAPI
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function uploadImage($request, $type = null)
|
||||||
|
{
|
||||||
|
$file = $request->getUploadedFiles();
|
||||||
|
$uploadPath = "";
|
||||||
|
$path = date("Y") . "/" . date("m");
|
||||||
|
$response = [];
|
||||||
|
switch ($type) {
|
||||||
|
case "avatar":
|
||||||
|
$image = $file["avatar_upload"];
|
||||||
|
$uploadPath = "../public/assets/images/user/" . $path;
|
||||||
|
break;
|
||||||
|
case "background":
|
||||||
|
$image = $file["background_upload"];
|
||||||
|
$uploadPath = "../public/assets/images/user/" . $path;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$image = $file["post_image"];
|
||||||
|
$path = date("Y") . "/" . date("m");
|
||||||
|
$uploadPath = "../public/assets/images/blog/" . $path;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = FileUploader::uploadFile($uploadPath, $image);
|
||||||
|
|
||||||
|
switch ($type) {
|
||||||
|
case "avatar":
|
||||||
|
$response = [
|
||||||
|
"message" => "Avatar Added. You look great!",
|
||||||
|
"type" => "avatarUploaded",
|
||||||
|
"url" =>
|
||||||
|
"/assets/images/user/" . $path . "/" . $image->getClientFileName(),
|
||||||
|
];
|
||||||
|
|
||||||
|
//update member data
|
||||||
|
Member::updateData(
|
||||||
|
"avi",
|
||||||
|
"/assets/images/user/" . $path . "/" . $image->getClientFileName()
|
||||||
|
);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case "background":
|
||||||
|
$response = [
|
||||||
|
"message" => "Background plugged in. That's nice!",
|
||||||
|
"type" => "siteBackgroundUploaded",
|
||||||
|
"url" =>
|
||||||
|
"/assets/images/user/" . $path . "/" . $image->getClientFileName(),
|
||||||
|
];
|
||||||
|
|
||||||
|
//update settings file
|
||||||
|
Settings::updateGlobalData(
|
||||||
|
"background",
|
||||||
|
"/assets/images/user/" . $path . "/" . $image->getClientFileName()
|
||||||
|
);
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$response = [
|
||||||
|
"message" => "Image Added. Very slick",
|
||||||
|
"type" => "postImageAdded",
|
||||||
|
"url" =>
|
||||||
|
"/assets/images/blog/" . $path . "/" . $image->getClientFileName(),
|
||||||
|
];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
}
|
@ -1,30 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class InitAPI
|
|
||||||
{
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function handleInitTasks($task, $request)
|
|
||||||
{
|
|
||||||
//check if a site config already exists. if it does, deny set up request
|
|
||||||
//restore to previous version of site while a config exists is only accessible
|
|
||||||
//through settings.
|
|
||||||
|
|
||||||
if (Setup::status()) {
|
|
||||||
$result = ["type" => "blogInitFail", "message" => "Site already set up"];
|
|
||||||
} else {
|
|
||||||
switch ($task) {
|
|
||||||
case "init":
|
|
||||||
$result = Setup::init($request);
|
|
||||||
break;
|
|
||||||
case "restore":
|
|
||||||
$result = Setup::restore($request);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace brain\api\v1;
|
||||||
|
|
||||||
|
use brain\utility\Setup;
|
||||||
|
|
||||||
|
class InitAPI
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function handleInitTasks($task, $request)
|
||||||
|
{
|
||||||
|
//check if a site config already exists. if it does, deny set up request
|
||||||
|
//restore to previous version of site while a config exists is only accessible
|
||||||
|
//through settings.
|
||||||
|
|
||||||
|
if (Setup::status()) {
|
||||||
|
$result = ["type" => "blogInitFail", "message" => "Site already set up"];
|
||||||
|
} else {
|
||||||
|
switch ($task) {
|
||||||
|
case "init":
|
||||||
|
$result = Setup::init($request);
|
||||||
|
break;
|
||||||
|
case "restore":
|
||||||
|
$result = Setup::restore($request);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
}
|
@ -1,26 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class MailerAPI
|
|
||||||
{
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function handleMail($request, $body, $response)
|
|
||||||
{
|
|
||||||
//if testing, verify session is active
|
|
||||||
if ($body["mail_task"] == "TESTING") {
|
|
||||||
if (Session::active()) {
|
|
||||||
$result = Mailer::sendmail($body);
|
|
||||||
} else {
|
|
||||||
$result = [
|
|
||||||
"message" => "You need to be logged in for this, champ.",
|
|
||||||
"type" => "MAILER_ERROR",
|
|
||||||
];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace brain\api\v1;
|
||||||
|
|
||||||
|
use brain\data\Session;
|
||||||
|
use brain\utility\Mailer;
|
||||||
|
|
||||||
|
class MailerAPI
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function handleMail($request, $body, $response)
|
||||||
|
{
|
||||||
|
//if testing, verify session is active
|
||||||
|
if ($body["mail_task"] == "TESTING") {
|
||||||
|
if (Session::active()) {
|
||||||
|
$result = Mailer::sendmail($body);
|
||||||
|
} else {
|
||||||
|
$result = [
|
||||||
|
"message" => "You need to be logged in for this, champ.",
|
||||||
|
"type" => "MAILER_ERROR",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
}
|
@ -1,171 +0,0 @@
|
|||||||
<?php
|
|
||||||
use function _\filter;
|
|
||||||
use Mni\FrontYAML\Parser;
|
|
||||||
|
|
||||||
class PagesAPI
|
|
||||||
{
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getPageContent($request, $args)
|
|
||||||
{
|
|
||||||
$task = $args["fourth"];
|
|
||||||
$pages = (new Book("../content/pages"))->getContents();
|
|
||||||
$content = [];
|
|
||||||
foreach ($pages as $page) {
|
|
||||||
$entry = [
|
|
||||||
"id" => $page["id"],
|
|
||||||
"uuid" => $page["uuid"],
|
|
||||||
"title" => $page["title"],
|
|
||||||
"feature" => $page["feature"],
|
|
||||||
"path" => $page["path"],
|
|
||||||
"layout" => $page["layout"],
|
|
||||||
"tags" => $page["tags"],
|
|
||||||
"author" => $page["author"],
|
|
||||||
"created" => $page["created"],
|
|
||||||
"updated" => $page["updated"],
|
|
||||||
"deleted" => $page["deleted"],
|
|
||||||
"menu" => $page["menu"],
|
|
||||||
"featured" => $page["featured"],
|
|
||||||
"published" => $page["published"],
|
|
||||||
"slug" => $page["slug"],
|
|
||||||
"content" => StringTools::sanitizeContent($page["content"]),
|
|
||||||
];
|
|
||||||
|
|
||||||
array_push($content, $entry);
|
|
||||||
}
|
|
||||||
switch ($task) {
|
|
||||||
case "published":
|
|
||||||
$published = filter($content, function ($item) {
|
|
||||||
return $item["published"] == true && $item["deleted"] == false;
|
|
||||||
});
|
|
||||||
|
|
||||||
$result = ["pages" => $published, "totalItems" => count($published)];
|
|
||||||
break;
|
|
||||||
case "featured":
|
|
||||||
$featured = filter($content, function ($item) {
|
|
||||||
return $item["featured"] == true && $item["deleted"] == false;
|
|
||||||
});
|
|
||||||
|
|
||||||
$result = [
|
|
||||||
"pages" => $featured,
|
|
||||||
"totalItems" => count($featured),
|
|
||||||
];
|
|
||||||
break;
|
|
||||||
case "menu":
|
|
||||||
$menu = filter($content, function ($item) {
|
|
||||||
return $item["menu"] == true && $item["deleted"] == false;
|
|
||||||
});
|
|
||||||
|
|
||||||
$result = ["pages" => $menu, "totalItems" => count($menu)];
|
|
||||||
break;
|
|
||||||
case "single":
|
|
||||||
$uuid = $args["fifth"];
|
|
||||||
$page = (new Book("../content/pages"))->findPageById($uuid);
|
|
||||||
|
|
||||||
$entry = [
|
|
||||||
"id" => $page["id"],
|
|
||||||
"uuid" => $page["uuid"],
|
|
||||||
"title" => $page["title"],
|
|
||||||
"feature" => $page["feature"],
|
|
||||||
"path" => $page["path"],
|
|
||||||
"layout" => $page["layout"],
|
|
||||||
"tags" => $page["tags"],
|
|
||||||
"author" => $page["author"],
|
|
||||||
"created" => $page["created"],
|
|
||||||
"updated" => $page["updated"],
|
|
||||||
"deleted" => $page["deleted"],
|
|
||||||
"menu" => $page["menu"],
|
|
||||||
"featured" => $page["featured"],
|
|
||||||
"published" => $page["published"],
|
|
||||||
"slug" => $page["slug"],
|
|
||||||
"content" => StringTools::sanitizeContent($page["content"]),
|
|
||||||
];
|
|
||||||
$result = $entry;
|
|
||||||
break;
|
|
||||||
case "tags":
|
|
||||||
$result = Settings::getTags();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$result = [
|
|
||||||
"message" => "Hm, no task. That's unfortunate",
|
|
||||||
"type" => "TASK_NONE",
|
|
||||||
];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function handlePageTask($request, $args)
|
|
||||||
{
|
|
||||||
$task = $args["fourth"];
|
|
||||||
switch ($task) {
|
|
||||||
case "delete":
|
|
||||||
case "create":
|
|
||||||
case "write":
|
|
||||||
$body = $request->getParsedBody();
|
|
||||||
$passed = true;
|
|
||||||
if (!isset($body["form_token"])) {
|
|
||||||
$result = [
|
|
||||||
"message" => "No form token. Not good, sport.",
|
|
||||||
"type" => "TASK_FORM_AUTH",
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
if ($body["form_token"] == Session::get("form_token")) {
|
|
||||||
//TODO: Verify form fields
|
|
||||||
$keys = [
|
|
||||||
"id",
|
|
||||||
"uuid",
|
|
||||||
"layout",
|
|
||||||
"current_title",
|
|
||||||
"content",
|
|
||||||
"title",
|
|
||||||
"created",
|
|
||||||
"slug",
|
|
||||||
"tags",
|
|
||||||
"menu",
|
|
||||||
"featured",
|
|
||||||
"published",
|
|
||||||
"form_token",
|
|
||||||
"feature_image",
|
|
||||||
];
|
|
||||||
|
|
||||||
foreach ($body as $key => $item) {
|
|
||||||
if (!in_array($key, $keys)) {
|
|
||||||
//found unnecessary key, so reject submission
|
|
||||||
$passed = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($passed) {
|
|
||||||
$result = (new Book())->editPage($task, $request);
|
|
||||||
} else {
|
|
||||||
$result = [
|
|
||||||
"message" =>
|
|
||||||
"Unneccessary key found. Post not authorized, slick.",
|
|
||||||
"type" => "TASK_FORM_AUTH",
|
|
||||||
];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$result = [
|
|
||||||
"message" => "Form token, auth failed. Uh oh.",
|
|
||||||
"type" => "TASK_FORM_AUTH",
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case "add-entry-image":
|
|
||||||
$result = ImagesAPI::uploadImage($request);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$result = [
|
|
||||||
"message" => "Hm, no task. That's unfortunate",
|
|
||||||
"type" => "TASK_NONE",
|
|
||||||
];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,180 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace brain\api\v1;
|
||||||
|
|
||||||
|
use Mni\FrontYAML\Parser;
|
||||||
|
use brain\api\v1\ImagesAPI;
|
||||||
|
use brain\data\Book;
|
||||||
|
use brain\data\Settings;
|
||||||
|
use brain\data\Session;
|
||||||
|
use brain\utility\StringTools;
|
||||||
|
|
||||||
|
use function _\filter;
|
||||||
|
|
||||||
|
class PagesAPI
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getPageContent($request, $args)
|
||||||
|
{
|
||||||
|
$task = $args["fourth"];
|
||||||
|
$pages = (new Book("../content/pages"))->getContents();
|
||||||
|
$content = [];
|
||||||
|
foreach ($pages as $page) {
|
||||||
|
$entry = [
|
||||||
|
"id" => $page["id"],
|
||||||
|
"uuid" => $page["uuid"],
|
||||||
|
"title" => $page["title"],
|
||||||
|
"feature" => $page["feature"],
|
||||||
|
"path" => $page["path"],
|
||||||
|
"layout" => $page["layout"],
|
||||||
|
"tags" => $page["tags"],
|
||||||
|
"author" => $page["author"],
|
||||||
|
"created" => $page["created"],
|
||||||
|
"updated" => $page["updated"],
|
||||||
|
"deleted" => $page["deleted"],
|
||||||
|
"menu" => $page["menu"],
|
||||||
|
"featured" => $page["featured"],
|
||||||
|
"published" => $page["published"],
|
||||||
|
"slug" => $page["slug"],
|
||||||
|
"content" => StringTools::sanitizeContent($page["content"]),
|
||||||
|
];
|
||||||
|
|
||||||
|
array_push($content, $entry);
|
||||||
|
}
|
||||||
|
switch ($task) {
|
||||||
|
case "published":
|
||||||
|
$published = filter($content, function ($item) {
|
||||||
|
return $item["published"] == true && $item["deleted"] == false;
|
||||||
|
});
|
||||||
|
|
||||||
|
$result = ["pages" => $published, "totalItems" => count($published)];
|
||||||
|
break;
|
||||||
|
case "featured":
|
||||||
|
$featured = filter($content, function ($item) {
|
||||||
|
return $item["featured"] == true && $item["deleted"] == false;
|
||||||
|
});
|
||||||
|
|
||||||
|
$result = [
|
||||||
|
"pages" => $featured,
|
||||||
|
"totalItems" => count($featured),
|
||||||
|
];
|
||||||
|
break;
|
||||||
|
case "menu":
|
||||||
|
$menu = filter($content, function ($item) {
|
||||||
|
return $item["menu"] == true && $item["deleted"] == false;
|
||||||
|
});
|
||||||
|
|
||||||
|
$result = ["pages" => $menu, "totalItems" => count($menu)];
|
||||||
|
break;
|
||||||
|
case "single":
|
||||||
|
$uuid = $args["fifth"];
|
||||||
|
$page = (new Book("../content/pages"))->findPageById($uuid);
|
||||||
|
|
||||||
|
$entry = [
|
||||||
|
"id" => $page["id"],
|
||||||
|
"uuid" => $page["uuid"],
|
||||||
|
"title" => $page["title"],
|
||||||
|
"feature" => $page["feature"],
|
||||||
|
"path" => $page["path"],
|
||||||
|
"layout" => $page["layout"],
|
||||||
|
"tags" => $page["tags"],
|
||||||
|
"author" => $page["author"],
|
||||||
|
"created" => $page["created"],
|
||||||
|
"updated" => $page["updated"],
|
||||||
|
"deleted" => $page["deleted"],
|
||||||
|
"menu" => $page["menu"],
|
||||||
|
"featured" => $page["featured"],
|
||||||
|
"published" => $page["published"],
|
||||||
|
"slug" => $page["slug"],
|
||||||
|
"content" => StringTools::sanitizeContent($page["content"]),
|
||||||
|
];
|
||||||
|
$result = $entry;
|
||||||
|
break;
|
||||||
|
case "tags":
|
||||||
|
$result = Settings::getTags();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$result = [
|
||||||
|
"message" => "Hm, no task. That's unfortunate",
|
||||||
|
"type" => "TASK_NONE",
|
||||||
|
];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function handlePageTask($request, $args)
|
||||||
|
{
|
||||||
|
$task = $args["fourth"];
|
||||||
|
switch ($task) {
|
||||||
|
case "delete":
|
||||||
|
case "create":
|
||||||
|
case "write":
|
||||||
|
$body = $request->getParsedBody();
|
||||||
|
$passed = true;
|
||||||
|
if (!isset($body["form_token"])) {
|
||||||
|
$result = [
|
||||||
|
"message" => "No form token. Not good, sport.",
|
||||||
|
"type" => "TASK_FORM_AUTH",
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
if ($body["form_token"] == Session::get("form_token")) {
|
||||||
|
//TODO: Verify form fields
|
||||||
|
$keys = [
|
||||||
|
"id",
|
||||||
|
"uuid",
|
||||||
|
"layout",
|
||||||
|
"current_title",
|
||||||
|
"content",
|
||||||
|
"title",
|
||||||
|
"created",
|
||||||
|
"slug",
|
||||||
|
"tags",
|
||||||
|
"menu",
|
||||||
|
"featured",
|
||||||
|
"published",
|
||||||
|
"form_token",
|
||||||
|
"feature_image",
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($body as $key => $item) {
|
||||||
|
if (!in_array($key, $keys)) {
|
||||||
|
//found unnecessary key, so reject submission
|
||||||
|
$passed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($passed) {
|
||||||
|
$result = (new Book())->editPage($task, $request);
|
||||||
|
} else {
|
||||||
|
$result = [
|
||||||
|
"message" =>
|
||||||
|
"Unneccessary key found. Post not authorized, slick.",
|
||||||
|
"type" => "TASK_FORM_AUTH",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$result = [
|
||||||
|
"message" => "Form token, auth failed. Uh oh.",
|
||||||
|
"type" => "TASK_FORM_AUTH",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case "add-entry-image":
|
||||||
|
$result = ImagesAPI::uploadImage($request);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$result = [
|
||||||
|
"message" => "Hm, no task. That's unfortunate",
|
||||||
|
"type" => "TASK_NONE",
|
||||||
|
];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
}
|
@ -1,147 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Slim\Views\Twig;
|
|
||||||
|
|
||||||
class SettingsAPI
|
|
||||||
{
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function handleSettingsTask($request, $args, $body = null)
|
|
||||||
{
|
|
||||||
$task = $args["fourth"];
|
|
||||||
switch ($task) {
|
|
||||||
case "publish":
|
|
||||||
//check settings to see if site is a one pager
|
|
||||||
$config = new Settings();
|
|
||||||
$settings = $config->getSettings();
|
|
||||||
$theme = $settings["global"]["theme"];
|
|
||||||
$themeConfig = json_decode(
|
|
||||||
file_get_contents("../content/themes/" . $theme . "/theme.json"),
|
|
||||||
true
|
|
||||||
);
|
|
||||||
//check to see if dynamic rendering is active
|
|
||||||
if (
|
|
||||||
isset($settings["global"]["dynamicRender"]) &&
|
|
||||||
$settings["global"]["dynamicRender"] === "true"
|
|
||||||
) {
|
|
||||||
$result = [
|
|
||||||
"message" => "Dynamic Render Active! You're good!",
|
|
||||||
"type" => "RENDER_SUCCESS",
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
$render = new Render();
|
|
||||||
if (isset($themeConfig["render"])) {
|
|
||||||
if (!$themeConfig["render"] || $themeConfig["render"] === "false") {
|
|
||||||
$render->renderIndex();
|
|
||||||
$result = [
|
|
||||||
"message" => "Index Rendered. HAND CLAPS",
|
|
||||||
"type" => "RENDER_SUCCESS",
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
$render->renderTags();
|
|
||||||
$render->renderArchive();
|
|
||||||
$render->renderPages();
|
|
||||||
$result = [
|
|
||||||
"message" => "Site Rendered. GOOD EFFORT",
|
|
||||||
"type" => "RENDER_SUCCESS",
|
|
||||||
];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// just incase the render flag is missing
|
|
||||||
$render->renderTags();
|
|
||||||
$render->renderArchive();
|
|
||||||
$render->renderPages();
|
|
||||||
$result = [
|
|
||||||
"message" => "Site Rendered. GOOD EFFORT",
|
|
||||||
"type" => "RENDER_SUCCESS",
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//if render flag is set and false, just render index page for one page sites
|
|
||||||
//otherwise, render all pages according to theme template files
|
|
||||||
|
|
||||||
break;
|
|
||||||
case "add-avatar":
|
|
||||||
$result = ImagesAPI::uploadImage($request, "avatar");
|
|
||||||
break;
|
|
||||||
case "add-feature-background":
|
|
||||||
$result = ImagesAPI::uploadImage($request, "background");
|
|
||||||
break;
|
|
||||||
case "sync":
|
|
||||||
Settings::sync($body);
|
|
||||||
$result = [
|
|
||||||
"message" => "Settings Synced. You're doing great!",
|
|
||||||
"type" => "settingsUpdated",
|
|
||||||
];
|
|
||||||
break;
|
|
||||||
case "nav-sync":
|
|
||||||
Settings::navSync($body);
|
|
||||||
$result = [
|
|
||||||
"message" => "Navigation updated. Very slick!",
|
|
||||||
"type" => "menuUpdated",
|
|
||||||
];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$result = [
|
|
||||||
"message" => "Hm, no task. That's unfortunate",
|
|
||||||
"type" => "TASK_NONE",
|
|
||||||
];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getInfo($request, $args)
|
|
||||||
{
|
|
||||||
$task = $args["fourth"];
|
|
||||||
switch ($task) {
|
|
||||||
case "site":
|
|
||||||
$config = new Settings();
|
|
||||||
$settings = $config->getSettings();
|
|
||||||
$data = [
|
|
||||||
"title" => $settings["global"]["title"],
|
|
||||||
"base_url" => $settings["global"]["base_url"],
|
|
||||||
"description" => $settings["global"]["descriptions"],
|
|
||||||
];
|
|
||||||
$result = [
|
|
||||||
"message" => "Settings Found",
|
|
||||||
"type" => "GET_SETTINGS",
|
|
||||||
"data" => $data,
|
|
||||||
];
|
|
||||||
break;
|
|
||||||
case "member":
|
|
||||||
if (Session::active()) {
|
|
||||||
$member = $member = Session::get("member");
|
|
||||||
$data = ["handle" => $member["handle"], "email" => $member["email"]];
|
|
||||||
$result = [
|
|
||||||
"message" => "Member Info Found",
|
|
||||||
"type" => "GET_MEMBER_INFO",
|
|
||||||
"data" => $data,
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
$result = [
|
|
||||||
"message" => "Not logged in. C'mon, bruh",
|
|
||||||
"type" => "TASK_NONE",
|
|
||||||
];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$result = [
|
|
||||||
"message" => "No Settings found. Frowny Face",
|
|
||||||
"type" => "TASK_NONE",
|
|
||||||
];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function createBackup()
|
|
||||||
{
|
|
||||||
$result = Maintenance::makeBackup();
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,154 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace brain\api\v1;
|
||||||
|
|
||||||
|
use Slim\Views\Twig;
|
||||||
|
use brain\api\v1\ImagesApi;
|
||||||
|
use brain\data\Render;
|
||||||
|
use brain\data\Settings;
|
||||||
|
use brain\data\Session;
|
||||||
|
use brain\utility\Maintenance;
|
||||||
|
|
||||||
|
class SettingsAPI
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function handleSettingsTask($request, $args, $body = null)
|
||||||
|
{
|
||||||
|
$task = $args["fourth"];
|
||||||
|
switch ($task) {
|
||||||
|
case "publish":
|
||||||
|
//check settings to see if site is a one pager
|
||||||
|
$config = new Settings();
|
||||||
|
$settings = $config->getSettings();
|
||||||
|
$theme = $settings["global"]["theme"];
|
||||||
|
$themeConfig = json_decode(
|
||||||
|
file_get_contents("../content/themes/" . $theme . "/theme.json"),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
//check to see if dynamic rendering is active
|
||||||
|
if (
|
||||||
|
isset($settings["global"]["dynamicRender"]) &&
|
||||||
|
$settings["global"]["dynamicRender"] === "true"
|
||||||
|
) {
|
||||||
|
$result = [
|
||||||
|
"message" => "Dynamic Render Active! You're good!",
|
||||||
|
"type" => "RENDER_SUCCESS",
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
$render = new Render();
|
||||||
|
if (isset($themeConfig["render"])) {
|
||||||
|
if (!$themeConfig["render"] || $themeConfig["render"] === "false") {
|
||||||
|
$render->renderIndex();
|
||||||
|
$result = [
|
||||||
|
"message" => "Index Rendered. HAND CLAPS",
|
||||||
|
"type" => "RENDER_SUCCESS",
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
$render->renderTags();
|
||||||
|
$render->renderArchive();
|
||||||
|
$render->renderPages();
|
||||||
|
$result = [
|
||||||
|
"message" => "Site Rendered. GOOD EFFORT",
|
||||||
|
"type" => "RENDER_SUCCESS",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// just incase the render flag is missing
|
||||||
|
$render->renderTags();
|
||||||
|
$render->renderArchive();
|
||||||
|
$render->renderPages();
|
||||||
|
$result = [
|
||||||
|
"message" => "Site Rendered. GOOD EFFORT",
|
||||||
|
"type" => "RENDER_SUCCESS",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//if render flag is set and false, just render index page for one page sites
|
||||||
|
//otherwise, render all pages according to theme template files
|
||||||
|
|
||||||
|
break;
|
||||||
|
case "add-avatar":
|
||||||
|
$result = ImagesAPI::uploadImage($request, "avatar");
|
||||||
|
break;
|
||||||
|
case "add-feature-background":
|
||||||
|
$result = ImagesAPI::uploadImage($request, "background");
|
||||||
|
break;
|
||||||
|
case "sync":
|
||||||
|
Settings::sync($body);
|
||||||
|
$result = [
|
||||||
|
"message" => "Settings Synced. You're doing great!",
|
||||||
|
"type" => "settingsUpdated",
|
||||||
|
];
|
||||||
|
break;
|
||||||
|
case "nav-sync":
|
||||||
|
Settings::navSync($body);
|
||||||
|
$result = [
|
||||||
|
"message" => "Navigation updated. Very slick!",
|
||||||
|
"type" => "menuUpdated",
|
||||||
|
];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$result = [
|
||||||
|
"message" => "Hm, no task. That's unfortunate",
|
||||||
|
"type" => "TASK_NONE",
|
||||||
|
];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getInfo($request, $args)
|
||||||
|
{
|
||||||
|
$task = $args["fourth"];
|
||||||
|
switch ($task) {
|
||||||
|
case "site":
|
||||||
|
$config = new Settings();
|
||||||
|
$settings = $config->getSettings();
|
||||||
|
$data = [
|
||||||
|
"title" => $settings["global"]["title"],
|
||||||
|
"base_url" => $settings["global"]["base_url"],
|
||||||
|
"description" => $settings["global"]["descriptions"],
|
||||||
|
];
|
||||||
|
$result = [
|
||||||
|
"message" => "Settings Found",
|
||||||
|
"type" => "GET_SETTINGS",
|
||||||
|
"data" => $data,
|
||||||
|
];
|
||||||
|
break;
|
||||||
|
case "member":
|
||||||
|
if (Session::active()) {
|
||||||
|
$member = $member = Session::get("member");
|
||||||
|
$data = ["handle" => $member["handle"], "email" => $member["email"]];
|
||||||
|
$result = [
|
||||||
|
"message" => "Member Info Found",
|
||||||
|
"type" => "GET_MEMBER_INFO",
|
||||||
|
"data" => $data,
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
$result = [
|
||||||
|
"message" => "Not logged in. C'mon, bruh",
|
||||||
|
"type" => "TASK_NONE",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$result = [
|
||||||
|
"message" => "No Settings found. Frowny Face",
|
||||||
|
"type" => "TASK_NONE",
|
||||||
|
];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function createBackup()
|
||||||
|
{
|
||||||
|
$result = Maintenance::makeBackup();
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
}
|
@ -1,227 +0,0 @@
|
|||||||
<?php
|
|
||||||
use Psr\Http\Message\ResponseInterface;
|
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
|
||||||
|
|
||||||
include "../brain/api/v1/AuthAPI.inc.php";
|
|
||||||
include "../brain/api/v1/ImagesAPI.inc.php";
|
|
||||||
include "../brain/api/v1/PagesAPI.inc.php";
|
|
||||||
include "../brain/api/v1/SettingsAPI.inc.php";
|
|
||||||
include "../brain/api/v1/InitAPI.inc.php";
|
|
||||||
include "../brain/api/v1/MailerAPI.inc.php";
|
|
||||||
|
|
||||||
class APIControl
|
|
||||||
{
|
|
||||||
public static function get(
|
|
||||||
ServerRequestInterface $request,
|
|
||||||
ResponseInterface $response,
|
|
||||||
array $args
|
|
||||||
): ResponseInterface {
|
|
||||||
$filename = "";
|
|
||||||
switch (isset($args["third"]) ? $args["third"] : "none") {
|
|
||||||
case "status":
|
|
||||||
$result = AuthAPI::status();
|
|
||||||
|
|
||||||
break;
|
|
||||||
case "page":
|
|
||||||
//echo
|
|
||||||
if (Member::verifyKey($_GET["key"])) {
|
|
||||||
$result = PagesAPI::getPageContent($request, $args);
|
|
||||||
} else {
|
|
||||||
$result = [
|
|
||||||
"message" => "API access denied, homie",
|
|
||||||
"type" => "API_ERROR",
|
|
||||||
];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "settings":
|
|
||||||
$token = $request->getHeader("fipamo-access-token");
|
|
||||||
//Verify token to get site info
|
|
||||||
if (isset($token[0])) {
|
|
||||||
if (Session::verifyToken($token[0])) {
|
|
||||||
$result = SettingsAPI::getInfo($request, $args);
|
|
||||||
} else {
|
|
||||||
$result = [
|
|
||||||
"message" => "Invalid token, API access denied, homie",
|
|
||||||
"type" => "API_ERROR",
|
|
||||||
];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$result = [
|
|
||||||
"message" => "No token, API access denied, homie",
|
|
||||||
"type" => "API_ERROR",
|
|
||||||
];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "files":
|
|
||||||
if (Session::active()) {
|
|
||||||
if ($args["third"] == "backup") {
|
|
||||||
$filename = "../config/backups/latest_backup.zip";
|
|
||||||
if (file_exists($filename)) {
|
|
||||||
header("Content-Type: application/zip");
|
|
||||||
header(
|
|
||||||
'Content-Disposition: attachment; filename="' .
|
|
||||||
basename($filename) .
|
|
||||||
'"'
|
|
||||||
);
|
|
||||||
header("Content-Length: " . filesize($filename));
|
|
||||||
|
|
||||||
flush();
|
|
||||||
// return readfile($filename);
|
|
||||||
//readfile($filename);
|
|
||||||
// delete file
|
|
||||||
//unlink($filename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$result = [
|
|
||||||
"message" => "API access denied, homie",
|
|
||||||
"type" => "API_ERROR",
|
|
||||||
];
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$freshResponse = $response;
|
|
||||||
|
|
||||||
if ($args["third"] == "files") {
|
|
||||||
$freshResponse
|
|
||||||
->getBody()
|
|
||||||
->write(file_get_contents("../config/backups/latest_back.zip"));
|
|
||||||
|
|
||||||
$freshResponse->withHeader("Content-Type", "application/zip");
|
|
||||||
return $freshResponse->withAddedHeader(
|
|
||||||
"Content-Disposition",
|
|
||||||
"attachment; filename=latest_backup.zip"
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
$response->getBody()->write(json_encode($result));
|
|
||||||
return $response->withHeader("Content-Type", "application/json");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static function post(
|
|
||||||
ServerRequestInterface $request,
|
|
||||||
ResponseInterface $response,
|
|
||||||
array $args
|
|
||||||
): ResponseInterface {
|
|
||||||
$contentType = $request->getHeader("Content-Type");
|
|
||||||
switch ($contentType[0]) {
|
|
||||||
case "application/json":
|
|
||||||
$body = json_decode(file_get_contents("php://input"), true);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (isset($args["third"]) ? $args["third"] : "none") {
|
|
||||||
case "restore": //move to 'api/auth'
|
|
||||||
case "init": //move to 'api/auth'
|
|
||||||
$task = $args["third"];
|
|
||||||
$result = InitApi::handleInitTasks(
|
|
||||||
$task,
|
|
||||||
$task == "init" ? $body : $request
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case "backup": //move to 'api/auth'
|
|
||||||
$token = $request->getHeader("fipamo-access-token");
|
|
||||||
//Verify token for admin tasks
|
|
||||||
$result = SettingsAPI::createBackup();
|
|
||||||
/*
|
|
||||||
|
|
||||||
if (Session::verifyToken($token[0])) {
|
|
||||||
$result = SettingsAPI::createBackup();
|
|
||||||
} else {
|
|
||||||
$result = [
|
|
||||||
"message" => "API access denied, homie",
|
|
||||||
"type" => "API_ERROR",
|
|
||||||
];
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
break;
|
|
||||||
case "login": //move to 'api/auth'
|
|
||||||
//check if request is remote and if so, verify token
|
|
||||||
if ($body["remote"] || $body["remote"] == "true") {
|
|
||||||
if (Member::verifyKey($body["key"])) {
|
|
||||||
$result = AuthAPI::login($body);
|
|
||||||
} else {
|
|
||||||
$result = [
|
|
||||||
"message" => "API access denied, homie",
|
|
||||||
"type" => "API_ERROR",
|
|
||||||
];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//request is local, so it's cool
|
|
||||||
$result = AuthAPI::login($body);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case "logout": //move to 'api/auth'
|
|
||||||
$result = AuthAPI::logout($body);
|
|
||||||
break;
|
|
||||||
case "get-secret": //move to 'api/auth'
|
|
||||||
$result = AuthAPI::requestSecret($body);
|
|
||||||
break;
|
|
||||||
case "reset-password": //move to 'api/auth'
|
|
||||||
$result = AuthAPI::resetPassword($body);
|
|
||||||
break;
|
|
||||||
case "page":
|
|
||||||
$token = $request->getHeader("fipamo-access-token");
|
|
||||||
//Verify token for admin tasks
|
|
||||||
if (isset($token[0])) {
|
|
||||||
if (Session::verifyToken($token[0])) {
|
|
||||||
$result = PagesAPI::handlePageTask($request, $args);
|
|
||||||
} else {
|
|
||||||
$result = [
|
|
||||||
"message" => "Invalid token, API access denied, homie",
|
|
||||||
"type" => "API_ERROR",
|
|
||||||
];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$result = [
|
|
||||||
"message" => "No token, API access denied, homie",
|
|
||||||
"type" => "API_ERROR",
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case "settings":
|
|
||||||
if (isset($body)) {
|
|
||||||
$postBody = $body;
|
|
||||||
} else {
|
|
||||||
$postBody = null;
|
|
||||||
}
|
|
||||||
$task = $args["fourth"];
|
|
||||||
if ($task == "add-feature-background" || $task == "add-avatar") {
|
|
||||||
$result = SettingsAPI::handleSettingsTask($request, $args, $postBody);
|
|
||||||
} else {
|
|
||||||
$token = $request->getHeader("fipamo-access-token");
|
|
||||||
if (Session::verifyToken($token[0])) {
|
|
||||||
$result = SettingsAPI::handleSettingsTask(
|
|
||||||
$request,
|
|
||||||
$args,
|
|
||||||
$postBody
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
$result = [
|
|
||||||
"message" => "API access denied, homie",
|
|
||||||
"type" => "API_ERROR",
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case "mailer":
|
|
||||||
$result = MailerAPI::handleMail($request, $body, $response);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$result = [
|
|
||||||
"message" => "Oh, nothing to do. That's unfortunate",
|
|
||||||
"type" => "TASK_NONE",
|
|
||||||
];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$response->getBody()->write(json_encode($result));
|
|
||||||
return $response->withHeader("Content-Type", "application/json");
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,232 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace brain\controller;
|
||||||
|
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
use brain\api\v1\AuthAPI;
|
||||||
|
use brain\api\v1\ImagesAPI;
|
||||||
|
use brain\api\v1\PagesAPI;
|
||||||
|
use brain\api\v1\SettingsAPI;
|
||||||
|
use brain\api\v1\InitAPI;
|
||||||
|
use brain\api\v1\MailerAPI;
|
||||||
|
use brain\data\Member;
|
||||||
|
use brain\data\Session;
|
||||||
|
|
||||||
|
class APIControl
|
||||||
|
{
|
||||||
|
public static function get(
|
||||||
|
ServerRequestInterface $request,
|
||||||
|
ResponseInterface $response,
|
||||||
|
array $args
|
||||||
|
): ResponseInterface {
|
||||||
|
$filename = "";
|
||||||
|
switch (isset($args["third"]) ? $args["third"] : "none") {
|
||||||
|
case "status":
|
||||||
|
$result = AuthAPI::status();
|
||||||
|
|
||||||
|
break;
|
||||||
|
case "page":
|
||||||
|
//echo
|
||||||
|
if (Member::verifyKey($_GET["key"])) {
|
||||||
|
$result = PagesAPI::getPageContent($request, $args);
|
||||||
|
} else {
|
||||||
|
$result = [
|
||||||
|
"message" => "API access denied, homie",
|
||||||
|
"type" => "API_ERROR",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "settings":
|
||||||
|
$token = $request->getHeader("fipamo-access-token");
|
||||||
|
//Verify token to get site info
|
||||||
|
if (isset($token[0])) {
|
||||||
|
if (Session::verifyToken($token[0])) {
|
||||||
|
$result = SettingsAPI::getInfo($request, $args);
|
||||||
|
} else {
|
||||||
|
$result = [
|
||||||
|
"message" => "Invalid token, API access denied, homie",
|
||||||
|
"type" => "API_ERROR",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$result = [
|
||||||
|
"message" => "No token, API access denied, homie",
|
||||||
|
"type" => "API_ERROR",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "files":
|
||||||
|
if (Session::active()) {
|
||||||
|
if ($args["third"] == "backup") {
|
||||||
|
$filename = "../config/backups/latest_backup.zip";
|
||||||
|
if (file_exists($filename)) {
|
||||||
|
header("Content-Type: application/zip");
|
||||||
|
header(
|
||||||
|
'Content-Disposition: attachment; filename="' .
|
||||||
|
basename($filename) .
|
||||||
|
'"'
|
||||||
|
);
|
||||||
|
header("Content-Length: " . filesize($filename));
|
||||||
|
|
||||||
|
flush();
|
||||||
|
// return readfile($filename);
|
||||||
|
//readfile($filename);
|
||||||
|
// delete file
|
||||||
|
//unlink($filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$result = [
|
||||||
|
"message" => "API access denied, homie",
|
||||||
|
"type" => "API_ERROR",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
// no break
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$freshResponse = $response;
|
||||||
|
|
||||||
|
if ($args["third"] == "files") {
|
||||||
|
$freshResponse
|
||||||
|
->getBody()
|
||||||
|
->write(file_get_contents("../config/backups/latest_back.zip"));
|
||||||
|
|
||||||
|
$freshResponse->withHeader("Content-Type", "application/zip");
|
||||||
|
return $freshResponse->withAddedHeader(
|
||||||
|
"Content-Disposition",
|
||||||
|
"attachment; filename=latest_backup.zip"
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$response->getBody()->write(json_encode($result));
|
||||||
|
return $response->withHeader("Content-Type", "application/json");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static function post(
|
||||||
|
ServerRequestInterface $request,
|
||||||
|
ResponseInterface $response,
|
||||||
|
array $args
|
||||||
|
): ResponseInterface {
|
||||||
|
$contentType = $request->getHeader("Content-Type");
|
||||||
|
switch ($contentType[0]) {
|
||||||
|
case "application/json":
|
||||||
|
$body = json_decode(file_get_contents("php://input"), true);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (isset($args["third"]) ? $args["third"] : "none") {
|
||||||
|
case "restore": //move to 'api/auth'
|
||||||
|
case "init": //move to 'api/auth'
|
||||||
|
$task = $args["third"];
|
||||||
|
$result = InitApi::handleInitTasks(
|
||||||
|
$task,
|
||||||
|
$task == "init" ? $body : $request
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case "backup": //move to 'api/auth'
|
||||||
|
$token = $request->getHeader("fipamo-access-token");
|
||||||
|
//Verify token for admin tasks
|
||||||
|
$result = SettingsAPI::createBackup();
|
||||||
|
/*
|
||||||
|
|
||||||
|
if (Session::verifyToken($token[0])) {
|
||||||
|
$result = SettingsAPI::createBackup();
|
||||||
|
} else {
|
||||||
|
$result = [
|
||||||
|
"message" => "API access denied, homie",
|
||||||
|
"type" => "API_ERROR",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
case "login": //move to 'api/auth'
|
||||||
|
//check if request is remote and if so, verify token
|
||||||
|
if ($body["remote"] || $body["remote"] == "true") {
|
||||||
|
if (Member::verifyKey($body["key"])) {
|
||||||
|
$result = AuthAPI::login($body);
|
||||||
|
} else {
|
||||||
|
$result = [
|
||||||
|
"message" => "API access denied, homie",
|
||||||
|
"type" => "API_ERROR",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//request is local, so it's cool
|
||||||
|
$result = AuthAPI::login($body);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case "logout": //move to 'api/auth'
|
||||||
|
$result = AuthAPI::logout($body);
|
||||||
|
break;
|
||||||
|
case "get-secret": //move to 'api/auth'
|
||||||
|
$result = AuthAPI::requestSecret($body);
|
||||||
|
break;
|
||||||
|
case "reset-password": //move to 'api/auth'
|
||||||
|
$result = AuthAPI::resetPassword($body);
|
||||||
|
break;
|
||||||
|
case "page":
|
||||||
|
$token = $request->getHeader("fipamo-access-token");
|
||||||
|
//Verify token for admin tasks
|
||||||
|
if (isset($token[0])) {
|
||||||
|
if (Session::verifyToken($token[0])) {
|
||||||
|
$result = PagesAPI::handlePageTask($request, $args);
|
||||||
|
} else {
|
||||||
|
$result = [
|
||||||
|
"message" => "Invalid token, API access denied, homie",
|
||||||
|
"type" => "API_ERROR",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$result = [
|
||||||
|
"message" => "No token, API access denied, homie",
|
||||||
|
"type" => "API_ERROR",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case "settings":
|
||||||
|
if (isset($body)) {
|
||||||
|
$postBody = $body;
|
||||||
|
} else {
|
||||||
|
$postBody = null;
|
||||||
|
}
|
||||||
|
$task = $args["fourth"];
|
||||||
|
if ($task == "add-feature-background" || $task == "add-avatar") {
|
||||||
|
$result = SettingsAPI::handleSettingsTask($request, $args, $postBody);
|
||||||
|
} else {
|
||||||
|
$token = $request->getHeader("fipamo-access-token");
|
||||||
|
if (Session::verifyToken($token[0])) {
|
||||||
|
$result = SettingsAPI::handleSettingsTask(
|
||||||
|
$request,
|
||||||
|
$args,
|
||||||
|
$postBody
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$result = [
|
||||||
|
"message" => "API access denied, homie",
|
||||||
|
"type" => "API_ERROR",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case "mailer":
|
||||||
|
$result = MailerAPI::handleMail($request, $body, $response);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$result = [
|
||||||
|
"message" => "Oh, nothing to do. That's unfortunate",
|
||||||
|
"type" => "TASK_NONE",
|
||||||
|
];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$response->getBody()->write(json_encode($result));
|
||||||
|
return $response->withHeader("Content-Type", "application/json");
|
||||||
|
}
|
||||||
|
}
|
@ -1,189 +0,0 @@
|
|||||||
<?php
|
|
||||||
use Psr\Http\Message\ResponseInterface;
|
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
|
||||||
use Slim\Views\Twig;
|
|
||||||
|
|
||||||
include "../brain/data/Book.inc.php";
|
|
||||||
|
|
||||||
class DashControl
|
|
||||||
{
|
|
||||||
public static function start(
|
|
||||||
ServerRequestInterface $request,
|
|
||||||
ResponseInterface $response,
|
|
||||||
array $args
|
|
||||||
): ResponseInterface {
|
|
||||||
$view = Twig::fromRequest($request);
|
|
||||||
$pageOptions = [];
|
|
||||||
$template = "";
|
|
||||||
if (Setup::status()) {
|
|
||||||
switch (isset($args["second"]) ? $args["second"] : "index") {
|
|
||||||
case "settings":
|
|
||||||
if (Session::active()) {
|
|
||||||
$config = new Settings();
|
|
||||||
$settings = $config->getSettings();
|
|
||||||
$themes = (new Themes())->getThemes(); //$config->getThemes();
|
|
||||||
$template = "dash/settings.twig";
|
|
||||||
$member = Session::get("member");
|
|
||||||
$form_token = Session::get("form_token");
|
|
||||||
$updated = new \Moment\Moment($settings["global"]["last_backup"]);
|
|
||||||
$pageOptions = [
|
|
||||||
"title" => "Dash Settings",
|
|
||||||
"private" => $settings["global"]["private"],
|
|
||||||
"renderOnSave" => $settings["global"]["renderOnSave"],
|
|
||||||
"background" => $settings["global"]["background"],
|
|
||||||
"member" => $member,
|
|
||||||
"ftoken" => $form_token,
|
|
||||||
"siteTitle" => $settings["global"]["title"],
|
|
||||||
"baseUrl" => $settings["global"]["base_url"],
|
|
||||||
"desc" => $settings["global"]["descriptions"],
|
|
||||||
"lastBackup" => $updated->format("Y M D d"),
|
|
||||||
"currentTheme" => $settings["global"]["theme"],
|
|
||||||
"themes" => $themes,
|
|
||||||
"apiStatus" => isset($settings["global"]["externalAPI"])
|
|
||||||
? $settings["global"]["externalAPI"]
|
|
||||||
: "false",
|
|
||||||
"dynamicRenderStatus" => isset(
|
|
||||||
$settings["global"]["dynamicRender"]
|
|
||||||
)
|
|
||||||
? $settings["global"]["dynamicRender"]
|
|
||||||
: "false",
|
|
||||||
"mailOption" => $settings["email"]["active"],
|
|
||||||
"mailConfig" => $settings["email"],
|
|
||||||
"status" => Session::active(),
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
header("Location: /dashboard");
|
|
||||||
die();
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case "navigation":
|
|
||||||
if (Session::active()) {
|
|
||||||
$config = new Settings();
|
|
||||||
$settings = $config->getSettings();
|
|
||||||
$template = "dash/navigation.twig";
|
|
||||||
$pageOptions = [
|
|
||||||
"title" => "Edit Dash Navigation",
|
|
||||||
"status" => Session::active(),
|
|
||||||
"menu" => $settings["menu"],
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
header("Location: /dashboard");
|
|
||||||
die();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "pages":
|
|
||||||
if (Session::active()) {
|
|
||||||
$currentPage = isset($args["fourth"]) ? $args["fourth"] : 1;
|
|
||||||
$filter = isset($args["third"]) ? $args["third"] : "all";
|
|
||||||
$data = (new Book())->getPages($currentPage, 4, $filter);
|
|
||||||
$template = "dash/book.twig";
|
|
||||||
$pageOptions = [
|
|
||||||
"entryCount" => $data["entryCount"],
|
|
||||||
"numOfPages" => $data["numOfPages"],
|
|
||||||
"currentPage" => $currentPage,
|
|
||||||
"filter" => $data["paginate"]["sort"],
|
|
||||||
"stats" => $data["stats"],
|
|
||||||
"pages" => $data["pages"],
|
|
||||||
"paginate" => $data["paginate"],
|
|
||||||
"status" => Session::active(),
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
header("Location: /dashboard");
|
|
||||||
die();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "page":
|
|
||||||
if (Session::active()) {
|
|
||||||
$template = "dash/page-edit.twig";
|
|
||||||
$mode = $args["third"];
|
|
||||||
$uuid = $args["fourth"];
|
|
||||||
|
|
||||||
switch ($mode) {
|
|
||||||
case "edit":
|
|
||||||
$page = (new Book())->findPageById($uuid);
|
|
||||||
$views = [];
|
|
||||||
if (str_contains($page["layout"], "index")) {
|
|
||||||
$views = (new Themes())->getCustomIndex();
|
|
||||||
} else {
|
|
||||||
$views = (new Themes())->getCustomViews();
|
|
||||||
}
|
|
||||||
$pageOptions = [
|
|
||||||
"title" => "Fipamo | Edit Page",
|
|
||||||
"page" => $page,
|
|
||||||
"mode" => $mode,
|
|
||||||
"token" => Session::get("form_token"),
|
|
||||||
"status" => Session::active(),
|
|
||||||
"views" => $views,
|
|
||||||
];
|
|
||||||
break;
|
|
||||||
case "preview":
|
|
||||||
$config = new Settings();
|
|
||||||
$settings = $config->getSettings();
|
|
||||||
$loader = new \Twig\Loader\FilesystemLoader(
|
|
||||||
"../content/themes"
|
|
||||||
);
|
|
||||||
$display = new \Twig\Environment($loader, []);
|
|
||||||
|
|
||||||
$book = new Book();
|
|
||||||
$page = $book->findPageById($uuid);
|
|
||||||
$pageOptions = Sorting::page($page);
|
|
||||||
$preview =
|
|
||||||
$settings["global"]["theme"] .
|
|
||||||
"/" .
|
|
||||||
$page["layout"] .
|
|
||||||
".twig";
|
|
||||||
$html = $display->render($preview, $pageOptions);
|
|
||||||
$response->getBody()->write($html);
|
|
||||||
return $response;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$pageOptions = [
|
|
||||||
"title" => "Fipamo | Create Page",
|
|
||||||
"token" => Session::get("form_token"),
|
|
||||||
"mode" => $mode,
|
|
||||||
"status" => Session::active(),
|
|
||||||
];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
header("Location: /dashboard");
|
|
||||||
die();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "logout":
|
|
||||||
Session::kill();
|
|
||||||
header("Location: /dashboard");
|
|
||||||
die();
|
|
||||||
break;
|
|
||||||
case "reset-password":
|
|
||||||
$template = "dash/reset-password.twig";
|
|
||||||
$pageOptions = [
|
|
||||||
"title" => "Reset Password",
|
|
||||||
];
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
$template = "dash/start.twig";
|
|
||||||
if (Session::active()) {
|
|
||||||
$pageOptions = [
|
|
||||||
"title" => "Welcome Back",
|
|
||||||
"status" => Session::active(),
|
|
||||||
"data" => (new Book())->getPages(1, 4),
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
$pageOptions = [
|
|
||||||
"title" => "Welcome to Fipamo",
|
|
||||||
"status" => Session::active(),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$template = "dash/init.twig";
|
|
||||||
$pageOptions = ["title" => "Fipamo Setup"];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $view->render($response, $template, $pageOptions);
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,218 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace brain\controller;
|
||||||
|
|
||||||
|
use brain\data\Book;
|
||||||
|
use brain\data\Session;
|
||||||
|
use brain\data\Settings;
|
||||||
|
use brain\data\Themes;
|
||||||
|
use brain\utility\Setup;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
use Slim\Views\Twig;
|
||||||
|
|
||||||
|
class DashControl
|
||||||
|
{
|
||||||
|
public static function start(
|
||||||
|
ServerRequestInterface $request,
|
||||||
|
ResponseInterface $response,
|
||||||
|
array $args
|
||||||
|
): ResponseInterface {
|
||||||
|
$view = Twig::fromRequest($request);
|
||||||
|
$pageOptions = [];
|
||||||
|
$template = '';
|
||||||
|
if (Setup::status()) {
|
||||||
|
switch (isset($args['second']) ? $args['second'] : 'index') {
|
||||||
|
case 'settings':
|
||||||
|
if (Session::active()) {
|
||||||
|
$config = new Settings();
|
||||||
|
$settings = $config->getSettings();
|
||||||
|
$themes = (new Themes())->getThemes(); // $config->getThemes();
|
||||||
|
$template = 'dash/settings.twig';
|
||||||
|
$member = Session::get('member');
|
||||||
|
$form_token = Session::get('form_token');
|
||||||
|
$updated = new \Moment\Moment($settings['global']['last_backup']);
|
||||||
|
$pageOptions = [
|
||||||
|
'title' => 'Dash Settings',
|
||||||
|
'private' => $settings['global']['private'],
|
||||||
|
'renderOnSave' => $settings['global']['renderOnSave'],
|
||||||
|
'background' => $settings['global']['background'],
|
||||||
|
'member' => $member,
|
||||||
|
'ftoken' => $form_token,
|
||||||
|
'siteTitle' => $settings['global']['title'],
|
||||||
|
'baseUrl' => $settings['global']['base_url'],
|
||||||
|
'desc' => $settings['global']['descriptions'],
|
||||||
|
'lastBackup' => $updated->format('Y M D d'),
|
||||||
|
'currentTheme' => $settings['global']['theme'],
|
||||||
|
'themes' => $themes,
|
||||||
|
'apiStatus' => isset($settings['global']['externalAPI'])
|
||||||
|
? $settings['global']['externalAPI']
|
||||||
|
: 'false',
|
||||||
|
'dynamicRenderStatus' => isset(
|
||||||
|
$settings['global']['dynamicRender']
|
||||||
|
)
|
||||||
|
? $settings['global']['dynamicRender']
|
||||||
|
: 'false',
|
||||||
|
'mailOption' => $settings['email']['active'],
|
||||||
|
'mailConfig' => $settings['email'],
|
||||||
|
'status' => Session::active(),
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
header('Location: /dashboard');
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 'navigation':
|
||||||
|
if (Session::active()) {
|
||||||
|
$config = new Settings();
|
||||||
|
$settings = $config->getSettings();
|
||||||
|
$template = 'dash/navigation.twig';
|
||||||
|
$pageOptions = [
|
||||||
|
'title' => 'Edit Dash Navigation',
|
||||||
|
'status' => Session::active(),
|
||||||
|
'menu' => $settings['menu'],
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
header('Location: /dashboard');
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'pages':
|
||||||
|
if (Session::active()) {
|
||||||
|
$currentPage = isset($args['fourth']) ? $args['fourth'] : 1;
|
||||||
|
$filter = isset($args['third']) ? $args['third'] : 'all';
|
||||||
|
$data = (new Book())->getPages($currentPage, 4, $filter);
|
||||||
|
$template = 'dash/book.twig';
|
||||||
|
$pageOptions = [
|
||||||
|
'title' => 'Contents',
|
||||||
|
'entryCount' => $data['entryCount'],
|
||||||
|
'numOfPages' => $data['numOfPages'],
|
||||||
|
'currentPage' => $currentPage,
|
||||||
|
'filter' => $data['paginate']['sort'],
|
||||||
|
'stats' => $data['stats'],
|
||||||
|
'pages' => $data['pages'],
|
||||||
|
'paginate' => $data['paginate'],
|
||||||
|
'status' => Session::active(),
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
header('Location: /dashboard');
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'page':
|
||||||
|
if (Session::active()) {
|
||||||
|
$template = 'dash/page-edit.twig';
|
||||||
|
$mode = $args['third'];
|
||||||
|
$uuid = $args['fourth'];
|
||||||
|
|
||||||
|
switch ($mode) {
|
||||||
|
case 'edit':
|
||||||
|
$page = (new Book())->findPageById($uuid);
|
||||||
|
$views = [];
|
||||||
|
if (str_contains($page['layout'], 'index')) {
|
||||||
|
$views = (new Themes())->getCustomIndex();
|
||||||
|
} else {
|
||||||
|
$views = (new Themes())->getCustomViews();
|
||||||
|
}
|
||||||
|
|
||||||
|
$imageList = explode(',', $page['feature']);
|
||||||
|
$fileList = explode(',', $page['files']);
|
||||||
|
|
||||||
|
$images = [];
|
||||||
|
$files = [];
|
||||||
|
foreach ($imageList as $item) {
|
||||||
|
$image = trim($item);
|
||||||
|
if (!empty($image)) {
|
||||||
|
array_push($images, $image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($fileList as $item) {
|
||||||
|
$file = trim($item);
|
||||||
|
if (!empty($file)) {
|
||||||
|
array_push($files, $file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$pageOptions = [
|
||||||
|
'title' => 'Fipamo | Edit Page',
|
||||||
|
'page' => $page,
|
||||||
|
'mode' => $mode,
|
||||||
|
'token' => Session::get('form_token'),
|
||||||
|
'status' => Session::active(),
|
||||||
|
'images' => $images,
|
||||||
|
'files' => $files,
|
||||||
|
'views' => $views,
|
||||||
|
];
|
||||||
|
break;
|
||||||
|
case 'preview':
|
||||||
|
$config = new Settings();
|
||||||
|
$settings = $config->getSettings();
|
||||||
|
$loader = new \Twig\Loader\FilesystemLoader(
|
||||||
|
'../content/themes'
|
||||||
|
);
|
||||||
|
$display = new \Twig\Environment($loader, []);
|
||||||
|
|
||||||
|
$book = new Book();
|
||||||
|
$page = $book->findPageById($uuid);
|
||||||
|
$pageOptions = Sorting::page($page);
|
||||||
|
$preview =
|
||||||
|
$settings['global']['theme'].
|
||||||
|
'/'.
|
||||||
|
$page['layout'].
|
||||||
|
'.twig';
|
||||||
|
$html = $display->render($preview, $pageOptions);
|
||||||
|
$response->getBody()->write($html);
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$pageOptions = [
|
||||||
|
'title' => 'Fipamo | Create Page',
|
||||||
|
'token' => Session::get('form_token'),
|
||||||
|
'mode' => $mode,
|
||||||
|
'status' => Session::active(),
|
||||||
|
];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
header('Location: /dashboard');
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'logout':
|
||||||
|
Session::kill();
|
||||||
|
header('Location: /dashboard');
|
||||||
|
exit();
|
||||||
|
break;
|
||||||
|
case 'reset-password':
|
||||||
|
$template = 'dash/reset-password.twig';
|
||||||
|
$pageOptions = [
|
||||||
|
'title' => 'Reset Password',
|
||||||
|
];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$template = 'dash/start.twig';
|
||||||
|
if (Session::active()) {
|
||||||
|
$pageOptions = [
|
||||||
|
'title' => 'Welcome Back',
|
||||||
|
'status' => Session::active(),
|
||||||
|
'data' => (new Book())->getPages(1, 4),
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
$pageOptions = [
|
||||||
|
'title' => 'Welcome to Fipamo',
|
||||||
|
'status' => Session::active(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$template = 'dash/init.twig';
|
||||||
|
$pageOptions = ['title' => 'Fipamo Setup'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $view->render($response, $template, $pageOptions);
|
||||||
|
}
|
||||||
|
}
|
@ -1,107 +0,0 @@
|
|||||||
<?php
|
|
||||||
use Psr\Http\Message\ResponseInterface;
|
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
|
||||||
use Slim\Views\Twig;
|
|
||||||
use function _\find;
|
|
||||||
|
|
||||||
class IndexControl
|
|
||||||
{
|
|
||||||
public static function start(
|
|
||||||
ServerRequestInterface $request,
|
|
||||||
ResponseInterface $response,
|
|
||||||
array $args
|
|
||||||
): ResponseInterface {
|
|
||||||
//unset($_SESSION);
|
|
||||||
$config = new Settings();
|
|
||||||
$settings = $config->getSettings();
|
|
||||||
$view = Twig::fromRequest($request);
|
|
||||||
//checks dynamic render flag for site render status
|
|
||||||
if ($settings["global"]["dynamicRender"]) {
|
|
||||||
if ($settings["global"]["dynamicRender"] == "true") {
|
|
||||||
$loader = new \Twig\Loader\FilesystemLoader("../content/themes");
|
|
||||||
$display = new \Twig\Environment($loader, []);
|
|
||||||
$template = "";
|
|
||||||
$pageOptions = [];
|
|
||||||
|
|
||||||
$pageInfo = [
|
|
||||||
"keywords" => isset($settings["global"]["keywords"])
|
|
||||||
? $settings["global"]["keywords"]
|
|
||||||
: "fipamo, blog, jamstack, php, markdown, js",
|
|
||||||
"description" => $settings["global"]["descriptions"],
|
|
||||||
"image" =>
|
|
||||||
$settings["global"]["base_url"] . $settings["global"]["background"],
|
|
||||||
"baseURL" => $settings["global"]["base_url"],
|
|
||||||
];
|
|
||||||
|
|
||||||
if (isset($args["first"])) {
|
|
||||||
switch ($args["first"]) {
|
|
||||||
case "tags":
|
|
||||||
$template = $settings["global"]["theme"] . "/tags.twig";
|
|
||||||
$tag = trim($args["second"]);
|
|
||||||
$taglist = Sorting::tags();
|
|
||||||
$item = find($taglist, ["tag_name" => $tag]);
|
|
||||||
$pageOptions = [
|
|
||||||
"title" => "Pages Tagged as " . $item["tag_name"],
|
|
||||||
"background" => $pageInfo["image"],
|
|
||||||
"tag_list" => $item["pages"],
|
|
||||||
"info" => $pageInfo,
|
|
||||||
"menu" => $settings["menu"],
|
|
||||||
"dynamicRender" => $settings["global"]["dynamicRender"],
|
|
||||||
];
|
|
||||||
break;
|
|
||||||
case "archives":
|
|
||||||
$archive = Sorting::archive();
|
|
||||||
$template = $settings["global"]["theme"] . "/archive.twig";
|
|
||||||
$pageOptions = [
|
|
||||||
"title" => "Archive",
|
|
||||||
"background" => $pageInfo["image"],
|
|
||||||
"archives" => $archive,
|
|
||||||
"info" => $pageInfo,
|
|
||||||
"menu" => $settings["menu"],
|
|
||||||
"dynamicRender" => $settings["global"]["dynamicRender"],
|
|
||||||
];
|
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
//check if page is a menu item, if not render along path as usual
|
|
||||||
$page = [];
|
|
||||||
$book = new Book();
|
|
||||||
if (is_numeric($args["first"])) {
|
|
||||||
$page = $book->findPageBySlug($args["third"]);
|
|
||||||
} else {
|
|
||||||
$page = $book->findPageBySlug($args["first"]);
|
|
||||||
}
|
|
||||||
$template =
|
|
||||||
$settings["global"]["theme"] . "/" . $page["layout"] . ".twig";
|
|
||||||
$pageOptions = Sorting::page($page);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//index
|
|
||||||
$template =
|
|
||||||
$settings["global"]["theme"] . "/" . $page["layout"] . ".twig";
|
|
||||||
$book = new Book("");
|
|
||||||
$page = $book->findPageBySlug();
|
|
||||||
$pageOptions = Sorting::page($page);
|
|
||||||
}
|
|
||||||
|
|
||||||
$html = $display->render($template, $pageOptions);
|
|
||||||
$response->getBody()->write($html);
|
|
||||||
return $response;
|
|
||||||
} else {
|
|
||||||
//if dynamic flag is false, load up html
|
|
||||||
$view = Twig::fromRequest($request);
|
|
||||||
$html = file_get_contents("../public/index.html");
|
|
||||||
$response->getBody()->write($html);
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//if flag is not present, default to static html
|
|
||||||
$view = Twig::fromRequest($request);
|
|
||||||
$html = file_get_contents("../public/index.html");
|
|
||||||
$response->getBody()->write($html);
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,113 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace brain\controller;
|
||||||
|
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
use Slim\Views\Twig;
|
||||||
|
use brain\data\Settings;
|
||||||
|
use brain\utility\Sorting;
|
||||||
|
|
||||||
|
use function _\find;
|
||||||
|
|
||||||
|
class IndexControl
|
||||||
|
{
|
||||||
|
public static function start(
|
||||||
|
ServerRequestInterface $request,
|
||||||
|
ResponseInterface $response,
|
||||||
|
array $args
|
||||||
|
): ResponseInterface {
|
||||||
|
//unset($_SESSION);
|
||||||
|
$config = new Settings();
|
||||||
|
$settings = $config->getSettings();
|
||||||
|
$view = Twig::fromRequest($request);
|
||||||
|
//checks dynamic render flag for site render status
|
||||||
|
if ($settings["global"]["dynamicRender"]) {
|
||||||
|
if ($settings["global"]["dynamicRender"] == "true") {
|
||||||
|
$loader = new \Twig\Loader\FilesystemLoader("../content/themes");
|
||||||
|
$display = new \Twig\Environment($loader, []);
|
||||||
|
$template = "";
|
||||||
|
$pageOptions = [];
|
||||||
|
|
||||||
|
$pageInfo = [
|
||||||
|
"keywords" => isset($settings["global"]["keywords"])
|
||||||
|
? $settings["global"]["keywords"]
|
||||||
|
: "fipamo, blog, jamstack, php, markdown, js",
|
||||||
|
"description" => $settings["global"]["descriptions"],
|
||||||
|
"image" =>
|
||||||
|
$settings["global"]["base_url"] . $settings["global"]["background"],
|
||||||
|
"baseURL" => $settings["global"]["base_url"],
|
||||||
|
];
|
||||||
|
|
||||||
|
if (isset($args["first"])) {
|
||||||
|
switch ($args["first"]) {
|
||||||
|
case "tags":
|
||||||
|
$template = $settings["global"]["theme"] . "/tags.twig";
|
||||||
|
$tag = trim($args["second"]);
|
||||||
|
$taglist = Sorting::tags();
|
||||||
|
$item = find($taglist, ["tag_name" => $tag]);
|
||||||
|
$pageOptions = [
|
||||||
|
"title" => "Pages Tagged as " . $item["tag_name"],
|
||||||
|
"background" => $pageInfo["image"],
|
||||||
|
"tag_list" => $item["pages"],
|
||||||
|
"info" => $pageInfo,
|
||||||
|
"menu" => $settings["menu"],
|
||||||
|
"dynamicRender" => $settings["global"]["dynamicRender"],
|
||||||
|
];
|
||||||
|
break;
|
||||||
|
case "archives":
|
||||||
|
$archive = Sorting::archive();
|
||||||
|
$template = $settings["global"]["theme"] . "/archive.twig";
|
||||||
|
$pageOptions = [
|
||||||
|
"title" => "Archive",
|
||||||
|
"background" => $pageInfo["image"],
|
||||||
|
"archives" => $archive,
|
||||||
|
"info" => $pageInfo,
|
||||||
|
"menu" => $settings["menu"],
|
||||||
|
"dynamicRender" => $settings["global"]["dynamicRender"],
|
||||||
|
];
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
//check if page is a menu item, if not render along path as usual
|
||||||
|
$page = [];
|
||||||
|
$book = new Book();
|
||||||
|
if (is_numeric($args["first"])) {
|
||||||
|
$page = $book->findPageBySlug($args["third"]);
|
||||||
|
} else {
|
||||||
|
$page = $book->findPageBySlug($args["first"]);
|
||||||
|
}
|
||||||
|
$template =
|
||||||
|
$settings["global"]["theme"] . "/" . $page["layout"] . ".twig";
|
||||||
|
$pageOptions = Sorting::page($page);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//index
|
||||||
|
$template =
|
||||||
|
$settings["global"]["theme"] . "/" . $page["layout"] . ".twig";
|
||||||
|
$book = new Book("");
|
||||||
|
$page = $book->findPageBySlug();
|
||||||
|
$pageOptions = Sorting::page($page);
|
||||||
|
}
|
||||||
|
|
||||||
|
$html = $display->render($template, $pageOptions);
|
||||||
|
$response->getBody()->write($html);
|
||||||
|
return $response;
|
||||||
|
} else {
|
||||||
|
//if dynamic flag is false, load up html
|
||||||
|
$view = Twig::fromRequest($request);
|
||||||
|
$html = file_get_contents("../public/index.html");
|
||||||
|
$response->getBody()->write($html);
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//if flag is not present, default to static html
|
||||||
|
$view = Twig::fromRequest($request);
|
||||||
|
$html = file_get_contents("../public/index.html");
|
||||||
|
$response->getBody()->write($html);
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,44 +0,0 @@
|
|||||||
<?php
|
|
||||||
use Psr\Http\Message\ResponseInterface;
|
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
|
||||||
|
|
||||||
include "../brain/controller/IndexControl.inc.php";
|
|
||||||
include "../brain/controller/DashControl.inc.php";
|
|
||||||
include "../brain/controller/APIControl.inc.php";
|
|
||||||
|
|
||||||
class RouteControl
|
|
||||||
{
|
|
||||||
public function get(
|
|
||||||
ServerRequestInterface $request,
|
|
||||||
ResponseInterface $response,
|
|
||||||
array $args
|
|
||||||
): ResponseInterface {
|
|
||||||
switch (isset($args["first"]) ? $args["first"] : "index") {
|
|
||||||
case "dashboard":
|
|
||||||
return DashControl::start($request, $response, $args);
|
|
||||||
break;
|
|
||||||
case "api":
|
|
||||||
return APIControl::get($request, $response, $args);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return IndexControl::start($request, $response, $args);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function post(
|
|
||||||
ServerRequestInterface $request,
|
|
||||||
ResponseInterface $response,
|
|
||||||
array $args
|
|
||||||
): ResponseInterface {
|
|
||||||
switch (isset($args["first"]) ? $args["first"] : "index") {
|
|
||||||
case "api":
|
|
||||||
return APIControl::post($request, $response, $args);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
//echo "YES";
|
|
||||||
//return IndexControl::start($request, $response, $args);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace brain\controller;
|
||||||
|
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
use brain\controller\DashControl;
|
||||||
|
use brain\controller\APIControl;
|
||||||
|
use brain\controller\IndexControl;
|
||||||
|
|
||||||
|
class RouteControl
|
||||||
|
{
|
||||||
|
public function get(
|
||||||
|
ServerRequestInterface $request,
|
||||||
|
ResponseInterface $response,
|
||||||
|
array $args
|
||||||
|
): ResponseInterface {
|
||||||
|
switch (isset($args["first"]) ? $args["first"] : "index") {
|
||||||
|
case "dashboard":
|
||||||
|
return DashControl::start($request, $response, $args);
|
||||||
|
break;
|
||||||
|
case "api":
|
||||||
|
return APIControl::get($request, $response, $args);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return IndexControl::start($request, $response, $args);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function post(
|
||||||
|
ServerRequestInterface $request,
|
||||||
|
ResponseInterface $response,
|
||||||
|
array $args
|
||||||
|
): ResponseInterface {
|
||||||
|
switch (isset($args["first"]) ? $args["first"] : "index") {
|
||||||
|
case "api":
|
||||||
|
//$result = APIControl::post($request, $response, $args);
|
||||||
|
//var_dump($result);
|
||||||
|
return APIControl::post($request, $response, $args);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
//echo "YES";
|
||||||
|
//return IndexControl::start($request, $response, $args);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,154 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use function _\find;
|
|
||||||
use ReallySimpleJWT\Token;
|
|
||||||
|
|
||||||
class Auth
|
|
||||||
{
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function sessionStatus()
|
|
||||||
{
|
|
||||||
if (isset($_SESSION["member"])) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
//return $this->secret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function status()
|
|
||||||
{
|
|
||||||
$result = "";
|
|
||||||
if (Session::active()) {
|
|
||||||
$result = true;
|
|
||||||
} else {
|
|
||||||
$result = false;
|
|
||||||
}
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function login($who)
|
|
||||||
{
|
|
||||||
//grab member list
|
|
||||||
$folks = (new Settings())->getFolks();
|
|
||||||
$found = find($folks, ["handle" => $who["handle"]]);
|
|
||||||
|
|
||||||
if ($found) {
|
|
||||||
//name is found, verify password
|
|
||||||
if (password_verify($who["password"], $found["password"])) {
|
|
||||||
$member = [
|
|
||||||
"handle" => $found["handle"],
|
|
||||||
"email" => $found["email"],
|
|
||||||
"role" => $found["role"],
|
|
||||||
"avatar" => $found["avi"],
|
|
||||||
"key" => $found["key"],
|
|
||||||
];
|
|
||||||
|
|
||||||
$token = Token::create(
|
|
||||||
$found["key"],
|
|
||||||
$found["secret"],
|
|
||||||
time() + 3600,
|
|
||||||
"localhost"
|
|
||||||
); //expires in an hour
|
|
||||||
|
|
||||||
$form_token = md5(uniqid(microtime(), true));
|
|
||||||
Session::start();
|
|
||||||
Session::set("member", $member);
|
|
||||||
Session::set("token", $token);
|
|
||||||
Session::set("form_token", $form_token);
|
|
||||||
|
|
||||||
$result = "good_login";
|
|
||||||
} else {
|
|
||||||
$result = "bad_pass";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//if name is not found
|
|
||||||
$result = "no_name";
|
|
||||||
}
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function findSecret($data)
|
|
||||||
{
|
|
||||||
$result = [];
|
|
||||||
$folks = (new Settings())->getFolks();
|
|
||||||
|
|
||||||
if (
|
|
||||||
!empty($data["email"]) &&
|
|
||||||
filter_var($data["email"], FILTER_VALIDATE_EMAIL)
|
|
||||||
) {
|
|
||||||
$found = find($folks, ["email" => $data["email"]]);
|
|
||||||
if ($found) {
|
|
||||||
//if email is cool, check mail relay status
|
|
||||||
//if set up, send secret there, if not just return it
|
|
||||||
$config = new Settings();
|
|
||||||
$settings = $config->getSettings();
|
|
||||||
$email = $settings["email"]["active"];
|
|
||||||
if ($email != "option-none") {
|
|
||||||
$data["mail_task"] = "SEND_SECRET";
|
|
||||||
$data["secret"] = $found["secret"];
|
|
||||||
$result = Mailer::sendmail($data);
|
|
||||||
} else {
|
|
||||||
$result = [
|
|
||||||
"message" => "Valid email, but no email set up!",
|
|
||||||
"type" => "secretFound",
|
|
||||||
"secret" => $found["secret"],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$result = [
|
|
||||||
"message" => "No valid email, no goodies, pleighboi",
|
|
||||||
"type" => "secretNotFound",
|
|
||||||
];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$result = [
|
|
||||||
"message" => "Aye, this address is not right, slick.",
|
|
||||||
"type" => "secretNotFound",
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function makeNewPassword($data)
|
|
||||||
{
|
|
||||||
//check if passwordsmatch
|
|
||||||
if ($data["newPass"] == $data["newPassConfirm"]) {
|
|
||||||
//verify secret
|
|
||||||
$folks = (new Settings())->getFolks();
|
|
||||||
$found = find($folks, ["secret" => $data["secret"]]);
|
|
||||||
if ($found) {
|
|
||||||
//create new pass and secret key, then update file
|
|
||||||
$hash = password_hash($data["newPass"], PASSWORD_DEFAULT);
|
|
||||||
$freshSecret = StringTools::randomString(12);
|
|
||||||
Member::updateData("password", $hash, $data["secret"]);
|
|
||||||
Member::updateData("secret", $freshSecret, $data["secret"]);
|
|
||||||
$result = [
|
|
||||||
"message" => "Password Updated. Very nice!",
|
|
||||||
"type" => "passCreated",
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
$result = [
|
|
||||||
"message" => "Secret key is invalid. Try to retrieve it again",
|
|
||||||
"type" => "passNotCreated",
|
|
||||||
];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$result = [
|
|
||||||
"message" => "Passwords don't match. Try it again.",
|
|
||||||
"type" => "passNotCreated",
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function logout()
|
|
||||||
{
|
|
||||||
Session::kill();
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,159 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace brain\data;
|
||||||
|
|
||||||
|
use ReallySimpleJWT\Token;
|
||||||
|
use brain\data\Settings;
|
||||||
|
use brain\data\Session;
|
||||||
|
|
||||||
|
use function _\find;
|
||||||
|
|
||||||
|
class Auth
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function sessionStatus()
|
||||||
|
{
|
||||||
|
if (isset($_SESSION["member"])) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//return $this->secret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function status()
|
||||||
|
{
|
||||||
|
$result = "";
|
||||||
|
if (Session::active()) {
|
||||||
|
$result = true;
|
||||||
|
} else {
|
||||||
|
$result = false;
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function login($who)
|
||||||
|
{
|
||||||
|
//grab member list
|
||||||
|
$folks = (new Settings())->getFolks();
|
||||||
|
$found = find($folks, ["handle" => $who["handle"]]);
|
||||||
|
|
||||||
|
if ($found) {
|
||||||
|
//name is found, verify password
|
||||||
|
if (password_verify($who["password"], $found["password"])) {
|
||||||
|
$member = [
|
||||||
|
"handle" => $found["handle"],
|
||||||
|
"email" => $found["email"],
|
||||||
|
"role" => $found["role"],
|
||||||
|
"avatar" => $found["avi"],
|
||||||
|
"key" => $found["key"],
|
||||||
|
];
|
||||||
|
|
||||||
|
$token = Token::create(
|
||||||
|
$found["key"],
|
||||||
|
$found["secret"],
|
||||||
|
time() + 3600,
|
||||||
|
"localhost"
|
||||||
|
); //expires in an hour
|
||||||
|
|
||||||
|
$form_token = md5(uniqid(microtime(), true));
|
||||||
|
Session::start();
|
||||||
|
Session::set("member", $member);
|
||||||
|
Session::set("token", $token);
|
||||||
|
Session::set("form_token", $form_token);
|
||||||
|
|
||||||
|
$result = "good_login";
|
||||||
|
} else {
|
||||||
|
$result = "bad_pass";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//if name is not found
|
||||||
|
$result = "no_name";
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function findSecret($data)
|
||||||
|
{
|
||||||
|
$result = [];
|
||||||
|
$folks = (new Settings())->getFolks();
|
||||||
|
|
||||||
|
if (
|
||||||
|
!empty($data["email"]) &&
|
||||||
|
filter_var($data["email"], FILTER_VALIDATE_EMAIL)
|
||||||
|
) {
|
||||||
|
$found = find($folks, ["email" => $data["email"]]);
|
||||||
|
if ($found) {
|
||||||
|
//if email is cool, check mail relay status
|
||||||
|
//if set up, send secret there, if not just return it
|
||||||
|
$config = new Settings();
|
||||||
|
$settings = $config->getSettings();
|
||||||
|
$email = $settings["email"]["active"];
|
||||||
|
if ($email != "option-none") {
|
||||||
|
$data["mail_task"] = "SEND_SECRET";
|
||||||
|
$data["secret"] = $found["secret"];
|
||||||
|
$result = Mailer::sendmail($data);
|
||||||
|
} else {
|
||||||
|
$result = [
|
||||||
|
"message" => "Valid email, but no email set up!",
|
||||||
|
"type" => "secretFound",
|
||||||
|
"secret" => $found["secret"],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$result = [
|
||||||
|
"message" => "No valid email, no goodies, pleighboi",
|
||||||
|
"type" => "secretNotFound",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$result = [
|
||||||
|
"message" => "Aye, this address is not right, slick.",
|
||||||
|
"type" => "secretNotFound",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function makeNewPassword($data)
|
||||||
|
{
|
||||||
|
//check if passwordsmatch
|
||||||
|
if ($data["newPass"] == $data["newPassConfirm"]) {
|
||||||
|
//verify secret
|
||||||
|
$folks = (new Settings())->getFolks();
|
||||||
|
$found = find($folks, ["secret" => $data["secret"]]);
|
||||||
|
if ($found) {
|
||||||
|
//create new pass and secret key, then update file
|
||||||
|
$hash = password_hash($data["newPass"], PASSWORD_DEFAULT);
|
||||||
|
$freshSecret = StringTools::randomString(12);
|
||||||
|
Member::updateData("password", $hash, $data["secret"]);
|
||||||
|
Member::updateData("secret", $freshSecret, $data["secret"]);
|
||||||
|
$result = [
|
||||||
|
"message" => "Password Updated. Very nice!",
|
||||||
|
"type" => "passCreated",
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
$result = [
|
||||||
|
"message" => "Secret key is invalid. Try to retrieve it again",
|
||||||
|
"type" => "passNotCreated",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$result = [
|
||||||
|
"message" => "Passwords don't match. Try it again.",
|
||||||
|
"type" => "passNotCreated",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function logout()
|
||||||
|
{
|
||||||
|
Session::kill();
|
||||||
|
}
|
||||||
|
}
|
@ -1,265 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use function _\filter;
|
|
||||||
use function _\find;
|
|
||||||
|
|
||||||
class Book
|
|
||||||
{
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public function findPageById(string $uuid)
|
|
||||||
{
|
|
||||||
$content = $this->getContents();
|
|
||||||
$page = find($content, ["uuid" => $uuid]);
|
|
||||||
return $page;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function findPageBySlug(string $slug = null)
|
|
||||||
{
|
|
||||||
$content = $this->getContents();
|
|
||||||
if (isset($slug)) {
|
|
||||||
$page = find($content, ["slug" => $slug]);
|
|
||||||
} else {
|
|
||||||
$page = find($content, ["layout" => "index"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
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"]]);
|
|
||||||
$body = $request->getParsedBody();
|
|
||||||
} else {
|
|
||||||
$body = $request->getParsedBody();
|
|
||||||
}
|
|
||||||
|
|
||||||
$page = find($content, ["uuid" => $body["uuid"]]);
|
|
||||||
$image = $request->getUploadedFiles();
|
|
||||||
$member = Session::get("member");
|
|
||||||
|
|
||||||
if ($task != "create") {
|
|
||||||
$path =
|
|
||||||
date("Y", date($page["rawCreated"])) .
|
|
||||||
"/" .
|
|
||||||
date("m", date($page["rawCreated"]));
|
|
||||||
} else {
|
|
||||||
$path = date("Y") . "/" . date("m");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($image["feature_image"])) {
|
|
||||||
if ($task != "create") {
|
|
||||||
$feature =
|
|
||||||
"/assets/images/blog/" .
|
|
||||||
$path .
|
|
||||||
"/" .
|
|
||||||
$image["feature_image"]->getClientFileName();
|
|
||||||
} else {
|
|
||||||
$feature =
|
|
||||||
"/assets/images/blog/" .
|
|
||||||
$path .
|
|
||||||
"/" .
|
|
||||||
$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 {
|
|
||||||
$task == "create" ? ($feature = "") : ($feature = $body["feature"]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($task == "delete") {
|
|
||||||
$deleted = "true";
|
|
||||||
$body["menu"] = "false";
|
|
||||||
$body["published"] = "false";
|
|
||||||
$body["featured"] = "false";
|
|
||||||
} else {
|
|
||||||
$deleted = isset($page["deleted"]) ? $page["deleted"] : "false";
|
|
||||||
}
|
|
||||||
|
|
||||||
$created =
|
|
||||||
$task != "create"
|
|
||||||
? new \Moment\Moment($page["rawCreated"])
|
|
||||||
: new \Moment\Moment();
|
|
||||||
$updated = new \Moment\Moment();
|
|
||||||
|
|
||||||
//grab current index from settings and update
|
|
||||||
$id = $task != "create" ? $body["id"] : Settings::getCurrentIndex();
|
|
||||||
$uuid = $task != "create" ? $body["uuid"] : StringTools::createUUID();
|
|
||||||
// now that variables are done, set to body object and then convert to markdown to save
|
|
||||||
|
|
||||||
$body["id"] = $id;
|
|
||||||
$body["uuid"] = $uuid;
|
|
||||||
$body["feature"] = $feature;
|
|
||||||
$body["path"] = $path;
|
|
||||||
$body["author"] = $member["handle"];
|
|
||||||
$body["created"] = $created->format("Y-m-d\TH:i:sP");
|
|
||||||
$body["updated"] = $updated->format("Y-m-d\TH:i:sP");
|
|
||||||
$body["deleted"] = $deleted;
|
|
||||||
|
|
||||||
$write = DocTools::objectToMD($body);
|
|
||||||
|
|
||||||
// if layout is index, change path to file
|
|
||||||
|
|
||||||
if ($body["layout"] == "index") {
|
|
||||||
$writePath = "../content/pages/start/index.md";
|
|
||||||
} else {
|
|
||||||
$writePath = "../content/pages/" . $path . "/" . $body["slug"] . ".md";
|
|
||||||
}
|
|
||||||
|
|
||||||
$status = DocTools::writePages($task, $path, $writePath, $write);
|
|
||||||
|
|
||||||
if ($status) {
|
|
||||||
$config = new Settings();
|
|
||||||
$settings = $config->getSettings();
|
|
||||||
$message = "";
|
|
||||||
|
|
||||||
if (
|
|
||||||
$settings["global"]["renderOnSave"] == "true" &&
|
|
||||||
$settings["global"]["dynamicRender"] == "false"
|
|
||||||
) {
|
|
||||||
$render = new Render();
|
|
||||||
$render->renderTags();
|
|
||||||
$render->renderArchive();
|
|
||||||
$render->renderPages();
|
|
||||||
$message = "Filed edited and rendered. NOICE.";
|
|
||||||
} else {
|
|
||||||
$message = "File edited. Nice work";
|
|
||||||
}
|
|
||||||
|
|
||||||
$response = [
|
|
||||||
"message" => $message,
|
|
||||||
"type" => $task == "write" ? "postUpdated" : "postAdded",
|
|
||||||
"id" => $uuid,
|
|
||||||
];
|
|
||||||
|
|
||||||
//TODO: When form submission is successful, make new form token
|
|
||||||
//Session token doesn't reset on the front end, so turning this off for now
|
|
||||||
//$form_token = md5(uniqid(microtime(), true));
|
|
||||||
//Session::set("form_token", $form_token);
|
|
||||||
|
|
||||||
//once saved, update menu
|
|
||||||
$body["path"] = $path;
|
|
||||||
Settings::updateMenu($body);
|
|
||||||
Settings::updateTags();
|
|
||||||
//if new page added, update current index in Settings file
|
|
||||||
if ($task == "create") {
|
|
||||||
Settings::updateIndex();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$response = [
|
|
||||||
"message" => "Uh oh. File save problem. Don't panic",
|
|
||||||
"type" => "postError",
|
|
||||||
"id" => $uuid,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getPages(int $page, int $limit, string $sort = null)
|
|
||||||
{
|
|
||||||
$content = $this->getContents();
|
|
||||||
|
|
||||||
$published = filter($content, function ($item) {
|
|
||||||
return $item["published"] == true && $item["deleted"] == false;
|
|
||||||
});
|
|
||||||
$deleted = filter($content, function ($item) {
|
|
||||||
return $item["deleted"] == true;
|
|
||||||
});
|
|
||||||
|
|
||||||
//$all = $content;
|
|
||||||
$all = filter($content, function ($item) {
|
|
||||||
return $item["deleted"] == false;
|
|
||||||
});
|
|
||||||
$filter = isset($sort) ? $sort : "all";
|
|
||||||
switch ($filter) {
|
|
||||||
case "published":
|
|
||||||
$filtered = $published;
|
|
||||||
break;
|
|
||||||
case "deleted":
|
|
||||||
$filtered = $deleted;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$filtered = $all;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
$numOfPages = ceil(count($filtered) / ($limit + 1));
|
|
||||||
$folder = [];
|
|
||||||
|
|
||||||
if (count($filtered) != 0) {
|
|
||||||
if (count($filtered) < $limit) {
|
|
||||||
$limit = count($filtered) - 1;
|
|
||||||
}
|
|
||||||
$range = $page * $limit - $limit;
|
|
||||||
|
|
||||||
if ($range != 0) {
|
|
||||||
$range = $range + 1;
|
|
||||||
}
|
|
||||||
for ($i = 0; $i <= $limit; $i++) {
|
|
||||||
if (isset($filtered[$i + $range])) {
|
|
||||||
array_push($folder, $filtered[$i + $range]);
|
|
||||||
} else {
|
|
||||||
//chill out
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$prev = $page - 1;
|
|
||||||
if ($prev <= 0) {
|
|
||||||
$prev = $numOfPages;
|
|
||||||
}
|
|
||||||
|
|
||||||
$next = $page + 1;
|
|
||||||
if ($next > $numOfPages) {
|
|
||||||
$next = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return [
|
|
||||||
"pages" => $folder,
|
|
||||||
"numOfPages" => $numOfPages,
|
|
||||||
"entryCount" => count($filtered),
|
|
||||||
"paginate" => [
|
|
||||||
"sort" => $sort,
|
|
||||||
"nextPage" => $next,
|
|
||||||
"prevPage" => $prev,
|
|
||||||
],
|
|
||||||
"stats" => [
|
|
||||||
"all" => count($all),
|
|
||||||
"published" => count($published),
|
|
||||||
"deleted" => count($deleted),
|
|
||||||
],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
public function getContents()
|
|
||||||
{
|
|
||||||
//test new contents data class
|
|
||||||
//$new = (new Contents("../content/pages"))->getAll();
|
|
||||||
$contents = (new Contents("../content/pages"))->getAll();
|
|
||||||
return $contents;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,298 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace brain\data;
|
||||||
|
|
||||||
|
use function _\filter;
|
||||||
|
use function _\find;
|
||||||
|
use brain\utility\DocTools;
|
||||||
|
use brain\utility\FileUploader;
|
||||||
|
use brain\utility\StringTools;
|
||||||
|
|
||||||
|
class Book
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findPageById(string $uuid)
|
||||||
|
{
|
||||||
|
$content = $this->getContents();
|
||||||
|
$page = find($content, ['uuid' => $uuid]);
|
||||||
|
|
||||||
|
return $page;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findPageBySlug(string $slug = null)
|
||||||
|
{
|
||||||
|
$content = $this->getContents();
|
||||||
|
if (isset($slug)) {
|
||||||
|
$page = find($content, ['slug' => $slug]);
|
||||||
|
} else {
|
||||||
|
$page = find($content, ['layout' => 'index']);
|
||||||
|
}
|
||||||
|
|
||||||
|
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"]]);
|
||||||
|
$body = $request->getParsedBody();
|
||||||
|
} else {
|
||||||
|
$body = $request->getParsedBody();
|
||||||
|
}
|
||||||
|
|
||||||
|
$page = find($content, ['uuid' => $body['uuid']]);
|
||||||
|
$files = $request->getUploadedFiles();
|
||||||
|
|
||||||
|
$member = Session::get('member');
|
||||||
|
|
||||||
|
if ($task != 'create') {
|
||||||
|
$path =
|
||||||
|
date('Y', date($page['rawCreated'])).
|
||||||
|
'/'.
|
||||||
|
date('m', date($page['rawCreated']));
|
||||||
|
} else {
|
||||||
|
$path = date('Y').'/'.date('m');
|
||||||
|
}
|
||||||
|
|
||||||
|
$page_feature = '';
|
||||||
|
$page_files = '';
|
||||||
|
|
||||||
|
if (isset($files['page_files'])) {
|
||||||
|
$imageList = '';
|
||||||
|
$fileList = '';
|
||||||
|
// var_dump($files["page_files"] );
|
||||||
|
foreach ($files['page_files'] as $file) {
|
||||||
|
$type = $file->getClientMediaType();
|
||||||
|
switch ($type) {
|
||||||
|
case 'image/jpeg':
|
||||||
|
case 'image/png':
|
||||||
|
case 'image/gif':
|
||||||
|
case 'image/svg':
|
||||||
|
$imagesPath = '/assets/images/blog/'.$path.'/';
|
||||||
|
$imageList =
|
||||||
|
$imageList.$imagesPath.urlencode($file->getClientFileName()).', ';
|
||||||
|
|
||||||
|
FileUploader::uploadFile(
|
||||||
|
'../public/assets/images/blog/'.$path.'/',
|
||||||
|
$file
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'video/mp4':
|
||||||
|
$videosPath = '/assets/video/blog/'.$path.'/';
|
||||||
|
$imageList =
|
||||||
|
$imageList.$videosPath.urlencode($file->getClientFileName()).', ';
|
||||||
|
|
||||||
|
FileUploader::uploadFile(
|
||||||
|
'../public/assets/video/blog/'.$path.'/',
|
||||||
|
$file
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'audio/mpeg':
|
||||||
|
$soundPath = '/assets/sound/blog/'.$path.'/';
|
||||||
|
$fileList = $fileList.$soundPath.urlencode($file->getClientFileName()).', ';
|
||||||
|
|
||||||
|
FileUploader::uploadFile(
|
||||||
|
'../public/assets/sound/blog/'.$path.'/',
|
||||||
|
$file
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'application/pdf':
|
||||||
|
case 'text/plain':
|
||||||
|
case 'text/rtf':
|
||||||
|
$docPath = '/assets/docs/blog/'.$path.'/';
|
||||||
|
$fileList = $fileList.$docPath.urlencode($file->getClientFileName()).', ';
|
||||||
|
|
||||||
|
FileUploader::uploadFile(
|
||||||
|
'../public/assets/docs/blog/'.$path.'/',
|
||||||
|
$file
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$page_feature = $imageList;
|
||||||
|
$page_files = $fileList;
|
||||||
|
} else {
|
||||||
|
// if no files, just reset string from page object
|
||||||
|
$page_feature = $page['feature'];
|
||||||
|
$page_files = $page['files'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($task == 'delete') {
|
||||||
|
$deleted = 'true';
|
||||||
|
$body['menu'] = 'false';
|
||||||
|
$body['published'] = 'false';
|
||||||
|
$body['featured'] = 'false';
|
||||||
|
} else {
|
||||||
|
$deleted = isset($page['deleted']) ? $page['deleted'] : 'false';
|
||||||
|
}
|
||||||
|
|
||||||
|
$created =
|
||||||
|
$task != 'create'
|
||||||
|
? new \Moment\Moment($page['rawCreated'])
|
||||||
|
: new \Moment\Moment();
|
||||||
|
$updated = new \Moment\Moment();
|
||||||
|
|
||||||
|
// grab current index from settings and update
|
||||||
|
$id = $task != 'create' ? $body['id'] : Settings::getCurrentIndex();
|
||||||
|
$uuid = $task != 'create' ? $body['uuid'] : StringTools::createUUID();
|
||||||
|
// now that variables are done, set to body object and then convert to markdown to save
|
||||||
|
|
||||||
|
$body['id'] = $id;
|
||||||
|
$body['uuid'] = $uuid;
|
||||||
|
$body['feature'] = $page_feature;
|
||||||
|
$body['files'] = $page_files;
|
||||||
|
$body['path'] = $path;
|
||||||
|
$body['author'] = $member['handle'];
|
||||||
|
$body['created'] = $created->format("Y-m-d\TH:i:sP");
|
||||||
|
$body['updated'] = $updated->format("Y-m-d\TH:i:sP");
|
||||||
|
$body['deleted'] = $deleted;
|
||||||
|
|
||||||
|
$write = DocTools::objectToMD($body);
|
||||||
|
|
||||||
|
// if layout is index, change path to file
|
||||||
|
|
||||||
|
if ($body['layout'] == 'index') {
|
||||||
|
$writePath = '../content/pages/start/index.md';
|
||||||
|
} else {
|
||||||
|
$writePath = '../content/pages/'.$path.'/'.$body['slug'].'.md';
|
||||||
|
}
|
||||||
|
|
||||||
|
$status = DocTools::writePages($task, $path, $writePath, $write);
|
||||||
|
|
||||||
|
if ($status) {
|
||||||
|
$config = new Settings();
|
||||||
|
$settings = $config->getSettings();
|
||||||
|
$message = '';
|
||||||
|
|
||||||
|
if (
|
||||||
|
$settings['global']['renderOnSave'] == 'true' &&
|
||||||
|
$settings['global']['dynamicRender'] == 'false'
|
||||||
|
) {
|
||||||
|
$render = new Render();
|
||||||
|
$render->renderTags();
|
||||||
|
$render->renderArchive();
|
||||||
|
$render->renderPages();
|
||||||
|
$message = 'Filed edited and rendered. NOICE.';
|
||||||
|
} else {
|
||||||
|
$message = 'File edited. Nice work';
|
||||||
|
}
|
||||||
|
|
||||||
|
$response = [
|
||||||
|
'message' => $message,
|
||||||
|
'type' => $task == 'write' ? 'postUpdated' : 'postAdded',
|
||||||
|
'id' => $uuid,
|
||||||
|
];
|
||||||
|
|
||||||
|
// TODO: When form submission is successful, make new form token
|
||||||
|
// Session token doesn't reset on the front end, so turning this off for now
|
||||||
|
// $form_token = md5(uniqid(microtime(), true));
|
||||||
|
// Session::set("form_token", $form_token);
|
||||||
|
|
||||||
|
// once saved, update menu
|
||||||
|
$body['path'] = $path;
|
||||||
|
Settings::updateMenu($body);
|
||||||
|
Settings::updateTags();
|
||||||
|
// if new page added, update current index in Settings file
|
||||||
|
if ($task == 'create') {
|
||||||
|
Settings::updateIndex();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$response = [
|
||||||
|
'message' => "Uh oh. File save problem. Don't panic",
|
||||||
|
'type' => 'postError',
|
||||||
|
'id' => $uuid,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPages(int $page, int $limit, string $sort = null)
|
||||||
|
{
|
||||||
|
$content = $this->getContents();
|
||||||
|
|
||||||
|
$published = filter($content, function ($item) {
|
||||||
|
return $item['published'] == true && $item['deleted'] == false;
|
||||||
|
});
|
||||||
|
$deleted = filter($content, function ($item) {
|
||||||
|
return $item['deleted'] == true;
|
||||||
|
});
|
||||||
|
|
||||||
|
// $all = $content;
|
||||||
|
$all = filter($content, function ($item) {
|
||||||
|
return $item['deleted'] == false;
|
||||||
|
});
|
||||||
|
$filter = isset($sort) ? $sort : 'all';
|
||||||
|
switch ($filter) {
|
||||||
|
case 'published':
|
||||||
|
$filtered = $published;
|
||||||
|
break;
|
||||||
|
case 'deleted':
|
||||||
|
$filtered = $deleted;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$filtered = $all;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$numOfPages = ceil(count($filtered) / ($limit + 1));
|
||||||
|
$folder = [];
|
||||||
|
|
||||||
|
if (count($filtered) != 0) {
|
||||||
|
if (count($filtered) < $limit) {
|
||||||
|
$limit = count($filtered) - 1;
|
||||||
|
}
|
||||||
|
$range = $page * $limit - $limit;
|
||||||
|
|
||||||
|
if ($range != 0) {
|
||||||
|
$range = $range + 1;
|
||||||
|
}
|
||||||
|
for ($i = 0; $i <= $limit; ++$i) {
|
||||||
|
if (isset($filtered[$i + $range])) {
|
||||||
|
array_push($folder, $filtered[$i + $range]);
|
||||||
|
} else {
|
||||||
|
// chill out
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$prev = $page - 1;
|
||||||
|
if ($prev <= 0) {
|
||||||
|
$prev = $numOfPages;
|
||||||
|
}
|
||||||
|
|
||||||
|
$next = $page + 1;
|
||||||
|
if ($next > $numOfPages) {
|
||||||
|
$next = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'pages' => $folder,
|
||||||
|
'numOfPages' => $numOfPages,
|
||||||
|
'entryCount' => count($filtered),
|
||||||
|
'paginate' => [
|
||||||
|
'sort' => $sort,
|
||||||
|
'nextPage' => $next,
|
||||||
|
'prevPage' => $prev,
|
||||||
|
],
|
||||||
|
'stats' => [
|
||||||
|
'all' => count($all),
|
||||||
|
'published' => count($published),
|
||||||
|
'deleted' => count($deleted),
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getContents()
|
||||||
|
{
|
||||||
|
// test new contents data class
|
||||||
|
// $new = (new Contents("../content/pages"))->getAll();
|
||||||
|
$contents = (new Contents('../content/pages'))->getAll();
|
||||||
|
|
||||||
|
return $contents;
|
||||||
|
}
|
||||||
|
}
|
@ -1,144 +0,0 @@
|
|||||||
<?php
|
|
||||||
use League\CommonMark\Environment\Environment;
|
|
||||||
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
|
|
||||||
use League\CommonMark\Extension\Strikethrough\StrikethroughExtension;
|
|
||||||
use League\CommonMark\Extension\Attributes\AttributesExtension;
|
|
||||||
use League\CommonMark\Extension\FrontMatter\FrontMatterExtension;
|
|
||||||
use League\CommonMark\Extension\FrontMatter\Output\RenderedContentWithFrontMatter;
|
|
||||||
use League\CommonMark\MarkdownConverter;
|
|
||||||
use League\CommonMark\CommonMarkConverter;
|
|
||||||
|
|
||||||
use HtmlSanitizer\Extension\Basic\BasicExtension;
|
|
||||||
use HtmlSanitizer\Extension\Iframe\IframeExtension;
|
|
||||||
use HtmlSanitizer\SanitizerBuilder;
|
|
||||||
|
|
||||||
use function _\orderBy;
|
|
||||||
|
|
||||||
class Contents
|
|
||||||
{
|
|
||||||
public $files = [];
|
|
||||||
public $config = [];
|
|
||||||
public function __construct($folder)
|
|
||||||
{
|
|
||||||
$this->read($folder);
|
|
||||||
}
|
|
||||||
public function read($folder)
|
|
||||||
{
|
|
||||||
$folders = glob("$folder/*", GLOB_ONLYDIR);
|
|
||||||
foreach ($folders as $folder) {
|
|
||||||
//$this->files[] = $folder . "/";
|
|
||||||
$this->read($folder);
|
|
||||||
}
|
|
||||||
$files = array_filter(glob("$folder/*md"), "is_file");
|
|
||||||
foreach ($files as $file) {
|
|
||||||
$this->files[] = $file;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getAll()
|
|
||||||
{
|
|
||||||
$environment = new Environment($this->config);
|
|
||||||
$environment->addExtension(new CommonMarkCoreExtension());
|
|
||||||
|
|
||||||
// Add the extension
|
|
||||||
$environment->addExtension(new FrontMatterExtension());
|
|
||||||
|
|
||||||
//Add Strikethrough rendering
|
|
||||||
$environment->addExtension(new StrikethroughExtension());
|
|
||||||
|
|
||||||
//add attributes to elements in markdown
|
|
||||||
$environment->addExtension(new AttributesExtension());
|
|
||||||
|
|
||||||
// Instantiate the converter engine and start converting some Markdown!
|
|
||||||
$converter = new MarkdownConverter($environment);
|
|
||||||
|
|
||||||
$contents = [];
|
|
||||||
foreach ($this->files as $file) {
|
|
||||||
//get meta and html from file
|
|
||||||
$result = $converter->convertToHtml(file_get_contents($file));
|
|
||||||
$meta = [];
|
|
||||||
if ($result instanceof RenderedContentWithFrontMatter) {
|
|
||||||
$meta = $result->getFrontMatter();
|
|
||||||
}
|
|
||||||
|
|
||||||
//get raw markdown from file
|
|
||||||
$frontMatterExtension = new FrontMatterExtension();
|
|
||||||
$parsed = $frontMatterExtension
|
|
||||||
->getFrontMatterParser()
|
|
||||||
->parse(file_get_contents($file));
|
|
||||||
|
|
||||||
//never trust the front end. clean it up
|
|
||||||
|
|
||||||
$builder = new SanitizerBuilder();
|
|
||||||
$builder->registerExtension(new BasicExtension());
|
|
||||||
$builder->registerExtension(new IframeExtension());
|
|
||||||
|
|
||||||
//relative-a and relative-image
|
|
||||||
$builder->registerExtension(
|
|
||||||
new \HtmlSanitizer\Extension\Relative\A\AExtension()
|
|
||||||
);
|
|
||||||
$builder->registerExtension(
|
|
||||||
new \HtmlSanitizer\Extension\Relative\Image\ImageExtension()
|
|
||||||
);
|
|
||||||
|
|
||||||
$detergent = [
|
|
||||||
"extensions" => ["basic", "relative-a", "relative-image", "iframe"],
|
|
||||||
"tags" => [
|
|
||||||
"div" => [
|
|
||||||
"allowed_attributes" => ["class", "title"],
|
|
||||||
],
|
|
||||||
"img" => [
|
|
||||||
"allowed_attributes" => ["src", "alt", "title", "class"],
|
|
||||||
],
|
|
||||||
"iframe" => [
|
|
||||||
"allowed_attributes" => ["height", "width", "title", "src"],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
];
|
|
||||||
|
|
||||||
$sanitizer = $builder->build($detergent);
|
|
||||||
|
|
||||||
$scrubbed = $sanitizer->sanitize($result->getContent());
|
|
||||||
|
|
||||||
//sort attributes into page object
|
|
||||||
$page = [
|
|
||||||
"id" => $meta["id"],
|
|
||||||
"uuid" => $meta["uuid"],
|
|
||||||
"title" => $meta["title"],
|
|
||||||
"feature" => $meta["feature"],
|
|
||||||
"path" => $meta["path"],
|
|
||||||
"layout" => $meta["layout"],
|
|
||||||
"tags" => $meta["tags"],
|
|
||||||
"author" => $meta["author"],
|
|
||||||
"created" => date("Y M D d", $meta["created"]),
|
|
||||||
"updated" => date("Y M D d", $meta["updated"]),
|
|
||||||
"rawCreated" => $meta["created"],
|
|
||||||
"rawUpdated" => $meta["updated"],
|
|
||||||
"createdYear" => date("Y", $meta["created"]),
|
|
||||||
"createdMonth" => date("m", $meta["created"]),
|
|
||||||
"deleted" => $meta["deleted"],
|
|
||||||
"menu" => $meta["menu"],
|
|
||||||
"featured" => $meta["featured"],
|
|
||||||
"published" => $meta["published"],
|
|
||||||
"slug" => $meta["slug"],
|
|
||||||
"filePath" => $file,
|
|
||||||
"content" => $parsed->getContent(),
|
|
||||||
"html" => $scrubbed,
|
|
||||||
];
|
|
||||||
//checks for duplicates
|
|
||||||
$uuid = $meta["uuid"];
|
|
||||||
$found = current(
|
|
||||||
array_filter($contents, function ($item) use ($uuid) {
|
|
||||||
return isset($item["uuid"]) && $uuid == $item["uuid"];
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
// if uuid is not present, add it
|
|
||||||
if (!$found) {
|
|
||||||
array_push($contents, $page);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$contents = orderBy($contents, ["id"], ["desc"]);
|
|
||||||
return $contents;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,178 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace brain\data;
|
||||||
|
|
||||||
|
use League\CommonMark\Environment\Environment;
|
||||||
|
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
|
||||||
|
use League\CommonMark\Extension\Strikethrough\StrikethroughExtension;
|
||||||
|
use League\CommonMark\Extension\Attributes\AttributesExtension;
|
||||||
|
use League\CommonMark\Extension\FrontMatter\FrontMatterExtension;
|
||||||
|
use League\CommonMark\Extension\FrontMatter\Output\RenderedContentWithFrontMatter;
|
||||||
|
use League\CommonMark\MarkdownConverter;
|
||||||
|
use League\CommonMark\CommonMarkConverter;
|
||||||
|
use HtmlSanitizer\Extension\Basic\BasicExtension;
|
||||||
|
use HtmlSanitizer\Extension\Iframe\IframeExtension;
|
||||||
|
use HtmlSanitizer\Extension\Listing\ListExtension;
|
||||||
|
use HtmlSanitizer\SanitizerBuilder;
|
||||||
|
|
||||||
|
use function _\orderBy;
|
||||||
|
|
||||||
|
class Contents
|
||||||
|
{
|
||||||
|
public $files = [];
|
||||||
|
public $config = [];
|
||||||
|
public function __construct($folder)
|
||||||
|
{
|
||||||
|
$this->read($folder);
|
||||||
|
}
|
||||||
|
public function read($folder)
|
||||||
|
{
|
||||||
|
$folders = glob("$folder/*", GLOB_ONLYDIR);
|
||||||
|
foreach ($folders as $folder) {
|
||||||
|
//$this->files[] = $folder . "/";
|
||||||
|
$this->read($folder);
|
||||||
|
}
|
||||||
|
$files = array_filter(glob("$folder/*md"), "is_file");
|
||||||
|
foreach ($files as $file) {
|
||||||
|
$this->files[] = $file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAll()
|
||||||
|
{
|
||||||
|
$environment = new Environment($this->config);
|
||||||
|
$environment->addExtension(new CommonMarkCoreExtension());
|
||||||
|
|
||||||
|
// Add the extension
|
||||||
|
$environment->addExtension(new FrontMatterExtension());
|
||||||
|
|
||||||
|
//Add Strikethrough rendering
|
||||||
|
$environment->addExtension(new StrikethroughExtension());
|
||||||
|
|
||||||
|
//add attributes to elements in markdown
|
||||||
|
$environment->addExtension(new AttributesExtension());
|
||||||
|
|
||||||
|
// Instantiate the converter engine and start converting some Markdown!
|
||||||
|
$converter = new MarkdownConverter($environment);
|
||||||
|
|
||||||
|
$contents = [];
|
||||||
|
foreach ($this->files as $file) {
|
||||||
|
//get meta and html from file
|
||||||
|
$result = $converter->convertToHtml(file_get_contents($file));
|
||||||
|
$meta = [];
|
||||||
|
if ($result instanceof RenderedContentWithFrontMatter) {
|
||||||
|
$meta = $result->getFrontMatter();
|
||||||
|
}
|
||||||
|
|
||||||
|
//get raw markdown from file
|
||||||
|
$frontMatterExtension = new FrontMatterExtension();
|
||||||
|
$parsed = $frontMatterExtension
|
||||||
|
->getFrontMatterParser()
|
||||||
|
->parse(file_get_contents($file));
|
||||||
|
|
||||||
|
//never trust the front end. clean it up
|
||||||
|
//add what sanitizer extensions we need manually
|
||||||
|
$builder = new SanitizerBuilder();
|
||||||
|
$builder->registerExtension(new BasicExtension());
|
||||||
|
$builder->registerExtension(new IframeExtension());
|
||||||
|
$builder->registerExtension(new ListExtension());
|
||||||
|
|
||||||
|
//relative-a and relative-image
|
||||||
|
$builder->registerExtension(
|
||||||
|
new \HtmlSanitizer\Extension\Relative\A\AExtension()
|
||||||
|
);
|
||||||
|
$builder->registerExtension(
|
||||||
|
new \HtmlSanitizer\Extension\Relative\Image\ImageExtension()
|
||||||
|
);
|
||||||
|
|
||||||
|
$detergent = [
|
||||||
|
"extensions" => ["basic", "list","relative-a", "relative-image", "iframe"],
|
||||||
|
"tags" => [
|
||||||
|
"div" => [
|
||||||
|
"allowed_attributes" => ["class", "title", "id", "style"],
|
||||||
|
],
|
||||||
|
"img" => [
|
||||||
|
"allowed_attributes" => ["src", "alt", "title", "class"],
|
||||||
|
],
|
||||||
|
"iframe" => [
|
||||||
|
"allowed_attributes" => ["height", "width", "title", "src"],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
$sanitizer = $builder->build($detergent);
|
||||||
|
|
||||||
|
$scrubbed = $sanitizer->sanitize($result->getContent());
|
||||||
|
$featureList = explode(",", $meta["feature"]);
|
||||||
|
$docs = '';
|
||||||
|
if (isset($meta["files"])) {
|
||||||
|
$fileList = explode(",", $meta["files"]);
|
||||||
|
$docs = $meta["files"];
|
||||||
|
} else {
|
||||||
|
$fileList = [];
|
||||||
|
$docs = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$media = [];
|
||||||
|
$files = [];
|
||||||
|
foreach ($featureList as $file) {
|
||||||
|
$item = trim($file);
|
||||||
|
$ext = pathinfo($item, PATHINFO_EXTENSION);
|
||||||
|
if ($item != null || $item != "") {
|
||||||
|
array_push($media, ["file" => $item, "type" => trim($ext)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($fileList as $file) {
|
||||||
|
$item = trim($file);
|
||||||
|
$ext = pathinfo($item, PATHINFO_EXTENSION);
|
||||||
|
if ($item != null || $item != "") {
|
||||||
|
array_push($files, ["file" => $item, "type" => trim($ext)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//sort attributes into page object
|
||||||
|
$page = [
|
||||||
|
"id" => $meta["id"],
|
||||||
|
"uuid" => $meta["uuid"],
|
||||||
|
"title" => $meta["title"],
|
||||||
|
"feature" => $meta["feature"],
|
||||||
|
"files" => $docs,
|
||||||
|
"path" => $meta["path"],
|
||||||
|
"layout" => $meta["layout"],
|
||||||
|
"tags" => $meta["tags"],
|
||||||
|
"author" => $meta["author"],
|
||||||
|
"created" => date("Y M D d", $meta["created"]),
|
||||||
|
"updated" => date("Y M D d", $meta["updated"]),
|
||||||
|
"rawCreated" => $meta["created"],
|
||||||
|
"rawUpdated" => $meta["updated"],
|
||||||
|
"createdYear" => date("Y", $meta["created"]),
|
||||||
|
"createdMonth" => date("m", $meta["created"]),
|
||||||
|
"deleted" => $meta["deleted"],
|
||||||
|
"menu" => $meta["menu"],
|
||||||
|
"featured" => $meta["featured"],
|
||||||
|
"published" => $meta["published"],
|
||||||
|
"slug" => $meta["slug"],
|
||||||
|
"filePath" => $file,
|
||||||
|
"content" => $parsed->getContent(),
|
||||||
|
"html" => $scrubbed,
|
||||||
|
"media" => $media,
|
||||||
|
"docs" => $files
|
||||||
|
];
|
||||||
|
//checks for duplicates
|
||||||
|
$uuid = $meta["uuid"];
|
||||||
|
$found = current(
|
||||||
|
array_filter($contents, function ($item) use ($uuid) {
|
||||||
|
return isset($item["uuid"]) && $uuid == $item["uuid"];
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
// if uuid is not present, add it
|
||||||
|
if (!$found) {
|
||||||
|
array_push($contents, $page);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$contents = orderBy($contents, ["id"], ["desc"]);
|
||||||
|
return $contents;
|
||||||
|
}
|
||||||
|
}
|
@ -1,55 +0,0 @@
|
|||||||
<?php
|
|
||||||
use function _\find;
|
|
||||||
|
|
||||||
class Member
|
|
||||||
{
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function verifyKey(string $key)
|
|
||||||
{
|
|
||||||
if (isset($key)) {
|
|
||||||
$folks = (new Settings())->getFolks();
|
|
||||||
$found = find($folks, ["key" => $key]);
|
|
||||||
if ($found) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function updateData(string $key, string $data, $secret = null)
|
|
||||||
{
|
|
||||||
$folks = (new Settings())->getFolks();
|
|
||||||
if (isset($secret)) {
|
|
||||||
$found = find($folks, ["secret" => $secret]);
|
|
||||||
} else {
|
|
||||||
$member = Session::get("member");
|
|
||||||
$found = find($folks, ["handle" => $member["handle"]]);
|
|
||||||
}
|
|
||||||
$found[$key] = $data;
|
|
||||||
//record time updated
|
|
||||||
$updated = new \Moment\Moment();
|
|
||||||
$found["updated"] = $updated->format("Y-m-d\TH:i:sP");
|
|
||||||
$newFolks = [];
|
|
||||||
array_push($newFolks, $found);
|
|
||||||
//save updated file
|
|
||||||
DocTools::writeSettings("../config/folks.json", $newFolks);
|
|
||||||
//update member data in session
|
|
||||||
|
|
||||||
if (!isset($secret)) {
|
|
||||||
$member = [
|
|
||||||
"handle" => $found["handle"],
|
|
||||||
"email" => $found["email"],
|
|
||||||
"role" => $found["role"],
|
|
||||||
"avatar" => $found["avi"],
|
|
||||||
"key" => $found["key"],
|
|
||||||
];
|
|
||||||
Session::set("member", $member);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,62 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace brain\data;
|
||||||
|
|
||||||
|
use brain\data\Settings;
|
||||||
|
use brain\data\Session;
|
||||||
|
use brain\utility\DocTools;
|
||||||
|
|
||||||
|
use function _\find;
|
||||||
|
|
||||||
|
class Member
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function verifyKey(string $key)
|
||||||
|
{
|
||||||
|
if (isset($key)) {
|
||||||
|
$folks = (new Settings())->getFolks();
|
||||||
|
$found = find($folks, ["key" => $key]);
|
||||||
|
if ($found) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function updateData(string $key, string $data, $secret = null)
|
||||||
|
{
|
||||||
|
$folks = (new Settings())->getFolks();
|
||||||
|
if (isset($secret)) {
|
||||||
|
$found = find($folks, ["secret" => $secret]);
|
||||||
|
} else {
|
||||||
|
$member = Session::get("member");
|
||||||
|
$found = find($folks, ["handle" => $member["handle"]]);
|
||||||
|
}
|
||||||
|
$found[$key] = $data;
|
||||||
|
//record time updated
|
||||||
|
$updated = new \Moment\Moment();
|
||||||
|
$found["updated"] = $updated->format("Y-m-d\TH:i:sP");
|
||||||
|
$newFolks = [];
|
||||||
|
array_push($newFolks, $found);
|
||||||
|
//save updated file
|
||||||
|
DocTools::writeSettings("../config/folks.json", $newFolks);
|
||||||
|
//update member data in session
|
||||||
|
|
||||||
|
if (!isset($secret)) {
|
||||||
|
$member = [
|
||||||
|
"handle" => $found["handle"],
|
||||||
|
"email" => $found["email"],
|
||||||
|
"role" => $found["role"],
|
||||||
|
"avatar" => $found["avi"],
|
||||||
|
"key" => $found["key"],
|
||||||
|
];
|
||||||
|
Session::set("member", $member);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,179 +0,0 @@
|
|||||||
<?php
|
|
||||||
use Mni\FrontYAML\Parser;
|
|
||||||
use function _\find;
|
|
||||||
|
|
||||||
class Render
|
|
||||||
{
|
|
||||||
public $loader;
|
|
||||||
public $twig;
|
|
||||||
public $pageInfo;
|
|
||||||
public $menu;
|
|
||||||
public $background;
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$config = new Settings();
|
|
||||||
$this->loader = new \Twig\Loader\FilesystemLoader("../content/themes");
|
|
||||||
$this->twig = new \Twig\Environment($this->loader, []);
|
|
||||||
$settings = $config->getSettings();
|
|
||||||
$this->menu = $settings["menu"];
|
|
||||||
$this->theme = $settings["global"]["theme"];
|
|
||||||
$this->pageInfo = [
|
|
||||||
"keywords" => isset($settings["global"]["keywords"])
|
|
||||||
? $settings["global"]["keywords"]
|
|
||||||
: "fipamo, blog, jamstack, php, markdown, js",
|
|
||||||
"description" => $settings["global"]["descriptions"],
|
|
||||||
"image" =>
|
|
||||||
$settings["global"]["base_url"] . $settings["global"]["background"],
|
|
||||||
"baseURL" => $settings["global"]["base_url"],
|
|
||||||
];
|
|
||||||
//move global theme image assets to public folder
|
|
||||||
foreach (
|
|
||||||
new DirectoryIterator(
|
|
||||||
"../content/themes/" . $this->theme . "/assets/images/global/"
|
|
||||||
)
|
|
||||||
as $file
|
|
||||||
) {
|
|
||||||
if ($file->isDot()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!is_file("../public/assets/images/global/" . $file->getFileName())) {
|
|
||||||
copy(
|
|
||||||
"../content/themes/" .
|
|
||||||
$this->theme .
|
|
||||||
"/assets/images/global/" .
|
|
||||||
$file->getFileName(),
|
|
||||||
"../public/assets/images/global/" . $file->getFileName()
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
//image is already there, so chill
|
|
||||||
}
|
|
||||||
//print $file->getFilename() . "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
//copy current theme assets to public
|
|
||||||
if (is_file("../public/assets/css/base.css")) {
|
|
||||||
unlink("../public/assets/css/base.css");
|
|
||||||
}
|
|
||||||
copy(
|
|
||||||
"../content/themes/" . $this->theme . "/assets/css/base.css",
|
|
||||||
"../public/assets/css/base.css"
|
|
||||||
);
|
|
||||||
if (is_file("../public/assets/scripts/start.min.js")) {
|
|
||||||
unlink("../public/assets/scripts/start.min.js");
|
|
||||||
}
|
|
||||||
copy(
|
|
||||||
"../content/themes/" . $this->theme . "/assets/scripts/start.min.js",
|
|
||||||
"../public/assets/scripts/start.min.js"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function renderPages()
|
|
||||||
{
|
|
||||||
$pages = (new Book())->getContents();
|
|
||||||
$recent = [];
|
|
||||||
$featured = [];
|
|
||||||
$limit = 4;
|
|
||||||
foreach ($pages as $page) {
|
|
||||||
$pageOptions = Sorting::page($page);
|
|
||||||
|
|
||||||
$layout = $page["layout"];
|
|
||||||
//new pages have no layout, so defautl for now
|
|
||||||
if ($layout == "" || $layout == null) {
|
|
||||||
$layout = "page";
|
|
||||||
}
|
|
||||||
|
|
||||||
$template = $this->theme . "/" . $layout . ".twig";
|
|
||||||
if (str_contains($page["layout"], "index")) {
|
|
||||||
$location = "../public/index.html";
|
|
||||||
$dir = null;
|
|
||||||
} else {
|
|
||||||
// if page is a menu item, render the page on public root
|
|
||||||
if ($page["menu"] == "true") {
|
|
||||||
$location = "../public/" . $page["slug"] . ".html";
|
|
||||||
$dir = "../public/";
|
|
||||||
} else {
|
|
||||||
$location =
|
|
||||||
"../public/" . $page["path"] . "/" . $page["slug"] . ".html";
|
|
||||||
$dir = "../public/" . $page["path"];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$html = $this->twig->render($template, $pageOptions);
|
|
||||||
DocTools::writeHTML($location, $html, $dir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function renderArchive()
|
|
||||||
{
|
|
||||||
$archive = Sorting::archive();
|
|
||||||
$template = $this->theme . "/archive.twig";
|
|
||||||
$pageOptions = [
|
|
||||||
"title" => "Archive",
|
|
||||||
"background" => $this->pageInfo["image"],
|
|
||||||
"archives" => $archive,
|
|
||||||
"info" => $this->pageInfo,
|
|
||||||
"menu" => $this->menu,
|
|
||||||
];
|
|
||||||
|
|
||||||
$html = $this->twig->render($template, $pageOptions);
|
|
||||||
$location = "../public/archives.html";
|
|
||||||
DocTools::writeHTML($location, $html);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function renderTags()
|
|
||||||
{
|
|
||||||
$list = Sorting::tags();
|
|
||||||
foreach ($list as $item) {
|
|
||||||
$template = $this->theme . "/tags.twig";
|
|
||||||
$pageOptions = [
|
|
||||||
"title" => "Pages Tagged as " . $item["tag_name"],
|
|
||||||
"background" => $this->pageInfo["image"],
|
|
||||||
"tag_list" => $item["pages"],
|
|
||||||
"info" => $this->pageInfo,
|
|
||||||
"menu" => $this->menu,
|
|
||||||
];
|
|
||||||
|
|
||||||
$html = $this->twig->render($template, $pageOptions);
|
|
||||||
|
|
||||||
$location = "../public/tags/" . $item["slug"] . ".html";
|
|
||||||
|
|
||||||
//if tags folder doesn't exist, make it
|
|
||||||
if (!is_dir("../public/tags")) {
|
|
||||||
mkdir("../public/tags", 0755, true);
|
|
||||||
} else {
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_file($location)) {
|
|
||||||
file_put_contents($location, $html);
|
|
||||||
} else {
|
|
||||||
($new = fopen($location, "w")) or die("Unable to open file!");
|
|
||||||
fwrite($new, $html);
|
|
||||||
fclose($new);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function renderIndex()
|
|
||||||
{
|
|
||||||
//TODO: Need to fix this to account for new index templating system
|
|
||||||
$pages = (new Book())->getContents();
|
|
||||||
$index = find($pages, ["layout" => "index"]);
|
|
||||||
$template = $this->theme . "/index.twig";
|
|
||||||
$location = "../public/index.html";
|
|
||||||
$dir = null;
|
|
||||||
|
|
||||||
$meta = [
|
|
||||||
"who" => $index["author"],
|
|
||||||
"when" => $index["created"],
|
|
||||||
];
|
|
||||||
|
|
||||||
$pageOptions = [
|
|
||||||
"title" => $index["title"],
|
|
||||||
"background" => $index["feature"],
|
|
||||||
"meta" => $meta,
|
|
||||||
];
|
|
||||||
|
|
||||||
$html = $this->twig->render($template, $pageOptions);
|
|
||||||
DocTools::writeHTML($location, $html, $dir);
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,206 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace brain\data;
|
||||||
|
|
||||||
|
use Mni\FrontYAML\Parser;
|
||||||
|
use brain\data\Settings;
|
||||||
|
use brain\data\Book;
|
||||||
|
use brain\utility\Sorting;
|
||||||
|
use brain\utility\DocTools;
|
||||||
|
|
||||||
|
use function _\find;
|
||||||
|
|
||||||
|
class Render
|
||||||
|
{
|
||||||
|
public $loader;
|
||||||
|
public $twig;
|
||||||
|
public $pageInfo;
|
||||||
|
public $menu;
|
||||||
|
public $background;
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$config = new Settings();
|
||||||
|
//TODO: Add theme folder to loader
|
||||||
|
$settings = $config->getSettings();
|
||||||
|
$this->menu = $settings["menu"];
|
||||||
|
$this->theme = $settings["global"]["theme"];
|
||||||
|
$this->loader = new \Twig\Loader\FilesystemLoader("../content/themes/" . $this->theme);
|
||||||
|
$this->twig = new \Twig\Environment($this->loader, []);
|
||||||
|
$this->pageInfo = [
|
||||||
|
"keywords" => isset($settings["global"]["keywords"])
|
||||||
|
? $settings["global"]["keywords"]
|
||||||
|
: "fipamo, blog, jamstack, php, markdown, js",
|
||||||
|
"description" => $settings["global"]["descriptions"],
|
||||||
|
"image" =>
|
||||||
|
$settings["global"]["base_url"] . $settings["global"]["background"],
|
||||||
|
"baseURL" => $settings["global"]["base_url"],
|
||||||
|
];
|
||||||
|
//move global theme image assets to public folder
|
||||||
|
foreach (
|
||||||
|
new \DirectoryIterator("../content/themes/" . $this->theme . "/assets/images/global/") as $file
|
||||||
|
) {
|
||||||
|
if ($file->isDot()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!is_file("../public/assets/images/global/" . $file->getFileName())) {
|
||||||
|
copy(
|
||||||
|
"../content/themes/" .
|
||||||
|
$this->theme .
|
||||||
|
"/assets/images/global/" .
|
||||||
|
$file->getFileName(),
|
||||||
|
"../public/assets/images/global/" . $file->getFileName()
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
//image is already there, so chill
|
||||||
|
}
|
||||||
|
//print $file->getFilename() . "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
//copy current theme assets to public
|
||||||
|
|
||||||
|
//clear files in css and scripts folder
|
||||||
|
$styles = glob('../public/assets/css/*'); // get all file names
|
||||||
|
foreach ($styles as $file) { // iterate files
|
||||||
|
if (is_file($file)) {
|
||||||
|
//don't erase dashboard css
|
||||||
|
if (!$file == '../public/assets/css/dash.css') {
|
||||||
|
unlink($file); // delete file
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$scripts = glob('../public/assets/scripts/*'); // get all file names
|
||||||
|
foreach ($scripts as $file) { // iterate files
|
||||||
|
if (is_file($file)) {
|
||||||
|
if (!$file == "../public/assets/scripts/Start.js") {
|
||||||
|
unlink($file); // delete file
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//copy theme assets to public
|
||||||
|
$newcss = glob("../content/themes/" . $this->theme . "/assets/css/*");
|
||||||
|
foreach ($newcss as $file) { // iterate files
|
||||||
|
if (is_file($file)) {
|
||||||
|
$path = explode("/", $file);
|
||||||
|
copy($file, "../public/assets/css/" . $path[6]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$newjs = glob("../content/themes/" . $this->theme . "/assets/scripts/*");
|
||||||
|
foreach ($newjs as $file) { // iterate files
|
||||||
|
if (is_file($file)) {
|
||||||
|
$path = explode("/", $file);
|
||||||
|
copy($file, "../public/assets/scripts/" . $path[6]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function renderPages()
|
||||||
|
{
|
||||||
|
$pages = (new Book())->getContents();
|
||||||
|
$recent = [];
|
||||||
|
$featured = [];
|
||||||
|
$limit = 4;
|
||||||
|
foreach ($pages as $page) {
|
||||||
|
$pageOptions = Sorting::page($page);
|
||||||
|
|
||||||
|
$layout = $page["layout"];
|
||||||
|
//new pages have no layout, so defautl for now
|
||||||
|
if ($layout == "" || $layout == null) {
|
||||||
|
$layout = "page";
|
||||||
|
}
|
||||||
|
|
||||||
|
$template = $layout . ".twig";
|
||||||
|
if (str_contains($page["layout"], "index")) {
|
||||||
|
$location = "../public/index.html";
|
||||||
|
$dir = null;
|
||||||
|
} else {
|
||||||
|
// if page is a menu item, render the page on public root
|
||||||
|
if ($page["menu"] == "true") {
|
||||||
|
$location = "../public/" . $page["slug"] . ".html";
|
||||||
|
$dir = "../public/";
|
||||||
|
} else {
|
||||||
|
$location =
|
||||||
|
"../public/" . $page["path"] . "/" . $page["slug"] . ".html";
|
||||||
|
$dir = "../public/" . $page["path"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$html = $this->twig->render($template, $pageOptions);
|
||||||
|
DocTools::writeHTML($location, $html, $dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function renderArchive()
|
||||||
|
{
|
||||||
|
$archive = Sorting::archive();
|
||||||
|
$template = "archive.twig";
|
||||||
|
$pageOptions = [
|
||||||
|
"title" => "Archive",
|
||||||
|
"background" => $this->pageInfo["image"],
|
||||||
|
"archives" => $archive,
|
||||||
|
"info" => $this->pageInfo,
|
||||||
|
"menu" => $this->menu,
|
||||||
|
];
|
||||||
|
|
||||||
|
$html = $this->twig->render($template, $pageOptions);
|
||||||
|
$location = "../public/archives.html";
|
||||||
|
DocTools::writeHTML($location, $html);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function renderTags()
|
||||||
|
{
|
||||||
|
$list = Sorting::tags();
|
||||||
|
foreach ($list as $item) {
|
||||||
|
$template = "tags.twig";
|
||||||
|
$pageOptions = [
|
||||||
|
"title" => "Pages Tagged as " . $item["tag_name"],
|
||||||
|
"background" => $this->pageInfo["image"],
|
||||||
|
"tag_list" => $item["pages"],
|
||||||
|
"info" => $this->pageInfo,
|
||||||
|
"menu" => $this->menu,
|
||||||
|
];
|
||||||
|
|
||||||
|
$html = $this->twig->render($template, $pageOptions);
|
||||||
|
|
||||||
|
$location = "../public/tags/" . $item["slug"] . ".html";
|
||||||
|
|
||||||
|
//if tags folder doesn't exist, make it
|
||||||
|
if (!is_dir("../public/tags")) {
|
||||||
|
mkdir("../public/tags", 0755, true);
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_file($location)) {
|
||||||
|
file_put_contents($location, $html);
|
||||||
|
} else {
|
||||||
|
($new = fopen($location, "w")) or die("Unable to open file!");
|
||||||
|
fwrite($new, $html);
|
||||||
|
fclose($new);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function renderIndex()
|
||||||
|
{
|
||||||
|
//TODO: Need to fix this to account for new index templating system
|
||||||
|
$pages = (new Book())->getContents();
|
||||||
|
$index = find($pages, ["layout" => "index"]);
|
||||||
|
$template = "index.twig";
|
||||||
|
$location = "../public/index.html";
|
||||||
|
$dir = null;
|
||||||
|
|
||||||
|
$meta = [
|
||||||
|
"who" => $index["author"],
|
||||||
|
"when" => $index["created"],
|
||||||
|
];
|
||||||
|
|
||||||
|
$pageOptions = [
|
||||||
|
"title" => $index["title"],
|
||||||
|
"background" => $index["feature"],
|
||||||
|
"meta" => $meta,
|
||||||
|
];
|
||||||
|
|
||||||
|
$html = $this->twig->render($template, $pageOptions);
|
||||||
|
DocTools::writeHTML($location, $html, $dir);
|
||||||
|
}
|
||||||
|
}
|
@ -1,90 +0,0 @@
|
|||||||
<?php
|
|
||||||
use function _\find;
|
|
||||||
use ReallySimpleJWT\Token;
|
|
||||||
|
|
||||||
class Session
|
|
||||||
{
|
|
||||||
private static $file = "../content/.session";
|
|
||||||
private static $data = [
|
|
||||||
"member" => "",
|
|
||||||
"token" => "",
|
|
||||||
"form_token" => "",
|
|
||||||
];
|
|
||||||
public static function start()
|
|
||||||
{
|
|
||||||
if (!is_file(self::$file)) {
|
|
||||||
file_put_contents(self::$file, json_encode(self::$data));
|
|
||||||
} else {
|
|
||||||
($new = fopen(self::$file, "w")) or die("Unable to open file!");
|
|
||||||
fwrite($new, json_encode(self::$data));
|
|
||||||
fclose($new);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function active()
|
|
||||||
{
|
|
||||||
if (!is_file(self::$file)) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
$data = json_decode(file_get_contents(self::$file), true);
|
|
||||||
if ($data["member"] != null) {
|
|
||||||
$secret = (new Settings())->getFolks("secret");
|
|
||||||
if ($secret == null) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
if (
|
|
||||||
Token::validate($data["token"], $secret) &&
|
|
||||||
Token::validateExpiration($data["token"], $secret)
|
|
||||||
) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
$data = json_decode(file_get_contents(self::$file), true);
|
|
||||||
$data[$key] = $value;
|
|
||||||
($fresh = fopen(self::$file, "w")) or die("Unable to open file!");
|
|
||||||
fwrite($fresh, json_encode($data));
|
|
||||||
fclose($fresh);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function get($key)
|
|
||||||
{
|
|
||||||
$data = json_decode(file_get_contents(self::$file), true);
|
|
||||||
|
|
||||||
return $data[$key];
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function kill()
|
|
||||||
{
|
|
||||||
($fresh = fopen(self::$file, "w")) or die("Unable to open file!");
|
|
||||||
fwrite($fresh, json_encode(self::$data));
|
|
||||||
fclose($fresh);
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,94 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace brain\data;
|
||||||
|
|
||||||
|
use ReallySimpleJWT\Token;
|
||||||
|
|
||||||
|
use function _\find;
|
||||||
|
|
||||||
|
class Session
|
||||||
|
{
|
||||||
|
private static $file = "../content/.session";
|
||||||
|
private static $data = [
|
||||||
|
"member" => "",
|
||||||
|
"token" => "",
|
||||||
|
"form_token" => "",
|
||||||
|
];
|
||||||
|
public static function start()
|
||||||
|
{
|
||||||
|
if (!is_file(self::$file)) {
|
||||||
|
file_put_contents(self::$file, json_encode(self::$data));
|
||||||
|
} else {
|
||||||
|
($new = fopen(self::$file, "w")) or die("Unable to open file!");
|
||||||
|
fwrite($new, json_encode(self::$data));
|
||||||
|
fclose($new);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function active()
|
||||||
|
{
|
||||||
|
if (!is_file(self::$file)) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
$data = json_decode(file_get_contents(self::$file), true);
|
||||||
|
if ($data["member"] != null) {
|
||||||
|
$secret = (new Settings())->getFolks("secret");
|
||||||
|
if ($secret == null) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
if (
|
||||||
|
Token::validate($data["token"], $secret) &&
|
||||||
|
Token::validateExpiration($data["token"], $secret)
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
$data = json_decode(file_get_contents(self::$file), true);
|
||||||
|
$data[$key] = $value;
|
||||||
|
($fresh = fopen(self::$file, "w")) or die("Unable to open file!");
|
||||||
|
fwrite($fresh, json_encode($data));
|
||||||
|
fclose($fresh);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function get($key)
|
||||||
|
{
|
||||||
|
$data = json_decode(file_get_contents(self::$file), true);
|
||||||
|
|
||||||
|
return $data[$key];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function kill()
|
||||||
|
{
|
||||||
|
($fresh = fopen(self::$file, "w")) or die("Unable to open file!");
|
||||||
|
fwrite($fresh, json_encode(self::$data));
|
||||||
|
fclose($fresh);
|
||||||
|
}
|
||||||
|
}
|
@ -1,169 +0,0 @@
|
|||||||
<?php
|
|
||||||
use function _\find;
|
|
||||||
use function _\pull;
|
|
||||||
use function _\remove;
|
|
||||||
class Settings
|
|
||||||
{
|
|
||||||
private $folks;
|
|
||||||
private static $tags;
|
|
||||||
private static $settings;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
//gets all settings files and converts to php objects
|
|
||||||
$this->folks = json_decode(file_get_contents("../config/folks.json"), true);
|
|
||||||
self::$tags = json_decode(file_get_contents("../config/tags.json"), true);
|
|
||||||
self::$settings = json_decode(
|
|
||||||
file_get_contents("../config/settings.json"),
|
|
||||||
true
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function sync($data)
|
|
||||||
{
|
|
||||||
$settings = self::$settings;
|
|
||||||
$settings["global"]["base_url"] = $data["global"]["base_url"];
|
|
||||||
$settings["global"]["title"] = $data["global"]["title"];
|
|
||||||
$settings["global"]["descriptions"] = $data["global"]["descriptions"];
|
|
||||||
$settings["global"]["base_url"] = $data["global"]["base_url"];
|
|
||||||
$settings["global"]["private"] = $data["global"]["private"];
|
|
||||||
$settings["global"]["renderOnSave"] = $data["global"]["renderOnSave"];
|
|
||||||
$settings["global"]["theme"] = $data["global"]["theme"];
|
|
||||||
$settings["global"]["externalAPI"] = $data["global"]["externalAPI"];
|
|
||||||
$settings["global"]["dynamicRender"] = $data["global"]["dynamicRender"];
|
|
||||||
|
|
||||||
Member::updateData("handle", $data["member"]["handle"]);
|
|
||||||
Member::updateData("email", $data["member"]["email"]);
|
|
||||||
|
|
||||||
$settings["email"]["active"] = $data["email"]["active"];
|
|
||||||
$settings["email"]["smtp"] = $data["email"]["smtp"];
|
|
||||||
$settings["email"]["mailgun"] = $data["email"]["mailgun"];
|
|
||||||
|
|
||||||
DocTools::writeSettings("../config/settings.json", $settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function navSync($data)
|
|
||||||
{
|
|
||||||
$settings = self::$settings;
|
|
||||||
|
|
||||||
$remove = $data["remove"];
|
|
||||||
//if remove contains id, find nav item page and set menu to false
|
|
||||||
if ($remove != null || $remove != "") {
|
|
||||||
$page = (new Book("../content/pages"))->findPageById($remove);
|
|
||||||
$page["menu"] = "false";
|
|
||||||
$page["published"]
|
|
||||||
? ($page["published"] = "true")
|
|
||||||
: ($page["published"] = "false");
|
|
||||||
$page["featured"]
|
|
||||||
? ($page["featured"] = "true")
|
|
||||||
: ($page["featured"] = "false");
|
|
||||||
$page["deleted"]
|
|
||||||
? ($page["deleted"] = "true")
|
|
||||||
: ($page["deleted"] = "false");
|
|
||||||
$updated = new \Moment\Moment();
|
|
||||||
$created = new \Moment\Moment($page["rawCreated"]);
|
|
||||||
$page["created"] = $created->format("Y-m-d\TH:i:sP");
|
|
||||||
$page["updated"] = $updated->format("Y-m-d\TH:i:sP");
|
|
||||||
|
|
||||||
$md = DocTools::objectToMD($page);
|
|
||||||
|
|
||||||
if ($page["layout"] == "index") {
|
|
||||||
$writePath = "../content/pages/start/index.md";
|
|
||||||
} else {
|
|
||||||
$writePath =
|
|
||||||
"../content/pages/" . $page["path"] . "/" . $page["slug"] . ".md";
|
|
||||||
}
|
|
||||||
|
|
||||||
DocTools::writePages("write", $page["path"], $writePath, $md);
|
|
||||||
}
|
|
||||||
|
|
||||||
$settings["menu"] = [];
|
|
||||||
$items = $data["menu"];
|
|
||||||
foreach ($items as $item) {
|
|
||||||
array_push($settings["menu"], [
|
|
||||||
"title" => $item["title"],
|
|
||||||
"id" => $item["id"],
|
|
||||||
"uuid" => $item["uuid"],
|
|
||||||
"slug" => $item["slug"],
|
|
||||||
"path" => $item["path"],
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
DocTools::writeSettings("../config/settings.json", $settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getFolks($key = null)
|
|
||||||
{
|
|
||||||
if (isset($key)) {
|
|
||||||
$member = Session::get("member");
|
|
||||||
$found = find($this->folks, ["handle" => $member["handle"]]);
|
|
||||||
if ($found) {
|
|
||||||
return $found[$key];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return $this->folks;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSettings($key = null)
|
|
||||||
{
|
|
||||||
return self::$settings;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getTags()
|
|
||||||
{
|
|
||||||
return self::$tags;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function updateGlobalData($key, $data)
|
|
||||||
{
|
|
||||||
$settings = self::$settings;
|
|
||||||
$settings["global"][$key] = $data;
|
|
||||||
DocTools::writeSettings("../config/settings.json", $settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getCurrentIndex()
|
|
||||||
{
|
|
||||||
$settings = self::$settings;
|
|
||||||
return $settings["library_stats"]["current_index"];
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function updateIndex()
|
|
||||||
{
|
|
||||||
$settings = self::$settings;
|
|
||||||
|
|
||||||
$settings["library_stats"]["current_index"] =
|
|
||||||
$settings["library_stats"]["current_index"] + 1;
|
|
||||||
|
|
||||||
DocTools::writeSettings("../config/settings.json", $settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function updateMenu($body)
|
|
||||||
{
|
|
||||||
$settings = self::$settings;
|
|
||||||
//$menu = $settings["menu"];
|
|
||||||
$item = [
|
|
||||||
"title" => $body["title"],
|
|
||||||
"id" => $body["id"],
|
|
||||||
"uuid" => $body["uuid"],
|
|
||||||
"slug" => $body["slug"],
|
|
||||||
"path" => $body["path"],
|
|
||||||
];
|
|
||||||
if ($body["menu"] == "true") {
|
|
||||||
if (!find($settings["menu"], ["uuid" => $item["uuid"]])) {
|
|
||||||
array_push($settings["menu"], $item);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (find($settings["menu"], ["uuid" => $item["uuid"]])) {
|
|
||||||
pull($settings["menu"], $item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DocTools::writeSettings("../config/settings.json", $settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function updateTags()
|
|
||||||
{
|
|
||||||
$tags = Sorting::tags();
|
|
||||||
DocTools::writeSettings("../config/tags.json", $tags);
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,177 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace brain\data;
|
||||||
|
|
||||||
|
use brain\data\Member;
|
||||||
|
use brain\utility\DocTools;
|
||||||
|
use brain\utility\Sorting;
|
||||||
|
|
||||||
|
use function _\find;
|
||||||
|
use function _\pull;
|
||||||
|
use function _\remove;
|
||||||
|
|
||||||
|
class Settings
|
||||||
|
{
|
||||||
|
private $folks;
|
||||||
|
private static $tags;
|
||||||
|
private static $settings;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
//gets all settings files and converts to php objects
|
||||||
|
$this->folks = json_decode(file_get_contents("../config/folks.json"), true);
|
||||||
|
self::$tags = json_decode(file_get_contents("../config/tags.json"), true);
|
||||||
|
self::$settings = json_decode(
|
||||||
|
file_get_contents("../config/settings.json"),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function sync($data)
|
||||||
|
{
|
||||||
|
$settings = self::$settings;
|
||||||
|
$settings["global"]["base_url"] = $data["global"]["base_url"];
|
||||||
|
$settings["global"]["title"] = $data["global"]["title"];
|
||||||
|
$settings["global"]["descriptions"] = $data["global"]["descriptions"];
|
||||||
|
$settings["global"]["base_url"] = $data["global"]["base_url"];
|
||||||
|
$settings["global"]["private"] = $data["global"]["private"];
|
||||||
|
$settings["global"]["renderOnSave"] = $data["global"]["renderOnSave"];
|
||||||
|
$settings["global"]["theme"] = $data["global"]["theme"];
|
||||||
|
$settings["global"]["externalAPI"] = $data["global"]["externalAPI"];
|
||||||
|
$settings["global"]["dynamicRender"] = $data["global"]["dynamicRender"];
|
||||||
|
|
||||||
|
Member::updateData("handle", $data["member"]["handle"]);
|
||||||
|
Member::updateData("email", $data["member"]["email"]);
|
||||||
|
|
||||||
|
$settings["email"]["active"] = $data["email"]["active"];
|
||||||
|
$settings["email"]["smtp"] = $data["email"]["smtp"];
|
||||||
|
$settings["email"]["mailgun"] = $data["email"]["mailgun"];
|
||||||
|
|
||||||
|
DocTools::writeSettings("../config/settings.json", $settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function navSync($data)
|
||||||
|
{
|
||||||
|
$settings = self::$settings;
|
||||||
|
|
||||||
|
$remove = $data["remove"];
|
||||||
|
//if remove contains id, find nav item page and set menu to false
|
||||||
|
if ($remove != null || $remove != "") {
|
||||||
|
$page = (new Book("../content/pages"))->findPageById($remove);
|
||||||
|
$page["menu"] = "false";
|
||||||
|
$page["published"]
|
||||||
|
? ($page["published"] = "true")
|
||||||
|
: ($page["published"] = "false");
|
||||||
|
$page["featured"]
|
||||||
|
? ($page["featured"] = "true")
|
||||||
|
: ($page["featured"] = "false");
|
||||||
|
$page["deleted"]
|
||||||
|
? ($page["deleted"] = "true")
|
||||||
|
: ($page["deleted"] = "false");
|
||||||
|
$updated = new \Moment\Moment();
|
||||||
|
$created = new \Moment\Moment($page["rawCreated"]);
|
||||||
|
$page["created"] = $created->format("Y-m-d\TH:i:sP");
|
||||||
|
$page["updated"] = $updated->format("Y-m-d\TH:i:sP");
|
||||||
|
|
||||||
|
$md = DocTools::objectToMD($page);
|
||||||
|
|
||||||
|
if ($page["layout"] == "index") {
|
||||||
|
$writePath = "../content/pages/start/index.md";
|
||||||
|
} else {
|
||||||
|
$writePath =
|
||||||
|
"../content/pages/" . $page["path"] . "/" . $page["slug"] . ".md";
|
||||||
|
}
|
||||||
|
|
||||||
|
DocTools::writePages("write", $page["path"], $writePath, $md);
|
||||||
|
}
|
||||||
|
|
||||||
|
$settings["menu"] = [];
|
||||||
|
$items = $data["menu"];
|
||||||
|
foreach ($items as $item) {
|
||||||
|
array_push($settings["menu"], [
|
||||||
|
"title" => $item["title"],
|
||||||
|
"id" => $item["id"],
|
||||||
|
"uuid" => $item["uuid"],
|
||||||
|
"slug" => $item["slug"],
|
||||||
|
"path" => $item["path"],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
DocTools::writeSettings("../config/settings.json", $settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFolks($key = null)
|
||||||
|
{
|
||||||
|
if (isset($key)) {
|
||||||
|
$member = Session::get("member");
|
||||||
|
$found = find($this->folks, ["handle" => $member["handle"]]);
|
||||||
|
if ($found) {
|
||||||
|
return $found[$key];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return $this->folks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSettings($key = null)
|
||||||
|
{
|
||||||
|
return self::$settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getTags()
|
||||||
|
{
|
||||||
|
return self::$tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function updateGlobalData($key, $data)
|
||||||
|
{
|
||||||
|
$settings = self::$settings;
|
||||||
|
$settings["global"][$key] = $data;
|
||||||
|
DocTools::writeSettings("../config/settings.json", $settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getCurrentIndex()
|
||||||
|
{
|
||||||
|
$settings = self::$settings;
|
||||||
|
return $settings["library_stats"]["current_index"];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function updateIndex()
|
||||||
|
{
|
||||||
|
$settings = self::$settings;
|
||||||
|
|
||||||
|
$settings["library_stats"]["current_index"] =
|
||||||
|
$settings["library_stats"]["current_index"] + 1;
|
||||||
|
|
||||||
|
DocTools::writeSettings("../config/settings.json", $settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function updateMenu($body)
|
||||||
|
{
|
||||||
|
$settings = self::$settings;
|
||||||
|
//$menu = $settings["menu"];
|
||||||
|
$item = [
|
||||||
|
"title" => $body["title"],
|
||||||
|
"id" => $body["id"],
|
||||||
|
"uuid" => $body["uuid"],
|
||||||
|
"slug" => $body["slug"],
|
||||||
|
"path" => $body["path"],
|
||||||
|
];
|
||||||
|
if ($body["menu"] == "true") {
|
||||||
|
if (!find($settings["menu"], ["uuid" => $item["uuid"]])) {
|
||||||
|
array_push($settings["menu"], $item);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (find($settings["menu"], ["uuid" => $item["uuid"]])) {
|
||||||
|
pull($settings["menu"], $item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DocTools::writeSettings("../config/settings.json", $settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function updateTags()
|
||||||
|
{
|
||||||
|
$tags = Sorting::tags();
|
||||||
|
DocTools::writeSettings("../config/tags.json", $tags);
|
||||||
|
}
|
||||||
|
}
|
@ -1,60 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class Themes
|
|
||||||
{
|
|
||||||
private $themes = [];
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$_themes = glob("../content/themes/*", GLOB_ONLYDIR);
|
|
||||||
foreach ($_themes as $theme) {
|
|
||||||
array_push(
|
|
||||||
$this->themes,
|
|
||||||
json_decode(file_get_contents($theme . "/theme.json"), true)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getThemes()
|
|
||||||
{
|
|
||||||
return $this->themes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getCustomIndex()
|
|
||||||
{
|
|
||||||
$settings = (new Settings())->getSettings();
|
|
||||||
$currentTheme = $settings["global"]["theme"];
|
|
||||||
$folder = "../content/themes/" . $currentTheme;
|
|
||||||
$files = array_filter(glob("$folder/*twig"), "is_file");
|
|
||||||
$views = [];
|
|
||||||
|
|
||||||
foreach ($files as $file) {
|
|
||||||
$path = explode("/", $file);
|
|
||||||
$fileName = $path[4];
|
|
||||||
if (str_contains($fileName, "index")) {
|
|
||||||
$page = explode(".", $fileName);
|
|
||||||
$views[] = $page[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $views;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getCustomViews()
|
|
||||||
{
|
|
||||||
$settings = (new Settings())->getSettings();
|
|
||||||
$currentTheme = $settings["global"]["theme"];
|
|
||||||
$folder = "../content/themes/" . $currentTheme;
|
|
||||||
$files = array_filter(glob("$folder/*twig"), "is_file");
|
|
||||||
$views = [];
|
|
||||||
|
|
||||||
foreach ($files as $file) {
|
|
||||||
$path = explode("/", $file);
|
|
||||||
$fileName = $path[4];
|
|
||||||
if (str_contains($fileName, "page")) {
|
|
||||||
$page = explode(".", $fileName);
|
|
||||||
$views[] = $page[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $views;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,64 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace brain\data;
|
||||||
|
|
||||||
|
use brain\data\Settings;
|
||||||
|
|
||||||
|
class Themes
|
||||||
|
{
|
||||||
|
private $themes = [];
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$_themes = glob("../content/themes/*", GLOB_ONLYDIR);
|
||||||
|
foreach ($_themes as $theme) {
|
||||||
|
array_push(
|
||||||
|
$this->themes,
|
||||||
|
json_decode(file_get_contents($theme . "/theme.json"), true)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getThemes()
|
||||||
|
{
|
||||||
|
return $this->themes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCustomIndex()
|
||||||
|
{
|
||||||
|
$settings = (new Settings())->getSettings();
|
||||||
|
$currentTheme = $settings["global"]["theme"];
|
||||||
|
$folder = "../content/themes/" . $currentTheme;
|
||||||
|
$files = array_filter(glob("$folder/*twig"), "is_file");
|
||||||
|
$views = [];
|
||||||
|
|
||||||
|
foreach ($files as $file) {
|
||||||
|
$path = explode("/", $file);
|
||||||
|
$fileName = $path[4];
|
||||||
|
if (str_contains($fileName, "index")) {
|
||||||
|
$page = explode(".", $fileName);
|
||||||
|
$views[] = $page[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $views;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCustomViews()
|
||||||
|
{
|
||||||
|
$settings = (new Settings())->getSettings();
|
||||||
|
$currentTheme = $settings["global"]["theme"];
|
||||||
|
$folder = "../content/themes/" . $currentTheme;
|
||||||
|
$files = array_filter(glob("$folder/*twig"), "is_file");
|
||||||
|
$views = [];
|
||||||
|
|
||||||
|
foreach ($files as $file) {
|
||||||
|
$path = explode("/", $file);
|
||||||
|
$fileName = $path[4];
|
||||||
|
if (str_contains($fileName, "page")) {
|
||||||
|
$page = explode(".", $fileName);
|
||||||
|
$views[] = $page[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $views;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace brain\init;
|
||||||
|
|
||||||
|
use Psr\Http\Message\ResponseInterface as Response;
|
||||||
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
|
use Slim\Factory\AppFactory;
|
||||||
|
use Slim\Views\Twig;
|
||||||
|
use Slim\Views\TwigMiddleware;
|
||||||
|
// Fipamo Core Classes
|
||||||
|
use brain\utility\HandleCors;
|
||||||
|
|
||||||
|
class App
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
// when a new class is made, run composer dump-autoload
|
||||||
|
// set up cors
|
||||||
|
new HandleCors();
|
||||||
|
$app = AppFactory::create();
|
||||||
|
$twig = Twig::create("../brain/views/");
|
||||||
|
$app->add(TwigMiddleware::create($app, $twig));
|
||||||
|
//set up routing
|
||||||
|
$app->get(
|
||||||
|
"/[{first}[/{second}[/{third}[/{fourth}[/{fifth}]]]]]",
|
||||||
|
"brain\controller\RouteControl:get"
|
||||||
|
);
|
||||||
|
$app->post(
|
||||||
|
"/[{first}[/{second}[/{third}[/{fourth}]]]]",
|
||||||
|
"brain\controller\RouteControl:post"
|
||||||
|
);
|
||||||
|
//start the app
|
||||||
|
|
||||||
|
$app->run();
|
||||||
|
}
|
||||||
|
}
|
@ -1,140 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class DocTools
|
|
||||||
{
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function writePages($task, $path, $fileLocation, $fileContents)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
if ($task == "create") {
|
|
||||||
if (!is_dir("../content/pages/" . $path)) {
|
|
||||||
//Directory does not exist, so lets create it.
|
|
||||||
mkdir("../content/pages/" . $path, 0755, true);
|
|
||||||
}
|
|
||||||
file_put_contents($fileLocation, $fileContents);
|
|
||||||
} else {
|
|
||||||
($new = fopen($fileLocation, "w")) or die("Unable to open file!");
|
|
||||||
fwrite($new, $fileContents);
|
|
||||||
fclose($new);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} catch (Error $error) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function writeSettings($fileLocation, $fileContents)
|
|
||||||
{
|
|
||||||
if (!is_file($fileLocation)) {
|
|
||||||
file_put_contents($fileLocation, json_encode($fileContents));
|
|
||||||
} else {
|
|
||||||
($new = fopen($fileLocation, "w")) or die("Unable to open file!");
|
|
||||||
fwrite($new, json_encode($fileContents));
|
|
||||||
fclose($new);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function writeHTML($location, $html, $path = null)
|
|
||||||
{
|
|
||||||
if ($path != null) {
|
|
||||||
if (!is_dir($path)) {
|
|
||||||
//Directory does not exist, so lets create it.
|
|
||||||
mkdir($path, 0755, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!is_file($location)) {
|
|
||||||
file_put_contents($location, $html);
|
|
||||||
} else {
|
|
||||||
($new = fopen($location, "w")) or die("Unable to open file!");
|
|
||||||
fwrite($new, $html);
|
|
||||||
fclose($new);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function deleteFolder($path)
|
|
||||||
{
|
|
||||||
if (!empty($path) && is_dir($path)) {
|
|
||||||
$dir = new RecursiveDirectoryIterator(
|
|
||||||
$path,
|
|
||||||
RecursiveDirectoryIterator::SKIP_DOTS
|
|
||||||
); //upper dirs are not included,otherwise DISASTER HAPPENS :)
|
|
||||||
$files = new RecursiveIteratorIterator(
|
|
||||||
$dir,
|
|
||||||
RecursiveIteratorIterator::CHILD_FIRST
|
|
||||||
);
|
|
||||||
foreach ($files as $f) {
|
|
||||||
if (is_file($f)) {
|
|
||||||
unlink($f);
|
|
||||||
} else {
|
|
||||||
$empty_dirs[] = $f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!empty($empty_dirs)) {
|
|
||||||
foreach ($empty_dirs as $eachDir) {
|
|
||||||
rmdir($eachDir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rmdir($path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function objectToMD($object)
|
|
||||||
{
|
|
||||||
$markdown =
|
|
||||||
"---\n" .
|
|
||||||
"id: " .
|
|
||||||
$object["id"] .
|
|
||||||
"\n" .
|
|
||||||
"uuid: " .
|
|
||||||
$object["uuid"] .
|
|
||||||
"\n" .
|
|
||||||
"title: " .
|
|
||||||
"'" .
|
|
||||||
$object["title"] .
|
|
||||||
"'" .
|
|
||||||
"\n" .
|
|
||||||
"feature: " .
|
|
||||||
$object["feature"] .
|
|
||||||
"\n" .
|
|
||||||
"path: " .
|
|
||||||
$object["path"] .
|
|
||||||
"\n" .
|
|
||||||
"layout: " .
|
|
||||||
$object["layout"] .
|
|
||||||
"\n" .
|
|
||||||
"tags: " .
|
|
||||||
$object["tags"] .
|
|
||||||
"\n" .
|
|
||||||
"author: " .
|
|
||||||
$object["author"] .
|
|
||||||
"\n" .
|
|
||||||
"created: " .
|
|
||||||
$object["created"] .
|
|
||||||
"\n" .
|
|
||||||
"updated: " .
|
|
||||||
$object["updated"] .
|
|
||||||
"\n" .
|
|
||||||
"deleted: " .
|
|
||||||
$object["deleted"] .
|
|
||||||
"\n" .
|
|
||||||
"slug: " .
|
|
||||||
$object["slug"] .
|
|
||||||
"\n" .
|
|
||||||
"menu: " .
|
|
||||||
$object["menu"] .
|
|
||||||
"\n" .
|
|
||||||
"published: " .
|
|
||||||
$object["published"] .
|
|
||||||
"\n" .
|
|
||||||
"featured: " .
|
|
||||||
$object["featured"] .
|
|
||||||
"\n---\n" .
|
|
||||||
$object["content"];
|
|
||||||
|
|
||||||
return $markdown;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,145 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace brain\utility;
|
||||||
|
|
||||||
|
class DocTools
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function writePages($task, $path, $fileLocation, $fileContents)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if ($task == "create") {
|
||||||
|
if (!is_dir("../content/pages/" . $path)) {
|
||||||
|
//Directory does not exist, so lets create it.
|
||||||
|
mkdir("../content/pages/" . $path, 0755, true);
|
||||||
|
}
|
||||||
|
file_put_contents($fileLocation, $fileContents);
|
||||||
|
} else {
|
||||||
|
($new = fopen($fileLocation, "w")) or die("Unable to open file!");
|
||||||
|
fwrite($new, $fileContents);
|
||||||
|
fclose($new);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (Error $error) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function writeSettings($fileLocation, $fileContents)
|
||||||
|
{
|
||||||
|
if (!is_file($fileLocation)) {
|
||||||
|
file_put_contents($fileLocation, json_encode($fileContents));
|
||||||
|
} else {
|
||||||
|
($new = fopen($fileLocation, "w")) or die("Unable to open file!");
|
||||||
|
fwrite($new, json_encode($fileContents));
|
||||||
|
fclose($new);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function writeHTML($location, $html, $path = null)
|
||||||
|
{
|
||||||
|
if ($path != null) {
|
||||||
|
if (!is_dir($path)) {
|
||||||
|
//Directory does not exist, so lets create it.
|
||||||
|
mkdir($path, 0755, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!is_file($location)) {
|
||||||
|
file_put_contents($location, $html);
|
||||||
|
} else {
|
||||||
|
($new = fopen($location, "w")) or die("Unable to open file!");
|
||||||
|
fwrite($new, $html);
|
||||||
|
fclose($new);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function deleteFolder($path)
|
||||||
|
{
|
||||||
|
if (!empty($path) && is_dir($path)) {
|
||||||
|
$dir = new \RecursiveDirectoryIterator(
|
||||||
|
$path,
|
||||||
|
\RecursiveDirectoryIterator::SKIP_DOTS
|
||||||
|
); //upper dirs are not included,otherwise DISASTER HAPPENS :)
|
||||||
|
$files = new \RecursiveIteratorIterator(
|
||||||
|
$dir,
|
||||||
|
\RecursiveIteratorIterator::CHILD_FIRST
|
||||||
|
);
|
||||||
|
foreach ($files as $f) {
|
||||||
|
if (is_file($f)) {
|
||||||
|
unlink($f);
|
||||||
|
} else {
|
||||||
|
$empty_dirs[] = $f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!empty($empty_dirs)) {
|
||||||
|
foreach ($empty_dirs as $eachDir) {
|
||||||
|
rmdir($eachDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rmdir($path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function objectToMD($object)
|
||||||
|
{
|
||||||
|
$markdown =
|
||||||
|
"---\n" .
|
||||||
|
"id: " .
|
||||||
|
$object["id"] .
|
||||||
|
"\n" .
|
||||||
|
"uuid: " .
|
||||||
|
$object["uuid"] .
|
||||||
|
"\n" .
|
||||||
|
"title: " .
|
||||||
|
"'" .
|
||||||
|
$object["title"] .
|
||||||
|
"'" .
|
||||||
|
"\n" .
|
||||||
|
"feature: " .
|
||||||
|
$object["feature"] .
|
||||||
|
"\n" .
|
||||||
|
"files: " .
|
||||||
|
$object["files"] .
|
||||||
|
"\n" .
|
||||||
|
"path: " .
|
||||||
|
$object["path"] .
|
||||||
|
"\n" .
|
||||||
|
"layout: " .
|
||||||
|
$object["layout"] .
|
||||||
|
"\n" .
|
||||||
|
"tags: " .
|
||||||
|
$object["tags"] .
|
||||||
|
"\n" .
|
||||||
|
"author: " .
|
||||||
|
$object["author"] .
|
||||||
|
"\n" .
|
||||||
|
"created: " .
|
||||||
|
$object["created"] .
|
||||||
|
"\n" .
|
||||||
|
"updated: " .
|
||||||
|
$object["updated"] .
|
||||||
|
"\n" .
|
||||||
|
"deleted: " .
|
||||||
|
$object["deleted"] .
|
||||||
|
"\n" .
|
||||||
|
"slug: " .
|
||||||
|
$object["slug"] .
|
||||||
|
"\n" .
|
||||||
|
"menu: " .
|
||||||
|
$object["menu"] .
|
||||||
|
"\n" .
|
||||||
|
"published: " .
|
||||||
|
$object["published"] .
|
||||||
|
"\n" .
|
||||||
|
"featured: " .
|
||||||
|
$object["featured"] .
|
||||||
|
"\n---\n" .
|
||||||
|
$object["content"];
|
||||||
|
|
||||||
|
return $markdown;
|
||||||
|
}
|
||||||
|
}
|
@ -1,32 +0,0 @@
|
|||||||
<?php
|
|
||||||
use Psr\Http\Message\UploadedFileInterface;
|
|
||||||
//include "brain/data/Auth.inc.php";
|
|
||||||
define("MAXIMUM_FILESIZE", "10485760"); //10 MB
|
|
||||||
class FileUploader
|
|
||||||
{
|
|
||||||
public static function uploadFile(string $directory, $file)
|
|
||||||
{
|
|
||||||
$response = [];
|
|
||||||
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);
|
|
||||||
|
|
||||||
//echo "**FILE** " . $file->getClientFileName();
|
|
||||||
|
|
||||||
$file->moveTo($directory . "/" . $file->getClientFileName());
|
|
||||||
} catch (RuntimeException $e) {
|
|
||||||
echo "ERROR " . $e->getMessage();
|
|
||||||
|
|
||||||
//echo "failed to upload image: " . $e->getMessage();
|
|
||||||
//throw new Error("Failed to upload image file");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace brain\utility;
|
||||||
|
|
||||||
|
class FileUploader
|
||||||
|
{
|
||||||
|
public static function uploadFile(string $directory, $file)
|
||||||
|
{
|
||||||
|
$response = [];
|
||||||
|
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);
|
||||||
|
|
||||||
|
// echo "**FILE** " . $file->getClientFileName();
|
||||||
|
|
||||||
|
$file->moveTo($directory.'/'.urlencode($file->getClientFileName()));
|
||||||
|
} catch (RuntimeException $e) {
|
||||||
|
echo 'ERROR '.$e->getMessage();
|
||||||
|
|
||||||
|
// echo "failed to upload image: " . $e->getMessage();
|
||||||
|
// throw new Error("Failed to upload image file");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
class handleCors
|
namespace brain\utility;
|
||||||
|
|
||||||
|
use brain\data\Settings;
|
||||||
|
|
||||||
|
class HandleCors
|
||||||
{
|
{
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
@ -1,94 +0,0 @@
|
|||||||
<?php
|
|
||||||
use Slim\Views\Twig;
|
|
||||||
|
|
||||||
use PHPMailer\PHPMailer\PHPMailer;
|
|
||||||
use PHPMailer\PHPMailer\Exception;
|
|
||||||
|
|
||||||
class Mailer
|
|
||||||
{
|
|
||||||
public static function sendMail($body)
|
|
||||||
{
|
|
||||||
$config = new Settings();
|
|
||||||
$settings = $config->getSettings();
|
|
||||||
$mailConfig = $settings["email"];
|
|
||||||
$mail = new PHPMailer();
|
|
||||||
|
|
||||||
switch ($body["mail_task"]) {
|
|
||||||
case "TESTING":
|
|
||||||
$html =
|
|
||||||
"<h1>Hi! It's Fipamo!</h1><br>" .
|
|
||||||
"<strong>It's just a test</strong><br>" .
|
|
||||||
$body["content"];
|
|
||||||
$member = Session::get("member");
|
|
||||||
$mail->addAddress($member["email"], ""); //pull email address from current user
|
|
||||||
$mail->Subject = "A test email";
|
|
||||||
break;
|
|
||||||
case "SEND_SECRET":
|
|
||||||
$html =
|
|
||||||
"<h1>Hi! It's Fipamo!</h1><br>" .
|
|
||||||
"<strong>This is your secret key.</strong><br><br>" .
|
|
||||||
"<h3>" .
|
|
||||||
$body["secret"] .
|
|
||||||
"</h3>" .
|
|
||||||
"<br> Use this key to reset your password.";
|
|
||||||
$mail->addAddress($body["email"], ""); //pull email address from current user
|
|
||||||
$mail->Subject = "Shhhh! It's a secret!";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return $result = [
|
|
||||||
"type" => "noMailService",
|
|
||||||
"message" => "Mail task is undefined. What are you doing??",
|
|
||||||
];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
//set values based on current active protocol
|
|
||||||
switch ($mailConfig["active"]) {
|
|
||||||
case "option-smtp":
|
|
||||||
$mail->setFrom($mailConfig["smtp"]["email"], "System Email");
|
|
||||||
$mail->Host = "playvicio.us";
|
|
||||||
$mail->Username = $mailConfig["smtp"]["email"];
|
|
||||||
$mail->Password = $mailConfig["smtp"]["password"];
|
|
||||||
|
|
||||||
break;
|
|
||||||
case "option-mg":
|
|
||||||
$mail->setFrom($mailConfig["mailgun"]["domain"], "No Reply");
|
|
||||||
$mail->Host = "smtp.mailgun.org";
|
|
||||||
$mail->Username = $mailConfig["mailgun"]["domain"];
|
|
||||||
$mail->Password = $mailConfig["mailgun"]["key"];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
//no mail service
|
|
||||||
return $result = [
|
|
||||||
"type" => "noMailService",
|
|
||||||
"message" => "Mail is not configured. Handle that.",
|
|
||||||
];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$mail->Body = $html;
|
|
||||||
$mail->IsHTML(true);
|
|
||||||
$mail->isSMTP();
|
|
||||||
$mail->SMTPAuth = true;
|
|
||||||
$mail->SMTPSecure = "ssl";
|
|
||||||
$mail->Port = 465;
|
|
||||||
|
|
||||||
// Uncomment for debug info
|
|
||||||
//$mail->SMTPDebug = 4;
|
|
||||||
|
|
||||||
/* Finally send the mail. */
|
|
||||||
try {
|
|
||||||
$mail->send();
|
|
||||||
$result = ["type" => "mailSent", "message" => "Message Away!"];
|
|
||||||
} catch (Exception $e) {
|
|
||||||
//echo $e->errorMessage();
|
|
||||||
$result = [
|
|
||||||
"type" => "mailNotSent",
|
|
||||||
"message" => "Message Not Away!",
|
|
||||||
"error" => $e->errorMessage(),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,98 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace brain\utility;
|
||||||
|
|
||||||
|
use Slim\Views\Twig;
|
||||||
|
use PHPMailer\PHPMailer\PHPMailer;
|
||||||
|
use PHPMailer\PHPMailer\Exception;
|
||||||
|
use brain\data\Settings;
|
||||||
|
use brain\data\Session;
|
||||||
|
|
||||||
|
class Mailer
|
||||||
|
{
|
||||||
|
public static function sendMail($body)
|
||||||
|
{
|
||||||
|
$config = new Settings();
|
||||||
|
$settings = $config->getSettings();
|
||||||
|
$mailConfig = $settings["email"];
|
||||||
|
$mail = new PHPMailer();
|
||||||
|
|
||||||
|
switch ($body["mail_task"]) {
|
||||||
|
case "TESTING":
|
||||||
|
$html =
|
||||||
|
"<h1>Hi! It's Fipamo!</h1><br>" .
|
||||||
|
"<strong>It's just a test</strong><br>" .
|
||||||
|
$body["content"];
|
||||||
|
$member = Session::get("member");
|
||||||
|
$mail->addAddress($member["email"], ""); //pull email address from current user
|
||||||
|
$mail->Subject = "A test email";
|
||||||
|
break;
|
||||||
|
case "SEND_SECRET":
|
||||||
|
$html =
|
||||||
|
"<h1>Hi! It's Fipamo!</h1><br>" .
|
||||||
|
"<strong>This is your secret key.</strong><br><br>" .
|
||||||
|
"<h3>" .
|
||||||
|
$body["secret"] .
|
||||||
|
"</h3>" .
|
||||||
|
"<br> Use this key to reset your password.";
|
||||||
|
$mail->addAddress($body["email"], ""); //pull email address from current user
|
||||||
|
$mail->Subject = "Shhhh! It's a secret!";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return $result = [
|
||||||
|
"type" => "noMailService",
|
||||||
|
"message" => "Mail task is undefined. What are you doing??",
|
||||||
|
];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//set values based on current active protocol
|
||||||
|
switch ($mailConfig["active"]) {
|
||||||
|
case "option-smtp":
|
||||||
|
$mail->setFrom($mailConfig["smtp"]["email"], "System Email");
|
||||||
|
$mail->Host = "playvicio.us";
|
||||||
|
$mail->Username = $mailConfig["smtp"]["email"];
|
||||||
|
$mail->Password = $mailConfig["smtp"]["password"];
|
||||||
|
|
||||||
|
break;
|
||||||
|
case "option-mg":
|
||||||
|
$mail->setFrom($mailConfig["mailgun"]["domain"], "No Reply");
|
||||||
|
$mail->Host = "smtp.mailgun.org";
|
||||||
|
$mail->Username = $mailConfig["mailgun"]["domain"];
|
||||||
|
$mail->Password = $mailConfig["mailgun"]["key"];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
//no mail service
|
||||||
|
return $result = [
|
||||||
|
"type" => "noMailService",
|
||||||
|
"message" => "Mail is not configured. Handle that.",
|
||||||
|
];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$mail->Body = $html;
|
||||||
|
$mail->IsHTML(true);
|
||||||
|
$mail->isSMTP();
|
||||||
|
$mail->SMTPAuth = true;
|
||||||
|
$mail->SMTPSecure = "ssl";
|
||||||
|
$mail->Port = 465;
|
||||||
|
|
||||||
|
// Uncomment for debug info
|
||||||
|
//$mail->SMTPDebug = 4;
|
||||||
|
|
||||||
|
/* Finally send the mail. */
|
||||||
|
try {
|
||||||
|
$mail->send();
|
||||||
|
$result = ["type" => "mailSent", "message" => "Message Away!"];
|
||||||
|
} catch (Exception $e) {
|
||||||
|
//echo $e->errorMessage();
|
||||||
|
$result = [
|
||||||
|
"type" => "mailNotSent",
|
||||||
|
"message" => "Message Not Away!",
|
||||||
|
"error" => $e->errorMessage(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
}
|
@ -1,99 +0,0 @@
|
|||||||
<?php
|
|
||||||
class Maintenance
|
|
||||||
{
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function makeBackup()
|
|
||||||
{
|
|
||||||
//make sure back directory is there
|
|
||||||
if (!is_dir("../config/backups")) {
|
|
||||||
mkdir("../config/backups", 0755, true);
|
|
||||||
}
|
|
||||||
//creat backup zip
|
|
||||||
$zip = new ZipArchive();
|
|
||||||
$zip->open(
|
|
||||||
"../config/backups/latest_back.zip",
|
|
||||||
ZipArchive::CREATE | ZipArchive::OVERWRITE
|
|
||||||
);
|
|
||||||
//gather data and path info for md pages
|
|
||||||
$pagePath = "../content/pages";
|
|
||||||
$yearPaths = glob($pagePath . "/*", GLOB_ONLYDIR);
|
|
||||||
foreach ($yearPaths as $years) {
|
|
||||||
$year = explode("/", $years);
|
|
||||||
//grap the index and save it
|
|
||||||
if (trim($year[3]) == "start") {
|
|
||||||
$options = [
|
|
||||||
"add_path" => "content/pages/" . $year[3] . "/",
|
|
||||||
"remove_all_path" => true,
|
|
||||||
];
|
|
||||||
$zip->addGlob($years . "/*.md", GLOB_BRACE, $options);
|
|
||||||
}
|
|
||||||
$monthsPath = glob($pagePath . "/" . $year[3] . "/*", GLOB_ONLYDIR);
|
|
||||||
foreach ($monthsPath as $months) {
|
|
||||||
$month = explode("/", $months);
|
|
||||||
//once info is collected, add md pages to zip
|
|
||||||
$options = [
|
|
||||||
"add_path" => "content/pages/" . $year[3] . "/" . $month[4] . "/",
|
|
||||||
"remove_all_path" => true,
|
|
||||||
];
|
|
||||||
$zip->addGlob($months . "/*.md", GLOB_BRACE, $options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//gather data and path info for blog images
|
|
||||||
$blogImagesPath = "../public/assets/images/blog";
|
|
||||||
$yearPaths = glob($blogImagesPath . "/*", GLOB_ONLYDIR);
|
|
||||||
foreach ($yearPaths as $years) {
|
|
||||||
$year = explode("/", $years);
|
|
||||||
$monthsPath = glob($blogImagesPath . "/" . $year[5] . "/*", GLOB_ONLYDIR);
|
|
||||||
foreach ($monthsPath as $months) {
|
|
||||||
$month = explode("/", $months);
|
|
||||||
//once info is collected, add images pages to zip
|
|
||||||
$options = [
|
|
||||||
"add_path" =>
|
|
||||||
"public/assets/images/blog/" . $year[5] . "/" . $month[6] . "/",
|
|
||||||
"remove_all_path" => true,
|
|
||||||
];
|
|
||||||
$zip->addGlob($months . "/*.*", GLOB_BRACE, $options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//gather data and path info for user images
|
|
||||||
$userImagesPath = "../public/assets/images/user";
|
|
||||||
$yearPaths = glob($userImagesPath . "/*", GLOB_ONLYDIR);
|
|
||||||
foreach ($yearPaths as $years) {
|
|
||||||
$year = explode("/", $years);
|
|
||||||
$monthsPath = glob($userImagesPath . "/" . $year[5] . "/*", GLOB_ONLYDIR);
|
|
||||||
foreach ($monthsPath as $months) {
|
|
||||||
$month = explode("/", $months);
|
|
||||||
//once info is collected, add images pages to zip
|
|
||||||
$options = [
|
|
||||||
"add_path" =>
|
|
||||||
"public/assets/images/user/" . $year[5] . "/" . $month[6] . "/",
|
|
||||||
"remove_all_path" => true,
|
|
||||||
];
|
|
||||||
$zip->addGlob($months . "/*.*", GLOB_BRACE, $options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//add directory for settings and save them
|
|
||||||
$zip->addEmptyDir("settings");
|
|
||||||
$zip->addFile("../config/settings.json", "settings/settings.json");
|
|
||||||
$zip->addFile("../config/folks.json", "settings/folks.json");
|
|
||||||
$zip->addFile("../config/tags.json", "settings/tags.json");
|
|
||||||
//save zip file
|
|
||||||
$zip->close();
|
|
||||||
|
|
||||||
//update settings file with latest back up date
|
|
||||||
$updated = new \Moment\Moment();
|
|
||||||
Settings::updateGlobalData(
|
|
||||||
"last_backup",
|
|
||||||
$updated->format("Y-m-d\TH:i:sP")
|
|
||||||
);
|
|
||||||
|
|
||||||
$result = ["message" => "Backup created. THIS IS A SAFE SPACE!"];
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,104 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace brain\utility;
|
||||||
|
|
||||||
|
use brain\data\Settings;
|
||||||
|
|
||||||
|
class Maintenance
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function makeBackup()
|
||||||
|
{
|
||||||
|
//make sure back directory is there
|
||||||
|
if (!is_dir("../config/backups")) {
|
||||||
|
mkdir("../config/backups", 0755, true);
|
||||||
|
}
|
||||||
|
//creat backup zip
|
||||||
|
$zip = new \ZipArchive();
|
||||||
|
$zip->open(
|
||||||
|
"../config/backups/latest_back.zip",
|
||||||
|
\ZipArchive::CREATE | \ZipArchive::OVERWRITE
|
||||||
|
);
|
||||||
|
//gather data and path info for md pages
|
||||||
|
$pagePath = "../content/pages";
|
||||||
|
$yearPaths = glob($pagePath . "/*", GLOB_ONLYDIR);
|
||||||
|
foreach ($yearPaths as $years) {
|
||||||
|
$year = explode("/", $years);
|
||||||
|
//grap the index and save it
|
||||||
|
if (trim($year[3]) == "start") {
|
||||||
|
$options = [
|
||||||
|
"add_path" => "content/pages/" . $year[3] . "/",
|
||||||
|
"remove_all_path" => true,
|
||||||
|
];
|
||||||
|
$zip->addGlob($years . "/*.md", GLOB_BRACE, $options);
|
||||||
|
}
|
||||||
|
$monthsPath = glob($pagePath . "/" . $year[3] . "/*", GLOB_ONLYDIR);
|
||||||
|
foreach ($monthsPath as $months) {
|
||||||
|
$month = explode("/", $months);
|
||||||
|
//once info is collected, add md pages to zip
|
||||||
|
$options = [
|
||||||
|
"add_path" => "content/pages/" . $year[3] . "/" . $month[4] . "/",
|
||||||
|
"remove_all_path" => true,
|
||||||
|
];
|
||||||
|
$zip->addGlob($months . "/*.md", GLOB_BRACE, $options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//gather data and path info for blog images
|
||||||
|
$blogImagesPath = "../public/assets/images/blog";
|
||||||
|
$yearPaths = glob($blogImagesPath . "/*", GLOB_ONLYDIR);
|
||||||
|
foreach ($yearPaths as $years) {
|
||||||
|
$year = explode("/", $years);
|
||||||
|
$monthsPath = glob($blogImagesPath . "/" . $year[5] . "/*", GLOB_ONLYDIR);
|
||||||
|
foreach ($monthsPath as $months) {
|
||||||
|
$month = explode("/", $months);
|
||||||
|
//once info is collected, add images pages to zip
|
||||||
|
$options = [
|
||||||
|
"add_path" =>
|
||||||
|
"public/assets/images/blog/" . $year[5] . "/" . $month[6] . "/",
|
||||||
|
"remove_all_path" => true,
|
||||||
|
];
|
||||||
|
$zip->addGlob($months . "/*.*", GLOB_BRACE, $options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//gather data and path info for user images
|
||||||
|
$userImagesPath = "../public/assets/images/user";
|
||||||
|
$yearPaths = glob($userImagesPath . "/*", GLOB_ONLYDIR);
|
||||||
|
foreach ($yearPaths as $years) {
|
||||||
|
$year = explode("/", $years);
|
||||||
|
$monthsPath = glob($userImagesPath . "/" . $year[5] . "/*", GLOB_ONLYDIR);
|
||||||
|
foreach ($monthsPath as $months) {
|
||||||
|
$month = explode("/", $months);
|
||||||
|
//once info is collected, add images pages to zip
|
||||||
|
$options = [
|
||||||
|
"add_path" =>
|
||||||
|
"public/assets/images/user/" . $year[5] . "/" . $month[6] . "/",
|
||||||
|
"remove_all_path" => true,
|
||||||
|
];
|
||||||
|
$zip->addGlob($months . "/*.*", GLOB_BRACE, $options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//add directory for settings and save them
|
||||||
|
$zip->addEmptyDir("settings");
|
||||||
|
$zip->addFile("../config/settings.json", "settings/settings.json");
|
||||||
|
$zip->addFile("../config/folks.json", "settings/folks.json");
|
||||||
|
$zip->addFile("../config/tags.json", "settings/tags.json");
|
||||||
|
//save zip file
|
||||||
|
$zip->close();
|
||||||
|
|
||||||
|
//update settings file with latest back up date
|
||||||
|
$updated = new \Moment\Moment();
|
||||||
|
Settings::updateGlobalData(
|
||||||
|
"last_backup",
|
||||||
|
$updated->format("Y-m-d\TH:i:sP")
|
||||||
|
);
|
||||||
|
|
||||||
|
$result = ["message" => "Backup created. THIS IS A SAFE SPACE!"];
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
}
|
@ -1,223 +0,0 @@
|
|||||||
<?php
|
|
||||||
use function _\find;
|
|
||||||
class SetUp
|
|
||||||
{
|
|
||||||
public static function status()
|
|
||||||
{
|
|
||||||
if (file_exists("../config/settings.json")) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function init($body)
|
|
||||||
{
|
|
||||||
//grab template files
|
|
||||||
$newFolks = json_decode(
|
|
||||||
file_get_contents("../config/init/folks-template.json"),
|
|
||||||
true
|
|
||||||
);
|
|
||||||
$newSettings = json_decode(
|
|
||||||
file_get_contents("../config/init/settings-template.json"),
|
|
||||||
true
|
|
||||||
);
|
|
||||||
//get form values
|
|
||||||
//$body = $request->getParsedBody();
|
|
||||||
$handle = $body["new_member_handle"];
|
|
||||||
$email = $body["new_member_email"];
|
|
||||||
$pass = $body["new_member_pass"];
|
|
||||||
$title = $body["new_member_title"];
|
|
||||||
|
|
||||||
$now = new \Moment\Moment();
|
|
||||||
//setup folks config
|
|
||||||
$hash = password_hash($pass, PASSWORD_DEFAULT);
|
|
||||||
$newFolks[0]["id"] = 0;
|
|
||||||
$newFolks[0]["handle"] = $handle;
|
|
||||||
$newFolks[0]["email"] = $email;
|
|
||||||
$newFolks[0]["password"] = $hash;
|
|
||||||
$newFolks[0]["key"] = password_hash($email, PASSWORD_DEFAULT);
|
|
||||||
$newFolks[0]["secret"] = StringTools::randomString(12);
|
|
||||||
$newFolks[0]["role"] = "hnic";
|
|
||||||
$newFolks[0]["created"] = $now->format("Y-m-d\TH:i:sP");
|
|
||||||
$newFolks[0]["updated"] = $now->format("Y-m-d\TH:i:sP");
|
|
||||||
//set up settings config
|
|
||||||
$newSettings["global"]["title"] = $title;
|
|
||||||
|
|
||||||
//create index file
|
|
||||||
//$rightNow = $now->format("Y-m-d\TH:i:sP");
|
|
||||||
//var_dump($now->format("Y-m-d\TH:i:sP"));
|
|
||||||
$index = [
|
|
||||||
"id" => 1,
|
|
||||||
"uuid" => StringTools::createUUID(),
|
|
||||||
"title" => "FIRST!",
|
|
||||||
"feature" => "/assets/images/global/default-bg.jpg",
|
|
||||||
"path" => "content/pages/start",
|
|
||||||
"layout" => "index",
|
|
||||||
"tags" => "start, welcome",
|
|
||||||
"author" => $handle,
|
|
||||||
"created" => $now->format("Y-m-d\TH:i:sP"),
|
|
||||||
"updated" => $now->format("Y-m-d\TH:i:sP"),
|
|
||||||
"deleted" => "false",
|
|
||||||
"slug" => "first",
|
|
||||||
"menu" => "false",
|
|
||||||
"featured" => "false",
|
|
||||||
"published" => "true",
|
|
||||||
"content" =>
|
|
||||||
"# F**k Yes \n\nIf you're seeing this, you're up and running. NICE WORK!\n\nFrom here, feel free to start dropping pages to your heart's content.\n\nFor some tips about using Fipamo, check out the ![docs](https://code.playvicio.us/Are0h/Fipamo/wiki/02-Usage)\n\nAll good? Feel free to edit this page to whatever you want!\n\nYOU'RE THE CAPTAIN NOW.",
|
|
||||||
];
|
|
||||||
|
|
||||||
$freshIndex = DocTools::objectToMD($index);
|
|
||||||
|
|
||||||
//once all files created, write down
|
|
||||||
|
|
||||||
DocTools::writeSettings("../config/settings.json", $newSettings);
|
|
||||||
DocTools::writeSettings("../config/folks.json", $newFolks);
|
|
||||||
DocTools::writeSettings("../config/tags.json", []);
|
|
||||||
DocTools::writePages(
|
|
||||||
"create",
|
|
||||||
"start",
|
|
||||||
"../content/pages/start/index.md",
|
|
||||||
$freshIndex
|
|
||||||
);
|
|
||||||
|
|
||||||
//if there is an older session file, get rid of it
|
|
||||||
if (is_file("../content/.session")) {
|
|
||||||
unlink("../content/.session");
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = ["type" => "blogInitGood", "message" => "Site Created"];
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function restore($request)
|
|
||||||
{
|
|
||||||
$result = [
|
|
||||||
"type" => "requestLame",
|
|
||||||
"message" => "Still working on it.",
|
|
||||||
];
|
|
||||||
$body = $request->getParsedBody();
|
|
||||||
|
|
||||||
$backup = $request->getUploadedFiles();
|
|
||||||
$file = $backup["backup-upload"];
|
|
||||||
$size = $file->getSize();
|
|
||||||
$name = $file->getClientFileName();
|
|
||||||
|
|
||||||
//park it so it can be read
|
|
||||||
$file->moveTo("../content" . "/" . $name);
|
|
||||||
|
|
||||||
//open it and get files to verify user
|
|
||||||
$zip = new ZipArchive();
|
|
||||||
if ($zip->open("../content" . "/" . $name) === true) {
|
|
||||||
$folks = json_decode($zip->getFromName("settings/folks.json"), true);
|
|
||||||
$found = find($folks, ["handle" => $body["restore_member_handle"]]);
|
|
||||||
|
|
||||||
//if member is found in back up, check pass
|
|
||||||
if ($found) {
|
|
||||||
if (password_verify($body["restore_member_pass"], $found["password"])) {
|
|
||||||
//backup verified, restore site
|
|
||||||
|
|
||||||
//set new secret key for older folks configs
|
|
||||||
$newFolks = [];
|
|
||||||
if (!isset($found["secret"])) {
|
|
||||||
$found["secret"] = StringTools::randomString(12);
|
|
||||||
}
|
|
||||||
array_push($newFolks, $found);
|
|
||||||
//dump files in folder
|
|
||||||
$zip->extractTo("../content");
|
|
||||||
|
|
||||||
//move to appropriate spots
|
|
||||||
/*
|
|
||||||
rename(
|
|
||||||
"../content/settings/settings.json",
|
|
||||||
"../config/settings.json"
|
|
||||||
);
|
|
||||||
*/
|
|
||||||
|
|
||||||
//load up old config file
|
|
||||||
$newConfig = json_decode(
|
|
||||||
file_get_contents("../content/settings/settings.json"),
|
|
||||||
true
|
|
||||||
);
|
|
||||||
//check for key, add if not there
|
|
||||||
if (!isset($newConfig["global"]["externalAPI"])) {
|
|
||||||
$newConfig["global"]["externalAPI"] = "false";
|
|
||||||
}
|
|
||||||
//write new config file
|
|
||||||
DocTools::writeSettings("../config/settings.json", $newConfig);
|
|
||||||
|
|
||||||
//rename("../content/settings/folks.json", "../config/folks.json");
|
|
||||||
DocTools::writeSettings("../config/folks.json", $newFolks);
|
|
||||||
|
|
||||||
rename("../content/settings/tags.json", "../config/tags.json");
|
|
||||||
|
|
||||||
//images path for blog and user
|
|
||||||
$blogImagePath = "../public/assets/images/blog";
|
|
||||||
$userImagePath = "../public/assets/images/user";
|
|
||||||
|
|
||||||
//check to see if image dirs are empty, if not chill
|
|
||||||
if ($globs = glob($blogImagePath . "/*")) {
|
|
||||||
//directory not empty, relax
|
|
||||||
} else {
|
|
||||||
rename("../content/public/assets/images/blog", $blogImagePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($globs = glob($userImagePath . "/*")) {
|
|
||||||
//directory not empty, relax
|
|
||||||
} else {
|
|
||||||
rename("../content/public/assets/images/user", $userImagePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
rename("../content/content/pages/", "../content/pages");
|
|
||||||
|
|
||||||
//legacy check for old file structure
|
|
||||||
if (is_file("../content/pages/index.md")) {
|
|
||||||
if (!is_dir("../content/pages/start")) {
|
|
||||||
//Directory does not exist, so lets create it.
|
|
||||||
mkdir("../content/pages/start", 0755, true);
|
|
||||||
//move start page to appropriate spot
|
|
||||||
rename(
|
|
||||||
"../content/pages/index.md",
|
|
||||||
"../content/pages/start/index.md"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//chill
|
|
||||||
}
|
|
||||||
|
|
||||||
//clean up
|
|
||||||
|
|
||||||
DocTools::deleteFolder("../content/settings");
|
|
||||||
DocTools::deleteFolder("../content/public");
|
|
||||||
DocTools::deleteFolder("../content/content");
|
|
||||||
$result = [
|
|
||||||
"type" => "requestGood",
|
|
||||||
"message" => "Site Restored! Redirecting",
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
$result = [
|
|
||||||
"type" => "requestLame",
|
|
||||||
"message" => "Check that password, champ.",
|
|
||||||
];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$result = [
|
|
||||||
"type" => "requestLame",
|
|
||||||
"message" => "No member found by that name, hoss",
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
$zip->close();
|
|
||||||
$zipPath = "../content/" . $name;
|
|
||||||
//trash zip when done
|
|
||||||
unlink($zipPath);
|
|
||||||
} else {
|
|
||||||
$result = [
|
|
||||||
"type" => "requestLame",
|
|
||||||
"message" => "Could not open backup. RATS!",
|
|
||||||
];
|
|
||||||
}
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,229 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace brain\utility;
|
||||||
|
|
||||||
|
use function _\find;
|
||||||
|
|
||||||
|
class SetUp
|
||||||
|
{
|
||||||
|
public static function status()
|
||||||
|
{
|
||||||
|
if (file_exists("../config/settings.json")) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function init($body)
|
||||||
|
{
|
||||||
|
//grab template files
|
||||||
|
$newFolks = json_decode(
|
||||||
|
file_get_contents("../config/init/folks-template.json"),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
$newSettings = json_decode(
|
||||||
|
file_get_contents("../config/init/settings-template.json"),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
//get form values
|
||||||
|
//$body = $request->getParsedBody();
|
||||||
|
$handle = $body["new_member_handle"];
|
||||||
|
$email = $body["new_member_email"];
|
||||||
|
$pass = $body["new_member_pass"];
|
||||||
|
$title = $body["new_member_title"];
|
||||||
|
|
||||||
|
$now = new \Moment\Moment();
|
||||||
|
//setup folks config
|
||||||
|
$hash = password_hash($pass, PASSWORD_DEFAULT);
|
||||||
|
$newFolks[0]["id"] = 0;
|
||||||
|
$newFolks[0]["handle"] = $handle;
|
||||||
|
$newFolks[0]["email"] = $email;
|
||||||
|
$newFolks[0]["password"] = $hash;
|
||||||
|
$newFolks[0]["key"] = password_hash($email, PASSWORD_DEFAULT);
|
||||||
|
$newFolks[0]["secret"] = StringTools::randomString(12);
|
||||||
|
$newFolks[0]["role"] = "hnic";
|
||||||
|
$newFolks[0]["created"] = $now->format("Y-m-d\TH:i:sP");
|
||||||
|
$newFolks[0]["updated"] = $now->format("Y-m-d\TH:i:sP");
|
||||||
|
//set up settings config
|
||||||
|
$newSettings["global"]["title"] = $title;
|
||||||
|
|
||||||
|
//create index file
|
||||||
|
//$rightNow = $now->format("Y-m-d\TH:i:sP");
|
||||||
|
//var_dump($now->format("Y-m-d\TH:i:sP"));
|
||||||
|
$index = [
|
||||||
|
"id" => 1,
|
||||||
|
"uuid" => StringTools::createUUID(),
|
||||||
|
"title" => "FIRST!",
|
||||||
|
"feature" => "/assets/images/global/default-bg.jpg",
|
||||||
|
"files" => "",
|
||||||
|
"path" => "content/pages/start",
|
||||||
|
"layout" => "index",
|
||||||
|
"tags" => "start, welcome",
|
||||||
|
"author" => $handle,
|
||||||
|
"created" => $now->format("Y-m-d\TH:i:sP"),
|
||||||
|
"updated" => $now->format("Y-m-d\TH:i:sP"),
|
||||||
|
"deleted" => "false",
|
||||||
|
"slug" => "first",
|
||||||
|
"menu" => "false",
|
||||||
|
"featured" => "false",
|
||||||
|
"published" => "true",
|
||||||
|
"content" =>
|
||||||
|
"# F**k Yes \n\nIf you're seeing this, you're up and running. NICE WORK!\n\nFrom here, feel free to start dropping pages to your heart's content.\n\nFor some tips about using Fipamo, check out the ![docs](https://code.playvicio.us/Are0h/Fipamo/wiki/02-Usage)\n\nAll good? Feel free to edit this page to whatever you want!\n\nYOU'RE THE CAPTAIN NOW.",
|
||||||
|
];
|
||||||
|
|
||||||
|
$freshIndex = DocTools::objectToMD($index);
|
||||||
|
|
||||||
|
//once all files created, write down
|
||||||
|
|
||||||
|
DocTools::writeSettings("../config/settings.json", $newSettings);
|
||||||
|
DocTools::writeSettings("../config/folks.json", $newFolks);
|
||||||
|
DocTools::writeSettings("../config/tags.json", []);
|
||||||
|
DocTools::writePages(
|
||||||
|
"create",
|
||||||
|
"start",
|
||||||
|
"../content/pages/start/index.md",
|
||||||
|
$freshIndex
|
||||||
|
);
|
||||||
|
|
||||||
|
//if there is an older session file, get rid of it
|
||||||
|
if (is_file("../content/.session")) {
|
||||||
|
unlink("../content/.session");
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = ["type" => "blogInitGood", "message" => "Site Created"];
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function restore($request)
|
||||||
|
{
|
||||||
|
$result = [
|
||||||
|
"type" => "requestLame",
|
||||||
|
"message" => "Still working on it.",
|
||||||
|
];
|
||||||
|
$body = $request->getParsedBody();
|
||||||
|
|
||||||
|
$backup = $request->getUploadedFiles();
|
||||||
|
$file = $backup["backup-upload"];
|
||||||
|
//NOTE: If this fails check 'post_max_size' in php.ini
|
||||||
|
$size = $file->getSize();
|
||||||
|
$name = $file->getClientFileName();
|
||||||
|
|
||||||
|
//park it so it can be read
|
||||||
|
$file->moveTo("../content" . "/" . $name);
|
||||||
|
|
||||||
|
//open it and get files to verify user
|
||||||
|
$zip = new \ZipArchive();
|
||||||
|
if ($zip->open("../content" . "/" . $name) === true) {
|
||||||
|
$folks = json_decode($zip->getFromName("settings/folks.json"), true);
|
||||||
|
$found = find($folks, ["handle" => $body["restore_member_handle"]]);
|
||||||
|
|
||||||
|
//if member is found in back up, check pass
|
||||||
|
if ($found) {
|
||||||
|
if (password_verify($body["restore_member_pass"], $found["password"])) {
|
||||||
|
//backup verified, restore site
|
||||||
|
|
||||||
|
//set new secret key for older folks configs
|
||||||
|
$newFolks = [];
|
||||||
|
if (!isset($found["secret"])) {
|
||||||
|
$found["secret"] = StringTools::randomString(12);
|
||||||
|
}
|
||||||
|
array_push($newFolks, $found);
|
||||||
|
//dump files in folder
|
||||||
|
$zip->extractTo("../content");
|
||||||
|
|
||||||
|
//move to appropriate spots
|
||||||
|
/*
|
||||||
|
rename(
|
||||||
|
"../content/settings/settings.json",
|
||||||
|
"../config/settings.json"
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
|
||||||
|
//load up old config file
|
||||||
|
$newConfig = json_decode(
|
||||||
|
file_get_contents("../content/settings/settings.json"),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
//check for key, add if not there
|
||||||
|
if (!isset($newConfig["global"]["externalAPI"])) {
|
||||||
|
$newConfig["global"]["externalAPI"] = "false";
|
||||||
|
}
|
||||||
|
//write new config file
|
||||||
|
DocTools::writeSettings("../config/settings.json", $newConfig);
|
||||||
|
|
||||||
|
//rename("../content/settings/folks.json", "../config/folks.json");
|
||||||
|
DocTools::writeSettings("../config/folks.json", $newFolks);
|
||||||
|
|
||||||
|
rename("../content/settings/tags.json", "../config/tags.json");
|
||||||
|
|
||||||
|
//images path for blog and user
|
||||||
|
$blogImagePath = "../public/assets/images/blog";
|
||||||
|
$userImagePath = "../public/assets/images/user";
|
||||||
|
|
||||||
|
//check to see if image dirs are empty, if not chill
|
||||||
|
if ($globs = glob($blogImagePath . "/*")) {
|
||||||
|
//directory not empty, relax
|
||||||
|
} else {
|
||||||
|
rename("../content/public/assets/images/blog", $blogImagePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($globs = glob($userImagePath . "/*")) {
|
||||||
|
//directory not empty, relax
|
||||||
|
} else {
|
||||||
|
rename("../content/public/assets/images/user", $userImagePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
rename("../content/content/pages/", "../content/pages");
|
||||||
|
|
||||||
|
//legacy check for old file structure
|
||||||
|
if (is_file("../content/pages/index.md")) {
|
||||||
|
if (!is_dir("../content/pages/start")) {
|
||||||
|
//Directory does not exist, so lets create it.
|
||||||
|
mkdir("../content/pages/start", 0755, true);
|
||||||
|
//move start page to appropriate spot
|
||||||
|
rename(
|
||||||
|
"../content/pages/index.md",
|
||||||
|
"../content/pages/start/index.md"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//chill
|
||||||
|
}
|
||||||
|
|
||||||
|
//clean up
|
||||||
|
|
||||||
|
DocTools::deleteFolder("../content/settings");
|
||||||
|
DocTools::deleteFolder("../content/public");
|
||||||
|
DocTools::deleteFolder("../content/content");
|
||||||
|
$result = [
|
||||||
|
"type" => "requestGood",
|
||||||
|
"message" => "Site Restored! Redirecting",
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
$result = [
|
||||||
|
"type" => "requestLame",
|
||||||
|
"message" => "Check that password, champ.",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$result = [
|
||||||
|
"type" => "requestLame",
|
||||||
|
"message" => "No member found by that name, hoss",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$zip->close();
|
||||||
|
$zipPath = "../content/" . $name;
|
||||||
|
//trash zip when done
|
||||||
|
unlink($zipPath);
|
||||||
|
} else {
|
||||||
|
$result = [
|
||||||
|
"type" => "requestLame",
|
||||||
|
"message" => "Could not open backup. RATS!",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
}
|
@ -1,238 +0,0 @@
|
|||||||
<?php
|
|
||||||
use Mni\FrontYAML\Parser;
|
|
||||||
use function _\find;
|
|
||||||
use function _\filter;
|
|
||||||
|
|
||||||
class Sorting
|
|
||||||
{
|
|
||||||
private static $_tags = [];
|
|
||||||
private static $_archive = [];
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function tags()
|
|
||||||
{
|
|
||||||
$pages = (new Book("../content/pages"))->getContents();
|
|
||||||
foreach ($pages as $page) {
|
|
||||||
$temp = [];
|
|
||||||
$temp = explode(",", $page["tags"]);
|
|
||||||
foreach ($temp as $tag) {
|
|
||||||
$label = trim($tag);
|
|
||||||
if (!find(self::$_tags, ["tag_name" => $label])) {
|
|
||||||
array_push(self::$_tags, [
|
|
||||||
"tag_name" => $label,
|
|
||||||
"slug" => StringTools::safeString($label),
|
|
||||||
"pages" => self::tagPages($label, $pages),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return self::$_tags;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static function tagPages($tag, $pages)
|
|
||||||
{
|
|
||||||
$tagged = [];
|
|
||||||
foreach ($pages as $page) {
|
|
||||||
if (strpos($page["tags"], $tag) !== false) {
|
|
||||||
array_push($tagged, [
|
|
||||||
"title" => $page["title"],
|
|
||||||
"slug" => $page["slug"],
|
|
||||||
"path" => $page["path"],
|
|
||||||
"feature" => $page["feature"],
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $tagged;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function archive()
|
|
||||||
{
|
|
||||||
$pages = (new Book("../content/pages"))->getContents();
|
|
||||||
$years = [];
|
|
||||||
$archive = [];
|
|
||||||
foreach ($pages as $page) {
|
|
||||||
//$year = date("Y", date($page["rawCreated"]));
|
|
||||||
$date = explode("/", $page["path"]);
|
|
||||||
//echo $page["title"] . " : " . $year . "\n";
|
|
||||||
if (!find($years, ["year" => trim($date[0])])) {
|
|
||||||
$findPages = filter($pages, ["createdYear" => trim($date[0])]);
|
|
||||||
//var_dump($findPages);
|
|
||||||
array_push($years, [
|
|
||||||
"year" => trim($date[0]),
|
|
||||||
"count" => count($findPages),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
foreach ($years as $year) {
|
|
||||||
$sorted = [];
|
|
||||||
$filtered = filter($pages, ["createdYear" => $year["year"]]);
|
|
||||||
|
|
||||||
foreach ($filtered as $obj) {
|
|
||||||
$month = date("m", date($obj["rawCreated"]));
|
|
||||||
if (!find($sorted, ["month" => $month])) {
|
|
||||||
$perMonth = filter($pages, [
|
|
||||||
"path" => $year["year"] . "/" . $month,
|
|
||||||
"deleted" => false,
|
|
||||||
"published" => true,
|
|
||||||
"layout" => "page",
|
|
||||||
]);
|
|
||||||
array_push($sorted, [
|
|
||||||
"month" => $month,
|
|
||||||
"full_month" => date("F", date($obj["rawCreated"])),
|
|
||||||
"count" => count($perMonth),
|
|
||||||
"pages" => $perMonth,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
array_push(self::$_archive, [
|
|
||||||
"year" => $year["year"],
|
|
||||||
"year_data" => $sorted,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
return self::$_archive;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function page($page)
|
|
||||||
{
|
|
||||||
$config = new Settings();
|
|
||||||
$settings = $config->getSettings();
|
|
||||||
$pageOption = [];
|
|
||||||
|
|
||||||
$pageInfo = [
|
|
||||||
"keywords" => isset($settings["global"]["keywords"])
|
|
||||||
? $settings["global"]["keywords"]
|
|
||||||
: "fipamo, blog, jamstack, php, markdown, js",
|
|
||||||
"description" => $settings["global"]["descriptions"],
|
|
||||||
"image" =>
|
|
||||||
$settings["global"]["base_url"] . $settings["global"]["background"],
|
|
||||||
"baseURL" => $settings["global"]["base_url"],
|
|
||||||
];
|
|
||||||
|
|
||||||
$taglist = explode(",", $page["tags"]);
|
|
||||||
$tags = [];
|
|
||||||
foreach ($taglist as $tag) {
|
|
||||||
$label = trim($tag);
|
|
||||||
array_push($tags, [
|
|
||||||
"label" => $label . " ",
|
|
||||||
"slug" => StringTools::safeString($label),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$meta = [
|
|
||||||
"who" => $page["author"],
|
|
||||||
"when" => $page["created"],
|
|
||||||
"tags" => $tags,
|
|
||||||
];
|
|
||||||
|
|
||||||
//render markdown content and clean it
|
|
||||||
$parser = new Parser();
|
|
||||||
$rendered = $parser->parse($page["content"]);
|
|
||||||
$sanitizer = HtmlSanitizer\Sanitizer::create([
|
|
||||||
"extensions" => ["basic", "image", "list", "code"],
|
|
||||||
"tags" => [
|
|
||||||
"img" => [
|
|
||||||
"allowed_attributes" => ["src", "alt", "title", "class"],
|
|
||||||
"allowed_hosts" => null,
|
|
||||||
],
|
|
||||||
],
|
|
||||||
]);
|
|
||||||
|
|
||||||
$preclean = $sanitizer->sanitize($rendered->getContent());
|
|
||||||
|
|
||||||
//just clean renderd string for now, Sanitize doesn't like relative img urls
|
|
||||||
//so another option is needed
|
|
||||||
$cleaned = strip_tags($rendered->getContent(), [
|
|
||||||
"a",
|
|
||||||
"br",
|
|
||||||
"p",
|
|
||||||
"strong",
|
|
||||||
"br",
|
|
||||||
"img",
|
|
||||||
"iframe",
|
|
||||||
"ul",
|
|
||||||
"li",
|
|
||||||
"i",
|
|
||||||
"em",
|
|
||||||
"h1",
|
|
||||||
"h2",
|
|
||||||
"h3",
|
|
||||||
"pre",
|
|
||||||
"code",
|
|
||||||
]);
|
|
||||||
//$cleaned = preg_replace('/(?:\r\n|[\r\n]){2,}/', "\n\n", $cleaned);
|
|
||||||
//$cleaned = html_entity_decode($cleaned, ENT_QUOTES, "UTF-8");
|
|
||||||
|
|
||||||
//if page feature isn't empty, replace page info meta image
|
|
||||||
if ($page["feature"] != "" || $page["feature"] != null) {
|
|
||||||
$pageInfo["image"] = $pageInfo["baseURL"] . $page["feature"];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($page["layout"] == "index") {
|
|
||||||
//$template = $this->theme . "/index.twig";
|
|
||||||
//$location = "../public/index.html";
|
|
||||||
//$dir = null;
|
|
||||||
|
|
||||||
$recent = [];
|
|
||||||
$featured = [];
|
|
||||||
$limit = 4;
|
|
||||||
$pages = (new Book())->getContents();
|
|
||||||
foreach ($pages as $item) {
|
|
||||||
if (
|
|
||||||
!$item["deleted"] &&
|
|
||||||
$item["published"] &&
|
|
||||||
$item["menu"] != "true"
|
|
||||||
) {
|
|
||||||
if (count($recent) < $limit) {
|
|
||||||
array_push($recent, [
|
|
||||||
"path" => $item["path"],
|
|
||||||
"slug" => $item["slug"],
|
|
||||||
"title" => $item["title"],
|
|
||||||
"feature" => $item["feature"],
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($item["featured"] == true) {
|
|
||||||
if (count($featured) < $limit) {
|
|
||||||
array_push($featured, [
|
|
||||||
"path" => $item["path"],
|
|
||||||
"slug" => $item["slug"],
|
|
||||||
"title" => $item["title"],
|
|
||||||
"feature" => $item["feature"],
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$pageOptions = [
|
|
||||||
"title" => $page["title"],
|
|
||||||
"background" => $page["feature"],
|
|
||||||
"content" => $page["html"], //$cleaned,
|
|
||||||
"meta" => $meta,
|
|
||||||
"recent" => $recent,
|
|
||||||
"featured" => $featured,
|
|
||||||
"info" => $pageInfo,
|
|
||||||
"menu" => $settings["menu"],
|
|
||||||
"dynamicRender" => $settings["global"]["dynamicRender"],
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
//$template = $this->theme . "/page.twig";
|
|
||||||
//$location = "../public/" . $page["path"] . "/" . $page["slug"] . ".html";
|
|
||||||
//$dir = "../public/" . $page["path"];
|
|
||||||
$pageOptions = [
|
|
||||||
"title" => $page["title"],
|
|
||||||
"background" => $page["feature"],
|
|
||||||
"content" => $page["html"], //$cleaned,
|
|
||||||
"meta" => $meta,
|
|
||||||
"info" => $pageInfo,
|
|
||||||
"menu" => $settings["menu"],
|
|
||||||
"dynamicRender" => $settings["global"]["dynamicRender"],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
return $pageOptions;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,248 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace brain\utility;
|
||||||
|
|
||||||
|
use Mni\FrontYAML\Parser;
|
||||||
|
use brain\data\Book;
|
||||||
|
use brain\data\Settings;
|
||||||
|
|
||||||
|
use function _\find;
|
||||||
|
use function _\filter;
|
||||||
|
|
||||||
|
class Sorting
|
||||||
|
{
|
||||||
|
private static $_tags = [];
|
||||||
|
private static $_archive = [];
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function tags()
|
||||||
|
{
|
||||||
|
$pages = (new Book("../content/pages"))->getContents();
|
||||||
|
foreach ($pages as $page) {
|
||||||
|
$temp = [];
|
||||||
|
$temp = explode(",", $page["tags"]);
|
||||||
|
foreach ($temp as $tag) {
|
||||||
|
$label = trim($tag);
|
||||||
|
if (!find(self::$_tags, ["tag_name" => $label])) {
|
||||||
|
array_push(self::$_tags, [
|
||||||
|
"tag_name" => $label,
|
||||||
|
"slug" => StringTools::safeString($label),
|
||||||
|
"pages" => self::tagPages($label, $pages),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$_tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function tagPages($tag, $pages)
|
||||||
|
{
|
||||||
|
$tagged = [];
|
||||||
|
foreach ($pages as $page) {
|
||||||
|
if (strpos($page["tags"], $tag) !== false) {
|
||||||
|
array_push($tagged, [
|
||||||
|
"title" => $page["title"],
|
||||||
|
"slug" => $page["slug"],
|
||||||
|
"path" => $page["path"],
|
||||||
|
"feature" => $page["feature"],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $tagged;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function archive()
|
||||||
|
{
|
||||||
|
$pages = (new Book("../content/pages"))->getContents();
|
||||||
|
$years = [];
|
||||||
|
$archive = [];
|
||||||
|
foreach ($pages as $page) {
|
||||||
|
//$year = date("Y", date($page["rawCreated"]));
|
||||||
|
$date = explode("/", $page["path"]);
|
||||||
|
//echo $page["title"] . " : " . $year . "\n";
|
||||||
|
if (!find($years, ["year" => trim($date[0])])) {
|
||||||
|
$findPages = filter($pages, ["createdYear" => trim($date[0])]);
|
||||||
|
//var_dump($findPages);
|
||||||
|
array_push($years, [
|
||||||
|
"year" => trim($date[0]),
|
||||||
|
"count" => count($findPages),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach ($years as $year) {
|
||||||
|
$sorted = [];
|
||||||
|
$filtered = filter($pages, ["createdYear" => $year["year"]]);
|
||||||
|
|
||||||
|
foreach ($filtered as $obj) {
|
||||||
|
$month = date("m", date($obj["rawCreated"]));
|
||||||
|
if (!find($sorted, ["month" => $month])) {
|
||||||
|
$perMonth = filter($pages, [
|
||||||
|
"path" => $year["year"] . "/" . $month,
|
||||||
|
"deleted" => false,
|
||||||
|
"published" => true,
|
||||||
|
"layout" => "page",
|
||||||
|
]);
|
||||||
|
array_push($sorted, [
|
||||||
|
"month" => $month,
|
||||||
|
"full_month" => date("F", date($obj["rawCreated"])),
|
||||||
|
"count" => count($perMonth),
|
||||||
|
"pages" => $perMonth,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
array_push(self::$_archive, [
|
||||||
|
"year" => $year["year"],
|
||||||
|
"year_data" => $sorted,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
return self::$_archive;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function page($page)
|
||||||
|
{
|
||||||
|
$config = new Settings();
|
||||||
|
$settings = $config->getSettings();
|
||||||
|
$pageOption = [];
|
||||||
|
|
||||||
|
$pageInfo = [
|
||||||
|
"keywords" => isset($settings["global"]["keywords"])
|
||||||
|
? $settings["global"]["keywords"]
|
||||||
|
: "fipamo, blog, jamstack, php, markdown, js",
|
||||||
|
"description" => $settings["global"]["descriptions"],
|
||||||
|
"image" =>
|
||||||
|
$settings["global"]["base_url"] . $settings["global"]["background"],
|
||||||
|
"baseURL" => $settings["global"]["base_url"],
|
||||||
|
];
|
||||||
|
|
||||||
|
$taglist = explode(",", $page["tags"]);
|
||||||
|
$tags = [];
|
||||||
|
foreach ($taglist as $tag) {
|
||||||
|
$label = trim($tag);
|
||||||
|
array_push($tags, [
|
||||||
|
"label" => $label . " ",
|
||||||
|
"slug" => StringTools::safeString($label),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$meta = [
|
||||||
|
"who" => $page["author"],
|
||||||
|
"when" => $page["created"],
|
||||||
|
"tags" => $tags,
|
||||||
|
];
|
||||||
|
|
||||||
|
//render markdown content and clean it
|
||||||
|
$parser = new Parser();
|
||||||
|
$rendered = $parser->parse($page["content"]);
|
||||||
|
$sanitizer = \HtmlSanitizer\Sanitizer::create([
|
||||||
|
"extensions" => ["basic", "image", "list", "code"],
|
||||||
|
"tags" => [
|
||||||
|
"img" => [
|
||||||
|
"allowed_attributes" => ["src", "alt", "title", "class"],
|
||||||
|
"allowed_hosts" => null,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$preclean = $sanitizer->sanitize($rendered->getContent());
|
||||||
|
|
||||||
|
//just clean renderd string for now, Sanitize doesn't like relative img urls
|
||||||
|
//so another option is needed
|
||||||
|
$cleaned = strip_tags($rendered->getContent(), [
|
||||||
|
"a",
|
||||||
|
"br",
|
||||||
|
"p",
|
||||||
|
"strong",
|
||||||
|
"br",
|
||||||
|
"img",
|
||||||
|
"iframe",
|
||||||
|
"ul",
|
||||||
|
"li",
|
||||||
|
"i",
|
||||||
|
"em",
|
||||||
|
"h1",
|
||||||
|
"h2",
|
||||||
|
"h3",
|
||||||
|
"pre",
|
||||||
|
"code",
|
||||||
|
]);
|
||||||
|
//$cleaned = preg_replace('/(?:\r\n|[\r\n]){2,}/', "\n\n", $cleaned);
|
||||||
|
//$cleaned = html_entity_decode($cleaned, ENT_QUOTES, "UTF-8");
|
||||||
|
|
||||||
|
//if page feature isn't empty, replace page info meta image
|
||||||
|
if ($page["feature"] != "" || $page["feature"] != null) {
|
||||||
|
$pageInfo["image"] = $pageInfo["baseURL"] . $page["feature"];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($page["layout"] == "index") {
|
||||||
|
//$template = $this->theme . "/index.twig";
|
||||||
|
//$location = "../public/index.html";
|
||||||
|
//$dir = null;
|
||||||
|
|
||||||
|
$recent = [];
|
||||||
|
$featured = [];
|
||||||
|
$limit = 4;
|
||||||
|
$pages = (new Book())->getContents();
|
||||||
|
foreach ($pages as $item) {
|
||||||
|
if (
|
||||||
|
!$item["deleted"] &&
|
||||||
|
$item["published"] &&
|
||||||
|
$item["menu"] != "true"
|
||||||
|
) {
|
||||||
|
if (count($recent) < $limit) {
|
||||||
|
array_push($recent, [
|
||||||
|
"path" => $item["path"],
|
||||||
|
"slug" => $item["slug"],
|
||||||
|
"title" => $item["title"],
|
||||||
|
"feature" => $item["feature"],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($item["featured"] == true) {
|
||||||
|
if (count($featured) < $limit) {
|
||||||
|
array_push($featured, [
|
||||||
|
"path" => $item["path"],
|
||||||
|
"slug" => $item["slug"],
|
||||||
|
"title" => $item["title"],
|
||||||
|
"feature" => $item["feature"],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$pageOptions = [
|
||||||
|
"title" => $page["title"],
|
||||||
|
"background" => $page["feature"],
|
||||||
|
"content" => $page["html"], //$cleaned,
|
||||||
|
"meta" => $meta,
|
||||||
|
"recent" => $recent,
|
||||||
|
"featured" => $featured,
|
||||||
|
"info" => $pageInfo,
|
||||||
|
"menu" => $settings["menu"],
|
||||||
|
"dynamicRender" => $settings["global"]["dynamicRender"],
|
||||||
|
"media" => $page["media"],
|
||||||
|
"files" => $page["docs"],
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
//$template = $this->theme . "/page.twig";
|
||||||
|
//$location = "../public/" . $page["path"] . "/" . $page["slug"] . ".html";
|
||||||
|
//$dir = "../public/" . $page["path"];
|
||||||
|
$pageOptions = [
|
||||||
|
"title" => $page["title"],
|
||||||
|
"background" => $page["feature"],
|
||||||
|
"content" => $page["html"], //$cleaned,
|
||||||
|
"meta" => $meta,
|
||||||
|
"info" => $pageInfo,
|
||||||
|
"menu" => $settings["menu"],
|
||||||
|
"dynamicRender" => $settings["global"]["dynamicRender"],
|
||||||
|
"media" => $page["media"],
|
||||||
|
"files" => $page["docs"],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return $pageOptions;
|
||||||
|
}
|
||||||
|
}
|
@ -1,130 +0,0 @@
|
|||||||
<?php
|
|
||||||
use ReallySimpleJWT\Token;
|
|
||||||
use ReallySimpleJWT\Exception\BuildException;
|
|
||||||
use Mni\FrontYAML\Parser;
|
|
||||||
//include "brain/data/Auth.inc.php";
|
|
||||||
|
|
||||||
class StringTools
|
|
||||||
{
|
|
||||||
public static function createUUID()
|
|
||||||
{
|
|
||||||
if (function_exists("com_create_guid") === true) {
|
|
||||||
return trim(com_create_guid(), "{}");
|
|
||||||
}
|
|
||||||
|
|
||||||
return sprintf(
|
|
||||||
"%04X%04X-%04X-%04X-%04X-%04X%04X%04X",
|
|
||||||
mt_rand(0, 65535),
|
|
||||||
mt_rand(0, 65535),
|
|
||||||
mt_rand(0, 65535),
|
|
||||||
mt_rand(16384, 20479),
|
|
||||||
mt_rand(32768, 49151),
|
|
||||||
mt_rand(0, 65535),
|
|
||||||
mt_rand(0, 65535),
|
|
||||||
mt_rand(0, 65535)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function sanitizeContent($entry)
|
|
||||||
{
|
|
||||||
$parser = new Parser();
|
|
||||||
$rendered = $parser->parse($entry);
|
|
||||||
$sanitizer = HtmlSanitizer\Sanitizer::create([
|
|
||||||
"extensions" => ["basic", "image", "list", "code"],
|
|
||||||
"tags" => [
|
|
||||||
"img" => [
|
|
||||||
"allowed_attributes" => ["src", "alt", "title", "class"],
|
|
||||||
"allowed_hosts" => null,
|
|
||||||
],
|
|
||||||
],
|
|
||||||
]);
|
|
||||||
|
|
||||||
$preclean = $sanitizer->sanitize($rendered->getContent());
|
|
||||||
|
|
||||||
$cleaned = strip_tags($rendered->getContent(), [
|
|
||||||
"a",
|
|
||||||
"br",
|
|
||||||
"p",
|
|
||||||
"strong",
|
|
||||||
"br",
|
|
||||||
"img",
|
|
||||||
"iframe",
|
|
||||||
"ul",
|
|
||||||
"li",
|
|
||||||
"i",
|
|
||||||
"h1",
|
|
||||||
"h2",
|
|
||||||
"h3",
|
|
||||||
"pre",
|
|
||||||
"code",
|
|
||||||
]);
|
|
||||||
|
|
||||||
return $cleaned;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function safeString($string)
|
|
||||||
{
|
|
||||||
return strtolower(
|
|
||||||
trim(
|
|
||||||
preg_replace(
|
|
||||||
"~[^0-9a-z]+~i",
|
|
||||||
"_",
|
|
||||||
html_entity_decode(
|
|
||||||
preg_replace(
|
|
||||||
"~&([a-z]{1,2})(?:acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);~i",
|
|
||||||
'$1',
|
|
||||||
htmlentities($string, ENT_QUOTES, "UTF-8")
|
|
||||||
),
|
|
||||||
ENT_QUOTES,
|
|
||||||
"UTF-8"
|
|
||||||
)
|
|
||||||
),
|
|
||||||
"-"
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function randomString(int $length)
|
|
||||||
{
|
|
||||||
$alphanum =
|
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
||||||
$special = '*&!@%^#$';
|
|
||||||
$alphabet = $alphanum . $special;
|
|
||||||
$random = openssl_random_pseudo_bytes($length);
|
|
||||||
$alphabet_length = strlen($alphabet);
|
|
||||||
$string = "";
|
|
||||||
for ($i = 0; $i < $length; ++$i) {
|
|
||||||
$string .= $alphabet[ord($random[$i]) % $alphabet_length];
|
|
||||||
}
|
|
||||||
|
|
||||||
//secret needs to be a valid token
|
|
||||||
if ($length == 12) {
|
|
||||||
try {
|
|
||||||
$secret = Token::create(12, $string, time() + 3600, "localhost");
|
|
||||||
return $string;
|
|
||||||
} catch (BuildException $e) {
|
|
||||||
//bad secret, so try agiain
|
|
||||||
//echo "BAD STRING";
|
|
||||||
return self::randomString(12);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Token::validate($key, $string)) {
|
|
||||||
return $string;
|
|
||||||
} else {
|
|
||||||
return self::randomString(12);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static function checkSpecial($string)
|
|
||||||
{
|
|
||||||
$specials = ["*", "&", "!", "@", "%", "^", "#", "$"];
|
|
||||||
$valid = false;
|
|
||||||
foreach ($specials as $item) {
|
|
||||||
if (strpos($string, $item)) {
|
|
||||||
return $valid = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $valid;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,132 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace brain\utility;
|
||||||
|
|
||||||
|
use ReallySimpleJWT\Token;
|
||||||
|
use ReallySimpleJWT\Exception\BuildException;
|
||||||
|
use Mni\FrontYAML\Parser;
|
||||||
|
|
||||||
|
class StringTools
|
||||||
|
{
|
||||||
|
public static function createUUID()
|
||||||
|
{
|
||||||
|
if (function_exists("com_create_guid") === true) {
|
||||||
|
return trim(com_create_guid(), "{}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return sprintf(
|
||||||
|
"%04X%04X-%04X-%04X-%04X-%04X%04X%04X",
|
||||||
|
mt_rand(0, 65535),
|
||||||
|
mt_rand(0, 65535),
|
||||||
|
mt_rand(0, 65535),
|
||||||
|
mt_rand(16384, 20479),
|
||||||
|
mt_rand(32768, 49151),
|
||||||
|
mt_rand(0, 65535),
|
||||||
|
mt_rand(0, 65535),
|
||||||
|
mt_rand(0, 65535)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function sanitizeContent($entry)
|
||||||
|
{
|
||||||
|
$parser = new Parser();
|
||||||
|
$rendered = $parser->parse($entry);
|
||||||
|
$sanitizer = HtmlSanitizer\Sanitizer::create([
|
||||||
|
"extensions" => ["basic", "image", "list", "code"],
|
||||||
|
"tags" => [
|
||||||
|
"img" => [
|
||||||
|
"allowed_attributes" => ["src", "alt", "title", "class"],
|
||||||
|
"allowed_hosts" => null,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$preclean = $sanitizer->sanitize($rendered->getContent());
|
||||||
|
|
||||||
|
$cleaned = strip_tags($rendered->getContent(), [
|
||||||
|
"a",
|
||||||
|
"br",
|
||||||
|
"p",
|
||||||
|
"strong",
|
||||||
|
"br",
|
||||||
|
"img",
|
||||||
|
"iframe",
|
||||||
|
"ul",
|
||||||
|
"li",
|
||||||
|
"i",
|
||||||
|
"h1",
|
||||||
|
"h2",
|
||||||
|
"h3",
|
||||||
|
"pre",
|
||||||
|
"code",
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $cleaned;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function safeString($string)
|
||||||
|
{
|
||||||
|
return strtolower(
|
||||||
|
trim(
|
||||||
|
preg_replace(
|
||||||
|
"~[^0-9a-z]+~i",
|
||||||
|
"_",
|
||||||
|
html_entity_decode(
|
||||||
|
preg_replace(
|
||||||
|
"~&([a-z]{1,2})(?:acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);~i",
|
||||||
|
'$1',
|
||||||
|
htmlentities($string, ENT_QUOTES, "UTF-8")
|
||||||
|
),
|
||||||
|
ENT_QUOTES,
|
||||||
|
"UTF-8"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"-"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function randomString(int $length)
|
||||||
|
{
|
||||||
|
$alphanum =
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||||
|
$special = '*&!@%^#$';
|
||||||
|
$alphabet = $alphanum . $special;
|
||||||
|
$random = openssl_random_pseudo_bytes($length);
|
||||||
|
$alphabet_length = strlen($alphabet);
|
||||||
|
$string = "";
|
||||||
|
for ($i = 0; $i < $length; ++$i) {
|
||||||
|
$string .= $alphabet[ord($random[$i]) % $alphabet_length];
|
||||||
|
}
|
||||||
|
|
||||||
|
//secret needs to be a valid token
|
||||||
|
if ($length == 12) {
|
||||||
|
try {
|
||||||
|
$secret = Token::create(12, $string, time() + 3600, "localhost");
|
||||||
|
return $string;
|
||||||
|
} catch (BuildException $e) {
|
||||||
|
//bad secret, so try agiain
|
||||||
|
//echo "BAD STRING";
|
||||||
|
return self::randomString(12);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Token::validate($key, $string)) {
|
||||||
|
return $string;
|
||||||
|
} else {
|
||||||
|
return self::randomString(12);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function checkSpecial($string)
|
||||||
|
{
|
||||||
|
$specials = ["*", "&", "!", "@", "%", "^", "#", "$"];
|
||||||
|
$valid = false;
|
||||||
|
foreach ($specials as $item) {
|
||||||
|
if (strpos($string, $item)) {
|
||||||
|
return $valid = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $valid;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
<div id="options">
|
||||||
|
{% if page.menu == 'true' %}
|
||||||
|
{% set menu = "true" %}
|
||||||
|
{% else %}
|
||||||
|
{% set menu = "false" %}
|
||||||
|
{% endif %}
|
||||||
|
{% if page.published == 'true' %}
|
||||||
|
{% set published = "true" %}
|
||||||
|
{% else %}
|
||||||
|
{% set published = "false" %}
|
||||||
|
{% endif %}
|
||||||
|
{% if page.featured == 'true' %}
|
||||||
|
{% set featured = "true" %}
|
||||||
|
{% else %}
|
||||||
|
{% set featured = "false" %}
|
||||||
|
{% endif %}
|
||||||
|
<div id="option-left">
|
||||||
|
|
||||||
|
<button data-active="{{ menu }}">
|
||||||
|
<svg>
|
||||||
|
<use xlink:href="/assets/images/global/sprite.svg#entypo-add-to-list"/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<button data-active="{{ published }}">
|
||||||
|
<svg>
|
||||||
|
<use xlink:href="/assets/images/global/sprite.svg#entypo-globe"/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button data-active="{{ featured }}">
|
||||||
|
<svg>
|
||||||
|
<use xlink:href="/assets/images/global/sprite.svg#entypo-star"/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div id="option-right">
|
||||||
|
<span>
|
||||||
|
{{ page.updated }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
@ -0,0 +1,2 @@
|
|||||||
|
(()=>{class t{constructor(){this.start()}start(){console.log("Connected like F.E.")}}document.addEventListener("DOMContentLoaded",(function(){new t}),!1)})();
|
||||||
|
//# sourceMappingURL=Start.js.map
|
@ -0,0 +1 @@
|
|||||||
|
{"mappings":"4BAKIA,KAAKC,QAEPA,QACEC,QAAQC,IAAI,wBCNhBC,SAASC,iBACP,oBACA,WACa,IAAIC,KAEjB","sources":["src/themes/theme-fipamo-default/com/Base.js","src/themes/theme-fipamo-default/com/Start.js"],"sourcesContent":["export default class Base {\n //--------------------------\n // constructor\n //--------------------------\n constructor() {\n this.start();\n }\n start() {\n console.log(\"Connected like F.E.\");\n }\n //--------------------------\n // methods\n //--------------------------\n\n //--------------------------\n // event handlers\n //--------------------------\n}\n","import Base from \"./Base.js\";\n\ndocument.addEventListener(\n \"DOMContentLoaded\",\n function () {\n var base = new Base();\n },\n false\n);\n"],"names":["this","start","console","log","document","addEventListener","$b8d4b81eabebe07b$export$2e2bcd8739ae039"],"version":3,"file":"Start.js.map"}
|
@ -0,0 +1,583 @@
|
|||||||
|
// modules are defined as an array
|
||||||
|
// [ module function, map of requires ]
|
||||||
|
//
|
||||||
|
// map of requires is short require name -> numeric require
|
||||||
|
//
|
||||||
|
// anything defined in a previous bundle is accessed via the
|
||||||
|
// orig method which is the require for previous bundles
|
||||||
|
|
||||||
|
(function (modules, entry, mainEntry, parcelRequireName, globalName) {
|
||||||
|
/* eslint-disable no-undef */
|
||||||
|
var globalObject =
|
||||||
|
typeof globalThis !== 'undefined'
|
||||||
|
? globalThis
|
||||||
|
: typeof self !== 'undefined'
|
||||||
|
? self
|
||||||
|
: typeof window !== 'undefined'
|
||||||
|
? window
|
||||||
|
: typeof global !== 'undefined'
|
||||||
|
? global
|
||||||
|
: {};
|
||||||
|
/* eslint-enable no-undef */
|
||||||
|
|
||||||
|
// Save the require from previous bundle to this closure if any
|
||||||
|
var previousRequire =
|
||||||
|
typeof globalObject[parcelRequireName] === 'function' &&
|
||||||
|
globalObject[parcelRequireName];
|
||||||
|
|
||||||
|
var cache = previousRequire.cache || {};
|
||||||
|
// Do not use `require` to prevent Webpack from trying to bundle this call
|
||||||
|
var nodeRequire =
|
||||||
|
typeof module !== 'undefined' &&
|
||||||
|
typeof module.require === 'function' &&
|
||||||
|
module.require.bind(module);
|
||||||
|
|
||||||
|
function newRequire(name, jumped) {
|
||||||
|
if (!cache[name]) {
|
||||||
|
if (!modules[name]) {
|
||||||
|
// if we cannot find the module within our internal map or
|
||||||
|
// cache jump to the current global require ie. the last bundle
|
||||||
|
// that was added to the page.
|
||||||
|
var currentRequire =
|
||||||
|
typeof globalObject[parcelRequireName] === 'function' &&
|
||||||
|
globalObject[parcelRequireName];
|
||||||
|
if (!jumped && currentRequire) {
|
||||||
|
return currentRequire(name, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there are other bundles on this page the require from the
|
||||||
|
// previous one is saved to 'previousRequire'. Repeat this as
|
||||||
|
// many times as there are bundles until the module is found or
|
||||||
|
// we exhaust the require chain.
|
||||||
|
if (previousRequire) {
|
||||||
|
return previousRequire(name, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try the node require function if it exists.
|
||||||
|
if (nodeRequire && typeof name === 'string') {
|
||||||
|
return nodeRequire(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
var err = new Error("Cannot find module '" + name + "'");
|
||||||
|
err.code = 'MODULE_NOT_FOUND';
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
|
localRequire.resolve = resolve;
|
||||||
|
localRequire.cache = {};
|
||||||
|
|
||||||
|
var module = (cache[name] = new newRequire.Module(name));
|
||||||
|
|
||||||
|
modules[name][0].call(
|
||||||
|
module.exports,
|
||||||
|
localRequire,
|
||||||
|
module,
|
||||||
|
module.exports,
|
||||||
|
this
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cache[name].exports;
|
||||||
|
|
||||||
|
function localRequire(x) {
|
||||||
|
var res = localRequire.resolve(x);
|
||||||
|
return res === false ? {} : newRequire(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolve(x) {
|
||||||
|
var id = modules[name][1][x];
|
||||||
|
return id != null ? id : x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Module(moduleName) {
|
||||||
|
this.id = moduleName;
|
||||||
|
this.bundle = newRequire;
|
||||||
|
this.exports = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
newRequire.isParcelRequire = true;
|
||||||
|
newRequire.Module = Module;
|
||||||
|
newRequire.modules = modules;
|
||||||
|
newRequire.cache = cache;
|
||||||
|
newRequire.parent = previousRequire;
|
||||||
|
newRequire.register = function (id, exports) {
|
||||||
|
modules[id] = [
|
||||||
|
function (require, module) {
|
||||||
|
module.exports = exports;
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.defineProperty(newRequire, 'root', {
|
||||||
|
get: function () {
|
||||||
|
return globalObject[parcelRequireName];
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
globalObject[parcelRequireName] = newRequire;
|
||||||
|
|
||||||
|
for (var i = 0; i < entry.length; i++) {
|
||||||
|
newRequire(entry[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mainEntry) {
|
||||||
|
// Expose entry point to Node, AMD or browser globals
|
||||||
|
// Based on https://github.com/ForbesLindesay/umd/blob/master/template.js
|
||||||
|
var mainExports = newRequire(mainEntry);
|
||||||
|
|
||||||
|
// CommonJS
|
||||||
|
if (typeof exports === 'object' && typeof module !== 'undefined') {
|
||||||
|
module.exports = mainExports;
|
||||||
|
|
||||||
|
// RequireJS
|
||||||
|
} else if (typeof define === 'function' && define.amd) {
|
||||||
|
define(function () {
|
||||||
|
return mainExports;
|
||||||
|
});
|
||||||
|
|
||||||
|
// <script>
|
||||||
|
} else if (globalName) {
|
||||||
|
this[globalName] = mainExports;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})({"5ZIt9":[function(require,module,exports) {
|
||||||
|
"use strict";
|
||||||
|
var HMR_HOST = null;
|
||||||
|
var HMR_PORT = 1234;
|
||||||
|
var HMR_SECURE = false;
|
||||||
|
var HMR_ENV_HASH = "d6ea1d42532a7575";
|
||||||
|
module.bundle.HMR_BUNDLE_ID = "423b0fbd795fbd6e";
|
||||||
|
function _toConsumableArray(arr) {
|
||||||
|
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
|
||||||
|
}
|
||||||
|
function _nonIterableSpread() {
|
||||||
|
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
||||||
|
}
|
||||||
|
function _iterableToArray(iter) {
|
||||||
|
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
||||||
|
}
|
||||||
|
function _arrayWithoutHoles(arr) {
|
||||||
|
if (Array.isArray(arr)) return _arrayLikeToArray(arr);
|
||||||
|
}
|
||||||
|
function _createForOfIteratorHelper(o, allowArrayLike) {
|
||||||
|
var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
|
||||||
|
if (!it) {
|
||||||
|
if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
|
||||||
|
if (it) o = it;
|
||||||
|
var i = 0;
|
||||||
|
var F = function F() {
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
s: F,
|
||||||
|
n: function n() {
|
||||||
|
if (i >= o.length) return {
|
||||||
|
done: true
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
done: false,
|
||||||
|
value: o[i++]
|
||||||
|
};
|
||||||
|
},
|
||||||
|
e: function e(_e) {
|
||||||
|
throw _e;
|
||||||
|
},
|
||||||
|
f: F
|
||||||
|
};
|
||||||
|
}
|
||||||
|
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
||||||
|
}
|
||||||
|
var normalCompletion = true, didErr = false, err;
|
||||||
|
return {
|
||||||
|
s: function s() {
|
||||||
|
it = it.call(o);
|
||||||
|
},
|
||||||
|
n: function n() {
|
||||||
|
var step = it.next();
|
||||||
|
normalCompletion = step.done;
|
||||||
|
return step;
|
||||||
|
},
|
||||||
|
e: function e(_e2) {
|
||||||
|
didErr = true;
|
||||||
|
err = _e2;
|
||||||
|
},
|
||||||
|
f: function f() {
|
||||||
|
try {
|
||||||
|
if (!normalCompletion && it.return != null) it.return();
|
||||||
|
} finally{
|
||||||
|
if (didErr) throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function _unsupportedIterableToArray(o, minLen) {
|
||||||
|
if (!o) return;
|
||||||
|
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
|
||||||
|
var n = Object.prototype.toString.call(o).slice(8, -1);
|
||||||
|
if (n === "Object" && o.constructor) n = o.constructor.name;
|
||||||
|
if (n === "Map" || n === "Set") return Array.from(o);
|
||||||
|
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
|
||||||
|
}
|
||||||
|
function _arrayLikeToArray(arr, len) {
|
||||||
|
if (len == null || len > arr.length) len = arr.length;
|
||||||
|
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
||||||
|
return arr2;
|
||||||
|
}
|
||||||
|
/* global HMR_HOST, HMR_PORT, HMR_ENV_HASH, HMR_SECURE */ /*::
|
||||||
|
import type {
|
||||||
|
HMRAsset,
|
||||||
|
HMRMessage,
|
||||||
|
} from '@parcel/reporter-dev-server/src/HMRServer.js';
|
||||||
|
interface ParcelRequire {
|
||||||
|
(string): mixed;
|
||||||
|
cache: {|[string]: ParcelModule|};
|
||||||
|
hotData: mixed;
|
||||||
|
Module: any;
|
||||||
|
parent: ?ParcelRequire;
|
||||||
|
isParcelRequire: true;
|
||||||
|
modules: {|[string]: [Function, {|[string]: string|}]|};
|
||||||
|
HMR_BUNDLE_ID: string;
|
||||||
|
root: ParcelRequire;
|
||||||
|
}
|
||||||
|
interface ParcelModule {
|
||||||
|
hot: {|
|
||||||
|
data: mixed,
|
||||||
|
accept(cb: (Function) => void): void,
|
||||||
|
dispose(cb: (mixed) => void): void,
|
||||||
|
// accept(deps: Array<string> | string, cb: (Function) => void): void,
|
||||||
|
// decline(): void,
|
||||||
|
_acceptCallbacks: Array<(Function) => void>,
|
||||||
|
_disposeCallbacks: Array<(mixed) => void>,
|
||||||
|
|};
|
||||||
|
}
|
||||||
|
declare var module: {bundle: ParcelRequire, ...};
|
||||||
|
declare var HMR_HOST: string;
|
||||||
|
declare var HMR_PORT: string;
|
||||||
|
declare var HMR_ENV_HASH: string;
|
||||||
|
declare var HMR_SECURE: boolean;
|
||||||
|
*/ var OVERLAY_ID = '__parcel__error__overlay__';
|
||||||
|
var OldModule = module.bundle.Module;
|
||||||
|
function Module(moduleName) {
|
||||||
|
OldModule.call(this, moduleName);
|
||||||
|
this.hot = {
|
||||||
|
data: module.bundle.hotData,
|
||||||
|
_acceptCallbacks: [],
|
||||||
|
_disposeCallbacks: [],
|
||||||
|
accept: function accept(fn) {
|
||||||
|
this._acceptCallbacks.push(fn || function() {
|
||||||
|
});
|
||||||
|
},
|
||||||
|
dispose: function dispose(fn) {
|
||||||
|
this._disposeCallbacks.push(fn);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
module.bundle.hotData = undefined;
|
||||||
|
}
|
||||||
|
module.bundle.Module = Module;
|
||||||
|
var checkedAssets, acceptedAssets, assetsToAccept;
|
||||||
|
function getHostname() {
|
||||||
|
return HMR_HOST || (location.protocol.indexOf('http') === 0 ? location.hostname : 'localhost');
|
||||||
|
}
|
||||||
|
function getPort() {
|
||||||
|
return HMR_PORT || location.port;
|
||||||
|
} // eslint-disable-next-line no-redeclare
|
||||||
|
var parent = module.bundle.parent;
|
||||||
|
if ((!parent || !parent.isParcelRequire) && typeof WebSocket !== 'undefined') {
|
||||||
|
var hostname = getHostname();
|
||||||
|
var port = getPort();
|
||||||
|
var protocol = HMR_SECURE || location.protocol == 'https:' && !/localhost|127.0.0.1|0.0.0.0/.test(hostname) ? 'wss' : 'ws';
|
||||||
|
var ws = new WebSocket(protocol + '://' + hostname + (port ? ':' + port : '') + '/'); // $FlowFixMe
|
||||||
|
ws.onmessage = function(event) {
|
||||||
|
checkedAssets = {
|
||||||
|
};
|
||||||
|
acceptedAssets = {
|
||||||
|
};
|
||||||
|
assetsToAccept = [];
|
||||||
|
var data = JSON.parse(event.data);
|
||||||
|
if (data.type === 'update') {
|
||||||
|
// Remove error overlay if there is one
|
||||||
|
if (typeof document !== 'undefined') removeErrorOverlay();
|
||||||
|
var assets = data.assets.filter(function(asset) {
|
||||||
|
return asset.envHash === HMR_ENV_HASH;
|
||||||
|
}); // Handle HMR Update
|
||||||
|
var handled = assets.every(function(asset) {
|
||||||
|
return asset.type === 'css' || asset.type === 'js' && hmrAcceptCheck(module.bundle.root, asset.id, asset.depsByBundle);
|
||||||
|
});
|
||||||
|
if (handled) {
|
||||||
|
console.clear();
|
||||||
|
assets.forEach(function(asset) {
|
||||||
|
hmrApply(module.bundle.root, asset);
|
||||||
|
});
|
||||||
|
for(var i = 0; i < assetsToAccept.length; i++){
|
||||||
|
var id = assetsToAccept[i][1];
|
||||||
|
if (!acceptedAssets[id]) hmrAcceptRun(assetsToAccept[i][0], id);
|
||||||
|
}
|
||||||
|
} else window.location.reload();
|
||||||
|
}
|
||||||
|
if (data.type === 'error') {
|
||||||
|
// Log parcel errors to console
|
||||||
|
var _iterator = _createForOfIteratorHelper(data.diagnostics.ansi), _step;
|
||||||
|
try {
|
||||||
|
for(_iterator.s(); !(_step = _iterator.n()).done;){
|
||||||
|
var ansiDiagnostic = _step.value;
|
||||||
|
var stack = ansiDiagnostic.codeframe ? ansiDiagnostic.codeframe : ansiDiagnostic.stack;
|
||||||
|
console.error('🚨 [parcel]: ' + ansiDiagnostic.message + '\n' + stack + '\n\n' + ansiDiagnostic.hints.join('\n'));
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
_iterator.e(err);
|
||||||
|
} finally{
|
||||||
|
_iterator.f();
|
||||||
|
}
|
||||||
|
if (typeof document !== 'undefined') {
|
||||||
|
// Render the fancy html overlay
|
||||||
|
removeErrorOverlay();
|
||||||
|
var overlay = createErrorOverlay(data.diagnostics.html); // $FlowFixMe
|
||||||
|
document.body.appendChild(overlay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ws.onerror = function(e) {
|
||||||
|
console.error(e.message);
|
||||||
|
};
|
||||||
|
ws.onclose = function() {
|
||||||
|
console.warn('[parcel] 🚨 Connection to the HMR server was lost');
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function removeErrorOverlay() {
|
||||||
|
var overlay = document.getElementById(OVERLAY_ID);
|
||||||
|
if (overlay) {
|
||||||
|
overlay.remove();
|
||||||
|
console.log('[parcel] ✨ Error resolved');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function createErrorOverlay(diagnostics) {
|
||||||
|
var overlay = document.createElement('div');
|
||||||
|
overlay.id = OVERLAY_ID;
|
||||||
|
var errorHTML = '<div style="background: black; opacity: 0.85; font-size: 16px; color: white; position: fixed; height: 100%; width: 100%; top: 0px; left: 0px; padding: 30px; font-family: Menlo, Consolas, monospace; z-index: 9999;">';
|
||||||
|
var _iterator2 = _createForOfIteratorHelper(diagnostics), _step2;
|
||||||
|
try {
|
||||||
|
for(_iterator2.s(); !(_step2 = _iterator2.n()).done;){
|
||||||
|
var diagnostic = _step2.value;
|
||||||
|
var stack = diagnostic.codeframe ? diagnostic.codeframe : diagnostic.stack;
|
||||||
|
errorHTML += "\n <div>\n <div style=\"font-size: 18px; font-weight: bold; margin-top: 20px;\">\n \uD83D\uDEA8 ".concat(diagnostic.message, "\n </div>\n <pre>").concat(stack, "</pre>\n <div>\n ").concat(diagnostic.hints.map(function(hint) {
|
||||||
|
return '<div>💡 ' + hint + '</div>';
|
||||||
|
}).join(''), "\n </div>\n ").concat(diagnostic.documentation ? "<div>\uD83D\uDCDD <a style=\"color: violet\" href=\"".concat(diagnostic.documentation, "\" target=\"_blank\">Learn more</a></div>") : '', "\n </div>\n ");
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
_iterator2.e(err);
|
||||||
|
} finally{
|
||||||
|
_iterator2.f();
|
||||||
|
}
|
||||||
|
errorHTML += '</div>';
|
||||||
|
overlay.innerHTML = errorHTML;
|
||||||
|
return overlay;
|
||||||
|
}
|
||||||
|
function getParents(bundle, id) /*: Array<[ParcelRequire, string]> */ {
|
||||||
|
var modules = bundle.modules;
|
||||||
|
if (!modules) return [];
|
||||||
|
var parents = [];
|
||||||
|
var k, d, dep;
|
||||||
|
for(k in modules)for(d in modules[k][1]){
|
||||||
|
dep = modules[k][1][d];
|
||||||
|
if (dep === id || Array.isArray(dep) && dep[dep.length - 1] === id) parents.push([
|
||||||
|
bundle,
|
||||||
|
k
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
if (bundle.parent) parents = parents.concat(getParents(bundle.parent, id));
|
||||||
|
return parents;
|
||||||
|
}
|
||||||
|
function updateLink(link) {
|
||||||
|
var newLink = link.cloneNode();
|
||||||
|
newLink.onload = function() {
|
||||||
|
if (link.parentNode !== null) // $FlowFixMe
|
||||||
|
link.parentNode.removeChild(link);
|
||||||
|
};
|
||||||
|
newLink.setAttribute('href', link.getAttribute('href').split('?')[0] + '?' + Date.now()); // $FlowFixMe
|
||||||
|
link.parentNode.insertBefore(newLink, link.nextSibling);
|
||||||
|
}
|
||||||
|
var cssTimeout = null;
|
||||||
|
function reloadCSS() {
|
||||||
|
if (cssTimeout) return;
|
||||||
|
cssTimeout = setTimeout(function() {
|
||||||
|
var links = document.querySelectorAll('link[rel="stylesheet"]');
|
||||||
|
for(var i = 0; i < links.length; i++){
|
||||||
|
// $FlowFixMe[incompatible-type]
|
||||||
|
var href = links[i].getAttribute('href');
|
||||||
|
var hostname = getHostname();
|
||||||
|
var servedFromHMRServer = hostname === 'localhost' ? new RegExp('^(https?:\\/\\/(0.0.0.0|127.0.0.1)|localhost):' + getPort()).test(href) : href.indexOf(hostname + ':' + getPort());
|
||||||
|
var absolute = /^https?:\/\//i.test(href) && href.indexOf(window.location.origin) !== 0 && !servedFromHMRServer;
|
||||||
|
if (!absolute) updateLink(links[i]);
|
||||||
|
}
|
||||||
|
cssTimeout = null;
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
|
function hmrApply(bundle, asset) {
|
||||||
|
var modules = bundle.modules;
|
||||||
|
if (!modules) return;
|
||||||
|
if (asset.type === 'css') reloadCSS();
|
||||||
|
else if (asset.type === 'js') {
|
||||||
|
var deps = asset.depsByBundle[bundle.HMR_BUNDLE_ID];
|
||||||
|
if (deps) {
|
||||||
|
if (modules[asset.id]) {
|
||||||
|
// Remove dependencies that are removed and will become orphaned.
|
||||||
|
// This is necessary so that if the asset is added back again, the cache is gone, and we prevent a full page reload.
|
||||||
|
var oldDeps = modules[asset.id][1];
|
||||||
|
for(var dep in oldDeps)if (!deps[dep] || deps[dep] !== oldDeps[dep]) {
|
||||||
|
var id = oldDeps[dep];
|
||||||
|
var parents = getParents(module.bundle.root, id);
|
||||||
|
if (parents.length === 1) hmrDelete(module.bundle.root, id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var fn = new Function('require', 'module', 'exports', asset.output);
|
||||||
|
modules[asset.id] = [
|
||||||
|
fn,
|
||||||
|
deps
|
||||||
|
];
|
||||||
|
} else if (bundle.parent) hmrApply(bundle.parent, asset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function hmrDelete(bundle, id1) {
|
||||||
|
var modules = bundle.modules;
|
||||||
|
if (!modules) return;
|
||||||
|
if (modules[id1]) {
|
||||||
|
// Collect dependencies that will become orphaned when this module is deleted.
|
||||||
|
var deps = modules[id1][1];
|
||||||
|
var orphans = [];
|
||||||
|
for(var dep in deps){
|
||||||
|
var parents = getParents(module.bundle.root, deps[dep]);
|
||||||
|
if (parents.length === 1) orphans.push(deps[dep]);
|
||||||
|
} // Delete the module. This must be done before deleting dependencies in case of circular dependencies.
|
||||||
|
delete modules[id1];
|
||||||
|
delete bundle.cache[id1]; // Now delete the orphans.
|
||||||
|
orphans.forEach(function(id) {
|
||||||
|
hmrDelete(module.bundle.root, id);
|
||||||
|
});
|
||||||
|
} else if (bundle.parent) hmrDelete(bundle.parent, id1);
|
||||||
|
}
|
||||||
|
function hmrAcceptCheck(bundle, id, depsByBundle) {
|
||||||
|
if (hmrAcceptCheckOne(bundle, id, depsByBundle)) return true;
|
||||||
|
// Traverse parents breadth first. All possible ancestries must accept the HMR update, or we'll reload.
|
||||||
|
var parents = getParents(module.bundle.root, id);
|
||||||
|
var accepted = false;
|
||||||
|
while(parents.length > 0){
|
||||||
|
var v = parents.shift();
|
||||||
|
var a = hmrAcceptCheckOne(v[0], v[1], null);
|
||||||
|
if (a) // If this parent accepts, stop traversing upward, but still consider siblings.
|
||||||
|
accepted = true;
|
||||||
|
else {
|
||||||
|
// Otherwise, queue the parents in the next level upward.
|
||||||
|
var p = getParents(module.bundle.root, v[1]);
|
||||||
|
if (p.length === 0) {
|
||||||
|
// If there are no parents, then we've reached an entry without accepting. Reload.
|
||||||
|
accepted = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
parents.push.apply(parents, _toConsumableArray(p));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return accepted;
|
||||||
|
}
|
||||||
|
function hmrAcceptCheckOne(bundle, id, depsByBundle) {
|
||||||
|
var modules = bundle.modules;
|
||||||
|
if (!modules) return;
|
||||||
|
if (depsByBundle && !depsByBundle[bundle.HMR_BUNDLE_ID]) {
|
||||||
|
// If we reached the root bundle without finding where the asset should go,
|
||||||
|
// there's nothing to do. Mark as "accepted" so we don't reload the page.
|
||||||
|
if (!bundle.parent) return true;
|
||||||
|
return hmrAcceptCheck(bundle.parent, id, depsByBundle);
|
||||||
|
}
|
||||||
|
if (checkedAssets[id]) return true;
|
||||||
|
checkedAssets[id] = true;
|
||||||
|
var cached = bundle.cache[id];
|
||||||
|
assetsToAccept.push([
|
||||||
|
bundle,
|
||||||
|
id
|
||||||
|
]);
|
||||||
|
if (!cached || cached.hot && cached.hot._acceptCallbacks.length) return true;
|
||||||
|
}
|
||||||
|
function hmrAcceptRun(bundle, id) {
|
||||||
|
var cached = bundle.cache[id];
|
||||||
|
bundle.hotData = {
|
||||||
|
};
|
||||||
|
if (cached && cached.hot) cached.hot.data = bundle.hotData;
|
||||||
|
if (cached && cached.hot && cached.hot._disposeCallbacks.length) cached.hot._disposeCallbacks.forEach(function(cb) {
|
||||||
|
cb(bundle.hotData);
|
||||||
|
});
|
||||||
|
delete bundle.cache[id];
|
||||||
|
bundle(id);
|
||||||
|
cached = bundle.cache[id];
|
||||||
|
if (cached && cached.hot && cached.hot._acceptCallbacks.length) cached.hot._acceptCallbacks.forEach(function(cb) {
|
||||||
|
var assetsToAlsoAccept = cb(function() {
|
||||||
|
return getParents(module.bundle.root, id);
|
||||||
|
});
|
||||||
|
if (assetsToAlsoAccept && assetsToAccept.length) // $FlowFixMe[method-unbinding]
|
||||||
|
assetsToAccept.push.apply(assetsToAccept, assetsToAlsoAccept);
|
||||||
|
});
|
||||||
|
acceptedAssets[id] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
},{}],"3OjfR":[function(require,module,exports) {
|
||||||
|
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
|
||||||
|
var _baseJs = require("./Base.js");
|
||||||
|
var _baseJsDefault = parcelHelpers.interopDefault(_baseJs);
|
||||||
|
document.addEventListener("DOMContentLoaded", function() {
|
||||||
|
var base = new _baseJsDefault.default();
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
},{"./Base.js":"jWciR","@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}],"jWciR":[function(require,module,exports) {
|
||||||
|
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
|
||||||
|
parcelHelpers.defineInteropFlag(exports);
|
||||||
|
class Base {
|
||||||
|
//--------------------------
|
||||||
|
// constructor
|
||||||
|
//--------------------------
|
||||||
|
constructor(){
|
||||||
|
this.currentSlide = 0;
|
||||||
|
this.slides = document.querySelectorAll("#media .slide");
|
||||||
|
this.start();
|
||||||
|
}
|
||||||
|
start() {
|
||||||
|
if (this.slides.length > 1) this.slideInterval = setInterval(()=>{
|
||||||
|
this.slides[this.currentSlide].className = "slide hide";
|
||||||
|
this.currentSlide = (this.currentSlide + 1) % this.slides.length;
|
||||||
|
this.slides[this.currentSlide].className = "slide show";
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.default = Base;
|
||||||
|
|
||||||
|
},{"@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}],"gkKU3":[function(require,module,exports) {
|
||||||
|
exports.interopDefault = function(a) {
|
||||||
|
return a && a.__esModule ? a : {
|
||||||
|
default: a
|
||||||
|
};
|
||||||
|
};
|
||||||
|
exports.defineInteropFlag = function(a) {
|
||||||
|
Object.defineProperty(a, '__esModule', {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
};
|
||||||
|
exports.exportAll = function(source, dest) {
|
||||||
|
Object.keys(source).forEach(function(key) {
|
||||||
|
if (key === 'default' || key === '__esModule' || dest.hasOwnProperty(key)) return;
|
||||||
|
Object.defineProperty(dest, key, {
|
||||||
|
enumerable: true,
|
||||||
|
get: function() {
|
||||||
|
return source[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return dest;
|
||||||
|
};
|
||||||
|
exports.export = function(dest, destName, get) {
|
||||||
|
Object.defineProperty(dest, destName, {
|
||||||
|
enumerable: true,
|
||||||
|
get: get
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
},{}]},["5ZIt9","3OjfR"], "3OjfR", "parcelRequire0e20")
|
||||||
|
|
||||||
|
//# sourceMappingURL=ThemeStart.js.map
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,33 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg width="100%" height="100%" viewBox="0 0 486 678" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||||
|
<g id="Logo" transform="matrix(1.36867,0,0,1.36867,-351.696,-71.9183)">
|
||||||
|
<g transform="matrix(2.31599,0,0,2.31599,218.53,-99.4797)">
|
||||||
|
<path d="M93.67,140.92L93.67,140.921C105.569,140.921 115.216,150.567 115.216,162.467L115.216,172.724L115.216,172.724L115.216,182.262C115.216,194.161 105.569,203.808 93.669,203.808C81.976,203.217 74.12,195.969 72.237,184.474L72.282,182.737L72.282,162.467L72.205,160.847C72.775,149.587 82.728,141.121 93.67,140.92Z" style="fill:rgb(252,99,153);fill-rule:nonzero;"/>
|
||||||
|
</g>
|
||||||
|
<g transform="matrix(2.31599,0,0,2.31599,218.53,-437.697)">
|
||||||
|
<path d="M93.67,211.678L93.67,211.678C105.569,211.678 115.216,221.324 115.216,233.224L115.216,243.481L115.216,243.481L115.216,253.019C115.216,264.919 105.569,274.565 93.669,274.565C81.976,273.975 74.12,266.726 72.237,255.232L72.282,253.495L72.282,233.224L72.205,231.604C72.775,220.344 82.728,211.878 93.67,211.678Z" style="fill:rgb(252,99,153);fill-rule:nonzero;"/>
|
||||||
|
</g>
|
||||||
|
<g transform="matrix(2.31599,0,0,2.31599,218.53,241.338)">
|
||||||
|
<path d="M93.67,69.288L93.67,69.288C105.569,69.288 115.216,78.934 115.216,90.834L115.216,101.091L115.216,101.091L115.216,110.629C115.216,122.528 105.569,132.175 93.669,132.175C81.976,131.584 74.12,124.336 72.237,112.842L72.282,111.105L72.282,90.834L72.205,89.214C72.775,77.954 82.728,69.488 93.67,69.288Z" style="fill:rgb(171,183,183);fill-rule:nonzero;"/>
|
||||||
|
</g>
|
||||||
|
<g transform="matrix(2.31599,0,0,2.31599,218.53,-104.112)">
|
||||||
|
<path d="M38.059,142.92L38.059,142.921C49.958,142.921 59.605,152.567 59.605,164.467L59.605,174.724L59.605,174.724L59.605,184.262C59.605,196.161 49.958,205.808 38.058,205.808C26.365,205.217 18.509,197.969 16.626,186.474L16.671,184.737L16.671,164.467L16.594,162.847C17.164,151.587 27.117,143.121 38.059,142.92Z" style="fill:rgb(252,99,153);fill-rule:nonzero;"/>
|
||||||
|
</g>
|
||||||
|
<g transform="matrix(2.31599,0,0,2.31599,218.53,-104.112)">
|
||||||
|
<path d="M148.331,142.92L148.331,142.921C160.23,142.921 169.877,152.567 169.877,164.467L169.877,174.724L169.877,174.724L169.877,184.262C169.877,196.161 160.23,205.808 148.331,205.808C136.637,205.217 128.782,197.969 126.898,186.474L126.943,184.737L126.943,164.467L126.867,162.847C127.436,151.587 137.389,143.121 148.331,142.92Z" style="fill:rgb(171,183,183);fill-rule:nonzero;"/>
|
||||||
|
</g>
|
||||||
|
<g transform="matrix(2.31599,0,0,2.31599,218.53,-437.697)">
|
||||||
|
<path d="M38.059,211.678L38.059,211.678C49.958,211.678 59.605,221.324 59.605,233.224L59.605,243.481L59.605,243.481L59.605,253.019C59.605,264.919 49.958,274.565 38.058,274.565C26.365,273.975 18.509,266.726 16.626,255.232L16.671,253.495L16.671,233.224L16.594,231.604C17.164,220.344 27.117,211.878 38.059,211.678Z" style="fill:rgb(252,99,153);fill-rule:nonzero;"/>
|
||||||
|
</g>
|
||||||
|
<g transform="matrix(2.31599,0,0,2.31599,218.53,-437.697)">
|
||||||
|
<path d="M148.331,211.678L148.331,211.678C160.23,211.678 169.877,221.324 169.877,233.224L169.877,243.481L169.877,243.481L169.877,253.019C169.877,264.919 160.23,274.565 148.331,274.565C136.637,273.975 128.782,266.726 126.898,255.232L126.943,253.495L126.943,233.224L126.867,231.604C127.436,220.344 137.389,211.878 148.331,211.678Z" style="fill:rgb(252,99,153);fill-rule:nonzero;"/>
|
||||||
|
</g>
|
||||||
|
<g transform="matrix(2.31599,0,0,2.31599,218.53,241.338)">
|
||||||
|
<path d="M38.059,69.288L38.059,69.288C49.958,69.288 59.605,78.934 59.605,90.834L59.605,101.091L59.605,101.091L59.605,110.629C59.605,122.528 49.958,132.175 38.058,132.175C26.365,131.584 18.509,124.336 16.626,112.842L16.671,111.105L16.671,90.834L16.594,89.214C17.164,77.954 27.117,69.488 38.059,69.288Z" style="fill:rgb(252,99,153);fill-rule:nonzero;"/>
|
||||||
|
</g>
|
||||||
|
<g transform="matrix(2.31599,0,0,2.31599,218.53,241.338)">
|
||||||
|
<path d="M148.331,69.288L148.331,69.288C160.23,69.288 169.877,78.934 169.877,90.834L169.877,101.091L169.877,101.091L169.877,110.629C169.877,122.528 160.23,132.175 148.331,132.175C136.637,131.584 128.782,124.336 126.898,112.842L126.943,111.105L126.943,90.834L126.867,89.214C127.436,77.954 137.389,69.488 148.331,69.288Z" style="fill:rgb(171,183,183);fill-rule:nonzero;"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 4.6 KiB |
Binary file not shown.
After Width: | Height: | Size: 8.0 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.9 KiB |
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
require "../vendor/autoload.php";
|
require "../vendor/autoload.php";
|
||||||
include "../brain/App.inc.php";
|
|
||||||
|
use brain\init\App as App;
|
||||||
|
|
||||||
new App();
|
new App();
|
||||||
|
@ -0,0 +1,204 @@
|
|||||||
|
import Sortable from 'sortablejs';
|
||||||
|
import DataUtils from '../utils/DataUtils';
|
||||||
|
import Notfications from './Notifications.js';
|
||||||
|
const notify = new Notfications();
|
||||||
|
|
||||||
|
export default class FileManager {
|
||||||
|
//--------------------------
|
||||||
|
// constructor
|
||||||
|
//--------------------------
|
||||||
|
constructor(upload, input, imageList, fileList) {
|
||||||
|
this.upload = upload;
|
||||||
|
this.input = input;
|
||||||
|
this.imageList = imageList;
|
||||||
|
this.fileList = fileList;
|
||||||
|
this.accetableFiles = [
|
||||||
|
'image/jpeg',
|
||||||
|
'image/gif',
|
||||||
|
'image/png',
|
||||||
|
'image/svg',
|
||||||
|
'audio/mpeg',
|
||||||
|
'video/mp4',
|
||||||
|
'application/pdf',
|
||||||
|
'text/plain',
|
||||||
|
'text/rtf'
|
||||||
|
];
|
||||||
|
this.files = [];
|
||||||
|
this.sortedFiles = [];
|
||||||
|
this.storage = [];
|
||||||
|
this.start();
|
||||||
|
}
|
||||||
|
//--------------------------
|
||||||
|
// methods
|
||||||
|
//--------------------------
|
||||||
|
start() {
|
||||||
|
this.upload.addEventListener('dragover', e => this.handleFileActions(e), false);
|
||||||
|
this.upload.addEventListener('drop', e => this.handleFileActions(e), false);
|
||||||
|
this.input.addEventListener('change', e => this.handleFileActions(e), false);
|
||||||
|
|
||||||
|
Sortable.create(this.imageList, {
|
||||||
|
onUpdate: e => {
|
||||||
|
notify.alert('REINDEXING FILES', null);
|
||||||
|
let currentFiles = []; //store current list
|
||||||
|
let items = e.target.children;
|
||||||
|
for (let index = 0; index < items.length; index++) {
|
||||||
|
var item = items[index];
|
||||||
|
let url = '';
|
||||||
|
if (item.className == 'img-item') {
|
||||||
|
url = item.style.backgroundImage.slice(4, -1).replace(/"/g, '');
|
||||||
|
} else {
|
||||||
|
url = item.getAttribute('data-source');
|
||||||
|
}
|
||||||
|
|
||||||
|
currentFiles.push({
|
||||||
|
earl: url
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.reindexFiles(currentFiles, 0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Sortable.create(this.fileList, {
|
||||||
|
onUpdate: e => {
|
||||||
|
notify.alert('REINDEXING FILES', null);
|
||||||
|
let currentFiles = [];
|
||||||
|
let items = e.target.children;
|
||||||
|
for (let index = 0; index < items.length; index++) {
|
||||||
|
var item = items[index];
|
||||||
|
let url = item.getAttribute('data-source');
|
||||||
|
currentFiles.push({
|
||||||
|
earl: url
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.reindexFiles(currentFiles, 0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getFiles() {
|
||||||
|
return this.files;
|
||||||
|
}
|
||||||
|
|
||||||
|
reindexFiles(sortOrder, step) {
|
||||||
|
let count = sortOrder.length;
|
||||||
|
if (step == 0) this.files = [];
|
||||||
|
var utils = new DataUtils();
|
||||||
|
var path = sortOrder[step].earl.split('/');
|
||||||
|
utils.imgLoad(sortOrder[step].earl).then(blob => {
|
||||||
|
var fresh = new File([blob], path[6], { type: blob.type });
|
||||||
|
this.files.push(fresh);
|
||||||
|
if (this.files.length <= count - 1) {
|
||||||
|
this.reindexFiles(sortOrder, ++step);
|
||||||
|
} else {
|
||||||
|
notify.alert('FILES READY TO UPLOAD', true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
sortFiles(files) {
|
||||||
|
var self = this;
|
||||||
|
this.files = []; //clear files array
|
||||||
|
this.imageList.innerHTML = '';
|
||||||
|
this.fileList.innerHTML = '';
|
||||||
|
for (var i = 0, file; (file = files[i]); i++) {
|
||||||
|
var reader = new FileReader();
|
||||||
|
// Closure to capture the file information
|
||||||
|
|
||||||
|
reader.onload = (theFile => {
|
||||||
|
return function (f) {
|
||||||
|
// sort files
|
||||||
|
switch (theFile.type) {
|
||||||
|
case 'image/jpg':
|
||||||
|
case 'image/jpeg':
|
||||||
|
case 'image/gif':
|
||||||
|
case 'image/svg':
|
||||||
|
case 'image/png':
|
||||||
|
//create element and add to list
|
||||||
|
var image = document.createElement('img');
|
||||||
|
image.src = f.target.result;
|
||||||
|
image.title = escape(theFile.name);
|
||||||
|
var span = document.createElement('div');
|
||||||
|
span.style.background =
|
||||||
|
'url(' +
|
||||||
|
f.target.result +
|
||||||
|
') no-repeat center center / cover';
|
||||||
|
span.className = 'img-item';
|
||||||
|
image.setAttribute('id', i);
|
||||||
|
self.storage.push([
|
||||||
|
{
|
||||||
|
id: 'page_image' + i,
|
||||||
|
data: f.target.result,
|
||||||
|
type: theFile.type,
|
||||||
|
name: escape(theFile.name)
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
self.imageList.appendChild(span);
|
||||||
|
//add to files list
|
||||||
|
self.files.push(theFile);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 'video/mp4':
|
||||||
|
var video = document.createElement('div');
|
||||||
|
video.className = 'video-item';
|
||||||
|
video.setAttribute('data-source', f.target.result);
|
||||||
|
self.imageList.appendChild(video);
|
||||||
|
self.files.push(theFile);
|
||||||
|
break;
|
||||||
|
case 'audio/mpeg':
|
||||||
|
var sound = document.createElement('div');
|
||||||
|
sound.className = 'audio-item';
|
||||||
|
sound.setAttribute('data-source', f.target.result);
|
||||||
|
self.fileList.appendChild(sound);
|
||||||
|
self.files.push(theFile);
|
||||||
|
break;
|
||||||
|
case 'application/pdf':
|
||||||
|
case 'text/plain':
|
||||||
|
case 'text/rtf':
|
||||||
|
var file = document.createElement('div');
|
||||||
|
file.className = 'file-item';
|
||||||
|
file.setAttribute('data-source', f.target.result);
|
||||||
|
self.fileList.appendChild(file);
|
||||||
|
self.files.push(theFile);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})(file);
|
||||||
|
// Read in the image file as a data URL.
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------
|
||||||
|
// event handlers
|
||||||
|
//--------------------------
|
||||||
|
handleFileActions(e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
let self = this;
|
||||||
|
let rawList = [];
|
||||||
|
let sortedList = [];
|
||||||
|
let notOnTheList = [];
|
||||||
|
|
||||||
|
switch (e.type) {
|
||||||
|
case 'dragover':
|
||||||
|
e.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.
|
||||||
|
break;
|
||||||
|
case 'change':
|
||||||
|
case 'drop':
|
||||||
|
e.type == 'drop'
|
||||||
|
? (rawList = e.dataTransfer.files)
|
||||||
|
: (rawList = e.target.files);
|
||||||
|
for (var i = 0, f; (f = rawList[i]); i++) {
|
||||||
|
// check witch files are cool to upload
|
||||||
|
if (this.accetableFiles.includes(f.type)) {
|
||||||
|
sortedList.push(f);
|
||||||
|
} else {
|
||||||
|
notOnTheList.push(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//send for sorting
|
||||||
|
self.sortFiles(sortedList);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue