Automatic push 4.3.0

This commit is contained in:
chevereto
2025-05-13 16:49:51 +00:00
parent 61fb0347f8
commit 73b180a372
282 changed files with 15241 additions and 11049 deletions

1
.github/FUNDING.yml vendored
View File

@@ -1 +0,0 @@
custom: ['https://chevereto.com/pricing']

View File

@@ -46,8 +46,7 @@ jobs:
chevereto/chevereto
${{ env.GHCR_SLUG }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=raw,value=latest,enable={{is_default_branch}}
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}

View File

@@ -1,9 +0,0 @@
Chevereto 4.2.5 (2025-01-31)
- Added `putenv` to integrity-check
- Fixed "Twitter" branding assets to "X"
- Fixed bug in account confirmation process
- Fixed bug in guest owned content editing
- Fixed bug in search functionality
- Fixed bug in tags per file limitation
- Fixed bug with not working local storage in Chevereto Lite

50
.package/4.3.0.txt Normal file
View File

@@ -0,0 +1,50 @@
Chevereto 4.3.0 (2025-05-13)
- Added API dashboard settings page
- Added application-level categories cache
- Added application-level guest listing cache
- Added application-level pages cache
- Added application-level settings cache
- Added application-level top tags cache
- Added application-level user albums cache
- Added application-level variables cache
- Added cache-flush command
- Added cache-view command
- Added CHEVERETO_ENABLE_API_USER
- Added CHEVERETO_MAX_LISTING_ITEMS_PER_PAGE limit
- Added CHEVERETO_MAX_TAGS limit
- Added chunked uploads
- Added circles for user avatars
- Added configurable API availability
- Added connect URL display for each login provider
- Added customizable semantics for file concerns
- Added customizable semantics for tag concerns
- Added customizable semantics for video concerns
- Added explicit instructions to "Something went wrong" message
- Added lossless JPEG auto-orientation using ExifTran
- Added lossless metadata removal using ExifTool
- Added more database composite indexes
- Added option to disable user color palette selection
- Added restricted password reset after repeated failures
- Added restricted two-factor access after repeated failures
- Added support for Cloudflare Turnstile captcha
- Added support for GoPro 360 photos
- Fixed bug affecting EXIF read for Sony cameras
- Fixed bug affecting private sub-albums
- Fixed bug in upload queue handler
- Fixed bug on upgrading.php
- Improved Dashboard settings menu sort display
- Improved database schema integer types
- Improved listing database queries
- Improved search engine (boolean matching)
- Improved stats query handling
- Improved user albums query
- Removed guest upload session binding
- Removed maximum upload limit imposed by php.ini
- Removed sendmail for Docker servicing
- Removed support for ModerateContent
- Removed unused dependencies and files
- Renamed "Asset storage" to "Site storage"
- Renamed "External storage" to "Upload storage"
- Renamed app/bin/legacy to app/bin/cli
- Updated file checksum algo to xxh64

View File

