* @license GPL-2.0+ * @link http://anspress.io * @copyright 2014 Rahul Aryan */ $user_pages = array(); class AnsPress_User { /** * Store upload error * @var string */ private $upload_error; /** * Initialize the plugin by setting localization and loading public scripts * and styles. * @param AnsPress $ap */ public function __construct( $ap ) { $ap->add_action( 'init', $this, 'init_actions' ); $ap->add_filter( 'pre_user_query', $this, 'follower_query' ); $ap->add_filter( 'pre_user_query', $this, 'following_query' ); $ap->add_filter( 'pre_user_query', $this, 'user_sort_by_reputation' ); $ap->add_action( 'wp_ajax_ap_cover_upload', $this, 'cover_upload' ); $ap->add_action( 'wp_ajax_ap_avatar_upload', $this, 'avatar_upload' ); $ap->add_filter( 'avatar_defaults' , $this, 'default_avatar' ); $ap->add_filter( 'get_avatar', $this, 'get_avatar', 10, 5 ); $ap->add_filter( 'ap_user_menu', $this, 'ap_user_menu_icons' ); } /** * Actions to do in init */ public function init_actions() { // Register AnsPress pages. ap_register_page( ap_opt( 'users_page_slug' ), __( 'Users', 'anspress-question-answer' ), array( $this, 'users_page' ) ); ap_register_page( ap_opt( 'user_page_slug' ), __( 'User', 'anspress-question-answer' ), array( $this, 'user_page' ), false ); ap_register_user_page( 'about', __( 'About', 'anspress-question-answer' ), array( $this, 'about_page' ) ); ap_register_user_page( 'activity-feed', __( 'Activity Feed', 'anspress-question-answer' ), array( $this, 'feed_page' ), true ); ap_register_user_page( 'notification', __( 'Notification', 'anspress-question-answer' ), array( $this, 'notification_page' ), true, false ); ap_register_user_page( 'profile', __( 'Profile', 'anspress-question-answer' ), array( $this, 'profile_page' ), true, false ); ap_register_user_page( 'questions', __( 'Questions', 'anspress-question-answer' ), array( $this, 'questions_page' ) ); ap_register_user_page( 'answers', __( 'Answers', 'anspress-question-answer' ), array( $this, 'answers_page' ) ); ap_register_user_page( 'followers', __( 'Followers', 'anspress-question-answer' ), array( $this, 'followers_page' ) ); ap_register_user_page( 'following', __( 'Following', 'anspress-question-answer' ), array( $this, 'following_page' ) ); add_filter( 'ap_page_title', array( $this, 'ap_page_title' ) ); } /** * Register users directory page in AnsPress */ public function users_page() { if ( ap_opt( 'enable_users_directory' ) ) { global $ap_user_query; $ap_user_query = ap_has_users(); include ap_get_theme_location( 'users/users.php' ); } else { _e( 'User directory is disabled.', 'anspress-question-answer' ); } } /** * Register user page in AnsPress */ public function user_page() { // Return if user profile is not active if ( ! ap_is_profile_active() ) { return; } global $ap_user_query; if ( ap_get_displayed_user_id() == 0 && ! is_user_logged_in() ) { ap_get_template_part( 'login-signup' ); return; } $ap_user_query = ap_has_users( array( 'ID' => ap_get_displayed_user_id() ) ); if ( $ap_user_query->has_users() ) { include ap_get_theme_location( 'user/user.php' ); } else { _e( 'No user found', 'anspress-question-answer' ); } } /** * Output user about page * @since 2.3 */ public function about_page() { ap_get_template_part( 'user/about' ); } /** * Output user feed page. * @since 2.4 */ public function feed_page() { global $ap_activities; $paged = get_query_var( 'paged', 1 ); $ap_activities = ap_get_activities( array( 'per_page' => 20, 'subscriber' => true, 'user_id' => ap_get_displayed_user_id(), 'orderby' => 'created', 'order' => 'DESC', 'paged' => $paged ) ); ap_get_template_part( 'user/activity-feed' ); } /** * Output notification page * @since 2.3 */ public function notification_page() { if ( ! ap_is_user_page_public( 'profile' ) && ! ap_is_my_profile() ) { ap_get_template_part( 'not-found' ); return; } global $ap_activities; $ap_activities = ap_get_activities( array( 'notification' => true, 'user_id' => ap_get_displayed_user_id() ) ); ap_get_template_part( 'user/notification' ); } /** * Output for activity page * @since 2.1 */ public function activity_page() { include ap_get_theme_location( 'user/activity.php' ); } /** * Output for profile page * @since 2.1 */ public function profile_page() { if ( ! ap_is_user_page_public( 'profile' ) && ! ap_is_my_profile() ) { ap_get_template_part( 'not-found' ); return; } include ap_get_theme_location( 'user/profile.php' ); } /** * Output for user questions page * @since 2.1 */ public function questions_page() { global $questions; $questions = ap_get_questions( array( 'author' => ap_get_displayed_user_id() ) ); ap_get_template_part( 'user/user-questions' ); wp_reset_postdata(); } /** * Output for user answers page * @since 2.0.1 */ public function answers_page() { global $answers; $answers = ap_get_answers( array( 'author' => ap_get_displayed_user_id() ) ); include ap_get_theme_location( 'user/user-answers.php' ); wp_reset_postdata(); } /** * Register user foloowers page. */ public function followers_page() { $followers = ap_has_users( array( 'user_id' => ap_get_displayed_user_id(), 'sortby' => 'followers', ) ); if ( $followers->has_users() ) { include ap_get_theme_location( 'user/followers.php' ); } else { esc_attr_e( 'No followers found', 'anspress-question-answer' ); } } /** * Register followers page in AnsPress */ public function following_page() { $following = ap_has_users( array( 'user_id' => ap_get_displayed_user_id(), 'sortby' => 'following' ) ); if ( $following->has_users() ) { include ap_get_theme_location( 'user/following.php' ); } else { esc_attr_e( 'You are not following anyone.', 'anspress-question-answer' ); } } /** * Filter AnsPress page title for user sub pages * @param string $title Title. * @return string */ public function ap_page_title($title) { if ( is_ap_user() ) { $active = ap_active_user_page(); $name = ap_user_get_the_display_name(); $my = ap_is_my_profile(); $user_pages = anspress()->user_pages; if ( 'activity' == $active ) { $title = $my ? __( 'My activity', 'anspress-question-answer' ) : sprintf( __( '%s\'s activity', 'anspress-question-answer' ), $name ); } elseif ('profile' == $active) $title = $my ? __( 'My profile', 'anspress-question-answer' ) : sprintf( __( '%s\'s profile', 'anspress-question-answer' ), $name ); elseif ('questions' == $active) $title = $my ? __( 'My questions', 'anspress-question-answer' ) : sprintf( __( '%s\'s questions', 'anspress-question-answer' ), $name ); elseif ('answers' == $active) $title = $my ? __( 'My answers', 'anspress-question-answer' ) : sprintf( __( '%s\'s answers', 'anspress-question-answer' ), $name ); elseif ('reputation' == $active) $title = $my ? __( 'My reputation', 'anspress-question-answer' ) : sprintf( __( '%s\'s reputation', 'anspress-question-answer' ), $name ); elseif ('about' == $active) $title = $my ? __( 'About me', 'anspress-question-answer' ) : sprintf( __( '%s', 'anspress-question-answer' ), $name ); elseif ('followers' == $active) $title = $my ? __( 'My followers', 'anspress-question-answer' ) : sprintf( __( '%s\'s followers', 'anspress-question-answer' ), $name ); elseif ('following' == $active) $title = __( 'Following', 'anspress-question-answer' ); elseif ('subscription' == $active) $title = __( 'My subscriptions', 'anspress-question-answer' ); elseif ('notification' == $active) $title = __( 'My notification', 'anspress-question-answer' ); else $title = $user_pages[$active]['title']; } return $title; } /** * For modifying WP_User_Query, if passed with a var ap_followers_query * @param array $query Mysql clauses. * @return array */ public function follower_query( $query ) { if ( isset( $query->query_vars['ap_query'] ) && $query->query_vars['ap_query'] == 'user_sort_by_followers' && isset( $query->query_vars['user_id'] ) ) { global $wpdb; $query->query_from = $query->query_from.' LEFT JOIN '.$wpdb->ap_subscribers." ON ID = subs_user_id"; $userid = $query->query_vars['user_id']; $query->query_where = $query->query_where." AND subs_activity = 'u_all' AND subs_item_id = $userid"; } return $query; } /** * Modify user query to get following users * @param array $query Mysql claueses * @return array */ public function following_query($query) { if ( isset( $query->query_vars['ap_query'] ) && $query->query_vars['ap_query'] == 'user_sort_by_following' && isset( $query->query_vars['user_id'] ) ) { global $wpdb; $query->query_from = $query->query_from.' LEFT JOIN '.$wpdb->ap_subscribers." ON ID = subs_item_id"; $userid = $query->query_vars['user_id']; $query->query_where = $query->query_where." AND subs_activity = 'u_all' AND subs_user_id = $userid"; } return $query; } /** * Filter user query so that it can be sorted by user reputation * @param array $query Mysql claueses. * @return array */ public function user_sort_by_reputation($query) { global $wpdb; if ( isset( $query->query_vars['ap_query'] ) ) { $query->query_where = $query->query_where." AND (apm1.user_id IS NULL OR ( apm1.meta_value != 1) )"; $query->query_from = $query->query_from. " LEFT JOIN {$wpdb->usermeta} AS apm1 ON ( {$wpdb->users}.ID = apm1.user_id AND apm1.meta_key = 'hide_profile' )"; if ( $query->query_vars['ap_query'] == 'user_sort_by_reputation' ) { $query->query_orderby = 'ORDER BY cast(mt1.meta_value AS DECIMAL) DESC'; } } return $query; } /** * Create unique name for files * @param string $dir Directory. * @param integer $user_id User ID. * @param string $ext Image extension. * @return string * @since 2.1.5 */ public function unique_filename_callback( $dir, $user_id, $ext ) { global $user_id; $md5 = md5( $user_id.time() ); return $md5 . $ext; } /** * Upload a photo to server. Before uploading it check for valid image type * @uses wp_handle_upload * @param string $file_name Name of file input field. * @return array|false */ public function upload_photo($file_name) { if ( $_FILES[ $file_name ]['size'] > ap_opt( 'max_upload_size' ) ) { $this->upload_error = sprintf( __( 'File cannot be uploaded, size is bigger then %d Byte', 'anspress-question-answer' ), ap_opt( 'max_upload_size' ) ); return false; } require_once ABSPATH.'wp-admin/includes/image.php'; require_once ABSPATH.'wp-admin/includes/file.php'; require_once ABSPATH.'wp-admin/includes/media.php'; if ( ! empty( $_FILES[ $file_name ][ 'name' ] ) && is_uploaded_file( $_FILES[ $file_name ]['tmp_name'] ) ) { $mimes = array( 'jpg|jpeg|jpe' => 'image/jpeg', 'gif' => 'image/gif', 'png' => 'image/png', ); $photo = wp_handle_upload( $_FILES[ $file_name ], array( 'mimes' => $mimes, 'test_form' => false, 'unique_filename_callback' => array( $this, 'unique_filename_callback' ), ) ); if ( empty( $photo[ 'file' ] ) || isset( $photo['error'] ) ) { // Handle failures. $this->upload_error = __( 'There was an error while uploading avatar, please check your image', 'anspress-question-answer' ); return false; } return $photo; } } /** * Process cover upload form */ public function cover_upload() { if ( ap_user_can_upload_cover() && ap_verify_nonce( 'upload_cover_'.get_current_user_id() ) ) { $photo = $this->upload_photo( 'image' ); if ( $photo === false ) { ap_send_json( ap_ajax_responce( array( 'message' => $this->upload_error, 'message_type' => 'error' ) ) ); } $file = str_replace( '\\', '\\\\', $photo['file'] ); $photo['file'] = $file; $photo['small_url'] = str_replace( basename( $photo['url'] ), 'small_'.basename( $photo['url'] ), $photo['url'] ); $small_name = str_replace( basename( $photo['file'] ), 'small_'.basename( $photo['file'] ), $photo['file'] ); $photo['small_file'] = $small_name; $userid = get_current_user_id(); // Remove previous cover image. $previous_cover = get_user_meta( $userid, '_ap_cover', true ); if ( $previous_cover['file'] && file_exists( $previous_cover['file'] ) ) { unlink( $previous_cover['file'] ); } // Delete previous image. if ( $previous_cover['small_file'] && file_exists( $previous_cover['small_file'] ) ) { unlink( $previous_cover['small_file'] ); } // Resize thumbnail. $image = wp_get_image_editor( $file ); if ( ! is_wp_error( $image ) ) { $image->resize( 960, 250, true ); $image->save( $file ); $image->resize( 350, 95, true ); $image->save( $small_name ); } // Update new photo link. update_user_meta( $userid, '_ap_cover', $photo ); do_action( 'ap_after_cover_upload', $userid, $photo ); ap_ajax_json( array( 'action' => 'cover_uploaded', 'status' => true, 'message' => __( 'Cover photo uploaded successfully.', 'anspress-question-answer' ), 'user_id' => $userid, 'image' => ap_get_cover_src( $userid ), ) ); } ap_ajax_json( array( 'message' => __( 'There was an error while uploading cover photo, please check your image and try again.', 'anspress-question-answer' ), 'message_type' => 'error', ) ); } /** * Process ajax user avatar upload request. * Sanitize file and pass to upload_file(). Rename image to md5 and store file * name in user meta. Also remove existing avtar if exists * @return void */ public function avatar_upload() { if ( ap_user_can_upload_avatar() && ap_verify_nonce( 'upload_avatar_'.get_current_user_id() ) ) { $photo = $this->upload_photo( 'thumbnail' ); if ( false === $photo ) { ap_send_json( ap_ajax_responce( array( 'message' => $this->upload_error, 'message_type' => 'error' ) ) ); } $file = str_replace( '\\', '\\\\', $photo['file'] ); $photo['file'] = $file; $photo['small_url'] = str_replace( basename( $photo['url'] ), 'small_'.basename( $photo['url'] ), $photo['url'] ); $small_name = str_replace( basename( $photo['file'] ), 'small_'.basename( $photo['file'] ), $photo['file'] ); $photo['small_file'] = $small_name; $userid = get_current_user_id(); // Remove previous image. $previous_avatar = get_user_meta( $userid, '_ap_avatar', true ); if ( $previous_avatar['file'] && file_exists( $previous_avatar['file'] ) ) { unlink( $previous_avatar['file'] ); } if ( $previous_avatar['small_file'] && file_exists( $previous_avatar['small_file'] ) ) { unlink( $previous_avatar['small_file'] ); } // Resize thumbnail. $image = wp_get_image_editor( $file ); if ( ! is_wp_error( $image ) ) { $image->resize( 200, 200, true ); $image->save( $file ); $image->resize( 50, 50, true ); $image->save( $small_name ); } update_user_meta( $userid, '_ap_avatar', $photo ); do_action( 'ap_after_avatar_upload', $userid, $photo ); ap_ajax_json( array( 'status' => true, 'message' => __( 'Avatar uploaded successfully.', 'anspress-question-answer' ), 'do' => array('replaceWith'), 'html' => get_avatar( $userid, 150 ), 'container' => '[data-view="user_avatar_'.$userid.'"]', ) ); } ap_ajax_json( array( 'message' => __( 'There was an error while uploading avatar, please check your image', 'anspress-question-answer' ), 'message_type' => 'error', ) ); } /** * Add AnsPress avtar in Wp discussion setting * @param array $avatar_defaults Avatar types. * @return array */ public function default_avatar($avatar_defaults) { $new_avatar = 'ANSPRESS_AVATAR_SRC'; $avatar_defaults[$new_avatar] = 'AnsPress'; return $avatar_defaults; } /** * Override get_avatar * @param string $avatar Avatar image. * @param integar|string $id_or_email User id or email. * @param string $size Avatar size. * @param string $default Default avatar. * @param string $alt Avatar image alternate text. * @return string */ public function get_avatar($avatar, $id_or_email, $size, $default, $alt) { if ( ! empty( $id_or_email ) ) { if ( is_object( $id_or_email ) ) { $allowed_comment_types = apply_filters('get_avatar_comment_types', array( 'comment' )); if ( ! empty( $id_or_email->comment_type ) && ! in_array( $id_or_email->comment_type, (array) $allowed_comment_types ) ) { return $avatar; } if ( ! empty( $id_or_email->user_id ) ) { $id = (int) $id_or_email->user_id; $user = get_userdata( $id ); if ( $user ) { $id_or_email = $user->ID; } } else { $id_or_email = 0; } } elseif ( is_email( $id_or_email ) ) { $u = get_user_by( 'email', $id_or_email ); $id_or_email = $u->ID; } $ap_avatar = ap_get_avatar_src( $id_or_email, ($size > 50 ? false: true) ); if ( $ap_avatar !== false ) { return "{$alt}"; } } if ( strpos( $avatar, 'ANSPRESS_AVATAR_SRC' ) !== false ) { $display_name = ap_user_display_name( array( 'user_id' => $id_or_email ) ); return '' . $alt . ''; } return $avatar; } /** * Set icon class for user menus * @param array $menus AnsPress user menu. * @return array * @since 2.0.1 */ public function ap_user_menu_icons($menus) { $icons = array( 'about' => ap_icon( 'home' ), 'profile' => ap_icon( 'board' ), 'questions' => ap_icon( 'question' ), 'answers' => ap_icon( 'answer' ), 'activity' => ap_icon( 'pulse' ), 'reputation' => ap_icon( 'reputation' ), 'followers' => ap_icon( 'users' ), 'following' => ap_icon( 'users' ), 'subscription' => ap_icon( 'mail' ), 'notification' => ap_icon( 'globe' ), 'activity-feed' => ap_icon( 'rss' ), ); foreach ( $icons as $k => $i ) { if ( isset( $menus[ $k ] ) ) { $menus[ $k ]['class'] = $i; } } return $menus; } }