[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/api/components/com_media/src/Controller/ -> MediaController.php (source)

   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  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer