PluginProbe ʕ •ᴥ•ʔ
Broken Link Checker / 1.5.3
Broken Link Checker v1.5.3
1.5.4 1.5.5 1.6 1.6.1 1.6.2 1.7 1.7.1 1.8 1.8.1 1.8.2 1.8.3 1.9 1.9.1 1.9.2 1.9.3 1.9.4 1.9.4.1 1.9.4.2 1.9.5 2.0.0 2.1.0 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.3.0 2.3.1 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.4.8 0.9.4 0.9.4.1 0.9.4.2 0.9.4.3 0.9.4.4 0.9.4.4-last-non-modular 0.9.5 0.9.6 0.9.7 0.9.7.1 0.9.7.2 1.10 1.10.1 1.10.10 1.10.11 1.10.2 1.10.3 1.10.4 1.10.5 1.10.6 1.10.7 1.10.8 1.10.9 1.11.1 1.11.10 1.11.11 1.11.12 1.11.13 1.11.14 1.11.15 1.11.17 1.11.18 1.11.19 1.11.2 1.11.20 1.11.21 1.11.3 1.11.4 1.11.5 1.11.8 1.11.9 1.2.2 1.2.3 1.2.4 1.2.5 1.3 1.3.1 1.4 1.5 1.5.1 1.5.2 1.5.3 trunk 0.1 0.2 0.2.2 0.2.2.1 0.2.3 0.2.4 0.2.5 0.3 0.3.1 0.3.2 0.3.3 0.3.4 0.3.5 0.3.6 0.3.7 0.3.8 0.3.9 0.4 0.4-i8n 0.4.1 0.4.10 0.4.11 0.4.12 0.4.13 0.4.14 0.4.2 0.4.3 0.4.4 0.4.5 0.4.6 0.4.7 0.4.8 0.4.9 0.5 0.5.1 0.5.10 0.5.10.1 0.5.11 0.5.12 0.5.13 0.5.14 0.5.15 0.5.16 0.5.16.1 0.5.17 0.5.18 0.5.2 0.5.3 0.5.4 0.5.5 0.5.6 0.5.7 0.5.8 0.5.8.1 0.5.9 0.6 0.6.1 0.6.2 0.6.3 0.6.4 0.6.5 0.7 0.7.1 0.7.2 0.7.3 0.7.4 0.8 0.8.1 0.9 0.9.1 0.9.2 0.9.3
broken-link-checker / includes / link-query.php
broken-link-checker / includes Last commit date
admin 14 years ago screen-options 15 years ago activation.php 14 years ago any-post.php 14 years ago checkers.php 14 years ago config-manager.php 14 years ago containers.php 14 years ago extra-strings.php 14 years ago instances.php 14 years ago link-query.php 14 years ago links.php 14 years ago logger.php 15 years ago module-base.php 15 years ago module-manager.php 14 years ago modules.php 14 years ago parsers.php 14 years ago screen-meta-links.php 14 years ago survey.php 14 years ago utility-class.php 14 years ago wp-mutex.php 14 years ago
link-query.php
796 lines
1 <?php
2
3 /**
4 * Class for querying, sorting and filtering links.
5 * Used as a singleton.
6 *
7 * @package Broken Link Checker
8 * @access public
9 */
10 class blcLinkQuery {
11
12 var $native_filters;
13 var $search_filter;
14 var $custom_filters = array();
15
16 var $valid_url_params = array();
17
18 function __construct(){
19 //Init. the available native filters.
20 $this->native_filters = array(
21 'broken' => array(
22 'params' => array(
23 'where_expr' => '( broken = 1 )',
24 ),
25 'name' => __('Broken', 'broken-link-checker'),
26 'heading' => __('Broken Links', 'broken-link-checker'),
27 'heading_zero' => __('No broken links found', 'broken-link-checker'),
28 'native' => true,
29 ),
30 'redirects' => array(
31 'params' => array(
32 'where_expr' => '( redirect_count > 0 )',
33 ),
34 'name' => __('Redirects', 'broken-link-checker'),
35 'heading' => __('Redirected Links', 'broken-link-checker'),
36 'heading_zero' => __('No redirects found', 'broken-link-checker'),
37 'native' => true,
38 ),
39
40 'all' => array(
41 'params' => array(
42 'where_expr' => '1',
43 ),
44 'name' => __('All', 'broken-link-checker'),
45 'heading' => __('Detected Links', 'broken-link-checker'),
46 'heading_zero' => __('No links found (yet)', 'broken-link-checker'),
47 'native' => true,
48 ),
49 );
50
51 //Create the special "search" filter
52 $this->search_filter = array(
53 'name' => __('Search', 'broken-link-checker'),
54 'heading' => __('Search Results', 'broken-link-checker'),
55 'heading_zero' => __('No links found for your query', 'broken-link-checker'),
56 'params' => array(),
57 'use_url_params' => true,
58 'hidden' => true,
59 );
60
61 //These search arguments may be passed via the URL if the filter's 'use_url_params' field is set to True.
62 //They map to the fields of the search form on the Tools -> Broken Links page. Only these arguments
63 //can be used in user-defined filters.
64 $this->valid_url_params = array(
65 's_link_text',
66 's_link_url',
67 's_parser_type',
68 's_container_type',
69 's_link_type',
70 's_http_code',
71 's_filter',
72 );
73 }
74
75 static function getInstance(){
76 static $instance = null;
77 if ( is_null($instance) ){
78 $instance = new blcLinkQuery;
79 }
80 return $instance;
81 }
82
83 /**
84 * Load and return the list of user-defined link filters.
85 *
86 * @return array An array of custom filter definitions. If there are no custom filters defined returns an empty array.
87 */
88 function load_custom_filters(){
89 global $wpdb; /** @var wpdb $wpdb */
90
91 $filter_data = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}blc_filters ORDER BY name ASC", ARRAY_A);
92 $filters = array();
93
94 if ( !empty($filter_data) ) {
95 foreach($filter_data as $data){
96 wp_parse_str($data['params'], $params);
97
98 $filters[ 'f'.$data['id'] ] = array(
99 'name' => $data['name'],
100 'params' => $params,
101 'heading' => ucwords($data['name']),
102 'heading_zero' => __('No links found for your query', 'broken-link-checker'),
103 'custom' => true,
104 );
105 }
106 }
107
108 $this->custom_filters = $filters;
109
110 return $filters;
111 }
112
113 /**
114 * Add a custom link filter.
115 *
116 * @param string $name Filter name.
117 * @param string|array $params Filter params. Either as a query string, or an array.
118 * @return string|bool The ID of the newly added filter, or False.
119 */
120 function create_custom_filter($name, $params){
121 global $wpdb; /** @var wpdb $wpdb */
122
123 if ( is_array($params) ){
124 $params = http_build_query($params, null, '&');
125 }
126
127 //Save the new filter
128 $q = $wpdb->prepare(
129 "INSERT INTO {$wpdb->prefix}blc_filters(name, params) VALUES (%s, %s)",
130 $name, $params
131 );
132
133 if ( $wpdb->query($q) !== false ){
134 $filter_id = 'f'.$wpdb->insert_id;
135 return $filter_id;
136 } else {
137 return false;
138 }
139 }
140
141 /**
142 * Delete a custom filter
143 *
144 * @param string $filter_id
145 * @return bool True on success, False if a database error occured.
146 */
147 function delete_custom_filter($filter_id){
148 global $wpdb; /** @var wpdb $wpdb */
149
150 //Remove the "f" character from the filter ID to get its database key
151 $filter_id = intval(ltrim($_POST['filter_id'], 'f'));
152
153 //Try to delete the filter
154 $q = $wpdb->prepare("DELETE FROM {$wpdb->prefix}blc_filters WHERE id = %d", $filter_id);
155 if ( $wpdb->query($q) !== false ){
156 return true;
157 } else {
158 return false;
159 }
160 }
161
162 function get_filters(){
163 $filters = array_merge($this->native_filters, $this->custom_filters);
164 $filters['search'] = $this->search_filter;
165 return $filters;
166 }
167
168 /**
169 * Get a link search filter by filter ID.
170 *
171 * @param string $filter_id
172 * @return array|null
173 */
174 function get_filter($filter_id){
175 $filters = $this->get_filters();
176 if ( isset($filters[$filter_id]) ){
177 return $filters[$filter_id];
178 } else {
179 return null;
180 }
181 }
182
183 /**
184 * Get link search parameters from the specified filter.
185 *
186 * @param array $filter
187 * @return array An array of parameters suitable for use with blcLinkQuery::get_links()
188 */
189 function get_search_params( $filter = null ){
190 //If present, the filter's parameters may be saved either as an array or a string.
191 $params = array();
192 if ( !empty($filter) && !empty($filter['params']) ){
193 $params = $filter['params'];
194 if ( is_string( $params ) ){
195 wp_parse_str($params, $params);
196 }
197 }
198
199 //Merge in the parameters from the current request, if required
200 if ( isset($filter['use_url_params']) && $filter['use_url_params'] ){
201 $params = array_merge($params, $this->get_url_search_params());
202 }
203
204 return $params;
205 }
206
207 /**
208 * Extract search query parameters from the current URL
209 *
210 * @return array
211 */
212 function get_url_search_params(){
213 $url_params = array();
214 foreach ($_GET as $param => $value){
215 if ( in_array($param, $this->valid_url_params) ){
216 $url_params[$param] = $value;
217 }
218 }
219 return $url_params;
220 }
221
222
223
224 /**
225 * A helper method for parsing a list of search criteria and generating the parts of the SQL query.
226 *
227 * @see blcLinkQuery::get_links()
228 *
229 * @param array $params An array of search criteria.
230 * @return array 'where_exprs' - an array of search expressions, 'join_instances' - whether joining the instance table is required.
231 */
232 function compile_search_params($params){
233 global $wpdb; /** @var wpdb $wpdb */
234
235 //Track whether we'll need to left-join the instance table to run the query.
236 $join_instances = false;
237
238 //Generate the individual clauses of the WHERE expression and store them in an array.
239 $pieces = array();
240
241 //Convert parser and container type lists to arrays of valid values
242 $s_parser_type = array();
243 if ( !empty($params['s_parser_type']) ){
244 $s_parser_type = $params['s_parser_type'];
245 if ( is_string($s_parser_type) ){
246 $s_parser_type = preg_split('/[,\s]+/', $s_parser_type);
247 }
248 }
249
250 $s_container_type = array();
251 if ( !empty($params['s_container_type']) ){
252 $s_container_type = $params['s_container_type'];
253 if ( is_string($s_container_type) ){
254 $s_container_type = preg_split('/[,\s]+/', $s_container_type);
255 }
256 }
257
258 //Don't include links with instances that reference invalid (not currently loaded)
259 //containers and parsers (unless specifically told to also include invalid links).
260 if ( empty($params['include_invalid']) ){
261 $join_instances = true;
262
263 $module_manager = blcModuleManager::getInstance();
264 $loaded_containers = array_keys($module_manager->get_active_by_category('container'));
265 $loaded_parsers = array_keys($module_manager->get_active_by_category('parser'));
266
267 if ( empty($s_parser_type) ){
268 $s_parser_type = $loaded_parsers;
269 } else {
270 $s_parser_type = array_intersect($s_parser_type, $loaded_parsers);
271 }
272
273 if ( empty($s_container_type) ){
274 $s_container_type = $loaded_containers;
275 } else {
276 $s_container_type = array_intersect($s_container_type, $loaded_containers);
277 }
278 }
279
280 //Parser type should match the parser_type column in the instance table.
281 if ( !empty($s_parser_type) ){
282 $s_parser_type = array_map('trim', array_unique($s_parser_type));
283 $s_parser_type = array_map(array(&$wpdb, 'escape'), $s_parser_type);
284
285 if ( count($s_parser_type) == 1 ){
286 $pieces[] = sprintf("instances.parser_type = '%s'", reset($s_parser_type));
287 } else {
288 $pieces[] = "instances.parser_type IN ('" . implode("', '", $s_parser_type) . "')";
289 }
290
291 $join_instances = true;
292 }
293
294 //Container type should match the container_type column in the instance table.
295 if ( !empty($s_container_type) ){
296 //Sanitize for use in SQL
297 $s_container_type = array_map('trim', array_unique($s_container_type));
298 $s_container_type = array_map(array(&$wpdb, 'escape'), $s_container_type);
299
300 if ( count($s_container_type) == 1 ){
301 $pieces[] = sprintf("instances.container_type = '%s'", reset($s_container_type));
302 } else {
303 $pieces[] = "instances.container_type IN ('" . implode("', '", $s_container_type) . "')";
304 }
305
306 $join_instances = true;
307 }
308
309 //A part of the WHERE expression can be specified explicitly
310 if ( !empty($params['where_expr']) ){
311 $pieces[] = $params['where_expr'];
312 $join_instances = $join_instances || ( stripos($params['where_expr'], 'instances') !== false );
313 }
314
315 //List of allowed link ids (either an array or comma-separated)
316 if ( !empty($params['link_ids']) ){
317 $link_ids = $params['link_ids'];
318
319 if ( is_string($link_ids) ){
320 $link_ids = preg_split('/[,\s]+/', $link_ids);
321 }
322
323 //Only accept non-zero integers
324 $sanitized_link_ids = array();
325 foreach($link_ids as $id){
326 $id = intval($id);
327 if ( $id != 0 ){
328 $sanitized_link_ids[] = $id;
329 }
330 }
331
332 $pieces[] = 'links.link_id IN (' . implode(', ', $sanitized_link_ids) . ')';
333 }
334
335 //Anchor text - use LIKE search
336 if ( !empty($params['s_link_text']) ){
337 $s_link_text = like_escape($wpdb->escape($params['s_link_text']));
338 $s_link_text = str_replace('*', '%', $s_link_text);
339
340 $pieces[] = '(instances.link_text LIKE "%' . $s_link_text . '%")';
341 $join_instances = true;
342 }
343
344 //URL - try to match both the initial URL and the final URL.
345 //There is limited wildcard support, e.g. "google.*/search" will match both
346 //"google.com/search" and "google.lv/search"
347 if ( !empty($params['s_link_url']) ){
348 $s_link_url = like_escape($wpdb->escape($params['s_link_url']));
349 $s_link_url = str_replace('*', '%', $s_link_url);
350
351 $pieces[] = '(links.url LIKE "%'. $s_link_url .'%") OR '.
352 '(links.final_url LIKE "%'. $s_link_url .'%")';
353 }
354
355 //Container ID should match... you guessed it - container_id
356 if ( !empty($params['s_container_id']) ){
357 $s_container_id = intval($params['s_container_id']);
358 if ( $s_container_id != 0 ){
359 $pieces[] = "instances.container_id = $s_container_id";
360 $join_instances = true;
361 }
362 }
363
364 //Link type can match either the the parser_type or the container_type.
365 if ( !empty($params['s_link_type']) ){
366 $s_link_type = $wpdb->escape($params['s_link_type']);
367 $pieces[] = "instances.parser_type = '$s_link_type' OR instances.container_type='$s_link_type'";
368 $join_instances = true;
369 }
370
371 //HTTP code - the user can provide a list of HTTP response codes and code ranges.
372 //Example : 201,400-410,500
373 if ( !empty($params['s_http_code']) ){
374 //Strip spaces.
375 $params['s_http_code'] = str_replace(' ', '', $params['s_http_code']);
376 //Split by comma
377 $codes = explode(',', $params['s_http_code']);
378
379 $individual_codes = array();
380 $ranges = array();
381
382 //Try to parse each response code or range. Invalid ones are simply ignored.
383 foreach($codes as $code){
384 if ( is_numeric($code) ){
385 //It's a single number
386 $individual_codes[] = abs(intval($code));
387 } elseif ( strpos($code, '-') !== false ) {
388 //Try to parse it as a range
389 $range = explode( '-', $code, 2 );
390 if ( (count($range) == 2) && is_numeric($range[0]) && is_numeric($range[0]) ){
391 //Make sure the smaller code comes first
392 $range = array( intval($range[0]), intval($range[1]) );
393 $ranges[] = array( min($range), max($range) );
394 }
395 }
396 }
397
398 $piece = array();
399
400 //All individual response codes get one "http_code IN (...)" clause
401 if ( !empty($individual_codes) ){
402 $piece[] = '(links.http_code IN ('. implode(', ', $individual_codes) .'))';
403 }
404
405 //Ranges get a "http_code BETWEEN min AND max" clause each
406 if ( !empty($ranges) ){
407 $range_strings = array();
408 foreach($ranges as $range){
409 $range_strings[] = "(links.http_code BETWEEN $range[0] AND $range[1])";
410 }
411 $piece[] = '( ' . implode(' OR ', $range_strings) . ' )';
412 }
413
414 //Finally, generate a composite WHERE clause for both types of response code queries
415 if ( !empty($piece) ){
416 $pieces[] = implode(' OR ', $piece);
417 }
418
419 }
420
421 //Optionally sorting is also possible
422 $order_exprs = array();
423 if ( !empty($params['orderby']) ) {
424 $allowed_columns = array(
425 'url' => 'links.url',
426 );
427 $column = $params['orderby'];
428
429 $direction = !empty($params['order']) ? strtolower($params['order']) : 'asc';
430 if ( !in_array($direction, array('asc', 'desc')) ) {
431 $direction = 'asc';
432 }
433
434 if ( array_key_exists($column, $allowed_columns) ) {
435 $order_exprs[] = $allowed_columns[$column] . ' ' . $direction;
436 }
437 }
438
439 //Custom filters can optionally call one of the native filters
440 //to narrow down the result set.
441 if ( !empty($params['s_filter']) && isset($this->native_filters[$params['s_filter']]) ){
442 $the_filter = $this->native_filters[$params['s_filter']];
443 $extra_criteria = $this->compile_search_params($the_filter['params']);
444
445 $pieces = array_merge($pieces, $extra_criteria['where_exprs']);
446 $join_instances = $join_instances || $extra_criteria['join_instances'];
447 }
448
449 return array(
450 'where_exprs' => $pieces,
451 'join_instances' => $join_instances,
452 'order_exprs' => $order_exprs,
453 );
454 }
455
456 /**
457 * blcLinkQuery::get_links()
458 *
459 * @see blc_get_links()
460 *
461 * @param array $params
462 * @return array|int
463 */
464 function get_links($params = null){
465 global $wpdb; /** @var wpdb $wpdb */
466
467 if( !is_array($params) ){
468 $params = array();
469 }
470
471 $defaults = array(
472 'offset' => 0,
473 'max_results' => 0,
474 'load_instances' => false,
475 'load_containers' => false,
476 'load_wrapped_objects' => false,
477 'count_only' => false,
478 'purpose' => '',
479 'include_invalid' => false,
480 'orderby' => '',
481 'order' => '',
482 );
483
484 $params = array_merge($defaults, $params);
485
486 //Compile the search-related params into search expressions usable in a WHERE clause
487 $criteria = $this->compile_search_params($params);
488
489 //Build the WHERE clause
490 if ( !empty($criteria['where_exprs']) ){
491 $where_expr = "\t( " . implode(" ) AND\n\t( ", $criteria['where_exprs']) . ' ) ';
492 } else {
493 $where_expr = '1';
494 }
495
496 //Join the blc_instances table if it's required to perform the search.
497 $joins = "";
498 if ( $criteria['join_instances'] ){
499 $joins = "JOIN {$wpdb->prefix}blc_instances AS instances ON links.link_id = instances.link_id";
500 }
501
502 //Optional sorting
503 if ( !empty($criteria['order_exprs']) ) {
504 $order_clause = 'ORDER BY ' . implode(', ', $criteria['order_exprs']);
505 } else {
506 $order_clause = '';
507 }
508
509 if ( $params['count_only'] ){
510 //Only get the number of matching links.
511 $q = "
512 SELECT COUNT(*)
513 FROM (
514 SELECT 0
515
516 FROM
517 {$wpdb->prefix}blc_links AS links
518 $joins
519
520 WHERE
521 $where_expr
522
523 GROUP BY links.link_id) AS foo";
524
525 return $wpdb->get_var($q);
526 }
527
528 //Select the required links.
529 $q = "SELECT
530 links.*
531
532 FROM
533 {$wpdb->prefix}blc_links AS links
534 $joins
535
536 WHERE
537 $where_expr
538
539 GROUP BY links.link_id
540
541 {$order_clause}"; //Note: would be a lot faster without GROUP BY
542
543 //Add the LIMIT clause
544 if ( $params['max_results'] || $params['offset'] ){
545 $q .= sprintf("\nLIMIT %d, %d", $params['offset'], $params['max_results']);
546 }
547
548 $results = $wpdb->get_results($q, ARRAY_A);
549 if ( empty($results) ){
550 return array();
551 }
552
553 //Create the link objects
554 $links = array();
555
556 foreach($results as $result){
557 $link = new blcLink($result);
558 $links[$link->link_id] = $link;
559 }
560
561 $purpose = $params['purpose'];
562 /*
563 Preload instances if :
564 * It has been requested via the 'load_instances' argument.
565 * The links are going to be displayed or edited, which involves instances.
566 */
567 $load_instances = $params['load_instances'] || in_array($purpose, array(BLC_FOR_DISPLAY, BLC_FOR_EDITING));
568
569 if ( $load_instances ){
570 $link_ids = array_keys($links);
571 $all_instances = blc_get_instances($link_ids, $purpose, $params['load_containers'], $params['load_wrapped_objects']);
572 //Assign each batch of instances to the right link
573 foreach($all_instances as $link_id => $instances){
574 foreach($instances as $instance) { /** @var blcLinkInstance $instance */
575 $instance->_link = $links[$link_id];
576 }
577 $links[$link_id]->_instances = $instances;
578 }
579 }
580
581 return $links;
582 }
583
584 /**
585 * Calculate the number of results for all known filters
586 *
587 * @return void
588 */
589 function count_filter_results(){
590 foreach($this->native_filters as $filter_id => $filter){
591 $this->native_filters[$filter_id]['count'] = $this->get_filter_links(
592 $filter, array('count_only' => true)
593 );
594 }
595
596 foreach($this->custom_filters as $filter_id => $filter){
597 $this->custom_filters[$filter_id]['count'] = $this->get_filter_links(
598 $filter, array('count_only' => true)
599 );
600 }
601
602 $this->search_filter['count'] = $this->get_filter_links($this->search_filter, array('count_only' => true));
603 }
604
605 /**
606 * Retrieve a list of links matching a filter.
607 *
608 * @uses blcLinkQuery::get_links()
609 *
610 * @param string|array $filter Either a filter ID or an array containing filter data.
611 * @param array $extra_params Optional extra criteria that will override those set by the filter. See blc_get_links() for details.
612 * @return array|int Either an array of blcLink objects, or an integer indicating the number of links that match the filter.
613 */
614 function get_filter_links($filter, $extra_params = null){
615 if ( is_string($filter) ){
616 $filter = $this->get_filter($filter);
617 }
618
619 $params = $this->get_search_params($filter);
620
621
622 if ( !empty($extra_params) ){
623 $params = array_merge($params, $extra_params);
624 }
625
626 return $this->get_links($params);
627 }
628
629 /**
630 * Print a menu of available filters, both native and user-created.
631 *
632 * @param string $current Current filter ID.
633 * @return void
634 */
635 function print_filter_menu($current = ''){
636 $filters = $this->get_filters();
637
638 echo '<ul class="subsubsub">';
639
640 //Construct a submenu of filter types
641 $items = array();
642 foreach ($filters as $filter => $data){
643 if ( !empty($data['hidden']) ) continue; //skip hidden filters
644
645 $class = $number_class = '';
646
647 if ( $current == $filter ) {
648 $class = 'class="current"';
649 $number_class = 'current-link-count';
650 }
651
652 $items[] = "<li><a href='tools.php?page=view-broken-links&filter_id=$filter' $class>
653 {$data['name']}</a> <span class='count'>(<span class='$number_class'>{$data['count']}</span>)</span>";
654 }
655 echo implode(' |</li>', $items);
656
657 echo '</ul>';
658 }
659
660 /**
661 * Print the appropriate heading for the given filter.
662 *
663 * @param array $current_filter
664 * @return void
665 */
666 function print_filter_heading($current_filter){
667 echo '<h2>';
668 //Output a header matching the current filter
669 if ( $current_filter['count'] > 0 ){
670 echo $current_filter['heading'] . " (<span class='current-link-count'>{$current_filter['count']}</span>)";
671 } else {
672 echo $current_filter['heading_zero'] . "<span class='current-link-count'></span>";
673 }
674 echo '</h2>';
675 }
676
677 /**
678 * Execute a filter.
679 *
680 * Gathers paging and search parameters from $_GET and executes the specified filter.
681 * The returned array contains standard filter data plus several additional fields :
682 * 'filter_id' - Which filter was used. May differ from the specified $filter_id due to fallback settings.
683 * 'per_page' - How many results per page the method tried to retrieve.
684 * 'page' - Which page of results was retrieved.
685 * 'max_pages' - The total number of results pages, calculated using the above 'per_page' value.
686 * 'links' - An array of retrieved links (blcLink objects).
687 * 'search_params' - An associative array of the current search parameters as extracted either from the current URL or the filter itself.
688 * 'is_broken_filter' - TRUE if the filter was set to retrieve only broken links, FALSE otherwise.
689 *
690 * @param string $filter_id Filter ID.
691 * @param int $page Optional. Which page of results to retrieve. Defaults to returning the first page of results.
692 * @param int $per_page Optional. The number of results per page. Defaults to 30.
693 * @param string $fallback Optional. Which filter to use if none match the specified $filter_id. Defaults to the native broken link filter.
694 * @param string $orderby Optional. Sort results by this column.
695 * @param string $order Optional. Sort direction ('asc' or 'desc').
696 * @return array Associative array of filter data and the results of its execution.
697 */
698 function exec_filter($filter_id, $page = 1, $per_page = 30, $fallback = 'broken', $orderby = '', $order = 'asc'){
699
700 //Get the selected filter (defaults to displaying broken links)
701 $current_filter = $this->get_filter($filter_id);
702 if ( empty($current_filter) ){
703 $current_filter = $this->get_filter($fallback);
704 $filter_id = $fallback;
705 }
706
707 //Page number must be > 0
708 if ($page < 1) $page = 1;
709
710 //Links per page [1 - 500]
711 if ($per_page < 1){
712 $per_page = 30;
713 } else if ($per_page > 500){
714 $per_page = 500;
715 }
716
717 //Calculate the maximum number of pages.
718 $max_pages = ceil($current_filter['count'] / $per_page);
719
720 //Select the required links
721 $extra_params = array(
722 'offset' => ( ($page-1) * $per_page ),
723 'max_results' => $per_page,
724 'purpose' => BLC_FOR_DISPLAY,
725 'orderby' => $orderby,
726 'order' => $order,
727 );
728 $links = $this->get_filter_links($current_filter, $extra_params);
729
730 //If the current request is a user-initiated search query (either directly or
731 //via a custom filter), save the search params. They can later be used to pre-fill
732 //the search form or build a new/modified custom filter.
733 $search_params = array();
734 if ( !empty($current_filter['custom']) || ($filter_id == 'search') ){
735 $search_params = $this->get_search_params($current_filter);
736 }
737
738 //TODO: Simplify this. Maybe overhaul the filter system to let us query the effective filter.
739 $is_broken_filter =
740 ($filter_id == 'broken')
741 || ( isset($current_filter['params']['s_filter']) && ($current_filter['params']['s_filter'] == 'broken') )
742 || ( isset($_GET['s_filter']) && ($_GET['s_filter'] == 'broken') );
743
744 //Save the effective filter data in the filter array.
745 //It can be used later to print the link table.
746 $current_filter = array_merge(array(
747 'filter_id' => $filter_id,
748 'page' => $page,
749 'per_page' => $per_page,
750 'max_pages' => $max_pages,
751 'links' => $links,
752 'search_params' => $search_params,
753 'is_broken_filter' => $is_broken_filter,
754 ), $current_filter);
755
756 return $current_filter;
757 }
758 }
759
760 /**
761 * Retrieve a list of links matching some criteria.
762 *
763 * The function argument should be an associative array describing the criteria.
764 * The supported keys are :
765 * 'offset' - Skip the first X results. Default is 0.
766 * 'max_results' - The maximum number of links to return. Defaults to returning all results.
767 * 'link_ids' - Retrieve only links with these IDs. This should either be a comma-separated list or an array.
768 * 's_link_text' - Link text must match this keyphrase (performs a fulltext search).
769 * 's_link_url' - Link URL must contain this string. You can use "*" as a wildcard.
770 * 's_parser_type' - Filter links by the type of link parser that was used to find them.
771 * 's_container_type' - Filter links by where they were found, e.g. 'post'.
772 * 's_container_id' - Find links that belong to a container with this ID (should be used together with s_container_type).
773 * 's_link_type' - Either parser type or container type must match this.
774 * 's_http_code' - Filter by HTTP code. Example : 201,400-410,500
775 * 's_filter' - Use a built-in filter. Available filters : 'broken', 'redirects', 'all'
776 * 'where_expr' - Advanced. Lets you directly specify a part of the WHERE clause.
777 * 'load_instances' - Pre-load all link instance data for each link. Default is false.
778 * 'load_containers' - Pre-load container data for each instance. Default is false.
779 * 'load_wrapped_objects' - Pre-load wrapped object data (e.g. posts, comments, etc) for each container. Default is false.
780 * 'count_only' - Only return the number of results (int), not the whole result set. 'offset' and 'max_results' will be ignored if this is set. Default is false.
781 * 'purpose' - An optional code indicating how the links will be used.
782 * 'include_invalid' - Include links that have no instances and links that only have instances that reference not-loaded containers or parsers. Defaults to false.
783 *
784 * All keys are optional.
785 *
786 * @uses blcLinkQuery::get_links();
787 *
788 * @param array $params
789 * @return int|array Either an array of blcLink objects, or the number of results for the query.
790 */
791 function blc_get_links($params = null){
792 $instance = blcLinkQuery::getInstance();
793 return $instance->get_links($params);
794 }
795
796 ?>