<?php
/**
* Squiloople Framework
*
* LICENSE: Feel free to use and redistribute this code.
*
* @author Michael Rushton <michael@squiloople.com>
* @link http://squiloople.com/
* @package Squiloople
* @version 1.0
* @copyright © 2012 Michael Rushton
*/
/**
* Paginator
*
* Create the pagination
*/
final class Paginator
{
/**
* The URL
*
* @access private
* @var string $_url
*/
private $_url;
/**
* The total number of results
*
* @access private
* @var integer $_total
*/
private $_total;
/**
* The page number
*
* @access private
* @var integer $_page
*/
private $_page;
/**
* The limit
*
* @access private
* @var integer $_limit
*/
private $_limit;
/**
* The total number of pages
*
* @access private
* @var integer $_pages
*/
private $_pages;
/**
* The offset
*
* @access private
* @var integer $_offset
*/
private $_offset;
/**
* Set the initial conditions
*
* @access public
* @param string $url
* @param integer $total
* @param integer $page
* @param integer $limit
*/
public function __construct($url, $total, $page, $limit)
{
// Set the URL
$this->_setURL($url);
// Set the total
$this->_setTotal($total);
// Set the page
$this->_setPage($page);
// Set the limit
$this->_setLimit($limit);
// Set the total number of pages
$this->_setTotalPages();
// Set the offset
$this->_setOffset();
}
/**
* Set the URL
*
* @access private
* @param string $url
*/
private function _setURL($url)
{
$this->_url = (string) $url;
}
/**
* Set the total number of results
*
* @access private
* @param integer $total
*/
private function _setTotal($total)
{
// Set the total to 0 if less than 0
if (($this->_total = (int) $total) < 0)
{
$this->_total = 0;
}
}
/**
* Get the total
*
* @access public
* @return integer
*/
public function getTotal()
{
return $this->_total;
}
/**
* Set the page
*
* @access private
* @param integer $page
*/
private function _setPage($page)
{
// Set the page to 1 if less than 1
if (($this->_page = (int) $page) < 1)
{
$this->_page = 1;
}
}
/**
* Get the page
*
* @access public
* @return integer
*/
public function getPage()
{
return $this->_page;
}
/**
* Set the limit
*
* @access private
* @param integer $limit
*/
private function _setLimit($limit)
{
// Set the limit to 10 if less than 1
if (($this->_limit = (int) $limit) < 1)
{
$this->_limit = 10;
}
}
/**
* Get the limit
*
* @access public
* @return integer
*/
public function getLimit()
{
return $this->_limit;
}
/**
* Set the offset
*
* @access private
*/
private function _setOffset()
{
$this->_offset = $this->_limit * ($this->_page - 1);
}
/**
* Get the offset
*
* @access public
* @return integer
*/
public function getOffset()
{
return $this->_offset;
}
/**
* Set the total number of pages
*
* @access private
*/
private function _setTotalPages()
{
// Set the page to the last if later than the last
if ($this->_page > $this->_pages = 0 != $this->_total ? ceil($this->_total / $this->_limit) : 1)
{
$this->_page = $this->_pages;
}
}
/**
* Get the total number of pages
*
* @access public
* @return integer
*/
public function getTotalPages()
{
return $this->_pages;
}
/**
* Get the limit options
*
* @access public
* @param array $options
* @param string $name
* @return string
*/
public function getLimitOptions(array $options = array(10, 25, 50, 100), $name = 'squiloople-pagination-limit')
{
// Include the limit if not already included
if (!in_array($this->_limit, $options))
{
array_push($options, $this->_limit);
}
// Sort the array
sort($options);
// Open the drop-down
$select[] = '<select name="' . $name . '">';
// Iterate over each option and add
foreach (array_unique($options) as $option)
{
$select[] = '<option value="' . $option . '" ' . ($this->_limit == $option ? 'selected' : '') . '>' . $option . '</option>';
}
// Close the drop-down
$select[] = '</select>';
// Return the limit options
return '<div class="squiloople-pagination-limit"><span>Results Per Page:</span> ' . implode(PHP_EOL, $select) . '</div>';
}
/**
* Get the information
*
* @access public
* @return string
*/
public function getInformation()
{
// Get the first result
$first = 0 != $this->_total ? $this->_offset + 1 : 0;
// Get the last result
if ($this->_total < $last = $this->_limit * $this->_page)
{
$last = $this->_total;
}
// Return the result information
return '<div class="squiloople-pagination-information">Results ' . number_format($first) . ' - ' . number_format($last) . ' of ' . number_format($this->_total) . '</div>';
}
/**
* Get the first page link
*
* @access private
* @return string
*/
private function _getFirstPageLink()
{
return '<li class="squiloople-pagination-active"><a href="' . $this->_url . '?page=1&limit=' . $this->_limit . '" title="First page">«</a></li>';
}
/**
* Get the previous page link
*
* @access private
* @return string
*/
private function _getPreviousPageLink()
{
return '<li class="squiloople-pagination-active"><a href="' . $this->_url . '?page=' . ($this->_page - 1) . '&limit=' . $this->_limit . '" title="Previous page">‹</a></li>';
}
/**
* Get the next page link
*
* @access private
* @return string
*/
private function _getNextPageLink()
{
return '<li class="squiloople-pagination-active"><a href="' . $this->_url . '?page=' . ($this->_page + 1) . '&limit=' . $this->_limit . '" title="Next page">›</a></li>';
}
/**
* Get the last page link
*
* @access private
* @return string
*/
private function _getLastPageLink()
{
return '<li class="squiloople-pagination-active"><a href="' . $this->_url . '?page=' . $this->_pages . '&limit=' . $this->_limit . '" title="Last page">»</a></li>';
}
/**
* Get the page link
*
* @access private
* @param integer $page
* @return string
*/
private function _getPageLink($page)
{
// Return an empty link if we're on the last page
if ($page == $this->_page)
{
return '<li class="squiloople-pagination-inactive">' . number_format($page) . '</li>';
}
// Return the link
return '<li class="squiloople-pagination-active"><a href="' . $this->_url . '?page=' . $page . '&limit=' . $this->_limit . '" title="Page ' . number_format($page) . '">' . number_format($page) . '</a></li>';
}
/**
* Get the pagination
*
* @access public
* @return string
*/
public function getPagination()
{
// If we only have one page then return an empty string
if (1 == $this->_pages)
{
return '';
}
// If we are not on the first page
if (1 != $this->_page)
{
// Add the first page link
$pages[] = $this->_getFirstPageLink();
// Add the previous page link
$pages[] = $this->_getPreviousPageLink();
// Add an empty page link
$pages[] = '<li class="squiloople-pagination-inactive"> </li>';
}
// Iterate over available pages
for ($i = 1; $i <= $this->_pages; ++$i)
{
// Determine what is to be added
switch (TRUE)
{
// If there are 7 or fewer pages
case ($this->_pages <= 7):
// If the page is the first, the one before the current, the current, the one after the current, or the last
case (in_array($i, array(1, $this->_page - 1, $this->_page, $this->_page + 1, $this->_pages))):
// If the page is at most the fifth and the current is at most the fourth
case ($i <= 5 && $this->_page < 5):
// If the page is at least the fifth-to-last and the current is at least the fourth-to-last
case ($i >= $this->_pages - 4 && $this->_page > $this->_pages - 4):
// Add the page link
$pages[] = $this->_getPageLink($i);
// Break
break;
// If the page is the second or the second-to-last
case (in_array($i, array(2, $this->_pages - 1))):
// Add the ellipsis
$pages[] = '<li class="squiloople-pagination-inactive">…</li>';
// Break
break;
}
}
// If we are not on the last page
if ($this->_pages != $this->_page)
{
// Add an empty page link
$pages[] = '<li class="squiloople-pagination-inactive"> </li>';
// Add the next page link
$pages[] = $this->_getNextPageLink();
// Add the last page link
$pages[] = $this->_getLastPageLink();
}
// Return the pagination
return '<ul class="squiloople-pagination">' . implode(PHP_EOL, $pages) . '</ul>';
}
}
No comments
<?php
/**
* Squiloople Framework
*
* LICENSE: Feel free to use and redistribute this code.
*
* @author Michael Rushton <michael@squiloople.com>
* @link http://squiloople.com/
* @package Squiloople
* @version 1.0
* @copyright © 2012 Michael Rushton
*/
/**
* Password Validator
*
* Hash, generate, or validate passwords
*/
final class PasswordValidator
{
/**
* The password
*
* @access private
* @var string $_password
*/
private $_password;
/**
* The salt
*
* @access private
* @var string $_salt
*/
private $_salt;
/**
* The pepper
*/
const PEPPER = 'Sz^3X6r[UyvV~2]_0stT}8 uY7RwZx4{q|Q91W5';
/**
* Set the password
*
* @access public
* @param string $password
*/
public function __construct($password = '')
{
$this->_password = $password;
}
/**
* Call the constructor fluently
*
* @access public
* @static
* @param string $password
* @return PasswordValidator
*/
public static function setPassword($password)
{
return new self($password);
}
/**
* Return the password
*
* @access public
* @return string
*/
public function getPassword()
{
return $this->_password;
}
/**
* Generate a random password
*
* @access public
* @return PasswordValidator
*/
public function randomizePassword()
{
// Randomize the password
$this->_password = substr($this->getSalt(TRUE), 0, 8);
// Reset the salt
$this->_salt = NULL;
// Return the PasswordValidator object
return $this;
}
/**
* The password must contain at least one letter of each case, one digit, and be between 8 and 39 characters inclusive in length
*
* @access public
* @param boolean|string $new
* @return integer
*/
public function isValid($new = FALSE)
{
return preg_match('/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[\x20-\x7E]{8,39}$/D', $new ?: $this->_password);
}
/**
* Set the salt
*
* @access public
* @param string $salt
* @return PasswordValidator
*/
public function setSalt($salt)
{
// Set the salt
$this->_salt = $salt;
// Return the PasswordValidator object
return $this;
}
/**
* Generate and return a salt
*
* @access public
* @param boolean $reset
* @return string
*/
public function getSalt($reset = FALSE)
{
// Return the salt if one has been set and a reset is not required
if (!$reset && isset($this->_salt))
{
return $this->_salt;
}
// Generate a random salt of 39 printable ASCII characters
for ($i = 1; $i <= 39; ++$i)
{
$salt[] = chr(mt_rand(32, 126));
}
// Return the random salt
return $this->_salt = implode($salt);
}
/**
* Return the pepper portion
*
* @access private
* @return string
*/
private function _getPepper()
{
return substr(self::PEPPER, 0, 39 - strlen($this->_password));
}
/**
* Hash the password
*
* @access private
* @return string
*/
private function _getHash()
{
return hash('sha384', $this->getSalt() . $this->_password . $this->_getPepper());
}
/**
* Hash the password using an HMAC-inspired hash
*
* @access public
* @return string
*/
public function getHash()
{
return hash('sha512', substr(strrev(self::PEPPER), 0, 20) . $this->_getHash());
}
}
No comments
This class is designed to be used with the MySQL Classes provided in an earlier post.
<?php
/**
* Squiloople Framework
*
* LICENSE: Feel free to use and redistribute this code.
*
* @author Michael Rushton <michael@squiloople.com>
* @link http://squiloople.com/
* @package Models
* @subpackage Databases
* @version 1.0
* @copyright © 2013 Michael Rushton
*/
/**
* Database
*
* Acts as a database for simple queries
*/
class Database
{
/**
* An instance of MySQLConnection
*
* @access protected
* @var MySQLConnection $_connection
*/
protected $_connection;
/**
* The database table
*
* @access private
* @var string $_table
*/
private $_table;
/**
* The indexes
*
* @access private
* @var array $_indexes
*/
private $_indexes = array();
/**
* The auto increment column
*
* @access private
* @var null|string $_auto_increment
*/
private $_auto_increment = NULL;
/**
* An array of the data
*
* @access protected
* @var array $_data
*/
protected $_data;
/**
* Store the connection object and set the initial data
*
* @access public
* @param string $table
* @param array $data
*/
public function __construct($table, array $data = array())
{
// Store the table name
$this->_table = $table;
// Store the connection
$this->_connection = MySQLConnection::connection();
// Get the unique indexes
$indexes = $this->_connection->prepareQuery("SHOW INDEX FROM `" . $table . "` WHERE Non_unique = 0", MySQLSelectStatement::STATEMENT)
->execute()->getAll();
// Iterate over each index
foreach ($indexes as $index)
{
// Create the key if it does not exist
if (!isset($this->_indexes[$key_name = $index->STATISTICS->Key_name]))
{
$this->_indexes[$key_name] = array();
}
// Store the key's column
$this->_indexes[$key_name][] = $index->STATISTICS->Column_name;
}
// Throw an exception if there is no primary key
if (empty($this->_indexes['PRIMARY']))
{
throw new Exception('Table `' . $table . '` has no primary key.');
}
// Get the auto increment column
$auto_increment = $this->_connection->prepareQuery("SHOW COLUMNS FROM `" . $table . "` WHERE Extra = 'auto_increment'", MySQLSelectStatement::STATEMENT)
->execute()->getOne();
// If there is an auto increment column then store it
if (0 != $auto_increment->getNumRows())
{
$this->_auto_increment = $auto_increment->COLUMNS->Field;
}
// Store the data
$this->_data = $data;
}
/**
* Insert a row with the given data
*
* @access public
*/
public function insert()
{
// Prepare the statement
$stmt = $this->_connection->prepareInsertStatement()
->addTable($this->_table);
// Execute the query
$stmt = $this->_executeQuery($stmt, __FUNCTION__);
// Store the new row's auto increment value if there is one
if (NULL != $this->_auto_increment)
{
$this->_data[$this->_auto_increment] = $stmt->getInsertID();
}
// Select the row
$this->select();
}
/**
* Delete the row with the given data
*
* @access public
*/
public function delete()
{
// Prepare the statement
$stmt = $this->_connection->prepareDeleteStatement()
->addTable($this->_table)
->setLimit(1);
// Iterate over each primary key
foreach ($this->_indexes['PRIMARY'] as $key)
{
// Throw an exception if the value has not been set
if (NULL == $this->$key)
{
throw new Exception('The primary key has not been set.');
}
}
// Execute the query
$this->_executeQuery($stmt, __FUNCTION__);
}
/**
* Update the row with the given data
*
* @access public
*/
public function update()
{
// Prepare the statement
$stmt = $this->_connection->prepareUpdateStatement()
->addTable($this->_table)
->setLimit(1);
// Iterate over each primary key
foreach ($this->_indexes['PRIMARY'] as $key)
{
// Throw an exception if the value has not been set
if (NULL == $this->$key)
{
throw new Exception('The primary key has not been set.');
}
}
// Execute the query
$this->_executeQuery($stmt, __FUNCTION__);
}
/**
* Select the row with the given data
*
* @access public
*/
public function select()
{
// Iterate over each index
foreach ($this->_indexes as $index)
{
// Set the unique index status to true
$unique = TRUE;
// Iterate over each column
foreach ($index as $column)
{
// If the column value has not been set
if (NULL == $this->$column)
{
// Set the unique index status to false
$unique = FALSE;
// Break out of the iteration
break;
}
}
// If a unique index has been set then break out of the iteration
if ($unique)
{
break;
}
}
// Throw an exception a unique index has not been set
if (!$unique)
{
throw new Exception('A unique key has not been set.');
}
// Prepare the select statement
$stmt = $this->_connection->prepareSelectStatement()
->addTable($this->_table, '*')
->setLimit(1);
// Get the result
$stmt = $this->_executeQuery($stmt, __FUNCTION__)->getOne();
// If there are results then store the data
if (0 != $stmt->getNumRows())
{
$this->_data = (array) current($stmt->getData());
}
// Otherwise if there is an auto increment column then unset it
elseif (NULL != $this->_auto_increment)
{
unset($this->_data[$this->_auto_increment]);
}
// Free the result
$stmt->freeResult();
}
/**
* Prepare, bind, and execute the query
*
* @access private
* @param MySQLStatement $stmt
* @param string $method
* @return object
*/
final private function _executeQuery(MySQLStatement $stmt, $method)
{
// Throw an exception if the data is empty
if (empty($this->_data))
{
throw new Exception('No data has been set.');
}
// Iterate over the data
foreach ($this->_data as $field => $value)
{
// Get the data type
switch (gettype($value))
{
// If an integer
case ('integer'):
$type = 'i';
break;
// Otherwise if a double
case ('double'):
$type = 'd';
break;
// Otherwise if a string
case ('string'):
$type = 's';
break;
// Otherwise if null
case ('NULL'):
$type = NULL;
break;
// Default
default:
continue 2;
}
// Store the parameter if not null
if (NULL != $type)
{
$parameters[$field] = $value;
}
// If the parent method is not "insert"
if ('insert' != $method)
{
// Iterate over each index
foreach ($this->_indexes as $key => $index)
{
// If the parent method is "select" or the key is primary
if ('select' == $method || 'PRIMARY' == $key)
{
// If the field is an index
if (in_array($field, $index))
{
// If the value is not null
if (NULL != $type)
{
$stmt->addWhere('`' . $field . '` = ' . $type . ':' . $field);
}
// Otherwise
else
{
$stmt->addWhere('`' . $field . '` IS NULL');
}
}
}
}
}
// Add a SET clause if the parent method is "insert" or if it is "update" and the field is not a primary key
if ('insert' == $method || ('update' == $method && !isset($this->_indexes['PRIMARY'][$field])))
{
// If not NULL
if (NULL != $type)
{
$stmt->addValue($field, $type . ':' . $field);
}
// Otherwise
else
{
$stmt->addValue($field, 'NULL');
}
}
}
// Set the parameters, execute the statement, and return the object
return $stmt->setParameters($parameters)->execute();
}
/**
* Set the field data
*
* @access public
* @param string $field
* @param mixed $value
*/
final public function __set($field, $value)
{
$this->_data[$field] = $value;
}
/**
* Get the field data
*
* @access public
* @param string $field
* @return mixed
*/
final public function __get($field)
{
return isset($this->_data[$field]) ? $this->_data[$field] : NULL;
}
/**
* Set all the field data
*
* @access public
* @param array $data
*/
final public function setData(array $data)
{
$this->_data = $data;
}
/**
* Get all the field data
*
* @access public
* @return array
*/
final public function getData()
{
return $this->_data;
}
/**
* Clear all the field data
*
* @access public
*/
final public function clearData()
{
$this->_data = array();
}
}
No comments
<?php
/**
* Squiloople Framework
*
* LICENSE: Feel free to use and redistribute this code.
*
* @author Michael Rushton <michael@squiloople.com>
* @link http://squiloople.com/
* @package Squiloople
* @version 1.0
* @copyright © 2012 Michael Rushton
*/
/**
* BBCode Parser
*
* Parses BBCode in a string
*/
final class BBCodeParser
{
/**
* Array to contain regular expressions of BB tags
*
* @access private
* @var array $_bb_tags
*/
private $_bb_tags = array(
'/\[b\]([\x20-\x7E]+?)\[\/b\]/i',
'/\[i\]([\x20-\x7E]+?)\[\/i\]/i',
'/\[u\]([\x20-\x7E]+?)\[\/u\]/i',
'/\[s\]([\x20-\x7E]+?)\[\/s\]/i',
'/\[sub\]([\x20-\x7E]+?)\[\/sub\]/i',
'/\[sup\]([\x20-\x7E]+?)\[\/sup\]/i',
'/\[img\]([\x20-\x7E]+?)\[\/img\]/i',
'/\[url\]([\x20-\x7E]+?)\[\/url\]/i',
'/\[email\]([\x20-\x7E]+?)\[\/email\]/i',
'/\[quote\]([\x20-\x7E]+?)\[\/quote\]/i',
'/\[color=([0-9a-f]{6})\]([\x20-\x7E]+?)\[\/color\]/i',
'/\[size=([1-9]?[0-9])\]([\x20-\x7E]+?)\[\/size\]/i',
'/\[font=([a-z\x20]+)\]([\x20-\x7E]+?)\[\/font\]/i',
'/\[img=([\x20-\x7E]+?)\]([\x20-\x7E]+?)\[\/img\]/i',
'/\[url=([\x20-\x5A\x5C\x5E-\x7E]+)\]([\x20-\x7E]+?)\[\/url\]/i',
'/\[email=([\x20-\x5A\x5C\x5E-\x7E]+)\]([\x20-\x7E]+?)\[\/email\]/i',
'/\[quote=([\x20-\x5A\x5C\x5E-\x7E]+)\]([\x20-\x7E]+?)\[\/quote\]/i',
);
/**
* Array to contain HTML tag replacements
*
* @access private
* @var array $_html_tags
*/
private $_html_tags = array(
'<strong>$1</strong>',
'<em>$1</em>',
'<span style="text-decoration: underline;">$1</span>',
'<del>$1</del>',
'<sub>$1</sub>',
'<sup>$1</sup>',
'<img src="$1" alt="" />',
'<a href="$1">$1</a>',
'<a href="mailto:$1">$1</a>',
'<fieldset>$1</fieldset>',
'<span style="color: #$1; background-color: transparent;">$2</span>',
'<span style="font-size: $1px;">$2</span>',
'<span style="font-family: \'$1\', sans-serif;">$2</span>',
'<img src="$2" alt="$1" />',
'<a href="$1">$2</a>',
'<a href="mailto:$1">$2</a>',
'<fieldset><legend>$1</legend>$2</fieldset>',
);
/**
* Create "[tag]Text[/tag] => <tag>Text</tag>" style BB tags
*
* @access public
* @param string $bb_tag
* @param string|boolean $html_tag
* @return BBCodeParser
*/
public function createTag($bb_tag, $html_tag = FALSE)
{
// Emulate the BB tag if an HTML tag has not been specified
$html_tag = $html_tag ?: $bb_tag;
// Create a new BB tag regular expression of the form: [tag]Text[/tag]
$this->_bb_tags[] = '/\[' . $bb_tag. '\]([\x20-\x7E]+?)\[\/' . $bb_tag . '\]/i';
// Create a new HTML tag replacement of the form <tag>Text</tag>
$this->_html_tags[] = '<' . $html_tag . '>$1</' . strtok($html_tag, ' ') . '>';
// Return the BBCodeParser object
return $this;
}
/**
* Create "[tag=option]Text[/tag] => <tag option="option">Text</tag>" style BB tags
*
* @access public
* @param string $bb_tag
* @param string $html_tag
* @return BBCodeParser
*/
public function createParameterTag($bb_tag)
{
// Create a new BB tag regular expression of the form [tag=option]Text[/tag]
$this->_bb_tags[] = '/\[' . $bb_tag . '=([\x20-\x5A\x5C\x5E-\x7E]+)\]([\x20-\x7E]+?)\[\/' . $bb_tag . '\]/i';
// Create a new HTML tag replacement of the form <tag option="option">Text</tag>
$this->_html_tags[] = '<' . $html_tag . '>$2</' . strtok($html_tag, ' ') . '>';
// Return the BBCodeParser object
return $this;
}
/**
* Create "[smile] => :)" style BB tags
*
* @access public
* @param string $bb_tag
* @param string $html_tag
* @return BBCodeParser
*/
public function createSpecialTag($bb_tag, $html_tag)
{
// Create a new BB tag regular expression of the form [tag] (does not require usual brackets)
$this->_bb_tags[] = '/' . preg_quote($bb_tag) . '/i';
// Create a new replacement (does not need to be an HTML tag)
$this->_html_tags[] = $html_tag;
// Return the BBCodeParser object
return $this;
}
/**
* Return the parsed string
*
* @access public
* @param string $string
* @return string
*/
public function parseString($string)
{
// Only replace tags if the string has not been fully parsed
for ($count = 1; $count != 0;)
{
$string = preg_replace($this->_bb_tags, $this->_html_tags, $string, -1, $count);
}
// Return the parsed string
return $string;
}
}
No comments
MySQL Connection
<?php
/**
* Squiloople Framework
*
* LICENSE: Feel free to use and redistribute this code.
*
* @author Michael Rushton <michael@squiloople.com>
* @link http://squiloople.com/
* @package Squiloople
* @version 1.0
* @copyright © 2012 Michael Rushton
*/
/**
* MySQLConnection
*
* Control a MySQL connection
*/
final class MySQLConnection
{
/**
* An instance of the class
*
* @access private
* @static
* @var MySQLConnection $_instance
*/
private static $_instance;
/**
* The mysqli connection resource
*
* @access private
* @var mysqli $_connection
*/
private $_connection;
/**
* Try to connect to the server
*
* @access private
* @param array $connect
*/
private function __construct(array $connect)
{
// Throw an exception if a connection cannot be made
if (!$this->_connection = call_user_func_array('mysqli_connect', $connect))
{
throw new MySQLException($this->getConnectError());
}
}
/**
* Create and/or return an instance of the object
*
* @access public
* @static
* @param string $hostname
* @param string $username
* @param string $password
* @param string $database
* @return MySQLConnection
*/
public static function connection()
{
// Instantiate the object if one does not exist
if (!isset(self::$_instance))
{
self::$_instance = new self(func_get_args());
}
// Return the MySQLConnection instance
return self::$_instance;
}
/**
* Return the connection
*
* @access public
* @return mysqli|boolean
*/
public function getConnection()
{
return $this->_connection;
}
/**
* Select the database
*
* @access public
* @param string $database
* @return MySQLConnection
*/
public function setDatabase($database)
{
// Throw an exception if the database cannot be selected
if (!$this->_connection->select_db($database))
{
throw new MySQLException($this->getError());
}
// Return the MySQLConnection instance
return $this;
}
/**
* Prepare the query
*
* @access public
* @param string $query
* @param string $result
* @param array $vars
* @return object
*/
public function prepareQuery($query, $result = '', array $vars = array())
{
// Store all the matches to be used for bound parameters
preg_match_all('/[idsb]:[a-zA-Z0-9_]+/', $query, $refs);
// Throw an exception if the re-formatted query cannot be prepared
if (!$stmt = $this->_connection->prepare(preg_replace('/[idsb]:[a-zA-Z0-9_]+/', '?', $query)))
{
throw new MySQLException($this->getError());
}
// Set the relevant MySQL result class name
$class = 'MySQL' . ucfirst(strtolower($result)) . 'Result';
// Instantiate and return the object
return new $class($stmt, $refs[0], $vars);
}
/**
* Prepare an INSERT statement
*
* @access public
* @return MySQLInsertStatement
*/
public function prepareInsertStatement()
{
return new MySQLInsertStatement;
}
/**
* Prepare a DELETE statement
*
* @access public
* @return MySQLDeleteStatement
*/
public function prepareDeleteStatement()
{
return new MySQLDeleteStatement;
}
/**
* Prepare an UPDATE statement
*
* @access public
* @return MySQLUpdateStatement
*/
public function prepareUpdateStatement()
{
return new MySQLUpdateStatement;
}
/**
* Prepare a SELECT statement
*
* @access public
* @return MySQLSelectStatement
*/
public function prepareSelectStatement()
{
return new MySQLSelectStatement;
}
/**
* Return the connection errno
*
* @access public
* @return integer
*/
public function getConnectErrno()
{
return mysqli_connect_errno();
}
/**
* Return the connection error
*
* @access public
* @return string
*/
public function getConnectError()
{
return mysqli_connect_error();
}
/**
* Return the error
*
* @access public
* @return integer
*/
public function getErrno()
{
return $this->_connection->errno;
}
/**
* Return the error
*
* @access public
* @return string
*/
public function getError()
{
return $this->_connection->error;
}
/**
* Disconnect from the server
*
* @access public
*/
public function disconnect()
{
// Throw an exception if the server connection cannot be closed
if (!$this->_connection->close())
{
throw new MySQLException($this->getError());
}
// Destroy the instance
self::$_instance = NULL;
}
/**
* Throw an exception if a clone is attempted
*
* @access public
*/
public function __clone()
{
throw new Exception('Attempt to clone MySQLConnection instance.');
}
/**
* Disconnect from the server
*
* @access public
*/
public function __destruct()
{
$this->disconnect();
}
}
2 comments
An IP address is one of an IPv4 address, an IPv6 address, or an IPv4-mapped IPv6 address.
An IPv4 address consists of four groups, separated by dots, each containing a decimal value between 0 and 255. A regular expression to match for an IPv4 address is as follows:
// IPv4 address
'/^(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)(?>\.(?1)){3}$/D'
1 comment
Email addresses have a local-part and a domain separated by an (unquoted) “@” symbol. The local-part must be either a dot-atom or a quoted string, and the domain must be either a domain name or a domain literal.
A dot-atom may only contain letters, numbers, dots, and the following characters: ! # $ % & ‘ * + – / = ? ^ _ ` { | } ~. However, neither the first nor the last character can be a dot, and two or more consecutive dots are not allowed. The maximum length of a dot-atom is 64 characters. A regular expression to match for a dot-atom local-part is as follows:
// Dot-atom
"/^(?!.{65,})([!#-'*+\/-9=?^-~-]+)(?>\.(?1))*$/iD"
30 comments