rename p2
This commit is contained in:
380
classes/config.php
Normal file
380
classes/config.php
Normal file
@ -0,0 +1,380 @@
|
||||
<?php
|
||||
/**
|
||||
* classes/config.php
|
||||
*
|
||||
* This class handles all the hard-coded configurations.
|
||||
*
|
||||
* @version 1.1.2
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com/libraries/Bedrock
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject\Bedrock\Classes;
|
||||
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Bedrock\Functions\Input;
|
||||
use TheTempusProject\Bedrock\Functions\Upload;
|
||||
|
||||
class Config {
|
||||
public static $config = false;
|
||||
private static $location = false;
|
||||
private static $initialized = false;
|
||||
|
||||
/**
|
||||
* Default constructor which will attempt to load the config from the location specified.
|
||||
*
|
||||
* @param {string} [$location]
|
||||
* @return {null|object}
|
||||
*/
|
||||
public function __construct( $location = '' ) {
|
||||
if ( self::$initialized !== false ) {
|
||||
Debug::log( 'Config already initialized.' );
|
||||
return $this;
|
||||
}
|
||||
if ( empty( $location ) ) {
|
||||
$location = CONFIG_JSON;
|
||||
}
|
||||
self::$initialized = $this->load( $location );
|
||||
if ( self::$initialized !== false ) {
|
||||
Debug::log( 'Config initialization succeeded.' );
|
||||
return $this;
|
||||
}
|
||||
Debug::warn( 'Config initialization failed.' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to retrieve then set the configuration from a file.
|
||||
* @note This function will reset the config every time it is used.
|
||||
*
|
||||
* @param {string} $location
|
||||
* @return {bool}
|
||||
*/
|
||||
public function load( $location ) {
|
||||
self::$config = $this->getConfigFile( $location );
|
||||
self::$location = $location;
|
||||
if ( self::$config === false || empty( self::$config ) ) {
|
||||
Debug::warn( 'Config load failed.' );
|
||||
return false;
|
||||
}
|
||||
Debug::log( 'Config load succeeded.' );
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens and decodes the config json from the location provided.
|
||||
*
|
||||
* @param {string} [$location]
|
||||
* @return {bool|array}
|
||||
*/
|
||||
public function getConfigFile( $location ) {
|
||||
if ( file_exists( $location ) ) {
|
||||
Debug::debug( "Config json found: $location" );
|
||||
return json_decode( file_get_contents( $location ), true );
|
||||
} else {
|
||||
Debug::warn( "Config json not found: $location" );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new config option for the specified category.
|
||||
*
|
||||
* NOTE: Use a default option when using this function to
|
||||
* aid in fail safe execution.
|
||||
*
|
||||
* @param {string} [$category] - The primary category to add the option to.
|
||||
* @param {string} [$node] - The name of the new option.
|
||||
* @param {wild} [$value] - The desired value for the new option.
|
||||
* @param {bool} [$createMissing] - Whether or not to create missing options.
|
||||
* @param {bool} [$save] - Whether or not to save the config.
|
||||
* @param {bool} [$saveDefault] - Whether or not to save the default config.
|
||||
* @return {bool}
|
||||
*/
|
||||
public function update( $category, $node, $value, $createMissing = false, $save = false, $saveDefault = false ) {
|
||||
// @todo: createMissing is unused here
|
||||
if ( self::$config === false ) {
|
||||
Debug::warn( 'Config not loaded.' );
|
||||
return false;
|
||||
}
|
||||
if ( !Check::simpleName( $category ) ) {
|
||||
Debug::warn( "Category name invalid: $categoryName" );
|
||||
return false;
|
||||
}
|
||||
if ( !isset( self::$config[$category] ) ) {
|
||||
Debug::warn( "No such category: $category" );
|
||||
return false;
|
||||
}
|
||||
if ( !Check::simpleName( $node ) ) {
|
||||
Debug::warn( "Node name invalid: $categoryName" );
|
||||
return false;
|
||||
}
|
||||
if ( !isset( self::$config[$category][$node] ) ) {
|
||||
Debug::warn( 'Config not found.' );
|
||||
return false;
|
||||
}
|
||||
if ( $value === 'true' ) {
|
||||
$value = true;
|
||||
}
|
||||
if ( $value === 'false' ) {
|
||||
$value = false;
|
||||
}
|
||||
self::$config[$category][$node]['value'] = $value;
|
||||
if ( $save ) {
|
||||
$this->save( $saveDefault );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function updateFromForm( $save = false, $saveDefault = false ) {
|
||||
if ( self::$config === false ) {
|
||||
Debug::warn( 'Config not loaded.' );
|
||||
return;
|
||||
}
|
||||
foreach ( self::$config as $category => $fields ) {
|
||||
if ( empty( self::$config[ $category ] ) ) {
|
||||
Debug::warn( "Config category not found: $category" );
|
||||
continue;
|
||||
}
|
||||
foreach ( self::$config[ $category ] as $field => $node ) {
|
||||
$name = $category . '/' . $field;
|
||||
if ( empty( $node ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( !empty( $node['protected'] ) ) {
|
||||
continue;
|
||||
}
|
||||
$fieldname = str_ireplace( '/', '-', $name );
|
||||
if ( Input::exists( $fieldname ) ) {
|
||||
if ( 'file' == $node['type'] ) {
|
||||
$upload = Upload::image( $fieldname, IMAGE_DIRECTORY );
|
||||
if ( $upload ) {
|
||||
$route = str_replace( APP_ROOT_DIRECTORY, '', IMAGE_DIRECTORY );
|
||||
$this->update( $category, $field, $route . Upload::last() );
|
||||
} else {
|
||||
Debug::error( 'There was an error with your upload.');
|
||||
}
|
||||
} else {
|
||||
$this->update( $category, $field, Input::post( $fieldname ) );
|
||||
}
|
||||
} elseif ( 'radio' == $node['type'] ) {
|
||||
$this->update( $category, $field, false );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( $save ) {
|
||||
return $this->save( $saveDefault );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the current config.
|
||||
*
|
||||
* @param {bool} [$default] - Whether or not to save a default copy.
|
||||
* @return {bool}
|
||||
*/
|
||||
public function save( $default = false ) {
|
||||
if ( self::$config === false ) {
|
||||
Debug::warn( 'Config not loaded.' );
|
||||
return false;
|
||||
}
|
||||
if ( self::$location === false ) {
|
||||
Debug::warn( 'Config location not set.' );
|
||||
return false;
|
||||
}
|
||||
if ( $default ) {
|
||||
$locationArray = explode( '.', self::$location );
|
||||
$locationArray[] = 'bak';
|
||||
$backupLoction = implode( '.', $locationArray );
|
||||
if ( !file_put_contents( $backupLoction, json_encode( self::$config ) ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ( file_put_contents( self::$location, json_encode( self::$config ) ) ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new category to the $config array.
|
||||
*
|
||||
* @param {string} [$categoryName]
|
||||
* @return {bool}
|
||||
*/
|
||||
public function addCategory( $categoryName ) {
|
||||
if ( self::$config === false ) {
|
||||
self::$config = [];
|
||||
}
|
||||
if ( !Check::simpleName( $categoryName ) ) {
|
||||
Debug::warn( "Category name invalid: $categoryName" );
|
||||
return false;
|
||||
}
|
||||
if ( isset( self::$config[$categoryName] ) ) {
|
||||
Debug::warn( "Category already exists: $categoryName" );
|
||||
return false;
|
||||
}
|
||||
self::$config[$categoryName] = [];
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an existing category from the $config array.
|
||||
*
|
||||
* @param {string} [$categoryName]
|
||||
* @param {string} [$save]
|
||||
* @return {bool}
|
||||
*/
|
||||
public function removeCategory( $categoryName, $save = false, $saveDefault = true ) {
|
||||
if ( self::$config === false ) {
|
||||
Debug::warn( 'Config not loaded.' );
|
||||
return;
|
||||
}
|
||||
if ( !isset( self::$config[$categoryName] ) ) {
|
||||
Debug::warn( "Config does not have category: $categoryName" );
|
||||
return true;
|
||||
}
|
||||
unset( self::$config[$categoryName] );
|
||||
if ( $save ) {
|
||||
$this->save( $saveDefault );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new config node for the specified category.
|
||||
*
|
||||
* @param {string} [$category] - The primary category to add the option to.
|
||||
* @param {string} [$node] - The name of the new option.
|
||||
* @param {wild} [$value] - The desired value for the new option.
|
||||
* @return {bool}
|
||||
*/
|
||||
public function add( $category, $node, $details, $updateExisting = false ) {
|
||||
if ( self::$config === false ) {
|
||||
Debug::warn( 'Config not loaded.' );
|
||||
return false;
|
||||
}
|
||||
if ( !Check::simpleName( $category ) ) {
|
||||
Debug::warn( "Category name invalid: $category" );
|
||||
return false;
|
||||
}
|
||||
if ( !isset( self::$config[$category] ) ) {
|
||||
Debug::warn( "No such category: $category" );
|
||||
return false;
|
||||
}
|
||||
if ( !Check::simpleName( $node ) ) {
|
||||
Debug::warn( "Category Node name invalid: $node" );
|
||||
return false;
|
||||
}
|
||||
if ( isset( self::$config[$category][$node] ) ) {
|
||||
if ( $updateExisting ) {
|
||||
$details = array_replace(self::$config[$category][$node], $details );
|
||||
} else {
|
||||
Debug::warn( "Config already exists: $node" );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ( !isset( $details['value'] ) ) {
|
||||
$details['value'] = $details['default'];
|
||||
}
|
||||
self::$config[$category][$node] = $details;
|
||||
return true;
|
||||
}
|
||||
|
||||
public function generate( $location, $mods = [] ) {
|
||||
self::$location = $location;
|
||||
if ( !empty( $mods ) ) {
|
||||
foreach ( $mods as $category => $node ) {
|
||||
$this->addCategory( $category );
|
||||
foreach ( $node as $name => $details ) {
|
||||
$this->add( $category, $name, $details, true );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( $this->save( true ) ) {
|
||||
Debug::info( 'config file generated successfully.' );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the config option for $name.
|
||||
*
|
||||
* @param {string} [$name] - Must be in <category>/<option> format.
|
||||
* @return {WILD}
|
||||
*/
|
||||
public static function get( $name ) {
|
||||
$data = explode( '/', $name );
|
||||
if ( count( $data ) != 2 ) {
|
||||
Debug::warn( "Config not properly formatted: $name" );
|
||||
return;
|
||||
}
|
||||
if ( self::$config === false ) {
|
||||
Debug::warn( 'Config not loaded.' );
|
||||
return;
|
||||
}
|
||||
$category = $data[0];
|
||||
$field = $data[1];
|
||||
if ( !isset( self::$config[$category][$field] ) ) {
|
||||
Debug::warn( "Config not found: $name" );
|
||||
return;
|
||||
}
|
||||
$node = self::$config[$category][$field];
|
||||
if ( !isset( $node['type'] ) ) {
|
||||
$node['type'] = 'text';
|
||||
}
|
||||
if ( !isset( $node['pretty'] ) ) {
|
||||
$node['pretty'] = $node;
|
||||
}
|
||||
if ( !isset( $node['default'] ) ) {
|
||||
$node['default'] = '';
|
||||
}
|
||||
if ( !isset( $node['value'] ) ) {
|
||||
$node['value'] = $node['default'];
|
||||
}
|
||||
if ( !isset( $node['protected'] ) ) {
|
||||
$node['protected'] = false;
|
||||
}
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the config option for $name and if the result is bool, converts it to a string.
|
||||
*
|
||||
* @param {string} [$name] - Must be in <category>/<option> format.
|
||||
* @return {WILD}
|
||||
*/
|
||||
public static function getString( $name ) {
|
||||
$result = self::getValue( $name );
|
||||
if ( is_bool( $result ) ) {
|
||||
$result = ( $result ? 'true' : 'false' );
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function getValue( $name ) {
|
||||
$node = self::get( $name );
|
||||
if ( empty( $node ) ) {
|
||||
return;
|
||||
}
|
||||
if ( !isset( $node['value'] ) ) {
|
||||
Debug::warn( 'Node Value not set.' );
|
||||
return;
|
||||
}
|
||||
return $node['value'];
|
||||
}
|
||||
|
||||
public static function getDefault( $name ) {
|
||||
$node = self::get( $name );
|
||||
if ( empty( $node ) ) {
|
||||
return;
|
||||
}
|
||||
if ( !isset( $node['default'] ) ) {
|
||||
Debug::warn( 'Node default not set.' );
|
||||
return;
|
||||
}
|
||||
return $node['default'];
|
||||
}
|
||||
}
|
56
classes/controller.php
Normal file
56
classes/controller.php
Normal file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/**
|
||||
* classes/controller.php
|
||||
*
|
||||
* The controller handles our main template and provides the
|
||||
* model and view functions which are the backbone of the tempus
|
||||
* project. Used to hold and keep track of many of the variables
|
||||
* that support the applications execution.
|
||||
*
|
||||
* @version 1.1.2
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com/libraries/Bedrock
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject\Bedrock\Classes;
|
||||
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
use TheTempusProject\Bedrock\Functions\Session;
|
||||
use TheTempusProject\Houdini\Classes\Issues;
|
||||
|
||||
class Controller {
|
||||
public static $title = null;
|
||||
public static $pageDescription = null;
|
||||
public static $template = null;
|
||||
|
||||
/**
|
||||
* Check for issues stored in sessions and add them to current issues.
|
||||
*/
|
||||
public static function checkSessions() {
|
||||
$success = Session::checkFlash( 'success' );
|
||||
$notice = Session::checkFlash( 'notice' );
|
||||
$error = Session::checkFlash( 'error' );
|
||||
$info = Session::checkFlash( 'info' );
|
||||
if ( !empty( $success ) ) {
|
||||
Issues::add( 'success', $success );
|
||||
}
|
||||
if ( !empty( $notice ) ) {
|
||||
Issues::add( 'notice', $notice );
|
||||
}
|
||||
if ( !empty( $error ) ) {
|
||||
Issues::add( 'error', $error );
|
||||
}
|
||||
if ( !empty( $info ) ) {
|
||||
Issues::add( 'info', $info );
|
||||
}
|
||||
}
|
||||
|
||||
public function __construct() {
|
||||
Debug::log( 'Controller Constructing: ' . get_class( $this ) );
|
||||
self::checkSessions();
|
||||
}
|
||||
|
||||
public function __destruct() {
|
||||
Debug::log( 'Controller Destructing: ' . get_class( $this ) );
|
||||
}
|
||||
}
|
764
classes/database.php
Normal file
764
classes/database.php
Normal file
@ -0,0 +1,764 @@
|
||||
<?php
|
||||
/**
|
||||
* classes/database.php
|
||||
*
|
||||
* Defines all interactions with the database.
|
||||
*
|
||||
* @todo - Add more than just MySQL
|
||||
*
|
||||
* @version 1.1.2
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com/libraries/Bedrock
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject\Bedrock\Classes;
|
||||
|
||||
use PDO;
|
||||
use PDOException;
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
use TheTempusProject\Canary\Classes\CustomException;
|
||||
|
||||
class Database {
|
||||
public static $instance = null;
|
||||
private $pdo = null;
|
||||
private $query = null;
|
||||
private $error = false;
|
||||
private $results = null;
|
||||
private $count = 0;
|
||||
private $maxQuery = 0;
|
||||
private $totalResults = 0;
|
||||
private $errorMessage = null;
|
||||
private $tableBuff = null;
|
||||
private $fieldBuff = null;
|
||||
private $queryStatus = false;
|
||||
|
||||
/**
|
||||
* Checks the DB connection with the provided information.
|
||||
*
|
||||
* @param string $host - Database Host.
|
||||
* @param string $db - Database Name.
|
||||
* @param string $user - Database Username.
|
||||
* @param string $pass - Database Password.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function check( $host = null, $db = null, $user = null, $pass = null ) {
|
||||
if ( empty( $host ) || empty( $db ) || empty( $user ) || empty( $pass ) ) {
|
||||
Debug::error( 'check::db: one or more parameters are missing.' );
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
Debug::log( 'Attempting to connect to DB with supplied credentials.' );
|
||||
$test = new PDO( 'mysql:host=' . $host . ';dbname=' . $db, $user, $pass );
|
||||
} catch ( PDOException $Exception ) {
|
||||
Debug::error( 'Cannot connect to DB with provided credentials: ' . $Exception->getMessage() );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the current database in the configuration file for version verification.
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @todo - Update this function to be more effective.
|
||||
*/
|
||||
public static function mysql() {
|
||||
self::connect();
|
||||
$dbVersion = self::$db->version();
|
||||
preg_match( '@[0-9]+\.[0-9]+\.[0-9]+@', $dbVersion, $version );
|
||||
if ( version_compare( $version[0], '10.0.0', '>' ) ) {
|
||||
return true;
|
||||
}
|
||||
self::addError( "MySQL Version is too low! Current version is $version[0]. Version 10.0.0 or higher is required." );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatically open the DB connection with settings from our global config.
|
||||
*/
|
||||
private function __construct( $host = null, $name = null, $user = null, $pass = null ) {
|
||||
Debug::debug( 'Class initialized: ' . get_class( $this ) );
|
||||
if ( isset( $host ) && isset( $name ) && isset( $user ) && isset( $pass ) ) {
|
||||
try {
|
||||
Debug::log( 'Attempting to connect to DB with supplied credentials.' );
|
||||
$this->pdo = new PDO( 'mysql:host=' . $host . ';dbname=' . $name, $user, $pass );
|
||||
} catch ( PDOException $Exception ) {
|
||||
$this->error = true;
|
||||
$this->errorMessage = $Exception->getMessage();
|
||||
}
|
||||
}
|
||||
if ( !$this->enabled() ) {
|
||||
$this->error = true;
|
||||
$this->errorMessage = 'Database disabled in config.';
|
||||
}
|
||||
if ( $this->error === false ) {
|
||||
try {
|
||||
Debug::debug( 'Attempting to connect to DB with config credentials.' );
|
||||
$this->pdo = new PDO( 'mysql:host=' . Config::getValue( 'database/dbHost' ) . ';dbname=' . Config::getValue( 'database/dbName' ), Config::getValue( 'database/dbUsername' ), Config::getValue( 'database/dbPassword' ) );
|
||||
} catch ( PDOException $Exception ) {
|
||||
$this->error = true;
|
||||
$this->errorMessage = $Exception->getMessage();
|
||||
}
|
||||
}
|
||||
if ( $this->error !== false ) {
|
||||
new CustomException( 'dbConnection', $this->errorMessage );
|
||||
return;
|
||||
}
|
||||
$this->maxQuery = Config::getValue( 'database/dbMaxQuery' );
|
||||
// @TODO add a toggle for this
|
||||
$this->pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
|
||||
Debug::debug( 'DB connection successful' );
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the DB is enabled via the config file.
|
||||
*
|
||||
* @return bool - whether the db module is enabled or not.
|
||||
*/
|
||||
public function enabled( $type = '' ) {
|
||||
if ( Config::getValue( 'database/dbEnabled' ) === true ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function lastId() {
|
||||
return $this->pdo->lastInsertId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if there is already a DB instance open, and if not; create one.
|
||||
*
|
||||
* @return function - Returns the PDO DB connection.
|
||||
*/
|
||||
public static function getInstance( $host = null, $name = null, $user = null, $pass = null, $new = false ) {
|
||||
// used to force a new connection
|
||||
if ( !empty( $host ) && !empty( $name ) && !empty( $user ) && !empty( $pass ) ) {
|
||||
self::$instance = new self( $host, $name, $user, $pass );
|
||||
}
|
||||
if ( empty( self::$instance ) || $new ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the DB version.
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
public function version() {
|
||||
if ( !$this->enabled() ) {
|
||||
$this->error = true;
|
||||
$this->errorMessage = 'Database disabled';
|
||||
return false;
|
||||
}
|
||||
$sql = 'select version()';
|
||||
if ( $this->query = $this->pdo->prepare( $sql ) ) {
|
||||
try {
|
||||
$this->query->execute();
|
||||
} catch ( PDOException $Exception ) {
|
||||
$this->error = true;
|
||||
$this->errorMessage = $Exception->getMessage();
|
||||
Debug::error( 'DB Version Error' );
|
||||
Debug::error( $this->errorMessage );
|
||||
return false;
|
||||
}
|
||||
return $this->query->fetchColumn();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the database to see if the specified table exists.
|
||||
*
|
||||
* @param string $name - The name of the table to check for.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
protected function tableExists( $name ) {
|
||||
$name = Config::getValue( 'database/dbPrefix' ) . $name;
|
||||
$this->raw( "SHOW TABLES LIKE '$name'" );
|
||||
if ( $this->error ) {
|
||||
Debug::error( var_export( $this->errorMessage, true ) );
|
||||
return false;
|
||||
}
|
||||
if ( $this->count === 0 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks first that the table exists, then checks if the specified
|
||||
* column exists in the table.
|
||||
*
|
||||
* @param string $table - The table to search.
|
||||
* @param string $column - The column to look for.
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @todo - Is it necessary to check the current $fields list too?
|
||||
*/
|
||||
protected function columnExists( $table, $column ) {
|
||||
if ( !$this->tableExists( $table ) ) {
|
||||
return false;
|
||||
}
|
||||
$table = Config::getValue( 'database/dbPrefix' ) . $table;
|
||||
$this->raw( "SHOW COLUMNS FROM `$table` LIKE '$column'" );
|
||||
if ( !$this->error && $this->count === 0 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a raw DB query.
|
||||
*
|
||||
* @param string $data the query to execute
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function raw( $data ) {
|
||||
$this->queryReset();
|
||||
if ( !$this->enabled() ) {
|
||||
$this->error = true;
|
||||
$this->errorMessage = 'Database disabled';
|
||||
return false;
|
||||
}
|
||||
$this->query = $this->pdo->prepare( $data );
|
||||
try {
|
||||
$this->query->execute();
|
||||
} catch ( PDOException $Exception ) {
|
||||
$this->error = true;
|
||||
$this->errorMessage = $Exception->getMessage();
|
||||
Debug::warn( 'DB Raw Query Error' );
|
||||
Debug::warn( $this->errorMessage );
|
||||
return false;
|
||||
}
|
||||
// @todo i think this will cause an error some circumstances
|
||||
$this->count = $this->query->rowCount();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* The actual Query function. This function takes our setup queries
|
||||
* and send them to the database. it then properly sets our instance
|
||||
* variables with the proper info from the DB, as secondary constructor
|
||||
* for almost all objects in this class.
|
||||
*
|
||||
* @param string $sql - The SQL to execute.
|
||||
* @param array $params - Any bound parameters for the query.
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function query( $sql, $params = [], $noFetch = false ) {
|
||||
$this->queryReset();
|
||||
if ( $this->pdo == false ) {
|
||||
Debug::warn( 'DB::query - no database connection established' );
|
||||
$this->error = true;
|
||||
$this->errorMessage = 'DB::query - no database connection established';
|
||||
return $this;
|
||||
}
|
||||
$this->query = $this->pdo->prepare( $sql );
|
||||
if ( !empty( $params ) ) {
|
||||
$x = 0;
|
||||
foreach ( $params as $param ) {
|
||||
$x++;
|
||||
if ( is_array( $param ) ) {
|
||||
// dv( $param );
|
||||
}
|
||||
$this->query->bindValue( $x, $param );
|
||||
}
|
||||
}
|
||||
try {
|
||||
$this->query->execute();
|
||||
} catch ( PDOException $Exception ) {
|
||||
$this->error = true;
|
||||
$this->errorMessage = $Exception->getMessage();
|
||||
Debug::error( 'DB Query Error' );
|
||||
Debug::error( $this->errorMessage );
|
||||
return $this;
|
||||
}
|
||||
if ( $noFetch === true ) {
|
||||
$this->results = null;
|
||||
$this->count = 1;
|
||||
} else {
|
||||
$this->results = $this->query->fetchAll( PDO::FETCH_OBJ );
|
||||
$this->count = $this->query->rowCount();
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function resets the values used for creating or modifying tables.
|
||||
* Essentially a cleaner function.
|
||||
*/
|
||||
public function queryReset( $includeBuffers = false ) {
|
||||
$this->results = null;
|
||||
$this->count = 0;
|
||||
$this->error = false;
|
||||
$this->errorMessage = null;
|
||||
$this->query = null;
|
||||
if ( $includeBuffers ) {
|
||||
$this->tableBuff = null;
|
||||
$this->fieldBuff = null;
|
||||
$this->queryStatus = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The action function builds all of our SQL.
|
||||
*
|
||||
* @todo : Clean this up.
|
||||
*
|
||||
* @param string $action - The type of action being carried out.
|
||||
* @param string $tableName - The table name being used.
|
||||
* @param array $where - The parameters for the action
|
||||
* @param string $by - The key to sort by.
|
||||
* @param string $direction - The direction to sort the results.
|
||||
* @param array $limit - The result limit of the query.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function action( $action, $tableName, $where, $by = null, $direction = 'DESC', $reqLimit = null ) {
|
||||
$this->totalResults = 0; // since this is how we paginate, it can't be reset when we exceed the max
|
||||
if ( !$this->enabled() ) {
|
||||
$this->error = true;
|
||||
$this->errorMessage = 'Database disabled';
|
||||
return $this;
|
||||
}
|
||||
$whereCount = count( $where );
|
||||
if ( $whereCount < 3 ) {
|
||||
Debug::error( 'DB::action - Not enough arguments supplied for "where" clause' );
|
||||
$this->error = true;
|
||||
$this->errorMessage = 'DB::action - Not enough arguments supplied for "where" clause';
|
||||
return $this;
|
||||
}
|
||||
if ( $action == 'DELETE' ) {
|
||||
$noFetch = true;
|
||||
}
|
||||
$tableName = Config::getValue( 'database/dbPrefix' ) . $tableName;
|
||||
$sql = "{$action} FROM `{$tableName}` WHERE ";
|
||||
$validOperators = ['=', '!=', '>', '<', '>=', '<=', 'LIKE', 'IS'];
|
||||
$validDelimiters = ['AND', 'OR'];
|
||||
$values = [];
|
||||
while ( $whereCount > 2 ) {
|
||||
$whereCount = $whereCount - 3;
|
||||
$field = array_shift( $where );
|
||||
$operator = array_shift( $where );
|
||||
array_push( $values, array_shift( $where ) );
|
||||
if ( !in_array( $operator, $validOperators ) ) {
|
||||
Debug::error( 'DB::action - Invalid operator.' );
|
||||
$this->error = true;
|
||||
$this->errorMessage = 'DB::action - Invalid operator.';
|
||||
return $this;
|
||||
}
|
||||
$sql .= "{$field} {$operator} ?";
|
||||
if ( $whereCount > 0 ) {
|
||||
$delimiter = array_shift( $where );
|
||||
if ( !in_array( $delimiter, $validDelimiters ) ) {
|
||||
Debug::error( 'DB::action - Invalid delimiter.' );
|
||||
$this->error = true;
|
||||
$this->errorMessage = 'DB::action - Invalid delimiter.';
|
||||
return $this;
|
||||
}
|
||||
$sql .= " {$delimiter} ";
|
||||
$whereCount--;
|
||||
}
|
||||
}
|
||||
if ( isset( $by ) ) {
|
||||
$sql .= " ORDER BY {$by} {$direction}";
|
||||
}
|
||||
$sqlPreLimit = $sql;
|
||||
if ( !empty( $reqLimit ) ) {
|
||||
$lim = implode(',',$reqLimit);
|
||||
$sql .= " LIMIT {$lim}";
|
||||
}
|
||||
if ( isset( $values ) ) {
|
||||
if ( !empty( $noFetch ) ) {
|
||||
$error = $this->query( $sql, $values, true )->error();
|
||||
} else {
|
||||
$error = $this->query( $sql, $values )->error();
|
||||
}
|
||||
} else {
|
||||
$error = $this->query( $sql )->error();
|
||||
}
|
||||
if ( $error ) {
|
||||
Debug::warn( 'DB Action Error: ' );
|
||||
Debug::warn( $this->errorMessage );
|
||||
return $this;
|
||||
}
|
||||
$this->totalResults = $this->count;
|
||||
if ( $this->count <= $this->maxQuery ) {
|
||||
return $this;
|
||||
}
|
||||
Debug::warn( 'Query exceeded maximum results. Maximum allowed is ' . $this->maxQuery );
|
||||
if ( !empty( $limit ) ) {
|
||||
$newLimit = ( $reqLimit[0] + Pagination::perPage() );
|
||||
$limit = " LIMIT {$reqLimit[0]},{$newLimit}";
|
||||
} else {
|
||||
$limit = ' LIMIT 0,' .Pagination::perPage();
|
||||
}
|
||||
$sql = $sqlPreLimit . $limit;
|
||||
if ( isset( $values ) ) {
|
||||
$error = $this->query( $sql, $values )->error();
|
||||
} else {
|
||||
$error = $this->query( $sql )->error();
|
||||
}
|
||||
if ( $error ) {
|
||||
Debug::warn( 'DB Action Error: ' );
|
||||
Debug::warn( $this->errorMessage );
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to insert into the DB.
|
||||
*
|
||||
* @param string $table - The table you wish to insert into.
|
||||
* @param array $fields - The array of fields you wish to insert.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function insert( $table, $fields = [] ) {
|
||||
$keys = array_keys( $fields );
|
||||
$valuesSQL = null;
|
||||
$x = 0;
|
||||
$keysSQL = implode( '`, `', $keys );
|
||||
foreach ( $fields as $value ) {
|
||||
$x++;
|
||||
$valuesSQL .= '?';
|
||||
if ( $x < count( $fields ) ) {
|
||||
$valuesSQL .= ', ';
|
||||
}
|
||||
}
|
||||
$table = Config::getValue( 'database/dbPrefix' ) . $table;
|
||||
$sql = "INSERT INTO `{$table}` (`" . $keysSQL . "`) VALUES ({$valuesSQL})";
|
||||
if ( !$this->query( $sql, $fields, true )->error() ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to duplicate a database entry.
|
||||
*
|
||||
* @param string $table - The table you wish to duplicate the entry in.
|
||||
* @param int $id - The ID of the entry you wish to duplicate.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function duplicateEntry($table, $id) {
|
||||
// Get the original entry
|
||||
$originalEntry = $this->action('SELECT', $table, ['ID', '=', $id])->results();
|
||||
|
||||
// Exclude the ID field
|
||||
unset($originalEntry->ID);
|
||||
|
||||
// Insert the duplicated entry
|
||||
if ($this->insert($table, (array) $originalEntry)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to update the database.
|
||||
*
|
||||
* @param string $table - The table you wish to update in.
|
||||
* @param int $id - The ID of the entry you wish to update.
|
||||
* @param array $fields - the various fields you wish to update
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function update( $table, $id, $fields = [] ) {
|
||||
$updateSQL = null;
|
||||
$x = 0;
|
||||
foreach ( $fields as $name => $value ) {
|
||||
$x++;
|
||||
$updateSQL .= "{$name} = ?";
|
||||
if ( $x < count( $fields ) ) {
|
||||
$updateSQL .= ', ';
|
||||
}
|
||||
}
|
||||
$table = Config::getValue( 'database/dbPrefix' ) . $table;
|
||||
$sql = "UPDATE {$table} SET {$updateSQL} WHERE ID = {$id}";
|
||||
if ( !$this->query( $sql, $fields, true )->error() ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a series of, or a single instance(s) in the database.
|
||||
*
|
||||
* @param string $table - The table you are deleting from.
|
||||
* @param string $where - The criteria for deletion.
|
||||
*
|
||||
* @return function
|
||||
*/
|
||||
public function delete( $table, $where ) {
|
||||
return $this->action( 'DELETE', $table, $where );
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the object to create a new table if none already exists.
|
||||
*
|
||||
* NOTE: All tables created with this function will automatically
|
||||
* have an 11 digit integer called ID added as a primary key.
|
||||
*
|
||||
* @param string $name - The name of the table you wish to create.
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @todo - add a check for the name.
|
||||
*/
|
||||
public function newTable( $name, $addID = true ) {
|
||||
if ( $this->tableExists( $name ) ) {
|
||||
$this->tableBuff = null;
|
||||
Debug::error( "Table already exists: $name" );
|
||||
|
||||
return false;
|
||||
}
|
||||
$this->queryReset( true );
|
||||
$this->tableBuff = $name;
|
||||
if ( $addID === true ) {
|
||||
$this->addField( 'ID', 'int', 11, false );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds and executes a database query to to create a table
|
||||
* using the current object's table name and fields.
|
||||
*
|
||||
* NOTE: By default: All tables have an auto incrementing primary key named 'ID'.
|
||||
*
|
||||
* @todo - Come back and add more versatility here.
|
||||
*/
|
||||
public function createTable() {
|
||||
if ( empty( $this->tableBuff ) ) {
|
||||
Debug::info( 'No Table set.' );
|
||||
|
||||
return false;
|
||||
}
|
||||
$table = Config::getValue( 'database/dbPrefix' ) . $this->tableBuff;
|
||||
if ( $this->tableExists( $this->tableBuff ) ) {
|
||||
Debug::error( "Table already exists: $table" );
|
||||
|
||||
return false;
|
||||
}
|
||||
$queryBuff = "CREATE TABLE `$table` (";
|
||||
$x = 0;
|
||||
$y = count( $this->fieldBuff );
|
||||
while ( $x < $y ) {
|
||||
$queryBuff .= $this->fieldBuff[$x];
|
||||
$x++;
|
||||
$queryBuff .= ( $x < $y ) ? ',' : '';
|
||||
}
|
||||
$queryBuff .= ') ENGINE=InnoDB DEFAULT CHARSET=latin1; ALTER TABLE `' . $table . '` ADD PRIMARY KEY (`ID`); ';
|
||||
$queryBuff .= 'ALTER TABLE `' . $table . "` MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Primary index value';";
|
||||
$this->queryStatus = ( $this->raw( $queryBuff ) ? true : false );
|
||||
return $this->queryStatus;
|
||||
}
|
||||
|
||||
public function removeTable( $name ) {
|
||||
if ( !$this->tableExists( $name ) ) {
|
||||
Debug::error( "No table exists: $name" );
|
||||
|
||||
return false;
|
||||
}
|
||||
$table = Config::getValue( 'database/dbPrefix' ) . $name;
|
||||
$this->queryStatus = ( $this->raw( 'DROP TABLE `' . $table . '`' ) ? true : false );
|
||||
return $this->queryStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function allows you to add a new field to be
|
||||
* added to a previously specified table.
|
||||
*
|
||||
* @param string $name - The name of the field to add
|
||||
* @param string $type - The type of field.
|
||||
* @param integer $length - The maximum length value for the field.
|
||||
* @param boolean $null - Whether or not the field can be null
|
||||
* @param string $default - The default value to use for new entries if any.
|
||||
* @param string $comment - DB comment for this field.
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @todo - add more error reporting and checks
|
||||
* use switch/cases?
|
||||
*/
|
||||
public function addField( $name, $type, $length, $null = true, $default = null, $comment = '' ) {
|
||||
if ( empty( $this->tableBuff ) ) {
|
||||
Debug::info( 'No Table set.' );
|
||||
return false;
|
||||
}
|
||||
if ( $this->columnExists( $this->tableBuff, $name ) ) {
|
||||
Debug::error( "Column already exists: $this->tableBuff > $name" );
|
||||
return false;
|
||||
}
|
||||
if ( $null === true ) {
|
||||
$sDefault = ' DEFAULT NULL';
|
||||
} else {
|
||||
$sDefault = ' NOT NULL';
|
||||
if ( !empty( $default ) ) {
|
||||
$sDefault .= " DEFAULT '$default'";
|
||||
}
|
||||
}
|
||||
if ( !empty( $length ) ) {
|
||||
if ( is_int( $length ) ) {
|
||||
$sType = $type . '(' . $length . ')';
|
||||
} elseif ( is_string( $length ) && ctype_digit( $length ) ) {
|
||||
$sType = $type . '(' . $length . ')';
|
||||
} else {
|
||||
$sType = $type;
|
||||
}
|
||||
} else {
|
||||
$sType = $type;
|
||||
}
|
||||
if ( !empty( $comment ) ) {
|
||||
$sComment = " COMMENT '$comment'";
|
||||
} else {
|
||||
$sComment = '';
|
||||
}
|
||||
$this->fieldBuff[] = ' `' . $name . '` ' . $sType . $sDefault . $sComment;
|
||||
return true;
|
||||
}
|
||||
|
||||
public function searchColumn( $table, $column, $param ) {
|
||||
return $this->action( 'SELECT *', $table, [$column, 'LIKE', '%' . $param . '%'] );
|
||||
}
|
||||
|
||||
public function search( $table, $columns, $param ) {
|
||||
if ( empty( $columns ) || ! is_array( $columns ) ) {
|
||||
Debug::log( 'No columns provided for search' );
|
||||
return [];
|
||||
}
|
||||
|
||||
$conditions = [];
|
||||
foreach ( $columns as $column ) {
|
||||
$conditions[] = $column;
|
||||
$conditions[] = 'LIKE';
|
||||
$conditions[] = '%' . $param . '%';
|
||||
$conditions[] = 'OR';
|
||||
}
|
||||
array_pop( $conditions );
|
||||
|
||||
return $this->action( 'SELECT *', $table, $conditions );
|
||||
// return $this->action( 'SELECT ' . implode( ',', $columns ), $table, $conditions ); // need to find a way to casually make this the default....
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects data from the database.
|
||||
*
|
||||
* @param string $table - The table we wish to select from.
|
||||
* @param string $where - The criteria we wish to select.
|
||||
* @param string $by - The key we wish to order by.
|
||||
* @param string $direction - The direction we wish to order the results.
|
||||
*
|
||||
* @return function
|
||||
*/
|
||||
public function get( $table, $where, $by = 'ID', $direction = 'DESC', $limit = null ) {
|
||||
if ( $where === '*' ) {
|
||||
$where = ['ID', '>=', '0'];
|
||||
}
|
||||
return $this->action( 'SELECT *', $table, $where, $by, $direction, $limit );
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects data from the database and automatically builds the pagination filter for the results array.
|
||||
*
|
||||
* @param string $table - The table we wish to select from.
|
||||
* @param string $where - The criteria we wish to select.
|
||||
* @param string $by - The key we wish to order by.
|
||||
* @param string $direction - The direction we wish to order the results.
|
||||
*
|
||||
* @return function
|
||||
*/
|
||||
public function getPaginated( $table, $where, $by = 'ID', $direction = 'DESC', $limit = null ) {
|
||||
if ( $where === '*' ) {
|
||||
$where = ['ID', '>=', '0'];
|
||||
}
|
||||
$db = $this->action( 'SELECT ID', $table, $where, $by, $direction );
|
||||
|
||||
Pagination::updatePaginationTotal( $this->totalResults );
|
||||
|
||||
if ( ! is_array( $limit ) ) {
|
||||
$limit = [ Pagination::getMin(), Pagination::getMax() ];
|
||||
}
|
||||
|
||||
Pagination::paginate();
|
||||
|
||||
return $this->action( 'SELECT *', $table, $where, $by, $direction, $limit );
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for returning the entire $results array.
|
||||
*
|
||||
* @return array - Returns the current query's results.
|
||||
*/
|
||||
public function results() {
|
||||
return $this->results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for returning the first result in the results array.
|
||||
*
|
||||
* @return array - Returns the current first member of the results array.
|
||||
*/
|
||||
public function first() {
|
||||
if ( !empty( $this->results[0] ) ) {
|
||||
return $this->results[0];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for returning current results' row count.
|
||||
*
|
||||
* @return int - Returns the current instance's SQL result count.
|
||||
*/
|
||||
public function count() {
|
||||
return $this->count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if there are errors with the current query or not.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function error() {
|
||||
return $this->error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if there are errors with the current query or not.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function errorMessage() {
|
||||
//$this->query->errorInfo();
|
||||
return $this->errorMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the boolean status of the most recently executed query.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getStatus() {
|
||||
return $this->queryStatus;
|
||||
}
|
||||
}
|
209
classes/databaseModel.php
Normal file
209
classes/databaseModel.php
Normal file
@ -0,0 +1,209 @@
|
||||
<?php
|
||||
/**
|
||||
* classes/DatabaseModel.php
|
||||
*
|
||||
* The class provides some basic functionality for models that interact
|
||||
* with the database.
|
||||
*
|
||||
* @version 1.1.2
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com/libraries/Bedrock
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject\Bedrock\Classes;
|
||||
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Bedrock\Bedrock;
|
||||
|
||||
class DatabaseModel extends Model {
|
||||
public $tableName;
|
||||
public $databaseMatrix;
|
||||
public $searchFields;
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function enabled() {
|
||||
if ( empty( $this->enabled ) ) {
|
||||
$this->enabled = self::$db->enabled();
|
||||
}
|
||||
return $this->enabled;
|
||||
}
|
||||
|
||||
public function filter( $data, $params = [] ) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will remove all the installed model components.
|
||||
*
|
||||
* @return bool - If the uninstall was completed without error
|
||||
*/
|
||||
public function uninstall() {
|
||||
parent::uninstall();
|
||||
$this->uninstallTable();
|
||||
return true;
|
||||
}
|
||||
|
||||
public function rowMatrixToArray( $row_matrix ) {
|
||||
$row_array = [];
|
||||
$row_array['row_name'] = array_shift( $row_matrix );
|
||||
$row_array['row_type'] = array_shift( $row_matrix );
|
||||
$row_array['length'] = array_shift( $row_matrix );
|
||||
if ( !empty( $row_matrix ) ) {
|
||||
$row_array['is_null'] = array_shift( $row_matrix );
|
||||
} else {
|
||||
$row_array['is_null'] = true;
|
||||
}
|
||||
if ( !empty( $row_matrix ) ) {
|
||||
$row_array['default_value'] = array_shift( $row_matrix );
|
||||
} else {
|
||||
$row_array['default_value'] = null;
|
||||
}
|
||||
if ( !empty( $row_matrix ) ) {
|
||||
$row_array['comment'] = array_shift( $row_matrix );
|
||||
} else {
|
||||
$row_array['comment'] = '';
|
||||
}
|
||||
return $row_array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Install db tables needed for the model.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public function installTable() {
|
||||
// should have some sort of DELTA functionality and safeguards
|
||||
if ( empty( $this->tableName ) || empty( $this->databaseMatrix )) {
|
||||
Debug::log( 'databaseMatrix is empty' );
|
||||
return true;
|
||||
}
|
||||
if ( false === self::$db->newTable( $this->tableName ) ) {
|
||||
return false;
|
||||
}
|
||||
Debug::log( 'adding a new table named: ' . $this->tableName );
|
||||
foreach ( $this->databaseMatrix as $key => $row_matrix ) {
|
||||
$row = $this->rowMatrixToArray( $row_matrix );
|
||||
self::$db->addField(
|
||||
$row['row_name'],
|
||||
$row['row_type'],
|
||||
$row['length'],
|
||||
$row['is_null'],
|
||||
$row['default_value'],
|
||||
$row['comment'],
|
||||
);
|
||||
}
|
||||
self::$db->createTable();
|
||||
return self::$db->getStatus();
|
||||
}
|
||||
|
||||
public function uninstallTable() {
|
||||
if ( empty( $this->tableName ) ) {
|
||||
return;
|
||||
}
|
||||
return self::$db->removeTable( $this->tableName );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a row by its ID and filters it.
|
||||
*
|
||||
* @param {int} [$id]
|
||||
* @return {object} - The filtered db entry.
|
||||
*/
|
||||
public function findById( $id ) {
|
||||
if ( !Check::id( $id ) ) {
|
||||
Debug::warn( "$this->tableName fingByID: illegal ID: $id" );
|
||||
return false;
|
||||
}
|
||||
$data = self::$db->get( $this->tableName, ['ID', '=', $id] );
|
||||
if ( !$data->count() ) {
|
||||
Debug::info( 'No ' . $this->tableName . ' data found.' );
|
||||
return false;
|
||||
}
|
||||
return $this->filter( $data->first() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to delete the specified entry.
|
||||
*
|
||||
* @param int|array $ID the log ID or array of ID's to be deleted
|
||||
* @return bool
|
||||
*/
|
||||
public function delete( $idArray ) {
|
||||
if ( !is_array( $idArray ) ) {
|
||||
$idArray = [ $idArray ];
|
||||
}
|
||||
foreach ( $idArray as $id ) {
|
||||
if ( !Check::id( $id ) ) {
|
||||
Debug::info( "invalid ID: $id." );
|
||||
$error = true;
|
||||
continue;
|
||||
}
|
||||
if ( self::$db->delete( $this->tableName, [ 'ID', '=', $id ] )->error() ) {
|
||||
Debug::info( "Error Deleting id: $id" );
|
||||
$error = true;
|
||||
continue;
|
||||
}
|
||||
Debug::info( $this->tableName . " deleted: $id" );
|
||||
}
|
||||
if ( !empty( $error ) ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to clear entries of a defined type.
|
||||
*
|
||||
* @todo this is probably dumb
|
||||
* @param string $data - The log type to be cleared
|
||||
* @return bool
|
||||
*/
|
||||
public function empty() {
|
||||
self::$db->delete( $this->tableName, ['ID', '>=', '0'] );
|
||||
Debug::info( $this->tableName . ' Cleared' );
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieves a list of paginated (limited) results.
|
||||
*
|
||||
* @param array $filter - A filter to be applied to the list.
|
||||
* @return bool|object - Depending on success.
|
||||
*/
|
||||
public function listPaginated( $filter = null ) {
|
||||
$data = self::$db->getPaginated( $this->tableName, '*' );
|
||||
if ( !$data->count() ) {
|
||||
Debug::info( $this->tableName . ' - No entries found' );
|
||||
return false;
|
||||
}
|
||||
return $this->filter( $data->results() );
|
||||
}
|
||||
|
||||
public function list( $filter = null ) {
|
||||
$data = self::$db->get( $this->tableName, '*' );
|
||||
if ( !$data->count() ) {
|
||||
Debug::info( $this->tableName . ' - No entries found' );
|
||||
return false;
|
||||
}
|
||||
return $this->filter( $data->results() );
|
||||
}
|
||||
|
||||
public function search($param) {
|
||||
if (empty($this->searchFields)) {
|
||||
Debug::log('searchFields is empty');
|
||||
return [];
|
||||
}
|
||||
|
||||
$result = self::$db->search($this->tableName, $this->searchFields, $param);
|
||||
|
||||
if ( $result->count() ) {
|
||||
return $this->filter( $result->results() );
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
124
classes/model.php
Normal file
124
classes/model.php
Normal file
@ -0,0 +1,124 @@
|
||||
<?php
|
||||
/**
|
||||
* classes/model.php
|
||||
*
|
||||
* The class provides some basic functionality for models.
|
||||
*
|
||||
* @version 1.1.2
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com/libraries/Bedrock
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject\Bedrock\Classes;
|
||||
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
use TheTempusProject\Bedrock\Classes\Config;
|
||||
use TheTempusProject\Bedrock\Classes\Database;
|
||||
|
||||
class Model {
|
||||
public static $db;
|
||||
public $configName;
|
||||
public $configMatrix = [];
|
||||
public $resourceMatrix = [];
|
||||
public $modelVersion;
|
||||
public $enabled = false;
|
||||
|
||||
/**
|
||||
* The model constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
Debug::debug( 'Model Constructed: ' . get_class( $this ) );
|
||||
self::$db = Database::getInstance();
|
||||
$this->load();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will remove all the installed model components.
|
||||
*
|
||||
* @return bool - If the uninstall was completed without error
|
||||
*/
|
||||
public function uninstall() {
|
||||
$this->uninstallResources();
|
||||
$this->uninstallConfigs();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Install resources needed for the model.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public function installResources() {
|
||||
// should have some sort of DELTA functionality and safeguards
|
||||
$ids = [];
|
||||
if ( empty($this->resourceMatrix) ) {
|
||||
return true;
|
||||
}
|
||||
foreach ( $this->resourceMatrix as $entry ) {
|
||||
foreach ( $entry as $key => $value ) {
|
||||
if ( '{time}' == $value ) {
|
||||
$entry[$key] = time();
|
||||
}
|
||||
}
|
||||
self::$db->insert( $this->tableName, $entry );
|
||||
$id = self::$db->lastId();
|
||||
if ( $id ) {
|
||||
$ids[] = $id;
|
||||
}
|
||||
}
|
||||
return $ids;
|
||||
}
|
||||
|
||||
public function uninstallResources() {
|
||||
// this one needs some work
|
||||
// should probably save the created resource ID's or something and remove them.
|
||||
// presumably this isn't a big issue because i would imagine the table is removed
|
||||
// there may be future instances where you can create resources for other tables
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Install configs needed for the model.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public function installConfigs() {
|
||||
$config = new Config( CONFIG_JSON );
|
||||
// should have some sort of DELTA functionality and safeguards
|
||||
$config->addCategory( $this->configName );
|
||||
foreach ( $this->configMatrix as $name => $details ) {
|
||||
$config->add( $this->configName, $name, $details );
|
||||
}
|
||||
return $config->save();
|
||||
}
|
||||
|
||||
public function uninstallConfigs() {
|
||||
if ( empty( $this->configName ) ) {
|
||||
return true;
|
||||
}
|
||||
$config = new Config( CONFIG_JSON );
|
||||
return $config->removeCategory( $this->configName, true, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells the installer which types of integrations your model needs to install.
|
||||
*
|
||||
* @return bool - if the model was loaded without error
|
||||
*/
|
||||
public function load() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getModelVersion() {
|
||||
return $this->modelVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the model is enabled.
|
||||
*
|
||||
* @return bool - if the model is enabled or not
|
||||
*/
|
||||
public function enabled() {
|
||||
return $this->enabled;
|
||||
}
|
||||
}
|
226
classes/pagination.php
Normal file
226
classes/pagination.php
Normal file
@ -0,0 +1,226 @@
|
||||
<?php
|
||||
/**
|
||||
* classes/pagination.php
|
||||
*
|
||||
* This class is for managing template pagination.
|
||||
*
|
||||
* @version 1.1.2
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com/libraries/Bedrock
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject\Bedrock\Classes;
|
||||
|
||||
use TheTempusProject\Houdini\Classes\Template;
|
||||
use TheTempusProject\Hermes\Functions\Route as Routes;
|
||||
use TheTempusProject\Bedrock\Functions\Input;
|
||||
use TheTempusProject\Bedrock\Classes\Config;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
use TheTempusProject\Houdini\Classes\Components;
|
||||
use TheTempusProject\Houdini\Classes\Views;
|
||||
|
||||
class Pagination extends Template {
|
||||
//The settings that will not change
|
||||
public static $paginationSettings = [];
|
||||
|
||||
//The instance for each generation
|
||||
public static $instance = null;
|
||||
|
||||
public function __construct() {
|
||||
if ( empty( self::$paginationSettings['limit'] ) ) {
|
||||
$this->loadSettings();
|
||||
}
|
||||
// check for user settings
|
||||
if ( empty( self::$paginationSettings['perPage'] ) ) {
|
||||
self::$paginationSettings['perPage'] = DEFAULT_RESULTS_PER_PAGE;
|
||||
if ( ( !empty( self::$paginationSettings['userPerPage'] ) ) && ( self::$paginationSettings['userPerPage'] <= self::$paginationSettings['maxPerPage'] ) ) {
|
||||
self::$paginationSettings['perPage'] = self::$paginationSettings['userPerPage'];
|
||||
}
|
||||
}
|
||||
// The query minimum and maximum based on current page and page limit
|
||||
if ( self::$paginationSettings['currentPage'] == 1 ) {
|
||||
self::$paginationSettings['min'] = 0;
|
||||
} else {
|
||||
self::$paginationSettings['min'] = ( ( self::$paginationSettings['currentPage'] - 1 ) * self::$paginationSettings['perPage'] );
|
||||
}
|
||||
// if ( self::$paginationSettings['currentPage'] == 1 ) {
|
||||
self::$paginationSettings['max'] = self::$paginationSettings['perPage'];
|
||||
// } else {
|
||||
// self::$paginationSettings['max'] = ( self::$paginationSettings['currentPage'] * self::$paginationSettings['perPage'] );
|
||||
// }
|
||||
// The query limit based on our settings here
|
||||
self::$paginationSettings['limit'] = [self::$paginationSettings['min'], self::$paginationSettings['max']];
|
||||
}
|
||||
|
||||
private static function loadSettings() {
|
||||
Debug::log( 'Loading Pagination Settings.' );
|
||||
// hard cap built into system for displaying results
|
||||
self::$paginationSettings['maxPerPage'] = MAX_RESULTS_PER_PAGE;
|
||||
|
||||
// hard cap built into system retrieving results
|
||||
self::$paginationSettings['maxQuery'] = Config::getValue( 'database/dbMaxQuery' );
|
||||
|
||||
// Set max query to the lowest of the three settings since this will modify how many results are possible.
|
||||
if ( self::$paginationSettings['maxQuery'] <= self::$paginationSettings['maxPerPage'] ) {
|
||||
self::$paginationSettings['maxPerPage'] = self::$paginationSettings['maxQuery'];
|
||||
}
|
||||
|
||||
// Check for results request to set/modify the perPage setting
|
||||
if ( Input::exists( 'results' ) ) {
|
||||
if ( Check::ID( Input::get( 'results' ) ) ) {
|
||||
if ( Input::get( 'results' ) <= self::$paginationSettings['maxPerPage'] ) {
|
||||
self::$paginationSettings['perPage'] = Input::get( 'results' );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( empty( self::$paginationSettings['perPage'] ) ) {
|
||||
self::$paginationSettings['perPage'] = self::$paginationSettings['maxPerPage'];
|
||||
}
|
||||
|
||||
// Check for pagination in get
|
||||
if ( Input::exists( 'page' ) ) {
|
||||
if ( Check::ID( Input::get( 'page' ) ) ) {
|
||||
self::$paginationSettings['currentPage'] = (int) Input::get( 'page' );
|
||||
} else {
|
||||
self::$paginationSettings['currentPage'] = 1;
|
||||
}
|
||||
} else {
|
||||
self::$paginationSettings['currentPage'] = 1;
|
||||
}
|
||||
|
||||
if ( ( self::$paginationSettings['currentPage'] - 3 ) > 1 ) {
|
||||
self::$paginationSettings['firstPage'] = ( self::$paginationSettings['currentPage'] - 2 );
|
||||
} else {
|
||||
self::$paginationSettings['firstPage'] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
public static function generate() {
|
||||
// account for empty values here instead of inside the script.
|
||||
Debug::log( 'Creating new Pagination Instance.' );
|
||||
self::$instance = new self();
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
public static function updatePaginationTotal( $count ) {
|
||||
if ( empty( self::$paginationSettings ) ) {
|
||||
self::generate();
|
||||
}
|
||||
if ( Check::id( $count ) ) {
|
||||
Debug::log( 'Pagination: Updating results count' );
|
||||
self::$paginationSettings['results'] = $count;
|
||||
self::$paginationSettings['totalPages'] = ceil( ( self::$paginationSettings['results'] / self::$paginationSettings['perPage'] ) );
|
||||
if ( ( self::$paginationSettings['currentPage'] + 3 ) < self::$paginationSettings['totalPages'] ) {
|
||||
self::$paginationSettings['lastPage'] = self::$paginationSettings['currentPage'] + 3;
|
||||
} else {
|
||||
self::$paginationSettings['lastPage'] = self::$paginationSettings['totalPages'];
|
||||
}
|
||||
Debug::info( 'Pagination: results update completed.' );
|
||||
} else {
|
||||
Debug::info( 'Pagination: results update failed.' );
|
||||
}
|
||||
}
|
||||
|
||||
public static function paginate() {
|
||||
$pageData = [];
|
||||
if ( self::firstPage() != 1 ) {
|
||||
$data[1]['ACTIVEPAGE'] = '';
|
||||
$data[1]['PAGENUMBER'] = 1;
|
||||
$data[1]['LABEL'] = 'First';
|
||||
$pageData[1] = (object) $data[1];
|
||||
}
|
||||
for ( $x = self::firstPage(); $x < self::lastPage(); $x++ ) {
|
||||
if ( $x == self::currentPage() ) {
|
||||
$active = ' class="active"';
|
||||
} else {
|
||||
$active = '';
|
||||
}
|
||||
$data[$x]['ACTIVEPAGE'] = $active;
|
||||
$data[$x]['PAGENUMBER'] = $x;
|
||||
$data[$x]['LABEL'] = $x;
|
||||
$pageData[$x] = (object) $data[$x];
|
||||
}
|
||||
if ( self::lastPage() <= self::totalPages() ) {
|
||||
$x = self::totalPages();
|
||||
if ( $x == self::currentPage() ) {
|
||||
$active = ' class="active"';
|
||||
} else {
|
||||
$active = '';
|
||||
}
|
||||
$data[$x]['ACTIVEPAGE'] = $active;
|
||||
$data[$x]['PAGENUMBER'] = $x;
|
||||
$data[$x]['LABEL'] = 'Last';
|
||||
$pageData[$x] = (object) $data[$x];
|
||||
}
|
||||
$pageData = (object) $pageData;
|
||||
|
||||
if ( self::totalPages() <= 1 ) {
|
||||
Components::set( 'PAGINATION', '' );
|
||||
} else {
|
||||
Components::set( 'PAGINATION', Views::simpleView( 'nav.pagination', $pageData ) );
|
||||
}
|
||||
}
|
||||
|
||||
public static function updatePrefs( $pageLimit ) {
|
||||
if ( Check::id( $pageLimit ) ) {
|
||||
Debug::log( 'Pagination: Updating user pref' );
|
||||
self::$paginationSettings['userPerPage'] = $pageLimit;
|
||||
} else {
|
||||
Debug::info( 'Pagination: User pref update failed.' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Getters
|
||||
*/
|
||||
public static function getMin() {
|
||||
if ( isset( self::$paginationSettings['min'] ) ) {
|
||||
return self::$paginationSettings['min'];
|
||||
} else {
|
||||
Debug::info( 'Pagination: Min not found' );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
public static function getMax() {
|
||||
if ( isset( self::$paginationSettings['max'] ) ) {
|
||||
return self::$paginationSettings['max'];
|
||||
} else {
|
||||
Debug::info( 'Pagination: Max not found' );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
public static function perPage() {
|
||||
if ( !empty( self::$paginationSettings['perPage'] ) ) {
|
||||
return self::$paginationSettings['perPage'];
|
||||
}
|
||||
}
|
||||
public static function firstPage() {
|
||||
if ( !empty( self::$paginationSettings['firstPage'] ) ) {
|
||||
return self::$paginationSettings['firstPage'];
|
||||
} else {
|
||||
Debug::info( 'Pagination: firstPage not found' );
|
||||
}
|
||||
}
|
||||
public static function lastPage() {
|
||||
if ( !empty( self::$paginationSettings['lastPage'] ) ) {
|
||||
return self::$paginationSettings['lastPage'];
|
||||
} else {
|
||||
Debug::info( 'Pagination: lastPage not found' );
|
||||
}
|
||||
}
|
||||
public static function totalPages() {
|
||||
if ( !empty( self::$paginationSettings['totalPages'] ) ) {
|
||||
return self::$paginationSettings['totalPages'];
|
||||
} else {
|
||||
Debug::info( 'Pagination: totalPages not found' );
|
||||
}
|
||||
}
|
||||
public static function currentPage() {
|
||||
if ( !empty( self::$paginationSettings['currentPage'] ) ) {
|
||||
return self::$paginationSettings['currentPage'];
|
||||
} else {
|
||||
Debug::info( 'Pagination: currentPage not found' );
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user