Ticket #4988: 4988.04.patch
File 4988.04.patch, 49.2 KB (added by , 9 years ago) |
---|
-
src/bp-activity/bp-activity-classes.php
275 275 * @type array $date_query An array of date_query conditions. 276 276 * See first parameter of WP_Date_Query::__construct() 277 277 * for description. 278 * @type array $filter_query An array of activity query conditions. 279 * See BP_Activity_Query::__construct() 280 * for description. 278 281 * @type array $filter See BP_Activity_Activity::get_filter_sql(). 279 282 * @type string $search_terms Limit results by a search term. 280 283 * Default: false. … … 327 330 'in' => false, // Array of ids to limit query by (IN) 328 331 'meta_query' => false, // Filter by activitymeta 329 332 'date_query' => false, // Filter by date 333 'filter_query' => false, // Advanced filtering - see BP_Activity_Query 330 334 'filter' => false, // See self::get_filter_sql() 335 'scope' => false, // Preset activity arguments 331 336 'search_terms' => false, // Terms to search by 332 337 'display_comments' => false, // Whether to include activity comments 333 338 'show_hidden' => false, // Show items marked hide_sitewide … … 350 355 // Excluded types 351 356 $excluded_types = array(); 352 357 358 // Scope takes precedence 359 if ( ! empty( $r['scope'] ) ) { 360 $scope_query = self::get_scope_query_sql( $r['scope'], $r ); 361 362 if ( ! empty( $scope_query['sql'] ) ) { 363 $where_conditions['scope_query_sql'] = $scope_query['sql']; 364 } 365 366 // override some arguments if needed 367 if ( ! empty( $scope_query['override'] ) ) { 368 $r = array_replace_recursive( $r, $scope_query['override'] ); 369 } 370 371 // Advanced filtering 372 } elseif ( ! empty( $r['filter_query'] ) ) { 373 $filter_query = new BP_Activity_Query( $r['filter_query'] ); 374 if ( $sql = $filter_query->get_sql() ) { 375 $where_conditions['filter_query_sql'] = $sql; 376 } 377 } 378 353 379 // Regular filtering 354 380 if ( $r['filter'] && $filter_sql = BP_Activity_Activity::get_filter_sql( $r['filter'] ) ) { 355 381 $where_conditions['filter_sql'] = $filter_sql; … … 520 546 } 521 547 522 548 } else { 523 524 549 // Query first for activity IDs 525 550 $activity_ids_sql = "{$select_sql} {$from_sql} {$join_sql} {$where_sql} ORDER BY a.date_recorded {$sort}"; 526 551 … … 821 846 } 822 847 823 848 /** 849 * Get the SQL for the 'scope' param in BP_Activity_Activity::get(). 850 * 851 * A scope is a predetermined set of activity arguments. This method is used 852 * to grab these activity arguments and override any existing args if needed. 853 * 854 * Can handle multple scopes. 855 * 856 * @since BuddyPress (2.2.0) 857 * 858 * @param string $scope The activity scope 859 * @param array $r Current activity arguments. Same as those of BP_Activity_Activity::get(), 860 * but merged with defaults. 861 * @return array 'sql' WHERE SQL string and 'override' activity args 862 */ 863 public static function get_scope_query_sql( $scope = '', $r = array() ) { 864 $query_args = array(); 865 $override = array(); 866 $retval = array(); 867 868 if ( ! is_array( $scope ) ) { 869 $scopes = explode( ',', $scope ); 870 } else { 871 $scopes = $scope; 872 } 873 874 if ( empty( $scopes ) ) { 875 return $sql; 876 } 877 878 // helper to easily grab the 'user_id' 879 if ( ! empty( $r['filter']['user_id'] ) ) { 880 $r['user_id'] = $r['filter']['user_id']; 881 } 882 883 // parse each scope; yes! we handle multiples! 884 foreach ( $scopes as $scope ) { 885 $scope_args = array(); 886 887 switch ( $scope ) { 888 case 'just-me' : 889 $scope_args = array( 890 'column' => 'user_id', 891 'value' => $r['user_id'] 892 ); 893 894 $scope_args['override']['display_comments'] = 'stream'; 895 896 // wipe out the user ID 897 $scope_args['override']['filter']['user_id'] = 0; 898 899 break; 900 901 case 'favorites': 902 $favs = bp_activity_get_user_favorites( $r['user_id'] ); 903 if ( empty( $favs ) ) { 904 return $scope_args; 905 } 906 907 $scope_args = array( 908 'column' => 'id', 909 'compare' => 'IN', 910 'value' => (array) $favs 911 ); 912 $scope_args['override']['display_comments'] = true; 913 914 // wipe out the user ID 915 $scope_args['override']['filter']['user_id'] = 0; 916 917 break; 918 919 case 'mentions': 920 // Are mentions disabled? 921 if ( ! bp_activity_do_mentions() ) { 922 return $scope_args; 923 } 924 925 $scope_args = array( 926 'column' => 'content', 927 'compare' => 'LIKE', 928 929 // Start search at @ symbol and stop search at closing tag delimiter. 930 'value' => '@' . bp_activity_get_user_mentionname( $r['user_id'] ) . '<' 931 ); 932 933 // wipe out current search terms if any 934 // this is so the 'mentions' scope can be combined with other scopes 935 $scope_args['override']['search_terms'] = false; 936 937 $scope_args['override']['display_comments'] = 'stream'; 938 $scope_args['override']['filter']['user_id'] = 0; 939 940 break; 941 942 default : 943 /** 944 * Plugins can hook here to set their activity arguments for custom scopes. 945 * 946 * This is a dynamic filter based on the activity scope. eg: 947 * - 'bp_activity_set_groups_scope_args' 948 * - 'bp_activity_set_friends_scope_args' 949 * 950 * To see how this filter is used, plugin devs should check out: 951 * - bp_groups_filter_activity_scope() - used for 'groups' scope 952 * - bp_friends_filter_activity_scope() - used for 'friends' scope 953 * 954 * @since BuddyPress (2.2.0) 955 * 956 * @param array { 957 * Activity query clauses. 958 * 959 * @type array { 960 * Activity arguments for your custom scope. 961 * See {@link BP_Activity_Query::_construct()} for more details. 962 * } 963 * @type array $override Optional. Override existing activity arguments passed by $r. 964 * } 965 * @param array $r Current activity arguments passed in BP_Activity_Activity::get() 966 */ 967 $scope_args = apply_filters( "bp_activity_set_{$scope}_scope_args", array(), $r ); 968 break; 969 } 970 971 if ( ! empty( $scope_args ) ) { 972 // merge override properties from other scopes 973 // this might be a problem... 974 if ( ! empty( $scope_args['override'] ) ) { 975 $override = array_merge( $override, $scope_args['override'] ); 976 unset( $scope_args['override'] ); 977 } 978 979 // save scope args 980 if ( ! empty( $scope_args ) ) { 981 $query_args[] = $scope_args; 982 } 983 } 984 } 985 986 if ( ! empty( $query_args ) ) { 987 // set relation to OR 988 $query_args['relation'] = 'OR'; 989 990 $query = new BP_Activity_Query( $query_args ); 991 if ( $sql = $query->get_sql() ) { 992 $retval['sql'] = $sql; 993 } 994 } 995 996 if ( ! empty( $override ) ) { 997 $retval['override'] = $override; 998 } 999 1000 return $retval; 1001 } 1002 1003 /** 824 1004 * In BuddyPress 1.2.x, this was used to retrieve specific activity stream items (for example, on an activity's permalink page). 825 1005 * 826 1006 * As of 1.5.x, use BP_Activity_Activity::get() with an 'in' parameter instead. … … 1501 1681 } 1502 1682 1503 1683 /** 1684 * Class for generating the WHERE SQL clause for advanced activity fetching. 1685 * 1686 * This is notably used in {@link BP_Activity_Activity::get()} with the 1687 * 'filter_query' parameter. 1688 * 1689 * @since BuddyPress (2.2.0) 1690 */ 1691 class BP_Activity_Query extends BP_Recursive_Query { 1692 /** 1693 * Array of activity queries. 1694 * 1695 * See {@see BP_Activity_Query::__construct()} for information on query arguments. 1696 * 1697 * @since BuddyPress (2.2.0) 1698 * @access public 1699 * @var array 1700 */ 1701 public $queries = array(); 1702 1703 /** 1704 * Table alias. 1705 * 1706 * @since BuddyPress (2.2.0) 1707 * @access public 1708 * @var string 1709 */ 1710 public $table_alias = ''; 1711 1712 /** 1713 * Supported DB columns. 1714 * 1715 * See the 'wp_bp_activity' DB table schema. 1716 * 1717 * @since BuddyPress (2.2.0) 1718 * @access public 1719 * @var array 1720 */ 1721 public $db_columns = array( 1722 'id', 'user_id', 'component', 'type', 'action', 'content', 1723 'item_id', 'secondary_item_id', 'hide_sitewide', 'is_spam', 1724 ); 1725 1726 /** 1727 * Constructor. 1728 * 1729 * @since BuddyPress (2.2.0) 1730 * 1731 * @param array $query { 1732 * Array of query clauses. 1733 * 1734 * @type array { 1735 * @type string $column Required. The column to query against. Basically, any DB column in the main 1736 * 'wp_bp_activity' table. 1737 * @type string $value Required. Value to filter by. 1738 * @type string $compare Optional. The comparison operator. Default '='. 1739 * Accepts '=', '!=', '>', '>=', '<', '<=', 'IN', 'NOT IN', 'LIKE', 1740 * 'NOT LIKE', BETWEEN', 'NOT BETWEEN', 'REGEXP', 'NOT REGEXP', 'RLIKE' 1741 * @type string $relation Optional. The boolean relationship between the activity queries. 1742 * Accepts 'OR', 'AND'. Default 'AND'. 1743 * @type array { 1744 * Optional. Another fully-formed activity query. See parameters above. 1745 * } 1746 * } 1747 * } 1748 */ 1749 public function __construct( $query = array() ) { 1750 if ( ! is_array( $query ) ) { 1751 return; 1752 } 1753 1754 $this->queries = $this->sanitize_query( $query ); 1755 } 1756 1757 /** 1758 * Generates WHERE SQL clause to be appended to a main query. 1759 * 1760 * @since BuddyPress (2.2.0) 1761 * @access public 1762 * 1763 * @param string $alias An existing table alias that is compatible with the current query clause. 1764 * Default: 'a'. BP_Activity_Activity::get() uses 'a', so we default to that. 1765 * @return string SQL fragment to append to the main WHERE clause. 1766 * } 1767 */ 1768 public function get_sql( $alias = 'a' ) { 1769 if ( ! empty( $alias ) ) { 1770 $this->table_alias = sanitize_title( $alias ); 1771 } 1772 1773 $sql = $this->get_sql_clauses(); 1774 1775 // we only need the 'where' clause 1776 // 1777 // also trim trailing "AND" clause from parent BP_Recursive_Query class 1778 // since it's not necessary for our needs 1779 return preg_replace( '/^\sAND/', '', $sql['where'] ); 1780 } 1781 1782 /** 1783 * Generate WHERE clauses for a first-order clause. 1784 * 1785 * @since BuddyPress (2.2.0) 1786 * @access protected 1787 * 1788 * @param array $clause Array of arguments belonging to the clause. 1789 * @param array $parent_query Parent query to which the clause belongs. 1790 * @return array { 1791 * @type array $where Array of subclauses for the WHERE statement. 1792 * @type array $join Empty array. Not used. 1793 * } 1794 */ 1795 protected function get_sql_for_clause( $clause, $parent_query ) { 1796 global $wpdb; 1797 1798 $sql_chunks = array( 1799 'where' => array(), 1800 'join' => array(), 1801 ); 1802 1803 $column = isset( $clause['column'] ) ? $this->validate_column( $clause['column'] ) : ''; 1804 $value = isset( $clause['value'] ) ? $clause['value'] : ''; 1805 if ( empty( $column ) || ! isset( $clause['value'] ) ) { 1806 return $sql_chunks; 1807 } 1808 1809 if ( isset( $clause['compare'] ) ) { 1810 $clause['compare'] = strtoupper( $clause['compare'] ); 1811 } else { 1812 $clause['compare'] = isset( $clause['value'] ) && is_array( $clause['value'] ) ? 'IN' : '='; 1813 } 1814 1815 // default 'compare' to '=' if no valid operator is found 1816 if ( ! in_array( $clause['compare'], array( 1817 '=', '!=', '>', '>=', '<', '<=', 1818 'LIKE', 'NOT LIKE', 1819 'IN', 'NOT IN', 1820 'BETWEEN', 'NOT BETWEEN', 1821 'REGEXP', 'NOT REGEXP', 'RLIKE' 1822 ) ) ) { 1823 $clause['compare'] = '='; 1824 } 1825 1826 $compare = $clause['compare']; 1827 1828 $alias = ! empty( $this->table_alias ) ? "{$this->table_alias}." : ''; 1829 1830 // Next, Build the WHERE clause. 1831 $where = ''; 1832 1833 // value. 1834 if ( isset( $clause['value'] ) ) { 1835 if ( in_array( $compare, array( 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN' ) ) ) { 1836 if ( ! is_array( $value ) ) { 1837 $value = preg_split( '/[,\s]+/', $value ); 1838 } 1839 } 1840 1841 // tinyint 1842 if ( ! empty( $column ) && true === in_array( $column, array( 'hide_sitewide', 'is_spam' ) ) ) { 1843 $sql_chunks['where'][] = $wpdb->prepare( "{$alias}{$column} = %d", $value ); 1844 1845 } else { 1846 switch ( $compare ) { 1847 // IN uses different syntax 1848 case 'IN' : 1849 case 'NOT IN' : 1850 $in_sql = BP_Activity_Activity::get_in_operator_sql( "{$alias}{$column}", $value ); 1851 1852 // 'NOT IN' operator is as easy as a string replace! 1853 if ( 'NOT IN' === $compare ) { 1854 $in_sql = str_replace( 'IN', 'NOT IN', $in_sql ); 1855 } 1856 1857 $sql_chunks['where'][] = $in_sql; 1858 break; 1859 1860 case 'BETWEEN' : 1861 case 'NOT BETWEEN' : 1862 $value = array_slice( $value, 0, 2 ); 1863 $where = $wpdb->prepare( '%s AND %s', $value ); 1864 break; 1865 1866 case 'LIKE' : 1867 case 'NOT LIKE' : 1868 $value = '%' . bp_esc_like( $value ) . '%'; 1869 $where = $wpdb->prepare( '%s', $value ); 1870 break; 1871 1872 default : 1873 $where = $wpdb->prepare( '%s', $value ); 1874 break; 1875 1876 } 1877 } 1878 1879 if ( $where ) { 1880 $sql_chunks['where'][] = "{$alias}{$column} {$compare} {$where}"; 1881 } 1882 } 1883 1884 /* 1885 * Multiple WHERE clauses should be joined in parentheses. 1886 */ 1887 if ( 1 < count( $sql_chunks['where'] ) ) { 1888 $sql_chunks['where'] = array( '( ' . implode( ' AND ', $sql_chunks['where'] ) . ' )' ); 1889 } 1890 1891 return $sql_chunks; 1892 } 1893 1894 /** 1895 * Determine whether a clause is first-order. 1896 * 1897 * @since BuddyPress (2.2.0) 1898 * @access protected 1899 * 1900 * @param array $q Clause to check. 1901 * @return bool 1902 */ 1903 protected function is_first_order_clause( $query ) { 1904 return isset( $query['column'] ) || isset( $query['value'] ); 1905 } 1906 1907 /** 1908 * Validates a column name parameter. 1909 * 1910 * Column names are checked against a whitelist of known tables. 1911 * See {@link BP_Activity_Query::db_tables}. 1912 * 1913 * @since BuddyPress (2.2.0) 1914 * @access public 1915 * 1916 * @param string $column The user-supplied column name. 1917 * @return string A validated column name value. 1918 */ 1919 public function validate_column( $column = '' ) { 1920 if ( in_array( $column, $this->db_columns ) ) { 1921 return $column; 1922 } else { 1923 return ''; 1924 } 1925 } 1926 } 1927 1928 /** 1504 1929 * Create a RSS feed using the activity component. 1505 1930 * 1506 1931 * You should only construct a new feed when you've validated that you're on -
src/bp-activity/bp-activity-functions.php
1417 1417 'search_terms' => false, // Pass search terms as a string 1418 1418 'meta_query' => false, // Filter by activity meta. See WP_Meta_Query for format 1419 1419 'date_query' => false, // Filter by date. See first parameter of WP_Date_Query for format 1420 'filter_query' => false, 1420 1421 'show_hidden' => false, // Show activity items that are hidden site-wide? 1421 1422 'exclude' => false, // Comma-separated list of activity IDs to exclude 1422 1423 'in' => false, // Comma-separated list or array of activity IDs to which you want to limit the query 1423 1424 'spam' => 'ham_only', // 'ham_only' (default), 'spam_only' or 'all'. 1424 1425 'update_meta_cache' => true, 1425 1426 'count_total' => false, 1427 'scope' => false, 1426 1428 1427 1429 /** 1428 1430 * Pass filters as an array -- all filter items can be multiple values comma separated: … … 1438 1440 ) ); 1439 1441 1440 1442 // Attempt to return a cached copy of the first page of sitewide activity. 1441 if ( ( 1 === (int) $r['page'] ) && empty( $r['max'] ) && empty( $r['search_terms'] ) && empty( $r['meta_query'] ) && empty( $r['date_query'] ) && empty( $r['filter '] ) && empty( $r['exclude'] ) && empty( $r['in'] ) && ( 'DESC' === $r['sort'] ) && empty( $r['exclude'] ) && ( 'ham_only' === $r['spam'] ) ) {1443 if ( ( 1 === (int) $r['page'] ) && empty( $r['max'] ) && empty( $r['search_terms'] ) && empty( $r['meta_query'] ) && empty( $r['date_query'] ) && empty( $r['filter_query'] ) && empty( $r['filter'] ) && empty( $r['scope'] ) && empty( $r['exclude'] ) && empty( $r['in'] ) && ( 'DESC' === $r['sort'] ) && empty( $r['exclude'] ) && ( 'ham_only' === $r['spam'] ) ) { 1442 1444 1443 1445 $activity = wp_cache_get( 'bp_activity_sitewide_front', 'bp' ); 1444 1446 if ( false === $activity ) { … … 1451 1453 'search_terms' => $r['search_terms'], 1452 1454 'meta_query' => $r['meta_query'], 1453 1455 'date_query' => $r['date_query'], 1456 'filter_query' => $r['filter_query'], 1454 1457 'filter' => $r['filter'], 1458 'scope' => $r['scope'], 1455 1459 'display_comments' => $r['display_comments'], 1456 1460 'show_hidden' => $r['show_hidden'], 1457 1461 'spam' => $r['spam'], … … 1471 1475 'search_terms' => $r['search_terms'], 1472 1476 'meta_query' => $r['meta_query'], 1473 1477 'date_query' => $r['date_query'], 1478 'filter_query' => $r['filter_query'], 1474 1479 'filter' => $r['filter'], 1480 'scope' => $r['scope'], 1475 1481 'display_comments' => $r['display_comments'], 1476 1482 'show_hidden' => $r['show_hidden'], 1477 1483 'exclude' => $r['exclude'], -
src/bp-activity/bp-activity-template.php
201 201 'exclude' => false, 202 202 'in' => false, 203 203 'filter' => false, 204 'scope' => false, 204 205 'search_terms' => false, 205 206 'meta_query' => false, 206 207 'date_query' => false, 208 'filter_query' => false, 207 209 'display_comments' => 'threaded', 208 210 'show_hidden' => false, 209 211 'spam' => 'ham_only', … … 249 251 'search_terms' => $search_terms, 250 252 'meta_query' => $meta_query, 251 253 'date_query' => $date_query, 254 'filter_query' => $filter_query, 252 255 'filter' => $filter, 256 'scope' => $scope, 253 257 'show_hidden' => $show_hidden, 254 258 'exclude' => $exclude, 255 259 'in' => $in, … … 611 615 612 616 'meta_query' => false, // filter on activity meta. See WP_Meta_Query for format 613 617 'date_query' => false, // filter by date. See first parameter of WP_Date_Query for format 618 'filter_query' => false, // advanced filtering. See BP_Activity_Query for format 614 619 615 620 // Searching 616 621 'search_terms' => false, // specify terms to search on … … 632 637 $page = 0; 633 638 } 634 639 635 if ( empty( $search_terms ) && ! empty( $_REQUEST['s'] ) ) 640 // Search terms 641 if ( empty( $search_terms ) && ! empty( $_REQUEST['s'] ) ) { 636 642 $search_terms = $_REQUEST['s']; 643 } 637 644 638 // If you have passed a "scope" then this will override any filters you have passed. 639 if ( 'just-me' == $scope || 'friends' == $scope || 'groups' == $scope || 'favorites' == $scope || 'mentions' == $scope ) { 640 if ( 'just-me' == $scope ) 641 $display_comments = 'stream'; 642 643 // determine which user_id applies 644 if ( empty( $user_id ) ) 645 // Set some default arguments when using a scope 646 if ( ! empty( $scope ) ) { 647 // Determine which user ID applies 648 if ( empty( $user_id ) ) { 645 649 $user_id = bp_displayed_user_id() ? bp_displayed_user_id() : bp_loggedin_user_id(); 650 } 646 651 647 // are we displaying user specific activity? 648 if ( is_numeric( $user_id ) ) { 649 $show_hidden = ( $user_id == bp_loggedin_user_id() && $scope != 'friends' ) ? 1 : 0; 650 651 switch ( $scope ) { 652 case 'friends': 653 if ( bp_is_active( 'friends' ) ) 654 $friends = friends_get_friend_user_ids( $user_id ); 655 if ( empty( $friends ) ) 656 return false; 657 658 $user_id = implode( ',', (array) $friends ); 659 break; 660 case 'groups': 661 if ( bp_is_active( 'groups' ) ) { 662 $groups = groups_get_user_groups( $user_id ); 663 if ( empty( $groups['groups'] ) ) 664 return false; 665 666 $object = $bp->groups->id; 667 $primary_id = implode( ',', (array) $groups['groups'] ); 668 669 $user_id = 0; 670 } 671 break; 672 case 'favorites': 673 $favs = bp_activity_get_user_favorites( $user_id ); 674 if ( empty( $favs ) ) 675 return false; 676 677 $in = implode( ',', (array) $favs ); 678 $display_comments = true; 679 $user_id = 0; 680 break; 681 case 'mentions': 682 683 // Are mentions disabled? 684 if ( ! bp_activity_do_mentions() ) { 685 return false; 686 } 687 688 // Start search at @ symbol and stop search at closing tag delimiter. 689 $search_terms = '@' . bp_activity_get_user_mentionname( $user_id ) . '<'; 690 $display_comments = 'stream'; 691 $user_id = 0; 692 break; 693 } 652 // Should we show all items regardless of sitewide visibility? 653 if ( ! empty( $user_id ) ) { 654 $show_hidden = ( $user_id == bp_loggedin_user_id() ) ? 1 : 0; 694 655 } 695 656 } 696 657 697 658 // Do not exceed the maximum per page 698 if ( ! empty( $max ) && ( (int) $per_page > (int) $max ) )659 if ( ! empty( $max ) && ( (int) $per_page > (int) $max ) ) { 699 660 $per_page = $max; 661 } 700 662 701 663 /** 702 664 * Filters whether BuddyPress should enable afilter support. … … 709 671 * 710 672 * @param bool $value True if BuddyPress should enable afilter support. 711 673 */ 712 if ( isset( $_GET['afilter'] ) && apply_filters( 'bp_activity_enable_afilter_support', false ) ) 674 if ( isset( $_GET['afilter'] ) && apply_filters( 'bp_activity_enable_afilter_support', false ) ) { 713 675 $filter = array( 'object' => $_GET['afilter'] ); 714 else if ( ! empty( $user_id ) || ! empty( $object ) || ! empty( $action ) || ! empty( $primary_id ) || ! empty( $secondary_id ) || ! empty( $offset ) || ! empty( $since ) )676 } else if ( ! empty( $user_id ) || ! empty( $object ) || ! empty( $action ) || ! empty( $primary_id ) || ! empty( $secondary_id ) || ! empty( $offset ) || ! empty( $since ) ) { 715 677 $filter = array( 'user_id' => $user_id, 'object' => $object, 'action' => $action, 'primary_id' => $primary_id, 'secondary_id' => $secondary_id, 'offset' => $offset, 'since' => $since ); 716 else678 } else { 717 679 $filter = false; 680 } 718 681 719 682 // If specific activity items have been requested, override the $hide_spam argument. This prevents backpat errors with AJAX. 720 if ( ! empty( $include ) && ( 'ham_only' == $spam ) )683 if ( ! empty( $include ) && ( 'ham_only' == $spam ) ) { 721 684 $spam = 'all'; 685 } 722 686 723 687 $template_args = array( 724 688 'page' => $page, … … 731 695 'exclude' => $exclude, 732 696 'in' => $in, 733 697 'filter' => $filter, 698 'scope' => $scope, 734 699 'search_terms' => $search_terms, 735 700 'meta_query' => $meta_query, 736 701 'date_query' => $date_query, 702 'filter_query' => $filter_query, 737 703 'display_comments' => $display_comments, 738 704 'show_hidden' => $show_hidden, 739 705 'spam' => $spam, -
src/bp-core/bp-core-classes.php
2754 2754 return apply_filters( 'bp_members_suggestions_get_suggestions', $results, $this ); 2755 2755 } 2756 2756 } 2757 2758 /** 2759 * Base class for creating query classes that generate SQL fragments for filtering results based on recursive query params. 2760 * 2761 * @since BuddyPress (2.2.0) 2762 */ 2763 abstract class BP_Recursive_Query { 2764 2765 /** 2766 * Query arguments passed to the constructor. 2767 * 2768 * @since BuddyPress (2.2.0) 2769 * @access public 2770 * @var array 2771 */ 2772 public $queries = array(); 2773 2774 /** 2775 * Generate SQL clauses to be appended to a main query. 2776 * 2777 * Extending classes should call this method from within a publicly 2778 * accessible get_sql() method, and manipulate the SQL as necessary. 2779 * For example, {@link BP_XProfile_Query::get_sql()} is merely a wrapper for 2780 * get_sql_clauses(), while {@link BP_Activity_Query::get_sql()} discards 2781 * the empty 'join' clauses are discarded, and passes the 'where' 2782 * clause through apply_filters(). 2783 * 2784 * @since BuddyPress (2.2.0) 2785 * @access protected 2786 * 2787 * @param string $primary_table 2788 * @param string $primary_id_column 2789 * @return array 2790 */ 2791 protected function get_sql_clauses() { 2792 $sql = $this->get_sql_for_query( $this->queries ); 2793 2794 if ( ! empty( $sql['where'] ) ) { 2795 $sql['where'] = ' AND ' . "\n" . $sql['where'] . "\n"; 2796 } 2797 2798 return $sql; 2799 } 2800 2801 /** 2802 * Generate SQL clauses for a single query array. 2803 * 2804 * If nested subqueries are found, this method recurses the tree to 2805 * produce the properly nested SQL. 2806 * 2807 * Subclasses generally do not need to call this method. It is invoked 2808 * automatically from get_sql_clauses(). 2809 * 2810 * @since BuddyPress (2.2.0) 2811 * @access protected 2812 * 2813 * @param array $query Query to parse. 2814 * @param int $depth Optional. Number of tree levels deep we 2815 * currently are. Used to calculate indentation. 2816 * @return array 2817 */ 2818 protected function get_sql_for_query( $query, $depth = 0 ) { 2819 $sql_chunks = array( 2820 'join' => array(), 2821 'where' => array(), 2822 ); 2823 2824 $sql = array( 2825 'join' => '', 2826 'where' => '', 2827 ); 2828 2829 $indent = ''; 2830 for ( $i = 0; $i < $depth; $i++ ) { 2831 $indent .= "\t"; 2832 } 2833 2834 foreach ( $query as $key => $clause ) { 2835 if ( 'relation' === $key ) { 2836 $relation = $query['relation']; 2837 } else if ( is_array( $clause ) ) { 2838 // This is a first-order clause 2839 if ( $this->is_first_order_clause( $clause ) ) { 2840 $clause_sql = $this->get_sql_for_clause( $clause, $query ); 2841 2842 $where_count = count( $clause_sql['where'] ); 2843 if ( ! $where_count ) { 2844 $sql_chunks['where'][] = ''; 2845 } else if ( 1 === $where_count ) { 2846 $sql_chunks['where'][] = $clause_sql['where'][0]; 2847 } else { 2848 $sql_chunks['where'][] = '( ' . implode( ' AND ', $clause_sql['where'] ) . ' )'; 2849 } 2850 2851 $sql_chunks['join'] = array_merge( $sql_chunks['join'], $clause_sql['join'] ); 2852 // This is a subquery 2853 } else { 2854 $clause_sql = $this->get_sql_for_query( $clause, $depth + 1 ); 2855 2856 $sql_chunks['where'][] = $clause_sql['where']; 2857 $sql_chunks['join'][] = $clause_sql['join']; 2858 2859 } 2860 } 2861 } 2862 2863 // Filter empties 2864 $sql_chunks['join'] = array_filter( $sql_chunks['join'] ); 2865 $sql_chunks['where'] = array_filter( $sql_chunks['where'] ); 2866 2867 if ( empty( $relation ) ) { 2868 $relation = 'AND'; 2869 } 2870 2871 if ( ! empty( $sql_chunks['join'] ) ) { 2872 $sql['join'] = implode( ' ', array_unique( $sql_chunks['join'] ) ); 2873 } 2874 2875 if ( ! empty( $sql_chunks['where'] ) ) { 2876 $sql['where'] = '( ' . "\n\t" . $indent . implode( ' ' . "\n\t" . $indent . $relation . ' ' . "\n\t" . $indent, $sql_chunks['where'] ) . "\n" . $indent . ')' . "\n"; 2877 } 2878 2879 return $sql; 2880 } 2881 2882 /** 2883 * Recursive-friendly query sanitizer. 2884 * 2885 * Ensures that each query-level clause has a 'relation' key, and that 2886 * each first-order clause contains all the necessary keys from 2887 * $defaults. 2888 * 2889 * Extend this method if your class uses different sanitizing logic. 2890 * 2891 * @since BuddyPress (2.2.0) 2892 * @access public 2893 * 2894 * @param array $queries Array of query clauses. 2895 * @return array Sanitized array of query clauses. 2896 */ 2897 protected function sanitize_query( $queries ) { 2898 $clean_queries = array(); 2899 2900 if ( ! is_array( $queries ) ) { 2901 return $clean_queries; 2902 } 2903 2904 foreach ( $queries as $key => $query ) { 2905 if ( 'relation' === $key ) { 2906 $relation = $query; 2907 2908 } else if ( ! is_array( $query ) ) { 2909 continue; 2910 2911 // First-order clause. 2912 } else if ( $this->is_first_order_clause( $query ) ) { 2913 if ( isset( $query['value'] ) && array() === $query['value'] ) { 2914 unset( $query['value'] ); 2915 } 2916 2917 $clean_queries[] = $query; 2918 2919 // Otherwise, it's a nested query, so we recurse. 2920 } else { 2921 $cleaned_query = $this->sanitize_query( $query ); 2922 2923 if ( ! empty( $cleaned_query ) ) { 2924 $clean_queries[] = $cleaned_query; 2925 } 2926 } 2927 } 2928 2929 if ( empty( $clean_queries ) ) { 2930 return $clean_queries; 2931 } 2932 2933 // Sanitize the 'relation' key provided in the query. 2934 if ( isset( $relation ) && 'OR' === strtoupper( $relation ) ) { 2935 $clean_queries['relation'] = 'OR'; 2936 2937 /* 2938 * If there is only a single clause, call the relation 'OR'. 2939 * This value will not actually be used to join clauses, but it 2940 * simplifies the logic around combining key-only queries. 2941 */ 2942 } else if ( 1 === count( $clean_queries ) ) { 2943 $clean_queries['relation'] = 'OR'; 2944 2945 // Default to AND. 2946 } else { 2947 $clean_queries['relation'] = 'AND'; 2948 } 2949 2950 return $clean_queries; 2951 } 2952 2953 /** 2954 * Generate JOIN and WHERE clauses for a first-order clause. 2955 * 2956 * Must be overridden in a subclass. 2957 * 2958 * @since BuddyPress (2.2.0) 2959 * @access protected 2960 * 2961 * @param array $clause Array of arguments belonging to the clause. 2962 * @param array $parent_query Parent query to which the clause belongs. 2963 * @return array { 2964 * @type array $join Array of subclauses for the JOIN statement. 2965 * @type array $where Array of subclauses for the WHERE statement. 2966 * } 2967 */ 2968 abstract protected function get_sql_for_clause( $clause, $parent_query ); 2969 2970 /** 2971 * Determine whether a clause is first-order. 2972 * 2973 * Must be overridden in a subclass. 2974 * 2975 * @since BuddyPress (2.2.0) 2976 * @access protected 2977 * 2978 * @param array $q Clause to check. 2979 * @return bool 2980 */ 2981 abstract protected function is_first_order_clause( $query ); 2982 } 2983 No newline at end of file -
src/bp-friends/bp-friends-activity.php
228 228 add_filter( 'bp_activity_prefetch_object_data', 'bp_friends_prefetch_activity_object_data' ); 229 229 230 230 /** 231 * Set up activity arguments for use with the 'friends' scope. 232 * 233 * For details on the syntax, see {@link BP_Activity_Query}. 234 * 235 * @since BuddyPress (2.2.0) 236 * 237 * @param array $retval Empty array by default 238 * @param array $filter Current activity arguments 239 * @return array 240 */ 241 function bp_friends_filter_activity_scope( $retval, $filter ) { 242 $friends = friends_get_friend_user_ids( $filter['user_id'] ); 243 244 if ( empty( $friends ) ) { 245 return $retval; 246 } 247 248 $retval= array( 249 'relation' => 'AND', 250 array( 251 'column' => 'user_id', 252 'compare' => 'IN', 253 'value' => (array) $friends 254 ), 255 // we should only be able to view sitewide activity content for friends 256 array( 257 'column' => 'hide_sitewide', 258 'value' => 0 259 ), 260 ); 261 262 // wipe out the user ID 263 $retval['override']['filter']['user_id'] = 0; 264 265 // make sure we aren't limiting items by 'hide_sitewide' since we're already 266 // limiting it above 267 $scope_args['override']['show_hidden'] = true; 268 269 return $retval; 270 } 271 add_filter( 'bp_activity_set_friends_scope_args', 'bp_friends_filter_activity_scope', 10, 2 ); 272 273 /** 231 274 * Add activity stream items when one members accepts another members request 232 275 * for virtual friendship. 233 276 * -
src/bp-groups/bp-groups-activity.php
234 234 add_filter( 'bp_activity_prefetch_object_data', 'bp_groups_prefetch_activity_object_data' ); 235 235 236 236 /** 237 * Set up activity arguments for use with the 'groups' scope. 238 * 239 * @since BuddyPress (2.2.0) 240 * 241 * @param array $retval Empty array by default 242 * @param array $filter Current activity arguments 243 * @return array 244 */ 245 function bp_groups_filter_activity_scope( $retval, $filter ) { 246 $groups = groups_get_user_groups( $filter['user_id'] ); 247 248 if ( empty( $groups['groups'] ) ) { 249 return $retval; 250 } 251 252 $retval= array( 253 'relation' => 'AND', 254 array( 255 'column' => 'component', 256 'value' => buddypress()->groups->id 257 ), 258 array( 259 'column' => 'item_id', 260 'compare' => 'IN', 261 'value' => (array) $groups['groups'] 262 ), 263 ); 264 265 // wipe out the user ID 266 $retval['override']['filter']['user_id'] = 0; 267 268 return $retval; 269 } 270 add_filter( 'bp_activity_set_groups_scope_args', 'bp_groups_filter_activity_scope', 10, 2 ); 271 272 /** 237 273 * Record an activity item related to the Groups component. 238 274 * 239 275 * A wrapper for {@link bp_activity_add()} that provides some Groups-specific -
tests/phpunit/testcases/activity/template.php
89 89 * limiting query to user favorites 90 90 * 91 91 * @ticket BP4872 92 * @group scope 92 93 */ 93 94 public function test_bp_has_activities_favorites_action_filter() { 94 95 $user_id = $this->factory->user->create( array( 'role' => 'subscriber' ) ); … … 143 144 } 144 145 145 146 /** 147 * @group scope 148 * @group filter_query 149 * @group BP_Activity_Query 150 */ 151 function test_bp_has_activities_mentions_scope() { 152 $u1 = $this->factory->user->create(); 153 $u2 = $this->factory->user->create(); 154 155 $now = time(); 156 157 // mentioned activity item 158 $mention_username = '@' . bp_activity_get_user_mentionname( $u1 ); 159 $a1 = $this->factory->activity->create( array( 160 'user_id' => $u2, 161 'type' => 'activity_update', 162 'content' => "{$mention_username} - You rule, dude!", 163 'recorded_time' => date( 'Y-m-d H:i:s', $now ), 164 ) ); 165 166 // misc activity items 167 $this->factory->activity->create( array( 168 'user_id' => $u1, 169 'component' => 'blogs', 170 'item_id' => 1, 171 'type' => 'new_blog_post', 172 'recorded_time' => date( 'Y-m-d H:i:s', $now - 100 ), 173 ) ); 174 $this->factory->activity->create( array( 175 'user_id' => $u2, 176 'component' => 'activity', 177 'type' => 'activity_update', 178 'recorded_time' => date( 'Y-m-d H:i:s', $now - 100 ), 179 ) ); 180 $this->factory->activity->create( array( 181 'user_id' => $u2, 182 'component' => 'groups', 183 'item_id' => 324, 184 'type' => 'activity_update', 185 'recorded_time' => date( 'Y-m-d H:i:s', $now - 100 ), 186 ) ); 187 188 global $activities_template; 189 190 // grab activities from multiple scopes 191 bp_has_activities( array( 192 'user_id' => $u1, 193 'scope' => 'mentions', 194 ) ); 195 196 // assert! 197 $this->assertEqualSets( array( $a1 ), wp_list_pluck( $activities_template->activities, 'id' ) ); 198 199 // clean up! 200 $activities_template = null; 201 } 202 203 /** 204 * @group scope 205 * @group filter_query 206 * @group BP_Activity_Query 207 */ 208 function test_bp_has_activities_friends_and_mentions_scope() { 209 $u1 = $this->factory->user->create(); 210 $u2 = $this->factory->user->create(); 211 $u3 = $this->factory->user->create(); 212 213 // user 1 becomes friends with user 2 214 friends_add_friend( $u1, $u2, true ); 215 216 $now = time(); 217 218 // friend status update 219 $a1 = $this->factory->activity->create( array( 220 'user_id' => $u2, 221 'type' => 'activity_update', 222 'recorded_time' => date( 'Y-m-d H:i:s', $now ), 223 ) ); 224 225 // mentioned item by non-friend 226 $mention_username = '@' . bp_activity_get_user_mentionname( $u1 ); 227 $a2 = $this->factory->activity->create( array( 228 'user_id' => $u3, 229 'component' => 'activity', 230 'type' => 'activity_update', 231 'content' => "{$mention_username} - Oy!", 232 'recorded_time' => date( 'Y-m-d H:i:s', $now - 100 ), 233 ) ); 234 235 // misc activity items 236 $this->factory->activity->create( array( 237 'user_id' => $u1, 238 'component' => 'blogs', 239 'item_id' => 1, 240 'type' => 'new_blog_post', 241 'recorded_time' => date( 'Y-m-d H:i:s', $now - 100 ), 242 ) ); 243 $this->factory->activity->create( array( 244 'user_id' => $u3, 245 'component' => 'activity', 246 'type' => 'activity_update', 247 'recorded_time' => date( 'Y-m-d H:i:s', $now - 100 ), 248 ) ); 249 $this->factory->activity->create( array( 250 'user_id' => $u3, 251 'component' => 'groups', 252 'item_id' => 324, 253 'type' => 'activity_update', 254 'recorded_time' => date( 'Y-m-d H:i:s', $now - 100 ), 255 ) ); 256 257 global $activities_template; 258 259 // grab activities from multiple scopes 260 bp_has_activities( array( 261 'user_id' => $u1, 262 'scope' => 'mentions,friends', 263 ) ); 264 265 // assert! 266 $this->assertEqualSets( array( $a1, $a2 ), wp_list_pluck( $activities_template->activities, 'id' ) ); 267 268 // clean up! 269 $activities_template = null; 270 } 271 272 /** 273 * @group scope 274 * @group filter_query 275 * @group BP_Activity_Query 276 */ 277 function test_bp_has_activities_groups_and_friends_scope() { 278 $u1 = $this->factory->user->create(); 279 $u2 = $this->factory->user->create(); 280 $u3 = $this->factory->user->create(); 281 282 // user 1 becomes friends with user 2 283 friends_add_friend( $u1, $u2, true ); 284 285 // user 1 joins a group 286 $g1 = $this->factory->group->create( array( 'creator_id' => $u1 ) ); 287 $g2 = $this->factory->group->create( array( 'creator_id' => $u1 ) ); 288 289 $now = time(); 290 291 // friend status update 292 $a1 = $this->factory->activity->create( array( 293 'user_id' => $u2, 294 'type' => 'activity_update', 295 'recorded_time' => date( 'Y-m-d H:i:s', $now ), 296 ) ); 297 298 // group activity 299 $a2 = $this->factory->activity->create( array( 300 'user_id' => $u3, 301 'component' => 'groups', 302 'item_id' => $g1, 303 'type' => 'joined_group', 304 'recorded_time' => date( 'Y-m-d H:i:s', $now - 100 ), 305 ) ); 306 307 // misc activity items 308 $this->factory->activity->create( array( 309 'user_id' => $u3, 310 'component' => 'blogs', 311 'item_id' => 1, 312 'type' => 'new_blog_post', 313 'recorded_time' => date( 'Y-m-d H:i:s', $now - 100 ), 314 ) ); 315 $this->factory->activity->create( array( 316 'user_id' => $u3, 317 'component' => 'activity', 318 'type' => 'activity_update', 319 'recorded_time' => date( 'Y-m-d H:i:s', $now - 100 ), 320 ) ); 321 $this->factory->activity->create( array( 322 'user_id' => $u3, 323 'component' => 'groups', 324 'item_id' => 324, 325 'type' => 'activity_update', 326 'recorded_time' => date( 'Y-m-d H:i:s', $now - 100 ), 327 ) ); 328 329 global $activities_template; 330 331 // grab activities from multiple scopes 332 bp_has_activities( array( 333 'user_id' => $u1, 334 'scope' => 'groups,friends', 335 ) ); 336 337 // assert! 338 $this->assertEqualSets( array( $a1, $a2 ), wp_list_pluck( $activities_template->activities, 'id' ) ); 339 340 // clean up! 341 $activities_template = null; 342 } 343 344 /** 345 * @group filter_query 346 * @group BP_Activity_Query 347 */ 348 function test_bp_has_activities_with_filter_query_nested_conditions() { 349 $u1 = $this->factory->user->create(); 350 $u2 = $this->factory->user->create(); 351 $u3 = $this->factory->user->create(); 352 353 $now = time(); 354 355 $a1 = $this->factory->activity->create( array( 356 'user_id' => $u3, 357 'component' => 'blogs', 358 'item_id' => 1, 359 'type' => 'new_blog_post', 360 'recorded_time' => date( 'Y-m-d H:i:s', $now - 100 ), 361 ) ); 362 $a2 = $this->factory->activity->create( array( 363 'user_id' => $u2, 364 'component' => 'activity', 365 'type' => 'activity_update', 366 'recorded_time' => date( 'Y-m-d H:i:s', $now - 100 ), 367 ) ); 368 369 // misc activity items 370 $this->factory->activity->create( array( 371 'user_id' => $u3, 372 'component' => 'activity', 373 'type' => 'activity_update', 374 'recorded_time' => date( 'Y-m-d H:i:s', $now - 100 ), 375 ) ); 376 $this->factory->activity->create( array( 377 'user_id' => $u3, 378 'component' => 'groups', 379 'item_id' => 324, 380 'type' => 'activity_update', 381 'recorded_time' => date( 'Y-m-d H:i:s', $now - 100 ), 382 ) ); 383 384 global $activities_template; 385 386 bp_has_activities( array( 387 'filter_query' => array( 388 'relation' => 'OR', 389 array( 390 'column' => 'component', 391 'value' => 'blogs', 392 ), 393 array( 394 'relation' => 'AND', 395 array( 396 'column' => 'type', 397 'value' => 'activity_update', 398 ), 399 array( 400 'column' => 'user_id', 401 'value' => $u2, 402 ), 403 ), 404 ) 405 ) ); 406 407 // assert! 408 $this->assertEqualSets( array( $a1, $a2 ), wp_list_pluck( $activities_template->activities, 'id' ) ); 409 410 // clean up! 411 $activities_template = null; 412 } 413 414 /** 415 * @group filter_query 416 * @group BP_Activity_Query 417 */ 418 function test_bp_has_activities_with_filter_query_compare_not_in_operator() { 419 $u1 = $this->factory->user->create(); 420 $u2 = $this->factory->user->create(); 421 $u3 = $this->factory->user->create(); 422 423 $now = time(); 424 425 // misc activity items 426 $a1 = $this->factory->activity->create( array( 427 'user_id' => $u3, 428 'component' => 'blogs', 429 'item_id' => 1, 430 'type' => 'new_blog_post', 431 'recorded_time' => date( 'Y-m-d H:i:s', $now - 100 ), 432 ) ); 433 $a2 = $this->factory->activity->create( array( 434 'user_id' => $u2, 435 'component' => 'activity', 436 'type' => 'activity_update', 437 'recorded_time' => date( 'Y-m-d H:i:s', $now - 100 ), 438 ) ); 439 $a3 = $this->factory->activity->create( array( 440 'user_id' => $u3, 441 'component' => 'activity', 442 'type' => 'activity_update', 443 'recorded_time' => date( 'Y-m-d H:i:s', $now - 100 ), 444 ) ); 445 $a4 = $this->factory->activity->create( array( 446 'user_id' => $u3, 447 'component' => 'groups', 448 'item_id' => 324, 449 'type' => 'activity_update', 450 'recorded_time' => date( 'Y-m-d H:i:s', $now - 100 ), 451 ) ); 452 453 global $activities_template; 454 455 bp_has_activities( array( 456 'filter_query' => array( 457 array( 458 'column' => 'id', 459 'compare' => 'NOT IN', 460 'value' => array( $a1, $a4 ), 461 ), 462 ) 463 ) ); 464 465 // assert! 466 $this->assertEqualSets( array( $a2, $a3 ), wp_list_pluck( $activities_template->activities, 'id' ) ); 467 468 // clean up! 469 $activities_template = null; 470 } 471 472 /** 473 * @group filter_query 474 * @group BP_Activity_Query 475 */ 476 function test_bp_has_activities_with_filter_query_compare_between_operator() { 477 $u1 = $this->factory->user->create(); 478 479 $now = time(); 480 481 // misc activity items 482 $a1 = $this->factory->activity->create( array( 483 'user_id' => $u1, 484 'component' => 'blogs', 485 'item_id' => 1, 486 'type' => 'new_blog_post', 487 'recorded_time' => date( 'Y-m-d H:i:s', $now - 100 ), 488 ) ); 489 $a2 = $this->factory->activity->create( array( 490 'user_id' => $u1, 491 'component' => 'activity', 492 'type' => 'activity_update', 493 'recorded_time' => date( 'Y-m-d H:i:s', $now - 100 ), 494 ) ); 495 $a3 = $this->factory->activity->create( array( 496 'user_id' => $u1, 497 'component' => 'activity', 498 'type' => 'activity_update', 499 'recorded_time' => date( 'Y-m-d H:i:s', $now - 100 ), 500 ) ); 501 $a4 = $this->factory->activity->create( array( 502 'user_id' => $u1, 503 'component' => 'groups', 504 'item_id' => 324, 505 'type' => 'activity_update', 506 'recorded_time' => date( 'Y-m-d H:i:s', $now - 100 ), 507 ) ); 508 509 global $activities_template; 510 511 bp_has_activities( array( 512 'filter_query' => array( 513 array( 514 'column' => 'id', 515 'compare' => 'BETWEEN', 516 'value' => array( $a3, $a4 ), 517 ), 518 ) 519 ) ); 520 521 // assert! 522 $this->assertEqualSets( array( $a3, $a4 ), wp_list_pluck( $activities_template->activities, 'id' ) ); 523 524 // clean up! 525 $activities_template = null; 526 } 527 528 /** 529 * @group filter_query 530 * @group BP_Activity_Query 531 */ 532 function test_bp_has_activities_with_filter_query_compare_arithmetic_comparisons() { 533 $u1 = $this->factory->user->create(); 534 535 $now = time(); 536 537 // misc activity items 538 $a1 = $this->factory->activity->create( array( 539 'user_id' => $u1, 540 'component' => 'activity', 541 'item_id' => 1, 542 'type' => 'activity_update', 543 'recorded_time' => date( 'Y-m-d H:i:s', $now - 100 ), 544 ) ); 545 $a2 = $this->factory->activity->create( array( 546 'user_id' => $u1, 547 'component' => 'activity', 548 'item_id' => 10, 549 'type' => 'activity_update', 550 'recorded_time' => date( 'Y-m-d H:i:s', $now - 100 ), 551 ) ); 552 $a3 = $this->factory->activity->create( array( 553 'user_id' => $u1, 554 'component' => 'activity', 555 'item_id' => 25, 556 'type' => 'activity_update', 557 'recorded_time' => date( 'Y-m-d H:i:s', $now - 100 ), 558 ) ); 559 $a4 = $this->factory->activity->create( array( 560 'user_id' => $u1, 561 'component' => 'activity', 562 'item_id' => 100, 563 'type' => 'activity_update', 564 'recorded_time' => date( 'Y-m-d H:i:s', $now - 100 ), 565 ) ); 566 567 global $activities_template; 568 569 // greater than 570 bp_has_activities( array( 571 'filter_query' => array( 572 array( 573 'column' => 'item_id', 574 'compare' => '>', 575 'value' => 10, 576 ), 577 ) 578 ) ); 579 580 // assert! 581 $this->assertEqualSets( array( $a3, $a4 ), wp_list_pluck( $activities_template->activities, 'id' ) ); 582 583 // greater or equal than 584 bp_has_activities( array( 585 'filter_query' => array( 586 array( 587 'column' => 'item_id', 588 'compare' => '>=', 589 'value' => 10, 590 ), 591 ) 592 ) ); 593 594 // assert! 595 $this->assertEqualSets( array( $a2, $a3, $a4 ), wp_list_pluck( $activities_template->activities, 'id' ) ); 596 597 // less than 598 bp_has_activities( array( 599 'filter_query' => array( 600 array( 601 'column' => 'item_id', 602 'compare' => '<', 603 'value' => 10, 604 ), 605 ) 606 ) ); 607 608 // assert! 609 $this->assertEqualSets( array( $a1 ), wp_list_pluck( $activities_template->activities, 'id' ) ); 610 611 // less or equal than 612 bp_has_activities( array( 613 'filter_query' => array( 614 array( 615 'column' => 'item_id', 616 'compare' => '<=', 617 'value' => 10, 618 ), 619 ) 620 ) ); 621 622 // assert! 623 $this->assertEqualSets( array( $a1, $a2 ), wp_list_pluck( $activities_template->activities, 'id' ) ); 624 625 // not equal to 626 bp_has_activities( array( 627 'filter_query' => array( 628 array( 629 'column' => 'item_id', 630 'compare' => '!=', 631 'value' => 10, 632 ), 633 ) 634 ) ); 635 636 // assert! 637 $this->assertEqualSets( array( $a1, $a3, $a4 ), wp_list_pluck( $activities_template->activities, 'id' ) ); 638 639 // clean up! 640 $activities_template = null; 641 } 642 643 /** 644 * @group filter_query 645 * @group BP_Activity_Query 646 */ 647 function test_bp_has_activities_with_filter_query_compare_regex() { 648 $u1 = $this->factory->user->create(); 649 650 $now = time(); 651 652 // misc activity items 653 $a1 = $this->factory->activity->create( array( 654 'user_id' => $u1, 655 'component' => 'blogs', 656 'item_id' => 1, 657 'type' => 'new_blog_post', 658 'recorded_time' => date( 'Y-m-d H:i:s', $now - 100 ), 659 ) ); 660 $a2 = $this->factory->activity->create( array( 661 'user_id' => $u1, 662 'component' => 'blogs', 663 'type' => 'new_blog_comment', 664 'recorded_time' => date( 'Y-m-d H:i:s', $now - 100 ), 665 ) ); 666 $a3 = $this->factory->activity->create( array( 667 'user_id' => $u1, 668 'component' => 'activity', 669 'type' => 'activity_update', 670 'recorded_time' => date( 'Y-m-d H:i:s', $now - 100 ), 671 ) ); 672 $a4 = $this->factory->activity->create( array( 673 'user_id' => $u1, 674 'component' => 'groups', 675 'item_id' => 324, 676 'type' => 'activity_update', 677 'recorded_time' => date( 'Y-m-d H:i:s', $now - 100 ), 678 ) ); 679 680 global $activities_template; 681 682 // REGEXP 683 bp_has_activities( array( 684 'filter_query' => array( 685 array( 686 'column' => 'type', 687 'compare' => 'REGEXP', 688 'value' => '^new_blog_', 689 ), 690 ) 691 ) ); 692 693 // assert! 694 $this->assertEqualSets( array( $a1, $a2 ), wp_list_pluck( $activities_template->activities, 'id' ) ); 695 696 // RLIKE is a synonym for REGEXP 697 bp_has_activities( array( 698 'filter_query' => array( 699 array( 700 'column' => 'type', 701 'compare' => 'RLIKE', 702 'value' => '^new_blog_', 703 ), 704 ) 705 ) ); 706 707 // assert! 708 $this->assertEqualSets( array( $a1, $a2 ), wp_list_pluck( $activities_template->activities, 'id' ) ); 709 710 // NOT REGEXP 711 bp_has_activities( array( 712 'filter_query' => array( 713 array( 714 'column' => 'type', 715 'compare' => 'NOT REGEXP', 716 'value' => '^new_blog_', 717 ), 718 ) 719 ) ); 720 721 // assert! 722 $this->assertEqualSets( array( $a3, $a4 ), wp_list_pluck( $activities_template->activities, 'id' ) ); 723 724 // clean up! 725 $activities_template = null; 726 } 727 728 /** 146 729 * Integration test for 'meta_query' param 147 730 */ 148 731 function test_bp_has_activities_with_meta_query() {