1. Chokri.Z

    Chokri.Z مشرف موقع أكتب كود

    سيكو هذا الموضوع إن شاء الله، أساسا خاص بأكواد البرمجة الخاصة بـمشروع : إنشاء موقع بالإعتماد على إطار العمل الشهير بوتستراب
    ليس هذا فقط، بل يمكن تعديل الأكواد و إدراجها على حسب إحتياجاتك في مشاريعك ككل.
    يمكن كذلك لمن يريد المشاركة، أن يعدلها (الأكواد) إلى الأفضل إن أمكن ذلك. و يدرج ما قام بالتعديل عليه هنا في هذا الموضوع لتعم الفائدة.
    هناك أكثر من طريقة للبرمجة كما هو معلوم.

    لمن ليس له دراية ببرمجة المواقع، أقترح عليه زيارة هذا المنتدى الذي يعج بمواضيع ستكون مفيدة بإذن الله.
    شخصيا، أعتبره ممتاز

    يــتــبــع
     
    آخر تعديل: ‏2/6/2022
  2. Chokri.Z

    Chokri.Z مشرف موقع أكتب كود

    إنشاء ملف "autoload.php"

    سيكون الملف، هو المسؤول عن تحميل جميع الفئات التي سننشأها إن شاء الله، تلقائيا.
    يعني هو ملف تحميل تلقائي كما يدل اسمه.
    الفئات (classes)، ستكون مسبوقة باسم المساحة (namespace) itabcode\classes
    لهذا، الملف سيكون مسؤول على استدعاء كل فئة مسبوقة باسم المساحة المذكور فقط.

    لقد تم بالفعل إنشاء الملف المذكور في وقت سابق هنا ، و تم إدراجه على المسار "C:/xampp/htdocs/itabcode/vendor"
    كود PHP:
    <?php

        
    /*
        دالة التحميل التلقائي ستشمل الفئات المسبوقة باسم المساحة
        itabcode\classes
        */
        
    spl_autoload_register(function ($class) {
            
    // بادئة مساحة الاسم
            
    $prefix 'itabcode\\classes';

            
    // التحقق مما إذا كانت فئة من المشروع
            
    $len strlen($prefix);
            if (
    strncmp($prefix$class$len) !== 0)
                return; 
    // الفئة ليست من المشروع

            // الحصول على اسم فئة نسبي وإزالة اسم مساحة الاسم
            
    $className substr($class$len);

            
    // مجلد الفئات الأساسية
            
    $baseDir dirname(__DIR__) . '/classes/';
            
    //  parent  بما في ذلك
            
    $file $baseDir str_replace('\\'DIRECTORY_SEPARATOR$className) . '.php';

            
    // إذا كان الملف موجودًا نقوم باستدعائه
            
    if (file_exists($file)) {
                require 
    $file;
            }
        });
    ?>
    يــتــبــع
     
  3. Chokri.Z

    Chokri.Z مشرف موقع أكتب كود

    إنشاء ملفات الفئات "Database.php" و "Validation.php"
    و ملف "register_login_submit.php" الذي سيكون المسؤول عن عمليات التسجيل و تسجيل الدخول.


    سنعتبر إنشاء المجلدين "vendor" و "classes" قد تم على المسار التالي:
    "C:/xampp/htdocs/itabcode/classes"

    سنقوم بإنشاء ملفات الفئات المذكورة، حيث يتم إدراجها كما يلي:
    "C:/xampp/htdocs/itabcode/classes/Database.php"
    "C:/xampp/htdocs/itabcode/classes/Vٍalidation.php"

    ثم نقوم بإنشاء الملف "register_login_submit.php" و نقوم بإدراجه في المجلد الرئيسي للمشروع،
    على المسار "C:/xampp/htdocs/itabcode/register_login_submit.php"

    عملية إرسال و استقبال البيانات ستتم عن طريق الـ "Ajax" داخل الملف "C:/xampp/htdocs/itabcode/js/main.js"
    الذي تم إدراجه أسفل الصفحات
    "register.php" و "login.php" مثل ما هو مبين هنا


    أما عملية التحقق من الخانات الفارغة و غيرها، تتم داخل الملف "C:/xampp/htdocs/itabcode/register_login_submit.php"

    ملف "register_login_submit.php"
    كود PHP:
    <?php
    session_start
    ();

    require_once 
    realpath(__DIR__ '/vendor/autoload.php');

    use 
    itabcode\classes\Validation;
    use 
    itabcode\classes\Database;

    if (
    strtoupper($_SERVER['REQUEST_METHOD']) === 'POST') {

        
    $user null;
        
    $db   null;
        
    $json = [];

        
    $validation = new Validation();
        
    $reg        $validation->post('reg_btn');

        if (
    $reg === 'reg') {
     
            
    $isValid = function () use ($validation): bool {

                
    $validation->requireField('f_name''الإسم الأول مطلوب')
                        ->
    requireField('l_name''إسم العائلة مطلوب')
                        ->
    requireField('r_email',   'البريد الالكتروني مطلوب');
                
    $validation->validateEmail('r_email','الرجاء إدخال عنوان بريد إلكتروني صالح')
                        ->
    isUniqueEmail('r_email''قم بإدخال بريد إلكتروني مختلف');
                
    $validation->requireField('uname',   'إسم المستخدم مطلوب')
                            ->
    isUniqueUname('uname''قم بإدخال إسم مستخدم آخر');
                
    $validation->requireField('pwd',   'كلمة المرور مطلوبة')
                        ->
    requireField('cpass''أعد كلمة المرور في خانة الإعادة')
                        ->
    requireField('therms''يجب أن توافق على الشروط والأحكام الخاصة بنا');


                return 
    $validation->passes();
            };

            if (
    $isValid()) {

                
    $db    = new Database();

                
    $birth $validation->post('birthday');
                
    $gender $validation->post('gender');

                if (
    $birth$db->data('birthday'$birth);

                if (
    $birth$db->data('gender'$gender);

                
    $db->data('f_name'$validation->post('f_name'))
                    ->
    data('l_name'$validation->post('l_name'))
                    ->
    data('email'$validation->post('r_email'))
                    ->
    data('uname'$validation->post('uname'))
                    ->
    data('password'password_hash($validation->post('pwd'), PASSWORD_DEFAULT))
                    ->
    data('created'time())
                    ->
    insert('users');

                
    $json['success'] = 'تم إنشاء حسابك بنجاح';
                
    $json['redirectTo'] = 'index.php';
            } else {
                
    $json['errors'] = $validation->flattenMessages();
            }
        } else {

            
    $isValid = function () use ($validation): bool {
                
    $validation->requireField('l_email''البريد الإلكتروني مطلوب')
                            ->
    validateEmail('l_email''الرجاء إدخال عنوان بريد إلكتروني صالح')
                            ->
    requireField('pass''كلمة المرور مطلوبة');

                return 
    $validation->passes();
            };

            if (
    $isValid()) {
             
                
    $email    $validation->post('l_email');
                
    $password $validation->post('pass');

                
    $db = new Database();

                
    $user $db->where('email=?'$email)->fetch('users');

                if (!
    $user or !(password_verify($password$user->password))) {

                    
    $_SESSION['uname'] = '';

                    
    $json['errors'] = 'بيانات تسجيل الدخول غير متطابقة';
                } else {

                    
    $_SESSION['uname'] = $user->uname;

                    
    $json['success'] =  'أهلا بك ' $_SESSION['uname'];
                    
    $json['redirectTo'] = 'index.php';
                }
             
            }else {
                
    $json['errors'] = $validation->flattenMessages();
            }
         
        }

        echo 
    json_encode($json);
    }
    ملف "Database.php"
    كود PHP:
    <?php


    declare(strict_types=1);

    namespace 
    itabcode\classes;

    use 
    PDO;
    use 
    PDOException;
    use 
    PDOStatement;

    class 
    Database
    {

        private static 
    $connection;
        private 
    $selects = [], $wheres = [], $table$data = [], $bindings = [];

        function 
    __construct()
        {
            if (!
    $this->isConnected()) {
                
    $this->connect();
            }
        }

        private function 
    isConnected(): bool
        
    {
            return static::
    $connection instanceof PDO;
        }

        private function 
    connect(): void
        
    {
            
    $options = [
                
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
                
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ,
                
    PDO::ATTR_EMULATE_PREPARES   => false,
                
    PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'
            
    ];

            try {
                static::
    $connection = new PDO('mysql:host=localhost;dbname=itabcode''root'''$options);
            } catch (
    PDOException $exception) {
                exit(
    'فشل الاتصال بقاعدة البيانات<br>' $exception->getMessage());
            }
        }

        function 
    select(...$selects): Database
        
    {
            
    //PHP >=5.6 (...)  يمكنك استخدام عامل التشغيل

            //وإلا ، استخدم السطر التالي للحصول على كافة الوسائط التي تم تمريرها
            //$selects = func_get_args();

            
    $this->selects array_merge($this->selects$selects);

            return 
    $this;
        }

        private function 
    fetchStatement(): string
        
    {

            
    $sql 'SELECT ';

            if (
    $this->selects) {
                
    $sql .= implode(','$this->selects);
            } else {
                
    $sql .= '*';
            }

            
    $sql .= ' FROM ' $this->table ' ';

            if (
    $this->wheres) {
                
    $sql .= ' WHERE ' implode(' '$this->wheres) . ' ';
            }

            return 
    $sql;
        }

        function 
    table($table): Database
        
    {
            
    $this->table $table;

            return 
    $this;
        }

        function 
    from($table): Database
        
    {
            return 
    $this->table($table);
        }

        function 
    fetch($table null): mixed
        
    {
            if (
    $table) {
                
    $this->table($table);
            }

            
    $sql $this->fetchStatement();

            
    $result $this->query($sql$this->bindings)->fetch();

            return 
    $result;
        }

        function 
    fetchAll($table null): mixed
        
    {
            if (
    $table) {
                
    $this->table($table);
            }

            
    $sql $this->fetchStatement();

            
    $query $this->query($sql$this->bindings);

            
    $results $query->fetchAll();

            return 
    $results;
        }

        function 
    query(): PDOStatement
        
    {
            
    $bindings func_get_args();

            
    $sql array_shift($bindings);

            if (
    count($bindings) == && is_array($bindings[0])) {
                
    $bindings $bindings[0];
            }

            try {
                
    $query = static::$connection->prepare($sql);

                foreach (
    $bindings as $key => $value) {
                    
    $query->bindValue($key 1$value);
                }

                
    $query->execute();

                return 
    $query;
            } catch (
    PDOException $e) {

                echo 
    $sql;
                die(
    $e->getMessage());
            }
        }

        function 
    addToBindings($value): void
        
    {

            if (
    is_array($value)) {
                
    $this->bindings array_merge($this->bindingsarray_values($value));
            } else {
                
    $this->bindings[] = $value;
            }
        }

        private function 
    setFields(): string
        
    {
            
    $sql '';

            foreach (
    array_keys($this->data) as $key) {
                
    $sql .= '`' $key '` = ? , ';
            }

            
    $sql rtrim($sql', ');

            return 
    $sql;
        }

        function 
    data($key$value null): Database
        
    {
            if (
    is_array($key)) {
                
    $this->data array_merge($this->data$key);

                
    $this->addToBindings($key);
            } else {
                
    $this->data[$key] = $value;

                
    $this->addToBindings($value);
            }

            return 
    $this;
        }

        function 
    insert($table null): Database
        
    {
            if (
    $table) {
                
    $this->table($table);
            }

            
    $sql 'INSERT INTO ' $this->table ' SET ';

            
    $sql .= $this->setFields();

            
    $this->query($sql$this->bindings);

            return 
    $this;
        }

        function 
    where(...$bindings): Database
        
    {
            
    //$bindings = func_get_args();

            
    $sql array_shift($bindings);

            
    $this->addToBindings($bindings);

            
    $this->wheres[] = $sql;

            return 
    $this;
        }

        function 
    __destruct()
        {
            static::
    $connection null;
        }
    }


    أخيرا و ليس آخر، ملف تسجيل الخروج "logout.php"
    كود PHP:
    <?php
    session_start
    ();
    session_destroy();
    if (!
    headers_sent()) header('Location: index.php');
    ?>


    كودات البرمجة تمت لتكون متوافقة مع آخر إصدار للـ ¨PHP"
     
    آخر تعديل: ‏3/6/2022
  4. Chokri.Z

    Chokri.Z مشرف موقع أكتب كود

    التعديل على الملفات

    سنقوم اليوم بالتعديل على جميع الملفات الـ PHP المدرجة، بكيفية تكون داعمة لكل الحقول الموجودة داخل اسنمارة التسجيل و تسجيل الدخول.
    أولا، نقوم بالتعديل على الملف "itabcode_sql" و تحديدا على الأعمدة "uname" و "birth" .
    العمود "birth" سيكون ياسم "birthday" و سيكون من نوع "varchar" . والعمود uname سيكون هو أيظا unique مثل العمود "email" .

    نص الإستعلام كامل لإنشاء الجدول "users"
    كود PHP:
    CREATE TABLE `users` (
      `
    idint(10UNSIGNED NOT NULL,
      `
    f_namevarchar(50NOT NULL,
      `
    l_namevarchar(50NOT NULL,
      `
    emailvarchar(155NOT NULL,
      `
    unamevarchar(50NOT NULL,
      `
    passwordvarchar(255NOT NULL,
      `
    birthdayvarchar(20) DEFAULT NULL,
      `
    gendertinytext DEFAULT NULL,
      `
    avatarvarchar(155) DEFAULT NULL,
      `
    createdint(11NOT NULL
    ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;


    ALTER TABLE `users`
      
    ADD PRIMARY KEY (`id`),
      
    ADD UNIQUE KEY `email` (`email`),
      
    ADD UNIQUE KEY `uname` (`uname`);
    بعد إتمام هذه العملية، ننتقل إلى اتعديل على الملفات

    ملف التحميل التلقائي: "C:/xampp/htdocs/itabcode/vendor/autoload.php"
    سنضيف لهذا الملف تفقد و مراقبة اسم المساحة "namespace" بطريقة لا تسمح باستعمال أسماء مساحة متعددة.
    كود PHP:
    if (strpos($class$prefix) !== 0) {
      throw new 
    Exception(
        
    'أداة التحميل التلقائي لتسجيلات متعددة لمساحات الأسماء غير ممكنة'
      
    );
    }
    الملف بعد التعديل:​
    كود PHP:
    /*
        دالة التحميل التلقائي ستشمل الفئات المسبوقة باسم المساحة
        itabcode\classes
        */
        
    spl_autoload_register(function ($class) {
            
            
    // بادئة مساحة الاسم
            
    $prefix 'itabcode\\classes';
            
            if (
    strpos($class$prefix) !== 0) {
                 throw new 
    Exception(
                    
    'أداة التحميل التلقائي لتسجيلات متعددة لمساحات الأسماء غير ممكنة'
                
    );
            }

            
    // التحقق مما إذا كانت فئة من المشروع
            
    $len strlen($prefix);
            if (
    strncmp($prefix$class$len) !== 0)
                return; 
    // الفئة ليست من المشروع

            // الحصول على اسم فئة نسبي وإزالة اسم مساحة الاسم
            
    $className substr($class$len);

            
    // مجلد الفئات الأساسية
            
    $baseDir dirname(__DIR__) . '/classes/';
            
    // parent y compris
            
    $file $baseDir str_replace('\\'DIRECTORY_SEPARATOR$className) . '.php';

            
    // إذا كان الملف موجودًا نقوم باستدعائه
            
    if (file_exists($file)) {
                require 
    $file;
            }
        });
    ملف "C:/xampp/htdocs/itabcode/classes/Database.php" بعد التعديل​
    كود PHP:
    <?php

    declare(strict_types=1);

    namespace 
    itabcode\classes;

    use 
    PDO;
    use 
    PDOException;
    use 
    PDOStatement;

    class 
    Database
    {

        private static 
    $connection;
        private 
    $selects = [], $wheres = [], $table$data = [], $bindings = [];

        
    /**
         * باني الفئة Constructor
         */
        
    function __construct()
        {
            if (!
    $this->isConnected()) {
                
    $this->connect();
            }
        }

        
    /**
         * تحقق مما إذا كان الاتصال نشطًا
         *
         * @return boolean
         */
        
    private function isConnected(): bool
        
    {
            return static::
    $connection instanceof PDO;
        }

        
    /**
         * تحقيق الإتصال بقاعدة البيانات
         *
         * @return void
         */
        
    private function connect(): void
        
    {
            
    $options = [
                
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
                
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ,
                
    PDO::ATTR_EMULATE_PREPARES   => false,
                
    PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'
            
    ];

            try {
                static::
    $connection = new PDO('mysql:host=localhost;dbname=itabcode''root'''$options);
            } catch (
    PDOException $exception) {
                exit(
    'فشل الاتصال بقاعدة البيانات<br>' $exception->getMessage());
            }
        }
        
    /**
         * تعيين بند التحديد
         *
         * @param mixed ...$selects
         * @return Database
         */
        
    function select(mixed ...$selects): Database
        
    {
            
    //PHP >=5.6 (...)  يمكنك استخدام عامل التشغيل

            //وإلا ، استخدم السطر التالي للحصول على كافة الوسائط التي تم تمريرها
            //$selects = func_get_args();

            
    $this->selects array_merge($this->selects$selects);

            return 
    $this;
        }

        
    /**
         * إعداد بيان التحديد
         *
         * @return string
         */
        
    private function fetchStatement(): string
        
    {

            
    $sql 'SELECT ';

            if (
    $this->selects) {
                
    $sql .= implode(','$this->selects);
            } else {
                
    $sql .= '*';
            }

            
    $sql .= ' FROM ' $this->table ' ';

            if (
    $this->wheres) {
                
    $sql .= ' WHERE ' implode(' '$this->wheres) . ' ';
            }

            return 
    $sql;
        }

        
    /**
         * قم بتعيين اسم الجدول
         *
         * @param string $table
         * @return Database
         */
        
    function table(string $table): Database
        
    {
            
    $this->table $table;

            return 
    $this;
        }

        
    /**
         * قم بتعيين اسم الجدول
         *
         * @param string $table
         * @return Database
         */
        
    function from(string $table): Database
        
    {
            return 
    $this->table($table);
        }

        
    /**
         * جدول الجلب. سيؤدي هذا إلى إرجاع سجل واحد فقط
         *
         * @param mixed $table
         * @return mixed
         */
        
    function fetch(mixed $table null): mixed
        
    {
            if (
    $table) {
                
    $this->table($table);
            }

            
    $sql $this->fetchStatement();

            
    $result $this->query($sql$this->bindings)->fetch();

            return 
    $result;
        }

        
    /**
         * إحضار كل السجلات من الجدول
         *
         * @param mixed $table
         * @return mixed
         */
        
    function fetchAll(mixed $table null): mixed
        
    {
            if (
    $table) {
                
    $this->table($table);
            }

            
    $sql $this->fetchStatement();

            
    $query $this->query($sql$this->bindings);

            
    $results $query->fetchAll();

            return 
    $results;
        }

        
    /**
         * SQL تنفيذ البيان المحدد
         *
         * @return PDOStatement
         */
        
    function query(): PDOStatement
        
    {
            
    $bindings func_get_args();

            
    $sql array_shift($bindings);

            if (
    count($bindings) == && is_array($bindings[0])) {
                
    $bindings $bindings[0];
            }

            try {
                
    $query = static::$connection->prepare($sql);

                foreach (
    $bindings as $key => $value) {
                    
    $query->bindValue($key 1$value);
                }

                
    $query->execute();

                return 
    $query;
            } catch (
    PDOException $e) {

                echo 
    $sql;
                die(
    $e->getMessage());
            }
        }

        
    /**
         * أضف القيمة المعطاة إلى الارتباطات
         *
         * @param mixed $value
         * @return void
         */
        
    function addToBindings(mixed $value): void
        
    {

            if (
    is_array($value)) {
                
    $this->bindings array_merge($this->bindingsarray_values($value));
            } else {
                
    $this->bindings[] = $value;
            }
        }

        
    /**
         * قم بتعيين الحقول للإدراج والتحديث
         *
         * @return string
         */
        
    private function setFields(): string
        
    {
            
    $sql '';

            foreach (
    array_keys($this->data) as $key) {
                
    $sql .= '`' $key '` = ? , ';
            }

            
    $sql rtrim($sql', ');

            return 
    $sql;
        }

        
    /**
         * قم بتعيين البيانات التي سيتم تخزينها في جدول قاعدة البيانات
         *
         * @param mixed $key
         * @param mixed $value
         * @return Database
         */
        
    function data(mixed $keymixed $value null): Database
        
    {
            if (
    is_array($key)) {
                
    $this->data array_merge($this->data$key);

                
    $this->addToBindings($key);
            } else {
                
    $this->data[$key] = $value;

                
    $this->addToBindings($value);
            }

            return 
    $this;
        }

        
    /**
         * أدخل البيانات في قاعدة البيانات
         *
         * @param mixed $table
         * @return Database
         */
        
    function insert(mixed $table null): Database
        
    {
            if (
    $table) {
                
    $this->table($table);
            }

            
    $sql 'INSERT INTO ' $this->table ' SET ';

            
    $sql .= $this->setFields();

            
    $this->query($sql$this->bindings);

            return 
    $this;
        }

        
    /**
         *  "Where" إضافة العبارة الجديدة
         *
         * @param mixed ...$bindings
         * @return Database
         */
        
    function where(mixed ...$bindings): Database
        
    {
            
    //$bindings = func_get_args();

            
    $sql array_shift($bindings);

            
    $this->addToBindings($bindings);

            
    $this->wheres[] = $sql;

            return 
    $this;
        }

        function 
    __destruct()
        {
            static::
    $connection null;
        }
    }
    ملف" C:/xampp/htdocs/itabcode/register_login_submit.php" بعد النعديل​
    كود PHP:
    <?php
    session_start
    ();

    require_once 
    realpath(__DIR__ '/vendor/autoload.php');

    use 
    itabcode\classes\Validation;
    use 
    itabcode\classes\Database;

    if (
    strtoupper($_SERVER['REQUEST_METHOD']) === 'POST') {

        
    $user null;
        
    $db   null;
        
    $json = [];

        
    $validation  = new Validation();
        
    $reg         $validation->post('reg_btn');

        if (
    $reg === 'reg') { // التسجيل

            
    $isValid = function () use ($validation): bool {

                
    $validation->requireField('f_name''الإسم الأول مطلوب')
                    ->
    requireField('l_name''إسم العائلة مطلوب')
                    ->
    requireField('r_email',   'البريد الالكتروني مطلوب');
                
    $validation->validateEmail('r_email''الرجاء إدخال عنوان بريد إلكتروني صالح')
                    ->
    isUniqueEmail('r_email''قم بإدخال بريد إلكتروني مختلف');
                
    $validation->requireField('uname',   'إسم المستخدم مطلوب')
                    ->
    isUniqueUname('uname''قم بإدخال إسم مستخدم آخر');
                
    $validation->requireField('pwd',   'كلمة المرور مطلوبة')
                    ->
    requireField('cpass''أعد كلمة المرور في خانة الإعادة')
                    ->
    requireField('therms''يجب أن توافق على الشروط والأحكام الخاصة بنا');

                return 
    $validation->passes();
            };

            if (
    $isValid()) { // لا اخطاء

                
    $birth  $validation->post('birthday');
                
    $gender $validation->post('gender');
                
    $avatar $validation->emptyImage('r_avatar');

                
    $db     = new Database();

                if (
    $birth$db->data('birthday'$birth);
                if (
    $gender$db->data('gender'$gender);
                if (!
    is_null($avatar)) {
                    
    $img_name $validation->saveImage('r_avatar'true);
                    if (!
    is_null($img_name)) {
                        
    $db->data('avatar'$img_name);
                    }
                }

                
    $db->data('f_name'$validation->post('f_name'))
                    ->
    data('l_name'$validation->post('l_name'))
                    ->
    data('email'$validation->post('r_email'))
                    ->
    data('uname'$validation->post('uname'))
                    ->
    data('password'password_hash($validation->post('pwd'), PASSWORD_DEFAULT))
                    ->
    data('created'time())
                    ->
    insert('users');

                
    $json['success']    = 'تم إنشاء حسابك بنجاح';
                
    $json['redirectTo'] = 'index.php';
            } else {
                
    $json['errors'] = $validation->flattenMessages();
            }
        } else { 
    // تسجيل الدخول

            
    $isValid = function () use ($validation): bool {
                
    $validation->requireField('l_email''البريد الإلكتروني مطلوب')
                    ->
    validateEmail('l_email''الرجاء إدخال عنوان بريد إلكتروني صالح')
                    ->
    requireField('pass''كلمة المرور مطلوبة');

                return 
    $validation->passes();
            };

            if (
    $isValid()) { // لا اخطاء

                
    $email    $validation->post('l_email');
                
    $password $validation->post('pass');

                
    $db = new Database();

                
    $user $db->where('email=?'$email)->fetch('users');

                if (!
    $user or !(password_verify($password$user->password))) {

                    
    $_SESSION['uname']  = '';
                    
    $_SESSION['avatar'] = '';

                    
    $json['errors'] = 'بيانات تسجيل الدخول غير متطابقة';
                } else {

                    
    $_SESSION['uname']  = $user->uname;
                    
    $_SESSION['avatar'] = $user->avatar;

                    
    $json['success']    =  'أهلا بك ' $_SESSION['uname'];
                    
    $json['redirectTo'] = 'index.php';
                }
            } else {
                
    $_SESSION['uname'] = '';
                
    $_SESSION['avatar'] = '';
                
    $json['errors'] = $validation->flattenMessages();
            }
        }

        echo 
    json_encode($json);
    }
    ملف "C:/xampp/htdocs/itabcode/classes/Validation.php" بعد التعديل​
    كود PHP:
    <?php

    declare(strict_types=1);

    namespace 
    itabcode\classes;

    class 
    Validation
    {

        private ?array 
    $errors = [];
        private 
    $error;


        
    /**
         * تمكن من الحصول على قيمة للمفتاح الممرر كإعدادات
         *
         * @param string $key
         * @param mixed $default
         * @return string|null
         */
        
    function post(string $keymixed $default null): mixed
        
    {
            
    $value = isset($_POST[$key]) ? $_POST[$key] : $default;
            
            if(!
    is_null($value)) {
              if (
    is_array($value)) {
                  
    // أزل أي مسافة بيضاء إذا كانت هناك قيمة
                  
    $value array_filter($value);
              } elseif (
    is_string($value)) {
                  
    $value addslashes($value);
                  
    $value trim($value);
                  
    $value htmlentities($value);
              } else {
                  
    $value htmlentities($value);
              }
            }

            return 
    $value;
        }

        
    /**
         * السماح للحصول على امتداد الملف المرفوع
         *
         * @param string $str
         * @return string
         */
        
    function getExtension(string $str): string
        
    {
            
    $i strrpos($str".");

            if (!
    $i) {
                return 
    "";
            }

            
    $l strlen($str) - $i;

            
    $ext substr($str$i 1$l);

            return 
    $ext;
        }

        
    /**
         * يمكن التحقق مما إذا كان ملف الإدخال فارغًا
         *
         * @param mixed $key
         * @return mixed
         */
        
    function emptyImage(mixed $key): mixed
        
    {
            if (
    $_FILES[$key]['size'] == && $_FILES[$key]['name'] == '') {

                
    $this->addError('r_avatar''الصورة الرمزية مطلوبة');

                return 
    null;
            }

            return 
    $_FILES[$key];
        }

        
    /**
         * احفظ الصورة التي تم تحميلها
         *
         * @param mixed $key
         * @param string $uploaddir
         * @param boolean $res
         * @return mixed
         */
        
    function saveImage(mixed $keybool $res false): mixed
        
    {
            
    $valid_formats = [
                
    'jpg''jpeg''pjpeg''png''gif''jpeg''webp''x-webp',
            ];

            
    $image $this->emptyImage($key);

            if (
    is_null($image)) {
                return 
    null;
            }

            
    $this->error      $image['error'];

            if (
    $this->error != UPLOAD_ERR_OK) {
                return 
    null;
            }

            
    $old_image_name $image['name'];
            
    $size           $image['size'];

            if (
    strlen($old_image_name)) {
                
    $ext strtolower($this->getExtension($old_image_name));

                if (
                    
    strpos($image['type'], 'image/') === 0
                    
    and in_array($ext$valid_formats)
                ) {
                    if (
    $size < (1024 1024)) { // حجم الصورة 1 ميغا بايت كحد أقصى

                        
    $usename $this->post('uname');
                        
    $niew_image_name =  strtolower($usename) . '.' $ext;
                        
    $uploadedfile    $image['tmp_name'];

                        if (
    move_uploaded_file($uploadedfiledirname(__DIR__) . '/images/avatars/' $niew_image_name)) {
                            if (
    $res) {
                                
    $resize = new Image(\dirname(__DIR__) . '/images/avatars/' $niew_image_name);
                                
    $err_resize $resize->getErrors();
                                
    $err_resize = (array) $err_resize;

                                if (!empty(
    $err_resize)) {

                                    foreach (
    $err_resize as $key => $value) {
                                        
    $err_resize[$key] = $value;
                                        
    $this->addError('r_avatar'$value);
                                    }
                                } else {
                                    if (
    $resize->resizeTo(100100)) {
                                        
    $resize->saveImg(dirname(__DIR__) . '/images/avatars/' $niew_image_name);
                                    }
                                }

                                unset(
    $resize);
                            }

                            return 
    $niew_image_name;
                        } else {
                            
    $this->addError('r_avatar''تعذر تنزيل الصورة');
                        }
                    } else {
                        
    $this->addError('r_avatar''حجم ملف الصورة بحد أقصى 1 ميجا بايت');
                    }
                } else {
                    
    $this->addError('r_avatar''تنسيق غير صالح');
                }
            } else {
                
    $this->addError('r_avatar''لم تقم بإدخال ملف');
            }

            return 
    null;
        }

        
    /**
         * تحقق مما إذا كانت حاوية الخطأ تحتوي على الاسم المحدد
         *
         * @param string $inputName
         * @return boolean
         */
        
    private function hasErrors(string $inputName): bool
        
    {
            return 
    array_key_exists($inputName$this->errors)? true:false;
        }

        
    /**
         * أضف اسم خطأ محدد إلى حاوية الخطأ
         *
         * @param string $inputName
         * @param string $errMsg
         * @return void
         */
        
    private function addError(string $inputNamestring $errMsg): void
        
    {
            
    $this->errors[$inputName] = $errMsg '  ️';
        }

        
    /**
         * أضف التزامًا إلى الحقل المحدد
         *
         * @param mixed $inputName
         * @param mixed $custErrMsg
         * @return Validation
         */
        
    function requireField(mixed $inputNamemixed $custErrMsg null): Validation
        
    {
            if (
    $this->hasErrors($inputName)) {
                return 
    $this;
            }

            
    $inputValue $this->post($inputName);

            if (
    $inputValue === '' || is_null($inputValue)) {
                
    $msg $custErrMsg ?: sprintf('%s مطلوب'ucfirst($inputName));
                
    $this->addError($inputName$msg);
            }

            return 
    $this;
        }
        
    /**
         * تحقق مما إذا كان البريد الإلكتروني المعطى بريدًا إلكترونيًا صالحًا
         *
         * @param string $inputName
         * @param mixed $customErrorMessage
         * @return Validation
         */
        
    function validateEmail(string $inputNamemixed $customErrorMessage null): Validation
        
    {
            if (
    $this->hasErrors($inputName)) {
                return 
    $this;
            }

            
    $inputValue $this->post($inputName);

            if (!
    filter_var($inputValueFILTER_VALIDATE_EMAIL)) {
                
    $message $customErrorMessage ?: sprintf('%s ليس بريدًا إلكترونيًا صالحًا'ucfirst($inputName));
                
    $this->addError($inputName$message);
            }

            return 
    $this;
        }
        
    /**
         * تحقق مما إذا كان البريد الإلكتروني المحدد فريدًا في قاعدة البيانات
         *
         * @param string $inputName
         * @param mixed $customErrorMessage
         * @return boolean
         */
        
    function isUniqueEmail(string $inputNamemixed $customErrorMessage null)
        {

            if (
    $this->hasErrors($inputName)) {
                return 
    $this;
            }

            
    $inputValue $this->post($inputName);

            
    $db = new Database();

            
    $result $db->select('email')
                ->
    from('users')
                ->
    where('email= ?'$inputValue)
                ->
    fetch();

            if (
    $result) {
                
    $message $customErrorMessage ?: sprintf('%s  أدخل بريد آخر غير 'ucfirst($inputValue));
                
    $this->addError($inputName$message);
            }
        }
        
    /**
         *  النحقق من إذا كان اسم المستخدم فريد في قاعدة البيانات
         *
         * @param string $inputName
         * @param mixed $customErrorMessage
         * @return boolean
         */
        
    function isUniqueUname(string $inputNamemixed $customErrorMessage null)
        {

            if (
    $this->hasErrors($inputName)) {
                return 
    $this;
            }

            
    $inputValue $this->post($inputName);

            
    $db = new Database();

            
    $result $db->select('uname')
                ->
    from('users')
                ->
    where('uname= ?'$inputValue)
                ->
    fetch();

            if (
    $result) {
                
    $message $customErrorMessage ?: printf('%s قم بإدخال إسم مسنخدم غير 'ucfirst($inputValue));
                
    $this->addError($inputName$message);
            }
        }

        
    /**
         * تفكيك الأخطاء ز عرضها
         *
         * @return string
         */
        
    function flattenMessages(): string
        
    {
            return 
    implode('<br>'$this->errors);
        }

        
    /**
         * تحقق مما إذا كانت حاوية الخطأ فارغة
         *
         * @return boolean
         */
        
    function passes(): bool
        
    {
            return empty(
    $this->errors) ? true false;
        }
    }

    ملاحظة: الملف الأخير سيكون فيه شرط يتطلب فئة "class image" سينم إدراجها في و قت لاحق.

    يــتــبــع​
     
  5. Chokri.Z

    Chokri.Z مشرف موقع أكتب كود

    عفوا نسيت إدراج ملف "C:/xampp/htdocs/itabcode/js/main.js" الدي هو بدوره تم تعديله​
    كود PHP:
    $(function () {
        
    'use strict';
     
        
    // Array.isArray() إذا كان المنصفح لا يدعم الدالة، نقوم بإنشائها
        
    if (!Array.isArray) {
            Array.
    isArray = function(arg) {
              return 
    Object.prototype.toString.call(arg) === '[object Array]';
            };
        }
     
        
    // معرض الصور
        
    const gallery document.getElementById('lightgallery');
        if (
    gallerylightGallery(gallery);

        
    // خاص بمراقبة الصورة إطا ما نم الرفغ
        
    const img document.getElementById('avatar');
        if (
    imgimg.addEventListener('change'selectSingleFile);

        function 
    selectSingleFile(e) {
            var 
    file e.target.files// كائن "FileList"
            
    var file[0];
            var 
    output document.getElementById('output');
            
    // معالجة ملفات الصور فقط
            
    if (!f.type.match('image.*')) {
                
    output.classList.add('alert''alert-danger');
                
    output.innerHTML '';
                
    output.innerHTML '<p>يجب أن يكون الملف الذي تريد تحميله صورة صالحة</p>';

                return 
    false;
            } else {
                
    output.classList.remove('alert''alert-danger');
                $(
    '#form-results').removeClass().addClass('d-none');
            }

            var 
    reader = new FileReader();
            
    // الإغلاق لالتقاط معلومات الملف
            
    reader.onload = (function (file) {
                return function (
    e) {
                    
    // عرض الصورة المصغرة
                    
    var span document.createElement('span');
                    
    span.innerHTML = ['<img class="small_avatar" src="'e.target.result,
                        
    '" alt="'encodeURI(file.name), '" title="'encodeURI(file.name), '"/>'].join('');
                    
    output.innerHTML "";
                    
    output.insertBefore(spannull);
                };
            })(
    f);
            
    //"url" قراءة ملف الصورة كعنوان للبيانات
            
    reader.readAsDataURL(f);

            return 
    true;
        }
     
        
    /* تعطيل عمليات إرسال النموذج إذا كانت هناك حقول غير صالحة */
        // تحديد جميع النماذج التي نريد تطبيق أنماط تحقق مخصصة عليها
        
    var frms document.querySelectorAll('.needs-validation');
        if (
    typeof(frms) !== 'undefined') {
            
    //نقوم بإنشاء حلقة دوران و نمنع بعث البيانات
            
    Array.prototype.slice.call(frms)
              .forEach(function(
    frm) {
                
    frm.addEventListener('submit', function(event) {
                  if (!
    frm.checkValidity()) {
                    
    event.preventDefault();
                    
    event.stopPropagation();
                  }

                  
    frm.classList.add('was-validated');
                }, 
    false)
              });
        }

        
    // تغيير الأيقونة داخل خانة كلمة المرور عند الضفط عليها
        
    $('.toggle-password').on('click', function () {
            $(
    this).toggleClass('fa-lighte fa-eye-slash');
            const 
    input = $($(this).data('id'));
            if (
    input.attr('type') == 'password') {
                
    input.attr('type''text');
            } else {
                
    input.attr('type''password');
            }
        });

        
    // register/login forms
        
    $(document).on('click''.submit-btn', function (e) {
            
    e.preventDefault();
            var 
    btn = $(this),
                
    frm btn.parents('.form'),
                
    url frm.attr('action'),
                
    src_avatar frm.data('loader'),
                
    flag false,
                
    formResults frm.find('#form-results');

            if (
    flag === true) {
                return 
    false;
            }

            const 
    data = new FormData(frm[0]);
         
            $.
    ajax({
                
    urlurl,
                
    datadata,
                
    type'POST',
                
    dataType'json',
                
    beforeSend: function () {
                    
    flag true;
                    
    btn.attr('disabled'true);
                    
    formResults.removeClass().addClass('alert alert-info').html('<p class="text-center"><img src="' src_avatar '" alt="Loading..."></p>');
                },
                
    success: function (results) {
                    
    setTimeout(function () {
                        if (
    results.errors) {
                     
                            $(
    '.required').each(function(){
                                $(
    this).removeClass("has-error");
                                if($(
    this).val() == '')
                                {
                                    $(
    this).addClass("has-error");
                                }
                            });
                     
                            
    formResults.removeClass().addClass('alert alert-danger').html(results.errors);
                            
    btn.removeAttr('disabled');
                         
                            
    flag false;
                         
                        } else if (
    results.success) {
                            
    formResults.removeClass().addClass('alert alert-success').html(results.success);
                        }
                    }, 
    1000);
                    if (
    results.redirectTo) {
                        
    setTimeout(function () {
                            
    window.location.href results.redirectTo;
                        }, 
    4000);
                    }
                },
                
    cachefalse,
                
    processDatafalse,
                
    contentTypefalse,
            });
        });


        
    // إن وجد AOS plugin تفعيل الـ
        
    const allDiv document.querySelectorAll('div[data-aos]');
        if (
    typeof(allDiv) != 'undefined' && allDiv != null) {
            
    allDiv.forEach(div => {
               
    AOS.init({ mirrortrue });
            });
        }
     
        
    // (tooltip) تفعيل تلميح أداة التمهيد
        
    let btns_toggle document.querySelectorAll('[data-bs-toggle="tooltip"]');
        
    btns_toggle.forEach(function (btn) {
            if (
    btn) { // التحقق مما إذا كان العنصر موجودًا
                
    var tooltipBtn = new bootstrap.Tooltip(btn);

                
    btn.addEventListener('mouseleave', function () {
                    
    // إخفاء التلميح بشكل صريح ، لأنه بعد النقر عليه يظل مركزًا (لأنه زر) ، لذلك سيظل تلميح الأداة مرئيًا حتى يتم نقل التركيز بعيدًا
                    
    tooltipBtn.hide();
                });
            }
        });
    });
    لا ننسي إدراج الملف أسفل الصفحات
     
  6. Chokri.Z

    Chokri.Z مشرف موقع أكتب كود

    إنشاء ملف الفئة "C:/xampp/htdocs/itabcode/classes/Image.php"

    سيكون هذا الملف المسؤول عن كل عمليات الصور.
    حالياـ سنستعين به لمراقبة الملف المرفوع و لتصغير حجم الصورة بعد رفعها.​
    كود PHP:
    <?php

    declare(strict_types=1);

    namespace 
    itabcode\classes;

    class 
    Image
    {
        private 
    $mime$image$newImage$errors = [];
        private 
    $origWidth$origHeight$resizeWidth$resizeHeight;

        
    /**
         * Constructor
         *
         * @param string $filename
         */
        
    function __construct(string $filename)
        {
            if (
    file_exists($filename)) {
                
    $this->populateImg($filename);
                
    // throw new \Exception('المعلن عنه،لم يتم العثور عليه' . $filename . ' ملف');
            
    } else {
                
    $this->errors['resize'] ='المعلن عنه،لم يتم العثور عليه' $filename ' ملف';
            }

            return (!empty(
    $this->errors))? $this:false;
        }

        
    /**
         * تعيين الصورة
         *
         * @param string $filename
         * @return void
         */
        
    private function populateImg(string $filename): void
        
    {
            
    $size       getimagesize($filename);
            
    $this->mime $size['mime'];

            switch (
    $this->mime) {
                    
    // JPG أو JPEG الصورة بتنسيق
                
    case 'image/jpg':
                case 
    'image/jpeg':
                case 
    'image/pjpeg':
                    
    $this->image imagecreatefromjpeg($filename);
                    break;
                    
    // GIF الصورة بتنسيق
                
    case 'image/gif':
                    
    $this->image imagecreatefromgif($filename);
                    break;
                    
    // PNG الصورة بتنسيق
                
    case 'image/png':
                case 
    'image/x-png':
                    
    $this->image imagecreatefrompng($filename);
                    break;
                    
    // web الصورة بتنسيق
                
    case 'image/webp':
                case 
    'image/x-webp':
                    
    $this->image imagecreatefromwebp($filename);
                    break;
                    
    //  النتسيق غير موجود
                
    default:
                    
    $this->errors['resize'] = 'نوع الملف غير مسموح به ، الرجاء استخدام نوع ملف آخر ';
            }

            
    $this->origWidth  imagesx($this->image);
            
    $this->origHeight imagesy($this->image);
        }

        
    /**
         * تغيير حجم الصورة إلى قيم معينة جديدة
         *
         * @param mixed $width
         * @param mixed $height
         * @return boolean
         */
        
    function resizeTo(mixed $widthmixed $height): bool
        
    {
            
    $this->resizeWidth  intval($width);
            
    $this->resizeHeight intval($height);

            
    $this->newImage imagecreatetruecolor($this->resizeWidth$this->resizeHeight);

            if (
    $this->newImage) {
                if (
    imagecopyresampled($this->newImage$this->image0000$this->resizeWidth$this->resizeHeightintval($this->origWidth), intval($this->origHeight))) {
                    return 
    true;
                }
            }

            return 
    false;
        }

        
    /**
         * حفظ الصورة بالقيم الجديدة
         *
         * @param string $savePath
         * @param integer $imageQuality
         * @return void
         */
        
    function saveImg(string $savePathint $imageQuality 100)
        {
            
    defined('IMG_WEBP') or define('IMG_WEBP'32);

            switch (
    $this->mime) {
                case 
    'image/jpg':
                case 
    'image/jpeg':
                case 
    'image/pjpeg':
                    
    // التأكد من أن لغة البرمجة تدعم هذا النوع من الملفات
                    
    if (imagetypes() & IMG_JPG) {
                        
    imagejpeg($this->newImage$savePath85);
                    }
                    break;
                case 
    'image/gif':

                    if (
    imagetypes() & IMG_GIF) {
                        
    imagegif($this->newImage$savePath);
                    }
                    break;
                case 
    'image/png':
                case 
    'image/x-png':
                    
    $invertScaleQuality round(($imageQuality 100) * 9);

                    if (
    imagetypes() & IMG_PNG) {
                        
    imagepng($this->newImage$savePath, (int) $invertScaleQuality);
                    }
                    break;
                case 
    'image/webp':
                case 
    'image/x-webp':
                    if (
    imagetypes() & IMG_WEBP) {
                        
    imagewebp($this->newImage$savePath85);
                    }
                    break;
                default:
                    
    imagejpeg($this->newImage$savePath85);
                    break;
            }

            
    imagedestroy($this->newImage);

            return 
    $this;
        }

        
    /**
         * الحصول على كافة الأخطاء
         *
         * @return mixed
         */
        
    function getErrors(): mixed
        
    {
            return 
    $this->errors;
        }

        function  
    __destruct()
        {
            
    $this->mime null;
            
    $this->origWidth  null;
            
    $this->origHeight null;
        }
    }

    مجلد المشروع تم التعديل عليه و إدراجه كمرفقات هنا .

    إلى هنا نكون قد أتممنا تقريبا أكثر من 90 بالمائة من المشروع.
    كل ما تبقى ملف sendmail.php الذي سيكون مسؤول عن تحليل ملف "contact.php" و تنفيذ الإتصال.

    يــتــبــع
     
    آخر تعديل: ‏9/6/2022
  7. Chokri.Z

    Chokri.Z مشرف موقع أكتب كود

    إدراج مجلد "C:/xampp/sendmail"

    هو المجلد المسؤول عن بعث الرسائل محليا "on loclal" .
    يعني من خلال السرفر المحلي "XAMPP" .

    هناك طريقتان لفعل ذلك
    - إما أن يكون المجلد مدرج أو منصب عند أول تنصيب السرفر المحلي (هذا يتم عن طريق خانة الاختيار)

    [​IMG]

    - أو نقوم بتحميله و تنصيبه يدويا على المسار "C:/xampp/sendmail"

    [​IMG]
    رابط النحميل:
    كود:
    https://sourceforge.net/projects/send-mail/files/latest/download

    العملية تمت بنجاح. و بهذا نكون هيئنا البيئة لإنشاء ملفنا "C:/xampp/htdocs/itabcode/sendmail.php"

    الخطوة التالية بإذن الله، ستكون وضع الإعدادات الازمة في بعض ملفات المجلد

    يــتــبــع

    للتذكير كل ما أقوم به خاص بنظام التشغيل "windows"

     
  8. Chokri.Z

    Chokri.Z مشرف موقع أكتب كود

    إعدادات "xampp" و "sendmail" الخاصة بحسابات "GMAIL"

    في هذه المرحلة سنقوم بالتعديل على الملفين:
    "C:/xampp/php/php.ini" و "C:/xampp/sendmail/sendmail.ini"

    في إعدادات الملف "C:/xampp/sendmail/sendmail.ini" ، سنكون مطالبين بـ auth_username و auth_password
    لذا، نقوم بتسجيل الدخول على حسابنا gmail ، و من ثم نضغط على الصورة الرمزية من أعلى اليمين.
    نختار خيار إدارة حساب جوجل الخاص بك "Manage your google account" أو بالفرنسية "Gérer votre compte google"
    ستفتح على المتصفح نافذة مستقلة
    من على اليسار، توجد خيارات. نقوم بالختيار "securité" أو "security"
    ثم من على اليمين، يجب أن يكون خيار التحقق بخطوتين مفعل. إن لم يكن كذلك، قم بتفعيله.
    ثم نختار "Application Passwords" أو "Mots de passe des applications"

    [​IMG]

    على هذه النافذة، إن لم يكن لك كلمات مرور خاصة بالتطبيقات، قم بتحرير واحدة.
    عند الضغط على "Application Passwords"، ستفتح لك نافدة
    [​IMG]
    كما هو مبين في الصورة
    إختر "Messaging" أو "Messagerie" (الخانة رقم 1)
    ثم اختر "windows computer" أو " Ordinateur windows" (الخانة رقم 2)
    ثم إضعط على زر "Generate" أو " Générer"

    تمت العملية بنجاح، و أصبح لدينا كلمة مرور خاصة بالتطبيقات
    [​IMG]

    نقوم بنسخ و الصاق كلمة المرور و حفظها في مكان آمن، ثم قم بالضغط على الزر "ok"

    في المرحلة التالية، سنبدأ بإذن الله التعديل على الملفات المذكورة أعلاه.

    يــتــبــع
     
  9. Chokri.Z

    Chokri.Z مشرف موقع أكتب كود

    إعدادات "xampp" و "sendmail" الخاصة بحسابات "GMAIL"

    أولا، سنقوم بالتعديل على ملف "C:/xampp/php/php.ini"
    للقيام بذلك، كما تبين الصورة في هذه المشاركة. بعد تشغيل الخادم "XAMPP" ، من خلال قائمة هذا الأخير نقوم بالنقر فوق علامة التبويب "config" . ثم و من قائمة الخيارات نختر (php.ini)
    سيتم فتح ملف في المحرر الافتراضي للنظام. في هذا الملف المفتوح ، ابحث عن "mail function"
    نبحث عن الأسطر: "smtp_port, smtp" و "sendmail_path"

    ثم نقوم بالتعديل عليها كما يلي:​
    كود HTML:
    SMTP=smtp.gmail.com
    smtp_port=587
    sendmail_path = "\"C:\xampp\sendmail\sendmail.exe\" -t"
    السطر "sendmail_from = [email protected]" يبقى إختياري
    إن أراد أحدا تفعيله كخيار، يضع مكان البريد الإلكتروني الإفتراضي، بريده هو.

    نقوم بعملية الحفظ، و ننتقل إلى الملف "C:/xampp/sendmail/sendmail.ini"
    نقوم بفتحه على المحرر المضل لديك، ثم نقوم بالتعديلات التالية على الأسطر المعنية:​
    كود HTML:
    smtp_server=smtp.gmail.com
    smtp_port=587
    smtp_ssl=auto
    error_logfile=error.log
    debug_logfile=debug.log
    auth_username=بريدك الإلكتروني
    auth_password=كلمة المرور الخاصة بالنطبيقات المحررة مؤخرا

    بعد التعديل و الحفظ، أصبج و الحمد لله، لدينا سرفر محلي قادر على إرسال الرسائل الإلكترونية عن طريق "GMAIL"

    المرحلة التالية، ستكون مخصصة لإنشاء ملف "sendmail.php"

    يــتــبــع


     
  10. Chokri.Z

    Chokri.Z مشرف موقع أكتب كود

    إنشاء ملف "C:/xampp/htdocs/itabcode/sendmail.php"

    هذا الملف، سيكون بإذن الله داعم لإرسال ملف مرفق مع رسالة، و مسؤول عن تحليل محتوى نصي داخل بطاقة الإشعار (HTML textarea tag) الموجدة بإستمارة داخل ملف "C:/xampp/htdocs/itabcode/contact.php" و من ثمه يقوم ببعث الرسالة و إرجاع محتوى رسالة تأكيد على شكل "JSON" .​
    كود PHP:
    <?php

    declare(strict_types=1);

    function 
    escp_input(string $data): string
    {
        
    $data trim($data);
        
    $data stripslashes($data);
        
    $data htmlspecialchars($data);

        return 
    $data;
    }
    if (
    $_SERVER['REQUEST_METHOD'] == 'POST') {

        
    $json    = [];
        
    $errors  = [];
        
    $subject escp_input($_POST['s_subject']);
        
    $from    escp_input($_POST['s_email']);
        
    $message escp_input($_POST['s_msg']);

        
    $to      ''// عنوان الوجهة

        
    if (empty($to)) {
            
    $errors['to']      = 'لقد نسيت أن تعلن عن البريد الإلكتروني للمستلم  ️';
            
    $json['errors']    = 'لقد نسيت أن تعلن عن البريد الإلكتروني للمستلم  ️';
        }
        if (empty(
    $subject)) {
            
    $errors['subject'] = 'عنوان الرسالة مطلوب  ️';
            
    $json['errors']    = 'عنوان الرسالة مطلوب  ️';
        }
        if (empty(
    $from)) {
            
    $errors['email'] = 'البريد الإلكتروني مطلوب  ️';
            
    $json['errors']    = 'البريد الإلكتروني مطلوب  ️';
        } else {

            
    // إزالة الأحرف غير القانونية
            
    $sanitized_email filter_var($fromFILTER_SANITIZE_EMAIL);

            if (!
    filter_var($sanitized_emailFILTER_VALIDATE_EMAIL)) {
                
    $errors['email'] = 'عنوان البريد الإلكتروني غير صالح  ️';
                
    $json['errors']    = 'عنوان البريد الإلكتروني غير صالح  ️';
            }
        }
        if (empty(
    $message)) {
            
    $errors['message'] = 'الرجاء إدخال نص الرسالة  ️';
            
    $json['errors']    = 'الرجاء إدخال نص الرسالة  ️';
        } else {
            
    $message =  nl2br($message);
        }
        
    // نقوم بتصفية الخوادم التي بها أخطاء
        
    if (!preg_match("#^[a-z0-9._-][email protected](hotmail|live|msn).[a-z]{2,4}$#"$from)) {
            
    $pass_ligne "\r\n";
        } else {
            
    $pass_ligne "\n";
        }

        
    //===== HTML إعلان الرسالة بتنسيق الـ
        
    $msg_html  '<html><head></head><body>';
        
    $msg_html .= '<div dir="rtl" style="border-style: solid;
                        border-width: thin;border-color: #818ea7;
                        border-radius: 8px;padding: 40px 20px;">
                        <h1 style="text-align:center;color:Blue;">أكتب كود لعلوم الحاسوب</h1>
                        <h2 style="text-align:center;color:Blue;">هناك رسالة واردة</h2>'
    ;
        
    $msg_html .=    '<div style="border-style: solid;
                                border-width:thin;border-color:#818ea7;
                                padding:10px 5px;">'
    ;
        
    $msg_html .=       '<p>
                                <strong style="font-size:16px;color:red;">نص الرسالة:</strong><br><br>'
    ;
        
    $msg_html .=            '<em style="font-size:18px;">' $message '</em>
                            </p>'
    ;
        
    $msg_html .=    '</div>
                      </div>'
    ;
        
    $msg_html .= '</body></html>';
        
    //==========

        //===== قراءة المرفق و تنسيقه
        
    $file        fopen("images/img-1.jpg""r");
        
    $attachement fread($filefilesize("images/img-1.jpg"));
        
    $attachement chunk_split(base64_encode($attachement));
        
    fclose($file);
        
    //==========

        //===== حدود الرسالة
        
    $boundary     "-----=" md5((string) rand());
        
    $boundary_alt "-----=" md5((string) rand());

        
    //=====  Headers إنشاء الـ
        
    $header  "From: Sender <$from>" $pass_ligne;
        
    $header .= "Reply-to: Sender <$from>" $pass_ligne;
        
    $header .= "MIME-Version: 1.0" $pass_ligne;
        
    $header .= "Content-Type: multipart/mixed;" $pass_ligne " boundary=\"$boundary\"" $pass_ligne;
        
    //==========

        //===== إنشاء الرسالة
        
    $msg  $pass_ligne "--" $boundary $pass_ligne;
        
    $msg .= "Content-Type: multipart/alternative;" $pass_ligne " boundary=\"$boundary_alt\"" $pass_ligne;
        
    $msg .= $pass_ligne "--" $boundary_alt $pass_ligne;
        
    $msg .= $pass_ligne "--" $boundary_alt $pass_ligne;
        
    $msg .= "Content-Type: text/html; charset=\"ISO-8859-1\"" $pass_ligne;
        
    $msg .= "Content-Transfer-Encoding: 8bit" $pass_ligne;
        
    $msg .= $pass_ligne $msg_html $pass_ligne;
        
    //==========

        //===== غلق الجدود البديلة
        
    $msg .= $pass_ligne "--" $boundary_alt "--" $pass_ligne;
        
    //==========

        
    $msg .= $pass_ligne "--" $boundary $pass_ligne;

        
    //===== إضافة المرفق
        
    $msg .= "Content-Type: image/jpeg; name=\"image.jpg\"" $pass_ligne;
        
    $msg .= "Content-Transfer-Encoding: base64" $pass_ligne;
        
    $msg .= "Content-Disposition: attachment; filename=\"image.jpg\"" $pass_ligne;
        
    $msg .= $pass_ligne $attachement $pass_ligne $pass_ligne;
        
    $msg .= $pass_ligne "--" $boundary "--" $pass_ligne;
        
    //==========

        //===== إرسال الرسالة مع إظهار خطأ في حالة عدم الإرسال إو إعلام بالنجاح
        
    if (empty($errors)) {
            if (
    mail($to$subject$msg$header)) {
                
    $json['success'] = 'تم الإرسال بنجاح';
            } else {
                
    $json['errors'] = 'خطأ: لم يتم إرسال الرسالة!';
            }
        } else {
            
    $json['errors'] = implode('<br>' PHP_EOL$errors);
        }
        
    //==========

        
    echo json_encode($json);
    }
    [​IMG]

    [​IMG]

    [​IMG]

    [​IMG]


    لا ننسى التعديل على السطر الآني بإدخالد بريد المستلم.
    كود PHP:
    $to      ''// عنوان الوجهة
    لا تقلق على كل حال. تم وضع شرط لمراقبة حسن إتمام الأمر، و سيتم إعلامك في صورة النسيان أو اخطأ.

    إلى هنا، نكون قد أتممنا كل المراحل و الحمد الله.

    سيتم رفع مجلد المشروع هنا بإذن الله

    في انتظار تفاعلكم و مقتراحاتكم و نقدكم أيضا ;)
     
    آخر تعديل: ‏11/6/2022
جاري تحميل الصفحة...