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

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

  1. Hafsa Aly

    Hafsa Aly

    الأعضاء


    • نقاط

      6

    • المساهمات

      340


  2. بلال زيادة

    بلال زيادة

    الأعضاء


    • نقاط

      5

    • المساهمات

      4657


  3. Abdulraheem Barghouthi

    Abdulraheem Barghouthi

    الأعضاء


    • نقاط

      5

    • المساهمات

      182


  4. سامح أشرف

    سامح أشرف

    الأعضاء


    • نقاط

      3

    • المساهمات

      2934


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

المحتوى الأعلى تقييمًا في 02/14/21 in أجوبة

  1. لدي تطبيق بسيط جداً يحتوي على Column يضم عنصرين Text يحملان قيمة عشوائية من 0 لـ 100 ويوجد أيضاً Button عند الضغط عليها من المفترض تبديل أماكن العناصر في القائمة. لا يوجد أي أخطاء أو تحذيرات ! لكن عند الضغط على الButton لا يتم تبديل العناصر كما يجب أن يحدث. هذا هو الكود الخاص بالتطبيق: import 'dart:math'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; void main() => runApp(new MaterialApp(home: HomePage())); class HomePage extends StatefulWidget { @override State<StatefulWidget> createState() => HomePageState(); } class HomePageState extends State<HomePage> { List<Widget> tiles = [ MyRandomWidget(), MyRandomWidget(), ]; @override Widget build(BuildContext context) { return Scaffold( body: Center(child: Column( mainAxisSize: MainAxisSize.max, crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: tiles )), floatingActionButton: FloatingActionButton( child: Icon(Icons.sentiment_very_satisfied), onPressed: swap), ); } swap() { setState(() { tiles.insert(1, tiles.removeAt(0)); }); } } class MyRandomWidget extends StatefulWidget { @override ColorfulTileState createState() => ColorfulTileState(); } class ColorfulTileState extends State<MyRandomWidget> { int myNo; @override void initState() { super.initState(); myNo = Random().nextInt(100); } @override Widget build(BuildContext context) { return Text(myNo.toString()); } }
    2 نقاط
  2. السلام عليكم لدي فورم بسيط يحوي ادخال الاسم والموبايل والايميل كيف يمكن عدم ادخال الا الحروف فى حقل الاسم وارقام فقط فى حقل الفون وعدم ادخال اي صيغة اخرى غير الايميل فى خانة الايميل ولكم جزيل الشكر <?PHP $name = $_POST['name']; $phone = $_POST['phone']; $email = $_POST['email']; $db = mysql_connect('localhost', 'root', '', 'info'); $query = "insert into user values('".$name."','".$phone."','".$email."')"; $insert =$db->query($query); ?> <form method="post" action=""> <p><input name="name" type="text"></p> <p><input name="phone" type="text"></p> <p><input name="email" type="text"></p> <p><input type="submit"></p> </form>
    2 نقاط
  3. لفهم الفرق بين أنواع الـwidgets علينا أولاً فهم ماهيتها ومكوناتها. كل عنصر يظهر للمستخدم هو عبارة عن widget مثل نص، صورة، حقل إدخال...الخ. حيث يصف الـwidget سلوك وشكل العنصر في الشاشة، على سبيل المثال عند إضافة نص ومحاذاته في المنتصف نستخدم الـtext widget و الـcenter widget كالتالي: Center(// widget1 child: Text('hello',style:TextStyle(color:Colors.black)), // widget2 ) لاحظ أن الـ widget هو object يصف ويحدد شكل العنصر في الشاشة. بعد فهم ماهية الـwidget سنفرق بين الـstateless widget والـstateful widget. stateful widget: هو عبارة عن عنصر يحتوي على حالة أي يمكن حفظ بيانات فيه ويمكنه تغييرها وإعادة بناء/رسم نفسه أثناء التشغيل عن طريق الدالة setState. مثال عليه: class FavoriteWidget extends StatefulWidget { //القسم الأول الخاص بالعنصر @override _FavoriteWidgetState createState() => _FavoriteWidgetState(); } class _FavoriteWidgetState extends State<FavoriteWidget> { // القسم الثاني الخاص بحالة العنصر String msg = “hello”; // يمكن تعريف متغيرات وتغيير قيمتها أثناء تشغيل التطبيق @override Widget build(BuildContext context) { // الدالة الخاصة ببناء شكل العنصر return Text(‘$msg’); // نرجع نصاً يحمل قيمة المتغير المعرف مسبقاً } } stateless widget: هو عنصر ليس لديه حالة ولا يمكن تغيير بياناته أثناء تشغيل التطبيق إلا عن طريق إعادة تعريفه مرة أُخرى ببيانات مختلفة. مثال عليه: class MyWidget extends StatelessWidget { // يتكون من قسم واحد فقط خاص بالعنصر وليس له حالة final String msg = “hello”; // لاحظ تعريف المتغير يجب أن يكون نهائي ولا يمكن تغييره أثناء التشغيل @override Widget build(BuildContext context) { // دالة بناء شكل العنصر return Text(‘$msg’); } } إذاً نستخدم stateful مع العناصر التي تعتمد على بيانات متغيرة وتحتاج لإعادة رسم نفسها على الشاشة أثناء التشغيل. ونستخدم stateless في العناصر الثابتة التي لا نحتاج لتغييرها أو التعديل عليها أثناء التشغيل.
    2 نقاط
  4. $users = User::select('name', 'image', 'age')->where('age', '>=', 18)->limit(100)->get(); يمكنك جلب عدة حقول باستخدام دالة select كما في المثال إعلاه, اسماء الحقول داخل دالة select هي اسماء الحقول كما في الجدول في قاعدة البيانات. أما لو كنتي تقصدين كيف يتم ارجاع الحقول جميعها $users = User::where('age', '>=', 18)->limit(100)->get(); $users = User::whereIn('id', [6, 7, 9])->get(); هذه الاستعلامات ترجع جميع الحقول الموجودة لكل سجل وما قمنا بتحديده في دالة where أو whereIn هو الشرط الذي الذي يعود بالنتائج بناء عليه.
    2 نقاط
  5. التابع first() يقوم بجلب أول سجل يجده فقط، بينما التابع get() يجلب صنف collection، ويمكن تخيل هذا الصنف على أنه مصفوفة array من السجلات يمكن إستخدامها في حلقات التكرار مثل for loop أو while loop. بالنسبة لجلب عدد محدد من السجلات فيمكن إستخدام التابع limit(num) والذي يقبل عدد يتم تمريره إليه يعبر عن عدد السجلات المراد جلبها. $user = User::limit(2)->get(); بالنسبة لجلب السجلات بطريقة عشوائية in random order فيمكن إستخدام التابع ()inRandomOrder ليجلب كل السجلات في ترتيب عشوائي. $users = User::inRandomOrder()->get();
    2 نقاط
  6. 2 نقاط
  7. السلام عليكم .. الحين أنا كنت بدي اربط حسابي على github مع برنامج VSC عن طريق GitLens Extension لكن طلعتلي هادي الرسالة وما ظبط يربط مع الحساب فشو السبب ؟
    1 نقطة
  8. مرحبا ما هي افضل طريقة لسحب رصيد من مستقل الى سوريا علما ان paypal محظور. ارجو نصيحة من لديه تجربة
    1 نقطة
  9. السلام عليكم ورحمة الله وبركاته تحيه طيبه للجميع يا اخوان انا احاول اعمل مشروعي من نوع فلاتر نسخة APK ولكن كل ما احاول اعمل BUILD تجيني المشكله التاليه : C:\src\flutter\bin\flutter.bat --no-color build apk You are building a fat APK that includes binaries for android-arm, android-arm64, android-x64. If you are deploying the app to the Play Store, it's recommended to use app bundles or split the APK to reduce the APK size. To generate an app bundle, run: flutter build appbundle --target-platform android-arm,android-arm64,android-x64 Learn more on: https://developer.android.com/guide/app-bundle To split the APKs per ABI, run: flutter build apk --target-platform android-arm,android-arm64,android-x64 --split-per-abi Learn more on: https://developer.android.com/studio/build/configure-apk-splits#configure-abi-split Running Gradle task 'assembleRelease'... Plugin project :firebase_core_web not found. Please update settings.gradle. Note: C:\src\flutter\.pub-cache\hosted\pub.dartlang.org\cloud_firestore-0.12.11\android\src\main\java\io\flutter\plugins\firebase\cloudfirestore\CloudFirestorePlugin.java uses or overrides a deprecated API. Note: Recompile with -Xlint:deprecation for details. Note: C:\src\flutter\.pub-cache\hosted\pub.dartlang.org\cloud_firestore-0.12.11\android\src\main\java\io\flutter\plugins\firebase\cloudfirestore\CloudFirestorePlugin.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details. Removed unused resources: Binary resource data reduced from 235KB to 212KB: Removed 9% FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':path_provider:verifyReleaseResources'. > A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade > Android resource linking failed C:\Users\*****\.gradle\caches\transforms-2\files-2.1\733257008ca62c5b6ddfd0e885c42d88\core-1.1.0\res\values\values.xml:142:5-173:25: AAPT: error: resource android:attr/fontVariationSettings not found. C:\Users\*****\.gradle\caches\transforms-2\files-2.1\733257008ca62c5b6ddfd0e885c42d88\core-1.1.0\res\values\values.xml:142:5-173:25: AAPT: error: resource android:attr/ttcIndex not found. * Try: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights. * Get more help at https://help.gradle.org BUILD FAILED in 1m 19s Running Gradle task 'assembleRelease'... 80.8s The built failed likely due to AndroidX incompatibilities in a plugin. The tool is about to try using Jetfier to solve the incompatibility. Building plugin cloud_firestore... Running Gradle task 'assembleAarRelease'... The plugin cloud_firestore could not be built due to the issue above. Process finished with exit code 1 في احد يعرف سبب المشكله هذا او كيف يمكن حلها؟
    1 نقطة
  10. لو وضعت stateless widgets في الـList واعطيتهم أرقام مباشرة كالتالي: List<Widget> myList = [ Text(‘1’), Text(‘2’) ]; لسار كل شيء كما تريد لكنك قمت بإستخدام stateful widgets بدون تعيين key لها وبالتالي لن يتم التعرف على التغيير الحاصل في الـList الخاصة بك. لكن لماذا تم التعرف على هذا التغير عندما تم إستخدام عناصر من نوع stateless ؟ لأن القيمة النصية للعنصر مرتبطة بالعنصر نفسه أي لا يوجد لها حالة كما هو الحال في stateful widgets الذي تحتفظ بالقيمة النصية في الحالة الخاصة بها. إذاً لحل المشكلة يجب إضافة key فريد لكل العناصر المراد التبديل بينها بحيث يتم التفريق بين تلك العناصر حسب الـkey. يجب أولا أن نهيئ الـ constructor الخاص بـ MyRandomWidget ليستقبل key ويقوم بتمريره للـsuper: class MyRandomWidget extends StatefulWidget { MyRandomWidget({Key key}) : super(key: key); //….باقي الكود } بعد تهيئة الـconstructor نقوم بتمرير UniqueKey (مفتاح فريد يتم توليده عشوائياً ) عند تعريف العناصر في داخل الـList ليصبح الكود كالتالي: List<Widget> tiles = [ MyRandomWidget(key: UniqueKey()), //إضافة معرف فريد للعنصر MyRandomWidget(key: UniqueKey()),//إضافة معرف فريد للعنصر ]; الآن وبعد إسناد معرف فريد لكل عنصر سيعمل كل شيء على يرام. مرفق الملف بعد التعديل. main.dart
    1 نقطة
  11. هل التابع first() نفس دور get() ام انه لجلب المستخدم الاول واذا كان لدي مثلا في جدول البيانات ثلاثة مواضيع واريد عرض اول وثاني موضوع فقط ومرة اخرى عرض موضوعين فقط ولكن بطريقه عشوائيه
    1 نقطة
  12. كيف احفظ صفحه الاجابات ع سؤالي هذه بحيث استطيع ان اراها بسهوله مرة اخرى
    1 نقطة
  13. يمكنك الوصول إلى الـenvironment variables الضغط على This PC أو my computer بزر الفأرة الأيسر ومن ثم إختيار properties كما هو موضح في الصورة التالية: نقوم بعدها بالضغط على advanced system settings: بعد ذلك نقوم بالدخول على system environment variables كما هو موضح: بعد وصولنا لهذه الشاشة نتابع الخطوات في التعليق السابق لإضافة الـgit إلى الـenvironment variables.
    1 نقطة
  14. فهمت عليك لكن المشكلة ان لما كتبت في البحث environment variables ما ظهر اشي ؟
    1 نقطة
  15. عدم إدخال إلا الحروف : يمكنك القيام بذلك من خلال الجافا سكربت باختبار الزر الذي يتم الضغط عليه عند الكتابة داخل الinput كالاتي: <input type="text" onkeydown="return checkValue(event)"> وفي الدالة checkValue سيتم اختبار قيمة الادخال والتأكد من أنها تتكون من حروف فقط كما يلي: function checkValue(event) { let key = event.keyCode;//للحصول على الكود الخاص بالزر المضغوظ return ((key >= 65 && key <= 90) || (key >= 95 && key <= 122));//هنا يتم اختبار الكود الخاص بالزر ما إذا كان الحرف كبير ويقع بين القيمتين الA-Z (95-120) او حرف صغير a-z (65-90) } ادخال ارقام فقط: <input type="number"> ادخال البريد الإلكتروني فقط: <input type="email">
    1 نقطة
  16. على أي أساس يتم إستخدام stateful أو stateless ؟ وما هو الفرق بينهما ؟
    1 نقطة
  17. رسالة الخطأ تقول أنه لا يمكن العثور على git في جهازك، إذا كان الـgit غير منصب فيجب تحميله وتنصيبه ومن ثم متابعة الشرح التالي. أما كان الـgit منصباً يجب عليك إضافته في الـenvironment variables لكي يعثر عليه الـVS Code، تابعي الخطوات التالية: نضغط على قائمة إبدأ ونكتب في حقل البحث " environment variables " ثم نضغط عليها كما هو موضح في الصورة التالية نقوم بالضغط على زر environment variables تحت قسم user variables نضغط على Path نقوم بإضافة المسار الخاص ببرنامج git المنصب على جهازك " C:\Program Files\Git\bin " نضغط ok لحفظ التعديلات ومن ثم نعيد تشغيل الـVS Code.
    1 نقطة
  18. أول شيء إصدارات PHP أوقفت التعامل مع mysql و استبدلتها ب mysqli أو PDO. هناك عدة دوال لحماية المدخلات ومنها mysql_real_escape_string: تقوم بحماية المدخلات المضافة إلى قاعدة البيانات. strip_tags: تمنع إضافة أكواد HTML , PHP داخل قاعدة البيانات. htmlspecialchars: يمكنك مراجعة توثيق موسوعة حسوب بالدالة لفهمها أكثر من هنا $name = strip_tags($_POST['name']); $name = htmlspecialchars($_POST['name']); $name = mysql_real_escape_string($_POST['name']); ويمكن صنع دالة حماية واستخدامها مع كل مدخل مثل function filterThis($string) { return mysql_real_escape_string($string); } function filterThis($string) { return strip_tags($string); } function filterThis($string) { return htmlspecialchars($string); } فلو أردنا تطبيق هذه الدوال على الكود الخاص بك يصبح هكذا <?PHP $name = strip_tags($_POST['name']); $phone = strip_tags($_POST['phone']); $email = strip_tags($_POST['email']); $db = mysql_connect('localhost', 'root', '', 'info'); $query = "insert into user values('".$name."','".$phone."','".$email."')"; $insert =$db->query($query); ?> <form method="post" action=""> <p><input name="name" type="text"></p> <p><input name="phone" type="text"></p> <p><input name="email" type="text"></p> <p><input type="submit"></p> </form>
    1 نقطة
  19. قد تلاحظين أن في laravel هناك عدة طرق للوصول إلى ما نريد، لذلك في هذه الحالة لا يوجد فرق، whereIn تُستخدم لإنشاء الإستعلام الذي نريده و get هي التي تقوم بتطبيق الإستعلام و إرجاع النتائج، بعكس find التي تقوم بالإثنين معاً، أحياناً قد لا نريد جلب السجلات بل نريد حذفها مثلاً او إجراء عملية أخرى و في هذه الحالة لن تُساعدنا find، يُمكن إستخدامها لكن سنقوم في هذه الحالة بإجراء إستعلامات زائدة لا داعي لها. فإذا كنا نريد الحذف لماذا نجلب البيانات ما دُمنا نستطيع حذفها مُباشرة: Model::whereIn('id', [1, 2])->delete();
    1 نقطة
  20. لجلب سجلات مُحددة عن طريق id النموذج مثلاً 1، 4، و 9 نقوم بإستعمال التابع find على الmodel و تمرير مصفوفة تضم المُعرفات التي نريد جلب سجلاتها: Model::find([1, 4, 9]); أي أننا إن أردنا جلب المُستخدم الأول و الثاني يُمكننا إستخدام: User::find([1, 2]); أما إن كنا نريد جلب سجلين عشوائيين يُمكن إستخدام هذه الطريق: Model::inRandomOrder()->limit(2)->get(); الفرق بين first و get أن first يجلب أول سجل يُطابق الإستعلام، أما get تجلب كل السجلات التي تُطابق الإستعلام على شكل collection، مجموعة سجلات
    1 نقطة
  21. هل كتابة الكود هذه صحيحه لكي اجلب السجلات من اخر الجدول الى اولها User::orderByDesc('title')->first(); اسفه اقصد التابع orderAsce () بدل من orderDesc()
    1 نقطة
  22. نعم هي بداخل class بالفعل اذا اردت ان اعرض من اخر السجلات الى اولها فكيف؟
    1 نقطة
  23. ممتاز جدا يمكنك التحقق أكثر عندما تطبعي البيانات في ملف view.
    1 نقطة
  24. namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Slide; use App\About; public function homepage(){ $slides = Slide::all(); $about = About::whereIn('id', [1,2])->get(); return view ('front.homepage', compact('slides','about')); } هل هذا الكود صحيح
    1 نقطة
  25. first تستخدم لجلب صف واحد ( سجل واحد ) من الجدول داخل قاعدة البيانات. $user = User::where('id', 1)->first(); ويتم جلب هذا الاستعلام داخل ملف view فمثلاً <p>{{ $user->name }}</p> أما get تستخدم لجلب عدة سجلات على شكل مصفوفة كما في المثال التالي $posts = Post::where('user_id', 1)->get(); ويتم جلب هذا الاستعلام داخل ملف view فمثلاً <table class="table table-bordered table-hover"> <thead> <tr> <th>ID</th> <th>Phone</th> <th>ORDER</th> <th>DATE</th> </tr> </thead> <tbody> @foreach($posts as $post) <tr> <td>{{ $post->id ?? '' }}</td> <td>{{ $post->title ?? '' }}</td> <td>{{ $post->desc ?? '' }}</td> <td>{{ $post->created_at ?? '' }}</td> </tr> @endforeach </tbody> </table> ويمكن استخدام أي دالة loop مثل while , for, foreach لجلب عناصر المصفوفة العائدة من الاستعلام
    1 نقطة
  26. يمكن إستخدام التابع whereIn والذي يقبل اسم عمود ومصفوفة من القيم $users = User::whereIn('id', [6, 7, 9])->get(); في الكود أعلاه سيتم جلب السجلات التي تحمل معرف 6 و 7 و 9 فقط. هنا مثال آخر لجلب كل السجلات الخاصة بالمستخدمين الذين لديهم عمر أكبر من 18 ووضع حد لعدد السجلات التي يتم جلبها وهو 100 سجل فقط $users = User::where('age', '>=', 18)->limit(100)->get();
    1 نقطة
  27. ولكن التابع limit سيجلب لي او سجلين يراهم اما اذا اردي سجلين مثلا السادس والسابع فماذا استخدم
    1 نقطة
  28. السلام عليكم أنا جديد في البرمجة كائنية الوجه وواجهتني مشكلة جعل المتغير $conn متغير global داخل الكلاس حينما أريد جعل المتغير global داخل function أقوم بكتابة الكود التالي global $conn; فعندما كتبته داخل class بدل من function واجهتني مشكلة ذات خطأ: Parse error: syntax error, unexpected token "global", expecting "function" or "const" in C:\xampp\htdocs\private\teachers.php on line 10 فما الحل؟ الكود المستخدم
    1 نقطة
  29. مرحباً صالح : مستقل لا يدعم السحب إلا عن طريق paypal يمكنك أن تتواصل مع مركز المساعدة وفتح تذكرة أما عن اقتراحي الشخصي من الممكن أن يستلم الحوالة أحد من اقاربك أو أصدقائك الموثوقين الموجودين خارج سوريا ويرسل لك الأموال عن طريق حوالة بنكية.
    1 نقطة
  30. السلام عليكم, هل هناك دورات مختصة وشاملة ل WordPress؟
    1 نقطة
  31. ليست هناك دورة كاملة ومختصة بال wordpress ولكن المسار الموجود في دورة تطوير تطبيقات الويب بإستخدام لغة php جيد جداً وسيعطيك الأساسيات التي تحتاجها حيث لن تحتاج إلى دورة أخرى في ال WordPress إنما ما تحتاج إليه بعد تعلم ذلك هو التطبيق أكثر وتجربة الإضافات المشهورة والتعديل علي القوالب المختلفة أي بمعنى الممارسة وبناء المشاريع
    1 نقطة
  32. تغطي شهادة Linux+ المهام الشائعة في التوزيعات الرئيسية لنظام linux، بما في ذلك سطر الأوامر Linux Command Line والصيانة الأساسية وتثبيت محطات العمل وتكوينها وتكوين الشبكات أيضاً. وسأقوم بكتابة أبرز المتطلبات التي تغطيها الشهادة: تثبيت وتكوين نظام التشغيل Linux تنفيذ العمليات الأساسية على سطر الأوامر command line operations إنشاء وإدارة وتهيئة المستخدمين والمجموعات ضمن النظام. إدارة نظام الملفات والتنقل بين الملفات وإجراء العمليات الأساسية عليها بما فيها تعديل محتويات الملفات النصية. إنشاء الملفات وتحريرها وتحديد موقعها والعمليات الأساسية عليها (نسخ،نقل،حذف،...) ونسخها احتياطاً واستعادتها. تكوين الطابعات ووظائف الطباعة والتعامل معها عن بعد. معرفة كيفية استخدام الأوامر الرئيسية في SQL والبرامج النصية لمعالجة البيانات وكيفية الولوج إليها. فهم بروتوكولات الشبكات الأساسية والتكوينات لها. أداء مهام الأمان مثل إعطاء وتغيير الصلاحيات والتحكم بها وتغيير كلمات المرور وتشفير البيانات. ويكون فحص الشهادة مقسّم كالتالي حسب المحاور: Hardware and System Configuration 21% Systems Operation and Maintenance 26% Security 19% Linux Troubleshooting and Diagnostics 20% Automation and Scripting 14% كما يمكنك الاطلاع على أسئلة سنوات سابقة لأخذ فكرة عن نوعية الأسئلة وتوزيعها والتدرّب عليها.
    1 نقطة
  33. اهلا بك مرحبا سؤالك مهم لكي تكون نجم في عالم التسويق الالكتروني هناك بعض المهارات التى يجب عليك ان تتقنها واهمها دراسة كورس في علم النفس الرقمي ، التحليل الالكتروني والمحتوى. البداية هي الاساس والبداية هي المحفز الاكبر والدافع الاعظم في اي شئ تم انجازة على هذه الكون . ومن هنا يواجهة الكثير من الشباب والشبات مشكلة عدم وجود بوصلة تحدد المسار الذى يمكن ان يتم المضى فيه لكي يصلون الى هدفهم . وعلى هذا الاساس يسالني الكثير من الاخوة والاخوات الكثير من الاسئلة منها: – كيف ابدا التسويق الالكتروني ؟ – ماهو مفهوم التسويق الالكتروني؟ – كيف اطور مهارتي في التسويق الالكتروني ؟ – ماهي اهم كورسات التسويق الالكتروني المعتمدة ؟ سوف تجد اجابة على هذه الاسئلة عن طريق الدورات المجانية التالية والتى ركزت في مجملها على مساعدتك في رفع قدراتك في مجال التسويق الرقمي بالاضافة الى انها تعتبر اللبنه الاولي في طريقك لتعلم مبادئ التسويق عن طريق الانترنت او بالانجليزيةbasics of digital marketing . أساسيات التسويق الألكتروني من google تعلم اساسيات التسويق الرقمي مع مشروع حي
    1 نقطة
×
×
  • أضف...