diff --git a/brain/App.inc.php b/brain/App.inc.php deleted file mode 100644 index 0ac8161..0000000 --- a/brain/App.inc.php +++ /dev/null @@ -1,48 +0,0 @@ -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(); - } -} diff --git a/brain/api/v1/AuthAPI.inc.php b/brain/api/v1/AuthAPI.inc.php deleted file mode 100644 index 8d99ef9..0000000 --- a/brain/api/v1/AuthAPI.inc.php +++ /dev/null @@ -1,74 +0,0 @@ - "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; - } -} diff --git a/brain/api/v1/AuthAPI.php b/brain/api/v1/AuthAPI.php new file mode 100644 index 0000000..a95dd47 --- /dev/null +++ b/brain/api/v1/AuthAPI.php @@ -0,0 +1,79 @@ + "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; + } +} diff --git a/brain/api/v1/ImagesAPI.inc.php b/brain/api/v1/ImagesAPI.inc.php deleted file mode 100644 index 1bfed8e..0000000 --- a/brain/api/v1/ImagesAPI.inc.php +++ /dev/null @@ -1,76 +0,0 @@ -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; - } -} diff --git a/brain/api/v1/ImagesAPI.php b/brain/api/v1/ImagesAPI.php new file mode 100644 index 0000000..4329969 --- /dev/null +++ b/brain/api/v1/ImagesAPI.php @@ -0,0 +1,81 @@ +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; + } +} diff --git a/brain/api/v1/InitAPI.inc.php b/brain/api/v1/InitAPI.inc.php deleted file mode 100644 index 871e068..0000000 --- a/brain/api/v1/InitAPI.inc.php +++ /dev/null @@ -1,30 +0,0 @@ - "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; - } -} diff --git a/brain/api/v1/InitAPI.php b/brain/api/v1/InitAPI.php new file mode 100644 index 0000000..4c67320 --- /dev/null +++ b/brain/api/v1/InitAPI.php @@ -0,0 +1,34 @@ + "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; + } +} diff --git a/brain/api/v1/MailerAPI.inc.php b/brain/api/v1/MailerAPI.inc.php deleted file mode 100644 index 669a5b5..0000000 --- a/brain/api/v1/MailerAPI.inc.php +++ /dev/null @@ -1,26 +0,0 @@ - "You need to be logged in for this, champ.", - "type" => "MAILER_ERROR", - ]; - } - } else { - } - - return $result; - } -} diff --git a/brain/api/v1/MailerAPI.php b/brain/api/v1/MailerAPI.php new file mode 100644 index 0000000..5eb4c36 --- /dev/null +++ b/brain/api/v1/MailerAPI.php @@ -0,0 +1,31 @@ + "You need to be logged in for this, champ.", + "type" => "MAILER_ERROR", + ]; + } + } else { + } + + return $result; + } +} diff --git a/brain/api/v1/PagesAPI.inc.php b/brain/api/v1/PagesAPI.inc.php deleted file mode 100644 index b8f15f0..0000000 --- a/brain/api/v1/PagesAPI.inc.php +++ /dev/null @@ -1,171 +0,0 @@ -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; - } -} diff --git a/brain/api/v1/PagesAPI.php b/brain/api/v1/PagesAPI.php new file mode 100644 index 0000000..89f1d9f --- /dev/null +++ b/brain/api/v1/PagesAPI.php @@ -0,0 +1,180 @@ +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; + } +} diff --git a/brain/api/v1/SettingsAPI.inc.php b/brain/api/v1/SettingsAPI.inc.php deleted file mode 100644 index 2474ff0..0000000 --- a/brain/api/v1/SettingsAPI.inc.php +++ /dev/null @@ -1,147 +0,0 @@ -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; - } -} diff --git a/brain/api/v1/SettingsAPI.php b/brain/api/v1/SettingsAPI.php new file mode 100644 index 0000000..e2e4c7c --- /dev/null +++ b/brain/api/v1/SettingsAPI.php @@ -0,0 +1,154 @@ +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; + } +} diff --git a/brain/controller/APIControl.inc.php b/brain/controller/APIControl.inc.php deleted file mode 100644 index 7ecbbee..0000000 --- a/brain/controller/APIControl.inc.php +++ /dev/null @@ -1,227 +0,0 @@ - "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"); - } -} diff --git a/brain/controller/APIControl.php b/brain/controller/APIControl.php new file mode 100644 index 0000000..819237a --- /dev/null +++ b/brain/controller/APIControl.php @@ -0,0 +1,232 @@ + "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"); + } +} diff --git a/brain/controller/DashControl.inc.php b/brain/controller/DashControl.php similarity index 97% rename from brain/controller/DashControl.inc.php rename to brain/controller/DashControl.php index b011507..64b0dd0 100644 --- a/brain/controller/DashControl.inc.php +++ b/brain/controller/DashControl.php @@ -1,9 +1,15 @@ getPages($currentPage, 4, $filter); $template = "dash/book.twig"; $pageOptions = [ + "title" => "Contents", "entryCount" => $data["entryCount"], "numOfPages" => $data["numOfPages"], "currentPage" => $currentPage, @@ -135,7 +142,7 @@ class DashControl "token" => Session::get("form_token"), "status" => Session::active(), "images" => $images, - "files"=>$files, + "files" => $files, "views" => $views, ]; break; diff --git a/brain/controller/IndexControl.inc.php b/brain/controller/IndexControl.inc.php deleted file mode 100644 index 615c4e6..0000000 --- a/brain/controller/IndexControl.inc.php +++ /dev/null @@ -1,107 +0,0 @@ -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; - } - } -} diff --git a/brain/controller/IndexControl.php b/brain/controller/IndexControl.php new file mode 100644 index 0000000..07fab53 --- /dev/null +++ b/brain/controller/IndexControl.php @@ -0,0 +1,113 @@ +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; + } + } +} diff --git a/brain/controller/RouteControl.inc.php b/brain/controller/RouteControl.inc.php deleted file mode 100644 index c54fc38..0000000 --- a/brain/controller/RouteControl.inc.php +++ /dev/null @@ -1,46 +0,0 @@ -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(); - } -} diff --git a/brain/data/Auth.php b/brain/data/Auth.php new file mode 100644 index 0000000..fa2444c --- /dev/null +++ b/brain/data/Auth.php @@ -0,0 +1,159 @@ +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(); + } +} diff --git a/brain/data/Book.inc.php b/brain/data/Book.php similarity index 85% rename from brain/data/Book.inc.php rename to brain/data/Book.php index b3a68ff..fb6f22e 100644 --- a/brain/data/Book.inc.php +++ b/brain/data/Book.php @@ -1,5 +1,11 @@ getContents(); if ($task == "delete") { - //$parsed = json_decode(file_get_contents("php://input"), true); - //$body = find($content, ["uuid" => $parsed["id"]]); + //$parsed = json_decode(file_get_contents("php://input"), true); + //$body = find($content, ["uuid" => $parsed["id"]]); $body = $request->getParsedBody(); } else { $body = $request->getParsedBody(); @@ -59,7 +65,7 @@ class Book if (isset($files["page_files"])) { $imageList = ""; $fileList = ""; - //var_dump($files["page_files"] ); + //var_dump($files["page_files"] ); foreach ($files["page_files"] as $file) { $type = $file->getClientMediaType(); switch ($type) { @@ -69,7 +75,7 @@ class Book case "image/svg": $imagesPath = "/assets/images/blog/" . $path . "/"; $imageList = - $imageList . $imagesPath . urlencode($file->getClientFileName()). ", "; + $imageList . $imagesPath . urlencode($file->getClientFileName()) . ", "; FileUploader::uploadFile( "../public/assets/images/blog/" . $path . "/", @@ -88,7 +94,7 @@ class Book break; case "audio/mpeg": $soundPath = "/assets/sound/blog/" . $path . "/"; - $fileList = $fileList . $soundPath . urlencode($file->getClientFileName()). ", "; + $fileList = $fileList . $soundPath . urlencode($file->getClientFileName()) . ", "; FileUploader::uploadFile( "../public/assets/sound/blog/" . $path . "/", @@ -99,7 +105,7 @@ class Book case 'text/plain': case 'text/rtf': $docPath = "/assets/docs/blog/" . $path . "/"; - $fileList = $fileList . $docPath . urlencode($file->getClientFileName()). ", "; + $fileList = $fileList . $docPath . urlencode($file->getClientFileName()) . ", "; FileUploader::uploadFile( "../public/assets/docs/blog/" . $path . "/", @@ -108,8 +114,8 @@ class Book break; } } - $page_feature = $imageList; - $page_files = $fileList; + $page_feature = $imageList; + $page_files = $fileList; } else { //if no files, just reset string from page object $page_feature = $page["feature"]; @@ -131,10 +137,10 @@ class Book : new \Moment\Moment(); $updated = new \Moment\Moment(); - //grab current index from settings and update + //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 + // now that variables are done, set to body object and then convert to markdown to save $body["id"] = $id; $body["uuid"] = $uuid; @@ -148,7 +154,7 @@ class Book $write = DocTools::objectToMD($body); - // if layout is index, change path to file + // if layout is index, change path to file if ($body["layout"] == "index") { $writePath = "../content/pages/start/index.md"; @@ -163,8 +169,9 @@ class Book $settings = $config->getSettings(); $message = ""; - if ($settings["global"]["renderOnSave"] == "true" && - $settings["global"]["dynamicRender"] == "false" + if ( + $settings["global"]["renderOnSave"] == "true" && + $settings["global"]["dynamicRender"] == "false" ) { $render = new Render(); $render->renderTags(); @@ -181,16 +188,16 @@ class Book "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); + //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 + //once saved, update menu $body["path"] = $path; Settings::updateMenu($body); Settings::updateTags(); - //if new page added, update current index in Settings file + //if new page added, update current index in Settings file if ($task == "create") { Settings::updateIndex(); } @@ -216,7 +223,7 @@ class Book return $item["deleted"] == true; }); - //$all = $content; + //$all = $content; $all = filter($content, function ($item) { return $item["deleted"] == false; }); @@ -248,7 +255,7 @@ class Book if (isset($filtered[$i + $range])) { array_push($folder, $filtered[$i + $range]); } else { - //chill out + //chill out } } } @@ -281,8 +288,8 @@ class Book } public function getContents() { - //test new contents data class - //$new = (new Contents("../content/pages"))->getAll(); + //test new contents data class + //$new = (new Contents("../content/pages"))->getAll(); $contents = (new Contents("../content/pages"))->getAll(); return $contents; } diff --git a/brain/data/Contents.inc.php b/brain/data/Contents.php similarity index 86% rename from brain/data/Contents.inc.php rename to brain/data/Contents.php index 977e8c9..27edc9d 100644 --- a/brain/data/Contents.inc.php +++ b/brain/data/Contents.php @@ -1,4 +1,7 @@ files[] = $folder . "/"; + //$this->files[] = $folder . "/"; $this->read($folder); } $files = array_filter(glob("$folder/*md"), "is_file"); @@ -35,45 +37,45 @@ class Contents } } - function getAll() + public function getAll() { $environment = new Environment($this->config); $environment->addExtension(new CommonMarkCoreExtension()); - // Add the extension + // Add the extension $environment->addExtension(new FrontMatterExtension()); - //Add Strikethrough rendering + //Add Strikethrough rendering $environment->addExtension(new StrikethroughExtension()); - //add attributes to elements in markdown + //add attributes to elements in markdown $environment->addExtension(new AttributesExtension()); - // Instantiate the converter engine and start converting some Markdown! + // 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 + //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 + //get raw markdown from file $frontMatterExtension = new FrontMatterExtension(); $parsed = $frontMatterExtension ->getFrontMatterParser() ->parse(file_get_contents($file)); - //never trust the front end. clean it up + //never trust the front end. clean it up $builder = new SanitizerBuilder(); $builder->registerExtension(new BasicExtension()); $builder->registerExtension(new IframeExtension()); - //relative-a and relative-image + //relative-a and relative-image $builder->registerExtension( new \HtmlSanitizer\Extension\Relative\A\AExtension() ); @@ -108,14 +110,14 @@ class Contents $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)]); + array_push($media, ["file" => $item, "type" => trim($ext)]); } } @@ -123,11 +125,11 @@ class Contents $item = trim($file); $ext = pathinfo($item, PATHINFO_EXTENSION); if ($item != null || $item != "") { - array_push($files, ["file"=>$item, "type"=>trim($ext)]); + array_push($files, ["file" => $item, "type" => trim($ext)]); } } - //sort attributes into page object + //sort attributes into page object $page = [ "id" => $meta["id"], "uuid" => $meta["uuid"], @@ -153,9 +155,9 @@ class Contents "content" => $parsed->getContent(), "html" => $scrubbed, "media" => $media, - "docs"=>$files + "docs" => $files ]; - //checks for duplicates + //checks for duplicates $uuid = $meta["uuid"]; $found = current( array_filter($contents, function ($item) use ($uuid) { @@ -163,9 +165,9 @@ class Contents }) ); - // if uuid is not present, add it + // if uuid is not present, add it if (!$found) { - array_push($contents, $page); + array_push($contents, $page); } } $contents = orderBy($contents, ["id"], ["desc"]); diff --git a/brain/data/Member.inc.php b/brain/data/Member.inc.php deleted file mode 100644 index b163366..0000000 --- a/brain/data/Member.inc.php +++ /dev/null @@ -1,55 +0,0 @@ -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); - } - } -} diff --git a/brain/data/Member.php b/brain/data/Member.php new file mode 100644 index 0000000..00e342f --- /dev/null +++ b/brain/data/Member.php @@ -0,0 +1,62 @@ +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); + } + } +} diff --git a/brain/data/Render.inc.php b/brain/data/Render.inc.php deleted file mode 100644 index e618e4f..0000000 --- a/brain/data/Render.inc.php +++ /dev/null @@ -1,181 +0,0 @@ -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 - //TODO: change to just grab directory contents for scripts and css - 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); - } -} diff --git a/brain/data/Render.php b/brain/data/Render.php new file mode 100644 index 0000000..9fecabe --- /dev/null +++ b/brain/data/Render.php @@ -0,0 +1,206 @@ +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); + } +} diff --git a/brain/data/Session.inc.php b/brain/data/Session.inc.php deleted file mode 100644 index f5063c9..0000000 --- a/brain/data/Session.inc.php +++ /dev/null @@ -1,90 +0,0 @@ - "", - "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); - } -} diff --git a/brain/data/Session.php b/brain/data/Session.php new file mode 100644 index 0000000..b4a0561 --- /dev/null +++ b/brain/data/Session.php @@ -0,0 +1,94 @@ + "", + "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); + } +} diff --git a/brain/data/Settings.inc.php b/brain/data/Settings.inc.php deleted file mode 100644 index ff25452..0000000 --- a/brain/data/Settings.inc.php +++ /dev/null @@ -1,169 +0,0 @@ -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); - } -} diff --git a/brain/data/Settings.php b/brain/data/Settings.php new file mode 100644 index 0000000..71b3c21 --- /dev/null +++ b/brain/data/Settings.php @@ -0,0 +1,177 @@ +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); + } +} diff --git a/brain/data/Themes.inc.php b/brain/data/Themes.inc.php deleted file mode 100644 index 6ad02fb..0000000 --- a/brain/data/Themes.inc.php +++ /dev/null @@ -1,60 +0,0 @@ -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; - } -} diff --git a/brain/data/Themes.php b/brain/data/Themes.php new file mode 100644 index 0000000..3c15bf4 --- /dev/null +++ b/brain/data/Themes.php @@ -0,0 +1,64 @@ +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; + } +} diff --git a/brain/init/App.php b/brain/init/App.php new file mode 100644 index 0000000..7c8cb5e --- /dev/null +++ b/brain/init/App.php @@ -0,0 +1,36 @@ +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(); + } +} diff --git a/brain/utility/DocTools.inc.php b/brain/utility/DocTools.php similarity index 97% rename from brain/utility/DocTools.inc.php rename to brain/utility/DocTools.php index 0af7a4c..d29c0db 100644 --- a/brain/utility/DocTools.inc.php +++ b/brain/utility/DocTools.php @@ -1,5 +1,7 @@ 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"); - } - } -} diff --git a/brain/utility/FileUploader.php b/brain/utility/FileUploader.php new file mode 100644 index 0000000..befb992 --- /dev/null +++ b/brain/utility/FileUploader.php @@ -0,0 +1,35 @@ +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"); + } + } +} diff --git a/brain/utility/HandleCors.inc.php b/brain/utility/HandleCors.php similarity index 97% rename from brain/utility/HandleCors.inc.php rename to brain/utility/HandleCors.php index 86fa7b0..7082fdd 100644 --- a/brain/utility/HandleCors.inc.php +++ b/brain/utility/HandleCors.php @@ -1,6 +1,10 @@ getSettings(); - $mailConfig = $settings["email"]; - $mail = new PHPMailer(); - - switch ($body["mail_task"]) { - case "TESTING": - $html = - "

Hi! It's Fipamo!


" . - "It's just a test
" . - $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 = - "

Hi! It's Fipamo!


" . - "This is your secret key.

" . - "

" . - $body["secret"] . - "

" . - "
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; - } -} \ No newline at end of file diff --git a/brain/utility/Mailer.php b/brain/utility/Mailer.php new file mode 100644 index 0000000..e1b15f2 --- /dev/null +++ b/brain/utility/Mailer.php @@ -0,0 +1,97 @@ +getSettings(); + $mailConfig = $settings["email"]; + $mail = new PHPMailer(); + + switch ($body["mail_task"]) { + case "TESTING": + $html = + "

Hi! It's Fipamo!


" . + "It's just a test
" . + $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 = + "

Hi! It's Fipamo!


" . + "This is your secret key.

" . + "

" . + $body["secret"] . + "

" . + "
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; + } +} diff --git a/brain/utility/Maintenance.inc.php b/brain/utility/Maintenance.inc.php deleted file mode 100644 index 2697e3e..0000000 --- a/brain/utility/Maintenance.inc.php +++ /dev/null @@ -1,99 +0,0 @@ -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; - } -} diff --git a/brain/utility/Maintenance.php b/brain/utility/Maintenance.php new file mode 100644 index 0000000..a7a6865 --- /dev/null +++ b/brain/utility/Maintenance.php @@ -0,0 +1,104 @@ +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; + } +} diff --git a/brain/utility/Setup.inc.php b/brain/utility/Setup.inc.php deleted file mode 100644 index 5f09f47..0000000 --- a/brain/utility/Setup.inc.php +++ /dev/null @@ -1,223 +0,0 @@ -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; - } -} diff --git a/brain/utility/Setup.php b/brain/utility/Setup.php new file mode 100644 index 0000000..9d4cf1a --- /dev/null +++ b/brain/utility/Setup.php @@ -0,0 +1,227 @@ +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; + } +} diff --git a/brain/utility/Sorting.inc.php b/brain/utility/Sorting.inc.php deleted file mode 100644 index 70ee2a1..0000000 --- a/brain/utility/Sorting.inc.php +++ /dev/null @@ -1,238 +0,0 @@ -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; - } -} diff --git a/brain/utility/Sorting.php b/brain/utility/Sorting.php new file mode 100644 index 0000000..15f2800 --- /dev/null +++ b/brain/utility/Sorting.php @@ -0,0 +1,248 @@ +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; + } +} diff --git a/brain/utility/StringTools.inc.php b/brain/utility/StringTools.inc.php deleted file mode 100644 index 2c16ae7..0000000 --- a/brain/utility/StringTools.inc.php +++ /dev/null @@ -1,130 +0,0 @@ -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; - } -} diff --git a/brain/utility/StringTools.php b/brain/utility/StringTools.php new file mode 100644 index 0000000..f39ae12 --- /dev/null +++ b/brain/utility/StringTools.php @@ -0,0 +1,132 @@ +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; + } +} diff --git a/brain/views/dash/book.twig b/brain/views/dash/book.twig index b13c883..813b291 100644 --- a/brain/views/dash/book.twig +++ b/brain/views/dash/book.twig @@ -62,10 +62,9 @@ - {% else %} -
+
diff --git a/brain/views/dash/start.twig b/brain/views/dash/start.twig index 059dd2e..aff4004 100644 --- a/brain/views/dash/start.twig +++ b/brain/views/dash/start.twig @@ -5,7 +5,7 @@ {% endblock %} {% block stylesheets %} - + {% endblock %} {% block mainContent %} diff --git a/composer.json b/composer.json index 25e5c5d..1881c97 100644 --- a/composer.json +++ b/composer.json @@ -9,6 +9,11 @@ "homepage": "https://roiskinda.cool" } ], + "autoload": { + "psr-4": { + "brain\\":"brain" + } + }, "support": { "source": "https://code.playvicio.us/Are0h/Fipamo", "wiki": "https://code.playvicio.us/Are0h/Fipamo/wiki/_pages", diff --git a/content/themes/fipamo-default/archive.twig b/content/themes/fipamo-default/archive.twig index 45ff5c1..681596e 100644 --- a/content/themes/fipamo-default/archive.twig +++ b/content/themes/fipamo-default/archive.twig @@ -1,4 +1,4 @@ -{% extends "fipamo-default/frame.twig" %} +{% extends "frame.twig" %} {% block title %} {{ title }} diff --git a/content/themes/fipamo-default/assets/css/base.css b/content/themes/fipamo-default/assets/css/base.css index a1a08e0..ff391d5 100644 --- a/content/themes/fipamo-default/assets/css/base.css +++ b/content/themes/fipamo-default/assets/css/base.css @@ -1,31 +1,32 @@ -/** -------------------------------- --- Typography -------------------------------- -**/ -/** -------------------------------- --- Colors -------------------------------- -**/ -/** -------------------------------- --- Mixins -------------------------------- -**/ -/** -------------------------------- --- Normalize -------------------------------- -**/ +h1, h2, h3 { + color: #ebe5d4; +} + +h1 { + font-size: 2em; + font-weight: 400; +} + +h2 { + font-size: 1.75em; + font-weight: 400; +} + +h3 { + font-size: 1.5em; + font-weight: 300; +} + html { line-height: 1.15; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; } + body { margin: 0; } + article, aside, footer, @@ -34,62 +35,75 @@ nav, section { display: block; } + h1 { font-size: 2em; margin: 0.67em 0; line-height: 1em; } + figcaption, figure, main { display: block; } + figure { margin: 1em 40px; } + hr { box-sizing: content-box; height: 0; overflow: visible; } + pre { font-family: monospace, monospace; font-size: 1em; } + a { background-color: transparent; -webkit-text-decoration-skip: objects; } + a:active, a:hover { outline-width: 0; } + abbr[title] { border-bottom: none; text-decoration: underline; text-decoration: underline dotted; } + b, strong { font-weight: inherit; font-weight: bolder; } -code, + kbd, samp { font-family: monospace, monospace; font-size: 1em; } + dfn { font-style: italic; } + mark { background-color: #ff0; color: #000; } + small { font-size: 80%; } + sub, sup { font-size: 60%; @@ -97,31 +111,38 @@ sup { position: relative; vertical-align: baseline; } + sub { bottom: -0.25em; } + sup { top: -0.55em; - background: #bdcbdb; + background: #151d26; color: #151d26; border-radius: 2px; padding: 0 2px 0 2px; margin: 0 2px 0 0; } + audio, video { display: inline-block; } + audio:not([controls]) { display: none; height: 0; } + img { border-style: none; } + svg:not(:root) { overflow: hidden; } + button, input, optgroup, @@ -132,38 +153,44 @@ textarea { line-height: 1.15; margin: 0; } + button, input { overflow: visible; } + button, select { text-transform: none; } -button, -html [type="button"], -[type="reset"], -[type="submit"] { + +button, html [type=button], +[type=reset], +[type=submit] { -webkit-appearance: button; } -[type="button"]::-moz-focus-inner, -[type="reset"]::-moz-focus-inner, -[type="submit"]::-moz-focus-inner, + +[type=button]::-moz-focus-inner, +[type=reset]::-moz-focus-inner, +[type=submit]::-moz-focus-inner, button::-moz-focus-inner { border-style: none; padding: 0; } -[type="button"]:-moz-focusring, -[type="reset"]:-moz-focusring, -[type="submit"]:-moz-focusring, + +[type=button]:-moz-focusring, +[type=reset]:-moz-focusring, +[type=submit]:-moz-focusring, button:-moz-focusring { outline: 1px dotted ButtonText; } + fieldset { border: 1px solid #c0c0c0; margin: 0 2px; padding: 0.35em 0.625em 0.75em; } + legend { box-sizing: border-box; color: inherit; @@ -172,55 +199,143 @@ legend { padding: 0; white-space: normal; } + progress { display: inline-block; vertical-align: baseline; } + textarea { overflow: auto; } -[type="checkbox"], -[type="radio"] { + +[type=checkbox], +[type=radio] { box-sizing: border-box; padding: 0; } -[type="number"]::-webkit-inner-spin-button, -[type="number"]::-webkit-outer-spin-button { + +[type=number]::-webkit-inner-spin-button, +[type=number]::-webkit-outer-spin-button { height: auto; } -[type="search"] { + +[type=search] { -webkit-appearance: textfield; outline-offset: -2px; } -[type="search"]::-webkit-search-cancel-button, -[type="search"]::-webkit-search-decoration { + +[type=search]::-webkit-search-cancel-button, +[type=search]::-webkit-search-decoration { -webkit-appearance: none; } + ::-webkit-file-upload-button { -webkit-appearance: button; font: inherit; } + details, menu { display: block; } + summary { display: list-item; } + canvas { display: inline-block; } + template { display: none; } + [hidden] { display: none; } -/** -------------------------------- --- Main Structure -------------------------------- -**/ + +form { + display: inline-block; +} +form a { + color: #151d26; +} +form p { + background: #e8c33e; + color: #151d26; + padding: 5px; + display: block; + border-radius: 5px; + text-align: left; +} + +input[type=email], input[type=password], input[type=text] { + border: 0; + border-radius: 5px; + padding: 5px; + margin: 10px 5px 0 0; + font: 18px Helvetica, Arial, sans-serif; + display: inline-block; + background: #151d26; + color: #e8c33e; +} + +textarea { + border: 0; + border-radius: 3px; + color: #ebe5d4; + font: 15px Helvetica, Arial, sans-serif; + background: #151d26; +} + +button, input[type=submit] { + background: #7ED07E; + color: #151d26; + font: 20px Helvetica, Arial, sans-serif; + border-radius: 5px; + position: relative; + cursor: pointer; + border: 0; + padding: 10px 0 5px 0; + -moz-transition: all 0.3s linear; + -webkit-transition: all 0.3s linear; + -o-transition: all 0.3s linear; + transition: all 0.3s linear; +} + +select { + font: 14px Helvetica, Arial, sans-serif; + border: 1px solid #FC6399; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + color: #151d26; +} + +::-webkit-input-placeholder { + font: 25px Helvetica, Arial, sans-serif; + color: #ebe5d4; +} + +:-moz-placeholder { + /* Firefox 18- */ + font: 25px Helvetica, Arial, sans-serif; + color: #ebe5d4; +} + +::-moz-placeholder { + /* Firefox 19+ */ + font: 15px Helvetica, Arial, sans-serif; + color: #ebe5d4; +} + +:-ms-input-placeholder { + font: 25px Helvetica, Arial, sans-serif; + color: #ebe5d4; +} + html { margin: 0; padding: 0; @@ -229,6 +344,7 @@ html { overflow: hidden; font: 400 1.2em/1.4em Helvetica, Arial, sans-serif; } + body { background: #ebe5d4; margin: 0; @@ -240,51 +356,79 @@ body { overflow-y: scroll; overflow-x: hidden; } + a { color: #151d26; text-decoration: none; - border-bottom: 1px solid #7ed07e; - -moz-transition: all 0.2s linear; - -webkit-transition: all 0.2s linear; - -o-transition: all 0.2s linear; - transition: all 0.2s linear; + border-bottom: 1px solid #7ED07E; } a:hover { - border-bottom: 1px solid #fc6399; + border-bottom: 1px solid #FC6399; } + code { background: #32302f; - color: #7ed07e; + color: #7ED07E; border-radius: 3px; padding: 3px; } + pre { background: #32302f; - color: #7ed07e; + color: #7ED07E; border-radius: 3px; padding: 3px; } -pre code { - color: #fc6399; + +code { + color: #FC6399; background: none; } + svg.icons { width: 25px; fill: #ebe5d4; } + header { background: #151d26; height: 90%; width: 100%; border-top: #ebe5d4 3px solid; } +header #media { + width: 100%; + height: 90%; + position: absolute; +} +header #media .slide { + -moz-transition: all 0.7s linear; + -webkit-transition: all 0.7s linear; + -o-transition: all 0.7s linear; + transition: all 0.7s linear; + width: 100%; + height: 100%; + position: absolute; +} +header #media .hide { + opacity: 0; +} +header #media .show { + opacity: 1; +} +header #media video { + width: 100%; + height: 100%; + object-fit: cover; +} header nav { width: 97%; margin: 10px auto; + z-index: 1000; + position: relative; color: #151d26; } -header nav .left, -header nav .right { +header nav .left, header nav .right { width: 50%; display: inline-block; vertical-align: top; @@ -302,7 +446,7 @@ header nav .right { text-align: right; } header nav .right a.menu-link { - background: #fc6399; + background: #FC6399; margin-bottom: 4px; padding: 3px; border-radius: 2px; @@ -311,8 +455,9 @@ header nav .right a.menu-link { border-bottom: none; } header nav .right a.menu-link:hover { - background: #feb1cc; + background: #FC6399; } + .container { z-index: 2; background: #ebe5d4; @@ -331,57 +476,47 @@ header nav .right a.menu-link:hover { color: #32302f; margin: 0 auto; } -.container article .index, -.container article .page { +.container article .index, .container article .page { padding: 0 0 15px 0; } -.container article .index img, -.container article .page img { +.container article .index img, .container article .page img { display: block; width: 100%; } -.container article .index h1, -.container article .page h1 { +.container article .index h1, .container article .page h1 { color: #151d26; } -.container article .index p, -.container article .page p { +.container article .index p, .container article .page p { font: 300 1.25em/1.6em Helvetica, Arial, sans-serif; } -.container article .index .meta, -.container article .page .meta { +.container article .index .meta, .container article .page .meta { font: 500 0.8em/1.3em Helvetica, Arial, sans-serif; padding: 5px 0 0 0; border-top: 1px solid #151d26; - background: #ede8d8; + background: #ebe5d4; } -.container article .index .meta a, -.container article .page .meta a { +.container article .index .meta a, .container article .page .meta a { font-size: 0.8em; font-weight: 400; } -.container article .index .archive-item, -.container article .page .archive-item { +.container article .index .archive-item, .container article .page .archive-item { padding: 15px 0 20px 0; } -.container article .index .archive-item span.year, -.container article .page .archive-item span.year { +.container article .index .archive-item span.year, .container article .page .archive-item span.year { font-size: 1.5em; font-weight: 500; padding: 5px; display: block; color: #151d26; } -.container article .index .archive-item .archive-month, -.container article .page .archive-item .archive-month { +.container article .index .archive-item .archive-month, .container article .page .archive-item .archive-month { display: inline-block; vertical-align: top; width: 30%; padding: 5px; } -.container article .index .archive-item .archive-month span.month, -.container article .page .archive-item .archive-month span.month { - color: #fc6399; +.container article .index .archive-item .archive-month span.month, .container article .page .archive-item .archive-month span.month { + color: #FC6399; font-size: 1.5em; font-weight: 300; padding: 5px; @@ -394,35 +529,31 @@ header nav .right a.menu-link:hover { .container section a { color: #ebe5d4; } -.container section .index-lists, -.container section .page-title { +.container section .index-lists, .container section .page-title { max-width: 840px; width: 80%; margin: 0 auto; padding: 20px 0 0 0; } -.container section .index-lists span, -.container section .page-title span { - font: 600 2em/1.5 Helvetica, Arial, sans-serif; - color: #ebe5d4; +.container section .index-lists span, .container section .page-title span { + font-size: 2em; + color: #FC6399; + font-weight: 400; } -.container section .index-lists .recent, -.container section .page-title .recent, -.container section .index-lists .featured, -.container section .page-title .featured { +.container section .index-lists .recent, .container section .index-lists .featured, .container section .page-title .recent, .container section .page-title .featured { display: inline-block; width: 50%; vertical-align: top; } -.container section .index-lists label, -.container section .page-title label { +.container section .index-lists label, .container section .page-title label { background: #32302f; color: #ebe5d4; font-size: 1.5em; line-height: 1.3; } + footer { - background: #e4dcc5; + background: #ebe5d4; padding: 10px; color: #151d26; font-size: 0.8em; @@ -435,121 +566,44 @@ footer .inner { max-width: 840px; } footer .inner a { - color: #fc6399; -} -@media only screen and (max-width: 640px) { - header nav { - width: 98%; - } - header span { - font-size: 2.5em; - } - .container article .index .archive-item .archive-month, - .container article .page .archive-item .archive-month { - width: 45%; - } -} -@media only screen and (max-width: 480px) { - header nav { - width: 96%; - } - .container article .index, - .container article .page { - margin: 0; - } - .container article .index p, - .container article .page p { - font: 300 1em/1.6em Helvetica, Arial, sans-serif; - } - .container section .index-lists .recent, - .container section .index-lists .featured { - width: 100% !important; - } -} -@media only screen and (max-width: 375px) { - header nav { - width: 95%; - } - .container article .index, - .container article .page { - margin: 0; - } - .container article .index p, - .container article .page p { - font: 300 0.9em/1.7em Helvetica, Arial, sans-serif; - } - .container article .index .archive-item .archive-month, - .container article .page .archive-item .archive-month { - width: 95%; - } -} -/** -------------------------------- --- Forms -------------------------------- -**/ -form { - display: inline-block; + color: #FC6399; } -input[type=email], -input[type=password], -input[type=text] { - border: 0; - border-radius: 5px; - padding: 5px; - margin: 10px 5px 0 0; - font: 15px 'RobotoMono'; - display: inline-block; + +header nav { + width: 98%; } -textarea { - border: 0; - border-radius: 3px; - color: $type02; - font: 15px 'RobotoMono'; +header span { + font-size: 2.5em; } -button, -input[type=submit] { - background: #fc6399; - color: #ebe5d4; - font: 14px Helvetica, Arial, sans-serif; - border-radius: 5px; - position: relative; - cursor: pointer; - border: 0; - padding: 5px 5px 0 5px; - -moz-transition: all 0.3s linear; - -webkit-transition: all 0.3s linear; - -o-transition: all 0.3s linear; - transition: all 0.3s linear; +header .container article .index .archive-item .archive-month, header .container article .page .archive-item .archive-month { + width: 45%; } -button:hover, -input[type=submit]:hover { - background: #fc7ca9; + +header nav { + width: 96%; } -select { - font: 14px 'RobotoMono'; - border: 1px solid #fc6399; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - color: #151d26; +header .container article .index, header .container article .page { + margin: 0; } -::-webkit-input-placeholder { - font: 14px 'RobotoMono'; - color: #837e7c; +header .container article .index p, header .container article .page p { + font: 300 1em/1.6em Helvetica, Arial, sans-serif; } -:-moz-placeholder { -/* Firefox 18- */ - font: 14px 'RobotoMono'; - color: #837e7c; +header .container section .index-lists .recent, header .container section .index-lists .featured { + width: 100% !important; } -::-moz-placeholder { -/* Firefox 19+ */ - font: 14px 'RobotoMono'; - color: #837e7c; + +header nav { + width: 95%; } -:-ms-input-placeholder { - font: 14px 'RobotoMono'; - color: #837e7c; + +.container article .index, .container article .page { + margin: 0; +} +.container article .index p, .container article .page p { + font: 300 0.9em/1.7em Helvetica, Arial, sans-serif; +} +.container article .index .archive-item .archive-month, .container article .page .archive-item .archive-month { + width: 95%; } -/*# sourceMappingURL=base.css.map */ \ No newline at end of file + +/*# sourceMappingURL=base.css.map */ diff --git a/content/themes/fipamo-default/assets/css/base.css.map b/content/themes/fipamo-default/assets/css/base.css.map index d9e5fd2..fb355de 100644 --- a/content/themes/fipamo-default/assets/css/base.css.map +++ b/content/themes/fipamo-default/assets/css/base.css.map @@ -1 +1 @@ -{"version":3,"sources":["../../../styles/base.styl","../../../styles/_normalize.styl","../../../styles/_structure.styl","../../../styles/_mixins.styl","../../../styles/_forms.styl"],"names":[],"mappings":"AACA;;;;;AAQA;;;;;AAQA;;;;;AAQA;;;;;ACzBA;EACI,aAAY,KAAZ;EACA,sBAAqB,KAArB;EACA,0BAAyB,KAAzB;;AAEJ;EACI,QAAO,EAAP;;AAEJ;AACA;AACA;AACA;AACA;AACA;EACI,SAAQ,MAAR;;AAEJ;EACI,WAAU,IAAV;EACA,QAAO,SAAP;EACA,aAAY,IAAZ;;AAEJ;AACA;AACA;EACI,SAAQ,MAAR;;AAEJ;EACI,QAAO,SAAP;;AAEJ;EACI,YAAW,YAAX;EACA,QAAO,EAAP;EACA,UAAS,QAAT;;AAEJ;EACI,aAAqB,qBAArB;EACA,WAAU,IAAV;;AACJ;EACI,kBAAiB,YAAjB;EACA,8BAA6B,QAA7B;;AAEJ;AACA;EACI,eAAc,EAAd;;AAEJ;EACI,eAAc,KAAd;EACA,iBAAgB,UAAhB;EACA,iBAAgB,iBAAhB;;AAEJ;AACA;EACI,aAAY,QAAZ;EACA,aAAY,OAAZ;;AAEJ;AACA;AACA;EACI,aAAqB,qBAArB;EACA,WAAU,IAAV;;AAEJ;EACI,YAAW,OAAX;;AAEJ;EACI,kBAAiB,KAAjB;EACA,OAAM,KAAN;;AAEJ;EACI,WAAU,IAAV;;AAEJ;AACA;EACI,WAAU,IAAV;EACA,aAAY,EAAZ;EACA,UAAS,SAAT;EACA,gBAAe,SAAf;;AAEJ;EACI,QAAO,QAAP;;AAEJ;EACI,KAAI,QAAJ;EACA,YAAW,QAAX;EACA,OAAM,QAAN;EACA,eAAe,IAAf;EACA,SAAQ,YAAR;EACA,QAAQ,UAAR;;AAEJ;AACA;EACI,SAAQ,aAAR;;AAGA;EACI,SAAQ,KAAR;EACA,QAAO,EAAP;;AAER;EACI,cAAa,KAAb;;AAGA;EACI,UAAS,OAAT;;AAER;AACA;AACA;AACA;AACA;EACI,aAAY,WAAZ;EACA,WAAU,KAAV;EACA,aAAY,KAAZ;EACA,QAAO,EAAP;;AAEJ;AACA;EACI,UAAS,QAAT;;AAEJ;AACA;EACI,gBAAe,KAAf;;AAEJ;AAAQ;AACR;AACA;EACI,oBAAmB,OAAnB;;AAEJ;AACA;AACA;AACA;EACI,cAAa,KAAb;EACA,SAAQ,EAAR;;AAEJ;AACA;AACA;AACA;EACI,SAAQ,sBAAR;;AAEJ;EACI,QAAO,kBAAP;EACA,QAAO,MAAP;EACA,SAAQ,sBAAR;;AAEJ;EACI,YAAW,WAAX;EACA,OAAM,QAAN;EACA,SAAQ,MAAR;EACA,WAAU,KAAV;EACA,SAAQ,EAAR;EACA,aAAY,OAAZ;;AAEJ;EACI,SAAQ,aAAR;EACA,gBAAe,SAAf;;AAEJ;EACI,UAAS,KAAT;;AAEJ;AACA;EACI,YAAW,WAAX;EACA,SAAQ,EAAR;;AAEJ;AACA;EACI,QAAO,KAAP;;AAEJ;EACI,oBAAmB,UAAnB;EACA,gBAAe,KAAf;;AAEJ;AACA;EACI,oBAAmB,KAAnB;;AAEJ;EACI,oBAAmB,OAAnB;EACA,MAAK,QAAL;;AAEJ;AACA;EACI,SAAQ,MAAR;;AAEJ;EACI,SAAQ,UAAR;;AAEJ;EACI,SAAQ,aAAR;;AAEJ;EACI,SAAQ,KAAR;;AAEJ;EACI,SAAQ,KAAR;;ADpKJ;;;;;AEhCA;EACI,QAAO,EAAP;EACA,SAAQ,EAAR;EACA,OAAM,KAAN;EACA,QAAO,KAAP;EACA,UAAS,OAAT;EACA,MAAK,6CAAL;;AAEJ;EACI,YAAW,QAAX;EACA,QAAO,EAAP;EACA,SAAQ,EAAR;EACA,aAAY,IAAZ;EACA,iBAAgB,YAAhB;EACA,QAAO,KAAP;EACA,OAAM,KAAN;EACA,YAAW,OAAX;EACA,YAAW,OAAX;;AAEJ;EACE,OAAM,QAAN;EACA,iBAAgB,KAAhB;EACA,eAAc,kBAAd;ECjBD,iBAAgB,gBAAhB;EACA,oBAAmB,gBAAnB;EACA,eAAc,gBAAd;EACA,YAAW,gBAAX;;ADgBC;EACE,eAAc,kBAAd;;AAEJ;EACE,YAAW,QAAX;EACA,OAAM,QAAN;EACA,eAAc,IAAd;EACA,SAAQ,IAAR;;AAEF;EACE,YAAW,QAAX;EACA,OAAM,QAAN;EACA,eAAc,IAAd;EACA,SAAQ,IAAR;;AACA;EACE,OAAM,QAAN;EACA,YAAW,KAAX;;AAEJ;EACE,OAAM,KAAN;EACA,MAAK,QAAL;;AAEF;EACE,YAAW,QAAX;EACA,QAAO,IAAP;EACA,OAAM,KAAN;EACA,YAAW,kBAAX;;AACA;EACE,OAAM,IAAN;EACA,QAAO,UAAP;EACA,OAAM,QAAN;;AACA;AAAM;EACJ,OAAM,IAAN;EACA,SAAQ,aAAR;EACA,gBAAe,IAAf;;AAEA;EACE,eAAc,KAAd;EACA,QAAO,WAAP;EACA,SAAQ,MAAR;;AACA;EACE,OAAM,KAAN;EACA,eAAc,KAAd;;AACN;EACE,YAAW,MAAX;;AACA;EACE,YAAW,QAAX;EACA,eAAc,IAAd;EACA,SAAQ,IAAR;EACA,eAAc,IAAd;EACA,SAAQ,aAAR;EACA,WAAU,MAAV;EACA,eAAc,KAAd;;AACA;EACE,YAAwB,QAAxB;;AAIV;EACI,SAAQ,EAAR;EACA,YAAW,QAAX;EACA,aAAY,KAAZ;EACA,aAAY,QAAZ;EACA,OAAM,KAAN;EAEA,OAAM,QAAN;;AACA;EACE,UAAS,SAAT;EACA,OAAO,IAAP;EACA,QAAO,IAAP;EACA,WAAU,MAAV;EAEA,YAAW,QAAX;EACA,gBAAe,IAAf;EACA,OAAM,QAAN;EACA,QAAO,OAAP;;AAGA;AAAQ;EACN,SAAQ,WAAR;;AACA;;EACE,SAAQ,MAAR;EACA,OAAM,KAAN;;AACF;;EACE,OAAM,QAAN;;AACF;;EACE,MAAK,8CAAL;;AAEF;;EACI,MAAK,6CAAL;EACA,SAAQ,UAAR;EACA,YAAW,kBAAX;EACA,YAAoB,QAApB;;AACA;;EACE,WAAW,MAAX;EACA,aAAY,IAAZ;;AAEN;;EACE,SAAQ,cAAR;;AACA;;EACE,WAAU,MAAV;EACA,aAAY,IAAZ;EACA,SAAQ,IAAR;EACA,SAAQ,MAAR;EACA,OAAM,QAAN;;AACF;;EACE,SAAQ,aAAR;EACA,gBAAe,IAAf;EACA,OAAM,IAAN;EACA,SAAQ,IAAR;;AACA;;EACE,OAAM,QAAN;EACA,WAAU,MAAV;EACA,aAAY,IAAZ;EACA,SAAQ,IAAR;EACA,SAAQ,MAAR;;AACV;EACE,SAAQ,WAAR;EACA,YAAW,QAAX;;AACA;EACE,OAAM,QAAN;;AACF;AAAc;EACZ,WAAU,MAAV;EAGA,OAAM,IAAN;EACA,QAAO,OAAP;EACA,SAAQ,WAAR;;AAJA;;ECrIP,MAAM,yCAAN;EACA,OAAO,QAAP;;ADyIO;AAAS;;;EACP,SAAQ,aAAR;EACA,OAAM,IAAN;EACA,gBAAe,IAAf;;AACF;;EACE,YAAW,QAAX;EACA,OAAM,QAAN;EACA,WAAU,MAAV;EACA,aAAY,IAAZ;;AAKR;EACE,YAAoB,QAApB;EACA,SAAQ,KAAR;EACA,OAAM,QAAN;EACA,WAAU,MAAV;EACA,aAAY,IAAZ;EACA,QAAO,MAAP;;AACA;EACE,QAAO,UAAP;EACA,OAAM,IAAN;EACA,WAAU,MAAV;;AACA;EACE,OAAM,QAAN;;AASgC;AAEpC;IACI,OAAM,IAAN;;AACJ;IACE,WAAU,MAAV;;AAKI;;IACE,OAAM,IAAN;;;AAE4B;AAEpC;IACI,OAAM,IAAN;;AAGF;AAAQ;IACN,QAAO,EAAP;;AACA;;IACE,MAAK,2CAAL;;AAGF;AAAS;IACP,OAAM,gBAAN;;;AAG8B;AAElC;IACE,OAAM,IAAN;;AAGA;AAAQ;IACN,QAAO,EAAP;;AACA;;IACE,MAAK,6CAAL;;AAEA;;IACE,OAAM,IAAN;;;AF3Ld;;;;;AIxCA;EACI,SAAQ,aAAR;;AAEJ;AAAmB;AAAsB;EACrC,QAAO,EAAP;EACA,eAAc,IAAd;EACA,SAAQ,IAAR;EACA,QAAO,aAAP;EACA,MAAK,kBAAL;EACA,SAAQ,aAAR;;AAEJ;EACI,QAAO,EAAP;EACA,eAAc,IAAd;EACA,OAAM,QAAN;EACA,MAAK,kBAAL;;AAEJ;AAAQ;EACJ,YAAW,QAAX;EACA,OAAM,QAAN;EACA,MAAK,kCAAL;EACA,eAAc,IAAd;EACA,UAAS,SAAT;EACA,QAAO,QAAP;EACA,QAAO,EAAP;EACA,SAAQ,cAAR;EDpBH,iBAAgB,gBAAhB;EACA,oBAAmB,gBAAnB;EACA,eAAc,gBAAd;EACA,YAAW,gBAAX;;ACmBG;;EACI,YAAW,QAAX;;AAER;EACI,MAAK,kBAAL;EACA,QAAO,kBAAP;EACA,oBAAmB,KAAnB;EACA,iBAAgB,KAAhB;EACA,YAAW,KAAX;EAEA,OAAM,QAAN;;AAEJ;EACI,MAAK,kBAAL;EACA,OAAM,QAAN;;AAEJ;AACI;EACA,MAAK,kBAAL;EACA,OAAM,QAAN;;AAEJ;AACI;EACA,MAAK,kBAAL;EACA,OAAM,QAAN;;AAEJ;EACI,MAAK,kBAAL;EACA,OAAM,QAAN","file":"base.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../../../styles/_typography.sass","../../../styles/_normalize.sass","../../../styles/_colors.sass","../../../styles/_forms.sass","../../../styles/_mixins.sass","../../../styles/_structure.sass"],"names":[],"mappings":"AAGA;EACI;;;AAEJ;EACI;EACA;;;AAEJ;EACI;EACA;;;AAEJ;EACI;EACA;;;AChBJ;EACI;EACA;EACA;;;AAEJ;EACI;;;AAEJ;AAAA;AAAA;AAAA;AAAA;AAAA;EAMI;;;AAEJ;EACI;EACA;EACA;;;AAEJ;AAAA;AAAA;EAGI;;;AAEJ;EACI;;;AAEJ;EACI;EACA;EACA;;;AAEJ;EACI;EACA;;;AACJ;EACI;EACA;;;AAEJ;AAAA;EAEI;;;AAEJ;EACI;EACA;EACA;;;AAEJ;AAAA;EAEI;EACA;;;AAGJ;AAAA;EAEI;EACA;;;AAEJ;EACI;;;AAEJ;EACI;EACA;;;AAEJ;EACI;;;AAEJ;AAAA;EAEI;EACA;EACA;EACA;;;AAEJ;EACI;;;AAEJ;EACI;EACA,YCnFM;EDoFN,OCpFM;EDqFN;EACA;EACA;;;AAEJ;AAAA;EAEI;;;AAGA;EACI;EACA;;;AAER;EACI;;;AAGA;EACI;;;AAER;AAAA;AAAA;AAAA;AAAA;EAKI;EACA;EACA;EACA;;;AAEJ;AAAA;EAEI;;;AAEJ;AAAA;EAEI;;;AAEJ;AAAA;AAAA;EAGI;;;AAEJ;AAAA;AAAA;AAAA;EAII;EACA;;;AAEJ;AAAA;AAAA;AAAA;EAII;;;AAEJ;EACI;EACA;EACA;;;AAEJ;EACI;EACA;EACA;EACA;EACA;EACA;;;AAEJ;EACI;EACA;;;AAEJ;EACI;;;AAEJ;AAAA;EAEI;EACA;;;AAEJ;AAAA;EAEI;;;AAEJ;EACI;EACA;;;AAEJ;AAAA;EAEI;;;AAEJ;EACI;EACA;;;AAEJ;AAAA;EAEI;;;AAEJ;EACI;;;AAEJ;EACI;;;AAEJ;EACI;;;AAEJ;EACI;;;AEpMJ;EACI;;AACA;EACI,ODHE;;ACIN;EACI,YDHI;ECIJ,ODNE;ECOF;EACA;EACA;EACA;;;AAER;EACI;EACA;EACA;EACA;EACA;EACA;EACA,YDnBM;ECoBN,ODlBQ;;;ACoBZ;EACI;EACA;EACA,ODrBK;ECsBL;EACA,YD3BM;;;AC6BV;EACI,YD3BS;EC4BT,OD/BM;ECgCN;EACA;EACA;EACA;EACA;EACA;ECjCH;EACA;EACA;EACA;;;ADiCD;EACI;EACA;EACA;EACA;EACA;EACA,OD9CM;;;ACgDV;EACI;EACA,OD9CK;;;ACgDT;AACI;EACA;EACA,ODnDK;;;ACqDT;AACI;EACA;EACA,ODxDK;;;AC0DT;EACI;EACA,OD5DK;;;AGJT;EACE;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE,YHLO;EGMP;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE,OHpBQ;EGqBR;EACA;;AAEA;EACE;;;AAEJ;EACE,YHvBO;EGwBP,OH1BW;EG2BX;EACA;;;AAEF;EACE,YH7BO;EG8BP,OHhCW;EGiCX;EACA;;;AACF;EACE,OHtCW;EGuCX;;;AAEF;EACE;EACA,MHxCO;;;AG0CT;EACE,YH/CQ;EGgDR;EACA;EACA;;AACA;EACE;EACA;EACA;;AACA;EDnDH;EACA;EACA;EACA;ECkDK;EACA;EACA;;AACF;EACE;;AACF;EACE;;AACF;EACE;EACA;EACA;;AACJ;EACE;EACA;EACA;EACA;EACA,OHzEM;;AG0EN;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;AACA;EACE;EACA;;AACN;EACE;;AACA;EACE,YHxFK;EGyFL;EACA;EACA;EACA;EACA;EACA;;AACA;EACE,YHhGG;;;AGoGb;EACE;EACA,YHnGO;EGoGP;EACA;EACA;EAEA,OHvGO;;AGwGP;EACE;EACA;EACA;EACA;EAEA,YH/GK;EGgHL;EACA,OHhHK;EGiHL;;AAGA;EACE;;AACA;EACE;EACA;;AACF;EACE,OH/HE;;AGgIJ;EACE;;AAEF;EACI;EACA;EACA;EACA,YHnID;;AGoIC;EACE;EACA;;AAEN;EACE;;AACA;EACE;EACA;EACA;EACA;EACA,OHnJA;;AGoJF;EACE;EACA;EACA;EACA;;AACA;EACE,OHzJC;EG0JD;EACA;EACA;EACA;;AACV;EACE;EACA,YHjKM;;AGkKN;EACE,OH/JG;;AGgKL;EACE;EAKA;EACA;EACA;;AANA;EACE;EACA,OHvKK;EGwKL;;AAIF;EACE;EACA;EACA;;AACF;EACE,YH7KC;EG8KD,OH/KC;EGgLD;EACA;;;AAKR;EACE,YHvLO;EGwLP;EACA,OH7LQ;EG8LR;EACA;EACA;;AACA;EACE;EACA;EACA;;AACA;EACE,OHrMO;;;AG4MX;EACI;;AACJ;EACE;;AAKM;EACE;;;AAIV;EACI;;AAGA;EACE;;AACA;EACE;;AAGF;EACE;;;AAKR;EACE;;;AAGA;EACE;;AACA;EACE;;AAEA;EACE","file":"base.css"} \ No newline at end of file diff --git a/content/themes/fipamo-default/assets/images/global/fipamo-logo.svg b/content/themes/fipamo-default/assets/images/global/the-logo.svg similarity index 100% rename from content/themes/fipamo-default/assets/images/global/fipamo-logo.svg rename to content/themes/fipamo-default/assets/images/global/the-logo.svg diff --git a/content/themes/fipamo-default/assets/scripts/Start.js b/content/themes/fipamo-default/assets/scripts/Start.js new file mode 100644 index 0000000..cda5f3b --- /dev/null +++ b/content/themes/fipamo-default/assets/scripts/Start.js @@ -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 diff --git a/content/themes/fipamo-default/assets/scripts/Start.js.map b/content/themes/fipamo-default/assets/scripts/Start.js.map new file mode 100644 index 0000000..f163a50 --- /dev/null +++ b/content/themes/fipamo-default/assets/scripts/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"} \ No newline at end of file diff --git a/content/themes/fipamo-default/assets/scripts/ThemeStart.js b/content/themes/fipamo-default/assets/scripts/ThemeStart.js new file mode 100644 index 0000000..a113cdb --- /dev/null +++ b/content/themes/fipamo-default/assets/scripts/ThemeStart.js @@ -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; + }); + + // + \ No newline at end of file diff --git a/content/themes/fipamo-default/index.twig b/content/themes/fipamo-default/index.twig index 6c355cd..11cba2f 100644 --- a/content/themes/fipamo-default/index.twig +++ b/content/themes/fipamo-default/index.twig @@ -1,4 +1,4 @@ -{% extends "fipamo-default/frame.twig" %} +{% extends "frame.twig" %} {% block title %} {{ title }} @@ -39,6 +39,7 @@ {% else %} {{item.title}}
{% endif %} + {% else %} {{item.title}}
{% endif %} diff --git a/content/themes/fipamo-default/page-custom.twig b/content/themes/fipamo-default/page-custom.twig index db2d69e..4cd7edf 100644 --- a/content/themes/fipamo-default/page-custom.twig +++ b/content/themes/fipamo-default/page-custom.twig @@ -1,4 +1,4 @@ -{% extends "fipamo-default/frame.twig" %} +{% extends "frame.twig" %} {% block title %} {{ title }} @@ -12,7 +12,7 @@
- THIS IS A CUSTOM TEMPLATE
+ [CUSTOM PAGE BRUH]

{{content | raw}}

@@ -20,7 +20,7 @@ tags: {% for tag in meta['tags'] %} {% if dynamicRender is defined %} - {% if dynamicRender == 'true' %} + {% if dynamicRender == 'false' %} {{ tag.label }} {% else %} {{ tag.label }} @@ -28,7 +28,6 @@ {% else %} {{ tag.label }} {% endif %} - {% endfor %}
diff --git a/content/themes/fipamo-default/page.twig b/content/themes/fipamo-default/page.twig index 541b55e..e44d36a 100644 --- a/content/themes/fipamo-default/page.twig +++ b/content/themes/fipamo-default/page.twig @@ -1,4 +1,4 @@ -{% extends "fipamo-default/frame.twig" %} +{% extends "frame.twig" %} {% block title %} {{ title }} @@ -19,7 +19,7 @@ tags: {% for tag in meta['tags'] %} {% if dynamicRender is defined %} - {% if dynamicRender == 'false' %} + {% if dynamicRender == 'true' %} {{ tag.label }} {% else %} {{ tag.label }} @@ -27,7 +27,6 @@ {% else %} {{ tag.label }} {% endif %} - {% endfor %}
diff --git a/content/themes/fipamo-default/tags.twig b/content/themes/fipamo-default/tags.twig index 66b2644..baa6694 100644 --- a/content/themes/fipamo-default/tags.twig +++ b/content/themes/fipamo-default/tags.twig @@ -1,4 +1,4 @@ -{% extends "fipamo-default/frame.twig" %} +{% extends "frame.twig" %} {% block title %} {{ title }} @@ -23,7 +23,6 @@ {% else %} {{tag.title}}
{% endif %} - {% endfor %} diff --git a/public/assets/css/dash.css b/public/assets/css/dash.css index 6005767..addb51c 100644 --- a/public/assets/css/dash.css +++ b/public/assets/css/dash.css @@ -2290,6 +2290,8 @@ svg.icons { } #dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-link .post-video, #dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-video-link .post-video { width: 100%; + height: 100%; + object-fit: cover; position: absolute; } #dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-link label, #dash-index-content #dash-index #dash-index-wrapper #dash-recent #recent-list a.post-video-link label { diff --git a/public/assets/images/global/the-logo.svg b/public/assets/images/global/the-logo.svg new file mode 100644 index 0000000..f8d21b5 --- /dev/null +++ b/public/assets/images/global/the-logo.svg @@ -0,0 +1,33 @@ + + + + + diff --git a/public/assets/scripts/Start.js b/public/assets/scripts/Start.js index 54650e0..cda5f3b 100644 --- a/public/assets/scripts/Start.js +++ b/public/assets/scripts/Start.js @@ -1,8531 +1,2 @@ -// 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) { - return newRequire(localRequire.resolve(x)); - } - - function resolve(x) { - return modules[name][1][x] || 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; - }); - - //