ساخت یک سیستم مدیریت محتوا (CMS) اختصاصی با PHP

img
img
img
img
shape
shape
blog-details

ساختن یک سیستم مدیریت محتوا (CMS) می تواند یک کار دلهره آور برای توسعه دهنده تازه کار PHP به نظر برسد. با این حال ، این کار دشوار نیست. در این آموزش به شما نشان خواهم داد که تنها در چند ساعت یک CMS کاملاً کاربردی ، از ابتدا را می توانید بسازید.

فرض ما بر این است که شما دوره ابتدایی PHP و HTML را از قبل گذرانده اید

در ادامه مباحث زیر را هم آموزش خواهیم دید : 

  • ارتباط CMS با MySQL 
  • PHP objects
  •  constants
  •  includes
  • sessions
  • و دیگر بخش های اساسی یک CMS PHP

بخش های نمایشی برنامه مدیریت محتوا شما - Front end

  • صفحه اصلی ، فهرست 5 مقاله اخیر

  • صفحه فهرست مقاله ، لیست تمام مقالات

  • صفحه "مشاهده مقاله" ، به بازدید کنندگان این امکان را می دهد تا مقاله را مشاهده کنند 

بخش های سمت سرور برنامه مدیریت محتوا شما - Back end

  • ورود / خروج مدیر
  • لیست تمام مقالات
  • مقاله جدیدی اضافه کنید
  • مقاله موجود را ویرایش کنید
  • مقاله موجود را حذف کنید

 هر مقاله دارای یک عنوان ، محنوا و تاریخ انتشار است

مرحله 1: ایجاد دیتابیس

خب ما برای اینکه بتوانیم جدول های پایگاه داده های خودمان را داشته باشیم یک فایل tables.sql ایجاد می کنیم تا هر زمان که خواستیم CMS خودمان را بر روی یک هاست پیاده سازی کنیم بتوانیم به راحتی جدول ها را در بخش IMPORT برنامه MYSQL درون ریزی کنیم ! در واقه ما یک schema ایجاد می کنیم تا طرح اصلی دیتابیس خوددمان را داشته باشیم . CMS ما تنها جدول در پایگاه داده خود دارد با نام articles خب حالا یک قایل با نام tables.sql درست کنید و کد های زیر را درون این فایل ذخیره کنید : 

DROP TABLE IF EXISTS articles;
CREATE TABLE articles
(
  id              smallint unsigned NOT NULL auto_increment,
  publicationDate date NOT NULL,                              # When the article was published
  title           varchar(255) NOT NULL,                      # Full title of the article
  summary         text NOT NULL,                              # A short summary of the article
  content         mediumtext NOT NULL,                        # The HTML content of the article

  PRIMARY KEY     (id)
);

مرحله 2 : یک فایل پیکربندی ایجاد کنید - configuration file

کارایی این قایل پیکربندی این است که تنظیمات اساسی برنامه مدیریت ما را مانند اطلاعات دیتا بیس و غیره را در خود نگهداری و در صورت نیاز به برنامه ارائه می دهد . 

ابتدا یک پوشه cms را در جایی در وب سایت محلی روی رایانه خود ایجاد کنید تا تمام پرونده های مربوط به CMS را نگه دارید. اگر XAMPP را اجرا می کنید ، وب سایت محلی در پوشه htdocs در پوشه XAMPP شما قرار می گیرد. 

بعد از اینکار در مسیر پوشه اصلی پروژه CMS خود فایل config.php را ایجاد کنید و کد های زیر را درون این قایل قرار دهید :‌

<?php
ini_set( "display_errors", true );
date_default_timezone_set( "Asia/Tehran" );  // http://www.php.net/manual/en/timezones.php
define( "DB_DSN", "mysql:host=localhost;dbname=cms" );
define( "DB_USERNAME", "username" );
define( "DB_PASSWORD", "password" );
define( "CLASS_PATH", "classes" );
define( "TEMPLATE_PATH", "templates" );
define( "HOMEPAGE_NUM_ARTICLES", 5 );
define( "ADMIN_USERNAME", "admin" );
define( "ADMIN_PASSWORD", "mypass" );
require( CLASS_PATH . "/Article.php" );

function handleException( $exception ) {
  echo "Sorry, a problem occurred. Please try later.";
  error_log( $exception->getMessage() );
}

set_exception_handler( 'handleException' );

بیایید ببینیم در کد های بالا چه اتفاقی می افتد : 

خطاها را در مرورگر نمایش دهید

 تابع ini_set می تواند پیام های خطا در مرورگر را نمایش دهد. این تابع برای اشکالزدایی کد ها بسیار مناسب است ، اما باید در یک سایت در حال توسعه فعال شود و اگر برای همیشه این تابع فعال باشد  می تواند یک خطر امنیتی محسوب شود .

