موقع إلكتروني من الصفر إلى الإحتراف بcakephp الجزء الأول

imadbelasri Cakephp
CA

فهاد المشروع غادي نشوفو كيفاش نقادو واحد الموقع إلكتروني عبارة عن موقع كيقدم عروض العمل بإستعمال cakephp framework لي غادي يكون فيه 4 أجزاء فهاد الجزء الأول غادي نحملو cakephp من الموقع الرسمي غادي نزيدو قاعدة البيانات منبعد نربطو بها الإتصال ونقادو الصفحة الرئيسية.


نظرة سريعة بالفيديو


- إنشاء قاعدة البيانات

اول حاجة غادي نديروها هي تثبيت cakephp فكنحمل composer من https://getcomposer.org/download من بعد كنمشي ل cmd كندير ل:commande cd c من بعد لcommande cd wamp/www من بعد كنكتب commande لي غادي تمكني من تثبيت cakephp لي هي composer self-update && composer create-project --prefer-dist cakephp/app JobFinder من بعد ما تثبت غادي نمشي لwamp/www غادي نلقا المشروع ديالي تزاد JobFinder من بعد غادي نمشي phpmyadmin وغادي نزيد قاعدة بيانات نسميها jobs الكود ديال لtables لي فيها هو:

                                                    
                                                        //categories table
CREATE TABLE IF NOT EXISTS `categories` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

-- Structure de la table `offres`
--

CREATE TABLE IF NOT EXISTS `offres` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `category_id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  `type_id` int(11) NOT NULL,
  `title` varchar(200) NOT NULL,
  `desc` text NOT NULL,
  `company_name` varchar(200) NOT NULL,
  `ville` varchar(200) NOT NULL,
  `contact_email` varchar(200) NOT NULL,
  `created` timestamp NOT NULL,
  PRIMARY KEY (`id`),
  KEY `category_id` (`category_id`,`user_id`,`type_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

-- Structure de la table `types`
--

CREATE TABLE IF NOT EXISTS `types` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `color` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

-- Structure de la table `users`
--
CREATE TABLE IF NOT EXISTS `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nom` varchar(255) NOT NULL,
  `prenom` varchar(255) NOT NULL,
  `email` varchar(255) NOT NULL,
  `username` varchar(200) NOT NULL,
  `password` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
                                                    
                                                

- ملف الإتصال بقاعدة البيانات

باش تربط الإتصال بقاعدة البيانات كتمشي للمجلد config من بعد للملف app.php وكتغير قيم الجدول لي سيمتو Datasources غادي ندخلو السمية ديال قاعدة البيانات بالإضافة للمستخدم فالقيم لي غادي تغير هي هادي:

                                                        
                                                            'host' => 'localhost',
'username' => 'root',
'password' => '',
'database' => 'jobs',


'quoteIdentifiers' => true,
                                                        
                                                    

- الصفحة الرئيسية

أول حاجة كتمشي ل config/routes.php و كتغير القيم ديال : $routes->connect('/',['controller' => 'Offres','action' => 'index', 'home']); ولي كاتعني بلي غادي نخدمو بلcontroller offres ول methode index منبعد كنمشي ل src/controller وكنزيد controller جديد سميتو OffresController.php يكون الكود ديالو فيه methode index لي كتمكن من عرض كل فرص العمل المتوفرة فقاعدة البيانات و browse لي كتدير نفس الخدمة و find لي كتمكن من البحث على فرصة عمل و view لي كتمكن من مشاهدة فرصة عمل اختارها المستخدم و add لي كتمكن من إضافة معلومات فقاعدة البيانات خاصة بفرصة عمل وedit لي كتمكن من تعديل المعلومات الخاصة بفرصة عمل و delete لي كتمكن من مسح فرصة عمل اختارها المستخدم الكود ديال الملف هو :

                                                        
                                                            <?php
namespace App\Controller;

use App\Controller\AppController;

