Egy egyszerű form elküldése, a HTTP POST metódus, DB INSERT, foglalás oldal

Bár a dolgok “belseje”, mégis nézzük csak meg, hogy a model rétegnek mit kell tudnia. A models/Reservations_model.php file tartalmazza az adatbázis beszúrást, azt a bizonyos DB INSERT-et a címből.

<?php
class Reservations_model extends CI_Model {

        public function insert_reservation() {    
                $date = date('Y-m-d H:i:s');
                $data = array(
                        'name' => $this->input->post('name'),
                        'email' => $this->input->post('email'),
                        'phone' => $this->input->post('phone'),
                        'message' => $this->input->post('message'),
                        'checkin' => $this->input->post('checkin'),
                        'checkout' => $this->input->post('checkout'),
                        'apartment_id' => 1,
                        'created_at' => $date,
                        'updated_at' => $date,
                        'locale' => $this->session->userdata('site_lang')
                );

                return $this->db->insert('reservations', $data);
        }

}

Az insert során vesszük a HTTP POST asszociatív tömbből a megfelelő értékeket, néhányat pedig “generálunk”, illetve “kiszámítunk”. Ilyen az apartment_id, a created_at, az updated_at és a locale (nyelv).

Ezt a model metódust a controller-ből fogjuk hívni. Picit megbonyolítottam ezt a controller-t, ahogy az látszani fog. Tettem bele egy viszonyag egyszerű validációt. A validáció vagyis ellenőrzés arra szolgál, hogy a formban – ahogy az példánkban látható – ne lehessen a név, email, foglalás tól-ig adatok megadása nélkül elküldeni a foglalást. 🙂

Nézzük a controllers/Apartments.php vezérlőnket! Kiegészítjük a booking() és a book() metódusokkal.

        public function booking()
        {
                $data = array();
                $data['validation_errors'] = '';
                if (!empty($this->session->flashdata('validation_errors'))) {
                        $data['validation_errors'] = $this->session->flashdata('validation_errors');
                }

                $this->template->set('title', $this->lang->line('menu_booking'));
                $this->template->load('menu_layout', 'contents', 'booking', $data);
        }

        public function book()
        {
                $this->load->library('form_validation');
                $this->form_validation->set_rules('name', 'Name', 'required');
                $this->form_validation->set_rules('email', 'Email', 'required');
                $this->form_validation->set_rules('checkin', 'Check-in', 'required');
                $this->form_validation->set_rules('checkout', 'Check-out', 'required');

                if ($this->form_validation->run() === FALSE) {
                        $this->session->set_flashdata('validation_errors', validation_errors());
                        redirect($_SERVER['HTTP_REFERER']);
                } else {
                        $this->load->model('reservations_model');
                        $this->reservations_model->insert_reservation();

                        $data = array();

                        $this->template->set('title', $this->lang->line('menu_booking'));
                        $this->template->load('menu_layout', 'contents', 'booking_accepted', $data);
                }
        }

Látható, hogy a book() metódusban hívjuk a modellünket, majd a booking_accepted oldalra irányítjuk a klienst. 🙂

Végül nézzük a két view-nkat. Előbb vegyük a formunkat tartalmazó views/booking.php állományt.

<?php
        $my_base_url = '/apartman/';
?>
                                <div class="row">
                                        <div class="col-sm-2">
                                                <div id="fh5co-logo"><a href="index.html">Apartman<span>.</span></a></div>
                                        </div>
                                        <div class="col-sm-10 text-right menu-1">
                                                <ul>
                                                        <li><a href="photos"><?php echo $this->lang->line('menu_photos'); ?></a></li>
                                                        <li class="active"><a href="booking"><?php echo $this->lang->line('menu_booking'); ?></a></li>
                                                        <li><a href="contact"><?php echo $this->lang->line('menu_contact'); ?></a></li>
                                                </ul>
                                        </div>
                                </div>
                                
                        </div>
                </div>
        </nav>
        <div class="container">
                <div id="fh5co-intro">
                        <div class="row animate-box">
                                <div class="col-md-8 col-md-offset-2 col-md-pull-2">
                                        <h2><?php echo $this->lang->line('menu_booking'); ?></h2>
                                </div>
                        </div>
                </div>
                <div id="fh5co-contact">
                        <div class="row">
                                <div class="col-md-4 animate-box">
                                        <h3>Contact Information</h3>
                                        <ul class="contact-info">
                                                <li><i class="icon-location4"></i>1117 Budapest, Irinyi J. utca 42.</li>
                                                <li><i class="icon-phone3"></i>+ 1235 2355 98</li>
                                                <li><i class="icon-location3"></i><a href="#">info@yoursite.com</a></li>
                                                <li><i class="icon-globe2"></i><a href="#">www.yoursite.com</a></li>
                                        </ul>
                                </div>
                                <div class="col-md-8 animate-box">
                                        <div class="form-wrap">
                                                <div class="row">
                                                        <form action="book" method="POST">
                                                        <?php if ($validation_errors) { ?>
                                                        <div class="col-md-12">
                                                                <div class="form-group">
                                                                        <h3><font color="red"><?php echo $validation_errors; ?></font></h3>
                                                                </div>
                                                        </div>
                                                        <?php } ?>
                                                        <div class="col-md-12">
                                                                <div class="form-group">
                                                                        <input type="text" name="name" class="form-control" placeholder="Name">
                                                                </div>
                                                        </div>
                                                        <div class="col-md-12">
                                                                <div class="form-group">
                                                                        <input type="text" name="email" class="form-control" placeholder="Email">
                                                                </div>
                                                        </div>
                                                        <div class="col-md-12">
                                                                <div class="form-group">
                                                                        <input type="text" name="phone" class="form-control" placeholder="Phone">
                                                                </div>
                                                        </div>
                                                        <div class="col-md-12">
                                                                <div class="form-group">
                                                                        <textarea name="message" class="form-control" id="" cols="30" rows="15" placeholder="Message"></textarea>
                                                                </div>
                                                        </div>
                                                        <div class="col-md-12">
                                                                <div class="form-group">
                                                                        <input type="text" name="checkin" class="form-control" placeholder="Check-in">
                                                                </div>
                                                        </div>
                                                        <div class="col-md-12">
                                                                <div class="form-group">
                                                                        <input type="text" name="checkout" class="form-control" placeholder="Check-out">
                                                                </div>
                                                        </div>
                                                        <div class="col-md-12">
                                                                <div class="form-group">
                                                                        <input type="submit" value="Book" class="btn btn-primary btn-modify">
                                                                </div>
                                                        </div>
                                                        </form>
                                                </div>
                                        </div>
                                </div>
                        </div>
                </div>
        </div><!-- END container -->

Ebben a fontos talán a $validation_errors változó kiíratása, illetve maga a form. Azt, hogy mi az action-je, és mi a metódus, az alábbi sor írja le.

<form action="book" method="POST">

Érdemes még megnézni a form egy mezőjének definiálását is.

<input type="text" name="name" class="form-control" placeholder="Name">

