* @license GPL-3.0+ * @link https://anspress.io * @copyright 2014 Rahul Aryan * @since 4.0.0 */ /** * AnsPress upload hooks. */ class AnsPress_Uploader { /** * Upload an attachment to server. */ public static function image_submission() { $post_id = ap_sanitize_unslash( 'post_id', 'r' ); if ( ! check_ajax_referer( 'media-upload', false, false ) || ! ap_user_can_upload( ) || empty( $_FILES['async-upload'] ) ) { ap_ajax_json( [ 'success' => false, 'snackbar' => [ 'message' => __( 'You are not allowed to upload attachments.', 'anspress-question-answer' ), ], ] ); } if ( ! empty( $post_id ) && ! ap_user_can_edit_post( $post_id ) ) { ap_ajax_json( [ 'success' => false ] ); } else { $post_id = null; } $attachment_id = ap_upload_user_file( $_FILES['async-upload'], true, $post_id ); if ( is_wp_error( $attachment_id ) ) { ap_ajax_json( [ 'success' => false, 'snackbar' => [ 'message' => $attachment_id->get_error_message(), ], ] ); } ap_ajax_json( array( 'success' => true, 'attachment_url' => wp_get_attachment_url( $attachment_id ), 'attachment_id' => $attachment_id, 'is_image' => wp_attachment_is_image( $attachment_id ), 'delete_nonce' => wp_create_nonce( 'delete-attachment-' . $attachment_id ), ) ); } /** * Delete question or answer attachment. */ public static function delete_attachment() { $attachment_id = ap_sanitize_unslash( 'attachment_id', 'r' ); if ( ! ap_verify_nonce( 'delete-attachment-' . $attachment_id ) ) { ap_ajax_json( 'no_permission' ); } // If user cannot delete then die. if ( ! ap_user_can_delete_attachment( $attachment_id ) ) { ap_ajax_json( 'no_permission' ); } $attach = get_post( $attachment_id ); $row = wp_delete_attachment( $attachment_id, true ); if ( false !== $row ) { ap_update_post_attach_ids( $attach->post_parent ); ap_ajax_json( [ 'success' => true ] ); } ap_ajax_json( [ 'success' => false, 'snackbar' => [ 'message' => __( 'Unable to delete attachment', 'anspress-question-answer' ) ], ] ); } /** * Update users temproary attachment count before a attachment deleted. * * @param integer $post_id Post ID. */ public static function before_delete_attachment( $post_id ) { $_post = get_post( $post_id ); if ( 'attachment' === $_post->post_type ) { ap_update_user_temp_media_count(); } } /** * Schedule event twice daily. */ public static function create_single_schedule() { // Check if event scheduled before. if ( ! wp_next_scheduled( 'ap_delete_temp_attachments' ) ) { // Shedule event to run every day. wp_schedule_event( time(), 'twicedaily', 'ap_delete_temp_attachments' ); } } /** * Delete temproary media which are older then today. */ public static function cron_delete_temp_attachments() { global $wpdb; $posts = $wpdb->get_results( "SELECT ID, post_author FROM $wpdb->posts WHERE post_type = 'attachment' AND post_title='_ap_temp_media' AND post_date >= CURDATE()" ); // db call okay, db cache okay. $authors = []; foreach ( (array) $posts as $_post ) { wp_delete_attachment( $_post->ID, true ); ap_update_post_attach_ids( $_post->post_parent ); $authors[] = $_post->post_author; } // Update temproary attachment counts of a user. foreach ( (array) array_unique( $authors ) as $author ) { ap_update_user_temp_media_count( $author ); } } } /** * Upload and create an attachment. Set post_status as _ap_temp_media, * later it will be removed using cron if no post parent is set. * * This function will prevent users to upload if they have more then defined * numbers of un-attached medias. * * @param array $file $_FILE variable. * @param boolean $temp Is temproary image? If so it will be deleted if no post parent. * @param boolean $parent_post Attachment parent post ID. * @return integer|boolean|object * @since 3.0.0 Added new argument `$post_parent`. */ function ap_upload_user_file( $file = array(), $temp = true, $parent_post = '' ) { // Checks if user already have un-attached media. if ( ! ap_user_can_upload_temp_media() ) { return new WP_Error( 'max_temp_attachments', __( 'You have already uploaded maximum numbers of allowed attachments', 'anspress-question-answer' ) ); } require_once ABSPATH . 'wp-admin/includes/admin.php'; // Check if file is greater then allowed size. if ( $file['size'] > ap_opt( 'max_upload_size' ) ) { return new WP_Error( 'file_size_error', sprintf( __( 'File cannot be uploaded, size is bigger then %s MB', 'anspress-question-answer' ), round( ap_opt( 'max_upload_size' ) / ( 1024 * 1024 ), 2 ) ) ); } $file_return = wp_handle_upload( $file, array( 'test_form' => false, 'mimes' => ap_allowed_mimes(), )); if ( isset( $file_return['error'] ) || isset( $file_return['upload_error_handler'] ) ) { return new WP_Error( 'upload_error', $file_return['error'], $file_return ); } $attachment = array( 'post_parent' => $parent_post, 'post_mime_type' => $file_return['type'], 'post_content' => '', 'guid' => $file_return['url'], ); // Add special post status if is temproary attachment. if ( false !== $temp ) { $attachment['post_title'] = '_ap_temp_media'; } require_once ABSPATH . 'wp-admin/includes/image.php'; $attachment_id = wp_insert_attachment( $attachment, $file_return['file'] ); if ( ! empty( $attachment_id ) ) { ap_update_user_temp_media_count(); } return $attachment_id; } /** * Initialize AnsPress uploader settings. **/ function ap_upload_js_init() { if ( ap_user_can_upload( ) ) { $mimes = []; foreach ( ap_allowed_mimes() as $ext => $mime ) { $mimes[] = [ 'title' => $mime, 'extensions' => str_replace( '|', ',', $ext ) ]; } $plupload_init = array( 'runtimes' => 'html5,flash,silverlight,html4', 'browse_button' => 'plupload-browse-button', 'container' => 'plupload-upload-ui', 'drop_element' => 'ap-drop-area', 'file_data_name' => 'async-upload', 'url' => admin_url( 'admin-ajax.php' ), 'flash_swf_url' => includes_url( 'js/plupload/plupload.flash.swf' ), 'silverlight_xap_url' => includes_url( 'js/plupload/plupload.silverlight.xap' ), 'filters' => array( 'mime_types' => $mimes, 'max_file_size' => (int) ap_opt( 'max_upload_size' ) . 'b', 'prevent_duplicates' => true, ), //'maxfiles' => ap_opt( 'uploads_per_post' ), 'multipart_params' => [ '_wpnonce' => wp_create_nonce( 'media-upload' ), 'action' => 'ap_image_submission', ], ); echo ''; echo ''; } } /** * Return allowed mime types. * * @return array * @since 3.0.0 */ function ap_allowed_mimes() { $mimes = array( 'jpg|jpeg' => 'image/jpeg', 'gif' => 'image/gif', 'png' => 'image/png', 'doc|docx' => 'application/msword', 'xls' => 'application/vnd.ms-excel', ); /** * Filter allowed mimes types. * * @param array $mimes Default mimes types. * @since 3.0.0 */ return apply_filters( 'ap_allowed_mimes', $mimes ); } /** * Upload form. * * @param boolean|integer $post_id Post ID. * @return string */ function ap_post_upload_form( $post_id = false ) { if ( ! ap_user_can_upload( ) ) { return; } if ( false === $post_id ) { $media = get_posts( [ 'post_type' => 'attachment', 'title' => '_ap_temp_media', 'post_author' => get_current_user_id(), ]); } else { $media = get_attached_media( '', $post_id ); } $label = sprintf( __( 'Insert images and attach media by %1$sselecting them%2$s', 'anspress-question-answer' ), '', '' ); $html = '