PageRenderTime 39ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/FileManager/Controller/FileManagerController.php

http://github.com/croogo/croogo
PHP | 400 lines | 236 code | 53 blank | 111 comment | 60 complexity | e2f527553bb52b776c34efb2c2781208 MD5 | raw file
Possible License(s): LGPL-2.1
  1. <?php
  2. App::uses('FileManagerAppController', 'FileManager.Controller');
  3. App::uses('FileManager', 'FileManager.Model');
  4. App::uses('File', 'Utility');
  5. App::uses('Folder', 'Utility');
  6. /**
  7. * FileManager Controller
  8. *
  9. * @category FileManager.Controller
  10. * @package Croogo.FileManager.Controller
  11. * @version 1.0
  12. * @author Fahad Ibnay Heylaal <contact@fahad19.com>
  13. * @license http://www.opensource.org/licenses/mit-license.php The MIT License
  14. * @link http://www.croogo.org
  15. */
  16. class FileManagerController extends FileManagerAppController {
  17. /**
  18. * Models used by the Controller
  19. *
  20. * @var array
  21. * @access public
  22. */
  23. public $uses = array('Settings.Setting', 'Users.User', 'FileManager.FileManager');
  24. /**
  25. * Helpers used by the Controller
  26. *
  27. * @var array
  28. * @access public
  29. */
  30. public $helpers = array('Html', 'Form', 'FileManager.FileManager');
  31. /**
  32. * Deletable Paths
  33. *
  34. * @var array
  35. * @access public
  36. */
  37. public $deletablePaths = array();
  38. /**
  39. * beforeFilter
  40. *
  41. * @return void
  42. * @access public
  43. */
  44. public function beforeFilter() {
  45. parent::beforeFilter();
  46. $this->deletablePaths = array(
  47. APP . 'View' . DS . 'Themed' . DS,
  48. WWW_ROOT,
  49. );
  50. $this->set('deletablePaths', $this->deletablePaths);
  51. }
  52. /**
  53. * Checks wether given $path is editable.
  54. * A file is editable when it resides under the APP directory
  55. *
  56. * @param string $path Path to check
  57. * @return boolean true if file is editable
  58. * @deprecated Use FileManager::isEditable()
  59. */
  60. protected function _isEditable($path) {
  61. $path = realpath($path);
  62. $regex = '/^' . preg_quote(realpath(APP), '/') . '/';
  63. return preg_match($regex, $path) > 0;
  64. }
  65. /**
  66. * Checks wether given $path is editable.
  67. * A file is deleteable when it resides under directories registered in
  68. * FileManagerController::deletablePaths
  69. *
  70. * @param string $path Path to check
  71. * @return boolean true when file is deletable
  72. * @deprecated Use FileManager::isDeletable()
  73. */
  74. protected function _isDeletable($path) {
  75. $path = realpath($path);
  76. $regex = array();
  77. for ($i = 0, $ii = count($this->deletablePaths); $i < $ii; $i++) {
  78. $regex[] = '(^' . preg_quote(realpath($this->deletablePaths[$i]), '/') . ')';
  79. }
  80. $regex = '/' . join($regex, '|') . '/';
  81. return preg_match($regex, $path) > 0;
  82. }
  83. /**
  84. * Admin index
  85. *
  86. * @return void
  87. * @access public
  88. */
  89. public function admin_index() {
  90. return $this->redirect(array('action' => 'browse'));
  91. }
  92. /**
  93. * Admin browse
  94. *
  95. * @return void
  96. * @access public
  97. */
  98. public function admin_browse() {
  99. $this->folder = new Folder;
  100. if (isset($this->request->query['path'])) {
  101. $path = $this->request->query['path'];
  102. } else {
  103. $path = APP;
  104. }
  105. $this->set('title_for_layout', __d('croogo', 'File Manager'));
  106. $path = realpath($path) . DS;
  107. $regex = '/^' . preg_quote(realpath(APP), '/') . '/';
  108. if (preg_match($regex, $path) == false) {
  109. $this->Session->setFlash(__d('croogo', 'Path %s is restricted', $path), 'flash', array('class' => 'error'));
  110. $path = APP;
  111. }
  112. $blacklist = array('.git', '.svn', '.CVS');
  113. $regex = '/(' . preg_quote(implode('|', $blacklist), '.') . ')/';
  114. if (in_array(basename($path), $blacklist) || preg_match($regex, $path)) {
  115. $this->Session->setFlash(__d('croogo', sprintf('Path %s is restricted', $path)), 'flash', array('class' => 'error'));
  116. $path = dirname($path);
  117. }
  118. $this->folder->path = $path;
  119. $content = $this->folder->read();
  120. $this->set(compact('content'));
  121. $this->set('path', $path);
  122. }
  123. /**
  124. * Admin editfile
  125. *
  126. * @return void
  127. * @access public
  128. */
  129. public function admin_editfile() {
  130. if (isset($this->request->query['path'])) {
  131. $path = $this->request->query['path'];
  132. $absolutefilepath = $path;
  133. } else {
  134. return $this->redirect(array('controller' => 'file_manager', 'action' => 'browse'));
  135. }
  136. if (!$this->FileManager->isEditable($path)) {
  137. $this->Session->setFlash(__d('croogo', 'Path %s is restricted', $path), 'flash', array('class' => 'error'));
  138. return $this->redirect(array('controller' => 'file_manager', 'action' => 'browse'));
  139. }
  140. $this->set('title_for_layout', __d('croogo', 'Edit file: %s', $path));
  141. $pathE = explode(DS, $path);
  142. $n = count($pathE) - 1;
  143. unset($pathE[$n]);
  144. $path = implode(DS, $pathE);
  145. $this->file = new File($absolutefilepath, true);
  146. if (!empty($this->request->data) ) {
  147. if ($this->file->write($this->request->data['FileManager']['content'])) {
  148. $this->Session->setFlash(__d('croogo', 'File saved successfully'), 'flash', array('class' => 'success'));
  149. }
  150. }
  151. $content = $this->file->read();
  152. $this->set(compact('content', 'path', 'absolutefilepath'));
  153. }
  154. /**
  155. * Admin upload
  156. *
  157. * @return void
  158. * @access public
  159. */
  160. public function admin_upload() {
  161. $this->set('title_for_layout', __d('croogo', 'Upload'));
  162. if (isset($this->request->query['path'])) {
  163. $path = $this->request->query['path'];
  164. } else {
  165. $path = APP;
  166. }
  167. $this->set(compact('path'));
  168. if (isset($path) && !$this->_isDeletable($path)) {
  169. $this->Session->setFlash(__d('croogo', 'Path %s is restricted', $path), 'flash', array('class' => 'error'));
  170. return $this->redirect($this->referer());
  171. }
  172. if (isset($this->request->data['FileManager']['file']['tmp_name']) &&
  173. is_uploaded_file($this->request->data['FileManager']['file']['tmp_name'])) {
  174. $destination = $path . $this->request->data['FileManager']['file']['name'];
  175. move_uploaded_file($this->request->data['FileManager']['file']['tmp_name'], $destination);
  176. $this->Session->setFlash(__d('croogo', 'File uploaded successfully.'), 'flash', array('class' => 'success'));
  177. $redirectUrl = Router::url(array('controller' => 'file_manager', 'action' => 'browse'), true) . '?path=' . urlencode($path);
  178. return $this->redirect($redirectUrl);
  179. }
  180. }
  181. /**
  182. * Admin Delete File
  183. *
  184. * @return void
  185. * @access public
  186. */
  187. public function admin_delete_file() {
  188. if (!empty($this->request->data['path'])) {
  189. $path = $this->request->data['path'];
  190. } else {
  191. return $this->redirect(array('controller' => 'file_manager', 'action' => 'browse'));
  192. }
  193. if (!$this->_isDeletable($path)) {
  194. $this->Session->setFlash(__d('croogo', 'Path %s is restricted', $path), 'flash', array('class' => 'error'));
  195. return $this->redirect(array('controller' => 'file_manager', 'action' => 'browse'));
  196. }
  197. if (file_exists($path) && unlink($path)) {
  198. $this->Session->setFlash(__d('croogo', 'File deleted'), 'flash', array('class' => 'success'));
  199. } else {
  200. $this->Session->setFlash(__d('croogo', 'An error occured'), 'flash', array('class' => 'error'));
  201. }
  202. if (isset($_SERVER['HTTP_REFERER'])) {
  203. return $this->redirect($_SERVER['HTTP_REFERER']);
  204. } else {
  205. return $this->redirect(array('controller' => 'file_manager', 'action' => 'index'));
  206. }
  207. exit();
  208. }
  209. /**
  210. * Admin Delete Directory
  211. *
  212. * @return void
  213. * @access public
  214. */
  215. public function admin_delete_directory() {
  216. if (!empty($this->request->data['path'])) {
  217. $path = $this->request->data['path'];
  218. } else {
  219. return $this->redirect(array('controller' => 'file_manager', 'action' => 'browse'));
  220. }
  221. if (isset($path) && !$this->_isDeletable($path)) {
  222. $this->Session->setFlash(__d('croogo', 'Path %s is restricted', $path), 'flash', array('class' => 'error'));
  223. return $this->redirect(array('controller' => 'file_manager', 'action' => 'browse'));
  224. }
  225. if (is_dir($path) && rmdir($path)) {
  226. $this->Session->setFlash(__d('croogo', 'Directory deleted'), 'flash', array('class' => 'success'));
  227. } else {
  228. $this->Session->setFlash(__d('croogo', 'An error occured'), 'flash', array('class' => 'error'));
  229. }
  230. if (isset($_SERVER['HTTP_REFERER'])) {
  231. return $this->redirect($_SERVER['HTTP_REFERER']);
  232. } else {
  233. return $this->redirect(array('controller' => 'file_manager', 'action' => 'index'));
  234. }
  235. exit;
  236. }
  237. /**
  238. * Rename a file or directory
  239. *
  240. * @return void
  241. * @access public
  242. */
  243. public function admin_rename() {
  244. $path = $this->request->query('path');
  245. $pathFragments = array_filter(explode(DIRECTORY_SEPARATOR, $path));
  246. if (!$this->FileManager->isEditable($path)) {
  247. $this->Session->setFlash(__d('croogo', 'Path "%s" cannot be renamed', $path), 'flash', array('class' => 'error'));
  248. $this->redirect(array('controller' => 'file_manager', 'action' => 'browse'));
  249. }
  250. if ($this->request->is('post') || $this->request->is('put')) {
  251. if (!is_null($this->request->data('FileManager.name')) && !empty($this->request->data['FileManager']['name'])) {
  252. $newName = trim($this->request->data['FileManager']['name']);
  253. $oldName = array_pop($pathFragments);
  254. $newPath = DIRECTORY_SEPARATOR . implode(DIRECTORY_SEPARATOR, $pathFragments) . DIRECTORY_SEPARATOR . $newName;
  255. $fileExists = file_exists($newPath);
  256. if ($oldName !== $newName) {
  257. if ($fileExists) {
  258. $message = __d('croogo', '%s already exists', $newName);
  259. $alertType = 'error';
  260. } else {
  261. if ($this->FileManager->rename($path, $newPath)) {
  262. $message = __d('croogo', '"%s" has been renamed to "%s"', $oldName, $newName);
  263. $alertType = 'success';
  264. } else {
  265. $message = __d('croogo', 'Could not rename "%s" to "%s"', $oldName,$newName);
  266. $alertType = 'error';
  267. }
  268. }
  269. } else {
  270. $message = __d('croogo', 'Name has not changed');
  271. $alertType = 'alert';
  272. }
  273. $this->Session->setFlash($message, 'flash', array('class' => $alertType));
  274. }
  275. return $this->Croogo->redirect(array('controller' => 'file_manager', 'action' => 'browse'));
  276. } else {
  277. $this->Croogo->setReferer();
  278. }
  279. $this->request->data('FileManager.name', array_pop($pathFragments));
  280. $this->set('path', $path);
  281. }
  282. /**
  283. * Admin Create Directory
  284. *
  285. * @return void
  286. * @access public
  287. */
  288. public function admin_create_directory() {
  289. $this->set('title_for_layout', __d('croogo', 'Create Directory'));
  290. if (isset($this->request->query['path'])) {
  291. $path = $this->request->query['path'];
  292. } else {
  293. return $this->redirect(array('controller' => 'file_manager', 'action' => 'browse'));
  294. }
  295. if (isset($path) && !$this->_isDeletable($path)) {
  296. $this->Session->setFlash(__d('croogo', 'Path %s is restricted', $path), 'flash', array('class' => 'error'));
  297. return $this->redirect($this->referer());
  298. }
  299. if (!empty($this->request->data)) {
  300. $this->folder = new Folder;
  301. if ($this->folder->create($path . $this->request->data['FileManager']['name'])) {
  302. $this->Session->setFlash(__d('croogo', 'Directory created successfully.'), 'flash', array('class' => 'success'));
  303. $redirectUrl = Router::url(array('controller' => 'file_manager', 'action' => 'browse'), true) . '?path=' . urlencode($path);
  304. return $this->redirect($redirectUrl);
  305. } else {
  306. $this->Session->setFlash(__d('croogo', 'An error occured'), 'flash', array('class' => 'error'));
  307. }
  308. }
  309. $this->set(compact('path'));
  310. }
  311. /**
  312. * Admin Create File
  313. *
  314. * @return void
  315. * @access public
  316. */
  317. public function admin_create_file() {
  318. $this->set('title_for_layout', __d('croogo', 'Create File'));
  319. if (isset($this->request->query['path'])) {
  320. $path = $this->request->query['path'];
  321. } else {
  322. return $this->redirect(array('controller' => 'file_manager', 'action' => 'browse'));
  323. }
  324. if (isset($path) && !$this->_isEditable($path)) {
  325. $this->Session->setFlash(__d('croogo', 'Path %s is restricted', $path), 'flash', array('class' => 'error'));
  326. return $this->redirect($this->referer());
  327. }
  328. if (!empty($this->request->data)) {
  329. if (touch($path . $this->request->data['FileManager']['name'])) {
  330. $this->Session->setFlash(__d('croogo', 'File created successfully.'), 'flash', array('class' => 'success'));
  331. $redirectUrl = Router::url(array('controller' => 'file_manager', 'action' => 'browse'), true) . '?path=' . urlencode($path);
  332. return $this->redirect($redirectUrl);
  333. } else {
  334. $this->Session->setFlash(__d('croogo', 'An error occured'), 'flash', array('class' => 'error'));
  335. }
  336. }
  337. $this->set(compact('path'));
  338. }
  339. /**
  340. * Admin chmod
  341. *
  342. * @return void
  343. * @access public
  344. */
  345. public function admin_chmod() {
  346. }
  347. }