Browse Source

rewrite config files to JSON, refactor environment bootstrap #14

main
ghost 1 year ago
parent
commit
32c1bbe4a2
  1. 5
      .gitignore
  2. 5
      README.md
  3. 216
      example/environment/env.example.php
  4. 4
      src/app/controller/index.php
  5. 4
      src/app/controller/response.php
  6. 4
      src/app/controller/welcome.php
  7. 49
      src/app/model/database.php
  8. 116
      src/config/bootstrap.php
  9. 7
      src/config/database.json
  10. 6
      src/config/memcached.json
  11. 3
      src/config/moderators.json
  12. 4
      src/config/sphinx.json
  13. 4
      src/config/website.json

5
.gitignore vendored

@ -9,7 +9,12 @@ @@ -9,7 +9,12 @@
/src/config/*
!/src/config/bootstrap.php
!/src/config/website.json
!/src/config/sphinx.json
!/src/config/memcached.json
!/src/config/database.json
!/src/config/validator.json
!/src/config/moderators.json
!/src/config/nodes.json
!/src/config/trackers.json
!/src/config/peers.json

5
README.md

@ -50,8 +50,9 @@ memcached @@ -50,8 +50,9 @@ memcached
* The web root dir is `/src/public`
* Deploy the database using [MySQL Workbench](https://www.mysql.com/products/workbench) project presented in the `/database` folder
* Install [Sphinx Search Server](https://sphinxsearch.com)
* Configuration examples presented at `/example/environment` folder. On first app launch, configuration file will be auto-generated in `/src/config`
* Make sure `/src/api` folder writable
* Server environment examples presented at `/example/environment` folder
* App config available at `/src/config` folder in JSON format.
+ To make environment-based configuration for JSON files, create subfolder `/src/config/env` and define `env` in `/src/config/.env` file
#### Contribute

216
example/environment/env.example.php

@ -1,216 +0,0 @@ @@ -1,216 +0,0 @@
<?php
/*
* MIT License
*
* Copyright (c) 2023 YGGverse
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Project home page
* https://github.com/YGGverse/YGGtracker
*
* Get support
* https://github.com/YGGverse/YGGtracker/issues
*/
// Debug
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
error_reporting(E_ALL);
// Database
define('DB_PORT', 3306);
define('DB_HOST', 'localhost');
define('DB_NAME', '');
define('DB_USERNAME', '');
define('DB_PASSWORD', '');
// Sphinx
define('SPHINX_HOST', '127.0.0.1');
define('SPHINX_PORT', 9306);
// Memcached
define('MEMCACHED_PORT', 11211);
define('MEMCACHED_HOST', 'localhost');
define('MEMCACHED_NAMESPACE', 'yggtracker');
define('MEMCACHED_TIMEOUT', 60 * 5);
// Webapp
define('WEBSITE_URL', '');
define('WEBSITE_NAME', 'YGGtracker');
define('WEBSITE_CSS_VERSION', 2);
define('WEBSITE_PAGINATION_LIMIT', 20);
// Moderation
define('MODERATOR_IP_LIST', (array)
[
'127.0.0.1',
// ...
]
);
// User
define('USER_DEFAULT_APPROVED', false);
define('USER_AUTO_APPROVE_ON_MAGNET_APPROVE', true);
define('USER_AUTO_APPROVE_ON_COMMENT_APPROVE', true);
define('USER_AUTO_APPROVE_ON_IMPORT_APPROVED', false);
define('USER_DEFAULT_IDENTICON', 'jidenticon'); // jidenticon|false
define('USER_IDENTICON_FIELD', 'address'); // address|userId|...
// Magnet
define('MAGNET_DEFAULT_APPROVED', USER_DEFAULT_APPROVED);
define('MAGNET_DEFAULT_PUBLIC', false);
define('MAGNET_DEFAULT_COMMENTS', true);
define('MAGNET_DEFAULT_SENSITIVE', false);
define('MAGNET_AUTO_APPROVE_ON_IMPORT_APPROVED', true);
define('MAGNET_EDITOR_LOCK_TIMEOUT', 60*60);
define('MAGNET_TITLE_MIN_LENGTH', 10);
define('MAGNET_TITLE_MAX_LENGTH', 140);
define('MAGNET_TITLE_REGEX', '/.*/ui');
define('MAGNET_PREVIEW_MIN_LENGTH', 0);
define('MAGNET_PREVIEW_MAX_LENGTH', 255);
define('MAGNET_PREVIEW_REGEX', '/.*/ui');
define('MAGNET_DESCRIPTION_MIN_LENGTH', 0);
define('MAGNET_DESCRIPTION_MAX_LENGTH', 10000);
define('MAGNET_DESCRIPTION_REGEX', '/.*/ui');
define('MAGNET_DN_MIN_LENGTH', 2);
define('MAGNET_DN_MAX_LENGTH', 255);
define('MAGNET_DN_REGEX', '/.*/ui');
define('MAGNET_KT_MIN_LENGTH', 2);
define('MAGNET_KT_MAX_LENGTH', 140);
define('MAGNET_KT_REGEX', '/[\w]+/ui');
define('MAGNET_KT_MIN_QUANTITY', 0);
define('MAGNET_KT_MAX_QUANTITY', 20);
define('MAGNET_TR_MIN_QUANTITY', 1);
define('MAGNET_TR_MAX_QUANTITY', 50);
define('MAGNET_AS_MIN_QUANTITY', 0);
define('MAGNET_AS_MAX_QUANTITY', 50);
define('MAGNET_WS_MIN_QUANTITY', 0);
define('MAGNET_WS_MAX_QUANTITY', 50);
define('MAGNET_STOP_WORDS_SIMILAR',
[
'series',
'season',
'discography',
// ...
]
);
// Magnet comment
define('MAGNET_COMMENT_DEFAULT_APPROVED', false);
define('MAGNET_COMMENT_DEFAULT_PUBLIC', false);
define('MAGNET_COMMENT_MIN_LENGTH', 1);
define('MAGNET_COMMENT_MAX_LENGTH', 1000);
// Torrent
define('TORRENT_ANNOUNCE_MIN_QUANTITY', 1);
define('TORRENT_ANNOUNCE_MAX_QUANTITY', 50);
define('TORRENT_COMMENT_MIN_LENGTH', 0);
define('TORRENT_COMMENT_MAX_LENGTH', 255);
define('TORRENT_COMMENT_REGEX', '/.*/ui');
define('TORRENT_INFO_NAME_MIN_LENGTH', 0);
define('TORRENT_INFO_NAME_MAX_LENGTH', 255);
define('TORRENT_INFO_NAME_REGEX', '/.*/ui');
define('TORRENT_INFO_SOURCE_MIN_LENGTH', 0);
define('TORRENT_INFO_SOURCE_MAX_LENGTH', 255);
define('TORRENT_INFO_SOURCE_REGEX', '/.*/ui');
define('TORRENT_CREATED_BY_MIN_LENGTH', 0);
define('TORRENT_CREATED_BY_MAX_LENGTH', 255);
define('TORRENT_CREATED_BY_REGEX', '/.*/ui');
// Yggdrasil
define('YGGDRASIL_HOST_REGEX', '/^0{0,1}[2-3][a-f0-9]{0,2}:/'); // thanks to @ygguser (https://github.com/YGGverse/YGGo/issues/1#issuecomment-1498182228 )
// Crawler
define('CRAWLER_SCRAPE_QUEUE_LIMIT', 1);
define('CRAWLER_SCRAPE_TIME_OFFLINE_TIMEOUT', 60*60*24);
// Node
define('NODE_RULE_SUBJECT', 'Common');
define('NODE_RULE_LANGUAGES', 'All');
// API
define('API_USER_AGENT', WEBSITE_NAME);
/// Export
define('API_EXPORT_ENABLED', true);
define('API_EXPORT_PUSH_ENABLED', true); // depends of API_EXPORT_ENABLED
define('API_EXPORT_USERS_ENABLED', true); // depends of API_EXPORT_ENABLED
define('API_EXPORT_MAGNETS_ENABLED', true); // depends of API_EXPORT_ENABLED, API_EXPORT_USERS_ENABLED
define('API_EXPORT_MAGNET_DOWNLOADS_ENABLED', true); // depends of API_EXPORT_ENABLED, API_EXPORT_USERS_ENABLED, API_EXPORT_MAGNETS_ENABLED
define('API_EXPORT_MAGNET_COMMENTS_ENABLED', true); // depends of API_EXPORT_ENABLED, API_EXPORT_USERS_ENABLED, API_EXPORT_MAGNETS_ENABLED
define('API_EXPORT_MAGNET_STARS_ENABLED', true); // depends of API_EXPORT_ENABLED, API_EXPORT_USERS_ENABLED, API_EXPORT_MAGNETS_ENABLED
define('API_EXPORT_MAGNET_VIEWS_ENABLED', true); // depends of API_EXPORT_ENABLED, API_EXPORT_USERS_ENABLED, API_EXPORT_MAGNETS_ENABLED
/// Import
define('API_IMPORT_ENABLED', true);
define('API_IMPORT_PUSH_ENABLED', true); // depends of API_IMPORT_ENABLED
define('API_IMPORT_USERS_ENABLED', true); // depends of API_IMPORT_ENABLED
define('API_IMPORT_USERS_APPROVED_ONLY', false); // depends of API_IMPORT_ENABLED, API_IMPORT_USERS_ENABLED
define('API_IMPORT_MAGNETS_ENABLED', true); // depends of API_IMPORT_ENABLED, API_IMPORT_USERS_ENABLED
define('API_IMPORT_MAGNETS_APPROVED_ONLY', false); // depends of API_IMPORT_ENABLED, API_IMPORT_USERS_ENABLED, API_IMPORT_MAGNETS_ENABLED
define('API_IMPORT_MAGNET_DOWNLOADS_ENABLED', true); // depends of API_IMPORT_ENABLED, API_IMPORT_USERS_ENABLED, API_IMPORT_MAGNETS_ENABLED
define('API_IMPORT_MAGNET_COMMENTS_ENABLED', true); // depends of API_IMPORT_ENABLED, API_IMPORT_USERS_ENABLED, API_IMPORT_MAGNETS_ENABLED
define('API_IMPORT_MAGNET_COMMENTS_APPROVED_ONLY', false); // depends of API_IMPORT_ENABLED, API_IMPORT_USERS_ENABLED, API_IMPORT_MAGNETS_ENABLED, API_IMPORT_MAGNET_COMMENTS_ENABLED
define('API_IMPORT_MAGNET_STARS_ENABLED', true); // depends of API_IMPORT_ENABLED, API_IMPORT_USERS_ENABLED, API_IMPORT_MAGNETS_ENABLED
define('API_IMPORT_MAGNET_VIEWS_ENABLED', true); // depends of API_IMPORT_ENABLED, API_IMPORT_USERS_ENABLED, API_IMPORT_MAGNETS_ENABLED
// Logs
define('LOG_DIRECTORY', __DIR__ . '/../storage/log');
define('LOG_CRONTAB_SCRAPE_ENABLED', true);
define('LOG_CRONTAB_SCRAPE_FILENAME', sprintf('crontab_scrape_%s.log', date('Y-m-d')));
define('LOG_CRONTAB_SITEMAP_ENABLED', true);
define('LOG_CRONTAB_SITEMAP_FILENAME', sprintf('crontab_sitemap_%s.log', date('Y-m-d')));
define('LOG_CRONTAB_EXPORT_FEED_ENABLED', true);
define('LOG_CRONTAB_EXPORT_FEED_FILENAME', sprintf('crontab_export_feed_%s.log', date('Y-m-d')));
define('LOG_CRONTAB_EXPORT_PUSH_ENABLED', true);
define('LOG_CRONTAB_EXPORT_PUSH_FILENAME', sprintf('crontab_export_push_%s.log', date('Y-m-d')));
define('LOG_CRONTAB_IMPORT_FEED_ENABLED', true);
define('LOG_CRONTAB_IMPORT_FEED_FILENAME', sprintf('crontab_import_feed_%s.log', date('Y-m-d')));
define('LOG_API_PUSH_ENABLED', true);
define('LOG_API_PUSH_FILENAME', sprintf('api_push_%s.log', date('Y-m-d')));

