Compare commits

..

93 commits

Author SHA1 Message Date
Diego Najar
3c02c86498 feat: new bludit version with bug fix for php 5 2024-08-25 10:11:57 +02:00
Diego Najar
fa736d907b chore: fix versioning number 2024-08-06 22:48:54 +02:00
Diego Najar
16c70204dc
Merge pull request #1572 from basteyy/patch-1
Fix 2 deprecated messages
2024-08-06 22:48:24 +02:00
Diego Najar
151c5ab482
Merge pull request #1573 from bramley/correct_good_afternoon
Welcome message displays "good night" in the afternoon
2024-08-06 22:40:05 +02:00
Diego Najar
27f352f586
Merge pull request #1574 from kurisotofaa/patch-1
Create lt.json
2024-08-06 22:38:49 +02:00
Kristupas Grigas
76a3ea1c3d
Create lt.json
translated to lithuanian
2024-07-19 21:08:27 +02:00
Duncan Cameron
e17583fb63 Display correct welcome message when hour is exactly 6, 12 or 18 2024-07-07 13:50:14 +01:00
basteyy
593f5b3aed
Update pagex.class.php
Fix deprecated dynamic property creation and week calculation in relativeTime function

- Resolved deprecated warning by avoiding dynamic property creation on DateInterval object.
- Calculated weeks separately and included them correctly in the output string.
- Adjusted the logic to handle weeks within the string array without creating a dynamic property.
- Ensured compatibility with PHP 8.2 and higher, where dynamic properties are deprecated.

This fix prevents the "Deprecated: Creation of dynamic property DateInterval::$w is deprecated" warning and correctly formats the relative time string.
2024-07-06 23:05:51 +02:00
basteyy
4412f339cc
Update pages.class.php
Deprecated: uasort(): Returning bool from comparison function is deprecated, return an integer less than, equal to, or greater than zero in /var/www/html/bludit/bl-kernel/pages.class.php on line 424
2024-07-06 23:03:12 +02:00
Diego Najar
49fb7f03b1 after save content redirect to the proper tab to avoid confusion if the content was created or not #1541 2024-06-30 21:59:24 +02:00
Diego Najar
437190fcbb add telegram support #1565 2024-06-30 21:48:29 +02:00
Diego Najar
4bfa4a74a9 fix: page upload symlink 2024-06-23 21:46:43 +02:00
Diego Najar
e770d6a972 fix: password length when changed user password 2024-06-22 16:34:24 +02:00
Diego Najar
6248ea0a62 chore: add prettierrc and dir=auto to form inputs 2024-06-22 16:22:05 +02:00
Diego Najar
16cd57029b
Merge pull request #1563 from bramley/footer_span_element
Remove spurious </span> from theme footer
2024-03-29 10:08:34 +01:00
Diego Najar
af7488f1b4
Merge pull request #1564 from bramley/remove_upload_when_deleting_content_page
Use the page UUID to identify the upload directory when deleting a page
2024-03-29 10:07:57 +01:00
Duncan Cameron
957663b48b Use the page UUID to identify the upload directory when deleting a page
Fixes #1545
2024-03-24 20:40:15 +00:00
Duncan Cameron
0b381e8df7 Remove spurious </span> 2024-03-24 12:32:29 +00:00
Diego Najar
d586fce4f2
Merge pull request #1553 from gaincoder/v3.0
Add .webp support and fix #1467
2024-01-28 20:13:39 +01:00
Diego Najar
4a645173f7
Merge pull request #1554 from gaincoder/bug-related 2024-01-13 16:03:38 -03:00
Tim Moritz
1c32692b2a fix crash if no releated pages found 2024-01-12 11:36:08 +01:00
Tim Moritz
1868c63b93 Add .webp support 2024-01-12 10:56:39 +01:00
Diego Najar
7995d862bc
Merge pull request #1543 from gentledawn/patch-1
Update theme.class.php
2023-10-14 10:07:09 +02:00
gentledawn
b05655717e
Update theme.class.php
Add missing Dribbble.
2023-10-14 14:52:53 +07:00
Diego Najar
be292c15ff
Merge pull request #1533 from hide-me/patch-1
Update ru_RU.json
2023-09-19 17:47:12 +02:00
Diego Najar
2d33a325d1
Merge pull request #1534 from hide-me/patch-2
Created ru.json
2023-09-19 17:47:04 +02:00
Diego Najar
d2f1068e08
Merge pull request #1535 from hide-me/patch-3
Update and rename ru_RU.json to ru.json
2023-09-19 17:46:42 +02:00
Diego Najar
53cc162d3a
Merge pull request #1536 from hide-me/patch-5
Rename ru_RU.json to ru.json
2023-09-19 17:46:31 +02:00
Diego Najar
39ff27bff6
Merge pull request #1537 from hide-me/patch-6
Rename ru_RU.json to ru.json
2023-09-19 17:46:08 +02:00
Diego Najar
e8e83a3219
Merge pull request #1538 from hide-me/patch-4
Create ru.json
2023-09-19 17:45:53 +02:00
Paul
90e81d7fe8
Rename ru_RU.json to ru.json 2023-09-19 14:26:04 +03:00
Paul
d7b76909f7
Update ru.json 2023-09-19 14:25:07 +03:00
Paul
c1093dbef1
Rename ru_RU.json to ru.json 2023-09-19 14:24:03 +03:00
Paul
e913a1a857
Rename ru_RU.json to ru.json 2023-09-19 14:23:06 +03:00
Paul
6331155414
Create ru.json
Added russian translation for this plugin
2023-09-19 14:21:11 +03:00
Paul
d9963918fb
Update and rename ru_RU.json to ru.json 2023-09-19 14:17:59 +03:00
Paul
f29db1eee0
Created ru.json
Added russian translation for this plugin
2023-09-19 14:11:11 +03:00
Paul
4998bc7005
Update ru_RU.json 2023-09-19 14:03:34 +03:00
Diego Najar
0a9c21a1e8 release name krakow 2023-07-15 16:16:24 +02:00
Diego Najar
6d38311c72 bl content 2023-07-15 16:11:35 +02:00
Diego Najar
c65282334d update license 2023-07-15 16:10:01 +02:00
Diego Najar
27415297e8 bludit v3.15.0 2023-07-15 15:59:51 +02:00
Diego Najar
654be18345
Update issue_template.md 2023-07-11 00:09:35 +02:00
Diego Najar
2ab78beb8b small changes for Bludit PRO 2022-09-08 21:35:32 +02:00
Diego Najar
600724da2b Bug fix, the new version is not showing up 2022-09-08 21:35:15 +02:00
Diego Najar
e5a7735360 Fix deprecation warninigs 2022-09-07 17:03:45 +02:00
Diego Najar
eed574d21f remove backup plugin 2022-09-05 22:20:29 +02:00
Diego Najar
b6c212337e fix for #1327 2022-09-05 20:27:56 +02:00
Diego Najar
29b7d74ead change metadata and compatibility with php8 2022-09-05 20:11:15 +02:00
Diego Najar
5cad642a68 change metadata for new release 2022-09-05 20:10:28 +02:00
Diego Najar
8636f6d6b8 refactor UI 2022-09-05 20:08:48 +02:00
Diego Najar
3a8fa7ab94 add compatibility with php8.1 #1452 2022-09-05 20:08:04 +02:00
Diego Najar
bda30ee9b0 change icon 2022-09-05 20:07:24 +02:00
Diego Najar
1b6a5587d6 show site name instead of Bludit 2022-09-05 20:07:02 +02:00
Diego Najar
a01a611990 add support to webp images, improve UI 2022-09-05 20:06:18 +02:00
Diego Najar
20c03011cb update bootstrap 2022-09-05 20:05:19 +02:00
Diego Najar
d9fdd9aac0 update tinymce v5.10.5 2022-09-05 20:04:20 +02:00
Diego Najar
dbeda6bc54
Merge pull request #1391 from ronaldaug/master
Missing comma - it shows the errors at installation page
2021-12-21 09:31:41 +01:00
ronaldaug
3964a743e0
Missing comma - error at install page
Error shows at installation page
2021-12-13 20:31:44 +06:30
Diego Najar
116bacf322
Update README.md 2021-12-12 13:35:47 +01:00
Diego Najar
f4f85ec3d4 bug fix on session and multiple paths 2021-11-28 13:43:55 +01:00
Diego Najar
a3555315b8 bug fix on session and multiple paths 2021-11-28 12:45:31 +01:00
Diego Najar
0b7d327480
Merge pull request #1359 from nogajun/master
update Japanese translation(fix translation and typo).
2021-10-04 19:23:35 +02:00
Jun Nogata
cd2ba5c848 update Japanese translation(fix translation and typo). 2021-10-01 19:48:48 +09:00
Diego Najar
ae514f2665
Merge pull request #1348 from marekrost/czech-locale
Czech translation update
2021-09-20 09:31:33 +02:00
Marek Rost
e8536d1890 User feedback changes to improve translation clarity 2021-09-19 11:54:46 +02:00
Marek Rost
20b4852491 Updated the czech translation to reflect latest changes to bludit. With the addition of page templating, changed the title of graphical themes since the meaning of word "šablona" fits page templating better. 2021-09-18 15:39:35 +02:00
Edi
3e3fb95a19
Merge pull request #1335 from nsauter/master
fix 'mitatbeiter' typo in german (DE,AT & CH) locale files
2021-06-28 12:37:32 +02:00
Nico Sauter
8e31d1ba2a fix 'mitatbeiter' typo in german (DE,AT & CH) locale files 2021-06-27 13:08:52 +00:00
Diego Najar
aa1dee1d30
Merge pull request #1291 from ltGuillaume/master
Completed Dutch translation for TinyMCE
2021-06-05 21:14:03 +02:00
Diego Najar
ba11fe5450
Merge pull request #1326 from angerangel/patch-1
Added link for image
2021-06-05 21:09:12 +02:00
angerangel
5767f08b4f
Added link for image
Link for image is very important for sharing rss.
2021-05-25 12:52:53 +02:00
Diego Najar
f10ad07fad
Merge pull request #1313 from nicobubulle/french
French update
2021-04-26 14:05:43 +02:00
Diego Najar
caa3138f07
Merge pull request #1323 from richelbilderbeek/patch-1
Fix typo
2021-04-26 14:05:11 +02:00
Richel Bilderbeek
4dbf631405
Fix typo 2021-04-26 14:03:53 +02:00
nicobubulle
c7f8a1da17 French update 2021-03-20 16:55:02 +01:00
Diego Najar
b7c5ced470
Update README.md 2021-01-22 19:24:43 +01:00
ltGuillaume
8f05af194d Completed Dutch translation for TinyMCE 2020-12-26 15:49:04 +01:00
Diego Najar
5abddff1aa
Merge pull request #1290 from MrReSc/master
Codesample plugin setting and translations
2020-12-21 09:52:29 +01:00
MrReSc
17a3fcf779 remove whitespace 2020-12-20 08:24:20 +01:00
MrReSc
a1e6443cc8 json formated 2020-12-20 08:23:14 +01:00
MrReSc
d68b6e9469 json formated 2020-12-20 08:21:54 +01:00
MrReSc
bd15f96d06 remove prism plugin 2020-12-20 08:19:39 +01:00
MrReSc
381cfa5cb7 revert changes in htaccess 2020-12-20 08:18:59 +01:00
MrReSc
9ed96fc771 revert change in gitignore 2020-12-20 08:16:05 +01:00
MrReSc
4c44e48ffc description on settings page added 2020-12-20 08:08:11 +01:00
MrReSc
4a489ec1d1 add description for codesample langs 2020-12-20 08:00:09 +01:00
MrReSc
fec2df5a23 fix broken translation and plugin texts added 2020-12-20 07:44:40 +01:00
MrReSc
717b196594 codesample languges added 2020-12-20 07:14:38 +01:00
Diego Najar
35a39cff65
Merge pull request #1283 from ltGuillaume/master
Dutch
2020-11-18 09:34:00 +01:00
ltGuillaume
007f580f5f Dutch 2020-11-01 17:55:54 +01:00
Diego Najar
3110e55e90
Merge pull request #1282 from jedix/feat-insert-image-with-thumbnail
feat: Allow images to be inserted as thumbnails or as linked thumbnails
2020-11-01 11:43:13 +01:00
Jens Rey
c8e83737e0 Feature: Allow images to be inserted as thumbnails or as linked thumbnails 2020-10-30 16:06:14 +01:00
369 changed files with 21031 additions and 14542 deletions

View file