Ez annyit jelent, hogy szöveg beviteli mező, name névvel, ahol a vakszöveg a “Name” felirat lesz.

Fontos továbbá az elküldő gomb megadása is, més a form tag-en belül. A tag amúgy, HTML tag, azaz egy két kacsacsőr közé rejtett literál (sztring), amiben nincs további kacsacsőr karakter. Példa nyitó és záró tag-ekre: <form></form>. 🙂

<input type="submit" value="Book" class="btn btn-primary btn-modify">

Ez egy submit button – elküldő gomb, “Book” felirattal.

Ezt a formot a submit gomb megnyomása után a book() metódus fogja “megkapni” a controller-ben egy HTTP POST metódushívás után. A form mezőit egy a name attribútumokban megadott nevekkel kulcsolt asszociatív tömb fogja tartalmazni. Ennyi az egész! 🙂

Látható az adatbázisunkban, hogy a megfelelő rekord bekerült a reservations táblába (SQL konzol hozzáférés mysql -u apartman -p apartman_devel parancs kiadásával).

mysql> select * from reservations;
+----+-----------------+------------+------------+------------+------------+-----------------------+----------+--------------+---------+---------------------+---------------------+
| id | name            | email      | phone      | checkin    | checkout   | message               | approved | apartment_id | locale  | created_at          | updated_at          |
+----+-----------------+------------+------------+------------+------------+-----------------------+----------+--------------+---------+---------------------+---------------------+
|  5 | Gergely Vámosi  | mail@to.me | 0123456789 | 2020-07-29 | 2020-08-01 | Szeretnék egy szobát! |     NULL |            1 | english | 2020-07-29 01:33:20 | 2020-07-29 01:33:20 |
+----+-----------------+------------+------------+------------+------------+-----------------------+----------+--------------+---------+---------------------+---------------------+
1 row in set (0.00 sec)

Nézzük meg még a views/booking_accepted.php oldalt. Ez arról ad tájékoztatást az apartmant lefoglalni szándékozó ügyfélnek, hogy sikeres a foglalása!

<?php
        $my_base_url = '/apartman/';
?>
                                <div class="row">
                                        <div class="col-sm-2">
                                                <div id="fh5co-logo"><a href="index.html">Apartman<span>.</span></a></div>
                                        </div>
                                        <div class="col-sm-10 text-right menu-1">
                                                <ul>
                                                        <li><a href="photos"><?php echo $this->lang->line('menu_photos'); ?></a></li>
                                                        <li class="active"><a href="booking"><?php echo $this->lang->line('menu_booking'); ?></a></li>
                                                        <li><a href="contact"><?php echo $this->lang->line('menu_contact'); ?></a></li>
                                                </ul>
                                        </div>
                                </div>
                                
                        </div>
                </div>
        </nav>
        <div class="container">
                <div id="fh5co-intro">
                        <div class="row animate-box">
                                <div class="col-md-8 col-md-offset-2 col-md-pull-2">
                                        <h2><?php echo $this->lang->line('menu_booking'); ?></h2>
                                </div>
                        </div>
                </div>
                <div id="fh5co-contact">
                        <div class="row">
                                <div class="col-md-4 animate-box">
                                        <h3>Thanks for booking!</h3>
                                </div>
                        </div>
                </div>
        </div><!-- END container -->

Vegyük kicsit górcső alá a biztonságot! Hisz adatot közlünk a szerverrel, bármit beírhatunk a weblapon az űrlapba, amit pár szűrőn áteresztve adatbázisban tárolunk!

Először is érdemes megvizsgálni azt, hogy mit írhatunk be a mezőkbe: speciális karakterek, többek között a HTML formátum speciális jelei, a <>” és ‘ jelek. Aztán az ún. SQL injection veszélyei, amikor is az adatbáziselérésen keresztül speciális, például rosszakaratú SQL parancsokat tudunk kiadni, ami akár lehet egy ;DELETE FROM <TÁBLANÉV> pontosvessző után beszúrt parancs is akár. Szerencsés esetben ezeknek az eseteknek a kiszűrését a keretrendszerünk biztosítja. 🙂

Érdemes továbbá megvizsgálni az esetleges ún. CSRF – Cross-site request forgery veszélyét is. Bővebben a https://hu.wikipedia.org/wiki/Cross-site_request_forgery cím alatt olvashatunk róla. Röviden arról van szó, hogy a böngészőn keresztül nem kívánt parancsok hajthatók végre egy weblapon a felhasználó tudta nélkül. Ebbe a témakörbe tartozik egyébként még az XSS – Cross-site scripting is. A CSRF ellen egyébként többnyire egy minden formhoz (űrlapohoz) egyedileg generált azonosító, egy speciális kód véd, ami üzenetváltásonként újragenerált (töken). Ez véd többek között egy form újraküldése ellen, azaz adott esetben egy művelet (pl. fizetés) adott esetben rossz szándékú újbóli végrehajtása ellen. Az XSS csupán egy weblap funkcióinak más weblapbóli történő meghívása. 🙂 Játék. A baj, ha nem barátágos.

Aztán ott van az úgynevezett Captcha-teszt szükségessége is. Bővebben a https://hu.wikipedia.org/wiki/Captcha címen olvashatunk róla. Itt arról van szó, hogy weblapunk az emberi felhasználót megkülönböztesse egy generált robot, azaz gépi hozzáféréstől. Csak valós emberektől szeretnénk apartman foglalást elfogadni! Semmi esetre sem rossz szándékú hekkerek által készített programoktól. Ismerősök ugye az elhanyagolt facebook profilok mindenféle “fake” felhasználó általi “hello, ismerjük egymást” üzenetei? Főleg attraktív “csajoktól”? 🙂

És akkor lássuk a http://localhost/apartman/index.php/apartments/booking oldalt!

Egyszerű oldal létrehozása – képek oldal

Egy egyszerű oldalt az apartmanunkat bemutató képekkel három egyszerű lépésben hozhatunk létre. A demo képeket letöltöttük ingyenesen a https://www.pexels.com/ oldalról és előzőleg már előkészítettük.

Először is a controller-ünket kell megbűvölni. A controllers/Apartments.php file-hoz az alábbi sorokat fűzzük hozzá.

        public function photos()
        {
                $data = array();

                $this->template->set('title', $this->lang->line('menu_photos'));
                $this->template->load('menu_layout', 'contents', 'photos', $data);
        }

Másodjára létrehozzuk a views/layouts/menu_layout.php sablon-t, ami alapvetően annyival tud többet a default_layout.php file-unknál, hogy a menüt is meg lehet benne változtatni. Erre csupán azért van szükségünk, hogy az aktuális menüpont piros lehessen. 🙂

<?php
        $my_base_url = '/apartman/';
