Compare commits
90 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f5a90aea4d | |||
| dff376217f | |||
| 55a8154b52 | |||
| 8ca82fd0c8 | |||
| 837b3de163 | |||
| 71014349aa | |||
| aefe03ed67 | |||
| 1afe77415d | |||
| f492a4d02f | |||
| 0c0a6a401e | |||
| bdc4158dec | |||
| 0ecb4610eb | |||
| d75d76ef6e | |||
| dc6df8b02a | |||
| a91106ddf7 | |||
| 53b611bb31 | |||
| 7e1f8fc55a | |||
| f71c51f4ba | |||
| ef24a16132 | |||
| 3b0051585c | |||
| a52db45972 | |||
| 487b2e2956 | |||
| 74a678edda | |||
| dc577f5c8b | |||
| 22893fd957 | |||
| 176a883633 | |||
| 3cb98ce542 | |||
| 300c417f3c | |||
| dcf99a3351 | |||
| 1bc89691d9 | |||
| c76bf45904 | |||
| 3cdb6f88b8 | |||
| 378c34b8c0 | |||
| 73844b6db0 | |||
| f47528a2a1 | |||
| 6977d5ad57 | |||
| 0009d3339e | |||
| 93acbb4325 | |||
| e9fdc9be51 | |||
| a1ca5b084a | |||
| 60dfa1588a | |||
| 60ce1cf400 | |||
| a9158c722a | |||
| 848c528de3 | |||
| d163d24780 | |||
| 05e7d4754f | |||
| 1abfa96c2c | |||
| b6dcaa195d | |||
| 08fcca7ce0 | |||
| bb8fdac460 | |||
| d41be1f36e | |||
| 86ca0ecd77 | |||
| ed5e794692 | |||
| 1bb842cdd3 | |||
| 755554293e | |||
| 3195a40f53 | |||
| e02e404942 | |||
| b562abd271 | |||
| 43018e5aae | |||
| 3225bd9a74 | |||
| e35d7fa480 | |||
| 593479f41f | |||
| 76a1e62129 | |||
| d9c907d643 | |||
| 71c4cbef46 | |||
| 4a7c43f9e7 | |||
| cac8b03a0d | |||
| 632374af7e | |||
| dc0a09f530 | |||
| 8e83110093 | |||
| edecfafea8 | |||
| fa403d58b0 | |||
| 6ae5e083a5 | |||
| 8d954872d5 | |||
| 35701ad7e6 | |||
| 4409e427e2 | |||
| d5d24657c3 | |||
| 3f6a469e96 | |||
| 0fae5bbcd7 | |||
| 712d2b2161 | |||
| 0c7c430c73 | |||
| 30977ca676 | |||
| 2f8cc01e0a | |||
| 94d4e25a2d | |||
| f927c35bab | |||
| 9b94faaade | |||
| d677eff19f | |||
| f9bb53a90d | |||
| c0e0a3974f | |||
| 2dd47100bc |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -27,3 +27,7 @@ Homestead.yaml
|
||||
Thumbs.db
|
||||
avancee.ods
|
||||
.~lock.avancee.ods#
|
||||
rhpz.local+1.pem
|
||||
rhpz.local+1-key.pem
|
||||
extra.less
|
||||
config/xenforo.php
|
||||
|
||||
@@ -60,6 +60,7 @@ use Illuminate\Contracts\Auth\Authenticatable;
|
||||
* Custom properties.
|
||||
*
|
||||
* @property-read int $rhpz_entry_count
|
||||
* @property-read int $nsfw_content
|
||||
*/
|
||||
class XenForoUser extends XenForoData implements Authenticatable, Authorizable, FilamentUser, HasName {
|
||||
|
||||
|
||||
38
app/Console/Commands/CalculateAllHashes.php
Normal file
38
app/Console/Commands/CalculateAllHashes.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Helpers\HashesHelpers;
|
||||
use App\Models\EntryHash;
|
||||
use Illuminate\Console\Attributes\Description;
|
||||
use Illuminate\Console\Attributes\Signature;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
#[Signature('hashes:calculate')]
|
||||
#[Description('Recalculate all hashes for EntryHashes')]
|
||||
class CalculateAllHashes extends Command
|
||||
{
|
||||
public function handle()
|
||||
{
|
||||
EntryHash::where('verified', '=', 'TBD')->cursor()->each(function ($entryHash) {
|
||||
if( ( $hash = HashesHelpers::findHashes( $entryHash->hash_sha1 ) ) !== null ){
|
||||
$entryHash->filename = $hash->filename;
|
||||
$entryHash->hash_crc32 = $hash->crc32;
|
||||
$entryHash->hash_sha1 = $hash->sha1;
|
||||
$entryHash->verified = HashesHelpers::getReferenceName( $hash->dat_reference_id );
|
||||
$entryHash->save();
|
||||
} else {
|
||||
if( !$entryHash->hash_crc32 || !$entryHash->hash_sha1 )
|
||||
$entryHash->delete();
|
||||
else {
|
||||
if (!$entryHash->filename)
|
||||
$entryHash->filename = "Unknown";
|
||||
$entryHash->verified = 'No';
|
||||
$entryHash->save();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$this->info('Hashes calculated');
|
||||
}
|
||||
}
|
||||
71
app/Console/Commands/GenerateSitemap.php
Normal file
71
app/Console/Commands/GenerateSitemap.php
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Entry;
|
||||
use App\Models\News;
|
||||
use Illuminate\Console\Attributes\Signature;
|
||||
use Illuminate\Console\Command;
|
||||
use Spatie\Sitemap\Sitemap;
|
||||
use Spatie\Sitemap\Tags\Url;
|
||||
|
||||
#[Signature('sitemap:generate')]
|
||||
class GenerateSitemap extends Command
|
||||
{
|
||||
public function handle()
|
||||
{
|
||||
$sitemap = Sitemap::create()
|
||||
->add(Url::create('/')->setPriority(1.0)->setChangeFrequency(Url::CHANGE_FREQUENCY_DAILY))
|
||||
->add(Url::create('/database')->setPriority(0.8)->setChangeFrequency(Url::CHANGE_FREQUENCY_DAILY))
|
||||
->add(Url::create('/news')->setPriority(0.7)->setChangeFrequency(Url::CHANGE_FREQUENCY_DAILY))
|
||||
->add(Url::create(route('tools.patcher'))->setPriority(0.2)->setChangeFrequency(Url::CHANGE_FREQUENCY_MONTHLY) )
|
||||
->add(Url::create(route('tools.hash'))->setPriority(0.2)->setChangeFrequency(Url::CHANGE_FREQUENCY_MONTHLY) )
|
||||
;
|
||||
|
||||
Entry::cursor()->each(function (Entry $entry) use ($sitemap) {
|
||||
|
||||
if (empty($entry->type) || empty($entry->slug)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$url = route('entries.show', [
|
||||
'section' => $entry->type,
|
||||
'entry' => $entry->slug
|
||||
]);
|
||||
|
||||
$sitemap->add(
|
||||
Url::create($url)
|
||||
->setLastModificationDate($entry->updated_at)
|
||||
->setChangeFrequency(Url::CHANGE_FREQUENCY_WEEKLY)
|
||||
->setPriority(0.8)
|
||||
);
|
||||
} catch (\Exception $e) {
|
||||
logger()->error("Sitemap error for entry : {$entry->id}: " . $e->getMessage());
|
||||
}
|
||||
});
|
||||
|
||||
News::cursor()->each(function (News $entry) use ($sitemap) {
|
||||
|
||||
if (empty($entry->type) || empty($entry->slug)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$url = route('news.show', ['news' => $entry]);
|
||||
|
||||
$sitemap->add(
|
||||
Url::create($url)
|
||||
->setLastModificationDate($entry->updated_at)
|
||||
->setChangeFrequency(Url::CHANGE_FREQUENCY_WEEKLY)
|
||||
->setPriority(0.8)
|
||||
);
|
||||
} catch (\Exception $e) {
|
||||
logger()->error("Sitemap error for news : {$entry->id}: " . $e->getMessage());
|
||||
}
|
||||
});
|
||||
|
||||
$sitemap->writeToFile(public_path('sitemap.xml'));
|
||||
$this->info('Generated sitemap');
|
||||
}
|
||||
}
|
||||
41
app/Console/Commands/MigrateDownloadsCount.php
Normal file
41
app/Console/Commands/MigrateDownloadsCount.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Attributes\Description;
|
||||
use Illuminate\Console\Attributes\Signature;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
#[Signature('migrate:downloads-count')]
|
||||
#[Description('Command description')]
|
||||
class MigrateDownloadsCount extends Command
|
||||
{
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$rows = DB::table('migrations_logs')
|
||||
->where('source_system', 'wp')
|
||||
->where('source_table', 'wp_posts')
|
||||
->where('target_table', 'entries' )
|
||||
->get(['source_id', 'target_id'])
|
||||
;
|
||||
|
||||
$updated = 0;
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$downloadCount = DB::connection('old_wp')
|
||||
->table('postmeta')
|
||||
->where('post_id', $row->source_id)
|
||||
->where('meta_key', 'download_counter' )
|
||||
->value('meta_value');
|
||||
|
||||
if( $downloadCount ) {
|
||||
DB::table('entries')->where('id', $row->target_id)->update(['old_download_count' => intval($downloadCount)]);
|
||||
$updated++;
|
||||
}
|
||||
}
|
||||
|
||||
$this->info('All done (' . $updated . '/' . count($rows) .')');
|
||||
}
|
||||
}
|
||||
110
app/Console/Commands/MigrateFilesExecute.php
Normal file
110
app/Console/Commands/MigrateFilesExecute.php
Normal file
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Helpers\EntryHelpers;
|
||||
use Illuminate\Console\Attributes\Description;
|
||||
use Illuminate\Console\Attributes\Signature;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Spatie\SimpleExcel\SimpleExcelReader;
|
||||
|
||||
#[Signature('migrate:files:execute {--csv-file=} {--favorite-server=oedipus} ')]
|
||||
#[Description("Migrate all files tables into an EntryFile.")]
|
||||
class MigrateFilesExecute extends Command
|
||||
{
|
||||
|
||||
private function getState( array $file ): string
|
||||
{
|
||||
if( str_contains( $file['old_path'], 'private' ) )
|
||||
return 'private';
|
||||
if( str_contains( $file['old_path'], 'archive' ) )
|
||||
return 'archived';
|
||||
return 'public';
|
||||
}
|
||||
|
||||
private function getNewPath( array $file ): string
|
||||
{
|
||||
$newPath = $file['new_path'];
|
||||
$newPath = str_replace('rhpz-fs-storage//', '', $newPath);
|
||||
$newPath = str_replace( './rhpz-fs-storage/', '', $newPath);
|
||||
|
||||
return dirname($newPath);
|
||||
}
|
||||
|
||||
private function createEntryFile( array $file )
|
||||
{
|
||||
$exists = DB::table('migration_files')
|
||||
->where('filename', $file['filename'] )
|
||||
->where('old_path', $file['old_path'] )
|
||||
->where('wp_post_id', (int) $file['wp_post_id'] )
|
||||
->where('uuid', $file['uuid'] )
|
||||
->where('new_path', $this->getNewPath( $file ) )
|
||||
->exists();
|
||||
|
||||
if( $exists )
|
||||
return;
|
||||
|
||||
$entryId = DB::table('migrations_logs')
|
||||
->where('source_system', 'wp')
|
||||
->where('source_table', 'wp_posts')
|
||||
->where('target_table', 'entries' )
|
||||
->where('source_id', (int) $file['wp_post_id'] )
|
||||
->value('target_id');
|
||||
|
||||
if( !$entryId ){
|
||||
$this->info("Not copied entry for {$file['wp_post_id']}");
|
||||
return;
|
||||
}
|
||||
|
||||
$fileId = DB::table('entry_files')->insertGetId([
|
||||
'entry_id' => $entryId,
|
||||
'filename' => $file['filename'],
|
||||
'filepath' => $this->getNewPath( $file ),
|
||||
'favorite_server' => $this->option('favorite-server') ?? "oedipus",
|
||||
'favorite_at' => now(),
|
||||
'filesize' => (int) $file['filesize'],
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
'file_uuid' => $file['uuid'],
|
||||
'state' => $this->getState( $file ),
|
||||
'online_patcher' => (int) EntryHelpers::enableOnlinePatcherBasedOnExtension( $file['filename'] ),
|
||||
'secondary_online_patcher' => 0,
|
||||
'download_count' => 0
|
||||
]);
|
||||
|
||||
if( !$fileId ){
|
||||
$this->info( "Not created file for {$file['wp_post_id']}" );
|
||||
return;
|
||||
}
|
||||
|
||||
DB::table('migration_files')->insert([
|
||||
'filename' => $file['filename'],
|
||||
'old_path' => $file['old_path'],
|
||||
'wp_post_id' => (int) $file['wp_post_id'],
|
||||
'uuid' => $file['uuid'],
|
||||
'new_path' => $this->getNewPath( $file ),
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
$this->info( "Created file for {$file['wp_post_id']}" );
|
||||
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$csvFile = $this->option('csv-file');
|
||||
if( !$csvFile || !is_file($csvFile) ){
|
||||
$this->error('Missing CSV file Path');
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
$rows = SimpleExcelReader::create($csvFile)->useDelimiter(';')->getRows();
|
||||
$rows->each(function(array $row){
|
||||
$this->createEntryFile($row);
|
||||
});
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
}
|
||||
@@ -87,10 +87,10 @@ class MigrateUsersExecute extends Command
|
||||
->leftJoin('usermeta as m2', fn( $j ) => $j->on('users.ID', '=', 'm2.user_id')->where('m2.meta_key', '=', 'wp_capabilities') )
|
||||
->leftJoin('usermeta as m3', fn( $j ) => $j->on('users.ID', '=', 'm3.user_id')->where('m3.meta_key', '=', 'simple_local_avatar') )
|
||||
->where('users.ID', '=', $plan->wp_user_id )
|
||||
->select('m1.meta_value as description', 'm2.meta_value as capabilities', 'm3.meta_value as avatar_meta', 'users.user_url as website', 'users.user_pass as password', 'users.user_registred' )
|
||||
->select('m1.meta_value as description', 'm2.meta_value as capabilities', 'm3.meta_value as avatar_meta', 'users.user_url as website', 'users.user_pass as password', 'users.user_registered' )
|
||||
->first();
|
||||
|
||||
$infos['register_date'] = $wp->user_registred ? strtotime($wp->user_registred) : null;
|
||||
$infos['register_date'] = $wp->user_registered ? strtotime($wp->user_registered) : null;
|
||||
$infos['profile']['about'] = $wp->description;
|
||||
$infos['profile']['website'] = $wp->website;
|
||||
$role = $this->extractWpRole($wp->capabilities);
|
||||
|
||||
22
app/Console/Commands/SubmissionsDown.php
Normal file
22
app/Console/Commands/SubmissionsDown.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Attributes\Description;
|
||||
use Illuminate\Console\Attributes\Signature;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
#[Signature('submissions:down')]
|
||||
#[Description('Disable submissions')]
|
||||
class SubmissionsDown extends Command
|
||||
{
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
Cache::put('submissions_maintenance', true );
|
||||
$this->info("Submissions disabled.");
|
||||
}
|
||||
}
|
||||
22
app/Console/Commands/SubmissionsUp.php
Normal file
22
app/Console/Commands/SubmissionsUp.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Attributes\Description;
|
||||
use Illuminate\Console\Attributes\Signature;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
#[Signature('submissions:up')]
|
||||
#[Description('Enable submissions')]
|
||||
class SubmissionsUp extends Command
|
||||
{
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
Cache::forget('submissions_maintenance');
|
||||
$this->info('Submissions enabled.');
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,8 @@ use App\Models\Entry;
|
||||
use App\Models\EntryFile;
|
||||
use App\Models\News;
|
||||
use App\Services\XenforoApiService;
|
||||
use GuzzleHttp\Exception\ConnectException;
|
||||
use GuzzleHttp\Exception\RequestException;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
@@ -74,25 +76,29 @@ class EntryHelpers {
|
||||
$cacheKey = "news_comments_{$entry->id}";
|
||||
else
|
||||
$cacheKey = "entry_comments_{$entry->id}";
|
||||
return Cache::remember($cacheKey, now()->addDays(1), function () use ($entry, $limit) {
|
||||
return Cache::flexible($cacheKey, [now()->addMinutes(30), now()->addMinutes(60)], function () use ($entry, $limit) {
|
||||
|
||||
$service = app(XenforoApiService::class);
|
||||
try {
|
||||
$service = app(XenforoApiService::class);
|
||||
|
||||
// Get thread infos and pagination.
|
||||
$paginationInfos = $service->getThreadPosts($entry->comments_thread_id, 1);
|
||||
$lastPage = $paginationInfos['pagination']['last_page'] ?? 1;
|
||||
// Get thread infos and pagination.
|
||||
$paginationInfos = $service->getThreadPosts($entry->comments_thread_id, 1);
|
||||
$lastPage = $paginationInfos['pagination']['last_page'] ?? 1;
|
||||
|
||||
// Get last threads
|
||||
$lastPageData = $lastPage > 1 ? $service->getThreadPosts($entry->comments_thread_id, $lastPage) : $paginationInfos;
|
||||
$posts = $lastPageData['posts'] ?? [];
|
||||
// Get last threads
|
||||
$lastPageData = $lastPage > 1 ? $service->getThreadPosts($entry->comments_thread_id, $lastPage) : $paginationInfos;
|
||||
$posts = $lastPageData['posts'] ?? [];
|
||||
|
||||
if( count( $posts ) < $limit && $lastPage > 1 ){
|
||||
$previousPageData = $service->getThreadPosts($entry->comments_thread_id, $lastPage - 1 );
|
||||
$posts = array_merge( $posts, $previousPageData['posts'] ?? [] );
|
||||
if (count($posts) < $limit && $lastPage > 1) {
|
||||
$previousPageData = $service->getThreadPosts($entry->comments_thread_id, $lastPage - 1);
|
||||
$posts = array_merge($posts, $previousPageData['posts'] ?? []);
|
||||
}
|
||||
|
||||
return collect($posts)->slice(-$limit)->reverse()->values()->toArray();
|
||||
} catch (ConnectException|RequestException $e ){
|
||||
return [];
|
||||
}
|
||||
|
||||
return collect( $posts )->slice(-$limit)->reverse()->values()->toArray();
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,13 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Artesaos\SEOTools\Facades\SEOTools;
|
||||
|
||||
abstract class Controller
|
||||
{
|
||||
//
|
||||
protected function seoNoIndex(): void
|
||||
{
|
||||
SEOTools::metatags()->setRobots('noindex, nofollow');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,8 +5,11 @@ namespace App\Http\Controllers;
|
||||
use App\Helpers\EntryHelpers;
|
||||
use App\Models\Entry;
|
||||
use App\Models\News;
|
||||
use Artesaos\SEOTools\Facades\SEOTools;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class EntryController extends Controller
|
||||
@@ -16,6 +19,7 @@ class EntryController extends Controller
|
||||
|
||||
public function index(): View
|
||||
{
|
||||
SEOTools::setTitle('Database');
|
||||
return view('entries.index');
|
||||
}
|
||||
|
||||
@@ -26,6 +30,7 @@ class EntryController extends Controller
|
||||
|
||||
public function show(string $section, Entry $entry): View
|
||||
{
|
||||
|
||||
if (!in_array($section, self::SECTION_TYPES))
|
||||
abort(404);
|
||||
|
||||
@@ -52,6 +57,13 @@ class EntryController extends Controller
|
||||
$comments = EntryHelpers::getLatestComments($entry);
|
||||
$reviews = $entry->reviews()->orderBy('created_at', 'desc')->limit(10)->get();
|
||||
|
||||
SEOTools::setTitle($entry->complete_title ?? $entry->title);
|
||||
SEOTools::setDescription( Str::limit( $entry->description, 150) );
|
||||
SEOTools::opengraph()->addProperty('type', 'article');
|
||||
if( $entry->main_image ){
|
||||
SEOTools::opengraph()->addImage( url( Storage::url( $entry->main_image ) ) );
|
||||
}
|
||||
|
||||
return view('entries.show', compact('entry', 'section', 'comments', 'reviews'));
|
||||
|
||||
}
|
||||
@@ -69,6 +81,7 @@ class EntryController extends Controller
|
||||
->orderBy('updated_at', 'desc')
|
||||
->paginate(20);
|
||||
|
||||
SEOTools::setTitle('My Drafts');
|
||||
return view('entries.drafts', compact('drafts', 'newsDrafts'));
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Entry;
|
||||
use App\Services\ActivityService;
|
||||
use Artesaos\SEOTools\Facades\SEOTools;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
use App\Models\News;
|
||||
@@ -15,6 +16,8 @@ class HomeController extends Controller
|
||||
|
||||
public function index( Request $request ): View {
|
||||
|
||||
SEOTools::setTitle('A Romhack community where you can share your creations with the world.');
|
||||
|
||||
$filters = [ 'entries', 'news', 'messages', 'threads', 'clubs', 'reviews' ];
|
||||
|
||||
$cookie = $request->cookie('activity_filters');
|
||||
|
||||
@@ -19,7 +19,7 @@ class AuthorController extends Controller
|
||||
{
|
||||
$items = Author::withCount('entries')
|
||||
->orderBy('name')
|
||||
->tap(fn($query) => $this->applySearch($query, ['name']))
|
||||
->tap(fn($query) => $this->applySearch($query, ['id','name']))
|
||||
->paginate(30)
|
||||
->withQueryString();
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ class GameController extends Controller
|
||||
public function index()
|
||||
{
|
||||
$items = Game::withCount('entries')->orderBy('name')
|
||||
->tap(fn($query) => $this->applySearch($query, ['name']))
|
||||
->tap(fn($query) => $this->applySearch($query, ['id','name']))
|
||||
->paginate(30)->withQueryString();
|
||||
$platforms = Platform::orderBy('name')->get();
|
||||
$genres = Genre::orderBy('name')->get();
|
||||
|
||||
@@ -18,7 +18,7 @@ class GenreController extends Controller
|
||||
{
|
||||
$items = Genre::withCount('games')
|
||||
->orderBy('name')
|
||||
->tap(fn($query) => $this->applySearch($query, ['name']))
|
||||
->tap(fn($query) => $this->applySearch($query, ['id','name']))
|
||||
->paginate(30)
|
||||
->withQueryString();
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ class LanguageController extends Controller
|
||||
{
|
||||
$items = Language::withCount('entries')
|
||||
->orderBy('name')
|
||||
->tap(fn($query) => $this->applySearch($query, ['name']))
|
||||
->tap(fn($query) => $this->applySearch($query, ['id','name']))
|
||||
->paginate(30)
|
||||
->withQueryString();
|
||||
|
||||
|
||||
67
app/Http/Controllers/ModCP/LevelController.php
Normal file
67
app/Http/Controllers/ModCP/LevelController.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\ModCP;
|
||||
|
||||
use App\Helpers\EntryHelpers;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Level;
|
||||
use App\Traits\ModCPSearch;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class LevelController extends Controller
|
||||
{
|
||||
|
||||
use ModCPSearch;
|
||||
|
||||
public function index()
|
||||
{
|
||||
$items = Level::withCount('entries')
|
||||
->orderBy('name')
|
||||
->tap(fn($query) => $this->applySearch($query, ['id','name']))
|
||||
->paginate(30)
|
||||
->withQueryString();
|
||||
|
||||
return view('modcp.resources', [
|
||||
'items' => $items,
|
||||
'title' => 'Levels',
|
||||
'singular' => 'Level',
|
||||
'storeRoute' => 'modcp.levels.store',
|
||||
'updateRoute' => 'modcp.levels.update',
|
||||
'destroyRoute' => 'modcp.levels.destroy'
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'name' => 'required|string|max:255|unique:levels,name',
|
||||
]);
|
||||
|
||||
Level::create([
|
||||
'name' => trim($request->name),
|
||||
'slug' => EntryHelpers::uniqueSlug( $request->name, Level::class ),
|
||||
]);
|
||||
|
||||
return back()->with('success', 'Level added.');
|
||||
}
|
||||
|
||||
public function update(Request $request, Level $level)
|
||||
{
|
||||
$request->validate([
|
||||
'name' => 'required|string|max:255|unique:levels,name,' . $level->id,
|
||||
]);
|
||||
|
||||
$level->update([
|
||||
'name' => trim($request->name),
|
||||
'slug' => EntryHelpers::uniqueSlug( $request->name, Level::class, $level->id ),
|
||||
]);
|
||||
|
||||
return back()->with('success', 'Level updated.');
|
||||
}
|
||||
|
||||
public function destroy(Level $level)
|
||||
{
|
||||
$level->delete();
|
||||
return back()->with('success', 'Level deleted.');
|
||||
}
|
||||
}
|
||||
67
app/Http/Controllers/ModCP/ModificationsController.php
Normal file
67
app/Http/Controllers/ModCP/ModificationsController.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\ModCP;
|
||||
|
||||
use App\Helpers\EntryHelpers;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Modification;
|
||||
use App\Traits\ModCPSearch;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ModificationsController extends Controller
|
||||
{
|
||||
|
||||
use ModCPSearch;
|
||||
|
||||
public function index()
|
||||
{
|
||||
$items = Modification::withCount('entries')
|
||||
->orderBy('name')
|
||||
->tap(fn($query) => $this->applySearch($query, ['id','name']))
|
||||
->paginate(30)
|
||||
->withQueryString();
|
||||
|
||||
return view('modcp.resources', [
|
||||
'items' => $items,
|
||||
'title' => 'Modifications',
|
||||
'singular' => 'Modification',
|
||||
'storeRoute' => 'modcp.modifications.store',
|
||||
'updateRoute' => 'modcp.modifications.update',
|
||||
'destroyRoute' => 'modcp.modifications.destroy'
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'name' => 'required|string|max:255|unique:modifications,name',
|
||||
]);
|
||||
|
||||
Modification::create([
|
||||
'name' => trim($request->name),
|
||||
'slug' => EntryHelpers::uniqueSlug( $request->name, Modification::class ),
|
||||
]);
|
||||
|
||||
return back()->with('success', 'Modification added.');
|
||||
}
|
||||
|
||||
public function update(Request $request, Modification $Modification)
|
||||
{
|
||||
$request->validate([
|
||||
'name' => 'required|string|max:255|unique:modifications,name,' . $Modification->id,
|
||||
]);
|
||||
|
||||
$Modification->update([
|
||||
'name' => trim($request->name),
|
||||
'slug' => EntryHelpers::uniqueSlug( $request->name, Modification::class, $Modification->id ),
|
||||
]);
|
||||
|
||||
return back()->with('success', 'Modification updated.');
|
||||
}
|
||||
|
||||
public function destroy(Modification $Modification)
|
||||
{
|
||||
$Modification->delete();
|
||||
return back()->with('success', 'Modification deleted.');
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ class PlatformController extends Controller
|
||||
{
|
||||
$items = Platform::withCount(['games','entries'])
|
||||
->orderBy('name')
|
||||
->tap(fn($query) => $this->applySearch($query, ['name']))
|
||||
->tap(fn($query) => $this->applySearch($query, ['id','name']))
|
||||
->paginate(30)
|
||||
->withQueryString();
|
||||
|
||||
|
||||
@@ -4,10 +4,16 @@ namespace App\Http\Controllers;
|
||||
|
||||
use App\Jobs\RestoreXenForoCommentsThread;
|
||||
use App\Models\Entry;
|
||||
use Artesaos\SEOTools\Facades\SEOTools;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ModCPController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
SEOTools::setTitle('ModCP');
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$stats = [
|
||||
|
||||
@@ -11,14 +11,18 @@ use App\Http\Requests\StoreNewsRequest;
|
||||
use App\Jobs\DeleteXenForoCommentsThread;
|
||||
use App\Models\News;
|
||||
use App\Services\NewsService;
|
||||
use Artesaos\SEOTools\Facades\SEOTools;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class NewsController extends Controller
|
||||
{
|
||||
|
||||
public function index()
|
||||
{
|
||||
SEOTools::setTitle('News');
|
||||
return view('news.index');
|
||||
}
|
||||
|
||||
@@ -43,6 +47,13 @@ class NewsController extends Controller
|
||||
|
||||
$comments = EntryHelpers::getLatestComments($news);
|
||||
|
||||
SEOTools::setTitle($news->title);
|
||||
SEOTools::setDescription( Str::limit( $news->description , 150 ) );
|
||||
SEOTools::opengraph()->addProperty('type', 'article');
|
||||
if( $news->gallery->first() ){
|
||||
SEOTools::opengraph()->addImage( url( Storage::url( $news->gallery->first()->image ) ) );
|
||||
}
|
||||
|
||||
return view('news.show', compact('news', 'comments'));
|
||||
}
|
||||
|
||||
@@ -54,6 +65,7 @@ class NewsController extends Controller
|
||||
'oldCategory' => old('category') ? [ old('category') ] : []
|
||||
];
|
||||
|
||||
SEOTools::setTitle('Submit News');
|
||||
return view ('news.create', $data);
|
||||
}
|
||||
|
||||
@@ -65,6 +77,7 @@ class NewsController extends Controller
|
||||
'oldCategory' => old('category', $news->category_id) ? [ old('category', $news->category_id) ] : []
|
||||
];
|
||||
|
||||
SEOTools::setTitle('Edit News');
|
||||
return view ('news.edit', $data);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ use App\Helpers\XenForoHelpers;
|
||||
use App\Models\Entry;
|
||||
use App\Models\News;
|
||||
use App\Services\XenforoService;
|
||||
use Artesaos\SEOTools\Facades\SEOTools;
|
||||
use Illuminate\Http\Request;
|
||||
class QueueController extends Controller
|
||||
{
|
||||
@@ -35,6 +36,7 @@ class QueueController extends Controller
|
||||
return $a->created_at <=> $b->created_at;
|
||||
})->values();
|
||||
|
||||
SEOTools::setTitle('Submissions Queue');
|
||||
return view('queue.index', compact('entries'));
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ use App\Exceptions\SubmissionException;
|
||||
use App\Http\Requests\StoreReviewRequest;
|
||||
use App\Models\Entry;
|
||||
use App\Services\ReviewsService;
|
||||
use Artesaos\SEOTools\Facades\SEOTools;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ReviewController extends Controller
|
||||
@@ -15,6 +16,7 @@ class ReviewController extends Controller
|
||||
|
||||
public function index(){
|
||||
|
||||
SEOTools::setTitle('Reviews');
|
||||
return view('reviews.index');
|
||||
}
|
||||
|
||||
|
||||
56
app/Http/Controllers/ShortLinkController.php
Normal file
56
app/Http/Controllers/ShortLinkController.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Entry;
|
||||
use App\Models\News;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class ShortLinkController extends Controller
|
||||
{
|
||||
|
||||
private const array LETTER_TO_TYPE = [
|
||||
't' => 'translations',
|
||||
'r' => 'romhacks',
|
||||
'h' => 'homebrew',
|
||||
'u' => 'utilities',
|
||||
'd' => 'documents',
|
||||
'l' => 'lua-scripts',
|
||||
];
|
||||
|
||||
public function legacy( int $wpId )
|
||||
{
|
||||
$log = DB::table('migrations_logs')
|
||||
->where('source_system')
|
||||
->whereIn('source_table', ['wp_posts', 'wp_posts__news'] )
|
||||
->where('source_id', $wpId)
|
||||
->first(['target_table', 'target_id']);
|
||||
|
||||
abort_unless((bool)$log, 404);
|
||||
|
||||
if( $log->target_table == 'entries' ){
|
||||
$entry = Entry::findOrFail($log->target_id);
|
||||
return redirect()->route('entries.show', ['section' => $entry->type, 'entry' => $entry], 301 );
|
||||
} else if( $log->target_table == 'news' ){
|
||||
$news = News::findOrFail($log->target_id);
|
||||
return redirect()->route('news.show', ['news' => $news], 301);
|
||||
}
|
||||
|
||||
abort(404);
|
||||
}
|
||||
|
||||
public function redirect( string $letter, int $id )
|
||||
{
|
||||
if( $letter === 'n' ){
|
||||
$news = News::findOrFail($id);
|
||||
return redirect()->route('news.show', ['news' => $news], 301 );
|
||||
}
|
||||
|
||||
$type = self::LETTER_TO_TYPE[$letter] ?? abort(404);
|
||||
$entry = Entry::where('id', $id)->where('type', $type)->firstOrFail();
|
||||
|
||||
return redirect()->route('entries.show', ['section' => $entry->type, 'entry' => $entry], 301 );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,6 +22,7 @@ use App\Models\Status;
|
||||
use App\Models\System;
|
||||
use App\Services\SubmissionsService;
|
||||
use App\Services\XenforoApiService;
|
||||
use Artesaos\SEOTools\Facades\SEOTools;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
@@ -77,8 +78,8 @@ class SubmissionController extends Controller
|
||||
'bg' => '#f3eaff1a',
|
||||
'border' => '#f3eaff40',
|
||||
],
|
||||
'lua-script' => [
|
||||
'slug' => 'lua-script',
|
||||
'lua-scripts' => [
|
||||
'slug' => 'lua-scripts',
|
||||
'label' => 'Lua script',
|
||||
'icon' => 'terminal',
|
||||
'color' => '#a04515',
|
||||
@@ -86,6 +87,7 @@ class SubmissionController extends Controller
|
||||
'border' => '#eed6c540',
|
||||
] ];
|
||||
|
||||
SEOTools::setTitle('Submit');
|
||||
return view('submissions.index', compact('entryTypes'));
|
||||
}
|
||||
|
||||
@@ -119,6 +121,7 @@ class SubmissionController extends Controller
|
||||
$data['levels'] = Level::orderBy('id')->get();
|
||||
}
|
||||
|
||||
SEOTools::setTitle( $data['words']['page_title'] );
|
||||
return view('submissions.create', $data);
|
||||
}
|
||||
|
||||
@@ -156,6 +159,7 @@ class SubmissionController extends Controller
|
||||
$data['levels'] = Level::orderBy('id')->get();
|
||||
}
|
||||
|
||||
SEOTools::setTitle( $data['words']['page_title'] );
|
||||
return view('submissions.edit', $data);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Http\Controllers;
|
||||
use App\Models\Entry;
|
||||
use App\Models\EntryFile;
|
||||
use App\Services\FileServersService;
|
||||
use Artesaos\SEOTools\Facades\SEOTools;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ToolsController extends Controller
|
||||
@@ -31,7 +32,7 @@ class ToolsController extends Controller
|
||||
];
|
||||
|
||||
|
||||
|
||||
SEOTools::setTitle('ROM Patcher');
|
||||
return view('tools.patcher', compact('patches'));
|
||||
}
|
||||
|
||||
@@ -59,11 +60,13 @@ class ToolsController extends Controller
|
||||
'outputName' => $file->filename
|
||||
];
|
||||
|
||||
SEOTools::setTitle('Play online');
|
||||
return view('tools.play', compact('patches', 'emuConfig'));
|
||||
}
|
||||
|
||||
public function hasher( Request $request )
|
||||
{
|
||||
SEOTools::setTitle('Play online');
|
||||
return view('tools.hasher');
|
||||
}
|
||||
|
||||
|
||||
33
app/Http/Middleware/SubmissionsEnabled.php
Normal file
33
app/Http/Middleware/SubmissionsEnabled.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class SubmissionsEnabled
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param Closure(Request): (Response) $next
|
||||
*/
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
if( Cache::get('submissions_maintenance', false ) ){
|
||||
if( $request->expectsJson() ){
|
||||
return response()->json([
|
||||
'message' => 'The submissions are currently in maintenance mode.',
|
||||
], 503 );
|
||||
}
|
||||
|
||||
return back()->withErrors([
|
||||
'maintenance' => "The submissions are currently in maintenance mode.",
|
||||
])->withInput();
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
@@ -106,7 +106,9 @@ class StoreEntryRequest extends FormRequest
|
||||
$rules['new-game-genre'] = 'required_with:new-game-title|integer|nullable|exists:genres,id';
|
||||
}
|
||||
|
||||
if( section_must_be( ['translations', 'romhacks'], $section ) ){
|
||||
$bypassHashes = $isEdit && $this->user()->can('moderate', $this->route('entry') ) && ($this->input('bypass_hashes') !== null);
|
||||
|
||||
if( section_must_be( ['translations', 'romhacks'], $section ) && !$bypassHashes ){
|
||||
$rules['hashes'] = 'array|required|min:1';
|
||||
$rules['hashes.*.filename'] = 'required|string|max:512';
|
||||
$rules['hashes.*.hash_crc32'] = 'required|string|max:512';
|
||||
@@ -138,6 +140,7 @@ class StoreEntryRequest extends FormRequest
|
||||
$ss .= ',locked';
|
||||
$rules['submit-state'] = 'required|in:' . $ss;
|
||||
} else {
|
||||
$rules['nsfw-entry'] = 'nullable|boolean';
|
||||
if( $this->user()->can('skip-queue', '\App\Models\Entry') ){
|
||||
$rules['submit-state'] = 'required|string|in:draft,pending,published';
|
||||
} else {
|
||||
@@ -160,6 +163,7 @@ class StoreEntryRequest extends FormRequest
|
||||
$rules['comments_thread_id'] = 'nullable|integer';
|
||||
$rules['featured'] = 'nullable|boolean';
|
||||
$rules['refresh_created_at'] = 'nullable|boolean';
|
||||
$rules['nsfw-entry'] = 'nullable|boolean';
|
||||
}
|
||||
|
||||
return $rules;
|
||||
|
||||
@@ -175,6 +175,7 @@ class Database extends Component
|
||||
public const array SORT_OPTIONS = [
|
||||
'created_at' => 'Date added',
|
||||
'release_date' => 'Release date',
|
||||
'total_downloads' => 'Total downloads',
|
||||
'title' => 'Title'
|
||||
];
|
||||
|
||||
@@ -236,7 +237,7 @@ class Database extends Component
|
||||
{
|
||||
$query = Entry::query()->published()->with([
|
||||
'game.platform', 'game.genre', 'status', 'authors', 'languages', 'level', 'systems', 'categories', 'modifications'
|
||||
]);
|
||||
])->withSum('files', 'download_count');
|
||||
|
||||
if( $this->search ) {
|
||||
$query->where(function($q) {
|
||||
@@ -328,7 +329,13 @@ class Database extends Component
|
||||
$query->where('user_id', $this->userId);
|
||||
}
|
||||
|
||||
return $query->orderBy($this->sortBy, $this->sortDir);
|
||||
$sortColumn = $this->sortBy;
|
||||
|
||||
if ($sortColumn === 'total_downloads') {
|
||||
return $query->orderByRaw('COALESCE(files_sum_download_count, 0) + old_download_count ' . $this->sortDir);
|
||||
}
|
||||
|
||||
return $query->orderBy($sortColumn, $this->sortDir);
|
||||
}
|
||||
|
||||
private function searchFilter( string $modelClass, string $search )
|
||||
|
||||
@@ -21,6 +21,7 @@ class EntrySelector extends Component
|
||||
if( $entry ) {
|
||||
$this->selectedEntryId = $oldEntryId;
|
||||
$this->entryName = $entry->complete_title ?? $entry->title;
|
||||
$this->search = $entry->complete_title ?? $entry->title;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,8 @@ class HashesUpload extends Component
|
||||
public function mount( array $oldHashes = [] ): void
|
||||
{
|
||||
foreach ($oldHashes as $hash) {
|
||||
$this->addHash( $hash['filename'], $hash['hash_crc32'], $hash['hash_sha1'], $hash['verified'] );
|
||||
if( isset( $hash['filename'], $hash['hash_crc32'], $hash['hash_sha1'], $hash['verified'] ) )
|
||||
$this->addHash( $hash['filename'], $hash['hash_crc32'], $hash['hash_sha1'], $hash['verified'] );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ use App\Services\XenforoService;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Spatie\Activitylog\Models\Concerns\LogsActivity;
|
||||
use Spatie\Activitylog\Support\LogOptions;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
@@ -32,6 +34,9 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
*/
|
||||
class Author extends Model
|
||||
{
|
||||
|
||||
use LogsActivity;
|
||||
|
||||
protected $fillable = [
|
||||
'name', 'slug', 'user_id', 'website'
|
||||
];
|
||||
@@ -49,4 +54,14 @@ class Author extends Model
|
||||
return app(XenforoService::class)->getXfUser($this->user_id);
|
||||
}
|
||||
|
||||
public function getActivitylogOptions(): LogOptions
|
||||
{
|
||||
return LogOptions::defaults()
|
||||
->useLogName('author')
|
||||
->logAll()
|
||||
->logOnlyDirty()
|
||||
->dontLogEmptyChanges()
|
||||
->setDescriptionForEvent(fn(string $eventName) => "Author {$eventName}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Models;
|
||||
|
||||
use App\Helpers\EntryHelpers;
|
||||
use App\Models\Scopes\NsfwScope;
|
||||
use App\Traits\HasGallery;
|
||||
use App\Traits\HasXenforoUserId;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
@@ -137,7 +138,8 @@ class Entry extends Model
|
||||
'staff_comment',
|
||||
'rejected_at',
|
||||
'level_id',
|
||||
'created_at'
|
||||
'created_at',
|
||||
'nsfw'
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -151,11 +153,15 @@ class Entry extends Model
|
||||
];
|
||||
|
||||
protected static function booted(): void {
|
||||
|
||||
static::addGlobalScope(new NsfwScope);
|
||||
|
||||
static::saving( function( $entry ) {
|
||||
if( $entry->isDirty('version') ) {
|
||||
$entry->created_at = now();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -247,6 +253,11 @@ class Entry extends Model
|
||||
return $converter->convert($this->description)->getContent();
|
||||
}
|
||||
|
||||
public function getTotalDownloadsAttribute(): int
|
||||
{
|
||||
return $this->files->sum('download_count') + $this->old_download_count;
|
||||
}
|
||||
|
||||
public function parseStaffCredits(): ?array {
|
||||
return json_decode( $this->staff_credits ?? "", true );
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Support\Str;
|
||||
use League\CommonMark\GithubFlavoredMarkdownConverter;
|
||||
use Spatie\Activitylog\Models\Concerns\LogsActivity;
|
||||
use Spatie\Activitylog\Support\LogOptions;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
@@ -41,7 +43,7 @@ use League\CommonMark\GithubFlavoredMarkdownConverter;
|
||||
class EntryReview extends Model
|
||||
{
|
||||
|
||||
use HasXenforoUserId, SoftDeletes;
|
||||
use HasXenforoUserId, SoftDeletes, LogsActivity;
|
||||
|
||||
protected $fillable = [ 'entry_id', 'title', 'rating', 'description', 'user_id' ];
|
||||
|
||||
@@ -60,4 +62,14 @@ class EntryReview extends Model
|
||||
return $converter->convert($this->description)->getContent();
|
||||
}
|
||||
|
||||
public function getActivitylogOptions(): LogOptions
|
||||
{
|
||||
return LogOptions::defaults()
|
||||
->useLogName('review')
|
||||
->logAll()
|
||||
->logOnlyDirty()
|
||||
->dontLogEmptyChanges()
|
||||
->setDescriptionForEvent(fn(string $eventName) => "Review {$eventName}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Spatie\Activitylog\Models\Concerns\LogsActivity;
|
||||
use Spatie\Activitylog\Support\LogOptions;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
@@ -31,6 +33,9 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
*/
|
||||
class Game extends Model
|
||||
{
|
||||
|
||||
use LogsActivity;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
@@ -50,4 +55,14 @@ class Game extends Model
|
||||
{
|
||||
return $this->hasMany(Entry::class);
|
||||
}
|
||||
|
||||
public function getActivitylogOptions(): LogOptions
|
||||
{
|
||||
return LogOptions::defaults()
|
||||
->useLogName('game')
|
||||
->logAll()
|
||||
->logOnlyDirty()
|
||||
->dontLogEmptyChanges()
|
||||
->setDescriptionForEvent(fn(string $eventName) => "Game {$eventName}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
@@ -23,4 +24,9 @@ use Illuminate\Database\Eloquent\Model;
|
||||
class Level extends Model
|
||||
{
|
||||
protected $fillable = ['name', 'slug'];
|
||||
|
||||
public function entries(): HasMany
|
||||
{
|
||||
return $this->hasMany(Entry::class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
@@ -23,4 +25,9 @@ use Illuminate\Database\Eloquent\Model;
|
||||
class Modification extends Model
|
||||
{
|
||||
protected $fillable = [ 'name', 'slug' ];
|
||||
|
||||
public function entries(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Entry::class, 'entry_modifications');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use League\CommonMark\GithubFlavoredMarkdownConverter;
|
||||
use Spatie\Activitylog\Models\Concerns\LogsActivity;
|
||||
use Spatie\Activitylog\Support\LogOptions;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
@@ -61,7 +63,7 @@ use League\CommonMark\GithubFlavoredMarkdownConverter;
|
||||
class News extends Model
|
||||
{
|
||||
|
||||
use SoftDeletes, HasGallery, HasXenforoUserId;
|
||||
use SoftDeletes, HasGallery, HasXenforoUserId, LogsActivity;
|
||||
|
||||
protected $table = 'news';
|
||||
|
||||
@@ -127,4 +129,14 @@ class News extends Model
|
||||
return EntryHelpers::getYoutubeVideoId( $this->youtube_link );
|
||||
}
|
||||
|
||||
public function getActivitylogOptions(): LogOptions
|
||||
{
|
||||
return LogOptions::defaults()
|
||||
->useLogName('news')
|
||||
->logAll()
|
||||
->logOnlyDirty()
|
||||
->dontLogEmptyChanges()
|
||||
->setDescriptionForEvent(fn(string $eventName) => "News {$eventName}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
29
app/Models/Scopes/NsfwScope.php
Normal file
29
app/Models/Scopes/NsfwScope.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Scopes;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Scope;
|
||||
|
||||
class NsfwScope implements Scope
|
||||
{
|
||||
|
||||
private function canNsfw(): bool
|
||||
{
|
||||
if( \Auth::guest() )
|
||||
return false;
|
||||
|
||||
$user = \Auth::user();
|
||||
return $user->nsfw_content === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the scope to a given Eloquent query builder.
|
||||
*/
|
||||
public function apply(Builder $builder, Model $model): void
|
||||
{
|
||||
if( !$this->canNsfw() )
|
||||
$builder->where('nsfw', false );
|
||||
}
|
||||
}
|
||||
@@ -159,7 +159,7 @@ class EntryPolicy
|
||||
return $user->_can('romhackplaza', 'canModerateEntries' );
|
||||
}
|
||||
|
||||
public function moderate(User $user, Entry $entry): bool
|
||||
public function moderate(User $user, ?Entry $entry = null): bool
|
||||
{
|
||||
return $user->_can('romhackplaza', 'canModerateEntries' );
|
||||
}
|
||||
|
||||
@@ -199,6 +199,9 @@ class ActivityService
|
||||
'post.user_id', 'post.message'
|
||||
])
|
||||
->get()
|
||||
->reject(function($post){
|
||||
return (int) $post->user_id === config('xenforo.bot_user_id');
|
||||
})
|
||||
->map($this->formatMessage(...))
|
||||
->toArray();
|
||||
});
|
||||
@@ -213,6 +216,7 @@ class ActivityService
|
||||
->join('post', 'thread.first_post_id', '=', 'post.post_id')
|
||||
->where('thread.discussion_state', 'visible')
|
||||
->where('thread.discussion_type', '!=', 'redirect' )
|
||||
->where('thread.node_id', '!=', config('xenforo.comments_node_id') )
|
||||
->orderByDesc('thread.post_date')
|
||||
->limit(self::ITEMS_PER_TYPE)
|
||||
->select([
|
||||
|
||||
@@ -174,7 +174,8 @@ class SubmissionsService {
|
||||
'youtube_link' => $this->request->input('youtube_video'),
|
||||
'user_id' => $user_id,
|
||||
'complete_title' => $completeTitle,
|
||||
'level_id' => $this->request->input('level')
|
||||
'level_id' => $this->request->input('level'),
|
||||
'nsfw' => $this->request->input('nsfw-entry') ?? false,
|
||||
];
|
||||
|
||||
$entry = Entry::create( $fields );
|
||||
@@ -608,6 +609,7 @@ class SubmissionsService {
|
||||
$refresh_created_at = $this->request->input('refresh_created_at') ?? false;
|
||||
if( $refresh_created_at )
|
||||
$fields['created_at'] = now();
|
||||
$fields['nsfw'] = $this->request->input('nsfw-entry') ?? false;
|
||||
}
|
||||
|
||||
$this->entry->update( $fields );
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\Entry;
|
||||
use App\Models\News;
|
||||
use Illuminate\Http\Client\ConnectionException;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
@@ -24,39 +25,45 @@ class XenforoApiService {
|
||||
*/
|
||||
private function get(string $endpoint, ?int $customUserId = null ): mixed
|
||||
{
|
||||
$response = Http::timeout(30)->withHeaders([
|
||||
$response = Http::timeout(8)->connectTimeout(4)->withOptions(['verify' => false])->withHeaders([
|
||||
'XF-Api-Key' => $this->apiKey,
|
||||
'XF-Api-User' => $customUserId ?? $this->superUserId,
|
||||
])->get("{$this->apiUrl}/{$endpoint}");
|
||||
|
||||
if( !$response->ok() )
|
||||
if( !$response->ok() ) {
|
||||
\Illuminate\Support\Facades\Log::error("XF API error [{$response->status()}] on {$endpoint}: " . $response->body());
|
||||
return null;
|
||||
}
|
||||
|
||||
return $response->json();
|
||||
}
|
||||
|
||||
private function post(string $endpoint, ?int $customUserId = null, array $data = [] ): mixed
|
||||
{
|
||||
$response = Http::timeout(30)->withHeaders([
|
||||
$response = Http::timeout(8)->connectTimeout(4)->withOptions(['verify' => false])->withHeaders([
|
||||
'XF-Api-Key' => $this->apiKey,
|
||||
'XF-Api-User' => $customUserId ?? $this->superUserId,
|
||||
])->post("{$this->apiUrl}/{$endpoint}", $data);
|
||||
|
||||
if( !$response->ok() )
|
||||
if( !$response->ok() ) {
|
||||
\Illuminate\Support\Facades\Log::error("XF API error [{$response->status()}] on {$endpoint}: " . $response->body());
|
||||
return null;
|
||||
}
|
||||
|
||||
return $response->json();
|
||||
}
|
||||
|
||||
private function delete(string $endpoint, ?int $customUserId = null, array $data = [] ): mixed
|
||||
{
|
||||
$response = Http::timeout(30)->withHeaders([
|
||||
$response = Http::timeout(8)->connectTimeout(4)->withOptions(['verify' => false])->withHeaders([
|
||||
'XF-Api-Key' => $this->apiKey,
|
||||
'XF-Api-User' => $customUserId ?? $this->superUserId,
|
||||
])->delete("{$this->apiUrl}/{$endpoint}", $data);
|
||||
|
||||
if( !$response->ok() )
|
||||
if( !$response->ok() ) {
|
||||
\Illuminate\Support\Facades\Log::error("XF API error [{$response->status()}] on {$endpoint}: " . $response->body());
|
||||
return null;
|
||||
}
|
||||
|
||||
return $response->json();
|
||||
}
|
||||
@@ -75,7 +82,7 @@ class XenforoApiService {
|
||||
public function markAllNotificationsRead(int $userId): void
|
||||
{
|
||||
Cache::forget("xf_alerts_{$userId}");
|
||||
$this->post("alerts/mark-all", $userId );
|
||||
$this->post("alerts/mark-all", $userId, ['read' => true, 'viewed' => true] );
|
||||
}
|
||||
|
||||
public function getConversations(int $userId): mixed
|
||||
@@ -98,10 +105,10 @@ class XenforoApiService {
|
||||
if( !$entry->comments_thread_id || $entry->comments_thread_id <= 0 ){
|
||||
$data = [
|
||||
'node_id' => config('xenforo.comments_node_id'),
|
||||
'title' => $entry->complete_title,
|
||||
'title' => $entry->complete_title ?? $entry->title,
|
||||
'message' => $entry->description,
|
||||
'prefix_id' => config('xenforo.comments_prefixes')[$entry->type] ?? 1,
|
||||
'custom_fields' => [ 'entry_id' => $entry->id ],
|
||||
'prefix_id' => config('xenforo.comments_prefixes')[$entry->type ?? "news"] ?? 1,
|
||||
'custom_fields' => $entry->type ? [ 'entry_id' => $entry->id ] : [ 'news_id' => $entry->id ],
|
||||
'discussion_open' => true,
|
||||
];
|
||||
|
||||
|
||||
@@ -14,6 +14,10 @@ class ErrorBlock extends Component
|
||||
'icon' => 'ban',
|
||||
'message' => '%s'
|
||||
],
|
||||
'not-found' => [
|
||||
'icon' => 'sticky-note-off',
|
||||
'message' => "404: This page does not exist."
|
||||
],
|
||||
'page-not-allowed' => [
|
||||
'icon' => 'shield-ban',
|
||||
'message' => "You do not have permission to access this page.\nRequired permission: %s"
|
||||
@@ -21,6 +25,10 @@ class ErrorBlock extends Component
|
||||
'user-state-not-valid' => [
|
||||
'icon' => 'shield-ban',
|
||||
'message' => "You do not have permission to access this page.\nYour user profile is incomplete: %s\nGo back to the forum for more details."
|
||||
],
|
||||
'server-error' => [
|
||||
'icon' => 'bomb',
|
||||
'message' => "500: Internal Server Error."
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
@@ -61,6 +61,10 @@ class SubmitEntryStatus extends Component
|
||||
}
|
||||
}
|
||||
|
||||
if( $this->isEdit && $this->entry->state === 'pending' && isset( $states['published'] ) ) {
|
||||
unset( $states['published'] );
|
||||
}
|
||||
|
||||
return $states;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ return Application::configure(basePath: dirname(__DIR__))
|
||||
$middleware->encryptCookies(except: ['xf_session','xf_user','xf_csrf','xf_style_variation','activity_filters']);
|
||||
$middleware->alias([
|
||||
'xf.auth' => \App\Http\Middleware\CheckXenForoPermissions::class,
|
||||
'submissions.maintenance' => \App\Http\Middleware\SubmissionsEnabled::class,
|
||||
]);
|
||||
$middleware->redirectGuestsTo(function(Request $request): void {
|
||||
if( $request->is('manage*'))
|
||||
@@ -24,5 +25,28 @@ return Application::configure(basePath: dirname(__DIR__))
|
||||
$middleware->append(\App\Http\Middleware\CheckXenForoUserState::class);
|
||||
})
|
||||
->withExceptions(function (Exceptions $exceptions): void {
|
||||
//
|
||||
$exceptions->render(function(Throwable $e, $request) {
|
||||
if (
|
||||
$e instanceof \Illuminate\Validation\ValidationException ||
|
||||
$e instanceof \Illuminate\Auth\AuthenticationException ||
|
||||
$e instanceof \Illuminate\Auth\Access\AuthorizationException ||
|
||||
$e instanceof \Symfony\Component\HttpKernel\Exception\HttpException
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
$statusCode = method_exists($e, 'getStatusCode') ? $e->getStatusCode() : 500;
|
||||
|
||||
if( app()->environment('production') && $statusCode >= 500 && !$request->expectsJson() ){
|
||||
$errorId = (string) Str::uuid();
|
||||
|
||||
\Illuminate\Support\Facades\Log::error($e->getMessage(), [
|
||||
'error_id' => $errorId,
|
||||
'exception' => $e,
|
||||
'url' => $request->fullUrl(),
|
||||
'user_id' => (optional($request->user())->user_id ?? 0),
|
||||
]);
|
||||
|
||||
return response()->view('errors.500', ['errorId' => $errorId], 500 );
|
||||
}
|
||||
});
|
||||
})->create();
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
"ext-pdo": "*",
|
||||
"ext-simplexml": "*",
|
||||
"ext-xmlreader": "*",
|
||||
"artesaos/seotools": "^1.4",
|
||||
"diglactic/laravel-breadcrumbs": "^10.1",
|
||||
"filament/filament": "^5.6",
|
||||
"laravel/framework": "^13.7",
|
||||
@@ -18,7 +19,9 @@
|
||||
"league/html-to-markdown": "^5.1",
|
||||
"livewire/livewire": "^4.3",
|
||||
"predis/predis": "^3.4",
|
||||
"spatie/laravel-activitylog": "^5.0"
|
||||
"spatie/laravel-activitylog": "^5.0",
|
||||
"spatie/laravel-sitemap": "*",
|
||||
"spatie/simple-excel": "^3.10"
|
||||
},
|
||||
"require-dev": {
|
||||
"barryvdh/laravel-debugbar": "^4.2",
|
||||
|
||||
416
composer.lock
generated
416
composer.lock
generated
@@ -4,8 +4,79 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "ea9258b1759d46665d2487b066c686ee",
|
||||
"content-hash": "7c9b7fd591cb7e152659cf998900a531",
|
||||
"packages": [
|
||||
{
|
||||
"name": "artesaos/seotools",
|
||||
"version": "v1.4.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/artesaos/seotools.git",
|
||||
"reference": "c92d09f0ad4491181863850a3ab2e1534361409b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/artesaos/seotools/zipball/c92d09f0ad4491181863850a3ab2e1534361409b",
|
||||
"reference": "c92d09f0ad4491181863850a3ab2e1534361409b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"illuminate/config": "^10.0 || ^11.0 || ^12.0 || ^13.0",
|
||||
"illuminate/support": "^10.0 || ^11.0 || ^12.0 || ^13.0",
|
||||
"php": "^8.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"orchestra/testbench": "^8.0 || ^9.0 || ^10.0 || ^11.0",
|
||||
"phpunit/phpunit": "^9.0 || ^10.0 || ^11.5.3"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"aliases": {
|
||||
"SEO": "Artesaos\\SEOTools\\Facades\\SEOTools",
|
||||
"JsonLd": "Artesaos\\SEOTools\\Facades\\JsonLd",
|
||||
"SEOMeta": "Artesaos\\SEOTools\\Facades\\SEOMeta",
|
||||
"Twitter": "Artesaos\\SEOTools\\Facades\\TwitterCard",
|
||||
"OpenGraph": "Artesaos\\SEOTools\\Facades\\OpenGraph"
|
||||
},
|
||||
"providers": [
|
||||
"Artesaos\\SEOTools\\Providers\\SEOToolsServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Artesaos\\SEOTools\\": "src/SEOTools/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Vinicius",
|
||||
"email": "luiz.vinicius73@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "SEO Tools for Laravel and Lumen",
|
||||
"keywords": [
|
||||
"JSON-LD",
|
||||
"laravel",
|
||||
"lumen",
|
||||
"metatags",
|
||||
"opengraph",
|
||||
"seo",
|
||||
"seotools",
|
||||
"webmaster"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/artesaos/seotools/issues",
|
||||
"source": "https://github.com/artesaos/seotools"
|
||||
},
|
||||
"time": "2026-03-28T12:37:33+00:00"
|
||||
},
|
||||
{
|
||||
"name": "blade-ui-kit/blade-heroicons",
|
||||
"version": "2.7.0",
|
||||
@@ -5303,6 +5374,85 @@
|
||||
],
|
||||
"time": "2022-12-17T21:53:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spatie/crawler",
|
||||
"version": "9.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/spatie/crawler.git",
|
||||
"reference": "3b3a9a1a8c750b0240c2b7c9e2ef22e84092416e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/spatie/crawler/zipball/3b3a9a1a8c750b0240c2b7c9e2ef22e84092416e",
|
||||
"reference": "3b3a9a1a8c750b0240c2b7c9e2ef22e84092416e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"guzzlehttp/guzzle": "^7.3",
|
||||
"guzzlehttp/psr7": "^2.0",
|
||||
"php": "^8.4",
|
||||
"spatie/robots-txt": "^2.0",
|
||||
"symfony/css-selector": "^7.0|^8.0",
|
||||
"symfony/dom-crawler": "^7.0|^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"pestphp/pest": "^4.0",
|
||||
"phpstan/extension-installer": "^1.4",
|
||||
"phpstan/phpstan": "^2.0",
|
||||
"phpstan/phpstan-deprecation-rules": "^2.0",
|
||||
"phpstan/phpstan-phpunit": "^2.0",
|
||||
"spatie/invade": "^2.1",
|
||||
"spatie/ray": "^1.37"
|
||||
},
|
||||
"suggest": {
|
||||
"spatie/browsershot": "Required for JavaScript rendering with BrowsershotRenderer (^5.0.5)"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-v9": "9.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Spatie\\Crawler\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Freek Van der Herten",
|
||||
"email": "freek@spatie.be"
|
||||
}
|
||||
],
|
||||
"description": "Crawl all internal links found on a website",
|
||||
"homepage": "https://github.com/spatie/crawler",
|
||||
"keywords": [
|
||||
"crawler",
|
||||
"link",
|
||||
"spatie",
|
||||
"website"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/spatie/crawler/issues",
|
||||
"source": "https://github.com/spatie/crawler/tree/9.3.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://spatie.be/open-source/support-us",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/spatie",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2026-06-12T15:45:15+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spatie/invade",
|
||||
"version": "2.1.0",
|
||||
@@ -5516,6 +5666,140 @@
|
||||
],
|
||||
"time": "2026-02-21T12:49:54+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spatie/laravel-sitemap",
|
||||
"version": "8.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/spatie/laravel-sitemap.git",
|
||||
"reference": "51f52030ab22abf5e95ed037fea5f8073114e784"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/spatie/laravel-sitemap/zipball/51f52030ab22abf5e95ed037fea5f8073114e784",
|
||||
"reference": "51f52030ab22abf5e95ed037fea5f8073114e784",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/support": "^12.0|^13.0",
|
||||
"nesbot/carbon": "^2.71|^3.0",
|
||||
"php": "^8.4",
|
||||
"spatie/crawler": "^9.0",
|
||||
"spatie/laravel-package-tools": "^1.16.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"larastan/larastan": "^3.0",
|
||||
"laravel/pint": "^1.13",
|
||||
"orchestra/testbench": "^10.0|^11.0",
|
||||
"pestphp/pest": "^4.0",
|
||||
"phpstan/extension-installer": "^1.3",
|
||||
"phpstan/phpstan-deprecation-rules": "^2.0",
|
||||
"phpstan/phpstan-phpunit": "^2.0",
|
||||
"spatie/pest-plugin-snapshots": "^2.1",
|
||||
"spatie/temporary-directory": "^2.2"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Spatie\\Sitemap\\SitemapServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Spatie\\Sitemap\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Freek Van der Herten",
|
||||
"email": "freek@spatie.be",
|
||||
"homepage": "https://spatie.be",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Create and generate sitemaps with ease",
|
||||
"homepage": "https://github.com/spatie/laravel-sitemap",
|
||||
"keywords": [
|
||||
"laravel-sitemap",
|
||||
"spatie"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/spatie/laravel-sitemap/tree/8.2.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://spatie.be/open-source/support-us",
|
||||
"type": "custom"
|
||||
}
|
||||
],
|
||||
"time": "2026-06-24T07:59:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spatie/robots-txt",
|
||||
"version": "2.5.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/spatie/robots-txt.git",
|
||||
"reference": "a8dd35d0a94e863f52509a366a634978e9c1db03"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/spatie/robots-txt/zipball/a8dd35d0a94e863f52509a366a634978e9c1db03",
|
||||
"reference": "a8dd35d0a94e863f52509a366a634978e9c1db03",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^8.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^11.5.2"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Spatie\\Robots\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Brent Roose",
|
||||
"email": "brent@spatie.be",
|
||||
"homepage": "https://spatie.be",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Determine if a page may be crawled from robots.txt and robots meta tags",
|
||||
"homepage": "https://github.com/spatie/robots-txt",
|
||||
"keywords": [
|
||||
"robots-txt",
|
||||
"spatie"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/spatie/robots-txt/issues",
|
||||
"source": "https://github.com/spatie/robots-txt/tree/2.5.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://spatie.be/open-source/support-us",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/spatie",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2026-02-25T07:59:20+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spatie/shiki-php",
|
||||
"version": "2.4.0",
|
||||
@@ -5581,6 +5865,66 @@
|
||||
],
|
||||
"time": "2026-04-27T14:27:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spatie/simple-excel",
|
||||
"version": "3.10.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/spatie/simple-excel.git",
|
||||
"reference": "2aa4cd9da6f29a23e4f7b6f4c6944dce204ea47a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/spatie/simple-excel/zipball/2aa4cd9da6f29a23e4f7b6f4c6944dce204ea47a",
|
||||
"reference": "2aa4cd9da6f29a23e4f7b6f4c6944dce204ea47a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/support": "^9.0|^10.0|^11.0|^12.0|^13.0",
|
||||
"openspout/openspout": "^4.30",
|
||||
"php": "^8.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.4|^10.5|^11.0|^12.0",
|
||||
"spatie/pest-plugin-snapshots": "^1.1|^2.1",
|
||||
"spatie/phpunit-snapshot-assertions": "^4.0|^5.1",
|
||||
"spatie/temporary-directory": "^1.2|^2.2"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Spatie\\SimpleExcel\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Freek Van der Herten",
|
||||
"email": "freek@spatie.be",
|
||||
"homepage": "https://spatie.be",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Read and write simple Excel and CSV files",
|
||||
"homepage": "https://github.com/spatie/simple-excel",
|
||||
"keywords": [
|
||||
"simple-excel",
|
||||
"spatie"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/spatie/simple-excel/tree/3.10.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/spatie",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2026-06-15T06:21:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/clock",
|
||||
"version": "v8.0.8",
|
||||
@@ -5888,6 +6232,76 @@
|
||||
],
|
||||
"time": "2026-04-13T15:52:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/dom-crawler",
|
||||
"version": "v8.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/dom-crawler.git",
|
||||
"reference": "77ca351474ea018daba5f2e473cbf1b9b8e72ac6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/77ca351474ea018daba5f2e473cbf1b9b8e72ac6",
|
||||
"reference": "77ca351474ea018daba5f2e473cbf1b9b8e72ac6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.4.1",
|
||||
"symfony/polyfill-ctype": "^1.8",
|
||||
"symfony/polyfill-mbstring": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/css-selector": "^7.4|^8.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\DomCrawler\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Eases DOM navigation for HTML and XML documents",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/dom-crawler/tree/v8.1.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2026-05-29T05:06:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/error-handler",
|
||||
"version": "v8.0.8",
|
||||
|
||||
@@ -52,7 +52,7 @@ return [
|
||||
[
|
||||
'name' => 'Discord',
|
||||
'icon' => 'messages-square',
|
||||
'route' => 'home'
|
||||
'custom_route' => 'https://discord.gg/5CKzeWmZZU'
|
||||
],
|
||||
[
|
||||
'name' => 'Members',
|
||||
@@ -80,15 +80,21 @@ return [
|
||||
'pages' => [
|
||||
'name' => 'Pages',
|
||||
'items' => [
|
||||
[
|
||||
'name' => 'Support us',
|
||||
'icon' => 'coffee',
|
||||
'custom_route' => 'https://ko-fi.com/romhackplaza',
|
||||
'color' => 'var(--rhpz-orange)'
|
||||
],
|
||||
[
|
||||
'name' => 'Learn Romhacking',
|
||||
'icon' => 'graduation-cap',
|
||||
'route' => 'home'
|
||||
'xf_route' => 'help/learn-romhacking'
|
||||
],
|
||||
[
|
||||
'name' => 'About',
|
||||
'icon' => 'info',
|
||||
'route' => 'home'
|
||||
'xf_route' => 'help/about'
|
||||
],
|
||||
[
|
||||
'name' => 'Contact Us',
|
||||
@@ -96,9 +102,9 @@ return [
|
||||
'xf_route' => 'misc/contact'
|
||||
],
|
||||
[
|
||||
'name' => 'Legal pages',
|
||||
'name' => 'Help & Legal pages',
|
||||
'icon' => 'scale',
|
||||
'route' => 'home'
|
||||
'xf_route' => 'help'
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
69
config/seotools.php
Normal file
69
config/seotools.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
/**
|
||||
* @see https://github.com/artesaos/seotools
|
||||
*/
|
||||
|
||||
return [
|
||||
'inertia' => env('SEO_TOOLS_INERTIA', false),
|
||||
'meta' => [
|
||||
/*
|
||||
* The default configurations to be used by the meta generator.
|
||||
*/
|
||||
'defaults' => [
|
||||
'title' => "Romhack Plaza", // set false to total remove
|
||||
'titleBefore' => false, // Put defaults.title before page title, like 'It's Over 9000! - Dashboard'
|
||||
'description' => 'A Romhack community where you can share your creations with the world.', // set false to total remove
|
||||
'separator' => ' - ',
|
||||
'keywords' => [],
|
||||
'canonical' => 'current', // Set to null or 'full' to use Url::full(), set to 'current' to use Url::current(), set false to total remove
|
||||
'robots' => 'index, follow', // Set to 'all', 'none' or any combination of index/noindex and follow/nofollow
|
||||
],
|
||||
/*
|
||||
* Webmaster tags are always added.
|
||||
*/
|
||||
'webmaster_tags' => [
|
||||
'google' => null,
|
||||
'bing' => null,
|
||||
'alexa' => null,
|
||||
'pinterest' => null,
|
||||
'yandex' => null,
|
||||
'norton' => null,
|
||||
],
|
||||
|
||||
'add_notranslate_class' => false,
|
||||
],
|
||||
'opengraph' => [
|
||||
/*
|
||||
* The default configurations to be used by the opengraph generator.
|
||||
*/
|
||||
'defaults' => [
|
||||
'title' => 'Romhack Plaza', // set false to total remove
|
||||
'description' => 'A Romhack community where you can share your creations with the world.', // set false to total remove
|
||||
'url' => null, // Set null for using Url::current(), set false to total remove
|
||||
'type' => 'website',
|
||||
'site_name' => 'Romhack Plaza',
|
||||
'images' => [ 'logo/plaza-logo.png' ],
|
||||
],
|
||||
],
|
||||
'twitter' => [
|
||||
/*
|
||||
* The default values to be used by the twitter cards generator.
|
||||
*/
|
||||
'defaults' => [
|
||||
'card' => 'summary_large_image',
|
||||
'site' => '@romhackplaza'
|
||||
],
|
||||
],
|
||||
'json-ld' => [
|
||||
/*
|
||||
* The default configurations to be used by the json-ld generator.
|
||||
*/
|
||||
'defaults' => [
|
||||
'title' => 'Romhack Plaza', // set false to total remove
|
||||
'description' => 'A Romhack community where you can share your creations with the world.', // set false to total remove
|
||||
'url' => 'current', // Set to null or 'full' to use Url::full(), set to 'current' to use Url::current(), set false to total remove
|
||||
'type' => 'WebPage',
|
||||
'images' => [ 'logo/plaza-logo.png' ],
|
||||
],
|
||||
],
|
||||
];
|
||||
@@ -1,18 +0,0 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'bot_user_id' => 1,
|
||||
|
||||
'comments_node_id' => 4,
|
||||
|
||||
'comments_prefixes' => [
|
||||
'translations' => 1,
|
||||
'romhacks' => 2,
|
||||
'homebrew' => 3,
|
||||
'utilities' => 4,
|
||||
'documents' => 5,
|
||||
'lua-scripts' => 6,
|
||||
'tutorials' => 7,
|
||||
'news' => 8
|
||||
],
|
||||
];
|
||||
@@ -44,7 +44,7 @@ return new class extends Migration
|
||||
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['type','status','game_id','platform_id','status_id']);
|
||||
$table->index(['type','state','game_id','platform_id','status_id']);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('migration_files', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('filename');
|
||||
$table->string('old_path');
|
||||
$table->unsignedBigInteger('wp_post_id');
|
||||
$table->uuid('uuid');
|
||||
$table->string('new_path');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('migration_files');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('entries', function (Blueprint $table) {
|
||||
$table->boolean('nsfw')->default(false);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('entries', function (Blueprint $table) {
|
||||
$table->dropColumn('nsfw');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('entries', function (Blueprint $table) {
|
||||
$table->unsignedBigInteger('old_download_count')->default(0);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('entries', function (Blueprint $table) {
|
||||
$table->dropColumn('old_download_count');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -1,634 +0,0 @@
|
||||
/*M!999999\- enable the sandbox mode */
|
||||
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
|
||||
/*!40103 SET TIME_ZONE='+00:00' */;
|
||||
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||
/*M!100616 SET @OLD_NOTE_VERBOSITY=@@NOTE_VERBOSITY, NOTE_VERBOSITY=0 */;
|
||||
DROP TABLE IF EXISTS `activity_log`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `activity_log` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`log_name` varchar(255) DEFAULT NULL,
|
||||
`description` text NOT NULL,
|
||||
`subject_type` varchar(255) DEFAULT NULL,
|
||||
`subject_id` bigint(20) unsigned DEFAULT NULL,
|
||||
`event` varchar(255) DEFAULT NULL,
|
||||
`causer_type` varchar(255) DEFAULT NULL,
|
||||
`causer_id` bigint(20) unsigned DEFAULT NULL,
|
||||
`attribute_changes` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`attribute_changes`)),
|
||||
`properties` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`properties`)),
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `subject` (`subject_type`,`subject_id`),
|
||||
KEY `causer` (`causer_type`,`causer_id`),
|
||||
KEY `activity_log_log_name_index` (`log_name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `authors`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `authors` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`slug` varchar(255) NOT NULL,
|
||||
`website` varchar(500) DEFAULT NULL,
|
||||
`user_id` int(10) unsigned DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `authors_slug_unique` (`slug`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `cache`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `cache` (
|
||||
`key` varchar(255) NOT NULL,
|
||||
`value` mediumtext NOT NULL,
|
||||
`expiration` bigint(20) NOT NULL,
|
||||
PRIMARY KEY (`key`),
|
||||
KEY `cache_expiration_index` (`expiration`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `cache_locks`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `cache_locks` (
|
||||
`key` varchar(255) NOT NULL,
|
||||
`owner` varchar(255) NOT NULL,
|
||||
`expiration` bigint(20) NOT NULL,
|
||||
PRIMARY KEY (`key`),
|
||||
KEY `cache_locks_expiration_index` (`expiration`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `categories`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `categories` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`slug` varchar(255) NOT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
`restricted_to` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`restricted_to`)),
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `categories_slug_unique` (`slug`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `entries`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `entries` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`type` enum('translations','romhacks','homebrew','utilities','documents','lua-scripts','tutorials') NOT NULL,
|
||||
`title` varchar(255) DEFAULT NULL,
|
||||
`slug` varchar(255) DEFAULT NULL,
|
||||
`description` longtext DEFAULT NULL,
|
||||
`main_image` varchar(255) DEFAULT NULL,
|
||||
`state` enum('draft','pending','published','locked','rejected','hidden') NOT NULL DEFAULT 'draft',
|
||||
`staff_comment` text DEFAULT NULL,
|
||||
`rejected_at` timestamp NULL DEFAULT NULL,
|
||||
`featured` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`featured_at` datetime DEFAULT NULL,
|
||||
`game_id` bigint(20) unsigned DEFAULT NULL,
|
||||
`platform_id` bigint(20) unsigned DEFAULT NULL,
|
||||
`status_id` bigint(20) unsigned DEFAULT NULL,
|
||||
`version` varchar(50) DEFAULT NULL,
|
||||
`release_date` date DEFAULT NULL,
|
||||
`staff_credits` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`staff_credits`)),
|
||||
`relevant_link` varchar(500) DEFAULT NULL,
|
||||
`youtube_link` varchar(500) DEFAULT NULL,
|
||||
`user_id` bigint(20) unsigned NOT NULL,
|
||||
`comments_thread_id` bigint(20) unsigned DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
`complete_title` varchar(255) DEFAULT NULL,
|
||||
`deleted_at` timestamp NULL DEFAULT NULL,
|
||||
`level_id` bigint(20) unsigned DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `entries_slug_unique` (`slug`),
|
||||
KEY `entries_game_id_foreign` (`game_id`),
|
||||
KEY `entries_platform_id_foreign` (`platform_id`),
|
||||
KEY `entries_status_id_foreign` (`status_id`),
|
||||
KEY `entries_type_state_game_id_platform_id_status_id_index` (`type`,`state`,`game_id`,`platform_id`,`status_id`),
|
||||
KEY `entries_level_id_foreign` (`level_id`),
|
||||
CONSTRAINT `entries_game_id_foreign` FOREIGN KEY (`game_id`) REFERENCES `games` (`id`) ON DELETE SET NULL,
|
||||
CONSTRAINT `entries_level_id_foreign` FOREIGN KEY (`level_id`) REFERENCES `levels` (`id`) ON DELETE SET NULL,
|
||||
CONSTRAINT `entries_platform_id_foreign` FOREIGN KEY (`platform_id`) REFERENCES `platforms` (`id`) ON DELETE SET NULL,
|
||||
CONSTRAINT `entries_status_id_foreign` FOREIGN KEY (`status_id`) REFERENCES `statuses` (`id`) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `entry_authors`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `entry_authors` (
|
||||
`entry_id` bigint(20) unsigned NOT NULL,
|
||||
`author_id` bigint(20) unsigned NOT NULL,
|
||||
PRIMARY KEY (`entry_id`,`author_id`),
|
||||
KEY `entry_authors_author_id_foreign` (`author_id`),
|
||||
CONSTRAINT `entry_authors_author_id_foreign` FOREIGN KEY (`author_id`) REFERENCES `authors` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `entry_authors_entry_id_foreign` FOREIGN KEY (`entry_id`) REFERENCES `entries` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `entry_categories`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `entry_categories` (
|
||||
`entry_id` bigint(20) unsigned NOT NULL,
|
||||
`category_id` bigint(20) unsigned NOT NULL,
|
||||
PRIMARY KEY (`entry_id`,`category_id`),
|
||||
KEY `entry_categories_category_id_foreign` (`category_id`),
|
||||
CONSTRAINT `entry_categories_category_id_foreign` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `entry_categories_entry_id_foreign` FOREIGN KEY (`entry_id`) REFERENCES `entries` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `entry_files`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `entry_files` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`entry_id` bigint(20) unsigned NOT NULL,
|
||||
`filename` varchar(1024) NOT NULL,
|
||||
`filepath` varchar(1024) NOT NULL,
|
||||
`favorite_server` varchar(11) NOT NULL,
|
||||
`favorite_at` timestamp NOT NULL,
|
||||
`filesize` bigint(20) unsigned DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
`file_uuid` uuid NOT NULL,
|
||||
`state` enum('public','private','archived') NOT NULL DEFAULT 'public',
|
||||
`online_patcher` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`secondary_online_patcher` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`download_count` bigint(20) unsigned NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `entry_files_file_uuid_unique` (`file_uuid`),
|
||||
KEY `entry_files_entry_id_foreign` (`entry_id`),
|
||||
CONSTRAINT `entry_files_entry_id_foreign` FOREIGN KEY (`entry_id`) REFERENCES `entries` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `entry_hashes`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `entry_hashes` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`entry_id` bigint(20) unsigned NOT NULL,
|
||||
`filename` varchar(256) NOT NULL,
|
||||
`hash_crc32` varchar(256) NOT NULL,
|
||||
`hash_sha1` varchar(256) NOT NULL,
|
||||
`verified` varchar(256) NOT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `entry_hashes_entry_id_foreign` (`entry_id`),
|
||||
CONSTRAINT `entry_hashes_entry_id_foreign` FOREIGN KEY (`entry_id`) REFERENCES `entries` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `entry_languages`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `entry_languages` (
|
||||
`entry_id` bigint(20) unsigned NOT NULL,
|
||||
`language_id` bigint(20) unsigned NOT NULL,
|
||||
PRIMARY KEY (`entry_id`,`language_id`),
|
||||
KEY `entry_languages_language_id_foreign` (`language_id`),
|
||||
CONSTRAINT `entry_languages_entry_id_foreign` FOREIGN KEY (`entry_id`) REFERENCES `entries` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `entry_languages_language_id_foreign` FOREIGN KEY (`language_id`) REFERENCES `languages` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `entry_modifications`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `entry_modifications` (
|
||||
`entry_id` bigint(20) unsigned NOT NULL,
|
||||
`modification_id` bigint(20) unsigned NOT NULL,
|
||||
PRIMARY KEY (`entry_id`,`modification_id`),
|
||||
KEY `entry_modifications_modification_id_foreign` (`modification_id`),
|
||||
CONSTRAINT `entry_modifications_entry_id_foreign` FOREIGN KEY (`entry_id`) REFERENCES `entries` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `entry_modifications_modification_id_foreign` FOREIGN KEY (`modification_id`) REFERENCES `modifications` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `entry_reviews`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `entry_reviews` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`entry_id` bigint(20) unsigned NOT NULL,
|
||||
`title` varchar(255) NOT NULL,
|
||||
`rating` int(11) NOT NULL,
|
||||
`description` text NOT NULL,
|
||||
`user_id` bigint(20) unsigned NOT NULL,
|
||||
`deleted_at` timestamp NULL DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `entry_reviews_entry_id_foreign` (`entry_id`),
|
||||
CONSTRAINT `entry_reviews_entry_id_foreign` FOREIGN KEY (`entry_id`) REFERENCES `entries` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `entry_systems`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `entry_systems` (
|
||||
`entry_id` bigint(20) unsigned NOT NULL,
|
||||
`system_id` bigint(20) unsigned NOT NULL,
|
||||
PRIMARY KEY (`entry_id`,`system_id`),
|
||||
KEY `entry_systems_system_id_foreign` (`system_id`),
|
||||
CONSTRAINT `entry_systems_entry_id_foreign` FOREIGN KEY (`entry_id`) REFERENCES `entries` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `entry_systems_system_id_foreign` FOREIGN KEY (`system_id`) REFERENCES `systems` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `failed_jobs`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `failed_jobs` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`uuid` varchar(255) NOT NULL,
|
||||
`connection` text NOT NULL,
|
||||
`queue` text NOT NULL,
|
||||
`payload` longtext NOT NULL,
|
||||
`exception` longtext NOT NULL,
|
||||
`failed_at` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `failed_jobs_uuid_unique` (`uuid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `galleries`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `galleries` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`galleryable_type` varchar(255) NOT NULL DEFAULT 'AppModelsEntry',
|
||||
`galleryable_id` bigint(20) unsigned NOT NULL,
|
||||
`image` varchar(255) NOT NULL,
|
||||
`order` smallint(5) unsigned NOT NULL DEFAULT 0,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `entry_galleries_entry_id_foreign` (`galleryable_id`),
|
||||
KEY `galleries_galleryable_type_galleryable_id_index` (`galleryable_type`,`galleryable_id`),
|
||||
CONSTRAINT `entry_galleries_entry_id_foreign` FOREIGN KEY (`galleryable_id`) REFERENCES `entries` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `games`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `games` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`slug` varchar(255) NOT NULL,
|
||||
`platform_id` bigint(20) unsigned NOT NULL,
|
||||
`genre_id` bigint(20) unsigned NOT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `games_slug_unique` (`slug`),
|
||||
KEY `games_platform_id_foreign` (`platform_id`),
|
||||
KEY `games_genre_id_foreign` (`genre_id`),
|
||||
CONSTRAINT `games_genre_id_foreign` FOREIGN KEY (`genre_id`) REFERENCES `genres` (`id`),
|
||||
CONSTRAINT `games_platform_id_foreign` FOREIGN KEY (`platform_id`) REFERENCES `platforms` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `genres`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `genres` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`slug` varchar(255) NOT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `genres_slug_unique` (`slug`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `job_batches`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `job_batches` (
|
||||
`id` varchar(255) NOT NULL,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`total_jobs` int(11) NOT NULL,
|
||||
`pending_jobs` int(11) NOT NULL,
|
||||
`failed_jobs` int(11) NOT NULL,
|
||||
`failed_job_ids` longtext NOT NULL,
|
||||
`options` mediumtext DEFAULT NULL,
|
||||
`cancelled_at` int(11) DEFAULT NULL,
|
||||
`created_at` int(11) NOT NULL,
|
||||
`finished_at` int(11) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `jobs`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `jobs` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`queue` varchar(255) NOT NULL,
|
||||
`payload` longtext NOT NULL,
|
||||
`attempts` smallint(5) unsigned NOT NULL,
|
||||
`reserved_at` int(10) unsigned DEFAULT NULL,
|
||||
`available_at` int(10) unsigned NOT NULL,
|
||||
`created_at` int(10) unsigned NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `jobs_queue_index` (`queue`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `languages`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `languages` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`slug` varchar(255) NOT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `languages_slug_unique` (`slug`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `levels`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `levels` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`slug` varchar(255) NOT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `levels_slug_unique` (`slug`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `migration_game_plan`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `migration_game_plan` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`wp_game_id` bigint(20) unsigned NOT NULL,
|
||||
`wp_platform_id` bigint(20) unsigned NOT NULL,
|
||||
`game_id` bigint(20) unsigned DEFAULT NULL,
|
||||
`wp_genre_id` bigint(20) unsigned DEFAULT NULL,
|
||||
`post_count` int(10) unsigned NOT NULL DEFAULT 0,
|
||||
`genre_conflict` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `migration_game_plan_wp_game_id_wp_platform_id_unique` (`wp_game_id`,`wp_platform_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `migration_settings`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `migration_settings` (
|
||||
`key` varchar(255) NOT NULL,
|
||||
`value` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL CHECK (json_valid(`value`)),
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`key`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `migration_user_plan`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `migration_user_plan` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`wp_user_id` bigint(20) unsigned DEFAULT NULL,
|
||||
`xf_user_id` bigint(20) unsigned DEFAULT NULL,
|
||||
`match_type` varchar(255) NOT NULL,
|
||||
`email` varchar(255) DEFAULT NULL,
|
||||
`wp_username` varchar(255) DEFAULT NULL,
|
||||
`xf_username` varchar(255) DEFAULT NULL,
|
||||
`note` text DEFAULT NULL,
|
||||
`status` varchar(255) NOT NULL DEFAULT 'pending',
|
||||
`user_id` bigint(20) unsigned DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
`wp_password_bridge` tinyint(1) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `migration_user_plan_match_type_index` (`match_type`),
|
||||
KEY `migration_user_plan_status_index` (`status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `migrations`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `migrations` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`migration` varchar(255) NOT NULL,
|
||||
`batch` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `migrations_logs`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `migrations_logs` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`source_system` varchar(255) NOT NULL,
|
||||
`source_table` varchar(255) NOT NULL,
|
||||
`source_id` bigint(20) unsigned NOT NULL,
|
||||
`target_table` varchar(255) NOT NULL,
|
||||
`target_id` bigint(20) unsigned NOT NULL,
|
||||
`status` varchar(255) NOT NULL DEFAULT 'pending',
|
||||
`migrated_at` datetime DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `modifications`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `modifications` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`slug` varchar(255) NOT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `news`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `news` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`title` varchar(255) NOT NULL,
|
||||
`slug` varchar(255) NOT NULL,
|
||||
`category_id` bigint(20) unsigned DEFAULT NULL,
|
||||
`description` longtext NOT NULL,
|
||||
`state` enum('draft','pending','published','locked','rejected','hidden') NOT NULL DEFAULT 'draft',
|
||||
`staff_comment` text DEFAULT NULL,
|
||||
`rejected_at` timestamp NULL DEFAULT NULL,
|
||||
`entry_id` bigint(20) unsigned DEFAULT NULL,
|
||||
`relevant_link` varchar(500) DEFAULT NULL,
|
||||
`youtube_link` varchar(500) DEFAULT NULL,
|
||||
`user_id` bigint(20) unsigned NOT NULL,
|
||||
`comments_thread_id` bigint(20) unsigned DEFAULT NULL,
|
||||
`deleted_at` timestamp NULL DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `news_slug_unique` (`slug`),
|
||||
KEY `news_category_id_foreign` (`category_id`),
|
||||
KEY `news_entry_id_foreign` (`entry_id`),
|
||||
CONSTRAINT `news_category_id_foreign` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`) ON DELETE SET NULL,
|
||||
CONSTRAINT `news_entry_id_foreign` FOREIGN KEY (`entry_id`) REFERENCES `entries` (`id`) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `password_reset_tokens`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `password_reset_tokens` (
|
||||
`email` varchar(255) NOT NULL,
|
||||
`token` varchar(255) NOT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`email`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `platforms`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `platforms` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(100) NOT NULL,
|
||||
`slug` varchar(100) NOT NULL,
|
||||
`short_name` varchar(30) DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
`play_online_core` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `platforms_slug_unique` (`slug`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `play_online_settings`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `play_online_settings` (
|
||||
`file_id` bigint(20) unsigned NOT NULL,
|
||||
`core` varchar(30) NOT NULL,
|
||||
`threads` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`file_id`),
|
||||
CONSTRAINT `play_online_settings_file_id_foreign` FOREIGN KEY (`file_id`) REFERENCES `entry_files` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `sessions`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `sessions` (
|
||||
`id` varchar(255) NOT NULL,
|
||||
`user_id` bigint(20) unsigned DEFAULT NULL,
|
||||
`ip_address` varchar(45) DEFAULT NULL,
|
||||
`user_agent` text DEFAULT NULL,
|
||||
`payload` longtext NOT NULL,
|
||||
`last_activity` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `sessions_user_id_index` (`user_id`),
|
||||
KEY `sessions_last_activity_index` (`last_activity`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `statuses`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `statuses` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`slug` varchar(255) NOT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `status_slug_unique` (`slug`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `systems`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `systems` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`slug` varchar(255) NOT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `systems_slug_unique` (`slug`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `users`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `users` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`email` varchar(255) NOT NULL,
|
||||
`email_verified_at` timestamp NULL DEFAULT NULL,
|
||||
`password` varchar(255) NOT NULL,
|
||||
`remember_token` varchar(100) DEFAULT NULL,
|
||||
`created_at` timestamp NULL DEFAULT NULL,
|
||||
`updated_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `users_email_unique` (`email`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
||||
|
||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
||||
/*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */;
|
||||
|
||||
/*M!999999\- enable the sandbox mode */
|
||||
SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0;
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (1,'0001_01_01_000000_create_users_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (2,'0001_01_01_000001_create_cache_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (3,'0001_01_01_000002_create_jobs_table',1);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (4,'2026_05_09_153326_create_platforms_table',2);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (5,'2026_05_09_153901_add_platform_timestamp',3);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (6,'2026_05_10_071323_create_genres_table',4);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (7,'2026_05_10_071400_create_games_table',5);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (8,'2026_05_10_072139_create_languages_table',6);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (9,'2026_05_10_072201_create_authors_table',6);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (10,'2026_05_10_072332_create_modifications_table',6);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (11,'2026_05_10_072441_create_status_table',6);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (12,'2026_05_10_072747_create_entries_table',7);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (13,'2026_05_10_074735_create_entry_authors_table',8);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (14,'2026_05_10_074830_create_entry_languages_table',8);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (15,'2026_05_10_074907_create_entry_modifications_table',8);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (16,'2026_05_12_114815_create_entry_files_table',9);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (19,'2026_05_12_115134_create_entry_hashes_table',10);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (20,'2026_05_13_084522_add_fields_to_entry_files',11);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (22,'2026_05_16_134002_create_entry_gallery_table',12);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (23,'2026_05_18_131712_change_staff_credits_field',13);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (24,'2026_05_19_090838_add_complete_title_to_entry',14);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (25,'2026_05_27_192635_add_fields_for_queue_to_entries',15);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (26,'2026_05_27_193235_add_rejected_state_to_entries',16);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (27,'2026_06_04_083346_make_entries_fields_draft_compatible',17);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (35,'2026_06_05_163235_add_online_patcher_fields_to_files',18);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (36,'2026_06_09_122425_create_category_table',18);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (37,'2026_06_09_122655_create_os_table',18);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (38,'2026_06_09_122817_create_level_table',18);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (39,'2026_06_09_123242_add_entry_level_id_field',18);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (40,'2026_06_09_123458_create_entry_systems_table',18);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (41,'2026_06_09_123533_create_entry_categories_table',18);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (42,'2026_06_09_124832_add_restricted_field_to_categories',19);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (43,'2026_06_10_084936_make_entry_galleries_polymorphic',20);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (44,'2026_06_10_090320_create_news_table',21);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (45,'2026_06_10_091105_add_fields_for_queue_to_news',22);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (46,'2026_06_11_155053_add_order_to_galleries_table',23);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (47,'2026_06_13_210606_add_featured_at_field_to_entries',24);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (48,'2026_06_14_163648_create_play_online_settings_table',25);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (49,'2026_06_14_174906_add_default_core_play_online_for_platforms',26);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (50,'2026_06_16_100941_create_activity_log_table',27);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (51,'2026_06_16_122812_add_download_field_to_entry_files',28);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (53,'2026_06_17_114641_create_reviews_table',29);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (54,'2026_06_18_084700_create_migration_user_plan_table',30);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (55,'2026_06_19_080416_create_migration_settings_table',31);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (56,'2026_06_19_125237_create_migrations_logs_table',32);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (57,'2026_06_19_134939_alter_migration_user_plan_table',33);
|
||||
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (59,'2026_06_21_085615_create_migration_game_plan_table',34);
|
||||
COMMIT;
|
||||
SET AUTOCOMMIT=@OLD_AUTOCOMMIT;
|
||||
14
extra.less
14
extra.less
@@ -71,6 +71,9 @@ ul {
|
||||
/* Menu settings */
|
||||
--menu-size: 260px;
|
||||
--menu-user-avatar-bg: #555;
|
||||
|
||||
/* Gap */
|
||||
--gap: 15px;
|
||||
}
|
||||
|
||||
.\$light-mode {
|
||||
@@ -132,6 +135,7 @@ ul {
|
||||
background-color: var(--bg2);
|
||||
border: 1px solid var(--border);
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
flex-direction: column;
|
||||
transition: transform 0.2s, border-color 0.2s;
|
||||
cursor: pointer;
|
||||
@@ -144,6 +148,7 @@ ul {
|
||||
.\$entry-cover-wrapper {
|
||||
position: relative;
|
||||
aspect-ratio: 4/3;
|
||||
min-width: 0;
|
||||
background-color: var(--bg);
|
||||
border-bottom: 1px solid var(--border);
|
||||
display: flex;
|
||||
@@ -183,6 +188,7 @@ ul {
|
||||
font-size: 1.1rem;
|
||||
margin-bottom: 5px;
|
||||
line-height: 1.3;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.\$entry-card-author {
|
||||
@@ -5277,6 +5283,14 @@ ul {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
.\$menu-user-info {
|
||||
display: flex;
|
||||
|
||||
24
origin_ca_rsa_root.pem
Normal file
24
origin_ca_rsa_root.pem
Normal file
@@ -0,0 +1,24 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEADCCAuigAwIBAgIID+rOSdTGfGcwDQYJKoZIhvcNAQELBQAwgYsxCzAJBgNV
|
||||
BAYTAlVTMRkwFwYDVQQKExBDbG91ZEZsYXJlLCBJbmMuMTQwMgYDVQQLEytDbG91
|
||||
ZEZsYXJlIE9yaWdpbiBTU0wgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MRYwFAYDVQQH
|
||||
Ew1TYW4gRnJhbmNpc2NvMRMwEQYDVQQIEwpDYWxpZm9ybmlhMB4XDTE5MDgyMzIx
|
||||
MDgwMFoXDTI5MDgxNTE3MDAwMFowgYsxCzAJBgNVBAYTAlVTMRkwFwYDVQQKExBD
|
||||
bG91ZEZsYXJlLCBJbmMuMTQwMgYDVQQLEytDbG91ZEZsYXJlIE9yaWdpbiBTU0wg
|
||||
Q2VydGlmaWNhdGUgQXV0aG9yaXR5MRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRMw
|
||||
EQYDVQQIEwpDYWxpZm9ybmlhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
|
||||
AQEAwEiVZ/UoQpHmFsHvk5isBxRehukP8DG9JhFev3WZtG76WoTthvLJFRKFCHXm
|
||||
V6Z5/66Z4S09mgsUuFwvJzMnE6Ej6yIsYNCb9r9QORa8BdhrkNn6kdTly3mdnykb
|
||||
OomnwbUfLlExVgNdlP0XoRoeMwbQ4598foiHblO2B/LKuNfJzAMfS7oZe34b+vLB
|
||||
yrP/1bgCSLdc1AxQc1AC0EsQQhgcyTJNgnG4va1c7ogPlwKyhbDyZ4e59N5lbYPJ
|
||||
SmXI/cAe3jXj1FBLJZkwnoDKe0v13xeF+nF32smSH0qB7aJX2tBMW4TWtFPmzs5I
|
||||
lwrFSySWAdwYdgxw180yKU0dvwIDAQABo2YwZDAOBgNVHQ8BAf8EBAMCAQYwEgYD
|
||||
VR0TAQH/BAgwBgEB/wIBAjAdBgNVHQ4EFgQUJOhTV118NECHqeuU27rhFnj8KaQw
|
||||
HwYDVR0jBBgwFoAUJOhTV118NECHqeuU27rhFnj8KaQwDQYJKoZIhvcNAQELBQAD
|
||||
ggEBAHwOf9Ur1l0Ar5vFE6PNrZWrDfQIMyEfdgSKofCdTckbqXNTiXdgbHs+TWoQ
|
||||
wAB0pfJDAHJDXOTCWRyTeXOseeOi5Btj5CnEuw3P0oXqdqevM1/+uWp0CM35zgZ8
|
||||
VD4aITxity0djzE6Qnx3Syzz+ZkoBgTnNum7d9A66/V636x4vTeqbZFBr9erJzgz
|
||||
hhurjcoacvRNhnjtDRM0dPeiCJ50CP3wEYuvUzDHUaowOsnLCjQIkWbR7Ni6KEIk
|
||||
MOz2U0OBSif3FTkhCgZWQKOOLo1P42jHC3ssUZAtVNXrCk3fw9/E15k8NPkBazZ6
|
||||
0iykLhH1trywrKRMVw67F44IE8Y=
|
||||
-----END CERTIFICATE-----
|
||||
@@ -94,21 +94,36 @@
|
||||
color: var(--text3);
|
||||
border-color: var(--rhpz-orange);
|
||||
}
|
||||
.badge.blue, .badge.translations {
|
||||
.badge.blue, .badge.romhacks {
|
||||
background-color: var(--info);
|
||||
color: var(--text);
|
||||
border-color: var(--info);
|
||||
}
|
||||
.badge.green, .badge.romhacks {
|
||||
.badge.green, .badge.translations {
|
||||
background-color: var(--success2);
|
||||
color: var(--text);
|
||||
border-color: var(--success2);
|
||||
}
|
||||
.badge.red, .badge.homebrew {
|
||||
background-color: #bf2323;
|
||||
color: var(--text);
|
||||
border-color: #bf2323;
|
||||
}
|
||||
.badge.yellow, .badge.utilities {
|
||||
background-color: #fdeb0f;
|
||||
color: #000;
|
||||
border-color: #fdeb0f;
|
||||
}
|
||||
.badge.purple, .badge.documents{
|
||||
background-color: #8b23bf;
|
||||
color: var(--text);
|
||||
border-color: #8b23bf;
|
||||
}
|
||||
.badge.brown, .badge.lua-scripts {
|
||||
background-color: #b4825f;
|
||||
color: var(--text);
|
||||
border-color: #b4825f;
|
||||
}
|
||||
|
||||
.topbar-badge {
|
||||
position: absolute;
|
||||
|
||||
@@ -220,6 +220,9 @@
|
||||
overflow: hidden;
|
||||
background-color: var(--bg4);
|
||||
border: 1px solid var(--border);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
|
||||
@@ -115,6 +115,14 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
.menu-user-info {
|
||||
display: flex;
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
</div>
|
||||
<div style="margin-bottom:10px">
|
||||
<span class="badge {{ $entry->type }}">{{ \App\View\Components\EntryCard::ENTRY_TYPES_BADGE[$entry->type] ?? $entry->type }}</span>
|
||||
@if( section_must_be('romhacks', $entry->type ) )
|
||||
@if( section_must_be(['romhacks', 'lua-scripts'], $entry->type ) )
|
||||
@foreach( $entry->modifications as $modif )
|
||||
<span class="badge orange">{{ $modif->name }}</span>
|
||||
@endforeach
|
||||
@@ -28,7 +28,7 @@
|
||||
@foreach( $entry->languages as $lang )
|
||||
<span class="badge orange">{{ $lang->name }}</span>
|
||||
@endforeach
|
||||
@elseif( section_must_be( 'utilities', $entry->type ) )
|
||||
@elseif( section_must_be( ['utilities', 'documents'], $entry->type ) )
|
||||
@foreach( $entry->categories as $category )
|
||||
<span class="badge orange">{{ $category->name }}</span>
|
||||
@endforeach
|
||||
@@ -46,7 +46,7 @@
|
||||
@endif
|
||||
</div>
|
||||
<div class="entry-card-meta">
|
||||
<span><i data-lucide="download" size="12"></i> x</span>
|
||||
<span><i data-lucide="download" size="12"></i> {{ $entry->total_downloads ?? 0 }}</span>
|
||||
<span>Added: {{ $entry->created_at->format('y-m-d') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
<x-form-field-title name="Screenshots" helper="At least 1 Screenshot required, Maximum 20." required="{{ $required ? 'true' : 'false' }}" />
|
||||
<div class="form-group main-image-grid">
|
||||
<div class="form-upload" style="flex:1;" :class="{ 'disabled': isFull }">
|
||||
<input type="file" id="gallery-field" accept="image/png, image/jpeg, image/webp" multiple :disabled="isFull" @change="handleSubmitFiles($event)">
|
||||
<input type="file" id="gallery-field" accept="image/png, image/jpeg, image/webp, image/gif" multiple :disabled="isFull" @change="handleSubmitFiles($event)">
|
||||
<div class="form-upload-placeholder level">
|
||||
<i data-lucide="file-archive" size="36" style="margin-bottom:15px;color:var(--text2)"></i>
|
||||
<div style="font-size: 1.1rem;color:var(--text);margin-bottom:5px;">
|
||||
Click or drag'n drop files here.
|
||||
</div>
|
||||
<div style="font-size:0.85rem;color:var(--text2);">
|
||||
Accepted: PNG, JPG or WebP
|
||||
Accepted: PNG, JPG, GIF or WebP
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
<x-form-field-title name="Main image" helper="This will show up on the index and on top of the entry. A screenshot or custom cover is prefered else all entries of same game will look the same." required="{{ $required ? 'true' : 'false' }}" />
|
||||
<div class="form-group main-image-grid">
|
||||
<div class="form-upload" style="flex:4;">
|
||||
<input type="file" id="main-image-field" accept="image/png, image/jpeg, image/webp" @change="handleSubmitFile($event)">
|
||||
<input type="file" id="main-image-field" accept="image/png, image/jpeg, image/webp, image/gif" @change="handleSubmitFile($event)">
|
||||
<div class="form-upload-placeholder level">
|
||||
<i data-lucide="file-archive" size="36" style="margin-bottom:15px;color:var(--text2)"></i>
|
||||
<div style="font-size: 1.1rem;color:var(--text);margin-bottom:5px;">
|
||||
Click or drag'n drop files here.
|
||||
</div>
|
||||
<div style="font-size:0.85rem;color:var(--text2);">
|
||||
Accepted: PNG, JPG or WebP
|
||||
Accepted: PNG, JPG, GIF or WebP
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" name="main-image" x-model="serverFilePath">
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<div class="comment-block">
|
||||
<x-xen-foro-avatar :user="$review->user_id" />
|
||||
<div class="comment-avatar">
|
||||
<x-xen-foro-avatar :user="$review->user_id" />
|
||||
</div>
|
||||
|
||||
<div class="comment-content">
|
||||
<div class="comment-meta">
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
</div>
|
||||
@endif
|
||||
<div>
|
||||
@if( section_must_be( [ 'romhacks', 'homebrew' ], $section ) && !$isEdit )
|
||||
@if( section_must_be( [ 'romhacks', 'homebrew' ], $section ) && !$isEdit && $VISITOR->nsfw_content === 1 )
|
||||
<label class="nsfw-label"><input id="nsfw-checkbox" type="checkbox" name="nsfw-entry" x-model="nsfw" style="transform: scale(1.5)"> NSFW</label>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@@ -42,7 +42,9 @@
|
||||
@continue
|
||||
@else
|
||||
<div class="comment-block">
|
||||
<div class="comment-avatar">
|
||||
<x-xen-foro-avatar :user="$comment['user_id']" />
|
||||
</div>
|
||||
|
||||
<div class="comment-content">
|
||||
<div class="comment-meta">
|
||||
|
||||
@@ -122,6 +122,9 @@
|
||||
<x-entry-meta-item label="Release Date" value="{{ $entry->release_date->format('Y-m-d') }}"
|
||||
route="none"/>
|
||||
@endif
|
||||
@if( $entry->total_downloads )
|
||||
<x-entry-meta-item label="Downloads" value="{{ $entry->total_downloads }}" route="none" />
|
||||
@endif
|
||||
</div>
|
||||
<div class="hack-actions" style="display:flex;gap:10px;">
|
||||
@if($entry->state === 'pending')
|
||||
|
||||
6
resources/views/errors/403.blade.php
Normal file
6
resources/views/errors/403.blade.php
Normal file
@@ -0,0 +1,6 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<x-error-block error-type="page-not-allowed" message="Unknown" />
|
||||
<a class="btn" href="javascript:history.go(-1)">Go back to the previous page</a>
|
||||
@endsection
|
||||
6
resources/views/errors/404.blade.php
Normal file
6
resources/views/errors/404.blade.php
Normal file
@@ -0,0 +1,6 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<x-error-block error-type="not-found" />
|
||||
<a class="btn" href="javascript:history.go(-1)">Go back to the previous page</a>
|
||||
@endsection
|
||||
6
resources/views/errors/4xx.blade.php
Normal file
6
resources/views/errors/4xx.blade.php
Normal file
@@ -0,0 +1,6 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<x-error-block error-type="custom" message="{{ $exception->getMessage() }}" />
|
||||
<a class="btn" href="javascript:history.go(-1)">Go back to the previous page</a>
|
||||
@endsection
|
||||
305
resources/views/errors/500.blade.php
Normal file
305
resources/views/errors/500.blade.php
Normal file
@@ -0,0 +1,305 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>500 - Internal server error - Romhack Plaza</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<style>
|
||||
|
||||
:root {
|
||||
|
||||
/* RHPZ color */
|
||||
--rhpz-orange: #ff7300;
|
||||
--rhpz-orange-hover: #e56700;
|
||||
|
||||
/* Background colors */
|
||||
--bg: #1e1e1e;
|
||||
--bg2: #252526;
|
||||
--bg3: #2d2d30;
|
||||
--bg4: #3e3e42;
|
||||
|
||||
/* Text */
|
||||
--text: #f1f1f1;
|
||||
--text2: #a1a1aa;
|
||||
--text3: #111111;
|
||||
|
||||
/* Elements */
|
||||
--border: #3f3f46;
|
||||
--error: #e57373;
|
||||
--info: #1976d2;
|
||||
--success: #81c784;
|
||||
--success2: #388e3c;
|
||||
|
||||
/* Typo */
|
||||
--typography: 'Segoe UI', 'San Francisco', 'Helvetica Neue', sans-serif;
|
||||
|
||||
/* Menu settings */
|
||||
--menu-size: 260px;
|
||||
--menu-user-avatar-bg: #555;
|
||||
|
||||
/* Gap */
|
||||
--gap: 15px;
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: var(--typography);
|
||||
background-color: var(--bg);
|
||||
color: var(--text);
|
||||
display: flex;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--rhpz-orange);
|
||||
text-decoration: none;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: var(--rhpz-orange-hover);
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#app {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin-left: 20px;
|
||||
margin-bottom: 20px;
|
||||
list-style-type: square;
|
||||
}
|
||||
|
||||
[x-cloak] {display: none !important;}
|
||||
|
||||
|
||||
/* BUTTONS */
|
||||
|
||||
.btn {
|
||||
background-color: var(--bg3);
|
||||
border: 1px solid var(--border);
|
||||
color: var(--text);
|
||||
padding: 8px 16px;
|
||||
font-size: 0.9rem;
|
||||
cursor: pointer;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
transition: all 0.1s;
|
||||
}
|
||||
.btn:hover {
|
||||
background-color: var(--bg4);
|
||||
border-color: var(--menu-user-avatar-bg);
|
||||
}
|
||||
.btn.primary {
|
||||
background-color: var(--rhpz-orange);
|
||||
color: var(--text3);
|
||||
border-color: var(--rhpz-orange);
|
||||
font-weight: 600;
|
||||
}
|
||||
.btn.primary:hover {
|
||||
background-color: var(--rhpz-orange-hover);
|
||||
border-color: var(--rhpz-orange-hover);
|
||||
}
|
||||
.btn.danger {
|
||||
background-color: transparent;
|
||||
color: var(--error);
|
||||
border-color: var(--error);
|
||||
}
|
||||
.btn.danger:hover {
|
||||
background-color: rgba(229, 115, 115, 0.1);
|
||||
}
|
||||
.btn.success {
|
||||
background-color: transparent;
|
||||
color: var(--success);
|
||||
border-color: var(--success);
|
||||
}
|
||||
.btn.success:hover {
|
||||
background-color: rgba(129, 199, 132, 0.1);
|
||||
}
|
||||
|
||||
/* BLOCK */
|
||||
|
||||
.block {
|
||||
background-color: var(--bg2);
|
||||
border: 1px solid var(--border);
|
||||
padding: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.block.featured {
|
||||
border-left: 3px solid var(--rhpz-orange);
|
||||
}
|
||||
.block-header {
|
||||
font-size: 1.2rem;
|
||||
color: var(--text);
|
||||
margin-bottom: 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
.block-success {
|
||||
background-color: var(--success);
|
||||
border: 1px solid var(--success);
|
||||
color: var(--text);
|
||||
padding: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.block-error {
|
||||
background-color: var(--error);
|
||||
border: 1px solid var(--error);
|
||||
color: var(--text);
|
||||
padding: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
/* PAGE */
|
||||
|
||||
.page-title {
|
||||
font-size: 1.8rem;
|
||||
font-weight: 300;
|
||||
margin-bottom: 20px;
|
||||
color: var(--text);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* TEXTS */
|
||||
|
||||
.whisper {
|
||||
color: var(--text2);
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.content-title {
|
||||
color: var(--text);
|
||||
margin: 30px 0 15px 0;
|
||||
border-left: 3px solid var(--rhpz-orange);
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.quote {
|
||||
background-color: var(--bg);
|
||||
border-left: 4px solid #1976d2;
|
||||
padding: 15px;
|
||||
margin-top: 30px;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.btn {
|
||||
padding: 7px 12px;
|
||||
font-size: 0.85rem;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.block {
|
||||
padding: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.block-header {
|
||||
font-size: 1.05rem;
|
||||
margin-bottom: 12px;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 1.5rem;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.content-title {
|
||||
margin: 20px 0 12px 0;
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
.quote {
|
||||
padding: 12px;
|
||||
margin-top: 20px;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.whisper {
|
||||
margin-bottom: 12px;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.breadcrumb {
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.btn {
|
||||
padding: 6px 10px;
|
||||
font-size: 0.8rem;
|
||||
gap: 4px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.btn.primary, .btn.danger, .btn.success {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.block {
|
||||
padding: 12px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.block-header {
|
||||
font-size: 0.95rem;
|
||||
margin-bottom: 10px;
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 1.2rem;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.badge {
|
||||
padding: 2px 6px;
|
||||
font-size: 0.7rem;
|
||||
}
|
||||
|
||||
.topbar-badge {
|
||||
min-width: 16px;
|
||||
height: 16px;
|
||||
padding: 0 3px;
|
||||
font-size: 0.6rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app" style="display:flex;flex-direction: column;align-items: center;justify-content: center;">
|
||||
<main id="main-wrapper">
|
||||
<main id="content">
|
||||
<div class="block">
|
||||
<div class="page-title">500 - Internal server error</div>
|
||||
<p>To resolve the issue quickly, please report it on Gitea, Discord, or the forum with the following information.</p>
|
||||
<ul>
|
||||
<li>Your error code: {{ $errorId ?? "" }}</li>
|
||||
<li>What you were doing before the error occurred.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<a href="https://code.romhackplaza.org/RHPZAdmin/RomhackPlaza/issues" class="btn primary">Report the problem on Gitea</a>
|
||||
<a href="https://community.romhackplaza.org/forums/bug-reports.6/" class="btn primary">Report the problem on the forum</a>
|
||||
<a href="https://community.romhackplaza.org/misc/contact/" class="btn">Report the problem with the contact form</a>
|
||||
<a href="https://discord.gg/5CKzeWmZZU" class="btn">Report the problem on Discord</a>
|
||||
</div>
|
||||
</main>
|
||||
</main>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -4,8 +4,6 @@
|
||||
|
||||
@section('content')
|
||||
|
||||
{{ dd( $VISITOR ) }}
|
||||
|
||||
@include('activity.latest-news')
|
||||
@include('activity.featured-entries')
|
||||
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
{!! SEO::generate() !!}
|
||||
@include('meta')
|
||||
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
||||
@livewireStyles
|
||||
@stack('styles')
|
||||
<title>@yield('page-title', 'Romhack Plaza')</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
@if(session('error'))
|
||||
<x-error-block error-type="custom" :message="session('error')" />
|
||||
@endif
|
||||
@if(isset($errors) && $errors->has('maintenance'))
|
||||
<x-error-block error-type="custom" :message="$errors->get('maintenance')[0]" />
|
||||
@endif
|
||||
@yield('content')
|
||||
</div>
|
||||
</main>
|
||||
|
||||
@@ -16,8 +16,11 @@
|
||||
|
||||
@foreach( $menu['items'] as $item )
|
||||
@if( !isset( $item['requires_auth'] ) || $item['requires_auth'] === true && $VISITOR->loggedIn() )
|
||||
<a href="{{ isset($item['xf_route']) ? xfRoute($item['xf_route']) : route($item['route']) }}"
|
||||
@class(['menu-item', 'active' => request()->routeIs( $item['route'] ?? '' )]) >
|
||||
<a href="{{ isset($item['xf_route']) ? xfRoute($item['xf_route']) : $item['custom_route'] ?? route($item['route']) }}"
|
||||
@class(['menu-item', 'active' => request()->routeIs( $item['route'] ?? '' )])
|
||||
style="{{ isset( $item['color'] ) ? 'color:' . $item['color'] . ';' : '' }}"
|
||||
{{ isset( $item['custom_route'] ) ? 'target="_blank"' : '' }}
|
||||
>
|
||||
<i data-lucide="{{ $item['icon'] }}"></i><span>{{ $item['name'] }}</span>
|
||||
</a>
|
||||
@endif
|
||||
|
||||
@@ -27,10 +27,12 @@
|
||||
|
||||
<div class="modcp-nav-group">
|
||||
<span class="modcp-nav-label">Content</span>
|
||||
<a href="{{ route('modcp.locked') }}" class="modcp-nav-item" {{ request()->routeIs('modcp.locked') ? 'active' : '' }}>
|
||||
<i data-lucide="lock" size="15"></i>
|
||||
Locked entries
|
||||
</a>
|
||||
@can('moderate','\App\Models\Entry')
|
||||
<a href="{{ route('modcp.locked') }}" class="modcp-nav-item" {{ request()->routeIs('modcp.locked') ? 'active' : '' }}>
|
||||
<i data-lucide="lock" size="15"></i>
|
||||
Locked entries
|
||||
</a>
|
||||
@endcan
|
||||
@can('is-admin')
|
||||
<a href="{{ route('modcp.draft') }}" class="modcp-nav-item" {{ request()->routeIs('modcp.draft') ? 'active' : '' }}>
|
||||
<i data-lucide="scissors" size="15"></i>
|
||||
@@ -74,6 +76,14 @@
|
||||
<i data-lucide="box" size="15"></i>
|
||||
Genres
|
||||
</a>
|
||||
<a href="{{ route('modcp.levels.index') }}" class="modcp-nav-item" {{ request()->routeIs('modcp.levels.*') ? 'active' : '' }}">
|
||||
<i data-lucide="weight" size="15"></i>
|
||||
Levels
|
||||
</a>
|
||||
<a href="{{ route('modcp.modifications.index') }}" class="modcp-nav-item" {{ request()->routeIs('modcp.modifications.*') ? 'active' : '' }}">
|
||||
<i data-lucide="pencil-ruler" size="15"></i>
|
||||
Modifications
|
||||
</a>
|
||||
@endcan
|
||||
</div>
|
||||
|
||||
|
||||
@@ -203,7 +203,7 @@
|
||||
</div>
|
||||
|
||||
<div class="log-pagination">
|
||||
{{ $logs->links() }}
|
||||
{{ $logs->links('modcp.pagination') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
|
||||
299
resources/views/maintenance.blade.php
Normal file
299
resources/views/maintenance.blade.php
Normal file
@@ -0,0 +1,299 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>500 - Internal server error - Romhack Plaza</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<style>
|
||||
|
||||
:root {
|
||||
|
||||
/* RHPZ color */
|
||||
--rhpz-orange: #ff7300;
|
||||
--rhpz-orange-hover: #e56700;
|
||||
|
||||
/* Background colors */
|
||||
--bg: #1e1e1e;
|
||||
--bg2: #252526;
|
||||
--bg3: #2d2d30;
|
||||
--bg4: #3e3e42;
|
||||
|
||||
/* Text */
|
||||
--text: #f1f1f1;
|
||||
--text2: #a1a1aa;
|
||||
--text3: #111111;
|
||||
|
||||
/* Elements */
|
||||
--border: #3f3f46;
|
||||
--error: #e57373;
|
||||
--info: #1976d2;
|
||||
--success: #81c784;
|
||||
--success2: #388e3c;
|
||||
|
||||
/* Typo */
|
||||
--typography: 'Segoe UI', 'San Francisco', 'Helvetica Neue', sans-serif;
|
||||
|
||||
/* Menu settings */
|
||||
--menu-size: 260px;
|
||||
--menu-user-avatar-bg: #555;
|
||||
|
||||
/* Gap */
|
||||
--gap: 15px;
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: var(--typography);
|
||||
background-color: var(--bg);
|
||||
color: var(--text);
|
||||
display: flex;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--rhpz-orange);
|
||||
text-decoration: none;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: var(--rhpz-orange-hover);
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#app {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin-left: 20px;
|
||||
margin-bottom: 20px;
|
||||
list-style-type: square;
|
||||
}
|
||||
|
||||
[x-cloak] {display: none !important;}
|
||||
|
||||
|
||||
/* BUTTONS */
|
||||
|
||||
.btn {
|
||||
background-color: var(--bg3);
|
||||
border: 1px solid var(--border);
|
||||
color: var(--text);
|
||||
padding: 8px 16px;
|
||||
font-size: 0.9rem;
|
||||
cursor: pointer;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
transition: all 0.1s;
|
||||
}
|
||||
.btn:hover {
|
||||
background-color: var(--bg4);
|
||||
border-color: var(--menu-user-avatar-bg);
|
||||
}
|
||||
.btn.primary {
|
||||
background-color: var(--rhpz-orange);
|
||||
color: var(--text3);
|
||||
border-color: var(--rhpz-orange);
|
||||
font-weight: 600;
|
||||
}
|
||||
.btn.primary:hover {
|
||||
background-color: var(--rhpz-orange-hover);
|
||||
border-color: var(--rhpz-orange-hover);
|
||||
}
|
||||
.btn.danger {
|
||||
background-color: transparent;
|
||||
color: var(--error);
|
||||
border-color: var(--error);
|
||||
}
|
||||
.btn.danger:hover {
|
||||
background-color: rgba(229, 115, 115, 0.1);
|
||||
}
|
||||
.btn.success {
|
||||
background-color: transparent;
|
||||
color: var(--success);
|
||||
border-color: var(--success);
|
||||
}
|
||||
.btn.success:hover {
|
||||
background-color: rgba(129, 199, 132, 0.1);
|
||||
}
|
||||
|
||||
/* BLOCK */
|
||||
|
||||
.block {
|
||||
background-color: var(--bg2);
|
||||
border: 1px solid var(--border);
|
||||
padding: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.block.featured {
|
||||
border-left: 3px solid var(--rhpz-orange);
|
||||
}
|
||||
.block-header {
|
||||
font-size: 1.2rem;
|
||||
color: var(--text);
|
||||
margin-bottom: 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
.block-success {
|
||||
background-color: var(--success);
|
||||
border: 1px solid var(--success);
|
||||
color: var(--text);
|
||||
padding: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.block-error {
|
||||
background-color: var(--error);
|
||||
border: 1px solid var(--error);
|
||||
color: var(--text);
|
||||
padding: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
/* PAGE */
|
||||
|
||||
.page-title {
|
||||
font-size: 1.8rem;
|
||||
font-weight: 300;
|
||||
margin-bottom: 20px;
|
||||
color: var(--text);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* TEXTS */
|
||||
|
||||
.whisper {
|
||||
color: var(--text2);
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.content-title {
|
||||
color: var(--text);
|
||||
margin: 30px 0 15px 0;
|
||||
border-left: 3px solid var(--rhpz-orange);
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.quote {
|
||||
background-color: var(--bg);
|
||||
border-left: 4px solid #1976d2;
|
||||
padding: 15px;
|
||||
margin-top: 30px;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.btn {
|
||||
padding: 7px 12px;
|
||||
font-size: 0.85rem;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.block {
|
||||
padding: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.block-header {
|
||||
font-size: 1.05rem;
|
||||
margin-bottom: 12px;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 1.5rem;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.content-title {
|
||||
margin: 20px 0 12px 0;
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
.quote {
|
||||
padding: 12px;
|
||||
margin-top: 20px;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.whisper {
|
||||
margin-bottom: 12px;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.breadcrumb {
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.btn {
|
||||
padding: 6px 10px;
|
||||
font-size: 0.8rem;
|
||||
gap: 4px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.btn.primary, .btn.danger, .btn.success {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.block {
|
||||
padding: 12px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.block-header {
|
||||
font-size: 0.95rem;
|
||||
margin-bottom: 10px;
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 1.2rem;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.badge {
|
||||
padding: 2px 6px;
|
||||
font-size: 0.7rem;
|
||||
}
|
||||
|
||||
.topbar-badge {
|
||||
min-width: 16px;
|
||||
height: 16px;
|
||||
padding: 0 3px;
|
||||
font-size: 0.6rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app" style="display:flex;flex-direction: column;align-items: center;justify-content: center;">
|
||||
<main id="main-wrapper">
|
||||
<main id="content">
|
||||
<div class="block">
|
||||
<div class="page-title">Maintenance is in progress.</div>
|
||||
<p>Please wait until maintenance is complete. Follow the Discord server or the forum if this is unscheduled maintenance.</p>
|
||||
</div>
|
||||
<div>
|
||||
<a href="https://community.romhackplaza.org/" class="btn primary">Go to the forum</a>
|
||||
<a href="https://discord.gg/5CKzeWmZZU" class="btn">Go to Discord</a>
|
||||
</div>
|
||||
</main>
|
||||
</main>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -84,6 +84,6 @@
|
||||
@endforelse
|
||||
</div>
|
||||
|
||||
{{ $items->links() }}
|
||||
{{ $items->links('modcp.pagination') }}
|
||||
|
||||
@endsection
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
{{ $entries->links() }}
|
||||
{{ $entries->links('modcp.pagination') }}
|
||||
@endif
|
||||
|
||||
@endsection
|
||||
|
||||
@@ -47,6 +47,6 @@
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
{{ $entries->links() }}
|
||||
{{ $entries->links( 'modcp.pagination' ) }}
|
||||
@endif
|
||||
@endsection
|
||||
|
||||
@@ -98,6 +98,6 @@
|
||||
@endforelse
|
||||
</div>
|
||||
|
||||
{{ $items->links() }}
|
||||
{{ $items->links('modcp.pagination') }}
|
||||
|
||||
@endsection
|
||||
|
||||
@@ -14,13 +14,15 @@
|
||||
<span class="modcp-stat-label">In queue</span>
|
||||
</div>
|
||||
</a>
|
||||
<a href="{{ route('modcp.locked') }}" class="modcp-stat-card">
|
||||
<div class="modcp-stat-icon"><i data-lucide="lock" size="22"></i></div>
|
||||
<div class="modcp-stat-info">
|
||||
<span class="modcp-stat-value">{{ $stats['locked'] }}</span>
|
||||
<span class="modcp-stat-label">Locked</span>
|
||||
</div>
|
||||
</a>
|
||||
@can('moderate','\App\Models\Entry')
|
||||
<a href="{{ route('modcp.locked') }}" class="modcp-stat-card">
|
||||
<div class="modcp-stat-icon"><i data-lucide="lock" size="22"></i></div>
|
||||
<div class="modcp-stat-info">
|
||||
<span class="modcp-stat-value">{{ $stats['locked'] }}</span>
|
||||
<span class="modcp-stat-label">Locked</span>
|
||||
</div>
|
||||
</a>
|
||||
@endcan
|
||||
@can('is-admin')
|
||||
<a href="{{ route('modcp.draft') }}" class="modcp-stat-card">
|
||||
<div class="modcp-stat-icon"><i data-lucide="scissors" size="22"></i></div>
|
||||
@@ -54,37 +56,39 @@
|
||||
</div>
|
||||
|
||||
@if($recentDeleted->isNotEmpty())
|
||||
<div class="modcp-section-title" style="margin-top: 25px;">Recently deleted</div>
|
||||
<div class="modcp-list">
|
||||
@foreach($recentDeleted as $entry)
|
||||
<div class="modcp-list-item">
|
||||
<div class="modcp-list-item-info">
|
||||
<span class="modcp-list-item-title">{{ $entry->complete_title ?? $entry->title }}</span>
|
||||
<span class="modcp-list-item-meta">
|
||||
<span class="badge {{ $entry->type }}">{{ $entry->type }}</span>
|
||||
Deleted {{ $entry->deleted_at->diffForHumans() }}
|
||||
</span>
|
||||
@can('is-admin')
|
||||
<div class="modcp-section-title" style="margin-top: 25px;">Recently deleted</div>
|
||||
<div class="modcp-list">
|
||||
@foreach($recentDeleted as $entry)
|
||||
<div class="modcp-list-item">
|
||||
<div class="modcp-list-item-info">
|
||||
<span class="modcp-list-item-title">{{ $entry->complete_title ?? $entry->title }}</span>
|
||||
<span class="modcp-list-item-meta">
|
||||
<span class="badge {{ $entry->type }}">{{ $entry->type }}</span>
|
||||
Deleted {{ $entry->deleted_at->diffForHumans() }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="modcp-list-item-actions">
|
||||
<form action="{{ route('modcp.restore', $entry->id) }}" method="POST" style="display:inline">
|
||||
@csrf @method('PATCH')
|
||||
<button type="submit" class="btn success">
|
||||
<i data-lucide="rotate-ccw" size="13"></i> Restore
|
||||
</button>
|
||||
</form>
|
||||
<form action="{{ route('modcp.destroy', $entry->id) }}" method="POST" style="display:inline"
|
||||
onsubmit="return confirm('Permanently delete?')">
|
||||
@csrf @method('DELETE')
|
||||
<button type="submit" class="btn danger">
|
||||
<i data-lucide="trash-2" size="13"></i> Purge
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modcp-list-item-actions">
|
||||
<form action="{{ route('modcp.restore', $entry->id) }}" method="POST" style="display:inline">
|
||||
@csrf @method('PATCH')
|
||||
<button type="submit" class="btn success">
|
||||
<i data-lucide="rotate-ccw" size="13"></i> Restore
|
||||
</button>
|
||||
</form>
|
||||
<form action="{{ route('modcp.destroy', $entry->id) }}" method="POST" style="display:inline"
|
||||
onsubmit="return confirm('Permanently delete?')">
|
||||
@csrf @method('DELETE')
|
||||
<button type="submit" class="btn danger">
|
||||
<i data-lucide="trash-2" size="13"></i> Purge
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
<a href="{{ route('modcp.deleted') }}" class="modcp-list-see-all">
|
||||
See all deleted entries →
|
||||
</a>
|
||||
@endforeach
|
||||
<a href="{{ route('modcp.deleted') }}" class="modcp-list-see-all">
|
||||
See all deleted entries →
|
||||
</a>
|
||||
@endcan
|
||||
</div>
|
||||
@endif
|
||||
|
||||
|
||||
34
resources/views/modcp/pagination.blade.php
Normal file
34
resources/views/modcp/pagination.blade.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php /** @var \Illuminate\Pagination\LengthAwarePaginator $paginator */ ?>
|
||||
@if ($paginator->hasPages())
|
||||
<div class="database-pagination">
|
||||
|
||||
@if ($paginator->onFirstPage())
|
||||
<button class="btn" disabled>«</button>
|
||||
@else
|
||||
<a class="btn" href="{{ $paginator->previousPageUrl() }}">«</a>
|
||||
@endif
|
||||
|
||||
{{-- Pages --}}
|
||||
@foreach ($elements as $element)
|
||||
@if (is_string($element))
|
||||
<button class="btn" disabled>{{ $element }}</button>
|
||||
@endif
|
||||
|
||||
@if (is_array($element))
|
||||
@foreach ($element as $page => $url)
|
||||
<a
|
||||
class="btn {{ $page == $paginator->currentPage() ? 'active' : '' }}"
|
||||
href="{{ $url }}"
|
||||
>{{ $page }}</a>
|
||||
@endforeach
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
@if ($paginator->hasMorePages())
|
||||
<a class="btn" href="{{ $paginator->nextPageUrl() }}">»</a>
|
||||
@else
|
||||
<button class="btn" disabled>»</button>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
@endif
|
||||
@@ -71,6 +71,6 @@
|
||||
@endforelse
|
||||
</div>
|
||||
|
||||
{{ $items->links() }}
|
||||
{{ $items->links('modcp.pagination') }}
|
||||
|
||||
@endsection
|
||||
|
||||
@@ -154,71 +154,73 @@
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<aside class="news-sidebar">
|
||||
@if( $news->entry()->exists() || $news->relevant_link || $news->youtube_link )
|
||||
<aside class="news-sidebar">
|
||||
|
||||
@if($news->entry()->exists())
|
||||
<div class="sidebar-block">
|
||||
<h3 class="sidebar-title">
|
||||
<i data-lucide="content" size="18"></i>
|
||||
Related entry
|
||||
</h3>
|
||||
<div class="related-card">
|
||||
@if( $news->entry->main_image )
|
||||
<div class="related-card-cover">
|
||||
<img src="{{ Storage::url($news->entry->main_image) }}">
|
||||
@if($news->entry()->exists())
|
||||
<div class="sidebar-block">
|
||||
<h3 class="sidebar-title">
|
||||
<i data-lucide="content" size="18"></i>
|
||||
Related entry
|
||||
</h3>
|
||||
<div class="related-card">
|
||||
@if( $news->entry->main_image )
|
||||
<div class="related-card-cover">
|
||||
<img src="{{ Storage::url($news->entry->main_image) }}">
|
||||
</div>
|
||||
@endif
|
||||
<div class="related-card-info">
|
||||
<h4>{{ $news->entry->title }}</h4>
|
||||
<a href="{{ route('entries.show', ['section' => $news->entry->type, 'entry' => $news->entry ]) }}" class="btn-sidebar" class="btn-orange">
|
||||
Go to the entry
|
||||
</a>
|
||||
</div>
|
||||
@endif
|
||||
<div class="related-card-info">
|
||||
<h4>{{ $news->entry->title }}</h4>
|
||||
<a href="{{ route('entries.show', ['section' => $news->entry->type, 'entry' => $news->entry ]) }}" class="btn-sidebar" class="btn-orange">
|
||||
Go to the entry
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
@endif
|
||||
|
||||
@if($news->relevant_link)
|
||||
<div class="sidebar-block">
|
||||
<h3 class="sidebar-title">
|
||||
<i data-lucide="link" size="18"></i>
|
||||
Relevant link
|
||||
</h3>
|
||||
<a href="{{ $news->relevant_link }}" target="_blank" rel="noopener">
|
||||
{{ $news->relevant_link }}
|
||||
</a>
|
||||
</div>
|
||||
@endif
|
||||
@if($news->relevant_link)
|
||||
<div class="sidebar-block">
|
||||
<h3 class="sidebar-title">
|
||||
<i data-lucide="link" size="18"></i>
|
||||
Relevant link
|
||||
</h3>
|
||||
<a href="{{ $news->relevant_link }}" target="_blank" rel="noopener">
|
||||
{{ $news->relevant_link }}
|
||||
</a>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if( $news->youtube_link )
|
||||
<div x-data="{open: false, src: ''}" x-cloak class="sidebar-block youtube-section">
|
||||
@if( $news->youtube_link )
|
||||
<div x-data="{open: false, src: ''}" x-cloak class="sidebar-block youtube-section">
|
||||
|
||||
<h3 class="sidebar-title">
|
||||
<i data-lucide="play" size="18"></i>
|
||||
Youtube video
|
||||
</h3>
|
||||
<h3 class="sidebar-title">
|
||||
<i data-lucide="play" size="18"></i>
|
||||
Youtube video
|
||||
</h3>
|
||||
|
||||
<div class="video-thumbnail-wrapper"
|
||||
@click="src = 'https://www.youtube.com/embed/{{ $news->getYoutubeVideoId() }}?autoplay=1'; open = true">
|
||||
<img src="https://img.youtube.com/vi/{{ $news->getYoutubeVideoId() }}/maxresdefault.jpg">
|
||||
<div class="play-trigger">
|
||||
<i data-lucide="play"></i>
|
||||
<div class="video-thumbnail-wrapper"
|
||||
@click="src = 'https://www.youtube.com/embed/{{ $news->getYoutubeVideoId() }}?autoplay=1'; open = true">
|
||||
<img src="https://img.youtube.com/vi/{{ $news->getYoutubeVideoId() }}/maxresdefault.jpg">
|
||||
<div class="play-trigger">
|
||||
<i data-lucide="play"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gallery-modal" x-show="open" x-transition.opacity.duration.300ms
|
||||
@click="open = false; src = ''" @keydown.escape.window="open = false; src = ''">
|
||||
<span class="gallery-modal-close" @click="open = false; src = '';"><i
|
||||
data-lucide="x"></i></span>
|
||||
<div class="gallery-modal-video" @click.stop>
|
||||
<iframe :src="src"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gallery-modal" x-show="open" x-transition.opacity.duration.300ms
|
||||
@click="open = false; src = ''" @keydown.escape.window="open = false; src = ''">
|
||||
<span class="gallery-modal-close" @click="open = false; src = '';"><i
|
||||
data-lucide="x"></i></span>
|
||||
<div class="gallery-modal-video" @click.stop>
|
||||
<iframe :src="src"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</aside>
|
||||
@endif
|
||||
</aside>
|
||||
@endif
|
||||
</div>
|
||||
</article>
|
||||
@include('entries.comments')
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<i data-lucide="x-circle" size="12"></i>
|
||||
Rejected
|
||||
@php
|
||||
$daysLeft = intval(7 - now()->diffInDays($entry->rejected_at));
|
||||
$daysLeft = 7 + intval(now()->diffInDays($entry->rejected_at));
|
||||
@endphp
|
||||
@if($daysLeft > 0)
|
||||
- deleted in {{ $daysLeft }} days
|
||||
|
||||
@@ -231,6 +231,12 @@
|
||||
<div class="form-type-of-checkboxes form-group level" id="entry-metadata">
|
||||
<label><input class="form-checkbox" type="checkbox" name="featured" value="1" {{ old('featured', $entry->featured ) ? 'checked' : '' }}>Featured entry</label>
|
||||
<label><input class="form-checkbox" type="checkbox" name="refresh_created_at" value="1">Refresh created at</label>
|
||||
@if( section_must_be(['romhacks', 'homebrew'], $section ) )
|
||||
<label><input class="form-checkbox" type="checkbox" name="nsfw-entry" value="1" {{ old('nsfw-entry', $entry->nsfw ) ? 'checked' : '' }}>NSFW</label>
|
||||
@endif
|
||||
@if( section_must_be( ['romhacks', 'translations'], $section ) )
|
||||
<label><input class="form-checkbox" type="checkbox" name="bypass_hashes" value="1">Bypass hashes requirements</label>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@endcan
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<x-form-error-text message="Don't submit ROMs" />
|
||||
<x-form-error-text message="For patches .zip is preferred .7z/.rar accepted. Don't submit ROMs" />
|
||||
|
||||
{{-- Client-side Errors --}}
|
||||
<div class="form-error-text" x-show="errorKey === 'noFiles' || errorKey === 'uploadError' || errorKey === 'notAllFilesDone'" x-text="errorMessage"></div>
|
||||
|
||||
@@ -56,15 +56,27 @@
|
||||
<div class="submit-rules">
|
||||
<div class="submit-rule">
|
||||
<span class="submit-rule-num">1</span>
|
||||
<p><strong>One entry per submission.</strong> Do not bundle multiple hacks or versions in a single form.</p>
|
||||
<p><strong>ROM files are not allowed</strong> Only patches (does not apply to homebrews).</p>
|
||||
</div>
|
||||
<div class="submit-rule">
|
||||
<span class="submit-rule-num">2</span>
|
||||
<p><strong>You must be the author</strong> or have explicit permission from the original creator.</p>
|
||||
<p>Always search before adding something, it might already be on the site.</p>
|
||||
</div>
|
||||
<div class="submit-rule">
|
||||
<span class="submit-rule-num">3</span>
|
||||
<p><strong>Patch files only.</strong> Never upload ROM files — attach an IPS, BPS or xdelta patch.</p>
|
||||
<p>When typing game titles make sure to use "Title Case", when unsure copy GameFAQs title.</p>
|
||||
</div>
|
||||
<div class="submit-rule">
|
||||
<span class="submit-rule-num">4</span>
|
||||
<p>Descriptions must be in English. For non-English hacks you can have both versions: one in the hack language and one in English</p>
|
||||
</div>
|
||||
<div class="submit-rule">
|
||||
<span class="submit-rule-num">5</span>
|
||||
<p>Try to put screenshots that showcase the work, if the work is not graphical use original screenshots. Mobygames is a great source for them.</p>
|
||||
</div>
|
||||
<div class="submit-rule">
|
||||
<span class="submit-rule-num">...</span>
|
||||
<p>All rules and guidelines are available <a href="{{ xfRoute('misc/terms') }}">here</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
@if ($paginator->hasPages())
|
||||
<div class="database-pagination">
|
||||
|
||||
{{-- Précédent --}}
|
||||
@if ($paginator->onFirstPage())
|
||||
<button class="btn" disabled>«</button>
|
||||
@else
|
||||
@@ -24,7 +23,6 @@
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
{{-- Suivant --}}
|
||||
@if ($paginator->hasMorePages())
|
||||
<button class="btn" wire:click="nextPage">»</button>
|
||||
@else
|
||||
|
||||
@@ -9,3 +9,4 @@ Artisan::command('inspire', function () {
|
||||
|
||||
Schedule::command('entries:purge-rejected')->daily();
|
||||
Schedule::command('entries:purge-featured')->daily();
|
||||
Schedule::command('sitemap:generate')->daily();
|
||||
|
||||
@@ -33,14 +33,14 @@ Route::name('reviews.')->controller(ReviewController::class)->group(function ()
|
||||
});
|
||||
|
||||
// SubmissionController.
|
||||
Route::name('submit.')->prefix('/submit')->controller(\App\Http\Controllers\SubmissionController::class)->middleware(['xf.auth', 'can:create,\App\Models\Entry'])->group(function () {
|
||||
Route::name('submit.')->prefix('/submit')->controller(\App\Http\Controllers\SubmissionController::class)->middleware(['submissions.maintenance','xf.auth', 'can:create,\App\Models\Entry'])->group(function () {
|
||||
Route::get('/', 'index')->name('index');
|
||||
Route::get('/{section}', 'create' )->name('create')
|
||||
->where([ 'section' => 'translations|romhacks|homebrew|utilities|documents|lua-scripts' ]);
|
||||
Route::post('/{section}', 'store' )->name('store')
|
||||
->where([ 'section' => 'translations|romhacks|homebrew|utilities|documents|lua-scripts' ]);
|
||||
});
|
||||
Route::name('submit.')->prefix('/edit')->controller(\App\Http\Controllers\SubmissionController::class)->middleware(['xf.auth', 'can:update,entry'])->group(function () {
|
||||
Route::name('submit.')->prefix('/edit')->controller(\App\Http\Controllers\SubmissionController::class)->middleware(['submissions.maintenance','xf.auth', 'can:update,entry'])->group(function () {
|
||||
Route::get('/{section}/{entry:id}', 'edit' )->name('edit')
|
||||
->where([ 'section' => 'translations|romhacks|homebrew|utilities|documents|lua-scripts', 'entry' => '[0-9\-]+' ]);
|
||||
Route::post('/{section}/{entry:id}', 'update' )->name('update')
|
||||
@@ -54,12 +54,12 @@ Route::name('news.')->controller(\App\Http\Controllers\NewsController::class)->g
|
||||
Route::get('/news/', 'index' )->name('index');
|
||||
Route::get('/news/{news:slug}', 'show' )->name('show')->where([ 'news' => '[a-zA-Z0-9\-_]+']);
|
||||
|
||||
Route::get('/submit/news', 'create' )->name('create')->middleware(['xf.auth','can:create,\App\Models\News']);
|
||||
Route::post('/submit/news', 'store' )->name('store')->middleware(['xf.auth','can:create,\App\Models\News']);
|
||||
Route::get('/submit/news', 'create' )->name('create')->middleware(['submissions.maintenance','xf.auth','can:create,\App\Models\News']);
|
||||
Route::post('/submit/news', 'store' )->name('store')->middleware(['submissions.maintenance','xf.auth','can:create,\App\Models\News']);
|
||||
|
||||
Route::get('/edit/news/{news:id}', 'edit')->name('edit')->where(['news' => '[0-9\-]+'])->middleware(['xf.auth','can:update,news']);
|
||||
Route::post('/edit/news/{news:id}', 'update')->name('update')->where(['news' => '[0-9\-]+'])->middleware(['xf.auth','can:update,news']);
|
||||
Route::delete('/edit/news/{news:id}', 'destroy')->name('destroy')->where(['news' => '[0-9\-]+'])->middleware(['xf.auth','can:update,news']);
|
||||
Route::get('/edit/news/{news:id}', 'edit')->name('edit')->where(['news' => '[0-9\-]+'])->middleware(['submissions.maintenance','xf.auth','can:update,news']);
|
||||
Route::post('/edit/news/{news:id}', 'update')->name('update')->where(['news' => '[0-9\-]+'])->middleware(['submissions.maintenance','xf.auth','can:update,news']);
|
||||
Route::delete('/edit/news/{news:id}', 'destroy')->name('destroy')->where(['news' => '[0-9\-]+'])->middleware(['submissions.maintenance','xf.auth','can:update,news']);
|
||||
});
|
||||
|
||||
// QueueController
|
||||
@@ -67,32 +67,32 @@ Route::name('queue.')->prefix('/queue')->controller(\App\Http\Controllers\QueueC
|
||||
Route::get('/', 'index' )->name('index');
|
||||
|
||||
Route::patch('/{entry:id}/comment', 'updateComment' )
|
||||
->middleware(['xf.auth', 'can:updateComment,entry' ] )
|
||||
->middleware(['submissions.maintenance','xf.auth', 'can:updateComment,entry' ] )
|
||||
->where([ 'entry' => '[0-9\-]+' ])
|
||||
->name('comment');
|
||||
|
||||
Route::patch('/{entry:id}/approve', 'approve' )
|
||||
->middleware(['xf.auth', 'can:approve,entry' ] )
|
||||
->middleware(['submissions.maintenance','xf.auth', 'can:approve,entry' ] )
|
||||
->where([ 'entry' => '[0-9\-]+' ])
|
||||
->name('approve');
|
||||
|
||||
Route::patch('/{entry:id}/reject', 'reject' )
|
||||
->middleware(['xf.auth', 'can:reject,entry' ] )
|
||||
->middleware(['submissions.maintenance','xf.auth', 'can:reject,entry' ] )
|
||||
->where([ 'entry' => '[0-9\-]+' ])
|
||||
->name('reject');
|
||||
|
||||
Route::patch('/news/{news:id}/comment', 'updateComment_news' )
|
||||
->middleware(['xf.auth', 'can:updateComment,news' ] )
|
||||
->middleware(['submissions.maintenance','xf.auth', 'can:updateComment,news' ] )
|
||||
->where([ 'news' => '[0-9\-]+' ])
|
||||
->name('news.comment');
|
||||
|
||||
Route::patch('/news/{news:id}/approve', 'approve_news' )
|
||||
->middleware(['xf.auth', 'can:approve,news' ] )
|
||||
->middleware(['submissions.maintenance','xf.auth', 'can:approve,news' ] )
|
||||
->where([ 'news' => '[0-9\-]+' ])
|
||||
->name('news.approve');
|
||||
|
||||
Route::patch('/news/{news:id}/reject', 'reject_news' )
|
||||
->middleware(['xf.auth', 'can:reject,news' ] )
|
||||
->middleware(['submissions.maintenance','xf.auth', 'can:reject,news' ] )
|
||||
->where([ 'news' => '[0-9\-]+' ])
|
||||
->name('news.reject');
|
||||
});
|
||||
@@ -111,7 +111,7 @@ Route::name('tools.')->controller(\App\Http\Controllers\ToolsController::class)-
|
||||
Route::name('modcp.')->prefix('/modcp')->controller(\App\Http\Controllers\ModCPController::class)->middleware(['xf.auth','can:is-mod'])->group(function () {
|
||||
|
||||
Route::get('/', 'index' )->name('index');
|
||||
Route::get('/locked-entries', 'locked' )->name('locked');
|
||||
Route::get('/locked-entries', 'locked' )->name('locked')->middleware('can:moderate,\App\Models\Entry');
|
||||
Route::get('/draft-entries', 'draft' )->name('draft')->middleware('can:is-admin');
|
||||
Route::get('/hidden-entries', 'hidden' )->name('hidden')->middleware('can:is-admin');
|
||||
Route::get('/deleted-entries', 'deleted' )->name('deleted')->middleware('can:is-admin');
|
||||
@@ -125,6 +125,8 @@ Route::name('modcp.')->prefix('/modcp')->controller(\App\Http\Controllers\ModCPC
|
||||
Route::resource('authors', \App\Http\Controllers\ModCP\AuthorController::class)->only(['index', 'store','update','destroy']);
|
||||
Route::resource('platforms', \App\Http\Controllers\ModCP\PlatformController::class )->middleware('can:is-admin')->only(['index', 'store','update','destroy']);
|
||||
Route::resource('genres', \App\Http\Controllers\ModCP\GenreController::class )->middleware('can:is-admin')->only(['index', 'store','update','destroy']);
|
||||
Route::resource('levels', \App\Http\Controllers\ModCP\LevelController::class )->middleware('can:is-admin')->only(['index', 'store','update','destroy']);
|
||||
Route::resource('modifications', \App\Http\Controllers\ModCP\ModificationsController::class )->middleware('can:is-admin')->only(['index', 'store','update','destroy']);
|
||||
});
|
||||
|
||||
// RedirectController
|
||||
@@ -132,3 +134,9 @@ Route::name('redirect.')->controller(\App\Http\Controllers\RedirectController::c
|
||||
Route::get('/entry/report_redirect', 'entryReportRedirect' )->name('entry_report');
|
||||
Route::get('/news/report_redirect', 'newsReportRedirect' )->name('news_report');
|
||||
});
|
||||
|
||||
// ShortLinkController
|
||||
Route::domain('rhpz.org')->name('shorturl.')->controller(\App\Http\Controllers\ShortLinkController::class)->group(function () {
|
||||
Route::get('/{id}', 'legacy' )->where('id', '[0-9]+')->name('legacy');
|
||||
Route::get('/{letter}/{id}', 'redirect' )->where(['letter' => '[a-z]', 'id' => '[0-9]+'])->name('redirect');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user