mirror of
https://codeberg.org/vlw/vlw.se.git
synced 2025-09-14 05:13:46 +02:00
Compare commits
2 commits
2fa62991f9
...
4b71bbd10e
Author | SHA1 | Date | |
---|---|---|---|
4b71bbd10e | |||
56cf142e0d |
109 changed files with 1778 additions and 3120 deletions
|
@ -1,7 +1,20 @@
|
||||||
[api]
|
[client_api]
|
||||||
base_url = "https://api.vlw.one/"
|
base_url = ""
|
||||||
api_key = ""
|
api_key = ""
|
||||||
verify_peer = 0
|
verify_peer = true
|
||||||
|
|
||||||
[time]
|
[client_time_available]
|
||||||
date_time_zone = "Europe/Stockholm"
|
time_zone = "Europe/Stockholm"
|
||||||
|
available_to_hour = 0;
|
||||||
|
reply_average_hours = 0;
|
||||||
|
available_from_hour = 0;
|
||||||
|
|
||||||
|
[server_database]
|
||||||
|
host = ""
|
||||||
|
user = ""
|
||||||
|
pass = ""
|
||||||
|
db = ""
|
||||||
|
|
||||||
|
[server_forgejo]
|
||||||
|
base_url = ""
|
||||||
|
scan_profiles = ""
|
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -1,9 +1,7 @@
|
||||||
# Public assets #
|
# Public assets #
|
||||||
#################
|
#################
|
||||||
public/robots.txt
|
|
||||||
public/.well-known
|
public/.well-known
|
||||||
|
public/assets/js/modules/npm
|
||||||
assets/js/modules/npm
|
|
||||||
|
|
||||||
# Bootstrapping #
|
# Bootstrapping #
|
||||||
#################
|
#################
|
||||||
|
|
103
README.md
103
README.md
|
@ -1,73 +1,66 @@
|
||||||
# vlw.se
|
# 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
|
# 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
|
**Make sure you have both of these package managers installed before proceeding:**
|
||||||
- [PHP 8.0+](https://www.php.net/)
|
- [Composer](https://getcomposer.org/)
|
||||||
- [MariaDB 14+](https://mariadb.org/)
|
- [NPM](https://www.npmjs.com/)
|
||||||
- [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/)
|
|
||||||
|
|
||||||
**Confimed supported framework versions:**
|
## 1. Clone this repo
|
||||||
Vegvisir|Reflect
|
Clone/download this repo to your machine. Preferably to a non-public directory - the frameworks will handle that.
|
||||||
--|--
|
|
||||||
✅ [`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)
|
|
||||||
|
|
||||||
## Website (Vegvisir)
|
```
|
||||||
1. **Download this repo**
|
git clone https://codeberg.org/vlw/vlw.se --depth 1
|
||||||
|
```
|
||||||
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.
|
|
||||||
|
|
||||||
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.
|
- [Vegvisir installation](https://vegvisir.vlw.se)
|
||||||
```
|
- [Reflect installation](https://reflect.vlw.se)
|
||||||
./install.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
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)
|
## 3. Run the install script
|
||||||
The API (and database) is where most content is stored and served from on this website.
|
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
|
- [Download SQL-snapshots](https://codeberg.org/vlw/vlw.se/releases)
|
||||||
```
|
|
||||||
git clone https://codeberg.org/vlw/vlw.se
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Download and install Reflect**
|
## 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:
|
||||||
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.
|
|
||||||
|
|
||||||
3. **Install dependencies**
|
```ini
|
||||||
|
[client_api]
|
||||||
|
base_url = ""
|
||||||
|
api_key = ""
|
||||||
|
|
||||||
`cd` into the api folder and install dependencies with composer.
|
[server_database]
|
||||||
```
|
host = ""
|
||||||
composer install --optimize-autoloader
|
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.
|
## Done!
|
||||||
|
That should be it. Navigate to your configured Vegvisir public host!
|
||||||
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.
|
|
|
@ -1,19 +0,0 @@
|
||||||
[connect]
|
|
||||||
host = ""
|
|
||||||
user = ""
|
|
||||||
pass = ""
|
|
||||||
|
|
||||||
[databases]
|
|
||||||
vlw = ""
|
|
||||||
battlestation = ""
|
|
||||||
|
|
||||||
; Forgejo instance config
|
|
||||||
[forgejo]
|
|
||||||
base_url = ""
|
|
||||||
|
|
||||||
; Forgejo language chart endpoints config
|
|
||||||
[about_languages]
|
|
||||||
; CSV of Forgejo profiles to include public source repositories from
|
|
||||||
scan_profiles = ""
|
|
||||||
; Path to a JSON file to store cached language endpoint responses
|
|
||||||
cache_file = ""
|
|
|
@ -1,8 +0,0 @@
|
||||||
{
|
|
||||||
"require": {
|
|
||||||
"reflect/plugin-rules": "^1.5",
|
|
||||||
"victorwesterlund/xenum": "dev-master",
|
|
||||||
"vlw/mysql": "dev-master"
|
|
||||||
},
|
|
||||||
"minimum-stability": "dev"
|
|
||||||
}
|
|
115
api/composer.lock
generated
115
api/composer.lock
generated
|
@ -1,115 +0,0 @@
|
||||||
{
|
|
||||||
"_readme": [
|
|
||||||
"This file locks the dependencies of your project to a known state",
|
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
|
||||||
"This file is @generated automatically"
|
|
||||||
],
|
|
||||||
"content-hash": "f3f2b3cb3bd789eee6af4a93f4a6e0f9",
|
|
||||||
"packages": [
|
|
||||||
{
|
|
||||||
"name": "reflect/plugin-rules",
|
|
||||||
"version": "1.5.1",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://codeberg.org/reflect/reflect-rules-plugin",
|
|
||||||
"reference": "df150f0d860dbc2311e5e2fcb2fac36ee52db56b"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"ReflectRules\\": "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"GPL-3.0-only"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Victor Westerlund",
|
|
||||||
"email": "victor.vesterlund@gmail.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Add request search paramter and request body constraints to an API built with Reflect",
|
|
||||||
"time": "2024-11-20T10:39:33+00:00"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "victorwesterlund/xenum",
|
|
||||||
"version": "dev-master",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/VictorWesterlund/php-xenum.git",
|
|
||||||
"reference": "8972f06f42abd1f382807a67e937d5564bb89699"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/VictorWesterlund/php-xenum/zipball/8972f06f42abd1f382807a67e937d5564bb89699",
|
|
||||||
"reference": "8972f06f42abd1f382807a67e937d5564bb89699",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"default-branch": true,
|
|
||||||
"type": "library",
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"victorwesterlund\\": "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"GPL-3.0-only"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Victor Westerlund",
|
|
||||||
"email": "victor.vesterlund@gmail.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "PHP eXtended Enums. The missing quality-of-life features from PHP 8+ Enums",
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/VictorWesterlund/php-xenum/issues",
|
|
||||||
"source": "https://github.com/VictorWesterlund/php-xenum/tree/1.1.1"
|
|
||||||
},
|
|
||||||
"time": "2023-11-20T10:10:39+00:00"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "vlw/mysql",
|
|
||||||
"version": "dev-master",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://codeberg.org/vlw/php-mysql",
|
|
||||||
"reference": "619f43b3bfab9eb034dca3e54c7466055240c861"
|
|
||||||
},
|
|
||||||
"default-branch": true,
|
|
||||||
"type": "library",
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"vlw\\MySQL\\": "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"GPL-3.0-or-later"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Victor Westerlund",
|
|
||||||
"email": "victor@vlw.se"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Abstraction library for common MySQL/MariaDB DML operations with php-mysqli",
|
|
||||||
"time": "2024-09-25T13:28:15+00:00"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"packages-dev": [],
|
|
||||||
"aliases": [],
|
|
||||||
"minimum-stability": "dev",
|
|
||||||
"stability-flags": {
|
|
||||||
"victorwesterlund/xenum": 20,
|
|
||||||
"vlw/mysql": 20
|
|
||||||
},
|
|
||||||
"prefer-stable": false,
|
|
||||||
"prefer-lowest": false,
|
|
||||||
"platform": [],
|
|
||||||
"platform-dev": [],
|
|
||||||
"plugin-api-version": "2.3.0"
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use Reflect\Call;
|
|
||||||
use Reflect\Path;
|
|
||||||
use Reflect\Response;
|
|
||||||
|
|
||||||
const MSG_OK = "Cache file deleted";
|
|
||||||
const MSG_FAIL = "Cache file does not exist or can't be deleted";
|
|
||||||
|
|
||||||
class DELETE_AboutLanguages {
|
|
||||||
public function __construct() {}
|
|
||||||
|
|
||||||
// Delete languages cache file if it exists
|
|
||||||
public function main(): Response {
|
|
||||||
// Bail out if cache is not used
|
|
||||||
if (empty($_ENV["forgejo_languages"]["cache_file"])) {
|
|
||||||
return new Response(MSG_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
return unlink($_ENV["forgejo_languages"]["cache_file"]) ? new Response(MSG_OK) : new Response(MSG_FAIL, 404);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use Reflect\Call;
|
|
||||||
use Reflect\Path;
|
|
||||||
use Reflect\Response;
|
|
||||||
use ReflectRules\Type;
|
|
||||||
use ReflectRules\Rules;
|
|
||||||
use ReflectRules\Ruleset;
|
|
||||||
|
|
||||||
use VLW\API\Endpoints;
|
|
||||||
|
|
||||||
require_once Path::root("src/Endpoints.php");
|
|
||||||
|
|
||||||
const PARM_FORCE_RECACHE = "force_recache";
|
|
||||||
|
|
||||||
class GET_AboutLanguages {
|
|
||||||
protected Ruleset $ruleset;
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
$this->ruleset = new Ruleset(strict: true);
|
|
||||||
|
|
||||||
$this->ruleset->GET([
|
|
||||||
(new Rules(PARM_FORCE_RECACHE))
|
|
||||||
->type(Type::BOOLEAN)
|
|
||||||
->default(false)
|
|
||||||
]);
|
|
||||||
|
|
||||||
$this->ruleset->validate_or_exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static function cache_exists(): bool {
|
|
||||||
return file_exists($_ENV["forgejo_languages"]["cache_file"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static function load_cache(): array {
|
|
||||||
return json_decode(file_get_contents($_ENV["forgejo_languages"]["cache_file"]), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function main(): Response {
|
|
||||||
// Delete cache file if force flag is set
|
|
||||||
if ($_GET[PARM_FORCE_RECACHE]) {
|
|
||||||
(new Call(Endpoints::ABOUT_LANGUAGES->value))->delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
return self::cache_exists()
|
|
||||||
// Return languages from cache
|
|
||||||
? new Response(self::load_cache())
|
|
||||||
// Fetch and return languages (and generate cache file if enabled)
|
|
||||||
: new Response((new Call(Endpoints::ABOUT_LANGUAGES->value))->post());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,63 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use Reflect\Path;
|
|
||||||
use Reflect\Response;
|
|
||||||
use ReflectRules\Type;
|
|
||||||
use ReflectRules\Rules;
|
|
||||||
use ReflectRules\Ruleset;
|
|
||||||
|
|
||||||
use VLW\API\Databases\VLWdb\{
|
|
||||||
VLWdb,
|
|
||||||
Databases
|
|
||||||
};
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Battlestation\Config\ConfigModel;
|
|
||||||
|
|
||||||
require_once Path::root("src/databases/VLWdb.php");
|
|
||||||
require_once Path::root("src/databases/models/Battlestation/Config/Config.php");
|
|
||||||
|
|
||||||
class GET_Battlestation extends VLWdb {
|
|
||||||
protected Ruleset $ruleset;
|
|
||||||
|
|
||||||
private array $query;
|
|
||||||
private array $results = [];
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
$this->ruleset = new Ruleset(strict: true);
|
|
||||||
|
|
||||||
$this->ruleset->GET([
|
|
||||||
(new Rules(ConfigModel::REF_MB_ID->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(parent::UUID_LENGTH)
|
|
||||||
->max(parent::UUID_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(ConfigModel::FRIENDLY_NAME->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH)
|
|
||||||
]);
|
|
||||||
|
|
||||||
parent::__construct(Databases::BATTLESTATION, $this->ruleset);
|
|
||||||
|
|
||||||
// Use a copy of search parameters
|
|
||||||
$this->query = $_GET;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function get_config(): array {
|
|
||||||
return $this->results = $this->db
|
|
||||||
->for(ConfigModel::TABLE)
|
|
||||||
->where($this->query)
|
|
||||||
->order([ConfigModel::DATE_BUILT->value => "DESC"])
|
|
||||||
->select(ConfigModel::values())
|
|
||||||
->fetch_all(MYSQLI_ASSOC);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function main(): Response {
|
|
||||||
// Set properties as "searchable"
|
|
||||||
parent::make_wildcard_search(ConfigModel::FRIENDLY_NAME->value, $this->query);
|
|
||||||
|
|
||||||
$this->get_config();
|
|
||||||
|
|
||||||
// Return 404 Not Found if response array is empty
|
|
||||||
return new Response($this->results, $this->results ? 200 : 404);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,103 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use Reflect\Path;
|
|
||||||
use Reflect\Response;
|
|
||||||
use ReflectRules\Type;
|
|
||||||
use ReflectRules\Rules;
|
|
||||||
use ReflectRules\Ruleset;
|
|
||||||
|
|
||||||
use VLW\API\Databases\VLWdb\{
|
|
||||||
VLWdb,
|
|
||||||
Databases
|
|
||||||
};
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Battlestation\ChassisModel;
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Battlestation\Config\ChassisMbModel;
|
|
||||||
|
|
||||||
require_once Path::root("src/databases/VLWdb.php");
|
|
||||||
require_once Path::root("src/databases/models/Battlestation/Chassis.php");
|
|
||||||
require_once Path::root("src/databases/models/Battlestation/Config/ChassisMb.php");
|
|
||||||
|
|
||||||
class GET_BattlestationChassis extends VLWdb {
|
|
||||||
private const REL_MOTHERBOARDS = "motherboards";
|
|
||||||
|
|
||||||
protected Ruleset $ruleset;
|
|
||||||
|
|
||||||
private array $query;
|
|
||||||
private array $results = [];
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
$this->ruleset = new Ruleset(strict: true);
|
|
||||||
|
|
||||||
$this->ruleset->GET([
|
|
||||||
(new Rules(ChassisModel::ID->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(parent::UUID_LENGTH)
|
|
||||||
->max(parent::UUID_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(ChassisModel::VENDOR_NAME->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(ChassisModel::VENDOR_MODEL->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(ChassisModel::STORAGE_TWOINCHFIVE->value))
|
|
||||||
->type(Type::NUMBER)
|
|
||||||
->type(Type::NULL)
|
|
||||||
->min(0)
|
|
||||||
->max(parent::MYSQL_TINYINT_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(ChassisModel::STORAGE_THREEINCHFIVE->value))
|
|
||||||
->type(Type::NUMBER)
|
|
||||||
->type(Type::NULL)
|
|
||||||
->min(0)
|
|
||||||
->max(parent::MYSQL_TINYINT_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(ChassisModel::IS_RETIRED->value))
|
|
||||||
->type(Type::BOOLEAN)
|
|
||||||
]);
|
|
||||||
|
|
||||||
parent::__construct(Databases::BATTLESTATION, $this->ruleset);
|
|
||||||
|
|
||||||
// Use a copy of search parameters
|
|
||||||
$this->query = $_GET;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function get_motherboards(): void {
|
|
||||||
foreach ($this->results as &$result) {
|
|
||||||
// Get motherboard id from relationship by chassis id
|
|
||||||
$result[self::REL_MOTHERBOARDS] = $this->db
|
|
||||||
->for(ChassisMbModel::TABLE)
|
|
||||||
->where([ChassisMbModel::REF_CHASSIS_ID->value => $result[ChassisModel::ID->value]])
|
|
||||||
->select(ChassisMbModel::values())
|
|
||||||
->fetch_all(MYSQLI_ASSOC);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function get_chassis(): array {
|
|
||||||
return $this->results = $this->db
|
|
||||||
->for(ChassisModel::TABLE)
|
|
||||||
->where($this->query)
|
|
||||||
->order([ChassisModel::DATE_AQUIRED->value => "DESC"])
|
|
||||||
->select(ChassisModel::values())
|
|
||||||
->fetch_all(MYSQLI_ASSOC);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function main(): Response {
|
|
||||||
// Set properties as "searchable"
|
|
||||||
parent::make_wildcard_search(ChassisModel::VENDOR_NAME->value, $this->query);
|
|
||||||
parent::make_wildcard_search(ChassisModel::VENDOR_MODEL->value, $this->query);
|
|
||||||
|
|
||||||
// Get hardware
|
|
||||||
$this->get_chassis();
|
|
||||||
|
|
||||||
// Resolve hardware relationships
|
|
||||||
$this->get_motherboards();
|
|
||||||
|
|
||||||
// Return 404 Not Found if response array is empty
|
|
||||||
return new Response($this->results, $this->results ? 200 : 404);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,108 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use Reflect\Path;
|
|
||||||
use Reflect\Response;
|
|
||||||
use ReflectRules\Type;
|
|
||||||
use ReflectRules\Rules;
|
|
||||||
use ReflectRules\Ruleset;
|
|
||||||
|
|
||||||
use VLW\API\Databases\VLWdb\{
|
|
||||||
VLWdb,
|
|
||||||
Databases
|
|
||||||
};
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Battlestation\{
|
|
||||||
CoolerModel
|
|
||||||
};
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Battlestation\Config\MbCpuCoolerModel;
|
|
||||||
|
|
||||||
require_once Path::root("src/databases/VLWdb.php");
|
|
||||||
require_once Path::root("src/databases/models/Battlestation/Coolers.php");
|
|
||||||
require_once Path::root("src/databases/models/Battlestation/Config/MbCpuCooler.php");
|
|
||||||
|
|
||||||
class GET_BattlestationCoolers extends VLWdb {
|
|
||||||
private const REL_MOTHERBOARDS = "motherboards";
|
|
||||||
|
|
||||||
protected Ruleset $ruleset;
|
|
||||||
|
|
||||||
private array $query;
|
|
||||||
private array $results = [];
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
$this->ruleset = new Ruleset(strict: true);
|
|
||||||
|
|
||||||
$this->ruleset->GET([
|
|
||||||
(new Rules(CoolerModel::ID->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(parent::UUID_LENGTH)
|
|
||||||
->max(parent::UUID_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(CoolerModel::TYPE_LIQUID->value))
|
|
||||||
->type(Type::BOOLEAN),
|
|
||||||
|
|
||||||
(new Rules(CoolerModel::SIZE_FAN->value))
|
|
||||||
->type(Type::NULL)
|
|
||||||
->type(Type::NUMBER)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_INTR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(CoolerModel::SIZE_RADIATOR->value))
|
|
||||||
->type(Type::NULL)
|
|
||||||
->type(Type::NUMBER)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_INTR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(CoolerModel::VENDOR_NAME->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(CoolerModel::VENDOR_MODEL->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(CoolerModel::IS_RETIRED->value))
|
|
||||||
->type(Type::BOOLEAN)
|
|
||||||
]);
|
|
||||||
|
|
||||||
parent::__construct(Databases::BATTLESTATION, $this->ruleset);
|
|
||||||
|
|
||||||
// Use a copy of search parameters
|
|
||||||
$this->query = $_GET;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function get_motherboards(): void {
|
|
||||||
foreach ($this->results as &$result) {
|
|
||||||
// Get motherboard id from relationship by chassis id
|
|
||||||
$result[self::REL_MOTHERBOARDS] = $this->db
|
|
||||||
->for(MbCoolerModel::TABLE)
|
|
||||||
->where([MbCoolerModel::REF_COOLER_ID->value => $result[CoolerModel::ID->value]])
|
|
||||||
->select(MbCoolerModel::values())
|
|
||||||
->fetch_all(MYSQLI_ASSOC);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function get_coolers(): array {
|
|
||||||
return $this->results = $this->db
|
|
||||||
->for(CoolerModel::TABLE)
|
|
||||||
->where($this->query)
|
|
||||||
->order([CoolerModel::DATE_AQUIRED->value => "DESC"])
|
|
||||||
->select(CoolerModel::values())
|
|
||||||
->fetch_all(MYSQLI_ASSOC);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function main(): Response {
|
|
||||||
// Set properties as "searchable"
|
|
||||||
parent::make_wildcard_search(CoolerModel::VENDOR_NAME->value, $this->query);
|
|
||||||
parent::make_wildcard_search(CoolerModel::VENDOR_MODEL->value, $this->query);
|
|
||||||
|
|
||||||
// Get hardware
|
|
||||||
$this->get_coolers();
|
|
||||||
|
|
||||||
// Resolve hardware relationships
|
|
||||||
$this->get_motherboards();
|
|
||||||
|
|
||||||
// Return 404 Not Found if response array is empty
|
|
||||||
return new Response($this->results, $this->results ? 200 : 404);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,117 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use Reflect\Path;
|
|
||||||
use Reflect\Response;
|
|
||||||
use ReflectRules\Type;
|
|
||||||
use ReflectRules\Rules;
|
|
||||||
use ReflectRules\Ruleset;
|
|
||||||
|
|
||||||
use VLW\API\Databases\VLWdb\{
|
|
||||||
VLWdb,
|
|
||||||
Databases
|
|
||||||
};
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Battlestation\{
|
|
||||||
CpuModel,
|
|
||||||
ClassEnum
|
|
||||||
};
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Battlestation\Config\MbCpuCoolerModel;
|
|
||||||
|
|
||||||
require_once Path::root("src/databases/VLWdb.php");
|
|
||||||
require_once Path::root("src/databases/models/Battlestation/Cpu.php");
|
|
||||||
require_once Path::root("src/databases/models/Battlestation/Config/MbCpuCooler.php");
|
|
||||||
|
|
||||||
class GET_BattlestationCpu extends VLWdb {
|
|
||||||
private const REL_MOTHERBOARDS = "motherboards";
|
|
||||||
|
|
||||||
protected Ruleset $ruleset;
|
|
||||||
|
|
||||||
private array $query;
|
|
||||||
private array $results = [];
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
$this->ruleset = new Ruleset(strict: true);
|
|
||||||
|
|
||||||
$this->ruleset->GET([
|
|
||||||
(new Rules(CpuModel::ID->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(parent::UUID_LENGTH)
|
|
||||||
->max(parent::UUID_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(CpuModel::CLOCK_BASE->value))
|
|
||||||
->type(Type::NUMBER)
|
|
||||||
->min(1),
|
|
||||||
|
|
||||||
(new Rules(CpuModel::CLOCK_TURBO->value))
|
|
||||||
->type(Type::NUMBER)
|
|
||||||
->min(1),
|
|
||||||
|
|
||||||
(new Rules(CpuModel::CORE_COUNT_PERFORMANCE->value))
|
|
||||||
->type(Type::NUMBER)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_TINYINT_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(CpuModel::CORE_COUNT_EFFICIENCY->value))
|
|
||||||
->type(Type::NUMBER)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_TINYINT_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(CpuModel::CORE_THREADS->value))
|
|
||||||
->type(Type::NUMBER)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_TINYINT_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(CpuModel::VENDOR_NAME->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(CpuModel::VENDOR_MODEL->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(CpuModel::IS_RETIRED->value))
|
|
||||||
->type(Type::BOOLEAN)
|
|
||||||
]);
|
|
||||||
|
|
||||||
parent::__construct(Databases::BATTLESTATION, $this->ruleset);
|
|
||||||
|
|
||||||
// Use a copy of search parameters
|
|
||||||
$this->query = $_GET;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function get_motherboards(): void {
|
|
||||||
foreach ($this->results as &$result) {
|
|
||||||
// Get motherboard id from relationship by chassis id
|
|
||||||
$result[self::REL_MOTHERBOARDS] = $this->db
|
|
||||||
->for(MbCpuCoolerModel::TABLE)
|
|
||||||
->where([MbCpuCoolerModel::REF_CPU_ID->value => $result[CpuModel::ID->value]])
|
|
||||||
->select(MbCpuCoolerModel::values())
|
|
||||||
->fetch_all(MYSQLI_ASSOC);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function get_cpu(): array {
|
|
||||||
return $this->results = $this->db
|
|
||||||
->for(CpuModel::TABLE)
|
|
||||||
->where($this->query)
|
|
||||||
->order([CpuModel::DATE_AQUIRED->value => "DESC"])
|
|
||||||
->select(CpuModel::values())
|
|
||||||
->fetch_all(MYSQLI_ASSOC);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function main(): Response {
|
|
||||||
// Set properties as "searchable"
|
|
||||||
parent::make_wildcard_search(CpuModel::VENDOR_NAME->value, $this->query);
|
|
||||||
parent::make_wildcard_search(CpuModel::VENDOR_MODEL->value, $this->query);
|
|
||||||
|
|
||||||
// Get hardware
|
|
||||||
$this->get_cpu();
|
|
||||||
|
|
||||||
// Resolve hardware relationships
|
|
||||||
$this->get_motherboards();
|
|
||||||
|
|
||||||
// Return 404 Not Found if response array is empty
|
|
||||||
return new Response($this->results, $this->results ? 200 : 404);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,115 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use Reflect\Path;
|
|
||||||
use Reflect\Response;
|
|
||||||
use ReflectRules\Type;
|
|
||||||
use ReflectRules\Rules;
|
|
||||||
use ReflectRules\Ruleset;
|
|
||||||
|
|
||||||
use VLW\API\Databases\VLWdb\{
|
|
||||||
VLWdb,
|
|
||||||
Databases
|
|
||||||
};
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Battlestation\{
|
|
||||||
DramModel,
|
|
||||||
DramFormfactorEnum,
|
|
||||||
DramTechnologyEnum
|
|
||||||
};
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Battlestation\Config\MbDramModel;
|
|
||||||
|
|
||||||
require_once Path::root("src/databases/VLWdb.php");
|
|
||||||
require_once Path::root("src/databases/models/Battlestation/Dram.php");
|
|
||||||
require_once Path::root("src/databases/models/Battlestation/Config/MbDram.php");
|
|
||||||
|
|
||||||
class GET_BattlestationDram extends VLWdb {
|
|
||||||
private const REL_MOTHERBOARDS = "motherboards";
|
|
||||||
|
|
||||||
protected Ruleset $ruleset;
|
|
||||||
|
|
||||||
private array $query;
|
|
||||||
private array $results = [];
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
$this->ruleset = new Ruleset(strict: true);
|
|
||||||
|
|
||||||
$this->ruleset->GET([
|
|
||||||
(new Rules(DramModel::ID->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(parent::UUID_LENGTH)
|
|
||||||
->max(parent::UUID_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(DramModel::CAPACITY->value))
|
|
||||||
->type(Type::NUMBER)
|
|
||||||
->min(1),
|
|
||||||
|
|
||||||
(new Rules(DramModel::SPEED->value))
|
|
||||||
->type(Type::NUMBER)
|
|
||||||
->min(1),
|
|
||||||
|
|
||||||
(new Rules(DramModel::FORMFACTOR->value))
|
|
||||||
->type(Type::ENUM, DramFormfactorEnum::names()),
|
|
||||||
|
|
||||||
(new Rules(DramModel::TECHNOLOGY->value))
|
|
||||||
->type(Type::ENUM, DramTechnologyEnum::names()),
|
|
||||||
|
|
||||||
(new Rules(DramModel::ECC->value))
|
|
||||||
->type(Type::BOOLEAN),
|
|
||||||
|
|
||||||
(new Rules(DramModel::BUFFERED->value))
|
|
||||||
->type(Type::BOOLEAN),
|
|
||||||
|
|
||||||
(new Rules(DramModel::VENDOR_NAME->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(DramModel::VENDOR_MODEL->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(DramModel::IS_RETIRED->value))
|
|
||||||
->type(Type::BOOLEAN)
|
|
||||||
]);
|
|
||||||
|
|
||||||
parent::__construct(Databases::BATTLESTATION, $this->ruleset);
|
|
||||||
|
|
||||||
// Use a copy of search parameters
|
|
||||||
$this->query = $_GET;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function get_motherboards(): void {
|
|
||||||
foreach ($this->results as &$result) {
|
|
||||||
// Get motherboard id from relationship by chassis id
|
|
||||||
$result[self::REL_MOTHERBOARDS] = $this->db
|
|
||||||
->for(MbDramModel::TABLE)
|
|
||||||
->where([MbDramModel::REF_DRAM_ID->value => $result[DramModel::ID->value]])
|
|
||||||
->select(MbDramModel::values())
|
|
||||||
->fetch_all(MYSQLI_ASSOC);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function get_dram(): array {
|
|
||||||
return $this->results = $this->db
|
|
||||||
->for(DramModel::TABLE)
|
|
||||||
->where($this->query)
|
|
||||||
->order([DramModel::DATE_AQUIRED->value => "DESC"])
|
|
||||||
->select(DramModel::values())
|
|
||||||
->fetch_all(MYSQLI_ASSOC);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function main(): Response {
|
|
||||||
// Set properties as "searchable"
|
|
||||||
parent::make_wildcard_search(DramModel::VENDOR_NAME->value, $this->query);
|
|
||||||
parent::make_wildcard_search(DramModel::VENDOR_MODEL->value, $this->query);
|
|
||||||
|
|
||||||
// Get hardware
|
|
||||||
$this->get_dram();
|
|
||||||
|
|
||||||
// Resolve hardware relationships
|
|
||||||
$this->get_motherboards();
|
|
||||||
|
|
||||||
// Return 404 Not Found if response array is empty
|
|
||||||
return new Response($this->results, $this->results ? 200 : 404);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,107 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use Reflect\Path;
|
|
||||||
use Reflect\Response;
|
|
||||||
use ReflectRules\Type;
|
|
||||||
use ReflectRules\Rules;
|
|
||||||
use ReflectRules\Ruleset;
|
|
||||||
|
|
||||||
use VLW\API\Databases\VLWdb\{
|
|
||||||
VLWdb,
|
|
||||||
Databases
|
|
||||||
};
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Battlestation\GpuModel;
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Battlestation\Config\MbGpuModel;
|
|
||||||
|
|
||||||
require_once Path::root("src/databases/VLWdb.php");
|
|
||||||
require_once Path::root("src/databases/models/Battlestation/Gpu.php");
|
|
||||||
require_once Path::root("src/databases/models/Battlestation/Config/MbGpu.php");
|
|
||||||
|
|
||||||
class GET_BattlestationGpu extends VLWdb {
|
|
||||||
private const REL_MOTHERBOARDS = "motherboards";
|
|
||||||
|
|
||||||
protected Ruleset $ruleset;
|
|
||||||
|
|
||||||
private array $query;
|
|
||||||
private array $results = [];
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
$this->ruleset = new Ruleset(strict: true);
|
|
||||||
|
|
||||||
$this->ruleset->GET([
|
|
||||||
(new Rules(GpuModel::ID->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(parent::UUID_LENGTH)
|
|
||||||
->max(parent::UUID_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(GpuModel::MEMORY->value))
|
|
||||||
->type(Type::NUMBER)
|
|
||||||
->min(1),
|
|
||||||
|
|
||||||
(new Rules(GpuModel::VENDOR_NAME->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(GpuModel::VENDOR_MODEL->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(GpuModel::VENDOR_CHIP_NAME->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(GpuModel::VENDOR_CHIP_MODEL->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(GpuModel::IS_RETIRED->value))
|
|
||||||
->type(Type::BOOLEAN)
|
|
||||||
]);
|
|
||||||
|
|
||||||
parent::__construct(Databases::BATTLESTATION, $this->ruleset);
|
|
||||||
|
|
||||||
// Use a copy of search parameters
|
|
||||||
$this->query = $_GET;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function get_motherboards(): void {
|
|
||||||
foreach ($this->results as &$result) {
|
|
||||||
// Get motherboard id from relationship by chassis id
|
|
||||||
$result[self::REL_MOTHERBOARDS] = $this->db
|
|
||||||
->for(MbGpuModel::TABLE)
|
|
||||||
->where([MbGpuModel::REF_GPU_ID->value => $result[GpuModel::ID->value]])
|
|
||||||
->select(MbGpuModel::values())
|
|
||||||
->fetch_all(MYSQLI_ASSOC);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function get_gpu(): array {
|
|
||||||
return $this->results = $this->db
|
|
||||||
->for(GpuModel::TABLE)
|
|
||||||
->where($this->query)
|
|
||||||
->order([GpuModel::DATE_AQUIRED->value => "DESC"])
|
|
||||||
->select(GpuModel::values())
|
|
||||||
->fetch_all(MYSQLI_ASSOC);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function main(): Response {
|
|
||||||
// Set properties as "searchable"
|
|
||||||
parent::make_wildcard_search(GpuModel::VENDOR_NAME->value, $this->query);
|
|
||||||
parent::make_wildcard_search(GpuModel::VENDOR_MODEL->value, $this->query);
|
|
||||||
parent::make_wildcard_search(GpuModel::VENDOR_CHIP_NAME->value, $this->query);
|
|
||||||
parent::make_wildcard_search(GpuModel::VENDOR_CHIP_MODEL->value, $this->query);
|
|
||||||
|
|
||||||
// Get hardware
|
|
||||||
$this->get_gpu();
|
|
||||||
|
|
||||||
// Resolve hardware relationships
|
|
||||||
$this->get_motherboards();
|
|
||||||
|
|
||||||
// Return 404 Not Found if response array is empty
|
|
||||||
return new Response($this->results, $this->results ? 200 : 404);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,194 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use Reflect\Path;
|
|
||||||
use Reflect\Response;
|
|
||||||
use ReflectRules\Type;
|
|
||||||
use ReflectRules\Rules;
|
|
||||||
use ReflectRules\Ruleset;
|
|
||||||
|
|
||||||
use VLW\API\Databases\VLWdb\{
|
|
||||||
VLWdb,
|
|
||||||
Databases
|
|
||||||
};
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Battlestation\{
|
|
||||||
MbModel,
|
|
||||||
MbFormfactorEnum
|
|
||||||
};
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Battlestation\Config\{
|
|
||||||
MbGpuModel,
|
|
||||||
MbPsuModel,
|
|
||||||
MbDramModel,
|
|
||||||
MbStorageModel,
|
|
||||||
ChassisMbModel,
|
|
||||||
MbCpuCoolerModel
|
|
||||||
};
|
|
||||||
|
|
||||||
require_once Path::root("src/databases/VLWdb.php");
|
|
||||||
require_once Path::root("src/databases/models/Battlestation/Mb.php");
|
|
||||||
require_once Path::root("src/databases/models/Battlestation/Config/MbPsu.php");
|
|
||||||
require_once Path::root("src/databases/models/Battlestation/Config/MbGpu.php");
|
|
||||||
require_once Path::root("src/databases/models/Battlestation/Config/MbDram.php");
|
|
||||||
require_once Path::root("src/databases/models/Battlestation/Config/MbStorage.php");
|
|
||||||
require_once Path::root("src/databases/models/Battlestation/Config/ChassisMb.php");
|
|
||||||
require_once Path::root("src/databases/models/Battlestation/Config/MbCpuCooler.php");
|
|
||||||
|
|
||||||
class GET_BattlestationMb extends VLWdb {
|
|
||||||
private const REL_CPU = "cpus";
|
|
||||||
private const REL_PSU = "psus";
|
|
||||||
private const REL_GPU = "gpus";
|
|
||||||
private const REL_DRAM = "dram";
|
|
||||||
private const REL_STORAGE = "storage";
|
|
||||||
private const REL_CHASSIS = "chassis";
|
|
||||||
|
|
||||||
protected Ruleset $ruleset;
|
|
||||||
|
|
||||||
private array $query;
|
|
||||||
private array $results = [];
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
$this->ruleset = new Ruleset(strict: true);
|
|
||||||
|
|
||||||
$this->ruleset->GET([
|
|
||||||
(new Rules(MbModel::ID->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(parent::UUID_LENGTH)
|
|
||||||
->max(parent::UUID_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(MbModel::FORMFACTOR->value))
|
|
||||||
->type(Type::ENUM, MbFormfactorEnum::names()),
|
|
||||||
|
|
||||||
(new Rules(MbModel::VENDOR_NAME->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(MbModel::VENDOR_MODEL->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(MbModel::NETWORK_ETHERNET->value))
|
|
||||||
->type(Type::NULL)
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(MbModel::NETWORK_WLAN->value))
|
|
||||||
->type(Type::NULL)
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(MbModel::NETWORK_BLUETOOTH->value))
|
|
||||||
->type(Type::NULL)
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(MbModel::IS_RETIRED->value))
|
|
||||||
->type(Type::BOOLEAN)
|
|
||||||
]);
|
|
||||||
|
|
||||||
parent::__construct(Databases::BATTLESTATION, $this->ruleset);
|
|
||||||
|
|
||||||
// Use a copy of search parameters
|
|
||||||
$this->query = $_GET;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function get_chassis(): void {
|
|
||||||
foreach ($this->results as &$result) {
|
|
||||||
// Get motherboard id from relationship by chassis id
|
|
||||||
$result[self::REL_CHASSIS] = $this->db
|
|
||||||
->for(ChassisMbModel::TABLE)
|
|
||||||
->where([ChassisMbModel::REF_MB_ID->value => $result[MbModel::ID->value]])
|
|
||||||
->select(ChassisMbModel::values())
|
|
||||||
->fetch_all(MYSQLI_ASSOC);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function get_psu(): void {
|
|
||||||
foreach ($this->results as &$result) {
|
|
||||||
// Get motherboard id from relationship by chassis id
|
|
||||||
$result[self::REL_PSU] = $this->db
|
|
||||||
->for(MbPsuModel::TABLE)
|
|
||||||
->where([MbPsuModel::REF_MB_ID->value => $result[MbModel::ID->value]])
|
|
||||||
->select(MbPsuModel::values())
|
|
||||||
->fetch_all(MYSQLI_ASSOC);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function get_cpu(): void {
|
|
||||||
foreach ($this->results as &$result) {
|
|
||||||
// Get motherboard id from relationship by chassis id
|
|
||||||
$result[self::REL_CPU] = $this->db
|
|
||||||
->for(MbCpuCoolerModel::TABLE)
|
|
||||||
->where([MbCpuCoolerModel::REF_MB_ID->value => $result[MbModel::ID->value]])
|
|
||||||
->select(MbCpuCoolerModel::values())
|
|
||||||
->fetch_all(MYSQLI_ASSOC);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function get_gpu(): void {
|
|
||||||
foreach ($this->results as &$result) {
|
|
||||||
// Get motherboard id from relationship by chassis id
|
|
||||||
$result[self::REL_GPU] = $this->db
|
|
||||||
->for(MbGpuModel::TABLE)
|
|
||||||
->where([MbGpuModel::REF_MB_ID->value => $result[MbModel::ID->value]])
|
|
||||||
->select(MbGpuModel::values())
|
|
||||||
->fetch_all(MYSQLI_ASSOC);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function get_dram(): void {
|
|
||||||
foreach ($this->results as &$result) {
|
|
||||||
// Get motherboard id from relationship by chassis id
|
|
||||||
$result[self::REL_DRAM] = $this->db
|
|
||||||
->for(MbDramModel::TABLE)
|
|
||||||
->where([MbDramModel::REF_MB_ID->value => $result[MbModel::ID->value]])
|
|
||||||
->select(MbDramModel::values())
|
|
||||||
->fetch_all(MYSQLI_ASSOC);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function get_storage(): void {
|
|
||||||
foreach ($this->results as &$result) {
|
|
||||||
// Get motherboard id from relationship by chassis id
|
|
||||||
$result[self::REL_STORAGE] = $this->db
|
|
||||||
->for(MbStorageModel::TABLE)
|
|
||||||
->where([MbStorageModel::REF_MB_ID->value => $result[MbModel::ID->value]])
|
|
||||||
->select(MbStorageModel::values())
|
|
||||||
->fetch_all(MYSQLI_ASSOC);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----
|
|
||||||
|
|
||||||
private function get_motherboards(): array {
|
|
||||||
return $this->results = $this->db
|
|
||||||
->for(MbModel::TABLE)
|
|
||||||
->where($this->query)
|
|
||||||
->order([MbModel::DATE_AQUIRED->value => "DESC"])
|
|
||||||
->select(MbModel::values())
|
|
||||||
->fetch_all(MYSQLI_ASSOC);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function main(): Response {
|
|
||||||
// Set properties as "searchable"
|
|
||||||
parent::make_wildcard_search(MbModel::VENDOR_NAME->value, $this->query);
|
|
||||||
parent::make_wildcard_search(MbModel::VENDOR_MODEL->value, $this->query);
|
|
||||||
|
|
||||||
// Get hardware
|
|
||||||
$this->get_motherboards();
|
|
||||||
|
|
||||||
// Resolve hardware relationships
|
|
||||||
$this->get_chassis();
|
|
||||||
$this->get_cpu();
|
|
||||||
$this->get_psu();
|
|
||||||
$this->get_gpu();
|
|
||||||
$this->get_dram();
|
|
||||||
$this->get_storage();
|
|
||||||
|
|
||||||
// Return 404 Not Found if response array is empty
|
|
||||||
return new Response($this->results, $this->results ? 200 : 404);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,102 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use Reflect\Path;
|
|
||||||
use Reflect\Response;
|
|
||||||
use ReflectRules\Type;
|
|
||||||
use ReflectRules\Rules;
|
|
||||||
use ReflectRules\Ruleset;
|
|
||||||
|
|
||||||
use VLW\API\Databases\VLWdb\{
|
|
||||||
VLWdb,
|
|
||||||
Databases
|
|
||||||
};
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Battlestation\{
|
|
||||||
PsuModel,
|
|
||||||
EightyplusRatingEnum
|
|
||||||
};
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Battlestation\Config\MbPsuModel;
|
|
||||||
|
|
||||||
require_once Path::root("src/databases/VLWdb.php");
|
|
||||||
require_once Path::root("src/databases/models/Battlestation/Psu.php");
|
|
||||||
require_once Path::root("src/databases/models/Battlestation/Config/MbPsu.php");
|
|
||||||
|
|
||||||
class GET_BattlestationPsu extends VLWdb {
|
|
||||||
private const REL_MOTHERBOARDS = "motherboards";
|
|
||||||
|
|
||||||
protected Ruleset $ruleset;
|
|
||||||
|
|
||||||
private array $query;
|
|
||||||
private array $results = [];
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
$this->ruleset = new Ruleset(strict: true);
|
|
||||||
|
|
||||||
$this->ruleset->GET([
|
|
||||||
(new Rules(PsuModel::ID->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(parent::UUID_LENGTH)
|
|
||||||
->max(parent::UUID_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(PsuModel::POWER->value))
|
|
||||||
->type(Type::NUMBER)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_INT_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(PsuModel::EIGHTYPLUS_RATING->value))
|
|
||||||
->type(Type::ENUM, EightyplusRatingEnum::names()),
|
|
||||||
|
|
||||||
(new Rules(PsuModel::VENDOR_NAME->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(PsuModel::VENDOR_MODEL->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(PsuModel::IS_RETIRED->value))
|
|
||||||
->type(Type::BOOLEAN)
|
|
||||||
]);
|
|
||||||
|
|
||||||
parent::__construct(Databases::BATTLESTATION, $this->ruleset);
|
|
||||||
|
|
||||||
// Use a copy of search parameters
|
|
||||||
$this->query = $_GET;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function get_motherboards(): void {
|
|
||||||
foreach ($this->results as &$result) {
|
|
||||||
// Get motherboard id from relationship by chassis id
|
|
||||||
$result[self::REL_MOTHERBOARDS] = $this->db
|
|
||||||
->for(MbPsuModel::TABLE)
|
|
||||||
->where([MbPsuModel::REF_PSU_ID->value => $result[PsuModel::ID->value]])
|
|
||||||
->select(MbPsuModel::values())
|
|
||||||
->fetch_all(MYSQLI_ASSOC);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function get_psu(): array {
|
|
||||||
return $this->results = $this->db
|
|
||||||
->for(PsuModel::TABLE)
|
|
||||||
->where($this->query)
|
|
||||||
->order([PsuModel::DATE_AQUIRED->value => "DESC"])
|
|
||||||
->select(PsuModel::values())
|
|
||||||
->fetch_all(MYSQLI_ASSOC);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function main(): Response {
|
|
||||||
// Set properties as "searchable"
|
|
||||||
parent::make_wildcard_search(PsuModel::VENDOR_NAME->value, $this->query);
|
|
||||||
parent::make_wildcard_search(PsuModel::VENDOR_MODEL->value, $this->query);
|
|
||||||
|
|
||||||
// Get hardware
|
|
||||||
$this->get_psu();
|
|
||||||
|
|
||||||
// Resolve hardware relationships
|
|
||||||
$this->get_motherboards();
|
|
||||||
|
|
||||||
// Return 404 Not Found if response array is empty
|
|
||||||
return new Response($this->results, $this->results ? 200 : 404);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,110 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use Reflect\Path;
|
|
||||||
use Reflect\Response;
|
|
||||||
use ReflectRules\Type;
|
|
||||||
use ReflectRules\Rules;
|
|
||||||
use ReflectRules\Ruleset;
|
|
||||||
|
|
||||||
use VLW\API\Databases\VLWdb\{
|
|
||||||
VLWdb,
|
|
||||||
Databases
|
|
||||||
};
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Battlestation\{
|
|
||||||
StorageModel,
|
|
||||||
StorageDiskTypeEnum,
|
|
||||||
StorageDiskInterfaceEnum,
|
|
||||||
StorageDiskFormfactorEnum
|
|
||||||
};
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Battlestation\Config\MbStorageModel;
|
|
||||||
|
|
||||||
require_once Path::root("src/databases/VLWdb.php");
|
|
||||||
require_once Path::root("src/databases/models/Battlestation/Storage.php");
|
|
||||||
require_once Path::root("src/databases/models/Battlestation/Config/MbStorage.php");
|
|
||||||
|
|
||||||
class GET_BattlestationStorage extends VLWdb {
|
|
||||||
private const REL_MOTHERBOARDS = "motherboards";
|
|
||||||
|
|
||||||
protected Ruleset $ruleset;
|
|
||||||
|
|
||||||
private array $query;
|
|
||||||
private array $results = [];
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
$this->ruleset = new Ruleset(strict: true);
|
|
||||||
|
|
||||||
$this->ruleset->GET([
|
|
||||||
(new Rules(StorageModel::ID->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(parent::UUID_LENGTH)
|
|
||||||
->max(parent::UUID_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(StorageModel::DISK_TYPE->value))
|
|
||||||
->type(Type::ENUM, StorageDiskTypeEnum::names()),
|
|
||||||
|
|
||||||
(new Rules(StorageModel::DISK_SIZE->value))
|
|
||||||
->type(Type::NUMBER)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_INT_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(StorageModel::DISK_INTERFACE->value))
|
|
||||||
->type(Type::ENUM, StorageDiskInterfaceEnum::names()),
|
|
||||||
|
|
||||||
(new Rules(StorageModel::DISK_FORMFACTOR->value))
|
|
||||||
->type(Type::ENUM, StorageDiskFormfactorEnum::names()),
|
|
||||||
|
|
||||||
(new Rules(StorageModel::VENDOR_NAME->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(StorageModel::VENDOR_MODEL->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(StorageModel::IS_RETIRED->value))
|
|
||||||
->type(Type::BOOLEAN)
|
|
||||||
]);
|
|
||||||
|
|
||||||
parent::__construct(Databases::BATTLESTATION, $this->ruleset);
|
|
||||||
|
|
||||||
// Use a copy of search parameters
|
|
||||||
$this->query = $_GET;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function get_motherboards(): void {
|
|
||||||
foreach ($this->results as &$result) {
|
|
||||||
// Get motherboard id from relationship by chassis id
|
|
||||||
$result[self::REL_MOTHERBOARDS] = $this->db
|
|
||||||
->for(MbStorageModel::TABLE)
|
|
||||||
->where([MbStorageModel::REF_STORAGE_ID->value => $result[StorageModel::ID->value]])
|
|
||||||
->select(MbStorageModel::values())
|
|
||||||
->fetch_all(MYSQLI_ASSOC);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function get_storage(): array {
|
|
||||||
return $this->results = $this->db
|
|
||||||
->for(StorageModel::TABLE)
|
|
||||||
->where($this->query)
|
|
||||||
->order([StorageModel::DATE_AQUIRED->value => "DESC"])
|
|
||||||
->select(StorageModel::values())
|
|
||||||
->fetch_all(MYSQLI_ASSOC);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function main(): Response {
|
|
||||||
// Set properties as "searchable"
|
|
||||||
parent::make_wildcard_search(StorageModel::VENDOR_NAME->value, $this->query);
|
|
||||||
parent::make_wildcard_search(StorageModel::VENDOR_MODEL->value, $this->query);
|
|
||||||
|
|
||||||
// Get hardware
|
|
||||||
$this->get_storage();
|
|
||||||
|
|
||||||
// Resolve hardware relationships
|
|
||||||
$this->get_motherboards();
|
|
||||||
|
|
||||||
// Return 404 Not Found if response array is empty
|
|
||||||
return new Response($this->results, $this->results ? 200 : 404);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use Reflect\Path;
|
|
||||||
use Reflect\Response;
|
|
||||||
use ReflectRules\Type;
|
|
||||||
use ReflectRules\Rules;
|
|
||||||
use ReflectRules\Ruleset;
|
|
||||||
|
|
||||||
use VLW\API\Databases\VLWdb\{
|
|
||||||
VLWdb,
|
|
||||||
Databases
|
|
||||||
};
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Messages\MessagesModel;
|
|
||||||
|
|
||||||
require_once Path::root("src/databases/VLWdb.php");
|
|
||||||
require_once Path::root("src/databases/models/Messages/Messages.php");
|
|
||||||
|
|
||||||
class POST_Messages extends VLWdb {
|
|
||||||
protected Ruleset $ruleset;
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
$this->ruleset = new Ruleset(strict: true);
|
|
||||||
|
|
||||||
$this->ruleset->POST([
|
|
||||||
(new Rules(MessagesModel::EMAIL->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->max(255)
|
|
||||||
->default(null),
|
|
||||||
|
|
||||||
(new Rules(MessagesModel::MESSAGE->value))
|
|
||||||
->required()
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_TEXT_MAX_LENGTH)
|
|
||||||
]);
|
|
||||||
|
|
||||||
parent::__construct(Databases::VLW, $this->ruleset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function main(): Response {
|
|
||||||
// Use copy of request body as entity
|
|
||||||
$entity = $_POST;
|
|
||||||
|
|
||||||
$entity[MessagesModel::ID->value] = parent::gen_uuid4();
|
|
||||||
$entity[MessagesModel::DATE_CREATED->value] = time();
|
|
||||||
|
|
||||||
return $this->db->for(MessagesModel::TABLE)->insert($entity) === true
|
|
||||||
? new Response($entity[MessagesModel::ID->value], 201)
|
|
||||||
: new Response("Failed to create message", 500);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use Reflect\Call;
|
|
||||||
use Reflect\Path;
|
|
||||||
use Reflect\Response;
|
|
||||||
use ReflectRules\Type;
|
|
||||||
use ReflectRules\Rules;
|
|
||||||
use ReflectRules\Ruleset;
|
|
||||||
|
|
||||||
use VLW\API\Endpoints;
|
|
||||||
|
|
||||||
use VLW\API\Databases\VLWdb\{
|
|
||||||
VLWdb,
|
|
||||||
Databases
|
|
||||||
};
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Work\WorkModel;
|
|
||||||
|
|
||||||
require_once Path::root("src/Endpoints.php");
|
|
||||||
require_once Path::root("src/databases/VLWdb.php");
|
|
||||||
require_once Path::root("src/databases/models/Work/Work.php");
|
|
||||||
|
|
||||||
class GET_Search extends VLWdb {
|
|
||||||
const GET_QUERY = "q";
|
|
||||||
|
|
||||||
protected Ruleset $ruleset;
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
$this->ruleset = new Ruleset(strict: true);
|
|
||||||
|
|
||||||
$this->ruleset->GET([
|
|
||||||
(new Rules(self::GET_QUERY))
|
|
||||||
->required()
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH)
|
|
||||||
]);
|
|
||||||
|
|
||||||
parent::__construct(Databases::VLW, $this->ruleset);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function search_work(): Response {
|
|
||||||
return (new Call(Endpoints::WORK->value))->params([
|
|
||||||
WorkModel::TITLE->value => $_GET[self::GET_QUERY],
|
|
||||||
WorkModel::SUMMARY->value => $_GET[self::GET_QUERY]
|
|
||||||
])->get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function main(): Response {
|
|
||||||
$results = [
|
|
||||||
Endpoints::WORK->value => $this->search_work()->output()
|
|
||||||
];
|
|
||||||
|
|
||||||
// Calculate the total number of results from all searched endpoints
|
|
||||||
$num_results = array_sum(array_map(fn(array $result): int => count($result), array_values($results)));
|
|
||||||
|
|
||||||
// Return 404 if no search results
|
|
||||||
return new Response($results, $num_results > 0 ? 200 : 404);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,64 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use Reflect\Path;
|
|
||||||
use Reflect\Response;
|
|
||||||
use ReflectRules\Type;
|
|
||||||
use ReflectRules\Rules;
|
|
||||||
use ReflectRules\Ruleset;
|
|
||||||
|
|
||||||
use const VLW\API\RESP_DELETE_OK;
|
|
||||||
use VLW\API\Databases\VLWdb\{
|
|
||||||
VLWdb,
|
|
||||||
Databases
|
|
||||||
};
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Work\WorkModel;
|
|
||||||
|
|
||||||
require_once Path::root("src/Endpoints.php");
|
|
||||||
require_once Path::root("src/databases/VLWdb.php");
|
|
||||||
require_once Path::root("src/databases/models/Work.php");
|
|
||||||
|
|
||||||
class DELETE_Work extends VLWdb {
|
|
||||||
protected Ruleset $ruleset;
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
$this->ruleset = new Ruleset(strict: true);
|
|
||||||
|
|
||||||
$this->ruleset->POST([
|
|
||||||
(new Rules(WorkModel::ID->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(WorkModel::TITLE->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(3)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(WorkModel::SUMMARY->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_TEXT_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(WorkModel::IS_LISTED->value))
|
|
||||||
->type(Type::BOOLEAN),
|
|
||||||
|
|
||||||
(new Rules(WorkModel::DATE_MODIFIED->value))
|
|
||||||
->type(Type::NUMBER)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_INT_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(WorkModel::DATE_CREATED->value))
|
|
||||||
->type(Type::NUMBER)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_INT_MAX_LENGTH)
|
|
||||||
]);
|
|
||||||
|
|
||||||
parent::__construct(Databases::VLW, $this->ruleset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function main(): Response {
|
|
||||||
return $this->db->for(FieldsEnumsModel::TABLE)->delete($_POST) === true
|
|
||||||
? new Response(RESP_DELETE_OK)
|
|
||||||
: new Response("Failed to delete work entity", 500);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,107 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use Reflect\Path;
|
|
||||||
use Reflect\Response;
|
|
||||||
use ReflectRules\Type;
|
|
||||||
use ReflectRules\Rules;
|
|
||||||
use ReflectRules\Ruleset;
|
|
||||||
|
|
||||||
use VLW\API\Databases\VLWdb\{
|
|
||||||
VLWdb,
|
|
||||||
Databases
|
|
||||||
};
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Work\WorkModel;
|
|
||||||
|
|
||||||
require_once Path::root("src/databases/VLWdb.php");
|
|
||||||
require_once Path::root("src/databases/models/Work/Work.php");
|
|
||||||
|
|
||||||
const PARAM_LIMIT = "limit";
|
|
||||||
|
|
||||||
class GET_Work extends VLWdb {
|
|
||||||
protected Ruleset $ruleset;
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
$this->ruleset = new Ruleset(strict: true);
|
|
||||||
|
|
||||||
$this->ruleset->GET([
|
|
||||||
(new Rules(WorkModel::ID->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(WorkModel::TITLE->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(WorkModel::SUMMARY->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->max(parent::MYSQL_TEXT_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(WorkModel::IS_LISTED->value))
|
|
||||||
->type(Type::BOOLEAN)
|
|
||||||
->default(true),
|
|
||||||
|
|
||||||
(new Rules(WorkModel::DATE_MODIFIED->value))
|
|
||||||
->type(Type::NUMBER)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_INT_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(WorkModel::DATE_CREATED->value))
|
|
||||||
->type(Type::NUMBER)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_INT_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(PARAM_LIMIT))
|
|
||||||
->type(Type::NUMBER)
|
|
||||||
->type(Type::NULL)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_INT_MAX_LENGTH)
|
|
||||||
->default(null)
|
|
||||||
]);
|
|
||||||
|
|
||||||
parent::__construct(Databases::VLW, $this->ruleset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function main(): Response {
|
|
||||||
// Use search parameters from model as filters
|
|
||||||
$filters = $_GET;
|
|
||||||
// Unset keys not included in database model from filter
|
|
||||||
foreach (array_diff(array_keys($_GET), WorkModel::values()) as $k) {
|
|
||||||
unset($filters[$k]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do a wildcard search on the title column if provided
|
|
||||||
if (array_key_exists(WorkModel::TITLE->value, $_GET)) {
|
|
||||||
$filters[WorkModel::TITLE->value] = [
|
|
||||||
"LIKE" => "%{$_GET[WorkModel::TITLE->value]}%"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do a wildcard search on the summary column if provided
|
|
||||||
if (array_key_exists(WorkModel::SUMMARY->value, $_GET)) {
|
|
||||||
$filters[WorkModel::SUMMARY->value] = [
|
|
||||||
"LIKE" => "%{$_GET[WorkModel::SUMMARY->value]}%"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
$response = $this->db->for(WorkModel::TABLE)
|
|
||||||
->where($filters)
|
|
||||||
->order([WorkModel::DATE_CREATED->value => "DESC"])
|
|
||||||
->limit($_GET[PARAM_LIMIT])
|
|
||||||
->select([
|
|
||||||
WorkModel::ID->value,
|
|
||||||
WorkModel::TITLE->value,
|
|
||||||
WorkModel::SUMMARY->value,
|
|
||||||
WorkModel::IS_LISTED->value,
|
|
||||||
WorkModel::DATE_YEAR->value,
|
|
||||||
WorkModel::DATE_MONTH->value,
|
|
||||||
WorkModel::DATE_DAY->value,
|
|
||||||
WorkModel::DATE_MODIFIED->value,
|
|
||||||
WorkModel::DATE_CREATED->value
|
|
||||||
]);
|
|
||||||
|
|
||||||
return $response->num_rows > 0
|
|
||||||
? new Response($response->fetch_all(MYSQLI_ASSOC))
|
|
||||||
: new Response([], 404);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,115 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use Reflect\Call;
|
|
||||||
use Reflect\Path;
|
|
||||||
use Reflect\Response;
|
|
||||||
use ReflectRules\Type;
|
|
||||||
use ReflectRules\Rules;
|
|
||||||
use ReflectRules\Ruleset;
|
|
||||||
|
|
||||||
use VLW\API\Endpoints;
|
|
||||||
use VLW\API\Databases\VLWdb\{
|
|
||||||
VLWdb,
|
|
||||||
Databases
|
|
||||||
};
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Work\{
|
|
||||||
WorkModel,
|
|
||||||
WorkPermalinksModel
|
|
||||||
};
|
|
||||||
|
|
||||||
require_once Path::root("src/Endpoints.php");
|
|
||||||
require_once Path::root("src/databases/VLWdb.php");
|
|
||||||
require_once Path::root("src/databases/models/Work/Work.php");
|
|
||||||
require_once Path::root("src/databases/models/Work/WorkPermalinks.php");
|
|
||||||
|
|
||||||
class PATCH_Work extends VLWdb {
|
|
||||||
protected Ruleset $ruleset;
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
$this->ruleset = new Ruleset(strict: true);
|
|
||||||
|
|
||||||
$this->ruleset->GET([
|
|
||||||
(new Rules(WorkModel::ID->value))
|
|
||||||
->required()
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH)
|
|
||||||
]);
|
|
||||||
|
|
||||||
$this->ruleset->POST([
|
|
||||||
(new Rules(WorkModel::TITLE->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(3)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(WorkModel::SUMMARY->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_TEXT_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(WorkModel::IS_LISTED->value))
|
|
||||||
->type(Type::BOOLEAN),
|
|
||||||
|
|
||||||
(new Rules(WorkModel::DATE_MODIFIED->value))
|
|
||||||
->type(Type::NUMBER)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_INT_MAX_LENGTH)
|
|
||||||
->default(time()),
|
|
||||||
|
|
||||||
(new Rules(WorkModel::DATE_CREATED->value))
|
|
||||||
->type(Type::NUMBER)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_INT_MAX_LENGTH)
|
|
||||||
]);
|
|
||||||
|
|
||||||
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 [
|
|
||||||
WorkModel::DATE_YEAR->value => date("Y", $_POST[WorkModel::DATE_CREATED->value]),
|
|
||||||
WorkModel::DATE_MONTH ->value => date("n", $_POST[WorkModel::DATE_CREATED->value]),
|
|
||||||
WorkModel::DATE_DAY->value => date("j", $_POST[WorkModel::DATE_CREATED->value])
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
private function get_entity_by_id(string $id): Response {
|
|
||||||
return (new Call(Endpoints::WORK->value))->params([
|
|
||||||
WorkModel::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[WorkModel::TITLE->value]) {
|
|
||||||
$slug = $_POST[WorkModel::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[WorkModel::ID] = $slug;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate new work date fields from timestamp
|
|
||||||
if ($_POST[WorkModel::DATE_CREATED->value]) {
|
|
||||||
array_merge($entity, self::gen_date_created());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update entity by existing id
|
|
||||||
return $this->db->for(WorkModel::TABLE)->where([WorkModel::ID->value => $_GET[WorkModel::ID->value]])->update($entity) === true
|
|
||||||
? new Response($_GET[WorkModel::ID->value])
|
|
||||||
: new Response("Failed to update entity", 500);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,110 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use Reflect\Call;
|
|
||||||
use Reflect\Path;
|
|
||||||
use Reflect\Response;
|
|
||||||
use ReflectRules\Type;
|
|
||||||
use ReflectRules\Rules;
|
|
||||||
use ReflectRules\Ruleset;
|
|
||||||
|
|
||||||
use VLW\API\Endpoints;
|
|
||||||
use VLW\API\Databases\VLWdb\{
|
|
||||||
VLWdb,
|
|
||||||
Databases
|
|
||||||
};
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Work\{
|
|
||||||
WorkModel,
|
|
||||||
WorkPermalinksModel
|
|
||||||
};
|
|
||||||
|
|
||||||
require_once Path::root("src/Endpoints.php");
|
|
||||||
require_once Path::root("src/databases/VLWdb.php");
|
|
||||||
require_once Path::root("src/databases/models/Work/Work.php");
|
|
||||||
require_once Path::root("src/databases/models/Work/WorkPermalinks.php");
|
|
||||||
|
|
||||||
class POST_Work extends VLWdb {
|
|
||||||
protected Ruleset $ruleset;
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
$this->ruleset = new Ruleset(strict: true);
|
|
||||||
|
|
||||||
$this->ruleset->POST([
|
|
||||||
(new Rules(WorkModel::TITLE->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(3)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH)
|
|
||||||
->default(null),
|
|
||||||
|
|
||||||
(new Rules(WorkModel::SUMMARY->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_TEXT_MAX_LENGTH)
|
|
||||||
->default(null),
|
|
||||||
|
|
||||||
(new Rules(WorkModel::IS_LISTED->value))
|
|
||||||
->type(Type::BOOLEAN)
|
|
||||||
->default(false),
|
|
||||||
|
|
||||||
(new Rules(WorkModel::DATE_CREATED->value))
|
|
||||||
->type(Type::NUMBER)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_INT_MAX_LENGTH)
|
|
||||||
->default(time())
|
|
||||||
]);
|
|
||||||
|
|
||||||
parent::__construct(Databases::VLW, $this->ruleset);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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[WorkModel::DATE_CREATED->value];
|
|
||||||
|
|
||||||
return [
|
|
||||||
WorkModel::DATE_YEAR->value => date("Y", $date_created),
|
|
||||||
WorkModel::DATE_MONTH ->value => date("n", $date_created),
|
|
||||||
WorkModel::DATE_DAY->value => date("j", $date_created)
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
private function get_entity_by_id(string $id): Response {
|
|
||||||
return (new Call(Endpoints::WORK->value))->params([
|
|
||||||
WorkModel::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[WorkModel::ID->value] = $_POST[WorkModel::TITLE->value]
|
|
||||||
? self::gen_slug($_POST[WorkModel::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[WorkModel::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(WorkModel::TABLE)->insert($entity)) {
|
|
||||||
return new Response("Failed to insert work entry", 500);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate permalink for new entity
|
|
||||||
return (new Call(Endpoints::WORK_PERMALINKS->value))->post([
|
|
||||||
WorkPermalinksModel::ID => $entity[WorkModel::ID->value],
|
|
||||||
WorkPermalinksModel::REF_WORK_ID => $entity[WorkModel::ID->value],
|
|
||||||
WorkPermalinksModel::DATE_CREATED => time()
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use Reflect\Path;
|
|
||||||
use Reflect\Response;
|
|
||||||
use ReflectRules\Type;
|
|
||||||
use ReflectRules\Rules;
|
|
||||||
use ReflectRules\Ruleset;
|
|
||||||
|
|
||||||
use const VLW\API\RESP_DELETE_OK;
|
|
||||||
use VLW\API\Databases\VLWdb\{
|
|
||||||
VLWdb,
|
|
||||||
Databases
|
|
||||||
};
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Work\WorkActionsModel;
|
|
||||||
|
|
||||||
require_once Path::root("src/databases/VLWdb.php");
|
|
||||||
require_once Path::root("src/databases/models/WorkActions.php");
|
|
||||||
|
|
||||||
class DELETE_WorkActions extends VLWdb {
|
|
||||||
protected Ruleset $ruleset;
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
parent::__construct();
|
|
||||||
$this->ruleset = new Ruleset(strict: true);
|
|
||||||
|
|
||||||
$this->ruleset->POST([
|
|
||||||
(new Rules(WorkActionsModel::REF_WORK_ID->value))
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH)
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function main(): Response {
|
|
||||||
return $this->db->for(WorkActionsModel::TABLE)->delete($_POST) === true
|
|
||||||
? new Response(RESP_DELETE_OK)
|
|
||||||
: new Response("Failed to delete action for work entity", 500);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use Reflect\Path;
|
|
||||||
use Reflect\Response;
|
|
||||||
use ReflectRules\Type;
|
|
||||||
use ReflectRules\Rules;
|
|
||||||
use ReflectRules\Ruleset;
|
|
||||||
|
|
||||||
use VLW\API\Databases\VLWdb\{
|
|
||||||
VLWdb,
|
|
||||||
Databases
|
|
||||||
};
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Work\WorkActionsModel;
|
|
||||||
|
|
||||||
require_once Path::root("src/databases/VLWdb.php");
|
|
||||||
require_once Path::root("src/databases/models/Work/WorkActions.php");
|
|
||||||
|
|
||||||
class GET_WorkActions extends VLWdb {
|
|
||||||
protected Ruleset $ruleset;
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
$this->ruleset = new Ruleset(strict: true);
|
|
||||||
|
|
||||||
$this->ruleset->GET([
|
|
||||||
(new Rules(WorkActionsModel::REF_WORK_ID->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH)
|
|
||||||
]);
|
|
||||||
|
|
||||||
parent::__construct(Databases::VLW, $this->ruleset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function main(): Response {
|
|
||||||
$response = $this->db->for(WorkActionsModel::TABLE)
|
|
||||||
->where($_GET)
|
|
||||||
->select([
|
|
||||||
WorkActionsModel::REF_WORK_ID->value,
|
|
||||||
WorkActionsModel::DISPLAY_TEXT->value,
|
|
||||||
WorkActionsModel::HREF->value,
|
|
||||||
WorkActionsModel::CLASS_LIST->value
|
|
||||||
]);
|
|
||||||
|
|
||||||
return $response->num_rows > 0
|
|
||||||
? new Response(parent::index_array_by_key($response->fetch_all(MYSQLI_ASSOC), WorkActionsModel::REF_WORK_ID->value))
|
|
||||||
: new Response([], 404);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,76 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use Reflect\Call;
|
|
||||||
use Reflect\Path;
|
|
||||||
use Reflect\Response;
|
|
||||||
use ReflectRules\Type;
|
|
||||||
use ReflectRules\Rules;
|
|
||||||
use ReflectRules\Ruleset;
|
|
||||||
|
|
||||||
use VLW\API\Endpoints;
|
|
||||||
use VLW\API\Databases\VLWdb\{
|
|
||||||
VLWdb,
|
|
||||||
Databases
|
|
||||||
};
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Work\{
|
|
||||||
WorkModel,
|
|
||||||
WorkActionsModel
|
|
||||||
};
|
|
||||||
|
|
||||||
require_once Path::root("src/Endpoints.php");
|
|
||||||
require_once Path::root("src/databases/VLWdb.php");
|
|
||||||
require_once Path::root("src/databases/models/Work/Work.php");
|
|
||||||
require_once Path::root("src/databases/models/Work/WorkActions.php");
|
|
||||||
|
|
||||||
class POST_WorkActions extends VLWdb {
|
|
||||||
protected Ruleset $ruleset;
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
$this->ruleset = new Ruleset(strict: true);
|
|
||||||
|
|
||||||
$this->ruleset->POST([
|
|
||||||
(new Rules(WorkActionsModel::REF_WORK_ID->value))
|
|
||||||
->required()
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(WorkActionsModel::DISPLAY_TEXT->value))
|
|
||||||
->required()
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(WorkActionsModel::HREF->value))
|
|
||||||
->required()
|
|
||||||
->type(Type::STRING)
|
|
||||||
->type(Type::NULL)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(WorkActionsModel::CLASS_LIST->value))
|
|
||||||
->type(Type::ARRAY)
|
|
||||||
->min(1)
|
|
||||||
->default([])
|
|
||||||
]);
|
|
||||||
|
|
||||||
parent::__construct(Databases::VLW, $this->ruleset);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static function get_entity(): Response {
|
|
||||||
return (new Call(Endpoints::WORK->value))->params([
|
|
||||||
WorkModel::ID->value => $_POST[WorkActionsModel::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(WorkActionsModel::TABLE)->insert($_POST) === true
|
|
||||||
? new Response($_POST[WorkActionsModel::REF_WORK_ID->value], 201)
|
|
||||||
: new Response("Failed to add action to work entity", 500);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,52 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use Reflect\Path;
|
|
||||||
use Reflect\Response;
|
|
||||||
use ReflectRules\Type;
|
|
||||||
use ReflectRules\Rules;
|
|
||||||
use ReflectRules\Ruleset;
|
|
||||||
|
|
||||||
use VLW\API\Databases\VLWdb\{
|
|
||||||
VLWdb,
|
|
||||||
Databases
|
|
||||||
};
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Work\WorkPermalinksModel;
|
|
||||||
|
|
||||||
require_once Path::root("src/databases/VLWdb.php");
|
|
||||||
require_once Path::root("src/databases/models/Work/WorkPermalinks.php");
|
|
||||||
|
|
||||||
class GET_WorkPermalinks extends VLWdb {
|
|
||||||
protected Ruleset $ruleset;
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
$this->ruleset = new Ruleset(strict: true);
|
|
||||||
|
|
||||||
$this->ruleset->GET([
|
|
||||||
(new Rules(WorkPermalinksModel::ID->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(WorkPermalinksModel::REF_WORK_ID->value))
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH)
|
|
||||||
]);
|
|
||||||
|
|
||||||
parent::__construct(Databases::VLW, $this->ruleset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function main(): Response {
|
|
||||||
$response = $this->db->for(WorkPermalinksModel::TABLE)
|
|
||||||
->where($_GET)
|
|
||||||
->select([
|
|
||||||
WorkPermalinksModel::ID->value,
|
|
||||||
WorkPermalinksModel::REF_WORK_ID->value,
|
|
||||||
WorkPermalinksModel::DATE_CREATED->value
|
|
||||||
]);
|
|
||||||
|
|
||||||
return $response->num_rows > 0
|
|
||||||
? new Response($response->fetch_all(MYSQLI_ASSOC))
|
|
||||||
: new Response([], 404);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,65 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use Reflect\Call;
|
|
||||||
use Reflect\Path;
|
|
||||||
use Reflect\Response;
|
|
||||||
use ReflectRules\Type;
|
|
||||||
use ReflectRules\Rules;
|
|
||||||
use ReflectRules\Ruleset;
|
|
||||||
|
|
||||||
use VLW\API\Databases\VLWdb\{
|
|
||||||
VLWdb,
|
|
||||||
Databases
|
|
||||||
};
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Work\WorkPermalinksModel;
|
|
||||||
|
|
||||||
require_once Path::root("src/databases/VLWdb.php");
|
|
||||||
require_once Path::root("src/databases/models/Work/WorkPermalinks.php");
|
|
||||||
|
|
||||||
class POST_WorkPermalinks extends VLWdb {
|
|
||||||
protected Ruleset $ruleset;
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
$this->ruleset = new Ruleset(strict: true);
|
|
||||||
|
|
||||||
$this->ruleset->POST([
|
|
||||||
(new Rules(WorkPermalinksModel::ID->value))
|
|
||||||
->required()
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(WorkPermalinksModel::REF_WORK_ID->value))
|
|
||||||
->required()
|
|
||||||
->type(Type::STRING)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(WorkPermalinksModel::DATE_CREATED->value))
|
|
||||||
->type(Type::NUMBER)
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_INT_MAX_LENGTH)
|
|
||||||
->default(time())
|
|
||||||
]);
|
|
||||||
|
|
||||||
parent::__construct(Databases::VLW, $this->ruleset);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static function get_entity(): Response {
|
|
||||||
return (new Call(Endpoints::WORK->value))->params([
|
|
||||||
WorkModel::ID->value => $_POST[WorkTagsModel::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(WorkPermalinksModel::TABLE)->insert($_POST) === true
|
|
||||||
? new Response($_POST[WorkPermalinksModel::ID->value], 201)
|
|
||||||
: new Response("Failed to add permalink to work entity", 500);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use Reflect\Path;
|
|
||||||
use Reflect\Response;
|
|
||||||
use ReflectRules\Type;
|
|
||||||
use ReflectRules\Rules;
|
|
||||||
use ReflectRules\Ruleset;
|
|
||||||
|
|
||||||
use const VLW\API\RESP_DELETE_OK;
|
|
||||||
use VLW\API\Databases\VLWdb\{
|
|
||||||
VLWdb,
|
|
||||||
Databases
|
|
||||||
};
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Work\WorkTagsModel;
|
|
||||||
|
|
||||||
require_once Path::root("src/databases/VLWdb.php");
|
|
||||||
require_once Path::root("src/databases/models/Work/WorkTags.php");
|
|
||||||
|
|
||||||
class DELETE_WorkTags extends VLWdb {
|
|
||||||
private Ruleset $ruleset;
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
$this->ruleset = new Ruleset(strict: true);
|
|
||||||
|
|
||||||
$this->ruleset->GET([
|
|
||||||
(new Rules(WorkTagsModel::REF_WORK_ID->value))
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(WorkTagsModel::NAME->value))
|
|
||||||
->type(Type::ENUM, WorkTagsNameEnum::names())
|
|
||||||
]);
|
|
||||||
|
|
||||||
parent::__construct(Databases::VLW, $this->ruleset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function main(): Response {
|
|
||||||
return $this->db->for(WorkTagsModel::TABLE)->delete($_POST) === true
|
|
||||||
? new Response(RESP_DELETE_OK)
|
|
||||||
: new Response("Failed to delete value from document", 500);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use Reflect\Path;
|
|
||||||
use Reflect\Response;
|
|
||||||
use ReflectRules\Type;
|
|
||||||
use ReflectRules\Rules;
|
|
||||||
use ReflectRules\Ruleset;
|
|
||||||
|
|
||||||
use VLW\API\Databases\VLWdb\{
|
|
||||||
VLWdb,
|
|
||||||
Databases
|
|
||||||
};
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Work\{
|
|
||||||
WorkTagsModel,
|
|
||||||
WorkTagsNameEnum
|
|
||||||
};
|
|
||||||
|
|
||||||
require_once Path::root("src/databases/VLWdb.php");
|
|
||||||
require_once Path::root("src/databases/models/Work/WorkTags.php");
|
|
||||||
|
|
||||||
class GET_WorkTags extends VLWdb {
|
|
||||||
private Ruleset $ruleset;
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
$this->ruleset = new Ruleset(strict: true);
|
|
||||||
|
|
||||||
$this->ruleset->GET([
|
|
||||||
(new Rules(WorkTagsModel::REF_WORK_ID->value))
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(WorkTagsModel::NAME->value))
|
|
||||||
->type(Type::ENUM, WorkTagsNameEnum::names())
|
|
||||||
]);
|
|
||||||
|
|
||||||
parent::__construct(Databases::VLW, $this->ruleset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function main(): Response {
|
|
||||||
$response = $this->db->for(WorkTagsModel::TABLE)
|
|
||||||
->where($_GET)
|
|
||||||
->select([
|
|
||||||
WorkTagsModel::REF_WORK_ID->value,
|
|
||||||
WorkTagsModel::NAME->value
|
|
||||||
]);
|
|
||||||
|
|
||||||
return $response->num_rows > 0
|
|
||||||
? new Response(parent::index_array_by_key($response->fetch_all(MYSQLI_ASSOC), WorkTagsModel::REF_WORK_ID->value))
|
|
||||||
: new Response([], 404);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,63 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use Reflect\Call;
|
|
||||||
use Reflect\Path;
|
|
||||||
use Reflect\Response;
|
|
||||||
use ReflectRules\Type;
|
|
||||||
use ReflectRules\Rules;
|
|
||||||
use ReflectRules\Ruleset;
|
|
||||||
|
|
||||||
use VLW\API\Endpoints;
|
|
||||||
use VLW\API\Databases\VLWdb\{
|
|
||||||
VLWdb,
|
|
||||||
Databases
|
|
||||||
};
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Work\{
|
|
||||||
WorkModel,
|
|
||||||
WorkTagsModel,
|
|
||||||
WorkTagsNameEnum
|
|
||||||
};
|
|
||||||
|
|
||||||
require_once Path::root("src/Endpoints.php");
|
|
||||||
require_once Path::root("src/databases/VLWdb.php");
|
|
||||||
require_once Path::root("src/databases/models/Work/Work.php");
|
|
||||||
require_once Path::root("src/databases/models/Work/WorkTags.php");
|
|
||||||
|
|
||||||
class POST_WorkTags extends VLWdb {
|
|
||||||
protected Ruleset $ruleset;
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
$this->ruleset = new Ruleset(strict: true);
|
|
||||||
|
|
||||||
$this->ruleset->POST([
|
|
||||||
(new Rules(WorkTagsModel::REF_WORK_ID->value))
|
|
||||||
->required()
|
|
||||||
->min(1)
|
|
||||||
->max(parent::MYSQL_VARCHAR_MAX_LENGTH),
|
|
||||||
|
|
||||||
(new Rules(WorkTagsModel::NAME->value))
|
|
||||||
->required()
|
|
||||||
->type(Type::ENUM, WorkTagsNameEnum::names())
|
|
||||||
]);
|
|
||||||
|
|
||||||
parent::__construct(Databases::VLW, $this->ruleset);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static function get_entity(): Response {
|
|
||||||
return (new Call(Endpoints::WORK->value))->params([
|
|
||||||
WorkModel::ID->value => $_POST[WorkTagsModel::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(WorkTagsModel::TABLE)->insert($_POST) === true
|
|
||||||
? new Response($_POST[WorkTagsModel::REF_WORK_ID->value], 201)
|
|
||||||
: new Response("Failed to add tag to work entity", 500);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,2 +0,0 @@
|
||||||
# Install dependencies
|
|
||||||
composer install --optimize-autoloader
|
|
|
@ -1,101 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace VLW\API\Databases\VLWdb;
|
|
||||||
|
|
||||||
use Reflect\Path;
|
|
||||||
use Reflect\Request;
|
|
||||||
use Reflect\Response;
|
|
||||||
use ReflectRules\Ruleset;
|
|
||||||
|
|
||||||
use vlw\MySQL\MySQL;
|
|
||||||
|
|
||||||
enum Databases: string {
|
|
||||||
case VLW = "vlw";
|
|
||||||
case BATTLESTATION = "battlestation";
|
|
||||||
}
|
|
||||||
|
|
||||||
class VLWdb {
|
|
||||||
const UUID_LENGTH = 36;
|
|
||||||
|
|
||||||
const MYSQL_INT_MAX_LENGTH = 2147483647;
|
|
||||||
const MYSQL_TEXT_MAX_LENGTH = 65538;
|
|
||||||
const MYSQL_VARCHAR_MAX_LENGTH = 255;
|
|
||||||
const MYSQL_TINYINT_MAX_LENGTH = 255;
|
|
||||||
|
|
||||||
protected readonly MySQL $db;
|
|
||||||
|
|
||||||
public function __construct(Databases $database, Ruleset $ruleset) {
|
|
||||||
// Validate provided Ruleset before attempting to connect to the database
|
|
||||||
self::eval_ruleset_or_exit($ruleset);
|
|
||||||
|
|
||||||
// Create new MariaDB connection
|
|
||||||
$this->db = new MySQL(
|
|
||||||
$_ENV["connect"]["host"],
|
|
||||||
$_ENV["connect"]["user"],
|
|
||||||
$_ENV["connect"]["pass"],
|
|
||||||
$_ENV["databases"][$database->value],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bail out if provided ReflectRules\Ruleset is invalid
|
|
||||||
private static function eval_ruleset_or_exit(Ruleset $ruleset): ?Response {
|
|
||||||
return !$ruleset->is_valid() ? new Response($ruleset->get_errors(), 422) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate and return UUID4 string
|
|
||||||
public static function gen_uuid4(): string {
|
|
||||||
return sprintf("%04x%04x-%04x-%04x-%04x-%04x%04x%04x",
|
|
||||||
// 32 bits for "time_low"
|
|
||||||
mt_rand(0, 0xffff), mt_rand(0, 0xffff),
|
|
||||||
|
|
||||||
// 16 bits for "time_mid"
|
|
||||||
mt_rand(0, 0xffff),
|
|
||||||
|
|
||||||
// 16 bits for "time_hi_and_version",
|
|
||||||
// four most significant bits holds version number 4
|
|
||||||
mt_rand(0, 0x0fff) | 0x4000,
|
|
||||||
|
|
||||||
// 16 bits, 8 bits for "clk_seq_hi_res",
|
|
||||||
// 8 bits for "clk_seq_low",
|
|
||||||
// two most significant bits holds zero and one for variant DCE1.1
|
|
||||||
mt_rand(0, 0x3fff) | 0x8000,
|
|
||||||
|
|
||||||
// 48 bits for "node"
|
|
||||||
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mutate the value by array key $property_name into a libmysqldriver\MySQL custom operator
|
|
||||||
// https://codeberg.org/vlw/php-mysql#define-custom-operators
|
|
||||||
public static function make_wildcard_search(string $property_name, array &$filters): array {
|
|
||||||
// Bail out if property name is not set in filters array or if its value is null
|
|
||||||
if (!array_key_exists($property_name, $filters) || $filters[$property_name] === null) {
|
|
||||||
return $filters;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mutate filter value into a custom operator array
|
|
||||||
$filters[$property_name] = [
|
|
||||||
"LIKE" => "%{$filters[$property_name]}%"
|
|
||||||
];
|
|
||||||
|
|
||||||
return $filters;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function index_array_by_key(array $input, string $key): array {
|
|
||||||
$output = [];
|
|
||||||
|
|
||||||
foreach ($input as $item) {
|
|
||||||
$idx = $item[$key];
|
|
||||||
|
|
||||||
// Create entry for key in output array if first item
|
|
||||||
if (!array_key_exists($idx, $output)) {
|
|
||||||
$output[$idx] = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append item to array of array by key
|
|
||||||
$output[$idx][] = $item;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $output;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace VLW\API\Databases\VLWdb\Models\Battlestation\Config;
|
|
||||||
|
|
||||||
use victorwesterlund\xEnum;
|
|
||||||
|
|
||||||
enum ChassisMbModel: string {
|
|
||||||
use xEnum;
|
|
||||||
|
|
||||||
const TABLE = "config_chassis_mb";
|
|
||||||
|
|
||||||
case REF_CHASSIS_ID = "ref_chassis_id";
|
|
||||||
case REF_MB_ID = "ref_mb_id";
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace VLW\API\Databases\VLWdb\Models\Battlestation\Config;
|
|
||||||
|
|
||||||
use victorwesterlund\xEnum;
|
|
||||||
|
|
||||||
enum MbGpuModel: string {
|
|
||||||
use xEnum;
|
|
||||||
|
|
||||||
const TABLE = "config_mb_gpu";
|
|
||||||
|
|
||||||
case REF_MB_ID = "ref_mb_id";
|
|
||||||
case REF_GPU_ID = "ref_gpu_id";
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace VLW\API\Databases\VLWdb\Models\Battlestation\Config;
|
|
||||||
|
|
||||||
use victorwesterlund\xEnum;
|
|
||||||
|
|
||||||
enum MbPsuModel: string {
|
|
||||||
use xEnum;
|
|
||||||
|
|
||||||
const TABLE = "config_mb_psu";
|
|
||||||
|
|
||||||
case REF_MB_ID = "ref_mb_id";
|
|
||||||
case REF_PSU_ID = "ref_psu_id";
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace VLW\API\Databases\VLWdb\Models\Messages;
|
|
||||||
|
|
||||||
enum MessagesModel: string {
|
|
||||||
const TABLE = "messages";
|
|
||||||
|
|
||||||
case ID = "id";
|
|
||||||
case EMAIL = "email";
|
|
||||||
case MESSAGE = "message";
|
|
||||||
case IS_READ = "is_read";
|
|
||||||
case IS_SPAM = "is_spam";
|
|
||||||
case IS_SAVED = "is_saved";
|
|
||||||
case DATE_CREATED = "date_created";
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace VLW\API\Databases\VLWdb\Models\Work;
|
|
||||||
|
|
||||||
use victorwesterlund\xEnum;
|
|
||||||
|
|
||||||
enum WorkModel: string {
|
|
||||||
use xEnum;
|
|
||||||
|
|
||||||
const TABLE = "work";
|
|
||||||
|
|
||||||
case ID = "id";
|
|
||||||
case TITLE = "title";
|
|
||||||
case SUMMARY = "summary";
|
|
||||||
case COVER_SRCSET = "cover_srcset";
|
|
||||||
case IS_LISTED = "is_listed";
|
|
||||||
case DATE_YEAR = "date_year";
|
|
||||||
case DATE_MONTH = "date_month";
|
|
||||||
case DATE_DAY = "date_day";
|
|
||||||
case DATE_MODIFIED = "date_modified";
|
|
||||||
case DATE_CREATED = "date_created";
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace VLW\API\Databases\VLWdb\Models\Work;
|
|
||||||
|
|
||||||
enum WorkMediaModel: string {
|
|
||||||
const TABLE = "work_media";
|
|
||||||
|
|
||||||
case ANCHOR = "anchor";
|
|
||||||
case MEDIA = "media";
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace VLW\API\Databases\VLWdb\Models\Work;
|
|
||||||
|
|
||||||
enum WorkNamespacesModel: string {
|
|
||||||
const TABLE = "work_actions";
|
|
||||||
|
|
||||||
case REF_WORK_ID = "ref_work_id";
|
|
||||||
case ICON_PREFIX = "icon_prefix";
|
|
||||||
case ICON_SUFFIX = "icon_suffix";
|
|
||||||
case ORDER_IDX = "order_idx";
|
|
||||||
case DISPLAY_TEXT = "display_text";
|
|
||||||
case HREF = "href";
|
|
||||||
case CLASS_LIST = "class_list";
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace VLW\API\Databases\VLWdb\Models\Work;
|
|
||||||
|
|
||||||
use victorwesterlund\xEnum;
|
|
||||||
|
|
||||||
enum WorkTagsNameEnum {
|
|
||||||
use xEnum;
|
|
||||||
|
|
||||||
case VLW;
|
|
||||||
case RELEASE;
|
|
||||||
case WEBSITE;
|
|
||||||
case REPO;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum WorkTagsModel: string {
|
|
||||||
const TABLE = "work_tags";
|
|
||||||
|
|
||||||
case REF_WORK_ID = "ref_work_id";
|
|
||||||
case NAME = "name";
|
|
||||||
}
|
|
|
@ -1,7 +1,9 @@
|
||||||
{
|
{
|
||||||
"require": {
|
"require": {
|
||||||
"reflect/client": "dev-master",
|
"reflect/client": "dev-master",
|
||||||
"victorwesterlund/xenum": "dev-master"
|
"reflect/plugin-rules": "dev-master",
|
||||||
|
"vlw/mysql": "dev-master",
|
||||||
|
"vlw/xenum": "dev-master"
|
||||||
},
|
},
|
||||||
"minimum-stability": "dev"
|
"minimum-stability": "dev"
|
||||||
}
|
}
|
||||||
|
|
96
composer.lock
generated
96
composer.lock
generated
|
@ -4,22 +4,16 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "2a8a06dc452a4eb9055d238f771dcd37",
|
"content-hash": "cb70f9f3f538a72aa8bcf906fdc906bf",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "reflect/client",
|
"name": "reflect/client",
|
||||||
"version": "dev-master",
|
"version": "dev-master",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/VictorWesterlund/reflect-client-php.git",
|
"url": "https://codeberg.org/reflect/client-php",
|
||||||
"reference": "89a8c041044c8c60cefafc4716d5d61b96c43e06"
|
"reference": "89a8c041044c8c60cefafc4716d5d61b96c43e06"
|
||||||
},
|
},
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/VictorWesterlund/reflect-client-php/zipball/89a8c041044c8c60cefafc4716d5d61b96c43e06",
|
|
||||||
"reference": "89a8c041044c8c60cefafc4716d5d61b96c43e06",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"default-branch": true,
|
"default-branch": true,
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
@ -38,31 +32,21 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Extendable PHP interface for communicating with Reflect API over HTTP or UNIX sockets",
|
"description": "Extendable PHP interface for communicating with Reflect API over HTTP or UNIX sockets",
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/VictorWesterlund/reflect-client-php/issues",
|
|
||||||
"source": "https://github.com/VictorWesterlund/reflect-client-php/tree/3.0.6"
|
|
||||||
},
|
|
||||||
"time": "2024-04-06T14:55:04+00:00"
|
"time": "2024-04-06T14:55:04+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "victorwesterlund/xenum",
|
"name": "reflect/plugin-rules",
|
||||||
"version": "dev-master",
|
"version": "dev-master",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/VictorWesterlund/php-xenum.git",
|
"url": "https://codeberg.org/reflect/rules-plugin",
|
||||||
"reference": "8972f06f42abd1f382807a67e937d5564bb89699"
|
"reference": "aa7d969350f50d00d7dce01b948276946fcc0e81"
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/VictorWesterlund/php-xenum/zipball/8972f06f42abd1f382807a67e937d5564bb89699",
|
|
||||||
"reference": "8972f06f42abd1f382807a67e937d5564bb89699",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
},
|
||||||
"default-branch": true,
|
"default-branch": true,
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"victorwesterlund\\": "src/"
|
"ReflectRules\\": "src/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
@ -75,12 +59,64 @@
|
||||||
"email": "victor.vesterlund@gmail.com"
|
"email": "victor.vesterlund@gmail.com"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "PHP eXtended Enums. The missing quality-of-life features from PHP 8+ Enums",
|
"description": "Add request search paramter and request body constraints to an API built with Reflect",
|
||||||
"support": {
|
"time": "2024-11-28T17:05:16+00:00"
|
||||||
"issues": "https://github.com/VictorWesterlund/php-xenum/issues",
|
},
|
||||||
"source": "https://github.com/VictorWesterlund/php-xenum/tree/1.1.1"
|
{
|
||||||
|
"name": "vlw/mysql",
|
||||||
|
"version": "dev-master",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://codeberg.org/vlw/php-mysql",
|
||||||
|
"reference": "c64eb96049907da60dc9f237d26aef0e531b0015"
|
||||||
},
|
},
|
||||||
"time": "2023-11-20T10:10:39+00:00"
|
"default-branch": true,
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"vlw\\MySQL\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"GPL-3.0-or-later"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Victor Westerlund",
|
||||||
|
"email": "victor@vlw.se"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Abstraction library for common MySQL/MariaDB DML operations with php-mysqli",
|
||||||
|
"time": "2025-01-30T09:33:10+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "vlw/xenum",
|
||||||
|
"version": "dev-master",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://codeberg.org/vlw/php-xenum",
|
||||||
|
"reference": "1c997a5574656b88a62f5ee160ee5a6439932a2f"
|
||||||
|
},
|
||||||
|
"default-branch": true,
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"vlw\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"GPL-3.0-only"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Victor Westerlund",
|
||||||
|
"email": "victor@vlw.se"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "PHP eXtended Enums. The missing quality-of-life features from PHP 8+ Enums",
|
||||||
|
"time": "2024-12-02T10:36:32+00:00"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"packages-dev": [],
|
"packages-dev": [],
|
||||||
|
@ -88,11 +124,13 @@
|
||||||
"minimum-stability": "dev",
|
"minimum-stability": "dev",
|
||||||
"stability-flags": {
|
"stability-flags": {
|
||||||
"reflect/client": 20,
|
"reflect/client": 20,
|
||||||
"victorwesterlund/xenum": 20
|
"reflect/plugin-rules": 20,
|
||||||
|
"vlw/mysql": 20,
|
||||||
|
"vlw/xenum": 20
|
||||||
},
|
},
|
||||||
"prefer-stable": false,
|
"prefer-stable": false,
|
||||||
"prefer-lowest": false,
|
"prefer-lowest": false,
|
||||||
"platform": [],
|
"platform": [],
|
||||||
"platform-dev": [],
|
"platform-dev": [],
|
||||||
"plugin-api-version": "2.0.0"
|
"plugin-api-version": "2.3.0"
|
||||||
}
|
}
|
||||||
|
|
40
endpoints/about/languages/DELETE.php
Normal file
40
endpoints/about/languages/DELETE.php
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use ReflectRules\Ruleset;
|
||||||
|
use Reflect\{Response, Path, Call};
|
||||||
|
|
||||||
|
use VLW\API\Endpoints;
|
||||||
|
use VLW\Database\Database;
|
||||||
|
use VLW\Database\Tables\About\LanguagesTable;
|
||||||
|
|
||||||
|
require_once Path::root("src/API/Endpoints.php");
|
||||||
|
require_once Path::root("src/Database/Database.php");
|
||||||
|
require_once Path::root("src/Database/Tables/About/Languages.php");
|
||||||
|
|
||||||
|
class DELETE_AboutLanguages extends Database {
|
||||||
|
protected readonly Ruleset $ruleset;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->ruleset = new Ruleset(strict: true);
|
||||||
|
$this->ruleset->validate_or_exit();
|
||||||
|
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function languages(): array {
|
||||||
|
$resp = (new Call(Endpoints::ABOUT_LANGUAGES->value))->get();
|
||||||
|
|
||||||
|
return array_column($resp->output(), LanguagesTable::ID->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete languages cache file if it exists
|
||||||
|
public function main(): Response {
|
||||||
|
$this->db->for(LanguagesTable::NAME);
|
||||||
|
|
||||||
|
foreach ($this->languages() as $language){
|
||||||
|
$this->db->delete([LanguagesTable::ID->value => $language]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Response();
|
||||||
|
}
|
||||||
|
}
|
54
endpoints/about/languages/GET.php
Normal file
54
endpoints/about/languages/GET.php
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use vlw\MySQL\Order;
|
||||||
|
use Reflect\{Response, Path, Call};
|
||||||
|
use ReflectRules\{Ruleset, Rules, Type};
|
||||||
|
|
||||||
|
use VLW\API\Endpoints;
|
||||||
|
use VLW\Database\Database;
|
||||||
|
use const VLW\FORGEJO_UPDATE_CACHE_PARAM;
|
||||||
|
use VLW\Database\Tables\About\LanguagesTable;
|
||||||
|
|
||||||
|
require_once Path::root("src/Consts.php");
|
||||||
|
require_once Path::root("src/API/Endpoints.php");
|
||||||
|
require_once Path::root("src/Database/Database.php");
|
||||||
|
require_once Path::root("src/Database/Tables/About/Languages.php");
|
||||||
|
|
||||||
|
class GET_AboutLanguages extends Database {
|
||||||
|
protected readonly Ruleset $ruleset;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->ruleset = new Ruleset(strict: true);
|
||||||
|
|
||||||
|
$this->ruleset->GET([
|
||||||
|
(new Rules(LanguagesTable::ID->value))
|
||||||
|
->type(Type::STRING)
|
||||||
|
->min(1)
|
||||||
|
->max(parent::SIZE_VARCHAR),
|
||||||
|
|
||||||
|
(new Rules(LanguagesTable::BYTES->value))
|
||||||
|
->type(Type::NUMBER)
|
||||||
|
->min(1)
|
||||||
|
->max(parent::SIZE_UINT32),
|
||||||
|
|
||||||
|
(new Rules(FORGEJO_UPDATE_CACHE_PARAM))
|
||||||
|
->type(Type::BOOLEAN)
|
||||||
|
->default(false)
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->ruleset->validate_or_exit();
|
||||||
|
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function main(): Response {
|
||||||
|
// Refresh the language cache if param is set
|
||||||
|
if ($_GET[FORGEJO_UPDATE_CACHE_PARAM]) {
|
||||||
|
(new Call(Endpoints::ABOUT_LANGUAGES->value))->post();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->list(LanguagesTable::NAME, LanguagesTable::values(), [
|
||||||
|
LanguagesTable::BYTES->value => Order::DESC
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,20 +1,29 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Reflect\Call;
|
use ReflectRules\Ruleset;
|
||||||
use Reflect\Path;
|
use Reflect\{Response, Path, Call};
|
||||||
use Reflect\Response;
|
|
||||||
|
|
||||||
const ERRNO_CACHE_FAILED = 0;
|
use VLW\API\Endpoints;
|
||||||
|
use VLW\Database\Database;
|
||||||
|
use VLW\Database\Tables\About\LanguagesTable;
|
||||||
|
use const VLW\{FORGEJO_ENDPOINT_USER, FORGEJO_ENDPOINT_SEARCH};
|
||||||
|
|
||||||
const FORGEJO_ENDPOINT_USER = "/api/v1/users/%s";
|
require_once Path::root("src/Consts.php");
|
||||||
const FORGEJO_ENDPOINT_SEARCH = "/api/v1/repos/search?uid=%s";
|
require_once Path::root("src/API/Endpoints.php");
|
||||||
|
require_once Path::root("src/Database/Tables/About/Languages.php");
|
||||||
|
|
||||||
|
class POST_AboutLanguages extends Database {
|
||||||
|
protected readonly Ruleset $ruleset;
|
||||||
|
|
||||||
class POST_AboutLanguages {
|
|
||||||
private array $errors = [];
|
|
||||||
// Tally of all languages used in all configured repositories
|
// Tally of all languages used in all configured repositories
|
||||||
private array $languages = [];
|
private array $languages = [];
|
||||||
|
|
||||||
public function __construct() {}
|
public function __construct() {
|
||||||
|
$this->ruleset = new Ruleset(strict: true);
|
||||||
|
$this->ruleset->validate_or_exit();
|
||||||
|
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
// Fetch JSON from URL
|
// Fetch JSON from URL
|
||||||
private static function fetch_json(string $url): array {
|
private static function fetch_json(string $url): array {
|
||||||
|
@ -23,20 +32,23 @@
|
||||||
|
|
||||||
// Fetch JSON from a Forgejo endpoint
|
// Fetch JSON from a Forgejo endpoint
|
||||||
private static function fetch_endpoint(string $endpoint): array {
|
private static function fetch_endpoint(string $endpoint): array {
|
||||||
$url = $_ENV["forgejo"]["base_url"] . $endpoint;
|
$url = $_ENV["server_forgejo"]["base_url"] . $endpoint;
|
||||||
return self::fetch_json($url);
|
return self::fetch_json($url);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write $this->languages to a JSON file
|
// Write $this->languages to a JSON file
|
||||||
private function cache_languages(): int|bool {
|
private function cache_languages(): void {
|
||||||
$cache_filename = $_ENV["forgejo_languages"]["cache_file"];
|
// Delete existing cache
|
||||||
|
(new Call(Endpoints::ABOUT_LANGUAGES->value))->delete();
|
||||||
|
|
||||||
// Bail out if cache file is not configured
|
$this->db->for(LanguagesTable::NAME);
|
||||||
if (empty($cache_filename)) {
|
|
||||||
return true;
|
foreach ($this->languages as $language => $bytes) {
|
||||||
|
$this->db->insert([
|
||||||
|
LanguagesTable::ID->value => $language,
|
||||||
|
LanguagesTable::BYTES->value => $bytes
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return file_put_contents($cache_filename, json_encode($this->languages));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch and add languages to total from a fully-qualified Forgejo URL
|
// Fetch and add languages to total from a fully-qualified Forgejo URL
|
||||||
|
@ -71,13 +83,10 @@
|
||||||
|
|
||||||
// Add languages from all public repositories for profiles in config
|
// Add languages from all public repositories for profiles in config
|
||||||
private function add_repositories_from_config_profiles(): void {
|
private function add_repositories_from_config_profiles(): void {
|
||||||
foreach(explode(",", $_ENV["forgejo_languages"]["scan_profiles"]) as $profile) {
|
foreach(explode(",", $_ENV["server_forgejo"]["scan_profiles"]) as $profile) {
|
||||||
// Resolve user data from username
|
// Resolve user data from username
|
||||||
$user = self::fetch_endpoint(sprintf(FORGEJO_ENDPOINT_USER, $profile));
|
$user = self::fetch_endpoint(sprintf(FORGEJO_ENDPOINT_USER, $profile));
|
||||||
|
$this->add_public_repositores($user["id"]);
|
||||||
if (!$this->add_public_repositores($user["id"])) {
|
|
||||||
$this->errors[] = $profile;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,11 +96,7 @@
|
||||||
// Sort langauges bytes tally by largest in descending order
|
// Sort langauges bytes tally by largest in descending order
|
||||||
arsort($this->languages);
|
arsort($this->languages);
|
||||||
|
|
||||||
// Save languages to cache
|
$this->cache_languages();
|
||||||
if (!$this->cache_languages()) {
|
|
||||||
$this->errors[] = ERRNO_CACHE_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Response($this->languages);
|
return new Response($this->languages);
|
||||||
}
|
}
|
||||||
}
|
}
|
43
endpoints/messages/POST.php
Normal file
43
endpoints/messages/POST.php
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Reflect\{Response, Path};
|
||||||
|
use ReflectRules\{Ruleset, Rules, Type};
|
||||||
|
|
||||||
|
use VLW\Database\Database;
|
||||||
|
use VLW\Database\Tables\Messages\MessagesTable;
|
||||||
|
|
||||||
|
require_once Path::root("src/Database/Database.php");
|
||||||
|
require_once Path::root("src/Database/Tables/Messages/Messages.php");
|
||||||
|
|
||||||
|
class POST_Messages extends Database {
|
||||||
|
protected Ruleset $ruleset;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->ruleset = new Ruleset(strict: true);
|
||||||
|
|
||||||
|
$this->ruleset->POST([
|
||||||
|
(new Rules(MessagesTable::EMAIL->value))
|
||||||
|
->type(Type::STRING)
|
||||||
|
->max(255)
|
||||||
|
->default(null),
|
||||||
|
|
||||||
|
(new Rules(MessagesTable::MESSAGE->value))
|
||||||
|
->required()
|
||||||
|
->type(Type::STRING)
|
||||||
|
->min(1)
|
||||||
|
->max(parent::SIZE_TEXT)
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->ruleset->validate_or_exit();
|
||||||
|
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function main(): Response {
|
||||||
|
$_POST[MessagesTable::TIMESTAMP_CREATED->value] = time();
|
||||||
|
|
||||||
|
return $this->db->for(MessagesTable::NAME)->insert($_POST) === true
|
||||||
|
? new Response(null, 201)
|
||||||
|
: new Response("Failed to send message", 500);
|
||||||
|
}
|
||||||
|
}
|
35
endpoints/search/DELETE.php
Normal file
35
endpoints/search/DELETE.php
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use vlw\MySQL\Operators;
|
||||||
|
use Reflect\{Response, Path};
|
||||||
|
use ReflectRules\{Ruleset, Rules, Type};
|
||||||
|
|
||||||
|
use VLW\Database\Database;
|
||||||
|
use VLW\Database\Tables\Search\SearchTable;
|
||||||
|
|
||||||
|
require_once Path::root("src/Database/Database.php");
|
||||||
|
require_once Path::root("src/Database/Tables/Search/Search.php");
|
||||||
|
|
||||||
|
class DELETE_Search extends Database {
|
||||||
|
protected Ruleset $ruleset;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->ruleset = new Ruleset(strict: true);
|
||||||
|
|
||||||
|
$this->ruleset->POST([
|
||||||
|
(new Rules(SearchTable::ID->value))
|
||||||
|
->required()
|
||||||
|
->type(Type::STRING)
|
||||||
|
->min(2)
|
||||||
|
->max(parent::SIZE_VARCHAR)
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->ruleset->validate_or_exit();
|
||||||
|
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function main(): Response {
|
||||||
|
return $this->db->for(SearchTable::NAME)->delete($_POST) === true ? new Response() : new Response("", 500);
|
||||||
|
}
|
||||||
|
}
|
96
endpoints/search/GET.php
Normal file
96
endpoints/search/GET.php
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use vlw\MySQL\Operators;
|
||||||
|
use Reflect\{Response, Path, Call};
|
||||||
|
use ReflectRules\{Ruleset, Rules, Type};
|
||||||
|
|
||||||
|
use VLW\API\Endpoints;
|
||||||
|
use VLW\Database\Database;
|
||||||
|
use const VLW\SEARCH_UPDATE_CACHE_PARM;
|
||||||
|
use VLW\Database\Tables\Search\{SearchTable, SearchCategoryEnum};
|
||||||
|
|
||||||
|
require_once Path::root("src/Consts.php");
|
||||||
|
require_once Path::root("src/API/Endpoints.php");
|
||||||
|
require_once Path::root("src/Database/Database.php");
|
||||||
|
require_once Path::root("src/Database/Tables/Search/Search.php");
|
||||||
|
|
||||||
|
class GET_Search extends Database {
|
||||||
|
protected Ruleset $ruleset;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->ruleset = new Ruleset(strict: true);
|
||||||
|
|
||||||
|
$this->ruleset->GET([
|
||||||
|
(new Rules(SearchTable::QUERY->value))
|
||||||
|
->type(Type::STRING)
|
||||||
|
->min(2)
|
||||||
|
->max(parent::SIZE_VARCHAR)
|
||||||
|
->default(null),
|
||||||
|
|
||||||
|
(new Rules(SearchTable::ID->value))
|
||||||
|
->type(Type::STRING)
|
||||||
|
->min(1)
|
||||||
|
->max(10)
|
||||||
|
->default(null),
|
||||||
|
|
||||||
|
(new Rules(SearchTable::CATEGORY->value))
|
||||||
|
->type(Type::ENUM, SearchCategoryEnum::names())
|
||||||
|
->default(null),
|
||||||
|
|
||||||
|
(new Rules(SEARCH_UPDATE_CACHE_PARM))
|
||||||
|
->type(Type::BOOLEAN)
|
||||||
|
->default(false)
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->ruleset->validate_or_exit();
|
||||||
|
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function get_query(): string {
|
||||||
|
preg_match_all("/[a-zA-Z0-9]+/", $_GET[SearchTable::QUERY->value], $matches);
|
||||||
|
|
||||||
|
return strtolower(implode("", $matches[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function main(): Response {
|
||||||
|
// Freshen cache if update flag is set
|
||||||
|
if ($_GET[SEARCH_UPDATE_CACHE_PARM]) {
|
||||||
|
(new Call(Endpoints::SEARCH->value))->post();
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $this->db->for(SearchTable::NAME);
|
||||||
|
|
||||||
|
if ($_GET[SearchTable::ID->value]) {
|
||||||
|
$result = $result->where([SearchTable::ID->value => $_GET[SearchTable::ID->value]]);
|
||||||
|
} else if ($_GET[SearchTable::QUERY->value]) {
|
||||||
|
$query = self::get_query();
|
||||||
|
|
||||||
|
$filter = [
|
||||||
|
SearchTable::QUERY->value => [
|
||||||
|
Operators::LIKE->value => "%{$query}%"
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
if ($_GET[SearchTable::CATEGORY->value]) {
|
||||||
|
$filter[SearchTable::CATEGORY->value] = $_GET[SearchTable::CATEGORY->value];
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $result->where($filter);
|
||||||
|
} else {
|
||||||
|
new Response([], 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $result->select([
|
||||||
|
SearchTable::ID->value,
|
||||||
|
SearchTable::TITLE->value,
|
||||||
|
SearchTable::SUMMARY->value,
|
||||||
|
SearchTable::CATEGORY->value,
|
||||||
|
SearchTable::HREF->value
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $result->num_rows > 0
|
||||||
|
? new Response($result->fetch_all(MYSQLI_ASSOC))
|
||||||
|
: new Response([], 404);
|
||||||
|
}
|
||||||
|
}
|
73
endpoints/search/POST.php
Normal file
73
endpoints/search/POST.php
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use vlw\MySQL\Operators;
|
||||||
|
use Reflect\{Response, Path, Call};
|
||||||
|
use ReflectRules\{Ruleset, Rules, Type};
|
||||||
|
|
||||||
|
use VLW\API\Endpoints;
|
||||||
|
use VLW\Database\Database;
|
||||||
|
use const VLW\SEARCH_QUERY_MAX_LENGTH;
|
||||||
|
use VLW\Database\Tables\Search\{SearchTable, SearchCategoryEnum};
|
||||||
|
use VLW\Database\Tables\Work\{WorkTable, ActionsTable};
|
||||||
|
|
||||||
|
require_once Path::root("src/Consts.php");
|
||||||
|
require_once Path::root("src/API/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/Actions.php");
|
||||||
|
require_once Path::root("src/Database/Tables/Search/Search.php");
|
||||||
|
|
||||||
|
class POST_Search extends Database {
|
||||||
|
protected Ruleset $ruleset;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->ruleset = new Ruleset(strict: true);
|
||||||
|
$this->ruleset->validate_or_exit();
|
||||||
|
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function truncate_string(string $input): string {
|
||||||
|
return substr($input, 0, SEARCH_QUERY_MAX_LENGTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function create_query(string $input): string {
|
||||||
|
preg_match_all("/[a-zA-Z0-9]+/", $input, $matches);
|
||||||
|
|
||||||
|
return self::truncate_string(strtolower(implode("", $matches[0])));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function index_work(): void {
|
||||||
|
foreach ((new Call(Endpoints::WORK->value))->get()->output() as $result) {
|
||||||
|
$query = self::create_query(implode("", array_values($result)), 0, SEARCH_QUERY_MAX_LENGTH);
|
||||||
|
|
||||||
|
// Get actions related to current result
|
||||||
|
$actions = (new Call(Endpoints::WORK_ACTIONS->value))->params([
|
||||||
|
ActionsTable::REF_WORK_ID->value => $result[WorkTable::ID->value]
|
||||||
|
])->get()->output();
|
||||||
|
|
||||||
|
$this->db->for(SearchTable::NAME)->insert([
|
||||||
|
SearchTable::QUERY->value => $query,
|
||||||
|
SearchTable::ID->value => crc32($query),
|
||||||
|
SearchTable::TITLE->value => self::truncate_string($result[WorkTable::TITLE->value]),
|
||||||
|
SearchTable::SUMMARY->value => self::truncate_string($result[WorkTable::SUMMARY->value]),
|
||||||
|
SearchTable::CATEGORY->value => SearchCategoryEnum::WORK->name,
|
||||||
|
// Use first action as link for search result
|
||||||
|
SearchTable::HREF->value => $actions
|
||||||
|
? self::truncate_string($actions[0][ActionsTable::HREF->value])
|
||||||
|
: null
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function main(): Response {
|
||||||
|
// Truncate existing cache
|
||||||
|
(new Call(Endpoints::SEARCH->value))->delete();
|
||||||
|
|
||||||
|
$this->index_work();
|
||||||
|
|
||||||
|
return $result->num_rows > 0
|
||||||
|
? new Response($result->fetch_all(MYSQLI_ASSOC))
|
||||||
|
: new Response([], 404);
|
||||||
|
}
|
||||||
|
}
|
49
endpoints/work/GET.php
Normal file
49
endpoints/work/GET.php
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use vlw\MySQL\Order;
|
||||||
|
use Reflect\{Response, Path};
|
||||||
|
use ReflectRules\{Ruleset, Rules, Type};
|
||||||
|
|
||||||
|
use VLW\Database\Database;
|
||||||
|
use VLW\Database\Tables\Work\WorkTable;
|
||||||
|
|
||||||
|
require_once Path::root("src/Database/Database.php");
|
||||||
|
require_once Path::root("src/Database/Tables/Work/Work.php");
|
||||||
|
|
||||||
|
class GET_Work extends Database {
|
||||||
|
protected Ruleset $ruleset;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->ruleset = new Ruleset(strict: true);
|
||||||
|
|
||||||
|
$this->ruleset->GET([
|
||||||
|
(new Rules(WorkTable::ID->value))
|
||||||
|
->type(Type::STRING)
|
||||||
|
->min(1)
|
||||||
|
->max(parent::SIZE_VARCHAR),
|
||||||
|
|
||||||
|
(new Rules(WorkTable::TITLE->value))
|
||||||
|
->type(Type::STRING)
|
||||||
|
->max(parent::SIZE_VARCHAR),
|
||||||
|
|
||||||
|
(new Rules(WorkTable::SUMMARY->value))
|
||||||
|
->type(Type::STRING)
|
||||||
|
->max(parent::SIZE_TEXT),
|
||||||
|
|
||||||
|
(new Rules(WorkTable::CREATED->value))
|
||||||
|
->type(Type::STRING)
|
||||||
|
->min(1)
|
||||||
|
->max(parent::SIZE_VARCHAR)
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->ruleset->validate_or_exit();
|
||||||
|
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function main(): Response {
|
||||||
|
return $this->list(WorkTable::NAME, WorkTable::values(), [
|
||||||
|
WorkTable::CREATED->value => Order::DESC
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
36
endpoints/work/actions/GET.php
Normal file
36
endpoints/work/actions/GET.php
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use vlw\MySQL\Order;
|
||||||
|
use Reflect\{Response, Path};
|
||||||
|
use ReflectRules\{Ruleset, Rules, Type};
|
||||||
|
|
||||||
|
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/Work/Actions.php");
|
||||||
|
|
||||||
|
class GET_WorkActions extends Database {
|
||||||
|
protected Ruleset $ruleset;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->ruleset = new Ruleset(strict: true);
|
||||||
|
|
||||||
|
$this->ruleset->GET([
|
||||||
|
(new Rules(ActionsTable::REF_WORK_ID->value))
|
||||||
|
->type(Type::STRING)
|
||||||
|
->min(1)
|
||||||
|
->max(parent::SIZE_VARCHAR)
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->ruleset->validate_or_exit();
|
||||||
|
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function main(): Response {
|
||||||
|
return $this->list(ActionsTable::NAME, ActionsTable::values(), [
|
||||||
|
ActionsTable::ORDER_IDX->value => Order::DESC
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
35
endpoints/work/tags/GET.php
Normal file
35
endpoints/work/tags/GET.php
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Reflect\{Response, Path};
|
||||||
|
use ReflectRules\{Ruleset, Rules, Type};
|
||||||
|
|
||||||
|
use VLW\Database\Database;
|
||||||
|
use VLW\Database\Tables\Work\{TagsTable, TagsLabelEnum};
|
||||||
|
|
||||||
|
require_once Path::root("src/Database/Database.php");
|
||||||
|
require_once Path::root("src/Database/Tables/Work/Tags.php");
|
||||||
|
|
||||||
|
class GET_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::LABEL->value))
|
||||||
|
->type(Type::ENUM, TagsLabelEnum::names())
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->ruleset->validate_or_exit();
|
||||||
|
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function main(): Response {
|
||||||
|
return $this->list(TagsTable::NAME, TagsTable::values());
|
||||||
|
}
|
||||||
|
}
|
53
endpoints/work/timeline/GET.php
Normal file
53
endpoints/work/timeline/GET.php
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use vlw\MySQL\Order;
|
||||||
|
use Reflect\{Response, Path};
|
||||||
|
use ReflectRules\{Ruleset, Rules, Type};
|
||||||
|
|
||||||
|
use VLW\Database\Database;
|
||||||
|
use VLW\Database\Tables\Work\TimelineTable;
|
||||||
|
|
||||||
|
require_once Path::root("src/Database/Database.php");
|
||||||
|
require_once Path::root("src/Database/Tables/Work/Timeline.php");
|
||||||
|
|
||||||
|
class GET_WorkTimeline extends Database {
|
||||||
|
protected Ruleset $ruleset;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->ruleset = new Ruleset(strict: true);
|
||||||
|
|
||||||
|
$this->ruleset->GET([
|
||||||
|
(new Rules(TimelineTable::REF_WORK_ID->value))
|
||||||
|
->type(Type::STRING)
|
||||||
|
->min(1)
|
||||||
|
->max(parent::SIZE_VARCHAR),
|
||||||
|
|
||||||
|
(new Rules(TimelineTable::YEAR->value))
|
||||||
|
->type(Type::NUMBER)
|
||||||
|
->min(0)
|
||||||
|
->max(parent::SIZE_UINT16),
|
||||||
|
|
||||||
|
(new Rules(TimelineTable::MONTH->value))
|
||||||
|
->type(Type::NUMBER)
|
||||||
|
->min(0)
|
||||||
|
->max(parent::SIZE_UINT8),
|
||||||
|
|
||||||
|
(new Rules(TimelineTable::DAY->value))
|
||||||
|
->type(Type::NUMBER)
|
||||||
|
->min(0)
|
||||||
|
->max(parent::SIZE_UINT8)
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->ruleset->validate_or_exit();
|
||||||
|
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function main(): Response {
|
||||||
|
return $this->list(TimelineTable::NAME, TimelineTable::values(), [
|
||||||
|
TimelineTable::YEAR->value => Order::DESC,
|
||||||
|
TimelineTable::MONTH->value => Order::DESC,
|
||||||
|
TimelineTable::DAY->value => Order::DESC
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,64 +1,39 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Vegvisir\Path;
|
use VLW\Database\Models\About\Language;
|
||||||
use Reflect\Response;
|
use const VLW\{
|
||||||
|
FORGEJO_HREF,
|
||||||
|
FORGEJO_SI_BYTE_MULTIPLE,
|
||||||
|
DEFAULT_BUTTON_ICON
|
||||||
|
};
|
||||||
|
|
||||||
use VLW\Client\API;
|
require_once VV::root("src/Consts.php");
|
||||||
use VLW\API\Endpoints;
|
require_once VV::root("src/Database/Models/About/Language.php");
|
||||||
|
|
||||||
require_once VV::root("src/client/API.php");
|
$languages = new class extends Language {
|
||||||
require_once VV::root("api/src/Endpoints.php");
|
private readonly int $total_bytes;
|
||||||
|
|
||||||
const BYTE_UNITS = ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
|
||||||
const FORGEJO_HREF = "https://git.vlw.se/explore/repos?q=&sort=recentupdate&language=";
|
|
||||||
|
|
||||||
$langs = new class extends API {
|
|
||||||
public readonly int $total_bytes;
|
|
||||||
|
|
||||||
private readonly Response $resp;
|
|
||||||
private readonly array $languages;
|
|
||||||
|
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
parent::__construct();
|
$this->total_bytes = array_sum(array_map(fn(Language $language): int => $language->bytes(), parent::all()));
|
||||||
|
|
||||||
// Fetch languages from endpoint
|
|
||||||
$this->resp = $this->call(Endpoints::ABOUT_LANGUAGES->value)->get();
|
|
||||||
|
|
||||||
// We got a response from endpoint
|
|
||||||
if ($this->resp->ok) {
|
|
||||||
$this->languages = $this->resp->json();
|
|
||||||
$this->total_bytes = array_sum($this->languages);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return all languages as (string) language => (int) language_bytes
|
public function percent(Language $language, int $mode = PHP_ROUND_HALF_UP): int {
|
||||||
public function all(): array {
|
return round(($language->bytes() / $this->total_bytes) * 100, 0, $mode);
|
||||||
return $this->languages;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return percent of total for all languages
|
public function percent_string(Language $language): string {
|
||||||
public function get_percent(string $lang, int $mode = PHP_ROUND_HALF_UP): int {
|
return ($this->percent($language) > 1 ? $this->percent($language) : "<1") . "%";
|
||||||
return round(($this->languages[$lang] / $this->total_bytes) * 100, 0, $mode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return language bytes as percent of whole
|
public function bytes_si_string(Language $language): string {
|
||||||
public function get_percent_str(string $lang): string {
|
|
||||||
$percent = $this->get_percent($lang, PHP_ROUND_HALF_DOWN);
|
|
||||||
return ($percent > 1 ? $percent : "<1") . "%";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return languages bytes as a multiple-byte decimal unit
|
|
||||||
public function get_bytes_str(string $lang): string {
|
|
||||||
$bytes = $this->languages[$lang];
|
|
||||||
|
|
||||||
// Calculate factor for unit
|
// Calculate factor for unit
|
||||||
$factor = floor((strlen($bytes) - 1) / 3);
|
$factor = floor((strlen($language->bytes()) - 1) / 3);
|
||||||
// Divide by radix 10
|
// Divide by radix 10
|
||||||
$format = $bytes / pow(1000, $factor);
|
$format = $language->bytes() / pow(1000, $factor);
|
||||||
|
|
||||||
return round($format) . " " . BYTE_UNITS[$factor];
|
return round($format) . " " . FORGEJO_SI_BYTE_MULTIPLE[$factor];
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<style><?= VV::css("public/assets/css/pages/about") ?></style>
|
<style><?= VV::css("public/assets/css/pages/about") ?></style>
|
||||||
|
@ -74,32 +49,30 @@
|
||||||
<section class="languages">
|
<section class="languages">
|
||||||
<stacked-bar-chart>
|
<stacked-bar-chart>
|
||||||
|
|
||||||
<?php foreach ($langs->all() as $lang => $bytes): ?>
|
<?php foreach ($languages::all() as $language): ?>
|
||||||
<a href="<?= FORGEJO_HREF . $lang ?>" target="_blank"><chart-segment style="--size:<?= $langs->get_percent($lang) ?>%;" data-lang="<?= $lang ?>" data-bytes="<?= $bytes ?>">
|
<a href="<?= FORGEJO_HREF . $language->id ?>" target="_blank"><chart-segment style="--size:<?= $languages->percent($language) ?>%;" data-lang="<?= $language->id ?>" data-bytes="<?= $language->bytes() ?>">
|
||||||
<span data-hover><strong><?= $langs->get_percent_str($lang) ?> <?= $lang ?></strong><br>(<?= $bytes ?> bytes)</span>
|
<span data-hover><strong><?= $languages->percent_string($language) ?> <?= $language->id ?></strong><br>(<?= $language->bytes() ?> bytes)</span>
|
||||||
<!--<p><span><?= $lang ?></span></p>-->
|
|
||||||
</chart-segment></a>
|
</chart-segment></a>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
|
|
||||||
</stacked-bar-chart>
|
</stacked-bar-chart>
|
||||||
<languages-list>
|
<languages-list>
|
||||||
|
|
||||||
<?php foreach ($langs->all() as $lang => $bytes): ?>
|
<?php foreach ($languages::all() as $language): ?>
|
||||||
<a href="<?= FORGEJO_HREF . $lang ?>"><button data-lang="<?= $lang ?>" class="inline">
|
<a href="<?= FORGEJO_HREF . $language->id ?>"><button data-lang="<?= $language->id ?>" class="inline">
|
||||||
<p><?= $langs->get_percent_str($lang) ?></p>
|
<p><?= $languages->percent_string($language) ?></p>
|
||||||
<p class="lang"><?= $lang ?></p>
|
<p class="lang"><?= $language->id ?></p>
|
||||||
<p><?= $langs->get_bytes_str($lang) ?></p>
|
<p><?= $languages->bytes_si_string($language) ?></p>
|
||||||
<?= VV::embed("public/assets/media/icons/chevron.svg") ?>
|
<?= VV::embed(DEFAULT_BUTTON_ICON) ?>
|
||||||
</button></a>
|
</button></a>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
|
|
||||||
</languages-list>
|
</languages-list>
|
||||||
<stacked-bar-chart>
|
<stacked-bar-chart>
|
||||||
|
|
||||||
<?php foreach ($langs->all() as $lang => $bytes): ?>
|
<?php foreach ($languages::all() as $language): ?>
|
||||||
<a href="<?= FORGEJO_HREF . $lang ?>" target="_blank"><chart-segment style="--size:<?= $langs->get_percent($lang) ?>%;" data-lang="<?= $lang ?>" data-bytes="<?= $bytes ?>">
|
<a href="<?= FORGEJO_HREF . $language->id ?>" target="_blank"><chart-segment style="--size:<?= $languages->percent($language) ?>%;" data-lang="<?= $language->id ?>" data-bytes="<?= $language->bytes() ?>">
|
||||||
<span data-hover><strong><?= $langs->get_percent_str($lang) ?> <?= $lang ?></strong><br>(<?= $bytes ?> bytes)</span>
|
<span data-hover><strong><?= $languages->percent_string($language) ?> <?= $language->id ?></strong><br>(<?= $language->bytes() ?> bytes)</span>
|
||||||
<!--<p><span><?= $lang ?></span></p>-->
|
|
||||||
</chart-segment></a>
|
</chart-segment></a>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
|
|
||||||
|
@ -115,7 +88,7 @@
|
||||||
<h2>Personal</h2>
|
<h2>Personal</h2>
|
||||||
<p>Coffee, of course.. and..</p>
|
<p>Coffee, of course.. and..</p>
|
||||||
<p>At times, I become a true, amateur, armchair detective for a <span class="interests">variety of your typical-nerdy topics that I find interesting</span>. And will spend a disproportionate to real-world-personal-use amount of time reading about that stuff too.</p>
|
<p>At times, I become a true, amateur, armchair detective for a <span class="interests">variety of your typical-nerdy topics that I find interesting</span>. And will spend a disproportionate to real-world-personal-use amount of time reading about that stuff too.</p>
|
||||||
<p>Another silent passion of mine that comes out every few years is <a href="/about/battlestation">building computers</a> and fiddling with weird networking stuff.</p>
|
<p>Another silent passion of mine that comes out every few years is building computers and fiddling with weird networking stuff.</p>
|
||||||
<p>And then of course I don't mind some occational gaming, and watching movies and TV-series.</p>
|
<p>And then of course I don't mind some occational gaming, and watching movies and TV-series.</p>
|
||||||
</section>
|
</section>
|
||||||
<section class="about">
|
<section class="about">
|
||||||
|
|
|
@ -5,22 +5,22 @@
|
||||||
use VLW\Client\API;
|
use VLW\Client\API;
|
||||||
use VLW\API\Endpoints;
|
use VLW\API\Endpoints;
|
||||||
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Battlestation\{
|
use VLW\Database\Tables\Battlestation\{
|
||||||
MbModel,
|
MbTable,
|
||||||
CpuModel,
|
CpuTable,
|
||||||
GpuModel,
|
GpuTable,
|
||||||
PsuModel,
|
PsuTable,
|
||||||
DramModel,
|
DramTable,
|
||||||
StorageModel,
|
StorageTable,
|
||||||
ChassisModel
|
ChassisTable
|
||||||
};
|
};
|
||||||
use VLW\API\Databases\VLWdb\Models\Battlestation\Config\{
|
use VLW\Database\Tables\Battlestation\Config\{
|
||||||
MbPsuModel,
|
MbPsuTable,
|
||||||
MbGpuModel,
|
MbGpuTable,
|
||||||
MbDramModel,
|
MbDramTable,
|
||||||
ConfigModel,
|
ConfigModel,
|
||||||
MbStorageModel,
|
MbStorageTable,
|
||||||
ChassisMbModel,
|
ChassisMbTable,
|
||||||
MbCpuCoolerModel,
|
MbCpuCoolerModel,
|
||||||
MbStorageSlotFormfactorEnum
|
MbStorageSlotFormfactorEnum
|
||||||
};
|
};
|
||||||
|
@ -29,22 +29,22 @@
|
||||||
require_once VV::root("api/src/Endpoints.php");
|
require_once VV::root("api/src/Endpoints.php");
|
||||||
|
|
||||||
// Load hardware database models
|
// Load hardware database models
|
||||||
require_once VV::root("api/src/databases/models/Battlestation/Mb.php");
|
require_once VV::root("api/src/Database/Tables/Battlestation/Mb.php");
|
||||||
require_once VV::root("api/src/databases/models/Battlestation/Cpu.php");
|
require_once VV::root("api/src/Database/Tables/Battlestation/Cpu.php");
|
||||||
require_once VV::root("api/src/databases/models/Battlestation/Gpu.php");
|
require_once VV::root("api/src/Database/Tables/Battlestation/Gpu.php");
|
||||||
require_once VV::root("api/src/databases/models/Battlestation/Psu.php");
|
require_once VV::root("api/src/Database/Tables/Battlestation/Psu.php");
|
||||||
require_once VV::root("api/src/databases/models/Battlestation/Dram.php");
|
require_once VV::root("api/src/Database/Tables/Battlestation/Dram.php");
|
||||||
require_once VV::root("api/src/databases/models/Battlestation/Storage.php");
|
require_once VV::root("api/src/Database/Tables/Battlestation/Storage.php");
|
||||||
require_once VV::root("api/src/databases/models/Battlestation/Chassis.php");
|
require_once VV::root("api/src/Database/Tables/Battlestation/Chassis.php");
|
||||||
|
|
||||||
// Load hardware config database models
|
// Load hardware config database models
|
||||||
require_once VV::root("api/src/databases/models/Battlestation/Config/MbPsu.php");
|
require_once VV::root("api/src/Database/Tables/Battlestation/Config/MbPsu.php");
|
||||||
require_once VV::root("api/src/databases/models/Battlestation/Config/MbGpu.php");
|
require_once VV::root("api/src/Database/Tables/Battlestation/Config/MbGpu.php");
|
||||||
require_once VV::root("api/src/databases/models/Battlestation/Config/MbDram.php");
|
require_once VV::root("api/src/Database/Tables/Battlestation/Config/MbDram.php");
|
||||||
require_once VV::root("api/src/databases/models/Battlestation/Config/Config.php");
|
require_once VV::root("api/src/Database/Tables/Battlestation/Config/Config.php");
|
||||||
require_once VV::root("api/src/databases/models/Battlestation/Config/MbStorage.php");
|
require_once VV::root("api/src/Database/Tables/Battlestation/Config/MbStorage.php");
|
||||||
require_once VV::root("api/src/databases/models/Battlestation/Config/ChassisMb.php");
|
require_once VV::root("api/src/Database/Tables/Battlestation/Config/ChassisMb.php");
|
||||||
require_once VV::root("api/src/databases/models/Battlestation/Config/MbCpuCooler.php");
|
require_once VV::root("api/src/Database/Tables/Battlestation/Config/MbCpuCooler.php");
|
||||||
|
|
||||||
const GIGA = 0x3B9ACA00;
|
const GIGA = 0x3B9ACA00;
|
||||||
const MEGA = 0xF4240;
|
const MEGA = 0xF4240;
|
||||||
|
@ -73,7 +73,7 @@
|
||||||
|
|
||||||
// Get motherboard details by ref_mb_id from config
|
// Get motherboard details by ref_mb_id from config
|
||||||
$motherboard = $api->call(Endpoints::BATTLESTATION_MB->value)->params([
|
$motherboard = $api->call(Endpoints::BATTLESTATION_MB->value)->params([
|
||||||
MbModel::ID->value => $config[ChassisMbModel::REF_MB_ID->value]
|
MbTable::ID->value => $config[ChassisMbTable::REF_MB_ID->value]
|
||||||
])->get()->json()[0];
|
])->get()->json()[0];
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
@ -89,9 +89,9 @@
|
||||||
data-gpu="<?= count($motherboard["gpus"]) ?>"
|
data-gpu="<?= count($motherboard["gpus"]) ?>"
|
||||||
data-dram="<?= count($motherboard["dram"]) ?>"
|
data-dram="<?= count($motherboard["dram"]) ?>"
|
||||||
data-case="<?= count($motherboard["chassis"]) ?>"
|
data-case="<?= count($motherboard["chassis"]) ?>"
|
||||||
data-drives-mdottwo="<?= count(array_keys(array_column($motherboard["storage"], MbStorageModel::SLOT_FORMFACTOR->value), MbStorageSlotFormfactorEnum::MDOTTWO->value)) ?>"
|
data-drives-mdottwo="<?= count(array_keys(array_column($motherboard["storage"], MbStorageTable::SLOT_FORMFACTOR->value), MbStorageSlotFormfactorEnum::MDOTTWO->value)) ?>"
|
||||||
data-drives-twodotfive="<?= count(array_keys(array_column($motherboard["storage"], MbStorageModel::SLOT_FORMFACTOR->value), MbStorageSlotFormfactorEnum::TWODOTFIVE->value)) ?>"
|
data-drives-twodotfive="<?= count(array_keys(array_column($motherboard["storage"], MbStorageTable::SLOT_FORMFACTOR->value), MbStorageSlotFormfactorEnum::TWODOTFIVE->value)) ?>"
|
||||||
data-drives-threedotfive="<?= count(array_keys(array_column($motherboard["storage"], MbStorageModel::SLOT_FORMFACTOR->value), MbStorageSlotFormfactorEnum::THREEDOTFIVE->value)) ?>"
|
data-drives-threedotfive="<?= count(array_keys(array_column($motherboard["storage"], MbStorageTable::SLOT_FORMFACTOR->value), MbStorageSlotFormfactorEnum::THREEDOTFIVE->value)) ?>"
|
||||||
>
|
>
|
||||||
<?= VV::embed("public/assets/media/battlestation.svg") ?>
|
<?= VV::embed("public/assets/media/battlestation.svg") ?>
|
||||||
<div class="specs">
|
<div class="specs">
|
||||||
|
@ -100,38 +100,38 @@
|
||||||
<?php if ($motherboard): ?>
|
<?php if ($motherboard): ?>
|
||||||
<div data-target="mb" class="spec">
|
<div data-target="mb" class="spec">
|
||||||
<p>Motherboard</p>
|
<p>Motherboard</p>
|
||||||
<h3><?= $motherboard[MbModel::VENDOR_NAME->value] ?> <span><?= $motherboard[MbModel::VENDOR_MODEL->value] ?></span></h3>
|
<h3><?= $motherboard[MbTable::VENDOR_NAME->value] ?> <span><?= $motherboard[MbTable::VENDOR_MODEL->value] ?></span></h3>
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<label>Formfactor</label>
|
<label>Formfactor</label>
|
||||||
<p><?= $motherboard[MbModel::FORMFACTOR->value] ?></p>
|
<p><?= $motherboard[MbTable::FORMFACTOR->value] ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Brand name</label>
|
<label>Brand name</label>
|
||||||
<p><?= $motherboard[MbModel::VENDOR_NAME->value] ?></p>
|
<p><?= $motherboard[MbTable::VENDOR_NAME->value] ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Brand model</label>
|
<label>Brand model</label>
|
||||||
<p><?= $motherboard[MbModel::VENDOR_MODEL->value] ?></p>
|
<p><?= $motherboard[MbTable::VENDOR_MODEL->value] ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>LAN</label>
|
<label>LAN</label>
|
||||||
<p><?= $motherboard[MbModel::NETWORK_ETHERNET->value] ?? "No LAN" ?></p>
|
<p><?= $motherboard[MbTable::NETWORK_ETHERNET->value] ?? "No LAN" ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>WLAN</label>
|
<label>WLAN</label>
|
||||||
<p><?= $motherboard[MbModel::NETWORK_WLAN->value] ?? "No WLAN" ?></p>
|
<p><?= $motherboard[MbTable::NETWORK_WLAN->value] ?? "No WLAN" ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Bluetooth</label>
|
<label>Bluetooth</label>
|
||||||
<p><?= $motherboard[MbModel::NETWORK_BLUETOOTH->value] ?? "No Bluetooth" ?></p>
|
<p><?= $motherboard[MbTable::NETWORK_BLUETOOTH->value] ?? "No Bluetooth" ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Aquired</label>
|
<label>Aquired</label>
|
||||||
<p><?= date(API::DATE_FORMAT, $motherboard[MbModel::DATE_AQUIRED->value]) ?></p>
|
<p><?= date(API::DATE_FORMAT, $motherboard[MbTable::DATE_AQUIRED->value]) ?></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php if ($motherboard[MbModel::IS_RETIRED->value]): ?>
|
<?php if ($motherboard[MbTable::IS_RETIRED->value]): ?>
|
||||||
<div>
|
<div>
|
||||||
<label>Retired</label>
|
<label>Retired</label>
|
||||||
<p>Yes</p>
|
<p>Yes</p>
|
||||||
|
@ -146,35 +146,35 @@
|
||||||
|
|
||||||
<?php // Get case details from endpoint by id ?>
|
<?php // Get case details from endpoint by id ?>
|
||||||
<?php $case = $api->call(Endpoints::BATTLESTATION_CHASSIS->value)->params([
|
<?php $case = $api->call(Endpoints::BATTLESTATION_CHASSIS->value)->params([
|
||||||
ChassisModel::ID->value => $mb_chassis[ChassisMbModel::REF_CHASSIS_ID->value]
|
ChassisTable::ID->value => $mb_chassis[ChassisMbTable::REF_CHASSIS_ID->value]
|
||||||
])->get()->json()[0]; ?>
|
])->get()->json()[0]; ?>
|
||||||
|
|
||||||
<div data-target="case" class="spec">
|
<div data-target="case" class="spec">
|
||||||
<p>Case</p>
|
<p>Case</p>
|
||||||
<h3><?= $case[ChassisModel::VENDOR_NAME->value] ?> <span><?= $case[ChassisModel::VENDOR_MODEL->value] ?></span></h3>
|
<h3><?= $case[ChassisTable::VENDOR_NAME->value] ?> <span><?= $case[ChassisTable::VENDOR_MODEL->value] ?></span></h3>
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<label>Brand name</label>
|
<label>Brand name</label>
|
||||||
<p><?= $case[ChassisModel::VENDOR_NAME->value] ?></p>
|
<p><?= $case[ChassisTable::VENDOR_NAME->value] ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Brand model</label>
|
<label>Brand model</label>
|
||||||
<p><?= $case[ChassisModel::VENDOR_MODEL->value] ?></p>
|
<p><?= $case[ChassisTable::VENDOR_MODEL->value] ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Nº 2.5" slots</label>
|
<label>Nº 2.5" slots</label>
|
||||||
<p><?= $case[ChassisModel::STORAGE_TWOINCHFIVE->value] ?></p>
|
<p><?= $case[ChassisTable::STORAGE_TWOINCHFIVE->value] ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Nº 3.5" slots</label>
|
<label>Nº 3.5" slots</label>
|
||||||
<p><?= $case[ChassisModel::STORAGE_THREEINCHFIVE->value] ?></p>
|
<p><?= $case[ChassisTable::STORAGE_THREEINCHFIVE->value] ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Aquired</label>
|
<label>Aquired</label>
|
||||||
<p><?= date(API::DATE_FORMAT, $case[ChassisModel::DATE_AQUIRED->value]) ?></p>
|
<p><?= date(API::DATE_FORMAT, $case[ChassisTable::DATE_AQUIRED->value]) ?></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php if ($case[ChassisModel::IS_RETIRED->value]): ?>
|
<?php if ($case[ChassisTable::IS_RETIRED->value]): ?>
|
||||||
<div>
|
<div>
|
||||||
<label>Retired</label>
|
<label>Retired</label>
|
||||||
<p>Yes</p>
|
<p>Yes</p>
|
||||||
|
@ -189,47 +189,47 @@
|
||||||
|
|
||||||
<?php // Get case details from endpoint by id ?>
|
<?php // Get case details from endpoint by id ?>
|
||||||
<?php $cpu = $api->call(Endpoints::BATTLESTATION_CPU->value)->params([
|
<?php $cpu = $api->call(Endpoints::BATTLESTATION_CPU->value)->params([
|
||||||
CpuModel::ID->value => $mb_cpu[MbCpuCoolerModel::REF_CPU_ID->value]
|
CpuTable::ID->value => $mb_cpu[MbCpuCoolerModel::REF_CPU_ID->value]
|
||||||
])->get()->json()[0]; ?>
|
])->get()->json()[0]; ?>
|
||||||
|
|
||||||
<div data-target="cpu" class="spec">
|
<div data-target="cpu" class="spec">
|
||||||
<p>CPU</p>
|
<p>CPU</p>
|
||||||
<h3><?= $cpu[CpuModel::VENDOR_NAME->value] ?> <span><?= $cpu[CpuModel::VENDOR_MODEL->value] ?></span></h3>
|
<h3><?= $cpu[CpuTable::VENDOR_NAME->value] ?> <span><?= $cpu[CpuTable::VENDOR_MODEL->value] ?></span></h3>
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<label>Brand name</label>
|
<label>Brand name</label>
|
||||||
<p><?= $cpu[CpuModel::VENDOR_NAME->value] ?></p>
|
<p><?= $cpu[CpuTable::VENDOR_NAME->value] ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Brand model</label>
|
<label>Brand model</label>
|
||||||
<p><?= $cpu[CpuModel::VENDOR_MODEL->value] ?></p>
|
<p><?= $cpu[CpuTable::VENDOR_MODEL->value] ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Class</label>
|
<label>Class</label>
|
||||||
<p><?= $cpu[CpuModel::CPU_CLASS->value] ?></p>
|
<p><?= $cpu[CpuTable::CPU_CLASS->value] ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Base Clockspeed</label>
|
<label>Base Clockspeed</label>
|
||||||
<p><?= $cpu[CpuModel::CLOCK_BASE->value] / GIGA ?>GHz</p>
|
<p><?= $cpu[CpuTable::CLOCK_BASE->value] / GIGA ?>GHz</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Turbo Clockspeed</label>
|
<label>Turbo Clockspeed</label>
|
||||||
<p><?= $cpu[CpuModel::CLOCK_TURBO->value] / GIGA ?>GHz</p>
|
<p><?= $cpu[CpuTable::CLOCK_TURBO->value] / GIGA ?>GHz</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Nº cores (P/E)</label>
|
<label>Nº cores (P/E)</label>
|
||||||
<p><?= $cpu[CpuModel::CORE_COUNT_PERFORMANCE->value] + $cpu[CpuModel::CORE_COUNT_EFFICIENCY->value] ?> (<?= $cpu[CpuModel::CORE_COUNT_PERFORMANCE->value] ?>/<?= $cpu[CpuModel::CORE_COUNT_EFFICIENCY->value] ?>)</p>
|
<p><?= $cpu[CpuTable::CORE_COUNT_PERFORMANCE->value] + $cpu[CpuTable::CORE_COUNT_EFFICIENCY->value] ?> (<?= $cpu[CpuTable::CORE_COUNT_PERFORMANCE->value] ?>/<?= $cpu[CpuTable::CORE_COUNT_EFFICIENCY->value] ?>)</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Nº total threads</label>
|
<label>Nº total threads</label>
|
||||||
<p><?= $cpu[CpuModel::CORE_THREADS->value] ?></p>
|
<p><?= $cpu[CpuTable::CORE_THREADS->value] ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Aquired</label>
|
<label>Aquired</label>
|
||||||
<p><?= date(API::DATE_FORMAT, $cpu[CpuModel::DATE_AQUIRED->value]) ?></p>
|
<p><?= date(API::DATE_FORMAT, $cpu[CpuTable::DATE_AQUIRED->value]) ?></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php if ($cpu[CpuModel::IS_RETIRED->value]): ?>
|
<?php if ($cpu[CpuTable::IS_RETIRED->value]): ?>
|
||||||
<div>
|
<div>
|
||||||
<label>Retired</label>
|
<label>Retired</label>
|
||||||
<p>Yes</p>
|
<p>Yes</p>
|
||||||
|
@ -254,39 +254,39 @@
|
||||||
|
|
||||||
<?php // Get case details from endpoint by id ?>
|
<?php // Get case details from endpoint by id ?>
|
||||||
<?php $gpu = $api->call(Endpoints::BATTLESTATION_GPU->value)->params([
|
<?php $gpu = $api->call(Endpoints::BATTLESTATION_GPU->value)->params([
|
||||||
GpuModel::ID->value => $mb_gpu[MbGpuModel::REF_GPU_ID->value]
|
GpuTable::ID->value => $mb_gpu[MbGpuTable::REF_GPU_ID->value]
|
||||||
])->get()->json()[0]; ?>
|
])->get()->json()[0]; ?>
|
||||||
|
|
||||||
<div data-target="gpu" class="spec">
|
<div data-target="gpu" class="spec">
|
||||||
<p>GPU</p>
|
<p>GPU</p>
|
||||||
<h3><?= $gpu[GpuModel::VENDOR_NAME->value] ?> <span><?= $gpu[GpuModel::VENDOR_CHIP_MODEL->value] ?></span></h3>
|
<h3><?= $gpu[GpuTable::VENDOR_NAME->value] ?> <span><?= $gpu[GpuTable::VENDOR_CHIP_MODEL->value] ?></span></h3>
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<label>Chip brand name</label>
|
<label>Chip brand name</label>
|
||||||
<p><?= $gpu[GpuModel::VENDOR_CHIP_NAME->value] ?></p>
|
<p><?= $gpu[GpuTable::VENDOR_CHIP_NAME->value] ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Chip brand model</label>
|
<label>Chip brand model</label>
|
||||||
<p><?= $gpu[GpuModel::VENDOR_CHIP_MODEL->value] ?></p>
|
<p><?= $gpu[GpuTable::VENDOR_CHIP_MODEL->value] ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>VRAM</label>
|
<label>VRAM</label>
|
||||||
<p><?= $gpu[GpuModel::MEMORY->value] / GIGA ?>GB</p>
|
<p><?= $gpu[GpuTable::MEMORY->value] / GIGA ?>GB</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Brand name</label>
|
<label>Brand name</label>
|
||||||
<p><?= $gpu[GpuModel::VENDOR_NAME->value] ?></p>
|
<p><?= $gpu[GpuTable::VENDOR_NAME->value] ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Brand model</label>
|
<label>Brand model</label>
|
||||||
<p><?= $gpu[GpuModel::VENDOR_MODEL->value] ?></p>
|
<p><?= $gpu[GpuTable::VENDOR_MODEL->value] ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Aquired</label>
|
<label>Aquired</label>
|
||||||
<p><?= date(API::DATE_FORMAT, $gpu[GpuModel::DATE_AQUIRED->value]) ?></p>
|
<p><?= date(API::DATE_FORMAT, $gpu[GpuTable::DATE_AQUIRED->value]) ?></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php if ($gpu[GpuModel::IS_RETIRED->value]): ?>
|
<?php if ($gpu[GpuTable::IS_RETIRED->value]): ?>
|
||||||
<div>
|
<div>
|
||||||
<label>Retired</label>
|
<label>Retired</label>
|
||||||
<p>Yes</p>
|
<p>Yes</p>
|
||||||
|
@ -301,39 +301,39 @@
|
||||||
|
|
||||||
<?php // Get case details from endpoint by id ?>
|
<?php // Get case details from endpoint by id ?>
|
||||||
<?php $psu = $api->call(Endpoints::BATTLESTATION_PSU->value)->params([
|
<?php $psu = $api->call(Endpoints::BATTLESTATION_PSU->value)->params([
|
||||||
PsuModel::ID->value => $mb_psu[MbPsuModel::REF_PSU_ID->value]
|
PsuTable::ID->value => $mb_psu[MbPsuTable::REF_PSU_ID->value]
|
||||||
])->get()->json()[0]; ?>
|
])->get()->json()[0]; ?>
|
||||||
|
|
||||||
<div data-target="psu" class="spec">
|
<div data-target="psu" class="spec">
|
||||||
<p>PSU</p>
|
<p>PSU</p>
|
||||||
<h3><?= $psu[PsuModel::VENDOR_NAME->value] ?> <span><?= $psu[PsuModel::VENDOR_MODEL->value] ?></span> <span><?= $psu[PsuModel::POWER->value] ?>W</span></h3>
|
<h3><?= $psu[PsuTable::VENDOR_NAME->value] ?> <span><?= $psu[PsuTable::VENDOR_MODEL->value] ?></span> <span><?= $psu[PsuTable::POWER->value] ?>W</span></h3>
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<label>Power</label>
|
<label>Power</label>
|
||||||
<p><?= $psu[PsuModel::POWER->value] ?>W</p>
|
<p><?= $psu[PsuTable::POWER->value] ?>W</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Brand name</label>
|
<label>Brand name</label>
|
||||||
<p><?= $psu[PsuModel::VENDOR_NAME->value] ?></p>
|
<p><?= $psu[PsuTable::VENDOR_NAME->value] ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Brand model</label>
|
<label>Brand model</label>
|
||||||
<p><?= $psu[PsuModel::VENDOR_MODEL->value] ?></p>
|
<p><?= $psu[PsuTable::VENDOR_MODEL->value] ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Is modular?</label>
|
<label>Is modular?</label>
|
||||||
<p><?= $psu[PsuModel::TYPE_MODULAR->value] === "TRUE" ? "Yes" : "No" ?></p>
|
<p><?= $psu[PsuTable::TYPE_MODULAR->value] === "TRUE" ? "Yes" : "No" ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>80+ Rating</label>
|
<label>80+ Rating</label>
|
||||||
<p><?= $psu[PsuModel::EIGHTYPLUS_RATING->value] ?? "None" ?></p>
|
<p><?= $psu[PsuTable::EIGHTYPLUS_RATING->value] ?? "None" ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Aquired</label>
|
<label>Aquired</label>
|
||||||
<p><?= date(API::DATE_FORMAT, $psu[PsuModel::DATE_AQUIRED->value]) ?></p>
|
<p><?= date(API::DATE_FORMAT, $psu[PsuTable::DATE_AQUIRED->value]) ?></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php if ($psu[PsuModel::IS_RETIRED->value]): ?>
|
<?php if ($psu[PsuTable::IS_RETIRED->value]): ?>
|
||||||
<div>
|
<div>
|
||||||
<label>Retired</label>
|
<label>Retired</label>
|
||||||
<p>Yes</p>
|
<p>Yes</p>
|
||||||
|
@ -354,54 +354,54 @@
|
||||||
|
|
||||||
<?php // Get case details from endpoint by id ?>
|
<?php // Get case details from endpoint by id ?>
|
||||||
<?php $dram = $api->call(Endpoints::BATTLESTATION_DRAM->value)->params([
|
<?php $dram = $api->call(Endpoints::BATTLESTATION_DRAM->value)->params([
|
||||||
DramModel::ID->value => $mb_dram[MbDramModel::REF_DRAM_ID->value]
|
DramTable::ID->value => $mb_dram[MbDramTable::REF_DRAM_ID->value]
|
||||||
])->get()->json()[0]; ?>
|
])->get()->json()[0]; ?>
|
||||||
|
|
||||||
<div data-target="dram" class="spec">
|
<div data-target="dram" class="spec">
|
||||||
<p>DRAM - <?= $dram[DramModel::TECHNOLOGY->value] ?></p>
|
<p>DRAM - <?= $dram[DramTable::TECHNOLOGY->value] ?></p>
|
||||||
<h3><?= $dram[DramModel::VENDOR_NAME->value] ?>
|
<h3><?= $dram[DramTable::VENDOR_NAME->value] ?>
|
||||||
<span><?= $dram[DramModel::CAPACITY->value] / GIGA ?>GB</span>
|
<span><?= $dram[DramTable::CAPACITY->value] / GIGA ?>GB</span>
|
||||||
<span><?= $dram[DramModel::SPEED->value] / MEGA ?>MHz</span>
|
<span><?= $dram[DramTable::SPEED->value] / MEGA ?>MHz</span>
|
||||||
</h3>
|
</h3>
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<label>Capacity</label>
|
<label>Capacity</label>
|
||||||
<p><?= $dram[DramModel::CAPACITY->value] / GIGA ?>GB</p>
|
<p><?= $dram[DramTable::CAPACITY->value] / GIGA ?>GB</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Speed</label>
|
<label>Speed</label>
|
||||||
<p><?= $dram[DramModel::SPEED->value] / MEGA ?>MHz</p>
|
<p><?= $dram[DramTable::SPEED->value] / MEGA ?>MHz</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Brand name</label>
|
<label>Brand name</label>
|
||||||
<p><?= $dram[DramModel::VENDOR_NAME->value] ?></p>
|
<p><?= $dram[DramTable::VENDOR_NAME->value] ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Brand model</label>
|
<label>Brand model</label>
|
||||||
<p><?= $dram[DramModel::VENDOR_MODEL->value] ?></p>
|
<p><?= $dram[DramTable::VENDOR_MODEL->value] ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Formfactor</label>
|
<label>Formfactor</label>
|
||||||
<p><?= $dram[DramModel::FORMFACTOR->value] ?></p>
|
<p><?= $dram[DramTable::FORMFACTOR->value] ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Technology</label>
|
<label>Technology</label>
|
||||||
<p><?= $dram[DramModel::TECHNOLOGY->value] ?></p>
|
<p><?= $dram[DramTable::TECHNOLOGY->value] ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Is ECC?</label>
|
<label>Is ECC?</label>
|
||||||
<p><?= $dram[DramModel::ECC->value] === "TRUE" ? "Yes" : "No" ?></p>
|
<p><?= $dram[DramTable::ECC->value] === "TRUE" ? "Yes" : "No" ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Is buffered?</label>
|
<label>Is buffered?</label>
|
||||||
<p><?= $dram[DramModel::BUFFERED->value] === "TRUE" ? "Yes" : "No" ?></p>
|
<p><?= $dram[DramTable::BUFFERED->value] === "TRUE" ? "Yes" : "No" ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Aquired</label>
|
<label>Aquired</label>
|
||||||
<p><?= date(API::DATE_FORMAT, $dram[DramModel::DATE_AQUIRED->value]) ?></p>
|
<p><?= date(API::DATE_FORMAT, $dram[DramTable::DATE_AQUIRED->value]) ?></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php if ($dram[DramModel::IS_RETIRED->value]): ?>
|
<?php if ($dram[DramTable::IS_RETIRED->value]): ?>
|
||||||
<div>
|
<div>
|
||||||
<label>Retired</label>
|
<label>Retired</label>
|
||||||
<p>Yes</p>
|
<p>Yes</p>
|
||||||
|
@ -411,11 +411,11 @@
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<label>In motherboard slot number</label>
|
<label>In motherboard slot number</label>
|
||||||
<p><?= $mb_dram[MbDramModel::SOCKET->value] ?></p>
|
<p><?= $mb_dram[MbDramTable::SOCKET->value] ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Motherboard slot type</label>
|
<label>Motherboard slot type</label>
|
||||||
<p><?= $mb_dram[MbDramModel::SOCKET_TYPE->value] ?></p>
|
<p><?= $mb_dram[MbDramTable::SOCKET_TYPE->value] ?></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -433,46 +433,46 @@
|
||||||
|
|
||||||
<?php // Get case details from endpoint by id ?>
|
<?php // Get case details from endpoint by id ?>
|
||||||
<?php $storage = $api->call(Endpoints::BATTLESTATION_STORAGE->value)->params([
|
<?php $storage = $api->call(Endpoints::BATTLESTATION_STORAGE->value)->params([
|
||||||
StorageModel::ID->value => $mb_storage[MbStorageModel::REF_STORAGE_ID->value]
|
StorageTable::ID->value => $mb_storage[MbStorageTable::REF_STORAGE_ID->value]
|
||||||
])->get()->json()[0]; ?>
|
])->get()->json()[0]; ?>
|
||||||
|
|
||||||
<div data-target="drive" class="spec">
|
<div data-target="drive" class="spec">
|
||||||
<p><?= $storage[StorageModel::DISK_FORMFACTOR->value] ?> <?= $storage[StorageModel::DISK_TYPE->value] ?></p>
|
<p><?= $storage[StorageTable::DISK_FORMFACTOR->value] ?> <?= $storage[StorageTable::DISK_TYPE->value] ?></p>
|
||||||
<h3>
|
<h3>
|
||||||
<?= $storage[StorageModel::VENDOR_NAME->value] ?>
|
<?= $storage[StorageTable::VENDOR_NAME->value] ?>
|
||||||
<span><?= floor($storage[StorageModel::DISK_SIZE->value] / GIGA) ?>GB</span>
|
<span><?= floor($storage[StorageTable::DISK_SIZE->value] / GIGA) ?>GB</span>
|
||||||
</h3>
|
</h3>
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<label>Type</label>
|
<label>Type</label>
|
||||||
<p><?= $storage[StorageModel::DISK_TYPE->value] ?></p>
|
<p><?= $storage[StorageTable::DISK_TYPE->value] ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Capacity</label>
|
<label>Capacity</label>
|
||||||
<p><?= floor($storage[StorageModel::DISK_SIZE->value] / GIGA) ?>GB</p>
|
<p><?= floor($storage[StorageTable::DISK_SIZE->value] / GIGA) ?>GB</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Interface</label>
|
<label>Interface</label>
|
||||||
<p><?= $storage[StorageModel::DISK_INTERFACE->value] ?></p>
|
<p><?= $storage[StorageTable::DISK_INTERFACE->value] ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Formfactor</label>
|
<label>Formfactor</label>
|
||||||
<p><?= $storage[StorageModel::DISK_FORMFACTOR->value] ?></p>
|
<p><?= $storage[StorageTable::DISK_FORMFACTOR->value] ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Brand name</label>
|
<label>Brand name</label>
|
||||||
<p><?= $storage[StorageModel::VENDOR_NAME->value] ?></p>
|
<p><?= $storage[StorageTable::VENDOR_NAME->value] ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Brand model</label>
|
<label>Brand model</label>
|
||||||
<p><?= $storage[StorageModel::VENDOR_MODEL->value] ?></p>
|
<p><?= $storage[StorageTable::VENDOR_MODEL->value] ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Aquired</label>
|
<label>Aquired</label>
|
||||||
<p><?= date(API::DATE_FORMAT, $storage[StorageModel::DATE_AQUIRED->value]) ?></p>
|
<p><?= date(API::DATE_FORMAT, $storage[StorageTable::DATE_AQUIRED->value]) ?></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php if ($storage[StorageModel::IS_RETIRED->value]): ?>
|
<?php if ($storage[StorageTable::IS_RETIRED->value]): ?>
|
||||||
<div>
|
<div>
|
||||||
<label>Retired</label>
|
<label>Retired</label>
|
||||||
<p>Yes</p>
|
<p>Yes</p>
|
||||||
|
@ -482,7 +482,7 @@
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<label>Attatched via interface</label>
|
<label>Attatched via interface</label>
|
||||||
<p><?= $mb_storage[MbStorageModel::INTERFACE->value] ?></p>
|
<p><?= $mb_storage[MbStorageTable::INTERFACE->value] ?></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
:root {
|
:root {
|
||||||
--primer-color-accent: 148, 255, 21;
|
--primer-color-accent: 148, 255, 21;
|
||||||
--color-accent: rgb(var(--primer-color-accent));
|
--color-accent: rgb(var(--primer-color-accent));
|
||||||
|
--hue-accent: 390deg;
|
||||||
|
|
||||||
--primer-color-go: 0, 173, 216;
|
--primer-color-go: 0, 173, 216;
|
||||||
--primer-color-php: 79, 93, 149;
|
--primer-color-php: 79, 93, 149;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
:root {
|
:root {
|
||||||
--primer-color-accent: 255, 195, 255;
|
--primer-color-accent: 255, 195, 255;
|
||||||
--color-accent: rgb(var(--primer-color-accent));
|
--color-accent: rgb(var(--primer-color-accent));
|
||||||
|
--hue-accent: 200deg;
|
||||||
}
|
}
|
||||||
|
|
||||||
vv-shell {
|
vv-shell {
|
||||||
|
@ -28,10 +29,6 @@ section.center {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
section.fade {
|
|
||||||
opacity: .3;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ## Social */
|
/* ## Social */
|
||||||
|
|
||||||
section.social {
|
section.social {
|
||||||
|
@ -81,11 +78,12 @@ section.pgp {
|
||||||
max-width: 800px;
|
max-width: 800px;
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
border-radius: 12px;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: var(--padding);
|
gap: var(--padding);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background-color: rgba(var(--primer-color-accent), .15);
|
background-color: rgba(var(--primer-color-accent), .15);
|
||||||
padding: calc(var(--padding) * 1.5);
|
padding: var(--padding);
|
||||||
transform: rotate(-1.5deg);
|
transform: rotate(-1.5deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,10 +106,6 @@ section.pgp .buttons {
|
||||||
gap: var(--padding);
|
gap: var(--padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
section.pgp .buttons .download svg.chevron {
|
|
||||||
transform: unset;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ## Contact form */
|
/* ## Contact form */
|
||||||
|
|
||||||
section.form :is(input, textarea) {
|
section.form :is(input, textarea) {
|
||||||
|
@ -200,6 +194,10 @@ section.form-message.sent + section.form {
|
||||||
/* # Size queries */
|
/* # Size queries */
|
||||||
|
|
||||||
@media (min-width: 460px) {
|
@media (min-width: 460px) {
|
||||||
|
section.pgp {
|
||||||
|
padding: calc(var(--padding) * 1.5);
|
||||||
|
}
|
||||||
|
|
||||||
section.pgp .buttons {
|
section.pgp .buttons {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
|
@ -1,85 +1,84 @@
|
||||||
/* # Overrides */
|
vv-shell[vv-page="/search"] {
|
||||||
|
|
||||||
[vv-page="/search"]:not(body) {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: var(--padding);
|
gap: calc(var(--padding) / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* # Sections */
|
/* # Search */
|
||||||
|
|
||||||
/* ## Search */
|
|
||||||
|
|
||||||
section.search {
|
section.search {
|
||||||
width: 100%;
|
|
||||||
display: none;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
gap: var(--padding);
|
|
||||||
background-color: rgba(255, 255, 255, .05);
|
|
||||||
padding: calc(var(--padding) * 1.5);
|
|
||||||
margin-bottom: calc(var(--padding) * 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
vv-shell[vv-page="/search"] > section.search {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
|
gap: var(--padding);
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: var(--padding);
|
||||||
|
background-color: rgba(255, 255, 255, .1);
|
||||||
}
|
}
|
||||||
|
|
||||||
section.search form {
|
section.search form {
|
||||||
display: contents;
|
display: contents;
|
||||||
}
|
}
|
||||||
|
|
||||||
section.search search {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
section.search input {
|
section.search input {
|
||||||
width: 100%;
|
flex: 1 1 auto;
|
||||||
border: none;
|
|
||||||
color: black;
|
|
||||||
outline: none;
|
|
||||||
padding: var(--padding);
|
|
||||||
background-color: var(--color-accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
section.search button[type="submit"] {
|
|
||||||
width: 100%;
|
|
||||||
max-width: 350px;
|
|
||||||
}
|
|
||||||
|
|
||||||
section.search > svg {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* # Search results */
|
|
||||||
|
|
||||||
section.results .result {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: calc(var(--padding) / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ## Titles */
|
|
||||||
|
|
||||||
section.title a h2 {
|
|
||||||
color: var(--color-accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
section.title a h2::before {
|
|
||||||
content: "// ";
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ## Work */
|
|
||||||
|
|
||||||
section.results.work {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
gap: calc(var(--padding) / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
section.results.work .result {
|
|
||||||
padding: var(--padding);
|
|
||||||
background-color: rgba(255, 255, 255, .03);
|
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
|
padding: 0 var(--padding);
|
||||||
|
border: solid 2px rgba(255, 255, 255, .1);
|
||||||
|
background-color: rgba(255, 255, 255, .1);
|
||||||
|
}
|
||||||
|
|
||||||
|
section.search input:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.search select {
|
||||||
|
padding: 5px;
|
||||||
|
border: none;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.search select :is(option, optgroup) {
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* # Center */
|
||||||
|
|
||||||
|
section.center {
|
||||||
|
display: flex;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
fill: var(--color-accent);
|
||||||
|
gap: calc(var(--padding) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
section.center svg {
|
||||||
|
width: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* # Result */
|
||||||
|
|
||||||
|
section.result {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.result button {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
text-align: left;
|
||||||
|
padding: var(--padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* # Stats */
|
||||||
|
|
||||||
|
section.stats {
|
||||||
|
min-height: calc(var(--padding) * 2);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: calc(var(--padding) / 2);
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
vv-shell[vv-page="/search"] section.stats button {
|
||||||
|
display: none;
|
||||||
}
|
}
|
|
@ -3,9 +3,10 @@
|
||||||
:root {
|
:root {
|
||||||
--primer-color-accent: 3, 255, 219;
|
--primer-color-accent: 3, 255, 219;
|
||||||
--color-accent: rgb(var(--primer-color-accent));
|
--color-accent: rgb(var(--primer-color-accent));
|
||||||
|
--hue-accent: 90deg;
|
||||||
|
|
||||||
--color-reflect: 220, 26, 0;
|
--primer-color-reflect: 220, 26, 0;
|
||||||
--color-vegvisir: 0, 128, 255;
|
--primer-color-vegvisir: 0, 128, 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
vv-shell {
|
vv-shell {
|
||||||
|
@ -22,7 +23,7 @@ vv-shell {
|
||||||
/* ## Hero */
|
/* ## Hero */
|
||||||
|
|
||||||
section.hero {
|
section.hero {
|
||||||
--color-accent: rgba(255, 255, 255);
|
--color-accent: rgb(255, 255, 255);
|
||||||
|
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: var(--padding);
|
gap: var(--padding);
|
||||||
|
@ -65,19 +66,21 @@ section.hero .actions {
|
||||||
/* ### Vegivisr */
|
/* ### Vegivisr */
|
||||||
|
|
||||||
section.hero .item.vegvisir {
|
section.hero .item.vegvisir {
|
||||||
--color-accent: var(--color-vegvisir);
|
--primer-color-accent: var(--primer-color-vegvisir);
|
||||||
|
--color-accent: rgb(var(--primer-color-vegvisir));
|
||||||
|
|
||||||
color: rgb(var(--color-vegvisir));
|
color: var(--color-vegvisir);
|
||||||
background-color: rgba(var(--color-vegvisir), .1);
|
background-color: rgba(var(--primer-color-vegvisir), .1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ### Reflect */
|
/* ### Reflect */
|
||||||
|
|
||||||
section.hero .item.reflect {
|
section.hero .item.reflect {
|
||||||
--color-accent: var(--color-reflect);
|
--primer-color-accent: var(--primer-color-reflect);
|
||||||
|
--color-accent: rgb(var(--primer-color-reflect));
|
||||||
|
|
||||||
color: rgb(var(--color-reflect));
|
color: var(--color-reflect);
|
||||||
background-color: rgba(var(--color-reflect), .2);
|
background-color: rgba(var(--primer-color-reflect), .2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ## Heading */
|
/* ## Heading */
|
||||||
|
@ -90,7 +93,6 @@ section.heading {
|
||||||
}
|
}
|
||||||
|
|
||||||
section.heading svg {
|
section.heading svg {
|
||||||
fill: white;
|
|
||||||
height: 2em;
|
height: 2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
:root {
|
:root {
|
||||||
--primer-color-accent: 3, 255, 219;
|
--primer-color-accent: 3, 255, 219;
|
||||||
--color-accent: rgb(var(--primer-color-accent));
|
--color-accent: rgb(var(--primer-color-accent));
|
||||||
|
--hue-accent: 90deg;
|
||||||
}
|
}
|
||||||
|
|
||||||
vv-shell {
|
vv-shell {
|
||||||
|
@ -27,7 +28,7 @@ section.git {
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
section.git svg {
|
section.git > svg {
|
||||||
fill: white;
|
fill: white;
|
||||||
width: 60px;
|
width: 60px;
|
||||||
}
|
}
|
||||||
|
@ -120,7 +121,10 @@ section.timeline .items .item img {
|
||||||
}
|
}
|
||||||
|
|
||||||
section.timeline .items .item .actions {
|
section.timeline .items .item .actions {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
margin-top: 7px;
|
margin-top: 7px;
|
||||||
|
gap: var(--padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* # Size queries */
|
/* # Size queries */
|
||||||
|
@ -165,6 +169,10 @@ section.timeline .items .item .actions {
|
||||||
border-top-color: rgba(var(--primer-color-accent), .2);
|
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 {
|
section.timeline .year:first-of-type .month:first-of-type .day:first-of-type .items .item:first-of-type {
|
||||||
margin-top: var(--padding);
|
margin-top: var(--padding);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
:root {
|
:root {
|
||||||
--primer-color-accent: 3, 255, 219;
|
--primer-color-accent: 3, 255, 219;
|
||||||
--color-accent: rgb(var(--primer-color-accent));
|
--color-accent: rgb(var(--primer-color-accent));
|
||||||
|
--hue-accent: 90deg;
|
||||||
}
|
}
|
||||||
|
|
||||||
vv-shell {
|
vv-shell {
|
||||||
|
|
|
@ -11,7 +11,8 @@
|
||||||
/* # Cornerstones */
|
/* # Cornerstones */
|
||||||
|
|
||||||
* {
|
* {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
fill: inherit;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
font-family: "Roboto Mono", sans-serif;
|
font-family: "Roboto Mono", sans-serif;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
|
@ -88,6 +89,32 @@ h3 {
|
||||||
font-size: 25px;
|
font-size: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ## Page transition */
|
||||||
|
|
||||||
|
[vv-loading] * {
|
||||||
|
transition: 200ms opacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
[vv-loading="true"] * {
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
[vv-loading="true"]::after {
|
||||||
|
content: "";
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
width: 45px;
|
||||||
|
height: 49px;
|
||||||
|
background-size: contain;
|
||||||
|
image-rendering: pixelated;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
background-image: url("/assets/media/spinner.gif");
|
||||||
|
-webkit-filter: hue-rotate(var(--hue-accent));
|
||||||
|
filter: hue-rotate(var(--hue-accent));
|
||||||
|
}
|
||||||
|
|
||||||
/* ## Buttons */
|
/* ## Buttons */
|
||||||
|
|
||||||
button {
|
button {
|
||||||
|
@ -118,6 +145,7 @@ button.inline:not(.solid) {
|
||||||
}
|
}
|
||||||
|
|
||||||
button.inline svg {
|
button.inline svg {
|
||||||
|
flex: none;
|
||||||
height: 1em;
|
height: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,6 +310,9 @@ vv-shell {
|
||||||
search-results {
|
search-results {
|
||||||
transition: 500ms opacity, 300ms transform;
|
transition: 500ms opacity, 300ms transform;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: var(--padding);
|
||||||
top: var(--running-size);
|
top: var(--running-size);
|
||||||
right: 0;
|
right: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -296,18 +327,16 @@ search-results {
|
||||||
z-index: 50;
|
z-index: 50;
|
||||||
}
|
}
|
||||||
|
|
||||||
search-results:not([vv-page]) {
|
|
||||||
display: grid;
|
|
||||||
align-items: center;
|
|
||||||
justify-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
header.searchboxActive ~ search-results {
|
header.searchboxActive ~ search-results {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
transform: scale(1);
|
transform: scale(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
search-results section.search {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
/* ### "Start typing" prompt */
|
/* ### "Start typing" prompt */
|
||||||
|
|
||||||
search-results .info {
|
search-results .info {
|
||||||
|
@ -315,11 +344,11 @@ search-results .info {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
gap: 3svh;
|
gap: var(--padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
search-results .info :is(svg, img) {
|
search-results .info :is(svg, img) {
|
||||||
width: 128px;
|
width: 60px;
|
||||||
fill: var(--color-accent);
|
fill: var(--color-accent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
../../../../../node_modules/elevent/src/Elevent.mjs
|
|
|
@ -2,6 +2,9 @@ import { Elevent } from "/assets/js/modules/npm/Elevent.mjs";
|
||||||
|
|
||||||
const CLASSNAME_SEARCHBOX_ACTIVE = "searchboxActive";
|
const CLASSNAME_SEARCHBOX_ACTIVE = "searchboxActive";
|
||||||
|
|
||||||
|
// Set global Vegvisir naviation delay for page transition effect
|
||||||
|
globalThis.vegvisir.globalNavigationDelayMs = 100;
|
||||||
|
|
||||||
// Handle search box open/close buttons
|
// Handle search box open/close buttons
|
||||||
{
|
{
|
||||||
// Open search box
|
// Open search box
|
||||||
|
@ -44,12 +47,10 @@ const CLASSNAME_SEARCHBOX_ACTIVE = "searchboxActive";
|
||||||
clearTimeout(event.target._throttle);
|
clearTimeout(event.target._throttle);
|
||||||
event.target._throttle = setTimeout(() => {
|
event.target._throttle = setTimeout(() => {
|
||||||
// Navigate search-results element on user input
|
// Navigate search-results element on user input
|
||||||
new vv.Navigation(`/search?q=${event.target.value}`).navigate(searchResultsElement);
|
new vv.Navigation(`/search?query=${event.target.value}`).navigate(searchResultsElement);
|
||||||
}, 100);
|
}, 100);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scroll page to top on navigation
|
// Scroll page to top on navigation
|
||||||
{
|
document.addEventListener(vegvisir.Navigation.EVENTS.FINISHED, () => window.scrollTo({ top: 0 }));
|
||||||
document.addEventListener(vegvisir.Navigation.EVENTS.FINISHED, () => window.scrollTo({top: 0}));
|
|
||||||
}
|
|
BIN
public/assets/media/spinner.gif
Normal file
BIN
public/assets/media/spinner.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
|
@ -2,58 +2,43 @@
|
||||||
|
|
||||||
use Vegvisir\Path;
|
use Vegvisir\Path;
|
||||||
|
|
||||||
use VLW\Client\API;
|
use VLW\API\{Client, Endpoints};
|
||||||
use VLW\API\Endpoints;
|
use VLW\Database\Tables\Messages\MessagesTable;
|
||||||
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Messages\MessagesModel;
|
require_once VV::root("src/API/API.php");
|
||||||
|
require_once VV::root("src/API/Endpoints.php");
|
||||||
require_once VV::root("src/client/API.php");
|
require_once VV::root("src/Database/Tables/Messages/Messages.php");
|
||||||
require_once VV::root("api/src/Endpoints.php");
|
|
||||||
|
|
||||||
require_once VV::root("api/src/databases/models/Messages/Messages.php");
|
|
||||||
|
|
||||||
// Connect to VLW API
|
|
||||||
$api = new API();
|
|
||||||
|
|
||||||
class Date extends DateTimeImmutable {
|
|
||||||
private const AVAILABLE_TO_HOUR = 16;
|
|
||||||
private const AVAILABLE_FROM_HOUR = 10;
|
|
||||||
|
|
||||||
private const REPLY_TIME_HOURS_AVAILABLE = 2;
|
|
||||||
|
|
||||||
|
$date = new class extends DateTimeImmutable {
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
// Set DateTime for configured timezone
|
// Set DateTime for configured timezone
|
||||||
parent::__construct("now", new DateTimeZone($_ENV["time"]["date_time_zone"]));
|
parent::__construct("now", new DateTimeZone($_ENV["client_time_available"]["time_zone"]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return current hour in 24-hour format
|
// Return current hour in 24-hour format
|
||||||
private function get_hour(): int {
|
private function hour(): int {
|
||||||
return (int) $this->format("G");
|
return (int) $this->format("G");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if current time is between available from and to hours
|
// Returns true if current time is between available from and to hours
|
||||||
public function is_available(): bool {
|
public function is_available(): bool {
|
||||||
return $this->get_hour() >= self::AVAILABLE_FROM_HOUR && $this->get_hour() < self::AVAILABLE_TO_HOUR;
|
return $this->hour() >= $_ENV["client_time_available"]["available_from_hour"] && $this->hour() < $_ENV["client_time_available"]["available_to_hour"];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function get_estimated_reply_hours(): int {
|
public function get_estimated_reply_hours(): int {
|
||||||
// I'm available! Return the estimated reply time for that
|
// I'm available! Return the estimated reply time for that
|
||||||
if ($this->is_available()) {
|
if ($this->is_available()) {
|
||||||
return self::REPLY_TIME_HOURS_AVAILABLE;
|
return $_ENV["client_time_available"]["reply_average_hours"];
|
||||||
}
|
}
|
||||||
|
|
||||||
$hour = $this->get_hour();
|
return $this->hour() < $_ENV["client_time_available"]["available_from_hour"]
|
||||||
|
|
||||||
return $hour < self::AVAILABLE_FROM_HOUR
|
|
||||||
// Return hours past midnight until I become available (clamped to estimated reply hours)
|
// Return hours past midnight until I become available (clamped to estimated reply hours)
|
||||||
? max(self::AVAILABLE_FROM_HOUR - $hour, self::REPLY_TIME_HOURS_AVAILABLE)
|
? max($_ENV["client_time_available"]["available_from_hour"] - $this->hour(), $_ENV["client_time_available"]["reply_average_hours"])
|
||||||
// Return hours before midnight until I become available (clamped to estimated reply hours)
|
// Return hours before midnight until I become available (clamped to estimated reply hours)
|
||||||
: max(self::AVAILABLE_FROM_HOUR + (24 - $hour), self::REPLY_TIME_HOURS_AVAILABLE);
|
: max($_ENV["client_time_available"]["available_from_hour"] + (24 - $this->hour()), $_ENV["client_time_available"]["reply_average_hours"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$date = new Date();
|
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<style><?= VV::css("public/assets/css/pages/contact") ?></style>
|
<style><?= VV::css("public/assets/css/pages/contact") ?></style>
|
||||||
<section>
|
<section>
|
||||||
|
@ -103,9 +88,9 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Send message via API
|
// Send message via API
|
||||||
$send = $api->call(Endpoints::MESSAGES->value)->post([
|
$send = (new Client())->call(Endpoints::MESSAGES->value)->post([
|
||||||
MessagesModel::EMAIL->value => $_POST[MessagesModel::EMAIL->value],
|
MessagesTable::EMAIL->value => $_POST[MessagesTable::EMAIL->value],
|
||||||
MessagesModel::MESSAGE->value => $_POST[MessagesModel::MESSAGE->value]
|
MessagesTable::MESSAGE->value => $_POST[MessagesTable::MESSAGE->value]
|
||||||
]);
|
]);
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
@ -128,11 +113,11 @@
|
||||||
<form method="POST">
|
<form method="POST">
|
||||||
<input-group>
|
<input-group>
|
||||||
<label>your email (optional)</label>
|
<label>your email (optional)</label>
|
||||||
<input type="email" name="<?= MessagesModel::EMAIL->value ?>" placeholder="nissehult@example.com" autocomplete="off"></input>
|
<input type="email" name="<?= MessagesTable::EMAIL->value ?>" placeholder="nissehult@example.com" autocomplete="off"></input>
|
||||||
</input-group>
|
</input-group>
|
||||||
<input-group>
|
<input-group>
|
||||||
<label title="this field is required">your message (required)</label>
|
<label title="this field is required">your message (required)</label>
|
||||||
<textarea name="<?= MessagesModel::MESSAGE->value ?>" required placeholder="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed molestie dignissim mauris vel dignissim. Sed et aliquet odio, id egestas libero. Vestibulum ut dui a turpis aliquam hendrerit id et dui. Morbi eu tristique quam, sit amet dictum felis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin ac nibh a ex accumsan ullamcorper non quis eros. Nam at suscipit lacus. Nullam placerat semper sapien, vitae aliquet nisl elementum a. Duis viverra quam eros, eu vestibulum quam egestas sit amet. Duis lobortis varius malesuada. Mauris in fringilla mi. "></textarea>
|
<textarea name="<?= MessagesTable::MESSAGE->value ?>" required placeholder="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed molestie dignissim mauris vel dignissim. Sed et aliquet odio, id egestas libero. Vestibulum ut dui a turpis aliquam hendrerit id et dui. Morbi eu tristique quam, sit amet dictum felis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin ac nibh a ex accumsan ullamcorper non quis eros. Nam at suscipit lacus. Nullam placerat semper sapien, vitae aliquet nisl elementum a. Duis viverra quam eros, eu vestibulum quam egestas sit amet. Duis lobortis varius malesuada. Mauris in fringilla mi. "></textarea>
|
||||||
</input-group>
|
</input-group>
|
||||||
<button class="inline solid">
|
<button class="inline solid">
|
||||||
<?= VV::embed("public/assets/media/icons/email.svg") ?>
|
<?= VV::embed("public/assets/media/icons/email.svg") ?>
|
||||||
|
|
2
public/robots.txt
Normal file
2
public/robots.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
User-agent: *
|
||||||
|
Disallow:
|
|
@ -1,95 +1,111 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Vegvisir\Path;
|
use VLW\Database\Models\Search\Search;
|
||||||
|
use const VLW\{ICONS_DIR, DEFAULT_BUTTON_ICON};
|
||||||
|
use VLW\Database\Tables\Search\{SearchTable, SearchCategoryEnum};
|
||||||
|
|
||||||
use VLW\Client\API;
|
require_once VV::root("src/Consts.php");
|
||||||
use VLW\API\Endpoints;
|
require_once VV::root("src/Database/Tables/Search/Search.php");
|
||||||
|
require_once VV::root("src/Database/Models/Search/Search.php");
|
||||||
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Work\{
|
$search = new class extends Search {
|
||||||
WorkModel,
|
public function __construct() {}
|
||||||
WorkActionsModel
|
|
||||||
};
|
|
||||||
|
|
||||||
require_once VV::root("src/client/API.php");
|
public static function get_query(): ?string {
|
||||||
require_once VV::root("api/src/Endpoints.php");
|
return $_GET[SearchTable::QUERY->value] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
require_once VV::root("api/src/databases/models/Work/Work.php");
|
public static function get_category(): ?SearchCategoryEnum {
|
||||||
require_once VV::root("api/src/databases/models/Work/WorkActions.php");
|
return SearchCategoryEnum::tryFromName($_GET[SearchTable::CATEGORY->value] ?? "");
|
||||||
|
}
|
||||||
|
|
||||||
// Search endpoint query paramter
|
public function search(): array {
|
||||||
const SEARCH_PARAM = "q";
|
return parent::all([SearchTable::QUERY->value => self::get_query()]);
|
||||||
|
}
|
||||||
// Connect to VLW API
|
}
|
||||||
$api = new API();
|
|
||||||
|
|
||||||
// Get search results from endpoint
|
|
||||||
$response = $api->call(Endpoints::SEARCH->value)->params([SEARCH_PARAM => $_GET[SEARCH_PARAM]])->get();
|
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<style><?= VV::css("public/assets/css/pages/search") ?></style>
|
<style><?= VV::css("public/assets/css/pages/search") ?></style>
|
||||||
<section class="search">
|
<section class="search">
|
||||||
<form method="GET">
|
<form>
|
||||||
<search>
|
<input name="<?= SearchTable::QUERY->value ?>" type="search" placeholder="search vlw.se..." value="<?= $search::get_query() ?>">
|
||||||
<input name="<? SEARCH_PARAM ?>" type="text" placeholder="search vlw.se..." value="<?= $_GET[SEARCH_PARAM] ?>"></input>
|
<select name="<?= SearchTable::CATEGORY->value ?>">
|
||||||
</search>
|
<option value="null">All</option>
|
||||||
<button type="submit" class="inline solid">Search</button>
|
<optgroup label="Categories">
|
||||||
|
|
||||||
|
<?php foreach (SearchCategoryEnum::names() as $category): ?>
|
||||||
|
<?php $category = SearchCategoryEnum::fromName($category); ?>
|
||||||
|
<option value="<?= $category->name ?>" <?= $search::get_category() === $category ? "selected" : "" ?>><?= ucfirst(strtolower($category->name)) ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
|
||||||
|
</optgroup>
|
||||||
|
</select>
|
||||||
|
<button type="submit" class="inline solid"><?= VV::embed(ICONS_DIR . "search.svg") ?></button>
|
||||||
</form>
|
</form>
|
||||||
<?= VV::embed("public/assets/media/line.svg") ?>
|
|
||||||
<button class="inline">advanced search options</button>
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<?php if ($response->ok): ?>
|
<?php if (array_key_exists(SearchTable::QUERY->value, $_GET)): ?>
|
||||||
<?php // Get response body ?>
|
|
||||||
<?php $results = $response->json(); ?>
|
<?php if ($search->search()): ?>
|
||||||
|
<section class="stats">
|
||||||
<?php // Search contains results from the work endpoint ?>
|
<p><?= count($search->search()) ?> result(s)</p>
|
||||||
<?php if ($results[Endpoints::WORK->value]): ?>
|
<a href="/search?query=<?= $search::get_query() ?>"><button class="inline solid">
|
||||||
<section class="title work">
|
<?= VV::embed(ICONS_DIR . "search.svg") ?>
|
||||||
<a href="<? Endpoints::WORK->value ?>"><h2>Work</h2></a>
|
<p>Advanced search</p>
|
||||||
<p><?= count($results[Endpoints::WORK->value]) ?> search result(s) from my public work</p>
|
<?= VV::embed(DEFAULT_BUTTON_ICON) ?>
|
||||||
|
</button></a>
|
||||||
</section>
|
</section>
|
||||||
<section class="results work">
|
|
||||||
|
|
||||||
<?php // List all work category search results ?>
|
<?php foreach ($search->search() as $result): ?>
|
||||||
<?php foreach ($results[Endpoints::WORK->value] as $result): ?>
|
<section class="result" data-id="<?= $result->id ?>">
|
||||||
<div class="result">
|
<a href="<?= $result->href() ?>"><button class="inline">
|
||||||
<h3><?= $result[WorkModel::TITLE->value] ?></h3>
|
<div>
|
||||||
<p><?= $result[WorkModel::SUMMARY->value] ?></p>
|
<h2><?= $result->title() ?></h2>
|
||||||
<p><?= date(API::DATE_FORMAT, $result[WorkModel::DATE_CREATED->value]) ?></p>
|
<p><?= $result->summary() ?></p>
|
||||||
|
</div>
|
||||||
|
<?= VV::embed(DEFAULT_BUTTON_ICON) ?>
|
||||||
|
</button></a>
|
||||||
|
</section>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
|
||||||
<?php // Get action buttons for work entity by id ?>
|
|
||||||
<?php $actions = $api->call(Endpoints::WORK_ACTIONS->value)->params([WorkActionsModel::REF_WORK_ID->value => $result[WorkModel::ID->value]])->get(); ?>
|
|
||||||
|
|
||||||
<?php // List each action button for work entity if exists ?>
|
|
||||||
<?php if ($actions->ok): ?>
|
|
||||||
<div class="actions">
|
|
||||||
<?php foreach ($actions->json() as $action): ?>
|
|
||||||
|
|
||||||
<?php // Bind VV Interactions if link is same origin, else open in new tab ?>
|
|
||||||
<a href="<?= $action[WorkActionsModel::HREF->value] ?>" target="_blank"><button class="inline <?= $action[WorkActionsModel::CLASS_LIST->value] ?>"><?= $action[WorkActionsModel::DISPLAY_TEXT->value] ?></button></a>
|
|
||||||
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</div>
|
|
||||||
<?php endif; ?>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</section>
|
|
||||||
<?php endif; ?>
|
|
||||||
<?php else: ?>
|
|
||||||
|
|
||||||
<?php if (!empty($_GET[SEARCH_PARAM])): ?>
|
|
||||||
<section class="info noresults">
|
|
||||||
<img src="/assets/media/travolta.gif" alt="">
|
|
||||||
<p>No results for search term "<?= $_GET[SEARCH_PARAM] ?>"</p>
|
|
||||||
</section>
|
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<section class="info empty">
|
<?php switch (strlen($search::get_query())): default: ?>
|
||||||
<?= VV::embed("public/assets/media/icons/search.svg") ?>
|
<section class="stats">
|
||||||
<p>Start typing to search</p>
|
<p>0 result(s)</p>
|
||||||
</section>
|
<a href="/search?query=<?= $search::get_query() ?>"><button class="inline solid">
|
||||||
|
<?= VV::embed(ICONS_DIR . "search.svg") ?>
|
||||||
|
<p>Advanced search</p>
|
||||||
|
<?= VV::embed(DEFAULT_BUTTON_ICON) ?>
|
||||||
|
</button></a>
|
||||||
|
</section>
|
||||||
|
<section class="center">
|
||||||
|
<img src="/assets/media/travolta.gif">
|
||||||
|
<p>Nothing to see here, that's a bummer..</p>
|
||||||
|
</section>
|
||||||
|
<?php break; ?>
|
||||||
|
|
||||||
|
<?php case 0: ?>
|
||||||
|
<section class="center">
|
||||||
|
<?= VV::embed(ICONS_DIR . "search.svg") ?>
|
||||||
|
<p>Start typing to search</p>
|
||||||
|
</section>
|
||||||
|
<?php break; ?>
|
||||||
|
|
||||||
|
<?php case 1: ?>
|
||||||
|
<section class="center">
|
||||||
|
<?= VV::embed(ICONS_DIR . "search.svg") ?>
|
||||||
|
<p>Almost, type at least two letters to search</p>
|
||||||
|
</section>
|
||||||
|
<?php break; ?>
|
||||||
|
|
||||||
|
<?php endswitch; ?>
|
||||||
|
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php else: ?>
|
||||||
|
<section class="center">
|
||||||
|
<?= VV::embed(ICONS_DIR . "search.svg") ?>
|
||||||
|
<p>Start typing to search</p>
|
||||||
|
</section>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<script><?= VV::js("public/assets/js/pages/search") ?></script>
|
<script><?= VV::js("public/assets/js/pages/search") ?></script>
|
|
@ -1,43 +1,10 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Reflect\Response;
|
use VLW\Database\Models\Work\Work;
|
||||||
|
use const VLW\{TIMELINE_PREVIEW_LIMIT_PARAM, TIMELINE_PREVIEW_LIMIT_COUNT};
|
||||||
|
|
||||||
use VLW\Client\API;
|
require_once VV::root("src/Consts.php");
|
||||||
use VLW\API\Endpoints;
|
require_once VV::root("src/Database/Models/Work/Work.php");
|
||||||
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Work\WorkModel;
|
|
||||||
|
|
||||||
require_once VV::root("src/client/API.php");
|
|
||||||
require_once VV::root("api/src/Endpoints.php");
|
|
||||||
|
|
||||||
require_once VV::root("api/src/databases/models/Work/Work.php");
|
|
||||||
|
|
||||||
// Number of items from the timeline to display on this page
|
|
||||||
const TIMELINE_PREVIEW_LIMIT = 5;
|
|
||||||
|
|
||||||
$work = new class extends API {
|
|
||||||
const ERROR_MSG = "Something went wrong";
|
|
||||||
|
|
||||||
private readonly Response $resp;
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
parent::__construct();
|
|
||||||
|
|
||||||
// Get work items from endpoint
|
|
||||||
$this->resp = $this->call(Endpoints::WORK->value)->params([
|
|
||||||
WorkModel::IS_LISTED->value => true
|
|
||||||
])->get();
|
|
||||||
}
|
|
||||||
|
|
||||||
private function get_item(string $key): array {
|
|
||||||
$idx = array_search($key, array_column($this->resp->json(), WorkModel::ID->value));
|
|
||||||
return $this->resp->json()[$idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function get_summary(string $key): string {
|
|
||||||
return $this->resp->ok ? $this->get_item($key)[WorkModel::SUMMARY->value] : self::ERROR_MSG;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<style><?= VV::css("public/assets/css/pages/work") ?></style>
|
<style><?= VV::css("public/assets/css/pages/work") ?></style>
|
||||||
|
@ -48,7 +15,7 @@
|
||||||
<?= VV::embed("public/assets/media/icons/vegvisir.svg") ?>
|
<?= VV::embed("public/assets/media/icons/vegvisir.svg") ?>
|
||||||
<h1>vegvisir</h1>
|
<h1>vegvisir</h1>
|
||||||
</div>
|
</div>
|
||||||
<p><?= $work->get_summary("vlw/vegvisir") ?></p>
|
<p><?= (new Work("vlw/vegvisir"))->summary() ?></p>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<a href="https://vegvisir.vlw.se"><button class="inline solid">
|
<a href="https://vegvisir.vlw.se"><button class="inline solid">
|
||||||
<p>read more</p>
|
<p>read more</p>
|
||||||
|
@ -63,7 +30,7 @@
|
||||||
<?= VV::embed("public/assets/media/icons/reflect.svg") ?>
|
<?= VV::embed("public/assets/media/icons/reflect.svg") ?>
|
||||||
<h1>reflect</h1>
|
<h1>reflect</h1>
|
||||||
</div>
|
</div>
|
||||||
<p><?= $work->get_summary("vlw/reflect") ?></p>
|
<p><?= (new Work("vlw/reflect"))->summary() ?></p>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<a href="https://reflect.vlw.se"><button class="inline solid">
|
<a href="https://reflect.vlw.se"><button class="inline solid">
|
||||||
<p>read more</p>
|
<p>read more</p>
|
||||||
|
@ -105,7 +72,7 @@
|
||||||
<?= VV::embed("public/assets/media/icons/repo.svg") ?>
|
<?= VV::embed("public/assets/media/icons/repo.svg") ?>
|
||||||
</div>
|
</div>
|
||||||
<h3>vlw/php-mysql</h3>
|
<h3>vlw/php-mysql</h3>
|
||||||
<p><?= $work->get_summary("vlw/php-mysql") ?></p>
|
<p><?= (new Work("vlw/php-mysql"))->summary() ?></p>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<a href="https://codeberg.org/vlw/php-mysql"><button class="inline">
|
<a href="https://codeberg.org/vlw/php-mysql"><button class="inline">
|
||||||
<?= VV::embed("public/assets/media/icons/codeberg.svg") ?>
|
<?= VV::embed("public/assets/media/icons/codeberg.svg") ?>
|
||||||
|
@ -119,7 +86,7 @@
|
||||||
<?= VV::embed("public/assets/media/icons/star.svg") ?>
|
<?= VV::embed("public/assets/media/icons/star.svg") ?>
|
||||||
</div>
|
</div>
|
||||||
<h3>Website for iCellate Medical</h3>
|
<h3>Website for iCellate Medical</h3>
|
||||||
<p><?= $work->get_summary("icellate/website") ?></p>
|
<p><?= (new Work("icellate/website"))->summary() ?></p>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<a href="/work/icellate/website"><button class="inline">
|
<a href="/work/icellate/website"><button class="inline">
|
||||||
<p>read more</p>
|
<p>read more</p>
|
||||||
|
@ -132,7 +99,7 @@
|
||||||
<?= VV::embed("public/assets/media/icons/star.svg") ?>
|
<?= VV::embed("public/assets/media/icons/star.svg") ?>
|
||||||
</div>
|
</div>
|
||||||
<h3>Modernizing GeneMate by iCellate</h3>
|
<h3>Modernizing GeneMate by iCellate</h3>
|
||||||
<p><?= $work->get_summary("icellate/genemate") ?></p>
|
<p><?= (new Work("icellate/genemate"))->summary() ?></p>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<a href="/work/icellate/genemate"><button class="inline">
|
<a href="/work/icellate/genemate"><button class="inline">
|
||||||
<p>read more</p>
|
<p>read more</p>
|
||||||
|
@ -145,7 +112,7 @@
|
||||||
<?= VV::embed("public/assets/media/icons/star.svg") ?>
|
<?= VV::embed("public/assets/media/icons/star.svg") ?>
|
||||||
</div>
|
</div>
|
||||||
<h3>Custom pages for Deltaco AB</h3>
|
<h3>Custom pages for Deltaco AB</h3>
|
||||||
<p><?= $work->get_summary("deltaco/asyncapp") ?></p>
|
<p><?= (new Work("deltaco/asyncapp"))->summary() ?></p>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<a href="/work/deltaco/asyncapp"><button class="inline">
|
<a href="/work/deltaco/asyncapp"><button class="inline">
|
||||||
<p>read more</p>
|
<p>read more</p>
|
||||||
|
@ -157,7 +124,7 @@
|
||||||
<section class="heading">
|
<section class="heading">
|
||||||
<h1>latest projects</h1>
|
<h1>latest projects</h1>
|
||||||
</section>
|
</section>
|
||||||
<?= VV::include("public/work/timeline?limit=" . TIMELINE_PREVIEW_LIMIT) ?>
|
<?= VV::include("public/work/timeline?" . http_build_query([TIMELINE_PREVIEW_LIMIT_PARAM => TIMELINE_PREVIEW_LIMIT_COUNT])) ?>
|
||||||
<section class="heading">
|
<section class="heading">
|
||||||
<a href="/work/timeline"><button class="inline solid">
|
<a href="/work/timeline"><button class="inline solid">
|
||||||
<p>view full timeline</p>
|
<p>view full timeline</p>
|
||||||
|
|
|
@ -1,97 +1,51 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Vegvisir\Path;
|
use VLW\Database\Models\Work\Timeline;
|
||||||
use Reflect\Response;
|
use const VLW\{
|
||||||
|
ICONS_DIR,
|
||||||
use VLW\Client\API;
|
DEFAULT_BUTTON_ICON,
|
||||||
use VLW\API\Endpoints;
|
TIMELINE_PREVIEW_LIMIT_PARAM
|
||||||
|
|
||||||
use VLW\API\Databases\VLWdb\Models\Work\{
|
|
||||||
WorkModel,
|
|
||||||
WorkTagsModel,
|
|
||||||
WorkActionsModel
|
|
||||||
};
|
};
|
||||||
|
|
||||||
require_once VV::root("src/client/API.php");
|
require_once VV::root("src/Consts.php");
|
||||||
require_once VV::root("api/src/Endpoints.php");
|
require_once VV::root("src/Database/Models/Work/Timeline.php");
|
||||||
|
|
||||||
require_once VV::root("api/src/databases/models/Work/Work.php");
|
$timeline = new class extends Timeline {
|
||||||
require_once VV::root("api/src/databases/models/Work/WorkTags.php");
|
public function __construct() {}
|
||||||
require_once VV::root("api/src/databases/models/Work/WorkActions.php");
|
|
||||||
|
|
||||||
$work = new class extends API {
|
public static function ordered(): array {
|
||||||
private const API_PARAM_LIMIT = "limit";
|
// Get timeline list limit from search param if set
|
||||||
|
$limit = array_key_exists(TIMELINE_PREVIEW_LIMIT_PARAM, $_GET) ? (int) $_GET[TIMELINE_PREVIEW_LIMIT_PARAM] : null;
|
||||||
private readonly Response $resp;
|
|
||||||
private readonly Response $tags;
|
|
||||||
private readonly Response $actions;
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
parent::__construct();
|
|
||||||
|
|
||||||
$this->resp = $this->call(Endpoints::WORK->value)->params([
|
|
||||||
WorkModel::IS_LISTED->value => true,
|
|
||||||
self::API_PARAM_LIMIT => $_GET[self::API_PARAM_LIMIT] ?? null
|
|
||||||
])->get();
|
|
||||||
|
|
||||||
// Fetch metadata for work items if we got an ok from work endpoint
|
|
||||||
if ($this->resp->ok) {
|
|
||||||
$this->tags = $this->call(Endpoints::WORK_TAGS->value)->get();
|
|
||||||
$this->actions = $this->call(Endpoints::WORK_ACTIONS->value)->get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Order response from endpoint into a multi-dimensional array.
|
|
||||||
For example, a single item created at 14th of February 2024 would be ordered like this
|
|
||||||
[2024 => [[02 => [14 => [<row_data>]]]]]
|
|
||||||
*/
|
|
||||||
public function get_timeline(): array {
|
|
||||||
if (!$this->resp->ok) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
$timeline = [];
|
$timeline = [];
|
||||||
|
|
||||||
// Create array of arrays ordered by decending year, month, day, items
|
foreach (parent::all() as $idx => $item) {
|
||||||
foreach ($this->resp->json() as $row) {
|
// Use year as the first dimension
|
||||||
// Create array for current year if it doesn't exist
|
if (!array_key_exists($item->year(), $timeline)) {
|
||||||
if (!array_key_exists($row[WorkModel::DATE_YEAR->value], $timeline)) {
|
$timeline[$item->year()] = [];
|
||||||
$timeline[$row[WorkModel::DATE_YEAR->value]] = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create array for current month if it doesn't exist
|
// And month as the second dimension
|
||||||
if (!array_key_exists($row[WorkModel::DATE_MONTH->value], $timeline[$row[WorkModel::DATE_YEAR->value]])) {
|
if (!array_key_exists($item->month(), $timeline[$item->year()])) {
|
||||||
$timeline[$row[WorkModel::DATE_YEAR->value]][$row[WorkModel::DATE_MONTH->value]] = [];
|
$timeline[$item->year()][$item->month()] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create array for current day if it doesn't exist
|
// Lastly, day as the third dimension
|
||||||
if (!array_key_exists($row[WorkModel::DATE_DAY->value], $timeline[$row[WorkModel::DATE_YEAR->value]][$row[WorkModel::DATE_MONTH->value]])) {
|
if (!array_key_exists($item->day(), $timeline[$item->year()][$item->month()])) {
|
||||||
$timeline[$row[WorkModel::DATE_YEAR->value]][$row[WorkModel::DATE_MONTH->value]][$row[WorkModel::DATE_DAY->value]] = [];
|
$timeline[$item->year()][$item->month()][$item->day()] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append item to ordered array
|
// Append Work instance on Timeline object to the output array by year->month->day
|
||||||
$timeline[$row[WorkModel::DATE_YEAR->value]][$row[WorkModel::DATE_MONTH->value]][$row[WorkModel::DATE_DAY->value]][] = $row;
|
$timeline[$item->year()][$item->month()][$item->day()][] = $item->work();
|
||||||
|
|
||||||
|
// Bail out here if we've reached the theshold for items to display
|
||||||
|
if ($limit && $idx === $limit) {
|
||||||
|
return $timeline;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $timeline;
|
return $timeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function get_tags(string $key): array {
|
|
||||||
if (!$this->resp->ok) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return in_array($key, $this->tags->json()) ? $this->tags->json()[$key] : [];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function get_actions(string $key): array {
|
|
||||||
if (!$this->resp->ok) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return array_key_exists($key, $this->actions->json()) ? $this->actions->json()[$key] : [];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
@ -113,7 +67,7 @@
|
||||||
<section class="timeline">
|
<section class="timeline">
|
||||||
|
|
||||||
<?php // Get year int from key and array of months for current year ?>
|
<?php // Get year int from key and array of months for current year ?>
|
||||||
<?php foreach ($work->get_timeline() as $year => $months): ?>
|
<?php foreach ($timeline::ordered() as $year => $months): ?>
|
||||||
<div class="year">
|
<div class="year">
|
||||||
<div class="track">
|
<div class="track">
|
||||||
<p><?= $year ?></p>
|
<p><?= $year ?></p>
|
||||||
|
@ -138,43 +92,51 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="items">
|
<div class="items">
|
||||||
<?php foreach ($items as $item): ?>
|
<?php foreach ($items as $work): ?>
|
||||||
<div class="item">
|
<div class="item">
|
||||||
|
|
||||||
<?php // List tags if available ?>
|
<?php // List tags if available ?>
|
||||||
<?php if ($work->get_tags($item[WorkModel::ID->value])): ?>
|
<?php if ($work->tags()): ?>
|
||||||
<div class="tags">
|
<div class="tags">
|
||||||
<?php foreach ($work->get_tags($item[WorkModel::ID->value]) as $tag): ?>
|
|
||||||
<p class="tag <?= $tag[WorkTagsModel::NAME->value] ?>"><?= $tag[WorkTagsModel::NAME->value] ?></p>
|
<?php foreach ($work->tags() as $tag): ?>
|
||||||
|
<p class="tag <?= $tag->label()->name ?>"><?= $tag->label()->name ?></p>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<?php // Show large heading if defined ?>
|
<?php if ($work->title()): ?>
|
||||||
<?php if (!empty($item[WorkModel::TITLE->value])): ?>
|
<h2><?= $work->title() ?></h2>
|
||||||
<h2><?= $item[WorkModel::TITLE->value] ?></h2>
|
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<p><?= $item[WorkModel::SUMMARY->value] ?></p>
|
<p><?= $work->summary() ?></p>
|
||||||
|
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<?php if ($work->get_actions($item[WorkModel::ID->value])): ?>
|
|
||||||
|
|
||||||
<?php // Display each action button ?>
|
<?php if ($work->actions()): ?>
|
||||||
<?php foreach ($work->get_actions($item[WorkModel::ID->value]) as $action): ?>
|
<?php foreach ($work->actions() as $action): ?>
|
||||||
<a href="<?= $action[WorkActionsModel::HREF->value] ?>"><button class="inline <?= $action[WorkActionsModel::CLASS_LIST->value] ?>">
|
<a href="<?= $action->href() ?? "/work/{$work->id}" ?>"><button class="inline <?= implode(" ", $action->classes()) ?>">
|
||||||
<p><?= $action[WorkActionsModel::DISPLAY_TEXT->value] ?></p>
|
<?php if ($action->icon_prepended()): ?>
|
||||||
<?= VV::embed("public/assets/media/icons/chevron.svg") ?>
|
<?= VV::embed(ICONS_DIR . $action->icon_prepended()) ?>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<p><?= $action->display_text() ?></p>
|
||||||
|
|
||||||
|
<?php if ($action->icon_appended()): ?>
|
||||||
|
<?= VV::embed(ICONS_DIR . $action->icon_appended()) ?>
|
||||||
|
<?php else: ?>
|
||||||
|
<?= VV::embed(DEFAULT_BUTTON_ICON) ?>
|
||||||
|
<?php endif; ?>
|
||||||
</button></a>
|
</button></a>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
|
|
||||||
<?php // Display a link to namespaced page on vlw.se if no action is defined ?>
|
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<a href="<?= $item[WorkModel::ID->value] ?>"><button class="inline">
|
<a href="<?= "/work/{$work->id}" ?>"><button class="inline">
|
||||||
<p>read more</p>
|
<p>read more</p>
|
||||||
<?= VV::embed("public/assets/media/icons/chevron.svg") ?>
|
<?= VV::embed(DEFAULT_BUTTON_ICON) ?>
|
||||||
</button></a>
|
</button></a>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,8 +1,18 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use const VLW\DEFAULT_BUTTON_ICON;
|
||||||
|
|
||||||
|
require_once VV::root("src/Consts.php");
|
||||||
|
|
||||||
|
?>
|
||||||
<style><?= VV::css("public/assets/css/pages/work/wip") ?></style>
|
<style><?= VV::css("public/assets/css/pages/work/wip") ?></style>
|
||||||
<section class="disclaimer">
|
<section class="disclaimer">
|
||||||
<h1>Soon, very soon!</h1>
|
<h1>Soon, very soon!</h1>
|
||||||
<p>Bear with me as I cook up some texts about this project! Hopefully with some pictures too.</p>
|
<p>Bear with me as I cook up some texts about this project! Hopefully with some pictures too.</p>
|
||||||
</section>
|
</section>
|
||||||
<section class="actions">
|
<section class="actions">
|
||||||
<a href="/work"><button class="inline">to featured work</button></a>
|
<a href="/work"><button class="inline">
|
||||||
|
<p>to featured work</p>
|
||||||
|
<?= VV::embed(DEFAULT_BUTTON_ICON) ?>
|
||||||
|
</button></a>
|
||||||
</section>
|
</section>
|
18
src/API/API.php
Normal file
18
src/API/API.php
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace VLW\API;
|
||||||
|
|
||||||
|
use Reflect\Client as ReflectClient;
|
||||||
|
|
||||||
|
class Client extends ReflectClient {
|
||||||
|
// ISO 8601: YYYY-MM-DD
|
||||||
|
public const DATE_FORMAT = "Y-m-d";
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
parent::__construct(
|
||||||
|
$_ENV["client_api"]["base_url"],
|
||||||
|
$_ENV["client_api"]["api_key"],
|
||||||
|
$_ENV["client_api"]["verify_peer"]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,22 +2,20 @@
|
||||||
|
|
||||||
namespace VLW\API;
|
namespace VLW\API;
|
||||||
|
|
||||||
// Default string to return when a DELETE request is successful
|
use vlw\xEnum;
|
||||||
const RESP_DELETE_OK = "OK";
|
|
||||||
|
|
||||||
// Enum of all available VLW endpoints grouped by category
|
// Enum of all available VLW endpoints grouped by category
|
||||||
enum Endpoints: string {
|
enum Endpoints: string {
|
||||||
case ABOUT_LANGUAGES = "/about/languages";
|
use xEnum;
|
||||||
|
|
||||||
case SEARCH = "/search";
|
case WORK = "/work";
|
||||||
|
case SEARCH = "/search";
|
||||||
case MESSAGES = "/messages";
|
case MESSAGES = "/messages";
|
||||||
|
case WORK_TAGS = "/work/tags";
|
||||||
case WORK = "/work";
|
case WORK_ACTIONS = "/work/actions";
|
||||||
case WORK_TAGS = "/work/tags";
|
case WORK_TIMELINE = "/work/timeline";
|
||||||
case WORK_ACTIONS = "/work/actions";
|
|
||||||
|
|
||||||
case BATTLESTATION = "/battlestation";
|
case BATTLESTATION = "/battlestation";
|
||||||
|
case ABOUT_LANGUAGES = "/about/languages";
|
||||||
case BATTLESTATION_MB = "/battlestation/mb";
|
case BATTLESTATION_MB = "/battlestation/mb";
|
||||||
case BATTLESTATION_CPU = "/battlestation/cpu";
|
case BATTLESTATION_CPU = "/battlestation/cpu";
|
||||||
case BATTLESTATION_GPU = "/battlestation/gpu";
|
case BATTLESTATION_GPU = "/battlestation/gpu";
|
35
src/Consts.php
Normal file
35
src/Consts.php
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace VLW;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # Media
|
||||||
|
* Constants related to media files
|
||||||
|
*/
|
||||||
|
const MEDIA_DIR = "/public/assets/media/";
|
||||||
|
const ICONS_DIR = MEDIA_DIR . "icons/";
|
||||||
|
const DEFAULT_BUTTON_ICON = ICONS_DIR . "chevron.svg";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # Search
|
||||||
|
* Constants for the search API endpoint
|
||||||
|
*/
|
||||||
|
const SEARCH_QUERY_MAX_LENGTH = 2048;
|
||||||
|
const SEARCH_UPDATE_CACHE_PARM = "update";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # Timeline
|
||||||
|
* Constants related to the work timeline
|
||||||
|
*/
|
||||||
|
const TIMELINE_PREVIEW_LIMIT_PARAM = "limit";
|
||||||
|
const TIMELINE_PREVIEW_LIMIT_COUNT = 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # Forgejo
|
||||||
|
* Constants related to the fetching and caching of real-time prog. language use on Forgejo
|
||||||
|
*/
|
||||||
|
const FORGEJO_HREF = "https://git.vlw.se/explore/repos?q=&sort=recentupdate&language=";
|
||||||
|
const FORGEJO_ENDPOINT_USER = "/api/v1/users/%s";
|
||||||
|
const FORGEJO_ENDPOINT_SEARCH = "/api/v1/repos/search?uid=%s";
|
||||||
|
const FORGEJO_SI_BYTE_MULTIPLE = ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
||||||
|
const FORGEJO_UPDATE_CACHE_PARAM = "update";
|
45
src/Database/Database.php
Normal file
45
src/Database/Database.php
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace VLW\Database;
|
||||||
|
|
||||||
|
use Reflect\Response;
|
||||||
|
|
||||||
|
use vlw\MySQL\MySQL;
|
||||||
|
|
||||||
|
class Database {
|
||||||
|
public const SIZE_UUID = 36;
|
||||||
|
public const SIZE_TEXT = 65535;
|
||||||
|
public const SIZE_UINT8 = 2 ** 8 -1;
|
||||||
|
public const SIZE_UINT16 = 2 ** 16 -1;
|
||||||
|
public const SIZE_UINT32 = 2 ** 32 -1;
|
||||||
|
public const SIZE_UINT64 = 2 ** 64 -1;
|
||||||
|
public const SIZE_VARCHAR = 255;
|
||||||
|
|
||||||
|
protected readonly MySQL $db;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
// Create new MariaDB connection
|
||||||
|
$this->db = new MySQL(
|
||||||
|
$_ENV["server_database"]["host"],
|
||||||
|
$_ENV["server_database"]["user"],
|
||||||
|
$_ENV["server_database"]["pass"],
|
||||||
|
$_ENV["server_database"]["db"],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return all rows from a table using $_GET paramters as the WHERE clause as a Reflect\Response
|
||||||
|
public function list(string $table, array $columns, array $order = null): Response {
|
||||||
|
$resp = $this->db->for($table)->where(array_intersect_key($_GET, array_flip($columns)));
|
||||||
|
|
||||||
|
// Optionally order rows by columns
|
||||||
|
if ($order) {
|
||||||
|
$resp = $resp->order($order);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return all matched rows or a 404 with an empty array if there were not results
|
||||||
|
$resp = $resp->select($columns);
|
||||||
|
return $resp && $resp->num_rows > 0
|
||||||
|
? new Response($resp->fetch_all(MYSQLI_ASSOC))
|
||||||
|
: new Response([], 404);
|
||||||
|
}
|
||||||
|
}
|
30
src/Database/Models/About/Language.php
Normal file
30
src/Database/Models/About/Language.php
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace VLW\Database\Models\About;
|
||||||
|
|
||||||
|
use \VV;
|
||||||
|
|
||||||
|
use VLW\API\Endpoints;
|
||||||
|
use VLW\Database\Models\Model;
|
||||||
|
use VLW\Database\Tables\About\LanguagesTable;
|
||||||
|
|
||||||
|
require_once VV::root("src/Consts.php");
|
||||||
|
require_once VV::root("src/API/Endpoints.php");
|
||||||
|
require_once VV::root("src/Database/Models/Model.php");
|
||||||
|
require_once VV::root("src/Database/Tables/About/Languages.php");
|
||||||
|
|
||||||
|
class Language extends Model {
|
||||||
|
public function __construct(public readonly string $id) {
|
||||||
|
parent::__construct(Endpoints::ABOUT_LANGUAGES, [
|
||||||
|
LanguagesTable::ID->value => $this->id
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function all(array $params = []): array {
|
||||||
|
return array_map(fn(array $item): Language => new Language($item[LanguagesTable::ID->value]), parent::list(Endpoints::ABOUT_LANGUAGES, $params));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function bytes(): int {
|
||||||
|
return $this->get(LanguagesTable::BYTES->value);
|
||||||
|
}
|
||||||
|
}
|
43
src/Database/Models/Model.php
Normal file
43
src/Database/Models/Model.php
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace VLW\Database\Models;
|
||||||
|
|
||||||
|
use \VV;
|
||||||
|
|
||||||
|
use VLW\API\{Client, Endpoints};
|
||||||
|
|
||||||
|
require_once VV::root("src/API/API.php");
|
||||||
|
require_once VV::root("src/API/Endpoints.php");
|
||||||
|
|
||||||
|
abstract class Model {
|
||||||
|
abstract public static function all(array $params = []): array;
|
||||||
|
|
||||||
|
private array $row;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
public readonly ?Endpoints $endpoint = null,
|
||||||
|
private readonly array $params = []
|
||||||
|
) {
|
||||||
|
if ($this->endpoint) {
|
||||||
|
$this->assign(self::first(self::list($endpoint, $params)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function first(array $array): array {
|
||||||
|
return $array && is_array(array_values($array)[0]) ? $array[0] : $array;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function list(Endpoints $endpoint, array $params = []): array {
|
||||||
|
$resp = (new Client())->call($endpoint->value)->params($params)->get();
|
||||||
|
return $resp->ok ? $resp->json() : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function assign(array $row): self {
|
||||||
|
$this->row = $row;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get(string $key): mixed {
|
||||||
|
return $this->row[$key] ?? null;
|
||||||
|
}
|
||||||
|
}
|
42
src/Database/Models/Search/Search.php
Normal file
42
src/Database/Models/Search/Search.php
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace VLW\Database\Models\Search;
|
||||||
|
|
||||||
|
use \VV;
|
||||||
|
|
||||||
|
use VLW\API\Endpoints;
|
||||||
|
use VLW\Database\Models\Model;
|
||||||
|
use VLW\Database\Tables\Search\{SearchTable, SearchCategoryEnum};
|
||||||
|
|
||||||
|
require_once VV::root("src/Consts.php");
|
||||||
|
require_once VV::root("src/API/Endpoints.php");
|
||||||
|
require_once VV::root("src/Database/Models/Model.php");
|
||||||
|
require_once VV::root("src/Database/Tables/Search/Search.php");
|
||||||
|
|
||||||
|
class Search extends Model {
|
||||||
|
public function __construct(public readonly string $id) {
|
||||||
|
parent::__construct(Endpoints::SEARCH, [
|
||||||
|
SearchTable::ID->value => $this->id
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function all(array $params = []): array {
|
||||||
|
return array_map(fn(array $item): Search => new Search($item[SearchTable::ID->value]), parent::list(Endpoints::SEARCH, $params));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function title(): ?string {
|
||||||
|
return $this->get(SearchTable::TITLE->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function summary(): ?string {
|
||||||
|
return $this->get(SearchTable::SUMMARY->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function category(): ?SearchCategoryEnum {
|
||||||
|
return SearchCategoryEnum::tryFromName($this->get(SearchTable::CATEGORY->value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function href(): ?string {
|
||||||
|
return $this->get(SearchTable::HREF->value);
|
||||||
|
}
|
||||||
|
}
|
51
src/Database/Models/Work/Action.php
Normal file
51
src/Database/Models/Work/Action.php
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace VLW\Database\Models\Work;
|
||||||
|
|
||||||
|
use \VV;
|
||||||
|
|
||||||
|
use VLW\API\Endpoints;
|
||||||
|
use VLW\Database\Models\Model;
|
||||||
|
use VLW\Database\Models\Work\Work;
|
||||||
|
use VLW\Database\Tables\Work\ActionsTable;
|
||||||
|
|
||||||
|
require_once VV::root("src/API/Endpoints.php");
|
||||||
|
require_once VV::root("src/Database/Models/Model.php");
|
||||||
|
require_once VV::root("src/Database/Models/Work/Work.php");
|
||||||
|
require_once VV::root("src/Database/Tables/Work/Actions.php");
|
||||||
|
|
||||||
|
class Action extends Model {
|
||||||
|
public function __construct() {
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function all(array $params = []): array {
|
||||||
|
return array_map(fn(array $item): Action => (new Action())->assign($item), parent::list(Endpoints::WORK_ACTIONS, $params));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function from(Work $work): array {
|
||||||
|
return self::all([
|
||||||
|
ActionsTable::REF_WORK_ID->value => $work->id
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function icon_prepended(): ?string {
|
||||||
|
return $this->get(ActionsTable::ICON_PREPENDED->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function icon_appended(): ?string {
|
||||||
|
return $this->get(ActionsTable::ICON_APPENDED->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function display_text(): string {
|
||||||
|
return $this->get(ActionsTable::DISPLAY_TEXT->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function href(): ?string {
|
||||||
|
return $this->get(ActionsTable::HREF->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function classes(): array {
|
||||||
|
return $this->get(ActionsTable::CLASS_LIST->value) ? explode(",", $this->get(ActionsTable::CLASS_LIST->value)) : [];
|
||||||
|
}
|
||||||
|
}
|
35
src/Database/Models/Work/Tag.php
Normal file
35
src/Database/Models/Work/Tag.php
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace VLW\Database\Models\Work;
|
||||||
|
|
||||||
|
use \VV;
|
||||||
|
|
||||||
|
use VLW\API\Endpoints;
|
||||||
|
use VLW\Database\Models\Model;
|
||||||
|
use VLW\Database\Models\Work\Work;
|
||||||
|
use VLW\Database\Tables\Work\{TagsTable, TagsLabelEnum};
|
||||||
|
|
||||||
|
require_once VV::root("src/API/Endpoints.php");
|
||||||
|
require_once VV::root("src/Database/Models/Model.php");
|
||||||
|
require_once VV::root("src/Database/Models/Work/Work.php");
|
||||||
|
require_once VV::root("src/Database/Tables/Work/Tags.php");
|
||||||
|
|
||||||
|
class Tag extends Model {
|
||||||
|
public function __construct() {
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function all(array $params = []): array {
|
||||||
|
return array_map(fn(array $item): Tag => (new Tag())->assign($item), parent::list(Endpoints::WORK_TAGS, $params));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function from(Work $work): array {
|
||||||
|
return self::all([
|
||||||
|
TagsTable::REF_WORK_ID->value => $work->id
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function label(): TagsLabelEnum {
|
||||||
|
return TagsLabelEnum::fromName($this->get(TagsTable::LABEL->value));
|
||||||
|
}
|
||||||
|
}
|
43
src/Database/Models/Work/Timeline.php
Normal file
43
src/Database/Models/Work/Timeline.php
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace VLW\Database\Models\Work;
|
||||||
|
|
||||||
|
use \VV;
|
||||||
|
|
||||||
|
use VLW\API\Endpoints;
|
||||||
|
use VLW\Database\Models\Model;
|
||||||
|
use VLW\Database\Models\Work\Work;
|
||||||
|
use VLW\Database\Tables\Work\TimelineTable;
|
||||||
|
|
||||||
|
require_once VV::root("src/API/Endpoints.php");
|
||||||
|
require_once VV::root("src/Database/Models/Model.php");
|
||||||
|
require_once VV::root("src/Database/Models/Work/Work.php");
|
||||||
|
require_once VV::root("src/Database/Tables/Work/Timeline.php");
|
||||||
|
|
||||||
|
class Timeline extends Model {
|
||||||
|
public function __construct(public readonly string $id) {
|
||||||
|
parent::__construct(Endpoints::WORK_TIMELINE, [
|
||||||
|
TimelineTable::REF_WORK_ID->value => $this->id
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function all(array $params = []): array {
|
||||||
|
return array_map(fn(array $item): Timeline => new Timeline($item[TimelineTable::REF_WORK_ID->value]), parent::list(Endpoints::WORK_TIMELINE, $params));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function work(): Work {
|
||||||
|
return new Work($this->get(TimelineTable::REF_WORK_ID->value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function year(): int {
|
||||||
|
return $this->get(TimelineTable::YEAR->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function month(): int {
|
||||||
|
return $this->get(TimelineTable::MONTH->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function day(): int {
|
||||||
|
return $this->get(TimelineTable::DAY->value);
|
||||||
|
}
|
||||||
|
}
|
48
src/Database/Models/Work/Work.php
Normal file
48
src/Database/Models/Work/Work.php
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace VLW\Database\Models\Work;
|
||||||
|
|
||||||
|
use \VV;
|
||||||
|
|
||||||
|
use VLW\API\Endpoints;
|
||||||
|
use VLW\Database\Models\Model;
|
||||||
|
use VLW\Database\Tables\Work\WorkTable;
|
||||||
|
use VLW\Database\Models\Work\{Tag, Action};
|
||||||
|
|
||||||
|
require_once VV::root("src/API/Endpoints.php");
|
||||||
|
require_once VV::root("src/Database/Models/Model.php");
|
||||||
|
require_once VV::root("src/Database/Models/Work/Tag.php");
|
||||||
|
require_once VV::root("src/Database/Tables/Work/Work.php");
|
||||||
|
require_once VV::root("src/Database/Models/Work/Action.php");
|
||||||
|
|
||||||
|
class Work extends Model {
|
||||||
|
public function __construct(public readonly string $id) {
|
||||||
|
parent::__construct(Endpoints::WORK, [
|
||||||
|
WorkTable::ID->value => $this->id
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function all(array $params = []): array {
|
||||||
|
return array_map(fn(array $item): Work => new Work($item[WorkTable::ID->value]), parent::list(Endpoints::WORK, $params));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function title(): ?string {
|
||||||
|
return $this->get(WorkTable::TITLE->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function summary(): string {
|
||||||
|
return $this->get(WorkTable::SUMMARY->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function created(): DateTimeImmutable {
|
||||||
|
return new DateTimeImmutable($this->get(WorkTable::CREATED->value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function tags(): array {
|
||||||
|
return Tag::from($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function actions(): array {
|
||||||
|
return Action::from($this);
|
||||||
|
}
|
||||||
|
}
|
14
src/Database/Tables/About/Languages.php
Normal file
14
src/Database/Tables/About/Languages.php
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace VLW\Database\Tables\About;
|
||||||
|
|
||||||
|
use vlw\xEnum;
|
||||||
|
|
||||||
|
enum LanguagesTable: string {
|
||||||
|
use xEnum;
|
||||||
|
|
||||||
|
const NAME = "about_languages";
|
||||||
|
|
||||||
|
case ID = "id";
|
||||||
|
case BYTES = "bytes";
|
||||||
|
}
|
|
@ -1,13 +1,13 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace VLW\API\Databases\VLWdb\Models\Battlestation;
|
namespace VLW\Database\Tables\Battlestation;
|
||||||
|
|
||||||
use victorwesterlund\xEnum;
|
use vlw\xEnum;
|
||||||
|
|
||||||
enum ChassisModel: string {
|
enum ChassisTable: string {
|
||||||
use xEnum;
|
use xEnum;
|
||||||
|
|
||||||
const TABLE = "chassis";
|
const NAME = "chassis";
|
||||||
|
|
||||||
case ID = "id";
|
case ID = "id";
|
||||||
case VENDOR_NAME = "vendor_name";
|
case VENDOR_NAME = "vendor_name";
|
14
src/Database/Tables/Battlestation/Config/ChassisMb.php
Normal file
14
src/Database/Tables/Battlestation/Config/ChassisMb.php
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace VLW\Database\Tables\Battlestation\Config;
|
||||||
|
|
||||||
|
use vlw\xEnum;
|
||||||
|
|
||||||
|
enum ChassisMbTable: string {
|
||||||
|
use xEnum;
|
||||||
|
|
||||||
|
const NAME = "config_chassis_mb";
|
||||||
|
|
||||||
|
case REF_CHASSIS_ID = "ref_chassis_id";
|
||||||
|
case REF_MB_ID = "ref_mb_id";
|
||||||
|
}
|
|
@ -1,13 +1,13 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace VLW\API\Databases\VLWdb\Models\Battlestation\Config;
|
namespace VLW\Database\Tables\Battlestation\Config;
|
||||||
|
|
||||||
use victorwesterlund\xEnum;
|
use vlw\xEnum;
|
||||||
|
|
||||||
enum ConfigModel: string {
|
enum ConfigModel: string {
|
||||||
use xEnum;
|
use xEnum;
|
||||||
|
|
||||||
const TABLE = "config";
|
const NAME = "config";
|
||||||
|
|
||||||
case REF_MB_ID = "ref_mb_id";
|
case REF_MB_ID = "ref_mb_id";
|
||||||
case FRIENDLY_NAME = "friendly_name";
|
case FRIENDLY_NAME = "friendly_name";
|
|
@ -1,8 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace VLW\API\Databases\VLWdb\Models\Battlestation\Config;
|
namespace VLW\Database\Tables\Battlestation\Config;
|
||||||
|
|
||||||
use victorwesterlund\xEnum;
|
use vlw\xEnum;
|
||||||
|
|
||||||
enum SocketTypeEnum {
|
enum SocketTypeEnum {
|
||||||
use xEnum;
|
use xEnum;
|
||||||
|
@ -14,7 +14,7 @@
|
||||||
enum MbCpuCoolerModel: string {
|
enum MbCpuCoolerModel: string {
|
||||||
use xEnum;
|
use xEnum;
|
||||||
|
|
||||||
const TABLE = "config_mb_cpu_cooler";
|
const NAME = "config_mb_cpu_cooler";
|
||||||
|
|
||||||
case REF_MB_ID = "ref_mb_id";
|
case REF_MB_ID = "ref_mb_id";
|
||||||
case REF_CPU_ID = "ref_cpu_id";
|
case REF_CPU_ID = "ref_cpu_id";
|
|
@ -1,8 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace VLW\API\Databases\VLWdb\Models\Battlestation\Config;
|
namespace VLW\Database\Tables\Battlestation\Config;
|
||||||
|
|
||||||
use victorwesterlund\xEnum;
|
use vlw\xEnum;
|
||||||
|
|
||||||
enum SocketTypeModel {
|
enum SocketTypeModel {
|
||||||
use xEnum;
|
use xEnum;
|
||||||
|
@ -11,10 +11,10 @@
|
||||||
case INTEGRATED;
|
case INTEGRATED;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum MbDramModel: string {
|
enum MbDramTable: string {
|
||||||
use xEnum;
|
use xEnum;
|
||||||
|
|
||||||
const TABLE = "config_mb_dram";
|
const NAME = "config_mb_dram";
|
||||||
|
|
||||||
case REF_MB_ID = "ref_mb_id";
|
case REF_MB_ID = "ref_mb_id";
|
||||||
case REF_DRAM_ID = "ref_dram_id";
|
case REF_DRAM_ID = "ref_dram_id";
|
14
src/Database/Tables/Battlestation/Config/MbGpu.php
Normal file
14
src/Database/Tables/Battlestation/Config/MbGpu.php
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace VLW\Database\Tables\Battlestation\Config;
|
||||||
|
|
||||||
|
use vlw\xEnum;
|
||||||
|
|
||||||
|
enum MbGpuTable: string {
|
||||||
|
use xEnum;
|
||||||
|
|
||||||
|
const NAME = "config_mb_gpu";
|
||||||
|
|
||||||
|
case REF_MB_ID = "ref_mb_id";
|
||||||
|
case REF_GPU_ID = "ref_gpu_id";
|
||||||
|
}
|
14
src/Database/Tables/Battlestation/Config/MbPsu.php
Normal file
14
src/Database/Tables/Battlestation/Config/MbPsu.php
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace VLW\Database\Tables\Battlestation\Config;
|
||||||
|
|
||||||
|
use vlw\xEnum;
|
||||||
|
|
||||||
|
enum MbPsuTable: string {
|
||||||
|
use xEnum;
|
||||||
|
|
||||||
|
const NAME = "config_mb_psu";
|
||||||
|
|
||||||
|
case REF_MB_ID = "ref_mb_id";
|
||||||
|
case REF_PSU_ID = "ref_psu_id";
|
||||||
|
}
|
|
@ -1,8 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace VLW\API\Databases\VLWdb\Models\Battlestation\Config;
|
namespace VLW\Database\Tables\Battlestation\Config;
|
||||||
|
|
||||||
use victorwesterlund\xEnum;
|
use vlw\xEnum;
|
||||||
|
|
||||||
enum MbStorageSlotFormfactorEnum: string {
|
enum MbStorageSlotFormfactorEnum: string {
|
||||||
use xEnum;
|
use xEnum;
|
||||||
|
@ -13,10 +13,10 @@
|
||||||
case EXTERNAL = "EXTERNAL";
|
case EXTERNAL = "EXTERNAL";
|
||||||
}
|
}
|
||||||
|
|
||||||
enum MbStorageModel: string {
|
enum MbStorageTable: string {
|
||||||
use xEnum;
|
use xEnum;
|
||||||
|
|
||||||
const TABLE = "config_mb_storage";
|
const NAME = "config_mb_storage";
|
||||||
|
|
||||||
case REF_MB_ID = "ref_mb_id";
|
case REF_MB_ID = "ref_mb_id";
|
||||||
case REF_STORAGE_ID = "ref_storage_id";
|
case REF_STORAGE_ID = "ref_storage_id";
|
|
@ -1,9 +1,9 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace VLW\API\Databases\VLWdb\Models\Battlestation;
|
namespace VLW\Database\Tables\Battlestation;
|
||||||
|
|
||||||
enum CoolersModel: string {
|
enum CoolersTable: string {
|
||||||
const TABLE = "coolers";
|
const NAME = "coolers";
|
||||||
|
|
||||||
case ID = "id";
|
case ID = "id";
|
||||||
case TYPE_LIQUID = "type_liquid";
|
case TYPE_LIQUID = "type_liquid";
|
|
@ -1,8 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace VLW\API\Databases\VLWdb\Models\Battlestation;
|
namespace VLW\Database\Tables\Battlestation;
|
||||||
|
|
||||||
use victorwesterlund\xEnum;
|
use vlw\xEnum;
|
||||||
|
|
||||||
enum ClassEnum {
|
enum ClassEnum {
|
||||||
use xEnum;
|
use xEnum;
|
||||||
|
@ -12,10 +12,10 @@
|
||||||
case SERVER;
|
case SERVER;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum CpuModel: string {
|
enum CpuTable: string {
|
||||||
use xEnum;
|
use xEnum;
|
||||||
|
|
||||||
const TABLE = "cpu";
|
const NAME = "cpu";
|
||||||
|
|
||||||
case ID = "id";
|
case ID = "id";
|
||||||
case CPU_CLASS = "class";
|
case CPU_CLASS = "class";
|
|
@ -1,8 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace VLW\API\Databases\VLWdb\Models\Battlestation;
|
namespace VLW\Database\Tables\Battlestation;
|
||||||
|
|
||||||
use victorwesterlund\xEnum;
|
use vlw\xEnum;
|
||||||
|
|
||||||
enum DramFormfactorEnum {
|
enum DramFormfactorEnum {
|
||||||
use xEnum;
|
use xEnum;
|
||||||
|
@ -18,10 +18,10 @@
|
||||||
case DDR5;
|
case DDR5;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum DramModel: string {
|
enum DramTable: string {
|
||||||
use xEnum;
|
use xEnum;
|
||||||
|
|
||||||
const TABLE = "dram";
|
const NAME = "dram";
|
||||||
|
|
||||||
case ID = "id";
|
case ID = "id";
|
||||||
case CAPACITY = "capacity";
|
case CAPACITY = "capacity";
|
|
@ -1,13 +1,13 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace VLW\API\Databases\VLWdb\Models\Battlestation;
|
namespace VLW\Database\Tables\Battlestation;
|
||||||
|
|
||||||
use victorwesterlund\xEnum;
|
use vlw\xEnum;
|
||||||
|
|
||||||
enum GpuModel: string {
|
enum GpuTable: string {
|
||||||
use xEnum;
|
use xEnum;
|
||||||
|
|
||||||
const TABLE = "gpu";
|
const NAME = "gpu";
|
||||||
|
|
||||||
case ID = "id";
|
case ID = "id";
|
||||||
case MEMORY = "memory";
|
case MEMORY = "memory";
|
|
@ -1,8 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace VLW\API\Databases\VLWdb\Models\Battlestation;
|
namespace VLW\Database\Tables\Battlestation;
|
||||||
|
|
||||||
use victorwesterlund\xEnum;
|
use vlw\xEnum;
|
||||||
|
|
||||||
enum MbFormfactorEnum {
|
enum MbFormfactorEnum {
|
||||||
use xEnum;
|
use xEnum;
|
||||||
|
@ -13,10 +13,10 @@
|
||||||
case LAPTOP;
|
case LAPTOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum MbModel: string {
|
enum MbTable: string {
|
||||||
use xEnum;
|
use xEnum;
|
||||||
|
|
||||||
const TABLE = "mb";
|
const NAME = "mb";
|
||||||
|
|
||||||
case ID = "id";
|
case ID = "id";
|
||||||
case FORMFACTOR = "formfactor";
|
case FORMFACTOR = "formfactor";
|
|
@ -1,8 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace VLW\API\Databases\VLWdb\Models\Battlestation;
|
namespace VLW\Database\Tables\Battlestation;
|
||||||
|
|
||||||
use victorwesterlund\xEnum;
|
use vlw\xEnum;
|
||||||
|
|
||||||
enum EightyplusRatingEnum {
|
enum EightyplusRatingEnum {
|
||||||
use xEnum;
|
use xEnum;
|
||||||
|
@ -15,10 +15,10 @@
|
||||||
case TITANIUM;
|
case TITANIUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum PsuModel: string {
|
enum PsuTable: string {
|
||||||
use xEnum;
|
use xEnum;
|
||||||
|
|
||||||
const TABLE = "psu";
|
const NAME = "psu";
|
||||||
|
|
||||||
case ID = "id";
|
case ID = "id";
|
||||||
case POWER = "power";
|
case POWER = "power";
|
|
@ -1,8 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace VLW\API\Databases\VLWdb\Models\Battlestation;
|
namespace VLW\Database\Tables\Battlestation;
|
||||||
|
|
||||||
use victorwesterlund\xEnum;
|
use vlw\xEnum;
|
||||||
|
|
||||||
enum StorageDiskTypeEnum {
|
enum StorageDiskTypeEnum {
|
||||||
use xEnum;
|
use xEnum;
|
||||||
|
@ -27,10 +27,10 @@
|
||||||
case MDOTTWO;
|
case MDOTTWO;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum StorageModel: string {
|
enum StorageTable: string {
|
||||||
use xEnum;
|
use xEnum;
|
||||||
|
|
||||||
const TABLE = "storage";
|
const NAME = "storage";
|
||||||
|
|
||||||
case ID = "id";
|
case ID = "id";
|
||||||
case DISK_TYPE = "disk_type";
|
case DISK_TYPE = "disk_type";
|
11
src/Database/Tables/Messages/Messages.php
Normal file
11
src/Database/Tables/Messages/Messages.php
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace VLW\Database\Tables\Messages;
|
||||||
|
|
||||||
|
enum MessagesTable: string {
|
||||||
|
const NAME = "messages";
|
||||||
|
|
||||||
|
case EMAIL = "email";
|
||||||
|
case MESSAGE = "message";
|
||||||
|
case TIMESTAMP_CREATED = "timestamp_created";
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue