Util.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
  4. *
  5. * @author Christoph Wurst <christoph@winzerhof-wurst.at>
  6. * @author Daniel Kesselberg <mail@danielkesselberg.de>
  7. * @author Joas Schilling <coding@schilljs.com>
  8. * @author Julien Veyssier <eneiluj@posteo.net>
  9. * @author Julius Haertl <jus@bitgrid.net>
  10. * @author Julius Härtl <jus@bitgrid.net>
  11. * @author Michael Weimann <mail@michael-weimann.eu>
  12. *
  13. * @license GNU AGPL version 3 or any later version
  14. *
  15. * This program is free software: you can redistribute it and/or modify
  16. * it under the terms of the GNU Affero General Public License as
  17. * published by the Free Software Foundation, either version 3 of the
  18. * License, or (at your option) any later version.
  19. *
  20. * This program is distributed in the hope that it will be useful,
  21. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23. * GNU Affero General Public License for more details.
  24. *
  25. * You should have received a copy of the GNU Affero General Public License
  26. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  27. *
  28. */
  29. namespace OCA\Theming;
  30. use OCP\App\AppPathNotFoundException;
  31. use OCP\App\IAppManager;
  32. use OCP\Files\IAppData;
  33. use OCP\Files\NotFoundException;
  34. use OCP\Files\SimpleFS\ISimpleFile;
  35. use OCP\IConfig;
  36. use ScssPhp\ScssPhp\Compiler;
  37. class Util {
  38. /** @var IConfig */
  39. private $config;
  40. /** @var IAppManager */
  41. private $appManager;
  42. /** @var IAppData */
  43. private $appData;
  44. /**
  45. * Util constructor.
  46. *
  47. * @param IConfig $config
  48. * @param IAppManager $appManager
  49. * @param IAppData $appData
  50. */
  51. public function __construct(IConfig $config, IAppManager $appManager, IAppData $appData) {
  52. $this->config = $config;
  53. $this->appManager = $appManager;
  54. $this->appData = $appData;
  55. }
  56. /**
  57. * @param string $color rgb color value
  58. * @return bool
  59. */
  60. public function invertTextColor($color) {
  61. $l = $this->calculateLuma($color);
  62. if ($l > 0.6) {
  63. return true;
  64. } else {
  65. return false;
  66. }
  67. }
  68. /**
  69. * get color for on-page elements:
  70. * theme color by default, grey if theme color is to bright
  71. * @param string $color
  72. * @param bool $brightBackground
  73. * @return string
  74. */
  75. public function elementColor($color, bool $brightBackground = true) {
  76. $luminance = $this->calculateLuminance($color);
  77. if ($brightBackground && $luminance > 0.8) {
  78. // If the color is too bright in bright mode, we fall back to a darker gray
  79. return '#aaaaaa';
  80. }
  81. if (!$brightBackground && $luminance < 0.2) {
  82. // If the color is too dark in dark mode, we fall back to a brighter gray
  83. return '#555555';
  84. }
  85. return $color;
  86. }
  87. /**
  88. * @param string $color rgb color value
  89. * @return float
  90. */
  91. public function calculateLuminance($color) {
  92. list($red, $green, $blue) = $this->hexToRGB($color);
  93. $compiler = new Compiler();
  94. $hsl = $compiler->toHSL($red, $green, $blue);
  95. return $hsl[3] / 100;
  96. }
  97. /**
  98. * @param string $color rgb color value
  99. * @return float
  100. */
  101. public function calculateLuma($color) {
  102. list($red, $green, $blue) = $this->hexToRGB($color);
  103. return (0.2126 * $red + 0.7152 * $green + 0.0722 * $blue) / 255;
  104. }
  105. /**
  106. * @param string $color rgb color value
  107. * @return int[]
  108. */
  109. public function hexToRGB($color) {
  110. $hex = preg_replace("/[^0-9A-Fa-f]/", '', $color);
  111. if (strlen($hex) === 3) {
  112. $hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2];
  113. }
  114. if (strlen($hex) !== 6) {
  115. return 0;
  116. }
  117. return [
  118. hexdec(substr($hex, 0, 2)),
  119. hexdec(substr($hex, 2, 2)),
  120. hexdec(substr($hex, 4, 2))
  121. ];
  122. }
  123. /**
  124. * @param $color
  125. * @return string base64 encoded radio button svg
  126. */
  127. public function generateRadioButton($color) {
  128. $radioButtonIcon = '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16">' .
  129. '<path d="M8 1a7 7 0 0 0-7 7 7 7 0 0 0 7 7 7 7 0 0 0 7-7 7 7 0 0 0-7-7zm0 1a6 6 0 0 1 6 6 6 6 0 0 1-6 6 6 6 0 0 1-6-6 6 6 0 0 1 6-6zm0 2a4 4 0 1 0 0 8 4 4 0 0 0 0-8z" fill="'.$color.'"/></svg>';
  130. return base64_encode($radioButtonIcon);
  131. }
  132. /**
  133. * @param $app string app name
  134. * @return string|ISimpleFile path to app icon / file of logo
  135. */
  136. public function getAppIcon($app) {
  137. $app = str_replace(['\0', '/', '\\', '..'], '', $app);
  138. try {
  139. $appPath = $this->appManager->getAppPath($app);
  140. $icon = $appPath . '/img/' . $app . '.svg';
  141. if (file_exists($icon)) {
  142. return $icon;
  143. }
  144. $icon = $appPath . '/img/app.svg';
  145. if (file_exists($icon)) {
  146. return $icon;
  147. }
  148. } catch (AppPathNotFoundException $e) {
  149. }
  150. if ($this->config->getAppValue('theming', 'logoMime', '') !== '') {
  151. $logoFile = null;
  152. try {
  153. $folder = $this->appData->getFolder('images');
  154. if ($folder !== null) {
  155. return $folder->getFile('logo');
  156. }
  157. } catch (NotFoundException $e) {
  158. }
  159. }
  160. return \OC::$SERVERROOT . '/core/img/logo/logo.svg';
  161. }
  162. /**
  163. * @param $app string app name
  164. * @param $image string relative path to image in app folder
  165. * @return string|false absolute path to image
  166. */
  167. public function getAppImage($app, $image) {
  168. $app = str_replace(['\0', '/', '\\', '..'], '', $app);
  169. $image = str_replace(['\0', '\\', '..'], '', $image);
  170. if ($app === "core") {
  171. $icon = \OC::$SERVERROOT . '/core/img/' . $image;
  172. if (file_exists($icon)) {
  173. return $icon;
  174. }
  175. }
  176. try {
  177. $appPath = $this->appManager->getAppPath($app);
  178. } catch (AppPathNotFoundException $e) {
  179. return false;
  180. }
  181. $icon = $appPath . '/img/' . $image;
  182. if (file_exists($icon)) {
  183. return $icon;
  184. }
  185. $icon = $appPath . '/img/' . $image . '.svg';
  186. if (file_exists($icon)) {
  187. return $icon;
  188. }
  189. $icon = $appPath . '/img/' . $image . '.png';
  190. if (file_exists($icon)) {
  191. return $icon;
  192. }
  193. $icon = $appPath . '/img/' . $image . '.gif';
  194. if (file_exists($icon)) {
  195. return $icon;
  196. }
  197. $icon = $appPath . '/img/' . $image . '.jpg';
  198. if (file_exists($icon)) {
  199. return $icon;
  200. }
  201. return false;
  202. }
  203. /**
  204. * replace default color with a custom one
  205. *
  206. * @param $svg string content of a svg file
  207. * @param $color string color to match
  208. * @return string
  209. */
  210. public function colorizeSvg($svg, $color) {
  211. $svg = preg_replace('/#0082c9/i', $color, $svg);
  212. return $svg;
  213. }
  214. /**
  215. * Check if a custom theme is set in the server configuration
  216. *
  217. * @return bool
  218. */
  219. public function isAlreadyThemed() {
  220. $theme = $this->config->getSystemValue('theme', '');
  221. if ($theme !== '') {
  222. return true;
  223. }
  224. return false;
  225. }
  226. public function isBackgroundThemed() {
  227. $backgroundLogo = $this->config->getAppValue('theming', 'backgroundMime', '');
  228. return $backgroundLogo !== '' && $backgroundLogo !== 'backgroundColor';
  229. }
  230. }