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 );
}
public function addReply ( $userID , $content , $replyToUUID )
{
$content = $this -> preparePostContent ( $content );
$uuid = $this -> generatePostUUID ( $userID , $content );
$replyTo = NULL ;
if ( $replyToUUID !== NULL ) {
$replyToID = $this -> db -> query ( 'SELECT ID FROM user_posts WHERE uuid = ?' , [ $replyToUUID ]) -> result_array ();
$replyTo = ! empty ( $replyToID ) ? $replyToID [ 0 ][ 'ID' ] : NULL ;
}
$this -> db -> query ( 'INSERT INTO user_posts (user_id, content, uuid, reply_to) VALUES (?, ?, ?, ?)' , [ $userID , $content , $uuid , $replyTo ]);
$insertedPost = $this -> db -> query ( 'SELECT ID, user_id FROM user_posts WHERE uuid = ?' , [ $uuid ]) -> result_array ();
$this -> addPostMentions ( $insertedPost [ 0 ][ 'ID' ], $content , $uuid );
$this -> addPostHashtags ( $insertedPost [ 0 ][ 'ID' ], $content );
// Send notification to user whose post was replied to
if ( $userID != $insertedPost [ 0 ][ 'user_id' ]) {
$this -> NotificationModel -> userNotificationPostReply ( $userID , $insertedPost [ 0 ][ 'user_id' ], $insertedPost [ 0 ][ 'ID' ], $uuid );
}
return $insertedPost [ 0 ][ 'ID' ];
}
2018-10-17 11:56:22 +00:00
public function deletePost ( $userID , $uuid ) {
$postID = $this -> db -> query ( 'SELECT ID FROM user_posts WHERE user_id = ? AND uuid = ?' , [ $userID , $uuid ]) -> result_array ()[ 0 ][ 'ID' ];
$this -> db -> query ( 'DELETE FROM user_posts WHERE user_id = ? AND uuid = ?' , [ $userID , $uuid ]);
$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 ]);
}
2018-10-16 16:28:42 +00:00
public function addImageToPost ( $postID , $imageUrl ) {
$this -> db -> query ( 'INSERT INTO user_posts_media (postID, mediaType, mediaUrl) VALUES (?, ?, ?)' , [ $postID , 'image' , $imageUrl ]);
}
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 );
}
function generatePostUUID ( $userID , $content )
{
return md5 ( $userID . $content . date ( " Y-m-d H:i:s " ));
}
public function addPostMentions ( $postID , $content , $postUUID )
{
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 ];
$this -> addMention ( $postID , $_SESSION [ 'user' ][ 'ID' ], $mentionedUser [ 'ID' ], $mention [ 1 ], $postUUID );
}
}
public function addMention ( $postID , $userID , $mentionedUserID , $position , $postUUID )
{
$this -> db -> query ( 'INSERT INTO user_posts_mentions (userID, postID, mentionedUserID, position) VALUES (?, ?, ?, ?)' , [ $userID , $postID , $mentionedUserID , $position ]);
// Send notification
$this -> NotificationModel -> userNotificationPostMentioned ( $userID , $mentionedUserID , $postID , $postUUID );
}
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 ]);
}
function getUserPosts ( $id , $count , $offset , $maxLength = 250 )
{
$this -> db -> cache_off ();
$posts = $this -> db -> query ( 'SELECT * FROM user_posts p WHERE user_id = ? ORDER BY date DESC LIMIT ? OFFSET ?' , [ $id , $count , $offset ]) -> result_array ();
$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' ]);
}
if ( $post [ 'reply_to' ] != NULL ) {
$post = $this -> mergeReplyData ( $post );
}
$postList [ $i ] = $post ;
}
$postList = $this -> UserModel -> setDefaultImages ( $postList );
return $postList ;
}
public function getPostMedia ( $postID ) {
$result = $this -> db -> query ( 'SELECT * FROM user_posts_media WHERE postID = ?' , [ $postID ]) -> result_array ();
return $result ;
}
private function mergePostUserData ( $post )
{
$user = $this -> UserModel -> getUserByID ( $post [ 'user_id' ]);
$user = $user [ 0 ];
$post [ 'username' ] = $user [ 'username' ];
$post [ 'displayname' ] = $user [ 'displayname' ];
$post [ 'profile_picture' ] = $user [ 'profile_picture' ];
return $post ;
}
public function getPostReplyCountByID ( $postID )
{
$this -> db -> cache_off ();
$data = $this -> db -> query ( 'SELECT count(*) replyCount FROM user_posts WHERE reply_to = ?' , [ $postID ]) -> result_array ();
$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 ;
}
private function mergeUserHasLiked ( $post , $userID )
{
$this -> db -> cache_off ();
$data = $this -> db -> query ( 'SELECT * FROM user_posts_likes WHERE postID = (SELECT ID FROM user_posts WHERE uuid = ?) AND likerUserID = ?' , [ $post [ 'uuid' ], $userID ]) -> result_array ();
$this -> db -> cache_on ();
if ( empty ( $data )) {
$post [ 'userHasLiked' ] = FALSE ;
} else {
$post [ 'userHasLiked' ] = TRUE ;
}
return $post ;
}
private function mergeReplyData ( $post ) {
2018-10-18 12:49:07 +00:00
$data = $this -> db -> query ( 'SELECT p.*, username, displayname FROM user_posts p LEFT JOIN users ON users.ID = p.user_id WHERE p.ID = ?' , [ $post [ 'reply_to' ]]) -> result_array ();
$data = $this -> preparePostList ( $data );
if ( ! empty ( $data )) {
$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 ();
$data = $this -> db -> query ( 'SELECT * FROM user_posts WHERE user_id 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 user_id = ? ORDER BY date DESC LIMIT ? OFFSET ?' , [ $userID , $userID , $userID , $userID , $amount , $offset ]) -> result_array ();
$this -> db -> cache_on ();
$data = $this -> preparePostList ( $data );
return $data ;
}
public function getPopularPosts ( $amount , $offset )
{
$this -> db -> cache_off ();
$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 reply_to = p.ID)) DESC, date DESC LIMIT ? OFFSET ?' , [ $amount , $offset ]) -> result_array ();
$this -> db -> cache_on ();
$data = $this -> preparePostList ( $data );
return $data ;
}
public function getPostDetails ( $userID , $uuid )
{
$this -> db -> cache_off ();
$data = $this -> db -> query ( 'SELECT * FROM user_posts WHERE user_id = ? AND uuid = ?' , [ $userID , $uuid ]) -> result_array ();
$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 ();
$replies = $this -> db -> query ( 'SELECT * FROM user_posts WHERE reply_to = ? ORDER BY date' , [ $postID ]) -> result_array ();
$this -> db -> cache_on ();
$replies = $this -> preparePostList ( $replies );
return $replies ;
}
public function getPostByUUID ( $uuid ) {
2018-10-17 11:56:22 +00:00
$this -> db -> cache_off ();
2018-10-16 16:28:42 +00:00
$result = $this -> db -> query ( 'SELECT * FROM user_posts WHERE uuid = ?' , [ $uuid ]) -> result_array ();
2018-10-17 11:56:22 +00:00
$this -> db -> cache_on ();
2018-10-16 16:28:42 +00:00
return $result ;
}
public function addPostLikeByUUID ( $uuid , $userID )
{
$this -> db -> cache_off ();
$data = $this -> db -> query ( 'SELECT * FROM user_posts_likes WHERE postID = (SELECT ID FROM user_posts WHERE uuid = ?) AND likerUserID = ?' , [ $uuid , $userID ]) -> result_array ();
$this -> db -> cache_on ();
// IDs needed for handling notifications later
$postUser = $this -> db -> query ( 'SELECT ID FROM users WHERE ID = (SELECT user_id FROM user_posts WHERE uuid = ?)' , [ $uuid ]) -> result_array ();
$postID = $this -> db -> query ( 'SELECT ID FROM user_posts WHERE uuid = ?' , [ $uuid ]) -> result_array ();
if ( empty ( $data )) {
$this -> db -> query ( 'INSERT INTO user_posts_likes (postID, likedUserID, likerUserID) VALUES ((SELECT ID FROM user_posts WHERE uuid = ?), (SELECT user_id FROM user_posts WHERE uuid = ?), ?)' , [ $uuid , $uuid , $userID ]);
// Send like notification
if ( $postUser [ 0 ][ 'ID' ] != $userID ) {
$this -> NotificationModel -> userNotificationPostLike ( $userID , $postUser [ 0 ][ 'ID' ], $postID [ 0 ][ 'ID' ], $uuid );
}
return true ;
} else {
$this -> db -> query ( 'DELETE FROM user_posts_likes WHERE postID = (SELECT ID FROM user_posts WHERE uuid = ?) AND likerUserID = ?' , [ $uuid , $userID ]);
// Remove existing notification
$this -> NotificationModel -> removeNotification ( $userID , $postUser [ 0 ][ 'ID' ], $postID [ 0 ][ 'ID' ], 'users.likedPost' );
return false ;
}
}
public function getPostLikeCountByUUID ( $uuid )
{
$this -> db -> cache_off ();
$data = $this -> db -> query ( 'SELECT count(*) likeCount FROM user_posts_likes WHERE postID = (SELECT ID FROM user_posts WHERE uuid = ?)' , [ $uuid ]) -> result_array ();
$this -> db -> cache_on ();
return $data [ 0 ][ 'likeCount' ];
}
public function isUUIDValid ( $uuid )
{
$this -> db -> cache_off ();
$data = $this -> db -> query ( 'SELECT ID FROM user_posts WHERE uuid = ?' , [ $uuid ]) -> result_array ();
$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 ();
$results = $this -> db -> query ( 'SELECT * FROM user_posts WHERE content RLIKE ? OR (SELECT username FROM users WHERE ID = user_id) RLIKE ? ORDER BY (SELECT count(*) FROM user_posts_likes WHERE postID = ID) DESC, (SELECT count(*) FROM user_posts WHERE user_posts.reply_to = ID) DESC, date DESC LIMIT ? OFFSET ?' , [ $query , $query , $limit , $offset ]) -> result_array ();
$this -> db -> cache_on ();
$results = $this -> preparePostList ( $results );
return $results ;
}
public function reportPost ( $uuid , $reason , $reasonText ) {
$this -> db -> query ( 'INSERT INTO user_posts_reports (postID, reason, reasonText) VALUES ((SELECT ID FROM user_posts WHERE uuid = ?), ?, ?)' , [ $uuid , $reason , $reasonText ]);
$this -> db -> cache_delete ( 'admin' , 'reports' );
// Send notification
$postID = $this -> db -> query ( 'SELECT ID FROM user_posts WHERE uuid = ?' , [ $uuid ]) -> result_array ();
$this -> NotificationModel -> rankNotificationPostReport (
isset ( $_SESSION [ 'user' ]) ? $_SESSION [ 'user' ][ 'ID' ] : - 1 ,
8 , $postID [ 0 ][ 'ID' ], $uuid );
}
}