Create New Item
Item Type
File
Folder
Item Name
Search file in folder and subfolders...
Are you sure want to rename?
optometrists
/
cache
/
cache
/
cache
/
.wp-cli
/
wp-content
/
plugins
/
wp-data-access
/
WPDataAccess
/
Data_Dictionary
:
WPDA_Dictionary_Exist.php
Advanced Search
Upload
New Item
Settings
Back
Back Up
Advanced Editor
Save
<?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 ); } } }