s3 config
This commit is contained in:
parent
d9dca29bc9
commit
093c538752
19 changed files with 751 additions and 40 deletions
|
|
@ -61,5 +61,7 @@ AWS_SECRET_ACCESS_KEY=
|
|||
AWS_DEFAULT_REGION=us-east-1
|
||||
AWS_BUCKET=
|
||||
AWS_USE_PATH_STYLE_ENDPOINT=false
|
||||
# AWS_BUCKET=share-lt-images
|
||||
# MEDIA_DISK=s3
|
||||
|
||||
VITE_APP_NAME="${APP_NAME}"
|
||||
|
|
|
|||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -26,3 +26,4 @@ yarn-error.log
|
|||
.env.dusk.local
|
||||
log*.txt
|
||||
.envrc
|
||||
database/backups
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# CHANGELOG
|
||||
|
||||
## 2026-01-08
|
||||
## 2026-01-19
|
||||
|
||||
added text widgets
|
||||
|
||||
|
|
|
|||
61
app/Console/Commands/RemediateBlogS3Images.php
Normal file
61
app/Console/Commands/RemediateBlogS3Images.php
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use App\Models\Entry;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
use function Livewire\str;
|
||||
|
||||
class RemediateBlogS3Images extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'app:remediate-blog-s3-images';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Command description';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$stringToFind = 'src="http://127.0.0.1:8000/storage';
|
||||
$stringToReplace = 'src="https://your-s3-bucket-here/yours-site-static-media-dir-here';
|
||||
|
||||
Log::info('RemediateBlogS3Images command executed.');
|
||||
foreach (Entry::all() as $entry) {
|
||||
|
||||
$this->info('Entry ID: ' . $entry->id);
|
||||
if (str_contains($entry->content, $stringToFind)) {
|
||||
$this->info(' - Found occurrence in entry ID: ' . $entry->id);
|
||||
// Extract all image srcs that match the pattern
|
||||
preg_match_all('/src=\"http:\/\/127.0.0.1:8000\/storage([^\"]*)/', $entry->content, $matches);
|
||||
if (!empty($matches[0])) {
|
||||
foreach ($matches[0] as $i => $foundUrl) {
|
||||
$this->info(' - Found image src: ' . $foundUrl);
|
||||
// Compute the replacement for this specific image
|
||||
$relativePath = $matches[1][$i] ?? '';
|
||||
$newUrl = 'src="https://your-s3-bucket-here/yours-site-static-media-dir-here' . $relativePath;
|
||||
$this->info(' - Will replace with: ' . $newUrl);
|
||||
}
|
||||
}
|
||||
$updatedContent = \str_replace($stringToFind, $stringToReplace, $entry->content);
|
||||
// uncomment the following when your sure about the changes
|
||||
// $entry->content = $updatedContent;
|
||||
// $entry->save();
|
||||
// $this->info(' - Updated entry ID: ' . $entry->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -13,6 +13,7 @@ use Filament\Forms\Components\Textarea;
|
|||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\Toggle;
|
||||
use Filament\Schemas\Schema;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Str;
|
||||
use Spatie\MediaLibrary\MediaCollections\Models\Media;
|
||||
|
||||
|
|
@ -22,6 +23,16 @@ class EntryForm
|
|||
{
|
||||
return $schema
|
||||
->components([
|
||||
Select::make('type')
|
||||
->options([
|
||||
'article' => 'Article',
|
||||
'card' => 'Card',
|
||||
'text' => 'Text',
|
||||
'image' => 'Image',
|
||||
])
|
||||
->default('article')
|
||||
->required()
|
||||
->live(),
|
||||
TextInput::make('title')
|
||||
->required()
|
||||
->live(onBlur: true)
|
||||
|
|
@ -30,21 +41,112 @@ class EntryForm
|
|||
}),
|
||||
TextInput::make('slug')
|
||||
->required()
|
||||
->visible(fn($get) => $get('type') === 'article')
|
||||
->dehydrated()
|
||||
->readOnly(),
|
||||
Textarea::make('description')
|
||||
->visible(fn($get) => $get('type') === 'article')
|
||||
->columnSpanFull(),
|
||||
SpatieTagsInput::make('tags')
|
||||
->type('entry-tags')
|
||||
->visible(fn($get) => $get('type') === 'article')
|
||||
->columnSpanFull(),
|
||||
SpatieMediaLibraryFileUpload::make('featured_image')
|
||||
->visible(
|
||||
fn($get) =>
|
||||
$get('type') === 'article' || $get('type') === 'image'
|
||||
)
|
||||
->collection('featured-image')
|
||||
->image()
|
||||
->imageEditor()
|
||||
->disk('public')
|
||||
->disk(config('media-library.disk_name', 'public'))
|
||||
->visibility('public')
|
||||
->columnSpanFull()
|
||||
->dehydrated(false)
|
||||
->saveUploadedFileUsing(function ($file, $record) {
|
||||
$diskName = config('media-library.disk_name', 'public');
|
||||
|
||||
if (config('app.env') === 'local') {
|
||||
Log::info('Featured Image Upload Debug', [
|
||||
'disk' => $diskName,
|
||||
'file_name' => $file->getClientOriginalName(),
|
||||
'file_size' => $file->getSize(),
|
||||
'file_mime' => $file->getMimeType(),
|
||||
'file_path' => $file->getRealPath(),
|
||||
'record_id' => $record?->id,
|
||||
'aws_config' => [
|
||||
'bucket' => config('filesystems.disks.s3.bucket'),
|
||||
'region' => config('filesystems.disks.s3.region'),
|
||||
'key_exists' => !empty(config('filesystems.disks.s3.key')),
|
||||
'secret_exists' => !empty(config('filesystems.disks.s3.secret')),
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
try {
|
||||
if (!$record) {
|
||||
throw new \Exception('Record not found during upload');
|
||||
}
|
||||
|
||||
// Test S3 connection if using S3
|
||||
if ($diskName === 's3') {
|
||||
$disk = \Storage::disk('s3');
|
||||
|
||||
// Test basic S3 connectivity
|
||||
$testFile = 'test-' . time() . '.txt';
|
||||
$disk->put($testFile, 'test content');
|
||||
$disk->delete($testFile);
|
||||
|
||||
if (config('app.env') === 'local') {
|
||||
Log::info('S3 connectivity test passed');
|
||||
}
|
||||
}
|
||||
|
||||
// Use addMedia with the file directly, not addMediaFromRequest
|
||||
// Generate secure filename similar to Livewire temp files
|
||||
$originalName = $file->getClientOriginalName();
|
||||
$extension = pathinfo($originalName, PATHINFO_EXTENSION);
|
||||
$baseName = pathinfo($originalName, PATHINFO_FILENAME);
|
||||
|
||||
// Generate secure filename with encoded original name
|
||||
$encodedName = base64_encode($originalName);
|
||||
$secureFileName = Str::random(32) . '-meta' . $encodedName . '-.' . $extension;
|
||||
|
||||
$media = $record->addMedia($file->getRealPath())
|
||||
->usingName($baseName) // Keep original name for display/search
|
||||
->usingFileName($secureFileName) // Use secure filename for storage
|
||||
->toMediaCollection('featured-image', $diskName);
|
||||
|
||||
if (config('app.env') === 'local') {
|
||||
Log::info('Featured Image Upload Success', [
|
||||
'media_id' => $media->id,
|
||||
'media_url' => $media->getUrl(),
|
||||
'media_path' => $media->getPathRelativeToRoot(),
|
||||
'disk' => $media->disk
|
||||
]);
|
||||
}
|
||||
|
||||
return $media->getUrl();
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Featured Image Upload Failed', [
|
||||
'error' => $e->getMessage(),
|
||||
'trace' => $e->getTraceAsString(),
|
||||
'disk' => $diskName,
|
||||
'file_name' => $file->getClientOriginalName()
|
||||
]);
|
||||
|
||||
|
||||
// Also show error to user
|
||||
\Filament\Notifications\Notification::make()
|
||||
->danger()
|
||||
->title('Upload Failed')
|
||||
->body($e->getMessage())
|
||||
->persistent()
|
||||
->send();
|
||||
|
||||
throw $e;
|
||||
}
|
||||
})
|
||||
->hintAction(
|
||||
Action::make('featured_picker')
|
||||
->label('Featured Image from Gallery')
|
||||
|
|
@ -55,11 +157,10 @@ class EntryForm
|
|||
->label('Select an existing image')
|
||||
->allowHtml()
|
||||
->options(function () {
|
||||
return Media::where('model_type', 'temp')
|
||||
->where('model_id', 0)
|
||||
->where('disk', 'public')
|
||||
$currentDisk = config('media-library.disk_name', 'public');
|
||||
return Media::where('disk', $currentDisk)
|
||||
->latest()
|
||||
->limit(30)
|
||||
->limit(50)
|
||||
->get(['id', 'file_name', 'name', 'disk'])
|
||||
->mapWithKeys(function (Media $item) {
|
||||
try {
|
||||
|
|
@ -86,6 +187,15 @@ class EntryForm
|
|||
])
|
||||
->action(function (array $data, SpatieMediaLibraryFileUpload $component): void {
|
||||
$record = $component->getRecord();
|
||||
$diskName = config('media-library.disk_name', 'public');
|
||||
|
||||
if (config('app.env') === 'local') {
|
||||
Log::info('Featured Image Picker Action Debug', [
|
||||
'disk' => $diskName,
|
||||
'record_id' => $record?->id,
|
||||
'image_id' => $data['image_id'] ?? null
|
||||
]);
|
||||
}
|
||||
|
||||
if (! $record) {
|
||||
\Filament\Notifications\Notification::make()
|
||||
|
|
@ -101,27 +211,53 @@ class EntryForm
|
|||
}
|
||||
|
||||
$sourceMedia = Media::find($data['image_id']);
|
||||
if (! $sourceMedia || ! file_exists($sourceMedia->getPath())) {
|
||||
if (! $sourceMedia) {
|
||||
Log::error('Source media not found', ['image_id' => $data['image_id']]);
|
||||
\Filament\Notifications\Notification::make()
|
||||
->danger()
|
||||
->title('Image file not found')
|
||||
->title('Source image not found in database')
|
||||
->send();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$sourceFile = $sourceMedia->getPath();
|
||||
$tempCopy = sys_get_temp_dir() . '/' . uniqid() . '_' . $sourceMedia->file_name;
|
||||
copy($sourceFile, $tempCopy);
|
||||
|
||||
try {
|
||||
// For S3, we need to handle file copying differently
|
||||
if ($sourceMedia->disk === 's3') {
|
||||
if (config('app.env') === 'local') {
|
||||
Log::info('Copying S3 media to new collection', [
|
||||
'source_disk' => $sourceMedia->disk,
|
||||
'source_path' => $sourceMedia->getPathRelativeToRoot(),
|
||||
'target_disk' => $diskName
|
||||
]);
|
||||
}
|
||||
|
||||
// Copy from S3 to S3 or download temporarily
|
||||
$sourceDisk = \Storage::disk($sourceMedia->disk);
|
||||
$sourceContent = $sourceDisk->get($sourceMedia->getPathRelativeToRoot());
|
||||
|
||||
if (!$sourceContent) {
|
||||
throw new \Exception('Could not read source file from S3');
|
||||
}
|
||||
|
||||
$tempCopy = sys_get_temp_dir() . '/' . uniqid() . '_' . $sourceMedia->file_name;
|
||||
file_put_contents($tempCopy, $sourceContent);
|
||||
} else {
|
||||
// Local file handling
|
||||
$sourceFile = $sourceMedia->getPath();
|
||||
if (! file_exists($sourceFile)) {
|
||||
throw new \Exception('Source file not found on disk');
|
||||
}
|
||||
|
||||
$tempCopy = sys_get_temp_dir() . '/' . uniqid() . '_' . $sourceMedia->file_name;
|
||||
copy($sourceFile, $tempCopy);
|
||||
}
|
||||
|
||||
// Verify record has ID
|
||||
if (! $record->id) {
|
||||
\Filament\Notifications\Notification::make()
|
||||
->danger()
|
||||
->title('Entry must be saved first')
|
||||
->send();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -129,7 +265,15 @@ class EntryForm
|
|||
$newMedia = $record->addMedia($tempCopy)
|
||||
->usingName($sourceMedia->name ?: pathinfo($sourceMedia->file_name, PATHINFO_FILENAME))
|
||||
->usingFileName($sourceMedia->file_name)
|
||||
->toMediaCollection('featured-image', 'public');
|
||||
->toMediaCollection('featured-image', $diskName);
|
||||
|
||||
if (config('app.env') === 'local') {
|
||||
Log::info('Featured Image Picker Success', [
|
||||
'new_media_id' => $newMedia->id,
|
||||
'new_media_disk' => $newMedia->disk,
|
||||
'new_media_url' => $newMedia->getUrl()
|
||||
]);
|
||||
}
|
||||
|
||||
// Dispatch event for app.js to handle
|
||||
$component->getLivewire()->dispatch('featured-image-added', ['mediaId' => $newMedia->id]);
|
||||
|
|
@ -139,12 +283,20 @@ class EntryForm
|
|||
->title('Image added to featured image')
|
||||
->send();
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Featured Image Picker Failed', [
|
||||
'error' => $e->getMessage(),
|
||||
'trace' => $e->getTraceAsString(),
|
||||
'source_media_id' => $data['image_id'],
|
||||
'disk' => $diskName
|
||||
]);
|
||||
|
||||
\Filament\Notifications\Notification::make()
|
||||
->danger()
|
||||
->title('Error: ' . $e->getMessage())
|
||||
->persistent()
|
||||
->send();
|
||||
} finally {
|
||||
if (file_exists($tempCopy)) {
|
||||
if (isset($tempCopy) && file_exists($tempCopy)) {
|
||||
unlink($tempCopy);
|
||||
}
|
||||
}
|
||||
|
|
@ -154,7 +306,13 @@ class EntryForm
|
|||
->required(),
|
||||
Toggle::make('is_featured')
|
||||
->required(),
|
||||
DatePicker::make('published_at'),
|
||||
TextInput::make('priority')
|
||||
->label('Priority')
|
||||
->numeric()
|
||||
->default(0)
|
||||
->required(),
|
||||
DatePicker::make('published_at')
|
||||
->visible(fn($get) => $get('type') === 'article'),
|
||||
Select::make('category_id')
|
||||
->label('Category')
|
||||
->options(function () {
|
||||
|
|
@ -164,11 +322,14 @@ class EntryForm
|
|||
})
|
||||
->searchable(),
|
||||
TextInput::make('call_to_action_text')
|
||||
->label('Call to Action Text'),
|
||||
->label('Call to Action Text')
|
||||
->visible(fn($get) => $get('type') !== 'article'),
|
||||
TextInput::make('call_to_action_link')
|
||||
->label('Call to Action URL'),
|
||||
->label('Call to Action URL')
|
||||
->visible(fn($get) => $get('type') !== 'article'),
|
||||
|
||||
RichEditor::make('content')
|
||||
->visible(fn($get) => $get('type') !== 'image')
|
||||
->columnSpanFull()
|
||||
->hintAction(
|
||||
Action::make('picker')
|
||||
|
|
|
|||
|
|
@ -32,12 +32,12 @@ class MediaForm
|
|||
'1:1',
|
||||
])
|
||||
->columnSpanFull()
|
||||
->disk('public')
|
||||
->disk('s3')
|
||||
->directory('media')
|
||||
->visibility('public')
|
||||
->acceptedFileTypes(['image/*', 'application/pdf'])
|
||||
->maxSize(10240)
|
||||
->required(fn ($context) => $context === 'create')
|
||||
->required(fn($context) => $context === 'create')
|
||||
->afterStateHydrated(function (FileUpload $component, $state, $record): void {
|
||||
if (! $record) {
|
||||
return;
|
||||
|
|
@ -50,7 +50,7 @@ class MediaForm
|
|||
}
|
||||
|
||||
// Construct the correct path: {media_id}/{filename}
|
||||
$path = $media->id.'/'.$media->file_name;
|
||||
$path = $media->id . '/' . $media->file_name;
|
||||
|
||||
$component->state($path);
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ class EntryResource extends JsonResource
|
|||
'call_to_action_link' => $this->call_to_action_link,
|
||||
'created_at' => $this->created_at,
|
||||
'updated_at' => $this->updated_at,
|
||||
'priority' => $this->priority,
|
||||
'type' => $this->type,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ class Entry extends Model implements HasMedia, HasRichContent
|
|||
|
||||
protected $fillable = [
|
||||
'title',
|
||||
'type',
|
||||
'slug',
|
||||
'description',
|
||||
'is_published',
|
||||
|
|
@ -33,6 +34,7 @@ class Entry extends Model implements HasMedia, HasRichContent
|
|||
'call_to_action_link',
|
||||
'call_to_action_text',
|
||||
'category_id',
|
||||
'priority',
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -34,7 +34,12 @@ class AdminPanelProvider extends PanelProvider
|
|||
->colors([
|
||||
'primary' => Color::Blue,
|
||||
])
|
||||
->discoverResources(in: app_path('Filament/Resources'), for: 'App\Filament\Resources')
|
||||
->resources([
|
||||
\App\Filament\Resources\Entries\EntryResource::class,
|
||||
\App\Filament\Resources\TextWidgets\TextWidgetResource::class,
|
||||
\App\Filament\Resources\Media\MediaResource::class,
|
||||
\App\Filament\Resources\Categroys\CategroyResource::class,
|
||||
])
|
||||
->discoverPages(in: app_path('Filament/Pages'), for: 'App\Filament\Pages')
|
||||
->pages([
|
||||
Dashboard::class,
|
||||
|
|
|
|||
15
cmd/backup_raw_data.sh
Executable file
15
cmd/backup_raw_data.sh
Executable file
|
|
@ -0,0 +1,15 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
#SQLITE_DB_PATH="../share-lt/database/database.sqlite"
|
||||
SQLITE_DB_PATH="../share-lt/database/database.sqlite.backup5.recovery"
|
||||
BACKUP_DIR="database/backups"
|
||||
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
|
||||
BACKUP_FILE="$BACKUP_DIR/backup_$TIMESTAMP.sql"
|
||||
TABLES="taggables media tags categories text_widgets entries users"
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
for TABLE in $TABLES; do
|
||||
echo "Backing up table: $TABLE"
|
||||
sqlite3 "$SQLITE_DB_PATH" ".dump $TABLE" > "$BACKUP_DIR/${TABLE}_backup_$TIMESTAMP.sql"
|
||||
done
|
||||
|
||||
58
cmd/restore_raw_data.sh
Executable file
58
cmd/restore_raw_data.sh
Executable file
|
|
@ -0,0 +1,58 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Define the backup directory and the SQLite database file
|
||||
BACKUP_DIR="database/backups"
|
||||
DB_FILE="database/database.sqlite"
|
||||
# DATE="20260124_115644"
|
||||
DATE="20260124_123340"
|
||||
|
||||
# Ensure the DATE variable is set
|
||||
if [ -z "$DATE" ]; then
|
||||
echo "DATE variable is not set. Please set the DATE variable to match the backup file date."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if the backup directory exists
|
||||
if [ ! -d "$BACKUP_DIR" ]; then
|
||||
echo "Backup directory does not exist: $BACKUP_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if the SQLite database file exists
|
||||
if [ ! -f "$DB_FILE" ]; then
|
||||
echo "SQLite database file does not exist: $DB_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if there are any matching backup files
|
||||
if ! ls "$BACKUP_DIR"/*"$DATE".sql 1> /dev/null 2>&1; then
|
||||
echo "No backup files found for the date: $DATE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Starting restore process from backups dated: $DATE"
|
||||
echo "Using database file: $DB_FILE"
|
||||
|
||||
# Loop through each file in the backup directory
|
||||
for file in "$BACKUP_DIR"/*"$DATE".sql; do
|
||||
if [ -f "$file" ]; then
|
||||
echo "Restoring data from $file into $DB_FILE..."
|
||||
|
||||
# Import the SQL file into the SQLite database and log output
|
||||
sqlite3 "$DB_FILE" < "$file" 2>> restore_errors.log
|
||||
|
||||
# Check for errors in the restore process
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Successfully restored $file"
|
||||
else
|
||||
echo "Failed to restore $file. Check restore_errors.log for details."
|
||||
fi
|
||||
|
||||
# Debugging: Print the last 10 lines of the database to verify data
|
||||
# echo "Last 10 rows of the database after restoring $file:"
|
||||
# sqlite3 "$DB_FILE" "SELECT * FROM sqlite_master WHERE type='table';" 2>> restore_errors.log
|
||||
# sqlite3 "$DB_FILE" "SELECT * FROM entries ORDER BY rowid DESC LIMIT 10;" 2>> restore_errors.log
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Restore process completed."
|
||||
|
|
@ -14,6 +14,7 @@
|
|||
"laravel/framework": "^12.0",
|
||||
"laravel/sanctum": "^4.0",
|
||||
"laravel/tinker": "^2.10.1",
|
||||
"league/flysystem-aws-s3-v3": "^3.0",
|
||||
"livewire/flux": "^2.9.0",
|
||||
"spatie/laravel-medialibrary": "^11.17",
|
||||
"spatie/laravel-tags": "^4.10"
|
||||
|
|
|
|||
372
composer.lock
generated
372
composer.lock
generated
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "f4958020fbef658afa0859ba9b23a152",
|
||||
"content-hash": "07b9fb2e6bdb329e62a1cf4d814812df",
|
||||
"packages": [
|
||||
{
|
||||
"name": "anourvalar/eloquent-serialize",
|
||||
|
|
@ -72,6 +72,157 @@
|
|||
},
|
||||
"time": "2025-12-04T13:38:21+00:00"
|
||||
},
|
||||
{
|
||||
"name": "aws/aws-crt-php",
|
||||
"version": "v1.2.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/awslabs/aws-crt-php.git",
|
||||
"reference": "d71d9906c7bb63a28295447ba12e74723bd3730e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/awslabs/aws-crt-php/zipball/d71d9906c7bb63a28295447ba12e74723bd3730e",
|
||||
"reference": "d71d9906c7bb63a28295447ba12e74723bd3730e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.5"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8.35||^5.6.3||^9.5",
|
||||
"yoast/phpunit-polyfills": "^1.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-awscrt": "Make sure you install awscrt native extension to use any of the functionality."
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"src/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"Apache-2.0"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "AWS SDK Common Runtime Team",
|
||||
"email": "aws-sdk-common-runtime@amazon.com"
|
||||
}
|
||||
],
|
||||
"description": "AWS Common Runtime for PHP",
|
||||
"homepage": "https://github.com/awslabs/aws-crt-php",
|
||||
"keywords": [
|
||||
"amazon",
|
||||
"aws",
|
||||
"crt",
|
||||
"sdk"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/awslabs/aws-crt-php/issues",
|
||||
"source": "https://github.com/awslabs/aws-crt-php/tree/v1.2.7"
|
||||
},
|
||||
"time": "2024-10-18T22:15:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "aws/aws-sdk-php",
|
||||
"version": "3.369.19",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/aws/aws-sdk-php.git",
|
||||
"reference": "32fee3a25290186724ede9ca177d5090f7c5a837"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/32fee3a25290186724ede9ca177d5090f7c5a837",
|
||||
"reference": "32fee3a25290186724ede9ca177d5090f7c5a837",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"aws/aws-crt-php": "^1.2.3",
|
||||
"ext-json": "*",
|
||||
"ext-pcre": "*",
|
||||
"ext-simplexml": "*",
|
||||
"guzzlehttp/guzzle": "^7.4.5",
|
||||
"guzzlehttp/promises": "^2.0",
|
||||
"guzzlehttp/psr7": "^2.4.5",
|
||||
"mtdowling/jmespath.php": "^2.8.0",
|
||||
"php": ">=8.1",
|
||||
"psr/http-message": "^1.0 || ^2.0",
|
||||
"symfony/filesystem": "^v5.4.45 || ^v6.4.3 || ^v7.1.0 || ^v8.0.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"andrewsville/php-token-reflection": "^1.4",
|
||||
"aws/aws-php-sns-message-validator": "~1.0",
|
||||
"behat/behat": "~3.0",
|
||||
"composer/composer": "^2.7.8",
|
||||
"dms/phpunit-arraysubset-asserts": "^0.4.0",
|
||||
"doctrine/cache": "~1.4",
|
||||
"ext-dom": "*",
|
||||
"ext-openssl": "*",
|
||||
"ext-sockets": "*",
|
||||
"phpunit/phpunit": "^9.6",
|
||||
"psr/cache": "^2.0 || ^3.0",
|
||||
"psr/simple-cache": "^2.0 || ^3.0",
|
||||
"sebastian/comparator": "^1.2.3 || ^4.0 || ^5.0",
|
||||
"yoast/phpunit-polyfills": "^2.0"
|
||||
},
|
||||
"suggest": {
|
||||
"aws/aws-php-sns-message-validator": "To validate incoming SNS notifications",
|
||||
"doctrine/cache": "To use the DoctrineCacheAdapter",
|
||||
"ext-curl": "To send requests using cURL",
|
||||
"ext-openssl": "Allows working with CloudFront private distributions and verifying received SNS messages",
|
||||
"ext-pcntl": "To use client-side monitoring",
|
||||
"ext-sockets": "To use client-side monitoring"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/functions.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Aws\\": "src/"
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"src/data/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"Apache-2.0"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Amazon Web Services",
|
||||
"homepage": "http://aws.amazon.com"
|
||||
}
|
||||
],
|
||||
"description": "AWS SDK for PHP - Use Amazon Web Services in your PHP project",
|
||||
"homepage": "http://aws.amazon.com/sdkforphp",
|
||||
"keywords": [
|
||||
"amazon",
|
||||
"aws",
|
||||
"cloud",
|
||||
"dynamodb",
|
||||
"ec2",
|
||||
"glacier",
|
||||
"s3",
|
||||
"sdk"
|
||||
],
|
||||
"support": {
|
||||
"forum": "https://github.com/aws/aws-sdk-php/discussions",
|
||||
"issues": "https://github.com/aws/aws-sdk-php/issues",
|
||||
"source": "https://github.com/aws/aws-sdk-php/tree/3.369.19"
|
||||
},
|
||||
"time": "2026-01-23T19:05:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "bacon/bacon-qr-code",
|
||||
"version": "v3.0.3",
|
||||
|
|
@ -3154,16 +3305,16 @@
|
|||
},
|
||||
{
|
||||
"name": "league/flysystem",
|
||||
"version": "3.30.2",
|
||||
"version": "3.31.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/flysystem.git",
|
||||
"reference": "5966a8ba23e62bdb518dd9e0e665c2dbd4b5b277"
|
||||
"reference": "1717e0b3642b0df65ecb0cc89cdd99fa840672ff"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/5966a8ba23e62bdb518dd9e0e665c2dbd4b5b277",
|
||||
"reference": "5966a8ba23e62bdb518dd9e0e665c2dbd4b5b277",
|
||||
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/1717e0b3642b0df65ecb0cc89cdd99fa840672ff",
|
||||
"reference": "1717e0b3642b0df65ecb0cc89cdd99fa840672ff",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -3231,22 +3382,77 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/thephpleague/flysystem/issues",
|
||||
"source": "https://github.com/thephpleague/flysystem/tree/3.30.2"
|
||||
"source": "https://github.com/thephpleague/flysystem/tree/3.31.0"
|
||||
},
|
||||
"time": "2025-11-10T17:13:11+00:00"
|
||||
"time": "2026-01-23T15:38:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/flysystem-local",
|
||||
"version": "3.30.2",
|
||||
"name": "league/flysystem-aws-s3-v3",
|
||||
"version": "3.31.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/flysystem-local.git",
|
||||
"reference": "ab4f9d0d672f601b102936aa728801dd1a11968d"
|
||||
"url": "https://github.com/thephpleague/flysystem-aws-s3-v3.git",
|
||||
"reference": "e36a2bc60b06332c92e4435047797ded352b446f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/ab4f9d0d672f601b102936aa728801dd1a11968d",
|
||||
"reference": "ab4f9d0d672f601b102936aa728801dd1a11968d",
|
||||
"url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/e36a2bc60b06332c92e4435047797ded352b446f",
|
||||
"reference": "e36a2bc60b06332c92e4435047797ded352b446f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"aws/aws-sdk-php": "^3.295.10",
|
||||
"league/flysystem": "^3.10.0",
|
||||
"league/mime-type-detection": "^1.0.0",
|
||||
"php": "^8.0.2"
|
||||
},
|
||||
"conflict": {
|
||||
"guzzlehttp/guzzle": "<7.0",
|
||||
"guzzlehttp/ringphp": "<1.1.1"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"League\\Flysystem\\AwsS3V3\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Frank de Jonge",
|
||||
"email": "info@frankdejonge.nl"
|
||||
}
|
||||
],
|
||||
"description": "AWS S3 filesystem adapter for Flysystem.",
|
||||
"keywords": [
|
||||
"Flysystem",
|
||||
"aws",
|
||||
"file",
|
||||
"files",
|
||||
"filesystem",
|
||||
"s3",
|
||||
"storage"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/thephpleague/flysystem-aws-s3-v3/tree/3.31.0"
|
||||
},
|
||||
"time": "2026-01-23T15:30:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/flysystem-local",
|
||||
"version": "3.31.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/flysystem-local.git",
|
||||
"reference": "2f669db18a4c20c755c2bb7d3a7b0b2340488079"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/2f669db18a4c20c755c2bb7d3a7b0b2340488079",
|
||||
"reference": "2f669db18a4c20c755c2bb7d3a7b0b2340488079",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -3280,9 +3486,9 @@
|
|||
"local"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/thephpleague/flysystem-local/tree/3.30.2"
|
||||
"source": "https://github.com/thephpleague/flysystem-local/tree/3.31.0"
|
||||
},
|
||||
"time": "2025-11-10T11:23:37+00:00"
|
||||
"time": "2026-01-23T15:30:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/mime-type-detection",
|
||||
|
|
@ -3997,6 +4203,72 @@
|
|||
],
|
||||
"time": "2026-01-02T08:56:05+00:00"
|
||||
},
|
||||
{
|
||||
"name": "mtdowling/jmespath.php",
|
||||
"version": "2.8.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jmespath/jmespath.php.git",
|
||||
"reference": "a2a865e05d5f420b50cc2f85bb78d565db12a6bc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/a2a865e05d5f420b50cc2f85bb78d565db12a6bc",
|
||||
"reference": "a2a865e05d5f420b50cc2f85bb78d565db12a6bc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2.5 || ^8.0",
|
||||
"symfony/polyfill-mbstring": "^1.17"
|
||||
},
|
||||
"require-dev": {
|
||||
"composer/xdebug-handler": "^3.0.3",
|
||||
"phpunit/phpunit": "^8.5.33"
|
||||
},
|
||||
"bin": [
|
||||
"bin/jp.php"
|
||||
],
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.8-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/JmesPath.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"JmesPath\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Graham Campbell",
|
||||
"email": "hello@gjcampbell.co.uk",
|
||||
"homepage": "https://github.com/GrahamCampbell"
|
||||
},
|
||||
{
|
||||
"name": "Michael Dowling",
|
||||
"email": "mtdowling@gmail.com",
|
||||
"homepage": "https://github.com/mtdowling"
|
||||
}
|
||||
],
|
||||
"description": "Declaratively specify how to extract elements from a JSON document",
|
||||
"keywords": [
|
||||
"json",
|
||||
"jsonpath"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/jmespath/jmespath.php/issues",
|
||||
"source": "https://github.com/jmespath/jmespath.php/tree/2.8.0"
|
||||
},
|
||||
"time": "2024-09-04T18:46:31+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nesbot/carbon",
|
||||
"version": "3.11.0",
|
||||
|
|
@ -6940,6 +7212,76 @@
|
|||
],
|
||||
"time": "2024-09-25T14:21:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/filesystem",
|
||||
"version": "v7.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/filesystem.git",
|
||||
"reference": "d551b38811096d0be9c4691d406991b47c0c630a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/filesystem/zipball/d551b38811096d0be9c4691d406991b47c0c630a",
|
||||
"reference": "d551b38811096d0be9c4691d406991b47c0c630a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.2",
|
||||
"symfony/polyfill-ctype": "~1.8",
|
||||
"symfony/polyfill-mbstring": "~1.8"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/process": "^6.4|^7.0|^8.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\Filesystem\\": ""
|
||||
},
|
||||
"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": "Provides basic utilities for the filesystem",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/filesystem/tree/v7.4.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": "2025-11-27T13:27:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/finder",
|
||||
"version": "v7.4.3",
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ return [
|
|||
'public' => [
|
||||
'driver' => 'local',
|
||||
'root' => storage_path('app/public'),
|
||||
'url' => env('APP_URL').'/storage',
|
||||
'url' => env('APP_URL') . '/storage',
|
||||
'visibility' => 'public',
|
||||
'throw' => false,
|
||||
'report' => false,
|
||||
|
|
@ -53,6 +53,7 @@ return [
|
|||
'secret' => env('AWS_SECRET_ACCESS_KEY'),
|
||||
'region' => env('AWS_DEFAULT_REGION'),
|
||||
'bucket' => env('AWS_BUCKET'),
|
||||
'root' => env('AWS_DIRECTORY', ''),
|
||||
'url' => env('AWS_URL'),
|
||||
'endpoint' => env('AWS_ENDPOINT'),
|
||||
'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false),
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ return [
|
|||
'key' => env('AWS_ACCESS_KEY_ID'),
|
||||
'secret' => env('AWS_SECRET_ACCESS_KEY'),
|
||||
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
|
||||
'directory' => env('AWS_DIRECTORY'),
|
||||
],
|
||||
|
||||
'slack' => [
|
||||
|
|
|
|||
|
|
@ -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->string('type')->nullable()->default('article')->after('title');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('entries', function (Blueprint $table) {
|
||||
$table->dropColumn('type');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
@ -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->integer('priority')->default(0);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('entries', function (Blueprint $table) {
|
||||
$table->dropColumn('priority');
|
||||
});
|
||||
}
|
||||
};
|
||||
2
package-lock.json
generated
2
package-lock.json
generated
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "share-lt",
|
||||
"name": "share-lt-recovery-zone",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ use App\Models\Entry;
|
|||
it('has correct fillable attributes', function () {
|
||||
$expected = [
|
||||
'title',
|
||||
'type',
|
||||
'slug',
|
||||
'description',
|
||||
'is_published',
|
||||
|
|
@ -13,6 +14,8 @@ it('has correct fillable attributes', function () {
|
|||
'content',
|
||||
'call_to_action_link',
|
||||
'call_to_action_text',
|
||||
'category_id',
|
||||
'priority',
|
||||
];
|
||||
|
||||
$entry = new Entry;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue