table = $table; $this->primary_key_column = $primary_key_column; } /** * Get Query select * * @return array|string */ private function get_select_query() { return esc_sql( implode( ',', $this->selects ) ); } /** * Get Sort SQl * * @return string */ private function get_sort_sql() { $orderby = $this->orderby ?: $this->primary_key_column; $order = $this->order ?: 'ASC'; return "ORDER BY {$this->table}.{$orderby} {$order}"; } /** * Get Group By SQL * * @return string */ private function get_grouping_sql() { if ( empty( $this->group_by ) ) { return ''; } return "GROUP BY {$this->group_by}"; } /** * Get pagination SQL * * @return string */ private function get_pagination_sql() { if ( $this->limit ) { $offset = $this->offset ?: 0; return "LIMIT {$this->limit} OFFSET {$offset}"; } return ''; } /** * Get complete sql * * @return string */ public function get_sql() { return " SELECT {$this->get_select_query()} FROM $this->table {$this->table_join} {$this->where} {$this->get_grouping_sql()} {$this->get_sort_sql()} {$this->get_pagination_sql()} "; } /** * Update Query select * * @param $select * @return UserFeedback_Query */ public function select( $select = array( '*' ) ) { $this->selects = $select; return $this; } /** * Add raw select * * @param $select * @return void */ public function select_raw( $select ) { $this->selects[] = $select; return $this; } /** * Update Query Where clause * * @param array $args * @return UserFeedback_Query */ public function where( $args = array(), $or = false, $override = false ) { global $wpdb; $where_parts = array(); $where = $override ? '' : $this->where; $allowed_symbols = array( '<', '>', '<=', '>=', '!=', '=', 'is', 'is not' ); $values = array(); foreach ( $args as $key => $value ) { if ( is_array( $value ) ) { if ( sizeof( $value ) < 3 ) { continue; } $key = $value[0]; $operator = $value[1]; $target_value = $value[2]; if ( ! in_array( $operator, $allowed_symbols ) ) { continue; } if ( $target_value === null ) { $where_parts[] = "{$key} {$operator} null"; } else { $where_parts[] = "{$key} {$operator} %s"; $values[] = $target_value; } } else { if ( $value !== null ) { $values[] = $value; $where_parts[] = "{$key} = '%s'"; } else { $where_parts[] = "{$key} is null"; } } } if ( empty( $where ) ) { $where = 'WHERE '; } elseif ( $or ) { $where .= ' OR '; } else { $where .= ' AND '; } $where .= '(' . implode( ' AND ', $where_parts ) . ')'; if ( ! empty( $where ) ) { // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- $where contains only column name fragments and %s placeholders; values passed as $values array. $this->where = $wpdb->prepare( $where, $values ); } return $this; } /** * Add Or where config * * @param $args * @return $this */ public function or_where( $args ) { return $this->where( $args, true ); } /** * Join tables * * @param $table * @param $this_table_attr * @param $other_table_attr * @return void */ public function join( $table, $this_table_attr, $other_table_attr ) { $this->table_join = "LEFT JOIN {$table} on {$this_table_attr} = {$other_table_attr}"; } /** * Update Query sortby and order * * @param $attr * @param $order * @return UserFeedback_Query */ public function orderby( $attr, $order = 'ASC' ) { $this->orderby = $attr; $this->order = $order; return $this; } /** * Add grouping to SQL query * * @param $attr * @return $this */ public function group_by( $attr ) { $this->selects[] = 'count(*) as count'; $this->group_by = $attr; return $this; } /** * Update query pagination * * @param $per_page * @param $page * @return UserFeedback_Query */ public function paginate( $per_page, $page = 1 ) { $this->is_paginated = true; $this->page = $page; $this->per_page = $per_page; $limit = $per_page; $offset = $page > 1 ? ( $page - 1 ) * $limit : 0; if ( $limit < 1 ) { $limit = PHP_INT_MAX; } $this->limit = $limit; $this->offset = $offset; return $this; } /** * Execute query * * @return array|object|null */ public function run() { global $wpdb; // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter -- SQL is built by this query builder using $wpdb->prepare() in where(); table/column names are validated internally. return $wpdb->get_results( $this->get_sql() ); } /** * Get Query Where clause * * @return string */ public function get_where_query() { return $this->where; } /** * Returns true if query has pagination params * * @return bool */ public function is_paginated() { return $this->is_paginated; } /** * Get Pagination basic info * * @return array */ public function get_pagination() { return array( 'page' => $this->page, 'per_page' => $this->per_page, ); } }