?>
<!DOCTYPE HTML>
<html>
        <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>Apartman - <?php echo $title;?></title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="description" content="Apartman booking website" />
        <meta name="keywords" content="apartman, booking, website" />
        <meta name="author" content="Gergely Vámosi" />

        <!-- 
        //////////////////////////////////////////////////////

        FREE HTML5 TEMPLATE 
        DESIGNED & DEVELOPED by FreeHTML5.co
                
        Website:                http://freehtml5.co/
        Email:                  info@freehtml5.co
        Twitter:                http://twitter.com/fh5co
        Facebook:               https://www.facebook.com/fh5co

        //////////////////////////////////////////////////////
         -->

        <!-- Facebook and Twitter integration -->
        <meta property="og:title" content=""/>
        <meta property="og:image" content=""/>
        <meta property="og:url" content=""/>
        <meta property="og:site_name" content=""/>
        <meta property="og:description" content=""/>
        <meta name="twitter:title" content="" />
        <meta name="twitter:image" content="" />
        <meta name="twitter:url" content="" />
        <meta name="twitter:card" content="" />

        <link href="https://fonts.googleapis.com/css?family=Open+Sans|Playfair+Display" rel="stylesheet">
        
        <!-- Animate.css -->
        <link rel="stylesheet" href="<?php echo $my_base_url?>assets/css/animate.css">
        <!-- Icomoon Icon Fonts-->
        <link rel="stylesheet" href="<?php echo $my_base_url?>assets/css/icomoon.css">
        <!-- Bootstrap  -->
        <link rel="stylesheet" href="<?php echo $my_base_url?>assets/css/bootstrap.css">

        <!-- Flexslider  -->
        <link rel="stylesheet" href="<?php echo $my_base_url?>assets/css/flexslider.css">

        <!-- Theme style  -->
        <link rel="stylesheet" href="<?php echo $my_base_url?>assets/css/style.css">

        <!-- Modernizr JS -->
<script src="<?php echo $my_base_url?>assets/js/modernizr-2.6.2.min.js"></script>
        <!-- FOR IE9 below -->
        <!--[if lt IE 9]>
<script src="<?php echo $my_base_url?>assets/js/respond.min.js"></script>
        <![endif]-->

        </head>
        <body>
                
        <div class="fh5co-loader"></div>
        
        <div id="page">
        <nav class="fh5co-nav" role="navigation">
                <div class="container">
                        <div class="top-menu">
                                <div class="row">
                                        <div class="col-sm-10 text-right menu-1">
                                                <ul>
                                                        <li><a style="font-size: 14px; padding: 5px 5px;" href="<?php echo $my_base_url?>index.php/LanguageSwitcher/switchLang/magyar">Magyar</a></li>
                                                        <li><a style="font-size: 14px; padding: 5px 5px;" href="<?php echo $my_base_url?>index.php/LanguageSwitcher/switchLang/english">English</a></li>
                                                        <li><a style="font-size: 14px; padding: 5px 5px;" href="<?php echo $my_base_url?>index.php/LanguageSwitcher/switchLang/deutsch">Deutsch</a></li>
                                                </ul>
                                        </div>
                                </div>
                                <div class="row">
                                        &nbsp;
                                </div>

                <!-- PAGE CONTENT BEGINS -->
                        <?php echo $contents;?>
                <!-- PAGE CONTENT ENDS -->

        <div class="container">
                <footer id="fh5co-footer" role="contentinfo">
                        <div class="row">
                                <div class="col-md-3 fh5co-widget">
                                        <h4>Az oldalról</h4>
                                        <p>Jogi információ.</p>
                                </div>
                                <div class="col-md-3 col-md-push-1">
                                        <h4>Lorem Ipsum</h4>
                                        <ul class="fh5co-footer-links">
                                                <li><a href="#">12345</a></li>
                                                <li><a href="#">67890</a></li>
                                        </ul>
                                </div>

                                <div class="col-md-3 col-md-push-1">
                                        <h4>Linkek</h4>
                                        <ul class="fh5co-footer-links">
                                                <li><a href="#">Home</a></li>
                                                <li><a href="#">Képek</a></li>
                                                <li><a href="#">Foglalás</a></li>
                                                <li><a href="#">Kapcsolat</a></li>
                                        </ul>
                                </div>

                                <div class="col-md-3">
                                        <h4>Kapcsolat</h4>
                                        <ul class="fh5co-footer-links">
                                                <li>Kossuth utca 10,<br>1111 Budapest</li>
                                                <li><a href="tel://1234567920">+ 1235 2355 98</a></li>
                                                <li><a href="mailto:info@yoursite.com">info@yoursite.com</a></li>
                                                <li><a href="http://localhost/apartman">apartman</a></li>
                                        </ul>
                                </div>

                        </div>

                        <div class="row copyright">
                                <div class="col-md-12 text-center">
                                        <p>
                                                <small class="block">&copy; 2016 Free HTML5. All Rights Reserved.</small>
                                                <small class="block">Designed by <a href="http://freehtml5.co/" target="_blank">FreeHTML5.co</a> Demo Images: <a href="http://unsplash.co/" target="_blank">Unsplash</a></small>
                                        </p>
                                        <p>
                                                <ul class="fh5co-social-icons">
                                                        <li><a href="#"><i class="icon-twitter"></i></a></li>
                                                        <li><a href="#"><i class="icon-facebook"></i></a></li>
                                                        <li><a href="#"><i class="icon-linkedin"></i></a></li>
                                                        <li><a href="#"><i class="icon-dribbble"></i></a></li>
                                                </ul>
                                        </p>
                                </div>
                        </div>
                </footer>
        </div><!-- END container -->
        </div>

        <div class="gototop js-top">
                <a href="#" class="js-gotop"><i class="icon-arrow-up2"></i></a>
        </div>
        
        <!-- jQuery -->
<script src="<?php echo $my_base_url?>assets/js/jquery.min.js"></script>
        <!-- jQuery Easing -->
<script src="<?php echo $my_base_url?>assets/js/jquery.easing.1.3.js"></script>
        <!-- Bootstrap -->
<script src="<?php echo $my_base_url?>assets/js/bootstrap.min.js"></script>
        <!-- Waypoints -->
<script src="<?php echo $my_base_url?>assets/js/jquery.waypoints.min.js"></script>
        <!-- Flexslider -->
<script src="<?php echo $my_base_url?>assets/js/jquery.flexslider-min.js"></script>
        <!-- Sticky Kit -->
<script src="<?php echo $my_base_url?>assets/js/sticky-kit.min.js"></script>
        <!-- Main -->
<script src="<?php echo $my_base_url?>assets/js/main.js"></script>

        </body>
</html>

Harmadjára pedig hozzuk létre a sablonban a $contents helyére kerülő views/photos.php file-t.

<?php
        $my_base_url = '/apartman/';
