Compare commits

..

164 commits

Author SHA1 Message Date
Diego Najar
c81b34eeca bug fix for page autosave 2021-10-23 18:15:03 +02:00
Diego Najar
a5390963fb move vendors to vendors folder, include tinymce languages, update vendors, include vendors in the helper 2021-10-23 18:07:15 +02:00
Diego Najar
f6a6660f48 Fix for #1347, display navbar for mobiles 2021-10-16 16:17:00 +02:00
Diego Najar
ef8ac0ca5c bug fix for #1334 2021-10-16 15:55:33 +02:00
Diego Najar
594ba12ea3 fix for #1356 2021-10-13 21:50:54 +02:00
Diego Najar
72d89576f1 Show date as block and inline depeding on the screen size 2021-10-13 21:41:49 +02:00
Diego Najar
1f6dd0b6e7 include page position, and fix deprecated warninings for PHP8 2021-10-13 21:20:32 +02:00
Diego Najar
76ce475cfe Merge branch 'v4.0' of github.com:bludit/bludit into v4.0 2021-10-13 21:18:58 +02:00
Diego Najar
a0681985c0 fix for #1364 2021-10-13 21:18:50 +02:00
Diego Najar
f3707235f3
Merge pull request #1371 from nogajun/v4.0
update plugin Japanese translation
2021-10-11 10:03:06 +02:00
Jun Nogata
0f319d5613 Merge branch 'v4.0' of github.com:nogajun/bludit into v4.0 2021-10-08 23:46:20 +09:00
Jun Nogata
e7d4ddb0f9 update plugin Japanese translation 2021-10-08 23:41:06 +09:00
Diego Najar
2271f6c986
Merge pull request #1368 from nogajun/v4.0
update Japanese translation
2021-10-08 14:55:33 +02:00
Jun Nogata
2f1cfdfd10 update Japanese translation 2021-10-08 17:39:11 +09:00
Diego Najar
fc4d8ed7b2 include words for relativetime 2021-10-06 18:15:02 +02:00
Diego Najar
696d6ca828
Merge pull request #1367 from clickwork-git/v4.0
V4.0: Modifications and additions for translations
2021-10-06 18:14:19 +02:00
Edi
aba4ff730d
Additional terms 2021-10-06 18:03:48 +02:00
Edi
1fac66d574
Additional terms 2021-10-06 18:03:11 +02:00
Edi
e46cd13b53
Update de_CH.json 2021-10-06 18:02:40 +02:00
Edi
ca97f18cc6
Additional terms 2021-10-06 18:02:18 +02:00
Edi
5251a365d4
Additions 2021-10-06 17:57:34 +02:00
Edi
8ccb4db5d0
Fix update date 2021-10-06 17:56:29 +02:00
Edi
0d18390c2a
Update de_DE.json 2021-10-06 17:55:30 +02:00
Edi
1528d8f011
Additions 2021-10-06 17:52:48 +02:00
Edi
ada81366c1
Additions for translations 2021-10-06 17:51:43 +02:00
Diego Najar
ea4942b360 change options for filemanager 2021-10-06 09:02:54 +02:00
Diego Najar
b1be4f79cf
Merge pull request #1365 from clickwork-git/v4.0
V4.0: Additions and modifications for translations
2021-10-06 09:02:04 +02:00
Edi
d2ed09e630
Create de_AT.php 2021-10-05 22:40:13 +02:00
Edi
60b35daeb3
Create de_DE.php 2021-10-05 22:39:20 +02:00
Edi
243b5c63b6
Create de_CH.php 2021-10-05 22:38:15 +02:00
Edi
e14e2eae02
Merge branch 'bludit:v4.0' into v4.0 2021-10-05 22:30:32 +02:00
Diego Najar
f6ccb90f8c file manager options for files 2021-10-05 21:48:30 +02:00
Edi
3232adca17
Create de_AT.json 2021-10-05 21:43:43 +02:00
Edi
def9001a83
Create de_DE.json 2021-10-05 21:43:25 +02:00
Edi
696c4c8a2a
Create de_CH.json 2021-10-05 21:43:05 +02:00
Edi
ddad09e865
Additional phrases 2021-10-05 21:42:24 +02:00
Edi
e5d3eb0d3b
Additional phrases 2021-10-05 21:41:20 +02:00
Diego Najar
7393081b9d alert over modal 2021-10-05 21:40:15 +02:00
Edi
7717195be1
Merge branch 'bludit:v4.0' into v4.0 2021-10-05 21:25:21 +02:00
Diego Najar
6b807179d5 include pdf files 2021-10-05 21:22:31 +02:00
Edi
c60df51e4c
Create de_AT.json 2021-10-05 19:41:18 +02:00
Edi
1db2196ad3
Create de_DE.json 2021-10-05 19:40:56 +02:00
Edi
90e6c914eb
Create de_CH.json 2021-10-05 19:40:33 +02:00
Edi
87c2d807a4
Additional phrase 2021-10-05 19:39:42 +02:00
Edi
299c7f528a
Update de_DE.json 2021-10-05 16:17:19 +02:00
Edi
244e3dd522
Update de_CH.json 2021-10-05 16:16:34 +02:00
Edi
e692fe28ab
Update de_AT.json 2021-10-05 16:15:47 +02:00
Edi
e53c35b52c
Update de_AT.json 2021-10-05 16:15:23 +02:00
Edi
6967bb13cd
Modification for translation 2021-10-05 16:11:43 +02:00
Edi
78fcb9d798
Update de_AT.json 2021-10-05 11:19:59 +02:00
Edi
69bbc0474b
Fix native 2021-10-05 11:18:59 +02:00
Edi
4dccd0ce79
Fix locale 2021-10-05 11:18:04 +02:00
Diego Najar
e37e972c59
Merge pull request #1361 from clickwork-git/v4.0
V4.0: Modifications for translations file-manager.php, updates of translationsV4.0
2021-10-04 19:22:45 +02:00
Diego Najar
948ca56000
Merge pull request #1362 from marekrost/v4.0-bootstrap-pagination
V4.0 bootstrap pagination
2021-10-04 19:21:16 +02:00
Marek Rost
79dd46eb1e renamed bootstrap_html -> boostrapHTML function in paginator helper class 2021-10-04 13:54:20 +02:00
Marek Rost
3dacf7378d Improvements to bootstrap pagination function. Maintaining full compatibility. Added missing classes to certain elements like page number links, slightly simplified the conditional logic for first+last page button display. Added first and last button text override parameters and option to not show them with default to invisible. Made the bootstrap_html actually use these parameters when configured. 2021-10-04 13:53:01 +02:00
Edi
59c48bb8b3
Additions and modifications 2021-10-04 13:27:34 +02:00
Edi
72fb7fb03b
Additions and modifications 2021-10-04 13:26:54 +02:00
Edi
1adf73d053
Addditions and modifications 2021-10-04 13:22:47 +02:00
Edi
e7814d84ca
Update de_AT.json 2021-09-27 17:34:40 +02:00
Edi
d733aa160c
Update de_DE.json 2021-09-27 17:33:41 +02:00
Edi
2863ba49d8
Update de_CH.json 2021-09-27 17:31:42 +02:00
Edi
e0829ca73a
Modifications for translations 2021-09-27 17:27:01 +02:00
Edi
17526d484f
Create de_AT.json 2021-09-27 15:30:33 +02:00
Edi
fb997bb451
Create de_DE.json 2021-09-27 15:30:13 +02:00
Edi
94fd054072
Create de_CH.json 2021-09-27 15:29:52 +02:00
Edi
64a7192974
Update editor.php 2021-09-26 22:59:50 +02:00
Edi
eb79fec300
Update de_AT.json 2021-09-26 22:58:07 +02:00
Edi
329144ac0e
Update de_DE.json 2021-09-26 22:56:29 +02:00
Edi
d98c8ed4b1
Update de_CH.json 2021-09-26 22:55:30 +02:00
Diego Najar
f529cd26cb rename function to check if the plugin is enabled 2021-09-25 20:29:31 +02:00
Diego Najar
ccb9123ac0 include textarea when call the api 2021-09-25 20:29:09 +02:00
Diego Najar
f03109844a refactor plugins for bludit v4.0 2021-09-25 20:28:17 +02:00
Diego Najar
e584226387 include words to the translations 2021-09-24 19:54:36 +02:00
Diego Najar
9af6f81b2f
Merge pull request #1351 from clickwork-git/v4.0
Additional phrases
2021-09-24 11:30:09 +02:00
Edi
b0d0b180e5
Update de_CH.json 2021-09-23 22:52:03 +02:00
Diego Najar
51422e9a60 remove examples pages 2021-09-23 18:57:18 +02:00
Diego Najar
4357710bfe remove directory creation 2021-09-23 18:56:57 +02:00
Diego Najar
452e621cb2 bug fixes in tags 2021-09-23 18:51:07 +02:00
Diego Najar
09fbbbb599 improve Bludit installer 2021-09-23 18:50:43 +02:00
Diego Najar
67e66e3662 include new logo to Popeye theme 2021-09-23 18:50:26 +02:00
Diego Najar
65a9a27ac7 remove examples pages 2021-09-23 18:50:02 +02:00
Diego Najar
3904fd8683 new logo 2021-09-23 18:48:23 +02:00
Diego Najar
272cc5bad0 examples pages per language 2021-09-23 18:48:11 +02:00
Diego Najar
bfaedbb6df
Merge pull request #1350 from clickwork-git/v4.0
V4.0: Modifications and additions for translations
2021-09-21 20:05:31 +02:00
Edi
7b2dd3de73
Additional terms 2021-09-21 17:48:38 +02:00
Edi
b0b442c0a0
Additional terms 2021-09-21 17:47:15 +02:00
Edi
f731368922
Update about.php 2021-09-21 14:04:12 +02:00
Diego Najar
667b3e3a65
Merge pull request #1344 from clickwork-git/v4.0
V4.0 plugin Welcome
2021-09-16 09:23:13 +02:00
Edi
4fdec3c919
Update en.json 2021-09-14 23:22:15 +02:00
Edi
2d93a349d6
Create de_AT.json 2021-09-14 17:42:43 +02:00
Edi
3f9b3c0c54
Create de_DE.json 2021-09-14 17:42:21 +02:00
Edi
48ea498b95
Create de_CH.json 2021-09-14 17:41:59 +02:00
Edi
ed1bf235ad
Addition 2021-09-14 17:40:42 +02:00
Edi
fc001194c6
Modification for translations
Modification of the code from line 23 to add translation for "Welcome".
2021-09-14 17:39:51 +02:00
Diego Najar
5ccd35544b Merge branch 'v4.0' of github.com:bludit/bludit into v4.0 2021-09-14 17:38:26 +02:00
Diego Najar
4ebdd50f1f compatibility with php7 2021-09-14 17:38:19 +02:00
Diego Najar
36d802e798
Merge pull request #1343 from clickwork-git/v4.0
V4.0 plugin Latest pages
2021-09-14 16:29:44 +02:00
Edi
1f99d43bb8
Update en.json 2021-09-14 11:32:06 +02:00
Edi
dfb534c817
Create de_AT.json 2021-09-14 11:31:30 +02:00
Edi
0bee7d8541
Create de_DE.json 2021-09-14 11:31:06 +02:00
Edi
2e9c753667
Create de_CH.json 2021-09-14 11:30:30 +02:00
Edi
19d1b7a694
Update plugin.php 2021-09-14 11:22:59 +02:00
Edi
bd5f724503
Missing translations 2021-09-13 20:07:13 +02:00
Diego Najar
8439abbe97 add comments, and styling 2021-09-12 22:06:29 +02:00
Diego Najar
f9ec67ad27 include unlisted pages 2021-09-12 22:06:01 +02:00
Diego Najar
1045d83004 vscode configuration 2021-09-12 20:57:59 +02:00
Diego Najar
6a0f32900b Bug fixes on UI 2021-09-12 20:57:44 +02:00
Diego Najar
2eac988843 Add tag Dashboard 2021-09-12 20:57:18 +02:00
Diego Najar
cf4e0cc755 bug fixes 2021-09-05 16:18:01 +02:00
Diego Najar
7a96a8f1af update select2 and move to vendors dir 2021-09-05 16:17:23 +02:00
Diego Najar
9c5aed2e9b Bootstrap 5.10 2021-08-25 23:18:10 +02:00
Diego Najar
2b9b89b166 Small issues with CSS 2021-08-25 23:17:46 +02:00
Diego Najar
41131960be plugin for the dashboard, list 5 latest published pages 2021-08-25 23:17:20 +02:00
Diego Najar
336ca49397 update easymde 2021-06-14 23:56:04 +02:00
Diego Najar
6d0d250075 include phpstan 2021-06-14 23:55:00 +02:00
Diego Najar
2982a94f5f return a proper error alert, bugfix for bludit installation inside a directory 2021-06-10 20:38:20 +02:00
Diego Najar
a98e5e4582 Bugfix for EOF 2021-06-08 23:34:49 +02:00
Diego Najar
1edd3eec53 comments standars 2021-06-07 20:18:53 +02:00
Diego Najar
ed1edb902f UI improvements, comments refactor for lint 2021-06-07 19:52:26 +02:00
Diego Najar
ad0c024362 bugfix for #1321 2021-06-07 19:51:01 +02:00
Diego Najar
3f39ec94e9 add remove page 2021-06-07 19:50:04 +02:00
Diego Najar
a27cefec3f add remove page 2021-06-07 19:49:38 +02:00
Diego Najar
20fe525375 remove renew API token every time the user login 2021-06-07 19:48:52 +02:00
Diego Najar
272e5d3b5b Include image in RSS, related PR https://github.com/bludit/bludit/pull/1326 2021-06-05 21:09:43 +02:00
Diego Najar
d2f7c79cf6 Update Simple Image Class to 3.6.3 2021-06-05 21:07:31 +02:00
Diego Najar
42952a5433 improve https detection 2021-06-05 19:59:20 +02:00
Diego Najar
84baa2c16b change in metadata for Bludit v4.0, plugin for popeye theme updated, refactor 2021-06-02 22:48:30 +02:00
Diego Najar
1c49bef304 Darkmode for Admin panel and Website, Bootstrap 5.0.1, refactor for Bludit v4 2021-05-17 20:04:59 +02:00
Diego Najar
fca4deb8c9 Add Google Fonts and Dark Mode 2021-05-11 17:56:30 +02:00
Diego Najar
2de6b6a3b1 PopEye theme updates 2021-04-20 23:21:44 +02:00
Diego Najar
ee0adae2d9 Merge branch 'v4.0' of github.com:bludit/bludit into v4.0 2021-04-20 17:32:52 +02:00
Diego Najar
a69aa3edb9 Default logo 2021-04-20 17:32:41 +02:00
dignajar
6688d0bd49 PopEye theme improvments 2021-04-18 17:50:04 +02:00
dignajar
930dd9a01b Enable API when the user login, starting new default theme for Bludit v4 Popeye 2021-04-13 20:28:51 +02:00
Diego Najar
1c5992477f refactor to remove Theme helper 2021-03-19 16:48:04 -03:00
Diego Najar
ae1c99c813 refactor and delete old files 2021-03-19 16:42:17 -03:00
Diego Najar
b455bbb055 doc for bludit v4 2021-03-19 16:06:17 -03:00
Diego Najar
93077d2647 add discord for social media 2021-03-19 16:01:38 -03:00
Diego Najar
adb84d792d plugin position for dashboard, new plugins for welcome message and visits 2021-03-19 15:54:09 -03:00
Diego Najar
fc12ebadc8 Grettings message for Dashboard 2021-03-09 12:29:13 -03:00
Diego Najar
7358a7e0e4 change function name 2021-03-09 12:28:52 -03:00
Diego Najar
a55ab5d2ec Refactor for Site logo 2021-03-09 11:55:08 -03:00
Diego Najar
3570734110 remove maps 2021-03-09 11:54:22 -03:00
Diego Najar
55a7a62780 Update EasyMDE for Bludit v4 2021-03-09 11:53:36 -03:00
Diego Najar
f11eed0a96 TinyMCE 5.7 and plugin updated 2021-03-04 14:50:28 -03:00
Diego Najar
5b64d3b2fa Move vendors to a proper folder, update Bootstrap, Icons and jQuery 2021-03-04 12:27:02 -03:00
Diego Najar
9fb07d918a Minor changes in visits stats and fix notifications in dahsboard 2021-03-04 12:00:54 -03:00
Diego Najar
3c97a31b1b Delete Simple Stats and create Visits stats 2021-03-03 13:31:32 -03:00
dignajar
231a500a52 add some documentation to the readme, now all plugins print the description in the settings form its possible disable as well, clean up css, and refactor Categories plugin 2021-02-07 22:03:53 +01:00
dignajar
f2b8955e96 Add custom template for JS for the views 2021-02-07 18:22:20 +01:00
dignajar
0f71046b92 Deactivate plugin via API 2021-02-07 18:13:25 +01:00
dignajar
cd0446e080 Settings trough API, change user password via API, refactor code 2021-02-07 17:19:24 +01:00
dignajar
71f1742c45 Change user password, Disable user, improve comments on functions 2021-01-26 22:31:12 +01:00
dignajar
3b37cb2905 Refactor main clasess, add new library for manage images 2021-01-23 22:19:47 +01:00
dignajar
993a4f92d6 API create/edit/delete category, UI for manage categories, UI for manage users still in progress, improvments in dbList class, warn the user when didn't save the progress in the editor 2021-01-16 13:03:16 +01:00
dignajar
38bd6dd551 Create user via API, create category via API, Bootstrap icons v1.3, improve in creation content 2021-01-12 21:46:42 +01:00
dignajar
ff2a51fae8 New approach when the page is created, remove UUID, remove symlinks for upload images, modal for filemanager, and more 2021-01-01 23:13:01 +01:00
dignajar
39de732f3b port to Bootstrap v5 modals and change icons 2020-12-29 18:53:06 +01:00
dignajar
1e143270aa missing name field for floating labels 2020-12-29 14:57:20 +01:00
dignajar
70cefda593 Added floating labels and changed in login form 2020-12-29 14:55:55 +01:00
dignajar
5469ce51b1 bootstrap v5, bootstrap icons, cleaning css, cleaning classes 2020-12-29 14:39:47 +01:00
dignajar
e84df311c2 a few updates for the admin panel 2020-11-30 22:00:54 +01:00
dignajar
226750af09 init branch for Bludit v4 2020-11-01 11:55:34 +01:00
474 changed files with 17417 additions and 19613 deletions