class OffresController extends AppController
{
    public $name = 'Offres';
    public function initialize()
    {
        parent::initialize();
        $this->loadComponent('Flash'); // Include the FlashComponent
    }
    public function index()
    {
        //categories
        $options = array(
            'order'=>array('Categories.id'=>'asc')
        );
        $categories = $this->Offres->Categories->find('all',$options);
        $this->set('categories',$categories);
        //offres
        $options = array(
            'order'=>array('Offres.id'=>'desc'),
            'limit' => 10
        );
        $offres = $this->Offres->find('all',$options)->contain(['Types']);
        $this->set('title','Emploi.com|Acceuil');
        $this->set('offres',$offres);
    }
    public function browse($category = null)
    {
        $conditions = array();
        if($category != null){
            $conditions[] = array(
                'Offres.category_id =' => $category
            );
        }
         //categories
        $options = array(
            'order'=>array('Categories.id'=>'asc')
        );
        $categories = $this->Offres->Categories->find('all',$options);
        $this->set('categories',$categories);
        //offres
        $options = array(
            'order'=>array('Offres.id'=>'desc'),
            'conditions'=>$conditions,
            'limit' => 10
        );
        $this->set('title','Emploi.com|Offres');
        $offres = $this->Offres->find('all',$options)->contain(['Types']);
        $this->set('offres',$offres);
    }
    public function find()
    {
        $conditions = array();
        if(!empty($this->request->data('keywords'))){
            $conditions[] = array('or'=>array(
                'Offres.title LIKE' => "%".$this->request->data('keywords')."%",
                'Offres.desc LIKE' => "%".$this->request->data('keywords')."%",
            ));
        }
        if(!empty($this->request->data('ville')) && $this->request->data('ville') != "default"){
            $conditions[] = array(
                'Offres.ville =' => $this->request->data('ville')
            );
        }
        if(!empty($this->request->data('categorie')) && $this->request->data('categorie') != "default"){
            $conditions[] = array(
                'Offres.category_id =' => $this->request->data('categorie')
            );
        }
         //categories
        $options = array(
            'order'=>array('Categories.id'=>'asc')
        );
        $categories = $this->Offres->Categories->find('all',$options);
        $this->set('categories',$categories);
        //offres
        $options = array(
            'order'=>array('Offres.id'=>'desc'),
            'conditions'=>$conditions,
            'limit' => 10
        );
        $offres = $this->Offres->find('all',$options)->contain(['Types']);
        $this->set('title','Emploi.com|Recherhce');
        $this->set('offres',$offres);
    }
    public function view($id){
         $conditions = array();
         //offres
         $query = $this->Offres->findById($id)->contain(['Types']);
         $offre = $query->first();
         $this->set('title',$offre->title);
         $this->set('offre',$offre);
    }
    public function add(){
        $categories = $this->Offres->Categories->find('list');
        $this->set('categories',$categories);
        $types = $this->Offres->Types->find('list');
        $this->set('types',$types);
        $offre = $this->Offres->newEntity();
        if($this->request->is('post')){
            //user id par default
            $this->request->data['user_id'] = $this->Auth->user('id');
            $this->request->data['created'] = date("Y-m-d h:s:i");
            //save data
            $offre = $this->Offres->patchEntity($offre, $this->request->data);
            if($this->Offres->save($offre)){
                $this->Flash->success(__('Offre ajoutée avec succés'),[
                    'params' => [
                        'class' => 'alert alert-success'
                    ]
                ]);
                return $this->redirect(['action' => 'index']);
            }
            $this->Flash->error(__('Une erreur est survenue veuillez réessayer'),[
                'params' => [
                    'class' => 'alert alert-danger'
                ]
            ]);
        }
        $this->set('title','Emploi.com|Ajouter une offre');
        $this->set('offre',$offre);
    }
     public function edit($id){
        $categories = $this->Offres->Categories->find('list');
        $this->set('categories',$categories);
        $types = $this->Offres->Types->find('list');
        $this->set('types',$types);
        $offre = $this->Offres->get($id);
        if($this->request->is(['post','put'])){
            //user id par default
            if(empty($this->request->data('category_id')) || empty($this->request->data('category_id'))){
                $this->Flash->error(__('Veuillez choisir une catégorie et un type'),[
                    'params' => [
                        'class' => 'alert alert-danger'
                    ]
                ]);
                return $this->redirect(['action' => 'edit',$id]);
            }else{
                $this->request->data['user_id'] = 1;
                $this->request->data['created'] = date("Y-m-d h:s:i");
                //save data
                $offre = $this->Offres->patchEntity($offre, $this->request->data);
                if($this->Offres->save($offre)){
                    $this->Flash->success(__('Offre modifiée avec succés'),[
                        'params' => [
                            'class' => 'alert alert-success'
                        ]
                    ]);
                    return $this->redirect(['action' => 'index']);
                }
                $this->Flash->error(__('Une erreur est survenue veuillez réessayer'),[
                    'params' => [
                        'class' => 'alert alert-danger'
                    ]
                ]);
            }
        }
        $this->set('title',$offre->title);
        $this->set('offre',$offre);
    }
    public function delete($id)
    {
        $this->request->allowMethod(['post', 'delete']);
        $offre = $this->Offres->get($id);
        if ($this->Offres->delete($offre)) {
            $this->Flash->success(__('Offre avec le id: {0} est supprimée avec succés.', h($id)),[
                'params' => [
                    'class' => 'alert alert-success'
                ]
            ]);
            return $this->redirect(['action' => 'index']);
        }
    }
}
                                                        
                                                    

- الصفحة الرئيسية تتمة

