[], 'tags' => [], 'item' => [], 'topic' => [], 'tag' => [], 'forum_slug' => [] ]; function __construct() { $this->init_hooks(); } public function get_cache( $var ) { if( isset( self::$cache[ $var ] ) ) return self::$cache[ $var ]; return []; } public function reset() { self::$cache = [ 'topics' => [], 'tags' => [], 'item' => [], 'topic' => [], 'tag' => [], 'forum_slug' => [] ]; } private function init_hooks() { add_action( 'wpforo_after_add_post', [ $this, 'after_add_post' ], 10, 2 ); add_action( 'wpforo_after_delete_post', [ $this, 'after_delete_post' ] ); add_action( 'wpforo_post_status_update', [ $this, 'after_post_status_update' ] ); add_action( 'wpforo_after_delete_user', [ $this, 'after_delete_user' ], 11, 2 ); } private function unique_slug( $slug ) { $new_slug = wpforo_text( $slug, 250, false ); $i = 2; while( ! WPF()->can_use_this_slug( $new_slug ) || WPF()->db->get_var( "SELECT `topicid` FROM " . WPF()->tables->topics . " WHERE `slug` = '" . esc_sql( $new_slug ) . "'" ) ) { $new_slug = wpforo_text( $slug, 250, false ) . '-' . $i; $i ++; } return $new_slug; } public function add( $args = [] ) { if( empty( $args ) && empty( $_REQUEST['thread'] ) ) return false; if( empty( $args ) && ! empty( $_REQUEST['thread'] ) ) $args = $_REQUEST['thread']; if( $min = wpforo_setting('posting', 'topic_body_min_length') ){ if( wpfkey( $args, 'body' ) && (int) $min > wpforo_length( $args['body'] ) ) { WPF()->notice->add( 'The content is too short', 'error' ); return false; } } $args['name'] = ( isset( $args['name'] ) ? strip_tags( (string) $args['name'] ) : '' ); $args['email'] = ( isset( $args['email'] ) ? sanitize_email( $args['email'] ) : '' ); if( ! isset( $args['forumid'] ) || ! $args['forumid'] = intval( $args['forumid'] ) ) { WPF()->notice->add( 'Add Topic error: No forum selected', 'error' ); return false; } if( ! $forum = WPF()->forum->get_forum( $args['forumid'] ) ) { WPF()->notice->add( 'Add Topic error: No forum selected', 'error' ); return false; } if( ! WPF()->perm->forum_can( 'ct', $args['forumid'] ) ) { WPF()->notice->add( 'You don\'t have permission to create topic into this forum', 'error' ); return false; } if( ! WPF()->perm->can_post_now() ) { WPF()->notice->add( 'You are posting too quickly. Slow down.', 'error' ); return false; } if( ! isset( $args['title'] ) || ! $args['title'] = wpforo_text( $args['title'], 250, false, true, false, false, false ) ) { WPF()->notice->add( 'Please insert required fields!', 'error' ); return false; } if( ! is_user_logged_in() ) { if( $args['name'] && $args['email'] ) { WPF()->member->set_guest_cookies( $args ); } else { $uqid = uniqid(); if( ! trim( (string) $args['name'] ) ) $args['name'] = wpforo_phrase( 'Anonymous', false ); if( ! trim( (string) $args['email'] ) ) $args['email'] = "anonymous_$uqid@example.com"; } } do_action( 'wpforo_start_add_topic', $args, $forum ); $root_exists = wpforo_root_exist(); $args['body'] = preg_replace( '#[\r\n\t\s\0]*
#isu', "\r\n", (string) $args['body'] );
$args['slug'] = ( isset( $args['slug'] ) && $args['slug'] ) ? sanitize_title( $args['slug'] ) : ( ( isset( $args['title'] ) ) ? sanitize_title( $args['title'] ) : md5( time() ) );
if( ! trim( (string) $args['slug'] ) ) $args['slug'] = md5( time() );
$args['slug'] = $this->unique_slug( $args['slug'] );
$args['created'] = ( isset( $args['created'] ) ? sanitize_text_field( $args['created'] ) : current_time( 'mysql', 1 ) );
$args['userid'] = ( isset( $args['userid'] ) ? intval( $args['userid'] ) : WPF()->current_userid );
$args['name'] = ( isset( $args['name'] ) ? $args['name'] : '' );
$args['email'] = ( isset( $args['email'] ) ? $args['email'] : '' );
$args['tags'] = ( isset( $args['tags'] ) ? $args['tags'] : '' );
$args = apply_filters( 'wpforo_add_topic_data_filter', $args, $forum );
if( empty( $args ) ) return false;
extract( $args, EXTR_OVERWRITE );
if( isset( $title ) ) $title = sanitize_text_field( trim( (string) $title ) );
if( isset( $created ) ) $created = sanitize_text_field( $created );
if( isset( $userid ) ) $userid = intval( $userid );
$type = ( isset( $type ) && $type ? 1 : 0 );
$status = ( isset( $status ) && $status ? 1 : 0 );
$private = ( isset( $private ) && $private ? 1 : 0 );
if( isset( $meta_key ) ) $meta_key = sanitize_text_field( $meta_key );
if( isset( $meta_desc ) ) $meta_desc = sanitize_text_field( $meta_desc );
if( isset( $name ) ) $name = strip_tags( trim( (string) $name ) );
if( isset( $email ) ) $email = strip_tags( trim( (string) $email ) );
if( isset( $body ) ) $body = wpforo_kses( trim( (string) $body ) );
if( isset( $tags ) ) {
if( wpforo_is_module_enabled( 'tags' ) && WPF()->perm->forum_can( 'tag', $forum['forumid'] ) ) {
$tags = $this->sanitize_tags( $tags, false, true );
} else {
$tags = '';
}
}
$views = ( isset( $views ) ? intval( $views ) : 0 );
$meta_key = ( isset( $meta_key ) ? $meta_key : '' );
$meta_desc = ( isset( $meta_desc ) ? $meta_desc : '' );
$has_attach = ( isset( $has_attach ) && $has_attach ) ? 1 : ( ( strpos( (string) $body, '[attach]' ) !== false ) ? 1 : 0 );
$layout = WPF()->forum->get_layout( $forum );
$posts = ( $layout == 3 ) ? 0 : 1;
do_action( 'wpforo_before_add_topic', $args );
if( WPF()->db->insert(
WPF()->tables->topics,
[
'title' => stripslashes( $title ),
'slug' => $slug,
'forumid' => $forum['forumid'],
'userid' => $userid,
'type' => $type,
'status' => $status,
'private' => $private,
'created' => $created,
'modified' => $created,
'last_post' => 0,
'views' => $views,
'posts' => $posts,
'meta_key' => $meta_key,
'meta_desc' => $meta_desc,
'has_attach' => $has_attach,
'name' => $name,
'email' => $email,
'tags' => $tags,
],
['%s','%s','%d','%d','%d','%d','%d','%s','%s','%d','%d','%d','%s','%s','%d','%s','%s','%s']
) ) {
$topicid = WPF()->db->insert_id;
$fields = [
'forumid' => $forum['forumid'],
'topicid' => $topicid,
'userid' => $userid,
'title' => stripslashes( $title ),
'body' => stripslashes( (string) $body ),
'created' => $created,
'modified' => $created,
'is_first_post' => 1,
'status' => $status,
'private' => $private,
'name' => $name,
'email' => $email,
'root' => - 1,
];
$values = [ '%d', '%d', '%d', '%s', '%s', '%s', '%s', '%d', '%d', '%d', '%s', '%s', '%d' ];
if( ! $root_exists ) {
unset( $fields['root'] );
unset( $fields[13] );
}
if( WPF()->db->insert(
WPF()->tables->posts,
$fields,
$values
) ) {
$first_postid = WPF()->db->insert_id;
if( false !== WPF()->db->update( WPF()->tables->topics, [ 'first_postid' => $first_postid, 'last_post' => $first_postid ], [ 'topicid' => $topicid ], [ '%d', '%d' ], [ '%d' ] ) ) {
$args['topicid'] = $topicid;
$args['first_postid'] = $first_postid;
$args['type'] = $type;
$args['status'] = $status;
$args['private'] = $private;
$args['url'] = $args['topicurl'] = $this->get_url( $topicid );
if( $tags && ! $status && ! $private ) $this->add_tags( $tags );
$topic = apply_filters( 'wpforo_after_add_topic_filter', $args, $forum );
do_action( 'wpforo_after_add_topic', $topic, $forum );
wpforo_clean_cache( 'topic', $topicid, $topic );
if( $status ) {
WPF()->notice->add( 'Your topic successfully added and awaiting moderation', 'success' );
} else {
WPF()->notice->add( 'Your topic successfully added', 'success' );
}
return $topicid;
}
}
}
WPF()->notice->add( 'Topic add error', 'error' );
return false;
}
public function edit( $args = [] ) {
if( empty( $args ) && empty( $_REQUEST['thread'] ) ) return false;
if( ! isset( $args['topicid'] ) && isset( $_GET['id'] ) ) $args['topicid'] = intval( $_GET['id'] );
if( empty( $args ) && ! empty( $_REQUEST['thread'] ) ) $args = $_REQUEST['thread'];
if( isset( $args['name'] ) ) {
$args['name'] = strip_tags( (string) $args['name'] );
}
if( isset( $args['email'] ) ) {
$args['email'] = sanitize_email( $args['email'] );
}
if( ! $topic = $this->get_topic( $args['topicid'] ) ) {
WPF()->notice->add( 'Topic not found.', 'error' );
return false;
}
if( ! $forum = WPF()->forum->get_forum( $topic['forumid'] ) ) {
WPF()->notice->add( 'Forum not found.', 'error' );
return false;
}
do_action( 'wpforo_start_edit_topic', $args, $forum );
if( ! is_user_logged_in() ) {
if( ! isset( $topic['email'] ) || ! $topic['email'] ) {
WPF()->notice->add( 'Permission denied', 'error' );
return false;
} elseif( ! wpforo_current_guest( $topic['email'] ) ) {
WPF()->notice->add( 'You are not allowed to edit this post', 'error' );
return false;
}
}
$args['status'] = $topic['status'];
$args['userid'] = $topic['userid'];
$args = apply_filters( 'wpforo_edit_topic_data_filter', $args, $forum );
if( empty( $args ) ) return false;
if( $min = wpforo_setting('posting', 'topic_body_min_length') ){
if( wpfkey( $args, 'body' ) && (int) $min > wpforo_length( $args['body'] ) ) {
WPF()->notice->add( 'The content is too short', 'error' );
return false;
}
}
extract( $args, EXTR_OVERWRITE );
if( isset( $topicid ) ) $topicid = intval( $topicid );
if( isset( $title ) ) $title = sanitize_text_field( trim( (string) $title ) );
if( isset( $type ) ) $type = intval( $type );
if( isset( $status ) ) $status = intval( $status );
if( isset( $private ) ) $private = intval( $private );
if( isset( $name ) ) $name = strip_tags( trim( (string) $name ) );
if( isset( $email ) ) $email = strip_tags( trim( (string) $email ) );
if( isset( $body ) ) $body = wpforo_kses( trim( (string) $body ) );
if( isset( $tags ) ) {
if( isset( $topic['forumid'] ) && wpforo_is_module_enabled( 'tags' ) && WPF()->perm->forum_can( 'tag', $topic['forumid'] ) ) {
$tags = $this->sanitize_tags( $tags, false, true );
} else {
$tags = '';
}
}
if( ! isset( $topicid ) ) {
WPF()->notice->add( 'Topic edit error', 'error' );
return false;
}
if( ! isset( $title ) || ! $title = wpforo_text( $title, 250, false, true, false, false, false ) ) {
WPF()->notice->add( 'Please insert required fields!', 'error' );
return false;
}
if( isset( $body ) ) $body = preg_replace( '#[\r\n\t\s\0]*#isu', "\r\n", (string) $body );
$diff = time() - strtotime( $topic['created'] . ' GMT' );
if( ! ( WPF()->perm->forum_can( 'et', $topic['forumid'] ) || ( WPF()->current_userid == $topic['userid'] && WPF()->perm->forum_can( 'eot', $topic['forumid'] ) ) ) ) {
WPF()->notice->add( 'You have no permission to edit this topic', 'error' );
return false;
}
if( ! WPF()->perm->forum_can( 'et', $topic['forumid'] ) && wpforo_setting( 'posting', 'edit_own_topic_durr' ) !== 0 && $diff > wpforo_setting( 'posting', 'edit_own_topic_durr' ) ) {
WPF()->notice->add( 'The time to edit this topic is expired', 'error' );
return false;
}
$title = ( isset( $title ) ? stripslashes( $title ) : stripslashes( (string) $topic['title'] ) );
$type = ( isset( $type ) ? $type : intval( $topic['type'] ) );
$status = ( isset( $status ) ? $status : intval( $topic['status'] ) );
$private = ( isset( $private ) ? $private : intval( $topic['private'] ) );
$has_attach = ( isset( $body ) ? ( strpos( (string) $body, '[attach]' ) !== false ? 1 : 0 ) : $topic['has_attach'] );
$name = ( isset( $name ) ? stripslashes( $name ) : stripslashes( (string) $topic['name'] ) );
$email = ( isset( $email ) ? stripslashes( $email ) : stripslashes( (string) $topic['email'] ) );
$tags = ( isset( $tags ) ? $tags : '' );
$t_update = WPF()->db->update( WPF()->tables->topics,
[
'title' => $title,
'type' => $type,
'status' => $status,
'private' => $private,
'has_attach' => $has_attach,
'name' => $name,
'email' => $email,
'tags' => $tags,
],
[ 'topicid' => $topicid ],
[ '%s', '%d', '%d', '%d', '%d', '%s', '%s', '%s' ],
[ '%d' ] );
if( isset( $topic['first_postid'] ) ) {
if( ! $post = WPF()->post->get_post( $topic['first_postid'] ) ) {
WPF()->notice->add( 'Topic first post data not found.', 'error' );
return false;
}
} else {
WPF()->notice->add( 'Topic first post not found.', 'error' );
return false;
}
$body = ( !$min || ( isset( $body ) && $body ) ) ? stripslashes( (string) $body ) : stripslashes( (string) $post['body'] );
$p_update = WPF()->db->update( WPF()->tables->posts,
[
'title' => $title,
'body' => $body,
'modified' => current_time(
'mysql',
1
),
'status' => $status,
'private' => $private,
'name' => $name,
'email' => $email,
],
[ 'postid' => intval( $topic['first_postid'] ) ],
[ '%s', '%s', '%s', '%d', '%d', '%s', '%s' ],
[ '%d' ] );
if( $t_update !== false && $p_update !== false ) {
if( isset( $tags ) ) $this->edit_tags( $tags, $topic );
$a = [
'userid' => $topic['userid'],
'forumid' => $topic['forumid'],
'topicid' => $topicid,
'postid' => $topic['first_postid'],
'first_postid' => $topic['first_postid'],
'title' => $title,
'body' => $body,
'status' => $status,
'private' => $private,
'name' => $name,
'email' => $email,
'type' => $type,
'has_attach' => $has_attach,
'tags' => $tags,
];
do_action( 'wpforo_after_edit_topic', $a, $args, $forum );
wpforo_clean_cache( 'topic-first-post', $topicid, $topic );
WPF()->notice->add( 'Topic successfully updated', 'success' );
return $topicid;
}
WPF()->notice->add( 'Topic edit error', 'error' );
return false;
}
#################################################################################
/**
* Delete topic from DB
*
* Returns true if successfully deleted or false.
*
* @param int $topicid
* @param bool $delete_cache
*
* @return bool
* @since 1.0.0
*
*/
function delete( $topicid = 0, $delete_cache = true, $check_permissions = true ) {
$topicid = intval( $topicid );
if( ! $topicid && isset( $_REQUEST['id'] ) ) $topicid = intval( $_REQUEST['id'] );
if( ! $topic = $this->get_topic( $topicid ) ) return true;
do_action( 'wpforo_before_delete_topic', $topic );
if( $check_permissions ){
$diff = time() - strtotime( $topic['created'] . ' GMT' );
if( ! ( WPF()->perm->forum_can( 'dt', $topic['forumid'] ) || ( WPF()->current_userid == $topic['userid'] && WPF()->perm->forum_can( 'dot', $topic['forumid'] ) ) ) ) {
WPF()->notice->add( 'You don\'t have permission to delete topic from this forum.', 'error' );
return false;
}
if( ! WPF()->perm->forum_can( 'dt', $topic['forumid'] ) && wpforo_setting( 'posting', 'delete_own_topic_durr' ) !== 0 && $diff > wpforo_setting( 'posting', 'delete_own_topic_durr' ) ) {
WPF()->notice->add( 'The time to delete this topic is expired.', 'error' );
return false;
}
}
// START delete topic posts include first post
if( $postids = WPF()->db->get_col(
WPF()->db->prepare( "SELECT `postid` FROM `" . WPF()->tables->posts . "` WHERE `topicid` = %d ORDER BY `is_first_post`", $topicid )
) ) {
foreach( $postids as $postid ) {
if( $postid == $topic['first_postid'] ) {
return WPF()->post->delete( $postid, false, false, $exclude, false );
} else {
WPF()->post->delete( $postid, false, false, $exclude, false );
}
}
}
// END delete topic posts include first post
if( WPF()->db->delete( WPF()->tables->topics, [ 'topicid' => $topicid ], [ '%d' ] ) ) {
if( wpfval( $topic, 'tags' ) ) $this->remove_tags( $topic['tags'] );
do_action( 'wpforo_after_delete_topic', $topic );
if( $delete_cache ) wpforo_clean_cache( 'topic', $topicid, $topic );
WPF()->notice->add( 'This topic successfully deleted', 'success' );
return true;
}
WPF()->notice->add( 'Topics delete error', 'error' );
return false;
}
#################################################################################
/**
* array get_topic(array or id(num))
*
* Returns array from defined and default arguments.
*
* @param mixed $args defined arguments array for returning
* @param bool $protect
*
* @return array
* @since 1.0.0
*
*/
public function _get_topic( $args = [], $protect = true ) {
if( ! $args ) return [];
if( is_array( $args ) ) {
$default = [
'topicid' => null,
'slug' => '',
];
} elseif( is_numeric( $args ) ) {
$default = [
'topicid' => $args,
'slug' => '',
];
} else {
$default = [
'topicid' => null,
'slug' => $args,
];
}
$args = wpforo_parse_args( $args, $default );
$sql = "SELECT * FROM `" . WPF()->tables->topics . "`";
$wheres = [];
if( $topicid = wpforo_bigintval( $args['topicid'] ) ) $wheres[] = "`topicid` = " . $topicid;
if( $args['slug'] ) $wheres[] = "`slug` = '" . esc_sql( $args['slug'] ) . "'";
if( ! empty( $wheres ) ) $sql .= " WHERE " . implode( " AND ", $wheres );
$topic = (array) WPF()->db->get_row( $sql, ARRAY_A );
if( $protect ) {
if( isset( $topic['forumid'] ) && $topic['forumid'] && ! WPF()->perm->forum_can( 'vf', $topic['forumid'] ) ) {
return [];
}
if( isset( $topic['private'] ) && $topic['private'] && ! wpforo_is_owner( $topic['userid'], $topic['email'] ) ) {
if( isset( $topic['forumid'] ) && $topic['forumid'] && ! WPF()->perm->forum_can( 'vp', $topic['forumid'] ) ) {
return [];
}
}
if( isset( $topic['status'] ) && $topic['status'] && ! wpforo_is_owner( $topic['userid'], $topic['email'] ) ) {
if( isset( $topic['forumid'] ) && $topic['forumid'] && ! WPF()->perm->forum_can( 'au', $topic['forumid'] ) ) {
WPF()->current_object['status'] = 'unapproved';
return [];
}
}
}
if( $topic ) {
$topic['url'] = $this->get_url( $topic, [], false );
$topic['full_url'] = $this->get_full_url( $topic, [], false );
$topic['short_url'] = $this->get_short_url( $topic );
}
return apply_filters('wpforo_get_topic', $topic);
}
public function get_topic( $args = [], $protect = true ) {
return wpforo_ram_get( [ $this, '_get_topic' ], $args, $protect );
}
/**
* array get_topic(array or id(num))
* Returns merged arguments array from defined and default arguments.
*
* @return array where count is topic count and other numeric arrays with topic
* @since 1.0.0
*
*/
function get_topics( $args = [], &$items_count = 0, $count = true ) {
$cache = WPF()->cache->on('topic');
$default = [
'include' => [], // array( 2, 10, 25 )
'exclude' => [], // array( 2, 10, 25 )
'forumids' => [],
'forumid' => null,
'userid' => null, // user id in DB
'type' => null, //0, 1, etc . . .
'solved' => null,
'closed' => null,
'status' => null, //0, 1, etc . . .
'private' => null, //0, 1, etc . . .''
'pollid' => null,
'orderby' => 'type, topicid', // type, topicid, modified, created
'order' => 'DESC', // ASC DESC
'offset' => null, // this use when you give row_count
'row_count' => null, // 4 or 1 ...
'permgroup' => null, //Checks permissions based on attribute value not on current user usergroup
'read' => null, //true / false
'prefix' => null, //23 / 23,24,50
'where' => null,
];
$args = wpforo_parse_args( $args, $default );
extract( $args, EXTR_OVERWRITE );
if( $row_count === 0 ) return [];
$include = wpforo_parse_args( $include );
$exclude = wpforo_parse_args( $exclude );
$forumids = wpforo_parse_args( $forumids );
$guest = [];
$wheres = [];
if( ! is_null( $prefix ) ) {
$prefixes = explode( ',', $prefix );
if( ! empty( $prefixes ) ) {
foreach( $prefixes as $prefixid ) {
$wheres[] = " FIND_IN_SET('" . intval( $prefixid ) . "', `prefix`) ";
}
}
}
if( ! is_null( $read ) ) {
$last_read_postid = WPF()->log->get_all_read( 'post' );
if( $read ) {
if( $last_read_postid ) {
$wheres[] = "`last_post` <= " . intval( $last_read_postid );
}
$include_read = WPF()->log->get_read();
$include = array_merge( $include, $include_read );
} else {
if( $last_read_postid ) {
$wheres[] = "`last_post` > " . intval( $last_read_postid );
}
$exclude_read = WPF()->log->get_read();
$exclude = array_merge( $exclude, $exclude_read );
}
}
if( ! empty( $include ) ) $wheres[] = "`topicid` IN(" . implode( ', ', array_map( 'intval', $include ) ) . ")";
if( ! empty( $exclude ) ) $wheres[] = "`topicid` NOT IN(" . implode( ', ', array_map( 'intval', $exclude ) ) . ")";
if( ! empty( $forumids ) ) $wheres[] = "`forumid` IN(" . implode( ', ', array_map( 'intval', $forumids ) ) . ")";
if( ! is_null( $forumid ) ) $wheres[] = "`forumid` = " . intval( $forumid );
if( ! is_null( $userid ) ) $wheres[] = "`userid` = " . wpforo_bigintval( $userid );
if( ! is_null( $solved ) ) $wheres[] = "`solved` = " . intval( $solved );
if( ! is_null( $closed ) ) $wheres[] = "`closed` = " . intval( $closed );
if( ! is_null( $type ) ) $wheres[] = "`type` = " . intval( $type );
if( ! is_null( $where ) ) $wheres[] = $where;
if( ! is_user_logged_in() ) $guest = WPF()->member->get_guest_cookies();
if( empty( $forumids ) ) {
if( isset( $forumid ) && ! WPF()->perm->forum_can( 'vf', $forumid, $permgroup ) ) {
return [];
}
}
if( isset( $forumid ) && $forumid ) {
if( WPF()->perm->forum_can( 'vp', $forumid, $permgroup ) ) {
if( ! is_null( $private ) ) $wheres[] = " `private` = " . intval( $private );
} elseif( isset( WPF()->current_userid ) && WPF()->current_userid ) {
$wheres[] = " ( `private` = 0 OR (`private` = 1 AND `userid` = " . WPF()->current_userid . ") )";
} elseif( wpfval( $guest, 'email' ) ) {
$wheres[] = " ( `private` = 0 OR (`private` = 1 AND `email` = '" . sanitize_email( $guest['email'] ) . "') )";
} else {
$wheres[] = " `private` = 0";
}
} else {
if( ! is_null( $private ) ) $wheres[] = " `private` = " . intval( $private );
}
if( isset( $forumid ) && $forumid ) {
if( WPF()->perm->forum_can( 'au', $forumid, $permgroup ) ) {
if( ! is_null( $status ) ) $wheres[] = " `status` = " . intval( $status );
} elseif( isset( WPF()->current_userid ) && WPF()->current_userid ) {
$wheres[] = " ( `status` = 0 OR (`status` = 1 AND `userid` = " . WPF()->current_userid . ") )";
} elseif( wpfval( $guest, 'email' ) ) {
$wheres[] = " ( `status` = 0 OR (`status` = 1 AND `email` = '" . sanitize_email( $guest['email'] ) . "') )";
} else {
$wheres[] = " `status` = 0";
}
} else {
if( ! is_null( $status ) ) $wheres[] = " `status` = " . intval( $status );
}
if( function_exists( 'WPF_POLL' ) ) {
if( ! is_null( $pollid ) ) $wheres[] = " `pollid` <> 0";
}
$wheres = apply_filters('wpforo_get_topics_sql_wheres', $wheres);
$sql = "SELECT * FROM `" . WPF()->tables->topics . "`";
if( ! empty( $wheres ) ) {
$sql .= " WHERE " . implode( " AND ", $wheres );
}
if( $count ) {
$item_count_sql = preg_replace( '#SELECT.+?FROM#isu', 'SELECT count(*) FROM', $sql );
if( $item_count_sql ) $items_count = WPF()->db->get_var( $item_count_sql );
}
$sql .= " ORDER BY " . str_replace( ',', ' ' . esc_sql( $order ) . ',', esc_sql( $orderby ) ) . " " . esc_sql( $order );
if( ! is_null( $row_count ) ) {
if( ! is_null( $offset ) ) {
$sql .= esc_sql( " LIMIT $offset,$row_count" );
} else {
$sql .= esc_sql( " LIMIT $row_count" );
}
}
if( $cache ) {
$object_key = md5( $sql . WPF()->current_user_groupid );
$object_cache = WPF()->cache->get( $object_key );
if( ! empty( $object_cache ) ) {
if( ! empty( $object_cache['items'] ) ) {
$access_filter = apply_filters( 'wpforo_topic_access_filter_cache', true );
if( $access_filter ) {
$object_cache['items'] = $this->access_filter( $object_cache['items'], [ 'groupids' => ( array_filter( array_map( 'intval', (array) $permgroup ) ) ?: null )] );
return apply_filters( 'wpforo_get_topics', $object_cache['items'] );
} else {
return apply_filters( 'wpforo_get_topics', $object_cache['items'] );
}
}
}
}
$topics = WPF()->db->get_results( $sql, ARRAY_A );
if( $cache && isset( $object_key ) && ! empty( $topics ) ) {
self::$cache['topics'][ $object_key ]['items'] = $topics;
self::$cache['topics'][ $object_key ]['items_count'] = $items_count;
}
if( ! empty( $forumids ) || ! $forumid ) {
$topics = $this->access_filter( $topics, [ 'groupids' => ( array_filter( array_map( 'intval', (array) $permgroup ) ) ?: null )] );
}
return apply_filters( 'wpforo_get_topics', $topics );
}
function access_filter( $topics, $user = null ) {
if( ! empty( $topics ) ) {
foreach( $topics as $key => $topic ) {
if( ! $this->view_access( $topic, $user ) ) unset( $topics[ $key ] );
}
}
return $topics;
}
function view_access( $topic, $user = null ) {
$groupids = wpfval( $user, 'groupids' );
if( ! WPF()->perm->forum_can( 'vf', $topic['forumid'], $groupids ) ) return apply_filters( 'wpforo_topic_view_access', false, $topic, $user );
if( ! WPF()->perm->forum_can( 'vt', $topic['forumid'], $groupids ) ) return apply_filters( 'wpforo_topic_view_access', false, $topic, $user );
if(
! wpforo_is_users_same( wpforo_member( $topic ), $user )
&& (
( (int) wpfval( $topic, 'private' ) && ! WPF()->perm->forum_can( 'vp', $topic['forumid'], $groupids ) )
|| ( (int) wpfval( $topic, 'status' ) && ! WPF()->perm->forum_can( 'au', $topic['forumid'], $groupids ) )
)
) return apply_filters( 'wpforo_topic_view_access', false, $topic, $user );
return apply_filters( 'wpforo_topic_view_access', true, $topic, $user );
}
/**
* Search in your chosen column and return array with needles
*
* @param string $needle
*
* @param array $fields can be ( slug, title, body )
*
* @return array with matches
* @since 1.0.0
*
*/
function search( $needle = '', $fields = [ 'title', 'body' ] ) {
if( $needle !== '' ) {
$needle = stripslashes( (string) $needle );
$fields = (array) $fields;
$topicids = [];
foreach( $fields as $field ) {
$matches = [];
if( $field === 'body' ) {
// Search the needle as a whole phrase in body to find closer result
$matches = WPF()->db->get_col( "SELECT `topicid` FROM " . WPF()->tables->posts . " WHERE `" . esc_sql( $field ) . "` LIKE '%" . esc_sql( sanitize_text_field( $needle ) ) . "%'" );
} else {
// Search all words of the needle independently in title and other fields
// If the search phrase is "es lorem du ipsum dolor", then SQL becomes
// SELECT * FROM `wp_wpforo_topics` WHERE `title` REGEXP 'lorem|ipsum|dolor'
$words = array_filter( explode(' ', sanitize_text_field( $needle ) ), function($word){ return mb_strlen((string) $word) > 2; });
if( $words ){
if( apply_filters( 'wpforo_suggested_topics_search_fields_method_regexp', true ) ){
$words = array_map( function( $word ){ return preg_quote( preg_quote( $word ) ); }, $words );
$search_mode_sql = '`' . esc_sql( $field ) . '` REGEXP "' . implode('|', $words ) . '"';
} else {
$wheres = array_map( function( $word ) use ($field){
return sprintf(
'`%1$s` LIKE \'%%%2$s%%\'',
esc_sql( $field ),
esc_sql( $word )
);
}, $words );
$search_mode_sql = implode( ' OR ', $wheres );
}
$sql = "SELECT `topicid` FROM " . WPF()->tables->topics . " WHERE " . $search_mode_sql;
$matches = WPF()->db->get_col( $sql );
}
}
$topicids = array_merge( $topicids, $matches );
}
return array_unique( array_map( 'wpforo_bigintval', $topicids ) );
}
return [];
}
function get_sum_answer( $forumids ) {
$sum = WPF()->db->get_var( "SELECT SUM(`answers`) FROM `" . WPF()->tables->topics . "` WHERE `forumid` IN(" . implode( ', ', array_map( 'intval', $forumids ) ) . ")" );
if( $sum ) return $sum;
return 0;
}
function get_forumslug( $forumid ) {
$slug = WPF()->db->get_var( "SELECT `slug` FROM " . WPF()->tables->forums . " WHERE `forumid` = " . intval( $forumid ) );
if( $slug ) return $slug;
return 0;
}
function get_forumslug_byid( $topicid ) {
$slug = WPF()->db->get_var( "SELECT `slug` FROM " . WPF()->tables->forums . " WHERE `forumid` =(SELECT forumid FROM `" . WPF()->tables->topics . "` WHERE `topicid` =" . intval( $topicid ) . ")" );
if( $slug ) return $slug;
return 0;
}
function is_sticky( $topicid ) {
if( $topicid ) {
if( WPF()->cache->on() ) {
$is_sticky = wpforo_topic( $topicid, 'type' );
} else {
$sql = "SELECT `type` FROM " . WPF()->tables->topics . " WHERE `topicid` = %d";
$is_sticky = WPF()->db->get_var( WPF()->db->prepare( $sql, $topicid ) );
}
return (bool) $is_sticky;
}
return false;
}
function is_private( $topicid ) {
if( $topicid ) {
if( WPF()->cache->on() ) {
$private = wpforo_topic( $topicid, 'private' );
} else {
$sql = "SELECT `private` FROM " . WPF()->tables->topics . " WHERE `topicid` = %d";
$private = WPF()->db->get_var( WPF()->db->prepare( $sql, $topicid ) );
}
return (bool) $private;
}
return false;
}
function is_unapproved( $topicid ) {
if( WPF()->cache->on() ) {
$status = wpforo_topic( $topicid, 'status' );
} else {
$status = WPF()->db->get_var( "SELECT `status` FROM " . WPF()->tables->topics . " WHERE `topicid` = " . intval( $topicid ) );
}
if( $status == 1 ) return true;
return false;
}
function is_closed( $topicid ) {
if( $topicid ) {
if( WPF()->cache->on() ) {
$closed = wpforo_topic( $topicid, 'closed' );
} else {
$sql = "SELECT `closed` FROM " . WPF()->tables->topics . " WHERE `topicid` = %d";
$closed = WPF()->db->get_var( WPF()->db->prepare( $sql, $topicid ) );
}
return (bool) $closed;
}
return false;
}
function is_solved( $topicid ) {
if( $topicid ) {
$sql = "SELECT `solved` FROM " . WPF()->tables->topics . " WHERE `topicid` = %d";
$solved = WPF()->db->get_var( WPF()->db->prepare( $sql, $topicid ) );
return (bool) $solved;
}
return false;
}
/**
* Move topic to another forum
*
* @param int $topicid
* @param int $forumid
*
* @return int|false $topicid on success, otherwise false
* @since 1.0.0
*
*/
function move( $topicid, $forumid ) {
$topic = $this->get_topic( $topicid );
if( WPF()->db->query( "UPDATE `" . WPF()->tables->topics . "` SET `forumid` = " . intval( $forumid ) . " WHERE `topicid` = " . intval( $topicid ) ) ) {
WPF()->db->query( "UPDATE `" . WPF()->tables->posts . "` SET `forumid` = " . intval( $forumid ) . " WHERE `topicid` = " . intval( $topicid ) );
do_action( 'wpforo_after_move_topic', $topic, $forumid );
wpforo_clean_cache( 'topic', $topicid, $topic );
WPF()->notice->add( 'Done!', 'success' );
return $topicid;
}
WPF()->notice->add( 'Topic Move Error', 'error' );
return false;
}
/**
* merge topic with target topic
*
* @param array $target target topic array
* @param array $current current topic array
* @param array $postids current topic postids array
* @param int $to_target_title Update post titles with target topic title
* @param int $append Update post dates and append to end
*
* @return bool true|false true on success, otherwise false
*/
public function merge( $target, $current = [], $postids = [], $to_target_title = 0, $append = 0 ) {
if( ! $current ) $current = WPF()->current_object['topic'];
$sql = "UPDATE `" . WPF()->tables->posts . "` SET `topicid` = %d, `forumid` = %d, `private` = %d,`is_first_post` = 0";
$sql = WPF()->db->prepare( $sql, $target['topicid'], $target['forumid'], (int) wpfval( $target, 'private' ) );
if( $append ) {
$sql .= ", `modified` = %s, `created` = %s";
$sql = WPF()->db->prepare( $sql, current_time( 'mysql', 1 ), current_time( 'mysql', 1 ) );
}
if( $to_target_title ) {
$layout = WPF()->forum->get_layout( $target['forumid'] );
$phrase = ( $layout == 3 ? wpforo_phrase( 'Answer to', false ) : wpforo_phrase( 'RE', false ) );
$title = $phrase . ': ' . $target['title'];
$sql .= ", `title` = %s";
$sql = WPF()->db->prepare( $sql, $title );
}
$sql .= " WHERE `topicid` = %d";
$sql = WPF()->db->prepare( $sql, $current['topicid'] );
if( $postids ) {
$postids = (array) $postids;
$postids = array_map( 'wpforo_bigintval', $postids );
$sql .= " AND `postid` IN(" . implode( ',', $postids ) . ")";
}
do_action( 'wpforo_before_merge_topic', $target, $current, $postids, $to_target_title, $append );
$db_resp = WPF()->db->query( $sql );
if( $db_resp !== false ) {
$sql = "SELECT COUNT(*) FROM `" . WPF()->tables->posts . "` WHERE `topicid` = %d";
$sql = WPF()->db->prepare( $sql, $current['topicid'] );
if( ! WPF()->db->get_var( $sql ) ) {
$this->delete( $current['topicid'], true, false );
} else {
$this->rebuild_first_last( $current );
$this->rebuild_stats( $current );
$this->rebuild_threads( $current );
wpforo_clean_cache( 'topic', $current['topicid'], $current );
}
$this->rebuild_first_last( $target );
$this->rebuild_stats( $target );
$this->rebuild_threads( $target );
do_action( 'wpforo_after_merge_topic', $target, $current, $postids, $to_target_title, $append );
WPF()->notice->clear();
WPF()->notice->add( 'Done!', 'success' );
wpforo_clean_cache();
return true;
}
WPF()->notice->add( 'Data merging error', 'error' );
return false;
}
public function split( $args, $to_target_title = 0 ) {
if( ! $args ) return false;
$args['name'] = ( isset( $args['name'] ) ? strip_tags( (string) $args['name'] ) : '' );
$args['email'] = ( isset( $args['email'] ) ? sanitize_email( $args['email'] ) : '' );
if( ! isset( $args['forumid'] ) || ! $args['forumid'] = intval( $args['forumid'] ) ) {
WPF()->notice->add( 'Please select a target forum', 'error' );
return false;
}
if( ! isset( $args['title'] ) || ! $args['title'] = trim( strip_tags( (string) $args['title'] ) ) ) {
WPF()->notice->add( 'Please insert required fields', 'error' );
return false;
}
if( empty( $args['postids'] ) ) {
WPF()->notice->add( 'Please select at least one post to split', 'error' );
return false;
}
$args['postids'] = array_values( $args['postids'] );
if( $fpost = WPF()->post->get_post( $args['postids'][0] ) ) {
$args['title'] = wpforo_text( $args['title'], 250, false );
$args['slug'] = ( isset( $args['slug'] ) && $args['slug'] ) ? sanitize_title( $args['slug'] ) : ( ( isset( $args['title'] ) ) ? sanitize_title( $args['title'] ) : md5( time() ) );
if( ! trim( $args['slug'] ) ) $args['slug'] = md5( time() );
$args['slug'] = $this->unique_slug( $args['slug'] );
$args['body'] = $fpost['body'];
$args['created'] = $fpost['created'];
$args['userid'] = $fpost['userid'];
$args['name'] = $fpost['name'];
$args['email'] = $fpost['email'];
extract( $args );
if( isset( $forumid ) ) $forumid = intval( $forumid );
if( isset( $title ) ) $title = sanitize_text_field( trim( (string) $title ) );
if( isset( $slug ) ) $slug = sanitize_title( $slug );
if( isset( $created ) ) $created = sanitize_text_field( $created );
if( isset( $userid ) ) $userid = intval( $userid );
$type = ( isset( $type ) && $type ? 1 : 0 );
$status = ( isset( $status ) && $status ? 1 : 0 );
$private = ( isset( $private ) && $private ? 1 : 0 );
if( isset( $name ) ) $name = strip_tags( trim( (string) $name ) );
if( isset( $email ) ) $email = strip_tags( trim( (string) $email ) );
$has_attach = ( isset( $has_attach ) && $has_attach ) ? 1 : ( ( strpos( (string) $body, '[attach]' ) !== false ) ? 1 : 0 );
if( WPF()->db->insert(
WPF()->tables->topics,
[
'title' => stripslashes(
$title
),
'slug' => $slug,
'forumid' => $forumid,
'userid' => $userid,
'type' => $type,
'status' => $status,
'private' => $private,
'created' => $created,
'modified' => $created,
'last_post' => 0,
'views' => 0,
'posts' => 1,
'has_attach' => $has_attach,
'name' => $name,
'email' => $email,
],
[ '%s', '%s', '%d', '%d', '%d', '%d', '%d', '%s', '%s', '%d', '%d', '%d', '%d', '%s', '%s' ]
) ) {
$args['topicid'] = $topicid = WPF()->db->insert_id;
if( $this->merge( $args, WPF()->current_object['topic'], $args['postids'], $to_target_title ) ) {
WPF()->notice->clear();
WPF()->notice->add( 'Done!', 'success' );
return $topicid;
}
}
}
WPF()->notice->add( 'Topic splitting error', 'error' );
return false;
}
/**
* @deprecated since 2.0.10 instead this method use _get_url()
*
* @param $topic
* @param $forum
* @param $_cache
*
* @return string
*/
public function _get_topic_url( $topic, $forum = [], $_cache = true ) {
return $this->_get_url( $topic, $forum, $_cache );
}
/**
* @param $topic
* @param $forum
* @param $_cache
*
* @return string
*/
public function _get_url( $topic, $forum = [], $_cache = true ) {
if( wpforo_setting( 'board', 'url_structure' ) === 'short' ) return $this->get_short_url( $topic );
return $this->get_full_url( $topic, $forum, $_cache );
}
public function get_full_url( $topic, $forum = [], $_cache = true ) {
if( ! is_array( $topic ) ) $topic = $this->get_topic( $topic );
if( $topic ) {
$cache = WPF()->cache->on('url');
// $_cache is used to stop caching on merge and move actions,
// otherwise the merging and splitting go to redirection loop
if( $_cache && $cache && wpfval($topic, 'topicid') ) {
$topic_url = (string) WPF()->cache->get_item( $topic['topicid'], 'url', 'topic' );
if( $topic_url ) return $topic_url;
}
if( is_array( $forum ) && ! empty( $forum ) ) {
$forum_slug = $forum['slug'];
} else {
$forum_slug = '';
if( wpfval( $topic, 'forumid' ) ) {
$forum_slug = $this->get_forumslug( $topic['forumid'] );
} elseif( wpfval( $topic, 'topicid' ) ) {
$forum_slug = $this->get_forumslug_byid( $topic['topicid'] );
}
}
if( wpfval( $topic, 'slug' ) ) {
$topic_url = wpforo_home_url( $forum_slug . '/' . $topic['slug'] );
if( $cache ) WPF()->cache->create( 'item', [ 'topic_' . intval( $topic['topicid'] ) => $topic_url ], 'url' );
return $topic_url;
}
}
return wpforo_home_url();
}
public function get_short_url( $arg ) {
if( is_numeric( $arg ) ){
$topicid = $arg;
}elseif( wpfkey( $arg, 'topicid' ) ){
$topicid = $arg['topicid'];
}else{
$topicid = 0;
}
if( $topicid = wpforo_bigintval( $topicid ) ) return wpforo_home_url( '/' . wpforo_settings_get_slug( 'topicid' ) . '/' . $topicid . '/' );
return wpforo_home_url();
}
/**
* @deprecated since 2.0.10 instead this method use get_url()
*
* @param $topic
* @param $forum
* @param $_cache
*
* @return string
*/
public function get_topic_url( $topic, $forum = [], $_cache = true ) {
return $this->get_url( $topic, $forum, $_cache );
}
/**
* @param $topic
* @param $forum
* @param $_cache
*
* @return string
*/
public function get_url( $topic, $forum = [], $_cache = true ) {
return (string) wpforo_ram_get( [ $this, '_get_url' ], $topic, $forum, $_cache );
}
function get_count( $args = [] ) {
$sql = "SELECT SQL_NO_CACHE COUNT(*) FROM `" . WPF()->tables->topics . "`";
if( ! empty( $args ) ) {
$wheres = [];
foreach( $args as $key => $value ) $wheres[] = "`$key` = '" . esc_sql( $value ) . "'";
if( $wheres ) $sql .= " WHERE " . implode( ' AND ', $wheres );
}
return WPF()->db->get_var( $sql );
}
public function set_status( $topicid, $status ) {
$topicid = wpforo_bigintval( $topicid );
$status = intval( $status );
if( ! $topic = $this->get_topic( $topicid, false ) ) return false;
if( $r = WPF()->db->update( WPF()->tables->topics, [ 'status' => $status ], [ 'topicid' => $topicid ], [ '%d' ], [ '%d' ] ) ) {
if( $status ) {
do_action( 'wpforo_topic_unapprove', $topic );
if( wpfval( $topic, 'tags' ) ) $this->remove_tags( $topic['tags'] );
} else {
do_action( 'wpforo_topic_approve', $topic );
if( wpfval( $topic, 'tags' ) ) $this->add_tags( $topic['tags'] );
}
do_action( 'wpforo_topic_status_update', $topic, $status );
wpforo_clean_cache( 'topic-first-post', $topicid );
}
if( $r !== false ){
WPF()->notice->add( 'Done!', 'success' );
return true;
}
WPF()->notice->add( 'Status changing error', 'error' );
return false;
}
public function wprivate( $topicid, $private ) {
WPF()->db->update( WPF()->tables->topics, [ 'private' => $private ], [ 'topicid' => $topicid ], [ '%d' ], [ '%d' ] );
WPF()->db->update( WPF()->tables->posts, [ 'private' => $private ], [ 'topicid' => $topicid ], [ '%d' ], [ '%d' ] );
do_action( 'wpforo_topic_private_update', $topicid, $private );
wpforo_clean_cache();
return true;
}
public function delete_attachments( $topicid ) {
$args = [ 'topicid' => $topicid ];
$posts = WPF()->post->get_posts( $args );
if( ! empty( $posts ) ) {
foreach( $posts as $post ) {
WPF()->post->delete_attachments( $post['postid'] );
}
}
}
public function rebuild_stats( $topic ) {
if( ! $topic ) return false;
if( is_numeric( $topic ) ) $topic = $this->get_topic( $topic );
if( ! is_array( $topic ) || ! $topic ) return false;
$posts = WPF()->post->get_count( [ 'topicid' => $topic['topicid'], 'status' => 0 ] );
$data = [ 'posts' => $posts, 'answers' => 0 ];
$data_format = [ '%d', '%d' ];
$layout = WPF()->forum->get_layout( $topic['forumid'] );
if( $layout === 3 ) {
$data['answers'] = WPF()->post->get_count( [ 'topicid' => $topic['topicid'], 'status' => 0, 'parentid' => 0, 'is_first_post' => 0 ] );
$data['posts'] = $posts - 1;
}
if( $r = WPF()->db->update( WPF()->tables->topics, $data, [ 'topicid' => $topic['topicid'] ], $data_format, [ '%d' ] ) ) {
wpforo_clean_cache( 'topic-first-post', $topic['topicid'], $topic );
}
return $r !== false;
}
public function rebuild_first_last( $topic ) {
if( ! $topic ) return false;
if( is_numeric( $topic ) ) $topic = $this->get_topic( $topic );
if( ! is_array( $topic ) || ! $topic ) return false;
$sql = "SELECT `postid` FROM `" . WPF()->tables->posts . "` WHERE `topicid` = %d ORDER BY `is_first_post` DESC, `created` ASC, `postid` ASC LIMIT 1";
if( $first_postid = WPF()->db->get_var( WPF()->db->prepare( $sql, $topic['topicid'] ) ) ) {
$sql = "UPDATE `" . WPF()->tables->posts . "` SET `is_first_post` = 1 WHERE `postid` = %d";
WPF()->db->query( WPF()->db->prepare( $sql, $first_postid ) );
do_action( 'wpforo_after_is_first_post_update', $first_postid, 1 );
} else {
$first_postid = 0;
}
$sql = "SELECT `postid`, `created`
FROM `" . WPF()->tables->posts . "`
WHERE `topicid` = %d
ORDER BY `is_first_post` ASC, `created` DESC, `postid` DESC LIMIT 1";
if( ! $last_post = WPF()->db->get_row( WPF()->db->prepare( $sql, $topic['topicid'] ), ARRAY_A ) ) {
$last_post = [ 'postid' => 0, 'created' => $topic['modified'] ];
}
if( $r = WPF()->db->update(
WPF()->tables->topics,
[
'first_postid' => $first_postid,
'last_post' => $last_post['postid'],
'modified' => $last_post['created'],
],
[ 'topicid' => $topic['topicid'] ],
[ '%d', '%d', '%s' ],
[ '%d' ]
) ) {
wpforo_clean_cache( 'topic-first-post' );
}
return $r !== false;
}
function rebuild_threads( $topicid, $root = null ) {
if( ! is_null( $root ) && $root <= 0 ) return;
if( is_array( $topicid ) && wpfval( $topicid, 'topicid' ) ) $topicid = $topicid['topicid'];
if( $topicid ) {
$posts = WPF()->db->get_results( "SELECT * FROM `" . WPF()->tables->posts . "` WHERE `topicid` = " . intval( $topicid ), ARRAY_A );
if( ! empty( $posts ) ) {
$threads = [];
foreach( $posts as $post ) {
$threads[ $post['postid'] ] = [ 'postid' => $post['postid'], 'parentid' => $post['parentid'] ];
}
unset( $posts );
foreach( $threads as $item ) {
if( ! is_null( $root ) && $root != $item['postid'] ) continue;
if( ! $item['parentid'] ) {
$thread = WPF()->post->build_thread_data( $item['postid'], $threads );
if( wpfval( $thread, 'children' ) ) {
$children = implode( ',', $thread['children'] );
WPF()->db->query( "UPDATE `" . WPF()->tables->posts . "` SET `root` = 0 WHERE `postid` = " . intval( $item['postid'] ) );
WPF()->db->query( "UPDATE `" . WPF()->tables->posts . "` SET `root` = " . intval( $item['postid'] ) . " WHERE `postid` IN(" . esc_sql( $children ) . ")" );
}
} elseif( ! wpfkey( $threads, $item['parentid'] ) ) {
WPF()->db->query( "UPDATE `" . WPF()->tables->posts . "` SET `root` = 0, `parentid` = 0 WHERE `postid` = " . intval( $item['postid'] ) );
}
}
}
}
}
function rebuild_forum_threads( $forumid = 0 ) {
if( ! $forumid ) {
$args = [ 'layout' => 4 ];
$forums = WPF()->forum->get_forums( $args );
if( ! empty( $forums ) ) {
foreach( $forums as $forum ) {
$args = [ 'forumid' => $forum['forumid'] ];
$topics = $this->get_topics( $args );
if( ! empty( $topics ) ) {
foreach( $topics as $topic ) {
$this->rebuild_threads( $topic['topicid'] );
}
}
}
}
} else {
$args = [ 'forumid' => $forumid ];
$topics = $this->get_topics( $args );
if( ! empty( $topics ) ) {
foreach( $topics as $topic ) {
$this->rebuild_threads( $topic['topicid'] );
}
}
}
}
public function members( $topicid, $limit = 0 ) {
if( ! $topicid ) return [];
$members = [];
$args = [
'topicid' => $topicid,
'orderby' => 'created',
'order' => 'ASC',
'private' => 0,
'status' => 0,
'cache_type' => 'args',
];
$posts = WPF()->post->get_posts( $args );
foreach( $posts as $post ) {
if( wpfval( $post, 'userid' ) ) {
$members[ $post['userid'] ] = wpforo_member( $post['userid'] );
if( $limit && count( $members ) >= $limit ) break;
}
}
return array_filter( $members );
}
public function can_answer( $topicid ) {
if( ! $topicid ) return false;
$topic = wpforo_topic( $topicid );
if( wpfval( $topic, 'topicid' ) ) {
if( wpfval( $topic, 'userid' ) ) {
if( ! WPF()->perm->forum_can( 'aot', $topic['forumid'] ) && WPF()->current_userid == $topic['userid'] ) {
return false;
}
} else {
$guest = WPF()->member->get_guest_cookies();
if( wpfval( $topic, 'email' ) && wpfval( $guest, 'email' ) ) {
if( ! WPF()->perm->forum_can( 'aot', $topic['forumid'] ) && $topic['email'] == $guest['email'] ) {
return false;
}
}
}
}
return true;
}
/**
* @param $topicid
*
* @return bool
*/
public function has_is_answer_post( $topicid ) {
if( ! $topicid ) return false;
$sql = "SELECT EXISTS ( SELECT * FROM `" . WPF()->tables->posts . "` WHERE `is_answer` = 1 AND `topicid` = %d) AS is_exists";
$sql = WPF()->db->prepare( $sql, $topicid );
return (bool) WPF()->db->get_var( $sql );
}
public function get_postids( $topicid ) {
$sql = "SELECT `postid`
FROM `" . WPF()->tables->posts . "`
WHERE `topicid` = %d";
$sql = WPF()->db->prepare( $sql, $topicid );
return array_map( 'wpforo_bigintval', WPF()->db->get_col( $sql ) );
}
public function add_tags( $tags ) {
if( $tags ) {
$tags = $this->sanitize_tags( $tags, true );
if( ! empty( $tags ) ) {
$tags = array_slice( $tags, 0, wpforo_setting( 'tags', 'max_per_topic' ) );
foreach( $tags as $tag ) {
$count = (int) WPF()->db->get_var( "SELECT `count` FROM `" . WPF()->tables->tags . "` WHERE `tag` = '" . esc_sql( $tag ) . "'" );
if( $count ) {
WPF()->db->update( WPF()->tables->tags, [ 'count' => $count + 1 ], [ 'tag' => $tag ], [ '%d' ], [ '%s' ] );
} else {
$this->add_tag( $tag, 1 );
}
wpforo_clean_cache( 'tag', $tag );
}
wpforo_clean_cache( 'tag' );
}
}
}
public function add_tag( $tag, $count = 0 ) {
$tagid = 0;
if( $tag ) {
$tag = $this->sanitize_tag( $tag );
if( ! WPF()->db->get_var( "SELECT `tagid` FROM `" . WPF()->tables->tags . "` WHERE `tag` = '" . esc_sql( $tag ) . "'" ) ) {
$tagid = WPF()->db->insert( WPF()->tables->tags, [ 'tag' => $tag, 'prefix' => 0, 'count' => intval( $count ) ], [ '%s', '%d', '%d' ] );
}
}
return $tagid;
}
public function edit_tags( $tags, $topic = [] ) {
$old_tags = ( wpfval( $topic, 'tags' ) ) ? $this->sanitize_tags( $topic['tags'], true ) : false;
if( $tags ) {
$tags = $this->sanitize_tags( $tags, true );
$tags = array_slice( $tags, 0, wpforo_setting( 'tags', 'max_per_topic' ) );
if( ! empty( $tags ) ) {
if( wpfval( $topic, 'topicid' ) ) {
if( ! empty( $old_tags ) ) {
foreach( $old_tags as $old_tag ) {
if( ! in_array( $old_tag, $tags ) ) {
$this->remove_tags( $old_tag );
}
}
}
}
if( ! wpfval( $topic, 'status' ) && ! wpfval( $topic, 'private' ) ) {
foreach( $tags as $tag ) {
$count = (int) WPF()->db->get_var( "SELECT `count` FROM `" . WPF()->tables->tags . "` WHERE `tag` = '" . esc_sql( $tag ) . "'" );
if( ! $count ) {
WPF()->db->insert( WPF()->tables->tags, [ 'tag' => $tag, 'prefix' => 0, 'count' => 1 ], [ '%s', '%d', '%d' ] );
} elseif( empty( $old_tags ) || ! in_array( $tag, $old_tags ) ) {
WPF()->db->update( WPF()->tables->tags, [ 'count' => ( $count + 1 ) ], [ 'tag' => $tag ], [ '%d' ], [ '%s' ] );
}
wpforo_clean_cache( 'tag', $tag );
}
}
}
} else {
if( ! empty( $old_tags ) && wpfval( $topic, 'topicid' ) ) {
WPF()->db->update( WPF()->tables->topics, [ 'tags' => '' ], [ 'topicid' => $topic['topicid'] ], [ '%s' ], [ '%d' ] );
$this->remove_tags( $old_tags );
}
}
wpforo_clean_cache( 'tag' );
}
public function edit_tag( $tag, $old_tag = '', $disconnect = false ) {
$tag_id = wpfval( $tag, 'tagid' );
$tag_name = wpfval( $tag, 'tag' );
$tag_name = $this->sanitize_tag( $tag_name );
if( false !== WPF()->db->update( WPF()->tables->tags, [ 'tag' => $tag_name ], [ 'tagid' => intval( $tag_id ) ], [ '%s' ], [ '%d' ] ) ) {
if( $old_tag ) {
if( $disconnect ) {
$this->remove_tag_from_topics( $old_tag );
WPF()->db->update( WPF()->tables->tags, [ 'count' => 0 ], [ 'tag' => $tag_name ], [ '%d' ], [ '%s' ] );
} else {
if( $old_tag != $tag_name ) {
$this->update_tag_in_topics( $tag_name, $old_tag );
}
$count = WPF()->db->get_var( "SELECT COUNT(*) FROM `" . WPF()->tables->topics . "` WHERE FIND_IN_SET('" . esc_sql( $tag_name ) . "', tags)" );
WPF()->db->update( WPF()->tables->tags, [ 'count' => intval( $count ) ], [ 'tag' => $tag_name ], [ '%d' ], [ '%s' ] );
}
}
wpforo_clean_cache( 'tag', $tag_name );
return true;
}
return false;
}
public function remove_tags( $tags ) {
if( $tags ) {
$tags = $this->sanitize_tags( $tags, true );
foreach( $tags as $tag ) {
$count = (int) WPF()->db->get_var( "SELECT `count` FROM `" . WPF()->tables->tags . "` WHERE `tag` = '" . esc_sql( $tag ) . "'" );
if( $count === 1 ) {
WPF()->db->query( "DELETE FROM `" . WPF()->tables->tags . "` WHERE `tag` = '" . esc_sql( $tag ) . "'" );
} else {
WPF()->db->update( WPF()->tables->tags, [ 'count' => ( $count - 1 ) ], [ 'tag' => $tag ], [ '%d' ], [ '%s' ] );
}
wpforo_clean_cache( 'tag', $tag );
}
}
wpforo_clean_cache( 'tag' );
}
public function remove_tag( $tag ) {
if( $tag ) {
$this->remove_tag_from_topics( $tag );
$sql_delete_tag = "DELETE FROM `" . WPF()->tables->tags . "` WHERE `tag` = '" . esc_sql( $tag ) . "'";
WPF()->db->query( $sql_delete_tag );
wpforo_clean_cache( 'tag', $tag );
}
}
public function remove_tag_from_topics( $tag ) {
if( $tag ) {
WPF()->db->query(
"UPDATE `" . WPF()->tables->topics . "`
SET tags = TRIM(BOTH ',' FROM REPLACE(CONCAT(',', tags, ','), '," . esc_sql( $tag ) . ",', ','))
WHERE FIND_IN_SET('" . esc_sql( $tag ) . "', tags)"
);
}
}
public function update_tag_in_topics( $new_tag, $old_tag ) {
if( $new_tag && $old_tag ) {
WPF()->db->query(
"UPDATE `" . WPF()->tables->topics . "`
SET tags = '" . esc_sql( $new_tag ) . "'
WHERE tags LIKE '" . esc_sql( $old_tag ) . "'"
);
WPF()->db->query(
"UPDATE `" . WPF()->tables->topics . "`
SET tags = REPLACE(tags, '," . esc_sql( $old_tag ) . ",', '," . esc_sql( $new_tag ) . ",')
WHERE tags LIKE '%," . esc_sql( $old_tag ) . ",%'"
);
$topics = WPF()->db->get_results(
"SELECT `topicid`, `tags`
FROM `" . WPF()->tables->topics . "`
WHERE FIND_IN_SET('" . esc_sql( $old_tag ) . "', tags)",
ARRAY_A
);
if( ! empty( $topics ) ) {
foreach( $topics as $topic ) {
$tags = explode( ',', $topic['tags'] );
if( ! empty( $tags ) ) {
foreach( $tags as $key => $tag ) {
if( $tag === $old_tag ) $tags[ $key ] = $new_tag;
}
$tags = implode( ',', $tags );
WPF()->db->update( WPF()->tables->topics, [ 'tags' => $tags ], [ 'topicid' => $topic['topicid'] ], [ '%s' ], [ '%d' ] );
}
}
}
}
}
public function get_tag( $args = [] ) {
if( $args ) {
$default = [
'tagid' => null,
'tag' => null,
];
if( is_numeric( $args ) ) {
$args = [ 'tagid' => $args ];
} elseif( is_string( $args ) ) {
$args = [ 'tag' => $args ];
}
$args = wpforo_parse_args( $args, $default );
$sql = "SELECT * FROM `" . WPF()->tables->tags . "`";
$wheres = [];
if( $args['tagid'] ) $wheres[] = "`tagid` = " . intval( $args['tagid'] );
if( $args['tag'] ) $wheres[] = "`tag` = '" . esc_sql( $args['tag'] ) . "'";
if( $wheres ) {
$sql .= " WHERE " . implode( " AND ", $wheres );
if( WPF()->ram_cache->exists( $sql ) ) {
$tag = WPF()->ram_cache->get( $sql );
} else {
$tag = WPF()->db->get_row( $sql, ARRAY_A );
WPF()->ram_cache->set( $sql, $tag );
}
return $tag;
}
}
return [];
}
public function get_tags( $args = [], &$items_count = 0 ) {
$cache = WPF()->cache->on('tag');
$default = [
'tag' => '',
'prefix' => 0,
'count' => null,
'orderby' => 'count',
'order' => 'DESC',
'offset' => null,
'row_count' => null,
];
$args = wpforo_parse_args( $args, $default );
$sql = "SELECT * FROM `" . WPF()->tables->tags . "`";
$wheres = [];
$wheres[] = " `prefix` = " . intval( $args['prefix'] );
if( ! empty( $wheres ) ) $sql .= " WHERE " . implode( " AND ", $wheres );
$item_count_sql = preg_replace( '#SELECT.+?FROM#isu', 'SELECT count(*) FROM', $sql );
if( $item_count_sql ) $items_count = WPF()->db->get_var( $item_count_sql );
$sql .= " ORDER BY `" . esc_sql( $args['orderby'] ) . "` " . esc_sql( $args['order'] );
if( $args['row_count'] != null ) {
if( $args['offset'] != null ) {
$sql .= " LIMIT " . intval( $args['offset'] ) . ',' . intval( $args['row_count'] );
} else {
$sql .= " LIMIT " . intval( $args['row_count'] );
}
}
if( $cache ) {
$object_key = md5( $sql . WPF()->current_user_groupid );
$object_cache = WPF()->cache->get( $object_key, 'loop', 'tag' );
if( ! empty( $object_cache ) ) {
$items_count = $object_cache['items_count'];
return $object_cache['items'];
}
}
$tags = WPF()->db->get_results( $sql, ARRAY_A );
$tags = apply_filters( 'wpforo_get_tags', $tags );
if( $cache && isset( $object_key ) && ! empty( $tags ) ) {
self::$cache['tags'][ $object_key ]['items'] = $tags;
self::$cache['tags'][ $object_key ]['items_count'] = $items_count;
WPF()->cache->create( 'loop', self::$cache, 'tag' );
}
return $tags;
}
public function sanitize_tags( $tags, $array = false, $limit = false ) {
if( $tags ) {
if( ! is_array( $tags ) ) {
$tag_separator = ( strpos($tags,'،') !== FALSE ) ? '،' : ',';
$tag_separator = apply_filters( 'wpforo_tag_separator', $tag_separator );
$tags = wp_unslash( $tags );
//Replace other tag separators to regular comma to store in the database
$tags = str_replace($tag_separator, ',', $tags);
$tags = explode( $tag_separator, $tags );
}
if( wpforo_setting( 'tags', 'lowercase' ) ) {
if( function_exists( 'mb_strtolower' ) ) {
$tags = array_map( 'mb_strtolower', $tags );
} else {
$tags = array_map( 'strtolower', $tags );
}
}
$length = wpforo_setting( 'tags', 'length' );
$mb_substr = function_exists( 'mb_substr' );
foreach( $tags as $key => $tag ) {
if( $mb_substr ) {
$tags[ $key ] = mb_substr( (string) $tag, 0, $length );
} else {
$tags[ $key ] = substr( (string) $tag, 0, $length );
}
}
$tags = array_map( 'trim', $tags );
$tags = array_map( 'sanitize_text_field', $tags );
$tags = array_filter( $tags );
$tags = array_unique( $tags );
if( $limit ) {
$tags = array_slice( $tags, 0, wpforo_setting( 'tags', 'max_per_topic' ) );
}
if( $array ) {
return $tags;
} else {
// We keep using "," in the database even if the separator is different
return implode( ',', $tags );
}
}
if( $array ) {
return [];
} else {
return '';
}
}
public function sanitize_tag( $tag ) {
$tag = trim( (string) $tag );
$tag = wp_unslash( $tag );
$tag = sanitize_text_field( $tag );
$length = wpforo_setting( 'tags', 'length' );
$tag = ( function_exists( 'mb_substr' ) ) ? mb_substr( (string) $tag, 0, $length ) : substr( (string) $tag, 0, $length );
$lowcase = wpforo_setting( 'tags', 'lowercase' );
if( $lowcase ) {
$tag = ( function_exists( 'mb_strtolower' ) ) ? mb_strtolower( (string) $tag ) : strtolower( (string) $tag );
}
return $tag;
}
public function after_add_post( $post, $topic ) {
if( !intval( $post['status'] ) ){
$this->rebuild_first_last( $topic );
$this->rebuild_stats( $topic );
}
}
public function after_delete_post( $post ) {
if( !intval( $post['status'] ) ){
$this->rebuild_first_last( $post['topicid'] );
$this->rebuild_stats( $post['topicid'] );
}
}
public function after_post_status_update( $post ) {
if( $topic = $this->get_topic( $post['topicid'] ) ){
$this->rebuild_first_last( $topic );
$this->rebuild_stats( $topic );
}
}
public function after_delete_user( $userid, $reassign ) {
if( $boardids = WPF()->board->get_active_boardids() ){
if( is_null( $reassign ) ) {
foreach( $boardids as $boardid ){
WPF()->change_board( $boardid );
if( $topicids = WPF()->db->get_col( WPF()->db->prepare( "SELECT `topicid` FROM `" . WPF()->tables->topics . "` WHERE userid = %d", $userid ) ) ) {
foreach( $topicids as $topicid ) $this->delete( $topicid, false, false );
}
}
} else {
if( $reassign = wpforo_bigintval( $reassign ) ){
$data = [ 'userid' => $reassign ];
$format = [ '%d' ];
}else{
$data = [
'userid' => 0,
'name' => wpforo_phrase( 'Anonymous', false ) . " " . $userid,
'email' => "anonymous_$userid@example.com",
];
$format = [ '%d', '%s', '%s' ];
}
foreach( $boardids as $boardid ){
WPF()->change_board( $boardid );
WPF()->db->update( WPF()->tables->topics, $data, [ 'userid' => $userid ], $format, ['%d'] );
}
}
}
}
}