diff --git a/.eslintrc b/.eslintrc index a1f75dd..3c174b3 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,70 +1,70 @@ { - "parserOptions": { - "ecmaVersion": 7, - "sourceType": "module", - "ecmaFeatures": {} - }, - "rules": { - "constructor-super": 2, - "for-direction": 2, - "getter-return": 2, - "no-case-declarations": 2, - "no-class-assign": 2, - "no-compare-neg-zero": 2, - "no-cond-assign": 2, - "no-console": 1, - "no-const-assign": 2, - "no-constant-condition": 2, - "no-control-regex": 1, - "no-debugger": 2, - "no-delete-var": 2, - "no-dupe-args": 2, - "no-dupe-class-members": 2, - "no-dupe-keys": 2, - "no-duplicate-case": 2, - "no-empty": 2, - "no-empty-character-class": 2, - "no-empty-pattern": 2, - "no-ex-assign": 2, - "no-extra-boolean-cast": 2, - "no-extra-semi": 2, - "no-fallthrough": 2, - "no-func-assign": 2, - "no-global-assign": 2, - "no-inner-declarations": 2, - "no-invalid-regexp": 2, - "no-irregular-whitespace": 2, - "no-mixed-spaces-and-tabs": 2, - "no-new-symbol": 2, - "no-obj-calls": 2, - "no-octal": 2, - "no-redeclare": 2, - "no-regex-spaces": 2, - "no-self-assign": 2, - "no-sparse-arrays": 2, - "no-this-before-super": 2, - "no-undef": 2, - "no-unexpected-multiline": 2, - "no-unreachable": 2, - "no-unsafe-finally": 2, - "no-unsafe-negation": 2, - "no-unused-labels": 2, - "no-unused-vars": 2, - "no-useless-escape": 1, - "require-yield": 2, - "use-isnan": 2, - "valid-typeof": 2, - "no-duplicate-imports": 2 - }, - "env": { - "node": true, - "browser": true, - "es6": true - }, - "globals": { - "_": false, - "hljs": false, - "Sortable": false, - "Prism": false - } -} \ No newline at end of file + "parserOptions": { + "ecmaVersion": 7, + "sourceType": "module", + "ecmaFeatures": {} + }, + "rules": { + "constructor-super": 2, + "for-direction": 2, + "getter-return": 2, + "no-case-declarations": 2, + "no-class-assign": 2, + "no-compare-neg-zero": 2, + "no-cond-assign": 2, + "no-console": 1, + "no-const-assign": 2, + "no-constant-condition": 2, + "no-control-regex": 1, + "no-debugger": 2, + "no-delete-var": 2, + "no-dupe-args": 2, + "no-dupe-class-members": 2, + "no-dupe-keys": 2, + "no-duplicate-case": 2, + "no-empty": 2, + "no-empty-character-class": 2, + "no-empty-pattern": 2, + "no-ex-assign": 2, + "no-extra-boolean-cast": 2, + "no-extra-semi": 2, + "no-fallthrough": 2, + "no-func-assign": 2, + "no-global-assign": 2, + "no-inner-declarations": 2, + "no-invalid-regexp": 2, + "no-irregular-whitespace": 2, + "no-mixed-spaces-and-tabs": 2, + "no-new-symbol": 2, + "no-obj-calls": 2, + "no-octal": 2, + "no-redeclare": 2, + "no-regex-spaces": 2, + "no-self-assign": 2, + "no-sparse-arrays": 2, + "no-this-before-super": 2, + "no-undef": 2, + "no-unexpected-multiline": 2, + "no-unreachable": 2, + "no-unsafe-finally": 2, + "no-unsafe-negation": 2, + "no-unused-labels": 2, + "no-unused-vars": 1, + "no-useless-escape": 1, + "require-yield": 2, + "use-isnan": 2, + "valid-typeof": 2, + "no-duplicate-imports": 2 + }, + "env": { + "node": true, + "browser": true, + "es6": true + }, + "globals": { + "_": false, + "hljs": false, + "Sortable": false, + "Prism": false + } +} diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..f967116 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,7 @@ +.babelrc +README.md +*.twig +*.sass +*.json +*.php +*.md diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..951ce9f --- /dev/null +++ b/.prettierrc @@ -0,0 +1,17 @@ + { + "arrowParens": "avoid", + "bracketSpacing": true, + "htmlWhitespaceSensitivity": "css", + "insertPragma": false, + "bracketSameLine": false, + "jsxSingleQuote": true, + "parser": "babel", + "proseWrap": "preserve", + "requirePragma": false, + "semi": true, + "singleQuote": true, + "trailingComma": "none", + "useTabs": true, + "tabWidth": 4, + "printWidth": 90 + } \ No newline at end of file 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..ad20f2b --- /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.inc.php deleted file mode 100644 index 360bedc..0000000 --- a/brain/controller/DashControl.inc.php +++ /dev/null @@ -1,189 +0,0 @@ -getSettings(); - $themes = (new Themes())->getThemes(); //$config->getThemes(); - $template = "dash/settings.twig"; - $member = Session::get("member"); - $form_token = Session::get("form_token"); - $updated = new \Moment\Moment($settings["global"]["last_backup"]); - $pageOptions = [ - "title" => "Dash Settings", - "private" => $settings["global"]["private"], - "renderOnSave" => $settings["global"]["renderOnSave"], - "background" => $settings["global"]["background"], - "member" => $member, - "ftoken" => $form_token, - "siteTitle" => $settings["global"]["title"], - "baseUrl" => $settings["global"]["base_url"], - "desc" => $settings["global"]["descriptions"], - "lastBackup" => $updated->format("Y M D d"), - "currentTheme" => $settings["global"]["theme"], - "themes" => $themes, - "apiStatus" => isset($settings["global"]["externalAPI"]) - ? $settings["global"]["externalAPI"] - : "false", - "dynamicRenderStatus" => isset( - $settings["global"]["dynamicRender"] - ) - ? $settings["global"]["dynamicRender"] - : "false", - "mailOption" => $settings["email"]["active"], - "mailConfig" => $settings["email"], - "status" => Session::active(), - ]; - } else { - header("Location: /dashboard"); - die(); - } - - break; - case "navigation": - if (Session::active()) { - $config = new Settings(); - $settings = $config->getSettings(); - $template = "dash/navigation.twig"; - $pageOptions = [ - "title" => "Edit Dash Navigation", - "status" => Session::active(), - "menu" => $settings["menu"], - ]; - } else { - header("Location: /dashboard"); - die(); - } - break; - case "pages": - if (Session::active()) { - $currentPage = isset($args["fourth"]) ? $args["fourth"] : 1; - $filter = isset($args["third"]) ? $args["third"] : "all"; - $data = (new Book())->getPages($currentPage, 4, $filter); - $template = "dash/book.twig"; - $pageOptions = [ - "entryCount" => $data["entryCount"], - "numOfPages" => $data["numOfPages"], - "currentPage" => $currentPage, - "filter" => $data["paginate"]["sort"], - "stats" => $data["stats"], - "pages" => $data["pages"], - "paginate" => $data["paginate"], - "status" => Session::active(), - ]; - } else { - header("Location: /dashboard"); - die(); - } - break; - case "page": - if (Session::active()) { - $template = "dash/page-edit.twig"; - $mode = $args["third"]; - $uuid = $args["fourth"]; - - switch ($mode) { - case "edit": - $page = (new Book())->findPageById($uuid); - $views = []; - if (str_contains($page["layout"], "index")) { - $views = (new Themes())->getCustomIndex(); - } else { - $views = (new Themes())->getCustomViews(); - } - $pageOptions = [ - "title" => "Fipamo | Edit Page", - "page" => $page, - "mode" => $mode, - "token" => Session::get("form_token"), - "status" => Session::active(), - "views" => $views, - ]; - break; - case "preview": - $config = new Settings(); - $settings = $config->getSettings(); - $loader = new \Twig\Loader\FilesystemLoader( - "../content/themes" - ); - $display = new \Twig\Environment($loader, []); - - $book = new Book(); - $page = $book->findPageById($uuid); - $pageOptions = Sorting::page($page); - $preview = - $settings["global"]["theme"] . - "/" . - $page["layout"] . - ".twig"; - $html = $display->render($preview, $pageOptions); - $response->getBody()->write($html); - return $response; - break; - default: - $pageOptions = [ - "title" => "Fipamo | Create Page", - "token" => Session::get("form_token"), - "mode" => $mode, - "status" => Session::active(), - ]; - break; - } - } else { - header("Location: /dashboard"); - die(); - } - break; - case "logout": - Session::kill(); - header("Location: /dashboard"); - die(); - break; - case "reset-password": - $template = "dash/reset-password.twig"; - $pageOptions = [ - "title" => "Reset Password", - ]; - break; - - default: - $template = "dash/start.twig"; - if (Session::active()) { - $pageOptions = [ - "title" => "Welcome Back", - "status" => Session::active(), - "data" => (new Book())->getPages(1, 4), - ]; - } else { - $pageOptions = [ - "title" => "Welcome to Fipamo", - "status" => Session::active(), - ]; - } - break; - } - } else { - $template = "dash/init.twig"; - $pageOptions = ["title" => "Fipamo Setup"]; - } - - return $view->render($response, $template, $pageOptions); - } -} diff --git a/brain/controller/DashControl.php b/brain/controller/DashControl.php new file mode 100644 index 0000000..c75a724 --- /dev/null +++ b/brain/controller/DashControl.php @@ -0,0 +1,218 @@ +getSettings(); + $themes = (new Themes())->getThemes(); // $config->getThemes(); + $template = 'dash/settings.twig'; + $member = Session::get('member'); + $form_token = Session::get('form_token'); + $updated = new \Moment\Moment($settings['global']['last_backup']); + $pageOptions = [ + 'title' => 'Dash Settings', + 'private' => $settings['global']['private'], + 'renderOnSave' => $settings['global']['renderOnSave'], + 'background' => $settings['global']['background'], + 'member' => $member, + 'ftoken' => $form_token, + 'siteTitle' => $settings['global']['title'], + 'baseUrl' => $settings['global']['base_url'], + 'desc' => $settings['global']['descriptions'], + 'lastBackup' => $updated->format('Y M D d'), + 'currentTheme' => $settings['global']['theme'], + 'themes' => $themes, + 'apiStatus' => isset($settings['global']['externalAPI']) + ? $settings['global']['externalAPI'] + : 'false', + 'dynamicRenderStatus' => isset( + $settings['global']['dynamicRender'] + ) + ? $settings['global']['dynamicRender'] + : 'false', + 'mailOption' => $settings['email']['active'], + 'mailConfig' => $settings['email'], + 'status' => Session::active(), + ]; + } else { + header('Location: /dashboard'); + exit(); + } + + break; + case 'navigation': + if (Session::active()) { + $config = new Settings(); + $settings = $config->getSettings(); + $template = 'dash/navigation.twig'; + $pageOptions = [ + 'title' => 'Edit Dash Navigation', + 'status' => Session::active(), + 'menu' => $settings['menu'], + ]; + } else { + header('Location: /dashboard'); + exit(); + } + break; + case 'pages': + if (Session::active()) { + $currentPage = isset($args['fourth']) ? $args['fourth'] : 1; + $filter = isset($args['third']) ? $args['third'] : 'all'; + $data = (new Book())->getPages($currentPage, 4, $filter); + $template = 'dash/book.twig'; + $pageOptions = [ + 'title' => 'Contents', + 'entryCount' => $data['entryCount'], + 'numOfPages' => $data['numOfPages'], + 'currentPage' => $currentPage, + 'filter' => $data['paginate']['sort'], + 'stats' => $data['stats'], + 'pages' => $data['pages'], + 'paginate' => $data['paginate'], + 'status' => Session::active(), + ]; + } else { + header('Location: /dashboard'); + exit(); + } + break; + case 'page': + if (Session::active()) { + $template = 'dash/page-edit.twig'; + $mode = $args['third']; + $uuid = $args['fourth']; + + switch ($mode) { + case 'edit': + $page = (new Book())->findPageById($uuid); + $views = []; + if (str_contains($page['layout'], 'index')) { + $views = (new Themes())->getCustomIndex(); + } else { + $views = (new Themes())->getCustomViews(); + } + + $imageList = explode(',', $page['feature']); + $fileList = explode(',', $page['files']); + + $images = []; + $files = []; + foreach ($imageList as $item) { + $image = trim($item); + if (!empty($image)) { + array_push($images, $image); + } + } + + foreach ($fileList as $item) { + $file = trim($item); + if (!empty($file)) { + array_push($files, $file); + } + } + + $pageOptions = [ + 'title' => 'Fipamo | Edit Page', + 'page' => $page, + 'mode' => $mode, + 'token' => Session::get('form_token'), + 'status' => Session::active(), + 'images' => $images, + 'files' => $files, + 'views' => $views, + ]; + break; + case 'preview': + $config = new Settings(); + $settings = $config->getSettings(); + $loader = new \Twig\Loader\FilesystemLoader( + '../content/themes' + ); + $display = new \Twig\Environment($loader, []); + + $book = new Book(); + $page = $book->findPageById($uuid); + $pageOptions = Sorting::page($page); + $preview = + $settings['global']['theme']. + '/'. + $page['layout']. + '.twig'; + $html = $display->render($preview, $pageOptions); + $response->getBody()->write($html); + + return $response; + break; + default: + $pageOptions = [ + 'title' => 'Fipamo | Create Page', + 'token' => Session::get('form_token'), + 'mode' => $mode, + 'status' => Session::active(), + ]; + break; + } + } else { + header('Location: /dashboard'); + exit(); + } + break; + case 'logout': + Session::kill(); + header('Location: /dashboard'); + exit(); + break; + case 'reset-password': + $template = 'dash/reset-password.twig'; + $pageOptions = [ + 'title' => 'Reset Password', + ]; + break; + default: + $template = 'dash/start.twig'; + if (Session::active()) { + $pageOptions = [ + 'title' => 'Welcome Back', + 'status' => Session::active(), + 'data' => (new Book())->getPages(1, 4), + ]; + } else { + $pageOptions = [ + 'title' => 'Welcome to Fipamo', + 'status' => Session::active(), + ]; + } + break; + } + } else { + $template = 'dash/init.twig'; + $pageOptions = ['title' => 'Fipamo Setup']; + } + + return $view->render($response, $template, $pageOptions); + } +} 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 b207b1f..0000000 --- a/brain/controller/RouteControl.inc.php +++ /dev/null @@ -1,44 +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.inc.php deleted file mode 100644 index e9cec78..0000000 --- a/brain/data/Book.inc.php +++ /dev/null @@ -1,265 +0,0 @@ -getContents(); - $page = find($content, ["uuid" => $uuid]); - return $page; - } - - public function findPageBySlug(string $slug = null) - { - $content = $this->getContents(); - if (isset($slug)) { - $page = find($content, ["slug" => $slug]); - } else { - $page = find($content, ["layout" => "index"]); - } - - return $page; - } - - public function editPage($task, $request) - { - $content = $this->getContents(); - if ($task == "delete") { - //$parsed = json_decode(file_get_contents("php://input"), true); - //$body = find($content, ["uuid" => $parsed["id"]]); - $body = $request->getParsedBody(); - } else { - $body = $request->getParsedBody(); - } - - $page = find($content, ["uuid" => $body["uuid"]]); - $image = $request->getUploadedFiles(); - $member = Session::get("member"); - - if ($task != "create") { - $path = - date("Y", date($page["rawCreated"])) . - "/" . - date("m", date($page["rawCreated"])); - } else { - $path = date("Y") . "/" . date("m"); - } - - if (isset($image["feature_image"])) { - if ($task != "create") { - $feature = - "/assets/images/blog/" . - $path . - "/" . - $image["feature_image"]->getClientFileName(); - } else { - $feature = - "/assets/images/blog/" . - $path . - "/" . - $image["feature_image"]->getClientFileName(); - } - - FileUploader::uploadFile( - "../public/assets/images/blog/" . $path . "/", - $image["feature_image"] - ); - } else { - if (isset($body["feature_image"])) { - $url = explode("/", $body["feature_image"]); - $feature = - "/" . - $url[3] . - "/" . - $url[4] . - "/" . - $url[5] . - "/" . - $url[6] . - "/" . - $url[7] . - "/" . - $url[8]; - } else { - $task == "create" ? ($feature = "") : ($feature = $body["feature"]); - } - } - - if ($task == "delete") { - $deleted = "true"; - $body["menu"] = "false"; - $body["published"] = "false"; - $body["featured"] = "false"; - } else { - $deleted = isset($page["deleted"]) ? $page["deleted"] : "false"; - } - - $created = - $task != "create" - ? new \Moment\Moment($page["rawCreated"]) - : new \Moment\Moment(); - $updated = new \Moment\Moment(); - - //grab current index from settings and update - $id = $task != "create" ? $body["id"] : Settings::getCurrentIndex(); - $uuid = $task != "create" ? $body["uuid"] : StringTools::createUUID(); - // now that variables are done, set to body object and then convert to markdown to save - - $body["id"] = $id; - $body["uuid"] = $uuid; - $body["feature"] = $feature; - $body["path"] = $path; - $body["author"] = $member["handle"]; - $body["created"] = $created->format("Y-m-d\TH:i:sP"); - $body["updated"] = $updated->format("Y-m-d\TH:i:sP"); - $body["deleted"] = $deleted; - - $write = DocTools::objectToMD($body); - - // if layout is index, change path to file - - if ($body["layout"] == "index") { - $writePath = "../content/pages/start/index.md"; - } else { - $writePath = "../content/pages/" . $path . "/" . $body["slug"] . ".md"; - } - - $status = DocTools::writePages($task, $path, $writePath, $write); - - if ($status) { - $config = new Settings(); - $settings = $config->getSettings(); - $message = ""; - - if ( - $settings["global"]["renderOnSave"] == "true" && - $settings["global"]["dynamicRender"] == "false" - ) { - $render = new Render(); - $render->renderTags(); - $render->renderArchive(); - $render->renderPages(); - $message = "Filed edited and rendered. NOICE."; - } else { - $message = "File edited. Nice work"; - } - - $response = [ - "message" => $message, - "type" => $task == "write" ? "postUpdated" : "postAdded", - "id" => $uuid, - ]; - - //TODO: When form submission is successful, make new form token - //Session token doesn't reset on the front end, so turning this off for now - //$form_token = md5(uniqid(microtime(), true)); - //Session::set("form_token", $form_token); - - //once saved, update menu - $body["path"] = $path; - Settings::updateMenu($body); - Settings::updateTags(); - //if new page added, update current index in Settings file - if ($task == "create") { - Settings::updateIndex(); - } - } else { - $response = [ - "message" => "Uh oh. File save problem. Don't panic", - "type" => "postError", - "id" => $uuid, - ]; - } - - return $response; - } - - public function getPages(int $page, int $limit, string $sort = null) - { - $content = $this->getContents(); - - $published = filter($content, function ($item) { - return $item["published"] == true && $item["deleted"] == false; - }); - $deleted = filter($content, function ($item) { - return $item["deleted"] == true; - }); - - //$all = $content; - $all = filter($content, function ($item) { - return $item["deleted"] == false; - }); - $filter = isset($sort) ? $sort : "all"; - switch ($filter) { - case "published": - $filtered = $published; - break; - case "deleted": - $filtered = $deleted; - break; - default: - $filtered = $all; - break; - } - $numOfPages = ceil(count($filtered) / ($limit + 1)); - $folder = []; - - if (count($filtered) != 0) { - if (count($filtered) < $limit) { - $limit = count($filtered) - 1; - } - $range = $page * $limit - $limit; - - if ($range != 0) { - $range = $range + 1; - } - for ($i = 0; $i <= $limit; $i++) { - if (isset($filtered[$i + $range])) { - array_push($folder, $filtered[$i + $range]); - } else { - //chill out - } - } - } - - $prev = $page - 1; - if ($prev <= 0) { - $prev = $numOfPages; - } - - $next = $page + 1; - if ($next > $numOfPages) { - $next = 1; - } - - return [ - "pages" => $folder, - "numOfPages" => $numOfPages, - "entryCount" => count($filtered), - "paginate" => [ - "sort" => $sort, - "nextPage" => $next, - "prevPage" => $prev, - ], - "stats" => [ - "all" => count($all), - "published" => count($published), - "deleted" => count($deleted), - ], - ]; - } - public function getContents() - { - //test new contents data class - //$new = (new Contents("../content/pages"))->getAll(); - $contents = (new Contents("../content/pages"))->getAll(); - return $contents; - } -} diff --git a/brain/data/Book.php b/brain/data/Book.php new file mode 100644 index 0000000..237f66a --- /dev/null +++ b/brain/data/Book.php @@ -0,0 +1,298 @@ +getContents(); + $page = find($content, ['uuid' => $uuid]); + + return $page; + } + + public function findPageBySlug(string $slug = null) + { + $content = $this->getContents(); + if (isset($slug)) { + $page = find($content, ['slug' => $slug]); + } else { + $page = find($content, ['layout' => 'index']); + } + + return $page; + } + + public function editPage($task, $request) + { + $content = $this->getContents(); + if ($task == 'delete') { + // $parsed = json_decode(file_get_contents("php://input"), true); + // $body = find($content, ["uuid" => $parsed["id"]]); + $body = $request->getParsedBody(); + } else { + $body = $request->getParsedBody(); + } + + $page = find($content, ['uuid' => $body['uuid']]); + $files = $request->getUploadedFiles(); + + $member = Session::get('member'); + + if ($task != 'create') { + $path = + date('Y', date($page['rawCreated'])). + '/'. + date('m', date($page['rawCreated'])); + } else { + $path = date('Y').'/'.date('m'); + } + + $page_feature = ''; + $page_files = ''; + + if (isset($files['page_files'])) { + $imageList = ''; + $fileList = ''; + // var_dump($files["page_files"] ); + foreach ($files['page_files'] as $file) { + $type = $file->getClientMediaType(); + switch ($type) { + case 'image/jpeg': + case 'image/png': + case 'image/gif': + case 'image/svg': + $imagesPath = '/assets/images/blog/'.$path.'/'; + $imageList = + $imageList.$imagesPath.urlencode($file->getClientFileName()).', '; + + FileUploader::uploadFile( + '../public/assets/images/blog/'.$path.'/', + $file + ); + break; + case 'video/mp4': + $videosPath = '/assets/video/blog/'.$path.'/'; + $imageList = + $imageList.$videosPath.urlencode($file->getClientFileName()).', '; + + FileUploader::uploadFile( + '../public/assets/video/blog/'.$path.'/', + $file + ); + break; + case 'audio/mpeg': + $soundPath = '/assets/sound/blog/'.$path.'/'; + $fileList = $fileList.$soundPath.urlencode($file->getClientFileName()).', '; + + FileUploader::uploadFile( + '../public/assets/sound/blog/'.$path.'/', + $file + ); + break; + case 'application/pdf': + case 'text/plain': + case 'text/rtf': + $docPath = '/assets/docs/blog/'.$path.'/'; + $fileList = $fileList.$docPath.urlencode($file->getClientFileName()).', '; + + FileUploader::uploadFile( + '../public/assets/docs/blog/'.$path.'/', + $file + ); + break; + } + } + $page_feature = $imageList; + $page_files = $fileList; + } else { + // if no files, just reset string from page object + $page_feature = $page['feature']; + $page_files = $page['files']; + } + + if ($task == 'delete') { + $deleted = 'true'; + $body['menu'] = 'false'; + $body['published'] = 'false'; + $body['featured'] = 'false'; + } else { + $deleted = isset($page['deleted']) ? $page['deleted'] : 'false'; + } + + $created = + $task != 'create' + ? new \Moment\Moment($page['rawCreated']) + : new \Moment\Moment(); + $updated = new \Moment\Moment(); + + // grab current index from settings and update + $id = $task != 'create' ? $body['id'] : Settings::getCurrentIndex(); + $uuid = $task != 'create' ? $body['uuid'] : StringTools::createUUID(); + // now that variables are done, set to body object and then convert to markdown to save + + $body['id'] = $id; + $body['uuid'] = $uuid; + $body['feature'] = $page_feature; + $body['files'] = $page_files; + $body['path'] = $path; + $body['author'] = $member['handle']; + $body['created'] = $created->format("Y-m-d\TH:i:sP"); + $body['updated'] = $updated->format("Y-m-d\TH:i:sP"); + $body['deleted'] = $deleted; + + $write = DocTools::objectToMD($body); + + // if layout is index, change path to file + + if ($body['layout'] == 'index') { + $writePath = '../content/pages/start/index.md'; + } else { + $writePath = '../content/pages/'.$path.'/'.$body['slug'].'.md'; + } + + $status = DocTools::writePages($task, $path, $writePath, $write); + + if ($status) { + $config = new Settings(); + $settings = $config->getSettings(); + $message = ''; + + if ( + $settings['global']['renderOnSave'] == 'true' && + $settings['global']['dynamicRender'] == 'false' + ) { + $render = new Render(); + $render->renderTags(); + $render->renderArchive(); + $render->renderPages(); + $message = 'Filed edited and rendered. NOICE.'; + } else { + $message = 'File edited. Nice work'; + } + + $response = [ + 'message' => $message, + 'type' => $task == 'write' ? 'postUpdated' : 'postAdded', + 'id' => $uuid, + ]; + + // TODO: When form submission is successful, make new form token + // Session token doesn't reset on the front end, so turning this off for now + // $form_token = md5(uniqid(microtime(), true)); + // Session::set("form_token", $form_token); + + // once saved, update menu + $body['path'] = $path; + Settings::updateMenu($body); + Settings::updateTags(); + // if new page added, update current index in Settings file + if ($task == 'create') { + Settings::updateIndex(); + } + } else { + $response = [ + 'message' => "Uh oh. File save problem. Don't panic", + 'type' => 'postError', + 'id' => $uuid, + ]; + } + + return $response; + } + + public function getPages(int $page, int $limit, string $sort = null) + { + $content = $this->getContents(); + + $published = filter($content, function ($item) { + return $item['published'] == true && $item['deleted'] == false; + }); + $deleted = filter($content, function ($item) { + return $item['deleted'] == true; + }); + + // $all = $content; + $all = filter($content, function ($item) { + return $item['deleted'] == false; + }); + $filter = isset($sort) ? $sort : 'all'; + switch ($filter) { + case 'published': + $filtered = $published; + break; + case 'deleted': + $filtered = $deleted; + break; + default: + $filtered = $all; + break; + } + $numOfPages = ceil(count($filtered) / ($limit + 1)); + $folder = []; + + if (count($filtered) != 0) { + if (count($filtered) < $limit) { + $limit = count($filtered) - 1; + } + $range = $page * $limit - $limit; + + if ($range != 0) { + $range = $range + 1; + } + for ($i = 0; $i <= $limit; ++$i) { + if (isset($filtered[$i + $range])) { + array_push($folder, $filtered[$i + $range]); + } else { + // chill out + } + } + } + + $prev = $page - 1; + if ($prev <= 0) { + $prev = $numOfPages; + } + + $next = $page + 1; + if ($next > $numOfPages) { + $next = 1; + } + + return [ + 'pages' => $folder, + 'numOfPages' => $numOfPages, + 'entryCount' => count($filtered), + 'paginate' => [ + 'sort' => $sort, + 'nextPage' => $next, + 'prevPage' => $prev, + ], + 'stats' => [ + 'all' => count($all), + 'published' => count($published), + 'deleted' => count($deleted), + ], + ]; + } + + public function getContents() + { + // test new contents data class + // $new = (new Contents("../content/pages"))->getAll(); + $contents = (new Contents('../content/pages'))->getAll(); + + return $contents; + } +} diff --git a/brain/data/Contents.inc.php b/brain/data/Contents.inc.php deleted file mode 100644 index 010e1d7..0000000 --- a/brain/data/Contents.inc.php +++ /dev/null @@ -1,144 +0,0 @@ -read($folder); - } - public function read($folder) - { - $folders = glob("$folder/*", GLOB_ONLYDIR); - foreach ($folders as $folder) { - //$this->files[] = $folder . "/"; - $this->read($folder); - } - $files = array_filter(glob("$folder/*md"), "is_file"); - foreach ($files as $file) { - $this->files[] = $file; - } - } - - function getAll() - { - $environment = new Environment($this->config); - $environment->addExtension(new CommonMarkCoreExtension()); - - // Add the extension - $environment->addExtension(new FrontMatterExtension()); - - //Add Strikethrough rendering - $environment->addExtension(new StrikethroughExtension()); - - //add attributes to elements in markdown - $environment->addExtension(new AttributesExtension()); - - // Instantiate the converter engine and start converting some Markdown! - $converter = new MarkdownConverter($environment); - - $contents = []; - foreach ($this->files as $file) { - //get meta and html from file - $result = $converter->convertToHtml(file_get_contents($file)); - $meta = []; - if ($result instanceof RenderedContentWithFrontMatter) { - $meta = $result->getFrontMatter(); - } - - //get raw markdown from file - $frontMatterExtension = new FrontMatterExtension(); - $parsed = $frontMatterExtension - ->getFrontMatterParser() - ->parse(file_get_contents($file)); - - //never trust the front end. clean it up - - $builder = new SanitizerBuilder(); - $builder->registerExtension(new BasicExtension()); - $builder->registerExtension(new IframeExtension()); - - //relative-a and relative-image - $builder->registerExtension( - new \HtmlSanitizer\Extension\Relative\A\AExtension() - ); - $builder->registerExtension( - new \HtmlSanitizer\Extension\Relative\Image\ImageExtension() - ); - - $detergent = [ - "extensions" => ["basic", "relative-a", "relative-image", "iframe"], - "tags" => [ - "div" => [ - "allowed_attributes" => ["class", "title"], - ], - "img" => [ - "allowed_attributes" => ["src", "alt", "title", "class"], - ], - "iframe" => [ - "allowed_attributes" => ["height", "width", "title", "src"], - ], - ], - ]; - - $sanitizer = $builder->build($detergent); - - $scrubbed = $sanitizer->sanitize($result->getContent()); - - //sort attributes into page object - $page = [ - "id" => $meta["id"], - "uuid" => $meta["uuid"], - "title" => $meta["title"], - "feature" => $meta["feature"], - "path" => $meta["path"], - "layout" => $meta["layout"], - "tags" => $meta["tags"], - "author" => $meta["author"], - "created" => date("Y M D d", $meta["created"]), - "updated" => date("Y M D d", $meta["updated"]), - "rawCreated" => $meta["created"], - "rawUpdated" => $meta["updated"], - "createdYear" => date("Y", $meta["created"]), - "createdMonth" => date("m", $meta["created"]), - "deleted" => $meta["deleted"], - "menu" => $meta["menu"], - "featured" => $meta["featured"], - "published" => $meta["published"], - "slug" => $meta["slug"], - "filePath" => $file, - "content" => $parsed->getContent(), - "html" => $scrubbed, - ]; - //checks for duplicates - $uuid = $meta["uuid"]; - $found = current( - array_filter($contents, function ($item) use ($uuid) { - return isset($item["uuid"]) && $uuid == $item["uuid"]; - }) - ); - - // if uuid is not present, add it - if (!$found) { - array_push($contents, $page); - } - } - $contents = orderBy($contents, ["id"], ["desc"]); - return $contents; - } -} diff --git a/brain/data/Contents.php b/brain/data/Contents.php new file mode 100644 index 0000000..9fd6b41 --- /dev/null +++ b/brain/data/Contents.php @@ -0,0 +1,178 @@ +read($folder); + } + public function read($folder) + { + $folders = glob("$folder/*", GLOB_ONLYDIR); + foreach ($folders as $folder) { + //$this->files[] = $folder . "/"; + $this->read($folder); + } + $files = array_filter(glob("$folder/*md"), "is_file"); + foreach ($files as $file) { + $this->files[] = $file; + } + } + + public function getAll() + { + $environment = new Environment($this->config); + $environment->addExtension(new CommonMarkCoreExtension()); + + // Add the extension + $environment->addExtension(new FrontMatterExtension()); + + //Add Strikethrough rendering + $environment->addExtension(new StrikethroughExtension()); + + //add attributes to elements in markdown + $environment->addExtension(new AttributesExtension()); + + // Instantiate the converter engine and start converting some Markdown! + $converter = new MarkdownConverter($environment); + + $contents = []; + foreach ($this->files as $file) { + //get meta and html from file + $result = $converter->convertToHtml(file_get_contents($file)); + $meta = []; + if ($result instanceof RenderedContentWithFrontMatter) { + $meta = $result->getFrontMatter(); + } + + //get raw markdown from file + $frontMatterExtension = new FrontMatterExtension(); + $parsed = $frontMatterExtension + ->getFrontMatterParser() + ->parse(file_get_contents($file)); + + //never trust the front end. clean it up + //add what sanitizer extensions we need manually + $builder = new SanitizerBuilder(); + $builder->registerExtension(new BasicExtension()); + $builder->registerExtension(new IframeExtension()); + $builder->registerExtension(new ListExtension()); + + //relative-a and relative-image + $builder->registerExtension( + new \HtmlSanitizer\Extension\Relative\A\AExtension() + ); + $builder->registerExtension( + new \HtmlSanitizer\Extension\Relative\Image\ImageExtension() + ); + + $detergent = [ + "extensions" => ["basic", "list","relative-a", "relative-image", "iframe"], + "tags" => [ + "div" => [ + "allowed_attributes" => ["class", "title", "id", "style"], + ], + "img" => [ + "allowed_attributes" => ["src", "alt", "title", "class"], + ], + "iframe" => [ + "allowed_attributes" => ["height", "width", "title", "src"], + ], + ], + ]; + + $sanitizer = $builder->build($detergent); + + $scrubbed = $sanitizer->sanitize($result->getContent()); + $featureList = explode(",", $meta["feature"]); + $docs = ''; + if (isset($meta["files"])) { + $fileList = explode(",", $meta["files"]); + $docs = $meta["files"]; + } else { + $fileList = []; + $docs = ''; + } + + $media = []; + $files = []; + foreach ($featureList as $file) { + $item = trim($file); + $ext = pathinfo($item, PATHINFO_EXTENSION); + if ($item != null || $item != "") { + array_push($media, ["file" => $item, "type" => trim($ext)]); + } + } + + foreach ($fileList as $file) { + $item = trim($file); + $ext = pathinfo($item, PATHINFO_EXTENSION); + if ($item != null || $item != "") { + array_push($files, ["file" => $item, "type" => trim($ext)]); + } + } + + //sort attributes into page object + $page = [ + "id" => $meta["id"], + "uuid" => $meta["uuid"], + "title" => $meta["title"], + "feature" => $meta["feature"], + "files" => $docs, + "path" => $meta["path"], + "layout" => $meta["layout"], + "tags" => $meta["tags"], + "author" => $meta["author"], + "created" => date("Y M D d", $meta["created"]), + "updated" => date("Y M D d", $meta["updated"]), + "rawCreated" => $meta["created"], + "rawUpdated" => $meta["updated"], + "createdYear" => date("Y", $meta["created"]), + "createdMonth" => date("m", $meta["created"]), + "deleted" => $meta["deleted"], + "menu" => $meta["menu"], + "featured" => $meta["featured"], + "published" => $meta["published"], + "slug" => $meta["slug"], + "filePath" => $file, + "content" => $parsed->getContent(), + "html" => $scrubbed, + "media" => $media, + "docs" => $files + ]; + //checks for duplicates + $uuid = $meta["uuid"]; + $found = current( + array_filter($contents, function ($item) use ($uuid) { + return isset($item["uuid"]) && $uuid == $item["uuid"]; + }) + ); + + // if uuid is not present, add it + if (!$found) { + array_push($contents, $page); + } + } + $contents = orderBy($contents, ["id"], ["desc"]); + return $contents; + } +} 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 3c85a2a..0000000 --- a/brain/data/Render.inc.php +++ /dev/null @@ -1,179 +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 - 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.inc.php deleted file mode 100644 index e28197f..0000000 --- a/brain/utility/DocTools.inc.php +++ /dev/null @@ -1,140 +0,0 @@ -getClientFileName(), $directory); - //$extension = pathinfo($file->getClientFilename(), PATHINFO_EXTENSION); - - // see http://php.net/manual/en/function.random-bytes.php - //$basename = bin2hex(random_bytes(8)); - //$filename = sprintf("%s.%0.8s", $basename, $extension); - - //echo "**FILE** " . $file->getClientFileName(); - - $file->moveTo($directory . "/" . $file->getClientFileName()); - } catch (RuntimeException $e) { - echo "ERROR " . $e->getMessage(); - - //echo "failed to upload image: " . $e->getMessage(); - //throw new Error("Failed to upload image file"); - } - } -} diff --git a/brain/utility/FileUploader.php b/brain/utility/FileUploader.php new file mode 100644 index 0000000..c40b2a5 --- /dev/null +++ b/brain/utility/FileUploader.php @@ -0,0 +1,32 @@ +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 = - "