فباش نبدلو الصفحة الرئيسية لي كاتجي مع cakephp كنمشي ل src/Template/Layout وكنحذف الملف default.ctp وكنزيد ملف جديد كنسميه نفس الإسم default.ctp منبعد كنحمل bootstrap كنزيد bootstrap.min.css ف webroot/css وbootstrap.min.js ف webroot/js منبعد كنحمل fontawsome و كنزيد fontawsome.css فwebroot/css و الملفات لي فالمجلد fonts ف webroot/fonts الكود ديال الملف default.ctp هو :

                                                        
                                                            <!DOCTYPE html>
<html lang="fr">
<head>
    <?= $this->Html->charset() ?>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>
        <?php echo $title;?>
    </title>
    <?= $this->Html->meta('icon') ?>
    <?= $this->Html->css('bootstrap.min') ?>
    <?= $this->Html->css('main') ?>
    <?= $this->Html->css('fontawsome') ?>
    <?= $this->Html->script('bootstrap.min') ?>
    <?= $this->Html->script('jquery') ?>
    <?= $this->fetch('meta') ?>
    <?= $this->fetch('css') ?>
    <?= $this->fetch('script') ?>
</head>
<body>
    <div class="container">
        <div class="panel panel-default main">
            <header>
                <div class="row header">
                    <div class="col-md-10">
                        <div class="pull-left">
                            <span class="logo text-primary">Emplois.<span class="text-danger">com</span></span>
                        </div>
                    </div>
                    <div class="col-md-2">
                        <div class="pull-right">
                            <?php echo $this->Html->link($this->Html->tag('i', '', array('class' => 'fa fa-plus')).' Ajouter',array('controller'=>'offres','action'=>'add'),array('escape' => false,'class'=>'btn btn-success','id'=>'addBtn'));?></span>
                        </div>
                    </div>
                </div>
            </header>
            <nav class="navbar navbar-default">
                <div class="container-fluid">
                    <!-- Brand and toggle get grouped for better mobile display -->
                    <div class="navbar-header">
                        <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                            <span class="sr-only">Toggle navigation</span>
                            <span class="icon-bar"></span>
                            <span class="icon-bar"></span>
                            <span class="icon-bar"></span>
                        </button>
                    </div>
                    <!-- Collect the nav links, forms, and other content for toggling -->
                    <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                        <ul class="nav navbar-nav">
                            <li><?php echo $this->Html->link($this->Html->tag('i', '', array('class' => 'fa fa-home')).'Accueil',array('controller'=>'offres','action'=>'index'),array('escape' => false));?><span class="sr-only"></span></li>
                            <li><?php echo $this->Html->link($this->Html->tag('i', '', array('class' => 'fa fa-search')).'Offres',array('controller'=>'offres','action'=>'browse'),array('escape' => false));?></li>
                            <?php if ($authUser):?>
                            <li><?php echo $this->Html->link($this->Html->tag('i', '', array('class' => 'fa fa-sign-out')).$authUser['username'].' Déconnexion',array('controller'=>'users','action'=>'logout'),array('escape' => false));?></li>
                            <?php else:?>
                            <li><?php echo $this->Html->link($this->Html->tag('i', '', array('class' => 'fa fa-user-plus')).'Inscription',array('controller'=>'users','action'=>'register'),array('escape' => false));?></li>
                            <li><?php echo $this->Html->link($this->Html->tag('i', '', array('class' => 'fa fa-sign-in')).'Connexion',array('controller'=>'users','action'=>'login'),array('escape' => false));?></li>
                            <?php endif;?>
                        </ul>
                    </div><!-- /.navbar-collapse -->
                </div><!-- /.container-fluid -->
            </nav>
            <div class="row">
                <div class="col-md-12">
                    <?php echo $this->Flash->render();?>
                </div>
            </div>
            <div class="row">
                <div class="col-md-12">
                    <?= $this->fetch('content') ?>
                </div>
            </div>
            <div class="row">
                <div class="col-md-12">
                    <footer>
                        <p class="center">&copy DarijaCoding 2017 Tous droits réservés</p>
                    </footer>
                </div>
            </div>
        </div>
    </div>
</body>
<script type="text/javascript" src="js/bootstrap.min.js"></script>
</html>
                                                        
                                                    

- الملف main.css

فالمجلد webroot/css كنزيد ملف سميتو main.css لي عبارة عن des styles css لي غادي نحتاجو الكود ديالو هو :

                                                        
                                                            body{
    background: #C9C9C9;
    font-family: Verdana, Geneva, Tahoma, sans-serif;
}
header{
    margin-top: 30px;
}
span.logo{
    font-size: 30px;
    padding: 10px;
    font-weight: bold;
}
#addBtn{
    margin:5px;
}
nav{
    margin-top:10px;
}
div.offre{
    margin-top:30px;
}
footer p.center{
    text-align: center;
    font-size: 15px;
    color:#000;
    font-weight: bold;
    margin-top: 60px;
}
.categories{
    margin: 25px;
}