timezone محلی خود را فعال کنید
از آنجا که CMS ما از تابع  تاریخ PHP date() استفاده می کند ، باید منطقه زمانی سرور خود را تنظبم کنیم (در غیر این صورت PHP یک پیام هشدار دهنده ایجاد می کند). در اینجا Asia/Tehran تنظیم شده است - این مقدار را به منطقه زمانی محلی خود تغییر دهید.

اطلاعات پایگاه داده MySql را تعریف کنید 

برای اینکه برنامه مدیریت محتوا CMS ما بتواند به پایگاه داده ما متصل شود باید در این فایل اطلاعات اتصال به پایگاه داده خود را وارد کنیم برای اینکار از دو مقدار سراسری از پیش تعیین شده define مقدار دهی می کنیم یعنی دو مقدار سراسری : DB_USERNAME - DB_PASSWORD

تعریف آدرس های مخرن فایل های حیاتی

برای دسترسی به پوشه CLASS ها و پوشه پوسته های از دو مقدار سراسری  define استفاده می کنیم و آن ها را مقدار دهی می کنیم : CLASS_PATH - TEMPLATE_PATH

تعداد مقالات را برای نمایش در صفحه اصلی تنظیم کنید
برای این کار ما از تابع سراسری HOMEPAGE_NUM_ARTICLES استفاده می کنیم 

نام کاربری و رمزعبور مدیر را تنظیم کنید

اطلاعات ورود ادمین را برای ورود به داشبورد سایت در دو تابع سراسری مقابل وارد می کنیم :‌  ADMIN_USERNAME - ADMIN_PASSWORD

 

ایجاد یک کلاس برای توابع و فانکشن های PHP برای کنترل تمام قسمت های مقالات Article PHP class

اکنون می توانیم کلاس Article PHP را ایجاد کنید . این تنها کلاس در CMS ماست ، و آن را به خوبی کنترل می کند تا مقالات را در دیتابیس ذخیره کند ، همچنین می توانید مقالاتی را از پایگاه داده فراخوانی کنید. پس از ساختن این کلاس ، ایجاد و به روزرسانی ، بازیابی و حذف مقالات برای CMS ما بسیار آسان خواهد بود.

خب حالا یک پوشه به نام classes ایجاد کنید و داخل آن فایلی با نام Article.php درست کنید . حال کد های زیر را داخل آن قرار دهید :‌

<?php

/**
 * Class to handle articles
 */

class Article
{

  // Properties

  /**
  * @var int The article ID from the database
  */
  public $id = null;

  /**
  * @var int When the article was published
  */
  public $publicationDate = null;

  /**
  * @var string Full title of the article
  */
  public $title = null;

  /**
  * @var string A short summary of the article
  */
  public $summary = null;

  /**
  * @var string The HTML content of the article
  */
  public $content = null;


  /**
  * Sets the object's properties using the values in the supplied array
  *
  * @param assoc The property values
  */

  public function __construct( $data=array() ) {
    if ( isset( $data['id'] ) ) $this->id = (int) $data['id'];
    if ( isset( $data['publicationDate'] ) ) $this->publicationDate = (int) $data['publicationDate'];
    if ( isset( $data['title'] ) ) $this->title = preg_replace ( "/[^\.\,\-\_\'\"\@\?\!\:\$ a-zA-Z0-9()]/", "", $data['title'] );
    if ( isset( $data['summary'] ) ) $this->summary = preg_replace ( "/[^\.\,\-\_\'\"\@\?\!\:\$ a-zA-Z0-9()]/", "", $data['summary'] );
    if ( isset( $data['content'] ) ) $this->content = $data['content'];
  }


  /**
  * Sets the object's properties using the edit form post values in the supplied array
  *
  * @param assoc The form post values
  */

  public function storeFormValues ( $params ) {

    // Store all the parameters
    $this->__construct( $params );

    // Parse and store the publication date
    if ( isset($params['publicationDate']) ) {
      $publicationDate = explode ( '-', $params['publicationDate'] );

      if ( count($publicationDate) == 3 ) {
        list ( $y, $m, $d ) = $publicationDate;
        $this->publicationDate = mktime ( 0, 0, 0, $m, $d, $y );
      }
    }
  }


  /**
  * Returns an Article object matching the given article ID
  *
  * @param int The article ID
  * @return Article|false The article object, or false if the record was not found or there was a problem
  */