4
src/app/controller/index.php

@ -85,7 +85,7 @@ class AppControllerIndex @@ -85,7 +85,7 @@ class AppControllerIndex
'type' => 'text/css',
'href' => sprintf(
'assets/theme/default/css/common.css?%s',
WEBSITE_CSS_VERSION
CSS_VERSION
),
],
[
@ -93,7 +93,7 @@ class AppControllerIndex @@ -93,7 +93,7 @@ class AppControllerIndex
'type' => 'text/css',
'href' => sprintf(
'assets/theme/default/css/framework.css?%s',
WEBSITE_CSS_VERSION
CSS_VERSION
),
],
]

4
src/app/controller/response.php

@ -38,7 +38,7 @@ class AppControllerResponse @@ -38,7 +38,7 @@ class AppControllerResponse
'type' => 'text/css',
'href' => sprintf(
'assets/theme/default/css/common.css?%s',
WEBSITE_CSS_VERSION
CSS_VERSION
),
],
[
@ -46,7 +46,7 @@ class AppControllerResponse @@ -46,7 +46,7 @@ class AppControllerResponse
'type' => 'text/css',
'href' => sprintf(
'assets/theme/default/css/framework.css?%s',
WEBSITE_CSS_VERSION
CSS_VERSION
),
],
]

