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

Adnane Kadri

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

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

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

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

    51

كل منشورات العضو Adnane Kadri

  1. يحاول الخطأ اخبارك أنك قمت بتشغيل خادم ويب باك بإستعمال نمط غير صحيح، ويكون ذلك عادة في تعريف خاصية غير موجودة أو معرفة بشكل خاطئ، وفي الحالة التي لديك تلك الخاصية هي writeToDisk، ففي الغالب أنت تقوم بتعريفها وفق التالي: devServer: { .. writeToDisk: true, .. }, وهذا صحيح الى حد النسخة 4.0.0 - beta.0 من webpack dev-server ففي هاته النسخة وفق ما هو موضح في توثيق الحزمة قد تم نقل كل من الخواص fs index, mimeTypes, publicPath, serverSideRender, writeToDisk الى الكائن dev لتعرف وفق التالي: devServer: { dev:{ writeToDist:true, } } وبمجرد اطلاق النسخة 4.0.0 - beta.3 بزمن قصير قد تم اعادة تسمية الخاصية dev لتصبح devMiddleware وهو التعريف الذي استقرت عليه للآن. devServer: { devMiddleware:{ writeToDist:true, } } قد لا تحتاج كل هاته التفاصيل ولكنك ستحتاج حتما لتشخيص هذا الخطأ وحله معرفة أي نسخة تستعمل من webpack dev server وتعريف الخاصية بشكل صحيح وفق ما يوافقها. بجانب هذا سيكفيك ان تكون على اطلاع على الواجهة البرمجية لكائن devServer في التوثيق الرسمي.
  2. كل الوظائف موجهة لتنفيذ أوامر معينة تختلف فيما بينها من حيث أن: الوظيفة system تقوم بتنفيذ الأمر وإعادة خرج الأمر ان وجد. فهنا ستقوم أنت نفسك بالتعامل مع الخرج وفق نمط او فكرة معينة مثل تنسيقه. الوظيفة exec تقوم بتنفيذ الأمر وعرض خرج الأمر مباشرة، أي انه لن يمكن تخزينه في متغير بغرض تنسيقه أو عرضه وفق شكل معين. الوظيفة passthru تقوم بتنفيذ الأمر وعرض خرج الأمر بشكل خام (وحدات ثنائية binary) مباشرة. يجب الحذر بشأن استعمال هاته الوظائف ان كنت تستقبل أو تقوم بتخصيص هاته الاوامر وفق تعامل المستخدمين معها، ففي هجمات تزوير الطلبات عبر المواقع CSRF مثلا يمكن حقن سطر أوامر يسمح للمستهدف ܏بتنفيذ أي أوامر تخص النظام على خادم ويب. خصوصا في الخوادم الهشة مثل بعض تلك التي توفر استضافات مجانية، فهذا يعطي المهاجم تحكما كاملا بالنظام فضلا عن تحكمه بالموقع أو التطبيق. يتم كحل لهاته المشاكل تغليف وسائط الأوامر باستخدام الدالة escapeshellarg()‎ أو escapeshellcmd()‎ مما يجعلها غير قابلة للتنفيذ ومتحقق من صحة كل قيمة مدخلة. فان كنت تستقبل مثلا متغيرا path عبر الطلب GET لعرض محتويات مجلد ما لمشرف الموقع كالتالي: <pre> <?php system('ls ' . $_GET['path']); ?> </pre> فإن تعليف الأمر سيكون كـ: <pre> <?php system('ls ' . escapeshellarg($_GET['path'])); ?> </pre>
  3. يمكنك استعمال أحد توابع الكائن DateTime في PHP لعمل الفكرة، يجب أولا تمرير التاريخين الى الباني كالتالي: $first_date = new DateTime('2022-03-25 14:21:36'); $second_date = new DateTime('2022-03-26 10:15:48'); ثم سيمكن عن طريق التابع diff استخلاص الفرق بين التاريخين كالتالي: $difference = $first_date->diff($second_date); سيبدوا خرج النتيجة كائن DateInterval يبدوا كالتالي: object(DateInterval) public 'y' => int 0 public 'm' => int 0 public 'd' => int 20 public 'h' => int 6 public 'i' => int 56 public 's' => int 30 public 'invert' => int 0 public 'days' => int 20 واستخلاص الدقيقة من الخرج بشكل بسيط عن طريق قراءة الخاصية i: echo $difference->i; في حالة تجاوز الفرق لدقائق ستحتاج تحويل الساعات او الثواني او الايام الى دقائق هي الأخرى لحسابها ضمن الفرق. تعرف أكثر عن التعامل مع الوقت والتاريخ في PHP.
  4. واحدة من المميزات التي يقدمها لارافيل هي في إمكانية استعماله لاتصالات قواعد بيانات مختلفة، ولن يكون ذلك الا بإعداد كل منها في ملفات الاعداد. لاحظ أن ملف config/database.php يتوفر على مصفوفة بالمفتاح connections تحمل هاته المصفوفة تعريفات مختلفة من بينها تلك الخاصة بـ mysql و pgsql: 'mysql' => [ 'driver' => 'mysql', 'url' => env('DATABASE_URL'), 'host' => env('DB_HOST', '127.0.0.1'), 'port' => env('DB_PORT', '3306'), 'database' => env('DB_DATABASE', 'forge'), 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''), 'unix_socket' => env('DB_SOCKET', ''), 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', 'prefix_indexes' => true, 'strict' => true, 'engine' => null, 'options' => extension_loaded('pdo_mysql') ? array_filter([ PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), ]) : [], ], 'pgsql' => [ 'driver' => 'pgsql', 'url' => env('DATABASE_URL'), 'host' => env('DB_HOST', '127.0.0.1'), 'port' => env('DB_PORT', '5432'), 'database' => env('DB_DATABASE', 'forge'), 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''), 'charset' => 'utf8', 'prefix' => '', 'prefix_indexes' => true, 'schema' => 'public', 'sslmode' => 'prefer', ], كل نموذج Model من نماذج لارافيل يحتوي على الخاصية connection التي تكون مضبوطة على اتصال قواعد البيانات الافتراضي المعرف في ملف اعداد قواعد البيانات. يمكنك تخصيص تلك التي تعمل على اتصال قاعدة بيانات pgsql وتلك التي تعمل على اتصال mysql باسنادها كقيمة ل connection في ملف النموذج المستهدف: class Post extends Model{ protected $connection = 'pqsql'; .. } في ملف التهجير المرافق لهذا النموذج قم بضبط نفس الامر عن طريق استعمال التابع connection للواجهة Schema: Schema::connection('pqsql')->create('posts', function (Blueprint $table) { $table->id(); $table->string('title'); $table->timestamps(); }); بفرض أنك اتصالي قواعد البيانات اللذان لديك يعملان بشكل عادي، نفذ أمر التهجير php artisan migrate وستلاحظ أن كل قاعدة بيانات تهجر بها بيانات مختلفة.
  5. يحاول الخطأ اخبارك ان لديك مشكلة بوصول المستخدم dzlaboco_bt لقاعدة البيانات، يظهر هذا الخطأ في حالة عدم امتلاك المستخدم المعني لصلاحية الوصول الى موارد قواعد البيانات أو عدم وجوده من الأساس. ان كنت تشتغل على الخادم المحلي فيمكنك اصلاح المشكلة باستخدام المستخدم root بدون كلمة مرور الذي يكون معرفا بشكل افتراضيا في العادة. $conn = new mysqli("localhost", "root", "", "DB_NAME"); وإلا فإنك ستحتاج انشاء مستخدم قواعد بيانات جديد، فيما يلي خطوات إنشاء مستخدم كامل الصلاحيات في مدير قواعد البيانات PHPmyAdmin: الآن ستحتاج تعريف بيانات هذا المستخدم في ملف اعداد قواعد البيانات المرافق لمشروعك. يكون ذلك في العادة بتعديل الأسطر التالية بمكان ما: $conn = new mysqli("localhost", "USER", "USER_PASSWORD", "DB_NAME");
  6. أي صفحة تحاولين الوصول اليها؟ تشخيص الأخطاء في لارافيل سهل ولا يكون الا بإتباع موضع الخطأ وأصله. ففي هذا المثال يحاول لارافيل اخبارك ان هنالك خطأ بشأن استدعاء تابع غير موجود وهو التابع posts.. بمكان ما من ذات الصفحة، ستجدين ان نص الخطأ يشير الى موضعه بالضبط. يرجى ارفاق ذلك لمساعدتك في الوصول الى حل للمشكلة. ان كان السؤال متعلقا بأحد مسارات الدورة، فيفضل اضافة السؤال بقسم تعليقات الطلبة في الفيديو المرافق للمشكلة. تحياتي.
  7. السبب وراء هاته الفكرة ليس واضحا، ولكن كون المعامل الثاني الذي يستقبله التابع group عبارة عن شيفرة تنفذ executable فسيمكنك بنفس المنطق تحقيق ذلك عن طريق تعريف كامل مساراتك بشكل منفصل وحقنها كمعامل ثان في كل تعريف للنطاقين الفرعين، يكون ذلك كـ: $my_routes = function() { Route::get('/home', HomeController::class); Route::get('/admin', AdminController::class); }; Route::group(array('domain' => 'app.example.com'), $my_routes); Route::group(array('domain' => 'dashboard.example.com'), $my_routes);
  8. ثانيتان كمعامل للمهلة setTimeout هي 2000 معبرة عن 2000 ميلي ثانية. فيما يلي الصيغة العامة لاستعمال هاته الوظيفة: const myTimeout = setTimeout(myFunction, 2000); function myFunction() { // اي شيفرة هنا // لمحو المهلة الزمنية clearTimeout(myTimeout); } فان كانت الشيفرة الخاصة باخفاء عنصر ما مظهر فعلا هي ما كالتالي: function hideElement() { var el = document.querySelector('#my-element-id'); el.style.display = 'none'; } فان استدعاءها خلال مهلة زمنية هو ما سيكون كالتالي: const myTimeout = setTimeout(hideElement, 2000); function hideElement() { var el = document.querySelector('#my-element-id'); el.style.display = 'none'; // لمحو المهلة الزمنية clearTimeout(myTimeout); } تعرف أكثر عن الجدولة: المهلة setTimeout والفترة setInterval في جافاسكربت
  9. بالتأكيد فإنه توجد هنالك فروقات جوهرية بين الاثنين، نذكر من بينها: PDO تدعم أكثر من 12 نظام قواعد بيانات مختلف في حين ان MySQLi يمكنها العمل مع Mysql فقط. PDO تستعمل البرمجة الكائنية التوجه في عملها في حين Mysqli توفر بجانب خيار الـ OOP واجهة اتصال بسيطة (يعرفان ب Mysqli الاجرائية و Mysqli كائنية التوجه). في هاته الناحية تعطى الافضلية ل PDO فعند تبديل نظام قواعد البيانات لن يكفي في mysqli تغيير نوع الاتصال وانما سيشمل ذلك تغيير كامل الشيفرة ومن بينها استعلامات قواعد البيانات. تعتبر PDO أفضل من ناحية تشخصي الاخطاء وتقريرها. في PDO يمكن تسمية المعاملات وعنونتها بشكل عام global بشكل يجعل من السهل التعديل عليها لاحقا اما في mysqli فلا يمكن. لـ PDO أفضلية استخدامها من قبل اغلب المجتمع البرمجي بلغة PHP، يعني هذا ان اخطاءها ومشاكلها اسهل تشخيصا وحلا مقارنة بـ MySQLi. مبدئيا، استعمال PDO سيكون أفضل بكثير، من ناحية التنفيذ والتعديل وخدمة انظمة قواعد البيانات. اما Mysqli فتعتبر افضل من ناحية التخصص، فإن كنت لا تستعمل الا اتصال MySQL دون وجود اي احتمال لتوسيع قواعد البيانات او تغيير نمطها او نظامها فسيكون استعمال MySQLi عمليا.
  10. لا يوجد حد أدنى، ولكن لا يعني هذا أنه عليك كتابة كامل شيفرات الجافاسكربت الخاصة بك في ملف واحد، فمن شأن هذا أن يجعلها صعبة القراءة وبطيئة التحميل بالنسبة للمتصفح. عوضا عن هذا، واحتراما لمبدأ فصل المهام, وهو أحد مبادئ التصميم والشيفرة النظيفة, قم بفصل شيفرتك وتوزيعها في ملفات مختلفة على أن يحمل كل ملف جافاسكربت اهتماما منفصلا (مثال: لا يصح وضع الشيفرة التي تتحكم في اظهار القائمة الجانبية من عدمها مع الشيفرة التي تقوم بتحميل المقالات بطلبية Ajax!). في NodeJS تدعى كل من هاته الملفات وحدة نمطية Module ولذلك قد تحتاج في هذا استعمال آداة لتجميع هاته الوحدات في ملف واحد يسهل تضمينه بأي مكان. تعتبر webpack أشهر مجمع وحدات. قد تحتاج أيضا مفاهيم او مبادئ البرمجة الكائنية التوجه لعمل ذلك باحتراف. على أن التقسيم والفصل والتضمين بشكل تقليدي مثلما تعرفه كاف جدا ان كنت تقوم بتضمين هاته الملفات في ملف HTML واحد مثلا.
  11. لا يظهر أي فيديو في الصفحة التي قمت بارفاق رابطها. هلا قمت باضافة تفاصيل أكثر؟
  12. هلا قمت بارفاق اية محاولات قمت بها؟ سيمكننا توجيهك نحو حل مشكلتك بنفسك.
  13. قد يحدث أن تمتلك شركة أعمال أو نشاط تجاري واحد العديد من المتاجر، كأن تتواجد العديد من متاجر البيع بالتجزئة التي يمتلكها المالك نفسه. أو أن تشترك العديد من المتاجر في العديد من الخصائص العامة والمنتجات، لذا تهتم بريستاشوب بخدمة هذه الفكرة وتتيح إمكانية إنشاء مجموعة متاجر وإدارتها بسهولة ومن لوحة تحكم واحدة. تفعيل المتاجر المتعددة بصفة عامة، قد نتوجه لاستعمال خيار المتاجر المتعددة في بريستاشوب عندما نرغب في أن يتسوق عملائنا في نوعين مختلفين من المتاجر أو أكثر دون أن تتداخل الطلبات من المتجرين أو عربات التسوق لكل منهما مثلا. يمكن تفعيل خيار المتاجر المتعددة عن طريق: لوحة التحكم، التوجه إلى صفحة "إعدادات > عام" من قسم الإعدادات في القائمة الجانبية. نافذة "عام"، البحث عن خيار المتاجر المتعددة وتفعيله. التعرف على واجهة المتاجر المتعددة بعد تفعيل خيار المتاجر المتعددة، سيتم إضافة رابط للتصفح إلى صفحة إدارة المتاجر المتعددة في "إعدادات متقدمة > متاجر متعددة" من قسم الإعدادات المتقدمة من القائمة الجانبية. يمكن عن طريق هذه الصفحة إدارة واستعراض المتاجر المتوفرة، وتحوي بشكل عام الأقسام الثلاث: شجرة المتاجر المتعددة multi store tree: أين يتم عرض قائمة منسدلة بكامل المتاجر المتوفرة ورابط كل منها. المتاجر المتعددة: يمكن هنا استعراض أو تعديل مجموعات المتاجر الموجودة. إعدادات المتاجر المتعددة: أين يمكن تحديد المتجر الافتراضي للموقع. المتجر الافتراضي هو المتجر المركز الذي تأخذ عنه باقي المتاجر نفس الخصائص العامة مثل المنتجات والموردين وغيرها. التعرف على مجموعات المتاجر قد ترغب في تعيين نفس الموظفين أو العملاء أو الأسعار لعدد معين من المتاجر، دون أن يتم تعميمهم على كل كامل المتجر. وقد يصبح أمر إعداد كل منها وضبطه أمرا مجهدا ومشتتا كلما زاد عدد المتاجر. في الحقيقة تتيح بريستاشوب إمكانية ضم كل عينة من المتاجر تحت مجموعة واحدة، وإعدادها كلها بدل إعداد كل منها على حدة، هذا ويمكن بالطبع تخصيص كل منها أيضا على حدة، إذ يوجد هذا الخيار بغرض تسهيل إدارة المتاجر، ولن تظهر هذه المجموعات للعملاء. بل وتتجاوز هذا الأمر، وتجعل عملية إنشاء مجموعة متاجر أولى من إنشاء المتجر نفسه، وذلك لأن هذا الأخير نفسه يندرج في مجموعة متاجر، ولفهم هذا التفرع بشكل جيد لنتناول المثال التالي: يمتلك نشاط تجاري ما 20 متجرا ينشط عشرة منها في مجال البناء و العشرة الأخرى في مجال الإلكترونيات، نسمي كلا من الإلكترونيات والبناء "مجموعات متاجر". وعموما، يمكن إنشاء مجموعة متاجر عن طريق الضغط على زر "إضافة مجموعة متاجر جديدة" من القائمة العلوية لصفحة "المتاجر المتعددة". بعد الضغط على هذا الزر، يتم التوجه بنا إلى صفحة الإنشاء والتي يمكن عن طريقها تخصيص كل من الحقول: اسم مجموعة المتاجر. تعطيل أو تمكين مشاركة العملاء، بمجرد تفعيل هذا الخيار، فإن المتاجر في هذه المجموعة ستشارك العملاء. حيث إذا سجل العميل في أي من هذه المتاجر، فسيكون الحساب متاحا تلقائيا في المتاجر الأخرى في هذه المجموعة ولن يتطلبه إنشاء حساب في كل متجر من هذه المجموعة (لن يمكن تعطيل الخيار بعد الإنشاء). تعطيل أو تمكين مشاركة الكميات المتاحة للبيع بين متاجر المجموعة. تعطيل أو تمكين مشاركة الطلبات بين متاجر المجموعة، بمجرد تفعيل هذا الخيار (لاحظ أن ذلك ممكن فقط في حالة مشاركة العملاء والكميات المتاحة بين المتاجر) سيتم مشاركة جميع المتاجر سلات الشراء في هذه المجموعة. وبهذه الطريقة، سيمكن إكمال أي عملية شراء تبدأ من متجر معين في متجر آخر من نفس المجموعة (لن يمكن تعطيل الخيار بعد الإنشاء). تمكين أو تعطيل المجموعة (يتم تعطيل كامل المتاجر المنتمية لها في حالة التفعيل). يمكن تعديل المجموعات عن طريق الضغط على زر "تعديل" في جدول مجموعات المتاجر الظاهر افتراضا في صفحة "المتاجر المتعددة". إدارة متجر ضمن مجموعة متاجر يمكن من صفحة "المتاجر المتعددة" استعراض المتاجر المنتمية لمجموعة ما عن طريق الضغط على اسم هذه المجموعة في شجرة المتاجر أو جدول مجموعات المتاجر المبين بذات الصفحة. إنشاء متجر جديد يمكن عن طريق صفحة إنشاء متجر جديد يمكن تحديد كل مما يلي (التي يمكن التوجه لها بالضغط على زر إضافة متجر جديد بالقائمة العلوية لصفحة المتاجر المتعددة): اسم المتجر، وبما أن الاسم عام سيكون متضحا للعملاء في العديد من الأماكن، مثل عناوين النوافذ ومراجع البريد الإلكتروني وغيرها. ولذلك تأكد من إعطاءه اسما دلاليا واضحا. مجموعة المتاجر المنتمية لها (لن يمكن التراجع عن هذا الخيار لاحقا). جذر الأقسام، ويقصد به عن أي قسم يتفرع هذا المتجر. فئات المنتجات المرتبطة بهذا المتجر. الموضوع أو السمة، حيث يمكنك اختيار سمة رئيسية للمتجر من بين مجموعات السمات التي ثبتَّها. كما يمكن عن طريق خيار الاستيراد استيراد بيانات من متجر آخر دون الحاجة لإنشائها يدويا مرة أخرى، بيانات مثل الإضافات والعلامات التجارية واللغات وغيرها. ويكون هذا عن طريق تحديد نوع البيانات والمتجر المستهدف والمراد الاستيراد منه. تخصيص عناوين المتاجر من الطبيعي أن يمتلك كل متجر مستقل رابطا خاصا به (واحد على الأقل)، حيث يكون هذا الرابط مستقلا عن المتجر الأول الذي قمت بتثبيته. يمكن أن يكون: نطاقا مستقلا تماما، مثل: https://www.matjar.store. نطاقا فرعيا، مثل: https://matjar.company.store. نطاقا ذا مسار نسبي، مثل: https://www.company.store/matjar . ويمكن تخصيص ذلك عن طريق صفحة تعديل الرابط التي يمكن التوجه لها عن طريق الضغط على رابط المتجر الظاهر في شجرة المتاجر بصفحة "المتاجر المتعددة". ثم زر "تعديل" بالصف المرافق لهذا المتجر في جدول المتاجر. تضم الصفحة قسمان: خيارات الرابط، يمكن عن طريقها: تحديد المتجر المراد تعديل رابطه. تحديد ما إن كان هذا المتجر سيمتلك الرابط الأساسي للموقع (لا يمكن أن يمتلكه أكثر من متجر واحد). تمكينه أو تعطيله. رابط المتجر، يمكن عن طريقها: تحديد اسم نطاق المتجر (اسم صالح: www.domain.com، اسم غير صالح: http://www.domain.com). تحديد اسم نطاق SSL للمتجر، فقد ترغب مثلا في أن يختلف اسم نطاقك العادي عن اسم نطاقك الآمن SSL. عموما يمكنك إدخال نفس النطاق السابق (اسم صالح: www.domain.com، اسم غير صالح: https://www.domain.com). المجلد الفعلي Physical URL للمتجر. حيث أن هذا هو المجلد الفعلي لمتجرك على خادمك. يمكنك ترك هذا الحقل فارغا إذا تم تثبيت متجرك على مسار الجذر (أي مباشرة داخل مجلد public_html في خادم استضافتك المشترك أو داخل localhost إن كنت تستخدم استضافة محلية). أما اذا كان موقعك الأساسي متاحًا على www.example.com/some-path، فيجب عليك إدخال قيمة my-store/ في هذا الحقل. الرابط الظاهري Virtual URL للمتجر. ويقصد به الرابط الذي يظهر للعملاء، في حالة رغبتك في استعمال نطاق ذي مسار نسبي يمكنك إضافة اسم المتجر في مكان هذا الحقل لتمييزه، وإلا فإنك ستحتاج تركه فارغا في حالة استعمال نطاقا فرعيا أو مستقلا تماما. يمكنك بكل حال من الأحوال استعراض شكل الرابط النهائي لهذا المتجر. إدارة المتاجر ومجموعاتها من لوحة تحكم واحدة صحيح أن امتلاك متاجر متعددة يعني واجهات أمامية متعددة، ولكن لا يعني هذا أن كل واجهة ستمتلك لوحة تحكم خاصة بها. بل إن بريستاشوب تحرص على أن تكون عملية ادارة هذه المتاجر سهلة وبسيطة. وتتيح إمكانية إدارتها كلها عن طريق نفس لوحة التحكم التي تعرفت عليها في الدروس السابقة. هذا وتوضح بشكل جيد ما المشترك بين مجموعة متاجر وما الممكن تخصيصه في كل واحدة منها، ويكون كل ذلك عن طريق التبديل بين المتاجر بسهولة. وبشكل افتراضي، لا يمكن استعمال هذا الخيار إلا بعد إنشاء مجموعة متاجر واحدة فأكثر. ولذلك يجب التأكد من تفعيل ميزة المتاجر المتعددة ومن امتلاك أكثر من مجموعة متاجر واحدة. بعد هذا، سيمكن التبديل بين مجموعات المتاجر والمتاجر عن طريق المحدد المبين كقائمة منسدلة من صفحة لوحة التحكم المبينة في أعلى الصفحة. لاحظ أن هذا المُحدد يقبل اختيار جميع المتاجر، أو متجر معين، أو مجموعة متاجر معينة. في الحالة الأولى، ستبدوا جميع صفحات الإعدادات بشكلها وتقسيمها العادي مما يعني أن أي إعدادات يتم تخصيصها تطبق على كامل المتاجر والمجموعات. أما في حالة اختيار متجر أو مجموعة معينة فستلاحظ أنه يتم إضافة خيار "المتاجر المتعددة" في صفحات الإعدادات بشكل يمكن عن طريقه تخصيص سريان هذا الإعداد على جميع المتاجر أو على المتجر المحدد فقط. فيما يلي مجموعة العناصر موضح عليها ما إن كانت تقبل تخصيصها بالنسبة للمتجر الواحد، أو ما كانت تقبل تخصيصها بالنسبة لمجموعة المتاجر أو بالنسبة لجميع المجموعات والمتاجر. table { width: 100%; } thead { vertical-align: middle; text-align: center; } td, th { border: 1px solid #dddddd; text-align: right; padding: 8px; text-align: inherit; } tr:nth-child(even) { background-color: #dddddd; } الخاصية كل متجر مجموعة متاجر كامل المتاجر الموظفين، مجموعات العملاء، المنتجات، الأسعار، المنتجات، التركيبات، اللغات، الكمية المتوفرة للبيع، القواعد الضريبية، الفئات، جهات الشحن، المستودعات، الموردين، العلامات التجارية، صفحات CMS، جهات الاتصال، العملات واللغات والوحدات النمطية والخطافات والاستثناءات، حسابات خدمة الويب نعم نعم نعم الخصومات، إدارة المخزون المتقدمة، التكوين، قيود لكل دولة، قيود العملة، تقييد مجموعة لكل عميل، عناوين المواقع الودية، منزلق صورة الصفحة الرئيسية نعم لا لا لا يمكن أن يظهر المنتج إلا في فئة معينة من المتجر إذا كان مرتبطًا بهذه الفئة في سياق هذا المتجر، بمعنى آخر: إذا اشترك المتجر A والمتجر B في الفئة C، فيمكنك ربط المنتج P بالفئة C في سياق المتجر A، ولن يظهر P في الفئة C في المتجر B. الخاتمة تعرفنا في هذه المقالة الأخيرة من السلسلة على كل ما يخص خدمة فكرة المتاجر المتعددة في نسخة بريستاشوب الخاصة بنا، فبدأنا في السلسلة من التعرف على واجهة المتجر ومجموعات المتاجر والمتاجر ضمنها إلى كيفية إدارتها من لوحة تحكم واحدة وغيرها من التفاصيل حتى وصلنا إلى هذه المحطة الأخيرة والتي أرجو فيها أن تكون امتلكت المعرفة المطلوبة لإدارة متجرك على بريستاشوب بمهارة والانطلاق بمشروعك بكفاءة. اقرأ أيضًا التعرف على قسم الإدارة في متجر بريستاشوب إدارة المنتجات في متجر بريستاشوب التعامل مع العملاء وطلباتهم في متجر بريستاشوب ضبط طرق الدفع وعملية الشحن لمتجر بريستاشوب
  14. لا اظن انه يوجد بالضبط مكتبات لعمل ذلك، انت في الغالب تحتاج بناءها من الصفر. قد ذكرت سابقا ان اطر عمل مثل React أو Vue ستسهل المهمة.
  15. بالاضافة الى اجابة المدرب وائل، يمكنك اعادة تعريف او تجاوز overriding التابع all بما يوافق مرادك. كأن تستثني معرفا أو مستخدما ما بشكل عام دون الحاجة لإعادة استثناءه كل مرة. يشترط أثناء تجاوز اي تابع او وظيفة في لارافيل تعريفها وفق ما هي معرفة في صنفها الحاوي لها. اعادة تعريف التابع all بما يوافقنا سيكون في ملف النموذج User.php كالتالي: /** * اصتثناء مستخدمين معينين * * @param array|mixed $keys * @return array */ public static function all($keys = null) { $data = parent::all(); # حقن البيانات من صنف النموذج في متغير return $data->except(auth()->id); # استثناء المستخدم القائم بالطلب } ثم سيمكنك بأي مكان من تطبيقك استدعاء التابع all بالطريقة التقليدية التي تعرفها: User::all() # ستقوم بإعادة كامل المستخدمين معدا المحدد لها سيجنب هذا التكرار في حال ما كنت تكرر استعلام جلب المستخدمين معدا المستخدم القائم الطلب كل مرة. بجانب ان التعديل عليها لن يكون سهلا، فقد تشاء في المستقبل استثناء المستخدمين غير المفعلين أو المستخدمين المشرفين مثلا. ميزة اطر العمل مفتوحة المصدر هي في مرونتها ولامحدوديتها، يمكنك تخصيص اي جزء من التطبيق وفق منطق الخاص.
  16. يمكنك أيضا استعمال التابع inRandomOrder للحصول على نتيجة عشوائية من بين تجميعة نتائج كالتالي: $users = User::inRandomOrder()->first(); أو كطريقة أقرب لـ SQL أكثر يمكنك ترتيب الصفوف التي تجلبها من قواعد البيانات بواسطة الدالة RAND() منتجة استعلاما مشابها لـ: select * from users order by RAND() ASC وذلك كالتالي: $user = User::select("*")->orderBy(DB::raw('RAND()'))->first(); وبالطبع فإن هذا سيتطلب منك تضمين الواجهة DB قبل استعمال اي توابع لها. use DB;
  17. أفضل الطرق هي في تصدير هاته البيانات من برنامج الاسكل بصيغة JSON واستعمالها في الجافاسكربت مباشرة دون أي ربط بين الاثنين، هاته الفكرة عملية في حالة كون البيانات التي لديك ثابتة وغير قابلة للتغيير. في حالة تعذر تحويل هاته البيانات من اكسيل الى صيغة JSON لسبب من الاسباب يمكنك الاستعانة بأحد الخدمات او الحزم التي توفر امكانية تحويل صيغ CSV الى صيغ JSON قابلة للعرض عن طريق جافاسكربت. أستعمل csvtojson مثلا. تعرض صيغ JSON وفق هذا الشكل عادة: { "glossary": { "title": "example glossary", "GlossDiv": { "title": "S", "GlossList": { "GlossEntry": { "ID": "SGML", "SortAs": "SGML", "GlossTerm": "Standard Generalized Markup Language", "Acronym": "SGML", "Abbrev": "ISO 8879:1986", "GlossDef": { "para": "A meta-markup language, used to create markup languages such as DocBook.", "GlossSeeAlso": ["GML", "XML"] }, "GlossSee": "markup" } } } } } يمكن تحويلها الى كائن جافاسكربت عن طريق التابع parse للكائن JSON كالتالي: const obj = JSON.parse('PUT_JSON_HERE'); تفاصيل أكثر في:
  18. بالطبع سيمكنك ذلك، ستحتاج في هذا بناء واجهة التطبيق عن طريق HTML وتنسيقها عن طريق CSS أو أحد مكتباتها أو اطر عملها ثم تعريف الوظائف اللازمة لتوليد التهنئة كقسم HTML منسق أو عن طريق إرسال التهنئة عبر البريد الالكتروني باستخدام احد المكتبات او الواجهات البرمجية المجانية او المدفوعة التي توفر امكانية ارسال رسالة بريد الكتروني مباشرة عن طريق واجهة العميل دون الحاجة الى خادم او واجهة خلفية. نذكر مثلا emailjs. اما كان مرادك صفحة ثابتة تعرض محتوى تهنئة فبالطبع يمكنك عملها عن طريق HTML و CSS. توجد أيضا مواقع تقدم خدمات تصميم وإنشاء بطاقات التهنئة من مثل موقع بطاقات فيمكنك انشاء مثلها أيضا، هاته الانواع من التطبيقات قد تتطلب العمل على أحد اطر جافاسكربت، ReactJS أو VueJS مثلا.
  19. لمساعدتنا كمدربين في توجيهك نحو حل مشكلتك ومساعدتك على ذلك يرجى دوما تقسيم المشاكل التي تواجهها الى مشاكل منفصلة يمكن العمل على كل منها على حدة، بجانب ارفاق الشيفرة أو الشيفرات المتعلقة بالمشكلة مباشرة. مشكلتك غير واضحة جيدا، هلا قمت بتوضيح ذلك أكثر؟
  20. هل يمكنك إضافة تفاصيل أكثر عما تحاولين القيام به؟ ان كنت تحاولين انشاء استعلام قواعد بيانات لقراءة موظفي قسم معين، فهدا سيعتمد بالدرجة الأولى على هيكلتك لقواعد بياناتك، وعموما سيكون هنالك عمود يربط جدول الموظفين بجدول الأقسام يمكن عن طريقه قراءة الموظفين المنتمين لهذا القسم كالتالي: SELECT * FROM employees WHERE section_id=PUT_SECTION_ID_HERE; يمكنك أيضا استبدال * بأسماء الأعمدة التي تريدينها مفصول بينها بفاصلة أجنبية. أما ان كان المقصود هيكلة قائمة موظفين في شكل بطاقات في HTML فيمكنك الاستعانة ببوتسراب لتنسيقها وإنشاءها كالتالي مثلا: <div class="container"> <div class="row"> <div class="container"> <div class="row"> <!-- بطاقة الموظف --> <div class="card col-sm"> <div class="card-body"> <h5 class="card-title">اسم الموظف هنا</h5> <h6 class="card-subtitle mb-2 text-muted">الاسم الوظيفي</h6> <p class="card-text">نبذة شخصية عن هذا الموظف</p> <a href="#" class="card-link">رابط أعمال الموظف</a> <a href="#" class="card-link">رابط لينكد ان</a> </div> </div> <!-- بطاقة الموظف --> <div class="card col-sm"> <div class="card-body"> <h5 class="card-title">اسم الموظف هنا</h5> <h6 class="card-subtitle mb-2 text-muted">الاسم الوظيفي</h6> <p class="card-text">نبذة شخصية عن هذا الموظف</p> <a href="#" class="card-link">رابط أعمال الموظف</a> <a href="#" class="card-link">رابط لينكد ان</a> </div> </div> <!-- بطاقة الموظف --> <div class="card col-sm"> <div class="card-body"> <h5 class="card-title">اسم الموظف هنا</h5> <h6 class="card-subtitle mb-2 text-muted">الاسم الوظيفي</h6> <p class="card-text">نبذة شخصية عن هذا الموظف</p> <a href="#" class="card-link">رابط أعمال الموظف</a> <a href="#" class="card-link">رابط لينكد ان</a> </div> </div> </div> </div> </div> </div> مع تخصيصها وفق ما يليق بمشروعك. قد تحتاج الاطلاع أكثر على Bootstrap و البطاقات في إطار العمل Bootstrap.
  21. يتم استعمال القاعدة accepted بدل required لمربعات التحقق في لارافيل، يجب أن يكون الحقل قيد التحقق "true" أو "on" أو "1. يكون هذا مفيدا في حالات التحقق من الموافقة على شروط الاستخدام مثلا. مثال عملي: $validated = $request->validate([ 'email' => 'required|unique:users', 'terms' => 'accepted', // ... ]); تعرف أكثر عن التحقق (validation) في Laravel
  22. أظنك تحاول تشغيل الموقع على المتصفح وفق الرابط الموضح. يتطلب منك هذا أولا تشغيل Live Server لتشغيل الموقع على المتصفح والاستماع لأية تحديثات تقوم بها على ملفات مشروعك. لتشغيل Live Server يمكنك الضغط على Go Live في الشريط الأزرق السفلي في VS code. أو عن طريق فتح ملف html في VS code واختيار open with live server بعد الضغط على الزر الأيمن للفأرة. طريقة أخرى يمكنك بها ذلك هي عن طريق الضغط على Alt + L و ALT + O. سيتم فتح الموقع مباشرة في المتصفح الافتراضي لك.
  23. هلا تأكدت من أنك بالفعل في نافذة Terminal وليس أي نافذة أخرى؟ debug console مثلا ان لم تكن المشكلة بسبب هذا يرجى ارفاق تفاصيل أكثر عن المشكلة حتى يتم معالجتها بشكل فعال.
  24. يمكنك استعمال substr لاقتطاع الجزء الذي تريده، حيث تستعمال هاته الدالة اساسا لإعادة جزء معين من سلسلة نصية نمررها عبرها. فيما يلي السياق العام للدالة: string substr ( string $string , int $start [, int $length ] ) حيث تعبر كل من: string عن السلسلة النصية المستهدفة. start بداية السلسلة النصية المراد اقتطاعها. في حالة استعمال قيمة سالبة سيتم احتساب السلسلة النصية المُعادة من الموضع الذي يبعد مسافةً تُقدَّر بقيمة المعامل start عن نهاية السلسلة النصية string. length طول السلسلة النصية المراد اقتطاعها. في المثال الذي لديك، يكفي تمرير 10 باشارة سالبة كمعامل start لاقتطاع عشرة محارف ابتداءا من نهاية السلسلة: <?php $my_text = 'academy hsoub is cool'; // 10987654321 echo substr($my_text ,-10); النتيجة: ub is cool توثيق الدالة substr()‎ في PHP
  25. نعم يمكنك توظيف واجهات البرامج التي تستعمل تقنيات وبروتوكول الويب سوكيت لخدمة هذا الغرض، وهو بروتوكول ويب يوفر اتصالا دائما بين الخادم والمتصفح. فكل مرة يستقبل فيها الخادم رسالة جديدة مثلا من الطرف A يقوم مباشرة بتنبيه الطرف B الذي يقوم بدوره بعرض البيانات الممررة في شكل رسالة او تنبيه مثلا. تفصيل: يشترك كل من A و B في قناة ولتكن مثلا ConversationChannel. هاته القناة تحتوي أحداثا معينة، مثل: ReceivedMessageEvent, ClientIsTypingEvent. يستمع كل من A و B لهاته الأحداث. عندما يرسل A الى B رسالة فان مسار هاته الرسالة سيكون عبر هاته القناة ليستهدف حدثا معينا فيها. يقوم الخادم بالتقاط استهداف A للحدث ويقوم بتمرير البيانات الممررة عبر القناة. بما ان B مشترك في القناة ويستمع للحدث فانه سيلتقط اية بيانات ممررة عبر هذا الحدث. يقوم تطبيقك على المتصفح بالتقاط هذا الحدث ونمذجة البيانات وفق أي شكل من الأشكال. نذكر الأكثر شيوعا socket.io، وهي مكتبة مفتوحة المصدر تقدم كامل خدماتها بشكل مجاني. مناسبة جدا للتطبيقات المبنية على أطر عمل الجافاسكربت ومكتباتها. بجانب أنها توفر حلولا سهلة لأغلب استعمالات هذا البروتوكول. يوجد أيضا pusher والذي يعتبر سهلا بشكل واضح مقارنة ب socket.io ، شائع استخدامه في تطبيقات اللارافيل على الـ PHP رغم انه يوفر وصولا سهلا وتوثيقا موضحا في اغلب اطر العمل الموجودة على الساحة.
×
×
  • أضف...