  public static function getById( $id ) {
    $conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
    $sql = "SELECT *, UNIX_TIMESTAMP(publicationDate) AS publicationDate FROM articles WHERE id = :id";
    $st = $conn->prepare( $sql );
    $st->bindValue( ":id", $id, PDO::PARAM_INT );
    $st->execute();
    $row = $st->fetch();
    $conn = null;
    if ( $row ) return new Article( $row );
  }


  /**
  * Returns all (or a range of) Article objects in the DB
  *
  * @param int Optional The number of rows to return (default=all)
  * @return Array|false A two-element array : results => array, a list of Article objects; totalRows => Total number of articles
  */

  public static function getList( $numRows=1000000 ) {
    $conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
    $sql = "SELECT SQL_CALC_FOUND_ROWS *, UNIX_TIMESTAMP(publicationDate) AS publicationDate FROM articles
            ORDER BY publicationDate DESC LIMIT :numRows";

    $st = $conn->prepare( $sql );
    $st->bindValue( ":numRows", $numRows, PDO::PARAM_INT );
    $st->execute();
    $list = array();

    while ( $row = $st->fetch() ) {
      $article = new Article( $row );
      $list[] = $article;
    }

    // Now get the total number of articles that matched the criteria
    $sql = "SELECT FOUND_ROWS() AS totalRows";
    $totalRows = $conn->query( $sql )->fetch();
    $conn = null;
    return ( array ( "results" => $list, "totalRows" => $totalRows[0] ) );
  }


  /**
  * Inserts the current Article object into the database, and sets its ID property.
  */

  public function insert() {

    // Does the Article object already have an ID?
    if ( !is_null( $this->id ) ) trigger_error ( "Article::insert(): Attempt to insert an Article object that already has its ID property set (to $this->id).", E_USER_ERROR );

    // Insert the Article
    $conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
    $sql = "INSERT INTO articles ( publicationDate, title, summary, content ) VALUES ( FROM_UNIXTIME(:publicationDate), :title, :summary, :content )";
    $st = $conn->prepare ( $sql );
    $st->bindValue( ":publicationDate", $this->publicationDate, PDO::PARAM_INT );
    $st->bindValue( ":title", $this->title, PDO::PARAM_STR );
    $st->bindValue( ":summary", $this->summary, PDO::PARAM_STR );
    $st->bindValue( ":content", $this->content, PDO::PARAM_STR );
    $st->execute();
    $this->id = $conn->lastInsertId();
    $conn = null;
  }


  /**
  * Updates the current Article object in the database.
  */

  public function update() {

    // Does the Article object have an ID?
    if ( is_null( $this->id ) ) trigger_error ( "Article::update(): Attempt to update an Article object that does not have its ID property set.", E_USER_ERROR );
   
    // Update the Article
    $conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
    $sql = "UPDATE articles SET publicationDate=FROM_UNIXTIME(:publicationDate), title=:title, summary=:summary, content=:content WHERE id = :id";
    $st = $conn->prepare ( $sql );
    $st->bindValue( ":publicationDate", $this->publicationDate, PDO::PARAM_INT );
    $st->bindValue( ":title", $this->title, PDO::PARAM_STR );
    $st->bindValue( ":summary", $this->summary, PDO::PARAM_STR );
    $st->bindValue( ":content", $this->content, PDO::PARAM_STR );
    $st->bindValue( ":id", $this->id, PDO::PARAM_INT );
    $st->execute();
    $conn = null;
  }


  /**
  * Deletes the current Article object from the database.
  */

  public function delete() {

    // Does the Article object have an ID?
    if ( is_null( $this->id ) ) trigger_error ( "Article::delete(): Attempt to delete an Article object that does not have its ID property set.", E_USER_ERROR );

    // Delete the Article
    $conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
    $st = $conn->prepare ( "DELETE FROM articles WHERE id = :id LIMIT 1" );
    $st->bindValue( ":id", $this->id, PDO::PARAM_INT );
    $st->execute();
    $conn = null;
  }

}

درست است که حجم کدهای بالا بسیار زیاد است ولی اصلا گیج کننده نیست کافیست هر بخش را جدا سازی کنید تا وظیفه آن بخش برای شما آشکار شود : 

  • constructor برای استفاده و اجرا بلادرنگ بعضی از کد ها که همیشه در زمان فراخوانی این فایل اجرا شود . بعضی از عملیات های تمیز سازی اطلاعات ورودی را در صورت وجود انجام می دهد تا مشکلات زیاد دیگر به خصوص مشکلات امنیتی بر نخورید - منضور همان توابع داخل constructor است  .
  • storeFormValues با استفاده از مقادیر ارسال فرم ، ویژگی های شی را تنظیم می کند   
  • getById با استفاده از این تابع ما می توانیم اطلاعات مقاله را بر حسب ID مقاله دریافت کنیم 
  • getList کلیه موارد (یا طیف وسیعی از) مقاله را در DB باز می گرداند 
  • insert وظبفه ذخیره اطلاعات ارسالی شما که همان اطلاعات مقاله را در بر می گیرد را در پایگاه داده ثبت کند 
  • update وظیفه آپدیت کردن اطلاعاتی که قبلا بر روی دیتا بیس را دارد 
  • delete وظیفه پاک کردن مقالات انتخابی شما را دارد 

