mirror of
https://codeberg.org/vlw/vlw.se.git
synced 2025-09-13 21:13:40 +02:00
Compare commits
5 commits
28bb004004
...
f961579c79
Author | SHA1 | Date | |
---|---|---|---|
f961579c79 | |||
ecd9c4e3cc | |||
234c6c68a6 | |||
f7a237f6fe | |||
7f97bf7766 |
15 changed files with 59 additions and 645 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -1,9 +1,7 @@
|
|||
# Public assets #
|
||||
#################
|
||||
public/robots.txt
|
||||
public/.well-known
|
||||
|
||||
assets/js/modules/npm
|
||||
public/assets/js/modules/npm
|
||||
|
||||
# Bootstrapping #
|
||||
#################
|
||||
|
|
103
README.md
103
README.md
|
@ -1,73 +1,66 @@
|
|||
# vlw.se
|
||||
This is the source code behind [vlw.se](https://vlw.se) which has been written from the ground up by me. This website is built on top of my [Vegvisir web framework](https://vegvisir.vlw.se) and my [Reflect API framework](https://reflect.vlw.se).
|
||||
This is the source code behind [vlw.se](https://vlw.se) which is my personal website that I have written and designed from the ground up. The website is built on top of my own [web framework](https://vegvisir.vlw.se) and its API is also built on top of my own [API framework](https://reflect.vlw.se).
|
||||
|
||||
# Installation
|
||||
If you for whatever reason want to get this website up and running for yourself this is how that is done.
|
||||
Here's how you get my website up and running on your own machine. Note, I have only tested this on Linux and the install script we will run later is written in bash.
|
||||
|
||||
## This website requires the following prerequisites
|
||||
- [PHP 8.0+](https://www.php.net/)
|
||||
- [MariaDB 14+](https://mariadb.org/)
|
||||
- [The NPM package manager](https://www.npmjs.com/)
|
||||
- [The Reflect API framework](https://reflect.vlw.se)
|
||||
- [The Vegvisir web framework](https://vegvisir.vlw.se)
|
||||
- [The composer package manager](https://getcomposer.org/)
|
||||
**Make sure you have both of these package managers installed before proceeding:**
|
||||
- [Composer](https://getcomposer.org/)
|
||||
- [NPM](https://www.npmjs.com/)
|
||||
|
||||
**Confimed supported framework versions:**
|
||||
Vegvisir|Reflect
|
||||
--|--
|
||||
✅ [`3.1.0`](https://codeberg.org/vegvisir/vegvisir/releases/tag/3.1.0)|✅ [`2.7.2`](https://codeberg.org/reflect/reflect/releases/tag/2.7.2)
|
||||
## 1. Clone this repo
|
||||
Clone/download this repo to your machine. Preferably to a non-public directory - the frameworks will handle that.
|
||||
|
||||
## Website (Vegvisir)
|
||||
1. **Download this repo**
|
||||
|
||||
Git clone or download this repo to any local folder
|
||||
```
|
||||
git clone https://codeberg.org/vlw/vlw.se
|
||||
```
|
||||
2. **Download and install Vegvisir**
|
||||
|
||||
Follow the installation instructions for [Vegvisir](https://vegvisir.vlw.se/docs/installation) and point the `root_path` variable to your local vlw.se folder.
|
||||
```
|
||||
git clone https://codeberg.org/vlw/vlw.se --depth 1
|
||||
```
|
||||
|
||||
3. **Run the install script**
|
||||
## 2. Install [Vegvisir](https://vegvisir.vlw.se) and [Reflect](https://reflect.vlw.se)
|
||||
Follow the installation instructions for my web, and API framework. This site uses the default configuration for both frameworks so the only thing you need to do after you've installed both is to point the `root_path` and `endpoints` directory respectively to the directory where you cloned this repo.
|
||||
|
||||
This bash script will install dependencies and make npm modules public.
|
||||
```
|
||||
./install.sh
|
||||
```
|
||||
- [Vegvisir installation](https://vegvisir.vlw.se)
|
||||
- [Reflect installation](https://reflect.vlw.se)
|
||||
|
||||
Et voila! You probably want to install the API-side too but the website itself should now be accessible from your configured Vegvisir host.
|
||||
*Example:*
|
||||
```sh
|
||||
# Vegvisir
|
||||
root_path = "/var/www/vlw.se"
|
||||
# Reflect
|
||||
endpoints = "/var/www/vlw.se"
|
||||
```
|
||||
|
||||
## API (Reflect)
|
||||
The API (and database) is where most content is stored and served from on this website.
|
||||
## 3. Run the install script
|
||||
Run the `install.sh` script from the root of the repo directory. [Make sure you have the required package managers installed](#installation).
|
||||
|
||||
1. **Download this repo**
|
||||
**Example:**
|
||||
```sh
|
||||
# vlw@example:$
|
||||
cd /var/www/vlw.se
|
||||
# vlw@example:/var/www/vlw.se$
|
||||
./install.sh
|
||||
```
|
||||
|
||||
**You can skip this if you've already downloaded the repo from step 1 in the website installation.**
|
||||
## 4. Import the database templates
|
||||
There's are two SQL files that you can download from the releases page that has a snapshot of the MariaDB databases I use on my live website. The snapshot data for the website databse is not guaranteed to be up to date; but the database structure will be. Download and import these files into two existing databases. One for the website data, and the other has the Reflect API configurations.
|
||||
|
||||
Otherwise... Git clone or download this repo to any local folder
|
||||
```
|
||||
git clone https://codeberg.org/vlw/vlw.se
|
||||
```
|
||||
- [Download SQL-snapshots](https://codeberg.org/vlw/vlw.se/releases)
|
||||
|
||||
2. **Download and install Reflect**
|
||||
|
||||
Follow the installation instructions for [Reflect](https://reflect.vlw.se/docs/installation) and point the `endpoints` variable to the `/api` subdirectory in the local vlw.se folder.
|
||||
## 5. Set environment variables
|
||||
Make a copy of the `.env.example.ini` file called `.env.ini` from the root directory of the repo. There are a few parameters you can change here but the required ones are the following:
|
||||
|
||||
3. **Install dependencies**
|
||||
```ini
|
||||
[client_api]
|
||||
base_url = ""
|
||||
api_key = ""
|
||||
|
||||
`cd` into the api folder and install dependencies with composer.
|
||||
```
|
||||
composer install --optimize-autoloader
|
||||
```
|
||||
[server_database]
|
||||
host = ""
|
||||
user = ""
|
||||
pass = ""
|
||||
db = ""
|
||||
```
|
||||
|
||||
4. **Create and import database**
|
||||
Please refer to the comments in the ini file for more information about each field.
|
||||
|
||||
[Create and] import the two databases associated with vlw.se data and the Reflect API configurations from `.sql` files on the Releases page.
|
||||
|
||||
5. **Set environment variables**
|
||||
|
||||
Make a copy of `/api/.env.example.ini` and change the `[vlwdb]` variables with your MariaDB credentials.
|
||||
|
||||
6. **Set environment variables for website**
|
||||
|
||||
It's reasonable to assume if you've installed the website from this repo that you'd also want to use the API with it. Start my making a copy of `/.env.example.ini` (root directory) and change the `[api]` variables to point to your API hostname.
|
||||
## Done!
|
||||
That should be it. Navigate to your configured Vegvisir public host!
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
(new Rules(SearchTable::ID->value))
|
||||
->type(Type::STRING)
|
||||
->min(10)
|
||||
->min(1)
|
||||
->max(10)
|
||||
->default(null),
|
||||
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Reflect\{Response, Path};
|
||||
use ReflectRules\{Ruleset, Rules, Type};
|
||||
|
||||
use const VLW\API\RESP_DELETE_OK;
|
||||
use VLW\Database\Database;
|
||||
use VLW\Database\Tables\Work\WorkTable;
|
||||
|
||||
require_once Path::root("src/Endpoints.php");
|
||||
require_once Path::root("src/Database/Database.php");
|
||||
require_once Path::root("src/Database/Tables/Work.php");
|
||||
|
||||
class DELETE_Work extends Database {
|
||||
protected Ruleset $ruleset;
|
||||
|
||||
public function __construct() {
|
||||
$this->ruleset = new Ruleset(strict: true);
|
||||
|
||||
$this->ruleset->POST([
|
||||
(new Rules(WorkTable::ID->value))
|
||||
->type(Type::STRING)
|
||||
->min(1)
|
||||
->max(parent::SIZE_VARCHAR),
|
||||
|
||||
(new Rules(WorkTable::TITLE->value))
|
||||
->type(Type::STRING)
|
||||
->min(3)
|
||||
->max(parent::SIZE_VARCHAR),
|
||||
|
||||
(new Rules(WorkTable::SUMMARY->value))
|
||||
->type(Type::STRING)
|
||||
->min(1)
|
||||
->max(parent::SIZE_TEXT),
|
||||
|
||||
(new Rules(WorkTable::IS_LISTED->value))
|
||||
->type(Type::BOOLEAN),
|
||||
|
||||
(new Rules(WorkTable::DATE_MODIFIED->value))
|
||||
->type(Type::NUMBER)
|
||||
->min(1)
|
||||
->max(parent::SIZE_UINT8),
|
||||
|
||||
(new Rules(WorkTable::DATE_CREATED->value))
|
||||
->type(Type::NUMBER)
|
||||
->min(1)
|
||||
->max(parent::SIZE_UINT8)
|
||||
]);
|
||||
|
||||
$this->ruleset->validate_or_exit();
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function main(): Response {
|
||||
return $this->db->for(FieldsEnumsModel::NAME)->delete($_POST) === true
|
||||
? new Response(RESP_DELETE_OK)
|
||||
: new Response("Failed to delete work entity", 500);
|
||||
}
|
||||
}
|
|
@ -1,109 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Reflect\Call;
|
||||
use Reflect\{Response, Path};
|
||||
use ReflectRules\{Ruleset, Rules, Type};
|
||||
|
||||
use VLW\API\Endpoints;
|
||||
use VLW\Database\Database;
|
||||
use VLW\Database\Tables\Work\{
|
||||
WorkTable,
|
||||
PermalinksTable
|
||||
};
|
||||
|
||||
require_once Path::root("src/Endpoints.php");
|
||||
require_once Path::root("src/Database/Database.php");
|
||||
require_once Path::root("src/Database/Tables/Work/Work.php");
|
||||
require_once Path::root("src/Database/Tables/Work/WorkPermalinks.php");
|
||||
|
||||
class PATCH_Work extends Database {
|
||||
protected Ruleset $ruleset;
|
||||
|
||||
public function __construct() {
|
||||
$this->ruleset = new Ruleset(strict: true);
|
||||
|
||||
$this->ruleset->GET([
|
||||
(new Rules(WorkTable::ID->value))
|
||||
->required()
|
||||
->type(Type::STRING)
|
||||
->min(1)
|
||||
->max(parent::SIZE_VARCHAR)
|
||||
]);
|
||||
|
||||
$this->ruleset->POST([
|
||||
(new Rules(WorkTable::TITLE->value))
|
||||
->type(Type::STRING)
|
||||
->min(3)
|
||||
->max(parent::SIZE_VARCHAR),
|
||||
|
||||
(new Rules(WorkTable::SUMMARY->value))
|
||||
->type(Type::STRING)
|
||||
->min(1)
|
||||
->max(parent::SIZE_TEXT),
|
||||
|
||||
(new Rules(WorkTable::IS_LISTED->value))
|
||||
->type(Type::BOOLEAN),
|
||||
|
||||
(new Rules(WorkTable::DATE_MODIFIED->value))
|
||||
->type(Type::NUMBER)
|
||||
->min(1)
|
||||
->max(parent::SIZE_UINT8)
|
||||
->default(time()),
|
||||
|
||||
(new Rules(WorkTable::DATE_CREATED->value))
|
||||
->type(Type::NUMBER)
|
||||
->min(1)
|
||||
->max(parent::SIZE_UINT8)
|
||||
]);
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
// Generate a slug URL from string
|
||||
private static function gen_slug(string $input): string {
|
||||
return strtolower(trim(preg_replace('/[^A-Za-z0-9-]+/', '-', $input)));
|
||||
}
|
||||
|
||||
// Compute and return modeled year, month, and day from Unix timestamp in request body
|
||||
private static function gen_date_created(): array {
|
||||
return [
|
||||
WorkTable::DATE_YEAR->value => date("Y", $_POST[WorkTable::DATE_CREATED->value]),
|
||||
WorkTable::DATE_MONTH ->value => date("n", $_POST[WorkTable::DATE_CREATED->value]),
|
||||
WorkTable::DATE_DAY->value => date("j", $_POST[WorkTable::DATE_CREATED->value])
|
||||
];
|
||||
}
|
||||
|
||||
private function get_entity_by_id(string $id): Response {
|
||||
return (new Call(Endpoints::WORK->value))->params([
|
||||
WorkTable::ID->value => $id
|
||||
])->get();
|
||||
}
|
||||
|
||||
public function main(): Response {
|
||||
// Use copy of request body as entity
|
||||
$entity = $_POST;
|
||||
|
||||
// Generate a new slug id from title if changed
|
||||
if ($_POST[WorkTable::TITLE->value]) {
|
||||
$slug = $_POST[WorkTable::TITLE->value];
|
||||
|
||||
// Bail out if the slug generated from the new tite already exist
|
||||
if ($this->get_entity_by_id($slug)) {
|
||||
return new Response("An entity with this title already exist", 409);
|
||||
}
|
||||
|
||||
// Add the new slug to update entity
|
||||
$entity[WorkTable::ID] = $slug;
|
||||
}
|
||||
|
||||
// Generate new work date fields from timestamp
|
||||
if ($_POST[WorkTable::DATE_CREATED->value]) {
|
||||
array_merge($entity, self::gen_date_created());
|
||||
}
|
||||
|
||||
// Update entity by existing id
|
||||
return $this->db->for(WorkTable::NAME)->where([WorkTable::ID->value => $_GET[WorkTable::ID->value]])->update($entity) === true
|
||||
? new Response($_GET[WorkTable::ID->value])
|
||||
: new Response("Failed to update entity", 500);
|
||||
}
|
||||
}
|
|
@ -1,106 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Reflect\Call;
|
||||
use Reflect\{Response, Path};
|
||||
use ReflectRules\{Ruleset, Rules, Type};
|
||||
|
||||
use VLW\API\Endpoints;
|
||||
use VLW\Database\Database;
|
||||
use VLW\Database\Tables\Work\{
|
||||
WorkTable,
|
||||
PermalinksTable
|
||||
};
|
||||
|
||||
require_once Path::root("src/Endpoints.php");
|
||||
require_once Path::root("src/Database/Database.php");
|
||||
require_once Path::root("src/Database/Tables/Work/Work.php");
|
||||
require_once Path::root("src/Database/Tables/Work/WorkPermalinks.php");
|
||||
|
||||
class POST_Work extends Database {
|
||||
protected Ruleset $ruleset;
|
||||
|
||||
public function __construct() {
|
||||
$this->ruleset = new Ruleset(strict: true);
|
||||
|
||||
$this->ruleset->POST([
|
||||
(new Rules(WorkTable::TITLE->value))
|
||||
->type(Type::STRING)
|
||||
->min(3)
|
||||
->max(parent::SIZE_VARCHAR)
|
||||
->default(null),
|
||||
|
||||
(new Rules(WorkTable::SUMMARY->value))
|
||||
->type(Type::STRING)
|
||||
->min(1)
|
||||
->max(parent::SIZE_TEXT)
|
||||
->default(null),
|
||||
|
||||
(new Rules(WorkTable::IS_LISTED->value))
|
||||
->type(Type::BOOLEAN)
|
||||
->default(false),
|
||||
|
||||
(new Rules(WorkTable::DATE_CREATED->value))
|
||||
->type(Type::NUMBER)
|
||||
->min(1)
|
||||
->max(parent::SIZE_UINT8)
|
||||
->default(time())
|
||||
]);
|
||||
|
||||
$this->ruleset->validate_or_exit();
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
// Generate a slug URL from string
|
||||
private static function gen_slug(string $input): string {
|
||||
return strtolower(trim(preg_replace('/[^A-Za-z0-9-]+/', '-', $input)));
|
||||
}
|
||||
|
||||
// Compute and return modeled year, month, and day from a Unix timestamp
|
||||
private static function gen_date_created(): array {
|
||||
// Use provided timestamp in request
|
||||
$date_created = $_POST[WorkTable::DATE_CREATED->value];
|
||||
|
||||
return [
|
||||
WorkTable::DATE_YEAR->value => date("Y", $date_created),
|
||||
WorkTable::DATE_MONTH ->value => date("n", $date_created),
|
||||
WorkTable::DATE_DAY->value => date("j", $date_created)
|
||||
];
|
||||
}
|
||||
|
||||
private function get_entity_by_id(string $id): Response {
|
||||
return (new Call(Endpoints::WORK->value))->params([
|
||||
WorkTable::ID->value => $id
|
||||
])->get();
|
||||
}
|
||||
|
||||
public function main(): Response {
|
||||
// Use copy of request body as entity
|
||||
$entity = $_POST;
|
||||
|
||||
// Generate URL slug from title text or UUID if undefined
|
||||
$entity[WorkTable::ID->value] = $_POST[WorkTable::TITLE->value]
|
||||
? self::gen_slug($_POST[WorkTable::TITLE->value])
|
||||
: parent::gen_uuid4();
|
||||
|
||||
// Bail out here if a work entry with id had been created already
|
||||
if ($this->get_entity_by_id($entity[WorkTable::ID->value])->ok) {
|
||||
return new Response("An entity with id '{$slug}' already exist", 409);
|
||||
}
|
||||
|
||||
// Generate the necessary date fields
|
||||
array_merge($entity, self::gen_date_created());
|
||||
|
||||
// Let's try to insert the new entity
|
||||
if (!$this->db->for(WorkTable::NAME)->insert($entity)) {
|
||||
return new Response("Failed to insert work entry", 500);
|
||||
}
|
||||
|
||||
// Generate permalink for new entity
|
||||
return (new Call(Endpoints::WORK_PERMALINKS->value))->post([
|
||||
PermalinksTable::ID => $entity[WorkTable::ID->value],
|
||||
PermalinksTable::REF_WORK_ID => $entity[WorkTable::ID->value],
|
||||
PermalinksTable::DATE_CREATED => time()
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Reflect\{Response, Path};
|
||||
use ReflectRules\{Ruleset, Rules, Type};
|
||||
|
||||
use const VLW\API\RESP_DELETE_OK;
|
||||
use VLW\Database\Database;
|
||||
use VLW\Database\Tables\Work\ActionsTable;
|
||||
|
||||
require_once Path::root("src/Database/Database.php");
|
||||
require_once Path::root("src/Database/Tables/WorkActions.php");
|
||||
|
||||
class DELETE_WorkActions extends Database {
|
||||
protected Ruleset $ruleset;
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
$this->ruleset = new Ruleset(strict: true);
|
||||
|
||||
$this->ruleset->POST([
|
||||
(new Rules(ActionsTable::REF_WORK_ID->value))
|
||||
->min(1)
|
||||
->max(parent::SIZE_VARCHAR)
|
||||
]);
|
||||
}
|
||||
|
||||
public function main(): Response {
|
||||
return $this->db->for(ActionsTable::NAME)->delete($_POST) === true
|
||||
? new Response(RESP_DELETE_OK)
|
||||
: new Response("Failed to delete action for work entity", 500);
|
||||
}
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Reflect\Call;
|
||||
use Reflect\{Response, Path};
|
||||
use ReflectRules\{Ruleset, Rules, Type};
|
||||
|
||||
use VLW\API\Endpoints;
|
||||
use VLW\Database\Database;
|
||||
use VLW\Database\Tables\Work\{
|
||||
WorkTable,
|
||||
ActionsTable
|
||||
};
|
||||
|
||||
require_once Path::root("src/Endpoints.php");
|
||||
require_once Path::root("src/Database/Database.php");
|
||||
require_once Path::root("src/Database/Tables/Work/Work.php");
|
||||
require_once Path::root("src/Database/Tables/Work/WorkActions.php");
|
||||
|
||||
class POST_WorkActions extends Database {
|
||||
protected Ruleset $ruleset;
|
||||
|
||||
public function __construct() {
|
||||
$this->ruleset = new Ruleset(strict: true);
|
||||
|
||||
$this->ruleset->POST([
|
||||
(new Rules(ActionsTable::REF_WORK_ID->value))
|
||||
->required()
|
||||
->min(1)
|
||||
->max(parent::SIZE_VARCHAR),
|
||||
|
||||
(new Rules(ActionsTable::DISPLAY_TEXT->value))
|
||||
->required()
|
||||
->type(Type::STRING)
|
||||
->min(1)
|
||||
->max(parent::SIZE_VARCHAR),
|
||||
|
||||
(new Rules(ActionsTable::HREF->value))
|
||||
->required()
|
||||
->type(Type::STRING)
|
||||
->type(Type::NULL)
|
||||
->min(1)
|
||||
->max(parent::SIZE_VARCHAR),
|
||||
|
||||
(new Rules(ActionsTable::CLASS_LIST->value))
|
||||
->type(Type::ARRAY)
|
||||
->min(1)
|
||||
->default([])
|
||||
]);
|
||||
|
||||
$this->ruleset->validate_or_exit();
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
private static function get_entity(): Response {
|
||||
return (new Call(Endpoints::WORK->value))->params([
|
||||
WorkTable::ID->value => $_POST[ActionsTable::REF_WORK_ID->value]
|
||||
])->get();
|
||||
}
|
||||
|
||||
public function main(): Response {
|
||||
// Bail out if work entity could not be fetched
|
||||
$entity = self::get_entity();
|
||||
if (!$entity->ok) {
|
||||
return $entity;
|
||||
}
|
||||
|
||||
return $this->db->for(ActionsTable::NAME)->insert($_POST) === true
|
||||
? new Response($_POST[ActionsTable::REF_WORK_ID->value], 201)
|
||||
: new Response("Failed to add action to work entity", 500);
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Reflect\{Response, Path};
|
||||
use ReflectRules\{Ruleset, Rules, Type};
|
||||
|
||||
use VLW\Database\Database;
|
||||
use VLW\Database\Tables\Work\PermalinksTable;
|
||||
|
||||
require_once Path::root("src/Database/Database.php");
|
||||
require_once Path::root("src/Database/Tables/Work/WorkPermalinks.php");
|
||||
|
||||
class GET_WorkPermalinks extends Database {
|
||||
protected Ruleset $ruleset;
|
||||
|
||||
public function __construct() {
|
||||
$this->ruleset = new Ruleset(strict: true);
|
||||
|
||||
$this->ruleset->GET([
|
||||
(new Rules(PermalinksTable::ID->value))
|
||||
->type(Type::STRING)
|
||||
->min(1)
|
||||
->max(parent::SIZE_VARCHAR),
|
||||
|
||||
(new Rules(PermalinksTable::REF_WORK_ID->value))
|
||||
->type(Type::STRING)
|
||||
->min(1)
|
||||
->max(parent::SIZE_VARCHAR)
|
||||
]);
|
||||
|
||||
$this->ruleset->validate_or_exit();
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function main(): Response {
|
||||
$response = $this->db->for(PermalinksTable::NAME)
|
||||
->where($_GET)
|
||||
->select([
|
||||
PermalinksTable::ID->value,
|
||||
PermalinksTable::REF_WORK_ID->value,
|
||||
PermalinksTable::DATE_CREATED->value
|
||||
]);
|
||||
|
||||
return $response->num_rows > 0
|
||||
? new Response($response->fetch_all(MYSQLI_ASSOC))
|
||||
: new Response([], 404);
|
||||
}
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Reflect\Call;
|
||||
use Reflect\{Response, Path};
|
||||
use ReflectRules\{Ruleset, Rules, Type};
|
||||
|
||||
use VLW\Database\Database;
|
||||
use VLW\Database\Tables\Work\PermalinksTable;
|
||||
|
||||
require_once Path::root("src/Database/Database.php");
|
||||
require_once Path::root("src/Database/Tables/Work/WorkPermalinks.php");
|
||||
|
||||
class POST_WorkPermalinks extends Database {
|
||||
protected Ruleset $ruleset;
|
||||
|
||||
public function __construct() {
|
||||
$this->ruleset = new Ruleset(strict: true);
|
||||
|
||||
$this->ruleset->POST([
|
||||
(new Rules(PermalinksTable::ID->value))
|
||||
->required()
|
||||
->type(Type::STRING)
|
||||
->min(1)
|
||||
->max(parent::SIZE_VARCHAR),
|
||||
|
||||
(new Rules(PermalinksTable::REF_WORK_ID->value))
|
||||
->required()
|
||||
->type(Type::STRING)
|
||||
->min(1)
|
||||
->max(parent::SIZE_VARCHAR),
|
||||
|
||||
(new Rules(PermalinksTable::DATE_CREATED->value))
|
||||
->type(Type::NUMBER)
|
||||
->min(1)
|
||||
->max(parent::SIZE_UINT8)
|
||||
->default(time())
|
||||
]);
|
||||
|
||||
$this->ruleset->validate_or_exit();
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
private static function get_entity(): Response {
|
||||
return (new Call(Endpoints::WORK->value))->params([
|
||||
WorkTable::ID->value => $_POST[TagsTable::REF_WORK_ID->value]
|
||||
])->get();
|
||||
}
|
||||
|
||||
public function main(): Response {
|
||||
// Bail out if work entity could not be fetched
|
||||
$entity = self::get_entity();
|
||||
if (!$entity->ok) {
|
||||
return $entity;
|
||||
}
|
||||
|
||||
return $this->db->for(PermalinksTable::NAME)->insert($_POST) === true
|
||||
? new Response($_POST[PermalinksTable::ID->value], 201)
|
||||
: new Response("Failed to add permalink to work entity", 500);
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Reflect\{Response, Path};
|
||||
use ReflectRules\{Ruleset, Rules, Type};
|
||||
|
||||
use const VLW\API\RESP_DELETE_OK;
|
||||
use VLW\Database\Database;
|
||||
use VLW\Database\Tables\Work\TagsTable;
|
||||
|
||||
require_once Path::root("src/Database/Database.php");
|
||||
require_once Path::root("src/Database/Tables/Work/WorkTags.php");
|
||||
|
||||
class DELETE_WorkTags extends Database {
|
||||
private Ruleset $ruleset;
|
||||
|
||||
public function __construct() {
|
||||
$this->ruleset = new Ruleset(strict: true);
|
||||
|
||||
$this->ruleset->GET([
|
||||
(new Rules(TagsTable::REF_WORK_ID->value))
|
||||
->min(1)
|
||||
->max(parent::SIZE_VARCHAR),
|
||||
|
||||
(new Rules(TagsTable::NAME->value))
|
||||
->type(Type::ENUM, TagsNameEnum::names())
|
||||
]);
|
||||
|
||||
$this->ruleset->validate_or_exit();
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function main(): Response {
|
||||
return $this->db->for(TagsTable::NAME)->delete($_POST) === true
|
||||
? new Response(RESP_DELETE_OK)
|
||||
: new Response("Failed to delete value from document", 500);
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Reflect\Call;
|
||||
use Reflect\{Response, Path};
|
||||
use ReflectRules\{Ruleset, Rules, Type};
|
||||
|
||||
use VLW\API\Endpoints;
|
||||
use VLW\Database\Database;
|
||||
use VLW\Database\Tables\Work\{
|
||||
WorkTable,
|
||||
TagsTable,
|
||||
TagsNameEnum
|
||||
};
|
||||
|
||||
require_once Path::root("src/Endpoints.php");
|
||||
require_once Path::root("src/Database/Database.php");
|
||||
require_once Path::root("src/Database/Tables/Work/Work.php");
|
||||
require_once Path::root("src/Database/Tables/Work/WorkTags.php");
|
||||
|
||||
class POST_WorkTags extends Database {
|
||||
protected Ruleset $ruleset;
|
||||
|
||||
public function __construct() {
|
||||
$this->ruleset = new Ruleset(strict: true);
|
||||
|
||||
$this->ruleset->POST([
|
||||
(new Rules(TagsTable::REF_WORK_ID->value))
|
||||
->required()
|
||||
->min(1)
|
||||
->max(parent::SIZE_VARCHAR),
|
||||
|
||||
(new Rules(TagsTable::NAME->value))
|
||||
->required()
|
||||
->type(Type::ENUM, TagsNameEnum::names())
|
||||
]);
|
||||
|
||||
$this->ruleset->validate_or_exit();
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
private static function get_entity(): Response {
|
||||
return (new Call(Endpoints::WORK->value))->params([
|
||||
WorkTable::ID->value => $_POST[TagsTable::REF_WORK_ID->value]
|
||||
])->get();
|
||||
}
|
||||
|
||||
public function main(): Response {
|
||||
// Bail out if work entity could not be fetched
|
||||
$entity = self::get_entity();
|
||||
if (!$entity->ok) {
|
||||
return $entity;
|
||||
}
|
||||
|
||||
return $this->db->for(TagsTable::NAME)->insert($_POST) === true
|
||||
? new Response($_POST[TagsTable::REF_WORK_ID->value], 201)
|
||||
: new Response("Failed to add tag to work entity", 500);
|
||||
}
|
||||
}
|
|
@ -121,7 +121,10 @@ section.timeline .items .item img {
|
|||
}
|
||||
|
||||
section.timeline .items .item .actions {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
margin-top: 7px;
|
||||
gap: var(--padding);
|
||||
}
|
||||
|
||||
/* # Size queries */
|
||||
|
@ -166,6 +169,10 @@ section.timeline .items .item .actions {
|
|||
border-top-color: rgba(var(--primer-color-accent), .2);
|
||||
}
|
||||
|
||||
section.timeline .items .item .actions {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
section.timeline .year:first-of-type .month:first-of-type .day:first-of-type .items .item:first-of-type {
|
||||
margin-top: var(--padding);
|
||||
}
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
../../../../../node_modules/elevent/src/Elevent.mjs
|
2
public/robots.txt
Normal file
2
public/robots.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
User-agent: *
|
||||
Disallow:
|
Loading…
Add table
Reference in a new issue