PageRenderTime 56ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/sly/Controller/Mediapool/Base.php

https://bitbucket.org/SallyCMS/sallycms-backend
PHP | 417 lines | 312 code | 88 blank | 17 comment | 39 complexity | f54da0e370060f80c78e99f2edaf3486 MD5 | raw file
  1. <?php
  2. /*
  3. * Copyright (c) 2013, webvariants GbR, http://www.webvariants.de
  4. *
  5. * This file is released under the terms of the MIT license. You can find the
  6. * complete text in the attached LICENSE file or online at:
  7. *
  8. * http://www.opensource.org/licenses/mit-license.php
  9. */
  10. use sly\Assets\Util;
  11. abstract class sly_Controller_Mediapool_Base extends sly_Controller_Backend implements sly_Controller_Interface {
  12. protected $args;
  13. protected $category;
  14. protected $selectBox;
  15. protected $categories = null;
  16. protected $popupHelper;
  17. private $init = false;
  18. protected function init() {
  19. if ($this->init) return;
  20. $this->init = true;
  21. // init custom query string params
  22. $this->initPopupHelper();
  23. // init category filter
  24. $cats = $this->popupHelper->getArgument('categories');
  25. // do NOT use empty(), as '0' is a valid value!
  26. if (strlen($cats) > 0) {
  27. $cats = array_unique(array_map('intval', explode('|', $cats)));
  28. $this->categories = count($cats) === 0 ? null : $cats;
  29. }
  30. $this->getCurrentCategory();
  31. // build navigation
  32. $app = $this->getContainer()->getApplication();
  33. $cur = $app->getCurrentControllerName();
  34. $menu = new sly_Layout_Navigation_Page('');
  35. $values = $this->popupHelper->getValues();
  36. $menu->addSubpage('mediapool', t('media_list'));
  37. $menu->addSubpage('mediapool_upload', t('upload_file'));
  38. if ($this->isMediaAdmin()) {
  39. $menu->addSubpage('mediapool_structure', t('categories'));
  40. $menu->addSubpage('mediapool_sync', t('sync_files'));
  41. }
  42. if (!empty($values)) {
  43. foreach ($menu->getSubpages() as $sp) {
  44. $sp->setExtraParams($values);
  45. // ignore the extra params when detecting the current page
  46. if ($cur === $sp->getPageParam()) $sp->forceStatus(true);
  47. }
  48. }
  49. $layout = $this->getContainer()->getLayout();
  50. $layout->showNavigation(false);
  51. $layout->pageHeader(t('media_list'), $menu);
  52. $layout->setBodyAttr('class', 'sly-popup sly-mediapool');
  53. $this->render('mediapool/javascript.phtml', array(), false);
  54. }
  55. protected function initPopupHelper() {
  56. $request = $this->getRequest();
  57. $dispatcher = $this->container->getDispatcher();
  58. // init custom query string params
  59. $params = array('callback' => 'string', 'args' => 'array');
  60. $this->popupHelper = new sly_Helper_Popup($params, 'SLY_MEDIAPOOL_URL_PARAMS');
  61. $this->popupHelper->init($request, $dispatcher);
  62. }
  63. protected function appendQueryString($url, $separator = '&amp;') {
  64. return $this->popupHelper->appendQueryString($url, $separator);
  65. }
  66. protected function appendParamsToForm(sly_Form $form) {
  67. return $this->popupHelper->appendParamsToForm($form);
  68. }
  69. protected function getCurrentCategory() {
  70. if ($this->category === null) {
  71. $request = $this->getRequest();
  72. $category = $request->request('category', 'int', -1);
  73. $service = $this->getContainer()->getMediaCategoryService();
  74. $session = sly_Core::getSession();
  75. if ($category === -1) {
  76. $category = $session->get('sly-media-category', 'int', 0);
  77. }
  78. // respect category filter
  79. if (!empty($this->categories) && !in_array($category, $this->categories)) {
  80. $category = reset($this->categories);
  81. }
  82. $category = $service->findById($category);
  83. $category = $category ? $category->getId() : 0;
  84. $session->set('sly-media-category', $category);
  85. $this->category = $category;
  86. }
  87. return $this->category;
  88. }
  89. protected function getOpenerLink(sly_Model_Medium $file) {
  90. $link = '';
  91. $callback = $this->popupHelper->get('callback');
  92. if (!empty($callback)) {
  93. $filename = $file->getFilename();
  94. $title = $file->getTitle();
  95. $link = '<a href="#" data-filename="'.sly_html($filename).'" data-title="'.sly_html($title).'">'.t('apply_file').'</a>';
  96. }
  97. return $link;
  98. }
  99. protected function getFiles() {
  100. $cat = $this->getCurrentCategory();
  101. $where = 'f.category_id = '.$cat;
  102. $where = sly_Core::dispatcher()->filter('SLY_MEDIA_LIST_QUERY', $where, array('category_id' => $cat));
  103. $where = '('.$where.')';
  104. $types = $this->popupHelper->getArgument('types');
  105. if (!empty($types)) {
  106. $types = explode('|', preg_replace('#[^a-z0-9/+.-|]#i', '', $types));
  107. if (!empty($types)) {
  108. $where .= ' AND filetype IN ("'.implode('","', $types).'")';
  109. }
  110. }
  111. $db = $this->getContainer()->getPersistence();
  112. $prefix = $db->getPrefix();
  113. $query = 'SELECT f.id FROM '.$prefix.'file f LEFT JOIN '.$prefix.'file_category c ON f.category_id = c.id WHERE '.$where.' ORDER BY f.title ASC';
  114. $files = array();
  115. $db->query($query);
  116. foreach ($db as $row) {
  117. $files[$row['id']] = sly_Util_Medium::findById($row['id']);
  118. }
  119. return $files;
  120. }
  121. protected function deleteMedium(sly_Model_Medium $medium, sly_Util_FlashMessage $msg) {
  122. $filename = $medium->getFileName();
  123. $user = $this->getCurrentUser();
  124. $service = $this->getContainer()->getMediumService();
  125. if ($this->canAccessCategory($medium->getCategoryId())) {
  126. $usages = $this->isInUse($medium);
  127. if ($usages === false) {
  128. try {
  129. $service->deleteByMedium($medium);
  130. $msg->appendInfo($filename.': '.t('medium_deleted'));
  131. }
  132. catch (sly_Exception $e) {
  133. $msg->appendWarning($filename.': '.$e->getMessage());
  134. }
  135. }
  136. else {
  137. $tmp = array();
  138. $tmp[] = t('file_is_in_use', $filename);
  139. $tmp[] = '<ul>';
  140. foreach ($usages as $usage) {
  141. $title = sly_html($usage['title']);
  142. if (!empty($usage['link'])) {
  143. $tmp[] = '<li><a class="sly-blank" target="_blank" href="'.$usage['link'].'">'.$title.'</a></li>';
  144. }
  145. else {
  146. $tmp[] = '<li>'.$title.'</li>';
  147. }
  148. }
  149. $tmp[] = '</ul>';
  150. $msg->appendWarning(implode("\n", $tmp));
  151. }
  152. }
  153. else {
  154. $msg->appendWarning($filename.': '.t('no_permission'));
  155. }
  156. }
  157. public function checkPermission($action) {
  158. $user = $this->getCurrentUser();
  159. if (!$user || (!$user->isAdmin() && !$user->hasRight('pages', 'mediapool'))) {
  160. return false;
  161. }
  162. if ($action === 'batch') {
  163. sly_Util_Csrf::checkToken();
  164. }
  165. return true;
  166. }
  167. protected function isMediaAdmin() {
  168. $user = $this->getCurrentUser();
  169. return $user->isAdmin() || $user->hasRight('mediacategory', 'access', sly_Authorisation_ListProvider::ALL);
  170. }
  171. protected function canAccessFile(sly_Model_Medium $medium) {
  172. return $this->canAccessCategory($medium->getCategoryId());
  173. }
  174. protected function canAccessCategory($cat) {
  175. $user = $this->getCurrentUser();
  176. return $this->isMediaAdmin() || $user->hasRight('mediacategory', 'access', intval($cat));
  177. }
  178. protected function getCategorySelect() {
  179. $user = $this->getCurrentUser();
  180. if ($this->selectBox === null) {
  181. $this->selectBox = sly_Backend_Form_Helper::getMediaCategorySelect('category', null, $user);
  182. $this->selectBox->setLabel(t('categories'));
  183. $this->selectBox->setMultiple(false);
  184. $this->selectBox->setAttribute('value', $this->getCurrentCategory());
  185. // filter categories
  186. if (!empty($this->categories)) {
  187. $values = array_keys($this->selectBox->getValues());
  188. foreach ($values as $catID) {
  189. if (!in_array($catID, $this->categories)) {
  190. $this->selectBox->removeValue($catID);
  191. }
  192. }
  193. }
  194. }
  195. return $this->selectBox;
  196. }
  197. protected function getDimensions($width, $height, $maxWidth, $maxHeight) {
  198. if ($width > $maxWidth) {
  199. $factor = (float) $maxWidth / $width;
  200. $width = $maxWidth;
  201. $height *= $factor;
  202. }
  203. if ($height > $maxHeight) {
  204. $factor = (float) $maxHeight / $height;
  205. $height = $maxHeight;
  206. $width *= $factor;
  207. }
  208. return array(ceil($width), ceil($height));
  209. }
  210. protected function getMimeIcon(sly_Model_Medium $medium) {
  211. $mapping = array(
  212. 'compressed' => array('gz', 'gzip', 'tar', 'zip', 'tgz', 'bz', 'bz2', '7zip', '7z', 'rar'),
  213. 'audio' => array('mp3', 'flac', 'aac', 'wav', 'ac3', 'ogg', 'wma'),
  214. 'document' => array('doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'odt', 'rtf'),
  215. 'executable' => array('sh', 'exe', 'bin', 'com', 'bat'),
  216. 'pdf' => array('pdf'),
  217. 'text' => array('txt', 'java', 'css', 'markdown', 'textile', 'md'),
  218. 'vector' => array('svg', 'eps'),
  219. 'video' => array('mkv', 'avi', 'swf', 'mov', 'flv', 'ogv', 'vp8')
  220. );
  221. $extension = $medium->getExtension();
  222. $base = 'mime/';
  223. if (!$medium->exists()) {
  224. return Util::appUri($base.'missing.png');
  225. }
  226. foreach ($mapping as $type => $exts) {
  227. if (in_array($extension, $exts, true)) {
  228. return Util::appUri($base.$type.'.png');
  229. }
  230. }
  231. return Util::appUri($base.'unknown.png');
  232. }
  233. protected function isImage(sly_Model_Medium $medium) {
  234. $exts = array('gif', 'jpeg', 'jpg', 'png', 'bmp', 'tif', 'tiff', 'webp');
  235. return in_array($medium->getExtension(), $exts);
  236. }
  237. protected function getThumbnailTag(sly_Model_Medium $medium, $width, $height) {
  238. if (!$medium->exists()) {
  239. $thumbnail = '<img src="'.$this->getMimeIcon($medium).'" width="44" height="38" alt="'.ht('file_not_found').'" />';
  240. }
  241. else {
  242. $icon_src = $this->getMimeIcon($medium);
  243. $alt = $medium->getTitle();
  244. $thumbnail = '<img src="'.$icon_src.'" alt="'.sly_html($alt).'" title="'.sly_html($alt).'" />';
  245. if ($this->isImage($medium)) {
  246. $mwidth = $medium->getWidth();
  247. $mheight = $medium->getHeight();
  248. $timestamp = $medium->getUpdateDate();
  249. $encoded = urlencode($medium->getFilename());
  250. list($width, $height) = $this->getDimensions($mwidth, $mheight, $width, $height);
  251. $attrs = array(
  252. 'alt' => $alt,
  253. 'title' => $alt,
  254. 'width' => $width,
  255. 'height' => $height,
  256. 'src' => sly\Assets\Util::mediapoolUri($encoded.'?t='.$timestamp)
  257. );
  258. $thumbnail = '<img '.sly_Util_HTML::buildAttributeString($attrs, array('alt')).' />';
  259. }
  260. }
  261. $dispatcher = $this->getContainer()->getDispatcher();
  262. $thumbnail = $dispatcher->filter('SLY_BACKEND_MEDIAPOOL_THUMBNAIL', $thumbnail, array(
  263. 'medium' => $medium,
  264. 'width' => $width,
  265. 'height' => $height,
  266. 'isImage' => $this->isImage($medium)
  267. ));
  268. return $thumbnail;
  269. }
  270. protected function isInUse(sly_Model_Medium $medium) {
  271. $container = $this->getContainer();
  272. $service = $container->getMediumService();
  273. $router = $container->getApplication()->getRouter();
  274. $usages = $service->getUsages($medium);
  275. foreach ($usages as $idx => $usage) {
  276. // properly setup object
  277. if (!empty($usage['link']) && !empty($usage['title'])) {
  278. continue;
  279. }
  280. switch ($usage['type']) {
  281. case 'sly-article':
  282. $article = $usage['object'];
  283. $title = $article->getName();
  284. $link = $router->getPlainUrl('content', null, array(
  285. 'article_id' => $article->getId(),
  286. 'clang' => $article->getClang(),
  287. 'revision' => $article->getRevision()
  288. ));
  289. break;
  290. case 'sly-category':
  291. $category = $usage['object'];
  292. $title = $category->getCatName();
  293. $link = $router->getPlainUrl('structure', null, array(
  294. 'category_id' => $category->getId(),
  295. 'clang' => $category->getClang()
  296. ));
  297. break;
  298. case 'sly-medium':
  299. $medium = $usage['object'];
  300. $title = $medium->getTitle();
  301. $link = $router->getPlainUrl('mediapool_detail', null, array('file_id' => $medium->getId()));
  302. break;
  303. case 'sly-user':
  304. $user = $usage['object'];
  305. $title = $obj->getName()?: $obj->getLogin();
  306. $link = $router->getPlainUrl('user', 'edit', array('id' => $user->getId()));
  307. }
  308. $usages[$idx]['link'] = $link;
  309. $usages[$idx]['title'] = $title;
  310. }
  311. return empty($usages) ? false : $usages;
  312. }
  313. protected function redirect($params = array(), $page = null, $code = 302) {
  314. if (!$this->popupHelper) {
  315. $this->initPopupHelper();
  316. }
  317. $values = $this->popupHelper->getValues();
  318. $params = array_merge($values, sly_makeArray($params));
  319. $this->container->getApplication()->redirect($page, $params, $code);
  320. }
  321. protected function redirectResponse($params = array(), $controller = null, $action = null, $code = 302) {
  322. if (!$this->popupHelper) {
  323. $this->initPopupHelper();
  324. }
  325. $values = $this->popupHelper->getValues();
  326. $params = array_merge($values, sly_makeArray($params));
  327. return $this->container->getApplication()->redirectResponse($controller, $action, $params, $code);
  328. }
  329. }