@@ -9,23 +9,33 @@
[![Chevereto Docs](https://img.shields.io/badge/chevereto-docs-50C878?style=flat-square)](https://v4-docs.chevereto.com/)
[![Chevereto Community](https://img.shields.io/badge/chevereto-community-blue?style=flat-square)](https://chevereto.com/community)
[![Chevereto Demo](https://img.shields.io/badge/chevereto-demo-d4af37?style=flat-square&color=red)](https://demo.chevereto.com)
[![AGPL-3.0-only](https://img.shields.io/github/license/chevereto/chevereto?style=flat-square)](LICENSE)
[![Legacy stars](https://img.shields.io/github/stars/rodber/chevereto-free?style=flat-square&logo=github&label=Legacy%20stars&color=gold)](https://github.com/rodber/chevereto-free)
[![Chevereto Free](https://img.shields.io/badge/chevereto-editions-gold?style=flat-square)](https://v4-docs.chevereto.com/introduction/editions/compare.html)
[![Awesome F/OSS](https://img.shields.io/badge/Awesome_F%2FOSS-Certified-black?colorA=&colorB=874efe&style=flat-square)](https://awsmfoss.com/chevereto/)
> 🔔 [Subscribe](https://chevereto.com/go/newsletter) to don't miss any update regarding Chevereto.
Chevereto is a robust, self-hosted media-sharing platform that prioritizes flexibility and control. It enables you to build and manage a media-sharing website on your own server, granting you complete autonomy over your hosting environment and policies. With Chevereto, you eliminate the risk of platform restrictions and shutdowns, ensuring your site operates entirely on your terms.
This is the repository for **Chevereto Free** edition. You can [compare editions](https://v4-docs.chevereto.com/introduction/editions/compare.html) to find the Chevereto edition that best suits your needs.
![screen](.github/screen/user-listing-selected.webp)
## Features
Chevereto offers a comprehensive suite of features that make it the ultimate image and video sharing software:
* **Media Management**: Support for images, videos, categories, tags and albums with advanced organization tools
* **User Experience**: Customizable listings, responsive design, and intuitive user interface
* **Privacy Controls**: Granular content privacy settings and user management
* **Performance**: Optimized for speed with CDN support, caching, and image optimization
* **Customization**: Turnkey options, language, and extensive API for integration
You can check the complete list of features in our [Features page](https://chevereto.com/features) and you can also [compare Chevereto editions](https://v4-docs.chevereto.com/introduction/editions/compare.html).
## Requirements
* A [webserver](https://v4-docs.chevereto.com/application/stack/web-server.html) (Apache recommended)
* [PHP](https://v4-docs.chevereto.com/application/stack/php.html) 8.1+ with [extensions](https://v4-docs.chevereto.com/application/stack/php.html#extensions)
* [MySQL Server](https://v4-docs.chevereto.com/application/stack/mysql-server.html) 8.0.1+ or MariaDB Server 10.2.2+
* [Webserver](https://v4-docs.chevereto.com/application/stack/web-server.html)
* [PHP](https://v4-docs.chevereto.com/application/stack/php.html)
* [MySQL Server](https://v4-docs.chevereto.com/application/stack/mysql-server.html) (MariaDB Server)
* [Redis](https://v4-docs.chevereto.com/application/stack/redis.html) (optional)
## Download

7
app/src/Workflow/BaseWorkflow.php → app/bin/cli Normal file → Executable file
View File

@@ -1,3 +1,4 @@
#!/usr/bin/env php
<?php
/*
@@ -9,8 +10,4 @@
* file that was distributed with this source code.
*/
namespace Chevereto\Workflow;
abstract class BaseWorkflow
{
}
require_once dirname(__DIR__) . '/legacy/entrypoints/cli.php';

View File

@@ -10,4 +10,6 @@
* file that was distributed with this source code.
*/
define('APP_BIN_LEGACY', true);
require_once dirname(__DIR__) . '/legacy/entrypoints/cli.php';

View File

@@ -23,8 +23,6 @@
"php": "^8.1",
"intervention/image": "^2.6",
"jeroendesloovere/xmp-metadata-extractor": "^2.0",
"league/flysystem": "^2.0",
"jenssegers/imagehash": "^0.5.0",
"guzzlehttp/psr7": "^1.7||^2",
"phpmailer/phpmailer": "^6.5",
"psr/cache": "^1",
@@ -34,30 +32,26 @@
"mlocati/ip-lib": "^1.17",
"composer/ca-bundle": "^1.2",
"chevere/throwable-handler": "^1.0.2",
"xrdebug/php": "^2.0.2",
"xrdebug/xrdebug": "^2.0.2",
"chevere/workflow": "^0.9.0",
"pragmarx/google2fa": "^8.0",
"pragmarx/google2fa-qrcode": "^3.0",
"phpseclib/bcmath_compat": "^2.0",
"chillerlan/php-qrcode": "^4.3",
"firebase/php-jwt": "^6.3",
"lychee-org/php-exif": "^0.7.14",
"lychee-org/php-exif": "1.0.2",
"p3k/emoji-detector": "^1.0",
"php-ds/php-ds": "^1.4",
"php-ffmpeg/php-ffmpeg": "^1.2",
"psy/psysh": "^0.11.8",
"chevere/cache": "^0.5.0",
"chevere/var-dump": "^2.0.x-dev",
"chevere/var-support": "^1.0"
"chevere/var-support": "^1.0",
"matthiasmullie/scrapbook": "^1.0",
"xrdebug/php": "^3.0",
"xrdebug/xrdebug": "^2.0"
},
"autoload": {
"files": [
"src/File/functions.php",
"src/Image/functions.php",
"src/Encoding/functions.php",
"src/Encryption/functions.php",
"src/Workflow/functions.php",
"src/Vars/functions.php",
"src/Legacy/functions.php",
"src/Legacy/functions-render.php",

958
app/composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -10,8 +10,17 @@
*/
return [
'CHEVERETO_BINARY_EXIFTOOL' => 'exiftool',
'CHEVERETO_BINARY_EXIFTRAN' => 'exiftran',
'CHEVERETO_BINARY_FFMPEG' => 'ffmpeg',
'CHEVERETO_BINARY_FFPROBE' => 'ffprobe',
'CHEVERETO_CACHE_DRIVER' => 'redis',
'CHEVERETO_CACHE_HOST' => '',
'CHEVERETO_CACHE_KEY_PREFIX' => 'chv:',
'CHEVERETO_CACHE_PASSWORD' => '',
'CHEVERETO_CACHE_PORT' => '',
'CHEVERETO_CACHE_TIME_MICRO' => '60',
'CHEVERETO_CACHE_USER' => '',
'CHEVERETO_CONTEXT' => '',
'CHEVERETO_DB_DRIVER' => 'mysql',
'CHEVERETO_DB_HOST' => 'localhost',
@@ -24,6 +33,7 @@ return [
'CHEVERETO_DEBUG_LEVEL' => '1',
'CHEVERETO_EDITION' => 'pro',
'CHEVERETO_ENABLE_API_GUEST' => '1',
'CHEVERETO_ENABLE_API_USER' => '1',
'CHEVERETO_ENABLE_BANNERS' => '1',
'CHEVERETO_ENABLE_BULK_IMPORTER' => '1',
'CHEVERETO_ENABLE_CAPTCHA' => '1',
@@ -55,7 +65,7 @@ return [
'CHEVERETO_ENABLE_SEO_ALBUM_URL' => '1',
'CHEVERETO_ENABLE_SEO_IMAGE_URL' => '1',
'CHEVERETO_ENABLE_SERVICE_AKISMET' => '1',
'CHEVERETO_ENABLE_SERVICE_MODERATECONTENT' => '1',
'CHEVERETO_ENABLE_SERVICE_MODERATECONTENT' => '0',
'CHEVERETO_ENABLE_SERVICE_PROJECTARACHNID' => '1',
'CHEVERETO_ENABLE_SERVICE_STOPFORUMSPAM' => '1',
'CHEVERETO_ENABLE_STOPWORDS' => '1',
@@ -80,18 +90,22 @@ return [
'CHEVERETO_IMAGE_LIBRARY' => 'imagick',
'CHEVERETO_MAX_ADMINS' => '0',
'CHEVERETO_MAX_ALBUMS' => '0',
'CHEVERETO_MAX_CACHE_TTL' => '86400',
'CHEVERETO_MAX_CATEGORIES' => '0',
'CHEVERETO_MAX_CHUNK_UPLOAD_SIZE' => '16M',
'CHEVERETO_MAX_EXECUTION_TIME_SECONDS' => '30',
'CHEVERETO_MAX_FILES' => '0',
'CHEVERETO_MAX_LISTING_ITEMS_PER_PAGE' => '0',
'CHEVERETO_MAX_LOGIN_PROVIDERS' => '0',
'CHEVERETO_MAX_MANAGERS' => '0',
'CHEVERETO_MAX_MEMORY_SIZE' => '512M',
'CHEVERETO_MAX_PAGES' => '0',
'CHEVERETO_MAX_POST_SIZE' => '100M',
'CHEVERETO_MAX_POST_SIZE' => '64M',
'CHEVERETO_MAX_STORAGES' => '0',
'CHEVERETO_MAX_TAGS_PER_FILE' => '0',
'CHEVERETO_MAX_TAGS_PER_LISTING' => '0',
'CHEVERETO_MAX_TAGS' => '0',
'CHEVERETO_MAX_UPLOAD_FILE_SIZE' => '64M',
'CHEVERETO_MAX_UPLOAD_SIZE' => '100M',
'CHEVERETO_MAX_USER_ALBUMS_LIST' => '500',
'CHEVERETO_MAX_USERS' => '0',

View File

@@ -0,0 +1,66 @@
<?php
/*
* This file is part of Chevereto.
*
* (c) Rodolfo Berrios <rodolfo@chevereto.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Chevereto\Legacy\Classes\Cache;
use Chevereto\Legacy\Classes\Categories;
use Chevereto\Legacy\Classes\Tags;
if (! Cache::isEnabled()) {
echo "[ERROR] Cache is not enabled\n";
exit(255);
}
$keyValue = Cache::instance();
$redis = $keyValue->redis();
$prefix = $keyValue->getKey('');
$topLevel = [
'pages_visible',
'settings',
'variables',
Categories::CACHE_KEY,
Tags::CACHE_KEY,
];
$nested = [
'ip',
'l',
'rl',
'u',
];
foreach ($topLevel as $topKey) {
deleteCache($redis, "{$prefix}{$topKey}");
}
foreach ($nested as $nestedKey) {
iterateCache($redis, "{$prefix}{$nestedKey}:");
}
iterateCache($redis, $prefix);
function iterateCache(Redis $redis, string $prefix): void
{
$iterator = null;
while ($iterator !== 0) {
$scan = $redis->scan($iterator, "{$prefix}*");
foreach ($scan as $key) {
if (str_starts_with($key, "{$prefix}SESSION")
|| str_ends_with($key, '.stampede')
) {
continue;
}
deleteCache($redis, $key);
}
}
}
function deleteCache(Redis $redis, string $key): void
{
$result = (bool) $redis->del($key);
$status = 'DELETE';
if ($result === false && ! $redis->get($key)) {
$status = ' 404';
}
echo "* {$status} > {$key}\n";
}

View File

@@ -0,0 +1,79 @@
<?php
/*
* This file is part of Chevereto.
*
* (c) Rodolfo Berrios <rodolfo@chevereto.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Chevereto\Legacy\Classes\Cache;
use Chevereto\Legacy\Classes\Categories;
use Chevereto\Legacy\Classes\Tags;
use function Chevereto\Legacy\G\format_bytes;
if (! Cache::isEnabled()) {
echo "[ERROR] Cache is not enabled\n";
exit(255);
}
$keyValue = Cache::instance();
$redis = $keyValue->redis();
$prefix = $keyValue->getKey('');
$topLevel = [
'pages_visible',
'settings',
'variables',
Categories::CACHE_KEY,
Tags::CACHE_KEY,
];
foreach ($topLevel as $topKey) {
$cacheKey = $prefix . $topKey;
deleteCache($redis, $cacheKey);
}
$nested = [
'ip',
'l',
'rl',
'u',
];
foreach ($nested as $nestedKey) {
$iterator = null;
while ($iterator !== 0) {
$scanKeys = $keyValue->redis()->scan($iterator, "{$prefix}{$nestedKey}:*");
foreach ($scanKeys as $scanKey) {
deleteCache($redis, $scanKey);
}
}
}
function deleteCache(Redis $redis, string $key): void
{
$exists = $redis->exists($key);
if (! $exists) {
printf(
"| %-60s | %-12s | %-8s |\n",
$key,
'--',
'--'
);
return;
}
$ttl = $redis->ttl($key);
if ($ttl === -1) {
$ttlStr = 'no-expire';
} elseif ($ttl === -2) {
$ttlStr = 'expired';
} else {
$ttlStr = $ttl;
}
$bytes = $redis->rawCommand('MEMORY', 'USAGE', $key);
$sizeReadable = format_bytes($bytes);
printf(
"| %-60s | %-12s | %-8s |\n",
$key,
$ttlStr,
$sizeReadable
);
}

View File

@@ -40,10 +40,11 @@ if (getSetting('maintenance')) {
exit(255);
}
$jobs = [
'deleteExpiredImages',
'deleteExpiredFiles',
'cleanUnconfirmedUsers',
'removeDeleteLog',
'storageDelete',
'deleteExpiredUploads',
];
if ((bool) env()['CHEVERETO_ENABLE_UPDATE_CHECK']) {
$jobs[] = 'checkForUpdates';
@@ -152,9 +153,9 @@ function storageDelete(): void
}
echoLocked($job);
}
function deleteExpiredImages(): void
function deleteExpiredFiles(): void
{
$job = 'delete-expired-images';
$job = 'delete-expired-files';
$lock = new Lock($job);
if ($lock->create()) {
Image::deleteExpired(50);
@@ -241,3 +242,46 @@ function checkHtaccess()
{
include __DIR__ . '/htaccess-enforce.php';
}
function deleteExpiredUploads(): void
{
$job = 'delete-expired-uploads';
$lock = new Lock($job);
if ($lock->create()) {
$uploadsTable = DB::getTable('uploads');
$uploadsChunksTable = DB::getTable('uploads_chunks');
$db = DB::getInstance();
$db->query(
<<<MySQL
SELECT `upload_chunk_upload_id` `id`, `upload_chunk_index` `index`, `upload_chunk_path` path
FROM `{$uploadsChunksTable}` WHERE `upload_chunk_date_gmt` <= :time;
MySQL
);
$db->bind(':time', datetime_sub(datetimegmt(), 'P1D'));
$chunks = $db->fetchAll();
if (! $chunks) {
$lock->destroy();
return;
}
$ids = [];
foreach ($chunks as $chunk) {
$ids[] = (int) $chunk['id'];
$chunkPath = $chunk['path'];
if (file_exists($chunkPath)) {
unlink($chunkPath);
}
}
$ids = array_unique($ids);
$idsString = implode(',', $ids);
$db->query(
<<<MySQL
DELETE FROM `{$uploadsTable}` WHERE `upload_id` IN ({$idsString});
MySQL
);
$db->exec();
$lock->destroy();
return;
}
echoLocked($job);
}

View File

@@ -15,4 +15,5 @@ if (cheveretoVersionInstalled() !== '') {
echo "[ERROR] Chevereto is already installed, try with the update command\n";
exit(255);
}
require_once PATH_APP_LEGACY_INSTALL . 'installer.php';

View File

@@ -9,9 +9,14 @@
* file that was distributed with this source code.
*/
use Symfony\Component\Process\Exception\ProcessFailedException;
use Symfony\Component\Process\Process;
use function Chevereto\Legacy\G\str_replace_last;
$workingDir = PATH_PUBLIC_CONTENT_LEGACY_THEMES_PEAFOWL_LIB;
$target = 'chevereto-all.js';
$outputFile = $workingDir . $target;
$outputMinifiedFile = $workingDir . str_replace_last('.js', '.min.js', $target);
echo "* Compile JavaScript\n";
echo "---\n";
$fh = fopen($outputFile, 'w');
@@ -23,6 +28,7 @@ $files = [
'js/peafowl.js',
'js/images-loaded.js',
'js/load-image.js',
'js/xxhash-wasm.js',
'js/clipboard.js',
'js/chevereto.js',
];
@@ -37,5 +43,19 @@ foreach ($files as $file) {
}
fclose($fh);
echo "---\n";
echo "💯 [OK] {$outputFile}\n";
echo "[OK] {$outputFile}\n";
$process = new Process([
'uglifyjs',
$outputFile,
'-o',
$outputMinifiedFile,
'-c',
'-m',
]);
$process->run();
if (! $process->isSuccessful()) {
throw new ProcessFailedException($process);
}
echo "[OK] {$outputMinifiedFile}\n";
exit(0);

View File

@@ -15,4 +15,5 @@ if (cheveretoVersionInstalled() === '') {
echo "[ERROR] Chevereto is not installed, try with the install command.\n";
exit(255);
}
require_once PATH_APP_LEGACY_INSTALL . 'installer.php';

View File

@@ -9,6 +9,7 @@
* file that was distributed with this source code.
*/
use Chevere\ThrowableHandler\ThrowableHandler;
use function Chevereto\Legacy\getCheveretoEnv;
use function Chevereto\Legacy\loaderHandler;
@@ -24,27 +25,34 @@ if ($opts === []) {
}
$access = $opts['C'];
$options = [
'bulk-importer',
'cache-view',
'cache-flush',
'cron',
'update',
'encrypt-secrets',
'decrypt-secrets',
'encrypt-secrets',
'htaccess-checksum',
'htaccess-enforce',
'bulk-importer',
'install',
'langs',
'js',
'langs',
'password-reset',
'setting-get',
'setting-update',
'update',
'version',
];
if (! in_array($access, $options, true)) {
echo 'Invalid command' . PHP_EOL;
exit(255);
}
if (defined('APP_BIN_LEGACY')) {
echo 'Note: This CLI is migrating to app/bin/cli' . PHP_EOL . PHP_EOL;
}
define('ACCESS', $access);
require_once __DIR__ . '/../load/php-boot.php';
set_error_handler(ThrowableHandler::ERROR_AS_EXCEPTION);
set_exception_handler(ThrowableHandler::CONSOLE);
require_once loaderHandler(
$_COOKIE,
getCheveretoEnv(),

File diff suppressed because it is too large Load Diff

View File

@@ -9,5 +9,5 @@
* file that was distributed with this source code.
*/
const APP_VERSION = '4.2.5';
const APP_VERSION_AKA = 'regio';
const APP_VERSION = '4.3.0';
const APP_VERSION_AKA = 'entrador';

View File

@@ -90,9 +90,28 @@ set_exception_handler(function (Throwable $throwable) {
? 1
: (int) $envDebugLevel;
}
$doDebug = in_array($debugLevel, [2, 3], true) || isDebug();
$publicHandler = $publicHandler->withIsDebug($doDebug);
$internalHandler = $publicHandler->withIsDebug(true);
$doDebug = in_array($debugLevel, [2, 3], true) || isDebug();
if ($doDebug === false) {
$publicHandler = $publicHandler
->withIsDebug($doDebug)
->withPutExtra(
'Why am I seeing this?',
<<<HTML
For security reasons, detailed error information is not shown. This incident has been logged and will be reviewed by the system administrator.
HTML
)
->withPutExtra(
'Administrator guide',
<<<HTML
<ul>
<li>Refer to the <a href="https://v4-docs.chevereto.com/developer/how-to/debug" target="_blank">Chevereto documentation</a> to understand how to debug this error.</li>
<li>Need help? Visit <a href="https://chevereto.com/support" target="_blank">Chevereto support</a> to open a ticket.</li>
</ul>
<style>.administrator-guide ul{margin:0;padding-left:1.5em}</style>
HTML
);
}
$method = server()['REQUEST_METHOD'] ?? '';
$uri = server()['REQUEST_URI'] ?? '';
$uri = strtok($uri, '?');

View File

@@ -10,7 +10,8 @@
*/
use Chevereto\Config\Config;
use Chevereto\Legacy\Classes\DB;
use Chevereto\Legacy\Classes\Cache;
use Chevereto\Legacy\Classes\Categories;
use Chevereto\Legacy\Classes\Fonts;
use Chevereto\Legacy\Classes\IpBan;
use Chevereto\Legacy\Classes\L10n;
@@ -19,7 +20,7 @@ use Chevereto\Legacy\Classes\Page;
use Chevereto\Legacy\Classes\Palettes;
use Chevereto\Legacy\Classes\RequestLog;
use Chevereto\Legacy\Classes\Settings;
use Chevereto\Legacy\Classes\Tag;
use Chevereto\Legacy\Classes\Tags;
use Chevereto\Legacy\Classes\User;
use Chevereto\Legacy\G\Handler;
use function Chevereto\Legacy\badgePaid;
@@ -52,31 +53,19 @@ if (cheveretoVersionInstalled() === '') {
loadTemplate: ! REPL, // @phpstan-ignore-line
before: function ($handler) {
headersNoCache();
if ($handler->request_array()[0] !== 'install') {
if ($handler->requestArray()[0] !== 'install') {
redirect('install', 302);
}
},
);
}
$bannedIp = IpBan::getSingle();
if ($bannedIp !== []) {
headersNoCache();
// TODO: Cache until ban expires
if (is_url($bannedIp['message'] ?? false)) {
redirect($bannedIp['message'], 301);
} else {
$exitMessage = $bannedIp['message'] ?? '';
$exitMessage = match ($exitMessage) {
'' => _s('You have been forbidden to use this website.'),
default => $bannedIp['message'],
};
exit($exitMessage);
}
}
$hook_before = function (Handler $handler) {
header('Permissions-Policy: unload=()');
header('Permissions-Policy: interest-cohort=()');
header("Content-Security-Policy: frame-ancestors 'none'");
$dayCacheRoutes = [
'webmanifest',
];
$exitEarlyRoutes = [
'webmanifest',
];
@@ -96,17 +85,46 @@ $hook_before = function (Handler $handler) {
'settings',
'redirect',
];
$doNotCheckBanRoutes = [
'webmanifest',
];
if (! in_array($handler->requestArray()[0], $doNotCheckBanRoutes, true)) {
$bannedIp = IpBan::getSingle();
if ($bannedIp !== []) {
headersNoCache();
// TODO: Cache until ban expires
if (is_url($bannedIp['message'] ?? false)) {
redirect($bannedIp['message'], 301);
} else {
$exitMessage = $bannedIp['message'] ?? '';
$exitMessage = match ($exitMessage) {
'' => _s('You have been forbidden to use this website.'),
default => $bannedIp['message'],
};
exit($exitMessage);
}
}
}
$cache_ttl = (int) max(0, getSetting('cache_ttl') ?? 0);
if (in_array($handler->request_array()[0], $doNotCacheRoutes, true)) {
if (in_array($handler->requestArray()[0], $dayCacheRoutes, true)) {
$cache_ttl = 86400; // 1 day
}
if (in_array($handler->requestArray()[0], $doNotCacheRoutes, true)) {
headersNoCache();
} elseif ($cache_ttl > 0) {
headersResetCache();
header("Cache-Control: private, max-age={$cache_ttl}");
}
if (in_array($handler->request_array()[0], $exitEarlyRoutes, true)) {
if (in_array($handler->requestArray()[0], $exitEarlyRoutes, true)) {
return;
}
$failed_access_requests = RequestLog::getCounts(['login', 'signup'], 'fail');
$failTriggers = [
'account-password-forgot',
'account-two-factor',
'login',
'signup',
];
$failed_access_requests = RequestLog::getCounts($failTriggers, 'fail');
if (is_max_invalid_request($failed_access_requests['day'])) {
set_status_header(403);
} else {
@@ -119,9 +137,9 @@ $hook_before = function (Handler $handler) {
if (Login::getUser()['status'] === 'banned') {
set_status_header(403);
}
if (sessionVar()->hasKey('challenge_two_factor')
if (sessionVar()->has('challenge_two_factor')
&& ! in_array($handler->getRoutePath(), ['account/two-factor', 'captcha-verify', 'logout'], true)
&& $handler->request_array()[0] !== 'page'
&& $handler->requestArray()[0] !== 'page'
) {
headersNoCache();
redirect('account/two-factor', 302);
@@ -138,9 +156,10 @@ $hook_before = function (Handler $handler) {
);
if (http_response_code() === 403) {
headersNoCache();
echo '403 Forbidden';
exit();
}
if ($handler->request_array()[0] !== 'api'
if ($handler->requestArray()[0] !== 'api'
&& Settings::get('enable_uploads_url') && ! Login::isAdmin()) {
Settings::setValue('enable_uploads_url', 0);
}
@@ -212,10 +231,10 @@ $hook_before = function (Handler $handler) {
$handler::setVar('fonts', $fonts);
$fontId = intval(getSetting('theme_font') ?? 0);
$handler::setVar('theme_font', $fontId);
if (in_array($handler->request_array()[0], ['login', 'signup', 'account'], true)) {
if (in_array($handler->requestArray()[0], ['login', 'signup', 'account'], true)) {
$paletteId = 0;
} else {
$paletteId = Login::isLoggedUser()
$paletteId = Login::isLoggedUser() & Settings::get('theme_palette_user_select')
? Login::getUser()['palette_id']
: Settings::get('theme_palette');
}
@@ -227,7 +246,7 @@ $hook_before = function (Handler $handler) {
$handler::setVar('theme_palette', $paletteId);
$handler::setVar('theme_palette_handle', $theme_palette_handle);
if ($handler::cond('maintenance')
&& $handler->request_array()[0] === 'dashboard') {
&& $handler->requestArray()[0] === 'dashboard') {
headersNoCache();
redirect('login', 302);
}
@@ -273,24 +292,24 @@ $hook_before = function (Handler $handler) {
$userMapPaths[] = getSetting('user_profile_view') === 'files'
? 'albums'
: 'files';
if ($handler->request_array()[0] === '/'
if ($handler->requestArray()[0] === '/'
&& getSetting('website_mode_personal_routing') === '/'
&& in_array(key($querystr), ['random'], true)
) {
$handler->mapRoute('index');
} elseif ($handler->request_array()[0] === 'search'
&& in_array($handler->request_array()[1] ?? [], ['images', 'albums', 'users'], true)
} elseif ($handler->requestArray()[0] === 'search'
&& in_array($handler->requestArray()[1] ?? [], ['images', 'albums', 'users'], true)
) {
$handler->mapRoute('search');
} elseif ($handler->request_array()[0] === getSetting('website_mode_personal_routing')
} elseif ($handler->requestArray()[0] === getSetting('website_mode_personal_routing')
|| (getSetting('website_mode_personal_routing') === '/'
&& in_array($handler->request_array()[0], $userMapPaths, true))
&& in_array($handler->requestArray()[0], $userMapPaths, true))
) {
$handler->mapRoute('user', [
'id' => getSetting('website_mode_personal_uid'),
]);
}
if ($handler->request_array()[0] === '/'
if ($handler->requestArray()[0] === '/'
&& ! in_array(key($querystr), ['random', 'lang'], true)
&& ! $handler::cond('mapped_route')
) {
@@ -315,17 +334,17 @@ $hook_before = function (Handler $handler) {
}
}
} else {
if ($base !== 'index' and ! is_route_available($handler->request_array()[0])) {
if ($base !== 'index' and ! is_route_available($handler->requestArray()[0])) {
$mapTo = getSetting('root_route');
$handler->mapRoute($mapTo);
}
}
$virtual_routes = ['image', 'album', 'user', 'video', 'audio'];
if (in_array($handler->request_array()[0], $virtual_routes, true)) {
$virtual_route = getSetting('route_' . $handler->request_array()[0]);
if ($handler->request_array()[0] !== $virtual_route) {
if (in_array($handler->requestArray()[0], $virtual_routes, true)) {
$virtual_route = getSetting('route_' . $handler->requestArray()[0]);
if ($handler->requestArray()[0] !== $virtual_route) {
$virtualized_url = str_replace(
get_base_url($handler->request_array()[0]),
get_base_url($handler->requestArray()[0]),
get_base_url($virtual_route),
get_current_url()
);
@@ -334,9 +353,9 @@ $hook_before = function (Handler $handler) {
return;
}
}
if ($base !== 'index' && ! is_route_available($handler->request_array()[0])) {
if ($base !== 'index' && ! is_route_available($handler->requestArray()[0])) {
foreach ($virtual_routes as $k) {
if ($handler->request_array()[0] === getSetting('route_' . $k)) {
if ($handler->requestArray()[0] === getSetting('route_' . $k)) {
$handler->mapRoute($k);
}
}
@@ -352,7 +371,7 @@ $hook_before = function (Handler $handler) {
if (getSetting('enable_signups')) {
$allowed_requests[] = 'signup';
}
if (! in_array($handler->request_array()[0], $allowed_requests, true)) {
if (! in_array($handler->requestArray()[0], $allowed_requests, true)) {
headersNoCache();
redirect('login', 302);
}
@@ -400,43 +419,13 @@ $hook_before = function (Handler $handler) {
}
$handler::setCond('moderate_uploads', $moderate_uploads);
$categories = [];
$tags_top = [];
$tagsTop = [];
if ($handler::cond('explore_enabled') || $base === 'dashboard') {
try {
$categories_db = DB::queryFetchAll(
'SELECT * FROM '
. DB::getTable('categories')
. ' ORDER BY category_name ASC;'
);
foreach ($categories_db as $k => $v) {
$key = $v['category_id'];
$categories[$key] = $v;
$categories[$key]['category_url'] = get_base_url('category/' . $v['category_url_key']);
$categories[$key] = DB::formatRow($categories[$key]);
}
} catch (Throwable) {
}
try {
$tagsTable = DB::getTable('tags');
$tags_db = DB::queryFetchAll(
<<<MYSQL
SELECT t.tag_name name, t.tag_id id, t.tag_files files, t.tag_views views
FROM `{$tagsTable}` t
ORDER BY `tag_files` DESC, `tag_name` ASC
LIMIT 30;
MYSQL
);
foreach ($tags_db as $k => $v) {
$tag = array_merge($v, Tag::row($v['name']));
$tags_top[] = $tag;
}
} catch (Throwable) {
}
$categories = Categories::get();
$tagsTop = Tags::top();
}
$handler::setVar('categories', $categories);
$handler::setVar('tags_top', $tags_top);
$handler::setVar('tags_top', $tagsTop);
$explore_discovery = [
'recent' => [
'label' => _s('Recent'),
@@ -497,49 +486,66 @@ $hook_before = function (Handler $handler) {
$handler::setVar('explore_discovery', $explore_discovery);
$handler::setVar('explore_content', $explore_content);
$versionInstalled = cheveretoVersionInstalled();
$pages_visible = [];
$pages_link_visible = [];
if (version_compare($versionInstalled, '3.6.7', '>=')) {
$pages_visible_db = Page::getAll(
args: [
'is_active' => '1',
'is_link_visible' => '1',
],
sort: [
'field' => 'sort_display',
'order' => 'ASC',
]
);
$pos_page_tos = array_search('tos', array_column($pages_visible_db, 'internal'));
$pos_page_privacy = array_search('privacy', array_column($pages_visible_db, 'internal'));
$page_tos = $pos_page_tos === false
? null
: $pages_visible_db[$pos_page_tos];
$page_privacy = $pos_page_privacy === false
? null
: $pages_visible_db[$pos_page_privacy];
$handler::setVar('page_tos', $page_tos);
$handler::setVar('page_privacy', $page_privacy);
$cachedPagesVisibleRows = Cache::instance()->get('pages_visible');
if ($cachedPagesVisibleRows === false) {
$pagesVisibleRows = Page::getAll(
args: [
'is_active' => '1',
'is_link_visible' => '1',
],
sort: [
'field' => 'sort_display',
'order' => 'ASC',
]
);
$posPageTos = array_search('tos', array_column($pagesVisibleRows, 'internal'));
$posPagePrivacy = array_search('privacy', array_column($pagesVisibleRows, 'internal'));
Cache::instance()->set(
'pages_visible',
[
'rows' => $pagesVisibleRows,
'pos_page_tos' => $posPageTos,
'pos_page_privacy' => $posPagePrivacy,
],
3600
);
} else {
$pagesVisibleRows = $cachedPagesVisibleRows['rows'] ?? [];
$posPageTos = $cachedPagesVisibleRows['pos_page_tos'] ?? false;
$posPagePrivacy = $cachedPagesVisibleRows['pos_page_privacy'] ?? false;
}
$pageTos = $posPageTos === false ? null : $pagesVisibleRows[$posPageTos];
$pagePrivacy = $posPagePrivacy === false ? null : $pagesVisibleRows[$posPagePrivacy];
$handler::setVar('page_tos', $pageTos);
$handler::setVar('page_privacy', $pagePrivacy);
}
if ((bool) env()['CHEVERETO_ENABLE_PAGES']) {
foreach ($pages_visible_db ?? [] as $k => $v) {
foreach ($pagesVisibleRows ?? [] as $k => $v) {
if (! ($v['is_active'] ?? false) && ! ($v['is_link_visible'] ?? false)) {
continue;
}
$pages_visible[$v['id']] = $v;
$pages_link_visible[$v['id']] = $v;
}
}
$api_page = [
'type' => 'link',
'link_url' => get_base_url('api-v1'),
'icon' => 'fas fa-project-diagram',
'title' => 'API',
'is_active' => 1,
'is_link_visible' => 1,
'attr_target' => '_self',
'sort_display' => -2,
];
Page::fill($api_page);
$pages_visible[] = $api_page;
$apiEnabled = ((bool) env()['CHEVERETO_ENABLE_API_USER'] || (bool) env()['CHEVERETO_ENABLE_API_GUEST'])
&& (getSetting('enable_api_user') || getSetting('enable_api_guest'));
$handler::setCond('api_enabled', $apiEnabled);
if ($apiEnabled) {
$api_page = [
'type' => 'link',
'link_url' => get_base_url('api-v1'),
'icon' => 'fas fa-project-diagram',
'title' => 'API',
'is_active' => 1,
'is_link_visible' => 1,
'attr_target' => '_self',
'sort_display' => -2,
];
Page::fill($api_page);
$pages_link_visible[] = $api_page;
}
if (getSetting('enable_plugin_route')) {
$plugin_page = [
'type' => 'link',
@@ -552,12 +558,12 @@ $hook_before = function (Handler $handler) {
'sort_display' => -1,
];
Page::fill($plugin_page);
$pages_visible[] = $plugin_page;
$pages_link_visible[] = $plugin_page;
}
uasort($pages_visible, function ($a, $b) {
uasort($pages_link_visible, function ($a, $b) {
return $a['sort_display'] - $b['sort_display'];
});
$handler::setVar('pages_link_visible', $pages_visible);
$handler::setVar('pages_link_visible', $pages_link_visible);
$upload_enabled = Login::isAdmin() ?: getSetting('enable_uploads');
$upload_allowed = $upload_enabled;
if (! Login::getUser()) {
@@ -576,7 +582,7 @@ $hook_before = function (Handler $handler) {
Settings::setValue('upload_max_filesize_mb', getSetting('upload_max_filesize_mb_guest'));
}
if ($upload_allowed
&& in_array($handler->request_array()[0], ['login', 'signup', 'account'], true)
&& in_array($handler->requestArray()[0], ['login', 'signup', 'account'], true)
) {
$upload_allowed = false;
}
@@ -585,7 +591,7 @@ $hook_before = function (Handler $handler) {
if ($handler::cond('maintenance') || $handler::cond('show_consent_screen')) {
$handler::setCond('private_gate', true);
$allowed_requests = ['login', 'account', 'connect', 'captcha-verify', 'oembed'];
if (! in_array($handler->request_array()[0], $allowed_requests, true)) {
if (! in_array($handler->requestArray()[0], $allowed_requests, true)) {
$handler->preventRoute($handler::cond('show_consent_screen') ? 'consent-screen' : 'maintenance');
}
}
@@ -602,7 +608,7 @@ $hook_before = function (Handler $handler) {
'webmanifest',
'tag-autocomplete',
];
if (! in_array($handler->request_array()[0], $excludeLastUrl, true)) {
if (! in_array($handler->requestArray()[0], $excludeLastUrl, true)) {
sessionVar()->put('last_url', get_current_url());
}
$detect = new Mobile_Detect();
@@ -627,12 +633,12 @@ $hook_before = function (Handler $handler) {
};
$hook_after = function (Handler $handler) {
if (array_key_exists('deleted', get())
&& in_array($handler->template(), ['user', 'album'], true)
&& in_array($handler->template(), ['user', 'album'], true)
) {
set_status_header(303);
}
if ($handler->template() === '404') {
if (sessionVar()->hasKey('last_url')) {
if (sessionVar()->has('last_url')) {
sessionVar()->remove('last_url');
}
$handler::setVar('doctitle', _s("That page doesn't exist") . ' (404) - ' . getSetting('website_name'));

View File

@@ -89,7 +89,7 @@ return function (Handler $handler) {
if (! TwoFactor::hasFor($logged_user['id'])) {
redirect('settings/security', 302);
}
if (! sessionVar()->hasKey('challenge_two_factor')) {
if (! sessionVar()->has('challenge_two_factor')) {
redirect($logged_user['url'] ?? '', 302);
}

View File

@@ -368,7 +368,7 @@ return function (Handler $handler) {
$handler::setVar('meta_description', $meta_description);
if ($handler::cond('content_manager') || $is_owner) {
$handler::setVar('user_items_editor', [
'user_albums' => User::getAlbums((int) $album['user']['id']),
'user_albums' => User::getAlbums($album['user']),
'type' => $type,
]);
}

View File

@@ -12,7 +12,7 @@
use Chevereto\Legacy\G\Handler;
return function (Handler $handler) {
if ($handler->isRequestLevel(2)) {
if (! $handler::cond('api_enabled') || $handler->isRequestLevel(2)) {
$handler->issueError(404);
return;

View File

@@ -44,6 +44,12 @@ use function Chevereto\Vars\request;
use function Chevereto\Vars\server;
return function (Handler $handler) {
if (! $handler::cond('api_enabled')) {
$handler->issueError(404);
return;
}
try {
$user = [];
$REQUEST = request();

View File

@@ -12,7 +12,10 @@
use Chevereto\Config\Config;
use Chevereto\Legacy\Classes\Akismet;
use Chevereto\Legacy\Classes\AssetStorage;
use Chevereto\Legacy\Classes\Cache;
use Chevereto\Legacy\Classes\DB;
use Chevereto\Legacy\Classes\ExifTool;
use Chevereto\Legacy\Classes\ExifTran;
use Chevereto\Legacy\Classes\Image;
use Chevereto\Legacy\Classes\L10n;
use Chevereto\Legacy\Classes\Listing;
@@ -45,7 +48,6 @@ use function Chevereto\Legacy\G\fetch_url;
use function Chevereto\Legacy\G\format_bytes;
use function Chevereto\Legacy\G\get_app_version;
use function Chevereto\Legacy\G\get_base_url;
use function Chevereto\Legacy\G\get_bytes;
use function Chevereto\Legacy\G\get_client_ip;
use function Chevereto\Legacy\G\get_ffmpeg_error;
use function Chevereto\Legacy\G\get_ini_bytes;
@@ -133,6 +135,18 @@ return function (Handler $handler) {
return;
}
$request = implode('/', $handler->request());
$redirects = [
'settings/external-storage' => 'dashboard/settings/upload-storage',
'settings/asset-storage' => 'dashboard/settings/site-storage',
'settings/guest-api' => 'dashboard/settings/api',
];
$redirectTo = $redirects[$request] ?? null;
if ($redirectTo) {
redirect($redirectTo);
return;
}
$route_prefix = 'dashboard';
$routes = [
'stats' => _s('Home'),
@@ -178,6 +192,7 @@ return function (Handler $handler) {
'tags' => 'fas fa-tags',
];
$settings_sections = [
'api' => 'API',
'website' => _s('Website'),
'content' => _s('Content'),
'listings' => _s('Listings'),
@@ -190,14 +205,13 @@ return function (Handler $handler) {
'email' => _s('Email'),
'tools' => _s('Tools'),
'logo' => _s('Logo'),
'asset-storage' => _s('Asset storage'),
'external-storage' => _s('External storage'),
'site-storage' => _s('Site storage'),
'upload-storage' => _s('Upload storage'),
'upload-plugin' => _s('Upload plugin'),
'homepage' => _s('Homepage'),
'pages' => _s('Pages'),
'consent-screen' => _s('Consent screen'),
'users' => _n('User', 'Users', 20),
'guest-api' => _s('Guests %s', 'API'),
'login-providers' => _s('Login providers'),
'routing' => _s('Routing'),
'external-services' => _s('External services'),
@@ -218,11 +232,11 @@ return function (Handler $handler) {
'cookie-compliance' => 'fas fa-cookie-bite',
'email' => 'fas fa-at',
'external-services' => 'fas fa-concierge-bell',
'asset-storage' => 'fas fa-warehouse',
'external-storage' => 'fas fa-hdd',
'site-storage' => 'fas fa-warehouse',
'upload-storage' => 'fas fa-hdd',
'file-uploads' => 'fas fa-cloud-upload-alt',
'flood-protection' => 'fas fa-faucet',
'guest-api' => 'fas fa-project-diagram',
'api' => 'fas fa-project-diagram',
'homepage' => 'fas fa-home',
'ip-bans' => 'fas fa-ban',
'languages' => 'fas fa-language',
@@ -246,7 +260,6 @@ return function (Handler $handler) {
'cookie-compliance' => ['pro', 'CHEVERETO_ENABLE_COOKIE_COMPLIANCE'],
'external-services' => ['pro', 'CHEVERETO_ENABLE_EXTERNAL_SERVICES'],
'flood-protection' => ['pro', 'CHEVERETO_ENABLE_UPLOAD_FLOOD_PROTECTION'],
'guest-api' => ['lite', 'CHEVERETO_ENABLE_API_GUEST'],
'homepage' => ['lite', 'CHEVERETO_ENABLE_USERS'],
'ip-bans' => ['pro', 'CHEVERETO_ENABLE_IP_BANS'],
'login-providers' => ['lite', 'CHEVERETO_ENABLE_LOGIN_PROVIDERS'],
@@ -425,68 +438,10 @@ return function (Handler $handler) {
$cronRemark .= ' — <span class="color-fail"><span class="fas fa-exclamation-triangle"></span> ' . _s('not running') . '</span>';
}
if ((env()['CHEVERETO_SERVICING'] ?? null) === 'docker') {
$cronRemark .= '<div><code class="code code--inline-auto code--command" data-click="select-all">docker exec -it --user www-data ' . (gethostname() ?: 'chv-container') . ' app/bin/legacy -C cron</code></div>';
$cronRemark .= '<div><code class="code code--inline-auto code--command" data-click="select-all">docker exec -it --user www-data ' . (gethostname() ?: 'chv-container') . ' app/bin/cli -C cron</code></div>';
$errorLogRemark .= '<div><code class="code code--inline-auto code--command" data-click="select-all">docker logs ' . (gethostname() ?: 'chv-container') . ' -f 1>/dev/null</code></div>';
}
}
$ffmpegContent = '<i class="fas fa-video"></i> ';
try {
$missing = [
'proc_open' => ! function_exists('proc_open'),
'proc_close' => ! function_exists('proc_close'),
];
$missing = array_filter($missing);
if ($missing) {
throw new Exception(
_s(
'PHP function [%s] not available in this PHP installation',
implode(', ', array_keys($missing))
)
);
}
$ffmpegErrors = [];
try {
$ffmpeg = FFMpeg::create(
[
'ffmpeg.binaries' => env()['CHEVERETO_BINARY_FFMPEG'],
'ffprobe.binaries' => env()['CHEVERETO_BINARY_FFPROBE'],
]
);
} catch (Throwable $e) {
$ffmpegErrors[] = get_ffmpeg_error($e);
}
try {
$ffprobe = FFProbe::create(
[
'ffprobe.binaries' => env()['CHEVERETO_BINARY_FFPROBE'],
]
);
$ffprobe->getFFProbeDriver()->getName();
} catch (Throwable $e) {
$ffmpegErrors[] = get_ffmpeg_error($e);
}
if ($ffmpegErrors !== []) {
throw new Exception(implode(', ', $ffmpegErrors));
}
$ffmpegContent .= 'FFmpeg';
if (isset($ffmpeg) && env()['CHEVERETO_CONTEXT'] !== 'saas') {
$ffmpegContent .= ' bin: '
. env()['CHEVERETO_BINARY_FFMPEG']
. ' version '
. $ffmpeg->getFFMpegDriver()->getVersion()
. '<br>'
. '<i class="fas fa-circle-check"></i> FFprobe bin:'
. env()['CHEVERETO_BINARY_FFPROBE'];
}
} catch (Throwable $e) {
$ffmpegContent = '<span class="color-fail"><i class="fas fa-warning"></i> Error: '
. get_ffmpeg_error($e)
. '</span>';
}
$chv_versioning = explode('.', APP_VERSION);
$chv_version_major = $chv_versioning[0] . '.X';
$chv_version_minor = $chv_versioning[0] . '.' . $chv_versioning[1];
@@ -501,17 +456,10 @@ return function (Handler $handler) {
. '<div class="margin-bottom-20">' . $version_check . $linksButtons . '</div>
</div>',
],
'max_upload_size' => [
'upload_max_filesize' => [
'label' => _s('Max. upload file size'),
'content' => '<i class="fas fa-cloud-upload-alt"></i> ' . format_bytes(get_ini_bytes(ini_get('upload_max_filesize'))),
],
'graphics' => [
'label' => _s('Graphics library'),
],
'video' => [
'label' => _s('Video processing'),
'content' => $ffmpegContent,
],
'rebuild_stats' => [
'label' => _s('Stats'),
'content' => '<a data-action="dashboardTool" data-tool="rebuildStats"><span class="fas fa-sync-alt margin-right-5"></span>' . _s('Rebuild stats') . '</a>',
@@ -572,11 +520,113 @@ return function (Handler $handler) {
'%label%' => $link['label'],
]);
}
if (env()['CHEVERETO_CONTEXT'] !== 'saas') {
$ffmpegContent = '<i class="fas fa-video"></i> ';
try {
$missing = [
'proc_open' => ! function_exists('proc_open'),
'proc_close' => ! function_exists('proc_close'),
];
$missing = array_filter($missing);
if ($missing) {
throw new Exception(
_s(
'PHP function [%s] not available in this PHP installation',
implode(', ', array_keys($missing))
)
);
}
$ffmpegErrors = [];
try {
$ffmpeg = FFMpeg::create(
[
'ffmpeg.binaries' => env()['CHEVERETO_BINARY_FFMPEG'],
// 'ffprobe.binaries' => env()['CHEVERETO_BINARY_FFPROBE'],
]
);
} catch (Throwable $e) {
$ffmpegErrors[] = get_ffmpeg_error($e);
}
try {
$ffprobe = FFProbe::create(
[
'ffprobe.binaries' => env()['CHEVERETO_BINARY_FFPROBE'],
]
);
$ffprobe->getFFProbeDriver()->getName();
} catch (Throwable $e) {
$ffmpegErrors[] = get_ffmpeg_error($e);
}
if ($ffmpegErrors !== []) {
throw new Exception(implode('<br>', $ffmpegErrors));
}
$ffmpegContent .= 'FFmpeg';
if (isset($ffmpeg) && env()['CHEVERETO_CONTEXT'] !== 'saas') {
$ffmpegContent .= ' bin: '
. env()['CHEVERETO_BINARY_FFMPEG']
. ' version '
. $ffmpeg->getFFMpegDriver()->getVersion()
. '<br>'
. '<i class="fas fa-circle-check"></i> FFprobe bin: '
. env()['CHEVERETO_BINARY_FFPROBE'];
}
} catch (Throwable $e) {
$ffmpegContent = '<span class="color-fail"><i class="fas fa-warning"></i> Error: '
. get_ffmpeg_error($e)
. '</span>';
}
$graphicsLibraryContent = '<i class="fas fa-feather"></i> ';
if (ImageManagerStatic::getManager()->config['driver'] === 'imagick') {
$graphicVersion = Imagick::getVersion()['versionString'];
$graphicsLibraryContent .= $graphicVersion;
} else {
$graphicVersion = 'GD Version ' . gd_info()['GD Version'];
$graphicsLibraryContent .= $graphicVersion
. ' JPEG:' . gd_info()['JPEG Support']
. ' GIF:' . gd_info()['GIF Read Support'] . '/' . gd_info()['GIF Create Support']
. ' PNG:' . gd_info()['PNG Support']
. ' WEBP:' . (gd_info()['WebP Support'] ?? 0)
. ' WBMP:' . gd_info()['WBMP Support']
. ' XBM:' . gd_info()['XBM Support'];
}
$exifToolBinary = env()['CHEVERETO_BINARY_EXIFTOOL'] ?? '';
$exifToolContent = '<i class="fas fa-camera"></i> ExifTool';
if ($exifToolBinary !== '') {
$exifToolContent .= ' bin: ' . $exifToolBinary;
try {
$exifTool = new ExifTool(env()['CHEVERETO_BINARY_EXIFTOOL']);
$exifToolContent .= ' version ' . $exifTool->version();
} catch (RuntimeException $e) {
$exifToolContent .= ' <span class="color-fail"><i class="fas fa-warning"></i> ' . $e->getMessage() . '</span>';
}
} else {
$exifToolContent .= ' <span class="color-fail"><i class="fas fa-warning"></i> ' . _s('Not available') . '</span>';
}
$exifTranBinary = env()['CHEVERETO_BINARY_EXIFTRAN'] ?? '';
$exifTranContent = '<i class="fas fa-camera"></i> ExifTran';
if ($exifTranBinary !== '') {
$exifTranContent .= ' bin: ' . $exifTranBinary;
try {
new ExifTran($exifTranBinary);
} catch (RuntimeException $e) {
$exifTranContent .= ' <span class="color-fail"><i class="fas fa-warning"></i> ' . $e->getMessage() . '</span>';
}
} else {
$exifTranContent .= ' <span class="color-fail"><i class="fas fa-warning"></i> ' . _s('Not available') . '</span>';
}
$mysqlVersion = $db->getAttr(PDO::ATTR_SERVER_VERSION);
$db->closeCursor();
$mysqlServerInfo = $db->getAttr(PDO::ATTR_SERVER_INFO);
$redisVersion = _s('Disabled');
if (Cache::isEnabled()) {
$redisInfo = Cache::instance()->redis()->info();
$redisVersion = 'Redis v' . $redisInfo['redis_version'];
}
$phpIniLoaded = php_ini_loaded_file();
$phpIniFiles = php_ini_scanned_files() ?: 'N/A';
$phpIniFiles = explode(',', $phpIniFiles);
@@ -594,7 +644,7 @@ return function (Handler $handler) {
],
'cli' => [
'label' => 'CLI',
'content' => '<i class="fas fa-terminal"></i> <span data-click="select-all">' . PATH_PUBLIC . 'app/bin/legacy</span>',
'content' => '<i class="fas fa-terminal"></i> <span data-click="select-all">' . PATH_PUBLIC . 'app/bin/cli</span>',
],
'cron' => [
'label' => _s('Cron last ran'),
@@ -626,6 +676,11 @@ return function (Handler $handler) {
. '<br>'
. $mysqlServerInfo,
],
'cache' => [
'label' => 'Cache',
'content' => '<i class="fas fa-database"></i> '
. $redisVersion,
],
'php_version' => [
'label' => _s('PHP version'),
'content' => '<span class="fab fa-php"></span> '
@@ -648,29 +703,26 @@ return function (Handler $handler) {
'label' => _s('Memory limit'),
'content' => '<i class="fas fa-memory"></i> ' . format_bytes(get_ini_bytes(ini_get('memory_limit'))),
],
'graphics' => [
'label' => _s('Graphics library'),
'content' => $graphicsLibraryContent,
],
'exiftool' => [
'label' => 'ExifTool',
'content' => $exifToolContent,
],
'exiftran' => [
'label' => 'ExifTran',
'content' => $exifTranContent,
],
'video' => [
'label' => _s('Video processing'),
'content' => $ffmpegContent,
],
];
$pos = array_search('max_upload_size', array_keys($system_values), true);
$pos = array_search('upload_max_filesize', array_keys($system_values), true);
array_splice($system_values, $pos, 0, $system_values_more);
}
$graphicsLibraryContent = '<i class="fas fa-feather"></i> ';
if (ImageManagerStatic::getManager()->config['driver'] === 'imagick') {
$graphicVersion = env()['CHEVERETO_CONTEXT'] === 'saas'
? 'ImageMagick'
: Imagick::getVersion()['versionString'];
$system_values['graphics']['content'] = $graphicsLibraryContent . $graphicVersion;
} else {
$graphicVersion = env()['CHEVERETO_CONTEXT'] === 'saas'
? 'GD '
: ('GD Version ' . gd_info()['GD Version']);
$system_values['graphics']['content'] = $graphicsLibraryContent . $graphicVersion
. ' JPEG:' . gd_info()['JPEG Support']
. ' GIF:' . gd_info()['GIF Read Support'] . '/' . gd_info()['GIF Create Support']
. ' PNG:' . gd_info()['PNG Support']
. ' WEBP:' . (gd_info()['WebP Support'] ?? 0)
. ' WBMP:' . gd_info()['WBMP Support']
. ' XBM:' . gd_info()['XBM Support'];
}
$handler::setVar('system_values', $system_values);
$handler::setVar('totals', $totals);
$handler::setVar('totals_display', $totals_display);
@@ -717,7 +769,7 @@ return function (Handler $handler) {
];
if ($current) {
$handler::setVar('settings', $settings_sections[$k]);
if (in_array($k, ['categories', 'ip-bans', 'external-storage'], true)) {
if (in_array($k, ['categories', 'ip-bans', 'upload-storage'], true)) {
$handler::setCond('show_submit', false);
}
}
@@ -727,6 +779,9 @@ return function (Handler $handler) {
return;
}
uasort($settings_sections, function ($a, $b) {
return strcoll($a['label'], $b['label']);
});
$handler::setVar('settings_menu', $settings_sections);
if (isset($handler->request()[1])) {
$requestSetting = $handler->request()[1];
@@ -791,7 +846,7 @@ return function (Handler $handler) {
break;
case 'external-storage':
case 'upload-storage':
$disk_used_all = Stat::getTotals()['disk_used'];
$disk_used_external = DB::queryFetchSingle('SELECT SUM(storage_space_used) space_used FROM ' . DB::getTable('storages') . ';')['space_used'];
$storage_usage = [
@@ -857,7 +912,7 @@ return function (Handler $handler) {
$page = Page::getSingle($handler->request()[3], 'id');
if ($page) {
// Workaround for default pages
if (starts_with('default/', $page['file_path'])) {
if (starts_with('default/', $page['file_path'] ?? '')) {
$page['file_path'] = null;
}
} else {
@@ -1060,9 +1115,11 @@ return function (Handler $handler) {
}
}
if (($handler->request()[1] ?? null) === 'pages') {
$page_file_path_clean = trim(sanitize_relative_path($POST['page_file_path']), '/');
$POST['page_file_path'] = str_replace('default/', '', $page_file_path_clean);
$POST['page_file_path_absolute'] = Page::getPath($POST['page_file_path']);
if (Config::enabled()->phpPages()) {
$page_file_path_clean = trim(sanitize_relative_path($POST['page_file_path']), '/');
$POST['page_file_path'] = str_replace('default/', '', $page_file_path_clean);
$POST['page_file_path_absolute'] = Page::getPath($POST['page_file_path']);
}
if (! filter_var($POST['page_sort_display'], FILTER_VALIDATE_INT)) {
$POST['page_sort_display'] = null;
}
@@ -1076,9 +1133,13 @@ return function (Handler $handler) {
$handler::updateVar('safe_post', [
'page_is_active' => $POST['page_is_active'],
'page_is_link_visible' => $POST['page_is_link_visible'],
'page_file_path_absolute' => $POST['page_file_path_absolute'],
// 'page_file_path_absolute' => $POST['page_file_path_absolute'],
]);
}
$mailApis = ['smtp'];
if (env()['CHEVERETO_SERVICING'] !== 'docker') {
$mailApis[] = 'mail';
}
$validations = [
'website_name' => [
'validate' => isset($POST['website_name']),
@@ -1166,7 +1227,7 @@ return function (Handler $handler) {
'error_msg' => _s('Invalid user id'),
],
'email_mode' => [
'validate' => isset($POST['email_mode']) && in_array($POST['email_mode'], ['smtp', 'mail'], true),
'validate' => isset($POST['email_mode']) && in_array($POST['email_mode'], $mailApis, true),
'error_msg' => _s('Invalid email mode'),
],
'email_smtp_server_port' => [
@@ -1249,10 +1310,6 @@ return function (Handler $handler) {
'validate' => isset($POST['page_type'], $POST['page_url_key']) && $POST['page_type'] === 'internal' ? preg_match('/^[\w\-\_\/]+$/', $POST['page_url_key']) : true,
'error_msg' => _s('Invalid URL key'),
],
'page_file_path' => [
'validate' => isset($POST['page_type'], $POST['page_file_path']) && $POST['page_type'] === 'internal' ? preg_match('/^[\w\-\_\/]+\.' . (Config::enabled()->phpPages() ? 'html|php' : 'html') . '$/', $POST['page_file_path']) : true,
'error_msg' => _s('Invalid file path'),
],
'page_link_url' => [
'validate' => isset($POST['page_type'], $POST['page_link_url']) && $POST['page_type'] === 'link' ? is_url_web($POST['page_link_url']) : true,
'error_msg' => _s('Invalid link URL'),
@@ -1308,6 +1365,12 @@ return function (Handler $handler) {
'error_msg' => _s('Invalid key'),
],
];
if (Config::enabled()->phpPages()) {
$validations['page_file_path'] = [
'validate' => isset($POST['page_type'], $POST['page_file_path']) && $POST['page_type'] === 'internal' ? preg_match('/^[\w\-\_\/]+\.html|php$/', $POST['page_file_path']) : true,
'error_msg' => _s('Invalid file path'),
];
}
$customRoutes = [];
foreach (['image', 'album', 'user'] as $test) {
$tryValue = $POST['route_' . $test] ?? null;
@@ -1389,8 +1452,6 @@ return function (Handler $handler) {
if (isset($POST[$k])) {
if (! is_numeric($POST[$k]) || $POST[$k] == 0) {
$error_max_filesize = _s('Invalid value');
} elseif (get_bytes($POST[$k] . 'MB') > Settings::get('true_upload_max_filesize')) {
$error_max_filesize = _s('Max. allowed %s', format_bytes(Settings::get('true_upload_max_filesize')));
}
$validations[$k] = [
'validate' => ! isset($error_max_filesize),
@@ -1736,15 +1797,17 @@ return function (Handler $handler) {
: null;
try {
Page::writePage([
'file_path' => $POST['page_file_path'],
'code' => $page_write_code,
]);
if ($handler->request()[2] === 'edit'
&& isset($page['file_path'])
&& ! hash_equals((string) $page['file_path'], (string) $POST['page_file_path'])
) {
unlinkIfExists(Page::getPath($page['file_path']));
if (Config::enabled()->phpPages()) {
Page::writePage([
'file_path' => $POST['page_file_path'],
'code' => $page_write_code,
]);
if ($handler->request()[2] === 'edit'
&& isset($page['file_path'])
&& ! hash_equals((string) $page['file_path'], (string) $POST['page_file_path'])
) {
unlinkIfExists(Page::getPath($page['file_path']));
}
}
if (isset($page['id'])) {
Page::update((int) $page['id'], [
@@ -1841,7 +1904,7 @@ return function (Handler $handler) {
}
$oldSettings = Settings::get();
if ($update_settings !== [] && Settings::update($update_settings)) {
new Settings();
new Settings(reCache: true);
$diffSettings = array_diff_key($oldSettings, Settings::get());
foreach ($diffSettings as $k => $v) {
Settings::setValue($k, $v);

View File

@@ -150,7 +150,7 @@ return function (Handler $handler) {
}
if (isset($image['user']['id'])
&& ($handler::cond('content_manager') || $is_owner)) {
$image['user']['albums'] = User::getAlbums((int) $image['user']['id']);
$image['user']['albums'] = User::getAlbums($image['user']);
}
$is_album_cover = false;
if (isset($image['album']['id'])) {

View File

@@ -14,6 +14,7 @@ use Chevereto\Config\Config;
use Chevereto\Legacy\Classes\Akismet;
use Chevereto\Legacy\Classes\Album;
use Chevereto\Legacy\Classes\ApiKey;
use Chevereto\Legacy\Classes\Categories;
use Chevereto\Legacy\Classes\Category;
use Chevereto\Legacy\Classes\DB;
use Chevereto\Legacy\Classes\Follow;
@@ -31,10 +32,12 @@ use Chevereto\Legacy\Classes\Stat;
use Chevereto\Legacy\Classes\Storage;
use Chevereto\Legacy\Classes\Tag;
use Chevereto\Legacy\Classes\TwoFactor;
use Chevereto\Legacy\Classes\Upload;
use Chevereto\Legacy\Classes\User;
use Chevereto\Legacy\G\Handler;
use Hybridauth\Hybridauth;
use function Chevere\Message\message;
use function Chevere\Standard\randomString;
use function Chevere\ThrowableHandler\throwableHandler;
use function Chevere\Writer\writers;
use function Chevere\xrDebug\PHP\throwableHandler as XrThrowableHandler;
@@ -47,6 +50,8 @@ use function Chevereto\Legacy\G\datetime;
use function Chevereto\Legacy\G\datetimegmt;
use function Chevereto\Legacy\G\fetch_url;
use function Chevereto\Legacy\G\get_base_url;
use function Chevereto\Legacy\G\get_bytes;
use function Chevereto\Legacy\G\get_client_ip;
use function Chevereto\Legacy\G\get_current_url;
use function Chevereto\Legacy\G\get_public_url;
use function Chevereto\Legacy\G\json_document_output;
@@ -54,6 +59,7 @@ use function Chevereto\Legacy\G\nullify_string;
use function Chevereto\Legacy\G\require_theme_file;
use function Chevereto\Legacy\G\starts_with;
use function Chevereto\Legacy\getSetting;
use function Chevereto\Legacy\getVariable;
use function Chevereto\Legacy\isDebug;
use function Chevereto\Legacy\isShowEmbedContent;
use function Chevereto\Legacy\send_mail;
@@ -62,14 +68,17 @@ use function Chevereto\Vars\env;
use function Chevereto\Vars\files;
use function Chevereto\Vars\post;
use function Chevereto\Vars\request;
use function Chevereto\Vars\requestHeaders;
use function Chevereto\Vars\session;
return function (Handler $handler) {
try {
$REQUEST = request();
$FILES = files();
$POST = post();
if (! $handler::checkAuthToken(request()['auth_token'] ?? '')) {
$REQUEST = request();
$HEADERS = requestHeaders();
$REQUEST['auth_token'] ??= $HEADERS['X-Auth-Token'] ?? '';
$REQUEST['action'] ??= $HEADERS['X-Action'] ?? '';
if (! $handler::checkAuthToken($REQUEST['auth_token'] ?? '')) {
throw new Exception(_s('Request denied'), 401);
}
$logged_user = Login::getUser();
@@ -88,32 +97,188 @@ return function (Handler $handler) {
}
$import = new Import();
}
if (in_array($doing, ['chunked-upload', 'upload-chunk', 'upload'], true)) {
if (! $handler::cond('upload_allowed')) {
throw new Exception(_s('Request denied'), 403);
}
$REQUEST['type'] ??= $HEADERS['X-Type'] ?? '';
if ($doing !== 'upload-chunk') {
$source = $REQUEST['type'] === 'file'
? files()['source']
: $REQUEST['source'];
}
/** @var ?int $ownerId */
$ownerId = $logged_user['id'] ?? null;
$REQUEST['owner'] ??= $HEADERS['X-Owner'] ?? null;
if ((Login::isAdmin() || Login::isManager()) && ! empty($REQUEST['owner'])) {
$ownerId = decodeID($REQUEST['owner']);
}
}
$chunkUploadSize = getSetting('chunk_upload_size');
switch ($doing) {
case 'chunked-upload':
$maxSize = get_bytes(getSetting('upload_max_filesize_mb') . ' MB');
$checksum = $REQUEST['checksum'] ?? '';
$size = (int) ($REQUEST['size'] ?? 0);
if (! preg_match('/^[a-f0-9]{16,}$/', $checksum)) {
throw new Exception('Invalid file checksum', 100);
}
if ($size === 0) {
throw new Exception('Invalid file size', 100);
}
if ($source === '') {
throw new Exception('Invalid file name', 100);
}
$extension = strtolower(pathinfo($source, PATHINFO_EXTENSION));
if ($extension === '') {
throw new Exception('Missing file extension', 100);
}
if (! in_array($extension, Image::getEnabledImageExtensions(), true)) {
throw new Exception('Unsupported file extension', 100);
}
if ($size > $maxSize) {
throw new Exception('File size exceeds maximum', 101);
}
$do_dupe_check = ! getSetting('enable_duplicate_uploads') && ! Login::isAdmin();
if ($do_dupe_check && (Image::isDuplicatedChunkUpload($checksum) || Image::isDuplicatedUpload($checksum))) {
throw new Exception(_s('Duplicated upload'), 101);
}
$token = randomString(64);
$uploadId = DB::insert('uploads', [
'user_id' => $ownerId,
'uploader_ip' => get_client_ip(),
'token' => $token,
'checksum' => $checksum,
'params' => json_encode([
'source' => $REQUEST['source'],
]),
'chunks' => ceil($size / $chunkUploadSize),
]);
$json_array['status_code'] = 200;
$json_array['success'] = [
'message' => 'chunked upload',
'code' => 200,
'upload_id' => encodeID($uploadId),
'token' => $token,
'hash' => hash_hmac(
'sha256',
$uploadId . $token,
getVariable('crypt_salt')->string()
),
];
break;
case 'upload-chunk':
if ($logged_user !== []) {
session_write_close();
}
$uploadId = decodeID($HEADERS['X-Upload-Id']);
$index = (int) ($HEADERS['X-Index'] ?? 0);
$token = $HEADERS['X-Token'] ?? '';
$hash = $HEADERS['X-Hash'] ?? '';
if ($index === 0) {
throw new Exception('Invalid chunk index', 100);
}
if ($token === '') {
throw new Exception('Invalid token', 100);
}
if ($hash === '') {
throw new Exception('Invalid hash', 100);
}
$calcHash = hash_hmac(
'sha256',
$uploadId . $token,
getVariable('crypt_salt')->string()
);
if (! hash_equals($calcHash, $hash)) {
throw new Exception('Invalid hash', 100);
}
$uploadWhere = [
'id' => $uploadId,
'token' => $token,
];
if ($logged_user !== []) {
$uploadWhere['user_id'] = $logged_user['id'];
}
$uploadRow = DB::get(
table: 'uploads',
where: $uploadWhere,
limit: 1,
);
if (! $uploadRow) {
throw new Exception('Missing upload id', 100);
}
if ($index > $uploadRow['upload_chunks']) {
throw new Exception('Invalid chunk index', 100);
}
$db = DB::getInstance();
$db->query(
'SELECT COUNT(*) c FROM '
. DB::getTable('uploads_chunks')
. ' WHERE upload_chunk_upload_id=:upload_id AND upload_chunk_index=:chunk_index;'
);
$db->bind(':upload_id', $uploadId);
$db->bind(':chunk_index', $index);
if ($db->fetchSingle()['c'] > 0) {
throw new Exception('Chunk already uploaded', 100);
}
// $chunkFile = $source['tmp_name'];
// if (! file_exists($chunkFile)) {
// throw new Exception('Missing chunk file', 100);
// }
// $chunkFilesize = filesize($chunkFile);
// if ($chunkFilesize === 0) {
// throw new Exception('Empty chunk file', 100);
// }
// if ($chunkFilesize > $chunkUploadSize) {
// throw new Exception('Chunk file size exceeds maximum', 101);
// }
// Handle chunk upload as a stream (for "source" stream input)
$chunkFile = Upload::getTempNam(suffix: "{$uploadId}_{$index}");
$inputStream = fopen('php://input', 'rb');
if ($inputStream === false) {
throw new Exception('Failed to open input stream', 100);
}
$outputStream = fopen($chunkFile, 'wb');
if ($outputStream === false) {
fclose($inputStream);
throw new Exception('Failed to open chunk file for writing', 100);
}
stream_copy_to_stream($inputStream, $outputStream);
fclose($inputStream);
fclose($outputStream);
if (! file_exists($chunkFile) || filesize($chunkFile) === 0) {
throw new Exception('Failed to write chunk file', 100);
}
DB::insert('uploads_chunks', [
'upload_id' => $uploadId,
'index' => $index,
'path' => $chunkFile,
]);
$json_array['status_code'] = 200;
$json_array['success'] = [
'message' => 'chunk uploaded',
'code' => 200,
];
break;
case 'upload': // EX 100
// NOTE: This is considering assets and user uploads as the same "upload" action
$source = $REQUEST['type'] === 'file'
? $FILES['source']
: $REQUEST['source'];
$type = $REQUEST['type'];
/** @var ?int $owner_id */
$owner_id = ! empty($REQUEST['owner'])
? decodeID($REQUEST['owner'])
: ($logged_user['id'] ?? null);
if (isset($REQUEST['what'])
&& in_array($REQUEST['what'], ['avatar', 'background'], true)
) {
if ($logged_user === []) {
throw new Exception(_s('Login needed'), 403);
}
if (! $handler::cond('content_manager') && $owner_id !== $logged_user['id']) {
if (! $handler::cond('content_manager') && $ownerId !== $logged_user['id']) {
throw new Exception('Invalid content owner request', 115);
}
$user_picture_upload = User::uploadPicture(
$owner_id === $logged_user['id']
$ownerId === $logged_user['id']
? $logged_user
: $owner_id,
: $ownerId,
$REQUEST['what'],
$source
);
@@ -125,15 +290,13 @@ return function (Handler $handler) {
break;
}
if (! $handler::cond('upload_allowed')) {
throw new Exception(_s('Request denied'), 403);
}
if ($handler::cond('forced_private_mode')) {
$REQUEST['privacy'] = getSetting('website_content_privacy_mode');
}
if (! empty($REQUEST['album_id'])) {
$REQUEST['album_id'] = decodeID($REQUEST['album_id']);
}
// TODO: Unify this check
if (! $handler::cond('content_manager') && getSetting('akismet')) {
Akismet::checkImage(
title: $REQUEST['title'] ?? null,
@@ -144,7 +307,7 @@ return function (Handler $handler) {
}
$uploadToWebsite = Image::uploadToWebsite($source, $logged_user, $REQUEST);
if ($logged_user !== []) {
session_write_close(); // guest session uploads
session_write_close();
}
$uploaded_id = intval($uploadToWebsite[0]);
$json_array['status_code'] = 200;
@@ -198,7 +361,7 @@ return function (Handler $handler) {
if (! empty($REQUEST['albumid'])) {
$album_id = decodeID($REQUEST['albumid']);
}
$owner_id = null;
$ownerId = null;
$where = '';
switch ($list_request) {
case 'images':
@@ -219,11 +382,11 @@ return function (Handler $handler) {
];
}
if (! empty($REQUEST['userid'])) {
$owner_id = decodeID($REQUEST['userid']);
$ownerId = decodeID($REQUEST['userid']);
$where .= ($where === '' ? 'WHERE' : ' AND') . ' image_user_id=:image_user_id';
$binds[] = [
'param' => ':image_user_id',
'value' => $owner_id,
'value' => $ownerId,
];
}
if (isset($album_id)) {
@@ -234,12 +397,12 @@ return function (Handler $handler) {
];
$album = Album::getSingle($album_id);
if ($album['user']['id'] ?? false) {
$owner_id = $album['user']['id'];
$ownerId = $album['user']['id'];
}
if ($album['privacy'] === 'password'
&& (
! $handler::cond('content_manager')
&& $owner_id !== ($logged_user['id'] ?? 0)
&& $ownerId !== ($logged_user['id'] ?? 0)
&& ! Album::checkSessionPassword($album)
)
) {
@@ -267,11 +430,11 @@ return function (Handler $handler) {
$binds = [];
$where = '';
if (! empty($REQUEST['userid'])) {
$owner_id = decodeID($REQUEST['userid']);
$ownerId = decodeID($REQUEST['userid']);
$where .= 'WHERE album_user_id=:album_user_id';
$binds[] = [
'param' => ':album_user_id',
'value' => $owner_id,
'value' => $ownerId,
];
}
if (isset($REQUEST['from'])) {
@@ -404,14 +567,14 @@ return function (Handler $handler) {
}
}
$listing->setWhere($where);
if (isset($owner_id)) {
$listing->setOwner((int) $owner_id);
if (isset($ownerId)) {
$listing->setOwner((int) $ownerId);
}
$listing->setRequester($logged_user);
if (in_array($list_request, ['images', 'albums'], true)
&& (
$handler::cond('content_manager')
|| ($logged_user !== [] && $owner_id === $logged_user['id'])
|| ($logged_user !== [] && $ownerId === $logged_user['id'])
)
) {
$listing->setTools(true);
@@ -432,6 +595,7 @@ return function (Handler $handler) {
$listing->bind($bind['param'], $bind['value']);
}
}
$listing->setOutputAssoc(true);
$listing->exec();
$json_array['status_code'] = 200;
if ($doing === 'get-album-contents'
@@ -456,7 +620,7 @@ return function (Handler $handler) {
$editing_request = $REQUEST['editing'];
$editing = $editing_request;
$type = $REQUEST['edit'];
$owner_id = ! empty($REQUEST['owner']) ? decodeID($REQUEST['owner']) : $logged_user['id'];
$ownerId = ! empty($REQUEST['owner']) ? decodeID($REQUEST['owner']) : $logged_user['id'];
if (! in_array($type, ['image', 'album', 'images', 'albums', 'category', 'tag', 'storage', 'ip_ban'], true)) {
throw new Exception('Invalid edit request', 100);
}
@@ -702,6 +866,7 @@ return function (Handler $handler) {
'code' => 200,
];
$json_array['category'] = $category;
Categories::deleteCache();
break;
case 'tag':
@@ -891,6 +1056,7 @@ return function (Handler $handler) {
'code' => 200,
];
$json_array['category'] = $category;
Categories::deleteCache();
break;
case 'add-ip_ban':
@@ -965,12 +1131,7 @@ return function (Handler $handler) {
throw new Exception(_s('Login needed'), 403);
}
$editing = $REQUEST['editing'];
$owner_id = $logged_user['id'];
if (! $handler::cond('content_manager')
&& $owner_id !== $logged_user['id']
) {
throw new Exception('Invalid content owner request', 110);
}
$ownerId = $logged_user['id'];
$ids = [];
foreach ($editing['ids'] as $id) {
$ids[] = decodeID($id);
@@ -1039,23 +1200,23 @@ return function (Handler $handler) {
if ($logged_user === [] && $album['new'] === false) {
throw new Exception('Invalid request', 403);
}
$owner_id = ! empty($REQUEST['owner'])
$ownerId = ! empty($REQUEST['owner'])
? decodeID($REQUEST['owner'])
: ($logged_user['id'] ?? null);
if (! $handler::cond('content_manager') && $owner_id !== ($logged_user['id'] ?? null)) {
throw new Exception('Invalid content owner request' . var_export($owner_id, true), 112);
if (! $handler::cond('content_manager') && $ownerId !== ($logged_user['id'] ?? null)) {
throw new Exception('Invalid content owner request', 112);
}
if ($handler::cond('forced_private_mode')) {
$album['privacy'] = getSetting('website_content_privacy_mode');
}
if (! $handler::cond('content_manager') && getSetting('akismet') && $album['new']) {
Akismet::checkAlbum($album['name'], $album['description'], $owner_id === $logged_user['id'] ? $logged_user_source_db : null);
Akismet::checkAlbum($album['name'], $album['description'], $ownerId === $logged_user['id'] ? $logged_user_source_db : null);
}
$album_id = $album['new']
? Album::insert([
'name' => $album['name'],
'user_id' => $owner_id,
'user_id' => $ownerId,
'privacy' => $album['privacy'],
'description' => $album['description'],
'password' => $album['password'] ?? null,
@@ -1116,7 +1277,7 @@ return function (Handler $handler) {
}
$album_move_db = isset($album_db['album_id'])
? Album::getSingle(id: (int) $album_db['album_id'], pretty: false)
: User::getStreamAlbum($owner_id);
: User::getStreamAlbum($ownerId);
$json_array['status_code'] = 200;
$json_array['success'] = [
'message' => 'Content added to album',
@@ -1155,7 +1316,7 @@ return function (Handler $handler) {
) {
throw new Exception('Forbidden action', 403);
}
$owner_id = isset($REQUEST['owner'])
$ownerId = isset($REQUEST['owner'])
? decodeID($REQUEST['owner'])
: $logged_user['id'];
$multiple = ($REQUEST['multiple'] ?? null) == 'true';
@@ -1165,7 +1326,7 @@ return function (Handler $handler) {
}
if (
in_array($type, ['avatar', 'background', 'user', 'ip_ban', 'api_key', 'two_factor'], true)
&& ! $handler::cond('content_manager') && $owner_id !== $logged_user['id']
&& ! $handler::cond('content_manager') && $ownerId !== $logged_user['id']
) {
throw new Exception('Invalid content owner request', 113);
}
@@ -1182,7 +1343,7 @@ return function (Handler $handler) {
throw new Exception('Invalid content manager request', 115);
}
if (in_array($type, ['avatar', 'background'], true)) {
User::deletePicture($owner_id === $logged_user['id'] ? $logged_user : $owner_id, $type);
User::deletePicture($ownerId === $logged_user['id'] ? $logged_user : $ownerId, $type);
$json_array['status_code'] = 200;
$json_array['success'] = [
'message' => 'Profile background deleted',
@@ -1193,9 +1354,9 @@ return function (Handler $handler) {
}
if ($type === 'two_factor') {
$userTarget = intval(
$owner_id === $logged_user['id']
$ownerId === $logged_user['id']
? $logged_user['id']
: $owner_id
: $ownerId
);
if (! TwoFactor::hasFor($userTarget)) {
$status_code = 403;
@@ -1215,9 +1376,9 @@ return function (Handler $handler) {
}
if ($type === 'api_key') {
$userTarget = intval(
$owner_id === $logged_user['id']
$ownerId === $logged_user['id']
? $logged_user['id']
: $owner_id
: $ownerId
);
$apiKey = ApiKey::getUserKey($userTarget);
if ($apiKey !== []) {
@@ -1232,7 +1393,9 @@ return function (Handler $handler) {
break;
}
if ($type === 'user') {
$delete_user_id = $owner_id === $logged_user['id'] ? $logged_user : $owner_id;
$delete_user_id = $ownerId === $logged_user['id']
? $logged_user
: $ownerId;
$delete_user = User::getSingle($delete_user_id, 'id');
if ($delete_user === []) {
throw new Exception(_s('%s not found', _n('User', 'Users', 1)), 100);
@@ -1266,6 +1429,7 @@ return function (Handler $handler) {
], [
'category_id' => $deleting['id'],
]);
Categories::deleteCache();
} else {
throw new Exception('Error deleting category', 400);
}
@@ -1738,7 +1902,7 @@ return function (Handler $handler) {
break;
case 'paletteSet':
if ($logged_user === []) {
if ($logged_user === [] || ! getSetting('theme_palette_user_select')) {
throw new Exception('Invalid request', 403);
}
$palette_id = (int) $REQUEST['palette_id'];

View File

@@ -9,9 +9,11 @@
* file that was distributed with this source code.
*/
use Chevereto\Legacy\Classes\Cache;
use Chevereto\Legacy\Classes\Page;
use Chevereto\Legacy\G\Handler;
use function Chevereto\Legacy\G\add_ending_slash;
use function Chevereto\Legacy\G\str_replace_last;
use function Chevereto\Vars\env;
return function (Handler $handler) {
@@ -20,26 +22,42 @@ return function (Handler $handler) {
return;
}
$request_url_key = implode('/', $handler->request());
$page = Page::getSingle($request_url_key);
$urlKey = implode('/', $handler->request());
$cacheKey = Page::getCacheKey($urlKey);
$page = Cache::instance()->get($cacheKey);
if ($page === false) {
$page = Page::getSingle($urlKey);
if ($page !== []) {
Cache::instance()->set($cacheKey, $page, 3600);
}
}
if (! $page || ! $page['is_active'] || $page['type'] !== 'internal') {
$handler->issueError(404);
return;
}
if (! $page['file_path_absolute']) {
$handler->issueError(404);
if ((bool) env()['CHEVERETO_ENABLE_PHP_PAGES']) {
if (! fileExists($page['file_path_absolute'] ?? null)) {
$handler->issueError(404);
return;
return;
}
$pathinfo = pathinfo($page['file_path_absolute']);
$handler->setPathTheme(add_ending_slash($pathinfo['dirname']));
} else {
if ($page['code'] === null) {
$file = str_replace_last('.php', '.html', $page['file_path_absolute']);
if (fileExists($file)) {
$page['code'] = file_get_contents($file);
}
if ($page['code'] !== null) {
Page::update($page['id'], [
'code' => $page['code'],
]);
}
}
$handler->setContent($page['code'] ?? '');
}
if (! file_exists($page['file_path_absolute'])) {
$handler->issueError(404);
return;
}
$pathinfo = pathinfo($page['file_path_absolute']);
$handler->setPathTheme(add_ending_slash($pathinfo['dirname']));
$handler->setTemplate($pathinfo['filename']);
$page_metas = [
'pre_doctitle' => $page['title'],
'meta_description' => htmlspecialchars($page['description'] ?? ''),
@@ -52,3 +70,12 @@ return function (Handler $handler) {
$handler->setVar($k, $v);
}
};
function fileExists(?string $file): bool
{
if ($file === null || $file === '') {
return false;
}
return file_exists($file);
}

View File

@@ -396,7 +396,7 @@ return function (Handler $handler) {
break;
case 'security':
if (! TwoFactor::hasFor($user['id']) && sessionVar()->hasKey('two_factor_secret')) {
if (! TwoFactor::hasFor($user['id']) && sessionVar()->has('two_factor_secret')) {
$twoFactor = new TwoFactor();
$twoFactor = $twoFactor->withSecret(session()['two_factor_secret']);
sessionVar()->remove('two_factor_secret');

View File

@@ -85,6 +85,7 @@ return function (Handler $handler) {
$sumViews[] = $tag['id'];
}
}
$sumViews = array_unique($sumViews);
$tags_names = array_column($tags, 'name');
$tag_string = implode(', ', $tags_names);
$tag_string_no_spaces = implode(',', $tags_names);

View File

@@ -410,15 +410,18 @@ return function (Handler $handler) {
}
}
if (! isset($tabs)) {
$tabs = Listing::getTabs([
'listing' => $type,
'basename' => $base_user_url,
'tools' => $tools,
'tools_available' => $tools_available ?? [],
'params_hidden' => $params_hidden,
'params_remove_keys' => $params_remove_keys ?? null,
'tag' => rawurldecode($tag_string_no_spaces),
], [], true);
$tabs = Listing::getTabs(
args: [
'listing' => $type,
'basename' => $base_user_url,
'tools' => $tools,
'tools_available' => $tools_available ?? [],
'params_hidden' => $params_hidden,
'params_remove_keys' => $params_remove_keys ?? null,
'tag' => rawurldecode($tag_string_no_spaces),
],
expanded: true
);
$currentKey = $tabs['currentKey'];
$tabs = $tabs['tabs'];
}

View File

@@ -1,121 +0,0 @@
<?php
/*
* This file is part of Chevereto.
*
* (c) Rodolfo Berrios <rodolfo@chevereto.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use function Chevere\Router\route;
use function Chevere\Router\routes;
use Chevereto\Controllers\Api\V4\Ban\Ip\BanIpDeleteController;
use Chevereto\Controllers\Api\V4\Ban\Ip\BanIpPatchController;
use Chevereto\Controllers\Api\V4\Ban\Ip\BanIpPostController;
use Chevereto\Controllers\Api\V4\Category\CategoryPostController;
use Chevereto\Controllers\Api\V4\Image\Bulk\ImageBulkPatchController;
use Chevereto\Controllers\Api\V4\Stat\Rebuild\StatRebuildPostController;
use Chevereto\Controllers\Api\V4\Storage\Migrate\StorageMigratePostController;
use Chevereto\Controllers\Api\V4\Storage\Stat\Regen\StorageStatRegenPostController;
use Chevereto\Controllers\Api\V4\Storage\StoragePostController;
use Chevereto\Controllers\Api\V4\Tool\Id\Decode\ToolDecodeIdGetController;
use Chevereto\Controllers\Api\V4\Tool\Id\Encode\ToolEncodeIdGetController;
use Chevereto\Controllers\Api\V4\Tool\Probe\Email\ToolProbeEmailPostController;
use Chevereto\Controllers\Api\V4\User\Export\UserExportGetController;
use Chevereto\Controllers\Api\V4\User\UserGetController;
use Chevereto\Controllers\Api\V4\User\UserPostController;
$prefix = '/api/4/admin/';
return routes(
route(
path: $prefix . 'bans/ip/',
POST: new BanIpPostController(),
),
route(
path: $prefix . 'bans/ip/{ip}/',
DELETE: new BanIpDeleteController(),
PATCH: new BanIpPatchController(),
),
route(
path: $prefix . 'categories/',
POST: new CategoryPostController(),
),
route(
path: $prefix . 'categories/{id}/',
// DELETE: ,
// PATCH: ,
),
route(
path: $prefix . 'images/bulk/approve/',
PATCH: new ImageBulkPatchController(),
),
route(
path: $prefix . 'imports/',
// POST: ,
),
route(
path: $prefix . 'imports/{id}/',
// DELETE: ,
// GET: ,
// PATCH: ,
),
route(
path: $prefix . 'imports/{id}/process/',
// POST: ,
),
route(
path: $prefix . 'imports/{id}/reset/',
// POST: ,
),
route(
path: $prefix . 'imports/{id}/resume/',
// POST: ,
),
route(
path: $prefix . 'stats/rebuild/',
POST: new StatRebuildPostController(),
),
route(
path: $prefix . 'storages/',
POST: new StoragePostController(),
),
route(
path: $prefix . 'storages/{id}/',
// PATCH: ,
),
route(
path: $prefix . 'storages/{id}/migrate/',
POST: new StorageMigratePostController(),
),
route(
path: $prefix . 'storages/{id}/stats/regen/',
POST: new StorageStatRegenPostController(),
),
route(
path: $prefix . 'tools/id/{id}/decode/',
GET: new ToolDecodeIdGetController(),
),
route(
path: $prefix . 'tools/id/{id}/encode/',
GET: new ToolEncodeIdGetController(),
),
route(
path: $prefix . 'tools/probe/email/',
POST: new ToolProbeEmailPostController(),
),
route(
path: $prefix . 'users/',
POST: new UserPostController(),
),
route(
path: $prefix . 'users/{id}/',
GET: new UserGetController(),
),
route(
path: $prefix . 'users/{id}/export/',
GET: new UserExportGetController(),
),
);

View File

@@ -1,39 +0,0 @@
<?php
/*
* This file is part of Chevereto.
*
* (c) Rodolfo Berrios <rodolfo@chevereto.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use function App\Controllers\legacyController;
use function Chevere\Router\route;
use function Chevere\Router\routes;
return routes(
route(
name: 'dashboard',
path: '/dashboard/',
GET: legacyController('route.dashboard.php'),
POST: legacyController('route.dashboard.php'),
),
route(
name: 'importer-jobs',
path: '/importer-jobs/',
GET: legacyController('route.importer-jobs.php'),
),
route(
name: 'install',
path: '/install/',
GET: legacyController('route.install.php'),
POST: legacyController('route.install.php'),
),
route(
name: 'update',
path: '/update/',
POST: legacyController('route.update.php'),
),
);

View File

@@ -1,21 +0,0 @@
<?php
/*
* This file is part of Chevereto.
*
* (c) Rodolfo Berrios <rodolfo@chevereto.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use function Chevere\Router\route;
use function Chevere\Router\routes;
use Chevereto\Controllers\Api\V1\Upload\UploadPostController;
return routes(
route(
path: '/api/1/upload/',
POST: new UploadPostController()
),
);

View File

@@ -1,127 +0,0 @@
<?php
/*
* This file is part of Chevereto.
*
* (c) Rodolfo Berrios <rodolfo@chevereto.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use function Chevere\Router\route;
use function Chevere\Router\routes;
use Chevereto\Controllers\Api\V4\Album\AlbumDeleteController;
use Chevereto\Controllers\Api\V4\Album\AlbumGetController;
use Chevereto\Controllers\Api\V4\Album\AlbumPatchController;
use Chevereto\Controllers\Api\V4\Album\AlbumPostController;
use Chevereto\Controllers\Api\V4\Album\Like\AlbumLikeDeleteController;
use Chevereto\Controllers\Api\V4\Album\Like\AlbumLikePostController;
use Chevereto\Controllers\Api\V4\Image\Bulk\ImageBulkPatchController;
use Chevereto\Controllers\Api\V4\Image\ImageGetController;
use Chevereto\Controllers\Api\V4\Image\ImagePatchController;
use Chevereto\Controllers\Api\V4\Image\ImagePostController;
use Chevereto\Controllers\Api\V4\Image\Like\ImageLikeDeleteController;
use Chevereto\Controllers\Api\V4\Image\Like\ImageLikePostController;
use Chevereto\Controllers\Api\V4\User\Asset\Avatar\UserAssetAvatarDeleteController;
use Chevereto\Controllers\Api\V4\User\Asset\Avatar\UserAssetAvatarPostController;
use Chevereto\Controllers\Api\V4\User\Asset\Background\UserAssetBackgroundDeleteController;
use Chevereto\Controllers\Api\V4\User\Asset\Background\UserAssetBackgroundPostController;
use Chevereto\Controllers\Api\V4\User\Follow\UserFollowDeleteController;
use Chevereto\Controllers\Api\V4\User\Follow\UserFollowPostController;
use Chevereto\Controllers\Api\V4\User\Setting\UserSettingPatchController;
$prefix = '/api/4/user/';
return routes(
route(
path: $prefix . 'account/notifications/social/',
// GET: ,
),
route(
path: $prefix . 'account/notifications/social/{id}/',
// PATCH: ,
),
route(
path: $prefix . 'account/settings/',
PATCH: new UserSettingPatchController(),
),
route(
path: $prefix . 'account/login/{service}/',
// DELETE: ,
),
route(
path: $prefix . 'albums/',
POST: new AlbumPostController(),
),
route(
path: $prefix . 'albums/{id}/',
DELETE: new AlbumDeleteController(),
GET: new AlbumGetController(),
PATCH: new AlbumPatchController(),
),
route(
path: $prefix . 'albums/{id}/contents/',
// GET: ,
),
route(
path: $prefix . 'albums/{id}/like/',
DELETE: new AlbumLikeDeleteController(),
POST: new AlbumLikePostController(),
),
route(
path: $prefix . 'albums/bulk/',
// DELETE: ,
),
route(
path: $prefix . 'albums/bulk/parent/',
// PATCH: ,
),
route(
path: $prefix . 'albums/list/',
// GET:
),
route(
path: $prefix . 'images/',
POST: new ImagePostController(),
),
route(
path: $prefix . 'images/{id}/',
// DELETE: ,
GET: new ImageGetController(),
PATCH: new ImagePatchController(),
),
route(
path: $prefix . 'images/{id}/like/',
DELETE: new ImageLikeDeleteController(),
POST: new ImageLikePostController(),
),
route(
path: $prefix . 'images/bulk/',
PATCH: new ImageBulkPatchController(),
),
route(
path: $prefix . 'images/list/',
// GET:
),
route(
path: $prefix . 'user/{username}/assets/avatar/',
DELETE: new UserAssetAvatarDeleteController(),
POST: new UserAssetAvatarPostController()
),
route(
path: $prefix . 'user/{username}/assets/background/',
DELETE: new UserAssetBackgroundDeleteController(),
POST: new UserAssetBackgroundPostController()
),
route(
path: $prefix . 'users/{username}/follow/',
DELETE: new UserFollowDeleteController(),
POST: new UserFollowPostController(),
),
route(
path: $prefix . 'users/list/',
// GET:,
),
);

View File

@@ -1,127 +0,0 @@
<?php
/*
* This file is part of Chevereto.
*
* (c) Rodolfo Berrios <rodolfo@chevereto.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use function App\Controllers\legacyController;
use function Chevere\Router\route;
use function Chevere\Router\routes;
return routes(
route(
name: 'index',
path: '/',
),
route(
name: 'account',
path: '/account/',
GET: legacyController('account.php'),
POST: legacyController('account.php'),
),
route(
name: 'album',
path: '/album/',
GET: legacyController('album.php'),
POST: legacyController('album.php'),
),
route(
name: 'category',
path: '/category/',
GET: legacyController('category.php'),
),
route(
name: 'connect',
path: '/connect/',
GET: legacyController('connect.php'),
),
route(
name: 'explore',
path: '/explore/',
GET: legacyController('explore.php'),
),
route(
name: 'following',
path: '/following/',
GET: legacyController('following.php'),
),
route(
name: 'image',
path: '/image/',
GET: legacyController('image.php'),
),
route(
name: 'login',
path: '/login/',
GET: legacyController('login.php'),
POST: legacyController('login.php'),
),
route(
name: 'logout',
path: '/logout/',
GET: legacyController('logout.php'),
),
route(
name: 'moderate',
path: '/moderate/',
GET: legacyController('moderate.php'),
),
route(
name: 'oembed',
path: '/oembed/',
GET: legacyController('oembed.php'),
),
route(
name: 'page',
path: '/page/',
GET: legacyController('page.php'),
),
route(
name: 'plugin',
path: '/plugin/',
GET: legacyController('plugin.php'),
),
route(
name: 'captcha-verify',
path: '/captcha-verify/',
GET: legacyController('captcha-verify.php'),
),
route(
name: 'redirect',
path: '/redirect/',
GET: legacyController('redirect.php'),
),
route(
name: 'search',
path: '/search/',
GET: legacyController('search.php'),
POST: legacyController('search.php'),
),
route(
name: 'settings',
path: '/settings/',
GET: legacyController('settings.php'),
POST: legacyController('settings.php'),
),
route(
name: 'signup',
path: '/signup/',
GET: legacyController('signup.php'),
POST: legacyController('signup.php'),
),
route(
name: 'upload',
path: '/upload/',
GET: legacyController('upload.php'),
),
route(
name: 'user',
path: '/user/',
GET: legacyController('user.php'),
),
);

View File

@@ -1,22 +1,22 @@
DROP TABLE IF EXISTS `%table_prefix%albums`;
CREATE TABLE `%table_prefix%albums` (
`album_id` bigint(32) NOT NULL AUTO_INCREMENT,
`album_name` varchar(100) NOT NULL,
`album_user_id` bigint(32) DEFAULT NULL,
`album_date` datetime NOT NULL,
`album_date_gmt` datetime NOT NULL,
`album_creation_ip` varchar(255) NOT NULL,
`album_privacy` enum('public','password','private','private_but_link','custom') DEFAULT 'public',
`album_privacy_extra` text,
`album_password` text,
`album_image_count` bigint(32) NOT NULL DEFAULT '0',
`album_description` text,
`album_likes` bigint(32) NOT NULL DEFAULT '0',
`album_views` bigint(32) NOT NULL DEFAULT '0',
`album_cover_id` bigint(32) DEFAULT NULL,
`album_parent_id` bigint(32) DEFAULT NULL,
`album_cta_enable` tinyint(1) NOT NULL DEFAULT '0',
`album_cta` text,
`album_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`album_name` VARCHAR(100) NOT NULL,
`album_user_id` INT UNSIGNED DEFAULT NULL,
`album_date` DATETIME NOT NULL,
`album_date_gmt` DATETIME NOT NULL,
`album_creation_ip` VARCHAR(255) NOT NULL,
`album_privacy` ENUM('public','password','private','private_but_link','custom') DEFAULT 'public',
`album_privacy_extra` TEXT,
`album_password` TEXT,
`album_image_count` INT UNSIGNED NOT NULL DEFAULT '0',
`album_description` TEXT,
`album_likes` INT UNSIGNED NOT NULL DEFAULT '0',
`album_views` INT UNSIGNED NOT NULL DEFAULT '0',
`album_cover_id` INT UNSIGNED DEFAULT NULL,
`album_parent_id` INT UNSIGNED DEFAULT NULL,
`album_cta_enable` TINYINT UNSIGNED NOT NULL DEFAULT '0',
`album_cta` TEXT,
PRIMARY KEY (`album_id`),
KEY `album_name` (`album_name`),
KEY `album_user_id` (`album_user_id`),
@@ -27,5 +27,6 @@ CREATE TABLE `%table_prefix%albums` (
KEY `album_likes` (`album_likes`),
KEY `album_views` (`album_views`),
KEY `album_parent_id` (`album_parent_id`),
KEY `album_user_id_parent_id_name` (`album_user_id`, `album_parent_id`, `album_name`),
FULLTEXT KEY `searchindex` (`album_name`,`album_description`)
) ENGINE=%table_engine% DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

View File

@@ -1,10 +1,10 @@
DROP TABLE IF EXISTS `%table_prefix%api_keys`;
CREATE TABLE `%table_prefix%api_keys` (
`api_key_id` bigint(32) NOT NULL AUTO_INCREMENT,
`api_key_user_id` bigint(32) DEFAULT NULL,
`api_key_name` varchar(100) DEFAULT NULL,
`api_key_date_gmt` datetime NOT NULL,
`api_key_hash` text NOT NULL,
`api_key_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`api_key_user_id` INT UNSIGNED DEFAULT NULL,
`api_key_name` VARCHAR(100) DEFAULT NULL,
`api_key_date_gmt` DATETIME NOT NULL,
`api_key_hash` TEXT NOT NULL,
PRIMARY KEY (`api_key_id`),
KEY `api_key_user_id` (`api_key_user_id`),
KEY `api_key_name` (`api_key_name`),

View File

@@ -1,10 +1,10 @@
DROP TABLE IF EXISTS `%table_prefix%assets`;
CREATE TABLE `%table_prefix%assets` (
`asset_id` bigint(32) NOT NULL AUTO_INCREMENT,
`asset_key` varchar(255) NOT NULL,
`asset_md5` varchar(32) NOT NULL,
`asset_filename` varchar(255) NOT NULL,
`asset_file_path` varchar(255) NOT NULL,
`asset_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`asset_key` VARCHAR(255) NOT NULL,
`asset_checksum` VARCHAR(32) NOT NULL,
`asset_filename` VARCHAR(255) NOT NULL,
`asset_file_path` VARCHAR(255) NOT NULL,
`asset_blob` blob,
PRIMARY KEY (`asset_id`),
UNIQUE KEY `key` (`asset_key`(191)) USING BTREE,

View File

@@ -1,9 +1,10 @@
DROP TABLE IF EXISTS `%table_prefix%categories`;
CREATE TABLE `%table_prefix%categories` (
`category_id` bigint(32) NOT NULL AUTO_INCREMENT,
`category_name` varchar(32) NOT NULL,
`category_url_key` varchar(32) COLLATE utf8mb4_bin NOT NULL,
`category_description` text,
`category_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`category_name` VARCHAR(32) NOT NULL,
`category_url_key` VARCHAR(32) COLLATE utf8mb4_bin NOT NULL,
`category_description` TEXT,
PRIMARY KEY (`category_id`),
KEY `category_name` (`category_name`),
UNIQUE KEY `url_key` (`category_url_key`) USING BTREE
) ENGINE=%table_engine% DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

View File

@@ -1,13 +1,13 @@
DROP TABLE IF EXISTS `%table_prefix%confirmations`;
CREATE TABLE `%table_prefix%confirmations` (
`confirmation_id` bigint(32) NOT NULL AUTO_INCREMENT,
`confirmation_user_id` bigint(32) NOT NULL,
`confirmation_type` enum('account-activate','account-change-email','account-password-forgot') NOT NULL,
`confirmation_date` datetime NOT NULL,
`confirmation_date_gmt` datetime NOT NULL,
`confirmation_token_hash` varchar(255) NOT NULL,
`confirmation_status` enum('active','valid','invalid') NOT NULL,
`confirmation_extra` mediumtext,
`confirmation_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`confirmation_user_id` INT UNSIGNED NOT NULL,
`confirmation_type` ENUM('account-activate','account-change-email','account-password-forgot') NOT NULL,
`confirmation_date` DATETIME NOT NULL,
`confirmation_date_gmt` DATETIME NOT NULL,
`confirmation_token_hash` VARCHAR(255) NOT NULL,
`confirmation_status` ENUM('active','valid','invalid') NOT NULL,
`confirmation_extra` TEXT,
PRIMARY KEY (`confirmation_id`),
KEY `confirmation_user` (`confirmation_user_id`),
KEY `confirmation_user_type` (`confirmation_user_id`, `confirmation_type`),

View File

@@ -1,20 +1,20 @@
DROP TABLE IF EXISTS `%table_prefix%deletions`;
CREATE TABLE `%table_prefix%deletions` (
`deleted_id` bigint(32) NOT NULL AUTO_INCREMENT,
`deleted_date_gmt` datetime NOT NULL,
`deleted_content_id` bigint(32) NOT NULL,
`deleted_content_date_gmt` datetime NOT NULL,
`deleted_content_user_id` bigint(32) DEFAULT NULL,
`deleted_content_ip` varchar(255) NOT NULL,
`deleted_content_md5` varchar(32) DEFAULT NULL,
`deleted_content_original_filename` varchar(255) DEFAULT NULL,
`deleted_content_views` bigint(32) NOT NULL DEFAULT '0',
`deleted_content_likes` bigint(32) NOT NULL DEFAULT '0',
`deleted_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`deleted_date_gmt` DATETIME NOT NULL,
`deleted_content_id` INT UNSIGNED NOT NULL,
`deleted_content_date_gmt` DATETIME NOT NULL,
`deleted_content_user_id` INT UNSIGNED DEFAULT NULL,
`deleted_content_ip` VARCHAR(255) NOT NULL,
`deleted_content_checksum` VARCHAR(32) DEFAULT NULL,
`deleted_content_original_filename` VARCHAR(255) DEFAULT NULL,
`deleted_content_views` INT UNSIGNED NOT NULL DEFAULT '0',
`deleted_content_likes` INT UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (`deleted_id`),
KEY `deleted_content_id` (`deleted_content_id`),
KEY `deleted_content_user_id` (`deleted_content_user_id`),
KEY `deleted_content_ip` (`deleted_content_ip`),
KEY `deleted_content_md5` (`deleted_content_md5`),
KEY `deleted_content_checksum` (`deleted_content_checksum`),
KEY `deleted_content_views` (`deleted_content_views`),
KEY `deleted_content_likes` (`deleted_content_likes`)
) ENGINE=%table_engine% DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

View File

@@ -1,11 +1,11 @@
DROP TABLE IF EXISTS `%table_prefix%follows`;
CREATE TABLE `%table_prefix%follows` (
`follow_id` bigint(32) NOT NULL AUTO_INCREMENT,
`follow_date` datetime NOT NULL,
`follow_date_gmt` datetime NOT NULL,
`follow_user_id` bigint(32) NOT NULL,
`follow_followed_user_id` bigint(32) NOT NULL,
`follow_ip` varchar(255) NOT NULL,
`follow_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`follow_date` DATETIME NOT NULL,
`follow_date_gmt` DATETIME NOT NULL,
`follow_user_id` INT UNSIGNED NOT NULL,
`follow_followed_user_id` INT UNSIGNED NOT NULL,
`follow_ip` VARCHAR(255) NOT NULL,
PRIMARY KEY (`follow_id`),
KEY `follow_user_id` (`follow_user_id`),
KEY `follow_followed_user_id` (`follow_followed_user_id`)

View File

@@ -1,39 +1,39 @@
DROP TABLE IF EXISTS `%table_prefix%images`;
CREATE TABLE `%table_prefix%images` (
`image_id` bigint(32) NOT NULL AUTO_INCREMENT,
`image_name` varchar(255) NOT NULL,
`image_extension` varchar(255) NOT NULL,
`image_size` bigint(11) UNSIGNED NOT NULL,
`image_width` int(11) NOT NULL,
`image_height` int(11) NOT NULL,
`image_date` datetime NOT NULL,
`image_date_gmt` datetime NOT NULL,
`image_title` varchar(100) DEFAULT NULL,
`image_description` text,
`image_nsfw` tinyint(1) NOT NULL DEFAULT '0',
`image_user_id` bigint(32) DEFAULT NULL,
`image_album_id` bigint(32) DEFAULT NULL,
`image_uploader_ip` varchar(255) NOT NULL,
`image_storage_mode` enum('datefolder','direct','old','path') NOT NULL DEFAULT 'datefolder',
`image_path` varchar(4096) DEFAULT NULL,
`image_storage_id` bigint(32) DEFAULT NULL,
`image_md5` varchar(32) NOT NULL,
`image_source_md5` varchar(32) DEFAULT NULL,
`image_original_filename` varchar(255) NOT NULL,
`image_original_exifdata` mediumtext,
`image_views` bigint(32) NOT NULL DEFAULT '0',
`image_category_id` bigint(32) DEFAULT NULL,
`image_chain` tinyint(3) NOT NULL,
`image_thumb_size` int(11) NOT NULL,
`image_medium_size` int(11) NOT NULL DEFAULT '0',
`image_frame_size` int(11) NOT NULL DEFAULT '0',
`image_expiration_date_gmt` datetime DEFAULT NULL,
`image_likes` bigint(32) NOT NULL DEFAULT '0',
`image_is_animated` tinyint(1) NOT NULL DEFAULT '0',
`image_is_approved` tinyint(1) NOT NULL DEFAULT '1',
`image_is_360` tinyint(1) NOT NULL DEFAULT '0',
`image_duration` int(11) NOT NULL DEFAULT '0',
`image_type` tinyint(3) UNSIGNED as (case
`image_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`image_name` VARCHAR(255) NOT NULL,
`image_extension` VARCHAR(255) NOT NULL,
`image_size` BIGINT UNSIGNED NOT NULL,
`image_width` INT UNSIGNED NOT NULL,
`image_height` INT UNSIGNED NOT NULL,
`image_date` DATETIME NOT NULL,
`image_date_gmt` DATETIME NOT NULL,
`image_title` VARCHAR(100) DEFAULT NULL,
`image_description` TEXT,
`image_nsfw` TINYINT UNSIGNED NOT NULL DEFAULT '0',
`image_user_id` INT UNSIGNED DEFAULT NULL,
`image_album_id` INT UNSIGNED DEFAULT NULL,
`image_uploader_ip` VARCHAR(255) NOT NULL,
`image_storage_mode` ENUM('datefolder','direct','old','path') NOT NULL DEFAULT 'datefolder',
`image_path` VARCHAR(4096) DEFAULT NULL,
`image_storage_id` INT UNSIGNED DEFAULT NULL,
`image_checksum` VARCHAR(32) NOT NULL,
`image_source_checksum` VARCHAR(32) DEFAULT NULL,
`image_original_filename` VARCHAR(255) NOT NULL,
`image_original_exifdata` MEDIUMTEXT,
`image_views` INT UNSIGNED NOT NULL DEFAULT '0',
`image_category_id` INT UNSIGNED DEFAULT NULL,
`image_chain` TINYINT UNSIGNED NOT NULL,
`image_thumb_size` INT UNSIGNED NOT NULL,
`image_medium_size` INT UNSIGNED NOT NULL DEFAULT '0',
`image_frame_size` INT UNSIGNED NOT NULL DEFAULT '0',
`image_expiration_date_gmt` DATETIME DEFAULT NULL,
`image_likes` INT UNSIGNED NOT NULL DEFAULT '0',
`image_is_animated` TINYINT UNSIGNED NOT NULL DEFAULT '0',
`image_is_approved` TINYINT UNSIGNED NOT NULL DEFAULT '1',
`image_is_360` TINYINT UNSIGNED NOT NULL DEFAULT '0',
`image_duration` INT UNSIGNED NOT NULL DEFAULT '0',
`image_type` TINYINT UNSIGNED as (case
when `image_extension` in ('pdf','doc','md') then 4
when `image_extension` in ('mp3','m4a','wav') then 3
when `image_extension` in ('mp4','webm','mov') then 2
@@ -53,8 +53,8 @@ CREATE TABLE `%table_prefix%images` (
KEY `image_storage_mode` (`image_storage_mode`),
KEY `image_path` (`image_path`(255)),
KEY `image_storage_id` (`image_storage_id`),
KEY `image_md5` (`image_md5`),
KEY `image_source_md5` (`image_source_md5`),
KEY `image_checksum` (`image_checksum`),
KEY `image_source_checksum` (`image_source_checksum`),
KEY `image_views` (`image_views`),
KEY `image_category_id` (`image_category_id`),
KEY `image_chain` (`image_chain`),
@@ -66,5 +66,6 @@ CREATE TABLE `%table_prefix%images` (
KEY `image_album_id_image_id` (`image_album_id`, `image_id`),
KEY `image_duration` (`image_duration`),
KEY `image_type` (`image_type`),
FULLTEXT KEY `searchindex` (`image_name`,`image_title`,`image_description`,`image_original_filename`)
FULLTEXT KEY `searchindex` (`image_name`,`image_title`,`image_description`,`image_original_filename`),
KEY `image_uploader_ip_date_gmt_checksum_source_checksum` (`image_uploader_ip`, `image_date_gmt`, `image_checksum`, `image_source_checksum`)
) ENGINE=%table_engine% DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

View File

@@ -1,6 +1,6 @@
DROP TABLE IF EXISTS `%table_prefix%images_hash`;
CREATE TABLE `%table_prefix%images_hash` (
`image_hash_image_id` bigint(32) NOT NULL,
`image_hash_hash` mediumtext NOT NULL,
`image_hash_image_id` INT UNSIGNED NOT NULL,
`image_hash_hash` TEXT NOT NULL,
PRIMARY KEY (`image_hash_image_id`)
) ENGINE=%table_engine% DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

View File

@@ -1,10 +1,10 @@
DROP TABLE IF EXISTS `%table_prefix%importing`;
CREATE TABLE `%table_prefix%importing` (
`importing_id` bigint(32) NOT NULL AUTO_INCREMENT,
`importing_import_id` bigint(32) NOT NULL,
`importing_path` varchar(4096) NOT NULL,
`importing_content_type` enum('user','album','image') NOT NULL,
`importing_content_id` bigint(32) DEFAULT NULL,
`importing_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`importing_import_id` INT UNSIGNED NOT NULL,
`importing_path` VARCHAR(4096) NOT NULL,
`importing_content_type` ENUM('user','album','image') NOT NULL,
`importing_content_id` INT UNSIGNED DEFAULT NULL,
PRIMARY KEY (`importing_id`),
UNIQUE KEY `importing_path` (`importing_path`(191))
) ENGINE=%table_engine% DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

View File

@@ -1,17 +1,17 @@
DROP TABLE IF EXISTS `%table_prefix%imports`;
CREATE TABLE `%table_prefix%imports` (
`import_id` bigint(32) NOT NULL AUTO_INCREMENT,
`import_path` varchar(4096) NOT NULL,
`import_options` varchar(255) DEFAULT NULL,
`import_status` enum('queued','working','paused','canceled','completed') NOT NULL,
`import_users` bigint(32) NOT NULL DEFAULT '0',
`import_images` bigint(32) NOT NULL DEFAULT '0',
`import_albums` bigint(32) NOT NULL DEFAULT '0',
`import_time_created` datetime DEFAULT NULL,
`import_time_updated` datetime DEFAULT NULL,
`import_errors` tinyint(1) NOT NULL DEFAULT '0',
`import_started` tinyint(1) NOT NULL DEFAULT '0',
`import_continuous` tinyint(1) NOT NULL DEFAULT '0',
`import_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`import_path` VARCHAR(4096) NOT NULL,
`import_options` VARCHAR(255) DEFAULT NULL,
`import_status` ENUM('queued','working','paused','canceled','completed') NOT NULL,
`import_users` INT UNSIGNED NOT NULL DEFAULT '0',
`import_images` INT UNSIGNED NOT NULL DEFAULT '0',
`import_albums` INT UNSIGNED NOT NULL DEFAULT '0',
`import_time_created` DATETIME DEFAULT NULL,
`import_time_updated` DATETIME DEFAULT NULL,
`import_errors` TINYINT UNSIGNED NOT NULL DEFAULT '0',
`import_started` TINYINT UNSIGNED NOT NULL DEFAULT '0',
`import_continuous` TINYINT UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (`import_id`),
KEY `import_path` (`import_path`(191)) USING BTREE
) ENGINE=%table_engine% DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

View File

@@ -1,13 +1,13 @@
DROP TABLE IF EXISTS `%table_prefix%ip_bans`;
CREATE TABLE `%table_prefix%ip_bans` (
`ip_ban_id` bigint(20) NOT NULL AUTO_INCREMENT,
`ip_ban_date` datetime NOT NULL,
`ip_ban_date_gmt` datetime NOT NULL,
`ip_ban_expires` datetime DEFAULT NULL,
`ip_ban_expires_gmt` datetime DEFAULT NULL,
`ip_ban_ip` varchar(255) NOT NULL,
`ip_ban_message` text,
`ip_ban_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`ip_ban_date` DATETIME NOT NULL,
`ip_ban_date_gmt` DATETIME NOT NULL,
`ip_ban_expires` DATETIME DEFAULT NULL,
`ip_ban_expires_gmt` DATETIME DEFAULT NULL,
`ip_ban_ip` VARCHAR(255) NOT NULL,
`ip_ban_message` TEXT,
PRIMARY KEY (`ip_ban_id`),
KEY `ip_ban_date_gmt` (`ip_ban_date_gmt`),
UNIQUE KEY `ip_ban_ip` (`ip_ban_ip`(191)) USING BTREE
UNIQUE KEY `ip_ban_ip` (`ip_ban_ip`(191)) USING BTREE,
KEY `ip_ban_ip_expires_gmt_id` (`ip_ban_ip`, `ip_ban_expires_gmt`, `ip_ban_id` DESC)
) ENGINE=%table_engine% DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

View File

@@ -1,13 +1,13 @@
DROP TABLE IF EXISTS `%table_prefix%likes`;
CREATE TABLE `%table_prefix%likes` (
`like_id` bigint(32) NOT NULL AUTO_INCREMENT,
`like_date` datetime NOT NULL,
`like_date_gmt` datetime NOT NULL,
`like_user_id` bigint(32) DEFAULT NULL,
`like_content_type` enum('image','album') DEFAULT NULL,
`like_content_id` bigint(32) NOT NULL,
`like_content_user_id` bigint(32) DEFAULT NULL,
`like_ip` varchar(255) NOT NULL,
`like_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`like_date` DATETIME NOT NULL,
`like_date_gmt` DATETIME NOT NULL,
`like_user_id` INT UNSIGNED DEFAULT NULL,
`like_content_type` ENUM('image','album') DEFAULT NULL,
`like_content_id` INT UNSIGNED NOT NULL,
`like_content_user_id` INT UNSIGNED DEFAULT NULL,
`like_ip` VARCHAR(255) NOT NULL,
PRIMARY KEY (`like_id`),
KEY `like_date_gmt` (`like_date_gmt`),
KEY `like_user_id` (`like_user_id`),

View File

@@ -1,9 +1,9 @@
DROP TABLE IF EXISTS `%table_prefix%locks`;
CREATE TABLE `%table_prefix%locks` (
`lock_id` bigint(20) NOT NULL AUTO_INCREMENT,
`lock_name` varchar(255) NOT NULL,
`lock_date_gmt` datetime NOT NULL,
`lock_expires_gmt` datetime DEFAULT NULL,
`lock_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`lock_name` VARCHAR(255) NOT NULL,
`lock_date_gmt` DATETIME NOT NULL,
`lock_expires_gmt` DATETIME DEFAULT NULL,
PRIMARY KEY (`lock_id`),
KEY `lock_date_gmt` (`lock_date_gmt`),
KEY `lock_expires_gmt` (`lock_expires_gmt`),

View File

@@ -1,12 +1,12 @@
DROP TABLE IF EXISTS `%table_prefix%login_connections`;
CREATE TABLE `%table_prefix%login_connections` (
`login_connection_id` bigint(32) NOT NULL AUTO_INCREMENT,
`login_connection_user_id` bigint(32) NOT NULL,
`login_connection_provider_id` bigint(32) NOT NULL,
`login_connection_date_gmt` datetime NOT NULL,
`login_connection_resource_id` varchar(255) NOT NULL,
`login_connection_resource_name` text,
`login_connection_token` text NOT NULL COMMENT 'Ciphertext',
`login_connection_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`login_connection_user_id` INT UNSIGNED NOT NULL,
`login_connection_provider_id` INT UNSIGNED NOT NULL,
`login_connection_date_gmt` DATETIME NOT NULL,
`login_connection_resource_id` VARCHAR(255) NOT NULL,
`login_connection_resource_name` TEXT,
`login_connection_token` TEXT NOT NULL COMMENT 'Ciphertext',
PRIMARY KEY (`login_connection_id`),
UNIQUE KEY `login_connection_unique` (`login_connection_user_id`,`login_connection_provider_id`),
KEY `login_connection_user_id` (`login_connection_user_id`),

View File

@@ -1,16 +1,17 @@
DROP TABLE IF EXISTS `%table_prefix%login_cookies`;
CREATE TABLE `%table_prefix%login_cookies` (
`login_cookie_id` bigint(32) NOT NULL AUTO_INCREMENT,
`login_cookie_user_id` bigint(32) NOT NULL,
`login_cookie_connection_id` bigint(32) DEFAULT 0,
`login_cookie_date_gmt` datetime NOT NULL,
`login_cookie_ip` varchar(255) DEFAULT NULL,
`login_cookie_user_agent` text NOT NULL,
`login_cookie_hash` text NOT NULL,
`login_cookie_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`login_cookie_user_id` INT UNSIGNED NOT NULL,
`login_cookie_connection_id` INT UNSIGNED DEFAULT 0,
`login_cookie_date_gmt` DATETIME NOT NULL,
`login_cookie_ip` VARCHAR(255) DEFAULT NULL,
`login_cookie_user_agent` TEXT NOT NULL,
`login_cookie_hash` TEXT NOT NULL,
PRIMARY KEY (`login_cookie_id`),
UNIQUE KEY `login_cookie_unique` (`login_cookie_user_id`,`login_cookie_connection_id`,`login_cookie_date_gmt`),
KEY `login_cookie_user_id_date_gmt` (`login_cookie_user_id`, `login_cookie_date_gmt`),
KEY `login_cookie_user_id` (`login_cookie_user_id`),
KEY `login_cookie_ip` (`login_cookie_ip`),
KEY `login_cookie_connection_id` (`login_cookie_connection_id`)
KEY `login_cookie_connection_id` (`login_cookie_connection_id`),
KEY `login_cookie_user_id_date_gmt_connection_id` (`login_cookie_user_id`, `login_cookie_date_gmt`, `login_cookie_connection_id`)
) ENGINE=%table_engine% DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

View File

@@ -1,9 +1,9 @@
DROP TABLE IF EXISTS `%table_prefix%login_passwords`;
CREATE TABLE `%table_prefix%login_passwords` (
`login_password_id` bigint(32) NOT NULL AUTO_INCREMENT,
`login_password_user_id` bigint(32) NOT NULL,
`login_password_date_gmt` datetime NOT NULL,
`login_password_hash` text NOT NULL,
`login_password_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`login_password_user_id` INT UNSIGNED NOT NULL,
`login_password_date_gmt` DATETIME NOT NULL,
`login_password_hash` TEXT NOT NULL,
PRIMARY KEY (`login_password_id`),
UNIQUE KEY `login_password_user_id` (`login_password_user_id`)
) ENGINE=%table_engine% DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

View File

@@ -1,14 +1,15 @@
DROP TABLE IF EXISTS `%table_prefix%login_providers`;
CREATE TABLE `%table_prefix%login_providers` (
`login_provider_id` bigint(32) NOT NULL AUTO_INCREMENT,
`login_provider_name` varchar(255) DEFAULT NULL,
`login_provider_label` varchar(255) DEFAULT NULL,
`login_provider_key_id` text DEFAULT NULL,
`login_provider_key_secret` text DEFAULT NULL,
`login_provider_is_enabled` tinyint(1) NOT NULL DEFAULT '1',
`login_provider_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`login_provider_name` VARCHAR(255) DEFAULT NULL,
`login_provider_label` VARCHAR(255) DEFAULT NULL,
`login_provider_key_id` TEXT DEFAULT NULL,
`login_provider_key_secret` TEXT DEFAULT NULL,
`login_provider_is_enabled` TINYINT UNSIGNED NOT NULL DEFAULT '1',
PRIMARY KEY (`login_provider_id`),
UNIQUE KEY `login_provider_name` (`login_provider_name`(191)),
KEY `login_provider_is_enabled` (`login_provider_is_enabled`)
KEY `login_provider_is_enabled` (`login_provider_is_enabled`),
KEY `login_provider_id_is_enabled_name` (`login_provider_id`, `login_provider_is_enabled`, `login_provider_name` DESC)
) ENGINE=%table_engine% DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
INSERT INTO `%table_prefix%login_providers` VALUES ('1', 'facebook', 'Facebook', null, null, '0');
INSERT INTO `%table_prefix%login_providers` VALUES ('2', 'twitter', 'Twitter', null, null, '0');

View File

@@ -1,18 +1,18 @@
DROP TABLE IF EXISTS `%table_prefix%logins`;
CREATE TABLE `%table_prefix%logins` (
`login_id` bigint(32) NOT NULL AUTO_INCREMENT,
`login_user_id` bigint(32) NOT NULL,
`login_type` enum('password','session','cookie','facebook','twitter','google','vk','cookie_facebook','cookie_twitter','cookie_google','cookie_vk') NOT NULL,
`login_ip` varchar(255) DEFAULT NULL,
`login_hostname` text,
`login_date` datetime NOT NULL,
`login_date_gmt` datetime NOT NULL,
`login_resource_id` varchar(255) DEFAULT NULL,
`login_resource_name` text,
`login_resource_avatar` text,
`login_resource_url` text,
`login_secret` text DEFAULT NULL COMMENT 'The secret part',
`login_token_hash` text COMMENT 'Hashed complement to secret if needed',
`login_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`login_user_id` INT UNSIGNED NOT NULL,
`login_type` ENUM('password','session','cookie','facebook','twitter','google','vk','cookie_facebook','cookie_twitter','cookie_google','cookie_vk') NOT NULL,
`login_ip` VARCHAR(255) DEFAULT NULL,
`login_hostname` TEXT,
`login_date` DATETIME NOT NULL,
`login_date_gmt` DATETIME NOT NULL,
`login_resource_id` VARCHAR(255) DEFAULT NULL,
`login_resource_name` TEXT,
`login_resource_avatar` TEXT,
`login_resource_url` TEXT,
`login_secret` TEXT DEFAULT NULL COMMENT 'The secret part',
`login_token_hash` TEXT COMMENT 'Hashed complement to secret if needed',
PRIMARY KEY (`login_id`),
KEY `login_user_id` (`login_user_id`)
) ENGINE=%table_engine% DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

View File

@@ -1,13 +1,13 @@
DROP TABLE IF EXISTS `%table_prefix%notifications`;
CREATE TABLE `%table_prefix%notifications` (
`notification_id` bigint(32) NOT NULL AUTO_INCREMENT,
`notification_date_gmt` datetime NOT NULL,
`notification_user_id` bigint(32) NOT NULL,
`notification_trigger_user_id` bigint(32) DEFAULT NULL,
`notification_type` enum('follow','like') NOT NULL,
`notification_content_type` enum('user','image','album') NOT NULL,
`notification_type_id` bigint(32) NOT NULL COMMENT 'type_id based on action (type) table',
`notification_is_read` tinyint(1) NOT NULL DEFAULT '0',
`notification_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`notification_date_gmt` DATETIME NOT NULL,
`notification_user_id` INT UNSIGNED NOT NULL,
`notification_trigger_user_id` INT UNSIGNED DEFAULT NULL,
`notification_type` ENUM('follow','like') NOT NULL,
`notification_content_type` ENUM('user','image','album') NOT NULL,
`notification_type_id` INT UNSIGNED NOT NULL COMMENT 'type_id based on action (type) table',
`notification_is_read` TINYINT UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (`notification_id`),
KEY `notification_date_gmt` (`notification_date_gmt`),
KEY `notification_user_id` (`notification_user_id`),

View File

@@ -1,21 +1,21 @@
DROP TABLE IF EXISTS `%table_prefix%pages`;
CREATE TABLE `%table_prefix%pages` (
`page_id` bigint(32) NOT NULL AUTO_INCREMENT,
`page_url_key` varchar(32) DEFAULT NULL,
`page_type` enum('internal','link') NOT NULL DEFAULT 'internal',
`page_file_path` varchar(255) DEFAULT NULL,
`page_link_url` text,
`page_icon` varchar(255) DEFAULT NULL,
`page_title` varchar(255) NOT NULL,
`page_description` text,
`page_keywords` text,
`page_is_active` tinyint(1) NOT NULL DEFAULT '1',
`page_is_link_visible` tinyint(1) NOT NULL DEFAULT '1',
`page_attr_target` enum('_self','_blank') DEFAULT '_self',
`page_attr_rel` varchar(255) DEFAULT NULL,
`page_sort_display` int(11) DEFAULT NULL,
`page_internal` varchar(255) DEFAULT NULL,
`page_code` text,
`page_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`page_url_key` VARCHAR(32) DEFAULT NULL,
`page_type` ENUM('internal','link') NOT NULL DEFAULT 'internal',
`page_file_path` VARCHAR(255) DEFAULT NULL,
`page_link_url` TEXT,
`page_icon` VARCHAR(255) DEFAULT NULL,
`page_title` VARCHAR(255) NOT NULL,
`page_description` TEXT,
`page_keywords` TEXT,
`page_is_active` TINYINT UNSIGNED NOT NULL DEFAULT '1',
`page_is_link_visible` TINYINT UNSIGNED NOT NULL DEFAULT '1',
`page_attr_target` ENUM('_self','_blank') DEFAULT '_self',
`page_attr_rel` VARCHAR(255) DEFAULT NULL,
`page_sort_display` INT UNSIGNED DEFAULT NULL,
`page_internal` VARCHAR(255) DEFAULT NULL,
`page_code` TEXT,
PRIMARY KEY (`page_id`),
UNIQUE KEY `page_internal` (`page_internal`(191)),
KEY `page_url_key` (`page_url_key`),

View File

@@ -1,11 +1,11 @@
DROP TABLE IF EXISTS `%table_prefix%queues`;
CREATE TABLE `%table_prefix%queues` (
`queue_id` bigint(32) NOT NULL AUTO_INCREMENT,
`queue_type` enum('storage-delete') NOT NULL,
`queue_date_gmt` datetime NOT NULL,
`queue_args` text NOT NULL,
`queue_join` bigint(32) NOT NULL,
`queue_attempts` varchar(255) DEFAULT '0',
`queue_status` enum('pending','failed') NOT NULL DEFAULT 'pending',
`queue_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`queue_type` ENUM('storage-delete') NOT NULL,
`queue_date_gmt` DATETIME NOT NULL,
`queue_args` TEXT NOT NULL,
`queue_join` INT UNSIGNED NOT NULL,
`queue_attempts` VARCHAR(255) DEFAULT '0',
`queue_status` ENUM('pending','failed') NOT NULL DEFAULT 'pending',
PRIMARY KEY (`queue_id`)
) ENGINE=%table_engine% DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

View File

@@ -1,18 +1,20 @@
DROP TABLE IF EXISTS `%table_prefix%requests`;
CREATE TABLE `%table_prefix%requests` (
`request_id` bigint(32) NOT NULL AUTO_INCREMENT,
`request_type` enum('upload','signup','account-edit','account-password-forgot','account-password-reset','account-resend-activation','account-email-needed','account-change-email','account-activate','login', 'content-password', 'account-two-factor') NOT NULL,
`request_user_id` bigint(32) DEFAULT NULL,
`request_content_id` bigint(32) DEFAULT NULL,
`request_ip` varchar(255) NOT NULL,
`request_date` datetime NOT NULL,
`request_date_gmt` datetime NOT NULL,
`request_result` enum('success','fail') NOT NULL,
`request_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`request_type` ENUM('upload','signup','account-edit','account-password-forgot','account-password-reset','account-resend-activation','account-email-needed','account-change-email','account-activate','login', 'content-password', 'account-two-factor') NOT NULL,
`request_user_id` INT UNSIGNED DEFAULT NULL,
`request_content_id` INT UNSIGNED DEFAULT NULL,
`request_ip` VARCHAR(255) NOT NULL,
`request_date` DATETIME NOT NULL,
`request_date_gmt` DATETIME NOT NULL,
`request_result` ENUM('success','fail') NOT NULL,
PRIMARY KEY (`request_id`),
KEY `request_type` (`request_type`),
KEY `request_user_id` (`request_user_id`),
KEY `request_content_id` (`request_content_id`),
KEY `request_ip` (`request_ip`),
KEY `request_date_gmt` (`request_date_gmt`),
KEY `request_result` (`request_result`)
KEY `request_result` (`request_result`),
KEY `request_result_ip_type_date_gmt` (`request_result`, `request_type`, `request_ip`,`request_date_gmt`),
KEY `request_user_id_result_type_ip` (`request_user_id`, `request_result`, `request_type`, `request_ip`)
) ENGINE=%table_engine% DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

View File

@@ -1,10 +1,10 @@
DROP TABLE IF EXISTS `%table_prefix%settings`;
CREATE TABLE `%table_prefix%settings` (
`setting_id` int(11) NOT NULL AUTO_INCREMENT,
`setting_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`setting_value` text,
`setting_default` text,
`setting_typeset` enum('string','bool') DEFAULT 'string',
`setting_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`setting_name` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`setting_value` TEXT,
`setting_default` TEXT,
`setting_typeset` ENUM('string','bool') DEFAULT 'string',
PRIMARY KEY (`setting_id`),
UNIQUE KEY `setting_name` (`setting_name`) USING BTREE
) ENGINE=%table_engine% DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

View File

@@ -1,21 +1,22 @@
DROP TABLE IF EXISTS `%table_prefix%stats`;
CREATE TABLE `%table_prefix%stats` (
`stat_id` bigint(32) NOT NULL AUTO_INCREMENT,
`stat_type` enum('total','date') NOT NULL,
`stat_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`stat_type` ENUM('total','date') NOT NULL,
`stat_date_gmt` date DEFAULT NULL,
`stat_users` bigint(32) UNSIGNED NOT NULL DEFAULT '0',
`stat_images` bigint(32) UNSIGNED NOT NULL DEFAULT '0',
`stat_albums` bigint(32) UNSIGNED NOT NULL DEFAULT '0',
`stat_tags` bigint(32) UNSIGNED NOT NULL DEFAULT '0',
`stat_cron_runs` bigint(32) UNSIGNED NOT NULL DEFAULT '0',
`stat_cron_time` bigint(32) UNSIGNED NOT NULL DEFAULT '0',
`stat_image_views` bigint(32) UNSIGNED NOT NULL DEFAULT '0',
`stat_album_views` bigint(32) UNSIGNED NOT NULL DEFAULT '0',
`stat_image_likes` bigint(32) UNSIGNED NOT NULL DEFAULT '0',
`stat_album_likes` bigint(32) UNSIGNED NOT NULL DEFAULT '0',
`stat_disk_used` bigint(32) UNSIGNED NOT NULL DEFAULT '0',
`stat_users` INT UNSIGNED NOT NULL DEFAULT '0',
`stat_images` INT UNSIGNED NOT NULL DEFAULT '0',
`stat_albums` INT UNSIGNED NOT NULL DEFAULT '0',
`stat_tags` INT UNSIGNED NOT NULL DEFAULT '0',
`stat_cron_runs` INT UNSIGNED NOT NULL DEFAULT '0',
`stat_cron_time` INT UNSIGNED NOT NULL DEFAULT '0',
`stat_image_views` INT UNSIGNED NOT NULL DEFAULT '0',
`stat_album_views` INT UNSIGNED NOT NULL DEFAULT '0',
`stat_image_likes` INT UNSIGNED NOT NULL DEFAULT '0',
`stat_album_likes` INT UNSIGNED NOT NULL DEFAULT '0',
`stat_disk_used` BIGINT UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (`stat_id`),
UNIQUE KEY `stat_date_gmt` (`stat_date_gmt`) USING BTREE,
KEY `stat_type` (`stat_type`)
KEY `stat_type` (`stat_type`),
KEY `stat_type_date_gmt` (`stat_type`, `stat_date_gmt` DESC)
) ENGINE=%table_engine% DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
INSERT INTO `%table_prefix%stats` (stat_id, stat_type) VALUES (1, 'total');

View File

@@ -1,8 +1,8 @@
DROP TABLE IF EXISTS `%table_prefix%storage_apis`;
CREATE TABLE `%table_prefix%storage_apis` (
`storage_api_id` bigint(32) NOT NULL AUTO_INCREMENT,
`storage_api_name` varchar(255) NOT NULL,
`storage_api_type` varchar(255) NOT NULL,
`storage_api_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`storage_api_name` VARCHAR(255) NOT NULL,
`storage_api_type` VARCHAR(255) NOT NULL,
PRIMARY KEY (`storage_api_id`)
) ENGINE=%table_engine% DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
INSERT INTO `%table_prefix%storage_apis` VALUES ('1', 'Amazon S3', 's3');

View File

@@ -1,23 +1,23 @@
DROP TABLE IF EXISTS `%table_prefix%storages`;
CREATE TABLE `%table_prefix%storages` (
`storage_id` bigint(32) NOT NULL AUTO_INCREMENT,
`storage_api_id` bigint(32) NOT NULL,
`storage_name` varchar(255) NOT NULL,
`storage_service` varchar(255) DEFAULT NULL,
`storage_url` varchar(255) NOT NULL,
`storage_bucket` varchar(255) DEFAULT NULL,
`storage_region` varchar(255) DEFAULT NULL,
`storage_server` varchar(255) DEFAULT NULL,
`storage_account_id` varchar(255) DEFAULT NULL,
`storage_account_name` varchar(255) DEFAULT NULL,
`storage_key` text,
`storage_secret` text,
`storage_is_https` tinyint(1) NOT NULL DEFAULT '0',
`storage_is_active` tinyint(1) NOT NULL DEFAULT '0',
`storage_capacity` bigint(32) DEFAULT NULL,
`storage_space_used` bigint(32) DEFAULT '0',
`storage_type_chain` tinyint(3) NOT NULL DEFAULT '1',
`storage_use_path_style_endpoint` tinyint(1) NOT NULL DEFAULT '0',
`storage_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`storage_api_id` INT UNSIGNED NOT NULL,
`storage_name` VARCHAR(255) NOT NULL,
`storage_service` VARCHAR(255) DEFAULT NULL,
`storage_url` VARCHAR(255) NOT NULL,
`storage_bucket` VARCHAR(255) DEFAULT NULL,
`storage_region` VARCHAR(255) DEFAULT NULL,
`storage_server` VARCHAR(255) DEFAULT NULL,
`storage_account_id` VARCHAR(255) DEFAULT NULL,
`storage_account_name` VARCHAR(255) DEFAULT NULL,
`storage_key` TEXT,
`storage_secret` TEXT,
`storage_is_https` TINYINT UNSIGNED NOT NULL DEFAULT '0',
`storage_is_active` TINYINT UNSIGNED NOT NULL DEFAULT '0',
`storage_capacity` BIGINT UNSIGNED DEFAULT NULL,
`storage_space_used` BIGINT UNSIGNED DEFAULT '0',
`storage_type_chain` TINYINT UNSIGNED NOT NULL DEFAULT '1',
`storage_use_path_style_endpoint` TINYINT UNSIGNED NOT NULL DEFAULT '0',
`storage_deleted_at` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`storage_id`),
KEY `storage_api_id` (`storage_api_id`),

View File

@@ -1,12 +1,12 @@
DROP TABLE IF EXISTS `%table_prefix%tags`;
CREATE TABLE `%table_prefix%tags` (
`tag_id` bigint(32) NOT NULL AUTO_INCREMENT,
`tag_name` varchar(32) COLLATE utf8mb4_bin NOT NULL,
`tag_description` text,
`tag_user_id` bigint(32) NOT NULL,
`tag_date_gmt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`tag_files` bigint(32) NOT NULL DEFAULT 0,
`tag_views` bigint(32) NOT NULL DEFAULT 0,
`tag_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`tag_name` VARCHAR(32) COLLATE utf8mb4_bin NOT NULL,
`tag_description` TEXT,
`tag_user_id` INT UNSIGNED NOT NULL,
`tag_date_gmt` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`tag_files` INT UNSIGNED NOT NULL DEFAULT 0,
`tag_views` INT UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (`tag_id`),
UNIQUE KEY `tag_name` (`tag_name`) USING BTREE,
KEY `tag_user_id` (`tag_user_id`),
@@ -15,5 +15,6 @@ CREATE TABLE `%table_prefix%tags` (
KEY `tag_views` (`tag_views`),
KEY `tag_user_id_date_gmt` (`tag_user_id`,`tag_date_gmt`),
KEY `tag_user_id_files` (`tag_user_id`,`tag_files`),
KEY `tag_user_id_views` (`tag_user_id`,`tag_views`)
KEY `tag_user_id_views` (`tag_user_id`,`tag_views`),
KEY `tag_files_name` (`tag_files` DESC, `tag_name` ASC)
) ENGINE=%table_engine% DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

View File

@@ -1,10 +1,10 @@
DROP TABLE IF EXISTS `%table_prefix%tags_albums`;
CREATE TABLE `%table_prefix%tags_albums` (
`tag_album_tag_id` bigint(32) NOT NULL,
`tag_album_album_id` bigint(32) NOT NULL,
`tag_album_user_id` bigint(32) NOT NULL,
`tag_album_count` int(11) NOT NULL DEFAULT 0,
`tag_album_last_used_datetime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`tag_album_tag_id` INT UNSIGNED NOT NULL,
`tag_album_album_id` INT UNSIGNED NOT NULL,
`tag_album_user_id` INT UNSIGNED NOT NULL,
`tag_album_count` INT UNSIGNED NOT NULL DEFAULT 0,
`tag_album_last_used_datetime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (tag_album_tag_id) REFERENCES `%table_prefix%tags` (tag_id) ON DELETE CASCADE,
FOREIGN KEY (tag_album_album_id) REFERENCES `%table_prefix%albums` (album_id) ON DELETE CASCADE,
FOREIGN KEY (tag_album_user_id) REFERENCES `%table_prefix%users` (user_id) ON DELETE CASCADE,

View File

@@ -1,7 +1,7 @@
DROP TABLE IF EXISTS `%table_prefix%tags_files`;
CREATE TABLE `%table_prefix%tags_files` (
`tag_file_tag_id` bigint(32) NOT NULL,
`tag_file_file_id` bigint(32) NOT NULL,
`tag_file_tag_id` INT UNSIGNED NOT NULL,
`tag_file_file_id` INT UNSIGNED NOT NULL,
FOREIGN KEY (tag_file_tag_id) REFERENCES `%table_prefix%tags` (tag_id) ON DELETE CASCADE,
FOREIGN KEY (tag_file_file_id) REFERENCES `%table_prefix%images` (image_id) ON DELETE CASCADE,
UNIQUE INDEX `tag_file_UNIQUE` (`tag_file_tag_id` ASC, `tag_file_file_id` ASC)

View File

@@ -1,9 +1,9 @@
DROP TABLE IF EXISTS `%table_prefix%tags_users`;
CREATE TABLE `%table_prefix%tags_users` (
`tag_user_tag_id` bigint(32) NOT NULL,
`tag_user_user_id` bigint(32) NOT NULL,
`tag_user_count` int(11) NOT NULL DEFAULT 0,
`tag_user_last_used_datetime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`tag_user_tag_id` INT UNSIGNED NOT NULL,
`tag_user_user_id` INT UNSIGNED NOT NULL,
`tag_user_count` INT UNSIGNED NOT NULL DEFAULT 0,
`tag_user_last_used_datetime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (tag_user_tag_id) REFERENCES `%table_prefix%tags` (tag_id) ON DELETE CASCADE,
FOREIGN KEY (tag_user_user_id) REFERENCES `%table_prefix%users` (user_id) ON DELETE CASCADE,
UNIQUE INDEX `tag_user_UNIQUE` (`tag_user_tag_id` ASC, `tag_user_user_id` ASC),

View File

@@ -1,9 +1,9 @@
DROP TABLE IF EXISTS `%table_prefix%two_factors`;
CREATE TABLE `%table_prefix%two_factors` (
`two_factor_id` bigint(32) NOT NULL AUTO_INCREMENT,
`two_factor_user_id` bigint(32) DEFAULT NULL,
`two_factor_date_gmt` datetime NOT NULL,
`two_factor_secret` text NOT NULL,
`two_factor_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`two_factor_user_id` INT UNSIGNED DEFAULT NULL,
`two_factor_date_gmt` DATETIME NOT NULL,
`two_factor_secret` TEXT NOT NULL,
PRIMARY KEY (`two_factor_id`),
KEY `two_factor_user_id` (`two_factor_user_id`),
KEY `two_factor_date_gmt` (`two_factor_date_gmt`)

View File

@@ -0,0 +1,17 @@
DROP TABLE IF EXISTS `%table_prefix%uploads`;
CREATE TABLE `%table_prefix%uploads` (
`upload_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`upload_user_id` INT UNSIGNED DEFAULT NULL,
`upload_uploader_ip` VARCHAR(255) NOT NULL,
`upload_token` VARCHAR(64) NOT NULL,
`upload_checksum` VARCHAR(32) NOT NULL,
`upload_params` JSON NOT NULL,
`upload_chunks` INT UNSIGNED NOT NULL,
`upload_date_gmt` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`upload_completed` TINYINT UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (`upload_id`),
KEY `upload_id_token` (`upload_id`, `upload_token`),
KEY `upload_id_token_user_id` (`upload_id`, `upload_token`, `upload_user_id`),
KEY `upload_date_gmt` (`upload_date_gmt`),
KEY `upload_uploader_ip_date_gmt_checksum` (`upload_uploader_ip`, `upload_date_gmt`, `upload_checksum`)
) ENGINE=%table_engine% DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

View File

@@ -0,0 +1,10 @@
DROP TABLE IF EXISTS `%table_prefix%uploads_chunks`;
CREATE TABLE `%table_prefix%uploads_chunks` (
`upload_chunk_upload_id` INT UNSIGNED NOT NULL,
`upload_chunk_index` INT UNSIGNED NOT NULL,
`upload_chunk_path` VARCHAR(4096) DEFAULT NULL,
`upload_chunk_date_gmt` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`upload_chunk_upload_id`, `upload_chunk_index`),
FOREIGN KEY (upload_chunk_upload_id) REFERENCES `%table_prefix%uploads` (upload_id) ON DELETE CASCADE,
KEY `upload_chunk_date_gmt` (`upload_chunk_date_gmt`)
) ENGINE=%table_engine% DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

View File

@@ -1,38 +1,38 @@
DROP TABLE IF EXISTS `%table_prefix%users`;
CREATE TABLE `%table_prefix%users` (
`user_id` bigint(32) NOT NULL AUTO_INCREMENT,
`user_name` varchar(255) DEFAULT NULL,
`user_username` varchar(255) NOT NULL,
`user_date` datetime NOT NULL,
`user_date_gmt` datetime NOT NULL,
`user_email` varchar(255) DEFAULT NULL,
`user_avatar_filename` varchar(255) DEFAULT NULL,
`user_facebook_username` varchar(255) DEFAULT NULL,
`user_twitter_username` varchar(255) DEFAULT NULL,
`user_website` varchar(255) DEFAULT NULL,
`user_background_filename` varchar(255) DEFAULT NULL,
`user_bio` varchar(255) DEFAULT NULL,
`user_timezone` varchar(255) NOT NULL,
`user_language` varchar(255) DEFAULT NULL,
`user_status` enum('valid','awaiting-confirmation','awaiting-email','banned') NOT NULL,
`user_is_admin` tinyint(1) NOT NULL DEFAULT '0',
`user_is_manager` tinyint(1) NOT NULL DEFAULT '0',
`user_is_private` tinyint(1) NOT NULL DEFAULT '0',
`user_palette_id` int(11) NOT NULL DEFAULT '0',
`user_newsletter_subscribe` tinyint(1) NOT NULL DEFAULT '1',
`user_show_nsfw_listings` tinyint(1) NOT NULL DEFAULT '0',
`user_image_count` bigint(32) NOT NULL DEFAULT '0',
`user_album_count` bigint(32) NOT NULL DEFAULT '0',
`user_image_keep_exif` tinyint(1) NOT NULL DEFAULT '1',
`user_file_meta_tag_camera_model` tinyint(1) NOT NULL DEFAULT '1',
`user_image_expiration` varchar(255) DEFAULT NULL,
`user_registration_ip` varchar(255) NOT NULL,
`user_likes` bigint(32) NOT NULL DEFAULT '0' COMMENT 'Likes made to content owned by this user',
`user_liked` bigint(32) NOT NULL DEFAULT '0' COMMENT 'Likes made by this user',
`user_following` bigint(32) NOT NULL DEFAULT '0',
`user_followers` bigint(32) NOT NULL DEFAULT '0',
`user_content_views` bigint(32) NOT NULL DEFAULT '0',
`user_notifications_unread` bigint(32) NOT NULL DEFAULT '0',
`user_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`user_name` VARCHAR(255) DEFAULT NULL,
`user_username` VARCHAR(255) NOT NULL,
`user_date` DATETIME NOT NULL,
`user_date_gmt` DATETIME NOT NULL,
`user_email` VARCHAR(255) DEFAULT NULL,
`user_avatar_filename` VARCHAR(255) DEFAULT NULL,
`user_facebook_username` VARCHAR(255) DEFAULT NULL,
`user_twitter_username` VARCHAR(255) DEFAULT NULL,
`user_website` VARCHAR(255) DEFAULT NULL,
`user_background_filename` VARCHAR(255) DEFAULT NULL,
`user_bio` VARCHAR(255) DEFAULT NULL,
`user_timezone` VARCHAR(255) NOT NULL,
`user_language` VARCHAR(255) DEFAULT NULL,
`user_status` ENUM('valid','awaiting-confirmation','awaiting-email','banned') NOT NULL,
`user_is_admin` TINYINT UNSIGNED NOT NULL DEFAULT '0',
`user_is_manager` TINYINT UNSIGNED NOT NULL DEFAULT '0',
`user_is_private` TINYINT UNSIGNED NOT NULL DEFAULT '0',
`user_palette_id` INT UNSIGNED NOT NULL DEFAULT '0',
`user_newsletter_subscribe` TINYINT UNSIGNED NOT NULL DEFAULT '1',
`user_show_nsfw_listings` TINYINT UNSIGNED NOT NULL DEFAULT '0',
`user_image_count` INT UNSIGNED NOT NULL DEFAULT '0',
`user_album_count` INT UNSIGNED NOT NULL DEFAULT '0',
`user_image_keep_exif` TINYINT UNSIGNED NOT NULL DEFAULT '1',
`user_file_meta_tag_camera_model` TINYINT UNSIGNED NOT NULL DEFAULT '1',
`user_image_expiration` VARCHAR(255) DEFAULT NULL,
`user_registration_ip` VARCHAR(255) NOT NULL,
`user_likes` INT UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Likes made to content owned by this user',
`user_liked` INT UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Likes made by this user',
`user_following` INT UNSIGNED NOT NULL DEFAULT '0',
`user_followers` INT UNSIGNED NOT NULL DEFAULT '0',
`user_content_views` INT UNSIGNED NOT NULL DEFAULT '0',
`user_notifications_unread` INT UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (`user_id`),
UNIQUE KEY `username` (`user_username`(191)) USING BTREE,
UNIQUE KEY `email` (`user_email`(191)) USING BTREE,

View File

@@ -1,10 +1,10 @@
DROP TABLE IF EXISTS `%table_prefix%variables`;
CREATE TABLE `%table_prefix%variables` (
`variable_id` int(11) NOT NULL AUTO_INCREMENT,
`variable_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`variable_datetime_utc` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`variable_value` text,
`variable_type` enum('string','bool','int','float','array','object') DEFAULT 'string',
`variable_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`variable_name` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`variable_datetime_utc` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`variable_value` TEXT,
`variable_type` ENUM('string','bool','int','float','array','object') DEFAULT 'string',
PRIMARY KEY (`variable_id`),
UNIQUE KEY `variable_name` (`variable_name`) USING BTREE
) ENGINE=%table_engine% DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

View File

@@ -1,22 +1,22 @@
DROP TABLE IF EXISTS `%table_prefix%albums`;
CREATE TABLE `%table_prefix%albums` (
`album_id` bigint(32) NOT NULL AUTO_INCREMENT,
`album_name` varchar(100) NOT NULL,
`album_user_id` bigint(32) DEFAULT NULL,
`album_date` datetime NOT NULL,
`album_date_gmt` datetime NOT NULL,
`album_creation_ip` varchar(255) NOT NULL,
`album_privacy` enum('public','password','private','private_but_link','custom') DEFAULT 'public',
`album_privacy_extra` text,
`album_password` text,
`album_image_count` bigint(32) NOT NULL DEFAULT '0',
`album_description` text,
`album_likes` bigint(32) NOT NULL DEFAULT '0',
`album_views` bigint(32) NOT NULL DEFAULT '0',
`album_cover_id` bigint(32) DEFAULT NULL,
`album_parent_id` bigint(32) DEFAULT NULL,
`album_cta_enable` tinyint(1) NOT NULL DEFAULT '0',
`album_cta` text,
`album_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`album_name` VARCHAR(100) NOT NULL,
`album_user_id` INT UNSIGNED DEFAULT NULL,
`album_date` DATETIME NOT NULL,
`album_date_gmt` DATETIME NOT NULL,
`album_creation_ip` VARCHAR(255) NOT NULL,
`album_privacy` ENUM('public','password','private','private_but_link','custom') DEFAULT 'public',
`album_privacy_extra` TEXT,
`album_password` TEXT,
`album_image_count` INT UNSIGNED NOT NULL DEFAULT '0',
`album_description` TEXT,
`album_likes` INT UNSIGNED NOT NULL DEFAULT '0',
`album_views` INT UNSIGNED NOT NULL DEFAULT '0',
`album_cover_id` INT UNSIGNED DEFAULT NULL,
`album_parent_id` INT UNSIGNED DEFAULT NULL,
`album_cta_enable` TINYINT UNSIGNED NOT NULL DEFAULT '0',
`album_cta` TEXT,
PRIMARY KEY (`album_id`),
KEY `album_name` (`album_name`),
KEY `album_user_id` (`album_user_id`),
@@ -27,5 +27,6 @@ CREATE TABLE `%table_prefix%albums` (
KEY `album_likes` (`album_likes`),
KEY `album_views` (`album_views`),
KEY `album_parent_id` (`album_parent_id`),
KEY `album_user_id_parent_id_name` (`album_user_id`, `album_parent_id`, `album_name`),
FULLTEXT KEY `searchindex` (`album_name`,`album_description`)
) ENGINE=%table_engine% DEFAULT CHARSET=utf8mb4;

View File

@@ -1,10 +1,10 @@
DROP TABLE IF EXISTS `%table_prefix%api_keys`;
CREATE TABLE `%table_prefix%api_keys` (
`api_key_id` bigint(32) NOT NULL AUTO_INCREMENT,
`api_key_user_id` bigint(32) DEFAULT NULL,
`api_key_name` varchar(100) DEFAULT NULL,
`api_key_date_gmt` datetime NOT NULL,
`api_key_hash` text NOT NULL,
`api_key_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`api_key_user_id` INT UNSIGNED DEFAULT NULL,
`api_key_name` VARCHAR(100) DEFAULT NULL,
`api_key_date_gmt` DATETIME NOT NULL,
`api_key_hash` TEXT NOT NULL,
PRIMARY KEY (`api_key_id`),
KEY `api_key_user_id` (`api_key_user_id`),
KEY `api_key_name` (`api_key_name`),

View File

@@ -1,10 +1,10 @@
DROP TABLE IF EXISTS `%table_prefix%assets`;
CREATE TABLE `%table_prefix%assets` (
`asset_id` bigint(32) NOT NULL AUTO_INCREMENT,
`asset_key` varchar(255) NOT NULL,
`asset_md5` varchar(32) NOT NULL,
`asset_filename` varchar(255) NOT NULL,
`asset_file_path` varchar(255) NOT NULL,
`asset_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`asset_key` VARCHAR(255) NOT NULL,
`asset_checksum` VARCHAR(32) NOT NULL,
`asset_filename` VARCHAR(255) NOT NULL,
`asset_file_path` VARCHAR(255) NOT NULL,
`asset_blob` blob,
PRIMARY KEY (`asset_id`),
UNIQUE KEY `key` (`asset_key`) USING BTREE,

View File

@@ -1,9 +1,10 @@
DROP TABLE IF EXISTS `%table_prefix%categories`;
CREATE TABLE `%table_prefix%categories` (
`category_id` bigint(32) NOT NULL AUTO_INCREMENT,
`category_name` varchar(32) NOT NULL,
`category_url_key` varchar(32) COLLATE utf8mb4_bin NOT NULL,
`category_description` text,
`category_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`category_name` VARCHAR(32) NOT NULL,
`category_url_key` VARCHAR(32) COLLATE utf8mb4_bin NOT NULL,
`category_description` TEXT,
PRIMARY KEY (`category_id`),
KEY `category_name` (`category_name`),
UNIQUE KEY `url_key` (`category_url_key`) USING BTREE
) ENGINE=%table_engine% DEFAULT CHARSET=utf8mb4;

View File

@@ -1,13 +1,13 @@
DROP TABLE IF EXISTS `%table_prefix%confirmations`;
CREATE TABLE `%table_prefix%confirmations` (
`confirmation_id` bigint(32) NOT NULL AUTO_INCREMENT,
`confirmation_user_id` bigint(32) NOT NULL,
`confirmation_type` enum('account-activate','account-change-email','account-password-forgot') NOT NULL,
`confirmation_date` datetime NOT NULL,
`confirmation_date_gmt` datetime NOT NULL,
`confirmation_token_hash` varchar(255) NOT NULL,
`confirmation_status` enum('active','valid','invalid') NOT NULL,
`confirmation_extra` text,
`confirmation_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`confirmation_user_id` INT UNSIGNED NOT NULL,
`confirmation_type` ENUM('account-activate','account-change-email','account-password-forgot') NOT NULL,
`confirmation_date` DATETIME NOT NULL,
`confirmation_date_gmt` DATETIME NOT NULL,
`confirmation_token_hash` VARCHAR(255) NOT NULL,
`confirmation_status` ENUM('active','valid','invalid') NOT NULL,
`confirmation_extra` TEXT,
PRIMARY KEY (`confirmation_id`),
KEY `confirmation_user` (`confirmation_user_id`),
KEY `confirmation_user_type` (`confirmation_user_id`, `confirmation_type`),

View File

@@ -1,20 +1,20 @@
DROP TABLE IF EXISTS `%table_prefix%deletions`;
CREATE TABLE `%table_prefix%deletions` (
`deleted_id` bigint(32) NOT NULL AUTO_INCREMENT,
`deleted_date_gmt` datetime NOT NULL,
`deleted_content_id` bigint(32) NOT NULL,
`deleted_content_date_gmt` datetime NOT NULL,
`deleted_content_user_id` bigint(32) DEFAULT NULL,
`deleted_content_ip` varchar(255) NOT NULL,
`deleted_content_md5` varchar(32) DEFAULT NULL,
`deleted_content_original_filename` varchar(255) DEFAULT NULL,
`deleted_content_views` bigint(32) NOT NULL DEFAULT '0',
`deleted_content_likes` bigint(32) NOT NULL DEFAULT '0',
`deleted_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`deleted_date_gmt` DATETIME NOT NULL,
`deleted_content_id` INT UNSIGNED NOT NULL,
`deleted_content_date_gmt` DATETIME NOT NULL,
`deleted_content_user_id` INT UNSIGNED DEFAULT NULL,
`deleted_content_ip` VARCHAR(255) NOT NULL,
`deleted_content_checksum` VARCHAR(32) DEFAULT NULL,
`deleted_content_original_filename` VARCHAR(255) DEFAULT NULL,
`deleted_content_views` INT UNSIGNED NOT NULL DEFAULT '0',
`deleted_content_likes` INT UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (`deleted_id`),
KEY `deleted_content_id` (`deleted_content_id`),
KEY `deleted_content_user_id` (`deleted_content_user_id`),
KEY `deleted_content_ip` (`deleted_content_ip`),
KEY `deleted_content_md5` (`deleted_content_md5`),
KEY `deleted_content_checksum` (`deleted_content_checksum`),
KEY `deleted_content_views` (`deleted_content_views`),
KEY `deleted_content_likes` (`deleted_content_likes`)
) ENGINE=%table_engine% DEFAULT CHARSET=utf8mb4;

View File

@@ -1,12 +1,12 @@
DROP TABLE IF EXISTS `%table_prefix%follows`;
CREATE TABLE `%table_prefix%follows` (
`follow_id` bigint(32) NOT NULL AUTO_INCREMENT,
`follow_date` datetime NOT NULL,
`follow_date_gmt` datetime NOT NULL,
`follow_user_id` bigint(32) NOT NULL,
`follow_followed_user_id` bigint(32) NOT NULL,
`follow_ip` varchar(255) NOT NULL,
`follow_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`follow_date` DATETIME NOT NULL,
`follow_date_gmt` DATETIME NOT NULL,
`follow_user_id` INT UNSIGNED NOT NULL,
`follow_followed_user_id` INT UNSIGNED NOT NULL,
`follow_ip` VARCHAR(255) NOT NULL,
PRIMARY KEY (`follow_id`),
KEY `follow_user_id` (`follow_user_id`),
KEY `follow_followed_user_id` (`follow_followed_user_id`)
) ENGINE=%table_engine% DEFAULT CHARSET=utf8;
) ENGINE=%table_engine% DEFAULT CHARSET=utf8;

View File

@@ -1,39 +1,39 @@
DROP TABLE IF EXISTS `%table_prefix%images`;
CREATE TABLE `%table_prefix%images` (
`image_id` bigint(32) NOT NULL AUTO_INCREMENT,
`image_name` varchar(255) NOT NULL,
`image_extension` varchar(255) NOT NULL,
`image_size` bigint(11) UNSIGNED NOT NULL,
`image_width` int(11) NOT NULL,
`image_height` int(11) NOT NULL,
`image_date` datetime NOT NULL,
`image_date_gmt` datetime NOT NULL,
`image_title` varchar(100) DEFAULT NULL,
`image_description` text,
`image_nsfw` tinyint(1) NOT NULL DEFAULT '0',
`image_user_id` bigint(32) DEFAULT NULL,
`image_album_id` bigint(32) DEFAULT NULL,
`image_uploader_ip` varchar(255) NOT NULL,
`image_storage_mode` enum('datefolder','direct','old','path') NOT NULL DEFAULT 'datefolder',
`image_path` varchar(4096) DEFAULT NULL,
`image_storage_id` bigint(32) DEFAULT NULL,
`image_md5` varchar(32) NOT NULL,
`image_source_md5` varchar(32) DEFAULT NULL,
`image_original_filename` varchar(255) NOT NULL,
`image_original_exifdata` mediumtext,
`image_views` bigint(32) NOT NULL DEFAULT '0',
`image_category_id` bigint(32) DEFAULT NULL,
`image_chain` tinyint(3) NOT NULL,
`image_thumb_size` int(11) NOT NULL,
`image_medium_size` int(11) NOT NULL DEFAULT '0',
`image_frame_size` int(11) NOT NULL DEFAULT '0',
`image_expiration_date_gmt` datetime DEFAULT NULL,
`image_likes` bigint(32) NOT NULL DEFAULT '0',
`image_is_animated` tinyint(1) NOT NULL DEFAULT '0',
`image_is_approved` tinyint(1) NOT NULL DEFAULT '1',
`image_is_360` tinyint(1) NOT NULL DEFAULT '0',
`image_duration` int(11) NOT NULL DEFAULT '0',
`image_type` tinyint(3) UNSIGNED as (case
`image_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`image_name` VARCHAR(255) NOT NULL,
`image_extension` VARCHAR(255) NOT NULL,
`image_size` BIGINT UNSIGNED NOT NULL,
`image_width` INT UNSIGNED NOT NULL,
`image_height` INT UNSIGNED NOT NULL,
`image_date` DATETIME NOT NULL,
`image_date_gmt` DATETIME NOT NULL,
`image_title` VARCHAR(100) DEFAULT NULL,
`image_description` TEXT,
`image_nsfw` TINYINT UNSIGNED NOT NULL DEFAULT '0',
`image_user_id` INT UNSIGNED DEFAULT NULL,
`image_album_id` INT UNSIGNED DEFAULT NULL,
`image_uploader_ip` VARCHAR(255) NOT NULL,
`image_storage_mode` ENUM('datefolder','direct','old','path') NOT NULL DEFAULT 'datefolder',
`image_path` VARCHAR(4096) DEFAULT NULL,
`image_storage_id` INT UNSIGNED DEFAULT NULL,
`image_checksum` VARCHAR(32) NOT NULL,
`image_source_checksum` VARCHAR(32) DEFAULT NULL,
`image_original_filename` VARCHAR(255) NOT NULL,
`image_original_exifdata` MEDIUMTEXT,
`image_views` INT UNSIGNED NOT NULL DEFAULT '0',
`image_category_id` INT UNSIGNED DEFAULT NULL,
`image_chain` TINYINT UNSIGNED NOT NULL,
`image_thumb_size` INT UNSIGNED NOT NULL,
`image_medium_size` INT UNSIGNED NOT NULL DEFAULT '0',
`image_frame_size` INT UNSIGNED NOT NULL DEFAULT '0',
`image_expiration_date_gmt` DATETIME DEFAULT NULL,
`image_likes` INT UNSIGNED NOT NULL DEFAULT '0',
`image_is_animated` TINYINT UNSIGNED NOT NULL DEFAULT '0',
`image_is_approved` TINYINT UNSIGNED NOT NULL DEFAULT '1',
`image_is_360` TINYINT UNSIGNED NOT NULL DEFAULT '0',
`image_duration` INT UNSIGNED NOT NULL DEFAULT '0',
`image_type` TINYINT UNSIGNED as (case
when `image_extension` in ('pdf','doc','md') then 4
when `image_extension` in ('mp3','m4a','wav') then 3
when `image_extension` in ('mp4','webm','mov') then 2
@@ -53,8 +53,8 @@ CREATE TABLE `%table_prefix%images` (
KEY `image_storage_mode` (`image_storage_mode`),
KEY `image_path` (`image_path`(255)),
KEY `image_storage_id` (`image_storage_id`),
KEY `image_md5` (`image_md5`),
KEY `image_source_md5` (`image_source_md5`),
KEY `image_checksum` (`image_checksum`),
KEY `image_source_checksum` (`image_source_checksum`),
KEY `image_views` (`image_views`),
KEY `image_category_id` (`image_category_id`),
KEY `image_chain` (`image_chain`),
@@ -66,5 +66,6 @@ CREATE TABLE `%table_prefix%images` (
KEY `image_album_id_image_id` (`image_album_id`, `image_id`),
KEY `image_duration` (`image_duration`),
KEY `image_type` (`image_type`),
FULLTEXT KEY `searchindex` (`image_name`,`image_title`,`image_description`,`image_original_filename`)
FULLTEXT KEY `searchindex` (`image_name`,`image_title`,`image_description`,`image_original_filename`),
KEY `image_uploader_ip_date_gmt_checksum_source_checksum` (`image_uploader_ip`, `image_date_gmt`, `image_checksum`, `image_source_checksum`)
) ENGINE=%table_engine% DEFAULT CHARSET=utf8mb4;

View File

@@ -1,6 +1,6 @@
DROP TABLE IF EXISTS `%table_prefix%images_hash`;
CREATE TABLE `%table_prefix%images_hash` (
`image_hash_image_id` bigint(32) NOT NULL,
`image_hash_hash` text NOT NULL,
`image_hash_image_id` INT UNSIGNED NOT NULL,
`image_hash_hash` TEXT NOT NULL,
PRIMARY KEY (`image_hash_image_id`)
) ENGINE=%table_engine% DEFAULT CHARSET=utf8mb4;

View File

@@ -1,10 +1,10 @@
DROP TABLE IF EXISTS `%table_prefix%importing`;
CREATE TABLE `%table_prefix%importing` (
`importing_id` bigint(32) NOT NULL AUTO_INCREMENT,
`importing_import_id` bigint(32) NOT NULL,
`importing_path` varchar(4096) NOT NULL,
`importing_content_type` enum('user','album','image') NOT NULL,
`importing_content_id` bigint(32) DEFAULT NULL,
`importing_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`importing_import_id` INT UNSIGNED NOT NULL,
`importing_path` VARCHAR(4096) NOT NULL,
`importing_content_type` ENUM('user','album','image') NOT NULL,
`importing_content_id` INT UNSIGNED DEFAULT NULL,
PRIMARY KEY (`importing_id`),
UNIQUE KEY `importing_path` (`importing_path`(767))
) ENGINE=%table_engine% DEFAULT CHARSET=utf8mb4;

View File

@@ -1,21 +1,21 @@
DROP TABLE IF EXISTS `%table_prefix%imports`;
CREATE TABLE `%table_prefix%imports` (
`import_id` bigint(32) NOT NULL AUTO_INCREMENT,
`import_path` varchar(4096) NOT NULL,
`import_options` varchar(255) DEFAULT NULL,
`import_status` enum('queued','working','paused','canceled','completed') NOT NULL,
`import_users` bigint(32) NOT NULL DEFAULT '0',
`import_images` bigint(32) NOT NULL DEFAULT '0',
`import_albums` bigint(32) NOT NULL DEFAULT '0',
`import_time_created` datetime DEFAULT NULL,
`import_time_updated` datetime DEFAULT NULL,
`import_errors` tinyint(1) NOT NULL DEFAULT '0',
`import_started` tinyint(1) NOT NULL DEFAULT '0',
`import_continuous` tinyint(1) NOT NULL DEFAULT '0',
`import_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`import_path` VARCHAR(4096) NOT NULL,
`import_options` VARCHAR(255) DEFAULT NULL,
`import_status` ENUM('queued','working','paused','canceled','completed') NOT NULL,
`import_users` INT UNSIGNED NOT NULL DEFAULT '0',
`import_images` INT UNSIGNED NOT NULL DEFAULT '0',
`import_albums` INT UNSIGNED NOT NULL DEFAULT '0',
`import_time_created` DATETIME DEFAULT NULL,
`import_time_updated` DATETIME DEFAULT NULL,
`import_errors` TINYINT UNSIGNED NOT NULL DEFAULT '0',
`import_started` TINYINT UNSIGNED NOT NULL DEFAULT '0',
`import_continuous` TINYINT UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (`import_id`),
KEY `import_path` (`import_path`(767)) USING BTREE
) ENGINE=%table_engine% DEFAULT CHARSET=utf8mb4;
INSERT INTO `%table_prefix%imports` VALUES ('1', '%rootPath%importing/no-parse', 'a:1:{s:4:"root";s:5:"plain";}', 'working', '0', '0', '0', NOW(), NOW(), '0', '1', '1');
INSERT INTO `%table_prefix%imports` VALUES ('2', '%rootPath%importing/parse-users', 'a:1:{s:4:"root";s:5:"users";}', 'working', '0', '0', '0', NOW(), NOW(), '0', '1', '1');
INSERT INTO `%table_prefix%imports` VALUES ('3', '%rootPath%importing/parse-albums', 'a:1:{s:4:"root";s:6:"albums";}', 'working', '0', '0', '0', NOW(), NOW(), '0', '1', '1');
INSERT INTO `%table_prefix%imports` VALUES ('3', '%rootPath%importing/parse-albums', 'a:1:{s:4:"root";s:6:"albums";}', 'working', '0', '0', '0', NOW(), NOW(), '0', '1', '1');

View File

@@ -1,13 +1,13 @@
DROP TABLE IF EXISTS `%table_prefix%ip_bans`;
CREATE TABLE `%table_prefix%ip_bans` (
`ip_ban_id` bigint(20) NOT NULL AUTO_INCREMENT,
`ip_ban_date` datetime NOT NULL,
`ip_ban_date_gmt` datetime NOT NULL,
`ip_ban_expires` datetime DEFAULT NULL,
`ip_ban_expires_gmt` datetime DEFAULT NULL,
`ip_ban_ip` varchar(255) NOT NULL,
`ip_ban_message` text,
`ip_ban_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`ip_ban_date` DATETIME NOT NULL,
`ip_ban_date_gmt` DATETIME NOT NULL,
`ip_ban_expires` DATETIME DEFAULT NULL,
`ip_ban_expires_gmt` DATETIME DEFAULT NULL,
`ip_ban_ip` VARCHAR(255) NOT NULL,
`ip_ban_message` TEXT,
PRIMARY KEY (`ip_ban_id`),
KEY `ip_ban_date_gmt` (`ip_ban_date_gmt`),
UNIQUE KEY `ip_ban_ip` (`ip_ban_ip`) USING BTREE
) ENGINE=%table_engine% DEFAULT CHARSET=utf8mb4;
UNIQUE KEY `ip_ban_ip` (`ip_ban_ip`) USING BTREE,
KEY `ip_ban_ip_expires_gmt_id` (`ip_ban_ip`, `ip_ban_expires_gmt`, `ip_ban_id` DESC)
) ENGINE=%table_engine% DEFAULT CHARSET=utf8mb4;

View File

@@ -1,13 +1,13 @@
DROP TABLE IF EXISTS `%table_prefix%likes`;
CREATE TABLE `%table_prefix%likes` (
`like_id` bigint(32) NOT NULL AUTO_INCREMENT,
`like_date` datetime NOT NULL,
`like_date_gmt` datetime NOT NULL,
`like_user_id` bigint(32) DEFAULT NULL,
`like_content_type` enum('image','album') DEFAULT NULL,
`like_content_id` bigint(32) NOT NULL,
`like_content_user_id` bigint(32) DEFAULT NULL,
`like_ip` varchar(255) NOT NULL,
`like_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`like_date` DATETIME NOT NULL,
`like_date_gmt` DATETIME NOT NULL,
`like_user_id` INT UNSIGNED DEFAULT NULL,
`like_content_type` ENUM('image','album') DEFAULT NULL,
`like_content_id` INT UNSIGNED NOT NULL,
`like_content_user_id` INT UNSIGNED DEFAULT NULL,
`like_ip` VARCHAR(255) NOT NULL,
PRIMARY KEY (`like_id`),
KEY `like_date_gmt` (`like_date_gmt`),
KEY `like_user_id` (`like_user_id`),

View File

@@ -1,11 +1,11 @@
DROP TABLE IF EXISTS `%table_prefix%locks`;
CREATE TABLE `%table_prefix%locks` (
`lock_id` bigint(20) NOT NULL AUTO_INCREMENT,
`lock_name` varchar(255) NOT NULL,
`lock_date_gmt` datetime NOT NULL,
`lock_expires_gmt` datetime DEFAULT NULL,
`lock_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`lock_name` VARCHAR(255) NOT NULL,
`lock_date_gmt` DATETIME NOT NULL,
`lock_expires_gmt` DATETIME DEFAULT NULL,
PRIMARY KEY (`lock_id`),
KEY `lock_date_gmt` (`lock_date_gmt`),
KEY `lock_expires_gmt` (`lock_expires_gmt`),
UNIQUE KEY `lock_name` (`lock_name`) USING BTREE
) ENGINE=%table_engine% DEFAULT CHARSET=utf8mb4;
) ENGINE=%table_engine% DEFAULT CHARSET=utf8mb4;

View File

@@ -1,12 +1,12 @@
DROP TABLE IF EXISTS `%table_prefix%login_connections`;
CREATE TABLE `%table_prefix%login_connections` (
`login_connection_id` bigint(32) NOT NULL AUTO_INCREMENT,
`login_connection_user_id` bigint(32) NOT NULL,
`login_connection_provider_id` bigint(32) NOT NULL,
`login_connection_date_gmt` datetime NOT NULL,
`login_connection_resource_id` varchar(255) NOT NULL,
`login_connection_resource_name` text,
`login_connection_token` text NOT NULL COMMENT 'Ciphertext',
`login_connection_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`login_connection_user_id` INT UNSIGNED NOT NULL,
`login_connection_provider_id` INT UNSIGNED NOT NULL,
`login_connection_date_gmt` DATETIME NOT NULL,
`login_connection_resource_id` VARCHAR(255) NOT NULL,
`login_connection_resource_name` TEXT,
`login_connection_token` TEXT NOT NULL COMMENT 'Ciphertext',
PRIMARY KEY (`login_connection_id`),
UNIQUE KEY `login_connection_unique` (`login_connection_user_id`,`login_connection_provider_id`),
KEY `login_connection_user_id` (`login_connection_user_id`),

View File

@@ -1,16 +1,17 @@
DROP TABLE IF EXISTS `%table_prefix%login_cookies`;
CREATE TABLE `%table_prefix%login_cookies` (
`login_cookie_id` bigint(32) NOT NULL AUTO_INCREMENT,
`login_cookie_user_id` bigint(32) NOT NULL,
`login_cookie_connection_id` bigint(32) DEFAULT 0,
`login_cookie_date_gmt` datetime NOT NULL,
`login_cookie_ip` varchar(255) DEFAULT NULL,
`login_cookie_user_agent` text NOT NULL,
`login_cookie_hash` text NOT NULL,
`login_cookie_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`login_cookie_user_id` INT UNSIGNED NOT NULL,
`login_cookie_connection_id` INT UNSIGNED DEFAULT 0,
`login_cookie_date_gmt` DATETIME NOT NULL,
`login_cookie_ip` VARCHAR(255) DEFAULT NULL,
`login_cookie_user_agent` TEXT NOT NULL,
`login_cookie_hash` TEXT NOT NULL,
PRIMARY KEY (`login_cookie_id`),
UNIQUE KEY `login_cookie_unique` (`login_cookie_user_id`,`login_cookie_connection_id`,`login_cookie_date_gmt`),
KEY `login_cookie_user_id_date_gmt` (`login_cookie_user_id`, `login_cookie_date_gmt`),
KEY `login_cookie_user_id` (`login_cookie_user_id`),
KEY `login_cookie_ip` (`login_cookie_ip`),
KEY `login_cookie_connection_id` (`login_cookie_connection_id`)
KEY `login_cookie_connection_id` (`login_cookie_connection_id`),
KEY `login_cookie_user_id_date_gmt_connection_id` (`login_cookie_user_id`, `login_cookie_date_gmt`, `login_cookie_connection_id`)
) ENGINE=%table_engine% DEFAULT CHARSET=utf8mb4;

View File

@@ -1,9 +1,9 @@
DROP TABLE IF EXISTS `%table_prefix%login_passwords`;
CREATE TABLE `%table_prefix%login_passwords` (
`login_password_id` bigint(32) NOT NULL AUTO_INCREMENT,
`login_password_user_id` bigint(32) NOT NULL,
`login_password_date_gmt` datetime NOT NULL,
`login_password_hash` text NOT NULL,
`login_password_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`login_password_user_id` INT UNSIGNED NOT NULL,
`login_password_date_gmt` DATETIME NOT NULL,
`login_password_hash` TEXT NOT NULL,
PRIMARY KEY (`login_password_id`),
UNIQUE KEY `login_password_user_id` (`login_password_user_id`)
) ENGINE=%table_engine% DEFAULT CHARSET=utf8mb4;

View File

@@ -1,14 +1,15 @@
DROP TABLE IF EXISTS `%table_prefix%login_providers`;
CREATE TABLE `%table_prefix%login_providers` (
`login_provider_id` bigint(32) NOT NULL AUTO_INCREMENT,
`login_provider_name` varchar(255) DEFAULT NULL,
`login_provider_label` varchar(255) DEFAULT NULL,
`login_provider_key_id` text DEFAULT NULL,
`login_provider_key_secret` text DEFAULT NULL,
`login_provider_is_enabled` tinyint(1) NOT NULL DEFAULT '1',
`login_provider_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`login_provider_name` VARCHAR(255) DEFAULT NULL,
`login_provider_label` VARCHAR(255) DEFAULT NULL,
`login_provider_key_id` TEXT DEFAULT NULL,
`login_provider_key_secret` TEXT DEFAULT NULL,
`login_provider_is_enabled` TINYINT UNSIGNED NOT NULL DEFAULT '1',
PRIMARY KEY (`login_provider_id`),
UNIQUE KEY `login_provider_name` (`login_provider_name`),
KEY `login_provider_is_enabled` (`login_provider_is_enabled`)
KEY `login_provider_is_enabled` (`login_provider_is_enabled`),
KEY `login_provider_id_is_enabled_name` (`login_provider_id`, `login_provider_is_enabled`, `login_provider_name` DESC)
) ENGINE=%table_engine% DEFAULT CHARSET=utf8mb4;
INSERT INTO `%table_prefix%login_providers` VALUES ('1', 'facebook', 'Facebook', null, null, '0');
INSERT INTO `%table_prefix%login_providers` VALUES ('2', 'twitter', 'X', null, null, '0');

View File

@@ -1,18 +1,18 @@
DROP TABLE IF EXISTS `%table_prefix%logins`;
CREATE TABLE `%table_prefix%logins` (
`login_id` bigint(32) NOT NULL AUTO_INCREMENT,
`login_user_id` bigint(32) NOT NULL,
`login_type` enum('password','session','cookie','facebook','twitter','google','vk','cookie_facebook','cookie_twitter','cookie_google','cookie_vk') NOT NULL,
`login_ip` varchar(255) DEFAULT NULL,
`login_hostname` text,
`login_date` datetime NOT NULL,
`login_date_gmt` datetime NOT NULL,
`login_resource_id` varchar(255) DEFAULT NULL,
`login_resource_name` text,
`login_resource_avatar` text,
`login_resource_url` text,
`login_secret` text DEFAULT NULL COMMENT 'The secret part',
`login_token_hash` text COMMENT 'Hashed complement to secret if needed',
`login_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`login_user_id` INT UNSIGNED NOT NULL,
`login_type` ENUM('password','session','cookie','facebook','twitter','google','vk','cookie_facebook','cookie_twitter','cookie_google','cookie_vk') NOT NULL,
`login_ip` VARCHAR(255) DEFAULT NULL,
`login_hostname` TEXT,
`login_date` DATETIME NOT NULL,
`login_date_gmt` DATETIME NOT NULL,
`login_resource_id` VARCHAR(255) DEFAULT NULL,
`login_resource_name` TEXT,
`login_resource_avatar` TEXT,
`login_resource_url` TEXT,
`login_secret` TEXT DEFAULT NULL COMMENT 'The secret part',
`login_token_hash` TEXT COMMENT 'Hashed complement to secret if needed',
PRIMARY KEY (`login_id`),
KEY `login_user_id` (`login_user_id`)
) ENGINE=%table_engine% DEFAULT CHARSET=utf8mb4;

View File

@@ -1,13 +1,13 @@
DROP TABLE IF EXISTS `%table_prefix%notifications`;
CREATE TABLE `%table_prefix%notifications` (
`notification_id` bigint(32) NOT NULL AUTO_INCREMENT,
`notification_date_gmt` datetime NOT NULL,
`notification_user_id` bigint(32) NOT NULL,
`notification_trigger_user_id` bigint(32) DEFAULT NULL,
`notification_type` enum('follow','like') NOT NULL,
`notification_content_type` enum('user','image','album') NOT NULL,
`notification_type_id` bigint(32) NOT NULL COMMENT 'type_id based on action (type) table',
`notification_is_read` tinyint(1) NOT NULL DEFAULT '0',
`notification_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`notification_date_gmt` DATETIME NOT NULL,
`notification_user_id` INT UNSIGNED NOT NULL,
`notification_trigger_user_id` INT UNSIGNED DEFAULT NULL,
`notification_type` ENUM('follow','like') NOT NULL,
`notification_content_type` ENUM('user','image','album') NOT NULL,
`notification_type_id` INT UNSIGNED NOT NULL COMMENT 'type_id based on action (type) table',
`notification_is_read` TINYINT UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (`notification_id`),
KEY `notification_date_gmt` (`notification_date_gmt`),
KEY `notification_user_id` (`notification_user_id`),
@@ -16,4 +16,4 @@ CREATE TABLE `%table_prefix%notifications` (
KEY `notification_content_type` (`notification_content_type`),
KEY `notification_type_id` (`notification_type_id`),
KEY `notification_is_read` (`notification_is_read`)
) ENGINE=%table_engine% DEFAULT CHARSET=utf8;
) ENGINE=%table_engine% DEFAULT CHARSET=utf8;

View File

@@ -1,21 +1,21 @@
DROP TABLE IF EXISTS `%table_prefix%pages`;
CREATE TABLE `%table_prefix%pages` (
`page_id` bigint(32) NOT NULL AUTO_INCREMENT,
`page_url_key` varchar(32) DEFAULT NULL,
`page_type` enum('internal','link') NOT NULL DEFAULT 'internal',
`page_file_path` varchar(255) DEFAULT NULL,
`page_link_url` text,
`page_icon` varchar(255) DEFAULT NULL,
`page_title` varchar(255) NOT NULL,
`page_description` text,
`page_keywords` text,
`page_is_active` tinyint(1) NOT NULL DEFAULT '1',
`page_is_link_visible` tinyint(1) NOT NULL DEFAULT '1',
`page_attr_target` enum('_self','_blank') DEFAULT '_self',
`page_attr_rel` varchar(255) DEFAULT NULL,
`page_sort_display` int(11) DEFAULT NULL,
`page_internal` varchar(255) DEFAULT NULL,
`page_code` text,
`page_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`page_url_key` VARCHAR(32) DEFAULT NULL,
`page_type` ENUM('internal','link') NOT NULL DEFAULT 'internal',
`page_file_path` VARCHAR(255) DEFAULT NULL,
`page_link_url` TEXT,
`page_icon` VARCHAR(255) DEFAULT NULL,
`page_title` VARCHAR(255) NOT NULL,
`page_description` TEXT,
`page_keywords` TEXT,
`page_is_active` TINYINT UNSIGNED NOT NULL DEFAULT '1',
`page_is_link_visible` TINYINT UNSIGNED NOT NULL DEFAULT '1',
`page_attr_target` ENUM('_self','_blank') DEFAULT '_self',
`page_attr_rel` VARCHAR(255) DEFAULT NULL,
`page_sort_display` INT UNSIGNED DEFAULT NULL,
`page_internal` VARCHAR(255) DEFAULT NULL,
`page_code` TEXT,
PRIMARY KEY (`page_id`),
UNIQUE KEY `page_internal` (`page_internal`),
KEY `page_url_key` (`page_url_key`),

View File

@@ -1,11 +1,11 @@
DROP TABLE IF EXISTS `%table_prefix%queues`;
CREATE TABLE `%table_prefix%queues` (
`queue_id` bigint(32) NOT NULL AUTO_INCREMENT,
`queue_type` enum('storage-delete') NOT NULL,
`queue_date_gmt` datetime NOT NULL,
`queue_args` text NOT NULL,
`queue_join` bigint(32) NOT NULL,
`queue_attempts` varchar(255) DEFAULT '0',
`queue_status` enum('pending','failed') NOT NULL DEFAULT 'pending',
`queue_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`queue_type` ENUM('storage-delete') NOT NULL,
`queue_date_gmt` DATETIME NOT NULL,
`queue_args` TEXT NOT NULL,
`queue_join` INT UNSIGNED NOT NULL,
`queue_attempts` VARCHAR(255) DEFAULT '0',
`queue_status` ENUM('pending','failed') NOT NULL DEFAULT 'pending',
PRIMARY KEY (`queue_id`)
) ENGINE=%table_engine% DEFAULT CHARSET=utf8;

View File

@@ -1,18 +1,20 @@
DROP TABLE IF EXISTS `%table_prefix%requests`;
CREATE TABLE `%table_prefix%requests` (
`request_id` bigint(32) NOT NULL AUTO_INCREMENT,
`request_type` enum('upload','signup','account-edit','account-password-forgot','account-password-reset','account-resend-activation','account-email-needed','account-change-email','account-activate','login', 'content-password', 'account-two-factor') NOT NULL,
`request_user_id` bigint(32) DEFAULT NULL,
`request_content_id` bigint(32) DEFAULT NULL,
`request_ip` varchar(255) NOT NULL,
`request_date` datetime NOT NULL,
`request_date_gmt` datetime NOT NULL,
`request_result` enum('success','fail') NOT NULL,
`request_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`request_type` ENUM('upload','signup','account-edit','account-password-forgot','account-password-reset','account-resend-activation','account-email-needed','account-change-email','account-activate','login', 'content-password', 'account-two-factor') NOT NULL,
`request_user_id` INT UNSIGNED DEFAULT NULL,
`request_content_id` INT UNSIGNED DEFAULT NULL,
`request_ip` VARCHAR(255) NOT NULL,
`request_date` DATETIME NOT NULL,
`request_date_gmt` DATETIME NOT NULL,
`request_result` ENUM('success','fail') NOT NULL,
PRIMARY KEY (`request_id`),
KEY `request_type` (`request_type`),
KEY `request_user_id` (`request_user_id`),
KEY `request_content_id` (`request_content_id`),
KEY `request_ip` (`request_ip`),
KEY `request_date_gmt` (`request_date_gmt`),
KEY `request_result` (`request_result`)
KEY `request_result` (`request_result`),
KEY `request_result_ip_type_date_gmt` (`request_result`, `request_type`, `request_ip`,`request_date_gmt`),
KEY `request_user_id_result_type_ip` (`request_user_id`, `request_result`, `request_type`, `request_ip`)
) ENGINE=%table_engine% DEFAULT CHARSET=utf8;

View File

@@ -1,10 +1,10 @@
DROP TABLE IF EXISTS `%table_prefix%settings`;
CREATE TABLE `%table_prefix%settings` (
`setting_id` int(11) NOT NULL AUTO_INCREMENT,
`setting_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`setting_value` text,
`setting_default` text,
`setting_typeset` enum('string','bool') DEFAULT 'string',
`setting_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`setting_name` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`setting_value` TEXT,
`setting_default` TEXT,
`setting_typeset` ENUM('string','bool') DEFAULT 'string',
PRIMARY KEY (`setting_id`),
UNIQUE KEY `setting_name` (`setting_name`) USING BTREE
) ENGINE=%table_engine% DEFAULT CHARSET=utf8mb4;

View File

@@ -1,21 +1,22 @@
DROP TABLE IF EXISTS `%table_prefix%stats`;
CREATE TABLE `%table_prefix%stats` (
`stat_id` bigint(32) NOT NULL AUTO_INCREMENT,
`stat_type` enum('total','date') NOT NULL,
`stat_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`stat_type` ENUM('total','date') NOT NULL,
`stat_date_gmt` date DEFAULT NULL,
`stat_users` bigint(32) UNSIGNED NOT NULL DEFAULT '0',
`stat_images` bigint(32) UNSIGNED NOT NULL DEFAULT '0',
`stat_albums` bigint(32) UNSIGNED NOT NULL DEFAULT '0',
`stat_tags` bigint(32) UNSIGNED NOT NULL DEFAULT '0',
`stat_cron_runs` bigint(32) UNSIGNED NOT NULL DEFAULT '0',
`stat_cron_time` bigint(32) UNSIGNED NOT NULL DEFAULT '0',
`stat_image_views` bigint(32) UNSIGNED NOT NULL DEFAULT '0',
`stat_album_views` bigint(32) UNSIGNED NOT NULL DEFAULT '0',
`stat_image_likes` bigint(32) UNSIGNED NOT NULL DEFAULT '0',
`stat_album_likes` bigint(32) UNSIGNED NOT NULL DEFAULT '0',
`stat_disk_used` bigint(32) UNSIGNED NOT NULL DEFAULT '0',
`stat_users` INT UNSIGNED NOT NULL DEFAULT '0',
`stat_images` INT UNSIGNED NOT NULL DEFAULT '0',
`stat_albums` INT UNSIGNED NOT NULL DEFAULT '0',
`stat_tags` INT UNSIGNED NOT NULL DEFAULT '0',
`stat_cron_runs` INT UNSIGNED NOT NULL DEFAULT '0',
`stat_cron_time` INT UNSIGNED NOT NULL DEFAULT '0',
`stat_image_views` INT UNSIGNED NOT NULL DEFAULT '0',
`stat_album_views` INT UNSIGNED NOT NULL DEFAULT '0',
`stat_image_likes` INT UNSIGNED NOT NULL DEFAULT '0',
`stat_album_likes` INT UNSIGNED NOT NULL DEFAULT '0',
`stat_disk_used` BIGINT UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (`stat_id`),
UNIQUE KEY `stat_date_gmt` (`stat_date_gmt`) USING BTREE,
KEY `stat_type` (`stat_type`)
KEY `stat_type` (`stat_type`),
KEY `stat_type_date_gmt` (`stat_type`, `stat_date_gmt` DESC)
) ENGINE=%table_engine% DEFAULT CHARSET=utf8;
INSERT INTO `%table_prefix%stats` (stat_id, stat_type) VALUES (1, 'total');

View File

@@ -1,8 +1,8 @@
DROP TABLE IF EXISTS `%table_prefix%storage_apis`;
CREATE TABLE `%table_prefix%storage_apis` (
`storage_api_id` bigint(32) NOT NULL AUTO_INCREMENT,
`storage_api_name` varchar(255) NOT NULL,
`storage_api_type` varchar(255) NOT NULL,
`storage_api_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`storage_api_name` VARCHAR(255) NOT NULL,
`storage_api_type` VARCHAR(255) NOT NULL,
PRIMARY KEY (`storage_api_id`)
) ENGINE=%table_engine% DEFAULT CHARSET=utf8;
INSERT INTO `%table_prefix%storage_apis` VALUES ('1', 'Amazon S3', 's3');
@@ -15,4 +15,4 @@ INSERT INTO `%table_prefix%storage_apis` VALUES ('7', 'OpenStack', 'openstack');
INSERT INTO `%table_prefix%storage_apis` VALUES ('8', 'Local', 'local');
INSERT INTO `%table_prefix%storage_apis` VALUES ('9', 'S3 compatible', 's3compatible');
INSERT INTO `%table_prefix%storage_apis` VALUES ('10', 'Alibaba Cloud OSS', 'oss');
INSERT INTO `%table_prefix%storage_apis` VALUES ('11', 'Backblaze B2', 'b2');
INSERT INTO `%table_prefix%storage_apis` VALUES ('11', 'Backblaze B2', 'b2');

View File

@@ -1,23 +1,23 @@
DROP TABLE IF EXISTS `%table_prefix%storages`;
CREATE TABLE `%table_prefix%storages` (
`storage_id` bigint(32) NOT NULL AUTO_INCREMENT,
`storage_api_id` bigint(32) NOT NULL,
`storage_name` varchar(255) NOT NULL,
`storage_service` varchar(255) DEFAULT NULL,
`storage_url` varchar(255) NOT NULL,
`storage_bucket` varchar(255) DEFAULT NULL,
`storage_region` varchar(255) DEFAULT NULL,
`storage_server` varchar(255) DEFAULT NULL,
`storage_account_id` varchar(255) DEFAULT NULL,
`storage_account_name` varchar(255) DEFAULT NULL,
`storage_key` text,
`storage_secret` text,
`storage_is_https` tinyint(1) NOT NULL DEFAULT '0',
`storage_is_active` tinyint(1) NOT NULL DEFAULT '0',
`storage_capacity` bigint(32) DEFAULT NULL,
`storage_space_used` bigint(32) DEFAULT '0',
`storage_type_chain` tinyint(3) NOT NULL DEFAULT '1',
`storage_use_path_style_endpoint` tinyint(1) NOT NULL DEFAULT '0',
`storage_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`storage_api_id` INT UNSIGNED NOT NULL,
`storage_name` VARCHAR(255) NOT NULL,
`storage_service` VARCHAR(255) DEFAULT NULL,
`storage_url` VARCHAR(255) NOT NULL,
`storage_bucket` VARCHAR(255) DEFAULT NULL,
`storage_region` VARCHAR(255) DEFAULT NULL,
`storage_server` VARCHAR(255) DEFAULT NULL,
`storage_account_id` VARCHAR(255) DEFAULT NULL,
`storage_account_name` VARCHAR(255) DEFAULT NULL,
`storage_key` TEXT,
`storage_secret` TEXT,
`storage_is_https` TINYINT UNSIGNED NOT NULL DEFAULT '0',
`storage_is_active` TINYINT UNSIGNED NOT NULL DEFAULT '0',
`storage_capacity` BIGINT UNSIGNED DEFAULT NULL,
`storage_space_used` BIGINT UNSIGNED DEFAULT '0',
`storage_type_chain` TINYINT UNSIGNED NOT NULL DEFAULT '1',
`storage_use_path_style_endpoint` TINYINT UNSIGNED NOT NULL DEFAULT '0',
`storage_deleted_at` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`storage_id`),
KEY `storage_api_id` (`storage_api_id`),

Some files were not shown because too many files have changed in this diff Show More