mirror of
https://github.com/monstra-cms/monstra.git
synced 2025-08-06 13:16:54 +02:00
Monstra Library: basic core improvments
This commit is contained in:
489
libraries/engine/Core.php
Normal file
489
libraries/engine/Core.php
Normal file
@@ -0,0 +1,489 @@
|
||||
<?php defined('MONSTRA_ACCESS') or die('No direct script access.');
|
||||
|
||||
/**
|
||||
* Main Monstra engine module. Core module.
|
||||
*
|
||||
* Monstra - Content Management System.
|
||||
* Site: mostra.org
|
||||
* Copyright (C) 2012 Romanenko Sergey / Awilum [awilum@msn.com]
|
||||
*
|
||||
* @package Monstra
|
||||
* @author Romanenko Sergey / Awilum
|
||||
* @copyright 2012 Romanenko Sergey / Awilum
|
||||
* @version $Id$
|
||||
* @since 1.0.0
|
||||
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
|
||||
* Monstra is free software. This version may have been modified pursuant
|
||||
* to the GNU General Public License, and as distributed it includes or
|
||||
* is derivative of works licensed under the GNU General Public License or
|
||||
* other free or open source software licenses.
|
||||
* See COPYING.txt for copyright notices and details.
|
||||
*/
|
||||
|
||||
class Core
|
||||
{
|
||||
/**
|
||||
* An instance of the Core class
|
||||
*
|
||||
* @var core
|
||||
*/
|
||||
protected static $instance = null;
|
||||
|
||||
/**
|
||||
* Common environment type constants for consistency and convenience
|
||||
*/
|
||||
const PRODUCTION = 1;
|
||||
const STAGING = 2;
|
||||
const TESTING = 3;
|
||||
const DEVELOPMENT = 4;
|
||||
|
||||
/**
|
||||
* The version of Monstra
|
||||
*/
|
||||
const VERSION = '2.1.3';
|
||||
|
||||
/**
|
||||
* Monstra environment
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $environment = Core::PRODUCTION;
|
||||
|
||||
/**
|
||||
* Protected clone method to enforce singleton behavior.
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function __clone()
|
||||
{
|
||||
// Nothing here.
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
// Load core defines
|
||||
Core::loadDefines();
|
||||
|
||||
/**
|
||||
* Compress HTML with gzip
|
||||
*/
|
||||
if (MONSTRA_GZIP) {
|
||||
if ( ! ob_start("ob_gzhandler")) ob_start();
|
||||
} else {
|
||||
ob_start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send default header and set internal encoding
|
||||
*/
|
||||
header('Content-Type: text/html; charset=UTF-8');
|
||||
function_exists('mb_language') AND mb_language('uni');
|
||||
function_exists('mb_regex_encoding') AND mb_regex_encoding('UTF-8');
|
||||
function_exists('mb_internal_encoding') AND mb_internal_encoding('UTF-8');
|
||||
|
||||
/**
|
||||
* Gets the current configuration setting of magic_quotes_gpc
|
||||
* and kill magic quotes
|
||||
*/
|
||||
if (get_magic_quotes_gpc()) {
|
||||
function stripslashesGPC(&$value) { $value = stripslashes($value); }
|
||||
array_walk_recursive($_GET, 'stripslashesGPC');
|
||||
array_walk_recursive($_POST, 'stripslashesGPC');
|
||||
array_walk_recursive($_COOKIE, 'stripslashesGPC');
|
||||
array_walk_recursive($_REQUEST, 'stripslashesGPC');
|
||||
}
|
||||
|
||||
// Error handling for Developers only.
|
||||
if (Core::$environment != Core::PRODUCTION) {
|
||||
|
||||
// Set error handler
|
||||
set_error_handler('Core::errorHandler');
|
||||
|
||||
// Set fatal error handler
|
||||
register_shutdown_function('Core::fatalErrorHandler');
|
||||
|
||||
// Set exception handler
|
||||
set_exception_handler('Core::exceptionHandler');
|
||||
}
|
||||
|
||||
// Start session
|
||||
Session::start();
|
||||
|
||||
// Init ORM
|
||||
if (defined('MONSTRA_DB_DSN')) {
|
||||
ORM::configure(MONSTRA_DB_DSN);
|
||||
ORM::configure('username', MONSTRA_DB_USER);
|
||||
ORM::configure('password', MONSTRA_DB_PASSWORD);
|
||||
}
|
||||
|
||||
// Auto cleanup if MONSTRA_DEBUG is true
|
||||
if (Core::$environment == Core::DEVELOPMENT) {
|
||||
|
||||
// Cleanup minify
|
||||
if (count($files = File::scan(MINIFY, array('css', 'js', 'php'))) > 0) foreach ($files as $file) File::delete(MINIFY . DS . $file);
|
||||
|
||||
// Cleanup cache
|
||||
if (count($namespaces = Dir::scan(CACHE)) > 0) foreach ($namespaces as $namespace) Dir::delete(CACHE . DS . $namespace);
|
||||
}
|
||||
|
||||
// Load URI module
|
||||
require_once(ROOT . '/libraries/engine/Uri.php');
|
||||
|
||||
// Load XMLDB API module
|
||||
require_once(ROOT . '/libraries/engine/Xmldb.php');
|
||||
|
||||
// Load Options API module
|
||||
require_once(ROOT . '/libraries/engine/Options.php');
|
||||
|
||||
// Init Options API module
|
||||
Option::init();
|
||||
|
||||
// Set default timezone
|
||||
@ini_set('date.timezone', Option::get('timezone'));
|
||||
if (function_exists('date_default_timezone_set')) date_default_timezone_set(Option::get('timezone')); else putenv('TZ='.Option::get('timezone'));
|
||||
|
||||
// Sanitize URL to prevent XSS - Cross-site scripting
|
||||
Security::runSanitizeURL();
|
||||
|
||||
// Load Plugins API module
|
||||
require_once(ROOT . '/libraries/engine/Plugins.php');
|
||||
|
||||
// Load Shortcodes API module
|
||||
require_once(ROOT . '/libraries/engine/Shortcodes.php');
|
||||
|
||||
// Load default
|
||||
Core::loadPluggable();
|
||||
|
||||
// Init I18n
|
||||
I18n::init(Option::get('language'));
|
||||
|
||||
// Init Plugins API
|
||||
Plugin::init();
|
||||
|
||||
// Init Notification service
|
||||
Notification::init();
|
||||
|
||||
// Load Site module
|
||||
require_once(ROOT . '/libraries/engine/Site.php');
|
||||
|
||||
// Init site module
|
||||
if( ! BACKEND) Site::init();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Autoload helpers
|
||||
*
|
||||
* @param string $class_name Class name
|
||||
*/
|
||||
/*protected static function autoloadHelpers($class_name) {
|
||||
if (file_exists($path = HELPERS . DS . strtolower($class_name) . '.php')) include $path;
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Load Defines
|
||||
*/
|
||||
protected static function loadDefines()
|
||||
{
|
||||
$environments = array(1 => 'production',
|
||||
2 => 'staging',
|
||||
3 => 'testing',
|
||||
4 => 'development');
|
||||
|
||||
$root_defines = ROOT . DS . 'boot' . DS . 'defines.php';
|
||||
$environment_defines = ROOT . DS . 'boot' . DS . $environments[Core::$environment] . DS . 'defines.php';
|
||||
$monstra_defines = ROOT . DS . 'libraries/engine' . DS . 'boot' . DS . 'defines.php';
|
||||
|
||||
if (file_exists($root_defines)) {
|
||||
include $root_defines;
|
||||
} elseif (file_exists($environment_defines)) {
|
||||
include $environment_defines;
|
||||
} elseif (file_exists($monstra_defines)) {
|
||||
include $monstra_defines;
|
||||
} else {
|
||||
throw new RuntimeException("The defines file does not exist.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load Pluggable
|
||||
*/
|
||||
protected static function loadPluggable()
|
||||
{
|
||||
$environments = array(1 => 'production',
|
||||
2 => 'staging',
|
||||
3 => 'testing',
|
||||
4 => 'development');
|
||||
|
||||
$root_pluggable = ROOT . DS . 'boot';
|
||||
$environment_pluggable = ROOT . DS . 'boot' . DS . $environments[Core::$environment];
|
||||
$monstra_pluggable = ROOT . DS . 'libraries/engine' . DS . 'boot';
|
||||
|
||||
if (file_exists($root_pluggable . DS . 'filters.php')) {
|
||||
include $root_pluggable . DS . 'filters.php';
|
||||
} elseif (file_exists($environment_pluggable . DS . 'filters.php')) {
|
||||
include $environment_pluggable . DS . 'filters.php';
|
||||
} elseif (file_exists($monstra_pluggable . DS . 'filters.php')) {
|
||||
include $monstra_pluggable . DS . 'filters.php';
|
||||
} else {
|
||||
throw new RuntimeException("The pluggable file does not exist.");
|
||||
}
|
||||
|
||||
if (file_exists($root_pluggable . DS . 'actions.php')) {
|
||||
include $root_pluggable . DS . 'actions.php';
|
||||
} elseif (file_exists($environment_pluggable . DS . 'actions.php')) {
|
||||
include $environment_pluggable . DS . 'actions.php';
|
||||
} elseif (file_exists($monstra_pluggable . DS . 'actions.php')) {
|
||||
include $monstra_pluggable . DS . 'actions.php';
|
||||
} else {
|
||||
throw new RuntimeException("The pluggable file does not exist.");
|
||||
}
|
||||
|
||||
if (file_exists($root_pluggable . DS . 'shortcodes.php')) {
|
||||
include $root_pluggable . DS . 'shortcodes.php';
|
||||
} elseif (file_exists($environment_pluggable . DS . 'shortcodes.php')) {
|
||||
include $environment_pluggable . DS . 'shortcodes.php';
|
||||
} elseif (file_exists($monstra_pluggable . DS . 'shortcodes.php')) {
|
||||
include $monstra_pluggable . DS . 'shortcodes.php';
|
||||
} else {
|
||||
throw new RuntimeException("The pluggable file does not exist.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception Handler
|
||||
*
|
||||
* @param object $exception An exception object
|
||||
*/
|
||||
public static function exceptionHandler($exception)
|
||||
{
|
||||
// Empty output buffers
|
||||
while (ob_get_level() > 0) ob_end_clean();
|
||||
|
||||
// Send headers and output
|
||||
@header('Content-Type: text/html; charset=UTF-8');
|
||||
@header('HTTP/1.1 500 Internal Server Error');
|
||||
|
||||
// Get highlighted code
|
||||
$code = Core::highlightCode($exception->getFile(), $exception->getLine());
|
||||
|
||||
// Determine error type
|
||||
if ($exception instanceof ErrorException) {
|
||||
|
||||
$error_type = 'ErrorException: ';
|
||||
|
||||
$codes = array (
|
||||
E_ERROR => 'Fatal Error',
|
||||
E_PARSE => 'Parse Error',
|
||||
E_COMPILE_ERROR => 'Compile Error',
|
||||
E_COMPILE_WARNING => 'Compile Warning',
|
||||
E_STRICT => 'Strict Mode Error',
|
||||
E_NOTICE => 'Notice',
|
||||
E_WARNING => 'Warning',
|
||||
E_RECOVERABLE_ERROR => 'Recoverable Error',
|
||||
/*E_DEPRECATED => 'Deprecated',*/ /* PHP 5.3 */
|
||||
E_USER_NOTICE => 'Notice',
|
||||
E_USER_WARNING => 'Warning',
|
||||
E_USER_ERROR => 'Error',
|
||||
/*E_USER_DEPRECATED => 'Deprecated'*/ /* PHP 5.3 */
|
||||
);
|
||||
|
||||
$error_type .= in_array($exception->getCode(), array_keys($codes)) ? $codes[$exception->getCode()] : 'Unknown Error';
|
||||
} else {
|
||||
$error_type = get_class($exception);
|
||||
}
|
||||
|
||||
// Show exception if core environment is DEVELOPMENT
|
||||
if (Core::$environment == Core::DEVELOPMENT) {
|
||||
|
||||
// Development
|
||||
echo ("
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset='utf-8'>
|
||||
<title>Monstra</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; }
|
||||
body { background-color: #EEE; }
|
||||
h1,h2,h3,p{font-family:Verdana;font-weight:lighter;margin:10px;}
|
||||
.exception {border: 1px solid #CCC; padding: 10px; background-color: #FFF; color: #333; margin:10px;}
|
||||
pre, .code {font-family: Courier, monospace; font-size:12px;margin:0px;padding:0px;}
|
||||
.highlighted {background-color: #f0eb96; font-weight: bold; border-top: 1px solid #ccc; border-bottom: 1px solid #ccc;}
|
||||
.code {background:#fff;border:1px solid #ccc;overflow:auto;}
|
||||
.line {display: inline-block; background-color: #EFEFEF; padding: 4px 8px 4px 8px; margin-right:10px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class='exception'>
|
||||
<h1>Monstra - ".$error_type."</h1>
|
||||
<p>".$exception->getMessage()."</p>
|
||||
<h2>Location</h2>
|
||||
<p>Exception thrown on line <code>".$exception->getLine()."</code> in <code>".$exception->getFile()."</code></p>
|
||||
");
|
||||
|
||||
if ( ! empty($code)) {
|
||||
echo '<div class="code">';
|
||||
foreach ($code as $line) {
|
||||
echo '<pre '; if ($line['highlighted']) { echo 'class="highlighted"'; } echo '><span class="line">' . $line['number'] . '</span>' . $line['code'] . '</pre>';
|
||||
}
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
echo '</div></body></html>';
|
||||
|
||||
} else {
|
||||
|
||||
// Production
|
||||
echo ("
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset='utf-8'>
|
||||
<title>Monstra</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; }
|
||||
.exception {border: 1px solid #CCC; padding: 10px; background-color: #FFF; color: #333; margin:10px;}
|
||||
body { background-color: #EEE; font-family: sans-serif; font-size: 16px; line-height: 20px; margin: 40px; }
|
||||
h1,h2,h3,p{font-family:Verdana;font-weight:lighter;margin:10px;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class='exception'>
|
||||
<h1>Oops!</h1>
|
||||
<p>An unexpected error has occurred.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
");
|
||||
}
|
||||
|
||||
// Writes message to log
|
||||
@file_put_contents(LOGS . DS . gmdate('Y_m_d') . '.log',
|
||||
gmdate('Y/m/d H:i:s') . ' --- ' . '['.$error_type.']' . ' --- ' . $exception->getMessage() . ' --- ' . 'Exception thrown on line '.$exception->getLine().' in '.$exception->getFile() . "\n",
|
||||
FILE_APPEND);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts errors to ErrorExceptions.
|
||||
*
|
||||
* @param integer $code The error code
|
||||
* @param string $message The error message
|
||||
* @param string $file The filename where the error occurred
|
||||
* @param integer $line The line number where the error occurred
|
||||
* @return boolean
|
||||
*/
|
||||
public static function errorHandler($code, $message, $file, $line)
|
||||
{
|
||||
// If isset error_reporting and $code then throw new error exception
|
||||
if ((error_reporting() & $code) !== 0) {
|
||||
throw new ErrorException($message, $code, 0, $file, $line);
|
||||
}
|
||||
|
||||
// Don't execute PHP internal error handler
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of lines from a file.
|
||||
*
|
||||
* @param string $file File in which you want to highlight a line
|
||||
* @param integer $line Line number to highlight
|
||||
* @param integer $padding Number of padding lines
|
||||
* @return array
|
||||
*/
|
||||
protected static function highlightCode($file, $line, $padding = 5)
|
||||
{
|
||||
// Is file readable ?
|
||||
if ( ! is_readable($file)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Init vars
|
||||
$lines = array();
|
||||
$current_line = 0;
|
||||
|
||||
// Open file
|
||||
$handle = fopen($file, 'r');
|
||||
|
||||
// Read file
|
||||
while ( ! feof($handle)) {
|
||||
|
||||
$current_line++;
|
||||
|
||||
$temp = fgets($handle);
|
||||
|
||||
if ($current_line > $line + $padding) {
|
||||
break; // Exit loop after we have found what we were looking for
|
||||
}
|
||||
|
||||
if ($current_line >= ($line - $padding) && $current_line <= ($line + $padding)) {
|
||||
|
||||
$lines[] = array (
|
||||
'number' => str_pad($current_line, 4, ' ', STR_PAD_LEFT),
|
||||
'highlighted' => ($current_line === $line),
|
||||
'code' => Core::highlightString($temp),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Close
|
||||
fclose($handle);
|
||||
|
||||
// Return lines
|
||||
return $lines;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Highlight string
|
||||
*
|
||||
* @param string $string String
|
||||
* @return string
|
||||
*/
|
||||
protected static function highlightString($string)
|
||||
{
|
||||
return str_replace(array("\n", '<code>', '</code>', '<span style="color: #0000BB"><?php ', '#$@r4!/*'),
|
||||
array('', '', '', '<span style="color: #0000BB">', '/*'),
|
||||
highlight_string('<?php ' . str_replace('/*', '#$@r4!/*', $string), true));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert errors not caught by the errorHandler to ErrorExceptions.
|
||||
*/
|
||||
public static function fatalErrorHandler()
|
||||
{
|
||||
// Get last error
|
||||
$error = error_get_last();
|
||||
|
||||
// If isset error then throw new error exception
|
||||
if (isset($error) && ($error['type'] === E_ERROR)) {
|
||||
|
||||
Core::exceptionHandler(new ErrorException($error['message'], $error['type'], 0, $error['file'], $error['line']));
|
||||
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize Monstra engine
|
||||
*
|
||||
* @return Core
|
||||
*/
|
||||
public static function init()
|
||||
{
|
||||
if ( ! isset(self::$instance)) self::$instance = new Core();
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
}
|
183
libraries/engine/Options.php
Normal file
183
libraries/engine/Options.php
Normal file
@@ -0,0 +1,183 @@
|
||||
<?php defined('MONSTRA_ACCESS') or die('No direct script access.');
|
||||
|
||||
/**
|
||||
* Monstra Options API module
|
||||
*
|
||||
* @package Monstra
|
||||
* @subpackage Engine
|
||||
* @author Romanenko Sergey / Awilum
|
||||
* @copyright 2012 Romanenko Sergey / Awilum
|
||||
* @version $Id$
|
||||
* @since 1.0.0
|
||||
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
|
||||
* Monstra is free software. This version may have been modified pursuant
|
||||
* to the GNU General Public License, and as distributed it includes or
|
||||
* is derivative of works licensed under the GNU General Public License or
|
||||
* other free or open source software licenses.
|
||||
* See COPYING.txt for copyright notices and details.
|
||||
* @filesource
|
||||
*/
|
||||
|
||||
class Option
|
||||
{
|
||||
/**
|
||||
* Options
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $options = null;
|
||||
|
||||
/**
|
||||
* An instance of the Option class
|
||||
*
|
||||
* @var option
|
||||
*/
|
||||
protected static $instance = null;
|
||||
|
||||
/**
|
||||
* Initializing options
|
||||
*
|
||||
* @param string $name Options file
|
||||
*/
|
||||
public static function init()
|
||||
{
|
||||
if ( ! isset(self::$instance)) self::$instance = new Option();
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Protected clone method to enforce singleton behavior.
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function __clone()
|
||||
{
|
||||
// Nothing here.
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
Option::$options = new Table('options');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new option
|
||||
*
|
||||
* <code>
|
||||
* Option::add('pages_limit', 10);
|
||||
* Option::add(array('pages_count' => 10, 'pages_default' => 'home'));
|
||||
* </code>
|
||||
*
|
||||
* @param mixed $option Name of option to add.
|
||||
* @param mixed $value Option value.
|
||||
* @return boolean
|
||||
*/
|
||||
public static function add($option, $value = null)
|
||||
{
|
||||
if (is_array($option)) {
|
||||
foreach ($option as $k => $v) {
|
||||
$_option = Option::$options->select('[name="'.$k.'"]', null);
|
||||
if (count($_option) == 0) {
|
||||
Option::$options->insert(array('name' => $k, 'value' => $v));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$_option = Option::$options->select('[name="'.$option.'"]', null);
|
||||
if (count($_option) == 0) {
|
||||
return Option::$options->insert(array('name' => $option, 'value' => $value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update option value
|
||||
*
|
||||
* <code>
|
||||
* Option::update('pages_limit', 12);
|
||||
* Option::update(array('pages_count' => 10, 'pages_default' => 'home'));
|
||||
* </code>
|
||||
*
|
||||
* @param mixed $option Name of option to update.
|
||||
* @param mixed $value Option value.
|
||||
* @return boolean
|
||||
*/
|
||||
public static function update($option, $value = null)
|
||||
{
|
||||
if (is_array($option)) {
|
||||
foreach ($option as $k => $v) {
|
||||
Option::$options->updateWhere('[name="'.$k.'"]', array('value' => $v));
|
||||
}
|
||||
} else {
|
||||
return Option::$options->updateWhere('[name="'.$option.'"]', array('value' => $value));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get option value
|
||||
*
|
||||
* <code>
|
||||
* $pages_limit = Option::get('pages_limit');
|
||||
* if ($pages_limit == '10') {
|
||||
* // do something...
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @param string $option Name of option to get.
|
||||
* @return string
|
||||
*/
|
||||
public static function get($option)
|
||||
{
|
||||
// Redefine vars
|
||||
$option = (string) $option;
|
||||
|
||||
// Select specific option
|
||||
$option_name = Option::$options->select('[name="'.$option.'"]', null);
|
||||
|
||||
// Return specific option value
|
||||
return isset($option_name['value']) ? $option_name['value'] : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete option
|
||||
*
|
||||
* <code>
|
||||
* Option::delete('pages_limit');
|
||||
* </code>
|
||||
*
|
||||
* @param string $option Name of option to delete.
|
||||
* @return boolean
|
||||
*/
|
||||
public static function delete($option)
|
||||
{
|
||||
// Redefine vars
|
||||
$option = (string) $option;
|
||||
|
||||
// Delete specific option
|
||||
return Option::$options->deleteWhere('[name="'.$option.'"]');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if option exist
|
||||
*
|
||||
* <code>
|
||||
* if (Option::exists('pages_limit')) {
|
||||
* // do something...
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @param string $option Name of option to check.
|
||||
* @return boolean
|
||||
*/
|
||||
public static function exists($option)
|
||||
{
|
||||
// Redefine vars
|
||||
$option = (string) $option;
|
||||
|
||||
// Check if option exists
|
||||
return (count(Option::$options->select('[name="'.$option.'"]', null)) > 0) ? true : false;
|
||||
}
|
||||
|
||||
}
|
1228
libraries/engine/Plugins.php
Normal file
1228
libraries/engine/Plugins.php
Normal file
File diff suppressed because it is too large
Load Diff
180
libraries/engine/Shortcodes.php
Normal file
180
libraries/engine/Shortcodes.php
Normal file
@@ -0,0 +1,180 @@
|
||||
<?php defined('MONSTRA_ACCESS') or die('No direct script access.');
|
||||
|
||||
/**
|
||||
* Monstra Shortcodes API
|
||||
*
|
||||
* The Shortcode API s a simple regex based parser that allows you to replace simple bbcode-like tags
|
||||
* within a HTMLText or HTMLVarchar field when rendered into a content.
|
||||
*
|
||||
* Examples of shortcode tags:
|
||||
*
|
||||
* {shortcode}
|
||||
* {shortcode parameter="value"}
|
||||
* {shortcode parameter="value"}Enclosed Content{/shortcode}
|
||||
*
|
||||
*
|
||||
* Example of escaping shortcodes:
|
||||
*
|
||||
* {{shortcode}}
|
||||
*
|
||||
*
|
||||
* @package Monstra
|
||||
* @subpackage Engine
|
||||
* @author Romanenko Sergey / Awilum
|
||||
* @copyright 2012 Romanenko Sergey / Awilum
|
||||
* @version $Id$
|
||||
* @since 1.0.0
|
||||
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
|
||||
* Monstra is free software. This version may have been modified pursuant
|
||||
* to the GNU General Public License, and as distributed it includes or
|
||||
* is derivative of works licensed under the GNU General Public License or
|
||||
* other free or open source software licenses.
|
||||
* See COPYING.txt for copyright notices and details.
|
||||
* @filesource
|
||||
*/
|
||||
|
||||
class Shortcode
|
||||
{
|
||||
/**
|
||||
* Shortcode tags array
|
||||
*
|
||||
* @var shortcode_tags
|
||||
*/
|
||||
protected static $shortcode_tags = array();
|
||||
|
||||
/**
|
||||
* Protected constructor since this is a static class.
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
// Nothing here
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new shortcode
|
||||
*
|
||||
* <code>
|
||||
* function returnSiteUrl() {
|
||||
* return Option::get('siteurl');
|
||||
* }
|
||||
*
|
||||
* // Add shortcode {siteurl}
|
||||
* Shortcode::add('siteurl', 'returnSiteUrl');
|
||||
* </code>
|
||||
*
|
||||
* @param string $shortcode Shortcode tag to be searched in content.
|
||||
* @param string $callback_function The callback function to replace the shortcode with.
|
||||
*/
|
||||
public static function add($shortcode, $callback_function)
|
||||
{
|
||||
// Redefine vars
|
||||
$shortcode = (string) $shortcode;
|
||||
|
||||
// Add new shortcode
|
||||
if (is_callable($callback_function)) Shortcode::$shortcode_tags[$shortcode] = $callback_function;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a specific registered shortcode.
|
||||
*
|
||||
* <code>
|
||||
* Shortcode::delete('shortcode_name');
|
||||
* </code>
|
||||
*
|
||||
* @param string $shortcode Shortcode tag.
|
||||
*/
|
||||
public static function delete($shortcode)
|
||||
{
|
||||
// Redefine vars
|
||||
$shortcode = (string) $shortcode;
|
||||
|
||||
// Delete shortcode
|
||||
if (Shortcode::exists($shortcode)) unset(Shortcode::$shortcode_tags[$shortcode]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all registered shortcodes.
|
||||
*
|
||||
* <code>
|
||||
* Shortcode::clear();
|
||||
* </code>
|
||||
*
|
||||
*/
|
||||
public static function clear()
|
||||
{
|
||||
Shortcode::$shortcode_tags = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a shortcode has been registered.
|
||||
*
|
||||
* <code>
|
||||
* if (Shortcode::exists('shortcode_name')) {
|
||||
* // do something...
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @param string $shortcode Shortcode tag.
|
||||
*/
|
||||
public static function exists($shortcode)
|
||||
{
|
||||
// Redefine vars
|
||||
$shortcode = (string) $shortcode;
|
||||
|
||||
// Check shortcode
|
||||
return array_key_exists($shortcode, Shortcode::$shortcode_tags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a string, and replace any registered shortcodes within it with the result of the mapped callback.
|
||||
*
|
||||
* <code>
|
||||
* $content = Shortcode::parse($content);
|
||||
* </code>
|
||||
*
|
||||
* @param string $content Content
|
||||
* @return string
|
||||
*/
|
||||
public static function parse($content)
|
||||
{
|
||||
if ( ! Shortcode::$shortcode_tags) return $content;
|
||||
|
||||
$shortcodes = implode('|', array_map('preg_quote', array_keys(Shortcode::$shortcode_tags)));
|
||||
$pattern = "/(.?)\{([$shortcodes]+)(.*?)(\/)?\}(?(4)|(?:(.+?)\{\/\s*\\2\s*\}))?(.?)/s";
|
||||
|
||||
return preg_replace_callback($pattern, 'Shortcode::_handle', $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* _handle()
|
||||
*/
|
||||
protected static function _handle($matches)
|
||||
{
|
||||
$prefix = $matches[1];
|
||||
$suffix = $matches[6];
|
||||
$shortcode = $matches[2];
|
||||
|
||||
// Allow for escaping shortcodes by enclosing them in {{shortcode}}
|
||||
if ($prefix == '{' && $suffix == '}') {
|
||||
return substr($matches[0], 1, -1);
|
||||
}
|
||||
|
||||
$attributes = array(); // Parse attributes into into this array.
|
||||
|
||||
if (preg_match_all('/(\w+) *= *(?:([\'"])(.*?)\\2|([^ "\'>]+))/', $matches[3], $match, PREG_SET_ORDER)) {
|
||||
foreach ($match as $attribute) {
|
||||
if ( ! empty($attribute[4])) {
|
||||
$attributes[strtolower($attribute[1])] = $attribute[4];
|
||||
} elseif ( ! empty($attribute[3])) {
|
||||
$attributes[strtolower($attribute[1])] = $attribute[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if this shortcode realy exists then call user function else return empty string
|
||||
return (isset(Shortcode::$shortcode_tags[$shortcode])) ? $prefix . call_user_func(Shortcode::$shortcode_tags[$shortcode], $attributes, $matches[5], $shortcode) . $suffix : '';
|
||||
}
|
||||
|
||||
}
|
227
libraries/engine/Site.php
Normal file
227
libraries/engine/Site.php
Normal file
@@ -0,0 +1,227 @@
|
||||
<?php defined('MONSTRA_ACCESS') or die('No direct script access.');
|
||||
|
||||
/**
|
||||
* Monstra Site module
|
||||
*
|
||||
* @package Monstra
|
||||
* @subpackage Engine
|
||||
* @author Romanenko Sergey / Awilum
|
||||
* @copyright 2012 Romanenko Sergey / Awilum
|
||||
* @version $Id$
|
||||
* @since 1.0.0
|
||||
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
|
||||
* Monstra is free software. This version may have been modified pursuant
|
||||
* to the GNU General Public License, and as distributed it includes or
|
||||
* is derivative of works licensed under the GNU General Public License or
|
||||
* other free or open source software licenses.
|
||||
* See COPYING.txt for copyright notices and details.
|
||||
* @filesource
|
||||
*/
|
||||
|
||||
class Site
|
||||
{
|
||||
/**
|
||||
* An instance of the Site class
|
||||
*
|
||||
* @var site
|
||||
*/
|
||||
protected static $instance = null;
|
||||
|
||||
/**
|
||||
* Initializing site
|
||||
*
|
||||
* @return Site
|
||||
*/
|
||||
public static function init()
|
||||
{
|
||||
if ( ! isset(self::$instance)) self::$instance = new Site();
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Protected clone method to enforce singleton behavior.
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function __clone()
|
||||
{
|
||||
// Nothing here.
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
call_user_func(ucfirst(Uri::command()).'::main');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get site name
|
||||
*
|
||||
* <code>
|
||||
* echo Site::name();
|
||||
* </code>
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function name()
|
||||
{
|
||||
return Option::get('sitename');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get site theme
|
||||
*
|
||||
* <code>
|
||||
* echo Site::theme();
|
||||
* </code>
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function theme()
|
||||
{
|
||||
return Option::get('theme_site_name');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Page title
|
||||
*
|
||||
* <code>
|
||||
* echo Site::title();
|
||||
* </code>
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function title()
|
||||
{
|
||||
return call_user_func(ucfirst(Uri::command()).'::title');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get page description
|
||||
*
|
||||
* <code>
|
||||
* echo Site::description();
|
||||
* </code>
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function description()
|
||||
{
|
||||
return (($description = trim(call_user_func(ucfirst(Uri::command()).'::description'))) == '') ? Html::toText(Option::get('description')) : Html::toText($description);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get page keywords
|
||||
*
|
||||
* <code>
|
||||
* echo Site::keywords();
|
||||
* </code>
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function keywords()
|
||||
{
|
||||
return (($keywords = trim(call_user_func(ucfirst(Uri::command()).'::keywords'))) == '') ? Html::toText(Option::get('keywords')) : Html::toText($keywords);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get site slogan
|
||||
*
|
||||
* <code>
|
||||
* echo Site::slogan();
|
||||
* </code>
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function slogan()
|
||||
{
|
||||
return Option::get('slogan');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get page content
|
||||
*
|
||||
* <code>
|
||||
* echo Site::content();
|
||||
* </code>
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function content()
|
||||
{
|
||||
return Filter::apply('content', call_user_func(ucfirst(Uri::command()).'::content'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get compressed template
|
||||
*
|
||||
* <code>
|
||||
* echo Site::template();
|
||||
* </code>
|
||||
*
|
||||
* @param string $theme Theme name
|
||||
* @return mixed
|
||||
*/
|
||||
public static function template($theme = null)
|
||||
{
|
||||
// Get specific theme or current theme
|
||||
$current_theme = ($theme == null) ? Option::get('theme_site_name') : $theme ;
|
||||
|
||||
// Get template
|
||||
$template = call_user_func(ucfirst(Uri::command()).'::template');
|
||||
|
||||
// Check whether is there such a template in the current theme
|
||||
// else return default template: index
|
||||
// also compress template file :)
|
||||
if (File::exists(THEMES_SITE . DS . $current_theme . DS . $template . '.template.php')) {
|
||||
if ( ! file_exists(MINIFY . DS . 'theme.' . $current_theme . '.minify.' . $template . '.template.php') or
|
||||
filemtime(THEMES_SITE . DS . $current_theme . DS . $template .'.template.php') > filemtime(MINIFY . DS . 'theme.' . $current_theme . '.minify.' . $template . '.template.php')) {
|
||||
$buffer = file_get_contents(THEMES_SITE. DS . $current_theme . DS . $template .'.template.php');
|
||||
$buffer = Minify::html($buffer);
|
||||
file_put_contents(MINIFY . DS . 'theme.' . $current_theme . '.minify.' . $template . '.template.php', $buffer);
|
||||
}
|
||||
|
||||
return 'minify.'.$template;
|
||||
} else {
|
||||
if ( ! File::exists(MINIFY . DS . 'theme.' . $current_theme . '.' . 'minify.index.template.php') or
|
||||
filemtime(THEMES_SITE . DS . $current_theme . DS . 'index.template.php') > filemtime(MINIFY . DS . 'theme.' . $current_theme . '.' . 'minify.index.template.php')) {
|
||||
$buffer = file_get_contents(THEMES_SITE . DS . $current_theme . DS . 'index.template.php');
|
||||
$buffer = Minify::html($buffer);
|
||||
file_put_contents(MINIFY . DS . 'theme.' . $current_theme . '.' . 'minify.index.template.php', $buffer);
|
||||
}
|
||||
|
||||
return 'minify.index';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get site url
|
||||
*
|
||||
* <code>
|
||||
* echo Site::url();
|
||||
* </code>
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function url()
|
||||
{
|
||||
return Option::get('siteurl');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get copyright information
|
||||
*
|
||||
* <code>
|
||||
* echo Site::powered();
|
||||
* </code>
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function powered()
|
||||
{
|
||||
return __('Powered by', 'system').' <a href="http://monstra.org" target="_blank">Monstra</a> ' . Core::VERSION;
|
||||
}
|
||||
|
||||
}
|
163
libraries/engine/Uri.php
Normal file
163
libraries/engine/Uri.php
Normal file
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Monstra Library
|
||||
*
|
||||
* This source file is part of the Monstra Library. More information,
|
||||
* documentation and tutorials can be found at http://library.monstra.org
|
||||
*
|
||||
* @package Monstra
|
||||
*
|
||||
* @author Romanenko Sergey / Awilum
|
||||
* @copyright (c) 2012 - 2013 Romanenko Sergey / Awilum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
class Uri
|
||||
{
|
||||
/**
|
||||
* Protected constructor since this is a static class.
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
// Nothing here
|
||||
}
|
||||
|
||||
/**
|
||||
* Default component
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $default_component = 'pages';
|
||||
|
||||
/**
|
||||
* Get uri and explode command/param1/param2
|
||||
*
|
||||
* <code>
|
||||
* $segments = Uri::segments();
|
||||
* </code>
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function segments()
|
||||
{
|
||||
// Get request uri and current script path
|
||||
$request_uri = explode('/', $_SERVER['REQUEST_URI']);
|
||||
$script_name = explode('/', $_SERVER['SCRIPT_NAME']);
|
||||
|
||||
// Delete script name
|
||||
for ($i = 0; $i < sizeof($script_name); $i++) {
|
||||
if ($request_uri[$i] == $script_name[$i]) {
|
||||
unset($request_uri[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Get all the values of an array
|
||||
$uri = array_values($request_uri);
|
||||
|
||||
// Ability to pass parameters
|
||||
foreach ($uri as $i => $u) {
|
||||
if (isset($uri[$i])) { $pos = strrpos($uri[$i], "?"); if ($pos === false) { $uri[$i] = Security::sanitizeURL($uri[$i]); } else { $uri[$i] = Security::sanitizeURL(substr($uri[$i], 0, $pos)); } }
|
||||
}
|
||||
|
||||
// Return uri segments
|
||||
return $uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get uri segment
|
||||
*
|
||||
* <code>
|
||||
* $segment = Uri::segment(1);
|
||||
* </code>
|
||||
*
|
||||
* @param integer $segment Segment
|
||||
* @return mixed
|
||||
*/
|
||||
public static function segment($segment)
|
||||
{
|
||||
$segments = Uri::segments();
|
||||
|
||||
return isset($segments[$segment]) ? $segments[$segment] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get command/component from registed components
|
||||
*
|
||||
* <code>
|
||||
* $command = Uri::command();
|
||||
* </code>
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function command()
|
||||
{
|
||||
// Get uri segments
|
||||
$uri = Uri::segments();
|
||||
|
||||
if ( ! isset($uri[0])) {
|
||||
$uri[0] = Uri::$default_component;
|
||||
} else {
|
||||
if ( ! in_array($uri[0], Plugin::$components) ) {
|
||||
$uri[0] = Uri::$default_component;
|
||||
} else {
|
||||
$uri[0] = $uri[0];
|
||||
}
|
||||
}
|
||||
|
||||
return $uri[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get uri parammeters
|
||||
*
|
||||
* <code>
|
||||
* $params = Uri::params();
|
||||
* </code>
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function params()
|
||||
{
|
||||
//Init data array
|
||||
$data = array();
|
||||
|
||||
// Get URI
|
||||
$uri = Uri::segments();
|
||||
|
||||
// http://site.com/ and http://site.com/index.php same main home pages
|
||||
if ( ! isset($uri[0])) {
|
||||
$uri[0] = '';
|
||||
}
|
||||
|
||||
// param1/param2
|
||||
if ($uri[0] !== Uri::$default_component) {
|
||||
if (isset($uri[1])) {
|
||||
$data[0] = $uri[0];
|
||||
$data[1] = $uri[1];
|
||||
// Some more uri parts :)
|
||||
// site.ru/part1/part2/part3/part4/part5/part6/
|
||||
if (isset($uri[2])) $data[2] = $uri[2];
|
||||
if (isset($uri[3])) $data[3] = $uri[3];
|
||||
if (isset($uri[4])) $data[4] = $uri[4];
|
||||
if (isset($uri[5])) $data[5] = $uri[5];
|
||||
} else { // default
|
||||
$data[0] = $uri[0];
|
||||
}
|
||||
} else {
|
||||
// This is good for box plugin Pages
|
||||
// parent/child
|
||||
if (isset($uri[2])) {
|
||||
$data[0] = $uri[1];
|
||||
$data[1] = $uri[2];
|
||||
} else { // default
|
||||
$data[0] = $uri[1];
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
1036
libraries/engine/Xmldb.php
Normal file
1036
libraries/engine/Xmldb.php
Normal file
File diff suppressed because it is too large
Load Diff
53
libraries/engine/_init.php
Normal file
53
libraries/engine/_init.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php defined('MONSTRA_ACCESS') or die('No direct script access.');
|
||||
|
||||
/**
|
||||
* Include engine core
|
||||
*/
|
||||
include ROOT . '/libraries/monstra/Monstra.php';
|
||||
include ROOT . '/libraries/engine/Core.php';
|
||||
|
||||
/**
|
||||
* Set core environment
|
||||
*
|
||||
* Monstra has four predefined environments:
|
||||
* Core::DEVELOPMENT - The development environment.
|
||||
* Core::TESTING - The test environment.
|
||||
* Core::STAGING - The staging environment.
|
||||
* Core::PRODUCTION - The production environment.
|
||||
*/
|
||||
Core::$environment = Core::DEVELOPMENT;
|
||||
|
||||
/**
|
||||
* Monstra requires PHP 5.2.0 or greater
|
||||
*/
|
||||
if (version_compare(PHP_VERSION, "5.2.0", "<")) {
|
||||
exit("Monstra requires PHP 5.2.0 or greater.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Report Errors
|
||||
*/
|
||||
if (Core::$environment == Core::PRODUCTION) {
|
||||
|
||||
/**
|
||||
* Report All Errors
|
||||
*
|
||||
* By setting error reporting to -1, we essentially force PHP to report
|
||||
* every error, and this is guranteed to show every error on future
|
||||
* releases of PHP. This allows everything to be fixed early!
|
||||
*/
|
||||
error_reporting(0);
|
||||
|
||||
} else {
|
||||
|
||||
/**
|
||||
* Production environment
|
||||
*/
|
||||
error_reporting(-1);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize core
|
||||
*/
|
||||
Core::init();
|
7
libraries/engine/boot/actions.php
Normal file
7
libraries/engine/boot/actions.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Set meta generator
|
||||
*/
|
||||
Action::add('theme_meta', 'setMetaGenerator');
|
||||
function setMetaGenerator() { echo '<meta name="generator" content="Powered by Monstra '.Core::VERSION.'" />'; }
|
93
libraries/engine/boot/defines.php
Normal file
93
libraries/engine/boot/defines.php
Normal file
@@ -0,0 +1,93 @@
|
||||
<?php defined('MONSTRA_ACCESS') or die('No direct script access.');
|
||||
|
||||
/**
|
||||
* Monstra CMS Defines
|
||||
*/
|
||||
|
||||
/**
|
||||
* The filesystem path to the site 'themes' folder
|
||||
*/
|
||||
define('THEMES_SITE', ROOT . DS . 'public' . DS . 'themes');
|
||||
|
||||
/**
|
||||
* The filesystem path to the admin 'themes' folder
|
||||
*/
|
||||
define('THEMES_ADMIN', ROOT . DS . 'admin' . DS . 'themes');
|
||||
|
||||
/**
|
||||
* The filesystem path to the 'plugins' folder
|
||||
*/
|
||||
define('PLUGINS', ROOT . DS . 'plugins');
|
||||
|
||||
/**
|
||||
* The filesystem path to the 'box' folder which is contained within
|
||||
* the 'plugins' folder
|
||||
*/
|
||||
define('PLUGINS_BOX', PLUGINS . DS . 'box');
|
||||
|
||||
/**
|
||||
* The filesystem path to the 'storage' folder
|
||||
*/
|
||||
define('STORAGE', ROOT . DS . 'storage');
|
||||
|
||||
/**
|
||||
* The filesystem path to the 'xmldb' folder
|
||||
*/
|
||||
define('XMLDB', STORAGE . DS . 'database');
|
||||
|
||||
/**
|
||||
* The filesystem path to the 'cache' folder
|
||||
*/
|
||||
define('CACHE', ROOT . DS . 'tmp' . DS . 'cache');
|
||||
|
||||
/**
|
||||
* The filesystem path to the 'minify' folder
|
||||
*/
|
||||
define('MINIFY', ROOT . DS . 'tmp' . DS . 'minify');
|
||||
|
||||
/**
|
||||
* The filesystem path to the 'logs' folder
|
||||
*/
|
||||
define('LOGS', ROOT . DS . 'tmp' . DS . 'logs');
|
||||
|
||||
/**
|
||||
* The filesystem path to the 'assets' folder
|
||||
*/
|
||||
define('ASSETS', ROOT . DS . 'public' . DS . 'assets');
|
||||
|
||||
/**
|
||||
* The filesystem path to the 'uploads' folder
|
||||
*/
|
||||
define('UPLOADS', ROOT . DS . 'public' . DS . 'uploads');
|
||||
|
||||
/**
|
||||
* Set password salt
|
||||
*/
|
||||
define('MONSTRA_PASSWORD_SALT', 'YOUR_SALT_HERE');
|
||||
|
||||
/**
|
||||
* Set date format
|
||||
*/
|
||||
define('MONSTRA_DATE_FORMAT', 'Y-m-d / H:i:s');
|
||||
|
||||
/**
|
||||
* Set eval php
|
||||
*/
|
||||
define('MONSTRA_EVAL_PHP', false);
|
||||
|
||||
/**
|
||||
* Check Monstra CMS version
|
||||
*/
|
||||
define('CHECK_MONSTRA_VERSION', true);
|
||||
|
||||
/**
|
||||
* Set gzip output
|
||||
*/
|
||||
define('MONSTRA_GZIP', false);
|
||||
|
||||
/**
|
||||
* Monstra database settings
|
||||
*/
|
||||
//define('MONSTRA_DB_DSN', 'mysql:dbname=monstra;host=localhost;port=3306');
|
||||
//define('MONSTRA_DB_USER', 'root');
|
||||
//define('MONSTRA_DB_PASSWORD', 'password');
|
21
libraries/engine/boot/filters.php
Normal file
21
libraries/engine/boot/filters.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Evaluate a string as PHP code
|
||||
*/
|
||||
if (MONSTRA_EVAL_PHP) Filter::add('content', 'evalPHP');
|
||||
function obEval($mathes)
|
||||
{
|
||||
ob_start();
|
||||
eval($mathes[1]);
|
||||
$mathes = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
return $mathes;
|
||||
}
|
||||
function evalPHP($str) { return preg_replace_callback('/\[php\](.*?)\[\/php\]/ms','obEval', $str); }
|
||||
|
||||
/**
|
||||
* Add shortcode parser filter
|
||||
*/
|
||||
Filter::add('content', 'Shortcode::parse', 11);
|
7
libraries/engine/boot/shortcodes.php
Normal file
7
libraries/engine/boot/shortcodes.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Add new shortcode {siteurl}
|
||||
*/
|
||||
Shortcode::add('siteurl', 'returnSiteUrl');
|
||||
function returnSiteUrl() { return Option::get('siteurl'); }
|
162
libraries/monstra/Agent.php
Normal file
162
libraries/monstra/Agent.php
Normal file
@@ -0,0 +1,162 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Monstra Library
|
||||
*
|
||||
* This source file is part of the Monstra Library. More information,
|
||||
* documentation and tutorials can be found at http://library.monstra.org
|
||||
*
|
||||
* @package Monstra
|
||||
*
|
||||
* @author Romanenko Sergey / Awilum
|
||||
* @copyright (c) 2012 - 2013 Romanenko Sergey / Awilum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
class Agent
|
||||
{
|
||||
/**
|
||||
* Mobiles
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $mobiles = array (
|
||||
'ipad',
|
||||
'iphone',
|
||||
'ipod',
|
||||
'android',
|
||||
'windows ce',
|
||||
'windows phone',
|
||||
'mobileexplorer',
|
||||
'opera mobi',
|
||||
'opera mini',
|
||||
'fennec',
|
||||
'blackberry',
|
||||
'nokia',
|
||||
'kindle',
|
||||
'ericsson',
|
||||
'motorola',
|
||||
'minimo',
|
||||
'iemobile',
|
||||
'symbian',
|
||||
'webos',
|
||||
'hiptop',
|
||||
'palmos',
|
||||
'palmsource',
|
||||
'xiino',
|
||||
'avantgo',
|
||||
'docomo',
|
||||
'up.browser',
|
||||
'vodafone',
|
||||
'portable',
|
||||
'pocket',
|
||||
'mobile',
|
||||
'phone',
|
||||
);
|
||||
|
||||
/**
|
||||
* Robots
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $robots = array(
|
||||
'googlebot',
|
||||
'msnbot',
|
||||
'slurp',
|
||||
'yahoo',
|
||||
'askjeeves',
|
||||
'fastcrawler',
|
||||
'infoseek',
|
||||
'lycos',
|
||||
'ia_archiver',
|
||||
);
|
||||
|
||||
/**
|
||||
* Protected constructor since this is a static class.
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
// Nothing here
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for a string in the user agent string.
|
||||
*
|
||||
* @param array $agents Array of strings to look for
|
||||
* @return boolean
|
||||
*/
|
||||
protected static function find($agents)
|
||||
{
|
||||
// If isset HTTP_USER_AGENT ?
|
||||
if (isset($_SERVER['HTTP_USER_AGENT'])) {
|
||||
|
||||
// Loop through $agents array
|
||||
foreach ($agents as $agent) {
|
||||
|
||||
// If current user agent == agents[agent] then return true
|
||||
if (stripos($_SERVER['HTTP_USER_AGENT'], $agent) !== false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Else return false
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the user agent that made the request is identified as a mobile device.
|
||||
*
|
||||
* <code>
|
||||
* if (Agent::isMobile()) {
|
||||
* // Do something...
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isMobile()
|
||||
{
|
||||
return Agent::find(Agent::$mobiles);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the user agent that made the request is identified as a robot/crawler.
|
||||
*
|
||||
* <code>
|
||||
* if (Agent::isRobot()) {
|
||||
* // Do something...
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isRobot()
|
||||
{
|
||||
return Agent::find(Agent::$robots);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns TRUE if the string you're looking for exists in the user agent string and FALSE if not.
|
||||
*
|
||||
* <code>
|
||||
* if (Agent::is('iphone')) {
|
||||
* // Do something...
|
||||
* }
|
||||
*
|
||||
* if (Agent::is(array('iphone', 'ipod'))) {
|
||||
* // Do something...
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @param mixed $device String or array of strings you're looking for
|
||||
* @return boolean
|
||||
*/
|
||||
public static function is($device)
|
||||
{
|
||||
return Agent::find((array) $device);
|
||||
}
|
||||
|
||||
}
|
88
libraries/monstra/Alert.php
Normal file
88
libraries/monstra/Alert.php
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Monstra Library
|
||||
*
|
||||
* This source file is part of the Monstra Library. More information,
|
||||
* documentation and tutorials can be found at http://library.monstra.org
|
||||
*
|
||||
* @package Monstra
|
||||
*
|
||||
* @author Romanenko Sergey / Awilum
|
||||
* @copyright (c) 2012 - 2013 Romanenko Sergey / Awilum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
class Alert
|
||||
{
|
||||
/**
|
||||
* Protected constructor since this is a static class.
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
// Nothing here
|
||||
}
|
||||
|
||||
/**
|
||||
* Show success message
|
||||
*
|
||||
* <code>
|
||||
* Alert::success('Message here...');
|
||||
* </code>
|
||||
*
|
||||
* @param string $message Message
|
||||
* @param integer $time Time
|
||||
*/
|
||||
public static function success($message, $time = 3000)
|
||||
{
|
||||
// Redefine vars
|
||||
$message = (string) $message;
|
||||
$time = (int) $time;
|
||||
|
||||
echo '<div class="alert alert-info">'.$message.'</div>
|
||||
<script type="text/javascript">setTimeout(\'$(".alert").slideUp("slow")\', '.$time.'); </script>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Show warning message
|
||||
*
|
||||
* <code>
|
||||
* Alert::warning('Message here...');
|
||||
* </code>
|
||||
*
|
||||
* @param string $message Message
|
||||
* @param integer $time Time
|
||||
*/
|
||||
public static function warning($message, $time = 3000)
|
||||
{
|
||||
// Redefine vars
|
||||
$message = (string) $message;
|
||||
$time = (int) $time;
|
||||
|
||||
echo '<div class="alert alert-warning">'.$message.'</div>
|
||||
<script type="text/javascript">setTimeout(\'$(".alert").slideUp("slow")\', '.$time.'); </script>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Show error message
|
||||
*
|
||||
* <code>
|
||||
* Alert::error('Message here...');
|
||||
* </code>
|
||||
*
|
||||
* @param string $message Message
|
||||
* @param integer $time Time
|
||||
*/
|
||||
public static function error($message, $time = 3000)
|
||||
{
|
||||
// Redefine vars
|
||||
$message = (string) $message;
|
||||
$time = (int) $time;
|
||||
|
||||
echo '<div class="alert alert-error">'.$message.'</div>
|
||||
<script type="text/javascript">setTimeout(\'$(".alert").slideUp("slow")\', '.$time.'); </script>';
|
||||
}
|
||||
|
||||
}
|
185
libraries/monstra/Arr.php
Normal file
185
libraries/monstra/Arr.php
Normal file
@@ -0,0 +1,185 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Monstra Library
|
||||
*
|
||||
* This source file is part of the Monstra Library. More information,
|
||||
* documentation and tutorials can be found at http://library.monstra.org
|
||||
*
|
||||
* @package Monstra
|
||||
*
|
||||
* @author Romanenko Sergey / Awilum
|
||||
* @copyright (c) 2012 - 2013 Romanenko Sergey / Awilum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
class Arr
|
||||
{
|
||||
/**
|
||||
* Protected constructor since this is a static class.
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
// Nothing here
|
||||
}
|
||||
|
||||
/**
|
||||
* Subval sort
|
||||
*
|
||||
* <code>
|
||||
* $new_array = Arr::subvalSort($old_array, 'sort');
|
||||
* </code>
|
||||
*
|
||||
* @param array $a Array
|
||||
* @param string $subkey Key
|
||||
* @param string $order Order type DESC or ASC
|
||||
* @return array
|
||||
*/
|
||||
public static function subvalSort($a, $subkey, $order = null)
|
||||
{
|
||||
if (count($a) != 0 || (!empty($a))) {
|
||||
foreach ($a as $k => $v) $b[$k] = function_exists('mb_strtolower') ? mb_strtolower($v[$subkey]) : strtolower($v[$subkey]);
|
||||
if ($order == null || $order == 'ASC') asort($b); else if ($order == 'DESC') arsort($b);
|
||||
foreach ($b as $key => $val) $c[] = $a[$key];
|
||||
|
||||
return $c;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns value from array using "dot notation".
|
||||
* If the key does not exist in the array, the default value will be returned instead.
|
||||
*
|
||||
* <code>
|
||||
* $login = Arr::get($_POST, 'login');
|
||||
*
|
||||
* $array = array('foo' => 'bar');
|
||||
* $foo = Arr::get($array, 'foo');
|
||||
*
|
||||
* $array = array('test' => array('foo' => 'bar'));
|
||||
* $foo = Arr::get($array, 'test.foo');
|
||||
* </code>
|
||||
*
|
||||
* @param array $array Array to extract from
|
||||
* @param string $path Array path
|
||||
* @param mixed $default Default value
|
||||
* @return mixed
|
||||
*/
|
||||
public static function get($array, $path, $default = null)
|
||||
{
|
||||
// Get segments from path
|
||||
$segments = explode('.', $path);
|
||||
|
||||
// Loop through segments
|
||||
foreach ($segments as $segment) {
|
||||
|
||||
// Check
|
||||
if ( ! is_array($array) || !isset($array[$segment])) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
// Write
|
||||
$array = $array[$segment];
|
||||
}
|
||||
|
||||
// Return
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an array value using "dot notation".
|
||||
*
|
||||
* <code>
|
||||
* Arr::delete($array, 'foo.bar');
|
||||
* </code>
|
||||
*
|
||||
* @access public
|
||||
* @param array $array Array you want to modify
|
||||
* @param string $path Array path
|
||||
* @return boolean
|
||||
*/
|
||||
public static function delete(&$array, $path)
|
||||
{
|
||||
// Get segments from path
|
||||
$segments = explode('.', $path);
|
||||
|
||||
// Loop through segments
|
||||
while (count($segments) > 1) {
|
||||
|
||||
$segment = array_shift($segments);
|
||||
|
||||
if ( ! isset($array[$segment]) || !is_array($array[$segment])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$array =& $array[$segment];
|
||||
}
|
||||
|
||||
unset($array[array_shift($segments)]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given dot-notated key exists in the array.
|
||||
*
|
||||
* <code>
|
||||
* if (Arr::keyExists($array, 'foo.bar')) {
|
||||
* // Do something...
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @param array $array The search array
|
||||
* @param mixed $path Array path
|
||||
* @return boolean
|
||||
*/
|
||||
public static function keyExists($array, $path)
|
||||
{
|
||||
foreach (explode('.', $path) as $segment) {
|
||||
|
||||
if ( ! is_array($array) or ! array_key_exists($segment, $array)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$array = $array[$segment];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random value from an array.
|
||||
*
|
||||
* <code>
|
||||
* Arr::random(array('php', 'js', 'css', 'html'));
|
||||
* </code>
|
||||
*
|
||||
* @access public
|
||||
* @param array $array Array path
|
||||
* @return mixed
|
||||
*/
|
||||
public static function random($array)
|
||||
{
|
||||
return $array[array_rand($array)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns TRUE if the array is associative and FALSE if not.
|
||||
*
|
||||
* <code>
|
||||
* if (Arr::isAssoc($array)) {
|
||||
* // Do something...
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @param array $array Array to check
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isAssoc($array)
|
||||
{
|
||||
return (bool) count(array_filter(array_keys($array), 'is_string'));
|
||||
}
|
||||
|
||||
}
|
210
libraries/monstra/Cache.php
Normal file
210
libraries/monstra/Cache.php
Normal file
@@ -0,0 +1,210 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Monstra Library
|
||||
*
|
||||
* This source file is part of the Monstra Library. More information,
|
||||
* documentation and tutorials can be found at http://library.monstra.org
|
||||
*
|
||||
* @package Monstra
|
||||
*
|
||||
* @author Romanenko Sergey / Awilum
|
||||
* @copyright (c) 2012 - 2013 Romanenko Sergey / Awilum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
class Cache
|
||||
{
|
||||
/**
|
||||
* Cache directory
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $cache_dir = CACHE;
|
||||
|
||||
/**
|
||||
* Cache file ext
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $cache_file_ext = 'txt';
|
||||
|
||||
/**
|
||||
* Cache life time (in seconds)
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public static $cache_time = 31556926;
|
||||
|
||||
/**
|
||||
* Protected constructor since this is a static class.
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
// Nothing here
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the settings of Cache
|
||||
*
|
||||
* <code>
|
||||
* Cache::configure('cache_dir', 'path/to/cache/dir');
|
||||
* </code>
|
||||
*
|
||||
* @param mixed $setting Setting name
|
||||
* @param mixed $value Setting value
|
||||
*/
|
||||
public static function configure($setting, $value)
|
||||
{
|
||||
if (property_exists("cache", $setting)) Cache::$$setting = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data from cache
|
||||
*
|
||||
* <code>
|
||||
* $profile = Cache::get('profiles', 'profile');
|
||||
* </code>
|
||||
*
|
||||
* @param string $namespace Namespace
|
||||
* @param string $key Cache key
|
||||
* @return boolean
|
||||
*/
|
||||
public static function get($namespace, $key)
|
||||
{
|
||||
// Redefine vars
|
||||
$namespace = (string) $namespace;
|
||||
|
||||
// Get cache file id
|
||||
$cache_file_id = Cache::getCacheFileID($namespace, $key);
|
||||
|
||||
// Is cache file exists ?
|
||||
if (file_exists($cache_file_id)) {
|
||||
|
||||
// If cache file has not expired then fetch it
|
||||
if ((time() - filemtime($cache_file_id)) < Cache::$cache_time) {
|
||||
|
||||
$handle = fopen($cache_file_id, 'r');
|
||||
|
||||
$cache = '';
|
||||
|
||||
while ( ! feof($handle)) {
|
||||
$cache .= fgets($handle);
|
||||
}
|
||||
|
||||
fclose($handle);
|
||||
|
||||
return unserialize($cache);
|
||||
|
||||
} else {
|
||||
unlink($cache_file_id);
|
||||
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new cache file $key in namescapce $namespace with the given data $data
|
||||
*
|
||||
* <code>
|
||||
* $profile = array('login' => 'Awilum',
|
||||
* 'email' => 'awilum@msn.com');
|
||||
* Cache::put('profiles', 'profile', $profile);
|
||||
* </code>
|
||||
*
|
||||
* @param string $namespace Namespace
|
||||
* @param string $key Cache key
|
||||
* @param mixed $data The variable to store
|
||||
* @return boolean
|
||||
*/
|
||||
public static function put($namespace, $key, $data)
|
||||
{
|
||||
// Redefine vars
|
||||
$namespace = (string) $namespace;
|
||||
|
||||
// Is CACHE directory writable ?
|
||||
if (file_exists(CACHE) === false || is_readable(CACHE) === false || is_writable(CACHE) === false) {
|
||||
throw new RuntimeException(vsprintf("%s(): Cache directory ('%s') is not writable.", array(__METHOD__, CACHE)));
|
||||
}
|
||||
|
||||
// Create namespace
|
||||
if ( ! file_exists(Cache::getNamespaceID($namespace))) {
|
||||
mkdir(Cache::getNamespaceID($namespace), 0775, true);
|
||||
}
|
||||
|
||||
// Write cache to specific namespace
|
||||
return file_put_contents(Cache::getCacheFileID($namespace, $key), serialize($data), LOCK_EX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a cache in specific namespace
|
||||
*
|
||||
* <code>
|
||||
* Cache::delete('profiles', 'profile');
|
||||
* </code>
|
||||
*
|
||||
* @param string $namespace Namespace
|
||||
* @param string $key Cache key
|
||||
* @return boolean
|
||||
*/
|
||||
public static function delete($namespace, $key)
|
||||
{
|
||||
// Redefine vars
|
||||
$namespace = (string) $namespace;
|
||||
|
||||
if (file_exists(Cache::getCacheFileID($namespace, $key))) unlink(Cache::getCacheFileID($namespace, $key)); else return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean specific cache namespace.
|
||||
*
|
||||
* <code>
|
||||
* Cache::clean('profiles');
|
||||
* </code>
|
||||
*
|
||||
* @param string $namespace Namespace
|
||||
* @return null
|
||||
*/
|
||||
public static function clean($namespace)
|
||||
{
|
||||
// Redefine vars
|
||||
$namespace = (string) $namespace;
|
||||
|
||||
array_map("unlink", glob(Cache::$cache_dir . DS . md5($namespace) . DS . "*." . Cache::$cache_file_ext));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cache file ID
|
||||
*
|
||||
* @param string $namespace Namespace
|
||||
* @param string $key Cache key
|
||||
* @return string
|
||||
*/
|
||||
protected static function getCacheFileID($namespace, $key)
|
||||
{
|
||||
// Redefine vars
|
||||
$namespace = (string) $namespace;
|
||||
|
||||
return Cache::$cache_dir . DS . md5($namespace) . DS . md5($key) . '.' . Cache::$cache_file_ext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get namespace ID
|
||||
*
|
||||
* @param string $namespace Namespace
|
||||
* @return string
|
||||
*/
|
||||
protected static function getNamespaceID($namespace)
|
||||
{
|
||||
// Redefine vars
|
||||
$namespace = (string) $namespace;
|
||||
|
||||
return Cache::$cache_dir . DS . md5($namespace);
|
||||
}
|
||||
|
||||
}
|
106
libraries/monstra/Cookie.php
Normal file
106
libraries/monstra/Cookie.php
Normal file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Monstra Library
|
||||
*
|
||||
* This source file is part of the Monstra Library. More information,
|
||||
* documentation and tutorials can be found at http://library.monstra.org
|
||||
*
|
||||
* @package Monstra
|
||||
*
|
||||
* @author Romanenko Sergey / Awilum
|
||||
* @copyright (c) 2012 - 2013 Romanenko Sergey / Awilum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
class Cookie
|
||||
{
|
||||
/**
|
||||
* Protected constructor since this is a static class.
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
// Nothing here
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a cookie
|
||||
*
|
||||
* <code>
|
||||
* Cookie::set('limit', 10);
|
||||
* </code>
|
||||
*
|
||||
* @param string $key A name for the cookie.
|
||||
* @param mixed $value The value to be stored. Keep in mind that they will be serialized.
|
||||
* @param integer $expire The number of seconds that this cookie will be available.
|
||||
* @param string $path The path on the server in which the cookie will be availabe. Use / for the entire domain, /foo if you just want it to be available in /foo.
|
||||
* @param string $domain The domain that the cookie is available on. Use .example.com to make it available on all subdomains of example.com.
|
||||
* @param boolean $secure Should the cookie be transmitted over a HTTPS-connection? If true, make sure you use a secure connection, otherwise the cookie won't be set.
|
||||
* @param boolean $httpOnly Should the cookie only be available through HTTP-protocol? If true, the cookie can't be accessed by Javascript, ...
|
||||
* @return boolean
|
||||
*/
|
||||
public static function set($key, $value, $expire = 86400, $domain = '', $path = '/', $secure = false, $httpOnly = false)
|
||||
{
|
||||
// Redefine vars
|
||||
$key = (string) $key;
|
||||
$value = serialize($value);
|
||||
$expire = time() + (int) $expire;
|
||||
$path = (string) $path;
|
||||
$domain = (string) $domain;
|
||||
$secure = (bool) $secure;
|
||||
$httpOnly = (bool) $httpOnly;
|
||||
|
||||
// Set cookie
|
||||
return setcookie($key, $value, $expire, $path, $domain, $secure, $httpOnly);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a cookie
|
||||
*
|
||||
* <code>
|
||||
* $limit = Cookie::get('limit');
|
||||
* </code>
|
||||
*
|
||||
* @param string $key The name of the cookie that should be retrieved.
|
||||
* @return mixed
|
||||
*/
|
||||
public static function get($key)
|
||||
{
|
||||
// Redefine key
|
||||
$key = (string) $key;
|
||||
|
||||
// Cookie doesn't exist
|
||||
if( ! isset($_COOKIE[$key])) return false;
|
||||
|
||||
// Fetch base value
|
||||
$value = (get_magic_quotes_gpc()) ? stripslashes($_COOKIE[$key]) : $_COOKIE[$key];
|
||||
|
||||
// Unserialize
|
||||
$actual_value = @unserialize($value);
|
||||
|
||||
// If unserialize failed
|
||||
if($actual_value === false && serialize(false) != $value) return false;
|
||||
|
||||
// Everything is fine
|
||||
return $actual_value;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete a cookie
|
||||
*
|
||||
* <code>
|
||||
* Cookie::delete('limit');
|
||||
* </code>
|
||||
*
|
||||
* @param string $name The name of the cookie that should be deleted.
|
||||
*/
|
||||
public static function delete($key)
|
||||
{
|
||||
unset($_COOKIE[$key]);
|
||||
}
|
||||
|
||||
}
|
142
libraries/monstra/Curl.php
Normal file
142
libraries/monstra/Curl.php
Normal file
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Monstra Library
|
||||
*
|
||||
* This source file is part of the Monstra Library. More information,
|
||||
* documentation and tutorials can be found at http://library.monstra.org
|
||||
*
|
||||
* @package Monstra
|
||||
*
|
||||
* @author Romanenko Sergey / Awilum
|
||||
* @copyright (c) 2012 - 2013 Romanenko Sergey / Awilum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
class Curl
|
||||
{
|
||||
/**
|
||||
* Default curl options.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $default_options = array(
|
||||
CURLOPT_USERAGENT => 'Mozilla/5.0 (compatible; Monstra CMS; +http://monstra.org)',
|
||||
CURLOPT_RETURNTRANSFER => true
|
||||
);
|
||||
|
||||
/**
|
||||
* Information about the last transfer.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $info;
|
||||
|
||||
/**
|
||||
* Performs a curl GET request.
|
||||
*
|
||||
* <code>
|
||||
* $res = Curl::get('http://site.com/');
|
||||
* </code>
|
||||
*
|
||||
* @param string $url The URL to fetch
|
||||
* @param array $options An array specifying which options to set and their values
|
||||
* @return string
|
||||
*/
|
||||
public static function get($url, array $options = null)
|
||||
{
|
||||
// Redefine vars
|
||||
$url = (string) $url;
|
||||
|
||||
// Check if curl is available
|
||||
if ( ! function_exists('curl_init')) throw new RuntimeException(vsprintf("%s(): This method requires cURL (http://php.net/curl), it seems like the extension isn't installed.", array(__METHOD__)));
|
||||
|
||||
// Initialize a cURL session
|
||||
$handle = curl_init($url);
|
||||
|
||||
// Merge options
|
||||
$options = (array) $options + Curl::$default_options;
|
||||
|
||||
// Set multiple options for a cURL transfer
|
||||
curl_setopt_array($handle, $options);
|
||||
|
||||
// Perform a cURL session
|
||||
$response = curl_exec($handle);
|
||||
|
||||
// Set information regarding a specific transfer
|
||||
Curl::$info = curl_getinfo($handle);
|
||||
|
||||
// Close a cURL session
|
||||
curl_close($handle);
|
||||
|
||||
// Return response
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a curl POST request.
|
||||
*
|
||||
* <code>
|
||||
* $res = Curl::post('http://site.com/login');
|
||||
* </code>
|
||||
*
|
||||
* @param string $url The URL to fetch
|
||||
* @param array $data An array with the field name as key and field data as value
|
||||
* @param boolean $multipart True to send data as multipart/form-data and false to send as application/x-www-form-urlencoded
|
||||
* @param array $options An array specifying which options to set and their values
|
||||
* @return string
|
||||
*/
|
||||
public static function post($url, array $data = null, $multipart = false, array $options = null)
|
||||
{
|
||||
// Redefine vars
|
||||
$url = (string) $url;
|
||||
|
||||
// Check if curl is available
|
||||
if ( ! function_exists('curl_init')) throw new RuntimeException(vsprintf("%s(): This method requires cURL (http://php.net/curl), it seems like the extension isn't installed.", array(__METHOD__)));
|
||||
|
||||
// Initialize a cURL session
|
||||
$handle = curl_init($url);
|
||||
|
||||
// Merge options
|
||||
$options = (array) $options + Curl::$default_options;
|
||||
|
||||
// Add options
|
||||
$options[CURLOPT_POST] = true;
|
||||
$options[CURLOPT_POSTFIELDS] = ($multipart === true) ? (array) $data : http_build_query((array) $data);
|
||||
|
||||
// Set multiple options for a cURL transfer
|
||||
curl_setopt_array($handle, $options);
|
||||
|
||||
// Perform a cURL session
|
||||
$response = curl_exec($handle);
|
||||
|
||||
// Set information regarding a specific transfer
|
||||
Curl::$info = curl_getinfo($handle);
|
||||
|
||||
// Close a cURL session
|
||||
curl_close($handle);
|
||||
|
||||
// Return response
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets information about the last transfer.
|
||||
*
|
||||
* <code>
|
||||
* $res = Curl::getInfo();
|
||||
* </code>
|
||||
*
|
||||
* @param string $value Array key of the array returned by curl_getinfo()
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getInfo($value = null)
|
||||
{
|
||||
if (empty(Curl::$info)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ($value === null) ? Curl::$info : Curl::$info[$value];
|
||||
}
|
||||
|
||||
}
|
420
libraries/monstra/Date.php
Normal file
420
libraries/monstra/Date.php
Normal file
@@ -0,0 +1,420 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Monstra Library
|
||||
*
|
||||
* This source file is part of the Monstra Library. More information,
|
||||
* documentation and tutorials can be found at http://library.monstra.org
|
||||
*
|
||||
* @package Monstra
|
||||
*
|
||||
* @author Romanenko Sergey / Awilum
|
||||
* @copyright (c) 2012 - 2013 Romanenko Sergey / Awilum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
class Date
|
||||
{
|
||||
/**
|
||||
* Protected constructor since this is a static class.
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
// Nothing here
|
||||
}
|
||||
|
||||
/**
|
||||
* Get format date
|
||||
*
|
||||
* <code>
|
||||
* echo Date::format($date, 'j.n.Y');
|
||||
* </code>
|
||||
*
|
||||
* @param integer $date Unix timestamp
|
||||
* @param string $format Date format
|
||||
* @return integer
|
||||
*/
|
||||
public static function format($date, $format = '')
|
||||
{
|
||||
// Redefine vars
|
||||
$format = (string) $format;
|
||||
$date = (int) $date;
|
||||
|
||||
if ($format != '') { return date($format, $date); } else { return date(MONSTRA_DATE_FORMAT, $date); }
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of seconds in a minute, incrementing by a step.
|
||||
*
|
||||
* <code>
|
||||
* $seconds = Date::seconds();
|
||||
* </code>
|
||||
*
|
||||
* @param integer $step Amount to increment each step by, 1 to 30
|
||||
* @param integer $start Start value
|
||||
* @param integer $end End value
|
||||
* @return array
|
||||
*/
|
||||
public static function seconds($step = 1, $start = 0, $end = 60)
|
||||
{
|
||||
// Redefine vars
|
||||
$step = (int) $step;
|
||||
$start = (int) $start;
|
||||
$end = (int) $end;
|
||||
|
||||
return Date::_range($step, $start, $end);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of minutes in a hour, incrementing by a step.
|
||||
*
|
||||
* <code>
|
||||
* $minutes = Date::minutes();
|
||||
* </code>
|
||||
*
|
||||
* @param integer $step Amount to increment each step by, 1 to 30
|
||||
* @param integer $start Start value
|
||||
* @param integer $end End value
|
||||
* @return array
|
||||
*/
|
||||
public static function minutes($step = 5, $start = 0, $end = 60)
|
||||
{
|
||||
// Redefine vars
|
||||
$step = (int) $step;
|
||||
$start = (int) $start;
|
||||
$end = (int) $end;
|
||||
|
||||
return Date::_range($step, $start, $end);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of hours, incrementing by a step.
|
||||
*
|
||||
* <code>
|
||||
* $hours = Date::hours();
|
||||
* </code>
|
||||
*
|
||||
* @param integer $step Amount to increment each step by, 1 to 30
|
||||
* @param integer $long Start value
|
||||
* @param integer $start End value
|
||||
* @return array
|
||||
*/
|
||||
public static function hours($step = 1, $long = false, $start = null)
|
||||
{
|
||||
// Redefine vars
|
||||
$step = (int) $step;
|
||||
$long = (bool) $long;
|
||||
|
||||
if ($start === null) $start = ($long === FALSE) ? 1 : 0;
|
||||
$end = ($long === true) ? 23 : 12;
|
||||
|
||||
return Date::_range($step, $start, $end, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of months.
|
||||
*
|
||||
* <code>
|
||||
* $months = Date::months();
|
||||
* </code>
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function months()
|
||||
{
|
||||
return Date::_range(1, 1, 12, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of days.
|
||||
*
|
||||
* <code>
|
||||
* $months = Date::days();
|
||||
* </code>
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function days()
|
||||
{
|
||||
return Date::_range(1, 1, Date::daysInMonth((int) date('M')), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of days in the requested month
|
||||
*
|
||||
* <code>
|
||||
* $days = Date::daysInMonth(1);
|
||||
* </code>
|
||||
*
|
||||
* @param integer $month Month as a number (1-12)
|
||||
* @param integer $year The year
|
||||
* @return integer
|
||||
*/
|
||||
public static function daysInMonth($month, $year = null)
|
||||
{
|
||||
// Redefine vars
|
||||
$month = (int) $month;
|
||||
$year = ! empty($year) ? (int) $year : (int) date('Y');
|
||||
|
||||
if ($month < 1 or $month > 12) {
|
||||
return false;
|
||||
} elseif ($month == 2) {
|
||||
if ($year % 400 == 0 or ($year % 4 == 0 and $year % 100 != 0)) {
|
||||
return 29;
|
||||
}
|
||||
}
|
||||
|
||||
$days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
|
||||
|
||||
return $days_in_month[$month-1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of years.
|
||||
*
|
||||
* <code>
|
||||
* $years = Date::years();
|
||||
* </code>
|
||||
*
|
||||
* @param integer $long Start value
|
||||
* @param integer $start End value
|
||||
* @return array
|
||||
*/
|
||||
public static function years($start = 1980, $end = 2024)
|
||||
{
|
||||
// Redefine vars
|
||||
$start = (int) $start;
|
||||
$end = (int) $end;
|
||||
|
||||
return Date::_range(1, $start, $end, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current season name
|
||||
*
|
||||
* <code>
|
||||
* echo Date::season();
|
||||
* </code>
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function season()
|
||||
{
|
||||
$seasons = array("Winter", "Spring", "Summer", "Autumn");
|
||||
|
||||
return $seasons[(int) ((date("n") %12)/3)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get today date
|
||||
*
|
||||
* <code>
|
||||
* echo Date::today();
|
||||
* </code>
|
||||
*
|
||||
* @param string $format Date format
|
||||
* @return string
|
||||
*/
|
||||
public static function today($format = '')
|
||||
{
|
||||
// Redefine vars
|
||||
$format = (string) $format;
|
||||
|
||||
if ($format != '') { return date($format); } else { return date(MONSTRA_DATE_FORMAT); }
|
||||
}
|
||||
|
||||
/**
|
||||
* Get yesterday date
|
||||
*
|
||||
* <code>
|
||||
* echo Date::yesterday();
|
||||
* </code>
|
||||
*
|
||||
* @param string $format Date format
|
||||
* @return string
|
||||
*/
|
||||
public static function yesterday($format = '')
|
||||
{
|
||||
// Redefine vars
|
||||
$format = (string) $format;
|
||||
|
||||
if ($format != '') { return date($format, strtotime("-1 day")); } else { return date(MONSTRA_DATE_FORMAT, strtotime("-1 day")); }
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tomorrow date
|
||||
*
|
||||
* <code>
|
||||
* echo Date::tomorrow();
|
||||
* </code>
|
||||
*
|
||||
* @param string $format Date format
|
||||
* @return string
|
||||
*/
|
||||
public static function tomorrow($format = '')
|
||||
{
|
||||
// Redefine vars
|
||||
$format = (string) $format;
|
||||
|
||||
if ($format != '') { return date($format, strtotime("+1 day")); } else { return date(MONSTRA_DATE_FORMAT, strtotime("-1 day")); }
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a UNIX timestamp to DOS format.
|
||||
*
|
||||
* <code>
|
||||
* $dos = Date::unix2dos($unix);
|
||||
* </code>
|
||||
*
|
||||
* @param integer $timestamp UNIX timestamp
|
||||
* @return integer
|
||||
*/
|
||||
public static function unix2dos($timestamp = 0)
|
||||
{
|
||||
$timestamp = ($_timestamp == 0) ? getdate() : getdate($_timestamp);
|
||||
|
||||
if ($timestamp['year'] < 1980) return (1 << 21 | 1 << 16);
|
||||
|
||||
$timestamp['year'] -= 1980;
|
||||
|
||||
return ($timestamp['year'] << 25 | $timestamp['mon'] << 21 |
|
||||
$timestamp['mday'] << 16 | $timestamp['hours'] << 11 |
|
||||
$timestamp['minutes'] << 5 | $timestamp['seconds'] >> 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a DOS timestamp to UNIX format.
|
||||
*
|
||||
* <code>
|
||||
* $unix = Date::dos2unix($dos);
|
||||
* </code>
|
||||
*
|
||||
* @param integer $timestamp DOS timestamp
|
||||
* @return integer
|
||||
*/
|
||||
public static function dos2unix($timestamp)
|
||||
{
|
||||
$sec = 2 * ($timestamp & 0x1f);
|
||||
$min = ($timestamp >> 5) & 0x3f;
|
||||
$hrs = ($timestamp >> 11) & 0x1f;
|
||||
$day = ($timestamp >> 16) & 0x1f;
|
||||
$mon = (($timestamp >> 21) & 0x0f);
|
||||
$year = (($timestamp >> 25) & 0x7f) + 1980;
|
||||
|
||||
return mktime($hrs, $min, $sec, $mon, $day, $year);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Time zones
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function timezones()
|
||||
{
|
||||
return array('Kwajalein'=>'(GMT-12:00) International Date Line West',
|
||||
'Pacific/Samoa'=>'(GMT-11:00) Midway Island, Samoa',
|
||||
'Pacific/Honolulu'=>'(GMT-10:00) Hawaii',
|
||||
'America/Anchorage'=>'(GMT-09:00) Alaska',
|
||||
'America/Los_Angeles'=>'(GMT-08:00) Pacific Time (US & Canada)',
|
||||
'America/Tijuana'=>'(GMT-08:00) Tijuana, Baja California',
|
||||
'America/Denver'=>'(GMT-07:00) Mountain Time (US & Canada)',
|
||||
'America/Chihuahua'=>'(GMT-07:00) Chihuahua, La Paz, Mazatlan',
|
||||
'America/Phoenix'=>'(GMT-07:00) Arizona',
|
||||
'America/Regina'=>'(GMT-06:00) Saskatchewan',
|
||||
'America/Tegucigalpa'=>'(GMT-06:00) Central America',
|
||||
'America/Chicago'=>'(GMT-06:00) Central Time (US & Canada)',
|
||||
'America/Mexico_City'=>'(GMT-06:00) Guadalajara, Mexico City, Monterrey',
|
||||
'America/New_York'=>'(GMT-05:00) Eastern Time (US & Canada)',
|
||||
'America/Bogota'=>'(GMT-05:00) Bogota, Lima, Quito, Rio Branco',
|
||||
'America/Indiana/Indianapolis'=>'(GMT-05:00) Indiana (East)',
|
||||
'America/Caracas'=>'(GMT-04:30) Caracas',
|
||||
'America/Halifax'=>'(GMT-04:00) Atlantic Time (Canada)',
|
||||
'America/Manaus'=>'(GMT-04:00) Manaus',
|
||||
'America/Santiago'=>'(GMT-04:00) Santiago',
|
||||
'America/La_Paz'=>'(GMT-04:00) La Paz',
|
||||
'America/St_Johns'=>'(GMT-03:30) Newfoundland',
|
||||
'America/Argentina/Buenos_Aires'=>'(GMT-03:00) Buenos Aires',
|
||||
'America/Sao_Paulo'=>'(GMT-03:00) Brasilia',
|
||||
'America/Godthab'=>'(GMT-03:00) Greenland',
|
||||
'America/Montevideo'=>'(GMT-03:00) Montevideo',
|
||||
'America/Argentina/Buenos_Aires'=>'(GMT-03:00) Georgetown',
|
||||
'Atlantic/South_Georgia'=>'(GMT-02:00) Mid-Atlantic',
|
||||
'Atlantic/Azores'=>'(GMT-01:00) Azores',
|
||||
'Atlantic/Cape_Verde'=>'(GMT-01:00) Cape Verde Is.',
|
||||
'Europe/London'=>'(GMT) Greenwich Mean Time : Dublin, Edinburgh, Lisbon, London',
|
||||
'Atlantic/Reykjavik'=>'(GMT) Monrovia, Reykjavik',
|
||||
'Africa/Casablanca'=>'(GMT) Casablanca',
|
||||
'Europe/Belgrade'=>'(GMT+01:00) Belgrade, Bratislava, Budapest, Ljubljana, Prague',
|
||||
'Europe/Sarajevo'=>'(GMT+01:00) Sarajevo, Skopje, Warsaw, Zagreb',
|
||||
'Europe/Brussels'=>'(GMT+01:00) Brussels, Copenhagen, Madrid, Paris',
|
||||
'Africa/Algiers'=>'(GMT+01:00) West Central Africa',
|
||||
'Europe/Amsterdam'=>'(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna',
|
||||
'Africa/Cairo'=>'(GMT+02:00) Cairo',
|
||||
'Europe/Helsinki'=>'(GMT+02:00) Helsinki, Kyiv, Riga, Sofia, Tallinn, Vilnius',
|
||||
'Europe/Athens'=>'(GMT+02:00) Athens, Bucharest, Istanbul',
|
||||
'Asia/Jerusalem'=>'(GMT+02:00) Jerusalem',
|
||||
'Asia/Amman'=>'(GMT+02:00) Amman',
|
||||
'Asia/Beirut'=>'(GMT+02:00) Beirut',
|
||||
'Africa/Windhoek'=>'(GMT+02:00) Windhoek',
|
||||
'Africa/Harare'=>'(GMT+02:00) Harare, Pretoria',
|
||||
'Asia/Kuwait'=>'(GMT+03:00) Kuwait, Riyadh',
|
||||
'Asia/Baghdad'=>'(GMT+03:00) Baghdad',
|
||||
'Europe/Minsk'=>'(GMT+03:00) Minsk',
|
||||
'Africa/Nairobi'=>'(GMT+03:00) Nairobi',
|
||||
'Asia/Tbilisi'=>'(GMT+03:00) Tbilisi',
|
||||
'Asia/Tehran'=>'(GMT+03:30) Tehran',
|
||||
'Asia/Muscat'=>'(GMT+04:00) Abu Dhabi, Muscat',
|
||||
'Asia/Baku'=>'(GMT+04:00) Baku',
|
||||
'Europe/Moscow'=>'(GMT+04:00) Moscow, St. Petersburg, Volgograd',
|
||||
'Asia/Yerevan'=>'(GMT+04:00) Yerevan',
|
||||
'Asia/Karachi'=>'(GMT+05:00) Islamabad, Karachi',
|
||||
'Asia/Tashkent'=>'(GMT+05:00) Tashkent',
|
||||
'Asia/Kolkata'=>'(GMT+05:30) Chennai, Kolkata, Mumbai, New Delhi',
|
||||
'Asia/Colombo'=>'(GMT+05:30) Sri Jayawardenepura',
|
||||
'Asia/Katmandu'=>'(GMT+05:45) Kathmandu',
|
||||
'Asia/Dhaka'=>'(GMT+06:00) Astana, Dhaka',
|
||||
'Asia/Yekaterinburg'=>'(GMT+06:00) Ekaterinburg',
|
||||
'Asia/Rangoon'=>'(GMT+06:30) Yangon (Rangoon)',
|
||||
'Asia/Novosibirsk'=>'(GMT+07:00) Almaty, Novosibirsk',
|
||||
'Asia/Bangkok'=>'(GMT+07:00) Bangkok, Hanoi, Jakarta',
|
||||
'Asia/Beijing'=>'(GMT+08:00) Beijing, Chongqing, Hong Kong, Urumqi',
|
||||
'Asia/Ulaanbaatar'=>'(GMT+08:00) Irkutsk, Ulaan Bataar',
|
||||
'Asia/Krasnoyarsk'=>'(GMT+08:00) Krasnoyarsk',
|
||||
'Asia/Kuala_Lumpur'=>'(GMT+08:00) Kuala Lumpur, Singapore',
|
||||
'Asia/Taipei'=>'(GMT+08:00) Taipei',
|
||||
'Australia/Perth'=>'(GMT+08:00) Perth',
|
||||
'Asia/Seoul'=>'(GMT+09:00) Seoul',
|
||||
'Asia/Tokyo'=>'(GMT+09:00) Osaka, Sapporo, Tokyo',
|
||||
'Australia/Darwin'=>'(GMT+09:30) Darwin',
|
||||
'Australia/Adelaide'=>'(GMT+09:30) Adelaide',
|
||||
'Australia/Sydney'=>'(GMT+10:00) Canberra, Melbourne, Sydney',
|
||||
'Australia/Brisbane'=>'(GMT+10:00) Brisbane',
|
||||
'Australia/Hobart'=>'(GMT+10:00) Hobart',
|
||||
'Asia/Yakutsk'=>'(GMT+10:00) Yakutsk',
|
||||
'Pacific/Guam'=>'(GMT+10:00) Guam, Port Moresby',
|
||||
'Asia/Vladivostok'=>'(GMT+11:00) Vladivostok',
|
||||
'Pacific/Fiji'=>'(GMT+12:00) Fiji, Kamchatka, Marshall Is.',
|
||||
'Asia/Magadan'=>'(GMT+12:00) Magadan, Solomon Is., New Caledonia',
|
||||
'Pacific/Auckland'=>'(GMT+12:00) Auckland, Wellington',
|
||||
'Pacific/Tongatapu'=>'(GMT+13:00) Nukualofa'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* _range()
|
||||
*/
|
||||
protected static function _range($step, $start, $end, $flag = false)
|
||||
{
|
||||
$result = array();
|
||||
if ($flag) {
|
||||
for ($i = $start; $i <= $end; $i += $step) $result[$i] = (string) $i;
|
||||
} else {
|
||||
for ($i = $start; $i < $end; $i += $step) $result[$i] = sprintf('%02d', $i);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
116
libraries/monstra/Debug.php
Normal file
116
libraries/monstra/Debug.php
Normal file
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Monstra Library
|
||||
*
|
||||
* This source file is part of the Monstra Library. More information,
|
||||
* documentation and tutorials can be found at http://library.monstra.org
|
||||
*
|
||||
* @package Monstra
|
||||
*
|
||||
* @author Romanenko Sergey / Awilum
|
||||
* @copyright (c) 2012 - 2013 Romanenko Sergey / Awilum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
class Debug
|
||||
{
|
||||
/**
|
||||
* Time
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $time = array();
|
||||
|
||||
/**
|
||||
* Memory
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $memory = array();
|
||||
|
||||
/**
|
||||
* Protected constructor since this is a static class.
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
// Nothing here
|
||||
}
|
||||
|
||||
/**
|
||||
* Save current time for current point
|
||||
*
|
||||
* <code>
|
||||
* Debug::elapsedTimeSetPoint('point_name');
|
||||
* </code>
|
||||
*
|
||||
* @param string $point_name Point name
|
||||
*/
|
||||
public static function elapsedTimeSetPoint($point_name)
|
||||
{
|
||||
Debug::$time[$point_name] = microtime(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get elapsed time for current point
|
||||
*
|
||||
* <code>
|
||||
* echo Debug::elapsedTime('point_name');
|
||||
* </code>
|
||||
*
|
||||
* @param string $point_name Point name
|
||||
* @return string
|
||||
*/
|
||||
public static function elapsedTime($point_name)
|
||||
{
|
||||
if (isset(Debug::$time[$point_name])) return sprintf("%01.4f", microtime(true) - Debug::$time[$point_name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save current memory for current point
|
||||
*
|
||||
* <code>
|
||||
* Debug::memoryUsageSetPoint('point_name');
|
||||
* </code>
|
||||
*
|
||||
* @param string $point_name Point name
|
||||
*/
|
||||
public static function memoryUsageSetPoint($point_name)
|
||||
{
|
||||
Debug::$memory[$point_name] = memory_get_usage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get memory usage for current point
|
||||
*
|
||||
* <code>
|
||||
* echo Debug::memoryUsage('point_name');
|
||||
* </code>
|
||||
*
|
||||
* @param string $point_name Point name
|
||||
* @return string
|
||||
*/
|
||||
public static function memoryUsage($point_name)
|
||||
{
|
||||
if (isset(Debug::$memory[$point_name])) return Number::byteFormat(memory_get_usage() - Debug::$memory[$point_name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the variable $data and exit if exit = true
|
||||
*
|
||||
* <code>
|
||||
* Debug::dump($data);
|
||||
* </code>
|
||||
*
|
||||
* @param mixed $data Data
|
||||
* @param boolean $exit Exit
|
||||
*/
|
||||
public static function dump($data, $exit = false)
|
||||
{
|
||||
echo "<pre>dump \n---------------------- \n\n" . print_r($data, true) . "\n----------------------</pre>";
|
||||
if ($exit) exit;
|
||||
}
|
||||
|
||||
}
|
207
libraries/monstra/Dir.php
Normal file
207
libraries/monstra/Dir.php
Normal file
@@ -0,0 +1,207 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Monstra Library
|
||||
*
|
||||
* This source file is part of the Monstra Library. More information,
|
||||
* documentation and tutorials can be found at http://library.monstra.org
|
||||
*
|
||||
* @package Monstra
|
||||
*
|
||||
* @author Romanenko Sergey / Awilum
|
||||
* @copyright (c) 2012 - 2013 Romanenko Sergey / Awilum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Dir class
|
||||
*/
|
||||
class Dir
|
||||
{
|
||||
/**
|
||||
* Protected constructor since this is a static class.
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
// Nothing here
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a directory
|
||||
*
|
||||
* <code>
|
||||
* Dir::create('folder1');
|
||||
* </code>
|
||||
*
|
||||
* @param string $dir Name of directory to create
|
||||
* @param integer $chmod Chmod
|
||||
* @return boolean
|
||||
*/
|
||||
public static function create($dir, $chmod = 0775)
|
||||
{
|
||||
// Redefine vars
|
||||
$dir = (string) $dir;
|
||||
|
||||
// Create new dir if $dir !exists
|
||||
return ( ! Dir::exists($dir)) ? @mkdir($dir, $chmod, true) : true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this directory exists.
|
||||
*
|
||||
* <code>
|
||||
* if (Dir::exists('folder1')) {
|
||||
* // Do something...
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @param string $dir Full path of the directory to check.
|
||||
* @return boolean
|
||||
*/
|
||||
public static function exists($dir)
|
||||
{
|
||||
// Redefine vars
|
||||
$dir = (string) $dir;
|
||||
|
||||
// Directory exists
|
||||
if (file_exists($dir) && is_dir($dir)) return true;
|
||||
|
||||
// Doesn't exist
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check dir permission
|
||||
*
|
||||
* <code>
|
||||
* echo Dir::checkPerm('folder1');
|
||||
* </code>
|
||||
*
|
||||
* @param string $dir Directory to check
|
||||
* @return string
|
||||
*/
|
||||
public static function checkPerm($dir)
|
||||
{
|
||||
// Redefine vars
|
||||
$dir = (string) $dir;
|
||||
|
||||
// Clear stat cache
|
||||
clearstatcache();
|
||||
|
||||
// Return perm
|
||||
return substr(sprintf('%o', fileperms($dir)), -4);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete directory
|
||||
*
|
||||
* <code>
|
||||
* Dir::delete('folder1');
|
||||
* </code>
|
||||
*
|
||||
* @param string $dir Name of directory to delete
|
||||
*/
|
||||
public static function delete($dir)
|
||||
{
|
||||
// Redefine vars
|
||||
$dir = (string) $dir;
|
||||
|
||||
// Delete dir
|
||||
if (is_dir($dir)){$ob=scandir($dir);foreach ($ob as $o) {if ($o!='.'&&$o!='..') {if(filetype($dir.'/'.$o)=='dir')Dir::delete($dir.'/'.$o); else unlink($dir.'/'.$o);}}}
|
||||
reset($ob); rmdir($dir);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get list of directories
|
||||
*
|
||||
* <code>
|
||||
* $dirs = Dir::scan('folders');
|
||||
* </code>
|
||||
*
|
||||
* @param string $dir Directory
|
||||
*/
|
||||
public static function scan($dir)
|
||||
{
|
||||
// Redefine vars
|
||||
$dir = (string) $dir;
|
||||
|
||||
// Scan dir
|
||||
if (is_dir($dir)&&$dh=opendir($dir)){$f=array();while ($fn=readdir($dh)) {if($fn!='.'&&$fn!='..'&&is_dir($dir.DS.$fn))$f[]=$fn;}return$f;}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if a directory is writable.
|
||||
*
|
||||
* <code>
|
||||
* if (Dir::writable('folder1')) {
|
||||
* // Do something...
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @param string $path The path to check.
|
||||
* @return booleans
|
||||
*/
|
||||
public static function writable($path)
|
||||
{
|
||||
// Redefine vars
|
||||
$path = (string) $path;
|
||||
|
||||
// Create temporary file
|
||||
$file = tempnam($path, 'writable');
|
||||
|
||||
// File has been created
|
||||
if ($file !== false) {
|
||||
|
||||
// Remove temporary file
|
||||
File::delete($file);
|
||||
|
||||
// Writable
|
||||
return true;
|
||||
}
|
||||
|
||||
// Else not writable
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get directory size.
|
||||
*
|
||||
* <code>
|
||||
* echo Dir::size('folder1');
|
||||
* </code>
|
||||
*
|
||||
* @param string $path The path to directory.
|
||||
* @return integer
|
||||
*/
|
||||
public static function size($path)
|
||||
{
|
||||
// Redefine vars
|
||||
$path = (string) $path;
|
||||
|
||||
$total_size = 0;
|
||||
$files = scandir($path);
|
||||
$clean_path = rtrim($path, '/') . '/';
|
||||
|
||||
foreach ($files as $t) {
|
||||
if ($t <> "." && $t <> "..") {
|
||||
$current_file = $clean_path . $t;
|
||||
if (is_dir($current_file)) {
|
||||
$total_size += Dir::size($current_file);
|
||||
} else {
|
||||
$total_size += filesize($current_file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return total size
|
||||
return $total_size;
|
||||
}
|
||||
|
||||
}
|
575
libraries/monstra/File.php
Normal file
575
libraries/monstra/File.php
Normal file
@@ -0,0 +1,575 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Monstra Library
|
||||
*
|
||||
* This source file is part of the Monstra Library. More information,
|
||||
* documentation and tutorials can be found at http://library.monstra.org
|
||||
*
|
||||
* @package Monstra
|
||||
*
|
||||
* @author Romanenko Sergey / Awilum
|
||||
* @copyright (c) 2012 - 2013 Romanenko Sergey / Awilum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
class File
|
||||
{
|
||||
/**
|
||||
* Mime type list
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $mime_types = array(
|
||||
'aac' => 'audio/aac',
|
||||
'atom' => 'application/atom+xml',
|
||||
'avi' => 'video/avi',
|
||||
'bmp' => 'image/x-ms-bmp',
|
||||
'c' => 'text/x-c',
|
||||
'class' => 'application/octet-stream',
|
||||
'css' => 'text/css',
|
||||
'csv' => 'text/csv',
|
||||
'deb' => 'application/x-deb',
|
||||
'dll' => 'application/x-msdownload',
|
||||
'dmg' => 'application/x-apple-diskimage',
|
||||
'doc' => 'application/msword',
|
||||
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
'exe' => 'application/octet-stream',
|
||||
'flv' => 'video/x-flv',
|
||||
'gif' => 'image/gif',
|
||||
'gz' => 'application/x-gzip',
|
||||
'h' => 'text/x-c',
|
||||
'htm' => 'text/html',
|
||||
'html' => 'text/html',
|
||||
'ini' => 'text/plain',
|
||||
'jar' => 'application/java-archive',
|
||||
'java' => 'text/x-java',
|
||||
'jpeg' => 'image/jpeg',
|
||||
'jpg' => 'image/jpeg',
|
||||
'js' => 'text/javascript',
|
||||
'json' => 'application/json',
|
||||
'mid' => 'audio/midi',
|
||||
'midi' => 'audio/midi',
|
||||
'mka' => 'audio/x-matroska',
|
||||
'mkv' => 'video/x-matroska',
|
||||
'mp3' => 'audio/mpeg',
|
||||
'mp4' => 'application/mp4',
|
||||
'mpeg' => 'video/mpeg',
|
||||
'mpg' => 'video/mpeg',
|
||||
'odt' => 'application/vnd.oasis.opendocument.text',
|
||||
'ogg' => 'audio/ogg',
|
||||
'pdf' => 'application/pdf',
|
||||
'php' => 'text/x-php',
|
||||
'png' => 'image/png',
|
||||
'psd' => 'image/vnd.adobe.photoshop',
|
||||
'py' => 'application/x-python',
|
||||
'ra' => 'audio/vnd.rn-realaudio',
|
||||
'ram' => 'audio/vnd.rn-realaudio',
|
||||
'rar' => 'application/x-rar-compressed',
|
||||
'rss' => 'application/rss+xml',
|
||||
'safariextz' => 'application/x-safari-extension',
|
||||
'sh' => 'text/x-shellscript',
|
||||
'shtml' => 'text/html',
|
||||
'swf' => 'application/x-shockwave-flash',
|
||||
'tar' => 'application/x-tar',
|
||||
'tif' => 'image/tiff',
|
||||
'tiff' => 'image/tiff',
|
||||
'torrent' => 'application/x-bittorrent',
|
||||
'txt' => 'text/plain',
|
||||
'wav' => 'audio/wav',
|
||||
'webp' => 'image/webp',
|
||||
'wma' => 'audio/x-ms-wma',
|
||||
'xls' => 'application/vnd.ms-excel',
|
||||
'xml' => 'text/xml',
|
||||
'zip' => 'application/zip',
|
||||
);
|
||||
|
||||
/**
|
||||
* Protected constructor since this is a static class.
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
// Nothing here
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the File exists.
|
||||
*
|
||||
* <code>
|
||||
* if (File::exists('filename.txt')) {
|
||||
* // Do something...
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @param string $filename The file name
|
||||
* @return boolean
|
||||
*/
|
||||
public static function exists($filename)
|
||||
{
|
||||
// Redefine vars
|
||||
$filename = (string) $filename;
|
||||
|
||||
// Return
|
||||
return (file_exists($filename) && is_file($filename));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete file
|
||||
*
|
||||
* <code>
|
||||
* File::delete('filename.txt');
|
||||
* </code>
|
||||
*
|
||||
* @param mixed $filename The file name or array of files
|
||||
* @return boolean
|
||||
*/
|
||||
public static function delete($filename)
|
||||
{
|
||||
// Is array
|
||||
if (is_array($filename)) {
|
||||
|
||||
// Delete each file in $filename array
|
||||
foreach ($filename as $file) {
|
||||
@unlink((string) $file);
|
||||
}
|
||||
|
||||
} else {
|
||||
// Is string
|
||||
return @unlink((string) $filename);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename file
|
||||
*
|
||||
* <code>
|
||||
* File::rename('filename1.txt', 'filename2.txt');
|
||||
* </code>
|
||||
*
|
||||
* @param string $from Original file location
|
||||
* @param string $to Desitination location of the file
|
||||
* @return boolean
|
||||
*/
|
||||
public static function rename($from, $to)
|
||||
{
|
||||
// Redefine vars
|
||||
$from = (string) $from;
|
||||
$to = (string) $to;
|
||||
|
||||
// If file exists $to than rename it
|
||||
if ( ! File::exists($to)) return rename($from, $to);
|
||||
|
||||
// Else return false
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy file
|
||||
*
|
||||
* <code>
|
||||
* File::copy('folder1/filename.txt', 'folder2/filename.txt');
|
||||
* </code>
|
||||
*
|
||||
* @param string $from Original file location
|
||||
* @param string $to Desitination location of the file
|
||||
* @return boolean
|
||||
*/
|
||||
public static function copy($from, $to)
|
||||
{
|
||||
// Redefine vars
|
||||
$from = (string) $from;
|
||||
$to = (string) $to;
|
||||
|
||||
// If file !exists $from and exists $to then return false
|
||||
if ( ! File::exists($from) || File::exists($to)) return false;
|
||||
|
||||
// Else copy file
|
||||
return copy($from, $to);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the File extension.
|
||||
*
|
||||
* <code>
|
||||
* echo File::ext('filename.txt');
|
||||
* </code>
|
||||
*
|
||||
* @param string $filename The file name
|
||||
* @return string
|
||||
*/
|
||||
public static function ext($filename)
|
||||
{
|
||||
// Redefine vars
|
||||
$filename = (string) $filename;
|
||||
|
||||
// Return file extension
|
||||
return substr(strrchr($filename, '.'), 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the File name
|
||||
*
|
||||
* <code>
|
||||
* echo File::name('filename.txt');
|
||||
* </code>
|
||||
*
|
||||
* @param string $filename The file name
|
||||
* @return string
|
||||
*/
|
||||
public static function name($filename)
|
||||
{
|
||||
// Redefine vars
|
||||
$filename = (string) $filename;
|
||||
|
||||
// Return filename
|
||||
return basename($filename, '.'.File::ext($filename));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of files in directory recursive
|
||||
*
|
||||
* <code>
|
||||
* $files = File::scan('folder');
|
||||
* $files = File::scan('folder', 'txt');
|
||||
* $files = File::scan('folder', array('txt', 'log'));
|
||||
* </code>
|
||||
*
|
||||
* @param string $folder Folder
|
||||
* @param mixed $type Files types
|
||||
* @return array
|
||||
*/
|
||||
public static function scan($folder, $type = null)
|
||||
{
|
||||
$data = array();
|
||||
if (is_dir($folder)) {
|
||||
$iterator = new RecursiveDirectoryIterator($folder);
|
||||
foreach (new RecursiveIteratorIterator($iterator) as $file) {
|
||||
if ($type !== null) {
|
||||
if (is_array($type)) {
|
||||
$file_ext = substr(strrchr($file->getFilename(), '.'), 1);
|
||||
if (in_array($file_ext, $type)) {
|
||||
if (strpos($file->getFilename(), $file_ext, 1)) {
|
||||
$data[] = $file->getFilename();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (strpos($file->getFilename(), $type, 1)) {
|
||||
$data[] = $file->getFilename();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($file->getFilename() !== '.' && $file->getFilename() !== '..') $data[] = $file->getFilename();
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the content from a file or URL.
|
||||
*
|
||||
* <code>
|
||||
* echo File::getContent('filename.txt');
|
||||
* </code>
|
||||
*
|
||||
* @param string $filename The file name
|
||||
* @return boolean
|
||||
*/
|
||||
public static function getContent($filename)
|
||||
{
|
||||
// Redefine vars
|
||||
$filename = (string) $filename;
|
||||
|
||||
// If file exists load it
|
||||
if (File::exists($filename)) {
|
||||
return file_get_contents($filename);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a string to a file.
|
||||
*
|
||||
* @param string $filename The path of the file.
|
||||
* @param string $content The content that should be written.
|
||||
* @param boolean $createFile Should the file be created if it doesn't exists?
|
||||
* @param boolean $append Should the content be appended if the file already exists?
|
||||
* @param integer $chmod Mode that should be applied on the file.
|
||||
* @return boolean
|
||||
*/
|
||||
public static function setContent($filename, $content, $create_file = true, $append = false, $chmod = 0666)
|
||||
{
|
||||
// Redefine vars
|
||||
$filename = (string) $filename;
|
||||
$content = (string) $content;
|
||||
$create_file = (bool) $create_file;
|
||||
$append = (bool) $append;
|
||||
|
||||
// File may not be created, but it doesn't exist either
|
||||
if ( ! $create_file && File::exists($filename)) throw new RuntimeException(vsprintf("%s(): The file '{$filename}' doesn't exist", array(__METHOD__)));
|
||||
|
||||
// Create directory recursively if needed
|
||||
Dir::create(dirname($filename));
|
||||
|
||||
// Create file & open for writing
|
||||
$handler = ($append) ? @fopen($filename, 'a') : @fopen($filename, 'w');
|
||||
|
||||
// Something went wrong
|
||||
if ($handler === false) throw new RuntimeException(vsprintf("%s(): The file '{$filename}' could not be created. Check if PHP has enough permissions.", array(__METHOD__)));
|
||||
|
||||
// Store error reporting level
|
||||
$level = error_reporting();
|
||||
|
||||
// Disable errors
|
||||
error_reporting(0);
|
||||
|
||||
// Write to file
|
||||
$write = fwrite($handler, $content);
|
||||
|
||||
// Validate write
|
||||
if($write === false) throw new RuntimeException(vsprintf("%s(): The file '{$filename}' could not be created. Check if PHP has enough permissions.", array(__METHOD__)));
|
||||
|
||||
// Close the file
|
||||
fclose($handler);
|
||||
|
||||
// Chmod file
|
||||
chmod($filename, $chmod);
|
||||
|
||||
// Restore error reporting level
|
||||
error_reporting($level);
|
||||
|
||||
// Return
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get time(in Unix timestamp) the file was last changed
|
||||
*
|
||||
* <code>
|
||||
* echo File::lastChange('filename.txt');
|
||||
* </code>
|
||||
*
|
||||
* @param string $filename The file name
|
||||
* @return boolean
|
||||
*/
|
||||
public static function lastChange($filename)
|
||||
{
|
||||
// Redefine vars
|
||||
$filename = (string) $filename;
|
||||
|
||||
// If file exists return filemtime
|
||||
if (File::exists($filename)) {
|
||||
return filemtime($filename);
|
||||
}
|
||||
|
||||
// Return
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last access time
|
||||
*
|
||||
* <code>
|
||||
* echo File::lastAccess('filename.txt');
|
||||
* </code>
|
||||
*
|
||||
* @param string $filename The file name
|
||||
* @return boolean
|
||||
*/
|
||||
public static function lastAccess($filename)
|
||||
{
|
||||
// Redefine vars
|
||||
$filename = (string) $filename;
|
||||
|
||||
// If file exists return fileatime
|
||||
if (File::exists($filename)) {
|
||||
return fileatime($filename);
|
||||
}
|
||||
|
||||
// Return
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mime type of a file. Returns false if the mime type is not found.
|
||||
*
|
||||
* <code>
|
||||
* echo File::mime('filename.txt');
|
||||
* </code>
|
||||
*
|
||||
* @param string $file Full path to the file
|
||||
* @param boolean $guess Set to false to disable mime type guessing
|
||||
* @return string
|
||||
*/
|
||||
public static function mime($file, $guess = true)
|
||||
{
|
||||
// Redefine vars
|
||||
$file = (string) $file;
|
||||
$guess = (bool) $guess;
|
||||
|
||||
// Get mime using the file information functions
|
||||
if (function_exists('finfo_open')) {
|
||||
|
||||
$info = finfo_open(FILEINFO_MIME_TYPE);
|
||||
|
||||
$mime = finfo_file($info, $file);
|
||||
|
||||
finfo_close($info);
|
||||
|
||||
return $mime;
|
||||
|
||||
} else {
|
||||
|
||||
// Just guess mime by using the file extension
|
||||
if ($guess === true) {
|
||||
|
||||
$mime_types = File::$mime_types;
|
||||
|
||||
$extension = pathinfo($file, PATHINFO_EXTENSION);
|
||||
|
||||
return isset($mime_types[$extension]) ? $mime_types[$extension] : false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces a file to be downloaded.
|
||||
*
|
||||
* <code>
|
||||
* File::download('filename.txt');
|
||||
* </code>
|
||||
*
|
||||
* @param string $file Full path to file
|
||||
* @param string $content_type Content type of the file
|
||||
* @param string $filename Filename of the download
|
||||
* @param integer $kbps Max download speed in KiB/s
|
||||
*/
|
||||
public static function download($file, $content_type = null, $filename = null, $kbps = 0)
|
||||
{
|
||||
// Redefine vars
|
||||
$file = (string) $file;
|
||||
$content_type = ($content_type === null) ? null : (string) $content_type;
|
||||
$filename = ($filename === null) ? null : (string) $filename;
|
||||
$kbps = (int) $kbps;
|
||||
|
||||
// Check that the file exists and that its readable
|
||||
if (file_exists($file) === false || is_readable($file) === false) {
|
||||
throw new RuntimeException(vsprintf("%s(): Failed to open stream.", array(__METHOD__)));
|
||||
}
|
||||
|
||||
// Empty output buffers
|
||||
while (ob_get_level() > 0) ob_end_clean();
|
||||
|
||||
// Send headers
|
||||
if ($content_type === null) $content_type = File::mime($file);
|
||||
|
||||
if ($filename === null) $filename = basename($file);
|
||||
|
||||
header('Content-type: ' . $content_type);
|
||||
header('Content-Disposition: attachment; filename="' . $filename . '"');
|
||||
header('Content-Length: ' . filesize($file));
|
||||
|
||||
// Read file and write it to the output
|
||||
@set_time_limit(0);
|
||||
|
||||
if ($kbps === 0) {
|
||||
|
||||
readfile($file);
|
||||
|
||||
} else {
|
||||
|
||||
$handle = fopen($file, 'r');
|
||||
|
||||
while ( ! feof($handle) && !connection_aborted()) {
|
||||
|
||||
$s = microtime(true);
|
||||
|
||||
echo fread($handle, round($kbps * 1024));
|
||||
|
||||
if (($wait = 1e6 - (microtime(true) - $s)) > 0) usleep($wait);
|
||||
|
||||
}
|
||||
|
||||
fclose($handle);
|
||||
}
|
||||
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a file in the browser.
|
||||
*
|
||||
* <code>
|
||||
* File::display('filename.txt');
|
||||
* </code>
|
||||
*
|
||||
* @param string $file Full path to file
|
||||
* @param string $content_type Content type of the file
|
||||
* @param string $filename Filename of the download
|
||||
*/
|
||||
public static function display($file, $content_type = null, $filename = null)
|
||||
{
|
||||
// Redefine vars
|
||||
$file = (string) $file;
|
||||
$content_type = ($content_type === null) ? null : (string) $content_type;
|
||||
$filename = ($filename === null) ? null : (string) $filename;
|
||||
|
||||
// Check that the file exists and that its readable
|
||||
if (file_exists($file) === false || is_readable($file) === false) {
|
||||
throw new RuntimeException(vsprintf("%s(): Failed to open stream.", array(__METHOD__)));
|
||||
}
|
||||
|
||||
// Empty output buffers
|
||||
while (ob_get_level() > 0) ob_end_clean();
|
||||
|
||||
// Send headers
|
||||
if ($content_type === null) $content_type = File::mime($file);
|
||||
|
||||
if($filename === null) $filename = basename($file);
|
||||
|
||||
header('Content-type: ' . $content_type);
|
||||
header('Content-Disposition: inline; filename="' . $filename . '"');
|
||||
header('Content-Length: ' . filesize($file));
|
||||
|
||||
// Read file and write to output
|
||||
readfile($file);
|
||||
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether a file is writable for anyone.
|
||||
*
|
||||
* <code>
|
||||
* if (File::writable('filename.txt')) {
|
||||
* // do something...
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @param string $file File to check
|
||||
* @return boolean
|
||||
*/
|
||||
public static function writable($file)
|
||||
{
|
||||
// Redefine vars
|
||||
$file = (string) $file;
|
||||
|
||||
// Is file exists ?
|
||||
if ( ! file_exists($file)) throw new RuntimeException(vsprintf("%s(): The file '{$file}' doesn't exist", array(__METHOD__)));
|
||||
|
||||
// Gets file permissions
|
||||
$perms = fileperms($file);
|
||||
|
||||
// Is writable ?
|
||||
if (is_writable($file) || ($perms & 0x0080) || ($perms & 0x0010) || ($perms & 0x0002)) return true;
|
||||
}
|
||||
|
||||
}
|
409
libraries/monstra/Form.php
Normal file
409
libraries/monstra/Form.php
Normal file
@@ -0,0 +1,409 @@
|
||||
<?php
|
||||
/**
|
||||
* Monstra Library
|
||||
*
|
||||
* This source file is part of the Monstra Library. More information,
|
||||
* documentation and tutorials can be found at http://library.monstra.org
|
||||
*
|
||||
* @package Monstra
|
||||
*
|
||||
* @author Romanenko Sergey / Awilum
|
||||
* @copyright (c) 2012 - 2013 Romanenko Sergey / Awilum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
class Form
|
||||
{
|
||||
/**
|
||||
* The registered custom macros.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $macros = array();
|
||||
|
||||
/**
|
||||
* Protected constructor since this is a static class.
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
// Nothing here
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a custom macro.
|
||||
*
|
||||
* <code>
|
||||
*
|
||||
* // Registering a Form macro
|
||||
* Form::macro('my_field', function() {
|
||||
* return '<input type="text" name="my_field">';
|
||||
* });
|
||||
*
|
||||
* // Calling a custom Form macro
|
||||
* echo Form::my_field();
|
||||
*
|
||||
*
|
||||
* // Registering a Form macro with parameters
|
||||
* Form::macro('my_field', function($value = '') {
|
||||
* return '<input type="text" name="my_field" value="'.$value.'">';
|
||||
* });
|
||||
*
|
||||
* // Calling a custom Form macro with parameters
|
||||
* echo Form::my_field('Monstra');
|
||||
*
|
||||
* </code>
|
||||
*
|
||||
* @param string $name Name
|
||||
* @param Closure $macro Macro
|
||||
*/
|
||||
public static function macro($name, $macro)
|
||||
{
|
||||
Form::$macros[$name] = $macro;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an opening HTML form tag.
|
||||
*
|
||||
* <code>
|
||||
* // Form will submit back to the current page using POST
|
||||
* echo Form::open();
|
||||
*
|
||||
* // Form will submit to 'search' using GET
|
||||
* echo Form::open('search', array('method' => 'get'));
|
||||
*
|
||||
* // When "file" inputs are present, you must include the "enctype"
|
||||
* echo Form::open(null, array('enctype' => 'multipart/form-data'));
|
||||
* </code>
|
||||
*
|
||||
* @param mixed $action Form action, defaults to the current request URI.
|
||||
* @param array $attributes HTML attributes.
|
||||
* @uses Url::base
|
||||
* @uses Html::attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function open($action = null, array $attributes = null)
|
||||
{
|
||||
if (! $action) {
|
||||
|
||||
// Submits back to the current url
|
||||
$action = '';
|
||||
|
||||
} elseif (strpos($action, '://') === false) {
|
||||
|
||||
// Make the URI absolute
|
||||
$action = Url::base() . '/' . $action;
|
||||
}
|
||||
|
||||
// Add the form action to the attributes
|
||||
$attributes['action'] = $action;
|
||||
|
||||
if ( ! isset($attributes['method'])) {
|
||||
|
||||
// Use POST method
|
||||
$attributes['method'] = 'post';
|
||||
}
|
||||
|
||||
return '<form'.Html::attributes($attributes).'>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a form input.
|
||||
* Text is default input type.
|
||||
*
|
||||
* <code>
|
||||
* echo Form::input('username', $username);
|
||||
* </code>
|
||||
*
|
||||
* @param string $name Input name
|
||||
* @param string $value Input value
|
||||
* @param array $attributes HTML attributes
|
||||
* @uses Html::attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function input($name, $value = null, array $attributes = null)
|
||||
{
|
||||
// Set the input name
|
||||
$attributes['name'] = $name;
|
||||
|
||||
// Set the input id
|
||||
$attributes['id'] = (isset($attributes['id']))?$attributes['id']:$name;
|
||||
|
||||
// Set the input value
|
||||
$attributes['value'] = $value;
|
||||
|
||||
if ( ! isset($attributes['type'])) {
|
||||
// Default type is text
|
||||
$attributes['type'] = 'text';
|
||||
}
|
||||
|
||||
return '<input'.Html::attributes($attributes).' />';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a hidden form input.
|
||||
*
|
||||
* <code>
|
||||
* echo Form::hidden('user_id', $user_id);
|
||||
* </code>
|
||||
*
|
||||
* @param string $name Input name
|
||||
* @param string $value Input value
|
||||
* @param array $attributes HTML attributes
|
||||
* @uses Form::input
|
||||
* @return string
|
||||
*/
|
||||
public static function hidden($name, $value = null, array $attributes = null)
|
||||
{
|
||||
// Set the input type
|
||||
$attributes['type'] = 'hidden';
|
||||
|
||||
return Form::input($name, $value, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a password form input.
|
||||
*
|
||||
* <code>
|
||||
* echo Form::password('password');
|
||||
* </code>
|
||||
*
|
||||
* @param string $name Input name
|
||||
* @param string $value Input value
|
||||
* @param array $attributes HTML attributes
|
||||
* @uses Form::input
|
||||
* @return string
|
||||
*/
|
||||
public static function password($name, $value = null, array $attributes = null)
|
||||
{
|
||||
// Set the input type
|
||||
$attributes['type'] = 'password';
|
||||
|
||||
return Form::input($name, $value, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a file upload form input.
|
||||
*
|
||||
* <code>
|
||||
* echo Form::file('image');
|
||||
* </code>
|
||||
*
|
||||
* @param string $name Input name
|
||||
* @param array $attributes HTML attributes
|
||||
* @uses Form::input
|
||||
* @return string
|
||||
*/
|
||||
public static function file($name, array $attributes = null)
|
||||
{
|
||||
// Set the input type
|
||||
$attributes['type'] = 'file';
|
||||
|
||||
return Form::input($name, null, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a checkbox form input.
|
||||
*
|
||||
* <code>
|
||||
* echo Form::checkbox('i_am_not_a_robot');
|
||||
* </code>
|
||||
*
|
||||
* @param string $name Input name
|
||||
* @param string $input Input value
|
||||
* @param boolean $checked Checked status
|
||||
* @param array $attributes HTML attributes
|
||||
* @uses Form::input
|
||||
* @return string
|
||||
*/
|
||||
public static function checkbox($name, $value = null, $checked = false, array $attributes = null)
|
||||
{
|
||||
// Set the input type
|
||||
$attributes['type'] = 'checkbox';
|
||||
|
||||
if ($checked === true) {
|
||||
// Make the checkbox active
|
||||
$attributes['checked'] = 'checked';
|
||||
}
|
||||
|
||||
return Form::input($name, $value, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a radio form input.
|
||||
*
|
||||
* <code>
|
||||
* echo Form::radio('i_am_not_a_robot');
|
||||
* </code>
|
||||
*
|
||||
* @param string $name Input name
|
||||
* @param string $value Input value
|
||||
* @param boolean $checked Checked status
|
||||
* @param array $attributes HTML attributes
|
||||
* @uses Form::input
|
||||
* @return string
|
||||
*/
|
||||
public static function radio($name, $value = null, $checked = null, array $attributes = null)
|
||||
{
|
||||
// Set the input type
|
||||
$attributes['type'] = 'radio';
|
||||
|
||||
if ($checked === true) {
|
||||
// Make the radio active
|
||||
$attributes['checked'] = 'checked';
|
||||
}
|
||||
|
||||
return Form::input($name, $value, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a textarea form input.
|
||||
*
|
||||
* <code>
|
||||
* echo Form::textarea('text', $text);
|
||||
* </code>
|
||||
*
|
||||
* @param string $name Name
|
||||
* @param string $body Body
|
||||
* @param array $attributes HTML attributes
|
||||
* @uses Html::attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function textarea($name, $body = '', array $attributes = null)
|
||||
{
|
||||
// Set the input name
|
||||
$attributes['name'] = $name;
|
||||
|
||||
// Set the input id
|
||||
$attributes['id'] = (isset($attributes['id']))?$attributes['id']:$name;
|
||||
|
||||
return '<textarea'.Html::attributes($attributes).'>'.$body.'</textarea>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a select form input.
|
||||
*
|
||||
* <code>
|
||||
* echo Form::select('themes', array('default', 'classic', 'modern'));
|
||||
* </code>
|
||||
*
|
||||
* @param string $name Name
|
||||
* @param array $options Options array
|
||||
* @param string $selected Selected option
|
||||
* @param array $attributes HTML attributes
|
||||
* @uses Html::attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function select($name, array $options = null, $selected = null, array $attributes = null)
|
||||
{
|
||||
// Set the input name
|
||||
$attributes['name'] = $name;
|
||||
|
||||
// Set the input id
|
||||
$attributes['id'] = (isset($attributes['id']))?$attributes['id']:$name;
|
||||
|
||||
$options_output = '';
|
||||
|
||||
foreach ($options as $value => $name) {
|
||||
if ($selected == $value) $current = ' selected '; else $current = '';
|
||||
$options_output .= '<option value="'.$value.'" '.$current.'>'.$name.'</option>';
|
||||
}
|
||||
|
||||
return '<select'.Html::attributes($attributes).'>'.$options_output.'</select>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a submit form input.
|
||||
*
|
||||
* <code>
|
||||
* echo Form::submit('save', 'Save');
|
||||
* </code>
|
||||
*
|
||||
* @param string $name Input name
|
||||
* @param string $value Input value
|
||||
* @param array $attributes HTML attributes
|
||||
* @uses Form::input
|
||||
* @return string
|
||||
*/
|
||||
public static function submit($name, $value, array $attributes = null)
|
||||
{
|
||||
// Set the input type
|
||||
$attributes['type'] = 'submit';
|
||||
|
||||
return Form::input($name, $value, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a button form input.
|
||||
*
|
||||
* <code>
|
||||
* echo Form::button('save', 'Save Profile', array('type' => 'submit'));
|
||||
* </code>
|
||||
*
|
||||
* @param string $name Input name
|
||||
* @param string $value Input value
|
||||
* @param array $attributes HTML attributes
|
||||
* @uses Html::attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function button($name, $body, array $attributes = null)
|
||||
{
|
||||
// Set the input name
|
||||
$attributes['name'] = $name;
|
||||
|
||||
return '<button'.Html::attributes($attributes).'>'.$body.'</button>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a form label.
|
||||
*
|
||||
* <code>
|
||||
* echo Form::label('username', 'Username');
|
||||
* </code>
|
||||
*
|
||||
* @param string $input Target input
|
||||
* @param string $text Label text
|
||||
* @param array $attributes HTML attributes
|
||||
* @uses Html::attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function label($input, $text, array $attributes = null)
|
||||
{
|
||||
// Set the label target
|
||||
$attributes['for'] = $input;
|
||||
|
||||
return '<label'.Html::attributes($attributes).'>'.$text.'</label>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create closing form tag.
|
||||
*
|
||||
* <code>
|
||||
* echo Form::close();
|
||||
* </code>
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function close()
|
||||
{
|
||||
return '</form>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamically handle calls to custom macros.
|
||||
*
|
||||
* @param string $method
|
||||
* @param array $parameters
|
||||
* @return mixed
|
||||
*/
|
||||
public static function __callStatic($method, $parameters)
|
||||
{
|
||||
if (isset(Form::$macros[$method])) {
|
||||
return call_user_func_array(Form::$macros[$method], $parameters);
|
||||
}
|
||||
|
||||
throw new RuntimeException("Method [$method] does not exist.");
|
||||
}
|
||||
|
||||
}
|
314
libraries/monstra/Html.php
Normal file
314
libraries/monstra/Html.php
Normal file
@@ -0,0 +1,314 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Monstra Library
|
||||
*
|
||||
* This source file is part of the Monstra Library. More information,
|
||||
* documentation and tutorials can be found at http://library.monstra.org
|
||||
*
|
||||
* @package Monstra
|
||||
*
|
||||
* @author Romanenko Sergey / Awilum
|
||||
* @copyright (c) 2012 - 2013 Romanenko Sergey / Awilum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
class Html
|
||||
{
|
||||
/**
|
||||
* Preferred order of attributes
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $attribute_order = array (
|
||||
'action', 'method', 'type', 'id', 'name', 'value',
|
||||
'href', 'src', 'width', 'height', 'cols', 'rows',
|
||||
'size', 'maxlength', 'rel', 'media', 'accept-charset',
|
||||
'accept', 'tabindex', 'accesskey', 'alt', 'title', 'class',
|
||||
'style', 'selected', 'checked', 'readonly', 'disabled',
|
||||
);
|
||||
|
||||
/**
|
||||
* Protected constructor since this is a static class.
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
// Nothing here
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a custom macro.
|
||||
*
|
||||
* <code>
|
||||
*
|
||||
* // Registering a Htmlk macro
|
||||
* Html::macro('my_element', function() {
|
||||
* return '<element id="monstra">';
|
||||
* });
|
||||
*
|
||||
* // Calling a custom Html macro
|
||||
* echo Html::my_element();
|
||||
*
|
||||
*
|
||||
* // Registering a Html macro with parameters
|
||||
* Html::macro('my_element', function(id = '') {
|
||||
* return '<element id="'.$id.'">';
|
||||
* });
|
||||
*
|
||||
* // Calling a custom Html macro with parameters
|
||||
* echo Html::my_element('monstra');
|
||||
*
|
||||
* </code>
|
||||
*
|
||||
* @param string $name Name
|
||||
* @param Closure $macro Macro
|
||||
*/
|
||||
public static function macro($name, $macro)
|
||||
{
|
||||
Html::$macros[$name] = $macro;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert special characters to HTML entities. All untrusted content
|
||||
* should be passed through this method to prevent XSS injections.
|
||||
*
|
||||
* <code>
|
||||
* echo Html::chars($username);
|
||||
* </code>
|
||||
*
|
||||
* @param string $value String to convert
|
||||
* @param boolean $double_encode Encode existing entities
|
||||
* @return string
|
||||
*/
|
||||
public static function chars($value, $double_encode = true)
|
||||
{
|
||||
return htmlspecialchars((string) $value, ENT_QUOTES, 'utf-8', $double_encode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles an array of HTML attributes into an attribute string.
|
||||
* Attributes will be sorted using Html::$attribute_order for consistency.
|
||||
*
|
||||
* <code>
|
||||
* echo '<div'.Html::attributes($attrs).'>'.$content.'</div>';
|
||||
* </code>
|
||||
*
|
||||
* @param array $attributes Attribute list
|
||||
* @return string
|
||||
*/
|
||||
public static function attributes(array $attributes = null)
|
||||
{
|
||||
if (empty($attributes)) return '';
|
||||
|
||||
// Init var
|
||||
$sorted = array();
|
||||
|
||||
foreach (Html::$attribute_order as $key) {
|
||||
|
||||
if (isset($attributes[$key])) {
|
||||
// Add the attribute to the sorted list
|
||||
$sorted[$key] = $attributes[$key];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Combine the sorted attributes
|
||||
$attributes = $sorted + $attributes;
|
||||
|
||||
$compiled = '';
|
||||
foreach ($attributes as $key => $value) {
|
||||
|
||||
if ($value === NULL) {
|
||||
// Skip attributes that have NULL values
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_int($key)) {
|
||||
// Assume non-associative keys are mirrored attributes
|
||||
$key = $value;
|
||||
}
|
||||
|
||||
// Add the attribute value
|
||||
$compiled .= ' '.$key.'="'.Html::chars($value).'"';
|
||||
}
|
||||
|
||||
return $compiled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create br tags
|
||||
*
|
||||
* <code>
|
||||
* echo Html::br(2);
|
||||
* </code>
|
||||
*
|
||||
* @param integer $num Count of line break tag
|
||||
* @return string
|
||||
*/
|
||||
public static function br($num = 1)
|
||||
{
|
||||
return str_repeat("<br />",(int) $num);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create
|
||||
*
|
||||
* <code>
|
||||
* echo Html::nbsp(2);
|
||||
* </code>
|
||||
*
|
||||
* @param integer $num Count of
|
||||
* @return string
|
||||
*/
|
||||
public static function nbsp($num = 1)
|
||||
{
|
||||
return str_repeat(" ", (int) $num);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an arrow
|
||||
*
|
||||
* <code>
|
||||
* echo Html::arrow('right');
|
||||
* </code>
|
||||
*
|
||||
* @param string $direction Arrow direction [up,down,left,right]
|
||||
* @param boolean $render If this option is true then render html object else return it
|
||||
* @return string
|
||||
*/
|
||||
public static function arrow($direction)
|
||||
{
|
||||
switch ($direction) {
|
||||
case "up": $output = '<span class="arrow">↑</span>'; break;
|
||||
case "down": $output = '<span class="arrow">↓</span>'; break;
|
||||
case "left": $output = '<span class="arrow">←</span>'; break;
|
||||
case "right": $output = '<span class="arrow">→</span>'; break;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create HTML link anchor.
|
||||
*
|
||||
* <code>
|
||||
* echo Html::anchor('About', 'http://sitename.com/about');
|
||||
* </code>
|
||||
*
|
||||
* @param string $title Anchor title
|
||||
* @param string $url Anchor url
|
||||
* @param array $attributes Anchor attributes
|
||||
* @uses Html::attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function anchor($title, $url = null, array $attributes = null)
|
||||
{
|
||||
// Add link
|
||||
if ($url !== null) $attributes['href'] = $url;
|
||||
return '<a'.Html::attributes($attributes).'>'.$title.'</a>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create HTML <h> tag
|
||||
*
|
||||
* <code>
|
||||
* echo Html::heading('Title', 1);
|
||||
* </code>
|
||||
*
|
||||
* @param string $title Text
|
||||
* @param integer $h Number [1-6]
|
||||
* @param array $attributes Heading attributes
|
||||
* @uses Html::attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function heading($title, $h = 1, array $attributes = null)
|
||||
{
|
||||
$output = '<h'.(int) $h.Html::attributes($attributes).'>'.$title.'</h'.(int) $h.'>';
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate document type declarations
|
||||
*
|
||||
* <code>
|
||||
* echo Html::doctype('html5');
|
||||
* </code>
|
||||
*
|
||||
* @param string $type Doctype to generated
|
||||
* @return mixed
|
||||
*/
|
||||
public static function doctype($type = 'html5')
|
||||
{
|
||||
$doctypes = array('xhtml11' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">',
|
||||
'xhtml1-strict' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
|
||||
'xhtml1-trans' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
|
||||
'xhtml1-frame' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">',
|
||||
'html5' => '<!DOCTYPE html>',
|
||||
'html4-strict' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">',
|
||||
'html4-trans' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">',
|
||||
'html4-frame' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">');
|
||||
|
||||
if (isset($doctypes[$type])) return $doctypes[$type]; else return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create image
|
||||
*
|
||||
* <code>
|
||||
* echo Html::image('data/files/pic1.jpg');
|
||||
* </code>
|
||||
*
|
||||
* @param array $attributes Image attributes
|
||||
* @param string $file File
|
||||
* @uses Url::base
|
||||
* @return string
|
||||
*/
|
||||
public static function image($file, array $attributes = null)
|
||||
{
|
||||
if (strpos($file, '://') === FALSE) {
|
||||
$file = Url::base().'/'.$file;
|
||||
}
|
||||
|
||||
// Add the image link
|
||||
$attributes['src'] = $file;
|
||||
$attributes['alt'] = (isset($attributes['alt'])) ? $attributes['alt'] : pathinfo($file, PATHINFO_FILENAME);
|
||||
|
||||
return '<img'.Html::attributes($attributes).' />';
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert html to plain text
|
||||
*
|
||||
* <code>
|
||||
* echo Html::toText('test');
|
||||
* </code>
|
||||
*
|
||||
* @param string $str String
|
||||
* @return string
|
||||
*/
|
||||
public static function toText($str)
|
||||
{
|
||||
return htmlspecialchars($str, ENT_QUOTES, 'utf-8');
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamically handle calls to custom macros.
|
||||
*
|
||||
* @param string $method
|
||||
* @param array $parameters
|
||||
* @return mixed
|
||||
*/
|
||||
public static function __callStatic($method, $parameters)
|
||||
{
|
||||
if (isset(Html::$macros[$method])) {
|
||||
return call_user_func_array(Html::$macros[$method], $parameters);
|
||||
}
|
||||
|
||||
throw new RuntimeException("Method [$method] does not exist.");
|
||||
}
|
||||
|
||||
}
|
653
libraries/monstra/Image.php
Normal file
653
libraries/monstra/Image.php
Normal file
@@ -0,0 +1,653 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Monstra Library
|
||||
*
|
||||
* This source file is part of the Monstra Library. More information,
|
||||
* documentation and tutorials can be found at http://library.monstra.org
|
||||
*
|
||||
* @package Monstra
|
||||
*
|
||||
* @author Romanenko Sergey / Awilum
|
||||
* @copyright (c) 2012 - 2013 Romanenko Sergey / Awilum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
class Image
|
||||
{
|
||||
/**
|
||||
* Resizing contraint.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
const AUTO = 1;
|
||||
|
||||
/**
|
||||
* Resizing contraint.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
const WIDTH = 2;
|
||||
|
||||
/**
|
||||
* Resizing contraint.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
const HEIGHT = 3;
|
||||
|
||||
/**
|
||||
* Watermark position.
|
||||
*/
|
||||
const TOP_LEFT = 4;
|
||||
|
||||
/**
|
||||
* Watermark position.
|
||||
*/
|
||||
const TOP_RIGHT = 5;
|
||||
|
||||
/**
|
||||
* Watermark position.
|
||||
*/
|
||||
const BOTTOM_LEFT = 6;
|
||||
|
||||
/**
|
||||
* Watermark position.
|
||||
*/
|
||||
const BOTTOM_RIGHT = 7;
|
||||
|
||||
/**
|
||||
* Watermark position.
|
||||
*/
|
||||
const CENTER = 8;
|
||||
|
||||
/**
|
||||
* Holds info about the image.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $image_info;
|
||||
|
||||
/**
|
||||
* Get value
|
||||
*
|
||||
* @param string $key Key
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get($key)
|
||||
{
|
||||
if (array_key_exists($key, $this->image_info)) return $this->image_info[$key];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set value for specific key
|
||||
*
|
||||
* @param string $key Key
|
||||
* @param mixed $value Value
|
||||
*/
|
||||
public function __set($key, $value)
|
||||
{
|
||||
$this->image_info[$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Image factory.
|
||||
*
|
||||
* <code>
|
||||
* $image = Image::factory('original.png');
|
||||
* </code>
|
||||
*
|
||||
* @param string $filename Filename
|
||||
* @return Image
|
||||
*/
|
||||
public static function factory($filename)
|
||||
{
|
||||
return new Image($filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param string $file Filename
|
||||
*/
|
||||
public function __construct($file)
|
||||
{
|
||||
// Redefine vars
|
||||
$file = (string) $file;
|
||||
|
||||
// Check if the file exists
|
||||
if (file_exists($file)) {
|
||||
|
||||
// Extract attributes of the image file
|
||||
list($this->width, $this->height, $type, $a) = getimagesize($file);
|
||||
|
||||
// Save image type
|
||||
$this->type = $type;
|
||||
|
||||
// Create a new image
|
||||
$this->image = $this->createImage($file, $type);
|
||||
} else {
|
||||
throw new RuntimeException(vsprintf("%s(): The file '{$file}' doesn't exist", array(__METHOD__)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new image from file.
|
||||
*
|
||||
* @param string $file Path to the image file
|
||||
* @param integer $type Image type
|
||||
* @return resource
|
||||
*/
|
||||
protected function createImage($file, $type)
|
||||
{
|
||||
// Create image from file
|
||||
switch ($type) {
|
||||
case IMAGETYPE_JPEG:
|
||||
return imagecreatefromjpeg($file);
|
||||
break;
|
||||
case IMAGETYPE_GIF:
|
||||
return imagecreatefromgif($file);
|
||||
break;
|
||||
case IMAGETYPE_PNG:
|
||||
return imagecreatefrompng($file);
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(vsprintf("%s(): Unable to open '%s'. Unsupported image type.", array(__METHOD__, $type)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resizes the image to the chosen size.
|
||||
*
|
||||
* <code>
|
||||
* Image::factory('original.png')->resize(800, 600)->save('edited.png');
|
||||
* </code>
|
||||
*
|
||||
* @param integer $width Width of the image
|
||||
* @param integer $height Height of the image
|
||||
* @param integer $aspect_ratio Aspect ratio (Image::AUTO Image::WIDTH Image::HEIGHT)
|
||||
* @return Image
|
||||
*/
|
||||
public function resize($width, $height = null, $aspect_ratio = null)
|
||||
{
|
||||
// Redefine vars
|
||||
$width = (int) $width;
|
||||
$height = ($height === null) ? null : (int) $height;
|
||||
$aspect_ratio = ($aspect_ratio === null) ? null : (int) $aspect_ratio;
|
||||
|
||||
// Resizes the image to {$width}% of the original size
|
||||
if ($height === null) {
|
||||
|
||||
$new_width = round($this->width * ($width / 100));
|
||||
$new_height = round($this->height * ($width / 100));
|
||||
|
||||
} else {
|
||||
|
||||
// Resizes the image to the smalles possible dimension while maintaining aspect ratio
|
||||
if ($aspect_ratio === Image::AUTO) {
|
||||
|
||||
// Calculate smallest size based on given height and width while maintaining aspect ratio
|
||||
$percentage = min(($width / $this->width), ($height / $this->height));
|
||||
|
||||
$new_width = round($this->width * $percentage);
|
||||
$new_height = round($this->height * $percentage);
|
||||
|
||||
// Resizes the image using the width to maintain aspect ratio
|
||||
} elseif ($aspect_ratio === Image::WIDTH) {
|
||||
|
||||
// Base new size on given width while maintaining aspect ratio
|
||||
$new_width = $width;
|
||||
$new_height = round($this->height * ($width / $this->width));
|
||||
|
||||
// Resizes the image using the height to maintain aspect ratio
|
||||
} elseif ($aspect_ratio === Image::HEIGHT) {
|
||||
|
||||
// Base new size on given height while maintaining aspect ratio
|
||||
$new_width = round($this->width * ($height / $this->height));
|
||||
$new_height = $height;
|
||||
|
||||
// Resizes the image to a dimension of {$width}x{$height} pixels while ignoring the aspect ratio
|
||||
} else {
|
||||
|
||||
$new_width = $width;
|
||||
$new_height = $height;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new true color image width new width and height
|
||||
$resized = imagecreatetruecolor($new_width, $new_height);
|
||||
|
||||
// Copy and resize part of an image with resampling
|
||||
imagecopyresampled($resized, $this->image, 0, 0, 0, 0, $new_width, $new_height, $this->width, $this->height);
|
||||
|
||||
// Destroy an image
|
||||
imagedestroy($this->image);
|
||||
|
||||
// Create a new true color image width new width and height
|
||||
$this->image = imagecreatetruecolor($new_width, $new_height);
|
||||
|
||||
// Copy and resize part of an image with resampling
|
||||
imagecopyresampled($this->image, $resized, 0, 0, 0, 0, $new_width, $new_height, $new_width, $new_height);
|
||||
|
||||
// Destroy an image
|
||||
imagedestroy($resized);
|
||||
|
||||
// Save new width and height
|
||||
$this->width = $new_width;
|
||||
$this->height = $new_height;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Crops the image
|
||||
*
|
||||
* <code>
|
||||
* Image::factory('original.png')->crop(800, 600, 0, 0)->save('edited.png');
|
||||
* </code>
|
||||
*
|
||||
* @param integer $width Width of the crop
|
||||
* @param integer $height Height of the crop
|
||||
* @param integer $x The X coordinate of the cropped region's top left corner
|
||||
* @param integer $y The Y coordinate of the cropped region's top left corner
|
||||
* @return Image
|
||||
*/
|
||||
public function crop($width, $height, $x, $y)
|
||||
{
|
||||
// Redefine vars
|
||||
$width = (int) $width;
|
||||
$height = (int) $height;
|
||||
$x = (int) $x;
|
||||
$y = (int) $y;
|
||||
|
||||
// Calculate
|
||||
if ($x + $width > $this->width) $width = $this->width - $x;
|
||||
if ($y + $height > $this->height) $height = $this->height - $y;
|
||||
if ($width <= 0 || $height <= 0) return false;
|
||||
|
||||
// Create a new true color image
|
||||
$crop = imagecreatetruecolor($width, $height);
|
||||
|
||||
// Copy and resize part of an image with resampling
|
||||
imagecopyresampled($crop, $this->image, 0, 0, $x, $y, $this->width, $this->height, $this->width, $this->height);
|
||||
|
||||
// Destroy an image
|
||||
imagedestroy($this->image);
|
||||
|
||||
// Create a new true color image
|
||||
$this->image = imagecreatetruecolor($width, $height);
|
||||
|
||||
// Copy and resize part of an image with resampling
|
||||
imagecopyresampled($this->image, $crop, 0, 0, 0, 0, $width, $height, $width, $height);
|
||||
|
||||
// Destroy an image
|
||||
imagedestroy($crop);
|
||||
|
||||
// Save new width and height
|
||||
$this->width = $width;
|
||||
$this->height = $height;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a watermark to the image.
|
||||
*
|
||||
* @param string $file Path to the image file
|
||||
* @param integer $position Position of the watermark
|
||||
* @param integer $opacity Opacity of the watermark in percent
|
||||
* @return Image
|
||||
*/
|
||||
public function watermark($file, $position = null, $opacity = 100)
|
||||
{
|
||||
// Check if the image exists
|
||||
if ( ! file_exists($file)) {
|
||||
throw new RuntimeException(vsprintf("%s(): The image file ('%s') does not exist.", array(__METHOD__, $file)));
|
||||
}
|
||||
|
||||
$watermark = $this->createImage($file, $this->type);
|
||||
|
||||
$watermarkW = imagesx($watermark);
|
||||
$watermarkH = imagesy($watermark);
|
||||
|
||||
// Make sure that opacity is between 0 and 100
|
||||
$opacity = max(min((int) $opacity, 100), 0);
|
||||
|
||||
if ($opacity < 100) {
|
||||
|
||||
if (GD_BUNDLED === 0) {
|
||||
throw new RuntimeException(vsprintf("%s(): Setting watermark opacity requires the 'imagelayereffect' function which is only available in the bundled version of GD.", array(__METHOD__)));
|
||||
}
|
||||
|
||||
// Convert alpha to 0-127
|
||||
$alpha = min(round(abs(($opacity * 127 / 100) - 127)), 127);
|
||||
|
||||
$transparent = imagecolorallocatealpha($watermark, 0, 0, 0, $alpha);
|
||||
|
||||
imagelayereffect($watermark, IMG_EFFECT_OVERLAY);
|
||||
|
||||
imagefilledrectangle($watermark, 0, 0, $watermarkW, $watermarkH, $transparent);
|
||||
}
|
||||
|
||||
// Position the watermark.
|
||||
switch ($position) {
|
||||
case Image::TOP_RIGHT:
|
||||
$x = imagesx($this->image) - $watermarkW;
|
||||
$y = 0;
|
||||
break;
|
||||
case Image::BOTTOM_LEFT:
|
||||
$x = 0;
|
||||
$y = imagesy($this->image) - $watermarkH;
|
||||
break;
|
||||
case Image::BOTTOM_RIGHT:
|
||||
$x = imagesx($this->image) - $watermarkW;
|
||||
$y = imagesy($this->image) - $watermarkH;
|
||||
break;
|
||||
case Image::CENTER:
|
||||
$x = (imagesx($this->image) / 2) - ($watermarkW / 2);
|
||||
$y = (imagesy($this->image) / 2) - ($watermarkH / 2);
|
||||
break;
|
||||
default:
|
||||
$x = 0;
|
||||
$y = 0;
|
||||
}
|
||||
|
||||
imagealphablending($this->image, true);
|
||||
|
||||
imagecopy($this->image, $watermark, $x, $y, 0, 0, $watermarkW, $watermarkH);
|
||||
|
||||
imagedestroy($watermark);
|
||||
|
||||
// Return Image
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert image into grayscale
|
||||
*
|
||||
* <code>
|
||||
* Image::factory('original.png')->grayscale()->save('edited.png');
|
||||
* </code>
|
||||
*
|
||||
* @return Image
|
||||
*/
|
||||
public function grayscale()
|
||||
{
|
||||
imagefilter($this->image, IMG_FILTER_GRAYSCALE);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert image into sepia
|
||||
*
|
||||
* <code>
|
||||
* Image::factory('original.png')->sepia()->save('edited.png');
|
||||
* </code>
|
||||
*
|
||||
* @return Image
|
||||
*/
|
||||
public function sepia()
|
||||
{
|
||||
imagefilter($this->image, IMG_FILTER_GRAYSCALE);
|
||||
imagefilter($this->image, IMG_FILTER_COLORIZE, 112, 66, 20);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert image into brightness
|
||||
*
|
||||
* <code>
|
||||
* Image::factory('original.png')->brightness(60)->save('edited.png');
|
||||
* </code>
|
||||
*
|
||||
* @param integer $level Level. From -255(min) to 255(max)
|
||||
* @return Image
|
||||
*/
|
||||
public function brightness($level = 0)
|
||||
{
|
||||
imagefilter($this->image, IMG_FILTER_BRIGHTNESS, (int) $level);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert image into colorize
|
||||
*
|
||||
* <code>
|
||||
* Image::factory('original.png')->colorize(60, 0, 0)->save('edited.png');
|
||||
* </code>
|
||||
*
|
||||
* @param integer $red Red
|
||||
* @param integer $green Green
|
||||
* @param integer $blue Blue
|
||||
* @return Image
|
||||
*/
|
||||
public function colorize($red, $green, $blue)
|
||||
{
|
||||
imagefilter($this->image, IMG_FILTER_COLORIZE, (int) $red, (int) $green, (int) $blue);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert image into contrast
|
||||
*
|
||||
* <code>
|
||||
* Image::factory('original.png')->contrast(60)->save('edited.png');
|
||||
* </code>
|
||||
*
|
||||
* @param integer $level Level. From -100(max) to 100(min) note the direction!
|
||||
* @return Image
|
||||
*/
|
||||
public function contrast($level)
|
||||
{
|
||||
imagefilter($this->image, IMG_FILTER_CONTRAST, (int) $level);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a color based on a hex value.
|
||||
*
|
||||
* @param string $hex Hex code of the color
|
||||
* @param integer $alpha Alpha. Default is 100
|
||||
* @param boolean $returnRGB FALSE returns a color identifier, TRUE returns a RGB array
|
||||
* @return integer
|
||||
*/
|
||||
protected function createColor($hex, $alpha = 100, $return_rgb = false)
|
||||
{
|
||||
// Redefine vars
|
||||
$hex = (string) $hex;
|
||||
$alpha = (int) $alpha;
|
||||
$return_rgb = (bool) $return_rgb;
|
||||
|
||||
$hex = str_replace('#', '', $hex);
|
||||
|
||||
if (preg_match('/^([a-f0-9]{3}){1,2}$/i', $hex) === 0) {
|
||||
throw new RuntimeException(vsprintf("%s(): Invalid color code ('%s').", array(__METHOD__, $hex)));
|
||||
}
|
||||
|
||||
if (strlen($hex) === 3) {
|
||||
|
||||
$r = hexdec(str_repeat(substr($hex, 0, 1), 2));
|
||||
$g = hexdec(str_repeat(substr($hex, 1, 1), 2));
|
||||
$b = hexdec(str_repeat(substr($hex, 2, 1), 2));
|
||||
|
||||
} else {
|
||||
|
||||
$r = hexdec(substr($hex, 0, 2));
|
||||
$g = hexdec(substr($hex, 2, 2));
|
||||
$b = hexdec(substr($hex, 4, 2));
|
||||
|
||||
}
|
||||
|
||||
if ($return_rgb === true) {
|
||||
return array('r' => $r, 'g' => $g, 'b' => $b);
|
||||
|
||||
} else {
|
||||
|
||||
// Convert alpha to 0-127
|
||||
$alpha = min(round(abs(($alpha * 127 / 100) - 127)), 127);
|
||||
|
||||
return imagecolorallocatealpha($this->image, $r, $g, $b, $alpha);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotates the image using the given angle in degrees.
|
||||
*
|
||||
* <code>
|
||||
* Image::factory('original.png')->rotate(90)->save('edited.png');
|
||||
* </code>
|
||||
*
|
||||
* @param integer $degrees Degrees to rotate the image
|
||||
* @return Image
|
||||
*/
|
||||
public function rotate($degrees)
|
||||
{
|
||||
if (GD_BUNDLED === 0) {
|
||||
throw new RuntimeException(vsprintf("%s(): This method requires the 'imagerotate' function which is only available in the bundled version of GD.", array(__METHOD__)));
|
||||
}
|
||||
|
||||
// Redefine vars
|
||||
$degrees = (int) $degrees;
|
||||
|
||||
// Get image width and height
|
||||
$width = imagesx($this->image);
|
||||
$height = imagesy($this->image);
|
||||
|
||||
// Allocate a color for an image
|
||||
$transparent = imagecolorallocatealpha($this->image, 0, 0, 0, 127);
|
||||
|
||||
// Rotate gif image
|
||||
if ($this->image_info['type'] === IMAGETYPE_GIF) {
|
||||
|
||||
// Create a new true color image
|
||||
$temp = imagecreatetruecolor($width, $height);
|
||||
|
||||
// Flood fill
|
||||
imagefill($temp, 0, 0, $transparent);
|
||||
|
||||
// Copy part of an image
|
||||
imagecopy($temp, $this->image, 0, 0, 0, 0, $width, $height);
|
||||
|
||||
// Destroy an image
|
||||
imagedestroy($this->image);
|
||||
|
||||
// Save temp image
|
||||
$this->image = $temp;
|
||||
}
|
||||
|
||||
// Rotate an image with a given angle
|
||||
$this->image = imagerotate($this->image, (360 - $degrees), $transparent);
|
||||
|
||||
// Define a color as transparent
|
||||
imagecolortransparent($this->image, $transparent);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a border to the image.
|
||||
*
|
||||
* <code>
|
||||
* Image::factory('original.png')->border('#000', 5)->save('edited.png');
|
||||
* </code>
|
||||
*
|
||||
* @param string $color Hex code for the color
|
||||
* @param integer $thickness Thickness of the frame in pixels
|
||||
* @return Image
|
||||
*/
|
||||
public function border($color = '#000', $thickness = 5)
|
||||
{
|
||||
// Redefine vars
|
||||
$color = (string) $color;
|
||||
$thickness = (int) $thickness;
|
||||
|
||||
// Get image width and height
|
||||
$width = imagesx($this->image);
|
||||
$height = imagesy($this->image);
|
||||
|
||||
// Creates a color based on a hex value
|
||||
$color = $this->createColor($color);
|
||||
|
||||
// Create border
|
||||
for ($i = 0; $i < $thickness; $i++) {
|
||||
|
||||
if ($i < 0) {
|
||||
|
||||
$x = $width + 1;
|
||||
$y = $hidth + 1;
|
||||
|
||||
} else {
|
||||
|
||||
$x = --$width;
|
||||
$y = --$height;
|
||||
|
||||
}
|
||||
|
||||
imagerectangle($this->image, $i, $i, $x, $y, $color);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save image
|
||||
*
|
||||
* <code>
|
||||
* Image::factory('original.png')->save('edited.png');
|
||||
* </code>
|
||||
*
|
||||
* @param string $dest Desitination location of the file
|
||||
* @param integer $quality Image quality. Default is 100
|
||||
* @return Image
|
||||
*/
|
||||
public function save($file, $quality = 100)
|
||||
{
|
||||
// Redefine vars
|
||||
$file = (string) $file;
|
||||
$quality = (int) $quality;
|
||||
|
||||
$path_info = pathinfo($file);
|
||||
|
||||
if ( ! is_writable($path_info['dirname'])) {
|
||||
throw new RuntimeException(vsprintf("%s(): '%s' is not writable.", array(__METHOD__, $path_info['dirname'])));
|
||||
}
|
||||
|
||||
// Make sure that quality is between 0 and 100
|
||||
$quality = max(min((int) $quality, 100), 0);
|
||||
|
||||
// Save image
|
||||
switch ($path_info['extension']) {
|
||||
case 'jpg':
|
||||
case 'jpeg':
|
||||
imagejpeg($this->image, $file, $quality);
|
||||
break;
|
||||
case 'gif':
|
||||
imagegif($this->image, $file);
|
||||
break;
|
||||
case 'png':
|
||||
imagealphablending($this->image, true);
|
||||
imagesavealpha($this->image, true);
|
||||
imagepng($this->image, $file, (9 - (round(($quality / 100) * 9))));
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(vsprintf("%s(): Unable to save to '%s'. Unsupported image format.", array(__METHOD__, $path_info['extension'])));
|
||||
}
|
||||
|
||||
// Return Image
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
imagedestroy($this->image);
|
||||
}
|
||||
|
||||
}
|
224
libraries/monstra/Inflector.php
Normal file
224
libraries/monstra/Inflector.php
Normal file
@@ -0,0 +1,224 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Monstra Library
|
||||
*
|
||||
* This source file is part of the Monstra Library. More information,
|
||||
* documentation and tutorials can be found at http://library.monstra.org
|
||||
*
|
||||
* @package Monstra
|
||||
*
|
||||
* @author Romanenko Sergey / Awilum
|
||||
* @copyright (c) 2012 - 2013 Romanenko Sergey / Awilum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
class Inflector
|
||||
{
|
||||
/**
|
||||
* Plural rules
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $plural_rules = array(
|
||||
'/^(ox)$/' => '\1\2en', // ox
|
||||
'/([m|l])ouse$/' => '\1ice', // mouse, louse
|
||||
'/(matr|vert|ind)ix|ex$/' => '\1ices', // matrix, vertex, index
|
||||
'/(x|ch|ss|sh)$/' => '\1es', // search, switch, fix, box, process, address
|
||||
'/([^aeiouy]|qu)y$/' => '\1ies', // query, ability, agency
|
||||
'/(hive)$/' => '\1s', // archive, hive
|
||||
'/(?:([^f])fe|([lr])f)$/' => '\1\2ves', // half, safe, wife
|
||||
'/sis$/' => 'ses', // basis, diagnosis
|
||||
'/([ti])um$/' => '\1a', // datum, medium
|
||||
'/(p)erson$/' => '\1eople', // person, salesperson
|
||||
'/(m)an$/' => '\1en', // man, woman, spokesman
|
||||
'/(c)hild$/' => '\1hildren', // child
|
||||
'/(buffal|tomat)o$/' => '\1\2oes', // buffalo, tomato
|
||||
'/(bu|campu)s$/' => '\1\2ses', // bus, campus
|
||||
'/(alias|status|virus)$/' => '\1es', // alias
|
||||
'/(octop)us$/' => '\1i', // octopus
|
||||
'/(ax|cris|test)is$/' => '\1es', // axis, crisis
|
||||
'/s$/' => 's', // no change (compatibility)
|
||||
'/$/' => 's',
|
||||
);
|
||||
|
||||
/**
|
||||
* Singular rules
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $singular_rules = array(
|
||||
'/(matr)ices$/' => '\1ix',
|
||||
'/(vert|ind)ices$/' => '\1ex',
|
||||
'/^(ox)en/' => '\1',
|
||||
'/(alias)es$/' => '\1',
|
||||
'/([octop|vir])i$/' => '\1us',
|
||||
'/(cris|ax|test)es$/' => '\1is',
|
||||
'/(shoe)s$/' => '\1',
|
||||
'/(o)es$/' => '\1',
|
||||
'/(bus|campus)es$/' => '\1',
|
||||
'/([m|l])ice$/' => '\1ouse',
|
||||
'/(x|ch|ss|sh)es$/' => '\1',
|
||||
'/(m)ovies$/' => '\1\2ovie',
|
||||
'/(s)eries$/' => '\1\2eries',
|
||||
'/([^aeiouy]|qu)ies$/' => '\1y',
|
||||
'/([lr])ves$/' => '\1f',
|
||||
'/(tive)s$/' => '\1',
|
||||
'/(hive)s$/' => '\1',
|
||||
'/([^f])ves$/' => '\1fe',
|
||||
'/(^analy)ses$/' => '\1sis',
|
||||
'/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/' => '\1\2sis',
|
||||
'/([ti])a$/' => '\1um',
|
||||
'/(p)eople$/' => '\1\2erson',
|
||||
'/(m)en$/' => '\1an',
|
||||
'/(s)tatuses$/' => '\1\2tatus',
|
||||
'/(c)hildren$/' => '\1\2hild',
|
||||
'/(n)ews$/' => '\1\2ews',
|
||||
'/([^us])s$/' => '\1',
|
||||
);
|
||||
|
||||
/**
|
||||
* Protected constructor since this is a static class.
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
// Nothing here
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a camelized string from a string using underscore syntax.
|
||||
*
|
||||
* <code>
|
||||
* // "some_text_here" becomes "SomeTextHere"
|
||||
* echo Inflector::camelize('some_text_here');
|
||||
* </code>
|
||||
*
|
||||
* @param string $string Word to camelize.
|
||||
* @return string Camelized word.
|
||||
*/
|
||||
public static function camelize($string)
|
||||
{
|
||||
// Redefine vars
|
||||
$string = (string) $string;
|
||||
|
||||
return str_replace(' ', '', ucwords(str_replace('_', ' ', $string)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string using underscore syntax from a camelized string.
|
||||
*
|
||||
* <code>
|
||||
* // "SomeTextHere" becomes "some_text_here"
|
||||
* echo Inflector::underscore('SomeTextHere');
|
||||
* </code>
|
||||
*
|
||||
* @param string $string CamelCased word
|
||||
* @return string Underscored version of the $string
|
||||
*/
|
||||
public static function underscore($string)
|
||||
{
|
||||
// Redefine vars
|
||||
$string = (string) $string;
|
||||
|
||||
return strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $string));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a humanized string from a string using underscore syntax.
|
||||
*
|
||||
* <code>
|
||||
* // "some_text_here" becomes "Some text here"
|
||||
* echo Inflector::humanize('some_text_here');
|
||||
* </code>
|
||||
*
|
||||
* @param string $string String using underscore syntax.
|
||||
* @return string Humanized version of the $string
|
||||
*/
|
||||
public static function humanize($string)
|
||||
{
|
||||
// Redefine vars
|
||||
$string = (string) $string;
|
||||
|
||||
return ucfirst(strtolower(str_replace('_', ' ', $string)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns ordinalize number.
|
||||
*
|
||||
* <code>
|
||||
* // 1 becomes 1st
|
||||
* echo Inflector::ordinalize(1);
|
||||
* </code>
|
||||
*
|
||||
* @param integer $number Number to ordinalize
|
||||
* @return string
|
||||
*/
|
||||
public static function ordinalize($number)
|
||||
{
|
||||
if ( ! is_numeric($number)) {
|
||||
return $number;
|
||||
}
|
||||
|
||||
if (in_array(($number % 100), range(11, 13))) {
|
||||
return $number . 'th';
|
||||
} else {
|
||||
switch ($number % 10) {
|
||||
case 1: return $number . 'st'; break;
|
||||
case 2: return $number . 'nd'; break;
|
||||
case 3: return $number . 'rd'; break;
|
||||
default: return $number . 'th'; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the plural version of the given word
|
||||
*
|
||||
* <code>
|
||||
* echo Inflector::pluralize('cat');
|
||||
* </code>
|
||||
*
|
||||
* @param string $word Word to pluralize
|
||||
* @return string
|
||||
*/
|
||||
public static function pluralize($word)
|
||||
{
|
||||
$result = (string) $word;
|
||||
|
||||
foreach (Inflector::$plural_rules as $rule => $replacement) {
|
||||
if (preg_match($rule, $result)) {
|
||||
$result = preg_replace($rule, $replacement, $result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the singular version of the given word
|
||||
*
|
||||
* <code>
|
||||
* echo Inflector::singularize('cats');
|
||||
* </code>
|
||||
*
|
||||
* @param string $word Word to singularize
|
||||
* @return string
|
||||
*/
|
||||
public static function singularize($word)
|
||||
{
|
||||
$result = (string) $word;
|
||||
|
||||
foreach (Inflector::$singular_rules as $rule => $replacement) {
|
||||
if (preg_match($rule, $result)) {
|
||||
$result = preg_replace($rule, $replacement, $result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
91
libraries/monstra/Minify.php
Normal file
91
libraries/monstra/Minify.php
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Monstra Library
|
||||
*
|
||||
* This source file is part of the Monstra Library. More information,
|
||||
* documentation and tutorials can be found at http://library.monstra.org
|
||||
*
|
||||
* @package Monstra
|
||||
*
|
||||
* @author Romanenko Sergey / Awilum
|
||||
* @copyright (c) 2012 - 2013 Romanenko Sergey / Awilum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
class Minify
|
||||
{
|
||||
/**
|
||||
* Protected constructor since this is a static class.
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
// Nothing here
|
||||
}
|
||||
|
||||
/**
|
||||
* Minify html
|
||||
*
|
||||
* <code>
|
||||
* echo Minify::html($buffer);
|
||||
* </code>
|
||||
*
|
||||
* @param string $buffer html
|
||||
* @return string
|
||||
*/
|
||||
public static function html($buffer)
|
||||
{
|
||||
return preg_replace('/^\\s+|\\s+$/m', '', $buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Minify css
|
||||
*
|
||||
* <code>
|
||||
* echo Minify::css($buffer);
|
||||
* </code>
|
||||
*
|
||||
* @param string $buffer css
|
||||
* @return string
|
||||
*/
|
||||
public static function css($buffer)
|
||||
{
|
||||
// Remove comments
|
||||
$buffer = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $buffer);
|
||||
|
||||
// Remove tabs, spaces, newlines, etc.
|
||||
$buffer = str_replace(array("\r\n", "\r", "\n", "\t", ' ', ' ', ' '), '', $buffer);
|
||||
|
||||
// Preserve empty comment after '>' http://www.webdevout.net/css-hacks#in_css-selectors
|
||||
$buffer = preg_replace('@>/\\*\\s*\\*/@', '>/*keep*/', $buffer);
|
||||
|
||||
// Preserve empty comment between property and value
|
||||
// http://css-discuss.incutio.com/?page=BoxModelHack
|
||||
$buffer = preg_replace('@/\\*\\s*\\*/\\s*:@', '/*keep*/:', $buffer);
|
||||
$buffer = preg_replace('@:\\s*/\\*\\s*\\*/@', ':/*keep*/', $buffer);
|
||||
|
||||
// Remove ws around { } and last semicolon in declaration block
|
||||
$buffer = preg_replace('/\\s*{\\s*/', '{', $buffer);
|
||||
$buffer = preg_replace('/;?\\s*}\\s*/', '}', $buffer);
|
||||
|
||||
// Remove ws surrounding semicolons
|
||||
$buffer = preg_replace('/\\s*;\\s*/', ';', $buffer);
|
||||
|
||||
// Remove ws around urls
|
||||
$buffer = preg_replace('/url\\(\\s*([^\\)]+?)\\s*\\)/x', 'url($1)', $buffer);
|
||||
|
||||
// Remove ws between rules and colons
|
||||
$buffer = preg_replace('/\\s*([{;])\\s*([\\*_]?[\\w\\-]+)\\s*:\\s*(\\b|[#\'"])/x', '$1$2:$3', $buffer);
|
||||
|
||||
// Minimize hex colors
|
||||
$buffer = preg_replace('/([^=])#([a-f\\d])\\2([a-f\\d])\\3([a-f\\d])\\4([\\s;\\}])/i', '$1#$2$3$4$5', $buffer);
|
||||
|
||||
// Replace any ws involving newlines with a single newline
|
||||
$buffer = preg_replace('/[ \\t]*\\n+\\s*/', "\n", $buffer);
|
||||
|
||||
return $buffer;
|
||||
}
|
||||
|
||||
}
|
117
libraries/monstra/Monstra.php
Normal file
117
libraries/monstra/Monstra.php
Normal file
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Monstra Library
|
||||
*
|
||||
* This source file is part of the Monstra Library. More information,
|
||||
* documentation and tutorials can be found at http://library.monstra.org
|
||||
*
|
||||
* @package Monstra
|
||||
*
|
||||
* @author Romanenko Sergey / Awilum
|
||||
* @copyright (c) 2012 - 2013 Romanenko Sergey / Awilum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* Version number for the current version of the Monstra Library.
|
||||
*/
|
||||
define('MONSTRA_LIBRARY_VERSION', '1.0.0');
|
||||
|
||||
/*
|
||||
* Should we use the Monstra Autoloader to ensure the dependancies are automatically
|
||||
* loaded?
|
||||
*/
|
||||
if ( ! defined('MONSTRA_LIBRARY_AUTOLOADER')) {
|
||||
define('MONSTRA_LIBRARY_AUTOLOADER', true);
|
||||
}
|
||||
|
||||
// Register autoload function
|
||||
if (MONSTRA_LIBRARY_AUTOLOADER) {
|
||||
spl_autoload_register(array('Monstra', 'autoload'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Monstra
|
||||
*/
|
||||
class Monstra
|
||||
{
|
||||
|
||||
/**
|
||||
* Registry of variables
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $registry = array();
|
||||
|
||||
|
||||
/**
|
||||
* Autload
|
||||
*/
|
||||
public static function autoload($className)
|
||||
{
|
||||
$path = dirname(realpath(__FILE__));
|
||||
|
||||
$className = ltrim($className, '\\');
|
||||
$fileName = '';
|
||||
$namespace = '';
|
||||
if ($lastNsPos = strrpos($className, '\\')) {
|
||||
$namespace = substr($className, 0, $lastNsPos);
|
||||
$className = substr($className, $lastNsPos + 1);
|
||||
$fileName = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
|
||||
}
|
||||
$fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
|
||||
|
||||
require $path.DIRECTORY_SEPARATOR.$fileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an object with this name is in the registry.
|
||||
*
|
||||
* @return bool
|
||||
* @param string $name The name of the registry item to check for existence.
|
||||
*/
|
||||
public static function exists($name)
|
||||
{
|
||||
return isset(self::$registry[(string) $name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a given value under a given name.
|
||||
*
|
||||
* @param string $name The name of the value to store.
|
||||
* @param mixed[optional] $value The value that needs to be stored.
|
||||
*/
|
||||
public static function set($name, $value = null)
|
||||
{
|
||||
// redefine name
|
||||
$name = (string) $name;
|
||||
|
||||
// delete item
|
||||
if ($value === null) {
|
||||
unset(self::$registry[$name]);
|
||||
} else {
|
||||
self::$registry[$name] = $value;
|
||||
|
||||
return self::get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch an item from the registry.
|
||||
*
|
||||
* @return mixed
|
||||
* @param string $name The name of the item to fetch.
|
||||
*/
|
||||
public static function get($name)
|
||||
{
|
||||
$name = (string) $name;
|
||||
|
||||
if (!isset(self::$registry[$name])) {
|
||||
throw new SpoonException('No item "' . $name . '" exists in the registry.');
|
||||
}
|
||||
|
||||
return self::$registry[$name];
|
||||
}
|
||||
|
||||
}
|
138
libraries/monstra/Notification.php
Normal file
138
libraries/monstra/Notification.php
Normal file
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Monstra Library
|
||||
*
|
||||
* This source file is part of the Monstra Library. More information,
|
||||
* documentation and tutorials can be found at http://library.monstra.org
|
||||
*
|
||||
* @package Monstra
|
||||
*
|
||||
* @author Romanenko Sergey / Awilum
|
||||
* @copyright (c) 2012 - 2013 Romanenko Sergey / Awilum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
class Notification
|
||||
{
|
||||
/**
|
||||
* Notifications session key
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const SESSION_KEY = 'notifications';
|
||||
|
||||
/**
|
||||
* Notifications array
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $notifications = array();
|
||||
|
||||
/**
|
||||
* Protected constructor since this is a static class.
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
// Nothing here
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a specific variable from the Notifications array.
|
||||
*
|
||||
* <code>
|
||||
* echo Notification::get('success');
|
||||
* echo Notification::get('errors');
|
||||
* </code>
|
||||
*
|
||||
* @param string $key Variable name
|
||||
* @return mixed
|
||||
*/
|
||||
public static function get($key)
|
||||
{
|
||||
// Redefine arguments
|
||||
$key = (string) $key;
|
||||
|
||||
// Return specific variable from the Notifications array
|
||||
return isset(Notification::$notifications[$key]) ? Notification::$notifications[$key] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds specific variable to the Notifications array.
|
||||
*
|
||||
* <code>
|
||||
* Notification::set('success', 'Data has been saved with success!');
|
||||
* Notification::set('errors', 'Data not saved!');
|
||||
* </code>
|
||||
*
|
||||
* @param string $key Variable name
|
||||
* @param mixed $value Variable value
|
||||
*/
|
||||
public static function set($key, $value)
|
||||
{
|
||||
// Redefine arguments
|
||||
$key = (string) $key;
|
||||
|
||||
// Save specific variable to the Notifications array
|
||||
$_SESSION[Notification::SESSION_KEY][$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds specific variable to the Notifications array for current page.
|
||||
*
|
||||
* <code>
|
||||
* Notification::setNow('success', 'Success!');
|
||||
* </code>
|
||||
*
|
||||
* @param string $var Variable name
|
||||
* @param mixed $value Variable value
|
||||
*/
|
||||
public static function setNow($key, $value)
|
||||
{
|
||||
// Redefine arguments
|
||||
$key = (string) $key;
|
||||
|
||||
// Save specific variable for current page only
|
||||
Notification::$notifications[$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the Notifications array.
|
||||
*
|
||||
* <code>
|
||||
* Notification::clean();
|
||||
* </code>
|
||||
*
|
||||
* Data that previous pages stored will not be deleted, just the data that
|
||||
* this page stored itself.
|
||||
*/
|
||||
public static function clean()
|
||||
{
|
||||
$_SESSION[Notification::SESSION_KEY] = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the Notification service.
|
||||
*
|
||||
* <code>
|
||||
* Notification::init();
|
||||
* </code>
|
||||
*
|
||||
* This will read notification/flash data from the $_SESSION variable and load it into
|
||||
* the $this->previous array.
|
||||
*/
|
||||
public static function init()
|
||||
{
|
||||
// Get notification/flash data...
|
||||
|
||||
if ( ! empty($_SESSION[Notification::SESSION_KEY]) && is_array($_SESSION[Notification::SESSION_KEY])) {
|
||||
Notification::$notifications = $_SESSION[Notification::SESSION_KEY];
|
||||
}
|
||||
|
||||
$_SESSION[Notification::SESSION_KEY] = array();
|
||||
|
||||
}
|
||||
|
||||
}
|
203
libraries/monstra/Number.php
Normal file
203
libraries/monstra/Number.php
Normal file
@@ -0,0 +1,203 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Monstra Library
|
||||
*
|
||||
* This source file is part of the Monstra Library. More information,
|
||||
* documentation and tutorials can be found at http://library.monstra.org
|
||||
*
|
||||
* @package Monstra
|
||||
*
|
||||
* @author Romanenko Sergey / Awilum
|
||||
* @copyright (c) 2012 - 2013 Romanenko Sergey / Awilum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
class Number
|
||||
{
|
||||
/**
|
||||
* Protected constructor since this is a static class.
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
// Nothing here
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert bytes in 'kb','mb','gb','tb','pb'
|
||||
*
|
||||
* <code>
|
||||
* echo Number::byteFormat(10000);
|
||||
* </code>
|
||||
*
|
||||
* @param integer $size Data to convert
|
||||
* @return string
|
||||
*/
|
||||
public static function byteFormat($size)
|
||||
{
|
||||
// Redefine vars
|
||||
$size = (int) $size;
|
||||
|
||||
$unit = array('b', 'kb', 'mb', 'gb', 'tb', 'pb');
|
||||
|
||||
return @round($size/pow(1024, ($i=floor(log($size, 1024)))), 2).' '.$unit[$i];
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a number into a more readable human-type number.
|
||||
*
|
||||
* <code>
|
||||
* echo Number::quantity(7000); // 7K
|
||||
* echo Number::quantity(7500); // 8K
|
||||
* echo Number::quantity(7500, 1); // 7.5K
|
||||
* </code>
|
||||
*
|
||||
* @param integer $num Num to convert
|
||||
* @param integer $decimals Decimals
|
||||
* @return string
|
||||
*/
|
||||
public static function quantity($num, $decimals = 0)
|
||||
{
|
||||
// Redefine vars
|
||||
$num = (int) $num;
|
||||
$decimals = (int) $decimals;
|
||||
|
||||
if ($num >= 1000 && $num < 1000000) {
|
||||
return sprintf('%01.'.$decimals.'f', (sprintf('%01.0f', $num) / 1000)).'K';
|
||||
} elseif ($num >= 1000000 && $num < 1000000000) {
|
||||
return sprintf('%01.'.$decimals.'f', (sprintf('%01.0f', $num) / 1000000)).'M';
|
||||
} elseif ($num >= 1000000000) {
|
||||
return sprintf('%01.'.$decimals.'f', (sprintf('%01.0f', $num) / 1000000000)).'B';
|
||||
}
|
||||
|
||||
return $num;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the value is between the minimum and maximum (min & max included).
|
||||
*
|
||||
* <code>
|
||||
* if (Number::between(2, 10, 5)) {
|
||||
* // do something...
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @param float $minimum The minimum.
|
||||
* @param float $maximum The maximum.
|
||||
* @param float $value The value to validate.
|
||||
* @return boolean
|
||||
*/
|
||||
public static function between($minimum, $maximum, $value)
|
||||
{
|
||||
return ((float) $value >= (float) $minimum && (float) $value <= (float) $maximum);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the value for an even number.
|
||||
*
|
||||
* <code>
|
||||
* if (Number::even(2)) {
|
||||
* // do something...
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @param integer $value The value to validate.
|
||||
* @return boolean
|
||||
*/
|
||||
public static function even($value)
|
||||
{
|
||||
return (((int) $value % 2) == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the value is greather than a given minimum.
|
||||
*
|
||||
* <code>
|
||||
* if (Number::greaterThan(2, 10)) {
|
||||
* // do something...
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @param float $minimum The minimum as a float.
|
||||
* @param float $value The value to validate.
|
||||
* @return boolean
|
||||
*/
|
||||
public static function greaterThan($minimum, $value)
|
||||
{
|
||||
return ((float) $value > (float) $minimum);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the value is smaller than a given maximum.
|
||||
*
|
||||
* <code>
|
||||
* if (Number::smallerThan(2, 10)) {
|
||||
* // do something...
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @param integer $maximum The maximum.
|
||||
* @param integer $value The value to validate.
|
||||
* @return boolean
|
||||
*/
|
||||
public static function smallerThan($maximum, $value)
|
||||
{
|
||||
return ((int) $value < (int) $maximum);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the value is not greater than or equal a given maximum.
|
||||
*
|
||||
* <code>
|
||||
* if (Number::maximum(2, 10)) {
|
||||
* // do something...
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @param integer $maximum The maximum.
|
||||
* @param integer $value The value to validate.
|
||||
* @return boolean
|
||||
*/
|
||||
public static function maximum($maximum, $value)
|
||||
{
|
||||
return ((int) $value <= (int) $maximum);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the value is greater than or equal to a given minimum.
|
||||
*
|
||||
* <code>
|
||||
* if (Number::minimum(2, 10)) {
|
||||
* // do something...
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @param integer $minimum The minimum.
|
||||
* @param integer $value The value to validate.
|
||||
* @return boolean
|
||||
*/
|
||||
public static function minimum($minimum, $value)
|
||||
{
|
||||
return ((int) $value >= (int) $minimum);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the value for an odd number.
|
||||
*
|
||||
* <code>
|
||||
* if (Number::odd(2)) {
|
||||
* // do something...
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @param integer $value The value to validate.
|
||||
* @return boolean
|
||||
*/
|
||||
public static function odd($value)
|
||||
{
|
||||
return ! Number::even((int) $value);
|
||||
}
|
||||
|
||||
}
|
1266
libraries/monstra/Orm.php
Normal file
1266
libraries/monstra/Orm.php
Normal file
File diff suppressed because it is too large
Load Diff
153
libraries/monstra/Request.php
Normal file
153
libraries/monstra/Request.php
Normal file
@@ -0,0 +1,153 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Monstra Library
|
||||
*
|
||||
* This source file is part of the Monstra Library. More information,
|
||||
* documentation and tutorials can be found at http://library.monstra.org
|
||||
*
|
||||
* @package Monstra
|
||||
*
|
||||
* @author Romanenko Sergey / Awilum
|
||||
* @copyright (c) 2012 - 2013 Romanenko Sergey / Awilum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
class Request
|
||||
{
|
||||
/**
|
||||
* Protected constructor since this is a static class.
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
// Nothing here
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirects the browser to a page specified by the $url argument.
|
||||
*
|
||||
* <code>
|
||||
* Request::redirect('test');
|
||||
* </code>
|
||||
*
|
||||
* @param string $url The URL
|
||||
* @param integer $status Status
|
||||
* @param integer $delay Delay
|
||||
*/
|
||||
public static function redirect($url, $status = 302, $delay = null)
|
||||
{
|
||||
// Redefine vars
|
||||
$url = (string) $url;
|
||||
$status = (int) $status;
|
||||
|
||||
// Status codes
|
||||
$messages = array();
|
||||
$messages[301] = '301 Moved Permanently';
|
||||
$messages[302] = '302 Found';
|
||||
|
||||
// Is Headers sent ?
|
||||
if (headers_sent()) {
|
||||
|
||||
echo "<script>document.location.href='" . $url . "';</script>\n";
|
||||
|
||||
} else {
|
||||
|
||||
// Redirect headers
|
||||
Request::setHeaders('HTTP/1.1 ' . $status . ' ' . Arr::get($messages, $status, 302));
|
||||
|
||||
// Delay execution
|
||||
if ($delay !== null) sleep((int) $delay);
|
||||
|
||||
// Redirect
|
||||
Request::setHeaders("Location: $url");
|
||||
|
||||
// Shutdown request
|
||||
Request::shutdown();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set one or multiple headers.
|
||||
*
|
||||
* <code>
|
||||
* Request::setHeaders('Location: http://site.com/');
|
||||
* </code>
|
||||
*
|
||||
* @param mixed $headers String or array with headers to send.
|
||||
*/
|
||||
public static function setHeaders($headers)
|
||||
{
|
||||
// Loop elements
|
||||
foreach ((array) $headers as $header) {
|
||||
|
||||
// Set header
|
||||
header((string) $header);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get
|
||||
*
|
||||
* <code>
|
||||
* $action = Request::get('action');
|
||||
* </code>
|
||||
*
|
||||
* @param string $key Key
|
||||
* @param mixed
|
||||
*/
|
||||
public static function get($key)
|
||||
{
|
||||
return Arr::get($_GET, $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Post
|
||||
*
|
||||
* <code>
|
||||
* $login = Request::post('login');
|
||||
* </code>
|
||||
*
|
||||
* @param string $key Key
|
||||
* @param mixed
|
||||
*/
|
||||
public static function post($key)
|
||||
{
|
||||
return Arr::get($_POST, $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this is an ajax request or not
|
||||
*
|
||||
* <code>
|
||||
* if (Request::isAjax()) {
|
||||
* // do something...
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isAjax()
|
||||
{
|
||||
return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest';
|
||||
}
|
||||
|
||||
/**
|
||||
* Terminate request
|
||||
*
|
||||
* <code>
|
||||
* Request::shutdown();
|
||||
* </code>
|
||||
*
|
||||
*/
|
||||
public static function shutdown()
|
||||
{
|
||||
exit(0);
|
||||
}
|
||||
|
||||
}
|
101
libraries/monstra/Response.php
Normal file
101
libraries/monstra/Response.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Monstra Library
|
||||
*
|
||||
* This source file is part of the Monstra Library. More information,
|
||||
* documentation and tutorials can be found at http://library.monstra.org
|
||||
*
|
||||
* @package Monstra
|
||||
*
|
||||
* @author Romanenko Sergey / Awilum
|
||||
* @copyright (c) 2012 - 2013 Romanenko Sergey / Awilum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
class Response
|
||||
{
|
||||
/**
|
||||
* HTTP status codes and messages
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $messages = array(
|
||||
// Informational 1xx
|
||||
100 => 'Continue',
|
||||
101 => 'Switching Protocols',
|
||||
|
||||
// Success 2xx
|
||||
200 => 'OK',
|
||||
201 => 'Created',
|
||||
202 => 'Accepted',
|
||||
203 => 'Non-Authoritative Information',
|
||||
204 => 'No Content',
|
||||
205 => 'Reset Content',
|
||||
206 => 'Partial Content',
|
||||
|
||||
// Redirection 3xx
|
||||
300 => 'Multiple Choices',
|
||||
301 => 'Moved Permanently',
|
||||
302 => 'Found', // 1.1
|
||||
303 => 'See Other',
|
||||
304 => 'Not Modified',
|
||||
305 => 'Use Proxy',
|
||||
// 306 is deprecated but reserved
|
||||
307 => 'Temporary Redirect',
|
||||
|
||||
// Client Error 4xx
|
||||
400 => 'Bad Request',
|
||||
401 => 'Unauthorized',
|
||||
402 => 'Payment Required',
|
||||
403 => 'Forbidden',
|
||||
404 => 'Not Found',
|
||||
405 => 'Method Not Allowed',
|
||||
406 => 'Not Acceptable',
|
||||
407 => 'Proxy Authentication Required',
|
||||
408 => 'Request Timeout',
|
||||
409 => 'Conflict',
|
||||
410 => 'Gone',
|
||||
411 => 'Length Required',
|
||||
412 => 'Precondition Failed',
|
||||
413 => 'Request Entity Too Large',
|
||||
414 => 'Request-URI Too Long',
|
||||
415 => 'Unsupported Media Type',
|
||||
416 => 'Requested Range Not Satisfiable',
|
||||
417 => 'Expectation Failed',
|
||||
|
||||
// Server Error 5xx
|
||||
500 => 'Internal Server Error',
|
||||
501 => 'Not Implemented',
|
||||
502 => 'Bad Gateway',
|
||||
503 => 'Service Unavailable',
|
||||
504 => 'Gateway Timeout',
|
||||
505 => 'HTTP Version Not Supported',
|
||||
509 => 'Bandwidth Limit Exceeded'
|
||||
);
|
||||
|
||||
/**
|
||||
* Protected constructor since this is a static class.
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
// Nothing here
|
||||
}
|
||||
|
||||
/**
|
||||
* Set header status
|
||||
*
|
||||
* <code>
|
||||
* Response::status(404);
|
||||
* </code>
|
||||
*
|
||||
* @param integer $status Status code
|
||||
*/
|
||||
public static function status($status)
|
||||
{
|
||||
if (array_key_exists($status, Response::$messages)) header('HTTP/1.1 ' . $status . ' ' . Response::$messages[$status]);
|
||||
}
|
||||
|
||||
}
|
237
libraries/monstra/Security.php
Normal file
237
libraries/monstra/Security.php
Normal file
@@ -0,0 +1,237 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Monstra Library
|
||||
*
|
||||
* This source file is part of the Monstra Library. More information,
|
||||
* documentation and tutorials can be found at http://library.monstra.org
|
||||
*
|
||||
* @package Monstra
|
||||
*
|
||||
* @author Romanenko Sergey / Awilum
|
||||
* @copyright (c) 2012 - 2013 Romanenko Sergey / Awilum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
class Security
|
||||
{
|
||||
/**
|
||||
* Key name for token storage
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $token_name = 'security_token';
|
||||
|
||||
/**
|
||||
* Protected constructor since this is a static class.
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
// Nothing here
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate and store a unique token which can be used to help prevent
|
||||
* [CSRF](http://wikipedia.org/wiki/Cross_Site_Request_Forgery) attacks.
|
||||
*
|
||||
* <code>
|
||||
* $token = Security::token();
|
||||
* </code>
|
||||
*
|
||||
* You can insert this token into your forms as a hidden field:
|
||||
*
|
||||
* <code>
|
||||
* echo Form::hidden('csrf', Security::token());
|
||||
* </code>
|
||||
*
|
||||
* This provides a basic, but effective, method of preventing CSRF attacks.
|
||||
*
|
||||
* @param boolean $new force a new token to be generated?. Default is false
|
||||
* @return string
|
||||
*/
|
||||
public static function token($new = false)
|
||||
{
|
||||
// Get the current token
|
||||
$token = Session::get(Security::$token_name);
|
||||
|
||||
// Create a new unique token
|
||||
if ($new === true or ! $token) {
|
||||
|
||||
// Generate a new unique token
|
||||
$token = sha1(uniqid(mt_rand(), true));
|
||||
|
||||
// Store the new token
|
||||
Session::set(Security::$token_name, $token);
|
||||
}
|
||||
|
||||
// Return token
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the given token matches the currently stored security token.
|
||||
*
|
||||
* <code>
|
||||
* if (Security::check($token)) {
|
||||
* // Pass
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @param string $token token to check
|
||||
* @return boolean
|
||||
*/
|
||||
public static function check($token)
|
||||
{
|
||||
return Security::token() === $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt password
|
||||
*
|
||||
* <code>
|
||||
* $encrypt_password = Security::encryptPassword('password');
|
||||
* </code>
|
||||
*
|
||||
* @param string $password Password to encrypt
|
||||
*/
|
||||
public static function encryptPassword($password)
|
||||
{
|
||||
return md5(md5(trim($password) . MONSTRA_PASSWORD_SALT));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create safe name. Use to create safe username, filename, pagename.
|
||||
*
|
||||
* <code>
|
||||
* $safe_name = Security::safeName('hello world');
|
||||
* </code>
|
||||
*
|
||||
* @param string $str String
|
||||
* @param string $delimiter String delimiter
|
||||
* @param boolean $lowercase String Lowercase
|
||||
* @return string
|
||||
*/
|
||||
public static function safeName($str, $delimiter = '-', $lowercase = false)
|
||||
{
|
||||
// Redefine vars
|
||||
$str = (string) $str;
|
||||
$delimiter = (string) $delimiter;
|
||||
$lowercase = (bool) $lowercase;
|
||||
$delimiter = (string) $delimiter;
|
||||
|
||||
// Remove tags
|
||||
$str = filter_var($str, FILTER_SANITIZE_STRING);
|
||||
|
||||
// Decode all entities to their simpler forms
|
||||
$str = html_entity_decode($str, ENT_QUOTES, 'UTF-8');
|
||||
|
||||
// Reserved characters (RFC 3986)
|
||||
$reserved_characters = array(
|
||||
'/', '?', ':', '@', '#', '[', ']',
|
||||
'!', '$', '&', '\'', '(', ')', '*',
|
||||
'+', ',', ';', '='
|
||||
);
|
||||
|
||||
// Remove reserved characters
|
||||
$str = str_replace($reserved_characters, ' ', $str);
|
||||
|
||||
// Set locale to en_US.UTF8
|
||||
setlocale(LC_ALL, 'en_US.UTF8');
|
||||
|
||||
// Translit ua,ru => latin
|
||||
$str = Text::translitIt($str);
|
||||
|
||||
// Convert string
|
||||
$str = iconv('UTF-8', 'ASCII//TRANSLIT', $str);
|
||||
|
||||
// Remove characters
|
||||
$str = preg_replace("/[^a-zA-Z0-9\/_|+ -]/", '', $str );
|
||||
$str = preg_replace("/[\/_|+ -]+/", $delimiter, $str );
|
||||
$str = trim($str, $delimiter);
|
||||
|
||||
// Lowercase
|
||||
if ($lowercase === true) $str = Text::lowercase($str);
|
||||
|
||||
// Return safe name
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create safe url.
|
||||
*
|
||||
* <code>
|
||||
* $url = Security::sanitizeURL('http://test.com');
|
||||
* </code>
|
||||
*
|
||||
* @param string $url Url to sanitize
|
||||
* @return string
|
||||
*/
|
||||
public static function sanitizeURL($url)
|
||||
{
|
||||
$url = trim($url);
|
||||
$url = rawurldecode($url);
|
||||
$url = str_replace(array('--','"','!','@','#','$','%','^','*','(',')','+','{','}','|',':','"','<','>',
|
||||
'[',']','\\',';',"'",',','*','+','~','`','laquo','raquo',']>','‘','’','“','”','–','—'),
|
||||
array('-','-','','','','','','','','','','','','','','','','','','','','','','','','','','',''),
|
||||
$url);
|
||||
$url = str_replace('--', '-', $url);
|
||||
$url = rtrim($url, "-");
|
||||
|
||||
$url = str_replace('..', '', $url);
|
||||
$url = str_replace('//', '', $url);
|
||||
$url = preg_replace('/^\//', '', $url);
|
||||
$url = preg_replace('/^\./', '', $url);
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize URL to prevent XSS - Cross-site scripting
|
||||
*/
|
||||
public static function runSanitizeURL()
|
||||
{
|
||||
$_GET = array_map('Security::sanitizeURL', $_GET);
|
||||
}
|
||||
|
||||
/**
|
||||
* That prevents null characters between ascii characters.
|
||||
*
|
||||
* @param string $str String
|
||||
*/
|
||||
public static function removeInvisibleCharacters($str)
|
||||
{
|
||||
// Redefine vars
|
||||
$str = (string) $str;
|
||||
|
||||
// Thanks to ci for this tip :)
|
||||
$non_displayables = array('/%0[0-8bcef]/', '/%1[0-9a-f]/', '/[\x00-\x08]/', '/\x0b/', '/\x0c/', '/[\x0e-\x1f]/');
|
||||
|
||||
do {
|
||||
$cleaned = $str;
|
||||
$str = preg_replace($non_displayables, '', $str);
|
||||
} while ($cleaned != $str);
|
||||
|
||||
// Return safe string
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize data to prevent XSS - Cross-site scripting
|
||||
*
|
||||
* @param string $str String
|
||||
*/
|
||||
public static function xssClean($str)
|
||||
{
|
||||
// Remove invisible characters
|
||||
$str = Security::removeInvisibleCharacters($str);
|
||||
|
||||
// Convert html to plain text
|
||||
$str = Html::toText($str);
|
||||
|
||||
// Return safe string
|
||||
return $str;
|
||||
}
|
||||
|
||||
}
|
187
libraries/monstra/Session.php
Normal file
187
libraries/monstra/Session.php
Normal file
@@ -0,0 +1,187 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Monstra Library
|
||||
*
|
||||
* This source file is part of the Monstra Library. More information,
|
||||
* documentation and tutorials can be found at http://library.monstra.org
|
||||
*
|
||||
* @package Monstra
|
||||
*
|
||||
* @author Romanenko Sergey / Awilum
|
||||
* @copyright (c) 2012 - 2013 Romanenko Sergey / Awilum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
class Session
|
||||
{
|
||||
/**
|
||||
* Starts the session.
|
||||
*
|
||||
* <code>
|
||||
* Session::start();
|
||||
* </code>
|
||||
*
|
||||
*/
|
||||
public static function start()
|
||||
{
|
||||
// Is session already started?
|
||||
if ( ! session_id()) {
|
||||
|
||||
// Start the session
|
||||
return @session_start();
|
||||
}
|
||||
|
||||
// If already started
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes one or more session variables.
|
||||
*
|
||||
* <code>
|
||||
* Session::delete('user');
|
||||
* </code>
|
||||
*
|
||||
*/
|
||||
public static function delete()
|
||||
{
|
||||
// Loop all arguments
|
||||
foreach (func_get_args() as $argument) {
|
||||
|
||||
// Array element
|
||||
if (is_array($argument)) {
|
||||
|
||||
// Loop the keys
|
||||
foreach ($argument as $key) {
|
||||
|
||||
// Unset session key
|
||||
unset($_SESSION[(string) $key]);
|
||||
}
|
||||
} else {
|
||||
|
||||
// Remove from array
|
||||
unset($_SESSION[(string) $argument]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys the session.
|
||||
*
|
||||
* <code>
|
||||
* Session::destroy();
|
||||
* </code>
|
||||
*
|
||||
*/
|
||||
public static function destroy()
|
||||
{
|
||||
// Destroy
|
||||
if (session_id()) {
|
||||
session_unset();
|
||||
session_destroy();
|
||||
$_SESSION = array();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a session variable exists.
|
||||
*
|
||||
* <code>
|
||||
* if (Session::exists('user')) {
|
||||
* // Do something...
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function exists()
|
||||
{
|
||||
// Start session if needed
|
||||
if ( ! session_id()) Session::start();
|
||||
|
||||
// Loop all arguments
|
||||
foreach (func_get_args() as $argument) {
|
||||
|
||||
// Array element
|
||||
if (is_array($argument)) {
|
||||
|
||||
// Loop the keys
|
||||
foreach ($argument as $key) {
|
||||
|
||||
// Does NOT exist
|
||||
if ( ! isset($_SESSION[(string) $key])) return false;
|
||||
}
|
||||
} else {
|
||||
|
||||
// Does NOT exist
|
||||
if ( ! isset($_SESSION[(string) $argument])) return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a variable that was stored in the session.
|
||||
*
|
||||
* <code>
|
||||
* echo Session::get('user');
|
||||
* </code>
|
||||
*
|
||||
* @param string $key The key of the variable to get.
|
||||
* @return mixed
|
||||
*/
|
||||
public static function get($key)
|
||||
{
|
||||
// Start session if needed
|
||||
if ( ! session_id()) self::start();
|
||||
|
||||
// Redefine key
|
||||
$key = (string) $key;
|
||||
|
||||
// Fetch key
|
||||
if (Session::exists((string) $key)) return $_SESSION[(string) $key];
|
||||
|
||||
// Key doesn't exist
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the sessionID.
|
||||
*
|
||||
* <code>
|
||||
* echo Session::getSessionId();
|
||||
* </code>
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getSessionId()
|
||||
{
|
||||
if ( ! session_id()) Session::start();
|
||||
return session_id();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Stores a variable in the session.
|
||||
*
|
||||
* <code>
|
||||
* Session::set('user', 'Awilum');
|
||||
* </code>
|
||||
*
|
||||
* @param string $key The key for the variable.
|
||||
* @param mixed $value The value to store.
|
||||
*/
|
||||
public static function set($key, $value)
|
||||
{
|
||||
// Start session if needed
|
||||
if ( ! session_id()) self::start();
|
||||
|
||||
// Set key
|
||||
$_SESSION[(string) $key] = $value;
|
||||
}
|
||||
|
||||
}
|
475
libraries/monstra/Text.php
Normal file
475
libraries/monstra/Text.php
Normal file
@@ -0,0 +1,475 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Monstra Library
|
||||
*
|
||||
* This source file is part of the Monstra Library. More information,
|
||||
* documentation and tutorials can be found at http://library.monstra.org
|
||||
*
|
||||
* @package Monstra
|
||||
*
|
||||
* @author Romanenko Sergey / Awilum
|
||||
* @copyright (c) 2012 - 2013 Romanenko Sergey / Awilum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
class Text
|
||||
{
|
||||
/**
|
||||
* Protected constructor since this is a static class.
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
// Nothing here
|
||||
}
|
||||
|
||||
/**
|
||||
* Translit function ua,ru => latin
|
||||
*
|
||||
* <code>
|
||||
* echo Text::translitIt('Привет');
|
||||
* </code>
|
||||
*
|
||||
* @param string $str [ua,ru] string
|
||||
* @return string $str
|
||||
*/
|
||||
public static function translitIt($str)
|
||||
{
|
||||
// Redefine vars
|
||||
$str = (string) $str;
|
||||
|
||||
$patern = array(
|
||||
"А" => "A", "Б" => "B", "В" => "V", "Г" => "G",
|
||||
"Д" => "D", "Е" => "E", "Ж" => "J", "З" => "Z",
|
||||
"И" => "I", "Й" => "Y", "К" => "K", "Л" => "L",
|
||||
"М" => "M", "Н" => "N", "О" => "O", "П" => "P",
|
||||
"Р" => "R", "С" => "S", "Т" => "T", "У" => "U",
|
||||
"Ф" => "F", "Х" => "H", "Ц" => "TS", "Ч" => "CH",
|
||||
"Ш" => "SH", "Щ" => "SCH", "Ъ" => "", "Ы" => "YI",
|
||||
"Ь" => "", "Э" => "E", "Ю" => "YU", "Я" => "YA",
|
||||
"а" => "a", "б" => "b", "в" => "v", "г" => "g",
|
||||
"д" => "d", "е" => "e", "ж" => "j", "з" => "z",
|
||||
"и" => "i", "й" => "y", "к" => "k", "л" => "l",
|
||||
"м" => "m", "н" => "n", "о" => "o","п" => "p",
|
||||
"р" => "r", "с" => "s", "т" => "t", "у" => "u",
|
||||
"ф" => "f", "х" => "h", "ц" => "ts", "ч" => "ch",
|
||||
"ш" => "sh", "щ" => "sch", "ъ" => "y", "ї" => "i",
|
||||
"Ї" => "Yi", "є" => "ie", "Є" => "Ye", "ы" => "yi",
|
||||
"ь" => "", "э" => "e", "ю" => "yu", "я" => "ya", "ё" => "yo"
|
||||
);
|
||||
|
||||
return strtr($str, $patern);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes any leading and traling slashes from a string
|
||||
*
|
||||
* <code>
|
||||
* echo Text::trimSlashes('some text here/');
|
||||
* </code>
|
||||
*
|
||||
* @param string $str String with slashes
|
||||
* @return string
|
||||
*/
|
||||
public static function trimSlashes($str)
|
||||
{
|
||||
// Redefine vars
|
||||
$str = (string) $str;
|
||||
|
||||
return trim($str, '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes slashes contained in a string or in an array
|
||||
*
|
||||
* <code>
|
||||
* echo Text::strpSlashes('some \ text \ here');
|
||||
* </code>
|
||||
*
|
||||
* @param mixed $str String or array of strings with slashes
|
||||
* @return mixed
|
||||
*/
|
||||
public static function strpSlashes($str)
|
||||
{
|
||||
if (is_array($str)) {
|
||||
foreach ($str as $key => $val) {
|
||||
$result[$key] = stripslashes($val);
|
||||
}
|
||||
} else {
|
||||
$result = stripslashes($str);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes single and double quotes from a string
|
||||
*
|
||||
* <code>
|
||||
* echo Text::stripQuotes('some "text" here');
|
||||
* </code>
|
||||
*
|
||||
* @param string $str String with single and double quotes
|
||||
* @return string
|
||||
*/
|
||||
public static function stripQuotes($str)
|
||||
{
|
||||
// Redefine vars
|
||||
$str = (string) $str;
|
||||
|
||||
return str_replace(array('"', "'"), '', $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert single and double quotes to entities
|
||||
*
|
||||
* <code>
|
||||
* echo Text::quotesToEntities('some "text" here');
|
||||
* </code>
|
||||
*
|
||||
* @param string $str String with single and double quotes
|
||||
* @return string
|
||||
*/
|
||||
public static function quotesToEntities($str)
|
||||
{
|
||||
// Redefine vars
|
||||
$str = (string) $str;
|
||||
|
||||
return str_replace(array("\'", "\"", "'", '"'), array("'", """, "'", """), $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a random string of characters
|
||||
*
|
||||
* <code>
|
||||
* echo Text::random();
|
||||
* </code>
|
||||
*
|
||||
* @param string $type The type of string. Default is 'alnum'
|
||||
* @param integer $length The number of characters. Default is 16
|
||||
* @return string
|
||||
*/
|
||||
public static function random($type = 'alnum', $length = 16)
|
||||
{
|
||||
// Redefine vars
|
||||
$type = (string) $type;
|
||||
$length = (int) $length;
|
||||
|
||||
switch ($type) {
|
||||
|
||||
case 'basic':
|
||||
return mt_rand();
|
||||
break;
|
||||
|
||||
default:
|
||||
case 'alnum':
|
||||
case 'numeric':
|
||||
case 'nozero':
|
||||
case 'alpha':
|
||||
case 'distinct':
|
||||
case 'hexdec':
|
||||
switch ($type) {
|
||||
case 'alpha':
|
||||
$pool = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
break;
|
||||
|
||||
default:
|
||||
case 'alnum':
|
||||
$pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
break;
|
||||
|
||||
case 'numeric':
|
||||
$pool = '0123456789';
|
||||
break;
|
||||
|
||||
case 'nozero':
|
||||
$pool = '123456789';
|
||||
break;
|
||||
|
||||
case 'distinct':
|
||||
$pool = '2345679ACDEFHJKLMNPRSTUVWXYZ';
|
||||
break;
|
||||
|
||||
case 'hexdec':
|
||||
$pool = '0123456789abcdef';
|
||||
break;
|
||||
}
|
||||
|
||||
$str = '';
|
||||
for ($i=0; $i < $length; $i++) {
|
||||
$str .= substr($pool, mt_rand(0, strlen($pool) -1), 1);
|
||||
}
|
||||
|
||||
return $str;
|
||||
break;
|
||||
|
||||
case 'unique':
|
||||
return md5(uniqid(mt_rand()));
|
||||
break;
|
||||
|
||||
case 'sha1' :
|
||||
return sha1(uniqid(mt_rand(), true));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add's _1 to a string or increment the ending number to allow _2, _3, etc
|
||||
*
|
||||
* <code>
|
||||
* $str = Text::increment($str);
|
||||
* </code>
|
||||
*
|
||||
* @param string $str String to increment
|
||||
* @param integer $first Start with
|
||||
* @param string $separator Separator
|
||||
* @return string
|
||||
*/
|
||||
public static function increment($str, $first = 1, $separator = '_')
|
||||
{
|
||||
preg_match('/(.+)'.$separator.'([0-9]+)$/', $str, $match);
|
||||
|
||||
return isset($match[2]) ? $match[1].$separator.($match[2] + 1) : $str.$separator.$first;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Cut string
|
||||
*
|
||||
* <code>
|
||||
* echo Text::cut('Some text here', 5);
|
||||
* </code>
|
||||
*
|
||||
* @param string $str Input string
|
||||
* @param integer $length Length after cut
|
||||
* @param string $cut_msg Message after cut string
|
||||
* @return string
|
||||
*/
|
||||
public static function cut($str, $length, $cut_msg = null)
|
||||
{
|
||||
// Redefine vars
|
||||
$str = (string) $str;
|
||||
$length = (int) $length;
|
||||
|
||||
if (isset($cut_msg)) $msg = $cut_msg; else $msg = '...';
|
||||
return function_exists('mb_substr') ? mb_substr($str, 0, $length, 'utf-8') . $msg : substr($str, 0, $length) . $msg;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Lowercase
|
||||
*
|
||||
* <code>
|
||||
* echo Text::lowercase('Some text here');
|
||||
* </code>
|
||||
*
|
||||
* @param string $str String
|
||||
* @return string
|
||||
*/
|
||||
public static function lowercase($str)
|
||||
{
|
||||
// Redefine vars
|
||||
$str = (string) $str;
|
||||
|
||||
return function_exists('mb_strtolower') ? mb_strtolower($str, 'utf-8') : strtolower($str);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Uppercase
|
||||
*
|
||||
* <code>
|
||||
* echo Text::uppercase('some text here');
|
||||
* </code>
|
||||
*
|
||||
* @param string $str String
|
||||
* @return string
|
||||
*/
|
||||
public static function uppercase($str)
|
||||
{
|
||||
// Redefine vars
|
||||
$str = (string) $str;
|
||||
|
||||
return function_exists('mb_strtoupper') ? mb_strtoupper($str, 'utf-8') : strtoupper($str);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get length
|
||||
*
|
||||
* <code>
|
||||
* echo Text::length('Some text here');
|
||||
* </code>
|
||||
*
|
||||
* @param string $str String
|
||||
* @return string
|
||||
*/
|
||||
public static function length($str)
|
||||
{
|
||||
// Redefine vars
|
||||
$str = (string) $str;
|
||||
|
||||
return function_exists('mb_strlen') ? mb_strlen($str, 'utf-8') : strlen($str);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a lorem ipsum text
|
||||
*
|
||||
* <code>
|
||||
* echo Text::lorem(2);
|
||||
* </code>
|
||||
*
|
||||
* @param integer $num Count
|
||||
* @return string
|
||||
*/
|
||||
public static function lorem($num = 1)
|
||||
{
|
||||
// Redefine vars
|
||||
$num = (int) $num;
|
||||
|
||||
return str_repeat('Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.', (int) $num);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Extract the last `$num` characters from a string.
|
||||
*
|
||||
* <code>
|
||||
* echo Text::right('Some text here', 4);
|
||||
* </code>
|
||||
*
|
||||
* @param string $str The string to extract the characters from.
|
||||
* @param integer $num The number of characters to extract.
|
||||
* @return string
|
||||
*/
|
||||
public static function right($str, $num)
|
||||
{
|
||||
// Redefine vars
|
||||
$str = (string) $str;
|
||||
$num = (int) $num;
|
||||
|
||||
return substr($str, Text::length($str)-$num, $num);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Extract the first `$num` characters from a string.
|
||||
*
|
||||
* <code>
|
||||
* echo Text::left('Some text here', 4);
|
||||
* </code>
|
||||
*
|
||||
* @param string $str The string to extract the characters from.
|
||||
* @param integer $num The number of characters to extract.
|
||||
* @return string
|
||||
*/
|
||||
public static function left($str, $num)
|
||||
{
|
||||
// Redefine vars
|
||||
$str = (string) $str;
|
||||
$num = (int) $num;
|
||||
|
||||
return substr($str, 0, $num);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Replaces newline with <br> or <br />.
|
||||
*
|
||||
* <code>
|
||||
* echo Text::nl2br("Some \n text \n here");
|
||||
* </code>
|
||||
*
|
||||
* @param string $str The input string
|
||||
* @param boolean $xhtml Xhtml or not
|
||||
* @return string
|
||||
*/
|
||||
public static function nl2br($str, $xhtml = true)
|
||||
{
|
||||
// Redefine vars
|
||||
$str = (string) $str;
|
||||
$xhtml = (bool) $xhtml;
|
||||
|
||||
return str_replace(array("\r\n", "\n\r", "\n", "\r"), (($xhtml) ? '<br />' : '<br>'), $str);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Replaces <br> and <br /> with newline.
|
||||
*
|
||||
* <code>
|
||||
* echo Text::br2nl("Some <br /> text <br /> here");
|
||||
* </code>
|
||||
*
|
||||
* @param string $str The input string
|
||||
* @return string
|
||||
*/
|
||||
public static function br2nl($str)
|
||||
{
|
||||
// Redefine vars
|
||||
$str = (string) $str;
|
||||
|
||||
return str_replace(array('<br>', '<br/>', '<br />'), "\n", $str);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts & to &.
|
||||
*
|
||||
* <code>
|
||||
* echo Text::ampEncode("M&CMS");
|
||||
* </code>
|
||||
*
|
||||
* @param string $str The input string
|
||||
* @return string
|
||||
*/
|
||||
public static function ampEncode($str)
|
||||
{
|
||||
// Redefine vars
|
||||
$str = (string) $str;
|
||||
|
||||
return str_replace('&', '&', $str);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts & to &.
|
||||
*
|
||||
* <code>
|
||||
* echo Text::ampEncode("M&CMS");
|
||||
* </code>
|
||||
*
|
||||
* @param string $str The input string
|
||||
* @return string
|
||||
*/
|
||||
public static function ampDecode($str)
|
||||
{
|
||||
// Redefine vars
|
||||
$str = (string) $str;
|
||||
|
||||
return str_replace('&', '&', $str);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert plain text to html
|
||||
*
|
||||
* <code>
|
||||
* echo Text::toHtml('test');
|
||||
* </code>
|
||||
*
|
||||
* @param string $str String
|
||||
* @return string
|
||||
*/
|
||||
public static function toHtml($str)
|
||||
{
|
||||
// Redefine vars
|
||||
$str = (string) $str;
|
||||
|
||||
return html_entity_decode($str, ENT_QUOTES, 'utf-8');
|
||||
}
|
||||
|
||||
}
|
107
libraries/monstra/Url.php
Normal file
107
libraries/monstra/Url.php
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Monstra Library
|
||||
*
|
||||
* This source file is part of the Monstra Library. More information,
|
||||
* documentation and tutorials can be found at http://library.monstra.org
|
||||
*
|
||||
* @package Monstra
|
||||
*
|
||||
* @author Romanenko Sergey / Awilum
|
||||
* @copyright (c) 2012 - 2013 Romanenko Sergey / Awilum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
class Url
|
||||
{
|
||||
/**
|
||||
* Protected constructor since this is a static class.
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
// Nothing here
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a long url and uses the TinyURL API to return a shortened version.
|
||||
*
|
||||
* <code>
|
||||
* echo Url::tiny('http:://sitename.com');
|
||||
* </code>
|
||||
*
|
||||
* @param string $url Long url
|
||||
* @return string
|
||||
*/
|
||||
public static function tiny($url)
|
||||
{
|
||||
return file_get_contents('http://tinyurl.com/api-create.php?url='.(string) $url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check is url exists
|
||||
*
|
||||
* <code>
|
||||
* if (Url::exists('http:://sitename.com')) {
|
||||
* // Do something...
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @param string $url Url
|
||||
* @return boolean
|
||||
*/
|
||||
public static function exists($url)
|
||||
{
|
||||
$a_url = parse_url($url);
|
||||
if ( ! isset($a_url['port'])) $a_url['port'] = 80;
|
||||
$errno = 0;
|
||||
$errstr = '';
|
||||
$timeout = 30;
|
||||
if (isset($a_url['host']) && $a_url['host']!=gethostbyname($a_url['host'])) {
|
||||
$fid = fsockopen($a_url['host'], $a_url['port'], $errno, $errstr, $timeout);
|
||||
if ( ! $fid) return false;
|
||||
$page = isset($a_url['path']) ? $a_url['path'] : '';
|
||||
$page .= isset($a_url['query']) ? '?'.$a_url['query'] : '';
|
||||
fputs($fid, 'HEAD '.$page.' HTTP/1.0'."\r\n".'Host: '.$a_url['host']."\r\n\r\n");
|
||||
$head = fread($fid, 4096);
|
||||
fclose($fid);
|
||||
|
||||
return preg_match('#^HTTP/.*\s+[200|302]+\s#i', $head);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the base URL
|
||||
*
|
||||
* <code>
|
||||
* echo Url::base();
|
||||
* </code>
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function base()
|
||||
{
|
||||
$https = (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') ? 'https://' : 'http://';
|
||||
|
||||
return $https . rtrim(rtrim($_SERVER['HTTP_HOST'], '\\/') . dirname($_SERVER['PHP_SELF']), '\\/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets current URL
|
||||
*
|
||||
* <code>
|
||||
* echo Url::current();
|
||||
* </code>
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function current()
|
||||
{
|
||||
return (!empty($_SERVER['HTTPS'])) ? "https://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'] : "http://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
|
||||
}
|
||||
|
||||
}
|
207
libraries/monstra/Valid.php
Normal file
207
libraries/monstra/Valid.php
Normal file
@@ -0,0 +1,207 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Monstra Library
|
||||
*
|
||||
* This source file is part of the Monstra Library. More information,
|
||||
* documentation and tutorials can be found at http://library.monstra.org
|
||||
*
|
||||
* @package Monstra
|
||||
*
|
||||
* @author Romanenko Sergey / Awilum
|
||||
* @copyright (c) 2012 - 2013 Romanenko Sergey / Awilum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
class Valid
|
||||
{
|
||||
/**
|
||||
* Protected constructor since this is a static class.
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
// Nothing here
|
||||
}
|
||||
|
||||
/**
|
||||
* Check an email address for correct format.
|
||||
*
|
||||
* <code>
|
||||
* if (Valid::email('test@test.com')) {
|
||||
* // Do something...
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @param string $email email address
|
||||
* @return boolean
|
||||
*/
|
||||
public static function email($email)
|
||||
{
|
||||
return (bool) filter_var((string) $email, FILTER_VALIDATE_EMAIL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check an ip address for correct format.
|
||||
*
|
||||
* <code>
|
||||
* if (Valid::ip('127.0.0.1') || Valid::ip('0:0:0:0:0:0:7f00:1')) {
|
||||
* // Do something...
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @param string $ip ip address
|
||||
* @return boolean
|
||||
*/
|
||||
public static function ip($ip)
|
||||
{
|
||||
return (bool) filter_var((string) $ip, FILTER_VALIDATE_IP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check an credit card for correct format.
|
||||
*
|
||||
* <code>
|
||||
* if (Valid::creditCard(7711111111111111, 'Visa')) {
|
||||
* // Do something...
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @param integer $num Credit card num
|
||||
* @param string $type Credit card type:
|
||||
* American - American Express
|
||||
* Dinners - Diner's Club
|
||||
* Discover - Discover Card
|
||||
* Master - Mastercard
|
||||
* Visa - Visa
|
||||
* @return boolean
|
||||
*/
|
||||
public static function creditCard($num, $type)
|
||||
{
|
||||
// Redefine vars
|
||||
$num = (int) $num;
|
||||
$type = (string) $type;
|
||||
|
||||
switch ($type) {
|
||||
case "American": return (bool) preg_match("/^([34|37]{2})([0-9]{13})$/", $num);
|
||||
case "Dinners": return (bool) preg_match("/^([30|36|38]{2})([0-9]{12})$/", $num);
|
||||
case "Discover": return (bool) preg_match("/^([6011]{4})([0-9]{12})$/", $num);
|
||||
case "Master": return (bool) preg_match("/^([51|52|53|54|55]{2})([0-9]{14})$/", $num);
|
||||
case "Visa": return (bool) preg_match("/^([4]{1})([0-9]{12,15})$/", $num);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check an phone number for correct format.
|
||||
*
|
||||
* <code>
|
||||
* if (Valid::phone(0661111117)) {
|
||||
* // Do something...
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @param string $num Phone number
|
||||
* @return boolean
|
||||
*/
|
||||
public static function phone($num)
|
||||
{
|
||||
return (bool) preg_match("/^([0-9\(\)\/\+ \-]*)$/", (string) $num);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check an url for correct format.
|
||||
*
|
||||
* <code>
|
||||
* if (Valid::url('http://site.com/')) {
|
||||
* // Do something...
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @param string $url Url
|
||||
* @return boolean
|
||||
*/
|
||||
public static function url($url)
|
||||
{
|
||||
return (bool) filter_var((string) $url, FILTER_VALIDATE_URL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check an date for correct format.
|
||||
*
|
||||
* <code>
|
||||
* if (Valid::date('12/12/12')) {
|
||||
* // Do something...
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @param string $str Date
|
||||
* @return boolean
|
||||
*/
|
||||
public static function date($str)
|
||||
{
|
||||
return (strtotime($str) !== false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether a string consists of digits only (no dots or dashes).
|
||||
*
|
||||
* <code>
|
||||
* if (Valid::digit('12')) {
|
||||
* // Do something...
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @param string $str String
|
||||
* @return boolean
|
||||
*/
|
||||
public static function digit($str)
|
||||
{
|
||||
return (bool) preg_match ("/[^0-9]/", $str);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether a string is a valid number (negative and decimal numbers allowed).
|
||||
*
|
||||
* <code>
|
||||
* if (Valid::numeric('3.14')) {
|
||||
* // Do something...
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* Uses {@link http://www.php.net/manual/en/function.localeconv.php locale conversion}
|
||||
* to allow decimal point to be locale specific.
|
||||
*
|
||||
* @param string $str String
|
||||
* @return boolean
|
||||
*/
|
||||
public static function numeric($str)
|
||||
{
|
||||
$locale = localeconv();
|
||||
|
||||
return (bool) preg_match('/^-?[0-9'.$locale['decimal_point'].']++$/D', (string) $str);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the given regex statement is valid.
|
||||
*
|
||||
* @param string $regexp The value to validate.
|
||||
* @return boolean
|
||||
*/
|
||||
public static function regexp($regexp)
|
||||
{
|
||||
// dummy string
|
||||
$dummy = 'Monstra - fast and simple PHP library';
|
||||
|
||||
// validate
|
||||
return (@preg_match((string) $regexp, $dummy) !== false);
|
||||
|
||||
}
|
||||
|
||||
}
|
373
libraries/monstra/Zip.php
Normal file
373
libraries/monstra/Zip.php
Normal file
@@ -0,0 +1,373 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Monstra Library
|
||||
*
|
||||
* This source file is part of the Monstra Library. More information,
|
||||
* documentation and tutorials can be found at http://library.monstra.org
|
||||
*
|
||||
* @package Monstra
|
||||
*
|
||||
* @author Romanenko Sergey / Awilum
|
||||
* @copyright (c) 2012 - 2013 Romanenko Sergey / Awilum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
class Zip
|
||||
{
|
||||
public $zipdata = '';
|
||||
public $directory = '';
|
||||
public $entries = 0;
|
||||
public $file_num = 0;
|
||||
public $offset = 0;
|
||||
public $now;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->now = time();
|
||||
}
|
||||
|
||||
/**
|
||||
* Zip factory
|
||||
*
|
||||
* <code>
|
||||
* Zip::factory();
|
||||
* </code>
|
||||
*
|
||||
* @return Zip
|
||||
*/
|
||||
public static function factory()
|
||||
{
|
||||
return new Zip();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Directory
|
||||
*
|
||||
* <code>
|
||||
* Zip::factory()->addDir('test');
|
||||
* </code>
|
||||
*
|
||||
* @param mixed $directory The directory name. Can be string or array
|
||||
*/
|
||||
public function addDir($directory)
|
||||
{
|
||||
foreach ((array) $directory as $dir) {
|
||||
|
||||
if ( ! preg_match("|.+/$|", $dir)) {
|
||||
$dir .= '/';
|
||||
}
|
||||
|
||||
$dir_time = $this->_get_mod_time($dir);
|
||||
|
||||
$this->_add_dir($dir, $dir_time['file_mtime'], $dir_time['file_mdate']);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file/directory modification time
|
||||
*
|
||||
* @param string $dir Full path to the dir
|
||||
* @return array
|
||||
*/
|
||||
protected function _get_mod_time($dir)
|
||||
{
|
||||
// If this is a newly created file/dir, we will set the time to 'now'
|
||||
$date = (@filemtime($dir)) ? filemtime($dir) : getdate($this->now);
|
||||
|
||||
$time['file_mtime'] = ($date['hours'] << 11) + ($date['minutes'] << 5) + $date['seconds'] / 2;
|
||||
$time['file_mdate'] = (($date['year'] - 1980) << 9) + ($date['mon'] << 5) + $date['mday'];
|
||||
|
||||
return $time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Directory
|
||||
*
|
||||
* @param string $dir The directory name
|
||||
* @param integer $file_mtime File mtime
|
||||
* @param integer $file_mdate File mdate
|
||||
*/
|
||||
private function _add_dir($dir, $file_mtime, $file_mdate)
|
||||
{
|
||||
$dir = str_replace("\\", "/", $dir);
|
||||
|
||||
$this->zipdata .=
|
||||
"\x50\x4b\x03\x04\x0a\x00\x00\x00\x00\x00"
|
||||
.pack('v', $file_mtime)
|
||||
.pack('v', $file_mdate)
|
||||
.pack('V', 0) // crc32
|
||||
.pack('V', 0) // compressed filesize
|
||||
.pack('V', 0) // uncompressed filesize
|
||||
.pack('v', strlen($dir)) // length of pathname
|
||||
.pack('v', 0) // extra field length
|
||||
.$dir
|
||||
// below is "data descriptor" segment
|
||||
.pack('V', 0) // crc32
|
||||
.pack('V', 0) // compressed filesize
|
||||
.pack('V', 0); // uncompressed filesize
|
||||
|
||||
$this->directory .=
|
||||
"\x50\x4b\x01\x02\x00\x00\x0a\x00\x00\x00\x00\x00"
|
||||
.pack('v', $file_mtime)
|
||||
.pack('v', $file_mdate)
|
||||
.pack('V',0) // crc32
|
||||
.pack('V',0) // compressed filesize
|
||||
.pack('V',0) // uncompressed filesize
|
||||
.pack('v', strlen($dir)) // length of pathname
|
||||
.pack('v', 0) // extra field length
|
||||
.pack('v', 0) // file comment length
|
||||
.pack('v', 0) // disk number start
|
||||
.pack('v', 0) // internal file attributes
|
||||
.pack('V', 16) // external file attributes - 'directory' bit set
|
||||
.pack('V', $this->offset) // relative offset of local header
|
||||
.$dir;
|
||||
|
||||
$this->offset = strlen($this->zipdata);
|
||||
$this->entries++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Data to Zip
|
||||
*
|
||||
* <code>
|
||||
* Zip::factory()->addData('test.txt', 'Some test text here');
|
||||
* </code>
|
||||
*
|
||||
* Lets you add files to the archive. If the path is included
|
||||
* in the filename it will be placed within a directory. Make
|
||||
* sure you use add_dir() first to create the folder.
|
||||
*
|
||||
* @param mixed $filepath Full path to the file
|
||||
* @param string $data Data
|
||||
*/
|
||||
public function addData($filepath, $data = null)
|
||||
{
|
||||
if (is_array($filepath)) {
|
||||
foreach ($filepath as $path => $data) {
|
||||
$file_data = $this->_get_mod_time($path);
|
||||
$this->_add_data($path, $data, $file_data['file_mtime'], $file_data['file_mdate']);
|
||||
}
|
||||
} else {
|
||||
$file_data = $this->_get_mod_time($filepath);
|
||||
$this->_add_data($filepath, $data, $file_data['file_mtime'], $file_data['file_mdate']);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Data to Zip
|
||||
*
|
||||
* @param string $filepath Full path to the file
|
||||
* @param string $data The data to be encoded
|
||||
* @param integer $file_mtime File mtime
|
||||
* @param integer $file_mdate File mdate
|
||||
*/
|
||||
private function _add_data($filepath, $data, $file_mtime, $file_mdate)
|
||||
{
|
||||
$filepath = str_replace("\\", "/", $filepath);
|
||||
|
||||
$uncompressed_size = strlen($data);
|
||||
$crc32 = crc32($data);
|
||||
|
||||
$gzdata = gzcompress($data);
|
||||
$gzdata = substr($gzdata, 2, -4);
|
||||
$compressed_size = strlen($gzdata);
|
||||
|
||||
$this->zipdata .=
|
||||
"\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00"
|
||||
.pack('v', $file_mtime)
|
||||
.pack('v', $file_mdate)
|
||||
.pack('V', $crc32)
|
||||
.pack('V', $compressed_size)
|
||||
.pack('V', $uncompressed_size)
|
||||
.pack('v', strlen($filepath)) // length of filename
|
||||
.pack('v', 0) // extra field length
|
||||
.$filepath
|
||||
.$gzdata; // "file data" segment
|
||||
|
||||
$this->directory .=
|
||||
"\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00"
|
||||
.pack('v', $file_mtime)
|
||||
.pack('v', $file_mdate)
|
||||
.pack('V', $crc32)
|
||||
.pack('V', $compressed_size)
|
||||
.pack('V', $uncompressed_size)
|
||||
.pack('v', strlen($filepath)) // length of filename
|
||||
.pack('v', 0) // extra field length
|
||||
.pack('v', 0) // file comment length
|
||||
.pack('v', 0) // disk number start
|
||||
.pack('v', 0) // internal file attributes
|
||||
.pack('V', 32) // external file attributes - 'archive' bit set
|
||||
.pack('V', $this->offset) // relative offset of local header
|
||||
.$filepath;
|
||||
|
||||
$this->offset = strlen($this->zipdata);
|
||||
$this->entries++;
|
||||
$this->file_num++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the contents of a file and add it to the zip
|
||||
*
|
||||
* <code>
|
||||
* Zip::factory()->readFile('test.txt');
|
||||
* </code>
|
||||
*
|
||||
* @param string $path Path
|
||||
* @param boolean $preserve_filepath Preserve filepath
|
||||
* @return mixed
|
||||
*/
|
||||
public function readFile($path, $preserve_filepath = false)
|
||||
{
|
||||
if ( ! file_exists($path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (false !== ($data = file_get_contents($path))) {
|
||||
|
||||
$name = str_replace("\\", "/", $path);
|
||||
|
||||
if ($preserve_filepath === false) {
|
||||
$name = preg_replace("|.*/(.+)|", "\\1", $name);
|
||||
}
|
||||
|
||||
$this->addData($name, $data);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a directory and add it to the zip.
|
||||
*
|
||||
* <code>
|
||||
* Zip::factory()->readDir('test/');
|
||||
* </code>
|
||||
*
|
||||
* This function recursively reads a folder and everything it contains (including
|
||||
* sub-folders) and creates a zip based on it. Whatever directory structure
|
||||
* is in the original file path will be recreated in the zip file.
|
||||
*
|
||||
* @param string $path Path to source
|
||||
* @param boolean $preserve_filepath Preserve filepath
|
||||
* @param string $root_path Root path
|
||||
* @return mixed
|
||||
*/
|
||||
public function readDir($path, $preserve_filepath = true, $root_path = null)
|
||||
{
|
||||
if ( ! $fp = @opendir($path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set the original directory root for child dir's to use as relative
|
||||
if ($root_path === null) {
|
||||
$root_path = dirname($path) . '/';
|
||||
}
|
||||
|
||||
while (false !== ($file = readdir($fp))) {
|
||||
|
||||
if (substr($file, 0, 1) == '.') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (@is_dir($path.$file)) {
|
||||
$this->readDir($path.$file."/", $preserve_filepath, $root_path);
|
||||
} else {
|
||||
if (false !== ($data = file_get_contents($path.$file))) {
|
||||
$name = str_replace("\\", "/", $path);
|
||||
|
||||
if ($preserve_filepath === false) {
|
||||
$name = str_replace($root_path, '', $name);
|
||||
}
|
||||
|
||||
$this->addData($name.$file, $data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the Zip file
|
||||
*
|
||||
* <code>
|
||||
* Zip::factory()->getZip();
|
||||
* </code>
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getZip()
|
||||
{
|
||||
// Is there any data to return?
|
||||
if ($this->entries == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$zip_data = $this->zipdata;
|
||||
$zip_data .= $this->directory."\x50\x4b\x05\x06\x00\x00\x00\x00";
|
||||
$zip_data .= pack('v', $this->entries); // total # of entries "on this disk"
|
||||
$zip_data .= pack('v', $this->entries); // total # of entries overall
|
||||
$zip_data .= pack('V', strlen($this->directory)); // size of central dir
|
||||
$zip_data .= pack('V', strlen($this->zipdata)); // offset to start of central dir
|
||||
$zip_data .= "\x00\x00"; // .zip file comment length
|
||||
|
||||
return $zip_data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write File to the specified directory
|
||||
*
|
||||
* <code>
|
||||
* Zip::factory()->readDir('test1/')->readDir('test2/')->archive('test.zip');
|
||||
* </code>
|
||||
*
|
||||
* @param string $filepath The file name
|
||||
* @return boolean
|
||||
*/
|
||||
public function archive($filepath)
|
||||
{
|
||||
if ( ! ($fp = @fopen($filepath, "w"))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
flock($fp, LOCK_EX);
|
||||
fwrite($fp, $this->getZip());
|
||||
flock($fp, LOCK_UN);
|
||||
fclose($fp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize Data
|
||||
*
|
||||
* <code>
|
||||
* Zip::factory()->clearData();
|
||||
* </code>
|
||||
*
|
||||
* Lets you clear current zip data. Useful if you need to create
|
||||
* multiple zips with different data.
|
||||
*/
|
||||
public function clearData()
|
||||
{
|
||||
$this->zipdata = '';
|
||||
$this->directory = '';
|
||||
$this->entries = 0;
|
||||
$this->file_num = 0;
|
||||
$this->offset = 0;
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user