Files
wp-multisite-waas/dependencies/berlindb/core/src/Database/Base.php
2024-11-30 18:24:12 -07:00

299 lines
8.5 KiB
PHP

<?php
/**
* Base Custom Database Class.
*
* @package Database
* @subpackage Base
* @copyright Copyright (c) 2021
* @license https://opensource.org/licenses/MIT MIT
* @since 1.0.0
*/
namespace WP_Ultimo\Dependencies\BerlinDB\Database;
// Exit if accessed directly
\defined('ABSPATH') || exit;
/**
* The base class that all other database base classes extend.
*
* This class attempts to provide some universal immutability to all other
* classes that extend it, starting with a magic getter, but likely expanding
* into a magic call handler and others.
*
* @since 1.0.0
*/
class Base
{
/**
* The name of the PHP global that contains the primary database interface.
*
* For example, WordPress traditionally uses 'wpdb', but other applications
* may use something else, or you may be doing something really cool that
* requires a custom interface.
*
* A future version of this utility may abstract this out entirely, so
* custom calls to the get_db() should be avoided if at all possible.
*
* @since 1.0.0
* @var string
*/
protected $db_global = 'wpdb';
/** Global Properties *****************************************************/
/**
* Global prefix used for tables/hooks/cache-groups/etc...
*
* @since 1.0.0
* @var string
*/
protected $prefix = '';
/**
* The last database error, if any.
*
* @since 1.0.0
* @var mixed
*/
protected $last_error = \false;
/** Public ****************************************************************/
/**
* Magic isset'ter for immutability.
*
* @since 1.0.0
*
* @param string $key
* @return mixed
*/
public function __isset($key = '')
{
// No more uppercase ID properties ever
if ('ID' === $key) {
$key = 'id';
}
// Class method to try and call
$method = "get_{$key}";
// Return property if exists
if (\method_exists($this, $method)) {
return \true;
// Return get method results if exists
} elseif (\property_exists($this, $key)) {
return \true;
}
// Return false if not exists
return \false;
}
/**
* Magic getter for immutability.
*
* @since 1.0.0
*
* @param string $key
* @return mixed
*/
public function __get($key = '')
{
// No more uppercase ID properties ever
if ('ID' === $key) {
$key = 'id';
}
// Class method to try and call
$method = "get_{$key}";
// Return property if exists
if (\method_exists($this, $method)) {
return \call_user_func(array($this, $method));
// Return get method results if exists
} elseif (\property_exists($this, $key)) {
return $this->{$key};
}
// Return null if not exists
return null;
}
/**
* Converts the given object to an array.
*
* @since 1.0.0
*
* @return array Array version of the given object.
*/
public function to_array()
{
return \get_object_vars($this);
}
/** Protected *************************************************************/
/**
* Maybe append the prefix to string.
*
* @since 1.0.0
*
* @param string $string
* @param string $sep
* @return string
*/
protected function apply_prefix($string = '', $sep = '_')
{
return !empty($this->prefix) ? "{$this->prefix}{$sep}{$string}" : $string;
}
/**
* Return the first letters of a string of words with a separator.
*
* Used primarily to guess at table aliases when none is manually set.
*
* Applies the following formatting to a string:
* - Trim whitespace
* - No accents
* - No trailing underscores
*
* @since 1.0.0
*
* @param string $string
* @param string $sep
* @return string
*/
protected function first_letters($string = '', $sep = '_')
{
// Set empty default return value
$retval = '';
// Bail if empty or not a string
if (empty($string) || !\is_string($string)) {
return $retval;
}
// Trim spaces off the ends
$unspace = \trim($string);
// Only non-accented table names (avoid truncation)
$accents = remove_accents($unspace);
// Only lowercase letters are allowed
$lower = \strtolower($accents);
// Explode into parts
$parts = \explode($sep, $lower);
// Loop through parts and concatenate the first letters together
foreach ($parts as $part) {
$retval .= \substr($part, 0, 1);
}
// Return the result
return $retval;
}
/**
* Sanitize a table name string.
*
* Used to make sure that a table name value meets MySQL expectations.
*
* Applies the following formatting to a string:
* - Trim whitespace
* - No accents
* - No special characters
* - No hyphens
* - No double underscores
* - No trailing underscores
*
* @since 1.0.0
*
* @param string $name The name of the database table
*
* @return string Sanitized database table name
*/
protected function sanitize_table_name($name = '')
{
// Bail if empty or not a string
if (empty($name) || !\is_string($name)) {
return \false;
}
// Trim spaces off the ends
$unspace = \trim($name);
// Only non-accented table names (avoid truncation)
$accents = remove_accents($unspace);
// Only lowercase characters, hyphens, and dashes (avoid index corruption)
$lower = sanitize_key($accents);
// Replace hyphens with single underscores
$under = \str_replace('-', '_', $lower);
// Single underscores only
$single = \str_replace('__', '_', $under);
// Remove trailing underscores
$clean = \trim($single, '_');
// Bail if table name was garbaged
if (empty($clean)) {
return \false;
}
// Return the cleaned table name
return $clean;
}
/**
* Set class variables from arguments.
*
* @since 1.0.0
* @param array $args
*/
protected function set_vars($args = array())
{
// Bail if empty or not an array
if (empty($args)) {
return;
}
// Cast to an array
if (!\is_array($args)) {
$args = (array) $args;
}
// Set all properties
foreach ($args as $key => $value) {
$this->{$key} = $value;
}
}
/**
* Return the global database interface.
*
* See: https://core.trac.wordpress.org/ticket/31556
*
* @since 1.0.0
*
* @return \wpdb Database interface, or False if not set
*/
protected function get_db()
{
// Default database return value (might change)
$retval = \false;
// Look for a commonly used global database interface
if (isset($GLOBALS[$this->db_global])) {
$retval = $GLOBALS[$this->db_global];
}
/*
* Developer note:
*
* It should be impossible for a database table to be interacted with
* before the primary database interface is setup.
*
* However, because applications are complicated, it is unsafe to assume
* anything, so this silently returns false instead of halting everything.
*
* If you are here because this method is returning false for you, that
* means the database table is being invoked too early in the lifecycle
* of the application.
*
* In WordPress, that means before the $wpdb global is created; in other
* environments, you will need to adjust accordingly.
*/
// Return the database interface
return $retval;
}
/**
* Check if an operation succeeded.
*
* @since 1.0.0
*
* @param mixed $result
* @return bool
*/
protected function is_success($result = \false)
{
// Bail if no row exists
if (empty($result)) {
$retval = \false;
// Bail if an error occurred
} elseif (is_wp_error($result)) {
$this->last_error = $result;
$retval = \false;
// No errors
} else {
$retval = \true;
}
// Return the result
return (bool) $retval;
}
}