Added Blog (Articles) minimal CMS

This commit is contained in:
Samuel Ortion 2021-04-05 15:37:12 +02:00
parent fd4b9a2811
commit 353db5a8cb
20 changed files with 2518 additions and 179 deletions

View File

@ -1,9 +1,9 @@
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
$root = realpath($_SERVER["DOCUMENT_ROOT"]);
// session_start();
require "$root/database/credentials.php";
// Connect the database
try {
@ -33,7 +33,15 @@ class Article
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'];
global $db;
$req = $db->prepare('SELECT id FROM authors WHERE username=:username');
$req->execute(array(
"username"=>$_SESSION['username']
));
if ($data = $req->fetch()) {
if (isset($data['id']))
$this->author_id = $data['id'];
}
}
public function storeFormValues($params) {
@ -50,7 +58,7 @@ class Article
public static function getById($id)
{
global $db;
$req = $db->prepare('SELECT *, UNIX_TIMESTAMP(publication_date) AS publication_date FROM articles WHERE id=:id');
$req = $db->prepare('SELECT *, UNIX_TIMESTAMP(created_on) AS publication_date FROM articles WHERE id=:id');
$req->execute(array(
"id"=>$id
));
@ -69,6 +77,7 @@ class Article
while ($row = $req->fetch()) {
$article = new Article($row);
$list[] = $article;
// print_r($article);
}
return $list;
}
@ -78,16 +87,15 @@ class Article
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 = $db->prepare('INSERT INTO articles (created_on, modified_on, title, summary, content, article_by) VALUES (FROM_UNIXTIME(:created_on), FROM_UNIXTIME(:modified_on), :title, :summary, :content, :article_by)');
$req->execute(array(
"publication_date"=>$this->publication_date,
"modification_date"=>$this->modification_date,
"created_on"=>$this->publication_date,
"modified_on"=>$this->modification_date,
"title"=>$this->title,
"summary"=>$this->summary,
"content"=>$this->content,
"author_id"=>$this->author_id
"article_by"=>$this->author_id
));
$this->id = $db->lastInsertedId();
}
public function update() {

View File

@ -8,7 +8,7 @@ $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");
header("Location: /auth/login");
}
switch ($action) {
@ -72,8 +72,9 @@ function delete() {
function listArticles() {
$results = array();
$data = Article::getList();
$results['articles'] = $data['results'];
$results['totalRows'] = $data['totalRows'];
// print_r($data);
$results['articles'][] = $data[0];
// $results['totalRows'] = $data['totalRows'];
$results['pageTitle'] = "All Articles";
if (isset($_GET['error'])) {
if ($_GET['error'] == "notFound") {

View File

@ -1,25 +1,3 @@
<?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
@ -37,7 +15,3 @@ include("$root/analytics/matomo.php");
?>
</ul>
<p><a href="?action=archive">Article Archive</a></p>
<?php include("$root/footer.php");?>
</body>
<script src="/scripts/script.js"></script>
</html>

42
public/articles/edit.php Normal file
View File

@ -0,0 +1,42 @@
<?php
$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>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>
<h2>Articles</h2>
<article>
<h3>Create an article</h3>
<form action="admin.php?action=new" method="post">
<label for="publication_date">Publication Date</label>
<input type="date" name="publication_date" id="publication_date">
<label for="modification_date">Modification Date</label>
<input type="date" name="modification_date" id="modification_date">
<label for="title">Title</label>
<input type="text" name="title" id="title" placeholder="Enter article title..">
<label for="summary">Summary</label>
<textarea id="summary" name="summary" placeholder="Enter article summary (support Markdown).."></textarea><br>
<label for="content">Content</label>
<textarea id="content" name="content" placeholder="Enter article content (support Markdown).." rows="100"></textarea><br>
<input type="submit" name="save" value="Send Article">
<input type="reset" value="Reset">
</form>
</article>
</section>
<?php include("$root/footer.php");?>
</body>
<script src="/scripts/script.js"></script>
</html>

View File

@ -1,21 +1,14 @@
<?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);
// 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>
<p class="summary"><?php echo $Parsedown->text(htmlspecialchars($article->summary))?></p>
</li>
<?php

View File

@ -2,32 +2,42 @@
$root = realpath($_SERVER["DOCUMENT_ROOT"]);
require("$root/articles/config.php");
require("$root/articles/Article.php");
session_start();
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
include("$root/vendor/erusev/parsedown/Parsedown.php");
$Parsedown = new Parsedown();
function archive() {
$result = array();
global $root;
$results = array();
$data = Article::getList();
$result['articles'] = $data['results'];
$result['totalRows'] = $data['totalRows'];
$result['pageTitle'] = "Article Archive | Chiro - Canto";
$results['articles'] = $data;
// $result['totalRows'] = $data['totalRows'];
$results['pageTitle'] = "Article Archive | Chiro - Canto";
require("$root/articles/archive.php");
}
function view() {
global $root;
global $Parsedown;
if (! isset($_GET['article']) || ! $_GET['article']) {
home();
return;
}
$results = array();
$results['article'] = Article::getById( (int)$_GET["articleId"] );
$results['pageTitle'] = $results['article']->title . " | Chiro - Canto";
$results['articles'][] = Article::getById( (int)$_GET["article"] );
$results['pageTitle'] = $results['articles'][0]->title . " | Chiro - Canto";
require("$root/articles/view.php");
}
function home() {
global $Parsedown;
$results = array();
$data = Article::getList(HOMEPAGE_NUM_ARTICLES);
$results['articles'] = $data['results'];
$results['totalRows'] = $data['totalRows'];
$results['articles'][] = $data[0];
// $results['totalRows'] = $data['totalRows'];
$results['pageTitle'] = "Articles | Chiro - Canto";
require("home.php");
}

View File

@ -1,25 +1,3 @@
<?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>
@ -32,7 +10,7 @@ include("$root/analytics/matomo.php");
<th>Publication Date</th>
<th>Article</th>
</tr>
<?php foreach($results['articles'] as $article) { ?>
<?php foreach($results as $article) { ?>
<tr>
<td><?php echo date('j M Y', $article->publication_date)?></td>
<td>
@ -43,7 +21,3 @@ include("$root/analytics/matomo.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>

View File

@ -1,32 +1,6 @@
<?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>
<h3><?php echo htmlspecialchars($results['articles'][0]->title)?></h3>
<div><?php echo $Parsedown->text(htmlspecialchars($results['articles'][0]->summary))?></div>
<div><?php echo $Parsedown->text(htmlspecialchars($results['articles'][0]->content))?></div>
<p class="pub-date">Published on <?php echo date('j F Y', $results['articles'][0]->publication_date)?></p>
<p><a href="./">Return to Homepage</a></p>
<?php include("$root/footer.php");?>
</body>
<script src="/scripts/script.js"></script>
</html>

View File

@ -0,0 +1 @@
,ortion,fedora,04.04.2021 12:34,file:///home/ortion/.config/libreoffice/4;

File diff suppressed because it is too large Load Diff

View File

@ -36,7 +36,7 @@ foreach ($rows as $row) {
?>
<tr>
<td><a href="newtopic.php?cat=<?=$row['id']?>"><?=$row['cat_name']?></a></td></p>
<td><a href="topics/?cat=<?=$row['id']?>"><?=$row['cat_name']?></a></td></p>
<td><?=$Parsedown->text($row['cat_description'])?></td>
</tr>
<?php

View File

@ -0,0 +1,60 @@
function select() {
var selectedText = '';
// window.getSelection
if (window.getSelection) {
selectedText = window.getSelection();
}
// document.getSelection
else if (document.getSelection) {
selectedText = document.getSelection();
}
// document.selection
else if (document.selection) {
selectedText =
document.selection.createRange().text;
}
return selectedText;
}
// let bold_button = document.getElementById('bold').addEventListener('click', function() {
function bold() {
let selection = select();
if (selection == "") {
alert("Please select text to bold.");
}
else {
document.getElementById('reply').innerHTML.replace(selection, `**${selection}**`);
}
}
let url_button = document.getElementById('url');
let url_form = document.getElementById('url-form');
url_button.addEventListener('click', function() {
url_form.style.display = "block";
document.getElementById("submit-url").addEventListener("click", function() {
let url = document.getElementById('url-input').value;
let description = document.getElementById('url-description').value;
description = description == "" ? url : description;
let markdown = `[${description}](${url})`;
document.getElementById('reply').innerHTML += markdown;
url_form.style.display = "none";
// setCaret();
});
});
// function setCaret() {
// let el = document.getElementById('reply');
// let range = document.createRange();
// let sel = window.getSelection();
// range.setStar t(el, -1);
// range.collapse(true);
// sel.removeAllRanges();
// sel.addRange(range);
// }

View File

@ -3,7 +3,7 @@ ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
$root = realpath($_SERVER["DOCUMENT_ROOT"]);
include("$root/../vendor/erusev/parsedown/Parsedown.php");
include("$root/vendor/erusev/parsedown/Parsedown.php");
$Parsedown = new Parsedown();
require "$root/database/credentials.php";
// Connect the database
@ -69,13 +69,37 @@ if (isset($_GET['topic'])){
</tbody>
</table>
<br>
<h2>Your Reply</h2>
<div class="container column">
<div class="container items row">
<button id="bold" title="bold" onmousedown="bold()"><b>B</b></button>
<button id="italic" title="italic"><i>I</i></button>
<button id="underline" title="underline"><u>U</u></button>
<button id="crossed" title="crossed"><s>s</s></button>
</div>
<br>
<div class="container items row">
<button id="url" title="url">🔗</button>
<button id="code" title="code"><img src="/media/icons/code.svg" alt="code"></button>
<button id="cite" title="cite"><img src="/media/icons/cite.svg" alt="cite"></button>
<button id="image" title="image"><img src="/media/icons/dslr.png" alt="image"></button>
</div>
</div>
<form action="sendreply.php" method="post">
<input type="hidden" name="topic_id" value="<?=$topic_id?>">
<label for="reply">Your Reply</label>
<textarea name="reply" id="reply" cols="30" rows="10" placeholder="Enter your reply (support Markdown).."></textarea>
<input type="submit" name="submit" value="submit">
<input type="reset" name="reset" value="reset">
</form>
<form id="url-form">
<label for="url-input">URL</label>
<input type="url" id="url-input" name="url" placeholder="https://example.com">
<label for="text">Description (optional)</label>
<input type="text" name="url-description" id="url-description">
<input type="button" name="submit" value="Ok" id="submit-url">
</form>
<script src="scripts/editor.js"></script>
<?php
} catch (Exception $e)

View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="48"
height="48"
viewBox="0 0 12.7 12.7"
version="1.1"
id="svg8"
inkscape:version="1.0.2 (e86c870879, 2021-01-15)"
sodipodi:docname="cite.svg">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="10.596494"
inkscape:cx="14.943995"
inkscape:cy="9.4222023"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
inkscape:document-rotation="0"
showgrid="false"
units="px"
inkscape:window-width="1920"
inkscape:window-height="1011"
inkscape:window-x="0"
inkscape:window-y="32"
inkscape:window-maximized="1">
<inkscape:grid
type="xygrid"
id="grid835" />
</sodipodi:namedview>
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:#d5fff6;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
d="M 2.2805749,3.4700771 C 1.1002985,4.6500496 1.1223871,7.2738065 2.2790647,8.4769209 3.5512826,9.8002142 7.7818432,8.6919138 7.7818432,8.6919138 L 9.2038394,9.9477477 8.7034159,8.4422893 C 9.168145,8.4347714 9.6623161,8.5857716 10.097603,8.4197357 11.213306,8.1990578 11.124369,4.6181261 9.9384017,3.4697389 8.1046143,1.6940599 4.0857743,1.6653424 2.2805749,3.4700771 Z"
id="path833"
sodipodi:nodetypes="aaccccaa" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="48"
height="48"
viewBox="0 0 12.7 12.7"
version="1.1"
id="svg8"
inkscape:version="1.0.2 (e86c870879, 2021-01-15)"
sodipodi:docname="code.svg">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.5810083"
inkscape:cx="9.1451904"
inkscape:cy="36.627092"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
inkscape:document-rotation="0"
showgrid="false"
units="px"
inkscape:window-width="1530"
inkscape:window-height="1011"
inkscape:window-x="50"
inkscape:window-y="32"
inkscape:window-maximized="0" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.76111px;line-height:1.25;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
x="0.45211029"
y="8.5704489"
id="text835"><tspan
sodipodi:role="line"
id="tspan833"
x="0.45211029"
y="8.5704489"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.76111px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583">&lt;/&gt;</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
public/media/icons/dslr.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -16,9 +16,10 @@ try{
}
if ($file = fopen("/var/www/chiro-canto/public/database/TAXREF14.0_CHIRO.csv", 'r')) {
while($row = fgetcsv($file, 0, ','))
if ($file = fopen("/var/www/chiro-canto/public/database/TAXREF14.0_ORTHO.csv", 'r')) {
while($row = fgetcsv($file, 0, ';'))
{
print_r($row);
// print_r($row);
$kingdom = $row[0];
$phylum = $row[1];
@ -29,6 +30,7 @@ if ($file = fopen("/var/www/chiro-canto/public/database/TAXREF14.0_CHIRO.csv", '
$tribu = $row[6];
$genus = explode(' ', $row[12])[0];
$species = utf8_decode($row[12]);
try {
$req = $db->prepare('INSERT INTO `taxa` (taxon_kingdom, taxon_phylum, taxon_class, taxon_order, taxon_family, taxon_subfamily, taxon_tribu, taxon_genus, taxon_species) VALUES (:kingdom, :phylum, :class, :order, :family, :subfamily, :tribu, :genus, :species)');
$req->execute(array(
"kingdom"=>$kingdom,
@ -41,6 +43,9 @@ if ($file = fopen("/var/www/chiro-canto/public/database/TAXREF14.0_CHIRO.csv", '
"genus"=>$genus,
"species"=>$species
));
} catch (Exeption $e) {
echo "Error".$e->getMessage();
}
}
} else {
echo "Cannot open file";

View File

@ -94,7 +94,7 @@ input {
}
/* Style inputs with type="text", select elements and textareas */
input[type=text], input[type=email], input[type=url], input[type=password], input[type=number], select, textarea {
input[type=text], input[type=email], input[type=url], input[type=password], input[type=number], input[type=date], input[type=time], select, textarea {
width: 100%; /* Full width */
padding: 12px; /* Some padding */
border: 1px solid #ccc; /* Gray border */
@ -302,3 +302,20 @@ div.coordinates input[type="text"] {
width: 100%;
max-width: 75vh;
}
button img {
max-height: 1em;
}
form#url-form {
display: none;
position: fixed;
top: 50%;
left: 35%;
width: 15em;
z-index: 1;
background-color: white;
padding: 1em;
border-radius: 5px;
border: 1px solid #ccc;
}

File diff suppressed because one or more lines are too long