Skip to content

Instantly share code, notes, and snippets.

@Ziad-Abaza
Last active July 5, 2025 21:26
Show Gist options
  • Save Ziad-Abaza/bef4411e445bf9040e49a70ef74dc150 to your computer and use it in GitHub Desktop.
Save Ziad-Abaza/bef4411e445bf9040e49a70ef74dc150 to your computer and use it in GitHub Desktop.
Borshama
[{"title":"How to Fix CSRF Issues and Deploy a Laravel Project on a Hosting Server","content":"### 1. Fixing CSRF Issues After Deployment\n\nWhen deploying a Laravel project to a server, CSRF (Cross-Site Request Forgery) issues can arise, especially when handling authentication with APIs. To resolve this:\n\n#### **Update Environment Configuration in `.env`**\n\nMake sure your environment settings are configured for production:\n\n```env\nAPP_ENV=prod\nAPP_URL=https://yourdomain.com\nSESSION_DOMAIN=.yourdomain.com\nSANCTUM_STATEFUL_DOMAINS=yourdomain.com\n```\n\n- **APP_URL**: Set this to the production URL of your app.\n- **SESSION_DOMAIN**: Set this to your domain (with a dot before it, for cookie sharing).\n- **SANCTUM_STATEFUL_DOMAINS**: Make sure it includes your domain to handle API requests with session cookies.\n\n#### **Update CORS Configuration**\n\nIn `config/cors.php`, adjust the CORS settings to allow requests from your frontend domain:\n\n```php\n'paths' => ['*'],\n'allowed_methods' => ['*'],\n'allowed_origins' => ['https://yourdomain.com'], // Your frontend URL\n'allowed_origins_patterns' => [],\n'allowed_headers' => ['*'],\n'exposed_headers' => [],\n'max_age' => 0,\n'supports_credentials' => true,\n```\n\n- **allowed_origins**: Ensure that the frontend domain (where React is hosted) is allowed to send requests.\n\n#### **Configure Session Settings**\n\nIn `config/session.php`, configure the session cookie to be secure:\n\n```php\n'secure' => env('SESSION_SECURE_COOKIE', true),\n```\n\nThis ensures that cookies are sent over HTTPS, preventing session hijacking.\n\n### 2. Deploying the Laravel Project on a Hosting Server\n\nHere’s how to deploy your Laravel application to a live server:\n\n#### **Upload the Project**\n\n1. **Upload Backend Files**: Transfer all files of your Laravel project to the backend directory of your server.\n2. **Upload Frontend Files**: After building the React app (using `npm run build`), upload the production files (from the `dist/` folder) to the public directory of the frontend.\n\n#### **Create a Symlink for `index.php`**\n\nInstead of copying the `index.php` file from the Laravel `public` folder to your server, create a symlink:\n\n```bash\nln -s /path/to/your/laravel-project/public/index.php /path/to/your/public_html/index.php\n```\n\nThis ensures that the `index.php` file from Laravel is accessible correctly.\n\n#### **Update `.htaccess` for React**\n\nFor React to handle routing correctly on the server, update the `.htaccess` file in the frontend directory as follows:\n\n```apache\n<IfModule mod_rewrite.c>\n RewriteEngine On\n\n # Disable MultiViews to prevent issues with extensions\n Options -MultiViews\n\n # Redirect Trailing Slashes If Not A Folder\n RewriteCond %{REQUEST_FILENAME} !-d\n RewriteCond %{REQUEST_URI} (.+)/$\n RewriteRule ^ %1 [L,R=301]\n\n # Allow Authorization Header\n RewriteCond %{HTTP:Authorization} .\n RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]\n\n # Send all requests to index.html if not an existing file or directory\n RewriteCond %{REQUEST_FILENAME} !-f\n RewriteCond %{REQUEST_FILENAME} !-d\n RewriteRule ^ index.html [L]\n</IfModule>\n```\n\nThis setup ensures that React routing works properly by redirecting all requests to `index.html`, except for real files or directories.\n\n### 3. Test Your Application\n\nOnce you've completed the deployment steps, access the frontend and backend on the server and test if everything is working correctly. Ensure that:\n\n- CSRF tokens are being sent correctly.\n- The frontend can communicate with the backend via API.\n- No CORS or session issues arise.\n\nThis should resolve CSRF issues and ensure that your Laravel project runs smoothly on the server.","timestamp":"2025-01-31T15:32:30.979Z","comments":[]},{"title":"Jobs & Observers in laravel","content":"### **Understanding Jobs and Observers in Laravel: A Simple Guide** \n\nIn Laravel, **Jobs** and **Observers** are powerful tools that help enhance the architecture of your application, making it more **efficient** and **scalable**. This guide will walk you through both concepts with a simple example and a detailed explanation. \n\n---\n\n## **What is a Job?** \n\nA **Job** in Laravel is a task that runs **asynchronously** (in the background) using the **queue system**. Jobs help execute time-consuming tasks without affecting the application's performance. \n\n### **Creating a Job** \n\nTo create a job, run the following command: \n```bash\nphp artisan make:job SendWelcomeNotificationJob\n```\nThis command generates a job file inside the `app/Jobs` directory. \n\n### **Job Structure** \n\n```php\nnamespace App\\Jobs;\n\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Foundation\\Queue\\Queueable;\nuse App\\Models\\User;\nuse App\\Models\\Notification;\nuse Illuminate\\Queue\\InteractsWithQueue;\nuse Illuminate\\Queue\\SerializesModels;\n\nclass SendWelcomeNotificationJob implements ShouldQueue\n{\n use InteractsWithQueue, Queueable, SerializesModels;\n\n protected $user;\n\n /**\n * Create a new job instance.\n */\n public function __construct(User $user)\n {\n $this->user = $user;\n }\n\n /**\n * Execute the job.\n */\n public function handle(): void\n {\n // Create a new notification for the user\n Notification::create([\n 'user_id' => $this->user->id,\n 'message' => 'Welcome to our application!',\n ]);\n }\n}\n```\n\n### **Breaking Down the Job Components** \n- **`ShouldQueue`**: Ensures that the job is executed via the queue system. \n- **`InteractsWithQueue`**: Allows interaction with the queue, such as delaying or retrying jobs. \n- **`Queueable`**: Provides queue-related properties and behavior to the job. \n- **`SerializesModels`**: Ensures that model instances (like `$user`) are serialized correctly when passed to a queued job. \n- **`handle()`**: The function that executes the job logic (in this case, creating a notification). \n\n### **Dispatching the Job** \n\nYou can dispatch this job in your application using: \n```php\nSendWelcomeNotificationJob::dispatch($user);\n```\nTo process queued jobs, run: \n```bash\nphp artisan queue:work\n```\n\n---\n\n## **What is an Observer?** \n\nAn **Observer** in Laravel is a design pattern that listens to **model events** and executes specific actions when an event occurs. This is useful for handling operations such as **creating**, **updating**, or **deleting** a model without cluttering your controller or model logic. \n\n### **Creating an Observer** \n\nRun the following command to create an observer: \n```bash\nphp artisan make:observer UserObserver --model=User\n```\nThis will create a new observer file inside the `app/Observers` directory. \n\n### **Observer Structure** \n\n```php\nnamespace App\\Observers;\n\nuse App\\Models\\User;\nuse App\\Jobs\\SendWelcomeNotificationJob;\n\nclass UserObserver\n{\n /**\n * Handle the User \"created\" event.\n */\n public function created(User $user)\n {\n // Dispatch the job to send a welcome notification\n SendWelcomeNotificationJob::dispatch($user);\n }\n\n /**\n * Handle the User \"updated\" event.\n */\n public function updated(User $user): void\n {\n //\n }\n\n /**\n * Handle the User \"deleted\" event.\n */\n public function deleted(User $user): void\n {\n //\n }\n\n /**\n * Handle the User \"restored\" event.\n */\n public function restored(User $user): void\n {\n //\n }\n\n /**\n * Handle the User \"force deleted\" event.\n */\n public function forceDeleted(User $user): void\n {\n //\n }\n}\n```\n\n### **Understanding the Observer Methods** \n- **`created(User $user)`**: Called when a new user is created. In this case, it triggers the welcome notification job. \n- **`updated(User $user)`**: Called when a user is updated. \n- **`deleted(User $user)`**: Called when a user is deleted. \n- **`restored(User $user)`**: Called when a soft-deleted user is restored. \n- **`forceDeleted(User $user)`**: Called when a user is permanently deleted. \n\n---\n\n## **Registering the Observer in Laravel** \n\nFor Laravel to recognize and use the observer, register it in `AppServiceProvider.php`: \n\n```php\nnamespace App\\Providers;\n\nuse Illuminate\\Support\\ServiceProvider;\nuse App\\Models\\User;\nuse App\\Observers\\UserObserver;\n\nclass AppServiceProvider extends ServiceProvider\n{\n public function boot(): void\n {\n // Register the UserObserver\n User::observe(UserObserver::class);\n }\n}\n```\n\nNow, whenever a new `User` record is created, Laravel will **automatically** trigger the `created()` method in `UserObserver`, which dispatches the `SendWelcomeNotificationJob`.\n\n---\n\n## **What are `InteractsWithQueue` and `SerializesModels`?** \n\n### **1. `InteractsWithQueue`**\n- This trait provides methods to **interact with the queue system**, allowing you to: \n - Retry a job \n - Delete a job manually \n - Delay a job execution \n\nFor example, you can delay the job execution like this: \n```php\nSendWelcomeNotificationJob::dispatch($user)->delay(now()->addMinutes(5));\n```\nThis will execute the job **5 minutes later** instead of immediately.\n\n---\n\n### **2. `SerializesModels`**\n- This trait ensures that when a **model** (such as `User`) is passed to a queued job, it is **serialized** correctly. \n- Without this, you might face errors related to **stale data** or **object references**. \n\n**Example Problem (Without `SerializesModels`)** \nImagine a scenario where:\n1. A job is dispatched for a `User` instance.\n2. The user record is updated in the database.\n3. When the job executes, it uses the **old user data** instead of the updated one.\n\n**Solution (With `SerializesModels`)** \nBy using `SerializesModels`, Laravel **automatically fetches the latest data** from the database when the job runs.\n\n---\n\n## **Final Thoughts** \n\n### **When to Use Jobs?** \n- When performing **time-consuming tasks** (e.g., sending emails, notifications, processing images). \n- When you want to **offload tasks** from the main application request cycle. \n\n### **When to Use Observers?** \n- When you need to **react to model events** (e.g., sending notifications when a user registers). \n- To **separate concerns** and keep models/controllers **clean**. \n\n### **Combining Jobs & Observers** \nA common approach is to use **Observers** to detect model changes and trigger **Jobs** to execute tasks asynchronously. This improves performance and keeps the application **organized**. \n\n","timestamp":"2025-01-31T20:38:00.511Z","comments":[]},{"title":"Laravel Media Library","content":"### **Complete Guide to Using Laravel Media Library** \n\n**Laravel Media Library** is a powerful tool for handling files and images in Laravel applications. It simplifies tasks like uploading, organizing, and serving media files effortlessly. In this step-by-step guide, we will explore the essential features of Laravel Media Library, including creating, deleting, viewing files, and other crucial operations. Let's get started! πŸš€ \n\n---\n\n## **Prerequisites** \nBefore diving into this guide, make sure you have the following prerequisites in place: \n\n- A **Laravel project** set up and running. \n- **Eloquent ORM** configured in Laravel. \n- Basic knowledge of **Laravel** and **PHP**. \n\n---\n\n## **Installation** \nTo start using **Laravel Media Library**, install the package via Composer: \n\n```bash\ncomposer require spatie/laravel-medialibrary\n``` \n\nAfter installation, publish the package configuration and migrations by running the following commands: \n\n```bash\nphp artisan vendor:publish --provider=\"Spatie\\MediaLibrary\\MediaLibraryServiceProvider\" --tag=\"migrations\"\nphp artisan migrate\n``` \n\nThis will create the necessary database tables for media management. \n\n---\n\n## **1. Configure Your Model to Use Media Library** \nTo enable any **model** to support media files, it must implement the `HasMedia` interface and use the `InteractsWithMedia` trait: \n\n```php\nuse Spatie\\MediaLibrary\\HasMedia;\nuse Spatie\\MediaLibrary\\InteractsWithMedia;\nuse Illuminate\\Database\\Eloquent\\Model;\n\nclass Post extends Model implements HasMedia\n{\n use InteractsWithMedia;\n}\n``` \n\nNow, your model can manage media files seamlessly. \n\n---\n\n## **2. Upload Files to a Model** \nOnce your model is configured, you can easily upload files to it: \n\n```php\n$post = Post::find(1);\n$post->addMedia($request->file('image'))->toMediaCollection('images');\n``` \n\n> The file will be automatically stored in Laravel’s **default storage location**. \n\n---\n\n## **3. Retrieve and Display Files** \nTo retrieve the URL of the stored file, use: \n\n```php\n$post->getFirstMediaUrl('images');\n``` \n\nThis will return the **URL of the first media file** stored in the `images` collection. \n\n---\n\n## **4. Delete Files** \n### Delete all media files linked to a model: \n\n```php\n$post->clearMediaCollection('images');\n``` \n\n### Delete a specific media file: \n\n```php\n$media = $post->getFirstMedia('images');\n$media->delete();\n``` \n\n---\n\n## **5. Customizing Storage Locations** \nYou can store media files on a **specific storage disk** (such as `s3` or `public`) by specifying the disk name: \n\n```php\n$post->addMedia($request->file('image'))\n ->toMediaCollection('images', 's3');\n``` \n\n> This will save the file directly to **Amazon S3** or any other disk defined in Laravel's storage configuration. \n\n---\n\n## **6. Image Conversions & Resizing** \nYou can use **Media Conversions** to automatically resize or transform images before storing them: \n\n```php\nuse Spatie\\MediaLibrary\\MediaCollections\\Models\\Media;\n\npublic function registerMediaConversions(Media $media = null): void\n{\n $this->addMediaConversion('thumb')\n ->width(200)\n ->height(200)\n ->sharpen(10);\n}\n``` \n\n> To retrieve the **thumbnail version**, use: \n\n```php\n$post->getFirstMediaUrl('images', 'thumb');\n``` \n\n---\n\n## **7. Displaying Images in the Frontend** \nTo display the uploaded images in **Blade** or **Vue.js**, use: \n\n```blade\n<img src=\"{{ $post->getFirstMediaUrl('images') }}\" alt=\"Post Image\">\n``` \n\n---\n\n## **Conclusion** \n**Laravel Media Library** provides a flexible and efficient way to manage media files in Laravel applications. It allows you to upload, organize, delete, and dynamically transform images with ease. \n\n🎯 **Do you have any questions about implementing it in your project?** Feel free to ask! πŸš€","timestamp":"2025-02-01T11:59:20.972Z","comments":[{"text":"If \n```bash\nphp artisan vendor:publish --provider=\"Spatie\\MediaLibrary\\MediaLibraryServiceProvider\" --tag=\"migrations\"`\n```\n does not work, use: \n\n```bash\nphp artisan vendor:publish --provider=\"Spatie\\MediaLibrary\\MediaLibraryServiceProvider\"\n```","timestamp":"2025-02-01T16:47:13.073Z"}]},{"title":"Laravel 11 add sessions to database","content":"### Laravel 11 with Sanctum API Authentication, Sessions in Database, and Middleware Setup\nTo build a Laravel 11 application using the Sanctum package for API authentication, while keeping track of sessions in the database and managing login, registration, and logout properly, we can break down the process into multiple steps. Here's a breakdown and clarification of the steps with required configurations.\n\n### 1. **Database Configuration for Session Storage:**\n\nIn your `.env` file, you've already set the session driver to `database`:\n\n```env\nSESSION_DRIVER=database\nSESSION_LIFETIME=120\nSESSION_ENCRYPT=false\nSESSION_PATH=/\nSESSION_DOMAIN=null\n```\n\nThis stores your sessions in the database. You need to create a session table to store these sessions.\n\nRun the following command to create the session table:\n\n```bash\nphp artisan session:table\nphp artisan migrate\n```\n\n### 2. **AuthController Setup:**\n\nYou've already provided an excellent start with your `AuthController.php`. Here's an explanation of how the login, logout, and session regeneration work:\n\n#### `login` Method:\n\n- **Validation:** Ensures that the email and password are valid.\n- **User Retrieval and Validation:** The user is fetched based on the provided email, and the password is verified using `Hash::check`.\n- **Session Regeneration:** `session()->regenerate()` is called to create a new session ID.\n- **Token Creation:** The Sanctum token is generated for the user using `$user->createToken('auth_token')->plainTextToken`.\n- **Response:** It returns a JSON response with the user details and token.\n\n```php\npublic function login(Request $request)\n{\n // Validate the incoming request data\n $request->validate([\n 'email' => 'required|email',\n 'password' => 'required|min:8',\n ]);\n\n // Retrieve the user by email\n $user = User::where('email', $request->email)->first();\n\n // Check if the user exists and the password is correct\n if (!$user || !Hash::check($request->password, $user->password)) {\n throw ValidationException::withMessages([\n 'email' => ['The provided credentials are incorrect.'],\n 'success' => false,\n ], Response::HTTP_UNAUTHORIZED);\n }\n\n $request->session()->regenerate(); // Regenerate session\n\n // Create a new token for the user\n $token = $user->createToken('auth_token')->plainTextToken;\n\n // Return the token in a secure JSON response\n return response()->json([\n 'user' => $user,\n 'token' => $token,\n 'success'=> true,\n ], Response::HTTP_CREATED);\n}\n```\n\n#### `logout` Method:\n\n- **Session Invalidation:** `$request->session()->invalidate()` is used to invalidate the session.\n- **Session Token Regeneration:** `$request->session()->regenerateToken()` regenerates the session token.\n- **Token Deletion:** `$request->user()->currentAccessToken()->delete()` deletes the current token.\n\n```php\npublic function logout(Request $request)\n{\n $request->session()->invalidate();\n $request->session()->regenerateToken();\n // Revoke the token that was used to authenticate the current request\n $request->user()->currentAccessToken()->delete();\n\n return response()->json([\n 'success' => true,\n ], Response::HTTP_OK);\n}\n```\n\n### 3. **User Model Setup:**\n\nIn `User.php`, the `HasApiTokens` trait is necessary to allow the user to create API tokens.\n\n```php\nuse Laravel\\Sanctum\\HasApiTokens;\n\nclass User extends Authenticatable\n{\n use HasApiTokens, HasFactory, Notifiable;\n\n protected $fillable = ['name', 'email', 'password'];\n\n protected $hidden = ['password', 'remember_token'];\n\n protected function casts(): array\n {\n return [\n 'email_verified_at' => 'datetime',\n 'password' => 'hashed',\n ];\n }\n}\n```\n\n### 4. **Middleware Setup in `bootstrap/app.php`:**\n\nThe middleware is used to append the session start middleware to the app. This ensures that the session is correctly started for API routes that need it (such as the login and logout routes). The `append()` method allows you to add custom middleware to the existing stack.\n\n```php\nuse Illuminate\\Session\\Middleware\\StartSession;\n\nreturn Application::configure(basePath: dirname(__DIR__))\n ->withMiddleware(function (Middleware $middleware) {\n $middleware->append(StartSession::class);\n });\n```\n\nThis ensures that session management is applied properly, and sessions are stored in the database.\n\n### 5. **API Routes in `api.php`:**\n\nYou define your API routes here. You include the `auth:sanctum` middleware to protect routes that require authentication, and `StartSession` for session handling.\n\n```php\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Facades\\Route;\nuse App\\Http\\Controllers\\Auth\\AuthController;\nuse Illuminate\\Session\\Middleware\\StartSession;\n\nRoute::post('/login', [AuthController::class, 'login'])->middleware('throttle:5,1'); // Login route\n\nRoute::middleware(['auth:sanctum', StartSession::class])->group(function () {\n Route::post('/logout', [AuthController::class, 'logout']); // Logout route\n});\n```\n\n### 6. **Understanding `$middleware->append()`:**\n\nThe `$middleware->append()` method is used to add additional middleware to the existing middleware stack. The `StartSession` middleware is essential for handling sessions in Laravel. This method appends it to the stack, ensuring that sessions are handled even on API routes.\n\nThe `append()` method works like this:\n\n```php\n$middleware->append(StartSession::class);\n```\n\nIt ensures that the `StartSession` middleware is included for every request after the existing middleware, so sessions can be started and managed for each incoming request.\n\n### Final Notes:\n\n- Make sure that your `SESSION_DRIVER` is set to `database` in `.env`, and you've run the migration to create the session table.\n- Ensure that your Sanctum configurations and session settings are aligned in your `.env` and `config/session.php`.\n- The login method creates the token for the user, and the logout method ensures the session and token are properly cleared.\n\nBy following these configurations, you’ll have a solid foundation for API authentication using Sanctum while handling sessions in Laravel.","timestamp":"2025-02-01T16:34:50.389Z","comments":[]},{"title":"Creating Middleware in Laravel 11","content":"# Creating Middleware in Laravel 11\n\n## 1. Generating a New Middleware\nTo create a new middleware in Laravel 11, use the Artisan command:\n\n```bash\nphp artisan make:middleware CheckRole\n```\nThis will generate a new middleware file in `app/Http/Middleware/CheckRole.php`.\n\n## 2. Implementing Middleware Logic\nOnce created, modify the `handle()` method inside the middleware file to implement the required logic. Middleware can be used for tasks such as checking user permissions before allowing access.\n\nExample:\n\n```php\nnamespace App\\Http\\Middleware;\n\nuse Closure;\nuse Illuminate\\Http\\Request;\n\nclass CheckRole\n{\n public function handle(Request $request, Closure $next)\n {\n // Custom logic (e.g., checking user roles)\n\n return $next($request); // Continue request processing\n }\n}\n```\n\n## 3. Registering the Middleware\nSince Laravel 11 does not have `Kernel.php`, middleware registration is done inside `bootstrap/app.php`.\n\nAdd your middleware alias inside the `withMiddleware` function:\n\n```php\n<?php\n\nuse Illuminate\\Foundation\\Application;\nuse Illuminate\\Foundation\\Configuration\\Exceptions;\nuse Illuminate\\Foundation\\Configuration\\Middleware;\nuse Illuminate\\Session\\Middleware\\StartSession;\n\nreturn Application::configure(basePath: dirname(__DIR__))\n ->withRouting(\n web: __DIR__.'/../routes/web.php',\n api: __DIR__.'/../routes/api.php',\n commands: __DIR__.'/../routes/console.php',\n health: '/up',\n )\n ->withMiddleware(function (Middleware $middleware) {\n $middleware->api(prepend: [\n \\Laravel\\Sanctum\\Http\\Middleware\\EnsureFrontendRequestsAreStateful::class,\n StartSession::class\n ]);\n\n $middleware->alias([\n 'checkRole' => \\App\\Http\\Middleware\\CheckRole::class,\n ]);\n })\n ->withExceptions(function (Exceptions $exceptions) {\n })->create();\n```\n\n## 4. Applying Middleware to Routes\nOnce registered, the middleware can be applied to routes using its alias:\n\n```php\nRoute::get('/admin/dashboard', function () {\n return view('admin.dashboard');\n})->middleware('checkRole');\n```\n\nMiddleware can also accept parameters:\n\n```php\nRoute::get('/admin/dashboard', function () {\n return view('admin.dashboard');\n})->middleware('checkRole:admin');\n```\n\n## 5. Testing the Middleware\nTo verify the middleware functionality, use tools like Postman or manually test it through the application UI. Ensure it properly restricts or allows access based on the implemented logic.\n\nBy following these steps, you can successfully create and manage middleware in Laravel 11.\n\n","timestamp":"2025-02-01T23:21:49.183Z"},{"title":"Laravel Deployment VPS Server","content":"# Comprehensive Deployment Guide: Laravel Backend on VPS with Nginx\n\n## Table of Contents\n1. **Initial Server Setup**\n2. **Domain & DNS Configuration**\n3. **Project Directory & Permissions**\n4. **Nginx Configuration**\n5. **PHP-FPM Setup**\n6. **Troubleshooting Common Issues**\n7. **Security & HTTPS (Optional)**\n8. **Deployment Checklist**\n\n---\n\n## 1. Initial Server Setup\n\n### 1.1 Update System Packages\n```bash\nsudo apt update && sudo apt upgrade -y\n```\n\n### 1.2 Install Required Dependencies\n```bash\nsudo apt install nginx git unzip php8.2 php8.2-fpm php8.2-mysql php8.2-mbstring php8.2-xml php8.2-curl -y\n```\n\n### 1.3 Verify PHP Version\n```bash\nphp -v # Ensure PHP 8.2+ is active\n```\n\n---\n\n## 2. Domain & DNS Configuration\n\n### 2.1 Create an A Record\n- **Type**: `A` \n- **Name**: `backend` (for subdomain `backend.yourdomain.com`) \n- **Value**: `your_server_ip` (e.g., `147.93.127.228`) \n- **TTL**: `14400` \n\n**Note**: Replace `yourdomain.com` with your actual domain. Allow 5-30 minutes for DNS propagation.\n\n---\n\n## 3. Project Directory & Permissions\n\n### 3.1 Move Project to `/var/www`\n```bash\nsudo mv /root/next-app/backend /var/www/\n```\n\n### 3.2 Set Correct Ownership\n```bash\nsudo chown -R www-data:www-data /var/www/backend\n```\n\n### 3.3 Adjust File Permissions\n```bash\nsudo chmod -R 755 /var/www/backend\nsudo chmod -R 775 /var/www/backend/storage /var/www/backend/bootstrap/cache\n```\n\n---\n\n## 4. Nginx Configuration\n\n### 4.1 Create Nginx Server Block\n```bash\nsudo nano /etc/nginx/sites-available/backend.yourdomain.com\n```\n\n### 4.2 Paste Configuration\n```nginx\nserver {\n listen 80;\n server_name backend.yourdomain.com;\n root /var/www/backend/public;\n index index.php index.html;\n\n location / {\n try_files $uri $uri/ /index.php?$query_string;\n }\n\n location ~ \\.php$ {\n include snippets/fastcgi-php.conf;\n fastcgi_pass unix:/run/php/php8.2-fpm.sock;\n fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;\n include fastcgi_params;\n }\n\n location ~ /\\.ht {\n deny all;\n }\n}\n```\n\n### 4.3 Enable the Site\n```bash\nsudo ln -s /etc/nginx/sites-available/backend.yourdomain.com /etc/nginx/sites-enabled/\nsudo nginx -t # Validate config\nsudo systemctl restart nginx\n```\n\n---\n\n## 5. PHP-FPM Setup\n\n### 5.1 Verify PHP-FPM Socket Path\n```bash\nls /run/php/ # Look for php8.2-fpm.sock\n```\n\n### 5.2 Update PHP-FPM Configuration (If Needed)\n```bash\nsudo nano /etc/php/8.2/fpm/pool.d/www.conf\n```\nEnsure these lines exist:\n```ini\nuser = www-data\ngroup = www-data\nlisten = /run/php/php8.2-fpm.sock\n```\n\n### 5.3 Restart Services\n```bash\nsudo systemctl restart php8.2-fpm\nsudo systemctl restart nginx\n```\n\n---\n\n## 6. Troubleshooting Common Issues\n\n### 6.1 Permission Denied Errors\n**Solution**: \n```bash\nsudo chown -R www-data:www-data /var/www/backend\nsudo chmod -R 755 /var/www/backend\n```\n\n### 6.2 Missing PHP Extensions (e.g., DOMDocument)\n**Solution**: \n```bash\nsudo apt install php8.2-xml\nsudo systemctl restart php8.2-fpm\n```\n\n### 6.3 PHP-FPM Socket Not Found\n**Solution**: \n1. Confirm PHP version matches Nginx config (e.g., `php8.2` vs `php8.1`). \n2. Check socket existence: \n ```bash\n sudo find /run -name \"php*.sock\"\n ```\n3. Update Nginx’s `fastcgi_pass` line with the correct socket path.\n\n### 6.4 Nginx 502 Bad Gateway\n**Solution**: \n```bash\n# Check error logs:\nsudo tail -f /var/log/nginx/error.log\n# Ensure PHP-FPM is running:\nsudo systemctl status php8.2-fpm\n```\n\n---\n\n## 7. Security & HTTPS (Optional)\n\n### 7.1 Install Certbot\n```bash\nsudo apt install certbot python3-certbot-nginx -y\n```\n\n### 7.2 Obtain SSL Certificate\n```bash\nsudo certbot --nginx -d backend.yourdomain.com\n```\n\n### 7.3 Auto-Renew Certificates\n```bash\nsudo certbot renew --dry-run\n```\n\n---\n\n## 8. Deployment Checklist\n\n1. **Project Moved**: Files located at `/var/www/backend`. \n2. **Permissions Set**: Ownership to `www-data`, `755/775` permissions. \n3. **DNS Configured**: Valid A record for `backend.yourdomain.com`. \n4. **Nginx Configured**: Server block points to correct `root` and PHP socket. \n5. **PHP Extensions Installed**: `php8.2-xml`, `php8.2-mbstring`, etc. \n6. **Services Restarted**: Nginx and PHP-FPM running without errors. \n\n---\n\n**Final Test**: \nVisit `http://backend.yourdomain.com` or `https://backend.yourdomain.com` (if HTTPS enabled). \nIf you see a Laravel error page (not 502/404), the backend is successfully connected!","timestamp":"2025-02-07T16:16:05.358Z","comments":[]},{"title":" Raspberry Pi Audio Playback & Troubleshooting Guide","content":"# Raspberry Pi Audio Playback & Troubleshooting Guide\n\n## 1. Playing WAV Files\n### Using Command Line (`aplay`)\n```bash\n# Play file in current directory\naplay sample-wav-files-sample3.wav\n\n# Play file with full path\naplay ~/Desktop/voice_assistant/sample-wav-files-sample3.wav\n\n# Install alsa-utils if needed\nsudo apt-get update && sudo apt-get install alsa-utils\n```\n\n### Using GUI Players (VLC)\n```bash\n# Install VLC\nsudo apt-get update && sudo apt-get install vlc\n\n# Play file with GUI\nvlc sample-wav-files-sample3.wav\n\n# Play file in CLI mode\ncvlc sample-wav-files-sample3.wav\n```\n\n---\n\n## 2. Troubleshooting No Sound Issues\n\n### 2.1 Verify Audio Configuration\n```bash\n# List audio devices\naplay -l\n\n# Configure audio output\nsudo raspi-config\n# Navigate to: System Options β†’ Audio\n```\n\n### 2.2 Audio Hardware Test\n```bash\n# Run speaker test\nspeaker-test -t wav -c 2\n```\n\n### 2.3 Volume Control\n```bash\n# Adjust volume levels\nalsamixer\n```\n- Press `M` to unmute\n- Use arrow keys to adjust volume\n\n### 2.4 Verify Software Installation\n```bash\n# Ensure essential packages\nsudo apt update && sudo apt install alsa-utils vlc\n```\n\n### 2.5 File Integrity Check\n```bash\n# Verify WAV file format\nfile sample-wav-files-sample3.wav\n```\nExpected output: \n`RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, mono 44100 Hz`\n\n### 2.6 Alternative Players\n```bash\n# Install and use MPV\nsudo apt install mpv\nmpv sample-wav-files-sample3.wav\n```\n\n### 2.7 Hardware Connections\n- Confirm physical connections (HDMI/3.5mm jack)\n- Try different audio ports\n- Re-run `sudo raspi-config` to switch output devices\n\n### 2.8 System Maintenance\n```bash\n# Update system packages\nsudo apt update && sudo apt upgrade\n\n# Reboot system\nsudo reboot\n```\n\n---\n\n## 3. Additional Notes\n- If using VLC GUI fails, try CLI version with `cvlc`\n- Check Raspberry Pi 5 specific forums for hardware-related issues\n- Ensure adequate power supply for audio peripherals\n- Test with different audio files to isolate file-specific issues\n\nSave this guide as a reference for future audio-related configurations on your Raspberry Pi.","timestamp":"2025-02-18T10:59:03.105Z","comments":[]},{"title":"Enable a USB Microphone on Raspberry Pi","content":"# Raspberry Pi USB Microphone Setup Guide\n\n## 1. Connect and Verify the Microphone\n1. Plug the USB microphone into a USB port.\n2. Open a terminal and check detected devices:\n ```bash\n arecord -l\n ```\n Look for an entry like:\n ```plaintext\n card 2: Device [USB Audio Device], device 0: USB Audio [USB Audio]\n ```\n\n## 2. Set the USB Microphone as Default\n1. Edit ALSA configuration:\n ```bash\n sudo nano /etc/asound.conf\n ```\n2. Add the following (replace `2` with your card number):\n ```plaintext\n defaults.pcm.card 2\n defaults.ctl.card 2\n ```\n3. Save and exit (`Ctrl + X`, then `Y`, then `Enter`).\n\n## 3. Test the Microphone\n1. Record a 10-second audio sample:\n ```bash\n arecord -D plughw:2,0 -f cd -d 10 test.wav\n ```\n2. Play back the recording:\n ```bash\n aplay test.wav\n ```\n\n## 4. Adjust Microphone Volume (Optional)\n- Open ALSA mixer:\n ```bash\n alsamixer\n ```\n- Press `F6` to select the USB microphone, adjust volume with arrow keys, then press `Esc` to exit.\n\n## 5. Troubleshooting\n### No Sound or Device Not Detected\n- Ensure the microphone is properly connected.\n- Try a different USB port.\n- Check for additional drivers.\n\n### Permission Issues\n- Add your user to the `audio` group:\n ```bash\n sudo usermod -aG audio $(whoami)\n sudo reboot\n ```\n\n### \"audio open error: No such file or directory\"\n- Verify the correct card/device numbers with `arecord -l`.\n- Try:\n ```bash\n arecord -f cd -d 5 test.wav\n ```\n\n## 6. Optional: Use PulseAudio\nFor advanced control:\n```bash\nsudo apt install pulseaudio pavucontrol\npavucontrol\n```\nThis provides a graphical interface to manage audio devices.\n\nFollowing these steps, your Raspberry Pi should successfully recognize and use a USB microphone.\n\n","timestamp":"2025-02-19T01:38:00.272Z","comments":[]},{"title":"serial communication between a Raspberry Pi 5 and an Arduino","content":"### **1. Hardware Setup**\nYou can connect the Raspberry Pi and Arduino using **USB** or **UART (Tx/Rx pins).** \n\n#### **Option 1: USB Connection (Recommended)**\n- Simply connect the Arduino to the Raspberry Pi using a USB cable.\n\n#### **Option 2: UART Connection (Using GPIO)**\nIf using UART (without USB), make the following connections:\n- **Tx (GPIO14) on Raspberry Pi** β†’ **Rx (Pin 0) on Arduino**\n- **Rx (GPIO15) on Raspberry Pi** β†’ **Tx (Pin 1) on Arduino**\n- **GND (Raspberry Pi)** β†’ **GND (Arduino)**\n\n⚠ **Important:** If using UART, disable the serial console on Raspberry Pi to free the serial port.\n\n---\n\n### **2. Raspberry Pi Configuration**\n#### **Enable Serial Interface**\n1. Open a terminal and run:\n ```bash\n sudo raspi-config\n ```\n2. Go to **Interfacing Options > Serial** \n3. Disable the serial login shell but enable serial port hardware. \n4. Reboot the Raspberry Pi:\n ```bash\n sudo reboot\n ```\n\n#### **Check USB Connection**\nTo list connected USB devices:\n```bash\nlsusb\n```\nTo find the Arduino's serial port:\n```bash\ndmesg | grep \"tty\"\n```\nExample output:\n```\ncdc_acm 1-1:1.0: ttyACM0: USB ACM device\n```\nIn this case, the port name is **`/dev/ttyACM0`**.\n\n---\n\n### **3. Install Required Libraries**\nOn Raspberry Pi, install the Python serial library:\n```bash\npip install pyserial\n```\n\n---\n\n### **4. Arduino Code (Serial Communication)**\nUpload the following code to Arduino using the Arduino IDE:\n\n```cpp\nconst int ledPin = 13;\nString msg;\n\nvoid setup() {\n Serial.begin(9600);\n pinMode(ledPin, OUTPUT);\n}\n\nvoid loop() {\n readSerialPort();\n\n if (msg == \"led0\") {\n digitalWrite(ledPin, LOW);\n Serial.println(\"LED OFF\");\n } else if (msg == \"led1\") {\n digitalWrite(ledPin, HIGH);\n Serial.println(\"LED ON\");\n } else if (msg == \"data\") {\n sendData();\n }\n delay(500);\n}\n\nvoid readSerialPort() {\n msg = \"\";\n if (Serial.available()) {\n delay(10);\n while (Serial.available() > 0) {\n msg += (char)Serial.read();\n }\n Serial.flush();\n }\n}\n\nvoid sendData() {\n Serial.print(\"LED: \");\n Serial.print(digitalRead(ledPin));\n Serial.print(\", Sensor1: \");\n Serial.print(analogRead(A0));\n Serial.print(\", Sensor2: \");\n Serial.println(analogRead(A1));\n}\n```\n\n---\n\n### **5. Python Code (Raspberry Pi)**\nCreate a Python script (`serial_comm.py`) to communicate with the Arduino:\n\n```python\nimport serial\nimport time\n\narduino_port = \"/dev/ttyACM0\" # Change based on `dmesg | grep \"tty\"`\nbaud_rate = 9600\n\ntry:\n with serial.Serial(arduino_port, baud_rate, timeout=1) as arduino:\n time.sleep(2) # Wait for Arduino to initialize\n print(f\"Connected to {arduino.port}\")\n\n while True:\n cmd = input(\"Enter command (led0, led1, data): \")\n arduino.write(cmd.encode()) # Send command to Arduino\n time.sleep(0.1) # Allow Arduino to respond\n\n while arduino.inWaiting() > 0:\n response = arduino.readline().decode().strip()\n print(\"Arduino:\", response)\n\nexcept serial.SerialException as e:\n print(f\"Error: {e}\")\n\nexcept KeyboardInterrupt:\n print(\"\\nProgram terminated.\")\n```\n\n---\n\n### **6. Running the Program**\n1. Run the Python script on Raspberry Pi:\n ```bash\n python3 serial_comm.py\n ```\n2. Enter commands in the terminal:\n ```\n led1 # Turns LED ON\n led0 # Turns LED OFF\n data # Retrieves sensor values\n ```\n3. The Arduino will process the command and send a response.\n\n---\n\n### **7. Expected Output**\n#### **On Raspberry Pi Terminal**\n```\nConnected to /dev/ttyACM0\nEnter command (led0, led1, data): led1\nArduino: LED ON\nEnter command (led0, led1, data): data\nArduino: LED: 1, Sensor1: 523, Sensor2: 402\n```\n\n---\n\n### **Conclusion**\nYou have successfully established serial communication between **Raspberry Pi 5 and Arduino**, sending commands and receiving responses. πŸš€","timestamp":"2025-02-21T22:12:49.048Z","comments":[]},{"title":"Authentication in Laravel 11 Using Api-Token","content":"# **Authentication in Laravel 11 Using Laravel Breeze and Sanctum**\n\nLaravel Breeze provides a minimal and simple scaffolding for authentication (login, registration, etc.), while Laravel Sanctum allows you to issue API tokens for authenticating API requests. In Laravel 11, the framework has undergone some structural changes, such as simplifying traditional files like `config` and `Kernel`. As a result, setting up authentication might feel slightly different compared to previous versions.\n\nThis guide will walk you through the process of implementing authentication in Laravel 11 using **Laravel Breeze** for front-end scaffolding and **Laravel Sanctum** for API token-based authentication.\n\n---\n\n## **1. Installing Laravel Breeze and Sanctum**\n\n### **Laravel Breeze Installation**\n\nLaravel Breeze is a lightweight package that provides a simple starting point for building authentication features like login, registration, and password reset.\n\n1. **Install Laravel Breeze:** \n Run the following command in your Laravel 11 project to install Breeze:\n ```bash\n composer require laravel/breeze --dev\n ```\n\n2. **Scaffold Authentication:** \n After installing Breeze, run the following command to generate the necessary authentication scaffolding:\n ```bash\n php artisan breeze:install\n ```\n This command generates views, controllers, and routes for authentication.\n\n3. **Compile Assets:** \n To compile the frontend assets (CSS, JavaScript), run:\n ```bash\n npm install && npm run dev\n ```\n This step ensures that your application's frontend is ready to use.\n\n---\n\n### **Laravel Sanctum Installation**\n\nLaravel Sanctum is used for API token-based authentication. It allows you to issue API tokens for users and authenticate API requests securely.\n\n1. **Install Sanctum:** \n Run the following command to install Sanctum:\n ```bash\n composer require laravel/sanctum\n ```\n\n2. **Publish Sanctum Files:** \n Publish the Sanctum configuration and migration files by running:\n ```bash\n php artisan vendor:publish --provider=\"Laravel\\Sanctum\\SanctumServiceProvider\"\n ```\n\n3. **Run Migrations:** \n After publishing the Sanctum files, run the migrations to create the necessary database tables:\n ```bash\n php artisan migrate\n ```\n\n4. **Middleware Configuration:** \n In Laravel 11, the middleware stack may differ slightly from previous versions. Ensure that Sanctum’s middleware (`auth:sanctum`) is added to the `api` middleware group in `app/Http/Kernel.php`. By default, Sanctum should already be configured, but you can verify this in the official documentation.\n\n5. **Configure CORS (Optional):** \n If your frontend and backend are hosted on different domains, configure Cross-Origin Resource Sharing (CORS) in `config/cors.php`. Ensure that the `supports_credentials` option is set to `true` if needed.\n\n---\n\n## **2. Setting Up Routes**\n\nDefine your API routes in `routes/api.php`. These routes will handle user registration, login, fetching user data, and logout.\n\n```php\n<?php\n\nuse Illuminate\\Support\\Facades\\Route;\nuse App\\Http\\Controllers\\AuthController;\n\n// Public routes for registration and login\nRoute::post('/register', [AuthController::class, 'register'])->name('register');\nRoute::post('/login', [AuthController::class, 'login'])->name('login');\n\n// Protected routes (require authentication via Sanctum)\nRoute::middleware('auth:sanctum')->group(function () {\n Route::get('/user', [AuthController::class, 'currentUser'])->name('currentUser');\n Route::post('/logout', [AuthController::class, 'logout'])->name('logout');\n});\n```\n\n### **Explanation:**\n- **Public Routes:** `/register` and `/login` are accessible without authentication.\n- **Protected Routes:** The `auth:sanctum` middleware ensures that only authenticated users can access these routes.\n\n---\n\n## **3. Creating the AuthController**\n\nCreate a controller (e.g., `app/Http/Controllers/AuthController.php`) to handle authentication logic. Below is a detailed implementation:\n\n```php\n<?php\n\nnamespace App\\Http\\Controllers;\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Http\\Response;\nuse Illuminate\\Support\\Facades\\Hash;\nuse Illuminate\\Support\\Facades\\Validator;\nuse App\\Models\\User;\n\nclass AuthController extends Controller\n{\n /**\n * Register a new user and return an API token.\n */\n public function register(Request $request)\n {\n // Validate incoming request\n $validator = Validator::make($request->all(), [\n 'name' => 'required|string|max:255',\n 'email' => 'required|email|unique:users,email',\n 'password' => 'required|string|min:8'\n ]);\n\n if ($validator->fails()) {\n return response()->json([\n 'status' => false,\n 'errors' => $validator->errors()\n ], Response::HTTP_UNPROCESSABLE_ENTITY);\n }\n\n // Create user\n $user = User::create([\n 'name' => $request->name,\n 'email' => $request->email,\n 'password' => Hash::make($request->password)\n ]);\n\n // Generate API token using Sanctum\n $token = $user->createToken('auth_token')->plainTextToken;\n\n // Return response with user data and token\n return response()->json([\n 'status' => true,\n 'message' => 'User registered successfully',\n 'data' => [\n 'user' => $user,\n 'token' => $token\n ]\n ], Response::HTTP_CREATED);\n }\n\n /**\n * Log in an existing user and return an API token.\n */\n public function login(Request $request)\n {\n // Validate login credentials\n $validator = Validator::make($request->all(), [\n 'email' => 'required|email',\n 'password' => 'required'\n ]);\n\n if ($validator->fails()) {\n return response()->json([\n 'status' => false,\n 'errors' => $validator->errors()\n ], Response::HTTP_UNPROCESSABLE_ENTITY);\n }\n\n // Retrieve the user by email\n $user = User::where('email', $request->email)->first();\n\n // Check if user exists and password is correct\n if (!$user || !Hash::check($request->password, $user->password)) {\n return response()->json([\n 'status' => false,\n 'message' => 'Invalid credentials'\n ], Response::HTTP_UNAUTHORIZED);\n }\n\n // Generate a new API token\n $token = $user->createToken('auth_token')->plainTextToken;\n\n // Return successful login response\n return response()->json([\n 'status' => true,\n 'message' => 'User logged in successfully',\n 'data' => [\n 'user' => $user,\n 'token' => $token\n ]\n ], Response::HTTP_OK);\n }\n\n /**\n * Get the current authenticated user.\n */\n public function currentUser(Request $request)\n {\n return response()->json([\n 'status' => true,\n 'message' => 'User details fetched successfully',\n 'data' => $request->user()\n ], Response::HTTP_OK);\n }\n\n /**\n * Log out the current user by revoking the current token.\n */\n public function logout(Request $request)\n {\n // Revoke the token that was used to authenticate the current request\n $request->user()->currentAccessToken()->delete();\n\n return response()->json([\n 'status' => true,\n 'message' => 'Logged out successfully'\n ], Response::HTTP_OK);\n }\n}\n```\n\n### **Key Points:**\n- **Validation:** Each method validates the incoming request to ensure data integrity.\n- **Error Handling:** Proper error messages are returned with appropriate HTTP status codes.\n- **Token Management:** Tokens are generated during registration and login, and revoked during logout.\n\n---\n\n## **4. Setting Up the User Model**\n\nEnsure your `User` model (located at `app/Models/User.php`) uses the necessary traits for API token management and notifications. Here’s a minimal example:\n\n```php\n<?php\n\nnamespace App\\Models;\n\nuse Illuminate\\Foundation\\Auth\\User as Authenticatable;\nuse Illuminate\\Notifications\\Notifiable;\nuse Laravel\\Sanctum\\HasApiTokens;\n\nclass User extends Authenticatable\n{\n use HasApiTokens, Notifiable;\n\n // Define the attributes that are mass assignable\n protected $fillable = [\n 'name',\n 'email',\n 'password',\n ];\n\n // Hide sensitive fields from JSON output\n protected $hidden = [\n 'password',\n 'remember_token',\n ];\n}\n```\n\n### **Explanation:**\n- **Traits:** The `HasApiTokens` trait enables API token functionality, while `Notifiable` allows sending notifications.\n- **Mass Assignment:** The `$fillable` property specifies which attributes can be mass-assigned.\n- **Hidden Attributes:** The `$hidden` property ensures sensitive fields like `password` are not included in JSON responses.\n\n---\n\n## **5. Testing Your API**\n\nYou can test your API endpoints using tools like **Postman** or **cURL**. Here’s an example workflow:\n\n1. **Register a User:**\n - Send a `POST` request to `/register` with the required fields (`name`, `email`, `password`).\n - Example Payload:\n ```json\n {\n \"name\": \"John Doe\",\n \"email\": \"john@example.com\",\n \"password\": \"password123\"\n }\n ```\n\n2. **Log In:**\n - Send a `POST` request to `/login` with the user’s credentials.\n - Example Payload:\n ```json\n {\n \"email\": \"john@example.com\",\n \"password\": \"password123\"\n }\n ```\n\n3. **Access Protected Routes:**\n - Include the `Authorization` header with the token received during login:\n ```\n Authorization: Bearer <your_token>\n ```\n\n4. **Logout:**\n - Send a `POST` request to `/logout` to revoke the token.\n\n---\n\n## **6. Summary**\n\nThis guide covered the essential steps for implementing authentication in Laravel 11 using Laravel Breeze and Sanctum. Key takeaways include:\n\n- **Installation:** Install Laravel Breeze for scaffolding and Sanctum for API token management.\n- **Routing:** Define routes for registration, login, user details, and logout.\n- **Controller:** Implement an `AuthController` with methods for handling registration, login, fetching user data, and logout.\n- **User Model:** Configure the `User` model for API token usage.\n- **Testing:** Test your API endpoints using tools like Postman.\n\nBy following this guide, you’ll have a fully functional authentication system ready for your Laravel 11 project.","timestamp":"2025-04-07T05:15:33.482Z"},{"title":"How to Edit Images and Add Arabic Text Using Intervention Image and khaled.alshamaa/ar-php","content":"# How to Edit Images and Add Arabic Text Using **Intervention Image** and **khaled.alshamaa/ar-php**\n\nIn this article, we will explain how to use two PHP libraries, **Intervention Image** and **khaled.alshamaa/ar-php**, to edit images and add Arabic text. These libraries provide an easy and efficient way to manipulate images, overlay images, and handle Arabic text properly.\n\n### Libraries Overview\n\n* **Intervention Image**: A powerful library for image manipulation in PHP. It allows you to resize, crop, add overlays, apply filters, and much more.\n* **khaled.alshamaa/ar-php**: A library that helps in reshaping Arabic text to ensure it is displayed correctly when rendering on images.\n\n---\n\n### 1. **Prerequisites**\n\nBefore you start, make sure you have the following installed:\n\n* **PHP** (version 7.4 or higher recommended).\n* **Composer** to manage dependencies.\n\n---\n\n### 2. **Installation**\n\n#### **Install Intervention Image**\n\nTo install **Intervention Image**, run the following command in your terminal inside the project directory:\n\n```bash\ncomposer require intervention/image\n```\n\n#### **Install khaled.alshamaa/ar-php**\n\nTo install **khaled.alshamaa/ar-php**, run the following command:\n\n```bash\ncomposer require khaled.alshamaa/ar-php\n```\n\n---\n\n### 3. **How to Use the Libraries**\n\n#### **Setting Up ImageManager**\n\nTo start using **Intervention Image**, you first need to initialize an `ImageManager` object to handle image manipulation:\n\n```php\nuse Intervention\\Image\\ImageManager;\n\n$manager = new ImageManager();\n$image = $manager->make('path_to_image.jpg'); // Load an image\n```\n\n#### **Adding an Overlay Image**\n\nYou can overlay another image (e.g., a logo) on top of the base image:\n\n```php\n$overlay = $manager->make('overlay_image.png')->resize(150, 150);\n$image->insert($overlay, 'bottom-right', 20, 20); // Insert the overlay image at the bottom-right corner\n```\n\n#### **Adding Text to the Image**\n\nYou can add text to your image at specific coordinates, define the text size, and set the color:\n\n```php\n$image->text('Your Text Here', 100, 100, function($font) {\n $font->file('path_to_font.ttf'); // Set the font path\n $font->size(30); // Set font size\n $font->color('#ffffff'); // Set text color\n});\n```\n\n#### **Adding Arabic Text Using khaled.alshamaa/ar-php**\n\nTo handle Arabic text correctly, you need to use **khaled.alshamaa/ar-php** to reshape the Arabic text:\n\n```php\nuse ArPHP\\I18N\\Arabic;\n\n$arabic = new Arabic();\n$reshapedText = $arabic->utf8Glyphs('Ψ§Ω„Ω†Ψ΅ Ψ§Ω„ΨΉΨ±Ψ¨ΩŠ');\n$image->text($reshapedText, 100, 150, function($font) {\n $font->file('path_to_arabic_font.ttf'); // Set Arabic font\n $font->size(30); // Set font size\n $font->color('#ffffff'); // Set text color\n});\n```\n\n---\n\n### 4. **Returning the Modified Image**\n\nAfter modifying the image (adding overlays, text, etc.), you can return the image to the browser or save it:\n\n```php\nreturn response($image->encode('png'), 200)\n ->header('Content-Type', 'image/png'); // Return the image as PNG\n```\n\n---\n\n### 5. **Practical Examples**\n\n#### **Adding Arabic Text to an Image:**\n\n```php\n$image->text('Ω…Ψ±Ψ­Ψ¨Ω‹Ψ§ Ψ¨Ωƒ في Ω…ΩˆΩ‚ΨΉΩ†Ψ§', 100, 100, function($font) {\n $font->file(public_path('Amiri-Bold.ttf')); // Arabic font\n $font->size(40); // Font size\n $font->color('#0000ff'); // Text color\n});\n```\n\n#### **Applying Filters or Effects:**\n\n```php\n$image->brightness(20); // Increase brightness\n$image->contrast(10); // Add contrast\n```\n\n#### **Reshaping Arabic Text for Correct Display:**\n\n```php\n$arabic = new Arabic();\n$reshaped = $arabic->utf8Glyphs('Ω…Ψ±Ψ­Ψ¨Ψ§ Ψ¨Ωƒ في Ω‡Ψ°Ψ§ Ψ§Ω„Ω…Ψ«Ψ§Ω„!');\n$image->text($reshaped, 150, 150, function($font) {\n $font->file(public_path('Amiri-Bold.ttf')); // Arabic font\n $font->size(30); // Font size\n $font->color('#ff0000'); // Text color\n});\n```\n\n---\n\n### 6. **Important Notes**\n\n* **Fonts**: Ensure that the font you use supports Arabic characters. TrueType fonts (TTF) are recommended for Arabic text.\n* **Text Direction**: The library **khaled.alshamaa/ar-php** handles the reshaping of Arabic text to ensure proper direction and positioning.\n\n---\n\n### 7. **Conclusion**\n\nBy following the steps outlined above, you can easily manipulate images and add Arabic text to them using **Intervention Image** and **khaled.alshamaa/ar-php**. These libraries are powerful tools for developers who need to edit images dynamically, add overlays, and handle Arabic text correctly.\n\nThis guide provides a basic understanding of how to integrate these libraries into your PHP project. Whether you are building an image editor, adding watermarks, or creating dynamic image content, these libraries will save you time and effort.\n\n","timestamp":"2025-05-02T13:02:25.221Z","comments":[]},{"title":"How to Remove Ubuntu and GRUB 2.12 Bootloader to Boot Directly into Windows","content":"# How to Remove Ubuntu and GRUB Bootloader to Boot Directly into Windows\n\nThis guide explains how to fix the problem of the **GRUB bootloader appearing after uninstalling Ubuntu** and how to make your computer boot directly into Windows again.\n\n---\n\n## Problem Overview\n\nWhen you delete Ubuntu without properly removing GRUB (the bootloader), your computer may still show the GRUB menu at startup, causing confusion or boot failure. You want to remove GRUB and restore the Windows bootloader so that your PC boots straight into Windows.\n\n---\n\n## Step 1: Temporary Manual Boot into Windows from GRUB\n\nIf you see the GRUB command prompt (`grub>`), follow these steps to boot Windows manually:\n\n1. At the `grub>` prompt, type:\n\n ```bash\n ls\n ```\n\n This lists all available drives and partitions, e.g.:\n\n ```\n (hd0) (hd0,gpt1) (hd0,gpt2) (hd0,gpt3)\n ```\n\n2. Check each partition’s contents to find the Windows EFI boot file:\n\n ```bash\n ls (hd0,gpt1)/\n ls (hd0,gpt2)/\n ls (hd0,gpt3)/\n ```\n\n3. Look for the path:\n\n ```\n /EFI/Microsoft/Boot/bootmgfw.efi\n ```\n\n4. Once you find the partition containing that file (say `(hd0,gpt2)`), run:\n\n ```bash\n insmod part_gpt\n insmod fat\n insmod chain\n set root=(hd0,gpt2)\n chainloader /EFI/Microsoft/Boot/bootmgfw.efi\n boot\n ```\n\n5. This should boot you directly into Windows.\n\n---\n\n## Step 2: Assign a Drive Letter to the EFI Partition in Windows\n\nOnce you are in Windows, do the following to clean up the Ubuntu boot files:\n\n1. Open **Command Prompt as Administrator**.\n\n2. Type:\n\n ```bash\n diskpart\n ```\n\n3. List the volumes:\n\n ```bash\n list vol\n ```\n\n Example output:\n\n ```\n Volume ### Ltr Label Fs Type Size Status Info\n ---------- --- ----------- ----- ---------- ------- --------- --------\n Volume 0 C NTFS Partition 119 GB Healthy Boot\n Volume 1 D Local Disk NTFS Partition 205 GB Healthy\n Volume 2 E New Volume NTFS Partition 260 GB Healthy\n Volume 3 FAT32 Partition 100 MB Healthy System\n Volume 4 NTFS Partition 499 MB Healthy Hidden\n ```\n\n4. Identify the EFI System Partition: it is usually **FAT32**, small in size (\\~100 MB), and has the **System** status (Volume 3 above).\n\n5. Select this volume and assign a temporary drive letter (e.g., `Z`):\n\n ```bash\n select volume 3\n assign letter=Z\n exit\n ```\n\n---\n\n## Step 3: Delete Ubuntu Boot Files from EFI Partition\n\n1. In the same Command Prompt, switch to the EFI partition:\n\n ```bash\n Z:\n cd EFI\n dir\n ```\n\n2. Look for the `ubuntu` folder.\n\n3. To delete it:\n\n ```bash\n rmdir /S /Q ubuntu\n ```\n\n This deletes the Ubuntu boot files silently.\n\n---\n\n## Step 4: Remove Ubuntu Boot Entry from Boot Configuration Data (BCD)\n\n1. Still in **Command Prompt as Administrator**, list boot entries:\n\n ```bash\n bcdedit /enum firmware\n ```\n\n2. Look for any entry labeled **Ubuntu** and note its identifier (a GUID like `{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}`).\n\n3. Delete the Ubuntu boot entry by running:\n\n ```bash\n bcdedit /delete {identifier}\n ```\n\n Replace `{identifier}` with the actual GUID.\n\n---\n\n## Step 5: Restart Your PC\n\nAfter performing these steps, restart your computer. It should now boot directly into Windows without showing the GRUB menu.\n","timestamp":"2025-05-23T17:51:09.232Z","comments":[]},{"title":"configure a Laravel project with Vue 3 + Vite (With Tailwind CSS)","content":"# configure a Laravel project with Vue 3 + Vite (With Tailwind CSS)\n\n> This guide explains how to **configure a Laravel project with Vue 3** using **Vite** as the build tool and **Tailwind CSS** for styling. It covers everything from installation to production build and deployment β€” with clear explanations and file purposes.\n\n---\n\n## πŸ“ Project Structure Overview\n\n```\nproject-root/\nβ”œβ”€β”€ app/\nβ”œβ”€β”€ resources/\nβ”‚ β”œβ”€β”€ css/\nβ”‚ β”‚ └── app.css ← Tailwind entry file\nβ”‚ β”œβ”€β”€ js/\nβ”‚ β”‚ β”œβ”€β”€ app.js ← Vue app entry file\nβ”‚ β”‚ └── components/ ← Your Vue components\nβ”‚ └── views/\nβ”‚ └── welcome.blade.php\nβ”œβ”€β”€ public/\nβ”‚ └── build/ ← Vite build output\nβ”œβ”€β”€ vite.config.js ← Vite config file\nβ”œβ”€β”€ tailwind.config.js ← Tailwind config file\nβ”œβ”€β”€ postcss.config.js ← PostCSS config file\n└── package.json ← NPM dependencies and scripts\n```\n\n---\n\n## 1. πŸ“¦ Installing Dependencies\n\nRun the following in your project root:\n\n```bash\nnpm install vue@3\nnpm install -D vite laravel-vite-plugin @vitejs/plugin-vue\nnpm install -D tailwindcss autoprefixer @tailwindcss/postcss\n```\n\n* `vue@3`: Vue.js core\n* `vite`: Build tool\n* `laravel-vite-plugin`: Laravel integration\n* `@vitejs/plugin-vue`: Enables `.vue` file support\n* `tailwindcss`, `autoprefixer`, `@tailwindcss/postcss`: Tailwind setup for PostCSS\n\n---\n\n## 2. πŸ› οΈ Vite Configuration\n\n```js\n// vite.config.js\nimport { defineConfig } from \"vite\";\nimport laravel from \"laravel-vite-plugin\";\nimport vue from \"@vitejs/plugin-vue\";\n\nexport default defineConfig({\n plugins: [\n vue(),\n laravel({\n input: [\"resources/css/app.css\", \"resources/js/app.js\"],\n publicDirectory: \"public\",\n buildDirectory: \"build\",\n refresh: false,\n }),\n ],\n resolve: {\n alias: {\n \"@\": \"/resources/js\", // Makes imports easier: \"@/components/Example.vue\"\n },\n },\n build: {\n outDir: \"public/build\", // Build output path\n manifest: true, // Required for Laravel's @vite() directive\n rollupOptions: {\n output: {\n entryFileNames: \"js/[name]-[hash].js\",\n chunkFileNames: \"js/[name]-[hash].js\",\n assetFileNames: ({ name }) => {\n if (/\\.(css)$/.test(name ?? \"\")) {\n return \"css/[name]-[hash][extname]\";\n }\n return \"assets/[name]-[hash][extname]\";\n },\n },\n },\n },\n});\n```\n\n---\n\n## 3. 🧠 Tailwind CSS Setup\n\n### postcss.config.js\n\n```js\nexport default {\n plugins: {\n \"@tailwindcss/postcss\": {}, // Required with ESM projects\n autoprefixer: {},\n },\n};\n```\n\n### tailwind.config.js\n\n```js\n/** @type {import('tailwindcss').Config} */\nmodule.exports = {\n darkMode: \"class\",\n content: [\n \"./resources/**/*.blade.php\",\n \"./resources/**/*.js\",\n \"./resources/**/*.vue\",\n ],\n theme: {\n extend: {\n colors: {\n primary: \"#2563eb\",\n accent: \"#6366f1\",\n // Add more custom colors if needed\n },\n backgroundImage: {\n \"gradient-light\": \"linear-gradient(...)\", // Custom gradients\n },\n boxShadow: {\n \"card\": \"0 4px 24px rgba(0,0,0,0.06)\",\n },\n },\n },\n plugins: [],\n};\n```\n\n---\n\n## 4. πŸ“„ Main CSS File\n\n```css\n/* resources/css/app.css */\n\n@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n/* Custom utility classes */\n@layer utilities {\n .bg-gradient-to-br-light {\n background-image: linear-gradient(135deg, #f8fafc 0%, #dbeafe 25%, #e0f2fe 50%, #f0f9ff 100%);\n }\n\n .text-slate-900-light {\n color: #0f172a;\n }\n}\n```\n\n---\n\n## 5. 🧩 Vue App Entry\n\n```js\n// resources/js/app.js\n\nimport { createApp } from \"vue\";\nimport Example from \"./components/Example.vue\";\n\n// Mount Vue app to the DOM\ncreateApp(Example).mount(\"#app\");\n```\n\n---\n\n## 6. πŸ“ Blade Integration\n\nInside `resources/views/welcome.blade.php` (or any Blade file):\n\n```blade\n<!DOCTYPE html>\n<html lang=\"{{ str_replace('_', '-', app()->getLocale()) }}\">\n<head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <title>{{ config('app.name') }}</title>\n\n {{-- Vite will inject correct versioned CSS/JS files --}}\n @vite(['resources/css/app.css', 'resources/js/app.js'])\n</head>\n<body>\n <div id=\"app\"></div> <!-- Vue mounts here -->\n</body>\n</html>\n```\n\n---\n\n## 7. πŸ“œ NPM Scripts\n\nIn `package.json`, make sure these scripts are present:\n\n```json\n\"scripts\": {\n \"dev\": \"vite\",\n \"build\": \"vite build\",\n \"preview\": \"vite preview\"\n}\n```\n\n* `npm run dev`: Start local dev server with hot reload\n* `npm run build`: Build for production (output to `/public/build`)\n* `npm run preview`: Preview production build locally\n\n---\n\n## 8. πŸš€ Deployment to Production\n\n1. **Build locally:**\n\n ```bash\n npm run build\n ```\n\n2. **Upload `/public/build/` folder to your server**, next to `index.php` inside `public_html/`\n\n3. Ensure these files exist on the server:\n\n ```\n public_html/build/css/app-*.css\n public_html/build/js/app-*.js\n public_html/build/manifest.json\n ```\n\n4. Done! Visit your domain (e.g., `https://yourdomain.com`) β€” everything should load properly, including styles and Vue components.\n\n---\n\n## βœ… Summary\n\n| Tool | Purpose |\n| ------------ | ------------------------------------------------- |\n| **Vite** | Fast dev server and production bundler |\n| **Vue** | Frontend framework for components & interactivity |\n| **Laravel** | Backend framework to manage routes, data, views |\n| **Tailwind** | Utility-first CSS for fast styling |\n| **PostCSS** | Processes Tailwind and autoprefixes CSS |\n\n---\n\n## πŸ’‘ Final Notes\n\n* Make sure the `APP_URL` in `.env` matches your domain:\n\n ```\n APP_URL=https://yourdomain.com\n ```\n\n* The `@vite()` directive works only if:\n\n * `manifest.json` exists in `/public/build`\n * The paths are correctly defined in `vite.config.js`\n","timestamp":"2025-07-05T21:26:23.261Z","comments":[]}]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment