implemented following users to receive (opt-in) email notifications when they publish an article.
This commit is contained in:
+46
-37
@@ -5,6 +5,7 @@ require_once 'functions/functions.php';
|
|||||||
include_once 'components/head.php';
|
include_once 'components/head.php';
|
||||||
|
|
||||||
include_once 'functions/article_functions.php';
|
include_once 'functions/article_functions.php';
|
||||||
|
include_once 'functions/account_functions.php';
|
||||||
|
|
||||||
// UI Components
|
// UI Components
|
||||||
foreach (glob('components/article/*.php') as $file)
|
foreach (glob('components/article/*.php') as $file)
|
||||||
@@ -22,49 +23,57 @@ if (isset($_POST['form_id'])) {
|
|||||||
header('Location: articles.php?article_id=' . $_POST['article_id']);
|
header('Location: articles.php?article_id=' . $_POST['article_id']);
|
||||||
} else {
|
} else {
|
||||||
$id = create_article($_SESSION['user_id'], $_POST['title'], $_POST['excerpt'], (isset($_POST['tags']) ? $_POST['tags'] : []), $_POST['markdown']);
|
$id = create_article($_SESSION['user_id'], $_POST['title'], $_POST['excerpt'], (isset($_POST['tags']) ? $_POST['tags'] : []), $_POST['markdown']);
|
||||||
|
$emails = exec_stmt('SELECT email FROM user INNER JOIN follows ON user.user_id = follows.follower_user_id WHERE follows.following_user_id = ? AND follows.notify_user = 1', 'i', $_SESSION['user_id'])->fetch_assoc();
|
||||||
|
notify_users($emails, $_SESSION['username'], $id, $_POST['title'], $_POST['excerpt']);
|
||||||
header('Location: articles.php?article_id=' . $id);
|
header('Location: articles.php?article_id=' . $id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 'follow':
|
||||||
|
follow_user($_SESSION['user_id'], $_POST['author_id'], ($_POST['follow'] == 'email_notify' ? 1 : 0));
|
||||||
|
break;
|
||||||
|
case 'unfollow':
|
||||||
|
unfollow_user($_SESSION['user_id'], $_POST['author_id']);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
if (isset($_GET['view']))
|
|
||||||
$view = $_GET['view'];
|
|
||||||
else
|
|
||||||
$view = 'list';
|
|
||||||
|
|
||||||
switch ($view) {
|
if (isset($_GET['view']))
|
||||||
case 'list':
|
$view = $_GET['view'];
|
||||||
echo article_list();
|
else
|
||||||
break;
|
$view = 'list';
|
||||||
case 'filter':
|
|
||||||
if (isset($_GET['tag']))
|
switch ($view) {
|
||||||
echo article_list(article_ids_by_tag($_GET['tag']));
|
case 'list':
|
||||||
else if (isset($_GET['author_id']))
|
echo article_list();
|
||||||
echo article_list(articles_ids_by_author($_GET['author_id']));
|
break;
|
||||||
break;
|
case 'filter':
|
||||||
case 'sort':
|
if (isset($_GET['tag']))
|
||||||
if (isset($_GET['sort']) && $_GET['sort'] == 'oldest')
|
echo article_list(article_ids_by_tag($_GET['tag']));
|
||||||
echo article_list(article_ids_by_oldest());
|
else if (isset($_GET['author_id']))
|
||||||
else if (isset($_GET['sort']) && $_GET['sort'] == 'newest')
|
echo article_list(articles_ids_by_author($_GET['author_id']));
|
||||||
echo article_list(article_ids_by_newest());
|
break;
|
||||||
break;
|
case 'sort':
|
||||||
case 'read':
|
if (isset($_GET['sort']) && $_GET['sort'] == 'oldest')
|
||||||
if (isset($_SESSION['user_id']) && isset($_GET['article_id'])) {
|
echo article_list(article_ids_by_oldest());
|
||||||
increment_read_counter($_GET['article_id']);
|
else if (isset($_GET['sort']) && $_GET['sort'] == 'newest')
|
||||||
echo article_page_from_markdown($_GET['article_id']);
|
echo article_list(article_ids_by_newest());
|
||||||
} else {
|
break;
|
||||||
$redirect = (isset($_GET['article_id']) ? 'articles.php?view=read&article_id=' . $_GET['article_id'] : '');
|
case 'read':
|
||||||
if ($redirect)
|
if (isset($_SESSION['user_id']) && isset($_GET['article_id'])) {
|
||||||
header('Location: user.php?view=login&redirect=' . urlencode($redirect));
|
increment_read_counter($_GET['article_id']);
|
||||||
else
|
echo article_page_from_markdown($_GET['article_id']);
|
||||||
header('Location: articles.php');
|
} else {
|
||||||
}
|
$redirect = (isset($_GET['article_id']) ? 'articles.php?view=read&article_id=' . $_GET['article_id'] : '');
|
||||||
break;
|
if ($redirect)
|
||||||
case 'compose':
|
header('Location: user.php?view=login&redirect=' . urlencode($redirect));
|
||||||
echo compose_view((isset($_GET['article_id']) ? $_GET['article_id'] : ''));
|
else
|
||||||
break;
|
header('Location: articles.php');
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case 'compose':
|
||||||
|
echo compose_view((isset($_GET['article_id']) ? $_GET['article_id'] : ''));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (($view == 'list' || $view == 'sort') && (isset($_SESSION['role_id']) && $_SESSION['role_id'] <= 3)) {
|
if (($view == 'list' || $view == 'sort') && (isset($_SESSION['role_id']) && $_SESSION['role_id'] <= 3)) {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ function article_page_from_markdown($article_id)
|
|||||||
$article = exec_stmt('SELECT * FROM article WHERE article_id = ?', 'i', $article_id)->fetch_assoc();
|
$article = exec_stmt('SELECT * FROM article WHERE article_id = ?', 'i', $article_id)->fetch_assoc();
|
||||||
$author = exec_stmt('SELECT user_id, username, profile_picture FROM user WHERE user_id = ?', 'i', $article['author_id'])->fetch_assoc();
|
$author = exec_stmt('SELECT user_id, username, profile_picture FROM user WHERE user_id = ?', 'i', $article['author_id'])->fetch_assoc();
|
||||||
$markdown = read_file_one_string($_ENV['ARTICLES_FQ_PATH'] . $article_id . '/article.md');
|
$markdown = read_file_one_string($_ENV['ARTICLES_FQ_PATH'] . $article_id . '/article.md');
|
||||||
|
$following = exec_stmt('SELECT follower_user_id, following_user_id FROM follows WHERE follower_user_id = ? AND following_user_id = ?', 'ii', $_SESSION['user_id'], $author['user_id'])->fetch_assoc();
|
||||||
|
|
||||||
$parsedown = new Parsedown();
|
$parsedown = new Parsedown();
|
||||||
$parsedown->setSafeMode(true);
|
$parsedown->setSafeMode(true);
|
||||||
@@ -21,10 +22,41 @@ function article_page_from_markdown($article_id)
|
|||||||
' . (isset($_SESSION['user_id']) && $_SESSION['user_id'] == $article['author_id'] ? '<a href="articles.php?view=compose&article_id=' . $article_id . '"><i class="nf nf-fa-edit"></i></a>' : '') . '
|
' . (isset($_SESSION['user_id']) && $_SESSION['user_id'] == $article['author_id'] ? '<a href="articles.php?view=compose&article_id=' . $article_id . '"><i class="nf nf-fa-edit"></i></a>' : '') . '
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col_right">
|
<div class="row">
|
||||||
<h5>Written by <a href="user.php?action=view&user_id=' . $author['user_id'] . '">' . $author['username'] . '</a></h5>
|
<div class="col_right">
|
||||||
<p>Published on ' . $article['published_at'] . '<br>
|
<h5>Written by <a href="user.php?view=display&user_id=' . $author['user_id'] . '">' . $author['username'] . '</a></h5>
|
||||||
Lasted edited on ' . $article['updated_at'] . '</p>
|
<p>Published on ' . $article['published_at'] . '<br>
|
||||||
|
Lasted edited on ' . $article['updated_at'] . '</p>
|
||||||
|
</div>
|
||||||
|
';
|
||||||
|
|
||||||
|
if ($_SESSION['user_id'] != $author['user_id'] && !$following) {
|
||||||
|
$html .= '
|
||||||
|
<div class="dropdown">
|
||||||
|
<span>Follow</span>
|
||||||
|
<div class="dropdown_content">
|
||||||
|
<form method="post">
|
||||||
|
<input type="hidden" name="form_id" value="follow">
|
||||||
|
<input type="hidden" name="author_id" value="' . $author['user_id'] . '">
|
||||||
|
<button name="follow" value="no_notify" class="button"><i class="nf nf-md-bell_cancel"></i></button>
|
||||||
|
<button name="follow" value="email_notify" class="button"><i class="nf nf-cod-mail"></i></button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
';
|
||||||
|
} else if ($following) {
|
||||||
|
$html .= '
|
||||||
|
<div class="margin_right">
|
||||||
|
<form method="post">
|
||||||
|
<input type="hidden" name="form_id" value="unfollow">
|
||||||
|
<input type="hidden" name="author_id" value="' . $author['user_id'] . '">
|
||||||
|
<input type="submit" value="Unfollow">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
';
|
||||||
|
}
|
||||||
|
|
||||||
|
$html .= '
|
||||||
</div>
|
</div>
|
||||||
<div class="card_pic_box">
|
<div class="card_pic_box">
|
||||||
<img src="' . $_ENV['PROFILE_IMAGES_PQ_PATH'] . $author['profile_picture'] . '" class="card_profile_picture" />
|
<img src="' . $_ENV['PROFILE_IMAGES_PQ_PATH'] . $author['profile_picture'] . '" class="card_profile_picture" />
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ function article_card($article_id)
|
|||||||
<h4>' . $article['title'] . '</h4>
|
<h4>' . $article['title'] . '</h4>
|
||||||
<div class="card_info_box">
|
<div class="card_info_box">
|
||||||
<div class="col-right">
|
<div class="col-right">
|
||||||
<a href="user.php?action=view&user_id=' . $author['user_id'] . '">Written by: ' . $author['username'] . '</a>
|
<a href="user.php?view=display&user_id=' . $author['user_id'] . '">Written by: ' . $author['username'] . '</a>
|
||||||
<small>Published: ' . $article['published_at'] . '</small>
|
<small>Published: ' . $article['published_at'] . '</small>
|
||||||
<small>Updated: ' . $article['updated_at'] . '</small>
|
<small>Updated: ' . $article['updated_at'] . '</small>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,14 +1,50 @@
|
|||||||
<?php
|
<?php
|
||||||
|
include_once 'components/article/card.php';
|
||||||
|
|
||||||
function user_view($user_id)
|
function user_view($user_id)
|
||||||
{
|
{
|
||||||
|
if ($_SESSION['user_id'] != $user_id)
|
||||||
|
$following = exec_stmt('SELECT follower_user_id, following_user_id FROM follows WHERE follower_user_id = ? AND following_user_id = ?', 'ii', $_SESSION['user_id'], $user_id)->fetch_assoc();
|
||||||
$user = exec_stmt('SELECT user_id, username, email, role_id, created_at, last_active, is_active, profile_picture FROM user WHERE user_id = ?', 'i', $user_id)->fetch_assoc();
|
$user = exec_stmt('SELECT user_id, username, email, role_id, created_at, last_active, is_active, profile_picture FROM user WHERE user_id = ?', 'i', $user_id)->fetch_assoc();
|
||||||
|
|
||||||
if ($user == null)
|
if ($user == null)
|
||||||
header('Location: articles.php');
|
header('Location: articles.php?view=sort&sort=newest');
|
||||||
|
|
||||||
$view = '
|
$view = '
|
||||||
<div class="user_view">
|
<div class="user_view">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<h1>' . $user['username'] . '</h1>
|
<div class="row">
|
||||||
|
<h1>' . $user['username'] . '</h1>
|
||||||
|
';
|
||||||
|
|
||||||
|
if ($_SESSION['user_id'] != $user_id && !$following) {
|
||||||
|
$view .= '
|
||||||
|
<div class="dropdown">
|
||||||
|
<span>Follow</span>
|
||||||
|
<div class="dropdown_content">
|
||||||
|
<form method="post">
|
||||||
|
<input type="hidden" name="form_id" value="follow">
|
||||||
|
<input type="hidden" name="author_id" value="' . $user_id . '">
|
||||||
|
<button name="follow" value="no_notify" class="button"><i class="nf nf-md-bell_cancel"></i></button>
|
||||||
|
<button name="follow" value="email_notify" class="button"><i class="nf nf-cod-mail"></i></button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
';
|
||||||
|
} else if ($following) {
|
||||||
|
$view .= '
|
||||||
|
<div class="margin_right">
|
||||||
|
<form method="post">
|
||||||
|
<input type="hidden" name="form_id" value="unfollow">
|
||||||
|
<input type="hidden" name="author_id" value="' . $user_id . '">
|
||||||
|
<input type="submit" value="Unfollow">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
';
|
||||||
|
}
|
||||||
|
|
||||||
|
$view .= '
|
||||||
|
</div>
|
||||||
<div class="card_pic_box">
|
<div class="card_pic_box">
|
||||||
<img src="' . $_ENV['PROFILE_IMAGES_PQ_PATH'] . $user['profile_picture'] . '" class="profile_picture" />
|
<img src="' . $_ENV['PROFILE_IMAGES_PQ_PATH'] . $user['profile_picture'] . '" class="profile_picture" />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+37
-12
@@ -31,7 +31,8 @@ a,
|
|||||||
.modal_button,
|
.modal_button,
|
||||||
th,
|
th,
|
||||||
td,
|
td,
|
||||||
li {
|
li,
|
||||||
|
span {
|
||||||
font-family: 'Hack Nerd Font Mono', Hack, sans-serif;
|
font-family: 'Hack Nerd Font Mono', Hack, sans-serif;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@@ -65,7 +66,8 @@ a,
|
|||||||
label,
|
label,
|
||||||
li,
|
li,
|
||||||
.modal_button,
|
.modal_button,
|
||||||
.button {
|
.button,
|
||||||
|
span {
|
||||||
font-size: 1vw;
|
font-size: 1vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,10 +287,6 @@ table tr td label {
|
|||||||
border: 3px solid orange;
|
border: 3px solid orange;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button:hover {
|
|
||||||
box-shadow: 0 2px 4px 0 rgba(255, 165, 0, 0.3), 0 3px 8px 0 rgba(255, 165, 0, 0.7);
|
|
||||||
}
|
|
||||||
|
|
||||||
.narrow {
|
.narrow {
|
||||||
width: 20%;
|
width: 20%;
|
||||||
}
|
}
|
||||||
@@ -301,10 +299,6 @@ table tr td label {
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tag:hover {
|
|
||||||
box-shadow: 0 2px 4px 0 rgba(255, 165, 0, 0.3), 0 3px 8px 0 rgba(255, 165, 0, 0.7);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag_row {}
|
.tag_row {}
|
||||||
|
|
||||||
.tag_box {
|
.tag_box {
|
||||||
@@ -383,7 +377,6 @@ textarea:focus,
|
|||||||
input:hover,
|
input:hover,
|
||||||
textarea:hover {
|
textarea:hover {
|
||||||
border: 3px solid orange;
|
border: 3px solid orange;
|
||||||
box-shadow: 0 2px 4px 0 rgba(255, 165, 0, 0.3), 0 3px 8px 0 rgba(255, 165, 0, 0.7);
|
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -734,6 +727,37 @@ hr {
|
|||||||
border-radius: 9px;
|
border-radius: 9px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dropdown {
|
||||||
|
position: relative;
|
||||||
|
display: block;
|
||||||
|
margin-right: 15px;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 9px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown_content {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
min-width: 50px;
|
||||||
|
padding: 15px;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown:hover .dropdown_content {
|
||||||
|
display: block;
|
||||||
|
margin-left: -15px;
|
||||||
|
margin-top: 15px;
|
||||||
|
border-radius: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown_content form * {
|
||||||
|
margin-top: 5px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin_right {
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 992px) {
|
@media screen and (max-width: 992px) {
|
||||||
body {
|
body {
|
||||||
@@ -772,7 +796,8 @@ hr {
|
|||||||
ul li a,
|
ul li a,
|
||||||
ol li a,
|
ol li a,
|
||||||
.modal_button,
|
.modal_button,
|
||||||
.button {
|
.button,
|
||||||
|
span {
|
||||||
font-size: 2vw;
|
font-size: 2vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+14
-4
@@ -13,7 +13,8 @@ h4,
|
|||||||
h5,
|
h5,
|
||||||
p,
|
p,
|
||||||
small,
|
small,
|
||||||
label {
|
label,
|
||||||
|
span {
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,9 +55,9 @@ table tr {
|
|||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button:hover {
|
.button:hover,
|
||||||
color: black;
|
.button:hover i {
|
||||||
background-color: white;
|
color: orange;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tag {
|
.tag {
|
||||||
@@ -139,6 +140,15 @@ select:-webkit-autofill {
|
|||||||
border: 2px solid orange;
|
border: 2px solid orange;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dropdown {
|
||||||
|
border: 2px solid white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown_content {
|
||||||
|
background-color: black;
|
||||||
|
border: 2px solid white;
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 992px) {
|
@media screen and (max-width: 992px) {
|
||||||
nav {
|
nav {
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
|
|||||||
+14
-4
@@ -13,7 +13,8 @@ h4,
|
|||||||
h5,
|
h5,
|
||||||
p,
|
p,
|
||||||
small,
|
small,
|
||||||
label {
|
label,
|
||||||
|
span {
|
||||||
color: black;
|
color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,9 +55,9 @@ table tr {
|
|||||||
color: black;
|
color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button:hover {
|
.button:hover,
|
||||||
color: white;
|
.button:hover * {
|
||||||
background-color: black;
|
color: orange;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tag {
|
.tag {
|
||||||
@@ -139,6 +140,15 @@ select:-webkit-autofill {
|
|||||||
border: 2px solid orange;
|
border: 2px solid orange;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dropdown {
|
||||||
|
border: 2px solid black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown_content {
|
||||||
|
background-color: white;
|
||||||
|
border: 2px solid black;
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 992px) {
|
@media screen and (max-width: 992px) {
|
||||||
nav {
|
nav {
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
|
|||||||
@@ -4,6 +4,16 @@ require_once 'article_functions.php';
|
|||||||
|
|
||||||
use Postmark\PostmarkClient;
|
use Postmark\PostmarkClient;
|
||||||
|
|
||||||
|
function follow_user($follower_user_id, $following_user_id, $notify)
|
||||||
|
{
|
||||||
|
exec_stmt('INSERT INTO follows (follower_user_id, following_user_id, notify_user) VALUES (?, ?, ?)', 'iii', $follower_user_id, $following_user_id, $notify);
|
||||||
|
}
|
||||||
|
|
||||||
|
function unfollow_user($follower_user_id, $following_user_id)
|
||||||
|
{
|
||||||
|
exec_stmt('DELETE FROM follows WHERE follower_user_id = ? AND following_user_id = ?', 'ii', $follower_user_id, $following_user_id);
|
||||||
|
}
|
||||||
|
|
||||||
function user_id_exists($user_id)
|
function user_id_exists($user_id)
|
||||||
{
|
{
|
||||||
$result = exec_stmt('SELECT user_id FROM user WHERE user_id = ?', 'i', $user_id)->fetch_assoc();
|
$result = exec_stmt('SELECT user_id FROM user WHERE user_id = ?', 'i', $user_id)->fetch_assoc();
|
||||||
|
|||||||
+36
-18
@@ -1,17 +1,36 @@
|
|||||||
<?php
|
<?php
|
||||||
|
include_once 'functions/init.php';
|
||||||
|
|
||||||
if (!empty($_FILES['upload'])) {
|
use Postmark\PostmarkClient;
|
||||||
require_once '../vendor/autoload.php';
|
|
||||||
|
|
||||||
// Load environment variables.
|
if (!empty($_FILES['upload']))
|
||||||
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/../');
|
|
||||||
$dotenv->safeLoad();
|
|
||||||
upload($_FILES['upload'], $_ENV['UPLOAD_TMP_FQ_PATH'], isset($_POST['filename']) ? $_POST['filename'] : null);
|
upload($_FILES['upload'], $_ENV['UPLOAD_TMP_FQ_PATH'], isset($_POST['filename']) ? $_POST['filename'] : null);
|
||||||
|
|
||||||
|
function notify_users($emails, $auther_username, $article_id, $article_title, $excerpt)
|
||||||
|
{
|
||||||
|
foreach ($emails as $email) {
|
||||||
|
$email_html = '
|
||||||
|
<h1>' . $article_title . '</h1>
|
||||||
|
<p>An author you follow just published a new article! Read it <a href="https://vintagecoding.net/articles.php?view=read&article_id=' . $article_id . '" target="_blank">here</a></p>
|
||||||
|
<p><strong>Here is a snippet from the article!</strong></p>
|
||||||
|
<p>' . $excerpt . '</p>
|
||||||
|
';
|
||||||
|
|
||||||
|
$client = new PostmarkClient($_ENV['POSTMARK_API_TOKEN']);
|
||||||
|
|
||||||
|
$client->sendEmail(
|
||||||
|
'mailer@joshashton.dev',
|
||||||
|
$email,
|
||||||
|
$auther_username . ' just published a new article! - vintagecoding.net',
|
||||||
|
$email_html
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function delete_dir($dir)
|
function delete_dir($dir)
|
||||||
{
|
{
|
||||||
if (!is_dir($dir)) return false;
|
if (!is_dir($dir))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (substr($dir, strlen($dir) - 1, 1) != '/') {
|
if (substr($dir, strlen($dir) - 1, 1) != '/') {
|
||||||
$dir .= '/';
|
$dir .= '/';
|
||||||
@@ -28,7 +47,8 @@ function delete_dir($dir)
|
|||||||
|
|
||||||
function delete_file($file)
|
function delete_file($file)
|
||||||
{
|
{
|
||||||
if (!file_exists($file)) return false;
|
if (!file_exists($file))
|
||||||
|
return false;
|
||||||
|
|
||||||
unlink($file);
|
unlink($file);
|
||||||
}
|
}
|
||||||
@@ -54,7 +74,7 @@ function upload($input, $dest_dir, $filename = null)
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
# code...
|
// code...
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,7 +86,7 @@ function upload($input, $dest_dir, $filename = null)
|
|||||||
|
|
||||||
function crop_image($img_path, $x, $y, $height, $width)
|
function crop_image($img_path, $x, $y, $height, $width)
|
||||||
{
|
{
|
||||||
//$dest = $_ENV['UPLOAD_TMP_FQ_PATH'];
|
// $dest = $_ENV['UPLOAD_TMP_FQ_PATH'];
|
||||||
$dest = '/tmp/';
|
$dest = '/tmp/';
|
||||||
// Get the image type
|
// Get the image type
|
||||||
$imageType = exif_imagetype($img_path);
|
$imageType = exif_imagetype($img_path);
|
||||||
@@ -80,11 +100,11 @@ function crop_image($img_path, $x, $y, $height, $width)
|
|||||||
$sourceImage = imagecreatefrompng($img_path);
|
$sourceImage = imagecreatefrompng($img_path);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return false; // Unsupported image type
|
return false; // Unsupported image type
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$sourceImage)
|
if (!$sourceImage)
|
||||||
return false; // Failed to create image resource
|
return false; // Failed to create image resource
|
||||||
|
|
||||||
// Create a new image resource for the cropped image
|
// Create a new image resource for the cropped image
|
||||||
$croppedImage = imagecreatetruecolor($width, $height);
|
$croppedImage = imagecreatetruecolor($width, $height);
|
||||||
@@ -109,7 +129,7 @@ function crop_image($img_path, $x, $y, $height, $width)
|
|||||||
imagedestroy($sourceImage);
|
imagedestroy($sourceImage);
|
||||||
imagedestroy($croppedImage);
|
imagedestroy($croppedImage);
|
||||||
|
|
||||||
return true; // Cropping successful
|
return true; // Cropping successful
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -132,7 +152,7 @@ function extract_content_from_tag($string, $start, $end)
|
|||||||
{
|
{
|
||||||
$ini = strpos($string, $start);
|
$ini = strpos($string, $start);
|
||||||
if ($ini != 0)
|
if ($ini != 0)
|
||||||
return "nope";
|
return 'nope';
|
||||||
|
|
||||||
$ini += strlen($start);
|
$ini += strlen($start);
|
||||||
$len = strpos($string, $end, $ini) - $ini;
|
$len = strpos($string, $end, $ini) - $ini;
|
||||||
@@ -151,9 +171,7 @@ function check_csv_upload($target)
|
|||||||
|
|
||||||
function pretty_dump($arr)
|
function pretty_dump($arr)
|
||||||
{
|
{
|
||||||
echo '
|
echo '<pre>';
|
||||||
<pre>
|
print_r($arr);
|
||||||
' . print_r($arr) . '
|
echo '</pre>';
|
||||||
</pre>
|
|
||||||
';
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,16 @@ CREATE TABLE article_tags (
|
|||||||
FOREIGN KEY (tag_id) REFERENCES tags(tag_id)
|
FOREIGN KEY (tag_id) REFERENCES tags(tag_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE follows (
|
||||||
|
follower_user_id INT NOT NULL,
|
||||||
|
following_user_id INT NOT NULL,
|
||||||
|
notify_user BOOLEAN DEFAULT FALSE,
|
||||||
|
followed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
PRIMARY KEY (follower_user_id, following_user_id),
|
||||||
|
FOREIGN KEY (follower_user_id) REFERENCES user(user_id) ON DELETE CASCADE,
|
||||||
|
FOREIGN KEY (following_user_id) REFERENCES user(user_id) ON DELETE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
INSERT INTO roles (role)
|
INSERT INTO roles (role)
|
||||||
VALUES ('owner'), ('admin'), ('contributor'), ('reader');
|
VALUES ('owner'), ('admin'), ('contributor'), ('reader');
|
||||||
|
|
||||||
|
|||||||
@@ -82,6 +82,12 @@ if (isset($_POST['form_id'])) {
|
|||||||
$_POST['delete_verify_password']
|
$_POST['delete_verify_password']
|
||||||
);
|
);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 'follow':
|
||||||
|
follow_user($_SESSION['user_id'], $_POST['author_id'], ($_POST['follow'] == 'email_notify' ? 1 : 0));
|
||||||
|
break;
|
||||||
|
case 'unfollow':
|
||||||
|
unfollow_user($_SESSION['user_id'], $_POST['author_id']);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
echo $msg;
|
echo $msg;
|
||||||
|
|||||||
Reference in New Issue
Block a user