@ -1,3 +1,5 @@
Please follow the next steps. The issue will be closed if the following steps are not completed. Thank you. (You can remove this line).
### Describe your problem
Complete here.
@ -8,9 +10,9 @@ Complete here.
Complete here.
### PHP version
If you do not know delete this line.
If you do not know remove this line.
### PHP logs
If you do not know delete this line.
If you do not know remove 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`.

3
.gitignore vendored
View file

@ -1,6 +1,7 @@
.DS_Store
dbgenerator.php
bl-content/*
!bl-content/.keep
bl-content-migrator
bl-plugins/timemachine
bl-plugins/timemachine-x
@ -29,5 +30,3 @@ bl-themes/tagg
bl-themes/small
bl-themes/future-imperfect
bl-themes/social-network
Dockerfile
conf/*

7
.prettierrc Normal file
View file

@ -0,0 +1,7 @@
{
"semi": true,
"singleQuote": true,
"useTabs": false,
"tabWidth": 2,
"printWidth": 100
}

View file

@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2015-2021 Diego Najar
Copyright (c) 2015-2023 Diego Najar
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View file

@ -1,36 +1,52 @@
[Bludit](https://www.bludit.com/)
================================
# [Bludit](https://www.bludit.com/)
Dear developers
-------
Bludit the Simple, Fast, and Flexible CMS.
## Frameworks and libraries included in Bludit v4
Bludit will include the following frameworks, please use them with they native functions.
With Bludit, you can build your own website or blog in just seconds. Its completely free, open-source, and easy to use. Bludit stores content in JSON format, eliminating the need for database installation or configuration. All you need is a web server with PHP support.
Frontend:
- Bootstrap v5.
- Boostrap icons.
- jQuery, you can use vanilla Javascript but for events in the views please use jQuery.
As a Flat-File CMS, Bludit offers unparalleled flexibility and speed. Plus, with support for both Markdown and HTML code, creating and managing content has never been easier.
Backend:
- `bl-kernel/functions.php` provides the global function for Bludit; These functions provide connectivity between different objects and databases; These functions should provide different checks and logic before add/edit/delete into the databases.
- PHP SimpleImage for processing images: https://github.com/claviska/SimpleImage
## Resources
## Comments for functions and methods
Please add the following structure commenting what it does the function, also add the stamp `=== Bludit v4` so I know what is new.
```
/**
* Create a new category. === Bludit v4
* @param array $args [string $name, string $template, string $description]
* @return string|bool Returns the category key on successful create, FALSE otherwise
*/
function createCategory($args) {
...
}
```
- [Plugins](https://plugins.bludit.com)
- [Themes](https://themes.bludit.com)
- [Documentation](https://docs.bludit.com)
- News and announcement on [Twitter](https://twitter.com/bludit), [Facebook](https://www.facebook.com/bluditcms), and [Reddit](https://www.reddit.com/r/bludit/)
- Talk & Chat on [Discord](https://discord.gg/CFaXEdZWds)
- Help and Support on [Forum](https://forum.bludit.org)
- Bugs reports on [Github Issues](https://github.com/bludit/bludit/issues)
Documentation for Bludit v4
-------
There is a new branch for the Documentation in english for Bludit v4.
## Requirements
https://github.com/bludit/documentation-english/tree/v4.0
- Webserver with PHP support.
- PHP v5.6 or higher version.
- PHP [mbstring](http://php.net/manual/en/book.mbstring.php) module for full UTF-8 support.
- PHP [gd](http://php.net/manual/en/book.image.php) module for image processing.
- PHP [dom](http://php.net/manual/en/book.dom.php) module for DOM manipulation.
- PHP [json](http://php.net/manual/en/book.json.php) module for JSON manipulation.
## Installation
1. Download the latest version from the official page: [Bludit.com](https://www.bludit.com)
2. Extract the zip file into a directory, such as `bludit`.
3. Upload the `bludit` directory to your web server or hosting.
4. Visit your domain (e.g., https://example.com/bludit/).
5. Follow the Bludit Installer to set up your website.
## Quick installation for testing
You can use PHP Built-in web server (`php -S localhost:8000`) or [Docker image](https://hub.docker.com/r/bludit/docker/)
## Support Bludit
Bludit is open-source and free to use, but if you find the project useful and would like to support its development, you can contribute on [Patreon](https://www.patreon.com/bePatron?c=921115&rid=2458860). As a token of our appreciation, supporters will receive Bludit PRO.
If you prefer, you can also make a one-time donation to buy us a coffee or beer. Every contribution helps us continue to improve Bludit and provide the best possible experience for our users.
- [PayPal](https://www.paypal.me/bludit/10)
- BTC (Network BTC): bc1qtets5pdj73uyysjpegfh2gar4pfywra4rglcph
- ETH (Network ETH): 0x0d7D58D848aA5f175D75Ce4bC746bAC107f331b7
## License
Bludit is open source software licensed under the [MIT license](https://tldrlegal.com/license/mit-license).

0
bl-content/.keep Normal file
View file

View file

@ -61,10 +61,7 @@ class dbJSON {
return $this->dbFields[$field];
}
/* Save the JSON file
@return boolean Returns TRUE if the file was saved successfully, FALSE otherwise
*/
// Save the JSON file
public function save()
{
$data = '';
@ -82,7 +79,7 @@ class dbJSON {
if (file_put_contents($this->file, $data, LOCK_EX)) {
return true;
} else {
Log::set(__METHOD__.LOG_SEP.'An error occurred while trying to save the database.', LOG_TYPE_ERROR);
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to save the database file.', LOG_TYPE_ERROR);
return false;
}
}

View file

@ -75,35 +75,22 @@ class dbList extends dbJSON
return $key;
}
/* Add a new item to the dblist === Bludit v4
@args array The array $args supports the following keys 'name', 'template', 'description', list'
@return string/boolean Returns the item's key if the item was successfully added, FALSE otherwise
*/
// Add a new item to the dblist
// $args => 'name', 'template', 'description', list'
public function add($args)
{
$key = $this->generateKey($args['name']);
if ($this->exists($key)) {
Log::set(__METHOD__.LOG_SEP.'The item already exists. Key: '.$key);
return false;
}
$this->db[$key]['name'] = Sanitize::removeTags($args['name']);
$this->db[$key]['template'] = isset($args['template'])?Sanitize::removeTags($args['template']):'';
$this->db[$key]['description'] = isset($args['description'])?Sanitize::removeTags($args['description']):'';
$this->db[$key]['list'] = isset($args['list'])?$args['list']:array();
$this->db[$key]['name'] = Sanitize::removeTags($args['name']);
$this->db[$key]['template'] = isset($args['template'])?Sanitize::removeTags($args['template']):'';
$this->db[$key]['description'] = isset($args['description'])?Sanitize::removeTags($args['description']):'';
$this->db[$key]['list'] = isset($args['list'])?$args['list']:array();
$this->sortAlphanumeric();
$this->save();
return $key;
}
/* Delete an item from the dblist === Bludit v4
@key string Key of the item to be deleted
@return boolean Returns TRUE if the database was successfully saved, FALSE otherwise
*/
public function remove($key)
{
if (!isset($this->db[$key])) {
@ -189,21 +176,16 @@ class dbList extends dbJSON
return false;
}
/* Returns an array with a portion of the database filtered by key === Bludit v4
@key string The item key
@return array/bool Returns the following structure array('key'=>'', 'name'=>'', 'template'=>'', 'description'=>'', list'=>array()), FALSE if the key doesn't exist
*/
// Returns an array with a portion of the database filtered by key
// Returns array( 'key'=>'', 'name'=>'', 'template'=>'', 'description'=>'', list'=>array() )
public function getMap($key)
{
if (!$this->exists($key)) {
Log::set(__METHOD__.LOG_SEP.'The item doesn\'t exist. Key: '.$key);
return false;
if (isset($this->db[$key])) {
$tmp = $this->db[$key];
$tmp['key'] = $key;
return $tmp;
}
$tmp = $this->db[$key];
$tmp['key'] = $key;
return $tmp;
return false;
}
}

View file

@ -1,6 +1,7 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
class Plugin {
class Plugin
{
// (string) directory name, just the name
// Ex: sitemap
@ -55,10 +56,10 @@ class Plugin {
// Init empty database with default values
$this->db = $this->dbFields;
$this->filenameDb = PATH_PLUGINS_DATABASES.$this->directoryName.DS.'db.php';
$this->filenameDb = PATH_PLUGINS_DATABASES . $this->directoryName . DS . 'db.php';
// --- Metadata ---
$this->filenameMetadata = PATH_PLUGINS.$this->directoryName().DS.'metadata.json';
$this->filenameMetadata = PATH_PLUGINS . $this->directoryName() . DS . 'metadata.json';
$metadataString = file_get_contents($this->filenameMetadata);
$this->metadata = json_decode($metadataString, true);
@ -79,44 +80,44 @@ class Plugin {
public function includeCSS($filename)
{
return '<link rel="stylesheet" type="text/css" href="'.$this->domainPath().'css/'.$filename.'?version='.BLUDIT_VERSION.'">'.PHP_EOL;
return '<link rel="stylesheet" type="text/css" href="' . $this->domainPath() . 'css/' . $filename . '?version=' . BLUDIT_VERSION . '">' . PHP_EOL;
}
public function includeJS($filename)
{
return '<script charset="utf-8" src="'.$this->domainPath().'js/'.$filename.'?version='.BLUDIT_VERSION.'"></script>'.PHP_EOL;
return '<script charset="utf-8" src="' . $this->domainPath() . 'js/' . $filename . '?version=' . BLUDIT_VERSION . '"></script>' . PHP_EOL;
}
// Returns absolute URL and path of the plugin directory
// This function helps to include CSS or Javascript files with absolute URL
public function domainPath()
{
return DOMAIN_PLUGINS.$this->directoryName.'/';
return DOMAIN_PLUGINS . $this->directoryName . '/';
}
// Returns relative path of the plugin directory
// This function helps to include CSS or Javascript files with relative URL
public function htmlPath()
{
return HTML_PATH_PLUGINS.$this->directoryName.'/';
return HTML_PATH_PLUGINS . $this->directoryName . '/';
}
// Returns absolute path of the plugin directory
// This function helps to include PHP libraries or some file at server level
public function phpPath()
{
return PATH_PLUGINS.$this->directoryName.DS;
return PATH_PLUGINS . $this->directoryName . DS;
}
public function phpPathDB()
{
return PATH_PLUGINS_DATABASES.$this->directoryName.DS;
return PATH_PLUGINS_DATABASES . $this->directoryName . DS;
}
// Returns the value of the key from the metadata of the plugin, FALSE if the key doesn't exist
public function getMetadata($key)
{
if(isset($this->metadata[$key])) {
if (isset($this->metadata[$key])) {
return $this->metadata[$key];
}
@ -133,7 +134,7 @@ class Plugin {
// Returns the value of the field from the database
// (string) $field
// (boolean) $html, TRUE returns the value sanitized, FALSE unsanitized
public function getValue($field, $html=true)
public function getValue($field, $html = true)
{
if (isset($this->db[$field])) {
if ($html) {
@ -170,11 +171,6 @@ class Plugin {
return $this->getMetadata('email');
}
public function type()
{
return $this->getMetadata('type');
}
public function website()
{
return $this->getMetadata('website');
@ -209,9 +205,9 @@ class Plugin {
{
$bluditRoot = explode('.', BLUDIT_VERSION);
$compatible = explode(',', $this->getMetadata('compatible'));
foreach( $compatible as $version ) {
foreach ($compatible as $version) {
$root = explode('.', $version);
if( $root[0]==$bluditRoot[0] && $root[1]==$bluditRoot[1] ) {
if ($root[0] == $bluditRoot[0] && $root[1] == $bluditRoot[1]) {
return true;
}
}
@ -224,7 +220,7 @@ class Plugin {
}
// Return TRUE if the installation success, otherwise FALSE.
public function install($position=1)
public function install($position = 1)
{
if ($this->installed()) {
return false;
@ -235,11 +231,11 @@ class Plugin {
mkdir($workspace, DIR_PERMISSIONS, true);
// Create plugin directory for the database
mkdir(PATH_PLUGINS_DATABASES.$this->directoryName, DIR_PERMISSIONS, true);
mkdir(PATH_PLUGINS_DATABASES . $this->directoryName, DIR_PERMISSIONS, true);
$this->dbFields['position'] = $position;
// Sanitize default values to store in the file
foreach ($this->dbFields as $key=>$value) {
foreach ($this->dbFields as $key => $value) {
$value = Sanitize::html($value);
settype($value, gettype($this->dbFields[$key]));
$this->db[$key] = $value;
@ -252,7 +248,7 @@ class Plugin {
public function uninstall()
{
// Delete database
$path = PATH_PLUGINS_DATABASES.$this->directoryName;
$path = PATH_PLUGINS_DATABASES . $this->directoryName;
Filesystem::deleteRecursive($path);
// Delete workspace
@ -271,7 +267,7 @@ class Plugin {
public function workspace()
{
return PATH_WORKSPACES.$this->directoryName.DS;
return PATH_WORKSPACES . $this->directoryName . DS;
}
public function init()
@ -289,11 +285,14 @@ class Plugin {
public function post()
{
$args = $_POST;
foreach ($this->dbFields as $field=>$value) {
foreach ($this->dbFields as $field => $value) {
if (isset($args[$field])) {
$finalValue = Sanitize::html( $args[$field] );
if ($finalValue==='false') { $finalValue = false; }
elseif ($finalValue==='true') { $finalValue = true; }
$finalValue = Sanitize::html($args[$field]);
if ($finalValue === 'false') {
$finalValue = false;
} elseif ($finalValue === 'true') {
$finalValue = true;
}
settype($finalValue, gettype($value));
$this->db[$field] = $finalValue;
}
@ -301,18 +300,9 @@ class Plugin {
return $this->save();
}
public function configure($args)
public function type()
{
foreach ($this->db as $field=>$value) {
if (isset($args[$field])) {
$finalValue = Sanitize::html( $args[$field] );
if ($finalValue==='false') { $finalValue = false; }
elseif ($finalValue==='true') { $finalValue = true; }
settype($finalValue, gettype($value));
$this->db[$field] = $finalValue;
}
}
return $this->save();
return $this->getMetadata('type');
}
public function setField($field, $value)
@ -328,7 +318,7 @@ class Plugin {
// Returns the parameters after the URI, FALSE if the URI doesn't match with the webhook
// Example: https://www.mybludit.com/api/foo/bar
public function webhook($URI=false, $returnsAfterURI=false, $fixed=true)
public function webhook($URI = false, $returnsAfterURI = false, $fixed = true)
{
global $url;
@ -337,10 +327,10 @@ class Plugin {
}
// Check URI start with the webhook
$startString = HTML_PATH_ROOT.$URI;
$startString = HTML_PATH_ROOT . $URI;
$URI = $url->uri();
$length = mb_strlen($startString, CHARSET);
if (mb_substr($URI, 0, $length)!=$startString) {
if (mb_substr($URI, 0, $length) != $startString) {
return false;
}
@ -349,7 +339,7 @@ class Plugin {
if ($fixed) {
return false;
}
if ($afterURI[0]!='/') {
if ($afterURI[0] != '/') {
return false;
}
}
@ -358,8 +348,7 @@ class Plugin {
return $afterURI;
}
Log::set(__METHOD__.LOG_SEP.'Webhook requested.');
Log::set(__METHOD__ . LOG_SEP . 'Webhook requested.');
return true;
}
}
}

View file

@ -1,16 +1,4 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================
// Authorization
// ============================================================================
// ============================================================================
// Functions
// ============================================================================
// ============================================================================
// Main
// ============================================================================
// HTML <title>
// Title of the page
$layout['title'] = $L->g('About') . ' - ' . $layout['title'];

View file

@ -0,0 +1,40 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================
// Check role
// ============================================================================
checkRole(array('admin'));
// ============================================================================
// Functions
// ============================================================================
// ============================================================================
// Main before POST
// ============================================================================
// ============================================================================
// POST Method
// ============================================================================
// ============================================================================
// Main after POST
// ============================================================================
activatePlugin('pluginAPI');
$apiURL = DOMAIN_BASE.'api/';
$pluginAPI = getPlugin('pluginAPI');
$apiToken = $pluginAPI->getToken();
$username = $login->username();
$admin = new User($username);
$authToken = $admin->tokenAuth();
$output = array(
'apiURL'=>$apiURL,
'username'=>$username,
'apiToken'=>$apiToken,
'authToken'=>$authToken
);
exit(json_encode($output));
?>

View file

@ -1,7 +1,7 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================
// Authorization
// Check role
// ============================================================================
checkRole(array('admin'));
@ -11,8 +11,16 @@ checkRole(array('admin'));
// ============================================================================
// ============================================================================
// Main
// Main before POST
// ============================================================================
// HTML <title>
$layout['title'] = $L->g('Categories') . ' - ' . $layout['title'];
// ============================================================================
// POST Method
// ============================================================================
// ============================================================================
// Main after POST
// ============================================================================
// Title of the page
$layout['title'] .= ' - '.$L->g('Categories');

View file

@ -0,0 +1,53 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================
// Check role
// ============================================================================
checkRole(array('admin'));
// ============================================================================
// Functions
// ============================================================================
// ============================================================================
// Main before POST
// ============================================================================
$plugin = false;
$pluginClassName = $layout['parameters'];
// Check if the plugin exists
if (isset($plugins['all'][$pluginClassName])) {
$plugin = $plugins['all'][$pluginClassName];
} else {
Redirect::page('plugins');
}
// Check if the plugin has the method form()
if (!method_exists($plugin, 'form')) {
Redirect::page('plugins');
}
// ============================================================================
// POST Method
// ============================================================================
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// Add to syslog
$syslog->add(array(
'dictionaryKey'=>'plugin-configured',
'notes'=>$plugin->name()
));
// Call the method post of the plugin
$plugin->post();
Alert::set( $L->g('The changes have been saved') );
Redirect::page('configure-plugin/'.$plugin->className());
}
// ============================================================================
// Main after POST
// ============================================================================
// Title of the page
$layout['title'] = $L->g('Plugin').' - '.$plugin->name().' - '.$layout['title'];

View file

@ -1,7 +1,7 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================
// Authorization
// Check role
// ============================================================================
checkRole(array('admin', 'editor', 'author'));
@ -10,7 +10,7 @@ checkRole(array('admin', 'editor', 'author'));
// Functions
// ============================================================================
// Returns the content belongs to the current logged user
// Returns the content belongs to the current user if the user has the role Editor
function filterContentOwner($list) {
global $login;
global $pages;
@ -24,7 +24,15 @@ function filterContentOwner($list) {
}
// ============================================================================
// Main
// Main before POST
// ============================================================================
// ============================================================================
// POST Method
// ============================================================================
// ============================================================================
// Main after POST
// ============================================================================
$published = $pages->getList($url->pageNumber(), ITEMS_PER_PAGE_ADMIN);
@ -32,8 +40,9 @@ $drafts = $pages->getDraftDB(true);
$scheduled = $pages->getScheduledDB(true);
$static = $pages->getStaticDB(true);
$sticky = $pages->getStickyDB(true);
$autosave = $pages->getAutosaveDB(true);
// If the user has the role "Author" filter the content so he/she can edit
// If the user is an Author filter the content he/she can edit
if (checkRole(array('author'), false)) {
$published = filterContentOwner($published);
$drafts = filterContentOwner($drafts);
@ -42,10 +51,10 @@ if (checkRole(array('author'), false)) {
$sticky = filterContentOwner($sticky);
}
// Check if the page number is out of range
// Check if out of range the pageNumber
if (empty($published) && $url->pageNumber()>1) {
Redirect::page('content');
}
// View HTML <title>
$layout['title'] = $L->g('Manage content') . ' - ' . $layout['title'];
// Title of the page
$layout['title'] .= ' - '.$L->g('Manage content');

View file

@ -1,16 +1,66 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================
// Authorization
// ============================================================================
// ============================================================================
// Functions
// ============================================================================
function updateBludit() {
global $site;
global $syslog;
// New installation
if ($site->currentBuild()==0) {
$site->set(array('currentBuild'=>BLUDIT_BUILD));
}
// Check if Bludit need to be update
if ( ($site->currentBuild() < BLUDIT_BUILD) || isset($_GET['update']) ) {
Log::set('UPDATE SYSTEM - Starting.');
// Updates only for version less than Bludit v3.0 rc-3
if ($site->currentBuild()<='20180910') {
@mkdir(PATH_WORKSPACES, DIR_PERMISSIONS, true);
$plugins = array('simple-stats', 'pluginRSS', 'pluginSitemap', 'pluginTimeMachineX', 'pluginBackup');
foreach ($plugins as $plugin) {
if (pluginActivated($plugin)) {
Log::set('UPDATE SYSTEM - Re-enable plugin: '.$plugin);
deactivatePlugin($plugin);
activatePlugin($plugin);
}
}
}
// Updates only for version less than Bludit v3.1
if ($site->currentBuild()<='20180921') {
@mkdir(PATH_UPLOADS_PAGES, DIR_PERMISSIONS, true);
$site->set(array('imageRelativeToAbsolute'=>true, 'imageRestrict'=>false));
}
// Set the current build number
$site->set(array('currentBuild'=>BLUDIT_BUILD));
Log::set('UPDATE SYSTEM - Finished.');
// Add to syslog
$syslog->add(array(
'dictionaryKey'=>'system-updated',
'notes'=>'Bludit v'.BLUDIT_VERSION
));
}
}
// ============================================================================
// Main
// Main before POST
// ============================================================================
// HTML <title>
$layout['title'] = $L->g('Dashboard') . ' - ' . $layout['title'];
// ============================================================================
// POST Method
// ============================================================================
// ============================================================================
// Main after POST
// ============================================================================
// Try update Bludit
updateBludit();
// Title of the page
$layout['title'] .= ' - '.$L->g('Dashboard');

View file

@ -1,7 +1,7 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================
// Authorization
// Check role
// ============================================================================
checkRole(array('admin'));
@ -11,9 +11,26 @@ checkRole(array('admin'));
// ============================================================================
// ============================================================================
// Main
// Main before POST
// ============================================================================
// ============================================================================
// POST Method
// ============================================================================
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if ($_POST['action']=='delete') {
deleteCategory($_POST);
} elseif ($_POST['action']=='edit') {
editCategory($_POST);
}
Redirect::page('categories');
}
// ============================================================================
// Main after POST
// ============================================================================
$categoryKey = $layout['parameters'];
if (!$categories->exists($categoryKey)) {
@ -23,5 +40,5 @@ if (!$categories->exists($categoryKey)) {
$categoryMap = $categories->getMap($categoryKey);
// HTML <title>
$layout['title'] = $L->g('Edit Category') . ' [ ' . $categoryMap['name'] . ' ] ' . ' - ' . $layout['title'];
// Title of the page
$layout['title'] .= ' - '.$L->g('Edit Category').' [ '.$categoryMap['name'] . ' ] ';

View file

@ -0,0 +1,86 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================
// Check role
// ============================================================================
if (checkRole(array('author'), false)) {
try {
$pageKey = isset($_POST['key']) ? $_POST['key'] : $layout['parameters'];
$page = new Page($pageKey);
} catch (Exception $e) {
Alert::set($L->g('You do not have sufficient permissions'));
Redirect::page('dashboard');
}
if ($page->username()!==$login->username()) {
// Add to syslog
$syslog->add(array(
'dictionaryKey'=>'access-denied',
'notes'=>$login->username()
));
Alert::set($L->g('You do not have sufficient permissions'));
Redirect::page('dashboard');
}
}
// ============================================================================
// Functions
// ============================================================================
// ============================================================================
// Main before POST
// ============================================================================
// ============================================================================
// POST Method
// ============================================================================
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if ($_POST['type']==='delete') {
if (deletePage($_POST['key'])) {
Alert::set( $L->g('The changes have been saved') );
}
} else {
$key = editPage($_POST);
if ($key!==false) {
Alert::set( $L->g('The changes have been saved') );
Redirect::page('edit-content/'.$key);
}
}
Redirect::page('content');
}
// ============================================================================
// Main after POST
// ============================================================================
try {
$pageKey = $layout['parameters'];
$page = new Page($pageKey);
} catch (Exception $e) {
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to get the page: '.$pageKey, LOG_TYPE_ERROR);
Redirect::page('content');
}
// Images prefix directory
define('PAGE_IMAGES_KEY', $page->uuid());
// Images and thubmnails directories
if (IMAGE_RESTRICT) {
define('PAGE_IMAGES_DIRECTORY', (IMAGE_RELATIVE_TO_ABSOLUTE? '' : HTML_PATH_UPLOADS_PAGES.PAGE_IMAGES_KEY.'/'));
define('PAGE_IMAGES_URL', (IMAGE_RELATIVE_TO_ABSOLUTE? '' : DOMAIN_UPLOADS_PAGES.PAGE_IMAGES_KEY.'/'));
define('PAGE_THUMBNAILS_DIRECTORY', PATH_UPLOADS_PAGES.PAGE_IMAGES_KEY.DS.'thumbnails'.DS);
define('PAGE_THUMBNAILS_HTML', HTML_PATH_UPLOADS_PAGES.PAGE_IMAGES_KEY.'/thumbnails/');
define('PAGE_THUMBNAILS_URL', DOMAIN_UPLOADS_PAGES.PAGE_IMAGES_KEY.'/thumbnails/');
} else {
define('PAGE_IMAGES_DIRECTORY', (IMAGE_RELATIVE_TO_ABSOLUTE? '' : HTML_PATH_UPLOADS));
define('PAGE_IMAGES_URL', (IMAGE_RELATIVE_TO_ABSOLUTE? '' : DOMAIN_UPLOADS));
define('PAGE_THUMBNAILS_DIRECTORY', PATH_UPLOADS_THUMBNAILS);
define('PAGE_THUMBNAILS_HTML', HTML_PATH_UPLOADS_THUMBNAILS);
define('PAGE_THUMBNAILS_URL', DOMAIN_UPLOADS_THUMBNAILS);
}
// Title of the page
$layout['title'] .= ' - '.$L->g('Edit content').' - '.$page->title();

View file

@ -1,15 +1,46 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================
// Authorization
// ============================================================================
// ============================================================================
// Functions
// ============================================================================
// ============================================================================
// Main
// Main before POST
// ============================================================================
// ============================================================================
// POST Method
// ============================================================================
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// Prevent non-administrators to change other users
if ($login->role()!=='admin') {
$_POST['username'] = $login->username();
unset($_POST['role']);
}
if (isset($_POST['deleteUserAndDeleteContent']) && ($login->role()==='admin')) {
$_POST['deleteContent'] = true;
deleteUser($_POST);
} elseif (isset($_POST['deleteUserAndKeepContent']) && ($login->role()==='admin')) {
$_POST['deleteContent'] = false;
deleteUser($_POST);
} elseif (isset($_POST['disableUser']) && ($login->role()==='admin')) {
disableUser(array('username'=>$_POST['username']));
} else {
editUser($_POST);
}
Alert::set($L->g('The changes have been saved'));
if ($login->role()==='admin') {
Redirect::page('users');
}
Redirect::page('edit-user/'.$login->username());
}
// ============================================================================
// Main after POST
// ============================================================================
$username = $layout['parameters'];
@ -25,5 +56,5 @@ try {
Redirect::page('users');
}
// HTML <title>
$layout['title'] = $L->g('Edit user') . ' - ' . $layout['title'];
// Title of the page
$layout['title'] = $L->g('Edit user').' - '.$layout['title'];

View file

@ -1,29 +0,0 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================
// Authorization
// ============================================================================
checkRole(array('admin', 'editor', 'author'));
// ============================================================================
// Functions
// ============================================================================
// ============================================================================
// Main
// ============================================================================
$pageKey = false;
if (!empty($layout['parameters'])) {
try {
$pageKey = $layout['parameters'];
$page = new Page($pageKey);
} catch (Exception $e) {
Log::set(__METHOD__.LOG_SEP.'An error occurred while trying to get the page: '.$pageKey, LOG_TYPE_ERROR);
Redirect::page('content');
}
}
// HTML <title>
$layout['title'] = $L->g('New content') . ' - ' . $layout['title'];

View file

@ -0,0 +1,39 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================
// Check role
// ============================================================================
checkRole(array('admin'));
// ============================================================================
// Functions
// ============================================================================
// ============================================================================
// Main before POST
// ============================================================================
// ============================================================================
// POST Method
// ============================================================================
// ============================================================================
// Main after POST
// ============================================================================
$pluginClassName = $layout['parameters'];
if (!activatePlugin($pluginClassName)) {
Log::set('Fail when try to activate the plugin.', LOG_TYPE_ERROR);
}
if (isset($plugins['all'][$pluginClassName])) {
$plugin = $plugins['all'][$pluginClassName];
} else {
Redirect::page('plugins');
}
if (method_exists($plugin, 'form')) {
Redirect::page('configure-plugin/'.$pluginClassName);
}
Redirect::page('plugins#'.$pluginClassName);

View file

@ -1,7 +1,7 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================
// Authorization
// Check role
// ============================================================================
checkRole(array('admin'));
@ -11,8 +11,22 @@ checkRole(array('admin'));
// ============================================================================
// ============================================================================
// Main
// Main before POST
// ============================================================================
// HTML <title>
$layout['title'] = $L->g('New user') . ' - ' . $layout['title'];
// ============================================================================
// POST Method
// ============================================================================
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (createCategory($_POST)) {
Redirect::page('categories');
}
}
// ============================================================================
// Main after POST
// ============================================================================
// Title of the page
$layout['title'] .= ' - '.$L->g('New category');

View file

@ -0,0 +1,52 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================
// Check role
// ============================================================================
checkRole(array('admin', 'editor', 'author'));
// ============================================================================
// Functions
// ============================================================================
// ============================================================================
// Main before POST
// ============================================================================
// ============================================================================
// POST Method
// ============================================================================
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
createPage($_POST);
Redirect::page('content');
}
// ============================================================================
// Main after POST
// ============================================================================
// UUID of the page is need it for autosave and media manager
$uuid = $pages->generateUUID();
// Images prefix directory
define('PAGE_IMAGES_KEY', $uuid);
// Images and thubmnails directories
if (IMAGE_RESTRICT) {
define('PAGE_IMAGES_DIRECTORY', (IMAGE_RELATIVE_TO_ABSOLUTE? '' : HTML_PATH_UPLOADS_PAGES.PAGE_IMAGES_KEY.'/'));
define('PAGE_IMAGES_URL', (IMAGE_RELATIVE_TO_ABSOLUTE? '' : DOMAIN_UPLOADS_PAGES.PAGE_IMAGES_KEY.'/'));
define('PAGE_THUMBNAILS_DIRECTORY', PATH_UPLOADS_PAGES.PAGE_IMAGES_KEY.DS.'thumbnails'.DS);
define('PAGE_THUMBNAILS_HTML', HTML_PATH_UPLOADS_PAGES.PAGE_IMAGES_KEY.'/thumbnails/');
define('PAGE_THUMBNAILS_URL', DOMAIN_UPLOADS_PAGES.PAGE_IMAGES_KEY.'/thumbnails/');
} else {
define('PAGE_IMAGES_DIRECTORY', (IMAGE_RELATIVE_TO_ABSOLUTE? '' : HTML_PATH_UPLOADS));
define('PAGE_IMAGES_URL', (IMAGE_RELATIVE_TO_ABSOLUTE? '' : DOMAIN_UPLOADS));
define('PAGE_THUMBNAILS_DIRECTORY', PATH_UPLOADS_THUMBNAILS);
define('PAGE_THUMBNAILS_HTML', HTML_PATH_UPLOADS_THUMBNAILS);
define('PAGE_THUMBNAILS_URL', DOMAIN_UPLOADS_THUMBNAILS);
}
// Title of the page
$layout['title'] = $L->g('New content').' - '.$layout['title'];

View file

@ -1,7 +1,7 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================
// Authorization
// Check role
// ============================================================================
checkRole(array('admin'));
@ -11,8 +11,22 @@ checkRole(array('admin'));
// ============================================================================
// ============================================================================
// Main
// Main before POST
// ============================================================================
// HTML <title>
$layout['title'] = $L->g('New category') . ' - ' . $layout['title'];
// ============================================================================
// POST Method
// ============================================================================
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (createUser($_POST)) {
Redirect::page('users');
}
}
// ============================================================================
// Main after POST
// ============================================================================
// Title of the page
$layout['title'] .= ' - '.$L->g('Add a new user');

View file

@ -1,7 +1,7 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================
// Authorization
// Check role
// ============================================================================
checkRole(array('admin'));
@ -11,8 +11,19 @@ checkRole(array('admin'));
// ============================================================================
// ============================================================================
// Main
// Main before POST
// ============================================================================
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
changePluginsPosition(explode(',',$_POST['plugin-list']));
Redirect::page('plugins-position');
}
// ============================================================================
// POST Method
// ============================================================================
// HTML <title>
$layout['title'] = $L->g('Plugin') . ' - ' . $layout['title'];
// ============================================================================
// Main after POST
// ============================================================================
// Title of the page
$layout['title'] .= ' - '.$L->g('Plugins');

View file

@ -1,7 +1,7 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================
// Authorization
// Check role
// ============================================================================
checkRole(array('admin'));
@ -11,8 +11,16 @@ checkRole(array('admin'));
// ============================================================================
// ============================================================================
// Main
// Main before POST
// ============================================================================
// HTML <title>
$layout['title'] = $L->g('Plugins') . ' - ' . $layout['title'];
// ============================================================================
// POST Method
// ============================================================================
// ============================================================================
// Main after POST
// ============================================================================
// Title of the page
$layout['title'] .= ' - '.$L->g('Plugins');

View file

@ -1,7 +1,7 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================
// Authorization
// Check role
// ============================================================================
checkRole(array('admin'));
@ -11,8 +11,21 @@ checkRole(array('admin'));
// ============================================================================
// ============================================================================
// Main
// Main after POST
// ============================================================================
// HTML <title>
$layout['title'] = $L->g('Settings') . ' - ' . $layout['title'];
// ============================================================================
// POST Method
// ============================================================================
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
editSettings($_POST);
Redirect::page('settings');
}
// ============================================================================
// Main after POST
// ============================================================================
// Title of the page
$layout['title'] .= ' - '.$L->g('Advanced Settings');

View file

@ -21,4 +21,4 @@ checkRole(array('admin'));
$themes = buildThemes();
// Title of the page
$layout['title'] = $L->g('Themes') . ' - ' . $layout['title'];
$layout['title'] .= ' - '.$L->g('Themes');

View file

@ -1,7 +1,7 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================
// Authorization
// Check role
// ============================================================================
checkRole(array('admin'));
@ -11,23 +11,16 @@ checkRole(array('admin'));
// ============================================================================
// ============================================================================
// Main
// Main before POST
// ============================================================================
$plugin = false;
// ============================================================================
// POST Method
// ============================================================================
// ============================================================================
// Main after POST
// ============================================================================
$pluginClassName = $layout['parameters'];
// Check if the plugin is installed/activated
if (pluginActivated($pluginClassName)) {
$plugin = $plugins['all'][$pluginClassName];
} else {
Redirect::page('plugins');
}
// Check if the plugin has the method form()
if (!method_exists($plugin, 'form')) {
Redirect::page('plugins');
}
// HTML <title>
$layout['title'] = $L->g('Plugin'). ' [ ' .$plugin->name(). ' ] ' . ' - ' . $layout['title'];
deactivatePlugin($pluginClassName);
Redirect::page('plugins');

View file

@ -0,0 +1,51 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================
// Functions
// ============================================================================
// ============================================================================
// Main before POST
// ============================================================================
// ============================================================================
// POST Method
// ============================================================================
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// Prevent non-administrators to change other users
$username = $_POST['username'];
if ($login->role()!=='admin') {
$username = $login->username();
}
if (changeUserPassword(array(
'username'=>$username,
'newPassword'=>$_POST['newPassword'],
'confirmPassword'=>$_POST['confirmPassword']
))) {
if ($login->role()==='admin') {
Redirect::page('users');
}
Redirect::page('edit-user/'.$login->username());
}
}
// ============================================================================
// Main after POST
// ============================================================================
// Prevent non-administrators to change other users
if ($login->role()!=='admin') {
$layout['parameters'] = $login->username();
}
try {
$username = $layout['parameters'];
$user = new User($username);
} catch (Exception $e) {
Redirect::page('users');
}
// Title of the page
$layout['title'] = $L->g('Change password').' - '.$layout['title'];

View file

@ -1,7 +1,7 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================
// Authorization
// Check role
// ============================================================================
checkRole(array('admin'));
@ -11,8 +11,21 @@ checkRole(array('admin'));
// ============================================================================
// ============================================================================
// Main
// Main after POST
// ============================================================================
// HTML <title>
$layout['title'] = $L->g('Users') . ' - ' . $layout['title'];
// ============================================================================
// POST Method
// ============================================================================
if( $_SERVER['REQUEST_METHOD'] == 'POST' )
{
$site->set($_POST);
}
// ============================================================================
// Main after POST
// ============================================================================
// Title of the page
$layout['title'] .= ' - '.$L->g('Users');

View file

@ -1,46 +0,0 @@
html {
font-size: 0.9rem;
}
.link {
text-decoration: underline;
}
/*
Left sidebar
*/
div.sidebar .nav-item a {
padding-left: 0;
padding-right: 0;
padding-top: 5px;
padding-bottom: 5px;
}
div.sidebar .nav-item h4 {
font-size: 1.2em;
text-transform: uppercase;
font-weight: 400;
margin-top: 10px;
}
/*
Editor
*/
#btnCurrenType {
cursor: pointer;
}
.link {
cursor: pointer;
text-decoration: underline;
}
/** Tables
*/
tr.disabled{
filter: blur(1px);
pointer-events: none;
}

View file

@ -1,12 +0,0 @@
/* Remove Focus glow */
.btn:focus,
.form-control:focus,
.form-select:focus {
outline: none !important;
box-shadow: none !important;
}
/* Icons */
.bi {
margin-right: .5rem!important;
}

View file

@ -1,142 +0,0 @@
body {
background-color: #1C1C1E;
color: #b3b3b3;
}
.bg-dark {
background-color: #111111 !important;
}
.bg-light {
background-color: #111111 !important;
}
.bg-info {
background-color: #003c58!important;
}
a,
a.nav-link,
.link,
a.dropdown-menu,
.dropdown-item {
color: #b3b3b3;
}
a:hover,
a.nav-link:hover,
.link:hover {
color: #e2e2e2 !important
}
.form-text {
color: #989899 !important;
}
.form-control:disabled, .form-control[readonly] {
background-color: #444;
}
.color-blue {
color: #688bbd !important;
}
.btn {
color: #e0e0e0;
}
.btn-outline-primary {
color: #688bbd !important;
border-color: #688bbd !important;
}
.btn-outline-primary:hover {
background-color: #1C1C1E !important;
color: #fff !important;
}
.page-link {
color: #688bbd !important;
border-color: #688bbd !important;
background-color: #1C1C1E !important;
}
.form-control,
.form-select {
background-color: #111111;
border-color: #302F33;
color: #b3b3b3;
}
.form-control:focus,
.form-select:focus {
background-color: #111111;
border-color: #302F33;
color: #b3b3b3;
}
.nav-tabs .nav-item.show .nav-link,
.nav-tabs .nav-link.active {
background-color: #1C1C1E !important;
border-color: #302F33 !important;
color: #b3b3b3 !important;
}
.nav-tabs .nav-link:focus,
.nav-tabs .nav-link:hover {
border-color: #302F33 !important;
}
.nav-tabs {
border-bottom-color:#302F33 !important;
}
.table {
color: #b3b3b3 !important;
border-bottom-color:#302F33 !important;
}
.table-striped>tbody>tr:nth-of-type(odd) {
background-color: #171717;
color: #b3b3b3;
}
.border-bottom {
border-bottom-color:#302F33 !important;
}
.alert-primary {
background-color: #191e27;
border-color: #232a35;
color: #b3b3b3;
}
.modal-content {
background-color: #121212 !important;
color: #b3b3b3 !important;
border-color: #2f3233;
}
.modal-footer {
border-top-color: #302F33;
}
.dropdown-menu {
background-color: #121212 !important;
color: #b3b3b3 !important;
}
.list-group-item {
background-color: inherit;
color: #b3b3b3;
border: 0 none;
}
.list-group-item a {
text-decoration: none;
}
.border-top,
.border-bottom {
border-color: #302F33 !important;
}

View file

@ -1,40 +0,0 @@
body {
background-color: #f1f1f1;
}
a,
a.nav-link,
.link {
color: #555;
}
a:hover,
a.nav-link:hover,
.link:hover {
color: #0a58ca;
}
.form-control:focus,
.form-select:focus {
border-color: #999999;
}
.btn-primary-disabled {
background-color: #4792ff !important;
border-color: #4792ff !important;
}
.nav-tabs .nav-item.show .nav-link,
.nav-tabs .nav-link.active {
background-color: #d8d8d8;
border-color: #dee2e6;
}
.list-group-item {
background-color: inherit;
border: 0 none;
}
.list-group-item a {
text-decoration: none;
}

View file

@ -0,0 +1,58 @@
a {
color: #0078D4;
}
a:hover {
color: #003f6f;
text-decoration: none;
}
.bg-success {
background-color: #8BC34A!important;
}
.text-primary {
color: #0078D4!important;
}
.text-danger {
color: #D40000!important;
}
a.text-danger:focus,
a.text-danger:hover {
color: #790000!important;
}
/* Buttons */
.btn-primary {
background-color: #0078D4;
border-color: #0078D4;
}
.btn-primary:hover {
background-color: #4585CF;
border-color: #4a90e2;
}
.btn-light.focus, .btn-light:focus {
box-shadow: none;
}
.btn.focus, .btn:focus {
box-shadow: none;
}
/* Form */
.form-control:focus {
box-shadow: none;
}
/* Tables */
.table-striped tbody tr:nth-of-type(odd) {
background-color: rgba(0, 0, 0, 0.02);
}
.table thead th {
font-size: 0.8em;
text-transform: uppercase!important;
}

View file

@ -0,0 +1,367 @@
html {
height: 100%;
font-size: 0.9rem;
background: #fcfcfc;
}
body {
background: #fcfcfc;
}
/* Prevent events in iframes */
/* iframe{
pointer-events: none;
} */
/*
ICONS
*/
.fa {
margin-right: .5rem !important;
line-height: inherit;
}
/*
SIDEBAR
*/
div.sidebar .nav-item a {
padding-left: 0;
padding-right: 0;
color: #555;
padding-top: 5px;
padding-bottom: 5px;
}
div.sidebar .nav-item a:hover {
color: #0078D4;
}
div.sidebar .nav-item h4 {
font-size: 1.2em;
text-transform: uppercase;
font-weight: 400;
margin-top: 10px;
}
/*
AUTOCOMPLETE SEARCH
*/
.search-suggestion {
padding: 5px;
}
.search-suggestion-options {
font-size: 0.9em;
padding-top: 2px;
}
/*
BOOTSTRAP Hacks
*/
@media (min-width: 1200px) {
.container {
max-width: 1250px;
}
}
/* for small devices */
@media (max-width: 575.98px) {
#jsmediaManagerButton,
#jscategoryButton,
#jsdescriptionButton {
width: 100%;
text-align: left;
}
}
.btn-light {
color: #212529;
background-color: #f3f3f3;
border-color: #ced4d9;
}
.btn-form {
background-color: #F3F3F3;
border-color: #DDD;
color: #000;
}
.btn-form:hover {
background-color: rgb(228, 228, 228);
border-color: #DDD;
color: #000;
}
code {
padding: 3px 5px 2px;
margin: 0 1px;
background: #eaeaea;
background: rgba(0, 0, 0, .07);
color: #444;
}
.list-group-sortable {
cursor: pointer;
}
.modal-body {
padding: 2rem;
}
.modal-footer {
background-color: rgb(247, 247, 247);
}
.modal-dialog .btn-link {
color: #000;
}
/*
LOGIN
*/
body.login {
background: rgb(255, 255, 255);
background: linear-gradient(0deg, rgba(255, 255, 255, 1) 0%, rgba(250, 250, 250, 1) 53%);
height: 100%;
}
/*
DASHBOARD
*/
#dashboard ul.list-group.list-group-striped li {
border: none;
word-break: break-word;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
#dashboard ul.list-group.list-group-striped li:nth-of-type(even) {
background: #f1f1f1;
}
#dashboard div.quick-links-icons {
font-size: 3em;
width: 100%;
}
#dashboard a.quick-links {
color: #777;
}
#dashboard a.quick-links:hover {
text-decoration: none;
color: #4586d4;
}
#hello-message {
padding: 10px 0;
margin-bottom: 20px;
}
#hello-message span.oi {
top: 3px;
}
.ct-series-a .ct-line {
/* Set the colour of this series line */
stroke: #4a90e2;
/* Control the thikness of your lines */
stroke-width: 2px;
/* Create a dashed line with a pattern */
}
.ct-series-a .ct-point {
/* Colour of your points */
stroke: #4a90e2;
/* Size of your points */
stroke-width: 8px;
}
/*
ALERT
*/
#alert {
display: none;
position: fixed;
text-align: center;
border-radius: 0px;
border: 0;
z-index: 1000;
bottom: 0;
right: 0;
margin: 0;
}
.alert-success {
background-color: #4586d4;
border-left: 6px solid #abd1ff !important;
color: #ffffff;
}
.alert-danger {
background-color: #d44545;
border-left: 6px solid #ff9c9c !important;
color: #ffffff;
}
/*
PLUGINS
*/
.plugin-form label {
display: block;
margin-top: 1rem !important;
}
.plugin-form input[type="text"],
.plugin-form textarea,
.plugin-form select {
display: block;
width: 100%;
padding: .375rem .75rem;
font-size: 1rem;
line-height: 1.5;
color: #495057;
background-color: #fff;
background-clip: padding-box;
border: 1px solid #ced4da;
border-radius: .25rem;
transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out;
}
.plugin-form textarea {
min-height: 120px;
}
.plugin-form span.tip {
display: block;
font-size: 80%;
font-weight: 400;
margin-top: .25rem;
color: #6c757d !important;
}
/*
Manage > Content
*/
td.child {
padding-left: 30px;
}
/*
Manage > New Content
*/
#jseditor {
background: #fff;
padding: 10px 5% !important;
font-size: 16px;
line-height: 1.5em;
border: 1px solid #ced4da;
}
#jseditorSidebar {
display: none;
height: calc(100% - 45px);
width: 50%;
max-width: 350px;
position: absolute;
z-index: 50;
top: 45px;
right: 15px;
background-color: #fff;
overflow-x: hidden;
transition: 0.5s;
border-left: 1px solid #ccc;
border-right: 1px solid #ccc;
border-top: 1px solid #ccc;
}
@media (max-width: 575.98px) {
#jseditorSidebar {
width: 100%;
max-width: 100%;
right: 0;
}
#jseditorToolbarRight button {
font-size: 0px !important;
}
#jseditorToolbarRight button span {
font-size: 16px !important;
}
.contentTools .btn {
font-size: 0px !important;
margin-right: 5px;
}
.contentTools .btn span {
font-size: 16px !important;
}
}
#jseditorSidebar nav {
background: #f3f3f3;
}
#jseditorSidebar nav a {
color: #000;
}
#jseditorSidebar .nav-tabs .nav-link {
border: none;
}
#jseditorSidebar .nav-link.active {
background: none;
border: none;
border-bottom: 3px solid #ccc;
}
#jsshadow {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgba(72, 72, 72, 0.7);
z-index: 10;
display: none;
}
img.profilePicture {
width: 30px;
height: 30px;
border-radius: 30px;
border: 1px solid #ccc;
}
/* Switch button */
.switch-button {
font-size: 0.9em;
text-transform: uppercase;
cursor: pointer;
}
.switch-icon-publish {
color: #1cb11c;
}

View file

@ -0,0 +1,17 @@
<script charset="utf-8">
function showAlert(text) {
console.log("[INFO] Function showAlert() called.");
$("#alert").html(text);
$("#alert").slideDown().delay(<?php echo ALERT_DISAPPEAR_IN*1000 ?>).slideUp();
}
<?php if (Alert::defined()): ?>
setTimeout(function(){ showAlert("<?php echo Alert::get() ?>") }, 500);
<?php endif; ?>
$(window).click(function() {
$("#alert").hide();
});
</script>
<div id="alert" class="alert <?php echo (Alert::status()==ALERT_STATUS_FAIL)?'alert-danger':'alert-success' ?>"></div>

View file

@ -1,31 +0,0 @@
<div aria-live="polite" aria-atomic="true" class="position-relative">
<div class="toast-container position-absolute start-50 translate-middle-x mt-3" style="z-index:1050;">
<div id="alert" class="toast text-center text-white border-0 p-3" role="alert" aria-live="assertive" aria-atomic="true">
Hello, I'm a Bludit alert!
</div>
</div>
</div>
<script>
function showAlert(text, background='primary') {
$('#alert').removeClass('bg-danger bg-warning bg-primary').addClass('bg-'+background);
$('#alert').html(text);
$('#alert').toast('show');
}
function showAlertError(text) {
showAlert(text, 'danger');
}
function showAlertWarning(text) {
showAlert(text, 'warning');
}
function showAlertInfo(text) {
showAlert(text, 'primary');
}
function hideAlert(text) {
$('#alert').toast('hide');
}
</script>

View file

@ -0,0 +1,262 @@
<?php
// Preload the first 10 files to not call via AJAX when the user open the first time the media manager
$listOfFilesByPage = Filesystem::listFiles(PAGE_THUMBNAILS_DIRECTORY, '*', '*', MEDIA_MANAGER_SORT_BY_DATE, MEDIA_MANAGER_NUMBER_OF_FILES);
$preLoadFiles = array();
if (!empty($listOfFilesByPage[0])) {
foreach ($listOfFilesByPage[0] as $file) {
$filename = Filesystem::filename($file);
array_push($preLoadFiles, $filename);
}
}
// Amount of pages for the paginator
$numberOfPages = count($listOfFilesByPage);
?>
<div id="jsmediaManagerModal" class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="container-fluid">
<div class="row">
<div class="col p-3">
<!--
UPLOAD INPUT
-->
<h3 class="mt-2 mb-3"><i class="fa fa-image"></i> <?php $L->p('Images'); ?></h3>
<div id="jsalertMedia" class="alert alert-warning d-none" role="alert"></div>
<!-- Form and Input file -->
<form name="bluditFormUpload" id="jsbluditFormUpload" enctype="multipart/form-data">
<div class="custom-file">
<input type="file" class="custom-file-input" id="jsimages" name="images[]" multiple>
<label class="custom-file-label" for="jsimages"><?php $L->p('Choose images to upload'); ?></label>
</div>
</form>
<!-- Progress bar -->
<div class="progress mt-3">
<div id="jsbluditProgressBar" class="progress-bar bg-primary" role="progressbar" style="width:0%"></div>
</div>
<!--
IMAGES LIST
-->
<!-- Table for list files -->
<table id="jsbluditMediaTable" class="table mt-3">
<tr>
<td><?php $L->p('There are no images'); ?></td>
</tr>
</table>
<!-- Paginator -->
<nav id="jsbluditMediaTablePagination"></nav>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
<?php
echo 'var preLoadFiles = '.json_encode($preLoadFiles).';';
?>
function openMediaManager() {
$('#jsmediaManagerModal').modal('show');
}
function closeMediaManager() {
$('#jsmediaManagerModal').modal('hide');
}
// Remove all files from the table
function cleanTable() {
$('#jsbluditMediaTable').empty();
}
function showMediaAlert(message) {
$("#jsalertMedia").html(message).removeClass('d-none');
}
function hideMediaAlert() {
$("#jsalertMedia").addClass('d-none');
}
// Show the files in the table
function displayFiles(files, numberOfPages = <?= $numberOfPages ?>) {
if (!Array.isArray(files)) {
return false;
}
// Clean table
cleanTable();
// Regenerate the table
if (files.length > 0) {
$.each(files, function(key, filename) {
var thumbnail = "<?php echo PAGE_THUMBNAILS_URL; ?>"+filename;
var image = "<?php echo PAGE_IMAGES_URL; ?>"+filename;
tableRow = '<tr id="js'+filename+'">'+
'<td style="width:80px"><img class="img-thumbnail" alt="200x200" src="'+thumbnail+'" style="width: 50px; height: 50px;"><\/td>'+
'<td class="information">'+
'<div class="text-secondary pb-2">'+filename+'<\/div>'+
'<div>'+
'<a href="#" class="mr-3 text-primary" onClick="editorInsertMedia(\''+image+'\'); closeMediaManager();"><i class="fa fa-plus-circle"></i><?php $L->p('Insert') ?><\/a>'+
'<a href="#" class="mr-3 text-primary" onClick="editorInsertMedia(\''+thumbnail+'\'); closeMediaManager();"><i class="fa fa-image"></i><?php $L->p('Insert thumbnail') ?><\/a>'+
'<a href="#" class="mr-3 text-primary" onClick="editorInsertLinkedMedia(\''+thumbnail+'\',\''+image+'\'); closeMediaManager();"><i class="fa fa-link"></i><?php $L->p('Insert linked thumbnail') ?><\/a>'+
'<a href="#" class="text-primary" onClick="setCoverImage(\''+filename+'\'); closeMediaManager();"><i class="fa fa-desktop"></i><?php $L->p('Set as cover image') ?><\/button>'+
'<a href="#" class="float-right text-danger" onClick="deleteMedia(\''+filename+'\')"><i class="fa fa-trash-o"></i><?php $L->p('Delete') ?><\/a>'+
'<\/div>'+
'<\/td>'+
'<\/tr>';
$('#jsbluditMediaTable').append(tableRow);
});
mediaPagination = '<ul class="pagination justify-content-center flex-wrap">';
for (var i = 1; i <= numberOfPages; i++) {
mediaPagination += '<li class="page-item"><button type="button" class="btn btn-link page-link" onClick="getFiles('+i+')">'+i+'</button></li>';
}
mediaPagination += '</ul>';
$('#jsbluditMediaTablePagination').html(mediaPagination);
}
if (files.length == 0) {
$('#jsbluditMediaTable').html("<p><?php (IMAGE_RESTRICT ? $L->p('There are no images for the page') : $L->p('There are no images')) ?></p>");
$('#jsbluditMediaTablePagination').html('');
}
}
// Get the list of files via AJAX, filter by the page number
function getFiles(pageNumber) {
$.post(HTML_PATH_ADMIN_ROOT+"ajax/list-images",
{ tokenCSRF: tokenCSRF,
pageNumber: pageNumber,
uuid: "<?php echo PAGE_IMAGES_KEY ?>",
path: "thumbnails" // the paths are defined in ajax/list-images
},
function(data) { // success function
if (data.status==0) {
displayFiles(data.files, data.numberOfPages);
} else {
console.log(data.message);
}
}
);
}
// Delete the file and the thumbnail if exist
function deleteMedia(filename) {
$.post(HTML_PATH_ADMIN_ROOT+"ajax/delete-image",
{ tokenCSRF: tokenCSRF,
filename: filename,
uuid: "<?php echo PAGE_IMAGES_KEY; ?>"
},
function(data) { // success function
if (data.status==0) {
getFiles(1);
} else {
console.log(data.message);
}
}
);
}
function setCoverImage(filename) {
var image = "<?php echo PAGE_IMAGES_URL; ?>"+filename;
$("#jscoverImage").val(filename);
$("#jscoverImagePreview").attr("src", image);
}
function uploadImages() {
// Remove current alerts
hideMediaAlert();
var images = $("#jsimages")[0].files;
for (var i=0; i < images.length; i++) {
// Check file type/extension
const validImageTypes = ['image/gif', 'image/jpeg', 'image/png', 'image/svg+xml', 'image/webp'];
if (!validImageTypes.includes(images[i].type)) {
showMediaAlert("<?php echo $L->g('File type is not supported. Allowed types:').' '.implode(', ',$GLOBALS['ALLOWED_IMG_EXTENSION']) ?>");
return false;
}
// Check file size and compare with PHP upload_max_filesize
if (images[i].size > UPLOAD_MAX_FILESIZE) {
showMediaAlert("<?php echo $L->g('Maximum load file size allowed:').' '.ini_get('upload_max_filesize') ?>");
return false;
}
};
// Clean progress bar
$("#jsbluditProgressBar").removeClass().addClass("progress-bar bg-primary");
$("#jsbluditProgressBar").width("0");
// Data to send via AJAX
var formData = new FormData($("#jsbluditFormUpload")[0]);
formData.append("uuid", "<?php echo PAGE_IMAGES_KEY ?>");
formData.append("tokenCSRF", tokenCSRF);
$.ajax({
url: HTML_PATH_ADMIN_ROOT+"ajax/upload-images",
type: "POST",
data: formData,
cache: false,
contentType: false,
processData: false,
xhr: function() {
var xhr = $.ajaxSettings.xhr();
if (xhr.upload) {
xhr.upload.addEventListener("progress", function(e) {
if (e.lengthComputable) {
var percentComplete = (e.loaded / e.total)*100;
$("#jsbluditProgressBar").width(percentComplete+"%");
}
}, false);
}
return xhr;
}
}).done(function(data) {
if (data.status==0) {
$("#jsbluditProgressBar").removeClass("bg-primary").addClass("bg-success");
// Get the files for the first page, this include the files uploaded
getFiles(1);
} else {
$("#jsbluditProgressBar").removeClass("bg-primary").addClass("bg-danger");
showMediaAlert(data.message);
}
});
}
$(document).ready(function() {
// Display the files preloaded for the first time
displayFiles(preLoadFiles);
// Select image event
$("#jsimages").on("change", function(e) {
uploadImages();
});
// Drag and drop image
$(window).on("dragover dragenter", function(e) {
e.preventDefault();
e.stopPropagation();
openMediaManager();
});
// Drag and drop image
$(window).on("drop", function(e) {
e.preventDefault();
e.stopPropagation();
$("#jsimages").prop("files", e.originalEvent.dataTransfer.files);
uploadImages();
});
});
</script>

View file

@ -17,7 +17,7 @@
<?php $L->p('Website') ?></a>
</li>
<li class="nav-item">
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'editor' ?>">
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'new-content' ?>">
<?php $L->p('New content') ?></a>
</li>
<li class="nav-item">
@ -25,10 +25,10 @@
<?php $L->p('Content') ?></a>
</li>
<?php if (!checkRole(array('admin'),false)): ?>
<li class="nav-item">
<li class="nav-item">
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'edit-user/'.$login->username() ?>">
<?php $L->p('Profile') ?></a>
</li>
<?php $L->p('Profile') ?></a>
</li>
<?php endif; ?>
<?php if (checkRole(array('admin'),false)): ?>
<li class="nav-item">
@ -57,15 +57,15 @@
</li>
<?php endif; ?>
<?php if (checkRole(array('admin'),false)): ?>
<?php
if (!empty($plugins['adminSidebar'])) {
foreach ($plugins['adminSidebar'] as $pluginSidebar) {
echo '<li class="nav-item">';
echo $pluginSidebar->adminSidebar();
echo '</li>';
}
<?php
if (!empty($plugins['adminSidebar'])) {
foreach ($plugins['adminSidebar'] as $pluginSidebar) {
echo '<li class="nav-item">';
echo $pluginSidebar->adminSidebar();
echo '</li>';
}
?>
}
?>
<?php endif; ?>
<li class="nav-item">
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'logout' ?>">

View file

@ -1,31 +1,27 @@
<!-- Use .flex-column to set a vertical direction -->
<ul class="nav flex-column">
<ul class="nav flex-column pt-4">
<li class="nav-item mb-3">
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'editor' ?>">
<i class="bi bi-plus-circle"></i>
<?php $L->p('New content') ?>
</a>
<li class="nav-item mb-4" style="margin-left: -4px;">
<img src="<?php echo HTML_PATH_CORE_IMG ?>logo.svg" width="20" height="20" alt="bludit-logo"><span class="ml-2 align-middle"><?php echo (defined('BLUDIT_PRO'))?'BLUDIT PRO':'BLUDIT' ?></span>
</li>
<li class="nav-item">
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'dashboard' ?>"><span class="fa fa-dashboard"></span><?php $L->p('Dashboard') ?></a>
</li>
<li class="nav-item">
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'dashboard' ?>">
<i class="bi bi-kanban"></i>
<?php $L->p('Dashboard') ?>
</a>
<a class="nav-link" target="_blank" href="<?php echo HTML_PATH_ROOT ?>"><span class="fa fa-home"></span><?php $L->p('Website') ?></a>
</li>
<li class="nav-item">
<a class="nav-link" href="<?php echo DOMAIN_BASE ?>">
<i class="bi bi-house"></i>
<?php $L->p('Website') ?>
</a>
<li class="nav-item mt-3">
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'new-content' ?>"><span style="color: #0078D4;" class="fa fa-plus-circle"></span><?php $L->p('New content') ?></a>
</li>
<?php if (!checkRole(array('admin'),false)): ?>
<li class="nav-item">
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'content' ?>"><span class="bi bi-archive"></span><?php $L->p('Content') ?></a>
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'content' ?>"><span class="fa fa-archive"></span><?php $L->p('Content') ?></a>
</li>
<li class="nav-item">
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'edit-user/'.$login->username() ?>"><span class="bi bi-user"></span><?php $L->p('Profile') ?></a>
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'edit-user/'.$login->username() ?>"><span class="fa fa-user"></span><?php $L->p('Profile') ?></a>
</li>
<?php endif; ?>
@ -35,38 +31,30 @@
<h4><?php $L->p('Manage') ?></h4>
</li>
<li class="nav-item">
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'content' ?>">
<i class="bi bi-folder"></i>
<?php $L->p('Content') ?>
</a>
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'content' ?>"><span class="fa fa-folder"></span><?php $L->p('Content') ?></a>
</li>
<li class="nav-item">
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'categories' ?>"><span class="fa fa-bookmark"></span><?php $L->p('Categories') ?></a>
</li>
<li class="nav-item">
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'categories' ?>">
<i class="bi bi-bookmark"></i>
<?php $L->p('Categories') ?>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'users' ?>">
<i class="bi bi-people"></i>
<?php $L->p('Users') ?>
</a>
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'users' ?>"><span class="fa fa-users"></span><?php $L->p('Users') ?></a>
</li>
<li class="nav-item mt-3">
<h4><?php $L->p('Settings') ?></h4>
</li>
<li class="nav-item">
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'settings' ?>"><span class="bi bi-gear"></span><?php $L->p('General') ?></a>
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'settings' ?>"><span class="fa fa-gear"></span><?php $L->p('General') ?></a>
</li>
<li class="nav-item">
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'plugins' ?>"><span class="bi bi-node-plus"></span><?php $L->p('Plugins') ?></a>
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'plugins' ?>"><span class="fa fa-puzzle-piece"></span><?php $L->p('Plugins') ?></a>
</li>
<li class="nav-item">
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'themes' ?>"><span class="bi bi-display"></span><?php $L->p('Themes') ?></a>
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'themes' ?>"><span class="fa fa-desktop"></span><?php $L->p('Themes') ?></a>
</li>
<li class="nav-item">
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'about' ?>"><span class="bi bi-info-circle"></span><?php $L->p('About') ?></a>
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'about' ?>"><span class="fa fa-info"></span><?php $L->p('About') ?></a>
</li>
<?php endif; ?>
@ -87,6 +75,6 @@
<?php endif; ?>
<li class="nav-item mt-5">
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'logout' ?>"><span class="bi bi-door-closed"></span><?php $L->p('Logout') ?></a>
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'logout' ?>"><span class="fa fa-arrow-circle-right"></span><?php $L->p('Logout') ?></a>
</li>
</ul>

View file

@ -1,123 +1,98 @@
<!DOCTYPE html>
<html class="h-100">
<html>
<head>
<title><?php echo $layout['title'] ?></title>
<meta charset="<?php echo CHARSET ?>">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="robots" content="noindex,nofollow">
<meta name="generator" content="Bludit">
<!-- Favicon -->
<link rel="shortcut icon" type="image/x-icon" href="<?php echo HTML_PATH_CORE_IMG . 'favicon.png?version=' . BLUDIT_VERSION ?>">
<link rel="shortcut icon" type="image/x-icon" href="<?php echo HTML_PATH_CORE_IMG.'favicon.png?version='.BLUDIT_VERSION ?>">
<!-- CSS -->
<?php
echo HTML::cssBootstrap();
echo HTML::cssBootstrapIcons();
echo HTML::css(array(
'01-bludit.css',
'02-bootstrap-hacks.css'
echo Theme::cssBootstrap();
echo Theme::cssLineAwesome();
echo Theme::css(array(
'bludit.css',
'bludit.bootstrap.css'
), DOMAIN_ADMIN_THEME_CSS);
echo HTML::css(array(
echo Theme::css(array(
'jquery.datetimepicker.min.css',
'jquery-ui.min.css',
'select2.min.css',
'select2-bootstrap4.min.css',
'tagsinput-revisited.min.css'
'select2-bootstrap4.min.css'
), DOMAIN_CORE_CSS);
if ($site->darkModeAdmin()) {
echo HTML::css(array(
'99-darkmode.css'
), DOMAIN_ADMIN_THEME_CSS);
} else {
echo HTML::css(array(
'99-lightmode.css'
), DOMAIN_ADMIN_THEME_CSS);
}
?>
<!-- Javascript -->
<?php
echo HTML::jquery();
echo HTML::jsBootstrap();
echo HTML::jsSortable();
echo HTML::bootbox();
echo HTML::js(array(
'jquery.datetimepicker.full.min.js',
'jquery-ui.min.js',
'select2.full.min.js',
'tagsinput-revisited.min.js',
'functions.js',
'api.js'
), DOMAIN_CORE_JS);
echo Theme::jquery();
echo Theme::jsBootstrap();
echo Theme::jsSortable();
echo Theme::js(array(
'jquery.datetimepicker.full.min.js',
'select2.full.min.js',
'functions.js'
), DOMAIN_CORE_JS, null);
?>
<!-- Execute plugins for the admin area inside the HTML <head> tag -->
<?php execPluginsByHook('adminHead') ?>
</head>
<!-- Plugins -->
<?php Theme::plugins('adminHead') ?>
</head>
<body class="h-100">
<!-- Execute plugins for the admin area inside the HTML <body> at the begginig -->
<?php execPluginsByHook('adminBodyBegin') ?>
<!-- Plugins -->
<?php Theme::plugins('adminBodyBegin') ?>
<!-- Javascript global variable generated by PHP -->
<?php include(PATH_CORE_JS . 'variables.php') ?>
<!-- Javascript dynamic generated by PHP -->
<?php
echo '<script charset="utf-8">'.PHP_EOL;
include(PATH_CORE_JS.'variables.php');
echo '</script>'.PHP_EOL;
<div class="container-fluid p-0 m-0 d-flex flex-column h-100">
echo '<script charset="utf-8">'.PHP_EOL;
include(PATH_CORE_JS.'bludit-ajax.php');
echo '</script>'.PHP_EOL;
?>
<!-- Alerts -->
<?php include('html/alerts.php') ?>
<!-- End Alerts -->
<!-- Overlay background -->
<div id="jsshadow"></div>
<!-- Top Navbar -->
<div class="container-fluid p-0 bg-dark">
<div class="container">
<div class="row">
<nav class="navbar navbar-dark p-1">
<a class="navbar-brand" href="#">
<img src="<?php echo DOMAIN_BASE ?>bl-kernel/img/logo.svg" alt="" width="30" height="24" class="d-inline-block align-top">
Bludit
</a>
</nav>
</div>
</div>
<!-- Alert -->
<?php include('html/alert.php'); ?>
<!-- Navbar, only for small devices -->
<?php include('html/navbar.php'); ?>
<div class="container h-100">
<!-- 25%/75% split on large devices, small, medium devices hide -->
<div class="row h-100">
<!-- LEFT SIDEBAR - Display only on large devices -->
<div class="sidebar col-lg-2 d-none d-lg-block">
<?php include('html/sidebar.php'); ?>
</div>
<!-- End Top Navbar -->
<!-- Main -->
<div class="container h-100 flex-grow-1">
<div class="row h-100 flex-grow-1">
<!-- LEFT Main, display only on large devices -->
<div class="sidebar col-lg-2 d-none d-lg-block mt-4">
<?php include('html/sidebar.php'); ?>
</div>
<!-- RIGHT Main -->
<div class="main col-lg-10 mt-2">
<?php
if (Sanitize::pathFile(PATH_ADMIN_VIEWS . $layout['view'] . '.php')) {
include(PATH_ADMIN_VIEWS . $layout['view'] . '.php');
} elseif ($layout['plugin'] && method_exists($layout['plugin'], 'adminView')) {
echo $layout['plugin']->adminView();
} else {
echo '<h1 class="text-center">' . $L->g('Page not found') . '</h1>';
echo '<h2 class="text-center">' . $L->g('Choose a page from the sidebar.') . '</h2>';
}
?>
</div>
</div>
<!-- RIGHT MAIN -->
<div class="col-lg-10 pt-3 pb-1 h-100">
<?php
if (Sanitize::pathFile(PATH_ADMIN_VIEWS, $layout['view'].'.php')) {
include(PATH_ADMIN_VIEWS.$layout['view'].'.php');
} elseif ($layout['plugin'] && method_exists($layout['plugin'], 'adminView')) {
echo $layout['plugin']->adminView();
} else {
echo '<h1 class="text-center">'.$L->g('Page not found').'</h1>';
echo '<h2 class="text-center">'.$L->g('Choose a page from the sidebar.').'</h2>';
}
?>
</div>
<!-- End Main -->
</div>
</div>
<!-- Execute plugins for the admin area inside the HTML <body> at the end -->
<?php execPluginsByHook('adminBodyEnd') ?>
<!-- Plugins -->
<?php Theme::plugins('adminBodyEnd') ?>
</body>
</html>
</html>

View file

@ -1,8 +1,403 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
<?php
// Init scripts for the theme
class Bootstrap
{
// This theme use the API to work
if (!pluginActivated('pluginAPI')) {
activatePlugin('pluginAPI');
public static function modal($args)
{
$buttonSecondary = $args['buttonSecondary'];
$buttonSecondaryClass = $args['buttonSecondaryClass'];
$buttonPrimary = $args['buttonPrimary'];
$buttonPrimaryClass = $args['buttonPrimaryClass'];
$modalText = $args['modalText'];
$modalTitle = $args['modalTitle'];
$modalId = $args['modalId'];
return <<<EOF
<div id="$modalId" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-body">
<h3>$modalTitle</h3>
<p>$modalText</p>
</div>
<div class="modal-footer">
<button type="button" class="btn $buttonSecondaryClass" data-dismiss="modal">$buttonSecondary</button>
<button type="button" class="btn $buttonPrimaryClass">$buttonPrimary</button>
</div>
</div>
</div>
</div>
EOF;
}
public static function link($args)
{
$options = 'href="' . $args['href'] . '"';
if (isset($args['class'])) {
$options .= ' class="' . $args['class'] . '"';
}
if (isset($args['target'])) {
$options .= ' target="' . $args['target'] . '"';
}
if (isset($args['icon'])) {
return '<a ' . $options . '><span class="fa fa-' . $args['icon'] . '"></span>' . $args['title'] . '</a>';
}
return '<a ' . $options . '>' . $args['title'] . '</a>';
}
public static function pageTitle($args)
{
$icon = $args['icon'];
$title = $args['title'];
return <<<EOF
<h2 class="mt-0 mb-3">
<span class="fa fa-$icon" style="font-size: 0.9em;"></span><span>$title</span>
</h2>
EOF;
}
public static function formOpen($args)
{
$class = empty($args['class']) ? '' : 'class="' . $args['class'] . '"';
$id = empty($args['id']) ? '' : 'id="' . $args['id'] . '"';
$enctype = empty($args['enctype']) ? '' : 'enctype="' . $args['enctype'] . '"';
$action = empty($args['action']) ? 'action=""' : 'action="' . $args['action'] . '"';
$method = empty($args['method']) ? 'method="post"' : 'method="' . $args['method'] . '"';
$style = empty($args['style']) ? '' : 'style="' . $args['style'] . '"';
return <<<EOF
<form $class $enctype $id $method $action $style autocomplete="off">
EOF;
}
public static function formClose()
{
return <<<EOF
</form>
<script>
$(document).ready(function() {
// Prevent the form submit when press enter key.
$("form").keypress(function(e) {
if ((e.which == 13) && (e.target.type !== "textarea")) {
return false;
}
});
});
</script>
EOF;
}
public static function formTitle($args)
{
$title = $args['title'];
return <<<EOF
<h6 class="mt-4 mb-2 pb-2 border-bottom text-uppercase">$title</h6>
EOF;
}
public static function formInputTextBlock($args)
{
$name = $args['name'];
$disabled = empty($args['disabled']) ? '' : 'disabled';
$placeholder = isset($args['placeholder']) ? $args['placeholder'] : '';
$value = isset($args['value']) ? $args['value'] : '';
$id = 'js' . $name;
if (isset($args['id'])) {
$id = $args['id'];
}
$tip = '';
if (!empty($args['tip'])) {
$tip = '<small class="form-text text-muted">' . $args['tip'] . '</small>';
}
$class = 'form-group m-0';
if (isset($args['class'])) {
$class = $args['class'];
}
$labelClass = 'mt-4 mb-2 pb-2 border-bottom text-uppercase w-100';
if (isset($args['labelClass'])) {
$labelClass = $args['labelClass'];
}
$label = '';
if (!empty($args['label'])) {
$label = '<label class="' . $labelClass . '" for="' . $id . '">' . $args['label'] . '</label>';
}
$type = 'text';
if (isset($args['type'])) {
$type = $args['type'];
}
return <<<EOF
<div class="$class">
$label
<input type="text" dir="auto" value="$value" class="form-control" id="$id" name="$name" placeholder="$placeholder" $disabled>
$tip
</div>
EOF;
}
public static function formInputFile($args)
{
$id = 'js' . $args['name'];
if (isset($args['id'])) {
$id = $args['id'];
}
$class = 'custom-file';
if (isset($args['class'])) {
$class = $class . ' ' . $args['class'];
}
$html = '<div class="' . $class . '">';
$html .= '<input type="file" class="custom-file-input" id="' . $id . '">';
$html .= '<label class="custom-file-label" for="' . $id . '">' . $args['label'] . '</label>';
$html .= '</div>';
return $html;
}
public static function formTextarea($args)
{
$id = 'js' . $args['name'];
if (isset($args['id'])) {
$id = $args['id'];
}
$class = 'form-control';
if (isset($args['class'])) {
$class = $class . ' ' . $args['class'];
}
$html = '<div class="form-group row">';
if (!empty($args['label'])) {
$html .= '<label for="' . $id . '" class="col-sm-2 col-form-label">' . $args['label'] . '</label>';
}
$html .= '<div class="col-sm-10">';
$html .= '<textarea class="' . $class . '" id="' . $id . '" name="' . $args['name'] . '" rows="' . $args['rows'] . '" placeholder="' . $args['placeholder'] . '">' . $args['value'] . '</textarea>';
if (isset($args['tip'])) {
$html .= '<small class="form-text text-muted">' . $args['tip'] . '</small>';
}
$html .= '</div>';
$html .= '</div>';
return $html;
}
public static function formTextareaBlock($args)
{
$id = 'js' . $args['name'];
if (isset($args['id'])) {
$id = $args['id'];
}
$class = 'form-control';
if (!empty($args['class'])) {
$class = $class . ' ' . $args['class'];
}
$html = '<div class="form-group m-0">';
if (!empty($args['label'])) {
$html .= '<label class="mt-4 mb-2 pb-2 border-bottom text-uppercase w-100" for="' . $id . '">' . $args['label'] . '</label>';
}
$html .= '<textarea class="' . $class . '" id="' . $id . '" name="' . $args['name'] . '" rows="' . $args['rows'] . '" placeholder="' . $args['placeholder'] . '">' . $args['value'] . '</textarea>';
if (!empty($args['tip'])) {
$html .= '<small class="form-text text-muted">' . $args['tip'] . '</small>';
}
$html .= '</div>';
return $html;
}
public static function formInputText($args)
{
$name = $args['name'];
$disabled = empty($args['disabled']) ? '' : 'disabled';
$readonly = empty($args['readonly']) ? '' : 'readonly';
$placeholder = isset($args['placeholder']) ? $args['placeholder'] : '';
$value = isset($args['value']) ? $args['value'] : '';
$id = 'js' . $name;
if (isset($args['id'])) {
$id = $args['id'];
}
$tip = '';
if (isset($args['tip'])) {
$tip = '<small class="form-text text-muted">' . $args['tip'] . '</small>';
}
$label = '';
if (isset($args['label'])) {
$label = '<label for="' . $id . '" class="col-sm-2 col-form-label">' . $args['label'] . '</label>';
}
$class = 'form-control';
if (isset($args['class'])) {
$class = $class . ' ' . $args['class'];
}
$type = 'text';
if (isset($args['type'])) {
$type = $args['type'];
}
return <<<EOF
<div class="form-group row">
$label
<div class="col-sm-10">
<input class="$class" id="$id" name="$name" value="$value" placeholder="$placeholder" type="$type" dir="auto" $disabled $readonly>
$tip
</div>
</div>
EOF;
}
public static function formCheckbox($args)
{
$labelForCheckbox = isset($args['labelForCheckbox']) ? $args['labelForCheckbox'] : '';
$placeholder = isset($args['placeholder']) ? $args['placeholder'] : '';
$tip = isset($args['tip']) ? '<small class="form-text text-muted">' . $args['tip'] . '</small>' : '';
$value = isset($args['value']) ? $args['value'] : '';
$name = $args['name'];
$id = 'js' . $name;
if (isset($args['id'])) {
$id = $args['id'];
}
$disabled = isset($args['disabled']) ? 'disabled' : '';
$class = 'form-group m-0';
if (isset($args['class'])) {
$class = $args['class'];
}
$labelClass = 'mt-4 mb-2 pb-2 border-bottom text-uppercase w-100';
if (isset($args['labelClass'])) {
$labelClass = $args['labelClass'];
}
$type = 'text';
if (isset($args['type'])) {
$type = $args['type'];
}
$label = '';
if (!empty($args['label'])) {
$label = '<label class="' . $labelClass . '">' . $args['label'] . '</label>';
}
$checked = $args['checked'] ? 'checked' : '';
$value = $checked ? '1' : '0';
return <<<EOF
<div class="$class">
$label
<div class="form-check">
<input type="hidden" name="$name" value="$value"><input id="$id" type="checkbox" class="form-check-input" onclick="this.previousSibling.value=1-this.previousSibling.value" $checked>
<label class="form-check-label" for="$id">$labelForCheckbox</label>
$tip
</div>
</div>
EOF;
}
public static function formSelect($args)
{
$id = 'js' . $args['name'];
if (isset($args['id'])) {
$id = $args['id'];
}
$class = 'custom-select';
if (isset($args['class'])) {
$class = $class . ' ' . $args['class'];
}
$html = '<div class="form-group row">';
if (isset($args['label'])) {
$html .= '<label for="' . $id . '" class="col-sm-2 col-form-label">' . $args['label'] . '</label>';
}
$html .= '<div class="col-sm-10">';
$html .= '<select id="' . $id . '" name="' . $args['name'] . '" class="' . $class . '">';
foreach ($args['options'] as $key => $value) {
$html .= '<option ' . (($key == $args['selected']) ? 'selected' : '') . ' value="' . $key . '">' . $value . '</option>';
}
$html .= '</select>';
if (isset($args['tip'])) {
$html .= '<small class="form-text text-muted">' . $args['tip'] . '</small>';
}
$html .= '</div>';
$html .= '</div>';
return $html;
}
public static function formSelectBlock($args)
{
$id = 'js' . $args['name'];
if (isset($args['id'])) {
$id = $args['id'];
}
$class = 'custom-select';
if (!empty($args['class'])) {
$class = $class . ' ' . $args['class'];
}
$html = '<div class="form-group m-0">';
if (!empty($args['label'])) {
$html .= '<label class="mt-4 mb-2 pb-2 border-bottom text-uppercase w-100" for="' . $id . '">' . $args['label'] . '</label>';
}
$html .= '<select id="' . $id . '" name="' . $args['name'] . '" class="' . $class . '">';
if (!empty($args['emptyOption'])) {
$html .= '<option value="">' . $args['emptyOption'] . '</option>';
}
foreach ($args['options'] as $key => $value) {
$html .= '<option ' . (($key == $args['selected']) ? 'selected' : '') . ' value="' . $key . '">' . $value . '</option>';
}
$html .= '</select>';
if (!empty($args['tip'])) {
$html .= '<small class="form-text text-muted">' . $args['tip'] . '</small>';
}
$html .= '</div>';
return $html;
}
public static function formInputHidden($args)
{
return '<input type="hidden" id="js' . $args['name'] . '" name="' . $args['name'] . '" value="' . $args['value'] . '">';
}
public static function alert($args)
{
$class = 'alert';
if (!empty($args['class'])) {
$class = $class . ' ' . $args['class'];
}
$text = $args['text'];
return <<<EOF
<div class="$class" role="alert">$text</div>
EOF;
}
}

View file

@ -1,63 +1,57 @@
<!DOCTYPE html>
<html class="h-100">
<html>
<head>
<title><?php echo $layout['title'] ?></title>
<meta charset="<?php echo CHARSET ?>">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="noindex,nofollow">
<meta name="generator" content="Bludit">
<title>Bludit</title>
<meta charset="<?php echo CHARSET ?>">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="robots" content="noindex,nofollow">
<!-- Favicon -->
<link rel="shortcut icon" type="image/x-icon" href="<?php echo HTML_PATH_CORE_IMG . 'favicon.png?version=' . BLUDIT_VERSION ?>">
<!-- Favicon -->
<link rel="shortcut icon" type="image/x-icon" href="<?php echo HTML_PATH_CORE_IMG . 'favicon.png?version=' . BLUDIT_VERSION ?>">
<!-- CSS -->
<?php
echo HTML::cssBootstrap();
echo HTML::cssBootstrapIcons();
echo HTML::css(array(
'01-bludit.css',
'02-bootstrap-hacks.css'
), DOMAIN_ADMIN_THEME_CSS);
<!-- CSS -->
<?php
echo Theme::cssBootstrap();
echo Theme::css(array(
'bludit.css',
'bludit.bootstrap.css'
), DOMAIN_ADMIN_THEME_CSS);
?>
if ($site->darkModeAdmin()) {
echo HTML::css(array(
'99-darkmode.css'
), DOMAIN_ADMIN_THEME_CSS);
} else {
echo HTML::css(array(
'99-lightmode.css'
), DOMAIN_ADMIN_THEME_CSS);
}
?>
<!-- Javascript -->
<?php
echo Theme::jquery();
echo Theme::jsBootstrap();
?>
<!-- Javascript -->
<?php
echo HTML::jquery();
echo HTML::jsBootstrap();
?>
<!-- Execute plugins for the login page inside the HTML <head> tag -->
<?php execPluginsByHook('loginHead') ?>
<!-- Plugins -->
<?php Theme::plugins('loginHead') ?>
</head>
<body class="h-100 bg-light">
<!-- Execute plugins for the login page inside the HTML <body> at the begginig -->
<?php execPluginsByHook('loginBodyBegin') ?>
<body class="login">
<div class="container h-100">
<div class="row h-100 justify-content-center align-items-center">
<div class="col-8 col-md-6 col-lg-4">
<?php
if (Sanitize::pathFile(PATH_ADMIN_VIEWS.$layout['view'].'.php')) {
include(PATH_ADMIN_VIEWS.$layout['view'].'.php');
}
?>
</div>
</div>
</div>
<!-- Plugins -->
<?php Theme::plugins('loginBodyBegin') ?>
<!-- Execute plugins for the login page inside the HTML <body> at the end -->
<?php execPluginsByHook('loginBodyEnd') ?>
<!-- Alert -->
<?php include('html/alert.php'); ?>
<div class="container">
<div class="row justify-content-md-center pt-5">
<div class="col-md-4 mt-5 p-5 shadow-sm bg-white rounded border">
<?php
if (Sanitize::pathFile(PATH_ADMIN_VIEWS, $layout['view'] . '.php')) {
include(PATH_ADMIN_VIEWS . $layout['view'] . '.php');
}
?>
</div>
</div>
</div>
<!-- Plugins -->
<?php Theme::plugins('loginBodyEnd') ?>
</body>
</html>
</html>

View file

@ -1,29 +1,3 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
<script>
// ============================================================================
// Variables for the view
// ============================================================================
// ============================================================================
// Functions for the view
// ============================================================================
// ============================================================================
// Events for the view
// ============================================================================
$(document).ready(function() {
// No events for the view yet
});
// ============================================================================
// Initialization for the view
// ============================================================================
$(document).ready(function() {
// No initialization for the view yet
});
</script>
<?php
echo Bootstrap::pageTitle(array('title'=>$L->g('About'), 'icon'=>'info-circle'));
@ -34,37 +8,37 @@ echo '
';
echo '<tr>';
echo '<td class="pt-4 pb-4">Bludit Edition</td>';
echo '<td>Bludit Edition</td>';
if (defined('BLUDIT_PRO')) {
echo '<td class="pt-4 pb-4">PRO - '.$L->g('Thanks for supporting Bludit').' <span class="bi-heart" style="color: #ffc107"></span></td>';
echo '<td>PRO - '.$L->g('Thanks for supporting Bludit').' <span class="fa fa-heart" style="color: #ffc107"></span></td>';
} else {
echo '<td class="pt-4 pb-4">Standard - <a target="_blank" href="https://pro.bludit.com">'.$L->g('Upgrade to Bludit PRO').'</a></td>';
echo '<td>Standard - <a target="_blank" href="https://pro.bludit.com">'.$L->g('Upgrade to Bludit PRO').'</a></td>';
}
echo '</tr>';
echo '<tr>';
echo '<td class="pt-4 pb-4">Bludit Version</td>';
echo '<td class="pt-4 pb-4">'.BLUDIT_VERSION.'</td>';
echo '<td>Bludit Version</td>';
echo '<td>'.BLUDIT_VERSION.'</td>';
echo '</tr>';
echo '<tr>';
echo '<td class="pt-4 pb-4">Bludit Codename</td>';
echo '<td class="pt-4 pb-4">'.BLUDIT_CODENAME.'</td>';
echo '<td>Bludit Codename</td>';
echo '<td>'.BLUDIT_CODENAME.'</td>';
echo '</tr>';
echo '<tr>';
echo '<td class="pt-4 pb-4">Bludit Build Number</td>';
echo '<td class="pt-4 pb-4">'.BLUDIT_BUILD.'</td>';
echo '<td>Bludit Build Number</td>';
echo '<td>'.BLUDIT_BUILD.'</td>';
echo '</tr>';
echo '<tr>';
echo '<td class="pt-4 pb-4">Disk usage</td>';
echo '<td class="pt-4 pb-4">'.Filesystem::bytesToHumanFileSize(Filesystem::getSize(PATH_ROOT)).'</td>';
echo '<td>Disk usage</td>';
echo '<td>'.Filesystem::bytesToHumanFileSize(Filesystem::getSize(PATH_ROOT)).'</td>';
echo '</tr>';
echo '<tr>';
echo '<td class="pt-4 pb-4"><a href="'.HTML_PATH_ADMIN_ROOT.'developers'.'">Bludit Developers</a></td>';
echo '<td class="pt-4 pb-4"></td>';
echo '<td><a href="'.HTML_PATH_ADMIN_ROOT.'developers'.'">Bludit Developers</a></td>';
echo '<td></td>';
echo '</tr>';
echo '

View file

@ -1,74 +0,0 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
<script>
// ============================================================================
// Variables for the view
// ============================================================================
// ============================================================================
// Functions for the view
// ============================================================================
// ============================================================================
// Events for the view
// ============================================================================
$(document).ready(function() {
$('#btnSave').on('click', function() {
var name = $('#name').val();
if (name.length < 1) {
showAlertError("<?php $L->p('Complete all fields') ?>");
return false;
}
var args = {
name: name,
description: $('#description').val()
};
api.createCategory(args).then(function(response) {
if (response.status == 0) {
logs('Category created. Key: ' + response.data.key);
window.location.replace('<?php echo HTML_PATH_ADMIN_ROOT . 'categories' ?>');
} else {
logs("An error occurred while trying to create the category.");
showAlertError(response.message);
}
});
return true;
});
});
// ============================================================================
// Initialization for the view
// ============================================================================
$(document).ready(function() {
// No initialization for the view yet
});
</script>
<div class="d-flex align-items-center mb-4">
<h2 class="m-0"><i class="bi bi-bookmark"></i><?php $L->p('New category') ?></h2>
<div class="ms-auto">
<button id="btnSave" type="button" class="btn btn-primary btn-sm"><?php $L->p('Save') ?></button>
<a id="btnCancel" class="btn btn-secondary btn-sm" href="<?php echo HTML_PATH_ADMIN_ROOT . 'categories' ?>" role="button"><?php $L->p('Cancel') ?></a>
</div>
</div>
<?php
echo Bootstrap::formInputText(array(
'id' => 'name',
'name' => 'name',
'label' => $L->g('Name'),
'value' => isset($_POST['category']) ? $_POST['category'] : ''
));
echo Bootstrap::formTextarea(array(
'id' => 'description',
'name' => 'description',
'label' => $L->g('Description'),
'value' => isset($_POST['description']) ? $_POST['description'] : '',
'rows' => 5
));
?>

View file

@ -1,112 +0,0 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
<script>
// ============================================================================
// Variables for the view
// ============================================================================
// ============================================================================
// Functions for the view
// ============================================================================
// ============================================================================
// Events for the view
// ============================================================================
$(document).ready(function() {
$('#btnSave').on('click', function() {
var username = $('#username').val();
var password = $('#password').val();
var confirmPassword = $('#confirmPassword').val();
if (username.length < 1) {
showAlertError("<?php $L->p('Complete all fields') ?>");
return false;
}
if (password.length < PASSWORD_LENGTH) {
showAlertError("<?php $L->p('Password must be at least 6 characters long') ?>");
return false;
}
if (password !== confirmPassword) {
showAlertError("<?php $L->p('The password and confirmation password do not match') ?>");
return false;
}
var args = {
username: username,
password: password,
role: $('#role').val(),
email: $('#email').val()
};
api.createUser(args).then(function(response) {
if (response.status == 0) {
logs('User created. Username: ' + response.data.username);
window.location.replace(HTML_PATH_ADMIN_ROOT + 'users');
} else {
logs('An error occurred while trying to create the user.');
showAlertError(response.message);
}
});
return true;
});
});
// ============================================================================
// Initialization for the view
// ============================================================================
$(document).ready(function() {
// No initialization for the view yet
});
</script>
<div class="d-flex align-items-center mb-4">
<h2 class="m-0"><i class="bi bi-person"></i><?php $L->p('New user') ?></h2>
<div class="ms-auto">
<button id="btnSave" type="button" class="btn btn-primary btn-sm"><?php $L->p('Save') ?></button>
<a id="btnCancel" class="btn btn-secondary btn-sm" href="<?php echo HTML_PATH_ADMIN_ROOT . 'users' ?>" role="button"><?php $L->p('Cancel') ?></a>
</div>
</div>
<?php
echo Bootstrap::formInputText(array(
'id' => 'username',
'name' => 'username',
'label' => $L->g('Username'),
'value' => ''
));
echo Bootstrap::formInputText(array(
'id' => 'password',
'name' => 'password',
'type' => 'password',
'label' => $L->g('Password'),
'value' => ''
));
echo Bootstrap::formInputText(array(
'id' => 'confirmPassword',
'name' => 'confirmPassword',
'type' => 'password',
'label' => $L->g('Confirm Password'),
'value' => ''
));
echo Bootstrap::formSelect(array(
'name' => 'role',
'label' => $L->g('Role'),
'options' => array('author' => $L->g('Author'), 'editor' => $L->g('Editor'), 'admin' => $L->g('Administrator')),
'selected' => 'Author',
'tip' => $L->g('author-can-write-and-edit-their-own-content')
));
echo Bootstrap::formInputText(array(
'id' => 'email',
'name' => 'email',
'type' => 'email',
'label' => $L->g('Email'),
'value' => ''
));
?>

View file

@ -0,0 +1,59 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
<?php echo Bootstrap::formOpen(array('id'=>'jsform', 'class'=>'tab-content')); ?>
<div class="align-middle">
<div class="float-right mt-1">
<button type="submit" class="btn btn-primary btn-sm" name="save"><?php $L->p('Save') ?></button>
<a class="btn btn-secondary btn-sm" href="<?php echo HTML_PATH_ADMIN_ROOT.'themes' ?>" role="button"><?php $L->p('Cancel') ?></a>
</div>
<?php echo Bootstrap::pageTitle(array('title'=>$L->g('Blocks'), 'icon'=>'box')); ?>
</div>
<?php
// Token CSRF
echo Bootstrap::formInputHidden(array(
'name'=>'tokenCSRF',
'value'=>$security->getTokenCSRF()
));
foreach ($blocks->getAll() as $block) {
echo Bootstrap::formTitle(array('title'=>$block->title()));
if (Text::isNotEmpty( $block->description() )) {
echo Bootstrap::alert(array('class'=>'alert-primary', 'text'=>$block->description()));
}
echo Bootstrap::formInputText(array(
'name'=>'key[]',
'label'=>$L->g('Key'),
'value'=>$block->key(),
'class'=>'',
'placeholder'=>'',
'tip'=>'',
'readonly'=>true
));
echo Bootstrap::formInputText(array(
'name'=>'title[]',
'label'=>$L->g('title'),
'value'=>$block->title(),
'class'=>'',
'placeholder'=>'',
'tip'=>''
));
echo Bootstrap::formTextarea(array(
'name'=>'value[]',
'label'=>$L->g('Value'),
'value'=>$block->value(),
'class'=>'',
'placeholder'=>'',
'tip'=>'',
'rows'=>5
));
}
echo Bootstrap::formClose();
?>

View file

@ -1,44 +1,18 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
<?php defined('BLUDIT') or die('Bludit CMS.');
<script>
// ============================================================================
// Variables for the view
// ============================================================================
echo Bootstrap::pageTitle(array('title'=>$L->g('Categories'), 'icon'=>'tags'));
// ============================================================================
// Functions for the view
// ============================================================================
// ============================================================================
// Events for the view
// ============================================================================
$(document).ready(function() {
// No events for the view yet
});
// ============================================================================
// Initialization for the view
// ============================================================================
$(document).ready(function() {
// No initialization for the view yet
});
</script>
<div class="d-flex align-items-center mb-4">
<h2 class="m-0"><i class="bi bi-bookmark"></i><?php $L->p('Categories') ?></h2>
<div class="ms-auto">
<a id="btnNew" class="btn btn-primary btn-sm" href="<?php echo HTML_PATH_ADMIN_ROOT . 'add-category' ?>" role="button"><i class="bi bi-plus-circle"></i><?php $L->p('Add a new category') ?></a>
</div>
</div>
<?php
echo Bootstrap::link(array(
'title'=>$L->g('Add a new category'),
'href'=>HTML_PATH_ADMIN_ROOT.'new-category',
'icon'=>'plus'
));
echo '
<table class="table table-striped mt-3">
<thead>
<tr>
<th class="border-bottom-0" scope="col">'.$L->g('Name').'</th>
<th class="border-bottom-0" scope="col">'.$L->g('Description').'</th>
<th class="border-bottom-0" scope="col">'.$L->g('URL').'</th>
</tr>
</thead>
@ -46,19 +20,14 @@ echo '
';
foreach ($categories->keys() as $key) {
try {
$category = new Category($key);
echo '<tr>';
echo '<td class="pt-4 pb-4"><a href="'.HTML_PATH_ADMIN_ROOT.'edit-category/'.$key.'">'.$category->name().'</a></td>';
echo '<td class="pt-4 pb-4"><span>'.$category->description().'</span></td>';
echo '<td class="pt-4 pb-4"><a href="'.$category->permalink().'">'.$category->permalink().'</a></td>';
echo '</tr>';
} catch (Exception $e) {
// Continue
}
$category = new Category($key);
echo '<tr>';
echo '<td><a href="'.HTML_PATH_ADMIN_ROOT.'edit-category/'.$key.'">'.$category->name().'</a></td>';
echo '<td><a href="'.$category->permalink().'">'.$url->filters('category', false).$key.'</a></td>';
echo '</tr>';
}
echo '
</tbody>
</table>
';
';

View file

@ -0,0 +1,26 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
<?php echo Bootstrap::formOpen(array('id'=>'jsform', 'class'=>'plugin-form')); ?>
<div class="align-middle">
<?php if ($plugin->formButtons()): ?>
<div class="float-right mt-1">
<button type="submit" class="btn btn-primary btn-sm" name="save"><?php $L->p('Save') ?></button>
<a class="btn btn-secondary btn-sm" href="<?php echo HTML_PATH_ADMIN_ROOT.'plugins' ?>" role="button"><?php $L->p('Cancel') ?></a>
</div>
<?php endif; ?>
<?php echo Bootstrap::pageTitle(array('title'=>$plugin->name(), 'icon'=>'cog')); ?>
</div>
<?php
// Token CSRF
echo Bootstrap::formInputHidden(array(
'name'=>'tokenCSRF',
'value'=>$security->getTokenCSRF()
));
// Print the plugin form
echo $plugin->form();
?>
<?php echo Bootstrap::formClose(); ?>

View file

@ -1,179 +1,139 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
<script>
// ============================================================================
// Variables for the view
// ============================================================================
// ============================================================================
// Functions for the view
// ============================================================================
function deletePage(key) {
var args = {
key: key
};
api.deletePage(args).then(function(response) {
if (response.status == 0) {
logs('Page deleted. Key: ' + response.data.key);
showAlertInfo("<?php $L->p('Page deleted') ?>");
$('#pagekey-'+response.data.key).addClass('disabled');
} else {
logs('An error occurred while trying to delete the page.');
showAlertError(response.message);
}
});
}
// ============================================================================
// Events for the view
// ============================================================================
$(document).ready(function() {
$(".btnDeletePage").on("click", function() {
var key = $(this).data('key');
logs('Deleting page. Key: ' + key);
bootbox.confirm({
message: '<?php $L->p('Are you sure you want to delete this page') ?>',
buttons: {
cancel: {
label: '<i class="bi bi-x"></i><?php $L->p('Cancel') ?>',
className: 'btn-sm btn-secondary'
},
confirm: {
label: '<i class="bi bi-check"></i><?php $L->p('Confirm') ?>',
className: 'btn-sm btn-primary'
}
},
closeButton: false,
callback: function(result) {
if (result) {
deletePage(key);
}
}
});
});
});
// ============================================================================
// Initialization for the view
// ============================================================================
$(document).ready(function() {
// No initialization for the view yet
});
</script>
<div class="d-flex align-items-center mb-4">
<h2 class="m-0"><i class="bi bi-folder"></i><?php $L->p('Content') ?></h2>
<div class="ms-auto">
<a id="btnNew" class="btn btn-primary btn-sm" href="<?php echo HTML_PATH_ADMIN_ROOT . 'editor' ?>" role="button"><i class="bi bi-plus-circle"></i><?php $L->p('Add a new page') ?></a>
</div>
</div>
<?php
function table($type)
{
echo Bootstrap::pageTitle(array('title'=>$L->g('Content'), 'icon'=>'archive'));
function table($type) {
global $url;
global $L;
global $published;
global $drafts;
global $scheduled;
global $static;
global $sticky;
global $autosave;
if ($type == 'published') {
if ($type=='published') {
$list = $published;
if (empty($list)) {
echo '<p class="text-muted p-4">';
echo '<p class="mt-4 text-muted">';
echo $L->g('There are no pages at this moment.');
echo '</p>';
return false;
}
} elseif ($type == 'draft') {
} elseif ($type=='draft') {
$list = $drafts;
if (empty($list)) {
echo '<p class="text-muted p-4">';
echo '<p class="mt-4 text-muted">';
echo $L->g('There are no draft pages at this moment.');
echo '</p>';
return false;
}
} elseif ($type == 'scheduled') {
} elseif ($type=='scheduled') {
$list = $scheduled;
if (empty($list)) {
echo '<p class="text-muted p-4">';
echo '<p class="mt-4 text-muted">';
echo $L->g('There are no scheduled pages at this moment.');
echo '</p>';
return false;
}
} elseif ($type == 'static') {
} elseif ($type=='static') {
$list = $static;
if (empty($list)) {
echo '<p class="text-muted p-4">';
echo '<p class="mt-4 text-muted">';
echo $L->g('There are no static pages at this moment.');
echo '</p>';
return false;
}
} elseif ($type == 'sticky') {
} elseif ($type=='sticky') {
$list = $sticky;
if (empty($list)) {
echo '<p class="text-muted p-4">';
echo '<p class="mt-4 text-muted">';
echo $L->g('There are no sticky pages at this moment.');
echo '</p>';
return false;
}
} elseif ($type=='autosave') {
$list = $autosave;
}
echo '<table class="table table-striped"><tbody><tr></tr>';
echo '
<table class="table mt-3">
<thead>
<tr>
<th class="border-0" scope="col">'.$L->g('Title').'</th>
';
if ((ORDER_BY == 'position') || $type == 'static') {
if ($type=='published' || $type=='static' || $type=='sticky') {
echo '<th class="border-0 d-none d-lg-table-cell" scope="col">'.$L->g('URL').'</th>';
}
echo ' <th class="border-0 text-center d-sm-table-cell" scope="col">'.$L->g('Actions').'</th>
</tr>
</thead>
<tbody>
';
if ( (ORDER_BY=='position') || $type=='static' ) {
foreach ($list as $pageKey) {
try {
$page = new Page($pageKey);
if (!$page->isChild()) {
echo '<tr id="pagekey-'.$pageKey.'">';
echo '<td class="pt-4 pb-4">
<div>
<span>' . ($page->title() ? $page->title() : '<span class="text-muted">' . $L->g('Empty title') . '</span> ') . '</span>
</div>
<div class="mt-1">
<a class="me-2" target="_blank" href="' . $page->permalink() . '">' . $L->g('View') . '</a>
<a class="me-2" href="' . HTML_PATH_ADMIN_ROOT . 'editor/' . $page->key() . '">' . $L->g('Edit') . '</a>
';
if (count($page->children()) == 0) {
echo '<span class="link btnDeletePage" data-key="' . $page->key() . '">Delete</span>';
}
echo '
</div>
echo '<tr>
<td>
<div>
<a style="font-size: 1.1em" href="'.HTML_PATH_ADMIN_ROOT.'edit-content/'.$page->key().'">'
.($page->title()?$page->title():'<span class="label-empty-title">'.$L->g('Empty title').'</span> ')
.'</a>
</div>
<div>
<p style="font-size: 0.8em" class="m-0 text-uppercase text-muted">'.( ((ORDER_BY=='position') || ($type!='published'))?$L->g('Position').': '.$page->position():$page->date(MANAGE_CONTENT_DATE_FORMAT) ).'</p>
</div>
</td>';
echo '<td class="pt-4 pb-4 d-none d-lg-table-cell">' . $L->get('Category') . ': ' . ($page->category() ? $page->category() : $L->get('uncategorized')) . '</td>';
if ($type=='published' || $type=='static' || $type=='sticky') {
$friendlyURL = Text::isEmpty($url->filters('page')) ? '/'.$page->key() : '/'.$url->filters('page').'/'.$page->key();
echo '<td class="d-none d-lg-table-cell"><a target="_blank" href="'.$page->permalink().'">'.$friendlyURL.'</a></td>';
}
echo '<td class="pt-4 text-center d-sm-table-cell">' . (((ORDER_BY == 'position') || ($type != 'published')) ? $L->g('Position') . ': ' . $page->position() : $page->date(MANAGE_CONTENT_DATE_FORMAT)) . '</td>';
echo '<td class="contentTools pt-3 text-center d-sm-table-cell">'.PHP_EOL;
echo '<a class="text-secondary d-none d-md-inline" target="_blank" href="'.$page->permalink().'"><i class="fa fa-desktop"></i>'.$L->g('View').'</a>'.PHP_EOL;
echo '<a class="text-secondary d-none d-md-inline ml-2" href="'.HTML_PATH_ADMIN_ROOT.'edit-content/'.$page->key().'"><i class="fa fa-edit"></i>'.$L->g('Edit').'</a>'.PHP_EOL;
if (count($page->children())==0) {
echo '<a href="#" class="ml-2 text-danger deletePageButton d-block d-sm-inline" data-toggle="modal" data-target="#jsdeletePageModal" data-key="'.$page->key().'"><i class="fa fa-trash"></i>'.$L->g('Delete').'</a>'.PHP_EOL;
}
echo '</td>';
echo '</tr>';
foreach ($page->children() as $child) {
echo '<tr id="pagekey-'.$pageKey.'">';
echo '<td class="ps-3 pt-4 pb-4">
<div>
<span>' . ($child->title() ? $child->title() : '<span class="text-muted">' . $L->g('Empty title') . '</span> ') . '</span>
</div>
<div class="mt-1">
<a class="me-2" target="_blank" href="' . $child->permalink() . '">' . $L->g('View') . '</a>
<a class="me-2" href="' . HTML_PATH_ADMIN_ROOT . 'editor/' . $child->key() . '">' . $L->g('Edit') . '</a>
<span class="link btnDeletePage" data-key="' . $child->key() . '">Delete</span>
</div>
//if ($child->published()) {
echo '<tr>
<td class="child">
<div>
<a style="font-size: 1.1em" href="'.HTML_PATH_ADMIN_ROOT.'edit-content/'.$child->key().'">'
.($child->title()?$child->title():'<span class="label-empty-title">'.$L->g('Empty title').'</span> ')
.'</a>
</div>
<div>
<p style="font-size: 0.8em" class="m-0 text-uppercase text-muted">'.( ((ORDER_BY=='position') || ($type!='published'))?$L->g('Position').': '.$child->position():$child->date(MANAGE_CONTENT_DATE_FORMAT) ).'</p>
</div>
</td>';
echo '<td class="pt-4 d-none d-lg-table-cell">' . $L->get('Category') . ': ' . ($child->category() ? $child->category() : $L->get('uncategorized')) . '</td>';
if ($type=='published' || $type=='static' || $type=='sticky') {
$friendlyURL = Text::isEmpty($url->filters('page')) ? '/'.$child->key() : '/'.$url->filters('page').'/'.$child->key();
echo '<td class="d-none d-lg-table-cell"><a target="_blank" href="'.$child->permalink().'">'.$friendlyURL.'</a></td>';
}
echo '<td class="pt-4 text-center d-sm-table-cell">' . (((ORDER_BY == 'position') || ($type != 'published')) ? $L->g('Position') . ': ' . $child->position() : $child->date(MANAGE_CONTENT_DATE_FORMAT)) . '</td>';
echo '<td class="contentTools pt-3 text-center d-sm-table-cell">'.PHP_EOL;
if ($type=='published' || $type=='static' || $type=='sticky') {
echo '<a class="text-secondary d-none d-md-inline" target="_blank" href="'.$child->permalink().'"><i class="fa fa-desktop"></i>'.$L->g('View').'</a>'.PHP_EOL;
}
echo '<a class="text-secondary d-none d-md-inline ml-2" href="'.HTML_PATH_ADMIN_ROOT.'edit-content/'.$child->key().'"><i class="fa fa-edit"></i>'.$L->g('Edit').'</a>'.PHP_EOL;
echo '<a class="ml-2 text-danger deletePageButton d-block d-sm-inline" href="#" data-toggle="modal" data-target="#jsdeletePageModal" data-key="'.$child->key().'"><i class="fa fa-trash"></i>'.$L->g('Delete').'</a>'.PHP_EOL;
echo '</td>';
echo '</tr>';
//}
}
}
} catch (Exception $e) {
@ -184,22 +144,32 @@ function table($type)
foreach ($list as $pageKey) {
try {
$page = new Page($pageKey);
echo '<tr id="pagekey-'.$pageKey.'">';
echo '<td class="pt-4 pb-4">
echo '<tr>';
echo '<td class="pt-3">
<div>
' . ($page->title() ? $page->title() : '<span class="text-muted">' . $L->g('Empty title') . '</span> ') . '
<a style="font-size: 1.1em" href="'.HTML_PATH_ADMIN_ROOT.'edit-content/'.$page->key().'">'
.($page->title()?$page->title():'<span class="label-empty-title">'.$L->g('Empty title').'</span> ')
.'</a>
</div>
<div class="mt-1">
<a class="me-2" target="_blank" href="' . $page->permalink() . '">' . $L->g('View') . '</a>
<a class="me-2" href="' . HTML_PATH_ADMIN_ROOT . 'editor/' . $page->key() . '">' . $L->g('Edit') . '</a>
<span class="link btnDeletePage" data-key="' . $page->key() . '">Delete</span>
<div>
<p style="font-size: 0.8em" class="m-0 text-uppercase text-muted">'.( ($type=='scheduled')?$L->g('Scheduled').': '.$page->date(SCHEDULED_DATE_FORMAT):$page->date(MANAGE_CONTENT_DATE_FORMAT) ).'</p>
</div>
</td>';
echo '<td class="pt-4 d-none d-lg-table-cell">' . $L->get('Category') . ': ' . ($page->category() ? $page->category() : $L->get('uncategorized')) . '</td>';
if ($type=='published' || $type=='static' || $type=='sticky') {
$friendlyURL = Text::isEmpty($url->filters('page')) ? '/'.$page->key() : '/'.$url->filters('page').'/'.$page->key();
echo '<td class="pt-3 d-none d-lg-table-cell"><a target="_blank" href="'.$page->permalink().'">'.$friendlyURL.'</a></td>';
}
echo '<td class="pt-4 text-center d-sm-table-cell"> ' . (((ORDER_BY == 'position') || ($type != 'published')) ? $L->g('Position') . ': ' . $page->position() : $page->date(MANAGE_CONTENT_DATE_FORMAT)) . '</td>';
echo '<td class="contentTools pt-3 text-center d-sm-table-cell">'.PHP_EOL;
if ($type=='published' || $type=='static' || $type=='sticky') {
echo '<a class="text-secondary d-none d-md-inline" target="_blank" href="'.$page->permalink().'"><i class="fa fa-desktop"></i>'.$L->g('View').'</a>'.PHP_EOL;
}
echo '<a class="text-secondary d-none d-md-inline ml-2" href="'.HTML_PATH_ADMIN_ROOT.'edit-content/'.$page->key().'"><i class="fa fa-edit"></i>'.$L->g('Edit').'</a>'.PHP_EOL;
if (count($page->children())==0) {
echo '<a href="#" class="ml-2 text-danger deletePageButton d-block d-sm-inline" data-toggle="modal" data-target="#jsdeletePageModal" data-key="'.$page->key().'"><i class="fa fa-trash"></i>'.$L->g('Delete').'</a>'.PHP_EOL;
}
echo '</td>';
echo '</tr>';
} catch (Exception $e) {
@ -216,88 +186,142 @@ function table($type)
?>
<!-- Tabs -->
<ul class="nav nav-tabs ps-3" role="tablist">
<!-- TABS -->
<ul class="nav nav-tabs" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="pages-tab" data-bs-toggle="tab" href="#pages" role="tab" aria-controls="pages" aria-selected="true"><?php $L->p('Pages') ?></a>
<a class="nav-link active" id="pages-tab" data-toggle="tab" href="#pages" role="tab"><?php $L->p('Pages') ?></a>
</li>
<li class="nav-item">
<a class="nav-link" id="static-tab" data-bs-toggle="tab" href="#static" role="tab" aria-controls="static" aria-selected="true"><?php $L->p('Static') ?></a>
<a class="nav-link" id="static-tab" data-toggle="tab" href="#static" role="tab"><?php $L->p('Static') ?></a>
</li>
<li class="nav-item">
<a class="nav-link" id="sticky-tab" data-bs-toggle="tab" href="#sticky" role="tab" aria-controls="sticky" aria-selected="true"><?php $L->p('Sticky') ?></a>
<a class="nav-link" id="sticky-tab" data-toggle="tab" href="#sticky" role="tab"><?php $L->p('Sticky') ?></a>
</li>
<li class="nav-item">
<a class="nav-link" id="scheduled-tab" data-bs-toggle="tab" href="#scheduled" role="tab" aria-controls="scheduled" aria-selected="true"><?php $L->p('Scheduled') ?>
<?php if (count($scheduled) > 0) {
echo '<span class="badge badge-danger">' . count($scheduled) . '</span>';
} ?>
</a>
<a class="nav-link" id="scheduled-tab" data-toggle="tab" href="#scheduled" role="tab"><?php $L->p('Scheduled') ?> <?php if (count($scheduled)>0) { echo '<span class="badge badge-danger">'.count($scheduled).'</span>'; } ?></a>
</li>
<li class="nav-item">
<a class="nav-link" id="draft-tab" data-bs-toggle="tab" href="#draft" role="tab" aria-controls="draft" aria-selected="true"><?php $L->p('Draft') ?></a>
<a class="nav-link" id="draft-tab" data-toggle="tab" href="#draft" role="tab"><?php $L->p('Draft') ?></a>
</li>
<?php if (!empty($autosave)): ?>
<li class="nav-item">
<a class="nav-link" id="autosave-tab" data-toggle="tab" href="#autosave" role="tab"><?php $L->p('Autosave') ?></a>
</li>
<?php endif; ?>
</ul>
<!-- End Tabs -->
<!-- Content -->
<div class="tab-content">
<!-- Tab pages -->
<!-- TABS PAGES -->
<div class="tab-pane show active" id="pages" role="tabpanel">
<?php table('published'); ?>
<?php if (Paginator::numberOfPages() > 1): ?>
<!-- Paginator -->
<!-- The paginator is defined in the rule 99.paginator.php for the admin area -->
<?php if (Paginator::numberOfPages() > 1) : ?>
<nav class="mt-4 mb-4">
<ul class="pagination flex-wrap justify-content-center">
<!-- First button -->
<li class="page-item <?php if (!Paginator::showPrev()) echo 'disabled' ?>">
<a class="page-link" href="<?php echo Paginator::firstPageUrl() ?>"><i class="bi bi-arrow-left-circle"></i><?php echo $L->get('First'); ?></a>
</li>
<nav class="paginator">
<ul class="pagination flex-wrap justify-content-center">
<!-- Previous button -->
<li class="page-item <?php if (!Paginator::showPrev()) echo 'disabled' ?>">
<a class="page-link" href="<?php echo Paginator::previousPageUrl() ?>"><?php echo $L->get('Previous'); ?></a>
</li>
<!-- First button -->
<li class="page-item <?php if (!Paginator::showPrev()) echo 'disabled' ?>">
<a class="page-link" href="<?php echo Paginator::firstPageUrl() ?>"><span class="align-middle fa fa-media-skip-backward"></span> <?php echo $L->get('First'); ?></a>
</li>
<li class="page-item"><span class="page-link text-muted"><?php echo Paginator::currentPage() ?> / <?php echo Paginator::numberOfPages() ?></span></li>
<!-- Previous button -->
<li class="page-item <?php if (!Paginator::showPrev()) echo 'disabled' ?>">
<a class="page-link" href="<?php echo Paginator::previousPageUrl() ?>"><?php echo $L->get('Previous'); ?></a>
</li>
<!-- Next button -->
<li class="page-item <?php if (!Paginator::showNext()) echo 'disabled' ?>">
<a class="page-link" href="<?php echo Paginator::nextPageUrl() ?>"><?php echo $L->get('Next'); ?></a>
</li>
<!-- Next button -->
<li class="page-item <?php if (!Paginator::showNext()) echo 'disabled' ?>">
<a class="page-link" href="<?php echo Paginator::nextPageUrl() ?>"><?php echo $L->get('Next'); ?></a>
</li>
<!-- Last button -->
<li class="page-item <?php if (!Paginator::showNext()) echo 'disabled' ?>">
<a class="page-link" href="<?php echo Paginator::lastPageUrl() ?>"><?php echo $L->get('Last'); ?><i class="ms-2 bi bi-arrow-right-circle"></i></a>
</li>
</ul>
</nav>
<!-- Last button -->
<li class="page-item <?php if (!Paginator::showNext()) echo 'disabled' ?>">
<a class="page-link" href="<?php echo Paginator::lastPageUrl() ?>"><?php echo $L->get('Last'); ?> <span class="align-middle fa fa-media-skip-forward"></span></a>
</li>
</ul>
</nav>
<?php endif; ?>
<!-- End Paginator -->
</div>
<!-- End Tab pages -->
<!-- TABS STATIC -->
<div class="tab-pane" id="static" role="tabpanel">
<?php table('static'); ?>
<?php table('static'); ?>
</div>
<!-- TABS STICKY -->
<div class="tab-pane" id="sticky" role="tabpanel">
<?php table('sticky'); ?>
<?php table('sticky'); ?>
</div>
<!-- TABS SCHEDULED -->
<div class="tab-pane" id="scheduled" role="tabpanel">
<?php table('scheduled'); ?>
<?php table('scheduled'); ?>
</div>
<!-- TABS DRAFT -->
<div class="tab-pane" id="draft" role="tabpanel">
<?php table('draft'); ?>
<?php table('draft'); ?>
</div>
<!-- TABS AUTOSAVE -->
<?php if (!empty($autosave)): ?>
<div class="tab-pane" id="autosave" role="tabpanel">
<?php table('autosave'); ?>
</div>
<?php endif; ?>
</div>
<!-- End Content -->
<!-- Modal for delete page -->
<?php
echo Bootstrap::modal(array(
'buttonPrimary'=>$L->g('Delete'),
'buttonPrimaryClass'=>'btn-danger deletePageModalAcceptButton',
'buttonSecondary'=>$L->g('Cancel'),
'buttonSecondaryClass'=>'btn-link',
'modalTitle'=>$L->g('Delete content'),
'modalText'=>$L->g('Are you sure you want to delete this page'),
'modalId'=>'jsdeletePageModal'
));
?>
<script>
$(document).ready(function() {
var key = false;
// Button for delete a page in the table
$(".deletePageButton").on("click", function() {
key = $(this).data('key');
});
// Event from button accept from the modal
$(".deletePageModalAcceptButton").on("click", function() {
var form = jQuery('<form>', {
'action': HTML_PATH_ADMIN_ROOT+'edit-content/'+key,
'method': 'post',
'target': '_top'
}).append(jQuery('<input>', {
'type': 'hidden',
'name': 'tokenCSRF',
'value': tokenCSRF
}).append(jQuery('<input>', {
'type': 'hidden',
'name': 'key',
'value': key
}).append(jQuery('<input>', {
'type': 'hidden',
'name': 'type',
'value': 'delete'
}))));
form.hide().appendTo("body").submit();
});
});
</script>
<script>
// Open the tab defined in the URL
const anchor = window.location.hash;
$(`a[href="${anchor}"]`).tab('show');
</script>

View file

@ -1,62 +1,140 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
<div id="dashboard" class="container">
<div class="row">
<div class="col-md-7">
<script>
// ============================================================================
// Variables for the view
// ============================================================================
<!-- Good message -->
<div>
<h2 id="hello-message" class="pt-0">
<?php
$username = $login->username();
$user = new User($username);
$name = '';
if ($user->nickname()) {
$name = $user->nickname();
} elseif ($user->firstName()) {
$name = $user->firstName();
}
?>
<span class="fa fa-hand-spock-o"></span><span><?php echo $L->g('welcome') ?></span>
</h2>
<script>
$(document).ready(function() {
$("#hello-message").fadeOut(2400, function() {
var date = new Date()
var hours = date.getHours()
if (hours >= 6 && hours < 12) {
$(this).html('<span class="fa fa-sun-o"></span><?php echo $L->g('good-morning') . ', ' . $name ?>');
} else if (hours >= 12 && hours < 18) {
$(this).html('<span class="fa fa-sun-o"></span><?php echo $L->g('good-afternoon') . ', ' . $name ?>');
} else if (hours >= 18 && hours < 22) {
$(this).html('<span class="fa fa-moon-o"></span><?php echo $L->g('good-evening') . ', ' . $name ?>');
} else {
$(this).html('<span class="fa fa-moon-o"></span><span><?php echo $L->g('good-night') . ', ' . $name ?></span>');
}
}).fadeIn(1000);
});
</script>
</div>
// ============================================================================
// Functions for the view
// ============================================================================
<!-- Quick Links -->
<div class="container pb-5" id="jsclippyContainer">
// ============================================================================
// Events for the view
// ============================================================================
$(document).ready(function() {
// No events for the view yet
});
<div class="row">
<div class="col p-0">
<div class="form-group">
<select id="jsclippy" class="clippy" name="state"></select>
</div>
</div>
</div>
// ============================================================================
// Initialization for the view
// ============================================================================
$(document).ready(function() {
// No initialization for the view yet
});
</script>
<script>
$(document).ready(function() {
<div id="dashboard" class="container-fluid">
<div class="row">
<div class="col-7">
<?php execPluginsByHook('dashboard') ?>
</div>
var clippy = $("#jsclippy").select2({
placeholder: "<?php $L->p('Start typing to see a list of suggestions') ?>",
allowClear: true,
width: "100%",
theme: "bootstrap4",
minimumInputLength: 2,
dropdownParent: "#jsclippyContainer",
language: {
inputTooShort: function() {
return '';
}
},
ajax: {
url: HTML_PATH_ADMIN_ROOT + "ajax/clippy",
data: function(params) {
var query = {
query: params.term
}
return query;
},
processResults: function(data) {
return data;
}
},
templateResult: function(data) {
// console.log(data);
var html = '';
if (data.type == 'menu') {
html += '<a href="' + data.url + '"><div class="search-suggestion">';
html += '<span class="fa fa-' + data.icon + '"></span>' + data.text + '</div></a>';
} else {
if (typeof data.id === 'undefined') {
return '';
}
html += '<div class="search-suggestion">';
html += '<div class="search-suggestion-item">' + data.text + ' <span class="badge badge-pill badge-light">' + data.type + '</span></div>';
html += '<div class="search-suggestion-options">';
html += '<a target="_blank" href="' + DOMAIN_PAGES + data.id + '"><?php $L->p('view') ?></a>';
html += '<a class="ml-2" href="' + DOMAIN_ADMIN + 'edit-content/' + data.id + '"><?php $L->p('edit') ?></a>';
html += '</div></div>';
}
<div class="col-5">
return html;
},
escapeMarkup: function(markup) {
return markup;
}
}).on("select2:closing", function(e) {
e.preventDefault();
}).on("select2:closed", function(e) {
clippy.select2("open");
});
clippy.select2("open");
<!-- Notifications -->
<ul class="list-group">
<li class="list-group-item">
<h4 class="m-0 p-0"><i class="bi bi-bell"></i><?php $L->p('Notifications') ?></h4>
</li>
<?php
$logs = array_slice($syslog->db, 0, NOTIFICATIONS_AMOUNT);
foreach ($logs as $log) {
echo '<li class="list-group-item">';
echo '<div>';
echo $L->g($log['dictionaryKey']);
if (!empty($log['notes'])) {
echo ' « <b>'.$log['notes'].'</b> »';
}
echo '</div>';
echo '<div class="form-text">';
echo Date::format($log['date'], DB_DATE_FORMAT, NOTIFICATIONS_DATE_FORMAT);
echo ' [ '.$log['username'] .' ]';
echo '</div>';
echo '</li>';
}
?>
</ul>
<!-- End Notifications -->
});
</script>
</div>
</div>
</div>
<?php Theme::plugins('dashboard') ?>
</div>
<div class="col-md-5">
<!-- Notifications -->
<ul class="list-group list-group-striped b-0">
<li class="list-group-item pt-0">
<h4 class="m-0"><?php $L->p('Notifications') ?></h4>
</li>
<?php
$logs = array_slice($syslog->db, 0, NOTIFICATIONS_AMOUNT);
foreach ($logs as $log) {
$phrase = $L->g($log['dictionaryKey']);
echo '<li class="list-group-item">';
echo $phrase;
if (!empty($log['notes'])) {
echo ' « <b>' . $log['notes'] . '</b> »';
}
echo '<br><span class="notification-date"><small>';
echo Date::format($log['date'], DB_DATE_FORMAT, NOTIFICATIONS_DATE_FORMAT);
echo ' [ ' . $log['username'] . ' ]';
echo '</small></span>';
echo '</li>';
}
?>
</ul>
</div>
</div>
</div>

View file

@ -1,29 +1,3 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
<script>
// ============================================================================
// Variables for the view
// ============================================================================
// ============================================================================
// Functions for the view
// ============================================================================
// ============================================================================
// Events for the view
// ============================================================================
$(document).ready(function() {
// No events for the view yet
});
// ============================================================================
// Initialization for the view
// ============================================================================
$(document).ready(function() {
// No initialization for the view yet
});
</script>
<?php
echo Bootstrap::pageTitle(array('title'=>$L->g('Developers'), 'icon'=>'gears'));

View file

@ -1,135 +1,92 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
<script>
// ============================================================================
// Variables for the view
// ============================================================================
<?php echo Bootstrap::formOpen(array('id'=>'jsform')); ?>
// ============================================================================
// Functions for the view
// ============================================================================
// ============================================================================
// Events for the view
// ============================================================================
$(document).ready(function() {
$('#btnSave').on('click', function() {
var name = $('#name').val();
var friendlyURL = $('#friendlyURL').val();
if ((name.length < 1) || (friendlyURL.length < 1)) {
showAlertError("<?php $L->p('Complete all fields') ?>");
return false;
}
var args = {
key: $('#key').val(),
name: name,
description: $('#description').val(),
friendlyURL: $('#friendlyURL').val(),
template: $('#template').val()
};
api.editCategory(args).then(function(response) {
if (response.status == 0) {
logs('Category edited. Key: ' + response.data.key);
showAlertInfo("<?php $L->p('The changes have been saved') ?>");
$('#key').val(response.data.key);
} else {
logs('An error occurred while trying to edit the category.');
showAlertError(response.message);
}
});
return true;
});
$('#btnDelete').on('click', function() {
var key = $('#key').val();
logs('Deleting category. Key: ' + key);
bootbox.confirm({
message: '<?php $L->p('Are you sure you want to delete this category') ?>',
buttons: {
cancel: {
label: '<i class="fa fa-times"></i><?php $L->p('Cancel') ?>',
className: 'btn-sm btn-secondary'
},
confirm: {
label: '<i class="fa fa-check"></i><?php $L->p('Confirm') ?>',
className: 'btn-sm btn-primary'
}
},
closeButton: false,
callback: function(result) {
if (result) {
var args = {
key: key
};
api.deleteCategory(args).then(function(response) {
if (response.status == 0) {
logs('Category deleted. Key: ' + response.data.key);
window.location.replace(HTML_PATH_ADMIN_ROOT + 'categories');
} else {
logs('An error occurred while trying to delete the category.');
showAlertError(response.message);
}
});
return true;
}
}
});
});
});
// ============================================================================
// Initialization for the view
// ============================================================================
$(document).ready(function() {
// No initialization for the view yet
});
</script>
<div class="d-flex align-items-center mb-4">
<h2 class="m-0"><i class="bi bi-bookmark"></i><?php $L->p('Edit category') ?></h2>
<div class="ms-auto">
<button id="btnSave" type="button" class="btn btn-primary btn-sm"><?php $L->p('Save') ?></button>
<button id="btnDelete" type="button" class="btn btn-danger btn-sm"><?php $L->p('Delete') ?></button>
<a id="btnCancel" class="btn btn-secondary btn-sm" href="<?php echo HTML_PATH_ADMIN_ROOT . 'categories' ?>" role="button"><?php $L->p('Cancel') ?></a>
<div class="align-middle">
<div class="float-right mt-1">
<button type="submit" class="btn btn-primary btn-sm" name="save"><?php $L->p('Save') ?></button>
<button type="button" class="btn btn-danger btn-sm" data-toggle="modal" data-target="#jsdeleteModal"><?php $L->p('Delete') ?></button>
<a class="btn btn-secondary btn-sm" href="<?php echo HTML_PATH_ADMIN_ROOT.'dashboard' ?>" role="button"><?php $L->p('Cancel') ?></a>
</div>
<?php echo Bootstrap::pageTitle(array('title'=>$L->g('Edit Category'), 'icon'=>'cog')); ?>
</div>
<?php
echo Bootstrap::formInputHidden(array(
'id' => 'key',
'name' => 'key',
'value' => $categoryMap['key']
));
// Token CSRF
echo Bootstrap::formInputHidden(array(
'name'=>'tokenCSRF',
'value'=>$security->getTokenCSRF()
));
echo Bootstrap::formInputText(array(
'id' => 'name',
'name' => 'name',
'label' => $L->g('Name'),
'value' => $categoryMap['name']
));
echo Bootstrap::formInputHidden(array(
'name'=>'action',
'value'=>'edit'
));
echo Bootstrap::formTextarea(array(
'name' => 'description',
'label' => $L->g('Description'),
'value' => isset($categoryMap['description']) ? $categoryMap['description'] : '',
'rows' => 3
));
echo Bootstrap::formInputHidden(array(
'name'=>'oldKey',
'value'=>$categoryMap['key']
));
echo Bootstrap::formInputText(array(
'name' => 'template',
'label' => $L->g('Template'),
'value' => isset($categoryMap['template']) ? $categoryMap['template'] : ''
));
echo Bootstrap::formInputText(array(
'name'=>'name',
'label'=>$L->g('Name'),
'value'=>$categoryMap['name'],
'class'=>'',
'placeholder'=>'',
'tip'=>''
));
echo Bootstrap::formTextarea(array(
'name'=>'description',
'label'=>$L->g('Description'),
'value'=>isset($categoryMap['description'])?$categoryMap['description']:'',
'class'=>'',
'placeholder'=>'',
'tip'=>'',
'rows'=>3
));
echo Bootstrap::formInputText(array(
'name'=>'template',
'label'=>$L->g('Template'),
'value'=>isset($categoryMap['template'])?$categoryMap['template']:'',
'class'=>'',
'placeholder'=>'',
'tip'=>''
));
echo Bootstrap::formInputText(array(
'name'=>'newKey',
'label'=>$L->g('Friendly URL'),
'value'=>$categoryMap['key'],
'class'=>'',
'placeholder'=>'',
'tip'=>DOMAIN_CATEGORIES.$categoryMap['key']
));
echo Bootstrap::formClose();
echo Bootstrap::formInputText(array(
'name' => 'friendlyURL',
'label' => $L->g('Friendly URL'),
'value' => $categoryMap['key'],
'tip' => DOMAIN_CATEGORIES . $categoryMap['key']
));
?>
<!-- Modal for delete category -->
<?php
echo Bootstrap::modal(array(
'buttonPrimary'=>$L->g('Delete'),
'buttonPrimaryClass'=>'btn-danger jsbuttonDeleteAccept',
'buttonSecondary'=>$L->g('Cancel'),
'buttonSecondaryClass'=>'btn-link',
'modalTitle'=>$L->g('Delete category'),
'modalText'=>$L->g('Are you sure you want to delete this category?'),
'modalId'=>'jsdeleteModal'
));
?>
<script>
$(document).ready(function() {
// Delete content
$(".jsbuttonDeleteAccept").on("click", function() {
$("#jsaction").val("delete");
$("#jsform").submit();
});
});
</script>

View file

@ -0,0 +1,563 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
<?php
// FORM START
echo Bootstrap::formOpen(array(
'id' => 'jsform',
'class' => 'd-flex flex-column h-100'
));
// Token CSRF
echo Bootstrap::formInputHidden(array(
'name' => 'tokenCSRF',
'value' => $security->getTokenCSRF()
));
// UUID
// The UUID is generated in the controller
echo Bootstrap::formInputHidden(array(
'name' => 'uuid',
'value' => $page->uuid()
));
// Type = published, draft, sticky, static
echo Bootstrap::formInputHidden(array(
'name' => 'type',
'value' => $page->type()
));
// Cover image
echo Bootstrap::formInputHidden(array(
'name' => 'coverImage',
'value' => $page->coverImage(false)
));
// Content
echo Bootstrap::formInputHidden(array(
'name' => 'content',
'value' => ''
));
// Current page key
echo Bootstrap::formInputHidden(array(
'name' => 'key',
'value' => $page->key()
));
?>
<!-- TOOLBAR -->
<div id="jseditorToolbar" class="mb-1">
<div id="jseditorToolbarRight" class="btn-group btn-group-sm float-right" role="group" aria-label="Toolbar right">
<button type="button" class="btn btn-light" id="jsmediaManagerOpenModal" data-toggle="modal" data-target="#jsmediaManagerModal"><span class="fa fa-image"></span> <?php $L->p('Images') ?></button>
<button type="button" class="btn btn-light" id="jsoptionsSidebar" style="z-index:30"><span class="fa fa-cog"></span> <?php $L->p('Options') ?></button>
</div>
<div id="jseditorToolbarLeft">
<button type="button" class="btn btn-sm btn-primary" id="jsbuttonSave"><?php echo $L->g('Save') ?></button>
<button id="jsbuttonPreview" type="button" class="btn btn-sm btn-secondary"><?php $L->p('Preview') ?></button>
<span id="jsswitchButton" data-switch="<?php echo ($page->draft() ? 'draft' : 'publish') ?>" class="ml-2 text-secondary switch-button"><i class="fa fa-square switch-icon-<?php echo ($page->draft() ? 'draft' : 'publish') ?>"></i> <?php echo ($page->draft() ? $L->g('Draft') : $L->g('Publish')) ?></span>
</div>
<?php if ($page->scheduled()) : ?>
<div class="alert alert-warning p-1 mt-1 mb-0"><?php $L->p('scheduled') ?>: <?php echo $page->date(SCHEDULED_DATE_FORMAT) ?></div>
<?php endif; ?>
</div>
<script>
$(document).ready(function() {
$("#jsoptionsSidebar").on("click", function() {
$("#jseditorSidebar").toggle();
$("#jsshadow").toggle();
});
$("#jsshadow").on("click", function() {
$("#jseditorSidebar").toggle();
$("#jsshadow").toggle();
});
});
</script>
<!-- SIDEBAR OPTIONS -->
<div id="jseditorSidebar">
<nav>
<div class="nav nav-tabs" id="nav-tab" role="tablist">
<a class="nav-link active show" id="nav-general-tab" data-toggle="tab" href="#nav-general" role="tab" aria-controls="general"><?php $L->p('General') ?></a>
<a class="nav-link" id="nav-advanced-tab" data-toggle="tab" href="#nav-advanced" role="tab" aria-controls="advanced"><?php $L->p('Advanced') ?></a>
<?php if (!empty($site->customFields())) : ?>
<a class="nav-link" id="nav-custom-tab" data-toggle="tab" href="#nav-custom" role="tab" aria-controls="custom"><?php $L->p('Custom') ?></a>
<?php endif ?>
<a class="nav-link" id="nav-seo-tab" data-toggle="tab" href="#nav-seo" role="tab" aria-controls="seo"><?php $L->p('SEO') ?></a>
</div>
</nav>
<div class="tab-content pr-3 pl-3 pb-3">
<div id="nav-general" class="tab-pane fade show active" role="tabpanel" aria-labelledby="general-tab">
<?php
// Category
echo Bootstrap::formSelectBlock(array(
'name' => 'category',
'label' => $L->g('Category'),
'selected' => $page->categoryKey(),
'class' => '',
'emptyOption' => '- ' . $L->g('Uncategorized') . ' -',
'options' => $categories->getKeyNameArray()
));
// Description
echo Bootstrap::formTextareaBlock(array(
'name' => 'description',
'label' => $L->g('Description'),
'selected' => '',
'class' => '',
'value' => $page->description(),
'rows' => 5,
'placeholder' => $L->get('this-field-can-help-describe-the-content')
));
?>
<!-- Cover Image -->
<?php
$coverImage = $page->coverImage(false);
$externalCoverImage = '';
if (filter_var($coverImage, FILTER_VALIDATE_URL)) {
$coverImage = '';
$externalCoverImage = $page->coverImage(false);
}
?>
<label class="mt-4 mb-2 pb-2 border-bottom text-uppercase w-100"><?php $L->p('Cover Image') ?></label>
<div>
<img id="jscoverImagePreview" class="mx-auto d-block w-100" alt="Cover image preview" src="<?php echo (empty($coverImage) ? HTML_PATH_CORE_IMG . 'default.svg' : $page->coverImage()) ?>" />
</div>
<div class="mt-2 text-center">
<button type="button" id="jsbuttonSelectCoverImage" class="btn btn-primary btn-sm"><?php echo $L->g('Select cover image') ?></button>
<button type="button" id="jsbuttonRemoveCoverImage" class="btn btn-secondary btn-sm"><?php echo $L->g('Remove cover image') ?></button>
</div>
<script>
$(document).ready(function() {
$("#jscoverImagePreview").on("click", function() {
openMediaManager();
});
$("#jsbuttonSelectCoverImage").on("click", function() {
openMediaManager();
});
$("#jsbuttonRemoveCoverImage").on("click", function() {
$("#jscoverImage").val('');
$("#jscoverImagePreview").attr('src', HTML_PATH_CORE_IMG + 'default.svg');
});
});
</script>
</div>
<div id="nav-advanced" class="tab-pane fade" role="tabpanel" aria-labelledby="advanced-tab">
<?php
// Date
echo Bootstrap::formInputTextBlock(array(
'name' => 'date',
'label' => $L->g('Date'),
'placeholder' => '',
'value' => $page->dateRaw(),
'tip' => $L->g('date-format-format')
));
// Type
echo Bootstrap::formSelectBlock(array(
'name' => 'typeSelector',
'label' => $L->g('Type'),
'selected' => $page->type(),
'options' => array(
'published' => '- ' . $L->g('Default') . ' -',
'sticky' => $L->g('Sticky'),
'static' => $L->g('Static')
),
'tip' => ''
));
// Position
echo Bootstrap::formInputTextBlock(array(
'name' => 'position',
'label' => $L->g('Position'),
'tip' => $L->g('Field used when ordering content by position'),
'value' => $page->position()
));
// Tags
echo Bootstrap::formInputTextBlock(array(
'name' => 'tags',
'label' => $L->g('Tags'),
'placeholder' => '',
'tip' => $L->g('Write the tags separated by comma'),
'value' => $page->tags()
));
// Parent
try {
$options = array();
$parentKey = $page->parent();
if (!empty($parentKey)) {
$parent = new Page($parentKey);
$options = array($parentKey => $parent->title());
}
} catch (Exception $e) {
// continue
}
echo Bootstrap::formSelectBlock(array(
'name' => 'parent',
'label' => $L->g('Parent'),
'options' => $options,
'selected' => false,
'class' => '',
'tip' => $L->g('Start typing a page title to see a list of suggestions.'),
));
?>
<script>
$(document).ready(function() {
var parent = $("#jsparent").select2({
placeholder: "",
allowClear: true,
theme: "bootstrap4",
minimumInputLength: 2,
ajax: {
url: HTML_PATH_ADMIN_ROOT + "ajax/get-published",
data: function(params) {
var query = {
checkIsParent: true,
query: params.term
}
return query;
},
processResults: function(data) {
return data;
}
},
escapeMarkup: function(markup) {
return markup;
},
templateResult: function(data) {
var html = data.text
if (data.type == "static") {
html += '<span class="badge badge-pill badge-light">' + data.type + '</span>';
}
return html;
}
});
});
</script>
<?php
// Template
echo Bootstrap::formInputTextBlock(array(
'name' => 'template',
'label' => $L->g('Template'),
'placeholder' => '',
'value' => $page->template(),
'tip' => $L->g('Write a template name to filter the page in the theme and change the style of the page.')
));
echo Bootstrap::formInputTextBlock(array(
'name' => 'externalCoverImage',
'label' => $L->g('External cover image'),
'placeholder' => "https://",
'value' => $externalCoverImage,
'tip' => $L->g('Set a cover image from external URL, such as a CDN or some server dedicated for images.')
));
// Username
echo Bootstrap::formInputTextBlock(array(
'name' => '',
'label' => $L->g('Author'),
'placeholder' => '',
'value' => $page->username(),
'tip' => '',
'disabled' => true
));
?>
<script>
$(document).ready(function() {
// Changes in External cover image input
$("#jsexternalCoverImage").change(function() {
$("#jscoverImage").val($(this).val());
});
// Datepicker
$("#jsdate").datetimepicker({
format: DB_DATE_FORMAT
});
});
</script>
</div>
<?php if (!empty($site->customFields())) : ?>
<div id="nav-custom" class="tab-pane fade" role="tabpanel" aria-labelledby="custom-tab">
<?php
$customFields = $site->customFields();
foreach ($customFields as $field => $options) {
if (!isset($options['position'])) {
if ($options['type'] == "string") {
echo Bootstrap::formInputTextBlock(array(
'name' => 'custom[' . $field . ']',
'value' => (isset($options['default']) ? $options['default'] : ''),
'tip' => (isset($options['tip']) ? $options['tip'] : ''),
'label' => (isset($options['label']) ? $options['label'] : ''),
'placeholder' => (isset($options['placeholder']) ? $options['placeholder'] : ''),
'value' => $page->custom($field)
));
} elseif ($options['type'] == "bool") {
echo Bootstrap::formCheckbox(array(
'name' => 'custom[' . $field . ']',
'label' => (isset($options['label']) ? $options['label'] : ''),
'placeholder' => (isset($options['placeholder']) ? $options['placeholder'] : ''),
'checked' => $page->custom($field),
'labelForCheckbox' => (isset($options['tip']) ? $options['tip'] : '')
));
}
}
}
?>
</div>
<?php endif ?>
<div id="nav-seo" class="tab-pane fade" role="tabpanel" aria-labelledby="seo-tab">
<?php
// Friendly URL
echo Bootstrap::formInputTextBlock(array(
'name' => 'slug',
'tip' => $L->g('URL associated with the content'),
'label' => $L->g('Friendly URL'),
'placeholder' => $L->g('Leave empty for autocomplete by Bludit.'),
'value' => $page->slug()
));
// Robots
echo Bootstrap::formCheckbox(array(
'name' => 'noindex',
'label' => 'Robots',
'labelForCheckbox' => $L->g('apply-code-noindex-code-to-this-page'),
'placeholder' => '',
'checked' => $page->noindex(),
'tip' => $L->g('This tells search engines not to show this page in their search results.')
));
// Robots
echo Bootstrap::formCheckbox(array(
'name' => 'nofollow',
'label' => '',
'labelForCheckbox' => $L->g('apply-code-nofollow-code-to-this-page'),
'placeholder' => '',
'checked' => $page->nofollow(),
'tip' => $L->g('This tells search engines not to follow links on this page.')
));
// Robots
echo Bootstrap::formCheckbox(array(
'name' => 'noarchive',
'label' => '',
'labelForCheckbox' => $L->g('apply-code-noarchive-code-to-this-page'),
'placeholder' => '',
'checked' => $page->noarchive(),
'tip' => $L->g('This tells search engines not to save a cached copy of this page.')
));
?>
</div>
</div>
</div>
<!-- Custom fields: TOP -->
<?php
$customFields = $site->customFields();
foreach ($customFields as $field => $options) {
if (isset($options['position']) && ($options['position'] == 'top')) {
if ($options['type'] == "string") {
echo Bootstrap::formInputTextBlock(array(
'name' => 'custom[' . $field . ']',
'label' => (isset($options['label']) ? $options['label'] : ''),
'value' => $page->custom($field),
'tip' => (isset($options['tip']) ? $options['tip'] : ''),
'placeholder' => (isset($options['placeholder']) ? $options['placeholder'] : ''),
'class' => 'mb-2',
'labelClass' => 'mb-2 pb-2 border-bottom text-uppercase w-100'
));
} elseif ($options['type'] == "bool") {
echo Bootstrap::formCheckbox(array(
'name' => 'custom[' . $field . ']',
'label' => (isset($options['label']) ? $options['label'] : ''),
'placeholder' => (isset($options['placeholder']) ? $options['placeholder'] : ''),
'checked' => $page->custom($field),
'labelForCheckbox' => (isset($options['tip']) ? $options['tip'] : ''),
'class' => 'mb-2',
'labelClass' => 'mb-2 pb-2 border-bottom text-uppercase w-100'
));
}
}
}
?>
<!-- Title -->
<div class="form-group mb-1">
<input id="jstitle" name="title" type="text" dir="auto" class="form-control form-control-lg rounded-0" value="<?php echo $page->title() ?>" placeholder="<?php $L->p('Enter title') ?>">
</div>
<!-- Editor -->
<textarea id="jseditor" class="editable h-100" style=""><?php echo $page->contentRaw(true) ?></textarea>
<!-- Custom fields: BOTTOM -->
<?php
$customFields = $site->customFields();
foreach ($customFields as $field => $options) {
if (isset($options['position']) && ($options['position'] == 'bottom')) {
if ($options['type'] == "string") {
echo Bootstrap::formInputTextBlock(array(
'name' => 'custom[' . $field . ']',
'label' => (isset($options['label']) ? $options['label'] : ''),
'value' => $page->custom($field),
'tip' => (isset($options['tip']) ? $options['tip'] : ''),
'placeholder' => (isset($options['placeholder']) ? $options['placeholder'] : ''),
'class' => 'mt-2',
'labelClass' => 'mb-2 pb-2 border-bottom text-uppercase w-100'
));
} elseif ($options['type'] == "bool") {
echo Bootstrap::formCheckbox(array(
'name' => 'custom[' . $field . ']',
'label' => (isset($options['label']) ? $options['label'] : ''),
'placeholder' => (isset($options['placeholder']) ? $options['placeholder'] : ''),
'checked' => $page->custom($field),
'labelForCheckbox' => (isset($options['tip']) ? $options['tip'] : ''),
'class' => 'mt-2',
'labelClass' => 'mb-2 pb-2 border-bottom text-uppercase w-100'
));
}
}
}
?>
</form>
<!-- Modal for Delete page -->
<div id="jsdeletePageModal" class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<h3><?php $L->p('Delete content') ?></h3>
<p><?php $L->p('Are you sure you want to delete this page') ?></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-link" data-dismiss="modal"><?php $L->p('Cancel') ?></button>
<button type="button" class="btn btn-danger" data-dismiss="modal" id="jsbuttonDeleteAccept"><?php $L->p('Delete') ?></button>
</div>
</div>
</div>
<script>
$(document).ready(function() {
$("#jsbuttonDeleteAccept").on("click", function() {
$("#jstype").val("delete");
$("#jscontent").val("");
$("#jsform").submit();
});
});
</script>
</div>
<!-- Modal for Media Manager -->
<?php include(PATH_ADMIN_THEMES . 'booty/html/media.php'); ?>
<script>
$(document).ready(function() {
// Define function if they doesn't exist
// This helps if the user doesn't activate any plugin as editor
if (typeof editorGetContent != "function") {
window.editorGetContent = function() {
return $("#jseditor").val();
};
}
if (typeof editorInsertMedia != "function") {
window.editorInsertMedia = function(filename) {
$("#jseditor").val($('#jseditor').val() + '<img src="' + filename + '" alt="">');
};
}
if (typeof editorInsertLinkedMedia != "function") {
window.editorInsertLinkedMedia = function(filename, link) {
$("#jseditor").val($('#jseditor').val() + '<a href="' + link + '"><img src="' + filename + '" alt=""></a>');
};
}
// Button switch
$("#jsswitchButton").on("click", function() {
if ($(this).data("switch") == "publish") {
$(this).html('<i class="fa fa-square switch-icon-draft"></i> <?php $L->p('Draft') ?>');
$(this).data("switch", "draft");
} else {
$(this).html('<i class="fa fa-square switch-icon-publish"></i> <?php $L->p('Publish') ?>');
$(this).data("switch", "publish");
}
});
// Button preview
$("#jsbuttonPreview").on("click", function() {
var uuid = $("#jsuuid").val();
var title = $("#jstitle").val();
var content = editorGetContent();
var ajax = new bluditAjax();
bluditAjax.saveAsDraft(uuid, title, content).then(function(data) {
var preview = window.open("<?php echo DOMAIN_PAGES . 'autosave-' . $page->uuid() . '?preview=' . md5('autosave-' . $page->uuid()) ?>", "bludit-preview");
preview.focus();
});
});
// Button Save
$("#jsbuttonSave").on("click", function() {
// If the switch is setted to "published", get the value from the selector
if ($("#jsswitchButton").data("switch") == "publish") {
var value = $("#jstypeSelector option:selected").val();
$("#jstype").val(value);
} else {
$("#jstype").val("draft");
}
// Get the content
$("#jscontent").val(editorGetContent());
// Submit the form
$("#jsform").submit();
});
// Button Save as draft
$("#jsbuttonDraft").on("click", function() {
// Set the type as draft
$("#jstype").val("draft");
// Get the content
$("#jscontent").val(editorGetContent());
// Submit the form
$("#jsform").submit();
});
// Autosave
var currentContent = editorGetContent();
setInterval(function() {
var uuid = $("#jsuuid").val();
var title = $("#jstitle").val() + "[<?php $L->p('Autosave') ?>]";
var content = editorGetContent();
// Autosave when content has at least 100 characters
if (content.length < 100) {
return false;
}
// Autosave only when the user change the content
if (currentContent != content) {
currentContent = content;
bluditAjax.saveAsDraft(uuid, title, content).then(function(data) {
if (data.status == 0) {
showAlert("<?php $L->p('Autosave') ?>");
}
});
}
}, 1000 * 60 * AUTOSAVE_INTERVAL);
});
</script>

View file

@ -1,276 +1,52 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
<script>
// ============================================================================
// Variables for the view
// ============================================================================
<?php echo Bootstrap::formOpen(array('id' => 'jsform', 'class' => 'tab-content')); ?>
// ============================================================================
// Functions for the view
// ============================================================================
function changePassword() {
var newPassword = $('#newPassword').val();
var confirmPassword = $('#confirmPassword').val();
if (newPassword.length < PASSWORD_LENGTH) {
showAlertError("<?php $L->p('Password must be at least 6 characters long') ?>");
return false;
}
if (newPassword !== confirmPassword) {
showAlertError("<?php $L->p('The password and confirmation password do not match') ?>");
return false;
}
bootbox.confirm({
message: '<?php $L->p('Are you sure you want to change the password') ?>',
buttons: {
cancel: {
label: '<i class="fa fa-times"></i><?php $L->p('Cancel') ?>',
className: 'btn-sm btn-secondary'
},
confirm: {
label: '<i class="fa fa-check"></i><?php $L->p('Confirm') ?>',
className: 'btn-sm btn-primary'
}
},
closeButton: false,
callback: function(result) {
if (result) {
// The user accepted the action to change the password
var args = {
username: $('#username').val(),
password: $('#newPassword').val()
};
api.editUser(args).then(function(response) {
if (response.status == 0) {
logs('User password changed. Username: ' + response.data.key);
showAlertInfo("<?php $L->p('The changes have been saved') ?>");
} else {
logs('An error occurred while trying to change the user password.');
showAlertError(response.message);
}
});
}
$('#newPassword').val('');
$('#confirmPassword').val('');
return true;
}
});
}
function save() {
let args = {
username: $('#username').val(),
role: $('#role').val()
};
$('input[data-save="true"]').each(function() {
var key = $(this).attr('name');
var value = $(this).val();
args[key] = value;
});
$('select[data-save="true"]').each(function() {
var key = $(this).attr('name');
var value = $(this).val();
args[key] = value;
});
$('textarea[data-save="true"]').each(function() {
var key = $(this).attr('name');
var value = $(this).val();
args[key] = value;
});
api.editUser(args).then(function(response) {
if (response.status == 0) {
logs('User edited. Username: ' + response.data.key);
showAlertInfo("<?php $L->p('The changes have been saved') ?>");
} else {
logs('An error occurred while trying to edit the user.');
showAlertError(response.message);
}
});
}
// ============================================================================
// Events for the view
// ============================================================================
$(document).ready(function() {
$('#btnSave').on('click', function() {
// Change the password if the user write a new one in the input
if ($('#newPassword').val()) {
changePassword();
} else {
// Save the edited fields
save();
}
});
$('#inputProfilePicture').on("change", function(e) {
var inputProfilePicture = $('#inputProfilePicture')[0].files;
var username = $('#username').val();
var formData = new FormData();
formData.append("file", inputProfilePicture[0]);
formData.append("token", api.body.token);
formData.append("authentication", api.body.authentication);
$.ajax({
url: api.apiURL + 'users/picture/' + username,
type: "POST",
data: formData,
cache: false,
contentType: false,
processData: false,
xhr: function() {
var xhr = $.ajaxSettings.xhr();
if (xhr.upload) {
xhr.upload.addEventListener("progress", function(e) {
if (e.lengthComputable) {
var percentComplete = (e.loaded / e.total) * 100;
logs('Uploading profile image: ' + percentComplete + '%');
}
}, false);
}
return xhr;
}
}).done(function(response) {
logs(response);
if (response.status == 0) {
logs("Profile picture uploaded.");
showAlertInfo("<?php $L->p('The changes have been saved') ?>");
$('#profilePicturePreview').attr('src', response.data.absoluteURL);
} else {
logs("An error occurred while trying to upload the profile picture.");
showAlertError(response.message);
}
});
return true;
});
$('#btnRemoveProfilePicture').on('click', function() {
var username = $('#username').val();
logs('Deleting profile picture. Username: ' + username);
bootbox.confirm({
message: '<?php $L->p('Are you sure you want to delete the profile picture') ?>',
buttons: {
cancel: {
label: '<i class="fa fa-times"></i><?php $L->p('Cancel') ?>',
className: 'btn-sm btn-secondary'
},
confirm: {
label: '<i class="fa fa-check"></i><?php $L->p('Confirm') ?>',
className: 'btn-sm btn-primary'
}
},
closeButton: false,
callback: function(result) {
if (result) {
var args = {
username: username
};
api.deleteProfilePicture(args).then(function(response) {
if (response.status == 0) {
logs('Profile picture deleted. Username: ' + response.data.key);
showAlertInfo("<?php $L->p('The changes have been saved') ?>");
$('#profilePicturePreview').attr('src', '<?php echo HTML_PATH_CORE_IMG . 'default.svg' ?>');
} else {
logs("An error occurred while trying to delete the profile picture.");
showAlertError(response.message);
}
});
return true;
}
}
});
});
$('#btnDisableUser').on('click', function() {
var username = $('#username').val();
logs('Disabling user. Username: ' + username);
bootbox.confirm({
message: '<?php $L->p('Are you sure you want to disable this user') ?>',
buttons: {
cancel: {
label: '<i class="fa fa-times"></i><?php $L->p('Cancel') ?>',
className: 'btn-sm btn-secondary'
},
confirm: {
label: '<i class="fa fa-check"></i><?php $L->p('Confirm') ?>',
className: 'btn-sm btn-primary'
}
},
closeButton: false,
callback: function(result) {
if (result) {
var args = {
username: $('#username').val(),
disable: true
};
api.editUser(args).then(function(response) {
if (response.status == 0) {
logs('User disabled. Username: ' + response.data.key);
window.location.replace(HTML_PATH_ADMIN_ROOT + 'users');
} else {
logs("An error occurred while trying to disable the user.");
showAlertError(response.message);
}
});
}
}
});
});
});
// ============================================================================
// Initlization for the view
// ============================================================================
$(document).ready(function() {
// nothing here yet
// how do you hang your toilet paper ? over or under ?
});
</script>
<div class="d-flex align-items-center mb-4">
<h2 class="m-0"><i class="bi bi-person"></i><?php $L->p('Edit user') ?></h2>
<div class="ms-auto">
<button id="btnSave" type="button" class="btn btn-primary btn-sm"><?php $L->p('Save') ?></button>
<a id="btnCancel" class="btn btn-secondary btn-sm" href="<?php echo HTML_PATH_ADMIN_ROOT . 'users' ?>" role="button"><?php $L->p('Cancel') ?></a>
<div class="align-middle">
<div class="float-right mt-1">
<button type="submit" class="btn btn-primary btn-sm" name="save"><?php $L->p('Save') ?></button>
<a class="btn btn-secondary btn-sm" href="<?php echo HTML_PATH_ADMIN_ROOT . 'users' ?>" role="button"><?php $L->p('Cancel') ?></a>
</div>
<?php echo Bootstrap::pageTitle(array('title' => $L->g('Edit user'), 'icon' => 'user')); ?>
</div>
<!-- Tabs -->
<ul class="nav nav-tabs ps-3 mb-3" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="profile-tab" data-bs-toggle="tab" href="#profile" role="tab" aria-controls="profile" aria-selected="true"><?php $L->p('Profile') ?></a>
</li>
<li class="nav-item">
<a class="nav-link" id="picture-tab" data-bs-toggle="tab" href="#picture" role="tab" aria-controls="picture" aria-selected="false"><?php $L->p('Profile picture') ?></a>
</li>
<li class="nav-item">
<a class="nav-link" id="security-tab" data-bs-toggle="tab" href="#security" role="tab" aria-controls="security" aria-selected="false"><?php $L->p('Security') ?></a>
</li>
<li class="nav-item">
<a class="nav-link" id="social-tab" data-bs-toggle="tab" href="#social" role="tab" aria-controls="social" aria-selected="false"><?php $L->p('Social Networks') ?></a>
</li>
</ul>
<!-- End Tabs -->
<!-- TABS -->
<nav class="mb-3">
<div class="nav nav-tabs" id="nav-tab" role="tablist">
<a class="nav-item nav-link active" id="nav-profile-tab" data-toggle="tab" href="#profile" role="tab" aria-controls="nav-profile" aria-selected="false"><?php $L->p('Profile') ?></a>
<a class="nav-item nav-link" id="nav-picture-tab" data-toggle="tab" href="#picture" role="tab" aria-controls="nav-picture" aria-selected="false"><?php $L->p('Profile picture') ?></a>
<a class="nav-item nav-link" id="nav-security-tab" data-toggle="tab" href="#security" role="tab" aria-controls="nav-security" aria-selected="false"><?php $L->p('Security') ?></a>
<a class="nav-item nav-link" id="nav-social-tab" data-toggle="tab" href="#social" role="tab" aria-controls="nav-social" aria-selected="false"><?php $L->p('Social Networks') ?></a>
</div>
</nav>
<!-- Content -->
<div class="tab-content" id="tabContent">
<?php
// Token CSRF
echo Bootstrap::formInputHidden(array(
'name' => 'tokenCSRF',
'value' => $security->getTokenCSRF()
));
<!-- Tab profile -->
<div class="tab-pane show active" id="profile" role="tabpanel">
// Username
echo Bootstrap::formInputHidden(array(
'name' => 'username',
'value' => $user->username()
));
?>
<div class="tab-content" id="nav-tabContent">
<!-- Profile tab -->
<div class="tab-pane fade show active" id="profile" role="tabpanel" aria-labelledby="nav-profile-tab">
<?php
// Display username but disable the field
echo Bootstrap::formInputText(array(
'name' => 'username',
'name' => 'usernameDisabled',
'label' => $L->g('Username'),
'value' => $user->username(),
'disabled' => true
'class' => '',
'placeholder' => '',
'disabled' => true,
'tip' => ''
));
if ($login->role() === 'admin') {
@ -279,6 +55,7 @@
'label' => $L->g('Role'),
'options' => array('author' => $L->g('Author'), 'editor' => $L->g('Editor'), 'admin' => $L->g('Administrator')),
'selected' => $user->role(),
'class' => '',
'tip' => $L->g('author-can-write-and-edit-their-own-content')
));
}
@ -287,92 +64,96 @@
'name' => 'email',
'label' => $L->g('Email'),
'value' => $user->email(),
'data' => array('save' => 'true')
'class' => '',
'placeholder' => '',
'tip' => ''
));
echo Bootstrap::formInputText(array(
'name' => 'nickname',
'label' => $L->g('Nickname'),
'value' => $user->nickname(),
'tip' => $L->g('The nickname is almost used in the themes to display the author of the content'),
'data' => array('save' => 'true')
'class' => '',
'placeholder' => '',
'tip' => $L->g('The nickname is almost used in the themes to display the author of the content')
));
echo Bootstrap::formInputText(array(
'name' => 'firstName',
'label' => $L->g('First Name'),
'value' => $user->firstName(),
'data' => array('save' => 'true')
'class' => '',
'placeholder' => '',
'tip' => ''
));
echo Bootstrap::formInputText(array(
'name' => 'lastName',
'label' => $L->g('Last Name'),
'value' => $user->lastName(),
'data' => array('save' => 'true')
));
echo Bootstrap::formTextarea(array(
'name' => 'bio',
'label' => $L->g('Bio'),
'value' => $user->bio(),
'rows' => 4,
'data' => array('save' => 'true')
'class' => '',
'placeholder' => '',
'tip' => ''
));
?>
</div>
<!-- End Tab profile -->
<!-- Tab profile picture -->
<div class="tab-pane" id="picture" role="tabpanel">
<!-- Profile picture tab -->
<div class="tab-pane fade" id="picture" role="tabpanel" aria-labelledby="nav-picture-tab">
<div class="container">
<div class="row">
<div class="col-8">
<img id="profilePicturePreview" class="img-fluid img-thumbnail" alt="Profile picture preview" src="<?php echo ($user->profilePicture() ? $user->profilePicture() . '?version=' . time() : HTML_PATH_CORE_IMG . 'default.svg') ?>" />
<div class="col-lg-4 col-sm-12 p-0 pr-2">
<div class="custom-file">
<input type="file" class="custom-file-input" id="jsprofilePictureInputFile" name="profilePictureInputFile">
<label class="custom-file-label" for="jsprofilePictureInputFile"><?php $L->p('Upload image'); ?></label>
</div>
<!-- <button id="jsbuttonRemovePicture" type="button" class="btn btn-primary w-100 mt-4 mb-4"><i class="fa fa-trash"></i> Remove picture</button> -->
</div>
<div class="col-4">
<label id="btnUploadProfilePicture" class="btn btn-primary"><i class="bi bi-upload"></i><?php $L->p('Upload image'); ?><input type="file" id="inputProfilePicture" name="inputProfilePicture" hidden></label>
<button id="btnRemoveProfilePicture" type="button" class="btn btn-secondary"><i class="bi bi-trash"></i><?php $L->p('Remove image'); ?></button>
<div class="col-lg-8 col-sm-12 p-0 text-center">
<img id="jsprofilePicturePreview" class="img-fluid img-thumbnail" alt="Profile picture preview" src="<?php echo (Sanitize::pathFile(PATH_UPLOADS_PROFILES . $user->username() . '.png') ? DOMAIN_UPLOADS_PROFILES . $user->username() . '.png?version=' . time() : HTML_PATH_CORE_IMG . 'default.svg') ?>" />
</div>
</div>
</div>
<script>
// $("#jsbuttonRemovePicture").on("click", function() {
// var username = $("#jsusername").val();
// bluditAjax.removeProfilePicture(username);
// $("#jsprofilePicturePreview").attr("src", "<?php echo HTML_PATH_CORE_IMG . 'default.svg' ?>");
// });
$("#jsprofilePictureInputFile").on("change", function() {
var formData = new FormData();
formData.append('tokenCSRF', tokenCSRF);
formData.append('profilePictureInputFile', $(this)[0].files[0]);
formData.append('username', $("#jsusername").val());
$.ajax({
url: HTML_PATH_ADMIN_ROOT + "ajax/profile-picture-upload",
type: "POST",
data: formData,
cache: false,
contentType: false,
processData: false
}).done(function(data) {
if (data.status == 0) {
$("#jsprofilePicturePreview").attr('src', data.absoluteURL + "?time=" + Math.random());
} else {
showAlert(data.message);
}
});
});
</script>
</div>
<!-- End Tab profile picture -->
<!-- Tab security -->
<div class="tab-pane" id="security" role="tabpanel">
<!-- Security tab -->
<div class="tab-pane fade" id="security" role="tabpanel" aria-labelledby="nav-security-tab">
<?php
if (checkRole(array('admin'), false)) {
echo Bootstrap::formTitle(array('title' => $L->g('Status')));
echo Bootstrap::formTitle(array('title' => $L->g('Password')));
echo Bootstrap::formInputText(array(
'name' => 'status',
'label' => $L->g('Current status'),
'value' => $user->enabled() ? $L->g('Enabled') : $L->g('Disabled'),
'disabled' => true,
'tip' => $user->enabled() ? '' : $L->g('To enable the user you must set a new password')
));
echo Bootstrap::formInputText(array(
'name' => 'registered',
'label' => $L->g('Registered'),
'value' => Date::format($user->registered(), DB_DATE_FORMAT, ADMIN_PANEL_DATE_FORMAT),
'disabled' => true
));
if ($user->enabled()) {
echo '
<div class="form-group row">
<div class="col-sm-2"></div>
<div class="col-sm-10">
<button type="button" class="btn btn-warning me-2" id="btnDisableUser"><i class="bi bi-slash-circle"></i>' . $L->g('Disable user') . '</button>
<button type="button" class="btn btn-danger me-2" id="btnDeleteUserAndKeepContent"><i class="bi bi-trash"></i>' . $L->g('Delete user and keep content') . '</button>
<button type="button" class="btn btn-danger" id="btnDeleteUserAndContent"><i class="bi bi-trash"></i>' . $L->g('Delete user and delete content') . '</button>
</div>
</div>
';
}
}
echo '
<div class="form-group">
<a href="' . HTML_PATH_ADMIN_ROOT . 'user-password/' . $user->username() . '" class="btn btn-primary mr-2">' . $L->g('Change password') . '</a>
</div>
';
echo Bootstrap::formTitle(array('title' => $L->g('Authentication Token')));
@ -380,114 +161,156 @@
'name' => 'tokenAuth',
'label' => $L->g('Token'),
'value' => $user->tokenAuth(),
'class' => '',
'tip' => $L->g('this-token-is-similar-to-a-password-it-should-not-be-shared')
));
echo Bootstrap::formTitle(array('title' => $L->g('Change password')));
if (checkRole(array('admin'), false)) {
echo Bootstrap::formTitle(array('title' => $L->g('Status')));
echo Bootstrap::formInputText(array(
'name' => 'newPassword',
'label' => $L->g('New password'),
'type' => 'password',
'value' => ''
));
echo Bootstrap::formInputText(array(
'name' => 'status',
'label' => $L->g('Current status'),
'value' => $user->enabled() ? $L->g('Enabled') : $L->g('Disabled'),
'class' => '',
'disabled' => true,
'tip' => $user->enabled() ? '' : $L->g('To enable the user you must set a new password')
));
echo Bootstrap::formInputText(array(
'name' => 'confirmPassword',
'label' => $L->g('Confirm password'),
'type' => 'password',
'value' => ''
));
if ($user->enabled()) {
echo '
<div class="form-group row">
<div class="col-sm-2"></div>
<div class="col-sm-10">
<button type="submit" class="btn btn-warning mr-2" id="jsdisableUser" name="disableUser">' . $L->g('Disable user') . '</button>
<button type="submit" class="btn btn-danger mr-2" id="jsdeleteUserAndKeepContent" name="deleteUserAndKeepContent">' . $L->g('Delete user and keep content') . '</button>
<button type="submit" class="btn btn-danger mr-2" id="jsdeleteUserAndDeleteContent" name="deleteUserAndDeleteContent">' . $L->g('Delete user and delete content') . '</button>
</div>
</div>
';
}
}
?>
</div>
<!-- End Tab security -->
<!-- Social Networks tab -->
<div class="tab-pane" id="social" role="tabpanel">
<div class="tab-pane fade" id="social" role="tabpanel" aria-labelledby="nav-social-tab">
<?php
echo Bootstrap::formInputText(array(
'name' => 'youtube',
'label' => 'Youtube',
'value' => $user->youtube(),
'data' => array('save' => 'true')
));
echo Bootstrap::formInputText(array(
'name' => 'twitter',
'label' => 'Twitter',
'value' => $user->twitter(),
'data' => array('save' => 'true')
'class' => '',
'placeholder' => '',
'tip' => ''
));
echo Bootstrap::formInputText(array(
'name' => 'facebook',
'label' => 'Facebook',
'value' => $user->facebook(),
'data' => array('save' => 'true')
));
echo Bootstrap::formInputText(array(
'name' => 'discord',
'label' => 'Discord',
'value' => $user->discord(),
'data' => array('save' => 'true')
'class' => '',
'placeholder' => '',
'tip' => ''
));
echo Bootstrap::formInputText(array(
'name' => 'codepen',
'label' => 'CodePen',
'value' => $user->codepen(),
'data' => array('save' => 'true')
'class' => '',
'placeholder' => '',
'tip' => ''
));
echo Bootstrap::formInputText(array(
'name' => 'instagram',
'label' => 'Instagram',
'value' => $user->instagram(),
'data' => array('save' => 'true')
'class' => '',
'placeholder' => '',
'tip' => ''
));
echo Bootstrap::formInputText(array(
'name' => 'gitlab',
'label' => 'GitLab',
'value' => $user->gitlab(),
'data' => array('save' => 'true')
'class' => '',
'placeholder' => '',
'tip' => ''
));
echo Bootstrap::formInputText(array(
'name' => 'github',
'label' => 'GitHub',
'value' => $user->github(),
'data' => array('save' => 'true')
'class' => '',
'placeholder' => '',
'tip' => ''
));
echo Bootstrap::formInputText(array(
'name' => 'linkedin',
'label' => 'LinkedIn',
'value' => $user->linkedin(),
'data' => array('save' => 'true')
'class' => '',
'placeholder' => '',
'tip' => ''
));
echo Bootstrap::formInputText(array(
'name' => 'xing',
'label' => 'Xing',
'value' => $user->xing(),
'data' => array('save' => 'true')
'class' => '',
'placeholder' => '',
'tip' => ''
));
echo Bootstrap::formInputText(array(
'name' => 'telegram',
'label' => 'Telegram',
'value' => $user->telegram(),
'class' => '',
'placeholder' => '',
'tip' => ''
));
echo Bootstrap::formInputText(array(
'name' => 'mastodon',
'label' => 'Mastodon',
'value' => $user->mastodon(),
'data' => array('save' => 'true')
'class' => '',
'placeholder' => '',
'tip' => ''
));
echo Bootstrap::formInputText(array(
'name' => 'vk',
'label' => 'VK',
'value' => $user->vk(),
'data' => array('save' => 'true')
'class' => '',
'placeholder' => '',
'tip' => ''
));
?>
</div>
</div>
<?php echo Bootstrap::formClose(); ?>
<script>
// Open current tab after refresh page
$(function() {
$('a[data-toggle="tab"]').on('click', function(e) {
window.localStorage.setItem('activeTab', $(e.target).attr('href'));
console.log($(e.target).attr('href'));
});
var activeTab = window.localStorage.getItem('activeTab');
if (activeTab) {
$('#nav-tab a[href="' + activeTab + '"]').tab('show');
//window.localStorage.removeItem("activeTab");
}
});
</script>

View file

@ -1,679 +0,0 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
<script>
// ============================================================================
// Variables for the view
// ============================================================================
var _pageKey = <?php echo $pageKey ? '"' . $pageKey . '"' : 'null' ?>;
// ============================================================================
// Functions for the view
// ============================================================================
// Default function for the editor
// These functions work if the user does not activate any plugin
if (typeof editorGetContent != 'function') {
window.editorGetContent = function() {
return $('#editor').val();
};
}
if (typeof editorInsertContent != 'function') {
window.editorInsertContent = function(content, type = '') {
if (type == 'image') {
var html = '<img src="' + content + '" alt="" />';
} else {
var html = content;
}
$('#editor').val($('#editor').val() + html);
};
}
// Create the a page
// This function set the global variable "_pageKey"
function createPage() {
logs('Creating page.');
api.createPage().then(function(response) {
if (response.status == 0) {
logs('Page created. Key: ' + response.data.key);
// Set the global variable with the page key
_pageKey = response.data.key;
// Set Friendly URL
$('#friendlyURL').val(response.data.key);
// Get current files
fmGetFiles();
} else {
logs("An error occurred while trying to create the page.");
showAlertError(response.message);
}
});
return true;
}
// Set the page in the editor
function setPage() {
logs('Setting up the page');
// Get current files
fmGetFiles();
return true;
}
// Save the current page
// This function set the global variable "_pageKey"
function savePage(args) {
logs('Saving page.');
if (_pageKey == null) {
logs('Error, page not created.');
showAlertError("Error, page not created.");
return false;
}
args['pageKey'] = _pageKey;
api.savePage(args).then(function(response) {
if (response.status == 0) {
logs('Page saved. Old key: ' + _pageKey + ' / New key: ' + response.data.key);
// Set the global variable with the page key
// The page key can change after save the page so you need to set again the variable
_pageKey = response.data.key;
// Set friendly URL with the key
$('#friendlyURL').val(response.data.key);
} else {
logs('An error occurred while trying to save the current page.');
showAlertError(response.message);
}
});
return true;
}
// Open the modal and store the current value
// The current value is store to recover it if the user click on the button "Cancel"
function openModal(fieldName) {
var value = $('#' + fieldName).val();
localStorage.setItem(fieldName, value);
$('#modal-' + fieldName).modal('show');
}
// Close the modal when the user click in the button "Cancel"
// The function also recover the old value
function closeModal(fieldName) {
var value = localStorage.getItem(fieldName);
$('#' + fieldName).val(value);
$('#modal-' + fieldName).modal('hide');
}
function disableBtnSave() {
$('#btnSave').addClass('btn-primary-disabled').attr('data-current', 'saved').html('<i class="bi bi-check-square"></i><?php $L->p('Saved') ?>');
}
function enableBtnSave() {
$('#btnSave').removeClass('btn-primary-disabled').attr('data-current', 'unsaved').html('<i class="bi bi-save"></i><?php $L->p('Save') ?>');
}
// This function is to catch all key press and provides shortcuts
// The editor plugin need to call this function for the event "keydown"
function keypress(event) {
logs(event);
// Shortcuts
// ------------------------------------------------------------------------
// Ctrl+S or Command+S
if ((event.ctrlKey || event.metaKey) && event.which == 83) {
event.preventDefault();
var args = {
title: $('#title').val(),
content: editorGetContent(),
category: $('#category option:selected').val(),
tags: $('#tags').val()
}
savePage(args);
disableBtnSave();
return false;
}
// Ctrl+ or Command+ or Alt+ or Shift+ or Option+
if (event.ctrlKey || event.metaKey || event.altKey || event.shiftKey) {
return true;
}
enableBtnSave();
return true;
}
// ============================================================================
// Events for the view
// ============================================================================
$(document).ready(function() {
// Main interface events
// ------------------------------------------------------------------------
// Catch all keypress for shortcuts or other actions
$(this).keydown(function(event) {
keypress(event);
});
// Warn the user to save the changes before leave
$(window).bind('beforeunload', function(e) {
if ($('#btnSave').attr('data-current') == 'unsaved') {
(e || window.event).returnValue = '';
return '';
}
return undefined; // Return undefined to continue the unload
});
$('#btnSave').on('click', function() {
var args = {
title: $('#title').val(),
content: editorGetContent(),
category: $('#category option:selected').val(),
tags: $("#tags option:selected").map(function() {
return this.value
}).get().join(",")
}
savePage(args);
disableBtnSave();
});
$('#btnCurrenType').on('click', function() {
openModal('type');
});
$('#category').on("change", function() {
enableBtnSave();
});
// Modal description events
// ------------------------------------------------------------------------
$('#btnSaveDescription').on('click', function() {
var args = {
description: $('#description').val()
};
savePage(args);
disableBtnSave();
closeModal('description');
});
$('#btnCancelDescription').on('click', function() {
closeModal('description');
});
// Modal date events
// ------------------------------------------------------------------------
$('#btnSaveDate').on('click', function() {
var args = {
date: $('#date').val()
};
savePage(args);
disableBtnSave();
closeModal('date');
});
$('#btnCancelDate').on('click', function() {
closeModal('date');
});
// Modal friendly-url events
// ------------------------------------------------------------------------
$('#btnSaveFriendlyURL').on('click', function() {
var args = {
slug: $('#friendlyURL').val()
};
savePage(args);
disableBtnSave();
closeModal('friendlyURL');
});
$('#btnCancelFriendlyURL').on('click', function() {
closeModal('friendlyURL');
});
$('#btnGenURLFromTitle').on('click', function() {
var args = {
text: $('#title').val(),
parentKey: $('#parent').val(),
pageKey: _pageKey
}
api.friendlyURL(args).then(function(response) {
if (response.status == 0) {
logs('Friendly URL created: ' + response.data.slug);
$('#friendlyURL').val(response.data.slug);
} else {
logs('An error occurred while trying to generate a friendly URL for the page.');
showAlertError(response.message);
}
});
});
// Modal type events
// ------------------------------------------------------------------------
$('#btnSaveType').on('click', function() {
var args = {
type: $('input[name="type"]:checked').val()
};
savePage(args);
disableBtnSave();
closeModal('type');
if (args['type'] == 'draft') {
$('#btnCurrenType').html('<i class="bi bi-circle"></i><?php $L->p('Draft') ?>');
} else if (args['type'] == 'published') {
$('#btnCurrenType').html('<i class="bi bi-check2-circle"></i><?php $L->p('Published') ?>');
} else if (args['type'] == 'unlisted') {
$('#btnCurrenType').html('<i class="bi bi-check2-circle"></i><?php $L->p('Unlisted') ?>');
} else if (args['type'] == 'sticky') {
$('#btnCurrenType').html('<i class="bi bi-check2-circle"></i><?php $L->p('Sticky') ?>');
} else if (args['type'] == 'static') {
$('#btnCurrenType').html('<i class="bi bi-check2-circle"></i><?php $L->p('Static') ?>');
}
});
$('#btnCancelType').on('click', function() {
closeModal('type');
});
// Modal SEO events
// ------------------------------------------------------------------------
$('#btnSaveSeo').on('click', function() {
var args = {
parent: $('#parent').val()
};
savePage(args);
disableBtnSave();
closeModal('seo');
});
$('#btnCancelSeo').on('click', function() {
closeModal('seo');
});
// Modal parent events
// ------------------------------------------------------------------------
$('#btnSaveParent').on('click', function() {
var args = {
parent: $('#parent').val()
};
savePage(args);
disableBtnSave();
closeModal('parent');
});
$('#btnCancelParent').on('click', function() {
closeModal('parent');
});
});
// ============================================================================
// Initialization for the view
// ============================================================================
$(document).ready(function() {
// How do you hang your toilet paper ? over or under ?
// Create the page or set the page
if (_pageKey == null) {
createPage();
} else {
setPage();
}
// Autosave
setInterval(function() {
var content = editorGetContent();
// Autosave when content has at least 100 characters
if (content.length < 100) {
return false;
}
savePage();
disableBtnSave();
}, 1000 * 60 * AUTOSAVE_INTERVAL);
});
</script>
<!-- File manager -->
<?php include(PATH_ADMIN_VIEWS . 'editor' . DS . 'file-manager.php') ?>
<!-- End File manager -->
<!-- Modal Description -->
<div class="modal" id="modal-description" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<div class="m-0">
<label for="parent" class="fw-bold mb-2">Page description</label>
<textarea id="description" name="description" class="form-control" rows="3"><?php echo ($pageKey ? $page->description() : '') ?></textarea>
<div class="form-text"><?php echo $L->get('this-field-can-help-describe-the-content') ?></div>
</div>
</div>
<div class="modal-footer ps-2 pe-2 pt-1 pb-1">
<button id="btnCancelDescription" type="button" class="btn btn-sm btn-secondary"><i class="bi bi-x"></i>Cancel</button>
<button id="btnSaveDescription" type="button" class="btn btn-sm btn-primary"><i class="bi bi-check"></i>Save</button>
</div>
</div>
</div>
</div>
<!-- End Modal Description -->
<!-- Modal Date -->
<div class="modal" id="modal-date" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<div class="m-0">
<label for="date" class="fw-bold mb-2">Publish date</label>
<input id="date" name="date" type="text" class="form-control" value="<?php echo ($pageKey ? $page->dateRaw() : Date::current(DB_DATE_FORMAT)) ?>">
<div class="form-text"><?php echo $L->g('date-format-format') ?></div>
</div>
</div>
<div class="modal-footer ps-2 pe-2 pt-1 pb-1">
<button id="btnCancelDate" type="button" class="btn btn-sm btn-secondary"><i class="bi bi-x"></i>Cancel</button>
<button id="btnSaveDate" type="button" class="btn btn-sm btn-primary"><i class="bi bi-check"></i>Save</button>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function() {
$("#date").datetimepicker({
format: DB_DATE_FORMAT
});
});
</script>
<!-- End Modal Date -->
<!-- Modal friendly URL -->
<div class="modal" id="modal-friendlyURL" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<div class="m-0">
<div class="d-flex mb-2">
<label for="friendlyURL" class="p-0 m-0 me-auto fw-bold">Page URL</label>
<button id="btnGenURLFromTitle" type="button" class="btn p-0 m-0 text-primary"><i class="bi bi-hammer"></i>Generate from page title</button>
</div>
<input id="friendlyURL" name="friendlyURL" type="text" class="form-control" value="<?php echo ($pageKey ? $page->slug() : '') ?>">
<div class="form-text">https://www.varlogdiego.com/my-page-about-k8s</div>
</div>
</div>
<div class="modal-footer ps-2 pe-2 pt-1 pb-1">
<button id="btnCancelFriendlyURL" type="button" class="btn btn-sm btn-secondary"><i class="bi bi-x"></i>Cancel</button>
<button id="btnSaveFriendlyURL" type="button" class="btn btn-sm btn-primary"><i class="bi bi-check"></i>Save</button>
</div>
</div>
</div>
</div>
<!-- End Modal friendly URL -->
<!-- Modal Type -->
<div class="modal" id="modal-type" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<div class="m-0">
<label class="fw-bold mb-2">Page type</label>
</div>
<div class="form-check mb-2">
<input id="statusDraft" name="type" class="form-check-input" type="radio" value="draft" <?php echo ((($pageKey && $page->draft()) || !$pageKey) ? 'checked' : '') ?>>
<label class="form-check-label" for="statusDraft">Draft</label>
<div class="form-text">Page as draft, is not visible for visitors.</div>
</div>
<div class="form-check mb-2">
<input id="statusPublish" name="type" class="form-check-input" type="radio" value="published" <?php echo (($pageKey && $page->published()) ? 'checked' : '') ?>>
<label class="form-check-label" for="statusPublish">Publish</label>
<div class="form-text">Publish the page, everyone can see it.</div>
</div>
<hr>
<div class="form-check mb-2">
<input id="statusSticky" name="type" class="form-check-input" type="radio" value="sticky" <?php echo (($pageKey && $page->sticky()) ? 'checked' : '') ?>>
<label class="form-check-label" for="statusSticky">Publish as sticky</label>
<div class="form-text">The page can be seen by everyone in the top of the main page.</div>
</div>
<div class="form-check mb-2">
<input id="statusStatic" name="type" class="form-check-input" type="radio" value="static" <?php echo (($pageKey && $page->isStatic()) ? 'checked' : '') ?>>
<label class="form-check-label" for="statusStatic">Publish as static</label>
<div class="form-text">The page can be seen by everyone as static page.</div>
</div>
<div class="form-check mb-2">
<input id="statusUnlisted" name="type" class="form-check-input" type="radio" value="unlisted" <?php echo (($pageKey && $page->unlisted()) ? 'checked' : '') ?>>
<label class="form-check-label" for="statusUnlisted">Publish as unlisted</label>
<div class="form-text">The page can be seen and shared by anyone with the link.</div>
</div>
</div>
<div class="modal-footer ps-2 pe-2 pt-1 pb-1">
<button id="btnCancelType" type="button" class="btn btn-sm btn-secondary"><i class="bi bi-x"></i>Cancel</button>
<button id="btnSaveType" type="button" class="btn btn-sm btn-primary"><i class="bi bi-check"></i>Save</button>
</div>
</div>
</div>
</div>
<!-- End Modal Type -->
<!-- Modal SEO -->
<div class="modal" id="modal-seo" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<div class="m-0">
<label class="fw-bold mb-2">SEO features</label>
</div>
<div class="form-check mb-2">
<input id="noindex" name="noindex" class="form-check-input" type="checkbox" value="noindex" <?php echo (($pageKey && $page->noindex()) ? 'checked' : '') ?>>
<label class="form-check-label" for="noindex"><?php echo $L->g('apply-code-noindex-code-to-this-page') ?></label>
<div class="form-text"><?php echo $L->g('This tells search engines not to show this page in their search results.') ?></div>
</div>
<div class="form-check mb-2">
<input id="nofollow" name="nofollow" class="form-check-input" type="checkbox" value="nofollow" <?php echo (($pageKey && $page->nofollow()) ? 'checked' : '') ?>>
<label class="form-check-label" for="nofollow"><?php echo $L->g('apply-code-nofollow-code-to-this-page') ?></label>
<div class="form-text"><?php echo $L->g('This tells search engines not to follow links on this page.') ?></div>
</div>
<div class="form-check mb-2">
<input id="noarchive" name="noarchive" class="form-check-input" type="checkbox" value="noarchive" <?php echo (($pageKey && $page->noarchive()) ? 'checked' : '') ?>>
<label class="form-check-label" for="noarchive"><?php echo $L->g('apply-code-noarchive-code-to-this-page') ?></label>
<div class="form-text"><?php echo $L->g('This tells search engines not to save a cached copy of this page.') ?></div>
</div>
</div>
<div class="modal-footer ps-2 pe-2 pt-1 pb-1">
<button id="btnCancelSeo" type="button" class="btn btn-sm btn-secondary"><i class="bi bi-x"></i>Cancel</button>
<button id="btnSaveSeo" type="button" class="btn btn-sm btn-primary"><i class="bi bi-check"></i>Save</button>
</div>
</div>
</div>
</div>
<!-- End Modal SEO -->
<!-- Modal Parent -->
<div class="modal" id="modal-parent" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<div class="m-0">
<label for="parent" class="fw-bold mb-2">Parent page</label>
<select id="parent" name="parent" class="custom-select"></select>
<div class="form-text"><?php echo $L->g('Start typing a page title to see a list of suggestions.') ?></div>
</div>
</div>
<div class="modal-footer ps-2 pe-2 pt-1 pb-1">
<button id="btnCancelParent" type="button" class="btn btn-sm btn-secondary"><i class="bi bi-x"></i>Cancel</button>
<button id="btnSaveParent" type="button" class="btn btn-sm btn-primary"><i class="bi bi-check"></i>Save</button>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function() {
var parent = $("#parent").select2({
placeholder: "",
allowClear: true,
theme: "bootstrap4",
minimumInputLength: 2,
ajax: {
url: HTML_PATH_ADMIN_ROOT + "ajax/get-published",
data: function(params) {
var query = {
checkIsParent: true,
query: params.term
}
return query;
},
processResults: function(data) {
return data;
}
},
escapeMarkup: function(markup) {
return markup;
},
templateResult: function(data) {
var html = data.text;
if (data.type == "static") {
html += '<span class="badge badge-pill badge-light">' + data.type + '</span>';
}
return html;
}
});
});
</script>
<!-- End Modal Parent -->
<div class="container-fluid h-100">
<div class="row h-100">
<div class="col-sm-9 d-flex flex-column h-100">
<!-- Toolbar > Save, Preview, Type and Options -->
<div id="editorToolbar" class="d-flex align-items-center mb-2">
<div id="editorToolbarLeft">
<button id="btnSave" type="button" data-current="saved" class="btn btn-sm btn-primary btn-primary-disabled"><i class="bi bi-save"></i><?php $L->p('Saved') ?></button>
<button id="btnPreview" type="button" class="btn btn-sm btn-primary"><i class="bi bi-box-arrow-up-right"></i><?php $L->p('Preview') ?></button>
</div>
<div id="editorToolbarRight" class="ms-auto">
<span id="btnCurrenType" class="ms-1 text-uppercase">
<?php
if ($pageKey) {
if ($page->draft()) {
echo '<i class="bi bi-circle"></i><span>' . $L->g('Draft') . '</span>';
} elseif ($page->published()) {
echo '<i class="bi bi-check2-circle"></i><span>' . $L->g('Published') . '</span>';
} elseif ($page->sticky()) {
echo '<i class="bi bi-check2-circle"></i><span>' . $L->g('Sticky') . '</span>';
} elseif ($page->isStatic()) {
echo '<i class="bi bi-check2-circle"></i><span>' . $L->g('Static') . '</span>';
} elseif ($page->unlisted()) {
echo '<i class="bi bi-check2-circle"></i><span>' . $L->g('Unlisted') . '</span>';
}
} else {
echo '<i class="bi bi-circle"></i><span>' . $L->g('Draft') . '</span>';
}
?>
</span>
</div>
</div>
<!-- End Toolbar > Save, Preview, Type and Options -->
<!-- Title -->
<div class="mb-2">
<input id="title" name="title" type="text" class="form-control form-control-lg" value="<?php echo ($pageKey ? $page->title() : '') ?>" placeholder="<?php $L->p('Enter title') ?>">
</div>
<!-- End Title -->
<!-- Editor -->
<textarea class="form-control flex-grow-1" placeholder="" id="editor"><?php echo ($pageKey ? $page->contentRaw() : '') ?></textarea>
<!-- End Editor -->
</div> <!-- End <div class="col-sm-9 h-100"> -->
<div class="col-sm-3 h-100 mt-2">
<!-- Cover Image -->
<h6 class="text-uppercase"><?php $L->p('Cover Image') ?></h6>
<div>
<img id="jscoverImagePreview" class="mx-auto d-block w-100" alt="Cover image preview" src="<?php echo (($pageKey && $page->coverImage()) ? $page->coverImage() : HTML_PATH_CORE_IMG . 'default.svg') ?>" />
</div>
<!-- End Cover Image -->
<!-- Category -->
<h6 class="text-uppercase mt-4">Category</h6>
<?php
echo Bootstrap::formSelect(array(
'id' => 'category',
'name' => 'category',
'selected' => ($pageKey ? $page->categoryKey() : ''),
'options' => array_merge(array('' => $L->g('Uncategorized')), $categories->getKeyNameArray())
));
?>
<!-- End Category -->
<!-- Tags -->
<h6 class="text-uppercase mt-4">Tags</h6>
<div class="mb-1">
<input id="addTag" name="addTag" type="text" class="form-control" value="" placeholder="<?php $L->p('Add tag') ?>">
</div>
<select id="tags" size="5" class="form-select" multiple aria-label="multiple select">
<?php
foreach ($tags->db as $key => $fields) {
echo '<option value="' . $key . '" ' . ($pageKey && in_array($key, $page->tags(true)) ? 'selected' : '') . '>' . $fields['name'] . '</option>';
}
?>
</select>
<script>
$(document).ready(function() {
$('#addTag').keypress(function(e) {
if (e.which == 13) {
var value = $(this).val();
if ($("#tags option[value='" + value + "']").length > 0) {
$("#tags option[value='" + value + "']").prop('selected', true);
} else {
$('#tags').prepend($('<option>', {
value: $(this).val(),
text: $(this).val(),
selected: true
}));
}
$(this).val('');
return false;
}
});
$("#tags").on("mousedown", 'option', function(e) {
e.preventDefault();
$(this).prop('selected', !$(this).prop('selected'));
enableBtnSave();
return false;
});
});
</script>
<!-- End Tags -->
<h6 class="text-uppercase mt-4">More options</h6>
<ul class="list-group">
<li class="list-group-item p-0 pt-3"><a onclick="fmOpen()" href="#"><i class="bi bi-files"></i>Files & images</a></li>
<li class="list-group-item p-0 pt-3"><a onclick="openModal('description')" href="#"><i class="bi bi-info-square"></i>Description</a></li>
<li class="list-group-item p-0 pt-3"><a onclick="openModal('date')" href="#"><i class="bi bi-calendar"></i>Publish date</a></li>
<li class="list-group-item p-0 pt-3"><a onclick="openModal('friendlyURL')" href="#"><i class="bi bi-link"></i>Change URL</a></li>
<li class="list-group-item p-0 pt-3"><a onclick="openModal('type')" href="#"><i class="bi bi-eye"></i>Type</a></li>
<li class="list-group-item p-0 pt-3"><a onclick="openModal('seo')" href="#"><i class="bi bi-compass"></i>SEO features</a></li>
<li class="list-group-item p-0 pt-3"><a onclick="openModal('parent')" href="#"><i class="bi bi-diagram-2"></i>Parent page</a></li>
</ul>
<!-- Quick files
<h6 class="text-uppercase mt-4"><?php $L->p('Quick files') ?></h6>
<div id="quickFiles">
<div class="d-flex align-items-center mb-1">
<i class="bi bi-image" style="font-size: 1.6rem;"></i>
<span>photo1.jpg</span>
</div>
<div class="d-flex align-items-center mb-1">
<i class="bi bi-image" style="font-size: 1.6rem;"></i>
<span>test.txt</span>
</div>
<div class="d-flex align-items-center mb-1">
<i class="bi bi-image" style="font-size: 1.6rem;"></i>
<span>test.txt</span>
</div>
</div>
End Quick files
-->
</div> <!-- End <div class="col-sm-3 h-100"> -->
</div> <!-- End <div class="row h-100"> -->
</div> <!-- End <div class="container-fluid h-100"> -->

View file

@ -1,223 +0,0 @@
<div class="modal" id="modal-fileManager" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-body">
<div class="container-fluid">
<div class="row">
<div class="col">
<div class="d-flex align-items-center mb-4">
<h3 class="me-auto m-0 p-0"><i class="bi bi-image"></i><?php $L->p('File Manager'); ?></h3>
<label id="btnUploadFile" class="btn btn-primary"><i class="bi bi-upload"></i><?php $L->p('Upload file'); ?><input type="file" id="filesToUpload" name="filesToUpload[]" multiple hidden></label>
<div id="progressUploadFile" class="progress w-25 d-none">
<div class="progress-bar" role="progressbar" style="width: 0%" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
<table class="table">
<thead>
<tr>
<th scope="col">Preview</th>
<th scope="col">Filename</th>
<th scope="col">Type</th>
<th scope="col">Size</th>
<th scope="col"></th>
</tr>
</thead>
<tbody id="fmFiles">
<!-- <tr>
<td class="align-middle">
<img style="width: 32px" src="<?php echo HTML_PATH_CORE_IMG ?>default.svg" />
</td>
<td class="align-middle">photo.jpg</td>
<td class="align-middle">image/jpeg</td>
<td class="align-middle">300Kb</td>
<td class="align-middle">
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle" type="button" id="fileOptions" data-bs-toggle="dropdown" aria-expanded="false">
Options
</button>
<ul class="dropdown-menu" aria-labelledby="fileOptions">
<li><a class="dropdown-item" href="#">Insert</a></li>
<li><a class="dropdown-item" href="#">Set as cover image</a></li>
<li>
<hr class="dropdown-divider">
</li>
<li><a class="dropdown-item" href="#"><?php $L->p('Delete') ?></a></li>
</ul>
</div>
</td>
</tr> -->
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
// Open File Manager modal
function fmOpen() {
$('#modal-fileManager').modal('show');
}
// Close File Manager modal
function fmClose() {
$('#modal-fileManager').modal('hide');
}
// Insert HTML code in the Editor content
function fmInsertFile(filename, absoluteURL, mime) {
if (mime == 'image/jpeg' || mime == 'image/png') {
editorInsertContent(absoluteURL, 'image');
} else {
editorInsertContent('<a href="' + absoluteURL + '">' + filename + '</a>');
}
}
// Get the files for the current page and show them
function fmGetFiles() {
logs('File Manager. Getting files for the current page: ' + _pageKey);
api.getPageFiles({
'pageKey': _pageKey
}).then(function(response) {
if (response.status == 0) {
fmDisplayFiles(response.data);
} else {
logs("File Manager. An error occurred while trying to get the files for the current page.");
showAlertError(response.message);
}
});
}
// Displays the files in the table
function fmDisplayFiles(files) {
$('#fmFiles').empty();
if (files.length == 0) {
logs('File Manager. There are not files for the current page.');
return false;
}
$.each(files, function(key, file) {
var row = '<tr>' +
'<td class="align-middle">' +
' <img style="width: 32px" src="<?php echo HTML_PATH_CORE_IMG ?>default.svg" />' +
'</td>' +
'<td class="align-middle">' + file.filename + '</td>' +
'<td class="align-middle">' + file.mime + '</td>' +
'<td class="align-middle">' + formatBytes(file.size) + '</td>' +
'<td class="align-middle text-center">' +
'<div class="dropdown">' +
' <button class="btn btn-sm btn-secondary dropdown-toggle" type="button" id="fileOptions" data-bs-toggle="dropdown" aria-expanded="false"><i class="bi bi-gear"></i>Options</button>' +
' <ul class="dropdown-menu" aria-labelledby="fileOptions">' +
' <li><a class="dropdown-item" href="#" onClick="fmInsertFile(\'' + file.filename + '\', \'' + file.absoluteURL + '\', \'' + file.mime + '\'); fmClose();"><i class="bi bi-plus-circle"></i><?php $L->p('Insert') ?></a></li>' +
' <li><a class="dropdown-item" href="#"><i class="bi bi-image"></i>Set as cover image</a></li>' +
' <li><hr class="dropdown-divider"></li>' +
' <li><a class="dropdown-item" href="#"><i class="bi bi-trash"></i><?php $L->p('Delete') ?></a></li>' +
' </ul>' +
'</div>' +
'</td>' +
'</tr>';
$('#fmFiles').append(row);
});
return true;
}
// Upload a file for the current page
function fmUploadFile(file) {
logs('File Manager. Uploading file.');
// Check file type/extension
const validImageTypes = ['image/gif', 'image/jpeg', 'image/png', 'image/svg+xml', 'application/pdf'];
if (!validImageTypes.includes(file.type)) {
logs("File Manager. File type is not supported.");
showAlertError("<?php echo $L->g('File type is not supported. Allowed types:') . ' ' . implode(', ', $GLOBALS['ALLOWED_IMG_EXTENSIONS']) ?>");
return false;
}
// Check file size and compare with PHP upload_max_filesize
if (file.size > UPLOAD_MAX_FILESIZE) {
logs("File Manager. File size is to big for PHP configuration.");
showAlertError("<?php echo $L->g('Maximum load file size allowed:') . ' ' . ini_get('upload_max_filesize') ?>");
return false;
}
// Start progress bar
$('#btnUploadFile').addClass('d-none');
$('#progressUploadFile').removeClass('d-none');
$('#progressUploadFile').children('.progress-bar').width('0');
// Data to send via AJAX
var formData = new FormData();
formData.append("file", file);
formData.append("token", api.body.token);
formData.append("authentication", api.body.authentication);
$.ajax({
url: api.apiURL + 'pages/files/' + _pageKey,
type: "POST",
data: formData,
cache: false,
contentType: false,
processData: false,
xhr: function() {
var xhr = $.ajaxSettings.xhr();
if (xhr.upload) {
xhr.upload.addEventListener("progress", function(e) {
if (e.lengthComputable) {
var percentComplete = (e.loaded / e.total) * 100;
$('#progressUploadFile').children('.progress-bar').width(percentComplete + '%');
}
}, false);
}
return xhr;
}
}).done(function(response) {
if (response.status == 0) {
logs("File Manager. File uploaded.");
// Progress bar
$('#progressUploadFile').addClass('d-none');
$('#btnUploadFile').removeClass('d-none');
// Get current files
fmGetFiles();
} else {
logs("File Manager. An error occurred while trying to upload the file.");
// Progress bar
$('#progressUploadFile').children('.progress-bar').addClass('bg-danger');
// Alert the user about the error
showAlertError('File Manager. ' + response.message);
}
});
}
// Initlization and events for the File Manager
$(document).ready(function() {
// Input file change event
$('#filesToUpload').on("change", function(e) {
var filesToUpload = $('#filesToUpload')[0].files;
for (var i = 0; i < filesToUpload.length; i++) {
fmUploadFile(filesToUpload[i]);
}
});
// Drag and drop files to upload them
$(window).on("dragover dragenter", function(e) {
e.preventDefault();
e.stopPropagation();
fmOpen();
});
$(window).on("drop", function(e) {
e.preventDefault();
e.stopPropagation();
$('#filesToUpload').prop('files', e.originalEvent.dataTransfer.files);
$('#filesToUpload').trigger('change');
});
});
</script>

View file

@ -1,71 +1,37 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
<?php defined('BLUDIT') or die('Bludit CMS.');
<script>
// ============================================================================
// Variables for the view
// ============================================================================
echo '<h1 class="text-center mb-3 mt-3 font-weight-normal" style="color: #555;">' . $site->title() . '</h1>';
// ============================================================================
// Functions for the view
// ============================================================================
echo Bootstrap::formOpen(array());
// ============================================================================
// Events for the view
// ============================================================================
$(document).ready(function() {
// No events for the view yet
});
echo Bootstrap::formInputHidden(array(
'name' => 'tokenCSRF',
'value' => $security->getTokenCSRF()
));
// ============================================================================
// Initialization for the view
// ============================================================================
$(document).ready(function() {
// No initialization for the view yet
});
</script>
echo '
<div class="form-group">
<input type="text" dir="auto" value="' . (isset($_POST['username']) ? Sanitize::html($_POST['username']) : '') . '" class="form-control form-control-lg" id="jsusername" name="username" placeholder="' . $L->g('Username') . '" autofocus>
</div>
';
<?php
echo '
<div class="form-group">
<input type="password" class="form-control form-control-lg" id="jspassword" name="password" placeholder="' . $L->g('Password') . '">
</div>
';
echo '<h1 class="text-center fw-normal mb-5">'.$site->title().'</h1>';
echo Bootstrap::formOpen(array('name'=>'login'));
echo Bootstrap::formInputHidden(array(
'name'=>'tokenCSRF',
'value'=>$security->getTokenCSRF()
));
echo Bootstrap::formFloatingLabels(array(
'id'=>'username',
'name'=>'username',
'type'=>'text',
'value'=>(isset($_POST['username'])?Sanitize::html($_POST['username']):''),
'class'=>'form-control-lg',
'placeholder'=>$L->g('Username')
));
echo Bootstrap::formFloatingLabels(array(
'id'=>'password',
'name'=>'password',
'type'=>'password',
'value'=>'',
'class'=>'form-control-lg',
'placeholder'=>$L->g('Password')
));
echo '
echo '
<div class="form-check">
<input class="form-check-input" type="checkbox" value="true" id="jsremember" name="remember">
<label class="form-check-label" for="jsremember">'.$L->g('Remember me').'</label>
<label class="form-check-label" for="jsremember">' . $L->g('Remember me') . '</label>
</div>
<div class="mt-4">
<button type="submit" class="btn btn-primary btn-lg me-2 w-100" name="save">'.$L->g('Login').'</button>
<div class="form-group mt-3">
<button type="submit" class="btn btn-primary btn-lg mr-2 w-100" name="save">' . $L->g('Login') . '</button>
</div>
';
echo '</form>';
echo '<p class="mt-5 text-end">'.$L->g('Powered by Bludit').'</p>'
?>
echo '<p class="mt-3 text-right">' . $L->g('Powered by Bludit') . ((defined('BLUDIT_PRO')) ? ' PRO' : '') . '</p>';

View file

@ -0,0 +1,39 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
<?php echo Bootstrap::formOpen(array('id'=>'jsform', 'class'=>'tab-content')); ?>
<div class="align-middle">
<div class="float-right mt-1">
<button type="submit" class="btn btn-primary btn-sm" name="save"><?php $L->p('Save') ?></button>
<a class="btn btn-secondary btn-sm" href="<?php echo HTML_PATH_ADMIN_ROOT.'categories' ?>" role="button"><?php $L->p('Cancel') ?></a>
</div>
<?php echo Bootstrap::pageTitle(array('title'=>$L->g('New category'), 'icon'=>'tag')); ?>
</div>
<?php
echo Bootstrap::formInputHidden(array(
'name'=>'tokenCSRF',
'value'=>$security->getTokenCSRF()
));
echo Bootstrap::formInputText(array(
'name'=>'name',
'label'=>$L->g('Name'),
'value'=>isset($_POST['category'])?$_POST['category']:'',
'class'=>'',
'placeholder'=>'',
'tip'=>''
));
echo Bootstrap::formTextarea(array(
'name'=>'description',
'label'=>$L->g('Description'),
'value'=>isset($_POST['description'])?$_POST['description']:'',
'class'=>'',
'placeholder'=>'',
'tip'=>'',
'rows'=>3
));
?>
<?php echo Bootstrap::formClose(); ?>

View file

@ -0,0 +1,511 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
<?php
// Start form
echo Bootstrap::formOpen(array(
'id' => 'jsform',
'class' => 'd-flex flex-column h-100'
));
// Token CSRF
echo Bootstrap::formInputHidden(array(
'name' => 'tokenCSRF',
'value' => $security->getTokenCSRF()
));
// UUID
// The UUID is generated in the controller
echo Bootstrap::formInputHidden(array(
'name' => 'uuid',
'value' => $uuid
));
// Type = published, draft, sticky, static
echo Bootstrap::formInputHidden(array(
'name' => 'type',
'value' => 'published'
));
// Cover image
echo Bootstrap::formInputHidden(array(
'name' => 'coverImage',
'value' => ''
));
// Content
echo Bootstrap::formInputHidden(array(
'name' => 'content',
'value' => ''
));
?>
<!-- TOOLBAR -->
<div id="jseditorToolbar" class="mb-1">
<div id="jseditorToolbarRight" class="btn-group btn-group-sm float-right" role="group" aria-label="Toolbar right">
<button type="button" class="btn btn-light" id="jsmediaManagerOpenModal" data-toggle="modal" data-target="#jsmediaManagerModal"><span class="fa fa-image"></span> <?php $L->p('Images') ?></button>
<button type="button" class="btn btn-light" id="jsoptionsSidebar" style="z-index:30"><span class="fa fa-cog"></span> <?php $L->p('Options') ?></button>
</div>
<div id="jseditorToolbarLeft">
<button id="jsbuttonSave" type="button" class="btn btn-sm btn-primary"><?php $L->p('Save') ?></button>
<button id="jsbuttonPreview" type="button" class="btn btn-sm btn-secondary"><?php $L->p('Preview') ?></button>
<span id="jsbuttonSwitch" data-switch="publish" class="ml-2 text-secondary switch-button"><i class="fa fa-square switch-icon-publish"></i> <?php $L->p('Publish') ?></span>
</div>
</div>
<script>
$(document).ready(function() {
$("#jsoptionsSidebar").on("click", function() {
$("#jseditorSidebar").toggle();
$("#jsshadow").toggle();
});
$("#jsshadow").on("click", function() {
$("#jseditorSidebar").toggle();
$("#jsshadow").toggle();
});
});
</script>
<!-- SIDEBAR OPTIONS -->
<div id="jseditorSidebar">
<nav>
<div class="nav nav-tabs" id="nav-tab" role="tablist">
<a class="nav-link active show" id="nav-general-tab" data-toggle="tab" href="#nav-general" role="tab" aria-controls="general"><?php $L->p('General') ?></a>
<a class="nav-link" id="nav-advanced-tab" data-toggle="tab" href="#nav-advanced" role="tab" aria-controls="advanced"><?php $L->p('Advanced') ?></a>
<?php if (!empty($site->customFields())) : ?>
<a class="nav-link" id="nav-custom-tab" data-toggle="tab" href="#nav-custom" role="tab" aria-controls="custom"><?php $L->p('Custom') ?></a>
<?php endif ?>
<a class="nav-link" id="nav-seo-tab" data-toggle="tab" href="#nav-seo" role="tab" aria-controls="seo"><?php $L->p('SEO') ?></a>
</div>
</nav>
<div class="tab-content pr-3 pl-3 pb-3">
<div id="nav-general" class="tab-pane fade show active" role="tabpanel" aria-labelledby="general-tab">
<?php
// Category
echo Bootstrap::formSelectBlock(array(
'name' => 'category',
'label' => $L->g('Category'),
'selected' => '',
'class' => '',
'emptyOption' => '- ' . $L->g('Uncategorized') . ' -',
'options' => $categories->getKeyNameArray()
));
// Description
echo Bootstrap::formTextareaBlock(array(
'name' => 'description',
'label' => $L->g('Description'),
'selected' => '',
'class' => '',
'value' => '',
'rows' => 5,
'placeholder' => $L->get('this-field-can-help-describe-the-content')
));
?>
<!-- Cover Image -->
<label class="mt-4 mb-2 pb-2 border-bottom text-uppercase w-100"><?php $L->p('Cover Image') ?></label>
<div>
<img id="jscoverImagePreview" class="mx-auto d-block w-100" alt="Cover image preview" src="<?php echo HTML_PATH_CORE_IMG ?>default.svg" />
</div>
<div class="mt-2 text-center">
<button type="button" id="jsbuttonSelectCoverImage" class="btn btn-primary btn-sm"><?php echo $L->g('Select cover image') ?></button>
<button type="button" id="jsbuttonRemoveCoverImage" class="btn btn-secondary btn-sm"><?php echo $L->g('Remove cover image') ?></button>
</div>
<script>
$(document).ready(function() {
$("#jscoverImagePreview").on("click", function() {
openMediaManager();
});
$("#jsbuttonSelectCoverImage").on("click", function() {
openMediaManager();
});
$("#jsbuttonRemoveCoverImage").on("click", function() {
$("#jscoverImage").val('');
$("#jscoverImagePreview").attr('src', HTML_PATH_CORE_IMG + 'default.svg');
});
});
</script>
</div>
<div id="nav-advanced" class="tab-pane fade" role="tabpanel" aria-labelledby="advanced-tab">
<?php
// Date
echo Bootstrap::formInputTextBlock(array(
'name' => 'date',
'label' => $L->g('Date'),
'placeholder' => '',
'value' => Date::current(DB_DATE_FORMAT),
'tip' => $L->g('date-format-format')
));
// Type
echo Bootstrap::formSelectBlock(array(
'name' => 'typeSelector',
'label' => $L->g('Type'),
'selected' => '',
'options' => array(
'published' => '- ' . $L->g('Default') . ' -',
'sticky' => $L->g('Sticky'),
'static' => $L->g('Static')
),
'tip' => ''
));
// Position
echo Bootstrap::formInputTextBlock(array(
'name' => 'position',
'label' => $L->g('Position'),
'tip' => $L->g('Field used when ordering content by position'),
'value' => $pages->nextPositionNumber()
));
// Tags
echo Bootstrap::formInputTextBlock(array(
'name' => 'tags',
'label' => $L->g('Tags'),
'placeholder' => '',
'tip' => $L->g('Write the tags separated by comma')
));
// Parent
echo Bootstrap::formSelectBlock(array(
'name' => 'parent',
'label' => $L->g('Parent'),
'options' => array(),
'selected' => false,
'class' => '',
'tip' => $L->g('Start typing a page title to see a list of suggestions.'),
));
?>
<script>
$(document).ready(function() {
var parent = $("#jsparent").select2({
placeholder: "",
allowClear: true,
theme: "bootstrap4",
minimumInputLength: 2,
ajax: {
url: HTML_PATH_ADMIN_ROOT + "ajax/get-published",
data: function(params) {
var query = {
checkIsParent: true,
query: params.term
}
return query;
},
processResults: function(data) {
return data;
}
},
escapeMarkup: function(markup) {
return markup;
},
templateResult: function(data) {
var html = data.text;
if (data.type == "static") {
html += '<span class="badge badge-pill badge-light">' + data.type + '</span>';
}
return html;
}
});
});
</script>
<?php
// Template
echo Bootstrap::formInputTextBlock(array(
'name' => 'template',
'label' => $L->g('Template'),
'placeholder' => '',
'value' => '',
'tip' => $L->g('Write a template name to filter the page in the theme and change the style of the page.')
));
echo Bootstrap::formInputTextBlock(array(
'name' => 'externalCoverImage',
'label' => $L->g('External cover image'),
'placeholder' => "https://",
'value' => '',
'tip' => $L->g('Set a cover image from external URL, such as a CDN or some server dedicated for images.')
));
// Username
echo Bootstrap::formInputTextBlock(array(
'name' => '',
'label' => $L->g('Author'),
'placeholder' => '',
'value' => $login->username(),
'tip' => '',
'disabled' => true
));
?>
<script>
$(document).ready(function() {
// Changes in External cover image input
$("#jsexternalCoverImage").change(function() {
$("#jscoverImage").val($(this).val());
});
// Generate slug when the user type the title
$("#jstitle").keyup(function() {
var text = $(this).val();
var parent = $("#jsparent").val();
var currentKey = "";
var ajax = new bluditAjax();
var callBack = $("#jsslug");
ajax.generateSlug(text, parent, currentKey, callBack);
});
// Datepicker
$("#jsdate").datetimepicker({
format: DB_DATE_FORMAT
});
});
</script>
</div>
<?php if (!empty($site->customFields())) : ?>
<div id="nav-custom" class="tab-pane fade" role="tabpanel" aria-labelledby="custom-tab">
<?php
$customFields = $site->customFields();
foreach ($customFields as $field => $options) {
if (!isset($options['position'])) {
if ($options['type'] == "string") {
echo Bootstrap::formInputTextBlock(array(
'name' => 'custom[' . $field . ']',
'label' => (isset($options['label']) ? $options['label'] : ''),
'value' => (isset($options['default']) ? $options['default'] : ''),
'tip' => (isset($options['tip']) ? $options['tip'] : ''),
'placeholder' => (isset($options['placeholder']) ? $options['placeholder'] : '')
));
} elseif ($options['type'] == "bool") {
echo Bootstrap::formCheckbox(array(
'name' => 'custom[' . $field . ']',
'label' => (isset($options['label']) ? $options['label'] : ''),
'placeholder' => (isset($options['placeholder']) ? $options['placeholder'] : ''),
'checked' => (isset($options['checked']) ? true : false),
'labelForCheckbox' => (isset($options['tip']) ? $options['tip'] : '')
));
}
}
}
?>
</div>
<?php endif ?>
<div id="nav-seo" class="tab-pane fade" role="tabpanel" aria-labelledby="seo-tab">
<?php
// Friendly URL
echo Bootstrap::formInputTextBlock(array(
'name' => 'slug',
'tip' => $L->g('URL associated with the content'),
'label' => $L->g('Friendly URL'),
'placeholder' => $L->g('Leave empty for autocomplete by Bludit.')
));
// Robots
echo Bootstrap::formCheckbox(array(
'name' => 'noindex',
'label' => 'Robots',
'labelForCheckbox' => $L->g('apply-code-noindex-code-to-this-page'),
'placeholder' => '',
'checked' => false,
'tip' => $L->g('This tells search engines not to show this page in their search results.')
));
// Robots
echo Bootstrap::formCheckbox(array(
'name' => 'nofollow',
'label' => '',
'labelForCheckbox' => $L->g('apply-code-nofollow-code-to-this-page'),
'placeholder' => '',
'checked' => false,
'tip' => $L->g('This tells search engines not to follow links on this page.')
));
// Robots
echo Bootstrap::formCheckbox(array(
'name' => 'noarchive',
'label' => '',
'labelForCheckbox' => $L->g('apply-code-noarchive-code-to-this-page'),
'placeholder' => '',
'checked' => false,
'tip' => $L->g('This tells search engines not to save a cached copy of this page.')
));
?>
</div>
</div>
</div>
<!-- Custom fields: TOP -->
<?php
$customFields = $site->customFields();
foreach ($customFields as $field => $options) {
if (isset($options['position']) && ($options['position'] == 'top')) {
if ($options['type'] == "string") {
echo Bootstrap::formInputTextBlock(array(
'name' => 'custom[' . $field . ']',
'label' => (isset($options['label']) ? $options['label'] : ''),
'value' => (isset($options['default']) ? $options['default'] : ''),
'tip' => (isset($options['tip']) ? $options['tip'] : ''),
'placeholder' => (isset($options['placeholder']) ? $options['placeholder'] : ''),
'class' => 'mb-2',
'labelClass' => 'mb-2 pb-2 border-bottom text-uppercase w-100'
));
} elseif ($options['type'] == "bool") {
echo Bootstrap::formCheckbox(array(
'name' => 'custom[' . $field . ']',
'label' => (isset($options['label']) ? $options['label'] : ''),
'placeholder' => (isset($options['placeholder']) ? $options['placeholder'] : ''),
'checked' => (isset($options['checked']) ? true : false),
'labelForCheckbox' => (isset($options['tip']) ? $options['tip'] : ''),
'class' => 'mb-2',
'labelClass' => 'mb-2 pb-2 border-bottom text-uppercase w-100'
));
}
}
}
?>
<!-- Title -->
<div id="jseditorTitle" class="form-group mb-1">
<input id="jstitle" name="title" type="text" dir="auto" class="form-control form-control-lg rounded-0" value="" placeholder="<?php $L->p('Enter title') ?>">
</div>
<!-- Editor -->
<textarea id="jseditor" class="editable h-100 mb-1"></textarea>
<!-- Custom fields: BOTTOM -->
<?php
$customFields = $site->customFields();
foreach ($customFields as $field => $options) {
if (isset($options['position']) && ($options['position'] == 'bottom')) {
if ($options['type'] == "string") {
echo Bootstrap::formInputTextBlock(array(
'name' => 'custom[' . $field . ']',
'label' => (isset($options['label']) ? $options['label'] : ''),
'value' => (isset($options['default']) ? $options['default'] : ''),
'tip' => (isset($options['tip']) ? $options['tip'] : ''),
'placeholder' => (isset($options['placeholder']) ? $options['placeholder'] : ''),
'class' => 'mt-2',
'labelClass' => 'mb-2 pb-2 border-bottom text-uppercase w-100'
));
} elseif ($options['type'] == "bool") {
echo Bootstrap::formCheckbox(array(
'name' => 'custom[' . $field . ']',
'label' => (isset($options['label']) ? $options['label'] : ''),
'placeholder' => (isset($options['placeholder']) ? $options['placeholder'] : ''),
'checked' => (isset($options['checked']) ? true : false),
'labelForCheckbox' => (isset($options['tip']) ? $options['tip'] : ''),
'class' => 'mt-2',
'labelClass' => 'mb-2 pb-2 border-bottom text-uppercase w-100'
));
}
}
}
?>
</form>
<!-- Modal for Media Manager -->
<?php include(PATH_ADMIN_THEMES . 'booty/html/media.php'); ?>
<script>
$(document).ready(function() {
// Define function if they doesn't exist
// This helps if the user doesn't activate any plugin as editor
if (typeof editorGetContent != "function") {
window.editorGetContent = function() {
return $("#jseditor").val();
};
}
if (typeof editorInsertMedia != "function") {
window.editorInsertMedia = function(filename) {
$("#jseditor").val($('#jseditor').val() + '<img src="' + filename + '" alt="">');
};
}
if (typeof editorInsertLinkedMedia != "function") {
window.editorInsertLinkedMedia = function(filename, link) {
$("#jseditor").val($('#jseditor').val() + '<a href="' + link + '"><img src="' + filename + '" alt=""></a>');
};
}
// Button switch
$("#jsbuttonSwitch").on("click", function() {
if ($(this).data("switch") == "publish") {
$(this).html('<i class="fa fa-square switch-icon-draft"></i> <?php $L->p('Draft') ?>');
$(this).data("switch", "draft");
} else {
$(this).html('<i class="fa fa-square switch-icon-publish"></i> <?php $L->p('Publish') ?>');
$(this).data("switch", "publish");
}
});
// Button preview
$("#jsbuttonPreview").on("click", function() {
var uuid = $("#jsuuid").val();
var title = $("#jstitle").val();
var content = editorGetContent();
bluditAjax.saveAsDraft(uuid, title, content).then(function(data) {
var preview = window.open("<?php echo DOMAIN_PAGES . 'autosave-' . $uuid . '?preview=' . md5('autosave-' . $uuid) ?>", "bludit-preview");
preview.focus();
});
});
// Button Save
$("#jsbuttonSave").on("click", function() {
let actionParameters = '';
// If the switch is setted to "published", get the value from the selector
if ($("#jsbuttonSwitch").data("switch") == "publish") {
var value = $("#jstypeSelector option:selected").val();
$("#jstype").val(value);
actionParameters = '#' + value;
} else {
$("#jstype").val("draft");
actionParameters = '#draft';
}
// Get the content
$("#jscontent").val(editorGetContent());
// Submit the form
$("#jsform").attr('action', actionParameters);
$("#jsform").submit();
});
// Autosave
var currentContent = editorGetContent();
setInterval(function() {
var uuid = $("#jsuuid").val();
var title = $("#jstitle").val() + "[<?php $L->p('Autosave') ?>]";
var content = editorGetContent();
// Autosave when content has at least 100 characters
if (content.length < 100) {
return false;
}
// Autosave only when the user change the content
if (currentContent != content) {
currentContent = content;
bluditAjax.saveAsDraft(uuid, title, content).then(function(data) {
if (data.status == 0) {
showAlert("<?php $L->p('Autosave') ?>");
}
});
}
}, 1000 * 60 * AUTOSAVE_INTERVAL);
});
</script>

View file

@ -0,0 +1,67 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
<?php echo Bootstrap::formOpen(array('id'=>'jsform', 'class'=>'tab-content')); ?>
<div class="align-middle">
<div class="float-right mt-1">
<button type="submit" class="btn btn-primary btn-sm" name="save"><?php $L->p('Save') ?></button>
<a class="btn btn-secondary btn-sm" href="<?php echo HTML_PATH_ADMIN_ROOT.'users' ?>" role="button"><?php $L->p('Cancel') ?></a>
</div>
<?php echo Bootstrap::pageTitle(array('title'=>$L->g('Add a new user'), 'icon'=>'user')); ?>
</div>
<?php
echo Bootstrap::formInputHidden(array(
'name'=>'tokenCSRF',
'value'=>$security->getTokenCSRF()
));
echo Bootstrap::formInputText(array(
'name'=>'new_username',
'label'=>$L->g('Username'),
'value'=>(isset($_POST['new_username'])?$_POST['new_username']:''),
'class'=>'',
'placeholder'=>'',
'tip'=>''
));
echo Bootstrap::formInputText(array(
'name'=>'new_password',
'type'=>'password',
'label'=>$L->g('Password'),
'value'=>'',
'class'=>'',
'placeholder'=>'',
'tip'=>''
));
echo Bootstrap::formInputText(array(
'name'=>'confirm_password',
'type'=>'password',
'label'=>$L->g('Confirm Password'),
'value'=>'',
'class'=>'',
'placeholder'=>'',
'tip'=>''
));
echo Bootstrap::formSelect(array(
'name'=>'role',
'label'=>$L->g('Role'),
'options'=>array('author'=>$L->g('Author'), 'editor'=>$L->g('Editor'), 'admin'=>$L->g('Administrator')),
'selected'=>'Author',
'class'=>'',
'tip'=>$L->g('author-can-write-and-edit-their-own-content')
));
echo Bootstrap::formInputText(array(
'name'=>'email',
'label'=>$L->g('Email'),
'value'=>(isset($_POST['email'])?$_POST['email']:''),
'class'=>'',
'placeholder'=>'',
'tip'=>''
));
?>
<?php echo Bootstrap::formClose(); ?>

View file

@ -1,80 +1,51 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
<script>
// ============================================================================
// Variables for the view
// ============================================================================
<?php echo Bootstrap::formOpen(array('id'=>'jsform', 'class'=>'tab-content')); ?>
// ============================================================================
// Functions for the view
// ============================================================================
function changePluginsPosition() {
$("li.list-group-item").each(function(index, value) {
var args = {
position: index,
className: $(this).data("class-name")
};
console.log(index);
api.configurePlugin(args).then(function(response) {
if (response.status == 0) {
logs('Plugin configured: ' + response.data.key);
} else {
logs('An error occurred while trying to configured the plugin.');
showAlertError(response.message);
}
});
});
showAlertInfo("<?php $L->p('The changes have been saved') ?>");
}
// ============================================================================
// Events for the view
// ============================================================================
$(document).ready(function() {
$("#btnSave").on("click", function() {
changePluginsPosition();
});
});
// ============================================================================
// Initlization for the view
// ============================================================================
$(document).ready(function() {
$('.list-group-sortable').sortable({
placeholderClass: 'list-group-item'
});
});
</script>
<div class="d-flex align-items-center mb-4">
<h2 class="m-0"><i class="bi bi-arrow-down-up"></i><?php $L->p('Plugins position') ?></h2>
<div class="ms-auto">
<button id="btnSave" type="button" class="btn btn-primary btn-sm"><?php $L->p('Save') ?></button>
<a id="btnCancel" class="btn btn-secondary btn-sm" href="<?php echo HTML_PATH_ADMIN_ROOT . 'plugins' ?>" role="button"><?php $L->p('Cancel') ?></a>
<div class="align-middle">
<div class="float-right mt-1">
<button type="button" class="btn btn-primary btn-sm jsbuttonSave" name="save"><?php $L->p('Save') ?></button>
<a class="btn btn-secondary btn-sm" href="<?php echo HTML_PATH_ADMIN_ROOT.'plugins' ?>" role="button"><?php $L->p('Cancel') ?></a>
</div>
<?php echo Bootstrap::pageTitle(array('title'=>$L->g('Plugins position'), 'icon'=>'tags')); ?>
</div>
<div class="alert alert-primary">
<?php $L->p('Drag and Drop to sort the plugins') ?>
</div>
<div class="alert alert-primary"><?php $L->p('Drag and Drop to sort the plugins') ?></div>
<?php echo Bootstrap::formTitle(array('title' => $L->g('Website plugins'))) ?>
<?php
// Token CSRF
echo Bootstrap::formInputHidden(array(
'name'=>'tokenCSRF',
'value'=>$security->getTokenCSRF()
));
<ul class="website-plugins list-group list-group-sortable">
<?php foreach ($plugins['siteSidebar'] as $plugin): ?>
<li class="list-group-item" data-class-name="<?php echo $plugin->className() ?>">
<i class="bi bi-arrows-expand"></i><?php echo $plugin->name() ?>
</li>
<?php endforeach; ?>
</ul>
echo Bootstrap::formInputHidden(array(
'name'=>'plugin-list',
'value'=>''
));
<?php echo Bootstrap::formTitle(array('title' => $L->g('Dashboard plugins'))) ?>
echo '<ul class="list-group list-group-sortable">';
foreach ($plugins['siteSidebar'] as $Plugin) {
echo '<li class="list-group-item" data-plugin="'.$Plugin->className().'"><span class="fa fa-arrows-v"></span> '.$Plugin->name().'</li>';
}
echo '</ul>';
?>
<ul class="dashboard-plugins list-group list-group-sortable">
<?php foreach ($plugins['dashboard'] as $plugin): ?>
<li class="list-group-item" data-class-name="<?php echo $plugin->className() ?>">
<i class="bi bi-arrows-expand"></i><?php echo $plugin->name() ?>
</li>
<?php endforeach; ?>
</ul>
<?php echo Bootstrap::formClose(); ?>
<script>
$(document).ready(function() {
$('.list-group-sortable').sortable({
placeholderClass: 'list-group-item'
});
$(".jsbuttonSave").on("click", function() {
var tmp = [];
$("li.list-group-item").each(function() {
tmp.push( $(this).attr("data-plugin") );
});
$("#jsplugin-list").attr("value", tmp.join(",") );
$("#jsform").submit();
});
});
</script>

View file

@ -1,74 +0,0 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
<script>
// ============================================================================
// Variables for the view
// ============================================================================
// ============================================================================
// Functions for the view
// ============================================================================
function configurePlugin(className) {
var args = {
className: className
};
$('input').each(function() {
var key = $(this).attr('name');
var value = $(this).val();
args[key] = value;
});
$('select').each(function() {
var key = $(this).attr('name');
var value = $(this).val();
args[key] = value;
});
api.configurePlugin(args).then(function(response) {
if (response.status == 0) {
logs('Plugin configured: ' + response.data.key);
showAlertInfo("<?php $L->p('The changes have been saved') ?>");
} else {
logs('An error occurred while trying to configured the plugin.');
showAlertError(response.message);
}
});
}
// ============================================================================
// Events for the view
// ============================================================================
$(document).ready(function() {
$('#btnSave').on('click', function() {
var className = $(this).data('class-name');
configurePlugin(className);
});
});
// ============================================================================
// Initlization for the view
// ============================================================================
$(document).ready(function() {
// No initialization for the view yet
});
</script>
<div class="d-flex align-items-center mb-4">
<h2 class="m-0"><i class="bi bi-node-plus"></i><?php echo $plugin->name() ?></h2>
<?php if ($plugin->formButtons()) : ?>
<div class="ms-auto">
<button id="btnSave" type="button" class="btn btn-primary btn-sm" data-class-name="<?php echo $plugin->className() ?>"><?php $L->p('Save') ?></button>
<a id="btnCancel" class="btn btn-secondary btn-sm" href="<?php echo HTML_PATH_ADMIN_ROOT . 'plugins' ?>" role="button"><?php $L->p('Cancel') ?></a>
</div>
<?php endif; ?>
</div>
<?php
if ($plugin->description()) {
echo '<div class="alert alert-primary" role="alert">'.$plugin->description().'</div>';
}
echo $plugin->form();
?>

View file

@ -1,49 +1,20 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
<?php
echo Bootstrap::pageTitle(array('title' => $L->g('Plugins'), 'icon' => 'puzzle-piece'));
echo Bootstrap::link(array(
'title' => $L->g('Change the position of the plugins'),
'href' => HTML_PATH_ADMIN_ROOT . 'plugins-position',
'icon' => 'arrows'
));
echo Bootstrap::formTitle(array('title' => $L->g('Search plugins')));
?>
<input type="text" dir="auto" class="form-control" id="search" placeholder="<?php $L->p('Search') ?>">
<script>
// ============================================================================
// Variables for the view
// ============================================================================
// ============================================================================
// Functions for the view
// ============================================================================
function activatePlugin(className) {
var args = {
className: className
};
api.activatePlugin(args).then(function(response) {
if (response.status == 0) {
logs('Plugin activated: ' + response.data.key);
window.location.replace('<?php echo HTML_PATH_ADMIN_ROOT . 'plugins-settings/' ?>'+response.data.key);
} else {
logs('An error occurred while trying to activate the plugin.');
showAlertError(response.message);
}
});
}
function deactivatePlugin(className) {
var args = {
className: className
};
api.deactivatePlugin(args).then(function(response) {
if (response.status == 0) {
logs('Plugin deactivated: ' + response.data.key);
window.location.replace('<?php echo HTML_PATH_ADMIN_ROOT . 'plugins' ?>');
} else {
logs('An error occurred while trying to deactivate the plugin.');
showAlertError(response.message);
}
});
}
// ============================================================================
// Events for the view
// ============================================================================
$(document).ready(function() {
$("#search").on("keyup", function() {
var textToSearch = $(this).val().toLowerCase();
$(".searchItem").each(function() {
@ -57,62 +28,35 @@
});
});
});
$('.activatePlugin').on('click', function() {
var className = $(this).data('class-name');
activatePlugin(className);
});
$('.deactivatePlugin').on('click', function() {
var className = $(this).data('class-name');
deactivatePlugin(className);
});
});
// ============================================================================
// Initialization for the view
// ============================================================================
$(document).ready(function() {
// nothing here yet
// how do you hang your toilet paper ? over or under ?
});
</script>
<div class="d-flex align-items-center mb-4">
<h2 class="m-0"><i class="bi bi-node-plus"></i><?php $L->p('Plugins') ?></h2>
<div class="ms-auto">
<a id="btnNew" class="btn btn-primary btn-sm" href="<?php echo HTML_PATH_ADMIN_ROOT . 'plugins-position' ?>" role="button"><i class="bi bi-plus-circle"></i><?php $L->p('Change plugins position') ?></a>
</div>
</div>
<?php echo Bootstrap::formTitle(array('icon' => 'search', 'title' => $L->g('Search plugins'))); ?>
<input type="text" class="form-control" id="search" placeholder="<?php $L->p('Search') ?>">
<?php
echo Bootstrap::formTitle(array('icon' => 'check-square', 'title' => $L->g('Enabled plugins')));
echo Bootstrap::formTitle(array('title' => $L->g('Enabled plugins')));
echo '
<table class="table table-striped">
<table class="table">
<tbody>
';
// Show installed plugins
foreach ($pluginsInstalled as $plugin) {
echo '<tr id="' . $plugin->className() . '" class="searchItem">';
if ($plugin->type() == 'theme') {
// Do not display theme's plugins
continue;
}
echo '<tr id="' . $plugin->className() . '" class="bg-light searchItem">';
echo '<td class="align-middle pt-3 pb-3 w-25">
<div class="searchText">' . $plugin->name() . '</div>
<div class="mt-1">';
if (method_exists($plugin, 'form')) {
echo '<a class="me-3" href="' . HTML_PATH_ADMIN_ROOT . 'plugins-settings/' . $plugin->className() . '">' . $L->g('Settings') . '</a>';
}
// You can not disable a plugin for an activated theme
if ($plugin->type()!='theme') {
echo '<span class="link deactivatePlugin" data-class-name="' . $plugin->className() . '">' . $L->g('Deactivate') . '</a>';
echo '<a class="mr-3" href="' . HTML_PATH_ADMIN_ROOT . 'configure-plugin/' . $plugin->className() . '">' . $L->g('Settings') . '</a>';
}
echo '<a href="' . HTML_PATH_ADMIN_ROOT . 'uninstall-plugin/' . $plugin->className() . '">' . $L->g('Deactivate') . '</a>';
echo '</div>';
echo '</td>';
@ -136,22 +80,27 @@ echo '
</table>
';
echo Bootstrap::formTitle(array('icon' => 'dash-square', 'title' => $L->g('Disabled plugins')));
echo Bootstrap::formTitle(array('title' => $L->g('Disabled plugins')));
echo '
<table class="table table-striped">
<table class="table">
<tbody>
';
// Plugins not installed
$pluginsNotInstalled = array_diff_key($plugins['all'], $pluginsInstalled);
foreach ($pluginsNotInstalled as $plugin) {
if ($plugin->type() == 'theme') {
// Do not display theme's plugins
continue;
}
echo '<tr id="' . $plugin->className() . '" class="searchItem">';
echo '<td class="align-middle pt-3 pb-3 w-25">
<div class="searchText">' . $plugin->name() . '</div>
<div class="mt-1">
<span class="link activatePlugin" data-class-name="' . $plugin->className() . '">' . $L->g('Activate') . '</a>
<a href="' . HTML_PATH_ADMIN_ROOT . 'install-plugin/' . $plugin->className() . '">' . $L->g('Activate') . '</a>
</div>
</td>';

File diff suppressed because it is too large Load diff

View file

@ -1,83 +1,57 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
<script>
// ============================================================================
// Variables for the view
// ============================================================================
// ============================================================================
// Functions for the view
// ============================================================================
// ============================================================================
// Events for the view
// ============================================================================
$(document).ready(function() {
// No events for the view yet
});
// ============================================================================
// Initialization for the view
// ============================================================================
$(document).ready(function() {
// No initialization for the view yet
});
</script>
<?php
echo Bootstrap::pageTitle(array('title'=>$L->g('Themes'), 'icon'=>'eye'));
echo Bootstrap::pageTitle(array('title' => $L->g('Themes'), 'icon' => 'desktop'));
echo '
<table class="table table-striped mt-3">
<table class="table mt-3">
<thead>
<tr>
<th class="border-bottom-0 w-25" scope="col">'.$L->g('Name').'</th>
<th class="border-bottom-0 d-none d-sm-table-cell" scope="col">'.$L->g('Description').'</th>
<th class="text-center border-bottom-0 d-none d-lg-table-cell" scope="col">'.$L->g('Version').'</th>
<th class="text-center border-bottom-0 d-none d-lg-table-cell" scope="col">'.$L->g('Author').'</th>
<th class="border-bottom-0 w-25" scope="col">' . $L->g('Name') . '</th>
<th class="border-bottom-0 d-none d-sm-table-cell" scope="col">' . $L->g('Description') . '</th>
<th class="text-center border-bottom-0 d-none d-lg-table-cell" scope="col">' . $L->g('Version') . '</th>
<th class="text-center border-bottom-0 d-none d-lg-table-cell" scope="col">' . $L->g('Author') . '</th>
</tr>
</thead>
<tbody>
';
foreach ($themes as $theme) {
echo '
<tr>
<td class="align-middle pt-4 pb-4">
<div>'.$theme['name'].($theme['dirname']==$site->theme()?'<span class="badge bg-primary ms-2">Active</span>':'').'</div>
echo '
<tr ' . ($theme['dirname'] == $site->theme() ? 'class="bg-light"' : '') . '>
<td class="align-middle pt-3 pb-3">
<div>'.$theme['name'].($theme['dirname']==$site->theme()?'<span class="badge badge-primary ml-2">'.$L->g('Active').'</span>':'').'</div>
<div class="mt-1">
';
if ($theme['dirname']!=$site->theme()) {
echo '<a href="'.HTML_PATH_ADMIN_ROOT.'install-theme/'.$theme['dirname'].'">'.$L->g('Activate').'</a>';
} else {
if (isset($theme['plugin'])) {
echo '<a href="' . HTML_PATH_ADMIN_ROOT . 'plugins-settings/' . $theme['plugin'] . '">' . $L->g('Settings') . '</a>';
}
}
if ($theme['dirname'] != $site->theme()) {
echo '<a href="' . HTML_PATH_ADMIN_ROOT . 'install-theme/' . $theme['dirname'] . '">' . $L->g('Activate') . '</a>';
} else {
if (isset($theme['plugin'])) {
echo '<a href="' . HTML_PATH_ADMIN_ROOT . 'configure-plugin/' . $theme['plugin'] . '">' . $L->g('Settings') . '</a>';
}
}
echo '
echo '
</div>
</td>
';
echo '<td class="align-middle d-none d-sm-table-cell">';
echo $theme['description'];
echo '</td>';
echo '<td class="align-middle d-none d-sm-table-cell">';
echo $theme['description'];
echo '</td>';
echo '<td class="text-center align-middle d-none d-lg-table-cell">';
echo '<span>'.$theme['version'].'</span>';
echo '</td>';
echo '<td class="text-center align-middle d-none d-lg-table-cell">';
echo '<span>' . $theme['version'] . '</span>';
echo '</td>';
echo '<td class="text-center align-middle d-none d-lg-table-cell">
<a target="_blank" href="'.$theme['website'].'">'.$theme['author'].'</a>
echo '<td class="text-center align-middle d-none d-lg-table-cell">
<a target="_blank" href="' . $theme['website'] . '">' . $theme['author'] . '</a>
</td>';
echo '</tr>';
echo '</tr>';
}
echo '
</tbody>
</table>
';
';

View file

@ -0,0 +1,60 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
<?php echo Bootstrap::formOpen(array('id'=>'jsform', 'class'=>'tab-content')); ?>
<div class="align-middle">
<div class="float-right mt-1">
<button type="submit" class="btn btn-primary btn-sm" name="save"><?php $L->p('Save') ?></button>
<a class="btn btn-secondary btn-sm" href="<?php echo HTML_PATH_ADMIN_ROOT.'edit-user/'.$user->username() ?>" role="button"><?php $L->p('Cancel') ?></a>
</div>
<?php echo Bootstrap::pageTitle(array('title'=>$L->g('Change password'), 'icon'=>'user')); ?>
</div>
<?php
// Token CSRF
echo Bootstrap::formInputHidden(array(
'name'=>'tokenCSRF',
'value'=>$security->getTokenCSRF()
));
// Username
echo Bootstrap::formInputHidden(array(
'name'=>'username',
'value'=>$user->username()
));
// Username disabled
echo Bootstrap::formInputText(array(
'name'=>'usernameDisabled',
'label'=>$L->g('Username'),
'value'=>$user->username(),
'class'=>'',
'placeholder'=>'',
'disabled'=>true,
'tip'=>''
));
// New password
echo Bootstrap::formInputText(array(
'name'=>'newPassword',
'label'=>$L->g('New password'),
'type'=>'password',
'value'=>'',
'class'=>'',
'placeholder'=>'',
'tip'=>''
));
// Confirm password
echo Bootstrap::formInputText(array(
'name'=>'confirmPassword',
'label'=>$L->g('Confirm new password'),
'type'=>'password',
'value'=>'',
'class'=>'',
'placeholder'=>'',
'tip'=>''
));
?>
<?php echo Bootstrap::formClose(); ?>

View file

@ -1,37 +1,15 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
<script>
// ============================================================================
// Variables for the view
// ============================================================================
// ============================================================================
// Functions for the view
// ============================================================================
// ============================================================================
// Events for the view
// ============================================================================
$(document).ready(function() {
// No events for the view yet
});
// ============================================================================
// Initialization for the view
// ============================================================================
$(document).ready(function() {
// No initialization for the view yet
});
</script>
<div class="d-flex align-items-center mb-4">
<h2 class="m-0"><i class="bi bi-people"></i><?php $L->p('Users') ?></h2>
<div class="ms-auto">
<a id="btnNew" class="btn btn-primary btn-sm" href="<?php echo HTML_PATH_ADMIN_ROOT . 'add-user' ?>" role="button"><i class="bi bi-plus-circle"></i><?php $L->p('Add a new user') ?></a>
</div>
</div>
<?php
echo Bootstrap::pageTitle(array('title'=>$L->g('Users'), 'icon'=>'users'));
echo Bootstrap::link(array(
'title'=>$L->g('add-a-new-user'),
'href'=>HTML_PATH_ADMIN_ROOT.'new-user',
'icon'=>'plus'
));
echo '
<table class="table table-striped mt-3">
<thead>
@ -52,20 +30,20 @@ foreach ($list as $username) {
try {
$user = new User($username);
echo '<tr>';
echo '<td class="pt-4 pb-4"><a href="'.HTML_PATH_ADMIN_ROOT.'edit-user/'.$username.'">'.$username.'</a></td>';
echo '<td class="pt-4 pb-4 d-none d-lg-table-cell">'.$user->nickname().'</td>';
echo '<td class="pt-4 pb-4">'.$user->email().'</td>';
echo '<td class="pt-4 pb-4">'.($user->enabled()?'<b>'.$L->g('Enabled').'</b>':'<b class="text-danger">'.$L->g('Disabled').'</b>').'</td>';
echo '<td><img class="profilePicture mr-1" alt="" src="'.(Sanitize::pathFile(PATH_UPLOADS_PROFILES.$user->username().'.png')?DOMAIN_UPLOADS_PROFILES.$user->username().'.png':HTML_PATH_CORE_IMG.'default.svg').'" /><a href="'.HTML_PATH_ADMIN_ROOT.'edit-user/'.$username.'">'.$username.'</a></td>';
echo '<td class="d-none d-lg-table-cell">'.$user->nickname().'</td>';
echo '<td>'.$user->email().'</td>';
echo '<td>'.($user->enabled()?'<b>'.$L->g('Enabled').'</b>':$L->g('Disabled')).'</td>';
if ($user->role()=='admin') {
echo '<td class="pt-4 pb-4">'.$L->g('Administrator').'</td>';
echo '<td>'.$L->g('Administrator').'</td>';
} elseif ($user->role()=='editor') {
echo '<td class="pt-4 pb-4">'.$L->g('Editor').'</td>';
echo '<td>'.$L->g('Editor').'</td>';
} elseif ($user->role()=='author') {
echo '<td class="pt-4 pb-4">'.$L->g('Author').'</td>';
echo '<td>'.$L->g('Author').'</td>';
} else {
echo '<td class="pt-4 pb-4">'.$L->g('Reader').'</td>';
echo '<td>'.$L->g('Reader').'</td>';
}
echo '<td class="pt-4 pb-4 d-none d-lg-table-cell">'.Date::format($user->registered(), DB_DATE_FORMAT, ADMIN_PANEL_DATE_FORMAT).'</td>';
echo '<td class="d-none d-lg-table-cell">'.Date::format($user->registered(), DB_DATE_FORMAT, ADMIN_PANEL_DATE_FORMAT).'</td>';
echo '</tr>';
} catch (Exception $e) {
// Continue

View file

@ -16,13 +16,13 @@ $result = array();
if (Text::stringContains(Text::lowercase($L->g('New content')), $query)) {
$tmp = array('disabled'=>true, 'icon'=>'plus-circle', 'type'=>'menu');
$tmp['text'] = $L->g('New content');
$tmp['url'] = HTML_PATH_ADMIN_ROOT.'editor';
$tmp['url'] = HTML_PATH_ADMIN_ROOT.'new-content';
array_push($result, $tmp);
}
if (Text::stringContains(Text::lowercase($L->g('New category')), $query)) {
$tmp = array('disabled'=>true, 'icon'=>'tag', 'type'=>'menu');
$tmp['text'] = $L->g('New category');
$tmp['url'] = HTML_PATH_ADMIN_ROOT.'add-category';
$tmp['url'] = HTML_PATH_ADMIN_ROOT.'new-category';
array_push($result, $tmp);
}
if (Text::stringContains(Text::lowercase($L->g('New user')), $query)) {

View file

@ -0,0 +1,43 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
header('Content-Type: application/json');
/*
| Delete an image from a particular page
|
| @_POST['filename'] string Name of the file to delete
| @_POST['uuid'] string Page UUID
|
| @return array
*/
// $_POST
// ----------------------------------------------------------------------------
$filename = isset($_POST['filename']) ? $_POST['filename'] : false;
$uuid = empty($_POST['uuid']) ? false : $_POST['uuid'];
// ----------------------------------------------------------------------------
if ($filename===false) {
ajaxResponse(1, 'The filename is empty.');
}
if ($uuid && IMAGE_RESTRICT) {
$imagePath = PATH_UPLOADS_PAGES.$uuid.DS;
$thumbnailPath = PATH_UPLOADS_PAGES.$uuid.DS.'thumbnails'.DS;
} else {
$imagePath = PATH_UPLOADS;
$thumbnailPath = PATH_UPLOADS_THUMBNAILS;
}
// Delete image
if (Sanitize::pathFile($imagePath.$filename)) {
Filesystem::rmfile($imagePath.$filename);
}
// Delete thumbnail
if (Sanitize::pathFile($thumbnailPath.$filename)) {
Filesystem::rmfile($thumbnailPath.$filename);
}
ajaxResponse(0, 'Image deleted.');
?>

View file

@ -2,14 +2,12 @@
header('Content-Type: application/json');
/*
| Returns a list of pages that the title contains the query string.
| The returned list have published, sticky and statics pages.
| It's possible to filter the pages are parents by the flag "checkIsParent".
| Returns a list of pages and the title contains the query string
| The returned list have published, sticky and statics pages
|
| @_POST['query'] string The string to search in the title of the pages.
| @_POST['checkIsParent'] boolean TRUE returns only parent pages, FALSE returns all pages.
| @_POST['query'] string The string to search in the title of the pages
|
| @return json Ex. {"results":[{"disabled":false,"id":"follow-bludit","text":"Follow Bludit","type":"published"}]}
| @return array
*/
// $_GET

View file

@ -0,0 +1,62 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
header('Content-Type: application/json');
/*
| Returns a list of images from a particular page
|
| @_POST['pageNumber'] int Page number for the paginator
| @_POST['path'] string Pre-defined name for the directory to read, its pre-defined to avoid security issues
| @_POST['uuid'] string Page UUID
|
| @return array
*/
// $_POST
// ----------------------------------------------------------------------------
// $_POST['pageNumber'] > 0
$pageNumber = empty($_POST['pageNumber']) ? 1 : (int)$_POST['pageNumber'];
$pageNumber = $pageNumber - 1;
$path = empty($_POST['path']) ? false : $_POST['path'];
$uuid = empty($_POST['uuid']) ? false : $_POST['uuid'];
// ----------------------------------------------------------------------------
// Set the path to get the file list
if ($path=='thumbnails') {
if ($uuid && IMAGE_RESTRICT) {
$path = PATH_UPLOADS_PAGES.$uuid.DS.'thumbnails'.DS;
} else {
$path = PATH_UPLOADS_THUMBNAILS;
}
} else {
ajaxResponse(1, 'Invalid path.');
}
// Get all files from the directory $path, also split the array by numberOfItems
// The function listFiles split in chunks
$listOfFilesByPage = Filesystem::listFiles($path, '*', '*', MEDIA_MANAGER_SORT_BY_DATE, MEDIA_MANAGER_NUMBER_OF_FILES);
// Check if the page number exists in the chunks
if (isset($listOfFilesByPage[$pageNumber])) {
// Get only the filename from the chunk
$files = array();
foreach ($listOfFilesByPage[$pageNumber] as $file) {
$filename = basename($file);
array_push($files, $filename);
}
// Returns the number of chunks for the paginator
// Returns the files inside the chunk
ajaxResponse(0, 'List of files and number of chunks.', array(
'numberOfPages'=>count($listOfFilesByPage),
'files'=>$files
));
}
ajaxResponse(0, 'List of files and number of chunks.', array(
'numberOfPages'=>0,
'files'=>array()
));
?>

View file

@ -0,0 +1,22 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
header('Content-Type: application/json');
/*
| Delete the site logo
| This script delete the file and set and empty string in the database
|
| @return array
*/
// Delete the file
$logoFilename = $site->logo(false);
if ($logoFilename) {
Filesystem::rmfile(PATH_UPLOADS.$logoFilename);
}
// Remove the logo from the database
$site->set(array('logo'=>''));
ajaxResponse(0, 'Logo removed.');
?>

View file

@ -0,0 +1,70 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
header('Content-Type: application/json');
/*
| Upload site logo
| The final filename is the site's name and the extension is the same as the file uploaded
|
| @_FILES['inputFile'] multipart/form-data File from form
|
| @return array
*/
if (!isset($_FILES['inputFile'])) {
ajaxResponse(1, 'Error trying to upload the site logo.');
}
// Check path traversal on $filename
if (Text::stringContains($_FILES['inputFile']['name'], DS, false)) {
$message = 'Path traversal detected.';
Log::set($message, LOG_TYPE_ERROR);
ajaxResponse(1, $message);
}
// File extension
$fileExtension = Filesystem::extension($_FILES['inputFile']['name']);
$fileExtension = Text::lowercase($fileExtension);
if (!in_array($fileExtension, $GLOBALS['ALLOWED_IMG_EXTENSION'])) {
$message = $L->g('File type is not supported. Allowed types:').' '.implode(', ',$GLOBALS['ALLOWED_IMG_EXTENSION']);
Log::set($message, LOG_TYPE_ERROR);
ajaxResponse(1, $message);
}
// File MIME Type
$fileMimeType = Filesystem::mimeType($_FILES['inputFile']['tmp_name']);
if ($fileMimeType!==false) {
if (!in_array($fileMimeType, $GLOBALS['ALLOWED_IMG_MIMETYPES'])) {
$message = $L->g('File mime type is not supported. Allowed types:').' '.implode(', ',$GLOBALS['ALLOWED_IMG_MIMETYPES']);
Log::set($message, LOG_TYPE_ERROR);
ajaxResponse(1, $message);
}
}
// Final filename
$filename = 'logo.'.$fileExtension;
if (Text::isNotEmpty( $site->title() )) {
$filename = $site->title().'.'.$fileExtension;
}
// Delete old image
$oldFilename = $site->logo(false);
if ($oldFilename) {
Filesystem::rmfile(PATH_UPLOADS.$oldFilename);
}
// Move from temporary directory to uploads
Filesystem::mv($_FILES['inputFile']['tmp_name'], PATH_UPLOADS.$filename);
// Permissions
chmod(PATH_UPLOADS.$filename, 0644);
// Store the filename in the database
$site->set(array('logo'=>$filename));
ajaxResponse(0, 'Image uploaded.', array(
'filename'=>$filename,
'absoluteURL'=>DOMAIN_UPLOADS.$filename,
'absolutePath'=>PATH_UPLOADS.$filename
));
?>

View file

@ -0,0 +1,74 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
header('Content-Type: application/json');
// $_POST
// ----------------------------------------------------------------------------
// (string) $_POST['username']
$username = empty($_POST['username']) ? false : $_POST['username'];
// ----------------------------------------------------------------------------
if ($username===false) {
ajaxResponse(1, 'Error in username.');
}
if ( ($login->role()!='admin') && ($login->username()!=$username) ) {
ajaxResponse(1, 'Error in username.');
}
if (!isset($_FILES['profilePictureInputFile'])) {
ajaxResponse(1, 'Error trying to upload the profile picture.');
}
// Check path traversal
if (Text::stringContains($username, DS, false)) {
$message = 'Path traversal detected.';
Log::set($message, LOG_TYPE_ERROR);
ajaxResponse(1, $message);
}
// Check file extension
$fileExtension = Filesystem::extension($_FILES['profilePictureInputFile']['name']);
$fileExtension = Text::lowercase($fileExtension);
if (!in_array($fileExtension, $GLOBALS['ALLOWED_IMG_EXTENSION']) ) {
$message = $L->g('File type is not supported. Allowed types:').' '.implode(', ',$GLOBALS['ALLOWED_IMG_EXTENSION']);
Log::set($message, LOG_TYPE_ERROR);
ajaxResponse(1, $message);
}
// Check file MIME Type
$fileMimeType = Filesystem::mimeType($_FILES['profilePictureInputFile']['tmp_name']);
if ($fileMimeType!==false) {
if (!in_array($fileMimeType, $GLOBALS['ALLOWED_IMG_MIMETYPES'])) {
$message = $L->g('File mime type is not supported. Allowed types:').' '.implode(', ',$GLOBALS['ALLOWED_IMG_MIMETYPES']);
Log::set($message, LOG_TYPE_ERROR);
ajaxResponse(1, $message);
}
}
// Tmp filename
$tmpFilename = $username.'.'.$fileExtension;
// Final filename
$filename = $username.'.png';
// Move from temporary directory to uploads folder
rename($_FILES['profilePictureInputFile']['tmp_name'], PATH_TMP.$tmpFilename);
// Resize and convert to png
$image = new Image();
$image->setImage(PATH_TMP.$tmpFilename, PROFILE_IMG_WIDTH, PROFILE_IMG_HEIGHT, 'crop');
$image->saveImage(PATH_UPLOADS_PROFILES.$filename, PROFILE_IMG_QUALITY, false, true);
// Delete temporary file
Filesystem::rmfile(PATH_TMP.$tmpFilename);
// Permissions
chmod(PATH_UPLOADS_PROFILES.$filename, 0644);
ajaxResponse(0, 'Image uploaded.', array(
'filename'=>$filename,
'absoluteURL'=>DOMAIN_UPLOADS_PROFILES.$filename,
'absolutePath'=>PATH_UPLOADS_PROFILES.$filename
));
?>

View file

@ -0,0 +1,95 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
header('Content-Type: application/json');
/*
| Upload an image to a particular page
|
| @_POST['uuid'] string Page uuid
|
| @return array
*/
// $_POST
// ----------------------------------------------------------------------------
$uuid = empty($_POST['uuid']) ? false : $_POST['uuid'];
// ----------------------------------------------------------------------------
// Check path traversal on $uuid
if ($uuid) {
if (Text::stringContains($uuid, DS, false)) {
$message = 'Path traversal detected.';
Log::set($message, LOG_TYPE_ERROR);
ajaxResponse(1, $message);
}
}
// Set upload directory
if ($uuid && IMAGE_RESTRICT) {
$imageDirectory = PATH_UPLOADS_PAGES . $uuid . DS;
$thumbnailDirectory = $imageDirectory . 'thumbnails' . DS;
if (!Filesystem::directoryExists($thumbnailDirectory)) {
Filesystem::mkdir($thumbnailDirectory, true);
}
} else {
$imageDirectory = PATH_UPLOADS;
$thumbnailDirectory = PATH_UPLOADS_THUMBNAILS;
}
$images = array();
foreach ($_FILES['images']['name'] as $uuid => $filename) {
// Check for errors
if ($_FILES['images']['error'][$uuid] != 0) {
$message = $L->g('Maximum load file size allowed:') . ' ' . ini_get('upload_max_filesize');
Log::set($message, LOG_TYPE_ERROR);
ajaxResponse(1, $message);
}
// Convert URL characters such as spaces or quotes to characters
$filename = urldecode($filename);
// Check path traversal on $filename
if (Text::stringContains($filename, DS, false)) {
$message = 'Path traversal detected.';
Log::set($message, LOG_TYPE_ERROR);
ajaxResponse(1, $message);
}
// Check file extension
$fileExtension = Filesystem::extension($filename);
$fileExtension = Text::lowercase($fileExtension);
if (!in_array($fileExtension, $GLOBALS['ALLOWED_IMG_EXTENSION'])) {
$message = $L->g('File type is not supported. Allowed types:') . ' ' . implode(', ', $GLOBALS['ALLOWED_IMG_EXTENSION']);
Log::set($message, LOG_TYPE_ERROR);
ajaxResponse(1, $message);
}
// Check file MIME Type
$fileMimeType = Filesystem::mimeType($_FILES['images']['tmp_name'][$uuid]);
if ($fileMimeType !== false) {
if (!in_array($fileMimeType, $GLOBALS['ALLOWED_IMG_MIMETYPES'])) {
$message = $L->g('File mime type is not supported. Allowed types:') . ' ' . implode(', ', $GLOBALS['ALLOWED_IMG_MIMETYPES']);
Log::set($message, LOG_TYPE_ERROR);
ajaxResponse(1, $message);
}
}
// Move from PHP tmp file to Bludit tmp directory
Filesystem::mv($_FILES['images']['tmp_name'][$uuid], PATH_TMP . $filename);
// Transform the image and generate the thumbnail
$image = transformImage(PATH_TMP . $filename, $imageDirectory, $thumbnailDirectory);
if ($image) {
chmod($image, 0644);
$filename = Filesystem::filename($image);
array_push($images, $filename);
} else {
$message = 'Error after transformImage() function.';
Log::set($message, LOG_TYPE_ERROR);
ajaxResponse(1, $message);
}
}
ajaxResponse(0, 'Images uploaded.', array(
'images' => $images
));

View file

@ -1,20 +1,14 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// Start the session
// If the session is not started the admin area is not available
Session::start();
// If the session is not possible to start the admin area is not available
Session::start($site->urlPath(), $site->isHTTPS());
if (Session::started()===false) {
exit('Bludit CMS. Session initialization failed.');
}
// The login object contains the authentication system and/or the current user logged
$login = new Login();
// Initialize plugins
include(PATH_RULES.'60.plugins.php');
// Parameters for the controller and view
// For example "title" keeps the HTML tag <title>
$layout = array(
'controller'=>null,
'view'=>null,
@ -25,14 +19,14 @@ $layout = array(
'title'=>'Bludit'
);
// Get from the URL the controller and view
// Get the Controller
$explodeSlug = $url->explodeSlug();
$layout['controller'] = $layout['view'] = $layout['slug'] = empty($explodeSlug[0])?'dashboard':$explodeSlug[0];
unset($explodeSlug[0]);
// Check if the user want to get access to an admin controller or view from a plugin
// To get access to a plugin controller or view the URL should be: http://localhost/admin/plugin/<PLUGIN NAME>
// $explodeSlug = [0=>'<PLUGIN NAME>']
// Get the Plugins
include(PATH_RULES.'60.plugins.php');
// Check if the user want to access to an admin controller or view from a plugin
if ($layout['controller'] === 'plugin' && !empty($explodeSlug)) {
// Lowercase plugins class name to search by case-insensitive
$pluginsLowerCases = array_change_key_case($pluginsInstalled);
@ -52,57 +46,59 @@ if ($layout['slug']==='ajax') {
include(PATH_RULES.'99.security.php');
// Load the ajax file
if (Sanitize::pathFile(PATH_AJAX.$layout['parameters'].'.php')) {
if (Sanitize::pathFile(PATH_AJAX, $layout['parameters'].'.php')) {
include(PATH_AJAX.$layout['parameters'].'.php');
}
}
header('HTTP/1.1 401 User not logged.');
exit(0);
}
// --- ADMIN AREA ---
else
{
// Boot rules
include(PATH_RULES.'69.pages.php');
include(PATH_RULES.'99.header.php');
include(PATH_RULES.'99.paginator.php');
include(PATH_RULES.'99.themes.php');
include(PATH_RULES.'99.security.php');
// Boot rules
include(PATH_RULES.'69.pages.php');
include(PATH_RULES.'99.header.php');
include(PATH_RULES.'99.paginator.php');
include(PATH_RULES.'99.themes.php');
include(PATH_RULES.'99.security.php');
// Page not found.
// User not logged.
// Slug is login.
if ($url->notFound() || !$login->isLogged() || ($url->slug()==='login') ) {
$layout['controller'] = 'login';
$layout['view'] = 'login';
$layout['template'] = 'login.php';
// Define layout login-form for:
// - User not logged
// - Page not found
// - Slug is login. http://localhost/admin/login
if ($url->notFound() || !$login->isLogged() || ($url->slug()==='login') ) {
$layout['controller'] = 'login';
$layout['view'] = 'login';
$layout['template'] = 'login.php';
// Generate the tokenCSRF for the user not logged, when the user log-in the token will be change.
$security->generateTokenCSRF();
}
// Generate the tokenCSRF for the user not logged, when the user log-in the token will change
$security->generateTokenCSRF();
// Define variables
$ADMIN_CONTROLLER = $layout['controller'];
$ADMIN_VIEW = $layout['view'];
// Load plugins before the admin area will be load.
Theme::plugins('beforeAdminLoad');
// Load init.php if the theme has one.
if (Sanitize::pathFile(PATH_ADMIN_THEMES, $site->adminTheme().DS.'init.php')) {
include(PATH_ADMIN_THEMES.$site->adminTheme().DS.'init.php');
}
// Load controller.
if (Sanitize::pathFile(PATH_ADMIN_CONTROLLERS, $layout['controller'].'.php')) {
include(PATH_ADMIN_CONTROLLERS.$layout['controller'].'.php');
} elseif ($layout['plugin'] && method_exists($layout['plugin'], 'adminController')) {
$layout['plugin']->adminController();
}
// Load view and theme.
if (Sanitize::pathFile(PATH_ADMIN_THEMES, $site->adminTheme().DS.$layout['template'])) {
include(PATH_ADMIN_THEMES.$site->adminTheme().DS.$layout['template']);
}
// Load plugins after the admin area is loaded.
Theme::plugins('afterAdminLoad');
}
// Define global variables
$ADMIN_CONTROLLER = $layout['controller'];
$ADMIN_VIEW = $layout['view'];
// Execute plugins before load the admin area
execPluginsByHook('beforeAdminLoad');
// Load init.php if the theme has one
if (Sanitize::pathFile(PATH_ADMIN_THEMES.$site->adminTheme().DS.'init.php')) {
include(PATH_ADMIN_THEMES.$site->adminTheme().DS.'init.php');
}
// Load controller
if (Sanitize::pathFile(PATH_ADMIN_CONTROLLERS.$layout['controller'].'.php')) {
include(PATH_ADMIN_CONTROLLERS.$layout['controller'].'.php');
} elseif ($layout['plugin'] && method_exists($layout['plugin'], 'adminController')) {
$layout['plugin']->adminController();
}
// Load view and theme
if (Sanitize::pathFile(PATH_ADMIN_THEMES.$site->adminTheme().DS.$layout['template'])) {
include(PATH_ADMIN_THEMES.$site->adminTheme().DS.$layout['template']);
}
// Execute plugins after the admin area is loaded
execPluginsByHook('afterAdminLoad');

View file

@ -1,69 +1,77 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// Bludit version
define('BLUDIT_VERSION', '4.0.0');
define('BLUDIT_CODENAME', '');
define('BLUDIT_RELEASE_DATE', '2021-05-23');
define('BLUDIT_BUILD', '20210523');
define('BLUDIT_VERSION', '3.16.2');
define('BLUDIT_CODENAME', 'Valencia');
define('BLUDIT_RELEASE_DATE', '2024-08-23');
define('BLUDIT_BUILD', '20240806');
// Debug mode
// Change to FALSE, for prevent warning or errors on browser
// Change to TRUE for debugging
define('DEBUG_MODE', TRUE);
define('DEBUG_TYPE', 'INFO'); // INFO, TRACE
error_reporting(0); // Turn off all error reporting
// This determines whether errors should be printed to the screen as part of the output or if they should be hidden from the user.
ini_set("display_errors", 0);
// Even when display_errors is on, errors that occur during PHP's startup sequence are not displayed.
// It's strongly recommended to keep display_startup_errors off, except for debugging.
ini_set('display_startup_errors', 0);
// If disabled, error message will be solely plain text instead HTML code.
ini_set("html_errors", 0);
// Tells whether script error messages should be logged to the server's error log or error_log.
ini_set('log_errors', 1);
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);
error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);
} else {
error_reporting(E_ERROR);
}
// PHP paths
// PATH_ROOT and PATH_BOOT are defined in index.php
define('PATH_LANGUAGES', PATH_ROOT.'bl-languages'.DS);
define('PATH_THEMES', PATH_ROOT.'bl-themes'.DS);
define('PATH_PLUGINS', PATH_ROOT.'bl-plugins'.DS);
define('PATH_KERNEL', PATH_ROOT.'bl-kernel'.DS);
define('PATH_CONTENT', PATH_ROOT.'bl-content'.DS);
define('PATH_LANGUAGES', PATH_ROOT . 'bl-languages' . DS);
define('PATH_THEMES', PATH_ROOT . 'bl-themes' . DS);
define('PATH_PLUGINS', PATH_ROOT . 'bl-plugins' . DS);
define('PATH_KERNEL', PATH_ROOT . 'bl-kernel' . DS);
define('PATH_CONTENT', PATH_ROOT . 'bl-content' . DS);
define('PATH_ABSTRACT', PATH_KERNEL.'abstract'.DS);
define('PATH_RULES', PATH_KERNEL.'boot'.DS.'rules'.DS);
define('PATH_HELPERS', PATH_KERNEL.'helpers'.DS);
define('PATH_AJAX', PATH_KERNEL.'ajax'.DS);
define('PATH_CORE_JS', PATH_KERNEL.'js'.DS);
define('PATH_ABSTRACT', PATH_KERNEL . 'abstract' . DS);
define('PATH_RULES', PATH_KERNEL . 'boot' . DS . 'rules' . DS);
define('PATH_HELPERS', PATH_KERNEL . 'helpers' . DS);
define('PATH_AJAX', PATH_KERNEL . 'ajax' . DS);
define('PATH_CORE_JS', PATH_KERNEL . 'js' . DS);
define('PATH_PAGES', PATH_CONTENT.'pages'.DS);
define('PATH_DATABASES', PATH_CONTENT.'databases'.DS);
define('PATH_PLUGINS_DATABASES',PATH_CONTENT.'databases'.DS.'plugins'.DS);
define('PATH_THEMES_DATABASES', PATH_CONTENT.'databases'.DS.'themes'.DS);
define('PATH_TMP', PATH_CONTENT.'tmp'.DS);
define('PATH_UPLOADS', PATH_CONTENT.'uploads'.DS);
define('PATH_WORKSPACES', PATH_CONTENT.'workspaces'.DS);
define('PATH_PAGES', PATH_CONTENT . 'pages' . DS);
define('PATH_DATABASES', PATH_CONTENT . 'databases' . DS);
define('PATH_PLUGINS_DATABASES', PATH_CONTENT . 'databases' . DS . 'plugins' . DS);
define('PATH_TMP', PATH_CONTENT . 'tmp' . DS);
define('PATH_UPLOADS', PATH_CONTENT . 'uploads' . DS);
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_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);
define('PATH_ADMIN_CONTROLLERS',PATH_ADMIN.'controllers'.DS);
define('PATH_ADMIN_VIEWS', PATH_ADMIN.'views'.DS);
define('PATH_ADMIN', PATH_KERNEL . 'admin' . DS);
define('PATH_ADMIN_THEMES', PATH_ADMIN . 'themes' . DS);
define('PATH_ADMIN_CONTROLLERS', PATH_ADMIN . 'controllers' . DS);
define('PATH_ADMIN_VIEWS', PATH_ADMIN . 'views' . DS);
define('DEBUG_FILE', PATH_CONTENT.'debug.txt');
define('DEBUG_FILE', PATH_CONTENT . 'debug.txt');
// PAGES DATABASE
define('DB_PAGES', PATH_DATABASES.'pages.php');
define('DB_SITE', PATH_DATABASES.'site.php');
define('DB_CATEGORIES', PATH_DATABASES.'categories.php');
define('DB_TAGS', PATH_DATABASES.'tags.php');
define('DB_SYSLOG', PATH_DATABASES.'syslog.php');
define('DB_USERS', PATH_DATABASES.'users.php');
define('DB_SECURITY', PATH_DATABASES.'security.php');
define('DB_PAGES', PATH_DATABASES . 'pages.php');
define('DB_SITE', PATH_DATABASES . 'site.php');
define('DB_CATEGORIES', PATH_DATABASES . 'categories.php');
define('DB_TAGS', PATH_DATABASES . 'tags.php');
define('DB_SYSLOG', PATH_DATABASES . 'syslog.php');
define('DB_USERS', PATH_DATABASES . 'users.php');
define('DB_SECURITY', PATH_DATABASES . 'security.php');
// User environment variables
include(PATH_KERNEL.'boot'.DS.'variables.php');
include(PATH_KERNEL . 'boot' . DS . 'variables.php');
// Set internal character encoding
mb_internal_encoding(CHARSET);
@ -72,51 +80,50 @@ mb_internal_encoding(CHARSET);
mb_http_output(CHARSET);
// Inclde Abstract Classes
include(PATH_ABSTRACT.'dbjson.class.php');
include(PATH_ABSTRACT.'dblist.class.php');
include(PATH_ABSTRACT.'plugin.class.php');
include(PATH_ABSTRACT . 'dbjson.class.php');
include(PATH_ABSTRACT . 'dblist.class.php');
include(PATH_ABSTRACT . 'plugin.class.php');
// Inclde Classes
include(PATH_KERNEL.'pages.class.php');
include(PATH_KERNEL.'users.class.php');
include(PATH_KERNEL.'tags.class.php');
include(PATH_KERNEL.'language.class.php');
include(PATH_KERNEL.'site.class.php');
include(PATH_KERNEL.'categories.class.php');
include(PATH_KERNEL.'syslog.class.php');
include(PATH_KERNEL.'page.class.php');
include(PATH_KERNEL.'category.class.php');
include(PATH_KERNEL.'tag.class.php');
include(PATH_KERNEL.'user.class.php');
include(PATH_KERNEL.'url.class.php');
include(PATH_KERNEL.'login.class.php');
include(PATH_KERNEL.'parsedown.class.php');
include(PATH_KERNEL.'security.class.php');
include(PATH_KERNEL . 'pages.class.php');
include(PATH_KERNEL . 'users.class.php');
include(PATH_KERNEL . 'tags.class.php');
include(PATH_KERNEL . 'language.class.php');
include(PATH_KERNEL . 'site.class.php');
include(PATH_KERNEL . 'categories.class.php');
include(PATH_KERNEL . 'syslog.class.php');
include(PATH_KERNEL . 'pagex.class.php');
include(PATH_KERNEL . 'category.class.php');
include(PATH_KERNEL . 'tag.class.php');
include(PATH_KERNEL . 'user.class.php');
include(PATH_KERNEL . 'url.class.php');
include(PATH_KERNEL . 'login.class.php');
include(PATH_KERNEL . 'parsedown.class.php');
include(PATH_KERNEL . 'security.class.php');
// Include functions
include(PATH_KERNEL.'functions.php');
include(PATH_KERNEL . 'functions.php');
// Include Helpers Classes
include(PATH_HELPERS.'text.class.php');
include(PATH_HELPERS.'log.class.php');
include(PATH_HELPERS.'date.class.php');
include(PATH_HELPERS.'session.class.php');
include(PATH_HELPERS.'redirect.class.php');
include(PATH_HELPERS.'sanitize.class.php');
include(PATH_HELPERS.'valid.class.php');
include(PATH_HELPERS.'email.class.php');
include(PATH_HELPERS.'filesystem.class.php');
include(PATH_HELPERS.'alert.class.php');
include(PATH_HELPERS.'paginator.class.php');
include(PATH_HELPERS.'simple-image.class.php');
include(PATH_HELPERS.'tcp.class.php');
include(PATH_HELPERS.'dom.class.php');
include(PATH_HELPERS.'cookie.class.php');
include(PATH_HELPERS.'bootstrap.class.php');
include(PATH_HELPERS.'html.class.php');
include(PATH_HELPERS . 'text.class.php');
include(PATH_HELPERS . 'log.class.php');
include(PATH_HELPERS . 'date.class.php');
include(PATH_HELPERS . 'theme.class.php');
include(PATH_HELPERS . 'session.class.php');
include(PATH_HELPERS . 'redirect.class.php');
include(PATH_HELPERS . 'sanitize.class.php');
include(PATH_HELPERS . 'valid.class.php');
include(PATH_HELPERS . 'email.class.php');
include(PATH_HELPERS . 'filesystem.class.php');
include(PATH_HELPERS . 'alert.class.php');
include(PATH_HELPERS . 'paginator.class.php');
include(PATH_HELPERS . 'image.class.php');
include(PATH_HELPERS . 'tcp.class.php');
include(PATH_HELPERS . 'dom.class.php');
include(PATH_HELPERS . 'cookie.class.php');
if (file_exists(PATH_KERNEL.'bludit.pro.php')) {
include(PATH_KERNEL.'bludit.pro.php');
if (file_exists(PATH_KERNEL . 'bludit.pro.php')) {
include(PATH_KERNEL . 'bludit.pro.php');
}
// Objects
@ -141,44 +148,43 @@ if (!empty($_SERVER['DOCUMENT_ROOT']) && !empty($_SERVER['SCRIPT_NAME']) && empt
$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 = empty($_SERVER['SCRIPT_NAME']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
$base = dirname($base);
}
if (strpos($_SERVER['REQUEST_URI'], $base)!==0) {
if (strpos($_SERVER['REQUEST_URI'], $base) !== 0) {
$base = '/';
} elseif ($base!=DS) {
} elseif ($base != DS) {
$base = trim($base, '/');
$base = '/'.$base.'/';
$base = '/' . $base . '/';
} else {
// 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_THEME_CSS', HTML_PATH_THEME.'css/');
define('HTML_PATH_THEME_JS', HTML_PATH_THEME.'js/');
define('HTML_PATH_THEME_IMG', HTML_PATH_THEME.'img/');
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_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_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_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/');
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_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_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/');
// --- Objects with dependency ---
$language = new Language( $site->language() );
$url->checkFilters( $site->uriFilters() );
$language = new Language($site->language());
$url->checkFilters($site->uriFilters());
// --- CONSTANTS with dependency ---
@ -211,40 +217,38 @@ define('MARKDOWN_PARSER', $site->markdownParser());
// --- PHP paths with dependency ---
// This paths are absolutes for the OS
define('THEME_DIR', PATH_ROOT.'bl-themes'.DS.$site->theme().DS);
define('THEME_DIR_PHP', THEME_DIR.'php'.DS);
define('THEME_DIR_TEMPLATES', THEME_DIR.'templates'.DS);
define('THEME_DIR_CSS', THEME_DIR.'css'.DS);
define('THEME_DIR_JS', THEME_DIR.'js'.DS);
define('THEME_DIR_IMG', THEME_DIR.'img'.DS);
define('THEME_DIR_LANG', THEME_DIR.'languages'.DS);
define('THEME_DIR', PATH_ROOT . 'bl-themes' . DS . $site->theme() . DS);
define('THEME_DIR_PHP', THEME_DIR . 'php' . DS);
define('THEME_DIR_CSS', THEME_DIR . 'css' . DS);
define('THEME_DIR_JS', THEME_DIR . 'js' . DS);
define('THEME_DIR_IMG', THEME_DIR . 'img' . DS);
define('THEME_DIR_LANG', THEME_DIR . 'languages' . DS);
// --- Absolute paths with domain ---
// This paths are absolutes for the user / web browsing.
define('DOMAIN', $site->domain());
define('DOMAIN_BASE', DOMAIN.HTML_PATH_ROOT);
define('DOMAIN_CORE_JS', DOMAIN.HTML_PATH_CORE_JS);
define('DOMAIN_CORE_CSS', DOMAIN.HTML_PATH_CORE_CSS);
define('DOMAIN_CORE_VENDORS', DOMAIN.HTML_PATH_CORE_VENDORS);
define('DOMAIN_THEME', DOMAIN.HTML_PATH_THEME);
define('DOMAIN_THEME_CSS', DOMAIN.HTML_PATH_THEME_CSS);
define('DOMAIN_THEME_JS', DOMAIN.HTML_PATH_THEME_JS);
define('DOMAIN_THEME_IMG', DOMAIN.HTML_PATH_THEME_IMG);
define('DOMAIN_ADMIN_THEME', DOMAIN.HTML_PATH_ADMIN_THEME);
define('DOMAIN_ADMIN_THEME_CSS', DOMAIN.HTML_PATH_ADMIN_THEME_CSS);
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);
define('DOMAIN_BASE', DOMAIN . HTML_PATH_ROOT);
define('DOMAIN_CORE_JS', DOMAIN . HTML_PATH_CORE_JS);
define('DOMAIN_CORE_CSS', DOMAIN . HTML_PATH_CORE_CSS);
define('DOMAIN_THEME', DOMAIN . HTML_PATH_THEME);
define('DOMAIN_THEME_CSS', DOMAIN . HTML_PATH_THEME_CSS);
define('DOMAIN_THEME_JS', DOMAIN . HTML_PATH_THEME_JS);
define('DOMAIN_THEME_IMG', DOMAIN . HTML_PATH_THEME_IMG);
define('DOMAIN_ADMIN_THEME', DOMAIN . HTML_PATH_ADMIN_THEME);
define('DOMAIN_ADMIN_THEME_CSS', DOMAIN . HTML_PATH_ADMIN_THEME_CSS);
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);
define('DOMAIN_ADMIN', DOMAIN_BASE.ADMIN_URI_FILTER.'/');
define('DOMAIN_ADMIN', DOMAIN_BASE . ADMIN_URI_FILTER . '/');
define('DOMAIN_TAGS', Text::addSlashes(DOMAIN_BASE.TAG_URI_FILTER, false, true));
define('DOMAIN_CATEGORIES', Text::addSlashes(DOMAIN_BASE.CATEGORY_URI_FILTER, false, true));
define('DOMAIN_PAGES', Text::addSlashes(DOMAIN_BASE.PAGE_URI_FILTER, false, true));
define('DOMAIN_TAGS', Text::addSlashes(DOMAIN_BASE . TAG_URI_FILTER, false, true));
define('DOMAIN_CATEGORIES', Text::addSlashes(DOMAIN_BASE . CATEGORY_URI_FILTER, false, true));
define('DOMAIN_PAGES', Text::addSlashes(DOMAIN_BASE . PAGE_URI_FILTER, false, true));
$ADMIN_CONTROLLER = '';
$ADMIN_VIEW = '';

View file

@ -1,7 +1,7 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================
// Global Variables
// Variables
// ============================================================================
$plugins = array(
@ -29,9 +29,6 @@ $plugins = array(
'paginator'=>array(),
'beforePageModify'=>array(),
'beforePageDelete'=>array(),
'afterPageCreate'=>array(),
'afterPageModify'=>array(),
'afterPageDelete'=>array(),
@ -40,12 +37,12 @@ $plugins = array(
'loginBodyBegin'=>array(),
'loginBodyEnd'=>array(),
'all'=>array() // $plugins['all'] keep installed and not installed plugins
'all'=>array()
);
// This array has only the installed plugins
// The array key is the "plugin class name" and the value is the object
// pluginsInstalled[pluginClass] = $Plugin
$pluginsEvents = $plugins;
unset($pluginsEvents['all']);
$pluginsInstalled = array();
// ============================================================================
@ -55,20 +52,19 @@ $pluginsInstalled = array();
function buildPlugins()
{
global $plugins;
global $pluginsEvents;
global $pluginsInstalled;
global $L;
global $site;
// This array is only to get the hooks names
$pluginsHooks = $plugins;
unset($pluginsHooks['all']); // remove "all" because is not a valid hook
// Get declared clasess BEFORE load plugins clasess
$currentDeclaredClasess = get_declared_classes();
// Load plugins clasess
// List plugins directories
$list = Filesystem::listDirectories(PATH_PLUGINS);
// Load each plugin clasess
foreach ($list as $pluginPath) {
// Check if the directory has the plugin.php
if (file_exists($pluginPath.DS.'plugin.php')) {
include_once($pluginPath.DS.'plugin.php');
}
@ -93,7 +89,8 @@ function buildPlugins()
$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
// Remove name and description from the language file loaded and add new words if there are
// This function overwrite the key=>value
unset($database['plugin-data']);
if (!empty($database)) {
$L->add($database);
@ -102,24 +99,22 @@ function buildPlugins()
// $plugins['all'] Array with all plugins, installed and not installed
$plugins['all'][$pluginClass] = $Plugin;
// If the plugin is installed insert on the hooks
if ($Plugin->installed()) {
// Include the plugin installed in the global array
$pluginsInstalled[$pluginClass] = $Plugin;
// Define new hooks from custom hooks
// Include custom hooks
if (!empty($Plugin->customHooks)) {
foreach ($Plugin->customHooks as $hook) {
if (!isset($plugins[$hook])) {
$plugins[$hook] = array();
$pluginsHooks[$hook] = array();
foreach ($Plugin->customHooks as $customHook) {
if (!isset($plugins[$customHook])) {
$plugins[$customHook] = array();
$pluginsEvents[$customHook] = array();
}
}
}
// Insert the plugin into the hooks
foreach ($pluginsHooks as $hook=>$value) {
if (method_exists($Plugin, $hook)) {
array_push($plugins[$hook], $Plugin);
$pluginsInstalled[$pluginClass] = $Plugin;
foreach ($pluginsEvents as $event=>$value) {
if (method_exists($Plugin, $event)) {
array_push($plugins[$event], $Plugin);
}
}
}
@ -129,12 +124,6 @@ function buildPlugins()
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();
}
);
}
}

View file

@ -16,7 +16,7 @@
*/
$content = array();
// Page filtered by the user, will be a Page Object
// Page filtered by the user, is a Page Object
$page = false;
// Array with static content, each item is a Page Object
@ -29,7 +29,7 @@ $page = false;
N => Page Object
)
*/
$staticContent = buildStaticPages();
$staticContent = $staticPages = buildStaticPages();
// ============================================================================
// Main
@ -38,10 +38,10 @@ $staticContent = buildStaticPages();
// Execute the scheduler
if ($pages->scheduler()) {
// Execute plugins with the hook afterPageCreate
execPluginsByHook('afterPageCreate');
Theme::plugins('afterPageCreate');
reindexTags();
reindexCategories();
reindexCategories();
// Add to syslog
$syslog->add(array(
@ -61,7 +61,7 @@ if ($site->homepage() && $url->whereAmI()==='home') {
// Build specific page
if ($url->whereAmI()==='page') {
$page = buildThePage();
$content[0] = $page = buildThePage();
}
// Build content by tag
elseif ($url->whereAmI()==='tag') {
@ -73,10 +73,14 @@ elseif ($url->whereAmI()==='category') {
}
// Build content for the homepage
elseif ( ($url->whereAmI()==='home') || ($url->whereAmI()==='blog') ) {
$content = buildPagesForHome();
$content = buildPagesForHome();
}
if (isset($content[0])) {
$page = $content[0];
}
// If set notFound, create the page 404
if ($url->notFound()) {
$page = buildErrorPage();
$content[0] = $page = buildErrorPage();
}

View file

@ -21,7 +21,7 @@ if ($url->whereAmI()=='admin') {
}
// Execute hook from plugins
execPluginsByHook('paginator');
Theme::plugins('paginator');
// Items per page
Paginator::set('itemsPerPage', $itemsPerPage);

View file

@ -3,7 +3,7 @@
// ============================================================================
// Variables
// ============================================================================
$theme = getPlugin($site->theme()); // Returns plugin object or False
$themePlugin = getPlugin($site->theme()); // Returns plugin object or False
// ============================================================================
// Functions
@ -16,20 +16,18 @@ function buildThemes()
$themes = array();
$themesPaths = Filesystem::listDirectories(PATH_THEMES);
foreach($themesPaths as $themePath)
{
foreach ($themesPaths as $themePath) {
// Check if the theme is translated.
$languageFilename = $themePath.DS.'languages'.DS.$site->language().'.json';
if( !Sanitize::pathFile($languageFilename) ) {
$languageFilename = $themePath.DS.'languages'.DS.DEFAULT_LANGUAGE_FILE;
$languageFilename = $themePath . DS . 'languages' . DS . $site->language() . '.json';
if (!Sanitize::pathFile($languageFilename)) {
$languageFilename = $themePath . DS . 'languages' . DS . DEFAULT_LANGUAGE_FILE;
}
if( Sanitize::pathFile($languageFilename) )
{
if (Sanitize::pathFile($languageFilename)) {
$database = file_get_contents($languageFilename);
$database = json_decode($database, true);
if(empty($database)) {
Log::set('99.themes.php'.LOG_SEP.'Language file error on theme '.$themePath);
if (empty($database)) {
Log::set('99.themes.php' . LOG_SEP . 'Language file error on theme ' . $themePath);
break;
}
@ -38,20 +36,19 @@ function buildThemes()
$database['dirname'] = basename($themePath);
// --- Metadata ---
$filenameMetadata = $themePath.DS.'metadata.json';
$filenameMetadata = $themePath . DS . 'metadata.json';
if( Sanitize::pathFile($filenameMetadata) )
{
if (Sanitize::pathFile($filenameMetadata)) {
$metadataString = file_get_contents($filenameMetadata);
$metadata = json_decode($metadataString, true);
$database['compatible'] = false;
if( !empty($metadata['compatible']) ) {
if (!empty($metadata['compatible'])) {
$bluditRoot = explode('.', BLUDIT_VERSION);
$compatible = explode(',', $metadata['compatible']);
foreach( $compatible as $version ) {
foreach ($compatible as $version) {
$root = explode('.', $version);
if( $root[0]==$bluditRoot[0] && $root[1]==$bluditRoot[1] ) {
if ($root[0] == $bluditRoot[0] && $root[1] == $bluditRoot[1]) {
$database['compatible'] = true;
}
}
@ -71,13 +68,12 @@ function buildThemes()
// ============================================================================
// Load the language file
$languageFilename = THEME_DIR.'languages'.DS.$site->language().'.json';
if( !Sanitize::pathFile($languageFilename) ) {
$languageFilename = THEME_DIR.'languages'.DS.DEFAULT_LANGUAGE_FILE;
$languageFilename = THEME_DIR . 'languages' . DS . $site->language() . '.json';
if (!Sanitize::pathFile($languageFilename)) {
$languageFilename = THEME_DIR . 'languages' . DS . DEFAULT_LANGUAGE_FILE;
}
if( Sanitize::pathFile($languageFilename) )
{
if (Sanitize::pathFile($languageFilename)) {
$database = file_get_contents($languageFilename);
$database = json_decode($database, true);
@ -85,7 +81,7 @@ if( Sanitize::pathFile($languageFilename) )
unset($database['theme-data']);
// Load words from the theme language
if(!empty($database)) {
if (!empty($database)) {
$L->add($database);
}
}
}

View file

@ -4,7 +4,7 @@
include(PATH_RULES.'60.plugins.php');
// Plugins before all
execPluginsByHook('beforeAll');
Theme::plugins('beforeAll');
// Load rules
include(PATH_RULES.'60.router.php');
@ -14,22 +14,22 @@ include(PATH_RULES.'99.paginator.php');
include(PATH_RULES.'99.themes.php');
// Plugins before site loaded
execPluginsByHook('beforeSiteLoad');
Theme::plugins('beforeSiteLoad');
// Theme init.php
if (Sanitize::pathFile(PATH_THEMES.$site->theme().DS.'init.php')) {
if (Sanitize::pathFile(PATH_THEMES, $site->theme().DS.'init.php')) {
include(PATH_THEMES.$site->theme().DS.'init.php');
}
// Theme HTML
if (Sanitize::pathFile(PATH_THEMES.$site->theme().DS.'index.php')) {
if (Sanitize::pathFile(PATH_THEMES, $site->theme().DS.'index.php')) {
include(PATH_THEMES.$site->theme().DS.'index.php');
} else {
$L->p('Please check your theme configuration in the admin panel. Check for an active theme.');
}
// Plugins after site loaded
execPluginsByHook('afterSiteLoad');
Theme::plugins('afterSiteLoad');
// Plugins after all
execPluginsByHook('afterAll');
Theme::plugins('afterAll');

View file

@ -26,7 +26,7 @@ define('PROFILE_IMG_HEIGHT', 400);
define('PROFILE_IMG_QUALITY', 100); // 100%
// Items per page for admin area
define('ITEMS_PER_PAGE_ADMIN', 12);
define('ITEMS_PER_PAGE_ADMIN', 20);
// Password length
define('PASSWORD_LENGTH', 6);
@ -107,13 +107,7 @@ define('MEDIA_MANAGER_SORT_BY_DATE', true);
$GLOBALS['DB_TAGS_TYPES'] = array('published','static','sticky');
// Allowed image extensions
$GLOBALS['ALLOWED_IMG_EXTENSIONS'] = array('gif', 'png', 'jpg', 'jpeg', 'svg');
$GLOBALS['ALLOWED_IMG_EXTENSION'] = array('gif', 'png', 'jpg', 'jpeg', 'svg', 'webp');
// Allowed image mime types
$GLOBALS['ALLOWED_IMG_MIMETYPES'] = array('image/gif', 'image/png', 'image/jpeg', 'image/svg+xml');
// Allowed files extensions
$GLOBALS['ALLOWED_FILE_EXTENSIONS'] = array('gif', 'png', 'jpg', 'jpeg', 'svg');
// Allowed files mime types
$GLOBALS['ALLOWED_FILE_MIMETYPES'] = array('image/gif', 'image/png', 'image/jpeg', 'image/svg+xml', 'application/pdf');
$GLOBALS['ALLOWED_IMG_MIMETYPES'] = array('image/gif', 'image/png', 'image/jpeg', 'image/svg+xml', 'image/webp');

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

6
bl-kernel/css/bootstrap.min.css vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -1,6 +0,0 @@
/*! jQuery UI - v1.12.1 - 2020-11-01
* http://jqueryui.com
* Includes: core.css, autocomplete.css, menu.css
* Copyright jQuery Foundation and other contributors; Licensed MIT */
.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important;pointer-events:none}.ui-icon{display:inline-block;vertical-align:middle;margin-top:-.25em;position:relative;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-icon-block{left:50%;margin-left:-8px;display:block}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}.ui-menu{list-style:none;padding:0;margin:0;display:block;outline:0}.ui-menu .ui-menu{position:absolute}.ui-menu .ui-menu-item{margin:0;cursor:pointer;list-style-image:url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7")}.ui-menu .ui-menu-item-wrapper{position:relative;padding:3px 1em 3px .4em}.ui-menu .ui-menu-divider{margin:5px 0;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-state-focus,.ui-menu .ui-state-active{margin:-1px}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item-wrapper{padding-left:2em}.ui-menu .ui-icon{position:absolute;top:0;bottom:0;left:.2em;margin:auto 0}.ui-menu .ui-menu-icon{left:auto;right:0}

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 424 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,107 +0,0 @@
.tagsinput,
.tagsinput * {
box-sizing: border-box
}
.tagsinput {
display: flex;
flex-wrap: wrap;
color: #6c757d;
padding: 5px 5px 0;
border-radius: 2px;
border: 1px solid #ced4da;
}
.tagsinput .tag {
position: relative;
background: #6c757d;
display: block;
max-width: 100%;
word-wrap: break-word;
color: #fff;
padding: 5px 30px 5px 5px;
border-radius: 2px;
margin: 0 5px 5px 0
}
.tagsinput .tag .tag-remove {
position: absolute;
background: 0 0;
display: block;
width: 30px;
height: 30px;
top: 0;
right: 0;
cursor: pointer;
text-decoration: none;
text-align: center;
color: #ccc;
line-height: 30px;
padding: 0;
border: 0
}
.tagsinput .tag .tag-remove:after,
.tagsinput .tag .tag-remove:before {
background: #ccc;
position: absolute;
display: block;
width: 10px;
height: 2px;
top: 14px;
left: 10px;
content: ''
}
.tagsinput .tag .tag-remove:before {
-webkit-transform: rotateZ(45deg);
transform: rotateZ(45deg)
}
.tagsinput .tag .tag-remove:after {
-webkit-transform: rotateZ(-45deg);
transform: rotateZ(-45deg)
}
.tagsinput div {
-webkit-box-flex: 1;
-webkit-flex-grow: 1;
-ms-flex-positive: 1;
flex-grow: 1
}
.tagsinput div input {
display: block;
width: 100%;
padding: 5px;
border: 0;
margin: 0 5px 5px 0
}
.tagsinput div input.error {
color: #ccc
}
.tagsinput div input::-ms-clear {
display: none
}
.tagsinput div input::-webkit-input-placeholder {
color: #ccc;
opacity: 1
}
.tagsinput div input:-moz-placeholder {
color: #ccc;
opacity: 1
}
.tagsinput div input::-moz-placeholder {
color: #ccc;
opacity: 1
}
.tagsinput div input:-ms-input-placeholder {
color: #ccc;
opacity: 1
}

View file

@ -1,79 +0,0 @@
.token-autocomplete-container {
display: block;
flex-wrap: wrap;
border: 1px solid #E6E6E6;
background-color: #FFFFFF;
}
.token-autocomplete-container, .token-autocomplete-container * {
box-sizing: border-box;
}
.token-autocomplete-container .token-autocomplete-input {
display: block;
line-height: 32px;
margin: 4px 2px;
padding: 0px 8px;
}
.token-autocomplete-container .token-autocomplete-input:empty::before {
content: attr(data-placeholder);
color: rgb(0,0,0,0.6);
}
.token-autocomplete-container .token-autocomplete-token {
width: 100%;
display: block;
padding: 2px 8px;
background: #ccc;
}
.token-autocomplete-container .token-autocomplete-token:hover {
background-color: #ddd;
}
.token-autocomplete-container .token-autocomplete-token .token-autocomplete-token-delete {
cursor: pointer;
font-size: 24px;
line-height: 16px;
margin-left: 4px;
pointer-events: auto;
border-radius: 50%;
height: 24px;
width: 24px;
display: inline-block;
text-align: center;
}
.token-autocomplete-container .token-autocomplete-token .token-autocomplete-token-delete:hover {
background-color: #e55858;
}
.token-autocomplete-container .token-autocomplete-suggestions {
display: none;
width: 100%;
list-style-type: none;
padding: 0px;
margin: 0px;
}
.token-autocomplete-container .token-autocomplete-suggestions li {
width: 100%;
padding: 8px;
cursor: pointer;
}
.token-autocomplete-container .token-autocomplete-suggestions li.token-autocomplete-suggestion-active {
color: #747474;
background-color: #fdfdfd;
}
.token-autocomplete-container .token-autocomplete-suggestions li.token-autocomplete-suggestion-highlighted {
background-color: #95caec;
}
.token-autocomplete-container .token-autocomplete-suggestions li .token-autocomplete-suggestion-description {
display:block;
font-size: 0.7em;
color: #808080;
}

File diff suppressed because it is too large Load diff

Some files were not shown because too many files have changed in this diff Show more