IconsCacher.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2018, John Molakvoæ (skjnldsv@protonmail.com)
  4. *
  5. * @author John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
  6. *
  7. * @license GNU AGPL version 3 or any later version
  8. *
  9. * This program is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU Affero General Public License as
  11. * published by the Free Software Foundation, either version 3 of the
  12. * License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU Affero General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Affero General Public License
  20. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. *
  22. */
  23. namespace OC\Template;
  24. use OCP\Files\IAppData;
  25. use OCP\Files\NotFoundException;
  26. use OCP\Files\SimpleFS\ISimpleFolder;
  27. use OCP\Files\SimpleFS\ISimpleFile;
  28. use OCP\ILogger;
  29. use OCP\IURLGenerator;
  30. use OC\Files\AppData\Factory;
  31. class IconsCacher {
  32. /** @var ILogger */
  33. protected $logger;
  34. /** @var IAppData */
  35. protected $appData;
  36. /** @var ISimpleFolder */
  37. private $folder;
  38. /** @var IURLGenerator */
  39. protected $urlGenerator;
  40. /** @var string */
  41. private $iconVarRE = '/--(icon-[a-z0-9-]+): url\(["\']([a-z0-9-\/]+)[^;]+;/m';
  42. /** @var string */
  43. private $fileName = 'icons-vars.css';
  44. /**
  45. * @param ILogger $logger
  46. * @param Factory $appDataFactory
  47. * @param IURLGenerator $urlGenerator
  48. */
  49. public function __construct(ILogger $logger,
  50. Factory $appDataFactory,
  51. IURLGenerator $urlGenerator) {
  52. $this->logger = $logger;
  53. $this->appData = $appDataFactory->get('css');
  54. $this->urlGenerator = $urlGenerator;
  55. try {
  56. $this->folder = $this->appData->getFolder('icons');
  57. } catch (NotFoundException $e) {
  58. $this->folder = $this->appData->newFolder('icons');
  59. }
  60. }
  61. private function getIconsFromCss(string $css): array{
  62. preg_match_all($this->iconVarRE, $css, $matches, PREG_SET_ORDER);
  63. $icons = [];
  64. foreach ($matches as $icon) {
  65. $icons[$icon[1]] = $icon[2];
  66. }
  67. return $icons;
  68. }
  69. /**
  70. * Parse and cache css
  71. *
  72. * @param string $css
  73. */
  74. public function setIconsCss(string $css) {
  75. $cachedFile = $this->getCachedCSS();
  76. if (!$cachedFile) {
  77. $currentData = '';
  78. } else {
  79. $currentData = $cachedFile->getContent();
  80. }
  81. // remove :root
  82. $currentData = str_replace([':root {', '}'], '', $currentData);
  83. $icons = $this->getIconsFromCss($currentData . $css);
  84. $data = '';
  85. foreach ($icons as $icon => $url) {
  86. $data .= "--$icon: url('$url?v=1');";
  87. }
  88. if (strlen($data) > 0) {
  89. if (!$cachedFile) {
  90. $cachedFile = $this->folder->newFile($this->fileName);
  91. }
  92. $data = ":root {
  93. $data
  94. }";
  95. $cachedFile->putContent($data);
  96. }
  97. return preg_replace($this->iconVarRE, '', $css);
  98. }
  99. /**
  100. * Get icons css file
  101. * @return ISimpleFile|boolean
  102. */
  103. public function getCachedCSS() {
  104. try {
  105. return $this->folder->getFile($this->fileName);
  106. } catch (NotFoundException $e) {
  107. return false;
  108. }
  109. }
  110. public function injectCss() {
  111. // Only inject once
  112. foreach (\OC_Util::$headers as $header) {
  113. if (
  114. array_key_exists('attributes', $header) &&
  115. array_key_exists('href', $header['attributes']) &&
  116. strpos($header['attributes']['href'], $this->fileName) !== false) {
  117. return;
  118. }
  119. }
  120. $linkToCSS = substr($this->urlGenerator->linkToRoute('core.Css.getCss', ['appName' => 'icons', 'fileName' => $this->fileName]), strlen(\OC::$WEBROOT));
  121. \OC_Util::addHeader('link', ['rel' => 'stylesheet', 'href' => $linkToCSS], null, true);
  122. }
  123. }