public function brightcove_media_query() { if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], '_bc_ajax_search_nonce')) { wp_send_json_error(); } $video_ids = false; // Used for the playlist edit. if (isset($_POST['videoIds'])) { if ('none' === $_POST['videoIds']) { wp_send_json_success(array()); // Existing playlist with no video IDs. } $video_ids = array(); // To handle the playlist of one video ID which is sent as a string instead of Array of 1 element. if (is_string($_POST['videoIds'])) { $video_ids[] = BC_Utility::sanitize_id($_POST['videoIds']); } else { foreach ($_POST['videoIds'] as $video_id) { $video_ids[] = BC_Utility::sanitize_id($video_id); } } } $account_id = isset($_POST['account']) ? sanitize_text_field($_POST['account']) : 'all'; if ('all' !== $account_id) { $account_id = BC_Utility::sanitize_id($_POST['account']); } $query = isset($_POST['search']) && '' !== $_POST['search'] ? sanitize_text_field($_POST['search']) : false; $tags = isset($_POST['tags']) && '' !== $_POST['tags'] ? array_map('absint', (array) $_POST['tags']) : false; $tag_name = isset($_POST['tagName']) && '' !== $_POST['tagName'] ? sanitize_text_field($_POST['tagName']) : false; $dates = isset($_POST['dates']) && 'all' !== $_POST['dates'] ? BC_Utility::sanitize_date($_POST['dates']) : false; $posts_per_page = isset($_POST['posts_per_page']) ? absint($_POST['posts_per_page']) : apply_filters('brightcove_max_posts_per_page', 100); $page = isset($_POST['page_number']) ? absint($_POST['page_number']) : 1; $type = isset($_POST['type']) ? sanitize_key($_POST['type']) : false; if (!$type || !in_array($type, array('videos', 'playlists'))) { wp_send_json_error(esc_html__('Invalid Search Type', 'brightcove')); exit; // Type can only be videos or playlists. } global $bc_accounts; if ('videos' === $type) { $query_terms = array(); $query_string = ''; if ($tag_name) { $query_terms[] = "tags:{$tag_name}"; $query_string .= "tags:{$tag_name}"; } if ($dates) { $query_terms[] = "updated_at:{$dates}-01..{$dates}-31"; $query_string .= "updated_at:{$dates}-01..{$dates}-31"; } if ($query) { array_unshift($query_terms, $query); } if ($video_ids) { // We send the video_ids sorted since we have them returned sorted by ID. // This way we get cache hits when playlist order, but not content have changed. $video_ids_sorted = $video_ids; sort($video_ids_sorted); $query_terms[] = "id:" . implode("+id:", $video_ids_sorted); } $query_string = implode("+", $query_terms); /** * For playlists, we specify the order in the query string as follows: * https://cms.api.brightcove.com/v1/accounts/<account_id>/videos?q=id:<video_id1>...+id:<video_idn> * * However it comes back to us sorted by video ID (smallest to largest, so afterwards we resort the dataset * by playlist sort order. */ $bc_accounts->set_current_account_by_id($account_id); $results = $this->cms_api->video_list($posts_per_page, $posts_per_page * ($page - 1), $query_string, 'updated_at'); /** * Since we use the video_list to fetch the videos for a playlist, it returns them to us * ordered by video_id, so we use the order of video_ids (the playlist order) to sort them * as per the playlist. */ if ($video_ids) { $ordered_results = array(); foreach ($video_ids as $video_id) { foreach ($results as $video_result) { if ($video_id === $video_result['id']) { $ordered_results[] = $video_result; break; } } } // $ordered_results is now in the same order as $video_ids $results = $ordered_results; } } else { $bc_accounts->set_current_account_by_id($account_id); $results = $this->cms_api->playlist_list(); } $bc_accounts->restore_default_account(); wp_send_json_success($results); }
/** * Retrieves videos and playlists * * Handles the query and distributes to the proper part of the CMS API. * * @since 1.0 * * @return void */ public function brightcove_media_query() { if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], '_bc_ajax_search_nonce')) { wp_send_json_error(); } $video_ids = false; // Used for the playlist edit. if (isset($_POST['videoIds'])) { if ('none' === $_POST['videoIds']) { wp_send_json_success(array()); // Existing playlist with no video IDs. } $video_ids = array(); // To handle the playlist of one video ID which is sent as a string instead of Array of 1 element. if (is_string($_POST['videoIds'])) { $video_ids[] = BC_Utility::sanitize_id($_POST['videoIds']); } else { foreach ($_POST['videoIds'] as $video_id) { $video_ids[] = BC_Utility::sanitize_id($video_id); } } } $account_id = isset($_POST['account']) ? sanitize_text_field($_POST['account']) : 'all'; if ('all' !== $account_id) { $account_id = BC_Utility::sanitize_id($_POST['account']); } $query = isset($_POST['search']) && '' !== $_POST['search'] ? sanitize_text_field($_POST['search']) : false; $tag_name = isset($_POST['tagName']) && '' !== $_POST['tagName'] ? sanitize_text_field($_POST['tagName']) : false; $dates = isset($_POST['dates']) && 'all' !== $_POST['dates'] ? BC_Utility::sanitize_date($_POST['dates']) : false; /** * Filter the maximum number of items the brightcove media call will query for. * * Enables adjusting the `posts_per_page` parameter used when querying for media. Absint is applied, * so a positive number should be supplied. * * @param int $posts_per_page Posts per page for media query. Default 100. */ $posts_per_page = isset($_POST['posts_per_page']) ? absint($_POST['posts_per_page']) : apply_filters('brightcove_max_posts_per_page', 100); $page = isset($_POST['page_number']) ? absint($_POST['page_number']) : 1; $type = isset($_POST['type']) ? sanitize_key($_POST['type']) : false; if (!$type || !in_array($type, array('videos', 'playlists'))) { wp_send_json_error(esc_html__('Invalid Search Type', 'brightcove')); exit; // Type can only be videos or playlists. } global $bc_accounts; $tries = apply_filters('wpbc_api_tries', 3); if ('videos' === $type) { $query_terms = array(); if ($tag_name) { // Tag Dropdown Search should use quotes to signify an exact match. // Handles single and multi-word tags $query_terms[] = 'tags:"' . $tag_name . '"'; } if ($dates) { $query_terms[] = "updated_at:{$dates}-01..{$dates}-31"; } if ($query) { array_unshift($query_terms, $query); } if ($video_ids) { // We send the video_ids sorted since we have them returned sorted by ID. // This way we get cache hits when playlist order, but not content have changed. $video_ids_sorted = $video_ids; sort($video_ids_sorted); $query_terms[] = "id:" . implode("+id:", $video_ids_sorted); } $query_string = implode("+", $query_terms); /** * For playlists, we specify the order in the query string as follows: * https://cms.api.brightcove.com/v1/accounts/<account_id>/videos?q=id:<video_id1>...+id:<video_idn> * * However it comes back to us sorted by video ID (smallest to largest, so afterwards we resort the dataset * by playlist sort order. */ $bc_accounts->set_current_account_by_id($account_id); // Get a list of videos. for ($i = 0; $i < $tries; $i++) { $results = $this->cms_api->video_list($posts_per_page, $posts_per_page * ($page - 1), $query_string, 'updated_at'); if (!is_wp_error($results)) { break; } else { sleep(1); // Sleep for 1 second on a failure } } if (is_wp_error($results)) { wp_send_json_error(); } /** * Since we use the video_list to fetch the videos for a playlist, it returns them to us * ordered by video_id, so we use the order of video_ids (the playlist order) to sort them * as per the playlist. */ if ($video_ids) { $ordered_results = array(); foreach ($video_ids as $video_id) { foreach ($results as $video_result) { if ($video_id === $video_result['id']) { $ordered_results[] = $video_result; break; } } } // $ordered_results is now in the same order as $video_ids $results = $ordered_results; } } else { $bc_accounts->set_current_account_by_id($account_id); for ($i = 0; $i < $tries; $i++) { $results = $this->cms_api->playlist_list(); if (!is_wp_error($results)) { break; } else { sleep(1); // Sleep for 1 second on a failure } } if (is_wp_error($results)) { wp_send_json_error(); } } // Get a list of available custom fields for ($i = 0; $i < $tries; $i++) { $fields = $this->cms_api->video_fields(); if (!is_wp_error($fields)) { break; } else { sleep(1); // Sleep for 1 second on a failure } } if (is_wp_error($fields)) { wp_send_json_error(); } // Loop through results to remap items foreach ($results as &$result) { // Map the custom_fields array to a collection of objects with description, display name, id, etc $result['custom'] = $fields['custom_fields']; if (isset($result['custom_fields'])) { foreach ($result['custom_fields'] as $id => $value) { // Extract the change tracking item explicitly if ($id == '_change_history') { $result['history'] = $value; continue; } foreach ($result['custom'] as &$field) { if ($field['id'] === $id) { $field['value'] = $value; break; } } } } // Massage the text tracks $result['captions'] = array(); if (isset($result['test_tracks'])) { foreach ($result['text_tracks'] as $caption) { $result['captions'][] = array('source' => $caption['src'], 'language' => $caption['srclang'], 'label' => $caption['label']); } } } $bc_accounts->restore_default_account(); /** * Filter media query results. * * @since 1.3 */ $results = apply_filters('brightcove_media_query_results', $results, $type); wp_send_json_success($results); }