File "WPDA_Dictionary_Exist.php"
Full Path: /home/vantageo/public_html/cache/cache/cache/cache/cache/cache/cache/.wp-cli/wp-content/plugins/wp-data-access/WPDataAccess/Data_Dictionary/WPDA_Dictionary_Exist.php
File size: 12.03 KB
MIME-type: text/x-php
Charset: utf-8
<?php
/**
* Suppress "error - 0 - No summary was found for this file" on phpdoc generation
*
* @package WPDataAccess\Data_Dictionary
*/
namespace WPDataAccess\Data_Dictionary {
use WPDataAccess\Connection\WPDADB;
use WPDataAccess\WPDA;
/**
* Class WPDA_Dictionary_Exist
*
* WP Data Access provides interactive database access. Users might follow the interaction provided by the
* plugin, but might as well influence it's behaviour through plugin arguments (hack query strings and post
* values). The dynamic nature of WP Data Access allows users to change table and column names that are
* communicated from one page to another, which clearly leads to a SQL injection risk. This class deals with
* this issue through checks of existence of database object, like tables, columns, ect.
*
* @author Peter Schulz
* @since 1.0.0
*/
class WPDA_Dictionary_Exist {
/**
* Cached schema names
*
* @var array
*/
protected static $schema_name_cache = array();
/**
* Cached table names
*
* @var array
*/
protected static $table_name_cache = array();
/**
* Indicator to identify if standard database schema and plugin tables are loaded
*
* @var bool
*/
protected static $plugin_schema_and_tables_loaded = false;
/**
* Database schema name
*
* @var string
*/
protected $schema_name = '';
/**
* Database table name
*
* @var string
*/
protected $table_name = '';
/**
* WPDA_Dictionary_Checks constructor
*
* For table and column checks this class should be used by instantiating it. The table name must be
* provided as an argument. The schema name might be part of the table name provided in which case the
* schema name and table name should be seperated by a '.' (dot) as in MySQL notations. If no schema name
* is provided the WordPress schema is used as the default.
*
* @param string $schema_name Database schema name.
* @param string $table_name Database table name.
*
* @since 1.0.0
*/
public function __construct( $schema_name, $table_name ) {
// DO NOT ADD PLUGIN TABLES TO CACHE (causes problems if not found)
// self::load_plugin_tables();
global $wpdb;
if ( '' !== $schema_name ) {
if ( ! isset( self::$schema_name_cache[ $schema_name ] ) ) {
// Check if schema name is valid!
// Remote check...
$rdb = WPDADB::get_remote_database( $schema_name );
if ( false !== $rdb ) {
self::$schema_name_cache[ $schema_name ] = true;
} else {
// Local check...
// Since a table name (and therefor schema name as well) can be provided on the url we need to check for
// sql injection. We'll do this by checking of the schema name exists in our database.
$wpdb->get_results(
$wpdb->prepare(
'
SELECT TRUE
FROM information_schema.schemata
WHERE schema_name = %s
',
array(
$schema_name,
)
)
); // db call ok; no-cache ok.
if ( 1 !== $wpdb->num_rows ) {
// Schema name doesn't exist! It makes no sense to continue.
wp_die( __( 'ERROR: Wrong arguments [schema name not found]', 'wp-data-access' ) );
} else {
self::$schema_name_cache[ $schema_name ] = true;
}
}
}
$this->schema_name = $schema_name;
$this->table_name = $table_name;
} else {
// Table or view is located in the WordPress database schema.
$this->schema_name = $wpdb->dbname; // Taken from wpdb: no check needed.
$this->table_name = $table_name;
}
}
/**
* Load plugin table name into cache
*
* Loads the plugin tables into a named array to be cached for fast table named access.
*
* @since 2.0.11
*/
protected static function load_plugin_tables() {
if ( ! self::$plugin_schema_and_tables_loaded ) {
global $wpdb;
self::$schema_name_cache[ $wpdb->dbname ] = true;
$plugin_tables = WPDA::get_wpda_tables();
foreach ( $plugin_tables as $plugin_table ) {
self::$table_name_cache[ "{$wpdb->dbname}.$plugin_table" ] = true;
}
self::$plugin_schema_and_tables_loaded = true;
}
}
/**
* Check if function exists
*
* @param string $schema_name Database schema name.
* @param string $function_name Database function name.
*
* @return bool TRUE = function exists, FALSE = function does not exist.
* @since 1.0.0
*/
public static function function_exists( $schema_name, $function_name ) {
return self::routine_exists( $schema_name, $function_name, 'FUNCTION' );
}
/**
* Check is routine exists
*
* @param string $schema_name Database schema name.
* @param string $routine_name Database routine name.
* @param string $routine_type Database routine type.
*
* @return bool TRUE = routine exists, FALSE = routine does not exist.
* @since 1.0.0
*/
protected static function routine_exists( $schema_name, $routine_name, $routine_type ) {
$wpdadb = WPDADB::get_db_connection( $schema_name );
if ( $wpdadb === null ) {
return false;
}
$wpdadb->query(
$wpdadb->prepare(
'
SELECT TRUE
FROM information_schema.routines
WHERE routine_schema = %s
AND routine_name = %s
AND routine_type = %s
',
array(
$wpdadb->dbname,
$routine_name,
$routine_type,
)
)
); // db call ok; no-cache ok.
$wpdadb->get_results(); // phpcs:ignore Standard.Category.SniffName.ErrorCode
return ( 1 === $wpdadb->num_rows );
}
/**
* Check if procedure exists
*
* @param string $schema_name Database schema name.
* @param string $procedure_name Database procedure name.
*
* @return bool TRUE = procedure exists, FALSE = procedure does not exist.
* @since 1.0.0
*/
public static function procedure_exists( $schema_name, $procedure_name ) {
return self::routine_exists( $schema_name, $procedure_name, 'PROCEDURE' );
}
/**
* Check if trigger exists
*
* @param string $schema_name Database schema name.
* @param string $trigger_name Database trigger name.
*
* @return bool TRUE = trigger exists, FALSE = trigger does not exist.
* @since 1.0.0
*/
public static function trigger_exists( $schema_name, $trigger_name ) {
$wpdadb = WPDADB::get_db_connection( $schema_name );
if ( $wpdadb === null ) {
return false;
}
$wpdadb->query(
$wpdadb->prepare(
'
SELECT TRUE
FROM information_schema.triggers
WHERE trigger_schema = %s
AND trigger_name = %s
',
array(
$wpdadb->dbname,
$trigger_name,
)
)
); // db call ok; no-cache ok.
$wpdadb->get_results(); // phpcs:ignore Standard.Category.SniffName.ErrorCode
return ( 1 === $wpdadb->num_rows );
}
/**
* Checks if a table exists
*
* A dynamic SQL statement might use a table or view name which can be supplied as argument on the url. This
* is a source of a possible SQL injection attack. In cases where users have the possibility to change a table
* or view name argument, we must check if the table or view name exists in the WordPress database to protect
* ourselves against SQL injection attacks.
*
* Before the existence of a table is checked against the MySQL data dictionary, an access check is performed.
* If the access check returns FALSE, a query for existence is no longer needed. The access check is performed
* prior to the existence check as it quicker and might save us a more expensive action.
*
* Works with tables as well as views.
*
* @param bool $use_table_access_settings Indicator whether settings should be checked (default = true).
* @param bool $check_back_end TRUE = back-end check, FALSE = font-end check.
*
* @return bool TRUE means table name is valid.
* @since 1.0.0
*/
public function table_exists( $use_table_access_settings = true, $check_back_end = true ) {
if ( isset( self::$table_name_cache[ "$this->schema_name.$this->table_name" ] ) ) {
return true;
}
if ( $use_table_access_settings ) {
// First check if access is granted.
if ( $check_back_end ) {
// Check back-end access.
$access = WPDA_Dictionary_Access::check_table_access_backend(
$this->schema_name,
$this->table_name,
$done
);
if ( $done ) {
return $access;
}
if ( ! $access ) {
return false;
}
} else {
// Check front-end access.
$access = WPDA_Dictionary_Access::check_table_access_frontend(
$this->schema_name,
$this->table_name,
$done
);
if ( $done ) {
return $access;
}
if ( ! $access ) {
return false;
}
}
}
$wpdadb = WPDADB::get_db_connection( $this->schema_name );
if ( $wpdadb === null ) {
return false;
}
// In all other cases check if table or view exists.
$wpdadb->query(
$wpdadb->prepare(
'
SELECT TRUE
FROM information_schema.tables
WHERE table_schema = %s
AND table_name = %s
',
array(
$wpdadb->dbname,
$this->table_name,
)
)
); // db call ok; no-cache ok.
$wpdadb->get_results(); // phpcs:ignore Standard.Category.SniffName.ErrorCode
if ( 1 === $wpdadb->num_rows ) {
self::$table_name_cache[ "$this->schema_name.$this->table_name" ] = true;
return true;
} else {
return false;
}
}
/**
* Plain check if table exists
*
* No access control, back-end or front-end checks are taken into account. This method only checks the
* existence of the table.
*
* @return bool
*/
public function plain_table_exists() {
$wpdadb = WPDADB::get_db_connection( $this->schema_name );
if ( $wpdadb === null ) {
return false;
}
$wpdadb->query(
$wpdadb->prepare(
'
SELECT TRUE
FROM information_schema.tables
WHERE table_schema = %s
AND table_name = %s
',
array(
$wpdadb->dbname,
$this->table_name,
)
)
); // db call ok; no-cache ok.
$wpdadb->get_results(); // phpcs:ignore Standard.Category.SniffName.ErrorCode
return ( 1 === $wpdadb->num_rows );
}
/**
* Check is a column exists
*
* Checks whether a column name exists in the WordPress database. Used to prevent SQL injection. Also read
* {@see WPDA_Dictionary_Exist::table_exists()}.
*
* Works with tables as well as views.
*
* @param string $column_name Database columns name.
*
* @return bool TRUE = column exists.
* @since 1.0.0
*/
public function column_exists( $column_name ) {
$wpdadb = WPDADB::get_db_connection( $this->schema_name );
if ( $wpdadb === null ) {
return false;
}
$wpdadb->query(
$wpdadb->prepare(
'
SELECT TRUE
FROM information_schema.columns
WHERE table_schema = %s
AND table_name = %s
AND column_name = %s
',
array(
$wpdadb->dbname,
$this->table_name,
$column_name,
)
)
); // db call ok; no-cache ok.
$wpdadb->get_results(); // phpcs:ignore Standard.Category.SniffName.ErrorCode
return ( 1 === $wpdadb->num_rows );
}
/**
* Is provided table name a view?
*
* @return bool TRUE = $this->table_name is a view, FALSE = $this->table_name is a table
*/
public function is_view() {
$wpdadb = WPDADB::get_db_connection( $this->schema_name );
if ( $wpdadb === null ) {
return false;
}
$wpdadb->query(
$wpdadb->prepare(
"
SELECT TRUE
FROM information_schema.tables
WHERE table_schema = %s
AND table_name = %s
AND table_type LIKE '%VIEW'
",
array(
$wpdadb->dbname,
$this->table_name,
)
)
); // db call ok; no-cache ok.
$wpdadb->get_results(); // phpcs:ignore Standard.Category.SniffName.ErrorCode
return ( 1 === $wpdadb->num_rows );
}
public static function schema_exists( $schema_name ) {
global $wpdb;
$wpdb->get_results(
$wpdb->prepare(
'
SELECT TRUE
FROM information_schema.schemata
WHERE schema_name = %s
',
array(
$schema_name,
)
)
); // db call ok; no-cache ok.
return ( 1 === $wpdb->num_rows );
}
}
}