diff --git a/.github/issue_template.md b/.github/issue_template.md
new file mode 100644
index 00000000..62ecd03f
--- /dev/null
+++ b/.github/issue_template.md
@@ -0,0 +1,9 @@
+### Describe your problem
+
+### Expected behavior
+
+### Actual behavior
+
+### Steps to reproduce the problem
+
+### Bludit version
diff --git a/.gitignore b/.gitignore
index aceafd52..3a373671 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,10 +1,11 @@
.DS_Store
+dbgenerator.php
bl-content/*
bl-plugins/timemachine
bl-plugins/timemachine-x
-bl-plugins/remote-content
-bl-plugins/simple-stats
bl-plugins/discovery
+bl-plugins/updater
bl-kernel/bludit.pro.php
bl-themes/docs
bl-themes/docsx
+bl-themes/mediumish
\ No newline at end of file
diff --git a/.htaccess b/.htaccess
index cefe7dbe..3ef5e449 100644
--- a/.htaccess
+++ b/.htaccess
@@ -6,13 +6,13 @@ AddDefaultCharset UTF-8
RewriteEngine on
# Base directory
-#RewriteBase /
+# RewriteBase /
-# Deny direct access to .txt files
-RewriteRule ^bl-content/(.*)\.txt$ - [R=404,L]
+# Deny direct access to the next directories
+RewriteRule ^bl-content/(databases|workspaces|pages|tmp)/.*$ - [R=404,L]
# All URL process by index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*) index.php [PT,L]
-
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 1dc432d2..04635711 100644
--- a/README.md
+++ b/README.md
@@ -59,11 +59,14 @@ Become a **Backer** and support Bludit with a monthly contribution to help us co
Sponsors
--------
Become a **Sponsor** and support Bludit with a monthly contribution to help us continue development.
-- [Become a Sponsor](https://www.patreon.com/bePatron?c=921115&rid=2458860)
+
+[![Become a Sponsor](https://img.shields.io/badge/Become%20a%20Sponsor--green.svg)](https://www.patreon.com/bePatron?c=921115&rid=2458860)
- Clickwork
- KreativMind
-- Garriet Selent
+- Gerriet Selent
+- Jan Rippl
+- Wesleigh Walker
License
-------
diff --git a/bl-kernel/abstract/dbjson.class.php b/bl-kernel/abstract/dbjson.class.php
index 55a269a5..c7e54670 100644
--- a/bl-kernel/abstract/dbjson.class.php
+++ b/bl-kernel/abstract/dbjson.class.php
@@ -1,14 +1,14 @@
file = $file;
@@ -16,26 +16,25 @@ class dbJSON
$this->dbBackup = array();
$this->firstLine = $firstLine;
- if(file_exists($file))
- {
- // Read JSON file.
+ if (file_exists($file)) {
+ // Read JSON file
$lines = file($file);
- // Remove the first line, the first line is for security reasons.
- if($firstLine) {
+ // Remove the first line, the first line is for security reasons
+ if ($firstLine) {
unset($lines[0]);
}
- // Regenerate the JSON file.
+ // Regenerate the JSON file
$implode = implode($lines);
- // Unserialize, JSON to Array.
+ // Unserialize, JSON to Array
$array = $this->unserialize($implode);
- if(empty($array)) {
- //Log::set(__METHOD__.LOG_SEP.'Invalid JSON file: '.$file.', cannot be decoded. Check the file content.');
- }
- else {
+ if (empty($array)) {
+ $this->db = array();
+ $this->dbBackup = array();
+ } else {
$this->db = $array;
$this->dbBackup = $array;
}
@@ -45,32 +44,29 @@ class dbJSON
public function restoreDB()
{
$this->db = $this->dbBackup;
-
return true;
}
- // Returns the amount of database items.
+ // Returns the number of rows in the database
public function count()
{
return count($this->db);
}
- // Returns the value from the field.
+ // Returns the value from the field
public function getField($field)
{
- if(isset($this->db[$field])) {
+ if (isset($this->db[$field])) {
return $this->db[$field];
}
-
- return $this->dbFields[$field]['value'];
+ return $this->dbFields[$field];
}
- // Save the JSON file.
+ // Save the JSON file
public function save()
{
$data = '';
-
- if($this->firstLine) {
+ if ($this->firstLine) {
$data = "".PHP_EOL;
}
@@ -81,33 +77,37 @@ class dbJSON
$this->dbBackup = $this->db;
// LOCK_EX flag to prevent anyone else writing to the file at the same time.
- if( file_put_contents($this->file, $data, LOCK_EX) ) {
+ if (file_put_contents($this->file, $data, LOCK_EX)) {
return true;
- }
- else {
- Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to save the database file.');
+ } else {
+ Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to save the database file.', LOG_TYPE_ERROR);
return false;
}
}
- // Returns a JSON encoded string on success or FALSE on failure.
+ // Returns a JSON encoded string on success or FALSE on failure
private function serialize($data)
{
- return json_encode($data, JSON_PRETTY_PRINT);
+ if (DEBUG_MODE) {
+ return json_encode($data, JSON_PRETTY_PRINT);
+ }
+ return json_encode($data);
}
- // Returns the value encoded in json in appropriate PHP type.
+ // Returns the value encoded in json in appropriate PHP type
private function unserialize($data)
{
- // NULL is returned if the json cannot be decoded.
+ // NULL is returned if the json cannot be decoded
$decode = json_decode($data, true);
-
- // If NULL returns false.
- if(empty($decode)) {
+ if (empty($decode)) {
return false;
}
-
return $decode;
}
+ public function getDB()
+ {
+ return $this->db;
+ }
+
}
\ No newline at end of file
diff --git a/bl-kernel/abstract/dblist.class.php b/bl-kernel/abstract/dblist.class.php
index 26e9f3d5..1fabc6b6 100644
--- a/bl-kernel/abstract/dblist.class.php
+++ b/bl-kernel/abstract/dblist.class.php
@@ -6,10 +6,14 @@ Database structure
{
"videos": {
"name": "Videos",
+ "template: "",
+ "description: "",
"list": [ "my-page", "second-page" ]
},
"pets": {
"name": "Pets",
+ "template: "",
+ "description: "",
"list": [ "cats-and-dogs" ]
}
}
@@ -24,77 +28,73 @@ class dbList extends dbJSON
parent::__construct($file);
}
- // Returns an array with a list of key of pages, FALSE if out of range
- public function getList($key, $pageNumber, $amountOfItems)
+ public function keys()
{
- if (empty($key)) {
- return false;
- }
+ return array_keys($this->db);
+ }
+ // Returns the list of keys filter by pageNumber
+ public function getList($key, $pageNumber, $numberOfItems)
+ {
if (!isset($this->db[$key])) {
Log::set(__METHOD__.LOG_SEP.'Error key does not exist '.$key);
return false;
}
+ // List of keys
$list = $this->db[$key]['list'];
- if ($amountOfItems==-1) {
+ // Returns all the items from the list
+ if ($numberOfItems==-1) {
// Invert keys to values, is necesary returns as key the key pages
- //$list = array_flip($list);
+ $list = array_flip($list);
return $list;
}
// The first page number is 1, so the real is 0
$realPageNumber = $pageNumber - 1;
-
- $total = count($list);
- $init = (int) $amountOfItems * $realPageNumber;
- $end = (int) min( ($init + $amountOfItems - 1), $total );
- $outrange = $init<0 ? true : $init>$end;
-
- if($outrange) {
- Log::set(__METHOD__.LOG_SEP.'Error out of range');
- return false;
+ $chunks = array_chunk($list, $numberOfItems);
+ if (isset($chunks[$realPageNumber])) {
+ return $chunks[$realPageNumber];
}
- //$list = array_flip($list);
- return array_slice($list, $init, $amountOfItems, true);
+ // Out of index,returns FALSE
+ return false;
}
public function generateKey($name)
{
+ global $L;
+
$key = Text::cleanUrl($name);
- if (empty($key)) {
- return false;
+ if (Text::isEmpty($key)) {
+ $key = $L->g('empty');
+ }
+ while (isset($this->db[$key])) {
+ $key++;
}
return $key;
}
- public function add($name)
+ // Add a new item to the dblist
+ // $args => 'name', 'template', 'description', list'
+ public function add($args)
{
- $key = $this->generateKey($name);
- if ($key===false) {
- Log::set(__METHOD__.LOG_SEP.'Error when try to generate the key');
- return false;
- }
+ $key = $this->generateKey($args['name']);
- if (isset($this->db[$key])) {
- Log::set(__METHOD__.LOG_SEP.'Error key already exist: '.$key);
- return false;
- }
-
- $this->db[$key]['name'] = Sanitize::html($name);
- $this->db[$key]['list'] = array();
+ $this->db[$key]['name'] = $args['name'];
+ $this->db[$key]['template'] = isset($args['template'])?$args['template']:'';
+ $this->db[$key]['description'] = isset($args['description'])?$args['description']:'';
+ $this->db[$key]['list'] = isset($args['list'])?$args['list']:array();
$this->sortAlphanumeric();
$this->save();
-
return $key;
}
public function remove($key)
{
- if( !isset($this->db[$key]) ) {
+ if (!isset($this->db[$key])) {
Log::set(__METHOD__.LOG_SEP.'The key does not exist, key: '.$key);
return false;
}
@@ -103,21 +103,28 @@ class dbList extends dbJSON
return $this->save();
}
- public function edit($oldKey, $newName)
+ // Edit an item to the dblist
+ // $args => 'name', 'oldkey', 'newKey', 'template', 'description'
+ public function edit($args)
{
- $newKey = $this->generateKey($newName);
+ if ( isset($this->db[$args['newKey']]) && ($args['newKey']!==$args['oldKey']) ) {
+ Log::set(__METHOD__.LOG_SEP.'The new key already exists. Key: '.$args['newKey'], LOG_TYPE_WARN);
+ return false;
+ }
- $this->db[$newKey]['name'] = Sanitize::html($newName);
- $this->db[$newKey]['list'] = $this->db[$oldKey]['list'];
+ $this->db[$args['newKey']]['name'] = $args['name'];
+ $this->db[$args['newKey']]['template'] = isset($args['template'])?$args['template']:'';
+ $this->db[$args['newKey']]['description'] = isset($args['description'])?$args['description']:'';
+ $this->db[$args['newKey']]['list'] = $this->db[$args['oldKey']]['list'];
- // Remove the old key
- if( $oldKey != $newKey ) {
- unset( $this->db[$oldKey] );
+ // Remove the old category
+ if ($args['oldKey'] !== $args['newKey']) {
+ unset( $this->db[$args['oldKey']] );
}
$this->sortAlphanumeric();
$this->save();
- return $newKey;
+ return $args['newKey'];
}
// Sort the categories by "Natural order"
@@ -130,10 +137,9 @@ class dbList extends dbJSON
// Returns the name associated to the key, FALSE if the key doesn't exist
public function getName($key)
{
- if( isset($this->db[$key]) ) {
+ if (isset($this->db[$key])) {
return $this->db[$key]['name'];
}
-
return false;
}
@@ -144,17 +150,15 @@ class dbList extends dbJSON
foreach($this->db as $key=>$fields) {
$tmp[$key] = $fields['name'];
}
-
return $tmp;
}
- // Returns the amount of items for some key
+ // Returns the number of items in the list
public function countItems($key)
{
- if( isset($this->db[$key]) ) {
+ if (isset($this->db[$key])) {
return count($this->db[$key]['list']);
}
-
return 0;
}
@@ -163,14 +167,25 @@ class dbList extends dbJSON
return isset( $this->db[$key] );
}
+ public function existsName($name)
+ {
+ foreach ($this->db as $key=>$fields) {
+ if ($name==$fields['name']) {
+ return true;
+ }
+ }
+ return false;
+ }
+
// Returns an array with a portion of the database filtered by key
- // Returns array( 'name'=>'', 'list'=>array() )
+ // Returns array( 'key'=>'', 'name'=>'', 'template'=>'', 'description'=>'', list'=>array() )
public function getMap($key)
{
- if( isset($this->db[$key]) ) {
- return $this->db[$key];
+ if (isset($this->db[$key])) {
+ $tmp = $this->db[$key];
+ $tmp['key'] = $key;
+ return $tmp;
}
-
return false;
}
diff --git a/bl-kernel/abstract/plugin.class.php b/bl-kernel/abstract/plugin.class.php
index ce15c75e..62d82d79 100644
--- a/bl-kernel/abstract/plugin.class.php
+++ b/bl-kernel/abstract/plugin.class.php
@@ -59,29 +59,12 @@ class Plugin {
$this->metadata = json_decode($metadataString, true);
// If the plugin is installed then get the database
- if($this->installed()) {
+ if ($this->installed()) {
$Tmp = new dbJSON($this->filenameDb);
$this->db = $Tmp->db;
}
}
- // DEPRECATED
- // 2017-06-19
- public function setDb($args)
- {
- foreach($this->dbFields as $key=>$value) {
- if( isset($args[$key]) ) {
- $value = Sanitize::html( $args[$key] );
- if($value==='false') { $value = false; }
- elseif($value==='true') { $value = true; }
- settype($value, gettype($this->dbFields[$key]));
- $this->db[$key] = $value;
- }
- }
-
- $this->save();
- }
-
public function save()
{
$tmp = new dbJSON($this->filenameDb);
@@ -89,6 +72,21 @@ class Plugin {
return $tmp->save();
}
+ public function includeCSS($filename)
+ {
+ return ' '.PHP_EOL;
+ }
+
+ public function includeJS($filename)
+ {
+ return ''.PHP_EOL;
+ }
+
+ public function domainPath()
+ {
+ return DOMAIN_PLUGINS.$this->directoryName.'/';
+ }
+
public function htmlPath()
{
return HTML_PATH_PLUGINS.$this->directoryName.'/';
@@ -126,34 +124,19 @@ class Plugin {
// (boolean) $html, TRUE returns the value sanitized, FALSE unsanitized
public function getValue($field, $html=true)
{
- if( isset($this->db[$field]) ) {
- if($html) {
+ if (isset($this->db[$field])) {
+ if ($html) {
return $this->db[$field];
- }
- else {
+ } else {
return Sanitize::htmlDecode($this->db[$field]);
}
}
return false;
}
- // DEPRECATED
- // 2017-06-16
- public function getDbField($key, $html=true)
+ public function label()
{
- if(isset($this->db[$key])) {
-
- if($html) {
- // All fields from DBField are sanitized.
- return $this->db[$key];
- }
- else {
- // Decode HTML tags, this action unsanitized the variable.
- return Sanitize::htmlDecode($this->db[$key]);
- }
- }
-
- return '';
+ return $this->getMetadata('label');
}
public function name()
@@ -231,20 +214,36 @@ class Plugin {
return false;
}
- // Create plugin directory for databases and other files
+ // Create workspace
+ $workspace = $this->workspace();
+ mkdir($workspace, 0755, true);
+
+ // Create plugin directory for the database
mkdir(PATH_PLUGINS_DATABASES.$this->directoryName, 0755, true);
- // Create database
$this->dbFields['position'] = $position;
- $this->setDb($this->dbFields);
+ // Sanitize default values to store in the file
+ foreach ($this->dbFields as $key=>$value) {
+ $value = Sanitize::html($value);
+ settype($value, gettype($this->dbFields[$key]));
+ $this->db[$key] = $value;
+ }
- return true;
+ // Create the database
+ return $this->save();
}
public function uninstall()
{
+ // Delete database
$path = PATH_PLUGINS_DATABASES.$this->directoryName;
- return Filesystem::deleteRecursive($path);
+ Filesystem::deleteRecursive($path);
+
+ // Delete workspace
+ $workspace = $this->workspace();
+ Filesystem::deleteRecursive($workspace);
+
+ return true;
}
public function installed()
@@ -254,7 +253,7 @@ class Plugin {
public function workspace()
{
- return PATH_PLUGINS_DATABASES.$this->directoryName.DS;
+ return PATH_WORKSPACES.$this->directoryName.DS;
}
public function init()
@@ -293,7 +292,7 @@ class Plugin {
// Example: https://www.mybludit.com/api/foo/bar
public function webhook($URI=false, $returnsAfterURI=false, $fixed=true)
{
- global $Url;
+ global $url;
if (empty($URI)) {
return false;
@@ -301,7 +300,7 @@ class Plugin {
// Check URI start with the webhook
$startString = HTML_PATH_ROOT.$URI;
- $URI = $Url->uri();
+ $URI = $url->uri();
$length = mb_strlen($startString, CHARSET);
if (mb_substr($URI, 0, $length)!=$startString) {
return false;
diff --git a/bl-kernel/admin/controllers/about.php b/bl-kernel/admin/controllers/about.php
index 6b0c40e0..a27002e5 100644
--- a/bl-kernel/admin/controllers/about.php
+++ b/bl-kernel/admin/controllers/about.php
@@ -1,4 +1,4 @@
g('About');
\ No newline at end of file
+$layout['title'] = $L->g('About') . ' - ' . $layout['title'];
\ No newline at end of file
diff --git a/bl-kernel/admin/controllers/categories.php b/bl-kernel/admin/controllers/categories.php
index 0071384c..3a22161b 100644
--- a/bl-kernel/admin/controllers/categories.php
+++ b/bl-kernel/admin/controllers/categories.php
@@ -4,10 +4,7 @@
// Check role
// ============================================================================
-if ($Login->role()!=='admin') {
- Alert::set($Language->g('You do not have sufficient permissions'));
- Redirect::page('dashboard');
-}
+checkRole(array('admin'));
// ============================================================================
// Functions
@@ -26,4 +23,4 @@ if ($Login->role()!=='admin') {
// ============================================================================
// Title of the page
-$layout['title'] .= ' - '.$Language->g('Categories');
\ No newline at end of file
+$layout['title'] .= ' - '.$L->g('Categories');
\ No newline at end of file
diff --git a/bl-kernel/admin/controllers/configure-plugin.php b/bl-kernel/admin/controllers/configure-plugin.php
index 42c6d11b..9ce387c8 100644
--- a/bl-kernel/admin/controllers/configure-plugin.php
+++ b/bl-kernel/admin/controllers/configure-plugin.php
@@ -4,10 +4,7 @@
// Check role
// ============================================================================
-if ($Login->role()!=='admin') {
- Alert::set($Language->g('You do not have sufficient permissions'));
- Redirect::page('dashboard');
-}
+checkRole(array('admin'));
// ============================================================================
// Functions
@@ -20,15 +17,14 @@ $plugin = false;
$pluginClassName = $layout['parameters'];
// Check if the plugin exists
-if( isset($plugins['all'][$pluginClassName]) ) {
+if (isset($plugins['all'][$pluginClassName])) {
$plugin = $plugins['all'][$pluginClassName];
-}
-else {
+} else {
Redirect::page('plugins');
}
// Check if the plugin has the method form()
-if( !method_exists($plugin, 'form') ) {
+if (!method_exists($plugin, 'form')) {
Redirect::page('plugins');
}
@@ -36,23 +32,19 @@ if( !method_exists($plugin, 'form') ) {
// POST Method
// ============================================================================
-if( $_SERVER['REQUEST_METHOD'] == 'POST' )
-{
+if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// Add to syslog
- $Syslog->add(array(
+ $syslog->add(array(
'dictionaryKey'=>'plugin-configured',
'notes'=>$plugin->name()
));
// Call the method post of the plugin
- if( $plugin->post() ) {
- // Create an alert
- Alert::set( $Language->g('The changes have been saved') );
+ if ($plugin->post()) {
+ Alert::set( $L->g('The changes have been saved') );
Redirect::page('configure-plugin/'.$plugin->className());
- }
- else {
- // Create an alert
- Alert::set( $Language->g('Complete all fields') );
+ } else {
+ Alert::set( $L->g('Complete all fields') );
}
}
@@ -61,4 +53,4 @@ if( $_SERVER['REQUEST_METHOD'] == 'POST' )
// ============================================================================
// Title of the page
-$layout['title'] .= ' - '.$Language->g('Plugin').' - '.$plugin->name();
\ No newline at end of file
+$layout['title'] = $L->g('Plugin').' - '.$plugin->name().' - '.$layout['title'];
\ No newline at end of file
diff --git a/bl-kernel/admin/controllers/content.php b/bl-kernel/admin/controllers/content.php
index 425199bb..3ea7755f 100644
--- a/bl-kernel/admin/controllers/content.php
+++ b/bl-kernel/admin/controllers/content.php
@@ -4,6 +4,8 @@
// Check role
// ============================================================================
+checkRole(array('admin', 'editor'));
+
// ============================================================================
// Functions
// ============================================================================
@@ -22,18 +24,19 @@
// List of published pages
$onlyPublished = true;
-$amountOfItems = ITEMS_PER_PAGE_ADMIN;
-$pageNumber = $Url->pageNumber();
-$published = $dbPages->getList($pageNumber, $amountOfItems, $onlyPublished);
+$numberOfItems = ITEMS_PER_PAGE_ADMIN;
+$pageNumber = $url->pageNumber();
+$published = $pages->getList($pageNumber, $numberOfItems, $onlyPublished);
// Check if out of range the pageNumber
-if (empty($published) && $Url->pageNumber()>1) {
+if (empty($published) && $url->pageNumber()>1) {
Redirect::page('content');
}
-$drafts = $dbPages->getDraftDB(true);
-$scheduled = $dbPages->getScheduledDB(true);
-$static = $dbPages->getStaticDB(true);
+$drafts = $pages->getDraftDB(true);
+$scheduled = $pages->getScheduledDB(true);
+$static = $pages->getStaticDB(true);
+$sticky = $pages->getStickyDB(true);
// Title of the page
-$layout['title'] .= ' - '.$Language->g('Manage content');
\ No newline at end of file
+$layout['title'] .= ' - '.$L->g('Manage content');
\ No newline at end of file
diff --git a/bl-kernel/admin/controllers/dashboard.php b/bl-kernel/admin/controllers/dashboard.php
index 02b2edcc..b924561d 100644
--- a/bl-kernel/admin/controllers/dashboard.php
+++ b/bl-kernel/admin/controllers/dashboard.php
@@ -4,18 +4,26 @@
// Functions
// ============================================================================
function updateBludit() {
- global $Site;
+ global $site;
// Check if Bludit need to be update.
- if( ($Site->currentBuild() < BLUDIT_BUILD) || isset($_GET['update']) ) {
+ if( ($site->currentBuild() < BLUDIT_BUILD) || isset($_GET['update']) ) {
Log::set('UPDATE SYSTEM - Starting.');
- // From Bludit v2.0.x to v2.1.x
- if ($Site->currentBuild() < '20171102') {
- // Nothing to do
+ // Updates only for version less than Bludit v3.0 rc-3
+ if ($site->currentBuild()<'20180910') {
+ @mkdir(PATH_WORKSPACES, DIR_PERMISSIONS, true);
+ $plugins = array('simple-stats', 'pluginRSS', 'pluginSitemap', 'pluginTimeMachineX', 'pluginBackup');
+ foreach ($plugins as $plugin) {
+ if (pluginActivated($plugin)) {
+ Log::set('UPDATE SYSTEM - Re-enable plugin: '.$plugin);
+ deactivatePlugin($plugin);
+ activatePlugin($plugin);
+ }
+ }
}
// Set the current build number
- $Site->set(array('currentBuild'=>BLUDIT_BUILD));
+ $site->set(array('currentBuild'=>BLUDIT_BUILD));
Log::set('UPDATE SYSTEM - Finished.');
}
}
@@ -36,4 +44,4 @@ function updateBludit() {
updateBludit();
// Title of the page
-$layout['title'] .= ' - '.$Language->g('Dashboard');
\ No newline at end of file
+$layout['title'] .= ' - '.$L->g('Dashboard');
\ No newline at end of file
diff --git a/bl-kernel/admin/controllers/developers.php b/bl-kernel/admin/controllers/developers.php
index e91d5851..37b37c9c 100644
--- a/bl-kernel/admin/controllers/developers.php
+++ b/bl-kernel/admin/controllers/developers.php
@@ -4,10 +4,7 @@
// Check role
// ============================================================================
-if ($Login->role()!=='admin') {
- Alert::set($Language->g('You do not have sufficient permissions'));
- Redirect::page('dashboard');
-}
+checkRole(array('admin'));
// ============================================================================
// Functions
@@ -15,15 +12,8 @@ if ($Login->role()!=='admin') {
// This function is used on the VIEW to show the tables
function printTable($title, $array) {
- echo '
'.$title.' ';
- echo '
-
-
-
-
-
-
-
+ echo ''.$title.' ';
+ echo '
';
@@ -58,4 +48,4 @@ function printTable($title, $array) {
// Main after POST
// ============================================================================
-$layout['title'] .= ' - '.$Language->g('Developers');
\ No newline at end of file
+$layout['title'] .= ' - '.$L->g('Developers');
\ No newline at end of file
diff --git a/bl-kernel/admin/controllers/edit-category.php b/bl-kernel/admin/controllers/edit-category.php
index f93e541c..9df8f48c 100644
--- a/bl-kernel/admin/controllers/edit-category.php
+++ b/bl-kernel/admin/controllers/edit-category.php
@@ -4,10 +4,7 @@
// Check role
// ============================================================================
-if ($Login->role()!=='admin') {
- Alert::set($Language->g('You do not have sufficient permissions'));
- Redirect::page('dashboard');
-}
+checkRole(array('admin'));
// ============================================================================
// Functions
@@ -22,11 +19,10 @@ if ($Login->role()!=='admin') {
// ============================================================================
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
- if (isset($_POST['delete'])) {
- deleteCategory($_POST['categoryKey']);
- }
- elseif (isset($_POST['edit'])) {
- editCategory($_POST['categoryKey'], $_POST['category']);
+ if ($_POST['action']=='delete') {
+ deleteCategory($_POST);
+ } elseif ($_POST['action']=='edit') {
+ editCategory($_POST);
}
Redirect::page('categories');
@@ -37,12 +33,12 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// ============================================================================
$categoryKey = $layout['parameters'];
-if (!$dbCategories->exists($categoryKey)) {
+if (!$categories->exists($categoryKey)) {
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to get the category: '.$categoryKey);
Redirect::page('categories');
}
-$category = $dbCategories->getName($layout['parameters']);
+$categoryMap = $categories->getMap($categoryKey);
// Title of the page
-$layout['title'] .= ' - '.$Language->g('Edit Category').' - '.$category;
\ No newline at end of file
+$layout['title'] .= ' - '.$L->g('Edit Category').' [ '.$categoryMap['name'] . ' ] ';
\ No newline at end of file
diff --git a/bl-kernel/admin/controllers/edit-content.php b/bl-kernel/admin/controllers/edit-content.php
index 4294d973..eae42488 100644
--- a/bl-kernel/admin/controllers/edit-content.php
+++ b/bl-kernel/admin/controllers/edit-content.php
@@ -4,6 +4,27 @@
// Check role
// ============================================================================
+if (!checkRole(array('admin','editor'), false)) {
+ try {
+ $pageKey = isset($_POST['key']) ? $_POST['key'] : $layout['parameters'];
+ $page = new Page($pageKey);
+ } catch (Exception $e) {
+ Alert::set($L->g('You do not have sufficient permissions'));
+ Redirect::page('dashboard');
+ }
+
+ if ($page->username()!==$login->username()) {
+ // Add to syslog
+ $syslog->add(array(
+ 'dictionaryKey'=>'access-denied',
+ 'notes'=>$login->username()
+ ));
+
+ Alert::set($L->g('You do not have sufficient permissions'));
+ Redirect::page('dashboard');
+ }
+}
+
// ============================================================================
// Functions
// ============================================================================
@@ -17,16 +38,19 @@
// ============================================================================
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
- if( isset($_POST['delete-page']) ) {
- if( deletePage($_POST['key']) ) {
- Alert::set( $Language->g('The changes have been saved') );
- Redirect::page('content');
+ if ($_POST['type']==='delete') {
+ if (deletePage($_POST['key'])) {
+ Alert::set( $L->g('The changes have been saved') );
}
- }
- else {
+ } else {
+ // If the checkbox is not selected the form doesn't send the field
+ $_POST['noindex'] = isset($_POST['noindex'])?true:false;
+ $_POST['nofollow'] = isset($_POST['nofollow'])?true:false;
+ $_POST['noarchive'] = isset($_POST['noarchive'])?true:false;
+
$key = editPage($_POST);
- if( $key!==false ) {
- Alert::set( $Language->g('The changes have been saved') );
+ if ($key!==false) {
+ Alert::set( $L->g('The changes have been saved') );
Redirect::page('edit-content/'.$key);
}
}
@@ -37,12 +61,13 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// ============================================================================
// Main after POST
// ============================================================================
-$pageKey = $layout['parameters'];
-$page = buildPage($pageKey);
-if ($page===false) {
- Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to get the page: '.$pageKey);
+try {
+ $pageKey = $layout['parameters'];
+ $page = new Page($pageKey);
+} catch (Exception $e) {
+ Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to get the page: '.$pageKey, LOG_TYPE_ERROR);
Redirect::page('content');
}
// Title of the page
-$layout['title'] .= ' - '.$Language->g('Edit content').' - '.$page->title();
\ No newline at end of file
+$layout['title'] .= ' - '.$L->g('Edit content').' - '.$page->title();
\ No newline at end of file
diff --git a/bl-kernel/admin/controllers/edit-user.php b/bl-kernel/admin/controllers/edit-user.php
index fa312712..9e23f6b1 100644
--- a/bl-kernel/admin/controllers/edit-user.php
+++ b/bl-kernel/admin/controllers/edit-user.php
@@ -12,45 +12,45 @@
// POST Method
// ============================================================================
-if( $_SERVER['REQUEST_METHOD'] == 'POST' )
-{
+if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// Prevent non-administrators to change other users
- if($Login->role()!=='admin') {
- $_POST['username'] = $Login->username();
+ if ($login->role()!=='admin') {
+ $_POST['username'] = $login->username();
unset($_POST['role']);
}
- if(isset($_POST['delete-user-all'])) {
- deleteUser($_POST, $deleteContent=true);
- }
- elseif(isset($_POST['delete-user-associate'])) {
- deleteUser($_POST, $deleteContent=false);
- }
- elseif(isset($_POST['disable-user'])) {
- disableUser($_POST['username']);
- }
- else {
+ if (isset($_POST['deleteUserAndDeleteContent'])) {
+ $_POST['deleteContent'] = true;
+ deleteUser($_POST);
+ } elseif (isset($_POST['deleteUserAndKeepContent'])) {
+ $_POST['deleteContent'] = false;
+ deleteUser($_POST);
+ } elseif (isset($_POST['disableUser'])) {
+ disableUser(array('username'=>$_POST['username']));
+ } else {
editUser($_POST);
}
- Alert::set($Language->g('The changes have been saved'));
+ Alert::set($L->g('The changes have been saved'));
+ Redirect::page('users');
}
// ============================================================================
// Main after POST
// ============================================================================
+$username = $layout['parameters'];
+
// Prevent non-administrators to change other users
-if($Login->role()!=='admin') {
- $layout['parameters'] = $Login->username();
+if ($login->role()!=='admin') {
+ $username = $login->username();
}
-$User = $dbUsers->getUser($layout['parameters']);
-
-// If the user doesn't exist, redirect to the users list.
-if($User===false) {
+try {
+ $user = new User($username);
+} catch (Exception $e) {
Redirect::page('users');
}
// Title of the page
-$layout['title'] .= ' - '.$Language->g('Edit user');
\ No newline at end of file
+$layout['title'] = $L->g('Edit user').' - '.$layout['title'];
\ No newline at end of file
diff --git a/bl-kernel/admin/controllers/install-plugin.php b/bl-kernel/admin/controllers/install-plugin.php
index c8e1eef8..eb5a8832 100644
--- a/bl-kernel/admin/controllers/install-plugin.php
+++ b/bl-kernel/admin/controllers/install-plugin.php
@@ -4,10 +4,7 @@
// Check role
// ============================================================================
-if ($Login->role()!=='admin') {
- Alert::set($Language->g('You do not have sufficient permissions'));
- Redirect::page('dashboard');
-}
+checkRole(array('admin'));
// ============================================================================
// Functions
@@ -25,5 +22,18 @@ if ($Login->role()!=='admin') {
// Main after POST
// ============================================================================
$pluginClassName = $layout['parameters'];
-activatePlugin($pluginClassName);
+if (!activatePlugin($pluginClassName)) {
+ Log::set('Fail when try to activate the plugin.', LOG_TYPE_ERROR);
+}
+
+if (isset($plugins['all'][$pluginClassName])) {
+ $plugin = $plugins['all'][$pluginClassName];
+} else {
+ Redirect::page('plugins');
+}
+
+if (method_exists($plugin, 'form')) {
+ Redirect::page('configure-plugin/'.$pluginClassName);
+}
+
Redirect::page('plugins#'.$pluginClassName);
diff --git a/bl-kernel/admin/controllers/install-theme.php b/bl-kernel/admin/controllers/install-theme.php
index 1c80c08a..1a3dabfa 100644
--- a/bl-kernel/admin/controllers/install-theme.php
+++ b/bl-kernel/admin/controllers/install-theme.php
@@ -4,10 +4,7 @@
// Check role
// ============================================================================
-if ($Login->role()!=='admin') {
- Alert::set($Language->g('You do not have sufficient permissions'));
- Redirect::page('dashboard');
-}
+checkRole(array('admin'));
// ============================================================================
// Functions
@@ -26,18 +23,17 @@ if ($Login->role()!=='admin') {
// ============================================================================
$themeDirname = $layout['parameters'];
-if( Sanitize::pathFile(PATH_THEMES.$themeDirname) ) {
- // Set the theme
- $Site->set(array('theme'=>$themeDirname));
+if (Sanitize::pathFile(PATH_THEMES.$themeDirname)) {
+ $site->set(array('theme'=>$themeDirname));
// Add to syslog
- $Syslog->add(array(
+ $syslog->add(array(
'dictionaryKey'=>'new-theme-configured',
'notes'=>$themeDirname
));
// Create an alert
- Alert::set( $Language->g('The changes have been saved') );
+ Alert::set( $L->g('The changes have been saved') );
}
// Redirect
diff --git a/bl-kernel/admin/controllers/login-email.php b/bl-kernel/admin/controllers/login-email.php
deleted file mode 100644
index 685f7a60..00000000
--- a/bl-kernel/admin/controllers/login-email.php
+++ /dev/null
@@ -1,123 +0,0 @@
-isBlocked()) {
- Alert::set($Language->g('IP address has been blocked').' '.$Language->g('Try again in a few minutes'));
- return false;
- }
-
- // Remove illegal characters from email
- $email = Sanitize::email($args['email']);
-
- if(Valid::email($email))
- {
- // Get username associated to an email.
- $username = $dbUsers->getByEmail($email);
- if($username!=false)
- {
- // Generate the token and the token expiration date.
- $token = $dbUsers->setTokenEmail($username);
-
- // ---- EMAIL ----
- $link = $Site->url().'admin/login-email?tokenEmail='.$token.'&username='.$username;
- $subject = $Language->g('BLUDIT Login access code');
- $message = Text::replaceAssoc(
- array(
- '{{WEBSITE_NAME}}'=>$Site->title(),
- '{{LINK}}'=>''.$link.' '
- ),
- $Language->g('email-notification-login-access-code')
- );
-
- $sent = Email::send(array(
- 'from'=>$Site->emailFrom(),
- 'fromName'=>$Site->title(),
- 'to'=>$email,
- 'subject'=>$subject,
- 'message'=>$message
- ));
-
- if($sent) {
- Alert::set($Language->g('check-your-inbox-for-your-login-access-code'));
- return true;
- }
- else {
- Alert::set($Language->g('There was a problem sending the email'));
- return false;
- }
- }
- }
-
- // Bruteforce protection, add IP to blacklist.
- $Security->addLoginFail();
- Alert::set($Language->g('check-your-inbox-for-your-login-access-code'));
-
- return false;
-}
-
-function checkGet($args)
-{
- global $Security;
- global $Language;
- global $Login;
-
- if($Security->isBlocked()) {
- Alert::set($Language->g('IP address has been blocked').' '.$Language->g('Try again in a few minutes'));
- return false;
- }
-
- // Verify User sanitize the input
- if( $Login->verifyUserByToken($args['username'], $args['tokenEmail']) )
- {
- // Renew the tokenCRFS. This token will be the same inside the session for multiple forms.
- $Security->generateTokenCSRF();
-
- Redirect::page('admin', 'dashboard');
- return true;
- }
-
- // Bruteforce protection, add IP to blacklist.
- $Security->addToBlacklist();
- return false;
-}
-
-// ============================================================================
-// Main before POST
-// ============================================================================
-
-// ============================================================================
-// GET Method
-// ============================================================================
-
-if( !empty($_GET['tokenEmail']) && !empty($_GET['username']) )
-{
- checkGet($_GET);
-}
-
-
-// ============================================================================
-// POST Method
-// ============================================================================
-
-if( $_SERVER['REQUEST_METHOD'] == 'POST' )
-{
- checkPost($_POST);
-}
-
-// ============================================================================
-// Main after POST
-// ============================================================================
diff --git a/bl-kernel/admin/controllers/login.php b/bl-kernel/admin/controllers/login.php
index de7e95af..9b9da20c 100644
--- a/bl-kernel/admin/controllers/login.php
+++ b/bl-kernel/admin/controllers/login.php
@@ -10,45 +10,45 @@
function checkLogin($args)
{
- global $Security;
- global $Login;
- global $Language;
+ global $security;
+ global $login;
+ global $L;
- if ($Security->isBlocked()) {
- Alert::set($Language->g('IP address has been blocked').' '.$Language->g('Try again in a few minutes'));
+ if ($security->isBlocked()) {
+ Alert::set($L->g('IP address has been blocked').' '.$L->g('Try again in a few minutes'), ALERT_STATUS_FAIL);
return false;
}
- if ($Login->verifyUser($_POST['username'], $_POST['password'])) {
+ if ($login->verifyUser($_POST['username'], $_POST['password'])) {
if (isset($_POST['remember'])) {
- $Login->setRememberMe($_POST['username']);
+ $login->setRememberMe($_POST['username']);
}
// Renew the token. This token will be the same inside the session for multiple forms.
- $Security->generateTokenCSRF();
+ $security->generateTokenCSRF();
+
Redirect::page('dashboard');
return true;
}
// Bruteforce protection, add IP to the blacklist
- $Security->addToBlacklist();
+ $security->addToBlacklist();
// Create alert
- Alert::set($Language->g('Username or password incorrect'));
-
+ Alert::set($L->g('Username or password incorrect'), ALERT_STATUS_FAIL);
return false;
}
function checkRememberMe()
{
- global $Security;
- global $Login;
+ global $security;
+ global $login;
- if ($Security->isBlocked()) {
+ if ($security->isBlocked()) {
return false;
}
- if ($Login->verifyUserByRemember()) {
- $Security->generateTokenCSRF();
+ if ($login->verifyUserByRemember()) {
+ $security->generateTokenCSRF();
Redirect::page('dashboard');
return true;
}
diff --git a/bl-kernel/admin/controllers/logout.php b/bl-kernel/admin/controllers/logout.php
index 8aa4adef..dbb5794e 100644
--- a/bl-kernel/admin/controllers/logout.php
+++ b/bl-kernel/admin/controllers/logout.php
@@ -20,6 +20,6 @@
// Main after POST
// ============================================================================
-if ($Login->logout()) {
+if ($login->logout()) {
Redirect::home();
}
diff --git a/bl-kernel/admin/controllers/new-category.php b/bl-kernel/admin/controllers/new-category.php
index b752efb5..22ac496f 100644
--- a/bl-kernel/admin/controllers/new-category.php
+++ b/bl-kernel/admin/controllers/new-category.php
@@ -4,10 +4,7 @@
// Check role
// ============================================================================
-if ($Login->role()!=='admin') {
- Alert::set($Language->g('You do not have sufficient permissions'));
- Redirect::page('dashboard');
-}
+checkRole(array('admin'));
// ============================================================================
// Functions
@@ -22,8 +19,9 @@ if ($Login->role()!=='admin') {
// ============================================================================
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
- createCategory($_POST['category']);
- Redirect::page('categories');
+ if (createCategory($_POST['category'])) {
+ Redirect::page('categories');
+ }
}
// ============================================================================
@@ -31,4 +29,4 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// ============================================================================
// Title of the page
-$layout['title'] .= ' - '.$Language->g('New category');
\ No newline at end of file
+$layout['title'] .= ' - '.$L->g('New category');
\ No newline at end of file
diff --git a/bl-kernel/admin/controllers/new-content.php b/bl-kernel/admin/controllers/new-content.php
index 5c16c132..fd119222 100644
--- a/bl-kernel/admin/controllers/new-content.php
+++ b/bl-kernel/admin/controllers/new-content.php
@@ -4,6 +4,8 @@
// Check role
// ============================================================================
+checkRole(array('admin', 'editor'));
+
// ============================================================================
// Functions
// ============================================================================
@@ -17,6 +19,11 @@
// ============================================================================
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
+ // If the checkbox is not selected the form doesn't send the field
+ $_POST['noindex'] = isset($_POST['noindex'])?true:false;
+ $_POST['nofollow'] = isset($_POST['nofollow'])?true:false;
+ $_POST['noarchive'] = isset($_POST['noarchive'])?true:false;
+
createPage($_POST);
Redirect::page('content');
}
@@ -26,4 +33,4 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// ============================================================================
// Title of the page
-$layout['title'] .= ' - '.$Language->g('New content');
\ No newline at end of file
+$layout['title'] = $L->g('New content').' - '.$layout['title'];
\ No newline at end of file
diff --git a/bl-kernel/admin/controllers/add-user.php b/bl-kernel/admin/controllers/new-user.php
similarity index 84%
rename from bl-kernel/admin/controllers/add-user.php
rename to bl-kernel/admin/controllers/new-user.php
index 159c8193..e2a8ea9e 100644
--- a/bl-kernel/admin/controllers/add-user.php
+++ b/bl-kernel/admin/controllers/new-user.php
@@ -4,10 +4,7 @@
// Check role
// ============================================================================
-if ($Login->role()!=='admin') {
- Alert::set($Language->g('You do not have sufficient permissions'));
- Redirect::page('dashboard');
-}
+checkRole(array('admin'));
// ============================================================================
// Functions
@@ -32,4 +29,4 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// ============================================================================
// Title of the page
-$layout['title'] .= ' - '.$Language->g('Add a new user');
\ No newline at end of file
+$layout['title'] .= ' - '.$L->g('Add a new user');
\ No newline at end of file
diff --git a/bl-kernel/admin/controllers/plugins-position.php b/bl-kernel/admin/controllers/plugins-position.php
index cad0096c..164e113f 100644
--- a/bl-kernel/admin/controllers/plugins-position.php
+++ b/bl-kernel/admin/controllers/plugins-position.php
@@ -4,10 +4,7 @@
// Check role
// ============================================================================
-if ($Login->role()!=='admin') {
- Alert::set($Language->g('You do not have sufficient permissions'));
- Redirect::page('dashboard');
-}
+checkRole(array('admin'));
// ============================================================================
// Functions
@@ -29,4 +26,4 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// ============================================================================
// Title of the page
-$layout['title'] .= ' - '.$Language->g('Plugins');
\ No newline at end of file
+$layout['title'] .= ' - '.$L->g('Plugins');
\ No newline at end of file
diff --git a/bl-kernel/admin/controllers/plugins.php b/bl-kernel/admin/controllers/plugins.php
index 75833f08..074f555a 100644
--- a/bl-kernel/admin/controllers/plugins.php
+++ b/bl-kernel/admin/controllers/plugins.php
@@ -4,10 +4,7 @@
// Check role
// ============================================================================
-if ($Login->role()!=='admin') {
- Alert::set($Language->g('You do not have sufficient permissions'));
- Redirect::page('dashboard');
-}
+checkRole(array('admin'));
// ============================================================================
// Functions
@@ -26,4 +23,4 @@ if ($Login->role()!=='admin') {
// ============================================================================
// Title of the page
-$layout['title'] .= ' - '.$Language->g('Plugins');
\ No newline at end of file
+$layout['title'] .= ' - '.$L->g('Plugins');
\ No newline at end of file
diff --git a/bl-kernel/admin/controllers/settings-general.php b/bl-kernel/admin/controllers/settings-general.php
index 6608286c..0f7dbcee 100644
--- a/bl-kernel/admin/controllers/settings-general.php
+++ b/bl-kernel/admin/controllers/settings-general.php
@@ -4,10 +4,7 @@
// Check role
// ============================================================================
-if ($Login->role()!=='admin') {
- Alert::set($Language->g('You do not have sufficient permissions'));
- Redirect::page('dashboard');
-}
+checkRole(array('admin'));
// ============================================================================
// Functions
@@ -31,4 +28,4 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// ============================================================================
// Title of the page
-$layout['title'] .= ' - '.$Language->g('General Settings');
\ No newline at end of file
+$layout['title'] .= ' - '.$L->g('General Settings');
\ No newline at end of file
diff --git a/bl-kernel/admin/controllers/settings-regional.php b/bl-kernel/admin/controllers/settings-regional.php
index 2085e82f..98b4ded3 100644
--- a/bl-kernel/admin/controllers/settings-regional.php
+++ b/bl-kernel/admin/controllers/settings-regional.php
@@ -4,10 +4,7 @@
// Check role
// ============================================================================
-if ($Login->role()!=='admin') {
- Alert::set($Language->g('You do not have sufficient permissions'));
- Redirect::page('dashboard');
-}
+checkRole(array('admin'));
// ============================================================================
// Functions
@@ -31,4 +28,4 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// ============================================================================
// Title of the page
-$layout['title'] .= ' - '.$Language->g('Language and timezone');
\ No newline at end of file
+$layout['title'] .= ' - '.$L->g('Language and timezone');
\ No newline at end of file
diff --git a/bl-kernel/admin/controllers/settings-advanced.php b/bl-kernel/admin/controllers/settings.php
similarity index 54%
rename from bl-kernel/admin/controllers/settings-advanced.php
rename to bl-kernel/admin/controllers/settings.php
index 71f153fc..60c99564 100644
--- a/bl-kernel/admin/controllers/settings-advanced.php
+++ b/bl-kernel/admin/controllers/settings.php
@@ -4,10 +4,7 @@
// Check role
// ============================================================================
-if ($Login->role()!=='admin') {
- Alert::set($Language->g('You do not have sufficient permissions'));
- Redirect::page('dashboard');
-}
+checkRole(array('admin'));
// ============================================================================
// Functions
@@ -23,31 +20,12 @@ if ($Login->role()!=='admin') {
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
editSettings($_POST);
- Redirect::page('settings-advanced');
+ Redirect::page('settings');
}
// ============================================================================
// Main after POST
// ============================================================================
-$allPages = buildAllpages($publishedPages=true, $staticPages=true, $draftPages=false, $scheduledPages=false);
-
-// Generate $pagesByParentByKey and pagesByParent
-$pagesByParent = array(PARENT=>array());
-$pagesByParentByKey = array(PARENT=>array());
-buildPagesByParent(true, true);
-
-// Homepage select options
-$homepageOptions = array(' '=>'- '.$L->g('Default').' -');
-foreach ($allPages as $key=>$page) {
- $parentKey = $page->parentKey();
- if ($parentKey) {
- $homepageOptions[$key] = $pagesByParentByKey[PARENT][$parentKey]->title() .'->'. $page->title();
- } else {
- $homepageOptions[$key] = $page->title();
- }
-
- ksort($homepageOptions);
-}
// Title of the page
-$layout['title'] .= ' - '.$Language->g('Advanced Settings');
\ No newline at end of file
+$layout['title'] .= ' - '.$L->g('Advanced Settings');
\ No newline at end of file
diff --git a/bl-kernel/admin/controllers/themes.php b/bl-kernel/admin/controllers/themes.php
index ce4341fc..43e3dbf3 100644
--- a/bl-kernel/admin/controllers/themes.php
+++ b/bl-kernel/admin/controllers/themes.php
@@ -4,10 +4,7 @@
// Check role
// ============================================================================
-if ($Login->role()!=='admin') {
- Alert::set($Language->g('You do not have sufficient permissions'));
- Redirect::page('dashboard');
-}
+checkRole(array('admin'));
// ============================================================================
// Main after POST
@@ -24,4 +21,4 @@ if ($Login->role()!=='admin') {
$themes = buildThemes();
// Title of the page
-$layout['title'] .= ' - '.$Language->g('Themes');
\ No newline at end of file
+$layout['title'] .= ' - '.$L->g('Themes');
\ No newline at end of file
diff --git a/bl-kernel/admin/controllers/uninstall-plugin.php b/bl-kernel/admin/controllers/uninstall-plugin.php
index 1a694a57..16d865c7 100644
--- a/bl-kernel/admin/controllers/uninstall-plugin.php
+++ b/bl-kernel/admin/controllers/uninstall-plugin.php
@@ -4,10 +4,7 @@
// Check role
// ============================================================================
-if ($Login->role()!=='admin') {
- Alert::set($Language->g('You do not have sufficient permissions'));
- Redirect::page('dashboard');
-}
+checkRole(array('admin'));
// ============================================================================
// Functions
diff --git a/bl-kernel/admin/controllers/user-password.php b/bl-kernel/admin/controllers/user-password.php
index e498f307..bc92811b 100644
--- a/bl-kernel/admin/controllers/user-password.php
+++ b/bl-kernel/admin/controllers/user-password.php
@@ -4,40 +4,7 @@
// Functions
// ============================================================================
-function setPassword($username, $new_password, $confirm_password)
-{
- global $dbUsers;
- global $Language;
- global $Syslog;
- // Password length
- if( strlen($new_password) < 6 )
- {
- Alert::set($Language->g('Password must be at least 6 characters long'), ALERT_STATUS_FAIL);
- return false;
- }
-
- if($new_password===$confirm_password)
- {
- if( $dbUsers->setPassword($username, $new_password) ) {
- Alert::set($Language->g('The changes have been saved'), ALERT_STATUS_OK);
- // Add to syslog
- $Syslog->add(array(
- 'dictionaryKey'=>'user-password-changed',
- 'notes'=>$username
- ));
- return true;
- }
- else {
- Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to change the user password.');
- return false;
- }
- }
- else {
- Alert::set($Language->g('The password and confirmation password do not match'), ALERT_STATUS_FAIL);
- return false;
- }
-}
// ============================================================================
// Main before POST
@@ -47,16 +14,12 @@ function setPassword($username, $new_password, $confirm_password)
// POST Method
// ============================================================================
-if( $_SERVER['REQUEST_METHOD'] == 'POST' )
-{
- // Prevent editors to administrate other users.
- if($Login->role()!=='admin')
- {
- $_POST['username'] = $Login->username();
- unset($_POST['role']);
- }
-
- if( setPassword($_POST['username'], $_POST['new_password'], $_POST['confirm_password']) ) {
+if ($_SERVER['REQUEST_METHOD'] == 'POST') {
+ if (changeUserPassword(array(
+ 'username'=>$_POST['username'],
+ 'newPassword'=>$_POST['newPassword'],
+ 'confirmPassword'=>$_POST['confirmPassword']
+ ))) {
Redirect::page('users');
}
}
@@ -65,18 +28,17 @@ if( $_SERVER['REQUEST_METHOD'] == 'POST' )
// Main after POST
// ============================================================================
-if($Login->role()!=='admin') {
- $layout['parameters'] = $Login->username();
+// Prevent non-administrators to change other users
+if ($login->role()!=='admin') {
+ $layout['parameters'] = $login->username();
}
-$_user = $dbUsers->getDb($layout['parameters']);
-
-// If the user doesn't exist, redirect to the users list.
-if($_user===false) {
+try {
+ $username = $layout['parameters'];
+ $user = new User($username);
+} catch (Exception $e) {
Redirect::page('users');
}
-$_user['username'] = $layout['parameters'];
-
// Title of the page
-$layout['title'] .= ' - '.$Language->g('Change password');
\ No newline at end of file
+$layout['title'] = $L->g('Change password').' - '.$layout['title'];
\ No newline at end of file
diff --git a/bl-kernel/admin/controllers/users.php b/bl-kernel/admin/controllers/users.php
index 8fa9ab28..a9a00232 100644
--- a/bl-kernel/admin/controllers/users.php
+++ b/bl-kernel/admin/controllers/users.php
@@ -4,10 +4,7 @@
// Check role
// ============================================================================
-if ($Login->role()!=='admin') {
- Alert::set($Language->g('You do not have sufficient permissions'));
- Redirect::page('dashboard');
-}
+checkRole(array('admin'));
// ============================================================================
// Functions
@@ -23,7 +20,7 @@ if ($Login->role()!=='admin') {
if( $_SERVER['REQUEST_METHOD'] == 'POST' )
{
- $Site->set($_POST);
+ $site->set($_POST);
}
// ============================================================================
@@ -31,4 +28,4 @@ if( $_SERVER['REQUEST_METHOD'] == 'POST' )
// ============================================================================
// Title of the page
-$layout['title'] .= ' - '.$Language->g('Users');
\ No newline at end of file
+$layout['title'] .= ' - '.$L->g('Users');
\ No newline at end of file
diff --git a/bl-kernel/admin/themes/booty/css/bludit.css b/bl-kernel/admin/themes/booty/css/bludit.css
new file mode 100644
index 00000000..c8cde06e
--- /dev/null
+++ b/bl-kernel/admin/themes/booty/css/bludit.css
@@ -0,0 +1,226 @@
+
+html {
+ height: 100%;
+ font-size: 0.9rem;
+ background: #fcfcfc;
+}
+
+body {
+ background: #fcfcfc;
+}
+
+/*
+ BOOTSTRAP Hacks
+*/
+
+@media (min-width: 1200px) {
+ .container {
+ max-width: 1250px;
+ }
+}
+
+/* for small devices */
+@media (max-width: 575.98px) {
+ #jsmediaManagerButton,
+ #jscategoryButton,
+ #jsdescriptionButton {
+ width: 100%;
+ text-align: left;
+ }
+}
+
+a {
+ color: #4a90e2;
+}
+
+a:hover {
+ color: #4a90e2;
+}
+
+.btn {
+ border-radius: 2px;
+}
+
+.btn-primary {
+ background-color: #4F93E0;
+ border-color: #4a90e2;
+}
+
+.btn-primary:hover {
+ background-color: #4585CF;
+ border-color: #4a90e2;
+}
+
+.btn-form {
+ background-color: #F3F3F3;
+ border-color: #DDD;
+ color: #000;
+}
+
+.btn-form:hover {
+ background-color: rgb(228, 228, 228);
+ border-color: #DDD;
+ color: #000;
+}
+
+code {
+ padding: 3px 5px 2px;
+ margin: 0 1px;
+ background: #eaeaea;
+ background: rgba(0,0,0,.07);
+ color: #444;
+}
+
+.list-group-sortable {
+ cursor: pointer;
+}
+
+/*
+ LOGIN
+*/
+body.login {
+ background: rgb(255,255,255);
+ background: linear-gradient(0deg, rgba(255,255,255,1) 0%, rgba(250,250,250,1) 53%);
+ height: 100%;
+}
+
+
+/*
+ DASHBOARD
+*/
+
+#dashboard ul.list-group.list-group-striped li {
+ border: none;
+}
+
+#dashboard ul.list-group.list-group-striped li:nth-of-type(even) {
+ background: #f1f1f1;
+
+}
+
+#dashboard div.quick-links-icons {
+ font-size: 3em;
+ width: 100%;
+}
+
+#dashboard a.quick-links {
+ color: #777;
+}
+
+#dashboard a.quick-links:hover {
+ text-decoration: none;
+ color: #4586d4;
+}
+
+.ct-series-a .ct-line {
+ /* Set the colour of this series line */
+ stroke: #4a90e2;
+ /* Control the thikness of your lines */
+ stroke-width: 2px;
+ /* Create a dashed line with a pattern */
+}
+
+/* This selector overrides the points style on line charts. Points on line charts are actually just very short strokes. This allows you to customize even the point size in CSS */
+.ct-series-a .ct-point {
+ /* Colour of your points */
+ stroke: #4a90e2;
+ /* Size of your points */
+ stroke-width: 8px;
+}
+
+/*
+ ALERT
+*/
+#alert {
+ display: none;
+ position: fixed;
+ text-align: center;
+ border-radius: 0px;
+ border: 0;
+ z-index: 1000;
+ bottom: 0;
+ right: 0;
+ margin: 0;
+}
+
+.alert-success {
+ background-color: #4586d4;
+ color: #ffffff;
+}
+
+.alert-danger {
+ background-color: #d44545;
+ color: #ffffff;
+}
+
+/*
+ SIDEBAR
+*/
+div.sidebar .nav-item a {
+ padding-left:0;
+ padding-right:0;
+ color: #777;
+ padding-top: 5px;
+ padding-bottom: 5px;
+}
+
+div.sidebar .nav-item a:hover {
+ text-decoration: underline;
+}
+
+div.sidebar .nav-item h4 {
+ font-size: 1.3em;
+ text-transform: uppercase;
+ font-weight: 400;
+ margin-top: 10px;
+}
+
+div.sidebar .nav-item span.oi {
+ color: #000;
+ font-size: 0.8em;
+ padding-right: 5px;
+}
+
+/*
+ PLUGINS
+*/
+.plugin-form label {
+ display: block;
+ margin-top: 1rem !important;
+}
+
+.plugin-form input[type="text"],
+.plugin-form textarea,
+.plugin-form select {
+ display: block;
+ width: 100%;
+ padding: .375rem .75rem;
+ font-size: 1rem;
+ line-height: 1.5;
+ color: #495057;
+ background-color: #fff;
+ background-clip: padding-box;
+ border: 1px solid #ced4da;
+ border-radius: .25rem;
+ transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out;
+}
+
+.plugin-form textarea {
+ min-height: 120px;
+}
+
+.plugin-form span.tip {
+ display: block;
+ font-size: 80%;
+ font-weight: 400;
+ margin-top: .25rem;
+ color: #6c757d !important;
+}
+
+/*
+ Manage > Content
+*/
+
+td.child {
+ padding-left: 30px;
+}
\ No newline at end of file
diff --git a/bl-kernel/admin/themes/booty/css/chartist.min.css b/bl-kernel/admin/themes/booty/css/chartist.min.css
new file mode 100644
index 00000000..6a23d470
--- /dev/null
+++ b/bl-kernel/admin/themes/booty/css/chartist.min.css
@@ -0,0 +1 @@
+.ct-double-octave:after,.ct-major-eleventh:after,.ct-major-second:after,.ct-major-seventh:after,.ct-major-sixth:after,.ct-major-tenth:after,.ct-major-third:after,.ct-major-twelfth:after,.ct-minor-second:after,.ct-minor-seventh:after,.ct-minor-sixth:after,.ct-minor-third:after,.ct-octave:after,.ct-perfect-fifth:after,.ct-perfect-fourth:after,.ct-square:after{content:"";clear:both}.ct-label{fill:rgba(0,0,0,.4);color:rgba(0,0,0,.4);font-size:.75rem;line-height:1}.ct-grid-background,.ct-line{fill:none}.ct-chart-bar .ct-label,.ct-chart-line .ct-label{display:block;display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex}.ct-chart-donut .ct-label,.ct-chart-pie .ct-label{dominant-baseline:central}.ct-label.ct-horizontal.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-label.ct-horizontal.ct-end{-webkit-box-align:flex-start;-webkit-align-items:flex-start;-ms-flex-align:flex-start;align-items:flex-start;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-label.ct-vertical.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-end;-webkit-justify-content:flex-end;-ms-flex-pack:flex-end;justify-content:flex-end;text-align:right;text-anchor:end}.ct-label.ct-vertical.ct-end{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-chart-bar .ct-label.ct-horizontal.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;text-align:center;text-anchor:start}.ct-chart-bar .ct-label.ct-horizontal.ct-end{-webkit-box-align:flex-start;-webkit-align-items:flex-start;-ms-flex-align:flex-start;align-items:flex-start;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;text-align:center;text-anchor:start}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-horizontal.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-horizontal.ct-end{-webkit-box-align:flex-start;-webkit-align-items:flex-start;-ms-flex-align:flex-start;align-items:flex-start;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-vertical.ct-start{-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:flex-end;-webkit-justify-content:flex-end;-ms-flex-pack:flex-end;justify-content:flex-end;text-align:right;text-anchor:end}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-vertical.ct-end{-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:end}.ct-grid{stroke:rgba(0,0,0,.2);stroke-width:1px;stroke-dasharray:2px}.ct-point{stroke-width:10px;stroke-linecap:round}.ct-line{stroke-width:4px}.ct-area{stroke:none;fill-opacity:.1}.ct-bar{fill:none;stroke-width:10px}.ct-slice-donut{fill:none;stroke-width:60px}.ct-series-a .ct-bar,.ct-series-a .ct-line,.ct-series-a .ct-point,.ct-series-a .ct-slice-donut{stroke:#d70206}.ct-series-a .ct-area,.ct-series-a .ct-slice-donut-solid,.ct-series-a .ct-slice-pie{fill:#d70206}.ct-series-b .ct-bar,.ct-series-b .ct-line,.ct-series-b .ct-point,.ct-series-b .ct-slice-donut{stroke:#f05b4f}.ct-series-b .ct-area,.ct-series-b .ct-slice-donut-solid,.ct-series-b .ct-slice-pie{fill:#f05b4f}.ct-series-c .ct-bar,.ct-series-c .ct-line,.ct-series-c .ct-point,.ct-series-c .ct-slice-donut{stroke:#f4c63d}.ct-series-c .ct-area,.ct-series-c .ct-slice-donut-solid,.ct-series-c .ct-slice-pie{fill:#f4c63d}.ct-series-d .ct-bar,.ct-series-d .ct-line,.ct-series-d .ct-point,.ct-series-d .ct-slice-donut{stroke:#d17905}.ct-series-d .ct-area,.ct-series-d .ct-slice-donut-solid,.ct-series-d .ct-slice-pie{fill:#d17905}.ct-series-e .ct-bar,.ct-series-e .ct-line,.ct-series-e .ct-point,.ct-series-e .ct-slice-donut{stroke:#453d3f}.ct-series-e .ct-area,.ct-series-e .ct-slice-donut-solid,.ct-series-e .ct-slice-pie{fill:#453d3f}.ct-series-f .ct-bar,.ct-series-f .ct-line,.ct-series-f .ct-point,.ct-series-f .ct-slice-donut{stroke:#59922b}.ct-series-f .ct-area,.ct-series-f .ct-slice-donut-solid,.ct-series-f .ct-slice-pie{fill:#59922b}.ct-series-g .ct-bar,.ct-series-g .ct-line,.ct-series-g .ct-point,.ct-series-g .ct-slice-donut{stroke:#0544d3}.ct-series-g .ct-area,.ct-series-g .ct-slice-donut-solid,.ct-series-g .ct-slice-pie{fill:#0544d3}.ct-series-h .ct-bar,.ct-series-h .ct-line,.ct-series-h .ct-point,.ct-series-h .ct-slice-donut{stroke:#6b0392}.ct-series-h .ct-area,.ct-series-h .ct-slice-donut-solid,.ct-series-h .ct-slice-pie{fill:#6b0392}.ct-series-i .ct-bar,.ct-series-i .ct-line,.ct-series-i .ct-point,.ct-series-i .ct-slice-donut{stroke:#f05b4f}.ct-series-i .ct-area,.ct-series-i .ct-slice-donut-solid,.ct-series-i .ct-slice-pie{fill:#f05b4f}.ct-series-j .ct-bar,.ct-series-j .ct-line,.ct-series-j .ct-point,.ct-series-j .ct-slice-donut{stroke:#dda458}.ct-series-j .ct-area,.ct-series-j .ct-slice-donut-solid,.ct-series-j .ct-slice-pie{fill:#dda458}.ct-series-k .ct-bar,.ct-series-k .ct-line,.ct-series-k .ct-point,.ct-series-k .ct-slice-donut{stroke:#eacf7d}.ct-series-k .ct-area,.ct-series-k .ct-slice-donut-solid,.ct-series-k .ct-slice-pie{fill:#eacf7d}.ct-series-l .ct-bar,.ct-series-l .ct-line,.ct-series-l .ct-point,.ct-series-l .ct-slice-donut{stroke:#86797d}.ct-series-l .ct-area,.ct-series-l .ct-slice-donut-solid,.ct-series-l .ct-slice-pie{fill:#86797d}.ct-series-m .ct-bar,.ct-series-m .ct-line,.ct-series-m .ct-point,.ct-series-m .ct-slice-donut{stroke:#b2c326}.ct-series-m .ct-area,.ct-series-m .ct-slice-donut-solid,.ct-series-m .ct-slice-pie{fill:#b2c326}.ct-series-n .ct-bar,.ct-series-n .ct-line,.ct-series-n .ct-point,.ct-series-n .ct-slice-donut{stroke:#6188e2}.ct-series-n .ct-area,.ct-series-n .ct-slice-donut-solid,.ct-series-n .ct-slice-pie{fill:#6188e2}.ct-series-o .ct-bar,.ct-series-o .ct-line,.ct-series-o .ct-point,.ct-series-o .ct-slice-donut{stroke:#a748ca}.ct-series-o .ct-area,.ct-series-o .ct-slice-donut-solid,.ct-series-o .ct-slice-pie{fill:#a748ca}.ct-square{display:block;position:relative;width:100%}.ct-square:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:100%}.ct-square:after{display:table}.ct-square>svg{display:block;position:absolute;top:0;left:0}.ct-minor-second{display:block;position:relative;width:100%}.ct-minor-second:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:93.75%}.ct-minor-second:after{display:table}.ct-minor-second>svg{display:block;position:absolute;top:0;left:0}.ct-major-second{display:block;position:relative;width:100%}.ct-major-second:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:88.8888888889%}.ct-major-second:after{display:table}.ct-major-second>svg{display:block;position:absolute;top:0;left:0}.ct-minor-third{display:block;position:relative;width:100%}.ct-minor-third:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:83.3333333333%}.ct-minor-third:after{display:table}.ct-minor-third>svg{display:block;position:absolute;top:0;left:0}.ct-major-third{display:block;position:relative;width:100%}.ct-major-third:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:80%}.ct-major-third:after{display:table}.ct-major-third>svg{display:block;position:absolute;top:0;left:0}.ct-perfect-fourth{display:block;position:relative;width:100%}.ct-perfect-fourth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:75%}.ct-perfect-fourth:after{display:table}.ct-perfect-fourth>svg{display:block;position:absolute;top:0;left:0}.ct-perfect-fifth{display:block;position:relative;width:100%}.ct-perfect-fifth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:66.6666666667%}.ct-perfect-fifth:after{display:table}.ct-perfect-fifth>svg{display:block;position:absolute;top:0;left:0}.ct-minor-sixth{display:block;position:relative;width:100%}.ct-minor-sixth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:62.5%}.ct-minor-sixth:after{display:table}.ct-minor-sixth>svg{display:block;position:absolute;top:0;left:0}.ct-golden-section{display:block;position:relative;width:100%}.ct-golden-section:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:61.804697157%}.ct-golden-section:after{content:"";display:table;clear:both}.ct-golden-section>svg{display:block;position:absolute;top:0;left:0}.ct-major-sixth{display:block;position:relative;width:100%}.ct-major-sixth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:60%}.ct-major-sixth:after{display:table}.ct-major-sixth>svg{display:block;position:absolute;top:0;left:0}.ct-minor-seventh{display:block;position:relative;width:100%}.ct-minor-seventh:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:56.25%}.ct-minor-seventh:after{display:table}.ct-minor-seventh>svg{display:block;position:absolute;top:0;left:0}.ct-major-seventh{display:block;position:relative;width:100%}.ct-major-seventh:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:53.3333333333%}.ct-major-seventh:after{display:table}.ct-major-seventh>svg{display:block;position:absolute;top:0;left:0}.ct-octave{display:block;position:relative;width:100%}.ct-octave:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:50%}.ct-octave:after{display:table}.ct-octave>svg{display:block;position:absolute;top:0;left:0}.ct-major-tenth{display:block;position:relative;width:100%}.ct-major-tenth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:40%}.ct-major-tenth:after{display:table}.ct-major-tenth>svg{display:block;position:absolute;top:0;left:0}.ct-major-eleventh{display:block;position:relative;width:100%}.ct-major-eleventh:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:37.5%}.ct-major-eleventh:after{display:table}.ct-major-eleventh>svg{display:block;position:absolute;top:0;left:0}.ct-major-twelfth{display:block;position:relative;width:100%}.ct-major-twelfth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:33.3333333333%}.ct-major-twelfth:after{display:table}.ct-major-twelfth>svg{display:block;position:absolute;top:0;left:0}.ct-double-octave{display:block;position:relative;width:100%}.ct-double-octave:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:25%}.ct-double-octave:after{display:table}.ct-double-octave>svg{display:block;position:absolute;top:0;left:0}
\ No newline at end of file
diff --git a/bl-kernel/admin/themes/booty/css/fonts/open-iconic.eot b/bl-kernel/admin/themes/booty/css/fonts/open-iconic.eot
new file mode 100755
index 00000000..f98177db
Binary files /dev/null and b/bl-kernel/admin/themes/booty/css/fonts/open-iconic.eot differ
diff --git a/bl-kernel/admin/themes/booty/css/fonts/open-iconic.otf b/bl-kernel/admin/themes/booty/css/fonts/open-iconic.otf
new file mode 100755
index 00000000..f6bd6846
Binary files /dev/null and b/bl-kernel/admin/themes/booty/css/fonts/open-iconic.otf differ
diff --git a/bl-kernel/admin/themes/booty/css/fonts/open-iconic.svg b/bl-kernel/admin/themes/booty/css/fonts/open-iconic.svg
new file mode 100755
index 00000000..32b2c4e9
--- /dev/null
+++ b/bl-kernel/admin/themes/booty/css/fonts/open-iconic.svg
@@ -0,0 +1,543 @@
+
+
+
+
+
+Created by FontForge 20120731 at Tue Jul 1 20:39:22 2014
+ By P.J. Onori
+Created by P.J. Onori with FontForge 2.0 (http://fontforge.sf.net)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bl-kernel/admin/themes/booty/css/fonts/open-iconic.ttf b/bl-kernel/admin/themes/booty/css/fonts/open-iconic.ttf
new file mode 100755
index 00000000..fab60486
Binary files /dev/null and b/bl-kernel/admin/themes/booty/css/fonts/open-iconic.ttf differ
diff --git a/bl-kernel/admin/themes/booty/css/fonts/open-iconic.woff b/bl-kernel/admin/themes/booty/css/fonts/open-iconic.woff
new file mode 100755
index 00000000..f9309988
Binary files /dev/null and b/bl-kernel/admin/themes/booty/css/fonts/open-iconic.woff differ
diff --git a/bl-kernel/admin/themes/booty/css/jquery-auto-complete.css b/bl-kernel/admin/themes/booty/css/jquery-auto-complete.css
new file mode 100755
index 00000000..4261b1d0
--- /dev/null
+++ b/bl-kernel/admin/themes/booty/css/jquery-auto-complete.css
@@ -0,0 +1,9 @@
+.autocomplete-suggestions {
+ text-align: left; cursor: default; border: 1px solid #ccc; border-top: 0; background: #fff; box-shadow: -1px 1px 3px rgba(0,0,0,.1);
+
+ /* core styles should not be changed */
+ position: absolute; display: none; z-index: 9999; max-height: 254px; overflow: hidden; overflow-y: auto; box-sizing: border-box;
+}
+.autocomplete-suggestion { position: relative; padding: 0 .6em; line-height: 23px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 1.02em; color: #333; }
+.autocomplete-suggestion b { font-weight: normal; color: #1f8dd6; }
+.autocomplete-suggestion.selected { background: #f0f0f0; }
diff --git a/bl-kernel/admin/themes/booty/css/jquery.datetimepicker.min.css b/bl-kernel/admin/themes/booty/css/jquery.datetimepicker.min.css
new file mode 100755
index 00000000..e3e02e2b
--- /dev/null
+++ b/bl-kernel/admin/themes/booty/css/jquery.datetimepicker.min.css
@@ -0,0 +1 @@
+.xdsoft_datetimepicker{box-shadow:0 5px 15px -5px rgba(0,0,0,0.506);background:#fff;border-bottom:1px solid #bbb;border-left:1px solid #ccc;border-right:1px solid #ccc;border-top:1px solid #ccc;color:#333;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;padding:8px;padding-left:0;padding-top:2px;position:absolute;z-index:9999;-moz-box-sizing:border-box;box-sizing:border-box;display:none}.xdsoft_datetimepicker.xdsoft_rtl{padding:8px 0 8px 8px}.xdsoft_datetimepicker iframe{position:absolute;left:0;top:0;width:75px;height:210px;background:transparent;border:0}.xdsoft_datetimepicker button{border:none !important}.xdsoft_noselect{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.xdsoft_noselect::selection{background:transparent}.xdsoft_noselect::-moz-selection{background:transparent}.xdsoft_datetimepicker.xdsoft_inline{display:inline-block;position:static;box-shadow:none}.xdsoft_datetimepicker *{-moz-box-sizing:border-box;box-sizing:border-box;padding:0;margin:0}.xdsoft_datetimepicker .xdsoft_datepicker,.xdsoft_datetimepicker .xdsoft_timepicker{display:none}.xdsoft_datetimepicker .xdsoft_datepicker.active,.xdsoft_datetimepicker .xdsoft_timepicker.active{display:block}.xdsoft_datetimepicker .xdsoft_datepicker{width:224px;float:left;margin-left:8px}.xdsoft_datetimepicker.xdsoft_rtl .xdsoft_datepicker{float:right;margin-right:8px;margin-left:0}.xdsoft_datetimepicker.xdsoft_showweeks .xdsoft_datepicker{width:256px}.xdsoft_datetimepicker .xdsoft_timepicker{width:58px;float:left;text-align:center;margin-left:8px;margin-top:0}.xdsoft_datetimepicker.xdsoft_rtl .xdsoft_timepicker{float:right;margin-right:8px;margin-left:0}.xdsoft_datetimepicker .xdsoft_datepicker.active+.xdsoft_timepicker{margin-top:8px;margin-bottom:3px}.xdsoft_datetimepicker .xdsoft_monthpicker{position:relative;text-align:center}.xdsoft_datetimepicker .xdsoft_label i,.xdsoft_datetimepicker .xdsoft_prev,.xdsoft_datetimepicker .xdsoft_next,.xdsoft_datetimepicker .xdsoft_today_button{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAAeCAYAAADaW7vzAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6Q0NBRjI1NjM0M0UwMTFFNDk4NkFGMzJFQkQzQjEwRUIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6Q0NBRjI1NjQ0M0UwMTFFNDk4NkFGMzJFQkQzQjEwRUIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpDQ0FGMjU2MTQzRTAxMUU0OTg2QUYzMkVCRDNCMTBFQiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpDQ0FGMjU2MjQzRTAxMUU0OTg2QUYzMkVCRDNCMTBFQiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PoNEP54AAAIOSURBVHja7Jq9TsMwEMcxrZD4WpBYeKUCe+kTMCACHZh4BFfHO/AAIHZGFhYkBBsSEqxsLCAgXKhbXYOTxh9pfJVP+qutnZ5s/5Lz2Y5I03QhWji2GIcgAokWgfCxNvcOCCGKqiSqhUp0laHOne05vdEyGMfkdxJDVjgwDlEQgYQBgx+ULJaWSXXS6r/ER5FBVR8VfGftTKcITNs+a1XpcFoExREIDF14AVIFxgQUS+h520cdud6wNkC0UBw6BCO/HoCYwBhD8QCkQ/x1mwDyD4plh4D6DDV0TAGyo4HcawLIBBSLDkHeH0Mg2yVP3l4TQMZQDDsEOl/MgHQqhMNuE0D+oBh0CIr8MAKyazBH9WyBuKxDWgbXfjNf32TZ1KWm/Ap1oSk/R53UtQ5xTh3LUlMmT8gt6g51Q9p+SobxgJQ/qmsfZhWywGFSl0yBjCLJCMgXail3b7+rumdVJ2YRss4cN+r6qAHDkPWjPjdJCF4n9RmAD/V9A/Wp4NQassDjwlB6XBiCxcJQWmZZb8THFilfy/lfrTvLghq2TqTHrRMTKNJ0sIhdo15RT+RpyWwFdY96UZ/LdQKBGjcXpcc1AlSFEfLmouD+1knuxBDUVrvOBmoOC/rEcN7OQxKVeJTCiAdUzUJhA2Oez9QTkp72OTVcxDcXY8iKNkxGAJXmJCOQwOa6dhyXsOa6XwEGAKdeb5ET3rQdAAAAAElFTkSuQmCC)}.xdsoft_datetimepicker .xdsoft_label i{opacity:.5;background-position:-92px -19px;display:inline-block;width:9px;height:20px;vertical-align:middle}.xdsoft_datetimepicker .xdsoft_prev{float:left;background-position:-20px 0}.xdsoft_datetimepicker .xdsoft_today_button{float:left;background-position:-70px 0;margin-left:5px}.xdsoft_datetimepicker .xdsoft_next{float:right;background-position:0 0}.xdsoft_datetimepicker .xdsoft_next,.xdsoft_datetimepicker .xdsoft_prev,.xdsoft_datetimepicker .xdsoft_today_button{background-color:transparent;background-repeat:no-repeat;border:0 none;cursor:pointer;display:block;height:30px;opacity:.5;-ms-filter:"alpha(opacity=50)";outline:medium none;overflow:hidden;padding:0;position:relative;text-indent:100%;white-space:nowrap;width:20px;min-width:0}.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_prev,.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_next{float:none;background-position:-40px -15px;height:15px;width:30px;display:block;margin-left:14px;margin-top:7px}.xdsoft_datetimepicker.xdsoft_rtl .xdsoft_timepicker .xdsoft_prev,.xdsoft_datetimepicker.xdsoft_rtl .xdsoft_timepicker .xdsoft_next{float:none;margin-left:0;margin-right:14px}.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_prev{background-position:-40px 0;margin-bottom:7px;margin-top:0}.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time_box{height:151px;overflow:hidden;border-bottom:1px solid #ddd}.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time_box>div>div{background:#f5f5f5;border-top:1px solid #ddd;color:#666;font-size:12px;text-align:center;border-collapse:collapse;cursor:pointer;border-bottom-width:0;height:25px;line-height:25px}.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time_box>div>div:first-child{border-top-width:0}.xdsoft_datetimepicker .xdsoft_today_button:hover,.xdsoft_datetimepicker .xdsoft_next:hover,.xdsoft_datetimepicker .xdsoft_prev:hover{opacity:1;-ms-filter:"alpha(opacity=100)"}.xdsoft_datetimepicker .xdsoft_label{display:inline;position:relative;z-index:9999;margin:0;padding:5px 3px;font-size:14px;line-height:20px;font-weight:bold;background-color:#fff;float:left;width:182px;text-align:center;cursor:pointer}.xdsoft_datetimepicker .xdsoft_label:hover>span{text-decoration:underline}.xdsoft_datetimepicker .xdsoft_label:hover i{opacity:1.0}.xdsoft_datetimepicker .xdsoft_label>.xdsoft_select{border:1px solid #ccc;position:absolute;right:0;top:30px;z-index:101;display:none;background:#fff;max-height:160px;overflow-y:hidden}.xdsoft_datetimepicker .xdsoft_label>.xdsoft_select.xdsoft_monthselect{right:-7px}.xdsoft_datetimepicker .xdsoft_label>.xdsoft_select.xdsoft_yearselect{right:2px}.xdsoft_datetimepicker .xdsoft_label>.xdsoft_select>div>.xdsoft_option:hover{color:#fff;background:#ff8000}.xdsoft_datetimepicker .xdsoft_label>.xdsoft_select>div>.xdsoft_option{padding:2px 10px 2px 5px;text-decoration:none !important}.xdsoft_datetimepicker .xdsoft_label>.xdsoft_select>div>.xdsoft_option.xdsoft_current{background:#3af;box-shadow:#178fe5 0 1px 3px 0 inset;color:#fff;font-weight:700}.xdsoft_datetimepicker .xdsoft_month{width:100px;text-align:right}.xdsoft_datetimepicker .xdsoft_calendar{clear:both}.xdsoft_datetimepicker .xdsoft_year{width:48px;margin-left:5px}.xdsoft_datetimepicker .xdsoft_calendar table{border-collapse:collapse;width:100%}.xdsoft_datetimepicker .xdsoft_calendar td>div{padding-right:5px}.xdsoft_datetimepicker .xdsoft_calendar th{height:25px}.xdsoft_datetimepicker .xdsoft_calendar td,.xdsoft_datetimepicker .xdsoft_calendar th{width:14.2857142%;background:#f5f5f5;border:1px solid #ddd;color:#666;font-size:12px;text-align:right;vertical-align:middle;padding:0;border-collapse:collapse;cursor:pointer;height:25px}.xdsoft_datetimepicker.xdsoft_showweeks .xdsoft_calendar td,.xdsoft_datetimepicker.xdsoft_showweeks .xdsoft_calendar th{width:12.5%}.xdsoft_datetimepicker .xdsoft_calendar th{background:#f1f1f1}.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_today{color:#3af}.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_highlighted_default{background:#ffe9d2;box-shadow:#ffb871 0 1px 4px 0 inset;color:#000}.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_highlighted_mint{background:#c1ffc9;box-shadow:#00dd1c 0 1px 4px 0 inset;color:#000}.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_default,.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_current,.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time_box>div>div.xdsoft_current{background:#3af;box-shadow:#178fe5 0 1px 3px 0 inset;color:#fff;font-weight:700}.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_other_month,.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_disabled,.xdsoft_datetimepicker .xdsoft_time_box>div>div.xdsoft_disabled{opacity:.5;-ms-filter:"alpha(opacity=50)";cursor:default}.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_other_month.xdsoft_disabled{opacity:.2;-ms-filter:"alpha(opacity=20)"}.xdsoft_datetimepicker .xdsoft_calendar td:hover,.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time_box>div>div:hover{color:#fff !important;background:#ff8000 !important;box-shadow:none !important}.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_current.xdsoft_disabled:hover,.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time_box>div>div.xdsoft_current.xdsoft_disabled:hover{background:#3af !important;box-shadow:#178fe5 0 1px 3px 0 inset !important;color:#fff !important}.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_disabled:hover,.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time_box>div>div.xdsoft_disabled:hover{color:inherit !important;background:inherit !important;box-shadow:inherit !important}.xdsoft_datetimepicker .xdsoft_calendar th{font-weight:700;text-align:center;color:#999;cursor:default}.xdsoft_datetimepicker .xdsoft_copyright{color:#ccc !important;font-size:10px;clear:both;float:none;margin-left:8px}.xdsoft_datetimepicker .xdsoft_copyright a{color:#eee !important}.xdsoft_datetimepicker .xdsoft_copyright a:hover{color:#aaa !important}.xdsoft_time_box{position:relative;border:1px solid #ccc}.xdsoft_scrollbar>.xdsoft_scroller{background:#ccc !important;height:20px;border-radius:3px}.xdsoft_scrollbar{position:absolute;width:7px;right:0;top:0;bottom:0;cursor:pointer}.xdsoft_datetimepicker.xdsoft_rtl .xdsoft_scrollbar{left:0;right:auto}.xdsoft_scroller_box{position:relative}.xdsoft_datetimepicker.xdsoft_dark{box-shadow:0 5px 15px -5px rgba(255,255,255,0.506);background:#000;border-bottom:1px solid #444;border-left:1px solid #333;border-right:1px solid #333;border-top:1px solid #333;color:#ccc}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_timepicker .xdsoft_time_box{border-bottom:1px solid #222}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_timepicker .xdsoft_time_box>div>div{background:#0a0a0a;border-top:1px solid #222;color:#999}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_label{background-color:#000}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_label>.xdsoft_select{border:1px solid #333;background:#000}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_label>.xdsoft_select>div>.xdsoft_option:hover{color:#000;background:#007fff}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_label>.xdsoft_select>div>.xdsoft_option.xdsoft_current{background:#c50;box-shadow:#b03e00 0 1px 3px 0 inset;color:#000}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_label i,.xdsoft_datetimepicker.xdsoft_dark .xdsoft_prev,.xdsoft_datetimepicker.xdsoft_dark .xdsoft_next,.xdsoft_datetimepicker.xdsoft_dark .xdsoft_today_button{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAAeCAYAAADaW7vzAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QUExQUUzOTA0M0UyMTFFNDlBM0FFQTJENTExRDVBODYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QUExQUUzOTE0M0UyMTFFNDlBM0FFQTJENTExRDVBODYiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpBQTFBRTM4RTQzRTIxMUU0OUEzQUVBMkQ1MTFENUE4NiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpBQTFBRTM4RjQzRTIxMUU0OUEzQUVBMkQ1MTFENUE4NiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pp0VxGEAAAIASURBVHja7JrNSgMxEMebtgh+3MSLr1T1Xn2CHoSKB08+QmR8Bx9A8e7RixdB9CKCoNdexIugxFlJa7rNZneTbLIpM/CnNLsdMvNjM8l0mRCiQ9Ye61IKCAgZAUnH+mU3MMZaHYChBnJUDzWOFZdVfc5+ZFLbrWDeXPwbxIqrLLfaeS0hEBVGIRQCEiZoHQwtlGSByCCdYBl8g8egTTAWoKQMRBRBcZxYlhzhKegqMOageErsCHVkk3hXIFooDgHB1KkHIHVgzKB4ADJQ/A1jAFmAYhkQqA5TOBtocrKrgXwQA8gcFIuAIO8sQSA7hidvPwaQGZSaAYHOUWJABhWWw2EMIH9QagQERU4SArJXo0ZZL18uvaxejXt/Em8xjVBXmvFr1KVm/AJ10tRe2XnraNqaJvKE3KHuUbfK1E+VHB0q40/y3sdQSxY4FHWeKJCunP8UyDdqJZenT3ntVV5jIYCAh20vT7ioP8tpf6E2lfEMwERe+whV1MHjwZB7PBiCxcGQWwKZKD62lfGNnP/1poFAA60T7rF1UgcKd2id3KDeUS+oLWV8DfWAepOfq00CgQabi9zjcgJVYVD7PVzQUAUGAQkbNJTBICDhgwYTjDYD6XeW08ZKh+A4pYkzenOxXUbvZcWz7E8ykRMnIHGX1XPl+1m2vPYpL+2qdb8CDAARlKFEz/ZVkAAAAABJRU5ErkJggg==)}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar td,.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar th{background:#0a0a0a;border:1px solid #222;color:#999}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar th{background:#0e0e0e}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar td.xdsoft_today{color:#c50}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar td.xdsoft_highlighted_default{background:#ffe9d2;box-shadow:#ffb871 0 1px 4px 0 inset;color:#000}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar td.xdsoft_highlighted_mint{background:#c1ffc9;box-shadow:#00dd1c 0 1px 4px 0 inset;color:#000}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar td.xdsoft_default,.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar td.xdsoft_current,.xdsoft_datetimepicker.xdsoft_dark .xdsoft_timepicker .xdsoft_time_box>div>div.xdsoft_current{background:#c50;box-shadow:#b03e00 0 1px 3px 0 inset;color:#000}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar td:hover,.xdsoft_datetimepicker.xdsoft_dark .xdsoft_timepicker .xdsoft_time_box>div>div:hover{color:#000 !important;background:#007fff !important}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar th{color:#666}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_copyright{color:#333 !important}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_copyright a{color:#111 !important}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_copyright a:hover{color:#555 !important}.xdsoft_dark .xdsoft_time_box{border:1px solid #333}.xdsoft_dark .xdsoft_scrollbar>.xdsoft_scroller{background:#333 !important}.xdsoft_datetimepicker .xdsoft_save_selected{display:block;border:1px solid #ddd !important;margin-top:5px;width:100%;color:#454551;font-size:13px}.xdsoft_datetimepicker .blue-gradient-button{font-family:"museo-sans","Book Antiqua",sans-serif;font-size:12px;font-weight:300;color:#82878c;height:28px;position:relative;padding:4px 17px 4px 33px;border:1px solid #d7d8da;background:-moz-linear-gradient(top,#fff 0,#f4f8fa 73%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#fff),color-stop(73%,#f4f8fa));background:-webkit-linear-gradient(top,#fff 0,#f4f8fa 73%);background:-o-linear-gradient(top,#fff 0,#f4f8fa 73%);background:-ms-linear-gradient(top,#fff 0,#f4f8fa 73%);background:linear-gradient(to bottom,#fff 0,#f4f8fa 73%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff',endColorstr='#f4f8fa',GradientType=0)}.xdsoft_datetimepicker .blue-gradient-button:hover,.xdsoft_datetimepicker .blue-gradient-button:focus,.xdsoft_datetimepicker .blue-gradient-button:hover span,.xdsoft_datetimepicker .blue-gradient-button:focus span{color:#454551;background:-moz-linear-gradient(top,#f4f8fa 0,#FFF 73%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#f4f8fa),color-stop(73%,#FFF));background:-webkit-linear-gradient(top,#f4f8fa 0,#FFF 73%);background:-o-linear-gradient(top,#f4f8fa 0,#FFF 73%);background:-ms-linear-gradient(top,#f4f8fa 0,#FFF 73%);background:linear-gradient(to bottom,#f4f8fa 0,#FFF 73%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f4f8fa',endColorstr='#FFF',GradientType=0)}
diff --git a/bl-kernel/admin/themes/booty/css/open-iconic-bootstrap.min.css b/bl-kernel/admin/themes/booty/css/open-iconic-bootstrap.min.css
new file mode 100755
index 00000000..0ac996dd
--- /dev/null
+++ b/bl-kernel/admin/themes/booty/css/open-iconic-bootstrap.min.css
@@ -0,0 +1 @@
+@font-face{font-family:Icons;src:url(./fonts/open-iconic.eot);src:url(./fonts/open-iconic.eot?#iconic-sm) format('embedded-opentype'),url(./fonts/open-iconic.woff) format('woff'),url(./fonts/open-iconic.ttf) format('truetype'),url(./fonts/open-iconic.otf) format('opentype'),url(./fonts/open-iconic.svg#iconic-sm) format('svg');font-weight:400;font-style:normal}.oi{position:relative;top:1px;display:inline-block;speak:none;font-family:Icons;font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.oi:empty:before{width:1em;text-align:center;box-sizing:content-box}.oi.oi-align-center:before{text-align:center}.oi.oi-align-left:before{text-align:left}.oi.oi-align-right:before{text-align:right}.oi.oi-flip-horizontal:before{-webkit-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scale(-1,1)}.oi.oi-flip-vertical:before{-webkit-transform:scale(1,-1);-ms-transform:scale(-1,1);transform:scale(1,-1)}.oi.oi-flip-horizontal-vertical:before{-webkit-transform:scale(-1,-1);-ms-transform:scale(-1,1);transform:scale(-1,-1)}.oi-account-login:before{content:'\e000'}.oi-account-logout:before{content:'\e001'}.oi-action-redo:before{content:'\e002'}.oi-action-undo:before{content:'\e003'}.oi-align-center:before{content:'\e004'}.oi-align-left:before{content:'\e005'}.oi-align-right:before{content:'\e006'}.oi-aperture:before{content:'\e007'}.oi-arrow-bottom:before{content:'\e008'}.oi-arrow-circle-bottom:before{content:'\e009'}.oi-arrow-circle-left:before{content:'\e00a'}.oi-arrow-circle-right:before{content:'\e00b'}.oi-arrow-circle-top:before{content:'\e00c'}.oi-arrow-left:before{content:'\e00d'}.oi-arrow-right:before{content:'\e00e'}.oi-arrow-thick-bottom:before{content:'\e00f'}.oi-arrow-thick-left:before{content:'\e010'}.oi-arrow-thick-right:before{content:'\e011'}.oi-arrow-thick-top:before{content:'\e012'}.oi-arrow-top:before{content:'\e013'}.oi-audio-spectrum:before{content:'\e014'}.oi-audio:before{content:'\e015'}.oi-badge:before{content:'\e016'}.oi-ban:before{content:'\e017'}.oi-bar-chart:before{content:'\e018'}.oi-basket:before{content:'\e019'}.oi-battery-empty:before{content:'\e01a'}.oi-battery-full:before{content:'\e01b'}.oi-beaker:before{content:'\e01c'}.oi-bell:before{content:'\e01d'}.oi-bluetooth:before{content:'\e01e'}.oi-bold:before{content:'\e01f'}.oi-bolt:before{content:'\e020'}.oi-book:before{content:'\e021'}.oi-bookmark:before{content:'\e022'}.oi-box:before{content:'\e023'}.oi-briefcase:before{content:'\e024'}.oi-british-pound:before{content:'\e025'}.oi-browser:before{content:'\e026'}.oi-brush:before{content:'\e027'}.oi-bug:before{content:'\e028'}.oi-bullhorn:before{content:'\e029'}.oi-calculator:before{content:'\e02a'}.oi-calendar:before{content:'\e02b'}.oi-camera-slr:before{content:'\e02c'}.oi-caret-bottom:before{content:'\e02d'}.oi-caret-left:before{content:'\e02e'}.oi-caret-right:before{content:'\e02f'}.oi-caret-top:before{content:'\e030'}.oi-cart:before{content:'\e031'}.oi-chat:before{content:'\e032'}.oi-check:before{content:'\e033'}.oi-chevron-bottom:before{content:'\e034'}.oi-chevron-left:before{content:'\e035'}.oi-chevron-right:before{content:'\e036'}.oi-chevron-top:before{content:'\e037'}.oi-circle-check:before{content:'\e038'}.oi-circle-x:before{content:'\e039'}.oi-clipboard:before{content:'\e03a'}.oi-clock:before{content:'\e03b'}.oi-cloud-download:before{content:'\e03c'}.oi-cloud-upload:before{content:'\e03d'}.oi-cloud:before{content:'\e03e'}.oi-cloudy:before{content:'\e03f'}.oi-code:before{content:'\e040'}.oi-cog:before{content:'\e041'}.oi-collapse-down:before{content:'\e042'}.oi-collapse-left:before{content:'\e043'}.oi-collapse-right:before{content:'\e044'}.oi-collapse-up:before{content:'\e045'}.oi-command:before{content:'\e046'}.oi-comment-square:before{content:'\e047'}.oi-compass:before{content:'\e048'}.oi-contrast:before{content:'\e049'}.oi-copywriting:before{content:'\e04a'}.oi-credit-card:before{content:'\e04b'}.oi-crop:before{content:'\e04c'}.oi-dashboard:before{content:'\e04d'}.oi-data-transfer-download:before{content:'\e04e'}.oi-data-transfer-upload:before{content:'\e04f'}.oi-delete:before{content:'\e050'}.oi-dial:before{content:'\e051'}.oi-document:before{content:'\e052'}.oi-dollar:before{content:'\e053'}.oi-double-quote-sans-left:before{content:'\e054'}.oi-double-quote-sans-right:before{content:'\e055'}.oi-double-quote-serif-left:before{content:'\e056'}.oi-double-quote-serif-right:before{content:'\e057'}.oi-droplet:before{content:'\e058'}.oi-eject:before{content:'\e059'}.oi-elevator:before{content:'\e05a'}.oi-ellipses:before{content:'\e05b'}.oi-envelope-closed:before{content:'\e05c'}.oi-envelope-open:before{content:'\e05d'}.oi-euro:before{content:'\e05e'}.oi-excerpt:before{content:'\e05f'}.oi-expand-down:before{content:'\e060'}.oi-expand-left:before{content:'\e061'}.oi-expand-right:before{content:'\e062'}.oi-expand-up:before{content:'\e063'}.oi-external-link:before{content:'\e064'}.oi-eye:before{content:'\e065'}.oi-eyedropper:before{content:'\e066'}.oi-file:before{content:'\e067'}.oi-fire:before{content:'\e068'}.oi-flag:before{content:'\e069'}.oi-flash:before{content:'\e06a'}.oi-folder:before{content:'\e06b'}.oi-fork:before{content:'\e06c'}.oi-fullscreen-enter:before{content:'\e06d'}.oi-fullscreen-exit:before{content:'\e06e'}.oi-globe:before{content:'\e06f'}.oi-graph:before{content:'\e070'}.oi-grid-four-up:before{content:'\e071'}.oi-grid-three-up:before{content:'\e072'}.oi-grid-two-up:before{content:'\e073'}.oi-hard-drive:before{content:'\e074'}.oi-header:before{content:'\e075'}.oi-headphones:before{content:'\e076'}.oi-heart:before{content:'\e077'}.oi-home:before{content:'\e078'}.oi-image:before{content:'\e079'}.oi-inbox:before{content:'\e07a'}.oi-infinity:before{content:'\e07b'}.oi-info:before{content:'\e07c'}.oi-italic:before{content:'\e07d'}.oi-justify-center:before{content:'\e07e'}.oi-justify-left:before{content:'\e07f'}.oi-justify-right:before{content:'\e080'}.oi-key:before{content:'\e081'}.oi-laptop:before{content:'\e082'}.oi-layers:before{content:'\e083'}.oi-lightbulb:before{content:'\e084'}.oi-link-broken:before{content:'\e085'}.oi-link-intact:before{content:'\e086'}.oi-list-rich:before{content:'\e087'}.oi-list:before{content:'\e088'}.oi-location:before{content:'\e089'}.oi-lock-locked:before{content:'\e08a'}.oi-lock-unlocked:before{content:'\e08b'}.oi-loop-circular:before{content:'\e08c'}.oi-loop-square:before{content:'\e08d'}.oi-loop:before{content:'\e08e'}.oi-magnifying-glass:before{content:'\e08f'}.oi-map-marker:before{content:'\e090'}.oi-map:before{content:'\e091'}.oi-media-pause:before{content:'\e092'}.oi-media-play:before{content:'\e093'}.oi-media-record:before{content:'\e094'}.oi-media-skip-backward:before{content:'\e095'}.oi-media-skip-forward:before{content:'\e096'}.oi-media-step-backward:before{content:'\e097'}.oi-media-step-forward:before{content:'\e098'}.oi-media-stop:before{content:'\e099'}.oi-medical-cross:before{content:'\e09a'}.oi-menu:before{content:'\e09b'}.oi-microphone:before{content:'\e09c'}.oi-minus:before{content:'\e09d'}.oi-monitor:before{content:'\e09e'}.oi-moon:before{content:'\e09f'}.oi-move:before{content:'\e0a0'}.oi-musical-note:before{content:'\e0a1'}.oi-paperclip:before{content:'\e0a2'}.oi-pencil:before{content:'\e0a3'}.oi-people:before{content:'\e0a4'}.oi-person:before{content:'\e0a5'}.oi-phone:before{content:'\e0a6'}.oi-pie-chart:before{content:'\e0a7'}.oi-pin:before{content:'\e0a8'}.oi-play-circle:before{content:'\e0a9'}.oi-plus:before{content:'\e0aa'}.oi-power-standby:before{content:'\e0ab'}.oi-print:before{content:'\e0ac'}.oi-project:before{content:'\e0ad'}.oi-pulse:before{content:'\e0ae'}.oi-puzzle-piece:before{content:'\e0af'}.oi-question-mark:before{content:'\e0b0'}.oi-rain:before{content:'\e0b1'}.oi-random:before{content:'\e0b2'}.oi-reload:before{content:'\e0b3'}.oi-resize-both:before{content:'\e0b4'}.oi-resize-height:before{content:'\e0b5'}.oi-resize-width:before{content:'\e0b6'}.oi-rss-alt:before{content:'\e0b7'}.oi-rss:before{content:'\e0b8'}.oi-script:before{content:'\e0b9'}.oi-share-boxed:before{content:'\e0ba'}.oi-share:before{content:'\e0bb'}.oi-shield:before{content:'\e0bc'}.oi-signal:before{content:'\e0bd'}.oi-signpost:before{content:'\e0be'}.oi-sort-ascending:before{content:'\e0bf'}.oi-sort-descending:before{content:'\e0c0'}.oi-spreadsheet:before{content:'\e0c1'}.oi-star:before{content:'\e0c2'}.oi-sun:before{content:'\e0c3'}.oi-tablet:before{content:'\e0c4'}.oi-tag:before{content:'\e0c5'}.oi-tags:before{content:'\e0c6'}.oi-target:before{content:'\e0c7'}.oi-task:before{content:'\e0c8'}.oi-terminal:before{content:'\e0c9'}.oi-text:before{content:'\e0ca'}.oi-thumb-down:before{content:'\e0cb'}.oi-thumb-up:before{content:'\e0cc'}.oi-timer:before{content:'\e0cd'}.oi-transfer:before{content:'\e0ce'}.oi-trash:before{content:'\e0cf'}.oi-underline:before{content:'\e0d0'}.oi-vertical-align-bottom:before{content:'\e0d1'}.oi-vertical-align-center:before{content:'\e0d2'}.oi-vertical-align-top:before{content:'\e0d3'}.oi-video:before{content:'\e0d4'}.oi-volume-high:before{content:'\e0d5'}.oi-volume-low:before{content:'\e0d6'}.oi-volume-off:before{content:'\e0d7'}.oi-warning:before{content:'\e0d8'}.oi-wifi:before{content:'\e0d9'}.oi-wrench:before{content:'\e0da'}.oi-x:before{content:'\e0db'}.oi-yen:before{content:'\e0dc'}.oi-zoom-in:before{content:'\e0dd'}.oi-zoom-out:before{content:'\e0de'}
\ No newline at end of file
diff --git a/bl-kernel/admin/themes/booty/html/alert.php b/bl-kernel/admin/themes/booty/html/alert.php
new file mode 100644
index 00000000..fb7578af
--- /dev/null
+++ b/bl-kernel/admin/themes/booty/html/alert.php
@@ -0,0 +1,17 @@
+
+
+
diff --git a/bl-kernel/admin/themes/booty/html/media.php b/bl-kernel/admin/themes/booty/html/media.php
new file mode 100644
index 00000000..e2bab522
--- /dev/null
+++ b/bl-kernel/admin/themes/booty/html/media.php
@@ -0,0 +1,173 @@
+
+
+
+
+
diff --git a/bl-kernel/admin/themes/booty/html/navbar.php b/bl-kernel/admin/themes/booty/html/navbar.php
new file mode 100644
index 00000000..ac37cd87
--- /dev/null
+++ b/bl-kernel/admin/themes/booty/html/navbar.php
@@ -0,0 +1,54 @@
+
+
+
diff --git a/bl-kernel/admin/themes/booty/html/sidebar.php b/bl-kernel/admin/themes/booty/html/sidebar.php
new file mode 100644
index 00000000..bca9461a
--- /dev/null
+++ b/bl-kernel/admin/themes/booty/html/sidebar.php
@@ -0,0 +1,73 @@
+
+
diff --git a/bl-kernel/admin/themes/booty/html/user-logged.php b/bl-kernel/admin/themes/booty/html/user-logged.php
new file mode 100644
index 00000000..d969c19f
--- /dev/null
+++ b/bl-kernel/admin/themes/booty/html/user-logged.php
@@ -0,0 +1,11 @@
+
+
+
+
+
diff --git a/bl-kernel/admin/themes/booty/img/default.svg b/bl-kernel/admin/themes/booty/img/default.svg
new file mode 100644
index 00000000..155e5275
--- /dev/null
+++ b/bl-kernel/admin/themes/booty/img/default.svg
@@ -0,0 +1 @@
+missing-image-4x3
\ No newline at end of file
diff --git a/bl-kernel/admin/themes/default/img/favicon.png b/bl-kernel/admin/themes/booty/img/favicon.png
similarity index 100%
rename from bl-kernel/admin/themes/default/img/favicon.png
rename to bl-kernel/admin/themes/booty/img/favicon.png
diff --git a/bl-kernel/admin/themes/booty/img/logo.svg b/bl-kernel/admin/themes/booty/img/logo.svg
new file mode 100644
index 00000000..183e0ff1
--- /dev/null
+++ b/bl-kernel/admin/themes/booty/img/logo.svg
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bl-kernel/admin/themes/booty/index.php b/bl-kernel/admin/themes/booty/index.php
new file mode 100644
index 00000000..3a24714a
--- /dev/null
+++ b/bl-kernel/admin/themes/booty/index.php
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+'.PHP_EOL;
+ include(PATH_CORE_JS.'variables.php');
+ echo ''.PHP_EOL;
+
+ echo ''.PHP_EOL;
+?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ '.$L->g('Page not found').'';
+ echo '
'.$L->g('Choose a page from the sidebar.').' ';
+ }
+ ?>
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bl-kernel/admin/themes/booty/init.php b/bl-kernel/admin/themes/booty/init.php
new file mode 100644
index 00000000..01e70858
--- /dev/null
+++ b/bl-kernel/admin/themes/booty/init.php
@@ -0,0 +1,392 @@
+
+
+
+
+
$modalTitle
+
$modalText
+
+
+
+
+
+EOF;
+ }
+
+ public static function link($args)
+ {
+ $options = 'href="'.$args['href'].'"';
+ if (isset($args['class'])) {
+ $options .= ' class="'.$args['class'].'"';
+ }
+ if (isset($args['target'])) {
+ $options .= ' target="'.$args['target'].'"';
+ }
+
+ if (isset($args['icon'])) {
+ return ' '.$args['title'].' ';
+ }
+
+ return ''.$args['title'].' ';
+ }
+
+ public static function pageTitle($args)
+ {
+ $icon = $args['icon'];
+ $title = $args['title'];
+return <<
+ $title
+
+EOF;
+ }
+
+ public static function formOpen($args)
+ {
+ $class = empty($args['class'])?'':'class="'.$args['class'].'"';
+ $id = empty($args['id'])?'':'id="'.$args['id'].'"';
+ $enctype = empty($args['enctype'])?'':'enctype="'.$args['enctype'].'"';
+ $action = empty($args['action'])?'action=""':'action="'.$args['action'].'"';
+ $method = empty($args['method'])?'method="post"':'method="'.$args['method'].'"';
+
+return <<
+EOF;
+ }
+
+ public static function formClose()
+ {
+return <<
+
+EOF;
+ }
+
+ public static function formTitle($args)
+ {
+ $title = $args['title'];
+return <<$title
+EOF;
+ }
+
+ public static function formInputTextBlock($args)
+ {
+ $id = 'js'.$args['name'];
+ if (isset($args['id'])) {
+ $id = $args['id'];
+ }
+
+ $class = 'form-control';
+ if (isset($args['class'])) {
+ $class = $class.' '.$args['class'];
+ }
+
+ $html = '';
+
+ if (isset($args['label'])) {
+ $html .= ''.$args['label'].' ';
+ }
+
+ $html .= ' ';
+
+ if (isset($args['tip'])) {
+ $html .= ''.$args['tip'].' ';
+ }
+
+ $html .= '
';
+
+ return $html;
+ }
+
+ public static function formInputFile($args)
+ {
+ $id = 'js'.$args['name'];
+ if (isset($args['id'])) {
+ $id = $args['id'];
+ }
+
+ $class = 'custom-file';
+ if (isset($args['class'])) {
+ $class = $class.' '.$args['class'];
+ }
+
+ $html = '';
+ $html .= ' ';
+ $html .= ''.$args['label'].' ';
+ $html .= '
';
+
+ return $html;
+ }
+
+ public static function formTextarea($args)
+ {
+ $id = 'js'.$args['name'];
+ if (isset($args['id'])) {
+ $id = $args['id'];
+ }
+
+ $class = 'form-control';
+ if (isset($args['class'])) {
+ $class = $class.' '.$args['class'];
+ }
+
+ $html = '';
+
+ return $html;
+ }
+
+ public static function formTextareaBlock($args)
+ {
+ $id = 'js'.$args['name'];
+ if (isset($args['id'])) {
+ $id = $args['id'];
+ }
+
+ $class = 'form-control';
+ if (!empty($args['class'])) {
+ $class = $class.' '.$args['class'];
+ }
+
+ $html = '';
+ if (!empty($args['label'])) {
+ $html .= ''.$args['label'].' ';
+ }
+
+ $html .= '';
+ if (!empty($args['tip'])) {
+ $html .= ''.$args['tip'].' ';
+ }
+ $html .= '
';
+
+ return $html;
+ }
+
+ public static function formInputGroupText($args)
+ {
+ $label = $args['label'];
+ $labelInside = $args['labelInside'];
+ $tip = $args['tip'];
+ $value = $args['value'];
+ $name = $args['name'];
+ $id = 'js'.$name;
+ if (isset($args['id'])) {
+ $id = $args['id'];
+ }
+ $disabled = isset($args['disabled'])?'disabled':'';
+
+return <<
+ $label
+
+ $tip
+
+EOF;
+ }
+
+ public static function formInputText($args)
+ {
+ $label = isset($args['label'])?$args['label']:'';
+ $placeholder = isset($args['placeholder'])?$args['placeholder']:'';
+ $tip = isset($args['tip'])?$args['tip']:' ';
+ $value = isset($args['value'])?$args['value']:'';
+ $name = $args['name'];
+ $id = 'js'.$name;
+ if (isset($args['id'])) {
+ $id = $args['id'];
+ }
+ $disabled = empty($args['disabled'])?'':'disabled';
+
+ $class = 'form-control';
+ if (isset($args['class'])) {
+ $class = $class.' '.$args['class'];
+ }
+
+ $type = 'text';
+ if (isset($args['type'])) {
+ $type = $args['type'];
+ }
+
+return <<
+ $label
+
+
+ $tip
+
+
+EOF;
+ }
+
+ public static function formCheckbox($args)
+ {
+ $label = isset($args['label'])?$args['label']:'';
+ $labelForCheckbox = isset($args['labelForCheckbox'])?$args['labelForCheckbox']:'';
+ $placeholder = isset($args['placeholder'])?$args['placeholder']:'';
+ $tip = isset($args['tip'])?$args['tip']:' ';
+ $value = isset($args['value'])?$args['value']:'';
+ $name = $args['name'];
+ $id = 'js'.$name;
+ if (isset($args['id'])) {
+ $id = $args['id'];
+ }
+ $disabled = isset($args['disabled'])?'disabled':'';
+
+ $class = 'form-group row';
+ if (isset($args['class'])) {
+ $class = $class.' '.$args['class'];
+ }
+
+ $type = 'text';
+ if (isset($args['type'])) {
+ $type = $args['type'];
+ }
+
+ $checked = $args['checked']?'checked':'';
+
+return <<
+ $label
+
+
+
+ $labelForCheckbox
+ $tip
+
+
+
+EOF;
+ }
+
+ public static function formSelect($args)
+ {
+ $id = 'js'.$args['name'];
+ if (isset($args['id'])) {
+ $id = $args['id'];
+ }
+
+ $class = 'custom-select';
+ if (isset($args['class'])) {
+ $class = $class.' '.$args['class'];
+ }
+
+ $html = '';
+
+ return $html;
+ }
+
+ public static function formSelectBlock($args)
+ {
+ $id = 'js'.$args['name'];
+ if (isset($args['id'])) {
+ $id = $args['id'];
+ }
+
+ $class = 'custom-select';
+ if (!empty($args['class'])) {
+ $class = $class.' '.$args['class'];
+ }
+
+ $html = '';
+
+ if (!empty($args['label'])) {
+ $html .= ''.$args['label'].' ';
+ }
+
+ $html .= '';
+ if (!empty($args['emptyOption'])) {
+ $html .= ''.$args['emptyOption'].' ';
+ }
+ foreach ($args['options'] as $key=>$value) {
+ $html .= ''.$value.' ';
+ }
+ $html .= ' ';
+ if (!empty($args['tip'])) {
+ $html .= ''.$args['tip'].' ';
+ }
+ $html .= '
';
+
+ return $html;
+ }
+
+ public static function formInputHidden($args)
+ {
+ return ' ';
+ }
+
+ public static function alert($args)
+ {
+ $class = 'alert';
+ if (!empty($args['class'])) {
+ $class = $class.' '.$args['class'];
+ }
+
+ $text = $args['text'];
+
+return <<$text
+EOF;
+ }
+}
diff --git a/bl-kernel/admin/themes/booty/js/jquery-auto-complete.min.js b/bl-kernel/admin/themes/booty/js/jquery-auto-complete.min.js
new file mode 100755
index 00000000..c6deb2f2
--- /dev/null
+++ b/bl-kernel/admin/themes/booty/js/jquery-auto-complete.min.js
@@ -0,0 +1,3 @@
+// jQuery autoComplete v1.0.7
+// https://github.com/Pixabay/jQuery-autoComplete
+!function(e){e.fn.autoComplete=function(t){var o=e.extend({},e.fn.autoComplete.defaults,t);return"string"==typeof t?(this.each(function(){var o=e(this);"destroy"==t&&(e(window).off("resize.autocomplete",o.updateSC),o.off("blur.autocomplete focus.autocomplete keydown.autocomplete keyup.autocomplete"),o.data("autocomplete")?o.attr("autocomplete",o.data("autocomplete")):o.removeAttr("autocomplete"),e(o.data("sc")).remove(),o.removeData("sc").removeData("autocomplete"))}),this):this.each(function(){function t(e){var t=s.val();if(s.cache[t]=e,e.length&&t.length>=o.minChars){for(var a="",c=0;c