aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.dev/.sasslintrc8
-rw-r--r--.gitignore1
-rw-r--r--assets/default/scss/shaarli.scss58
-rw-r--r--doc/md/Plugin-System.md17
-rw-r--r--doc/md/Plugins.md4
-rw-r--r--inc/languages/fr/LC_MESSAGES/shaarli.po53
-rw-r--r--index.php1
-rw-r--r--plugins/default_colors/default_colors.css.template3
-rw-r--r--plugins/default_colors/default_colors.meta5
-rw-r--r--plugins/default_colors/default_colors.php111
-rw-r--r--plugins/demo_plugin/demo_plugin.meta3
-rw-r--r--plugins/demo_plugin/demo_plugin.php19
-rw-r--r--tests/plugins/PluginDefaultColorsTest.php195
13 files changed, 439 insertions, 39 deletions
diff --git a/.dev/.sasslintrc b/.dev/.sasslintrc
index ac406d7b..47c3145d 100644
--- a/.dev/.sasslintrc
+++ b/.dev/.sasslintrc
@@ -2,9 +2,11 @@ options:
2 max-warnings: 0 2 max-warnings: 0
3rules: 3rules:
4 property-sort-order: 4 property-sort-order:
5 - 1 5 - 0
6 - 6# Sort order rule does not work with CSS variables: https://github.com/sasstools/sass-lint/issues/1161
7 order: 'concentric' 7# - 1
8# -
9# order: 'concentric'
8 no-important: 10 no-important:
9 - 0 11 - 0
10 no-vendor-prefixes: 12 no-vendor-prefixes:
diff --git a/.gitignore b/.gitignore
index c54d9b69..b21d2118 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,6 +28,7 @@ phpdoc.xml
28 28
29# User plugin configuration 29# User plugin configuration
30plugins/*/config.php 30plugins/*/config.php
31plugins/default_colors/default_colors.css
31 32
32# HTML documentation 33# HTML documentation
33doc/html/ 34doc/html/
diff --git a/assets/default/scss/shaarli.scss b/assets/default/scss/shaarli.scss
index 9e5464a0..1d89f998 100644
--- a/assets/default/scss/shaarli.scss
+++ b/assets/default/scss/shaarli.scss
@@ -25,9 +25,15 @@ $warning-text: #97600d;
25$form-input-border: #d8d8d8; 25$form-input-border: #d8d8d8;
26$form-input-background: #eee; 26$form-input-background: #eee;
27 27
28:root {
29 --main-color: #{$main-green};
30 --background-color: #{$background-color};
31 --dark-main-color: #{$dark-green};
32}
33
28// General 34// General
29body { 35body {
30 background: $background-color; 36 background: var(--background-color);
31} 37}
32 38
33.strong { 39.strong {
@@ -143,7 +149,7 @@ body,
143} 149}
144 150
145.pure-alert-success { 151.pure-alert-success {
146 background-color: $main-green; 152 background-color: var(--main-color);
147} 153}
148 154
149.pure-alert-warning { 155.pure-alert-warning {
@@ -169,7 +175,7 @@ body,
169 top: 0; 175 top: 0;
170 transition: max-height .5s; 176 transition: max-height .5s;
171 z-index: 999; 177 z-index: 999;
172 background: $main-green; 178 background: var(--main-color);
173 width: 100%; 179 width: 100%;
174 // Hack to transition with auto height: http://stackoverflow.com/a/8331169/1484919 180 // Hack to transition with auto height: http://stackoverflow.com/a/8331169/1484919
175 max-height: 45px; 181 max-height: 45px;
@@ -322,7 +328,7 @@ body,
322 button { 328 button {
323 border: 0; 329 border: 0;
324 border-radius: 2px; 330 border-radius: 2px;
325 background-color: $main-green; 331 background-color: var(--main-color);
326 padding: 4px 8px 6px; 332 padding: 4px 8px 6px;
327 color: $almost-white; 333 color: $almost-white;
328 } 334 }
@@ -358,7 +364,7 @@ body,
358.search-tagcloud { 364.search-tagcloud {
359 button { 365 button {
360 &:hover { 366 &:hover {
361 color: $background-color; 367 color: var(--background-color);
362 } 368 }
363 } 369 }
364} 370}
@@ -389,7 +395,7 @@ body,
389 position: fixed; 395 position: fixed;
390 visibility: hidden; 396 visibility: hidden;
391 z-index: 999; 397 z-index: 999;
392 background: $main-green; 398 background: var(--main-color);
393 padding: 5px 0; 399 padding: 5px 0;
394 width: 100%; 400 width: 100%;
395 height: 30px; 401 height: 30px;
@@ -411,7 +417,7 @@ body,
411 margin: 0 0 5px; 417 margin: 0 0 5px;
412 border: 1px solid $almost-white; 418 border: 1px solid $almost-white;
413 border-radius: 2px; 419 border-radius: 2px;
414 background: $main-green; 420 background: var(--main-color);
415 padding: 4px 0; 421 padding: 4px 0;
416 width: 100px; 422 width: 100px;
417 height: 28px; 423 height: 28px;
@@ -419,7 +425,7 @@ body,
419 425
420 &:hover { 426 &:hover {
421 background: $almost-white; 427 background: $almost-white;
422 color: $main-green; 428 color: var(--main-color);
423 } 429 }
424 } 430 }
425 431
@@ -558,7 +564,7 @@ body,
558 } 564 }
559 565
560 .filter-on { 566 .filter-on {
561 background: $main-green; 567 background: var(--main-color);
562 color: $light-green; 568 color: $light-green;
563 } 569 }
564 570
@@ -697,7 +703,7 @@ body,
697 703
698 &:visited { 704 &:visited {
699 .linklist-link { 705 .linklist-link {
700 color: $dark-green; 706 color: var(--dark-main-color);
701 } 707 }
702 } 708 }
703 709
@@ -708,7 +714,7 @@ body,
708 } 714 }
709 715
710 .linklist-link { 716 .linklist-link {
711 color: $main-green; 717 color: var(--main-color);
712 font-size: 1.1em; 718 font-size: 1.1em;
713 719
714 &:hover { 720 &:hover {
@@ -783,14 +789,14 @@ body,
783 789
784 a { 790 a {
785 text-decoration: none; 791 text-decoration: none;
786 color: $main-green; 792 color: var(--main-color);
787 793
788 &:hover { 794 &:hover {
789 color: $dark-grey; 795 color: $dark-grey;
790 } 796 }
791 797
792 &:visited { 798 &:visited {
793 color: $dark-green; 799 color: var(--dark-main-color);
794 } 800 }
795 } 801 }
796} 802}
@@ -888,7 +894,7 @@ body,
888 &::before { 894 &::before {
889 display: block; 895 display: block;
890 margin: 10px auto; 896 margin: 10px auto;
891 background: linear-gradient(to right, $background-color, $dark-grey, $background-color); 897 background: linear-gradient(to right, var(--background-color), $dark-grey, var(--background-color));
892 width: 80%; 898 width: 80%;
893 height: 1px; 899 height: 1px;
894 content: ''; 900 content: '';
@@ -917,7 +923,7 @@ body,
917 margin: 15px 5px; 923 margin: 15px 5px;
918 border: 0; 924 border: 0;
919 box-shadow: 1px 1px 1px $form-input-border, -1px -1px 6px $form-input-border, -1px 1px 2px $form-input-border, 1px -1px 2px $form-input-border; 925 box-shadow: 1px 1px 1px $form-input-border, -1px -1px 6px $form-input-border, -1px 1px 2px $form-input-border, 1px -1px 2px $form-input-border;
920 background: $main-green; 926 background: var(--main-color);
921 min-width: 150px; 927 min-width: 150px;
922 height: 35px; 928 height: 35px;
923 vertical-align: center; 929 vertical-align: center;
@@ -941,7 +947,7 @@ body,
941 padding: 10px 0; 947 padding: 10px 0;
942 width: 100%; 948 width: 100%;
943 text-align: center; 949 text-align: center;
944 color: $main-green; 950 color: var(--main-color);
945 } 951 }
946 952
947 .window-subtitle { 953 .window-subtitle {
@@ -950,7 +956,7 @@ body,
950 956
951 a { 957 a {
952 text-decoration: none; 958 text-decoration: none;
953 color: $main-green; 959 color: var(--main-color);
954 font-weight: bold; 960 font-weight: bold;
955 961
956 &.button { 962 &.button {
@@ -1278,7 +1284,7 @@ form {
1278 1284
1279 .pure-button { 1285 .pure-button {
1280 &:hover { 1286 &:hover {
1281 background-color: $main-green; 1287 background-color: var(--main-color);
1282 background-image: none; 1288 background-image: none;
1283 color: $almost-white; 1289 color: $almost-white;
1284 } 1290 }
@@ -1362,7 +1368,7 @@ form {
1362 } 1368 }
1363 1369
1364 .validate-rename-tag { 1370 .validate-rename-tag {
1365 color: $main-green; 1371 color: var(--main-color);
1366 } 1372 }
1367} 1373}
1368 1374
@@ -1458,7 +1464,7 @@ form {
1458 &::after { 1464 &::after {
1459 display: block; 1465 display: block;
1460 margin: 10px auto; 1466 margin: 10px auto;
1461 background: linear-gradient(to right, $background-color, $dark-grey, $background-color); 1467 background: linear-gradient(to right, var(--background-color), $dark-grey, var(--background-color));
1462 width: 90%; 1468 width: 90%;
1463 height: 1px; 1469 height: 1px;
1464 content: ''; 1470 content: '';
@@ -1508,14 +1514,14 @@ form {
1508.daily-entry-description { 1514.daily-entry-description {
1509 a { 1515 a {
1510 text-decoration: none; 1516 text-decoration: none;
1511 color: $main-green; 1517 color: var(--main-color);
1512 1518
1513 &:hover { 1519 &:hover {
1514 text-shadow: 1px 1px $background-linklist-info; 1520 text-shadow: 1px 1px $background-linklist-info;
1515 } 1521 }
1516 1522
1517 &:visited { 1523 &:visited {
1518 color: $dark-green; 1524 color: var(--dark-main-color);
1519 } 1525 }
1520 } 1526 }
1521} 1527}
@@ -1572,12 +1578,12 @@ form {
1572} 1578}
1573 1579
1574.pure-button-shaarli { 1580.pure-button-shaarli {
1575 background-color: $main-green; 1581 background-color: var(--main-color);
1576} 1582}
1577 1583
1578.progressbar { 1584.progressbar {
1579 border-radius: 6px; 1585 border-radius: 6px;
1580 background-color: $main-green; 1586 background-color: var(--main-color);
1581 padding: 1px; 1587 padding: 1px;
1582 1588
1583 > div { 1589 > div {
@@ -1586,8 +1592,8 @@ form {
1586 -45deg, 1592 -45deg,
1587 $almost-white, 1593 $almost-white,
1588 $almost-white 6px, 1594 $almost-white 6px,
1589 $background-color 6px, 1595 var(--background-color) 6px,
1590 $background-color 12px 1596 var(--background-color) 12px
1591 ); 1597 );
1592 width: 0%; 1598 width: 0%;
1593 height: 10px; 1599 height: 10px;
diff --git a/doc/md/Plugin-System.md b/doc/md/Plugin-System.md
index cbec04c0..9b0d3a7d 100644
--- a/doc/md/Plugin-System.md
+++ b/doc/md/Plugin-System.md
@@ -137,6 +137,7 @@ If it's still not working, please [open an issue](https://github.com/shaarli/Sha
137| [render_feed](#render_feed) | Allow to do add tags in RSS and ATOM feeds. | 137| [render_feed](#render_feed) | Allow to do add tags in RSS and ATOM feeds. |
138| [save_link](#save_link) | Allow to alter the link being saved in the datastore. | 138| [save_link](#save_link) | Allow to alter the link being saved in the datastore. |
139| [delete_link](#delete_link) | Allow to do an action before a link is deleted from the datastore. | 139| [delete_link](#delete_link) | Allow to do an action before a link is deleted from the datastore. |
140| [save_plugin_parameters](#save_plugin_parameters) | Allow to manipulate plugin parameters before they're saved. |
140 141
141 142
142 143
@@ -471,6 +472,22 @@ Allow to execute any action before the link is actually removed from the datasto
471- created 472- created
472- updated 473- updated
473 474
475
476#### save_plugin_parameters
477
478Triggered when the plugin parameters are saved from the plugin administration page.
479
480Plugins can perform an action every times their settings are updated.
481For example it is used to update the CSS file of the `default_colors` plugins.
482
483##### Data
484
485`$data` input contains the `$_POST` array.
486
487So if the plugin has a parameter called `MYPLUGIN_PARAMETER`,
488the array will contain an entry with `MYPLUGIN_PARAMETER` as a key.
489
490
474## Guide for template designer 491## Guide for template designer
475 492
476### Plugin administration 493### Plugin administration
diff --git a/doc/md/Plugins.md b/doc/md/Plugins.md
index 954442e2..3e261815 100644
--- a/doc/md/Plugins.md
+++ b/doc/md/Plugins.md
@@ -63,8 +63,12 @@ Usage of each plugin is documented in it's README file:
63 63
64 * `addlink-toolbar`: Adds the addlink input on the linklist page 64 * `addlink-toolbar`: Adds the addlink input on the linklist page
65 * `archiveorg`: For each link, add an Archive.org icon 65 * `archiveorg`: For each link, add an Archive.org icon
66 * `default_colors`: Override default theme colors.
67 * `isso`: Let visitor comment your shaares on permalinks with Isso.
66 * [`markdown`](https://github.com/shaarli/Shaarli/blob/master/plugins/markdown/README.md): Render shaare description with Markdown syntax. 68 * [`markdown`](https://github.com/shaarli/Shaarli/blob/master/plugins/markdown/README.md): Render shaare description with Markdown syntax.
69 * `piwik`: A plugin that adds Piwik tracking code to Shaarli pages.
67 * [`playvideos`](https://github.com/shaarli/Shaarli/blob/master/plugins/playvideos/README.md): Add a button in the toolbar allowing to watch all videos. 70 * [`playvideos`](https://github.com/shaarli/Shaarli/blob/master/plugins/playvideos/README.md): Add a button in the toolbar allowing to watch all videos.
71 * `pubsubhubbub`: Enable PubSubHubbub feed publishing
68 * `qrcode`: For each link, add a QRCode icon. 72 * `qrcode`: For each link, add a QRCode icon.
69 * [`wallabag`](https://github.com/shaarli/Shaarli/blob/master/plugins/wallabag/README.md): For each link, add a Wallabag icon to save it in your instance. 73 * [`wallabag`](https://github.com/shaarli/Shaarli/blob/master/plugins/wallabag/README.md): For each link, add a Wallabag icon to save it in your instance.
70 74
diff --git a/inc/languages/fr/LC_MESSAGES/shaarli.po b/inc/languages/fr/LC_MESSAGES/shaarli.po
index 611296f1..026d0101 100644
--- a/inc/languages/fr/LC_MESSAGES/shaarli.po
+++ b/inc/languages/fr/LC_MESSAGES/shaarli.po
@@ -1,8 +1,8 @@
1msgid "" 1msgid ""
2msgstr "" 2msgstr ""
3"Project-Id-Version: Shaarli\n" 3"Project-Id-Version: Shaarli\n"
4"POT-Creation-Date: 2019-07-06 12:14+0200\n" 4"POT-Creation-Date: 2019-07-13 10:45+0200\n"
5"PO-Revision-Date: 2019-07-06 12:17+0200\n" 5"PO-Revision-Date: 2019-07-13 10:49+0200\n"
6"Last-Translator: \n" 6"Last-Translator: \n"
7"Language-Team: Shaarli\n" 7"Language-Team: Shaarli\n"
8"Language: fr_FR\n" 8"Language: fr_FR\n"
@@ -403,7 +403,7 @@ msgstr "Note : "
403 403
404#: index.php:1424 404#: index.php:1424
405msgid "Invalid link ID provided" 405msgid "Invalid link ID provided"
406msgstr "" 406msgstr "ID du lien non valide"
407 407
408#: index.php:1444 tmp/export.b91ef64efc3688266305ea9b42e5017e.rtpl.php:65 408#: index.php:1444 tmp/export.b91ef64efc3688266305ea9b42e5017e.rtpl.php:65
409msgid "Export" 409msgid "Export"
@@ -428,15 +428,15 @@ msgstr ""
428msgid "Plugin administration" 428msgid "Plugin administration"
429msgstr "Administration des plugins" 429msgstr "Administration des plugins"
430 430
431#: index.php:1615 tmp/thumbnails.b91ef64efc3688266305ea9b42e5017e.rtpl.php:14 431#: index.php:1616 tmp/thumbnails.b91ef64efc3688266305ea9b42e5017e.rtpl.php:14
432msgid "Thumbnails update" 432msgid "Thumbnails update"
433msgstr "Mise à jour des miniatures" 433msgstr "Mise à jour des miniatures"
434 434
435#: index.php:1781 435#: index.php:1782
436msgid "Search: " 436msgid "Search: "
437msgstr "Recherche : " 437msgstr "Recherche : "
438 438
439#: index.php:1824 439#: index.php:1825
440#, php-format 440#, php-format
441msgid "" 441msgid ""
442"<pre>Sessions do not seem to work correctly on your server.<br>Make sure the " 442"<pre>Sessions do not seem to work correctly on your server.<br>Make sure the "
@@ -455,7 +455,7 @@ msgstr ""
455"des cookies. Nous vous recommandons d'accéder à votre serveur depuis son " 455"des cookies. Nous vous recommandons d'accéder à votre serveur depuis son "
456"adresse IP ou un <em>Fully Qualified Domain Name</em>.<br>" 456"adresse IP ou un <em>Fully Qualified Domain Name</em>.<br>"
457 457
458#: index.php:1834 458#: index.php:1835
459msgid "Click to try again." 459msgid "Click to try again."
460msgstr "Cliquer ici pour réessayer." 460msgstr "Cliquer ici pour réessayer."
461 461
@@ -480,7 +480,33 @@ msgstr "Voir sur archive.org"
480msgid "For each link, add an Archive.org icon." 480msgid "For each link, add an Archive.org icon."
481msgstr "Pour chaque lien, ajoute une icône pour Archive.org." 481msgstr "Pour chaque lien, ajoute une icône pour Archive.org."
482 482
483#: plugins/demo_plugin/demo_plugin.php:465 483#: plugins/default_colors/default_colors.php:33
484msgid ""
485"Default colors plugin error: This plugin is active and no custom color is "
486"configured."
487msgstr ""
488"Erreur du plugin default colors : ce plugin est actif et aucune couleur "
489"n'est configurée."
490
491#: plugins/default_colors/default_colors.php:107
492msgid "Override default theme colors. Use any CSS valid color."
493msgstr ""
494"Remplacer les couleurs du thème par défaut. Utiliser n'importe quelle "
495"couleur CSS valide."
496
497#: plugins/default_colors/default_colors.php:108
498msgid "Main color (navbar green)"
499msgstr "Couleur principale (vert de la barre de navigation)"
500
501#: plugins/default_colors/default_colors.php:109
502msgid "Background color (light grey)"
503msgstr "Couleur de fond (gris léger)"
504
505#: plugins/default_colors/default_colors.php:110
506msgid "Dark main color (e.g. visited links)"
507msgstr "Couleur principale sombre (ex : les liens visités)"
508
509#: plugins/demo_plugin/demo_plugin.php:482
484msgid "" 510msgid ""
485"A demo plugin covering all use cases for template designers and plugin " 511"A demo plugin covering all use cases for template designers and plugin "
486"developers." 512"developers."
@@ -488,6 +514,14 @@ msgstr ""
488"Une extension de démonstration couvrant tous les cas d'utilisation pour les " 514"Une extension de démonstration couvrant tous les cas d'utilisation pour les "
489"designers de thèmes et les développeurs d'extensions." 515"designers de thèmes et les développeurs d'extensions."
490 516
517#: plugins/demo_plugin/demo_plugin.php:483
518msgid "This is a parameter dedicated to the demo plugin. It'll be suffixed."
519msgstr "Ceci est un paramètre dédié au plugin de démo. Il sera suffixé."
520
521#: plugins/demo_plugin/demo_plugin.php:484
522msgid "Other demo parameter"
523msgstr "Un autre paramètre de démo"
524
491#: plugins/isso/isso.php:22 525#: plugins/isso/isso.php:22
492msgid "" 526msgid ""
493"Isso plugin error: Please define the \"ISSO_SERVER\" setting in the plugin " 527"Isso plugin error: Please define the \"ISSO_SERVER\" setting in the plugin "
@@ -703,9 +737,8 @@ msgstr ""
703"miniatures." 737"miniatures."
704 738
705#: tmp/configure.90100d2eaf5d3705e14b9b4f78ecddc9.rtpl.php:162 739#: tmp/configure.90100d2eaf5d3705e14b9b4f78ecddc9.rtpl.php:162
706#| msgid "Enable thumbnails"
707msgid "Synchonize thumbnails" 740msgid "Synchonize thumbnails"
708msgstr "" 741msgstr "Synchroniser les miniatures"
709 742
710#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:29 743#: tmp/configure.b91ef64efc3688266305ea9b42e5017e.rtpl.php:29
711msgid "title" 744msgid "title"
diff --git a/index.php b/index.php
index 957d8d9a..f0f71dbb 100644
--- a/index.php
+++ b/index.php
@@ -1567,6 +1567,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager,
1567 if ($targetPage == Router::$PAGE_SAVE_PLUGINSADMIN) { 1567 if ($targetPage == Router::$PAGE_SAVE_PLUGINSADMIN) {
1568 try { 1568 try {
1569 if (isset($_POST['parameters_form'])) { 1569 if (isset($_POST['parameters_form'])) {
1570 $pluginManager->executeHooks('save_plugin_parameters', $_POST);
1570 unset($_POST['parameters_form']); 1571 unset($_POST['parameters_form']);
1571 foreach ($_POST as $param => $value) { 1572 foreach ($_POST as $param => $value) {
1572 $conf->set('plugins.'. $param, escape($value)); 1573 $conf->set('plugins.'. $param, escape($value));
diff --git a/plugins/default_colors/default_colors.css.template b/plugins/default_colors/default_colors.css.template
new file mode 100644
index 00000000..87e22a08
--- /dev/null
+++ b/plugins/default_colors/default_colors.css.template
@@ -0,0 +1,3 @@
1:root {
2%s
3}
diff --git a/plugins/default_colors/default_colors.meta b/plugins/default_colors/default_colors.meta
new file mode 100644
index 00000000..108962c6
--- /dev/null
+++ b/plugins/default_colors/default_colors.meta
@@ -0,0 +1,5 @@
1description="Override default theme colors. Use any CSS valid color."
2parameters="DEFAULT_COLORS_MAIN;DEFAULT_COLORS_BACKGROUND;DEFAULT_COLORS_DARK_MAIN"
3parameter.DEFAULT_COLORS_MAIN="Main color (navbar green)"
4parameter.DEFAULT_COLORS_BACKGROUND="Background color (light grey)"
5parameter.DEFAULT_COLORS_DARK_MAIN="Dark main color (e.g. visited links)"
diff --git a/plugins/default_colors/default_colors.php b/plugins/default_colors/default_colors.php
new file mode 100644
index 00000000..1928cc9f
--- /dev/null
+++ b/plugins/default_colors/default_colors.php
@@ -0,0 +1,111 @@
1<?php
2
3/**
4 * Plugin default_colors.
5 *
6 * Allow users to easily overrides colors of the default theme.
7 */
8
9use Shaarli\Config\ConfigManager;
10use Shaarli\Plugin\PluginManager;
11
12const DEFAULT_COLORS_PLACEHOLDERS = [
13 'DEFAULT_COLORS_MAIN',
14 'DEFAULT_COLORS_BACKGROUND',
15 'DEFAULT_COLORS_DARK_MAIN',
16];
17
18/**
19 * Display an error if the plugin is active a no color is configured.
20 *
21 * @param $conf ConfigManager instance
22 *
23 * @return array|null The errors array or null of there is none.
24 */
25function default_colors_init($conf)
26{
27 $params = '';
28 foreach (DEFAULT_COLORS_PLACEHOLDERS as $placeholder) {
29 $params .= trim($conf->get('plugins.'. $placeholder, ''));
30 }
31
32 if (empty($params)) {
33 $error = t('Default colors plugin error: '.
34 'This plugin is active and no custom color is configured.');
35 return array($error);
36 }
37}
38
39/**
40 * When plugin parameters are saved, we regenerate the custom CSS file with provided settings.
41 *
42 * @param array $data $_POST array
43 *
44 * @return array Updated $_POST array
45 */
46function hook_default_colors_save_plugin_parameters($data)
47{
48 $file = PluginManager::$PLUGINS_PATH . '/default_colors/default_colors.css';
49 $template = file_get_contents(PluginManager::$PLUGINS_PATH . '/default_colors/default_colors.css.template');
50 $content = '';
51 foreach (DEFAULT_COLORS_PLACEHOLDERS as $rule) {
52 $content .= ! empty($data[$rule])
53 ? default_colors_format_css_rule($data, $rule) .';'. PHP_EOL
54 : '';
55 }
56
57 if (! empty($content)) {
58 file_put_contents($file, sprintf($template, $content));
59 }
60
61 return $data;
62}
63
64/**
65 * When linklist is displayed, include default_colors CSS file.
66 *
67 * @param array $data - header data.
68 *
69 * @return mixed - header data with default_colors CSS file added.
70 */
71function hook_default_colors_render_includes($data)
72{
73 $file = PluginManager::$PLUGINS_PATH . '/default_colors/default_colors.css';
74 if (file_exists($file )) {
75 $data['css_files'][] = $file ;
76 }
77
78 return $data;
79}
80
81/**
82 * Create a valid CSS rule from parameters settings and plugin parameter.
83 *
84 * @param array $data $_POST array
85 * @param string $parameter Plugin parameter name
86 *
87 * @return string CSS rules for the provided parameter and its matching value.
88 */
89function default_colors_format_css_rule($data, $parameter)
90{
91 if (empty($data[$parameter])) {
92 return '';
93 }
94
95 $key = str_replace('DEFAULT_COLORS_', '', $parameter);
96 $key = str_replace('_', '-', strtolower($key)) .'-color';
97 return ' --'. $key .': '. $data[$parameter];
98}
99
100
101/**
102 * This function is never called, but contains translation calls for GNU gettext extraction.
103 */
104function default_colors_translation()
105{
106 // meta
107 t('Override default theme colors. Use any CSS valid color.');
108 t('Main color (navbar green)');
109 t('Background color (light grey)');
110 t('Dark main color (e.g. visited links)');
111}
diff --git a/plugins/demo_plugin/demo_plugin.meta b/plugins/demo_plugin/demo_plugin.meta
index b063ecb7..cd616441 100644
--- a/plugins/demo_plugin/demo_plugin.meta
+++ b/plugins/demo_plugin/demo_plugin.meta
@@ -1 +1,4 @@
1description="A demo plugin covering all use cases for template designers and plugin developers." 1description="A demo plugin covering all use cases for template designers and plugin developers."
2parameters="DEMO_PLUGIN_PARAMETER;DEMO_PLUGIN_OTHER_PARAMETER"
3parameter.DEMO_PLUGIN_PARAMETER="This is a parameter dedicated to the demo plugin. It'll be suffixed."
4parameter.DEMO_PLUGIN_OTHER_PARAMETER="Other demo parameter"
diff --git a/plugins/demo_plugin/demo_plugin.php b/plugins/demo_plugin/demo_plugin.php
index 95ea7fe2..71ba7495 100644
--- a/plugins/demo_plugin/demo_plugin.php
+++ b/plugins/demo_plugin/demo_plugin.php
@@ -457,10 +457,29 @@ function hook_demo_plugin_render_feed($data)
457} 457}
458 458
459/** 459/**
460 * When plugin parameters are saved.
461 *
462 * @param array $data $_POST array
463 *
464 * @return array Updated $_POST array
465 */
466function hook_demo_plugin_save_plugin_parameters($data)
467{
468 // Here we edit the provided value, but we can use this to generate config files, etc.
469 if (! empty($data['DEMO_PLUGIN_PARAMETER']) && ! endsWith($data['DEMO_PLUGIN_PARAMETER'], '_SUFFIX')) {
470 $data['DEMO_PLUGIN_PARAMETER'] .= '_SUFFIX';
471 }
472
473 return $data;
474}
475
476/**
460 * This function is never called, but contains translation calls for GNU gettext extraction. 477 * This function is never called, but contains translation calls for GNU gettext extraction.
461 */ 478 */
462function demo_dummy_translation() 479function demo_dummy_translation()
463{ 480{
464 // meta 481 // meta
465 t('A demo plugin covering all use cases for template designers and plugin developers.'); 482 t('A demo plugin covering all use cases for template designers and plugin developers.');
483 t('This is a parameter dedicated to the demo plugin. It\'ll be suffixed.');
484 t('Other demo parameter');
466} 485}
diff --git a/tests/plugins/PluginDefaultColorsTest.php b/tests/plugins/PluginDefaultColorsTest.php
new file mode 100644
index 00000000..b9951cca
--- /dev/null
+++ b/tests/plugins/PluginDefaultColorsTest.php
@@ -0,0 +1,195 @@
1<?php
2
3namespace Shaarli\Plugin\DefaultColors;
4
5use DateTime;
6use PHPUnit\Framework\TestCase;
7use Shaarli\Bookmark\LinkDB;
8use Shaarli\Config\ConfigManager;
9use Shaarli\Plugin\PluginManager;
10
11require_once 'plugins/default_colors/default_colors.php';
12
13/**
14 * Class PluginDefaultColorsTest
15 *
16 * Test the DefaultColors plugin (allowing to override default template colors).
17 */
18class PluginDefaultColorsTest extends TestCase
19{
20 /**
21 * Reset plugin path
22 */
23 public function setUp()
24 {
25 PluginManager::$PLUGINS_PATH = 'sandbox';
26 mkdir(PluginManager::$PLUGINS_PATH . '/default_colors/');
27 copy(
28 'plugins/default_colors/default_colors.css.template',
29 PluginManager::$PLUGINS_PATH . '/default_colors/default_colors.css.template'
30 );
31 }
32
33 /**
34 * Remove sandbox files and folder
35 */
36 public function tearDown()
37 {
38 if (file_exists('sandbox/default_colors/default_colors.css.template')) {
39 unlink('sandbox/default_colors/default_colors.css.template');
40 }
41
42 if (file_exists('sandbox/default_colors/default_colors.css')) {
43 unlink('sandbox/default_colors/default_colors.css');
44 }
45
46 if (is_dir('sandbox/default_colors')) {
47 rmdir('sandbox/default_colors');
48 }
49 }
50
51 /**
52 * Test DefaultColors init without errors.
53 */
54 public function testDefaultColorsInitNoError()
55 {
56 $conf = new ConfigManager('');
57 $conf->set('plugins.DEFAULT_COLORS_BACKGROUND', 'value');
58 $errors = default_colors_init($conf);
59 $this->assertEmpty($errors);
60 }
61
62 /**
63 * Test DefaultColors init with errors.
64 */
65 public function testDefaultColorsInitError()
66 {
67 $conf = new ConfigManager('');
68 $errors = default_colors_init($conf);
69 $this->assertNotEmpty($errors);
70 }
71
72 /**
73 * Test the save plugin parameters hook with all colors specified.
74 */
75 public function testSavePluginParametersAll()
76 {
77 $post = [
78 'other1' => true,
79 'DEFAULT_COLORS_MAIN' => 'blue',
80 'DEFAULT_COLORS_BACKGROUND' => 'pink',
81 'other2' => ['yep'],
82 'DEFAULT_COLORS_DARK_MAIN' => 'green',
83 ];
84
85 hook_default_colors_save_plugin_parameters($post);
86 $this->assertFileExists($file = 'sandbox/default_colors/default_colors.css');
87 $content = file_get_contents($file);
88 $expected = ':root {
89 --main-color: blue;
90 --background-color: pink;
91 --dark-main-color: green;
92
93}
94';
95 $this->assertEquals($expected, $content);
96 }
97
98 /**
99 * Test the save plugin parameters hook with only one color specified.
100 */
101 public function testSavePluginParametersSingle()
102 {
103 $post = [
104 'other1' => true,
105 'DEFAULT_COLORS_BACKGROUND' => 'pink',
106 'other2' => ['yep'],
107 'DEFAULT_COLORS_DARK_MAIN' => '',
108 ];
109
110 hook_default_colors_save_plugin_parameters($post);
111 $this->assertFileExists($file = 'sandbox/default_colors/default_colors.css');
112 $content = file_get_contents($file);
113 $expected = ':root {
114 --background-color: pink;
115
116}
117';
118 $this->assertEquals($expected, $content);
119 }
120
121 /**
122 * Test the save plugin parameters hook with no color specified.
123 */
124 public function testSavePluginParametersNone()
125 {
126 hook_default_colors_save_plugin_parameters([]);
127 $this->assertFileNotExists($file = 'sandbox/default_colors/default_colors.css');
128 }
129
130 /**
131 * Make sure that the CSS is properly included by the include hook.
132 */
133 public function testIncludeWithFile()
134 {
135 $data = [
136 'css_files' => ['file1'],
137 'js_files' => ['file2'],
138 ];
139 touch($file = 'sandbox/default_colors/default_colors.css');
140 $processedData = hook_default_colors_render_includes($data);
141
142 $this->assertCount(2, $processedData['css_files']);
143 $this->assertEquals($file, $processedData['css_files'][1]);
144 $this->assertCount(1, $processedData['js_files']);
145 }
146
147 /**
148 * Make sure that the CSS is not included by the include hook if the CSS file does not exist.
149 */
150 public function testIncludeWithoutFile()
151 {
152 $data = [
153 'css_files' => ['file1'],
154 'js_files' => ['file2'],
155 ];
156 $processedData = hook_default_colors_render_includes($data);
157
158 $this->assertEquals($data, $processedData);
159 }
160
161 /**
162 * Test helper function which generates CSS rules with valid input.
163 */
164 public function testFormatCssRuleValid()
165 {
166 $data = [
167 'other1' => true,
168 'DEFAULT_COLORS_BLIP_BLOP' => 'shinyColor',
169 'other2' => ['yep'],
170 ];
171 $result = default_colors_format_css_rule($data, 'DEFAULT_COLORS_BLIP_BLOP');
172 $this->assertEquals(' --blip-blop-color: shinyColor', $result);
173
174 $data = ['unknown-parameter' => true];
175 $result = default_colors_format_css_rule($data, 'unknown-parameter');
176 $this->assertEquals(' --unknown-parameter-color: 1', $result);
177 }
178
179 /**
180 * Test helper function which generates CSS rules with invalid input.
181 */
182 public function testFormatCssRuleInvalid()
183 {
184 $result = default_colors_format_css_rule([], 'DEFAULT_COLORS_BLIP_BLOP');
185 $this->assertEmpty($result);
186
187 $data = [
188 'other1' => true,
189 'DEFAULT_COLORS_BLIP_BLOP' => 'shinyColor',
190 'other2' => ['yep'],
191 ];
192 $result = default_colors_format_css_rule($data, '');
193 $this->assertEmpty($result);
194 }
195}