themingcontroller.php 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016 Bjoern Schiessle <bjoern@schiessle.org>
  4. * @copyright Copyright (c) 2016 Lukas Reschke <lukas@statuscode.ch>
  5. *
  6. * @author Bjoern Schiessle <bjoern@schiessle.org>
  7. * @author Julius Haertl <jus@bitgrid.net>
  8. * @author Lukas Reschke <lukas@statuscode.ch>
  9. * @author oparoz <owncloud@interfasys.ch>
  10. *
  11. * @license GNU AGPL version 3 or any later version
  12. *
  13. * This program is free software: you can redistribute it and/or modify
  14. * it under the terms of the GNU Affero General Public License as
  15. * published by the Free Software Foundation, either version 3 of the
  16. * License, or (at your option) any later version.
  17. *
  18. * This program is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU Affero General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU Affero General Public License
  24. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  25. *
  26. */
  27. namespace OCA\Theming\Controller;
  28. use OCA\Theming\Template;
  29. use OCP\AppFramework\Controller;
  30. use OCP\AppFramework\Http;
  31. use OCP\AppFramework\Http\DataResponse;
  32. use OCP\Files\IRootFolder;
  33. use OCP\IConfig;
  34. use OCP\IL10N;
  35. use OCP\IRequest;
  36. use OCA\Theming\Util;
  37. /**
  38. * Class ThemingController
  39. *
  40. * handle ajax requests to update the theme
  41. *
  42. * @package OCA\Theming\Controller
  43. */
  44. class ThemingController extends Controller {
  45. /** @var Template */
  46. private $template;
  47. /** @var IL10N */
  48. private $l;
  49. /** @var IConfig */
  50. private $config;
  51. /** @var IRootFolder */
  52. private $rootFolder;
  53. /**
  54. * ThemingController constructor.
  55. *
  56. * @param string $appName
  57. * @param IRequest $request
  58. * @param IConfig $config
  59. * @param Template $template
  60. * @param IL10N $l
  61. * @param IRootFolder $rootFolder
  62. */
  63. public function __construct(
  64. $appName,
  65. IRequest $request,
  66. IConfig $config,
  67. Template $template,
  68. IL10N $l,
  69. IRootFolder $rootFolder
  70. ) {
  71. parent::__construct($appName, $request);
  72. $this->template = $template;
  73. $this->l = $l;
  74. $this->config = $config;
  75. $this->rootFolder = $rootFolder;
  76. }
  77. /**
  78. * @param string $setting
  79. * @param string $value
  80. * @return DataResponse
  81. * @internal param string $color
  82. */
  83. public function updateStylesheet($setting, $value) {
  84. $this->template->set($setting, $value);
  85. return new DataResponse(
  86. [
  87. 'data' =>
  88. [
  89. 'message' => $this->l->t('Saved')
  90. ],
  91. 'status' => 'success'
  92. ]
  93. );
  94. }
  95. /**
  96. * Update the logos and background image
  97. *
  98. * @return DataResponse
  99. */
  100. public function updateLogo() {
  101. $newLogo = $this->request->getUploadedFile('uploadlogo');
  102. $newBackgroundLogo = $this->request->getUploadedFile('upload-login-background');
  103. if (empty($newLogo) && empty($newBackgroundLogo)) {
  104. return new DataResponse(
  105. [
  106. 'data' => [
  107. 'message' => $this->l->t('No file uploaded')
  108. ]
  109. ],
  110. Http::STATUS_UNPROCESSABLE_ENTITY);
  111. }
  112. $name = '';
  113. if(!empty($newLogo)) {
  114. $target = $this->rootFolder->newFile('themedinstancelogo');
  115. stream_copy_to_stream(fopen($newLogo['tmp_name'], 'r'), $target->fopen('w'));
  116. $this->template->set('logoMime', $newLogo['type']);
  117. $name = $newLogo['name'];
  118. }
  119. if(!empty($newBackgroundLogo)) {
  120. $target = $this->rootFolder->newFile('themedbackgroundlogo');
  121. stream_copy_to_stream(fopen($newBackgroundLogo['tmp_name'], 'r'), $target->fopen('w'));
  122. $this->template->set('backgroundMime', $newBackgroundLogo['type']);
  123. $name = $newBackgroundLogo['name'];
  124. }
  125. return new DataResponse(
  126. [
  127. 'data' =>
  128. [
  129. 'name' => $name,
  130. 'message' => $this->l->t('Saved')
  131. ],
  132. 'status' => 'success'
  133. ]
  134. );
  135. }
  136. /**
  137. * Revert setting to default value
  138. *
  139. * @param string $setting setting which should be reverted
  140. * @return DataResponse
  141. */
  142. public function undo($setting) {
  143. $value = $this->template->undo($setting);
  144. return new DataResponse(
  145. [
  146. 'data' =>
  147. [
  148. 'value' => $value,
  149. 'message' => $this->l->t('Saved')
  150. ],
  151. 'status' => 'success'
  152. ]
  153. );
  154. }
  155. /**
  156. * @PublicPage
  157. * @NoCSRFRequired
  158. *
  159. * @return Http\StreamResponse
  160. */
  161. public function getLogo() {
  162. $pathToLogo = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data/') . '/themedinstancelogo';
  163. if(!file_exists($pathToLogo)) {
  164. return new DataResponse();
  165. }
  166. \OC_Response::setExpiresHeader(gmdate('D, d M Y H:i:s', time() + (60*60*24*45)) . ' GMT');
  167. \OC_Response::enableCaching();
  168. $response = new Http\StreamResponse($pathToLogo);
  169. $response->cacheFor(3600);
  170. $response->addHeader('Content-Disposition', 'attachment');
  171. $response->addHeader('Content-Type', $this->config->getAppValue($this->appName, 'logoMime', ''));
  172. return $response;
  173. }
  174. /**
  175. * @PublicPage
  176. * @NoCSRFRequired
  177. *
  178. * @return Http\StreamResponse
  179. */
  180. public function getLoginBackground() {
  181. $pathToLogo = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data/') . '/themedbackgroundlogo';
  182. if(!file_exists($pathToLogo)) {
  183. return new DataResponse();
  184. }
  185. \OC_Response::setExpiresHeader(gmdate('D, d M Y H:i:s', time() + (60*60*24*45)) . ' GMT');
  186. \OC_Response::enableCaching();
  187. $response = new Http\StreamResponse($pathToLogo);
  188. $response->cacheFor(3600);
  189. $response->addHeader('Content-Disposition', 'attachment');
  190. $response->addHeader('Content-Type', $this->config->getAppValue($this->appName, 'backgroundMime', ''));
  191. return $response;
  192. }
  193. /**
  194. * @NoCSRFRequired
  195. * @PublicPage
  196. *
  197. * @return Http\DataDownloadResponse
  198. */
  199. public function getStylesheet() {
  200. $cacheBusterValue = $this->config->getAppValue('theming', 'cachebuster', '0');
  201. $responseCss = '';
  202. $color = $this->config->getAppValue($this->appName, 'color');
  203. if($color !== '') {
  204. $responseCss .= sprintf(
  205. '#body-user #header,#body-settings #header,#body-public #header {background-color: %s}',
  206. $color
  207. );
  208. }
  209. $logo = $this->config->getAppValue($this->appName, 'logoMime');
  210. if($logo !== '') {
  211. $responseCss .= sprintf('#header .logo {
  212. background-image: url(\'./logo?v='.$cacheBusterValue.'\');
  213. }
  214. #header .logo-icon {
  215. background-image: url(\'./logo?v='.$cacheBusterValue.'\');
  216. background-size: 62px 34px;
  217. }'
  218. );
  219. }
  220. $backgroundLogo = $this->config->getAppValue($this->appName, 'backgroundMime');
  221. if($backgroundLogo !== '') {
  222. $responseCss .= '#body-login {
  223. background-image: url(\'./loginbackground?v='.$cacheBusterValue.'\');
  224. }';
  225. }
  226. if(Util::invertTextColor($color)) {
  227. $responseCss .= '#header .header-appname, #expandDisplayName { color: #000000; } ';
  228. $responseCss .= '#header .icon-caret { background-image: url(\'' . \OC::$WEBROOT . '/core/img/actions/caret-dark.svg\'); } ';
  229. $responseCss .= '.searchbox input[type="search"] { background: transparent url(\'' . \OC::$WEBROOT . '/core/img/actions/search.svg\') no-repeat 6px center; color: #000; }';
  230. $responseCss .= '.searchbox input[type="search"]:focus,.searchbox input[type="search"]:active,.searchbox input[type="search"]:valid { color: #000; border: 1px solid rgba(0, 0, 0, .5); }';
  231. }
  232. \OC_Response::setExpiresHeader(gmdate('D, d M Y H:i:s', time() + (60*60*24*45)) . ' GMT');
  233. \OC_Response::enableCaching();
  234. $response = new Http\DataDownloadResponse($responseCss, 'style', 'text/css');
  235. $response->cacheFor(3600);
  236. return $response;
  237. }
  238. }