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

لوحة المتصدرين

  1. احمد صوالحة

    احمد صوالحة

    الأعضاء


    • نقاط

      4

    • المساهمات

      29


  2. سمير عبود

    سمير عبود

    الأعضاء


    • نقاط

      4

    • المساهمات

      3552


  3. Abdulraheem Barghouthi

    Abdulraheem Barghouthi

    الأعضاء


    • نقاط

      3

    • المساهمات

      182


  4. عبد الله محمد5

    عبد الله محمد5

    الأعضاء


    • نقاط

      3

    • المساهمات

      167


المحتوى الأكثر حصولًا على سمعة جيدة

المحتوى الأعلى تقييمًا في 02/16/21 في كل الموقع

  1. يوجد طريقتان لتنفيذ الـthreads وهما: عمل implement للواجهة Runnable عمل extend للصنف Thread ما الفرق بينهما وما هي الطريقة الأفضل ؟
    2 نقاط
  2. لفهم سبب إستخدام Char Array بدلاً من String يجب علينا أولاً فهم الفرق بينهم: String: هو عبارة عن نوع بيانات غير قابل للتغير أي أن مجرد تعريفك لبيانات ستبقى موجودة في الذاكرة لحين مسحها من قبل الـGarbage Collection المسؤولة عن إدارة الذاكرة. عند قيامك بتعريف متغير من نوع String بحيث يحتوي على القيمة النصية "hello" سيتم حفظه في String constant pool، في حال قمت بتغيير قيمة المتغير إلى " hello 2 " سيتم أنشاء String جديد وإضافته للـ String constant pool، أي عند تغيير قيمة المتغير يتم إنشاء كائن جديد من نوع String ولا يتم تعديل نفس الكائن. الخلاصة: لا يمكن مسح البيانات من String بعد تعريفها بل ستبقى في الذاكرة لحين مسحها من قبل الـGarbage Collection. Char Array: هي عبارة عن نوع بيانات قابل للتغير عكس الـString، أي عند تغيير قيم مصفوفة ما فإن القيم السابقة سيتم مسحها ولا يمكن إرجاعها. إذاً ما المغزى من إستخدام Char Array ؟ يجب أخذ التدابير الأمنية عند التعامل مع كلمات المرور والحسابات البنكية وغيرها من الأمور الحساسة الأخرى، لو إستخدمنا String في التعامل مع هكذا معلومات فيستطيع المهاجم الذي وصل إلى الذاكرة الخاصة بالـJVM أن يستخرج هذه المعلومات الحساسة بينما لو تم إستخدام Char Array فالمهمة ستكون أصعب كثيراً لأننا سنقوم بتعديل قيمة عناصر الـArray إلى قيم وهمية بعد إنتهائنا منها وبالتالي سيحصل على كلمة مرور خاطئة.
    2 نقاط
  3. متى سوف تبدأ الدوره وكيف الطريقه؟؟
    2 نقاط
  4. إن مفهوم العمل الحر بصورته التي تصف عمل الفرد لصالح جهة أو عدة جهات في الوقت نفسه دون ارتباط وظيفي بينه وبينها قديمٌ قِدم وجود الإنسان نفسه، لكننا سنشير في هذا الكتاب إلى العمل الحر بمفهومه المستحدث، أي العمل الحر وعن بعد في نفس الوقت باستخدام الإنترنت لتقديم خدمات لعملاء يحتاجونها بمقابل مادي. وقد تبلور هذا المفهوم إلى شكله الحالي بعد التطور الذي حدث في تقنيات الاتصالات في العشرين عامًا الأخيرة على وجه الخصوص، بحيث نستطيع الآن إدارة شركات كاملة دون أن يكون للشركة مقر على الأرض، ولا مكتب يحضر إليه الموظفون كل يوم، بل كل موظف يعمل من المكان المناسب له سواء في بيته أو مكتبه الخاص أو غير ذلك، في نفس الدولة التي يعمل فيها بقية زملاؤه أو فيها مقر الشركة أو من دولة أخرى! وربما لا يصلح هذا النمط في الشركات التي تحتاج تواجدًا حقيقيًا على الأرض في مصانع أو منشآت تبيع منتجات حقيقية ملموسة، لكن سوق الخدمات التي يمكن تقديمها عن بعد قد شمل منتجات وخدمات كثيرة في العقدين الماضيين مثل الترجمة والسكرتارية وإدخال البيانات والمحاسبة والاستشارات المحاسبية والقانونية والتصميم والبرمجة وغيرها مما لا يحتاج تواجد العامل في مقر العمل أو الشركة. فلم يعد العامل في مثل تلك المجالات مضطرًا إلى الذهاب كل يوم إلى مقر الشركة، ولم تعد الشركة في حاجة إلى إنفاق تلك النفقات التي تلزمه من إيجار ونفقات تشغيلية عالية وغير ذلك، رغم سريان منافعه الوظيفية كموظف عامل في شركة كما هي إن كان يعمل عن بعد بشكل منتظم. وعليه فقد انتشر نمط العمل المنتظم عن بعد بشكل عام، والعمل الحر عن بعد بشكل خاص بشكل متزايد في الأعوام الأخيرة على مستوى العالم، ثم دخل رويدًا إلى العالم العربي مؤخرًا بسبب الحاجة إليه وملاءمته للتغيرات التي طرأت على سوق العمل في العقد الماضي، إضافة إلى نزعة الشركات لتقليل التكاليف. لكن رغم هذا الانتشار فإنه لا يزال مبهم التفاصيل على من يرغب بتبنيه وتغيير نمط عمله، كما نلاحظ العديد من الأخطاء عند من يدخل هذا المجال إذ يشيع الخلط بينه كعمل حر (مستقل) وبين العمل عن بعد. وفي هذا المقال سننظر في ثقافة العمل الحر من هذا المنظور مع بيان لواقع العالم العربي فيما يتعلق بالعمل فيه من المحاسن والتحديات التي قد يواجهها المستقل. تعريف العمل الحر قلنا قبل قليل أن العمل الحر في مفهومه اللغوي ليس بالجديد على البشرية، فهو أي عمل لا يرتبط بوظيفة لها منافعها من التأمينات والإجازات والبدلات وغير ذلك من المتعارف عليه في وظائف الشركات في القطاعات العامة والخاصة والأهلية وغيرها، وعلى ذلك فإن أصحاب الحرف اليدوية من النجارين والحدادين والميكانيكيين وغيرهم يعملون بشكل حر إذ لا يرتبطون في الغالب بوظيفة لها دوام مستقر. وحسب موقع BusinessDictionary فإن العمل الحر هو العمل بنظام التعاقد لصالح مجموعة متنوعة من الشركات بدلًا من العمل كموظف في شركة واحدة. وعليه فإن العامل المستقل أو الحر (freelancer) يكون عاملًا لحسابه الخاص، ولديه حرية اختيار المشاريع التي يريد العمل عليها، والشركات التي يرغب في العمل معها. أما المفهوم الاصطلاحي المنتشر في السنوات الأخيرة فإنه يشير إلى العاملين في الأعمال التي يمكن إنجازها عن بعد، مثل البرمجة والتصميم والكتابة والترجمة والاستشارات الإدارية وغيرها، ويكون ذلك العمل وفقًا لمقدار معين من المهام التي ينتهي العقد عند إنجازها، سواء أنجزها المستقل في يوم أو في شهر أو غير ذلك مما يكون عليه العقد بين المستقل وصاحب المشروع، ولعل أكثر مهنة متعارف عليها في العمل الحر هي الكتابة إذ هي أقل الأعمال التي تتطلب مهارات وأدوات معقدة، على عكس البرمجة والتصميم ثلاثي الأبعاد مثلًا. وجاء انتشار العمل الحر في سياق انتشار العديد من المفاهيم والمصطلحات الأخرى مثل: اقتصاد العربة (Gig Economy)، وهو نظام لسوق يعتمد على العقود المؤقتة سواءً في الواقع أو عبر الإنترنت، مثل العاملين عبر المنصات الإلكترونية والعمال الذين يقدمون خدماتهم عند الاتصال بهم وغير ذلك، وأشهر الأمثلة على ذلك المفهوم هم السائقون في شركة أوبر الذين يقدمون خدمات التوصيل لزبائن الشركة عند الطلب. ورغم انتشار العمل الحر على نطاق واسع في الدول الغربية تحديدًا إلا أننا لم نقف على إحصاءات دقيقة في شأنه على مستوى العالم، إذ تتعلق أغلب التقارير والإحصاءات الموجودة بانتشاره داخل الولايات المتحدة الأمريكية فقط، فقد كشفت إحدى تلك الدراسات مثلًا أن 40% من القوى العاملة الأمريكية ستعمل بنظام العمل الحر كمستقلين أو موظفين بشكل مؤقت بحلول عام 2020، في حين أن حجم مساهمة العمل الحر في الاقتصاد الأمريكي بلغ 1 تريليون دولار في عام 2019 [1]. العمل الحر والعمل عن بعد زاد التوجه إلى العمل عن بعد بشكل عام والعمل الحر بشكل خاص مع انتشار ثقافة العمل من المنازل بسبب التقنيات التي تتيح ذلك، وربما يكون من اللائق هنا أن تميز بين المفهومين بشكل واضح قبل اختيار النوع الذي يناسبك. فالعمل عن بُعد هو إتمام مهام العمل خارج مقر الشركة بشكل عام، فقد يُسمح لبعض الموظفين بالعمل خارج المقر لبضعة أيام في الأسبوع ثم داخل مقر الشركة بقية الأيام، والبعض يعمل عن بعد متى شاء، ويمكن بيان ذلك في أربعة محاور: العمل من مقر الشركة مع وجود خيار العمل من المنزل: تلك شركات لديها مكتب فعليّ أو ربما أكثر من مكتب، لكنها تعطي أفراد فريقها خيار العمل من المنزل لمدة يوم واحد في الأسبوع أو أكثر. فريق يعمل عن بعد ولكن في نطاق زمني واحد: في هذا النموذج، لا يُتوقّع من أفراد الفريق الذهاب إلى مقر العمل (إن وُجِد) لأنهم يعملون من منازلهم (لا يُشترط وجود مكتب فعليّ). فريق أفراده من دول مختلفة وفي مناطق زمنية متنوِّعة: وهي خطوة أكثر تقدمًا للعمل عن بُعد لوجود أفراد لهم مناطق زمنية مختلفة. يتميز هذا النموذج بأنه غير متزامن، مما يجعل مسألة التعاون فيه أكثر حيوية، فأفراد الفريق لديهم ساعات عمل قليلة متداخلة مع بعضهم بعضًا، فيحتاج هذا النموذج إلى نظام لجعل التواصل والتعاون فيه أكثر فاعلية. فريق عمل موزَّع في دول مختلفة مع وجود بعض الأفراد كثيري السفر: يعد هذا النموذج هو الأكثر تطورًا؛ فأفراد الفريق يعملون من دول مختلفة تمامًا، بالإضافة إلى أن بعضهم يسافرون ويتنقَّلون بانتظام من منطقة زمنية إلى أخرى. أما العمل الحر أو المستقل في المقابل في معناه الواسع يضم جميع الأعمال الحرة التي يعمل فيها الشخص دون ارتباطه بعقد دائم مع صاحب العمل، حيث يقوم بأعمال محددة خلال فترة قصيرة معلومة مقابل أجر معين، وبهذا المنطق فإن الطبيب والمحامي وغيرهم ممن يعملون بشكل مستقل في عيادة أو مكتب خاص يمكن النظر إلى أعمالهم على أنها أعمال حرة. وتختلف مدة المشاريع التي يتم العمل عليها في مجال العمل الحر بين يوم واحد أو حتى بضعة ساعات، وحتى عام أو أكثر. موازنة بين العمل الحر والعمل التقليدي أول ما يتبادر لذهن القارئ حين يسمع عن العمل الحر هو موازنته مع العمل الوظيفي أو التقليدي، وسنشرح في الجدول التالي الفروقات الجوهرية بين العمل التقليدي والعمل المستقل أو الحر، وكذلك العمل عن بعد. العمل التقليدي العمل الحر العمل عن بعد مدة العقد ارتباط بعقد عمل طويل الأمد ارتباط قصير الأمد ارتباط بعقد عمل طويل الأمد التدريب المهني احتمال وجود تدريب التحفيز والعمل بشكل ذاتي احتمال وجود تدريب بيئة العمل العمل ضمن بيئة عمل متكاملة احتمال عدم وجود زملاء عمل العمل ضمن بيئة عمل لكنها عن بعد وضعيفة اجتماعياً العائد المادي عائد منتظم عائد متقلب غير منتظم عائد منتظم ضريبة الدخل دفع ضريبة دخل عدم وجود ضريبة دخل في الغالب عدم وجود ضريبة دخل في الغالب (حسب قوانين الدولة) مواعيد العمل دوام روتيني بمكان عمل واحد حرية اختيار مكان وزمان العمل دوام روتيني مع مرونة باختيار مكان العمل 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; } للعمل التقليدي مزاياه وتحدياته وللعمل الحر أيضًا تحدياته ومزاياه المختلفة، ومن ثم فلا يمكن استبدال جميع الأعمال التقليدية بعمل عن بعد، والعكس بالعكس أيضًا. على سبيل المثال، لا يمكن لموظف الاستقبال أن يعمل عن بعد أو بشكل حر، ذلك أن عمله مرتبط بمكان عمل معين وساعات معينة أيضًا وبالتالي لا يستطيع الحصول على تلك المرونة التي يتميز بها العمل الحر في اختيار مكان وزمان العمل. حاجة الوطن العربي للعمل الحر تأخر العالم العربي عن اللحاق بركب العمل الحر بسبب العديد من العوامل مثل تدني جودة الإنترنت وغلاء الخدمة في بعض البلاد، إضافة إلى قلة الوعي بالعلوم والمجالات التقنية والتي تُعد أساس للعمل الحر في معظم مجالاته مثل البرمجة وغيرها. لكن في الأيام الأخيرة ظهرت متغيرات جديدة على مستوى العالم دفعت كثيرًا من العاملين والشركات على حد سواء إلى تغيير نمط تنفيذ أعمالهم بشكل مفاجئ، فظهور فيروس كورونا المستجد (CoVID 19) مثلًا دفع كثيرًا من العاملين للاتجاه للعمل عن بعد في نفس وظائفهم لتعذر ذهابهم إلى مقار أعمالهم، وشمل ذلك قطاعات كثيرة وصلت إلى المدارس والحكومات نفسها، وكذلك دفعت بالعديد من العاملين الذين فقدوا وظائفهم إلى الاتجاه إلى العمل الحر كأفضل حل ممكن خلال هذه الفترة نظرًا لتطبيق الكثير من البلدان تقييدًا على حركة الناس عمومًا وفرض حجر على المقيمين فيها للحد من إنتشار الوباء، وفي الحقيقة يُعد العمل الحر ضرورة ملحّة هذه الأيام، وسنفصِّل بعض الأسباب التي نرى بأنها تشكّل أسبابًا جوهرية للانتقال إلى اقتصاد العمل الحر في ظل الظروف الراهنة، غير هادفين إلى التقليد أو المحاكاة وإنما إلى الإرشاد لاقتناص الفرص. 1- زيادة معدلات البطالة لا يخفى على المتابع لحال الدول العربية خاصة وباقي دول العالم بشكل عام أن معدلات البطالة قد زادت إلى معدلات كبيرة، ففي دولنا العربية وصلت معدلات البطالة إلى 10.3% من إجمالي السكان حسب إحصائيات البنك الدولي لعام 2019، في حين أن معدلات البطالة العالمية تشكل 5.4% من إجمالي السكان. ولا شك أن انعدام فرص العمل يعني ضرورة الانتقال إلى بدائل مختلفة تستهدف سوقًا آخر-ربما أكبر من السوق المحلية في حالة العمل الحر عن بعد، والتوجه لسوق أكبر يعني وجود فرص عمل أكبر ومن ثم إمكانية الحصول على عائد أفضل. 2- محدودية مصادر الدخل تستطيع أن تلاحظ وجود العديد من القيود على الفرص الوظيفية بسبب الشروط التي قد تكون مجحفة من جانب أصحاب العمل من ناحية، وبسبب غياب الكفاءات والكوادر المحلية المطلوبة لتلك الوظائف من ناحية أخرى، ويظهر عوار تلك الشروط بوجود نسبة بطالة كبيرة، فتقل فرص العمل المتاحة، ومن ثم يرضى العامل بأجر أقل من الأجر المعتاد لكسب الفرصة الوظيفية، بينما في العمل المستقل الأمر مختلف. فبادئ ذي بدء، من المعروف والمشاهد أن العمل الحر يزيد من دخل المرء إن كان يعمل في وظيفة أخرى تقليدية مما يعني أنه يستطيع الادخار من دخله أو استثماره في تجارة أو دراسة أو غير ذلك، إضافة إلى ذلك، فإن العمل الحر الذي يكون عن بعد، كما في أعمال مثل الكتابة والترجمة والبرمجة وغيرها مما لا يحتاج سوى حاسوب واتصال بالانترنت في أقل حالاته، يكون دخله أفضل بكثير، وقد يزيد على الدخل من الوظيفة التقليدية إن كان العامل مجتهدًا فيه وجادًا وحريصًا على التسويق لنفسه وكسب المزيد من العملاء. أما إن كنت تعمل بشكل حر مع عمل ثابت بنفس الوقت ولم تستخدم عائد أحدهما لادخاره أو استثماره مباشرةً فاعلم أنك واقف في محلك لأنك يفوتك بعض الانضباط أو أن العمل الحر لا يناسب ظروفك لضيق وقتك أو ضعف مهاراتك في التخصص الذي اخترته، وحينها يكون الاعتماد على العمل الحر بتلك الصورة خيارًا غير موفق. 3- هدر في استغلال الموارد البشرية قد يكون لدى كثير من الشركات وظائف لا تحتاجها بدوام منتظم أو لا تؤثر على مركزها السوقي، والذي يحدث في الغالب أن الشركة توظف من يؤدي هذه المهمة التي تريدها الشركة مرة أو بضع مرات كل شهر مثلًا، فلا تستفيد منه بقية الشهر، فتجد نفسها مضطرة إلى تقليل الراتب الممنوح له، أو تُبقي على راتبه فتخسر هي في صورة أموال مهدرة. ففي مثل تلك الحالة تستطيع الشركة أن توظف الشخص في صورة تعاقد حر مقابل خدماته فقط وليس مقابل الوقت الذي يمضيه في موقع العمل، وعليه سيكون العائد مجزيًا أكثر بالنسبة للموظف إذ وفر له عدة ساعات إضافية في اليوم أو الأسبوع يستطيع العمل فيها لصالح مكان آخر، وكذلك للشركة إذ وفرت موارد كانت تهدر في إبقاء موظف دون الاستفادة منه إلا قليلًا. 4- أسعار تنافسية موازنةً مع المستقلين الآخرين حول العالم إن الأسعار التي يطلبها العامل المستقل الذي يعمل من بلدان العالم الثالث بشكل عام أقل بكثير من أسعار المستقل الذي يعمل في البلدان الأخرى، وتُعدهذه النقطة بمثابة ميزة تنافسية له أمام أقرانه ممن يعملون في أماكن ترتفع تكلفة العيش فيها إذ سيكون الأجر الأقل مجزيًا لتغطية النفقات وتحقيق ربح أيضًا. أما إن كان يتقن لغة أجنبية للتواصل مع العملاء الأجانب فهذا يعني دخوله لسوق عمل أكبر وتعرضه لشرائح مختلفة من العملاء، ولا يشترط في هذه الحالة ولا التي في الفقرة السابقة أن يطلب المستقل أجرًا أقل من نظرائه على إطلاق المسألة، بل إن رأى أن عمله يستحق زيادة في الأجر أو إن زادت تكاليفه أو رأى إضافة خدمة جديدة أو أنه أراد رفع أجره لمجرد زيادة الدخل فلا حرج عليه، خاصة إن أثبت أحقيته بهذا المال في صورة عمل عالي الجودة وتعامل أفضل مع العملاء. 5- التوظيف وفق الكفاءة والخبرة بعيدًا عن الوساطة أو الشخصنة يُبنى التوظيف بشكل أساسي على المقابلة الشخصية وهي أحد الأساليب التي قد لا تكون عادلة في كل حالة لتوظيف شخص ما، سيما إن كان العمل لا يتطلب الكثير من المهارات الاجتماعية مثل القدرة على التعبير عن الذات أو التواصل المباشر مع الأشخاص. والواقع المشاهد أن توظيف العاملين بالطرق التقليدية عن طريق المقابلات الشخصية يدخل فيه كثير من العوامل النفسية التي تفرض نفسها عند اتخاذ قرار توظيف شخص من عدمه. أما في طلبات التوظيف التي تتم عبر الإنترنت فقط فإن قاعدة "دع عملك يتكلم عنك" هي التي ستحكم عملية التوظيف، ولا بأس أن تُعقد مقابلة مع العامل بعد قضاء مدة اختبار تحددها الشركة أو يتفق الطرفان عليها باستخدام برامج التواصل المرئي أو الصوتي، لكن هذا يكون بعد أن يتعرف الطرفان على بعضهما ويريا إن كان من المناسب ضم العامل إلى قوة الشركة أم لا، حيث تُراجع السيرة الذاتية والأعمال السابقة، وبهذا تزيد فرص الأشخاص الذين لا يمتلكون مهارات اجتماعية كافية للنجاح في المقابلة رغم أن لديهم خبرات ومهارات مهنية كبيرة. وهذا لا يعني قطعًا أن شخصية المستقل أو مهاراته الاجتماعية لا تلعب أي دور في العمل في مجال العمل الحر، لكننا قصدنا أنها لا تؤثر من نفس جهة تأثيرها في الوظائف العادية. محاسن وتحديات العمل الحر يتمتع نمط العمل الحر بالعديد من المزايا بالنسبة للعامل نفسه، لكن يعاني العامل في الوقت نفسه من بعض التحديات التي يجب أخذها بعين الاعتبار قبل بدء العمل. محاسن العمل الحر تشكل مزايا العمل الحر حافزًا كبيرًا لدى للشخص للانتقال إليه، ويرتبط الحكم عليه غالبًا بالموازنة بينه وبين العمل التقليدي، لذا سنوازن النقاط التالية مع العمل التقليدي لبيان الفروقات الواضحة التي تميز العمل الحر عن نظيره العادي: 1- العمل في المجال الذي تفضله من أهم ميزات العمل الحر هي أنك في الغالب غير مضطر للعمل ضمن مجالات لا تحبها أو لا تفضل العمل بها، فاختيارك للعمل الحر يعني أنك ستقوم باختيار مجال عملك الذي تفضله، في حين أنك في العمل التقليدي قد تضطر للعمل في مجال لا تحبه لعدم وجود فرص عمل ملائمة بالنسبة لك، أو أن العائد الذي تقدمه غير مجزي. كذلك يستطيع الطلاب العمل بشكل حر أثناء فترة دراستهم أو إجازاتهم، أو يتخصصوا بالمجالات التي تزيد من فرصهم في الأعمال المناسبة للعمل الحر فيما بعد. 2- حافز للإبداع والتميز يفسح العمل الحر مساحة للإبداع بما أنك اخترته بنفسك لملاءمته لظروفك أو رغبتك في العمل فيه دون قيود من السوق المحلي أو نظام التوظيف السائد حسب العرض والطلب المحلي كذلك، ومن ثم فلا حد نظريًا لتميزك كل يوم بطرق وأساليب جديدة تبتدعها لتطوير خدماتك وعملك. 3- قلة رأس المال المطلوب لدخول السوق لا يخفى على أحد أن التجارة تحتاج إلى رأس مال للبدء ودخول السوق، ونفقات تغطي في أضعف حالاتها بنود تكاليف التشغيل من الإيجارات والمصاريف الإدارية والقانونية وغير ذلك، وقد يثبط هذا من يرغبون في العمل لقلة خبرتهم بهذه الأمور أو عدم امتلاكهم لرأس المال ذلك. وهنا يأتي العمل الحر عبر الانترنت ليحل هذه المشكلة، فالترجمة والبرمجة والمحاسبة والمساعدة الافتراضية والسكرتارية والتصميم والكتابة والتأليف وغيرها مما شابهها من الأعمال وما يلحق بها من وظائف إدارية لا تحتاج إلا إلى حاسوب واتصال بالانترنت في الغالب. وبشكل عام فإن تكلفة دخول سوق العمل الحر هنا تكاد لا تذكر بالموازنة مع تكاليف التجارة الحقيقية على الأرض، لكن لا تظن أنك لن تدفع شيئًا إلى الأبد! فأنت لن تعمل من السرير مثلًا -وإن كنت ستجد نفسك تعمل منه بين الحين والآخر من باب التغيير-، بل ستحتاج إلى مكتب وكرسي للعمل، وإن استطعت تخصيص غرفة في بيتك فهو خير وأفضل، وإن استطعت استئجار مكتب خاص أو مكتب في مساحة عمل مشتركة فهو أفضل من سابقه. كما ستحتاج إلى شراء البرامج ونظم التشغيل التي ستعمل عليها إن كانت غير مجانية مثل برمجيات ميكروسوفت وبرامج أدوبي وغيرها. 4- تحقيق دخل أعلى لا شك أن العمل الحر يزيد من دخلك إن كان لديك وظيفة أخرى، وربما يحقق لك عائدًا يغنيك عن هذه الوظيفة بحيث تستطيع الاعتماد عليه كمصدر وحيد للدخل. ربما يكون أحد أسباب ذلك هو عدم تقيدك بعقد عمل مع شركة واحدة تلزمك ببنود محددة وتنهاك عن العمل في مشاريع جانبية أو لصالح شركات منافسة لها حتى لو كان لديك وقت وطاقة. والواقع المشاهد أن عديدًا من العاملين المستقلين يرفضون التوظيف لقيود الشركة على العامل فيها، بينما تكون له حرية العمل مع أكثر من شركة في نفس الوقت بنظام العمل الحر، ومن ثم يحقق دخلًا أعلى مع الحفاظ على نمط الحياة التي تناسب ظروفه. 5- ربح غير محدود نظريًا، لا يوجد حد للأرباح التي يمكنك تحقيقها في العمل الحر على عكس الراتب شبه الثابت في الوظيفة العادية، بل إن اجتهدت واستثمرت في تعليم نفسك وتطوير مهاراتك ستحقق عائدات أكبر بكثير. وستجد الكثير من الفرص والحالات التي يمكن أن تحقق فيها دخلًا عاليًا جدًا مع زيادة الخبرة وانتشار سمعتك أو سمعة علامتك التجارية وهويتك ومشاريعك التي عملتها وحجم سوقك المستهدف وحاجته إلى مثل خدماتك، فأبواب زيادة الأرباح مفتوحة دائمًا في العمل الحر على عكس العمل التقليدي. 6- اختزال وقت تحقيق النجاح ورؤية ثمرته يرتبط النجاح في العمل التقليدي بانتظار الترقية أو الانتقال لشركة أفضل برواتب أعلى وميزات أكبر، وغالبًا ستنتظر لتعبر الخط الزمني التقليدي الذي يجب أن يعبّر عن مدى الخبرات التي اكتسبتها خلال فترة معينة، إلا إن أحرزت قفزة نوعية جعلتك تتجاوز ذلك الخط. كذلك فإن بعض الأعمال التقليدية تكون روتينية بحيث لا يتطور العامل فيها ولا يكتسب خبرة بطول المدة التي قضاها فيها لثبات عواملها، فالعمل الروتيني على هذا الأساس لا يقاس بالسنوات، فلا نقول هنا أن لديك خبرة 10 سنوات بل خبرة سنة مثلًا مكررة 10 مرات، وذلك في مجال العمل الفني نفسه، وإلا فإن خبرة أي إنسان تزيد بالعمر في الجوانب الحياتية والإنسانية فيما يتعلق بالتعامل مع الناس وفهم البيئة المحيطة، وعليه فمن المهم أن يُعلم أننا نقصد زيادة الخبرة الفنية في مجال العمل. أما العمل الحر في المجالات التقنية فيكون متقلبًا وسريع التغير، سواء إن كنا نقصد تغير العملاء وثقافاتهم أو تغير تقنيات وأدوات إنجاز العمل أو ربما تغير مجال العمل كليًا، وفي نفس الوقت لا يرتبط بأقدمية توظيف ولا درجات وظيفية كي تستطيع الانتقال إلى تخصص ما، ولا يرتبط كذلك بموقع محلي لا تستطيع تركه، بل تستطيع دراسة ما تشاء ومتابعة ذلك التخصص والعمل فيه مع عملاء محليين ودوليين بدون أدنى فرق إلا في طرق تحويل قيمة تلك الأعمال ربما. وعليه فإن هذا يضمن لك انتشارًا أوسع في سوق أكبر، مما يعني زيادة فرص التعامل مع عملاء جدد ومن ثم زيادة دخلك. 7- المرونة قد تفتقد كثير من الوظائف التقليدية إلى بعض المرونة بسبب اعتماد المؤسسات الموفرة لتلك الوظائف على طرق مجربة أو محسوبة ضمن عوامل أخرى تكوّن فيما بينها منظومة تحقق الأهداف التي تريدها الشركة، وذلك معلوم ومشاهد في الوظائف الحكومية أو المالية أو في خطوط الإنتاج الصناعية وغير ذلك، إذ لا يستطيع موظف أن يغير من طريقة سير العمل فيها من تلقاء نفسه. بل قد لا تستطيع الوحدة التي يعمل الموظف فيها أن تغير شيئًا في أسلوب سير العمل حتى لو أرادت، إذ سيلحق ذلك تغيير في فروع الشركة الأخرى أو تغييرًا في سياسات مالية وتنفيذية وبرمجية على مستوى المؤسسة كلها، أو قد يعني أحيانًا ميزانية ضخمة لتغيير معدات وماكينات من أجل اتباع ذلك الأسلوب الجديد، وإن لم تكن ثمة حاجة اقتصادية ملحة لذلك فلن يحدث تغيير، وهذا ليس سيئًا في تلك الحالات بل هو المطلوب أحيانًا كثيرة لتقليل النفقات وللتركيز على الإنتاج. لكن قد يكون هذا النمط مملًا لبعض العاملين، وفي هذا دافع لهم لتجربة العمل الحر، إذ تكون لديهم حرية في تغيير نمط العمل والتقنيات التي يعملون بها، والأدوات التي يستخدمونها، والأماكن التي يعملون فيها، أو حتى تغيير مجال العمل بالكلية والانتقال إلى مجال جديد. ولعل أهم ميزة للعمل الحر هو أنك غير مقيد بالمهام المتكررة في البيئات التقليدية أو البيروقراطية الوظيفية، والتي تنفذ فيها مهامًا بعينها تأخذ عليها أجرك، فإن عملت مهامًا خارج نطاق ذلك المسمى وذلك العقد فليس لك شيء في الغالب، بل قد تُمنع من تنفيذ مهمة بأسلوبك الخاص الذي يختلف عن أسلوب الشركة، أو قد تُمنع من الذهاب لبيتك رغم إنهاء مهام يومك، أو تُمنع من البقاء ساعات إضافية ولا تُعطى أجرًا عليها إن قضيتها دون أن يُطلب منك، وهذا معلوم مشاهد في حال الشركات والمؤسسات التقليدية ولأسباب منطقية وصحيحة في حال تلك المؤسسات. أما في العمل الحر على الإنترنت فلا توجد هذه القيود، فقد تنهي عملك في أول 10% من وقت المشروع، وقد تعمل على عدة مشاريع لعدة عملاء في نفس الوقت، وقد تخرج من بيتك أو محل عملك إلى قضاء حاجات لك في منتصف النهار -السوق، الرياضة، المشفى …- ثم تعود لتكمل عملك دون مشاكل، بل قد تمضي أيامًا لا تنفذ فيها مهامًا على الحقيقة وإنما تقضيها في مراجعة وتنقيح أو تخطيط لباقي المشروع. كذلك فإن أرضيتك الصلبة التي تقف عليها حين تعرض نفسك للسوق هي أعمالك السابقة، فإن كنت مبرمجًا وتعلمت مهارة مثل التعليق الصوتي أو الترجمة أو التصميم ثلاثي الأبعاد مثلًا، ثم عرضت نفسك على أنك معلق صوتي، وقدمت معرض أعمال به نماذج لذلك التعليق الصوتي مع باقات أسعار تناسبك وتناسب السوق فلا مانع هنا أن تُطلب منك هذه الخدمات، فالفيصل هو أعمالك السابقة وسمعتك. وهكذا ترى أنك تحصل على كثير من المرونة وتغيير نمط العمل إن كنت ممن لا يتحملون السير على وتيرة واحدة أو العمل المتكرر أو المقيد بمكان ووقت محدد يخالف ظروفك. 8- حرية اختيار روتين العمل ربما تكون هذه النقطة امتدادًا للنقطة السابقة، إذ يرتبط العمل التقليدي غالبًا بروتين تحدده المؤسسة أو الشركة ليخدم مصالحها وأهدافها، فقد يعمل الموظف في نوبات تتغير كل أسبوع، أو يكون موقع العمل في الصحراء أو في أعالي البحار كما في صناعات التعدين مثلًا فيكون على الموظف السفر إلى الموقع في أوقات محكمة تحددها الشركة سلفًا وفق ما يقتضيه نظام العمل. كذلك قد يكون ذلك الروتين طارئًا ولا وقت محدد له، كما في حالة الأطباء والمؤسسات العسكرية والحماية المدنية وغيرها، وهذا كله قد يسبب إرهاقًا جسديًا ونفسيًا للعديد من العاملين في تلك القطاعات لكنهم لا يملكون تغيير شيء من ذلك. وقد رأيت بنفسي بعض ذلك إذ عملت في شركة لها مواقع في الصحراء فلا تستطيع الوصول إليها إلا بوسيلة انتقال لها مواعيد محددة، وكذلك لي صديق يعمل مهندسًا في مصنع تتغير نوباته كل أسبوع، فهو يعمل في أول النهار أسبوعًا ثم في الأسبوع التالي يعمل وسط النهار ثم آخره، وهكذا دواليك. ولما جربت مثل هذا النمط بنفسي في مصنع مشابه لم أتحمل أكثر من أسبوع واحد، فما إن كنت أضبط روتيني اليومي حتى يتغير في الأسبوع الذي يليه! وهنا يكون العمل الحر خيارًا مناسبًا لأولئك الذين يفضلون نمط عمل يخالف ما تحدده المؤسسة التي يعملون فيها، فقد يُجبر المرء على البقاء في المنزل لرعاية أهله أو يضطر للعمل ليلًا بسبب ظروف قاهرة مثلًا، أو قد يسأم السفر إلى مواقع العمل البعيدة أو الاستدعاءات الطارئة، هذا فضلًا عمن يفضلون دخول سوق العمل على الانترنت لزيادة الدخل ولأنهم يحبون ذلك، وهكذا. 12- استهداف مجموعة أوسع من العملاء قد ذكرنا هذه النقطة لمامًا قبل قليل وربما نفصلها قليلًا ها هنا، فالعمل التقليدي كما قلنا مرتبط بالسوق المحلية، فأنت مقيد بموقع شركتك أو مؤسستك التي تعمل فيها، وشركتك مقيدة بحيز جغرافي تستطيع الوصول إليه وخدمته بما لا يسبب خسائر عليها في زيادة التكاليف وصعوبة التواصل، وعليه فإن لم يكن ثمة سوق حولك يطلب خدمتك التي تعرضها فإن تجارتك ستبور ولن تجد لتخصصك سوقًا تعمل فيه. أما سوقك على الإنترنت فإنه يتسع ليتخطى الحواجز الجغرافية بسهولة، لكن هذا لا يعني أن العالم بأسره سيطلب خدمتك، وإنما نقصد زيادة تعرضك لشرائح العملاء على اختلاف أماكن إقاماتهم، فإن احتمال أن يطلب منك ياباني مثلًا ترجمة من الإنجليزية إلى الأردية ضئيل جدًا إن كنت تعمل في الترجمة بين هاتين اللغتين مثلًا، وستجد أن أغلب العملاء سيأتونك من الدول التي تتحدث بإحدى هاتين اللغتين، وهكذا. فالمنطق يحكم هنا مدى انتشار خدمتك، وحجم السوق الذي يطلب تلك الخدمة يتحكم كذلك في حجم الطلبات التي ستأتيك، فخدمات التصميم المرئي مثلًا سوقها أوسع من الترجمة، والبرمجة سوقها يدفع أجرًا أعلى للساعة، وإدارة المشاريع تدفع أعلى من البرمجة، وهكذا. وإجادتك للغة أجنبية يتحدث بها السوق الذي يطلب خدمتك يجعل من السهل عليك مضاعفة حجم ذلك السوق، فإن كنت مصممًا أو مبرمجًا وتنوي العمل على الانترنت فإن سوقك محدود بمن يطلب هذه الخدمة من العرب، فإن كنت تجيد الإنجليزية فقد فتحت على نفسك بابًا إلى السوق العالمية، ببساطة لأنك تجيد لغة ذلك السوق! تجدر الإشارة هنا إلى أن تعاملاتك تلك مع العملاء ستبني بينك وبينهم جسورًا للتواصل وبناء العلاقات، ويجب أن تستفيد من تلك العلاقات لبناء شبكة معارف واسعة، ومن المعلوم أن زيادة الأرباح لا تتعلق فقط بجودة العمل، بل بمدى معرفة السوق بمن ينفذ ذلك العمل، فإن كنت فريد زمانك في صنعتك ولا يعرف بك أحد فلن تبيع شيئًا، فأكثر الرابحين في السوق هم المعروفون من أصحاب الجودة والتميز، وفي أحيان كثيرة يكون أكثر الرابحين هم المشهورون فقط، حتى إذا عرف السوق أحدًا يقدم نفس الخدمة بجودة أعلى انتقل إليه مباشرة. ولك في كبرى الشركات العالمية مثلًا، ألا ترى كيف يضعون علاماتهم التجارية أعلى البنايات الشاهقة وبأحجام عملاقة؟ إنهم يعلنون عن أنفسهم بأعلى صوت ممكن وفي كل مناسبة تصلح للإعلان، فلا يفكر العميل إلا فيهم حين يحتاج إلى من يحل مشكلته. تحديات العمل الحر يتغافل أغلب من يتكلم عن العمل الحر على الإنترنت عن مساوئ هذا النمط، إذ يذهب أغلب حديثهم إلى بيع منافعه من المرونة وزيادة الدخل وعدم الالتزام بزي ولا نظام محدد للعمل، في حين أن هذا النمط يحمل كثيرًا من التحديات التي قد تمنع فئات كثيرة من انتهاجه. 1- المنافسة الكبيرة قلنا أن من منافع العمل الحر هو تعرضك لسوق أكبر بكثير من سوقك المحلي، لكن هذا يأتي مع منافسة كبيرة جدًا كذلك، فإن كانت مدينتك فيها عشر أشخاص يقدمون نفس خدمتك، فإنك على الإنترنت ستكون بين مئات الآلاف منهم، وحينها يكون عليك التميز بشيء يقلل عدد منافسيك أمام العملاء، وإلا ستضطر إلى المنافسة على سعر الخدمة نفسها. فيمكنك تقديم خدمات ما بعد البيع للعميل، مثل إمكانية المراجعة والتعديل على العمل، أو إنجاز العمل في وقت أقل من المنافسين، أو تقديم باقات عروض أكثر للعميل، وغير هذا مما يقلل عدد المنافسين لك ممن يحذو حذوك. واعلم أنك ستجد منافسة شرسة على سعر الخدمة كلما سهل تنفيذها مثل إدخال البيانات وكتابة محتوى الشبكات الاجتماعية مثلًا، بل حتى في المهام المتخصصة مثل البرمجة والتصميم ثلاثي الأبعاد وغير ذلك ستجد منافسة على الأسعار من بلدان مثل الهند وفيتنام وكثير من البلاد العربية بسبب انخفاض قيمة العملة المحلية أمام الدولار الأمريكي الذي يكون في الغالب هو المعتمد في معاملات هذا السوق. 2- صعوبة كسب أول عميل وتحديد سعر الخدمة تمثل معضلة الحصول على أول عميل مشكلة للذي يدخل هذا المجال لأول مرة بدون سابقة أعمال في ملفه أو معرض أعماله، وقد حدثني بعض من جربوا دخول العمل الحر أنهم واجهوا مشاكل في هذا الصدد جعلتهم يتراجعون عن دخول السوق بالكلية. فقد كانت معارض أعمالهم خاوية بالطبع، والذي حدث أنهم لسبب أو لآخر قرروا دخول مجال العمل الحر، فسجلوا حسابًا جديدًا على منصة مستقل أو خمسات وبدؤوا في تصفح المشاريع. وهذا من وجهة نظر تجارية يعد سذاجة، فكأنك تدخل سوقًا وترى العملاء يدورون على المتاجر يبحثون عن طلباتهم، فتأتي أنت من خلف أحد العملاء لتقول له أن لديك ما يطلب! ألا ترى أن هذا الموقف لو حدث معك في السوق لشعرت بريبة من ذلك الذي يعرض عليك هذه الخدمة؟ وأنت تراه واقفًا بشخصه دون متجر أو بضاعة أو علامة تجارية أو غير ذلك، والتي يقابلها سابقة الأعمال وشهادة العملاء هنا في العمل الحر. كذلك إن وضع هذا المستقل الجديد عرضًا على مشروع لتصميم موقع أو برمجته أو ترجمة مقالة أو وثيقة، فكيف يثمن قيمة خدمته؟ وما هي المعايير التي يجب أن يضعها في حساباته؟ 3- صعوبة سحب الأرباح وتحويل الأموال تعاني بعض الدول العربية من مشكلة حقيقة في تحويل الأرباح، إذ لا يمكن استخدام حساب باي بال فيها، وهو الوسيلة المتبعة بشكل واسع عبر العالم لتحويل الأرصدة والمبالغ المالية على مواقع الويب وخاصة منصات العمل الحر، وحتى إن تم تحويل المبالغ بطرق أخرى فإن العملية قد تستغرق وقتًا أطول، الأمر الذي يؤثر سلبًا على الشخص الذي يعتمد على العمل الحر كمصدر دخل أساسي. وسنذكر في المقال الثامن من هذه السلسلة بعض الطرق التي ثبت نجاحها -وقت نشر المقال- لكيفية الإدارة الناجحة للشؤون المالية. 4- حالات النصب والاحتيال العمل على الإنترنت يعني التعامل مع عملاء من مختلف أنحاء العالم، وأنت لا تعرف كل أولئك العملاء معرفة تضمن لك حقوقك، وعليه فهناك احتمال كبير لظهور حالات احتيال، أو امتناع من عميل عن دفع كامل المبلغ المستحق أو عن دفع آخر دفعة مثلًا وذلك بسبب غياب الثقة بين الطرفين، وفي هذه الحالات تُعد منصات العمل الحر خيارًا مناسبًا يضمن للمستقل الأمان المالي الذي يسعى إليه، والأمثلة على هذه المنصات في العالم العربي تشمل موقع مستقل وموقع خمسات، وفائدتها أنها تؤمّن لك مجتمعًا كاملًا من المستقلين والعملاء ومن ثم توفر عليك عناء البحث بمفردك عن عملائك، هذا من ناحية، وتضمن لك هي التزام العميل بدفع ثمن الخدمة التي تقدمها من ناحية أخرى. ويتمثل نموذج ربح هذه المنصات في اقتطاعها نسبة من قيمة العمل التي يحددها المستقل، وقد تصل إلى 20% من المبلغ المتفق عليه مقابل تقديم الخدمة أو المشروع بشكل آمن يضمن حقوق الطرفين، وقد تُنقص المنصة قيمة عمولتها منك مع عميل معين عند تجاوز حجم تعاملاتك معه قيمة معينة، هذا فضلًا عن تسهيل الإجراءات والأمور المالية بطريقة توفر الكثير من العناء بالنسبة للمستقل. 5- عدم الاستقرار وعدم وجود عائد منتظم أحد التحدياتالجوهرية في العمل الحر هي حالة عدم الاستقرار، فالمستقل لا يرتبط بوظيفة ثابتة، ويمكن في أي لحظة أن يبقى دون أي عمل بانتظار العميل القادم، وتؤثر حالة عدم الاستقرار هذه بشكل كبير على الشخص الذي يعتمد على العمل الحر كمصدر أساسي للدخل، شأنه في ذلك شأن أي عمل حر غير منتظم، وفي هذا ننصح باستغلال الوقت الذي لا يكون عندك طلبات من عملاء في تطوير نفسك في مجالك والتسويق على الإنترنت لعملك في حساباتك الاجتماعية أو موقعك، أو المتابعة مع عملائك السابقين برسائل تطمئن فيها على جودة العمل الذي سلمته لهم، أو تحسين معرض أعمالك وإضافة أعمالك الجديدة إليه التي شغلك تنفيذ العمل نفسه عن إضافتها. كذلك ستلاحظ عدم التوازن في طلبات العمل أو الخدمات، خاصة في بداية عملك في ذلك السوق، حيث سيكون هناك ضغط عمل في وقت معين وعدم وجود أي عميل في وقت آخر. ومن ثم لن يكون لديك أي دخل ثابت تستطيع الحصول عليه بشكل منتظم، الأمر الذي يؤدي إلى عدم قدرتك على الوفاء يالتزاماتك المالية خاصة في المراحل الأولى، لذا ننصح بالبدء في العمل الحر بشكل جانبي ما أمكنك ذلك إلى أن يصير دخلك من العمل الحر مجزيًا للانتقال إليه بشكل كامل. 7- عدم وجود مزايا وظيفية أو ضمان اجتماعي إن السبب الأول الذي يدفع الناس للوظائف الثابتة هي المنافع التي تأتي معها مثل الراتب التقاعدي والتأمينات والإجازة المرضية وغير ذلك، وهي من المغريات لأي موظف بلا ريب، في حين أن العمل الحر لا يتمتع بأي من تلك المزايا. بل أسوأ من ذلك، إن توقفت عن العمل فإن دخلك سيقف، فليس هناك إجازات مدفوعة الأجر مثلًا أو غير ذلك، وينبني على هذا أننا نحن الذين تقع على عاتقنا مسؤولية التفكير في دخل التقاعد ومتى يكون ذلك التقاعد، والتأمينات الصحية والطوارئ وغير ذلك، كما سنبين في المقال الثامن: الإدارة المالية في العمل الحر. 8- مسؤولية العمل الكبيرة إن كنت موظفًا في شركة أو مؤسسة ما فإنك ستحمل مجموعة محددة من المسؤوليات التي تقبض أجرك عليها، وستكون تلك المهام جزءًا من مهمات أكبر يتم تقسيمها على كافة أعضاء الفريق. أما في العمل الحر فأنت مضطر للعمل وحدك -على الأقل في البداية-، وعليه ستكون مسؤولية العمل كبيرة وتقع كلها على عاتقك، إذ أنك في هذه الحالة إما شركة من شخص واحد، أو مدير لشركة من عدة أشخاص إن كنت تدير فريقًا تحتك. 9- صعوبة إدارة الوقت بما أنك سيد نفسك في العمل الحر ، ومدير الشركة والمحاسب وعامل النظافة وأمين السر وفني الحواسيب وكل شيء، فستجد رأسك تنشغل بمهام كثيرة في كل يوم تزاحم تفكيرك كي ترى بأيها تبدأ، وقد تمر عليك أوقات يكثر فيها العملاء فتعاني فوق هذا من ضغط مواعيد التسليم، وكل هذا سببه سوء إدارة الوقت. ناهيك عن أنك بشر، وعملك هذا يجب ألا يستغرق كل يومك، فإن عندك شؤون بيتك وأهلك وحياتك الاجتماعية، وقد يؤدي سوء إدارة الوقت إلى تفضيلك العمل على ما سواه من أجل إنجازه خشية فقد الصفقة أو تشويه السمعة، ومن ثم قد تمر عليك أسابيع وربما شهور تنعزل فيها عن حياتك الاجتماعية، إن لم تفق سريعًا وتستدرك الأمر، وسنبين في المقال السادس: العناية بالصحة الجسدية والنفسية، كيفية إدارة ذلك الوقت بكفاءة 10- صعوبة صقل المهارات والحصول على الخبرة لا شك أن صقل المهارة يكون بكثرة الممارسة، ولهذا تجد صعوبة في تحديد منهجية العمل المثلى والمناسبة لك في البداية، ومن ثم تنفيذ مهامك في وقت أطول وبجهد أكبر. لكن كأي مهارة أو عمل آخر فإن الخبرة ستجد طريقها إليك مع كثرة إنجازك للأعمال، وستجد نفسك بعد عام أو أكثر أو ربما أقل، تنجز مهمة ما في نصف الوقت الذي كنت تنجزه فيها أول عملك كمستقل، وربما بنصف الجهد أيضًا. ويلزم هذه الخبرة تعلم مستمر وملاحظة لأسلوب العمل وتلافي الأخطاء التي تحدث فيه، فإن الخبرة لن تهبط عليك إذا قضيت س يومًا في العمل، بل حين تتعلمشيئًا جديدًا في كل يوم يزيدك مهارة وإتقانًا في عملك. 12- سهولة التخلف عن السوق بدون تعلم مستمر على عكس الصناعات المستقرة والمجالات التي لا تشهد تغيرًا في تنفيذها، فإن العمل على الإنترنت، بل الإنترنت نفسه في تغير دائم ومستمر بحيث يمكن القول أن طالب علوم الحاسوب إن درس تقنية ما في السنة الأولى فربما لن يعمل بها عند تخرجه لاحتمال تغير هذه التقنية أو صدور أخرى تستبدلها. فما العمل إذًا، وهل سنقضي أعمارنا في التعلم دون العمل؟ كلا، فأنت في العمل الحر تتعامل مع الخدمات نفسها التي يطلبها العملاء من تفسير وترجمة لوثائق أو تصميمًا وبرمجة لشركات ومؤسسات، أو استشارات إدارية أو نحو ذلك. فلا نقول أن التصميم هو تصميم مواقع فقط، وإلا فهي تقنية قد يأتي عليها يوم وتحل محلها خدمة تقدم تصميم المواقع ببضع نقرات -وهذا حاصل حقًا-، أو قد يأتي يوم تتحسن فيه الترجمة الآلية إلى أن تستبدل المترجمين، وهكذا، فما الحيلة في ذلك إذًا؟ يجب أن تنتبه جيدًا إلى المجال الذي تعمل فيه لتوجه تطوير نفسك بشكل سليم، فتعلم أن تصميم المواقع هو في ذاته تصميم لهوية الشركة نفسها التي تريد عرضها على العملاء، فتتعلم نظريات الألوان وتجربة الاستخدام وقابلية الاستخدام، وتتابع التوجه العام للأجهزة التي يتصفح منها المستخدمون موقع الشركة الطالبة للخدمة، حتى تعرف أي التقنيات التي يجب تعلمها لتنفيذ تلك الهوية. وكذلك في البرمجة مثلًا، فإن لغة البرمجة نفسها لا تزيد على مجرد أداة تنفذ بها عملك، فتصرف وقتك في النظر في توجه السوق الطالب لهذه الخدمة، سواء على مستوى العملاء أو مستخدمي خدماتهم، وتزيد حصيلتك المعرفية في الرياضيات والخوارزميات وأساليب حل المشاكل، لأنك كمبرمج إنما تحل مشكلة للعميل، والأسس الرياضية التي تنبني عليها تلك الحلول تكون أكثر ثباتًا وأقل تغيرًا من اللغات التي تتبنى تنفيذ الحل نفسه. واعلم أن السوق هنا لا يرحم المتخلفين عن الركب، فإن لم تخصص لنفسك برامج وجداول دورية للتعلم والتطوير فستجد غيرك ممن دخل السوق حديثًا بتقنياته الجديدة أو ممن يطور نفسه بشكل مستمر قد سبقوك إلى العملاء، وتبقى أنت بلا عملاء ولا دخل. 13- وهم المرونة المطلقة يقول كثير من العاملين بشكل حر على الإنترنت أن المرونة هي أهم ميزة للعمل الحر، لكنهم يقعون في فخ المرونة المطلقة إذ يعتقدون بأنهم حقًاأحرار في منهجية عملهم. والواقع يقول بعكس ذلك، فالمستقل، خاصة المبتدئ الذي عانى للحصول على أول عميل، لا يستطيع أن يرفض العملاء والطلبات الواردة إليهومن ثم فإنه يصبح مقيّدًا بمواعيد تسليم تكاد لا تنتهي وسيكون عليه الالتزام بأكثر من مشروع والعمل عليها جميعًا بكفاءة عالية، فضلًا عن ضرورة أن يأخذ الظروف الاستثنائية بعين الاعتبار مثل الطوارئ أو عدم تفهم العملاء للتأخر أو ضعف جودة العمل أو سوء التواصل. وقد بينا قبل قليل أن العمل الحر هو عمل بالنهاية يلزمه نظام ومنهج للعمل، وإن كانت الحرية هنا في اختيار العملاء، واختيار روتين العمل ووقته، لكن يلزمك حد أدنى من الالتزام بهذه المعايير حتى تصرف وقتك إلى الأعمال التي تدر المال فقط، ولا تشغل نفسك كل يوم بالأمور الإدارية نفسها للعمل. 14- التواجد الدائم على الإنترنت أحد أوجه التقييد التي يمكن أن يعاني منها المستقل أيضًا هو ضرورة تواجده الدائم على الإنترنت، فقد تضطر للبقاء على اتصال دائم كي لا تفوت أي عميل، وتتابع عملاءك على مدار الساعة، وذلك حتى يتكون عندك قاعدة من العملاء الذين يفضلون التعامل معك، وحينها ستكون قد وطدت وسائل التواصل بينك وبينهم، وصنعت لنفسك معرض أعمال يتحدث عنك على الويب، بحيث يصل إليه من يبحث عن الخدمة التي تنفذها. 15- ضعف العلاقات الاجتماعية من السهل على المستقل الذي يعمل من منزله أن يقع في فخ الخلط بين الحياة العملية والشخصية والاجتماعية، فلن يكون هناك وقت واضح للراحة وآخر للعمل، وسيتسبب ذلك لا محالة في إرهاق نفسي له. ذلك أن العامل الحر يكون وحده أغلب الوقت على حاسوبه، فيكون منعزلًا بشكل ما عن المجتمع، فلا يقابل زملاءًا في كل يوم مثلًا، وقد يفقد تواصله حتى مع أصدقائه وعائلته، وذلك خطأ لا ريب، لكن الكثير من العاملين يقعون فيه تحت وطأة العمل وسوء إدارة أوقاتهم، وقد وقعت فيه بنفسي مرات كثيرة. والحل قد يكون في فصل مكان العمل عن الراحة، كما سنبين في المقالين السادس والسابع في شأن العناية بالصحة وبيئة العمل، ولو استطعت فصله عن المنزل بالكلية يكون أفضل وأحرى إذ ستخالط الناس في ذهابك وعودتك فلا تشعر بالوحدة، وكذلك بتحديد ساعات العمل وتثبيتها كل يوم، فيتعود عقلك أن هذا الوقت وقت عمل، وما بعده راحة، وهكذا. كذلك فإن تخصيص ثياب خاصة بالعمل فيه منفعة عظيمة إذ تنبه الدماغ إلى أنك الآن في وضع العمل، فلا تجلس لتتصفح الويب أو يوتيوب مثلًا -بما أنك ترتدي البيجامة وتتكئ على سريرك في غرفة النوم!-، بل هو وقت عمل له ميقات محدد، وإن نفع هذه الطريقة معلوم مشاهد في الشركات التي لها زي موحد أو في الجيوش أو غير ذلك، فارتداء العامل للزي الخاص بالعمل يجعله يقصي تلقائيًا أي مهمة لا تمت لهذا العمل بصلة، وذلك حتى انتهاء وقت العمل أو تبديله لتلك الثياب. خلاصة المقال لا يزال العمل الحر كثقافة غامضًا بالنسبة للكثيرين، مما يؤثر على خياراتهم وقراراتهم المرتبطة بمسارهم المهني، في حين أن الظروف الحالية في العالم ككل، والعالم العربي بشكل خاص تبدو مبشرة للعمل عن بعد والعمل بشكل حر، إلا أن المقبلين على هذا النمط يجب أن يكونوا على اطلاع ومعرفة بجميع جوانبه. وقد حاولنا تغطية كل ما يجب على الشخص معرفته في هذا المقال قبل أن يقرر الدخول إلى السوق أو قبل أن يقرر بأن يصبح عاملًا مستقلًا، لكن هذه المقدمة ليست كافية. ويجب أن يكون قرارك لدخول سوق العمل الحر مدروسًا وملائمًا لطبيعة عملك وشخصيتك حتى، لذلك يجب أن تبدأ بتحليل متطلبات السوق ومقارنتها مع مهاراتك بالإضافة إلى اطلاعك على المزيد من الأساسيات التي سنذكرها في المقال القادم، حيث نوضح المفاهيم المرتبطة بدخول السوق واختيار المجال المناسب، بالإضافة إلى تصحيح العديد من المفاهيم والأفكار التي توهم البعض أن العمل الحر مناسب للجميع. كتبت سارة شهيد المسودة الأولية لهذه المقالة. اقرأ أيضًا المقال التالي: الدخول إلى سوق العمل الحر على الإنترنت النسخة الكاملة من كتاب دليل المستقل والعامل عن بعد
    1 نقطة
  5. عملت كود مبدئي ولسبب ما اضطررت الى نسخ الكود في برنامج one note وعندما ارت استعادت الكود لم يعمل بشكل صحيح ما الحل واين يمكنني نسخ الاكواد واسترجاعها بشكل سليم وصحيح
    1 نقطة
  6. أنا مبتدئ فى مجال البرمجة محتاج جهاز إمكانياته إيه علشان ابداء
    1 نقطة
  7. لدي جدول بيانات به مجموعة من السجلات و أريد إضافة عمود جديد لهذا الجدول بدون فقدان البيانات الحالية كيف استطيع عمل ذلك في laravel
    1 نقطة
  8. سأضيف معلومة مهمة جداً: عند إنشاء Thread بإستخدام Runnable فإنه يمكن تشارك الـObject لكل الـthreads، عكس الطريقة الثانية التي تنشئ Object منفصل لكل thread. سأترك لك مثال موضح بالتعليقات لتفهم الأمر بشكل أفضل: class MyImplementedThread implements Runnable{ // الطريقة الأولى public int counter = 0; @Override public void run(){ counter++; // يتم زيادة العداد في كل مرة يتم تشغيل //thread System.out.println("implemented: "+counter); } } class MyThread extends Thread{ // الطريقة الثانية public int counter = 0; @Override public void run(){ counter++; System.out.println("MyTheread: "+counter); } } public class Main{ public static void main(String []args){ //الطريقة الأولى MyImplementedThread myImplementedThread = new MyImplementedThread(); /* ننشئ الكائن الذي ستشترك به كل الـ threads التي ستتبع الطريقة الأولى */ Thread implemented1 = new Thread(myImplementedThread); /* نعرف thread جديدة مع ارفاق الكائن الخاص بالطريقة الأولى */ implemented1.start(); // نبدأ عمل الـ //thread try{ Thread.sleep(1000); /* نقوم بإيقاف تشغيل مؤقت لمدة ثانية واحدة قبل متابعة إنشاءالـ threads الأخرى */ } catch(Exception e){ System.out.println(e.getMessage()); } Thread implemented2 = new Thread(myImplementedThread); implemented2.start(); try{ Thread.sleep(1000); } catch(Exception e){ System.out.println(e.getMessage()); } Thread implemented3 = new Thread(myImplementedThread); implemented3.start(); try{ Thread.sleep(1000); } catch(Exception e){ System.out.println(e.getMessage()); } //---------------------- //الطريقة الثانية MyThread myThread1 = new MyThread(); myThread1.start(); /* ننشئ thread منفصلة في كل مرة */ try{ Thread.sleep(1000); } catch(Exception e){ System.out.println(e.getMessage()); } MyThread myThread2 = new MyThread(); myThread2.start(); try{ Thread.sleep(1000); } catch(Exception e){ System.out.println(e.getMessage()); } MyThread myThread3 = new MyThread(); myThread3.start(); try{ Thread.sleep(1000); } catch(Exception e){ System.out.println(e.getMessage()); } } } لاحظ ناتج تنفيذ البرنامج: وهذا يدل على التشارك في الـObject في الطريقة الأولى حيث تم زيادة الـcounter بواحد من قبل كل thread بينما في الطريقة الثانية كل thread كان لها object خاص بها وبالتالي ظهر الرقم واحد بدون أي زيادة.
    1 نقطة
  9. يظهر لدي الخطأ التالي عند محاولة تشغيل برنامج بلغة java : java.lang.NullPointerException ما هو سبب ظهوره ؟ وكيف أعالج هذه المشكلة؟
    1 نقطة
  10. إن الفرق بين الطريقتين هو كالتالي: أولاً: عن طريق تطبيق الواجهة Runnable Interface: public class DemoRunnable implements Runnable { public void run() { //نضع هنا الكود الخاص بالعملية } } ثانياً: عن طريق استخدام الصف Thread: public class DemoThread extends Thread { public DemoThread() { super("DemoThread"); } public void run() { //نضع هنا الكود الخاص بالعملية } } وإن كلا الطريقتين متشابهتين ولا يوجد طريقة جيدة وأخرى سيئة، وأيضاً يوجد العديد من النقاشات حول استخدامات كل منها، ولكن من أهم الفروقات أو النقاط التي يجب عليك الانتباه لها لاختيار الطريقة المناسبة هي: 1- في استخدام Runnable أنت لا تخصص حقًا سلوك المسالك أو تعدلها. أنت فقط تعطي المسلك شيئًا لتشغيله. هذا يعني أن الترتيب في الكود سيكون أفضل. 2- لغة جافا تدعم فقط الوراثة وحيدة الدرجة، لذلك لا يمكنك إنشاء extend لأكثر من صف. 3- إن إنشاء واجهة تعطي interface تسمح لك بفصل المكونات عن بعضها ضمن الكود، وبذلك يصبح الكود الخاص بك أكثر مرونة ويمكنك ذلك من فصله عن العمليات المستخدمة ضمن المسلك thread. 4- في استخدام Runnable تجعل الصف الذي يقوم باستدعائها أكثر مرونة، أما إذا استخدمت Thread فإن الحدث الذي سيقوم به سيبقى دوماً ضمن الـ thread، أما في الحالة الأخرى أي Runnable فليس من الضرورة أن يبقى ضمن المسلك thread حيث يمكنك أيضاً تمرير البيانات إلى خدمات وصفوف أخرى. 5- وأخيراً، في حال قررت استخدام Thread فيجب عليك الانتباه إلى وجود خطأ بسيط Bug في نسخ JDK 4 أو الأقدم يتعلّق بالتوقيت بين بناء المسلك contruction و بدء عمله start، حيث قامت شركة Sun بإصلاح الخطأ بدءً من نسخ Java 1.5 ولذلك يجب عليك الانتباه للنسخة التي تقوم باستخدامها من جافا. وإذا نظرنا إلى جميع النقاط السابقة يمكن أن نلاحظ أن استخدام runnable مناسب أكثر لمعظم الحالات. ولكن هذا لا يعني عدم استخدام الصف Thread فكل مبرمج يفضّل الطريقة التي تناسب عمله ويرتاح بالعمل فيها.
    1 نقطة
  11. ليس هنالك فرق واضح بين الطريقتين ولكن الطريقة الاولى تعتبر اسهل نسبياً من الطريقة الثانية.
    1 نقطة
  12. java.lang.NullPointerException تعني أن الكائن عبارة عن null وتحاول ان تستدعي دالة بداخله ويمكنك معالجة الامر باستخدام try catch ولكن لايوصى بذلك وعوضاً عن ذلك يمكنك استخدام هذه الطريقة: if(someVariable != null){ someVariable.doSomething();//في حالة أن المتغير ليس null }else{ // الكود في حالة أن المتغير null }
    1 نقطة
  13. عند التعامل مع الـPassword Field في Java Swing نلاحظ أن getPassword() تعيد لنا char array بينما عند التعامل مع الحقول الأخرى نستخدم getText() فتعيد لنا String. لماذا تم إستخدام char array بدلا من String ؟
    1 نقطة
  14. أريد إنشاء برنامج دردشة / شات باستخدام ما تعملته من أساسيات لغة php، فما مبدأ عمل برنامج الدردشة؟ وكيف يمكنني إنشاء واحد؟
    1 نقطة
  15. يمكنك أن تبدأ في أي دورة من الدورات الحالية الموجودة في أكاديمية حسوب في أي وقت من هنا، ولا يوجد وقت محدد لبدء أي دورة منهم. الأمر متوقف عليك ومتى تريد أن تبدأ.
    1 نقطة
  16. السلام عليكم ورحمة الله حياكم الله ,,, ب أرشيف المسارات الأقدم كان في دوره لاساسيات تطوير الويب ... لاستاذ ثاني غير الموجود حاليا بالخيار الاول ... كيف بصل للقديم ممكن جواب
    1 نقطة
  17. يوجد لديك خطأ في إستعمال الدالة fputs هذه الدالة تستقبل سلسلة نصية على شكل مصفوفة محارف كمُعامل أول و مؤشر على File كمُعامل ثاني بهذا الشكل مثلاً: #include <stdio.h> int main () { FILE *fp; fp = fopen("file.txt", "w+"); fputs("This is c programming.", fp); fclose(fp); return(0); } أنت لم تقرأ شيء من الملف الذي تريد نقل مُحتواه فللكتابة في الملف الثاني يجب قراءة مُحتوى الملف الأول ثم نقله للملف الثاني بهذا الشكل مثلاً: #include <iostream> #include <stdio.h> using namespace std; int main() { FILE* pFile; // المصدر FILE* pofg; // الخرج char ch; // مُتغير سنستخدمه للقراءة pFile = fopen("a.txt", "r"); // فتح المصدر للقراءة pofg = fopen("abc.txt", "w"); // فتح الخرج للكتابة if (pFile != NULL) // إذا كان المصدر لا يُساوي null { ch = fgetc(pFile); // قراءة المحرف الأول من المصدر while(ch != EOF) // بما اننا لم نصل إلى نهاية الملف { fputc(ch, pofg); // أكتب في الخرج ما قمت بقرائته ch = fgetc(pFile); // واصل القراءة } cout<<"\nFile copied successfully."; // تم نقل المحتوى fclose(pFile); // غلق المصدر fclose(pofg); // غلق الخرج } return 0; }
    1 نقطة
  18. لنفترض أنه لديك حقل username في جدول المُستخدمين بهذا الشكل: $table->string('username')->unique(); الآن يجب أن تُعدل على نموذج تسجيل الدخول و بالضبط في حقل البريد ليُصبح بهذا الشكل: <div class="form-group row"> <label for="login" class="col-md-4 col-form-label text-md-right">{{ __('Username or Email') }}</label> <div class="col-md-6"> <input id="login" type="text" class="form-control{{ $errors->has('username') || $errors->has('email') ? ' is-invalid' : '' }}" name="login" value="{{ old('username') ?: old('email') }}" required autofocus> @if ($errors->has('username') || $errors->has('email')) <span class="invalid-feedback"> <strong>{{ $errors->first('username') ?: $errors->first('email') }}</strong> </span> @endif </div> </div> في ملف login.blade.php، و هذا حتى يقبل الحقل إدخال نص و عرض رسائل الخطأ. الآن يجب التعديل على المُتحكم LoginController سنُجري عليه بعض التعديلات حتى يُلائم الوضعية: نضيف الخاصية التالية للمُتحكم: protected $username; ثم من خلال الباني نقوم بتهيئة هذه الخاصية: public function __construct() { $this->middleware('guest')->except('logout'); $this->username = $this->findUsername(); } لاحظ أنها تأخذ قيمتها من خلال ما يُرجعه التابع findUsername لذلك نقوم بإنشائه في المتحكم أيضاً: <?php public function findUsername() { $login = request()->input('login'); // جلب قيمة النص الذي أدخله المُستخدم في الحقل $fieldType = filter_var($login, FILTER_VALIDATE_EMAIL) ? 'email' : 'username'; // بإستخدام القيمة يُمكننا معرفة إن كان المُدخل بريد او نص و على اساسها نضع نوع الحقل request()->merge([$fieldType => $login]); // وضع حقل جديد في الطلب return $fieldType; // email or username } كل ما يفعله التابع أنه يجلب لنا email او username على حسب القيمة المُدخلة و يضيف ذلك لمصفوفة الطلب: إذا كان المُدخل بريداً: 'email' => 'قيمة الحقل' إذا لم يكن بريد إلكتروني: 'username' => 'قيمة الحقل' الآن نقوم بإعادة تعريف كل من التابع username و التابع login اللذان يستخدمها المُتحكم LoginController إعتمادًا على الTrait AuthenticatesUsers لن نُغير على التابع login كثيراً سنأخذه كما هو و نضيف بعض الأشياء فقط: التابع username: <?php public function username() { return $this->username; } التابع login: <?php public function login(Request $request) { //نُغير التحقق $this->validate($request, [ 'login' => 'required|string', 'password' => 'required|string', ]); // نجلب نوع التسجيل $login_type = filter_var($request->input('login'), FILTER_VALIDATE_EMAIL) ? 'email' : 'username'; // نضيفه لمصفوفة الطلب $request->merge([ $login_type => $request->input('login') ]); // بقية الأشياء موجودة من الإطار نفسه و لن نغير فيها // If the class is using the ThrottlesLogins trait, we can automatically throttle // the login attempts for this application. We'll key this by the username and // the IP address of the client making these requests into this application. if (method_exists($this, 'hasTooManyLoginAttempts') && $this->hasTooManyLoginAttempts($request)) { $this->fireLockoutEvent($request); return $this->sendLockoutResponse($request); } if ($this->attemptLogin($request)) { return $this->sendLoginResponse($request); } // If the login attempt was unsuccessful we will increment the number of attempts // to login and redirect the user back to the login form. Of course, when this // user surpasses their maximum number of attempts they will get locked out. $this->incrementLoginAttempts($request); return $this->sendFailedLoginResponse($request); } لا تنسى إستدعاء الكلاسات المُستخدم في المُتحكم. هذا مُحتوى المُتحكم LoginController بعد التعديلات المُضافة: <?php namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; use App\Providers\RouteServiceProvider; use Illuminate\Foundation\Auth\AuthenticatesUsers; use Illuminate\Http\Request; class LoginController extends Controller { /* |-------------------------------------------------------------------------- | Login Controller |-------------------------------------------------------------------------- | | This controller handles authenticating users for the application and | redirecting them to your home screen. The controller uses a trait | to conveniently provide its functionality to your applications. | */ use AuthenticatesUsers; /** * Where to redirect users after login. * * @var string */ protected $redirectTo = RouteServiceProvider::HOME; protected $username; /** * Create a new controller instance. * * @return void */ public function __construct() { $this->middleware('guest')->except('logout'); $this->username = $this->findUsername(); } public function findUsername() { $login = request()->input('login'); $fieldType = filter_var($login, FILTER_VALIDATE_EMAIL) ? 'email' : 'username'; request()->merge([$fieldType => $login]); return $fieldType; } public function username() { return $this->username; } public function login(Request $request) { $this->validate($request, [ 'login' => 'required|string', 'password' => 'required|string', ]); $login_type = filter_var($request->input('login'), FILTER_VALIDATE_EMAIL) ? 'email' : 'username'; $request->merge([ $login_type => $request->input('login') ]); // If the class is using the ThrottlesLogins trait, we can automatically throttle // the login attempts for this application. We'll key this by the username and // the IP address of the client making these requests into this application. if (method_exists($this, 'hasTooManyLoginAttempts') && $this->hasTooManyLoginAttempts($request)) { $this->fireLockoutEvent($request); return $this->sendLockoutResponse($request); } if ($this->attemptLogin($request)) { return $this->sendLoginResponse($request); } // If the login attempt was unsuccessful we will increment the number of attempts // to login and redirect the user back to the login form. Of course, when this // user surpasses their maximum number of attempts they will get locked out. $this->incrementLoginAttempts($request); return $this->sendFailedLoginResponse($request); } } ملاحظة: هذه الطريقة مُستخدمة على إصدار 8 من لارافيل، بإستعمال الحزمة Laravel/ui
    1 نقطة
  19. مرحباً، يمكنك تسجيل الدخول عن طريق أحد الحلقين المذكورين ( البريد الالكتروني او اسم المستخدم) من خلال تنفيذ الخطوات التالية: بالبداية بكل تأكيد يجب أن تكون قد أنشأت ملفات المصادقة auth scaffolding ، من خلال عدة خيارات متاحة أثناء بناء تطبيقك، مثلاً: php artisan ui bootstrap --auth بعدها تأكد من اضافة حقل username في جدول المستخدمين الخاص بك لتكون كالتالي: <?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreateUsersTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('users', function (Blueprint $table) { $table->bigIncrements('id'); $table->string('name'); $table->string('email'); $table->string('username')->nullable(); $table->timestamp('email_verified_at')->nullable(); $table->boolean('is_admin')->nullable(); $table->string('password'); $table->rememberToken(); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('users'); } } ولا تنسى القيام بـ migrate في حال قمت بالتعديل على الملف السابق ليتم بناء قاعدة البيانات من جديد في ملف واجهة تسجيل الدخول login blade قم بحذف حقل البريد الالكتروني email و إضافة حقل اسم المستخدم username كي يكون بديلا عنه (سنقوم بجعله يقبل الاثنين في الخطوة القادمة) عبر الكود التالي: <div class="form-group row"> <label for="username" class="col-md-4 col-form-label text-md-right">Username Or Email</label> <div class="col-md-6"> <input id="username" type="username" class="form-control @error('username') is-invalid @enderror" name="username" value="{{ old('username') }}" required autofocus> @error('username') <span class="invalid-feedback" role="alert"> <strong>{{ $message }}</strong> </span> @enderror </div> </div> الان سنقوم بتعديل تابع تسجيل الدخول login في ملف LoginController كي يحقق الوظيفة المطلوبة كالتالي: <?php namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; use Illuminate\Foundation\Auth\AuthenticatesUsers; use Illuminate\Http\Request; class LoginController extends Controller { use AuthenticatesUsers; protected $redirectTo = '/home'; /** * Create a new controller instance. * * @return void */ public function __construct() { $this->middleware('guest')->except('logout'); } /** * Create a new controller instance. * * @return void */ public function login(Request $request) { $input = $request->all(); $this->validate($request, [ 'username' => 'required', 'password' => 'required', ]); $fieldType = filter_var($request->username, FILTER_VALIDATE_EMAIL) ? 'email' : 'username'; if(auth()->attempt(array($fieldType => $input['username'], 'password' => $input['password']))) { return redirect()->route('home'); }else{ return redirect()->route('login') ->with('error','Email-Address And Password Are Wrong.'); } } } يقوم التعديل السابق بفحص البيانات المدخلة في حقل username فإذا كانت بصيغة email فإنه سيقوم بمقارنتها بعمود البريد الالكتروني في قاعدة البيانات و الا فإنها اسم مستخدم و سيقارنها بحقل username بقاعدة البيانات.
    1 نقطة
  20. هناك عدة حزم مُعظم المُطورون يستخدمون إحداها لعمل هذه الجزئية في مشروعهم و من هذه الحزم أذكر: Laravel-permission التي تم تطويرها من طرف spatie و هم معروفين بتطوير عدة حزم مشهورة و مُستخدمة و يُطورون عليها بإستمرار. bouncer من تطوير Joseph Silber Laratrust هذه الحزم أكثر إستخداماً في هذا الموضوع و هي تُحدث بإستمرار حتى تدعم الإصدارات الجديدة من إطار laravel. إن كنت تريد إنجاز هذا الأمر فستتعب قليلاً و هذه الخطوات يُمكنك تطبيقها للوصول إلى ما تريد: إنشاء مودل لكل من Role و Permission و ملف تهجير لكل منهما: php artisan make:model Permission -m php artisan make:model Role -m كما تعلم فتمرير -m يعني أننا نريد إنشاء ملف تهجير أيضاً. تعديل ملفات التهجير: ملف تهجير الصلاحيات: <?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreatePermissionsTable extends Migration { public function up() { Schema::create('permissions', function (Blueprint $table) { $table->id(); $table->string('name'); // edit posts $table->string('slug'); //edit-posts $table->timestamps(); }); } public function down() { Schema::dropIfExists('permissions'); } } ملف تهجير الأدوار: <?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreateRolesTable extends Migration { public function up() { Schema::create('roles', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('slug'); $table->timestamps(); }); } public function down() { Schema::dropIfExists('roles'); } } إنشاء ملفات تهجير الجداول الإضافية لربط الصلاحيات بالمستخدمين و ربط الصلاحيات بالأدوار و ربط الأدوار بالمُستخدمين: php artisan make:migration create_users_permissions_table --create=users_permissions php artisan make:migration create_users_roles_table --create=users_roles php artisan make:migration create_roles_permissions_table --create=roles_permissions و في ما يلي مُحتوى ملفات التهجير التي أنشأناها: جدول users_permissions: <?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreateUsersPermissionsTable extends Migration { public function up() { Schema::create('users_permissions', function (Blueprint $table) { $table->unsignedBigInteger('user_id'); $table->unsignedBigInteger('permission_id'); //FOREIGN KEY CONSTRAINTS $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); $table->foreign('permission_id')->references('id')->on('permissions')->onDelete('cascade'); //SETTING THE PRIMARY KEYS $table->primary(['user_id','permission_id']); }); } public function down() { Schema::dropIfExists('users_permissions'); } } جدول users_roles: <?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreateUsersRolesTable extends Migration { public function up() { Schema::create('users_roles', function (Blueprint $table) { $table->unsignedBigInteger('user_id'); $table->unsignedBigInteger('role_id'); //FOREIGN KEY CONSTRAINTS $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); $table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade'); //SETTING THE PRIMARY KEYS $table->primary(['user_id','role_id']); }); } public function down() { Schema::dropIfExists('users_roles'); } } جدول roles_permissions: <?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreateRolesPermissionsTable extends Migration { public function up() { Schema::create('roles_permissions', function (Blueprint $table) { $table->unsignedBigInteger('role_id'); $table->unsignedBigInteger('permission_id'); //FOREIGN KEY CONSTRAINTS $table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade'); $table->foreign('permission_id')->references('id')->on('permissions')->onDelete('cascade'); //SETTING THE PRIMARY KEYS $table->primary(['role_id','permission_id']); }); } public function down() { Schema::dropIfExists('roles_permissions'); } } نقوم بعملية التهجير: php artisan migrate إنشاء العلاقات بين النماذج علاقات النموذج Role: public function permissions() { return $this->belongsToMany(Permission::class,'roles_permissions'); } public function users() { return $this->belongsToMany(User::class,'users_roles'); } علاقات النموذج Permission: public function roles() { return $this->belongsToMany(Role::class,'roles_permissions'); } public function users() { return $this->belongsToMany(User::class,'users_permissions'); } إنشاء Trait لإستخدامه في النموذج User، في مٌجلد app نقوم بإنشاء مُجلد Permissions و نضع بداخله ملف HasPermissionsTrait.php ثم نقوم بتضمينه داخل النموذج User: <?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use App\Permissions\HasPermissionsTrait; class User extends Authenticatable { use HasFactory, Notifiable, HasPermissionsTrait; } يكون مُحتوى الملف HasPermissionsTrait بالشكل التالي: <?php namespace App\Permissions; use App\Models\Permission; use App\Models\Role; trait HasPermissionsTrait { public function givePermissionsTo(... $permissions) { $permissions = $this->getAllPermissions($permissions); if($permissions === null) { return $this; } $this->permissions()->saveMany($permissions); return $this; } public function withdrawPermissionsTo( ... $permissions ) { $permissions = $this->getAllPermissions($permissions); $this->permissions()->detach($permissions); return $this; } public function refreshPermissions( ... $permissions ) { $this->permissions()->detach(); return $this->givePermissionsTo($permissions); } public function hasPermissionTo($permission) { return $this->hasPermissionThroughRole($permission) || $this->hasPermission($permission); } public function hasPermissionThroughRole($permission) { foreach ($permission->roles as $role){ if($this->roles->contains($role)) { return true; } } return false; } public function hasRole( ... $roles ) { foreach ($roles as $role) { if ($this->roles->contains('slug', $role)) { return true; } } return false; } public function roles() { return $this->belongsToMany(Role::class,'users_roles'); } public function permissions() { return $this->belongsToMany(Permission::class,'users_permissions'); } protected function hasPermission($permission) { return (bool) $this->permissions->where('slug', $permission->slug)->count(); } protected function getAllPermissions(array $permissions) { return Permission::whereIn('slug',$permissions)->get(); } } إنشاء مُزود خدمة PermissionsServiceProvider: php artisan make:provider PermissionsServiceProvider نقوم بإضافة blade directive فيه و تعريف بوابة Gate من أجل كل صلاحية في الدالة boot: <?php namespace App\Providers; use App\Models\Permission; use Illuminate\Support\Facades\Blade; use Illuminate\Support\Facades\Gate; use Illuminate\Support\ServiceProvider; class PermissionsServiceProvider extends ServiceProvider { public function register() { // } public function boot() { try { Permission::get()->map(function ($permission) { Gate::define($permission->slug, function ($user) use ($permission) { return $user->hasPermissionTo($permission); }); }); } catch (\Exception $e) { report($e); return false; } //Blade directives Blade::directive('role', function ($role) { return "if(auth()->check() && auth()->user()->hasRole({$role})) :"; //return this if statement inside php tag }); Blade::directive('endrole', function ($role) { return "endif;"; //return this endif statement inside php tag }); } } بعد ذلك نقوم بتسجيل مُزود الخدمة في مصفوفة providers في الملف config\app.php: 'providers' => [ App\Providers\PermissionsServiceProvider::class, ], الآن تحتاج إلا إضافة بعض البيانات الإختبارية ملف بذر لكل من الصلاحيات و الأدوار و تضع فيه كل صلاحيات الموقع و بعض الأدوار التي تريد أن تكون ضمن تطبيقك و تربط الصلاحيات بالأدوار ثم تربط الأدوار بالمُستخدمين. <?php $admin_permission = Permission::where('slug','create-users')->first(); $manager_permission = Permission::where('slug', 'edit-users')->first(); //RoleTableSeeder.php $admin_role = new Role(); $admin_role->slug = 'admin'; $admin_role->name = 'Admin Role'; $admin_role->save(); $admin_role->permissions()->attach($admin_permission); $manager_role = new Role(); $manager_role->slug = 'manager'; $manager_role->name = 'Assistant Manager'; $manager_role->save(); $manager_role->permissions()->attach($manager_permission); $admin_role = Role::where('slug','admin')->first(); $manager_role = Role::where('slug', 'manager')->first(); $createUsers = new Permission(); $createUsers->slug = 'create-users'; $createUsers->name = 'Create Users'; $createUsers->save(); $createUsers->roles()->attach($admin_role); $editUsers = new Permission(); $editUsers->slug = 'edit-users'; $editUsers->name = 'Edit Users'; $editUsers->save(); $editUsers->roles()->attach($manager_role); $admin_role = Role::where('slug','admin')->first(); $manager_role = Role::where('slug', 'manager')->first(); $admin_perm = Permission::where('slug','create-users')->first(); $manager_perm = Permission::where('slug','edit-users')->first(); $admin = new User(); $admin->name = 'Samir Abboud'; $admin->email = 'samir@gmail.com'; $admin->password = bcrypt('password'); $admin->save(); $admin->roles()->attach($admin_role); $admin->permissions()->attach($admin_perm); $manager = new User(); $manager->name = 'Kamel Mahmoudi'; $manager->email = 'kamel@gmail.com'; $manager->password = bcrypt('password'); $manager->save(); $manager->roles()->attach($manager_role); $manager->permissions()->attach($manager_perm); يُمكنك إستخدام tinker لعمل test: $admin = User::where('email', 'samir@gmail.com')->first(); $admin->hasRole('admin'); // لفحص إن كان المُستخدم يملك الدور مدير $admin->givePermissionsTo('edit-users') // إعطاء المُستخدم صلاحية تعديل مُستخدمين $admin->can('create-users') // فحص المُستخدم إذا كان لديه صلاحية إنشاء مُستخدم في صفحات العرض يُمكن إستخدام التوجيه الذي أنشأناه: @role('admin') مرحبا مدير @endrole الخطوة الأخيرة هي إنشاء middleware لعدم السماح للمُستخدم الوصول إلى مسار مُحدد إذا لم يكن يملك الصلاحية: php artisan make:middleware RoleMiddleware php artisan make:middleware PermissionMiddleware <?php namespace App\Http\Middleware; use Closure; class RoleMiddleware { public function handle($request, Closure $next, $role) { if (!auth()->check()) { return redirect()->route('login'); } if(!auth()->user()->hasRole($role)) { abort(403); } return $next($request); } } <?php namespace App\Http\Middleware; use Closure; class PermissionMiddleware { public function handle($request, Closure $next, $permission) { if (!auth()->check()) { return redirect()->route('login'); } if(!auth()->user()->can($permission)) { abort(403); } return $next($request); } } بعد ذلك تقوم بتسجيل هاتين الmiddleware ضمن App\Http\Kernel.php في مصفوفة routeMiddleware: <?php protected $routeMiddleware = [ . . 'role' => \App\Http\Middleware\RoleMiddleware::class, 'permission' => \App\Http\Middleware\PermissionMiddleware::class, ]; الآن يتبقى فقط الإستخدام في ملف المسارات: <?php Route::group(['middleware' => 'role:admin'], function() { // مسارات المُستخدم الذي يملك الدور مدير }); أو من خلال باني المُتحكم: public function __construct() { $this->middleware('permission:create-users')->only(['create', 'store']); } إن كنت ستستخدم حزمة جاهزة فستجد كل هذه الخصائص موجودة فيها و ستجدها قد تم إختبارها بإستعمال الإختبارات الأحادية أيضاً.
    1 نقطة
  21. في البداية يجب عليك تجهيز بعض الجداول للقيام بذلك, فستحتاج على الأقل إلى جدول للأدوار وجدول للصلاحيات وجدول صلاحيات الدور. كل واحد منها يحمل الاسم الذي سيتعامل معه النظام, كالتالي: Schema::create('permissions', function (Blueprint $table) { $table->bigIncrements('id'); $table->string('name'); $table->timestamps(); }); هذا للصلاحيات وكذلك للأدوار كالتالي: Schema::create('roles', function (Blueprint $table) { $table->bigIncrements('id'); $table->string('name'); $table->timestamps(); }); أما لجدول صلاحيات الدور فسيحتوي على id لكل دور يقابله الصلاحيات المعطاه له كالتالي: Schema::create('role-permissions', function (Blueprint $table) { $table->bigIncrements('id'); $table->unsignedBigInteger('role_id'); $table->unsignedBigInteger('permission_id'); $table->timestamps(); $table->foreign('role_id')->references('id')->on('roles'); $table->foreign('permission_id')->references('id')->on('permissions'); }); حيث أن هذا الجدول مخصص للعلاقة وربط بين الجدولين. بالطبع سنحتاج إلى Models لل Role و Permission حتى نستطيع التعامل مع الجداول سأفترض معرفتك بهذا الأمر ولكن سأوضح العلاقة الموجودة والتي هي واحد لمجموعة 1:m وممثلة كالتالي في Permission model: public function role(): { return $this->belongsTo(Role::class); } وفي Role model: public function permission(): { return $this->hasMany(Permission::class); } هكذا تكونت العلاقات لدينا, الأن نريد أن نضيف عمود جديد في جدول users باسم role حتى نستطيع إعطاءه الدور الخاص به. وهذا يعني أننا نريد أن ننشئ الصلاحيات ومن ثم تحديد هذه الصلاحيات حسب دور محدد ومن ثم نعطي هذا الدور للمستخدم وبهذا الشكل سيمتلك المستخدم الصلاحيات. ولكن نريد تطبيق ذلك في المشروع لدينا وهذا يتم عبر ال Middlewate غالباً لكن يمكن فحصه في controller بداخل ال constructor الخاص بهذا ال controller ولكن دعنا نقول أننا نريد التعامل باستخدام Middleware فما علينا فعله هو أن نتأكد بداخله إن كان هذا المستخدم لديه الصلاحيات لدخول إلى صفحة معينة أو القيام بأمر معين. وعلى المستوي الشخصي أستخدم مكتبة جاهزة توفر الوقت علي بهذا الأمر وتقوم به بطريقة ممتازة واسم هذه المكتبة Laravel-permission فكل ما عليك فعله هو تتبع خطوات التنزيل الموضحة ومن ثم تعلم استخدام المكتبة.
    1 نقطة
  22. اللارافيل تسهل القيام بذلك من خلال امرين: البوابات او الgates : وهي عبارة عن بوابة تعطي المرور للمستخدمين المصرح لهم القيام بالواجبات المعينة. ويتم تعريف البوابات بداخل الدالة boot use App\Models\Post; use App\Models\User; use Illuminate\Support\Facades\Gate; /** * Register any authentication / authorization services. * * @return void */ public function boot() { $this->registerPolicies(); Gate::define('update-post', function (User $user, Post $post) { return $user->id === $post->user_id; }); } في الكود الموجود بالأعلى يتم إنشاء بوابة تقوم بتحديد عملية تحديث الpost للشخص الذي قام بانشائه فقط وذلك من خلال مقارنة الid الخاص بالمستخدم الحالي مع الid الخاص بالمستخدم الذي قام بإنشاء الpost. <?php namespace App\Http\Controllers; use App\Http\Controllers\Controller; use App\Models\Post; use Illuminate\Http\Request; use Illuminate\Support\Facades\Gate; class PostController extends Controller { /** * Update the given post. * * @param \Illuminate\Http\Request $request * @param \App\Models\Post $post * @return \Illuminate\Http\Response */ public function update(Request $request, Post $post) { if (! Gate::allows('update-post', $post)) {//هنا يتم التأكد باستخدام البوابة update-post من أن المستخدم مصرح له تحديث ال post abort(403);//يتم اجهاض العملية مع الخطأ 403 اي أن المستخدم غير مصرح للقيام بالعملية } // متابعة الكود وتحديث المنشور } } بعد عملية إنشاء الgate يأتي الدور على ربط البوابة مع الcontroller حيث تم وضع شرط لمواصلة تنفيذ التحديث على البوست وهو ان تكون قيمة البوابة قيمة ايجابية اي ان المستخدم مصرح له القيام بالامر. : او السياسات policies من خلال ال php artisan make:policy PostPolicy --model=Post خاصة بالموديل بوست حتكون موجودة في المسار policy الامر ده من خلاله سيتم إنشاء app/Policies بعدها ستقوم بتسجيل السياسة التي قمت بعملها في المسار App\Providers\AuthServiceProvider والتسجيل بمثابة اخبار للارافيل بالسياسات التي ستستخدمها في البرنامج. <?php namespace App\Policies; use App\Models\Post; use App\Models\User; class PostPolicy { /** * Determine if the given post can be updated by the user. * * @param \App\Models\User $user * @param \App\Models\Post $post * @return bool */ public function update(User $user, Post $post) { return $user->id === $post->user_id; } } في الكود السابق يتم التحقق من أن المستخدم مصرح له أن يقوم بعملية التحديث. وتقدر تستخدم الpolicy بواحدة من طريقتين: اما عن طريق الblade : @can('update', $post) <!-- ...بتقوم بعرض جزئيات من التصميم للمستخدم في حال انه كان يمكنه عمل تحديث للبوست --> @elsecan('create', App\Models\Post::class) <!-- ...بتقوم بعرض جزئيات من التصميم للمستخدم في حال انه كان يمكنه عمل انشاء لبوست جديد--> @endcan @cannot('update', $post) <!-- ...تقوم بعرض جزئيات من التصميم للمستخدم في حال انه كان لا يمكنه عمل تحديث للبوست --> @elsecannot('create', App\Models\Post::class) <!-- ...بتقوم بعرض جزئيات من التصميم للمستخدم في حال انه كان لا يمكنه عمل انشاء لبوست جديد--> @endcannot عن طريق الربط مع الcontroller: <?php namespace App\Http\Controllers; use App\Http\Controllers\Controller; use App\Models\Post; use Illuminate\Http\Request; class PostController extends Controller { /** * Update the given post. * * @param \Illuminate\Http\Request $request * @param \App\Models\Post $post * @return \Illuminate\Http\Response */ public function update(Request $request, Post $post) { if ($request->user()->cannot('update', $post)) { abort(403); } // Update the post... } }
    1 نقطة
  23. تعد المصادقة المتعددة مهمة جدًا إذا كنت تعمل على تطبيق ويب كبير الحجم، فتمكنك من استخدام صلاحيات مختلفة تابعة لجداول مختلفة للمستخدمين مثل جدول "المستخدمين" لتسجيل مستخدم الموقع وجدول "المشرفين" للمستخدم المسؤول أو للدخول إلى لوحة التحكم على سبيل المثال. وبهذه الطريقة توفر أمانًا وقوةً حيث يمكنك الفصل بين المستخدمين وإعطاء صلاحيات وصول مختلفة لكل نوع. مثال عن تطبيقها: أولاً نقوم بإنشاء مصادقة في حال لم تكن موجودة كالتالي: php artisan make:auth نقوم بإنشاء مودل للمدراء كالتالي، ونقوم بملء الحقول اللازمة ضمنه: php artisan make:model Admin ثم نقوم بإنشاء المتحكم الخاص بالمدراء: php artisan make:controller AdminController class AdminController extends Controller { public function __construct() { $this->middleware('auth:admin'); } public function index() { return view('admin'); } } ونلاحظ هنا أنه تم استخدام middleware وهو admin، ولكن لمستخدمي الموقع يجب أن نستخدم مصادقة أخرى، حيث لا يجب على المستخدمين العاديين الدخول إلى لوحة التحكم للموقع، فنقوم أولاً بمعالجة عملية المصادقة وتسجيل الدخول للمدراء عن طريق إنشاء متحكّم خاص بذلك كالتالي: php artisan make:controller Auth/AdminLoginController أما للمستخدمين العاديين فسيتم التحقق والمصادقة بشكل منفصل كالتالي: public function showLoginForm() { return view('auth.login'); } وأخيراً لا ننسى تعديل ملف config/auth.php وإضافة الجزئية الخاصة بمصادقة المدراء كالتالي: //المصادقة الافتراضية 'defaults' => [ 'guard' => 'web', 'passwords' => 'users', ], //مصادقة المدراء أو المشرفين التي قمنا بإنشائها 'admins' => [ 'driver' => 'eloquent', 'model' => App\Admin::class, ], // // 'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'admin' => [ 'driver' => 'session', 'provider' => 'admins', ], ], // // 'providers' => [ 'users' => [ 'driver' => 'eloquent', 'model' => App\User::class, ], 'admins' => [ 'driver' => 'eloquent', 'model' => App\Admin::class, ], ], // وهنا يمكننا ملاحظة أنه تمكّنا من فصل كيان المستخدم المدير عن كيان المستخدم العادي، عن طريق استخدام جدولين مختلفين في قاعدة البيانات واستخدام guard مختلف وجلسات مختلفة لكل منهما. وبنفس الطريقة يمكن إضافة نوع جديد آخر ينتمى أيضاً لجدول آخر في قاعدة البيانات وله صلاحيات وصول مختلفة.
    1 نقطة
  24. الحذف الناعم أو soft delete هي نوع من أنواع حذف البيانات ولكن بدل من التخلص من البيانات بشكل تام يتم إخفائه والاحتفاظ بالبيانات في الجداول لديك. ويتم ذلك عن طريق إضافة عمود جديد في الجدول باسم deleted_at أو أي اسم تريده ولكن هذا هو المتعارف عليه, حيث يكون فارغاً أو null بالوضع الطبيعي ولكن عن تطبيق ال soft delete على أحد العناصر يتم إضافة تاريخ الحذف في deleted_at. ويمكن تفعيل هذه الميزة عن طريق إضافة Trate use SoftDeletes; بداخل ال Model المراد تطبيق هذه الخاصية عليها وكذلك بداخل الجدول أو migration الخاص بهذا ال Model نضيف $table->softDeletes(); حتى يضيف العمود deleted_at بنوع date على هذا الجدول. وهكذا تضاف الحذف الناعم لدينا. ويترتب على هذه الميزة أنه في حال كانت هنالك بيانات محذوفة بالطريقة الناعمة فلا يمكنك إستدعائها بالطريقة العادية مثلاً: Product::all(); فيجب أن تضيف عليها الدالة withTrashed كما يلي: Product::withTrashed() ->get(); هذا في حال كنت تريد تضمين البيانات الغير محذوفة مع البيانات المحذوفة حذفاً ناعماً, أما إذا كنت تريد فقط البيانات المحذوفة بشكل ناعم نستخدم: Product::onlyTrashed(); وفي حال كنت تريد إستعادة إحدى البيانات من كونها محذوفة بطريقة ناعمة نستخدم الدالة restore كالتالي: $product = Product::withTrashed()->where('id', 1)->restore(); وأي معلومات إضافية يمكننا مساعدتك بها ولكن يمكن التوجه أيضاً إلى التوثيق الرسمي للارافيل.
    1 نقطة
  25. يُمكن إستخدام eloquent لحذف السجلات بشكل ناعم، عند الحذف الناعم للسجل، لن تُحذف السجلات فعليًّا، وإنما ستُعيّن الخاصية deleted_at على السجل وتُحفظ في قاعدة البيانات. في حال كان السجل يملك قيمة deleted_at غير فارغة non-null، هذا يعني أنه قد حُذف. لتمكين الحذف الناعم لسجل ما نضيف ال trait SoftDeletes للمودل الذي نريد أن يُطبق الحذف الناعم: <?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; class User extends Model { use SoftDeletes; } و نضيف العمود deleted_at لملف التهجير الخاص بالمودل: <?php Schema::table('users', function ($table) { // other fields $table->softDeletes(); }); بهذا الشكل عند إستخدام التابع delete على أي كائن من الصنف User: <?php $user = User::find(1); $user->delete(); لن يتم حذفه فعلياً بل سيتم تعديل السجل بتعديل قيمة deleted_at إلى التاريخ الذي تم حذف السجل فيه. و سيبقى في قاعدة البيانات، و عند الإستعلام على المُستخدمين: <?php $users = User::all(); لن تظهر السجلات المحذوفة بشكل ناعم مع السجلات الكلية. هناك عدة توابع أخرى يُمكن إستخدامها لمعرفة ما إذا كان سجل ما محذوف بشكل ناعم، او جلب السجلات المحذوفة ناعماً بالإضافة إلى عملية إسترجاع هذه السجلات يُمكنك الإطلاع عليها من خلال توثيق موسوعة حسوب: الحذف الناعم (Soft Deleting)
    1 نقطة
  26. في الحذف الناعم أو soft delete عند حذف نموذج ما ، لا تتم إزالته بالفعل من قاعدة البيانات الخاصة بك. بدلاً من ذلك ، يتم تعيين الطابع الزمني delete_at على السجل. وبذلك تمكّنك لارافيل من استعادة البيانات فيما بعد. لتمكين عمليات الحذف الناعمة لنموذج ، حدد خاصية softDelete على النموذج، مثال: عند كتابة ملفات التهجير، نضيف الحقل softDeletes كالتالي: use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateItemsTable extends Migration { public function up() { Schema::create('items', function(Blueprint $table) { $table->increments('id'); $table->string('title'); $table->text('description'); $table->softDeletes(); $table->timestamps(); }); } public function down() { Schema::drop("items"); } } ثم عند تعريف المودل item نقوم باستخادم use softDeletes كالتالي: namespace App; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; class Item extends Model { use SoftDeletes; public $fillable = ['title','description']; protected $dates = ['deleted_at']; } والآن، عند استرجاع بيانات محددة، ستقوم لارافيل بإعادة السجلات فقط التي تحوي القيمة null ضمن العمود deleted_at، أي بمعنى آخر سيتم إهمال أي سجلات تحوي قيم ضمن الحقل deleted_at وكأنها غير موجودة، ولكن يمكنك بأي وقت الرجوع إلى قاعدة البيانات ورؤيتها حيث لن يتم حذفها بشكل نهائي: مثلاً عند تنفيذ الأمر التالي: $data = Item::get(); ستعيد كافة الحقول التي قيمة deleted_at فيها هي null أما لاستعادة كافة السجلات (المحذوفة والغير محذوفة) عندها يجب أن تستعمل الأمر التالي: $data = Item::withTrashed()->get(); إذاً، الفائدة هنا هي عند وجود بعض السجلات التي ترغب بعدم حذفها نهائياً من قاعدة البيانات وحتى لا يتم استرجاعها عند كل عملية جلب للبيانات من القاعدة يمكنك استخدام تقنية الحذف الناعم وبالتالي ستبقى ضمن قاعدة البيانات ويمكنك الرجوع إليها عند الضرورة ولكن لن يتم استرجاعها إلا عندما ترغب بذلك. وهذا مفيد جداً لأنه يحسّن من الأداء والسرعة.
    1 نقطة
  27. نعم مفهومك عنها صحيح وهي غالبا تستعمل مع الملفات التي تحتوي على عدد لا بأس به من القيم تفاديا لاستهلاك الميموري ويمكنك ان ترى في المثال في الاسفل def numbers_sum(nums): result = [] for i in nums: result.append(i+i) return result my_nums = numbers_sum([1, 2, 3, 4, 5]) print(my_nums) # [2, 4, 6, 8, 10] في المثال لدينا قائمة وببساطة نحن نرجع قائمة اخرى للقيم مجموعة لنفسها وطول القائمة هو 5 لكن لو كانت لديك قائمة طولها 100 مليون وادخلتها للمعالجة في الكود السابق سوف تلاحظ مشاكل في الكمبيوتر وقد يتوقف عن الاستجابة اذا كان كمبيوتر قديم نوعا ما ولحل المشكلة نستخدم generators ونقرا القائمة قيمة بعد قيمة def numbers_sum(nums): for i in nums: yield(i+i) my_nums = numbers_sum([1, 2, 3, 4, 5]) print(my_nums) # <generator object numbers_sum at 0x7f95f264f518> for num in my_nums: print(num) الكود في الاعلى هو محاكات للكود السابق لكن باستخدام generators الفرق هنا انك ستتلقى كل قيمة على حدى عوض انك ستتلقاهم في قائمة وتلاحظ انني استخدمت for loop للدوران على my_nums وذلك لان for loop لديها القابلية للتوقف عند انتهاء القيم فعند مناداة next على my_num اكثر من 5 مرات في مثالنا سنتحصل على خطأ برمجي يخبرنا ان القيم انتهت print(next(my_nums)) # 2 print(next(my_nums)) # 4 print(next(my_nums)) # 6 print(next(my_nums)) # 8 print(next(my_nums)) # 10 print(next(my_nums)) # error StopIteration
    1 نقطة
×
×
  • أضف...