ساخت بخش front-end (نمایشی - سمت کاربر) برنامه مدیریت محتوا CMS

خب ما تا اینجا بخش سمت سرور تجزیه و تحلیل محتوا و یا همان مقالات را با هم ایجاد کرده ایم و حالا نوبت بخش نمایش محتوا است . برای اینکه بتوانیم یک صفحه خانه برای سایت و یا همان CMS خود داشته باشیم باید فایلی به نام index.php ایجاد کنیم . این فایل را در پوشه اصلی پروژه مان ایجاد می کنیم .

حالا کد هایی زیر را درون این فایل قرار می دهیم :

<?php

require( "config.php" );
$action = isset( $_GET['action'] ) ? $_GET['action'] : "";

switch ( $action ) {
  case 'archive':
    archive();
    break;
  case 'viewArticle':
    viewArticle();
    break;
  default:
    homepage();
}


function archive() {
  $results = array();
  $data = Article::getList();
  $results['articles'] = $data['results'];
  $results['totalRows'] = $data['totalRows'];
  $results['pageTitle'] = "Article Archive | Widget News";
  require( TEMPLATE_PATH . "/archive.php" );
}

function viewArticle() {
  if ( !isset($_GET["articleId"]) || !$_GET["articleId"] ) {
    homepage();
    return;
  }

  $results = array();
  $results['article'] = Article::getById( (int)$_GET["articleId"] );
  $results['pageTitle'] = $results['article']->title . " | Widget News";
  require( TEMPLATE_PATH . "/viewArticle.php" );
}

function homepage() {
  $results = array();
  $data = Article::getList( HOMEPAGE_NUM_ARTICLES );
  $results['articles'] = $data['results'];
  $results['totalRows'] = $data['totalRows'];
  $results['pageTitle'] = "Widget News";
  require( TEMPLATE_PATH . "/homepage.php" );
}

بیایید کد های بالا را با هم مرور کنیم : 

درون ریزی قایل تنظیمات CMS  - config file

خط اول کد شامل پرونده config.php است که قبلاً ایجاد کردیم ، به طوری که کلیه تنظیمات پیکربندی در دسترس اسکریپت باشد . برای این کار می توانیم تابع های زیر استفاده می کنیم : 

include();
require();

 پارامتر های ارسالی را دریافت می کنیم 

ما برای اینکه بتوانیم پارامتر هایی که از سمت داشبورد برای ما ارسال می شود را دریافت کنیم و آن ها را ذخیره کنیم از پارامتر زیر استفاده می کنیم : 

 $_GET['action']
این پارامتر را درون متغیر زیر میریزیم 
$action
و برای اینکه مطمين شویم که این مقدار خالی نباشد از تابع زیر استفاده می کنیم 
isset( $_GET['action'] )

یک برنامه نویس خوب همیشه جک می کند که اگر مقدار وجود داشت کدش اجرا شود و همینطور بیمورد کامپایلر را درگیر خود نکند .

 

فانکشن archive

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

فانکشن viewArticle

این تابع تمام اطلاعات هر مقاله خاص را با استفاده از articleId دریافت و برای استفاده آماده می کند 

فانکشن homepage

تمام تنظیمات مربوط به نمایش مقالات به همراه تمام اطلاعات دریافتی محتواهای نمایشی را دریافت می کند و به بخش نمایشی پاس میدهد تا اطلاعات نمایش داده شود .

ایحاد قسمت back-end برای داشبود مدیریت با قایل admin.php

در این بخش ما باید تمام دسترسی های مدیریت CMS خود را تعریف کنیم تا CMS ما به خوبی مدیریت و محتوا های ما به راحتی در سایت قرار بگیرد .

یک فایل با نام admin.php در پوشه اصلی CMS خود ایجاد می کنیم و کد های زیر را درون آن قرار می دهیم : 

<?php

require( "config.php" );
session_start();
$action = isset( $_GET['action'] ) ? $_GET['action'] : "";
$username = isset( $_SESSION['username'] ) ? $_SESSION['username'] : "";

if ( $action != "login" && $action != "logout" && !$username ) {
  login();
  exit;
}

