Compare commits
88 Commits
feature/Pa
...
master
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="SqlDialectMappings">
|
||||||
|
<file url="file://$PROJECT_DIR$/fluxRSS/DAL/ArticleGateway.php" dialect="PostgreSQL" />
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -0,0 +1,3 @@
|
|||||||
|
RewriteEngine on
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-f
|
||||||
|
RewriteRule . index.php [L]
|
@ -0,0 +1,304 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2012 Danny van Kooten <hi@dannyvankooten.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace vendor;
|
||||||
|
|
||||||
|
class AltoRouter
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array Array of all routes (incl. named routes).
|
||||||
|
*/
|
||||||
|
protected $routes = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array Array of all named routes.
|
||||||
|
*/
|
||||||
|
protected $namedRoutes = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string Can be used to ignore leading part of the Request URL (if main file lives in subdirectory of host)
|
||||||
|
*/
|
||||||
|
protected $basePath = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array Array of default match types (regex helpers)
|
||||||
|
*/
|
||||||
|
protected $matchTypes = [
|
||||||
|
'i' => '[0-9]++',
|
||||||
|
'a' => '[0-9A-Za-z]++',
|
||||||
|
'h' => '[0-9A-Fa-f]++',
|
||||||
|
'*' => '.+?',
|
||||||
|
'**' => '.++',
|
||||||
|
'' => '[^/\.]++'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create router in one call from config.
|
||||||
|
*
|
||||||
|
* @param array $routes
|
||||||
|
* @param string $basePath
|
||||||
|
* @param array $matchTypes
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function __construct(array $routes = [], $basePath = '', array $matchTypes = [])
|
||||||
|
{
|
||||||
|
$this->addRoutes($routes);
|
||||||
|
$this->setBasePath($basePath);
|
||||||
|
$this->addMatchTypes($matchTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves all routes.
|
||||||
|
* Useful if you want to process or display routes.
|
||||||
|
* @return array All routes.
|
||||||
|
*/
|
||||||
|
public function getRoutes()
|
||||||
|
{
|
||||||
|
return $this->routes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add multiple routes at once from array in the following format:
|
||||||
|
*
|
||||||
|
* $routes = [
|
||||||
|
* [$method, $route, $target, $name]
|
||||||
|
* ];
|
||||||
|
*
|
||||||
|
* @param array $routes
|
||||||
|
* @return void
|
||||||
|
* @author Koen Punt
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function addRoutes($routes)
|
||||||
|
{
|
||||||
|
if (!is_array($routes) && !$routes instanceof Traversable) {
|
||||||
|
throw new RuntimeException('Routes should be an array or an instance of Traversable');
|
||||||
|
}
|
||||||
|
foreach ($routes as $route) {
|
||||||
|
call_user_func_array([$this, 'map'], $route);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the base path.
|
||||||
|
* Useful if you are running your application from a subdirectory.
|
||||||
|
* @param string $basePath
|
||||||
|
*/
|
||||||
|
public function setBasePath($basePath)
|
||||||
|
{
|
||||||
|
$this->basePath = $basePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add named match types. It uses array_merge so keys can be overwritten.
|
||||||
|
*
|
||||||
|
* @param array $matchTypes The key is the name and the value is the regex.
|
||||||
|
*/
|
||||||
|
public function addMatchTypes(array $matchTypes)
|
||||||
|
{
|
||||||
|
$this->matchTypes = array_merge($this->matchTypes, $matchTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map a route to a target
|
||||||
|
*
|
||||||
|
* @param string $method One of 5 HTTP Methods, or a pipe-separated list of multiple HTTP Methods (GET|POST|PATCH|PUT|DELETE)
|
||||||
|
* @param string $route The route regex, custom regex must start with an @. You can use multiple pre-set regex filters, like [i:id]
|
||||||
|
* @param mixed $target The target where this route should point to. Can be anything.
|
||||||
|
* @param string $name Optional name of this route. Supply if you want to reverse route this url in your application.
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function map($method, $route, $target, $name = null)
|
||||||
|
{
|
||||||
|
|
||||||
|
$this->routes[] = [$method, $route, $target, $name];
|
||||||
|
|
||||||
|
if ($name) {
|
||||||
|
if (isset($this->namedRoutes[$name])) {
|
||||||
|
throw new RuntimeException("Can not redeclare route '{$name}'");
|
||||||
|
}
|
||||||
|
$this->namedRoutes[$name] = $route;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reversed routing
|
||||||
|
*
|
||||||
|
* Generate the URL for a named route. Replace regexes with supplied parameters
|
||||||
|
*
|
||||||
|
* @param string $routeName The name of the route.
|
||||||
|
* @param array @params Associative array of parameters to replace placeholders with.
|
||||||
|
* @return string The URL of the route with named parameters in place.
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function generate($routeName, array $params = [])
|
||||||
|
{
|
||||||
|
|
||||||
|
// Check if named route exists
|
||||||
|
if (!isset($this->namedRoutes[$routeName])) {
|
||||||
|
throw new RuntimeException("Route '{$routeName}' does not exist.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace named parameters
|
||||||
|
$route = $this->namedRoutes[$routeName];
|
||||||
|
|
||||||
|
// prepend base path to route url again
|
||||||
|
$url = $this->basePath . $route;
|
||||||
|
|
||||||
|
if (preg_match_all('`(/|\.|)\[([^:\]]*+)(?::([^:\]]*+))?\](\?|)`', $route, $matches, PREG_SET_ORDER)) {
|
||||||
|
foreach ($matches as $index => $match) {
|
||||||
|
list($block, $pre, $type, $param, $optional) = $match;
|
||||||
|
|
||||||
|
if ($pre) {
|
||||||
|
$block = substr($block, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($params[$param])) {
|
||||||
|
// Part is found, replace for param value
|
||||||
|
$url = str_replace($block, $params[$param], $url);
|
||||||
|
} elseif ($optional && $index !== 0) {
|
||||||
|
// Only strip preceding slash if it's not at the base
|
||||||
|
$url = str_replace($pre . $block, '', $url);
|
||||||
|
} else {
|
||||||
|
// Strip match block
|
||||||
|
$url = str_replace($block, '', $url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Match a given Request Url against stored routes
|
||||||
|
* @param string $requestUrl
|
||||||
|
* @param string $requestMethod
|
||||||
|
* @return array|boolean Array with route information on success, false on failure (no match).
|
||||||
|
*/
|
||||||
|
public function match($requestUrl = null, $requestMethod = null)
|
||||||
|
{
|
||||||
|
|
||||||
|
$params = [];
|
||||||
|
|
||||||
|
// set Request Url if it isn't passed as parameter
|
||||||
|
if ($requestUrl === null) {
|
||||||
|
$requestUrl = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
// strip base path from request url
|
||||||
|
$requestUrl = substr($requestUrl, strlen($this->basePath));
|
||||||
|
|
||||||
|
// Strip query string (?a=b) from Request Url
|
||||||
|
if (($strpos = strpos($requestUrl, '?')) !== false) {
|
||||||
|
$requestUrl = substr($requestUrl, 0, $strpos);
|
||||||
|
}
|
||||||
|
|
||||||
|
$lastRequestUrlChar = $requestUrl ? $requestUrl[strlen($requestUrl)-1] : '';
|
||||||
|
|
||||||
|
// set Request Method if it isn't passed as a parameter
|
||||||
|
if ($requestMethod === null) {
|
||||||
|
$requestMethod = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'GET';
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->routes as $handler) {
|
||||||
|
list($methods, $route, $target, $name) = $handler;
|
||||||
|
|
||||||
|
$method_match = (stripos($methods, $requestMethod) !== false);
|
||||||
|
|
||||||
|
// Method did not match, continue to next route.
|
||||||
|
if (!$method_match) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($route === '*') {
|
||||||
|
// * wildcard (matches all)
|
||||||
|
$match = true;
|
||||||
|
} elseif (isset($route[0]) && $route[0] === '@') {
|
||||||
|
// @ regex delimiter
|
||||||
|
$pattern = '`' . substr($route, 1) . '`u';
|
||||||
|
$match = preg_match($pattern, $requestUrl, $params) === 1;
|
||||||
|
} elseif (($position = strpos($route, '[')) === false) {
|
||||||
|
// No params in url, do string comparison
|
||||||
|
$match = strcmp($requestUrl, $route) === 0;
|
||||||
|
} else {
|
||||||
|
// Compare longest non-param string with url before moving on to regex
|
||||||
|
// Check if last character before param is a slash, because it could be optional if param is optional too (see https://github.com/dannyvankooten/AltoRouter/issues/241)
|
||||||
|
if (strncmp($requestUrl, $route, $position) !== 0 && ($lastRequestUrlChar === '/' || $route[$position-1] !== '/')) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$regex = $this->compileRoute($route);
|
||||||
|
$match = preg_match($regex, $requestUrl, $params) === 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($match) {
|
||||||
|
if ($params) {
|
||||||
|
foreach ($params as $key => $value) {
|
||||||
|
if (is_numeric($key)) {
|
||||||
|
unset($params[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'target' => $target,
|
||||||
|
'params' => $params,
|
||||||
|
'name' => $name
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compile the regex for a given route (EXPENSIVE)
|
||||||
|
* @param $route
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function compileRoute($route)
|
||||||
|
{
|
||||||
|
if (preg_match_all('`(/|\.|)\[([^:\]]*+)(?::([^:\]]*+))?\](\?|)`', $route, $matches, PREG_SET_ORDER)) {
|
||||||
|
$matchTypes = $this->matchTypes;
|
||||||
|
foreach ($matches as $match) {
|
||||||
|
list($block, $pre, $type, $param, $optional) = $match;
|
||||||
|
|
||||||
|
if (isset($matchTypes[$type])) {
|
||||||
|
$type = $matchTypes[$type];
|
||||||
|
}
|
||||||
|
if ($pre === '.') {
|
||||||
|
$pre = '\.';
|
||||||
|
}
|
||||||
|
|
||||||
|
$optional = $optional !== '' ? '?' : null;
|
||||||
|
|
||||||
|
//Older versions of PCRE require the 'P' in (?P<named>)
|
||||||
|
$pattern = '(?:'
|
||||||
|
. ($pre !== '' ? $pre : null)
|
||||||
|
. '('
|
||||||
|
. ($param !== '' ? "?P<$param>" : null)
|
||||||
|
. $type
|
||||||
|
. ')'
|
||||||
|
. $optional
|
||||||
|
. ')'
|
||||||
|
. $optional;
|
||||||
|
|
||||||
|
$route = str_replace($block, $pattern, $route);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "`^$route$`u";
|
||||||
|
}
|
||||||
|
}
|
@ -1,25 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace DAL;
|
|
||||||
|
|
||||||
use App\modeles\Article;
|
|
||||||
use PDO;
|
|
||||||
class ArticleGateway
|
|
||||||
{
|
|
||||||
private $con;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $con
|
|
||||||
*/
|
|
||||||
public function __construct($con)
|
|
||||||
{
|
|
||||||
$this->con = $con;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAllArticles():array
|
|
||||||
{
|
|
||||||
$query = 'SELECT * FROM Article;';
|
|
||||||
$this->con->executeQuery($query, array());
|
|
||||||
return $this->con->getResults();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace DAL;
|
|
||||||
|
|
||||||
use PDO;
|
|
||||||
|
|
||||||
class Connection extends PDO
|
|
||||||
{
|
|
||||||
private $stmt; // pas typé, car peut être faux ou statement
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $dsn
|
|
||||||
* @param string $username
|
|
||||||
* @param string $password
|
|
||||||
*/
|
|
||||||
public function __construct(string $dsn, string $username, string $password)
|
|
||||||
{
|
|
||||||
parent::__construct($dsn, $username, $password);
|
|
||||||
$this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $query to execute
|
|
||||||
* @param array $parameters to bind
|
|
||||||
* @return bool Returns `true` on success, `false` otherwise
|
|
||||||
*/
|
|
||||||
public function executeQuery(string $query, array $parameters = []): bool
|
|
||||||
{
|
|
||||||
$this->stmt = parent::prepare($query);
|
|
||||||
foreach ($parameters as $name => $value) {
|
|
||||||
$this->stmt->bindValue($name, $value[0], $value[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->stmt->execute();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function getResults(): array
|
|
||||||
{
|
|
||||||
return $this->stmt->fetchall();
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,258 @@
|
|||||||
|
{
|
||||||
|
"_readme": [
|
||||||
|
"This file locks the dependencies of your project to a known state",
|
||||||
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
|
"This file is @generated automatically"
|
||||||
|
],
|
||||||
|
"content-hash": "03e1f7c6d7574f3683225067dbb2becc",
|
||||||
|
"packages": [
|
||||||
|
{
|
||||||
|
"name": "symfony/polyfill-ctype",
|
||||||
|
"version": "v1.28.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/polyfill-ctype.git",
|
||||||
|
"reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb",
|
||||||
|
"reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.1"
|
||||||
|
},
|
||||||
|
"provide": {
|
||||||
|
"ext-ctype": "*"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-ctype": "For best performance"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-main": "1.28-dev"
|
||||||
|
},
|
||||||
|
"thanks": {
|
||||||
|
"name": "symfony/polyfill",
|
||||||
|
"url": "https://github.com/symfony/polyfill"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"files": [
|
||||||
|
"bootstrap.php"
|
||||||
|
],
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Polyfill\\Ctype\\": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Gert de Pagter",
|
||||||
|
"email": "BackEndTea@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Symfony polyfill for ctype functions",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"keywords": [
|
||||||
|
"compatibility",
|
||||||
|
"ctype",
|
||||||
|
"polyfill",
|
||||||
|
"portable"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://symfony.com/sponsor",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/fabpot",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2023-01-26T09:26:14+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/polyfill-mbstring",
|
||||||
|
"version": "v1.28.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||||
|
"reference": "42292d99c55abe617799667f454222c54c60e229"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229",
|
||||||
|
"reference": "42292d99c55abe617799667f454222c54c60e229",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.1"
|
||||||
|
},
|
||||||
|
"provide": {
|
||||||
|
"ext-mbstring": "*"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-mbstring": "For best performance"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-main": "1.28-dev"
|
||||||
|
},
|
||||||
|
"thanks": {
|
||||||
|
"name": "symfony/polyfill",
|
||||||
|
"url": "https://github.com/symfony/polyfill"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"files": [
|
||||||
|
"bootstrap.php"
|
||||||
|
],
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Polyfill\\Mbstring\\": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Nicolas Grekas",
|
||||||
|
"email": "p@tchwork.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Symfony polyfill for the Mbstring extension",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"keywords": [
|
||||||
|
"compatibility",
|
||||||
|
"mbstring",
|
||||||
|
"polyfill",
|
||||||
|
"portable",
|
||||||
|
"shim"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://symfony.com/sponsor",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/fabpot",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2023-07-28T09:04:16+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "twig/twig",
|
||||||
|
"version": "v3.7.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/twigphp/Twig.git",
|
||||||
|
"reference": "a0ce373a0ca3bf6c64b9e3e2124aca502ba39554"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/twigphp/Twig/zipball/a0ce373a0ca3bf6c64b9e3e2124aca502ba39554",
|
||||||
|
"reference": "a0ce373a0ca3bf6c64b9e3e2124aca502ba39554",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.2.5",
|
||||||
|
"symfony/polyfill-ctype": "^1.8",
|
||||||
|
"symfony/polyfill-mbstring": "^1.3"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"psr/container": "^1.0|^2.0",
|
||||||
|
"symfony/phpunit-bridge": "^5.4.9|^6.3"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Twig\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"BSD-3-Clause"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Fabien Potencier",
|
||||||
|
"email": "fabien@symfony.com",
|
||||||
|
"homepage": "http://fabien.potencier.org",
|
||||||
|
"role": "Lead Developer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Twig Team",
|
||||||
|
"role": "Contributors"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Armin Ronacher",
|
||||||
|
"email": "armin.ronacher@active-4.com",
|
||||||
|
"role": "Project Founder"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Twig, the flexible, fast, and secure template language for PHP",
|
||||||
|
"homepage": "https://twig.symfony.com",
|
||||||
|
"keywords": [
|
||||||
|
"templating"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/twigphp/Twig/issues",
|
||||||
|
"source": "https://github.com/twigphp/Twig/tree/v3.7.1"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://github.com/fabpot",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/twig/twig",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2023-08-28T11:09:02+00:00"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"packages-dev": [],
|
||||||
|
"aliases": [],
|
||||||
|
"minimum-stability": "stable",
|
||||||
|
"stability-flags": [],
|
||||||
|
"prefer-stable": false,
|
||||||
|
"prefer-lowest": false,
|
||||||
|
"platform": {
|
||||||
|
"ext-pdo": "*",
|
||||||
|
"ext-dom": "*"
|
||||||
|
},
|
||||||
|
"platform-dev": [],
|
||||||
|
"plugin-api-version": "2.6.0"
|
||||||
|
}
|
@ -1,14 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
//gen
|
|
||||||
$rep = __DIR__ . '/../';
|
|
||||||
|
|
||||||
// liste des modules à inclure
|
|
||||||
|
|
||||||
//$dConfig['includes']= array('controleur/Validation.php');
|
|
||||||
|
|
||||||
//BD
|
|
||||||
|
|
||||||
$base = 'sasa';
|
|
||||||
$login = '';
|
|
||||||
$mdp = '';
|
|
@ -0,0 +1,39 @@
|
|||||||
|
name: PHP
|
||||||
|
|
||||||
|
on: [ push, pull_request ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
php-versions: [ '7.3', '7.4', '8.0', '8.1' ]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- uses: shivammathur/setup-php@v2
|
||||||
|
with:
|
||||||
|
php-version: ${{ matrix.php-versions }}
|
||||||
|
tools: composer
|
||||||
|
|
||||||
|
- name: Validate composer.json and composer.lock
|
||||||
|
run: composer validate
|
||||||
|
|
||||||
|
- name: Get composer cache directory
|
||||||
|
id: composer-cache
|
||||||
|
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||||
|
|
||||||
|
- name: Cache dependencies
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: ${{ steps.composer-cache.outputs.dir }}
|
||||||
|
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||||
|
restore-keys: ${{ runner.os }}-composer-
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
if: steps.composer-cache.outputs.cache-hit != 'true'
|
||||||
|
run: composer install --prefer-dist --no-progress
|
||||||
|
|
||||||
|
- name: Run test suite
|
||||||
|
run: composer run-script test
|
@ -0,0 +1,302 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2012 Danny van Kooten <hi@dannyvankooten.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class AltoRouter
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array Array of all routes (incl. named routes).
|
||||||
|
*/
|
||||||
|
protected $routes = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array Array of all named routes.
|
||||||
|
*/
|
||||||
|
protected $namedRoutes = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string Can be used to ignore leading part of the Request URL (if main file lives in subdirectory of host)
|
||||||
|
*/
|
||||||
|
protected $basePath = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array Array of default match types (regex helpers)
|
||||||
|
*/
|
||||||
|
protected $matchTypes = [
|
||||||
|
'i' => '[0-9]++',
|
||||||
|
'a' => '[0-9A-Za-z]++',
|
||||||
|
'h' => '[0-9A-Fa-f]++',
|
||||||
|
'*' => '.+?',
|
||||||
|
'**' => '.++',
|
||||||
|
'' => '[^/\.]++'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create router in one call from config.
|
||||||
|
*
|
||||||
|
* @param array $routes
|
||||||
|
* @param string $basePath
|
||||||
|
* @param array $matchTypes
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function __construct(array $routes = [], $basePath = '', array $matchTypes = [])
|
||||||
|
{
|
||||||
|
$this->addRoutes($routes);
|
||||||
|
$this->setBasePath($basePath);
|
||||||
|
$this->addMatchTypes($matchTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves all routes.
|
||||||
|
* Useful if you want to process or display routes.
|
||||||
|
* @return array All routes.
|
||||||
|
*/
|
||||||
|
public function getRoutes()
|
||||||
|
{
|
||||||
|
return $this->routes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add multiple routes at once from array in the following format:
|
||||||
|
*
|
||||||
|
* $routes = [
|
||||||
|
* [$method, $route, $target, $name]
|
||||||
|
* ];
|
||||||
|
*
|
||||||
|
* @param array $routes
|
||||||
|
* @return void
|
||||||
|
* @author Koen Punt
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function addRoutes($routes)
|
||||||
|
{
|
||||||
|
if (!is_array($routes) && !$routes instanceof Traversable) {
|
||||||
|
throw new RuntimeException('Routes should be an array or an instance of Traversable');
|
||||||
|
}
|
||||||
|
foreach ($routes as $route) {
|
||||||
|
call_user_func_array([$this, 'map'], $route);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the base path.
|
||||||
|
* Useful if you are running your application from a subdirectory.
|
||||||
|
* @param string $basePath
|
||||||
|
*/
|
||||||
|
public function setBasePath($basePath)
|
||||||
|
{
|
||||||
|
$this->basePath = $basePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add named match types. It uses array_merge so keys can be overwritten.
|
||||||
|
*
|
||||||
|
* @param array $matchTypes The key is the name and the value is the regex.
|
||||||
|
*/
|
||||||
|
public function addMatchTypes(array $matchTypes)
|
||||||
|
{
|
||||||
|
$this->matchTypes = array_merge($this->matchTypes, $matchTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map a route to a target
|
||||||
|
*
|
||||||
|
* @param string $method One of 5 HTTP Methods, or a pipe-separated list of multiple HTTP Methods (GET|POST|PATCH|PUT|DELETE)
|
||||||
|
* @param string $route The route regex, custom regex must start with an @. You can use multiple pre-set regex filters, like [i:id]
|
||||||
|
* @param mixed $target The target where this route should point to. Can be anything.
|
||||||
|
* @param string $name Optional name of this route. Supply if you want to reverse route this url in your application.
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function map($method, $route, $target, $name = null)
|
||||||
|
{
|
||||||
|
|
||||||
|
$this->routes[] = [$method, $route, $target, $name];
|
||||||
|
|
||||||
|
if ($name) {
|
||||||
|
if (isset($this->namedRoutes[$name])) {
|
||||||
|
throw new RuntimeException("Can not redeclare route '{$name}'");
|
||||||
|
}
|
||||||
|
$this->namedRoutes[$name] = $route;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reversed routing
|
||||||
|
*
|
||||||
|
* Generate the URL for a named route. Replace regexes with supplied parameters
|
||||||
|
*
|
||||||
|
* @param string $routeName The name of the route.
|
||||||
|
* @param array @params Associative array of parameters to replace placeholders with.
|
||||||
|
* @return string The URL of the route with named parameters in place.
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function generate($routeName, array $params = [])
|
||||||
|
{
|
||||||
|
|
||||||
|
// Check if named route exists
|
||||||
|
if (!isset($this->namedRoutes[$routeName])) {
|
||||||
|
throw new RuntimeException("Route '{$routeName}' does not exist.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace named parameters
|
||||||
|
$route = $this->namedRoutes[$routeName];
|
||||||
|
|
||||||
|
// prepend base path to route url again
|
||||||
|
$url = $this->basePath . $route;
|
||||||
|
|
||||||
|
if (preg_match_all('`(/|\.|)\[([^:\]]*+)(?::([^:\]]*+))?\](\?|)`', $route, $matches, PREG_SET_ORDER)) {
|
||||||
|
foreach ($matches as $index => $match) {
|
||||||
|
list($block, $pre, $type, $param, $optional) = $match;
|
||||||
|
|
||||||
|
if ($pre) {
|
||||||
|
$block = substr($block, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($params[$param])) {
|
||||||
|
// Part is found, replace for param value
|
||||||
|
$url = str_replace($block, $params[$param], $url);
|
||||||
|
} elseif ($optional && $index !== 0) {
|
||||||
|
// Only strip preceding slash if it's not at the base
|
||||||
|
$url = str_replace($pre . $block, '', $url);
|
||||||
|
} else {
|
||||||
|
// Strip match block
|
||||||
|
$url = str_replace($block, '', $url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Match a given Request Url against stored routes
|
||||||
|
* @param string $requestUrl
|
||||||
|
* @param string $requestMethod
|
||||||
|
* @return array|boolean Array with route information on success, false on failure (no match).
|
||||||
|
*/
|
||||||
|
public function match($requestUrl = null, $requestMethod = null)
|
||||||
|
{
|
||||||
|
|
||||||
|
$params = [];
|
||||||
|
|
||||||
|
// set Request Url if it isn't passed as parameter
|
||||||
|
if ($requestUrl === null) {
|
||||||
|
$requestUrl = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
// strip base path from request url
|
||||||
|
$requestUrl = substr($requestUrl, strlen($this->basePath));
|
||||||
|
|
||||||
|
// Strip query string (?a=b) from Request Url
|
||||||
|
if (($strpos = strpos($requestUrl, '?')) !== false) {
|
||||||
|
$requestUrl = substr($requestUrl, 0, $strpos);
|
||||||
|
}
|
||||||
|
|
||||||
|
$lastRequestUrlChar = $requestUrl ? $requestUrl[strlen($requestUrl)-1] : '';
|
||||||
|
|
||||||
|
// set Request Method if it isn't passed as a parameter
|
||||||
|
if ($requestMethod === null) {
|
||||||
|
$requestMethod = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'GET';
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->routes as $handler) {
|
||||||
|
list($methods, $route, $target, $name) = $handler;
|
||||||
|
|
||||||
|
$method_match = (stripos($methods, $requestMethod) !== false);
|
||||||
|
|
||||||
|
// Method did not match, continue to next route.
|
||||||
|
if (!$method_match) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($route === '*') {
|
||||||
|
// * wildcard (matches all)
|
||||||
|
$match = true;
|
||||||
|
} elseif (isset($route[0]) && $route[0] === '@') {
|
||||||
|
// @ regex delimiter
|
||||||
|
$pattern = '`' . substr($route, 1) . '`u';
|
||||||
|
$match = preg_match($pattern, $requestUrl, $params) === 1;
|
||||||
|
} elseif (($position = strpos($route, '[')) === false) {
|
||||||
|
// No params in url, do string comparison
|
||||||
|
$match = strcmp($requestUrl, $route) === 0;
|
||||||
|
} else {
|
||||||
|
// Compare longest non-param string with url before moving on to regex
|
||||||
|
// Check if last character before param is a slash, because it could be optional if param is optional too (see https://github.com/dannyvankooten/AltoRouter/issues/241)
|
||||||
|
if (strncmp($requestUrl, $route, $position) !== 0 && ($lastRequestUrlChar === '/' || $route[$position-1] !== '/')) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$regex = $this->compileRoute($route);
|
||||||
|
$match = preg_match($regex, $requestUrl, $params) === 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($match) {
|
||||||
|
if ($params) {
|
||||||
|
foreach ($params as $key => $value) {
|
||||||
|
if (is_numeric($key)) {
|
||||||
|
unset($params[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'target' => $target,
|
||||||
|
'params' => $params,
|
||||||
|
'name' => $name
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compile the regex for a given route (EXPENSIVE)
|
||||||
|
* @param $route
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function compileRoute($route)
|
||||||
|
{
|
||||||
|
if (preg_match_all('`(/|\.|)\[([^:\]]*+)(?::([^:\]]*+))?\](\?|)`', $route, $matches, PREG_SET_ORDER)) {
|
||||||
|
$matchTypes = $this->matchTypes;
|
||||||
|
foreach ($matches as $match) {
|
||||||
|
list($block, $pre, $type, $param, $optional) = $match;
|
||||||
|
|
||||||
|
if (isset($matchTypes[$type])) {
|
||||||
|
$type = $matchTypes[$type];
|
||||||
|
}
|
||||||
|
if ($pre === '.') {
|
||||||
|
$pre = '\.';
|
||||||
|
}
|
||||||
|
|
||||||
|
$optional = $optional !== '' ? '?' : null;
|
||||||
|
|
||||||
|
//Older versions of PCRE require the 'P' in (?P<named>)
|
||||||
|
$pattern = '(?:'
|
||||||
|
. ($pre !== '' ? $pre : null)
|
||||||
|
. '('
|
||||||
|
. ($param !== '' ? "?P<$param>" : null)
|
||||||
|
. $type
|
||||||
|
. ')'
|
||||||
|
. $optional
|
||||||
|
. ')'
|
||||||
|
. $optional;
|
||||||
|
|
||||||
|
$route = str_replace($block, $pattern, $route);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "`^$route$`u";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2012 Danny van Kooten <hi@dannyvankooten.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@ -0,0 +1,57 @@
|
|||||||
|
# AltoRouter  [](https://packagist.org/packages/altorouter/altorouter) [](https://packagist.org/packages/altorouter/altorouter)
|
||||||
|
|
||||||
|
AltoRouter is a small but powerful routing class, heavily inspired by [klein.php](https://github.com/chriso/klein.php/).
|
||||||
|
|
||||||
|
```php
|
||||||
|
$router = new AltoRouter();
|
||||||
|
|
||||||
|
// map homepage
|
||||||
|
$router->map('GET', '/', function() {
|
||||||
|
require __DIR__ . '/views/home.php';
|
||||||
|
});
|
||||||
|
|
||||||
|
// dynamic named route
|
||||||
|
$router->map('GET|POST', '/users/[i:id]/', function($id) {
|
||||||
|
$user = .....
|
||||||
|
require __DIR__ . '/views/user/details.php';
|
||||||
|
}, 'user-details');
|
||||||
|
|
||||||
|
// echo URL to user-details page for ID 5
|
||||||
|
echo $router->generate('user-details', ['id' => 5]); // Output: "/users/5"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
* Can be used with all HTTP Methods
|
||||||
|
* Dynamic routing with named route parameters
|
||||||
|
* Reversed routing
|
||||||
|
* Flexible regular expression routing (inspired by [Sinatra](http://www.sinatrarb.com/))
|
||||||
|
* Custom regexes
|
||||||
|
|
||||||
|
## Getting started
|
||||||
|
|
||||||
|
You need PHP >= 5.6 to use AltoRouter, although we highly recommend you [use an officially supported PHP version](https://secure.php.net/supported-versions.php) that is not EOL.
|
||||||
|
|
||||||
|
- [Install AltoRouter](http://altorouter.com/usage/install.html)
|
||||||
|
- [Rewrite all requests to AltoRouter](http://altorouter.com/usage/rewrite-requests.html)
|
||||||
|
- [Map your routes](http://altorouter.com/usage/mapping-routes.html)
|
||||||
|
- [Match requests](http://altorouter.com/usage/matching-requests.html)
|
||||||
|
- [Process the request your preferred way](http://altorouter.com/usage/processing-requests.html)
|
||||||
|
|
||||||
|
## Contributors
|
||||||
|
- [Danny van Kooten](https://github.com/dannyvankooten)
|
||||||
|
- [Koen Punt](https://github.com/koenpunt)
|
||||||
|
- [John Long](https://github.com/adduc)
|
||||||
|
- [Niahoo Osef](https://github.com/niahoo)
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2012 Danny van Kooten <hi@dannyvankooten.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"name": "altorouter/altorouter",
|
||||||
|
"description": "A lightning fast router for PHP",
|
||||||
|
"keywords": ["router", "routing", "lightweight"],
|
||||||
|
"homepage": "https://github.com/dannyvankooten/AltoRouter",
|
||||||
|
"license": "MIT",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Danny van Kooten",
|
||||||
|
"email": "dannyvankooten@gmail.com",
|
||||||
|
"homepage": "http://dannyvankooten.com/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Koen Punt",
|
||||||
|
"homepage": "https://github.com/koenpunt"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "niahoo",
|
||||||
|
"homepage": "https://github.com/niahoo"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.6.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "9.5.*",
|
||||||
|
"squizlabs/php_codesniffer": "3.6.2"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"classmap": ["AltoRouter.php"]
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"test": "vendor/bin/phpunit"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<ruleset name="rules">
|
||||||
|
<description>rules</description>
|
||||||
|
<rule ref="PSR2"/>
|
||||||
|
<rule ref="Generic.Arrays.DisallowLongArraySyntax"/>
|
||||||
|
<file>tests</file>
|
||||||
|
<file>AltoRouter.php</file>
|
||||||
|
<file>examples/</file>
|
||||||
|
<arg name="colors"/>
|
||||||
|
</ruleset>
|
@ -1,18 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace model;
|
|
||||||
|
|
||||||
use DAL;
|
|
||||||
use metier;
|
|
||||||
class ArticleModel
|
|
||||||
{
|
|
||||||
public static function getArticles() : array
|
|
||||||
{
|
|
||||||
$gwArticle = new DAL\ArticleGateway(new DAL\Connection('mysql:host = localhost; dbname = dbrorossetto', 'rorossetto', 'tpphp'));
|
|
||||||
$res = $gwArticle->getAllArticles();
|
|
||||||
foreach($res as $row){
|
|
||||||
$tabArticle[] = new metier\Article($row['id'], $row['title'],$row['datePub'],$row['description'],$row['guid'],$row['link'],$row['mediaContent'],$row['provenance'] );
|
|
||||||
}
|
|
||||||
return $tabArticle;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,61 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace model;
|
|
||||||
|
|
||||||
class FluxModel
|
|
||||||
{
|
|
||||||
private FluxGateway $gateway;
|
|
||||||
public function FindAllFlux(){
|
|
||||||
$data = array();
|
|
||||||
$result = $this->gateway->findAllFlux();
|
|
||||||
|
|
||||||
foreach ($result as $row){
|
|
||||||
$data[] = new Flux($row['$flux']);
|
|
||||||
}
|
|
||||||
return $data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addFlux(Flux $flux)
|
|
||||||
{
|
|
||||||
$data = findFlux($flux);
|
|
||||||
if ($data == array()) {
|
|
||||||
$this->gateway->addFlux($flux);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addFluxBySrc(string $flux): Flux {
|
|
||||||
$newFlux = new Flux($flux);
|
|
||||||
$this->gateway->addFlux($newFlux);
|
|
||||||
return $newFlux;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function removeFlux(Flux $flux){
|
|
||||||
$this->gateway->removeFlux($flux);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function removeFluxBySrc(string $flux): Flux {
|
|
||||||
$newFlux = new Flux($flux);
|
|
||||||
$this->gateway->removeFlux($newFlux);
|
|
||||||
return $newFlux;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function findFlux(Flux $flux){
|
|
||||||
$data = array();
|
|
||||||
$result = $this->gateway->findFlux($flux);
|
|
||||||
|
|
||||||
foreach ($result as $row){
|
|
||||||
$data[] = new Flux($row['$flux']);
|
|
||||||
}
|
|
||||||
return $data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function findFluxBySrc(string $flux){
|
|
||||||
$data = array();
|
|
||||||
$result = $this->gateway->findFluxBySrc($flux);
|
|
||||||
|
|
||||||
foreach ($result as $row){
|
|
||||||
$data[] = new Flux($row['$flux']);
|
|
||||||
}
|
|
||||||
return $data;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,68 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace model;
|
|
||||||
|
|
||||||
use DAL\ArticleGateway;
|
|
||||||
use DAL\FluxGateway;
|
|
||||||
use DOMDocument;
|
|
||||||
use Exception;
|
|
||||||
use metier\Article;
|
|
||||||
use metier\Flux;
|
|
||||||
|
|
||||||
class Parser
|
|
||||||
{
|
|
||||||
private FluxGateway $fluxGateway;
|
|
||||||
private ArticleGateway $articleGateway;
|
|
||||||
|
|
||||||
public function __construct(FluxGateway $fluxGateway, ArticleGateway $articleGateway){
|
|
||||||
$this->fluxGateway = $fluxGateway;
|
|
||||||
$this->articleGateway = $articleGateway;
|
|
||||||
}
|
|
||||||
public function parseArticles(Flux $flux): array
|
|
||||||
{
|
|
||||||
$dom = new DOMDocument();
|
|
||||||
$tabArticle = array();
|
|
||||||
|
|
||||||
if ($dom->load($flux->getFlux())){
|
|
||||||
$items = $dom->getElementsByTagName('item');
|
|
||||||
|
|
||||||
foreach ($items as $item) {
|
|
||||||
$title = $item->getElementsByTagName('title')[0]->nodeValue;
|
|
||||||
$date = $item->getElementsByTagName('pubDate')[0]->nodeValue;
|
|
||||||
$guid = $item->getElementsByTagName('guid')[0]->nodeValue;
|
|
||||||
$link = $item->getElementsByTagName('link')[0]->nodeValue;
|
|
||||||
$description = $item->getElementsByTagName('description')[0]->nodeValue;
|
|
||||||
|
|
||||||
$media = $item->getElementsByTagName('media:content');
|
|
||||||
$mediaUrl = null;
|
|
||||||
if ($media->length > 0){
|
|
||||||
$mediaUrl = $media->item(0)->getAttribute('url');
|
|
||||||
}
|
|
||||||
|
|
||||||
$tabArticle[] = new Article((int)null, $title, $date, $description, $guid, $link, $mediaUrl, $flux->getId());
|
|
||||||
}
|
|
||||||
return $tabArticle;
|
|
||||||
} else {
|
|
||||||
// En cas d'erreur lors du chargement du flux RSS, lever une exception
|
|
||||||
throw new Exception("Erreur lors du chargement du flux RSS");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function parseAll($fluxes){
|
|
||||||
foreach ($fluxes as $flux){
|
|
||||||
$tabArticles[] =$this->parseArticles($flux);
|
|
||||||
}
|
|
||||||
return $tabArticles;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addAllArticles(){
|
|
||||||
$allFlux = $this->fluxGateway->findAllFlux();
|
|
||||||
|
|
||||||
$allArticles = $this->parseAll($allFlux);
|
|
||||||
|
|
||||||
foreach ($allArticles as $article) {
|
|
||||||
$this->articleGateway->addArticle($article);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace DAL;
|
||||||
|
|
||||||
|
use PDO;
|
||||||
|
|
||||||
|
class AdminGateway
|
||||||
|
{
|
||||||
|
private $con;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $con
|
||||||
|
*/
|
||||||
|
public function __construct($con)
|
||||||
|
{
|
||||||
|
$this->con = $con;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function login(string $login):array
|
||||||
|
{
|
||||||
|
$query = 'SELECT password,mail FROM Admin WHERE name = :login;';
|
||||||
|
$this->con->executeQuery($query, array(':login' => array($login, PDO::PARAM_STR)));
|
||||||
|
return $this->con->getResults();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
<?php
|
||||||
|
namespace DAL;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
use metier\Article;
|
||||||
|
use metier\Flux;
|
||||||
|
use PDO;
|
||||||
|
class ArticleGateway
|
||||||
|
{
|
||||||
|
private $con;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $con
|
||||||
|
*/
|
||||||
|
public function __construct($con)
|
||||||
|
{
|
||||||
|
$this->con = $con;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function getAllArticles():array
|
||||||
|
{
|
||||||
|
$query = 'SELECT * FROM Article ORDER BY datePub DESC;';
|
||||||
|
$this->con->executeQuery($query, array());
|
||||||
|
return $this->con->getResults();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function addArticle(Article $article){
|
||||||
|
$query = "INSERT INTO Article VALUES (:id,:title,STR_TO_DATE(:datePub, '%d/%m/%y %H:%i'),:description,:guid,:link,:mediaContent,:provenance);";
|
||||||
|
$this->con->executeQuery($query, array(':id' => array($article->getId(), PDO::PARAM_STR),
|
||||||
|
':title' => array($article->getTitle(), PDO::PARAM_STR),
|
||||||
|
':datePub' => array($article->getDate(), PDO::PARAM_STR),
|
||||||
|
':description' => array($article->getDescription(), PDO::PARAM_STR),
|
||||||
|
':guid' => array($article->getGuid(), PDO::PARAM_STR),
|
||||||
|
':link' => array($article->getLink(), PDO::PARAM_STR),
|
||||||
|
':mediaContent' => array($article->getMediaContent(), PDO::PARAM_STR),
|
||||||
|
':provenance' => array($article->getProvenance(), PDO::PARAM_INT)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeAllArticleForParser(){
|
||||||
|
$query = 'DELETE FROM Article;';
|
||||||
|
$this->con->executeQuery($query);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeAllArticleFromFlux(int $idFlux){
|
||||||
|
try {
|
||||||
|
$query = 'DELETE FROM Article WHERE Provenance = :idFlux;';
|
||||||
|
$this->con->executeQuery($query, array(':idFlux' => array($idFlux, PDO::PARAM_INT)));
|
||||||
|
}catch(\PDOException $p){
|
||||||
|
throw new Exception("Data of flux is not delete.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findArticleByFlux(int $flux){
|
||||||
|
$query = 'SELECT * FROM Article WHERE provenance = :flux;';
|
||||||
|
$this->con->executeQuery($query, array(':flux' => array($flux, PDO::PARAM_INT)));
|
||||||
|
return $this->con->getResults();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace DAL;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
use PDO;
|
||||||
|
use Twig\Error\Error;
|
||||||
|
|
||||||
|
class Connection extends PDO
|
||||||
|
{
|
||||||
|
private $stmt; // pas typé, car peut être faux ou statement
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $dsn
|
||||||
|
* @param string $username
|
||||||
|
* @param string $password
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function __construct(string $dsn, string $username, string $password)
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
parent::__construct($dsn, $username, $password);
|
||||||
|
$this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||||
|
}catch (\PDOException $e){
|
||||||
|
throw new Exception("PDO error con");
|
||||||
|
}
|
||||||
|
catch (Error $e){
|
||||||
|
throw new Error("Error PDO");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $query to execute
|
||||||
|
* @param array $parameters to bind
|
||||||
|
* @return bool Returns `true` on success, `false` otherwise
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function executeQuery(string $query, array $parameters = []): bool
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
$this->stmt = parent::prepare($query);
|
||||||
|
foreach ($parameters as $name => $value) {
|
||||||
|
$this->stmt->bindValue($name, $value[0], $value[1]);
|
||||||
|
}
|
||||||
|
if($this->stmt->execute()){
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
$error = $this->stmt->errorInfo();
|
||||||
|
throw new Exception("PDO error: ".$error[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}catch (\PDOException $e){
|
||||||
|
throw new Exception("PDO error: ".$e->getMessage());
|
||||||
|
}catch (\Error $r){
|
||||||
|
throw new Error("executionQuery not possible : ".$r->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getResults(): array
|
||||||
|
{
|
||||||
|
return $this->stmt->fetchall();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
//gen
|
||||||
|
$rep = __DIR__ . '/fluxRSS/';
|
||||||
|
|
||||||
|
// liste des modules à inclure
|
||||||
|
|
||||||
|
//$dConfig['includes']= array('controleur/Validation.php');
|
||||||
|
|
||||||
|
//BD
|
||||||
|
|
||||||
|
$base = 'mysql:host=londres.uca.local;dbname=dbrorossetto';
|
||||||
|
$login = 'rorossetto';
|
||||||
|
$mdpBd = 'tpphp';
|
||||||
|
$path = '~mapoint2/public_html/SAE/Php_RSS';
|
||||||
|
$nbArticle = 10;
|
@ -0,0 +1,185 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace controleur;
|
||||||
|
|
||||||
|
use config\Validation;
|
||||||
|
use DAL\ArticleGateway;
|
||||||
|
use DAL\Connection;
|
||||||
|
use DAL\FluxGateway;
|
||||||
|
use http\Exception;
|
||||||
|
use http\Url;
|
||||||
|
use metier\Flux;
|
||||||
|
use model\AdminModel;
|
||||||
|
use model\ArticleModel;
|
||||||
|
use model\FluxModel;
|
||||||
|
|
||||||
|
class AdminControleur
|
||||||
|
{
|
||||||
|
public function init(){
|
||||||
|
global $twig; // nécessaire pour utiliser variables globales
|
||||||
|
//debut
|
||||||
|
|
||||||
|
//on initialise un tableau d'erreur
|
||||||
|
$dVueEreur = [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
$action = $_REQUEST['action'] ?? null;
|
||||||
|
|
||||||
|
switch($action) {
|
||||||
|
//pas d'action, on réinitialise 1er appel
|
||||||
|
case 'listArticle':
|
||||||
|
case null:
|
||||||
|
$this->listArticle();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'connection':
|
||||||
|
$this->connection();;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'deleteFlux':
|
||||||
|
$this->deleteFlux();;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'validationFormulaire':
|
||||||
|
$this->ValidationFormulaire($dVueEreur);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'listFlux':
|
||||||
|
$this->listFlux();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'ajoutFlux':
|
||||||
|
$this->ajoutFlux();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'changeNbArticle':
|
||||||
|
$this->changeNbArticle();
|
||||||
|
break;
|
||||||
|
|
||||||
|
//mauvaise action
|
||||||
|
default:
|
||||||
|
$dVueEreur[] = "Erreur d'appel php";
|
||||||
|
echo $twig->render('erreur.html', ['dVueErreur'=>$dVueEreur,'isAdmin' => (AdminModel::isAdmin())]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (\PDOException $e) {
|
||||||
|
//si erreur BD, pas le cas ici
|
||||||
|
$dVueEreur[] = 'Erreur PDO : ' . $e->getMessage();
|
||||||
|
echo $twig->render('erreur.html', ['dVueEreur' => $dVueEreur]);
|
||||||
|
} catch (\Exception $e2) {
|
||||||
|
$dVueEreur[] = 'Erreur : ' . $e2->getMessage();
|
||||||
|
echo $twig->render('erreur.html', ['dVueEreur' => $dVueEreur]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//fin
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function listArticle()
|
||||||
|
{
|
||||||
|
global $twig;
|
||||||
|
$articleModel = new ArticleModel();
|
||||||
|
$nbArticle = isset($_SESSION['nbArticleAdmin']) ? intval($_SESSION['nbArticleAdmin']) : 5;
|
||||||
|
$allArticles = $articleModel->getArticles();
|
||||||
|
$articles = array_slice($allArticles, 0, $nbArticle);
|
||||||
|
if (AdminModel::isAdmin()) {
|
||||||
|
$dVue = [
|
||||||
|
'data' => $articles
|
||||||
|
];
|
||||||
|
echo $twig->render('listArticleAdmin.html', [
|
||||||
|
'dVue' => $dVue,
|
||||||
|
'isAdmin' => AdminModel::isAdmin()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$this->connection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function listFlux(){
|
||||||
|
global $twig;
|
||||||
|
$fluxModel = new FluxModel();
|
||||||
|
if (AdminModel::isAdmin()) {
|
||||||
|
$dVue = [
|
||||||
|
'data' => $fluxModel->findAllFlux()
|
||||||
|
];
|
||||||
|
echo $twig->render('listFlux.html', [
|
||||||
|
'dVue' => $dVue,
|
||||||
|
'isAdmin' => AdminModel::isAdmin()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$this->connection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function connection(){
|
||||||
|
global $twig; // nécessaire pour utiliser variables globales
|
||||||
|
|
||||||
|
$renderTemplate = true;
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['username'])){
|
||||||
|
$_REQUEST['action'] = null;
|
||||||
|
$this->login();
|
||||||
|
$renderTemplate = false;
|
||||||
|
}
|
||||||
|
if($renderTemplate) {
|
||||||
|
echo $twig->render('Connection.html');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleteFlux(){
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['flux'])){
|
||||||
|
$articleModel = new ArticleModel();
|
||||||
|
$fluxModel = new FluxModel();
|
||||||
|
$articleModel->removeArticleIdFlux(intval($_POST['flux']));
|
||||||
|
$fluxModel->removeFluxById(intval($_POST['flux']));
|
||||||
|
$_REQUEST['action'] = 'listFlux';
|
||||||
|
$this->init();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$_REQUEST['action'] = 'listFlux';
|
||||||
|
$this->init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function ajoutFlux(){
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['fluxAdd'])){
|
||||||
|
$fluxModel = new FluxModel();
|
||||||
|
if(Validation::ValidationFlux($_POST['fluxAdd'])){
|
||||||
|
$fluxModel->addFluxBySrc($_POST['fluxAdd']);
|
||||||
|
}
|
||||||
|
$_REQUEST['action'] = 'listFlux';
|
||||||
|
unset($_POST['fluxAdd']);
|
||||||
|
$this->init();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$_REQUEST['action'] = 'listFlux';
|
||||||
|
$this->init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function login(){
|
||||||
|
$username = $_POST['username'];
|
||||||
|
$password = $_POST['password'];
|
||||||
|
|
||||||
|
$adminModel = new AdminModel();
|
||||||
|
$admin = $adminModel->connection($username, $password);
|
||||||
|
if($admin != null) {
|
||||||
|
$this->init();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
unset($_POST['username']);
|
||||||
|
unset($_POST['password']);
|
||||||
|
$this->connection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function changeNbArticle()
|
||||||
|
{
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['nbArticleAdmin'])) {
|
||||||
|
$_SESSION['nbArticleAdmin'] = $_POST['nbArticleAdmin'];
|
||||||
|
unset($_POST['action']);
|
||||||
|
}
|
||||||
|
$this->init();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace controleur;
|
||||||
|
|
||||||
|
use model\AdminModel;
|
||||||
|
use vendor\AltoRouter;
|
||||||
|
use controleur\UserControleur;
|
||||||
|
use controleur\AdminControleur;
|
||||||
|
require 'AltoRouter.php';
|
||||||
|
|
||||||
|
class FrontControleur
|
||||||
|
{
|
||||||
|
public function __construct(){
|
||||||
|
$routeur = new AltoRouter();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
global $twig;
|
||||||
|
$router = new AltoRouter();
|
||||||
|
$router->setBasePath('~rorossetto/Php_RSS/fluxRSS/');
|
||||||
|
$router->map('GET', '/', 'UserControleur');
|
||||||
|
$router->map('GET|POST', '/[a:action]?', 'UserControleur');
|
||||||
|
$router->map('GET|POST','/user/[a:action]?','UserControleur');
|
||||||
|
$router->map('GET|POST','/admin/[a:action]?','AdminControleur');
|
||||||
|
|
||||||
|
$match = $router->match();
|
||||||
|
if (!$match) {
|
||||||
|
$dVueEreur[] = "Page doesn't exist";
|
||||||
|
echo $twig->render('erreur.html', ['dVueEreur' => $dVueEreur]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
session_start();
|
||||||
|
$controller=$match['target'] ?? null;
|
||||||
|
$action=$match['params']['action'] ?? "init";
|
||||||
|
try {
|
||||||
|
if($controller == "AdminControleur"){
|
||||||
|
if (!AdminModel::isAdmin()){
|
||||||
|
$action = "connection";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if($action == 'deconnection'){
|
||||||
|
AdminModel::deconnection();
|
||||||
|
}
|
||||||
|
$controller = '\\controleur\\' . $controller;
|
||||||
|
$controller = new $controller;
|
||||||
|
if (is_callable(array($controller, $action))) {
|
||||||
|
call_user_func_array(array($controller, $action),
|
||||||
|
array($match['params']));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Error $error){
|
||||||
|
$dVueEreur[] = "Controller doesn't exist";
|
||||||
|
echo $twig->render('erreur.html', ['dVueEreur' => $dVueEreur]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,151 @@
|
|||||||
|
<?php
|
||||||
|
namespace controleur;
|
||||||
|
|
||||||
|
use model\AdminModel;
|
||||||
|
use model\ArticleModel;
|
||||||
|
|
||||||
|
class UserControleur
|
||||||
|
{
|
||||||
|
public function init()
|
||||||
|
{
|
||||||
|
global $twig; // nécessaire pour utiliser variables globales
|
||||||
|
//debut
|
||||||
|
|
||||||
|
//on initialise un tableau d'erreur
|
||||||
|
$dVueEreur = [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
$action = $_REQUEST['action'] ?? null;
|
||||||
|
|
||||||
|
switch($action) {
|
||||||
|
//pas d'action, on réinitialise 1er appel
|
||||||
|
case 'listArticle':
|
||||||
|
case null:
|
||||||
|
$this->listArticle();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'connection':
|
||||||
|
$this->connection();;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'deconnection':
|
||||||
|
$this->deconnection();
|
||||||
|
break;
|
||||||
|
case 'validationFormulaire':
|
||||||
|
$this->ValidationFormulaire($dVueEreur);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'changeNbArticle':
|
||||||
|
$this->changeNbArticle();
|
||||||
|
break;
|
||||||
|
|
||||||
|
//mauvaise action
|
||||||
|
default:
|
||||||
|
$dVueEreur[] = "Erreur d'appel php";
|
||||||
|
echo $twig->render('erreur.html', ['dVueErreur'=>$dVueEreur, 'isAdmin' => AdminModel::isAdmin()]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (\PDOException $e) {
|
||||||
|
//si erreur BD, pas le cas ici
|
||||||
|
$dVueEreur[] = 'Erreur PDO : ' . $e->getMessage();
|
||||||
|
echo $twig->render('erreur.html', ['dVueEreur' => $dVueEreur]);
|
||||||
|
} catch (\Exception $e2) {
|
||||||
|
$dVueEreur[] = 'Erreur : ' . $e2->getMessage();
|
||||||
|
echo $twig->render('erreur.html', ['dVueEreur' => $dVueEreur]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//fin
|
||||||
|
exit(0);
|
||||||
|
}//fin constructeur
|
||||||
|
|
||||||
|
public function listArticle()
|
||||||
|
{
|
||||||
|
global $twig;
|
||||||
|
$articleModel = new ArticleModel();
|
||||||
|
$nbArticle = isset($_SESSION['nbArticle']) ? intval($_SESSION['nbArticle']) : 5;
|
||||||
|
$allArticles = $articleModel->getArticles();
|
||||||
|
$articles = array_slice($allArticles, 0, $nbArticle);
|
||||||
|
$dVue = [
|
||||||
|
'data' => $articles
|
||||||
|
];
|
||||||
|
echo $twig->render('listArticle.html', [
|
||||||
|
'dVue' => $dVue,
|
||||||
|
'isAdmin' => AdminModel::isAdmin()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function changeNbArticle()
|
||||||
|
{
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['nbArticle'])) {
|
||||||
|
$_SESSION['nbArticle'] = $_POST['nbArticle'];
|
||||||
|
unset($_POST['action']);
|
||||||
|
}
|
||||||
|
$this->init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws \Twig\Error\RuntimeError
|
||||||
|
* @throws \Twig\Error\SyntaxError
|
||||||
|
* @throws \Twig\Error\LoaderError
|
||||||
|
*/
|
||||||
|
public function connection(){
|
||||||
|
global $twig; // nécessaire pour utiliser variables globales
|
||||||
|
if (AdminModel::isAdmin()) {
|
||||||
|
$this->listArticle();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
echo $twig->render('Connection.html');
|
||||||
|
if (isset($_POST['username']) && isset($_POST['password'])) {
|
||||||
|
$this->login();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deconnection(){
|
||||||
|
AdminModel::deconnection();
|
||||||
|
$this->listArticle();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws \Twig\Error\RuntimeError
|
||||||
|
* @throws \Twig\Error\SyntaxError
|
||||||
|
* @throws \Twig\Error\LoaderError
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function login(){
|
||||||
|
$username = $_POST['username'];
|
||||||
|
$password = $_POST['password'];
|
||||||
|
|
||||||
|
$adminModel = new AdminModel();
|
||||||
|
$admin = $adminModel->connection($username, $password);
|
||||||
|
if ($admin != null) {
|
||||||
|
$this->listArticle();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$this->connection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function ValidationFormulaire(array $dVueEreur)
|
||||||
|
{
|
||||||
|
global $twig; // nécessaire pour utiliser variables globales
|
||||||
|
|
||||||
|
//si exception, ca remonte !!!
|
||||||
|
$nom = $_POST['txtNom']; // txtNom = nom du champ texte dans le formulaire
|
||||||
|
$age = $_POST['txtAge'];
|
||||||
|
\config\Validation::val_form($nom, $age, $dVueEreur);
|
||||||
|
|
||||||
|
/*
|
||||||
|
$model = new \metier\Simplemodel();
|
||||||
|
$data = $model->get_data();
|
||||||
|
*/
|
||||||
|
|
||||||
|
$dVue = [
|
||||||
|
'nom' => $nom,
|
||||||
|
'age' => $age,
|
||||||
|
//'data' => $data,
|
||||||
|
];
|
||||||
|
|
||||||
|
echo $twig->render('Connection.html', ['dVue' => $dVue, 'dVueEreur' => $dVueEreur]);
|
||||||
|
}
|
||||||
|
}//fin class
|
@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace metier;
|
||||||
|
|
||||||
|
class Admin
|
||||||
|
{
|
||||||
|
private string $username;
|
||||||
|
private string $mail;
|
||||||
|
|
||||||
|
public function __construct($username,$mail){
|
||||||
|
$this->username = $username;
|
||||||
|
$this->mail = $mail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getUsername(): string
|
||||||
|
{
|
||||||
|
return $this->username;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $username
|
||||||
|
*/
|
||||||
|
public function setUsername(string $username): void
|
||||||
|
{
|
||||||
|
$this->username = $username;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getMail(): string
|
||||||
|
{
|
||||||
|
return $this->mail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $mail
|
||||||
|
*/
|
||||||
|
public function setMail(string $mail): void
|
||||||
|
{
|
||||||
|
$this->mail = $mail;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace model;
|
||||||
|
|
||||||
|
use config\Validation;
|
||||||
|
use DAL\AdminGateway;
|
||||||
|
use DAL\Connection;
|
||||||
|
use metier\Admin;
|
||||||
|
|
||||||
|
class AdminModel
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function connection (string $username, string $mdp){
|
||||||
|
|
||||||
|
|
||||||
|
$gwArticle = new AdminGateway(new Connection('mysql:host=londres.uca.local;dbname=dbrorossetto','rorossetto','tpphp'));
|
||||||
|
if (Validation::validationLogin($username)){
|
||||||
|
$lmdp = $gwArticle->login($username);
|
||||||
|
}
|
||||||
|
if(Validation::validationMdp($mdp)){
|
||||||
|
foreach ($lmdp as $motDePasse){
|
||||||
|
if (password_verify($mdp,$motDePasse['password']) or $mdp == $motDePasse['password']){ //Si ajout d'admin on créer avec password_hash(string $mdp)
|
||||||
|
$_SESSION['role'] = 'admin';
|
||||||
|
$_SESSION['pseudo'] = $username;
|
||||||
|
return new Admin($username,$motDePasse['mail']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function isAdmin(): bool
|
||||||
|
{
|
||||||
|
return (isset($_SESSION['role']) && $_SESSION['role'] == 'admin');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function deconnection(){
|
||||||
|
$_SESSION['role'] = "";
|
||||||
|
unset($_SESSION['role']);
|
||||||
|
$_SESSION['pseudo'] = "";
|
||||||
|
unset($_SESSION['pseudo']);
|
||||||
|
header("Location: /~rorossetto/Php_RSS/fluxRSS/admin/");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace model;
|
||||||
|
|
||||||
|
use DAL\{ArticleGateway, Connection, FluxGateway};
|
||||||
|
use Exception;
|
||||||
|
use metier\Article;
|
||||||
|
use metier\Flux;
|
||||||
|
|
||||||
|
class ArticleModel
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static function getArticles() : array
|
||||||
|
{
|
||||||
|
$gwArticle = new ArticleGateway(new Connection('mysql:host=londres.uca.local;dbname=dbrorossetto','rorossetto','tpphp'));
|
||||||
|
$tabArticle = array();
|
||||||
|
$res = $gwArticle->getAllArticles();
|
||||||
|
foreach($res as $row){
|
||||||
|
$tabArticle[] = new Article($row['id'], $row['title'],$row['datePub'],$row['description'],$row['guid'],$row['link'],$row['mediaContent'],$row['provenance'] );
|
||||||
|
}
|
||||||
|
return $tabArticle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function findArticleByFlux(Flux $flux){
|
||||||
|
$con = new Connection('mysql:host=londres.uca.local;dbname=dbrorossetto','rorossetto','tpphp');
|
||||||
|
$gwArticle = new ArticleGateway($con);
|
||||||
|
$dicoFluxArticle = array();
|
||||||
|
$tabArticle = array();
|
||||||
|
$res = $gwArticle->findArticleByFlux($flux->getId());
|
||||||
|
|
||||||
|
foreach ($res as $row){
|
||||||
|
$tabArticle[] = new Article($row['id'], $row['title'],$row['datePub'],$row['description'],$row['guid'],$row['link'],$row['mediaContent'],$row['provenance'] );
|
||||||
|
}
|
||||||
|
$dicoFluxArticle[] = [$flux,$tabArticle];
|
||||||
|
return $dicoFluxArticle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findAllArticleByAllFlux(){
|
||||||
|
$con = new Connection('mysql:host=londres.uca.local;dbname=dbrorossetto','rorossetto','tpphp');
|
||||||
|
$gwFlux = new FluxGateway($con);
|
||||||
|
$tabFluxArticle = array();
|
||||||
|
$res = $gwFlux->findAllFlux();
|
||||||
|
|
||||||
|
foreach ($res as $row) {
|
||||||
|
$flux = new Flux((int)($row['id']),$row['flux']);
|
||||||
|
$tabFluxArticle[] = $this->findArticleByFluxAsStr($flux);
|
||||||
|
}
|
||||||
|
return $tabFluxArticle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findArticleByFluxAsStr(Flux $flux){
|
||||||
|
$con = new Connection('mysql:host=londres.uca.local;dbname=dbrorossetto','rorossetto','tpphp');
|
||||||
|
$gwArticle = new ArticleGateway($con);
|
||||||
|
$tabArticle = array();
|
||||||
|
$res = $gwArticle->findArticleByFlux($flux->getId());
|
||||||
|
|
||||||
|
foreach ($res as $row){
|
||||||
|
$article = new Article($row['id'], $row['title'],$row['datePub'],$row['description'],$row['guid'],$row['link'],$row['mediaContent'],$row['provenance'] );
|
||||||
|
$tabArticle[] = (string)$article;
|
||||||
|
}
|
||||||
|
$dicoFluxArticle = [$flux,$tabArticle];
|
||||||
|
return $dicoFluxArticle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function removeArticleIdFlux(int $idFlux)
|
||||||
|
{
|
||||||
|
$gwArticle = new ArticleGateway(new Connection('mysql:host=londres.uca.local;dbname=dbrorossetto','rorossetto','tpphp'));
|
||||||
|
$gwArticle->removeAllArticleFromFlux($idFlux);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace model;
|
||||||
|
|
||||||
|
use DAL\Connection;
|
||||||
|
use DAL\FluxGateway;
|
||||||
|
use metier\Flux;
|
||||||
|
|
||||||
|
class FluxModel
|
||||||
|
{
|
||||||
|
public function findAllFlux(){
|
||||||
|
$gateway = new FluxGateway(new Connection('mysql:host=londres.uca.local;dbname=dbrorossetto','rorossetto','tpphp'));
|
||||||
|
$data = array();
|
||||||
|
$result = $gateway->findAllFlux();
|
||||||
|
|
||||||
|
foreach ($result as $row){
|
||||||
|
$data[] = new Flux((int)$row['id'],$row['flux']);
|
||||||
|
}
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addFlux(Flux $flux){
|
||||||
|
$gateway = new FluxGateway(new Connection('mysql:host=londres.uca.local;dbname=dbrorossetto','rorossetto','tpphp'));
|
||||||
|
$data = $this->findFlux($flux);
|
||||||
|
if ($data == array()) {
|
||||||
|
$gateway->addFlux($flux);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addFluxBySrc(string $flux): Flux {
|
||||||
|
$gateway = new FluxGateway(new Connection('mysql:host=londres.uca.local;dbname=dbrorossetto','rorossetto','tpphp'));
|
||||||
|
$newFlux = new Flux(null,$flux);
|
||||||
|
$gateway->addFlux($newFlux);
|
||||||
|
return $newFlux;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeFlux(Flux $flux){
|
||||||
|
$gateway = new FluxGateway(new Connection('mysql:host=londres.uca.local;dbname=dbrorossetto','rorossetto','tpphp'));
|
||||||
|
$gateway->removeFlux($flux);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeFluxById(int $id){
|
||||||
|
$gateway = new FluxGateway(new Connection('mysql:host=londres.uca.local;dbname=dbrorossetto','rorossetto','tpphp'));
|
||||||
|
$gateway->removeFluxById($id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeFluxBySrc(string $flux) {
|
||||||
|
$gateway = new FluxGateway(new Connection('mysql:host=londres.uca.local;dbname=dbrorossetto','rorossetto','tpphp'));
|
||||||
|
$gateway->removeFluxBySrc($flux);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findFlux(Flux $flux){
|
||||||
|
$gateway = new FluxGateway(new Connection('mysql:host=londres.uca.local;dbname=dbrorossetto','rorossetto','tpphp'));
|
||||||
|
$data = array();
|
||||||
|
$result = $gateway->findFlux($flux);
|
||||||
|
|
||||||
|
foreach ($result as $row){
|
||||||
|
$data[] = new Flux((int)$row['id'],$row['$flux']);
|
||||||
|
}
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findFluxBySrc(string $flux){
|
||||||
|
$gateway = new FluxGateway(new Connection('mysql:host=londres.uca.local;dbname=dbrorossetto','rorossetto','tpphp'));
|
||||||
|
$data = array();
|
||||||
|
$result = $gateway->findFluxBySrc($flux);
|
||||||
|
|
||||||
|
foreach ($result as $row){
|
||||||
|
$data[] = new Flux((int)$row['id'],$row['$flux']);
|
||||||
|
}
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,116 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace model;
|
||||||
|
|
||||||
|
use DAL\ArticleGateway;
|
||||||
|
use DAL\Connection;
|
||||||
|
use DAL\FluxGateway;
|
||||||
|
use DateTime;
|
||||||
|
use DOMDocument;
|
||||||
|
use Exception;
|
||||||
|
use metier\Article;
|
||||||
|
use metier\Flux;
|
||||||
|
use Twig\Error\Error;
|
||||||
|
|
||||||
|
class Parser
|
||||||
|
{
|
||||||
|
private FluxGateway $fluxGateway;
|
||||||
|
private ArticleGateway $articleGateway;
|
||||||
|
|
||||||
|
public function __construct(FluxGateway $fluxGateway, ArticleGateway $articleGateway){
|
||||||
|
$this->fluxGateway = $fluxGateway;
|
||||||
|
$this->articleGateway = $articleGateway;
|
||||||
|
}
|
||||||
|
public function parseArticles(Flux $flux): array
|
||||||
|
{
|
||||||
|
$dom = new DOMDocument();
|
||||||
|
$tabArticle = array();
|
||||||
|
try {
|
||||||
|
if ($dom->load($flux->getFlux())) {
|
||||||
|
var_dump($flux);
|
||||||
|
$items = $dom->getElementsByTagName('item');
|
||||||
|
foreach ($items as $item) {
|
||||||
|
$title = $item->getElementsByTagName('title')[0]->nodeValue;
|
||||||
|
$date = $item->getElementsByTagName('pubDate')[0]->nodeValue;
|
||||||
|
$guid = $item->getElementsByTagName('guid')[0]->nodeValue;
|
||||||
|
$link = $item->getElementsByTagName('link')[0]->nodeValue;
|
||||||
|
$description = $item->getElementsByTagName('description')[0]->nodeValue;
|
||||||
|
$mediaUrl = null;
|
||||||
|
$mediaElements = $item->getElementsByTagNameNS('http://search.yahoo.com/mrss/', 'content');
|
||||||
|
|
||||||
|
// Vérifier si un élément media:content existe
|
||||||
|
if ($mediaElements->length > 0) {
|
||||||
|
$media = $mediaElements->item(0);
|
||||||
|
$mediaUrl = $media->getAttribute('url');
|
||||||
|
}
|
||||||
|
|
||||||
|
var_dump($mediaUrl);
|
||||||
|
|
||||||
|
$dateTime = new DateTime($date);
|
||||||
|
$tabArticle[] = new Article(
|
||||||
|
(int)null,
|
||||||
|
$title,
|
||||||
|
$dateTime->format('d/m/y H:i') . '',
|
||||||
|
$description,
|
||||||
|
$guid,
|
||||||
|
$link,
|
||||||
|
($mediaUrl !== null) ? (string)$mediaUrl : '',
|
||||||
|
$flux->getId());
|
||||||
|
}
|
||||||
|
return $tabArticle;
|
||||||
|
} else {
|
||||||
|
// En cas d'erreur lors du chargement du flux RSS, lever une exception
|
||||||
|
throw new Exception("Erreur lors du chargement du flux RSS");
|
||||||
|
}
|
||||||
|
}catch (Error $e){
|
||||||
|
echo $e->getMessage();
|
||||||
|
return $tabArticle;
|
||||||
|
}catch (Exception $e2){
|
||||||
|
echo $e2->getMessage();
|
||||||
|
return $tabArticle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function parseAll($fluxes){
|
||||||
|
$tabArticles = [];
|
||||||
|
foreach ($fluxes as $flux){
|
||||||
|
$fluxx = new Flux($flux[0],$flux[1]);
|
||||||
|
$tabArticles[] = $this->parseArticles($fluxx);
|
||||||
|
|
||||||
|
}
|
||||||
|
return $tabArticles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function addAllArticles()
|
||||||
|
{
|
||||||
|
$tabFluxes = [];
|
||||||
|
$this->articleGateway->removeAllArticleForParser();
|
||||||
|
|
||||||
|
$allItemFlux = $this->fluxGateway->findAllFlux();
|
||||||
|
foreach ($allItemFlux as $ItemFlux){
|
||||||
|
$tabFluxes[] = new Flux(intval($ItemFlux['id']), $ItemFlux['flux']);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($tabFluxes as $flux) {
|
||||||
|
$tabArticle = $this->parseArticles($flux);
|
||||||
|
foreach ($tabArticle as $item) {
|
||||||
|
$this->articleGateway->addArticle($item);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="refresh" content="5">
|
||||||
|
<title>Server</title>
|
||||||
|
<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="testContent">
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
// Fonction pour charger dynamiquement le contenu de test.php
|
||||||
|
function loadTestContent() {
|
||||||
|
$.ajax({
|
||||||
|
url: 'test.php', // Chemin vers test.php
|
||||||
|
type: 'GET',
|
||||||
|
success: function(response) {
|
||||||
|
$('#testContent').html(response); // Mettre à jour le contenu
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
console.error('Erreur lors du chargement de test.php');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Appeler la fonction pour charger le contenu au chargement initial
|
||||||
|
loadTestContent();
|
||||||
|
|
||||||
|
// Actualiser la page toutes les 5 secondes
|
||||||
|
setInterval(loadTestContent, 5000);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
namespace test;
|
||||||
|
use DAL\ArticleGateway;
|
||||||
|
use DAL\Connection;
|
||||||
|
use DAL\FluxGateway;
|
||||||
|
use model\Parser;
|
||||||
|
|
||||||
|
require '../../vendor/autoload.php';
|
||||||
|
|
||||||
|
$gwArt = new ArticleGateway(new Connection('mysql:host=londres.uca.local;dbname=dbrorossetto', 'rorossetto', 'tpphp'));
|
||||||
|
$gwFl = new FluxGateway(new Connection('mysql:host=londres.uca.local;dbname=dbrorossetto', 'rorossetto', 'tpphp'));
|
||||||
|
$pars = new Parser( $gwFl,$gwArt);
|
||||||
|
$pars->addAllArticles();
|
||||||
|
var_dump($pars);
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,597 @@
|
|||||||
|
/*!
|
||||||
|
* Bootstrap Reboot v5.3.2 (https://getbootstrap.com/)
|
||||||
|
* Copyright 2011-2023 The Bootstrap Authors
|
||||||
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||||
|
*/
|
||||||
|
:root,
|
||||||
|
[data-bs-theme=light] {
|
||||||
|
--bs-blue: #0d6efd;
|
||||||
|
--bs-indigo: #6610f2;
|
||||||
|
--bs-purple: #6f42c1;
|
||||||
|
--bs-pink: #d63384;
|
||||||
|
--bs-red: #dc3545;
|
||||||
|
--bs-orange: #fd7e14;
|
||||||
|
--bs-yellow: #ffc107;
|
||||||
|
--bs-green: #198754;
|
||||||
|
--bs-teal: #20c997;
|
||||||
|
--bs-cyan: #0dcaf0;
|
||||||
|
--bs-black: #000;
|
||||||
|
--bs-white: #fff;
|
||||||
|
--bs-gray: #6c757d;
|
||||||
|
--bs-gray-dark: #343a40;
|
||||||
|
--bs-gray-100: #f8f9fa;
|
||||||
|
--bs-gray-200: #e9ecef;
|
||||||
|
--bs-gray-300: #dee2e6;
|
||||||
|
--bs-gray-400: #ced4da;
|
||||||
|
--bs-gray-500: #adb5bd;
|
||||||
|
--bs-gray-600: #6c757d;
|
||||||
|
--bs-gray-700: #495057;
|
||||||
|
--bs-gray-800: #343a40;
|
||||||
|
--bs-gray-900: #212529;
|
||||||
|
--bs-primary: #0d6efd;
|
||||||
|
--bs-secondary: #6c757d;
|
||||||
|
--bs-success: #198754;
|
||||||
|
--bs-info: #0dcaf0;
|
||||||
|
--bs-warning: #ffc107;
|
||||||
|
--bs-danger: #dc3545;
|
||||||
|
--bs-light: #f8f9fa;
|
||||||
|
--bs-dark: #212529;
|
||||||
|
--bs-primary-rgb: 13, 110, 253;
|
||||||
|
--bs-secondary-rgb: 108, 117, 125;
|
||||||
|
--bs-success-rgb: 25, 135, 84;
|
||||||
|
--bs-info-rgb: 13, 202, 240;
|
||||||
|
--bs-warning-rgb: 255, 193, 7;
|
||||||
|
--bs-danger-rgb: 220, 53, 69;
|
||||||
|
--bs-light-rgb: 248, 249, 250;
|
||||||
|
--bs-dark-rgb: 33, 37, 41;
|
||||||
|
--bs-primary-text-emphasis: #052c65;
|
||||||
|
--bs-secondary-text-emphasis: #2b2f32;
|
||||||
|
--bs-success-text-emphasis: #0a3622;
|
||||||
|
--bs-info-text-emphasis: #055160;
|
||||||
|
--bs-warning-text-emphasis: #664d03;
|
||||||
|
--bs-danger-text-emphasis: #58151c;
|
||||||
|
--bs-light-text-emphasis: #495057;
|
||||||
|
--bs-dark-text-emphasis: #495057;
|
||||||
|
--bs-primary-bg-subtle: #cfe2ff;
|
||||||
|
--bs-secondary-bg-subtle: #e2e3e5;
|
||||||
|
--bs-success-bg-subtle: #d1e7dd;
|
||||||
|
--bs-info-bg-subtle: #cff4fc;
|
||||||
|
--bs-warning-bg-subtle: #fff3cd;
|
||||||
|
--bs-danger-bg-subtle: #f8d7da;
|
||||||
|
--bs-light-bg-subtle: #fcfcfd;
|
||||||
|
--bs-dark-bg-subtle: #ced4da;
|
||||||
|
--bs-primary-border-subtle: #9ec5fe;
|
||||||
|
--bs-secondary-border-subtle: #c4c8cb;
|
||||||
|
--bs-success-border-subtle: #a3cfbb;
|
||||||
|
--bs-info-border-subtle: #9eeaf9;
|
||||||
|
--bs-warning-border-subtle: #ffe69c;
|
||||||
|
--bs-danger-border-subtle: #f1aeb5;
|
||||||
|
--bs-light-border-subtle: #e9ecef;
|
||||||
|
--bs-dark-border-subtle: #adb5bd;
|
||||||
|
--bs-white-rgb: 255, 255, 255;
|
||||||
|
--bs-black-rgb: 0, 0, 0;
|
||||||
|
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||||
|
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||||
|
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
|
||||||
|
--bs-body-font-family: var(--bs-font-sans-serif);
|
||||||
|
--bs-body-font-size: 1rem;
|
||||||
|
--bs-body-font-weight: 400;
|
||||||
|
--bs-body-line-height: 1.5;
|
||||||
|
--bs-body-color: #212529;
|
||||||
|
--bs-body-color-rgb: 33, 37, 41;
|
||||||
|
--bs-body-bg: #fff;
|
||||||
|
--bs-body-bg-rgb: 255, 255, 255;
|
||||||
|
--bs-emphasis-color: #000;
|
||||||
|
--bs-emphasis-color-rgb: 0, 0, 0;
|
||||||
|
--bs-secondary-color: rgba(33, 37, 41, 0.75);
|
||||||
|
--bs-secondary-color-rgb: 33, 37, 41;
|
||||||
|
--bs-secondary-bg: #e9ecef;
|
||||||
|
--bs-secondary-bg-rgb: 233, 236, 239;
|
||||||
|
--bs-tertiary-color: rgba(33, 37, 41, 0.5);
|
||||||
|
--bs-tertiary-color-rgb: 33, 37, 41;
|
||||||
|
--bs-tertiary-bg: #f8f9fa;
|
||||||
|
--bs-tertiary-bg-rgb: 248, 249, 250;
|
||||||
|
--bs-heading-color: inherit;
|
||||||
|
--bs-link-color: #0d6efd;
|
||||||
|
--bs-link-color-rgb: 13, 110, 253;
|
||||||
|
--bs-link-decoration: underline;
|
||||||
|
--bs-link-hover-color: #0a58ca;
|
||||||
|
--bs-link-hover-color-rgb: 10, 88, 202;
|
||||||
|
--bs-code-color: #d63384;
|
||||||
|
--bs-highlight-color: #212529;
|
||||||
|
--bs-highlight-bg: #fff3cd;
|
||||||
|
--bs-border-width: 1px;
|
||||||
|
--bs-border-style: solid;
|
||||||
|
--bs-border-color: #dee2e6;
|
||||||
|
--bs-border-color-translucent: rgba(0, 0, 0, 0.175);
|
||||||
|
--bs-border-radius: 0.375rem;
|
||||||
|
--bs-border-radius-sm: 0.25rem;
|
||||||
|
--bs-border-radius-lg: 0.5rem;
|
||||||
|
--bs-border-radius-xl: 1rem;
|
||||||
|
--bs-border-radius-xxl: 2rem;
|
||||||
|
--bs-border-radius-2xl: var(--bs-border-radius-xxl);
|
||||||
|
--bs-border-radius-pill: 50rem;
|
||||||
|
--bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
||||||
|
--bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
||||||
|
--bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175);
|
||||||
|
--bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075);
|
||||||
|
--bs-focus-ring-width: 0.25rem;
|
||||||
|
--bs-focus-ring-opacity: 0.25;
|
||||||
|
--bs-focus-ring-color: rgba(13, 110, 253, 0.25);
|
||||||
|
--bs-form-valid-color: #198754;
|
||||||
|
--bs-form-valid-border-color: #198754;
|
||||||
|
--bs-form-invalid-color: #dc3545;
|
||||||
|
--bs-form-invalid-border-color: #dc3545;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-bs-theme=dark] {
|
||||||
|
color-scheme: dark;
|
||||||
|
--bs-body-color: #dee2e6;
|
||||||
|
--bs-body-color-rgb: 222, 226, 230;
|
||||||
|
--bs-body-bg: #212529;
|
||||||
|
--bs-body-bg-rgb: 33, 37, 41;
|
||||||
|
--bs-emphasis-color: #fff;
|
||||||
|
--bs-emphasis-color-rgb: 255, 255, 255;
|
||||||
|
--bs-secondary-color: rgba(222, 226, 230, 0.75);
|
||||||
|
--bs-secondary-color-rgb: 222, 226, 230;
|
||||||
|
--bs-secondary-bg: #343a40;
|
||||||
|
--bs-secondary-bg-rgb: 52, 58, 64;
|
||||||
|
--bs-tertiary-color: rgba(222, 226, 230, 0.5);
|
||||||
|
--bs-tertiary-color-rgb: 222, 226, 230;
|
||||||
|
--bs-tertiary-bg: #2b3035;
|
||||||
|
--bs-tertiary-bg-rgb: 43, 48, 53;
|
||||||
|
--bs-primary-text-emphasis: #6ea8fe;
|
||||||
|
--bs-secondary-text-emphasis: #a7acb1;
|
||||||
|
--bs-success-text-emphasis: #75b798;
|
||||||
|
--bs-info-text-emphasis: #6edff6;
|
||||||
|
--bs-warning-text-emphasis: #ffda6a;
|
||||||
|
--bs-danger-text-emphasis: #ea868f;
|
||||||
|
--bs-light-text-emphasis: #f8f9fa;
|
||||||
|
--bs-dark-text-emphasis: #dee2e6;
|
||||||
|
--bs-primary-bg-subtle: #031633;
|
||||||
|
--bs-secondary-bg-subtle: #161719;
|
||||||
|
--bs-success-bg-subtle: #051b11;
|
||||||
|
--bs-info-bg-subtle: #032830;
|
||||||
|
--bs-warning-bg-subtle: #332701;
|
||||||
|
--bs-danger-bg-subtle: #2c0b0e;
|
||||||
|
--bs-light-bg-subtle: #343a40;
|
||||||
|
--bs-dark-bg-subtle: #1a1d20;
|
||||||
|
--bs-primary-border-subtle: #084298;
|
||||||
|
--bs-secondary-border-subtle: #41464b;
|
||||||
|
--bs-success-border-subtle: #0f5132;
|
||||||
|
--bs-info-border-subtle: #087990;
|
||||||
|
--bs-warning-border-subtle: #997404;
|
||||||
|
--bs-danger-border-subtle: #842029;
|
||||||
|
--bs-light-border-subtle: #495057;
|
||||||
|
--bs-dark-border-subtle: #343a40;
|
||||||
|
--bs-heading-color: inherit;
|
||||||
|
--bs-link-color: #6ea8fe;
|
||||||
|
--bs-link-hover-color: #8bb9fe;
|
||||||
|
--bs-link-color-rgb: 110, 168, 254;
|
||||||
|
--bs-link-hover-color-rgb: 139, 185, 254;
|
||||||
|
--bs-code-color: #e685b5;
|
||||||
|
--bs-highlight-color: #dee2e6;
|
||||||
|
--bs-highlight-bg: #664d03;
|
||||||
|
--bs-border-color: #495057;
|
||||||
|
--bs-border-color-translucent: rgba(255, 255, 255, 0.15);
|
||||||
|
--bs-form-valid-color: #75b798;
|
||||||
|
--bs-form-valid-border-color: #75b798;
|
||||||
|
--bs-form-invalid-color: #ea868f;
|
||||||
|
--bs-form-invalid-border-color: #ea868f;
|
||||||
|
}
|
||||||
|
|
||||||
|
*,
|
||||||
|
*::before,
|
||||||
|
*::after {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: no-preference) {
|
||||||
|
:root {
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
font-family: var(--bs-body-font-family);
|
||||||
|
font-size: var(--bs-body-font-size);
|
||||||
|
font-weight: var(--bs-body-font-weight);
|
||||||
|
line-height: var(--bs-body-line-height);
|
||||||
|
color: var(--bs-body-color);
|
||||||
|
text-align: var(--bs-body-text-align);
|
||||||
|
background-color: var(--bs-body-bg);
|
||||||
|
-webkit-text-size-adjust: 100%;
|
||||||
|
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
margin: 1rem 0;
|
||||||
|
color: inherit;
|
||||||
|
border: 0;
|
||||||
|
border-top: var(--bs-border-width) solid;
|
||||||
|
opacity: 0.25;
|
||||||
|
}
|
||||||
|
|
||||||
|
h6, h5, h4, h3, h2, h1 {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 1.2;
|
||||||
|
color: var(--bs-heading-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: calc(1.375rem + 1.5vw);
|
||||||
|
}
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
h1 {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: calc(1.325rem + 0.9vw);
|
||||||
|
}
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
h2 {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: calc(1.3rem + 0.6vw);
|
||||||
|
}
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
h3 {
|
||||||
|
font-size: 1.75rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size: calc(1.275rem + 0.3vw);
|
||||||
|
}
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
h4 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h5 {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h6 {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
abbr[title] {
|
||||||
|
-webkit-text-decoration: underline dotted;
|
||||||
|
text-decoration: underline dotted;
|
||||||
|
cursor: help;
|
||||||
|
-webkit-text-decoration-skip-ink: none;
|
||||||
|
text-decoration-skip-ink: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
address {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
font-style: normal;
|
||||||
|
line-height: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol,
|
||||||
|
ul {
|
||||||
|
padding-left: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol,
|
||||||
|
ul,
|
||||||
|
dl {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol ol,
|
||||||
|
ul ul,
|
||||||
|
ol ul,
|
||||||
|
ul ol {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dt {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
dd {
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
margin: 0 0 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
b,
|
||||||
|
strong {
|
||||||
|
font-weight: bolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
small {
|
||||||
|
font-size: 0.875em;
|
||||||
|
}
|
||||||
|
|
||||||
|
mark {
|
||||||
|
padding: 0.1875em;
|
||||||
|
color: var(--bs-highlight-color);
|
||||||
|
background-color: var(--bs-highlight-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub,
|
||||||
|
sup {
|
||||||
|
position: relative;
|
||||||
|
font-size: 0.75em;
|
||||||
|
line-height: 0;
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub {
|
||||||
|
bottom: -0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
sup {
|
||||||
|
top: -0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
--bs-link-color-rgb: var(--bs-link-hover-color-rgb);
|
||||||
|
}
|
||||||
|
|
||||||
|
a:not([href]):not([class]), a:not([href]):not([class]):hover {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre,
|
||||||
|
code,
|
||||||
|
kbd,
|
||||||
|
samp {
|
||||||
|
font-family: var(--bs-font-monospace);
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
display: block;
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
overflow: auto;
|
||||||
|
font-size: 0.875em;
|
||||||
|
}
|
||||||
|
pre code {
|
||||||
|
font-size: inherit;
|
||||||
|
color: inherit;
|
||||||
|
word-break: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
font-size: 0.875em;
|
||||||
|
color: var(--bs-code-color);
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
a > code {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
kbd {
|
||||||
|
padding: 0.1875rem 0.375rem;
|
||||||
|
font-size: 0.875em;
|
||||||
|
color: var(--bs-body-bg);
|
||||||
|
background-color: var(--bs-body-color);
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
}
|
||||||
|
kbd kbd {
|
||||||
|
padding: 0;
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
figure {
|
||||||
|
margin: 0 0 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
img,
|
||||||
|
svg {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
caption-side: bottom;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
caption {
|
||||||
|
padding-top: 0.5rem;
|
||||||
|
padding-bottom: 0.5rem;
|
||||||
|
color: var(--bs-secondary-color);
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
text-align: inherit;
|
||||||
|
text-align: -webkit-match-parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
thead,
|
||||||
|
tbody,
|
||||||
|
tfoot,
|
||||||
|
tr,
|
||||||
|
td,
|
||||||
|
th {
|
||||||
|
border-color: inherit;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:focus:not(:focus-visible) {
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
input,
|
||||||
|
button,
|
||||||
|
select,
|
||||||
|
optgroup,
|
||||||
|
textarea {
|
||||||
|
margin: 0;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: inherit;
|
||||||
|
line-height: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
button,
|
||||||
|
select {
|
||||||
|
text-transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
[role=button] {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
word-wrap: normal;
|
||||||
|
}
|
||||||
|
select:disabled {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
button,
|
||||||
|
[type=button],
|
||||||
|
[type=reset],
|
||||||
|
[type=submit] {
|
||||||
|
-webkit-appearance: button;
|
||||||
|
}
|
||||||
|
button:not(:disabled),
|
||||||
|
[type=button]:not(:disabled),
|
||||||
|
[type=reset]:not(:disabled),
|
||||||
|
[type=submit]:not(:disabled) {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-moz-focus-inner {
|
||||||
|
padding: 0;
|
||||||
|
border-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
resize: vertical;
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldset {
|
||||||
|
min-width: 0;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
legend {
|
||||||
|
float: left;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
font-size: calc(1.275rem + 0.3vw);
|
||||||
|
line-height: inherit;
|
||||||
|
}
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
legend {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
legend + * {
|
||||||
|
clear: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-datetime-edit-fields-wrapper,
|
||||||
|
::-webkit-datetime-edit-text,
|
||||||
|
::-webkit-datetime-edit-minute,
|
||||||
|
::-webkit-datetime-edit-hour-field,
|
||||||
|
::-webkit-datetime-edit-day-field,
|
||||||
|
::-webkit-datetime-edit-month-field,
|
||||||
|
::-webkit-datetime-edit-year-field {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-inner-spin-button {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
[type=search] {
|
||||||
|
-webkit-appearance: textfield;
|
||||||
|
outline-offset: -2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* rtl:raw:
|
||||||
|
[type="tel"],
|
||||||
|
[type="url"],
|
||||||
|
[type="email"],
|
||||||
|
[type="number"] {
|
||||||
|
direction: ltr;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
::-webkit-search-decoration {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-color-swatch-wrapper {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-file-upload-button {
|
||||||
|
font: inherit;
|
||||||
|
-webkit-appearance: button;
|
||||||
|
}
|
||||||
|
|
||||||
|
::file-selector-button {
|
||||||
|
font: inherit;
|
||||||
|
-webkit-appearance: button;
|
||||||
|
}
|
||||||
|
|
||||||
|
output {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
iframe {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
summary {
|
||||||
|
display: list-item;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
progress {
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
[hidden] {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*# sourceMappingURL=bootstrap-reboot.css.map */
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,594 @@
|
|||||||
|
/*!
|
||||||
|
* Bootstrap Reboot v5.3.2 (https://getbootstrap.com/)
|
||||||
|
* Copyright 2011-2023 The Bootstrap Authors
|
||||||
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||||
|
*/
|
||||||
|
:root,
|
||||||
|
[data-bs-theme=light] {
|
||||||
|
--bs-blue: #0d6efd;
|
||||||
|
--bs-indigo: #6610f2;
|
||||||
|
--bs-purple: #6f42c1;
|
||||||
|
--bs-pink: #d63384;
|
||||||
|
--bs-red: #dc3545;
|
||||||
|
--bs-orange: #fd7e14;
|
||||||
|
--bs-yellow: #ffc107;
|
||||||
|
--bs-green: #198754;
|
||||||
|
--bs-teal: #20c997;
|
||||||
|
--bs-cyan: #0dcaf0;
|
||||||
|
--bs-black: #000;
|
||||||
|
--bs-white: #fff;
|
||||||
|
--bs-gray: #6c757d;
|
||||||
|
--bs-gray-dark: #343a40;
|
||||||
|
--bs-gray-100: #f8f9fa;
|
||||||
|
--bs-gray-200: #e9ecef;
|
||||||
|
--bs-gray-300: #dee2e6;
|
||||||
|
--bs-gray-400: #ced4da;
|
||||||
|
--bs-gray-500: #adb5bd;
|
||||||
|
--bs-gray-600: #6c757d;
|
||||||
|
--bs-gray-700: #495057;
|
||||||
|
--bs-gray-800: #343a40;
|
||||||
|
--bs-gray-900: #212529;
|
||||||
|
--bs-primary: #0d6efd;
|
||||||
|
--bs-secondary: #6c757d;
|
||||||
|
--bs-success: #198754;
|
||||||
|
--bs-info: #0dcaf0;
|
||||||
|
--bs-warning: #ffc107;
|
||||||
|
--bs-danger: #dc3545;
|
||||||
|
--bs-light: #f8f9fa;
|
||||||
|
--bs-dark: #212529;
|
||||||
|
--bs-primary-rgb: 13, 110, 253;
|
||||||
|
--bs-secondary-rgb: 108, 117, 125;
|
||||||
|
--bs-success-rgb: 25, 135, 84;
|
||||||
|
--bs-info-rgb: 13, 202, 240;
|
||||||
|
--bs-warning-rgb: 255, 193, 7;
|
||||||
|
--bs-danger-rgb: 220, 53, 69;
|
||||||
|
--bs-light-rgb: 248, 249, 250;
|
||||||
|
--bs-dark-rgb: 33, 37, 41;
|
||||||
|
--bs-primary-text-emphasis: #052c65;
|
||||||
|
--bs-secondary-text-emphasis: #2b2f32;
|
||||||
|
--bs-success-text-emphasis: #0a3622;
|
||||||
|
--bs-info-text-emphasis: #055160;
|
||||||
|
--bs-warning-text-emphasis: #664d03;
|
||||||
|
--bs-danger-text-emphasis: #58151c;
|
||||||
|
--bs-light-text-emphasis: #495057;
|
||||||
|
--bs-dark-text-emphasis: #495057;
|
||||||
|
--bs-primary-bg-subtle: #cfe2ff;
|
||||||
|
--bs-secondary-bg-subtle: #e2e3e5;
|
||||||
|
--bs-success-bg-subtle: #d1e7dd;
|
||||||
|
--bs-info-bg-subtle: #cff4fc;
|
||||||
|
--bs-warning-bg-subtle: #fff3cd;
|
||||||
|
--bs-danger-bg-subtle: #f8d7da;
|
||||||
|
--bs-light-bg-subtle: #fcfcfd;
|
||||||
|
--bs-dark-bg-subtle: #ced4da;
|
||||||
|
--bs-primary-border-subtle: #9ec5fe;
|
||||||
|
--bs-secondary-border-subtle: #c4c8cb;
|
||||||
|
--bs-success-border-subtle: #a3cfbb;
|
||||||
|
--bs-info-border-subtle: #9eeaf9;
|
||||||
|
--bs-warning-border-subtle: #ffe69c;
|
||||||
|
--bs-danger-border-subtle: #f1aeb5;
|
||||||
|
--bs-light-border-subtle: #e9ecef;
|
||||||
|
--bs-dark-border-subtle: #adb5bd;
|
||||||
|
--bs-white-rgb: 255, 255, 255;
|
||||||
|
--bs-black-rgb: 0, 0, 0;
|
||||||
|
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||||
|
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||||
|
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
|
||||||
|
--bs-body-font-family: var(--bs-font-sans-serif);
|
||||||
|
--bs-body-font-size: 1rem;
|
||||||
|
--bs-body-font-weight: 400;
|
||||||
|
--bs-body-line-height: 1.5;
|
||||||
|
--bs-body-color: #212529;
|
||||||
|
--bs-body-color-rgb: 33, 37, 41;
|
||||||
|
--bs-body-bg: #fff;
|
||||||
|
--bs-body-bg-rgb: 255, 255, 255;
|
||||||
|
--bs-emphasis-color: #000;
|
||||||
|
--bs-emphasis-color-rgb: 0, 0, 0;
|
||||||
|
--bs-secondary-color: rgba(33, 37, 41, 0.75);
|
||||||
|
--bs-secondary-color-rgb: 33, 37, 41;
|
||||||
|
--bs-secondary-bg: #e9ecef;
|
||||||
|
--bs-secondary-bg-rgb: 233, 236, 239;
|
||||||
|
--bs-tertiary-color: rgba(33, 37, 41, 0.5);
|
||||||
|
--bs-tertiary-color-rgb: 33, 37, 41;
|
||||||
|
--bs-tertiary-bg: #f8f9fa;
|
||||||
|
--bs-tertiary-bg-rgb: 248, 249, 250;
|
||||||
|
--bs-heading-color: inherit;
|
||||||
|
--bs-link-color: #0d6efd;
|
||||||
|
--bs-link-color-rgb: 13, 110, 253;
|
||||||
|
--bs-link-decoration: underline;
|
||||||
|
--bs-link-hover-color: #0a58ca;
|
||||||
|
--bs-link-hover-color-rgb: 10, 88, 202;
|
||||||
|
--bs-code-color: #d63384;
|
||||||
|
--bs-highlight-color: #212529;
|
||||||
|
--bs-highlight-bg: #fff3cd;
|
||||||
|
--bs-border-width: 1px;
|
||||||
|
--bs-border-style: solid;
|
||||||
|
--bs-border-color: #dee2e6;
|
||||||
|
--bs-border-color-translucent: rgba(0, 0, 0, 0.175);
|
||||||
|
--bs-border-radius: 0.375rem;
|
||||||
|
--bs-border-radius-sm: 0.25rem;
|
||||||
|
--bs-border-radius-lg: 0.5rem;
|
||||||
|
--bs-border-radius-xl: 1rem;
|
||||||
|
--bs-border-radius-xxl: 2rem;
|
||||||
|
--bs-border-radius-2xl: var(--bs-border-radius-xxl);
|
||||||
|
--bs-border-radius-pill: 50rem;
|
||||||
|
--bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
||||||
|
--bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
||||||
|
--bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175);
|
||||||
|
--bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075);
|
||||||
|
--bs-focus-ring-width: 0.25rem;
|
||||||
|
--bs-focus-ring-opacity: 0.25;
|
||||||
|
--bs-focus-ring-color: rgba(13, 110, 253, 0.25);
|
||||||
|
--bs-form-valid-color: #198754;
|
||||||
|
--bs-form-valid-border-color: #198754;
|
||||||
|
--bs-form-invalid-color: #dc3545;
|
||||||
|
--bs-form-invalid-border-color: #dc3545;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-bs-theme=dark] {
|
||||||
|
color-scheme: dark;
|
||||||
|
--bs-body-color: #dee2e6;
|
||||||
|
--bs-body-color-rgb: 222, 226, 230;
|
||||||
|
--bs-body-bg: #212529;
|
||||||
|
--bs-body-bg-rgb: 33, 37, 41;
|
||||||
|
--bs-emphasis-color: #fff;
|
||||||
|
--bs-emphasis-color-rgb: 255, 255, 255;
|
||||||
|
--bs-secondary-color: rgba(222, 226, 230, 0.75);
|
||||||
|
--bs-secondary-color-rgb: 222, 226, 230;
|
||||||
|
--bs-secondary-bg: #343a40;
|
||||||
|
--bs-secondary-bg-rgb: 52, 58, 64;
|
||||||
|
--bs-tertiary-color: rgba(222, 226, 230, 0.5);
|
||||||
|
--bs-tertiary-color-rgb: 222, 226, 230;
|
||||||
|
--bs-tertiary-bg: #2b3035;
|
||||||
|
--bs-tertiary-bg-rgb: 43, 48, 53;
|
||||||
|
--bs-primary-text-emphasis: #6ea8fe;
|
||||||
|
--bs-secondary-text-emphasis: #a7acb1;
|
||||||
|
--bs-success-text-emphasis: #75b798;
|
||||||
|
--bs-info-text-emphasis: #6edff6;
|
||||||
|
--bs-warning-text-emphasis: #ffda6a;
|
||||||
|
--bs-danger-text-emphasis: #ea868f;
|
||||||
|
--bs-light-text-emphasis: #f8f9fa;
|
||||||
|
--bs-dark-text-emphasis: #dee2e6;
|
||||||
|
--bs-primary-bg-subtle: #031633;
|
||||||
|
--bs-secondary-bg-subtle: #161719;
|
||||||
|
--bs-success-bg-subtle: #051b11;
|
||||||
|
--bs-info-bg-subtle: #032830;
|
||||||
|
--bs-warning-bg-subtle: #332701;
|
||||||
|
--bs-danger-bg-subtle: #2c0b0e;
|
||||||
|
--bs-light-bg-subtle: #343a40;
|
||||||
|
--bs-dark-bg-subtle: #1a1d20;
|
||||||
|
--bs-primary-border-subtle: #084298;
|
||||||
|
--bs-secondary-border-subtle: #41464b;
|
||||||
|
--bs-success-border-subtle: #0f5132;
|
||||||
|
--bs-info-border-subtle: #087990;
|
||||||
|
--bs-warning-border-subtle: #997404;
|
||||||
|
--bs-danger-border-subtle: #842029;
|
||||||
|
--bs-light-border-subtle: #495057;
|
||||||
|
--bs-dark-border-subtle: #343a40;
|
||||||
|
--bs-heading-color: inherit;
|
||||||
|
--bs-link-color: #6ea8fe;
|
||||||
|
--bs-link-hover-color: #8bb9fe;
|
||||||
|
--bs-link-color-rgb: 110, 168, 254;
|
||||||
|
--bs-link-hover-color-rgb: 139, 185, 254;
|
||||||
|
--bs-code-color: #e685b5;
|
||||||
|
--bs-highlight-color: #dee2e6;
|
||||||
|
--bs-highlight-bg: #664d03;
|
||||||
|
--bs-border-color: #495057;
|
||||||
|
--bs-border-color-translucent: rgba(255, 255, 255, 0.15);
|
||||||
|
--bs-form-valid-color: #75b798;
|
||||||
|
--bs-form-valid-border-color: #75b798;
|
||||||
|
--bs-form-invalid-color: #ea868f;
|
||||||
|
--bs-form-invalid-border-color: #ea868f;
|
||||||
|
}
|
||||||
|
|
||||||
|
*,
|
||||||
|
*::before,
|
||||||
|
*::after {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: no-preference) {
|
||||||
|
:root {
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
font-family: var(--bs-body-font-family);
|
||||||
|
font-size: var(--bs-body-font-size);
|
||||||
|
font-weight: var(--bs-body-font-weight);
|
||||||
|
line-height: var(--bs-body-line-height);
|
||||||
|
color: var(--bs-body-color);
|
||||||
|
text-align: var(--bs-body-text-align);
|
||||||
|
background-color: var(--bs-body-bg);
|
||||||
|
-webkit-text-size-adjust: 100%;
|
||||||
|
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
margin: 1rem 0;
|
||||||
|
color: inherit;
|
||||||
|
border: 0;
|
||||||
|
border-top: var(--bs-border-width) solid;
|
||||||
|
opacity: 0.25;
|
||||||
|
}
|
||||||
|
|
||||||
|
h6, h5, h4, h3, h2, h1 {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 1.2;
|
||||||
|
color: var(--bs-heading-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: calc(1.375rem + 1.5vw);
|
||||||
|
}
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
h1 {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: calc(1.325rem + 0.9vw);
|
||||||
|
}
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
h2 {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: calc(1.3rem + 0.6vw);
|
||||||
|
}
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
h3 {
|
||||||
|
font-size: 1.75rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size: calc(1.275rem + 0.3vw);
|
||||||
|
}
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
h4 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h5 {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h6 {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
abbr[title] {
|
||||||
|
-webkit-text-decoration: underline dotted;
|
||||||
|
text-decoration: underline dotted;
|
||||||
|
cursor: help;
|
||||||
|
-webkit-text-decoration-skip-ink: none;
|
||||||
|
text-decoration-skip-ink: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
address {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
font-style: normal;
|
||||||
|
line-height: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol,
|
||||||
|
ul {
|
||||||
|
padding-right: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol,
|
||||||
|
ul,
|
||||||
|
dl {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol ol,
|
||||||
|
ul ul,
|
||||||
|
ol ul,
|
||||||
|
ul ol {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dt {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
dd {
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
margin: 0 0 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
b,
|
||||||
|
strong {
|
||||||
|
font-weight: bolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
small {
|
||||||
|
font-size: 0.875em;
|
||||||
|
}
|
||||||
|
|
||||||
|
mark {
|
||||||
|
padding: 0.1875em;
|
||||||
|
color: var(--bs-highlight-color);
|
||||||
|
background-color: var(--bs-highlight-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub,
|
||||||
|
sup {
|
||||||
|
position: relative;
|
||||||
|
font-size: 0.75em;
|
||||||
|
line-height: 0;
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub {
|
||||||
|
bottom: -0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
sup {
|
||||||
|
top: -0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
--bs-link-color-rgb: var(--bs-link-hover-color-rgb);
|
||||||
|
}
|
||||||
|
|
||||||
|
a:not([href]):not([class]), a:not([href]):not([class]):hover {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre,
|
||||||
|
code,
|
||||||
|
kbd,
|
||||||
|
samp {
|
||||||
|
font-family: var(--bs-font-monospace);
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
display: block;
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
overflow: auto;
|
||||||
|
font-size: 0.875em;
|
||||||
|
}
|
||||||
|
pre code {
|
||||||
|
font-size: inherit;
|
||||||
|
color: inherit;
|
||||||
|
word-break: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
font-size: 0.875em;
|
||||||
|
color: var(--bs-code-color);
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
a > code {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
kbd {
|
||||||
|
padding: 0.1875rem 0.375rem;
|
||||||
|
font-size: 0.875em;
|
||||||
|
color: var(--bs-body-bg);
|
||||||
|
background-color: var(--bs-body-color);
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
}
|
||||||
|
kbd kbd {
|
||||||
|
padding: 0;
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
figure {
|
||||||
|
margin: 0 0 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
img,
|
||||||
|
svg {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
caption-side: bottom;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
caption {
|
||||||
|
padding-top: 0.5rem;
|
||||||
|
padding-bottom: 0.5rem;
|
||||||
|
color: var(--bs-secondary-color);
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
text-align: inherit;
|
||||||
|
text-align: -webkit-match-parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
thead,
|
||||||
|
tbody,
|
||||||
|
tfoot,
|
||||||
|
tr,
|
||||||
|
td,
|
||||||
|
th {
|
||||||
|
border-color: inherit;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:focus:not(:focus-visible) {
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
input,
|
||||||
|
button,
|
||||||
|
select,
|
||||||
|
optgroup,
|
||||||
|
textarea {
|
||||||
|
margin: 0;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: inherit;
|
||||||
|
line-height: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
button,
|
||||||
|
select {
|
||||||
|
text-transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
[role=button] {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
word-wrap: normal;
|
||||||
|
}
|
||||||
|
select:disabled {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
button,
|
||||||
|
[type=button],
|
||||||
|
[type=reset],
|
||||||
|
[type=submit] {
|
||||||
|
-webkit-appearance: button;
|
||||||
|
}
|
||||||
|
button:not(:disabled),
|
||||||
|
[type=button]:not(:disabled),
|
||||||
|
[type=reset]:not(:disabled),
|
||||||
|
[type=submit]:not(:disabled) {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-moz-focus-inner {
|
||||||
|
padding: 0;
|
||||||
|
border-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
resize: vertical;
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldset {
|
||||||
|
min-width: 0;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
legend {
|
||||||
|
float: right;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
font-size: calc(1.275rem + 0.3vw);
|
||||||
|
line-height: inherit;
|
||||||
|
}
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
legend {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
legend + * {
|
||||||
|
clear: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-datetime-edit-fields-wrapper,
|
||||||
|
::-webkit-datetime-edit-text,
|
||||||
|
::-webkit-datetime-edit-minute,
|
||||||
|
::-webkit-datetime-edit-hour-field,
|
||||||
|
::-webkit-datetime-edit-day-field,
|
||||||
|
::-webkit-datetime-edit-month-field,
|
||||||
|
::-webkit-datetime-edit-year-field {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-inner-spin-button {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
[type=search] {
|
||||||
|
-webkit-appearance: textfield;
|
||||||
|
outline-offset: -2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
[type="tel"],
|
||||||
|
[type="url"],
|
||||||
|
[type="email"],
|
||||||
|
[type="number"] {
|
||||||
|
direction: ltr;
|
||||||
|
}
|
||||||
|
::-webkit-search-decoration {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-color-swatch-wrapper {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-file-upload-button {
|
||||||
|
font: inherit;
|
||||||
|
-webkit-appearance: button;
|
||||||
|
}
|
||||||
|
|
||||||
|
::file-selector-button {
|
||||||
|
font: inherit;
|
||||||
|
-webkit-appearance: button;
|
||||||
|
}
|
||||||
|
|
||||||
|
output {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
iframe {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
summary {
|
||||||
|
display: list-item;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
progress {
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
[hidden] {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
/*# sourceMappingURL=bootstrap-reboot.rtl.css.map */
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,27 @@
|
|||||||
|
@charset "UTF-8";
|
||||||
|
.myBody{
|
||||||
|
background-color: rgba(255,187,248,0.50);
|
||||||
|
}
|
||||||
|
.imgArticle{
|
||||||
|
width: 15em;
|
||||||
|
margin: 1em;
|
||||||
|
}
|
||||||
|
.enTitre{
|
||||||
|
font-size: large;
|
||||||
|
}
|
||||||
|
.entete{
|
||||||
|
font-size: xxx-large;
|
||||||
|
}
|
||||||
|
.caseInfo{
|
||||||
|
margin: 1em;
|
||||||
|
padding: 1em;
|
||||||
|
background-color: rgba(255,185,251,0.61);
|
||||||
|
}
|
||||||
|
.dnconnect{
|
||||||
|
padding: 1em;
|
||||||
|
display: flex;
|
||||||
|
justify-content: right;
|
||||||
|
}
|
||||||
|
.margOp{
|
||||||
|
margin: 1em;
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<!--Boostrap-->
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
|
||||||
|
<!--CSS-->
|
||||||
|
<link rel="stylesheet" href="/~rorossetto/Php_RSS/fluxRSS/templates/CSS/myStyle.css" >
|
||||||
|
<title class="enTitre">Login</title>
|
||||||
|
</head>
|
||||||
|
<body class="myBody">
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
{% if dVue is defined %}
|
||||||
|
{% if dVueEreur is defined and dVueEreur|length >0 %}
|
||||||
|
<h2>ERREUR !!!!!</h2>
|
||||||
|
{% for value in dVueEreur %}
|
||||||
|
<p>{{value}}</p>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<h1 class="d-flex justify-content-center entete margOp">Login</h1>
|
||||||
|
<form method="POST" class="form-floating" name="myform" id="myform">
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>Nom</td>
|
||||||
|
<td>
|
||||||
|
<input class="margOp" name="username" id="username" type="text" size="20" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Password</td>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
<input class="margOp" type="password" id="password" name="password" required>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td><input class="margOp" type="submit" value="Envoyer" /></td>
|
||||||
|
<td><input class="margOp" type="reset" value="Rétablir" /></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<!-- action !!!!!!!!!! -->
|
||||||
|
<input type="hidden" name="action" value="connection" />
|
||||||
|
</form>
|
||||||
|
<a href="/~rorossetto/Php_RSS/fluxRSS/user/" class="modal-content">Not a member? Go to Articles</a>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,39 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
|
||||||
|
<!-- CSS -->
|
||||||
|
<link rel="stylesheet" href="/~rorossetto/Php_RSS/fluxRSS/templates/CSS/myStyle.css" >
|
||||||
|
<title>All Articles</title>
|
||||||
|
</head>
|
||||||
|
<body class="myBody margOp">
|
||||||
|
<a class="btn dnconnect" href="/~rorossetto/Php_RSS/fluxRSS/admin/deconnection">Déconnection</a>
|
||||||
|
<a class="btn" href="/~rorossetto/Php_RSS/fluxRSS/admin/listFlux">Vue flux</a>
|
||||||
|
<div class="margOp">
|
||||||
|
<h1 class="d-flex justify-content-center entete">Vue des articles</h1>
|
||||||
|
</div>
|
||||||
|
<form class="margOp" method="POST" action="changeNbArticle">
|
||||||
|
<input name="nbArticleAdmin" type="number" min="0">
|
||||||
|
<button type="submit">Change number of articles</button>
|
||||||
|
</form>
|
||||||
|
{% if dVue.data is defined %}
|
||||||
|
{% for article in dVue.data %}
|
||||||
|
<p class="caseInfo">
|
||||||
|
{{article.dateStr()}}<br>
|
||||||
|
<img class="imgArticle" src="{{ article.getMediaContent }}"/><br>
|
||||||
|
<a class="modal-content enTitre" href="{{ article.getLink() }}"target="_blank">{{ article.getTitle() }}</a>
|
||||||
|
{{ article.getDescription() }}
|
||||||
|
</p>
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
<p class="d-flex justify-content-center enTitre">Pas d'articles à afficher</p>
|
||||||
|
{% endif %}
|
||||||
|
<script>
|
||||||
|
// Actualiser la page toutes les 3 heures
|
||||||
|
setTimeout(function(){
|
||||||
|
location.reload();
|
||||||
|
}, 10800000);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,33 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
|
||||||
|
<!-- CSS -->
|
||||||
|
<link rel="stylesheet" href="/~rorossetto/Php_RSS/fluxRSS/templates/CSS/myStyle.css" >
|
||||||
|
<title>All Flux</title>
|
||||||
|
</head>
|
||||||
|
<body class="myBody margOp">
|
||||||
|
<a class="btn" href="/~rorossetto/Php_RSS/fluxRSS/admin/">Vue article</a>
|
||||||
|
<div class="margOp">
|
||||||
|
<h1 class="d-flex justify-content-center entete">Liste flux</h1>
|
||||||
|
</div>
|
||||||
|
{% if dVue.data is defined %}
|
||||||
|
{% for value in dVue.data %}
|
||||||
|
<div class="margOp enTitre caseInfo">
|
||||||
|
{{ value.getFlux() }}
|
||||||
|
<form method="post" action="deleteFlux">
|
||||||
|
<input type="hidden" name="flux" value="{{ value.getId() }}">
|
||||||
|
<button class="margOp" type="submit">Delete Flux</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
<p class="justify-content-center d-flex enTitre">Pas de flux présent</p>
|
||||||
|
{% endif %}
|
||||||
|
<form method="POST" action="ajoutFlux">
|
||||||
|
<input name="fluxAdd" type="text">
|
||||||
|
<button type="submit">Ajouter Flux</button>
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,105 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="fr">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<title>Personne - formulaire</title>
|
|
||||||
<script type="text/javascript">
|
|
||||||
function clearForm(oForm) {
|
|
||||||
const elements = oForm.elements;
|
|
||||||
oForm.reset();
|
|
||||||
|
|
||||||
for (i = 0; i < elements.length; i++) {
|
|
||||||
field_type = elements[i].type.toLowerCase();
|
|
||||||
|
|
||||||
switch (field_type) {
|
|
||||||
case "text":
|
|
||||||
case "password":
|
|
||||||
case "textarea":
|
|
||||||
case "hidden":
|
|
||||||
elements[i].value = "";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "radio":
|
|
||||||
case "checkbox":
|
|
||||||
if (elements[i].checked) {
|
|
||||||
elements[i].checked = false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "select-one":
|
|
||||||
case "select-multi":
|
|
||||||
elements[i].selectedIndex = -1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<!-- on vérifie les données provenant du modèle -->
|
|
||||||
{% if dVue is defined %}
|
|
||||||
<div align="center">
|
|
||||||
{% if dVueEreur is defined and dVueEreur|length >0 %}
|
|
||||||
<h2>ERREUR !!!!!</h2>
|
|
||||||
{% for value in dVueEreur %}
|
|
||||||
<p>{{value}}</p>
|
|
||||||
{% endfor %}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<h2>Personne - formulaire</h2>
|
|
||||||
<hr />
|
|
||||||
<!-- affichage de données provenant du modèle -->
|
|
||||||
{{dVue.data}}
|
|
||||||
|
|
||||||
<form method="post" name="myform" id="myform">
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td>Nom</td>
|
|
||||||
<td>
|
|
||||||
<input name="txtNom" value="{{dVue.nom}}" type="text" size="20" />
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Age</td>
|
|
||||||
<td>
|
|
||||||
<input
|
|
||||||
name="txtAge"
|
|
||||||
value="{{dVue.age}}"
|
|
||||||
type="text"
|
|
||||||
size="3"
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr></tr>
|
|
||||||
</table>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><input type="submit" value="Envoyer" /></td>
|
|
||||||
<td><input type="reset" value="Rétablir" /></td>
|
|
||||||
<td>
|
|
||||||
<input
|
|
||||||
type="button"
|
|
||||||
value="Effacer"
|
|
||||||
onclick="clearForm(this.form);"
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<!-- action !!!!!!!!!! -->
|
|
||||||
<input type="hidden" name="action" value="validationFormulaire" />
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<p>Erreur !!<br />utilisation anormale de la vuephp</p>
|
|
||||||
{% endif %}
|
|
||||||
<p>
|
|
||||||
Essayez de mettre du code html dans nom -> Correspond à une attaque de type injection
|
|
||||||
</p>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue