diff --git a/.github/issue_template.md b/.github/issue_template.md index edd96871..e21c69f2 100644 --- a/.github/issue_template.md +++ b/.github/issue_template.md @@ -7,10 +7,13 @@ Complete here. ### Bludit version Complete here. +### Hosting or Webserver name +Complete here. + ### PHP version If you do not know delete this line. ### PHP logs If you do not know delete this line. -The default settings of the PHP Error Log file varies from OS to OS. The location of the error log file itself can be set manually in the php.ini file. On a Windows server, in IIS, it may be something like `error_log = C:\log_files\php_errors.log` in Linux it may be a value of `/var/log/php_errors.log`. +The default settings for the PHP error log file vary from operating system to system. The location of the error log file itself can be set manually in the php.ini file. On a Windows server, in IIS, it may be something like `error_log = C:\log_files\php_errors.log` in Linux it may be a value of `/var/log/php_errors.log`. diff --git a/.gitignore b/.gitignore index e57370ed..7db06cf5 100644 --- a/.gitignore +++ b/.gitignore @@ -30,4 +30,4 @@ bl-themes/small bl-themes/future-imperfect bl-themes/social-network Dockerfile -conf/* \ No newline at end of file +conf/* diff --git a/README.md b/README.md index e7a66cf0..2e137a22 100644 --- a/README.md +++ b/README.md @@ -39,5 +39,5 @@ PHPStan ------- https://phpstan.org/ ``` -docker run --rm -v $(pwd):/app ghcr.io/phpstan/phpstan:0.12.89 analyse -c /app/phpstan.neon /app +docker run --rm -v $(pwd):/app ghcr.io/phpstan/phpstan:0.12.96 analyse -c /app/phpstan.neon /app ``` \ No newline at end of file diff --git a/bl-kernel/abstract/dbjson.class.php b/bl-kernel/abstract/dbjson.class.php index da9f989c..70feeaa7 100644 --- a/bl-kernel/abstract/dbjson.class.php +++ b/bl-kernel/abstract/dbjson.class.php @@ -6,6 +6,7 @@ class dbJSON { public $dbBackup; public $file; public $firstLine; + protected $dbFields; // These fields are defined in the extended classes // $file, the JSON file. // $firstLine, TRUE if you want to remove the first line, FALSE otherwise @@ -101,7 +102,7 @@ class dbJSON { { // NULL is returned if the json cannot be decoded $decode = json_decode($data, true); - if ($decode===NULL) { + if ($decode===null) { Log::set(__METHOD__.LOG_SEP.'Error trying to read the JSON file: '.$this->file, LOG_TYPE_ERROR); return false; } diff --git a/bl-kernel/admin/themes/booty/css/99-lightmode.css b/bl-kernel/admin/themes/booty/css/99-lightmode.css index 29e586d8..23b8c0e6 100644 --- a/bl-kernel/admin/themes/booty/css/99-lightmode.css +++ b/bl-kernel/admin/themes/booty/css/99-lightmode.css @@ -30,11 +30,6 @@ a.nav-link:hover, border-color: #dee2e6; } -.list-group-item { - background-color: inherit; - border: 0 none; -} - .list-group-item a { text-decoration: none; } diff --git a/bl-kernel/admin/themes/booty/index.php b/bl-kernel/admin/themes/booty/index.php index 537d1c5a..732df4ad 100644 --- a/bl-kernel/admin/themes/booty/index.php +++ b/bl-kernel/admin/themes/booty/index.php @@ -14,6 +14,7 @@ keys() as $key) { try { $category = new Category($key); echo ''; - echo ''.$category->name().''; + echo ''.$category->name().''; echo ''.$category->description().''; echo ''.$category->permalink().''; echo ''; diff --git a/bl-kernel/admin/views/content.php b/bl-kernel/admin/views/content.php index 56c4ca58..90f0e6b1 100644 --- a/bl-kernel/admin/views/content.php +++ b/bl-kernel/admin/views/content.php @@ -134,7 +134,7 @@ function table($type) echo '
- ' . ($page->title() ? $page->title() : '' . $L->g('Empty title') . ' ') . ' + ' . ($page->title() ? $page->title() : '' . $L->g('Empty title') . ' ') . '
' . $L->g('View') . ' @@ -160,7 +160,7 @@ function table($type) echo '
- ' . ($child->title() ? $child->title() : '' . $L->g('Empty title') . ' ') . ' + ' . ($child->title() ? $child->title() : '' . $L->g('Empty title') . ' ') . '
' . $L->g('View') . ' @@ -188,7 +188,7 @@ function table($type) echo '
- ' . ($page->title() ? $page->title() : '' . $L->g('Empty title') . ' ') . ' + ' . ($page->title() ? $page->title() : '' . $L->g('Empty title') . ' ') . '
' . $L->g('View') . ' diff --git a/bl-kernel/admin/views/dashboard.php b/bl-kernel/admin/views/dashboard.php index ae2d7308..62f5d2c1 100644 --- a/bl-kernel/admin/views/dashboard.php +++ b/bl-kernel/admin/views/dashboard.php @@ -1,5 +1,7 @@ + + @@ -487,11 +530,9 @@ -
-
+
@@ -645,13 +653,13 @@
More options
diff --git a/bl-kernel/admin/views/editor/file-manager.php b/bl-kernel/admin/views/editor/file-manager.php index 4d3005f2..7a7ef149 100644 --- a/bl-kernel/admin/views/editor/file-manager.php +++ b/bl-kernel/admin/views/editor/file-manager.php @@ -104,9 +104,10 @@ } $.each(files, function(key, file) { + console.log(file); var row = '' + '' + - ' ' + + ' ' + '' + '' + file.filename + '' + '' + file.mime + '' + diff --git a/bl-kernel/admin/views/settings.php b/bl-kernel/admin/views/settings.php index b0796170..711d9b57 100644 --- a/bl-kernel/admin/views/settings.php +++ b/bl-kernel/admin/views/settings.php @@ -145,8 +145,45 @@ // Initlization for the view // ============================================================================ $(document).ready(function() { - // nothing here yet - // how do you hang your toilet paper ? over or under ? + $("#homepage").select2({ + placeholder: "Search for a page", + allowClear: true, + theme: "bootstrap-5", + minimumInputLength: 2, + ajax: { + url: HTML_PATH_ADMIN_ROOT+"ajax/get-published", + data: function (params) { + var query = { query: params.term } + return query; + }, + processResults: function (data) { + return data; + }, + escapeMarkup: function(markup) { + return markup; + } + } + }); + + $("#pageNotFound").select2({ + placeholder: "Search for a page", + allowClear: true, + theme: "bootstrap-5", + minimumInputLength: 2, + ajax: { + url: HTML_PATH_ADMIN_ROOT+"ajax/get-published", + data: function (params) { + var query = { query: params.term } + return query; + }, + processResults: function (data) { + return data; + }, + escapeMarkup: function(markup) { + return markup; + } + } + }); }); @@ -288,19 +325,37 @@ echo Bootstrap::formTitle(array('title' => $L->g('Predefined pages'))); + try { + $options = array(); + if (!empty($site->homepage())) { + $tmp = new Page($site->homepage()); + $options = array($site->homepage()=>$tmp->title()); + } + } catch (Exception $e) { + // continue + } echo Bootstrap::formSelect(array( 'name' => 'homepage', 'label' => $L->g('Homepage'), - 'options' => array(), // Complete via Ajax + 'options' => $options, // Complete via Ajax 'selected' => false, 'tip' => $L->g('Returning page for the main page'), 'data' => array('save' => 'true') )); + try { + $options = array(); + if (!empty($site->pageNotFound())) { + $tmp = new Page($site->pageNotFound()); + $options = array($site->pageNotFound()=>$tmp->title()); + } + } catch (Exception $e) { + // continue + } echo Bootstrap::formSelect(array( 'name' => 'pageNotFound', 'label' => $L->g('Page not found'), - 'options' => array(), // Complete via Ajax + 'options' => $options, // Complete via Ajax 'selected' => false, 'tip' => $L->g('Returning page when the page doesnt exist'), 'data' => array('save' => 'true') @@ -516,28 +571,54 @@
$L->g('Thumbnails'))); + echo Bootstrap::formTitle(array('title' => $L->g('Thumbnail small'))); echo Bootstrap::formInputText(array( - 'name' => 'thumbnailWidth', + 'name' => 'thumbnailSmallWidth', 'label' => $L->g('Width'), - 'value' => $site->thumbnailWidth(), + 'value' => $site->thumbnailSmallWidth(), 'tip' => $L->g('Thumbnail width in pixels'), 'data' => array('save' => 'true') )); echo Bootstrap::formInputText(array( - 'name' => 'thumbnailHeight', + 'name' => 'thumbnailSmallHeight', 'label' => $L->g('Height'), - 'value' => $site->thumbnailHeight(), + 'value' => $site->thumbnailSmallHeight(), 'tip' => $L->g('Thumbnail height in pixels'), 'data' => array('save' => 'true') )); echo Bootstrap::formInputText(array( - 'name' => 'thumbnailQuality', + 'name' => 'thumbnailSmallQuality', 'label' => $L->g('Quality'), - 'value' => $site->thumbnailQuality(), + 'value' => $site->thumbnailSmallQuality(), + 'tip' => $L->g('Thumbnail quality in percentage'), + 'data' => array('save' => 'true') + )); + + echo Bootstrap::formTitle(array('title' => $L->g('Thumbnail medium'))); + + echo Bootstrap::formInputText(array( + 'name' => 'thumbnailMediumWidth', + 'label' => $L->g('Width'), + 'value' => $site->thumbnailMediumWidth(), + 'tip' => $L->g('Thumbnail width in pixels'), + 'data' => array('save' => 'true') + )); + + echo Bootstrap::formInputText(array( + 'name' => 'thumbnailMediumHeight', + 'label' => $L->g('Height'), + 'value' => $site->thumbnailMediumHeight(), + 'tip' => $L->g('Thumbnail height in pixels'), + 'data' => array('save' => 'true') + )); + + echo Bootstrap::formInputText(array( + 'name' => 'thumbnailMediumQuality', + 'label' => $L->g('Quality'), + 'value' => $site->thumbnailMediumQuality(), 'tip' => $L->g('Thumbnail quality in percentage'), 'data' => array('save' => 'true') )); diff --git a/bl-kernel/admin/views/users.php b/bl-kernel/admin/views/users.php index 2c22672b..ddcb0d2a 100644 --- a/bl-kernel/admin/views/users.php +++ b/bl-kernel/admin/views/users.php @@ -52,7 +52,7 @@ foreach ($list as $username) { try { $user = new User($username); echo ''; - echo ''.$username.''; + echo ''.$username.''; echo ''.$user->nickname().''; echo ''.$user->email().''; echo ''.($user->enabled()?''.$L->g('Enabled').'':''.$L->g('Disabled').'').''; diff --git a/bl-kernel/ajax/get-published.php b/bl-kernel/ajax/get-published.php index d20e800a..782c036a 100644 --- a/bl-kernel/ajax/get-published.php +++ b/bl-kernel/ajax/get-published.php @@ -20,33 +20,31 @@ $query = isset($_GET['query']) ? Text::lowercase($_GET['query']) : false; $checkIsParent = empty($_GET['checkIsParent']) ? false : true; // ---------------------------------------------------------------------------- if ($query===false) { - ajaxResponse(1, 'Invalid query.'); + ajaxResponse(1, 'Invalid query.'); } $result = array(); $pagesKey = $pages->getDB(); foreach ($pagesKey as $pageKey) { - try { - $page = new Page($pageKey); - if ($page->isParent() || !$checkIsParent) { - // Check page status - if ($page->published() || $page->sticky() || $page->isStatic()) { - // Check if the query contains in the title - $lowerTitle = Text::lowercase($page->title()); - if (Text::stringContains($lowerTitle, $query)) { - $tmp = array('disabled'=>false); - $tmp['id'] = $page->key(); - $tmp['text'] = $page->title(); - $tmp['type'] = $page->type(); - array_push($result, $tmp); - } - } - } - } catch (Exception $e) { - // continue - } + try { + $page = new Page($pageKey); + if ($page->isParent() || !$checkIsParent) { + // Check page status + if ($page->published() || $page->sticky() || $page->isStatic()) { + // Check if the query contains in the title + $lowerTitle = Text::lowercase($page->title()); + if (Text::stringContains($lowerTitle, $query)) { + $tmp = array('disabled'=>false); + $tmp['id'] = $page->key(); + $tmp['text'] = $page->title(); + $tmp['type'] = $page->type(); + array_push($result, $tmp); + } + } + } + } catch (Exception $e) { + // continue + } } exit (json_encode(array('results'=>$result))); - -?> \ No newline at end of file diff --git a/bl-kernel/boot/init.php b/bl-kernel/boot/init.php index 122977c6..c02bf708 100644 --- a/bl-kernel/boot/init.php +++ b/bl-kernel/boot/init.php @@ -12,12 +12,12 @@ define('DEBUG_MODE', TRUE); define('DEBUG_TYPE', 'INFO'); // INFO, TRACE error_reporting(0); // Turn off all error reporting if (DEBUG_MODE) { - // Turn on all error reporting - ini_set("display_errors", 0); - ini_set('display_startup_errors',0); - ini_set("html_errors", 1); - ini_set('log_errors', 1); - error_reporting(E_ALL | E_STRICT | E_NOTICE); + // Turn on all error reporting + ini_set("display_errors", 0); + ini_set('display_startup_errors',0); + ini_set("html_errors", 1); + ini_set('log_errors', 1); + error_reporting(E_ALL | E_STRICT | E_NOTICE); } // PHP paths @@ -44,7 +44,6 @@ define('PATH_WORKSPACES', PATH_CONTENT.'workspaces'.DS); define('PATH_UPLOADS_PAGES', PATH_UPLOADS.'pages'.DS); define('PATH_UPLOADS_PROFILES', PATH_UPLOADS.'profiles'.DS); -define('PATH_UPLOADS_THUMBNAILS',PATH_UPLOADS.'thumbnails'.DS); define('PATH_ADMIN', PATH_KERNEL.'admin'.DS); define('PATH_ADMIN_THEMES', PATH_ADMIN.'themes'.DS); @@ -116,7 +115,7 @@ include(PATH_HELPERS.'bootstrap.class.php'); include(PATH_HELPERS.'html.class.php'); if (file_exists(PATH_KERNEL.'bludit.pro.php')) { - include(PATH_KERNEL.'bludit.pro.php'); + include(PATH_KERNEL.'bludit.pro.php'); } // Objects @@ -138,26 +137,26 @@ $syslog = new Syslog(); $base = ''; if (!empty($_SERVER['DOCUMENT_ROOT']) && !empty($_SERVER['SCRIPT_NAME']) && empty($base)) { - $base = str_replace($_SERVER['DOCUMENT_ROOT'], '', $_SERVER['SCRIPT_NAME']); - $base = dirname($base); + $base = str_replace($_SERVER['DOCUMENT_ROOT'], '', $_SERVER['SCRIPT_NAME']); + $base = dirname($base); } elseif (empty($base)) { - $base = empty( $_SERVER['SCRIPT_NAME'] ) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME']; - $base = dirname($base); + $base = empty( $_SERVER['SCRIPT_NAME'] ) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME']; + $base = dirname($base); } if (strpos($_SERVER['REQUEST_URI'], $base)!==0) { - $base = '/'; + $base = '/'; } elseif ($base!=DS) { - $base = trim($base, '/'); - $base = '/'.$base.'/'; + $base = trim($base, '/'); + $base = '/'.$base.'/'; } else { - // Workaround for Windows Web Servers - $base = '/'; + // Workaround for Windows Web Servers + $base = '/'; } -define('HTML_PATH_ROOT', $base); -define('HTML_PATH_THEMES', HTML_PATH_ROOT.'bl-themes/'); -define('HTML_PATH_THEME', HTML_PATH_THEMES.$site->theme().'/'); +define('HTML_PATH_ROOT', $base); +define('HTML_PATH_THEMES', HTML_PATH_ROOT.'bl-themes/'); +define('HTML_PATH_THEME', HTML_PATH_THEMES.$site->theme().'/'); define('HTML_PATH_THEME_CSS', HTML_PATH_THEME.'css/'); define('HTML_PATH_THEME_JS', HTML_PATH_THEME.'js/'); define('HTML_PATH_THEME_IMG', HTML_PATH_THEME.'img/'); @@ -165,16 +164,15 @@ define('HTML_PATH_ADMIN_ROOT', HTML_PATH_ROOT.ADMIN_URI_FILTER.'/'); define('HTML_PATH_ADMIN_THEME', HTML_PATH_ROOT.'bl-kernel/admin/themes/'.$site->adminTheme().'/'); define('HTML_PATH_ADMIN_THEME_JS', HTML_PATH_ADMIN_THEME.'js/'); define('HTML_PATH_ADMIN_THEME_CSS', HTML_PATH_ADMIN_THEME.'css/'); -define('HTML_PATH_CORE_JS', HTML_PATH_ROOT.'bl-kernel/js/'); +define('HTML_PATH_CORE_JS', HTML_PATH_ROOT.'bl-kernel/js/'); define('HTML_PATH_CORE_VENDORS', HTML_PATH_ROOT.'bl-kernel/vendors/'); define('HTML_PATH_CORE_CSS', HTML_PATH_ROOT.'bl-kernel/css/'); define('HTML_PATH_CORE_IMG', HTML_PATH_ROOT.'bl-kernel/img/'); -define('HTML_PATH_CONTENT', HTML_PATH_ROOT.'bl-content/'); -define('HTML_PATH_UPLOADS', HTML_PATH_ROOT.'bl-content/uploads/'); +define('HTML_PATH_CONTENT', HTML_PATH_ROOT.'bl-content/'); +define('HTML_PATH_UPLOADS', HTML_PATH_ROOT.'bl-content/uploads/'); define('HTML_PATH_UPLOADS_PAGES', HTML_PATH_UPLOADS.'pages/'); -define('HTML_PATH_UPLOADS_PROFILES', HTML_PATH_UPLOADS.'profiles/'); -define('HTML_PATH_UPLOADS_THUMBNAILS', HTML_PATH_UPLOADS.'thumbnails/'); -define('HTML_PATH_PLUGINS', HTML_PATH_ROOT.'bl-plugins/'); +define('HTML_PATH_UPLOADS_PROFILES',HTML_PATH_UPLOADS.'profiles/'); +define('HTML_PATH_PLUGINS', HTML_PATH_ROOT.'bl-plugins/'); // --- Objects with dependency --- $language = new Language( $site->language() ); @@ -236,7 +234,6 @@ define('DOMAIN_ADMIN_THEME_JS', DOMAIN.HTML_PATH_ADMIN_THEME_JS); define('DOMAIN_UPLOADS', DOMAIN.HTML_PATH_UPLOADS); define('DOMAIN_UPLOADS_PAGES', DOMAIN.HTML_PATH_UPLOADS_PAGES); define('DOMAIN_UPLOADS_PROFILES', DOMAIN.HTML_PATH_UPLOADS_PROFILES); -define('DOMAIN_UPLOADS_THUMBNAILS', DOMAIN.HTML_PATH_UPLOADS_THUMBNAILS); define('DOMAIN_PLUGINS', DOMAIN.HTML_PATH_PLUGINS); define('DOMAIN_CONTENT', DOMAIN.HTML_PATH_CONTENT); diff --git a/bl-kernel/boot/rules/60.plugins.php b/bl-kernel/boot/rules/60.plugins.php index 5d4d61ea..4826432e 100644 --- a/bl-kernel/boot/rules/60.plugins.php +++ b/bl-kernel/boot/rules/60.plugins.php @@ -5,42 +5,42 @@ // ============================================================================ $plugins = array( - 'siteHead'=>array(), - 'siteBodyBegin'=>array(), - 'siteBodyEnd'=>array(), - 'siteSidebar'=>array(), - 'beforeSiteLoad'=>array(), - 'afterSiteLoad'=>array(), + 'siteHead' => array(), + 'siteBodyBegin' => array(), + 'siteBodyEnd' => array(), + 'siteSidebar' => array(), + 'beforeSiteLoad' => array(), + 'afterSiteLoad' => array(), - 'pageBegin'=>array(), - 'pageEnd'=>array(), + 'pageBegin' => array(), + 'pageEnd' => array(), - 'beforeAdminLoad'=>array(), - 'afterAdminLoad'=>array(), - 'adminHead'=>array(), - 'adminBodyBegin'=>array(), - 'adminBodyEnd'=>array(), - 'adminSidebar'=>array(), - 'adminContentSidebar'=>array(), - 'dashboard'=>array(), + 'beforeAdminLoad' => array(), + 'afterAdminLoad' => array(), + 'adminHead' => array(), + 'adminBodyBegin' => array(), + 'adminBodyEnd' => array(), + 'adminSidebar' => array(), + 'adminContentSidebar' => array(), + 'dashboard' => array(), - 'beforeAll'=>array(), - 'afterAll'=>array(), + 'beforeAll' => array(), + 'afterAll' => array(), - 'paginator'=>array(), + 'paginator' => array(), - 'beforePageModify'=>array(), - 'beforePageDelete'=>array(), + 'beforePageModify' => array(), + 'beforePageDelete' => array(), - 'afterPageCreate'=>array(), - 'afterPageModify'=>array(), - 'afterPageDelete'=>array(), + 'afterPageCreate' => array(), + 'afterPageModify' => array(), + 'afterPageDelete' => array(), - 'loginHead'=>array(), - 'loginBodyBegin'=>array(), - 'loginBodyEnd'=>array(), + 'loginHead' => array(), + 'loginBodyBegin' => array(), + 'loginBodyEnd' => array(), - 'all'=>array() // $plugins['all'] keep installed and not installed plugins + 'all' => array() // $plugins['all'] keep installed and not installed plugins ); // This array has only the installed plugins @@ -69,8 +69,8 @@ function buildPlugins() // Load plugins clasess $list = Filesystem::listDirectories(PATH_PLUGINS); foreach ($list as $pluginPath) { - if (file_exists($pluginPath.DS.'plugin.php')) { - include_once($pluginPath.DS.'plugin.php'); + if (file_exists($pluginPath . DS . 'plugin.php')) { + include_once($pluginPath . DS . 'plugin.php'); } } @@ -81,17 +81,17 @@ function buildPlugins() $Plugin = new $pluginClass; // Check if the plugin is translated - $languageFilename = PATH_PLUGINS.$Plugin->directoryName().DS.'languages'.DS.$site->language().'.json'; + $languageFilename = PATH_PLUGINS . $Plugin->directoryName() . DS . 'languages' . DS . $site->language() . '.json'; if (!Sanitize::pathFile($languageFilename)) { - $languageFilename = PATH_PLUGINS.$Plugin->directoryName().DS.'languages'.DS.DEFAULT_LANGUAGE_FILE; + $languageFilename = PATH_PLUGINS . $Plugin->directoryName() . DS . 'languages' . DS . DEFAULT_LANGUAGE_FILE; } $database = file_get_contents($languageFilename); $database = json_decode($database, true); // Set name and description from the language file - $Plugin->setMetadata('name',$database['plugin-data']['name']); - $Plugin->setMetadata('description',$database['plugin-data']['description']); + $Plugin->setMetadata('name', $database['plugin-data']['name']); + $Plugin->setMetadata('description', $database['plugin-data']['description']); // Remove name and description from the language and includes new words to the global language dictionary unset($database['plugin-data']); @@ -117,7 +117,7 @@ function buildPlugins() } // Insert the plugin into the hooks - foreach ($pluginsHooks as $hook=>$value) { + foreach ($pluginsHooks as $hook => $value) { if (method_exists($Plugin, $hook)) { array_push($plugins[$hook], $Plugin); } @@ -125,14 +125,18 @@ function buildPlugins() } // Sort the plugins by the position for the site sidebar - uasort($plugins['siteSidebar'], function ($a, $b) { - return $a->position()>$b->position(); + uasort( + $plugins['siteSidebar'], + function ($a, $b) { + return $a->position() <=> $b->position(); } ); // Sort the plugins by the position for the dashboard - uasort($plugins['dashboard'], function ($a, $b) { - return $a->position()>$b->position(); + uasort( + $plugins['dashboard'], + function ($a, $b) { + return $a->position() <=> $b->position(); } ); } diff --git a/bl-kernel/functions.php b/bl-kernel/functions.php index 072589ee..1d8267a8 100644 --- a/bl-kernel/functions.php +++ b/bl-kernel/functions.php @@ -13,90 +13,90 @@ /** * Create a new page. === bludit v4 - * @param array $args All supported keys are defined in the class pages.class.php variable $dbFields - * @return string|bool Returns the page key on successful create, FALSE otherwise + * @param array $args All supported parameters are defined in the class pages.class.php, variable $dbFields + * @return string|bool Returns the page key on successful create, FALSE otherwise */ function createPage($args) { - global $pages; - global $syslog; + global $pages; + global $syslog; - // The user is always the one logged - $args['username'] = Session::get('username'); - if (empty($args['username'])) { - Log::set(__FUNCTION__.LOG_SEP.'Empty username.', LOG_TYPE_ERROR); - return false; - } + // The user is always the one logged + $args['username'] = Session::get('username'); + if (empty($args['username'])) { + Log::set(__FUNCTION__.LOG_SEP.'Empty username.', LOG_TYPE_ERROR); + return false; + } - $key = $pages->add($args); - if ($key) { - // Call the plugins after page created - execPluginsByHook('afterPageCreate', array($key)); + $key = $pages->add($args); + if ($key) { + // Call the plugins after page created + execPluginsByHook('afterPageCreate', array($key)); - // Reindex categories and tags - reindexCategories(); - reindexTags(); + // Reindex categories and tags + reindexCategories(); + reindexTags(); - // Add to syslog - $syslog->add(array( - 'dictionaryKey'=>'new-content-created', - 'notes'=>(empty($args['title'])?$key:$args['title']) - )); + // Add to syslog + $syslog->add(array( + 'dictionaryKey'=>'new-content-created', + 'notes'=>(empty($args['title'])?$key:$args['title']) + )); - Log::set(__FUNCTION__.LOG_SEP.'Page created.', LOG_TYPE_INFO); - return $key; - } + Log::set(__FUNCTION__.LOG_SEP.'Page created.', LOG_TYPE_INFO); + return $key; + } - Log::set(__FUNCTION__.LOG_SEP.'Something happened when you tried to create the page.', LOG_TYPE_ERROR); - deletePage(array('key'=>$key)); - return false; + Log::set(__FUNCTION__.LOG_SEP.'Something happened when you tried to create the page.', LOG_TYPE_ERROR); + deletePage(array('key'=>$key)); + return false; } /** * Edit a page. === Bludit v4 - * @param array $args All supported keys are defined in the class pages.class.php variable $dbFields + * @param array $args All supported parameters are defined in the class pages.class.php, variable $dbFields * @param string $args['key'] The key of the page to be edited * @return string|bool Returns the page key on successful edit, FALSE otherwise */ function editPage($args) { - global $pages; - global $syslog; + global $pages; + global $syslog; - // Check if the key is not empty - if (empty($args['key'])) { - Log::set(__FUNCTION__.LOG_SEP.'Empty page key.', LOG_TYPE_ERROR); - return false; - } + // Check if the key is not empty + if (empty($args['key'])) { + Log::set(__FUNCTION__.LOG_SEP.'Empty page key.', LOG_TYPE_ERROR); + return false; + } - // Check if the page key exist - if (!$pages->exists($args['key'])) { - Log::set(__FUNCTION__.LOG_SEP.'Page key doesn\'t exist: '.$args['key'], LOG_TYPE_ERROR); - return false; - } + // Check if the page key exist + if (!$pages->exists($args['key'])) { + Log::set(__FUNCTION__.LOG_SEP.'Page key doesn\'t exist: '.$args['key'], LOG_TYPE_ERROR); + return false; + } - // Call the plugins before the page is edited - execPluginsByHook('beforePageModify', array($args['key'])); + // Call the plugins before the page is edited + execPluginsByHook('beforePageModify', array($args['key'])); - $key = $pages->edit($args); - if ($key) { - // Call the plugins after page modified - execPluginsByHook('afterPageModify', array($key)); + $key = $pages->edit($args); + if ($key) { + // Call the plugins after page modified + execPluginsByHook('afterPageModify', array($key)); - // Reindex categories and tags - reindexCategories(); - reindexTags(); + // Reindex categories and tags + reindexCategories(); + reindexTags(); - // Add to syslog - $syslog->add(array( - 'dictionaryKey'=>'content-edited', - 'notes'=>empty($args['title'])?$key:$args['title'] - )); + // Add to syslog + $syslog->add(array( + 'dictionaryKey'=>'content-edited', + 'notes'=>empty($args['title'])?$key:$args['title'] + )); - Log::set(__FUNCTION__.LOG_SEP.'Page edited.', LOG_TYPE_INFO); - return $key; - } + Log::set(__FUNCTION__.LOG_SEP.'Page edited.', LOG_TYPE_INFO); + return $key; + } - Log::set(__FUNCTION__.LOG_SEP.'Something happened when you tried to edit the page.', LOG_TYPE_ERROR); - return false; + Log::set(__FUNCTION__.LOG_SEP.'Something happened when you tried to edit the page.', LOG_TYPE_ERROR); + return false; } /** @@ -105,32 +105,32 @@ function editPage($args) { * @return string|bool Returns the page key on successful delete, FALSE otherwise */ function deletePage($args) { - global $pages; - global $syslog; + global $pages; + global $syslog; - // Call the plugins before the page is deleted - execPluginsByHook('beforePageDelete', array($args['key'])); + // Call the plugins before the page is deleted + execPluginsByHook('beforePageDelete', array($args['key'])); - if ($pages->delete($args['key'])) { - // Call the plugins after page deleted - execPluginsByHook('afterPageDelete', array($args['key'])); + if ($pages->delete($args['key'])) { + // Call the plugins after page deleted + execPluginsByHook('afterPageDelete', array($args['key'])); - // Reindex categories and tags - reindexCategories(); - reindexTags(); + // Reindex categories and tags + reindexCategories(); + reindexTags(); - // Add to syslog - $syslog->add(array( - 'dictionaryKey'=>'content-deleted', - 'notes'=>$args['key'] - )); + // Add to syslog + $syslog->add(array( + 'dictionaryKey'=>'content-deleted', + 'notes'=>$args['key'] + )); - Log::set(__FUNCTION__.LOG_SEP.'Page deleted.', LOG_TYPE_INFO); - return true; - } + Log::set(__FUNCTION__.LOG_SEP.'Page deleted.', LOG_TYPE_INFO); + return true; + } - Log::set(__FUNCTION__.LOG_SEP.'Something happened when you tried to delete the page.', LOG_TYPE_ERROR); - return false; + Log::set(__FUNCTION__.LOG_SEP.'Something happened when you tried to delete the page.', LOG_TYPE_ERROR); + return false; } /** @@ -139,27 +139,27 @@ function deletePage($args) { * @return string|bool Returns the category key on successful create, FALSE otherwise */ function createCategory($args) { - global $categories; - global $syslog; + global $categories; + global $syslog; - if (Text::isEmpty($args['name'])) { - Log::set(__FUNCTION__.LOG_SEP.'The category name is empty.', LOG_TYPE_ERROR); - return false; - } + if (Text::isEmpty($args['name'])) { + Log::set(__FUNCTION__.LOG_SEP.'The category name is empty.', LOG_TYPE_ERROR); + return false; + } - $key = $categories->add($args); - if ($key) { - $syslog->add(array( - 'dictionaryKey'=>'new-category-created', - 'notes'=>$args['name'] - )); + $key = $categories->add($args); + if ($key) { + $syslog->add(array( + 'dictionaryKey'=>'new-category-created', + 'notes'=>$args['name'] + )); - Log::set(__FUNCTION__.LOG_SEP.'Category created.', LOG_TYPE_INFO); - return $key; - } + Log::set(__FUNCTION__.LOG_SEP.'Category created.', LOG_TYPE_INFO); + return $key; + } - Log::set(__FUNCTION__.LOG_SEP.'The category already exists or some issue saving the database.', LOG_TYPE_ERROR); - return false; + Log::set(__FUNCTION__.LOG_SEP.'The category already exists or some issue saving the database.', LOG_TYPE_ERROR); + return false; } /** @@ -168,46 +168,46 @@ function createCategory($args) { * @return string|bool Returns the category key on successful edit, FALSE otherwise */ function editCategory($args) { - global $pages; - global $categories; - global $syslog; + global $pages; + global $categories; + global $syslog; - if (Text::isEmpty($args['key'])) { - Log::set(__FUNCTION__.LOG_SEP.'The category key is empty.', LOG_TYPE_ERROR); - return false; - } + if (Text::isEmpty($args['key'])) { + Log::set(__FUNCTION__.LOG_SEP.'The category key is empty.', LOG_TYPE_ERROR); + return false; + } - if (Text::isEmpty($args['name'])) { - Log::set(__FUNCTION__.LOG_SEP.'The category name is empty.', LOG_TYPE_ERROR); - return false; - } + if (Text::isEmpty($args['name'])) { + Log::set(__FUNCTION__.LOG_SEP.'The category name is empty.', LOG_TYPE_ERROR); + return false; + } - if (Text::isEmpty($args['friendlyURL'])) { - Log::set(__FUNCTION__.LOG_SEP.'The category friendlyURL is empty.', LOG_TYPE_ERROR); - return false; - } + if (Text::isEmpty($args['friendlyURL'])) { + Log::set(__FUNCTION__.LOG_SEP.'The category friendlyURL is empty.', LOG_TYPE_ERROR); + return false; + } - $args['oldKey'] = $args['key']; - $args['newKey'] = $args['friendlyURL']; - $finalKey = $categories->edit($args); + $args['oldKey'] = $args['key']; + $args['newKey'] = $args['friendlyURL']; + $finalKey = $categories->edit($args); - if ($finalKey==false) { - Log::set(__FUNCTION__.LOG_SEP.'The category already exists.', LOG_TYPE_ERROR); - return false; - } + if ($finalKey==false) { + Log::set(__FUNCTION__.LOG_SEP.'The category already exists.', LOG_TYPE_ERROR); + return false; + } - // Re-link all pages with the new category key - if ($args['key']!==$finalKey) { - $pages->changeCategory($args['key'], $finalKey); - } + // Re-link all pages with the new category key + if ($args['key']!==$finalKey) { + $pages->changeCategory($args['key'], $finalKey); + } - $syslog->add(array( - 'dictionaryKey'=>'category-edited', - 'notes'=>$finalKey - )); + $syslog->add(array( + 'dictionaryKey'=>'category-edited', + 'notes'=>$finalKey + )); - Log::set(__FUNCTION__.LOG_SEP.'Category edited.', LOG_TYPE_INFO); - return $finalKey; + Log::set(__FUNCTION__.LOG_SEP.'Category edited.', LOG_TYPE_INFO); + return $finalKey; } /** @@ -216,670 +216,677 @@ function editCategory($args) { * @return string|bool Returns TRUE on successful delete, FALSE otherwise */ function deleteCategory($args) { - global $categories; - global $syslog; + global $categories; + global $syslog; - if (Text::isEmpty($args['key'])) { - Log::set(__FUNCTION__.LOG_SEP.'The category key is empty.', LOG_TYPE_ERROR); - return false; - } + if (Text::isEmpty($args['key'])) { + Log::set(__FUNCTION__.LOG_SEP.'The category key is empty.', LOG_TYPE_ERROR); + return false; + } - if ($categories->remove($args['key'])===false) { - Log::set(__FUNCTION__.LOG_SEP.'Something happened when you tried to delete the category.', LOG_TYPE_ERROR); - return false; - } + if ($categories->remove($args['key'])===false) { + Log::set(__FUNCTION__.LOG_SEP.'Something happened when you tried to delete the category.', LOG_TYPE_ERROR); + return false; + } - $syslog->add(array( - 'dictionaryKey'=>'category-deleted', - 'notes'=>$args['key'] - )); + $syslog->add(array( + 'dictionaryKey'=>'category-deleted', + 'notes'=>$args['key'] + )); - Log::set(__FUNCTION__.LOG_SEP.'Category deleted.', LOG_TYPE_INFO); - return true; + Log::set(__FUNCTION__.LOG_SEP.'Category deleted.', LOG_TYPE_INFO); + return true; } /** * Create an user. === Bludit v4 - * This function should check everthing, such as empty username, emtpy password, password lenght, etc - * @param array $args All supported keys are defined in the class users.class.php variable $dbFields - * @return string|bool Returns the username on successful create, FALSE otherwise + * This function should check everthing, such as empty username, empty password, password lenght, etc + * @param array $args All supported parameters are defined in the class users.class.php variable $dbFields + * @return string|bool Returns the username on successful create, FALSE otherwise */ function createUser($args) { - global $users; - global $syslog; + global $users; + global $syslog; - $args['username'] = Text::removeSpecialCharacters($args['username']); + $args['username'] = Text::removeSpecialCharacters($args['username']); - if (Text::isEmpty($args['username'])) { - Log::set(__FUNCTION__.LOG_SEP.'Empty username.', LOG_TYPE_ERROR); - return false; - } + if (Text::isEmpty($args['username'])) { + Log::set(__FUNCTION__.LOG_SEP.'Empty username.', LOG_TYPE_ERROR); + return false; + } - if (Text::length($args['password']) < PASSWORD_LENGTH) { - Log::set(__FUNCTION__.LOG_SEP.'The password is to short.', LOG_TYPE_ERROR); - return false; - } + if (Text::length($args['password']) < PASSWORD_LENGTH) { + Log::set(__FUNCTION__.LOG_SEP.'The password is to short.', LOG_TYPE_ERROR); + return false; + } - $key = $users->add($args); - if ($key) { - $syslog->add(array( - 'dictionaryKey'=>'new-user-created', - 'notes'=>$args['username'] - )); + $key = $users->add($args); + if ($key) { + $syslog->add(array( + 'dictionaryKey'=>'new-user-created', + 'notes'=>$args['username'] + )); - Log::set(__FUNCTION__.LOG_SEP.'User created.', LOG_TYPE_INFO); - return true; - } + Log::set(__FUNCTION__.LOG_SEP.'User created.', LOG_TYPE_INFO); + return true; + } - Log::set(__FUNCTION__.LOG_SEP.'The user already exists or some issue saving the database.', LOG_TYPE_ERROR); - return false; + Log::set(__FUNCTION__.LOG_SEP.'The user already exists or some issue saving the database.', LOG_TYPE_ERROR); + return false; } /** * Edit an user. === Bludit v4 - * @param array $args All supported keys are defined in the class users.class.php variable $dbFields + * @param array $args All supported parameters are defined in the class users.class.php, variable $dbFields * @param bool $args['disable'] If you set this variable the user will be disabled * @param string $args['password'] If you set this variable a new password will be set for the user * @return string|bool Returns TRUE on successful delete, FALSE otherwise */ function editUser($args) { - global $users; - global $syslog; + global $users; + global $syslog; - if (Text::isEmpty($args['username'])) { - Log::set(__FUNCTION__.LOG_SEP.'Empty username.', LOG_TYPE_ERROR); - return false; - } + if (Text::isEmpty($args['username'])) { + Log::set(__FUNCTION__.LOG_SEP.'Empty username.', LOG_TYPE_ERROR); + return false; + } - if (!$users->exists($args['username'])) { - Log::set(__FUNCTION__.LOG_SEP.'Username doesn\'t exist.', LOG_TYPE_ERROR); - return false; - } + if (!$users->exists($args['username'])) { + Log::set(__FUNCTION__.LOG_SEP.'Username doesn\'t exist.', LOG_TYPE_ERROR); + return false; + } - // Disable the user - // Your should pass the argument 'disable' - if (isset($args['disable'])) { - if (Session::get('role')!=='admin') { - Log::set(__FUNCTION__.LOG_SEP.'Only the administrator can disable users.', LOG_TYPE_ERROR); - return false; - } + // Disable the user + // Your should pass the argument 'disable' + if (isset($args['disable'])) { + if (Session::get('role')!=='admin') { + Log::set(__FUNCTION__.LOG_SEP.'Only the administrator can disable users.', LOG_TYPE_ERROR); + return false; + } - $key = $users->disableUser($args['username']); - if ($key) { - Log::set(__FUNCTION__.LOG_SEP.'User disabled.', LOG_TYPE_INFO); - return $key; - } - } + $key = $users->disableUser($args['username']); + if ($key) { + Log::set(__FUNCTION__.LOG_SEP.'User disabled.', LOG_TYPE_INFO); + return $key; + } + } - $key = $users->edit($args); - if ($key) { - $syslog->add(array( - 'dictionaryKey'=>'user-edited', - 'notes'=>$args['username'] - )); + $key = $users->edit($args); + if ($key) { + $syslog->add(array( + 'dictionaryKey'=>'user-edited', + 'notes'=>$args['username'] + )); - Log::set(__FUNCTION__.LOG_SEP.'User edited.', LOG_TYPE_INFO); - return $key; - } + Log::set(__FUNCTION__.LOG_SEP.'User edited.', LOG_TYPE_INFO); + return $key; + } - Log::set(__FUNCTION__.LOG_SEP.'An error occurred while trying to edit the user.', LOG_TYPE_ERROR); - return false; + Log::set(__FUNCTION__.LOG_SEP.'An error occurred while trying to edit the user.', LOG_TYPE_ERROR); + return false; } /* Upload a profile picture === Bludit v4 - The profile picture is store in PATH_UPLOADS_PROFILES.$username.png + The profile picture is store in PATH_UPLOADS_PROFILES.$username.png - @username string Username - @_FILE array https://www.php.net/manual/en/reserved.variables.files.php - @return array + @username string Username + @_FILE array https://www.php.net/manual/en/reserved.variables.files.php + @return array */ function uploadProfilePicture($username) { - if (!isset($_FILES['file'])) { - Log::set(__FUNCTION__.LOG_SEP.'File not sent.', LOG_TYPE_ERROR); - return false; - } + if (!isset($_FILES['file'])) { + Log::set(__FUNCTION__.LOG_SEP.'File not sent.', LOG_TYPE_ERROR); + return false; + } - if ($_FILES['file']['error'] != 0) { - Log::set(__FUNCTION__.LOG_SEP.'Error uploading the file.', LOG_TYPE_ERROR); - return false; - } + if ($_FILES['file']['error'] != 0) { + Log::set(__FUNCTION__.LOG_SEP.'Error uploading the file.', LOG_TYPE_ERROR); + return false; + } - // Check path traversal - if (Text::stringContains($username, DS, false)) { - Log::set(__FUNCTION__.LOG_SEP.'Path traversal detected.', LOG_TYPE_ERROR); - return false; - } + // Check path traversal + if (Text::stringContains($username, DS, false)) { + Log::set(__FUNCTION__.LOG_SEP.'Path traversal detected.', LOG_TYPE_ERROR); + return false; + } - // Check file extension - $fileExtension = Filesystem::extension($_FILES['file']['name']); - $fileExtension = Text::lowercase($fileExtension); - if (!in_array($fileExtension, $GLOBALS['ALLOWED_IMG_EXTENSIONS']) ) { - Log::set(__FUNCTION__.LOG_SEP.'Image type is not supported.', LOG_TYPE_ERROR); - return false; - } + // Check file extension + $fileExtension = Filesystem::extension($_FILES['file']['name']); + $fileExtension = Text::lowercase($fileExtension); + if (!in_array($fileExtension, $GLOBALS['ALLOWED_IMG_EXTENSIONS']) ) { + Log::set(__FUNCTION__.LOG_SEP.'Image type is not supported.', LOG_TYPE_ERROR); + return false; + } - // Check file MIME Type - $fileMimeType = Filesystem::mimeType($_FILES['file']['tmp_name']); - if ($fileMimeType!==false) { - if (!in_array($fileMimeType, $GLOBALS['ALLOWED_IMG_MIMETYPES'])) { - Log::set(__FUNCTION__.LOG_SEP.'Image mime type is not supported.', LOG_TYPE_ERROR); - return false; - } - } + // Check file MIME Type + $fileMimeType = Filesystem::mimeType($_FILES['file']['tmp_name']); + if ($fileMimeType!==false) { + if (!in_array($fileMimeType, $GLOBALS['ALLOWED_IMG_MIMETYPES'])) { + Log::set(__FUNCTION__.LOG_SEP.'Image mime type is not supported.', LOG_TYPE_ERROR); + return false; + } + } - // Move the image from PHP tmp folder to Bludit tmp folder - $filename = $username.'.'.$fileExtension; - Filesystem::mv($_FILES['file']['tmp_name'], PATH_TMP.$filename); + // Move the image from PHP tmp folder to Bludit tmp folder + $filename = $username.'.'.$fileExtension; + Filesystem::mv($_FILES['file']['tmp_name'], PATH_TMP.$filename); - $finalFilename = $username.'.png'; - $absolutePath = PATH_UPLOADS_PROFILES.$finalFilename; - $absoluteURL = DOMAIN_UPLOADS_PROFILES.$finalFilename; + $finalFilename = $username.'.png'; + $absolutePath = PATH_UPLOADS_PROFILES.$finalFilename; + $absoluteURL = DOMAIN_UPLOADS_PROFILES.$finalFilename; - try { - $image = new \claviska\SimpleImage(); - $image - ->fromFile(PATH_TMP.$filename) - ->autoOrient() - ->thumbnail(PROFILE_IMG_WIDTH, PROFILE_IMG_HEIGHT, 'center') - ->toFile($absolutePath, 'image/png'); - } catch(Exception $e) { - Log::set(__FUNCTION__.LOG_SEP.$e->getMessage(), LOG_TYPE_ERROR); - return false; - } + try { + $image = new \claviska\SimpleImage(); + $image + ->fromFile(PATH_TMP.$filename) + ->autoOrient() + ->thumbnail(PROFILE_IMG_WIDTH, PROFILE_IMG_HEIGHT, 'center') + ->toFile($absolutePath, 'image/png'); + } catch(Exception $e) { + Log::set(__FUNCTION__.LOG_SEP.$e->getMessage(), LOG_TYPE_ERROR); + return false; + } - Log::set(__FUNCTION__.LOG_SEP.'Image profile uploaded to the user.', LOG_TYPE_INFO); - return array( - 'filename'=>$filename, - 'absolutePath'=>$absolutePath, - 'absoluteURL'=>$absoluteURL, - 'mime'=>Filesystem::mimeType($absolutePath), - 'size'=>Filesystem::getSize($absolutePath) - ); + Log::set(__FUNCTION__.LOG_SEP.'Image profile uploaded to the user.', LOG_TYPE_INFO); + return array( + 'filename'=>$filename, + 'absolutePath'=>$absolutePath, + 'absoluteURL'=>$absoluteURL, + 'mime'=>Filesystem::mimeType($absolutePath), + 'size'=>Filesystem::getSize($absolutePath) + ); } /* Delete a profile picture === Bludit v4 - @username string Username - @return bool Returns TRUE on successful delete, FALSE otherwise + @username string Username + @return bool Returns TRUE on successful delete, FALSE otherwise */ function deleteProfilePicture($username) { - // Check path traversal - if (Text::stringContains($username, DS, false)) { - Log::set(__FUNCTION__.LOG_SEP.'Path traversal detected.', LOG_TYPE_ERROR); - return false; - } + // Check path traversal + if (Text::stringContains($username, DS, false)) { + Log::set(__FUNCTION__.LOG_SEP.'Path traversal detected.', LOG_TYPE_ERROR); + return false; + } - $finalFilename = $username.'.png'; - $absolutePath = PATH_UPLOADS_PROFILES.$finalFilename; + $finalFilename = $username.'.png'; + $absolutePath = PATH_UPLOADS_PROFILES.$finalFilename; - if (Sanitize::pathFile($absolutePath)) { - Filesystem::rmfile($absolutePath); - Log::set(__FUNCTION__.LOG_SEP.'Profile picture deleted.', LOG_TYPE_INFO); - return true; - } + if (Sanitize::pathFile($absolutePath)) { + Filesystem::rmfile($absolutePath); + Log::set(__FUNCTION__.LOG_SEP.'Profile picture deleted.', LOG_TYPE_INFO); + return true; + } - Log::set(__FUNCTION__.LOG_SEP.'Error when try to delete the profile picture, the file doesn\'t exists.', LOG_TYPE_ERROR); - return false; + Log::set(__FUNCTION__.LOG_SEP.'Error when try to delete the profile picture, the file doesn\'t exists.', LOG_TYPE_ERROR); + return false; } /* Upload the site logo === Bludit v4 - The site logo is store in PATH_UPLOADS/. + The site logo is store in PATH_UPLOADS/. - @_FILE array https://www.php.net/manual/en/reserved.variables.files.php - @return array + @_FILE array https://www.php.net/manual/en/reserved.variables.files.php + @return array */ function uploadSiteLogo() { - global $site; + global $site; - if (!isset($_FILES['file'])) { - Log::set(__FUNCTION__.LOG_SEP.'File not sent.', LOG_TYPE_ERROR); - return false; - } + if (!isset($_FILES['file'])) { + Log::set(__FUNCTION__.LOG_SEP.'File not sent.', LOG_TYPE_ERROR); + return false; + } - if ($_FILES['file']['error'] != 0) { - Log::set(__FUNCTION__.LOG_SEP.'Error uploading the file.', LOG_TYPE_ERROR); - return false; - } + if ($_FILES['file']['error'] != 0) { + Log::set(__FUNCTION__.LOG_SEP.'Error uploading the file.', LOG_TYPE_ERROR); + return false; + } - // Check path traversal - if (Text::stringContains($_FILES['file']['name'], DS, false)) { - Log::set(__FUNCTION__.LOG_SEP.'Path traversal detected.', LOG_TYPE_ERROR); - return false; - } + // Check path traversal + if (Text::stringContains($_FILES['file']['name'], DS, false)) { + Log::set(__FUNCTION__.LOG_SEP.'Path traversal detected.', LOG_TYPE_ERROR); + return false; + } - // Check file extension - $fileExtension = Filesystem::extension($_FILES['file']['name']); - $fileExtension = Text::lowercase($fileExtension); - if (!in_array($fileExtension, $GLOBALS['ALLOWED_IMG_EXTENSIONS']) ) { - Log::set(__FUNCTION__.LOG_SEP.'Image type is not supported.', LOG_TYPE_ERROR); - return false; - } + // Check file extension + $fileExtension = Filesystem::extension($_FILES['file']['name']); + $fileExtension = Text::lowercase($fileExtension); + if (!in_array($fileExtension, $GLOBALS['ALLOWED_IMG_EXTENSIONS']) ) { + Log::set(__FUNCTION__.LOG_SEP.'Image type is not supported.', LOG_TYPE_ERROR); + return false; + } - // Check file MIME Type - $fileMimeType = Filesystem::mimeType($_FILES['file']['tmp_name']); - if ($fileMimeType!==false) { - if (!in_array($fileMimeType, $GLOBALS['ALLOWED_IMG_MIMETYPES'])) { - Log::set(__FUNCTION__.LOG_SEP.'Image mime type is not supported.', LOG_TYPE_ERROR); - return false; - } - } + // Check file MIME Type + $fileMimeType = Filesystem::mimeType($_FILES['file']['tmp_name']); + if ($fileMimeType!==false) { + if (!in_array($fileMimeType, $GLOBALS['ALLOWED_IMG_MIMETYPES'])) { + Log::set(__FUNCTION__.LOG_SEP.'Image mime type is not supported.', LOG_TYPE_ERROR); + return false; + } + } - // Final filename - $filename = 'logo.'.$fileExtension; - $siteTitle = Text::cleanUrl($site->title(), '-', $allowExtremeFriendlyURL=false); - if (Text::isNotEmpty($siteTitle)) { - $filename = $siteTitle.'.'.$fileExtension; - } + // Final filename + $filename = 'logo.'.$fileExtension; + $siteTitle = Text::cleanUrl($site->title(), '-', $allowExtremeFriendlyURL=false); + if (Text::isNotEmpty($siteTitle)) { + $filename = $siteTitle.'.'.$fileExtension; + } - // Move the image from PHP tmp folder to Bludit tmp folder - Filesystem::mv($_FILES['file']['tmp_name'], PATH_TMP.$filename); + // Move the image from PHP tmp folder to Bludit tmp folder + Filesystem::mv($_FILES['file']['tmp_name'], PATH_TMP.$filename); - $absolutePath = PATH_UPLOADS.$filename; - $absoluteURL = DOMAIN_UPLOADS.$filename; + $absolutePath = PATH_UPLOADS.$filename; + $absoluteURL = DOMAIN_UPLOADS.$filename; - try { - $image = new \claviska\SimpleImage(); - $image - ->fromFile(PATH_TMP.$filename) - ->autoOrient() - ->thumbnail(PROFILE_IMG_WIDTH, PROFILE_IMG_HEIGHT, 'center') - ->toFile($absolutePath, 'image/png'); - } catch(Exception $e) { - Log::set(__FUNCTION__.LOG_SEP.$e->getMessage(), LOG_TYPE_ERROR); - return false; - } + try { + $image = new \claviska\SimpleImage(); + $image + ->fromFile(PATH_TMP.$filename) + ->autoOrient() + ->thumbnail(PROFILE_IMG_WIDTH, PROFILE_IMG_HEIGHT, 'center') + ->toFile($absolutePath, 'image/png'); + } catch(Exception $e) { + Log::set(__FUNCTION__.LOG_SEP.$e->getMessage(), LOG_TYPE_ERROR); + return false; + } - $site->set(array('logo'=>$filename)); + $site->set(array('logo'=>$filename)); - Log::set(__FUNCTION__.LOG_SEP.'Site logo uploaded and cropped.', LOG_TYPE_INFO); - return array( - 'filename'=>$filename, - 'absolutePath'=>$absolutePath, - 'absoluteURL'=>$absoluteURL, - 'mime'=>Filesystem::mimeType($absolutePath), - 'size'=>Filesystem::getSize($absolutePath) - ); + Log::set(__FUNCTION__.LOG_SEP.'Site logo uploaded and cropped.', LOG_TYPE_INFO); + return array( + 'filename'=>$filename, + 'absolutePath'=>$absolutePath, + 'absoluteURL'=>$absoluteURL, + 'mime'=>Filesystem::mimeType($absolutePath), + 'size'=>Filesystem::getSize($absolutePath) + ); } /* Delete the site logo === Bludit v4 - @return bool Returns TRUE on successful delete, FALSE otherwise + @return bool Returns TRUE on successful delete, FALSE otherwise */ function deleteSiteLogo() { - global $site; + global $site; - if ($site->logo()) { - Filesystem::rmfile(PATH_UPLOADS.$site->logo(false)); - $site->set(array('logo'=>'')); - Log::set(__FUNCTION__.LOG_SEP.'Site logo deleted.', LOG_TYPE_INFO); - return true; - } + if ($site->logo()) { + Filesystem::rmfile(PATH_UPLOADS.$site->logo(false)); + $site->set(array('logo'=>'')); + Log::set(__FUNCTION__.LOG_SEP.'Site logo deleted.', LOG_TYPE_INFO); + return true; + } - Log::set(__FUNCTION__.LOG_SEP.'Error when try to delete the site logo, the file doesn\'t exists.', LOG_TYPE_ERROR); - return false; + Log::set(__FUNCTION__.LOG_SEP.'Error when try to delete the site logo, the file doesn\'t exists.', LOG_TYPE_ERROR); + return false; } /* Upload a file to a page === Bludit v4 - The files is saved in + The files is saved in - @pageKey string Page key - @_FILE array https://www.php.net/manual/en/reserved.variables.files.php + @pageKey string Page key + @_FILE array https://www.php.net/manual/en/reserved.variables.files.php - @return array + @return array */ function uploadPageFile($pageKey) { - global $site; + global $site; - if (!isset($_FILES['file'])) { - Log::set(__FUNCTION__.LOG_SEP.'File not sent.', LOG_TYPE_ERROR); - return false; - } + if (!isset($_FILES['file'])) { + Log::set(__FUNCTION__.LOG_SEP.'File not sent.', LOG_TYPE_ERROR); + return false; + } - if ($_FILES['file']['error'] != 0) { - Log::set(__FUNCTION__.LOG_SEP.'Error uploading the file.', LOG_TYPE_ERROR); - return false; - } + if ($_FILES['file']['error'] != 0) { + Log::set(__FUNCTION__.LOG_SEP.'Error uploading the file.', LOG_TYPE_ERROR); + return false; + } - // Check path traversal - if (Text::stringContains($pageKey, DS, false)) { - Log::set(__FUNCTION__.LOG_SEP.'Path traversal detected.', LOG_TYPE_ERROR); - return false; - } + // Check path traversal + if (Text::stringContains($pageKey, DS, false)) { + Log::set(__FUNCTION__.LOG_SEP.'Path traversal detected.', LOG_TYPE_ERROR); + return false; + } - // Check file extension - $fileExtension = Filesystem::extension($_FILES['file']['name']); - $fileExtension = Text::lowercase($fileExtension); - if (!in_array($fileExtension, $GLOBALS['ALLOWED_FILE_EXTENSIONS']) ) { - Log::set(__FUNCTION__.LOG_SEP.'File type is not supported.', LOG_TYPE_ERROR); - return false; - } + // Check file extension + $fileExtension = Filesystem::extension($_FILES['file']['name']); + $fileExtension = Text::lowercase($fileExtension); + if (!in_array($fileExtension, $GLOBALS['ALLOWED_FILE_EXTENSIONS']) ) { + Log::set(__FUNCTION__.LOG_SEP.'File type is not supported.', LOG_TYPE_ERROR); + return false; + } - // Check file MIME Type - $fileMimeType = Filesystem::mimeType($_FILES['file']['tmp_name']); - if ($fileMimeType!==false) { - if (!in_array($fileMimeType, $GLOBALS['ALLOWED_FILE_MIMETYPES'])) { - Log::set(__FUNCTION__.LOG_SEP.'File mime type is not supported.', LOG_TYPE_ERROR); - return false; - } - } + // Check file MIME Type + $fileMimeType = Filesystem::mimeType($_FILES['file']['tmp_name']); + if ($fileMimeType!==false) { + if (!in_array($fileMimeType, $GLOBALS['ALLOWED_FILE_MIMETYPES'])) { + Log::set(__FUNCTION__.LOG_SEP.'File mime type is not supported.', LOG_TYPE_ERROR); + return false; + } + } - $filename = $_FILES['file']['name']; - $absoluteURL = DOMAIN_UPLOADS_PAGES.$pageKey.DS.$filename; - $absolutePath = PATH_UPLOADS_PAGES.$pageKey.DS.$filename; - if (Filesystem::mv($_FILES['file']['tmp_name'], $absolutePath)) { - // Create thumbnail if the files is an image - $thumbnail = ''; - if (in_array($fileMimeType, $GLOBALS['ALLOWED_IMG_MIMETYPES'])) { - try { - $thumbnail = PATH_UPLOADS_THUMBNAILS.$pageKey.DS.$filename; - $image = new \claviska\SimpleImage(); - $image - ->fromFile($absolutePath) - ->thumbnail($site->thumbnailWidth(), $site->thumbnailHeight(), 'center') - ->toFile($thumbnail, 'image/jpeg'); - } catch(Exception $e) { - Log::set(__FUNCTION__.LOG_SEP.$e->getMessage(), LOG_TYPE_ERROR); - return false; - } - } + $filename = Filesystem::filename($_FILES['file']['name']); + $absoluteURL = DOMAIN_UPLOADS_PAGES.$pageKey.DS.$filename.'.'.$fileExtension; + $absolutePath = PATH_UPLOADS_PAGES.$pageKey.DS.$filename.'.'.$fileExtension; + if (Filesystem::mv($_FILES['file']['tmp_name'], $absolutePath)) { + // Create thumbnail if the files is an image + $thumbnail = ''; + if (in_array($fileMimeType, $GLOBALS['ALLOWED_IMG_MIMETYPES'])) { + try { + $image = new \claviska\SimpleImage(); - Log::set(__FUNCTION__.LOG_SEP.'File uploaded to the page.', LOG_TYPE_INFO); - return array( - 'filename'=>$filename, - 'absolutePath'=>$absolutePath, - 'absoluteURL'=>$absoluteURL, - 'mime'=>Filesystem::mimeType($absolutePath), - 'size'=>Filesystem::getSize($absolutePath), - 'thumbnail'=>$thumbnail - ); - } + $thumbnailSmall = PATH_UPLOADS_PAGES.$pageKey.DS.$filename.'-thumbnail-s.'.$fileExtension; + $image + ->fromFile($absolutePath) + ->thumbnail($site->thumbnailSmallWidth(), $site->thumbnailSmallHeight(), 'center') + ->toFile($thumbnailSmall, 'image/jpeg'); - Log::set(__FUNCTION__.LOG_SEP.'Error uploading the file.', LOG_TYPE_ERROR); - return false; + $thumbnailMedium = PATH_UPLOADS_PAGES.$pageKey.DS.$filename.'-thumbnail-m.'.$fileExtension; + $image + ->fromFile($absolutePath) + ->thumbnail($site->thumbnailMediumWidth(), $site->thumbnailMediumHeight(), 'center') + ->toFile($thumbnailMedium, 'image/jpeg'); + } catch(Exception $e) { + Log::set(__FUNCTION__.LOG_SEP.$e->getMessage(), LOG_TYPE_ERROR); + return false; + } + } + + Log::set(__FUNCTION__.LOG_SEP.'File uploaded to the page.', LOG_TYPE_INFO); + return array( + 'filename'=>$filename.'.'.$fileExtension, + 'absolutePath'=>$absolutePath, + 'absoluteURL'=>$absoluteURL, + 'mime'=>Filesystem::mimeType($absolutePath), + 'size'=>Filesystem::getSize($absolutePath), + 'thumbnail'=>$thumbnail + ); + } + + Log::set(__FUNCTION__.LOG_SEP.'Error uploading the file.', LOG_TYPE_ERROR); + return false; } /* Install and activate a plugin === Bludit v4 - @className string The plugin PHP class name - @return string/bool Returns TRUE on successful install, FALSE otherwise + @className string The plugin PHP class name + @return string/bool Returns TRUE on successful install, FALSE otherwise */ function activatePlugin($className) { - global $plugins; - global $syslog; + global $plugins; + global $syslog; - if (!isset($plugins['all'][$className])) { - Log::set(__FUNCTION__.LOG_SEP.'The plugin doesn\'t exist: '.$className, LOG_TYPE_ERROR); - return false; - } + if (!isset($plugins['all'][$className])) { + Log::set(__FUNCTION__.LOG_SEP.'The plugin doesn\'t exist: '.$className, LOG_TYPE_ERROR); + return false; + } - $plugin = $plugins['all'][$className]; - if ($plugin->install()) { - $syslog->add(array( - 'dictionaryKey'=>'plugin-activated', - 'notes'=>$plugin->name() - )); - Log::set(__FUNCTION__.LOG_SEP.'Plugin installed.', LOG_TYPE_INFO); - return true; - } + $plugin = $plugins['all'][$className]; + if ($plugin->install()) { + $syslog->add(array( + 'dictionaryKey'=>'plugin-activated', + 'notes'=>$plugin->name() + )); + Log::set(__FUNCTION__.LOG_SEP.'Plugin installed.', LOG_TYPE_INFO); + return true; + } - Log::set(__FUNCTION__.LOG_SEP.'It was not possible to install the plugin:'.$className, LOG_TYPE_ERROR); - return false; + Log::set(__FUNCTION__.LOG_SEP.'It was not possible to install the plugin:'.$className, LOG_TYPE_ERROR); + return false; } /* Uninstall and deactivate a plugin === Bludit v4 - @className string The plugin PHP class name - @return string/bool Returns TRUE on successful install, FALSE otherwise + @className string The plugin PHP class name + @return string/bool Returns TRUE on successful install, FALSE otherwise */ function deactivatePlugin($className) { - global $plugins; - global $syslog; + global $plugins; + global $syslog; - if (!isset($plugins['all'][$className])) { - Log::set(__FUNCTION__.LOG_SEP.'The plugin doesn\'t exist: '.$className, LOG_TYPE_ERROR); - return false; - } + if (!isset($plugins['all'][$className])) { + Log::set(__FUNCTION__.LOG_SEP.'The plugin doesn\'t exist: '.$className, LOG_TYPE_ERROR); + return false; + } - $plugin = $plugins['all'][$className]; - if ($plugin->uninstall()) { - $syslog->add(array( - 'dictionaryKey'=>'plugin-deactivated', - 'notes'=>$plugin->name() - )); - Log::set(__FUNCTION__.LOG_SEP.'Plugin uninstalled.', LOG_TYPE_INFO); - return true; - } + $plugin = $plugins['all'][$className]; + if ($plugin->uninstall()) { + $syslog->add(array( + 'dictionaryKey'=>'plugin-deactivated', + 'notes'=>$plugin->name() + )); + Log::set(__FUNCTION__.LOG_SEP.'Plugin uninstalled.', LOG_TYPE_INFO); + return true; + } - Log::set(__FUNCTION__.LOG_SEP.'It was not possible to uninstall the plugin:'.$className, LOG_TYPE_ERROR); - return false; + Log::set(__FUNCTION__.LOG_SEP.'It was not possible to uninstall the plugin:'.$className, LOG_TYPE_ERROR); + return false; } /* Change plugins settings === Bludit v4 - @args array The array $args supports all the keys from the plugin database - @return bool Returns TRUE on successful configure, FALSE otherwise + @args array The array $args supports all the keys from the plugin database + @return bool Returns TRUE on successful configure, FALSE otherwise */ function configurePlugin($args) { - global $plugins; - global $syslog; + global $plugins; + global $syslog; - // Plugin class name - $className = $args['className']; + // Plugin class name + $className = $args['className']; - // Check if the plugin exists - if (!isset($plugins['all'][$className])) { - Log::set(__FUNCTION__.LOG_SEP.'The plugin doesn\'t exist: '.$className, LOG_TYPE_ERROR); - return false; - } + // Check if the plugin exists + if (!isset($plugins['all'][$className])) { + Log::set(__FUNCTION__.LOG_SEP.'The plugin doesn\'t exist: '.$className, LOG_TYPE_ERROR); + return false; + } - $plugin = $plugins['all'][$className]; - $plugin->configure($args); - $syslog->add(array( - 'dictionaryKey'=>'plugin-configured', - 'notes'=>$plugin->name() - )); - Log::set(__FUNCTION__.LOG_SEP.'Plugin configured: '.$className, LOG_TYPE_INFO); - return true; + $plugin = $plugins['all'][$className]; + $plugin->configure($args); + $syslog->add(array( + 'dictionaryKey'=>'plugin-configured', + 'notes'=>$plugin->name() + )); + Log::set(__FUNCTION__.LOG_SEP.'Plugin configured: '.$className, LOG_TYPE_INFO); + return true; } // Re-index database of categories // If you create/edit/remove a page is necessary regenerate the database of categories function reindexCategories() { - global $categories; - return $categories->reindex(); + global $categories; + return $categories->reindex(); } // Re-index database of tags // If you create/edit/remove a page is necessary regenerate the database of tags function reindexTags() { - global $tags; - return $tags->reindex(); + global $tags; + return $tags->reindex(); } // Generate the page 404 Not found function buildErrorPage() { - global $site; - global $L; + global $site; + global $L; - try { - $pageNotFoundKey = $site->pageNotFound(); - $pageNotFound = New Page($pageNotFoundKey); - } catch (Exception $e) { - $pageNotFound = New Page(false); - $pageNotFound->setField('title', $L->get('page-not-found')); - $pageNotFound->setField('content', $L->get('page-not-found-content')); - $pageNotFound->setField('username', 'admin'); - } + try { + $pageNotFoundKey = $site->pageNotFound(); + $pageNotFound = New Page($pageNotFoundKey); + } catch (Exception $e) { + $pageNotFound = New Page(false); + $pageNotFound->setField('title', $L->get('page-not-found')); + $pageNotFound->setField('content', $L->get('page-not-found-content')); + $pageNotFound->setField('username', 'admin'); + } - return $pageNotFound; + return $pageNotFound; } // This function is only used from the rule 69.pages.php, DO NOT use this function! // This function generate a particular page from the current slug of the url // If the slug has not a page associated returns FALSE and set not-found as true function buildThePage() { - global $url; + global $url; - try { - $pageKey = $url->slug(); - $page = New Page($pageKey); - } catch (Exception $e) { - $url->setNotFound(); - return false; - } + try { + $pageKey = $url->slug(); + $page = New Page($pageKey); + } catch (Exception $e) { + $url->setNotFound(); + return false; + } - if ($page->draft() || $page->scheduled() || $page->autosave()) { - if ($url->parameter('preview')!==md5($page->uuid())) { - $url->setNotFound(); - return false; - } - } + if ($page->draft() || $page->scheduled() || $page->autosave()) { + if ($url->parameter('preview')!==md5($page->uuid())) { + $url->setNotFound(); + return false; + } + } - return $page; + return $page; } // This function is only used from the rule 69.pages.php, DO NOT use this function! function buildPagesForHome() { - return buildPagesFor('home'); + return buildPagesFor('home'); } // This function is only used from the rule 69.pages.php, DO NOT use this function! function buildPagesByCategory() { - global $url; + global $url; - $categoryKey = $url->slug(); - return buildPagesFor('category', $categoryKey, false); + $categoryKey = $url->slug(); + return buildPagesFor('category', $categoryKey, false); } // This function is only used from the rule 69.pages.php, DO NOT use this function! function buildPagesByTag() { - global $url; + global $url; - $tagKey = $url->slug(); - return buildPagesFor('tag', false, $tagKey); + $tagKey = $url->slug(); + return buildPagesFor('tag', false, $tagKey); } // This function is only used from the rule 69.pages.php, DO NOT use this function! // Generate the global variables $content / $content, defined on 69.pages.php // This function is use for buildPagesForHome(), buildPagesByCategory(), buildPagesByTag() function buildPagesFor($for, $categoryKey=false, $tagKey=false) { - global $pages; - global $categories; - global $tags; - global $site; - global $url; + global $pages; + global $categories; + global $tags; + global $site; + global $url; - // Get the page number from URL - $pageNumber = $url->pageNumber(); + // Get the page number from URL + $pageNumber = $url->pageNumber(); - if ($for=='home') { - $onlyPublished = true; - $numberOfItems = $site->itemsPerPage(); - $list = $pages->getList($pageNumber, $numberOfItems, $onlyPublished); + if ($for=='home') { + $onlyPublished = true; + $numberOfItems = $site->itemsPerPage(); + $list = $pages->getList($pageNumber, $numberOfItems, $onlyPublished); - // Include sticky pages only in the first page - if ($pageNumber==1) { - $sticky = $pages->getStickyDB(); - $list = array_merge($sticky, $list); - } - } - elseif ($for=='category') { - $numberOfItems = $site->itemsPerPage(); - $list = $categories->getList($categoryKey, $pageNumber, $numberOfItems); - } - elseif ($for=='tag') { - $numberOfItems = $site->itemsPerPage(); - $list = $tags->getList($tagKey, $pageNumber, $numberOfItems); - } + // Include sticky pages only in the first page + if ($pageNumber==1) { + $sticky = $pages->getStickyDB(); + $list = array_merge($sticky, $list); + } + } + elseif ($for=='category') { + $numberOfItems = $site->itemsPerPage(); + $list = $categories->getList($categoryKey, $pageNumber, $numberOfItems); + } + elseif ($for=='tag') { + $numberOfItems = $site->itemsPerPage(); + $list = $tags->getList($tagKey, $pageNumber, $numberOfItems); + } - // There are not items, invalid tag, invalid category, out of range, etc... - if ($list===false) { - $url->setNotFound(); - return false; - } + // There are not items, invalid tag, invalid category, out of range, etc... + if ($list===false) { + $url->setNotFound(); + return false; + } - $content = array(); - foreach ($list as $pageKey) { - try { - $page = new Page($pageKey); - if ( ($page->type()=='published') || - ($page->type()=='sticky') || - ($page->type()=='static') - ) { - array_push($content, $page); - } - } catch (Exception $e) { - // continue - } - } + $content = array(); + foreach ($list as $pageKey) { + try { + $page = new Page($pageKey); + if ( ($page->type()=='published') || + ($page->type()=='sticky') || + ($page->type()=='static') + ) { + array_push($content, $page); + } + } catch (Exception $e) { + // continue + } + } - return $content; + return $content; } // Returns an array with all the static pages as Page-Object // The static pages are order by position all the time function buildStaticPages() { - global $pages; + global $pages; - $list = array(); - $pagesKey = $pages->getStaticDB(); - foreach ($pagesKey as $pageKey) { - try { - $page = new Page($pageKey); - array_push($list, $page); - } catch (Exception $e) { - // continue - } - } + $list = array(); + $pagesKey = $pages->getStaticDB(); + foreach ($pagesKey as $pageKey) { + try { + $page = new Page($pageKey); + array_push($list, $page); + } catch (Exception $e) { + // continue + } + } - return $list; + return $list; } // Returns the Page-Object if exists, FALSE otherwise function buildPage($pageKey) { - try { - $page = new Page($pageKey); - return $page; - } catch (Exception $e) { - return false; - } + try { + $page = new Page($pageKey); + return $page; + } catch (Exception $e) { + return false; + } } // Returns an array with all the parent pages as Page-Object // The pages are order by the settings on the system function buildParentPages() { - global $pages; + global $pages; - $list = array(); - $pagesKey = $pages->getPublishedDB(); - foreach ($pagesKey as $pageKey) { - try { - $page = new Page($pageKey); - if ($page->isParent()) { - array_push($list, $page); - } - } catch (Exception $e) { - // continue - } - } + $list = array(); + $pagesKey = $pages->getPublishedDB(); + foreach ($pagesKey as $pageKey) { + try { + $page = new Page($pageKey); + if ($page->isParent()) { + array_push($list, $page); + } + } catch (Exception $e) { + // continue + } + } - return $list; + return $list; } // Returns the Plugin-Object if is enabled and installed, FALSE otherwise function getPlugin($pluginClassName) { - global $plugins; + global $plugins; - if (pluginActivated($pluginClassName)) { - return $plugins['all'][$pluginClassName]; - } - return false; + if (pluginActivated($pluginClassName)) { + return $plugins['all'][$pluginClassName]; + } + return false; } // Check if the plugin is activated / installed // Returns TRUE if the plugin is activated / installed, FALSE otherwise function pluginActivated($pluginClassName) { - global $plugins; + global $plugins; if (isset($plugins['all'][$pluginClassName])) { return $plugins['all'][$pluginClassName]->installed(); @@ -889,31 +896,31 @@ function pluginActivated($pluginClassName) { function deactivateAllPlugin() { - global $plugins; - global $syslog; - global $L; + global $plugins; + global $syslog; + global $L; - // Check if the plugin exists - foreach ($plugins['all'] as $plugin) { - if ($plugin->uninstall()) { - // Add to syslog - $syslog->add(array( - 'dictionaryKey'=>'plugin-deactivated', - 'notes'=>$plugin->name() - )); - } - } - return false; + // Check if the plugin exists + foreach ($plugins['all'] as $plugin) { + if ($plugin->uninstall()) { + // Add to syslog + $syslog->add(array( + 'dictionaryKey'=>'plugin-deactivated', + 'notes'=>$plugin->name() + )); + } + } + return false; } // Execute the plugins by hook function execPluginsByHook($hook, $args = array()) { - global $plugins; - foreach ($plugins[$hook] as $plugin) { - echo call_user_func_array(array($plugin, $hook), $args); - } + global $plugins; + foreach ($plugins[$hook] as $plugin) { + echo call_user_func_array(array($plugin, $hook), $args); + } } @@ -921,157 +928,157 @@ function execPluginsByHook($hook, $args = array()) { function deleteUser($args) { - global $users, $pages; - global $login; - global $syslog; + global $users, $pages; + global $login; + global $syslog; - // Arguments - $username = $args['username']; - $deleteContent = isset($args['deleteContent']) ? $args['deleteContent'] : false; + // Arguments + $username = $args['username']; + $deleteContent = isset($args['deleteContent']) ? $args['deleteContent'] : false; - // Only administrators can delete users - if ($login->role()!=='admin') { - return false; - } + // Only administrators can delete users + if ($login->role()!=='admin') { + return false; + } - // The user admin cannot be deleted - if ($username=='admin') { - return false; - } + // The user admin cannot be deleted + if ($username=='admin') { + return false; + } - // Check if the username exists - if (!$users->exists($username)) { - return false; - } + // Check if the username exists + if (!$users->exists($username)) { + return false; + } - if ($deleteContent) { - $pages->deletePagesByUser(array('username'=>$username)); - } else { - $pages->transferPages(array('oldUsername'=>$username)); - } + if ($deleteContent) { + $pages->deletePagesByUser(array('username'=>$username)); + } else { + $pages->transferPages(array('oldUsername'=>$username)); + } - if ($users->delete($username)) { - // Add to syslog - $syslog->add(array( - 'dictionaryKey'=>'user-deleted', - 'notes'=>$username - )); + if ($users->delete($username)) { + // Add to syslog + $syslog->add(array( + 'dictionaryKey'=>'user-deleted', + 'notes'=>$username + )); - return true; - } + return true; + } - return false; + return false; } function editSettings($args) { - global $site; - global $syslog; - global $L; - global $pages; + global $site; + global $syslog; + global $L; + global $pages; - if (isset($args['language'])) { - if ($args['language']!=$site->language()) { - $tmp = new dbJSON(PATH_LANGUAGES.$args['language'].'.json', false); - if (isset($tmp->db['language-data']['locale'])) { - $args['locale'] = $tmp->db['language-data']['locale']; - } else { - $args['locale'] = $args['language']; - } - } - } + if (isset($args['language'])) { + if ($args['language']!=$site->language()) { + $tmp = new dbJSON(PATH_LANGUAGES.$args['language'].'.json', false); + if (isset($tmp->db['language-data']['locale'])) { + $args['locale'] = $tmp->db['language-data']['locale']; + } else { + $args['locale'] = $args['language']; + } + } + } - if (empty($args['homepage'])) { - $args['homepage'] = ''; - $args['uriBlog'] = ''; - } + if (empty($args['homepage'])) { + $args['homepage'] = ''; + $args['uriBlog'] = ''; + } - if (empty($args['pageNotFound'])) { - $args['pageNotFound'] = ''; - } + if (empty($args['pageNotFound'])) { + $args['pageNotFound'] = ''; + } - if (isset($args['uriPage'])) { - $args['uriPage'] = Text::addSlashes($args['uriPage']); - } + if (isset($args['uriPage'])) { + $args['uriPage'] = Text::addSlashes($args['uriPage']); + } - if (isset($args['uriTag'])) { - $args['uriTag'] = Text::addSlashes($args['uriTag']); - } + if (isset($args['uriTag'])) { + $args['uriTag'] = Text::addSlashes($args['uriTag']); + } - if (isset($args['uriCategory'])) { - $args['uriCategory'] = Text::addSlashes($args['uriCategory']); - } + if (isset($args['uriCategory'])) { + $args['uriCategory'] = Text::addSlashes($args['uriCategory']); + } - if (!empty($args['uriBlog'])) { - $args['uriBlog'] = Text::addSlashes($args['uriBlog']); - } else { - if (!empty($args['homepage']) && empty($args['uriBlog'])) { - $args['uriBlog'] = '/blog/'; - } else { - $args['uriBlog'] = ''; - } - } + if (!empty($args['uriBlog'])) { + $args['uriBlog'] = Text::addSlashes($args['uriBlog']); + } else { + if (!empty($args['homepage']) && empty($args['uriBlog'])) { + $args['uriBlog'] = '/blog/'; + } else { + $args['uriBlog'] = ''; + } + } - if (isset($args['extremeFriendly'])) { - $args['extremeFriendly'] = (($args['extremeFriendly']=='true')?true:false); - } + if (isset($args['extremeFriendly'])) { + $args['extremeFriendly'] = (($args['extremeFriendly']=='true')?true:false); + } - if (isset($args['customFields'])) { - // Custom fields need to be JSON format valid, also the empty JSON need to be "{}" - json_decode($args['customFields']); - if (json_last_error() != JSON_ERROR_NONE) { - return false; - } - $pages->setCustomFields($args['customFields']); - } + if (isset($args['customFields'])) { + // Custom fields need to be JSON format valid, also the empty JSON need to be "{}" + json_decode($args['customFields']); + if (json_last_error() != JSON_ERROR_NONE) { + return false; + } + $pages->setCustomFields($args['customFields']); + } - if ($site->set($args)) { - // Check current order-by if changed it reorder the content - if ($site->orderBy()!=ORDER_BY) { - if ($site->orderBy()=='date') { - $pages->sortByDate(); - } else { - $pages->sortByPosition(); - } - $pages->save(); - } + if ($site->set($args)) { + // Check current order-by if changed it reorder the content + if ($site->orderBy()!=ORDER_BY) { + if ($site->orderBy()=='date') { + $pages->sortByDate(); + } else { + $pages->sortByPosition(); + } + $pages->save(); + } - // Add syslog - $syslog->add(array( - 'dictionaryKey'=>'settings-changes', - 'notes'=>'' - )); + // Add syslog + $syslog->add(array( + 'dictionaryKey'=>'settings-changes', + 'notes'=>'' + )); - return true; - } + return true; + } - return false; + return false; } // Returns true if the user is allowed to proceed function checkRole($allowRoles, $redirect=true) { - global $login; - global $L; - global $syslog; + global $login; + global $L; + global $syslog; - $userRole = $login->role(); - if (in_array($userRole, $allowRoles)) { - return true; - } + $userRole = $login->role(); + if (in_array($userRole, $allowRoles)) { + return true; + } - if ($redirect) { - // Add to syslog - $syslog->add(array( - 'dictionaryKey'=>'access-denied', - 'notes'=>$login->username() - )); + if ($redirect) { + // 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'); - } - return false; + Alert::set($L->g('You do not have sufficient permissions')); + Redirect::page('dashboard'); + } + return false; } @@ -1083,98 +1090,98 @@ function checkRole($allowRoles, $redirect=true) { // Returns an array with all the categories // By default, the database of categories is alphanumeric sorted function getCategories() { - global $categories; + global $categories; - $list = array(); - foreach ($categories->keys() as $key) { - $category = new Category($key); - array_push($list, $category); - } - return $list; + $list = array(); + foreach ($categories->keys() as $key) { + $category = new Category($key); + array_push($list, $category); + } + return $list; } // Returns the object category if the category exists, FALSE otherwise function getCategory($key) { - try { - $category = new Category($key); - return $category; - } catch (Exception $e) { - return false; - } + try { + $category = new Category($key); + return $category; + } catch (Exception $e) { + return false; + } } // Returns an array with all the tags // By default, the database of tags is alphanumeric sorted function getTags() { - global $tags; + global $tags; - $list = array(); - foreach ($tags->db as $key=>$fields) { - $tag = new Tag($key); - array_push($list, $tag); - } - return $list; + $list = array(); + foreach ($tags->db as $key=>$fields) { + $tag = new Tag($key); + array_push($list, $tag); + } + return $list; } // Returns the object tag if the tag exists, FALSE otherwise function getTag($key) { - try { - $tag = new Tag($key); - return $tag; - } catch (Exception $e) { - return false; - } + try { + $tag = new Tag($key); + return $tag; + } catch (Exception $e) { + return false; + } } // Activate a theme function activateTheme($themeDirectory) { - global $site; - global $syslog; - global $L; + global $site; + global $syslog; + global $L; - if (Sanitize::pathFile(PATH_THEMES.$themeDirectory)) { - // Disable current theme - $currentTheme = $site->theme(); - deactivatePlugin($currentTheme); + if (Sanitize::pathFile(PATH_THEMES.$themeDirectory)) { + // Disable current theme + $currentTheme = $site->theme(); + deactivatePlugin($currentTheme); - // Install new theme - if (Filesystem::fileExists(PATH_THEMES.$themeDirectory.DS.'install.php')) { - include_once(PATH_THEMES.$themeDirectory.DS.'install.php'); - } + // Install new theme + if (Filesystem::fileExists(PATH_THEMES.$themeDirectory.DS.'install.php')) { + include_once(PATH_THEMES.$themeDirectory.DS.'install.php'); + } - activatePlugin($themeDirectory); + activatePlugin($themeDirectory); - $site->set(array('theme'=>$themeDirectory)); + $site->set(array('theme'=>$themeDirectory)); - $syslog->add(array( - 'dictionaryKey'=>'new-theme-configured', - 'notes'=>$themeDirectory - )); + $syslog->add(array( + 'dictionaryKey'=>'new-theme-configured', + 'notes'=>$themeDirectory + )); - Alert::set( $L->g('The changes have been saved') ); - return true; - } - return false; + Alert::set( $L->g('The changes have been saved') ); + return true; + } + return false; } function ajaxResponse($status=0, $message="", $data=array()) { - $default = array('status'=>$status, 'message'=>$message); - $output = array_merge($default, $data); - exit (json_encode($output)); + $default = array('status'=>$status, 'message'=>$message); + $output = array_merge($default, $data); + exit (json_encode($output)); } function downloadRestrictedFile($file) { - if (is_file($file)) { - header('Content-Description: File Transfer'); - header('Content-Type: application/octet-stream'); - header('Content-Disposition: attachment; filename="'.basename($file).'"'); - header('Expires: 0'); - header('Cache-Control: must-revalidate'); - header('Pragma: public'); - header('Content-Length: ' . filesize($file)); - readfile($file); - exit(0); - } + if (is_file($file)) { + header('Content-Description: File Transfer'); + header('Content-Type: application/octet-stream'); + header('Content-Disposition: attachment; filename="'.basename($file).'"'); + header('Expires: 0'); + header('Cache-Control: must-revalidate'); + header('Pragma: public'); + header('Content-Length: ' . filesize($file)); + readfile($file); + exit(0); + } } diff --git a/bl-kernel/helpers/filesystem.class.php b/bl-kernel/helpers/filesystem.class.php index 418c0f0e..65185b82 100644 --- a/bl-kernel/helpers/filesystem.class.php +++ b/bl-kernel/helpers/filesystem.class.php @@ -2,320 +2,321 @@ class Filesystem { - // Returns an array with the absolutes directories. - public static function listDirectories($path, $regex='*', $sortByDate=false) - { - $directories = glob($path.$regex, GLOB_ONLYDIR); + // Returns an array with the absolutes directories. + public static function listDirectories($path, $regex='*', $sortByDate=false) + { + $directories = glob($path.$regex, GLOB_ONLYDIR); - if(empty($directories)) { - return array(); - } + if(empty($directories)) { + return array(); + } - if($sortByDate) { - usort($directories, - function($a, $b) { - return filemtime($b) - filemtime($a); - } - ); - } + if($sortByDate) { + usort($directories, + function($a, $b) { + return filemtime($b) - filemtime($a); + } + ); + } - return $directories; - } + return $directories; + } - // Returns an array with the list of files with the absolute path - // $sortByDate = TRUE, the first file is the newer file - // $chunk = amount of chunks, FALSE if you don't want to chunk - public static function listFiles($path, $regex='*', $extension='*', $sortByDate=false, $chunk=false) - { - Log::set('list files = '.$path.$regex.'.'.$extension, LOG_TYPE_INFO); - $files = glob($path.$regex.'.'.$extension); + // Returns an array with the list of files with the absolute path + // $sortByDate = TRUE, the first file is the newer file + // $chunk = amount of chunks, FALSE if you don't want to chunk + public static function listFiles($path, $regex='*', $extension='*', $sortByDate=false, $chunk=false) + { + Log::set('list files = '.$path.$regex.'.'.$extension, LOG_TYPE_INFO); + $files = glob($path.$regex.'.'.$extension); - if (empty($files)) { - return array(); - } + if (empty($files)) { + return array(); + } - if ($sortByDate) { - usort($files, - function($a, $b) { - return filemtime($b) - filemtime($a); - } - ); - } + if ($sortByDate) { + usort($files, + function($a, $b) { + return filemtime($b) - filemtime($a); + } + ); + } - // Split the list of files into chunks - // http://php.net/manual/en/function.array-chunk.php - if ($chunk) { - return array_chunk($files, $chunk); - } + // Split the list of files into chunks + // http://php.net/manual/en/function.array-chunk.php + if ($chunk) { + return array_chunk($files, $chunk); + } - return $files; - } + return $files; + } - public static function mkdir($pathname, $recursive=false) - { - return mkdir($pathname, DIR_PERMISSIONS, $recursive); - } + public static function mkdir($pathname, $recursive=false) + { + return mkdir($pathname, DIR_PERMISSIONS, $recursive); + } - public static function rmdir($pathname) - { - Log::set('rmdir = '.$pathname, LOG_TYPE_INFO); - return rmdir($pathname); - } + public static function rmdir($pathname) + { + Log::set('rmdir = '.$pathname, LOG_TYPE_INFO); + return rmdir($pathname); + } - public static function mv($oldname, $newname) - { - Log::set('mv '.$oldname.' '.$newname, LOG_TYPE_INFO); - return rename($oldname, $newname); - } + public static function mv($oldname, $newname) + { + Log::set('mv '.$oldname.' '.$newname, LOG_TYPE_INFO); + return rename($oldname, $newname); + } - public static function rmfile($filename) - { - Log::set('rmfile = '.$filename, LOG_TYPE_INFO); - return unlink($filename); - } + public static function rmfile($filename) + { + Log::set('rmfile = '.$filename, LOG_TYPE_INFO); + return unlink($filename); + } - public static function fileExists($filename) - { - return file_exists($filename); - } + public static function fileExists($filename) + { + return file_exists($filename); + } - public static function directoryExists($path) - { - return file_exists($path); - } + public static function directoryExists($path) + { + return file_exists($path); + } - // Copy recursive a directory to another - // If the destination directory not exists is created - // $source = /home/diego/example or /home/diego/example/ - // $destination = /home/diego/newplace or /home/diego/newplace/ - public static function copyRecursive($source, $destination, $skipDirectory=false) - { - $source = rtrim($source, DS); - $destination = rtrim($destination, DS); + // Copy recursive a directory to another + // If the destination directory not exists is created + // $source = /home/diego/example or /home/diego/example/ + // $destination = /home/diego/newplace or /home/diego/newplace/ + public static function copyRecursive($source, $destination, $skipDirectory=false) + { + $source = rtrim($source, DS); + $destination = rtrim($destination, DS); - // Check $source directory if exists - if (!self::directoryExists($source)) { - return false; - } + // Check $source directory if exists + if (!self::directoryExists($source)) { + return false; + } - // Check $destionation directory if exists - if (!self::directoryExists($destination)) { - // Create the $destination directory - if (!mkdir($destination, DIR_PERMISSIONS, true)) { - return false; - } - } + // Check $destionation directory if exists + if (!self::directoryExists($destination)) { + // Create the $destination directory + if (!mkdir($destination, DIR_PERMISSIONS, true)) { + return false; + } + } - foreach ($iterator = new RecursiveIteratorIterator( - new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS), - RecursiveIteratorIterator::SELF_FIRST) as $item) { + foreach ($iterator = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS), + RecursiveIteratorIterator::SELF_FIRST) as $item) { - $currentDirectory = dirname($item->getPathName()); - if ($skipDirectory !== $currentDirectory) { - if ($item->isDir()) { - @mkdir($destination.DS.$iterator->getSubPathName()); - } else { - copy($item, $destination.DS.$iterator->getSubPathName()); - } - } - } + $currentDirectory = dirname($item->getPathName()); + if ($skipDirectory !== $currentDirectory) { + if ($item->isDir()) { + @mkdir($destination.DS.$iterator->getSubPathName()); + } else { + copy($item, $destination.DS.$iterator->getSubPathName()); + } + } + } - return true; - } + return true; + } - // Delete a file or directory recursive - // The directory is delete - public static function deleteRecursive($source, $deleteDirectory=true) - { - Log::set('deleteRecursive = '.$source, LOG_TYPE_INFO); + // Delete a file or directory recursive + // The directory is delete + public static function deleteRecursive($source, $deleteDirectory=true) + { + Log::set('deleteRecursive = '.$source, LOG_TYPE_INFO); - if (!self::directoryExists($source)) { - return false; - } + if (!self::directoryExists($source)) { + return false; + } - foreach (new RecursiveIteratorIterator( - new RecursiveDirectoryIterator($source, FilesystemIterator::SKIP_DOTS), - RecursiveIteratorIterator::CHILD_FIRST) as $item) { - if ($item->isFile() || $item->isLink()) { - unlink($item); - } else { - rmdir($item); - } - } + foreach (new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($source, FilesystemIterator::SKIP_DOTS), + RecursiveIteratorIterator::CHILD_FIRST) as $item) { + if ($item->isFile() || $item->isLink()) { + unlink($item); + } else { + rmdir($item); + } + } - if ($deleteDirectory) { - return rmdir($source); - } - return true; - } + if ($deleteDirectory) { + return rmdir($source); + } + return true; + } - // Compress a file or directory - // $source = /home/diego/example - // $destionation = /tmp/example.zip - public static function zip($source, $destination) - { - if (!extension_loaded('zip')) { - return false; - } + /** + * Compress a file or directory. + * $source = /home/diego/example + * $destionation = /tmp/example.zip + */ + public static function zip(string $source, string $destination): bool + { + if (!extension_loaded('zip')) { + return false; + } - if (!file_exists($source)) { - return false; - } + if (!file_exists($source)) { + return false; + } - $zip = new ZipArchive(); - if (!$zip->open($destination, ZIPARCHIVE::CREATE)) { - return false; - } + $zip = new ZipArchive(); + if (!$zip->open($destination, ZIPARCHIVE::CREATE)) { + return false; + } - if (is_dir($source) === true) { - $iterator = new RecursiveDirectoryIterator($source); - $iterator->setFlags(RecursiveDirectoryIterator::SKIP_DOTS); - $files = new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::SELF_FIRST); + if (is_dir($source) === true) { + $iterator = new RecursiveDirectoryIterator($source); + $iterator->setFlags(RecursiveDirectoryIterator::SKIP_DOTS); + $files = new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::SELF_FIRST); - foreach ($files as $file) { - $file = realpath($file); - if (is_dir($file)) { - $zip->addEmptyDir(ltrim(str_replace($source, '', $file), "/\\")); - } elseif (is_file($file)) { - $zip->addFromString(ltrim(str_replace($source, '', $file), "/\\"), file_get_contents($file)); - } - } - } elseif (is_file($source)) { - $zip->addFromString(basename($source), file_get_contents($source)); - } + foreach ($files as $file) { + $file = realpath($file); + if (is_dir($file)) { + $zip->addEmptyDir(ltrim(str_replace($source, '', $file), "/\\")); + } elseif (is_file($file)) { + $zip->addFromString(ltrim(str_replace($source, '', $file), "/\\"), file_get_contents($file)); + } + } + } elseif (is_file($source)) { + $zip->addFromString(basename($source), file_get_contents($source)); + } - return $zip->close(); - } + return $zip->close(); + } - // Uncompress a zip file - // $source = /home/diego/example.zip - // $destionation = /home/diego/content - public static function unzip($source, $destination) - { - if (!extension_loaded('zip')) { - return false; - } + // Uncompress a zip file + // $source = /home/diego/example.zip + // $destionation = /home/diego/content + public static function unzip($source, $destination) + { + if (!extension_loaded('zip')) { + return false; + } - if (!file_exists($source)) { - return false; - } + if (!file_exists($source)) { + return false; + } - $zip = new ZipArchive(); - if (!$zip->open($source)) { - return false; - } + $zip = new ZipArchive(); + if (!$zip->open($source)) { + return false; + } - $zip->extractTo($destination); - return $zip->close(); - } + $zip->extractTo($destination); + return $zip->close(); + } - /* - | Returns the next filename if the filename already exist otherwise returns the original filename + /* + | Returns the next filename if the filename already exist otherwise returns the original filename | | @path string Path | @filename string Filename | | @return string */ - public static function nextFilename($path=PATH_UPLOADS, $filename) { - // Clean filename and get extension - $fileExtension = pathinfo($filename, PATHINFO_EXTENSION); - $fileExtension = Text::lowercase($fileExtension); - $filename = pathinfo($filename, PATHINFO_FILENAME); - $filename = Text::removeSpaces($filename); - $filename = Text::removeQuotes($filename); + public static function nextFilename($filename, $path=PATH_UPLOADS) { + // Clean filename and get extension + $fileExtension = pathinfo($filename, PATHINFO_EXTENSION); + $fileExtension = Text::lowercase($fileExtension); + $filename = pathinfo($filename, PATHINFO_FILENAME); + $filename = Text::removeSpaces($filename); + $filename = Text::removeQuotes($filename); - // Search for the next filename - $tmpName = $filename.'.'.$fileExtension; - if (Sanitize::pathFile($path.$tmpName)) { - $number = 0; - $tmpName = $filename.'_'.$number.'.'.$fileExtension; - while (Sanitize::pathFile($path.$tmpName)) { - $number = $number + 1; - $tmpName = $filename.'_'.$number.'.'.$fileExtension; - } - } - return $tmpName; - } + // Search for the next filename + $tmpName = $filename.'.'.$fileExtension; + if (Sanitize::pathFile($path.$tmpName)) { + $number = 0; + $tmpName = $filename.'_'.$number.'.'.$fileExtension; + while (Sanitize::pathFile($path.$tmpName)) { + $number = $number + 1; + $tmpName = $filename.'_'.$number.'.'.$fileExtension; + } + } + return $tmpName; + } - /* - | Returns the filename - | Example: - | @file /home/diego/dog.jpg - | @return dog.jpg - | - | @file string Full path of the file - | - | @return string - */ - public static function filename($file) { - return basename($file); - } + /** + * Returns the file filename witout the extension. === Bludit v4 + * @param string $file Filename with the path + * @return string Extension. Example: /home/diego/dog.jpg -> dog.jpg + */ + public static function basename(string $file): string { + return pathinfo($file, PATHINFO_BASENAME); + } - /* - | Returns the file extension - | Example: - | @file /home/diego/dog.jpg - | @return jpg - | - | @file string Full path of the file - | - | @return string - */ - public static function extension($file) { - return pathinfo($file, PATHINFO_EXTENSION); - } + /** + * Returns the file filename witout the extension. === Bludit v4 + * @param string $file Filename with the path + * @return string Extension. Example: /home/diego/dog.jpg -> dog + */ + public static function filename(string $file): string { + return pathinfo($file, PATHINFO_FILENAME); + } - /** - * Get Size of file or directory in bytes - * @param [string] $fileOrDirectory - * @return [int|bool] [bytes or false on error] - */ - public static function getSize($fileOrDirectory) { - // Files - if (is_file($fileOrDirectory)) { - return filesize($fileOrDirectory); - } - // Directories - if (file_exists($fileOrDirectory)) { - $size = 0; - foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($fileOrDirectory, FilesystemIterator::SKIP_DOTS)) as $file){ - try { - $size += $file->getSize(); - } catch (Exception $e) { - // SplFileInfo::getSize RuntimeException will be thrown on broken symlinks/errors - } - } - return $size; - } - return false; - } + /** + * Returns the file extension. === Bludit v4 + * @param string $file Filename with the path + * @return string Extension. Example: /home/diego/dog.jpg -> jpg + */ + public static function extension(string $file): string { + return pathinfo($file, PATHINFO_EXTENSION); + } - public static function bytesToHumanFileSize($bytes, $decimals = 2) { - $size = array('B','kB','MB','GB','TB','PB','EB','ZB','YB'); - $factor = floor((strlen($bytes) - 1) / 3); - return sprintf("%.{$decimals}f ", $bytes / pow(1024, $factor)) . @$size[$factor]; - } + /** + * Get size of file or directory in bytes + * @param string $fileOrDirectory + * @return int|bool Bytes or false on error + */ + public static function getSize($fileOrDirectory) { + // Files + if (is_file($fileOrDirectory)) { + return filesize($fileOrDirectory); + } + // Directories + if (file_exists($fileOrDirectory)) { + $size = 0; + foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($fileOrDirectory, FilesystemIterator::SKIP_DOTS)) as $file){ + try { + $size += $file->getSize(); + } catch (Exception $e) { + // SplFileInfo::getSize RuntimeException will be thrown on broken symlinks/errors + } + } + return $size; + } + return false; + } - /* Returns the mime type of the file === Bludit v4 + public static function bytesToHumanFileSize($bytes, $decimals = 2) { + $size = array('B','kB','MB','GB','TB','PB','EB','ZB','YB'); + $factor = floor((strlen($bytes) - 1) / 3); + return sprintf("%.{$decimals}f ", $bytes / pow(1024, $factor)) . @$size[$factor]; + } - @file string Full path of the file. Example: /home/diego/dog.jpg + /* Returns the mime type of the file === Bludit v4 - @return string|bool Mime type or FALSE if not possible to get the mime type. Example: image/jpeg - */ - public static function mimeType($file) { - if (function_exists('mime_content_type')) { - return mime_content_type($file); - } + @file string Full path of the file. Example: /home/diego/dog.jpg - if (function_exists('finfo_file')) { - $fileinfo = finfo_open(FILEINFO_MIME_TYPE); - $mimeType = finfo_file($fileinfo, $file); - finfo_close($fileinfo); - return $mimeType; - } + @return string|bool Mime type or FALSE if not possible to get the mime type. Example: image/jpeg + */ + public static function mimeType($file) { + if (function_exists('mime_content_type')) { + return mime_content_type($file); + } - return false; - } + if (function_exists('finfo_file')) { + $fileinfo = finfo_open(FILEINFO_MIME_TYPE); + $mimeType = finfo_file($fileinfo, $file); + finfo_close($fileinfo); + return $mimeType; + } + + return false; + } } diff --git a/bl-kernel/helpers/html.class.php b/bl-kernel/helpers/html.class.php index 34f3d27c..3fb6b13b 100644 --- a/bl-kernel/helpers/html.class.php +++ b/bl-kernel/helpers/html.class.php @@ -82,6 +82,18 @@ class HTML { return ''.PHP_EOL; } + public static function jsSelect2($attributes='') + { + return ''.PHP_EOL; + } + + public static function cssSelect2() + { + $html = ''.PHP_EOL; + $html .= ''.PHP_EOL; + return $html; + } + /* Generates a dynamiclly the meta tag title for the themes === Bludit v4 @return string Returns the meta tag title ... diff --git a/bl-kernel/helpers/text.class.php b/bl-kernel/helpers/text.class.php index 1e5520b3..20151075 100644 --- a/bl-kernel/helpers/text.class.php +++ b/bl-kernel/helpers/text.class.php @@ -218,7 +218,10 @@ class Text { return mb_stripos($string, $substring, 0, CHARSET); } - public static function stringContains($string, $substring, $caseSensitive=true) + /** + * Return TRUE if the string contains the substring, FALSE otherwhise. === Bludit v4 + */ + public static function stringContains(string $string, string $substring, bool $caseSensitive=true): bool { return (self::stringPosition($string, $substring, $caseSensitive) !== false); } diff --git a/bl-kernel/js/select2.full.min.js b/bl-kernel/js/select2.full.min.js deleted file mode 100644 index fa781916..00000000 --- a/bl-kernel/js/select2.full.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ -!function(n){"function"==typeof define&&define.amd?define(["jquery"],n):"object"==typeof module&&module.exports?module.exports=function(e,t){return void 0===t&&(t="undefined"!=typeof window?require("jquery"):require("jquery")(e)),n(t),t}:n(jQuery)}(function(d){var e=function(){if(d&&d.fn&&d.fn.select2&&d.fn.select2.amd)var e=d.fn.select2.amd;var t,n,i,h,o,s,f,g,m,v,y,_,r,a,w,l;function b(e,t){return r.call(e,t)}function c(e,t){var n,i,r,o,s,a,l,c,u,d,p,h=t&&t.split("/"),f=y.map,g=f&&f["*"]||{};if(e){for(s=(e=e.split("/")).length-1,y.nodeIdCompat&&w.test(e[s])&&(e[s]=e[s].replace(w,"")),"."===e[0].charAt(0)&&h&&(e=h.slice(0,h.length-1).concat(e)),u=0;u":">",'"':""","'":"'","/":"/"};return"string"!=typeof e?e:String(e).replace(/[&<>"'\/\\]/g,function(e){return t[e]})},r.appendMany=function(e,t){if("1.7"===o.fn.jquery.substr(0,3)){var n=o();o.map(t,function(e){n=n.add(e)}),t=n}e.append(t)},r.__cache={};var n=0;return r.GetUniqueElementId=function(e){var t=e.getAttribute("data-select2-id");return null==t&&(e.id?(t=e.id,e.setAttribute("data-select2-id",t)):(e.setAttribute("data-select2-id",++n),t=n.toString())),t},r.StoreData=function(e,t,n){var i=r.GetUniqueElementId(e);r.__cache[i]||(r.__cache[i]={}),r.__cache[i][t]=n},r.GetData=function(e,t){var n=r.GetUniqueElementId(e);return t?r.__cache[n]&&null!=r.__cache[n][t]?r.__cache[n][t]:o(e).data(t):r.__cache[n]},r.RemoveData=function(e){var t=r.GetUniqueElementId(e);null!=r.__cache[t]&&delete r.__cache[t],e.removeAttribute("data-select2-id")},r}),e.define("select2/results",["jquery","./utils"],function(h,f){function i(e,t,n){this.$element=e,this.data=n,this.options=t,i.__super__.constructor.call(this)}return f.Extend(i,f.Observable),i.prototype.render=function(){var e=h('
    ');return this.options.get("multiple")&&e.attr("aria-multiselectable","true"),this.$results=e},i.prototype.clear=function(){this.$results.empty()},i.prototype.displayMessage=function(e){var t=this.options.get("escapeMarkup");this.clear(),this.hideLoading();var n=h(''),i=this.options.get("translations").get(e.message);n.append(t(i(e.args))),n[0].className+=" select2-results__message",this.$results.append(n)},i.prototype.hideMessages=function(){this.$results.find(".select2-results__message").remove()},i.prototype.append=function(e){this.hideLoading();var t=[];if(null!=e.results&&0!==e.results.length){e.results=this.sort(e.results);for(var n=0;n",{class:"select2-results__options select2-results__options--nested"});p.append(l),s.append(a),s.append(p)}else this.template(e,t);return f.StoreData(t,"data",e),t},i.prototype.bind=function(t,e){var l=this,n=t.id+"-results";this.$results.attr("id",n),t.on("results:all",function(e){l.clear(),l.append(e.data),t.isOpen()&&(l.setClasses(),l.highlightFirstItem())}),t.on("results:append",function(e){l.append(e.data),t.isOpen()&&l.setClasses()}),t.on("query",function(e){l.hideMessages(),l.showLoading(e)}),t.on("select",function(){t.isOpen()&&(l.setClasses(),l.options.get("scrollAfterSelect")&&l.highlightFirstItem())}),t.on("unselect",function(){t.isOpen()&&(l.setClasses(),l.options.get("scrollAfterSelect")&&l.highlightFirstItem())}),t.on("open",function(){l.$results.attr("aria-expanded","true"),l.$results.attr("aria-hidden","false"),l.setClasses(),l.ensureHighlightVisible()}),t.on("close",function(){l.$results.attr("aria-expanded","false"),l.$results.attr("aria-hidden","true"),l.$results.removeAttr("aria-activedescendant")}),t.on("results:toggle",function(){var e=l.getHighlightedResults();0!==e.length&&e.trigger("mouseup")}),t.on("results:select",function(){var e=l.getHighlightedResults();if(0!==e.length){var t=f.GetData(e[0],"data");"true"==e.attr("aria-selected")?l.trigger("close",{}):l.trigger("select",{data:t})}}),t.on("results:previous",function(){var e=l.getHighlightedResults(),t=l.$results.find("[aria-selected]"),n=t.index(e);if(!(n<=0)){var i=n-1;0===e.length&&(i=0);var r=t.eq(i);r.trigger("mouseenter");var o=l.$results.offset().top,s=r.offset().top,a=l.$results.scrollTop()+(s-o);0===i?l.$results.scrollTop(0):s-o<0&&l.$results.scrollTop(a)}}),t.on("results:next",function(){var e=l.getHighlightedResults(),t=l.$results.find("[aria-selected]"),n=t.index(e)+1;if(!(n>=t.length)){var i=t.eq(n);i.trigger("mouseenter");var r=l.$results.offset().top+l.$results.outerHeight(!1),o=i.offset().top+i.outerHeight(!1),s=l.$results.scrollTop()+o-r;0===n?l.$results.scrollTop(0):rthis.$results.outerHeight()||o<0)&&this.$results.scrollTop(r)}},i.prototype.template=function(e,t){var n=this.options.get("templateResult"),i=this.options.get("escapeMarkup"),r=n(e,t);null==r?t.style.display="none":"string"==typeof r?t.innerHTML=i(r):h(t).append(r)},i}),e.define("select2/keys",[],function(){return{BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,DELETE:46}}),e.define("select2/selection/base",["jquery","../utils","../keys"],function(n,i,r){function o(e,t){this.$element=e,this.options=t,o.__super__.constructor.call(this)}return i.Extend(o,i.Observable),o.prototype.render=function(){var e=n('');return this._tabindex=0,null!=i.GetData(this.$element[0],"old-tabindex")?this._tabindex=i.GetData(this.$element[0],"old-tabindex"):null!=this.$element.attr("tabindex")&&(this._tabindex=this.$element.attr("tabindex")),e.attr("title",this.$element.attr("title")),e.attr("tabindex",this._tabindex),e.attr("aria-disabled","false"),this.$selection=e},o.prototype.bind=function(e,t){var n=this,i=e.id+"-results";this.container=e,this.$selection.on("focus",function(e){n.trigger("focus",e)}),this.$selection.on("blur",function(e){n._handleBlur(e)}),this.$selection.on("keydown",function(e){n.trigger("keypress",e),e.which===r.SPACE&&e.preventDefault()}),e.on("results:focus",function(e){n.$selection.attr("aria-activedescendant",e.data._resultId)}),e.on("selection:update",function(e){n.update(e.data)}),e.on("open",function(){n.$selection.attr("aria-expanded","true"),n.$selection.attr("aria-owns",i),n._attachCloseHandler(e)}),e.on("close",function(){n.$selection.attr("aria-expanded","false"),n.$selection.removeAttr("aria-activedescendant"),n.$selection.removeAttr("aria-owns"),n.$selection.trigger("focus"),n._detachCloseHandler(e)}),e.on("enable",function(){n.$selection.attr("tabindex",n._tabindex),n.$selection.attr("aria-disabled","false")}),e.on("disable",function(){n.$selection.attr("tabindex","-1"),n.$selection.attr("aria-disabled","true")})},o.prototype._handleBlur=function(e){var t=this;window.setTimeout(function(){document.activeElement==t.$selection[0]||n.contains(t.$selection[0],document.activeElement)||t.trigger("blur",e)},1)},o.prototype._attachCloseHandler=function(e){n(document.body).on("mousedown.select2."+e.id,function(e){var t=n(e.target).closest(".select2");n(".select2.select2-container--open").each(function(){this!=t[0]&&i.GetData(this,"element").select2("close")})})},o.prototype._detachCloseHandler=function(e){n(document.body).off("mousedown.select2."+e.id)},o.prototype.position=function(e,t){t.find(".selection").append(e)},o.prototype.destroy=function(){this._detachCloseHandler(this.container)},o.prototype.update=function(e){throw new Error("The `update` method must be defined in child classes.")},o.prototype.isEnabled=function(){return!this.isDisabled()},o.prototype.isDisabled=function(){return this.options.get("disabled")},o}),e.define("select2/selection/single",["jquery","./base","../utils","../keys"],function(e,t,n,i){function r(){r.__super__.constructor.apply(this,arguments)}return n.Extend(r,t),r.prototype.render=function(){var e=r.__super__.render.call(this);return e.addClass("select2-selection--single"),e.html(''),e},r.prototype.bind=function(t,e){var n=this;r.__super__.bind.apply(this,arguments);var i=t.id+"-container";this.$selection.find(".select2-selection__rendered").attr("id",i).attr("role","textbox").attr("aria-readonly","true"),this.$selection.attr("aria-labelledby",i),this.$selection.on("mousedown",function(e){1===e.which&&n.trigger("toggle",{originalEvent:e})}),this.$selection.on("focus",function(e){}),this.$selection.on("blur",function(e){}),t.on("focus",function(e){t.isOpen()||n.$selection.trigger("focus")})},r.prototype.clear=function(){var e=this.$selection.find(".select2-selection__rendered");e.empty(),e.removeAttr("title")},r.prototype.display=function(e,t){var n=this.options.get("templateSelection");return this.options.get("escapeMarkup")(n(e,t))},r.prototype.selectionContainer=function(){return e("")},r.prototype.update=function(e){if(0!==e.length){var t=e[0],n=this.$selection.find(".select2-selection__rendered"),i=this.display(t,n);n.empty().append(i);var r=t.title||t.text;r?n.attr("title",r):n.removeAttr("title")}else this.clear()},r}),e.define("select2/selection/multiple",["jquery","./base","../utils"],function(r,e,l){function n(e,t){n.__super__.constructor.apply(this,arguments)}return l.Extend(n,e),n.prototype.render=function(){var e=n.__super__.render.call(this);return e.addClass("select2-selection--multiple"),e.html('
      '),e},n.prototype.bind=function(e,t){var i=this;n.__super__.bind.apply(this,arguments),this.$selection.on("click",function(e){i.trigger("toggle",{originalEvent:e})}),this.$selection.on("click",".select2-selection__choice__remove",function(e){if(!i.isDisabled()){var t=r(this).parent(),n=l.GetData(t[0],"data");i.trigger("unselect",{originalEvent:e,data:n})}})},n.prototype.clear=function(){var e=this.$selection.find(".select2-selection__rendered");e.empty(),e.removeAttr("title")},n.prototype.display=function(e,t){var n=this.options.get("templateSelection");return this.options.get("escapeMarkup")(n(e,t))},n.prototype.selectionContainer=function(){return r('
    • ×
    • ')},n.prototype.update=function(e){if(this.clear(),0!==e.length){for(var t=[],n=0;n×');a.StoreData(i[0],"data",t),this.$selection.find(".select2-selection__rendered").prepend(i)}},e}),e.define("select2/selection/search",["jquery","../utils","../keys"],function(i,a,l){function e(e,t,n){e.call(this,t,n)}return e.prototype.render=function(e){var t=i('');this.$searchContainer=t,this.$search=t.find("input");var n=e.call(this);return this._transferTabIndex(),n},e.prototype.bind=function(e,t,n){var i=this,r=t.id+"-results";e.call(this,t,n),t.on("open",function(){i.$search.attr("aria-controls",r),i.$search.trigger("focus")}),t.on("close",function(){i.$search.val(""),i.$search.removeAttr("aria-controls"),i.$search.removeAttr("aria-activedescendant"),i.$search.trigger("focus")}),t.on("enable",function(){i.$search.prop("disabled",!1),i._transferTabIndex()}),t.on("disable",function(){i.$search.prop("disabled",!0)}),t.on("focus",function(e){i.$search.trigger("focus")}),t.on("results:focus",function(e){e.data._resultId?i.$search.attr("aria-activedescendant",e.data._resultId):i.$search.removeAttr("aria-activedescendant")}),this.$selection.on("focusin",".select2-search--inline",function(e){i.trigger("focus",e)}),this.$selection.on("focusout",".select2-search--inline",function(e){i._handleBlur(e)}),this.$selection.on("keydown",".select2-search--inline",function(e){if(e.stopPropagation(),i.trigger("keypress",e),i._keyUpPrevented=e.isDefaultPrevented(),e.which===l.BACKSPACE&&""===i.$search.val()){var t=i.$searchContainer.prev(".select2-selection__choice");if(0this.maximumInputLength?this.trigger("results:message",{message:"inputTooLong",args:{maximum:this.maximumInputLength,input:t.term,params:t}}):e.call(this,t,n)},e}),e.define("select2/data/maximumSelectionLength",[],function(){function e(e,t,n){this.maximumSelectionLength=n.get("maximumSelectionLength"),e.call(this,t,n)}return e.prototype.bind=function(e,t,n){var i=this;e.call(this,t,n),t.on("select",function(){i._checkIfMaximumSelected()})},e.prototype.query=function(e,t,n){var i=this;this._checkIfMaximumSelected(function(){e.call(i,t,n)})},e.prototype._checkIfMaximumSelected=function(e,n){var i=this;this.current(function(e){var t=null!=e?e.length:0;0=i.maximumSelectionLength?i.trigger("results:message",{message:"maximumSelected",args:{maximum:i.maximumSelectionLength}}):n&&n()})},e}),e.define("select2/dropdown",["jquery","./utils"],function(t,e){function n(e,t){this.$element=e,this.options=t,n.__super__.constructor.call(this)}return e.Extend(n,e.Observable),n.prototype.render=function(){var e=t('');return e.attr("dir",this.options.get("dir")),this.$dropdown=e},n.prototype.bind=function(){},n.prototype.position=function(e,t){},n.prototype.destroy=function(){this.$dropdown.remove()},n}),e.define("select2/dropdown/search",["jquery","../utils"],function(o,e){function t(){}return t.prototype.render=function(e){var t=e.call(this),n=o('');return this.$searchContainer=n,this.$search=n.find("input"),t.prepend(n),t},t.prototype.bind=function(e,t,n){var i=this,r=t.id+"-results";e.call(this,t,n),this.$search.on("keydown",function(e){i.trigger("keypress",e),i._keyUpPrevented=e.isDefaultPrevented()}),this.$search.on("input",function(e){o(this).off("keyup")}),this.$search.on("keyup input",function(e){i.handleSearch(e)}),t.on("open",function(){i.$search.attr("tabindex",0),i.$search.attr("aria-controls",r),i.$search.trigger("focus"),window.setTimeout(function(){i.$search.trigger("focus")},0)}),t.on("close",function(){i.$search.attr("tabindex",-1),i.$search.removeAttr("aria-controls"),i.$search.removeAttr("aria-activedescendant"),i.$search.val(""),i.$search.trigger("blur")}),t.on("focus",function(){t.isOpen()||i.$search.trigger("focus")}),t.on("results:all",function(e){null!=e.query.term&&""!==e.query.term||(i.showSearch(e)?i.$searchContainer.removeClass("select2-search--hide"):i.$searchContainer.addClass("select2-search--hide"))}),t.on("results:focus",function(e){e.data._resultId?i.$search.attr("aria-activedescendant",e.data._resultId):i.$search.removeAttr("aria-activedescendant")})},t.prototype.handleSearch=function(e){if(!this._keyUpPrevented){var t=this.$search.val();this.trigger("query",{term:t})}this._keyUpPrevented=!1},t.prototype.showSearch=function(e,t){return!0},t}),e.define("select2/dropdown/hidePlaceholder",[],function(){function e(e,t,n,i){this.placeholder=this.normalizePlaceholder(n.get("placeholder")),e.call(this,t,n,i)}return e.prototype.append=function(e,t){t.results=this.removePlaceholder(t.results),e.call(this,t)},e.prototype.normalizePlaceholder=function(e,t){return"string"==typeof t&&(t={id:"",text:t}),t},e.prototype.removePlaceholder=function(e,t){for(var n=t.slice(0),i=t.length-1;0<=i;i--){var r=t[i];this.placeholder.id===r.id&&n.splice(i,1)}return n},e}),e.define("select2/dropdown/infiniteScroll",["jquery"],function(n){function e(e,t,n,i){this.lastParams={},e.call(this,t,n,i),this.$loadingMore=this.createLoadingMore(),this.loading=!1}return e.prototype.append=function(e,t){this.$loadingMore.remove(),this.loading=!1,e.call(this,t),this.showLoadingMore(t)&&(this.$results.append(this.$loadingMore),this.loadMoreIfNeeded())},e.prototype.bind=function(e,t,n){var i=this;e.call(this,t,n),t.on("query",function(e){i.lastParams=e,i.loading=!0}),t.on("query:append",function(e){i.lastParams=e,i.loading=!0}),this.$results.on("scroll",this.loadMoreIfNeeded.bind(this))},e.prototype.loadMoreIfNeeded=function(){var e=n.contains(document.documentElement,this.$loadingMore[0]);if(!this.loading&&e){var t=this.$results.offset().top+this.$results.outerHeight(!1);this.$loadingMore.offset().top+this.$loadingMore.outerHeight(!1)<=t+50&&this.loadMore()}},e.prototype.loadMore=function(){this.loading=!0;var e=n.extend({},{page:1},this.lastParams);e.page++,this.trigger("query:append",e)},e.prototype.showLoadingMore=function(e,t){return t.pagination&&t.pagination.more},e.prototype.createLoadingMore=function(){var e=n('
    • '),t=this.options.get("translations").get("loadingMore");return e.html(t(this.lastParams)),e},e}),e.define("select2/dropdown/attachBody",["jquery","../utils"],function(f,a){function e(e,t,n){this.$dropdownParent=f(n.get("dropdownParent")||document.body),e.call(this,t,n)}return e.prototype.bind=function(e,t,n){var i=this;e.call(this,t,n),t.on("open",function(){i._showDropdown(),i._attachPositioningHandler(t),i._bindContainerResultHandlers(t)}),t.on("close",function(){i._hideDropdown(),i._detachPositioningHandler(t)}),this.$dropdownContainer.on("mousedown",function(e){e.stopPropagation()})},e.prototype.destroy=function(e){e.call(this),this.$dropdownContainer.remove()},e.prototype.position=function(e,t,n){t.attr("class",n.attr("class")),t.removeClass("select2"),t.addClass("select2-container--open"),t.css({position:"absolute",top:-999999}),this.$container=n},e.prototype.render=function(e){var t=f(""),n=e.call(this);return t.append(n),this.$dropdownContainer=t},e.prototype._hideDropdown=function(e){this.$dropdownContainer.detach()},e.prototype._bindContainerResultHandlers=function(e,t){if(!this._containerResultsHandlersBound){var n=this;t.on("results:all",function(){n._positionDropdown(),n._resizeDropdown()}),t.on("results:append",function(){n._positionDropdown(),n._resizeDropdown()}),t.on("results:message",function(){n._positionDropdown(),n._resizeDropdown()}),t.on("select",function(){n._positionDropdown(),n._resizeDropdown()}),t.on("unselect",function(){n._positionDropdown(),n._resizeDropdown()}),this._containerResultsHandlersBound=!0}},e.prototype._attachPositioningHandler=function(e,t){var n=this,i="scroll.select2."+t.id,r="resize.select2."+t.id,o="orientationchange.select2."+t.id,s=this.$container.parents().filter(a.hasScroll);s.each(function(){a.StoreData(this,"select2-scroll-position",{x:f(this).scrollLeft(),y:f(this).scrollTop()})}),s.on(i,function(e){var t=a.GetData(this,"select2-scroll-position");f(this).scrollTop(t.y)}),f(window).on(i+" "+r+" "+o,function(e){n._positionDropdown(),n._resizeDropdown()})},e.prototype._detachPositioningHandler=function(e,t){var n="scroll.select2."+t.id,i="resize.select2."+t.id,r="orientationchange.select2."+t.id;this.$container.parents().filter(a.hasScroll).off(n),f(window).off(n+" "+i+" "+r)},e.prototype._positionDropdown=function(){var e=f(window),t=this.$dropdown.hasClass("select2-dropdown--above"),n=this.$dropdown.hasClass("select2-dropdown--below"),i=null,r=this.$container.offset();r.bottom=r.top+this.$container.outerHeight(!1);var o={height:this.$container.outerHeight(!1)};o.top=r.top,o.bottom=r.top+o.height;var s=this.$dropdown.outerHeight(!1),a=e.scrollTop(),l=e.scrollTop()+e.height(),c=ar.bottom+s,d={left:r.left,top:o.bottom},p=this.$dropdownParent;"static"===p.css("position")&&(p=p.offsetParent());var h={top:0,left:0};(f.contains(document.body,p[0])||p[0].isConnected)&&(h=p.offset()),d.top-=h.top,d.left-=h.left,t||n||(i="below"),u||!c||t?!c&&u&&t&&(i="below"):i="above",("above"==i||t&&"below"!==i)&&(d.top=o.top-h.top-s),null!=i&&(this.$dropdown.removeClass("select2-dropdown--below select2-dropdown--above").addClass("select2-dropdown--"+i),this.$container.removeClass("select2-container--below select2-container--above").addClass("select2-container--"+i)),this.$dropdownContainer.css(d)},e.prototype._resizeDropdown=function(){var e={width:this.$container.outerWidth(!1)+"px"};this.options.get("dropdownAutoWidth")&&(e.minWidth=e.width,e.position="relative",e.width="auto"),this.$dropdown.css(e)},e.prototype._showDropdown=function(e){this.$dropdownContainer.appendTo(this.$dropdownParent),this._positionDropdown(),this._resizeDropdown()},e}),e.define("select2/dropdown/minimumResultsForSearch",[],function(){function e(e,t,n,i){this.minimumResultsForSearch=n.get("minimumResultsForSearch"),this.minimumResultsForSearch<0&&(this.minimumResultsForSearch=1/0),e.call(this,t,n,i)}return e.prototype.showSearch=function(e,t){return!(function e(t){for(var n=0,i=0;i');return e.attr("dir",this.options.get("dir")),this.$container=e,this.$container.addClass("select2-container--"+this.options.get("theme")),u.StoreData(e[0],"element",this.$element),e},d}),e.define("select2/compat/utils",["jquery"],function(s){return{syncCssClasses:function(e,t,n){var i,r,o=[];(i=s.trim(e.attr("class")))&&s((i=""+i).split(/\s+/)).each(function(){0===this.indexOf("select2-")&&o.push(this)}),(i=s.trim(t.attr("class")))&&s((i=""+i).split(/\s+/)).each(function(){0!==this.indexOf("select2-")&&null!=(r=n(this))&&o.push(r)}),e.attr("class",o.join(" "))}}}),e.define("select2/compat/containerCss",["jquery","./utils"],function(s,a){function l(e){return null}function e(){}return e.prototype.render=function(e){var t=e.call(this),n=this.options.get("containerCssClass")||"";s.isFunction(n)&&(n=n(this.$element));var i=this.options.get("adaptContainerCssClass");if(i=i||l,-1!==n.indexOf(":all:")){n=n.replace(":all:","");var r=i;i=function(e){var t=r(e);return null!=t?t+" "+e:e}}var o=this.options.get("containerCss")||{};return s.isFunction(o)&&(o=o(this.$element)),a.syncCssClasses(t,this.$element,i),t.css(o),t.addClass(n),t},e}),e.define("select2/compat/dropdownCss",["jquery","./utils"],function(s,a){function l(e){return null}function e(){}return e.prototype.render=function(e){var t=e.call(this),n=this.options.get("dropdownCssClass")||"";s.isFunction(n)&&(n=n(this.$element));var i=this.options.get("adaptDropdownCssClass");if(i=i||l,-1!==n.indexOf(":all:")){n=n.replace(":all:","");var r=i;i=function(e){var t=r(e);return null!=t?t+" "+e:e}}var o=this.options.get("dropdownCss")||{};return s.isFunction(o)&&(o=o(this.$element)),a.syncCssClasses(t,this.$element,i),t.css(o),t.addClass(n),t},e}),e.define("select2/compat/initSelection",["jquery"],function(i){function e(e,t,n){n.get("debug")&&window.console&&console.warn&&console.warn("Select2: The `initSelection` option has been deprecated in favor of a custom data adapter that overrides the `current` method. This method is now called multiple times instead of a single time when the instance is initialized. Support will be removed for the `initSelection` option in future versions of Select2"),this.initSelection=n.get("initSelection"),this._isInitialized=!1,e.call(this,t,n)}return e.prototype.current=function(e,t){var n=this;this._isInitialized?e.call(this,t):this.initSelection.call(null,this.$element,function(e){n._isInitialized=!0,i.isArray(e)||(e=[e]),t(e)})},e}),e.define("select2/compat/inputData",["jquery","../utils"],function(s,i){function e(e,t,n){this._currentData=[],this._valueSeparator=n.get("valueSeparator")||",","hidden"===t.prop("type")&&n.get("debug")&&console&&console.warn&&console.warn("Select2: Using a hidden input with Select2 is no longer supported and may stop working in the future. It is recommended to use a `