Compare commits

..

316 commits
v3.0 ... main

Author SHA1 Message Date
Diego Najar
a36f2534a0
Merge pull request #1512 from belomaxorka/added-missing-comma
Added missing comma in nl_NL.json
2023-07-10 19:40:01 +02:00
Diego Najar
573dc27447
Merge pull request #1511 from belomaxorka/minor-fixes-themes
Minor improvements in default themes
2023-07-10 19:39:29 +02:00
Diego Najar
cb11f7a9b1
Merge pull request #1510 from belomaxorka/use-checkbox-installer
Use checkbox instead of text [Installer]
2023-07-10 19:38:50 +02:00
Diego Najar
1c145a12e6
Merge pull request #1504 from hide-me/main
Improved translation files
2023-07-10 19:37:34 +02:00
Diego Najar
4ba266a83d
Merge pull request #1501 from basteyy/patch-2
Comma Seperated Tags List Walker Feature
2023-07-10 19:37:03 +02:00
Roman Kelesidis
3a24f5eb30 Added missing comma in nl_NL.json 2023-04-25 13:26:08 +07:00
Roman Kelesidis
0020afe6d1 Minor improvements in default themes 2023-04-25 13:16:52 +07:00
Roman Kelesidis
5ff606d526 Use checkbox instead of text [Installer] 2023-04-25 13:10:47 +07:00
Paul
401a14dcc4
Added link to Discord server 2023-03-29 23:04:19 +03:00
Paul
61e18cbfba
Converted spaces to tabs
Saved space
2023-03-29 23:03:08 +03:00
Sebastian
b0013d5d2c
Comma Seperated Tags List Walker Feature
Commit adds support of adding a list with commas to the tag field.
2023-02-28 21:11:49 +01:00
Diego Najar
e8cfad9241
Merge pull request #1483 from jlaase/Popeye-Mastadon
Popeye mastadon
2023-02-22 22:50:48 +01:00
Diego Najar
08f5522e62
Merge pull request #1495 from basteyy/fix_1494
Fix #1494
2023-02-22 22:49:53 +01:00
Diego Najar
a4654ce0ae
Merge pull request #1497 from basteyy/fix_1496
Fix Deprecated message
2023-02-22 22:49:00 +01:00
Sebastian
550a46f10f
Update simple-image.class.php
Fix float to int deprecation message
2023-02-22 21:48:18 +01:00
Diego Najar
87c52d25d8
Merge pull request #1499 from basteyy/patch-1
Fix handling array as object
2023-02-22 19:26:21 +01:00
Sebastian
027c85e968
Fix handling array as object
At this line, the  `$user ` is a `array` and not the User Object `User`.
2023-02-14 20:57:52 +01:00
Sebastian
5c260d82f4
Fix Deprecated message
Instead of adding a new dynamic property to the DateInterval-Object, a new var is created which stores the weeks. Inside the `foreach` a handler is created by checking, if the current `$key` is `w` for weeks.
2023-02-13 20:58:10 +01:00
Sebastian
fb0f974580
Fix #1494
Handle `checkbox`different than other `input` elements (such as text, password ...), by using a different selector and check, if the `checkbox` is checked.
2023-02-13 20:22:01 +01:00
Diego Najar
532140d967
Merge pull request #1488 from basteyy/patch-1
Fix #1487
2023-01-26 14:19:56 +01:00
Sebastian
53cbf84bc7
Add a minimum password length constant 2023-01-20 22:28:39 +01:00
Sebastian
26ac249c9e
Fix #1487
Add a password length check and display an error, if the password is not at least 6 signs.
Add html5 tag "minlength" to password input
2023-01-20 22:26:36 +01:00
Diego Najar
6cce49f0be
Merge pull request #1457 from wandrien/edit-user-title-fix
Display the user name in the title of page /admin/edit-user/$username
2023-01-04 15:43:23 +01:00
Diego Najar
578339dddb
Merge pull request #1465 from hide-me/main
Added ru lang file & fix file formatting
2023-01-04 15:38:12 +01:00
Joshua Laase
3787192ed8 Update footer.php
This change adds a rel='me' info to the mastodon link in the footer. This allows anyone using the Popeye theme to have their website validated in their Mastodon profile.
2023-01-02 09:33:36 -06:00
Joshua Laase
495ceb8bcc Revert "Update footer.php"
This reverts commit 67ca4fcde0.
2023-01-02 09:30:07 -06:00
Joshua Laase
67ca4fcde0 Update footer.php
This change adds a rel='me' info to the mastodon link in the footer. This allows anyone using the Popeye theme to have their website validated in their Mastodon profile.
2023-01-02 09:27:39 -06:00
Paul
084b79562a
Added two strings
still need to add more strings from en.json
2022-10-06 19:23:14 +03:00
Paul
d16400db96
Added ru lang + spaces converted to tabs 2022-10-06 19:14:08 +03:00
Vadim Ushakov
387e62ea7e Display the user name in the title of page /admin/edit-user/$username
Display the user name in the title of page `/admin/edit-user/$username`, in the same way as it's implemented for `/admin/edit-category/$category`.
2022-09-19 15:43:48 +07:00
Diego Najar
55d3b162bf
Include Reddit as social network 2022-09-07 17:02:49 +02:00
Diego Najar
50c6deb262
Merge pull request #1447 from kraiosis/main
version badge on admin sidebar
2022-09-05 19:55:54 +02:00
Diego Najar
93b840f063 logo refactor 2022-09-05 09:40:11 +02:00
Federico Guzman
3a0ce9a94e
version badge on admin sidebar
Update badge css to math bootstrap v5.1.3 as used in Bludit 4.x. css class names for badges has changed since boostrap 5.x from bagdewarning to bg-warning and badge-pill to rounded-pill. This allows to show correct badge in admin sidebar (menu)
2022-06-28 18:43:46 -04:00
Diego Najar
548c2a5d8f
Merge pull request #1445 from ltGuillaume/patch-1
Dutch
2022-06-21 21:08:54 +02:00
Diego Najar
e8e6584503
Merge pull request #1446 from kraiosis/main
Update es.json
2022-06-21 21:08:24 +02:00
Federico Guzman
30c118e236
Update es.json 2022-06-13 20:49:06 -04:00
Guillaume
c738e9f1cb
Dutch 2022-05-30 21:26:30 +02:00
Edi
58551c7d05
Update de_AT.json 2022-05-28 11:39:22 +02:00
Edi
d56a43c5d4
Update de_DE.json 2022-05-28 11:38:25 +02:00
Edi
8585aa3fa8
Update de_CH.json 2022-05-28 11:37:35 +02:00
Edi
36ffbdf366
Update en.json 2022-05-28 11:36:41 +02:00
Diego Najar
29563c8add
Merge pull request #1427 from gaincoder/main
check if the user of the session is in the database
2022-05-26 23:05:09 +02:00
Diego Najar
aeea823a3e
Merge pull request #1439 from emanueleg/it
Fix localization typos
2022-05-26 23:04:45 +02:00
Diego Najar
00a8cf666c
Merge pull request #1442 from emanueleg/parent
show parent page in modal
2022-05-26 23:04:23 +02:00
Emanuele Goldoni
fb4b65a4c7 show parent page in modal 2022-05-11 22:51:07 +02:00
Emanuele Goldoni
c6f6d3df81 Fix localization typos 2022-05-10 13:41:09 +02:00
Edi
440d825f79
Update de_AT.json 2022-05-09 14:04:24 +02:00
Edi
6558e480d8
Update de_CH.json 2022-05-09 14:03:53 +02:00
Edi
ea3be35761
Update de_DE.json 2022-05-09 14:03:09 +02:00
Edi
40615b8eac
Update de_DE.json 2022-05-09 14:01:40 +02:00
Edi
1038b46e83
Update de_CH.json 2022-05-09 13:59:34 +02:00
Edi
f1474098d8
Update de_AT.json 2022-05-09 13:58:35 +02:00
Edi
601932a119
Update de_AT.json 2022-05-09 13:52:18 +02:00
Edi
d4ebf62fcd
Update de_DE.json 2022-05-09 13:51:17 +02:00
Edi
7585898fa6
Update de_CH.json 2022-05-09 13:50:28 +02:00
Edi
7b06585238
Update de_CH.json 2022-05-09 13:49:50 +02:00
Tim Moritz
4a72c5968e check if the user of the session is in the database - change method 2022-05-09 08:42:24 +02:00
Diego Najar
16bb662cce Improve function preview #1438 2022-05-08 15:03:39 +02:00
Diego Najar
22bd590cf5
Merge pull request #1436 from ltGuillaume/patch-3
Dutch for html-code plugin
2022-05-08 14:16:21 +02:00
Diego Najar
50f4d3955c
Merge pull request #1435 from ltGuillaume/patch-2
Dutch
2022-05-08 14:16:10 +02:00
Diego Najar
b98f9a8c60
Merge pull request #1434 from ltGuillaume/patch-1
Dutch for installer
2022-05-08 14:15:49 +02:00
Guillaume
4c6d09d46e
Dutch for html-code plugin 2022-05-07 19:31:45 +02:00
Guillaume
5eb54d78ef
Dutch 2022-05-07 19:24:57 +02:00
Guillaume
ca5710f4ba
Dutch for installer
Add admin panel text
2022-05-07 19:17:14 +02:00
Diego Najar
cafc2630d4 Change more options order for #1423 2022-05-07 18:33:56 +02:00
Diego Najar
847c59e233 Fix for blog filter #1370 2022-05-07 18:27:22 +02:00
Diego Najar
4f20b3dbe2
Merge pull request #1420 from emanueleg/preview
enable content Preview - fixes #1383
2022-05-07 18:02:59 +02:00
Emanuele
5331362808
Merge branch 'bludit:main' into preview 2022-05-06 16:13:09 +02:00
Edi
41284f67fa
Update de_CH.json 2022-05-04 22:57:30 +02:00
Edi
64fdd9e407
Update de_AT.json 2022-05-04 22:55:29 +02:00
Edi
f6e9f2e0f2
Update de_DE.json 2022-05-04 22:54:36 +02:00
Edi
b9d2ea0e0f
Update de_CH.json 2022-05-04 22:53:16 +02:00
Edi
e386a7ca7a
Update de_DE.json 2022-05-04 22:26:43 +02:00
Edi
587414757d
Update de_CH.json 2022-05-04 22:25:54 +02:00
Emanuele
825bd5f509
Merge branch 'bludit:main' into preview 2022-05-04 09:32:11 +02:00
Diego Najar
299c334655 Remove HTML entities when generate the URL base on title, fix for #1428 2022-05-03 20:27:30 +02:00
Emanuele Goldoni
2d4544acbb remove commented code 2022-05-03 20:10:01 +02:00
Diego Najar
a3abf8e135 Remove autocomplete for inputs fields, fix for #1430 2022-05-03 19:58:33 +02:00
Diego Najar
66ff89c3ab check json format for custom fields, add position menu for custom fields, fix issues with boolean types 2022-05-03 19:45:01 +02:00
Diego Najar
c8fa8d5dd6 fix italian dictionary 2022-05-03 19:44:20 +02:00
Diego Najar
0f62247871 fix env variables for installer 2022-05-03 19:44:01 +02:00
Emanuele
5285ab78af
Merge branch 'bludit:main' into preview 2022-05-03 19:12:44 +02:00
Diego Najar
9e07add22d
Merge pull request #1413 from gaincoder/fixDeleteUser
fix User cannot be deleted #1407
2022-05-03 15:32:36 +02:00
Edi
d15137732e
Merge pull request #1424 from eagleman/patch-2
Create it_it.json
2022-04-21 17:42:15 +02:00
Tim Moritz
35826189ec check if the user of the session is in the database 2022-04-14 16:40:15 +02:00
eagleman
59839897a0
Create it_it.json
Italian file for alternative plugin
2022-04-13 13:04:42 +02:00
Edi
f6899abfeb
Merge pull request #1421 from eagleman/patch-1
Update it_IT.json
2022-04-09 08:40:58 +02:00
eagleman
c48ef00b38
Update it_IT.json
Updated italian file for Bludit 4
2022-04-07 16:38:50 +02:00
Diego Najar
974860cb88
Merge pull request #1408 from emanueleg/main
Use UUID when deleting pages and when installing example content
2022-04-06 11:13:42 +02:00
Emanuele
c6400d66f5
Merge branch 'bludit:main' into main 2022-03-22 18:10:50 +01:00
Diego Najar
334f02e113
Merge pull request #1412 from gaincoder/fix-api
add missing api endpoint (GET) /api/pages
2022-03-17 21:36:44 +01:00
Tim Moritz
774348fe02 add delete user function for V4 2022-03-17 15:09:20 +01:00
Tim Moritz
76e85f4082 add missing api endpoint (GET) /api/pages 2022-03-17 14:16:01 +01:00
Emanuele Goldoni
a128e603ca enable content Preview - fixes #1383 2022-03-07 23:12:58 +01:00
Emanuele
0bbf886fac
Use UUID for example pages 2022-03-02 22:39:30 +01:00
Emanuele
1e486574ef
UUID for deleting pages files 2022-03-02 22:23:07 +01:00
Diego Najar
9a2ac1eaf4 Add information about Admin panel in dummy page 2022-02-24 15:40:35 +01:00
Diego Najar
52d31317ed Merge branch 'main' of github.com:bludit/bludit 2022-02-23 14:15:17 +01:00
Diego Najar
1d6e1d8fc0 Page URL from title, UUID for pages files 2022-02-23 14:15:10 +01:00
Edi
30aeb202ce
Update de_AT.json 2022-02-22 23:11:55 +01:00
Edi
f65a98de7f
Update de_DE.json 2022-02-22 23:11:02 +01:00
Edi
57285feef2
Update de_CH.json 2022-02-22 23:10:10 +01:00
Diego Najar
347bc6fbbb Update README.md 2022-02-22 16:37:32 +01:00
Diego Najar
93eb607e35 minor ui change 2022-02-22 14:40:08 +01:00
Diego Najar
0a76a7785b Tooltip for cover image 2022-02-22 14:39:25 +01:00
Diego Najar
ae5e1fc59a Remove Cover image via double click 2022-02-22 14:36:15 +01:00
Diego Najar
da39fd6ce8 Add delete file from Filemanager #1384 2022-02-22 14:26:54 +01:00
Diego Najar
32a0170d64 update language dictionaries 2022-02-22 14:26:03 +01:00
Diego Najar
5986c1d220 Easymde insert image and insert image at cursor position #1405 2022-02-21 22:56:58 +01:00
Diego Najar
52ecf89b77 Add custom fields 2022-02-21 16:21:32 +01:00
Diego Najar
8e7a7eaf18 set min position to 0 #1397 2022-02-09 10:04:16 +01:00
Diego Najar
165baf94ab
Merge pull request #1398 from ltGuillaume/patch-1
Dutch for v4
2022-01-10 10:41:46 +01:00
Diego Najar
800641da5d
Merge pull request #1399 from ltGuillaume/patch-2
Dutch for v4 installer
2022-01-10 10:40:47 +01:00
Diego Najar
56a16cb38b
Merge pull request #1400 from ltGuillaume/patch-3
Dutch for Disqus plugin
2022-01-10 10:40:33 +01:00
Diego Najar
3e36d789ee
Merge pull request #1401 from ltGuillaume/v4.0nl
Dutch for v4.0 plugins
2022-01-10 10:40:13 +01:00
ltGuillaume
e9e1f221d6 Dutch for v4.0 plugins 2021-12-24 23:31:43 +01:00
Guillaume
1463ef9c32
Update nl_NL.json 2021-12-22 21:02:24 +01:00
Guillaume
660103de36
Dutch for Disqus plugin 2021-12-22 21:00:23 +01:00
Guillaume
62faaa39cb
Dutch for installer 2021-12-22 20:48:32 +01:00
Guillaume
112acb7d8c
Update nl_NL.json 2021-12-22 20:46:19 +01:00
Guillaume
d9665076f6
Dutch for v4 2021-12-22 20:27:04 +01:00
Diego Najar
320f9a2f0c Bug fix in Session handler for multiples Bludit installation in the same root folder 2021-11-25 20:17:38 +01:00
Diego Najar
9718e03590 Refactor Alternative theme for Bludit v4 and include plugin for settings 2021-11-22 10:59:38 +01:00
Diego Najar
92b91bfde6 Refactor Alternative theme for Bludit v4 and include plugin for settings 2021-11-22 10:57:27 +01:00
Diego Najar
70a22886dc
Merge pull request #1387 from nogajun/japanese
Add Japanese translation to installer and popeye
2021-11-22 09:51:39 +01:00
Diego Najar
9bf2663353 remove theme's plugins from the list 2021-11-21 18:50:58 +01:00
Diego Najar
4cfdf1722b Refactor BlogX theme for Bludit v4, include plugin with settings 2021-11-21 18:44:36 +01:00
Jun Nogata
0c6bc97133 Add Japanese translation to installer and popeye, and fix Japanese translation 2021-11-21 17:16:20 +09:00
Diego Najar
65afabefd8 remove multiples descriptions in plugins, fix for #1382 2021-11-11 13:40:33 +01:00
Diego Najar
642d07151e Fix for sub-pages #1380 2021-11-11 13:37:06 +01:00
Diego Najar
2af5d5332f
Merge pull request #1385 from clickwork-git/v4.0
V4.0: Additions and modifications language files
2021-11-10 17:21:51 +01:00
Edi
a1db1190c6
Update de_AT.json 2021-11-10 17:12:17 +01:00
Edi
e3fb7f3ec7
Update de_DE.json 2021-11-10 17:11:31 +01:00
Edi
e9030decc1
Update de_CH.json 2021-11-10 17:10:20 +01:00
Edi
bebd0fd2d7
Create de_AT.json 2021-11-10 17:06:58 +01:00
Edi
14ff421fcd
Update de_DE.json 2021-11-10 17:06:12 +01:00
Edi
01df98fc39
Update de_CH.json 2021-11-10 17:05:29 +01:00
Edi
89f9209b7d
Additional phrase 2021-11-10 17:04:33 +01:00
Edi
d3b03ad543
Update de_AT.json 2021-11-10 16:54:05 +01:00
Edi
4917391d4f
Update de_DE.json 2021-11-10 16:53:15 +01:00
Edi
d123dc5e12
Update de_CH.json 2021-11-10 16:52:18 +01:00
Diego Najar
fb9cd99a67
Merge pull request #1379 from gaincoder/v4.0
Install via composer #752
2021-10-28 09:28:35 +02:00
Tim Moritz
73fabfd81b Merge branch 'v4.0' of github.com:bludit/bludit into v4.0 2021-10-27 23:29:24 +02:00
Tim Moritz
96b738bc39 Install via composer #752 2021-10-27 23:17:14 +02:00
Diego Najar
6cebc2850b
Merge pull request #1376 from gaincoder/v4.0
add the possibility to use independend classes in plugins
2021-10-27 09:27:02 +02:00
Tim Moritz
2b17019bd5 rename plugin interface 2021-10-27 07:54:39 +02:00
Tim Moritz
54bc55f1cf Merge remote-tracking branch 'origin/v4.0' into v4.0 2021-10-26 11:27:03 +02:00
Tim Moritz
336cffe777 add the possibility to use independend classes in plugins 2021-10-26 11:25:05 +02:00
Diego Najar
f8366bb6c8 change label on the active theme 2021-10-25 18:40:42 +02:00
Diego Najar
90a4f304c8 Open website in new tab 2021-10-25 09:24:28 +02:00
Diego Najar
865fd124b7 remove backtrace 2021-10-25 09:15:45 +02:00
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
497 changed files with 31194 additions and 32001 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,12 +1,12 @@
# [Bludit](https://www.bludit.com/)
Bludit the Simple, Fast, and Flexible CMS.
Simple, Fast and Flexible CMS.
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.
Bludit is a web application to build your own website or blog in seconds, it's completely free and open source. Bludit uses files in JSON format to store the content, you don't need to install or configure a database. You only need a web server with PHP support.
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.
Bludit is a Flat-File CMS.
## Resources
Bludit supports Markdown and HTML code for the content.
- [Plugins](https://plugins.bludit.com)
- [Themes](https://themes.bludit.com)
@ -19,7 +19,7 @@ As a Flat-File CMS, Bludit offers unparalleled flexibility and speed. Plus, with
## Requirements
- Webserver with PHP support.
- PHP v5.6 or higher version.
- PHP v7 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.
@ -27,11 +27,11 @@ As a Flat-File CMS, Bludit offers unparalleled flexibility and speed. Plus, with
## 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.
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 directory `bludit` to your web server or hosting.
4. Visit your domain https://example.com/bludit/
5. Follow the Bludit Installer to set up the website.
## Quick installation for testing
@ -39,10 +39,9 @@ You can use PHP Built-in web server (`php -S localhost:8000`) or [Docker image](
## 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.
Bludit is open source and free, but if you really like the project and is useful for your you can contribute on [Patreon](https://www.patreon.com/bePatron?c=921115&rid=2458860), also for the supporters we provide Bludit PRO. [![Bludit PRO](https://img.shields.io/badge/Bludit-PRO-blue.svg)](https://pro.bludit.com/)
Donate one time for the coffee or beer:
- [PayPal](https://www.paypal.me/bludit/10)
- BTC (Network BTC): bc1qtets5pdj73uyysjpegfh2gar4pfywra4rglcph
- ETH (Network ETH): 0x0d7D58D848aA5f175D75Ce4bC746bAC107f331b7

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,6 +1,6 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
class Plugin
class Plugin implements PluginInterface
{
// (string) directory name, just the name
@ -56,10 +56,10 @@ class Plugin
// Init empty database with default values
$this->db = $this->dbFields;
$this->filenameDb = PATH_PLUGINS_DATABASES . $this->directoryName . DS . 'db.php';
$this->filenameDb = PATH_PLUGINS_DATABASES.$this->directoryName.DS.'db.php';
// --- Metadata ---
$this->filenameMetadata = PATH_PLUGINS . $this->directoryName() . DS . 'metadata.json';
$this->filenameMetadata = PATH_PLUGINS.$this->directoryName().DS.'metadata.json';
$metadataString = file_get_contents($this->filenameMetadata);
$this->metadata = json_decode($metadataString, true);
@ -80,44 +80,44 @@ class Plugin
public function includeCSS($filename)
{
return '<link rel="stylesheet" type="text/css" href="' . $this->domainPath() . 'css/' . $filename . '?version=' . BLUDIT_VERSION . '">' . PHP_EOL;
return '<link rel="stylesheet" type="text/css" href="'.$this->domainPath().'css/'.$filename.'?version='.BLUDIT_VERSION.'">'.PHP_EOL;
}
public function includeJS($filename)
{
return '<script charset="utf-8" src="' . $this->domainPath() . 'js/' . $filename . '?version=' . BLUDIT_VERSION . '"></script>' . PHP_EOL;
return '<script charset="utf-8" src="'.$this->domainPath().'js/'.$filename.'?version='.BLUDIT_VERSION.'"></script>'.PHP_EOL;
}
// Returns absolute URL and path of the plugin directory
// This function helps to include CSS or Javascript files with absolute URL
public function domainPath()
{
return DOMAIN_PLUGINS . $this->directoryName . '/';
return DOMAIN_PLUGINS.$this->directoryName.'/';
}
// Returns relative path of the plugin directory
// This function helps to include CSS or Javascript files with relative URL
public function htmlPath()
{
return HTML_PATH_PLUGINS . $this->directoryName . '/';
return HTML_PATH_PLUGINS.$this->directoryName.'/';
}
// Returns absolute path of the plugin directory
// This function helps to include PHP libraries or some file at server level
public function phpPath()
{
return PATH_PLUGINS . $this->directoryName . DS;
return PATH_PLUGINS.$this->directoryName.DS;
}
public function phpPathDB()
{
return PATH_PLUGINS_DATABASES . $this->directoryName . DS;
return PATH_PLUGINS_DATABASES.$this->directoryName.DS;
}
// Returns the value of the key from the metadata of the plugin, FALSE if the key doesn't exist
public function getMetadata($key)
{
if (isset($this->metadata[$key])) {
if(isset($this->metadata[$key])) {
return $this->metadata[$key];
}
@ -134,7 +134,7 @@ class Plugin
// Returns the value of the field from the database
// (string) $field
// (boolean) $html, TRUE returns the value sanitized, FALSE unsanitized
public function getValue($field, $html = true)
public function getValue($field, $html=true)
{
if (isset($this->db[$field])) {
if ($html) {
@ -171,6 +171,11 @@ class Plugin
return $this->getMetadata('email');
}
public function type()
{
return $this->getMetadata('type');
}
public function website()
{
return $this->getMetadata('website');
@ -205,9 +210,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 +225,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 +236,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 +253,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 +263,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 +293,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 +305,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 +332,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 +341,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 +353,7 @@ class Plugin
if ($fixed) {
return false;
}
if ($afterURI[0] != '/') {
if ($afterURI[0]!='/') {
return false;
}
}
@ -348,7 +362,8 @@ class Plugin
return $afterURI;
}
Log::set(__METHOD__ . LOG_SEP . 'Webhook requested.');
Log::set(__METHOD__.LOG_SEP.'Webhook requested.');
return true;
}
}
}

View file

@ -0,0 +1,79 @@
<?php
interface PluginInterface
{
public function save();
public function includeCSS($filename);
public function includeJS($filename);
public function domainPath();
public function htmlPath();
public function phpPath();
public function phpPathDB();
public function getMetadata($key);
public function setMetadata($key, $value);
public function getValue($field, $html = true);
public function label();
public function name();
public function description();
public function author();
public function email();
public function type();
public function website();
public function position();
public function version();
public function releaseDate();
public function className();
public function formButtons();
public function isCompatible();
public function directoryName();
public function install($position = 1);
public function uninstall();
/**
* Returns True if the plugin is installed
*
* @return boolean
*/
public function installed(): bool;
public function workspace();
public function init();
public function prepare();
public function post();
public function configure($args);
public function setField($field, $value);
public function setPosition($position);
public function webhook($URI = false, $returnsAfterURI = false, $fixed = 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') . ' [ ' . $username . ' ] ' . ' - ' . $layout['title'];

View file

@ -0,0 +1,33 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================
// Authorization
// ============================================================================
checkRole(array('admin', 'editor', 'author'));
// ============================================================================
// Functions
// ============================================================================
// ============================================================================
// Main
// ============================================================================
$pageKey = false;
$pageUUID = false;
$pagePreviewID = false;
if (!empty($layout['parameters'])) {
try {
$pageKey = $layout['parameters'];
$page = new Page($pageKey);
$pageUUID = $page->uuid();
$pagePreviewID = $page->previewID();
} 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">
@ -13,11 +16,11 @@
<?php $L->p('Dashboard') ?></a>
</li>
<li class="nav-item">
<a class="nav-link" href="<?php echo HTML_PATH_ROOT ?>">
<a class="nav-link" target="_blank" rel="noopener noreferrer" href="<?php echo HTML_PATH_ROOT ?>">
<?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" target="_blank" rel="noopener noreferrer" 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::formInputText(array(
'id' => 'email',
'name' => 'email',
'type' => 'email',
'label' => $L->g('Email'),
'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')
));
?>

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,189 @@
<?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-'.$child->key().'">';
echo '<td class="ps-4 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 class="text-muted"><small><i class="bi bi-diagram-2-fill"></i>' . ($page->title() ? $page->title() : $L->g('Empty title')) . '</small></div>
</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 +194,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 +226,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,347 @@
<?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);
}
});
}
}
});
});
$('#btnDeleteUserAndKeepContent').on('click', function() {
var username = $('#username').val();
logs('Deleting user. Username: ' + username);
bootbox.confirm({
message: '<?php $L->p('Are you sure you want to delete 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()
};
api.deleteUser(args).then(function(response) {
if (response.status == 0) {
logs('User deleted. 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);
}
});
}
}
});
});
$('#btnDeleteUserAndContent').on('click', function() {
var username = $('#username').val();
logs('Deleting user and content. Username: ' + username);
bootbox.confirm({
message: '<?php $L->p('Are you sure you want to delete 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(),
deleteContent: true
};
api.deleteUser(args).then(function(response) {
if (response.status == 0) {
logs('User and content deleted. 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 +350,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 +358,60 @@ 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')
'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 +419,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,915 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
<script>
// ============================================================================
// Variables for the view
// ============================================================================
var _pageKey = <?php echo $pageKey ? '"' . $pageKey . '"' : 'null' ?>;
var _pageUUID = <?php echo $pageUUID ? '"' . $pageUUID . '"' : 'null' ?>;
var _pagePreviewID = <?php echo $pagePreviewID ? '"' . $pagePreviewID . '"' : 'null' ?>;
// ============================================================================
// Functions for the view
// ============================================================================
// Default function for get the content inside the textarea from the Editor
// This function is enable only when the user doesn't define a plugin as Editor
if (typeof editorGetContent != 'function') {
window.editorGetContent = function() {
return $('#editor').val();
};
}
// Default function for insert content inside the textarea from the Editor
// This function is enable only when the user doesn't define a plugin as Editor
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 a new page
// This function set the global variable "_pageKey"
// This function set the global variable "_pageUUID"
// This function set the global variable "_pagePreviewID"
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;
_pageUUID = response.data.uuid;
_pagePreviewID = response.data.previewID;
// 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 = []) {
console.log('Saving page. Key: ' + _pageKey);
if (_pageKey == null) {
logs('Error, page not created.');
showAlertError("Error, page not created.");
return false;
}
args['pageKey'] = _pageKey;
args['parent'] = $('#parent').val();
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;
} 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();
// Parse all custom fields inputs
var customFields = {}
$('input[name^="custom"]').each(function() {
var field = $(this).data('field')
var value = $(this).val()
customFields[field] = value
});
$('select[name^="custom"]').each(function() {
var field = $(this).data('field');
var value = $(this).val();
customFields[field] = value;
});
// Create array with all inputs
var args = {
slug: $('#friendlyURL').val(),
title: $('#title').val(),
content: editorGetContent(),
custom: customFields,
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() {
// Parse all custom fields inputs
var customFields = {}
$('input[name^="custom"]').each(function() {
var field = $(this).data('field')
var value = $(this).val()
customFields[field] = value
});
$('select[name^="custom"]').each(function() {
var field = $(this).data('field');
var value = $(this).val();
customFields[field] = value;
});
// Create array with all inputs
var args = {
slug: $('#friendlyURL').val(),
title: $('#title').val(),
content: editorGetContent(),
custom: customFields,
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');
});
$('#btnPreview').click(function() {
window.open(DOMAIN_PAGES + _pageKey + '?preview=' + _pagePreviewID);
});
$('#category').on("change", function() {
enableBtnSave();
});
$('#coverImagePreview').dblclick(function() {
logs('Removing cover image.');
$('#coverImage').val('');
$(this).attr('src', HTML_PATH_CORE_IMG + 'default.svg');
var args = { coverImage: '' }
savePage(args);
});
// 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;
}
// Parse all custom fields inputs
var customFields = {}
$('input[name^="custom"]').each(function() {
var field = $(this).data('field')
var value = $(this).val()
customFields[field] = value
});
$('select[name^="custom"]').each(function() {
var field = $(this).data('field');
var value = $(this).val();
customFields[field] = value;
});
// Create array with all inputs
var args = {
slug: $('#friendlyURL').val(),
title: $('#title').val(),
content: content,
custom: customFields,
coverImage: $('#coverImage').val(),
category: $('#category option:selected').val(),
tags: $("#tags option:selected").map(function() {
return this.value
}).get().join(",")
}
savePage(args);
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="description" 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" min="0" 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="m-0">
<label class="fw-bold mb-2"><?php echo $L->g('Parent page') ?></label>
</div>
<div class="col-sm-10">
<select id="parent" name="parent" class="form-select" data-current-value="<?php echo (($pageKey && $page->parent()) ? $page->parent() : '') ?>" data-save="true">
<?php echo (($pageKey && $page->parent()) ? '<option value="'.$page->parent().'" selected>'.$page->parent().'</option>' : '') ?>
</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 -->
<!-- Custom fields without position or top position -->
<?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'=>(($pageKey && $page->custom($field))?$page->custom($field):''),
'tip'=>(isset($options['tip'])?$options['tip']:''),
'placeholder'=>(isset($options['placeholder'])?$options['placeholder']:''),
'class'=>'form-control-lg',
'data' => array('field' => $field)
));
} elseif ($options['type']=="bool") {
echo Bootstrap::formSelectBlock(array(
'name' => 'custom['.$field.']',
'label' => (isset($options['label'])?$options['label']:''),
'options' => array('true' => $L->g('Enabled'), 'false' => $L->g('Disabled')),
'selected' => (($pageKey && $page->custom($field))?'true':'false'),
'tip' => (isset($options['tip'])?$options['tip']:''),
'data' => array('field' => $field)
));
}
}
}
?>
<!-- Editor -->
<textarea class="form-control flex-grow-1" placeholder="" id="editor"><?php echo ($pageKey ? $page->contentRaw() : '') ?></textarea>
<!-- End Editor -->
<div class="mb-2"></div>
<!-- Custom fields bottom position -->
<?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'=>(($pageKey && $page->custom($field))?$page->custom($field):''),
'tip'=>(isset($options['tip'])?$options['tip']:''),
'placeholder'=>(isset($options['placeholder'])?$options['placeholder']:''),
'class'=>'form-control-lg',
'data' => array('field' => $field)
));
} elseif ($options['type']=="bool") {
echo Bootstrap::formSelectBlock(array(
'name' => 'custom['.$field.']',
'label' => (isset($options['label'])?$options['label']:''),
'options' => array('true' => $L->g('Enabled'), 'false' => $L->g('Disabled')),
'selected' => (($pageKey && $page->custom($field))?'true':'false'),
'tip' => (isset($options['tip'])?$options['tip']:''),
'data' => array('field' => $field)
));
}
}
}
?>
</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 data-toggle="tooltip" data-placement="top" title="Double click to delete the cover image" 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>
let addToTagList = function (value) {
// trim
value = value.replace(/^\s+|\s+$/g,"");
if ($("#tags option[value='" + value + "']").length > 0) {
$("#tags option[value='" + value + "']").prop('selected', true);
} else {
$('#tags').prepend($('<option>', {
value: value,
text: value,
selected: true
}));
}
};
$(document).ready(function() {
$('#addTag').keypress(function(e) {
if (e.which == 13) {
var value = $(this).val();
// Split input?
if (value.indexOf(',') > -1) {
value.split(',').forEach( function(s) {
addToTagList(s);
});
} else {
addToTagList(value);
}
$(this).val('');
return false;
}
});
$("#tags").on("mousedown", 'option', function(e) {
e.preventDefault();
$(this).prop('selected', !$(this).prop('selected'));
enableBtnSave();
return false;
});
});
</script>
<!-- End Tags -->
<!-- Custom fields menu position -->
<?php
$customFields = $site->customFields();
foreach ($customFields as $field=>$options) {
if ( isset($options['position']) && ($options['position']=='menu') ) {
if ($options['type']=="string") {
echo '<h6 class="text-uppercase mt-4">'.(isset($options['label'])?$options['label']:'').'</h6>';
echo Bootstrap::formInputTextBlock(array(
'name'=>'custom['.$field.']',
'value'=>(($pageKey && $page->custom($field))?$page->custom($field):''),
'tip'=>(isset($options['tip'])?$options['tip']:''),
'placeholder'=>(isset($options['placeholder'])?$options['placeholder']:''),
'class'=>'',
'data' => array('field' => $field)
));
} elseif ($options['type']=="bool") {
echo '<h6 class="text-uppercase mt-4">'.(isset($options['label'])?$options['label']:'').'</h6>';
echo Bootstrap::formSelectBlock(array(
'name' => 'custom['.$field.']',
'label' => '',
'options' => array('true' => $L->g('Enabled'), 'false' => $L->g('Disabled')),
'selected' => (($pageKey && $page->custom($field))?true:false),
'tip' => (isset($options['tip'])?$options['tip']:''),
'data' => array('field' => $field)
));
}
}
}
?>
<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="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="fmOpen()" href="#"><i class="bi bi-image"></i><?php $L->p('Images & Files') ?></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('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>
<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('seo')" href="#"><i class="bi bi-compass"></i><?php $L->p('SEO features') ?></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,256 @@
<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="#" onClick="fmDeleteFile(\'' + file.filename + '\');"><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);
}
});
}
// Delete a file for the current page
function fmDeleteFile(file) {
logs('File Manager. Deleting file.');
api.deletePageFile({
'key': _pageKey,
'file': file
}).then(function(response) {
if (response.status == 0) {
logs("File Manager. File deleted.");
// Get current files
fmGetFiles();
} else {
logs("File Manager. An error occurred while trying to delete the file for the current page.");
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,72 @@
<?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>
';
<img class="mx-auto d-block w-25 mb-4" alt="logo" src="<?php echo HTML_PATH_CORE_IMG . 'logo.svg' ?>" />
<h1 class="text-center text-uppercase mb-4"><?php echo $site->title() ?></h1>
echo '
<?php
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-secondary 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,89 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
<script>
// ============================================================================
// Variables for the view
// ============================================================================
// ============================================================================
// Functions for the view
// ============================================================================
function configurePlugin(className) {
var args = {
className: className
};
$('input:not([type=checkbox])').each(function() {
var key = $(this).attr('name');
var value = $(this).val();
args[key] = value;
});
$('input[type=checkbox]').each(function() {
var key = $(this).attr('name');
var value = $(this).val();
if($(this).is(":checked")) {
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,170 @@
<?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) {
if ($plugin->type() == 'theme') {
// Do not display theme's plugins
continue;
}
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>';
}
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) {
if ($plugin->type() == 'theme') {
// Do not display theme's plugins
continue;
}
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('Active').'</span>':'').'</div>
<div class="mt-1">
';
if ($theme['dirname'] != $site->theme()) {
echo '<a href="' . HTML_PATH_ADMIN_ROOT . 'install-theme/' . $theme['dirname'] . '">' . $L->g('Activate') . '</a>';
} else {
if (isset($theme['plugin'])) {
echo '<a href="' . HTML_PATH_ADMIN_ROOT . '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
// If the session is not started the admin area is not available
Session::start($site->urlPath(), $site->isHTTPS());
if (Session::started()===false) {
if (!Session::started()) {
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,67 @@
<?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
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.
error_reporting(0); // Turn off all error reporting
ini_set("display_errors", 0); // Turn off display errors in browser
ini_set('display_startup_errors', 0);
// If disabled, error message will be solely plain text instead HTML code.
ini_set("html_errors", 0);
// Tells whether script error messages should be logged to the server's error log or error_log.
ini_set('log_errors', 1);
if (DEBUG_MODE) {
error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);
} else {
error_reporting(E_ERROR);
// Turn on all error reporting, will be display in log server
ini_set("html_errors", 1);
ini_set('log_errors', 1);
error_reporting(E_ALL);
}
// 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);
@ -79,51 +69,56 @@ mb_internal_encoding(CHARSET);
// Set HTTP output character encoding
mb_http_output(CHARSET);
// Include interfaces
include(PATH_ABSTRACT . 'plugin.interface.php');
// 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 +140,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 +212,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');
}
}
@ -74,23 +78,28 @@ function buildPlugins()
$pluginsDeclaredClasess = array_diff(get_declared_classes(), $currentDeclaredClasess);
foreach ($pluginsDeclaredClasess as $pluginClass) {
$reflect = new ReflectionClass($pluginClass);
if(!$reflect->implementsInterface('PluginInterface')){
continue;
}
$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 +108,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

@ -6,11 +6,13 @@ if ($url->uri()==HTML_PATH_ROOT.ADMIN_URI_FILTER) {
}
// Redirect blog, from /blog to /blog/
// This rule only works when the user set a page as homepage
if ($url->uri()==HTML_PATH_ROOT.'blog' && $site->homepage()) {
$filter = $url->filters('blog');
$finalURL = Text::addSlashes(DOMAIN_BASE.$filter, false, true);
Redirect::url($finalURL);
// If the user define the blog's filter as "myblog" the redirection will be from /myblog to /myblog/
if ($site->homepage()) {
$filter = $url->filters('blog');
if ($url->uri()==HTML_PATH_ROOT.$filter) {
$finalURL = Text::addSlashes(DOMAIN_BASE.$filter, false, true);
Redirect::url($finalURL);
}
}
// Redirect pages, from /my-page/ to /my-page

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,14 +3,13 @@
// ============================================================================
// Variables
// ============================================================================
$themePlugin = getPlugin($site->theme()); // Returns plugin object or False
$theme = getPlugin($site->theme()); // Returns plugin object or False
// ============================================================================
// Functions
// ============================================================================
function buildThemes()
{
function buildThemes() {
global $site;
$themes = array();
@ -18,16 +17,16 @@ function buildThemes()
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);
Log::set('99.themes.php'.LOG_SEP.'Language file error on theme '.$themePath);
break;
}
@ -36,19 +35,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 +68,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 +82,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

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