[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * @package Joomla.API 4 * @subpackage com_media 5 * 6 * @copyright (C) 2021 Open Source Matters, Inc. <https://www.joomla.org> 7 * @license GNU General Public License version 2 or later; see LICENSE.txt 8 */ 9 10 namespace Joomla\Component\Media\Api\Controller; 11 12 \defined('_JEXEC') or die; 13 14 use Joomla\CMS\Access\Exception\NotAllowed; 15 use Joomla\CMS\Component\ComponentHelper; 16 use Joomla\CMS\Filter\InputFilter; 17 use Joomla\CMS\Language\Text; 18 use Joomla\CMS\MVC\Controller\ApiController; 19 use Joomla\Component\Media\Administrator\Exception\FileExistsException; 20 use Joomla\Component\Media\Administrator\Exception\InvalidPathException; 21 use Joomla\Component\Media\Administrator\Provider\ProviderManagerHelperTrait; 22 use Joomla\Component\Media\Api\Model\MediumModel; 23 use Joomla\String\Inflector; 24 use Tobscure\JsonApi\Exception\InvalidParameterException; 25 26 /** 27 * Media web service controller. 28 * 29 * @since 4.1.0 30 */ 31 class MediaController extends ApiController 32 { 33 use ProviderManagerHelperTrait; 34 35 /** 36 * The content type of the item. 37 * 38 * @var string 39 * @since 4.1.0 40 */ 41 protected $contentType = 'media'; 42 43 /** 44 * Query parameters => model state mappings 45 * 46 * @var array 47 * @since 4.1.0 48 */ 49 private static $listQueryModelStateMap = [ 50 'path' => [ 51 'name' => 'path', 52 'type' => 'STRING', 53 ], 54 'url' => [ 55 'name' => 'url', 56 'type' => 'BOOLEAN', 57 ], 58 'temp' => [ 59 'name' => 'temp', 60 'type' => 'BOOLEAN', 61 ], 62 'content' => [ 63 'name' => 'content', 64 'type' => 'BOOLEAN', 65 ], 66 ]; 67 68 /** 69 * Item query parameters => model state mappings 70 * 71 * @var array 72 * @since 4.1.0 73 */ 74 private static $itemQueryModelStateMap = [ 75 'path' => [ 76 'name' => 'path', 77 'type' => 'STRING', 78 ], 79 'url' => [ 80 'name' => 'url', 81 'type' => 'BOOLEAN', 82 ], 83 'temp' => [ 84 'name' => 'temp', 85 'type' => 'BOOLEAN', 86 ], 87 'content' => [ 88 'name' => 'content', 89 'type' => 'BOOLEAN', 90 ], 91 ]; 92 93 /** 94 * The default view for the display method. 95 * 96 * @var string 97 * 98 * @since 4.1.0 99 */ 100 protected $default_view = 'media'; 101 102 /** 103 * Display a list of files and/or folders. 104 * 105 * @return static A \JControllerLegacy object to support chaining. 106 * 107 * @since 4.1.0 108 * 109 * @throws \Exception 110 */ 111 public function displayList() 112 { 113 // Set list specific request parameters in model state. 114 $this->setModelState(self::$listQueryModelStateMap); 115 116 // Display files in specific path. 117 if ($this->input->exists('path')) 118 { 119 $this->modelState->set('path', $this->input->get('path', '', 'STRING')); 120 } 121 122 // Return files (not folders) as urls. 123 if ($this->input->exists('url')) 124 { 125 $this->modelState->set('url', $this->input->get('url', true, 'BOOLEAN')); 126 } 127 128 // Map JSON:API compliant filter[search] to com_media model state. 129 $apiFilterInfo = $this->input->get('filter', [], 'array'); 130 $filter = InputFilter::getInstance(); 131 132 // Search for files matching (part of) a name or glob pattern. 133 if (\array_key_exists('search', $apiFilterInfo)) 134 { 135 $this->modelState->set('search', $filter->clean($apiFilterInfo['search'], 'STRING')); 136 137 // Tell model to search recursively 138 $this->modelState->set('search_recursive', $this->input->get('search_recursive', false, 'BOOLEAN')); 139 } 140 141 return parent::displayList(); 142 } 143 144 /** 145 * Display one specific file or folder. 146 * 147 * @param string $path The path of the file to display. Leave empty if you want to retrieve data from the request. 148 * 149 * @return static A \JControllerLegacy object to support chaining. 150 * 151 * @since 4.1.0 152 * 153 * @throws InvalidPathException 154 * @throws \Exception 155 */ 156 public function displayItem($path = '') 157 { 158 // Set list specific request parameters in model state. 159 $this->setModelState(self::$itemQueryModelStateMap); 160 161 // Display files in specific path. 162 $this->modelState->set('path', $path ?: $this->input->get('path', '', 'STRING')); 163 164 // Return files (not folders) as urls. 165 if ($this->input->exists('url')) 166 { 167 $this->modelState->set('url', $this->input->get('url', true, 'BOOLEAN')); 168 } 169 170 return parent::displayItem(); 171 } 172 173 /** 174 * Set model state using a list of mappings between query parameters and model state names. 175 * 176 * @param array $mappings A list of mappings between query parameters and model state names. 177 * 178 * @return void 179 * 180 * @since 4.1.0 181 */ 182 private function setModelState(array $mappings): void 183 { 184 foreach ($mappings as $queryName => $modelState) 185 { 186 if ($this->input->exists($queryName)) 187 { 188 $this->modelState->set($modelState['name'], $this->input->get($queryName, '', $modelState['type'])); 189 } 190 } 191 } 192 193 /** 194 * Method to add a new file or folder. 195 * 196 * @return void 197 * 198 * @since 4.1.0 199 * 200 * @throws FileExistsException 201 * @throws InvalidPathException 202 * @throws InvalidParameterException 203 * @throws \RuntimeException 204 * @throws \Exception 205 */ 206 public function add(): void 207 { 208 $path = $this->input->json->get('path', '', 'STRING'); 209 $content = $this->input->json->get('content', '', 'RAW'); 210 211 $missingParameters = []; 212 213 if (empty($path)) 214 { 215 $missingParameters[] = 'path'; 216 } 217 218 // Content is only required when it is a file 219 if (empty($content) && strpos($path, '.') !== false) 220 { 221 $missingParameters[] = 'content'; 222 } 223 224 if (\count($missingParameters)) 225 { 226 throw new InvalidParameterException( 227 Text::sprintf('WEBSERVICE_COM_MEDIA_MISSING_REQUIRED_PARAMETERS', implode(' & ', $missingParameters)) 228 ); 229 } 230 231 $this->modelState->set('path', $this->input->json->get('path', '', 'STRING')); 232 233 // Check if an existing file may be overwritten. Defaults to false. 234 $this->modelState->set('override', $this->input->json->get('override', false)); 235 236 parent::add(); 237 } 238 239 /** 240 * Method to check if it's allowed to add a new file or folder 241 * 242 * @param array $data An array of input data. 243 * 244 * @return boolean 245 * 246 * @since 4.1.0 247 */ 248 protected function allowAdd($data = array()): bool 249 { 250 $user = $this->app->getIdentity(); 251 252 return $user->authorise('core.create', 'com_media'); 253 } 254 255 /** 256 * Method to modify an existing file or folder. 257 * 258 * @return void 259 * 260 * @since 4.1.0 261 * 262 * @throws FileExistsException 263 * @throws InvalidPathException 264 * @throws \RuntimeException 265 * @throws \Exception 266 */ 267 public function edit(): void 268 { 269 // Access check. 270 if (!$this->allowEdit()) 271 { 272 throw new NotAllowed('JLIB_APPLICATION_ERROR_CREATE_RECORD_NOT_PERMITTED', 403); 273 } 274 275 $path = $this->input->json->get('path', '', 'STRING'); 276 $content = $this->input->json->get('content', '', 'RAW'); 277 278 if (empty($path) && empty($content)) 279 { 280 throw new InvalidParameterException( 281 Text::sprintf('WEBSERVICE_COM_MEDIA_MISSING_REQUIRED_PARAMETERS', 'path | content') 282 ); 283 } 284 285 $this->modelState->set('path', $this->input->json->get('path', '', 'STRING')); 286 // For renaming/moving files, we need the path to the existing file or folder. 287 $this->modelState->set('old_path', $this->input->get('path', '', 'STRING')); 288 // Check if an existing file may be overwritten. Defaults to true. 289 $this->modelState->set('override', $this->input->json->get('override', true)); 290 291 $recordId = $this->save(); 292 293 $this->displayItem($recordId); 294 } 295 296 /** 297 * Method to check if it's allowed to modify an existing file or folder. 298 * 299 * @param array $data An array of input data. 300 * 301 * @return boolean 302 * 303 * @since 4.1.0 304 */ 305 protected function allowEdit($data = array(), $key = 'id'): bool 306 { 307 $user = $this->app->getIdentity(); 308 309 // com_media's access rules contains no specific update rule. 310 return $user->authorise('core.edit', 'com_media'); 311 } 312 313 /** 314 * Method to create or modify a file or folder. 315 * 316 * @param integer $recordKey The primary key of the item (if exists) 317 * 318 * @return string The path 319 * 320 * @since 4.1.0 321 */ 322 protected function save($recordKey = null) 323 { 324 // Explicitly get the single item model name. 325 $modelName = $this->input->get('model', Inflector::singularize($this->contentType)); 326 327 /** @var MediumModel $model */ 328 $model = $this->getModel($modelName, '', ['ignore_request' => true, 'state' => $this->modelState]); 329 330 $json = $this->input->json; 331 332 // Decode content, if any 333 if ($content = base64_decode($json->get('content', '', 'raw'))) 334 { 335 $this->checkContent(); 336 } 337 338 // If there is no content, com_media assumes the path refers to a folder. 339 $this->modelState->set('content', $content); 340 341 return $model->save(); 342 } 343 344 /** 345 * Performs various checks to see if it is allowed to save the content. 346 * 347 * @return void 348 * 349 * @since 4.1.0 350 * 351 * @throws \RuntimeException 352 */ 353 private function checkContent(): void 354 { 355 $params = ComponentHelper::getParams('com_media'); 356 $helper = new \Joomla\CMS\Helper\MediaHelper(); 357 $serverlength = $this->input->server->getInt('CONTENT_LENGTH'); 358 359 // Check if the size of the request body does not exceed various server imposed limits. 360 if (($params->get('upload_maxsize', 0) > 0 && $serverlength > ($params->get('upload_maxsize', 0) * 1024 * 1024)) 361 || $serverlength > $helper->toBytes(ini_get('upload_max_filesize')) 362 || $serverlength > $helper->toBytes(ini_get('post_max_size')) 363 || $serverlength > $helper->toBytes(ini_get('memory_limit'))) 364 { 365 throw new \RuntimeException(Text::_('COM_MEDIA_ERROR_WARNFILETOOLARGE'), 400); 366 } 367 } 368 369 /** 370 * Method to delete an existing file or folder. 371 * 372 * @return void 373 * 374 * @since 4.1.0 375 * 376 * @throws InvalidPathException 377 * @throws \RuntimeException 378 * @throws \Exception 379 */ 380 public function delete($id = null): void 381 { 382 if (!$this->allowDelete()) 383 { 384 throw new NotAllowed('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED', 403); 385 } 386 387 $this->modelState->set('path', $this->input->get('path', '', 'STRING')); 388 389 $modelName = $this->input->get('model', Inflector::singularize($this->contentType)); 390 $model = $this->getModel($modelName, '', ['ignore_request' => true, 'state' => $this->modelState]); 391 392 $model->delete(); 393 394 $this->app->setHeader('status', 204); 395 } 396 397 /** 398 * Method to check if it's allowed to delete an existing file or folder. 399 * 400 * @return boolean 401 * 402 * @since 4.1.0 403 */ 404 protected function allowDelete(): bool 405 { 406 $user = $this->app->getIdentity(); 407 408 return $user->authorise('core.delete', 'com_media'); 409 } 410 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |