Нова практична 3

 

         Метою даної практичної роботи буде створення сторінки-каталогу із товарами. Знову ж таки, використаємо все той стандартний шаблон bootstrap. Ось його вигляд.

         Як видно із малюнку вгорі, відмічені області співпадають із попередніми сторінками, тому шапку і підвал можна скопіювати звідти.

         Для реалізації цього нам потрібно буде таблиця для збереження товарів, вона буде мати вигляд:

         В кореневому каталозі сайту буде розміщений каталог images в якому будуть розміщуватися фото товарів, тому в таблиці зберігається лише назва файлу.

Так, як у кожного свій магазин із різним товарами, тексти товарів  таблиці не будуть наведені. Структура таблиці має вигляд:

CREATE TABLE `product` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `title` varchar(512) NOT NULL,

  `description` text,

  `price` decimal(10,0) DEFAULT NULL,

  `size` varchar(45) DEFAULT NULL,

  `color` varchar(45) DEFAULT NULL,

  `vendor` varchar(45) DEFAULT NULL,

  `picture` varchar(1024) DEFAULT NULL,

  PRIMARY KEY (`id`),

  UNIQUE KEY `id_UNIQUE` (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;

 

         Тепер потрібно змінити таблицю page додавши до неї поле type типу varchar(64). В результаті отримаємо ось таке:

         Як видно, тепер у нас є тип сторінки, і попередні сторінки (статичні) будуть мати тип html, а наша нова - каталог - php. В полі тіло (body) буде вказана назва файлу php скрипта для виконання, наш завантажувач буде при віддачі сторінки зважати на тип і якщо це динамічна сторінка - то виконувати скрипт який записаний в полі тіло сторінки.

         База даних описана, перейдемо до програмного коду. Спочатку опишемо модифікований шаблон каталогу. Функції формування каталогу не будуть винесені в окремий файл, як раніше. У наведеному файлі-шаблоні потрібні нам функції будуть прокоментовані зеленим кольором. Виносити їх немає необхідності, так як використовуються вони тільки при формуванні каталога, самим каталогом, тобто ззовні до них посилатися немає необхідності.

         Файл має назву catalog.php із таким вмістом:

<!-- Початок документу і шапка -->

<!DOCTYPE html>

<html lang="en">

 

  <head>

 

    <meta charset="utf-8">

    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <meta name="description" content="">

    <meta name="author" content="">

 

    <title><?php echo $sitetitle;?></title>

 

    <!-- Bootstrap core CSS -->

    <link href="templates/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">

 

    <!-- Custom styles for this template -->

    <link href="templates/css/modern-business.css" rel="stylesheet">

 

  </head>

 

  <body>

 

    <!-- Navigation -->

    <nav class="navbar fixed-top navbar-expand-lg navbar-dark bg-dark fixed-top">

      <div class="container">

        <a class="navbar-brand" href="/"><?php echo $sitename;?></a>

        <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">

          <span class="navbar-toggler-icon"></span>

        </button>

        <div class="collapse navbar-collapse" id="navbarResponsive">

                  <?php echo get_menu('main_menu');?>

        </div>

      </div>

    </nav>

 

    <!-- Page Content -->

    <div class="container">

 

      <!-- Page Heading/Breadcrumbs -->

      <h1 class="mt-4 mb-3">Каталог товарів

        <small>Носочки</small>

      </h1>

 

      <div class="row">

<!- Функції формування відображення товарів -->

            <?php

            function catalog_item($item) {//функція темізує одиницю товара, вхідний параметр - масив характеристик товару

      //формуємо спочатку таблицю із характеристиками

            $t="<table class=\"table-striped\" style=\"width:100%\">\n";//початок таблиці

            $t.="<tr><td><strong>Ціна</strong></td><td>".$item['price']."</td></tr>";//додаємо ціну

            $t.="<tr><td><strong>Розмір</strong></td><td>".$item['size']."</td></tr>";//додаємо розмір

            $t.="<tr><td><strong>Колір</strong></td><td>".$item['color']."</td></tr>";//додаємо колір

            $t.="<tr><td><strong>Виробник</strong></td><td>".$item['vendor']."</td></tr>";//додаємо виробника

            $t.="</table>\n";//закінчуємо таблицю

           

            $o="<div class=\"col-lg-4 col-sm-6 portfolio-item\">\n";//починаємо елемент товару

//$item['id'] - ідентифікатор товару

//$item['picture'] - зображення товару

//$item['title'] - назва товару

//$item['description'] - опис товару

          $o.="<div class=\"card h-100\">\n";

            $o.="<a href=\"/?q=product/".$item['id']."\"><img class=\"card-img-top\" src=\"/images/".$item['picture']."\" alt=\"\"></a>\n";

            $o.="<div class=\"card-body\">\n";

              $o.="<h4 class=\"card-title\">\n";

                $o.="<a href=\"/?q=product/".$item['id']."\">".$item['title']."</a>\n";

              $o.="</h4>\n";

                    $o.="<p class=\"card-text\">".$item['description']."</p>\n";

              $o.="<div style=\"width:100%\">".$t."</div>\n";//$t - таблиця характеристик зформована вище

            $o.="</div>\n";

          $o.="</div>\n";

        $o.="</div>\n";

                  return $o;//повертаємо елемент каталогу

            }

           

            function insert_pager(){//формує посторінкову навігацію

                  global $mysqli;//оголошуємо зв’язок з БД

                  $res=$mysqli->query("SELECT COUNT(*) as 'cnt' FROM `product`;");//виконуємо запит для з’ясування кількості товарів

                  $row=$res->fetch_assoc();//повертаємо рядок результату

                  $pc=$row['cnt'];//з’ясовуємо кількість товарів

                  $o="";//оголошуємо порожнюзмінну

                  if (isset($_GET['page'])) {$p=$_GET['page'];} else {$p=1;}//якщо сторінка не задана, вважаємо, що це 1ша сторінка

                  if ($pc>6) {//якщо кількість більше шести, тоді виводимо посторінкову навігацію

                    $o.="<ul class=\"pagination justify-content-center\">\n";

                    if ($p!=1) {//якщо поточна сторінка 1 тоді не виводимо кнопку попередня

                        $o.="<li class=\"page-item\">\n";

                          $o.="<a class=\"page-link\" href=\"/?q=products_catalog\" aria-label=\"Previous\">\n";

                             $o.="<span aria-hidden=\"true\">&laquo;</span>\n";

                             $o.="<span class=\"sr-only\">Previous</span>\n";

                          $o.="</a>\n";

                        $o.="</li>\n";

                    }

                        //виводимо поточну сторінку каталогу

                        $o.="<li class=\"page-item\">\n";

                          $o.="<a class=\"page-link\" href=\"#\">".$p."</a>\n";

                        $o.="</li>\n";

                       

                    if (($p*6)<$pc) {//якщо кількість товарів більша ніж поточна сторінка*6 виводимо кнопку наступна

                        $o.="<li class=\"page-item\">\n";

                          $o.="<a class=\"page-link\" href=\"/?q=products_catalog&page=".($p+1)."\" aria-label=\"Next\">\n";

                             $o.="<span aria-hidden=\"true\">&raquo;</span>\n";

                             $o.="<span class=\"sr-only\">Next</span>\n";

                          $o.="</a>\n";

                        $o.="</li>\n";

                    }

                    $o.="</ul>\n";

                  }

            return $o;//повертаємо сформовану навігацію

            }

           

            if (isset($_GET['page'])) {$p=$_GET['page'];} else {$p=1;}//якщо сторінка не задана, вжаємо, що ми на 1й сторінки

            $res=$mysqli->query("SELECT * FROM `product` LIMIT ".(($p-1)*6).",6;");//вибираємо із бд шість товарів поточної сторінки

            while ($row=$res->fetch_assoc()) {//перебираємо результат запиту по рядках

                  echo catalog_item($row);//виводимо на сторінку товар поточного рядка результату запиту

            }

           

            ?>

            <!-- Кінець функцій формування елементів каталогу -->

      </div>

 

<!-- Вставка посторінкової навігації -->

            <?php echo insert_pager(); //викликаємо функцію вставки посторінкової навігації

?>

    </div>

<!-- Блоки підвалу сторінки -->

 

    <!-- /.container -->

 

    <!-- Footer -->

    <footer class="py-5 bg-dark">

      <div class="container">

        <div class="row"><style>footer div.container div a {color:rgba(217, 219, 222, 1);}</style>

        <div class="col-lg-4" style="color:white;"><?php $block=get_block('footer_first');echo $block['block'];?></div>

        <div class="col-lg-4" style="color:white;"><?php $block=get_block('footer_second');echo $block['block'];?></div>

        <div class="col-lg-4" style="color:white;"><?php $block=get_block('footer_third');echo $block['block'];?></div>

        </div>

        <p class="m-0 text-center text-white">Copyright &copy; 2018</p>

      </div>

      <!-- /.container -->

    </footer>

 

    <!-- Bootstrap core JavaScript -->

    <script src="templates/vendor/jquery/jquery.min.js"></script>

    <script src="templates/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>

  </body>

</html>

 

                Хочеться відмітити, що у кожного із Вас свій сайт з товарами різного змісту тому характеристики відрізняються і ви маєте переписати формування елементу одиниці товару на свій лад. І ще, картока товара буде доступна за адресою product/<ідентифікатор одиниці товару>, але зараз посилання будуть вести внікуди, так як карточка товару - то наступна лабораторна робота.

Лишилося лише «навчити» наш завантажувач сайту (index.php). У файлі тільки рядки, які прокоментовані - нові, рядки без коментарів - із попередніх практичних.

<?php

 ini_set('display_errors', 1);

 ini_set('display_startup_errors', 1);

 error_reporting(E_ALL);

 

 require_once("database.php");

 require_once("block.php");

 require_once("menu.php");

 require_once("page.php");

 if (isset($_GET['q'])) {$q=$_GET['q'];} else {$q='/';}

 

 if ($q=='/') {include("templates/frontpage.php");}

  else {

      $res=$mysqli->query("SELECT * FROM `router` WHERE `link`='".mysql_escape($q)."';");

      //no record in router table, first parameter - type, second - entity_id

      if (!($row=$res->fetch_assoc())) {

            $qp=explode('/',$q);

            $row['type']=$qp[0];

            $row['entity_id']=$qp[1];

            }

      //додаємо тут обробник динамічних сторінок (тип php)

      if ($row['type']=='page') {//тип сторінка

            $page_id=$row['entity_id'];//з’ясовуємо ідентифікатор

            $p=get_page($page_id);//повертаємо дані сотрінки

            if ($p['type']=='html') include('templates/article.php');//якщо статична сотрінка

            if ($p['type']=='php') include($p['body']);//якщо сторінка динамічна то виконуємо скрипт який прописаний в полі тіло

            }

  }

?>

        Додано пізніше: Зміни зачепили і файл page.php, але це було неописано. Тому наведемо його зараз єдиний рядок який перетерпів зміни поміченмй зеленим комментарем.

<?php

 require_once("database.php");
 function get_page($pid){
 global $mysqli;
 $res=$mysqli->query("SELECT * FROM `page` WHERE `id`='".mysql_escape($pid)."';");
 $page=array();
 while ($row=$res->fetch_assoc()) {
  $page['title']=$row['title'];
  $page['body']=$row['body'];
  $page['type']=$row['type']; //додаємо до результату тип сторінки
  return $page;
 }
  return false; 
 }

?>

        В результаті наших маніпуляцій отримали ось такий каталог носків.