Init commit
This commit is contained in:
commit
117b6a9217
24 changed files with 508 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
.idea/
|
5
.htaccess
Normal file
5
.htaccess
Normal file
|
@ -0,0 +1,5 @@
|
|||
RewriteEngine on
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_URI} !^(/AccomodationCPOA/assets)
|
||||
RewriteRule ^.*$ /AccomodationCPOA/index.php [L,QSA]
|
58
assets/css/main.css
Normal file
58
assets/css/main.css
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
Layout
|
||||
*/
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.section {
|
||||
padding-top: 80px;
|
||||
}
|
||||
|
||||
/*
|
||||
Login
|
||||
*/
|
||||
.login {
|
||||
display: -ms-flexbox;
|
||||
display: -webkit-box;
|
||||
display: flex;
|
||||
-ms-flex-align: center;
|
||||
-ms-flex-pack: center;
|
||||
-webkit-box-align: center;
|
||||
align-items: center;
|
||||
-webkit-box-pack: center;
|
||||
justify-content: center;
|
||||
padding-top: 40px;
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
|
||||
.login .form-signin {
|
||||
width: 100%;
|
||||
max-width: 330px;
|
||||
padding: 15px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.login .form-signin .checkbox {
|
||||
font-weight: 400;
|
||||
}
|
||||
.login .form-signin .form-control {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
height: auto;
|
||||
padding: 10px;
|
||||
font-size: 16px;
|
||||
}
|
||||
.login .form-signin .form-control:focus {
|
||||
z-index: 2;
|
||||
}
|
||||
.login .form-signin input[type="email"] {
|
||||
margin-bottom: -1px;
|
||||
border-bottom-right-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
.login .form-signin input[type="password"] {
|
||||
margin-bottom: 10px;
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
28
config/config.php
Normal file
28
config/config.php
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
/*
|
||||
* General Configuration
|
||||
*/
|
||||
define('WEBSITE_NAME', 'AccomodationManager'); // Website name
|
||||
/*
|
||||
* Lang
|
||||
*/
|
||||
define('LANG_DEFAULT', 'fr'); // Default lang
|
||||
define('LANG_PATH', 'src/lang/');
|
||||
/*
|
||||
* Routing Configuration
|
||||
*/
|
||||
define('WEBSITE_DEFAULT_PATH', 'index');
|
||||
define('WEBSITE_PATH', '/AccomodationCPOA/'); // "/" for "https://website/" or "/sourcepath/" for "https://website/sourcepath/"
|
||||
/*
|
||||
* Database Configuration
|
||||
*/
|
||||
define('DB_HOST', "localhost");
|
||||
define('DB_USER', "root");
|
||||
define('DB_PASSWORD', "");
|
||||
define('DB_NAME', "cannes");
|
||||
/*
|
||||
* Engine Path
|
||||
*/
|
||||
define('CONTROLLER_PATH','controller/');
|
||||
define('MODELS_PATH','models/');
|
||||
define('VIEW_PATH','view/');
|
2
controller/404.php
Normal file
2
controller/404.php
Normal file
|
@ -0,0 +1,2 @@
|
|||
<?php
|
||||
echo '404';
|
20
controller/accomodation.php
Normal file
20
controller/accomodation.php
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
if($_SESSION['user']->isLoggedIn()) {
|
||||
if(isset($path[1])) {
|
||||
switch ($path[1]) {
|
||||
case 'add':
|
||||
$services = (new AccomodationServices())->getAll();
|
||||
require_once(VIEW_PATH.$path[1] . '_' . $path[0].'.php');
|
||||
break;
|
||||
case 'edit':
|
||||
require_once(VIEW_PATH.$path[1] . '_' . $path[0].'.php');
|
||||
break;
|
||||
default:
|
||||
redirect();
|
||||
}
|
||||
}else{
|
||||
redirect();
|
||||
}
|
||||
}else{
|
||||
redirect('login');
|
||||
}
|
8
controller/index.php
Normal file
8
controller/index.php
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
if($_SESSION['user']->isLoggedIn()) {
|
||||
if (!isset($path[1])) {
|
||||
require_once(VIEW_PATH . $path[0] . '.php');
|
||||
}
|
||||
}else{
|
||||
redirect('login');
|
||||
}
|
27
controller/login.php
Normal file
27
controller/login.php
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
if(!$_SESSION['user']->isLoggedIn() && !isset($path[1])) {
|
||||
if(isset($_POST['email'],$_POST['password'])){
|
||||
$user = new User;
|
||||
$userArray = $user->fetch(
|
||||
array(
|
||||
['email','=',$_POST['email']],
|
||||
['passwordHash', '=', hash('sha256',$_POST['password'])]
|
||||
)
|
||||
);
|
||||
if(count($userArray) === 1){
|
||||
/*
|
||||
* Successful login
|
||||
*/
|
||||
$_SESSION['user'] = $userArray[0]; // Pass the returned User type data into Session
|
||||
redirect();
|
||||
}else{
|
||||
/*
|
||||
* Error message
|
||||
*/
|
||||
}
|
||||
}
|
||||
require_once(VIEW_PATH . $path[0] . '.php');
|
||||
}else{
|
||||
redirect();
|
||||
}
|
4
controller/logout.php
Normal file
4
controller/logout.php
Normal file
|
@ -0,0 +1,4 @@
|
|||
<?php
|
||||
$_SESSION = array();
|
||||
session_destroy();
|
||||
redirect();
|
40
index.php
Normal file
40
index.php
Normal file
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
require_once('config/config.php');
|
||||
require_once('src/func.php');
|
||||
require_once('src/model.php');
|
||||
session_start();
|
||||
/*
|
||||
* Env path
|
||||
*/
|
||||
define('__PATH', str_replace(WEBSITE_PATH, '', $_SERVER['REQUEST_URI']));
|
||||
/*
|
||||
* User session
|
||||
*/
|
||||
|
||||
if(!isset($_SESSION['user'])){
|
||||
$_SESSION['user'] = new User();
|
||||
}
|
||||
/*
|
||||
* Lang
|
||||
*/
|
||||
$lang = LANG_DEFAULT;
|
||||
$langs = glob(LANG_PATH. '*.{json}', GLOB_BRACE);
|
||||
if(isset($_SESSION['lang']) && in_array(LANG_PATH.$_SESSION['lang'].'.json', $langs)) $lang = $_SESSION['lang'];
|
||||
if(isset($_GET['lang']) && in_array(LANG_PATH.$_GET['lang'].'.json', $langs)){ $lang = $_GET['lang']; $_SESSION['lang'] = $lang; }
|
||||
|
||||
/*
|
||||
* Routing
|
||||
*/
|
||||
$path = explode('/',explode('?',__PATH)[0]);
|
||||
$assetsLevel = count($path)-1;
|
||||
switch($path[0]){
|
||||
case '':
|
||||
$path[0] = WEBSITE_DEFAULT_PATH;
|
||||
require_once(CONTROLLER_PATH.WEBSITE_DEFAULT_PATH.'.php');
|
||||
break;
|
||||
case (is_file(CONTROLLER_PATH. $path[0] .'.php')):
|
||||
require_once(CONTROLLER_PATH.$path[0].'.php');
|
||||
break;
|
||||
default:
|
||||
require_once(CONTROLLER_PATH.'404.php');
|
||||
}
|
11
models/Accomodation.php
Normal file
11
models/Accomodation.php
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
|
||||
|
||||
class Accomodation extends Model
|
||||
{
|
||||
public function getByEmail($email){
|
||||
$q = Accomodation::$db->prepare('SELECT * FROM Accomodation WHERE UserEmail = ?');
|
||||
$q->execute(array($email));
|
||||
return $q->fetch(PDO::FETCH_ASSOC);
|
||||
}
|
||||
}
|
11
models/AccomodationServices.php
Normal file
11
models/AccomodationServices.php
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
|
||||
|
||||
class AccomodationServices extends Model
|
||||
{
|
||||
public static function getAll(){
|
||||
$q = AccomodationServices::$db->prepare('SELECT * FROM AccomodationServices');
|
||||
$q->execute();
|
||||
return $q->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
}
|
52
models/User.php
Normal file
52
models/User.php
Normal file
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
|
||||
class User extends Model
|
||||
{
|
||||
private $data;
|
||||
|
||||
public function __construct($data = null)
|
||||
{
|
||||
parent::__construct();
|
||||
$_col = get_class()::getColumns();
|
||||
if($data !== null){
|
||||
forEach($data as $key=>$value){
|
||||
if(!key_exists($key, $_col)){
|
||||
throw new Exception('Invalid data entry');
|
||||
}else{
|
||||
$this->data[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
public function getEmail(){
|
||||
if(isset($this->data['email']))
|
||||
return $this->data['email'];
|
||||
return false;
|
||||
}
|
||||
public function getFirstName(){
|
||||
if(isset($this->data['firstName']))
|
||||
return $this->data['firstName'];
|
||||
return false;
|
||||
}
|
||||
public function getLastName(){
|
||||
if(isset($this->data['lastName']))
|
||||
return $this->data['lastName'];
|
||||
return false;
|
||||
}
|
||||
public function getPhoneNumber(){
|
||||
if(isset($this->data['phoneNumber']))
|
||||
return $this->data['phoneNumber'];
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isLoggedIn(){
|
||||
return (isset($this->data['email']));
|
||||
}
|
||||
|
||||
|
||||
}
|
25
src/func.php
Normal file
25
src/func.php
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
/*
|
||||
* URL & Redirection
|
||||
*/
|
||||
function genURL($route = WEBSITE_DEFAULT_PATH){
|
||||
return $_SERVER["REQUEST_SCHEME"] . '://' . $_SERVER["SERVER_NAME"] . WEBSITE_PATH . $route;
|
||||
}
|
||||
function redirect($route = WEBSITE_DEFAULT_PATH){
|
||||
header('Location: ' . genURL($route));
|
||||
}
|
||||
/*
|
||||
* Front-end render
|
||||
*/
|
||||
# Assets path generator
|
||||
function assetsPath($path, $level = 0){
|
||||
return str_repeat('../', $level) . $path;
|
||||
}
|
||||
# Navbar button render
|
||||
function navItem($name, $path){
|
||||
$acc = '';
|
||||
if(($_SERVER['REDIRECT_URL'] === WEBSITE_PATH . $path) || ($path === ($_SERVER["REQUEST_SCHEME"] . '://' . $_SERVER["SERVER_NAME"] . $_SERVER["REDIRECT_URL"]))){
|
||||
$acc = 'active';
|
||||
}
|
||||
return '<li class="nav-item"><a class="nav-link ' .$acc. '" aria-current="page" href="' .htmlspecialchars($path). '">' .htmlspecialchars($name). '</a></li>';
|
||||
}
|
1
src/lang/en.json
Normal file
1
src/lang/en.json
Normal file
|
@ -0,0 +1 @@
|
|||
{}
|
5
src/lang/fr.json
Normal file
5
src/lang/fr.json
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"layout": {
|
||||
|
||||
}
|
||||
}
|
65
src/model.php
Normal file
65
src/model.php
Normal file
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
class Model {
|
||||
protected static $db = null;
|
||||
public function __construct(){
|
||||
try {
|
||||
/*
|
||||
* Init connection to the DB
|
||||
*/
|
||||
$this::$db = new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_NAME, DB_USER, DB_PASSWORD);
|
||||
$this::$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
} catch(Exception $e){
|
||||
var_dump($e);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* GET/SELECT Query
|
||||
*/
|
||||
public static function fetch($filters = []){
|
||||
$query = 'SELECT * FROM ' . get_called_class();
|
||||
$args = [];
|
||||
$c = 0;
|
||||
$output = [];
|
||||
$_col = get_called_class()::getColumns();
|
||||
forEach($filters as $filter){
|
||||
if (count($filter) === 3 && array_key_exists($filter[0], $_col) && in_array($filter[1], ['=','<','>','<>','LIKE'])){
|
||||
if($c === 0){
|
||||
$query .= ' WHERE';
|
||||
}else{
|
||||
$query .= ' AND';
|
||||
}
|
||||
$query .= ' ' . $filter[0] . ' ' . $filter[1] . ' ?';
|
||||
$args[] = $filter[2];
|
||||
}else{
|
||||
throw new Exception('Invalid SQL filters');
|
||||
}
|
||||
$c++;
|
||||
}
|
||||
$q = Model::$db->prepare($query);
|
||||
$q->execute($args);
|
||||
$d = $q->fetchAll(PDO::FETCH_ASSOC);
|
||||
forEach($d as $row){
|
||||
$class=get_called_class();
|
||||
$output[] = new $class($row);
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
protected function getColumns(){
|
||||
$q = Model::$db->prepare('SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ?');
|
||||
$q->execute(array(get_called_class()));
|
||||
$d = $q->fetchAll(PDO::FETCH_ASSOC);
|
||||
$out = [];
|
||||
forEach($d as $col){
|
||||
$out[$col['COLUMN_NAME']] = $col;
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Load our models
|
||||
*/
|
||||
foreach (glob(MODELS_PATH . '/*.php') as $filename)
|
||||
{
|
||||
require_once $filename;
|
||||
}
|
60
view/add_accomodation.php
Normal file
60
view/add_accomodation.php
Normal file
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
require_once('template/head.php');
|
||||
?>
|
||||
<div class="container-fluid section">
|
||||
<h1>Bienvenue M. <?=htmlspecialchars(strtoupper($_SESSION['user']->getLastName()))?>,</h1>
|
||||
<h2>Il semblerait que vous n'ayez pas encore ajouté d'hebergement...</h2>
|
||||
</div>
|
||||
<div class="container-fluid section">
|
||||
<form action="" method="POST">
|
||||
<div class="row justify-content-md-center">
|
||||
<div class="col col-lg-3">
|
||||
<div class="form-group">
|
||||
<label for="exampleInputEmail1">Donnez un nom à votre hebergement</label>
|
||||
<input type="text" class="form-control" name="accomodationName" id="accomodationName" aria-describedby="accomodationName" placeholder="Enter a name">
|
||||
<small id="accomodationName" class="form-text text-muted">We'll never share your email with anyone else.</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="exampleInputPassword1">Password</label>
|
||||
<input type="password" class="form-control" id="exampleInputPassword1" placeholder="Password">
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" id="exampleCheck1">
|
||||
<label class="form-check-label" for="exampleCheck1">Check me out</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-auto"></div>
|
||||
<div class="col col-lg-3">
|
||||
<div class="form-group">
|
||||
<label for="typeSelect">Sélectionnez un type d'hébergement</label>
|
||||
<select class="form-control" id="typeSelect">
|
||||
<option>Hôtel</option>
|
||||
<option>2</option>
|
||||
<option>3</option>
|
||||
<option>4</option>
|
||||
<option>5</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="typeSelect">Quels services proposez-vous ?</label><br>
|
||||
<?php
|
||||
$c = 0;
|
||||
foreach ($services as $service){
|
||||
$c++;
|
||||
?>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="checkbox" id="inlineCheckbox<?=$c?>" value="<?=htmlspecialchars($service['name'])?>">
|
||||
<label class="form-check-label" for="inlineCheckbox<?=$c?>"><?=htmlspecialchars($service['name'])?></label>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Ajouter</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<?php
|
||||
require_once('template/footer.php');
|
||||
?>
|
7
view/edit_accomodation.php
Normal file
7
view/edit_accomodation.php
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
require_once('template/head.php');
|
||||
?>
|
||||
|
||||
<?php
|
||||
require_once('template/footer.php');
|
||||
?>
|
8
view/index.php
Normal file
8
view/index.php
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
require_once('template/head.php');
|
||||
?>
|
||||
|
||||
|
||||
<?php
|
||||
require_once('template/footer.php');
|
||||
?>
|
17
view/login.php
Normal file
17
view/login.php
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
require_once('template/head.php');
|
||||
?>
|
||||
<div class="login">
|
||||
<form class="form-signin" method="POST">
|
||||
<h1><?=WEBSITE_NAME?></h1>
|
||||
<h1 class="h3 mb-3 font-weight-normal">Please sign in</h1>
|
||||
<label for="inputEmail" class="sr-only">Email address</label>
|
||||
<input type="email" name="email" id="inputEmail" class="form-control" placeholder="Email address" required autofocus>
|
||||
<label for="inputPassword" class="sr-only">Password</label>
|
||||
<input type="password" name="password" id="inputPassword" class="form-control" placeholder="Password" required>
|
||||
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
|
||||
</form>
|
||||
</div>
|
||||
<?php
|
||||
require_once('template/footer.php');
|
||||
?>
|
5
view/template/footer.php
Normal file
5
view/template/footer.php
Normal file
|
@ -0,0 +1,5 @@
|
|||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js"
|
||||
integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW"
|
||||
crossorigin="anonymous"></script>
|
||||
</body>
|
||||
</html>
|
16
view/template/head.php
Normal file
16
view/template/head.php
Normal file
|
@ -0,0 +1,16 @@
|
|||
<!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">
|
||||
<link rel="stylesheet" href="<?=assetsPath("assets/css/main.css", $assetsLevel);?>">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet"
|
||||
integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
|
||||
<title> - <?= WEBSITE_NAME ?></title>
|
||||
</head>
|
||||
<body>
|
||||
<?php
|
||||
require_once('navbar.php');
|
||||
?>
|
32
view/template/navbar.php
Normal file
32
view/template/navbar.php
Normal file
|
@ -0,0 +1,32 @@
|
|||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="#"><?= WEBSITE_NAME; ?></a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarText"
|
||||
aria-controls="navbarText" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarText">
|
||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||
<?php
|
||||
if($_SESSION['user']->isLoggedIn()){
|
||||
echo navItem('Ajout Hebergement',genURL('accomodation/add'));
|
||||
echo navItem('Edition de l\'hebergement',genURL('accomodation/edit'));
|
||||
echo navItem('Gestion des disponibilités',genURL('accomodation/manager'));
|
||||
}else{
|
||||
echo navItem('Login',genURL('login'));
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
<span class="navbar-text">
|
||||
<?php
|
||||
if($_SESSION['user']->isLoggedIn()){
|
||||
?>
|
||||
M. <?=htmlspecialchars(strtoupper($_SESSION['user']->getLastName()))?> <?=htmlspecialchars($_SESSION['user']->getFirstName())?>
|
||||
<a href="<?=genURL('logout')?>">Déconnexion</a>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
Reference in a new issue