switch ( $action ) {
  case 'login':
    login();
    break;
  case 'logout':
    logout();
    break;
  case 'newArticle':
    newArticle();
    break;
  case 'editArticle':
    editArticle();
    break;
  case 'deleteArticle':
    deleteArticle();
    break;
  default:
    listArticles();
}


function login() {

  $results = array();
  $results['pageTitle'] = "Admin Login | Widget News";

  if ( isset( $_POST['login'] ) ) {

    // User has posted the login form: attempt to log the user in

    if ( $_POST['username'] == ADMIN_USERNAME && $_POST['password'] == ADMIN_PASSWORD ) {

      // Login successful: Create a session and redirect to the admin homepage
      $_SESSION['username'] = ADMIN_USERNAME;
      header( "Location: admin.php" );

    } else {

      // Login failed: display an error message to the user
      $results['errorMessage'] = "Incorrect username or password. Please try again.";
      require( TEMPLATE_PATH . "/admin/loginForm.php" );
    }

  } else {

    // User has not posted the login form yet: display the form
    require( TEMPLATE_PATH . "/admin/loginForm.php" );
  }

}


function logout() {
  unset( $_SESSION['username'] );
  header( "Location: admin.php" );
}


function newArticle() {

  $results = array();
  $results['pageTitle'] = "New Article";
  $results['formAction'] = "newArticle";

  if ( isset( $_POST['saveChanges'] ) ) {

    // User has posted the article edit form: save the new article
    $article = new Article;
    $article->storeFormValues( $_POST );
    $article->insert();
    header( "Location: admin.php?status=changesSaved" );

  } elseif ( isset( $_POST['cancel'] ) ) {

    // User has cancelled their edits: return to the article list
    header( "Location: admin.php" );
  } else {

    // User has not posted the article edit form yet: display the form
    $results['article'] = new Article;
    require( TEMPLATE_PATH . "/admin/editArticle.php" );
  }

}


function editArticle() {

  $results = array();
  $results['pageTitle'] = "Edit Article";
  $results['formAction'] = "editArticle";

  if ( isset( $_POST['saveChanges'] ) ) {

    // User has posted the article edit form: save the article changes

    if ( !$article = Article::getById( (int)$_POST['articleId'] ) ) {
      header( "Location: admin.php?error=articleNotFound" );
      return;
    }

    $article->storeFormValues( $_POST );
    $article->update();
    header( "Location: admin.php?status=changesSaved" );

  } elseif ( isset( $_POST['cancel'] ) ) {

    // User has cancelled their edits: return to the article list
    header( "Location: admin.php" );
  } else {

    // User has not posted the article edit form yet: display the form
    $results['article'] = Article::getById( (int)$_GET['articleId'] );
    require( TEMPLATE_PATH . "/admin/editArticle.php" );
  }

}


function deleteArticle() {

  if ( !$article = Article::getById( (int)$_GET['articleId'] ) ) {
    header( "Location: admin.php?error=articleNotFound" );
    return;
  }

  $article->delete();
  header( "Location: admin.php?status=articleDeleted" );
}


function listArticles() {
  $results = array();
  $data = Article::getList();
  $results['articles'] = $data['results'];
  $results['totalRows'] = $data['totalRows'];
  $results['pageTitle'] = "All Articles";

  if ( isset( $_GET['error'] ) ) {
    if ( $_GET['error'] == "articleNotFound" ) $results['errorMessage'] = "Error: Article not found.";
  }

  if ( isset( $_GET['status'] ) ) {
    if ( $_GET['status'] == "changesSaved" ) $results['statusMessage'] = "Your changes have been saved.";
    if ( $_GET['status'] == "articleDeleted" ) $results['statusMessage'] = "Article deleted.";
  }

  require( TEMPLATE_PATH . "/admin/listArticles.php" );
}

 

ساختن بخش front-end - پوسته CMS  

اکنون همه عملکردهای PHP را برای عملکرد CMS ایجاد کرده ایم. مرحله بعدی ایجاد الگوهای HTML برای بخش نمایشی به کاربر است.

ایجاد فایل های مربوط به پوسته 

ساخت فایل  header.php درون پوشه اصلی :

<!DOCTYPE html>
<html lang="en">
  <head>
    <title><?php echo htmlspecialchars( $results['pageTitle'] )?></title>
    <link rel="stylesheet" type="text/css" href="style.css" />
  </head>
  <body>
    <div id="container">

      <a href="."><img id="logo" src="images/logo.jpg" alt="Widget News" /></a>

ایجاد فایل footer.php در مسیر پوشه اصلی : 

      <div id="footer">
        Widget News &copy; 2020. All rights reserved. <a href="admin.php">Site Admin</a>
      </div>

    </div>
  </body>
</html>

