update
This commit is contained in:
510
lib/common/Curl.php
Normal file
510
lib/common/Curl.php
Normal file
@ -0,0 +1,510 @@
|
||||
<?php
|
||||
|
||||
namespace Common;
|
||||
|
||||
class Curl {
|
||||
|
||||
/**
|
||||
* cURL request method
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_method = 'GET';
|
||||
|
||||
|
||||
/**
|
||||
* Currently accepted cURL request method types
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_methods = array('POST', 'GET');
|
||||
|
||||
|
||||
/**
|
||||
* cURL URL
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_url = '';
|
||||
|
||||
|
||||
/**
|
||||
* cURL data params
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_params;
|
||||
|
||||
|
||||
/**
|
||||
* cURL options
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_options = array();
|
||||
|
||||
|
||||
/**
|
||||
* cURL user agent
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_agent = 'lodev09 engine';
|
||||
|
||||
|
||||
/**
|
||||
* GET request
|
||||
*
|
||||
* @param string $url
|
||||
* @param array $params
|
||||
* @param array $options
|
||||
* @return mixed
|
||||
*/
|
||||
static public function get($url = '', $params = array(), $options = array()) {
|
||||
return self::make($url, $params, $options, 'GET');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* POST request
|
||||
*
|
||||
* @param string $url
|
||||
* @param array $params
|
||||
* @param array $options
|
||||
* @return mixed
|
||||
*/
|
||||
static public function post($url = '', $params = array(), $options = array()) {
|
||||
return self::make($url, $params, $options, 'POST');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make request
|
||||
*
|
||||
* @param string $url
|
||||
* @param array $params
|
||||
* @param array $options
|
||||
* @param string $method
|
||||
* @return Curl
|
||||
*/
|
||||
static public function make($url = '', $params = array(), $options = array(), $method = null) {
|
||||
return new self($url, $params, $options, $method);
|
||||
}
|
||||
|
||||
|
||||
public function __construct($url = '', $params = array(), $options = array(), $method = null) {
|
||||
// Set request method
|
||||
if ($method) {
|
||||
$this->_method = $method;
|
||||
}
|
||||
|
||||
$this->_params = $params;
|
||||
|
||||
if ($this->_method == 'GET') {
|
||||
// Explode the URL to get the URL params
|
||||
$url_split = explode('?', $url);
|
||||
|
||||
// Request URL is everything before the ? (if it exists)
|
||||
$this->_url = $url_split[0];
|
||||
|
||||
// If there were URL params, add it to the params array
|
||||
$this->_params = array_merge($this->_params, $this->_queryString($url), (array) $params);
|
||||
|
||||
} else {
|
||||
$this->_url = $url;
|
||||
}
|
||||
|
||||
// Set the passed options
|
||||
$this->_options($options);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add multiple params
|
||||
*
|
||||
* @param array $keys
|
||||
* @return Curl
|
||||
*/
|
||||
public function params($keys = array()) {
|
||||
$this->_params = array_merge((array) $this->_params, (array) $keys);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a single param
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
* @return Curl
|
||||
*/
|
||||
public function param($key = '', $value = '') {
|
||||
if ( ! empty($key) && is_string($key)) {
|
||||
$key = array(
|
||||
$key => (string) $value
|
||||
);
|
||||
}
|
||||
|
||||
return $this->params($key);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add multiple options
|
||||
*
|
||||
* @param array $options
|
||||
* @return Curl
|
||||
*/
|
||||
public function options($options = array()) {
|
||||
$this->_options($options);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add single option
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
* @return Curl
|
||||
*/
|
||||
public function option($key = '', $value = '') {
|
||||
$this->_option($key, $value);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Request method
|
||||
*
|
||||
* @param string $method
|
||||
* @return Curl
|
||||
*/
|
||||
public function method($method = null) {
|
||||
$this->_method = $method;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* User agent
|
||||
*
|
||||
* @param string $agent
|
||||
* @return Curl
|
||||
*/
|
||||
public function agent($agent = '') {
|
||||
if ($agent) {
|
||||
return $this->option('CURLOPT_USERAGENT', $agent);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Proxy helper
|
||||
*
|
||||
* @param string $url
|
||||
* @param int $port
|
||||
* @return Curl
|
||||
*/
|
||||
public function proxy($url = '', $port = 80) {
|
||||
return $this->options(array(
|
||||
'CURLOPT_HTTPPROXYTUNNEL' => true,
|
||||
'CURLOPT_PROXY' => $url.':'.$port
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Custom header helper
|
||||
*
|
||||
* @param string $header
|
||||
* @param string $content
|
||||
* @return Curl
|
||||
*/
|
||||
public function httpHeader($header, $content = null) {
|
||||
$header = ($content) ? $header.':'.$content : $header;
|
||||
|
||||
return $this->option('CURLOPT_HTTPHEADER', $header);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* HTTP login helper
|
||||
*
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @param string $type
|
||||
* @return Curl
|
||||
*/
|
||||
public function httpLogin($username = '', $password = '', $type = 'ANY') {
|
||||
return $this->options(array(
|
||||
'CURLOPT_HTTPAUTH' => constant('CURLAUTH_'.strtoupper($type)),
|
||||
'CURLOPT_USERPWD' => $username.':'.$password
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Proxy login helper
|
||||
*
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @return Curl
|
||||
*/
|
||||
public function proxyLogin($username = '', $password = '') {
|
||||
return $this->option('CURLOPT_PROXYUSERPWD', $username.':'.$password);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* SSL helper
|
||||
*
|
||||
* @param bool $verify_peer
|
||||
* @param int $verify_host
|
||||
* @param string $path_to_cert
|
||||
* @return Curl
|
||||
*/
|
||||
public function ssl($verify_peer = true, $verify_host = 2, $path_to_cert = null) {
|
||||
if ($verify_peer) {
|
||||
$options = array(
|
||||
'CURLOPT_SSL_VERIFYPEER' => true,
|
||||
'CURLOPT_SSL_VERIFYHOST' => $verify_host,
|
||||
'CURLOPT_CAINFO' => $path_to_cert
|
||||
);
|
||||
}
|
||||
|
||||
else {
|
||||
$options = array(
|
||||
'CURLOPT_SSL_VERIFYPEER' => false
|
||||
);
|
||||
}
|
||||
|
||||
return $this->options($options);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Execute request
|
||||
*
|
||||
* @return Curl
|
||||
* @throws Exception
|
||||
*/
|
||||
public function call() {
|
||||
// cURL is not enabled
|
||||
if ( ! $this->_isEnabled()) {
|
||||
throw new Exception(__CLASS__.': PHP was not built with cURL enabled. Rebuild PHP with --with-curl to use cURL.');
|
||||
}
|
||||
|
||||
// Request method
|
||||
$method = ($this->_method) ? strtoupper($this->_method) : 'GET';
|
||||
|
||||
// Unrecognized request method?
|
||||
if ( ! in_array($method, $this->_methods)) {
|
||||
throw new Exception(__CLASS__.': Unrecognized request method of '.$this->_method);
|
||||
}
|
||||
|
||||
return $this->_execute($method);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Alias for call();
|
||||
*
|
||||
* @return Curl
|
||||
*/
|
||||
public function execute() {
|
||||
return $this->call();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Execute request
|
||||
*
|
||||
* @param string $method
|
||||
* @return Curl
|
||||
*/
|
||||
private function _execute($method) {
|
||||
// Method specific options
|
||||
switch ($method) {
|
||||
case 'GET' :
|
||||
// Append GET params to URL
|
||||
$this->_url .= '?'.http_build_query($this->_params);
|
||||
|
||||
// Set options
|
||||
$this->options('CURLOPT_HTTPGET', 1);
|
||||
break;
|
||||
|
||||
case 'POST' :
|
||||
// Set options
|
||||
$this->options(array(
|
||||
'CURLOPT_POST' => true,
|
||||
'CURLOPT_POSTFIELDS' => $this->_params
|
||||
));
|
||||
break;
|
||||
|
||||
// Mostly for future use
|
||||
case 'PUT' :
|
||||
// Set options
|
||||
$this->options(array(
|
||||
'CURLOPT_PUT' => true,
|
||||
'CURLOPT_HTTPHEADER' => array('Content-Type: '.strlen($this->_params)),
|
||||
'CURLOPT_POSTFIELDS' => $this->_params
|
||||
));
|
||||
break;
|
||||
|
||||
// Mostly for future use
|
||||
case 'DELETE' :
|
||||
// Set options
|
||||
$this->option('CURLOPT_CUSTOMREQUEST', 'DELETE');
|
||||
$this->option('CURLOPT_POSTFIELDS', $this->_params);
|
||||
break;
|
||||
}
|
||||
|
||||
// Set timeout option if it isn't already set
|
||||
if ( ! array_key_exists('CURLOPT_TIMEOUT', $this->_options)) {
|
||||
$this->option('CURLOPT_TIMEOUT', 30);
|
||||
}
|
||||
|
||||
// Set returntransfer option if it isn't already set
|
||||
if ( ! array_key_exists('CURLOPT_RETURNTRANSFER', $this->_options)) {
|
||||
$this->option('CURLOPT_RETURNTRANSFER', true);
|
||||
}
|
||||
|
||||
// Set failonerror option if it isn't already set
|
||||
if ( ! array_key_exists('CURLOPT_FAILONERROR', $this->_options)) {
|
||||
$this->option('CURLOPT_FAILONERROR', true);
|
||||
}
|
||||
|
||||
// Set user agent option if it isn't already set
|
||||
if ( ! array_key_exists('CURLOPT_USERAGENT', $this->_options)) {
|
||||
$this->option('CURLOPT_USERAGENT', $this->_agent);
|
||||
}
|
||||
|
||||
// Only set follow location if not running securely
|
||||
if ( ! ini_get('safe_mode') && ! ini_get('open_basedir')) {
|
||||
// Ok, follow location is not set already so lets set it to true
|
||||
if ( ! array_key_exists('CURLOPT_FOLLOWLOCATION', $this->_options)) {
|
||||
$this->option('CURLOPT_FOLLOWLOCATION', true);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize cURL request
|
||||
$ch = curl_init($this->_url);
|
||||
|
||||
// Can't set the options in batch
|
||||
if ( ! function_exists('curl_setopt_array')) {
|
||||
foreach ($this->_options as $key => $value) {
|
||||
curl_setopt($ch, $key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
// Set options in batch
|
||||
else {
|
||||
curl_setopt_array($ch, $this->_options);
|
||||
}
|
||||
|
||||
// Execute
|
||||
$response = new stdClass();
|
||||
$response->result = curl_exec($ch);
|
||||
$response->info = curl_getinfo($ch);
|
||||
$response->error = curl_error($ch);
|
||||
$response->error_code = curl_errno($ch);
|
||||
|
||||
// Reset the options
|
||||
|
||||
$this->_url = '';
|
||||
$this->_params = '';
|
||||
$this->_options = array();
|
||||
|
||||
// Close cURL request
|
||||
curl_close($ch);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add multiple options
|
||||
*
|
||||
* @param array $options
|
||||
*/
|
||||
protected function _options($options = array()) {
|
||||
foreach ((array) $options as $key => $value) {
|
||||
$this->_option($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add single option
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function _option($key = '', $value = '') {
|
||||
if (is_string($key) && ! is_numeric($key)) {
|
||||
$const = strtoupper($key);
|
||||
|
||||
if (defined($const)) {
|
||||
$key = constant(strtoupper($key));
|
||||
}
|
||||
|
||||
else {
|
||||
throw new Exception('Curl: Constant ['.$const.'] not defined.');
|
||||
}
|
||||
}
|
||||
|
||||
// Custom header
|
||||
if ($key == CURLOPT_HTTPHEADER) {
|
||||
$this->_options[$key][] = $value;
|
||||
}
|
||||
|
||||
// Not a custom header
|
||||
else {
|
||||
$this->_options[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get query string from URL
|
||||
*
|
||||
* @param $uri
|
||||
* @return array
|
||||
*/
|
||||
protected function _queryString($uri) {
|
||||
$query_data = array();
|
||||
|
||||
$query_array = html_entity_decode(parse_url($uri, PHP_URL_QUERY));
|
||||
|
||||
if ( ! empty($query_array)) {
|
||||
$query_array = explode('&', $query_array);
|
||||
|
||||
foreach($query_array as $val) {
|
||||
$x = explode('=', $val);
|
||||
|
||||
$query_data[$x[0]] = $x[1];
|
||||
}
|
||||
}
|
||||
|
||||
return $query_data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if cURL is enabled
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function _isEnabled() {
|
||||
return function_exists('curl_init');
|
||||
}
|
||||
|
||||
}
|
||||
501
lib/common/Date.php
Normal file
501
lib/common/Date.php
Normal file
@ -0,0 +1,501 @@
|
||||
<?php
|
||||
|
||||
namespace Common;
|
||||
|
||||
/**
|
||||
* Date class
|
||||
*/
|
||||
class Date {
|
||||
|
||||
/**
|
||||
* Fuzzy date strings
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_time_formats = array(
|
||||
array(60, 'just now'),
|
||||
array(90, '1 minute'),
|
||||
array(3600, 'minutes', 60),
|
||||
array(5400, '1 hour'),
|
||||
array(86400, 'hours', 3600),
|
||||
array(129600, '1 day'),
|
||||
array(604800, 'days', 86400),
|
||||
array(907200, '1 week'),
|
||||
array(2628000, 'weeks', 604800),
|
||||
array(3942000, '1 month'),
|
||||
array(31536000, 'months', 2628000),
|
||||
array(47304000, '1 year'),
|
||||
array(3153600000, 'years', 31536000)
|
||||
);
|
||||
|
||||
protected $_time_format = 'H:i';
|
||||
|
||||
|
||||
/**
|
||||
* Timestamp
|
||||
*
|
||||
* @var DateTime
|
||||
*/
|
||||
protected $_timestamp = null;
|
||||
|
||||
|
||||
/**
|
||||
* Use current timestamp
|
||||
*
|
||||
* @return Date
|
||||
*/
|
||||
static public function now() {
|
||||
return self::with('now');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specified time
|
||||
*
|
||||
* @param int|string $date
|
||||
* @return Date
|
||||
*/
|
||||
static public function with($date) {
|
||||
return new self($date);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param int|string $date
|
||||
*/
|
||||
public function __construct($date) {
|
||||
// If the timestamp is not valid, set the timestamp to now
|
||||
if (($this->_timestamp = strtotime($date)) === false) {
|
||||
$this->_timestamp = strtotime('now');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Pretty formatted date. Yes, this is an actual method. Deal with it!
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function pretty_date($time = true) {
|
||||
return $this->formatted('F j, Y'.($time ? ' '.$this->_time_format : ''));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Timezone string. Or timezone abbreviation
|
||||
*
|
||||
* @param bool $abbrev
|
||||
* @return string
|
||||
*/
|
||||
public function timezone($abbrev = false) {
|
||||
$abbrev = ($abbrev) ? 'T' : 'e';
|
||||
|
||||
return $this->formatted($abbrev);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Timezone offset in seconds
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function timezone_offset() {
|
||||
return $this->formatted('z');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Difference to Greenwich time (GMT)
|
||||
*
|
||||
* @param bool $colon
|
||||
* @return string
|
||||
*/
|
||||
public function gmt_diff($colon = false) {
|
||||
$colon = ($colon) ? 'P' : 'O';
|
||||
|
||||
return $this->formatted($colon);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Current timestamp
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function timestamp() {
|
||||
return (int) $this->formatted('U');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Day
|
||||
*
|
||||
* @param bool $text
|
||||
* @param bool $full
|
||||
* @return string
|
||||
*/
|
||||
public function day($text = false, $full = true) {
|
||||
if ($text) {
|
||||
return $this->day_text($full);
|
||||
}
|
||||
|
||||
return $this->day_num($full);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Day of month. Optionally with leading 0
|
||||
*
|
||||
* @param bool $leading
|
||||
* @return string
|
||||
*/
|
||||
public function day_num($leading = false) {
|
||||
$leading = ($leading) ? 'd' : 'j';
|
||||
|
||||
return $this->formatted($leading);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A textual representation of a day
|
||||
*
|
||||
* @param bool $full
|
||||
* @return string
|
||||
*/
|
||||
public function day_text($full = true) {
|
||||
$full = ($full) ? 'l' : 'D';
|
||||
|
||||
return $this->formatted($full);
|
||||
}
|
||||
|
||||
/**
|
||||
* English ordinal suffix for the day of the month, 2 characters
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function ordinal() {
|
||||
return $this->formatted('S');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Numeric representation of the day of the week
|
||||
*
|
||||
* @param bool $iso8601
|
||||
* @return string
|
||||
*/
|
||||
public function day_of_week($iso8601 = false) {
|
||||
$iso8601 = ($iso8601) ? 'N' : 'w';
|
||||
|
||||
return $this->formatted($iso8601);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The day of the year (starting from 0)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function day_of_year() {
|
||||
return $this->formatted('z');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Number of days in the given month
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function days_in_month() {
|
||||
return $this->formatted('t');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Month
|
||||
*
|
||||
* @param bool $text
|
||||
* @param bool $full
|
||||
* @return string
|
||||
*/
|
||||
public function month($text = false, $full = true) {
|
||||
if ($text) {
|
||||
return $this->monthText($full);
|
||||
}
|
||||
|
||||
return $this->month_num($full);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Numeric representation of a month
|
||||
*
|
||||
* @param bool $leading
|
||||
* @return string
|
||||
*/
|
||||
public function month_num($leading = true) {
|
||||
$leading = ($leading) ? 'm' : 'n';
|
||||
|
||||
return $this->formatted($leading);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A textual representation of a month
|
||||
*
|
||||
* @param bool $abbrev
|
||||
* @return string
|
||||
*/
|
||||
public function monthText($abbrev = true) {
|
||||
$abbrev = ($abbrev) ? 'M' : 'F';
|
||||
|
||||
return $this->formatted($abbrev);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ISO-8601 week number of year, weeks starting on Monday
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function week_of_year() {
|
||||
return $this->formatted('W');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Year representation
|
||||
*
|
||||
* @param bool $full
|
||||
* @return string
|
||||
*/
|
||||
public function year($full = true) {
|
||||
$full = ($full) ? 'Y' : 'y';
|
||||
|
||||
return $this->formatted($full);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Whether it's a leap year
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function leapyear() {
|
||||
return (bool) $this->formatted('L');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 12 or 24-hour format of an hour with or without leading zeros
|
||||
*
|
||||
* @param bool $leading
|
||||
* @param bool $military
|
||||
* @return string
|
||||
*/
|
||||
public function hour($leading = true, $military = true) {
|
||||
if ($military) {
|
||||
return $this->hour12($leading);
|
||||
}
|
||||
|
||||
return $this->hour24($leading);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 12-hour format of an hour with or without leading zeros
|
||||
*
|
||||
* @param bool $leading
|
||||
* @return string
|
||||
*/
|
||||
public function hour12($leading = true) {
|
||||
$format = ($leading) ? 'h' : 'g';
|
||||
|
||||
return $this->formatted($format);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 24-hour format of an hour with or without leading zeros
|
||||
*
|
||||
* @param bool $leading
|
||||
* @return string
|
||||
*/
|
||||
public function hour24($leading = true) {
|
||||
$format = ($leading) ? 'H' : 'G';
|
||||
|
||||
return $this->formatted($format);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Minutes with leading zeros
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function minutes() {
|
||||
return $this->formatted('i');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Seconds with leading zeros
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function seconds() {
|
||||
return $this->formatted('s');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Microseconds
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function microseconds() {
|
||||
return $this->formatted('u');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ante meridiem or Post meridiem
|
||||
*
|
||||
* @param bool $upper
|
||||
* @return string
|
||||
*/
|
||||
public function meridiem($upper = true) {
|
||||
$upper = ($upper) ? 'A' : 'a';
|
||||
|
||||
return $this->formatted($upper);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Whether or not the date is in daylight saving time
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function daylight_saving() {
|
||||
return (bool) $this->formatted('I');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ISO 8601 date (eg. 2004-02-12T15:19:21+00:00)
|
||||
*
|
||||
* @param bool $utc
|
||||
* @return string
|
||||
*/
|
||||
public function iso8601($utc = false) {
|
||||
return $utc ? gmdate('c', $this->_timestamp) : $this->formatted('c');
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 2822 formatted date (eg. Thu, 21 Dec 2000 16:01:07 +0200)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function rfc2822() {
|
||||
return $this->formatted('r');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find the age in years
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function age() {
|
||||
// Current
|
||||
$now = self::now();
|
||||
|
||||
// Differences
|
||||
$year_diff = $now->year() - $this->year();
|
||||
$month_diff = $now->month_num() - $this->month_num();
|
||||
$day_diff = $now->day_num() - $this->day_num();
|
||||
|
||||
if ($day_diff < 0 || $month_diff < 0) {
|
||||
$year_diff --;
|
||||
}
|
||||
|
||||
return $year_diff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find MySQL Date format (eg. 2014-02-25 00:00:00)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function mysql($time = true) {
|
||||
return $this->formatted('Y-m-d'.($time ? ' H:i:s' : ''));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find the relative date
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function fuzzy($append = 'ago') {
|
||||
// Difference between now and the passed date
|
||||
$diff = time() - $this->_timestamp;
|
||||
|
||||
$val = '';
|
||||
|
||||
// Waaaayyyy to long ago (earlier than 1970)
|
||||
if ($this->_timestamp <= 0) {
|
||||
// A long time ago... in a galaxy far, far away
|
||||
$val = 'a long time '.$append;
|
||||
}
|
||||
|
||||
// Future date
|
||||
else if ($diff < 0) {
|
||||
$val = 'in the future';
|
||||
}
|
||||
|
||||
// Past date
|
||||
else {
|
||||
// Loop through each format measurement
|
||||
foreach ($this->_time_formats as $format) {
|
||||
// if the difference from now and passed time is less than first option in format measurement
|
||||
if ($diff < $format[0]) {
|
||||
// If the format array item has no calculation value
|
||||
if (count($format) == 2) {
|
||||
$val = $format[1].($format[0] === 60 ? '' : ' '.$append);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Divide difference by format item value to get number of units
|
||||
else {
|
||||
$val = ceil($diff / $format[2]).' '.$format[1].' '.$append;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $val;
|
||||
}
|
||||
|
||||
public function short($time = true) {
|
||||
return $this->formatted('m/d/Y'.($time ? ' '.$this->_time_format : ''));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generic date format. See http://php.net/manual/en/function.date.php
|
||||
*
|
||||
* @param string $format
|
||||
* @return mixed
|
||||
*/
|
||||
public function formatted($format = null) {
|
||||
$format = $format ? : 'F j, Y, '.$this->_time_format.' T';
|
||||
return date($format, $this->_timestamp);
|
||||
}
|
||||
|
||||
}
|
||||
443
lib/common/File.php
Normal file
443
lib/common/File.php
Normal file
@ -0,0 +1,443 @@
|
||||
<?php
|
||||
|
||||
namespace Common;
|
||||
|
||||
class File {
|
||||
|
||||
public $_exif = null;
|
||||
|
||||
private $_mime_types = array(
|
||||
'.txt' => 'text/plain',
|
||||
'.htm' => 'text/html',
|
||||
'.html' => 'text/html',
|
||||
'.php' => 'text/html',
|
||||
'.css' => 'text/css',
|
||||
'.js' => 'application/javascript',
|
||||
'.json' => 'application/json',
|
||||
'.xml' => 'application/xml',
|
||||
'.swf' => 'application/x-shockwave-flash',
|
||||
'.flv' => 'video/x-flv',
|
||||
|
||||
// images
|
||||
'.png' => 'image/png',
|
||||
'.jpe' => 'image/jpeg',
|
||||
'.jpeg' => 'image/jpeg',
|
||||
'.jpg' => 'image/jpeg',
|
||||
'.gif' => 'image/gif',
|
||||
'.bmp' => 'image/bmp',
|
||||
'.ico' => 'image/vnd.microsoft.icon',
|
||||
'.tiff' => 'image/tiff',
|
||||
'.tif' => 'image/tiff',
|
||||
'.svg' => 'image/svg+xml',
|
||||
'.svgz' => 'image/svg+xml',
|
||||
|
||||
// archives
|
||||
'.zip' => 'application/zip',
|
||||
'.rar' => 'application/x-rar-compressed',
|
||||
'.exe' => 'application/x-msdownload',
|
||||
'.msi' => 'application/x-msdownload',
|
||||
'.cab' => 'application/vnd.ms-cab-compressed',
|
||||
|
||||
// audio/video
|
||||
'.mp3' => 'audio/mpeg',
|
||||
'.qt' => 'video/quicktime',
|
||||
'.mov' => 'video/quicktime',
|
||||
'.wmv' => 'video/x-ms-wmv',
|
||||
'.mp4' => 'video/mp4',
|
||||
'.mp4a' => 'audio/mp4',
|
||||
'.mpeg' => 'video/mpeg',
|
||||
|
||||
// adobe
|
||||
'.pdf' => 'application/pdf',
|
||||
'.psd' => 'image/vnd.adobe.photoshop',
|
||||
'.ai' => 'application/postscript',
|
||||
'.eps' => 'application/postscript',
|
||||
'.ps' => 'application/postscript',
|
||||
'.tiff' => 'image/tiff',
|
||||
|
||||
// ms office
|
||||
'.doc' => 'application/msword',
|
||||
'.rtf' => 'application/rtf',
|
||||
'.xls' => 'application/vnd.ms-excel',
|
||||
'.xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
'.docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
'.ppt' => 'application/vnd.ms-powerpoint',
|
||||
|
||||
// open office
|
||||
'.odt' => 'application/vnd.oasis.opendocument.text',
|
||||
'.ods' => 'application/vnd.oasis.opendocument.spreadsheet',
|
||||
);
|
||||
|
||||
/**
|
||||
* default structure of the validations array
|
||||
* @var array
|
||||
*/
|
||||
private $_validations = array(
|
||||
'extension' => array(),
|
||||
'category' => array(),
|
||||
'size' => 200,
|
||||
'custom' => null
|
||||
);
|
||||
|
||||
private $_default_properties = array(
|
||||
'name' => '',
|
||||
'tmp_name' => '',
|
||||
'size' => 0,
|
||||
'error' => UPLOAD_ERR_OK,
|
||||
'extension' => ''
|
||||
);
|
||||
|
||||
// custom filtered errors
|
||||
const UPLOAD_ERR_EXTENSION_FILTER = 100;
|
||||
const UPLOAD_ERR_CATEGORY_FILTER = 101;
|
||||
const UPLOAD_ERR_SIZE_FILTER = 102;
|
||||
|
||||
/**
|
||||
* errors container array
|
||||
* @var array
|
||||
*/
|
||||
private $_errors = array();
|
||||
|
||||
/**
|
||||
* error messages container array
|
||||
* @var array
|
||||
*/
|
||||
private $_error_messages = array(
|
||||
UPLOAD_ERR_OK => "There is no error, the file uploaded with success.",
|
||||
UPLOAD_ERR_INI_SIZE => "The uploaded file exceeds the upload_max_filesize directive in php.ini.",
|
||||
UPLOAD_ERR_FORM_SIZE => "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.",
|
||||
UPLOAD_ERR_PARTIAL => "The uploaded file was only partially uploaded.",
|
||||
UPLOAD_ERR_NO_FILE => "No file was uploaded.",
|
||||
UPLOAD_ERR_NO_TMP_DIR => "Missing a temporary folder. Introduced in PHP 4.3.10 and PHP 5.0.3.",
|
||||
UPLOAD_ERR_CANT_WRITE => "Failed to write file to disk. Introduced in PHP 5.1.0.",
|
||||
UPLOAD_ERR_EXTENSION => "A PHP extension stopped the file upload. PHP does not provide a way to ascertain which extension caused the file upload to stop;examining the list of loaded extensions with phpinfo() may help. Introduced in PHP 5.2.0.",
|
||||
self::UPLOAD_ERR_EXTENSION_FILTER => "File type not allowed",
|
||||
self::UPLOAD_ERR_CATEGORY_FILTER => "File not allowed",
|
||||
self::UPLOAD_ERR_SIZE_FILTER => "File size not allowed"
|
||||
);
|
||||
|
||||
/**
|
||||
* initialize the File class
|
||||
* @param array $properties file data
|
||||
* @param array $validations validation array
|
||||
*/
|
||||
public function __construct($properties, $validations = array()) {
|
||||
$this->_validations = self::_set_array_defaults($this->_validations, $validations);
|
||||
$this->_default_properties = self::_set_array_defaults($this->_default_properties, $properties);
|
||||
|
||||
// set this instance's properties from the provided data
|
||||
foreach ($this->_default_properties as $key => $value) {
|
||||
$this->{$key} = $value;
|
||||
}
|
||||
|
||||
// get the file info and add them as this instance's properties
|
||||
$info = $this->get_info();
|
||||
foreach ($info as $key => $info) {
|
||||
$this->{$key} = $info;
|
||||
}
|
||||
|
||||
// see if Exif class exists and if it's an image file
|
||||
if (class_exists('Exif') && $this->tmp_name) {
|
||||
switch ($this->extension) {
|
||||
case '.jpg':
|
||||
case '.jpeg':
|
||||
case '.tiff':
|
||||
$this->_exif = new Exif($this->tmp_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* set the default values to an input array
|
||||
* @param array $default_structure the default structure of the array
|
||||
* @param array $array_value the input value
|
||||
* @param string $set_to_key_if_fail set to a default key if failed to set appropriate value
|
||||
*/
|
||||
private static function _set_array_defaults($default_structure, $array_value, $set_to_key_if_fail = "") {
|
||||
if ($set_to_key_if_fail != "") {
|
||||
if (!is_array($array_value) || !isset($array_value[$set_to_key_if_fail])) {
|
||||
if (isset($default_structure[$set_to_key_if_fail]))
|
||||
$default_structure[$set_to_key_if_fail] = $array_value;
|
||||
|
||||
return $default_structure;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($array_value as $key => $value) {
|
||||
$default_structure[$key] = $value;
|
||||
}
|
||||
return $default_structure;
|
||||
}
|
||||
|
||||
/**
|
||||
* put the tmp_name somewhere
|
||||
* @param string $dest_path the destination path
|
||||
* @param string $filename the filename, leave blank to use the upload's name
|
||||
* @return boolean true if success, otherwise false
|
||||
*/
|
||||
public function put($dest_path, $filename = '') {
|
||||
if (is_dir($dest_path)) {
|
||||
if (!$filename) $filename = $this->name;
|
||||
return move_uploaded_file($this->tmp_name, $dest_path.'/'.$filename);
|
||||
} return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* get error messages
|
||||
* @param boolean $return_str should it return an string or array
|
||||
* @return string/array returns the error string or errors array
|
||||
*/
|
||||
public function get_error($return_str = true) {
|
||||
$messages = $this->_error_messages;
|
||||
$errors = array_map(function($error) use ($messages) {
|
||||
if (isset($messages[$error])) return $messages[$error];
|
||||
else return is_int($error) ? 'Unknown File Error' : $error;
|
||||
|
||||
}, $this->_errors);
|
||||
return $return_str ? implode('; ', $errors) : $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* set the error message of the error type
|
||||
* @param int $error_num error type
|
||||
* @param string $message error message
|
||||
*/
|
||||
public function set_error_message($error_num, $message = '') {
|
||||
$this->_error_messages[$error_num] = $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* validate the file
|
||||
* @return boolean true if valid, otherwise false
|
||||
*/
|
||||
public function validate() {
|
||||
if ($this->error !== UPLOAD_ERR_OK) {
|
||||
$this->_errors[] = $this->error;
|
||||
}
|
||||
|
||||
// filter size
|
||||
$def_size_filter = array(
|
||||
'max' => 200, // 200 MB
|
||||
'min' => 0,
|
||||
'unit' => 'MB',
|
||||
'message' => '[size (kb): '.$this->size.'] '.$this->_error_messages[self::UPLOAD_ERR_SIZE_FILTER]
|
||||
);
|
||||
$size_filter = self::_set_array_defaults($def_size_filter, $this->_validations['size'], 'max');
|
||||
$this->set_error_message(self::UPLOAD_ERR_SIZE_FILTER, $size_filter['message']);
|
||||
|
||||
$get_actual_size = function($size, $unit) {
|
||||
switch (strtolower($unit)) {
|
||||
case 'mb':
|
||||
$size = $size * 1048576;
|
||||
break;
|
||||
case 'kb':
|
||||
$size = $size * 1024;
|
||||
case 'gb':
|
||||
$size = $size * 1073741824;
|
||||
}
|
||||
return $size;
|
||||
};
|
||||
$max_actual_size = $get_actual_size($size_filter['max'], $size_filter['unit']);
|
||||
$min_actual_size = $get_actual_size($size_filter['min'], $size_filter['unit']);
|
||||
|
||||
if ($this->size > $max_actual_size || $this->size < $min_actual_size)
|
||||
$this->_errors[] = self::UPLOAD_ERR_SIZE_FILTER;
|
||||
|
||||
// filter extension
|
||||
if ($this->_validations['extension']) {
|
||||
$def_ext_filter = array(
|
||||
'is' => array(),
|
||||
'not' => array(),
|
||||
'message' => '[extension: '.$this->extension.'] '.$this->_error_messages[self::UPLOAD_ERR_EXTENSION_FILTER]
|
||||
);
|
||||
$ext_filter = self::_set_array_defaults($def_ext_filter, $this->_validations['extension'], 'is');
|
||||
$this->set_error_message(self::UPLOAD_ERR_EXTENSION_FILTER, $ext_filter['message']);
|
||||
|
||||
if (!is_array($ext_filter['is'])) $ext_filter['is'] = array($ext_filter['is']);
|
||||
if (!is_array($ext_filter['not'])) $ext_filter['not'] = array($ext_filter['not']);
|
||||
|
||||
if (!in_array($this->extension, $ext_filter['is']) || in_array($this->extension, $ext_filter['not']))
|
||||
$this->_errors[] = self::UPLOAD_ERR_EXTENSION_FILTER;
|
||||
}
|
||||
|
||||
|
||||
// filter category
|
||||
if ($this->_validations['category']) {
|
||||
$def_cat_filter = array(
|
||||
'is' => array(),
|
||||
'not' => array(),
|
||||
'message' => '[category: '.$this->category.'] '.$this->_error_messages[self::UPLOAD_ERR_CATEGORY_FILTER]
|
||||
);
|
||||
$cat_filter = self::_set_array_defaults($def_cat_filter, $this->_validations['category'], 'is');
|
||||
$this->set_error_message(self::UPLOAD_ERR_CATEGORY_FILTER, $cat_filter['message']);
|
||||
|
||||
if (!is_array($cat_filter['is'])) $cat_filter['is'] = array($cat_filter['is']);
|
||||
if (!is_array($cat_filter['not'])) $cat_filter['not'] = array($cat_filter['not']);
|
||||
|
||||
if (!in_array($this->category, $cat_filter['is']) || in_array($this->category, $cat_filter['not']))
|
||||
$this->_errors[] = self::UPLOAD_ERR_CATEGORY_FILTER;
|
||||
}
|
||||
|
||||
if ($this->_validations['custom']) {
|
||||
$custom_validations = is_array($this->_validations['custom']) ? $this->_validations['custom'] : array($this->_validations['custom']);
|
||||
foreach ($custom_validations as $validation) {
|
||||
$result = $this->_validations['custom']($this);
|
||||
if ($result != '' && $result !== true && $result !== null) {
|
||||
$this->_errors[] = $result;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return !$this->_errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the exif GPS data (if the file is an image)
|
||||
* @return array array of lat/lng if success, otherwise false
|
||||
*/
|
||||
public function get_exif_gps() {
|
||||
return $this->_exif ? $this->_exif->get_gps() : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the exif data (if the file is an image)
|
||||
* @return array array of exif info if success, otherwise false
|
||||
*/
|
||||
public function get_exif() {
|
||||
return $this->_exif ? $this->_exif->get_data() : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* is category
|
||||
* @param string $category test if the file is this category
|
||||
* @return boolean true if it is, otherwise false
|
||||
*/
|
||||
public function is($category) {
|
||||
return $category == $this->category;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the file info evaluated from the $name property
|
||||
* @return stdClass file info
|
||||
*/
|
||||
public function get_info($icon_prefix = 'octicon') {
|
||||
preg_match('/\.[^\.]+$/i', $this->name, $ext);
|
||||
preg_match('/\.\w+/i', isset($ext[0]) ? $ext[0] : '', $ext);
|
||||
|
||||
$return = new \stdClass;
|
||||
$extension = isset($ext[0]) ? $ext[0] : '';
|
||||
$category = "";
|
||||
switch (strtolower($extension)) {
|
||||
case '.pdf':
|
||||
case '.doc':
|
||||
case '.rtf':
|
||||
case '.txt':
|
||||
case '.docx':
|
||||
case '.xls':
|
||||
case '.xlsx':
|
||||
$category = 'document';
|
||||
break;
|
||||
case '.png':
|
||||
case '.jpg':
|
||||
case '.jpeg':
|
||||
case '.gif':
|
||||
case '.bmp':
|
||||
case '.psd':
|
||||
case '.tif':
|
||||
case '.tiff':
|
||||
$category = 'image';
|
||||
break;
|
||||
case '.mp3':
|
||||
case '.wav':
|
||||
case '.wma':
|
||||
case '.m4a':
|
||||
case '.m3u':
|
||||
$category = 'audio';
|
||||
break;
|
||||
case '.3g2':
|
||||
case '.3gp':
|
||||
case '.asf':
|
||||
case '.asx':
|
||||
case '.avi':
|
||||
case '.flv':
|
||||
case '.m4v':
|
||||
case '.mov':
|
||||
case '.mp4':
|
||||
case '.mpg':
|
||||
case '.srt':
|
||||
case '.swf':
|
||||
case '.vob':
|
||||
case '.wmv':
|
||||
$category = 'video';
|
||||
break;
|
||||
case '.css':
|
||||
case '.php':
|
||||
case '.php3':
|
||||
case '.sql':
|
||||
case '.cs':
|
||||
case '.html':
|
||||
case '.less':
|
||||
case '.xml':
|
||||
$category = 'code';
|
||||
break;
|
||||
case '.zip':
|
||||
case '.gzip':
|
||||
case '.7z':
|
||||
case '.tar':
|
||||
case '.rar':
|
||||
$category = 'compressed';
|
||||
break;
|
||||
default:
|
||||
$category = 'other';
|
||||
break;
|
||||
}
|
||||
|
||||
$return->extension = $extension;
|
||||
$return->category = $category;
|
||||
$return->type = isset($this->_mime_types[$extension]) ? $this->_mime_types[$extension] : 'application/octet-stream';
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
public function get_mime_type() {
|
||||
return mime_content_type($this->tmp_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* get base64_encode of the file
|
||||
* @return string base64 encoded string
|
||||
*/
|
||||
public function get_base64() {
|
||||
return base64_encode(file_get_contents($this->tmp_name));
|
||||
}
|
||||
|
||||
/**
|
||||
* format the size of the file to a readable string
|
||||
* @return string formatted file size
|
||||
*/
|
||||
public function format_size() {
|
||||
$bytes = $this->size;
|
||||
|
||||
if ($bytes >= 1073741824) {
|
||||
$format = number_format($bytes / 1073741824, 2) . ' GB';
|
||||
} elseif ($bytes >= 1048576) {
|
||||
$format = number_format($bytes / 1048576, 2) . ' MB';
|
||||
} elseif ($bytes >= 1024) {
|
||||
$format = number_format($bytes / 1024, 2) . ' KB';
|
||||
} elseif ($bytes > 1) {
|
||||
$format = $bytes . ' bytes';
|
||||
} elseif ($bytes == 1) {
|
||||
$format = $bytes . ' byte';
|
||||
} else {
|
||||
$format = '0 bytes';
|
||||
}
|
||||
|
||||
return $format;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
89
lib/common/Gravatar.php
Normal file
89
lib/common/Gravatar.php
Normal file
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
namespace Common;
|
||||
|
||||
class Gravatar {
|
||||
|
||||
const URL = 'https://www.gravatar.com';
|
||||
const RATING_G = 'g';
|
||||
const RATING_PG = 'pg';
|
||||
const RATING_R = 'r';
|
||||
const RATING_X = 'x';
|
||||
|
||||
// 404 | mm | identicon | monsterid | wavatar
|
||||
|
||||
const IMAGESET_MM = 'mm';
|
||||
const IMAGESET_404 = '404';
|
||||
const IMAGESET_IDENTICON = 'identicon';
|
||||
const IMAGESET_MONSTERID = 'monsterid';
|
||||
const IMAGESET_WAVATAR = 'wavatar';
|
||||
|
||||
private $_email = '';
|
||||
private $_properties = array();
|
||||
|
||||
function __construct($email, $s = 80, $d = self::IMAGESET_IDENTICON, $r = self::RATING_G) {
|
||||
$this->_email = $email;
|
||||
$this->_properties['hash'] = md5(strtolower(trim($email)));
|
||||
$this->_properties['imageset'] = $d;
|
||||
$this->_properties['size'] = $s;
|
||||
$this->_properties['rating'] = $r;
|
||||
}
|
||||
|
||||
function get_url() {
|
||||
$url = self::URL.'/avatar/'.$this->_properties['hash'];
|
||||
$url .= '?s='.$this->_properties['size'].'&d='.$this->_properties['imageset'].'&r='.$this->_properties['rating'];
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
function get_profile() {
|
||||
$str = @file_get_contents(self::URL.'/'.$this->_properties['hash'].'.php');
|
||||
$profile = unserialize($str);
|
||||
|
||||
return $profile ? $profile['entry'][0] : false;
|
||||
}
|
||||
|
||||
function get_img($attrs = array()) {
|
||||
$url = $this->get_url();
|
||||
$arr_attrs = array();
|
||||
foreach ($attrs as $key => $value) {
|
||||
$arr_attrs[] = $key.'="'.$value.'"';
|
||||
}
|
||||
|
||||
$result = '<img src="'.$url.'" '.implode(' ', $arr_attrs).' style="width: '.$this->_properties['size'].'px !important;" />';
|
||||
return $result;
|
||||
}
|
||||
|
||||
function __call($name, $args) {
|
||||
$call = explode('_', $name);
|
||||
if ($call) {
|
||||
$method = $call[0];
|
||||
$property = $call[1];
|
||||
|
||||
switch ($method) {
|
||||
case 'get':
|
||||
if (isset($this->_properties[$property])) {
|
||||
return $this->_properties[$property];
|
||||
} else if ($property == 'img') {
|
||||
$size = $call[2];
|
||||
$this->_properties['size'] = (int)$size;
|
||||
return $this->get_img(($args[0]) ? $args[0] : array());
|
||||
}
|
||||
|
||||
break;
|
||||
case 'set':
|
||||
if (isset($this->_properties[$property]) && $args) {
|
||||
$this->_properties[$property] = $args[0];
|
||||
return true;
|
||||
} else return false;
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
break;
|
||||
}
|
||||
|
||||
} else return null;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
141
lib/common/HTMLIndent.php
Normal file
141
lib/common/HTMLIndent.php
Normal file
@ -0,0 +1,141 @@
|
||||
<?php
|
||||
|
||||
namespace Common;
|
||||
|
||||
/**
|
||||
* @link https://github.com/gajus/dintent for the canonical source repository
|
||||
* @license https://github.com/gajus/dintent/blob/master/LICENSE BSD 3-Clause
|
||||
*/
|
||||
class HTMLIndent {
|
||||
private
|
||||
$log = array(),
|
||||
$indent = ' ',
|
||||
$temporary_replacements_script = array(),
|
||||
$temporary_replacements_inline = array();
|
||||
|
||||
const MATCH_INDENT_NO = 0;
|
||||
const MATCH_INDENT_DECREASE = 1;
|
||||
const MATCH_INDENT_INCREASE = 2;
|
||||
const MATCH_DISCARD = 3;
|
||||
|
||||
public function indent ($input) {
|
||||
$this->log = array();
|
||||
|
||||
// Dindent does not indent <script> body. Instead, it temporary removes it from the code, indents the input, and restores the script body.
|
||||
if (preg_match_all('/<script\b[^>]*>([\s\S]*?)<\/script>/mi', $input, $matches)) {
|
||||
$this->temporary_replacements_script = $matches[0];
|
||||
foreach ($matches[0] as $i => $match) {
|
||||
$input = str_replace($match, '<script>' . ($i + 1) . '</script>', $input);
|
||||
}
|
||||
}
|
||||
|
||||
// Removing double whitespaces to make the source code easier to read.
|
||||
// With exception of <pre>/ CSS white-space changing the default behaviour, double whitespace is meaningless in HTML output.
|
||||
// This reason alone is sufficient not to use Dindent in production.
|
||||
$input = str_replace("\t", '', $input);
|
||||
$input = preg_replace('/\s{2,}/', ' ', $input);
|
||||
|
||||
// Remove inline tags and replace them with text entities.
|
||||
if (preg_match_all('/<(b|i|abbr|em|strong|a|span)[^>]*>(?:[^<]*)<\/\1>/', $input, $matches)) {
|
||||
$this->temporary_replacements_inline = $matches[0];
|
||||
foreach ($matches[0] as $i => $match) {
|
||||
$input = str_replace($match, 'ᐃ' . ($i + 1) . 'ᐃ', $input);
|
||||
}
|
||||
}
|
||||
|
||||
$subject = $input;
|
||||
|
||||
$output = '';
|
||||
|
||||
$next_line_indentation_level = 0;
|
||||
|
||||
do {
|
||||
$indentation_level = $next_line_indentation_level;
|
||||
|
||||
$patterns = array(
|
||||
// block tag
|
||||
'/^(<([a-z]+)(?:[^>]*)>(?:[^<]*)<\/(?:\2)>)/' => static::MATCH_INDENT_NO,
|
||||
// DOCTYPE
|
||||
'/^<!([^>]*)>/' => static::MATCH_INDENT_NO,
|
||||
// tag with implied closing
|
||||
'/^<(input|link|meta|base|br|img|hr)([^>]*)>/' => static::MATCH_INDENT_NO,
|
||||
// opening tag
|
||||
'/^<[^\/]([^>]*)>/' => static::MATCH_INDENT_INCREASE,
|
||||
// closing tag
|
||||
'/^<\/([^>]*)>/' => static::MATCH_INDENT_DECREASE,
|
||||
// self-closing tag
|
||||
'/^<(.+)\/>/' => static::MATCH_INDENT_DECREASE,
|
||||
// whitespace
|
||||
'/^(\s+)/' => static::MATCH_DISCARD,
|
||||
// text node
|
||||
'/([^<]+)/' => static::MATCH_INDENT_NO
|
||||
);
|
||||
$rules = array('NO', 'DECREASE', 'INCREASE', 'DISCARD');
|
||||
|
||||
foreach ($patterns as $pattern => $rule) {
|
||||
if ($match = preg_match($pattern, $subject, $matches)) {
|
||||
$this->log[] = array(
|
||||
'rule' => $rules[$rule],
|
||||
'pattern' => $pattern,
|
||||
'subject' => $subject,
|
||||
'match' => $matches[0]
|
||||
);
|
||||
|
||||
$subject = mb_substr($subject, mb_strlen($matches[0]));
|
||||
|
||||
if ($rule === static::MATCH_DISCARD) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ($rule === static::MATCH_INDENT_NO) {
|
||||
|
||||
} else if ($rule === static::MATCH_INDENT_DECREASE) {
|
||||
$next_line_indentation_level--;
|
||||
$indentation_level--;
|
||||
} else {
|
||||
$next_line_indentation_level++;
|
||||
}
|
||||
|
||||
if ($indentation_level < 0) {
|
||||
$indentation_level = 0;
|
||||
}
|
||||
|
||||
#$output .= str_repeat($this->indent, $indentation_level) . 'A:' . $indentation_level . "\n";
|
||||
$output .= str_repeat($this->indent, $indentation_level) . $matches[0] . "\n";
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while ($match);
|
||||
|
||||
$interpreted_input = '';
|
||||
foreach ($this->log as $e) {
|
||||
$interpreted_input .= $e['match'];
|
||||
}
|
||||
|
||||
if ($interpreted_input !== $input) {
|
||||
throw new \RuntimeException('Did not reproduce the exact input.');
|
||||
}
|
||||
|
||||
$output = preg_replace('/(<(\w+)[^>]*>)\s*(<\/\2>)/', '\\1\\3', $output);
|
||||
|
||||
foreach ($this->temporary_replacements_script as $i => $original) {
|
||||
$output = str_replace('<script>' . ($i + 1) . '</script>', $original, $output);
|
||||
}
|
||||
|
||||
foreach ($this->temporary_replacements_inline as $i => $original) {
|
||||
$output = str_replace('ᐃ' . ($i + 1) . 'ᐃ', $original, $output);
|
||||
}
|
||||
|
||||
return trim($output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Debugging utility. Get log for the last indent operation.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getLog () {
|
||||
return $this->log;
|
||||
}
|
||||
}
|
||||
117
lib/common/Upload.php
Normal file
117
lib/common/Upload.php
Normal file
@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
namespace Common;
|
||||
|
||||
/**
|
||||
* @package FileUpload Class in PHP5
|
||||
* @author Jovanni Lo
|
||||
* @link http://www.lodev09.com
|
||||
* @copyright 2014 Jovanni Lo, all rights reserved
|
||||
* @license
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2014 Jovanni Lo
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
class Upload {
|
||||
|
||||
/**
|
||||
* files array for mutliple
|
||||
* @var array
|
||||
*/
|
||||
public $files = array();
|
||||
|
||||
/**
|
||||
* file for single
|
||||
* @var [type]
|
||||
*/
|
||||
public $file;
|
||||
|
||||
/**
|
||||
* raw data of the file upload
|
||||
* @var [type]
|
||||
*/
|
||||
private $_raw;
|
||||
|
||||
/**
|
||||
* construct the class
|
||||
* @param array $files_data data from $_FILES['name']
|
||||
* @param array $validations validation array
|
||||
*/
|
||||
public function __construct($files_data, $validations = array()) {
|
||||
$this->_raw = $files_data;
|
||||
if ($this->_raw ) {
|
||||
// check if it's multiple or single file upload
|
||||
if ($this->_is_multiple()) {
|
||||
foreach ($this->_raw["error"] as $key => $error) {
|
||||
$file_info = new \stdClass;
|
||||
$file_info->name = $this->_raw['name'][$key];
|
||||
$file_info->type = $this->_raw['type'][$key];
|
||||
$file_info->tmp_name = $this->_raw['tmp_name'][$key];
|
||||
$file_info->error = $error;
|
||||
$file_info->size = $this->_raw['size'][$key];
|
||||
|
||||
$file = new File($file_info, $validations);
|
||||
$this->files[] = $file;
|
||||
}
|
||||
// let the single "file" property be the first file (index 0)
|
||||
if ($this->files) $this->file = $this->files[0];
|
||||
} else {
|
||||
$file_info = new \stdClass;
|
||||
foreach ($this->_raw as $key => $value) {
|
||||
$file_info->{$key} = $value;
|
||||
}
|
||||
$file = new File($file_info, $validations);
|
||||
$this->files[] = $file;
|
||||
$this->file = $this->files[0];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* loop through each file
|
||||
* @param closure $callback callback function for each file
|
||||
*/
|
||||
public function each($callback) {
|
||||
if (!$this->_is_closure($callback)) return;
|
||||
foreach ($this->files as $file) {
|
||||
$callback($file);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check if the upload data is multiple or not
|
||||
* @return boolean true if multiple, otherwise false
|
||||
*/
|
||||
private function _is_multiple() {
|
||||
return is_array($this->_raw["name"]);
|
||||
}
|
||||
|
||||
/**
|
||||
* check if a value is a closure object
|
||||
* @param object $obj object to test
|
||||
* @return boolean true if it's a closure object, otherwise false
|
||||
*/
|
||||
private function _is_closure($obj) {
|
||||
return (is_object($obj) && ($obj instanceof \Closure));
|
||||
}
|
||||
}
|
||||
?>
|
||||
1042
lib/common/Util.php
Normal file
1042
lib/common/Util.php
Normal file
File diff suppressed because it is too large
Load Diff
10
lib/config.php
Normal file
10
lib/config.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
// configure database connection
|
||||
|
||||
defined("DB_HOST") ? null : define("DB_HOST", "127.0.0.1");
|
||||
defined("DB_USER") ? null : define("DB_USER", "root");
|
||||
defined("DB_PASSWORD") ? null : define("DB_PASSWORD", "root_password");
|
||||
defined("DB_NAME") ? null : define("DB_NAME", "db");
|
||||
|
||||
?>
|
||||
27
lib/func.php
Normal file
27
lib/func.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
function debug($msg, $options = null, $return = false) {
|
||||
return \Common\Util::debug($msg, $options, $return);
|
||||
}
|
||||
|
||||
function plog($msg, $return = false) {
|
||||
return \Common\Util::debug($msg, array('dismiss' => false), $return);
|
||||
}
|
||||
|
||||
function clog($msg, $newline = true, $return = false) {
|
||||
return \Common\Util::debug($msg, array('newline' => $newline, 'dismiss' => false), $return);
|
||||
}
|
||||
|
||||
function get($field, $data = null, $default = null) {
|
||||
return \Common\Util::get($field, $data, $default);
|
||||
}
|
||||
|
||||
function br2nl($text) {
|
||||
return \Common\Util::br2nl($text);
|
||||
}
|
||||
|
||||
function array_delete($array, $items) {
|
||||
return array_diff($array, is_array($items) ? $items : array($items));
|
||||
}
|
||||
|
||||
?>
|
||||
155
lib/smartui/Components/Accordion.php
Normal file
155
lib/smartui/Components/Accordion.php
Normal file
@ -0,0 +1,155 @@
|
||||
<?php
|
||||
|
||||
namespace SmartUI\Components;
|
||||
use \SmartUI\UI;
|
||||
use \SmartUI\Util;
|
||||
|
||||
class Accordion extends UI {
|
||||
|
||||
private $_options_map = array(
|
||||
'global_icons' => array()
|
||||
);
|
||||
|
||||
private $_structure = array(
|
||||
'panel' => array(),
|
||||
'id' => '',
|
||||
'header' => array(),
|
||||
'content' => array(),
|
||||
'expand' => array(),
|
||||
'padding' => array(),
|
||||
'icons' => array(),
|
||||
'options' => array()
|
||||
);
|
||||
|
||||
public function __construct($panels, $options = array()) {
|
||||
$this->_options_map['global_icons'] = array(parent::$icon_source.'-lg '.parent::$icon_source.'-chevron-down pull-right', ''.parent::$icon_source.'-lg '.parent::$icon_source.'-chevron-up pull-right');
|
||||
$this->_init_structure($panels, $options);
|
||||
}
|
||||
|
||||
private function _init_structure($panels, $user_options = array()) {
|
||||
$this->_structure = Util::array_to_object($this->_structure);
|
||||
$this->_structure->options = Util::set_array_prop_def($this->_options_map, $user_options);
|
||||
$this->_structure->id = Util::create_id(true);
|
||||
$this->_structure->panel = $panels;
|
||||
}
|
||||
|
||||
public function __get($name) {
|
||||
if (isset($this->_structure->{$name})) {
|
||||
return $this->_structure->{$name};
|
||||
}
|
||||
parent::err('Undefined structure property: '.$name);
|
||||
return null;
|
||||
}
|
||||
|
||||
public function __set($name, $value) {
|
||||
if (isset($this->_structure->{$name})) {
|
||||
$this->_structure->{$name} = $value;
|
||||
return;
|
||||
}
|
||||
parent::err('Undefined structure property: '.$name);
|
||||
}
|
||||
|
||||
public function __call($name, $args) {
|
||||
return parent::_call($this, $this->_structure, $name, $args);
|
||||
}
|
||||
|
||||
public function print_html($return = false) {
|
||||
$structure = $this->_structure;
|
||||
|
||||
$panels = Util::get_property_value($structure->panel, array(
|
||||
'if_closure' => function($panels) {
|
||||
return Util::run_callback($panels, array($this));
|
||||
},
|
||||
'if_other' => function($panels) {
|
||||
parent::err('parent::Accordion:panel requires array');
|
||||
return null;
|
||||
}
|
||||
));
|
||||
|
||||
if (!is_array($panels)) {
|
||||
parent::err("parent::Accordion:panel requires array");
|
||||
return null;
|
||||
}
|
||||
|
||||
$panel_html_list = array();
|
||||
foreach ($panels as $panel_id => $panel_prop) {
|
||||
|
||||
$panel_structure = array(
|
||||
'header' => isset($structure->header[$panel_id]) ? $structure->header[$panel_id] : '',
|
||||
'content' => isset($structure->content[$panel_id]) ? $structure->content[$panel_id] : '',
|
||||
'expand' => isset($structure->expand[$panel_id]) ? $structure->expand[$panel_id] : false,
|
||||
'padding' => isset($structure->padding[$panel_id]) ? $structure->padding[$panel_id] : null,
|
||||
);
|
||||
|
||||
$new_panel_prop = Util::get_clean_structure($panel_structure, $panel_prop, array($this, $panels), 'header');
|
||||
|
||||
foreach ($new_panel_prop as $panel_prop_key => $panel_prop_vaue) {
|
||||
$new_panel_prop_value = Util::get_property_value($panel_prop_vaue, array(
|
||||
'if_closure' => function($prop_value) use ($panels) {
|
||||
return Util::run_callback($prop_value, array($this, $panels));
|
||||
}
|
||||
));
|
||||
$new_panel_prop[$panel_prop_key] = $new_panel_prop_value;
|
||||
}
|
||||
|
||||
// header
|
||||
$header_structure = array(
|
||||
'content' => '',
|
||||
'container' => 'h4',
|
||||
'icons' => isset($structure->icons[$panel_id]) ? $structure->icons[$panel_id] : $structure->options['global_icons']
|
||||
);
|
||||
$new_header_prop = Util::get_clean_structure($header_structure, $new_panel_prop['header'], array($this, $panels), 'content');
|
||||
|
||||
$a_classes = array();
|
||||
if (!$new_panel_prop['expand']) $a_classes[] = 'collapsed';
|
||||
|
||||
$a_attr = array();
|
||||
$a_attr[] = 'data-parent="#'.$structure->id.'"';
|
||||
$a_attr[] = 'href="#'.$panel_id.'"';
|
||||
$a_attr[] = 'data-toggle="collapse"';
|
||||
|
||||
$icons = is_array($new_header_prop['icons']) ? implode(' ', array_map(function($icon){
|
||||
return '<i class="'.parent::$icon_source.' '.$icon.'"></i> ';
|
||||
}, $new_header_prop['icons'])) : $new_header_prop['icons'];
|
||||
|
||||
$body_classes = array();
|
||||
$body_classes[] = 'panel-body';
|
||||
|
||||
if (isset($new_panel_prop['padding'])) {
|
||||
$body_classes[] = $new_panel_prop['padding'] ? 'padding-'.$new_panel_prop['padding'] : 'no-padding';
|
||||
}
|
||||
|
||||
|
||||
$panel_html = '<div class="panel panel-default">';
|
||||
$panel_html .= ' <div class="panel-heading">';
|
||||
$panel_html .= ' <'.$new_header_prop['container'].' class="panel-title">';
|
||||
|
||||
$panel_html .= ' <a '.implode(' ', $a_attr).' class="'.implode(' ', $a_classes).'"> ';
|
||||
$panel_html .= $icons;
|
||||
$panel_html .= $new_header_prop['content'];
|
||||
$panel_html .= ' </a>';
|
||||
|
||||
$panel_html .= ' </'.$new_header_prop['container'].'>';
|
||||
$panel_html .= ' </div>';
|
||||
|
||||
$panel_html .= ' <div id="'.$panel_id.'" class="panel-collapse collapse '.($new_panel_prop['expand'] ? 'in' : '').'">';
|
||||
$panel_html .= ' <div class="'.implode(' ', $body_classes).'">';
|
||||
$panel_html .= $new_panel_prop['content'];
|
||||
$panel_html .= ' </div>';
|
||||
$panel_html .= ' </div>';
|
||||
$panel_html .= '</div>';
|
||||
|
||||
$panel_html_list[] = $panel_html;
|
||||
}
|
||||
|
||||
|
||||
$result = '<div class="panel-group smart-accordion-default" id="'.$structure->id.'">';
|
||||
$result .= implode('', $panel_html_list);
|
||||
$result .= '</div>';
|
||||
|
||||
if ($return) return $result;
|
||||
else echo $result;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
241
lib/smartui/Components/Button.php
Normal file
241
lib/smartui/Components/Button.php
Normal file
@ -0,0 +1,241 @@
|
||||
<?php
|
||||
|
||||
namespace SmartUI\Components;
|
||||
use \SmartUI\UI;
|
||||
use \SmartUI\Util;
|
||||
|
||||
class Button extends UI {
|
||||
|
||||
const BUTTON_CONTAINER_ANCHOR = 'a';
|
||||
const BUTTON_CONTAINER_BUTTON = 'button';
|
||||
|
||||
const BUTTON_SIZE_LARGE = 'lg';
|
||||
const BUTTON_SIZE_SMALL = 'sm';
|
||||
const BUTTON_SIZE_XSMALL = 'xs';
|
||||
const BUTTON_SIZE_MEDIUM = 'md';
|
||||
|
||||
private $_options_map = array(
|
||||
'disabled' => false,
|
||||
'labeled' => false
|
||||
);
|
||||
|
||||
private $_structure = array(
|
||||
'options' => array(),
|
||||
'content' => '',
|
||||
'icon' => '',
|
||||
'type' => '',
|
||||
'container' => self::BUTTON_CONTAINER_BUTTON,
|
||||
'size' => self::BUTTON_SIZE_MEDIUM,
|
||||
'attr' => array(),
|
||||
'id' => '',
|
||||
'class' => '',
|
||||
'dropdown' => array()
|
||||
);
|
||||
|
||||
public function __construct($content = '', $type = 'default', $options = array()) {
|
||||
$this->_init_structure($type, $content, $options);
|
||||
}
|
||||
|
||||
private function _init_structure($type, $content, $user_options) {
|
||||
$this->_structure = Util::array_to_object($this->_structure);
|
||||
$this->_structure->type = $type;
|
||||
$this->_structure->content = $content;
|
||||
$this->_structure->options = Util::set_array_prop_def($this->_options_map, $user_options);
|
||||
|
||||
}
|
||||
|
||||
public function __call($name, $args) {
|
||||
return parent::_call($this, $this->_structure, $name, $args);
|
||||
}
|
||||
|
||||
public function __set($name, $value) {
|
||||
if (isset($this->_structure->{$name})) {
|
||||
$this->_structure->{$name} = $value;
|
||||
return;
|
||||
}
|
||||
parent::err('Undefined structure property: '.$name);
|
||||
}
|
||||
|
||||
public function __get($name) {
|
||||
if (isset($this->_structure->{$name})) {
|
||||
return $this->_structure->{$name};
|
||||
}
|
||||
parent::err('Undefined structure property: '.$name);
|
||||
return null;
|
||||
}
|
||||
|
||||
public function print_html($return = false) {
|
||||
|
||||
|
||||
$structure = $this->_structure;
|
||||
|
||||
$icon = Util::get_property_value($structure->icon, array(
|
||||
'if_closure' => function($icon) { return Util::run_callback($icon, array($this)); },
|
||||
'if_array' => function($icon) {
|
||||
parent::err('parent::Widget::icon requires string.');
|
||||
return '';
|
||||
}
|
||||
));
|
||||
|
||||
$container = Util::get_property_value($structure->container, array(
|
||||
'if_closure' => function($container) { return Util::run_callback($container, array($this)); },
|
||||
'if_array' => function($container) {
|
||||
parent::err('parent::Widget::container requires string.');
|
||||
return '';
|
||||
}
|
||||
));
|
||||
|
||||
$content = Util::get_property_value($structure->content, array(
|
||||
'if_closure' => function($content) { return Util::run_callback($content, array($this)); },
|
||||
'if_array' => function($content) {
|
||||
parent::err('parent::Widget::content requires string.');
|
||||
return '';
|
||||
}
|
||||
));
|
||||
|
||||
$attr = Util::get_property_value($structure->attr, array(
|
||||
'if_closure' => function($attr) {
|
||||
$callback_return = Util::run_callback($attr, $array($this));
|
||||
if (is_array($callback_return)) return $callback_return;
|
||||
else return array($callback_return);
|
||||
},
|
||||
'if_array' => function($attr) {
|
||||
$attrs = array();
|
||||
foreach ($attr as $key => $value) {
|
||||
$attrs[] = $key.'="'.$value.'"';
|
||||
}
|
||||
|
||||
return $attrs;
|
||||
},
|
||||
'if_other' => function($attr) {
|
||||
return array($attr);
|
||||
}
|
||||
));
|
||||
|
||||
$class = Util::get_property_value($structure->class, array(
|
||||
"if_closure" => function($class) { return Util::run_callback($class, array($this)); },
|
||||
"if_array" => function($class) {
|
||||
return implode(' ', $class);
|
||||
}
|
||||
));
|
||||
|
||||
$type = Util::get_property_value($structure->type, array(
|
||||
'if_array' => function($class) {
|
||||
parent::err('parent::Button:type requires string.');
|
||||
return parent::BUTTON_TYPE_DEFAULT;
|
||||
}
|
||||
));
|
||||
|
||||
$classes = array();
|
||||
|
||||
// labeled and icon
|
||||
|
||||
if (trim($icon)) {
|
||||
$icon = '<i class="'.parent::$icon_source.' '.$icon.'"></i>';
|
||||
if ($structure->options['labeled']) {
|
||||
$classes[] = 'btn-labeled';
|
||||
$icon = $structure->options['labeled'] ? '<span class="btn-label">'.$icon.'</span>' : $icon;
|
||||
}
|
||||
|
||||
$content = $icon.' '.$content;
|
||||
}
|
||||
|
||||
// custom class
|
||||
if ($class) $classes[] = $class;
|
||||
|
||||
// size
|
||||
$size_class = '';
|
||||
if ($structure->size) {
|
||||
$size_class = 'btn-'.$structure->size;
|
||||
$classes[] = $size_class;
|
||||
}
|
||||
// disabled
|
||||
$disabled = $structure->options['disabled'] ? 'disabled' : '';
|
||||
$classes[] = $disabled;
|
||||
|
||||
$class_htm = $classes ? ' '.implode(' ', $classes) : '';
|
||||
|
||||
$result = '';
|
||||
|
||||
if ($structure->id) $attr[] = 'id="'.$structure->id.'"';
|
||||
if ($structure->dropdown) {
|
||||
$dd_prop = array(
|
||||
'items' => array(),
|
||||
'multilevel' => false,
|
||||
'split' => false,
|
||||
'attr' => array(),
|
||||
'class' => '',
|
||||
'id' => ''
|
||||
);
|
||||
|
||||
$new_dd_prop = Util::get_clean_structure($dd_prop, $structure->dropdown, array($this), 'items');
|
||||
|
||||
if (is_array($new_dd_prop['items'])) {
|
||||
$dropdown_html = parent::print_dropdown($new_dd_prop['items'], array(
|
||||
'multilevel' => $new_dd_prop['multilevel'],
|
||||
'class' => $new_dd_prop['class'],
|
||||
'attr' => $new_dd_prop['attr'],
|
||||
'id' => $new_dd_prop['id']
|
||||
), true);
|
||||
} else {
|
||||
$dropdown_html = $new_dd_prop['items'];
|
||||
}
|
||||
|
||||
if ($new_dd_prop['split']) {
|
||||
$split_prop = array(
|
||||
'type' => $type,
|
||||
'disabled' => false,
|
||||
'dropup' => false,
|
||||
'class' => array(),
|
||||
'attr' => array()
|
||||
);
|
||||
|
||||
$new_split_prop = Util::get_clean_structure($split_prop, $new_dd_prop['split'], array($this, $new_dd_prop), 'type');
|
||||
|
||||
$split_attrs = array();
|
||||
if (is_array($new_split_prop['attr'])) {
|
||||
foreach ($new_split_prop['attr'] as $split_attr => $value) {
|
||||
$split_attrs[] = $split_attr.'="'.$value.'"';
|
||||
}
|
||||
} else {
|
||||
$split_attrs[] = $new_split_prop['attr'];
|
||||
}
|
||||
|
||||
$split_classes = array();
|
||||
if (is_array($new_split_prop['class'])) $split_classes[] = implode(' ', $new_split_prop['class']);
|
||||
else $split_classes[] = $new_split_prop['class'];
|
||||
|
||||
$split_classes[] = $size_class;
|
||||
$split_class_htm = $split_classes ? ' '.implode(' ', $split_classes) : '';
|
||||
|
||||
$btn_main = '<'.$container.' class="btn btn-'.$type.$class_htm.'" '.implode(' ', $attr).'>';
|
||||
$btn_main .= $content;
|
||||
$btn_main .= '</'.$container.'>';
|
||||
|
||||
$btn_dd = '<'.$container.' class="btn btn-'.$new_split_prop['type'].$split_class_htm.' dropdown-toggle" data-toggle="dropdown" '.implode(' ', $split_attrs).'>';
|
||||
$btn_dd .= '<span class="caret"></span>';
|
||||
$btn_dd .= '</'.$container.'>';
|
||||
$btn_dd .= $dropdown_html;
|
||||
|
||||
$result .= '<div class="btn-group'.($new_split_prop['dropup'] ? ' dropup' : '').'">'.$btn_main.$btn_dd.'</div>';
|
||||
} else {
|
||||
$result .= '<div class="dropdown">';
|
||||
$result .= '<'.$container.' class="btn btn-'.$type.$class_htm.' dropdown-toggle" '.implode(' ', $attr).' data-toggle="dropdown">';
|
||||
$result .= $content.' <span class="caret"></span>';
|
||||
$result .= '</'.$container.'>';
|
||||
$result .= $dropdown_html;
|
||||
$result .= '</div>';
|
||||
}
|
||||
|
||||
} else {
|
||||
$result .= '<'.$container.' class="btn btn-'.$type.$class_htm.'" '.implode(' ', $attr).'>';
|
||||
$result .= $content;
|
||||
$result .= '</'.$container.'>';
|
||||
}
|
||||
|
||||
if ($return) return $result;
|
||||
else echo $result;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
148
lib/smartui/Components/Carousel.php
Normal file
148
lib/smartui/Components/Carousel.php
Normal file
@ -0,0 +1,148 @@
|
||||
<?php
|
||||
|
||||
namespace SmartUI\Components;
|
||||
use \SmartUI\UI;
|
||||
use \SmartUI\Util;
|
||||
|
||||
class Carousel extends UI {
|
||||
|
||||
private $_options_map = array(
|
||||
'style' => 'slide',
|
||||
'controls' => array('<span class="glyphicon glyphicon-chevron-left"></span>', '<span class="glyphicon glyphicon-chevron-right"></span>')
|
||||
);
|
||||
|
||||
private $_structure = array(
|
||||
'item' => array(),
|
||||
'id' => '',
|
||||
'active' => array(),
|
||||
'caption' => array(),
|
||||
'img' => array(),
|
||||
'options' => array()
|
||||
);
|
||||
|
||||
public function __construct($items, $style='slide', $options = array()) {
|
||||
$this->_init_structure($items, $style, $options);
|
||||
}
|
||||
|
||||
private function _init_structure($items, $style='slide', $user_options = array()) {
|
||||
$this->_structure = Util::array_to_object($this->_structure);
|
||||
$this->_structure->options = Util::set_array_prop_def($this->_options_map, $user_options);
|
||||
$this->_structure->id = Util::create_id(true);
|
||||
$this->_structure->item = $items;
|
||||
$this->_structure->options['style'] = $style;
|
||||
}
|
||||
|
||||
public function __get($name) {
|
||||
if (isset($this->_structure->{$name})) {
|
||||
return $this->_structure->{$name};
|
||||
}
|
||||
parent::err('Undefined structure property: '.$name);
|
||||
return null;
|
||||
}
|
||||
|
||||
public function __set($name, $value) {
|
||||
if (isset($this->_structure->{$name})) {
|
||||
$this->_structure->{$name} = $value;
|
||||
return;
|
||||
}
|
||||
parent::err('Undefined structure property: '.$name);
|
||||
}
|
||||
|
||||
public function __call($name, $args) {
|
||||
return parent::_call($this, $this->_structure, $name, $args);
|
||||
}
|
||||
|
||||
public function print_html($return = false) {
|
||||
|
||||
|
||||
$structure = $this->_structure;
|
||||
|
||||
$items = Util::get_property_value($structure->item, array(
|
||||
'if_closure' => function($items) {
|
||||
return Util::run_callback($items, array($this));
|
||||
},
|
||||
'if_other' => function($items) {
|
||||
parent::err('parent::Carousel:item requires array');
|
||||
return null;
|
||||
}
|
||||
));
|
||||
|
||||
if (!is_array($items)) {
|
||||
parent::err("parent::Carousel:item requires array");
|
||||
return null;
|
||||
}
|
||||
|
||||
$indicators_list = array();
|
||||
$items_list = array();
|
||||
$has_active = false;
|
||||
$index = 0;
|
||||
foreach ($items as $item_key => $item) {
|
||||
$item_structure = array(
|
||||
'img' => isset($structure->img[$item_key]) ? $structure->img[$item_key] : '',
|
||||
'caption' => isset($structure->caption[$item_key]) ? $structure->caption[$item_key] : '',
|
||||
'active' => isset($structure->active[$item_key]) ? $structure->active[$item_key] : '',
|
||||
);
|
||||
|
||||
$new_item_prop = Util::get_clean_structure($item_structure, $item, array($this, $items), 'img');
|
||||
|
||||
foreach ($new_item_prop as $tab_item_key => $item_prop_value) {
|
||||
$new_item_prop_value = Util::get_property_value($item_prop_value, array(
|
||||
'if_closure' => function($prop_value) use ($items) {
|
||||
return Util::run_callback($prop_value, array($this, $items));
|
||||
}
|
||||
));
|
||||
$new_item_prop[$tab_item_key] = $new_item_prop_value;
|
||||
}
|
||||
|
||||
$image_prop = array('src' => '', 'alt' => '');
|
||||
$new_image_prop = Util::get_clean_structure($image_prop, $new_item_prop['img'], array($this, $items, $new_item_prop), 'src');
|
||||
|
||||
$indicator_classes = array();
|
||||
$item_classes = array();
|
||||
$item_classes[] = 'item';
|
||||
if ((!$structure->active && !$has_active) || ($new_item_prop['active'] === true && !$has_active)) {
|
||||
$has_active = true;
|
||||
$indicator_classes[] = 'active';
|
||||
$item_classes[] = 'active';
|
||||
}
|
||||
|
||||
$indicators_list[] = '<li data-target="#'.$structure->id.'" data-slide-to="'.$index.'" class="'.implode(' ', $indicator_classes).'"></li>';
|
||||
|
||||
$item_html = '<div class="'.implode(' ', $item_classes).'">';
|
||||
$item_html .= ' <img src="'.$new_image_prop['src'].'" alt="'.$new_image_prop['alt'].'">';
|
||||
$item_html .= ' <div class="carousel-caption">';
|
||||
$item_html .= $new_item_prop['caption'];
|
||||
$item_html .= ' </div>';
|
||||
$item_html .= '</div>';
|
||||
$items_list[] = $item_html;
|
||||
|
||||
|
||||
$index++;
|
||||
}
|
||||
$controls_html = '';
|
||||
if (($structure->options['controls'])) {
|
||||
$controls_html .= ' <a class="left carousel-control" href="#'.$structure->id.'" data-slide="prev">';
|
||||
$controls_html .= $structure->options['controls'][0];
|
||||
$controls_html .= ' </a>';
|
||||
$controls_html .= ' <a class="right carousel-control" href="#'.$structure->id.'" data-slide="next">';
|
||||
$controls_html .= $structure->options['controls'][1];
|
||||
$controls_html .= ' </a>';
|
||||
}
|
||||
|
||||
$result = '<div id="'.$structure->id.'" class="carousel '.$structure->options['style'].'">';
|
||||
$result .= ' <ol class="carousel-indicators">';
|
||||
$result .= implode('', $indicators_list);
|
||||
$result .= ' </ol>';
|
||||
$result .= ' <div class="carousel-inner">';
|
||||
$result .= implode('', $items_list);
|
||||
$result .= ' </div>';
|
||||
$result .= $controls_html;
|
||||
$result .= '</div>';
|
||||
|
||||
if ($return) return $result;
|
||||
else echo $result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
704
lib/smartui/Components/DataTable.php
Normal file
704
lib/smartui/Components/DataTable.php
Normal file
@ -0,0 +1,704 @@
|
||||
<?php
|
||||
|
||||
namespace SmartUI\Components;
|
||||
use \SmartUI\UI;
|
||||
use \SmartUI\Util;
|
||||
|
||||
class DataTable extends UI {
|
||||
|
||||
private $_options_map = array(
|
||||
"in_widget" => true,
|
||||
"row_details" => false,
|
||||
"row_details_opened" => false,
|
||||
"row_detail_icons" => array('closed' => 'chevron-right', 'opened' => 'chevron-down'),
|
||||
"checkboxes" => false,
|
||||
"static" => false,
|
||||
"paginate" => true,
|
||||
"columns" => true,
|
||||
"table" => true,
|
||||
"striped" => true,
|
||||
"bordered" => true,
|
||||
"hover" => true,
|
||||
"condensed" => false,
|
||||
"forum" => false,
|
||||
"default_col" => "No Data"
|
||||
);
|
||||
|
||||
private $_structure = array(
|
||||
"cell" => array(),
|
||||
"col" => array(),
|
||||
"options" => array(),
|
||||
"data" => array(),
|
||||
"widget" => null,
|
||||
"each" => array(),
|
||||
"id" => "",
|
||||
"row" => array(),
|
||||
"hidden" => array(),
|
||||
"hide" => array(),
|
||||
"js" => array(),
|
||||
"sort" => array(),
|
||||
"toolbar" => array(),
|
||||
"class" => array()
|
||||
);
|
||||
|
||||
private $_uid = '';
|
||||
|
||||
private $_data = array();
|
||||
|
||||
private $_cells_map = array();
|
||||
private $_cols_map = array();
|
||||
private $_hide_map = array();
|
||||
|
||||
public function __construct($data, $options = array(), $widget_title = '<h2>DataTable Result Set</h2>', $widget_icon = 'table') {
|
||||
$this->_init_structure($data, $options, $widget_title, $widget_icon);
|
||||
}
|
||||
|
||||
private function _init_structure($data, $user_options, $widget_title, $widget_icon) {
|
||||
$this->_structure = Util::array_to_object($this->_structure);
|
||||
$this->_structure->data = $data;
|
||||
$this->_structure->options = Util::set_array_prop_def($this->_options_map, $user_options);
|
||||
$uid = Util::create_id(true);
|
||||
$this->_structure->id = $uid; // set the id as default id
|
||||
$this->_uid = $uid;
|
||||
$this->_structure->widget = new Widget();
|
||||
$this->_structure->widget
|
||||
->header('title', $widget_title)
|
||||
->body("class", "no-padding")
|
||||
->body("editbox", '<input class="form-control" type="text">
|
||||
<span class="note"><i class="'.parent::$icon_source.' '.parent::$icon_source.'-check text-success"></i> Change title to update and save instantly!</span>');
|
||||
|
||||
if ($widget_icon) $this->_structure->widget->header('icon', parent::$icon_source.'-'.$widget_icon);
|
||||
|
||||
if (!$this->_structure->data) {
|
||||
$col_list = $this->_structure->options["default_col"] ? array($this->_structure->options["default_col"]) : array();
|
||||
} else {
|
||||
$col_list = array_keys(is_object($data[0]) ? get_object_vars($data[0]) : $data[0]);
|
||||
}
|
||||
|
||||
$cols = array_combine($col_list, $col_list);
|
||||
$cells = array_fill_keys($col_list, array());
|
||||
$hide = array_fill_keys($col_list, false);
|
||||
|
||||
$this->_cells_map = $cells;
|
||||
$this->_cols_map = $cols;
|
||||
$this->_hide_map = $hide;
|
||||
|
||||
$this->_structure->col = $cols;
|
||||
$this->_structure->cell = $cells;
|
||||
$this->_structure->hide = $hide;
|
||||
$this->_structure->row = array_fill(1, count($data) + 1, array());
|
||||
|
||||
$this->_structure->js = array(
|
||||
"properties" => array(),
|
||||
"oTable" => 'oTable_'.$this->_uid,
|
||||
"custom" => ""
|
||||
);
|
||||
}
|
||||
|
||||
public function rows() {
|
||||
return count($this->_structure->row);
|
||||
}
|
||||
|
||||
public function __get($name) {
|
||||
if (isset($this->_structure->{$name})) {
|
||||
return $this->_structure->{$name};
|
||||
}
|
||||
parent::err('Undefined structure property: '.$name);
|
||||
return null;
|
||||
}
|
||||
|
||||
public function __set($name, $value) {
|
||||
if (isset($this->_structure->{$name})) {
|
||||
$this->_structure->{$name} = $value;
|
||||
return;
|
||||
}
|
||||
parent::err('Undefined structure property: '.$name);
|
||||
}
|
||||
|
||||
public function __call($name, $args) {
|
||||
return parent::_call($this, $this->_structure, $name, $args);
|
||||
}
|
||||
|
||||
|
||||
public function is_with_details() {
|
||||
return isset($this->_structure->options["row_details"]) && $this->_structure->options["row_details"];
|
||||
}
|
||||
|
||||
public function is_with_checkboxes() {
|
||||
return isset($this->_structure->options["checkboxes"]) && $this->_structure->options["checkboxes"];
|
||||
}
|
||||
|
||||
public function print_js($return = false, $jquery_enclosed = true) {
|
||||
$structure = $this->_structure;
|
||||
$table_id = $structure->id;
|
||||
|
||||
$dtable_js = '';
|
||||
|
||||
if ($structure->options["static"]) {
|
||||
if ($structure->options['row_details_opened']) {
|
||||
$row_detail_code = Util::is_closure($structure->options['row_details_opened']) ? $structure->options['row_details_opened']($table_id) : $structure->options['row_details_opened'];
|
||||
} else {
|
||||
$row_detail_code = 'nTr.after("<tr class=\"details\"><td class=\"details\" colspan='.count($structure->col).'>" + value + "</td></tr>");';
|
||||
}
|
||||
$dtable_js = '
|
||||
function fnFormatDetails (nTr ) {
|
||||
var aData = nTr.find("td").map(function() {
|
||||
return $(this).html();
|
||||
}).get();
|
||||
|
||||
'.($this->is_with_details() ? $this->_get_detail_content($structure->options["row_details"], array_keys($structure->col)) : '').'
|
||||
}
|
||||
|
||||
$("#'.$table_id.' a i[data-toggle=\'row-detail\']").on("click", function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
var nTr = $(this).parents("tr"),
|
||||
details = nTr.nextUntil(":not(.details)", ".details");
|
||||
|
||||
if (details.length > 0) {
|
||||
/* This row is already open - close it */
|
||||
$(this).removeClass("'.parent::$icon_source.'-'.$this->options['row_detail_icons']['opened'].'").addClass("'.parent::$icon_source.'-'.$this->options['row_detail_icons']['closed'].'");
|
||||
this.title = "Show Details";
|
||||
|
||||
details.remove();
|
||||
} else {
|
||||
/* Open this row */
|
||||
$(this).removeClass("'.parent::$icon_source.'-'.$this->options['row_detail_icons']['closed'].'").addClass("'.parent::$icon_source.'-'.$this->options['row_detail_icons']['opened'].'");
|
||||
this.title = "Hide Details";
|
||||
var value = fnFormatDetails(nTr);
|
||||
'.$row_detail_code.'
|
||||
}
|
||||
});
|
||||
';
|
||||
} else {
|
||||
$otable_var = $structure->js["oTable"];
|
||||
|
||||
$dtable_js = '
|
||||
$(".desktop[data-rel=\'tooltip\']").tooltip();
|
||||
$(".phone[data-rel=\'tooltip\']").tooltip({placement: tooltip_placement});
|
||||
function tooltip_placement(context, source) {
|
||||
var $source = $(source);
|
||||
var $parent = $source.closest("table")
|
||||
var off1 = $parent.offset();
|
||||
var w1 = $parent.width();
|
||||
|
||||
var off2 = $source.offset();
|
||||
var w2 = $source.width();
|
||||
|
||||
if( parseInt(off2.left) < parseInt(off1.left) + parseInt(w1 / 2) ) return "right";
|
||||
return "left";
|
||||
}
|
||||
|
||||
$("#'.$table_id.' a i[data-toggle=\'row-detail\']").on("click", function () {
|
||||
var nTr = $(this).parents("tr")[0];
|
||||
if ( '.$otable_var.'.fnIsOpen(nTr) )
|
||||
{
|
||||
/* This row is already open - close it */
|
||||
$(this).removeClass("'.parent::$icon_source.'-'.$this->options['row_detail_icons']['opened'].'").addClass("'.parent::$icon_source.'-'.$this->options['row_detail_icons']['closed'].'");
|
||||
this.title = "Show Details";
|
||||
'.$otable_var.'.fnClose( nTr );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Open this row */
|
||||
$(this).removeClass("'.parent::$icon_source.'-'.$this->options['row_detail_icons']['closed'].'").addClass("'.parent::$icon_source.'-'.$this->options['row_detail_icons']['opened'].'");
|
||||
this.title = "Hide Details";
|
||||
'.$otable_var.'.fnOpen( nTr, fnFormatDetails('.$otable_var.', nTr), "details" );
|
||||
}
|
||||
return false;
|
||||
});
|
||||
var '.$otable_var.' = $("#'.$table_id.'").dataTable({
|
||||
'.(!isset($structure->js['properties']) || !$structure->js['properties'] ? '' :
|
||||
implode(', ', array_map(function($key, $js) {
|
||||
return "'$key' : $js";
|
||||
}, array_keys($structure->js['properties']), $structure->js['properties'])).',').'
|
||||
'.(!$structure->options["paginate"] ? '"bPaginate": false, "bInfo": false,' : '').'
|
||||
aoColumns: [
|
||||
'.($this->is_with_details() ? '{"bSortable": false},' : '').'
|
||||
'.($this->is_with_checkboxes() ? '{"bSortable": false},' : '').'
|
||||
'.implode(', ', array_map(function($col) use ($structure) {
|
||||
if (isset($structure->sort[$col]) && $structure->sort[$col] === false) return '{ "bSortable": false }';
|
||||
else return 'null';
|
||||
}, array_keys($structure->col))).'
|
||||
],
|
||||
aaSorting: ['.implode(', ', array_filter(array_map(function($col_index, $col) use ($structure) {
|
||||
$col_index = $this->is_with_details() ? $col_index + 1 : $col_index;
|
||||
$col_index = $this->is_with_checkboxes() ? $col_index + 1 : $col_index;
|
||||
if (isset($structure->sort[$col]) && $structure->sort[$col]) {
|
||||
$sorting = $structure->sort[$col];
|
||||
return "[$col_index, '$sorting']";
|
||||
} else return null;
|
||||
}, array_keys(array_keys($structure->col)), array_keys($structure->col)))).'],
|
||||
|
||||
});
|
||||
|
||||
// remove pagination div row ? TO-DO
|
||||
|
||||
$("#'.$structure->id.'_cols li label input[type=checkbox]").on("click", function() {
|
||||
fnShowHideCol($(this).data("column-toggle"), $(this).prop("checked"));
|
||||
});
|
||||
|
||||
function fnShowHideCol(iCol, bVis) {
|
||||
/* Get the DataTables object again - this is not a recreation, just a get of the object */
|
||||
//var bVis = '.$otable_var.'.fnSettings().aoColumns[iCol].bVisible;
|
||||
'.$otable_var.'.fnSetColumnVis(iCol, bVis);
|
||||
}
|
||||
|
||||
function fnFormatDetails ( '.$otable_var.', nTr ) {
|
||||
var aData = '.$otable_var.'.fnGetData( nTr );
|
||||
'.($this->is_with_details() ? $this->_get_detail_content($structure->options["row_details"], array_keys($structure->col)) : '').'
|
||||
}
|
||||
|
||||
$("#'.$table_id.' th input:checkbox").on("click" , function(){
|
||||
var that = this;
|
||||
$(this).closest("table").find("tr > td input:checkbox").each(function(){
|
||||
this.checked = that.checked;
|
||||
//$(this).closest("tr").toggleClass("selected");
|
||||
});
|
||||
});
|
||||
|
||||
'.(isset($structure->toolbar) ? implode("\n", array_map(function($toolbar) {
|
||||
return $toolbar['js'];
|
||||
}, $structure->toolbar)) : "" ).'
|
||||
|
||||
'.(isset($structure->js["custom"]) ? $structure->js['custom'] : '');
|
||||
}
|
||||
|
||||
if ($jquery_enclosed) {
|
||||
$result = '$(function() {
|
||||
'.$dtable_js.'
|
||||
});';
|
||||
} else $result = $dtable_js;
|
||||
|
||||
if ($return) return $result;
|
||||
else echo $result;
|
||||
}
|
||||
|
||||
private function _get_detail_content($detail, $cols) {
|
||||
$result = "";
|
||||
if (Util::is_closure($detail)) { // improve this TO-DO
|
||||
$cols_list = new \stdClass;
|
||||
foreach ($cols as $col)
|
||||
$cols_list->{$col} = '{'.$col.'}';
|
||||
|
||||
$str = $detail($cols_list);
|
||||
$result = 'return \''.$this->_replace_detail_codes($str, $cols).'\';';
|
||||
|
||||
} else if (is_array($detail)) {
|
||||
if (isset($detail["custom"])) {
|
||||
$result = $this->_replace_detail_codes($detail['code'], $cols, true);
|
||||
}
|
||||
} else $result = 'return \''.$this->_replace_detail_codes($detail, $cols).'\';';
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function _replace_detail_codes($str, $cols, $custom_code = false) {
|
||||
preg_match_all("/\{([^{{}}]+)\}/", $str, $matched_cols);
|
||||
$col_replace = array();
|
||||
$col_search = array();
|
||||
foreach($matched_cols[1] as $matched_col) {
|
||||
$arr_col_index = array_keys($cols, $matched_col);
|
||||
if ($arr_col_index) {
|
||||
$col_index = self::is_with_details() ? $arr_col_index[0] + 1 : $arr_col_index[0];
|
||||
$col_index = self::is_with_checkboxes() ? $col_index + 1 : $col_index;
|
||||
$col_replace[] = $custom_code ? 'aData['.$col_index.']' : '\'+aData['.$col_index.']+\'';
|
||||
$col_search[] = "/{{".$matched_col."}}/";
|
||||
}
|
||||
}
|
||||
$result = preg_replace($col_search, $col_replace, $str);
|
||||
return preg_replace('/\s+/', ' ', $result); //remove white spaces
|
||||
}
|
||||
|
||||
public function print_html($return = false) {
|
||||
|
||||
|
||||
$structure = $this->_structure;
|
||||
|
||||
$rows = Util::get_property_value($structure->data, array(
|
||||
"if_array" => function($data) use ($structure) {
|
||||
$html_rows = array();
|
||||
|
||||
foreach ($data as $row_index => $row_data) {
|
||||
|
||||
$row_prop = array(
|
||||
"hidden" => false,
|
||||
"checkbox" => array(),
|
||||
"detail" => true,
|
||||
"class" => "",
|
||||
"attr" => array(),
|
||||
"content" => true
|
||||
);
|
||||
|
||||
if (isset($structure->each['row']) && $structure->each['row']) {
|
||||
$structure->row[$row_index + 1] = Util::set_closure_prop_def($row_prop, $structure->each['row'], array($row_data, $row_index), 'class');
|
||||
}
|
||||
|
||||
$new_row_prop = $row_prop;
|
||||
|
||||
if (isset($structure->row[$row_index + 1])) {
|
||||
$row_prop_value = $structure->row[$row_index + 1];
|
||||
if ($row_prop_value === false) {
|
||||
$new_row_prop["hidden"] = true;
|
||||
} else if ($row_prop_value === "") {
|
||||
$new_row_prop["content"] = "";
|
||||
} else {
|
||||
$new_row_prop = Util::get_clean_structure($row_prop, $row_prop_value, array($row_data, $row_index), 'class');
|
||||
}
|
||||
}
|
||||
|
||||
$rows_html = '';
|
||||
foreach ($row_data as $col_name => $cell_value) {
|
||||
$cell_classes = array();
|
||||
$cell_attrs = array();
|
||||
if ((isset($structure->hide[$col_name]) && $structure->hide[$col_name] === true) || in_array($col_name, $structure->hidden)) {
|
||||
$cell_classes[] = 'hidden';
|
||||
}
|
||||
|
||||
if (isset($new_row_prop["content"]) && !$new_row_prop["content"]) {
|
||||
$rows_html .= '<td class="'.implode(' ', $cell_classes).'"></td>';
|
||||
continue;
|
||||
}
|
||||
$cell_html = $cell_value;
|
||||
|
||||
if (isset($structure->cell[$col_name])) {
|
||||
$cell_prop = $structure->cell[$col_name];
|
||||
$cell_html = Util::get_property_value($cell_prop, array(
|
||||
"if_closure" => function($prop) use ($row_data, $row_index, $cell_value) {
|
||||
return Util::run_callback($prop, array($row_data, $cell_value, $row_index));
|
||||
},
|
||||
"if_array" => function($cell_prop) use ($row_data, $row_index, $cell_value, &$cell_classes, &$cell_attrs) {
|
||||
//icon, content, color, url[href, title, tooltip, attr]
|
||||
$cell_html = $cell_value;
|
||||
|
||||
//content
|
||||
if (isset($cell_prop["content"])) {
|
||||
$cell_html = Util::get_property_value($cell_prop["content"], array(
|
||||
"if_closure" => function($content) use ($row_data, $row_index, $cell_value) {
|
||||
$content_value = Util::replace_col_codes(Util::run_callback($content, array($row_data, $cell_value, $row_index)), $row_data);
|
||||
|
||||
return $content_value;
|
||||
|
||||
},
|
||||
"if_other" => function($content) use ($row_data, $cell_html) {
|
||||
$cell_html = Util::replace_col_codes($content, $row_data);
|
||||
return $cell_html;
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
//url
|
||||
if (isset($cell_prop["url"])) {
|
||||
$map_url_prop = array(
|
||||
"href" => "#",
|
||||
"target" => "_self",
|
||||
"title" => "",
|
||||
"attr" => ""
|
||||
);
|
||||
|
||||
$map_url_prop = Util::get_property_value($cell_prop["url"], array(
|
||||
"if_closure" => function($prop) use ($row_data, $row_index, $cell_value, $map_url_prop) {
|
||||
$url = Util::run_callback($prop, array($row_data, $cell_value, $row_index));
|
||||
$map_url_prop["href"] = $url;
|
||||
|
||||
return $map_url_prop;
|
||||
},
|
||||
"if_array" => function($url_prop) use ($row_data, $cell_html, $map_url_prop) {
|
||||
$map_url_prop["target"] = isset($url_prop['target']) ? $url_prop['target'] : "_self";
|
||||
$map_url_prop["href"] = isset($url_prop['href']) ? Util::replace_col_codes($url_prop['href'], $row_data, true) : '#';
|
||||
$map_url_prop["attr"] = isset($url_prop['attr']) && $url_prop['attr'] ? $url_prop['attr'] : '';
|
||||
$map_url_prop["title"] = isset($url_prop['title']) ? Util::replace_col_codes($url_prop['title'], $row_data, true) : '';
|
||||
return $map_url_prop;
|
||||
|
||||
},
|
||||
"if_other" => function($url_prop) use ($row_data, $cell_html, $map_url_prop) {
|
||||
$map_url_prop["href"] = Util::replace_col_codes($url_prop, Util::object_to_array($row_data), true);
|
||||
return $map_url_prop;
|
||||
}
|
||||
));
|
||||
|
||||
$cell_html = '<a href="'.$map_url_prop["href"].'" target="'.$map_url_prop["target"].'" '.$map_url_prop["attr"].' title="'.$map_url_prop["title"].'">'.$cell_html.'</a>';
|
||||
}
|
||||
|
||||
//icon
|
||||
if (isset($cell_prop["icon"])) {
|
||||
$cell_html = Util::get_property_value($cell_prop["icon"], array(
|
||||
"if_closure" => function($icon) use ($row_data, $row_index, $cell_value, $cell_html) {
|
||||
$icon_value = Util::run_callback($prop, array($row_data, $cell_value, $row_index));
|
||||
return '<i class="'.parent::$icon_source.' '.$icon_value.'"></i> '.$cell_html;
|
||||
},
|
||||
"if_other" => function($icon) use ($cell_html) {
|
||||
return '<i class="'.parent::$icon_source.' '.$icon.'"></i> '.$cell_html;
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
//color
|
||||
if (isset($cell_prop["color"])) {
|
||||
$cell_html = Util::get_property_value($cell_prop["color"], array(
|
||||
"if_closure" => function($color) use ($row_data, $row_index, $cell_value, $cell_html) {
|
||||
$color_value = Util::run_callback($color, array($row_data, $cell_value, $row_index));
|
||||
return '<span class="'.$color_value.'">'.$cell_html.'</span>';
|
||||
},
|
||||
"if_other" => function($color) use ($cell_html) {
|
||||
return '<span class="'.$color.'">'.$cell_html.'</span>';
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
//class
|
||||
if (isset($cell_prop["class"])) {
|
||||
if (is_array($cell_prop["class"])) {
|
||||
$cell_classes = array_merge($cell_classes, $cell_prop["class"]);
|
||||
} else $cell_classes[] = $cell_prop["class"];
|
||||
}
|
||||
|
||||
if (isset($cell_prop["attr"])) {
|
||||
if (is_array($cell_prop["attr"])) {
|
||||
foreach ($cell_prop["attr"] as $attr => $value) {
|
||||
$cell_attrs[] = $attr.'="'.$value.'"';
|
||||
}
|
||||
} else $cell_attrs[] = $cell_prop["attr"];
|
||||
}
|
||||
|
||||
//callback
|
||||
if (isset($cell_prop["callback"]) && Util::is_closure($cell_prop["callback"])) {
|
||||
$new_cell_html = Util::run_callback($cell_prop["callback"], array($row_data, $cell_html, $row_index));
|
||||
if (trim($new_cell_html) != "") {
|
||||
$cell_html = $new_cell_html;
|
||||
}
|
||||
}
|
||||
|
||||
return $cell_html;
|
||||
},
|
||||
"if_other" => function($cell_prop) use ($row_data) {
|
||||
return Util::replace_col_codes($cell_prop, $row_data);
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
$rows_html .= '<td'.($cell_classes ? ' class="'.implode(' ', $cell_classes).'"' : '').($cell_attrs ? ' '.implode(' ', $cell_attrs) : '').'> '.$cell_html.' </td>';
|
||||
}
|
||||
|
||||
|
||||
$row_classes = array();
|
||||
if ($new_row_prop["class"]) $row_classes[] = $new_row_prop["class"];
|
||||
if ($new_row_prop["hidden"] === true) $row_classes[] = 'hidden';
|
||||
|
||||
$attrs = array();
|
||||
if (is_array($new_row_prop["attr"])) {
|
||||
foreach ($new_row_prop["attr"] as $attr => $value) {
|
||||
$attrs[] = $attr.'="'.$value.'"';
|
||||
}
|
||||
} else {
|
||||
$attrs[] = $new_row_prop["attr"];
|
||||
}
|
||||
$attr = $attrs ? ' '.implode(' ', $attrs) : '';
|
||||
|
||||
$row_class = $row_classes ? ' class="'.implode(' ', $row_classes).'"' : '';
|
||||
|
||||
$row_checkbox = '';
|
||||
$row_details = '';
|
||||
|
||||
if (isset($structure->options["checkboxes"]) && $structure->options["checkboxes"]) {
|
||||
|
||||
if ($new_row_prop["checkbox"] === false)
|
||||
$checkbox_content = '';
|
||||
else {
|
||||
// global checkboxes configuration
|
||||
$option = $structure->options["checkboxes"];
|
||||
$checkbox_prop = array(
|
||||
"name" => $structure->id."_checkbox",
|
||||
"id" => "",
|
||||
"checked" => false,
|
||||
"value" => "on"
|
||||
);
|
||||
|
||||
$new_checkbox_prop = Util::get_clean_structure($checkbox_prop, $option, array($this, $row_data, $row_index), 'name');
|
||||
|
||||
// override global checkbox settings if configured
|
||||
$this_row_checkbox_prop = Util::get_clean_structure($new_checkbox_prop, $new_row_prop['checkbox'], array($this, $row_data, $row_index), 'name');
|
||||
|
||||
$id = $this_row_checkbox_prop["id"] ? 'id="'.$this_row_checkbox_prop["id"].'"' : '';
|
||||
$value = '';
|
||||
|
||||
if (Util::is_closure($this_row_checkbox_prop['value']))
|
||||
$value = Util::run_callback($this_row_checkbox_prop['value'], array($row_data));
|
||||
else $value = $this_row_checkbox_prop['value'];
|
||||
|
||||
$value = Util::replace_col_codes($value, $row_data);
|
||||
|
||||
$checkbox_content = '<label class="checkbox-inline">
|
||||
<input type="checkbox" '.($this_row_checkbox_prop["checked"] ? 'checked' : '' ).' class="checkbox style-0" name="'.$this_row_checkbox_prop["name"].'[]" '.$id.' value="'.$value.'" />
|
||||
<span></span>
|
||||
</label>';
|
||||
|
||||
}
|
||||
|
||||
$row_checkbox = '<td class="center table-checkbox" width="20px"> '.$checkbox_content.' </td>';
|
||||
}
|
||||
|
||||
if (isset($structure->options["row_details"]) && $structure->options["row_details"]) {
|
||||
$option = $structure->options["row_details"];
|
||||
|
||||
$detail_prop = array(
|
||||
"id" => "",
|
||||
"icon" => parent::$icon_source."-".$this->options["row_detail_icons"]["closed"],
|
||||
"title" => 'Show Details'
|
||||
);
|
||||
|
||||
$new_detail_prop = Util::get_clean_structure($detail_prop, $option, array($this, $row_data, $row_index), 'icon');
|
||||
$id = $new_detail_prop["id"] ? 'id="'.$new_detail_prop["id"].'"' : '';
|
||||
|
||||
$content = '<a href="#" '.$id.'>
|
||||
<i class="'.parent::$icon_source.' '.$detail_prop['icon'].' '.parent::$icon_source.'" data-toggle="row-detail" title="'.$detail_prop['title'].'"></i>
|
||||
</a>';
|
||||
if ($new_row_prop["detail"] === false)
|
||||
$content = '';
|
||||
|
||||
$row_details =
|
||||
'<td class="center" width="20px"> '.$content.' </td>';
|
||||
}
|
||||
|
||||
$html_rows[] = '<tr'.$row_class.$attr.'>'.$row_details.$row_checkbox.$rows_html.'</tr>';
|
||||
}
|
||||
return implode('', $html_rows);
|
||||
},
|
||||
"if_closure" => function($data) {
|
||||
parent::err('SmartUI::DataTable::data requires an array of objects/array');
|
||||
return '';
|
||||
},
|
||||
"if_other" => function($data) {
|
||||
parent::err('SmartUI::DataTable::data requires an array of objects/array');
|
||||
return '';
|
||||
}
|
||||
));
|
||||
|
||||
if ($structure->options['columns']) {
|
||||
$cols = Util::get_property_value($structure->col, array(
|
||||
"if_array" => function($cols) use ($structure) {
|
||||
$html_col_list = array();
|
||||
|
||||
foreach ($cols as $col_name => $col_value) {
|
||||
|
||||
if (is_null($col_value) || $col_value === false) continue;;
|
||||
$col_value_prop = array(
|
||||
"title" => $col_name,
|
||||
"class" => "",
|
||||
"attr" => array(),
|
||||
"icon" => "",
|
||||
"hidden" => (isset($structure->hide[$col_name]) && $structure->hide[$col_name] === true) || in_array($col_name, $structure->hidden)
|
||||
);
|
||||
|
||||
$new_col_value = Util::get_clean_structure($col_value_prop, $col_value, array($this, $cols), 'title');
|
||||
if ($new_col_value['attr']) {
|
||||
if (is_array($new_col_value["attr"])) {
|
||||
foreach ($new_col_value["attr"] as $attr => $value) {
|
||||
$attrs[] = $attr.'="'.$value.'"';
|
||||
}
|
||||
|
||||
} else {
|
||||
$attrs[] = $new_col_value["attr"];
|
||||
}
|
||||
$new_col_value["attr"] = $attrs;
|
||||
}
|
||||
|
||||
$classes = array();
|
||||
if ($new_col_value['class'])
|
||||
$classes[] = $new_col_value['class'];
|
||||
|
||||
if ($new_col_value['hidden'] === true)
|
||||
$classes[] = "hidden";
|
||||
|
||||
$class = $classes ? 'class="'.implode(' ', $classes).'"' : '';
|
||||
|
||||
$main_attributes = array($class, implode(' ', $new_col_value['attr']));
|
||||
$htm_attrs = trim(implode(' ', $main_attributes));
|
||||
$htm_attrs = $htm_attrs ? ' '.$htm_attrs : '';
|
||||
|
||||
$html_col_list[] = '<th'.$htm_attrs.'>'.$new_col_value['icon'].' '.$new_col_value['title'].' </th>';
|
||||
}
|
||||
|
||||
|
||||
$html_cols = implode('', $html_col_list);
|
||||
|
||||
$checkbox_header = '';
|
||||
$detail_header = '';
|
||||
|
||||
if (isset($structure->options["checkboxes"]) && ($structure->options["checkboxes"])) {
|
||||
$checkbox_header = '
|
||||
<th class="center table-checkbox" width="20px">
|
||||
<label class="checkbox-inline">
|
||||
<input type="checkbox" class="checkbox style-0">
|
||||
<span></span>
|
||||
</label>
|
||||
</th>';
|
||||
}
|
||||
|
||||
if (isset($structure->options["row_details"]) && ($structure->options["row_details"])) {
|
||||
$detail_header = '
|
||||
<th class="center" width="20px"></th>';
|
||||
}
|
||||
|
||||
return '<tr>'.$detail_header.$checkbox_header.$html_cols.'</tr>';
|
||||
}
|
||||
));
|
||||
} else $cols = '';
|
||||
|
||||
$id = Util::get_property_value(
|
||||
$structure->id,
|
||||
array(
|
||||
"if_closure" => function($prop) { return Util::run_callback($prop, array($this)); },
|
||||
"if_other" => function($prop) { return $prop; },
|
||||
"if_array" => function($prop) use ($structure) {
|
||||
parent::err('SmartUI::Widget::id requires string.');
|
||||
return $structure->id;
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
$id = $id ? 'id="'.$id.'"' : '';
|
||||
|
||||
$classes = array();
|
||||
if ($structure->options['table']) $classes[] = 'table';
|
||||
if ($structure->options['striped']) $classes[] = 'table-striped';
|
||||
if ($structure->options['bordered']) $classes[] = 'table-bordered';
|
||||
if ($structure->options['hover']) $classes[] = 'table-hover';
|
||||
if ($structure->options['condensed']) $classes[] = 'table-condensed';
|
||||
if ($structure->options['forum']) $classes[] = 'table-forum';
|
||||
|
||||
if ($structure->class) {
|
||||
$classes[] = is_array($structure->class) ? implode(' ', $structure->class) : $structure->class;
|
||||
}
|
||||
|
||||
$table_html = '<table '.$id.' class="'.implode(' ', $classes).'">';
|
||||
$table_html .= '<thead>';
|
||||
$table_html .= $cols;
|
||||
$table_html .= '</thead>';
|
||||
$table_html .= '<tbody>';
|
||||
$table_html .= $rows;
|
||||
$table_html .= '</tbody>';
|
||||
$table_html .= '</table>';
|
||||
|
||||
$result = $table_html;
|
||||
|
||||
if (isset($structure->options["in_widget"]) && $structure->options["in_widget"]) {
|
||||
// no need for widget's toolbar for datatable 1.10.x
|
||||
// if (!$structure->options["static"])
|
||||
// $structure->widget->body('toolbar', '');
|
||||
|
||||
$structure->widget->body("content", $table_html);
|
||||
$result = $structure->widget->print_html(true);
|
||||
}
|
||||
|
||||
if ($return) return $result;
|
||||
else echo $result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
?>
|
||||
115
lib/smartui/Components/Info.php
Normal file
115
lib/smartui/Components/Info.php
Normal file
@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
namespace SmartUI\Components;
|
||||
use \SmartUI\UI;
|
||||
use \SmartUI\Util;
|
||||
|
||||
class Info extends UI {
|
||||
private $_options_map = array(
|
||||
'stripped' => false,
|
||||
'grouped' => false,
|
||||
'class' => ''
|
||||
);
|
||||
|
||||
private $_structure = array(
|
||||
'row' => array(),
|
||||
'options' => array(),
|
||||
'value' => array(),
|
||||
'name' => array(),
|
||||
'icon' => array(),
|
||||
'action' => array(),
|
||||
'title' => ''
|
||||
);
|
||||
|
||||
public function __construct($rows, $options = array()) {
|
||||
$this->_init_structure($rows, $options);
|
||||
}
|
||||
|
||||
private function _init_structure($rows, $user_options = array()) {
|
||||
$this->_structure = parent::array_to_object($this->_structure);
|
||||
$this->_structure->options = parent::set_array_prop_def($this->_options_map, $user_options);
|
||||
|
||||
$this->_structure->row = $rows;
|
||||
}
|
||||
|
||||
public function __get($name) {
|
||||
if (isset($this->_structure->{$name})) {
|
||||
return $this->_structure->{$name};
|
||||
}
|
||||
parent::err('Undefined structure property: '.$name);
|
||||
return null;
|
||||
}
|
||||
|
||||
public function __set($name, $value) {
|
||||
if (isset($this->_structure->{$name})) {
|
||||
$this->_structure->{$name} = $value;
|
||||
return;
|
||||
}
|
||||
parent::err('Undefined structure property: '.$name);
|
||||
}
|
||||
|
||||
public function __call($name, $args) {
|
||||
return parent::_call($this, $this->_structure, $name, $args);
|
||||
}
|
||||
|
||||
public function print_html($return = false) {
|
||||
|
||||
|
||||
$structure = $this->_structure;
|
||||
|
||||
$rows = Util::get_property_value($structure->row, array(
|
||||
'if_closure' => function($rows) {
|
||||
return Util::run_callback($rows, array($this));
|
||||
},
|
||||
'if_other' => function($rows) {
|
||||
parent::err('SmartUI::ProfileInfo::row requires array');
|
||||
return null;
|
||||
}
|
||||
));
|
||||
|
||||
if (!is_array($rows)) {
|
||||
parent::err("SmartUI::ProfileInfo::row requires array");
|
||||
return null;
|
||||
}
|
||||
|
||||
$rows_html_list = array();
|
||||
|
||||
foreach ($rows as $key => $info) {
|
||||
|
||||
$row_prop = array(
|
||||
'icon' => isset($structure->icon[$key]) ? $structure->icon[$key] : '',
|
||||
'value' => isset($structure->value[$key]) ? $structure->value[$key] : '',
|
||||
'name' => isset($structure->name[$key]) ? $structure->name[$key] : $key,
|
||||
'action' => isset($structure->action[$key]) ? $structure->action[$key] : '',
|
||||
'class' => null
|
||||
);
|
||||
|
||||
$new_row_prop = Util::get_clean_structure($row_prop, $info, array($this, $rows, $key), 'value');
|
||||
|
||||
$icon = $new_row_prop['icon'] ? '<i class="'.parent::$icon_source.' '.$new_row_prop['icon'].'"></i> ' : '';
|
||||
|
||||
$row_html = '<div class="info-row'.($new_row_prop['class'] ? ' '.$new_row_prop['class'] : '').'">';
|
||||
$row_html .= ' <div class="info-name"> '.$new_row_prop['name'].' </div>';
|
||||
$row_html .= ' <div class="info-action"> '.$new_row_prop['action'].' </div>';
|
||||
$row_html .= ' <div class="info-value"> '.$icon.$new_row_prop['value'].' </div>';
|
||||
$row_html .= '</div>';
|
||||
|
||||
$rows_html_list[] = $row_html;
|
||||
}
|
||||
$classes = array();
|
||||
if ($structure->options['stripped']) $classes[] = 'info-stripped';
|
||||
if ($structure->options['grouped']) $classes[] = 'info-grouped';
|
||||
|
||||
$classes[] = $structure->options['class'];
|
||||
|
||||
$result = '<div class="info'.($classes ? ' '.implode(' ', $classes) : '').'">';
|
||||
$result .= $structure->title ? '<div class="info-title">'.$structure->title.'</div>' : '';
|
||||
$result .= implode('', $rows_html_list);
|
||||
$result .= '</div>';
|
||||
|
||||
if ($return) return $result;
|
||||
else echo $result;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
167
lib/smartui/Components/Nav.php
Normal file
167
lib/smartui/Components/Nav.php
Normal file
@ -0,0 +1,167 @@
|
||||
<?php
|
||||
|
||||
namespace SmartUI\Components;
|
||||
use \SmartUI\UI;
|
||||
use \SmartUI\Util;
|
||||
|
||||
class Nav extends UI {
|
||||
|
||||
private $_structure = array(
|
||||
'nav' => array(),
|
||||
'id' => ''
|
||||
);
|
||||
|
||||
public function __construct($nav_items = array()) {
|
||||
$this->_init_structure($nav_items);
|
||||
}
|
||||
|
||||
private function _init_structure($nav_items) {
|
||||
$this->_structure = Util::array_to_object($this->_structure);
|
||||
$this->_structure->nav = $nav_items;
|
||||
$this->_structure->id = Util::create_id(true);
|
||||
}
|
||||
|
||||
public function __get($name) {
|
||||
if (isset($this->_structure->{$name})) {
|
||||
return $this->_structure->{$name};
|
||||
}
|
||||
parent::err('Undefined structure property: '.$name);
|
||||
return null;
|
||||
}
|
||||
|
||||
public function __set($name, $value) {
|
||||
if (isset($this->_structure->{$name})) {
|
||||
$this->_structure->{$name} = $value;
|
||||
return;
|
||||
}
|
||||
parent::err('Undefined structure property: '.$name);
|
||||
}
|
||||
|
||||
public function __call($name, $args) {
|
||||
return parent::_call($this, $this->_structure, $name, $args);
|
||||
}
|
||||
|
||||
public function print_html($return = false) {
|
||||
|
||||
$structure = $this->_structure;
|
||||
|
||||
$nav_items = Util::get_property_value($structure->nav, array(
|
||||
'if_closure' => function($nav_items) {
|
||||
return Util::run_callback($nav_items, array($this));
|
||||
},
|
||||
'if_other' => function($nav_items) {
|
||||
parent::err('SmartUI::Nav:nav requires array');
|
||||
return null;
|
||||
}
|
||||
));
|
||||
|
||||
if (!is_array($nav_items)) {
|
||||
parent::err("SmartUI::Nav:nav requires array");
|
||||
return null;
|
||||
}
|
||||
|
||||
$list_items = $this->parse_nav($nav_items, true);
|
||||
$result = parent::print_list($list_items, null, true);
|
||||
|
||||
if ($return) return $result;
|
||||
else echo $result;
|
||||
}
|
||||
|
||||
private function parse_nav($nav_item, $is_parent = false) {
|
||||
|
||||
if (!$nav_item) return '';
|
||||
$nav_items_list = array();
|
||||
foreach ($nav_item as $name => $nav) {
|
||||
$nav_prop = array(
|
||||
'url' => '#',
|
||||
'url_target' => '',
|
||||
'icon' => '',
|
||||
'icon_badge' => '',
|
||||
'label_htm' => '',
|
||||
'title' => $name,
|
||||
'title_append' => '',
|
||||
'label' => '',
|
||||
'active' => false,
|
||||
'sub' => array(),
|
||||
'attr' => array(),
|
||||
'class' => array(),
|
||||
'li_class' => array()
|
||||
);
|
||||
|
||||
$new_nav_prop = Util::set_array_prop_def($nav_prop, $nav, 'title');
|
||||
|
||||
$icon_badge_prop = array(
|
||||
'content' => '',
|
||||
'class' => ''
|
||||
);
|
||||
|
||||
$icon_badge_prop = Util::set_array_prop_def($icon_badge_prop, $new_nav_prop['icon_badge'], 'content');
|
||||
$badge = '';
|
||||
if ($icon_badge_prop['content']) {
|
||||
$badge_class = $icon_badge_prop['class'] ? 'class="'.$icon_badge_prop['class'].'"' : '';
|
||||
$badge = '<em '.$badge_class.'>'.$icon_badge_prop['content'].'</em>';
|
||||
}
|
||||
|
||||
$icon = $new_nav_prop['icon'] ? '<i class="'.parent::$icon_source.' '.parent::$icon_source.'-lg '.parent::$icon_source.'-fw '.$new_nav_prop['icon'].'">'.$badge.'</i>' : '';
|
||||
$title = $new_nav_prop['title'];
|
||||
$title_append = $new_nav_prop['title_append'];
|
||||
|
||||
$display_title = $title.' '.$title_append;
|
||||
|
||||
$label_htm = $new_nav_prop['label_htm'] ? ' '.$new_nav_prop['label_htm'] : '';
|
||||
|
||||
$display_text = $is_parent ? '<span class="menu-item-parent">'.$display_title.'</span>' : $display_title;
|
||||
$display_text .= $label_htm;
|
||||
|
||||
$attrs = array_map(function($attr, $value) {
|
||||
return $attr.'="'.$value.'"';
|
||||
}, array_keys($new_nav_prop['attr']), $new_nav_prop['attr']);
|
||||
|
||||
if ($new_nav_prop['class']) $attrs[] = 'class="'.$new_nav_prop['class'].'"';
|
||||
|
||||
$nav_htm = '<a ';
|
||||
$nav_htm .= 'href="'.$new_nav_prop['url'].'" ';
|
||||
$nav_htm .= ($new_nav_prop['url_target'] ? 'target="'.$new_nav_prop['url_target'].'"' : '').' ';
|
||||
$nav_htm .= implode(' ', $attrs).'> ';
|
||||
$nav_htm .= $icon.' '.$display_text.' '.$new_nav_prop['label'];
|
||||
$nav_htm .= '</a>';
|
||||
|
||||
$li_classes = array();
|
||||
if ($new_nav_prop["active"]) $li_classes[] = 'active';
|
||||
if ($new_nav_prop['li_class']) {
|
||||
if (is_string($new_nav_prop['li_class'])) $li_classes[] = $new_nav_prop['li_class'];
|
||||
else if (is_array($new_nav_prop['li_class'])) $li_classes = array_merge($li_classes, $new_nav_prop['li_class']);
|
||||
}
|
||||
|
||||
$nav_item_structure = array(
|
||||
'content' => $nav_htm,
|
||||
'class' => implode(' ', $li_classes)
|
||||
);
|
||||
|
||||
if (isset($new_nav_prop['sub'])) {
|
||||
if (is_string($new_nav_prop['sub'])) {
|
||||
$subitems = array($new_nav_prop['sub']);
|
||||
} else {
|
||||
foreach ($new_nav_prop['sub'] as $subitem) {
|
||||
if (isset($subitem['active'])) {
|
||||
$nav_item_structure['class'] .= ' active open';
|
||||
$nav_item_structure['subitem_options'] = array('attr' => array('style' => 'display: block;'));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$subitems = $this->parse_nav($new_nav_prop['sub']);
|
||||
}
|
||||
|
||||
$nav_item_structure['subitems'] = $subitems;
|
||||
}
|
||||
|
||||
$nav_items_list[] = $nav_item_structure;
|
||||
}
|
||||
|
||||
return $nav_items_list;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
888
lib/smartui/Components/SmartForm.php
Normal file
888
lib/smartui/Components/SmartForm.php
Normal file
@ -0,0 +1,888 @@
|
||||
<?php
|
||||
|
||||
namespace SmartUI\Components;
|
||||
use \SmartUI\UI;
|
||||
use \SmartUI\Util;
|
||||
|
||||
class SmartForm extends UI {
|
||||
|
||||
const FORM_FIELD_INPUT = 'input';
|
||||
const FORM_FIELD_TEXTAREA = 'textarea';
|
||||
const FORM_FIELD_CHECKBOX = 'checkbox';
|
||||
const FORM_FIELD_RADIO ='radio';
|
||||
const FORM_FIELD_SELECT = 'select';
|
||||
const FORM_FIELD_SELECT2 = 'select2';
|
||||
const FORM_FIELD_SELECT2_MULTI = 'select2-multi';
|
||||
const FORM_FIELD_MULTISELECT = 'multi-select';
|
||||
const FORM_FIELD_RATING = 'rating';
|
||||
const FORM_FIELD_RATINGS = 'ratings';
|
||||
const FORM_FIELD_FILEINPUT = 'file-input';
|
||||
const FORM_FIELD_LABEL = 'label';
|
||||
const FORM_FIELD_HIDDEN = 'hidden';
|
||||
const FORM_FIELD_BLANK = 'blank';
|
||||
|
||||
private $_options_map = array(
|
||||
'in_widget' => true,
|
||||
'wrapper' => 'form'
|
||||
);
|
||||
|
||||
private $_structure = array(
|
||||
'field' => array(),
|
||||
'fieldset' => array(),
|
||||
'type' => array(),
|
||||
'property' => array(),
|
||||
'footer' => '',
|
||||
'header' => '',
|
||||
'widget' => null,
|
||||
'title' => '',
|
||||
'col' => array(),
|
||||
'section' => array(),
|
||||
'options' => array(),
|
||||
'attr' => array(),
|
||||
'id' => '',
|
||||
'class' => array()
|
||||
);
|
||||
|
||||
public function __construct($fields, $options = array()) {
|
||||
$this->_init_structure($fields, $options);
|
||||
}
|
||||
|
||||
private function _init_structure($fields, $user_options = array()) {
|
||||
$this->_structure = Util::array_to_object($this->_structure);
|
||||
$this->_structure->options = Util::set_array_prop_def($this->_options_map, $user_options);
|
||||
$this->_structure->field = $fields;
|
||||
|
||||
$widget = new Widget();
|
||||
$widget->options('editbutton', false)
|
||||
->body('class', 'no-padding')
|
||||
->header('title', '<h2></h2>');
|
||||
|
||||
$this->_structure->widget = $widget;
|
||||
}
|
||||
|
||||
public function __get($name) {
|
||||
if (isset($this->_structure->{$name})) {
|
||||
return $this->_structure->{$name};
|
||||
}
|
||||
parent::err('Undefined structure property: '.$name);
|
||||
return null;
|
||||
}
|
||||
|
||||
public function __set($name, $value) {
|
||||
if (isset($this->_structure->{$name})) {
|
||||
$this->_structure->{$name} = $value;
|
||||
return;
|
||||
}
|
||||
parent::err('Undefined structure property: '.$name);
|
||||
}
|
||||
|
||||
public function __call($name, $args) {
|
||||
return parent::_call($this, $this->_structure, $name, $args);
|
||||
}
|
||||
|
||||
private function _create_field_group($collumed, $field_html, $col) {
|
||||
$group = new \stdClass;
|
||||
$group->collumned = $collumed;
|
||||
$group->items = array($field_html);
|
||||
$group->total = (int)$col;
|
||||
return $group;
|
||||
}
|
||||
|
||||
public function print_html($return = false) {
|
||||
|
||||
|
||||
$structure = $this->_structure;
|
||||
|
||||
$fields = Util::get_property_value($structure->field, array(
|
||||
'if_closure' => function($fields) {
|
||||
return Util::run_callback($fields, array($this));
|
||||
},
|
||||
'if_other' => function($fields) {
|
||||
parent::err('SmartUI::SmartForm:field requires array');
|
||||
return null;
|
||||
}
|
||||
));
|
||||
|
||||
if (!is_array($fields)) {
|
||||
parent::err("SmartUI::SmartForm:field requires array");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!$structure->fieldset || !is_array($structure->fieldset)) {
|
||||
$structure->fieldset[] = array_keys($fields);
|
||||
}
|
||||
|
||||
$fieldsets_html_list = array();
|
||||
$hidden_fields_list = array();
|
||||
$fieldsets = count($structure->fieldset);
|
||||
for ($fs_index = 0; $fs_index < $fieldsets; $fs_index++) {
|
||||
|
||||
$fs_fields = $structure->fieldset[$fs_index];
|
||||
|
||||
$groups = array();
|
||||
$with_col_cntr = 0;
|
||||
$grouped = false;
|
||||
|
||||
if (is_string($fs_fields)) $fs_fields = array($fs_fields);
|
||||
|
||||
foreach ($fs_fields as $field_name) {
|
||||
$field = $structure->field[$field_name];
|
||||
$field_prop = array(
|
||||
'type' => self::FORM_FIELD_INPUT,
|
||||
'col' => 0,
|
||||
'section' => array(),
|
||||
'properties' => array()
|
||||
);
|
||||
|
||||
$new_field_prop = Util::get_clean_structure($field_prop, $field, array($this, $fs_index, $fs_fields), 'type');
|
||||
|
||||
if ($new_field_prop['type'] == self::FORM_FIELD_HIDDEN) {
|
||||
$field_html = self::print_field($field_name, self::FORM_FIELD_HIDDEN, $new_field_prop['properties'], true);
|
||||
$hidden_fields_list[] = $field_html;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isset($structure->property[$field_name])) $new_field_prop['properties'] = $structure->property[$field_name];
|
||||
if (isset($structure->col[$field_name])) $new_field_prop['col'] = $structure->col[$field_name];
|
||||
if (isset($structure->type[$field_name])) $new_field_prop['type'] = $structure->type[$field_name];
|
||||
if (isset($structure->section[$field_name])) $new_field_prop['section'] = $$structure->section[$field_name];
|
||||
|
||||
$new_prop_col = (int)$new_field_prop['col'];
|
||||
|
||||
$field_html = self::print_field($field_name, $new_field_prop['type'], $new_field_prop['properties'], array(
|
||||
'col' => $new_prop_col,
|
||||
'section' => $new_field_prop['section']
|
||||
), true);
|
||||
|
||||
$collumned = $new_field_prop['col'] > 0 && $new_prop_col < 12;
|
||||
|
||||
if (!$grouped) {
|
||||
$last_group_key = Util::create_id();
|
||||
$group = self::_create_field_group($collumned, $field_html, $new_prop_col);
|
||||
$groups[$last_group_key] = $group;
|
||||
$grouped = true;
|
||||
} else {
|
||||
$last_group = $groups[$last_group_key];
|
||||
if ($last_group->collumned === $collumned && $last_group->total < 12 && ($last_group->total + $new_prop_col) <= 12) {
|
||||
$last_group->items[] = $field_html;
|
||||
$last_group->total = $last_group->total + $new_prop_col;
|
||||
} else {
|
||||
$last_group_key = Util::create_id();
|
||||
$group = self::_create_field_group($collumned, $field_html, $new_prop_col);
|
||||
$groups[$last_group_key] = $group;
|
||||
$grouped = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$fields_html_list = array();
|
||||
|
||||
foreach($groups as $group) {
|
||||
$group_html = '';
|
||||
$fields_html = implode('', $group->items);
|
||||
if ($group->collumned) {
|
||||
$group_html .= '<div class="row">';
|
||||
$group_html .= $fields_html;
|
||||
$group_html .= '</div>';
|
||||
} else {
|
||||
$group_html .= $fields_html;
|
||||
}
|
||||
|
||||
$fields_html_list[] = $group_html;
|
||||
}
|
||||
|
||||
$fieldsets_html_list[] = '<fieldset>'.implode('', $fields_html_list).'</fieldset>';
|
||||
}
|
||||
|
||||
$header = Util::get_property_value($structure->header, array(
|
||||
'if_closure' => function($header) {
|
||||
return Util::run_callback($header, array($this));
|
||||
}
|
||||
));
|
||||
|
||||
$footer = Util::get_property_value($structure->footer, array(
|
||||
'if_closure' => function($footer) {
|
||||
return Util::run_callback($footer, array($this));
|
||||
}
|
||||
));
|
||||
|
||||
$form_attrs = array();
|
||||
$form_attrs[] = 'class="smart-form '.(is_array($structure->class) ? implode(' ', $structure->class) : $structure->class).'"';
|
||||
$form_attrs[] = 'id="'.($structure->id ? $structure->id : Util::create_id()).'"';
|
||||
|
||||
$form_attrs = array_merge($form_attrs, array_map(function($attr, $value) {
|
||||
return $attr.'="'.$value.'"';
|
||||
}, array_keys($structure->attr), $structure->attr));
|
||||
|
||||
$fields_content = $header ? '<header>'.$header.'</header>' : '';
|
||||
$fields_content .= implode('', $fieldsets_html_list);
|
||||
$fields_content .= implode(' ', $hidden_fields_list);
|
||||
$fields_content .= $footer ? '<footer>'.$footer.'</footer>' : '';
|
||||
|
||||
if ($structure->options['wrapper']) {
|
||||
$form_html = '<'.$structure->options['wrapper'].' '.implode(' ', $form_attrs).'>';
|
||||
$form_html .= $fields_content;
|
||||
$form_html .= '</'.$structure->options['wrapper'].'>';
|
||||
} else {
|
||||
$form_html = $fields_content;
|
||||
}
|
||||
|
||||
if (isset($structure->options["in_widget"]) && $structure->options["in_widget"]) {
|
||||
$structure->widget->body("content", $form_html);
|
||||
if ($structure->title) {
|
||||
$structure->widget->header('title', $structure->title);
|
||||
}
|
||||
|
||||
$result = $structure->widget->print_html(true);
|
||||
} else $result = $form_html;
|
||||
|
||||
if ($return) return $result;
|
||||
else echo $result;
|
||||
}
|
||||
|
||||
public static function print_field($name, $type = self::FORM_FIELD_INPUT, $properties = array(), $options = false, $return = false) {
|
||||
$field_html = self::_get_field_html($name, $type, $properties);
|
||||
if ($type == self::FORM_FIELD_HIDDEN) return $field_html;
|
||||
|
||||
$classes = array();
|
||||
$section = array();
|
||||
if (is_array($options)) {
|
||||
$col = isset($options['col']) ? $options['col'] : null;
|
||||
$section = isset($options['section']) ? $options['section'] : array();
|
||||
} else $col = $options;
|
||||
|
||||
if ($col && $col < 12) $classes[] = 'col col-'.$col;
|
||||
if ($type == self::FORM_FIELD_LABEL) $classes[] = 'label';
|
||||
|
||||
$attr = array();
|
||||
if ($section) {
|
||||
if (is_string($section)) $classes[] = $section;
|
||||
else {
|
||||
if (isset($section['attr'])) $attr = array_merge($attr, $section['attr']);
|
||||
if (isset($section['class'])) $classes[] = is_string($section['class']) ? $section['class'] : implode(' ', $section['class']);
|
||||
if (isset($section['id'])) $attr['id'] = $section['id'];
|
||||
}
|
||||
}
|
||||
|
||||
if ($classes) {
|
||||
if (isset($attr['class'])) $attr['class'] .= implode(' ', $classes);
|
||||
else $attr['class'] = implode(' ', $classes);
|
||||
}
|
||||
|
||||
$attr_list = array_map(function($attr, $value) {
|
||||
return $attr.'="'.$value.'"';
|
||||
}, array_keys($attr), $attr);
|
||||
|
||||
$result = '<section '.implode(' ', $attr_list).'>';
|
||||
$result .= $field_html;
|
||||
$result .= '</section>';
|
||||
|
||||
if ($return) return $result;
|
||||
else echo $result;
|
||||
}
|
||||
|
||||
private static function _get_field_html($name, $field_type = self::FORM_FIELD_INPUT, $properties = array(), $field_html_only = false) {
|
||||
$field_class_map = array(
|
||||
self::FORM_FIELD_INPUT => 'input',
|
||||
self::FORM_FIELD_FILEINPUT => 'input input-file',
|
||||
self::FORM_FIELD_SELECT => 'select',
|
||||
self::FORM_FIELD_SELECT2 => 'select',
|
||||
self::FORM_FIELD_SELECT2_MULTI => 'select select-multiple',
|
||||
self::FORM_FIELD_MULTISELECT => 'select select-multiple',
|
||||
self::FORM_FIELD_TEXTAREA => 'textarea',
|
||||
self::FORM_FIELD_CHECKBOX => 'checkbox',
|
||||
self::FORM_FIELD_RADIO => 'radio',
|
||||
self::FORM_FIELD_RATING => 'rating',
|
||||
self::FORM_FIELD_RATINGS => 'rating',
|
||||
self::FORM_FIELD_HIDDEN => '',
|
||||
self::FORM_FIELD_BLANK => ''
|
||||
);
|
||||
|
||||
$result = '';
|
||||
$field_html = '';
|
||||
$result_html = '';
|
||||
$notes = '';
|
||||
$label = '';
|
||||
$attrs = array();
|
||||
switch ($field_type) {
|
||||
case self::FORM_FIELD_LABEL:
|
||||
$default_prop = array(
|
||||
'label' => ''
|
||||
);
|
||||
|
||||
$new_prop = Util::get_clean_structure($default_prop, $properties, array(), 'label');
|
||||
$result_html = $new_prop['label'];
|
||||
break;
|
||||
case self::FORM_FIELD_BLANK:
|
||||
$default_prop = array(
|
||||
'content' => ''
|
||||
);
|
||||
|
||||
$new_prop = Util::get_clean_structure($default_prop, $properties, array(), 'content');
|
||||
$result_html = $new_prop['content'];
|
||||
break;
|
||||
case self::FORM_FIELD_RATINGS:
|
||||
$default_prop = array(
|
||||
'items' => array(),
|
||||
'icon' => parent::$icon_source.'-star'
|
||||
);
|
||||
|
||||
$new_prop = Util::get_clean_structure($default_prop, $properties, array(), 'max');
|
||||
if (!is_array($new_prop['items'])) $new_prop['items'] = array($new_prop['items']);
|
||||
$items = $new_prop['items'];
|
||||
$rating_html_list = array();
|
||||
foreach ($items as $item) {
|
||||
$item_prop = array(
|
||||
'max' => 5,
|
||||
'icon' => $new_prop['icon'],
|
||||
'name' => $name.'-'.Util::create_id(),
|
||||
'label' => ''
|
||||
);
|
||||
|
||||
$new_item_prop = Util::set_array_prop_def($item_prop, $item, 'max');
|
||||
$field_html = self::_get_field_html($new_item_prop['name'], self::FORM_FIELD_RATING, $new_item_prop, true);
|
||||
$field_html .= $new_item_prop['label'] ? $new_item_prop['label'] : ' ';
|
||||
|
||||
$result_html = ' <div class="'.$field_class_map[$field_type].'">';
|
||||
$result_html .= $field_html;
|
||||
$result_html .= ' </div>';
|
||||
$rating_html_list[] = $result_html;
|
||||
}
|
||||
|
||||
$result_html = implode('', $rating_html_list);
|
||||
break;
|
||||
case self::FORM_FIELD_RATING:
|
||||
$default_prop = array(
|
||||
'max' => 5,
|
||||
'icon' => parent::$icon_source.'-star'
|
||||
);
|
||||
|
||||
$new_prop = Util::get_clean_structure($default_prop, $properties, array(), 'max');
|
||||
|
||||
$rating_html_list = array();
|
||||
for ($i = $new_prop['max']; $i >= 1; $i--) {
|
||||
$rate_id = $name.'-'.$i;
|
||||
$rating_html = self::_get_field_html($name, self::FORM_FIELD_INPUT, array(
|
||||
'type' => 'radio',
|
||||
'id' => $rate_id
|
||||
), true);
|
||||
|
||||
$rating_html .= '<label for="'.$rate_id.'"><i class="'.parent::$icon_source.' '.$new_prop['icon'].'"></i></label>';
|
||||
$rating_html_list[] = $rating_html;
|
||||
}
|
||||
|
||||
$field_html .= implode('', $rating_html_list);
|
||||
if ($field_html_only) return $field_html;
|
||||
|
||||
$result_html .= ' <label class="'.$field_class_map[$field_type].'">';
|
||||
$result_html .= $field_html;
|
||||
$result_html .= ' </label>';
|
||||
|
||||
break;
|
||||
case self::FORM_FIELD_TEXTAREA:
|
||||
$default_prop = array(
|
||||
'rows' => 3,
|
||||
'attr' => array(),
|
||||
'class' => array(),
|
||||
'icon' => '',
|
||||
'icon_append' => true,
|
||||
'value' => '',
|
||||
'id' => '',
|
||||
'type' => '',
|
||||
'placeholder' => '',
|
||||
'disabled' => false,
|
||||
'wrapper' => 'label'
|
||||
);
|
||||
$new_prop = Util::get_clean_structure($default_prop, $properties, array(), 'placeholder');
|
||||
|
||||
$classes = array();
|
||||
$classes[] = 'custom-scroll';
|
||||
if ($new_prop['class']) array_push($classes, $new_prop['class']);
|
||||
|
||||
$attrs = array();
|
||||
$attrs[] = 'class="'.implode(' ', $classes).'"';
|
||||
$attrs[] = 'rows="'.$new_prop['rows'].'"';
|
||||
$attrs[] = 'name="'.$name.'"';
|
||||
if ($new_prop['disabled']) $attrs[] = 'disabled="disabled"';
|
||||
if ($new_prop['id']) $attrs[] = 'id="'.$new_prop['id'].'"';
|
||||
if ($new_prop['placeholder']) $attrs[] = 'placeholder="'.$new_prop['placeholder'].'"';
|
||||
if ($new_prop['attr']) $attrs[] = implode(' ', $new_prop['attr']);
|
||||
|
||||
if ($new_prop['icon'])
|
||||
$field_html .= '<i class="icon-'.($new_prop['icon_append'] ? 'append' : 'prepend').' '.parent::$icon_source.' '.$new_prop['icon'].'"></i>';
|
||||
|
||||
$field_html .= '<textarea '.implode(' ', $attrs).'>';
|
||||
$field_html .= $new_prop['value'];
|
||||
$field_html .= '</textarea>';
|
||||
|
||||
$field_class_map[self::FORM_FIELD_TEXTAREA] = 'textarea'.($new_prop['type'] ? ' textarea-'.$new_prop['type'] : '');
|
||||
|
||||
if ($field_html_only) return $field_html;
|
||||
|
||||
$result_html .= ' <'.$new_prop['wrapper'].' class="'.$field_class_map[$field_type].' '.($new_prop['disabled'] ? 'state-disabled' : '').'">';
|
||||
$result_html .= $field_html;
|
||||
$result_html .= ' </'.$new_prop['wrapper'].'>';
|
||||
|
||||
break;
|
||||
case self::FORM_FIELD_MULTISELECT:
|
||||
if (isset($properties['attr'])) {
|
||||
array_push($properties['attr'], array('multiple="multiple"', 'class="custom-scroll"'));
|
||||
} else {
|
||||
$properties['attr'] = array('multiple="multiple"');
|
||||
}
|
||||
if (isset($properties['class'])) array_push($properties['class'], array('custom-scroll'));
|
||||
else $properties['class'] = array('custom-scroll');
|
||||
|
||||
$properties['icon'] = '';
|
||||
|
||||
$field_html = self::_get_field_html($name, self::FORM_FIELD_SELECT, $properties, true);
|
||||
|
||||
if ($field_html_only) return $field_html;
|
||||
|
||||
$result_html .= ' <label class="'.$field_class_map[$field_type].'">';
|
||||
$result_html .= $field_html;
|
||||
$result_html .= ' </label>';
|
||||
break;
|
||||
case self::FORM_FIELD_SELECT2_MULTI:
|
||||
if (isset($properties['attr'])) {
|
||||
array_push($properties['attr'], array('multiple="multiple"', 'class="custom-scroll"'));
|
||||
} else {
|
||||
$properties['attr'] = array('multiple="multiple"');
|
||||
}
|
||||
if (isset($properties['class'])) array_push($properties['class'], array('select2 custom-scroll'));
|
||||
else $properties['class'] = array('select2 custom-scroll');
|
||||
|
||||
$properties['icon'] = '';
|
||||
|
||||
$field_html = self::_get_field_html($name, self::FORM_FIELD_SELECT, $properties, true);
|
||||
|
||||
if ($field_html_only) return $field_html;
|
||||
|
||||
$result_html .= ' <label class="'.$field_class_map[$field_type].'">';
|
||||
$result_html .= $field_html;
|
||||
$result_html .= ' </label>';
|
||||
break;
|
||||
case self::FORM_FIELD_SELECT2:
|
||||
if (isset($properties['class'])) {
|
||||
if (!is_array($properties['class'])) $properties['class'] = array($properties['class']);
|
||||
array_push($properties['class'], 'select2');
|
||||
} else $properties['class'] = array('select2');
|
||||
|
||||
$properties['icon'] = '';
|
||||
|
||||
$field_html = self::_get_field_html($name, self::FORM_FIELD_SELECT, $properties, true);
|
||||
|
||||
if ($field_html_only) return $field_html;
|
||||
|
||||
$result_html .= ' <label class="'.$field_class_map[$field_type].'">';
|
||||
$result_html .= $field_html;
|
||||
$result_html .= ' </label>';
|
||||
break;
|
||||
case self::FORM_FIELD_SELECT:
|
||||
$default_prop = array(
|
||||
'data' => array(),
|
||||
'display' => '',
|
||||
'value' => '',
|
||||
'container' => 'select',
|
||||
'selected' => array(),
|
||||
'id' => '',
|
||||
'attr' => array(),
|
||||
'class' => array(),
|
||||
'icon' => '<i></i>',
|
||||
'item_attr' => null,
|
||||
'disabled' => false
|
||||
);
|
||||
|
||||
|
||||
|
||||
$new_prop = Util::get_clean_structure($default_prop, $properties, array(), 'data');
|
||||
$data = $new_prop['data'];
|
||||
if (!is_array($data)) {
|
||||
parent::err('SmartUI::Form "data" is required for "select" field.');
|
||||
return '';
|
||||
}
|
||||
|
||||
if (!$data) $data = array(array('No Data'));
|
||||
|
||||
$arr_data = (array)$data;
|
||||
|
||||
if (!$new_prop['display']) {
|
||||
$display_key = is_array($arr_data[0]) ? array_keys($arr_data[0]) : 0;
|
||||
$new_prop['display'] = $display_key ? $display_key[0] : 0;
|
||||
}
|
||||
|
||||
if (!$new_prop['value']) {
|
||||
$value_key = is_array($arr_data[0]) ? array_keys($arr_data[0]) : 0;
|
||||
$new_prop['value'] = $value_key ? $value_key[0] : 0;
|
||||
}
|
||||
|
||||
$selected_list = is_array($new_prop['selected']) ? $new_prop['selected'] : array($new_prop['selected']);
|
||||
|
||||
$option_list = array();
|
||||
foreach ($data as $row) {
|
||||
$item_attr = '';
|
||||
$arr_row = (array)$row;
|
||||
|
||||
if (isset($new_prop['item_attr'])) {
|
||||
$item_attr = Util::get_property_value($new_prop['item_attr'], array(
|
||||
'if_closure' => function($item_attr) use ($row) {
|
||||
return Util::run_callback($item_attr, array($row));
|
||||
},
|
||||
'if_array' => function($item_attr) use ($row) {
|
||||
$attrs = array();
|
||||
foreach ($item_attr as $attr) {
|
||||
$attrs[] = Util::replace_col_codes($attr, $row);
|
||||
}
|
||||
|
||||
return implode(' ', $attrs);
|
||||
},
|
||||
'if_other' => function($item_attr) use ($row) {
|
||||
return Util::replace_col_codes($item_attr, $row);
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
if (Util::is_closure($new_prop['value'])) $value = $new_prop['value']($row);
|
||||
else $value = $arr_row[$new_prop['value']];
|
||||
|
||||
if (Util::is_closure($new_prop['display'])) $display = $new_prop['display']($row);
|
||||
else $display = $arr_row[$new_prop['display']];
|
||||
|
||||
$selected = in_array($value, $selected_list);
|
||||
|
||||
$option_list[] = '<option value="'.$value.'"'.($selected ? ' selected' : '').($item_attr ? ' '.$item_attr : '').'>'.$display.'</option>';
|
||||
}
|
||||
|
||||
$attrs = array();
|
||||
$attrs[] = 'name="'.$name.'"';
|
||||
|
||||
$classes = is_array($new_prop['class']) ? $new_prop['class'] : array($new_prop['class']);
|
||||
|
||||
if ($new_prop['disabled']) $attrs[] = 'disabled="disabled"';
|
||||
if ($new_prop['id']) $attrs[] = 'id="'.$new_prop['id'].'"';
|
||||
if ($new_prop['attr']) $attrs[] = implode(' ', $new_prop['attr']);
|
||||
if ($new_prop['class']) $attrs[] = 'class="'.implode(' ', $classes).'"';
|
||||
|
||||
$field_html = '<'.$new_prop['container'].' '.implode(' ', $attrs).'>';
|
||||
$field_html .= implode('', $option_list);
|
||||
$field_html .= '</'.$new_prop['container'].'>'.$new_prop['icon'];
|
||||
|
||||
if ($field_html_only) return $field_html;
|
||||
|
||||
$result_html .= ' <label class="'.$field_class_map[$field_type].' '.($new_prop['disabled'] ? 'state-disabled' : '').'">';
|
||||
$result_html .= $field_html;
|
||||
$result_html .= ' </label>';
|
||||
break;
|
||||
case self::FORM_FIELD_FILEINPUT:
|
||||
$file_button = self::_get_field_html($name, self::FORM_FIELD_INPUT, array(
|
||||
'type' => 'file',
|
||||
'attr' => array_merge(array('onchange="this.parentNode.nextSibling.value = this.value"'), isset($properties['attr']) ? $properties['attr'] : array())
|
||||
), true);
|
||||
$field_html = '<span class="button">';
|
||||
$field_html .= $file_button;
|
||||
$field_html .= 'Browse</span>';
|
||||
|
||||
|
||||
$default_prop = array(
|
||||
'icon' => false,
|
||||
'tooltip' => false,
|
||||
'attr' => array('readonly'),
|
||||
'type' => 'text'
|
||||
);
|
||||
if ($properties) {
|
||||
foreach ($properties as $key => $value) {
|
||||
if (!isset($default_prop[$key])) {
|
||||
$default_prop[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$field_html .= self::_get_field_html($name.'-display', self::FORM_FIELD_INPUT, $default_prop, true);
|
||||
|
||||
if ($field_html_only) return $field_html;
|
||||
|
||||
$result_html .= ' <label class="'.$field_class_map[$field_type].'">';
|
||||
$result_html .= $field_html;
|
||||
$result_html .= ' </label>';
|
||||
break;
|
||||
case self::FORM_FIELD_HIDDEN:
|
||||
$default_prop = array(
|
||||
'icon' => false,
|
||||
'tooltip' => false,
|
||||
'type' => 'hidden',
|
||||
'value' => ''
|
||||
);
|
||||
|
||||
$new_prop = Util::get_clean_structure($default_prop, $properties, array(), 'value');
|
||||
|
||||
$field_html .= self::_get_field_html($name, self::FORM_FIELD_INPUT, $new_prop, true);
|
||||
return $field_html;
|
||||
break;
|
||||
case self::FORM_FIELD_INPUT:
|
||||
$default_prop = array(
|
||||
'type' => 'text',
|
||||
'attr' => array(),
|
||||
'id' => '',
|
||||
'icon' => '',
|
||||
'icon_append' => true,
|
||||
'icon_attr' => array(),
|
||||
'append' => '',
|
||||
'placeholder' => '',
|
||||
'value' => '',
|
||||
'tooltip' => array(),
|
||||
'disabled' => false,
|
||||
'autocomplete' => false,
|
||||
'size' => '',
|
||||
'class' => array()
|
||||
);
|
||||
|
||||
$new_prop = Util::get_clean_structure($default_prop, $properties, array(), 'placeholder');
|
||||
|
||||
$classes = array();
|
||||
if ($new_prop['class']) array_push($classes, $new_prop['class']);
|
||||
if ($new_prop['size']) $classes[] = 'input-'.$new_prop['size'];
|
||||
$attrs = array();
|
||||
$attrs[] = $classes ? 'class="'.implode(' ', $classes).'"' : '';
|
||||
$attrs[] = 'type="'.$new_prop['type'].'"';
|
||||
$attrs[] = 'name="'.$name.'"';
|
||||
if ($new_prop['attr']) $attrs[] = implode(' ', $new_prop['attr']);
|
||||
if ($new_prop['id']) $attrs[] = 'id="'.$new_prop['id'].'"';
|
||||
$attrs[] = 'value="'.$new_prop['value'].'"';
|
||||
if ($new_prop['placeholder']) $attrs[] = 'placeholder="'.$new_prop['placeholder'].'"';
|
||||
if ($new_prop['disabled']) $attrs[] = 'disabled="disabled"';
|
||||
$ac_html = '';
|
||||
if ($new_prop['autocomplete']) {
|
||||
$ac_prop = array(
|
||||
'data' => array(),
|
||||
'display' => '',
|
||||
'value' => ''
|
||||
);
|
||||
if (!isset($new_prop['autocomplete']['data']))
|
||||
$ac_prop['data'] = $new_prop['autocomplete'];
|
||||
else {
|
||||
$ac_prop['data'] = $new_prop['autocomplete']['data'];
|
||||
$ac_prop['display'] = isset($new_prop['autocomplete']['display']) ? $new_prop['autocomplete']['display'] : '';
|
||||
$ac_prop['value'] = isset($new_prop['autocomplete']['value']) ? $new_prop['autocomplete']['value'] : '';
|
||||
}
|
||||
|
||||
$list_name = 'list-'.$name.'-'.Util::create_id();
|
||||
$ac_html = self::_get_field_html('', self::FORM_FIELD_SELECT, array(
|
||||
'container' => 'datalist',
|
||||
'data' => $ac_prop['data'],
|
||||
'display' => $ac_prop['display'],
|
||||
'value' => $ac_prop['value'],
|
||||
'id' => $list_name
|
||||
), true);
|
||||
$attrs[] = 'list="'.$list_name.'"';
|
||||
}
|
||||
|
||||
if ($new_prop['icon']) {
|
||||
$def_icon_prop = array(
|
||||
'class' => '',
|
||||
'append' => $new_prop['icon_append'],
|
||||
'attr' => array(),
|
||||
'tag' => 'i'
|
||||
);
|
||||
|
||||
$icon_prop = Util::set_array_prop_def($def_icon_prop, $new_prop['icon'], 'class');
|
||||
|
||||
$icon_attrs = implode(' ', $icon_prop['attr']);
|
||||
$field_html .= '<'.$icon_prop['tag'].' class="icon-'.($icon_prop['append'] ? 'append' : 'prepend').' '.parent::$icon_source.' '.$icon_prop['class'].'" '.$icon_attrs.'></'.$icon_prop['tag'].'>';
|
||||
}
|
||||
|
||||
$field_html .= '<input '.implode(' ', $attrs).' />';
|
||||
$field_html .= $ac_html;
|
||||
$field_html .= $new_prop['append'];
|
||||
|
||||
if ($new_prop['tooltip']) {
|
||||
$tooltip_prop = array(
|
||||
'content' => '',
|
||||
'position' => 'top-right'
|
||||
);
|
||||
|
||||
$new_tooltip_prop = Util::set_array_prop_def($tooltip_prop, $new_prop['tooltip'], 'content');
|
||||
$field_html .= '<b class="tooltip tooltip-'.$new_tooltip_prop['position'].'">'.$new_tooltip_prop['content'].'</b>';
|
||||
}
|
||||
|
||||
if ($field_html_only) return $field_html;
|
||||
|
||||
$result_html .= ' <label class="'.$field_class_map[$field_type].' '.($new_prop['disabled'] ? 'state-disabled' : '').'">';
|
||||
$result_html .= $field_html;
|
||||
$result_html .= ' </label>';
|
||||
break;
|
||||
case self::FORM_FIELD_RADIO:
|
||||
$default_prop = array(
|
||||
'items' => array(),
|
||||
'cols' => 0,
|
||||
'inline' => false,
|
||||
'toggle' => false
|
||||
);
|
||||
|
||||
$new_prop = Util::get_clean_structure($default_prop, $properties, array(), 'items');
|
||||
|
||||
if (!is_array($new_prop['items'])) $new_prop['items'] = array($new_prop['items']);
|
||||
|
||||
$items = $new_prop['items'];
|
||||
$item_list_html = array();
|
||||
foreach ($items as $item) {
|
||||
$items_prop = array(
|
||||
'name' => $name,
|
||||
'checked' => false,
|
||||
'value' => '',
|
||||
'label' => '',
|
||||
'id' => '',
|
||||
'disabled' => false
|
||||
);
|
||||
|
||||
$new_item_prop = Util::set_array_prop_def($items_prop, $item, 'label');
|
||||
|
||||
$item_html = self::_get_field_html($new_item_prop['name'], self::FORM_FIELD_INPUT, array(
|
||||
'type' => 'radio',
|
||||
'attr' => $new_item_prop['checked'] ? array('checked') : null,
|
||||
'value' => $new_item_prop['value'],
|
||||
'id' => $new_item_prop['id']
|
||||
), true);
|
||||
|
||||
if ($new_prop['toggle']) {
|
||||
$text_off = is_array($new_prop['toggle']) && isset($new_prop['toggle']['text-off']) ? $new_prop['toggle']['text-off'] : 'OFF';
|
||||
$text_on = is_array($new_prop['toggle']) && isset($new_prop['toggle']['text-on']) ? $new_prop['toggle']['text-on'] : 'ON';
|
||||
$item_html .= '<i data-swchon-text="'.$text_on.'" data-swchoff-text="'.$text_off.'"></i>';
|
||||
} else $item_html .= '<i></i>';
|
||||
|
||||
$item_html .= $new_item_prop['label'];
|
||||
|
||||
$field_html = ' <label class="'.($new_prop['toggle'] ? 'toggle' : $field_class_map[$field_type]).' '.($new_item_prop['disabled'] ? 'state-disabled' : '').'">';
|
||||
$field_html .= $item_html;
|
||||
$field_html .= ' </label>';
|
||||
|
||||
$item_list_html[] = $field_html;
|
||||
}
|
||||
|
||||
if ($new_prop['cols']) {
|
||||
$result_html .= '<div class="row">';
|
||||
$result_html .= self::print_col_items($item_list_html, function($item) { return $item; }, $new_prop['cols'], true);
|
||||
$result_html .= '</div>';
|
||||
} else {
|
||||
$list_html = implode('', $item_list_html);
|
||||
if ($new_prop['inline']) {
|
||||
$result_html .= '<div class="inline-group">';
|
||||
$result_html .= $list_html;
|
||||
$result_html .= '</div>';
|
||||
} else $result_html .= $list_html;
|
||||
}
|
||||
|
||||
if ($field_html_only) return $result_html;
|
||||
|
||||
break;
|
||||
case self::FORM_FIELD_CHECKBOX:
|
||||
$default_prop = array(
|
||||
'items' => array(),
|
||||
'cols' => 0,
|
||||
'inline' => false,
|
||||
'toggle' => false
|
||||
);
|
||||
|
||||
$new_prop = Util::get_clean_structure($default_prop, $properties, array(), 'items');
|
||||
|
||||
if (!is_array($new_prop['items'])) $new_prop['items'] = array($new_prop['items']);
|
||||
|
||||
$items = $new_prop['items'];
|
||||
$item_list_html = array();
|
||||
foreach ($items as $item) {
|
||||
$items_prop = array(
|
||||
'name' => $name,
|
||||
'checked' => false,
|
||||
'value' => '',
|
||||
'label' => '',
|
||||
'id' => '',
|
||||
'disabled' => false
|
||||
);
|
||||
|
||||
$new_item_prop = Util::set_array_prop_def($items_prop, $item, 'label');
|
||||
|
||||
$item_html = self::_get_field_html($new_item_prop['name'], self::FORM_FIELD_INPUT, array(
|
||||
'type' => 'checkbox',
|
||||
'attr' => $new_item_prop['checked'] ? array('checked') : null,
|
||||
'value' => $new_item_prop['value'],
|
||||
'id' => $new_item_prop['id']
|
||||
), true);
|
||||
|
||||
if ($new_prop['toggle']) {
|
||||
$text_off = is_array($new_prop['toggle']) && isset($new_prop['toggle']['text-off']) ? $new_prop['toggle']['text-off'] : 'OFF';
|
||||
$text_on = is_array($new_prop['toggle']) && isset($new_prop['toggle']['text-on']) ? $new_prop['toggle']['text-on'] : 'ON';
|
||||
$item_html .= '<i data-swchon-text="'.$text_on.'" data-swchoff-text="'.$text_off.'"></i>';
|
||||
} else $item_html .= '<i></i>';
|
||||
|
||||
$item_html .= $new_item_prop['label'];
|
||||
|
||||
$field_html = ' <label class="'.($new_prop['toggle'] ? 'toggle' : $field_class_map[$field_type]).' '.($new_item_prop['disabled'] ? 'state-disabled' : '').'">';
|
||||
$field_html .= $item_html;
|
||||
$field_html .= ' </label>';
|
||||
|
||||
$item_list_html[] = $field_html;
|
||||
}
|
||||
|
||||
if ($new_prop['cols']) {
|
||||
$result_html .= '<div class="row">';
|
||||
$result_html .= self::print_col_items($item_list_html, function($item) { return $item; }, $new_prop['cols'], true);
|
||||
$result_html .= '</div>';
|
||||
} else {
|
||||
$list_html = implode('', $item_list_html);
|
||||
if ($new_prop['inline']) {
|
||||
$result_html .= '<div class="inline-group">';
|
||||
$result_html .= $list_html;
|
||||
$result_html .= '</div>';
|
||||
} else $result_html .= $list_html;
|
||||
}
|
||||
|
||||
if ($field_html_only) return $result_html;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (is_array($properties)) {
|
||||
$notes = isset($properties['note']) ? '<div class="note">'.$properties['note'].'</div>' : '';
|
||||
$label = isset($properties['label']) && $properties['label'] ? '<label class="label">'.$properties['label'].'</label>' : '';
|
||||
}
|
||||
$result .= $label;
|
||||
$result .= $result_html;
|
||||
$result .= $notes;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function print_col_items($items, $closure_content, $columns = 1, $return = false) {
|
||||
$htm_result = '';
|
||||
$arr_htm_items = array();
|
||||
$col_cntr = 0;
|
||||
$row_cntr = 0;
|
||||
$result_count = 0;
|
||||
for ($i=0; $i < $columns;$i++) {
|
||||
$arr_htm_items[$i] = "";
|
||||
}
|
||||
$htm_item = "";
|
||||
if ($items) {
|
||||
$result_count = count($items);
|
||||
foreach ($items as $item_data) {
|
||||
if ($row_cntr >= ($result_count / $columns)) {
|
||||
$col_cntr++;
|
||||
$row_cntr = 0;
|
||||
$htm_item = "";
|
||||
}
|
||||
$row_cntr++;
|
||||
|
||||
$htm_item .= $closure_content($item_data);
|
||||
$arr_htm_items[$col_cntr] = '<div class="col col-'.(12 / $columns).'">'.$htm_item.'</div>';
|
||||
}
|
||||
foreach ($arr_htm_items as $item_content) {
|
||||
$htm_result .= $item_content;
|
||||
}
|
||||
}
|
||||
if ($return) return $htm_result;
|
||||
else echo $htm_result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
255
lib/smartui/Components/Tab.php
Normal file
255
lib/smartui/Components/Tab.php
Normal file
@ -0,0 +1,255 @@
|
||||
<?php
|
||||
|
||||
namespace SmartUI\Components;
|
||||
use \SmartUI\UI;
|
||||
use \SmartUI\Util;
|
||||
|
||||
class Tab extends UI {
|
||||
|
||||
private $_options_map = array(
|
||||
'bordered' => true,
|
||||
'position' => '',
|
||||
'pull' => '',
|
||||
'padding' => 10,
|
||||
'widget' => false,
|
||||
'toggle' => true,
|
||||
'titles' => 'text',
|
||||
'class' => ''
|
||||
);
|
||||
|
||||
private $_structure = array(
|
||||
'tab' => array(),
|
||||
'content' => array(),
|
||||
'html' => array(),
|
||||
'url' => array(),
|
||||
'content_id' => '',
|
||||
'content_class' => '',
|
||||
'icon' => array(),
|
||||
'tabs_id' => '',
|
||||
'title' => array(),
|
||||
'options' => array(),
|
||||
'active' => array(),
|
||||
'dropdown' => array(),
|
||||
'position' => array()
|
||||
);
|
||||
|
||||
public function __construct($tabs, $options = array()) {
|
||||
$this->_init_structure($tabs, $options);
|
||||
}
|
||||
|
||||
private function _init_structure($tabs, $user_options = array()) {
|
||||
$this->_structure = Util::array_to_object($this->_structure);
|
||||
$this->_structure->options = Util::set_array_prop_def($this->_options_map, $user_options);
|
||||
|
||||
$this->_structure->tab = $tabs;
|
||||
}
|
||||
|
||||
public function __get($name) {
|
||||
if (isset($this->_structure->{$name})) {
|
||||
return $this->_structure->{$name};
|
||||
}
|
||||
parent::err('Undefined structure property: '.$name);
|
||||
return null;
|
||||
}
|
||||
|
||||
public function __set($name, $value) {
|
||||
if (isset($this->_structure->{$name})) {
|
||||
$this->_structure->{$name} = $value;
|
||||
return;
|
||||
}
|
||||
parent::err('Undefined structure property: '.$name);
|
||||
}
|
||||
|
||||
public function __call($name, $args) {
|
||||
return parent::_call($this, $this->_structure, $name, $args);
|
||||
}
|
||||
|
||||
public function print_html($return = false) {
|
||||
|
||||
|
||||
$structure = $this->_structure;
|
||||
|
||||
$structure->options = Util::set_array_prop_def($this->_options_map, $structure->options);
|
||||
|
||||
$tabs = Util::get_property_value($structure->tab, array(
|
||||
'if_closure' => function($tabs) {
|
||||
return Util::run_callback($tabs, array($this));
|
||||
},
|
||||
'if_other' => function($tabs) {
|
||||
parent::err('SmartUI::Tab::tab requires array');
|
||||
return null;
|
||||
}
|
||||
));
|
||||
|
||||
if (!is_array($tabs)) {
|
||||
parent::err("SmartUI::Tab::tab requires array");
|
||||
return null;
|
||||
}
|
||||
|
||||
$li_list = array();
|
||||
$tab_content_list = array();
|
||||
$has_active = false;
|
||||
foreach ($tabs as $tab_id => $tab_prop) {
|
||||
$tab_structure = array(
|
||||
'content' => isset($structure->content[$tab_id]) ? $structure->content[$tab_id] : '',
|
||||
'title' => isset($structure->title[$tab_id]) ? $structure->title[$tab_id] : '',
|
||||
'icon' => isset($structure->icon[$tab_id]) ? $structure->icon[$tab_id] : '',
|
||||
'dropdown' => isset($structure->dropdown[$tab_id]) ? $structure->dropdown[$tab_id] : '',
|
||||
'position' => isset($structure->position[$tab_id]) ? $structure->position[$tab_id] : '',
|
||||
'active' => isset($structure->active[$tab_id]) && $structure->active[$tab_id] === true,
|
||||
'fade' => false,
|
||||
'url' => isset($structure->url[$tab_id]) ? $structure->url[$tab_id] : '#'.$tab_id,
|
||||
'toggle' => true,
|
||||
'id' => false,
|
||||
'attr' => array(),
|
||||
'content_class' => array(),
|
||||
'html' => isset($structure->html[$tab_id]) ? $structure->html[$tab_id] : ''
|
||||
);
|
||||
|
||||
$new_tab_prop = Util::get_clean_structure($tab_structure, $tab_prop, array($this, $tabs, $tab_id), 'title');
|
||||
|
||||
foreach ($new_tab_prop as $tab_prop_key => $tab_prop_vaue) {
|
||||
$new_tab_prop_value = Util::get_property_value($tab_prop_vaue, array(
|
||||
'if_closure' => function($prop_value) use ($tabs) {
|
||||
return Util::run_callback($prop_value, array($this, $tabs));
|
||||
}
|
||||
));
|
||||
$new_tab_prop[$tab_prop_key] = $new_tab_prop_value;
|
||||
}
|
||||
|
||||
$tab_content_classes = is_array($new_tab_prop['content_class']) ? $new_tab_prop['content_class'] : array($new_tab_prop['content_class']);
|
||||
$tab_content_classes[] = 'tab-pane';
|
||||
$li_classes = array();
|
||||
$a_classes = array();
|
||||
$a_attr = array_map(function($attr, $value) {
|
||||
return $attr.'="'.$value.'"';
|
||||
}, array_keys($new_tab_prop['attr']), $new_tab_prop['attr']);
|
||||
|
||||
if ($new_tab_prop['active'] === true && !$has_active) {
|
||||
$li_classes[] = 'active';
|
||||
$tab_content_classes[] = 'in active';
|
||||
$has_active = true;
|
||||
}
|
||||
|
||||
// $a_attr[] = 'title="'.$new_tab_prop['title'].'"';
|
||||
if (!$structure->options['titles']) {
|
||||
$title = '';
|
||||
} else if ($structure->options['titles'] == 'tooltip') {
|
||||
$title = '';
|
||||
$a_attr[] = 'rel="tooltip"';
|
||||
$a_attr[] = 'data-placement="top"';
|
||||
$a_attr[] = 'title="'.$new_tab_prop['title'].'"';
|
||||
} else {
|
||||
$title = $new_tab_prop['title'];
|
||||
}
|
||||
$dropdown_html = '';
|
||||
if ($new_tab_prop['dropdown']) {
|
||||
$dropdown = $new_tab_prop['dropdown'];
|
||||
$li_classes[] = 'dropdown';
|
||||
$href = 'javascript:void(0);';
|
||||
$dropdown_html = is_array($dropdown) ? parent::print_dropdown($dropdown, false, true) : $dropdown;
|
||||
$a_classes[] = 'dropdown-toggle';
|
||||
$a_attr[] = 'data-toggle="dropdown"';
|
||||
$title .= ' <b class="caret"></b>';
|
||||
} else {
|
||||
$href = $new_tab_prop['url'];
|
||||
if ($structure->options['toggle'] && $new_tab_prop['toggle'])
|
||||
$a_attr[] = 'data-toggle="tab"';
|
||||
}
|
||||
|
||||
if ($new_tab_prop['id']) $a_attr[] = 'id="'.$new_tab_prop['id'].'"';
|
||||
|
||||
if ($new_tab_prop['position']) $li_classes[] = 'pull-'.$new_tab_prop['position'];
|
||||
$icon = $new_tab_prop['icon'] ? '<i class="'.parent::$icon_source.' '.$new_tab_prop['icon'].'"></i> ' : '';
|
||||
$class = $li_classes ? ' class="'.implode(' ', $li_classes).'"' : '';
|
||||
|
||||
$li_html = '<li'.$class.'>';
|
||||
|
||||
if ($new_tab_prop['html']) {
|
||||
$li_html .= $new_tab_prop['html'];
|
||||
} else {
|
||||
$li_html .= '<a href="'.$href.'" '.($a_classes ? 'class="'.implode(' ', $a_classes).'"' : '').($a_attr ? ' '.implode(' ', $a_attr) : '').' rel="tooltip" data-placement="top">'.$icon.$title.'</a>';
|
||||
$li_html .= $dropdown_html;
|
||||
}
|
||||
|
||||
$li_html .= '</li>';
|
||||
$li_list[] = $li_html;
|
||||
|
||||
if ($new_tab_prop['fade']) $tab_content_classes[] = 'fade';
|
||||
$tab_content_html = '<div class="'.implode(' ', $tab_content_classes).'" id="'.$tab_id.'">';
|
||||
$tab_content_html .= $new_tab_prop['content'];
|
||||
$tab_content_html .= '</div>';
|
||||
$tab_content_list[] = $tab_content_html;
|
||||
}
|
||||
|
||||
$ul_classes = array();
|
||||
$ul_attr = array();
|
||||
$ul_classes[] = 'nav nav-tabs '.$structure->options['class'];
|
||||
$ul_id = $structure->tabs_id ? 'id="'.$structure->tabs_id.'"' : '';
|
||||
$ul_attr[] = $ul_id;
|
||||
|
||||
$content_classes = array();
|
||||
$content_classes[] = 'tab-content';
|
||||
if ($structure->content_class)
|
||||
$content_classes[] = is_array($structure->content_class) ? implode(' ', $structure->content_class) : $structure->content_class;
|
||||
$content_id = $structure->content_id ? 'id="'.$structure->content_id.'"' : '';
|
||||
if ($structure->options['padding']) $content_classes[] = 'padding-'.$structure->options['padding'];
|
||||
$content_html = '<div class="'.implode(' ', $content_classes).'" '.$content_id.'>';
|
||||
$content_html .= implode('', $tab_content_list);
|
||||
$content_html .= '</div>';
|
||||
|
||||
$main_content_html = '';
|
||||
if ($structure->options['widget']) {
|
||||
|
||||
$ul_classes[] = $structure->options['pull'] ? 'pull-'.$structure->options['pull'] : 'pull-left';
|
||||
|
||||
$ul_html = '<ul class="'.implode(' ', $ul_classes).'" '.implode(' ', $ul_attr).'>';
|
||||
$ul_html .= implode('', $li_list);
|
||||
$ul_html .= '</ul>';
|
||||
$widget = $structure->options['widget'];
|
||||
if (!$widget instanceof Widget) {
|
||||
$widget = new Widget();
|
||||
}
|
||||
|
||||
$widget->body('content', $content_html);
|
||||
$widget->options('colorbutton', false)->options('editbutton', false);
|
||||
$widget->header('title', $widget->header('title').' '.$ul_html);
|
||||
|
||||
$result = $widget->print_html(true);
|
||||
|
||||
} else {
|
||||
if ($structure->options['bordered']) $ul_classes[] = 'bordered';
|
||||
if ($structure->options['pull']) $ul_classes[] = 'tabs-pull-'.$structure->options['pull'];
|
||||
|
||||
$ul_html = '<ul class="'.implode(' ', $ul_classes).'" '.implode(' ', $ul_attr).'>';
|
||||
$ul_html .= implode('', $li_list);
|
||||
$ul_html .= '</ul>';
|
||||
|
||||
$container_classes = array();
|
||||
$container_classes[] = 'tabbable';
|
||||
switch ($structure->options['position']) {
|
||||
case 'right':
|
||||
case 'left':
|
||||
$container_classes[] = 'tabs-'.$structure->options['position'];
|
||||
$main_content_html = $ul_html.$content_html;
|
||||
break;
|
||||
case 'below':
|
||||
$container_classes[] = 'tabs-'.$structure->options['position'];
|
||||
$main_content_html = $content_html.$ul_html;
|
||||
break;
|
||||
default:
|
||||
$main_content_html = $ul_html.$content_html;
|
||||
break;
|
||||
}
|
||||
|
||||
$result = '<div class="'.implode(' ', $container_classes).'">';
|
||||
$result .= $main_content_html;
|
||||
$result .= '</div>';
|
||||
}
|
||||
|
||||
if ($return) return $result;
|
||||
else echo $result;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
317
lib/smartui/Components/Widget.php
Normal file
317
lib/smartui/Components/Widget.php
Normal file
@ -0,0 +1,317 @@
|
||||
<?php
|
||||
|
||||
namespace SmartUI\Components;
|
||||
use \SmartUI\UI;
|
||||
use \SmartUI\Util;
|
||||
|
||||
class Widget extends UI {
|
||||
|
||||
private $_options_map = array(
|
||||
"editbutton" => true,
|
||||
"colorbutton" => true,
|
||||
"editbutton" => true,
|
||||
"togglebutton" => true,
|
||||
"deletebutton" => true,
|
||||
"fullscreenbutton" => true,
|
||||
"custombutton" => true,
|
||||
"collapsed" => false,
|
||||
"sortable" => true,
|
||||
"refreshbutton" => false
|
||||
);
|
||||
|
||||
private $_structure = array(
|
||||
"class" => "",
|
||||
"color" => "",
|
||||
"id" => "",
|
||||
"attr" => array(),
|
||||
"options" => array(),
|
||||
"header" => array(),
|
||||
"footer" => "",
|
||||
"footers" => array(),
|
||||
"body" => array()
|
||||
);
|
||||
|
||||
public function __construct($options = array(), $contents = array()) {
|
||||
$this->_init_structure($options, $contents);
|
||||
}
|
||||
|
||||
private function _init_structure($user_options, $user_contents) {
|
||||
$this->_structure = Util::array_to_object($this->_structure);
|
||||
|
||||
$user_contents_map = array("header" => array(), "body" => "", "color" => "");
|
||||
$new_user_contents = Util::set_array_prop_def($user_contents_map, $user_contents);
|
||||
|
||||
$this->_structure->options = Util::set_array_prop_def($this->_options_map, $user_options);
|
||||
|
||||
$body_structure = array(
|
||||
"editbox" => "",
|
||||
"content" => "",
|
||||
"class" => "",
|
||||
"toolbar" => null,
|
||||
"footer" => null
|
||||
);
|
||||
$this->_structure->body = Util::set_array_prop_def($body_structure, $new_user_contents["body"], "content");
|
||||
|
||||
$header_structure = array(
|
||||
"icon" => null,
|
||||
"class" => "",
|
||||
"title" => "",
|
||||
"toolbar" => array()
|
||||
);
|
||||
$this->_structure->header = Util::set_array_prop_def($header_structure, $new_user_contents["header"], "title");
|
||||
|
||||
$this->_structure->color = $new_user_contents["color"];
|
||||
$this->_structure->id = Util::create_id(true);
|
||||
}
|
||||
|
||||
public function __set($name, $value) {
|
||||
if (isset($this->_structure->{$name})) {
|
||||
$this->_structure->{$name} = $value;
|
||||
return;
|
||||
}
|
||||
parent::err('Undefined structure property: '.$name);
|
||||
}
|
||||
|
||||
public function __call($name, $args) {
|
||||
return parent::_call($this, $this->_structure, $name, $args);
|
||||
}
|
||||
|
||||
public function __get($name) {
|
||||
if (isset($this->_structure->{$name})) {
|
||||
return $this->_structure->{$name};
|
||||
}
|
||||
parent::err('Undefined structure property: '.$name);
|
||||
return null;
|
||||
}
|
||||
|
||||
public function print_html($return = false) {
|
||||
|
||||
|
||||
$structure = $this->_structure;
|
||||
|
||||
$attr = Util::get_property_value(
|
||||
$structure->attr,
|
||||
array(
|
||||
"if_closure" => function($attr) { return Util::run_callback($attr, array($this)); }, //if user passes a closure, pass those optional parameters that they can use
|
||||
"if_other" => function($attr) { return $attr; }, //just directly return the string for this type of structure item
|
||||
"if_array" => function($attr) {
|
||||
$props = array_map(function($attr, $attr_value) { //build attribute values from passed array
|
||||
return $attr.' = "'.$attr_value.'"';
|
||||
}, array_keys($attr), $attr);
|
||||
|
||||
return implode(' ', $props);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
$options_map = $this->_options_map;
|
||||
|
||||
$options = Util::get_property_value(
|
||||
$structure->options,
|
||||
array(
|
||||
"if_closure" => function($options) { return Util::run_callback($options, array($this)); },
|
||||
"if_other" => function($options) { return $options; },
|
||||
"if_array" => function($options) use ($options_map) {
|
||||
$props = array_map(function($option, $value) use ($options_map) {
|
||||
if (is_bool($value)) {
|
||||
$str_val = var_export($value, true);
|
||||
if (isset($options_map[$option])) {
|
||||
if ($value !== $options_map[$option]) {
|
||||
return 'data-widget-'.$option.'="'.$str_val.'"';
|
||||
} else return '';
|
||||
} else return 'data-widget-'.$option.'="'.$str_val.'"';
|
||||
}
|
||||
return 'data-widget-'.$option.'="'.$value.'"';
|
||||
}, array_keys($options), $options);
|
||||
|
||||
return implode(' ', $props);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
$body = Util::get_property_value(
|
||||
$structure->body,
|
||||
array(
|
||||
"if_closure" => function($body) { return Util::run_callback($body, array($this)); },
|
||||
"if_other" => function($body) {
|
||||
if ($body === false || is_null($body)) return null;
|
||||
return '<div class="widget-body">'.$body.'</div>';
|
||||
},
|
||||
"if_array" => function($body) {
|
||||
$editbox = '';
|
||||
if (isset($body["editbox"])) {
|
||||
$editbox = '<div class="jarviswidget-editbox">';
|
||||
$editbox .= $body["editbox"];
|
||||
$editbox .= '</div>';
|
||||
}
|
||||
|
||||
$content = '';
|
||||
if (isset($body['content'])) {
|
||||
if (Util::is_closure($body['content'])) {
|
||||
$content = Util::run_callback($body['content'], array($this));
|
||||
} else {
|
||||
$content = $body['content'];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$class = 'widget-body';
|
||||
if (isset($body["class"])) {
|
||||
if (is_array($body["class"])) {
|
||||
$class .= ' '.implode(' ', $body["class"]);
|
||||
} else {
|
||||
$class .= ' '.$body["class"];
|
||||
}
|
||||
}
|
||||
|
||||
$toolbar = '';
|
||||
if (isset($body["toolbar"])) {
|
||||
$toolbar = '<div class="widget-body-toolbar">';
|
||||
$toolbar .= $body["toolbar"];
|
||||
$toolbar .= '</div>';
|
||||
}
|
||||
|
||||
$footer = '';
|
||||
if (isset($body['footer'])) {
|
||||
$footer = '<div class="widget-footer">';
|
||||
$footer .= $body['footer'];
|
||||
$footer .= '</div>';
|
||||
}
|
||||
|
||||
$result = $editbox;
|
||||
$result .= '<div class="'.$class.'">';
|
||||
$result .= $toolbar;
|
||||
$result .= $content;
|
||||
$result .= $footer;
|
||||
$result .= '</div>';
|
||||
|
||||
return $result;
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
$header = Util::get_property_value(
|
||||
$structure->header,
|
||||
array(
|
||||
"if_closure" => function($header) use ($body) { return Util::run_callback($body, array($this)); },
|
||||
"if_other" => function($body) { return $body; },
|
||||
"if_array" => function($body) {
|
||||
$toolbar_htm = '';
|
||||
|
||||
if (isset($body["icon"]) && $body['icon']) {
|
||||
$toolbar_htm .= '<span class="widget-icon"> <i class="'.parent::$icon_source.' '.$body["icon"].'"></i> </span>';
|
||||
}
|
||||
|
||||
if (isset($body["toolbar"])) {
|
||||
$toolbar_htm .= Util::get_property_value($body["toolbar"], array(
|
||||
"if_closure" => function($toolbar) { return Util::run_callback($toolbar, array($this, $toolbar)); },
|
||||
"if_other" => function($toolbar) { return $toolbar; },
|
||||
"if_array" => function($toolbar) {
|
||||
$toolbar_props_htm = array();
|
||||
foreach ($toolbar as $toolbar_prop) {
|
||||
$id = '';
|
||||
$class = 'widget-toolbar';
|
||||
$attrs = array();
|
||||
$content = '';
|
||||
if (is_string($toolbar_prop)) {
|
||||
$content = $toolbar_prop;
|
||||
} else if (is_array($toolbar_prop)) {
|
||||
$id = isset($toolbar_prop["id"]) ? $toolbar_prop["id"] : '';
|
||||
$class .= isset($toolbar_prop["class"]) ? ' '.$toolbar_prop["class"] : '';
|
||||
if (isset($toolbar_prop["attr"])) {
|
||||
if (is_array($toolbar_prop["attr"])) {
|
||||
foreach ($toolbar_prop["attr"] as $attr => $value) {
|
||||
$attrs[] = $attr.'="'.$value.'"';
|
||||
}
|
||||
|
||||
} else {
|
||||
$attrs[] = $toolbar_prop["attr"];
|
||||
}
|
||||
}
|
||||
$content = isset($toolbar_prop["content"]) ? $toolbar_prop["content"] : '';
|
||||
}
|
||||
|
||||
$htm = '<div class="'.trim($class).'" id="'.$id.'" '.implode(' ', $attrs).'>';
|
||||
$htm .= $content;
|
||||
$htm .= '</div>';
|
||||
|
||||
$toolbar_props_htm[] = $htm;
|
||||
}
|
||||
|
||||
return implode(' ', $toolbar_props_htm);
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
if (isset($body["title"])) {
|
||||
$toolbar_htm .= $body["title"];
|
||||
} else
|
||||
$toolbar_htm .= '<h2><code>SmartUI::Widget->header[content] not defined</code></h2>';
|
||||
|
||||
return $toolbar_htm;
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
$footer_htm = '';
|
||||
if ($structure->footer) $structure->footers[] = $structure->footer;
|
||||
foreach ($structure->footers as $footer) {
|
||||
$footer_prop = array(
|
||||
'content' => '',
|
||||
'class' => '',
|
||||
'attr' => array()
|
||||
);
|
||||
$new_footer_prop = Util::get_clean_structure($footer_prop, $footer, array($this), 'content');
|
||||
$footer_attribues = array_map(function($attr, $value) {
|
||||
return $attr.'="'.$value.'"';
|
||||
}, array_keys($new_footer_prop['attr']), $new_footer_prop['attr']);
|
||||
if ($new_footer_prop['class']) $footer_attribues[] = 'class="'.$new_footer_prop['class'].'"';
|
||||
|
||||
$footer_htm .= $new_footer_prop['content'] ? '<footer '.implode(' ', $footer_attribues).'>'.$new_footer_prop['content'].'</footer>' : '';
|
||||
}
|
||||
|
||||
$class = Util::get_property_value($structure->class, array(
|
||||
"if_closure" => function($class) { return Util::run_callback($class, array($this)); },
|
||||
"if_array" => function($class) {
|
||||
return implode(' ', $class);
|
||||
}
|
||||
));
|
||||
|
||||
$color = Util::get_property_value(
|
||||
$structure->color,
|
||||
array(
|
||||
"if_closure" => function($color) { return Util::run_callback($color, array($this)); },
|
||||
"if_other" => function($color) { return $color ? 'jarviswidget-color-'.$color : ''; },
|
||||
"if_array" => function($color) {
|
||||
parent::err('SmartUI::Widget::color requires string');
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
$id = Util::get_property_value(
|
||||
$structure->id,
|
||||
array(
|
||||
"if_closure" => function($id) { return Util::run_callback($id, array($this)); },
|
||||
"if_array" => function($id) {
|
||||
parent::err('SmartUI::Widget::id requires string.');
|
||||
return '';
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
$id = $id ? 'id="'.$id.'"' : '';
|
||||
$main_classes = array('jarviswidget', $color, $class);
|
||||
$main_attributes = array('class="'.trim(implode(' ', $main_classes)).'"', $id, $options, $attr);
|
||||
|
||||
$result = '<div '.trim(implode(' ', $main_attributes)).'>';
|
||||
$result .= '<header>'.$header.'</header>';
|
||||
$result .= is_null($body) ? '' : '<div>'.$body.'</div>';
|
||||
$result .= $footer_htm;
|
||||
$result .= '</div>';
|
||||
|
||||
if ($return) return $result;
|
||||
else echo $result;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
219
lib/smartui/Components/Wizard.php
Normal file
219
lib/smartui/Components/Wizard.php
Normal file
@ -0,0 +1,219 @@
|
||||
<?php
|
||||
|
||||
namespace SmartUI\Components;
|
||||
use \SmartUI\UI;
|
||||
use \SmartUI\Util;
|
||||
|
||||
class Wizard extends UI {
|
||||
|
||||
const WIZARD_BOOTSTRAP = 'bootstrap';
|
||||
const WIZARD_FUEL = 'fuel';
|
||||
|
||||
private $_options_map = array(
|
||||
'in_widget' => true,
|
||||
'type' => Wizard::WIZARD_BOOTSTRAP
|
||||
);
|
||||
|
||||
private $_structure = array(
|
||||
'options' => array(),
|
||||
'step' => array(),
|
||||
'content' => array(),
|
||||
'widget' => null,
|
||||
'active' => array(),
|
||||
'title' => '',
|
||||
'tabl_class' => 'form-wizard',
|
||||
'id' => ''
|
||||
);
|
||||
|
||||
public function __construct($steps, $options = array()) {
|
||||
$this->_init_structure($steps, $options);
|
||||
}
|
||||
|
||||
private function _init_structure($steps, $user_options = array()) {
|
||||
$this->_structure = Util::array_to_object($this->_structure);
|
||||
$this->_structure->options = Util::set_array_prop_def($this->_options_map, $user_options);
|
||||
$this->_structure->step = $steps;
|
||||
$this->_structure->id = Util::create_id(true);
|
||||
$widget = new Widget();
|
||||
$widget->options('editbutton', false)
|
||||
->header('title', '<h2></h2>');
|
||||
|
||||
$this->_structure->widget = $widget;
|
||||
}
|
||||
|
||||
public function __get($name) {
|
||||
if (isset($this->_structure->{$name})) {
|
||||
return $this->_structure->{$name};
|
||||
}
|
||||
SmartUI::err('Undefined structure property: '.$name);
|
||||
return null;
|
||||
}
|
||||
|
||||
public function __set($name, $value) {
|
||||
if (isset($this->_structure->{$name})) {
|
||||
$this->_structure->{$name} = $value;
|
||||
return;
|
||||
}
|
||||
SmartUI::err('Undefined structure property: '.$name);
|
||||
}
|
||||
|
||||
public function __call($name, $args) {
|
||||
return parent::_call($this, $this->_structure, $name, $args);
|
||||
}
|
||||
|
||||
private function _get_bootstrap_result() {
|
||||
|
||||
|
||||
$structure = $this->_structure;
|
||||
|
||||
$steps = Util::get_property_value($structure->step, array(
|
||||
'if_closure' => function($steps) {
|
||||
return SmartUI::run_callback($steps, array($this));
|
||||
},
|
||||
'if_other' => function($steps) {
|
||||
SmartUI::err('SmartUI::Wizard::step requires array');
|
||||
return null;
|
||||
}
|
||||
));
|
||||
|
||||
if (!is_array($steps)) {
|
||||
parent::err("SmartUI::Wizard::step requires array");
|
||||
return null;
|
||||
}
|
||||
|
||||
$li_list = array();
|
||||
$step_content_list = array();
|
||||
$has_active = false;
|
||||
$step = 1;
|
||||
foreach ($steps as $step_id => $step_prop) {
|
||||
$step_structure = array(
|
||||
'content' => isset($structure->content[$step_id]) ? $structure->content[$step_id] : '',
|
||||
'title' => isset($structure->title[$step_id]) ? $structure->title[$step_id] : '',
|
||||
'step' => $step,
|
||||
'active' => isset($structure->active[$step_id]) && $structure->active[$step_id] === true,
|
||||
);
|
||||
|
||||
$new_step_prop = Util::get_clean_structure($step_structure, $step_prop, array($this, $steps, $step_id), 'title');
|
||||
|
||||
foreach ($new_step_prop as $step_prop_key => $step_prop_vaue) {
|
||||
$new_step_prop_value = Util::get_property_value($step_prop_vaue, array(
|
||||
'if_closure' => function($prop_value) use ($steps) {
|
||||
return SmartUI::run_callback($prop_value, array($this, $steps));
|
||||
}
|
||||
));
|
||||
$new_step_prop[$step_prop_key] = $new_step_prop_value;
|
||||
}
|
||||
|
||||
$step_content_classes = array();
|
||||
$step_content_classes[] = 'tab-pane';
|
||||
$li_classes = array();
|
||||
$a_classes = array();
|
||||
$a_attr = array();
|
||||
|
||||
if ((!$structure->active && !$has_active) || ($new_step_prop['active'] === true && !$has_active)) {
|
||||
$li_classes[] = 'active';
|
||||
$step_content_classes[] = 'active';
|
||||
$has_active = true;
|
||||
}
|
||||
|
||||
$title = $new_step_prop['title'];
|
||||
|
||||
$href = '#'.$step_id;
|
||||
$a_attr[] = 'data-toggle="tab"';
|
||||
|
||||
$class = $li_classes ? ' class="'.implode(' ', $li_classes).'"' : '';
|
||||
|
||||
$li_html = '<li'.$class.' data-target="#'.$step_id.'">';
|
||||
$li_html .= '<a href="'.$href.'" '.($a_classes ? 'class="'.implode(' ', $a_classes).'"' : '').($a_attr ? ' '.implode(' ', $a_attr) : '').'>';
|
||||
$li_html .= '<span class="step">'.$new_step_prop['step'].'</span> <span class="title">'.$title.'</span>';
|
||||
$li_html .= '</a>';
|
||||
$li_html .= '</li>';
|
||||
$li_list[] = $li_html;
|
||||
|
||||
$step_content_html = '<div class="'.implode(' ', $step_content_classes).'" id="'.$step_id.'">';
|
||||
$step_content_html .= $new_step_prop['content'];
|
||||
$step_content_html .= '</div>';
|
||||
$step_content_list[] = $step_content_html;
|
||||
|
||||
$step++;
|
||||
}
|
||||
|
||||
$ul_classes = array();
|
||||
$ul_classes[] = 'bootstrapWizard';
|
||||
$ul_classes[] = $structure->tabl_class;
|
||||
|
||||
$content_classes = array();
|
||||
$content_classes[] = 'tab-content';
|
||||
$content_html = '<div class="'.implode(' ', $content_classes).'">';
|
||||
$content_html .= implode('', $step_content_list);
|
||||
$content_html .= ' <div class="form-actions">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<ul class="pager wizard no-margin">
|
||||
<!--<li class="previous first disabled">
|
||||
<a href="javascript:void(0);" class="btn btn-lg btn-default"> First </a>
|
||||
</li>-->
|
||||
<li class="previous disabled">
|
||||
<a href="javascript:void(0);" class="btn btn-lg btn-default"> Previous </a>
|
||||
</li>
|
||||
<!--<li class="next last">
|
||||
<a href="javascript:void(0);" class="btn btn-lg btn-primary"> Last </a>
|
||||
</li>-->
|
||||
<li class="next">
|
||||
<a href="javascript:void(0);" class="btn btn-lg txt-color-darken"> Next </a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>';
|
||||
$content_html .= '</div>';
|
||||
|
||||
|
||||
|
||||
$ul_html = '<div class="form-bootstrapWizard">';
|
||||
$ul_html .= ' <ul class="'.implode(' ', $ul_classes).'">';
|
||||
$ul_html .= implode('', $li_list);
|
||||
$ul_html .= ' </ul>';
|
||||
$ul_html .= ' <div class="clearfix"></div>';
|
||||
$ul_html .= '</div>';
|
||||
|
||||
$main_content_html = '<div class="row">';
|
||||
$main_content_html .= ' <div class="col-sm-12" id="'.$structure->id.'">';
|
||||
$main_content_html .= $ul_html.$content_html;
|
||||
$main_content_html .= ' </div>';
|
||||
$main_content_html .= '</div>';
|
||||
|
||||
|
||||
if (isset($structure->options["in_widget"]) && $structure->options["in_widget"]) {
|
||||
$structure->widget->body("content", $main_content_html);
|
||||
if ($structure->title) {
|
||||
$structure->widget->header('title', $structure->title);
|
||||
}
|
||||
|
||||
$result = $structure->widget->print_html(true);
|
||||
} else $result = $main_content_html;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function _get_fuel_result() {
|
||||
|
||||
}
|
||||
|
||||
public function print_html($return = false) {
|
||||
switch ($this->_structure->options["type"]) {
|
||||
case Wizard::WIZARD_BOOTSTRAP:
|
||||
$result = self::_get_bootstrap_result();
|
||||
break;
|
||||
|
||||
default:
|
||||
parent::err('SmartUI::Wizard Invalid Wizard Type: wizard "'.$this->_structure->options["type"].'" not found.');
|
||||
break;
|
||||
}
|
||||
|
||||
if ($return) return $result;
|
||||
else echo $result;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
500
lib/smartui/UI.php
Normal file
500
lib/smartui/UI.php
Normal file
@ -0,0 +1,500 @@
|
||||
<?php
|
||||
|
||||
namespace SmartUI;
|
||||
|
||||
class UI {
|
||||
|
||||
const SMARTUI_WIDGET = 'widget';
|
||||
const SMARTUI_DATATABLE = 'datatable';
|
||||
const SMARTUI_BUTTON = 'button';
|
||||
const SMARTUI_TAB = 'tab';
|
||||
|
||||
private static $_ui_calls = array('create', 'set', 'get', 'print');
|
||||
private $_track_start_time;
|
||||
|
||||
private static $_uis = array();
|
||||
private static $_alerts = array('info', 'danger', 'primary', 'default', 'warning', 'success');
|
||||
public static $icon_source = 'fa';
|
||||
public static $debug = true;
|
||||
|
||||
public static function register($name, $class) {
|
||||
self::$_uis[$name] = $class;
|
||||
}
|
||||
|
||||
protected function _call($ui_member, $structure, $name, $args) {
|
||||
if (property_exists($structure, $name)) {
|
||||
if (!$args) return $structure->{$name};
|
||||
|
||||
$value = null;
|
||||
$key = null;
|
||||
if (count($args) > 1 && is_array($structure->{$name})) {
|
||||
$key = $args[0];
|
||||
$value = $args[1];
|
||||
if (!is_string($key) && !is_int($key)) {
|
||||
self::err("SmartUI structure property: $name must be string or int.");
|
||||
return null;
|
||||
}
|
||||
|
||||
$structure->{$name}[$key] = $value;
|
||||
|
||||
if (isset($args[2]) && Util::is_closure($args[2])) {
|
||||
//process callback
|
||||
$callback = $args[2];
|
||||
Util::run_callback($callback, array($ui_member));
|
||||
}
|
||||
|
||||
return $ui_member;
|
||||
} else {
|
||||
if (isset($args[1]) && Util::is_closure($args[1])) {
|
||||
$value = $args[0];
|
||||
$structure->{$name} = $value;
|
||||
$callback = $args[1];
|
||||
Util::run_callback($callback, array($ui_member));
|
||||
return $ui_member;
|
||||
} else if (is_array($structure->{$name}) && (is_string($args[0]) || is_int($args[0]))) {
|
||||
$key = $args[0];
|
||||
if (!is_string($key) && !is_int($key)) {
|
||||
self::err("SmartUI property key: $key must be string or int.");
|
||||
return null;
|
||||
}
|
||||
return $structure->{$name}[$key];
|
||||
} else {
|
||||
$value = $args[0];
|
||||
$structure->{$name} = $value;
|
||||
return $ui_member;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self::err('Undefined structure property: '.$name);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function start_track() {
|
||||
$this->_track_start_time = microtime(true);
|
||||
}
|
||||
|
||||
public function __call($name, $args) {
|
||||
$calls = explode('_', $name);
|
||||
if (!in_array($calls[0], self::$_ui_calls)) {
|
||||
self::err("Undefined call: $calls[0]");
|
||||
return null;
|
||||
}
|
||||
|
||||
$ui_class = strtolower($calls[1]);
|
||||
|
||||
if (isset(self::$_uis[$ui_class]) && $calls[0] == 'create') {
|
||||
$reflection = new \ReflectionClass(self::$_uis[$ui_class]);
|
||||
$new_ui = $args ? $reflection->newInstanceArgs($args) : $reflection->newInstance();
|
||||
|
||||
$this->start_track();
|
||||
return $new_ui;
|
||||
} else if ($calls[0] == 'print' && in_array($calls[1], self::$_alerts)) {
|
||||
$alert_args = array($args[0], $calls[1]);
|
||||
for ($i = 1; $i < count($args); $i++) {
|
||||
$alert_args[] = $args[$i];
|
||||
}
|
||||
return call_user_func_array(array($this, 'print_alert'), $alert_args);
|
||||
}
|
||||
|
||||
self::err("\"$ui_class\" is not a registered member of SmartUI: Class not found");
|
||||
}
|
||||
|
||||
public function run_time($print = true) {
|
||||
$time_end = microtime(true);
|
||||
$execution_time = number_format($time_end - $this->_track_start_time, 4);
|
||||
if ($print) echo $execution_time.'s';
|
||||
else return $execution_time.'s';
|
||||
}
|
||||
|
||||
public static function err($message = "SmartUI Error notice:") {
|
||||
if (self::$debug) {
|
||||
$trace = debug_backtrace();
|
||||
trigger_error($message.' in '.$trace[0]['file'].' on line '.$trace[0]['line'], E_USER_NOTICE);
|
||||
}
|
||||
}
|
||||
|
||||
public static function get_progress($value, $type = '', $options = array()) {
|
||||
$real_value = str_replace('%', '', $value);
|
||||
$percent_value = $real_value.'%';
|
||||
|
||||
$options_map = array(
|
||||
'transitional' => false,
|
||||
'class' => array(),
|
||||
'attr' => array(),
|
||||
'background' => '',
|
||||
'container' => 'div'
|
||||
);
|
||||
|
||||
$new_options_map = Util::set_array_prop_def($options_map, $options, 'class');
|
||||
|
||||
$classes = array();
|
||||
$classes[] = 'progress-bar';
|
||||
if ($type) $classes[] = 'progress-bar-'.$type;
|
||||
|
||||
// add additional user classes
|
||||
if (is_array($new_options_map['class'])) {
|
||||
array_merge($classes, $new_options_map['class']);
|
||||
} else {
|
||||
$classes[] = $new_options_map['class'];
|
||||
}
|
||||
|
||||
if ($new_options_map['background']) $classes[] = 'bg-color-'.$new_options_map['background'];
|
||||
|
||||
$attrs = array();
|
||||
$attrs_html = array();
|
||||
|
||||
if ($new_options_map['transitional'])
|
||||
$attrs['aria-valuetransitiongoal'] = $real_value;
|
||||
else
|
||||
$attrs['style'] = 'width: '.$percent_value;
|
||||
|
||||
|
||||
// add additional user attributes
|
||||
if (is_array($new_options_map['attr'])) {
|
||||
array_merge($attrs, $new_options_map['attr']);
|
||||
} else {
|
||||
$attrs_html[] = $new_options_map['attr'];
|
||||
}
|
||||
|
||||
foreach ($attrs as $attr => $attr_value) {
|
||||
$attrs_html[] = $attr.'="'.$attr_value.'"';
|
||||
}
|
||||
|
||||
return'<'.$new_options_map['container'].' class="'.implode(' ', $classes).'" '.implode(' ', $attrs_html).'></'.$new_options_map['container'].'>';
|
||||
}
|
||||
|
||||
public static function print_stack_progress($progress_bars, $base_options = array(), $return = false) {
|
||||
$options_map = array(
|
||||
'tooltip' => array(),
|
||||
'position' => 'left', // left, right, bottom (for vertical)
|
||||
'wide' => false,
|
||||
'size' => 'md', // sm, xs, md, xl, micro
|
||||
'striped' => false, // true or 'active'
|
||||
'vertical' => false
|
||||
);
|
||||
|
||||
$new_options_map = Util::set_array_prop_def($options_map, $base_options, 'class');
|
||||
|
||||
$container_classes = array();
|
||||
$container_classes[] = "progress";
|
||||
if ($new_options_map['vertical']) $container_classes[] = 'vertical';
|
||||
if ($new_options_map['position']) $container_classes[] = $new_options_map['position'];
|
||||
if ($new_options_map['wide']) $container_classes[] = 'wide-bar';
|
||||
if ($new_options_map['striped']) {
|
||||
$container_classes[] = 'progress-striped';
|
||||
if ($new_options_map['striped'] === 'active')
|
||||
$container_classes[] = 'active';
|
||||
}
|
||||
|
||||
$container_classes[] = 'progress-'.$new_options_map['size'];
|
||||
|
||||
$container_attrs = array();
|
||||
$container_attrs_html = array();
|
||||
|
||||
if ($new_options_map['tooltip']) {
|
||||
$tooltip_prop = array(
|
||||
'placement' => 'top',
|
||||
'title' => ''
|
||||
);
|
||||
$tooltip = $new_options_map['tooltip'];
|
||||
$new_tooltip_prop = Util::set_array_prop_def($tooltip_prop, $tooltip, 'title');
|
||||
$container_attrs['rel'] = 'tooltip';
|
||||
$container_attrs['data-original-title'] = $new_tooltip_prop['title'];
|
||||
$container_attrs['data-placement'] = $new_tooltip_prop['placement'];
|
||||
}
|
||||
|
||||
foreach ($container_attrs as $container_attr => $attr_value) {
|
||||
$container_attrs_html[] = $container_attr.'="'.$attr_value.'"';
|
||||
}
|
||||
|
||||
$result = '<div class="'.implode(' ', $container_classes).'" '.implode(' ', $container_attrs_html).'>';
|
||||
$result .= implode('', $progress_bars);
|
||||
$result .= '</div>';
|
||||
|
||||
if ($return) return $result;
|
||||
else echo $result;
|
||||
}
|
||||
|
||||
public static function print_progress($value, $type = '', $options = array(), $return = false) {
|
||||
$real_value = str_replace('%', '', $value);
|
||||
$percent_value = $real_value.'%';
|
||||
|
||||
$options_map = array(
|
||||
'transitional' => false,
|
||||
'class' => array(),
|
||||
'attr' => array(),
|
||||
'background' => '',
|
||||
'tooltip' => array(),
|
||||
'position' => 'left', // left, right, bottom (for vertical)
|
||||
'wide' => false,
|
||||
'size' => 'md', // sm, xs, md, xl, micro
|
||||
'striped' => false, // true or 'active'
|
||||
'vertical' => false,
|
||||
'container' => 'div'
|
||||
);
|
||||
|
||||
$new_options_map = Util::set_array_prop_def($options_map, $options, 'class');
|
||||
|
||||
$container_classes = array();
|
||||
$container_classes[] = "progress";
|
||||
if ($new_options_map['vertical']) $container_classes[] = 'vertical';
|
||||
if ($new_options_map['position']) $container_classes[] = $new_options_map['position'];
|
||||
if ($new_options_map['wide']) $container_classes[] = 'wide-bar';
|
||||
if ($new_options_map['striped']) {
|
||||
$container_classes[] = 'progress-striped';
|
||||
if ($new_options_map['striped'] === 'active')
|
||||
$container_classes[] = 'active';
|
||||
}
|
||||
|
||||
$container_classes[] = 'progress-'.$new_options_map['size'];
|
||||
|
||||
$container_attrs = array();
|
||||
$container_attrs_html = array();
|
||||
|
||||
if ($new_options_map['tooltip']) {
|
||||
$tooltip_prop = array(
|
||||
'placement' => 'top',
|
||||
'title' => $percent_value
|
||||
);
|
||||
$tooltip = $new_options_map['tooltip'];
|
||||
$new_tooltip_prop = Util::set_array_prop_def($tooltip_prop, $tooltip, 'title');
|
||||
$container_attrs['rel'] = 'tooltip';
|
||||
$container_attrs['data-original-title'] = $new_tooltip_prop['title'];
|
||||
$container_attrs['data-placement'] = $new_tooltip_prop['placement'];
|
||||
}
|
||||
|
||||
foreach ($container_attrs as $container_attr => $attr_value) {
|
||||
$container_attrs_html[] = $container_attr.'="'.$attr_value.'"';
|
||||
}
|
||||
|
||||
$classes = array();
|
||||
$classes[] = implode(' ', $container_classes);
|
||||
$classes[] = implode(' ', $new_options_map['class'] ? $new_options_map['class'] : array());
|
||||
|
||||
$container_attrs_html[] = implode(' ', $new_options_map['attr']);
|
||||
|
||||
$result = '<'.$new_options_map['container'].' class="'.implode(' ', $classes).'" '.implode(' ', $container_attrs_html).'>';
|
||||
$result .= self::get_progress($value, $type, $options);
|
||||
$result .= '</'.$new_options_map['container'].'>';
|
||||
|
||||
if ($return) return $result;
|
||||
else echo $result;
|
||||
}
|
||||
|
||||
public static function print_alert($message, $type = 'info', $options = array(), $return = false) {
|
||||
$options_map = array(
|
||||
'closebutton' => true,
|
||||
'block' => false,
|
||||
'container' => 'div',
|
||||
'class' => array(),
|
||||
'fade_in' => true,
|
||||
'icon' => $type,
|
||||
'js_escape' => false,
|
||||
'heading' => false
|
||||
);
|
||||
|
||||
$icon_map = array(
|
||||
'info' => self::$icon_source.'-info',
|
||||
'warning' => self::$icon_source.'-alert '.self::$icon_source.'-warning',
|
||||
'danger' => self::$icon_source.'-times '.self::$icon_source.'-x',
|
||||
'success' => ''.self::$icon_source.'-check'
|
||||
);
|
||||
$new_options_map = Util::set_array_prop_def($options_map, $options, 'class');
|
||||
$closebutton_html = $new_options_map['closebutton'] ?
|
||||
'<button class="close" data-dismiss="alert">
|
||||
×
|
||||
</button>' : '';
|
||||
|
||||
$classes = array();
|
||||
$classes[] = 'alert';
|
||||
$classes[] = 'alert-'.$type;
|
||||
if ($new_options_map['fade_in']) $classes[] = 'fade in';
|
||||
if ($new_options_map['block']) $classes[] = 'alert-block';
|
||||
|
||||
if ($new_options_map['icon']) {
|
||||
$icon = (isset($icon_map[$new_options_map['icon']]) ? $icon_map[$new_options_map['icon']] : self::$icon_source.'-'.$new_options_map['icon']);
|
||||
$icon_html = '<i class="'.self::$icon_source.' '.$icon.'"></i>';
|
||||
} else $icon_html = '';
|
||||
|
||||
$heading = '';
|
||||
if ($new_options_map['heading']) {
|
||||
$heading = '<h4 class="alert-heading">'.$icon_html.' '.$new_options_map['heading'].'</h4>';
|
||||
$icon_html = '';
|
||||
}
|
||||
|
||||
$result = '<div class="'.implode(' ', $classes).'">
|
||||
'.$closebutton_html.'
|
||||
'.$heading.'
|
||||
'.$icon_html.'
|
||||
'.$message.'
|
||||
</div>';
|
||||
|
||||
if ($new_options_map['js_escape']) $result = preg_replace("/\s+/", " ", $result);
|
||||
|
||||
if ($return) return $result;
|
||||
else echo $result;
|
||||
}
|
||||
|
||||
public static function print_list($items, $options = array(), $return = false) {
|
||||
|
||||
$items_html = '';
|
||||
$main_attrs = array();
|
||||
|
||||
$default_options = array(
|
||||
'type' => 'ul',
|
||||
'attr' => array(),
|
||||
'class' => array(),
|
||||
'id' => ''
|
||||
);
|
||||
|
||||
$new_options = Util::set_array_prop_def($default_options, $options, 'class');
|
||||
|
||||
foreach ($items as $item) {
|
||||
$item_html = '';
|
||||
$item_prop = array(
|
||||
'content' => '',
|
||||
'subitems' => array(),
|
||||
'subitem_options' => array(),
|
||||
'class' => '',
|
||||
'attr' => array()
|
||||
);
|
||||
|
||||
$new_item_prop = Util::get_clean_structure($item_prop, $item, array($item), 'content');
|
||||
|
||||
$content = $new_item_prop['content'];
|
||||
|
||||
if ($new_item_prop['subitems']) {
|
||||
$content .= self::print_list($new_item_prop['subitems'], $new_item_prop['subitem_options'], true);
|
||||
}
|
||||
|
||||
$attrs = array();
|
||||
if ($new_item_prop['class']) $attrs[] = 'class="'.(is_array($new_item_prop['class']) ? implode(' ', $new_item_prop['class']) : $new_item_prop['class']).'"';
|
||||
|
||||
if ($new_item_prop['attr']) {
|
||||
foreach ($new_item_prop['attr'] as $key => $value) {
|
||||
$attrs[] = $key.'="'.$value.'"';
|
||||
}
|
||||
}
|
||||
|
||||
$items_html .= '
|
||||
<li'.($attrs ? ' '.implode(' ', $attrs) : '').'>
|
||||
'.$content.'
|
||||
</li>
|
||||
';
|
||||
}
|
||||
|
||||
if ($new_options['class']) $main_attrs[] = 'class="'.(is_array($new_options['class']) ? implode(' ', $new_options['class']) : $new_options['class']).'"';
|
||||
if ($new_options['attr']) {
|
||||
foreach ($new_options['attr'] as $key => $value) {
|
||||
$main_attrs[] = $key.'="'.$value.'"';
|
||||
}
|
||||
}
|
||||
|
||||
if ($new_options['id']) $main_attrs[] = 'id="'.$new_options['id'].'"';
|
||||
|
||||
$result = '
|
||||
<'.$new_options['type'].($main_attrs ? ' '.implode(' ', $main_attrs) : '').'>
|
||||
'.$items_html.'
|
||||
</'.$new_options['type'].'>
|
||||
';
|
||||
|
||||
if ($return) return $result;
|
||||
else echo $result;
|
||||
}
|
||||
|
||||
public static function print_dropdown($items, $options = array(), $return = false) {
|
||||
|
||||
$items_html = '';
|
||||
|
||||
$main_attrs = array();
|
||||
|
||||
$default_options = array(
|
||||
'type' => 'ul',
|
||||
'attr' => array(),
|
||||
'class' => '',
|
||||
'id' => '',
|
||||
'multilevel' => false
|
||||
);
|
||||
|
||||
$new_options = Util::set_array_prop_def($default_options, $options, 'class');
|
||||
|
||||
foreach ($items as $item) {
|
||||
$item_html = '';
|
||||
$item_prop = array(
|
||||
'content' => '',
|
||||
'submenu' => array(),
|
||||
'class' => array(),
|
||||
'attr' => array()
|
||||
);
|
||||
|
||||
$new_item_prop = Util::get_property_value($item, array(
|
||||
'if_array' => function($item) use ($item_prop) {
|
||||
return Util::set_array_prop_def($item_prop, $item, 'content');
|
||||
},
|
||||
'if_closure' => function($item) use ($item_prop) {
|
||||
return Util::set_closure_prop_def($item_prop, $item);
|
||||
},
|
||||
'if_other' => function($item) use ($item_prop) {
|
||||
$item_prop['content'] = $item;
|
||||
return $item_prop;
|
||||
}
|
||||
));
|
||||
|
||||
$classes = array();
|
||||
if ($new_item_prop['class'])
|
||||
$classes[] = is_array($new_item_prop['class']) ? implode(' ', $new_item_prop['class']) : $new_item_prop['class'];
|
||||
|
||||
$attrs = array();
|
||||
|
||||
if ($new_item_prop['attr']) {
|
||||
foreach ($new_item_prop['attr'] as $key => $value) {
|
||||
$attrs[] = $key.'="'.$value.'"';
|
||||
}
|
||||
}
|
||||
|
||||
$content = $new_item_prop['content'];
|
||||
|
||||
if ($new_item_prop['submenu']) {
|
||||
$content .= self::print_dropdown($new_item_prop['submenu'], null, true);
|
||||
$classes[] = 'dropdown-submenu';
|
||||
} else if ($content === '-') {
|
||||
$classes[] = 'divider';
|
||||
} else if (preg_match("/##(.*)?##/", $content, $header_matches)) {
|
||||
$classes[] = 'dropdown-header';
|
||||
$content = trim($header_matches[1]);
|
||||
}
|
||||
|
||||
$attrs[] = $classes ? ' class="'.trim(implode(' ', $classes)).'"' : '';
|
||||
|
||||
$item_html = '<li'.($attrs ? ' '.implode(' ', $attrs) : '').'>'.$content.'</li>';
|
||||
$items_html .= $item_html;
|
||||
}
|
||||
|
||||
$classes = array('dropdown-menu');
|
||||
if ($new_options['multilevel']) $classes[] = 'multi-level';
|
||||
$main_attrs[] = 'role="menu"';
|
||||
|
||||
if ($new_options['class']) $classes[] = $new_options['class'];
|
||||
if ($new_options['attr']) {
|
||||
foreach ($new_options['attr'] as $key => $value) {
|
||||
$main_attrs[] = $key.'="'.$value.'"';
|
||||
}
|
||||
}
|
||||
|
||||
if ($new_options['id']) $main_attrs[] = 'id="'.$new_options['id'].'"';
|
||||
|
||||
$main_attrs[] = 'class="'.implode(' ', $classes).'"';
|
||||
|
||||
$result = '<ul '.implode(' ', $main_attrs).'>';
|
||||
$result .= $items_html;
|
||||
$result .= '</ul>';
|
||||
|
||||
if ($return) return $result;
|
||||
else echo $result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
148
lib/smartui/Util.php
Normal file
148
lib/smartui/Util.php
Normal file
@ -0,0 +1,148 @@
|
||||
<?php
|
||||
|
||||
namespace SmartUI;
|
||||
|
||||
class Util {
|
||||
|
||||
public static function is_assoc($array) {
|
||||
foreach (array_keys($array) as $k => $v) {
|
||||
if ($k !== $v)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function clean_html_string($str_value, $nl2br = true) {
|
||||
if (is_null($str_value)) $str_value = "";
|
||||
$new_str = is_string($str_value) ? htmlentities(html_entity_decode($str_value, ENT_QUOTES)) : $str_value;
|
||||
$new_str = utf8_encode($new_str);
|
||||
return $nl2br ? nl2br($new_str) : $new_str;
|
||||
}
|
||||
|
||||
public static function is_closure($obj) {
|
||||
return (is_object($obj) && ($obj instanceof \Closure));
|
||||
}
|
||||
|
||||
public static function array_to_object($array, $recursive = false) {
|
||||
if (!is_object($array) && !is_array($array))
|
||||
return $array;
|
||||
|
||||
if (!$recursive) return (object)$array;
|
||||
|
||||
if (is_array($array))
|
||||
return (object)array_map(array(__CLASS__, 'array_to_object'), $array);
|
||||
else return $array;
|
||||
}
|
||||
|
||||
public static function object_to_array($object) {
|
||||
if (!is_object($object) && !is_array($object))
|
||||
return $object;
|
||||
|
||||
if (is_object($object))
|
||||
$object = get_object_vars($object);
|
||||
|
||||
return array_map(array(__CLASS__, 'object_to_array'), $object);
|
||||
}
|
||||
|
||||
public static function create_id($md5 = false) {
|
||||
$uid = uniqid((double)microtime() * 10000, true);
|
||||
$result = str_replace(".", "", $uid);
|
||||
$result = $md5 ? md5($result) : $result;
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function get_property_value($prop, $prop_methods) {
|
||||
if (self::is_closure($prop)) {
|
||||
return isset($prop_methods['if_closure']) ? $prop_methods['if_closure']($prop) : $prop($prop);
|
||||
} else if (is_array($prop) || is_object($prop)) {
|
||||
if (is_object($prop))
|
||||
$prop = self::object_to_array($prop);
|
||||
return isset($prop_methods['if_array']) ? $prop_methods['if_array']($prop) : $prop;
|
||||
} else {
|
||||
return isset($prop_methods['if_other']) ? $prop_methods['if_other']($prop) : $prop;
|
||||
}
|
||||
}
|
||||
|
||||
public static function get_clean_structure($default_prop, $value, $closure_defaults = array(), $default_key = '') {
|
||||
$structure = self::get_property_value($value, array(
|
||||
'if_array' => function ($value) use ($default_prop, $default_key) {
|
||||
return self::set_array_prop_def($default_prop, $value, $default_key);
|
||||
},
|
||||
'if_closure' => function($value) use ($closure_defaults, $default_prop, $default_key) {
|
||||
return self::set_closure_prop_def($default_prop, $value, $closure_defaults, $default_key);
|
||||
},
|
||||
'if_other' => function($value) use ($default_prop, $default_key) {
|
||||
$default_prop[$default_key] = $value;
|
||||
return $default_prop;
|
||||
}
|
||||
));
|
||||
|
||||
return $structure;
|
||||
}
|
||||
|
||||
public static function set_closure_prop_def($default_structure, $callback_value, $callback_defaults = array(), $set_to_key_if_fail = "") {
|
||||
if ($set_to_key_if_fail != "") {
|
||||
if (!self::is_closure($callback_value)) {
|
||||
if (isset($default_structure[$set_to_key_if_fail]))
|
||||
$default_structure[$set_to_key_if_fail] = $callback_value;
|
||||
return $default_structure;
|
||||
}
|
||||
}
|
||||
|
||||
$callback_return = self::run_callback($callback_value, $callback_defaults);
|
||||
|
||||
if (is_array($callback_return)) {
|
||||
$default_structure = self::set_array_prop_def($default_structure, $callback_return);
|
||||
} else if ($set_to_key_if_fail != "" && isset($default_structure[$set_to_key_if_fail])) {
|
||||
$default_structure[$set_to_key_if_fail] = $callback_return;
|
||||
}
|
||||
return $default_structure;
|
||||
}
|
||||
|
||||
public static function set_array_prop_def($default_structure, $array_value, $set_to_key_if_fail = "") {
|
||||
if ($set_to_key_if_fail != "") {
|
||||
if (!is_array($array_value)) {
|
||||
if (isset($default_structure[$set_to_key_if_fail]))
|
||||
$default_structure[$set_to_key_if_fail] = $array_value;
|
||||
return $default_structure;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($array_value as $key => $value) {
|
||||
$default_structure[$key] = $value;
|
||||
}
|
||||
return $default_structure;
|
||||
}
|
||||
|
||||
public static function run_callback($callback, $default_args) {
|
||||
$reflection = new \ReflectionFunction($callback);
|
||||
$params = $reflection->getParameters();
|
||||
if (!$params || !$default_args) return call_user_func($callback);
|
||||
|
||||
$ref_args = array_keys($params);
|
||||
foreach ($ref_args as $param_index) {
|
||||
if (isset($default_args[$param_index]))
|
||||
$ref_args[$param_index] = $default_args[$param_index];
|
||||
else
|
||||
$ref_args[$param_index] = null;
|
||||
}
|
||||
|
||||
return call_user_func_array($callback, $ref_args);
|
||||
}
|
||||
|
||||
public static function replace_col_codes($str, $row, $url_encode=false) {
|
||||
preg_match_all("/\{([^&={{}}]+)\}/", $str, $matched_cols);
|
||||
$col_replace = array();
|
||||
$col_search = array();
|
||||
foreach($matched_cols[1] as $matched_col) {
|
||||
if (is_array($row)) $row = self::array_to_object($row);
|
||||
if (isset($row->{$matched_col})) {
|
||||
$col_replace[] = $url_encode ? urlencode($row->{$matched_col}) : $row->{$matched_col};
|
||||
$col_search[] = "/{{".$matched_col."}}/";
|
||||
}
|
||||
}
|
||||
return preg_replace($col_search, $col_replace, $str);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user