Save local changes before merge
This commit is contained in:
@@ -0,0 +1,246 @@
|
||||
<?php
|
||||
|
||||
namespace Paymenter\Extensions\Others\SocialBase\Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use App\Models\User;
|
||||
use Paymenter\Extensions\Others\SocialBase\Models\UserProfile;
|
||||
use Paymenter\Extensions\Others\SocialBase\Models\Conversation;
|
||||
use Paymenter\Extensions\Others\SocialBase\Models\Message;
|
||||
use Paymenter\Extensions\Others\SocialBase\Models\ProfileComment;
|
||||
use Paymenter\Extensions\Others\SocialBase\Models\Reaction;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class SocialBaseSeeder extends Seeder
|
||||
{
|
||||
private $users;
|
||||
private $profiles;
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
$this->command->info('Seeding SocialBase data...');
|
||||
|
||||
// Initialize collections
|
||||
$this->users = collect();
|
||||
$this->profiles = collect();
|
||||
|
||||
// Create 10 fake users
|
||||
$this->createUsers();
|
||||
|
||||
// Create user profiles
|
||||
$this->createUserProfiles();
|
||||
|
||||
// Create conversations and messages
|
||||
$this->createConversations();
|
||||
|
||||
// Create profile comments
|
||||
$this->createProfileComments();
|
||||
|
||||
// Create reactions
|
||||
$this->createReactions();
|
||||
|
||||
$this->command->info('SocialBase seeding completed!');
|
||||
}
|
||||
|
||||
private function createUsers(): void
|
||||
{
|
||||
$this->command->info('Creating 10 fake users...');
|
||||
|
||||
$names = [
|
||||
['John', 'Doe', 'john.doe@example.com'],
|
||||
['Jane', 'Smith', 'jane.smith@example.com'],
|
||||
['Mike', 'Johnson', 'mike.johnson@example.com'],
|
||||
['Sarah', 'Williams', 'sarah.williams@example.com'],
|
||||
['David', 'Brown', 'david.brown@example.com'],
|
||||
['Emily', 'Davis', 'emily.davis@example.com'],
|
||||
['James', 'Wilson', 'james.wilson@example.com'],
|
||||
['Lisa', 'Anderson', 'lisa.anderson@example.com'],
|
||||
['Robert', 'Taylor', 'robert.taylor@example.com'],
|
||||
['Jennifer', 'Moore', 'jennifer.moore@example.com'],
|
||||
];
|
||||
|
||||
foreach ($names as [$firstName, $lastName, $email]) {
|
||||
// Check if user already exists
|
||||
$user = User::where('email', $email)->first();
|
||||
|
||||
if (!$user) {
|
||||
$user = User::create([
|
||||
'first_name' => $firstName,
|
||||
'last_name' => $lastName,
|
||||
'email' => $email,
|
||||
'password' => Hash::make('password'),
|
||||
'email_verified_at' => now(),
|
||||
]);
|
||||
}
|
||||
|
||||
$this->users->push($user);
|
||||
}
|
||||
}
|
||||
|
||||
private function createUserProfiles(): void
|
||||
{
|
||||
$this->command->info('Creating user profiles...');
|
||||
|
||||
$bios = [
|
||||
'Tech enthusiast and developer. Love coding and building cool stuff! 🚀',
|
||||
'Gamer, streamer, and community builder. Let\'s connect!',
|
||||
'Web developer by day, gamer by night. Always learning something new.',
|
||||
'Passionate about technology and innovation. Open to collaboration!',
|
||||
'Full-stack developer. Coffee addict. Dog lover. 🐕',
|
||||
'Designer and developer. Creating beautiful digital experiences.',
|
||||
'System administrator and DevOps engineer. Infrastructure is my passion.',
|
||||
'Frontend developer specializing in React and Vue. UI/UX enthusiast.',
|
||||
'Backend developer working with Laravel and Node.js. API expert.',
|
||||
'Community manager and content creator. Let\'s grow together!',
|
||||
];
|
||||
|
||||
$locations = ['New York, USA', 'London, UK', 'Toronto, Canada', 'Sydney, Australia', 'Berlin, Germany', 'Tokyo, Japan', 'Paris, France', 'Amsterdam, Netherlands', 'Singapore', 'Dubai, UAE'];
|
||||
$websites = ['https://johndoe.dev', 'https://janesmith.io', 'https://mikej.dev', 'https://sarahw.com', 'https://davidb.dev', 'https://emilyd.design', 'https://jamesw.tech', 'https://lisaa.io', 'https://robertt.dev', 'https://jenniferm.com'];
|
||||
|
||||
foreach ($this->users as $index => $user) {
|
||||
$profile = UserProfile::where('user_id', $user->id)->first();
|
||||
|
||||
if (!$profile) {
|
||||
$profile = UserProfile::create([
|
||||
'user_id' => $user->id,
|
||||
'display_name' => $user->first_name . ' ' . $user->last_name,
|
||||
'bio' => $bios[$index],
|
||||
'location' => $locations[$index],
|
||||
'website' => $websites[$index],
|
||||
'is_public' => true,
|
||||
'show_email' => false,
|
||||
'show_joined_date' => true,
|
||||
'allow_comments' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
$this->profiles->push($profile);
|
||||
}
|
||||
}
|
||||
|
||||
private function createConversations(): void
|
||||
{
|
||||
$this->command->info('Creating conversations and messages...');
|
||||
|
||||
// Create 5 conversations
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
$user1 = $this->users->random();
|
||||
$user2 = $this->users->random();
|
||||
|
||||
// Don't create conversation with self
|
||||
if ($user1->id === $user2->id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$conversation = Conversation::create([
|
||||
'type' => 'direct',
|
||||
'last_message_at' => now(),
|
||||
'created_by' => $user1->id,
|
||||
]);
|
||||
|
||||
// Add participants
|
||||
$conversation->participants()->attach($user1->id);
|
||||
$conversation->participants()->attach($user2->id);
|
||||
|
||||
// Create 3-7 messages
|
||||
$messageCount = rand(3, 7);
|
||||
$messages = [
|
||||
'Hey! How are you doing?',
|
||||
'I\'m great, thanks for asking! How about you?',
|
||||
'Pretty good! Just working on some cool projects.',
|
||||
'That sounds awesome! What are you working on?',
|
||||
'Building a forum system with Laravel. It\'s coming along nicely!',
|
||||
'Nice! I\'d love to hear more about it.',
|
||||
'Sure! Let me know when you have time to chat.',
|
||||
];
|
||||
|
||||
for ($j = 0; $j < $messageCount && $j < count($messages); $j++) {
|
||||
$sender = $j % 2 === 0 ? $user1 : $user2;
|
||||
|
||||
Message::create([
|
||||
'conversation_id' => $conversation->id,
|
||||
'sender_id' => $sender->id,
|
||||
'content' => $messages[$j],
|
||||
'created_at' => now()->subMinutes($messageCount - $j),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// Create 1 group conversation
|
||||
$groupUsers = $this->users->take(5);
|
||||
|
||||
$groupConversation = Conversation::create([
|
||||
'type' => 'group',
|
||||
'subject' => 'Tech Enthusiasts',
|
||||
'last_message_at' => now(),
|
||||
'created_by' => $groupUsers->first()->id,
|
||||
]);
|
||||
|
||||
foreach ($groupUsers as $user) {
|
||||
$groupConversation->participants()->attach($user->id);
|
||||
}
|
||||
|
||||
// Add some group messages
|
||||
$groupMessages = [
|
||||
'Welcome to the group everyone!',
|
||||
'Hey! Excited to be here!',
|
||||
'Thanks for adding me!',
|
||||
'Looking forward to great discussions!',
|
||||
];
|
||||
|
||||
foreach ($groupMessages as $index => $content) {
|
||||
Message::create([
|
||||
'conversation_id' => $groupConversation->id,
|
||||
'sender_id' => $groupUsers->get($index % $groupUsers->count())->id,
|
||||
'content' => $content,
|
||||
'created_at' => now()->subMinutes(count($groupMessages) - $index),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function createProfileComments(): void
|
||||
{
|
||||
$this->command->info('Creating profile comments...');
|
||||
|
||||
$comments = [
|
||||
'Great profile! Love your work!',
|
||||
'Hey! Just wanted to say hi 👋',
|
||||
'Your projects are amazing!',
|
||||
'Let\'s collaborate sometime!',
|
||||
'Awesome bio! We have similar interests.',
|
||||
'Thanks for being part of the community!',
|
||||
];
|
||||
|
||||
// Create 10-15 random profile comments
|
||||
for ($i = 0; $i < rand(10, 15); $i++) {
|
||||
$commenter = $this->users->random();
|
||||
$profileOwner = $this->profiles->random();
|
||||
|
||||
// Don't comment on own profile
|
||||
if ($commenter->id === $profileOwner->user_id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ProfileComment::create([
|
||||
'user_profile_id' => $profileOwner->id,
|
||||
'user_id' => $commenter->id,
|
||||
'content' => $comments[array_rand($comments)],
|
||||
'approved' => 1, // Auto-approve seeded comments
|
||||
'created_at' => now()->subDays(rand(0, 30)),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function createReactions(): void
|
||||
{
|
||||
$this->command->info('Creating reactions...');
|
||||
|
||||
$reactionTypes = ['like', 'love', 'fire', 'celebrate', 'thinking'];
|
||||
$comments = ProfileComment::all();
|
||||
|
||||
// Add reactions to random comments (simplified to avoid duplicates)
|
||||
$this->command->info('Skipping reactions to avoid duplicate key constraints in this demo...');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
Schema::create('ext_social_user_profiles', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('user_id')->constrained()->onDelete('cascade');
|
||||
$table->string('display_name')->nullable();
|
||||
$table->text('bio')->nullable();
|
||||
$table->string('location')->nullable();
|
||||
$table->string('website')->nullable();
|
||||
$table->string('avatar_path')->nullable();
|
||||
$table->string('banner_path')->nullable();
|
||||
$table->boolean('is_public')->default(true);
|
||||
$table->boolean('show_email')->default(false);
|
||||
$table->boolean('show_joined_date')->default(true);
|
||||
$table->boolean('allow_comments')->default(true);
|
||||
$table->json('metadata')->nullable();
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
|
||||
// Indexes
|
||||
$table->index(['user_id']);
|
||||
$table->index(['is_public']);
|
||||
$table->index(['created_at']);
|
||||
|
||||
// Unique constraint to ensure one profile per user
|
||||
$table->unique(['user_id']);
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('ext_social_user_profiles');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,48 @@
|
||||
<?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('ext_social_user_profiles', function (Blueprint $table) {
|
||||
// Add restriction columns
|
||||
$table->boolean('is_banned')->default(false)->after('allow_comments');
|
||||
$table->boolean('upload_restricted')->default(false)->after('is_banned');
|
||||
$table->boolean('comment_restricted')->default(false)->after('upload_restricted');
|
||||
$table->boolean('profile_edit_restricted')->default(false)->after('comment_restricted');
|
||||
|
||||
// Add restriction reason and level
|
||||
$table->text('restriction_reason')->nullable()->after('profile_edit_restricted');
|
||||
$table->enum('restriction_level', ['none', 'warning', 'limited', 'suspended', 'banned'])
|
||||
->default('none')->after('restriction_reason');
|
||||
|
||||
// Add theme column
|
||||
$table->string('theme', 50)->default('default')->after('restriction_level');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('ext_social_user_profiles', function (Blueprint $table) {
|
||||
$table->dropColumn([
|
||||
'is_banned',
|
||||
'upload_restricted',
|
||||
'comment_restricted',
|
||||
'profile_edit_restricted',
|
||||
'restriction_reason',
|
||||
'restriction_level',
|
||||
'theme'
|
||||
]);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
Schema::create('ext_social_profile_comments', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('user_profile_id')->constrained('ext_social_user_profiles')->onDelete('cascade');
|
||||
$table->foreignId('user_id')->constrained()->onDelete('cascade');
|
||||
$table->foreignId('parent_id')->nullable()->constrained('ext_social_profile_comments')->onDelete('cascade');
|
||||
$table->text('content');
|
||||
$table->boolean('approved')->default(false);
|
||||
$table->json('metadata')->nullable();
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
|
||||
// Indexes
|
||||
$table->index(['user_profile_id', 'approved']);
|
||||
$table->index(['user_id']);
|
||||
$table->index(['parent_id']);
|
||||
$table->index(['created_at']);
|
||||
$table->index(['approved']);
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('ext_social_profile_comments');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,35 @@
|
||||
<?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('ext_social_comment_reactions', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('profile_comment_id')->constrained('ext_social_profile_comments')->onDelete('cascade');
|
||||
$table->foreignId('user_id')->constrained()->onDelete('cascade');
|
||||
$table->string('type', 20); // like, love, laugh, angry, sad, etc.
|
||||
$table->timestamps();
|
||||
|
||||
// Prevent duplicate reactions from same user on same comment
|
||||
$table->unique(['profile_comment_id', 'user_id']);
|
||||
|
||||
$table->index(['profile_comment_id', 'type']);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('ext_social_comment_reactions');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,39 @@
|
||||
<?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('ext_social_reactions', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('reactable_type'); // Model class name (e.g., ProfileComment, ForumPost, etc.)
|
||||
$table->unsignedBigInteger('reactable_id'); // Model ID
|
||||
$table->foreignId('user_id')->constrained()->onDelete('cascade');
|
||||
$table->string('type', 20); // like, love, laugh, angry, sad, etc.
|
||||
$table->timestamps();
|
||||
|
||||
// Prevent duplicate reactions from same user on same item
|
||||
$table->unique(['reactable_type', 'reactable_id', 'user_id']);
|
||||
|
||||
// Optimize queries
|
||||
$table->index(['reactable_type', 'reactable_id']);
|
||||
$table->index(['reactable_type', 'reactable_id', 'type']);
|
||||
$table->index(['user_id', 'type']);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('ext_social_reactions');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
// Migrate existing comment reactions to the generic reactions table
|
||||
$commentReactions = DB::table('ext_social_comment_reactions')->get();
|
||||
|
||||
foreach ($commentReactions as $reaction) {
|
||||
DB::table('ext_social_reactions')->insert([
|
||||
'reactable_type' => 'Paymenter\\Extensions\\Others\\SocialBase\\Models\\ProfileComment',
|
||||
'reactable_id' => $reaction->profile_comment_id,
|
||||
'user_id' => $reaction->user_id,
|
||||
'type' => $reaction->type,
|
||||
'created_at' => $reaction->created_at,
|
||||
'updated_at' => $reaction->updated_at,
|
||||
]);
|
||||
}
|
||||
|
||||
// Drop the old comment-specific reactions table
|
||||
Schema::dropIfExists('ext_social_comment_reactions');
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
// Recreate the old comment reactions table
|
||||
Schema::create('ext_social_comment_reactions', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('profile_comment_id')->constrained('ext_social_profile_comments')->onDelete('cascade');
|
||||
$table->foreignId('user_id')->constrained()->onDelete('cascade');
|
||||
$table->string('type', 20);
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['profile_comment_id', 'user_id']);
|
||||
$table->index(['profile_comment_id', 'type']);
|
||||
});
|
||||
|
||||
// Migrate data back from generic reactions table
|
||||
$genericReactions = DB::table('ext_social_reactions')
|
||||
->where('reactable_type', 'Paymenter\\Extensions\\Others\\SocialBase\\Models\\ProfileComment')
|
||||
->get();
|
||||
|
||||
foreach ($genericReactions as $reaction) {
|
||||
DB::table('ext_social_comment_reactions')->insert([
|
||||
'profile_comment_id' => $reaction->reactable_id,
|
||||
'user_id' => $reaction->user_id,
|
||||
'type' => $reaction->type,
|
||||
'created_at' => $reaction->created_at,
|
||||
'updated_at' => $reaction->updated_at,
|
||||
]);
|
||||
}
|
||||
|
||||
// Remove the generic reactions for comments
|
||||
DB::table('ext_social_reactions')
|
||||
->where('reactable_type', 'Paymenter\\Extensions\\Others\\SocialBase\\Models\\ProfileComment')
|
||||
->delete();
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('ext_social_user_profiles', function (Blueprint $table) {
|
||||
// Change default value for is_public to false (private by default)
|
||||
$table->boolean('is_public')->default(false)->change();
|
||||
});
|
||||
|
||||
// Update existing profiles to be private if they haven't been set up
|
||||
DB::table('ext_social_user_profiles')
|
||||
->whereNull('display_name')
|
||||
->whereNull('bio')
|
||||
->whereNull('avatar_path')
|
||||
->whereNull('banner_path')
|
||||
->update(['is_public' => false]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('ext_social_user_profiles', function (Blueprint $table) {
|
||||
$table->boolean('is_public')->default(true)->change();
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
// Conversations table
|
||||
Schema::create('ext_social_conversations', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('type')->default('direct'); // direct, group, system
|
||||
$table->string('subject')->nullable();
|
||||
$table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
|
||||
$table->timestamp('last_message_at')->nullable();
|
||||
$table->json('metadata')->nullable();
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
|
||||
$table->index('type');
|
||||
$table->index('last_message_at');
|
||||
});
|
||||
|
||||
// Conversation participants
|
||||
Schema::create('ext_social_conversation_participants', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('conversation_id')->constrained('ext_social_conversations')->cascadeOnDelete();
|
||||
$table->foreignId('user_id')->constrained('users')->cascadeOnDelete();
|
||||
$table->timestamp('last_read_at')->nullable();
|
||||
$table->boolean('is_muted')->default(false);
|
||||
$table->boolean('is_archived')->default(false);
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['conversation_id', 'user_id'], 'social_conv_part_unique');
|
||||
$table->index('user_id');
|
||||
});
|
||||
|
||||
// Messages table
|
||||
Schema::create('ext_social_messages', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('conversation_id')->constrained('ext_social_conversations')->cascadeOnDelete();
|
||||
$table->foreignId('sender_id')->nullable()->constrained('users')->nullOnDelete();
|
||||
$table->text('content');
|
||||
$table->string('type')->default('text'); // text, system, notification
|
||||
$table->boolean('is_system')->default(false);
|
||||
$table->string('system_type')->nullable(); // order_update, payment_received, etc.
|
||||
$table->json('metadata')->nullable();
|
||||
$table->boolean('is_moderated')->default(false);
|
||||
$table->string('moderation_status')->nullable(); // approved, flagged, deleted
|
||||
$table->foreignId('moderated_by')->nullable()->constrained('users')->nullOnDelete();
|
||||
$table->timestamp('moderated_at')->nullable();
|
||||
$table->text('moderation_reason')->nullable();
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
|
||||
$table->index('conversation_id');
|
||||
$table->index('sender_id');
|
||||
$table->index('is_system');
|
||||
$table->index('moderation_status');
|
||||
$table->index('created_at');
|
||||
});
|
||||
|
||||
// Message read receipts
|
||||
Schema::create('ext_social_message_reads', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('message_id')->constrained('ext_social_messages')->cascadeOnDelete();
|
||||
$table->foreignId('user_id')->constrained('users')->cascadeOnDelete();
|
||||
$table->timestamp('read_at');
|
||||
|
||||
$table->unique(['message_id', 'user_id']);
|
||||
$table->index('user_id');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('ext_social_message_reads');
|
||||
Schema::dropIfExists('ext_social_messages');
|
||||
Schema::dropIfExists('ext_social_conversation_participants');
|
||||
Schema::dropIfExists('ext_social_conversations');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
// Check if column doesn't exist before adding
|
||||
if (!Schema::hasColumn('ext_social_conversations', 'created_by')) {
|
||||
Schema::table('ext_social_conversations', function (Blueprint $table) {
|
||||
$table->foreignId('created_by')->nullable()->after('subject')->constrained('users')->nullOnDelete();
|
||||
});
|
||||
}
|
||||
|
||||
if (!Schema::hasColumn('ext_social_conversations', 'last_message_at')) {
|
||||
Schema::table('ext_social_conversations', function (Blueprint $table) {
|
||||
$table->timestamp('last_message_at')->nullable()->after('created_by');
|
||||
});
|
||||
}
|
||||
|
||||
if (!Schema::hasColumn('ext_social_conversations', 'metadata')) {
|
||||
Schema::table('ext_social_conversations', function (Blueprint $table) {
|
||||
$table->json('metadata')->nullable()->after('last_message_at');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('ext_social_conversations', function (Blueprint $table) {
|
||||
if (Schema::hasColumn('ext_social_conversations', 'created_by')) {
|
||||
$table->dropForeign(['created_by']);
|
||||
$table->dropColumn('created_by');
|
||||
}
|
||||
if (Schema::hasColumn('ext_social_conversations', 'last_message_at')) {
|
||||
$table->dropColumn('last_message_at');
|
||||
}
|
||||
if (Schema::hasColumn('ext_social_conversations', 'metadata')) {
|
||||
$table->dropColumn('metadata');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
// Drop existing tables in correct order (respecting foreign keys)
|
||||
Schema::dropIfExists('ext_social_message_reads');
|
||||
Schema::dropIfExists('ext_social_messages');
|
||||
Schema::dropIfExists('ext_social_conversation_participants');
|
||||
Schema::dropIfExists('ext_social_conversations');
|
||||
|
||||
// Recreate conversations table
|
||||
Schema::create('ext_social_conversations', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('type')->default('direct'); // direct, group, system
|
||||
$table->string('subject')->nullable();
|
||||
$table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
|
||||
$table->timestamp('last_message_at')->nullable();
|
||||
$table->json('metadata')->nullable();
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
|
||||
$table->index('type');
|
||||
$table->index('last_message_at');
|
||||
});
|
||||
|
||||
// Conversation participants
|
||||
Schema::create('ext_social_conversation_participants', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('conversation_id')->constrained('ext_social_conversations')->cascadeOnDelete();
|
||||
$table->foreignId('user_id')->constrained('users')->cascadeOnDelete();
|
||||
$table->timestamp('last_read_at')->nullable();
|
||||
$table->boolean('is_muted')->default(false);
|
||||
$table->boolean('is_archived')->default(false);
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['conversation_id', 'user_id'], 'conv_participant_unique');
|
||||
$table->index('user_id');
|
||||
});
|
||||
|
||||
// Messages table
|
||||
Schema::create('ext_social_messages', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('conversation_id')->constrained('ext_social_conversations')->cascadeOnDelete();
|
||||
$table->foreignId('sender_id')->nullable()->constrained('users')->nullOnDelete();
|
||||
$table->text('content');
|
||||
$table->string('type')->default('text'); // text, system, notification
|
||||
$table->boolean('is_system')->default(false);
|
||||
$table->string('system_type')->nullable(); // order_update, payment_received, etc.
|
||||
$table->json('metadata')->nullable();
|
||||
$table->boolean('is_moderated')->default(false);
|
||||
$table->string('moderation_status')->nullable(); // approved, flagged, deleted
|
||||
$table->foreignId('moderated_by')->nullable()->constrained('users')->nullOnDelete();
|
||||
$table->timestamp('moderated_at')->nullable();
|
||||
$table->text('moderation_reason')->nullable();
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
|
||||
$table->index('conversation_id');
|
||||
$table->index('sender_id');
|
||||
$table->index('is_system');
|
||||
$table->index('moderation_status');
|
||||
$table->index('created_at');
|
||||
});
|
||||
|
||||
// Message read receipts
|
||||
Schema::create('ext_social_message_reads', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('message_id')->constrained('ext_social_messages')->cascadeOnDelete();
|
||||
$table->foreignId('user_id')->constrained('users')->cascadeOnDelete();
|
||||
$table->timestamp('read_at');
|
||||
|
||||
$table->unique(['message_id', 'user_id'], 'message_read_unique');
|
||||
$table->index('user_id');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('ext_social_message_reads');
|
||||
Schema::dropIfExists('ext_social_messages');
|
||||
Schema::dropIfExists('ext_social_conversation_participants');
|
||||
Schema::dropIfExists('ext_social_conversations');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('ext_social_message_reports', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('message_id')->constrained('ext_social_messages')->cascadeOnDelete();
|
||||
$table->foreignId('reported_by')->constrained('users')->cascadeOnDelete();
|
||||
$table->string('reason');
|
||||
$table->text('description')->nullable();
|
||||
$table->string('status')->default('pending'); // pending, reviewed, dismissed
|
||||
$table->foreignId('reviewed_by')->nullable()->constrained('users')->nullOnDelete();
|
||||
$table->timestamp('reviewed_at')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['message_id', 'reported_by']);
|
||||
$table->index('status');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('ext_social_message_reports');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('ext_social_user_profiles', function (Blueprint $table) {
|
||||
$table->string('moderation_status')->default('active')->after('allow_comments');
|
||||
$table->text('moderation_notes')->nullable()->after('moderation_status');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('ext_social_user_profiles', function (Blueprint $table) {
|
||||
$table->dropColumn(['moderation_status', 'moderation_notes']);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('ext_social_user_reports', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('reported_user_id')->constrained('users')->onDelete('cascade');
|
||||
$table->foreignId('reported_by')->constrained('users')->onDelete('cascade');
|
||||
$table->string('reason'); // harassment, spam, inappropriate, impersonation, other
|
||||
$table->text('description')->nullable();
|
||||
$table->enum('status', ['pending', 'reviewed', 'dismissed'])->default('pending');
|
||||
$table->foreignId('reviewed_by')->nullable()->constrained('users')->onDelete('set null');
|
||||
$table->timestamp('reviewed_at')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
// Prevent duplicate reports
|
||||
$table->unique(['reported_user_id', 'reported_by', 'reason'], 'user_report_unique');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('ext_social_user_reports');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
Schema::table('ext_social_user_reports', function (Blueprint $table) {
|
||||
$table->text('admin_notes')->nullable()->after('status');
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
Schema::table('ext_social_user_reports', function (Blueprint $table) {
|
||||
$table->dropColumn('admin_notes');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
// Change the enum to support the new status values
|
||||
DB::statement("ALTER TABLE `ext_social_user_reports` MODIFY `status` VARCHAR(50) NOT NULL DEFAULT 'pending'");
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
DB::statement("ALTER TABLE `ext_social_user_reports` MODIFY `status` ENUM('pending', 'reviewed', 'dismissed') NOT NULL DEFAULT 'pending'");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
Schema::table('ext_social_messages', function (Blueprint $table) {
|
||||
$table->json('attachments')->nullable()->after('content');
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
Schema::table('ext_social_messages', function (Blueprint $table) {
|
||||
$table->dropColumn('attachments');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
Schema::table('ext_social_conversation_participants', function (Blueprint $table) {
|
||||
$table->boolean('is_pinned')->default(false)->after('is_archived');
|
||||
$table->index('is_pinned');
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
Schema::table('ext_social_conversation_participants', function (Blueprint $table) {
|
||||
$table->dropColumn('is_pinned');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use Paymenter\Extensions\Others\UptimeLab\Models\UptimeServer;
|
||||
|
||||
class UptimeServerSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
$servers = [
|
||||
[
|
||||
'name' => 'Web Server 01',
|
||||
'ip_address' => '192.168.1.10',
|
||||
'server_type' => 'ip',
|
||||
'location' => 'Jakarta, Indonesia',
|
||||
'is_active' => true,
|
||||
'status' => 'online',
|
||||
'uptime_percentage' => 99.8,
|
||||
'last_online' => now(),
|
||||
'last_offline' => now()->subHours(6),
|
||||
'last_check' => now(),
|
||||
'response_time' => 15,
|
||||
],
|
||||
[
|
||||
'name' => 'Main Database Server',
|
||||
'ip_address' => '192.168.1.20',
|
||||
'server_type' => 'ip',
|
||||
'location' => 'Surabaya, Indonesia',
|
||||
'is_active' => true,
|
||||
'status' => 'offline',
|
||||
'uptime_percentage' => 100.0,
|
||||
'last_online' => now()->subHours(5),
|
||||
'last_offline' => now(),
|
||||
'last_check' => now(),
|
||||
'response_time' => null,
|
||||
],
|
||||
[
|
||||
'name' => 'API Gateway',
|
||||
'ip_address' => 'api.example.com',
|
||||
'server_type' => 'subdomain',
|
||||
'location' => 'Bandung, Indonesia',
|
||||
'is_active' => true,
|
||||
'status' => 'online',
|
||||
'uptime_percentage' => 99.9,
|
||||
'last_online' => now()->subHours(6),
|
||||
'last_offline' => now()->subHours(5),
|
||||
'last_check' => now(),
|
||||
'response_time' => 25,
|
||||
],
|
||||
[
|
||||
'name' => 'Load Balancer',
|
||||
'ip_address' => '192.168.1.40',
|
||||
'server_type' => 'ip',
|
||||
'location' => 'Jakarta, Indonesia',
|
||||
'is_active' => true,
|
||||
'status' => 'online',
|
||||
'uptime_percentage' => 99.99,
|
||||
'last_online' => now(),
|
||||
'last_offline' => now()->subHours(6),
|
||||
'last_check' => now(),
|
||||
'response_time' => 8,
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($servers as $serverData) {
|
||||
UptimeServer::create($serverData);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?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('ext_uptime_servers', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->string('ip_address');
|
||||
$table->string('server_type')->default('ip'); // ip or subdomain
|
||||
$table->string('location');
|
||||
$table->string('type')->default('Production'); // Production, Staging, Development
|
||||
$table->boolean('is_active')->default(true);
|
||||
$table->string('status')->default('offline'); // online, offline
|
||||
$table->decimal('uptime_percentage', 5, 2)->default(0.00);
|
||||
$table->timestamp('last_online')->nullable();
|
||||
$table->timestamp('last_offline')->nullable();
|
||||
$table->timestamp('last_check')->nullable();
|
||||
$table->integer('response_time')->nullable(); // in milliseconds
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('ext_uptime_servers');
|
||||
}
|
||||
};
|
||||
@@ -17,7 +17,7 @@
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Paymenter\\Extensions\\Others\\UptimeLab\\": ""
|
||||
"Paymenter\\Extensions\\Others\\UptimeLab\\": "extensions/Others/UptimeLab/"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace Paymenter\Extensions\Others\UptimeLab\Database\Seeders;
|
||||
use Illuminate\Database\Seeder;
|
||||
use Paymenter\Extensions\Others\UptimeLab\Models\UptimeServer;
|
||||
|
||||
class UptimeServerSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
$servers = [
|
||||
[
|
||||
'name' => 'Web Server 01',
|
||||
'ip_address' => '192.168.1.10',
|
||||
'server_type' => 'ip',
|
||||
'location' => 'Jakarta, Indonesia',
|
||||
'is_active' => true,
|
||||
'status' => 'online',
|
||||
'uptime_percentage' => 99.8,
|
||||
'last_online' => now(),
|
||||
'last_offline' => now()->subHours(6),
|
||||
'last_check' => now(),
|
||||
'response_time' => 15,
|
||||
],
|
||||
[
|
||||
'name' => 'Main Database Server',
|
||||
'ip_address' => '192.168.1.20',
|
||||
'server_type' => 'ip',
|
||||
'location' => 'Surabaya, Indonesia',
|
||||
'is_active' => true,
|
||||
'status' => 'offline',
|
||||
'uptime_percentage' => 100.0,
|
||||
'last_online' => now()->subHours(5),
|
||||
'last_offline' => now(),
|
||||
'last_check' => now(),
|
||||
'response_time' => null,
|
||||
],
|
||||
[
|
||||
'name' => 'API Gateway',
|
||||
'ip_address' => 'api.example.com',
|
||||
'server_type' => 'subdomain',
|
||||
'location' => 'Bandung, Indonesia',
|
||||
'is_active' => true,
|
||||
'status' => 'online',
|
||||
'uptime_percentage' => 99.9,
|
||||
'last_online' => now()->subHours(6),
|
||||
'last_offline' => now()->subHours(5),
|
||||
'last_check' => now(),
|
||||
'response_time' => 25,
|
||||
],
|
||||
[
|
||||
'name' => 'Load Balancer',
|
||||
'ip_address' => '192.168.1.40',
|
||||
'server_type' => 'ip',
|
||||
'location' => 'Jakarta, Indonesia',
|
||||
'is_active' => true,
|
||||
'status' => 'online',
|
||||
'uptime_percentage' => 99.99,
|
||||
'last_online' => now(),
|
||||
'last_offline' => now()->subHours(6),
|
||||
'last_check' => now(),
|
||||
'response_time' => 8,
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($servers as $serverData) {
|
||||
UptimeServer::create($serverData);
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
public/assets/images/glados.jpg
Normal file
BIN
public/assets/images/glados.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 840 KiB |
BIN
public/assets/images/logofresh.png
Normal file
BIN
public/assets/images/logofresh.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 60 KiB |
BIN
public/assets/mp3/glados.mp3
Normal file
BIN
public/assets/mp3/glados.mp3
Normal file
Binary file not shown.
Reference in New Issue
Block a user