ساخت کنترلر و مدل Posts

Building Controller and Posts Model

25 بهمن 1399
پروژه ساخت شبکه ی اجتماعی: ساخت کنترلر و مدل Posts

ساخت کنترلر Posts

تا این قسمت تمام سیستم احراز هویت را کامل کرده ایم و می توانیم به راحتی کاربران خود را ثبت نام را وارد سیستم کنیم. حالا وقت آن رسیده است که به سراغ عملیات پست گذاری برویم. بنابراین اولین کاری که باید انجام دهیم، ساخت فایلی به نام Posts.php در پوشه controller است.

درون این فایل کلاس Posts را می نویسیم و با آن کلاس Controller را extend می کنیم تا به کدهایش دسترسی داشته باشیم. سپس یک تابع index می سازیم که داخلش یک view را بارگذاری کنیم:

<?php
  class Posts extends Controller {
    public function index(){
      $data = [];

      $this->view('posts/index', $data);
    }
  }

فعلا data ما یک آرایه خالی است تا بعدا آن را تکمیل کنیم.

سپس به پوشه views رفته و در آنجا پوشه ای جدید به نام posts ایجاد کنید. درون این پوشه یک فایل به نام index.php نیز ایجاد کنید و داخل آن header و footer را بارگذاری کنید (مانند view های جلسات قبلی):

<?php require APPROOT . '/views/inc/header.php'; ?>


<?php require APPROOT . '/views/inc/footer.php'; ?>

حالا باید کدهای HTML را به آن اضافه کنیم (بین header و footer):

<?php require APPROOT . '/views/inc/header.php'; ?>
  <div class="row">
    <div class="col-md-6">
      <h1>Posts</h1>
    </div>
    <div class="col-md-6">
      <a href="<?php echo URLROOT; ?>/posts/add" class="btn btn-primary pull-right">
        <i class="fa fa-pencil"></i> Add Post
      </a>
    </div>
  </div>
<?php require APPROOT . '/views/inc/footer.php'; ?>

کلاس fa مربوط به کتابخانه font awesome است. این کد HTML تنها کاری که می کند ایجاد یک ردیف ساده است که در سمت چپ آن عبارت Posts و در سمت راست دکمه Add Post نمایش داده می شود.

برای نمایش پست ها باید آن ها را از پایگاه داده fetch کنیم اما فعلا به صورت دستی و در محیط PHPMyAdmin چند پست را ایجاد می کنیم؛ به جدول posts بروید و یک پست دلخواه ایجاد کنید. در قسمت user_id باید id کاربری را قرار دهید که در جدول users ایجاد کرده ایم، اگر در این قسمت کاربری ندارید به صورت دستی یک کاربر نیز ایجاد کنید.

قبل از fetch کردن پست ها باید مسئله مهمی را حل کنیم: کاربران باید فقط و فقط هنگامی صفحه گذاشتن پست را ببینند که login شده باشند در غیر این صورت نباید اجازه گذاشتن پست به کسی داده شود. بنابراین باید فایل ها را کمی تغییر دهیم. وارد فایل Users.php از پوشه controllers شوید و در تابع createUserSession صفحه redirect را از pages/index به posts تغییر دهید:

   public function createUserSession($user){
      $_SESSION['user_id'] = $user->id;
      $_SESSION['user_email'] = $user->email;
      $_SESSION['user_name'] = $user->name;
      redirect('posts');
    }

حالا به فایل Posts.php در همان پوشه رفته و برایش یک constructor بسازید:

public function __construct(){
      if(!isLoggedIn()){
        redirect('users/login');
      }
    }

نکته: ما قصد داریم که هیچ کاربری اجازه مشاهده پست ها و پست گذاری نداشته باشد مگر اینکه login شده باشد، به همین دلیل تابع مربوطه را در خود constructor تعریف کرده ایم. اگر شما می خواهید کاربران مهمان بتوانند پست ها را مشاهده کنند اما نتوانند پست بگذارند، نباید این کار را در constructor انجام دهید بلکه لازم است فقط از توابع مربوط به پست گذاری محافظت کنید.

تابع isLoggedIn را در جلسات قبلی تعریف کردیم. به فایل Users.php (پوشه controller) بروید و کدهای مربوط به تابع isLoggedIn را cut کنید. سپس به فایل session_helper.php رفته و کدها را در آنجا قرار دهید. این کار به نظم پروژه ما کمک می کند ولی کاملا دلخواه است. (یادتان نرود که کلیدواژه public را حذف کنید چرا که در این فایل کلاسی نداریم):

function isLoggedIn(){
    if(isset($_SESSION['user_id'])){
      return true;
    } else {
      return false;
    }
  }

ساخت Model برای دریافت پست ها

در پوشه models یک فایل جدید به نام post.php بسازید. در این فایل کلاسی به نام Post ایجاد کرده و یک متغیر خصوصی به نام db می سازیم تا با استفاده از آن به پایگاه داده دسترسی داشته باشیم:

