BP_Document

BuddyBoss文档组件的数据库交互类。

描述

实例方法用于创建/编辑文档,静态方法用于查询文档。

文件:bp-document /类/ class-bp-document.php

BP_Document {/ **属性************************************************************** / / ** *文件项目的ID。* * @since buddyboss 1.4.0 * @var int * / var $ id;/ ** *文档项目的博客ID。* * @since buddyboss 1.4.0 * @var int * / var $ blog_id;/ ** *文档项的附件ID。* * @since buddyboss 1.4.0 * @var int * / var $附件_id;/ ** *文档项的用户标识。* * @since buddyboss 1.4.0 * @var int * / var $ user_id;/ ** *文件项目的标题。* * @since buddyboss 1.4.0 * @var字符串* / var $标题; /** * Folder ID of the document item. * * @since BuddyBoss 1.4.0 * @var int */ var $folder_id; /** * Group ID of the document item. * * @since BuddyBoss 1.4.0 * @var int */ var $group_id; /** * Activity ID of the document item. * * @since BuddyBoss 1.4.0 * @var int */ var $activity_id; /** * Privacy of the document item. * * @since BuddyBoss 1.4.0 * @var string */ var $privacy; /** * Menu order of the document item. * * @since BuddyBoss 1.4.0 * @var int */ var $menu_order; /** * Upload date of the document item. * * @since BuddyBoss 1.4.0 * @var string */ var $date_created; /** * Update date of the document item. * * @since BuddyBoss 1.4.0 * @var string */ var $date_modified; /** * Error holder. * * @since BuddyBoss 1.4.0 * @var WP_Error */ public $errors; /** * Error type to return. Either 'bool' or 'wp_error'. * * @since BuddyBoss 1.4.0 * @var string */ public $error_type = 'bool'; static $per_pdf_secs = 20; // Seconds to allow for regenerating the preview of each PDF in the "Regen. PDF Previews" administraion tool. static $min_time_limit = 300; // Minimum seconds to set max execution time to on doing regeneration. static $poll_interval = 1; // How often to poll for progress info in seconds. static $timing_dec_places = 1; // Number of decimal places to show on time (in seconds) taken. /** * Constructor method. * * @param int|bool $id Optional. The ID of a specific activity item. * * @since BuddyBoss 1.4.0 */ function __construct( $id = false ) { // Instantiate errors object. $this->errors = new WP_Error(); if ( ! empty( $id ) ) { $this->id = (int) $id; $this->populate(); } } /** * Called on 'wp_image_editors' action. * Adds Ghostscript `BP_GOPP_Image_Editor_GS` class to head of image editors list. */ static function bp_document_wp_image_editors( $image_editors ) { if ( ! in_array( 'BP_GOPP_Image_Editor_GS', $image_editors, true ) ) { self::bp_document_load_gopp_image_editor_gs(); array_unshift( $image_editors, 'BP_GOPP_Image_Editor_GS' ); } return $image_editors; } /** * Helper to load BP_GOPP_Image_Editor_GS class. */ static function bp_document_load_gopp_image_editor_gs() { if ( ! class_exists( 'BP_GOPP_Image_Editor_GS' ) ) { if ( ! class_exists( 'WP_Image_Editor' ) ) { require ABSPATH . WPINC . '/class-wp-image-editor.php'; } require trailingslashit( dirname( __FILE__ ) ) . '/class-bp-gopp-image-editor-gs.php'; } } /** * Populate the object with data about the specific document item. * * @since BuddyBoss 1.4.0 */ public function populate() { global $wpdb; $row = wp_cache_get( $this->id, 'bp_document' ); if ( false === $row ) { $bp = buddypress(); $row = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$bp->document->table_name} WHERE id = %d", $this->id ) ); // db call ok; no-cache ok; wp_cache_set( $this->id, $row, 'bp_document' ); } if ( empty( $row ) ) { $this->id = 0; return; } $this->id = (int) $row->id; $this->blog_id = (int) $row->blog_id; $this->attachment_id = (int) $row->attachment_id; $this->user_id = (int) $row->user_id; $this->title = $row->title; $this->folder_id = (int) $row->folder_id; $this->group_id = (int) $row->group_id; $this->activity_id = (int) $row->activity_id; $this->privacy = $row->privacy; $this->menu_order = (int) $row->menu_order; $this->date_created = $row->date_created; $this->date_modified = $row->date_modified; } /** * Remove all temp directory. * * @param $dir * * @since BuddyBoss 1.4.0 */ public static function bp_document_remove_temp_directory( $dir ) { if ( is_dir( $dir ) ) { $objects = scandir( $dir ); foreach ( $objects as $object ) { if ( $object != '.' && $object != '..' ) { if ( filetype( $dir . '/' . $object ) == 'dir' ) { self::bp_document_remove_temp_directory( $dir . '/' . $object ); } else { unlink( $dir . '/' . $object ); } } } reset( $objects ); rmdir( $dir ); } } /** * Get document items, as specified by parameters. * * @param array $args { * An array of arguments. All items are optional. * * @type int $page Which page of results to fetch. Using page=1 without per_page will result * in no pagination. Default: 1. * @type int|bool $per_page Number of results per page. Default: 20. * @type int|bool $max Maximum number of results to return. Default: false (unlimited). * @type string $fields Document fields to return. Pass 'ids' to get only the document IDs. * 'all' returns full document objects. * @type string $sort ASC or DESC. Default: 'DESC'. * @type string $order_by Column to order results by. * @type array $exclude Array of document IDs to exclude. Default: false. * @type string $search_terms Limit results by a search term. Default: false. * @type string|bool $count_total If true, an additional DB query is run to count the total document items * for the query. Default: false. * } * @return array The array returned has two keys: * - 'total' is the count of located documents * - 'documents' is an array of the located documents * @since BuddyBoss 1.4.0 */ public static function get( $args = array() ) { global $wpdb; $bp = buddypress(); $r = wp_parse_args( $args, array( 'scope' => '', // Scope - Groups, friends etc. 'page' => 1, // The current page. 'per_page' => 20, // Document items per page. 'max' => false, // Max number of items to return. 'fields' => 'all', // Fields to include. 'sort' => 'DESC', // ASC or DESC. 'order_by' => 'date_created', // Column to order by. 'exclude' => false, // Array of ids to exclude. 'in' => false, // Array of ids to limit query by (IN). 'search_terms' => false, // Terms to search by. 'privacy' => false, // public, loggedin, onlyme, friends, grouponly, message. 'count_total' => false, // Whether or not to use count_total. 'folder_id' => false, 'folder' => true, 'user_directory' => true, 'meta_query' => false, // Filter by document meta. ) ); // Select conditions. $select_sql = 'SELECT DISTINCT d.id'; $from_sql = " FROM {$bp->document->table_name} d"; $join_sql = ''; // Where conditions. $where_conditions = array(); if ( ! empty( $r['scope'] ) ) { $scope_query = self::get_scope_query_sql( $r['scope'], $r ); // Override some arguments if needed. if ( ! empty( $scope_query['override'] ) ) { $r = array_replace_recursive( $r, $scope_query['override'] ); } } // Searching. if ( $r['search_terms'] ) { $search_terms_like = '%' . bp_esc_like( $r['search_terms'] ) . '%'; $where_conditions['search_sql'] = $wpdb->prepare( 'd.title LIKE %s', $search_terms_like ); /** * Filters whether or not to include users for search parameters. * * @param bool $value Whether or not to include user search. Default false. * * @since BuddyBoss 1.4.0 */ if ( apply_filters( 'bp_document_get_include_user_search', false ) ) { $user_search = get_user_by( 'slug', $r['search_terms'] ); if ( false !== $user_search ) { $user_id = $user_search->ID; $where_conditions['search_sql'] .= $wpdb->prepare( ' OR d.user_id = %d', $user_id ); } } } // Sorting. $sort = $r['sort']; if ( $sort !== 'ASC' && $sort !== 'DESC' ) { $sort = 'DESC'; } switch ( $r['order_by'] ) { case 'id': case 'user_id': case 'blog_id': case 'attachment_id': case 'title': case 'folder': case 'folder_id': case 'activity_id': case 'group_id': case 'menu_order': break; default: $r['order_by'] = 'date_created'; break; } $order_by = 'd.' . $r['order_by']; // Exclude specified items. if ( ! empty( $r['exclude'] ) ) { $exclude = implode( ',', wp_parse_id_list( $r['exclude'] ) ); $where_conditions['exclude'] = "d.id NOT IN ({$exclude})"; } // The specific ids to which you want to limit the query. if ( ! empty( $r['in'] ) ) { $in = implode( ',', wp_parse_id_list( $r['in'] ) ); $where_conditions['in'] = "d.id IN ({$in})"; // we want to disable limit query when include document ids. $r['page'] = false; $r['per_page'] = false; } if ( ! empty( $r['activity_id'] ) ) { $where_conditions['activity'] = "d.activity_id = {$r['activity_id']}"; } // existing-document check to query document which has no folders assigned. if ( ! empty( $r['folder_id'] ) && 'existing-document' !== $r['folder_id'] ) { $where_conditions['folder'] = "d.folder_id = {$r['folder_id']}"; } elseif ( ! empty( $r['folder_id'] ) && 'existing-document' === $r['folder_id'] ) { $where_conditions['folder'] = 'd.folder_id = 0'; } if ( ! empty( $r['user_id'] ) ) { $where_conditions['user'] = "d.user_id = {$r['user_id']}"; } if ( ! empty( $r['group_id'] ) ) { $where_conditions['user'] = "d.group_id = {$r['group_id']}"; } if ( ! empty( $r['privacy'] ) ) { $privacy = "'" . implode( "', '", $r['privacy'] ) . "'"; $where_conditions['privacy'] = "d.privacy IN ({$privacy})"; } // Process meta_query into SQL. $meta_query_sql = self::get_meta_query_sql( $r['meta_query'] ); if ( ! empty( $meta_query_sql['join'] ) ) { $join_sql .= $meta_query_sql['join']; } if ( ! empty( $meta_query_sql['where'] ) ) { $where_conditions[] = $meta_query_sql['where']; } /** * Filters the MySQL WHERE conditions for the Document items get method. * * @param array $where_conditions Current conditions for MySQL WHERE statement. * @param array $r Parsed arguments passed into method. * @param string $select_sql Current SELECT MySQL statement at point of execution. * @param string $from_sql Current FROM MySQL statement at point of execution. * @param string $join_sql Current INNER JOIN MySQL statement at point of execution. * * @since BuddyBoss 1.4.0 */ $where_conditions = apply_filters( 'bp_document_get_where_conditions', $where_conditions, $r, $select_sql, $from_sql, $join_sql ); if ( empty( $where_conditions ) ) { $where_conditions['2'] = '2'; } // Join the where conditions together. if ( ! empty( $scope_query['sql'] ) ) { $where_sql = 'WHERE ( ' . join( ' AND ', $where_conditions ) . ' ) OR ( ' . $scope_query['sql'] . ' )'; } else { $where_sql = 'WHERE ' . join( ' AND ', $where_conditions ); } /** * Filter the MySQL JOIN clause for the main document query. * * @param string $join_sql JOIN clause. * @param array $r Method parameters. * @param string $select_sql Current SELECT MySQL statement. * @param string $from_sql Current FROM MySQL statement. * @param string $where_sql Current WHERE MySQL statement. * * @since BuddyBoss 1.4.0 */ $join_sql = apply_filters( 'bp_document_get_join_sql', $join_sql, $r, $select_sql, $from_sql, $where_sql ); // Sanitize page and per_page parameters. $page = absint( $r['page'] ); $per_page = absint( $r['per_page'] ); $retval = array( 'documents' => null, 'total' => null, 'has_more_items' => null, ); // Query first for document IDs. $document_ids_sql = "{$select_sql} {$from_sql} {$join_sql} {$where_sql} ORDER BY {$order_by} {$sort}, d.id {$sort}"; if ( ! empty( $per_page ) && ! empty( $page ) ) { // We query for $per_page + 1 items in order to // populate the has_more_items flag. $document_ids_sql .= $wpdb->prepare( ' LIMIT %d, %d', absint( ( $page - 1 ) * $per_page ), $per_page + 1 ); } /** * Filters the paged document MySQL statement. * * @param string $document_ids_sql MySQL statement used to query for Document IDs. * @param array $r Array of arguments passed into method. * * @since BuddyBoss 1.4.0 */ $document_ids_sql = apply_filters( 'bp_document_paged_activities_sql', $document_ids_sql, $r ); $cache_group = 'bp_document'; $cached = bp_core_get_incremented_cache( $document_ids_sql, $cache_group ); if ( false === $cached ) { $document_ids = $wpdb->get_col( $document_ids_sql ); bp_core_set_incremented_cache( $document_ids_sql, $cache_group, $document_ids ); } else { $document_ids = $cached; } $retval['has_more_items'] = ! empty( $per_page ) && count( $document_ids ) > $per_page; // If we've fetched more than the $per_page value, we // can discard the extra now. if ( ! empty( $per_page ) && count( $document_ids ) === $per_page + 1 ) { array_pop( $document_ids ); } if ( 'ids' === $r['fields'] ) { $documents = array_map( 'intval', $document_ids ); } else { $documents = self::get_document_data( $document_ids ); } if ( 'ids' !== $r['fields'] ) { // Get the fullnames of users so we don't have to query in the loop. // $documents = self::append_user_fullnames( $documents ); // Pre-fetch data associated with document users and other objects. $documents = self::prefetch_object_data( $documents ); } $retval['documents'] = $documents; // If $max is set, only return up to the max results. if ( ! empty( $r['count_total'] ) ) { /** * Filters the total document MySQL statement. * * @param string $value MySQL statement used to query for total documents. * @param string $where_sql MySQL WHERE statement portion. * @param string $sort Sort direction for query. * * @since BuddyBoss 1.4.0 */ $total_documents_sql = apply_filters( 'bp_document_total_documents_sql', "SELECT count(DISTINCT d.id) FROM {$bp->document->table_name} d {$join_sql} {$where_sql}", $where_sql, $sort ); $cached = bp_core_get_incremented_cache( $total_documents_sql, $cache_group ); if ( false === $cached ) { $total_documents = $wpdb->get_var( $total_documents_sql ); bp_core_set_incremented_cache( $total_documents_sql, $cache_group, $total_documents ); } else { $total_documents = $cached; } if ( ! empty( $r['max'] ) ) { if ( (int) $total_documents > (int) $r['max'] ) { $total_documents = $r['max']; } } $retval['total'] = $total_documents; } return $retval; } /** Static Methods ***************************************************/ /** * Get the SQL for the 'scope' param in BP_Document::get(). * A scope is a predetermined set of document arguments. This method is used * to grab these document arguments and override any existing args if needed. * Can handle multiple scopes. * * @param mixed $scope The document scope. Accepts string or array of scopes. * @param array $r Current activity arguments. Same as those of BP_document::get(), * but merged with defaults. * * @return false|array 'sql' WHERE SQL string and 'override' document args. * @since BuddyBoss 1.4.0 */ public static function get_scope_query_sql( $scope = false, $r = array() ) { // Define arrays for future use. $query_args = array(); $override = array(); $retval = array(); // Check for array of scopes. if ( is_array( $scope ) ) { $scopes = $scope; // Explode a comma separated string of scopes. } elseif ( is_string( $scope ) ) { $scopes = explode( ',', $scope ); } // Bail if no scope passed. if ( empty( $scopes ) ) { return false; } // Helper to easily grab the 'user_id'. if ( ! empty( $r['filter']['user_id'] ) ) { $r['user_id'] = $r['filter']['user_id']; } // Parse each scope; yes! we handle multiples! foreach ( $scopes as $scope ) { $scope_args = array(); /** * Plugins can hook here to set their document arguments for custom scopes. * This is a dynamic filter based on the document scope. eg: * - 'bp_document_set_groups_scope_args' * - 'bp_document_set_friends_scope_args' * To see how this filter is used, plugin devs should check out: * - bp_groups_filter_document_scope() - used for 'groups' scope * - bp_friends_filter_document_scope() - used for 'friends' scope * * @param array { * Document query clauses. * * @type array { * Document arguments for your custom scope. * See {@link BP_Document_Query::_construct()} for more details. * } * @type array $override Optional. Override existing document arguments passed by $r. * } * } * * @param array $r Current activity arguments passed in BP_Document::get(). * * @since BuddyBoss 1.4.0 */ $scope_args = apply_filters( "bp_document_set_{$scope}_scope_args", array(), $r ); if ( ! empty( $scope_args ) ) { // Merge override properties from other scopes // this might be a problem... if ( ! empty( $scope_args['override'] ) ) { $override = array_merge( $override, $scope_args['override'] ); unset( $scope_args['override'] ); } // Save scope args. if ( ! empty( $scope_args ) ) { $query_args[] = $scope_args; } } } if ( ! empty( $query_args ) ) { // Set relation to OR. $query_args['relation'] = 'OR'; $query = new BP_Document_Query( $query_args ); $sql = $query->get_sql(); if ( ! empty( $sql ) ) { $retval['sql'] = $sql; } } if ( ! empty( $override ) ) { $retval['override'] = $override; } return $retval; } /** * Convert document IDs to document objects, as expected in template loop. * * @param array $document_ids Array of document IDs. * * @return array * @since BuddyBoss 1.4.0 */ protected static function get_document_data( $document_ids = array() ) { global $wpdb; // Bail if no document ID's passed. if ( empty( $document_ids ) ) { return array(); } // Get BuddyPress. $bp = buddypress(); $documents = array(); $uncached_ids = bp_get_non_cached_ids( $document_ids, 'bp_document' ); // Prime caches as necessary. if ( ! empty( $uncached_ids ) ) { // Format the document ID's for use in the query below. $uncached_ids_sql = implode( ',', wp_parse_id_list( $uncached_ids ) ); // Fetch data from document table, preserving order. $queried_adata = $wpdb->get_results( "SELECT * FROM {$bp->document->table_name} WHERE id IN ({$uncached_ids_sql})" ); // db call ok; no-cache ok; // Put that data into the placeholders created earlier, // and add it to the cache. foreach ( (array) $queried_adata as $adata ) { wp_cache_set( $adata->id, $adata, 'bp_document' ); } } // Now fetch data from the cache. foreach ( $document_ids as $document_id ) { // Integer casting. $document = wp_cache_get( $document_id, 'bp_document' ); if ( ! empty( $document ) ) { $document->id = (int) $document->id; $document->blog_id = (int) $document->blog_id; $document->user_id = (int) $document->user_id; $document->attachment_id = (int) $document->attachment_id; $document->folder_id = (int) $document->folder_id; $document->activity_id = (int) $document->activity_id; $document->group_id = (int) $document->group_id; $document->menu_order = (int) $document->menu_order; $document->parent = (int) $document->folder_id; } $group_name = ''; $visibility = ''; if ( $document->group_id > 0 ) { if ( bp_is_active( 'groups' ) ) { $group = groups_get_group( $document->group_id ); $group_name = bp_get_group_name( $group ); $status = bp_get_group_status( $group ); if ( 'hidden' === $status || 'private' === $status ) { $visibility = esc_html__( 'Group Members', 'buddyboss' ); } else { $visibility = ucfirst( $status ); } } else { $visibility = ''; } } else { $document_privacy = bp_document_get_visibility_levels(); if ( 'friends' === $document->privacy && bp_loggedin_user_id() !== (int) $document->user_id ) { $visibility = esc_html__( 'Connections', 'buddyboss' ); } elseif ( 'message' === $document->privacy ) { $visibility = esc_html__( 'Message', 'buddyboss' ); } elseif ( 'forums' === $document->privacy ) { $visibility = esc_html__( 'Forums', 'buddyboss' ); } else { $visibility = ( isset( $document_privacy[ $document->privacy ] ) ) ? $document_privacy[ $document->privacy ] : ''; } } // fetch attachment data. $attachment_data = new stdClass(); $attachment_data->full = ''; $attachment_data->thumb = ''; $attachment_data->activity_thumb = ''; $attachment_data->meta = wp_get_attachment_metadata( $document->attachment_id ); $document->attachment_data = $attachment_data; $document->group_name = $group_name; $document->visibility = $visibility; $documents[] = $document; } // Then fetch user data. $user_query = new BP_User_Query( array( 'user_ids' => wp_list_pluck( $documents, 'user_id' ), 'populate_extras' => false, ) ); // Associated located user data with document items. foreach ( $documents as $a_index => $a_item ) { $a_user_id = intval( $a_item->user_id ); $a_user = isset( $user_query->results[ $a_user_id ] ) ? $user_query->results[ $a_user_id ] : ''; if ( ! empty( $a_user ) ) { $documents[ $a_index ]->user_email = $a_user->user_email; $documents[ $a_index ]->user_nicename = $a_user->user_nicename; $documents[ $a_index ]->user_login = $a_user->user_login; $documents[ $a_index ]->display_name = $a_user->display_name; } } return $documents; } /** * Pre-fetch data for objects associated with document items. * Document items are associated with users, and often with other * BuddyPress data objects. Here, we pre-fetch data about these * associated objects, so that inline lookups - done primarily when * building action strings - do not result in excess database queries. * * @param array $documents Array of document. * * @return array $documents Array of document. * @since BuddyBoss 1.4.0 */ protected static function prefetch_object_data( $documents ) { /** * Filters inside prefetch_object_data method to aid in pre-fetching object data associated with document item. * * @param array $documents Array of document. * * @since BuddyBoss 1.4.0 */ return apply_filters( 'bp_document_prefetch_object_data', $documents ); } /** * @param array $args * * @return null[] */ public static function documents( $args = array() ) { global $wpdb; $bp = buddypress(); $r = wp_parse_args( $args, array( 'scope' => '', // Scope - Groups, friends etc. 'page' => 1, // The current page. 'per_page' => 20, // Document items per page. 'max' => false, // Max number of items to return. 'fields' => 'all', // Fields to include. 'sort' => 'DESC', // ASC or DESC. 'order_by' => 'date_created', // Column to order by. 'exclude' => false, // Array of ids to exclude. 'in' => false, // Array of ids to limit query by (IN). 'search_terms' => false, // Terms to search by. 'privacy' => false, // public, loggedin, onlyme, friends, grouponly, message. 'count_total' => false, // Whether or not to use count_total. 'user_directory' => true, 'folder_id' => 0, 'meta_query_document' => false, 'meta_query_folder' => false, ) ); // Select conditions. $select_sql_document = 'SELECT DISTINCT d.*'; $select_sql_folder = 'SELECT DISTINCT f.*'; $from_sql_document = " FROM {$bp->document->table_name} d, {$bp->document->table_name_meta} dm WHERE ( d.id = dm.document_id ) "; $from_sql_folder = " FROM {$bp->document->table_name_folder} f WHERE id != '0' "; $join_sql_document = ''; $join_sql_folder = ''; // Where conditions. $where_conditions_document = array(); $where_conditions_folder = array(); if ( ! empty( $r['scope'] ) ) { $scope_query_document = self::get_scope_document_query_sql( $r['scope'], $r ); $scope_query_folder = self::get_scope_folder_query_sql( $r['scope'], $r ); // Override some arguments if needed. if ( ! empty( $scope_query_document['override'] ) ) { $r = array_replace_recursive( $r, $scope_query_document['override'] ); } // Override some arguments if needed. if ( ! empty( $scope_query_folder['override'] ) ) { $r = array_replace_recursive( $r, $scope_query_folder['override'] ); } } // Searching. if ( $r['search_terms'] ) { $search_terms_like = '%' . bp_esc_like( $r['search_terms'] ) . '%'; $where_conditions_document['search_sql'] = $wpdb->prepare( '( d.title LIKE %s', $search_terms_like ); $where_conditions_folder['search_sql'] = $wpdb->prepare( 'f.title LIKE %s', $search_terms_like ); $where_conditions_document['search_sql'] .= $wpdb->prepare( ' OR dm.meta_key = "extension" AND dm.meta_value LIKE %s ', $search_terms_like ); $where_conditions_document['search_sql'] .= $wpdb->prepare( ' OR dm.meta_key = "file_name" AND dm.meta_value LIKE %s )', $search_terms_like ); /** * Filters whether or not to include users for search parameters. * * @param bool $value Whether or not to include user search. Default false. * * @since BuddyBoss 1.4.0 */ if ( apply_filters( 'bp_document_get_include_user_search', false ) ) { $user_search = get_user_by( 'slug', $r['search_terms'] ); if ( false !== $user_search ) { $user_id = $user_search->ID; $where_conditions_document['search_sql'] .= $wpdb->prepare( ' OR d.user_id = %d', $user_id ); $where_conditions_folder['search_sql'] .= $wpdb->prepare( ' OR f.user_id = %d', $user_id ); } } } // Sorting. $sort = $r['sort']; if ( 'ASC' !== $sort && 'DESC' !== $sort ) { $sort = 'ASC'; } switch ( $r['order_by'] ) { case 'id': case 'user_id': case 'blog_id': case 'attachment_id': case 'title': case 'folder_id': case 'activity_id': case 'privacy': case 'group_id': case 'menu_order': case 'visibility': case 'date_modified': case 'date_created': break; default: $r['order_by'] = 'title'; break; } $order_by_document = 'd.' . $r['order_by']; $order_by_folder = 'f.' . $r['order_by']; // Exclude specified items. if ( ! empty( $r['exclude'] ) ) { $exclude = implode( ',', wp_parse_id_list( $r['exclude'] ) ); $where_conditions_document['exclude'] = "d.id NOT IN ({$exclude})"; $where_conditions_folder['exclude'] = "f.id NOT IN ({$exclude})"; } // The specific ids to which you want to limit the query. if ( ! empty( $r['in'] ) ) { $in = implode( ',', wp_parse_id_list( $r['in'] ) ); $where_conditions_document['in'] = "d.id IN ({$in})"; $where_conditions_folder['in'] = "f.id IN ({$in})"; } if ( ! empty( $r['activity_id'] ) ) { $where_conditions_document['activity'] = "d.activity_id = {$r['activity_id']}"; } if ( ! empty( $r['user_id'] ) ) { $where_conditions_document['user'] = "d.user_id = {$r['user_id']}"; $where_conditions_folder['user'] = "f.user_id = {$r['user_id']}"; } if ( ! empty( $r['group_id'] ) ) { $where_conditions_document['user'] = "d.group_id = {$r['group_id']}"; $where_conditions_folder['user'] = "f.group_id = {$r['group_id']}"; } if ( ! empty( $r['privacy'] ) ) { $privacy = "'" . implode( "', '", $r['privacy'] ) . "'"; $where_conditions_document['privacy'] = "d.privacy IN ({$privacy})"; $where_conditions_folder['privacy'] = "f.privacy IN ({$privacy})"; } // Process meta_query into SQL. $meta_query_sql_document = self::get_meta_query_sql( $r['meta_query_document'] ); $meta_query_sql_folder = self::get_document_folder_meta_query_sql( $r['meta_query_folder'] ); if ( ! empty( $meta_query_sql_document['join'] ) ) { $join_sql_document .= $meta_query_sql_document['join']; } if ( ! empty( $meta_query_sql_folder['join'] ) ) { $join_sql_folder .= $meta_query_sql_folder['join']; } if ( ! empty( $meta_query_sql_document['where'] ) ) { $where_conditions_document[] = $meta_query_sql_document['where']; } if ( ! empty( $meta_query_sql_folder['where'] ) ) { $where_conditions_folder[] = $meta_query_sql_folder['where']; } /** * Filters the MySQL WHERE conditions for the Document items get method. * * @param array $where_conditions Current conditions for MySQL WHERE statement. * @param array $r Parsed arguments passed into method. * @param string $select_sql Current SELECT MySQL statement at point of execution. * @param string $from_sql Current FROM MySQL statement at point of execution. * @param string $join_sql Current INNER JOIN MySQL statement at point of execution. * * @since BuddyBoss 1.4.0 */ $where_conditions_document = apply_filters( 'bp_document_get_where_conditions_document', $where_conditions_document, $r, $select_sql_document, $from_sql_document, $join_sql_document ); $where_conditions_folder = apply_filters( 'bp_document_get_where_conditions_folder', $where_conditions_folder, $r, $select_sql_folder, $from_sql_folder, $join_sql_folder ); // Join the where conditions together for document. if ( ! empty( $scope_query_document['sql'] ) ) { $where_sql_document = 'AND ' . ( ! empty( $where_conditions_document ) ? '( ' . join( ' AND ', $where_conditions_document ) . ' ) AND ' : '' ) . ' ( ' . $scope_query_document['sql'] . ' )'; } else { $where_sql_document = ( ! empty( $where_conditions_document ) ? 'AND ' . join( ' AND ', $where_conditions_document ) : '' ); } // Join the where conditions together for folder. if ( ! empty( $scope_query_folder['sql'] ) ) { $where_sql_folder = 'AND ' . ( ! empty( $where_conditions_folder ) ? '( ' . join( ' AND ', $where_conditions_folder ) . ' ) AND ' : '' ) . ' ( ' . $scope_query_folder['sql'] . ' )'; } else { $where_sql_folder = ( ! empty( $where_conditions_folder ) ? 'AND ' . join( ' AND ', $where_conditions_folder ) : '' ); } /** * Filter the MySQL JOIN clause for the main document query. * * @param string $join_sql JOIN clause. * @param array $r Method parameters. * @param string $select_sql Current SELECT MySQL statement. * @param string $from_sql Current FROM MySQL statement. * @param string $where_sql Current WHERE MySQL statement. * * @since BuddyBoss 1.4.0 */ $join_sql_folder = apply_filters( 'bp_document_get_join_sql_folder', $join_sql_folder, $r, $select_sql_folder, $from_sql_folder, $where_sql_folder ); $join_sql_document = apply_filters( 'bp_document_get_join_sql_document', $join_sql_document, $r, $select_sql_document, $from_sql_document, $where_sql_document ); $retval = array( 'documents' => null, 'total' => null, 'has_more_items' => null, ); // Query first for document IDs. $document_ids_sql_folder = "{$select_sql_folder} {$from_sql_folder} {$join_sql_folder} {$where_sql_folder} ORDER BY {$order_by_folder} {$sort}"; $document_ids_sql_document = "{$select_sql_document} {$from_sql_document} {$join_sql_document} {$where_sql_document} ORDER BY {$order_by_document} {$sort}"; /** * Filters the paged document MySQL statement. * * @param string $document_ids_sql MySQL statement used to query for Document IDs. * @param array $r Array of arguments passed into method. * * @since BuddyBoss 1.4.0 */ $document_ids_sql_folder = apply_filters( 'bp_document_paged_activities_sql_folder', $document_ids_sql_folder, $r ); $document_ids_sql_document = apply_filters( 'bp_document_paged_activities_sql_document', $document_ids_sql_document, $r ); $cache_group = 'bp_document'; $cached_folder = bp_core_get_incremented_cache( $document_ids_sql_folder, $cache_group ); $cached_document = bp_core_get_incremented_cache( $document_ids_sql_document, $cache_group ); if ( false === $cached_folder ) { $document_ids_folder = $wpdb->get_col( $document_ids_sql_folder ); // db call ok; no-cache ok; bp_core_set_incremented_cache( $document_ids_sql_folder, $cache_group, $document_ids_folder ); } else { $document_ids_folder = $cached_folder; } if ( false === $cached_document ) { $document_ids_document = $wpdb->get_col( $document_ids_sql_document ); // db call ok; no-cache ok; bp_core_set_incremented_cache( $document_ids_sql_document, $cache_group, $document_ids_document ); } else { $document_ids_document = $cached_document; } if ( 'ids' === $r['fields'] ) { $documents_folder = array_map( 'intval', $document_ids_folder ); $documents_document = array_map( 'intval', $document_ids_document ); $documents = array_merge( $documents_folder, $documents_document ); } else { $documents_document = self::get_document_data( $document_ids_document ); $documents_folder = self::get_folder_data( $document_ids_folder ); $documents = array_merge( $documents_folder, $documents_document ); } if ( 'ids' !== $r['fields'] ) { // Get the fullnames of users so we don't have to query in the loop. // $documents = self::append_user_fullnames( $documents ); // Pre-fetch data associated with document users and other objects. $documents = self::prefetch_object_data( $documents ); } $direction = 'SORT_' . $sort; if ( 'privacy' === $r['order_by'] ) { $r['order_by'] = 'visibility'; } elseif ( 'group_id' === $r['order_by'] ) { $r['order_by'] = 'group_name'; } $documents = self::array_msort( $documents, array( $r['order_by'] => $direction ) ); $retval['has_more_items'] = ! empty( $r['per_page'] ) && isset( $r['per_page'] ) && count( $documents ) > $r['per_page']; if ( isset( $r['per_page'] ) && isset( $r['page'] ) && ! empty( $r['per_page'] ) && ! empty( $r['page'] ) && $retval['has_more_items'] ) { $total = count( $documents ); $current_page = $r['page']; $item_per_page = $r['per_page']; $start = ( $current_page - 1 ) * $item_per_page; $documents = array_slice( $documents, $start, $item_per_page ); $retval['has_more_items'] = $total > ( $current_page * $item_per_page ); $retval['documents'] = $documents; } else { $retval['documents'] = $documents; } $retval['total'] = count( $retval['documents'] ); return $retval; } /** * Get the SQL for the 'scope' param in BP_Document::get(). * A scope is a predetermined set of document arguments. This method is used * to grab these document arguments and override any existing args if needed. * Can handle multiple scopes. * * @param mixed $scope The document scope. Accepts string or array of scopes. * @param array $r Current activity arguments. Same as those of BP_document::get(), * but merged with defaults. * * @return false|array 'sql' WHERE SQL string and 'override' document args. * @since BuddyBoss 1.4.0 */ public static function get_scope_document_query_sql( $scope = false, $r = array() ) { // Define arrays for future use. $query_args = array(); $override = array(); $retval = array(); // Check for array of scopes. if ( is_array( $scope ) ) { $scopes = $scope; // Explode a comma separated string of scopes. } elseif ( is_string( $scope ) ) { $scopes = explode( ',', $scope ); } // Bail if no scope passed. if ( empty( $scopes ) ) { return false; } // Helper to easily grab the 'user_id'. if ( ! empty( $r['filter']['user_id'] ) ) { $r['user_id'] = $r['filter']['user_id']; } // Parse each scope; yes! we handle multiples! foreach ( $scopes as $scope ) { $scope_args = array(); /** * Plugins can hook here to set their document arguments for custom scopes. * This is a dynamic filter based on the document scope. eg: * - 'bp_document_set_groups_scope_args' * - 'bp_document_set_friends_scope_args' * To see how this filter is used, plugin devs should check out: * - bp_groups_filter_document_scope() - used for 'groups' scope * - bp_friends_filter_document_scope() - used for 'friends' scope * * @param array { * Document query clauses. * * @type array { * Document arguments for your custom scope. * See {@link BP_Document_Query::_construct()} for more details. * } * @type array $override Optional. Override existing document arguments passed by $r. * } * } * * @param array $r Current activity arguments passed in BP_Document::get(). * * @since BuddyBoss 1.4.0 */ $scope_args = apply_filters( "bp_document_set_document_{$scope}_scope_args", array(), $r ); if ( ! empty( $scope_args ) ) { // Merge override properties from other scopes // this might be a problem... if ( ! empty( $scope_args['override'] ) ) { $override = array_merge( $override, $scope_args['override'] ); unset( $scope_args['override'] ); } // Save scope args. if ( ! empty( $scope_args ) ) { $query_args[] = $scope_args; } } } if ( ! empty( $query_args ) ) { // Set relation to OR. $query_args['relation'] = 'OR'; $query = new BP_Document_Query( $query_args ); $sql = $query->get_sql_document(); if ( ! empty( $sql ) ) { $retval['sql'] = $sql; } } if ( ! empty( $override ) ) { $retval['override'] = $override; } return $retval; } /** * Get the SQL for the 'scope' param in BP_Document::get(). * A scope is a predetermined set of document arguments. This method is used * to grab these document arguments and override any existing args if needed. * Can handle multiple scopes. * * @param mixed $scope The document scope. Accepts string or array of scopes. * @param array $r Current activity arguments. Same as those of BP_document::get(), * but merged with defaults. * * @return false|array 'sql' WHERE SQL string and 'override' document args. * @since BuddyBoss 1.4.0 */ public static function get_scope_folder_query_sql( $scope = false, $r = array() ) { // Define arrays for future use. $query_args = array(); $override = array(); $retval = array(); // Check for array of scopes. if ( is_array( $scope ) ) { $scopes = $scope; // Explode a comma separated string of scopes. } elseif ( is_string( $scope ) ) { $scopes = explode( ',', $scope ); } // Bail if no scope passed. if ( empty( $scopes ) ) { return false; } // Helper to easily grab the 'user_id'. if ( ! empty( $r['filter']['user_id'] ) ) { $r['user_id'] = $r['filter']['user_id']; } // Parse each scope; yes! we handle multiples! foreach ( $scopes as $scope ) { $scope_args = array(); /** * Plugins can hook here to set their document arguments for custom scopes. * This is a dynamic filter based on the document scope. eg: * - 'bp_document_set_groups_scope_args' * - 'bp_document_set_friends_scope_args' * To see how this filter is used, plugin devs should check out: * - bp_groups_filter_document_scope() - used for 'groups' scope * - bp_friends_filter_document_scope() - used for 'friends' scope * * @param array { * Document query clauses. * * @type array { * Document arguments for your custom scope. * See {@link BP_Document_Query::_construct()} for more details. * } * @type array $override Optional. Override existing document arguments passed by $r. * } * } * * @param array $r Current activity arguments passed in BP_Document::get(). * * @since BuddyBoss 1.4.0 */ $scope_args = apply_filters( "bp_document_set_folder_{$scope}_scope_args", array(), $r ); if ( ! empty( $scope_args ) ) { // Merge override properties from other scopes // this might be a problem... if ( ! empty( $scope_args['override'] ) ) { $override = array_merge( $override, $scope_args['override'] ); unset( $scope_args['override'] ); } // Save scope args. if ( ! empty( $scope_args ) ) { $query_args[] = $scope_args; } } } if ( ! empty( $query_args ) ) { // Set relation to OR. $query_args['relation'] = 'OR'; $query = new BP_Document_Query( $query_args ); $sql = $query->get_sql_folder(); if ( ! empty( $sql ) ) { $retval['sql'] = $sql; } } if ( ! empty( $override ) ) { $retval['override'] = $override; } return $retval; } /** * Convert document IDs to document objects, as expected in template loop. * * @param array $folder_ids Array of document IDs. * * @return array * @since BuddyBoss 1.4.0 */ protected static function get_folder_data( $folder_ids = array() ) { global $wpdb; // Bail if no document ID's passed. if ( empty( $folder_ids ) ) { return array(); } // Get BuddyPress. $bp = buddypress(); $documents = array(); $uncached_ids = bp_get_non_cached_ids( $folder_ids, 'bp_document_folder' ); // Prime caches as necessary. if ( ! empty( $uncached_ids ) ) { // Format the document ID's for use in the query below. $uncached_ids_sql = implode( ',', wp_parse_id_list( $uncached_ids ) ); // Fetch data from document table, preserving order. $queried_adata = $wpdb->get_results( "SELECT * FROM {$bp->document->table_name_folder} WHERE id IN ({$uncached_ids_sql})" ); // db call ok; no-cache ok; // Put that data into the placeholders created earlier, // and add it to the cache. foreach ( (array) $queried_adata as $adata ) { wp_cache_set( $adata->id, $adata, 'bp_document_folder' ); } } // Now fetch data from the cache. foreach ( $folder_ids as $document_id ) { // Integer casting. $document = wp_cache_get( $document_id, 'bp_document_folder' ); if ( ! empty( $document ) ) { $document->id = (int) $document->id; $document->user_id = (int) $document->user_id; $document->group_id = (int) $document->group_id; $document->date_created = $document->date_created; $document->title = $document->title; $document->privacy = $document->privacy; $document->parent = $document->parent; $document->folder_id = (int) $document->id; if ( (int) $document->group_id > 0 ) { $document->folder = 'group'; if ( bp_is_active( 'groups' ) ) { $group = groups_get_group( array( 'group_id' => $document->group_id ) ); $document->link = bp_get_group_permalink( $group ) . bp_get_document_slug() . '/folder/' . (int) $document->id; } $document->link = ''; } else { $document->folder = 'profile'; $document->link = bp_core_get_user_domain( (int) $document->user_id ) . bp_get_document_slug() . '/folder/' . (int) $document->id; } } $group_name = ''; $visibility = ''; if ( $document->group_id > 0 ) { if ( bp_is_active( 'groups' ) ) { $group = groups_get_group( $document->group_id ); $group_name = bp_get_group_name( $group ); $status = bp_get_group_status( $group ); if ( 'hidden' === $status || 'private' === $status ) { $visibility = esc_html__( 'Group Members', 'buddyboss' ); } else { $visibility = ucfirst( $status ); } } else { $visibility = ''; } } else { $document_privacy = bp_document_get_visibility_levels(); if ( 'friends' === $document->privacy && bp_loggedin_user_id() !== (int) $document->user_id ) { $visibility = esc_html__( 'Connections', 'buddyboss' ); } else { $visibility = (isset( $document_privacy[ $document->privacy ] ) ) ? $document_privacy[ $document->privacy ] : $document->privacy ; } } $document->group_name = $group_name; $document->visibility = $visibility; $documents[] = $document; } // Then fetch user data. $user_query = new BP_User_Query( array( 'user_ids' => wp_list_pluck( $documents, 'user_id' ), 'populate_extras' => false, ) ); // Associated located user data with document items. foreach ( $documents as $a_index => $a_item ) { $a_user_id = intval( $a_item->user_id ); $a_user = isset( $user_query->results[ $a_user_id ] ) ? $user_query->results[ $a_user_id ] : ''; if ( ! empty( $a_user ) ) { $documents[ $a_index ]->user_email = $a_user->user_email; $documents[ $a_index ]->user_nicename = $a_user->user_nicename; $documents[ $a_index ]->user_login = $a_user->user_login; $documents[ $a_index ]->display_name = $a_user->display_name; } } return $documents; } /** * Sort data based on order. * * @param $array * @param $cols * * @return array|mixed * * @since BuddyBoss 1.4.0 */ public static function array_msort( $array, $cols ) { $array = json_decode( json_encode( $array ), true ); $colarr = array(); foreach ( $cols as $col => $order ) { $colarr[ $col ] = array(); foreach ( $array as $k => $row ) { $colarr[ $col ][ '_' . $k ] = strtolower( $row[ $col ] ); } } $eval = 'array_multisort('; foreach ( $cols as $col => $order ) { $eval .= '$colarr[\'' . $col . '\'],' . $order . ','; } $eval = substr( $eval, 0, - 1 ) . ');'; eval( $eval ); $ret = array(); foreach ( $colarr as $col => $arr ) { foreach ( $arr as $k => $v ) { $k = substr( $k, 1 ); if ( ! isset( $ret[ $k ] ) ) { $ret[ $k ] = $array[ $k ]; } $ret[ $k ][ $col ] = $array[ $k ][ $col ]; } } if ( ! empty( $ret ) ) { $i = 0; $arr = array(); foreach ( $ret as $k => $v ) { $ret[ $i ] = (object) $v; $arr[ $i ] = (object) $v; $i ++; } } return $arr; } /** * Sort by column. * * @param $array * @param $column * @param int $direction * * @since BuddyBoss 1.4.0 */ public static function array_sort_by_column( $array, $column, $direction = SORT_DESC ) { $new_array = json_decode( json_encode( $array ), true ); if ( 'date_created' === $column ) { $mapping_arr = array_map( 'strtotime', array_column( $new_array, $column ) ); array_multisort( $mapping_arr, $direction ); } else { $reference_array = array(); foreach ( $array as $key => $row ) { $reference_array[ $key ] = $row[ $column ]; } array_multisort( $reference_array, $direction, $array ); } } /** * Create SQL IN clause for filter queries. * * @param string $field The database field. * @param array|bool $items The values for the IN clause, or false when none are found. * * @return string|false * @see BP_Document::get_filter_sql() * @since BuddyBoss 1.4.0 */ public static function get_in_operator_sql( $field, $items ) { global $wpdb; // Split items at the comma. if ( ! is_array( $items ) ) { $items = explode( ',', $items ); } // Array of prepared integers or quoted strings. $items_prepared = array(); // Clean up and format each item. foreach ( $items as $item ) { // Clean up the string. $item = trim( $item ); // Pass everything through prepare for security and to safely quote strings. $items_prepared[] = ( is_numeric( $item ) ) ? $wpdb->prepare( '%d', $item ) : $wpdb->prepare( '%s', $item ); } // Build IN operator sql syntax. if ( count( $items_prepared ) ) { return sprintf( '%s IN ( %s )', trim( $field ), implode( ',', $items_prepared ) ); } else { return false; } } /** * Delete document items from the database. * To delete a specific document item, pass an 'id' parameter. * Otherwise use the filters. * * @param array $args { * @int $id Optional. The ID of a specific item to delete. * @int $blog_id Optional. The blog ID to filter by. * @int $attachment_id Optional. The attachment ID to filter by. * @int $user_id Optional. The user ID to filter by. * @string $title Optional. The title to filter by. * @int $folder_id Optional. The folder ID to filter by. * @int $activity_id Optional. The activity ID to filter by. * @int $group_id Optional. The group ID to filter by. * @string $privacy Optional. The privacy to filter by. * @string $date_created Optional. The date to filter by. * } * @param bool $from Context of deletion from. ex. attachment, activity etc. * * @return array|bool An array of deleted document IDs on success, false on failure. * @since BuddyBoss 1.4.0 */ public static function delete( $args = array(), $from = false ) { global $wpdb; $bp = buddypress(); $r = wp_parse_args( $args, array( 'id' => false, 'blog_id' => false, 'attachment_id' => false, 'user_id' => false, 'title' => false, 'folder_id' => false, 'activity_id' => false, 'group_id' => false, 'privacy' => false, 'date_created' => false, ) ); // Setup empty array from where query arguments. $where_args = array(); // ID. if ( ! empty( $r['id'] ) ) { $where_args[] = $wpdb->prepare( 'id = %d', $r['id'] ); } // blog ID. if ( ! empty( $r['blog_id'] ) ) { $where_args[] = $wpdb->prepare( 'blog_id = %d', $r['blog_id'] ); } // attachment ID. if ( ! empty( $r['attachment_id'] ) ) { $where_args[] = $wpdb->prepare( 'attachment_id = %d', $r['attachment_id'] ); } // User ID. if ( ! empty( $r['user_id'] ) ) { $where_args[] = $wpdb->prepare( 'user_id = %d', $r['user_id'] ); } // title. if ( ! empty( $r['title'] ) ) { $where_args[] = $wpdb->prepare( 'title = %s', $r['title'] ); } // folder ID. if ( ! empty( $r['folder_id'] ) ) { $where_args[] = $wpdb->prepare( 'folder_id = %d', $r['folder_id'] ); } // activity ID. if ( ! empty( $r['activity_id'] ) ) { $where_args[] = $wpdb->prepare( 'activity_id = %d', $r['activity_id'] ); } // group ID. if ( ! empty( $r['group_id'] ) ) { $where_args[] = $wpdb->prepare( 'group_id = %d', $r['group_id'] ); } // privacy. if ( ! empty( $r['privacy'] ) ) { $where_args[] = $wpdb->prepare( 'privacy = %s', $r['privacy'] ); } // Date created. if ( ! empty( $r['date_created'] ) ) { $where_args[] = $wpdb->prepare( 'date_created = %s', $r['date_created'] ); } // Bail if no where arguments. if ( empty( $where_args ) ) { return false; } // Join the where arguments for querying. $where_sql = 'WHERE ' . join( ' AND ', $where_args ); // Fetch all document being deleted so we can perform more actions. $documents = $wpdb->get_results( "SELECT * FROM {$bp->document->table_name} {$where_sql}" ); // db call ok; no-cache ok; /** * Action to allow intercepting document items to be deleted. * * @param array $documents Array of document. * @param array $r Array of parsed arguments. * * @since BuddyBoss 1.4.0 */ do_action_ref_array( 'bp_document_before_delete', array( $documents, $r ) ); // Attempt to delete document from the database. $deleted = $wpdb->query( "DELETE FROM {$bp->document->table_name} {$where_sql}" ); // db call ok; no-cache ok; // Bail if nothing was deleted. if ( empty( $deleted ) ) { return false; } /** * Action to allow intercepting document items just deleted. * * @param array $documents Array of document. * @param array $r Array of parsed arguments. * * @since BuddyBoss 1.4.0 */ do_action_ref_array( 'bp_document_after_delete', array( $documents, $r ) ); // Pluck the document IDs out of the $documents array. $document_ids = wp_parse_id_list( wp_list_pluck( $documents, 'id' ) ); $activity_ids = wp_parse_id_list( wp_list_pluck( $documents, 'activity_id' ) ); $attachment_ids = wp_parse_id_list( wp_list_pluck( $documents, 'attachment_id' ) ); // Delete preview attachment. foreach ( $document_ids as $document_delete ) { $preview_id = bp_document_get_meta( $document_delete, 'preview_attachment_id', true ); if ( $preview_id ) { wp_delete_attachment( $preview_id, true ); } } // if ( ! empty( $document_ids ) ) { // // Loop through attachment ids and attempt to delete. // foreach ( $document_ids as $document ) { // $preview_attachment_id = bp_document_get_meta( $document, 'preview_attachment_id', true ); // if ( $preview_attachment_id ) { // wp_delete_attachment( $preview_attachment_id, true ); // } // } // } // Delete meta. if ( ! empty( $document_ids ) ) { // Delete all document meta entries for document items. self::delete_document_meta_entries( wp_list_pluck( $documents, 'id' ) ); } // Handle accompanying attachments and meta deletion. if ( ! empty( $attachment_ids ) ) { // Loop through attachment ids and attempt to delete. foreach ( $attachment_ids as $attachment_id ) { if ( bp_is_active( 'activity' ) ) { $parent_activity_id = get_post_meta( $attachment_id, 'bp_document_parent_activity_id', true ); if ( ! empty( $parent_activity_id ) ) { $activity_document_ids = bp_activity_get_meta( $parent_activity_id, 'bp_document_ids', true ); if ( ! empty( $activity_document_ids ) ) { $activity_document_ids = explode( ',', $activity_document_ids ); $activity_document_ids = array_diff( $activity_document_ids, $document_ids ); if ( ! empty( $activity_document_ids ) ) { $activity_document_ids = implode( ',', $activity_document_ids ); bp_activity_update_meta( $parent_activity_id, 'bp_document_ids', $activity_document_ids ); } else { $activity_ids[] = $parent_activity_id; } } } } if ( empty( $from ) ) { wp_delete_attachment( $attachment_id, true ); } } } // delete related activity. if ( ! empty( $activity_ids ) && bp_is_active( 'activity' ) ) { foreach ( $activity_ids as $activity_id ) { $activity = new BP_Activity_Activity( (int) $activity_id ); // Check access. if ( bp_activity_user_can_delete( $activity ) ) { /** This action is documented in bp-activity/bp-activity-actions.php */ do_action( 'bp_activity_before_action_delete_activity', $activity->id, $activity->user_id ); // Deleting an activity comment. if ( 'activity_comment' === $activity->type ) { if ( bp_activity_delete_comment( $activity->item_id, $activity->id ) ) { /** This action is documented in bp-activity/bp-activity-actions.php */ do_action( 'bp_activity_action_delete_activity', $activity->id, $activity->user_id ); } // Deleting an activity. } else { if ( bp_activity_delete( array( 'id' => $activity->id, 'user_id' => $activity->user_id, ) ) ) { /** This action is documented in bp-activity/bp-activity-actions.php */ do_action( 'bp_activity_action_delete_activity', $activity->id, $activity->user_id ); } } } } } return $document_ids; } /** * Delete the meta entries associated with a set of document items. * * @since BuddyBoss 1.4.0 * * @param array $document_ids Document IDs whose meta should be deleted. * @return bool True on success. */ public static function delete_document_meta_entries( $document_ids = array() ) { $document_ids = wp_parse_id_list( $document_ids ); foreach ( $document_ids as $document_id ) { bp_document_delete_meta( $document_id ); } return true; } /** * Count total document for the given user. * * @param int $user_id * * @return array|bool|int * @since BuddyBoss 1.4.0 */ public static function total_document_count( $user_id = 0 ) { global $bp, $wpdb; $privacy = array( 'public' ); if ( is_user_logged_in() ) { $privacy[] = 'loggedin'; if ( bp_is_active( 'friends' ) ) { $is_friend = friends_check_friendship( get_current_user_id(), $user_id ); if ( $is_friend ) { $privacy[] = 'friends'; } } } $privacy = "'" . implode( "', '", $privacy ) . "'"; $total_count_document = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$bp->document->table_name} WHERE user_id = {$user_id} AND privacy IN ({$privacy}) AND folder_id = 0" ); // db call ok; no-cache ok; $total_count_folder = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$bp->document->table_name_folder} WHERE user_id = {$user_id} AND privacy IN ({$privacy}) AND parent = 0" ); // db call ok; no-cache ok; $total_count = $total_count_folder + $total_count_document; return $total_count; } /** * Count total document for the given group. * * @param int $group_id * * @return array|bool|int * @since BuddyBoss 1.4.0 */ public static function total_group_document_count( $group_id = 0 ) { global $bp, $wpdb; $total_count_document = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$bp->document->table_name} WHERE group_id = {$group_id} AND folder_id = 0" ); // db call ok; no-cache ok; $total_count_folder = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$bp->document->table_name_folder} WHERE group_id = {$group_id} AND parent = 0" ); // db call ok; no-cache ok; $total_count = $total_count_folder + $total_count_document; return $total_count; } /** * Get all document ids for the folder. * * @param bool $folder_id * * @return array|bool * @since BuddyBoss 1.4.0 */ public static function get_folder_document_ids( $folder_id = false ) { global $bp, $wpdb; if ( ! $folder_id ) { return false; } $folder_document_sql = $wpdb->prepare( "SELECT DISTINCT d.id FROM {$bp->document->table_name} d WHERE d.folder_id = %d", $folder_id ); $cached = bp_core_get_incremented_cache( $folder_document_sql, 'bp_document' ); if ( false === $cached ) { $document_ids = $wpdb->get_col( $folder_document_sql ); // db call ok; no-cache ok; bp_core_set_incremented_cache( $folder_document_sql, 'bp_document', $document_ids ); } else { $document_ids = $cached; } return (array) $document_ids; } /** * Get document id for the activity. * * @param bool $activity_id * * @return array|bool * @since BuddyBoss 1.1.6 */ public static function get_activity_document_id( $activity_id = false ) { global $bp, $wpdb; if ( ! $activity_id ) { return false; } $activity_document_id = (int) $wpdb->get_var( "SELECT DISTINCT d.id FROM {$bp->document->table_name} d WHERE d.activity_id = {$activity_id}" ); // db call ok; no-cache ok; return $activity_document_id; } /** * Append xProfile fullnames to an document array. * * @param array $documents Documents array. * * @return array * @since BuddyBoss 1.4.0 */ protected static function append_user_fullnames( $documents ) { if ( bp_is_active( 'xprofile' ) && ! empty( $documents ) ) { $document_user_ids = wp_list_pluck( $documents, 'user_id' ); if ( ! empty( $document_user_ids ) ) { $fullnames = bp_core_get_user_displaynames( $document_user_ids ); if ( ! empty( $fullnames ) ) { foreach ( (array) $documents as $i => $document ) { if ( ! empty( $fullnames[ $document->user_id ] ) ) { $documents[ $i ]->user_fullname = $fullnames[ $document->user_id ]; } } } } } return $documents; } /** * Save the document item to the database. * * @return WP_Error|bool True on success. * @since BuddyBoss 1.4.0 */ public function save() { global $wpdb; $bp = buddypress(); $this->id = apply_filters_ref_array( 'bp_document_id_before_save', array( $this->id, &$this ) ); $this->blog_id = apply_filters_ref_array( 'bp_document_blog_id_before_save', array( $this->blog_id, &$this ) ); $this->attachment_id = apply_filters_ref_array( 'bp_document_attachment_id_before_save', array( $this->attachment_id, &$this ) ); $this->user_id = apply_filters_ref_array( 'bp_document_user_id_before_save', array( $this->user_id, &$this ) ); $this->title = apply_filters_ref_array( 'bp_document_title_before_save', array( $this->title, &$this ) ); $this->folder_id = apply_filters_ref_array( 'bp_document_folder_id_before_save', array( $this->folder_id, &$this ) ); $this->activity_id = apply_filters_ref_array( 'bp_document_activity_id_before_save', array( $this->activity_id, &$this ) ); $this->group_id = apply_filters_ref_array( 'bp_document_group_id_before_save', array( $this->group_id, &$this ) ); $this->privacy = apply_filters_ref_array( 'bp_document_privacy_before_save', array( $this->privacy, &$this ) ); $this->menu_order = apply_filters_ref_array( 'bp_document_menu_order_before_save', array( $this->menu_order, &$this ) ); $this->date_created = apply_filters_ref_array( 'bp_document_date_created_before_save', array( $this->date_created, &$this ) ); $this->date_modified = apply_filters_ref_array( 'bp_document_date_modified_before_save', array( $this->date_modified, &$this ) ); /** * Fires before the current document item gets saved. * Please use this hook to filter the properties above. Each part will be passed in. * * @param BP_Document $this Current instance of the document item being saved. Passed by reference. * * @since BuddyBoss 1.4.0 */ do_action_ref_array( 'bp_document_before_save', array( &$this ) ); if ( 'wp_error' === $this->error_type && $this->errors->get_error_code() ) { return $this->errors; } if ( empty( $this->attachment_id ) // || empty( $this->activity_id ) //todo: when forums document is saving, it should have activity id assigned if settings enabled need to check this ) { if ( 'bool' === $this->error_type ) { return false; } else { if ( empty( $this->activity_id ) ) { $this->errors->add( 'bp_document_missing_activity' ); } else { $this->errors->add( 'bp_document_missing_attachment' ); } return $this->errors; } } // Generate PDF file preview image. $attachment_id = $this->attachment_id; $pdf_preview = false; $is_pdf = false; $is_preview_generated = get_post_meta( $attachment_id, 'document_preview_generated', true ); $preview_attachment_id = (int) get_post_meta( $attachment_id, 'document_preview_attachment_id', true ); if ( empty( $is_preview_generated ) ) { $extension = bp_document_extension( $attachment_id ); $preview_attachment_id = 0; $file = get_attached_file( $attachment_id ); $upload_dir = wp_upload_dir(); if ( 'pdf' === $extension ) { $is_pdf = true; $output_file = wp_get_attachment_image_url( $attachment_id, 'full' ); $output_file_src = bp_document_scaled_image_path( $attachment_id ); if ( '' !== $output_file && '' !== basename( $output_file ) && strstr( $output_file, 'bb_documents/' ) ) { add_filter( 'upload_dir', 'bp_document_upload_dir_script' ); $upload_dir = $upload_dir['basedir']; // Create temp folder. $upload_dir = $upload_dir . '/preview-image-folder-' . time(); $preview_folder = $upload_dir; // If folder not exists then create. if ( ! is_dir( $upload_dir ) ) { // Create temp folder. wp_mkdir_p( $upload_dir ); chmod( $upload_dir, 0777 ); // Create given main parent folder. $preview_folder = $upload_dir; wp_mkdir_p( $preview_folder ); $file_name = basename( $output_file ); $extension_pos = strrpos($file_name, '.'); // find position of the last dot, so where the extension starts $thumb = substr($file_name, 0, $extension_pos) . '_thumb' . substr($file_name, $extension_pos); copy( $output_file_src, $preview_folder . '/' . $thumb ); } $files = scandir( $preview_folder ); $firstFile = $preview_folder . '/' . $files[2]; bp_document_chmod_r( $preview_folder ); $image_data = file_get_contents( $firstFile ); $filename = basename( $output_file ); $upload_dir = wp_upload_dir(); if ( wp_mkdir_p( $upload_dir['path'] ) ) { $file = $upload_dir['path'] . '/' . $filename; } else { $file = $upload_dir['basedir'] . '/' . $filename; } file_put_contents( $file, $image_data ); $wp_filetype = wp_check_filetype( $filename, null ); $attachment = array( 'post_mime_type' => $wp_filetype['type'], 'post_title' => sanitize_file_name( $filename ), 'post_content' => '', 'post_status' => 'inherit', ); $preview_attachment_id = wp_insert_attachment( $attachment, $file ); if ( ! function_exists( 'wp_generate_attachment_metadata' ) ) { require_once ABSPATH . 'wp-admin' . '/includes/image.php'; require_once ABSPATH . 'wp-admin' . '/includes/file.php'; require_once ABSPATH . 'wp-admin' . '/includes/media.php'; } $attach_data = wp_generate_attachment_metadata( $preview_attachment_id, $file ); wp_update_attachment_metadata( $preview_attachment_id, $attach_data ); update_post_meta( $attachment_id, 'document_preview_generated', 'yes' ); update_post_meta( $attachment_id, 'document_preview_attachment_id', $preview_attachment_id ); $pdf_preview = true; BP_Document::bp_document_remove_temp_directory( $preview_folder ); remove_filter( 'upload_dir', 'bp_document_upload_dir_script' ); } } else if ( 'css' === $extension || 'txt' === $extension || 'js' === $extension || 'html' === $extension || 'htm' === $extension || 'csv' === $extension ) { $absolute_path = get_attached_file( $attachment_id ); if ( '' !== $absolute_path && '' !== basename( $absolute_path ) && strstr( $absolute_path, 'bb_documents/' ) ) { $upload_dir = $upload_dir['basedir']; // Create temp folder. $upload_dir = $upload_dir . '/preview-image-folder-' . time(); $preview_folder = $upload_dir; // If folder not exists then create. if ( ! is_dir( $upload_dir ) ) { // Create temp folder. wp_mkdir_p( $upload_dir ); chmod( $upload_dir, 0777 ); // Create given main parent folder. $preview_folder = $upload_dir; wp_mkdir_p( $preview_folder ); $file_name = basename( $absolute_path ); $extension_pos = strrpos($file_name, '.'); // find position of the last dot, so where the extension starts $thumb = substr($file_name, 0, $extension_pos) . '_thumb' . substr($file_name, $extension_pos); copy( $absolute_path, $preview_folder . '/' . $thumb ); } $files = scandir( $preview_folder ); $firstFile = $preview_folder . '/' . $files[2]; bp_document_chmod_r( $preview_folder ); $image_data = file_get_contents( $firstFile ); $words = 10000; $mirror_text = strlen($image_data) > $words ? substr($image_data,0,$words).'...' : $image_data; update_post_meta( $attachment_id, 'document_preview_mirror_text', $mirror_text ); BP_Document::bp_document_remove_temp_directory( $preview_folder ); } } } // If we have an existing ID, update the document item, otherwise insert it. if ( ! empty( $this->id ) ) { $q = $wpdb->prepare( "UPDATE {$bp->document->table_name} SET blog_id = %d, attachment_id = %d, user_id = %d, title = %s, folder_id = %d, activity_id = %d, group_id = %d, privacy = %s, menu_order = %d, date_modified = %s WHERE id = %d", $this->blog_id, $this->attachment_id, $this->user_id, $this->title, $this->folder_id, $this->activity_id, $this->group_id, $this->privacy, $this->menu_order, $this->date_modified, $this->id ); } else { $q = $wpdb->prepare( "INSERT INTO {$bp->document->table_name} ( blog_id, attachment_id, user_id, title, folder_id, activity_id, group_id, privacy, menu_order, date_created, date_modified ) VALUES ( %d, %d, %d, %s, %d, %d, %d, %s, %d, %s, %s )", $this->blog_id, $this->attachment_id, $this->user_id, $this->title, $this->folder_id, $this->activity_id, $this->group_id, $this->privacy, $this->menu_order, $this->date_created, $this->date_modified ); } if ( false === $wpdb->query( $q ) ) { return false; } // If this is a new document item, set the $id property. if ( empty( $this->id ) ) { $this->id = $wpdb->insert_id; } if ( $preview_attachment_id ) { bp_document_update_meta( $this->id, 'preview_attachment_id', $preview_attachment_id ); } if ( ! $pdf_preview && $is_pdf ) { add_filter( 'wp_image_editors', array( $this, 'bp_document_wp_image_editors' ) ); self::bp_document_pdf_previews( array( $this->attachment_id ), true, $this->id ); remove_filter( 'wp_image_editors', array( $this, 'bp_document_wp_image_editors' ) ); } // Update folder modified date. $folder = (int) $this->folder_id; if ( $folder > 0 ) { bp_document_update_folder_modified_date( $folder ); } /** * Fires after an document item has been saved to the database. * * @param BP_Document $this Current instance of document item being saved. Passed by reference. * * @since BuddyBoss 1.4.0 */ do_action_ref_array( 'bp_document_after_save', array( &$this ) ); return true; } /** * Helper to set the max_execution_time. */ static function bp_document_set_time_limit( $time_limit ) { $max_execution_time = ini_get( 'max_execution_time' ); if ( $max_execution_time && $time_limit > $max_execution_time ) { return @ set_time_limit( $time_limit ); } return null; } /** * Does the actual PDF preview regenerate. */ static function bp_document_pdf_previews( $ids, $check_mime_type = false, $document_id ) { $cnt = $num_updates = $num_fails = $time = 0; $preview_attachment_id = bp_document_get_meta( $document_id, 'preview_attachment_id', true ); if ( $ids && ! $preview_attachment_id ) { $time = microtime( true ); $cnt = count( $ids ); self::bp_document_set_time_limit( max( $cnt * self::$per_pdf_secs, self::$min_time_limit ) ); foreach ( $ids as $idx => $id ) { if ( $check_mime_type && 'application/pdf' !== get_post_mime_type( $id ) ) { continue; } $file = get_attached_file( $id ); if ( false === $file || '' === $file ) { $num_fails++; } else { // Get current metadata if any. $old_value = get_metadata( 'post', $id, '_wp_attachment_metadata' ); if ( $old_value && ( ! is_array( $old_value ) || 1 !== count( $old_value ) ) ) { $old_value = null; } // Remove old intermediate thumbnails if any. if ( $old_value && ! empty( $old_value[0]['sizes'] ) && is_array( $old_value[0]['sizes'] ) ) { $dirname = dirname( $file ) . '/'; foreach ( $old_value[0]['sizes'] as $sizeinfo ) { // Check whether pre WP 4.7.3 lacking PDF marker and if so don't delete so as not to break links to thumbnails in content. if ( false !== strpos( $sizeinfo['file'], '-pdf' ) ) { @ unlink( $dirname . $sizeinfo['file'] ); } } } if ( ! function_exists( 'wp_generate_attachment_metadata' ) ) { require_once ABSPATH . 'wp-admin' . '/includes/image.php'; require_once ABSPATH . 'wp-admin' . '/includes/file.php'; require_once ABSPATH . 'wp-admin' . '/includes/media.php'; } // Generate new intermediate thumbnails. $meta = wp_generate_attachment_metadata( $id, $file ); if ( ! $meta ) { $num_fails++; } else { // wp_update_attachment_metadata() returns false if nothing to update so check first. if ( ( $old_value && $old_value[0] === $meta ) || false !== wp_update_attachment_metadata( $id, $meta ) ) { $num_updates++; } else { $num_fails++; } } if ( $meta ) { $upload_dir = wp_upload_dir(); $preview_folder = ''; $output_file = wp_get_attachment_image_url( $id, 'full' ); $output_file_src = bp_document_scaled_image_path( $id ); if ( '' !== $output_file && '' !== basename( $output_file ) && strstr( $output_file, 'bb_documents/' ) ) { add_filter( 'upload_dir', 'bp_document_upload_dir_script' ); $upload_dir = $upload_dir['basedir']; // Create temp folder. $upload_dir = $upload_dir . '/preview-image-folder-' . time(); // If folder not exists then create. if ( ! is_dir( $upload_dir ) ) { // Create temp folder. wp_mkdir_p( $upload_dir ); chmod( $upload_dir, 0777 ); // Create given main parent folder. $preview_folder = $upload_dir; wp_mkdir_p( $preview_folder ); $file_name = basename( $output_file ); $extension_pos = strrpos($file_name, '.'); // find position of the last dot, so where the extension starts $thumb = substr($file_name, 0, $extension_pos) . '_thumb' . substr($file_name, $extension_pos); copy( $output_file_src, $preview_folder . '/' . $thumb ); } $files = scandir( $preview_folder ); $firstFile = $preview_folder . '/' . $files[2]; bp_document_chmod_r( $preview_folder ); $image_data = file_get_contents( $firstFile ); $filename = basename( $output_file ); $upload_dir = wp_upload_dir(); if ( wp_mkdir_p( $upload_dir['path'] ) ) { $file = $upload_dir['path'] . '/' . $filename; } else { $file = $upload_dir['basedir'] . '/' . $filename; } file_put_contents( $file, $image_data ); $wp_filetype = wp_check_filetype( $filename, null ); $attachment = array( 'post_mime_type' => $wp_filetype['type'], 'post_title' => sanitize_file_name( $filename ), 'post_content' => '', 'post_status' => 'inherit', ); $preview_attachment_id = wp_insert_attachment( $attachment, $file ); if ( ! function_exists( 'wp_generate_attachment_metadata' ) ) { require_once ABSPATH . 'wp-admin' . '/includes/image.php'; require_once ABSPATH . 'wp-admin' . '/includes/file.php'; require_once ABSPATH . 'wp-admin' . '/includes/media.php'; } $attach_data = wp_generate_attachment_metadata( $preview_attachment_id, $file ); wp_update_attachment_metadata( $preview_attachment_id, $attach_data ); update_post_meta( $id, 'document_preview_generated', 'yes' ); update_post_meta( $id, 'document_preview_attachment_id', $preview_attachment_id ); bp_document_update_meta( $document_id, 'preview_attachment_id', $preview_attachment_id ); BP_Document::bp_document_remove_temp_directory( $preview_folder ); remove_filter( 'upload_dir', 'bp_document_upload_dir_script' ); } } } } $time = round( microtime( true ) - $time, self::$timing_dec_places ); } return array( $cnt, $num_updates, $num_fails, $time ); } /** * Get the SQL for the 'meta_query' param in BP_Document::get(). * * We use WP_Meta_Query to do the heavy lifting of parsing the * meta_query array and creating the necessary SQL clauses. However, * since BP_Document::get() builds its SQL differently than * WP_Query, we have to alter the return value (stripping the leading * AND keyword from the 'where' clause). * * @since BuddyPress 1.8.0 * * @param array $meta_query An array of meta_query filters. See the * documentation for WP_Meta_Query for details. * @return array $sql_array 'join' and 'where' clauses. */ public static function get_meta_query_sql( $meta_query = array() ) { global $wpdb; $sql_array = array( 'join' => '', 'where' => '', ); if ( ! empty( $meta_query ) ) { $document_meta_query = new WP_Meta_Query( $meta_query ); // WP_Meta_Query expects the table name at // $wpdb->document_meta. $wpdb->documentmeta = buddypress()->document->table_name_meta; $meta_sql = $document_meta_query->get_sql( 'document', 'd', 'id' ); // Strip the leading AND - BP handles it in get(). $sql_array['where'] = preg_replace( '/^\sAND/', '', $meta_sql['where'] ); $sql_array['join'] = $meta_sql['join']; } return $sql_array; } /** * Get the SQL for the 'meta_query' param in BP_Document::get(). * * We use WP_Meta_Query to do the heavy lifting of parsing the * meta_query array and creating the necessary SQL clauses. However, * since BP_Document::get() builds its SQL differently than * WP_Query, we have to alter the return value (stripping the leading * AND keyword from the 'where' clause). * * @since BuddyPress 1.8.0 * * @param array $meta_query An array of meta_query filters. See the * documentation for WP_Meta_Query for details. * @return array $sql_array 'join' and 'where' clauses. */ public static function get_document_folder_meta_query_sql( $meta_query = array() ) { global $wpdb; $sql_array = array( 'join' => '', 'where' => '', ); if ( ! empty( $meta_query ) ) { $document_meta_query = new WP_Meta_Query( $meta_query ); // WP_Meta_Query expects the table name at // $wpdb->document_meta. $wpdb->documentmeta = buddypress()->document->table_name_folder_meta; $meta_sql = $document_meta_query->get_sql( 'document_folder', 'f', 'id' ); // Strip the leading AND - BP handles it in get(). $sql_array['where'] = preg_replace( '/^\sAND/', '', $meta_sql['where'] ); $sql_array['join'] = $meta_sql['join']; } return $sql_array; } /** * Get document attachment id for the activity. * * @param integer $activity_id Activity ID * * @return integer|bool * @since BuddyBoss 1.4.0 */ public static function get_activity_attachment_id( $activity_id = 0 ) { global $bp, $wpdb; if ( empty( $activity_id ) ) { return false; } return (int) $wpdb->get_var( "SELECT DISTINCT d.attachment_id FROM {$bp->document->table_name} d WHERE d.activity_id = {$activity_id}" ); } }

更新日志

更新日志
版本 描述
BuddyBoss 1.4.0 介绍了。

方法

问题吗?

我们总是很乐意帮助您解决代码或其他问题!搜索我们的开发人员文档联络支持,或与我们联系销售团队