خب تا اینجا ما قسمت های HTML پوسته - بالا و پایین سایت - head و footer را ایجاد کرده ایم و با کد های PHP مربوطه ترکیب کرده ایم .

و حالا نوبت بدنه اصلی یعنی homepage.php است برای اینکار این قایل را در پوشه اصلی ایجاد و کد های زیر را در آن قرار می دهیم : 

<?php include "templates/include/header.php" ?>

      <ul id="headlines">

<?php foreach ( $results['articles'] as $article ) { ?>

        <li>
          <h2>
            <span class="pubDate"><?php echo date('j F', $article->publicationDate)?></span><a href=".?action=viewArticle&amp;articleId=<?php echo $article->id?>"><?php echo htmlspecialchars( $article->title )?></a>
          </h2>
          <p class="summary"><?php echo htmlspecialchars( $article->summary )?></p>
        </li>

<?php } ?>

      </ul>

      <p><a href="./?action=archive">Article Archive</a></p>

<?php include "templates/include/footer.php" ?>

ایجاد بخش آرشیو مقالات برای دسترسی به تمام مقالات موجود سایت - archive.php

برای اینکار فایلی در پوشه اصلی با نام archive.php ایجاد می کنیم و کد های زیر را درون آن قرار می دهیم :

<?php include "templates/include/header.php" ?>

      <h1>Article Archive</h1>

      <ul id="headlines" class="archive">

<?php foreach ( $results['articles'] as $article ) { ?>

        <li>
          <h2>
            <span class="pubDate"><?php echo date('j F Y', $article->publicationDate)?></span><a href=".?action=viewArticle&amp;articleId=<?php echo $article->id?>"><?php echo htmlspecialchars( $article->title )?></a>
          </h2>
          <p class="summary"><?php echo htmlspecialchars( $article->summary )?></p>
        </li>

<?php } ?>

      </ul>

      <p><?php echo $results['totalRows']?> article<?php echo ( $results['totalRows'] != 1 ) ? 's' : '' ?> in total.</p>

      <p><a href="./">Return to Homepage</a></p>

<?php include "templates/include/footer.php" ?>

ایجاد بخش صفحه اختصاصی برای هر مطلب viewArticle.php

فایل viewArticle.php را در مسیر پوشه اصلی پروژه ایجاد می کنیم : 

<?php include "templates/include/header.php" ?>

      <h1 style="width: 75%;"><?php echo htmlspecialchars( $results['article']->title )?></h1>
      <div style="width: 75%; font-style: italic;"><?php echo htmlspecialchars( $results['article']->summary )?></div>
      <div style="width: 75%;"><?php echo $results['article']->content?></div>
      <p class="pubDate">Published on <?php echo date('j F Y', $results['article']->publicationDate)?></p>

      <p><a href="./">Return to Homepage</a></p>

<?php include "templates/include/footer.php" ?>

ایجاد بخش اصلی مدیریتی پروژه 

یک پوشه به نام admin ایجاد می کنیم و سه فایل زیر را درون آن ایجاد می کنیم

بخش ورود - loginForm.php

فایل loginForm.php را ایجاد و کد های زیر را درون آن قرار می دهیم : 

<?php include "templates/include/header.php" ?>

      <form action="admin.php?action=login" method="post" style="width: 50%;">
        <input type="hidden" name="login" value="true" />

<?php if ( isset( $results['errorMessage'] ) ) { ?>
        <div class="errorMessage"><?php echo $results['errorMessage'] ?></div>
<?php } ?>

        <ul>

          <li>
            <label for="username">Username</label>
            <input type="text" name="username" id="username" placeholder="Your admin username" required autofocus maxlength="20" />
          </li>

          <li>
            <label for="password">Password</label>
            <input type="password" name="password" id="password" placeholder="Your admin password" required maxlength="20" />
          </li>

        </ul>

        <div class="buttons">
          <input type="submit" name="login" value="Login" />
        </div>

      </form>

<?php include "templates/include/footer.php" ?>

مدیریت مقالات در بخش داشبورد  listArticles.php

برای این بخش فایل listArticles.php را ایجاد می کنیم : 

<?php if ( isset( $results['errorMessage'] ) ) { ?>
        <div class="errorMessage"><?php echo $results['errorMessage'] ?></div>
<?php } ?>


<?php if ( isset( $results['statusMessage'] ) ) { ?>
        <div class="statusMessage"><?php echo $results['statusMessage'] ?></div>
<?php } ?>

      <table>
        <tr>
          <th>Publication Date</th>
          <th>Article</th>
        </tr>

