<?php /** * Suppress "error - 0 - No summary was found for this file" on phpdoc generation * * @package WPDataAccess\Data_Dictionary */ namespace WPDataAccess\Data_Dictionary { use WPDataAccess\List_Table\WPDA_List_Table; use WPDataAccess\WPDA; /** * Class WPDA_Dictionary_Access * * Check if access to a given table is granted. The existence of the table name (and schema name for back-end) is * not checked in this class. The class presumes that the table name (and schema name for back-end) is valid. * * The argument $done, which is used throughout the class, indicates whether the access check confirms the * existence of the table or whether no access is granted anyway and therefor no further checks are needed. In * some situations this saves us a query. * * For example: * * If table $wpdb->options is provided as an argument and access to WordPress tables is allowed we are done. If * only selected tables are allowed and the table provided as an argument is either in or not in the list we done * as well. When calling WPDA_Dictionary_Access functions check the return value as well as $done. * * @author Peter Schulz * @since 1.0.0 */ class WPDA_Dictionary_Access { /** * Check back-end table access * * Checks if access to a given schema and table is granted for back-end usage. * * The schema name must be provided as an argument. This argument is mainly added to support a clean access * check for the data explorer view which uses the view TABLES from MySQL schema INFORMATION_SCHEMA (see * {@see WPDA_List_Table::LIST_BASE_TABLE}). This is the only table/view outside the WordPress schema to * which access is granted. * * @param string $schema_name Schema name in which the table or view is located. * @param string $table_name Table or view name. * @param boolean $done TRUE = no further checks needed, FALSE = still need to check table name. * * @return bool TRUE = access granted, FALSE = access denied. * @since 1.0.0 * * @see WPDA_List_Table::LIST_BASE_TABLE */ public static function check_table_access_backend( $schema_name, $table_name, &$done ) { if ( WPDA_List_Table::LIST_BASE_TABLE === $schema_name . '.' . $table_name ) { // Always grant access to table list. $done = true; // No further checks needed. return true; } global $wpdb; if ( $schema_name === $wpdb->dbname && WPDA::is_wpda_table( $table_name ) ) { // Always grant access to WPDA table's in the back-end. $done = true; // No further checks needed. return true; } if ( $schema_name === $wpdb->dbname ) { $table_access = WPDA::get_option( WPDA::OPTION_BE_TABLE_ACCESS ); $table_access_selected = WPDA::get_option( WPDA::OPTION_BE_TABLE_ACCESS_SELECTED ); } else { $table_access = get_option( WPDA::BACKEND_OPTIONNAME_DATABASE_ACCESS . $schema_name ); if ( false === $table_access ) { $table_access = 'show'; } $table_access_selected = get_option( WPDA::BACKEND_OPTIONNAME_DATABASE_SELECTED . $schema_name ); if ( false === $table_access_selected ) { $table_access_selected = ''; } } return self::check_table_access( $schema_name, $table_name, $table_access, $table_access_selected, $done ); } /** * Check tables access * * Checks if access to a given table is granted for back-end or front-end usage. Whether the check is performed * for the back-end or front-end depends on the arguments $table_access and $table_access_selected. * * The schema name is not reflected in this check. It presumed that the schema name if the schema in which * WordPress is installed. * * This function is code which is shared between {@see WPDA_Dictionary_Access::check_table_access_backend()} * and {@see WPDA_Dictionary_Access::check_table_access_frontend()}. * * @param string $schema_name Schema name in which the table or view is located. * @param string $table_name Table or view name. * @param string $table_access Option value for table access as stored in wp_options. * @param string $table_access_selected Option value for tables selected access as stored in wp_options. * @param boolean $done TRUE = no futher checks needed, FALSE = still need to check table name. * * @return bool TRUE = access granted, FALSE = access denied. * @see WPDA_Dictionary_Access::check_table_access_frontend() * * @since 1.0.0 * * @see WPDA_Dictionary_Access::check_table_access_backend() */ protected static function check_table_access( $schema_name, $table_name, $table_access, $table_access_selected, &$done ) { if ( 'hide' === $table_access ) { global $wpdb; if ( $wpdb->dbname !== $schema_name ) { // Non WordPress database: access granted. $done = false; // Still need to check if table exists. return true; } // No access to WordPress tables: check if the requested table is a WordPress table. $wp_tables = $wpdb->tables( 'all', true ); if ( isset( $wp_tables[ substr( $table_name, strlen( $wpdb->prefix ) ) ] ) && $wp_tables[ substr( $table_name, strlen( $wpdb->prefix ) ) ] === $table_name ) { // WordPress table: deny access. $done = true; // No further checks needed. return false; } else { // Non WordPress table: access granted. $done = false; // Still need to check if table exists. return true; } } elseif ( 'select' === $table_access ) { // Only access to selected tables and views (front-end settings). if ( '' !== $table_access_selected ) { foreach ( $table_access_selected as $key => $value ) { if ( $table_name === $value ) { // Access to this table or view is granted. $done = true; // No further checks needed. return true; } } } // No access. $done = true; // No further checks needed. return false; } else { // Access granted to all tables and views. $done = false; // Still need to check if table exists. return true; } } /** * Check front-end table access * * Checks if access to a given table is granted for front-end usage. * * The schema name is not reflected in this check. It presumed that the schema name if the schema in which * WordPress is installed. * * @param string $schema_name Schema name in which the table or view is located. * @param string $table_name Table or view name. * @param boolean $done TRUE = no futher checks needed, FALSE = still need to check table name. * * @return bool TRUE = access granted, FALSE = access denied. * @since 1.0.0 */ public static function check_table_access_frontend( $schema_name, $table_name, &$done ) { global $wpdb; if ( $wpdb->dbname === $schema_name ) { $table_access = WPDA::get_option( WPDA::OPTION_FE_TABLE_ACCESS ); $table_access_selected = WPDA::get_option( WPDA::OPTION_FE_TABLE_ACCESS_SELECTED ); } else { $table_access = get_option( WPDA::FRONTEND_OPTIONNAME_DATABASE_ACCESS . $schema_name ); if ( false === $table_access ) { $table_access = 'select'; } $table_access_selected = get_option( WPDA::FRONTEND_OPTIONNAME_DATABASE_SELECTED . $schema_name ); if ( false === $table_access_selected ) { $table_access_selected = ''; } } return self::check_table_access( $schema_name, $table_name, $table_access, $table_access_selected, $done ); } /** * Check if user has CREATE (database) privilege * * @return bool * @since 2.7.2 */ public static function can_create_db() { global $wpdb; $wpdb->get_results( "select * from information_schema.user_privileges where privilege_type = 'CREATE' and replace(grantee, '\'', '') = current_user()" ); return $wpdb->num_rows > 0; } /** * Check if user has DROP (database) privilege * * @return bool * @since 2.7.2 */ public static function can_drop_db() { global $wpdb; $wpdb->get_results( "select * from information_schema.user_privileges where privilege_type = 'DROP' and replace(grantee, '\'', '') = current_user()" ); return $wpdb->num_rows > 0; } } }