ساخت یک سیستم مدیریت محتوای ساده (CMS):
حال با هم یک CMS بسیار ساده میسازیم، cms ما دارای دو بخش اصلی است. قسمت عمومی public area و قسمت ادمین admin area، به قسمت عمومی همه دسترسی دارند اما برای ورود به قسمت ادمین باید یوزرنیم و پسورد داشته باشند، درقسمت ادمین میتوان محتوا و همینطور admin یا admin ها را مدیریت کرد.
ابتدا دیتابیس را ایجاد میکنیم .
در قسمتهای قبل subjecs و pages را ساختیم جدول دیگری که باید بسازیم admins میباشد که دارای id،username و hashedPassword است.
بیاید جدول admin را ایجاد کنیم. با یوزر darkoob_cms که با هم ساختیم وارد mysql میشویم و جدولمان رامیسازیم.
حالا فایلها و فولدرهای خود را ایجاد میکنیم، پوشهای به نام darkoobweb میسازیم داخل آن دو پوشه به نام های includes و public ایجاد میکنیم داخل public سه پوشه و 3 فایل به نامهای css,images,js,admin.php,index.php,manageContent.php میسازیم، در داخل includes هم یک پوشه به نام layouts میسازیم، که داخل آن footer.php و header.php قرار میدهیم، درون این دو فایل کدهای html مربوط به footer و header را مینویسیم.
Header.php
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Darkoobweb.com</title> <link rel="stylesheet" href="css/public.css" media="all" type="text/css"> </head> <body> <div id="header"> <h1>DarkoobWeb</h1> </div> Footer.php <div id="footer">Copyright 2016, Darkoobweb.com</div> </body> </html>
در پوشه includes فایل functions.php را میسازیم، بعد در این فایل کدهای مورد نیاز را خواهیم نوشت.
خوب بیایید ظاهر admin.php را درست کنیم :
<?php include ('../includes/layouts/header.php'); ?> <div id="main"> <div id="navigation"> </div> <div id="page"> <h2>Admin Menu</h2> <p>Welcome to the admin area.</p> <ul> <li><a href="manageContent.php">Manage Website Content</a></li> <li><a href="manageAdmin.php">Manage Admin User</a></li> <li><a href="logout.php">Logout</a></li> </ul> </div> </div> <?php include ('../includes/layouts/footer.php'); ?>
اگر به این صفحه مراجعه کنید، باید به آدرس http://localhost/darkoobweb/public/admin.php برویم. صفحه html ای را میبینید اما زیبا نیست، پس فایلی به نام public.css در داخل پوشه css که در پوشه public وجود دارد ایجاد میکنیم شما میتوانید فایل css نوشته شده خود را قرار دهید.
html { height: 100%; width: 100% } body { width: 100%; height: 100%; margin: 0; padding: 0; border: 0; font-family: Verdana, Arial, sans-serif; font-size: 13px; line-height: 15px; } img { border: none; } a { color: #A2AB58; } a:hover { color: #67BCDB; } #header { height: 70px; margin: 0; padding: 0; text-align: left; background: #67BCDB; color: #FFFFFF; } #header h1 { padding: 1em; margin: 0; } #main { height: 600px; width: 100%; margin: 0; padding: 0; background: #FFFFFF; } #footer { clear: both; height:2em; margin:0; padding: 1em; text-align: center; background: #67BCDB; color: #FFFFFF; } #navigation{ float: left; width:150px; height: 100%; margin:0; padding:0 2em; color: #FFFFFF; background: #A2AB58; } #navigation a { color: #FFFFFF; text-decoration: none; } #navigation a:hover{ color: #E44424; } ul.subjects{ margin:1em 0; padding-left: 0; list-style: none; } .selected{ font-weight: bold; } #page{ float: left; height: 100%; padding-left:2em; vertical-align: top; background: #FFFFFF; } #page h2{ color:#E44424; margin-top: 1em; } #page h3{ color: #E44424; }
حال صفحه را رفرش کنید، میبینید ظاهر سایت بهتر شد است.
کدهای content.php نیز مانند admin.php خواهد بود با کمی تفاوت:
<?php require_once ('../includes/functions.php');?> <?php include ('../includes/layouts/header.php');?> <div id="main"> <div id="navigation"> </div> <div id="page"> <h2>Manage Content</h2> </div> </div> <?php include ('../includes/layouts/footer.php');?>
ظاهر را کمی مرتب کردایم، اکنون وقت آن است که به دیتابیس متصل شویم.
اتصال به دیتابیس:
برای اتصال به دیتابیس مانند کدی که در بخش (چگونه با php به MySql متصل شویم ) نوشتیم عمل میکنیم. البته با کمی تفاوت و آن تفاوت این است که دیگر کدهای اتصال را در تک تک صفحاتی که نیاز دارند وارد نمیکنیم بلکه فایلی به نام dbConnection.php در پوشه includes میسازیم و کدهای اتصال را در آن قسمت وارد میکنیم :
<?php define('DB_SERVER','localhost'); define('DB_USER','darkoob_cms'); define('DB_PASS','darkoob123'); define('DB_NAME','darkoob_web'); $connection = mysqli_connect(DB_SERVER, DB_USER, DB_PASS, DB_NAME); if (mysqli_connect_errno()) { die('Database connection failed: ' . mysqli_connect_error() . '(' . mysqli_connect_errno() . ')'); }
در footer.php هم مانند قبل بعد از اتمام کار با دیتابیس connection را میبندیم .
Footer.php
<div id="footer">Copyright 2016, Darkoobweb.com</div> </body> </html> <?php if(isset($connection)) { mysqli_close($connection); }
این هم از footer .
اگر به یاد داشته باشید ما کویری را مینوشتیم، سپس چک میکردیم آیا کویری اجرا شده است؟ یا با خطا رو به رو شده است؟
برای آن یک فانکشن در function.php مینویسسم و مانند کد بخش قبل عمل نخواهیم کرد.
Function.php
<?php function confirmQuery($resultSet) { if (!$resultSet) { die('Database query failed'); } } حالا نوبت آن است تا admin.php و content.php را تغییر دهیم . Admin.php <?php require_once ('../includes/dbConnection.php');?> <?php require_once('../includes/functions.php'); ?> <?php $query = 'SELECT * FROM subjects WHERE visible=1 ORDER BY POSITION ASC'; $result = mysqli_query($connection, $query); confirmQuery($result); ?> <?php include('../includes/layouts/header.php'); ?> <div id="main"> <div id="navigation"> <ul class="subjects"> <?php while ($subject = mysqli_fetch_assoc($result)) { ?> <li><?php echo $subject['menuName'] . '(' . $subject['id'] . ')'; ?></li> <hr/> <?php } ?> </ul> </div> <div id="page"> <h2>Admin Menu</h2> <p>Welcome to the admin area.</p> <ul> <li><a href="manageContent.php">Manage Website Content</a></li> <li><a href="manageAdmin.php">Manage Admin User</a></li> <li><a href="logout.php">Logout</a></li> </ul> </div> </div> <?php mysqli_free_result($result); ?> <?php include('../includes/layouts/footer.php'); ?> Content.php <?php require_once ('../includes/dbConnection.php');?> <?php require_once('../includes/functions.php'); ?> <?php $query = 'SELECT * FROM subjects WHERE visible=1 ORDER BY POSITION ASC'; $result = mysqli_query($connection, $query); confirmQuery($result); ?> <?php include('../includes/layouts/header.php'); ?> <div id="main"> <div id="navigation"> <ul class="subjects"> <?php while ($subject = mysqli_fetch_assoc($result)) { ?> <li><?php echo $subject['menuName'] . '(' . $subject['id'] . ')'; ?></li> <hr/> <?php } ?> </ul> </div> <div id="page"> <h2>Manage Content</h2> </div> </div> <?php mysqli_free_result($result); ?> <?php include('../includes/layouts/footer.php'); ?>
صفحه را رفرش کنید، باید سمت چب منوی خود را ببینید.
کامل کردن navigation :
همان طور که میبینید فقط نام منو را میبینیم و زیر منوها را نمیتوان دید، زیر منوها را در دیتابیس در جدول pages ساختیم.حتما به یاد دارید!
برای اینکه زیر منوها را نمایش دهیم، به یک حلقه while دیگر درون حلقه while که نام منوها را نمایش میدهد نیاز داریم به کد زیر دقت کنید.
Admin.php
<?php require_once('../includes/dbConnection.php'); ?> <?php require_once('../includes/functions.php'); ?> <?php include('../includes/layouts/header.php'); ?> <div id="main"> <div id="navigation"> <ul class="subjects"> <?php $query = 'SELECT * FROM subjects WHERE visible=1 ORDER BY POSITION ASC'; $result = mysqli_query($connection, $query); confirmQuery($result); while ($subject = mysqli_fetch_assoc($result)) { ?> <li> <?php echo $subject['menuName']; ?> <?php $query = "SELECT * FROM pages WHERE visible=1 AND subjectId = {$subject['id']} ORDER BY POSITION ASC"; $pageSet = mysqli_query($connection, $query); confirmQuery($pageSet); ?> <ul class="pages"> <?php while ($page = mysqli_fetch_assoc($pageSet)) { ?> <li> <?php echo $page['menuName']; ?> </li> <?php } ?> <?php mysqli_free_result($pageSet); ?> </ul> </li> <hr/> <?php } ?> <?php mysqli_free_result($result); ?> </ul> </div> <div id="page"> <h2>Admin Menu</h2> <p>Welcome to the admin area.</p> <ul> <li><a href="manageContent.php">Manage Website Content</a></li> <li><a href="manageAdmin.php">Manage Admin User</a></li> <li><a href="logout.php">Logout</a></li> </ul> </div> </div> <?php include('../includes/layouts/footer.php'); ?> manageContent.php <?php require_once ('../includes/dbConnection.php');?> <?php require_once('../includes/functions.php'); ?> <?php include('../includes/layouts/header.php'); ?> <div id="main"> <div id="navigation"> <ul class="subjects"> <?php $query = 'SELECT * FROM subjects WHERE visible=1 ORDER BY POSITION ASC'; $result = mysqli_query($connection, $query); confirmQuery($result); while ($subject = mysqli_fetch_assoc($result)) { ?> <li> <?php echo $subject['menuName']; ?> <?php $query = "SELECT * FROM pages WHERE visible=1 AND subjectId = {$subject['id']} ORDER BY POSITION ASC"; $pageSet = mysqli_query($connection, $query); confirmQuery($pageSet); ?> <ul class="pages"> <?php while ($page = mysqli_fetch_assoc($pageSet)) { ?> <li> <?php echo $page['menuName']; ?> </li> <?php } ?> <?php mysqli_free_result($pageSet); ?> </ul> </li> <hr/> <?php } ?> <?php mysqli_free_result($result); ?> </ul> </div> <div id="page"> <h2>Manage Content</h2> </div> </div> <?php mysqli_free_result($result); ?> <?php include('../includes/layouts/footer.php'); ?>
Refactoring :
اگر دقت کرده باشید کدهای بالا طولانی و شلوغ است همین طورممکن است صفحات دیگری هم داشته باشیم که نیاز به منو داشته باشند، در این صورت مجبوریم دوباره کویریهای خود را داخل هر صفحه بنویسم برای اینکه کد تمیزتری داشته باشم، همچنین نیاز نباشد هردفعه کد طولانی بنویسم میتوانیم در function.php برای کدهایی که ممکن است زیاد تکرار شوند فانکشنهایی تعریف کرده و از آن فانکشنها استفاده کنیم.
دو فانکشن در function.php برای گرفتن subject و گرفتن page ها میسازیم و کدهای خود را در آن کپی میکنیم .
Function.php
<?php function confirmQuery($resultSet) { if (!$resultSet) { die('Database query failed'); } } function findAllSubjects(){ global $connection; $query = 'SELECT * FROM subjects WHERE visible=1 ORDER BY POSITION ASC'; $result = mysqli_query($connection, $query); confirmQuery($result); return $result; } function findPagesForSubject($subjectId){ global $connection; $query = "SELECT * FROM pages WHERE visible=1 AND subjectId = {$subjectId} ORDER BY POSITION ASC"; $pageSet = mysqli_query($connection, $query); confirmQuery($pageSet); return $pageSet; }
دقیقا همان کدهای قبل است با این تفاوت که باید pageSet و result را return کنیم. همچنین در فانکشن findPagesForSubject باید مقدار subject id را به عنوان ورودی دریافت کنیم .
و این هم تغییرات در کدهای admin.php و manageContent.php
Admin.php :
<?php require_once('../includes/dbConnection.php'); ?> <?php require_once('../includes/functions.php'); ?> <?php include('../includes/layouts/header.php'); ?> <div id="main"> <div id="navigation"> <ul class="subjects"> <?php $result = findAllSubjects(); while ($subject = mysqli_fetch_assoc($result)) { ?> <li> <?php echo $subject['menuName']; ?> <?php $pageSet = findPagesForSubject($subject['id']); ?> <ul class="pages"> <?php while ($page = mysqli_fetch_assoc($pageSet)) { ?> <li><?php echo $page['menuName']; ?></li> <?php } ?> <?php mysqli_free_result($pageSet); ?> </ul> </li> <hr/> <?php } ?> <?php mysqli_free_result($result); ?> </ul> </div> <div id="page"> <h2>Admin Menu</h2> <p>Welcome to the admin area.</p> <ul> <li><a href="manageContent.php">Manage Website Content</a></li> <li><a href="manageAdmin.php">Manage Admin User</a></li> <li><a href="logout.php">Logout</a></li> </ul> </div> </div> <?php include('../includes/layouts/footer.php'); ?> manageContent.php <?php require_once('../includes/dbConnection.php'); ?> <?php require_once('../includes/functions.php'); ?> <?php include('../includes/layouts/header.php'); ?> <div id="main"> <div id="navigation"> <ul class="subjects"> <?php $result = findAllSubjects(); while ($subject = mysqli_fetch_assoc($result)) { ?> <li> <?php echo $subject['menuName']; ?> <?php $pageSet = findPagesForSubject($subject['id']); ?> <ul class="pages"> <?php while ($page = mysqli_fetch_assoc($pageSet)) { ?> <li><?php echo $page['menuName']; ?></li> <?php } ?> <?php mysqli_free_result($pageSet); ?> </ul> </li> <hr/> <?php } ?> <?php mysqli_free_result($result); ?> </ul> </div> <div id="page"> <h2>Manage Content</h2> </div> </div> <?php mysqli_free_result($result); ?> <?php include('../includes/layouts/footer.php'); ?>
حال بیاید کاری کنیم تا وقتی کاربر برروی یک subject یا page کلیک کرد آن موضوع یا صفحه بزرگ شود، هم چنین آی دی پیج یا سابجت برای ما به نمایش درآید.
پس ما نیاز داریم از تگ a استفاده کنیم هم چنین در داخل css خود تغییر کوچکی ایجاد میکنیم .
Public.css:
ul.pages{ padding-left: 2em; list-style: square; font-weight: normal; } .selected{ font-weight: bold; هم چنین در function.php کد زیررا می نویسم. function navigation($subjectId, $pageId) { $outPut = '<ul class="subjects">'; $result = findAllSubjects(); while ($subject = mysqli_fetch_assoc($result)) { $outPut .= '<li '; if ($subject['id'] == $subjectId) { $outPut .= 'class="selected"'; } $outPut .= '">'; $outPut .= '<a href="manageContent.php?subject='; $outPut .= urlencode($subject['id']); $outPut .= '">'; $outPut .= $subject['menuName']; $outPut .= '</a>'; $pageSet = findPagesForSubject($subject['id']); $outPut .= '<ul class="pages">'; while ($page = mysqli_fetch_assoc($pageSet)) { $outPut .= '<li '; if ($page['id'] == $pageId) { $outPut .= 'class="selected"'; } $outPut .= '">'; $outPut .= '<a href="manageContent.php?page='; $outPut .= urlencode($page['id']); $outPut .= '">'; $outPut .= $page['menuName']; $outPut .= '</a></li>'; } mysqli_free_result($pageSet); $outPut .= '</ul></li><hr/>'; } mysqli_free_result($result); $outPut .= '</ul>'; return $outPut; }
با فانکشنی که در function.php ایجاد کردیم دیگر نیازی به بسیاری از کدهای درون manageContent.php نیز نیست.
manageContent.php
<?php require_once('../includes/dbConnection.php'); ?> <?php require_once('../includes/functions.php'); ?> <?php include('../includes/layouts/header.php'); ?> <?php if (isset($_GET['subject'])) { $selectSubjectId = $_GET['subject']; $selectPageId = null; } elseif (isset($_GET['page'])) { $selectPageId = $_GET['page']; $selectSubjectId = null; } else { $selectPageId = null; $selectSubjectId = null; } ?> <div id="main"> <div id="navigation"> <?php echo navigation($selectSubjectId, $selectPageId); ?> </div> <div id="page"> <h2>Manage Content</h2> <?php echo $selectSubjectId; echo $selectPageId; ?> </div> </div> <?php mysqli_free_result($result); ?> <?php include('../includes/layouts/footer.php'); ?>
همان طور که میبینید، در manageContent.php ابتدا چک کردهایم اگر کویری پارامتر subject وجود داشت مقدار آن را در selectSubjectId قرار دهد و مقدار selectPageId را null قرار دادیم برای کویری پارامتر page نیز چنین کاری کردیم، اگر هیچ کدام وجود نداشته باشند مقدار هر دو را null قرار میدهیم، اولین باری که صفحه شما بالا میآید مقدار آنها null خواهد بود دراین صورت هیچ یک ار subject ها یا page ها در حالت انتخاب وجود ندارد و هیچ id چاپ نمیشود، اولین باری که بر روی یکی از لینک ها کلیک کنید، id آن را گرفته شده و در کویری پارامتر موردرنظر خواهد گرفت، این کار باعث میشود لینک مورد نظر دارای کلاس selected شود هم چنین id برای ما چاپ میشود.
تا اینجا توانیستیم id سابجکت و پیج را بگیریم و چاپ کنیم، حالا به جای id آن نام subject یا پیج را چاپ میکنیم، برای این کار دو فانکشن در function.php مینویسیم یکی برای subject و دیگری برای page
Function.php
function findPageById($pageId){ global $connection; $safePageId = mysqli_real_escape_string($connection,$pageId); $query = "SELECT * FROM pages WHERE id = {$safePageId} LIMIT 1"; $pageSet = mysqli_query($connection, $query); confirmQuery($pageSet); if ($page = mysqli_fetch_assoc($pageSet)) { return $page; } else { return null; } } function findSubjectById($subjectId) { global $connection; $safeSubjectId = mysqli_real_escape_string($connection,$subjectId); $query = "SELECT * FROM subjects WHERE id={$safeSubjectId} LIMIT 1"; $result = mysqli_query($connection, $query); confirmQuery($result); if ($subject = mysqli_fetch_assoc($result)) { return $subject; } else { return null; } }
این فانکشنها مانند findAllSubject و findPagesForSubject هستند تفاوت در این است که مقدار برگشتی این فانکشن ها یک associative array میباشد، حال به manageContent باز میگردیم و چک میکنیم اگر متغییر selectSubjectId مقدار داشت هدر به نام Manage subject تغییر کند و نام آن سابجکت را برای ما چاپ کند، برای page همچنین کاری را نجام میدهیم.
manageContent.php
<?php require_once('../includes/dbConnection.php'); ?> <?php require_once('../includes/functions.php'); ?> <?php include('../includes/layouts/header.php'); ?> <?php if (isset($_GET['subject'])) { $selectSubjectId = $_GET['subject']; $selectPageId = null; } elseif (isset($_GET['page'])) { $selectPageId = $_GET['page']; $selectSubjectId = null; } else { $selectPageId = null; $selectSubjectId = null; } ?> <div id="main"> <div id="navigation"> <?php echo navigation($selectSubjectId, $selectPageId); ?> </div> <div id="page"> <?php if ($selectSubjectId) { echo '<h2>Manage Subjects</h2>'; $currentSubject = findSubjectById($selectSubjectId); echo 'Menu Name: '.$currentSubject['menuName']; } elseif ($selectPageId) { echo '<h2>Manage Pages</h2>'; $currentPage = findSubjectById($selectPageId); echo 'Page Name: '.$currentPage['menuName']; } else { echo 'Please select subject or page'; } ?> </div> </div> <?php mysqli_free_result($result); ?> <?php include('../includes/layouts/footer.php'); ?>
میبیند که بالای صفحه کد زیادی وجود دارد، کد تمیزتری را با هم خواهیم نوشت، یک فانکشن دیگر در function.php برای کد بالا مینویسیم.
Function.php
function findSelectedPage(){ global $currentSubject; global $currentPage; if (isset($_GET['subject'])) { $currentSubject = findSubjectById($_GET['subject']); $currentPage = null; } elseif (isset($_GET['page'])) { $currentPage = findSubjectById($_GET['page']); $currentSubject =null; } else { $currentSubject =null; $currentPage = null; } }
در فانکشن navigation هم تغییرات کوچکی اعمال میکنیم .
function navigation($subjectArray, $pageArray) { $outPut = '<ul class="subjects">'; $result = findAllSubjects(); while ($subject = mysqli_fetch_assoc($result)) { $outPut .= '<li '; if ($subjectArray && $subject['id'] == $subjectArray['id']) { $outPut .= 'class="selected"'; } $outPut .= '">'; $outPut .= '<a href="manageContent.php?subject='; $outPut .= urlencode($subject['id']); $outPut .= '">'; $outPut .= $subject['menuName']; $outPut .= '</a>'; $pageSet = findPagesForSubject($subject['id']); $outPut .= '<ul class="pages">'; while ($page = mysqli_fetch_assoc($pageSet)) { $outPut .= '<li '; if ($pageArray && $page['id'] == $pageArray['id']) { $outPut .= 'class="selected"'; } $outPut .= '">'; $outPut .= '<a href="manageContent.php?page='; $outPut .= urlencode($page['id']); $outPut .= '">'; $outPut .= $page['menuName']; $outPut .= '</a></li>'; } mysqli_free_result($pageSet); $outPut .= '</ul></li><hr/>'; } mysqli_free_result($result); $outPut .= '</ul>'; return $outPut; }
حالا کدهای اضافه در manageContent را حذف میکنیم :
manageContent.php
<?php require_once('../includes/dbConnection.php'); ?> <?php require_once('../includes/functions.php'); ?> <?php include('../includes/layouts/header.php'); ?> <?php findSelectedPage(); ?> <div id="main"> <div id="navigation"> <?php echo navigation($currentSubject, $currentPage); ?> </div> <div id="page"> <?php if ($currentSubject) { echo '<h2>Manage Subjects</h2>'; echo 'Menu Name: ' . $currentSubject['menuName']; } elseif ($currentPage) { echo '<h2>Manage Pages</h2>'; echo 'Page Name: ' . $currentPage['menuName']; } else { echo 'Please select subject or page'; } ?> </div> </div> <?php mysqli_free_result($result); ?> <?php include('../includes/layouts/footer.php'); ?>
خیلی تمیزتر شد .
ایجاد منوی جدید :
برای ایجاد منویجدید نیاز به یک فرم داریم که بتوانیم نام منو position آن و visible بودن آن را تعیین کنیم، به یاد داشته باشید منوی جدید یعنی ساخت یک رکورد جدید در جدول subjects .
ابتدا در ManageContent.php در div نویگیشین یک لینک ایجاد میکنیم، تا ما را به صفحهای ببرد که در آنجا منو را ایجاد میکنیم، نام این صفحه را newSubject.php میگذاریم .
manageContent.php
<div id="navigation"> <?php echo navigation($currentSubject, $currentPage); ?> <br> <a href="newSubject.php">+ Add a Menu</a> </div>
صفحه newSubject.php بسیار شبیه به manageContent.php میباشد با این تفاوت که یک فرم در آن قرار میدهیم .
newSubject.php
<?php require_once('../includes/dbConnection.php'); ?> <?php require_once('../includes/functions.php'); ?> <?php include('../includes/layouts/header.php'); ?> <?php findSelectedPage(); ?> <div id="main"> <div id="navigation"> <?php echo navigation($currentSubject, $currentPage); ?> </div> <div id="page"> <h2>Create Subject</h2> <form action="createSubject.php" method="post"> <p>Menu Name: <input type="text" name="menuName" value=""></p> <p>Position: <select name="position"> <?php $subjectSet = findAllSubjects(); $subjectCount = mysqli_num_rows($subjectSet); for ($count = 1; $count <= $subjectCount + 1; $count++) { echo "<option value = \"{$count}\">{$count}</option >"; } ?> </select> </p> <p>Visible: <input type="radio" name="visible" value="0">No <input type="radio" name="visible" value="1">Yes </p> <input type="submit" value="Create Subject"> </form> <a href="manageContent.php">Cancel</a> </div> </div> <?php mysqli_free_result($result); ?> <?php include('../includes/layouts/footer.php'); ?>
برای گرفتن position یک select ایجاد میکنیم، تعداد position ها را میگیریم و در یک حلقه for قرار میدهیم. در این مثال ما 5 position را داریم و اگر یکی بیشتر نمایش ندهیم، در هنگام ایجاد subject جدید نمیتوانیم position 6 را اتنخاب کنیم پس یکی به تعداد position های موجود اضافه میکنیم .
همان طور که در کد بالا میبیند action فرم ما را به صفحهای به نام createSubject.php منتقل میکنید، این صفحه شامل دستورات insert در داخل دیتابیس است، در آموزشهای قبل فایلی به نام databaseInsert.php نوشتیم دقیقا مشابه همان کار را انجام میدهیم .
قبل از آن برای redirect کردن فانکشنی به نام redirectTo در function.php میسازیم.
Function.php
function redirectTo($newLocation) { header("Location: " . $newLocation); exit(); }
همچنین برای کار با session داخل پوشه includes فایلی به نام session.php میسازیم .
Session.php
<?php session_start(); function message() { if (isset($_SESSION['message'])) { $outPut = "<div class=\"message\">"; $outPut .= htmlentities($_SESSION['message']); $outPut .= '</div>'; $_SESSION['message'] = null; return $outPut; } }
در این فایل فانکشنی به نام message ساختیم که محتوای session ما را درون div class=message چاپ میکند، محتوای session[‘message’] پیامی است که در صفحه createSubject.php برای کاربر چاپ میشود، حالا نوبت ساخت این صفحه است .
<?php require_once('../includes/session.php'); require_once('../includes/dbConnection.php'); require_once('../includes/functions.php'); if (isset($_POST['submit'])) { $menuName = mysqlPrep($_POST['menuName']); $position = (int)$_POST['position']; $visible = (int)$_POST['visible']; $query = "INSERT INTO subjects (menuName,position,visible)VALUES ('{$menuName}',{$position},{$visible})"; $result = mysqli_query($connection, $query); if ($result) { $_SESSION['message'] = 'Subject creation success'; redirectTo('manageContent.php'); } else { $_SESSION['message'] = 'Subject creation failed'; redirectTo('newSubject.php'); } } else { redirectTo('newSubject.php'); } if (isset($connection)) { mysqli_close($connection); }
اگر به یاد داشته باشید از فانکشن mysql_real_escape_string برای جلوگیری از sqlInjection استفاده میکردیم، برای این فانکشن هم فانکشن دیگری در function.php ایجاد میکنیم :
Function.php
function mysqlPrep($string) { global $connection; $escapeString = mysqli_real_escape_string($connection, $string); return $escapeString; }
حالا باید فانکشن message را در فایلهای manageContent.php و newSubject.php قرار دهیم تا در صورت بودن پیغام آن را برای کاربر چاپ کند.
manageContent.php
<?php require_once('../includes/session.php'); ?> <?php require_once('../includes/dbConnection.php'); ?> <?php require_once('../includes/functions.php'); ?> <?php include('../includes/layouts/header.php'); ?> <?php findSelectedPage(); ?> <div id="main"> <div id="navigation"> <?php echo navigation($currentSubject, $currentPage); ?> <br> <a href="newSubject.php">+ Add a Menu</a> </div> <div id="page"> <?php echo message(); ?> <?php if ($currentSubject) { echo '<h2>Manage Subjects</h2>'; echo 'Menu Name: ' . $currentSubject['menuName']; } elseif ($currentPage) { echo '<h2>Manage Pages</h2>'; echo 'Page Name: ' . $currentPage['menuName']; } else { echo 'Please select subject or page'; } ?> </div> </div> <?php include('../includes/layouts/footer.php'); ?>
newSubject.php
<?php require_once('../includes/session.php'); ?> <?php require_once('../includes/dbConnection.php'); ?> <?php require_once('../includes/functions.php'); ?> <?php include('../includes/layouts/header.php'); ?> <?php findSelectedPage(); ?> <div id="main"> <div id="navigation"> <?php echo navigation($currentSubject, $currentPage); ?> </div> <div id="page"> <?php echo message(); ?> <h2>Create Subject</h2> <form action="createSubject.php" method="post"> <p>Menu Name: <input type="text" name="menuName" value=""></p> <p>Position: <select name="position"> <?php $subjectSet = findAllSubjects(); $subjectCount = mysqli_num_rows($subjectSet); for ($count = 1; $count <= $subjectCount + 1; $count++) { echo "<option value = \"{$count}\">{$count}</option >"; } ?> </select> </p> <p>Visible: <input type="radio" name="visible" value="0">No <input type="radio" name="visible" value="1">Yes </p> <input type="submit" name="submit" value="Create Subject"> </form> <a href="manageContent.php">Cancel</a> </div> </div> <?php include('../includes/layouts/footer.php'); ?>
برای اینکه پیام متمایز باشد در فایل public.css خود چند خط ساده css هم اضافه میکنیم .
div.message { border: 2px solid #8D0D19; color: #E44424; font-weight: bold; margin: 1em 0; padding: 1em; }
حالا سابجکت جدیدی ایجاد کنید میبینید که پیام برای شما چاپ میشود.
در تصاویر بالا میبینید که من tutorials را با position 6 ایجاد کردم و پیغام مبنی بر ایجاد این منو برای من چاپ شد .
Validation :
برای اعتبار سنجی از فانکشنهایی که قبلا در validationFunctions.php با هم ساختیم استفاده میکنیم، فایلی به همین نام در پوشه includes ایجاد میکنیم .
validationFunctions.php
<?php $errors = array(); function hasPresence($value) { return isset($value) && $value !== ""; } function validatePresences($requiredFields) { global $errors; foreach ($requiredFields as $field) { $value = trim($_POST[$field]); if (!hasPresence($value)) { $errors[$field] = ucfirst($field) . ' cant be blank'; } } } function hasMaxLength($value, $max) { return strlen($value) <= $max; } function validateMaxLengths($fieldsWithMaxLengths) { global $errors; foreach ($fieldsWithMaxLengths as $field => $max) { $value = trim($_POST[$field]); if (!hasMaxLength($value, $max)) { $errors[$field] = ucfirst($field) . ' is too long'; } } } function hasInclusion($value, $set) { return in_array($value, $set); }
در گذشته گفتیم این فانکشنها به چه شکل کار میکنند، فانکشن formErrors را نیز در function.php قرار میدهیم .
function formErrors($errors = array()) { $output = ''; if (!empty($errors)) { $output .= '<div class="error"> Please fix the following errors'; $output .= '<ul>'; foreach ($errors as $key => $error) { $output .= "<li>{$error}</li>"; } $output .= '</ul></div>'; } return $output; }
حالا در reateSubject.php اعتبارسنجی را انجام میدهیم :
<?php require_once('../includes/session.php'); require_once('../includes/dbConnection.php'); require_once('../includes/functions.php'); require_once('../includes/validationFunctions.php'); if (isset($_POST['submit'])) { $menuName = mysqlPrep($_POST['menuName']); $position = (int)$_POST['position']; $visible = (int)$_POST['visible']; $requiredFields = array('menuName', 'position', 'visible'); validatePresences($requiredFields); $fieldsWithMaxLengths = array('menuName' => 20); validateMaxLengths($fieldsWithMaxLengths); if (!empty($errors)) { $_SESSION['errors'] = $errors; redirectTo('newSubject.php'); } $query = "INSERT INTO subjects (menuName,position,visible)VALUES ('{$menuName}',{$position},{$visible})"; $result = mysqli_query($connection, $query); if ($result) { $_SESSION['message'] = 'Subject creation success'; redirectTo('manageContent.php'); } else { $_SESSION['message'] = 'Subject creation failed'; redirectTo('newSubject.php'); } } else { redirectTo('newSubject.php'); } if (isset($connection)) { mysqli_close($connection); } در session.php فانکشنی برای خطاها ایجاد می کنم : Session.php function errors() { if (isset($_SESSION['errors'])) { $errors = $_SESSION['errors']; $_SESSION['errors'] = null; return $errors; } }
حال تنها کاری که باید انجام شود فراخوانی فانکشنها در newSubject.php است .
newSubject.php
<?php require_once('../includes/session.php'); ?> <?php require_once('../includes/dbConnection.php'); ?> <?php require_once('../includes/functions.php'); ?> <?php include('../includes/layouts/header.php'); ?> <?php findSelectedPage(); ?> <div id="main"> <div id="navigation"> <?php echo navigation($currentSubject, $currentPage); ?> </div> <div id="page"> <?php echo message(); ?> <?php echo formErrors(errors()); ?> <h2>Create Subject</h2> <form action="createSubject.php" method="post"> <p>Menu Name: <input type="text" name="menuName" value=""></p> <p>Position: <select name="position"> <?php $subjectSet = findAllSubjects(); $subjectCount = mysqli_num_rows($subjectSet); for ($count = 1; $count <= $subjectCount + 1; $count++) { echo "<option value = \"{$count}\">{$count}</option >"; } ?> </select> </p> <p>Visible: <input type="radio" name="visible" value="0">No <input type="radio" name="visible" value="1">Yes </p> <input type="submit" name="submit" value="Create Subject"> </form> <a href="manageContent.php">Cancel</a> </div> </div> <?php include('../includes/layouts/footer.php'); ?>
به آدرس http://localhost/darkoobweb/public/newSubject.php
بروید و سعی کنید بدون وارد کردن اطلاعات سابجکتی ایجاد کنید، باید مانند من با پیغام خطا مواجه شوید .
ویرایش :
اگر به یاد داشته باشید در گذشته فایلی به نام databasesUpdate.php را با هم ساختیم و همین طور صفحه newSubject.php را برای ایجاد subject نوشتیم، من از این دو برای نوشتم صفحهی ویرایش استفاده خواهم کرد .
شروع میکنیم، صفحهای به نام editSubject.php در پوشه public میسازیم در این صفحه اعتبار سنجی و ویرایش را انجام خواهیم داد، شما میتوانید دو صفحه داشته باشید .
<?php require_once('../includes/session.php'); ?> <?php require_once('../includes/dbConnection.php'); ?> <?php require_once('../includes/functions.php'); ?> <?php require_once('../includes/validationFunctions.php'); ?> <?php findSelectedPage(); ?> <?php if (!$currentSubject) { redirectTo('manageContent.php'); } ?> <?php if (isset($_POST['submit'])) { $requiredFields = array('menuName', 'position', 'visible'); validatePresences($requiredFields); $fieldsWithMaxLengths = array('menuName' => 20); validateMaxLengths($fieldsWithMaxLengths); if (empty($errors)) { $id = $currentSubject['id']; $menuName = mysqlPrep($_POST['menuName']); $position = (int)$_POST['position']; $visible = (int)$_POST['visible']; $query = "UPDATE subjects SET menuName = '{$menuName}', position={$position}, visible ={$visible} WHERE id ={$id} LIMIT 1"; $result = mysqli_query($connection, $query); if ($result && mysqli_affected_rows($connection) == 1) { $_SESSION['message'] = 'Subject Edit success'; redirectTo('manageContent.php'); } else { $message = 'Subject Edit failed'; } } } else { } ?> <?php include('../includes/layouts/header.php'); ?> <div id="main"> <div id="navigation"> <?php echo navigation($currentSubject, $currentPage); ?> </div> <div id="page"> <?php if (!empty($message)) { echo "<div class=\"message\">" . $message . "</div>"; } ?> <?php echo formErrors($errors); ?> <h2>Edit Subject <?php echo $currentSubject['menuName']; ?></h2> <form action="editSubject.php?subject=<?php echo $currentSubject['id']; ?>" method="post"> <p>Menu Name: <input type="text" name="menuName" value="<?php echo $currentSubject['menuName']; ?>"></p> <p>Position: <select name="position"> <?php $subjectSet = findAllSubjects(); $subjectCount = mysqli_num_rows($subjectSet); for ($count = 1; $count <= $subjectCount; $count++) { echo "<option value = \"{$count}\""; if ($currentSubject['position'] == $count) { echo " selected "; } echo ">{$count}</option >"; } ?> </select> </p> <p>Visible: <input type="radio" name="visible" value="0" <?php if ($currentSubject['visible'] == 0) { echo 'checked'; } ?>>No <input type="radio" name="visible" value="1" <?php if ($currentSubject['visible'] == 1) { echo 'checked'; } ?>>Yes </p> <input type="submit" name="submit" value="Edit Subject"> </form> <a href="manageContent.php">Cancel</a> </div> </div> <?php include('../includes/layouts/footer.php'); ?>
بیشتر این کدها را قبلا نوشته و توضیح دادیم، پس فکر نمیکنم نیازی به توضیح باشد.
در صفحه manageContent.php نیز تغییر کوچکی برای ایجاد یک لینک در صفحه ایجاد میکنیم این لینک قرار است با استفاده از کویری استرینگ id سابجکت مورد نظر را به صفحه editeSubject.php انتقال دهد.
<div id="page"> <?php echo message(); ?> <?php if ($currentSubject) { echo '<h2>Manage Subjects</h2>'; echo 'Menu Name: ' . $currentSubject['menuName'] . '<br>'; echo '<a href="editSubject.php?subject=' . $currentSubject['id'] . '">Edit Subject</a>'; } elseif ($currentPage) { echo '<h2>Manage Pages</h2>'; echo 'Page Name: ' . $currentPage['menuName']; } else { echo 'Please select subject or page'; } ?> </div>
بعد از رفرش صفحه باید مانند من بتوانید سابجکتهای خود را ویرایش کنید.
در ادامه قسمت 19 میخواهیم عمل Delete را انجام دهیم.
حذف Delete :
صفحهای به نام deleteSubject.php میسازیم و کدهای زیر را در آن قرار میدهیم شما با کدها آشنایی دارید پس توضیج خاصی لازم نیست، فقط این نکته را در نظر بگیرید، قبل از عمل delete چک می کنیم آیا subject دارای page هست یا خیر اگر دارای page بود عمل حذف انجام نشود.
deleteSubject.php
<?php require_once('../includes/session.php'); require_once('../includes/dbConnection.php'); require_once('../includes/functions.php'); $currentSubject = findSubjectById($_GET['subject']); if (!$currentSubject) { redirectTo('manageContent.php'); } $pagesSet = findPagesForSubject($currentSubject['id']); if(mysqli_num_rows($pagesSet)>0){ $_SESSION['message'] = 'Cant delete subject with pages'; redirectTo("manageContent.php?subject={$currentSubject['id']}"); } $id = $currentSubject['id']; $query = "DELETE FROM subjects WHERE id = {$id} LIMIT 1"; $result = mysqli_query($connection,$query); if ($result && mysqli_affected_rows($connection) == 1) { $_SESSION['message'] = 'Subject Delete success'; redirectTo('manageContent.php'); } else { $_SESSION['message'] = 'Subject Delete failed'; redirectTo("manageContent.php?subject={$id}"); }
درeditSubject.php نیز یک لینک برای این صفحه ایجاد کردیم
<?php require_once('../includes/session.php'); ?> <?php require_once('../includes/dbConnection.php'); ?> <?php require_once('../includes/functions.php'); ?> <?php require_once('../includes/validationFunctions.php'); ?> <?php findSelectedPage(); ?> <?php if (!$currentSubject) { redirectTo('manageContent.php'); } ?> <?php if (isset($_POST['submit'])) { $requiredFields = array('menuName', 'position', 'visible'); validatePresences($requiredFields); $fieldsWithMaxLengths = array('menuName' => 20); validateMaxLengths($fieldsWithMaxLengths); if (empty($errors)) { $id = $currentSubject['id']; $menuName = mysqlPrep($_POST['menuName']); $position = (int)$_POST['position']; $visible = (int)$_POST['visible']; $query = "UPDATE subjects SET menuName = '{$menuName}', position={$position}, visible ={$visible} WHERE id ={$id} LIMIT 1"; $result = mysqli_query($connection, $query); if ($result && mysqli_affected_rows($connection) == 1) { $_SESSION['message'] = 'Subject Edit success'; redirectTo('manageContent.php'); } else { $message = 'Subject Edit failed'; } } } else { } ?> <?php include('../includes/layouts/header.php'); ?> <div id="main"> <div id="navigation"> <?php echo navigation($currentSubject, $currentPage); ?> </div> <div id="page"> <?php if (!empty($message)) { echo "<div class=\"message\">" . $message . "</div>"; } ?> <?php echo formErrors($errors); ?> <h2>Edit Subject <?php echo $currentSubject['menuName']; ?></h2> <form action="editSubject.php?subject=<?php echo $currentSubject['id']; ?>" method="post"> <p>Menu Name: <input type="text" name="menuName" value="<?php echo $currentSubject['menuName']; ?>"></p> <p>Position: <select name="position"> <?php $subjectSet = findAllSubjects(); $subjectCount = mysqli_num_rows($subjectSet); for ($count = 1; $count <= $subjectCount; $count++) { echo "<option value = \"{$count}\""; if ($currentSubject['position'] == $count) { echo " selected "; } echo ">{$count}</option >"; } ?> </select> </p> <p>Visible: <input type="radio" name="visible" value="0" <?php if ($currentSubject['visible'] == 0) { echo 'checked'; } ?>>No <input type="radio" name="visible" value="1" <?php if ($currentSubject['visible'] == 1) { echo 'checked'; } ?>>Yes </p> <input type="submit" name="submit" value="Edit Subject"> </form> <a href="manageContent.php">Cancel</a> <a href="deleteSubject.php?subject=<?php echo $currentSubject['id']; ?>" onclick="return confirm('Are You Sure?')">Delete Subject</a> </div> </div> <?php include('../includes/layouts/footer.php'); ?>
حالا شما بیاید چیزی مشابه تصاویر زیر را ببینید .
متوجه شدیم که چگونه میتوان سابجکت جدید را ایجاد ،ویرایش و حذف کرد، حالا نوبت pages است، قبل از دیدن کدها پیشنهاد میکنم خودتان تلاش کنید و کدها را بنویسید، همچنین من کدها را کمی مرتب کردم .
ManageContent.php
<?php require_once('../includes/session.php'); ?> <?php require_once('../includes/dbConnection.php'); ?> <?php require_once('../includes/functions.php'); ?> <?php include('../includes/layouts/header.php'); ?> <?php findSelectedPage(); ?> <div id="main"> <div id="navigation"> <br> <a href="admin.php">« Main Menu</a> <?php echo navigation($currentSubject, $currentPage); ?> <br> <a href="newSubject.php">+ Add a Menu</a> </div> <div id="page"> <?php echo message(); ?> <?php if ($currentSubject) { echo '<h2>Manage Subjects</h2>'; echo 'Menu Name: ' . htmlentities($currentSubject['menuName']) . '<br>'; echo '<a href="editSubject.php?subject=' . urlencode($currentSubject['id']) . '">Edit Subject</a><br>'; echo 'Position:' . $currentSubject['position'] . '<br>'; echo 'Visible: '; echo $currentSubject['visible'] == 1 ? ' yes' : 'no'; echo '<div style="margin-top: 2em;border-top=1px solid #000000;">'; echo '<h3>Pages in this subject:</h3>'; echo '<ul>'; $subjectPages = findPagesForSubject($currentSubject['id']); while ($page = mysqli_fetch_assoc($subjectPages)) { echo '<li>'; $safePageId = urlencode($page['id']); echo "<a href=\"manageContent.php?page={$safePageId}\">"; echo htmlentities($page['menuName']); echo '</a>'; echo '</li>'; } echo '</ul>'; echo '<br>'; echo '<a href="newPage.php?subject=' . urlencode($currentSubject['id']) . '">Add a new page to this subject </a>'; } elseif ($currentPage) { echo '<h2>Manage Pages</h2>'; echo 'Page Name: ' . htmlentities($currentPage['menuName']) . '<br>'; echo 'Position:' . $currentPage['position'] . '<br>'; echo 'Visible: '; echo $currentPage['visible'] == 1 ? ' yes<br>' : 'no<br>'; echo 'Content:<br><div class="view-content">' . htmlentities($currentPage['content']) . '</div>'; echo '<br><br>'; echo '<a href="editPage.php?page='.urlencode($currentPage['id']).'">Edit page</a>'; } else { echo 'Please select subject or page'; } ?> </div> </div> <?php include('../includes/layouts/footer.php'); ?>
newPage.php
<?php require_once('../includes/session.php'); ?> <?php require_once('../includes/dbConnection.php'); ?> <?php require_once('../includes/functions.php'); ?> <?php require_once('../includes/validationFunctions.php'); ?> <?php findSelectedPage(); ?> <?php if (!$currentSubject) { redirectTo('manageContent.php'); } ?> <?php if (isset($_POST['submit'])) { $requiredFields = array('menuName', 'position', 'visible', 'content'); validatePresences($requiredFields); $fieldWithMaxLengths = array('menuName' => 30); validateMaxLengths($fieldWithMaxLengths); if (empty($errors)) { $subjectId = $currentSubject['id']; $menuName = mysqlPrep($_POST['menuName']); $position = (int)$_POST['position']; $visible = (int)$_POST['visible']; $content = mysqlPrep($_POST['content']); $query = "INSERT INTO pages(subjectId,menuName,position,visible,content) VALUES ({$subjectId},'{$menuName}',{$position},{$visible},'{$content}')"; $result = mysqli_query($connection, $query); if ($result) { $_SESSION['message'] = 'Page created'; redirectTo('manageContent.php?subject=' . urlencode($currentSubject['id'])); } else { $_SESSION['message'] = 'Page creation failed'; } } } ?> <?php include('../includes/layouts/header.php'); ?> <div id="main"> <div id="navigation"> <?php echo navigation($currentSubject, $currentPage); ?> </div> <div id="page"> <?php echo message(); ?> <?php echo formErrors(errors()); ?> <h2>Create Page</h2> <form action="newPage.php?subject=<?php echo urlencode($currentSubject['id'])?>" method="post"> <p>Menu Name: <input type="text" name="menuName" value=""></p> <p>Position: <select name="position"> <?php $pageSet = findPagesForSubject($currentSubject['id']); $pageCount = mysqli_num_rows($pageSet); for ($count = 1; $count <= $pageCount + 1; $count++) { echo "<option value = \"{$count}\">{$count}</option >"; } ?> </select> </p> <p>Visible: <input type="radio" name="visible" value="0">No <input type="radio" name="visible" value="1">Yes </p> <p>Content:<br> <textarea name="content" rows="20" cols="80"></textarea> </p> <input type="submit" name="submit" value="Create Page"> </form> <a href="manageContent.php?subject=<?php echo urlencode($currentSubject['id']); ?>">Cancel</a> </div> </div> <?php include('../includes/layouts/footer.php'); ?>
editPage.php
<?php require_once('../includes/session.php'); ?> <?php require_once('../includes/dbConnection.php'); ?> <?php require_once('../includes/functions.php'); ?> <?php require_once('../includes/validationFunctions.php'); ?> <?php findSelectedPage(); ?> <?php if (!$currentPage) { redirectTo('manageContent.php'); } ?> <?php if (isset($_POST['submit'])) { $id = $currentPage['id']; $menuName = mysqlPrep($_POST['menuName']); $position = (int)$_POST['position']; $visible = (int)$_POST['visible']; $content = mysqlPrep($_POST['content']); $requiredFields = array('menuName', 'position', 'visible', 'content'); validatePresences($requiredFields); $fieldsWithMaxLengths = array('menuName' => 30); validateMaxLengths($fieldsWithMaxLengths); if (empty($errors)) { $query = "UPDATE pages SET menuName = '{$menuName}', position={$position}, visible ={$visible}, content='{$content}' WHERE id ={$id} LIMIT 1"; $result = mysqli_query($connection, $query); if ($result && mysqli_affected_rows($connection) >= 0) { $_SESSION['message'] = 'Page Edit success'; redirectTo("manageContent.php?page={$id}"); } else { $message = 'Page Edit failed'; } } } else { } ?> <?php include('../includes/layouts/header.php'); ?> <div id="main"> <div id="navigation"> <?php echo navigation($currentSubject, $currentPage); ?> </div> <div id="page"> <?php echo message(); ?> <?php echo formErrors($errors); ?> <h2>Edit Subject <?php echo htmlentities($currentPage['menuName']); ?></h2> <form action="editPage.php?page=<?php echo urlencode($currentPage['id']); ?>" method="post"> <p>Menu Name: <input type="text" name="menuName" value="<?php echo htmlentities($currentPage['menuName']); ?>"></p> <p>Position: <select name="position"> <?php $pageSet = findPagesForSubject($currentPage['subjectId']); $pageCount = mysqli_num_rows($pageSet); for ($count = 1; $count <= $pageCount; $count++) { echo "<option value = \"{$count}\""; if ($currentPage['position'] == $count) { echo " selected "; } echo ">{$count}</option >"; } ?> </select> </p> <p>Visible: <input type="radio" name="visible" value="0" <?php if ($currentPage['visible'] == 0) { echo 'checked'; } ?>>No <input type="radio" name="visible" value="1" <?php if ($currentPage['visible'] == 1) { echo 'checked'; } ?>>Yes </p> <p>Content:<br> <textarea name="content" cols="80" rows="20"><?php echo htmlentities($currentPage['content']); ?></textarea> </p> <input type="submit" name="submit" value="Edit Subject"/> </form> <a href="manageContent.php?page=<?php echo urlencode($currentPage['id']); ?>">Cancel</a> <a href="deletePage.php?page=<?php echo urlencode($currentPage['id']); ?>" onclick="return confirm('Are You Sure?')">Delete Page</a> </div> </div> <?php include('../includes/layouts/footer.php'); ?>
deletePage.php
<?php require_once('../includes/session.php'); require_once('../includes/dbConnection.php'); require_once('../includes/functions.php'); $currentPage = findPageById($_GET['page']); if (!$currentPage) { redirectTo('manageContent.php'); } $id = $currentPage['id']; $query = "DELETE FROM pages WHERE id = {$id} LIMIT 1"; $result = mysqli_query($connection, $query); if ($result && mysqli_affected_rows($connection) == 1) { $_SESSION['message'] = 'Page Delete success'; redirectTo('manageContent.php'); } else { $_SESSION['message'] = 'Page Delete failed'; redirectTo("manageContent.php?page={$id}"); }
ساخت قسمت عمومی Public area :
قبل از ساخت این قسمت به این سوال پاسخ دهید، چه چیزی باید در این قسمت نمایش داده شود ؟
اول اینکه اگر subject یا page دارای مقدار visible = false است نباید در این قسمت نمایش داده شود، دوم اینکه در قسمت منو زیر منوها وقتی نشان داده شوند که روی منو اصلی همان subject کلیک شده باشد، سوم باید دقت کنیم اگر پیجی را غیر فعال کردیم منظور visible =false کاربر نتواند از طریق مقدار دادن یه url به آن پیج دسترسی پیدا کند.
برای مثال: اگر پیج با id شماره 5 را غیر فعال کردیم کاربر نباید با وارد کردن چنین آدرسی به صفحه دسترسی پیدا کند http://localhost/darkoobweb/public/index.php?page=5
کار دیگری که میخواهیم انجام دهیم این است زمانی که در قسمت admin هستیم title دارای پسوند admin باشد، مثال: darkoobweb admin
موضوع دیگر در مورد نمایش content صفحههات است. از فانکشن nl2br در کد خود برای نمایش کانتنت استفاده کردهایم این فانکشن به جای تمام خط های جدید که آغاز به نوشتن آنها میکنیم یک تگ br قرار میدهد .
متغییری به نام laoutContext هم در نظر گرفتم که مقدار آن زمانی که در صفحههات admin هستیم admin و زمانی که در صفحات public باشیم public خواهد بود.
بهتر است اول خودتان سعی کنید کدها را بنویسید، اگر به یاد داشته باشید صفحهای به نام index.php داشتیم ،کار را از آنجا آغاز میکنیم .
Index.php
<?php require_once('../includes/session.php'); ?> <?php require_once('../includes/dbConnection.php'); ?> <?php require_once('../includes/functions.php'); ?> <?php $layoutContext = 'public'; ?> <?php include('../includes/layouts/header.php'); ?> <?php findSelectedPage(true); ?> <div id="main"> <div id="navigation"> <?php echo publicNavigation($currentSubject, $currentPage); ?> </div> <div id="page"> <?php if ($currentPage) { echo '<h2>' . htmlentities($currentPage['menuName']) . '</h2>'; echo nl2br(htmlentities($currentPage['content'])); } else { ?> <p>Welcome </p> <?php } ?> </div> </div> <?php include('../includes/layouts/footer.php'); ?>
Function.php تغییرات و فانکشنهای اضافه شده من
function findPageById($pageId, $public = true) { global $connection; $safePageId = mysqli_real_escape_string($connection, $pageId); $query = "SELECT * FROM pages WHERE id = {$safePageId} "; if($public){ $query.="AND visible = 1 "; } $query.= "LIMIT 1"; $pageSet = mysqli_query($connection, $query); confirmQuery($pageSet); if ($page = mysqli_fetch_assoc($pageSet)) { return $page; } else { return null; } } function findAllSubjects($public = true) { global $connection; $query = 'SELECT * FROM subjects '; if ($public) { $query .= 'WHERE visible=1 '; } $query .= 'ORDER BY POSITION ASC'; $result = mysqli_query($connection, $query); confirmQuery($result); return $result; } function findPagesForSubject($subjectId, $public = true) { global $connection; $safeSubjectId = mysqli_real_escape_string($connection, $subjectId); $query = "SELECT * "; $query .= "FROM pages "; $query .= "WHERE subjectId = {$safeSubjectId} "; if ($public) { $query .= 'AND visible=1 '; } $query .= "ORDER BY POSITION ASC"; $pageSet = mysqli_query($connection, $query); confirmQuery($pageSet); return $pageSet; } function findSubjectById($subjectId, $public = true) { global $connection; $safeSubjectId = mysqli_real_escape_string($connection, $subjectId); $query = "SELECT * FROM subjects WHERE id={$safeSubjectId} "; if($public){ $query.="AND visible = 1 "; } $query.= "LIMIT 1"; $result = mysqli_query($connection, $query); confirmQuery($result); if ($subject = mysqli_fetch_assoc($result)) { return $subject; } else { return null; } } function findDefaultPageForSubject($subjectId) { $pageSet = findPagesForSubject($subjectId); if ($firstPage = mysqli_fetch_assoc($pageSet)) { return $firstPage; } else { return null; } } function findSelectedPage($public = false) { global $currentSubject; global $currentPage; if (isset($_GET['subject'])) { $currentSubject = findSubjectById($_GET['subject'],$public); if ($currentSubject && $public) { $currentPage = findDefaultPageForSubject($currentSubject['id']); } else { $currentPage = null; } } elseif (isset($_GET['page'])) { $currentPage = findPageById($_GET['page'], $public); $currentSubject = null; } else { $currentSubject = null; $currentPage = null; } } function publicNavigation($subjectArray, $pageArray) { $outPut = '<ul class="subjects">'; $result = findAllSubjects(); while ($subject = mysqli_fetch_assoc($result)) { $outPut .= '<li'; if ($subjectArray && $subject['id'] == $subjectArray['id']) { $outPut .= ' class="selected"'; } $outPut .= '>'; $outPut .= '<a href="index.php?subject='; $outPut .= urlencode($subject['id']); $outPut .= '">'; $outPut .= htmlentities($subject['menuName']); $outPut .= '</a>'; if ($subjectArray['id'] == $subject['id'] || $pageArray['subjectId'] == $subject['id']) { $pageSet = findPagesForSubject($subject['id']); $outPut .= '<ul class="pages">'; while ($page = mysqli_fetch_assoc($pageSet)) { $outPut .= '<li'; if ($pageArray && $page['id'] == $pageArray['id']) { $outPut .= ' class="selected"'; } $outPut .= '>'; $outPut .= '<a href="index.php?page='; $outPut .= urlencode($page['id']); $outPut .= '">'; $outPut .= htmlentities($page['menuName']); $outPut .= '</a></li>'; } mysqli_free_result($pageSet); $outPut .= '</ul>'; } $outPut .= '</li><hr/>'; } mysqli_free_result($result); $outPut .= '</ul>'; return $outPut; }
header.php
<?php if(!isset($layoutContext)){ $layoutContext = 'public'; } ?> <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Darkoobweb.com<?php if ($layoutContext == 'admin') { echo ' Admin'; } ?></title> <link rel="stylesheet" href="css/public.css" media="all" type="text/css"> </head> <body> <div id="header"> <h1>DarkoobWeb<?php if ($layoutContext == 'admin') { echo ' Admin'; } ?></h1> </div>
تغییر در deleteSubject.php
$currentSubject = findSubjectById($_GET['subject'],false);
تغییر در deletePage.php
$currentPage = findPageById($_GET['page'],false);
اضافه شدن layoutContext در newSubject.php
<?php require_once('../includes/session.php'); ?> <?php require_once('../includes/dbConnection.php'); ?> <?php require_once('../includes/functions.php'); ?> <?php $layoutContext = 'admin'; ?> <?php include('../includes/layouts/header.php'); ?> <?php findSelectedPage(); ?> <div id="main"> <div id="navigation"> <?php echo navigation($currentSubject, $currentPage); ?> </div>
layoutContext را در editSubject.php,editPage.php,newPage.phpنیز با مقدار admin باید اضافه کنید آن هم قبل از فراخوانی header
تغییر در editSubject.php
<p>Position: <select name="position"> <?php $subjectSet = findAllSubjects(false); $subjectCount = mysqli_num_rows($subjectSet); for ($count = 1; $count <= $subjectCount; $count++) { echo "<option value = \"{$count}\""; if ($currentSubject['position'] == $count) { echo " selected "; } echo ">{$count}</option >"; } ?> </select>
شناسایی کاربر User Authentication :
در این قسمت چه کارهایی میخواهیم انجام شود؟
Admin باید بتواند کاربر را ایجاد حذف و ویرایش کند، لیست کاربران برای ما نمایش داده شوند، پسوردها به صورت رمز نمایش داده شوند، هنگام ورود، هویت کاربر چک شود، کاربر بتواد logout کند، سعی کنید این موارد را اول خودتون ایجاد کنید .
کار را با ساختن دو فانکشن در فایل function.php آغاز میکنیم :
Function.php
function findAllAdmins() { global $connection; $query = "SELECT * "; $query .= "FROM admins "; $query .= "ORDER BY userName ASC"; $adminSet = mysqli_query($connection, $query); confirmQuery($adminSet); return $adminSet; } function findAdminById($adminId) { global $connection; $safeAdminId = mysqli_real_escape_string($connection, $adminId); $query = "SELECT * "; $query .= "FROM admins "; $query .= "WHERE id = {$safeAdminId} "; $query .= "LIMIT 1 "; $adminSet = mysqli_query($connection, $query); confirmQuery($adminSet); if ($admin = mysqli_fetch_assoc($adminSet)) { return $admin; } else { return null; } }
سپس در داخل پوشه public فایلهایی به نام های manageAdmin.php, newAdmin.php, editAdmin.php, deleteAdmin میسازیم .
manageAdmin.php
<?php require_once('../includes/session.php'); ?> <?php require_once('../includes/dbConnection.php'); ?> <?php require_once('../includes/functions.php'); ?> <?php $adminSet = findAllAdmins(); ?> <?php $layoutContext = 'admin'; ?> <?php include('../includes/layouts/header.php'); ?> <div id="main"> <div id="page"> <?php echo message(); ?> <h2>Manage Admins</h2> <table> <tr> <th style="text-align: left; width: 200px;">Admins Name</th> <th colspan="2" style="text-align: left;">Actions</th> </tr> <?php while ($admin = mysqli_fetch_assoc($adminSet)) { ?> <tr> <td><?php echo htmlentities($admin['userName']) ?></td> <td><a href="editAdmin.php?id=<?php echo urldecode($admin['id']); ?>">Edit</a></td> <td><a href="deleteAdmin.php?id=<?php echo urldecode($admin['id']); ?>" onclick="return confirm('Are You Sure?');">Delete</a> </td> </tr> <?php } ?> </table> <br> <a href="newAdmin.php">Add new Admin</a> </div> </div> <?php include('../includes/layouts/footer.php'); ?>
newAdmin.php
<?php require_once('../includes/session.php'); ?> <?php require_once('../includes/dbConnection.php'); ?> <?php require_once('../includes/functions.php'); ?> <?php require_once('../includes/validationFunctions.php'); ?> <?php if (isset($_POST['submit'])) { $requiredFields = array('userName', 'password'); validatePresences($requiredFields); $fieldWithMaxLengths = array('userName' => 30); validateMaxLengths($fieldWithMaxLengths); if (empty($errors)) { $userName = mysqlPrep($_POST['userName']); $hashPassword = mysqlPrep($_POST['password']); $query = "INSERT INTO admins(userName,hashPassword) VALUES ('{$userName}','{$hashPassword}')"; $result = mysqli_query($connection, $query); if ($result) { $_SESSION['message'] = 'Admin created'; redirectTo('manageAdmin.php'); } else { $_SESSION['message'] = 'Admin creation failed'; } } } ?> <?php $layoutContext = 'admin'; ?> <?php include('../includes/layouts/header.php'); ?> <div id="main"> <div id="page"> <?php echo message(); ?> <?php echo formErrors(errors()); ?> <h2>Create Admin</h2> <form action="newAdmin.php" method="post"> <p>User Name: <input type="text" name="userName" value=""/></p> <p>Password: <input type="password" name="password" value=""/></p> <input type="submit" name="submit" value="Create Admin"/> </form> <a href="manageAdmin.php">Cancel</a> </div> </div> <?php include('../includes/layouts/footer.php'); ?>
editAdmin.php
<?php require_once('../includes/session.php'); ?> <?php require_once('../includes/dbConnection.php'); ?> <?php require_once('../includes/functions.php'); ?> <?php require_once('../includes/validationFunctions.php'); ?> <?php $admin = findAdminById($_GET['id']); if (!$admin) { redirectTo('manageAdmin.php'); } ?> <?php if (isset($_POST['submit'])) { $requiredFields = array('userName', 'password'); validatePresences($requiredFields); $fieldsWithMaxLengths = array('userName' => 30); validateMaxLengths($fieldsWithMaxLengths); if (empty($errors)) { $id = $admin['id']; $userName = mysqlPrep($_POST['userName']); $hashPassword = mysqlPrep($_POST['password']); $query = "UPDATE admins SET userName = '{$userName}', hashPassword ='{$hashPassword}' WHERE id ={$id} LIMIT 1"; $result = mysqli_query($connection, $query); if ($result && mysqli_affected_rows($connection) >= 0) { $_SESSION['message'] = 'Admin Edit success'; redirectTo("manageAdmin.php"); } else { $message = 'Admin Edit failed'; } } } else { } ?> <?php $layoutContext = 'admin'; ?> <?php include('../includes/layouts/header.php'); ?> <div id="main"> <div id="page"> <?php echo message(); ?> <?php echo formErrors($errors); ?> <h2>Edit Admin <?php echo htmlentities($admin['userName']); ?></h2> <form action="editAdmin.php?id=<?php echo urlencode($admin['id']); ?>" method="post"> <p>User Name: <input type="text" name="userName" value="<?php echo htmlentities($admin['userName']); ?>"></p> <p>Content: <input type="password" name="password" value=""> </p> <input type="submit" name="submit" value="Edit Admin"/> </form> <a href="manageAdmin.php">Cancel</a> </div> </div> <?php include('../includes/layouts/footer.php'); ?>
deleteAdmin.php
<?php require_once('../includes/session.php'); require_once('../includes/dbConnection.php'); require_once('../includes/functions.php'); $admin = findAdminById($_GET['id']); if (!$admin) { redirectTo('manageAdmin.php'); } $id = $admin['id']; $query = "DELETE FROM admins WHERE id = {$id} LIMIT 1"; $result = mysqli_query($connection, $query); if ($result && mysqli_affected_rows($connection) == 1) { $_SESSION['message'] = 'Admin Delete success'; redirectTo('manageAdmin.php'); } else { $_SESSION['message'] = 'Admin Delete failed'; redirectTo("manageAdmin.php"); }
حالا میتوانیم admin را ایجاد ویرایش و یا حذف کنیم، مشکل دیگری وجود دارد و آن این است که password ها را کد نکردیم.
رمزنگاری پسورد Encrypting password :
برای رمز نگاری پسورد من 3 فانکشن در function.php ایجاد کردم .
function passwordEncrypt($password) { $hashFormat = "$2y$10$"; $saltLength = 22; $salt = generateSalt($saltLength); $formatAndSalt = $hashFormat . $salt; $hash = crypt($password, $formatAndSalt); return $hash; } function generateSalt($length) { $uniqueRandomString = md5(uniqid(mt_rand(), true)); $base64String = base64_encode($uniqueRandomString); $modifiedBase64String = str_replace('+', '.', $base64String); $salt = substr($modifiedBase64String, 0, $length); return $salt; } function passwordCheck($password, $existingHash) { $hash = crypt($password, $existingHash); if ($hash === $existingHash) { return true; } else return false; }
سپس در newAdmin.php و editAdmin.php هنگامی که میخواهیم پسورد را در متغییر hashPassword قرار دهیم اول آن را به function خود میدهیم .
$hashPassword = passwordEncrypt($_POST['password']);
اما باید بدانید php ورژن 5.5 فانکشنهایی برای رمزنگاری در اختیار شما می گذارد مانند:
Password_hash();
برای چک کردن پسورد میتوانید از password_verify استفاده کنید، در کدی که باهم نوشتیم فانکشن passwordEncrypt تقریبا همان کار passwrd_hash و فانکشن passwordCheck تقریبا همان کار password_verify را انجام میدهد.
پیشنهاد میکنم در مورد رمز نگاری و فانکشنهای آن در php بیشتر تحقیق و مطالعه کنید، همین طور اگر دوست دارید از کتابخانه استفاده کنید میتوانید به آدرس گیت مراجعه کنید.
ساخت صفحه ورود Login Page :
ابتدا صفحهای به نام login.php ایجاد کنید.
<?php require_once('../includes/session.php'); ?> <?php require_once('../includes/dbConnection.php'); ?> <?php require_once('../includes/functions.php'); ?> <?php require_once('../includes/validationFunctions.php'); ?> <?php $username = ""; if (isset($_POST['submit'])) { $requiredFields = array('userName', 'password'); validatePresences($requiredFields); if (empty($errors)) { $username = $_POST['userName']; $password = $_POST['password']; $foundAdmin = attemptLogin($username, $password); if ($foundAdmin) { $_SESSION['adminId'] = $foundAdmin['id']; $_SESSION['userName'] = $foundAdmin['userName']; redirectTo('admin.php'); } else { $_SESSION['message'] = 'Username/Password not found'; } } } ?> <?php $layoutContext = 'admin'; ?> <?php include('../includes/layouts/header.php'); ?> <div id="main"> <div id="page"> <?php echo message(); ?> <?php echo formErrors($errors); ?> <h2>Login</h2> <form action="login.php" method="post"> <p>User Name: <input type="text" name="userName" value="<?php echo htmlentities($username); ?>"/></p> <p>Password: <input type="password" name="password" value=""/></p> <input type="submit" name="submit" value="login"/> </form> </div> </div> <?php include('../includes/layouts/footer.php'); ?>
سپس در function.php فانکشنی به نام attemptLogin و findAdminByUsername ایجاد میکنیم .
function attemptLogin($username, $password) { $admin = findAdminByUserName($username); if ($admin) { if (passwordCheck($password, $admin['hashPassword'])) { return $admin; }else{ return false; } } else { return false; } } function findAdminByUserName($username) { global $connection; $safeUserName = mysqli_real_escape_string($connection, $username); $query = "SELECT * "; $query .= "FROM admins "; $query .= "WHERE userName = '{$safeUserName}' "; $query .= "LIMIT 1 "; $adminSet = mysqli_query($connection, $query); confirmQuery($adminSet); if ($admin = mysqli_fetch_assoc($adminSet)) { return $admin; } else { return null; } }
در صفحه admin.php نیز از session[‘userName’] برای چاپ نام کاربر استفاده میکنیم.
Admin.php
<p>Welcome to the admin area. <?php echo htmlentities($_SESSION['userName']); ?></p>
ما نیاز داریم بدانیم کاربر login کرده است یا خیر، اگر login کرده بود صفحههای را ببینید و اگر login نکرده بود نباید صفحههات خاصی را ببیند و باید به صفحه login منتقل شود.
برای این کار دو فانکشن دیگر مینویسیم اوللی فقط چک میکند آیا کاربر login شده یا نه و دیگری بعد از چک کردن اگر login نشده باشد به صفحه login.php منتقل میشود.
function loggedIn() { return isset($_SESSION['adminId']); } function confirmLoggedIn() { if (!loggedIn()) { redirectTo('login.php'); } }
خوب فانکشن confirmLoggedIn را در صفحههات مربوط به admin اضافه کنید .
برای logout کردن صفحهای به همین نام میسازیم و سپس سادهترین کد به شکل زیر خواهد بود :
<?php require_once ('../includes/session.php'); require_once ('../includes/functions.php'); $_SESSION['adminId'] = null; $_SESSION['userName'] = null; redirectTo('login.php');
در اینجا ساخت cms ما تمام شد .
میتوانید کدها را تغییر دهید و امکانات این cms ساده را افزایش دهید .
حتما صفحه php.net را مطالعه کنید، و در مورد فانکشنها و دیگر امکانات php بیشتر تحقیق کنید.
شاد و سلامت باشید.