Sähköisten asiointipalveluiden toteuttaminen

Sorakuilu

Demo 13 (1908Tivib02), MVC-malli

Tehtävä: Muunna aikaisemmin tehtyä demoa 12 MVC-mallin mukaiseksi.

Alla oleva kuva esittää lopputulokseksi tulevaa pikkuriikistä järjestelmää, jolla voidaan ylläpitää pelaajien tietoja.

käsitteellinen sivukartta

Kansiot

Tiedostot organisoidaan uudestaan, ne sijoitetaan seuraavaan kansiorakennelmaan:

kansiot

Kohta A - index.php - reititys

Tehdään reititys edelleen aikaisempaan tapaan eli $_GET kertoo, mikä sivu sisällytetään - tämä tapahtuu index-sivussa. Index-sivu ei kuitenkaan tulosta mitään, vain require (kontrolleri tai view)on sallittu.

Muu koodi jaetaan kolmeen erilaiseen kategoriaan: mallit (models), kontrollerit ja näkymät (views). Tässä kohdassa laadimme vain yhden mallin jokaista tietokannan taulua varten, samaten yhden kontrollerin taulua kohti.

Yhteysfunktiota voit käyttää sellaisenaan.

./index.php

index-sivu ohjaa kaikki pyynnöt eteenpäin.

Lähdekoodi:

<?php
session_start
();
// pyynnöt muodossa index.php?action=edit&id=5

if(isset($_GET["action"])) $action $_GET["action"];
else 
$action ="index";

$method strtolower($_SERVER["REQUEST_METHOD"]);

require 
"./controllers/playercontroller.php";
require 
"./helpers/auth.php";

switch(
$action) {
    case 
"index":
    
indexcontroller();
    break;

    case 
"register":
    if(
$method=="get") require "./views/registerform.view.php";
    else 
postregister();
    break;

    case 
"login":
    if(
$method=="get") require "./views/loginform.view.php";
    else 
postlogin();
    break;

    case 
"logout":
    if(
islogged()) logout();
    else 
indexcontroller();
    break;

    case 
"admin":
    if(
islogged()) 
    
admincontroller();
    else require 
"./views/loginform.view.php";
    break;

    case 
"delete":
    
//echo $_SESSION["id"];
    //echo $_SESSION["ip"];
    
if(islogged()) deletecontroller();
    else require 
"./views/loginform.view.php";
    break;

    case 
"edit":
    if(
islogged()) {
        if(
$method=="get")
        
geteditcontroller();
        else 
posteditcontroller();
    }
    else require 
"./views/loginform.view.php";
    break;


    default:
    echo 
"404";
}

./database/connection.php

Lähdekoodi:

<?php
$dsn 
"mysql:host=magnesium;dbname=db13aleena";
$user "leena";
$passwd "lmjn";

$pdo = new PDO($dsn$user$passwd);
?>

Kohta B etusivu

Laadi etusivu pelaajille (listaa näkyville kaikki pelaajat).

Käytä ratkaisussa MVC-mallia. Siis: index-sivu ohjaa pyynnön oikealle näkymälle tai kontrollerille (controllers), joka keskustelee tietokantafunktioiden kanssa (models).

Tässä

./controllers/playercontroller.php

<?php
require "./database/models/Player.php";
require 
"./helpers/helper.php";

function 
indexcontroller()
{
    
$players getAllPlayers();
    require 
"./views/index.view.php";
}

function 
admincontroller()
{
    
$players getAllPlayers();
    require 
"./views/admin.view.php";
}

function 
postregister()
{
    if(isset(
$_POST["account_name"],$_POST["password"],$_POST["password2"],$_POST["email"],$_POST["current_character"]) && $_POST["password"]==$_POST["password2"])
    {
        
$account_name sanit($_POST["account_name"]);
        
$password password_sanit($_POST["password"]);
        
$email sanit($_POST["email"]);
        
$current_character sanit($_POST["current_character"]);
        
$last_login date('Y-m-d');

        
$data = array($account_name,$password,$email,$last_login,$current_character);
        
//var_dump($data);

        
if(addplayer($data)) {
            
indexcontroller();
        }
        else {
            
$message ="Pelaajan lisääminen kantaan ei onnistu";
            require 
"./views/registerform.view.php";
        }


    } else {
        
$message "Lomakkeen tiedot eivät ole kunnossa";
        require 
"./views/registerform.view.php";
    }
}

