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

محمد_عاطف

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

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

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

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

    117

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

  1. إجابة محمد_عاطف سؤال في خطأ في كود درس التعامل مع النماذج Forms كانت الإجابة المقبولة   
    المشكلة لديك هنا :
    لاحظ هنا في ال id لقد قمت بكتابة أول حرف كبير S . ولكنك في جزء إضافة الإستماع إلى الحدث وضعت حرف صغير :
    وحيث أن اللغة حساسة للأحرف لهذا لا يتم العثور على ال id الصحيح .
    ولذلك يجب عليك إما جعل أول حرف كبير في السطرين السابقين أو جعله صغير أى يجب أن يكونوا متطابقين :
    <html> <head> <link rel="stylesheet" href="training.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <script> $(function () { $('#selectBtn').click(function () { $('input:checkbox').attr('checked', 'checked'); }); $('#deselectBtn').click(function () { $('input:checkbox').removeAttr('checked'); }); }); </script> </head> <body> <form> <input id="html" value="" type="checkbox" /> <label for="html">HTML</label> <br> <input id="css" value="" type="checkbox" /> <label for="css">CSS</label><br> <input id="javascript" value="" type="checkbox" /> <label for="javascript">javascript</label><br> <input id="jquery" value="" type="checkbox" /> <label for="jquery">jquery</label><br> </form> <select id="languages" name="languages"> <obtion value="java"> Java</obtion> <option value="cs">C</option> <option value="php">php</option> <option value="vb">visual basic</option> </Select> <br><br> <form> <input type="button" id="selectBtn" value="Select ALL"> <input type="button" id="deselectBtn" value="Deselect ALL"> </form> <script src="java script.js"></script> </body> </html> إذا كان هذا السؤال هو سؤال خاص بالدروة يرجى وضع سؤالك أسفل الدرس الذي توجد به مشكلتك وليس هنا حيث هنا هو قسم الأسئلة العامة.
  2. إجابة محمد_عاطف سؤال في فرص العمل في البرمجة في وجود الذكاء الإصطناعي كانت الإجابة المقبولة   
    أولا إن البدأ في تعلم HTML و CSS هو أمر جيد في البداية ولكن دراستهم بمفردهم لن يفيدوك بأى شئ حاليا . فهما يعتبران فقط لغات الويب الأساسية لكن غير كافية للعمل على مشاريع حقيقية وأيضا توجد العديد من أدوات الذكاء الإصطناعي حاليا تقوم بإنشاء هيكل المشاريع ب HTML و CSS بسهولة وسرعة جدا والتي من المؤكد أنها ستأخذ وظائف المبرمجين في هذا المجال لهذا تعلمهم هما فقط ليس مناسبا ويمكنك قراءة التالي :
    أيضا لا يستطيع شخص أن يجزم بشكل كامل أو شبه متأكد من مما إذا كان سيأخذ الذكاء الإصطناعي وظائف المبرمجين أم لا . ولكن حاليا الذكاء الإصطناعي يستطيع إستبدال المبرمجين الصغار والمبتدئين بسهولة . لهذا ما ينبغي على المبرمجين تعمله والإهتمام به هو مهارات حل المشكلات وتعلم الخوارزميات وهياكل البيانات وهندسة البرمجيات عموما .
    وأيضا في بداية التعلم لا ينبغي الإعتماد بشكل كامل على الذكاء الإصطناعي حيث ستؤثر بشكل كبير على فهمك وأيضا من الممكن أن يعطيك إجابات أو شرح ليس دقيقا أو صحيحا أو ممكن ليس كاملا مما سيجعل معلومات ناقصه أو خاطئة وهذا ليس بالأمر الجيد . لهذا إستخدام أدوات الذكاء الإصطناعي ينبغى على الشخص أن يكون لديه العلم الكافي الذي يمكنه من إستغلالها وإستخدامها بالشكل الصحيح وليس أن يتعلم منها بشكل كامل.
    الشهادات الجامعية حاليا ليست المقياس ولكنها ضرورية في بعض الوظائف وبعض الشركات تتطلبها بشكل أساسي . ولكن ما يهم هو الخبرة وكم المعلومات التي لديك . فلو أردت أن تعمل في مجال العمل الحر فالشهادات الجامعية ليست مطلوبة هنا بل المطلوب والتي يتحدث عنك هو خبرتك وكم المشاريع التي عملت عليها وأنجزتها.
    وإليك الإجابات التالية أيضا :
     
  3. إجابة محمد_عاطف سؤال في اي دورة مناسبة لي؟ كانت الإجابة المقبولة   
    وعليكم السلام ورحمة الله وبركاته.
    أولا إن في دروة  تطوير واجهات المستخدم يتم شرح أساسيات Html و Css وJava Script و jquery  و bootstrap والعديد من التقنيات الأخرى مثل webpack وغيرها حيث تؤهلك الدورة لتكون مطور واجهات مستخدم لمواقع ثابته حيث يمكنك تحويل اي تصميم الى موقع ثابت بإستخدام html و css و js . و jquery  هنا يساعدك كثيرا في التلاعب بمحتوي الصفحات الثابته بدلا من إستخدام أطر العمل مثل react والتي تقوم ببناء مشاريع واجهات أمامية (frontend) كاملة.
    وبالنسبة للمبتدأين في مجال تطوير الواجهات الأمامية فإنه من الصعب أن يبدأو بتعلم المكتبات مباشرة مثل react  دون تعلم الأساسيات حيث سيجدوا الكثير من الصعوبة في ذلك و أيضا هناك من يريد فقط أن يقوم بإنشاء مواقع ثابته و ثيمات دون التطرق للمكتبات المعقدة مثل react ولذلك هنا في الأكاديمية تم فصل ذلك الأمر إلى دورتين دورة تطوير واجهات المستخدم و دورة تطوير التطبيقات باستخدام JavaScript .
    لهذا الأمر يعتمد عليك يمكنك الإشتراك في دورة تطوير التطبيقات باستخدام JavaScript و مشاهدة أول مسار من دورة تطوير واجهات المستخدم الخاص بأساسيات  Html و Css وJava Script و jquery وهذا سيكفي للبدأ في هذا الأمر . ولكن لو أردت تطبيق مشاريع عملية في التصميم وأيضا تعلم boostrap و webpack فيفضل الإشتراك في دورة تطوير واجهات المستخدم .
    وحاليا يوجد عرض دورتين بسعر دورة واحدة لهذا يمكنك إغتنام تلك الفرصة والإشتراك في هذا العرض وإختيار الدورتين معا .
  4. إجابة محمد_عاطف سؤال في اريد اكواد مربع البحث في برنامج الاندرويد ستوديو كانت الإجابة المقبولة   
    يمكننا إستخدام الطريق التي تعتمد على استخدام EditText كمربع للبحث و RecyclerView لعرض النتائج.
    أولا سنقوم بإضافة مربع البحث EditText والقائمة اللتي ستعرض النتائج RecyclerView في ملف ال Layout الخاص بال Activity أو ال Fragment.
    بعد ذلك في ملف ال Java سنحصل على مراجع للعناصر اللتي أضفناها باستخدام ال findViewById.
    ومن ثم سنستخدم واجهة TextWatcher حتى نستمع للتغييرات اللتي تحدث في مربع البحث أولا بأول.
    وفي كل مرة يتغير فيها النص في مربع البحث سنقوم بفلترة البيانات الأصلية ونعرض النتائج المتطابقة في ال RecyclerView.
    وأخيرا سننشأ ال Adapter لل RecyclerView لربط البيانات بال RecyclerView وعرضها بشكل صحيح.
    الآن إليك ملف التنسيق XML وليكن بإسم activity_main.xml:
    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="16dp" tools:context=".MainActivity"> <EditText android:id="@+id/searchEditText" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="ابحث عن اسم..." android:inputType="text" /> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="0dp" android:layout_marginTop="8dp" android:layout_weight="1" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" /> </LinearLayout> وملف ال Activity أو ال Fragment وليكن بإسم MainActivity.java:
    import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; import android.widget.EditText; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { private EditText searchEditText; private RecyclerView recyclerView; private NameAdapter adapter; private List<String> originalNameList; private List<String> filteredNameList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); searchEditText = findViewById(R.id.searchEditText); recyclerView = findViewById(R.id.recyclerView); recyclerView.setLayoutManager(new LinearLayoutManager(this)); originalNameList = new ArrayList<>(); originalNameList.add("ahmed"); originalNameList.add("danaa"); originalNameList.add("mohamed"); originalNameList.add("mona"); originalNameList.add("ali"); originalNameList.add("mostafe"); filteredNameList = new ArrayList<>(originalNameList); adapter = new NameAdapter(filteredNameList); recyclerView.setAdapter(adapter); searchEditText.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { filterNames(s.toString()); } @Override public void afterTextChanged(Editable s) { } }); } private void filterNames(String query) { filteredNameList.clear(); if (query.isEmpty()) { filteredNameList.addAll(originalNameList); } else { query = query.toLowerCase(); for (String name : originalNameList) { if (name.toLowerCase().contains(query)) { filteredNameList.add(name); } } } adapter.notifyDataSetChanged(); } } وأخيرا ملف ال Adapter لل RecyclerView وليكن بإسم  NameAdapter.java:
    import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import java.util.List; public class NameAdapter extends RecyclerView.Adapter<NameAdapter.NameViewHolder> { private List<String> nameList; public NameAdapter(List<String> nameList) { this.nameList = nameList; } @NonNull @Override public NameViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View itemView = LayoutInflater.from(parent.getContext()) .inflate(android.R.layout.simple_list_item_1, parent, false); return new NameViewHolder(itemView); } @Override public void onBindViewHolder(@NonNull NameViewHolder holder, int position) { String name = nameList.get(position); holder.nameTextView.setText(name); } @Override public int getItemCount() { return nameList.size(); } public static class NameViewHolder extends RecyclerView.ViewHolder { public TextView nameTextView; public NameViewHolder(@NonNull View itemView) { super(itemView); nameTextView = itemView.findViewById(android.R.id.text1); } } }  
    في ملف ال XML قمنا بإنشاء ال EditText بال ID searchEditText وهو مربع البحث اللذي سيقوم المستخدم بالكتابة فيه.
    و أنشأنا RecyclerView بال ID recyclerView وسيعرض قائمة الأسماء المتطابقة. واستخدمنا LinearLayoutManager حتى نعرض العناصر بشكل عمودي.
     وفي ملف في ملف ال Activity قمنا بالحصول على مراجع ل EditText و RecyclerView باستخدام findViewById وأنشأنا قائمتين:
    originalNameList: تحتوي على جميع الأسماء الأصلية. filteredNameList: ستحتوي على الأسماء اللي تتطابق مع نص البحث. وفي البداية تكون نسخة من originalNameList. وأنشأنا ال NameAdapter وربطناه بال RecyclerView وقمنا باستخدام TextWatcher حتى نستمع للتغييرات في نص searchEditText في كل مرة بيتغير النص ونقوم بإستدعاء الدالة filterNames.
    وفي ملف ال Adapter قمنا بإستقبال قائمة الأسماء nameList اللتي سيتم إرسالها وهنا هي filteredNameList.
  5. إجابة محمد_عاطف سؤال في ظهور Details في الروابط الموجودة في الموقع كانت الإجابة المقبولة   
    هذه المشكلة بسبب أنك تستخدم الروابط النسبية وليس المطلقة .
    فمثلا في الصورة التي لديك هذا هو الكود الذي يظهر في المتصفح :
    <img src="Admin/uploadImage/../../uploadImage/-1099770893-1715637400.webp" width="330" height="256" alt=""> لاحظ أنك في ال src لم تضع علامة / في بداية الرابط مما يشير إلى أننا نريد المسار المطلق من index وليس من صفحة details .
    وأيضا في رابط الذهاب إلى صفحة index لاحظ كيف الكود الذي أنت ققمت بكتابته :
    <a class="active" href="index">تقني44</a> لهذا يجب وضع علامة ال / قبل المسار ليصبح كالتالي :
    <a class="active" href="/index">تقني44</a> وهكذا سيعمل معك وهذا الأمر ليس له علاقة بإعادة التوجيه.
  6. إجابة محمد_عاطف سؤال في اختصار الروابط في ملف .htaccess كانت الإجابة المقبولة   
    لاحظ المشكلة كما وضحت لك أنك تستعمل كود أخر لإعادة التوجيه وتحديدا هذا هو الكود :
    RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME}\.php -f RewriteRule ^(.*)$ $1.php [NC,L] ولهذا يتم التوجيه إلى العنوان :
    https://www.tecani44.com/Details/358.php حيث يتم وضع php. في نهاية الرابط وبما أنه لايوجد هذا الملف تحدث تلك المشكلة .
    وأيضا أنت تستخدم عدة أوامر RewriteEngine On وقواعد متكررة.
    يمكنك تجربة إستخدام الكود التالي :
    #For cut query string RewriteRule ^Details/([^/]+)$ Details.php?t=$1 [L] RewriteCond %{QUERY_STRING} t=(.*) RewriteRule ^Details$.php$ /Details$-%1.html? [R=301,L] RewriteRule ^Details$-([^?]*).html$ /Details$.php?t=$1 [QSA,L] #for cut .php RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME}\.php -f RewriteRule ^(.*)$ $1.php [NC,L] #for check <ifmodule mod_speling.c> CheckSpelling On </ifmodule> <IfModule mod_headers.c> Header unset X-Powered-By </IfModule> <IfModule mod_headers.c> Header set X-Frame-Options: "sameorigin" </IfModule> # For message Erorr Options -Indexes ErrorDocument 404 https://www.Tecani44.com/404 ErrorDocument 403 https://www.Tecani44.com/403 ErrorDocument 500 https://www.Tecani44.com/500 #For serversignature ServerSignature off # DO NOT REMOVE THIS LINE AND THE LINES BELOW HOTLINKID:5ZlinWvz7G RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?tecani44.com/.*$ [NC] RewriteRule .*\.(php)$ https://tecani44.com/Erorr [R,NC] # DO NOT REMOVE THIS LINE AND THE LINES ABOVE 5ZlinWvz7G:HOTLINKID  
  7. إجابة محمد_عاطف سؤال في خطأ عند إرسال البيانات من خلال Postman كانت الإجابة المقبولة   
    من الممكن أن المشكلة في postman لنحاول إرسال الطلب من نوع POST اي يجب عليكي تغير PUT إلى POST وإضافة :
    _method بقيمة PUT في البيانات هكذا :

  8. إجابة محمد_عاطف سؤال في ما هو رابط التوثيق المترجم لأكاديمية حاسوب للغة بايثون كانت الإجابة المقبولة   
    أعتقد أنك تقصد موسوعة حسوب حيث يوجد توثيق لعدة لغات هناك ودروس يمكنك متابعتها على الموسوعة من خلال الرابط التالي :
    https://wiki.hsoub.com/Python ويوجد أيضا كتاب هنا خاص على الأكاديمية بخصوص تعلم بايثون وإليك الرابط الخاص به :
    وتوجد مقالات كثيرة هنا بخصوص بايثون وإليك الرابط الخاص بها:
    https://academy.hsoub.com/programming/python/
  9. إجابة محمد_عاطف سؤال في تنسيق قائمة بطريقة انيمشن كانت الإجابة المقبولة   
    هذه الأمر من الممكن أن يتم إنشاءه بأكثر من طريقة في css من خلال ال transition و إستخدام الخاصية transform لتغير أماكن العناصر .
    ولكن في الموقع المرفق هنا تم إستخدام العنصر مرتين . وأيضا تم فصل كل حرف من الكلمات وذلك لجعل كل حرف يتحرك بشكل منفصل عن الأخر وأيضا تأخير وقت كل حرف حتي لا يتحركون معا ويظهر لكي نفس الشكل الموجود في الفيديو .
    إليكي الكود الخاص ب HTML وإنشاء العناصر :
    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="style.css"> </head> <body> <div class="container"> <span class="rolling-text"> <div class="block"> <span class="letter">P</span> <span class="letter">O</span> <span class="letter">R</span> <span class="letter">T</span> <span class="letter">F</span> <span class="letter">O</span> <span class="letter">L</span> <span class="letter">I</span> <span class="letter">O</span> </div> <div class="block"><span class="letter">P</span> <span class="letter">O</span> <span class="letter">R</span> <span class="letter">T</span> <span class="letter">F</span> <span class="letter">O</span> <span class="letter">L</span> <span class="letter">I</span> <span class="letter">O</span> </div> </span> <span class="rolling-text"> <div class="block"><span class="letter">A</span> <span class="letter">B</span> <span class="letter">O</span> <span class="letter">U</span> <span class="letter">T</span> <span class="letter">&nbsp;</span> <span class="letter">U</span> <span class="letter">S</span> </div> <div class="block"><span class="letter">A</span> <span class="letter">B</span> <span class="letter">O</span> <span class="letter">U</span> <span class="letter">T</span> <span class="letter">&nbsp;</span> <span class="letter">U</span> <span class="letter">S</span> </div> </span> <span class="rolling-text"> <div class="block"><span class="letter">R</span> <span class="letter">E</span> <span class="letter">N</span> <span class="letter">T</span> <span class="letter">A</span> <span class="letter">L</span> </div> <div class="block"><span class="letter">R</span> <span class="letter">E</span> <span class="letter">N</span> <span class="letter">T</span> <span class="letter">A</span> <span class="letter">L</span> </div> </span> </div> </body> </html> وهذا هو ملف css للتنسيقات :
    .container { display: flex; justify-content: center; align-items: center; gap: 25px; } .rolling-text { display: inline-block; overflow: hidden; height: 30px; line-height: 30px; cursor: pointer; } .rolling-text:hover .letter, .rolling-text.play .letter { transform: translateY(-100%); } .rolling-text .letter { display: inline-block; transition: transform 0.5s cubic-bezier(0.76, 0, 0.24, 1), -webkit-transform 0.5s cubic-bezier(0.76, 0, 0.24, 1); } .letter:nth-child(1) { transition-delay: 0s; } .letter:nth-child(2) { transition-delay: 0.015s; } .letter:nth-child(3) { transition-delay: 0.03s; } .letter:nth-child(4) { transition-delay: 0.045s; } .letter:nth-child(5) { transition-delay: 0.06s; } .letter:nth-child(6) { transition-delay: 0.075s; } .letter:nth-child(7) { transition-delay: 0.09s; } .letter:nth-child(8) { transition-delay: 0.105s; } .letter:nth-child(9) { transition-delay: 0.12s; }  
  10. إجابة محمد_عاطف سؤال في مشكلة في تهجير قاعدة البيانات كانت الإجابة المقبولة   
    المشكلة لديكي أنه يوجد كود يتم تنفيذه قبل تشغيل أمر migrate وهذا الكود يبحث عن جدول يسمى subscriber_categories .
    لذلك يرجى البحث في الملفات التالية عن كود يستخدم الجدول subscriber_categories ويجب تعطيله مؤقتا ومن ثم تشغيله بعد أمر التهجير :
    App\Providers\AppServiceProvider.php حيث في هذا الملف توجد دالة boot التي قد تحتوي على كود يتم تنفيذه قبل المهاجرات. App\Providers\AuthServiceProvider.php وأيضا هذا الملف. ومجلد ال app/Http/Middleware أيضا . ومجلد app/Providers . بعد وجود الكود الذي يستخدم جدول subscriber_categories يرجى تعطيله أو خذفه وتنفيذ أمر المهجرات ومن ثم إعادة الكود مرة أخرى.
    إذا إستمرت المشكلة يرجى إرفاق ملف المشروع.
  11. إجابة محمد_عاطف سؤال في هل هناك صفحة في لارافيل تحظر عرض الصورة من قاعدة البيانات ؟؟ كانت الإجابة المقبولة   
    المشكلة انكي لا تستخدمين دالة insert لعرض الصور . حيث في لارافيل يجب استخدامها للتعامل بشكل صحيح مع الصور.
    ولكن اولا يرجي تجربة وضع علامة /قبل مسار الصورة حتي يتم عرض اىصورة من جذر الخادم . ولكن اذا لم يتم وضعها يتم عرض الصورة من مسار نسبي الذي تقفي فيه حاليا .
    <img style="height: 50px; width : 150px" src="/{{$information->logo}}" alt="" > وهذا سيحل المشكلة ولكن الافضل كما وضحت استخدام دالة asset :
    <img style="height: 50px; width : 150px" src="{{asset($information->logo)}}" alt="" >  
  12. إجابة محمد_عاطف سؤال في difference btw y++ and ++y كانت الإجابة المقبولة   
    وعليكم السلام ورحمة الله وبركاته.
    إن y++ and ++y هما مفهومان مختلفان تماما ولنشرح معا الفرق بينهما .
    إذا تم إستخدام المعامل  قبل اسم المتغير فإن هذا ما يعرف باسم pre-increment:
    y = 1; x = ++y console.log(x); هنا من الإسم فإن هنا إذا كان المعامل قبل المتغير فسيتم أولا زيادة المتغير y قبل أى عملية . أى هنا سيتم زيادة ال y ب قيمة 1 لتصبح 2 و من ثم يتم وضع قيمة 2 في المتغير x وبذلك يتم طباعة 2 لأن x أصبح يساوي 2.
    أما إذا تم إستخدان المعامل بعد المتغير فهذا ما يعرف باسم post-increment:
    y = 1; x = y++ console.log(x); وهنا من إسمه إذا كان المعامل بعد المتغير فسيتم أولا تنفيذ العمليات المطلوبة ومن ثم يتم الزيادة . يعني في المثال السابق هنا العملية هي وضع قيمة y في x أى يتم وضع أولا قيمة y القديمة في x وبذلك يصبح x ب 1 ومن ثم حين إنتهاء العملية يتم زيادة y بقيمة 1 . أي هنا سيتم طباعة 1 لأن x ستكون ب 1 و y ستكون ب 2 .
    وكما في مثالك هنا إذا وضعت المعامل بعد present : 
    var createCounter = function(init) { let present = init; return { increment:()=> present++, decrement:()=> present--, reset:()=> present = init, } }; فهنا سيتم إعادة قيمة present القديمة أولا ومن ثم يتم زيادة أو إنقاص present بقيمة 1 . ولهذا تحدث المشكلة لديك .
    أما في المثال التالي :
    var createCounter = function(init) { let present = init; return { increment:()=> ++present, decrement:()=> --present, reset:()=> present = init, } }; فهنا يتم أولا تطبيق المعامل أى زيادة إو إنقاص present بقيمة 1 ومن ثم إعادة القيمة الجديدة بعد الزيادة أو النقصان.
  13. إجابة محمد_عاطف سؤال في ما هو أنسب مكان لتخزين عناصر السلة, قاعدة البيانات, الكوكيز أم الـ session ؟ كانت الإجابة المقبولة   
    وعليكم السلام ورحمة الله وبركاته.
    يوجد العديد من الطرق منها التي ذكرتها ومنها التي لم تذكرها وكل طريقة لها مميزات وعيوب وأيضا لها خصائص يجب توافرها لتنفيذها وأيضا تعتمد بشكل كبير على الخصائص التي تريدها في مشروعك.
    فأولا لو أردت أن بيانات السلة تكون موجودة في حساب المستخدم أى إذا قام بتسجيل الدخول من أى مكان سواء الهاتف أو الحاسوب أو في أكثر من مكان وتريد تلك البيانات أن تكون متزامنة ومتاحة . أى نفرض أنه أضاف منتج من خلال الهاتف و من ثم فتح المتصفح على الحاسوب يجب حينها أن يرى المنتجات التي أضافها من خلال الهاتف . هنا يجب أن يتم تخزين تلك البيانات من خلال الخادم الخاص ب Laravel .أى يجب عليك هنا إستخدام قاعدة البيانات وتوفير API لإضافة المنتجات في السلة وإحضار تلك المنتجات. وهنا لن تنفع خاصية ال session أو ال cookies وغيرها والتي تعتمد على الجافاسكريبت .
    أما إذا أردت أن تكون السلة غير متزامنه فيمكنك إستخدام جميع ما قلته ولكن لكل طريقة حدود .
    فال API أرى أنه الأفضل وحينها فقط ستقوم بإنشاء المنطق مرة واحدة فقط في الخادم عند حفظ المنتجات ولو يوجد لديك تطبيق هاتف أو تطبيق ويب فقط ستقوم بعرض تلك البيانات لديك ولن تقوم بحفظها لديك في التطبيقين أى ستقوم بإنشا منطق عرض المنتجات فقط أما حفظها وإحضارها سيكون من خلال ال API. ويجب على ال API أن يكون سريعا أما إذا وجدت أن الوقت بين الطلب والإستقبال كبير فهنا أعتقد أن المشكلة لديك في طريقة حفظ البيانات أو في الكود الخاص بالحفظ لذلك يرجى التأكد من هذا الكود ومحاولة إكتشاف لماذا يأخذ وقتا كثيرا.
    أما ال cookies فيمكنك إيقاف تشفير تلك البيانات إذا أردت من خلال laravel ولكنها فقط لن تتجاوز 4096 بايت وهذا ليس جيدا ولا أنصح به.
    أما بخصوص ال session يمكنك إستخدامها ولكن سيتوجب حفظ ال id الخاص بال session في قاعدة البيانات وبذلك عندما يقوم المستخدم في أى وقت بستجيل الدخول سيمكنك إستخدام ال session_id وإسترجاع تلك البيانات مباشرة ولكنها أيضا طريقة لا أنصح بها.
    الأفضل لك هو إستخدام Local Storage حيث تقوم بحفظها في ال localstorage لديك ويمكنك إحضارها في أى وقت من خلال javascript ولا يتم مسحها إلا إذا إستخدمت كود جافاسكريبت أى لا تقلق من ناحية إنتهاء الوقت أو إغلاق المتصفح ولكن كما وضحت لك تلك الطريقة لن تجعل منتجات السلة متزامنة.
  14. إجابة محمد_عاطف سؤال في لماذا تظهر المساحة الفارغة عند إختبار تجاوب التصميم كانت الإجابة المقبولة   
    وعليكم السلام ورحمة الله وبركاته.
    المشكلة لديك في هذا العنصر :

    لاحظ كيف أنك تستخدم :
    margin-right: 50% !important; transform: translateX(25%); ولهذا فإنه يتم إزاحته كثيرا جهة اليسار مما يسبب تلك المسافة الزائدة.
    ويفضل لجعل العنصر في المنتصف إستخدام flexbox كالتالي .
    في ملف src\sass\index.scss سطر 389 يرجى إستبدال التنسيقات بالتالي :
    .center-div { display: flex; flex-direction: column; align-items: center; width: 100%; } أو إذا أردت إستخدام التنسيقات التي لديك يمكنك وضع خاصية overflow hidden للعنصر curve-contain كالتالي :
    .curve-contain{ overflow: hidden; }  
  15. إجابة محمد_عاطف سؤال في مشكلة رفع تغييرات على Git كانت الإجابة المقبولة   
    يرجى تحميل برنامج anydesk وإرسال ال address الخاص بك للدخول على جهازك ومحاولة حل المشكلة لك.
  16. إجابة محمد_عاطف سؤال في ماهي الدورة من اكاديمية حاسوب التي تفيدني اكثر في سوق العمل الحر php ام JavaScript كانت الإجابة المقبولة   
    على مواقع العمل الحر العربية ستجد أن أغلب المطلوب هو PHP مع إطار عمل لارافيل و وورد بريس  وستجد أيضًا بعض الوظائف للـ .NET وأحيانًا وظائف لـ React و node مع express ولكن النسبة الأكبر من الوظائف هنا هي php .
    ويمكنك قراءة الإجابة التالية لمزيد من التفاصيل حول الوظائف المتاحة و اللغات المطلوبة أكثر  :
    أما الأهم من ذلك هو يفضل إتباع ما تحب فبعض الناس يفضلون php عن java script والبعض الأخر العكس و لذلك يفضل أن تشترك في الدورة الخاصة باللغة التي تفضلها .
    أما بخصوص دورة تطوير التطبيقات باستخدام JavaScript بعد الانتهاء من هذه الدورة يمكنك ان تصبح مطور برمجيات بلغة جافاسكريبت وتمكنك من ان تصبح مطور واجهات خلفية MERN stack وايضا تمكنك من تطوير تطبيقات الهاتف ومن الممكن ان تستعملها لتصبح FULL STACK Developer.
    أما  دورة تطوير تطبيقات الويب باستخدام لغة PHP بعد الانتهاء من هذه الدورة يمكنك ان تصبح مطور برمجيات بلغة php باطار عمل لارافيل و ووردبريس وهذه الدورة تؤهلك لتصبح مطور واجهات خلفية بواسطة php.
    ويمكنك قراءة الإجابات التالية لمزيد من التفاصيل حول الدورة والوظيفة التي يمكنك العمل بها بعد إنهاء الدورة :
     
  17. إجابة محمد_عاطف سؤال في كيف أعطي العميل الموقع على WordPress؟ كانت الإجابة المقبولة   
    وعليكم السلام ورحمة الله وبركاته.
    هل الإستضافة Hosting خاصة بك أم بالعميل ؟
    إذا كانت خاصة بك إذا يجب تسليمه الملفات ليقوم برفع موقعه بنفسه أو يعطيك هو بيانات الإستضافة الخاصة به وتقوم أنت برفع الملفات مع ربط الدومين الخاص به في الإستضافة.
    أما إذا كانت الإستضافة خاصة بالعميل ولكنك قمت بربط الدومين الخاص بك فيمكنك تعديل الـDNS من لوحة التحكم cpanel أو لوحة التحكم الخاصة بالإستضافة وتقوم بكتابة بيانات ال DNS  الخاصة بالدومين الجديد في لوحة التحكم مثل إعدادات A Record و CNAME .
    ويجب عليك مستقبلا الإتفاق مع العميل على كل شئ مسبقا مثل الإستضافة والدومين . و يمكنك فقط رفع المشروع على الإستضافة الخاصة بك لعرض المشروع على العميل وحتي يستطيع تجربته بنفسه حتي لا تقوم بتسليم الملفات قبل إرسال الأموال إليك . وبعد تجربة الموقع على الإستضافة الخاصة بك و التأكد من أن كل شئ يعمل يمكنك إستلام الأموال منه وتسليمه ملفات المشروع أو رفعه على الإستضافة الخاصة به.
  18. إجابة محمد_عاطف سؤال في Breadcrumbs لDjango كانت الإجابة المقبولة   
    يجب أولا أن يقوم مطور ال front-end  بتصميم وكتابة أكواد HTML وتنسيقات CSS ووضعها في الصفحة بالإضافة إلى ملفات Javascript إذا كان يوجد animation أو سلوك معين لل Breadcrumb.
    وإذا كانت الروابط معقدة في ال Breadcrumbs  و تتطلب مسارا كبيرا أو عرضها بطريقة ديناميكية فهنا سيتوجب على مطور back-end أخذ الهيكل html من مطور  ال front-end وتضمين الروابط الخاصة بال Breadcrumb في كل صفحة والعمل على إظهارها بالطريقة الصحيحة.
     
  19. إجابة محمد_عاطف سؤال في هل يمكنني استخدام WordPress إذا تعلمت ال frontend؟ كانت الإجابة المقبولة   
    نعم بالطبع من الأشياء الملزمة لفهم التعامل مع wordpress . ستجد هناك الكثير من الأشخاص الذين يقومون بتعلم wordpress مباشرة دون تعلم php ولكن سيجدون صعوبة في فهم بعض الأمور أو تنفيذها .
    فتخيل أنك تتعلم شئ مبني على أساسيات معينة دون دراسة تلك الأساسيات . بالفعل ستجد نفسك تعرف بعض الأمور ولكن دون الأساسيات لن تلم بجميع الأمور والخصائص.
    لذلك يفضل تعلم أساسيات php على الأقل قبل الدخول في wordpress.
    وبالتوفيق لك إن شاء الله.
  20. إجابة محمد_عاطف سؤال في مشكلة إزدياد إرتفاع جميع عناصر الـ Grid كانت الإجابة المقبولة   
    وعليكم السلام ورحمة الله وبركاته.
    المشكلة تكمن في السمة grid-rows-3 حيث هذه السمة تحوي الكود التالي :
    .grid-rows-3 { grid-template-rows: repeat(3, minmax(0, 1fr)); } هذا الكود سينشئ شبكة بثلاثة صفوف تتوزع بالتساوي في الارتفاع ولهذا ستجد أن جميع الصفوف ستأخذ طول أكبر صف .
       لذلك يمكنك حذف تلك السمة grid-rows-3 وستجد أن عنصر سيأخذ الطول الخاص به . ولكن جميع العناصر في نفس الصف سيأخذون نفس الطول .
  21. إجابة محمد_عاطف سؤال في كلمة محددة عندما يكتبها المستخدم تتحول إلى رابط في رياكت كانت الإجابة المقبولة   
    هل قمت بحفظ المقالة بعد إستبدال الكلمات بالروابط أم تم حفظها هكذا دون إستبدال ؟
    إذا لم يتم حفظها بعد الإستبدال إذا يجب إستخدام الدالة replaceText بالإستبدال :
    const replaceText = (text) => { const regex = /phoenix/gi; // البحث عن اسم المدونة const replaced_text = text.split(regex).join( `<a href="/" style="color: blue; font-weight: bold;">phoenix</a>` ); return replaced_text; }; return ( <div dangerouslySetInnerHTML={{ __html: replaceText(content) }} /> ); حيث content هو المتغير الذي يحتوي على المقالة .
    أما إذا تم حفظها بعد الإستبدال ففقط يجب إستخدام  dangerouslySetInnerHTML وهي خاصية  لعرض النص كHTML المعدل :
    return ( <div dangerouslySetInnerHTML={{ __html: =content }} /> );  
  22. إجابة محمد_عاطف سؤال في خطأ في تشغيل pg Admin كانت الإجابة المقبولة   
    وعليكم السلام ورحمة الله وبركاته.
    أولا يجب عليك إغلاق برنامج pgAdmin تماما وإغلاق رسالة الخطأ التي تظهر لك .
    بعد ذلك يرجى حذف مجلد  pgAdmin  في المسار التالي :
    C:\Users\%USERNAME%\AppData\Roaming مع إستبدال %USERNAME% بإسم المستخدم الخاص بك على ويندوز.
    بعد ذلك قم بفتح برنامج pgAdmin كمسؤل run as adminstrator ويجب على ذلك أن يحل المشكلة إن شاء الله.
  23. إجابة محمد_عاطف سؤال في استعمال ajax مع جانغو كانت الإجابة المقبولة   
    مرحبا عزيزى محمود .
    الخطأ لديك في templates\store\product-details.html سطر رقم 85 و 86 حيث أنك تضع ال id الخاص بالعنصر input ك 
    id="item-{{ item.sku }}" وهنا معظم ال item لها نفس ال sku فهنا ستجد أن العديد من العناصر لها نفس ال id ولذلك عند الضغط على label فإنه يبحث عن أول عنصر له ال id الخاص به ولذلك فإنه يختار العناصر في المقاس الإفتراضي . ولحل تلك المشكلة نقوم بتحديد متغير أخر له رمز فريد وهو {{ size.id }} وهو لن يتكرر مع ال item.sku لذلك يرجى تغير سطر 85 و 86 بالتالي :
    <input type="radio" name="item" id="item-{{ size.id }}-{{ item.sku }}" value="{{ item.sku }}" class="item-option" {% if forloop.first %}checked{% endif %}> <label for="item-{{ size.id }}-{{ item.sku }}"> <img src="{{ item.image.url }}" alt="{{ item.color }}"> </label> ولقد أرسلت لك الملف بعد التعديل .
    product-details.html
  24. إجابة محمد_عاطف سؤال في مشكلة في swiper كانت الإجابة المقبولة   
    وعليكم السلام ورحمة الله وبركاته .
    إذا ذهبت إلى صفحة product-details.html  و قمت بفتح ال console في المتصفح ستجد أخطاء ظهرت في ملف main.js وستجد خطأ يظهر في سطر 412 والكود الخاص بال swipper الذي يقوم بإنشاءه في سطر رقم 482 ولهذا يتوقف الكود عند سطر 412 ولا يستمر إلى 482 لهذا لا يعمل معك .
    من المفترض تقسيم ملف main.js إلى عدة ملفات كل ملف خاص بصفحة معينة وملف يحوى جميع الأكواد المشتركة في جميع الصفحات .
    حيث أنك تقوم بالبحث عن عناصر في الصفحة وتضع حدث عليها أو تقوم بتعديل التنسيق الخاص بها وإذا لم توجد تلك العناصر يحدث خطأ لديك ويمنع تنفيذ باقي الأكواد .
    يمكنك قبل العمل على أي عنصر التحقق من وجوده أم لا إذا لم ترد فصل الكود إلى عدة ملفات .
    وحاليا لحل مشكلتك يرجى نقل كود ال swipper في سطر 482 إلى ما قبل سطر 12 ويفضل نقل جميع ال swipper إلى دالة منفصلة و تنفيذها حتي لا تحدث مشاكل .
    ولقد قمت بإرفاق ملف main.js بعد تعديله .
     
    main.js
  25. إجابة محمد_عاطف سؤال في ما فائدة Token base authentication ؟ كانت الإجابة المقبولة   
    وعليكم السلام ورحمة الله وبركاته .
    نعم بالفعل قديما يتم تخزين بيانات المستخدم في ال session كما كان يحدث في php ولكن لنشرح معا الفرق بين session وبين ال token .
    تعتمد فكرة الـ Sessions على تخزين حالة المستخدم (User State) على السيرفر. عندما يقوم المستخدم بتسجيل الدخول أو زيارة الموقع لأول مرة يتم إنشاء Session له تلقائيا في السيرفر، ويتم تعيين مُعرف (ID) فريد لهذه الـ Session في الخادم ويتم حفظ ال id في المتصفح في ال session ويتم إرسال ال id مع كل طلب . هذا المُعرف يتم استخدامه للتعرف على المستخدم في كل طلب يرسله إلى السيرفر، وبذلك يكون السيرفر قادراً على معرفة هوية المستخدم والتأكد من صلاحيته.
    على العكس تماما الـ Tokens هي عبارة عن عناصر صغيرة من المعلومات (مثل سلسلة نصية) يتم توليدها وتشفيرها من خلال السيرفر بعد عملية تسجيل الدخول بنجاح. يتم تضمين هذا الـ Token في كل طلب يقدمه المستخدم إلى السيرفر. السيرفر يقوم بفحص الـ Token للتحقق من هوية المستخدم وصلاحيته ويتأكد هل ال Token تم التلاعب به أم لا. الـ Token يحمل معلومات مثل هوية المستخدم وأي صلاحيات أو صلاحيات الوصول (Access Permissions) التي لديه.
    المزايا الرئيسية للاستخدام الـ Token-based:
    أمان : الـ Tokens يكون مشفرا لهذا من الصعب التلاعب به أو تزويره. قابلية التوزيع: يمكن توزيع الـ Tokens عبر عدة سيرفرات أو خدمات بسهولة دون الحاجة إلى مشاركة حالة الجلسة بينهم فمن الممكن أن يكون المشروع لديك على عدة سيرفرات أو خدمات لهذا ال Sessions لن تنفع. عديم الحالة (Stateless): الـ Tokens تسمح بإنشاء تطبيقات عديمة الحالة (Stateless Applications)، حيث لا يتم تخزين حالة المستخدم على السيرفر فمن الممكن أن يكون الطلب يتم إرساله من تطبيق هاتف أو حتي تطبيق سطح مكتب أو ويب. لذلك ال Token-based أفضل حاليا من حيث القدرة على توزيع المشروع على عدة سيرفرات و عدم الإعتماد على حالة سيرفر واحد وال session الخاص به.
×
×
  • أضف...