ap_opt( 'question_per_page' ), 'paged' => $paged, 'ap_query' => true, 'ap_order_by' => 'active', 'ap_question_query' => true, 'post_status' => [ 'publish' ], 'ap_current_user_ignore' => false, ); $this->args = wp_parse_args( $args, $defaults ); $this->args['ap_order_by'] = sanitize_title( $this->args['ap_order_by'] ); // Check if user can read private post. if ( ap_user_can_view_private_post( ) ) { $this->args['post_status'][] = 'private_post'; } // Check if user can read moderate posts. if ( ap_user_can_view_moderate_post( ) ) { $this->args['post_status'][] = 'moderate'; } // Check if user can read moderate posts. if ( ap_user_can_view_future_post( ) ) { $this->args['post_status'][] = 'future'; } // Show trash posts to super admin. if ( is_super_admin( ) ) { $this->args['post_status'][] = 'trash'; } $this->args['post_status'] = array_unique( $this->args['post_status'] ); if ( $post_parent ) { $this->args['post_parent'] = $post_parent; } if ( '' !== get_query_var( 'ap_s' ) ) { $this->args['s'] = ap_sanitize_unslash( 'ap_s', 'query_var' ); } $this->args['post_type'] = 'question'; parent::__construct( $this->args ); } /** * Get posts. */ public function get_questions() { return parent::get_posts(); } /** * Update loop index to next post. */ public function next_question() { return parent::next_post(); } /** * Undo the pointer to next. */ public function reset_next() { $this->current_post--; $this->post = $this->posts[ $this->current_post ]; return $this->post; } /** * Set current question in loop. */ public function the_question() { global $post; $this->in_the_loop = true; if ( -1 === $this->current_post ) { do_action_ref_array( 'ap_query_loop_start', array( &$this ) ); } $post = $this->next_question(); // override ok. setup_postdata( $post ); anspress()->current_question = $post; } /** * Check if loop have questions. * * @return boolean */ public function have_questions() { return parent::have_posts(); } /** * Rewind questions in loop. */ public function rewind_questions() { parent::rewind_posts(); } /** * Check if main question query. * * @return boolean */ public function is_main_query() { return anspress()->questions === $this; } /** * Reset current question in loop. */ public function reset_questions_data() { parent::reset_postdata(); if ( ! empty( $this->post ) ) { anspress()->current_question = $this->post; } } /** * Utility method to get all the ids in this request * * @return array of question ids */ public function get_ids() { if ( $this->ap_ids ) { return; } $this->ap_ids = [ 'post_ids' => [], 'attach_ids' => [], 'user_ids' => [] ]; foreach ( (array) $this->posts as $_post ) { $this->ap_ids['post_ids'][] = $_post->ID; $this->ap_ids['attach_ids'] = array_merge( explode( ',', $_post->attach ), $this->ap_ids['attach_ids'] ); if ( ! empty( $_post->post_author ) ) { $this->ap_ids['user_ids'][] = $_post->post_author; } // Add activities user_id to array. if ( ! empty( $_post->activities ) && ! empty( $_post->activities['user_id'] ) ) { $this->ap_ids['user_ids'][] = $_post->activities['user_id']; } } // Unique ids only. foreach ( (array) $this->ap_ids as $k => $ids ) { $this->ap_ids[ $k ] = array_unique( $ids ); } } /** * Pre fetch current users vote on all answers * * @since 3.1.0 * @since 4.1.2 Prefetch post activities. */ public function pre_fetch() { $this->get_ids(); ap_prefetch_recent_activities( $this->ap_ids['post_ids'] ); ap_user_votes_pre_fetch( $this->ap_ids['post_ids'] ); ap_post_attach_pre_fetch( $this->ap_ids['attach_ids'] ); // Pre fetch users. if ( ! empty( $this->ap_ids['user_ids'] ) ) { ap_post_author_pre_fetch( $this->ap_ids['user_ids'] ); } do_action( 'ap_pre_fetch_question_data', $this->ap_ids ); } } /** * Get posts with qameta fields. * * @param mixed $post Post object. * @return object */ function ap_get_post( $post = null ) { if ( empty( $post ) && isset( $GLOBALS['post'] ) ) { $post = $GLOBALS['post']; // override ok. } if ( $post instanceof WP_Post || is_object( $post ) ) { $_post = $post; } elseif ( false !== $post_o = wp_cache_get( $post, 'posts' ) ) { $_post = $post_o; } else { $_post = WP_Post::get_instance( $post ); } if ( $_post && ! isset( $_post->ap_qameta_wrapped ) ) { $_post = ap_append_qameta( $_post ); wp_cache_set( $_post->ID, $_post, 'posts' ); } return $_post; } /** * Check if there is post in loop * * @return boolean */ function ap_have_questions() { if ( anspress()->questions ) { return anspress()->questions->have_posts(); } } /** * Set current question in loop. * * @return Object */ function ap_the_question() { if ( anspress()->questions ) { return anspress()->questions->the_question(); } } /** * Return total numbers of questions found. * * @return integer */ function ap_total_questions_found() { if ( anspress()->questions ) { return anspress()->questions->found_posts; } } /** * Reset original question query. * * @return boolean * @since unknown * @since 4.1.0 Check if global `$questions` exists. */ function ap_reset_question_query() { if ( anspress()->questions ) { return anspress()->questions->reset_questions_data(); } } /** * Return link of user profile page * * @return string */ function ap_get_profile_link() { global $post; if ( ! $post ) { return false; } return ap_user_link( $post->post_author ); } /** * Echo user profile link */ function ap_profile_link() { echo ap_get_profile_link(); // xss ok. } /** * Return question author avatar. * * @param integer $size Avatar size. * @param mixed $_post Post. * @return string */ function ap_get_author_avatar( $size = 45, $_post = null ) { $_post = ap_get_post( $_post ); if ( ! $_post ) { return; } $author = 0 == $_post->post_author ? 'anonymous_' . $_post->ID : $_post->post_author; // @codingStandardsIgnoreLine // @codingStandardsIgnoreLine if ( false !== strpos( $author, 'anonymous' ) && is_array( $_post->fields ) && ! empty( $_post->fields['anonymous_name'] ) ) { $author = $_post->fields['anonymous_name']; } return get_avatar( $author, $size ); } /** * Echo question author avatar. * * @param integer $size Avatar size. * @param mixed $_post Post. */ function ap_author_avatar( $size = 45, $_post = null ) { echo ap_get_author_avatar( $size, $_post ); // xss ok. } /** * Return hover card attributes. * * @param mixed $_post Post ID, Object or null. * @return string */ function ap_get_hover_card_attr( $_post = null ) { $_post = ap_get_post( $_post ); if ( ! $_post ) { return; } return ap_hover_card_attributes( $_post->post_author ); } /** * Echo hover card attributes. * * @param mixed $_post Post ID, Object or null. */ function ap_hover_card_attr( $_post = null ) { echo ap_get_hover_card_attr( $_post ); // xss ok. } /** * Return total published answer count. * * @param mixed $_post Post ID, Object or null. * @return integer */ function ap_get_answers_count( $_post = null ) { $_post = ap_get_post( $_post ); return $_post->answers; } /** * Echo total votes count of a post. * * @param mixed $_post Post ID, Object or null. */ function ap_answers_count( $_post = null ) { echo ap_get_answers_count( $_post ); // xss ok. } /** * Return count of net vote of a question. * * @param mixed $_post Post ID, Object or null. * @return integer */ function ap_get_votes_net( $_post = null ) { $_post = ap_get_post( $_post ); return $_post->votes_net; } /** * Echo count of net vote of a question. * * @param mixed $_post Post ID, Object or null. */ function ap_votes_net( $_post = null ) { echo ap_get_votes_net( $_post ); // xss ok. } /** * Echo post status of a question. * * @param mixed $_post Post ID, Object or null. */ function ap_question_status( $_post = null ) { $_post = ap_get_post( $_post ); if ( 'publish' === $_post->post_status ) { return; } $status_obj = get_post_status_object( $_post->post_status ); echo '' . esc_attr( $status_obj->label ) . ''; } /** * Question meta to display. * * @param false|integer $question_id question id. * @since unknown * @since 4.1.2 Use @see ap_recent_activity() for showing activity. */ function ap_question_metas( $question_id = false ) { if ( false === $question_id ) { $question_id = get_the_ID(); } $metas = array(); // If featured question. if ( ap_is_featured_question( $question_id ) ) { $metas['featured'] = __( 'Featured', 'anspress-question-answer' ); } if ( ap_have_answer_selected() ) { $metas['solved'] = '' . __( 'Solved', 'anspress-question-answer' ) . ''; } $view_count = ap_get_post_field( 'views' ); $metas['views'] = '' . sprintf( __( '%d views', 'anspress-question-answer' ), $view_count ) . ''; if ( is_question() ) { $last_active = ap_get_last_active( get_question_id() ); $metas['active'] = ''; } if ( ! is_question() ) { $metas['history'] = '' . ap_recent_activity( $question_id, false ); } /** * Used to filter question display meta. * * @param array $metas */ $metas = apply_filters( 'ap_display_question_metas', $metas, $question_id ); $output = ''; if ( ! empty( $metas ) && is_array( $metas ) ) { foreach ( $metas as $meta => $display ) { $output .= "{$display}"; } } echo $output; // xss ok. } /** * Get recent activity of a post. * * @param mixed $_post Post ID, Object or null. * @return string */ function ap_get_recent_post_activity( $_post = null ) { $_post = ap_get_post( $_post ); return ap_latest_post_activity_html( $_post->ID ); } /** * Echo recent activity of a post. */ function ap_recent_post_activity() { echo ap_get_recent_post_activity(); // xss ok. } /** * Get last active time in human readable format. * * @param mixed $post_id Post ID/Object. * @return string * @since 2.4.8 Convert mysql date to GMT. */ function ap_get_last_active( $post_id = null ) { $p = ap_get_post( $post_id ); $date = ! empty( $p->last_updated ) ? $p->last_updated : $p->post_modified_gmt; return ap_human_time( get_gmt_from_date( $date ), false ); } /** * Echo last active time in human readable format. * * @param mixed $post_id Post ID/Object. * @since 2.4.8 Convert mysql date to GMT. */ function ap_last_active( $post_id = null ) { echo esc_attr( ap_get_last_active( $post_id ) ); } /** * Check if question have answer selected. * * @param mixed $question Post object or ID. * @return boolean */ function ap_have_answer_selected( $question = null ) { $question = ap_get_post( $question ); return ! empty( $question->selected_id ); } /** * Return the ID of selected answer from a question. * * @param object|null|integer $_post Post object, ID or null. * @return integer */ function ap_selected_answer( $_post = null ) { $_post = ap_get_post( $_post ); if ( ! $_post ) { return false; } return $_post->selected_id; } /** * Check if current answer is selected as a best * * @param mixed $_post Post. * @return boolean * @since 2.1 */ function ap_is_selected( $_post = null ) { $_post = ap_get_post( $_post ); if ( ! $_post ) { return false; } return (bool) $_post->selected; } /** * Return post time. * * @param mixed $_post Post ID, Object or null. * @param string $format Date format. * @return String */ function ap_get_time( $_post = null, $format = '' ) { $_post = ap_get_post( $_post ); if ( ! $_post ) { return; } return get_post_time( $format, true, $_post->ID, true ); } /** * Check if current post is marked as featured * * @param boolean|integer $question Question ID to check. * @return boolean * @since 2.2.0.1 */ function ap_is_featured_question( $question = null ) { $question = ap_get_post( $question ); return (bool) $question->featured; } /** * Get terms of a question. * * @param boolean|string $taxonomy Taxonomy slug. * @param mixed $_post Post object, ID or null. * @return string */ function ap_get_terms( $taxonomy = false, $_post = null ) { $_post = ap_get_post( $_post ); if ( ! empty( $_post->terms ) ) { return $_post->terms; } return false; } /** * Check if post have terms of a taxonomy. * * @param boolean|integer $post_id Post ID. * @param string $taxonomy Taxonomy name. * @return boolean */ function ap_post_have_terms( $post_id = false, $taxonomy = 'question_category' ) { if ( ! $post_id ) { $post_id = get_the_ID(); } $terms = get_the_terms( $post_id, $taxonomy ); if ( ! empty( $terms ) ) { return true; } return false; } /** * Check if question or answer have attachemnts. * * @param mixed $_post Post. * @return boolean */ function ap_have_attach( $_post = null ) { $_post = ap_get_post( $_post ); if ( ! empty( $_post->attach ) ) { return true; } return false; } /** * Get attachment ids of a question or answer. * * @param mixed $_post Post. * @return string|boolean */ function ap_get_attach( $_post = null ) { $_post = ap_get_post( $_post ); if ( ! empty( $_post->attach ) ) { return explode( ',', $_post->attach ); } return false; } /** * Get latest activity of question or answer. * * @param mixed $post_id Question or answer ID. * @param integer|boolean $answer_activities Show answers activities as well. * @return string */ function ap_latest_post_activity_html( $post_id = false, $answer_activities = false ) { if ( false === $post_id ) { $post_id = get_the_ID(); } $_post = ap_get_post( $post_id ); $activity = $_post->activities; if ( false !== $answer_activities && ! empty( $_post->activities['child'] ) ) { $activity = $_post->activities['child']; } if ( ! empty( $activity ) && ! empty( $activity['date'] ) ) { $activity['date'] = get_gmt_from_date( $activity['date'] ); } if ( false === $answer_activities && ( ! isset( $activity['type'] ) || in_array( $activity['type'], [ 'new_answer', 'new_question' ], true ) ) ) { return; } $html = ''; if ( $activity ) { $user_id = ! empty( $activity['user_id'] ) ? $activity['user_id'] : 0; $activity_type = ! empty( $activity['type'] ) ? $activity['type'] : ''; $html .= ''; $html .= ''; $html .= ' ' . ap_activity_short_title( $activity_type ); if ( ! empty( $activity['date'] ) ) { $html .= ' '; $html .= ''; $html .= ''; } $html .= ''; } if ( $html ) { return apply_filters( 'ap_latest_post_activity_html', $html ); } return false; } /** * Output answers of current question. * * @since 2.1 * @since 4.1.0 Removed calling function @see `ap_reset_question_query`. */ function ap_answers() { global $answers; $answers = ap_get_answers(); ap_get_template_part( 'answers' ); ap_reset_question_query(); }