اذهب إلى المحتوى

سمير عبود

الأعضاء
  • المساهمات

    3552
  • تاريخ الانضمام

  • تاريخ آخر زيارة

  • عدد الأيام التي تصدر بها

    34

كل منشورات العضو سمير عبود

  1. أعتقد أن علامة النجمة تعني أن ذلك المحتوى أو الدرس تقوم بمتابعته، أما علامة النقطة تعني أن ذلك المحتوى أو الدرس جديد لم تقم بقراءته أو الإطلاع عليه من قبل.
  2. يبدو أن المنفذ الإفتراضي الذي يتم تشغيل خادم websockets عليه من طرف الحزمة قيد التشغيل من طرف برنامج آخر أو Process آخر لذلك عليك تغييره لمنفذ لايتم إستخدامه حيث أنه يُمكن تمرير flag للأمر عن طريق --port و تمرير المنفذ الذي تريد بهذا الشكل: php artisan websockets:serve --port={port} مثال: php artisan websockets:serve --port=3030 كما يُمكن أيضاً تغيير المنفذ من خلال ملف إعدادات الحزمة عن طريق نشر الملف ضمن مجلد الإعدادات: php artisan vendor:publish --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider" --tag="config" بعد ذلك يُمكنك تغيير السطر: 'dashboard' => [ 'port' => env('LARAVEL_WEBSOCKETS_PORT', 6001), ], لاحظ أنه 6001 يُمكنك تغييره او إسناد قيمة ل LARAVEL_WEBSOCKETS_PORT في ملف env.
  3. بخصوص الصنف الذي لا يتم نشره عن طريق أمر: php artisan vendor:publish --tag=jetstream-views تحتاج إلى خطوات إضافية: إنشاء مُجلد Livewire في المسار: app\Http إن لم يكن موجود إنشاء صنف UpdateProfileInformationForm.php داخل المجلد Livewire نسخ مُحتوى الصنف \vendor\laravel\jetstream\src\Http\Livewire\UpdateProfileInformationForm.php إلى الصنف الذي أنشأته مع تعديل مجال الأسماء الخاص به. في مزود الخدمة JetstreamServiceProvider داخل التابع boot قم بإضافة: Livewire::component('profile.update-profile-information-form', UpdateProfileInformationForm::class); و لا تنسى إستدعاء الصنف الذي قمت بإنشائه النُسخة الخاصة بك. use App\Http\Livewire\UpdateProfileInformationForm; بعد ذلك يُمكنك التعديل كيفما شئت على الصنف.
  4. جرب تعليق ذلك السطر و ضع مكانه هذا السطر: Route::get('/', function () { dd("test"); }); ثم قم بعمل clear لأي cache او إعدادات عن طريق الأمر: php artisan optimize:clear ثم حاول تشغيل التطبيق.
  5. ماهو المسار الذي تُحاول الوصول إليه أي مسار من المسارات المرفقة أعلاه ظهرت صفحة 404
  6. لإضافة حقول جديدة تحتاج إتباع الخطوات التالية: إضافة الحقول لملف التهجير الخاص بالمُستخدمين: <?php public function up() { Schema::create('users', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('company'); // الحقل المضاف $table->string('email')->unique(); $table->timestamp('email_verified_at')->nullable(); $table->string('password'); $table->rememberToken(); $table->foreignId('current_team_id')->nullable(); $table->text('profile_photo_path')->nullable(); $table->timestamps(); }); } تنفيذ أمر التهجير: php artisan migrate:fresh إضافة الحقول الجديدة لمصفوفة fillable في النموذج User: <?php protected $fillable = [ 'name', 'email', 'password', 'company' ]; بعد ذلك تضيف الحقول لصفحة العرض register.blade.php الموجود في المسار resources\views\auth\register.blade.php <div class="mt-4"> <x-jet-label for="company" value="{{ __('Company') }}" /> <x-jet-input id="company" class="block mt-1 w-full" type="text" name="company" :value="old('company')" required /> </div> ثم تذهب إلى الصنف CreateNewUser الموجود في المسار: app\Actions\Fortify\CreateNewUser.php و تقوم بالتحقق من الحقول المُضافة و إضافتها للتابع create: <?php public function create(array $input) { Validator::make($input, [ 'name' => ['required', 'string', 'max:255'], 'company' => ['required', 'string', 'max:255'], 'email' => ['required', 'string', 'email', 'max:255', 'unique:users'], 'password' => $this->passwordRules(), 'terms' => Jetstream::hasTermsAndPrivacyPolicyFeature() ? ['required', 'accepted'] : '', ])->validate(); return DB::transaction(function () use ($input) { return tap(User::create([ 'name' => $input['name'], 'company' => $input['company'], 'email' => $input['email'], 'password' => Hash::make($input['password']), ]), function (User $user) { $this->createTeam($user); }); }); } و الآن قد جهزت كل شيء و تحتاج فقط للتجربة.
  7. السبب في ذلك أن الشرط الذي تستخدمه دائماً مُحقق فأحياناً لا يوجد سجل يُطابق ما تبحث عنه فيُرجع Null و أنت تحاول الوصول للخاصية meta_value من null، الصواب هو ان يكون بهذا الشكل مثلاً: <?php if ( $post_meta->where('meta_key', 'faq_content')->exists() ) { $faq_number = $post_meta->where('meta_key', 'faq_content')->first()->meta_value; } else { $faq_number = 0; } أو بهذا الشكل أحسن: <?php if ( $something = $post_meta->where('meta_key', 'faq_content')->first() ) { $faq_number = $something->meta_value; } else { $faq_number = 0; } أو تبسيط الشرط و إستخدام مُعامل الإندماج الفارغ ( Null coalescing operator): $faq_number = $post_meta->where('meta_key', 'faq_content')->first()->meta_value ?? 0;
  8. توفر لارافيل هذه الخاصية مُسبقاً و ما عليك إلا تفعيلها في المشروع و يتم ذلك عن طريق: تطبيق الواجهة MustVerifyEmail على النموذج User: <?php namespace App\Models; use Illuminate\Contracts\Auth\MustVerifyEmail; // ... class User extends Authenticatable implements MustVerifyEmail { use HasFactory, Notifiable; // ... } بعد ذلك في ملف المسارات تحتاج إلى التعديل على: Auth::routes(); ليُصبح: Auth::routes(['verify' => true]); إذا لم تقم بإضافة إعدادات البريد الإلكتروني في ملف .env يجب إضافتها: MAIL_MAILER=smtp MAIL_HOST=smtp.mailtrap.io MAIL_PORT=2525 MAIL_USERNAME= MAIL_PASSWORD= MAIL_ENCRYPTION=null MAIL_FROM_ADDRESS="laravel@app.com" MAIL_FROM_NAME="${APP_NAME}" يُمكنك إستخدام خدمة mailtrap إن كنت في مرحلة التطوير، بعد ذلك تحتاج إلى حماية المسارات من المستخدمين الذي لم يقومو بتفعيل حسابهم بإضافة ال middleware verified كما هو موضح أدناه: Route::middleware(['verified'])->group(function () { // المسارات التي تريد حمايتها }); و بهذا الشكل إذا قام أحد المُستخدمين الذين لم يُفعلو حسابهم بتصفح هذه المسارات يتم إعادة توجيههم تلقائياً إلى صفحة التحقق من البريد الإلكتروني.
  9. اسم القالب في الموقع الذي أرفقته هو موضوع و هذا كان إسمه سابقاً و الآن إسمه هو بحر و هو قالب مدفوع يُمكنك معرفة إسم القالب لاي موقع إن كان مبني على ووردبريس بالطريقة التالية:
  10. أعتقد أن المُشكلة في جزء with يجب أن تكون بهذا الشكل: $view->with([ 'current_user_notification' => $current_user_notification, 'current_user_notification_count' => $current_user_notification_count ]); ليُصبح الكود ككل بهذا الشكل: <?php View::composer('layouts.dashboard.master', function($view){ $userNoteRepository = resolve(UserNoteRepositoryInterface::class); $current_user_notification = $userNoteRepository->getCurrentUserAlertNotifications(); $current_user_notification_count = count($userNoteRepository->getCurrentUserAlertNotifications()); $view->with([ 'current_user_notification' => $current_user_notification, 'current_user_notification_count' => $current_user_notification_count ]); });
  11. حزمة laravel horizon الإصدار الآخير اي حالياً (5.7) يحتاج إلى هذه المتطلبات: requires php: ^7.3|^8.0 ext-json: * ext-pcntl: * ext-posix: * illuminate/contracts: ^8.17 illuminate/queue: ^8.17 illuminate/support: ^8.17 nesbot/carbon: ^2.17 ramsey/uuid: ^4.0 symfony/error-handler: ^5.0 symfony/process: ^5.0 requires (dev) mockery/mockery: ^1.0 orchestra/testbench: ^6.0 phpunit/phpunit: ^9.0 predis/predis: ^1.1 عليك التحقق منها، إصدار لارافيل الخاص بالمشروع يجب أن يكون أعلى من 8.17 بخصوص المُشكلة التي تواجهك يُمكن حلها بالشكل التالي: تعديل ملف composer.json بإضافة التالي للخاصية config: "config": { "platform": { "ext-pcntl": "7.1", "ext-posix": "7.1" }, } بعد ذلك أعد تنفيذ أمر تثبيت الحزمة: composer require laravel/horizon ثم: php artisan horizon:install
  12. في ملف jetstream.php الخاص بالإعدادات تجد أن jetstream يستخدم: 'profile_photo_disk' => 'public', و إذا ذهبنا إلى ملف الإعدادات الخاص ب filesystem نجد: <?php 'public' => [ 'driver' => 'local', 'root' => storage_path('app/public'), 'url' => env('APP_URL').'/storage', 'visibility' => 'public', ], اي أن ال disk public يعتمد على الثابت: APP_URL في ملف env. و يعتمد على الوصلة التي يتم إنشاؤها بين مُجلد storage و مُجلد public لذلك عليك الإنتباه لهذا الأمر: فأولا قم بإنشاء الوصلة عن طريق الأمر: php artisan storage:link بعد ذلك إن كنت تتصفح المشروع عن طريق: http://127.0.0.1:8000 عليك تعديل قيمة APP_URL بهذا الشكل: APP_URL=http://127.0.0.1:8000 و بهذا الشكل ستظهر الصور بشكل طبيعي، أما إن كنت تستخدم خادم وهمي بالرابط التالي مثلاً: http://cms.test تحتاج إلى وضع ذلك الرابط في APP_URL APP_URL=http://cms.test و في هذه الحالة ستظهر الصورة أيضاً.
  13. بإمكانك إنشاء صفحات عرض للأخطاء خاصة بك او التعديل على صفحات العرض الخاصة بعرض الأخطاء التي تستخدمها لارافيل بنشر مُجلد الأخطاء الذي تستخدمه لارافيل ضمن ملفات مشروعك عن طريق الأمر: php artisan vendor:publish --tag=laravel-errors هذا الأمر سيقوم بعمل نسخ للملفات ضمن مُجلد errors في مُجلد views حيث كل خطأ له ملف بنفس الإسم بالإضافة إلى 3 أنواع من القوالب الجاهزة يُمكنك إستخدامها لنأخذ مثال: 404.blade: @extends('errors::minimal') @section('title', __('Not Found')) @section('code', '404') @section('message', __('Not Found')) يُمكننا تعديله بهذا الشكل: @extends('errors::illustrated-layout') @section('title', __('الصفحة غير موجودة')) @section('code', '404') @section('message', __('الصفحة غير موجودة')) أو إنشاء قالب لصفحات الأخطاء بالشكل الذي نريد ثم نستخدمه.
  14. وسائل سحب الرصيد المتوفرة هي باي بال فقط و للمبالغ أكبر من 25$ إن لم يكن لديك حساب مُفعل على باي بال لا تستطيع السحب، يلجأ المستقلين في هذه الحالة إلى الإستعانة بأصدقاء موثوقين أو أقارب لديهم حساب باي بال كي يلعبو دور الوسيط ثم يقوم هذا الوسيط بتحويل المال لك بعد إستلامه. هناك جهات أخرى تقوم بالتحويل و ذلك بأخذ نسبة من المبلغ بعد التحويل بعد الإتفاق بينكم لكن لا أنصحك بهم فقد لا يكونون موثوقين و قد يضيع جهدك، لذلك من الأحسن أن يكون لديك حساب خاص بك، لكن إن كنت مضطر تأكد من الثقة أولاً.
  15. يُمكن عمل ذلك عن طريق الموصلات او Accessors مثلا لنقل أنه لديك عمود first_name و عمود last_name و تريد الإسم الكامل عند إسترجاع النموذج يُمكنك ذلك عن طريق إنشاء موصل بالشكل التالي في النموذج: public function getFullNameAttribute() { return "{$this->first_name} {$this->last_name}"; } و عند جلب النموذج يُمكنك الوصول للإسم الكامل عن طريق الخاصية: full_name. بنفس الطريقة يُمكنك إستخدام موصل لجلب الخاصية message بالشكل الذي تريد و بداخلها تستخدم الدالة str_replace لإستبدال المفاتيح بما يوافقها من قيم في الخاصية data بهذا الشكل مثلا: public function getFormattedMessageAttribute() { $message = $this->message; foreach ($this-data as $key => $value) { $message = str_replace("{{$key}}", $value, $message); } return $message } ثم عند جلب النموذج يُمكنك الوصول للشكل الذي تريده من خلال الوصول للخاصية formatted_message.
  16. نعم إضافة ملفات تنسيقات خارجية او ملفات جافاسكربت تُضاف بنفس طريقة إضافتها في ملفات ال blade العادية، فمثلا إذا كنت تريد إضافة ملف تنسيقات تحتاج إلى إضافة التوجيه: @yield('custom_css') في ملف layout قبل إستدعاء @livewireStyles ثم تستخدم التوجيه section في ملف ال blade الخاص بالمُكون بالشكل التالي: @section('custom_css') //....CDN @endsection أو يُمكنك إستخدام stack بدل yield بهذا الشكل: @stack('custom_css') ثم في ملف ال blade الخاص بالمُكون تستخدم التوجيه push بهذا الشكل: @push('custom_css') // ..... CDN @endpush
  17. يبدو أن Livewire يكتشف أن العنصر الذي يحتوي على مشغل الفيديو قد تغير ويحاول استبداله. عليك إضافة التوجيه wire:ignore للعُنصر الحاوي لعُنصر الفيديو أو عُنصر الفيديو نفسه: <video class="video-js" wire:ignore> تختلط الأمور على Livewire عندما يتم التلاعب بالصفحة بإستخدام شيفرات جافاسكربت خارجية دون علم Livewire بذلك، مُعظم المشاكل من هذا النوع يتم حلها بإضافة التوجيه او الخاصية "wire:ignore"
  18. في لغة php الدالة موجودة لكن أنت لست مُجبر على إستخدامها عند إنشاء أصناف PHP، بالعكس فالأمر متروك لك و تُستخدم عند حاجتك للدالة و في الوضعيات التي تحتاجها، فبنفس طريقة إنشائك للكلاسات في اللغات الأخرى مثل جافا او بايثون يُمكنك إنشاء الكلاسات في PHP بدون إستخدام الدالة class_exists فلا تحصر نفسك في سياق مُحدد و الدالة ليست موجودة لهذا الأمر فقط، قد تحتاج في جزئية مُحددة من الكود إلى إنشاء كائن من كلاس ما لكن إسم الكلاس هذا ليس معلوماً لديك قد يكون الكلاس موجود أو قد يكون غير موجود فالإسم يأتيك على شكل ديناميكي فهل ستقوم بإنشاء الكائن مُباشرة قد يعطيك خطأ لذلك يُمكن إستخدام الدالة class_exists في هذه الحالة للتأكد من وجود الصنف قبل إنشاء كائن منه و إلا مُعالجة الأمر عن طريق رمي إستثناء او ما إلى ذلك و هذه حالة من الحالات. أعتقد انه حتى لو لم تُوفر اللغات التي ذكرتها دالة مُشابهة إلا انها وفرت طرق للحصول على نفس نتيجة الدالة. أعتقد أيضاً أن إستخدام الدالة في ووردبريس حتى لا يتم إنشاء كلاسات بنفس الأسماء مما قد يُشكل لك بعض المشاكل في التطبيق الخاص بك. إحرص دائما على معرفة ما الذي تفعله الدالة و لا تُقيد نفسك بسياق واحد او إستخدام واحد للدالة و إنما فكر دائماً خارج الصندوق. هناك أيضاً دوال مُشابهة مثل method_exists، function_exists تُوفرها لغة PHP.
  19. يُمكنك إستخدام join لعمل الشيء الذي تُريده بهذا الشكل: لعمل فلترة للمُستخدمين حسب الأكثر طلباً: <?php User::join('orders', 'orders.user_id', '=', 'users.id') ->selectRaw('users.*, count(orders.id) as orders_count, sum(orders.amount) as total_amount') ->groupBy('users.id') ->orderBy('orders_count', 'desc') ->paginate(10); لعمل فلترة للمُستخدمين حسب مجموع قيمة الطلبات: <?php User::join('orders', 'orders.user_id', '=', 'users.id') ->selectRaw('users.*, count(orders.id) as orders_count, sum(orders.amount) as total_amount') ->groupBy('users.id') ->orderBy('total_amount', 'desc') ->paginate(10); أما إن كنت تريد عمل فلترة للمُستخدمين حسب مجموع قيمة الطلبات بالإضافة لتحديد مجال للمجموع يُمكنك ذلك من خلال التالي: <?php $min_amount = 30000; $max_amount = 40000; User::join('orders', 'orders.user_id', '=', 'users.id') ->selectRaw('users.*, count(orders.id) as orders_count, sum(orders.amount) as total_amount') ->groupBy('users.id') ->havingRaw('total_amount >= ? and total_amount <= ?', [$min_amount, $max_amount]) ->orderBy('total_amount', 'desc') ->paginate(10); بنفس الطريقة إن أردت تحديد مجال لعدد الطلبات يُمكنك ذلك أيضاً.
  20. من المفروض عند إنهاء أي مشروع على المنصة يأتيك إشعار في حسابك أنه تم إضافة مبلغ بقيمة كذا لحسابك، لكن هذا المبلغ يكون مُعلق لمُدة 14 يوم علماً أن مدة التعليق تبدأ من اليوم التالي لاستلام المشروع وتستمر حتى انتهاء اليوم الرابع عشر بتوقيت غرينتش. أما زر سحب الرصيد يظهر إذا توفر الحد الأدني للسحب وهو 25 دولار، إذا توفرت كل هذه الشروط و لم تظهر أرباحك مع الرصيد القابل للسحب إفتح صفحة الرصيد لديك و أعد تحديثها أكثر من مرة أو قم بحذف الكاش من المتصفح فعادة المُتصفح لا يقوم بتحميل الصفحة كلها من الخادم و إنما يستخدم ذاكرة التخزين المُؤقت لتسريع عملية التصفح. تأكد أنه يُمكنك دائما مواصلة الدعم الفني للمنصة للإستفسار عن أي شيء تُريده من خلال: مركز المساعدة بفتح تذكرة لإستفسارك و سيرد عليك الإخوة هناك و مُساعدتك.
  21. في لغة بايثون لجمع عناصر مصفوفة نستخدم الدالة sum: print(sum([1, 2, 3])) # 6 لترتيب عناصر مصفوفة نستخدم الدالة sorted: print(sorted([11, 2, 1, 9, 7])) # [1, 2, 7, 9, 11] الدالة sorted تُرتب تصاعدياً لقلب الترتيب نستخدم الدالة sorted و نُمرر لها مُعامل آخر: print(sorted([11, 2, 1, 9, 7], reverse=True)) # [11, 9, 7, 2, 1] لأخذ قطعة من مصفوفة نستخدم slice كما هو موضح أدناه: a[start:stop] # نُحدد البداية و النهاية مثلاً: print([11, 2, 1, 9, 7][0:3]) # [11, 2, 1] إجمع كل هذه النقاط مع بعض للوصول للشيء الذي تُريده أولاً الترتيب بشكل تنازلي ثانياً أخذ قطعة من المصفوفة المرتبة مكونة من 3 أعداد ثم إستعمال الدالة sum. و هذا مثال بسيط: print(sum(sorted([11, 2, 1, 9, 7], reverse=True)[0:3])) # 27 يُمكنك إستخدام هذه المراحل لإنشاء دالة تفعل ما تريد.
  22. الفكرة ككل هي في جلب رقم الآحاد لعدد مُعين و نحصل على هذا الرقم بإجراء قسمة إقليدية للعدد على 10 حيث باقي القسمة هو رقم الآحاد مثلاً لنأخذ العدد 62 عندما نقسمه على 10 نتحصل على 6 و باقي قسمة هو 2 و هو الرقم المطلوب. غالباً في لغات البرمجة علامة باقي القسمة هي: % بعد هذه المعلومة تُصبح الأمور واضحة المعالم فكل ما يتبقى لك هو تعريف دالة تستقبل مُعامل واحد بالشكل التالي مثلاً بلغة بايثون: def sumRightDigit(numbers): تعريف متغير داخل الدالة لتخزين المجموع و إسناد القيمة 0 له: def sumRightDigit(numbers): sum = 0 عمل حلقة على عناصر المصفوفة و إضافة رقم الآحاد في كل لفة من الحلقة. def sumRightDigit(numbers): sum = 0 for number in numbers: sum += number % 10 في الأخير إرجاع قيمة المُتغير الذي يحمل مجموع الآحاد، ثم إستخدام الدالة: def sumRightDigit(numbers): sum = 0 for number in numbers: sum += number % 10 return sum print(sumRightDigit([10,21,3,8,9,11,44,62,100])) # 28 بنفس الطريقة يُمكننا إستخدام لغة جافاسكربت الفرق فقط في بعض الsyntax: function sumRightDigit(numbers) { sum = 0 for (i in numbers) sum += numbers[i] % 10 return sum } console.log(sumRightDigit([10,21,3,8,9,11,44,62,100])) // 28 إتبع نفس الطريقة في اي لغة تريد.
  23. بما أنك تستخدم الحزمة عبر API فإنك تحتاج إلى إستخدام stateless في كل من الطلب الأول و الطلب الثاني فبدل: <?php Socialite::with('facebook')->stateless()->redirect()->getTargetUrl(); $fb_user = Socialite::with('facebook')->user(); إستخدم: <?php Socialite::with('facebook')->stateless()->redirect()->getTargetUrl(); $fb_user = Socialite::with('facebook')->stateless()->user();
  24. يُمكنك إستخدام حزمة symfony/process فلارافيل تستخدمها من المفروض تكون مُثبتة مُسبقاً مع الإعتماديات. للتأكد أنها مُثبتة: composer show symfony/process أمر التثبيت: composer require symfony/process الإستخدام: <?php // إستدعاء الكلاسات use Symfony\Component\Process\Process; use Symfony\Component\Process\Exception\ProcessFailedException; // الإستخدام $process = new Process(['python','/path/to/your_script.py']); $process->run(); if (!$process->isSuccessful()) { throw new ProcessFailedException($process); } echo $process->getOutput();
  25. حتى تستطيع إستخدام التحميل الحثيث بإستخدام التابع with يجب عليك تحديد المفتاح الثانوي ضمن الحقول التي تختارها في التابع select تأكد تماما أن إسم المفتاح الثانوي هو payment_method_category_id ثم قم بتغيير: return PaymentMethod::select('name', 'slug') ->with(['category' => function($query){ $query->select('id', 'name')->where('status', 1); }])->get(); إلى الشكل التالي بإضافة تحديد حقل المفتاح الثانوي: <?php return PaymentMethod::select('name', 'slug', 'payment_method_category_id') ->with(['category' => function($query){ $query->select('id', 'name')->where('status', 1); }])->get(); و بهذا الشكل سيتم إرجاع بيانات العلاقة بنفس الحقول التي حددتها.
×
×
  • أضف...