Server IP : 15.235.198.142 / Your IP : 216.73.216.193 Web Server : Apache/2.4.58 (Ubuntu) System : Linux ballsack 6.8.0-45-generic #45-Ubuntu SMP PREEMPT_DYNAMIC Fri Aug 30 12:02:04 UTC 2024 x86_64 User : www-data ( 33) PHP Version : 8.3.6 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /var/www/yme/wp-content/plugins/simply-static/src/ |
Upload File : |
<?php namespace Simply_Static; // Exit if accessed directly if ( ! defined( 'ABSPATH' ) ) { exit; } /** * Simply Static Query class * * Used for creating queries for the WordPress database */ class Query { /** * @var Simply_Static\Model */ protected $model; /** * Maximum number of rows to return * @var integer */ protected $limit = null; /** * Skip this many rows before returning results * @var integer */ protected $offset = null; /** * @var array */ protected $where = array(); /** * @var string */ protected $order = null; /** * @param Simply_Static\Model $model */ public function __construct( $model ) { $this->model = $model; } /** * Execute the query and return an array of models * @return array */ public function find() { global $wpdb; $model = $this->model; $query = $this->compose_select_query(); $rows = $wpdb->get_results( $query, ARRAY_A ); if ( $rows === null ) { return null; } else { $records = array(); foreach ( $rows as $row ) { $records[] = $model::initialize( $row ); } return $records; } } /** * First and return the first record matching the conditions * @return static|null An instance of the class, or null */ public function first() { global $wpdb; $model = $this->model; $this->limit(1); $query = $this->compose_select_query(); $attributes = $wpdb->get_row( $query, ARRAY_A ); if ( $attributes === null ) { return null; } else { return $model::initialize( $attributes ); } } /** * Find and return the first record matching the column name/value * * Example: find_by( 'id', 123 ) * @param string $column_name The name of the column to search on * @param string $value The value that the column should contain * @return static|null An instance of the class, or null */ public function find_by( $column_name, $value ) { global $wpdb; $model = $this->model; $this->where( array( $column_name => $value ) ); $query = $this->compose_select_query(); $attributes = $wpdb->get_row( $query, ARRAY_A ); if ( $attributes === null ) { return null; } else { return $model::initialize( $attributes ); } } /** * Find or initialize the first record with the given column name/value * * Finds the first record with the given column name/value, or initializes * an instance of the model if one is not found. * @param string $column_name The name of the column to search on * @param string $value The value that the column should contain * @return static An instance of the class (might not exist in db yet) */ public function find_or_initialize_by( $column_name, $value ) { global $wpdb; $model = $this->model; $obj = $this->find_by( $column_name, $value ); if ( ! $obj ) { $obj = $model::initialize( array( $column_name => $value ) ); } return $obj; } /** * Find the first record with the given column name/value, or create it * @param string $column_name The name of the column to search on * @param string $value The value that the column should contain * @return static An instance of the class (might not exist in db yet) */ public function find_or_create_by( $column_name, $value ) { $obj = $this->find_or_initialize_by( $column_name, $value ); if ( ! $obj->exists() ) { $obj->save(); } return $obj; } /** * Update all records to set the column name equal to the value * * string: * A single string, without additional args, is passed as-is to the query. * update_all( "widget_id = 2" ) * * assoc. array: * An associative array will use the keys as fields and the values as the * values to be updated. * update_all( array( 'widget_id' => 2, 'type' => 'sprocket' ) ) * @param mixed $arg See description * @return int|null The number of rows updated, or null if failure */ public function update_all( $arg ) { if ( func_num_args() > 1 ) { throw new \Exception( "Too many arguments passed" ); } global $wpdb; $query = $this->compose_update_query( $arg ); $rows_updated = $wpdb->query( $query ); return $rows_updated; } /** * Delete records matching a where query, replacing ? with $args * @return int|null The number of rows deleted, or null if failure */ public function delete_all() { global $wpdb; $query = $this->compose_query( 'DELETE FROM ' ); $rows_deleted = $wpdb->query( $query ); return $rows_deleted; } /** * Execute the query and return a count of records * @return int|null */ public function count() { global $wpdb; $query = $this->compose_select_query( 'COUNT(*)' ); return $wpdb->get_var( $query ); } public function get_raw_sql( $fields ) { return $this->compose_select_query( $fields ); } /** * Set the maximum number of rows to return * @param integer $limit * @return self */ public function limit( $limit ) { $this->limit = $limit; return $this; } /** * Set the number of rows to skip before returning results * @param integer $offset * @return self */ public function offset( $offset ) { if ( $this->limit === null ) { throw new \Exception( "Cannot offset without limit" ); } $this->offset = $offset; return $this; } /** * Set the ordering for results * @param string $order * @return self */ public function order( $order ) { $this->order = $order; return $this; } /** * Add a where clause to the query * * string: * A single string, without additional args, is passed as-is to the query. * where( "widget_id = 2" ) * * assoc. array: * An associative array will use the keys as fields and the values as the * values to be searched for to create a condition. * where( array( 'widget_id' => 2, 'type' => 'sprocket' ) ) * * string + args: * A string with placeholders '?' and additional args will have the string * treated as a template and the remaining args inserted into the template * to create a condition. * where( 'widget_id > ? AND widget_id < ?', 12, 18 ) * @param mixed $arg See description * @return self */ public function where( $arg ) { if ( func_num_args() == 1 ) { if ( is_array( $arg ) ) { // add array of conditions to the "where" array foreach ( $arg as $column_name => $value ) { $this->where[] = self::where_sql( $column_name, $value ); } } else if ( is_string( $arg ) ) { // pass the string as-is to our "where" array $this->where[] = $arg; } else { throw new \Exception( "One argument provided and it was not a string or array" ); } } else if ( func_num_args() > 1 ) { $where_values = func_get_args(); $condition = array_shift( $where_values ); if ( is_string( $condition ) ) { // check that the number of args and ?'s matches if ( substr_count( $condition, '?' ) != sizeof( $where_values ) ) { throw new \Exception( "Number of arguments does not match number of placeholders (?'s)" ); } else { // create a condition to add to the "where" array foreach ( $where_values as $value ) { $condition = preg_replace( '/\?/', self::escape_and_quote( $value ), $condition, 1 ); } $this->where[] = $condition; } } else { throw new \Exception( "Multiple arguments provided but first arg was not a string" ); } } else { throw new \Exception( "No arguments provided" ); } return $this; } /** * Generate a SQL query for selecting records * @param string $fields Fields to select (null = all records) * @return string The SQL query for selecting records */ private function compose_select_query( $fields = null ) { $select = ''; if ( $fields ) { $select = $fields; } else { $select = '*'; } $statement = "SELECT {$select} FROM "; return $this->compose_query( $statement ); } /** * Generate a SQL query for updating records * * string: * A single string, without additional args, is passed as-is to the query. * compose_update_query( "widget_id = 2" ) * * assoc. array: * An associative array will use the keys as fields and the values as the * values to be updated to create a condition. * compose_update_query( array( 'widget_id' => 2, 'type' => 'sprocket' ) ) * @param mixed $arg See description * @return The SQL query for updating records */ private function compose_update_query( $arg ) { $values = ' SET '; if ( is_array( $arg ) ) { // add array of conditions to the "where" array foreach ( $arg as $column_name => $value ) { $value = self::escape_and_quote( $value ); $values .= "{$column_name} = $value "; } } else if ( is_string( $arg ) ) { // pass the string as-is to our "where" array $values .= $arg . ' '; } else { throw new \Exception( "Argument provided was not a string or array" ); } return $this->compose_query( 'UPDATE ', $values ); } /** * Generate a SQL query * $param string $statement SELECT *, UPDATE, etc. * @return string */ private function compose_query( $statement, $values = '' ) { $model = $this->model; $table = ' ' . $model::table_name(); $where = ''; $order = ''; $limit = ''; $offset = ''; foreach ( $this->where as $condition ) { $where .= ' AND ' . $condition; } if ( is_a( $model, Page::class ) && false === strpos( $where, 'site_id=' ) ) { $where .= ' AND site_id=' . get_current_blog_id(); } if ( $where !== '' ) { $where = ' WHERE 1=1' . $where; } if ( $this->order ) { $order = ' ORDER BY ' . $this->order; } if ( $this->limit ) { $limit = ' LIMIT ' . $this->limit; } if ( $this->offset ) { $offset = ' OFFSET ' . $this->offset; } return "{$statement}{$table}{$values}$where{$order}{$limit}$offset"; } /** * Generate a SQL fragment for use in WHERE x=y * @param string $column_name The name of the column * @param mixed $value The value for the column * @return string The SQL fragment to be used in WHERE x=y */ private static function where_sql( $column_name, $value ) { $where_sql = $column_name; $where_sql .= ( $value === null ) ? ' IS ' : ' = '; $where_sql .= self::escape_and_quote( $value ); return $where_sql; } private static function escape_and_quote( $value ) { if ( $value === null ) { return 'NULL'; } else { $value = esc_sql( $value ); if ( is_string( $value ) ) { return "'{$value}'"; } else { return $value; } } } }