2023-06-06 16:04:39 +01:00
< ? php
2023-06-08 15:10:27 +01:00
namespace api\blog ;
2023-06-26 03:54:25 +01:00
use api\utils\imgUtils ;
use DOMDocument ;
2023-06-06 16:04:39 +01:00
use PDO ;
2023-06-26 03:54:25 +01:00
use Psr\Http\Message\UploadedFileInterface ;
2023-06-06 16:04:39 +01:00
2023-06-08 15:10:27 +01:00
require_once __DIR__ . " /../utils/config.php " ;
2023-06-26 03:54:25 +01:00
require_once __DIR__ . " /../utils/imgUtils.php " ;
2023-06-06 16:04:39 +01:00
/**
* Blog Data Class
* Define all functions which either get , update , create or delete posts
*/
class blogData
{
/**
* Get all blog posts
* @ return array - Array of all blog posts or error message
*/
2023-06-26 03:54:25 +01:00
public function getBlogPosts () : array
2023-06-06 16:04:39 +01:00
{
$conn = dbConn ();
2023-10-18 00:28:34 +01:00
$stmt = $conn -> prepare ( " SELECT * FROM blog ORDER BY dateCreated DESC; " );
2023-06-06 16:04:39 +01:00
$stmt -> execute ();
// set the resulting array to associative
$result = $stmt -> fetchAll ( PDO :: FETCH_ASSOC );
if ( $result )
{
return $result ;
}
return array ( " errorMessage " => " Error, blog data not found " );
}
/**
* Get a blog post with the given ID
2023-10-18 00:28:34 +01:00
* @ param string $title - Title of the blog post
2023-06-06 16:04:39 +01:00
* @ return array - Array of all blog posts or error message
*/
2023-10-18 00:28:34 +01:00
public function getBlogPost ( string $title ) : array
2023-06-06 16:04:39 +01:00
{
$conn = dbConn ();
2023-10-18 00:28:34 +01:00
$stmt = $conn -> prepare ( " SELECT * FROM blog WHERE title = :title; " );
$stmt -> bindParam ( " :title " , $title );
2023-06-06 16:04:39 +01:00
$stmt -> execute ();
// set the resulting array to associative
$result = $stmt -> fetch ( PDO :: FETCH_ASSOC );
if ( $result )
{
return $result ;
}
return array ( " errorMessage " => " Error, blog post could not found " );
}
/**
* Get the latest blog post
* @ return array - Array of the latest blog post or error message
*/
2023-06-26 03:54:25 +01:00
public function getLatestBlogPost () : array
2023-06-06 16:04:39 +01:00
{
$conn = dbConn ();
2023-10-18 00:28:34 +01:00
$stmt = $conn -> prepare ( " SELECT * FROM blog ORDER BY dateCreated DESC LIMIT 1; " );
2023-06-06 16:04:39 +01:00
$stmt -> execute ();
// set the resulting array to associative
$result = $stmt -> fetch ( PDO :: FETCH_ASSOC );
if ( $result )
{
return $result ;
}
return array ( " errorMessage " => " Error, blog post could not found " );
}
/**
* Get featured blog post
* @ return array - Array of the featured blog post or error message
*/
2023-06-26 03:54:25 +01:00
public function getFeaturedBlogPost () : array
2023-06-06 16:04:39 +01:00
{
$conn = dbConn ();
2023-10-18 00:28:34 +01:00
$stmt = $conn -> prepare ( " SELECT * FROM blog WHERE featured = 1; " );
2023-06-06 16:04:39 +01:00
$stmt -> execute ();
$result = $stmt -> fetch ( PDO :: FETCH_ASSOC );
if ( $result )
{
return $result ;
}
return array ( " errorMessage " => " Error, blog post could not found " );
}
2023-06-26 03:54:25 +01:00
2023-10-18 00:28:34 +01:00
/**
* Get the blog posts with the given category
* @ param string $category - Category of the blog post
* @ return array - Array of the blog posts with the given category or error message
*/
public function getBlogPostsWithCategory ( string $category ) : array
{
$conn = dbConn ();
$stmt = $conn -> prepare ( " SELECT * FROM blog WHERE categories LIKE :category; " );
$stmt -> bindParam ( " :category " , $category );
$stmt -> execute ();
// set the resulting array to associative
$result = $stmt -> fetchAll ( PDO :: FETCH_ASSOC );
if ( $result )
{
return $result ;
}
return array ( " errorMessage " => " Error, blog post could not found " );
}
public function getCategories () : array
{
$conn = dbConn ();
$stmt = $conn -> prepare ( " SELECT categories FROM blog; " );
$stmt -> execute ();
// set the resulting array to associative
$result = $stmt -> fetchAll ( PDO :: FETCH_ASSOC );
if ( $result )
{
return $result ;
}
return array ( " errorMessage " => " Error, blog post could not found " );
}
2023-07-12 03:29:56 +01:00
/**
* Delete a blog post with the given ID
* @ param int $ID - ID of the blog post to delete
* @ return string - Success or error message
*/
public function deletePost ( int $ID ) : string
{
$conn = dbConn ();
$stmtCheckPost = $conn -> prepare ( " SELECT * FROM blog WHERE ID = :ID " );
$stmtCheckPost -> bindParam ( " :ID " , $ID );
$stmtCheckPost -> execute ();
$result = $stmtCheckPost -> fetch ( PDO :: FETCH_ASSOC );
if ( ! $result )
{
return " post not found " ;
}
if ( $result [ " featured " ] === 1 )
{
return " cannot delete " ;
}
$stmt = $conn -> prepare ( " DELETE FROM blog WHERE ID = :ID " );
$stmt -> bindParam ( " :ID " , $ID );
if ( $stmt -> execute ())
{
$imagUtils = new imgUtils ();
$imagUtils -> deleteDirectory ( " ../blog/imgs/ " . $result [ " title " ] . " _ " . $result [ " folderID " ] . " / " );
return " success " ;
}
return " error " ;
}
/**
* Update the blog post with the given ID
* @ param int $ID - ID of the blog post to update
* @ param string $title - Title of the blog post
* @ param bool $featured - Whether the blog post is featured or not
2023-10-18 00:28:34 +01:00
* @ param string $abstract - Abstract of the blog post i . e . a short description
2023-07-12 03:29:56 +01:00
* @ param string $body - Body of the blog post
* @ param string $dateModified - Date the blog post was modified
* @ param string $categories - Categories of the blog post
* @ return bool | string - Success or error message
*/
2023-10-18 00:28:34 +01:00
public function updatePost ( int $ID , string $title , bool $featured , string $abstract , string $body , string $dateModified , string $categories ) : bool | string
2023-07-12 03:29:56 +01:00
{
$conn = dbConn ();
$stmtCheckPost = $conn -> prepare ( " SELECT * FROM blog WHERE ID = :ID " );
$stmtCheckPost -> bindParam ( " :ID " , $ID );
$stmtCheckPost -> execute ();
$result = $stmtCheckPost -> fetch ( PDO :: FETCH_ASSOC );
if ( ! $result )
{
return " post not found " ;
}
if ( ! $featured && $result [ " featured " ] === 1 )
{
return " unset feature " ;
}
if ( $featured )
{
$stmtUnsetFeatured = $conn -> prepare ( " UPDATE blog SET featured = 0 WHERE featured = 1; " );
$stmtUnsetFeatured -> execute ();
}
$to = " ../blog/imgs/ " . $title . " _ " . $result [ " folderID " ] . " / " ;
if ( $result [ " title " ] !== $title )
{
$from = " ../blog/imgs/ " . $result [ " title " ] . " _ " . $result [ " folderID " ] . " / " ;
mkdir ( $to , 0777 , true );
rename ( $result [ " headerImg " ], $to . basename ( $result [ " headerImg " ]));
$body = $this -> changeHTMLSrc ( $body , $to , $from );
rmdir ( $from );
}
$from = " ../blog/imgs/tmp/ " ;
$newBody = $this -> changeHTMLSrc ( $body , $to , $from );
2023-10-18 00:28:34 +01:00
$stmt = $conn -> prepare ( " UPDATE blog SET title = :title, featured = :featured, abstract = :abstract, body = :body, dateModified = :dateModified, categories = :categories WHERE ID = :ID; " );
2023-07-12 03:29:56 +01:00
$stmt -> bindParam ( " :ID " , $ID );
$stmt -> bindParam ( " :title " , $title );
$stmt -> bindParam ( " :featured " , $featured );
2023-10-18 00:28:34 +01:00
$stmt -> bindParam ( " :abstract " , $abstract );
2023-07-12 03:29:56 +01:00
$stmt -> bindParam ( " :body " , $newBody );
$stmt -> bindParam ( " :dateModified " , $dateModified );
$stmt -> bindParam ( " :categories " , $categories );
return $stmt -> execute ();
}
/**
* Creates a new post di rectory , 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
2023-10-18 00:28:34 +01:00
* @ param string $abstract - Abstract of the blog post i . e . a short description
2023-07-12 03:29:56 +01:00
* @ param string $body - Body of the blog post
* @ param string $dateCreated - Date the blog post was created
* @ param bool $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
*/
2023-10-18 00:28:34 +01:00
public function createPost ( string $title , string $abstract , string $body , string $dateCreated , bool $featured , string $categories , UploadedFileInterface $headerImg ) : int | string
2023-07-12 03:29:56 +01:00
{
$conn = dbConn ();
$folderID = uniqid ();
$targetFile = array ( " imgLocation " => " ../blog/imgs/placeholder.png " );
$targetDir = " ../blog/imgs/ " . $title . " _ " . $folderID . " / " ;
mkdir ( $targetDir , 0777 , true );
if ( $headerImg !== null )
{
$imagUtils = new imgUtils ();
$targetFile = $imagUtils -> uploadFile ( $targetDir , $headerImg );
}
if ( ! is_array ( $targetFile ))
{
return $targetFile ;
}
$newBody = $this -> changeHTMLSrc ( $body , $targetDir , " ../blog/imgs/tmp/ " );
if ( $featured )
{
$stmtMainProject = $conn -> prepare ( " UPDATE blog SET featured = 0 WHERE featured = 1; " );
$stmtMainProject -> execute ();
}
2023-10-18 00:28:34 +01:00
$stmt = $conn -> prepare ( " INSERT INTO blog (title, dateCreated, dateModified, featured, headerImg, abstract, body, categories, folderID)
VALUES ( : title , : dateCreated , : dateModified , : featured , : headerImg , : abstract , : body , : categories , : folderID ); " );
2023-07-12 03:29:56 +01:00
$stmt -> bindParam ( " :title " , $title );
$stmt -> bindParam ( " :dateCreated " , $dateCreated );
$stmt -> bindParam ( " :dateModified " , $dateCreated );
$isFeatured = $featured ? 1 : 0 ;
$stmt -> bindParam ( " :featured " , $isFeatured );
$stmt -> bindParam ( " :headerImg " , $targetFile [ " imgLocation " ]);
2023-10-18 00:28:34 +01:00
$stmt -> bindParam ( " :abstract " , $abstract );
2023-07-12 03:29:56 +01:00
$stmt -> bindParam ( " :body " , $newBody );
$stmt -> bindParam ( " :categories " , $categories );
$stmt -> bindParam ( " :folderID " , $folderID );
if ( $stmt -> execute ())
{
return intval ( $conn -> lastInsertId ());
}
return " Error, couldn't create post " ;
}
2023-06-26 03:54:25 +01:00
/**
* 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 " ;
}
/**
2023-07-12 03:29:56 +01:00
* Upload the header image of the post and update the database
* @ param int $ID - ID of the post
* @ param UploadedFileInterface $img - Image to upload
* @ return string | array - String with error message or array with the location of the uploaded file
2023-06-26 03:54:25 +01:00
*/
2023-07-12 03:29:56 +01:00
public function uploadHeaderImage ( int $ID , UploadedFileInterface $img ) : string | array
2023-06-26 03:54:25 +01:00
{
$conn = dbConn ();
2023-07-12 03:29:56 +01:00
$stmt = $conn -> prepare ( " SELECT * FROM blog WHERE ID = :ID; " );
$stmt -> bindParam ( " :ID " , $ID );
$stmt -> execute ();
$result = $stmt -> fetch ( PDO :: FETCH_ASSOC );
if ( ! $result )
2023-06-26 16:52:48 +01:00
{
2023-07-12 03:29:56 +01:00
return " Couldn't find the post " ;
2023-06-26 16:52:48 +01:00
}
2023-07-12 03:29:56 +01:00
$targetDir = " ../blog/imgs/ " . $result [ " title " ] . " _ " . $result [ " folderID " ] . " / " ;
$imagUtils = new imgUtils ();
$targetFile = $imagUtils -> uploadFile ( $targetDir , $img );
2023-06-26 16:52:48 +01:00
2023-06-26 03:54:25 +01:00
if ( ! is_array ( $targetFile ))
{
return $targetFile ;
}
2023-07-12 03:29:56 +01:00
if ( file_exists ( $targetFile [ " imgLocation " ]))
{
unlink ( $result [ " headerImg " ]);
$stmt = $conn -> prepare ( " UPDATE blog SET headerImg = :headerImg WHERE ID = :ID; " );
$stmt -> bindParam ( " :ID " , $ID );
$stmt -> bindParam ( " :headerImg " , $targetFile [ " imgLocation " ]);
$stmt -> execute ();
if ( $stmt -> rowCount () > 0 )
{
return $targetFile ;
}
return " Couldn't update the post " ;
}
return " Couldn't upload the image " ;
}
/**
* Change the HTML src of the images in the post to point to the new location
* @ param string $body - Body of the post
* @ param string $to - New location of the images
* @ param string $from - Old location of the images
* @ return string - Body of the post with the new image locations
*/
public function changeHTMLSrc ( string $body , string $to , string $from ) : string
{
2023-06-26 03:54:25 +01:00
$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 " );
2023-07-12 03:29:56 +01:00
$src = urldecode ( $src );
2023-06-26 03:54:25 +01:00
$srcList [] = $src ;
$fileName = basename ( $src );
2023-10-18 00:28:34 +01:00
$img -> setAttribute ( " src " , substr ( $to , 2 ) . $fileName );
2023-06-26 03:54:25 +01:00
}
2023-07-12 03:29:56 +01:00
$files = scandir ( $from );
2023-06-26 03:54:25 +01:00
foreach ( $files as $file )
{
if ( $file != " . " && $file != " .. " )
{
2023-07-12 03:29:56 +01:00
if ( ! in_array ( $from . $file , $srcList ))
2023-06-26 03:54:25 +01:00
{
2023-07-12 03:29:56 +01:00
unlink ( $from . $file );
2023-06-26 03:54:25 +01:00
}
else
{
2023-10-18 00:28:34 +01:00
rename ( $from . $file , $to . $file );
2023-06-26 03:54:25 +01:00
}
}
}
$newBody = '' ;
foreach ( $doc -> childNodes as $node )
{
$newBody .= $htmlDoc -> saveHTML ( $node );
}
2023-07-12 03:29:56 +01:00
return $newBody ;
2023-06-26 03:54:25 +01:00
}
2023-10-18 00:28:34 +01:00
/**
* Get all posts with the given category
* @ param mixed $category - Category of the post
* @ return array - Array of all posts with the given category or error message
*/
public function getPostsByCategory ( mixed $category )
{
$conn = dbConn ();
$stmt = $conn -> prepare ( " SELECT * FROM blog WHERE categories = :category; " );
$stmt -> bindParam ( " :category " , $category );
$stmt -> execute ();
$result = $stmt -> fetchAll ( PDO :: FETCH_ASSOC );
}
2023-06-06 16:04:39 +01:00
}