Developing Article Blog CMS
This commit is contained in:
parent
3ef76404a7
commit
52dd9b6ce0
@ -28,7 +28,7 @@ include("$root/analytics/matomo.php");
|
||||
<h3>Author</h3>
|
||||
<p>This website is developped with ♥ by Samuel ORTION, a juvenile <em>Geekus biologicus</em>.</p>
|
||||
<h3>Source code</h3>
|
||||
<p>This project is available under the GNU Affero GPL v3 license at <a href="https://forge.ortion.xyz/UncleSamulus/chiro-canto">https://forge.ortion.xyz/UncleSamulus/chiro-canto</a>.</p>
|
||||
<p>This project is available under the GNU Affero GPL v3 license at <a href="https://forge.ortion.xyz/Chiro-Canto/chiro-canto">https://forge.ortion.xyz/Chiro-Canto/chiro-canto</a>.</p>
|
||||
</section>
|
||||
<?php include("$root/footer.php");?>
|
||||
</body>
|
||||
|
122
public/articles/Article.php
Normal file
122
public/articles/Article.php
Normal file
@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
$root = realpath($_SERVER["DOCUMENT_ROOT"]);
|
||||
require "$root/database/credentials.php";
|
||||
// Connect the database
|
||||
try {
|
||||
$db = new PDO("mysql:host=$host;dbname=$database;charset=utf8",
|
||||
$user,
|
||||
$password,
|
||||
array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
|
||||
));
|
||||
} catch (Exception $e) {
|
||||
die("Error : ".$e->getMessage());
|
||||
}
|
||||
|
||||
class Article
|
||||
{
|
||||
public $id = null;
|
||||
public $publication_date = null;
|
||||
public $modification_date = null;
|
||||
public $title = null;
|
||||
public $summary = null;
|
||||
public $content = null;
|
||||
public $author_id = null;
|
||||
|
||||
public function __construct( $data=array() ) {
|
||||
if ( isset( $data['id'] ) ) $this->id = (int) $data['id'];
|
||||
if ( isset( $data['publication_date'] ) ) $this->publication_date = (int) $data['publication_date'];
|
||||
if ( isset( $data['modification_date'] ) ) $this->modification_date = (int) $data['modification_date'];
|
||||
if ( isset( $data['title'] ) ) $this->title = preg_replace ( "/[^\.\,\-\_\'\"\@\?\!\:\$ a-zA-Z0-9()]/", "", $data['title'] );
|
||||
if ( isset( $data['summary'] ) ) $this->summary = preg_replace ( "/[^\.\,\-\_\'\"\@\?\!\:\$ a-zA-Z0-9()]/", "", $data['summary'] );
|
||||
if ( isset( $data['content'] ) ) $this->content = $data['content'];
|
||||
if ( isset( $data['author_id'] ) ) $this->author_id = $data['author_id'];
|
||||
}
|
||||
|
||||
public function storeFormValues($params) {
|
||||
$this->__construct($params);
|
||||
if (isset($params['publication_date'])) {
|
||||
$publication_date = explode('-', $params['publication_date']);
|
||||
if(count($publication_date) == 3) {
|
||||
list($y, $m, $d) = $publication_date;
|
||||
$this->publication_date = mktime(0, 0, 0, $m, $d, $y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function getById($id)
|
||||
{
|
||||
global $db;
|
||||
$req = $db->prepare('SELECT *, UNIX_TIMESTAMP(publication_date) AS publication_date FROM articles WHERE id=:id');
|
||||
$req->execute(array(
|
||||
"id"=>$id
|
||||
));
|
||||
if ($data = $req->fetch()) {
|
||||
return new Article($data);
|
||||
}
|
||||
}
|
||||
|
||||
public static function getList($num = 1000000) {
|
||||
global $db;
|
||||
$req = $db->prepare('SELECT *, UNIX_TIMESTAMP(created_on) AS publication_date FROM articles ORDER BY created_on DESC LIMIT 5');
|
||||
$req->execute();//array(
|
||||
// "num_rows"=>$num
|
||||
// ));
|
||||
$list = array();
|
||||
while ($row = $req->fetch()) {
|
||||
$article = new Article($row);
|
||||
$list[] = $article;
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
public function insert() {
|
||||
if (! is_null($this->id)) {
|
||||
trigger_error("Article::insert(): Attempt to insert an Article object that already has its ID property set (to $this->id).", E_USER_ERROR);
|
||||
}
|
||||
global $db;
|
||||
$req = $db->prepare('INSERT INTO articles (publication_date, modification_date, title, summary, content) VALUES (FROM_UNIXTIME(:publication_date), FROM_UNIXTIME(:modification_date), :title, :summary, :content, :author_id');
|
||||
$req->execute(array(
|
||||
"publication_date"=>$this->publication_date,
|
||||
"modification_date"=>$this->modification_date,
|
||||
"title"=>$this->title,
|
||||
"summary"=>$this->summary,
|
||||
"content"=>$this->content,
|
||||
"author_id"=>$this->author_id
|
||||
));
|
||||
$this->id = $db->lastInsertedId();
|
||||
}
|
||||
|
||||
public function update() {
|
||||
if (is_null($this->id))
|
||||
{
|
||||
trigger_error("Article::update(): Attempt to update an Article object that does not have its ID property set.", E_USER_ERROR);
|
||||
}
|
||||
global $db;
|
||||
$req = $db->prepare('UPDATE article SET modification_date=FROM_UNIXTIMESTAMP(:modification_date), title=:title, summary=:summary, content=:content WHERE id=:id');
|
||||
$req->execute(array(
|
||||
"modification_date"=>$this->modification_date,
|
||||
"title"=>$this->title,
|
||||
"summary"=>$this->summary,
|
||||
"content"=>$this->content,
|
||||
"id"=>$this->id
|
||||
));
|
||||
}
|
||||
|
||||
public function delete() {
|
||||
if (is_null($this->id))
|
||||
{
|
||||
trigger_error( "Article::delete(): Attempt to delete an Article object that does not have its ID property set.", E_USER_ERROR);
|
||||
}
|
||||
global $db;
|
||||
$req = $db->prepare('DELETE FROM articles WHERE id=:id LIMIT 1');
|
||||
$req->execute(array(
|
||||
"id"=>$this->id
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
89
public/articles/admin.php
Normal file
89
public/articles/admin.php
Normal file
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
$root = realpath($_SERVER["DOCUMENT_ROOT"]);
|
||||
session_start();
|
||||
require("config.php");
|
||||
require("Article.php");
|
||||
$action = isset($_GET['action']) ? $_GET['action'] : "";
|
||||
$username = isset($_SESSION['username']) ? $_SESSION['username'] : "";
|
||||
|
||||
if ($username == "") {
|
||||
$_SESSION['error_msg'] = "You need to be logged in as administrator to perform these tasks.";
|
||||
header("Location: $root/auth/login");
|
||||
}
|
||||
|
||||
switch ($action) {
|
||||
case 'new':
|
||||
newArticle();
|
||||
break;
|
||||
case 'edit':
|
||||
edit();
|
||||
break;
|
||||
case 'delete':
|
||||
delete();
|
||||
break;
|
||||
default:
|
||||
listArticles();
|
||||
}
|
||||
|
||||
function newArticle() {
|
||||
if (isset($_POST['save'])) {
|
||||
$article = new Article;
|
||||
$article->storeFormValues($_POST);
|
||||
$article->insert();
|
||||
header("Location: admin.php?status=saved");
|
||||
} elseif (isset($_POST['cancel'])) {
|
||||
header("Location: admin.php");
|
||||
} else {
|
||||
$results['article'] = new Article;
|
||||
require("edit.php");
|
||||
}
|
||||
}
|
||||
|
||||
function edit() {
|
||||
$results = array();
|
||||
$results['pageTitle'] = "Edit Article";
|
||||
$result['form'] = "edit";
|
||||
|
||||
if (isset($_POST['save'])) {
|
||||
if (!$article = Article::getById((int)$_POST['id'])) {
|
||||
header( "Location: admin.php?error=notFound" );
|
||||
return;
|
||||
}
|
||||
$article->storeFormValues($_POST);
|
||||
$article->update();
|
||||
header("Location: admin.php?status=saved");
|
||||
} elseif (isset($_POST['cancel'])) {
|
||||
header("Location: admin.php");
|
||||
} else {
|
||||
$results['article'] = Article::getById((int)$_GET['article']);
|
||||
require("edit.php");
|
||||
}
|
||||
}
|
||||
|
||||
function delete() {
|
||||
if (!$article = Article::getById((int) $_GET['article'])) {
|
||||
header("Location: admin.php?error=notFound");
|
||||
return;
|
||||
}
|
||||
$article->delete();
|
||||
header("Location: admin.php?status=deleted");
|
||||
}
|
||||
|
||||
function listArticles() {
|
||||
$results = array();
|
||||
$data = Article::getList();
|
||||
$results['articles'] = $data['results'];
|
||||
$results['totalRows'] = $data['totalRows'];
|
||||
$results['pageTitle'] = "All Articles";
|
||||
if (isset($_GET['error'])) {
|
||||
if ($_GET['error'] == "notFound") {
|
||||
$results['error'] = "Error: Article not found.";
|
||||
}
|
||||
}
|
||||
if ( isset( $_GET['status'] ) ) {
|
||||
if ( $_GET['status'] == "saved" ) $results['status'] = "Your changes have been saved.";
|
||||
if ( $_GET['status'] == "deleted" ) $results['status'] = "Article deleted.";
|
||||
}
|
||||
require("list.php");
|
||||
}
|
||||
?>
|
43
public/articles/archive.php
Normal file
43
public/articles/archive.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
session_start();
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
$root = realpath($_SERVER["DOCUMENT_ROOT"]);
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Explore | Chiro - Canto</title>
|
||||
<link rel="stylesheet" type="text/css" href="/styles/style.css">
|
||||
</head>
|
||||
<?php
|
||||
include("$root/analytics/matomo.php");
|
||||
?>
|
||||
<body>
|
||||
<?php include("$root/menu.php");?>
|
||||
<?php include("$root/header.php");?>
|
||||
<h2>Articles Archive</h2>
|
||||
<ul id="headlines" class="arcive">
|
||||
<?php
|
||||
foreach ($results['articles'] as $article) {
|
||||
?>
|
||||
<li>
|
||||
<h2><span class="pub-date"><?=date('j F Y', $article->publication_date)?></span>
|
||||
<a href="?action=view&article=<?=$article->id?>"><?=htmlspecialchars($article->title)?></a>
|
||||
</h2>
|
||||
<p class="summary"><?php echo htmlspecialchars($article->summary)?></p>
|
||||
</li>
|
||||
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
<p><a href="?action=archive">Article Archive</a></p>
|
||||
<?php include("$root/footer.php");?>
|
||||
</body>
|
||||
<script src="/scripts/script.js"></script>
|
||||
</html>
|
3
public/articles/config.php
Normal file
3
public/articles/config.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
define("HOMEPAGE_NUM_ARTICLES", 5);
|
||||
?>
|
25
public/articles/home.php
Normal file
25
public/articles/home.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
session_start();
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
$root = realpath($_SERVER["DOCUMENT_ROOT"]);
|
||||
?>
|
||||
<h2>Articles Home</h2>
|
||||
<ul>
|
||||
<?php
|
||||
print_r($results);
|
||||
foreach ($results['articles'] as $article) {
|
||||
?>
|
||||
<li>
|
||||
<h2><span class="pub-date"><?=date('j F Y', $article->publication_date)?></span>
|
||||
<a href="?action=view&article=<?=$article->id?>"><?=htmlspecialchars($article->title)?></a>
|
||||
</h2>
|
||||
<p class="summary"><?php echo htmlspecialchars($article->summary)?></p>
|
||||
</li>
|
||||
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
<p><a href="?action=archive">Article Archive</a></p>
|
73
public/articles/index.php
Normal file
73
public/articles/index.php
Normal file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
$root = realpath($_SERVER["DOCUMENT_ROOT"]);
|
||||
require("$root/articles/config.php");
|
||||
require("$root/articles/Article.php");
|
||||
|
||||
function archive() {
|
||||
$result = array();
|
||||
$data = Article::getList();
|
||||
$result['articles'] = $data['results'];
|
||||
$result['totalRows'] = $data['totalRows'];
|
||||
$result['pageTitle'] = "Article Archive | Chiro - Canto";
|
||||
require("$root/articles/archive.php");
|
||||
}
|
||||
|
||||
function view() {
|
||||
if (! isset($_GET['article']) || ! $_GET['article']) {
|
||||
home();
|
||||
return;
|
||||
}
|
||||
$results = array();
|
||||
$results['article'] = Article::getById( (int)$_GET["articleId"] );
|
||||
$results['pageTitle'] = $results['article']->title . " | Chiro - Canto";
|
||||
require("$root/articles/view.php");
|
||||
}
|
||||
|
||||
function home() {
|
||||
$results = array();
|
||||
$data = Article::getList(HOMEPAGE_NUM_ARTICLES);
|
||||
$results['articles'] = $data['results'];
|
||||
$results['totalRows'] = $data['totalRows'];
|
||||
$results['pageTitle'] = "Articles | Chiro - Canto";
|
||||
require("home.php");
|
||||
}
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Articles | Chiro - Canto</title>
|
||||
<link rel="stylesheet" type="text/css" href="/styles/style.css">
|
||||
</head>
|
||||
<?php
|
||||
include("$root/analytics/matomo.php");
|
||||
?>
|
||||
<body>
|
||||
<?php include("$root/menu.php");?>
|
||||
<?php include("$root/header.php");?>
|
||||
<section>
|
||||
<?php
|
||||
$action = isset($_GET['action']) ? $_GET['action'] : "";
|
||||
switch ($action) {
|
||||
case 'archive':
|
||||
archive();
|
||||
break;
|
||||
case 'view':
|
||||
view();
|
||||
break;
|
||||
default:
|
||||
home();
|
||||
}
|
||||
?>
|
||||
<h2>Articles</h2>
|
||||
<article>
|
||||
<h3></h3>
|
||||
</article>
|
||||
</section>
|
||||
<?php include("$root/footer.php");?>
|
||||
</body>
|
||||
<script src="/scripts/script.js"></script>
|
||||
</html>
|
49
public/articles/list.php
Normal file
49
public/articles/list.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
session_start();
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
$root = realpath($_SERVER["DOCUMENT_ROOT"]);
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Explore | Chiro - Canto</title>
|
||||
<link rel="stylesheet" type="text/css" href="/styles/style.css">
|
||||
</head>
|
||||
<?php
|
||||
include("$root/analytics/matomo.php");
|
||||
?>
|
||||
<body>
|
||||
<?php include("$root/menu.php");?>
|
||||
<?php include("$root/header.php");?>
|
||||
<h2>All Articles</h2>
|
||||
<?php if (isset($results['error'])) { ?>
|
||||
<div class="error"><?php echo $results['error'] ?></div>
|
||||
<?php }
|
||||
if (isset($results['status'])) {?>
|
||||
<div class="status"><?php echo $results['status'] ?></div>
|
||||
<?php } ?>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Publication Date</th>
|
||||
<th>Article</th>
|
||||
</tr>
|
||||
<?php foreach($results['articles'] as $article) { ?>
|
||||
<tr>
|
||||
<td><?php echo date('j M Y', $article->publication_date)?></td>
|
||||
<td>
|
||||
<?php echo $article->title?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
</table>
|
||||
<p><a href="admin.php?action=new">New article</a></p>
|
||||
<p><a href="./">Return to Homepage</a></p>
|
||||
<?php include("$root/footer.php");?>
|
||||
</body>
|
||||
<script src="/scripts/script.js"></script>
|
||||
</html>
|
32
public/articles/view.php
Normal file
32
public/articles/view.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
session_start();
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
$root = realpath($_SERVER["DOCUMENT_ROOT"]);
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Explore | Chiro - Canto</title>
|
||||
<link rel="stylesheet" type="text/css" href="/styles/style.css">
|
||||
</head>
|
||||
<?php
|
||||
include("$root/analytics/matomo.php");
|
||||
?>
|
||||
<body>
|
||||
<?php include("$root/menu.php");?>
|
||||
<?php include("$root/header.php");?>
|
||||
<h2>Article</h2>
|
||||
<h3><?php echo htmlspecialchars($results['article']->title)?></h3>
|
||||
<div><?php echo htmlspecialchars($results['article']->summary)?></div>
|
||||
<div><?php echo $results['article']->content?></div>
|
||||
<p class="pub-date">Published on <?php echo date('j F Y', $results['article']->publication_date)?></p>
|
||||
<p><a href="./">Return to Homepage</a></p>
|
||||
<?php include("$root/footer.php");?>
|
||||
</body>
|
||||
<script src="/scripts/script.js"></script>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user