Used CKEditor for being able to edit the post body. Added the ability to make a post and send it to the backend. Formatted post on backend by moving images into respective directory with the post name and unique ID. Showed message if errored or succeeded.

Signed-off-by: rodude123 <rodude123@gmail.com>
This commit is contained in:
2023-06-26 03:54:25 +01:00
parent 88c5cc9508
commit 61b8d3a987
174 changed files with 895 additions and 187 deletions
+123 -8
View File
@@ -1,8 +1,12 @@
<?php
namespace api\blog;
use api\utils\imgUtils;
use DOMDocument;
use PDO;
use Psr\Http\Message\UploadedFileInterface;
require_once __DIR__ . "/../utils/config.php";
require_once __DIR__ . "/../utils/imgUtils.php";
/**
* Blog Data Class
@@ -14,10 +18,10 @@ class blogData
* Get all blog posts
* @return array - Array of all blog posts or error message
*/
function getBlogPosts(): array
public function getBlogPosts(): array
{
$conn = dbConn();
$stmt = $conn->prepare("SELECT ID, title, dateCreated, dateModified, body, tags FROM blog ORDER BY dateCreated DESC;");
$stmt = $conn->prepare("SELECT ID, title, dateCreated, dateModified, body, categories FROM blog ORDER BY dateCreated DESC;");
$stmt->execute();
// set the resulting array to associative
@@ -36,10 +40,10 @@ class blogData
* @param string $ID - ID of the blog post to get
* @return array - Array of all blog posts or error message
*/
function getBlogPost(string $ID): array
public function getBlogPost(string $ID): array
{
$conn = dbConn();
$stmt = $conn->prepare("SELECT ID, title, dateCreated, dateModified, featured, headerImg, body, tags FROM blog WHERE ID = :ID;");
$stmt = $conn->prepare("SELECT ID, title, dateCreated, dateModified, featured, headerImg, body, categories FROM blog WHERE ID = :ID;");
$stmt->bindParam(":ID", $ID);
$stmt->execute();
@@ -58,10 +62,10 @@ class blogData
* Get the latest blog post
* @return array - Array of the latest blog post or error message
*/
function getLatestBlogPost(): array
public function getLatestBlogPost(): array
{
$conn = dbConn();
$stmt = $conn->prepare("SELECT ID, title, dateCreated, dateModified, featured, headerImg, body, tags FROM blog ORDER BY dateCreated DESC LIMIT 1;");
$stmt = $conn->prepare("SELECT ID, title, dateCreated, dateModified, featured, headerImg, body, categories FROM blog ORDER BY dateCreated DESC LIMIT 1;");
$stmt->execute();
// set the resulting array to associative
@@ -79,10 +83,10 @@ class blogData
* Get featured blog post
* @return array - Array of the featured blog post or error message
*/
function getFeaturedBlogPost(): array
public function getFeaturedBlogPost(): array
{
$conn = dbConn();
$stmt = $conn->prepare("SELECT ID, title, dateCreated, dateModified, featured, headerImg, body, tags FROM blog WHERE featured = 1;");
$stmt = $conn->prepare("SELECT ID, title, dateCreated, dateModified, featured, headerImg, body, categories FROM blog WHERE featured = 1;");
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_ASSOC);
@@ -94,4 +98,115 @@ class blogData
return array("errorMessage" => "Error, blog post could not found");
}
/**
* Upload the images in the post to temp folder and return image location
* @param UploadedFileInterface $img - Image to upload
* @return string|array - String with error message or array with the location of the uploaded file
*/
public function uploadPostImage(UploadedFileInterface $img): string|array
{
$targetDir = "../blog/imgs/tmp/";
$imagUtils = new imgUtils();
$targetFile = $imagUtils->uploadFile($targetDir, $img);
$file = $targetDir . basename($img->getClientFilename());
if (file_exists($file))
{
return array("url" => $file);
}
if (!is_array($targetFile))
{
return $targetFile;
}
if (file_exists($targetFile["imgLocation"]))
{
return array("url" => $targetFile["imgLocation"]);
}
return "Couldn't upload the image";
}
/**
* Creates a new post directory, uploads the header image and moves the images from the
* temp folder to the new folder, then updates the post html to point to the new images, finally
* it creates the post in the database
* @param string $title - Title of the blog post
* @param string $body - Body of the blog post
* @param string $dateCreated - Date the blog post was created
* @param string $featured - Whether the blog post is featured or not
* @param string $categories - Categories of the blog post
* @param UploadedFileInterface $headerImg - Header image of the blog post
* @return int|string - ID of the blog post or error message
*/
public function createPost(string $title, string $body, string $dateCreated, string $featured, string $categories, UploadedFileInterface $headerImg): int|string
{
$conn = dbConn();
$targetDir = "../blog/imgs/" . $title . "_" . uniqid() . "/";
mkdir($targetDir, 0777, true);
$imagUtils = new imgUtils();
$targetFile = $imagUtils->uploadFile($targetDir, $headerImg);
if (!is_array($targetFile))
{
return $targetFile;
}
$htmlDoc = new DOMDocument();
$htmlDoc->loadHTML($body, LIBXML_NOERROR);
$doc = $htmlDoc->getElementsByTagName('body')->item(0);
$imgs = $doc->getElementsByTagName('img');
$srcList = array();
foreach ($imgs as $img)
{
$src = $img->getAttribute("src");
$srcList[] = $src;
$fileName = basename($src);
$img->setAttribute("src", $targetDir . $fileName);
}
$files = scandir("../blog/imgs/tmp/");
foreach ($files as $file)
{
if ($file != "." && $file != "..")
{
if (!in_array("../blog/imgs/tmp/" . $file, $srcList))
{
unlink("../blog/imgs/tmp/" . $file);
}
else
{
rename("../blog/imgs/tmp/" . $file, $targetDir . $file);
}
}
}
$newBody = '';
foreach ($doc->childNodes as $node)
{
$newBody .= $htmlDoc->saveHTML($node);
}
$stmt = $conn->prepare("INSERT INTO blog (title, dateCreated, dateModified, featured, headerImg, body, categories)
VALUES (:title, :dateCreated, :dateModified, :featured, :headerImg, :body, :categories);");
$stmt->bindParam(":title", $title);
$stmt->bindParam(":dateCreated", $dateCreated);
$stmt->bindParam(":dateModified", $dateCreated);
$stmt->bindParam(":featured", $featured);
$stmt->bindParam(":headerImg", $targetFile["imgLocation"]);
$stmt->bindParam(":body", $newBody);
$stmt->bindParam(":categories", $categories);
if ($stmt->execute())
{
return intval($conn->lastInsertId());
}
return "Error, couldn't create post";
}
}
+43 -2
View File
@@ -12,7 +12,6 @@ use Slim\App;
class blogRoutes implements routesInterface
{
private blogData $blogData;
/**
* constructor used to instantiate a base blog routes, to be used in the index.php file.
* @param App $app - the slim app used to create the routes
@@ -30,6 +29,48 @@ class blogRoutes implements routesInterface
*/
public function createRoutes(App $app): void
{
// TODO: Implement createRoutes() method.
$app->post("/blog/post", function (Request $request, Response $response, array $args)
{
$data = $request->getParsedBody();
$files = $request->getUploadedFiles();
if (empty($data["title"]) || empty($data["body"]) || empty($data["dateCreated"]) || empty($data["featured"]) || empty($data["categories"]) || empty($files["headerImg"]))
{
// uh oh sent some empty data
$response->getBody()->write(json_encode(array("error" => "Error, empty data sent")));
return $response->withStatus(400);
}
$insertedID = $this->blogData->createPost($data["title"], $data["body"], $data["dateCreated"], $data["featured"], $data["categories"], $files["headerImg"]);
if (!is_int($insertedID))
{
// uh oh something went wrong
$response->getBody()->write(json_encode(array("error" => $insertedID)));
return $response->withStatus(500);
}
$response->getBody()->write(json_encode(array("ID" => $insertedID)));
return $response->withStatus(201);
});
$app->post("/blog/uploadPostImage", function (Request $request, Response $response)
{
$files = $request->getUploadedFiles();
if (empty($files))
{
// uh oh sent some empty data
$response->getBody()->write(json_encode(array("error" => array("message" => "Error, empty data sent"))));
return $response->withStatus(400);
}
$message = $this->blogData->uploadPostImage($files["upload"]);
if (!is_array($message))
{
$response->getBody()->write(json_encode(array("error" => array("message" => $message))));
return $response->withStatus(500);
}
$response->getBody()->write(json_encode($message));
return $response->withStatus(201);
});
}
}