<?php foreach ( $results['articles'] as $article ) { ?>

        <tr onclick="location='admin.php?action=editArticle&amp;articleId=<?php echo $article->id?>'">
          <td><?php echo date('j M Y', $article->publicationDate)?></td>
          <td>
            <?php echo $article->title?>
          </td>
        </tr>

<?php } ?>

      </table>

      <p><?php echo $results['totalRows']?> article<?php echo ( $results['totalRows'] != 1 ) ? 's' : '' ?> in total.</p>

      <p><a href="admin.php?action=newArticle">Add a New Article</a></p>

<?php include "templates/include/footer.php" ?>

ایجاد بخش ویرایش مقالات - editArticle.php

برای این کار فایل editArticle.php را ایجاد می کنیم : 

<?php include "templates/include/header.php" ?>

      <div id="adminHeader">
        <h2>Widget News Admin</h2>
        <p>You are logged in as <b><?php echo htmlspecialchars( $_SESSION['username']) ?></b>. <a href="admin.php?action=logout"?>Log out</a></p>
      </div>

      <h1><?php echo $results['pageTitle']?></h1>

      <form action="admin.php?action=<?php echo $results['formAction']?>" method="post">
        <input type="hidden" name="articleId" value="<?php echo $results['article']->id ?>"/>

<?php if ( isset( $results['errorMessage'] ) ) { ?>
        <div class="errorMessage"><?php echo $results['errorMessage'] ?></div>
<?php } ?>

        <ul>

          <li>
            <label for="title">Article Title</label>
            <input type="text" name="title" id="title" placeholder="Name of the article" required autofocus maxlength="255" value="<?php echo htmlspecialchars( $results['article']->title )?>" />
          </li>

          <li>
            <label for="summary">Article Summary</label>
            <textarea name="summary" id="summary" placeholder="Brief description of the article" required maxlength="1000" style="height: 5em;"><?php echo htmlspecialchars( $results['article']->summary )?></textarea>
          </li>

          <li>
            <label for="content">Article Content</label>
            <textarea name="content" id="content" placeholder="The HTML content of the article" required maxlength="100000" style="height: 30em;"><?php echo htmlspecialchars( $results['article']->content )?></textarea>
          </li>

          <li>
            <label for="publicationDate">Publication Date</label>
            <input type="date" name="publicationDate" id="publicationDate" placeholder="YYYY-MM-DD" required maxlength="10" value="<?php echo $results['article']->publicationDate ? date( "Y-m-d", $results['article']->publicationDate ) : "" ?>" />
          </li>


        </ul>

        <div class="buttons">
          <input type="submit" name="saveChanges" value="Save Changes" />
          <input type="submit" formnovalidate name="cancel" value="Cancel" />
        </div>

      </form>

<?php if ( $results['article']->id ) { ?>
      <p><a href="admin.php?action=deleteArticle&amp;articleId=<?php echo $results['article']->id ?>" onclick="return confirm('Delete This Article?')">Delete This Article</a></p>
<?php } ?>

<?php include "templates/include/footer.php" ?>

ایجاد فایل استایل پوسته و قرار گیری لوگو سایت در آن  - style.css

برای اینکه تغیرات نهایی را بدهیم و دستی بر سر و روی پروژه بکشیم در مسیر و پوشه اصلی پروژه فایل style.css را ایجاد می کنیم : 

/* Style the body and outer container */

body {
  margin: 0;
  color: #333;
  background-color: #00a0b0;
  font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
  line-height: 1.5em;
}

#container {
  width: 960px;
  background: #fff;
  margin: 20px auto;
  padding: 20px;
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
  border-radius: 5px;
}


/* The logo and footer */

#logo {
  display: block;
  width: 300px;
  padding: 0 660px 20px 0;
  border: none;
  border-bottom: 1px solid #00a0b0;
  margin-bottom: 40px;
}

#footer {
  border-top: 1px solid #00a0b0;
  margin-top: 40px;
  padding: 20px 0 0 0;
  font-size: .8em;
}


/* Headings */

h1 {
  color: #eb6841;
  margin-bottom: 30px;
  line-height: 1.2em;
}

h2, h2 a {
  color: #edc951;
}

h2 a {
  text-decoration: none;
}


/* Article headlines */

#headlines {
  list-style: none;
  padding-left: 0;
  width: 75%;
}

#headlines li {
  margin-bottom: 2em;
}

.pubDate {
  font-size: .8em;
  color: #eb6841;
  text-transform: uppercase;
}

#headlines .pubDate {
  display: inline-block;
  width: 100px;
  font-size: .5em;
  vertical-align: middle;
}

#headlines.archive .pubDate {
  width: 130px;
}

.summary {
  padding-left: 100px;
}

#headlines.archive .summary {
  padding-left: 130px;
}


/* "You are logged in..." header on admin pages */

