diff options
author | Freya Murphy <freya@freyacat.org> | 2024-12-23 11:13:27 -0500 |
---|---|---|
committer | Freya Murphy <freya@freyacat.org> | 2024-12-23 11:13:27 -0500 |
commit | 5a2ba9c2e7605bb788bc406184547d22c6436867 (patch) | |
tree | cbd988d534e8a8593a31d70571222443f80da0b3 /src/web | |
parent | fix about modal (diff) | |
download | xssbook2-5a2ba9c2e7605bb788bc406184547d22c6436867.tar.gz xssbook2-5a2ba9c2e7605bb788bc406184547d22c6436867.tar.bz2 xssbook2-5a2ba9c2e7605bb788bc406184547d22c6436867.zip |
v2.1.0, refactor w/ crimson
Diffstat (limited to 'src/web')
-rw-r--r-- | src/web/_controller/_index.php | 23 | ||||
-rw-r--r-- | src/web/_controller/_meta.php | 12 | ||||
-rw-r--r-- | src/web/_controller/_modal.php | 28 | ||||
-rw-r--r-- | src/web/_controller/_post.php (renamed from src/web/_controller/_util/post.php) | 113 | ||||
-rw-r--r-- | src/web/_controller/_template.php | 21 | ||||
-rw-r--r-- | src/web/_controller/apps/auth.php | 56 | ||||
-rw-r--r-- | src/web/_controller/apps/error.php | 21 | ||||
-rw-r--r-- | src/web/_controller/apps/home.php | 26 | ||||
-rw-r--r-- | src/web/_controller/apps/people.php | 48 | ||||
-rw-r--r-- | src/web/_controller/apps/profile.php | 44 | ||||
-rw-r--r-- | src/web/_controller/apps/settings.php | 41 | ||||
-rw-r--r-- | src/web/_controller/auth.php | 45 | ||||
-rw-r--r-- | src/web/_controller/error.php | 36 | ||||
-rw-r--r-- | src/web/_controller/home.php | 27 | ||||
-rw-r--r-- | src/web/_controller/index.php | 16 | ||||
-rw-r--r-- | src/web/_controller/modal.php | 38 | ||||
-rw-r--r-- | src/web/_controller/people.php | 45 | ||||
-rw-r--r-- | src/web/_controller/profile.php | 44 | ||||
-rw-r--r-- | src/web/_controller/settings.php | 34 | ||||
-rw-r--r-- | src/web/_controller/template.php | 23 | ||||
-rw-r--r-- | src/web/_model/apps/auth.php | 13 | ||||
-rw-r--r-- | src/web/_model/apps/error.php | 31 | ||||
-rw-r--r-- | src/web/_model/apps/home.php | 22 | ||||
-rw-r--r-- | src/web/_model/apps/people.php | 90 | ||||
-rw-r--r-- | src/web/_model/apps/profile.php | 65 | ||||
-rw-r--r-- | src/web/_model/apps/settings.php | 16 | ||||
-rw-r--r-- | src/web/_model/auth.php | 42 | ||||
-rw-r--r-- | src/web/_model/cache.php | 37 | ||||
-rw-r--r-- | src/web/_model/error.php | 3 | ||||
-rw-r--r-- | src/web/_model/format.php | 36 | ||||
-rw-r--r-- | src/web/_model/home.php | 17 | ||||
-rw-r--r-- | src/web/_model/main.php | 119 | ||||
-rw-r--r-- | src/web/_model/people.php | 72 | ||||
-rw-r--r-- | src/web/_model/profile.php | 70 | ||||
-rw-r--r-- | src/web/_model/request.php | 40 | ||||
-rw-r--r-- | src/web/_model/settings.php | 3 | ||||
-rw-r--r-- | src/web/_views/_modal/about.php (renamed from src/web/_views/modal/about.php) | 0 | ||||
-rw-r--r-- | src/web/_views/_modal/new_post.php (renamed from src/web/_views/modal/new_post.php) | 25 | ||||
-rw-r--r-- | src/web/_views/_modal/register.php (renamed from src/web/_views/modal/register.php) | 2 | ||||
-rw-r--r-- | src/web/_views/_template/comment.php (renamed from src/web/_views/template/comment.php) | 7 | ||||
-rw-r--r-- | src/web/_views/_template/error.php (renamed from src/web/_views/template/error.php) | 0 | ||||
-rw-r--r-- | src/web/_views/_template/modal.php (renamed from src/web/_views/template/modal.php) | 2 | ||||
-rw-r--r-- | src/web/_views/_template/post.php (renamed from src/web/_views/template/post.php) | 13 | ||||
-rw-r--r-- | src/web/_views/_template/posts.php (renamed from src/web/_views/template/posts.php) | 11 | ||||
-rw-r--r-- | src/web/_views/_template/toast.php (renamed from src/web/_views/template/toast.php) | 18 | ||||
-rw-r--r-- | src/web/_views/apps/people/people.php | 7 | ||||
-rw-r--r-- | src/web/_views/auth/main.php (renamed from src/web/_views/apps/auth/login.php) | 6 | ||||
-rw-r--r-- | src/web/_views/error/main.php (renamed from src/web/_views/apps/error/main.php) | 0 | ||||
-rw-r--r-- | src/web/_views/head.php | 15 | ||||
-rw-r--r-- | src/web/_views/header.php | 38 | ||||
-rw-r--r-- | src/web/_views/home/main.php (renamed from src/web/_views/apps/home/main.php) | 8 | ||||
-rw-r--r-- | src/web/_views/people/card.php (renamed from src/web/_views/apps/people/card.php) | 2 | ||||
-rw-r--r-- | src/web/_views/people/footer.php (renamed from src/web/_views/apps/people/footer.php) | 0 | ||||
-rw-r--r-- | src/web/_views/people/header.php (renamed from src/web/_views/apps/people/header.php) | 0 | ||||
-rw-r--r-- | src/web/_views/people/main.php (renamed from src/web/_views/apps/people/main.php) | 12 | ||||
-rw-r--r-- | src/web/_views/people/people.php | 5 | ||||
-rw-r--r-- | src/web/_views/profile/main.php (renamed from src/web/_views/apps/profile/main.php) | 28 | ||||
-rw-r--r-- | src/web/_views/settings/main.php (renamed from src/web/_views/apps/settings/main.php) | 7 | ||||
-rw-r--r-- | src/web/config.php | 56 | ||||
-rw-r--r-- | src/web/config/aesthetic.php | 83 | ||||
-rw-r--r-- | src/web/config/routes.php | 12 | ||||
-rw-r--r-- | src/web/core/_controller.php | 69 | ||||
-rw-r--r-- | src/web/core/_model.php | 44 | ||||
-rw-r--r-- | src/web/core/database.php | 282 | ||||
-rw-r--r-- | src/web/core/loader.php | 101 | ||||
-rw-r--r-- | src/web/core/router.php | 159 | ||||
-rw-r--r-- | src/web/helper/error.php | 9 | ||||
-rw-r--r-- | src/web/helper/lang.php | 81 | ||||
-rw-r--r-- | src/web/index.php | 46 | ||||
-rw-r--r-- | src/web/lang/api.php (renamed from src/web/lang/en_US/api_lang.php) | 2 | ||||
-rw-r--r-- | src/web/lang/auth.php (renamed from src/web/lang/en_US/apps/auth.php) | 4 | ||||
-rw-r--r-- | src/web/lang/common.php (renamed from src/web/lang/en_US/common_lang.php) | 45 | ||||
-rw-r--r-- | src/web/lang/en_US/error_lang.php | 8 | ||||
-rw-r--r-- | src/web/lang/home.php (renamed from src/web/lang/en_US/apps/home.php) | 4 | ||||
-rw-r--r-- | src/web/lang/people.php (renamed from src/web/lang/en_US/apps/people.php) | 4 | ||||
-rw-r--r-- | src/web/lang/post.php | 35 | ||||
-rw-r--r-- | src/web/lang/profile.php (renamed from src/web/lang/en_US/apps/profile.php) | 7 | ||||
-rw-r--r-- | src/web/lang/settings.php (renamed from src/web/lang/en_US/apps/settings.php) | 2 | ||||
-rw-r--r-- | src/web/lib/_base.php | 61 | ||||
-rw-r--r-- | src/web/lib/_controller.php | 49 | ||||
-rw-r--r-- | src/web/lib/_model.php | 61 | ||||
-rw-r--r-- | src/web/lib/hooks.php | 31 | ||||
-rw-r--r-- | src/web/lib/image.php (renamed from src/web/helper/image.php) | 0 | ||||
-rw-r--r-- | src/web/lib/utils.php | 6 | ||||
-rw-r--r-- | src/web/stamp.php | 46 |
85 files changed, 1017 insertions, 1913 deletions
diff --git a/src/web/_controller/_index.php b/src/web/_controller/_index.php deleted file mode 100644 index 2fd7db2..0000000 --- a/src/web/_controller/_index.php +++ /dev/null @@ -1,23 +0,0 @@ -<?php /* Copyright (c) 2024 Freya Murphy */ -class _index_controller extends Controller { - - // the home model - private $home_model; - - // the request model - private $request_model; - - // the caceh model - private $cache_model; - - public function index(): void { - if ($this->main->session) { - $this->redirect('/home'); - } else { - $this->redirect('/auth/login'); - } - } - -} - -?> diff --git a/src/web/_controller/_meta.php b/src/web/_controller/_meta.php index bec3c65..06c7c0a 100644 --- a/src/web/_controller/_meta.php +++ b/src/web/_controller/_meta.php @@ -1,21 +1,21 @@ <?php /* Copyright (c) 2024 Freya Murphy */ -class _meta_controller extends Controller { +class _meta_controller extends XSS_Controller { public function manifest(): void { $json = array( - 'short_name' => 'xssbook.com', - 'name' => 'xssbook.com', + 'short_name' => CONFIG['domain'], + 'name' => CONFIG['domain'], 'icons' => [ array( - 'src' => 'https://xssbook.com/public/icons/logo512.png', + 'src' => $this->get_url('public/icons/logo512.png'), 'type' => 'image/png', 'sizes' => '512x512', 'purpose' => 'any maskable' ) ], - 'id' => 'https://xssbook.com/home', - 'start_url' => 'https://xssbook.com/home', + 'id' => $this->get_url('home'), + 'start_url' => $this->get_url('home'), 'background_color' => '#181818', 'display' => 'standalone', 'scope' => '/', diff --git a/src/web/_controller/_modal.php b/src/web/_controller/_modal.php new file mode 100644 index 0000000..0447ca8 --- /dev/null +++ b/src/web/_controller/_modal.php @@ -0,0 +1,28 @@ +<?php /* Copyright (c) 2024 Freya Murphy */ +class _modal_controller extends XSS_Controller { + + /** + * @param string $name + * @param array $data + */ + private function modal($name): void { + $data = $this->model->get_data(); + $data['title'] = ucwords(lang($name . '_modal_title')); + $data['content'] = $name; + $this->view('_template/modal', $data); + } + + public function new_post(): void { + $this->load_lang('post'); + $this->modal('new_post'); + } + + public function about(): void { + $this->modal('about'); + } + + public function register(): void { + $this->load_lang('auth'); + $this->modal('register'); + } +} diff --git a/src/web/_controller/_util/post.php b/src/web/_controller/_post.php index 5346497..56c997f 100644 --- a/src/web/_controller/_util/post.php +++ b/src/web/_controller/_post.php @@ -1,30 +1,22 @@ <?php /* Copyright (c) 2024 Freya Murphy */ -class Post_controller extends Controller { +class _post_controller extends XSS_Controller { - // the request model - private $request_model; + private $auth_model; - // the caceh model - private $cache_model; - - // page size - private $page_size; - - function __construct($load) { - parent::__construct($load); - $this->request_model = $this->load->model('request'); - $this->cache_model = $this->load->model('cache'); - $this->page_size = 10; + function __construct() { + parent::__construct(); + $this->auth_model = $this->load_model('auth'); + $this->load_lang('post'); } public function index(): void { - $this->view('template/posts'); + $this->view('_template/posts'); } public function post(): void { - $pid = $this->request_model->get_int('id', 0); + $pid = $this->get_int('id', 0); - $post = $this->db + $post = $this->db() ->select('p.*, l.id as like_id') ->from('api.post p') ->join('api.like l', 'p.id = l.post_id AND l.user_id') @@ -33,42 +25,37 @@ class Post_controller extends Controller { ->eq($pid) ->row(); - if (!$post) { + if (!$post) return; - } - $users = $this->cache_model->get_users([$post]); + $users = $this->model->get_users([$post]); $uid = $post['user_id']; - if (!array_key_exists($uid, $users)) { + if (!isset($users[$uid])) return; - } $user = $users[$uid]; - $data = array( - 'user' => $user, - 'page_size' => $this->page_size, - 'post' => $post - ); - $this->view('template/post', $data); + $data = $this->model->get_data(); + $data['user'] = $user; + $data['page_size'] = POST_PAGE_SIZE; + $data['post'] = $post; + $this->view('_template/post', $data); } /** * @return array<string,mixed> */ public function posts(): array { - $page = $this->request_model->get_int('page', 0); - $max = $this->request_model->get_int('max'); - $offset = $page * $this->page_size; - $filter_uid = $this->request_model->get_int('user_id', FALSE); + $page = $this->get_int('page', 0); + $max = $this->get_int('max'); + $offset = $page * POST_PAGE_SIZE; + $filter_uid = $this->get_int('user_id', FALSE); - $user = $this->main->user(); + $user = $this->auth_model->session(); $uid = isset($user) ? $user['id'] : NULL; - $query = $this->db; - - $query = $this->db + $query = $this->db() ->select('p.*, l.id as like_id') ->from('api.post p') ->join('api.like l', 'p.id = l.post_id AND l.user_id') @@ -86,23 +73,23 @@ class Post_controller extends Controller { $posts = $query ->order_by('p.id', 'DESC') - ->limit($this->page_size) + ->limit(POST_PAGE_SIZE) ->offset($offset) ->rows(); - $users = $this->cache_model->get_users($posts); + $users = $this->model->get_users($posts); $max = 0; foreach ($posts as $post) { $max = max($max, $post['id']); - $data = array(); - $data['page_size'] = $this->page_size; + $data = $this->model->get_data(); + $data['page_size'] = POST_PAGE_SIZE; $data['user'] = $users[$post['user_id']]; $data['post'] = $post; - $this->view('template/post', $data); + $this->view('_template/post', $data); } - $query = $this->db + $query = $this->db() ->select('COUNT(p.id) as pc') ->from('api.post p'); @@ -117,16 +104,17 @@ class Post_controller extends Controller { return array( 'loaded' => count($posts), 'total' => $pc, - 'page_size' => $this->page_size, + 'page_size' => POST_PAGE_SIZE, + 'max' => $max, 'filter_uid' => $filter_uid ); } public function comment(): void { - $cid = $this->request_model->get_int('id', 0); + $cid = $this->get_int('id', 0); - $comment = $this->db + $comment = $this->db() ->select('*') ->from('api.comment') ->where('id') @@ -137,7 +125,7 @@ class Post_controller extends Controller { return; } - $users = $this->cache_model->get_users([$comment]); + $users = $this->model->get_users([$comment]); $uid = $comment['user_id']; if (!array_key_exists($uid, $users)) { @@ -146,23 +134,24 @@ class Post_controller extends Controller { $user = $users[$uid]; - $data = array( - 'user' => $user, - 'comment' => $comment - ); - $this->view('template/comment', $data); + $data = $this->model->get_data(); + $data['user'] = $user; + $data['comment'] = $comment; + $this->view('_template/comment', $data); } /** * @return array<string,mixed> */ public function comments(): array { - $page = $this->request_model->get_int('page', 0); - $max = $this->request_model->get_int('max'); - $id = $this->request_model->get_int('id', 0); - $offset = $page * $this->page_size; + $page = $this->get_int('page', 0); + $max = $this->get_int('max'); + $id = $this->get_int('id', 0); + $offset = $page * COMMENT_PAGE_SIZE; + + $user = $this->auth_model->session(); - $query = $this->db + $query = $this->db() ->select('*') ->from('api.comment') ->where('post_id') @@ -177,11 +166,11 @@ class Post_controller extends Controller { $comments = $query ->order_by('id', 'ASC') - ->limit($this->page_size) + ->limit(COMMENT_PAGE_SIZE) ->offset($offset) ->rows(); - $users = $this->cache_model->get_users($comments); + $users = $this->model->get_users($comments); $max = 0; // only add this hr when not logged in @@ -190,22 +179,22 @@ class Post_controller extends Controller { if ( count($comments) && $page == 0 && - $this->main->session === NULL + $user === NULL ) { echo '<hr>'; } foreach ($comments as $comment) { $max = max($max, $comment['id']); - $data = array(); + $data = $this->model->get_data(); $data['user'] = $users[$comment['user_id']]; $data['comment'] = $comment; - $this->view('template/comment', $data); + $this->view('_template/comment', $data); } return array( 'loaded' => count($comments), - 'page_size' => $this->page_size, + 'page_size' => COMMENT_PAGE_SIZE, 'max' => $max, ); } diff --git a/src/web/_controller/_template.php b/src/web/_controller/_template.php new file mode 100644 index 0000000..9c82956 --- /dev/null +++ b/src/web/_controller/_template.php @@ -0,0 +1,21 @@ +<?php /* Copyright (c) 2024 Freya Murphy */ +class _template_controller extends XSS_Controller { + + public function toast(): void { + $msg = $this->get_string('msg') ?? ''; + $detail = $this->get_string('detail'); + $hint = $this->get_string('hint'); + $type = $this->get_string('type', 'error'); + + $data = array( + 'msg' => $msg, + 'detail' => $detail, + 'hint' => $hint, + 'type' => $type, + ); + + $this->view('_template/toast', $data); + } + +} + diff --git a/src/web/_controller/apps/auth.php b/src/web/_controller/apps/auth.php deleted file mode 100644 index 1df74da..0000000 --- a/src/web/_controller/apps/auth.php +++ /dev/null @@ -1,56 +0,0 @@ -<?php /* Copyright (c) 2024 Freya Murphy */ -class Auth_controller extends Controller { - - // the home model - private $auth_model; - - // the post controller - protected $post_controller; - - function __construct($load) { - parent::__construct($load); - $this->auth_model = $this->load->model('apps/auth'); - } - - public function index(): void { - if ($this->main->session) { - $this->redirect('/home'); - } else { - $this->redirect('/auth/login'); - } - } - - public function login(): void { - if ($this->main->session) { - $this->redirect('/home'); - } - - parent::index(); - $data = $this->auth_model->get_data(); - $this->view('head', $data); - $this->view('apps/auth/login', $data); - $this->view('footer', $data); - } - - public function logout(): void { - if ($this->main->session) { - $_SESSION['jwt'] = NULL; - } - $this->redirect('/auth/login'); - } - - public function update(): void { - if (!$this->is_ajax()) { - $this->error(400); - } - if (!isset($_POST['key']) || !isset($_POST['value'])) { - $this->error(400); - } - $key = $_POST['key']; - $value = $_POST['value']; - $_SESSION[$key] = $value; - } - -} - -?> diff --git a/src/web/_controller/apps/error.php b/src/web/_controller/apps/error.php deleted file mode 100644 index 03bbd8d..0000000 --- a/src/web/_controller/apps/error.php +++ /dev/null @@ -1,21 +0,0 @@ -<?php /* Copyright (c) 2024 Freya Murphy */ -class Error_controller extends Controller { - - private $error_model; - - function __construct($load) { - parent::__construct($load); - $this->error_model = $this->load->model('apps/error'); - } - - public function index(): void { - parent::index(); - $data = $this->error_model->get_data(); - $this->view('header', $data); - $this->view('apps/error/main', $data); - $this->view('footer', $data); - } - -} - -?> diff --git a/src/web/_controller/apps/home.php b/src/web/_controller/apps/home.php deleted file mode 100644 index c9a116d..0000000 --- a/src/web/_controller/apps/home.php +++ /dev/null @@ -1,26 +0,0 @@ -<?php /* Copyright (c) 2024 Freya Murphy */ -class Home_controller extends Controller { - - // the home model - private $home_model; - - // the post controller - protected $post_controller; - - function __construct($load) { - parent::__construct($load); - $this->home_model = $this->load->model('apps/home'); - $this->post_controller = $this->load->controller('_util/post'); - } - - public function index(): void { - parent::index(); - $data = $this->home_model->get_data(); - $this->view('header', $data); - $this->view('apps/home/main', $data); - $this->view('footer', $data); - } - -} - -?> diff --git a/src/web/_controller/apps/people.php b/src/web/_controller/apps/people.php deleted file mode 100644 index 86da3b3..0000000 --- a/src/web/_controller/apps/people.php +++ /dev/null @@ -1,48 +0,0 @@ -<?php /* Copyright (c) 2024 Freya Murphy */ -class People_controller extends Controller { - - // the people model - private $people_model; - - // format model - protected $format_model; - - function __construct($load) { - parent::__construct($load); - $this->people_model = $this->load->model('apps/people'); - $this->format_model = $this->load->model('format'); - } - - public function index(): void { - parent::index(); - $data = $this->people_model->get_data(); - $this->view('header', $data); - $this->view('apps/people/header', $data); - $this->view('apps/people/main', $data); - $this->view('apps/people/footer', $data); - $this->view('footer', $data); - } - - public function content(): void { - $data = $this->people_model->get_data(); - $this->view('apps/people/main', $data); - } - - /** - * @return array<string,mixed> - */ - public function people(): array { - $data = $this->people_model->get_users(); - - $this->view('apps/people/people', $data); - - $max = 0; - foreach ($data['users'] as $user) { - $max = max($max, $user['id']); - } - - return $data; - } -} - -?> diff --git a/src/web/_controller/apps/profile.php b/src/web/_controller/apps/profile.php deleted file mode 100644 index 9e9fca6..0000000 --- a/src/web/_controller/apps/profile.php +++ /dev/null @@ -1,44 +0,0 @@ -<?php /* Copyright (c) 2024 Freya Murphy */ -class Profile_controller extends Controller { - - // the home model - private $profile_model; - - // the format model - protected $format_model; - - // the post controller - protected $post_controller; - - // the people controller - protected $people_controller; - - function __construct($load) { - parent::__construct($load); - $this->profile_model = $this->load->model('apps/profile'); - $this->people_controller = $this->load->controller('apps/people'); - $this->format_model = $this->load->model('format'); - $this->post_controller = $this->load->controller('_util/post'); - } - - public function index(): void { - - if ($this->main->user() && !isset($_GET['id'])) { - $this->redirect('/profile?id=' . $this->main->user()['id']); - } - - parent::index(); - $data = $this->profile_model->get_data(); - - if (!$data) { - $this->error(404); - } - - $this->view('header', $data); - $this->view('apps/profile/main', $data); - $this->view('footer', $data); - } - -} - -?> diff --git a/src/web/_controller/apps/settings.php b/src/web/_controller/apps/settings.php deleted file mode 100644 index 8a409cc..0000000 --- a/src/web/_controller/apps/settings.php +++ /dev/null @@ -1,41 +0,0 @@ -<?php /* Copyright (c) 2024 Freya Murphy */ -class Settings_controller extends Controller { - - // the home model - private $settings_model; - - // the format model - protected $format_model; - - // the post controller - protected $post_controller; - - // the people controller - protected $people_controller; - - function __construct($load) { - parent::__construct($load); - $this->settings_model = $this->load->model('apps/settings'); - } - - public function index(): void { - if (!$this->main->session) { - $this->redirect('/auth/login'); - } - - parent::index(); - $data = $this->settings_model->get_data(); - - if (!$data) { - $this->error(404); - } - - $this->load->app_lang($this->main->info['lang'], 'auth'); - $this->view('header', $data); - $this->view('apps/settings/main', $data); - $this->view('footer', $data); - } - -} - -?> diff --git a/src/web/_controller/auth.php b/src/web/_controller/auth.php new file mode 100644 index 0000000..fd1931c --- /dev/null +++ b/src/web/_controller/auth.php @@ -0,0 +1,45 @@ +<?php /* Copyright (c) 2024 Freya Murphy */ +class Auth_controller extends XSS_Controller { + + private $auth_model; + + function __construct() { + parent::__construct(); + $this->auth_model = $this->load_model('auth'); + $this->load_lang('auth'); + } + + public function index(): void { + $this->load_controller('index')->index(); + } + + public function login(): void { + if ($this->auth_model->session()) + $this->redirect('/home'); + + parent::index(); + $data = $this->auth_model->get_data(); + $this->view('head', $data); + $this->view('auth/main', $data); + $this->view('footer', $data); + } + + public function logout(): void { + if ($this->auth_model->session()) + $_SESSION['jwt'] = NULL; + $this->redirect('/auth/login'); + } + + public function update(): void { + $key = $this->post_data('key'); + $value = $this->post_data('value'); + + if (!$key || !$value) + $this->error(400); + + $_SESSION[$key] = $value; + } + +} + +?> diff --git a/src/web/_controller/error.php b/src/web/_controller/error.php new file mode 100644 index 0000000..55034ba --- /dev/null +++ b/src/web/_controller/error.php @@ -0,0 +1,36 @@ +<?php /* Copyright (c) 2024 Freya Murphy */ +class Error_controller extends XSS_Controller { + + private $error_model; + + function __construct() { + parent::__construct(); + $this->error_model = $this->load_model('error'); + } + + public function index(): void { + $this->code(404); + } + + public function code($code): void { + parent::index(); + + $code = intval($code); + if ($code == 404 && rand(0, 100) > 95) + $code = 451; + if (!is_valid_status_code($code)) + $code = 404; + $msg = status_code_msg($code); + + $data = $this->error_model->get_data(); + $data['title'] = $code; + $data['msg'] = $msg; + + $this->view('header', $data); + $this->view('error/main', $data); + $this->view('footer', $data); + } + +} + +?> diff --git a/src/web/_controller/home.php b/src/web/_controller/home.php new file mode 100644 index 0000000..dc9da4d --- /dev/null +++ b/src/web/_controller/home.php @@ -0,0 +1,27 @@ +<?php /* Copyright (c) 2024 Freya Murphy */ +class Home_controller extends XSS_Controller { + + // the home model + protected $home_model; + + // the post controller + protected $post_controller; + + function __construct() { + parent::__construct(); + $this->home_model = $this->load_model('home'); + $this->post_controller = $this->load_controller('_post'); + $this->load_lang('post', 'home'); + } + + public function index(): void { + parent::index(); + $data = $this->home_model->get_data(); + $this->view('header', $data); + $this->view('home/main', $data); + $this->view('footer', $data); + } + +} + +?> diff --git a/src/web/_controller/index.php b/src/web/_controller/index.php new file mode 100644 index 0000000..0822a22 --- /dev/null +++ b/src/web/_controller/index.php @@ -0,0 +1,16 @@ +<?php /* Copyright (c) 2024 Freya Murphy */ +class Index_controller extends XSS_Controller { + + public function index(): void { + $auth_model = $this->load_model('auth'); + $session = $auth_model->session(); + + $home = $this->get_url('home'); + $login = $this->get_url('auth/login'); + + $this->redirect($session ? $home : $login); + } + +} + +?> diff --git a/src/web/_controller/modal.php b/src/web/_controller/modal.php deleted file mode 100644 index da17cca..0000000 --- a/src/web/_controller/modal.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php /* Copyright (c) 2024 Freya Murphy */ -class Modal_controller extends Controller { - - - function __construct($load) { - parent::__construct($load); - } - - /** - * @param string $name - * @param array $data - */ - private function modal($name, $data = array()): void { - $title = ucwords(lang($name . '_modal_title')); - $data['title'] = $title; - $data['content'] = $name; - $this->view('template/modal', $data); - } - - public function new_post(): void { - $this->modal('new_post'); - } - - public function about(): void { - $this->modal('about'); - } - - public function register(): void { - $this->load->app_lang( - $this->main->info['lang'], - 'auth' - ); - $this->modal('register'); - } -} - -?> - diff --git a/src/web/_controller/people.php b/src/web/_controller/people.php new file mode 100644 index 0000000..bb2db2c --- /dev/null +++ b/src/web/_controller/people.php @@ -0,0 +1,45 @@ +<?php /* Copyright (c) 2024 Freya Murphy */ +class People_controller extends XSS_Controller { + + // the people model + private $people_model; + + function __construct() { + parent::__construct(); + $this->people_model = $this->load_model('people'); + $this->load_lang('people'); + } + + public function index(): void { + parent::index(); + $data = $this->people_model->get_data(); + $this->view('header', $data); + $this->view('people/header', $data); + $this->view('people/main', $data); + $this->view('people/footer', $data); + $this->view('footer', $data); + } + + public function content(): void { + $data = $this->people_model->get_data(); + $this->view('people/main', $data); + } + + /** + * @return array<string,mixed> + */ + public function people(): array { + $data = $this->people_model->get_people(); + + $this->view('people/people', $data); + + $max = 0; + foreach ($data['users'] as $user) { + $max = max($max, $user['id']); + } + + return $data; + } +} + +?> diff --git a/src/web/_controller/profile.php b/src/web/_controller/profile.php new file mode 100644 index 0000000..dd02ed2 --- /dev/null +++ b/src/web/_controller/profile.php @@ -0,0 +1,44 @@ +<?php /* Copyright (c) 2024 Freya Murphy */ +class Profile_controller extends XSS_Controller { + + // the profile model + private $profile_model; + + // the post controller + protected $post_controller; + + // the people controller + protected $people_controller; + + function __construct() { + parent::__construct(); + $this->profile_model = $this->load_model('profile'); + $this->people_controller = $this->load_controller('people'); + $this->post_controller = $this->load_controller('_post'); + $this->load_lang('profile'); + } + + public function index(): void { + $id = $this->get_int('id'); + + parent::index(); + $data = $this->profile_model->get_data(); + + // profile does not exist + if (!$data) { + // not logged in and trying to access own profile + if (!$id) + $this->redirect('/auth/login'); + // directly accessing unknown user id => 404 + else + $this->error(404); + } + + $this->view('header', $data); + $this->view('profile/main', $data); + $this->view('footer', $data); + } + +} + +?> diff --git a/src/web/_controller/settings.php b/src/web/_controller/settings.php new file mode 100644 index 0000000..e42389f --- /dev/null +++ b/src/web/_controller/settings.php @@ -0,0 +1,34 @@ +<?php /* Copyright (c) 2024 Freya Murphy */ +class Settings_controller extends XSS_Controller { + + // the settings model + private $settings_model; + + // the auth model + private $auth_model; + + function __construct() { + parent::__construct(); + $this->settings_model = $this->load_model('settings'); + $this->auth_model = $this->load_model('auth'); + $this->load_lang('auth', 'settings'); + } + + public function index(): void { + if (!$this->auth_model->session()) + $this->redirect('/auth/login'); + + parent::index(); + $data = $this->settings_model->get_data(); + + if (!$data) + $this->error(404); + + $this->view('header', $data); + $this->view('settings/main', $data); + $this->view('footer', $data); + } + +} + +?> diff --git a/src/web/_controller/template.php b/src/web/_controller/template.php deleted file mode 100644 index 879eadc..0000000 --- a/src/web/_controller/template.php +++ /dev/null @@ -1,23 +0,0 @@ -<?php /* Copyright (c) 2024 Freya Murphy */ -class Template_controller extends Controller { - - // the request model - private $request_model; - - function __construct($load) { - parent::__construct($load); - $this->request_model = $this->load->model('request'); - } - - public function toast(): void { - $data = array( - 'msg' => $this->request_model->get_str('msg', FALSE), - 'detail' => $this->request_model->get_str('detail', FALSE), - 'hint' => $this->request_model->get_str('hint', FALSE), - 'type' => $this->request_model->get_str('type', 'error') - ); - $this->view('template/toast', $data); - } - -} - diff --git a/src/web/_model/apps/auth.php b/src/web/_model/apps/auth.php deleted file mode 100644 index c528601..0000000 --- a/src/web/_model/apps/auth.php +++ /dev/null @@ -1,13 +0,0 @@ -<?php /* Copyright (c) 2024 Freya Murphy */ -class Auth_model extends Model { - - function __construct($load) { - parent::__construct($load); - } - - public function get_data(): ?array { - $data = parent::get_data(); - $data['title'] = ucfirst(lang('login')); - return $data; - } -} diff --git a/src/web/_model/apps/error.php b/src/web/_model/apps/error.php deleted file mode 100644 index 0a08fdd..0000000 --- a/src/web/_model/apps/error.php +++ /dev/null @@ -1,31 +0,0 @@ -<?php /* Copyright (c) 2024 Freya Murphy */ -class Error_model extends Model { - - function __construct($load) { - parent::__construct($load); - } - - private function get_msg(&$data) { - if (!array_key_exists('code', $_GET)) { - http_response_code(500); - $data['msg'] = ucfirst(lang('error')); - $data['title'] = '500'; - } else { - $code = $_GET['code']; - http_response_code($code); - $data['title'] = $code; - $msg = ucfirst(lang('error_' . $code, FALSE)); - if (!$msg) { - $msg = ucfirst(lang('error')); - } - $data['msg'] = $msg; - } - } - - public function get_data(): ?array { - $data = parent::get_data(); - $this->get_msg($data); - return $data; - } -} -?> diff --git a/src/web/_model/apps/home.php b/src/web/_model/apps/home.php deleted file mode 100644 index 634bc67..0000000 --- a/src/web/_model/apps/home.php +++ /dev/null @@ -1,22 +0,0 @@ -<?php /* Copyright (c) 2024 Freya Murphy */ -class Home_model extends Model { - - function __construct($load) { - parent::__construct($load); - } - - private function get_posts(): array { - return $this->db - ->select('*') - ->from('xssbook.post') - ->limit(20) - ->rows(); - } - - public function get_data(): ?array { - $data = parent::get_data(); - $data['title'] = ucfirst(lang('title')); - $data['posts'] = $this->get_posts(); - return $data; - } -} diff --git a/src/web/_model/apps/people.php b/src/web/_model/apps/people.php deleted file mode 100644 index 08366a7..0000000 --- a/src/web/_model/apps/people.php +++ /dev/null @@ -1,90 +0,0 @@ -<?php /* Copyright (c) 2024 Freya Murphy */ -class People_model extends Model { - - private $request_model; - - function __construct($load) { - parent::__construct($load); - $this->request_model = $this->load->model('request'); - } - /** - * @param mixed $select - */ - private function get_filted_query($select): DatabaseQuery { - $filter_type = $this->request_model->get_str('filter', FALSE); - $filter_uid = $this->request_model->get_int('uid', FALSE); - $max = $this->request_model->get_int('max', FALSE); - - $query = $this->db - ->select($select) - ->from('api.user u'); - - if ($filter_type && $filter_uid) { - switch ($filter_type) { - case 'follower': { - $query = $query - ->join('xssbook.follow f', 'f.follower_id = u.id AND f.followee_id', 'INNER') - ->eq($filter_uid) - ->where('f.value = TRUE'); - } break; - - case 'followee': { - $query = $query - ->join('xssbook.follow f', 'f.followee_id = u.id AND f.follower_id', 'INNER') - ->eq($filter_uid) - ->where('f.value = TRUE'); - } break; - } - } - - if ($max) { - $query = $query - ->where('u.id') - ->le($max); - } - - return $query; - } - - /** - * @return array<string,mixed> - */ - public function get_users(): array { - $page = $this->request_model->get_int('page', 0); - $page_size = 24; - $offset = $page_size * $page; - - $users = $this->get_filted_query('u.*') - ->order_by('u.id', 'DESC') - ->offset($offset) - ->limit($page_size) - ->rows(); - - $count = $this->get_filted_query('COUNT(u.id) AS count') - ->row()['count']; - - $max = 0; - - foreach ($users as $user) { - $max = max($max, $user['id']); - } - - $filter_type = $this->request_model->get_str('filter', FALSE); - $filter_uid = $this->request_model->get_int('uid', FALSE); - - return array( - 'users' => $users, - 'count' => $count, - 'page_size' => $page_size, - 'max_id' => $max, - 'filter_type' => $filter_type || '', - 'filter_uid' => $filter_uid || '' - ); - } - - public function get_data(): ?array { - $data = parent::get_data(); - $data['title'] = ucfirst(lang('title')); - return $data; - } -} diff --git a/src/web/_model/apps/profile.php b/src/web/_model/apps/profile.php deleted file mode 100644 index acec9c0..0000000 --- a/src/web/_model/apps/profile.php +++ /dev/null @@ -1,65 +0,0 @@ -<?php /* Copyright (c) 2024 Freya Murphy */ -class Profile_model extends Model { - - private $request_model; - - function __construct($load) { - parent::__construct($load); - $this->request_model = $this->load->model('request'); - } - - public function get_data(): ?array { - $uid = $this->request_model->get_int('id', FALSE); - if ($uid === FALSE) { - if ($this->main->session) { - $uid = $this->main->user()['id']; - } else { - return NULL; - } - } - - $user = $this->db - ->select('*') - ->from('api.user u') - ->where('u.id') - ->eq($uid) - ->row(); - - if (!$user) { - return NULL; - } - - $following = FALSE; - $followed = FALSE; - $follow_id = NULL; - - if ($this->main->session) { - $sid = $this->main->user()['id']; - $res = $this->db->select('f.value, f.id') - ->from('xssbook.follow f') - ->where('f.follower_id') - ->eq($sid) - ->where('f.followee_id') - ->eq($uid) - ->row(); - $following = $res ? $res['value'] : FALSE; - $follow_id = $res ? $res['id'] : NULL; - $res = $this->db->select('f.value') - ->from('xssbook.follow f') - ->where('f.follower_id') - ->eq($uid) - ->where('f.followee_id') - ->eq($sid) - ->row(); - $followed = $res ? $res['value'] : FALSE; - } - - $data = parent::get_data(); - $data['user'] = $user; - $data['following'] = $following; - $data['followed'] = $followed; - $data['follow_id'] = $follow_id; - $data['title'] = ucfirst(lang('title', sub: [$user['first_name']])); - return $data; - } -} diff --git a/src/web/_model/apps/settings.php b/src/web/_model/apps/settings.php deleted file mode 100644 index 1f1e3f9..0000000 --- a/src/web/_model/apps/settings.php +++ /dev/null @@ -1,16 +0,0 @@ -<?php /* Copyright (c) 2024 Freya Murphy */ -class Settings_model extends Model { - - private $request_model; - - function __construct($load) { - parent::__construct($load); - $this->request_model = $this->load->model('request'); - } - - public function get_data(): ?array { - $data = parent::get_data(); - $data['title'] = ucfirst(lang('title')); - return $data; - } -} diff --git a/src/web/_model/auth.php b/src/web/_model/auth.php new file mode 100644 index 0000000..50cb367 --- /dev/null +++ b/src/web/_model/auth.php @@ -0,0 +1,42 @@ +<?php /* Copyright (c) 2024 Freya Murphy */ +class Auth_model extends XSS_Model { + + private static ?array $session = NULL; + + /** + * Loads current session + * @param string $jwt - the user provided JWT + */ + public function session(): ?array { + // check + if (self::$session) + return self::$session; + // get jwt + $jwt = $_SESSION['jwt'] ?? ''; + if (!$jwt) + return NULL; + // get session + $result = $this->db() + ->select("_api.verify_jwt(?) AS user_id;") + ->row($jwt); + // invalid JWT + if (!$result) + return NULL; + // load user inside session + $user_id = $result['user_id']; + $user = $this->db() + ->select('*') + ->from('api.user') + ->where('id') + ->eq($user_id) + ->row(); + // valid JWT, but invalid user + if (!$result) + return NULL; + // return session + self::$session = array_merge( + $user, + array('jwt' => $jwt)); + return self::$session; + } +} diff --git a/src/web/_model/cache.php b/src/web/_model/cache.php deleted file mode 100644 index 6cf9924..0000000 --- a/src/web/_model/cache.php +++ /dev/null @@ -1,37 +0,0 @@ -<?php /* Copyright (c) 2024 Freya Murphy */ -class Cache_model extends Model { - - // the user cache - private $users; - - function __construct($load) { - parent::__construct($load); - $this->users = array(); - } - - /** - * Gets a array of users - */ - public function get_users($objs) { - $ids = array(); - foreach ($objs as $obj) { - $id = $obj['user_id']; - if (!array_key_exists($id, $this->users)) { - array_push($ids, intval($id)); - } - } - if (!empty($ids)) { - $result = $this->main->db - ->select('*') - ->from('api.user') - ->where_in('id', $ids) - ->rows(); - foreach ($result as $user) { - $id = $user['id']; - $this->users[$id] = $user; - } - } - return $this->users; - } - -} diff --git a/src/web/_model/error.php b/src/web/_model/error.php new file mode 100644 index 0000000..ec376c7 --- /dev/null +++ b/src/web/_model/error.php @@ -0,0 +1,3 @@ +<?php /* Copyright (c) 2024 Freya Murphy */ +class Error_model extends XSS_Model { +} diff --git a/src/web/_model/format.php b/src/web/_model/format.php deleted file mode 100644 index d2b7316..0000000 --- a/src/web/_model/format.php +++ /dev/null @@ -1,36 +0,0 @@ -<?php /* Copyright (c) 2024 Freya Murphy */ -class Format_model extends Model { - - function __construct($load) { - parent::__construct($load); - } - - /** - * Formats a users's name - * @param array $user - the $user - * @returns the user's formatted display name - */ - public function name($user) { - $name = ''; - if ($user['first_name']) { - $name .= $user['first_name']; - } - if ($user['middle_name']) { - if ($name != '') { - $name .= ' '; - } - $name .= $user['middle_name']; - } - if ($user['last_name']) { - if ($name != '') { - $name .= ' '; - } - $name .= $user['last_name']; - } - if ($name == '') { - $name = '@' . $user['username']; - } - return $name; - } - -} diff --git a/src/web/_model/home.php b/src/web/_model/home.php new file mode 100644 index 0000000..f4a33e0 --- /dev/null +++ b/src/web/_model/home.php @@ -0,0 +1,17 @@ +<?php /* Copyright (c) 2024 Freya Murphy */ +class Home_model extends XSS_Model { + + private function get_posts(): ?array { + return $this->db() + ->select('*') + ->from('api.post') + ->limit(POST_PAGE_SIZE) + ->rows(); + } + + public function get_data(): ?array { + $data = parent::get_data(); + $data['posts'] = $this->get_posts(); + return $data; + } +} diff --git a/src/web/_model/main.php b/src/web/_model/main.php deleted file mode 100644 index cd34740..0000000 --- a/src/web/_model/main.php +++ /dev/null @@ -1,119 +0,0 @@ -<?php /* Copyright (c) 2024 Freya Murphy */ -class Main_model { - - // the website database - public $db; - - // the current user session (can be NULL) - public $session; - - // current loaded users - private $users; - - // stores the current request info - public $info; - - // tthe logged in user - private $user; - - /** - * Loads the main model - * @param Loader $load - the main loader object - */ - function __construct($load) { - /// load the database helper - $this->db = new DatabaseHelper(); - /// load the current session - if (array_key_exists('jwt', $_SESSION)) { - $this->get_session($_SESSION['jwt']); - } else { - $this->session = NULL; - }; - /// init other vars - $this->users = array(); - $this->user = NULL; - } - - /** - * Loads current session - * @param string $jwt - the user provided JWT - */ - private function get_session($jwt) { - $query = $this->db - ->select("_api.verify_jwt(?) AS user_id;"); - $result = $query->row($jwt); - $user_id = $result['user_id']; - if ($user_id) { - $this->session = array( - 'id' => $user_id, - 'jwt' => $jwt - ); - $user = $this->user(); - if ($user === FALSE) { - /// valid jwt for invalid user!!! - $this->session = NULL; - $this->user = NULL; - } - } - } - - /** - * Gets the stamp for a asset path - * @param string $path - */ - private function asset_stamp($path): int { - $root = $GLOBALS['webroot']; - $path = $root . '/../public/' . $path; - return filemtime($path); - } - - /** - * Loads a css html link - * @param string $path - the path to the css file - */ - public function link_css($path) { - $stamp = $this->asset_stamp($path); - return '<link rel="stylesheet" href="/public/' . $path . '?stamp=' . $stamp . '">'; - } - - /** - * Loads a js html link - * @param string $path - the path to the js file - */ - public function link_js($path) { - $stamp = $this->asset_stamp($path); - return '<script src="/public/'. $path . '?stamp=' . $stamp . '"></script>'; - } - - /** - * Gets the current user - */ - public function user() { - if ($this->user) { - return $this->user; - } - if ($this->session) { - $this->user = $this->db - ->select('*') - ->from('api.user') - ->where('id') - ->eq($this->session['id']) - ->row(); - return $this->user; - } - return NULL; - } - - /** - * Formats a date - * @param string $date - the data in RFC3999 format - * @returns the formatted date - */ - public function date($date) { - $date=date_create($date); - return date_format($date, "Y-m-d D H:m"); - } - -} - -?> diff --git a/src/web/_model/people.php b/src/web/_model/people.php new file mode 100644 index 0000000..bf540cf --- /dev/null +++ b/src/web/_model/people.php @@ -0,0 +1,72 @@ +<?php /* Copyright (c) 2024 Freya Murphy */ + +class People_model extends XSS_Model { + + private function get_filted_query($select): DatabaseQuery { + $filter_type = $this->get_string('filter'); + $filter_uid = $this->get_int('uid'); + $max = $this->get_int('max'); + $query = $this->db() + ->select($select) + ->from('api.user u'); + + if ($filter_type && $filter_uid) { + switch ($filter_type) { + // only show followers + case 'follower': + $query = $query + ->join('xssbook.follow f', 'f.follower_id = u.id AND f.followee_id', 'INNER') + ->eq($filter_uid) + ->where('f.value = TRUE'); + break; + // only show followees + case 'followee': + $query = $query + ->join('xssbook.follow f', 'f.followee_id = u.id AND f.follower_id', 'INNER') + ->eq($filter_uid) + ->where('f.value = TRUE'); + break; + } + } + + if ($max) { + $query = $query + ->where('u.id') + ->le($max); + } + + return $query; + } + + public function get_people(): array { + $filter_type = $this->get_string('filter'); + $filter_uid = $this->get_int('uid'); + $page = $this->get_int('page', 0); + + $page_size = PEOPLE_PAGE_SIZE; + $offset = $page_size * $page; + + $users = $this->get_filted_query('u.*') + ->order_by('u.id', 'DESC') + ->offset($offset) + ->limit($page_size) + ->rows(); + + $count = $this->get_filted_query('COUNT(u.id) AS count') + ->row()['count']; + + $max = 0; + + foreach ($users as $user) + $max = max($max, $user['id']); + + return array( + 'users' => $users, + 'count' => $count, + 'page_size' => $page_size, + 'max_id' => $max, + 'filter_type' => $filter_type, + 'filter_uid' => $filter_uid, + ); + } +} diff --git a/src/web/_model/profile.php b/src/web/_model/profile.php new file mode 100644 index 0000000..d35cc46 --- /dev/null +++ b/src/web/_model/profile.php @@ -0,0 +1,70 @@ +<?php /* Copyright (c) 2024 Freya Murphy */ +class Profile_model extends XSS_Model { + + private $auth_model; + + function __construct() { + $this->auth_model = $this->load_model('auth'); + } + + public function get_data(): ?array { + $uid = $this->get_int('id'); + $session = $this->auth_model->session(); + + if (!$uid && $session) + $uid = $session['id']; + if (!$uid) + return NULL; + + $user = $this->db() + ->select('*') + ->from('api.user u') + ->where('u.id') + ->eq($uid) + ->row(); + + if (!$user) + return NULL; + + // am i following $uid? + $following = FALSE; + $following_id = NULL; + // is $uid following me? + $followed = FALSE; + + if ($session) { + $sid = $session['id']; + // am i following $uid? + $res = $this->db() + ->select('f.value, f.id') + ->from('xssbook.follow f') + ->where('f.follower_id') + ->eq($sid) + ->where('f.followee_id') + ->eq($uid) + ->row(); + $following = $res ? $res['value'] : FALSE; + $following_id = $res ? $res['id'] : NULL; + // is $uid following me? + $res = $this->db() + ->select('f.value') + ->from('xssbook.follow f') + ->where('f.follower_id') + ->eq($uid) + ->where('f.followee_id') + ->eq($sid) + ->row(); + $followed = $res ? $res['value'] : FALSE; + } + + $data = parent::get_data(); + $data['user'] = $user; + $data['following'] = $following; + $data['following_id'] = $following_id; + $data['followed'] = $followed; + + $name = $this->format_name($user); + $data['title'] .= " - $name"; + return $data; + } +} diff --git a/src/web/_model/request.php b/src/web/_model/request.php deleted file mode 100644 index 4cce07a..0000000 --- a/src/web/_model/request.php +++ /dev/null @@ -1,40 +0,0 @@ -<?php /* Copyright (c) 2024 Freya Murphy */ -class Request_model extends Model { - - function __construct($load) { - parent::__construct($load); - } - - /** - * Loads a string from the GET request - * @param string $key - the name for the query param - * @param string $default - the default value if not exists - */ - public function get_str($key, $default = NULL): string | NULL { - if (!array_key_exists($key, $_GET)) { - return $default; - } else { - return $_GET[$key]; - } - } - - /** - * Loads a number from the GET request - * @param string $key - the name for the query param - * @param int $default - the default value if not exists - */ - public function get_int($key, $default = NULL): int | NULL { - if (!array_key_exists($key, $_GET)) { - return $default; - } else { - $val = $_GET[$key]; - $val = intval($val); - if ($val < 0) { - return 0; - } else { - return $val; - } - } - } - -} diff --git a/src/web/_model/settings.php b/src/web/_model/settings.php new file mode 100644 index 0000000..9748f26 --- /dev/null +++ b/src/web/_model/settings.php @@ -0,0 +1,3 @@ +<?php /* Copyright (c) 2024 Freya Murphy */ +class Settings_model extends XSS_Model { +} diff --git a/src/web/_views/modal/about.php b/src/web/_views/_modal/about.php index 4bc7a4f..4bc7a4f 100644 --- a/src/web/_views/modal/about.php +++ b/src/web/_views/_modal/about.php diff --git a/src/web/_views/modal/new_post.php b/src/web/_views/_modal/new_post.php index 66e6561..aff19a5 100644 --- a/src/web/_views/modal/new_post.php +++ b/src/web/_views/_modal/new_post.php @@ -1,31 +1,28 @@ <?php /* Copyright (c) 2024 Freya Murphy */ ?> <?php /* vi: syntax=php */ ?> -<?php - $user = $this->main->user(); -?> <form id="new-post-form"> <div class="modal-content new-post-modal"> <div class="row"> - <?=pfp($user)?> + <?=pfp($session)?> <div class="col ml"> - <strong><?=$user['first_name'] . ' ' . $user['last_name']?></strong> - <span class="subtext"><?=ucfirst(lang('now'))?></span> + <strong><?=$session['first_name'] . ' ' . $session['last_name']?></strong> + <span class="subtext"><?=ucfirst(lang('now'))?></span> </div> </div> <textarea type="text" name="content" id="new-post-content" - placeholder="<?=ucfirst(lang('action_new_post_text', sub: [$user['first_name']]))?>" + placeholder="<?=ucfirst(lang('action_new_post_text', sub: [$session['first_name']]))?>" ></textarea> </div> <div class="modal-footer"> - <?=ilang('action_submit', - id: 'new-post-submit', - class: 'btn btn-submit btn-alt grow', - attrs: array('type' => 'submit'), - button: TRUE - )?> + <?=ilang('action_submit', + id: 'new-post-submit', + class: 'btn btn-submit btn-alt grow', + attrs: array('type' => 'submit'), + type: 'button', + )?> </div> </form> <script> @@ -44,7 +41,7 @@ const onPost = function(data) { let id = data[0].id; $.get({ - url: '/_util/post/post?id=' + id, + url: '/_post/post?id=' + id, success: getPost }); } diff --git a/src/web/_views/modal/register.php b/src/web/_views/_modal/register.php index 5c76fe9..2126d0d 100644 --- a/src/web/_views/modal/register.php +++ b/src/web/_views/_modal/register.php @@ -125,7 +125,7 @@ id: 'register-submit', class: 'btn btn-submit btn-alt grow', attrs: array('type' => 'submit'), - button: TRUE + type: 'button', )?> </div> </form> diff --git a/src/web/_views/template/comment.php b/src/web/_views/_template/comment.php index ceac588..b947ff6 100644 --- a/src/web/_views/template/comment.php +++ b/src/web/_views/_template/comment.php @@ -1,14 +1,11 @@ <?php /* Copyright (c) 2024 Freya Murphy */ ?> <?php /* vi: syntax=php */ ?> -<?php - $format_model = $this->load->model('format'); -?> <div class="comment row mt"> <?=pfp($user)?> <div class="ml col sub-card"> <div class="row"> - <strong><?=$format_model->name($user)?></strong> - <span class="subtext ml"><?=$this->main->date($comment['created'])?></span> + <strong><?=$this->format_name($user)?></strong> + <span class="subtext ml"><?=$this->format_date($comment['created'])?></span> </div> <?=$comment['content']?> </div> diff --git a/src/web/_views/template/error.php b/src/web/_views/_template/error.php index 2e02cb1..2e02cb1 100644 --- a/src/web/_views/template/error.php +++ b/src/web/_views/_template/error.php diff --git a/src/web/_views/template/modal.php b/src/web/_views/_template/modal.php index 2a041a7..8e4545d 100644 --- a/src/web/_views/template/modal.php +++ b/src/web/_views/_template/modal.php @@ -9,6 +9,6 @@ class: 'btn btn-action modal-close', )?> </div> - <?php $this->view('modal/' . $content) ?> + <?php $this->view('_modal/' . $content, $data) ?> </div> </div> diff --git a/src/web/_views/template/post.php b/src/web/_views/_template/post.php index 48f8bb6..f7f5de2 100644 --- a/src/web/_views/template/post.php +++ b/src/web/_views/_template/post.php @@ -5,14 +5,13 @@ <?=pfp($user)?> <div class="col ml"> <strong><?=$user['first_name'] . ' ' . $user['last_name']?></strong> - <span class="subtext"><?=$this->main->date($post['created'])?></span> + <span class="subtext"><?=$this->format_date($post['created'])?></span> </div> </div> <p> <?=$post['content']?> </p> <?php - $self = $this->main->user(); $liked = $post['like_id'] ? 'btn-primary' : ''; $post_attrs = array( 'postId' => $post['id'] @@ -22,7 +21,7 @@ } ?> <span class="likes subtext"><span class="count"><?=$post['like_count']?></span><?=' ' . ucfirst(lang('likes'))?></span> -<?php if ($self): ?> +<?php if ($session): ?> <hr> <div class="row"> <?=ilang('action_like', @@ -30,7 +29,7 @@ attrs: $post_attrs )?> <?=ilang('action_comment', class: 'btn grow action-comment', - click: '$(\'#action-new-comment-' . $post['id'] . '\').focus()' + onclick: '$(\'#action-new-comment-' . $post['id'] . '\').focus()' )?> </div> <hr> @@ -46,7 +45,7 @@ $total = $post['comment_count']; if ($loaded >= $page_size && $page_size < $total) { - ilang('action_load_comments', + echo ilang('action_load_comments', class: 'action-load-comments btn btn-blend mt', attrs: array( 'postId' => $post['id'], @@ -60,9 +59,9 @@ ?> </div> -<?php if ($self): ?> +<?php if ($session): ?> <div class="row pb"> - <?=pfp($self)?> + <?=pfp($session)?> <form class="ml action-new-comment-form row"> <input type="hidden" diff --git a/src/web/_views/template/posts.php b/src/web/_views/_template/posts.php index ed79688..4202e67 100644 --- a/src/web/_views/template/posts.php +++ b/src/web/_views/_template/posts.php @@ -7,9 +7,16 @@ $total = $pdata['total']; $max = $pdata['max']; $filterUid = $pdata['filter_uid']; - +?> +<?php if ($loaded == 0): ?> + <div id="no-posts" class="card"> + <span class="no-posts-title mb"><?=lang('no_posts_found')?></span> + <span><?=random_value(explode("\n", lang('no_posts_found_ext')))?></span> + </div> +<?php endif; ?> +<?php if ($loaded >= $page_size && $page_size < $total) { - ilang('action_load_posts', + echo ilang('action_load_posts', id: 'action-load-posts', class: 'btn btn-blend grow mb mt', attrs: array( diff --git a/src/web/_views/template/toast.php b/src/web/_views/_template/toast.php index 0a6a82f..902955c 100644 --- a/src/web/_views/template/toast.php +++ b/src/web/_views/_template/toast.php @@ -3,21 +3,17 @@ <?php $params = array(); - if ($detail) { - array_push($params, lang('api_column_' . $detail)); - } + if ($detail) + $params[] = lang('api_column_' . $detail); - if ($hint) { - array_push($params, $hint); - } + if ($hint) + $params[] = $hint; - $lang_msg = lang($msg, FALSE, sub: $params); - - if(!$lang_msg) { + $lang_msg = lang($msg, '', sub: $params); + if(!$lang_msg) $lang_msg = $msg; - } else { + else $lang_msg = ucfirst($lang_msg); - } ?> <div class="toast <?=$type?>"> diff --git a/src/web/_views/apps/people/people.php b/src/web/_views/apps/people/people.php deleted file mode 100644 index 5fc0d17..0000000 --- a/src/web/_views/apps/people/people.php +++ /dev/null @@ -1,7 +0,0 @@ -<?php /* Copyright (c) 2024 Freya Murphy */ ?> -<?php /* vi: syntax=php */ ?> -<?php - foreach($users as $user) { - $this->view('apps/people/card', array('user' => $user)); - } -?> diff --git a/src/web/_views/apps/auth/login.php b/src/web/_views/auth/main.php index ac4cd02..9604770 100644 --- a/src/web/_views/apps/auth/login.php +++ b/src/web/_views/auth/main.php @@ -32,7 +32,7 @@ </div> <?=ilang('action_login', class: 'btn btn-primary btn-alt grow', - button: TRUE, + type: 'button', attrs: array('type' => 'submit') )?> <?/*=ilang('action_forgot_passwd', @@ -43,7 +43,7 @@ <?=ilang('action_create_account', id: 'action-register', class: 'btn btn-success btn-alt grow', - button: TRUE, + type: 'button', attrs: array('type' => 'submit') )?> </div> @@ -79,7 +79,7 @@ }); $('#action-register').on('click', function() { - $.get( "/modal/register", function (data) { + $.get( "/_modal/register", function (data) { $(document.body).append(data); }); }) diff --git a/src/web/_views/apps/error/main.php b/src/web/_views/error/main.php index bcc6f90..bcc6f90 100644 --- a/src/web/_views/apps/error/main.php +++ b/src/web/_views/error/main.php diff --git a/src/web/_views/head.php b/src/web/_views/head.php index cca43a1..809ab36 100644 --- a/src/web/_views/head.php +++ b/src/web/_views/head.php @@ -4,23 +4,14 @@ <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <script> - <?php if ($this->main->session): ?> - var jwtStr = <?=json_encode($this->main->session['jwt'])?>; + <?php if ($session): ?> + var jwtStr = <?=json_encode($session['jwt'])?>; <?php else: ?> var jwtStr = null; <?php endif; ?> </script> - <?php - foreach ($js_files as $js) { - echo $this->main->link_js($js); - } - foreach ($css_files as $css) { - echo $this->main->link_css($css); - } - ?> + <?=CRIMSON_META($this)?> <title><?=$title?></title> - <!-- haa haa hee hee hoo hoo --> - <script src="https://unpkg.com/@ruffle-rs/ruffle"></script> </head> <body> <div id="toast-container"> diff --git a/src/web/_views/header.php b/src/web/_views/header.php index 7315afb..4ba15ed 100644 --- a/src/web/_views/header.php +++ b/src/web/_views/header.php @@ -1,7 +1,6 @@ <?php /* Copyright (c) 2024 Freya Murphy */ ?> <?php /* vim: syntax=php */ ?> <?php - $self = $this->main->user(); $this->view('head', $data); ?> <header id="header"> @@ -11,41 +10,29 @@ <div class="center" :class="{hidden: !visible}"> <a id="action-home" - class="btn <?=$this->main->info['app'] == 'home' ? 'btn-primary btn-border' : ''?>" + class="btn <?=ROUTER->req['app'] == 'home' ? 'btn-primary btn-border' : ''?>" href="/home" - title="<?=ucfirst(lang('action_home_tip'))?>" - > + title="<?=ucfirst(lang('action_home_tip'))?>"> <i class="mi mi-lg">home</i> <span><?=ucfirst(lang('action_home_text'))?></span> </a> <a id="action-people" - class="btn <?=$this->main->info['app'] == 'people' ? 'btn-primary btn-border' : ''?>" + class="btn <?=ROUTER->req['app'] == 'people' ? 'btn-primary btn-border' : ''?>" href="/people" - title="<?=ucfirst(lang('action_people_tip'))?>" - > + title="<?=ucfirst(lang('action_people_tip'))?>"> <i class="mi mi-lg">people</i> <span><?=ucfirst(lang('action_people_text'))?></span> </a> - <!--a - id="action-chat" - class="btn <?=$this->main->info['app'] == 'chat' ? 'btn-primary btn-border' : ''?>" - href="/chat" - title="<?=lang('action_chat_tip')?>" - > - <i class="mi mi-lg">chat</i> - <span><?=lang('action_chat_text')?></span> - </a--> </div> <div class="right"> <button id="action-hamburger" title="<?=ucfirst(lang('action_hamburger_tip'))?>" - class="btn mr" - > + class="btn mr"> <i class="mi mi-lg">menu</i> </button> - <?php if($self): ?> + <?php if($session): ?> <script> var userMenu = null; @@ -53,13 +40,13 @@ userMenu.toggleClass('hidden'); } </script> - <?=pfp($self, FALSE, 'toggleUserMenu()')?> + <?=pfp($session, FALSE, 'toggleUserMenu()')?> <div class="card col hidden" id="user-menu"> <span class="user-menu-header row mr"> - <?=pfp($self, FALSE)?> + <?=pfp($session, FALSE)?> <span class="col"> - <strong><?=$this->format_model->name($self)?></strong> - <span class="subtext"><?=$self['username']?></span> + <strong><?=$this->format_name($session)?></strong> + <span class="subtext"><?=$session['username']?></span> </span> </span> <hr> @@ -67,13 +54,12 @@ 'action_profile', id: 'action-profile', class: 'btn', - href: '/profile?id=' . $self['id'] + href: '/profile?id=' . $session['id'] )?> <?=ilang( 'action_xssbook_about', id: 'action-xssbook-about', class: 'btn', - click: 'viewAbout' )?> <?=ilang( 'action_settings', @@ -94,7 +80,7 @@ </div> <script> $('#action-xssbook-about').on('click', function() { - $.get( "/modal/about", function (data) { + $.get( "/_modal/about", function (data) { $(document.body).append(data); }); }) diff --git a/src/web/_views/apps/home/main.php b/src/web/_views/home/main.php index 864034a..c9373d2 100644 --- a/src/web/_views/apps/home/main.php +++ b/src/web/_views/home/main.php @@ -1,22 +1,22 @@ <?php /* Copyright (c) 2024 Freya Murphy */ ?> <?php /* vi: syntax=php */ ?> <main id="main"> -<?php if ($self): ?> +<?php if ($session): ?> <div id="new-post" class="card"> <div class="row grow"> - <?=pfp($self)?> + <?=pfp($session)?> <a id="action-new-post" class="btn btn-alt grow ml" autocomplete="off" aria-label="<?=ucfirst(lang('action_new_post_tip'))?>" > - <?=ucfirst(lang('action_new_post_text', sub: [$self['first_name']]))?> + <?=ucfirst(lang('action_new_post_text', sub: [$session['first_name']]))?> </a> </div> <script> $('#action-new-post').on('click', function() { - $.get( "/modal/new_post", function (data) { + $.get( "/_modal/new_post", function (data) { $(document.body).append(data); }); }) diff --git a/src/web/_views/apps/people/card.php b/src/web/_views/people/card.php index 93b1350..7e040ba 100644 --- a/src/web/_views/apps/people/card.php +++ b/src/web/_views/people/card.php @@ -7,7 +7,7 @@ <div class="col"> <?=pfp($user, FALSE)?> <div class="col ml"> - <span class="name"><?=$this->format_model->name($user)?></span> + <span class="name"><?=$this->format_name($user)?></span> <span class="subtext"><?=$user['username']?></span> </div> </div> diff --git a/src/web/_views/apps/people/footer.php b/src/web/_views/people/footer.php index f18e031..f18e031 100644 --- a/src/web/_views/apps/people/footer.php +++ b/src/web/_views/people/footer.php diff --git a/src/web/_views/apps/people/header.php b/src/web/_views/people/header.php index b1099ec..b1099ec 100644 --- a/src/web/_views/apps/people/header.php +++ b/src/web/_views/people/header.php diff --git a/src/web/_views/apps/people/main.php b/src/web/_views/people/main.php index ec84ab9..c602b2c 100644 --- a/src/web/_views/apps/people/main.php +++ b/src/web/_views/people/main.php @@ -1,18 +1,22 @@ <?php /* Copyright (c) 2024 Freya Murphy */ ?> -<?php /* vi: syntax=php */ ?> <div id="people-container" class="col"> -<?php - $pdata = $this->people(); -?> + <?php $pdata = $this->people(); ?> </div> <?php + $loaded = count($pdata['users']); $page_size = $pdata['page_size']; $total = $pdata['count']; $max = $pdata['max_id']; $filter_uid = $pdata['filter_uid']; $filer_type = $pdata['filter_type']; + ?> +<?php if ($loaded == 0): ?> + <div id="no-people" class="card"> + <?=lang('no_people_found')?> + </div> +<?php endif; ?> <?php if ($loaded >= $page_size && $page_size < $total): ?> <?=ilang('action_load_users', id: 'action-load-users', diff --git a/src/web/_views/people/people.php b/src/web/_views/people/people.php new file mode 100644 index 0000000..8726f1d --- /dev/null +++ b/src/web/_views/people/people.php @@ -0,0 +1,5 @@ +<?php /* Copyright (c) 2024 Freya Murphy */ +foreach($users as $user) { + $this->view('people/card', array('user' => $user)); +} +?> diff --git a/src/web/_views/apps/profile/main.php b/src/web/_views/profile/main.php index b2ad496..3e7129c 100644 --- a/src/web/_views/apps/profile/main.php +++ b/src/web/_views/profile/main.php @@ -11,47 +11,47 @@ <div class="col content grow"> <div class="row grow"> <div class="col mb"> - <strong class="name"><?=$this->format_model->name($user)?></strong> + <strong class="name"><?=$this->format_name($user)?></strong> <span class="subtext"><?=$user['follower_count'] . ' ' . ucfirst(lang('followers'))?></span> </div> <?php if ( - $this->main->session && - (!isset($self) || $self['id'] != $user['id']) + $session && + ($session['id'] != $user['id']) ): ?> <div class="follow"> <?=ilang( 'action_follow', id: 'action-follow-follow', class: 'btn btn-alt', + sub: [$user['first_name']], style: (!$following && !$followed) ? '' : 'display: none', - sub: [$user['first_name']] )?> <?=ilang( 'action_follow_back', id: 'action-follow-follow-back', class: 'btn btn-alt', + sub: [$user['first_name']], style: (!$following && $followed) ? '' : 'display: none', - sub: [$user['first_name']] )?> <?=ilang( 'action_following', id: 'action-follow-following', class: 'btn btn-alt btn-primary', + sub: [$user['first_name']], style: ($following && !$followed) ? '' : 'display: none', - sub: [$user['first_name']] )?> <?=ilang( 'action_friends', id: 'action-follow-friends', class: 'btn btn-alt btn-primary', + sub: [$user['first_name']], style: ($following && $followed) ? '' : 'display: none', - sub: [$user['first_name']] )?> </div> <script> let following = <?=json_encode($following)?>; + let followingId = <?=json_encode($following_id)?>; let followed = <?=json_encode($followed)?>; - let followId = <?=json_encode($follow_id)?>; let followee_id = <?=json_encode($user['id'])?>; let btns = {}; @@ -84,15 +84,15 @@ } const onPostFollow = (data) => { - followId = data[0].id; + followingId = data[0].id; following = true; updateFollow(); } const onClickFollow = () => { - if (followId) { + if (followingId) { $.ajax({ - url: '/api/follow?id=eq.' + followId, + url: '/api/follow?id=eq.' + followingId, method: 'PATCH', data: JSON.stringify({ followee_id, value: !following }), success: onPatchFollow @@ -181,7 +181,7 @@ </tr> <tr> <td><strong><?=ucfirst(lang('about_general_birth_date'))?></strong></td> - <td><?=$this->main->date($user['birth_date'])?></td> + <td><?=$this->format_date($user['birth_date'])?></td> </tr> </table> <h1><?=ucfirst(lang('about_stats'))?></h1> @@ -204,11 +204,11 @@ </tr> <tr> <td><strong><?=ucfirst(lang('about_stats_joined'))?></strong></td> - <td><?=$this->main->date($user['created'])?></td> + <td><?=$this->format_date($user['created'])?></td> </tr> <tr> <td><strong><?=ucfirst(lang('about_stats_seen'))?></strong></td> - <td><?=$this->main->date($user['seen'])?></td> + <td><?=$this->format_date($user['seen'])?></td> </tr> </table> </div> diff --git a/src/web/_views/apps/settings/main.php b/src/web/_views/settings/main.php index 2033acc..4401fe1 100644 --- a/src/web/_views/apps/settings/main.php +++ b/src/web/_views/settings/main.php @@ -1,9 +1,6 @@ -<?php /* Copyright (c) 2024 Freya Murphy */ ?> -<?php /* vi: syntax=php */ ?> +<?php /* Copyright (c) 2024 Freya Murphy */ -<?php - -$user = $this->main->user(); +$user = $session; function __create_form($user, $col) { $ph = ucfirst(lang('ph_' . $col)); diff --git a/src/web/config.php b/src/web/config.php new file mode 100644 index 0000000..3ca2bbd --- /dev/null +++ b/src/web/config.php @@ -0,0 +1,56 @@ +<?php /* Copyright (c) 2024 Freya Murphy */ + +// CONFIG +// config values needed across the website +// +// domain - the default domain for the website +// +// allowed_hosts - accepted domains to use for the website +// +// base_path - the base path the website is located at +// +// theme_color - html hex color used for browser metadata +// +// routes - array of regex keys that match the request path and +// - place it with the value if it matches +// - e.g. '' => 'home' sends / to /home +// +// style - single or list of css styles to load on specific routes +// +// js - single or list of js script to load on specific routes +// +// autoload - list of directories to autoload all PHP files in them +// +define('SITE_CONFIG', array( + /* core settings */ + 'domain' => 'xssbook.com', + 'allowed_hosts' => ['xssbook.com'], + 'base_path' => '/', + 'theme_color' => '#1778f2', + /* route overides */ + 'routes' => array( + 'manifest.json' => '_meta/manifest', + ), + /* css to load on each route */ + 'style' => array( + '' => 'css/common.css', + 'home' => ['css/home.css', 'css/post.css'], + 'auth' => 'css/auth.css', + 'people' => 'css/people.css', + 'profile' => ['css/profile.css', 'css/people.css', 'css/post.css'], + 'settings' => 'css/settings.css', + 'error' => 'css/error.css', + ), + /* js to load on each route */ + 'js' => array( + '' => ['js/thirdparty/jquery.min.js', 'js/lib.js', 'js/modal.js'], + 'home' => 'js/post.js', + 'profile' => 'js/post.js', + ), + /* directories to autoload php code */ + 'autoload' => array('/lib'), +)); + +define('POST_PAGE_SIZE', 10); +define('COMMENT_PAGE_SIZE', 5); +define('PEOPLE_PAGE_SIZE', 24); diff --git a/src/web/config/aesthetic.php b/src/web/config/aesthetic.php deleted file mode 100644 index 5a66660..0000000 --- a/src/web/config/aesthetic.php +++ /dev/null @@ -1,83 +0,0 @@ -<?php /* Copyright (c) 2024 Freya Murphy */ -class Aesthetic { - - private $config; - - function __construct() { - $this->config = array( - '_common' => array( - 'js' => [ - 'js/thirdparty/jquery.min.js', - 'js/lib.js', - 'js/modal.js', - ], - 'css' => [ - 'css/common.css' - ], - ), - 'error' => array( - 'css' => [ - 'css/error.css' - ], - ), - 'home' => array( - 'js' => [ - 'js/post.js', - ], - 'css' => [ - 'css/home.css', - 'css/post.css' - ], - ), - 'auth' => array( - 'css' => [ - 'css/auth.css' - ], - ), - 'people' => array( - 'css' => [ - 'css/people.css' - ], - ), - 'profile' => array( - 'js' => [ - 'js/post.js', - ], - 'css' => [ - 'css/profile.css', - 'css/people.css', - 'css/post.css' - ], - ), - 'settings' => array( - 'css' => [ - 'css/settings.css' - ] - ), - ); - } - /** - * @param mixed $route - * @return array<string,> - */ - function get_files($route): array { - $js_files = $this->config['_common']['js']; - $css_files = $this->config['_common']['css']; - - if (array_key_exists($route, $this->config)) { - $config = $this->config[$route]; - if (array_key_exists('js', $config)) { - $js_files = array_merge($js_files, $config['js']); - } - if (array_key_exists('css', $config)) { - $css_files = array_merge($css_files, $config['css']); - } - } - - return array( - 'js_files' => $js_files, - 'css_files' => $css_files, - ); - } - -} diff --git a/src/web/config/routes.php b/src/web/config/routes.php deleted file mode 100644 index 20b499a..0000000 --- a/src/web/config/routes.php +++ /dev/null @@ -1,12 +0,0 @@ -<?php /* Copyright (c) 2024 Freya Murphy */ - -$routes = array(); -$routes['home'] = 'apps/home'; -$routes['error'] = 'apps/error'; -$routes['auth'] = 'apps/auth'; -$routes['people'] = 'apps/people'; -$routes['profile'] = 'apps/profile'; -$routes['settings'] = 'apps/settings'; - -$routes[''] = '_index'; -$routes['manifest.json'] = '_meta/manifest'; diff --git a/src/web/core/_controller.php b/src/web/core/_controller.php deleted file mode 100644 index 3502ea5..0000000 --- a/src/web/core/_controller.php +++ /dev/null @@ -1,69 +0,0 @@ -<?php /* Copyright (c) 2024 Freya Murphy */ -abstract class Controller { - - // the main model - public $main; - - // the loader - public $load; - - // the database - public $db; - - // the format model - protected $format_model; - - /** - * Creates a constructor - * @param Loader $load - the website loaded object - */ - function __construct($load) { - $this->load = $load; - $this->main = $this->load->model('main'); - $this->db = $this->main->db; - - $info = $this->main->info; - $lang = $info['lang']; - $this->load->lang($lang); - $app = $info['app']; - if ($app) { - $this->load->app_lang($lang, $app); - } - - $this->format_model = $this->load->model('format'); - } - - public function index() {} - - public function redirect($link) { - header('Location: '. $link, true, 301); - die(); - } - - protected function view($__name, $data = array()) { - $__root = $GLOBALS['webroot']; - $__path = $__root . '/_views/' . $__name . '.php'; - if (is_file($__path)) { - extract($data); - require($__path); - return; - } - } - - protected function is_ajax(): bool { - $_POST = json_decode( - file_get_contents("php://input"), true - ); - return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest'; - } - - protected function error($code): void { - $_GET['code'] = $code; - $this->main->info['app'] = 'error'; - $error_controller = $this->load->controller('apps/error'); - $error_controller->index(); - die(); - } - -} -?> diff --git a/src/web/core/_model.php b/src/web/core/_model.php deleted file mode 100644 index dfc7163..0000000 --- a/src/web/core/_model.php +++ /dev/null @@ -1,44 +0,0 @@ -<?php /* Copyright (c) 2024 Freya Murphy */ -abstract class Model { - // the main model - // shared by all controllers and models - public $main; - public $load; - - // the database - public $db; - - private $config; - - /** - * Creates a model - * @param Loader $load - the main loader object - */ - function __construct($load) { - $this->load = $load; - $this->main = $this->load->model('main'); - $this->db = $this->main->db; - $this->config = new Aesthetic(); - } - - /** - * @returns the base model data - */ - public function get_data(): ?array { - $data = array(); - $data['self'] = $this->main->user(); - - $info = $this->main->info; - $app = $info['app']; - - if ($app) { - $files = $this->config->get_files($app); - $data = array_merge($data, $files); - } else { - $files = $this->config->get_files(); - $data = array_merge($data, $files); - } - - return $data; - } -} diff --git a/src/web/core/database.php b/src/web/core/database.php deleted file mode 100644 index 25cb5ba..0000000 --- a/src/web/core/database.php +++ /dev/null @@ -1,282 +0,0 @@ -<?php /* Copyright (c) 2024 Freya Murphy */ - -class DatabaseQuery { - - private $conn; - private $query; - - private $where; - private $set; - - private $param; - - function __construct($conn) { - $this->conn = $conn; - $this->query = ''; - - $this->set = FALSE; - $this->where = FALSE; - $this->param = array(); - } - - /// - /// ARBITRARY QUERY - /// - - public function query($query) { - $this->query .= $query; - return $this; - } - - /// - /// SELECT - /// - - public function select($select) { - $this->query .= "SELECT $select\n"; - return $this; - } - - public function from($from) { - $this->query .= "FROM $from\n"; - return $this; - } - - /// - /// INSERT - /// - - public function insert_into($insert, ...$columns) { - $this->query .= "INSERT INTO $insert\n ("; - foreach ($columns as $idx => $column) { - if ($idx !== 0) { - $this->query .= ","; - } - $this->query .= $column; - } - $this->query .= ")\n"; - return $this; - } - - public function values(...$values) { - $this->query .= "VALUES ("; - foreach ($values as $idx => $value) { - if ($idx !== 0) { - $this->query .= ","; - } - $this->query .= "?"; - array_push($this->param, $value); - } - $this->query .= ")\n"; - return $this; - } - - /// - /// WHERE - /// - - public function where($cond) { - if (!$this->where) { - $this->where = TRUE; - $this->query .= "WHERE "; - } else { - $this->query .= "AND "; - } - $this->query .= "$cond "; - return $this; - } - - public function where_in($column, $array) { - if (!$this->where) { - $this->where = TRUE; - $this->query .= "WHERE "; - } else { - $this->query .= "AND "; - } - if (empty($array)) { - $this->query .= "FALSE\n"; - return $this; - } - $in = $this->in($array); - $this->query .= "$column $in\n"; - return $this; - } - - private function in($array) { - $in = 'IN ('; - foreach ($array as $idx => $item) { - if ($idx != 0) { - $in .= ","; - } - $in .= "?"; - array_push($this->param, $item); - } - $in .= ")"; - return $in; - } - - /// - /// OPERATORS - /// - - public function like($item) { - $this->query .= "LIKE ?\n"; - array_push($this->param, $item); - return $this; - } - - public function eq($item) { - $this->query .= "= ?\n"; - array_push($this->param, $item); - return $this; - } - - public function ne($item) { - $this->query .= "<> ?\n"; - array_push($this->param, $item); - return $this; - } - - public function lt($item) { - $this->query .= "< ?\n"; - array_push($this->param, $item); - return $this; - } - - public function le($item) { - $this->query .= "<= ?\n"; - array_push($this->param, $item); - return $this; - } - - /// - /// JOINS - /// - - public function join($table, $on, $type = 'LEFT') { - $this->query .= "$type JOIN $table ON $on\n"; - return $this; - } - - /// - /// LIMIT, OFFSET, ORDER - /// - - public function limit($limit) { - $this->query .= "LIMIT ?\n"; - array_push($this->param, $limit); - return $this; - } - - public function offset($offset) { - $this->query .= "OFFSET ?\n"; - array_push($this->param, $offset); - return $this; - } - - public function order_by($column, $order = 'ASC') { - $this->query .= "ORDER BY " . $column . ' ' . $order . ' '; - return $this; - } - - /// - /// COLLECT - /// - - public function rows(...$params) { - $args = $this->param; - foreach ($params as $param) { - array_push($args, $param); - } - $stmt = $this->conn->prepare($this->query); - try { - $stmt->execute($args); - } catch (Exception $ex) { - echo $ex; - echo '<br> >> caused by <<<br>'; - echo str_replace("\n", "<br>", $this->query); - } - return $stmt->fetchAll(PDO::FETCH_ASSOC); - } - - public function row(...$params) { - $args = $this->param; - foreach ($params as $param) { - array_push($args, $param); - } - $stmt = $this->conn->prepare($this->query); - $stmt->execute($args); - return $stmt->fetch(PDO::FETCH_ASSOC); - } - - public function execute(...$params) { - $args = $this->param; - foreach ($params as $param) { - array_push($args, $param); - } - $stmt = $this->conn->prepare($this->query); - try { - $stmt->execute($args); - return TRUE; - } catch (Exception $_e) { - echo $_e; - echo '<br> >> caused by <<<br>'; - echo str_replace("\n", "<br>", $this->query); - return FALSE; - } - } -} - -/** - * DatabaseHelper - * allows queries on the - * postgres database - */ -class DatabaseHelper { - - private $conn; - - function __construct() { - $this->conn = NULL; - } - - private function connect() { - if ($this->conn === NULL) { - $user = getenv("POSTGRES_USER"); - $pass = getenv("POSTGRES_PASSWORD"); - $db = getenv("POSTGRES_DB"); - $host = 'db'; - $port = '5432'; - - $conn_str = sprintf("pgsql:host=%s;port=%d;dbname=%s;user=%s;password=%s", - $host, - $port, - $db, - $user, - $pass - ); - $this->conn = new \PDO($conn_str); - $this->conn->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); - } - return $this->conn; - } - - public function select($select) { - $conn = $this->connect(); - $query = new DatabaseQuery($conn); - return $query->select($select); - } - - public function insert_into($insert, ...$columns) { - $conn = $this->connect(); - $query = new DatabaseQuery($conn); - return $query->insert_into($insert, ...$columns); - } - - public function query($query_str) { - $conn = $this->connect(); - $query = new DatabaseQuery($conn); - return $query->query($query_str); - } -} - diff --git a/src/web/core/loader.php b/src/web/core/loader.php deleted file mode 100644 index 2091533..0000000 --- a/src/web/core/loader.php +++ /dev/null @@ -1,101 +0,0 @@ -<?php /* Copyright (c) 2024 Freya Murphy */ -class Loader { - - // keep track of what has been loaded - private $loaded; - - function __construct() { - $this->loaded = array(); - } - - /** - * Loads a $type of object from a $dir with a given $name - * @param string $name - the name of the object to load - * @param string $dir - the directory theese objects are stored in - * @param string $type - the type of the object - */ - private function load_type($name, $dir, $type): object|NULL { - $path = $dir . '/' . $name . '.php'; - if (array_key_exists($path, $this->loaded)) { - return $this->loaded[$path]; - } - - if (!file_exists($path)) { - return NULL; - } - - $parts = explode('/', $name); - $part = end($parts); - $class = ucfirst($part) . '_' . $type; - require($path); - - $ref = NULL; - try { - $ref = new ReflectionClass($class); - } catch (Exception $_e) {} - - if ($ref === NULL) { - return NULL; - } - - $obj = $ref->newInstance($this); - $this->loaded[$path] = $obj; - - return $obj; - } - - /** - * Loads a model - * @param string $name - the name of the model to load - */ - public function model($name): object|NULL { - $root = $GLOBALS['webroot']; - $dir = $root . '/_model'; - return $this->load_type($name, $dir, 'model'); - } - - /** - * Loads a controller - * @param string $name - the name of the controller to load - */ - public function controller($name): Controller|NULL { - $root = $GLOBALS['webroot']; - $dir = $root . '/_controller'; - return $this->load_type($name, $dir, 'controller'); - } - - /** - * Loads the given common lang - * @param string $lang_code 0 the language code - */ - public function lang($lang_code): void { - $dir = $GLOBALS['webroot'] . '/lang/' . $lang_code . '/'; - $lang = $GLOBALS['lang']; - if ($handle = opendir($dir)) { - while (false !== ($entry = readdir($handle))) { - if ($entry === '.' || $entry === '..' || $entry === 'apps') { - continue; - } - $path = $dir . $entry; - require($path); - } - } - $GLOBALS['lang'] = $lang; - } - - /** - * Loads a given app specific lang - * @param string $lang_code - the language code - * @param string $name - the name of the app - */ - public function app_lang($lang_code, $name): void { - $dir = $GLOBALS['webroot'] . '/lang/' . $lang_code . '/apps/'; - $file = $dir . $name . '.php'; - if (file_exists($file)) { - $lang = $GLOBALS['lang']; - require($dir . $name . '.php'); - $GLOBALS['lang'] = $lang; - } - } - -} diff --git a/src/web/core/router.php b/src/web/core/router.php deleted file mode 100644 index 557665b..0000000 --- a/src/web/core/router.php +++ /dev/null @@ -1,159 +0,0 @@ -<?php /* Copyright (c) 2024 Freya Murphy */ -class Router { - - // the loader - private $load; - - // the main model - private $main; - - /** - * Creates a router - * @param Loader $load - the main laoder object - */ - function __construct($load) { - $this->load = $load; - $this->main = $this->load->model('main'); - } - - /** - * @param string $path - the current request path - * Gets the current route - * @return array<string,mixed> - */ - private function get_req_route($path): array { - // trim the path - $path = trim($path); - // remove first '/' - $path = substr($path, 1); - // get path parts - $parts = explode('/', $path); - - $len = count($parts); - - // get route info - $route = array(); - // e.g. / - if ($path === '') { - $route = array( - 'route' => '', - 'slug' => 'index', - ); - // e.g. /home /login - } else if ($len === 1) { - $route = array( - 'route' => $parts[0], - 'slug' => 'index', - ); - // e.g. /home/posts - } else { - $route = array ( - 'route' => implode('/', array_slice($parts, 0, -1)), - 'slug' => end($parts) - ); - }; - - $route['app'] = $route['route']; - $routes = $GLOBALS['routes']; - if (array_key_exists($route['route'], $routes)) { - $route['route'] = $routes[$route['route']]; - } - - return $route; - } - - /** - * Gets the curret request info - * @return array<string,mixed> - */ - private function get_req(): array|bool { - $method = $_SERVER['REQUEST_METHOD']; - - $uri = parse_url($_SERVER['REQUEST_URI']); - if (!$uri) { - return FALSE; - } - - $path = $uri['path']; - - return array_merge( - array( - 'uri' => $uri, - 'method' => $method, - 'lang' => $this->get_lang(), - ), - $this->get_req_route($path), - ); - } - - /** - * Gets the current language - * @return string - */ - private function get_lang(): string { - return 'en_US'; - } - - /** - * Handles a router error code - * @param int $code - the http error code - * @param bool $recursed - */ - private function handle_error($code, $recursed): void { - if ($recursed) { - die($code . ' (recursed)'); - } - - $this->main->info = array(); - $this->main->info['slug'] = 'index'; - $this->main->info['app'] = 'error'; - $this->main->info['route'] = 'apps/error'; - $this->main->info['lang'] = $this->get_lang(); - $req = $this->main->info; - $_GET['code'] = $code; - - $this->handle_req($req, TRUE); - } - - /** - * @param array $req - * @param bool $recursed - */ - private function handle_req($req, $recursed = FALSE): void { - - if ($req === FALSE) { - $this->handle_error(500, $recursed); - return; - } - - $controller = $this->load->controller($req['route']); - - if ($controller === NULL) { - $this->handle_error(404, $recursed); - return; - } - - $ref = NULL; - try { - $ref = new ReflectionMethod($controller, $req['slug']); - } catch (Exception $_e) {} - - if ($ref === NULL || !$ref->isPublic()) { - $this->handle_error(404, $recursed); - return; - - } - - $ref->invoke($controller); - } - - /** - * Handels the incomming reuqest - */ - public function handle_request(): void { - $req = $this->get_req(); - $this->main->info = $req; - $this->handle_req($req); - } - -} diff --git a/src/web/helper/error.php b/src/web/helper/error.php deleted file mode 100644 index 2b6959e..0000000 --- a/src/web/helper/error.php +++ /dev/null @@ -1,9 +0,0 @@ -<?php /* Copyright (c) 2024 Freya Murphy */ - -function error_page($code, $msg) { - $root = $GLOBALS['webroot']; - error_reporting(E_ERROR | E_PARSE); - http_response_code($code); - require($root . '/_views/template/error.php'); - die(); -} diff --git a/src/web/helper/lang.php b/src/web/helper/lang.php deleted file mode 100644 index 3397d63..0000000 --- a/src/web/helper/lang.php +++ /dev/null @@ -1,81 +0,0 @@ -<?php /* Copyright (c) 2024 Freya Murphy */ -$lang = array(); - -function lang($key, $default = NULL, $sub = NULL) { - $lang = $GLOBALS['lang']; - if(array_key_exists($key, $lang)) { - if ($sub) { - return sprintf($lang[$key], ...$sub); - } else { - return $lang[$key]; - } - } else if ($default !== NULL) { - return $default; - } else { - return $key; - } -} - -function ilang($key, - $class = NULL, - $style = NULL, - $id = NULL, - $href = NULL, - $click = NULL, - $attrs = array(), - $sub = NULL, - $button = FALSE, -) { - $text = ucfirst(lang($key . "_text", FALSE, sub: $sub)); - $tip = lang($key . "_tip", FALSE, sub: $sub); - $icon = lang($key . "_icon", FALSE); - $content = lang($key . "_content", FALSE); - - if ($click || $button) { - echo '<button '; - } else { - echo '<a '; - } - if ($tip) { - echo 'title="' . $tip . '" '; - echo 'aria-label="' . $tip . '" '; - } - if ($class) { - echo 'class="' . $class . '" '; - } - if ($style) { - echo 'style="' . $style . '" '; - } - if ($id) { - echo 'id="' . $id . '" '; - } - if ($click) { - echo 'onclick="' . $click . '" '; - } - if ($href) { - echo 'href="' . $href . '" '; - } - foreach ($attrs as $key => $attr) { - echo $key . '="' . $attr . '" '; - } - echo '> '; - if ($icon) { - echo '<i class="' . $icon . '">'; - if ($content) { - echo $content; - } - echo '</i>'; - } - if ($text) { - echo '<span'; - if ($icon) { - echo ' style="margin-left: .5em;"'; - } - echo '>' . $text . '</span>'; - } - if ($click || $button) { - echo '</button>'; - } else { - echo '</a>'; - } -} diff --git a/src/web/index.php b/src/web/index.php deleted file mode 100644 index 75c1b62..0000000 --- a/src/web/index.php +++ /dev/null @@ -1,46 +0,0 @@ -<?php /* Copyright (c) 2024 Freya Murphy */ - -$webroot = dirname(__FILE__); - -// load all the helper files -require($webroot . '/helper/image.php'); -require($webroot . '/helper/error.php'); -require($webroot . '/helper/lang.php'); - -// load all the config files -require($webroot . '/config/aesthetic.php'); -require($webroot . '/config/routes.php'); - -// load all core files -require($webroot . '/core/_controller.php'); -require($webroot . '/core/_model.php'); -require($webroot . '/core/database.php'); -require($webroot . '/core/loader.php'); -require($webroot . '/core/router.php'); - -session_save_path('/var/lib/php/session'); -session_start(); -setcookie( - session_name(), - session_id(), - array( - 'expires' => time() + 60*60*24*7, - 'path' => '/', - 'domain' => NULL, - 'secure' => FALSE, - 'httponly' => FALSE, - 'samesite' => 'Lax' - ) -); - -function __init() { - $load = new Loader(); - $router = new Router($load); - $router->handle_request(); -}; - -if (!file_exists('/status/ready')) { - error_page(503, 'Service Unavailable'); -} - -__init(); diff --git a/src/web/lang/en_US/api_lang.php b/src/web/lang/api.php index bc118dd..123052e 100644 --- a/src/web/lang/en_US/api_lang.php +++ b/src/web/lang/api.php @@ -29,5 +29,3 @@ $lang['api_unknown'] = 'An unknown error as occurred'; // toast messages $lang['toast_date_empty'] = 'Birthday cannot be empty'; - -?> diff --git a/src/web/lang/en_US/apps/auth.php b/src/web/lang/auth.php index fb9d758..b87ddd7 100644 --- a/src/web/lang/en_US/apps/auth.php +++ b/src/web/lang/auth.php @@ -1,4 +1,4 @@ -<?php +<?php /* Copyright (c) 2024 Freya Murphy */ $lang['login'] = 'Login'; $lang['login_branding'] = 'Connect with javascript and the world around you on XSSBook.'; @@ -30,5 +30,3 @@ $lang['action_forgot_passwd_text'] = 'Forgot password?'; $lang['register_modal_title'] = 'Create New Account'; $lang['action_register_text'] = 'Register'; $lang['action_register_tip'] = 'Register'; - -?> diff --git a/src/web/lang/en_US/common_lang.php b/src/web/lang/common.php index 073229f..8ed1df7 100644 --- a/src/web/lang/en_US/common_lang.php +++ b/src/web/lang/common.php @@ -1,9 +1,21 @@ <?php /* Copyright (c) 2024 Freya Murphy */ -$lang['version'] = 'Version 2.0.8'; +$lang['version'] = 'Version 2.1.0'; $lang['copyright'] = 'Freya Murphy © 2024'; -// Navigation Bar Lang +// Defaults +$lang['title'] = ''; + +// General +$lang['xssbook'] = 'XSSBook'; +$lang['action_submit_text'] = 'Submit'; +$lang['action_submit_tip'] = 'Submit'; +$lang['action_close_text'] = ''; +$lang['action_close_tip'] = 'Close'; +$lang['action_close_icon'] = 'mi mi-sm'; +$lang['action_close_content'] = 'close'; + +// Header $lang['action_home_text'] = 'Home'; $lang['action_home_tip'] = 'Goto your home page.'; $lang['action_people_text'] = 'People'; @@ -15,38 +27,13 @@ $lang['action_hamburger_tip'] = 'View header dropdown.'; $lang['action_login_text'] = 'Login'; $lang['action_login_tip'] = 'Login or signup'; -// Post lang -$lang['action_like_text'] = 'Like'; -$lang['action_like_tip'] = 'Like this post.'; -$lang['action_like_icon'] = 'mi mi-sm'; -$lang['action_like_content'] = 'thumb_up'; -$lang['action_comment_text'] = 'Comment'; -$lang['action_comment_tip'] = 'Focus the comment box.'; -$lang['action_comment_icon'] = 'mi mi-sm'; -$lang['action_comment_content'] = 'comment'; -$lang['action_new_comment_text'] = 'Write a comment'; -$lang['action_new_comment_tip'] = 'Write a comment, then press enter to submit.'; -$lang['action_load_comments_text'] = 'Load more comments'; -$lang['action_load_comments_tip'] = 'Load more comments'; - -// General -$lang['action_submit_text'] = 'Submit'; -$lang['action_submit_tip'] = 'Submit'; -$lang['action_close_text'] = ''; -$lang['action_close_tip'] = 'Close'; -$lang['action_close_icon'] = 'mi mi-sm'; -$lang['action_close_content'] = 'close'; - -// Modals +// Modal $lang['action_modal_close_text'] = ''; $lang['action_modal_close_tip'] = 'Close modal.'; $lang['action_modal_close_icon'] = 'mi mi-sm'; $lang['action_modal_close_content'] = 'close'; -$lang['new_post_modal_title'] = 'Author New Post'; -$lang['action_new_post_text'] = 'What\'s on your mind, %s'; -$lang['action_new_post_tip'] = 'Author a new post.'; - +// About Modal $lang['about_modal_title'] = 'XSSBook'; // User Menu diff --git a/src/web/lang/en_US/error_lang.php b/src/web/lang/en_US/error_lang.php deleted file mode 100644 index afecaa1..0000000 --- a/src/web/lang/en_US/error_lang.php +++ /dev/null @@ -1,8 +0,0 @@ -<?php /* Copyright (c) 2024 Freya Murphy */ - -$lang['error_400'] = 'Bad request'; -$lang['error_404'] = 'Resource not found'; -$lang['error_500'] = 'Whoops! Server error :('; -$lang['error'] = 'An unknown error has occoured'; - -?> diff --git a/src/web/lang/en_US/apps/home.php b/src/web/lang/home.php index a30eb88..a8bf849 100644 --- a/src/web/lang/en_US/apps/home.php +++ b/src/web/lang/home.php @@ -1,9 +1,7 @@ -<?php +<?php /* Copyright (c) 2024 Freya Murphy */ $lang['title'] = 'Home'; // actions $lang['action_load_posts_text'] = 'Load more posts'; $lang['action_load_posts_tip'] = 'Load more posts'; - -?> diff --git a/src/web/lang/en_US/apps/people.php b/src/web/lang/people.php index 2bfc240..55204aa 100644 --- a/src/web/lang/en_US/apps/people.php +++ b/src/web/lang/people.php @@ -1,4 +1,4 @@ -<?php +<?php /* Copyright (c) 2024 Freya Murphy */ $lang['title'] = 'Directory'; $lang['desc'] = 'Explore other people on xssbook!'; @@ -14,4 +14,4 @@ $lang['tbl_gender'] = 'Gender '; $lang['action_load_users_text'] = 'Load more users'; $lang['action_load_users_tip'] = 'Load more users'; -?> +$lang['no_people_found'] = 'No one is here... :('; diff --git a/src/web/lang/post.php b/src/web/lang/post.php new file mode 100644 index 0000000..39cb24d --- /dev/null +++ b/src/web/lang/post.php @@ -0,0 +1,35 @@ +<?php /* Copyright (c) 2024 Freya Murphy */ + +// Posts +$lang['action_like_text'] = 'Like'; +$lang['action_like_tip'] = 'Like this post.'; +$lang['action_like_icon'] = 'mi mi-sm'; +$lang['action_like_content'] = 'thumb_up'; + +$lang['no_posts_found'] = 'No posts here...'; +$lang['no_posts_found_ext'] = +"We ate them all. +They got lost in transit. +All stuck in line at the DMV. +Death has taken them. +[REDACTED] +They were non-RFC complient. +Submit a formal complaint at your local IRS office. +They are in jail for killing child processes. +They didn't deem you worthy. +Meta stole them for AI training."; + +// Comments +$lang['action_comment_text'] = 'Comment'; +$lang['action_comment_tip'] = 'Focus the comment box.'; +$lang['action_comment_icon'] = 'mi mi-sm'; +$lang['action_comment_content'] = 'comment'; +$lang['action_new_comment_text'] = 'Write a comment'; +$lang['action_new_comment_tip'] = 'Write a comment, then press enter to submit.'; +$lang['action_load_comments_text'] = 'Load more comments'; +$lang['action_load_comments_tip'] = 'Load more comments'; + +// New Post Modal +$lang['new_post_modal_title'] = 'Author New Post'; +$lang['action_new_post_text'] = 'What\'s on your mind, %s'; +$lang['action_new_post_tip'] = 'Author a new post.'; diff --git a/src/web/lang/en_US/apps/profile.php b/src/web/lang/profile.php index bb91e02..d7bbf2b 100644 --- a/src/web/lang/en_US/apps/profile.php +++ b/src/web/lang/profile.php @@ -1,6 +1,5 @@ -<?php - -$lang['title'] = '%s\'s profile'; +<?php /* Copyright (c) 2024 Freya Murphy */ +$lang['title'] = ''; $lang['joined'] = 'Joined: '; $lang['seen'] = 'Seen: '; @@ -42,5 +41,3 @@ $lang['about_stats_comments'] = 'Comments Created'; $lang['about_stats_following'] = 'Accounts Followed'; $lang['about_stats_joined'] = 'Date Joined'; $lang['about_stats_seen'] = 'Last Seen'; - -?> diff --git a/src/web/lang/en_US/apps/settings.php b/src/web/lang/settings.php index 81ba0ec..537cdca 100644 --- a/src/web/lang/en_US/apps/settings.php +++ b/src/web/lang/settings.php @@ -1,4 +1,4 @@ -<?php +<?php /* Copyright (c) 2024 Freya Murphy */ $lang['title'] = 'Settings'; diff --git a/src/web/lib/_base.php b/src/web/lib/_base.php new file mode 100644 index 0000000..790bac9 --- /dev/null +++ b/src/web/lib/_base.php @@ -0,0 +1,61 @@ +<?php /* Copyright (c) 2024 Freya Murphy */ + +trait XSS_Base { + + /** + * Formats a users's name + * @param array $user - the $user + * @returns the user's formatted display name + */ + public function format_name(array $user): string { + $name = ''; + // first_name + if ($user['first_name']) + $name .= $user['first_name']; + // middle_name + if ($user['middle_name']) { + if ($name != '') + $name .= ' '; + $name .= $user['middle_name']; + } + // last_name + if ($user['last_name']) { + if ($name != '') + $name .= ' '; + $name .= $user['last_name']; + } + if ($name == '') { + $name = '@' . $user['username']; + } + return $name; + } + + /** + * Formats a ISO date + * @param $iso_date the ISO date + */ + public function format_date(string $iso_date): string + { + return date("Y-m-d D H:i", strtotime($iso_date)); + } + + /** + * Loads a STRING from $_GET, or returns $default on failure + */ + public function get_string(string $key, ?string $default = NULL): ?string { + if (isset($_GET[$key])) + return $_GET[$key]; + return $default; + } + + /** + * Loads a INT from $_GET, or returns $default on failure + */ + public function get_int(string $key, ?int $default = NULL): ?int { + $value = $this->get_string($key); + if ($value) + return intval($value); + return $default; + } + +} diff --git a/src/web/lib/_controller.php b/src/web/lib/_controller.php new file mode 100644 index 0000000..122a7a7 --- /dev/null +++ b/src/web/lib/_controller.php @@ -0,0 +1,49 @@ +<?php /* Copyright (c) 2024 Freya Murphy */ + +class XSS_Controller extends Controller { + use XSS_Base; + + protected $model; + + public function __construct() { + $this->model = new XSS_model(); + $this->load_lang('common', 'api'); + } + + /** + * Formats a users's name + * @param array $user - the $user + * @returns the user's formatted display name + */ + public function format_name(array $user): string { + $name = ''; + // first_name + if ($user['first_name']) + $name .= $user['first_name']; + // middle_name + if ($user['middle_name']) { + if ($name != '') + $name .= ' '; + $name .= $user['middle_name']; + } + // last_name + if ($user['last_name']) { + if ($name != '') + $name .= ' '; + $name .= $user['last_name']; + } + if ($name == '') { + $name = '@' . $user['username']; + } + return $name; + } + + /** + * Formats a ISO date + * @param $iso_date the ISO date + */ + public function format_date(string $iso_date): string + { + return date("Y-m-d D H:i", strtotime($iso_date)); + } +} diff --git a/src/web/lib/_model.php b/src/web/lib/_model.php new file mode 100644 index 0000000..c29e015 --- /dev/null +++ b/src/web/lib/_model.php @@ -0,0 +1,61 @@ +<?php /* Copyright (c) 2024 Freya Murphy */ + +class XSS_Model extends Model { + use XSS_Base; + + private static array $loaded_users = array(); + + /** + * Gets an array of users with IDs specified by 'user_id' in $objs + */ + public function get_users($objs) { + // null check + if (!$objs) + return self::$loaded_users; + + $ids = array(); + // get all user_id's to load (not in loaded_users) + foreach ($objs as $obj) { + $id = $obj['user_id']; + if (!isset(self::$loaded_users[$id])) + $ids[] = intval($id); + } + // if there are users to load + if (count($ids)) { + $result = $this->db() + ->select('*') + ->from('api.user') + ->where_in('id', $ids) + ->rows(); + foreach ($result as $user) + self::$loaded_users[$user['id']] = $user; + } + // return result + return self::$loaded_users; + } + + /** + * Gets the page's title + */ + public function get_title(): string { + $xssbook = lang('xssbook'); + $title = lang('title'); + if ($title) + return "$xssbook - $title"; + return $xssbook; + } + + /** + * Adds title to base data + */ + #[\Override] + public function get_data(): ?array { + $data = parent::get_data(); + // title + $data['title'] = $this->get_title(); + // session + $auth_model = $this->load_model('auth'); + $data['session'] = $auth_model->session();; + return $data; + } +} diff --git a/src/web/lib/hooks.php b/src/web/lib/hooks.php new file mode 100644 index 0000000..45316ec --- /dev/null +++ b/src/web/lib/hooks.php @@ -0,0 +1,31 @@ +<?php /* Copyright (c) 2024 Freya Murphy */ + +function XSSBOOK_begin_session(): void { + session_start(); + setcookie( + session_name(), + session_id(), + array( + 'expires' => time() + 60*60*24*7, + 'path' => '/', + 'domain' => NULL, + 'secure' => FALSE, + 'httponly' => FALSE, + 'samesite' => 'Lax' + ) + ); +} + +function CRIMSON_init_hook(): void { + //date_default_timezone_set('America/New_York'); + XSSBOOK_begin_session(); +} + +function CRIMSON_pre_route_hook(Router $router): void { +} + +function CRIMSON_error_hook(?array $req, int $code): never { + $error_controller = ROUTER->load_controller('error'); + $error_controller->code($code); + CRIMSON_DIE(); +} diff --git a/src/web/helper/image.php b/src/web/lib/image.php index 6d42678..6d42678 100644 --- a/src/web/helper/image.php +++ b/src/web/lib/image.php diff --git a/src/web/lib/utils.php b/src/web/lib/utils.php new file mode 100644 index 0000000..254f9ea --- /dev/null +++ b/src/web/lib/utils.php @@ -0,0 +1,6 @@ +<?php /* Copyright (c) 2024 Freya Murphy */ + +function random_value(array $array): mixed { + shuffle($array); + return end($array); +} diff --git a/src/web/stamp.php b/src/web/stamp.php new file mode 100644 index 0000000..7a1956b --- /dev/null +++ b/src/web/stamp.php @@ -0,0 +1,46 @@ +<?php +$__stamps = array(); +$__stamps['public/css/home.css'] = 1734805900; +$__stamps['public/css/error.css'] = 1734805900; +$__stamps['public/css/post.css'] = 1734805900; +$__stamps['public/css/people.css'] = 1734805900; +$__stamps['public/css/profile.css'] = 1734805900; +$__stamps['public/css/auth.css'] = 1734805900; +$__stamps['public/css/common.css'] = 1734805900; +$__stamps['public/css/settings.css'] = 1734805900; +$__stamps['public/favicon.ico'] = 1721008734; +$__stamps['public/font/Facebook.otf'] = 1721008734; +$__stamps['public/font/Facebook.ttf'] = 1734674363; +$__stamps['public/font/Facebook.woff'] = 1734674376; +$__stamps['public/font/Facebook.woff2'] = 1734674377; +$__stamps['public/font/Helvetica'] = ; +$__stamps['public/Neue.otf'] = ; +$__stamps['public/font/Helvetica'] = ; +$__stamps['public/Neue.ttf'] = ; +$__stamps['public/font/Helvetica'] = ; +$__stamps['public/Neue.woff'] = ; +$__stamps['public/font/Helvetica'] = ; +$__stamps['public/Neue.woff2'] = ; +$__stamps['public/font/Material'] = ; +$__stamps['public/Icons.ttf'] = ; +$__stamps['public/font/SF'] = ; +$__stamps['public/Pro.otf'] = ; +$__stamps['public/font/SF'] = ; +$__stamps['public/Pro.ttf'] = ; +$__stamps['public/font/SF'] = ; +$__stamps['public/Pro.woff'] = ; +$__stamps['public/font/SF'] = ; +$__stamps['public/Pro.woff2'] = ; +$__stamps['public/font/Material'] = ; +$__stamps['public/Icons.otf'] = ; +$__stamps['public/font/Material'] = ; +$__stamps['public/Icons.woff'] = ; +$__stamps['public/font/Material'] = ; +$__stamps['public/Icons.woff2'] = ; +$__stamps['public/js/lib.js'] = 1734680679; +$__stamps['public/js/modal.js'] = 1721008734; +$__stamps['public/js/post.js'] = 1734678976; +$__stamps['public/js/thirdparty/jquery.min.js'] = 1721008734; +$__stamps['public/icons/logo512.png'] = 1731184206; +define('FILE_TIMES', $__stamps); +unset($__stamps); |