$status ) { if ( 'publish' === $status ) { unset( $query['status'][ $key ] ); } } $query['status'][] = 'complete'; } elseif ( 'publish' === $query['status'] ) { $query['status'] = 'complete'; } } parent::__construct( $query ); } /** * Set up the filter callback to add the country and region from the order addresses table. * * @since 3.0 * @access public * * @param string|array $query See Order::__construct() for accepted arguments. * * @see Order::__construct() */ public function query( $query = array() ) { $query_clauses_filters = $this->get_query_clauses_filters( $query ); foreach ( $query_clauses_filters as $filter ) { if ( $filter['condition'] ) { add_filter( 'edd_orders_query_clauses', array( $this, $filter['callback'] ) ); } } $result = parent::query( $query ); foreach ( $query_clauses_filters as $filter ) { if ( $filter['condition'] ) { remove_filter( 'edd_orders_query_clauses', array( $this, $filter['callback'] ) ); } } return $result; } /** * Filter the query clause to add the country and region from the order addresses table. * * @since 3.0 * @access public * * @param string|array $clauses The clauses which will generate the final SQL query. */ public function query_by_country( $clauses ) { if ( empty( $this->query_vars['country'] ) || 'all' === $this->query_vars['country'] ) { return $clauses; } global $wpdb; $primary_alias = $this->table_alias; $primary_column = parent::get_primary_column_name(); $order_addresses_query = new \EDD\Database\Queries\Order_Address(); $join_alias = $order_addresses_query->table_alias; // Filter by the order address's region (state/province/etc).. if ( ! empty( $this->query_vars['region'] ) && 'all' !== $this->query_vars['region'] ) { $location_join = $wpdb->prepare( " INNER JOIN {$order_addresses_query->table_name} {$join_alias} ON ({$primary_alias}.{$primary_column} = {$join_alias}.order_id AND {$join_alias}.country = %s AND {$join_alias}.region = %s)", $this->query_vars['country'], $this->query_vars['region'] ); // Add the region to the query var defaults. $this->query_var_defaults['region'] = $this->query_vars['region']; // Filter only by the country, not by region. } else { $location_join = $wpdb->prepare( " INNER JOIN {$order_addresses_query->table_name} {$join_alias} ON ({$primary_alias}.{$primary_column} = {$join_alias}.order_id AND {$join_alias}.country = %s)", $this->query_vars['country'] ); // Add the country to the query var defaults. $this->query_var_defaults['country'] = $this->query_vars['country']; } // Add the customized join to the query. $clauses['join'] .= ' ' . $location_join; return $clauses; } /** * Filter the query clause to filter by product ID. * * @since 3.0 * @access public * * @param string|array $clauses The clauses which will generate the final SQL query. */ public function query_by_product( $clauses ) { if ( empty( $this->query_vars['product_id'] ) && ( ! isset( $this->query_vars['product_price_id'] ) || ! is_numeric( $this->query_vars['product_price_id'] ) ) ) { return $clauses; } global $wpdb; $primary_column = parent::get_primary_column_name(); $order_items_query = new Order_Item(); // Build up our conditions. $conditions = array(); foreach ( array( 'product_id' => 'product_id', 'product_price_id' => 'price_id' ) as $query_var => $db_col ) { if ( isset( $this->query_vars[ $query_var ] ) && is_numeric( $this->query_vars[ $query_var ] ) ) { $conditions[] = $wpdb->prepare( "AND {$order_items_query->table_alias}.{$db_col} = %d", absint( $this->query_vars[ $query_var ] ) ); } } $conditions = implode( ' ', $conditions ); $clauses['join'] .= " INNER JOIN {$order_items_query->table_name} {$order_items_query->table_alias} ON( {$this->table_alias}.{$primary_column} = {$order_items_query->table_alias}.order_id {$conditions} )"; return $clauses; } /** * Filter the query clause to filter by transaction ID. * * @since 3.0.2 * @param string $clauses * @return string */ public function query_by_txn( $clauses ) { if ( empty( $this->query_vars['txn'] ) ) { return $clauses; } global $wpdb; $primary_column = parent::get_primary_column_name(); $order_transaction_query = new Order_Transaction(); $clauses['join'] .= $wpdb->prepare( " INNER JOIN {$order_transaction_query->table_name} {$order_transaction_query->table_alias} ON( {$this->table_alias}.{$primary_column} = {$order_transaction_query->table_alias}.object_id AND {$order_transaction_query->table_alias}.transaction_id = %s )", sanitize_text_field( $this->query_vars['txn'] ) ); return $clauses; } /** * Filter the query clause to filter by discount ID. * * @since 3.0.2 * @param string $clauses * @return string */ public function query_by_discount_id( $clauses ) { if ( empty( $this->query_vars['discount_id'] ) ) { return $clauses; } global $wpdb; $primary_column = parent::get_primary_column_name(); $order_adjustment_query = new Order_Adjustment(); $clauses['join'] .= $wpdb->prepare( " INNER JOIN {$order_adjustment_query->table_name} {$order_adjustment_query->table_alias} ON( {$this->table_alias}.{$primary_column} = {$order_adjustment_query->table_alias}.object_id AND {$order_adjustment_query->table_alias}.type_id = %d )", absint( $this->query_vars['discount_id'] ) ); return $clauses; } /** * When searching by a numeric order number, we need to override the default where clause * to return orders matching either the ID or order number. * * @since 3.1.1.4 * @param array $clauses * @return array */ public function query_by_order_search( $clauses ) { global $wpdb; $clauses['where'] = $wpdb->prepare( "{$this->table_alias}.id = %d OR {$this->table_alias}.order_number = %d", absint( $this->query_vars['id'] ), absint( $this->query_vars['order_number'] ) ); return $clauses; } /** * Set the query var defaults for country and region. * * @since 3.0 * @access public */ protected function set_query_var_defaults() { parent::set_query_var_defaults(); $this->query_var_defaults['country'] = false; $this->query_var_defaults['region'] = false; $this->query_var_defaults['product_id'] = false; $this->query_var_defaults['product_product_id'] = false; } /** * Adds an item to the database * * @since 3.0 * * @param array $data * @return false|int Returns the item ID on success; false on failure. */ public function add_item( $data = array() ) { // Every order should have a currency assigned. if ( empty( $data['currency'] ) ) { $data['currency'] = edd_get_currency(); } // If the payment key isn't already created, generate it. if ( empty( $data['payment_key'] ) ) { $email = ! empty( $data['email'] ) ? $data['email'] : ''; $data['payment_key'] = edd_generate_order_payment_key( $email ); } // Add the IP address if it hasn't been already. if ( empty( $data['ip'] ) ) { $data['ip'] = edd_get_ip(); } return parent::add_item( $data ); } /** * Get the array of possible query clause filters. * * @since 3.0.2 * @param array $query * @return array */ private function get_query_clauses_filters( $query ) { return array( array( 'condition' => ! empty( $query['country'] ), 'callback' => 'query_by_country', ), array( 'condition' => ! empty( $query['product_id'] ) || ( isset( $query['product_price_id'] ) && is_numeric( $query['product_price_id'] ) ), 'callback' => 'query_by_product', ), array( 'condition' => ! empty( $query['txn'] ), 'callback' => 'query_by_txn', ), array( 'condition' => ! empty( $query['discount_id'] ), 'callback' => 'query_by_discount_id', ), array( 'condition' => ! empty( $query['id'] ) && ! empty( $query['order_number'] ) && $query['id'] === $query['order_number'], 'callback' => 'query_by_order_search', ), ); } }