?>
                                <div class="row">
                                        <div class="col-sm-2">
                                                <div id="fh5co-logo"><a href="index.html">Apartman<span>.</span></a></div>
                                        </div>
                                        <div class="col-sm-10 text-right menu-1">
                                                <ul>
                                                        <li class="active"><a href="photos"><?php echo $this->lang->line('menu_photos'); ?></a></li>
                                                        <li><a href="booking"><?php echo $this->lang->line('menu_booking'); ?></a></li>
                                                        <li><a href="contact"><?php echo $this->lang->line('menu_contact'); ?></a></li>
                                                </ul>
                                        </div>
                                </div>
                                
                        </div>
                </div>
        </nav>
        <div class="container">
                <div id="fh5co-intro">
                        <div class="row animate-box">
                                <div class="col-md-8 col-md-offset-2 col-md-pull-2">
                                        <h2><?php echo $this->lang->line('menu_photos'); ?></h2>
                                </div>
                        </div>
                </div>
                <div id="fh5co-portfolio">
                        <div class="row">

                                <div class="col-md-4 col-md-push-8 sticky-parent">
                                        <div class="detail" id="sticky_item">
                                                <div class="animate-box">
                                                        <h2>Lorem ipsum</h2>
                                                        <span>Lorem ipsum dolor sit amet</span>
                                                        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
                                                        <p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p>
                                                        <p><a class="btn btn-primary btn-demo" href="#"></i> Lorem ipsum</a></p>
                                                </div>
                                        </div>
                                </div>

                                <div class="col-md-7 col-md-pull-4 image-content">
                                        <div class="image-item  animate-box">
                                                <img src="<?php echo $my_base_url?>assets/images/kitchen_480_.jpg" class="img-responsive" alt="Photo by Dmitry Zvolskiy from Pexels">
                                        </div>
                                        <div class="image-item  animate-box">
                                                <img src="<?php echo $my_base_url?>assets/images/interior_480.jpg" class="img-responsive" alt="Photo by Daria Shevtsova from Pexels">
                                        </div>
                                        <div class="image-item  animate-box">
                                                <img src="<?php echo $my_base_url?>assets/images/livingroom_480.jpg" class="img-responsive" alt="Photo by Daria Shevtsova from Pexels">
                                        </div>
                                        <div class="image-item  animate-box">
                                                <img src="<?php echo $my_base_url?>assets/images/bedroom_480.jpg" class="img-responsive" alt="https://www.pexels.com/">
                                        </div>
                                        <div class="image-item  animate-box">
                                                <img src="<?php echo $my_base_url?>assets/images/bathroom_480.jpg" class="img-responsive" alt="Photo by Jean van der Meulen from Pexels">
                                        </div>
                                </div>

                        </div>
                </div>
        </div><!-- END container-wrap -->

Ennyi az egész! Máris láthatjuk a http://localhost/apartman/index.php/apartments/photos cím alatt a szépséges “Képek” oldalunkat!

Többnyelvűség implementálása: Magyar, English, Deutsch

Szeretnénk, ha az oldalunk több nyelven is tudna, mivel lehetnek az apartmannak külföldi vendégei is.

A CodeIgniter ezt alapból jól megtámogatja úgynevezett nyelvi file-okkal, illetve a hook funkcióval, nézzünk a megvalósításra egy egyszerű utat. Az alábbi webhelyen elég jó útmutatást kapunk, csupán egy picit változtatunk az implementáción.

http://programmerblog.net/multilingual-website-in-codeigniter/

Először hozzunk létre nyelvi könyvtárakat. Nálunk az alapértelmezett nyelv a magyar lesz (angol, “english” ugye már alapból van).

gvamosi@gergo1:/var/www/html/apartman/application$ mkdir language/magyar
gvamosi@gergo1:/var/www/html/apartman/application$ mkdir language/deutsch

Az language/magyar/base_lang.php file tartalma a követező legyen.

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

$lang['menu_photos'] = 'Képek';
$lang['menu_booking'] = 'Foglalás';
$lang['menu_contact'] = 'Kapcsolat';
?>

Erre a mintára készüljön az angol nyelvű nyelvi file is: language/english/base_lang.php.

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

$lang['menu_photos'] = 'Photos';
$lang['menu_booking'] = 'Booking';
$lang['menu_contact'] = 'Contact';
?>

Majd a német is: language/deutsch/base_lang.php. 🙂

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

$lang['menu_photos'] = 'Fotos';
$lang['menu_booking'] = 'Reservieren';
$lang['menu_contact'] = 'Kontakt';
?>

A config/config.php-ban engedélyeznünk kell a hook funkciót.

$config['enable_hooks'] = TRUE;

Meg kell írnunk a hook-unkat a config/hooks.php file-ban.

$hook['post_controller_constructor'] = array(
	'class' => 'LanguageLoader',
	'function' => 'initialize',
	'filename' => 'LanguageLoader.php',
	'filepath' => 'hooks'
);

Az application könyvtár alatt létre kell hozzuk a hooks/LanguageLoader.php osztályt.

<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class LanguageLoader
{
   function initialize() {
       $ci =& get_instance();
       $ci->load->helper('language');
       $siteLang = $ci->session->userdata('site_lang');
       if ($siteLang) {
           $ci->lang->load('base', $siteLang);
       } else {
           $ci->lang->load('base', 'magyar');
       }
   }
}
?>

Ezután létre kell hoznunk egy controller-t történetesen controllers/LanguageSwitcher.php néven.

<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class LanguageSwitcher extends CI_Controller {
  public function __construct(){
    parent::__construct();
  }
  public function switchLang($language = "") {
    $this->session->set_userdata('site_lang', $language);
    redirect($_SERVER['HTTP_REFERER']);
  }
}

Némi magyarázatot fűznék a fenti két kódblokkhoz. A “session” magyar fordítáa munkamenet szokott lenni. Ha itt beállítunk egy változó értéket, akkor kliens oldalon a browser-ben egy weblaphoz kötött változót, egy ún. cookie-t, magyarul sütit tárol el a szerver alkalmazás ilyenkor. A szerver gép pedig az adott süti által meghatározott böngésző munkamenethez egy session változót regisztrál, esetünkben az oldal nyelvét, vagyis hogy magyar, angol vagy német nyelven kívánjuk olvasni az weblapot. Nagyon szépen meg lehet ezt nézni pl. a Chrome böngészőben a Developer Tools-ban az Application / Storage / Cookies rész alatt. Ott találunk egy localhost-tól bejegyzett sütit, ci_session néven, egy egyedi azonosítóval, egy ID-vel. A webszerverünkön a session, vagyis a HTTP SESSION egy idő után, ha nem történik újabb kommunikáció a weboldalon a szerver és a kliens között, elévül és törlődik. Milyen elmés! 🙂

Magyarázzuk meg még a “HTTP_REFERER” HTTP header, magyarul fejléc változó használatát. A HTTP kérés és válasz tartalmaz egy fejlécet és egy törzset (body), mint minden normális IP üzenet. Ez a fejléc érték azt az url-t tartalmazza, ahonnan az adott url-t “hívtuk”. Ebben a megoldásban, mivel bármely oldalon állíthatjuk a nyelvet, a hívó oldalra visszairányítjuk automatikusan a klienst, miután a /LanguageSwitcher/switchLang/<NYELV> url segítségével a megfelelő controller-ben átállítottuk a nyelvet a session-ben. 🙂

Bővebben az előbbiekről a https://hu.wikipedia.org/wiki/HTTP-s%C3%BCti és a https://hu.wikipedia.org/wiki/Referer címeken olvashatunk.