function 
postlogin()
{
    if(isset(
$_POST["account_name"],$_POST["password"])) {
        
$account_name sanit($_POST["account_name"]);
        
$password trim($_POST["password"]);

        
//haetaan kannasta tietue, jossa ovat samat
        
$ok loginplayer($account_name,$password);
        if(
$ok) {
            
$player getPlayerByName($account_name);
            
$id $player[0]["id"];
            
$ip $_SERVER["REMOTE_ADDR"];

            
$_SESSION["id"] = $id;
            
$_SESSION["ip"] = $ip;

            
$players getAllPlayers();
            require 
"./views/admin.view.php";
        } else {
            
$message ="Käyttäjää ei löydy";
            require 
"./views/loginform.view.php";
        }


    } else {
        
$message ="Käyttäjätunnus tai salasana puuttuu!";
        require 
"./views/loginform.view.php";
    }
}

function 
logout()
{
    if(isset(
$_SESSION["ip"],$_SESSION["id"]))
    {
        
session_unset(); //poistaa kaikki istuntomuuttujat
        
session_destroy(); //poistaa koko istunnon
        
header("Location:./index.php");
    }
}

function 
deletecontroller()
{
    if(isset(
$_GET["id"])) {
        
$id $_GET["id"];
        
$ok =deletePlayer($id);
        if(
$ok) {
            
$message "Pelaaja poistettu";
        } else 
$message ="Pelaaja ei poistu kannasta";
    } else 
$message ="Pelaajaa ei ole annettu";
    
$players getAllPlayers();
    require 
"./views/admin.view.php";
}

function 
geteditcontroller()
{
    if(isset(
$_GET["id"])) {
        
$id=$_GET["id"];
        
$player getPlayerById($id);
        require 
"./views/editplayerform.view.php";
    }
    else {
        
$message ="Ei pelaajan tietoja";
        require 
"./views/admin.view.php";
    }

}

function 
posteditcontroller()
{
    if(isset(
$_POST["id"],$_POST["aname"],$_POST["email"],$_POST["character"],$_POST["money"],$_POST["banned"])) {
        
$id $_POST["id"];
        
$account_name sanit($_POST["aname"]);
        
$email sanit($_POST["email"]);
        
$current_character sanit($_POST["character"]);
        
$money $_POST["money"];
        
$banned $_POST["banned"]; 

        
$data = array($account_name,$email,$money,$current_character,$banned,$id);

        if(
editPlayer($data)) {
            
$message "Muokkaus on tehty";
            
$players getAllPlayers();
            require 
"./views/admin.view.php";
        } else {
            
$message "Muokkaus ei onnistunut";
            
$players getAllPlayers();
            require 
"./views/admin.view.php";        
        }
    } else { 
        
$message "Lomakkeelta puuttuu tietoja";
        require 
"./views/admin.view.php";          
    }
}

./database/models/Player.php

<?php

require "./database/connection.php";

function 
getAllPlayers()
{
    global 
$pdo;
    
$sql "SELECT * FROM players";
    
$stm $pdo->query($sql);

    
$players $stm->fetchAll(PDO::FETCH_ASSOC);
    return 
$players;

    
// return  $stm->fetchAll(PDO::ASSOC);
}

function 
addplayer($data)
{
    global 
$pdo;
    
$sql "INSERT INTO players (account_name,password,email,last_login,current_character) VALUES(?,?,?,?,?)";

    
$stm=$pdo->prepare($sql);
    if(
$stm->execute($data)) return TRUE;
    else return 
FALSE;    
}

function 
deletePlayer($id)
{
    global 
$pdo;
    
$sql "DELETE FROM players WHERE id=?";
    
$stm=$pdo->prepare($sql);
    
$stm->bindValue(1,$id);
    if(
$stm->execute()) return TRUE;
    else return 
FALSE;    
}


