2018-10-16 16:28:42 +00:00
< ? php
defined ( 'BASEPATH' ) OR exit ( 'No direct script access allowed' );
class PostsModel extends CI_Model
{
public function __construct ()
{
parent :: __construct ();
$this -> load -> model ( 'UserModel' , '' , TRUE );
$this -> load -> model ( 'NotificationModel' , '' , TRUE );
}
function addPost ( $userID , $content )
{
return $this -> addReply ( $userID , $content , NULL );
}
2019-01-08 21:42:54 +00:00
public function addReply ( $userID , $content , $replyToHashID )
2018-10-16 16:28:42 +00:00
{
$content = $this -> preparePostContent ( $content );
2019-01-08 21:42:54 +00:00
$hashID = $this -> generatePostHashID ( $userID , $content );
2018-10-16 16:28:42 +00:00
$replyTo = NULL ;
2019-01-08 21:42:54 +00:00
if ( $replyToHashID !== NULL ) {
$replyToID = $this -> db -> query ( 'SELECT ID FROM user_posts WHERE hashID = ?' , [ $replyToHashID ]) -> result_array ();
2018-10-16 16:28:42 +00:00
$replyTo = ! empty ( $replyToID ) ? $replyToID [ 0 ][ 'ID' ] : NULL ;
}
2019-01-08 21:42:54 +00:00
$this -> db -> query ( 'INSERT INTO user_posts (userID, content, hashID, replyToPostID) VALUES (?, ?, ?, ?)' , [ $userID , $content , $hashID , $replyTo ]);
2018-10-16 16:28:42 +00:00
2019-01-08 21:42:54 +00:00
$insertedPost = $this -> db -> query ( 'SELECT ID, userID FROM user_posts WHERE hashID = ?' , [ $hashID ]) -> result_array ();
$this -> addPostMentions ( $insertedPost [ 0 ][ 'ID' ], $content , $hashID );
2018-10-16 16:28:42 +00:00
$this -> addPostHashtags ( $insertedPost [ 0 ][ 'ID' ], $content );
// Send notification to user whose post was replied to
2019-01-08 21:42:54 +00:00
if ( $userID != $insertedPost [ 0 ][ 'userID' ]) {
$this -> NotificationModel -> userNotificationPostReply ( $userID , $insertedPost [ 0 ][ 'userID' ], $insertedPost [ 0 ][ 'ID' ], $hashID );
2018-10-16 16:28:42 +00:00
}
return $insertedPost [ 0 ][ 'ID' ];
}
public function preparePostContent ( $content )
{
if ( $this -> endsWith ( $content , '<br> ' )) {
$content = substr ( $content , 0 , strlen ( $content ) - 10 );
}
$content = htmlspecialchars ( $content );
return $content ;
}
function endsWith ( $haystack , $needle )
{
$length = strlen ( $needle );
return $length === 0 ||
( substr ( $haystack , - $length ) === $needle );
}
2019-01-08 21:42:54 +00:00
public function addPostMentions ( $postID , $content , $postHashID )
2018-10-16 16:28:42 +00:00
{
preg_match_all ( '/@([A-Za-z0-9._]+)/' , $content , $mentions , PREG_OFFSET_CAPTURE );
foreach ( $mentions [ 1 ] as $mention ) {
$mentionedUser = $this -> UserModel -> getUserIDByUsername ( strtolower ( $mention [ 0 ]));
if ( $mentionedUser == null ) {
continue ;
}
$mentionedUser = $mentionedUser [ 0 ];
2019-01-08 21:42:54 +00:00
$this -> addMention ( $postID , $_SESSION [ 'user' ][ 'ID' ], $mentionedUser [ 'ID' ], $mention [ 1 ], $postHashID );
2018-10-16 16:28:42 +00:00
}
}
2019-01-08 21:42:54 +00:00
public function addMention ( $postID , $userID , $mentionedUserID , $position , $postHashID )
2018-10-16 16:28:42 +00:00
{
$this -> db -> query ( 'INSERT INTO user_posts_mentions (userID, postID, mentionedUserID, position) VALUES (?, ?, ?, ?)' , [ $userID , $postID , $mentionedUserID , $position ]);
// Send notification
2019-01-08 21:42:54 +00:00
$this -> NotificationModel -> userNotificationPostMentioned ( $userID , $mentionedUserID , $postID , $postHashID );
2018-10-16 16:28:42 +00:00
}
public function addPostHashtags ( $postID , $content )
{
preg_match_all ( '/#([A-Za-z0-9]+)/' , $content , $hashtags , PREG_OFFSET_CAPTURE );
foreach ( $hashtags [ 1 ] as $hashtag ) {
$this -> addHashtag ( $postID , $_SESSION [ 'user' ][ 'ID' ], $hashtag [ 0 ], $hashtag [ 1 ]);
}
}
public function addHashtag ( $postID , $userID , $hashtag , $position )
{
$this -> db -> query ( 'INSERT INTO user_posts_hashtags (userID, postID, hashtag, position) VALUES (?, ?, ?, ?)' , [ $userID , $postID , $hashtag , $position ]);
}
2019-01-08 21:42:54 +00:00
public function deletePost ( $userID , $hashID )
{
$postID = $this -> db -> query ( 'SELECT ID FROM user_posts WHERE userID = ? AND hashID = ?' , [ $userID , $hashID ]) -> result_array ()[ 0 ][ 'ID' ];
$this -> db -> query ( 'DELETE FROM user_posts WHERE userID = ? AND hashID = ?' , [ $userID , $hashID ]);
$this -> db -> query ( 'DELETE FROM user_posts_hashtags WHERE postID = ?' , [ $postID ]);
$this -> db -> query ( 'DELETE FROM user_posts_mentions WHERE postID = ?' , [ $postID ]);
$this -> db -> query ( 'DELETE FROM user_posts_likes WHERE postID = ?' , [ $postID ]);
$this -> db -> query ( 'DELETE FROM user_posts_media WHERE postID = ?' , [ $postID ]);
}
public function addMediaToPost ( $postID , $type , $fileID )
{
$this -> db -> query ( 'INSERT INTO user_posts_media (postID, mediaType, fileID) VALUES (?, ?, ?)' , [ $postID , $type , $fileID ]);
}
function generatePostHashID ( $userID , $content )
{
return md5 ( $userID . $content . date ( " Y-m-d H:i:s " ));
}
2018-10-16 16:28:42 +00:00
function getUserPosts ( $id , $count , $offset , $maxLength = 250 )
{
$this -> db -> cache_off ();
2019-01-08 21:42:54 +00:00
$posts = $this -> db -> query ( 'SELECT * FROM user_posts p WHERE userID = ? ORDER BY date DESC LIMIT ? OFFSET ?' , [ $id , $count , $offset ]) -> result_array ();
2018-10-16 16:28:42 +00:00
$this -> db -> cache_on ();
$posts = $this -> preparePostList ( $posts , $maxLength );
return $posts ;
}
public function preparePostList ( $postList , $maxLength = 250 )
{
foreach ( $postList as $i => $post ) {
$post = $this -> mergePostUserData ( $post );
$post [ 'replyCount' ] = $this -> getPostReplyCountByID ( $post [ 'ID' ]);
$post [ 'likeCount' ] = $this -> getPostLikeCountByID ( $post [ 'ID' ]);
if ( $maxLength > 0 ) {
$post [ 'content' ] = strlen ( $post [ 'content' ]) > $maxLength ? substr ( $post [ 'content' ], 0 , $maxLength ) . '...' : $post [ 'content' ];
}
$post [ 'content' ] = $this -> mergePostMentionsHashtags ( $post [ 'ID' ], $post [ 'content' ]);
$post [ 'media' ] = $this -> getPostMedia ( $post [ 'ID' ]);
if ( isset ( $_SESSION [ 'user' ]) && ! empty ( $_SESSION [ 'user' ])) {
$post = $this -> mergeUserHasLiked ( $post , $_SESSION [ 'user' ][ 'ID' ]);
}
2019-01-08 21:42:54 +00:00
if ( $post [ 'replyToPostID' ] != NULL ) {
2018-10-16 16:28:42 +00:00
$post = $this -> mergeReplyData ( $post );
}
$postList [ $i ] = $post ;
}
$postList = $this -> UserModel -> setDefaultImages ( $postList );
return $postList ;
}
private function mergePostUserData ( $post )
{
2019-01-08 21:42:54 +00:00
$user = $this -> UserModel -> getUserByID ( $post [ 'userID' ]);
2018-10-16 16:28:42 +00:00
$user = $user [ 0 ];
$post [ 'username' ] = $user [ 'username' ];
$post [ 'displayname' ] = $user [ 'displayname' ];
2019-01-08 21:42:54 +00:00
$post [ 'profilePicture' ] = $user [ 'profilePicture' ];
2018-10-16 16:28:42 +00:00
return $post ;
}
public function getPostReplyCountByID ( $postID )
{
$this -> db -> cache_off ();
2019-01-08 21:42:54 +00:00
$data = $this -> db -> query ( 'SELECT count(*) replyCount FROM user_posts WHERE replyToPostID = ?' , [ $postID ]) -> result_array ();
2018-10-16 16:28:42 +00:00
$this -> db -> cache_on ();
return $data [ 0 ][ 'replyCount' ];
}
public function getPostLikeCountByID ( $id )
{
$this -> db -> cache_off ();
$data = $this -> db -> query ( 'SELECT count(*) likeCount FROM user_posts_likes WHERE postID = ?' , [ $id ]) -> result_array ();
$this -> db -> cache_on ();
return $data [ 0 ][ 'likeCount' ];
}
private function mergePostMentionsHashtags ( $postID , $content )
{
$mentions = $this -> db -> query ( 'SELECT m.*, u.username, u.displayname FROM user_posts_mentions m LEFT JOIN users u ON m.mentionedUserID = u.ID WHERE postID = ?' , [ $postID ]) -> result_array ();
$hashtags = $this -> db -> query ( 'SELECT * FROM user_posts_hashtags WHERE postID = ?' , [ $postID ]) -> result_array ();
$links = array_merge ( $mentions , $hashtags );
usort ( $links , function ( $a , $b ) {
return $a [ 'position' ] - $b [ 'position' ];
});
$finalContent = '' ;
$prevPos = 0 ;
foreach ( $links as $link ) {
$finalContent .= substr ( $content , $prevPos , $link [ 'position' ] - $prevPos - 1 );
if ( isset ( $link [ 'username' ])) { // Is link a mention?
$finalContent .= '<a href="' . base_url ( 'user/' . $link [ 'username' ]) . '">@' . $link [ 'displayname' ] . '</a>' ;
$prevPos = $link [ 'position' ] + strlen ( $link [ 'username' ]);
} else { // Link is a hashtag
$finalContent .= '<a href="' . base_url ( 'posts/search?q=%23' . $link [ 'hashtag' ] . '&type=type-posts' ) . '">#' . $link [ 'hashtag' ] . '</a>' ;
$prevPos = $link [ 'position' ] + strlen ( $link [ 'hashtag' ]);
}
if ( $prevPos > strlen ( $content )) {
break ;
}
}
$finalContent .= substr ( $content , $prevPos , strlen ( $content ) - $prevPos );
return $finalContent ;
}
2019-01-08 21:42:54 +00:00
public function getPostMedia ( $postID )
{
$result = $this -> db -> query ( 'SELECT m.mediaType type, f.name name FROM user_posts_media m LEFT JOIN files f ON f.ID = m.fileID WHERE postID = ?' , [ $postID ]) -> result_array ();
return $result ;
}
2018-10-16 16:28:42 +00:00
private function mergeUserHasLiked ( $post , $userID )
{
$this -> db -> cache_off ();
2019-01-08 21:42:54 +00:00
$data = $this -> db -> query ( 'SELECT * FROM user_posts_likes WHERE postID = (SELECT ID FROM user_posts WHERE hashID = ?) AND likerUserID = ?' , [ $post [ 'hashID' ], $userID ]) -> result_array ();
2018-10-16 16:28:42 +00:00
$this -> db -> cache_on ();
if ( empty ( $data )) {
$post [ 'userHasLiked' ] = FALSE ;
} else {
$post [ 'userHasLiked' ] = TRUE ;
}
return $post ;
}
2019-01-08 21:42:54 +00:00
private function mergeReplyData ( $post )
{
$data = $this -> db -> query ( 'SELECT p.* FROM user_posts p WHERE p.ID = ?' , [ $post [ 'replyToPostID' ]]) -> result_array ();
2018-10-27 10:08:54 +00:00
$data = $this -> preparePostList ( $data );
2019-01-08 21:42:54 +00:00
if ( ! empty ( $data )) {
2018-10-27 10:08:54 +00:00
$post [ 'replyToPost' ] = $data [ 0 ];
} else {
$post [ 'replyToPost' ] = [
'username' => '' ,
'displayname' => '' ,
'content' => 'Nicht existent' ,
'date' => '' ,
];
}
2018-10-16 16:28:42 +00:00
return $post ;
}
public function getNewestPosts ( $count , $maxLength = 250 )
{
$this -> db -> cache_off ();
$data = $this -> db -> query ( 'SELECT * FROM user_posts ORDER BY date DESC LIMIT ?' , [ $count ]) -> result_array ();
$this -> db -> cache_on ();
$data = $this -> preparePostList ( $data , $maxLength );
return $data ;
}
public function getFeedPosts ( $userID , $amount , $offset )
{
$this -> db -> cache_off ();
2019-01-08 21:42:54 +00:00
$data = $this -> db -> query ( 'SELECT * FROM user_posts WHERE userID IN (SELECT followedUserID FROM user_followers WHERE followerUserID = ?) OR ID IN(SELECT postID FROM user_posts_mentions WHERE mentionedUserID = ?) OR ID IN (SELECT postID FROM user_posts_likes WHERE likedUserID = ?) OR userID = ? ORDER BY date DESC LIMIT ? OFFSET ?' , [ $userID , $userID , $userID , $userID , $amount , $offset ]) -> result_array ();
2018-10-16 16:28:42 +00:00
$this -> db -> cache_on ();
$data = $this -> preparePostList ( $data );
return $data ;
}
public function getPopularPosts ( $amount , $offset )
{
$this -> db -> cache_off ();
2019-01-08 21:42:54 +00:00
$data = $this -> db -> query ( 'SELECT * FROM user_posts p ORDER BY ((SELECT count(*) FROM user_posts_likes WHERE postID = p.ID) + (SELECT count(*) FROM user_posts WHERE replyToPostID = p.ID)) DESC, date DESC LIMIT ? OFFSET ?' , [ $amount , $offset ]) -> result_array ();
2018-10-16 16:28:42 +00:00
$this -> db -> cache_on ();
$data = $this -> preparePostList ( $data );
return $data ;
}
2019-01-08 21:42:54 +00:00
public function getPostDetails ( $userID , $hashID )
2018-10-16 16:28:42 +00:00
{
$this -> db -> cache_off ();
2019-01-08 21:42:54 +00:00
$data = $this -> db -> query ( 'SELECT * FROM user_posts WHERE userID = ? AND hashID = ?' , [ $userID , $hashID ]) -> result_array ();
2018-10-16 16:28:42 +00:00
$this -> db -> cache_on ();
2018-10-17 14:28:25 +00:00
$data = $this -> preparePostList ( $data , - 1 );
2018-10-16 16:28:42 +00:00
return $data ;
}
public function getPostReplies ( $postID )
{
$this -> db -> cache_off ();
2019-01-08 21:42:54 +00:00
$replies = $this -> db -> query ( 'SELECT * FROM user_posts WHERE replyToPostID = ? ORDER BY date' , [ $postID ]) -> result_array ();
2018-10-16 16:28:42 +00:00
$this -> db -> cache_on ();
$replies = $this -> preparePostList ( $replies );
return $replies ;
}
2019-01-08 21:42:54 +00:00
public function getPostByHashID ( $hashID )
{
2018-10-17 11:56:22 +00:00
$this -> db -> cache_off ();
2019-01-08 21:42:54 +00:00
$result = $this -> db -> query ( 'SELECT * FROM user_posts WHERE hashID = ?' , [ $hashID ]) -> result_array ();
2018-10-17 11:56:22 +00:00
$this -> db -> cache_on ();
2018-10-16 16:28:42 +00:00
return $result ;
}
2019-01-08 21:42:54 +00:00
public function addPostLikeByHashID ( $hashID , $userID )
2018-10-16 16:28:42 +00:00
{
$this -> db -> cache_off ();
2019-01-08 21:42:54 +00:00
$data = $this -> db -> query ( 'SELECT * FROM user_posts_likes WHERE postID = (SELECT ID FROM user_posts WHERE hashID = ?) AND likerUserID = ?' , [ $hashID , $userID ]) -> result_array ();
2018-10-16 16:28:42 +00:00
$this -> db -> cache_on ();
// IDs needed for handling notifications later
2019-01-08 21:42:54 +00:00
$postUser = $this -> db -> query ( 'SELECT ID FROM users WHERE ID = (SELECT userID FROM user_posts WHERE hashID = ?)' , [ $hashID ]) -> result_array ();
$postID = $this -> db -> query ( 'SELECT ID FROM user_posts WHERE hashID = ?' , [ $hashID ]) -> result_array ();
2018-10-16 16:28:42 +00:00
if ( empty ( $data )) {
2019-01-08 21:42:54 +00:00
$this -> db -> query ( 'INSERT INTO user_posts_likes (postID, likedUserID, likerUserID) VALUES ((SELECT ID FROM user_posts WHERE hashID = ?), (SELECT userID FROM user_posts WHERE hashID = ?), ?)' , [ $hashID , $hashID , $userID ]);
2018-10-16 16:28:42 +00:00
// Send like notification
if ( $postUser [ 0 ][ 'ID' ] != $userID ) {
2019-01-08 21:42:54 +00:00
$this -> NotificationModel -> userNotificationPostLike ( $userID , $postUser [ 0 ][ 'ID' ], $postID [ 0 ][ 'ID' ], $hashID );
2018-10-16 16:28:42 +00:00
}
return true ;
} else {
2019-01-08 21:42:54 +00:00
$this -> db -> query ( 'DELETE FROM user_posts_likes WHERE postID = (SELECT ID FROM user_posts WHERE hashID = ?) AND likerUserID = ?' , [ $hashID , $userID ]);
2018-10-16 16:28:42 +00:00
// Remove existing notification
$this -> NotificationModel -> removeNotification ( $userID , $postUser [ 0 ][ 'ID' ], $postID [ 0 ][ 'ID' ], 'users.likedPost' );
return false ;
}
}
2019-01-08 21:42:54 +00:00
public function getPostLikeCountByHashID ( $hashID )
2018-10-16 16:28:42 +00:00
{
$this -> db -> cache_off ();
2019-01-08 21:42:54 +00:00
$data = $this -> db -> query ( 'SELECT count(*) likeCount FROM user_posts_likes WHERE postID = (SELECT ID FROM user_posts WHERE hashID = ?)' , [ $hashID ]) -> result_array ();
2018-10-16 16:28:42 +00:00
$this -> db -> cache_on ();
return $data [ 0 ][ 'likeCount' ];
}
2019-01-08 21:42:54 +00:00
public function isHashIDValid ( $hashID )
2018-10-16 16:28:42 +00:00
{
$this -> db -> cache_off ();
2019-01-08 21:42:54 +00:00
$data = $this -> db -> query ( 'SELECT ID FROM user_posts WHERE hashID = ?' , [ $hashID ]) -> result_array ();
2018-10-16 16:28:42 +00:00
$this -> db -> cache_on ();
return ! empty ( $data );
}
public function closeTags ( $html )
{
preg_match_all ( '#<(?!meta|img|br|hr|input\b)\b([a-z]+)(?: .*)?(?<![/|/ ])>#iU' , $html , $result );
$openedtags = $result [ 1 ];
preg_match_all ( '#</([a-z]+)>#iU' , $html , $result );
$closedtags = $result [ 1 ];
$len_opened = count ( $openedtags );
if ( count ( $closedtags ) == $len_opened ) {
return $html ;
}
$openedtags = array_reverse ( $openedtags );
for ( $i = 0 ; $i < $len_opened ; $i ++ ) {
if ( ! in_array ( $openedtags [ $i ], $closedtags )) {
$html .= '</' . $openedtags [ $i ] . '>' ;
} else {
unset ( $closedtags [ array_search ( $openedtags [ $i ], $closedtags )]);
}
}
return $html ;
}
public function searchPosts ( $query , $limit = 20 , $offset = 0 )
{
$this -> db -> cache_off ();
2019-01-08 21:42:54 +00:00
$results = $this -> db -> query ( 'SELECT * FROM user_posts WHERE content RLIKE ? OR (SELECT username FROM users WHERE ID = userID) RLIKE ? ORDER BY (SELECT count(*) FROM user_posts_likes WHERE postID = ID) DESC, (SELECT count(*) FROM user_posts WHERE replyToPostID = ID) DESC, date DESC LIMIT ? OFFSET ?' , [ $query , $query , $limit , $offset ]) -> result_array ();
2018-10-16 16:28:42 +00:00
$this -> db -> cache_on ();
$results = $this -> preparePostList ( $results );
return $results ;
}
2019-01-08 21:42:54 +00:00
public function reportPost ( $hashID , $reason , $reasonText )
{
$this -> db -> query ( 'INSERT INTO user_posts_reports (postID, reason, reasonText) VALUES ((SELECT ID FROM user_posts WHERE hashID = ?), ?, ?)' , [ $hashID , $reason , $reasonText ]);
2018-10-16 16:28:42 +00:00
$this -> db -> cache_delete ( 'admin' , 'reports' );
// Send notification
2019-01-08 21:42:54 +00:00
$postID = $this -> db -> query ( 'SELECT ID FROM user_posts WHERE hashID = ?' , [ $hashID ]) -> result_array ();
2018-10-16 16:28:42 +00:00
$this -> NotificationModel -> rankNotificationPostReport (
isset ( $_SESSION [ 'user' ]) ? $_SESSION [ 'user' ][ 'ID' ] : - 1 ,
2019-01-08 21:42:54 +00:00
8 , $postID [ 0 ][ 'ID' ], $hashID );
2018-10-16 16:28:42 +00:00
}
}