MediaController.php
1 <?php
2 /**
3  * wCMF - wemove Content Management Framework
4  * Copyright (C) 2005-2020 wemove digital solutions GmbH
5  *
6  * Licensed under the terms of the MIT License.
7  *
8  * See the LICENSE file distributed with this work for
9  * additional information.
10  */
12 
17 
18 if (!class_exists('\elFinder')) {
19  throw new ConfigurationException(
20  'wcmf\application\controller\MediaController requires '.
21  'elFinder. If you are using composer, add studio-42/elfinder '.
22  'as dependency to your project');
23 }
24 
25 /**
26  * MediaController integrates elFinder (https://github.com/Studio-42/elFinder) into wCMF.
27  *
28  * @note This class requires ElFinder
29  *
30  * The controller supports the following actions:
31  *
32  * <div class="controller-action">
33  * <div> __Action__ browseMedia </div>
34  * <div>
35  * Run elFinder.
36  * | Parameter | Description
37  * |--------------------------|-------------------------
38  * | _in_ `directory` | elFinder _startPath_ parameter
39  * | _in_ / _out_ `fieldName` | The name of the input field that should receive the url of the selected file. if not given, elFinder will search for a CkEditor instance and set the url on that.
40  * | _out_ `rootUrl` | Root url of all media as derived from the configuration value _uploadDir_ in the configuration section _media_
41  * | _out_ `rootPath` | Root path of all media as derived from the configuration value _uploadDir_ in the configuration section _media_
42  * | __Response Actions__ | |
43  * | `ok` | In all cases
44  * </div>
45  * </div>
46  *
47  * @note elFinder defines action names in the _cmd_ parameter.
48  *
49  * @author ingo herwig <ingo@wemove.com>
50  */
51 class MediaController extends Controller {
52 
53  /**
54  * @see Controller::doExecute()
55  */
56  protected function doExecute($method=null) {
57  $request = $this->getRequest();
58  $response = $this->getResponse();
59 
60  $fileUtil = new FileUtil();
61 
62  // get root path and root url for the browser
63  $rootPath = $this->getResourceBaseDir();
64  $relRootPath = URIUtil::makeRelative($rootPath, dirname($fileUtil->realpath($_SERVER['SCRIPT_FILENAME'])));
65  $refURL = dirname(URIUtil::getProtocolStr().$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME']).'/';
66  $rootUrl = URIUtil::makeAbsolute($relRootPath, $refURL);
67 
68  // requested directory (elFinder expects DIRECTORY_SEPARATOR)
69  if (!is_dir($request->getValue('directory'))) {
70  // empty if not valid
71  $request->clearValue('directory');
72  }
73  else {
74  // force elFinder to use directory parameter
75  $request->setValue('target', '');
76  }
77  $directory = $request->hasValue('directory') ? $request->getValue('directory') : $rootPath;
78  $absDirectory = $fileUtil->realpath($directory).'/';
79 
80  // set common response values
81  if ($request->hasValue('fieldName')) {
82  $response->setValue('fieldName', $request->getValue('fieldName'));
83  }
84  $response->setValue('rootUrl', $rootUrl);
85  $response->setValue('rootPath', $rootPath);
86 
87  // get configuration
88  $config = $this->getConfiguration();
89  $lowercase = $config->hasValue('lowercase', 'media') ? $config->getBooleanValue('lowercase', 'media') : true;
90 
91  if ($request->getAction() == "browseMedia") {
92  $opts = [
93  'plugin' => [
94  'Normalizer' => [
95  'enable' => true,
96  'nfc' => true,
97  'nfkc' => true,
98  'umlauts' => true,
99  'lowercase' => $lowercase,
100  'convmap' => [],
101  ],
102  'Sanitizer' => [
103  'enable' => true,
104  'targets' => ['\\','/',':','*','?','"','<','>','|'],
105  'replace' => '_',
106  ],
107  ],
108  // 'debug' => true,
109  'roots' => [[
110  'driver' => 'LocalFileSystem',
111  'path' => str_replace('/', DIRECTORY_SEPARATOR, rtrim($rootPath, '/')),
112  'URL' => $rootUrl,
113  'alias' => 'Media',
114  'tmbBgColor' => 'transparent',
115  'startPath' => str_replace('/', DIRECTORY_SEPARATOR, rtrim($absDirectory, '/')),
116  'checkSubfolders' => false,
117  'treeDeep' => 1,
118  'accessControl' => [$this, 'access'],
119  ]],
120  'bind' => [
121  'rename rm paste' => [$this, 'onFileMoved'],
122  'upload.pre mkdir.pre archive.pre ls.pre' => [
123  'Plugin.Normalizer.cmdPreprocess'
124  ],
125  'ls' => [
126  'Plugin.Normalizer.cmdPostprocess'
127  ],
128  'mkdir.pre mkfile.pre rename.pre' => [
129  'Plugin.Sanitizer.cmdPreprocess',
130  'Plugin.Normalizer.cmdPreprocess'
131  ],
132  'upload.presave' => [
133  'Plugin.Sanitizer.onUpLoadPreSave',
134  'Plugin.Normalizer.onUpLoadPreSave'
135  ],
136  ],
137  ];
138 
139  // run elFinder
140  $connector = new \elFinderConnector(new \elFinder($opts));
141  $queryParams = $request->getValues();
142  $connector->run($queryParams);
143 
144  // unreachable, since elFinder calls exit()
145  $response->setAction('ok');
146  }
147  }
148 
149  /**
150  * Called when file is moved
151  * @param $cmd elFinder command name
152  * @param $result Command result as array
153  * @param $args Command arguments from client
154  * @param $elfinder elFinder instance
155  **/
156  protected function onFileMoved($cmd, $result, $args, $elfinder) {
157  $addedFiles = $result['added'];
158  $removedFiles = $result['removed'];
159  for ($i=0, $count=sizeof($removedFiles); $i<$count; $i++) {
160  $source = $removedFiles[$i]['realpath'];
161  $target = $elfinder->realpath($addedFiles[$i]['hash']);
162  }
163  $logger = $this->getLogger();
164  $logger->debug($cmd." file: ".$source." -> ".$target);
165  }
166 
167  /**
168  * Access control
169  * @param $attr Attribute name (read|write|locked|hidden)
170  * @param $path Absolute file path
171  * @param $data Value of volume option `accessControlData`
172  * @param $volume elFinder volume driver object
173  * @param $isDir Path is directory (true: directory, false: file, null: unknown)
174  * @param $relpath File path relative to volume root directory started with directory separator
175  * @return Boolean or null (elFinder decides)
176  **/
177  public function access($attr, $path, $data, $volume, $isDir, $relpath) {
178  // authorize using permission manager, but use no default policy
179  return $this->getPermissionManager()->authorize('media:'.$relpath, '', $attr, null, false);
180  }
181 
182  /**
183  * Get the base directory for resources. The default implementation
184  * returns the directory configured by the 'uploadDir' key in section 'media'.
185  * @return The directory name
186  * @note Subclasses will override this method to implement special application requirements
187  */
188  protected function getResourceBaseDir() {
189  $config = $this->getConfiguration();
190  $rootPath = $config->getDirectoryValue('uploadDir', 'media');
191  return $rootPath;
192  }
193 }
194 ?>
getConfiguration()
Get the Configuration instance.
Definition: Controller.php:323
getResourceBaseDir()
Get the base directory for resources.
static makeAbsolute($relUri, $base)
Convert a relative URI to an absolute code from http://99webtools.com/relative-path-into-absolute-url...
Definition: URIUtil.php:66
access($attr, $path, $data, $volume, $isDir, $relpath)
Access control.
getPermissionManager()
Get the PermissionManager instance.
Definition: Controller.php:291
MediaController integrates elFinder (https://github.com/Studio-42/elFinder) into wCMF.
ConfigurationException signals an exception in the configuration.
getLogger()
Get the Logger instance.
Definition: Controller.php:267
URIUtil provides support for uri manipulation.
Definition: URIUtil.php:18
getRequest()
Get the Request instance.
Definition: Controller.php:251
FileUtil provides basic support for file functionality like HTTP file upload.
Definition: FileUtil.php:22
Application controllers.
Definition: namespaces.php:3
Controller is the base class of all controllers.
Definition: Controller.php:49
onFileMoved($cmd, $result, $args, $elfinder)
Called when file is moved.
getResponse()
Get the Response instance.
Definition: Controller.php:259
static getProtocolStr()
Definition: URIUtil.php:169
static makeRelative($absUri, $base)
Convert an absolute URI to a relative code from http://www.webmasterworld.com/forum88/334....
Definition: URIUtil.php:27