function 
loginplayer($account_name,$password)
{
    global 
$pdo;

    
$sql "SELECT id,account_name,password FROM players WHERE account_name=?";

    
$stm$pdo->prepare($sql);
    
$stm->bindValue(1,$account_name);
    
$stm->execute();

    
$player $stm->fetchAll(PDO::FETCH_ASSOC);
    if(
$player) {
        if(
password_verify($password,$player[0]["password"])) {
            return 
TRUE;
        } else return 
FALSE;
    } else return 
FALSE;
}

function 
getPlayerByName($account_name)
{
    global 
$pdo;

    
$sql "SELECT * FROM players WHERE account_name=?";

    
$stm$pdo->prepare($sql);
    
$stm->bindValue(1,$account_name);
    
$stm->execute();

    
$player $stm->fetchAll(PDO::FETCH_ASSOC);
    return 
$player;
}

function 
getPlayerById($id)
{
    global 
$pdo;

    
$sql "SELECT * FROM players WHERE id=?";

    
$stm$pdo->prepare($sql);
    
$stm->bindValue(1,$id);
    
$stm->execute();

    
$player $stm->fetchAll(PDO::FETCH_ASSOC);
    return 
$player;
}

function 
editPlayer($data)
{
    global 
$pdo;
    
$sql "UPDATE players SET account_name = ?,email = ?, money = ?, current_character = ?, banned = ? WHERE id = ?";

    
$stm $pdo->prepare($sql);
    return 
$stm->execute($data);
}

./views/index.view.php

<?php
include "./views/partials/head.php";
if(isset(
$message)) echo $message;
?>


<h1>Kaikki pelaajat</h1>
<?php
foreach($players as $player) {?>

<h3><?= $player["account_name"];?></h3>

<?php
}
include 
"./views/partials/end.php";
?>

./views/partials/head.php, adminhead.php ja end.php

./views/partials/head.php

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Pelaajahallinta</title>
</head>
<body>
    
<a href="./index.php?action=register">Lisää pelaaja</a><br>
<a href="./index.php?action=login">Kirjaudu</a>
<hr>

./views/partials/adminhead.php

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Pelaajahallinta</title>
</head>
<body>
    
<a href="./index.php?action=logout">Kirjaudu ulos</a>
<hr>

./views/partials/end.php

</body>
</html>

Kohta C pelaajan lisääminen

Toteuta pelaajan lisääminen MVC-mallilla

Tässä

./views/registerform.view.php

<?php
include "./views/partials/head.php";
?>
<form method="post">

<label for="account_name">Käyttäjätunnus</label><br>
<input type="text" name ="account_name" required><br>

<label for="password">Salasana</label><br>
<input type="password" name="password" required><br>

<label for="password2">Salasana uudelleen</label><br>
<input type="password" name="password2" required><br>

<label for="email">Sähköposti</label><br>
<input type="email" name="email" required><br>

<label for="current_character">Hahmo</label><br>
<select name="current_character">
    <option value="hirviö">hirviö</option>
    <option value="keiju">keiju</option>
    <option value="olio">olio</option>
</select><br><br>

<input type="submit" value="Rekisteröi pelaaja"><br>
</form>


<?php
include "./views/partials/end.php";
?>

./helpers/helper.php

Tiedosto tarjoaa käyttöön sanitointifunktiot.

<?php

function sanit($word)
{
    
$word trim($word); //poistaa tyhjät välilyönnit
    
$word filter_var($word,FILTER_SANITIZE_STRING);
    return 
$word;
}

function 
password_sanit($password
{
    
$password trim($password);
    
$password password_hash($password,PASSWORD_DEFAULT);
    return 
$password;
}

Kohta D Kirjautuminen

Kirjautumisessa käytetään hyväksi istuntoa: kun käyttäjä on kirjoittanut käyttäjätunnuksen ja salasanan lomakkeelle, niiden olemassaolo tarkistetaan tietokannasta. Jos tiedot löytyvät, asetetaan istuntomuuttujaan id ja käyttäjän ip.

Periaate tiedostotasolla näkyy seuraavassa sekvenssikaaviossa:

sekvenssi login -toimintoon

Tässä