View file

@ -1,5 +1,3 @@
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.
@ -9,10 +7,13 @@ Complete here.
### Bludit version
Complete here.
### Hosting or Webserver name
Complete here.
### PHP version
If you do not know remove this line.
If you do not know delete this line.
### PHP logs
If you do not know remove this line.
If you do not know delete this line.
The default settings of the PHP Error Log file varies from OS to OS. The location of the error log file itself can be set manually in the php.ini file. On a Windows server, in IIS, it may be something like `error_log = C:\log_files\php_errors.log` in Linux it may be a value of `/var/log/php_errors.log`.
The default settings for the PHP error log file vary from operating system to system. The location of the error log file itself can be set manually in the php.ini file. On a Windows server, in IIS, it may be something like `error_log = C:\log_files\php_errors.log` in Linux it may be a value of `/var/log/php_errors.log`.

3
.gitignore vendored
View file

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

View file

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

5
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,5 @@
{
"editor.detectIndentation": false,
"editor.insertSpaces": true,
"editor.tabSize": 4
}

View file

@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2015-2023 Diego Najar
Copyright (c) 2015-2021 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,52 +1,43 @@
# [Bludit](https://www.bludit.com/)
[Bludit](https://www.bludit.com/)
================================
Bludit the Simple, Fast, and Flexible CMS.
Dear developers
-------
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.
## Frameworks and libraries included in Bludit v4
Bludit will include the following frameworks, please use them with they native functions.
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.
Frontend:
- Bootstrap v5.
- Boostrap icons.
- jQuery, you can use vanilla Javascript but for events in the views please use jQuery.
## Resources
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
- [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)
## 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) {
...
}
```
## Requirements
Documentation for Bludit v4
-------
There is a new branch for the Documentation in english for Bludit v4.
- 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.
https://github.com/bludit/documentation-english/tree/v4.0
## 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).
PHPStan
-------
https://phpstan.org/
```
docker run --rm -v $(pwd):/app ghcr.io/phpstan/phpstan:0.12.99 analyse -c /app/phpstan.neon /app
```

View file

View file

@ -6,6 +6,7 @@ class dbJSON {
public $dbBackup;
public $file;
public $firstLine;
protected $dbFields; // These fields are defined in the extended classes
// $file, the JSON file.
// $firstLine, TRUE if you want to remove the first line, FALSE otherwise
@ -61,7 +62,10 @@ class dbJSON {
return $this->dbFields[$field];
}
// Save the JSON file
/* Save the JSON file
@return boolean Returns TRUE if the file was saved successfully, FALSE otherwise
*/
public function save()
{
$data = '';
@ -79,7 +83,7 @@ class dbJSON {
if (file_put_contents($this->file, $data, LOCK_EX)) {
return true;
} else {
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to save the database file.', LOG_TYPE_ERROR);
Log::set(__METHOD__.LOG_SEP.'An error occurred while trying to save the database.', LOG_TYPE_ERROR);
return false;
}
}
@ -98,7 +102,7 @@ class dbJSON {
{
// NULL is returned if the json cannot be decoded
$decode = json_decode($data, true);
if ($decode===NULL) {
if ($decode===null) {
Log::set(__METHOD__.LOG_SEP.'Error trying to read the JSON file: '.$this->file, LOG_TYPE_ERROR);
return false;
}

View file

@ -75,22 +75,35 @@ class dbList extends dbJSON
return $key;
}
// Add a new item to the dblist
// $args => 'name', 'template', 'description', list'
/* 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
*/
public function add($args)
{
$key = $this->generateKey($args['name']);
$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();
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->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])) {
@ -176,16 +189,21 @@ class dbList extends dbJSON
return false;
}
// Returns an array with a portion of the database filtered by key
// Returns array( 'key'=>'', 'name'=>'', 'template'=>'', 'description'=>'', list'=>array() )
/* 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
*/
public function getMap($key)
{
if (isset($this->db[$key])) {
$tmp = $this->db[$key];
$tmp['key'] = $key;
return $tmp;
if (!$this->exists($key)) {
Log::set(__METHOD__.LOG_SEP.'The item doesn\'t exist. Key: '.$key);
return false;
}
return false;
$tmp = $this->db[$key];
$tmp['key'] = $key;
return $tmp;
}
}

View file

@ -1,7 +1,6 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
class Plugin
{
class Plugin {
// (string) directory name, just the name
// Ex: sitemap
@ -56,10 +55,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);
@ -80,44 +79,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];
}
@ -134,7 +133,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) {
@ -171,6 +170,11 @@ class Plugin
return $this->getMetadata('email');
}
public function type()
{
return $this->getMetadata('type');
}
public function website()
{
return $this->getMetadata('website');
@ -205,9 +209,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;
}
}
@ -220,7 +224,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;
@ -231,11 +235,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;
@ -248,7 +252,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
@ -258,16 +262,19 @@ class Plugin
return true;
}
// Returns TRUE if the plugin is installed
// This function just check if the database of the plugin is created
public function installed()
/**
* Returns True if the plugin is installed
*
* @return boolean
*/
public function installed(): bool
{
return file_exists($this->filenameDb);
}
public function workspace()
{
return PATH_WORKSPACES . $this->directoryName . DS;
return PATH_WORKSPACES.$this->directoryName.DS;
}
public function init()
@ -285,14 +292,11 @@ 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;
}
@ -300,9 +304,18 @@ class Plugin
return $this->save();
}
public function type()
public function configure($args)
{
return $this->getMetadata('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();
}
public function setField($field, $value)
@ -318,7 +331,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;
@ -327,10 +340,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;
}
@ -339,7 +352,7 @@ class Plugin
if ($fixed) {
return false;
}
if ($afterURI[0] != '/') {
if ($afterURI[0]!='/') {
return false;
}
}
@ -348,7 +361,8 @@ class Plugin
return $afterURI;
}
Log::set(__METHOD__ . LOG_SEP . 'Webhook requested.');
Log::set(__METHOD__.LOG_SEP.'Webhook requested.');
return true;
}
}
}

View file

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

View file

@ -1,7 +1,7 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================
// Check role
// Authorization
// ============================================================================
checkRole(array('admin'));
@ -11,22 +11,8 @@ checkRole(array('admin'));
// ============================================================================
// ============================================================================
// Main before POST
// Main
// ============================================================================
// ============================================================================
// 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');
// HTML <title>
$layout['title'] = $L->g('New category') . ' - ' . $layout['title'];

View file

@ -1,7 +1,7 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================
// Check role
// Authorization
// ============================================================================
checkRole(array('admin'));
@ -11,22 +11,8 @@ checkRole(array('admin'));
// ============================================================================
// ============================================================================
// Main before POST
// Main
// ============================================================================
// ============================================================================
// 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');
// HTML <title>
$layout['title'] = $L->g('New user') . ' - ' . $layout['title'];

View file

@ -1,40 +0,0 @@
<?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.');
// ============================================================================
// Check role
// Authorization
// ============================================================================
checkRole(array('admin'));
@ -11,16 +11,8 @@ checkRole(array('admin'));
// ============================================================================
// ============================================================================
// Main before POST
// Main
// ============================================================================
// ============================================================================
// POST Method
// ============================================================================
// ============================================================================
// Main after POST
// ============================================================================
// Title of the page
$layout['title'] .= ' - '.$L->g('Categories');
// HTML <title>
$layout['title'] = $L->g('Categories') . ' - ' . $layout['title'];

View file

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

View file

@ -1,66 +1,16 @@
<?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 before POST
// Main
// ============================================================================
// ============================================================================
// POST Method
// ============================================================================
// ============================================================================
// Main after POST
// ============================================================================
// Try update Bludit
updateBludit();
// Title of the page
$layout['title'] .= ' - '.$L->g('Dashboard');
// HTML <title>
$layout['title'] = $L->g('Dashboard') . ' - ' . $layout['title'];

View file

@ -1,7 +1,7 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================
// Check role
// Authorization
// ============================================================================
checkRole(array('admin'));
@ -11,26 +11,9 @@ checkRole(array('admin'));
// ============================================================================
// ============================================================================
// Main before POST
// Main
// ============================================================================
// ============================================================================
// 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)) {
@ -40,5 +23,5 @@ if (!$categories->exists($categoryKey)) {
$categoryMap = $categories->getMap($categoryKey);
// Title of the page
$layout['title'] .= ' - '.$L->g('Edit Category').' [ '.$categoryMap['name'] . ' ] ';
// HTML <title>
$layout['title'] = $L->g('Edit Category') . ' [ ' . $categoryMap['name'] . ' ] ' . ' - ' . $layout['title'];

View file

@ -1,86 +0,0 @@
<?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,46 +1,15 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================
// Authorization
// ============================================================================
// ============================================================================
// Functions
// ============================================================================
// ============================================================================
// 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
// Main
// ============================================================================
$username = $layout['parameters'];
@ -56,5 +25,5 @@ try {
Redirect::page('users');
}
// Title of the page
$layout['title'] = $L->g('Edit user').' - '.$layout['title'];
// HTML <title>
$layout['title'] = $L->g('Edit user') . ' - ' . $layout['title'];

View file

@ -0,0 +1,29 @@
<?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

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

View file

@ -1,7 +1,7 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================
// Check role
// Authorization
// ============================================================================
checkRole(array('admin'));
@ -11,16 +11,23 @@ checkRole(array('admin'));
// ============================================================================
// ============================================================================
// Main before POST
// Main
// ============================================================================
// ============================================================================
// POST Method
// ============================================================================
// ============================================================================
// Main after POST
// ============================================================================
$plugin = false;
$pluginClassName = $layout['parameters'];
deactivatePlugin($pluginClassName);
Redirect::page('plugins');
// Check if the plugin is installed/activated
if (isPluginActive($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'];

View file

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

View file

@ -1,7 +1,7 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================
// Check role
// Authorization
// ============================================================================
checkRole(array('admin'));
@ -11,21 +11,8 @@ checkRole(array('admin'));
// ============================================================================
// ============================================================================
// Main after POST
// Main
// ============================================================================
// ============================================================================
// 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');
// HTML <title>
$layout['title'] = $L->g('Settings') . ' - ' . $layout['title'];

View file

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

View file

@ -1,51 +0,0 @@
<?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.');
// ============================================================================
// Check role
// Authorization
// ============================================================================
checkRole(array('admin'));
@ -11,21 +11,8 @@ checkRole(array('admin'));
// ============================================================================
// ============================================================================
// Main after POST
// Main
// ============================================================================
// ============================================================================
// POST Method
// ============================================================================
if( $_SERVER['REQUEST_METHOD'] == 'POST' )
{
$site->set($_POST);
}
// ============================================================================
// Main after POST
// ============================================================================
// Title of the page
$layout['title'] .= ' - '.$L->g('Users');
// HTML <title>
$layout['title'] = $L->g('Users') . ' - ' . $layout['title'];

View file

@ -0,0 +1,46 @@
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

@ -0,0 +1,12 @@
/* 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

@ -0,0 +1,142 @@
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

@ -0,0 +1,35 @@
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 a {
text-decoration: none;
}

View file

@ -1,58 +0,0 @@
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

@ -1,367 +0,0 @@
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

@ -1,17 +0,0 @@
<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

@ -0,0 +1,31 @@
<div aria-live="polite" aria-atomic="true" class="position-relative z-index-master">
<div class="toast-container position-absolute start-50 translate-middle-x mt-3" style="z-index:1100;">
<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

@ -1,262 +0,0 @@
<?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

@ -1,11 +1,14 @@
<nav class="navbar navbar-expand-lg navbar-dark bg-dark text-uppercase d-block d-lg-none">
<div class="container">
<span class="navbar-brand">
<?php echo (defined('BLUDIT_PRO'))?'BLUDIT PRO':'BLUDIT' ?></span>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false"
aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<img src="<?php echo DOMAIN_BASE ?>bl-kernel/img/logo.svg" alt="" width="24" height="24" class="d-inline-block align-top">
<?php echo (defined('BLUDIT_PRO'))?'BLUDIT PRO':'BLUDIT' ?>
</span>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item">
@ -17,7 +20,7 @@
<?php $L->p('Website') ?></a>
</li>
<li class="nav-item">
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'new-content' ?>">
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'editor' ?>">
<?php $L->p('New content') ?></a>
</li>
<li class="nav-item">
@ -25,10 +28,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 +60,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,27 +1,31 @@
<!-- Use .flex-column to set a vertical direction -->
<ul class="nav flex-column pt-4">
<ul class="nav flex-column">
<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 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>
<li class="nav-item">
<a class="nav-link" target="_blank" href="<?php echo HTML_PATH_ROOT ?>"><span class="fa fa-home"></span><?php $L->p('Website') ?></a>
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'dashboard' ?>">
<i class="bi bi-kanban"></i>
<?php $L->p('Dashboard') ?>
</a>
</li>
<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 class="nav-item">
<a class="nav-link" href="<?php echo DOMAIN_BASE ?>">
<i class="bi bi-house"></i>
<?php $L->p('Website') ?>
</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="fa fa-archive"></span><?php $L->p('Content') ?></a>
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'content' ?>"><span class="bi bi-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="fa fa-user"></span><?php $L->p('Profile') ?></a>
<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>
</li>
<?php endif; ?>
@ -31,30 +35,38 @@
<h4><?php $L->p('Manage') ?></h4>
</li>
<li class="nav-item">
<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>
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'content' ?>">
<i class="bi bi-folder"></i>
<?php $L->p('Content') ?>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'users' ?>"><span class="fa fa-users"></span><?php $L->p('Users') ?></a>
<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>
</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="fa fa-gear"></span><?php $L->p('General') ?></a>
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'settings' ?>"><span class="bi bi-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="fa fa-puzzle-piece"></span><?php $L->p('Plugins') ?></a>
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'plugins' ?>"><span class="bi bi-node-plus"></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="fa fa-desktop"></span><?php $L->p('Themes') ?></a>
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'themes' ?>"><span class="bi bi-display"></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="fa fa-info"></span><?php $L->p('About') ?></a>
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'about' ?>"><span class="bi bi-info-circle"></span><?php $L->p('About') ?></a>
</li>
<?php endif; ?>
@ -75,6 +87,6 @@
<?php endif; ?>
<li class="nav-item mt-5">
<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>
<a class="nav-link" href="<?php echo HTML_PATH_ADMIN_ROOT.'logout' ?>"><span class="bi bi-door-closed"></span><?php $L->p('Logout') ?></a>
</li>
</ul>

View file

@ -1,98 +1,121 @@
<!DOCTYPE html>
<html>
<html class="h-100">
<head>
<title><?php echo $layout['title'] ?></title>
<meta charset="<?php echo CHARSET ?>">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="viewport" content="width=device-width, initial-scale=1">
<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 Theme::cssBootstrap();
echo Theme::cssLineAwesome();
echo Theme::css(array(
'bludit.css',
'bludit.bootstrap.css'
echo HTML::cssBootstrap();
echo HTML::cssBootstrapIcons();
echo HTML::cssSelect2();
echo HTML::cssDatetimepicker();
echo HTML::cssJqueryUI();
echo HTML::css(array(
'01-bludit.css',
'02-bootstrap-hacks.css'
), DOMAIN_ADMIN_THEME_CSS);
echo Theme::css(array(
'jquery.datetimepicker.min.css',
'select2.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 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);
echo HTML::jquery();
echo HTML::jsBootstrap();
echo HTML::jsSortable();
echo HTML::bootbox();
echo HTML::jsSelect2();
echo HTML::jsDatetimepicker();
echo HTML::jsJqueryUI();
echo HTML::js(array(
'functions.js',
'api.js'
), DOMAIN_CORE_JS);
?>
<!-- Plugins -->
<?php Theme::plugins('adminHead') ?>
<!-- Execute plugins for the admin area inside the HTML <head> tag -->
<?php execPluginsByHook('adminHead') ?>
</head>
<body class="h-100">
<!-- Plugins -->
<?php Theme::plugins('adminBodyBegin') ?>
<!-- Execute plugins for the admin area inside the HTML <body> at the begginig -->
<?php execPluginsByHook('adminBodyBegin') ?>
<!-- Javascript dynamic generated by PHP -->
<?php
echo '<script charset="utf-8">'.PHP_EOL;
include(PATH_CORE_JS.'variables.php');
echo '</script>'.PHP_EOL;
<!-- Javascript global variable generated by PHP -->
<?php include(PATH_CORE_JS . 'variables.php') ?>
echo '<script charset="utf-8">'.PHP_EOL;
include(PATH_CORE_JS.'bludit-ajax.php');
echo '</script>'.PHP_EOL;
?>
<div class="container-fluid p-0 m-0 d-flex flex-column h-100">
<!-- Overlay background -->
<div id="jsshadow"></div>
<!-- Alerts -->
<?php include('html/alerts.php') ?>
<!-- End Alerts -->
<!-- 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'); ?>
<!-- Top Navbar -->
<div class="container-fluid p-0 bg-dark d-none d-lg-block">
<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="24" height="24" class="d-inline-block align-top">
<?php echo (defined('BLUDIT_PRO'))?'BLUDIT PRO':'BLUDIT' ?>
</a>
</nav>
</div>
</div>
</div>
<!-- End Top Navbar -->
<!-- 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>';
}
?>
<!-- Navbar, only for small devices -->
<?php include('html/navbar.php') ?>
<!-- End 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>
</div>
<!-- End Main -->
</div>
</div>
<!-- Plugins -->
<?php Theme::plugins('adminBodyEnd') ?>
<!-- Execute plugins for the admin area inside the HTML <body> at the end -->
<?php execPluginsByHook('adminBodyEnd') ?>
</body>
</html>
</html>

View file

@ -1,403 +1,8 @@
<?php
<?php defined('BLUDIT') or die('Bludit CMS.');
class Bootstrap
{
// Init scripts for the theme
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;
}
// This theme use the API to work
if (!isPluginActive('pluginAPI')) {
activatePlugin('pluginAPI');
}

View file

@ -1,57 +1,63 @@
<!DOCTYPE html>
<html>
<html class="h-100">
<head>
<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">
<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">
<!-- 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 Theme::cssBootstrap();
echo Theme::css(array(
'bludit.css',
'bludit.bootstrap.css'
), DOMAIN_ADMIN_THEME_CSS);
?>
<!-- CSS -->
<?php
echo HTML::cssBootstrap();
echo HTML::cssBootstrapIcons();
echo HTML::css(array(
'01-bludit.css',
'02-bootstrap-hacks.css'
), DOMAIN_ADMIN_THEME_CSS);
<!-- Javascript -->
<?php
echo Theme::jquery();
echo Theme::jsBootstrap();
?>
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);
}
?>
<!-- Plugins -->
<?php Theme::plugins('loginHead') ?>
<!-- Javascript -->
<?php
echo HTML::jquery();
echo HTML::jsBootstrap();
?>
<!-- Execute plugins for the login page inside the HTML <head> tag -->
<?php execPluginsByHook('loginHead') ?>
</head>
<body class="h-100 bg-light">
<body class="login">
<!-- Execute plugins for the login page inside the HTML <body> at the begginig -->
<?php execPluginsByHook('loginBodyBegin') ?>
<!-- Plugins -->
<?php Theme::plugins('loginBodyBegin') ?>
<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>
<!-- 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') ?>
<!-- Execute plugins for the login page inside the HTML <body> at the end -->
<?php execPluginsByHook('loginBodyEnd') ?>
</body>
</html>
</html>

View file

@ -1,3 +1,29 @@
<?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'));
@ -8,37 +34,37 @@ echo '
';
echo '<tr>';
echo '<td>Bludit Edition</td>';
echo '<td class="pt-4 pb-4">Bludit Edition</td>';
if (defined('BLUDIT_PRO')) {
echo '<td>PRO - '.$L->g('Thanks for supporting Bludit').' <span class="fa fa-heart" style="color: #ffc107"></span></td>';
echo '<td class="pt-4 pb-4">PRO - '.$L->g('Thanks for supporting Bludit').' <span class="bi-heart" style="color: #ffc107"></span></td>';
} else {
echo '<td>Standard - <a target="_blank" href="https://pro.bludit.com">'.$L->g('Upgrade to Bludit PRO').'</a></td>';
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 '</tr>';
echo '<tr>';
echo '<td>Bludit Version</td>';
echo '<td>'.BLUDIT_VERSION.'</td>';
echo '<td class="pt-4 pb-4">Bludit Version</td>';
echo '<td class="pt-4 pb-4">'.BLUDIT_VERSION.'</td>';
echo '</tr>';
echo '<tr>';
echo '<td>Bludit Codename</td>';
echo '<td>'.BLUDIT_CODENAME.'</td>';
echo '<td class="pt-4 pb-4">Bludit Codename</td>';
echo '<td class="pt-4 pb-4">'.BLUDIT_CODENAME.'</td>';
echo '</tr>';
echo '<tr>';
echo '<td>Bludit Build Number</td>';
echo '<td>'.BLUDIT_BUILD.'</td>';
echo '<td class="pt-4 pb-4">Bludit '.$L->g('Build Number').'</td>';
echo '<td class="pt-4 pb-4">'.BLUDIT_BUILD.'</td>';
echo '</tr>';
echo '<tr>';
echo '<td>Disk usage</td>';
echo '<td>'.Filesystem::bytesToHumanFileSize(Filesystem::getSize(PATH_ROOT)).'</td>';
echo '<td class="pt-4 pb-4">'.$L->g('Disk usage').'</td>';
echo '<td class="pt-4 pb-4">'.Filesystem::bytesToHumanFileSize(Filesystem::getSize(PATH_ROOT)).'</td>';
echo '</tr>';
echo '<tr>';
echo '<td><a href="'.HTML_PATH_ADMIN_ROOT.'developers'.'">Bludit Developers</a></td>';
echo '<td></td>';
echo '<td class="pt-4 pb-4"><a href="'.HTML_PATH_ADMIN_ROOT.'developers'.'">Bludit '.$L->g('Developers').'</a></td>';
echo '<td class="pt-4 pb-4"></td>';
echo '</tr>';
echo '

View file

@ -0,0 +1,74 @@
<?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

@ -0,0 +1,112 @@
<?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

@ -1,59 +0,0 @@
<?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,18 +1,44 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
echo Bootstrap::pageTitle(array('title'=>$L->g('Categories'), 'icon'=>'tags'));
<script>
// ============================================================================
// Variables for the view
// ============================================================================
echo Bootstrap::link(array(
'title'=>$L->g('Add a new category'),
'href'=>HTML_PATH_ADMIN_ROOT.'new-category',
'icon'=>'plus'
));
// ============================================================================
// 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 '
<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>
@ -20,14 +46,19 @@ echo '
';
foreach ($categories->keys() as $key) {
$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>';
try {
$category = new Category($key);
echo '<tr>';
echo '<td class="pt-4 pb-4"><i class="bi bi-bookmark"></i><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
}
}
echo '
</tbody>
</table>
';
';

View file

@ -1,26 +0,0 @@
<?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,139 +1,188 @@
<?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('New content') ?></a>
</div>
</div>
<?php
echo Bootstrap::pageTitle(array('title'=>$L->g('Content'), 'icon'=>'archive'));
function table($type) {
global $url;
function table($type)
{
global $L;
global $published;
global $drafts;
global $scheduled;
global $static;
global $sticky;
global $autosave;
global $unlisted;
if ($type=='published') {
if ($type == 'published') {
$list = $published;
if (empty($list)) {
echo '<p class="mt-4 text-muted">';
echo '<p class="text-muted p-4">';
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="mt-4 text-muted">';
echo '<p class="text-muted p-4">';
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="mt-4 text-muted">';
echo '<p class="text-muted p-4">';
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="mt-4 text-muted">';
echo '<p class="text-muted p-4">';
echo $L->g('There are no static pages at this moment.');
echo '</p>';
return false;
}
} elseif ($type=='sticky') {
} elseif ($type == 'unlisted') {
$list = $unlisted;
if (empty($list)) {
echo '<p class="text-muted p-4">';
echo $L->g('There are no unlisted pages at this moment.');
echo '</p>';
return false;
}
} elseif ($type == 'sticky') {
$list = $sticky;
if (empty($list)) {
echo '<p class="mt-4 text-muted">';
echo '<p class="text-muted p-4">';
echo $L->g('There are no sticky pages at this moment.');
echo '</p>';
return false;
}
} elseif ($type=='autosave') {
$list = $autosave;
}
echo '
<table class="table mt-3">
<thead>
<tr>
<th class="border-0" scope="col">'.$L->g('Title').'</th>
';
echo '<table class="table table-striped"><tbody><tr></tr>';
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' ) {
if ((ORDER_BY == 'position') || $type == 'static') {
foreach ($list as $pageKey) {
try {
$page = new Page($pageKey);
if (!$page->isChild()) {
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>
echo '<tr id="pagekey-'.$pageKey.'">';
echo '<td class="pt-4 pb-4">
<div>
<i class="bi bi-file-text"></i><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() . '">' . $L->g('Delete') . '</span>';
}
echo '
</div>
</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 pb-4 d-none d-lg-table-cell">' . $L->get('Category') . ': ' . ($page->category() ? $page->category() : $L->get('uncategorized')) . '</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 '<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 '</tr>';
foreach ($page->children() as $child) {
//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>
echo '<tr id="pagekey-'.$pageKey.'">';
echo '<td class="ps-3 pt-4 pb-4">
<div>
<i class="bi bi-file-text"></i><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() . '">' . $L->g('Delete') . '</span>
</div>
</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 d-none d-lg-table-cell">' . $L->get('Category') . ': ' . ($child->category() ? $child->category() : $L->get('uncategorized')) . '</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 '<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 '</tr>';
//}
}
}
} catch (Exception $e) {
@ -144,32 +193,22 @@ function table($type) {
foreach ($list as $pageKey) {
try {
$page = new Page($pageKey);
echo '<tr>';
echo '<td class="pt-3">
echo '<tr id="pagekey-'.$pageKey.'">';
echo '<td class="pt-4 pb-4">
<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>
<i class="bi bi-file-text"></i>' . ($page->title() ? $page->title() : '<span class="text-muted">' . $L->g('Empty title') . '</span> ') . '
</div>
<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 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() . '">' . $L->g('Delete') . '</span>
</div>
</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 d-none d-lg-table-cell">' . $L->get('Category') . ': ' . ($page->category() ? $page->category() : $L->get('uncategorized')) . '</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 '<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 '</tr>';
} catch (Exception $e) {
@ -186,142 +225,96 @@ function table($type) {
?>
<!-- TABS -->
<ul class="nav nav-tabs" role="tablist">
<!-- Tabs -->
<ul class="nav nav-tabs ps-3" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="pages-tab" data-toggle="tab" href="#pages" role="tab"><?php $L->p('Pages') ?></a>
<a class="nav-link active" id="standard-tab" data-bs-toggle="tab" href="#standard" role="tab" aria-controls="standard" aria-selected="true"><?php $L->p('Standard') ?></a>
</li>
<li class="nav-item">
<a class="nav-link" id="static-tab" data-toggle="tab" href="#static" role="tab"><?php $L->p('Static') ?></a>
<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>
</li>
<li class="nav-item">
<a class="nav-link" id="sticky-tab" data-toggle="tab" href="#sticky" role="tab"><?php $L->p('Sticky') ?></a>
<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>
</li>
<li class="nav-item">
<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>
<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>
</li>
<li class="nav-item">
<a class="nav-link" id="draft-tab" data-toggle="tab" href="#draft" role="tab"><?php $L->p('Draft') ?></a>
<a class="nav-link" id="unlisted-tab" data-bs-toggle="tab" href="#unlisted" role="tab" aria-controls="unlisted" aria-selected="true"><?php $L->p('Unlisted') ?></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>
<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>
</li>
<?php endif; ?>
</ul>
<div class="tab-content">
<!-- TABS PAGES -->
<div class="tab-pane show active" id="pages" role="tabpanel">
<!-- End Tabs -->
<!-- Content -->
<div class="tab-content">
<!-- Tab pages -->
<div class="tab-pane show active" id="standard" role="tabpanel">
<?php table('published'); ?>
<?php if (Paginator::numberOfPages() > 1): ?>
<!-- Paginator -->
<nav class="paginator">
<ul class="pagination flex-wrap justify-content-center">
<!-- 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>
<!-- 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>
<!-- 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>
<!-- 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>
<li class="page-item"><span class="page-link text-muted"><?php echo Paginator::currentPage() ?> / <?php echo Paginator::numberOfPages() ?></span></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'); ?> <span class="align-middle fa fa-media-skip-forward"></span></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'); ?><i class="ms-2 bi bi-arrow-right-circle"></i></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 UNLISTED -->
<div class="tab-pane" id="unlisted" role="tabpanel">
<?php table('unlisted'); ?>
</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>
<!-- 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>
<!-- End Content -->

View file

@ -1,140 +1,62 @@
<div id="dashboard" class="container">
<div class="row">
<div class="col-md-7">
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
<!-- 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>
<script>
// ============================================================================
// Variables for the view
// ============================================================================
<!-- Quick Links -->
<div class="container pb-5" id="jsclippyContainer">
// ============================================================================
// Functions for the view
// ============================================================================
<div class="row">
<div class="col p-0">
<div class="form-group">
<select id="jsclippy" class="clippy" name="state"></select>
</div>
</div>
</div>
// ============================================================================
// Events for the view
// ============================================================================
$(document).ready(function() {
// No events for the view yet
});
<script>
$(document).ready(function() {
// ============================================================================
// Initialization for the view
// ============================================================================
$(document).ready(function() {
// No initialization for the view yet
});
</script>
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 id="dashboard" class="container-fluid">
<div class="row">
<div class="col-lg-7">
<?php execPluginsByHook('dashboard') ?>
</div>
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");
<div class="col-lg-5">
});
</script>
</div>
<!-- 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 -->
<?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>
</div>
</div>

View file

@ -1,8 +1,34 @@
<?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'));
echo '<h2 class="mb-4 mt-4"><b>PHP version: '.phpversion().'</b></h2>';
echo '<h2 class="mt-4 mb-4"><b>PHP version: '.phpversion().'</b></h2>';
// PHP Ini
$uploadOptions = array(

View file

@ -1,92 +1,135 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
<?php echo Bootstrap::formOpen(array('id'=>'jsform')); ?>
<script>
// ============================================================================
// Variables for the view
// ============================================================================
<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>
// ============================================================================
// 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>
<?php echo Bootstrap::pageTitle(array('title'=>$L->g('Edit Category'), 'icon'=>'cog')); ?>
</div>
<?php
// Token CSRF
echo Bootstrap::formInputHidden(array(
'name'=>'tokenCSRF',
'value'=>$security->getTokenCSRF()
));
echo Bootstrap::formInputHidden(array(
'id' => 'key',
'name' => 'key',
'value' => $categoryMap['key']
));
echo Bootstrap::formInputHidden(array(
'name'=>'action',
'value'=>'edit'
));
echo Bootstrap::formInputText(array(
'id' => 'name',
'name' => 'name',
'label' => $L->g('Name'),
'value' => $categoryMap['name']
));
echo Bootstrap::formInputHidden(array(
'name'=>'oldKey',
'value'=>$categoryMap['key']
));
echo Bootstrap::formTextarea(array(
'name' => 'description',
'label' => $L->g('Description'),
'value' => isset($categoryMap['description']) ? $categoryMap['description'] : '',
'rows' => 3
));
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' => 'template',
'label' => $L->g('Template'),
'value' => isset($categoryMap['template']) ? $categoryMap['template'] : ''
));
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

@ -1,563 +0,0 @@
<?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,52 +1,276 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
<?php echo Bootstrap::formOpen(array('id' => 'jsform', 'class' => 'tab-content')); ?>
<script>
// ============================================================================
// Variables for the view
// ============================================================================
<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>
// ============================================================================
// 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>
<?php echo Bootstrap::pageTitle(array('title' => $L->g('Edit user'), 'icon' => 'user')); ?>
</div>
<!-- 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>
<!-- 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 -->
<?php
// Token CSRF
echo Bootstrap::formInputHidden(array(
'name' => 'tokenCSRF',
'value' => $security->getTokenCSRF()
));
<!-- Content -->
<div class="tab-content" id="tabContent">
// 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">
<!-- Tab profile -->
<div class="tab-pane show active" id="profile" role="tabpanel">
<?php
// Display username but disable the field
echo Bootstrap::formInputText(array(
'name' => 'usernameDisabled',
'name' => 'username',
'label' => $L->g('Username'),
'value' => $user->username(),
'class' => '',
'placeholder' => '',
'disabled' => true,
'tip' => ''
'disabled' => true
));
if ($login->role() === 'admin') {
@ -55,7 +279,6 @@ echo Bootstrap::formInputHidden(array(
'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')
));
}
@ -64,107 +287,61 @@ echo Bootstrap::formInputHidden(array(
'name' => 'email',
'label' => $L->g('Email'),
'value' => $user->email(),
'class' => '',
'placeholder' => '',
'tip' => ''
'data' => array('save' => 'true')
));
echo Bootstrap::formInputText(array(
'name' => 'nickname',
'label' => $L->g('Nickname'),
'value' => $user->nickname(),
'class' => '',
'placeholder' => '',
'tip' => $L->g('The nickname is almost used in the themes to display the author of the content')
'tip' => $L->g('The nickname is almost used in the themes to display the author of the content'),
'data' => array('save' => 'true')
));
echo Bootstrap::formInputText(array(
'name' => 'firstName',
'label' => $L->g('First Name'),
'value' => $user->firstName(),
'class' => '',
'placeholder' => '',
'tip' => ''
'data' => array('save' => 'true')
));
echo Bootstrap::formInputText(array(
'name' => 'lastName',
'label' => $L->g('Last Name'),
'value' => $user->lastName(),
'class' => '',
'placeholder' => '',
'tip' => ''
'data' => array('save' => 'true')
));
echo Bootstrap::formTextarea(array(
'name' => 'bio',
'label' => $L->g('Bio'),
'value' => $user->bio(),
'rows' => 4,
'data' => array('save' => 'true')
));
?>
</div>
<!-- End Tab profile -->
<!-- Profile picture tab -->
<div class="tab-pane fade" id="picture" role="tabpanel" aria-labelledby="nav-picture-tab">
<!-- Tab profile picture -->
<div class="tab-pane" id="picture" role="tabpanel">
<div class="container">
<div class="row">
<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 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>
<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 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>
</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 -->
<!-- Security tab -->
<div class="tab-pane fade" id="security" role="tabpanel" aria-labelledby="nav-security-tab">
<!-- Tab security -->
<div class="tab-pane" id="security" role="tabpanel">
<?php
echo Bootstrap::formTitle(array('title' => $L->g('Password')));
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')));
echo Bootstrap::formInputText(array(
'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')
));
if (checkRole(array('admin'), false)) {
echo Bootstrap::formTitle(array('title' => $L->g('Status')));
@ -172,145 +349,145 @@ echo Bootstrap::formInputHidden(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' => '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="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>
<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 Bootstrap::formTitle(array('title' => $L->g('Authentication Token')));
echo Bootstrap::formInputText(array(
'name' => 'tokenAuth',
'label' => $L->g('Token'),
'value' => $user->tokenAuth(),
'tip' => $L->g('this-token-is-similar-to-a-password-it-should-not-be-shared')
));
echo Bootstrap::formTitle(array('title' => $L->g('Change password')));
echo Bootstrap::formInputText(array(
'name' => 'newPassword',
'label' => $L->g('New password'),
'type' => 'password',
'value' => ''
));
echo Bootstrap::formInputText(array(
'name' => 'confirmPassword',
'label' => $L->g('Confirm password'),
'type' => 'password',
'value' => ''
));
?>
</div>
<!-- End Tab security -->
<!-- Social Networks tab -->
<div class="tab-pane fade" id="social" role="tabpanel" aria-labelledby="nav-social-tab">
<div class="tab-pane" id="social" role="tabpanel">
<?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(),
'class' => '',
'placeholder' => '',
'tip' => ''
'data' => array('save' => 'true')
));
echo Bootstrap::formInputText(array(
'name' => 'facebook',
'label' => 'Facebook',
'value' => $user->facebook(),
'class' => '',
'placeholder' => '',
'tip' => ''
'data' => array('save' => 'true')
));
echo Bootstrap::formInputText(array(
'name' => 'discord',
'label' => 'Discord',
'value' => $user->discord(),
'data' => array('save' => 'true')
));
echo Bootstrap::formInputText(array(
'name' => 'codepen',
'label' => 'CodePen',
'value' => $user->codepen(),
'class' => '',
'placeholder' => '',
'tip' => ''
'data' => array('save' => 'true')
));
echo Bootstrap::formInputText(array(
'name' => 'instagram',
'label' => 'Instagram',
'value' => $user->instagram(),
'class' => '',
'placeholder' => '',
'tip' => ''
'data' => array('save' => 'true')
));
echo Bootstrap::formInputText(array(
'name' => 'gitlab',
'label' => 'GitLab',
'value' => $user->gitlab(),
'class' => '',
'placeholder' => '',
'tip' => ''
'data' => array('save' => 'true')
));
echo Bootstrap::formInputText(array(
'name' => 'github',
'label' => 'GitHub',
'value' => $user->github(),
'class' => '',
'placeholder' => '',
'tip' => ''
'data' => array('save' => 'true')
));
echo Bootstrap::formInputText(array(
'name' => 'linkedin',
'label' => 'LinkedIn',
'value' => $user->linkedin(),
'class' => '',
'placeholder' => '',
'tip' => ''
'data' => array('save' => 'true')
));
echo Bootstrap::formInputText(array(
'name' => 'xing',
'label' => 'Xing',
'value' => $user->xing(),
'class' => '',
'placeholder' => '',
'tip' => ''
));
echo Bootstrap::formInputText(array(
'name' => 'telegram',
'label' => 'Telegram',
'value' => $user->telegram(),
'class' => '',
'placeholder' => '',
'tip' => ''
'data' => array('save' => 'true')
));
echo Bootstrap::formInputText(array(
'name' => 'mastodon',
'label' => 'Mastodon',
'value' => $user->mastodon(),
'class' => '',
'placeholder' => '',
'tip' => ''
'data' => array('save' => 'true')
));
echo Bootstrap::formInputText(array(
'name' => 'vk',
'label' => 'VK',
'value' => $user->vk(),
'class' => '',
'placeholder' => '',
'tip' => ''
'data' => array('save' => 'true')
));
?>
</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

@ -0,0 +1,729 @@
<?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
The function also recover the old value
*/
function closeModal(fieldName, revertValue=false) {
if (revertValue) {
var value = localStorage.getItem(fieldName);
$('#' + fieldName).val(value);
}
$('#modal-' + fieldName).modal('hide');
}
/*
Disable the "Save" button
*/
function disableBtnSave() {
$('#btnSave').addClass('btn-primary-disabled').attr('data-current', 'saved').html('<i class="bi bi-check-square"></i><?php $L->p('Saved') ?>');
}
/*
Enable the "Save" button
*/
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(),
coverImage: $('#coverImage').val(),
category: $('#category option:selected').val(),
tags: $("#tags option:selected").map(function() {
return this.value
}).get().join(",")
}
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(),
coverImage: $('#coverImage').val(),
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', true);
});
// Modal date events
// ------------------------------------------------------------------------
$('#btnSaveDate').on('click', function() {
var args = {
date: $('#date').val()
};
savePage(args);
disableBtnSave();
closeModal('date');
});
$('#btnCancelDate').on('click', function() {
closeModal('date', true);
});
// Modal position events
// ------------------------------------------------------------------------
$('#btnSavePosition').on('click', function() {
var args = {
position: $('#position').val()
};
savePage(args);
disableBtnSave();
closeModal('position');
});
$('#btnCancelPosition').on('click', function() {
closeModal('position', true);
});
// Modal friendly-url events
// ------------------------------------------------------------------------
$('#btnSaveFriendlyURL').on('click', function() {
var args = {
slug: $('#friendlyURL').val()
};
savePage(args);
disableBtnSave();
closeModal('friendlyURL');
});
$('#btnCancelFriendlyURL').on('click', function() {
closeModal('friendlyURL', true);
});
$('#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', true);
});
// Modal SEO events
// ------------------------------------------------------------------------
$('#btnSaveSeo').on('click', function() {
var args = {
noindex: $('input[name="noindex"]').is(':checked'),
nofollow: $('input[name="nofollow"]').is(':checked'),
noarchive: $('input[name="noarchive"]').is(':checked')
};
savePage(args);
disableBtnSave();
closeModal('seo');
});
$('#btnCancelSeo').on('click', function() {
closeModal('seo', true);
});
// Modal parent events
// ------------------------------------------------------------------------
$('#btnSaveParent').on('click', function() {
var args = {
parent: $('#parent').val()
};
savePage(args);
disableBtnSave();
closeModal('parent');
});
$('#btnCancelParent').on('click', function() {
closeModal('parent', true);
});
});
// ============================================================================
// 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);
$("#parent").select2({
placeholder: '',
allowClear: true,
theme: 'bootstrap-5',
minimumInputLength: 2,
dropdownParent: $('#modal-parent'),
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>
<!-- 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"><?php echo $L->g('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><?php echo $L->g('Cancel') ?></button>
<button id="btnSaveDescription" type="button" class="btn btn-sm btn-primary"><i class="bi bi-check"></i><?php echo $L->g('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"><?php echo $L->g('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><?php echo $L->g('Cancel') ?></button>
<button id="btnSaveDate" type="button" class="btn btn-sm btn-primary"><i class="bi bi-check"></i><?php echo $L->g('Save') ?></button>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function() {
$("#date").datetimepicker({
format: DB_DATE_FORMAT
});
});
</script>
<!-- End Modal Date -->
<!-- Modal Position -->
<div class="modal" id="modal-position" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<div class="m-0">
<label for="position" class="fw-bold mb-2"><?php echo $L->g('Position') ?></label>
<input id="position" name="position" type="number" class="form-control" value="<?php echo ($pageKey ? $page->position() : '0') ?>">
<div class="form-text"><?php echo $L->g('Page position') ?></div>
</div>
</div>
<div class="modal-footer ps-2 pe-2 pt-1 pb-1">
<button id="btnCancelPosition" type="button" class="btn btn-sm btn-secondary"><i class="bi bi-x"></i><?php echo $L->g('Cancel') ?></button>
<button id="btnSavePosition" type="button" class="btn btn-sm btn-primary"><i class="bi bi-check"></i><?php echo $L->g('Save') ?></button>
</div>
</div>
</div>
</div>
<!-- End Modal Position -->
<!-- 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"><?php echo $L->g('Page URL') ?></label>
<button id="btnGenURLFromTitle" type="button" class="btn p-0 m-0 text-primary"><i class="bi bi-hammer"></i><?php echo $L->g('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><?php echo $L->g('Cancel') ?></button>
<button id="btnSaveFriendlyURL" type="button" class="btn btn-sm btn-primary"><i class="bi bi-check"></i><?php echo $L->g('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"><?php echo $L->g('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"><?php echo $L->g('Draft') ?></label>
<div class="form-text"><?php echo $L->g('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"><?php echo $L->g('Publish') ?></label>
<div class="form-text"><?php echo $L->g('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"><?php echo $L->g('Publish as sticky.') ?></label>
<div class="form-text"><?php echo $L->g('The page can be seen by everyone at 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"><?php echo $L->g('Publish as static.') ?></label>
<div class="form-text"><?php echo $L->g('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"><?php echo $L->g('Publish as unlisted.') ?></label>
<div class="form-text"><?php echo $L->g('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><?php echo $L->g('Cancel') ?></button>
<button id="btnSaveType" type="button" class="btn btn-sm btn-primary"><i class="bi bi-check"></i><?php echo $L->g('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"><?php echo $L->g('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><?php echo $L->g('Cancel') ?></button>
<button id="btnSaveSeo" type="button" class="btn btn-sm btn-primary"><i class="bi bi-check"></i><?php echo $L->g('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="col-sm-10">
<select id="parent" name="parent" class="form-select" data-current-value="" data-save="true"></select>
</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><?php echo $L->g('Cancel') ?></button>
<button id="btnSaveParent" type="button" class="btn btn-sm btn-primary"><i class="bi bi-check"></i><?php echo $L->g('Save') ?></button>
</div>
</div>
</div>
</div>
<!-- End Modal Parent -->
<div class="container-fluid h-100">
<div class="row h-100">
<div class="col-sm-9 d-flex flex-column" style="height: 85%">
<!-- 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>
<input id="coverImage" name="coverImage" data-save="true" type="hidden" value="<?php echo (($pageKey && $page->coverImage()) ? $page->coverImage(false) : '') ?>">
<img id="coverImagePreview" 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"><?php $L->p('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"><?php $L->p('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="' . $fields['name'] . '" ' . ($pageKey && array_key_exists($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"><?php $L->p('More options') ?></h6>
<ul class="list-group">
<li class="list-group-item p-0 pt-3 bg-transparent border-0"><a onclick="fmOpen()" href="#"><i class="bi bi-files"></i><?php $L->p('Files & images') ?></a></li>
<li class="list-group-item p-0 pt-3 bg-transparent border-0"><a onclick="openModal('description')" href="#"><i class="bi bi-info-square"></i><?php $L->p('Description') ?></a></li>
<li class="list-group-item p-0 pt-3 bg-transparent border-0"><a onclick="openModal('date')" href="#"><i class="bi bi-calendar"></i><?php $L->p('Publish date') ?></a></li>
<li class="list-group-item p-0 pt-3 bg-transparent border-0"><a onclick="openModal('friendlyURL')" href="#"><i class="bi bi-link"></i><?php echo $L->g('Change URL') ?></a></li>
<li class="list-group-item p-0 pt-3 bg-transparent border-0"><a onclick="openModal('type')" href="#"><i class="bi bi-eye"></i><?php $L->p('Type') ?></a></li>
<li class="list-group-item p-0 pt-3 bg-transparent border-0"><a onclick="openModal('seo')" href="#"><i class="bi bi-compass"></i><?php $L->p('SEO features') ?></a></li>
<li class="list-group-item p-0 pt-3 bg-transparent border-0"><a onclick="openModal('parent')" href="#"><i class="bi bi-diagram-2"></i><?php $L->p('Parent page') ?></a></li>
<li class="list-group-item p-0 pt-3 bg-transparent border-0"><a onclick="openModal('position')" href="#"><i class="bi bi-diagram-2"></i><?php $L->p('Position') ?></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

@ -0,0 +1,238 @@
<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"><?php echo $L->g('Preview') ?></th>
<th scope="col"><?php echo $L->g('Filename') ?></th>
<th scope="col"><?php echo $L->g('Type') ?></th>
<th scope="col"><?php echo $L->g('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);
}
});
}
function setCoverImage(filename) {
var image = DOMAIN_UPLOADS_PAGES+_pageKey+'/'+filename;
$("#coverImage").val(filename);
$("#coverImagePreview").attr("src", image);
}
// 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) {
console.log(file);
var row = '<tr>' +
'<td class="align-middle">' +
' <img style="width: 32px" src="' + file.thumbnailSmall + '" />' +
'</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><?php $L->p('Options') ?></button>' +
'<ul class="dropdown-menu dropdown-menu-dark" aria-labelledby="fileOptions">';
if (ALLOWED_IMG_MIMETYPES.includes(file.mime)) {
row += '<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 original size') ?></a></li>' +
'<li><a class="dropdown-item" href="#" onClick="fmInsertFile(\'' + file.filename + '\', \'' + file.thumbnailSmall + '\', \'' + file.mime + '\'); fmClose();"><i class="bi bi-plus-circle"></i><?php $L->p('Insert small size') ?></a></li>' +
'<li><a class="dropdown-item" href="#" onClick="fmInsertFile(\'' + file.filename + '\', \'' + file.thumbnailMedium + '\', \'' + file.mime + '\'); fmClose();"><i class="bi bi-plus-circle"></i><?php $L->p('Insert medium size') ?></a></li>' +
'<li><hr class="dropdown-divider"></li>' +
'<li><a class="dropdown-item" href="#" onClick="setCoverImage(\'' + file.filename + '\')"><i class="bi bi-image"></i><?php $L->p('Set as cover image') ?></a></li>';
} else {
row += '<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 file') ?></a></li>';
}
row += '<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
if (!ALLOWED_FILE_MIMETYPES.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_FILE_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,37 +1,71 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
echo '<h1 class="text-center mb-3 mt-3 font-weight-normal" style="color: #555;">' . $site->title() . '</h1>';
<script>
// ============================================================================
// Variables for the view
// ============================================================================
echo Bootstrap::formOpen(array());
// ============================================================================
// Functions for the view
// ============================================================================
echo Bootstrap::formInputHidden(array(
'name' => 'tokenCSRF',
'value' => $security->getTokenCSRF()
));
// ============================================================================
// Events for the view
// ============================================================================
$(document).ready(function() {
// No events for the view yet
});
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>
';
// ============================================================================
// Initialization for the view
// ============================================================================
$(document).ready(function() {
// No initialization for the view yet
});
</script>
echo '
<div class="form-group">
<input type="password" class="form-control form-control-lg" id="jspassword" name="password" placeholder="' . $L->g('Password') . '">
</div>
';
<?php
echo '
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 '
<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="form-group mt-3">
<button type="submit" class="btn btn-primary btn-lg mr-2 w-100" name="save">' . $L->g('Login') . '</button>
<div class="mt-4">
<button type="submit" class="btn btn-primary btn-lg me-2 w-100" name="save">'.$L->g('Login').'</button>
</div>
';
echo '</form>';
echo '<p class="mt-3 text-right">' . $L->g('Powered by Bludit') . ((defined('BLUDIT_PRO')) ? ' PRO' : '') . '</p>';
echo '<p class="mt-5 text-end">'.$L->g('Powered by Bludit').'</p>'
?>

View file

@ -1,39 +0,0 @@
<?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

@ -1,511 +0,0 @@
<?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

@ -1,67 +0,0 @@
<?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,51 +1,80 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
<?php echo Bootstrap::formOpen(array('id'=>'jsform', 'class'=>'tab-content')); ?>
<script>
// ============================================================================
// Variables for the view
// ============================================================================
<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>
// ============================================================================
// 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>
<?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
// Token CSRF
echo Bootstrap::formInputHidden(array(
'name'=>'tokenCSRF',
'value'=>$security->getTokenCSRF()
));
<?php echo Bootstrap::formTitle(array('title' => $L->g('Website plugins'))) ?>
echo Bootstrap::formInputHidden(array(
'name'=>'plugin-list',
'value'=>''
));
<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 '<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>';
?>
<?php echo Bootstrap::formTitle(array('title' => $L->g('Dashboard plugins'))) ?>
<?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>
<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>

View file

@ -0,0 +1,80 @@
<?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;
});
$('textarea').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,125 +1,165 @@
<?php
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
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>
$(document).ready(function() {
$("#search").on("keyup", function() {
var textToSearch = $(this).val().toLowerCase();
$(".searchItem").each(function() {
var item = $(this);
item.hide();
item.find(".searchText").each(function() {
var element = $(this).text().toLowerCase();
if (element.indexOf(textToSearch) != -1) {
item.show();
}
});
});
});
});
// ============================================================================
// 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() {
var item = $(this);
item.hide();
item.find(".searchText").each(function() {
var element = $(this).text().toLowerCase();
if (element.indexOf(textToSearch) != -1) {
item.show();
}
});
});
});
$('.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('title' => $L->g('Enabled plugins')));
// Plugins installed
echo Bootstrap::formTitle(array('icon' => 'check-square', 'title' => $L->g('Enabled plugins')));
echo '<table class="table table-striped"><tbody>';
echo '
<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 '<td class="align-middle pt-3 pb-3 w-25">';
echo '<div class="searchText">' . $plugin->name().'</div>';
echo '<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 theme which is active
if ($plugin->type() != 'theme') {
echo '<span class="link deactivatePlugin" data-class-name="' . $plugin->className() . '">' . $L->g('Deactivate') . '</a>';
}
echo '</div>';
echo '</td>';
echo '<tr id="' . $plugin->className() . '" class="bg-light searchItem">';
echo '<td class="searchText align-middle d-none d-sm-table-cell">';
echo '<div>' . $plugin->description() . '</div>';
if (in_array($plugin->type(), array('dashboard','theme','editor'))) {
echo '<div class="badge bg-primary">'.$L->g($plugin->type()).'</div>';
}
echo '</td>';
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="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 class="text-center align-middle d-none d-lg-table-cell">';
echo '<span>' . $plugin->version() . '</span>';
echo '</td>';
echo '<td class="text-center align-middle d-none d-lg-table-cell">';
echo '<a target="_blank" href="' . $plugin->website() . '">' . $plugin->author() . '</a>';
echo '</td>';
echo '<td class="searchText align-middle d-none d-sm-table-cell">';
echo $plugin->description();
echo '</td>';
echo '<td class="text-center align-middle d-none d-lg-table-cell">';
echo '<span>' . $plugin->version() . '</span>';
echo '</td>';
echo '<td class="text-center align-middle d-none d-lg-table-cell">
<a target="_blank" href="' . $plugin->website() . '">' . $plugin->author() . '</a>
</td>';
echo '</tr>';
echo '</tr>';
}
echo '
</tbody>
</table>
';
echo Bootstrap::formTitle(array('title' => $L->g('Disabled plugins')));
echo '
<table class="table">
<tbody>
';
echo '</tbody></table>';
// Plugins not installed
echo Bootstrap::formTitle(array('icon' => 'dash-square', 'title' => $L->g('Disabled plugins')));
echo '<table class="table table-striped"><tbody>';
$pluginsNotInstalled = array_diff_key($plugins['all'], $pluginsInstalled);
foreach ($pluginsNotInstalled 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="searchItem">';
echo '<td class="align-middle pt-3 pb-3 w-25">';
echo '<div class="searchText">' . $plugin->name() . '</div>';
echo '<div class="mt-1"><span class="link activatePlugin" data-class-name="' . $plugin->className() . '">' . $L->g('Activate') . '</a></div>';
echo '</td>';
echo '<td class="align-middle pt-3 pb-3 w-25">
<div class="searchText">' . $plugin->name() . '</div>
<div class="mt-1">
<a href="' . HTML_PATH_ADMIN_ROOT . 'install-plugin/' . $plugin->className() . '">' . $L->g('Activate') . '</a>
</div>
</td>';
echo '<td class="searchText align-middle d-none d-sm-table-cell">';
echo '<div>' . $plugin->description() . '</div>';
if (in_array($plugin->type(), array('dashboard','theme','editor'))) {
echo '<div class="badge bg-primary">'.$L->g($plugin->type()).'</div>';
}
echo '</td>';
echo '<td class="searchText align-middle d-none d-sm-table-cell">';
echo $plugin->description();
echo '<td class="text-center align-middle d-none d-lg-table-cell">';
echo '<span>' . $plugin->version() . '</span>';
echo '</td>';
echo '<td class="text-center align-middle d-none d-lg-table-cell">';
echo '<a target="_blank" href="' . $plugin->website() . '">' . $plugin->author() . '</a>';
echo '</td>';
echo '<td class="text-center align-middle d-none d-lg-table-cell">';
echo '<span>' . $plugin->version() . '</span>';
echo '</td>';
echo '<td class="text-center align-middle d-none d-lg-table-cell">
<a target="_blank" href="' . $plugin->website() . '">' . $plugin->author() . '</a>
</td>';
echo '</tr>';
echo '</tr>';
}
echo '
</tbody>
</table>
';
echo '</tbody></table>';

File diff suppressed because it is too large Load diff

View file

@ -1,54 +1,80 @@
<?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' => 'desktop'));
echo Bootstrap::pageTitle(array('title'=>$L->g('Themes'), 'icon'=>'eye'));
echo '
<table class="table mt-3">
<table class="table table-striped 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 ' . ($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>
echo '
<tr>
<td class="align-middle pt-4 pb-4">
<div>'.$theme['name'].($theme['dirname']==$site->theme()?'<span class="badge bg-primary ms-2">'.$L->g('Activate').'</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 . 'configure-plugin/' . $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 . 'plugins-settings/' . $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 '

View file

@ -1,60 +0,0 @@
<?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,15 +1,37 @@
<?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>
@ -30,20 +52,20 @@ foreach ($list as $username) {
try {
$user = new User($username);
echo '<tr>';
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>';
echo '<td class="pt-4 pb-4"><i class="bi bi-person"></i><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>';
if ($user->role()=='admin') {
echo '<td>'.$L->g('Administrator').'</td>';
echo '<td class="pt-4 pb-4">'.$L->g('Administrator').'</td>';
} elseif ($user->role()=='editor') {
echo '<td>'.$L->g('Editor').'</td>';
echo '<td class="pt-4 pb-4">'.$L->g('Editor').'</td>';
} elseif ($user->role()=='author') {
echo '<td>'.$L->g('Author').'</td>';
echo '<td class="pt-4 pb-4">'.$L->g('Author').'</td>';
} else {
echo '<td>'.$L->g('Reader').'</td>';
echo '<td class="pt-4 pb-4">'.$L->g('Reader').'</td>';
}
echo '<td class="d-none d-lg-table-cell">'.Date::format($user->registered(), DB_DATE_FORMAT, ADMIN_PANEL_DATE_FORMAT).'</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 '</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.'new-content';
$tmp['url'] = HTML_PATH_ADMIN_ROOT.'editor';
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.'new-category';
$tmp['url'] = HTML_PATH_ADMIN_ROOT.'add-category';
array_push($result, $tmp);
}
if (Text::stringContains(Text::lowercase($L->g('New user')), $query)) {

View file

@ -1,43 +0,0 @@
<?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,12 +2,14 @@
header('Content-Type: application/json');
/*
| Returns a list of pages and the title contains the query string
| The returned list have published, sticky and statics pages
| 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".
|
| @_POST['query'] string The string to search in the title of the 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.
|
| @return array
| @return json Ex. {"results":[{"disabled":false,"id":"follow-bludit","text":"Follow Bludit","type":"published"}]}
*/
// $_GET
@ -18,33 +20,31 @@ $query = isset($_GET['query']) ? Text::lowercase($_GET['query']) : false;
$checkIsParent = empty($_GET['checkIsParent']) ? false : true;
// ----------------------------------------------------------------------------
if ($query===false) {
ajaxResponse(1, 'Invalid query.');
ajaxResponse(1, 'Invalid query.');
}
$result = array();
$pagesKey = $pages->getDB();
foreach ($pagesKey as $pageKey) {
try {
$page = new Page($pageKey);
if ($page->isParent() || !$checkIsParent) {
// Check page status
if ($page->published() || $page->sticky() || $page->isStatic()) {
// Check if the query contains in the title
$lowerTitle = Text::lowercase($page->title());
if (Text::stringContains($lowerTitle, $query)) {
$tmp = array('disabled'=>false);
$tmp['id'] = $page->key();
$tmp['text'] = $page->title();
$tmp['type'] = $page->type();
array_push($result, $tmp);
}
}
}
} catch (Exception $e) {
// continue
}
try {
$page = new Page($pageKey);
if ($page->isParent() || !$checkIsParent) {
// Check page status
if ($page->published() || $page->sticky() || $page->isStatic()) {
// Check if the query contains in the title
$lowerTitle = Text::lowercase($page->title());
if (Text::stringContains($lowerTitle, $query)) {
$tmp = array('disabled'=>false);
$tmp['id'] = $page->key();
$tmp['text'] = $page->title();
$tmp['type'] = $page->type();
array_push($result, $tmp);
}
}
}
} catch (Exception $e) {
// continue
}
}
exit (json_encode(array('results'=>$result)));
?>

View file

@ -1,62 +0,0 @@
<?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

@ -1,22 +0,0 @@
<?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

@ -1,70 +0,0 @@
<?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

@ -1,74 +0,0 @@
<?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

@ -1,95 +0,0 @@
<?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,14 +1,20 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// Start the session
// If the session is not possible to start the admin area is not available
Session::start($site->urlPath(), $site->isHTTPS());
// If the session is not started the admin area is not available
Session::start();
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,
@ -19,14 +25,14 @@ $layout = array(
'title'=>'Bludit'
);
// Get the Controller
// Get from the URL the controller and view
$explodeSlug = $url->explodeSlug();
$layout['controller'] = $layout['view'] = $layout['slug'] = empty($explodeSlug[0])?'dashboard':$explodeSlug[0];
unset($explodeSlug[0]);
// 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
// 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>']
if ($layout['controller'] === 'plugin' && !empty($explodeSlug)) {
// Lowercase plugins class name to search by case-insensitive
$pluginsLowerCases = array_change_key_case($pluginsInstalled);
@ -46,59 +52,57 @@ 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');
// 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';
// 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');
// Generate the tokenCSRF for the user not logged, when the user log-in the token will be change.
$security->generateTokenCSRF();
}
// 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';
// 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');
// Generate the tokenCSRF for the user not logged, when the user log-in the token will change
$security->generateTokenCSRF();
}
// 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,77 +1,68 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// Bludit version
define('BLUDIT_VERSION', '3.16.2');
define('BLUDIT_CODENAME', 'Valencia');
define('BLUDIT_RELEASE_DATE', '2024-08-23');
define('BLUDIT_BUILD', '20240806');
define('BLUDIT_VERSION', '4.0.0');
define('BLUDIT_CODENAME', '');
define('BLUDIT_RELEASE_DATE', '2021-05-23');
define('BLUDIT_BUILD', '20210523');
// Change to TRUE for debugging
// Debug mode
// Change to FALSE, for prevent warning or errors on browser
define('DEBUG_MODE', TRUE);
define('DEBUG_TYPE', 'INFO'); // INFO, TRACE
// 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);
error_reporting(0); // Turn off all error reporting
if (DEBUG_MODE) {
error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);
} else {
error_reporting(E_ERROR);
// Turn on all error reporting
ini_set("display_errors", 0);
ini_set('display_startup_errors',0);
ini_set("html_errors", 1);
ini_set('log_errors', 1);
error_reporting(E_ALL | E_STRICT | E_NOTICE);
}
// PHP paths
// 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_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_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_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_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);
@ -80,50 +71,51 @@ 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 . '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(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 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 . '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');
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');
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
@ -145,46 +137,46 @@ $syslog = new Syslog();
$base = '';
if (!empty($_SERVER['DOCUMENT_ROOT']) && !empty($_SERVER['SCRIPT_NAME']) && empty($base)) {
$base = str_replace($_SERVER['DOCUMENT_ROOT'], '', $_SERVER['SCRIPT_NAME']);
$base = dirname($base);
$base = str_replace($_SERVER['DOCUMENT_ROOT'], '', $_SERVER['SCRIPT_NAME']);
$base = dirname($base);
} elseif (empty($base)) {
$base = empty($_SERVER['SCRIPT_NAME']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
$base = dirname($base);
$base = empty( $_SERVER['SCRIPT_NAME'] ) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
$base = dirname($base);
}
if (strpos($_SERVER['REQUEST_URI'], $base) !== 0) {
$base = '/';
} elseif ($base != DS) {
$base = trim($base, '/');
$base = '/' . $base . '/';
if (strpos($_SERVER['REQUEST_URI'], $base)!==0) {
$base = '/';
} elseif ($base!=DS) {
$base = trim($base, '/');
$base = '/'.$base.'/';
} else {
// Workaround for Windows Web Servers
$base = '/';
// Workaround for Windows Web Servers
$base = '/';
}
define('HTML_PATH_ROOT', $base);
define('HTML_PATH_THEMES', HTML_PATH_ROOT . 'bl-themes/');
define('HTML_PATH_THEME', HTML_PATH_THEMES . $site->theme() . '/');
define('HTML_PATH_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/');
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_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 ---
@ -217,38 +209,37 @@ 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_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_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);
// --- 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_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_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', $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_PLUGINS', DOMAIN.HTML_PATH_PLUGINS);
define('DOMAIN_CONTENT', DOMAIN.HTML_PATH_CONTENT);
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));
$ADMIN_CONTROLLER = '';
$ADMIN_VIEW = '';

View file

@ -1,48 +1,51 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================
// Variables
// Global Variables
// ============================================================================
$plugins = array(
'siteHead'=>array(),
'siteBodyBegin'=>array(),
'siteBodyEnd'=>array(),
'siteSidebar'=>array(),
'beforeSiteLoad'=>array(),
'afterSiteLoad'=>array(),
'siteHead' => array(),
'siteBodyBegin' => array(),
'siteBodyEnd' => array(),
'siteSidebar' => array(),
'beforeSiteLoad' => array(),
'afterSiteLoad' => array(),
'pageBegin'=>array(),
'pageEnd'=>array(),
'pageBegin' => array(),
'pageEnd' => array(),
'beforeAdminLoad'=>array(),
'afterAdminLoad'=>array(),
'adminHead'=>array(),
'adminBodyBegin'=>array(),
'adminBodyEnd'=>array(),
'adminSidebar'=>array(),
'adminContentSidebar'=>array(),
'dashboard'=>array(),
'beforeAdminLoad' => array(),
'afterAdminLoad' => array(),
'adminHead' => array(),
'adminBodyBegin' => array(),
'adminBodyEnd' => array(),
'adminSidebar' => array(),
'adminContentSidebar' => array(),
'dashboard' => array(),
'beforeAll'=>array(),
'afterAll'=>array(),
'beforeAll' => array(),
'afterAll' => array(),
'paginator'=>array(),
'paginator' => array(),
'afterPageCreate'=>array(),
'afterPageModify'=>array(),
'afterPageDelete'=>array(),
'beforePageModify' => array(),
'beforePageDelete' => array(),
'loginHead'=>array(),
'loginBodyBegin'=>array(),
'loginBodyEnd'=>array(),
'afterPageCreate' => array(),
'afterPageModify' => array(),
'afterPageDelete' => array(),
'all'=>array()
'loginHead' => array(),
'loginBodyBegin' => array(),
'loginBodyEnd' => array(),
'all' => array() // $plugins['all'] keep installed and not installed plugins
);
$pluginsEvents = $plugins;
unset($pluginsEvents['all']);
// This array has only the installed plugins
// The array key is the "plugin class name" and the value is the object
// pluginsInstalled[pluginClass] = $Plugin
$pluginsInstalled = array();
// ============================================================================
@ -52,21 +55,22 @@ $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();
// List plugins directories
// Load plugins clasess
$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');
if (file_exists($pluginPath . DS . 'plugin.php')) {
include_once($pluginPath . DS . 'plugin.php');
}
}
@ -77,20 +81,19 @@ function buildPlugins()
$Plugin = new $pluginClass;
// Check if the plugin is translated
$languageFilename = PATH_PLUGINS.$Plugin->directoryName().DS.'languages'.DS.$site->language().'.json';
$languageFilename = PATH_PLUGINS . $Plugin->directoryName() . DS . 'languages' . DS . $site->language() . '.json';
if (!Sanitize::pathFile($languageFilename)) {
$languageFilename = PATH_PLUGINS.$Plugin->directoryName().DS.'languages'.DS.DEFAULT_LANGUAGE_FILE;
$languageFilename = PATH_PLUGINS . $Plugin->directoryName() . DS . 'languages' . DS . DEFAULT_LANGUAGE_FILE;
}
$database = file_get_contents($languageFilename);
$database = json_decode($database, true);
// Set name and description from the language file
$Plugin->setMetadata('name',$database['plugin-data']['name']);
$Plugin->setMetadata('description',$database['plugin-data']['description']);
$Plugin->setMetadata('name', $database['plugin-data']['name']);
$Plugin->setMetadata('description', $database['plugin-data']['description']);
// Remove name and description from the language file loaded and add new words if there are
// This function overwrite the key=>value
// Remove name and description from the language and includes new words to the global language dictionary
unset($database['plugin-data']);
if (!empty($database)) {
$L->add($database);
@ -99,29 +102,41 @@ 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 custom hooks
// Include the plugin installed in the global array
$pluginsInstalled[$pluginClass] = $Plugin;
// Define new hooks from custom hooks
if (!empty($Plugin->customHooks)) {
foreach ($Plugin->customHooks as $customHook) {
if (!isset($plugins[$customHook])) {
$plugins[$customHook] = array();
$pluginsEvents[$customHook] = array();
foreach ($Plugin->customHooks as $hook) {
if (!isset($plugins[$hook])) {
$plugins[$hook] = array();
$pluginsHooks[$hook] = array();
}
}
}
$pluginsInstalled[$pluginClass] = $Plugin;
foreach ($pluginsEvents as $event=>$value) {
if (method_exists($Plugin, $event)) {
array_push($plugins[$event], $Plugin);
// Insert the plugin into the hooks
foreach ($pluginsHooks as $hook => $value) {
if (method_exists($Plugin, $hook)) {
array_push($plugins[$hook], $Plugin);
}
}
}
// Sort the plugins by the position for the site sidebar
uasort($plugins['siteSidebar'], function ($a, $b) {
return $a->position()>$b->position();
uasort(
$plugins['siteSidebar'],
function ($a, $b) {
return $a->position() <=> $b->position();
}
);
// Sort the plugins by the position for the dashboard
uasort(
$plugins['dashboard'],
function ($a, $b) {
return $a->position() <=> $b->position();
}
);
}

View file

@ -16,7 +16,7 @@
*/
$content = array();
// Page filtered by the user, is a Page Object
// Page filtered by the user, will be 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 = $staticPages = buildStaticPages();
$staticContent = buildStaticPages();
// ============================================================================
// Main
@ -38,10 +38,10 @@ $staticContent = $staticPages = buildStaticPages();
// Execute the scheduler
if ($pages->scheduler()) {
// Execute plugins with the hook afterPageCreate
Theme::plugins('afterPageCreate');
execPluginsByHook('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') {
$content[0] = $page = buildThePage();
$page = buildThePage();
}
// Build content by tag
elseif ($url->whereAmI()==='tag') {
@ -73,14 +73,10 @@ elseif ($url->whereAmI()==='category') {
}
// Build content for the homepage
elseif ( ($url->whereAmI()==='home') || ($url->whereAmI()==='blog') ) {
$content = buildPagesForHome();
}
if (isset($content[0])) {
$page = $content[0];
$content = buildPagesForHome();
}
// If set notFound, create the page 404
if ($url->notFound()) {
$content[0] = $page = buildErrorPage();
$page = buildErrorPage();
}

View file

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

View file

@ -3,7 +3,7 @@
// ============================================================================
// Variables
// ============================================================================
$themePlugin = getPlugin($site->theme()); // Returns plugin object or False
$theme = getPlugin($site->theme()); // Returns plugin object or False
// ============================================================================
// Functions
@ -16,18 +16,20 @@ 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;
}
@ -36,19 +38,20 @@ 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;
}
}
@ -68,12 +71,13 @@ 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);
@ -81,7 +85,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
Theme::plugins('beforeAll');
execPluginsByHook('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
Theme::plugins('beforeSiteLoad');
execPluginsByHook('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
Theme::plugins('afterSiteLoad');
execPluginsByHook('afterSiteLoad');
// Plugins after all
Theme::plugins('afterAll');
execPluginsByHook('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', 20);
define('ITEMS_PER_PAGE_ADMIN', 12);
// Password length
define('PASSWORD_LENGTH', 6);
@ -107,7 +107,13 @@ define('MEDIA_MANAGER_SORT_BY_DATE', true);
$GLOBALS['DB_TAGS_TYPES'] = array('published','static','sticky');
// Allowed image extensions
$GLOBALS['ALLOWED_IMG_EXTENSION'] = array('gif', 'png', 'jpg', 'jpeg', 'svg', 'webp');
$GLOBALS['ALLOWED_IMG_EXTENSIONS'] = array('gif', 'png', 'jpg', 'jpeg', 'svg');
// Allowed image mime types
$GLOBALS['ALLOWED_IMG_MIMETYPES'] = array('image/gif', 'image/png', 'image/jpeg', 'image/svg+xml', 'image/webp');
$GLOBALS['ALLOWED_IMG_MIMETYPES'] = array('image/gif', 'image/png', 'image/jpeg', 'image/svg+xml');
// Allowed files extensions
$GLOBALS['ALLOWED_FILE_EXTENSIONS'] = array_merge($GLOBALS['ALLOWED_IMG_EXTENSIONS'], array('pdf'));
// Allowed files mime types
$GLOBALS['ALLOWED_FILE_MIMETYPES'] = array_merge($GLOBALS['ALLOWED_IMG_MIMETYPES'], array('application/pdf'));

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

Before

Width:  |  Height:  |  Size: 424 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

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