?php
  class Post {
    private $db;

    public function __construct(){
      $this->db = new Database;
    }

حالا تابعی به نام getPosts تعریف می کنیم تا با استفاده از پست آن ها را دریافت کنیم:

public function getPosts(){
      $this->db->query('SELECT * FROM posts');

      $results = $this->db->resultSet();

      return $results;
    }

حالا به Posts.php بروید. می خواهیم model را در constructor بارگذاری کنیم:

public function __construct(){
      if(!isLoggedIn()){
        redirect('users/login');
      }

      $this->postModel = $this->model('Post');
    }

حالا درون تابع index می گوییم:

public function index(){
      // Get posts
      $posts = $this->postModel->getPosts();

      $data = [
        'posts' => $posts
      ];

      $this->view('posts/index', $data);
    }

با این کد پست ها را دریافت کرده و داخل متغیر data گذاشته ایم.

حالا فایل index.php را از پوشه views>posts باز کنید. از آنجایی که پست های ما قطعا بیشتر از یکی خواهند بود و آرایه هستند باید با یک حلقه در آن ها گردش کنیم:

<?php require APPROOT . '/views/inc/header.php'; ?>
  <div class="row mb-3">
    <div class="col-md-6">
      <h1>Posts</h1>
    </div>
    <div class="col-md-6">
      <a href="<?php echo URLROOT; ?>/posts/add" class="btn btn-primary pull-right">
        <i class="fa fa-pencil"></i> Add Post
      </a>
    </div>
  </div>
  <?php foreach($data['posts'] as $post) : ?>
    <div class="card card-body mb-3">
      <h4 class="card-title"><?php echo $post->title; ?></h4>
      <div class="bg-light p-2 mb-3">
	  // USERNAME
      </div>
    </div>
  <?php endforeach; ?>
<?php require APPROOT . '/views/inc/footer.php'; ?>

باید به جای USERNAME در کد بالا نام کاربر را نمایش دهیم اما اگر یادتان باشد نام کاربر را از پایگاه داده نگرفتیم. کوئری SQL ما به این شکل بود:

SELECT * FROM POSTS

نام کاربر داخل جدول Posts نیست بنابراین باید یک کوئری Join ایجاد کنیم. به فایل Post.php (پوشه model) بروید تا کوئری خود را ویرایش کنیم:

public function getPosts(){
      $this->db->query('SELECT *,
                        posts.id as postId,
                        users.id as userId,
                        posts.created_at as postCreated,
                        users.created_at as userCreated
                        FROM posts
                        INNER JOIN users
                        ON posts.user_id = users.id
                        ORDER BY posts.created_at DESC
                        ');

      $results = $this->db->resultSet();

      return $results;
    }

این کوئری جدول های posts و users را با هم join می کند و ستون user_id موجود در جدول posts را برابر با ستون id از جدول users قرار می دهد. اگر با زبان SQL آشنایی ندارید به دوره آموزشی زبان SQL ما سری بزنید.

حالا به فایل index.php از پوشه views>posts برمی گردیم و کدهایمان را به شکل زیر تکمیل می کنیم:

<?php require APPROOT . '/views/inc/header.php'; ?>
  <div class="row mb-3">
    <div class="col-md-6">
      <h1>Posts</h1>
    </div>
    <div class="col-md-6">
      <a href="<?php echo URLROOT; ?>/posts/add" class="btn btn-primary pull-right">
        <i class="fa fa-pencil"></i> Add Post
      </a>
    </div>
  </div>
  <?php foreach($data['posts'] as $post) : ?>
    <div class="card card-body mb-3">
      <h4 class="card-title"><?php echo $post->title; ?></h4>
      <div class="bg-light p-2 mb-3">
        Written by <?php echo $post->name; ?> on <?php echo $post->postCreated; ?>
      </div>
      <p class="card-text"><?php echo $post->body; ?></p>
      <a href="<?php echo URLROOT; ?>/posts/show/<?php echo $post->postId; ?>" class="btn btn-dark">More</a>
    </div>
  <?php endforeach; ?>
<?php require APPROOT . '/views/inc/footer.php'; ?>

دانلود فایل های پروژه تا این قسمت

امیدوارم از این قسمت لذت برده باشید.

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری آموزش ساخت شبکه اجتماعی توصیه می‌کند:
نویسنده شوید
دیدگاه‌های شما (1 دیدگاه)

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

محمد
21 مهر 1398
سلام خسته نباشید و ممنون بابت آموزش رایگان و بسیار جذابتون فقط لطف کنید هر چه سریعتر ادامه آموزش رو قرار بدید سپاس

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

امیر زوارمی
26 مهر 1398
سلام دوست عزیز، قسمت های جدید منتشر شدند.

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.