Ezután nem marad más hátra, mint “bedrótozni” egy menüstruktúrát a sablonfile-unkban, illetve a $this->lang->line('message') hívással előszedni a megfelelő sztringeket a nyelvi file-okból. Nézzük az új navigációt.

        <nav class="fh5co-nav" role="navigation">
                <div class="container">
                        <div class="top-menu">
                                <div class="row">
                                        <div class="col-sm-10 text-right menu-1">
                                                <ul>
                                                        <li><a style="font-size: 14px; padding: 5px 5px;" href="<?php echo $my_base_url?>index.php/LanguageSwitcher/switchLang/magyar">Magyar</a></li>
                                                        <li><a style="font-size: 14px; padding: 5px 5px;" href="<?php echo $my_base_url?>index.php/LanguageSwitcher/switchLang/english">English</a></li>
                                                        <li><a style="font-size: 14px; padding: 5px 5px;" href="<?php echo $my_base_url?>index.php/LanguageSwitcher/switchLang/deutsch">Deutsch</a></li>
                                                </ul>
                                        </div>
                                </div>
                                <div class="row">
                                        &nbsp;
                                </div>
                                <div class="row">
                                        <div class="col-sm-2">
                                                <div id="fh5co-logo"><a href="index.html">Apartman<span>.</span></a></div>
                                        </div>
                                        <div class="col-sm-10 text-right menu-1">
                                                <ul>
                                                        <li class="active"><a href="index.html"><?php echo $this->lang->line('menu_photos'); ?></a></li>
                                                        <li><a href="single.html"><?php echo $this->lang->line('menu_booking'); ?></a></li>
                                                        <li><a href="contact.html"><?php echo $this->lang->line('menu_contact'); ?></a></li>
                                                </ul>
                                        </div>
                                </div>
                                
                        </div>
                </div>
        </nav>

Kész a többnyelvű oldalunk! 🙂

Refactoring (a kód újra rendszerezése), templating (sablonok használata) és menü

A legutóbbi fejezetben megírtuk a Hello, Világ! oldalunkat. Most ezt egy kicsit újra rendszerezzük. Bár kétségkívűl jól mutat, most mégis eltávolítjuk a controller-ből a _controller utótagot. 🙂

Ezt néhány file-átnevezéssel, illetve pár sornyi kódmódosítással megtehetjük. A hivatkozások miatt (referenciák) ezt a műveletet nyilván körültekintéssel kell elvégeznünk. Így az oldalunkat az alábbi címen is elérhetjük.

http://localhost/apartman/index.php/apartments/index

