| 1358 | if ( '' != $qv['category_name'] ) { |
| 1359 | $this->is_category = true; |
| 1360 | } |
| 1361 | |
| 1362 | if ( !is_array($qv['category__in']) || empty($qv['category__in']) ) { |
| 1363 | $qv['category__in'] = array(); |
| 1364 | } else { |
| 1365 | $qv['category__in'] = array_map('absint', $qv['category__in']); |
| 1366 | $this->is_category = true; |
| 1367 | } |
| 1368 | |
| 1369 | if ( !is_array($qv['category__not_in']) || empty($qv['category__not_in']) ) { |
| 1370 | $qv['category__not_in'] = array(); |
| 1371 | } else { |
| 1372 | $qv['category__not_in'] = array_map('absint', $qv['category__not_in']); |
| 1373 | } |
| 1374 | |
| 1375 | if ( !is_array($qv['category__and']) || empty($qv['category__and']) ) { |
| 1376 | $qv['category__and'] = array(); |
| 1377 | } else { |
| 1378 | $qv['category__and'] = array_map('absint', $qv['category__and']); |
| 1379 | $this->is_category = true; |
| 1380 | } |
| 1381 | |
| 1382 | if ( '' != $qv['tag'] ) |
| 1383 | $this->is_tag = true; |
| 1384 | |
| 1385 | $qv['tag_id'] = absint($qv['tag_id']); |
| 1386 | if ( !empty($qv['tag_id']) ) |
| 1387 | $this->is_tag = true; |
| 1388 | |
| 1389 | if ( !is_array($qv['tag__in']) || empty($qv['tag__in']) ) { |
| 1390 | $qv['tag__in'] = array(); |
| 1391 | } else { |
| 1392 | $qv['tag__in'] = array_map('absint', $qv['tag__in']); |
| 1393 | $this->is_tag = true; |
| 1394 | } |
| 1395 | |
| 1396 | if ( !is_array($qv['tag__not_in']) || empty($qv['tag__not_in']) ) { |
| 1397 | $qv['tag__not_in'] = array(); |
| 1398 | } else { |
| 1399 | $qv['tag__not_in'] = array_map('absint', $qv['tag__not_in']); |
| 1400 | } |
| 1401 | |
| 1402 | if ( !is_array($qv['tag__and']) || empty($qv['tag__and']) ) { |
| 1403 | $qv['tag__and'] = array(); |
| 1404 | } else { |
| 1405 | $qv['tag__and'] = array_map('absint', $qv['tag__and']); |
| 1406 | $this->is_category = true; |
| 1407 | } |
| 1408 | |
| 1409 | if ( !is_array($qv['tag_slug__in']) || empty($qv['tag_slug__in']) ) { |
| 1410 | $qv['tag_slug__in'] = array(); |
| 1411 | } else { |
| 1412 | $qv['tag_slug__in'] = array_map('sanitize_title', $qv['tag_slug__in']); |
| 1413 | $this->is_tag = true; |
| 1414 | } |
| 1415 | |
| 1416 | if ( !is_array($qv['tag_slug__and']) || empty($qv['tag_slug__and']) ) { |
| 1417 | $qv['tag_slug__and'] = array(); |
| 1418 | } else { |
| 1419 | $qv['tag_slug__and'] = array_map('sanitize_title', $qv['tag_slug__and']); |
| 1420 | $this->is_tag = true; |
| 1421 | } |
| 1422 | |
| 1423 | if ( empty($qv['taxonomy']) || empty($qv['term']) ) { |
| 1424 | $this->is_tax = false; |
| 1425 | foreach ( $GLOBALS['wp_taxonomies'] as $taxonomy => $t ) { |
| 1426 | if ( $t->query_var && isset($qv[$t->query_var]) && '' != $qv[$t->query_var] ) { |
| 1427 | $qv['taxonomy'] = $taxonomy; |
| 1428 | $qv['term'] = $qv[$t->query_var]; |
| 1429 | $this->is_tax = true; |
| 1430 | break; |
| 1431 | } |
| 1432 | } |
| 1433 | } else { |
| 1434 | $this->is_tax = true; |
| 1435 | } |
| 1436 | |
1463 | | /* |
1464 | | * Parses various taxonomy related query vars and sets the appropriate query flags |
1465 | | * |
1466 | | * @access protected |
1467 | | * @since 3.1.0 |
1468 | | * |
1469 | | * @param array &$q The query variables |
1470 | | * @return array tax query |
1471 | | */ |
1472 | | function parse_tax_query( &$q ) { |
1473 | | if ( ! empty( $q['tax_query'] ) && is_array( $q['tax_query'] ) ) { |
1474 | | $tax_query = $q['tax_query']; |
1475 | | } else { |
1476 | | $tax_query = array(); |
1477 | | } |
1478 | | |
1479 | | if ( !empty($q['taxonomy']) && !empty($q['term']) ) { |
1480 | | $tax_query[] = array( |
1481 | | 'taxonomy' => $q['taxonomy'], |
1482 | | 'terms' => array( $q['term'] ), |
1483 | | 'field' => 'slug', |
1484 | | 'operator' => 'IN', |
1485 | | ); |
1486 | | } |
1487 | | |
1488 | | foreach ( $GLOBALS['wp_taxonomies'] as $taxonomy => $t ) { |
1489 | | if ( $t->query_var && !empty( $q[$t->query_var] ) ) { |
1490 | | $tax_query_defaults = array( |
1491 | | 'taxonomy' => $taxonomy, |
1492 | | 'field' => 'slug', |
1493 | | 'operator' => 'IN' |
1494 | | ); |
1495 | | |
1496 | | if ( $t->rewrite['hierarchical'] ) { |
1497 | | $q[$t->query_var] = wp_basename( $q[$t->query_var] ); |
1498 | | } |
1499 | | |
1500 | | $term = str_replace( ' ', '+', $q[$t->query_var] ); |
1501 | | |
1502 | | if ( strpos($term, '+') !== false ) { |
1503 | | $terms = preg_split( '/[+]+/', $term ); |
1504 | | foreach ( $terms as $term ) { |
1505 | | $tax_query[] = array_merge( $tax_query_defaults, array( |
1506 | | 'terms' => array( $term ) |
1507 | | ) ); |
1508 | | } |
1509 | | } else { |
1510 | | $tax_query[] = array_merge( $tax_query_defaults, array( |
1511 | | 'terms' => preg_split( '/[,]+/', $term ) |
1512 | | ) ); |
1513 | | } |
1514 | | } |
1515 | | } |
1516 | | |
1517 | | // Category stuff |
1518 | | if ( !empty($q['cat']) && '0' != $q['cat'] && !$this->is_singular ) { |
1519 | | $q['cat'] = ''.urldecode($q['cat']).''; |
1520 | | $q['cat'] = addslashes_gpc($q['cat']); |
1521 | | $cat_array = preg_split('/[,\s]+/', $q['cat']); |
1522 | | $q['cat'] = ''; |
1523 | | $req_cats = array(); |
1524 | | foreach ( (array) $cat_array as $cat ) { |
1525 | | $cat = intval($cat); |
1526 | | $req_cats[] = $cat; |
1527 | | $in = ($cat > 0); |
1528 | | $cat = abs($cat); |
1529 | | if ( $in ) { |
1530 | | $q['category__in'][] = $cat; |
1531 | | } else { |
1532 | | $q['category__not_in'][] = $cat; |
1533 | | } |
1534 | | } |
1535 | | $q['cat'] = implode(',', $req_cats); |
1536 | | } |
1537 | | |
1538 | | if ( !empty($q['category__in']) ) { |
1539 | | $tax_query[] = array( |
1540 | | 'taxonomy' => 'category', |
1541 | | 'terms' => $q['category__in'], |
1542 | | 'operator' => 'IN', |
1543 | | 'field' => 'term_id' |
1544 | | ); |
1545 | | } |
1546 | | |
1547 | | if ( !empty($q['category__not_in']) ) { |
1548 | | $tax_query[] = array( |
1549 | | 'taxonomy' => 'category', |
1550 | | 'terms' => $q['category__not_in'], |
1551 | | 'operator' => 'NOT IN', |
1552 | | 'field' => 'term_id' |
1553 | | ); |
1554 | | } |
1555 | | |
1556 | | // Tag stuff |
1557 | | if ( !empty($qv['tag_id']) ) { |
1558 | | $tax_query[] = array( |
1559 | | 'taxonomy' => 'post_tag', |
1560 | | 'terms' => $qv['tag_id'], |
1561 | | 'operator' => 'IN', |
1562 | | 'field' => 'term_id' |
1563 | | ); |
1564 | | } |
1565 | | |
1566 | | if ( !empty($q['tag__in']) ) { |
1567 | | $tax_query[] = array( |
1568 | | 'taxonomy' => 'post_tag', |
1569 | | 'terms' => $q['tag__in'], |
1570 | | 'operator' => 'IN', |
1571 | | 'field' => 'term_id' |
1572 | | ); |
1573 | | } |
1574 | | |
1575 | | if ( !empty($q['tag__not_in']) ) { |
1576 | | $tax_query[] = array( |
1577 | | 'taxonomy' => 'post_tag', |
1578 | | 'terms' => $q['tag__not_in'], |
1579 | | 'operator' => 'NOT IN', |
1580 | | 'field' => 'term_id' |
1581 | | ); |
1582 | | } |
1583 | | |
1584 | | foreach ( $tax_query as $query ) { |
1585 | | if ( 'IN' == $query['operator'] ) { |
1586 | | switch ( $query['taxonomy'] ) { |
1587 | | case 'category': |
1588 | | $this->is_category = true; |
1589 | | break; |
1590 | | case 'post_tag': |
1591 | | $this->is_tag = true; |
1592 | | break; |
1593 | | default: |
1594 | | $this->is_tax = true; |
1595 | | } |
1596 | | } |
1597 | | } |
1598 | | |
1599 | | return $tax_query; |
1600 | | } |
1601 | | |
1957 | | break; |
1958 | | } |
| 1922 | // Category stuff for nice URLs |
| 1923 | if ( '' != $q['category_name'] && !$this->is_singular ) { |
| 1924 | $q['category_name'] = implode('/', array_map('sanitize_title', explode('/', $q['category_name']))); |
| 1925 | $reqcat = get_category_by_path($q['category_name']); |
| 1926 | $q['category_name'] = str_replace('%2F', '/', urlencode(urldecode($q['category_name']))); |
| 1927 | $cat_paths = '/' . trim($q['category_name'], '/'); |
| 1928 | $q['category_name'] = sanitize_title(basename($cat_paths)); |
| 1929 | |
| 1930 | $cat_paths = '/' . trim(urldecode($q['category_name']), '/'); |
| 1931 | $q['category_name'] = sanitize_title(basename($cat_paths)); |
| 1932 | $cat_paths = explode('/', $cat_paths); |
| 1933 | $cat_path = ''; |
| 1934 | foreach ( (array) $cat_paths as $pathdir ) |
| 1935 | $cat_path .= ( $pathdir != '' ? '/' : '' ) . sanitize_title($pathdir); |
| 1936 | |
| 1937 | //if we don't match the entire hierarchy fallback on just matching the nicename |
| 1938 | if ( empty($reqcat) ) |
| 1939 | $reqcat = get_category_by_path($q['category_name'], false); |
| 1940 | |
| 1941 | if ( !empty($reqcat) ) |
| 1942 | $reqcat = $reqcat->term_id; |
| 1943 | else |
| 1944 | $reqcat = 0; |
| 1945 | |
| 1946 | $q['cat'] = $reqcat; |
| 1947 | |
| 1948 | $join = " INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id) "; |
| 1949 | $whichcat = " AND $wpdb->term_taxonomy.taxonomy = 'category' "; |
| 1950 | $in_cats = array($q['cat']); |
| 1951 | $in_cats = array_merge($in_cats, get_term_children($q['cat'], 'category')); |
| 1952 | $in_cats = "'" . implode("', '", $in_cats) . "'"; |
| 1953 | $whichcat .= "AND $wpdb->term_taxonomy.term_id IN ($in_cats)"; |
| 1954 | $groupby = "{$wpdb->posts}.ID"; |
| 1955 | } |
| 1956 | |
| 1957 | // Tags |
| 1958 | if ( '' != $q['tag'] ) { |
| 1959 | if ( strpos($q['tag'], ',') !== false ) { |
| 1960 | $tags = preg_split('/[,\s]+/', $q['tag']); |
| 1961 | foreach ( (array) $tags as $tag ) { |
| 1962 | $tag = sanitize_term_field('slug', $tag, 0, 'post_tag', 'db'); |
| 1963 | $q['tag_slug__in'][] = $tag; |
| 1964 | } |
| 1965 | } else if ( preg_match('/[+\s]+/', $q['tag']) || !empty($q['cat']) ) { |
| 1966 | $tags = preg_split('/[+\s]+/', $q['tag']); |
| 1967 | foreach ( (array) $tags as $tag ) { |
| 1968 | $tag = sanitize_term_field('slug', $tag, 0, 'post_tag', 'db'); |
| 1969 | $q['tag_slug__and'][] = $tag; |
| 1970 | } |
| 1971 | } else { |
| 1972 | $q['tag'] = sanitize_term_field('slug', $q['tag'], 0, 'post_tag', 'db'); |
| 1973 | $q['tag_slug__in'][] = $q['tag']; |
| 1974 | } |
| 1975 | } |
| 1976 | |
| 1977 | if ( !empty($q['category__in']) || !empty($q['meta_key']) || !empty($q['tag__in']) || !empty($q['tag_slug__in']) ) { |
| 1978 | $groupby = "{$wpdb->posts}.ID"; |
| 1979 | } |
| 1980 | |
| 1981 | if ( !empty($q['tag__in']) && empty($q['cat']) ) { |
| 1982 | $join = " INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id) "; |
| 1983 | $whichcat .= " AND $wpdb->term_taxonomy.taxonomy = 'post_tag' "; |
| 1984 | $include_tags = "'" . implode("', '", $q['tag__in']) . "'"; |
| 1985 | $whichcat .= " AND $wpdb->term_taxonomy.term_id IN ($include_tags) "; |
| 1986 | $reqtag = term_exists( $q['tag__in'][0], 'post_tag' ); |
| 1987 | if ( !empty($reqtag) ) |
| 1988 | $q['tag_id'] = $reqtag['term_id']; |
| 1989 | } |
| 1990 | |
| 1991 | if ( !empty($q['tag_slug__in']) && empty($q['cat']) ) { |
| 1992 | $join = " INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id) INNER JOIN $wpdb->terms ON ($wpdb->term_taxonomy.term_id = $wpdb->terms.term_id) "; |
| 1993 | $whichcat .= " AND $wpdb->term_taxonomy.taxonomy = 'post_tag' "; |
| 1994 | $include_tags = "'" . implode("', '", $q['tag_slug__in']) . "'"; |
| 1995 | $whichcat .= " AND $wpdb->terms.slug IN ($include_tags) "; |
| 1996 | $reqtag = get_term_by( 'slug', $q['tag_slug__in'][0], 'post_tag' ); |
| 1997 | if ( !empty($reqtag) ) |
| 1998 | $q['tag_id'] = $reqtag->term_id; |
| 1999 | } |
| 2000 | |
| 2001 | if ( !empty($q['tag__not_in']) ) { |
| 2002 | $tag_string = "'" . implode("', '", $q['tag__not_in']) . "'"; |
| 2003 | $whichcat .= " AND $wpdb->posts.ID NOT IN ( SELECT tr.object_id FROM $wpdb->term_relationships AS tr INNER JOIN $wpdb->term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy = 'post_tag' AND tt.term_id IN ($tag_string) )"; |
| 2004 | } |
| 2005 | |
| 2006 | // Tag and slug intersections. |
| 2007 | $intersections = array('category__and' => 'category', 'tag__and' => 'post_tag', 'tag_slug__and' => 'post_tag', 'tag__in' => 'post_tag', 'tag_slug__in' => 'post_tag'); |
| 2008 | $tagin = array('tag__in', 'tag_slug__in'); // These are used to make some exceptions below |
| 2009 | foreach ( $intersections as $item => $taxonomy ) { |
| 2010 | if ( empty($q[$item]) ) continue; |
| 2011 | if ( in_array($item, $tagin) && empty($q['cat']) ) continue; // We should already have what we need if categories aren't being used |
| 2012 | |
| 2013 | if ( $item != 'category__and' ) { |
| 2014 | $reqtag = term_exists( $q[$item][0], 'post_tag' ); |
| 2015 | if ( !empty($reqtag) ) |
| 2016 | $q['tag_id'] = $reqtag['term_id']; |
| 2017 | } |
| 2018 | |
| 2019 | if ( in_array( $item, array('tag_slug__and', 'tag_slug__in' ) ) ) |
| 2020 | $taxonomy_field = 'slug'; |
| 2021 | else |
| 2022 | $taxonomy_field = 'term_id'; |
| 2023 | |
| 2024 | $q[$item] = array_unique($q[$item]); |
| 2025 | $tsql = "SELECT p.ID FROM $wpdb->posts p INNER JOIN $wpdb->term_relationships tr ON (p.ID = tr.object_id) INNER JOIN $wpdb->term_taxonomy tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id) INNER JOIN $wpdb->terms t ON (tt.term_id = t.term_id)"; |
| 2026 | $tsql .= " WHERE tt.taxonomy = '$taxonomy' AND t.$taxonomy_field IN ('" . implode("', '", $q[$item]) . "')"; |
| 2027 | if ( !in_array($item, $tagin) ) { // This next line is only helpful if we are doing an and relationship |
| 2028 | $tsql .= " GROUP BY p.ID HAVING count(p.ID) = " . count($q[$item]); |
| 2029 | } |
| 2030 | $post_ids = $wpdb->get_col($tsql); |
| 2031 | |
| 2032 | if ( count($post_ids) ) |
| 2033 | $whichcat .= " AND $wpdb->posts.ID IN (" . implode(', ', $post_ids) . ") "; |
| 2034 | else { |
| 2035 | $whichcat = " AND 0 = 1"; |
| 2036 | break; |
| 2037 | } |
| 2038 | } |
| 2039 | |
| 2040 | // Taxonomies |
| 2041 | if ( $this->is_tax ) { |
| 2042 | if ( '' != $q['taxonomy'] ) { |
| 2043 | $taxonomy = $q['taxonomy']; |
| 2044 | $tt[$taxonomy] = $q['term']; |
| 2045 | } else { |
| 2046 | foreach ( $GLOBALS['wp_taxonomies'] as $taxonomy => $t ) { |
| 2047 | if ( $t->query_var && '' != $q[$t->query_var] ) { |
| 2048 | $tt[$taxonomy] = $q[$t->query_var]; |
| 2049 | break; |