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

سمير عبود

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

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

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

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

    34

إجابات الأسئلة

  1. إجابة سمير عبود سؤال في ظهور صفحة 404 عند استخدام laravel-localization كانت الإجابة المقبولة   
    جرب تعليق ذلك السطر و ضع مكانه هذا السطر:
    Route::get('/', function () { dd("test"); }); ثم قم بعمل clear لأي cache او إعدادات عن طريق الأمر:
    php artisan optimize:clear ثم حاول تشغيل التطبيق.
  2. إجابة سمير عبود سؤال في إضافة حقول لصفحة التسجيل Laravel Jetstream كانت الإجابة المقبولة   
    لإضافة حقول جديدة تحتاج إتباع الخطوات التالية:
    إضافة الحقول لملف التهجير الخاص بالمُستخدمين: <?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); }); }); } و الآن قد جهزت كل شيء و تحتاج فقط للتجربة.
  3. إجابة سمير عبود سؤال في مشكلة في كود لارافيل Trying to get property 'meta_value' of non-object كانت الإجابة المقبولة   
    السبب في ذلك أن الشرط الذي تستخدمه دائماً مُحقق فأحياناً لا يوجد سجل يُطابق ما تبحث عنه فيُرجع 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;
  4. إجابة سمير عبود سؤال في التحقق من البريد الإلكتروني في Laravel كانت الإجابة المقبولة   
    توفر لارافيل هذه الخاصية مُسبقاً و ما عليك إلا تفعيلها في المشروع و يتم ذلك عن طريق:
    تطبيق الواجهة 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 () { // المسارات التي تريد حمايتها }); و بهذا الشكل إذا قام أحد المُستخدمين الذين لم يُفعلو حسابهم بتصفح هذه المسارات يتم إعادة توجيههم تلقائياً إلى صفحة التحقق من البريد الإلكتروني.
  5. إجابة سمير عبود سؤال في مُشكلة عدم ظهور الصور في Laravel JetStream كانت الإجابة المقبولة   
    في ملف 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 و في هذه الحالة ستظهر الصورة أيضاً.
  6. إجابة سمير عبود سؤال في تخصيص صفحات عرض الأخطاء في Laravel كانت الإجابة المقبولة   
    بإمكانك إنشاء صفحات عرض للأخطاء خاصة بك او التعديل على صفحات العرض الخاصة بعرض الأخطاء التي تستخدمها لارافيل بنشر مُجلد الأخطاء الذي تستخدمه لارافيل ضمن ملفات مشروعك عن طريق الأمر:
    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', __('الصفحة غير موجودة')) أو إنشاء قالب لصفحات الأخطاء بالشكل الذي نريد ثم نستخدمه.
  7. إجابة سمير عبود سؤال في تعديل قيمة عمود عند استرجاع النموذج بناءً على عمود مختلف في Laravel كانت الإجابة المقبولة   
    يُمكن عمل ذلك عن طريق الموصلات او 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.
  8. إجابة سمير عبود سؤال في كيفية إضافة CDN لـ css داخل مكون Livewire واحد فقط كانت الإجابة المقبولة   
    نعم إضافة ملفات تنسيقات خارجية او ملفات جافاسكربت تُضاف بنفس طريقة إضافتها في ملفات ال 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
  9. إجابة سمير عبود سؤال في خطأ Failed to execute replaceChild on Node عند إستخدام Laravel Livewire كانت الإجابة المقبولة   
    يبدو أن Livewire يكتشف أن العنصر الذي يحتوي على مشغل الفيديو قد تغير ويحاول استبداله.
    عليك إضافة التوجيه wire:ignore للعُنصر الحاوي لعُنصر الفيديو أو عُنصر الفيديو نفسه:
    <video class="video-js" wire:ignore> تختلط الأمور على Livewire عندما يتم التلاعب بالصفحة بإستخدام شيفرات جافاسكربت خارجية دون علم Livewire بذلك، مُعظم المشاكل من هذا النوع يتم حلها بإضافة التوجيه او الخاصية "wire:ignore"
  10. إجابة سمير عبود سؤال في فلترة المُستخدمين حسب عدد الطلبات او حسب قيمة الطلبات في Laravel كانت الإجابة المقبولة   
    يُمكنك إستخدام 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); بنفس الطريقة إن أردت تحديد مجال لعدد الطلبات يُمكنك ذلك أيضاً.
  11. إجابة سمير عبود سؤال في List Python كانت الإجابة المقبولة   
    في لغة بايثون لجمع عناصر مصفوفة نستخدم الدالة 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 يُمكنك إستخدام هذه المراحل لإنشاء دالة تفعل ما تريد.
  12. إجابة سمير عبود سؤال في خطأ عند إستخدام Laravel Socialite عبر Api كانت الإجابة المقبولة   
    بما أنك تستخدم الحزمة عبر 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();
  13. إجابة سمير عبود سؤال في خطأ في إرجاع بيانات العلاقة في laravel كانت الإجابة المقبولة   
    حتى تستطيع إستخدام التحميل الحثيث بإستخدام التابع 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(); و بهذا الشكل سيتم إرجاع بيانات العلاقة بنفس الحقول التي حددتها.
  14. إجابة سمير عبود سؤال في كيفية عمل real time validation في Laravel Livewire كانت الإجابة المقبولة   
    أولا يجب إضافة قواعد التحقق في المُكون بالشكل التالي مثلاً:
    protected $rules = [ 'title' => 'required|min:10', 'description' => 'required' ]; بعد ذلك تستدعي دالة التحقق في الدالة addTask:
    <?php public function addTask() { $this->validate(); // ... } ثم تضيف التابع updated للمُكون ليُصبح بالشكل التالي:
    <?php class AppAddTask extends Component { public $title; public $description; protected $rules = [ 'title' => 'required|min:10', 'description' => 'required' ]; public function render() { return view('livewire.app-add-task'); } public function updated($property) { $this->validateOnly($property); } public function addTask() { $this->validate(); // ... } } ثم في صفحة عرض المُكون تعرض رسائل الخطأ:
    <div> <h3 class="text-center">Add New Task</h3> <div class="form-group"> <label for="title">Title</label> <input type="text" wire:model="title" class="form-control @error('title') is-invalid @enderror"> @error('title') <span class="error" role="alert"> <strong class="text-danger">{{ $message }}</strong> </span> @enderror </div> <div class="form-group"> <label for="description">Description</label> <textarea wire:model="description" class="form-control @error('description') is-invalid @enderror"></textarea> @error('description') <span class="error" role="alert"> <strong class="text-danger">{{ $message }}</strong> </span> @enderror </div> <div class="form-group"> <button wire:click.prevent="addTask" class="btn btn-primary btn-block">Add</button> </div> </div> و بهذا الشكل سيتم التحقق في الوقت الفعلي و يتم عرض أي رسالة خطأ إن وجدت.
  15. إجابة سمير عبود سؤال في كيفية إضافة Pagination في Laravel Livewire كانت الإجابة المقبولة   
    يُمكنك إستخدام الtrait WithPagination الذي يسمح لك بإضافة التصفح لمكون livewire ثم تحدد القالب على أنه bootstrap بهذا الشكل:
    use Livewire\WithPagination; class AppTasks extends Component { use WithPagination; protected $paginationTheme = 'bootstrap'; protected $listeners = ['taskAdded' => '$refresh']; public function render() { $totalTasks = auth()->user()->tasks()->count(); $tasks = auth()->user()->tasks()->latest()->paginate(5); return view('livewire.app-tasks', [ 'totalTasks' => $totalTasks, 'tasks' => $tasks ]); } } ثم إضافة السطر:
    {{ $tasks->links() }} لصفحة العرض. و سيظهر ترقيم الصفحات بشكل عادي، يُمكنك أيضاً إستخدام قالب خاص بك للصفحات إن رغبت في ذلك و الطريقة موجودة في التوثيق الرسمي : Pagination
  16. إجابة سمير عبود سؤال في الإتصال بين مُكونين في laravel livewire كانت الإجابة المقبولة   
    نعم فالفكرة تكمن في إستخدام الأحداث و هناك عدة طرق لإستخدامها من بينها إرسال أو عمل emit للحدث من خلال المُكون الأول و التسمع على الحدث في المُكون الثاني لكن بما أننا نريد عمل تحديث ف livewire توفر طريقة خاصة إسمها $refresh، يُمكن التعامل مع الأحداث بعدة طرق عن طريق القالب أو عن طريق كلاس المُكون أو عن طريق javascript و هذا شرح الطريقة الثانية:
    إرسال الحدث من المكون الأول:
    class AppAddTask extends Component { public $title; public function render() { return view('livewire.app-add-task'); } public function addTask() { auth()->user()->tasks()->create([ 'title' => $this->title, 'status' => false, ]); $this->title = ""; $this->emit('taskAdded'); // هنا قمنا بإرسال الحدث } } التسمع على الحدث من خلال المُكون الثاني و عمل refresh: 
    class AppTasks extends Component { protected $listeners = ['taskAdded' => '$refresh']; // التسمع و عمل تحديث public function render() { $totalTasks = auth()->user()->tasks()->count(); $tasks = auth()->user()->tasks()->latest()->get(); return view('livewire.app-tasks', [ 'totalTasks' => $totalTasks, 'tasks' => $tasks ]); } }
  17. إجابة سمير عبود سؤال في إختبار رفع فيديو لا ينجح Laravel Livewire كانت الإجابة المقبولة   
    هذا غالباً يحدث بسبب فشل ال validation حيث أنك تتحقق من mime type لكن في الإختبار الملف الوهمي لا يحتوي على نفس mime type هنا:
    <?php $file = UploadedFile::fake()->create( 'video.mp4', $sizeInKilobytes, 'mp4' ); لذلك حاول تغيير هذه الأسطر:
    <?php $file = UploadedFile::fake()->create( 'video.mp4', $sizeInKilobytes, 'mp4' ); إلى mime type صحيح بهذا الشكل:
    <?php $file = UploadedFile::fake()->create( 'video.mp4', $sizeInKilobytes, 'video/mp4' );
  18. إجابة سمير عبود سؤال في حفظ حاصل ضرب حقلين في حقل جديد بلغة الجافا سكربت كانت الإجابة المقبولة   
    المُشكلة أن حقول الإدخال لا تكون موجودة عند تحميل الصفحة و إنما يتم إضافتها عن طريق جافاسكربت فيما بعد، لذلك حتى تعمل يجب أن تُغير هذه:
    $(function () { $('.marker-hight-production, .layers-count').keyup (function() { let x = $(".marker-hight-production").val(), y = $(".layers-count").val(); $('.consumption-m').val(x * y); }); }); إلى هذا الشكل:
    $(function () { $(document).on('keyup', '.marker-hight-production, .layers-count', function() { let x = $(".marker-hight-production").val(), y = $(".layers-count").val(); $('.consumption-m').val(x * y); }); }); و ستعمل.
  19. إجابة سمير عبود سؤال في تعديل حقل معين إعتمادا على شرط في لارافيل كانت الإجابة المقبولة   
    نعم يُمكنك عمل ذلك بإستخدام بإستخدام مُعامل الشرط الثلاثي داخل الدالة update كما هو موضح أدناه:
    <?php Company::find($id)->update([ 'company_name' => $request->company_name, 'former_company' => $request->former_company ] + ($imageName ? [ 'company_logo' => $imageName ] : [])); و هذا يعني أننا نريد إضافة مصفوفة جديدة للمصفوفة الأولى تضم الحقل company_name في حالة ما إذا كان imageName لا يساوي null أما في الحالة المُعاكسة نضيف مصفوفة فارغة.
    أو يُمكنك إستخدام التالي:
    <?php Company::find($id)->update($request->only('company_name', 'former_company') + ($imageName ? [ 'company_logo' => $imageName ] : [])); هذا بطريقة مُختصرة يُمكنك أيضاً إنشاء المصفوفة خارج الدالة update. ثم تتفحص إن كان imageName يساوي null و على أساسه تضيف حقل جديد للمصفوفة ثم تمررها للدالة update
  20. إجابة سمير عبود سؤال في إستخدام when في laravel للتخلص من الشروط كانت الإجابة المقبولة   
    يُمكنك إستخدام when بالشكل التالي:
    $getSales = Shoppingcart::when($this->searchTerm, function ($query, $searchTerm) { return $query->where('trans_code', 'LIKE', "%{$searchTerm}%"); }, function ($query) { return $query->with('user'); })->select('trans_code', 'created_at', DB::raw("SUM(sub_total) as total")) ->groupBy('trans_code') ->paginate(10); يُمكنك الإطلاع على توثيق موسوعة حسوب: البنود المشروطة (Conditional Clauses) و ستجد مثال يُشابه لما تريد في هذه الفقرة:
    يُنفّذ التابع when النطاق المُغلق المحدّد Closure فقط عندما تكون المعاملة الأولى true. في حالة كانت المعاملة الأولى false لن يُنفّذ النطاق المغلق Closure. تستطيع تمرير نطاق مُغلق Closure آخر كثالث معامل للتابع when. سيُنفّذ هذا النطاق المُغلق في حالة كانت المعاملة الأولى false. 
  21. إجابة سمير عبود سؤال في laravel Job / Queue مُعالجة غير منتهية كانت الإجابة المقبولة   
    هذه المُشكلة تحدث لأن الأمر:
    php artisan queue:work سيُواصل العمل لحين يتم إنهاؤه يدوياً او إغلاق الطرفية. لذلك laravel تُوفر الأمر:
    php artisan queue:work --tries=3 يُمكنك تمرير عدد مرات المُحاولة بإستخدام --tries لتجنب الحلقة الغير مُنتهية التي تحدث بسبب خطأ في تنفيذ ال job و لمعرفة الخطأ الذي يُسبب المُشكلة يُمكنك الإطلاع على ملف laravel.log و ستجد سبب المُشكلة أيضاً يُمكنك الإطلاع على جدول failed_jobs في العمود exception لتعرف سبب المُشكلة إذا كنت تستخدم database driver.
  22. إجابة سمير عبود سؤال في تقليل عدد الإستعلامات في لارافيل كانت الإجابة المقبولة   
    للتخلص من الإستعلامات الإضافية او تخفيض عدد الإستعلامات إستخدم دائماً التحميل الحثيث Eager loading او التحميل المُسبق للعلاقات لأنه عند إستخدامك للعلاقة كخاصية من دون التحميل الحثيث سيتم إجراء إستعلام إضافي في كل مرة و هذه المُشكلة تُسمى ب N + 1 أي من أجل كل كائن تستعلم N مرة إضافية.
    ففي حالتك مثلاً:
    في النموذج Comment
    public function children() { return $this->hasMany(Comment::class, 'parent_id'); } في المُتحكم:
    public function show($slug) { $article = Article::with(['comments' => function ($query) { $query->with('children')->where('status', true); }])->where('slug', $slug)->firstOrFail(); return view('article.show', compact('article')); } في صفحة العرض تكون بهذا الشكل مثلاً:
    @foreach($article->comments as $comment) {{ $comment->body }} @foreach($comment->children as $subComment) {{ $subComment->body }} @endforeach @endforeach
  23. إجابة سمير عبود سؤال في خطأ أثناء تنفيذ شيفرة بلغة JavaScript كانت الإجابة المقبولة   
    المُشكلة التي ظهرت لك بسبب هذا السطر:
    let name = fares; لان جافاسكربت لا تعرف الكلمة fares فهي ليست كلمة محجوزة في اللغة، كما أنه لا يوجد في السكربت أي مُتغير بالإسم fares.
    أعتقد أنك تريد تعريف مُتغير name و إسناد إسمك له كقيمة. لكن لعمل هذا تحتاج أن تُخبر جافاسكرت بأنه نص بإستعمال علامتي التنصيص بهذا الشكل مثلاً:
    let name = "fares"; و هذا ما تُوضحه رسالة الخطأ:
    Uncaught ReferenceError: fares is not defined
  24. إجابة سمير عبود سؤال في إضافة ملف لدوال مُساعدة في Laravel كانت الإجابة المقبولة   
    يُمكنك ذلك من خلال إنشاء ملف php عادي في أي مسار تريده مثلاً في:
    tests |_ Utilities |_|___ functions.php و تضع الدوال التي تحتاجها فيه مثلاً:
    <?php function create($class, $attributes = []) { return $class::factory()->create($attributes); } function make($class, $attributes = []) { return $class::factory()->make($attributes); } الآن ستقوم بإضافة عملية التحميل التلقائي للملف من خلال composer و لعمل ذلك تحتاج التعديل على ملف composer.json:
    إن كنت تحتاج أن تتم عملية التحميل التلقائي للملف فقط في مرحلة التطوير ستُضيف مسار الملف داخل مصفوفة files ضمن الخاصية autoload-dev:
    "autoload-dev": { "psr-4": { "Tests\\": "tests/" }, "files": ["tests/Utilities/functions.php"] }, أما إن أردت أن تشمل العملية مرحلة الإنتاج فستضع مسار الملف داخل مصفوفة files في الخاصية autoload:
    "autoload": { "psr-4": { "App\\": "app/", "Database\\Factories\\": "database/factories/", "Database\\Seeders\\": "database/seeders/" }, "files": ["tests/Utilities/functions.php"] }, بعد ذلك قم بتنفيذ أمر:
    composer dump-autoload ثم ستتمكن من إستخدام الدوال التي أنشأتها في أي مكان تريد، في المثال أرفقت دالتين إحداهما لإنشاء سجل جديد من نموذج معين و الثانية تُنشئ السجل و تقوم بتخزينه في قاعدة البيانات، و هاتين الدالتين تحتاج لهما كثيرا في الإختبارات: 
    و هذا مثال عن إستخدامها:
    <?php /** @test */ function an_authenticated_user_may_participate_in_forum_threads() { $this->signIn(); $reply = make(Reply::class); $this->post($this->thread->path . "/replies", $reply->toArray()); $this->get($this->thread->path) ->assertSee($reply->body); }  
  25. إجابة سمير عبود سؤال في خطأ أثناء رفع ملف في Laravel كانت الإجابة المقبولة   
    تحدث هذه المُشكلة لك بسبب أنك حددت إسم المُجلد في المُعامل الأول للدالة put، مثلاً إن كنت تريد وضع الملفات داخل مُجلد images يُمكنك ذلك من خلال:
    public function test(Request $request) { $fileInForm = 'file'; if ($request->hasFile($fileInForm)) { $file = $request->file($fileInForm); if ($file->isValid()) { // Filename is hashed filename + part of timestamp $hashedName = hash_file('md5', $file->path()); $timestamp = microtime(); $newFilename = $hashedName . $timestamp . '.' . $file->getClientOriginalExtension(); Storage::disk('local')->putFile('images', $file); } } } في هذه الحالة سيتم حفظ الملفات داخل مُجلد images و ستُعطي لارافيل إسم مُختلف للملف المرفوع في كل مرة تلقائياً، و ستُرجع الدالة putFile المسار الذي تم حفظ الملف فيه يُمكنك حفظه إن احتجت له.
    إن كنت ترغب في وضع الإسم الذي يُحفظ به الملف بنفسك يُمكنك إستخدام الدالة putFileAs بنفس الطريقة و تُمرر الإسم الذي ترغب فيه كمعامل ثالث:
    public function test(Request $request) { $fileInForm = 'file'; if ($request->hasFile($fileInForm)) { $file = $request->file($fileInForm); if ($file->isValid()) { // Filename is hashed filename + part of timestamp $hashedName = hash_file('md5', $file->path()); $timestamp = microtime(); $newFilename = $hashedName . $timestamp . '.' . $file->getClientOriginalExtension(); Storage::disk('local')->putFileAs('images', $file, $newFilename); } } } تُرجع الدالة أيضاً مسار الملف.
    تُتيح لارافيل أيضاً دالتي store و storeAs لكن هاتين الدالتين لا تُستخدمان بإستعمال الfacade بل مُباشرة على الملف بهذا الشكل مثلاً:
    $path = $request->file('file')->store('images'); $path = $request->file('file')->storeAs( 'images', $newName );  
×
×
  • أضف...