Ahol az apartments a controller neve, az index pedig a megfelelő metódus. Ez egy ún. beszédes url, a RESTful architektúrának (https://hu.wikipedia.org/wiki/REST) megfelel.

Miután ezzel megvagyunk, keressünk egy ingyenes sablont az interneten. Az alábbi némi keresés után pont megfelelő. Ez egy ingyenes jQuery és Bootstrap alapokra épülő HTML5-ös sablon. A jQuery java script könyvtárnak a https://jquery.com/ oldalon, a Bootstrap front-end toolkit-nek pedig a https://getbootstrap.com/ oldalon lehet utánanézni. Fontos szempont egy modern weblapnál, hogy jól olvasható legyen okostelefonon is. Ez a gyakorlatban azt jelenti, hogy bizonyos szélesség alatt hamburgermenü jelenik meg az oldalon, illetve a több hasábos megjelenés összecsúszik egyetlen hasábba.

https://freehtml5.co/architect-free-html5-bootstrap-template-for-architects-and-portfolio-websites/

A sablont kibontjuk, majd a benne található css, fonts, images és js könyvtárakat az application gyökér könyvtárral egy szinten újonnan létrehozott assets könyvtárba másoljuk.

A sablon beillesztését az alábbi weboldalon leírt módon végezzük.

https://www.phpflow.com/php/creating-template-codeigniter-3-using-bootstrap-theme/

Az index.php eltűntetésével (mod_rewrite apache modul) nagyvonalúan nem foglalkozunk. Extrémsportolók beállíthatják önszorgalomból. 🙂

A libraries könyvtárban létrehozzuk a Template.php állományt az alábbi tartalommal.

<?php
class Template {
                //ci instance
                private $CI;
                //template Data
                var $template_data = array();
 
                public function __construct() 
                {
                                $this->CI =& get_instance();
                }
 
                function set($content_area, $value)
                {
                                $this->template_data[$content_area] = $value;
                }
 
                function load($template = '', $name ='', $view = '' , $view_data = array(), $return = FALSE)
                {
                                $this->set($name , $this->CI->load->view($view, $view_data, TRUE));
                               
                                $this->CI->load->view('layouts/'.$template, $this->template_data);
                }
                               
}
?>

Látható, hogy ez egy igen egyszerű implementáció, egy set és egy load függvénnyel. Többre azonban nincs szükségünk. 🙂

A views könyvtár alatt (az appplication gyökérben) hozzunk létre egy layouts könyvtárat. Ebbe fog kerülni a sablonunk, a default_layout.php file.

<?php
        $my_base_url = '/apartman/';
?>
<!DOCTYPE HTML>
<html>
        <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>Apartman - <?php echo $title;?></title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="description" content="Apartman booking website" />
        <meta name="keywords" content="apartman, booking, website" />
        <meta name="author" content="Gergely Vámosi" />

        <!-- 
        //////////////////////////////////////////////////////

        FREE HTML5 TEMPLATE 
        DESIGNED & DEVELOPED by FreeHTML5.co
                
        Website:                http://freehtml5.co/
        Email:                  info@freehtml5.co
        Twitter:                http://twitter.com/fh5co
        Facebook:               https://www.facebook.com/fh5co

        //////////////////////////////////////////////////////
         -->

        <!-- Facebook and Twitter integration -->
        <meta property="og:title" content=""/>
        <meta property="og:image" content=""/>
        <meta property="og:url" content=""/>
        <meta property="og:site_name" content=""/>
        <meta property="og:description" content=""/>
        <meta name="twitter:title" content="" />
        <meta name="twitter:image" content="" />
        <meta name="twitter:url" content="" />
        <meta name="twitter:card" content="" />

        <link href="https://fonts.googleapis.com/css?family=Open+Sans|Playfair+Display" rel="stylesheet">
        
        <!-- Animate.css -->
        <link rel="stylesheet" href="<?php echo $my_base_url?>assets/css/animate.css">
        <!-- Icomoon Icon Fonts-->
        <link rel="stylesheet" href="<?php echo $my_base_url?>assets/css/icomoon.css">
        <!-- Bootstrap  -->
        <link rel="stylesheet" href="<?php echo $my_base_url?>assets/css/bootstrap.css">

        <!-- Flexslider  -->
        <link rel="stylesheet" href="<?php echo $my_base_url?>assets/css/flexslider.css">

        <!-- Theme style  -->
        <link rel="stylesheet" href="<?php echo $my_base_url?>assets/css/style.css">

        <!-- Modernizr JS -->
<script src="<?php echo $my_base_url?>assets/js/modernizr-2.6.2.min.js"></script>
        <!-- FOR IE9 below -->
        <!--[if lt IE 9]>
<script src="<?php echo $my_base_url?>assets/js/respond.min.js"></script>
        <![endif]-->

        </head>
        <body>
                
        <div class="fh5co-loader"></div>
        
        <div id="page">
        <nav class="fh5co-nav" role="navigation">
                <div class="container">
                        <div class="top-menu">
                                <div class="row">
                                        <div class="col-sm-2">
                                                <div id="fh5co-logo"><a href="index.html">Apartman<span>.</span></a></div>
                                        </div>
                                        <div class="col-sm-10 text-right menu-1">
                                                <ul>
                                                        <li class="active"><a href="index.html">Képek</a></li>
                                                        <li><a href="single.html">Foglalás</a></li>
                                                        <li><a href="contact.html">Kapcsolat</a></li>
                                                </ul>
                                        </div>
                                </div>
                                
                        </div>
                </div>
        </nav>
        <div class="container">
                <div id="fh5co-intro">
                        <div class="row animate-box">
                                <div class="col-md-8 col-md-offset-2 col-md-pull-2">
                                        <h2>Apartman kiadó.</span></h2>
                <!-- PAGE CONTENT BEGINS -->
                        <?php echo $contents;?>
                <!-- PAGE CONTENT ENDS -->
                                </div>
                        </div>
                </div>
        </div><!-- END container -->

        <div class="container">
                <footer id="fh5co-footer" role="contentinfo">
                        <div class="row">
                                <div class="col-md-3 fh5co-widget">
                                        <h4>Az oldalról</h4>
                                        <p>Jogi információ.</p>
                                </div>
                                <div class="col-md-3 col-md-push-1">
                                        <h4>Lorem Ipsum</h4>
                                        <ul class="fh5co-footer-links">
                                                <li><a href="#">12345</a></li>
                                                <li><a href="#">67890</a></li>
                                        </ul>
                                </div>

                                <div class="col-md-3 col-md-push-1">
                                        <h4>Linkek</h4>
                                        <ul class="fh5co-footer-links">
                                                <li><a href="#">Home</a></li>
                                                <li><a href="#">Képek</a></li>
                                                <li><a href="#">Foglalás</a></li>
                                                <li><a href="#">Kapcsolat</a></li>
                                        </ul>
                                </div>

                                <div class="col-md-3">
                                        <h4>Kapcsolat</h4>
                                        <ul class="fh5co-footer-links">
                                                <li>Kossuth utca 10,<br>1111 Budapest</li>
                                                <li><a href="tel://1234567920">+ 1235 2355 98</a></li>
                                                <li><a href="mailto:info@yoursite.com">info@yoursite.com</a></li>
                                                <li><a href="http://localhost/apartman">apartman</a></li>
                                        </ul>
                                </div>

                        </div>

                        <div class="row copyright">
                                <div class="col-md-12 text-center">
                                        <p>
                                                <small class="block">&copy; 2016 Free HTML5. All Rights Reserved.</small>
                                                <small class="block">Designed by <a href="http://freehtml5.co/" target="_blank">FreeHTML5.co</a> Demo Images: <a href="http://unsplash.co/" target="_blank">Unsplash</a></small>
                                        </p>
                                        <p>
                                                <ul class="fh5co-social-icons">
                                                        <li><a href="#"><i class="icon-twitter"></i></a></li>
                                                        <li><a href="#"><i class="icon-facebook"></i></a></li>
                                                        <li><a href="#"><i class="icon-linkedin"></i></a></li>
                                                        <li><a href="#"><i class="icon-dribbble"></i></a></li>
                                                </ul>
                                        </p>
                                </div>
                        </div>
                </footer>
        </div><!-- END container -->
        </div>

        <div class="gototop js-top">
                <a href="#" class="js-gotop"><i class="icon-arrow-up2"></i></a>
        </div>
        
        <!-- jQuery -->
<script src="<?php echo $my_base_url?>assets/js/jquery.min.js"></script>
        <!-- jQuery Easing -->
<script src="<?php echo $my_base_url?>assets/js/jquery.easing.1.3.js"></script>
        <!-- Bootstrap -->
<script src="<?php echo $my_base_url?>assets/js/bootstrap.min.js"></script>
        <!-- Waypoints -->
<script src="<?php echo $my_base_url?>assets/js/jquery.waypoints.min.js"></script>
        <!-- Flexslider -->
<script src="<?php echo $my_base_url?>assets/js/jquery.flexslider-min.js"></script>
        <!-- Sticky Kit -->
<script src="<?php echo $my_base_url?>assets/js/sticky-kit.min.js"></script>
        <!-- Main -->
<script src="<?php echo $my_base_url?>assets/js/main.js"></script>

        </body>
</html>

A config/autoload.php file-ban az alábbi módosítástokat eszközöljük.

// templating added by me on 2020/07/23
$autoload['libraries'] = array('database','session','template');
// added by  me on 2020/07/23
$autoload['helper'] = array('url');

A controllers/Apartments.php controller-ünkbe pedig illesszük be a sablonkezelést.

//$this->load->view('apartments', $data);

$this->template->set('title', 'Home');
$this->template->load('default_layout', 'contents' , 'apartments', $data);

Tesztelhetjük az új oldalunkat! 🙂

http://localhost/apartman/index.php/apartments/index

CodeIgniter modell réteg az adatbázissal és a Hello, World!

Programozóknak ugyan nem kell bemutatni Hello, World! fogalmát, de most kell hogy beszéljünk róla. A mai fejezetben szeretnénk létrehozni az adatbázist MySQL-ben, legyártani a modell réteget, majd adattal feltölteni, és a weben megjelentíteni. Mindezt mind saját kézzel írt kóddal, lehetőleg kevés kódsorban megvalósítva! Ez a Hello, World! – Helló, Világ! példánkban.

https://en.wikipedia.org/wiki/%22Hello,_World!%22_program

Hozzunk létre egy adatbázist a MySQL szerverünkön a https://wlammpp.wordpress.com/2019/10/04/i-resz-wordpress-webfejlesztes-a-wordpress-telepitese korábbi fejezetben ismertetett módon. Van egy adatbázis dump-om, ezt kell “bejátszani”.

-- MySQL dump 10.13 Distrib 5.7.29, for Linux (x86_64)
-- Host: localhost Database: evaap_devel

-- Server version 5.7.29
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table apartments
DROP TABLE IF EXISTS apartments;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE apartments (
id bigint(20) NOT NULL AUTO_INCREMENT,
name varchar(255) DEFAULT NULL,
address varchar(255) DEFAULT NULL,
created_at datetime NOT NULL,
updated_at datetime NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table apartments
LOCK TABLES apartments WRITE;
/*!40000 ALTER TABLE apartments DISABLE KEYS */;
INSERT INTO apartments VALUES (1,'Budapest I','VII. kerulet','2020-03-20 00:26:35','2020-03-20 00:26:35');
/*!40000 ALTER TABLE apartments ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table reservations
DROP TABLE IF EXISTS reservations;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE reservations (
id bigint(20) NOT NULL AUTO_INCREMENT,
name varchar(255) DEFAULT NULL,
email varchar(255) DEFAULT NULL,
phone varchar(255) DEFAULT NULL,
checkin date DEFAULT NULL,
checkout date DEFAULT NULL,
message text,
approved tinyint(1) DEFAULT NULL,
apartment_id int(11) DEFAULT NULL,
locale varchar(255) DEFAULT NULL,
created_at datetime NOT NULL,
updated_at datetime NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table users
DROP TABLE IF EXISTS users;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE users (
id bigint(20) NOT NULL AUTO_INCREMENT,
name varchar(255) DEFAULT NULL,
email varchar(255) DEFAULT NULL,
password varchar(255) DEFAULT NULL,
is_admin tinyint(1) DEFAULT NULL,
created_at datetime NOT NULL,
updated_at datetime NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table users
LOCK TABLES users WRITE;
/*!40000 ALTER TABLE users DISABLE KEYS */;
INSERT INTO users VALUES (1,'admin','gvamosi@linux.hu','manager',1,'2020-03-19 00:00:00','2020-03-19 00:00:00');
/*!40000 ALTER TABLE users ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2020-04-07 14:05:14

Az alábbi módon:

gvamosi@gergo1:/var/www/html/apartman$ mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 50
Server version: 5.7.29 MySQL Community Server (GPL)
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> CREATE DATABASE apartman_devel CHARACTER SET utf8 COLLATE utf8_general_ci;
Query OK, 1 row affected (0.01 sec)
mysql> CREATE USER 'apartman'@'localhost' IDENTIFIED BY 'apartman1';
Query OK, 0 rows affected (0.02 sec)
mysql> GRANT ALL PRIVILEGES ON apartman_devel.* TO 'apartman'@'localhost';
Query OK, 0 rows affected (0.00 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.01 sec)
mysql> \q
Bye
gvamosi@gergo1:/var/www/html/apartman$ mysql -u apartman -p apartman_devel < db/create_and_insert_tables.sql
Enter password:
gvamosi@gergo1:/var/www/html/apartman$

Hozzuk létre az alkalmazás modell rétegét! Ehhez először be kell konfigurálnunk az adatbázist.

gvamosi@gergo1:/var/www/html/apartman/application$ vi config/database.php

$db['default'] = array(
'dsn' => '',
'hostname' => 'localhost',
'username' => 'apartman',
'password' => 'apartman1',
'database' => 'apartman_devel',
'dbdriver' => 'mysqli',
'dbprefix' => '',
'pconnect' => FALSE,
'db_debug' => (ENVIRONMENT !== 'production'),
'cache_on' => FALSE,
'cachedir' => '',
'char_set' => 'utf8',
'dbcollat' => 'utf8_general_ci',
'swap_pre' => '',
'encrypt' => FALSE,
'compress' => FALSE,
'stricton' => FALSE,
'failover' => array(),
'save_queries' => TRUE
);

Ez eddig 3 string (karakterlánc)! 🙂 Aztán meg kell írnunk az Apartments_model.php file-t!

gvamosi@gergo1:/var/www/html/apartman/application$ vi models/Apartments_model.php

<?php
class Apartments_model extends CI_Model {
public function get_last_ten_entries()
{
$query = $this->db->get('apartments', 10);
return $query->result();
}
}

Ez 8 sor. 🙂 Most írjuk meg a controller-t!

gvamosi@gergo1:/var/www/html/apartman/application$ vi controllers/Apartments_controller.php
<?php
class Apartments_controller extends CI_Controller {
public function index() {
echo 'Helló, Világ!!';
$this->load->model('apartments_model');
$data['query'] = $this->apartments_model->get_last_ten_entries();
$this->load->view('apartments', $data);
}
}

Ez újabb 9 sor! Nem sok ez egy listáért? És akkor írjuk meg a view-t is!

gvamosi@gergo1:/var/www/html/apartman/application/views$ vi apartments.php

<ul>
<?php foreach ($query as $item):?>
<li><?php echo $item->address;?></li>
<?php endforeach;?>
</ul>

Ez húzós 5 sor! 🙂 Állítsuk be az útvonalakat, az autoload-ot (még két sor :)), majd hívjuk meg a következő módon a böngészőnkből az “oldalunkat”!

gvamosi@gergo1:/var/www/html/apartman/application$ vi config/routes.php
$route['apartmanok'] = 'apartments_controller/index';

gvamosi@gergo1:/var/www/html/apartman/application$ vi config/autoload.php
$autoload['libraries'] = array('database','session');

http://localhost/apartman/index.php/apartmanok

Listázza az egy darab apartmanunk címét, Budapesten. Siker! 🙂

II. rész – Airbnb apartman foglalás – esettenulmány – PHP CodeIgniter keretrendszerben

Amint megígértem, ebben az évben folytatom, és remélhetőleg be is fejezem a webprogramozásról szóló online könyvemet. 🙂

Hogy jobban megértsük a webprogramozást, egy kis architektúrális ismertetőt kell tartsak. Általánosságban már szóltam a kliens-szerver felépítésről (https://wlammpp.wordpress.com/2019/10/03/mit-ertunk-webprogramozas-webfejlesztes-alatt). Egy webes alkalmazás a felhasználóval a böngészőn (browser) keresztül “lép interaktív kapcsolatba”. Ez azt jelenti, hogy a felhsználó egy böngésző ablakban illetve tabfülön keresztül látja illetve használja a grafikus felhasználói felületet (GUI – graphical user interface, ide tartozik még a népszerű Ui / UX Design fogalma, vagyis a felhasználói felület és élmény tervezés). A felhasználó az alkalmazás funkcióit a böngészőben megjelenő felületen keresztül éri el: elolvas információkat, regisztrál egy webes űrlapon (formon) keresztül, keres, navigál, “kattint” (click-el). Ezek közül komolyabb programozást az űrlapkitöltés és a keresés igényel, illetve a különböző grafikai látványelemek is.

Az egész webprogramozás illetve -fejlesztés azért tűnhet bonyolultnak, mert egyrészt kellenek a “szerver oldali” dolgok: egy adatbázis – esetünkben relációs -, amit az ún. SQL nyelven lehet manipuláni, lekérdezni, feltölteni, frissíteni illetve törölni (https://hu.wikipedia.org/wiki/SQL), továbbá egy beágyazott, illetve szerver oldalon értelmezett (ún. script) nyelv, ez a PHP 7-es verzió konkrét esetünkben (https://www.php.net/), amely a funkcionalitást, az “üzleti folyamatot” valósítja meg (implementálja). A PHP Hyprtext Preprocessor-nak hirdeti magát, ami azt jelenti, hogy a HTML nyelven (ez a weblapok nyelve) írt hypertext-be van beágyazva, amit a webszerverünk megfelelő modulja értelmez, amikor valaki az adott weboldalt a böngészőjében megnyitja. Tehát nincs előre lefordítva, mint például egy C nyelven írt kernel modul (Linux), hanem “on the fly” fordul (compile), és “fut” (run). Ezt szemléltetném is egy pár soros kódban.

<!DOCTYPE html>
<html>
<head>
<title>Lapcím</title>
</head>
<body>

<h1>Ez egy címsor.</h1>
<p>Ez egy bekezdés.</p

<!-- Ez egy megjegyzés. Ide jön a PHP kódrészlet. -->

<?php
phpinfo();
?>

</body>
</html>

Ebben a rövid kódrészletben (snippet) ún. HTML tag-eket láthatunk. Az eleje egy dokumentum típus megjelölés, majd html, head – fejléc, body – törzs olvashatóak. Látható, hogy <? ?> jelek között van a PHP kódrészlet, ami konkrétan egy hosszú és részletes kiírást eszközöl a szerverünk beállításáról, ha megnézzük böngészőben (írtam már róla itt: https://wlammpp.wordpress.com/2019/10/04/i-resz-wordpress-webfejlesztes-a-wordpress-telepitese). Ezek a tag-ek mind “kacsacsőrök” között vannak. Ez a leíró nyelvek sajátossága. Az XML is ilyen formátumú. 🙂

A HTML oldal önmagában statikus, ha pl. PHP kódrészletet nem tartalmaz. Lehet benne hivatkozás képre, hangra, videóra, tehát Hypertext, ugyanakkor nem igényel szerveroldali processzálást (feldolgozást). Ezért a szerveren statikus oldalként kerül kiszolgálásra. Erre általában az oldalt tartalmazó állomány nevének kiterjesztése utal, ez többnyire .html – PHP oldalak esetében pedig .php. A nagy különbség egy “honlap” és egy “webalkalmazás” között abban rejlik, hogy milyen és mennyi “kód” van mögötte és benne a szerveren, illetve a kliens oldalon JavaScript formájában, értsd: hogy mennyire interaktív. Alábbiakban egy kis összefoglaló a HTML struktúráról, a tag-ekről.

<!-- Nyitó és záró tag, közte a tartalom. -->
<tagnev>Töltelék.</tagnev>

<!-- Önmagában záródó tag (XML helyes), paraméterekkel. -->
<tagnev parameter1="ertek1" parameter2="ertek2" />

<!-- A legegyszerűbb "beágyazás". -->
<tag1>
<tag2 />
</tag1>

Ha ez már bonyolult volna, szólnom kell még a kliens oldalon fontossá váló komponensekről. Ezek az előbbiekben taglalt az oldalak alapvető struktúrájáért és megjelenéséért felelős HTML (Hypertext Markup Language – https://www.w3schools.com/html/), a látványért felelős CSS (https://hu.wikipedia.org/wiki/Cascading_Style_Sheets, https://www.w3schools.com/css/) illetve a dinamikus működésért felelős JavaScript (https://www.w3schools.com/js/) nyelveken implementált böngészőben futó, “héj” réteg. A könyv legelején taglalt MVC architektúra (Model – View – Controller) View – nézet rétegéről szól ez a kliens oldali rész. A dinamikus működést biztosító JavaScript, ha AJAX-ról (https://hu.wikipedia.org/wiki/Ajax_(programoz%C3%A1s)) beszélünk, akkor lehet “okos” Controller – vezérló működésű is, sőt bizonyos szempontból még Model – adatszerkezet érintettségről is beszélhetünk, amennyiben XML-formátumban történik az adatátvitel pl. egy kliens oldali űrlap (form) és a szerver oldali Controller között.

A szerveroldali részek azonban a Model és a Controller rétegbe tartoznak. Technikailag ugyan a View is a szerver oldalon van, ámde csupán a böngészőben válik látvánnyá. Ha jól implementáltuk (programoztuk) az alkalmazást, az architektúrális elveknek megfelelően, akkor elválnak egymástól a rétegek. Ettől áttekinthető és karbantartható marad a kódunk. Sokkal kisebb a hibalehetőség, illetve egyszerűbb továbbfejleszteni, módosítani és dokumentálni. Hogy ezt az architektúrális szétválasztást tényleg meg is tehessük, segítségül hívtuk a CodeIgniter (https://codeigniter.com/) keretrendszert (framework-öt).

A CodeIgniter-t (3-as verzió) egész egyszerűen letöltjük (https://codeigniter.com/download), és kicsomagoljuk a webszerverünk gyökér könyvtára alatt létrehozott “apartman” könyvtárba.

gvamosi@gergo1:/var/www/html$ sudo mkdir apartman
[sudo] password for gvamosi:
gvamosi@gergo1:/var/www/html$ sudo chown gvamosi:gvamosi apartman/
gvamosi@gergo1:/var/www/html$ cd apartman/
gvamosi@gergo1:/var/www/html/apartman$ cp ~/Downloads/bcit-ci-CodeIgniter-3.1.11-0-gb73eb19.zip .
gvamosi@gergo1:/var/www/html/apartman$ unzip bcit-ci-CodeIgniter-3.1.11-0-gb73eb19.zip
gvamosi@gergo1:/var/www/html/apartman$ mv bcit-ci-CodeIgniter-b73eb19/* .
gvamosi@gergo1:/var/www/html/apartman$ l
total 3836
drwxr-xr-x 14 gvamosi gvamosi 4096 Sep 19 2019 application
-rw-r--r-- 1 gvamosi gvamosi 2758337 Apr 6 11:30 bcit-ci-CodeIgniter-3.1.11-0-gb73eb19.zip
drwxr-xr-x 2 gvamosi gvamosi 4096 Apr 6 11:32 bcit-ci-CodeIgniter-b73eb19
-rw-r--r-- 1 gvamosi gvamosi 594 Sep 19 2019 composer.json
-rw-r--r-- 1 gvamosi gvamosi 6841 Sep 19 2019 contributing.md
-rw-r--r-- 1 gvamosi gvamosi 1117463 Apr 6 11:23 framework-4.0.2.zip
-rwxr-xr-x 1 gvamosi gvamosi 10255 Sep 19 2019 index.php
-rw-r--r-- 1 gvamosi gvamosi 1114 Sep 19 2019 license.txt
-rw-r--r-- 1 gvamosi gvamosi 2343 Sep 19 2019 readme.rst
drwxr-xr-x 8 gvamosi gvamosi 4096 Sep 19 2019 system
drwxr-xr-x 14 gvamosi gvamosi 4096 Sep 19 2019 user_guide

Ezek után megnézhetjük a “helyi” webszerverünket, hogy sikerült-e a telepítés. Írjuk be a kedvenc böngészőnkbe (én a Google Chrome-ot használom) a következő címet: http://localhost/apartman/. 🙂

Siker! 🙂 Jól látható, hogy vagy 5 nyelven kell tudnunk kódolni egy átlagos webalkalmazáshoz. 😀 Megjegyzem, hogy ez az esettanulmány ugyan konkrét példát mutat be, azonban általános érvényű az architektúrában és főbb irányelveiben.