4
src/app/controller/welcome.php

@ -92,7 +92,7 @@ class AppControllerWelcome @@ -92,7 +92,7 @@ class AppControllerWelcome
'type' => 'text/css',
'href' => sprintf(
'assets/theme/default/css/common.css?%s',
WEBSITE_CSS_VERSION
CSS_VERSION
),
],
[
@ -100,7 +100,7 @@ class AppControllerWelcome @@ -100,7 +100,7 @@ class AppControllerWelcome
'type' => 'text/css',
'href' => sprintf(
'assets/theme/default/css/framework.css?%s',
WEBSITE_CSS_VERSION
CSS_VERSION
),
],
]

49
src/app/model/database.php

@ -1,17 +1,36 @@ @@ -1,17 +1,36 @@
<?php
class AppModelDatabase {
class AppModelDatabase
{
private PDO $_db;
private object $_debug;
public function __construct(string $host, int $port, string $database, string $username, string $password) {
public function __construct(object $config)
{
$this->_db = new PDO(
'mysql:dbname=' . $config->name . ';host=' . $config->host . ';port=' . $config->port . ';charset=utf8',
$config->user,
$config->password,
[
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'
]
);
$this->_db->setAttribute(
PDO::ATTR_ERRMODE,
PDO::ERRMODE_EXCEPTION
);
$this->_db->setAttribute(
PDO::ATTR_DEFAULT_FETCH_MODE,
PDO::FETCH_OBJ
);
$this->_db = new PDO('mysql:dbname=' . $database . ';host=' . $host . ';port=' . $port . ';charset=utf8', $username, $password, [PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8']);
$this->_db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->_db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
$this->_db->setAttribute(PDO::ATTR_TIMEOUT, 600);
$this->_db->setAttribute(
PDO::ATTR_TIMEOUT,
600
);
$this->_debug = (object)
[
@ -38,23 +57,23 @@ class AppModelDatabase { @@ -38,23 +57,23 @@ class AppModelDatabase {
}
// Tools
public function beginTransaction() {
public function beginTransaction() : void
{
$this->_db->beginTransaction();
}
public function commit() {
public function commit() : void
{
$this->_db->commit();
}
public function rollBack() {
public function rollBack() : void
{
$this->_db->rollBack();
}
public function getDebug() {
public function getDebug() : object
{
return $this->_debug;
}

116
src/config/bootstrap.php

@ -3,42 +3,20 @@ @@ -3,42 +3,20 @@
// PHP
declare(strict_types=1);
// Debug
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
error_reporting(E_ALL);
// Application
define('APP_VERSION', '2.0.0');
define('API_VERSION', APP_VERSION);
define('CSS_VERSION', APP_VERSION);
// Init environment
if (!file_exists(__DIR__ . '/.env'))
{
if ($handle = fopen(__DIR__ . '/.env', 'w+'))
{
fwrite($handle, 'default');
fclose($handle);
chmod(__DIR__ . '/.env', 0770);
}
else exit (_('Could not init environment file. Please check permissions.'));
}
define('PHP_ENV', file_get_contents(__DIR__ . '/.env'));
// Init config
if (!file_exists(__DIR__ . '/env.' . PHP_ENV . '.php'))
{
if (copy(__DIR__ . '/../../example/environment/env.example.php',
__DIR__ . '/env.' . PHP_ENV . '.php'))
{
chmod(__DIR__ . '/env.' . PHP_ENV . '.php', 0770);
}
else exit (_('Could not init configuration file. Please check permissions.'));
}
// Environment
require_once __DIR__ . '/../library/environment.php';
// Load environment
require_once __DIR__ . '/env.' . PHP_ENV . '.php';
// Autoload vendors
// Autoload
require_once __DIR__ . '/../../vendor/autoload.php';
// Route
@ -50,93 +28,109 @@ if (isset($request['_route_'])) @@ -50,93 +28,109 @@ if (isset($request['_route_']))
{
case 'stars':
require_once(__DIR__ . '/../app/controller/stars.php');
require_once __DIR__ . '/../app/controller/stars.php';
$appControllerStars = new AppControllerStars();
$controller = new AppControllerStars();
$appControllerStars->render();
break;
case 'views':
require_once(__DIR__ . '/../app/controller/views.php');
require_once __DIR__ . '/../app/controller/views.php';
$controller = new AppControllerViews();
$appControllerViews = new AppControllerViews();
$appControllerViews->render();
break;
case 'downloads':
require_once(__DIR__ . '/../app/controller/downloads.php');
require_once __DIR__ . '/../app/controller/downloads.php';
$appControllerDownloads = new AppControllerDownloads();
$controller = new AppControllerDownloads();
$appControllerDownloads->render();
break;
case 'comments':
require_once(__DIR__ . '/../app/controller/comments.php');
require_once __DIR__ . '/../app/controller/comments.php';
$controller = new AppControllerComments();
$appControllerComments = new AppControllerComments();
$appControllerComments->render();
break;
case 'editions':
require_once(__DIR__ . '/../app/controller/editions.php');
require_once __DIR__ . '/../app/controller/editions.php';
$appControllerEditions = new AppControllerEditions();
$controller = new AppControllerEditions();
$appControllerEditions->render();
break;
case 'welcome':
require_once(__DIR__ . '/../app/controller/welcome.php');
require_once __DIR__ . '/../app/controller/welcome.php';
$appControllerWelcome = new AppControllerWelcome();
$controller = new AppControllerWelcome();
$appControllerWelcome->render();
break;
case 'submit':
case 'page/form':
require_once(__DIR__ . '/../app/model/validator.php');
require_once __DIR__ . '/../app/controller/page.php';
$validator = new AppModelValidator(
json_decode(
file_get_contents(
__DIR__ . '/../config/validator.json'
)
)
$appControllerPage = new AppControllerPage(
Environment::config('website')
);
require_once(__DIR__ . '/../app/controller/submit.php');
require_once __DIR__ . '/../app/model/database.php';
require_once __DIR__ . '/../app/model/validator.php';
$controller = new AppControllerSubmit(
$validator
$appControllerPage->renderFormDescription(
new AppModelDatabase(
Environment::config('database')
),
new AppModelValidator(
Environment::config('validator')
)
);
break;
default:
require_once(__DIR__ . '/../app/controller/response.php');
require_once __DIR__ . '/../app/controller/response.php';
$controller = new AppControllerResponse(
$appControllerResponse = new AppControllerResponse(
sprintf(
_('404 - Not found - %s'),
WEBSITE_NAME
Environment::config('website')->name
),
_('404'),
_('Page not found'),
404
);
$appControllerResponse->render();
}
}
else
{
require_once(__DIR__ . '/../app/controller/index.php');
require_once __DIR__ . '/../app/controller/index.php';
$controller = new AppControllerIndex();
}
$appControllerIndex = new AppControllerIndex();
$controller->render();
$appControllerIndex->render();
}

7
src/config/database.json

@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
{
"port":3306,
"host":"127.0.0.1",
"name":"",
"user":"",
"password":""
}

6
src/config/memcached.json

@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
{
"port": 11211,
"host": "127.0.0.1",
"namespace": "",
"timeout": 3600
}

3
src/config/moderators.json

@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
[
""
]

4
src/config/sphinx.json

@ -0,0 +1,4 @@ @@ -0,0 +1,4 @@
{
"port":9306,
"host":"127.0.0.1"
}

4
src/config/website.json

@ -0,0 +1,4 @@ @@ -0,0 +1,4 @@
{
"name":"YGGtracker",
"url":""
}
Loading…
Cancel
Save