#adminHeader {
  width: 940px;
  padding: 0 10px;
  border-bottom: 1px solid #00a0b0;
  margin: -30px 0 40px 0;
  font-size: 0.8em;
}


/* Style the form with a coloured background, along with curved corners and a drop shadow */

form {
  margin: 20px auto;
  padding: 40px 20px;
  overflow: auto;
  background: #fff4cf;
  border: 1px solid #666;
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;  
  border-radius: 5px;
  -moz-box-shadow: 0 0 .5em rgba(0, 0, 0, .8);
  -webkit-box-shadow: 0 0 .5em rgba(0, 0, 0, .8);
  box-shadow: 0 0 .5em rgba(0, 0, 0, .8);
}


/* Give form elements consistent margin, padding and line height */

form ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

form ul li {
  margin: .9em 0 0 0;
  padding: 0;
}

form * {
  line-height: 1em;
}


/* The field labels */

label {
  display: block;
  float: left;
  clear: left;
  text-align: right;
  width: 15%;
  padding: .4em 0 0 0;
  margin: .15em .5em 0 0;
}


/* The fields */

input, select, textarea {
  display: block;
  margin: 0;
  padding: .4em;
  width: 80%;
}

input, textarea, .date {
  border: 2px solid #666;
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;    
  border-radius: 5px;
  background: #fff;
}

input {
  font-size: .9em;
}

select {
  padding: 0;
  margin-bottom: 2.5em;
  position: relative;
  top: .7em;
}

textarea {
  font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
  font-size: .9em;
  height: 5em;
  line-height: 1.5em;
}

textarea#content {
  font-family: "Courier New", courier, fixed;
}
  

/* Place a border around focused fields */

form *:focus {
  border: 2px solid #7c412b;
  outline: none;
}


/* Display correctly filled-in fields with a green background */

input:valid, textarea:valid {
  background: #efe;
}


/* Submit buttons */

.buttons {
  text-align: center;
  margin: 40px 0 0 0;
}

input[type="submit"] {
  display: inline;
  margin: 0 20px;
  width: 12em;
  padding: 10px;
  border: 2px solid #7c412b;
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;  
  border-radius: 5px;
  -moz-box-shadow: 0 0 .5em rgba(0, 0, 0, .8);
  -webkit-box-shadow: 0 0 .5em rgba(0, 0, 0, .8);
  box-shadow: 0 0 .5em rgba(0, 0, 0, .8);
  color: #fff;
  background: #ef7d50;
  font-weight: bold;
  -webkit-appearance: none;
}

input[type="submit"]:hover, input[type="submit"]:active {
  cursor: pointer;
  background: #fff;
  color: #ef7d50;
}

input[type="submit"]:active {
  background: #eee;
  -moz-box-shadow: 0 0 .5em rgba(0, 0, 0, .8) inset;
  -webkit-box-shadow: 0 0 .5em rgba(0, 0, 0, .8) inset;
  box-shadow: 0 0 .5em rgba(0, 0, 0, .8) inset;
}


/* Tables */

table {
  width: 100%;
  border-collapse: collapse;
}

tr, th, td {
  padding: 10px;
  margin: 0;
  text-align: left;
}

table, th {
  border: 1px solid #00a0b0;
}

th {
  border-left: none;
  border-right: none;
  background: #ef7d50;
  color: #fff;
  cursor: default;
}

tr:nth-child(odd) {
  background: #fff4cf;
}

tr:nth-child(even) {
  background: #fff;
}

tr:hover {
  background: #ddd;
  cursor: pointer;
}


/* Status and error boxes */

.statusMessage, .errorMessage {
  font-size: .8em;
  padding: .5em;
  margin: 2em 0;
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
  border-radius: 5px; 
  -moz-box-shadow: 0 0 .5em rgba(0, 0, 0, .8);
  -webkit-box-shadow: 0 0 .5em rgba(0, 0, 0, .8);
  -box-shadow: 0 0 .5em rgba(0, 0, 0, .8);
}

.statusMessage {
  background-color: #2b2;
  border: 1px solid #080;
  color: #fff;
}

.errorMessage {
  background-color: #f22;
  border: 1px solid #800;
  color: #fff;
}

برای تغیر لوگو سایت نام لوگو را که قبلا فایلش را در پوشه اصلی ریخته اید تغیر دهید : logo.jpg

خب همه چی تموم شد !

دانلود تمام این پروژه آموزشی

 رمز : E4pY1nQ0vWK7UT6TtfUvBX1vfqKVOqU1APKFH7aI3Ms

اطلاعات این دوره آموزش
ساخت یک سیستم مدیریت محتوا (CMS) اختصاصی با PHP

قیمت : 0 تومان

زمان : 00:00:00

بالا