SproutCMS

This is the code documentation for the SproutCMS project

source of /sprout/Controllers/Tinymce4Controller.php

  1. <?php
  2. /*
  3.  * Copyright (C) 2017 Karmabunny Pty Ltd.
  4.  *
  5.  * This file is a part of SproutCMS.
  6.  *
  7.  * SproutCMS is free software: you can redistribute it and/or modify it under the terms
  8.  * of the GNU General Public License as published by the Free Software Foundation, either
  9.  * version 2 of the License, or (at your option) any later version.
  10.  *
  11.  * For more information, visit <http://getsproutcms.com>.
  12.  */
  13.  
  14. namespace Sprout\Controllers;
  15.  
  16. use Exception;
  17.  
  18. use Kohana;
  19.  
  20. use Sprout\Helpers\AdminAuth;
  21. use Sprout\Helpers\AdminPerms;
  22. use Sprout\Helpers\Category;
  23. use Sprout\Helpers\Enc;
  24. use Sprout\Helpers\File;
  25. use Sprout\Helpers\FileConstants;
  26. use Sprout\Helpers\Pdb;
  27. use Sprout\Helpers\Register;
  28. use Sprout\Helpers\RteLibContainer;
  29. use Sprout\Helpers\RteLibObject;
  30. use Sprout\Helpers\Sprout;
  31. use Sprout\Helpers\View;
  32.  
  33.  
  34. /**
  35. * Link library, image library, etc
  36. **/
  37. class Tinymce4Controller extends Controller
  38. {
  39.  
  40. public function __construct()
  41. {
  42. parent::__construct();
  43. }
  44.  
  45.  
  46. /**
  47.   * Initialises a new search toolbar
  48.   *
  49.   * @param string $type 'image' or 'library'
  50.   **/
  51. protected static function initToolbar($type)
  52. {
  53. if (!in_array($type, array('image', 'video', 'library'))) {
  54. throw new Exception("Must be 'image', 'video', or 'library'");
  55. }
  56.  
  57. $view = new View("sprout/tinymce4/toolbar");
  58. $view->is_root = false;
  59. $view->is_search = false;
  60. $view->search_url = "tinymce4/{$type}_search";
  61. $view->upload_url = "tinymce4/upload?type=" . $type;
  62. $view->reset_url = "tinymce4/{$type}";
  63.  
  64. if ($type == 'image') {
  65. $view->search_label = 'Search for an image';
  66. $view->upload_label = 'Upload an image';
  67. } else if ($type == 'video') {
  68. $view->search_label = 'Search for a video';
  69. $view->upload_label = 'Upload a video';
  70. } else {
  71. $view->search_label = 'Search';
  72. $view->upload_label = 'Upload a file';
  73. }
  74.  
  75. $view->can_upload = AdminPerms::controllerAccess('file', 'add');
  76.  
  77. if (isset($_GET['search'])) {
  78. $view->search_query = $_GET['search'];
  79. } else {
  80. $view->search_query = '';
  81. }
  82.  
  83. return $view;
  84. }
  85.  
  86.  
  87. /**
  88.   * Show a gallery of image categories
  89.   **/
  90. public function image()
  91. {
  92. AdminAuth::checkLogin();
  93.  
  94. $cat_table = Category::tableMain2cat('files');
  95. $joiner_table = Category::tableMain2joiner('files');
  96. $q = "SELECT cat.id, cat.name, GROUP_CONCAT(file.filename ORDER BY RAND() SEPARATOR '|') AS filenames
  97. FROM ~{$cat_table} AS cat
  98. INNER JOIN ~{$joiner_table} AS joiner ON joiner.cat_id = cat.id
  99. INNER JOIN ~files AS file ON joiner.file_id = file.id
  100. WHERE file.name != '' AND file.type = ?
  101. GROUP BY cat.id
  102. ORDER BY cat.name
  103. LIMIT 500";
  104. $res = Pdb::q($q, [FileConstants::TYPE_IMAGE], 'pdo');
  105.  
  106. $view = new View('sprout/tinymce4/image_cat');
  107. $view->toolbar = self::initToolbar('image');
  108. $view->toolbar->is_root = true;
  109. $view->categories = $res;
  110.  
  111. $outer = new View('sprout/tinymce4/outer');
  112. $outer->main_content = $view->render();
  113. $outer->page_title = 'Insert image - choose category';
  114.  
  115. $res->closeCursor();
  116.  
  117. echo $outer->render();
  118. }
  119.  
  120.  
  121. /**
  122.   * Show a gallery of images for a given category
  123.   **/
  124. public function imageList($category_id)
  125. {
  126. AdminAuth::checkLogin();
  127. $category_id = (int) $category_id;
  128.  
  129. $cat_name = Category::name('files', $category_id);
  130.  
  131. $cat_table = Category::tableMain2cat('files');
  132. $joiner_table = Category::tableMain2joiner('files');
  133. $q = "SELECT file.id, file.name, file.filename
  134. FROM ~files AS file
  135. INNER JOIN ~{$joiner_table} AS joiner ON joiner.file_id = file.id
  136. WHERE joiner.cat_id = ? AND file.name != '' AND file.type = ?
  137. GROUP BY file.id
  138. ORDER BY file.name
  139. LIMIT 500";
  140. $res = Pdb::q($q, [$category_id, FileConstants::TYPE_IMAGE], 'pdo');
  141.  
  142. $view = new View('sprout/tinymce4/image_list');
  143. $view->toolbar = self::initToolbar('image');
  144. $view->images = $res;
  145. $view->up_url = 'SITE/tinymce4/image';
  146. $view->gallery_name = $cat_name;
  147. $view->link_attrs = array('category_id' => $category_id);
  148.  
  149. $outer = new View('sprout/tinymce4/outer');
  150. $outer->main_content = $view->render();
  151. $outer->page_title = 'Insert image - ' . $cat_name;
  152.  
  153. $res->closeCursor();
  154.  
  155. echo $outer->render();
  156. }
  157.  
  158.  
  159. /**
  160.   * Show image search results
  161.   **/
  162. public function imageSearch()
  163. {
  164. AdminAuth::checkLogin();
  165. $key = trim(@$_GET['search']);
  166. $safe_key = Pdb::likeEscape($key);
  167.  
  168. $q = "SELECT id, name, filename
  169. FROM ~files
  170. WHERE type = ?
  171. AND (name LIKE CONCAT('%', ?, '%') OR filename LIKE CONCAT('%', ?, '%'))
  172. ORDER BY name
  173. LIMIT 200";
  174. $res = Pdb::q($q, [FileConstants::TYPE_IMAGE, $safe_key, $safe_key], 'pdo');
  175.  
  176. $view = new View('sprout/tinymce4/image_list');
  177. $view->toolbar = self::initToolbar('image');
  178. $view->toolbar->is_search = true;
  179. $view->images = $res;
  180. $view->search_key = $key;
  181. $view->link_attrs = array('search' => $key);
  182.  
  183. $outer = new View('sprout/tinymce4/outer');
  184. $outer->main_content = $view->render();
  185. $outer->page_title = 'Insert image';
  186.  
  187. $res->closeCursor();
  188.  
  189. echo $outer->render();
  190. }
  191.  
  192.  
  193. /**
  194.   * Show the various sizes to choose from
  195.   **/
  196. public function imageSize($file_id)
  197. {
  198. AdminAuth::checkLogin();
  199. $file_id = (int) $file_id;
  200. $_GET['category_id'] = (int) @$_GET['category_id'];
  201. $_GET['search'] = (string) @$_GET['search'];
  202.  
  203. // Grab file info
  204. $q = "SELECT id, name, filename FROM ~files WHERE id = ?";
  205. $row = Pdb::q($q, [$file_id], 'row');
  206.  
  207. // Prep links for the various sizes
  208. $sizes = array();
  209. $transforms = Kohana::config('file.image_transformations');
  210.  
  211. // Exclude transforms that don't actually exist, e.g. if the original image is smaller than certain sizes
  212. foreach ($transforms as $key => $resolution) {
  213. $original = $row['filename'];
  214. $resize = File::getNoext($original) . ".{$key}." . File::getExt($original);
  215. if (!File::exists($resize)) {
  216. unset($transforms[$key]);
  217. }
  218. }
  219.  
  220. // The UP url
  221. $up_url = 'SITE/tinymce4/image';
  222. if (!empty($_GET['category_id'])) {
  223. $up_url = 'SITE/tinymce4/image_list/' . $_GET['category_id'];
  224. } else if (!empty($_GET['search'])) {
  225. $up_url = 'SITE/tinymce4/image_search?search=' . Enc::url($_GET['search']);
  226. }
  227.  
  228. $view = new View('sprout/tinymce4/image_size');
  229. $view->toolbar = self::initToolbar('image');
  230. $view->image = $row;
  231. $view->sizes = array_keys($transforms);
  232. $view->up_url = $up_url;
  233.  
  234. $outer = new View('sprout/tinymce4/outer');
  235. $outer->main_content = $view->render();
  236. $outer->page_title = 'Insert image - ' . $row['name'];
  237. echo $outer->render();
  238. }
  239.  
  240.  
  241. /**
  242.   * Show a list of RTE libraries
  243.   **/
  244. public function library()
  245. {
  246. AdminAuth::checkLogin();
  247.  
  248. $libraries = array();
  249. foreach (Register::getRteLibraries() as $class_name) {
  250. $inst = Sprout::instance($class_name, ['Sprout\\Helpers\\RteLibrary']);
  251.  
  252. $url = 'SITE/tinymce4/library_browse/' . Enc::url($class_name) . '?path=';
  253.  
  254. $libraries[$inst->getName()] = array(
  255. 'url' => $url,
  256. 'name' => $inst->getName(),
  257. );
  258. }
  259.  
  260. $view = new View('sprout/tinymce4/library_list');
  261. $view->toolbar = self::initToolbar('library');
  262. $view->toolbar->is_root = true;
  263. $view->libraries = $libraries;
  264.  
  265. $outer = new View('sprout/tinymce4/outer');
  266. $outer->main_content = $view->render();
  267. $outer->page_title = 'Insert link';
  268. echo $outer->render();
  269. }
  270.  
  271.  
  272. /**
  273.   * Search rte libraries
  274.   **/
  275. public function librarySearch()
  276. {
  277. AdminAuth::checkLogin();
  278.  
  279. $key = trim(@$_GET['search']);
  280.  
  281. $class_names = Register::getRteLibraries();
  282. if (isset($_GET['lib']) and in_array($_GET['lib'], $class_names)) {
  283. $class_names = array($_GET['lib']);
  284. }
  285.  
  286. $objects = array();
  287. foreach ($class_names as $class_name) {
  288. $inst = Sprout::instance($class_name, ['Sprout\\Helpers\\RteLibrary']);
  289.  
  290. try {
  291. $res = $inst->search($key);
  292. } catch (Exception $ex) {
  293. continue;
  294. }
  295.  
  296. $objects = array_merge($objects, $res);
  297. }
  298.  
  299. $view = new View('sprout/tinymce4/library_search');
  300. $view->toolbar = self::initToolbar('library');
  301. $view->toolbar->is_search = true;
  302. $view->objects = $objects;
  303.  
  304. $outer = new View('sprout/tinymce4/outer');
  305. $outer->main_content = $view;
  306.  
  307. if (isset($_GET['lib'])) {
  308. $outer->page_title = 'Insert link - ' . $inst->getName() . ' - Search';
  309. $view->library_name = $inst->getName();
  310. $view->toolbar->search_params = array('lib' => $_GET['lib']);
  311. $view->toolbar->reset_url = 'tinymce4/library_browse/' . $_GET['lib'];
  312. } else {
  313. $outer->page_title = 'Insert link - Search';
  314. $view->library_name = null;
  315. }
  316.  
  317. echo $outer->render();
  318. }
  319.  
  320.  
  321. /**
  322.   * Browse an RTE library
  323.   *
  324.   * @param string $class_name The RTE library to browse
  325.   * @get string path The path to browse
  326.   **/
  327. public function libraryBrowse($class_name)
  328. {
  329. AdminAuth::checkLogin();
  330.  
  331. $class_name = trim($class_name);
  332. if (!in_array($class_name, Register::getRteLibraries())) {
  333. throw new Exception('Invalid library class');
  334. }
  335.  
  336. $inst = Sprout::instance($class_name, ['Sprout\\Helpers\\RteLibrary']);
  337. $res = $inst->browse(@$_GET['path']);
  338.  
  339. // Split into two arrays
  340. $objects = array();
  341. $containers = array();
  342. foreach ($res as $obj) {
  343. if ($obj instanceof RteLibObject) {
  344. $objects[] = $obj;
  345.  
  346. } else if ($obj instanceof RteLibContainer) {
  347. $path = trim(@$_GET['path'] . '/' . $obj->getName(), '/');
  348. $url = 'SITE/tinymce4/library_browse/' . Enc::url($class_name) . '?path=' . Enc::url($path);
  349.  
  350. $containers[$url] = $obj->getLabel();
  351. }
  352. }
  353.  
  354. // The URL to go "up" a level
  355. $up_url = 'SITE/tinymce4/library';
  356. if (!empty($_GET['path'])) {
  357. $parts = explode('/', $_GET['path']);
  358. array_pop($parts);
  359. $up_url = 'SITE/tinymce4/library_browse/' . Enc::url($class_name) . '?path=' . Enc::url(implode('/', $parts));
  360. }
  361.  
  362. $view = new View('sprout/tinymce4/library_browse');
  363. $view->toolbar = self::initToolbar('library');
  364. $view->toolbar->search_url .= '&lib=' . $class_name;
  365. $view->objects = $objects;
  366. $view->containers = $containers;
  367. $view->up_url = $up_url;
  368. $view->library_name = $inst->getName();
  369.  
  370. $outer = new View('sprout/tinymce4/outer');
  371. $outer->main_content = $view->render();
  372. $outer->page_title = 'Insert link - ' . $inst->getName();
  373. echo $outer->render();
  374. }
  375.  
  376.  
  377. /**
  378.   * Show a gallery of video categories
  379.   */
  380. public function video()
  381. {
  382. AdminAuth::checkLogin();
  383.  
  384. $cat_table = Category::tableMain2cat('files');
  385. $joiner_table = Category::tableMain2joiner('files');
  386. $q = "SELECT cat.id, cat.name, COUNT(file.id) AS num_files
  387. FROM ~{$cat_table} AS cat
  388. INNER JOIN ~{$joiner_table} AS joiner ON joiner.cat_id = cat.id
  389. INNER JOIN ~files AS file ON joiner.file_id = file.id
  390. AND file.name != '' AND file.type = ?
  391. GROUP BY cat.id
  392. ORDER BY cat.name
  393. LIMIT 100";
  394. $res = Pdb::q($q, [FileConstants::TYPE_VIDEO], 'pdo');
  395.  
  396. $view = new View('sprout/tinymce4/video_cat');
  397. $view->toolbar = self::initToolbar('video');
  398. $view->toolbar->is_root = true;
  399. $view->categories = $res;
  400.  
  401. $outer = new View('sprout/tinymce4/outer');
  402. $outer->main_content = $view->render();
  403. $outer->page_title = 'Insert video - choose category';
  404.  
  405. $res->closeCursor();
  406.  
  407. echo $outer->render();
  408. }
  409.  
  410.  
  411. /**
  412.   * Show a gallery of videos for a given category
  413.   */
  414. public function videoList($category_id)
  415. {
  416. AdminAuth::checkLogin();
  417. $category_id = (int) $category_id;
  418.  
  419. $cat_name = Category::name('files', $category_id);
  420.  
  421. $cat_table = Category::tableMain2cat('files');
  422. $joiner_table = Category::tableMain2joiner('files');
  423. $q = "SELECT file.id, file.name, file.filename
  424. FROM ~{$joiner_table} AS joiner
  425. INNER JOIN ~files AS file ON joiner.file_id = file.id
  426. AND file.name != '' AND file.type = ?
  427. WHERE joiner.cat_id = ?
  428. GROUP BY file.id
  429. ORDER BY file.name
  430. LIMIT 500";
  431. $res = Pdb::q($q, [FileConstants::TYPE_VIDEO, $category_id], 'pdo');
  432.  
  433. $view = new View('sprout/tinymce4/video_list');
  434. $view->toolbar = self::initToolbar('video');
  435. $view->videos = $res;
  436. $view->up_url = 'SITE/tinymce4/video';
  437. $view->gallery_name = $cat_name;
  438. $view->link_attrs = ['category_id' => $category_id];
  439.  
  440. $outer = new View('sprout/tinymce4/outer');
  441. $outer->main_content = $view->render();
  442. $outer->page_title = 'Insert video - ' . $cat_name;
  443.  
  444. $res->closeCursor();
  445.  
  446. echo $outer->render();
  447. }
  448.  
  449.  
  450. /**
  451.   * Show video search results
  452.   */
  453. public function videoSearch()
  454. {
  455. AdminAuth::checkLogin();
  456. $key = trim(@$_GET['search']);
  457. $safe_key = Pdb::likeEscape($key);
  458.  
  459. $q = "SELECT id, name, filename
  460. FROM ~files
  461. WHERE type = ?
  462. AND (name LIKE CONCAT('%', ?, '%') OR filename LIKE CONCAT('%', ?, '%'))
  463. ORDER BY name
  464. LIMIT 200";
  465. $res = Pdb::q($q, [FileConstants::TYPE_VIDEO, $safe_key, $safe_key], 'pdo');
  466.  
  467. $view = new View('sprout/tinymce4/video_list');
  468. $view->toolbar = self::initToolbar('video');
  469. $view->toolbar->is_search = true;
  470. $view->videos = $res;
  471. $view->search_key = $key;
  472. $view->link_attrs = ['search' => $key];
  473.  
  474. $outer = new View('sprout/tinymce4/outer');
  475. $outer->main_content = $view->render();
  476. $outer->page_title = 'Insert video';
  477.  
  478. $res->closeCursor();
  479.  
  480. echo $outer->render();
  481. }
  482.  
  483.  
  484. /**
  485.   * UI for uploading files
  486.   **/
  487. public function upload()
  488. {
  489. AdminAuth::checkLogin();
  490.  
  491. if (!AdminPerms::controllerAccess('file', 'add')) {
  492. echo '<p>You do not have permission to upload files.</p>';
  493. return;
  494. }
  495.  
  496. $view = new View('sprout/tinymce4/upload');
  497. $view->toolbar = self::initToolbar(@$_GET['type']);
  498.  
  499. switch (@$_GET['type']) {
  500. case 'image':
  501. $view->f_type = FileConstants::TYPE_IMAGE;
  502. break;
  503.  
  504. case 'video':
  505. $view->f_type = FileConstants::TYPE_VIDEO;
  506. break;
  507.  
  508. default:
  509. $view->f_type = FileConstants::TYPE_DOCUMENT;
  510. }
  511.  
  512. $cat_table = Category::tableMain2cat('files');
  513. $view->cats = Pdb::lookup($cat_table);
  514. $view->cats['_new'] = '-- New --';
  515.  
  516. $outer = new View('sprout/tinymce4/outer');
  517. $outer->main_content = $view->render();
  518. $outer->page_title = $view->toolbar->upload_label;
  519. echo $outer->render();
  520. }
  521.  
  522.  
  523. /**
  524.   * Show a gallery of image categories
  525.   **/
  526. public function gallery()
  527. {
  528. AdminAuth::checkLogin();
  529.  
  530. $cat_table = Category::tableMain2cat('files');
  531. $joiner_table = Category::tableMain2joiner('files');
  532.  
  533. $q = "SELECT
  534. cat.id,
  535. cat.name,
  536. GROUP_CONCAT(file.filename ORDER BY RAND() SEPARATOR '|') AS filenames
  537. FROM ~{$cat_table} AS cat
  538. INNER JOIN ~{$joiner_table} AS joiner
  539. ON joiner.cat_id = cat.id
  540. INNER JOIN ~files AS file
  541. ON joiner.file_id = file.id
  542. WHERE file.name != ''
  543. AND file.type = ?
  544. GROUP BY cat.id
  545. ORDER BY cat.name
  546. LIMIT 500";
  547.  
  548. $categories = Pdb::q($q, [FileConstants::TYPE_IMAGE], 'arr');
  549.  
  550. $view = new View('sprout/tinymce4/image_gallery');
  551. $view->categories = $categories;
  552.  
  553. $outer = new View('sprout/tinymce4/outer');
  554. $outer->main_content = $view->render();
  555. $outer->page_title = 'Insert Gallery - choose category';
  556.  
  557. echo $outer->render();
  558. }
  559. }
  560.  
  561.