Settings saved!
'; } // Get saved options $postTypes = get_option('content_filter_post_types', []); $taxonomies = get_option('content_filter_taxonomies', []); $posts_per_page = get_option('content_filter_posts_per_page', 12); $homepage_taxonomy = get_option('content_filter_homepage_taxonomy', ''); // Get all available post types and taxonomies $all_post_types = get_post_types(['public' => true], 'objects'); $all_taxonomies = get_taxonomies(['public' => true], 'objects'); ?>Error: No valid taxonomy configured for the homepage filter.
'; return false; } } else { return 'filter-form.php'; } } /** Includes a template file. * * If the template file is found, it is included once. Otherwise, an error message is displayed. * * @param string $template The path to the template file. * @param string $errorMessage The error message to display if the template file is not found. * * @since 1.0.0 */ private function includeTemplate($template, $errorMessage) { if ($template) { include_once $template; } else { echo 'Error: ' . $errorMessage . '
'; } } /** Renders the resource results. * * If the request method is POST, this directly renders the filtered results. * Otherwise, it loads all resources initially. * * This function also handles pagination for the resource results. * * @param \WP_Query $query The WP_Query object for the resource results. * * @since 1.0.0 */ private function renderResourceResults($query) { ?>Error: Results template not found.
'; } wp_reset_postdata(); } /** AJAX handler for filtering resources. * * Searches for resources based on search term, resource type, and/or resource subject. * Returns a JSON response with the count of resources found and the HTML for the resource results. * * Verifies the nonce and sanitizes the input data. * * @since 1.0.0 */ public function filterResources() { $is_ajax = defined('DOING_AJAX') && DOING_AJAX; if ($is_ajax) { check_ajax_referer('resource_filter_nonce', 'nonce'); } $query_args = $this->buildQueryArgs(); $query = new WP_Query($query_args); ob_start(); $resources = $query->posts; $resResults = rfGetTemplate('resource-results.php'); if ($resResults) { include_once $resResults; } else { echo 'Error: Results template not found.
'; } if ($is_ajax) { $this->sendAjaxResponse($query); } else { echo ob_get_clean(); } } /** Build the query arguments array for filtering resources. * * Uses the $_POST data to generate the query arguments for the WP_Query object. * Sanitizes the input data to prevent SQL injection attacks. * * @return array The query arguments array. * * @since 1.0.0 */ private function buildQueryArgs() { $postTypes = get_option('content_filter_post_types', []); $postCount = get_option('content_filter_posts_per_page', 12); // Get posts per page from admin $strSearch = isset($_POST['search']) ? sanitize_text_field($_POST['search']) : ''; $sort_order = isset($_POST['sort_order']) ? sanitize_text_field($_POST['sort_order']) : 'date_desc'; $query_args = [ 'post_type' => !empty($postTypes) ? $postTypes : ['post'], 'posts_per_page' => $postCount, 'paged' => isset($_POST['paged']) ? intval($_POST['paged']) : 1, // Get current page number 'tax_query' => $this->buildDynamicTaxQuery(), 's' => $strSearch, ]; $query_args = $this->applySorting($query_args, $sort_order); $query_args['tax_query'] = $this->buildDynamicTaxQuery(); return $query_args; } /** Generate a dynamic tax query based on the $_POST data. * * Looks through the taxonomies specified in the settings and builds a tax query * for each one that has a value in the $_POST data. Sanitizes the input data to * prevent SQL injection attacks. * * @return array The tax query array. * * @since 1.4.0 */ private function buildDynamicTaxQuery() { $taxonomies = get_option('content_filter_taxonomies', []); // Get selected taxonomies from admin $tax_query = []; if (!empty($taxonomies)) { foreach ($taxonomies as $taxonomy) { if (!empty($_POST[$taxonomy])) { $terms = is_array($_POST[$taxonomy]) ? array_map('sanitize_text_field', $_POST[$taxonomy]) : sanitize_text_field($_POST[$taxonomy]); $tax_query[] = [ 'taxonomy' => $taxonomy, 'field' => 'slug', 'terms' => $terms, 'operator' => 'IN', ]; } } } if (!empty($tax_query)) { return [ 'relation' => 'AND', ...$tax_query, ]; } return []; } /** Sends an AJAX response with resource filtering results. * * Constructs a response array containing the number of resources found, * the applied filters, the HTML output of the resources, and pagination links. * The response is then encoded as a JSON object and sent back to the client. * * @param WP_Query $query The query object containing the filtered resources. * * @since 1.0.0 */ private function sendAjaxResponse($query) { $response = [ 'count' => $query->found_posts, 'filters' => [ 'search' => isset($_POST['search']) ? sanitize_text_field($_POST['search']) : '', ], 'html' => ob_get_clean(), 'pagination' => paginate_links([ 'total' => $query->max_num_pages, 'current' => isset($_POST['paged']) ? intval($_POST['paged']) : 1, 'format' => '?paged=%#%', 'add_args' => [], // Pass additional query arguments 'prev_text' => '«', 'next_text' => '»', 'type' => 'array', ]) ]; // Include dynamic taxonomy filters in the response $taxonomies = get_option('content_filter_taxonomies', []); foreach ($taxonomies as $taxonomy) { if (!empty($_POST[$taxonomy])) { $response['filters'][$taxonomy] = array_map('sanitize_text_field', (array) $_POST[$taxonomy]); } } echo json_encode($response); wp_die(); } } new ContentFilterPlugin(); $gitHubUpdater = new GitHubUpdater(__FILE__); $gitHubUpdater->setChangelog('CHANGELOG.md'); $gitHubUpdater->setPluginIcon('assets/icon-256x256.png'); $gitHubUpdater->setPluginBannerLarge('assets/banner.jpg'); $gitHubUpdater->setPluginBannerSmall('assets/banner.jpg'); $gitHubUpdater->add();