[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/administrator/components/com_media/src/Controller/ -> ApiController.php (source)

   1  <?php
   2  
   3  /**
   4   * @package     Joomla.Administrator
   5   * @subpackage  com_media
   6   *
   7   * @copyright   (C) 2017 Open Source Matters, Inc. <https://www.joomla.org>
   8   * @license     GNU General Public License version 2 or later; see LICENSE.txt
   9   */
  10  
  11  namespace Joomla\Component\Media\Administrator\Controller;
  12  
  13  use Joomla\CMS\Component\ComponentHelper;
  14  use Joomla\CMS\Helper\MediaHelper;
  15  use Joomla\CMS\Language\Text;
  16  use Joomla\CMS\MVC\Controller\BaseController;
  17  use Joomla\CMS\MVC\Model\BaseModel;
  18  use Joomla\CMS\Response\JsonResponse;
  19  use Joomla\CMS\Session\Session;
  20  use Joomla\Component\Media\Administrator\Exception\FileExistsException;
  21  use Joomla\Component\Media\Administrator\Exception\FileNotFoundException;
  22  use Joomla\Component\Media\Administrator\Exception\InvalidPathException;
  23  
  24  // phpcs:disable PSR1.Files.SideEffects
  25  \defined('_JEXEC') or die;
  26  // phpcs:enable PSR1.Files.SideEffects
  27  
  28  /**
  29   * Api Media Controller
  30   *
  31   * This is NO public api controller, it is internal for the com_media component only!
  32   *
  33   * @since  4.0.0
  34   */
  35  class ApiController extends BaseController
  36  {
  37      /**
  38       * Execute a task by triggering a method in the derived class.
  39       *
  40       * @param   string  $task  The task to perform. If no matching task is found, the '__default' task is executed, if defined.
  41       *
  42       * @return  mixed   The value returned by the called method.
  43       *
  44       * @since   4.0.0
  45       * @throws  \Exception
  46       */
  47      public function execute($task)
  48      {
  49          $method = $this->input->getMethod();
  50  
  51          $this->task   = $task;
  52          $this->method = $method;
  53  
  54          try {
  55              // Check token for requests which do modify files (all except get requests)
  56              if ($method !== 'GET' && !Session::checkToken('json')) {
  57                  throw new \InvalidArgumentException(Text::_('JINVALID_TOKEN_NOTICE'), 403);
  58              }
  59  
  60              $doTask = strtolower($method) . ucfirst($task);
  61  
  62              // Record the actual task being fired
  63              $this->doTask = $doTask;
  64  
  65              if (!in_array($this->doTask, $this->taskMap)) {
  66                  throw new \Exception(Text::sprintf('JLIB_APPLICATION_ERROR_TASK_NOT_FOUND', $task), 405);
  67              }
  68  
  69              $data = $this->$doTask();
  70  
  71              // Return the data
  72              $this->sendResponse($data);
  73          } catch (FileNotFoundException $e) {
  74              $this->sendResponse($e, 404);
  75          } catch (FileExistsException $e) {
  76              $this->sendResponse($e, 409);
  77          } catch (InvalidPathException $e) {
  78              $this->sendResponse($e, 400);
  79          } catch (\Exception $e) {
  80              $errorCode = 500;
  81  
  82              if ($e->getCode() > 0) {
  83                  $errorCode = $e->getCode();
  84              }
  85  
  86              $this->sendResponse($e, $errorCode);
  87          }
  88      }
  89  
  90      /**
  91       * Files Get Method
  92       *
  93       * Examples:
  94       *
  95       * - GET a list of folders below the root:
  96       *      index.php?option=com_media&task=api.files
  97       *      /api/files
  98       * - GET a list of files and subfolders of a given folder:
  99       *      index.php?option=com_media&task=api.files&format=json&path=/sampledata/cassiopeia
 100       *      /api/files/sampledata/cassiopeia
 101       * - GET a list of files and subfolders of a given folder for a given search term:
 102       *   use recursive=1 to search recursively in the working directory
 103       *      index.php?option=com_media&task=api.files&format=json&path=/sampledata/cassiopeia&search=nasa5
 104       *      /api/files/sampledata/cassiopeia?search=nasa5
 105       *   To look up in same working directory set flag recursive=0
 106       *      index.php?option=com_media&task=api.files&format=json&path=/sampledata/cassiopeia&search=nasa5&recursive=0
 107       *      /api/files/sampledata/cassiopeia?search=nasa5&recursive=0
 108       * - GET file information for a specific file:
 109       *      index.php?option=com_media&task=api.files&format=json&path=/sampledata/cassiopeia/test.jpg
 110       *      /api/files/sampledata/cassiopeia/test.jpg
 111       * - GET a temporary URL to a given file
 112       *      index.php?option=com_media&task=api.files&format=json&path=/sampledata/cassiopeia/test.jpg&url=1&temp=1
 113       *      /api/files/sampledata/cassiopeia/test.jpg&url=1&temp=1
 114       * - GET a temporary URL to a given file
 115       *      index.php?option=com_media&task=api.files&format=json&path=/sampledata/cassiopeia/test.jpg&url=1
 116       *      /api/files/sampledata/cassiopeia/test.jpg&url=1
 117       *
 118       * @return  array  The data to send with the response
 119       *
 120       * @since   4.0.0
 121       * @throws  \Exception
 122       */
 123      public function getFiles()
 124      {
 125          // Grab options
 126          $options              = [];
 127          $options['url']       = $this->input->getBool('url', false);
 128          $options['search']    = $this->input->getString('search', '');
 129          $options['recursive'] = $this->input->getBool('recursive', true);
 130          $options['content']   = $this->input->getBool('content', false);
 131  
 132          return $this->getModel()->getFiles($this->getAdapter(), $this->getPath(), $options);
 133      }
 134  
 135      /**
 136       * Files delete Method
 137       *
 138       * Examples:
 139       *
 140       * - DELETE an existing folder in a specific folder:
 141       *      index.php?option=com_media&task=api.files&format=json&path=/sampledata/cassiopeia/test
 142       *      /api/files/sampledata/cassiopeia/test
 143       * - DELETE an existing file in a specific folder:
 144       *      index.php?option=com_media&task=api.files&path=/sampledata/cassiopeia/test.jpg
 145       *      /api/files/sampledata/cassiopeia/test.jpg
 146       *
 147       * @return  null
 148       *
 149       * @since   4.0.0
 150       * @throws  \Exception
 151       */
 152      public function deleteFiles()
 153      {
 154          if (!$this->app->getIdentity()->authorise('core.delete', 'com_media')) {
 155              throw new \Exception(Text::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED'), 403);
 156          }
 157  
 158          $this->getModel()->delete($this->getAdapter(), $this->getPath());
 159  
 160          return null;
 161      }
 162  
 163      /**
 164       * Files Post Method
 165       *
 166       * Examples:
 167       *
 168       * - POST a new file or folder into a specific folder, the file or folder information is returned:
 169       *      index.php?option=com_media&task=api.files&format=json&path=/sampledata/cassiopeia
 170       *      /api/files/sampledata/cassiopeia
 171       *
 172       *      New file body:
 173       *      {
 174       *          "name": "test.jpg",
 175       *          "content":"base64 encoded image"
 176       *      }
 177       *      New folder body:
 178       *      {
 179       *          "name": "test",
 180       *      }
 181       *
 182       * @return  array  The data to send with the response
 183       *
 184       * @since   4.0.0
 185       * @throws  \Exception
 186       */
 187      public function postFiles()
 188      {
 189          if (!$this->app->getIdentity()->authorise('core.create', 'com_media')) {
 190              throw new \Exception(Text::_('JLIB_APPLICATION_ERROR_CREATE_RECORD_NOT_PERMITTED'), 403);
 191          }
 192  
 193          $adapter      = $this->getAdapter();
 194          $path         = $this->getPath();
 195          $content      = $this->input->json;
 196          $name         = $content->getString('name');
 197          $mediaContent = base64_decode($content->get('content', '', 'raw'));
 198          $override     = $content->get('override', false);
 199  
 200          if ($mediaContent) {
 201              $this->checkContent();
 202  
 203              // A file needs to be created
 204              $name = $this->getModel()->createFile($adapter, $name, $path, $mediaContent, $override);
 205          } else {
 206              // A file needs to be created
 207              $name = $this->getModel()->createFolder($adapter, $name, $path, $override);
 208          }
 209  
 210          $options        = [];
 211          $options['url'] = $this->input->getBool('url', false);
 212  
 213          return $this->getModel()->getFile($adapter, $path . '/' . $name, $options);
 214      }
 215  
 216      /**
 217       * Files Put method
 218       *
 219       * Examples:
 220       *
 221       * - PUT a media file, the file or folder information is returned:
 222       *      index.php?option=com_media&task=api.files&format=json&path=/sampledata/cassiopeia/test.jpg
 223       *      /api/files/sampledata/cassiopeia/test.jpg
 224       *
 225       *      Update file body:
 226       *      {
 227       *          "content":"base64 encoded image"
 228       *      }
 229       *
 230       * - PUT move a file, folder to another one
 231       *     path : will be taken as the source
 232       *     index.php?option=com_media&task=api.files&format=json&path=/sampledata/cassiopeia/test.jpg
 233       *     /api/files/sampledata/cassiopeia/test.jpg
 234       *
 235       *     JSON body:
 236       *     {
 237       *          "newPath" : "/path/to/destination",
 238       *          "move"    : "1"
 239       *     }
 240       *
 241       * - PUT copy a file, folder to another one
 242       *     path : will be taken as the source
 243       *     index.php?option=com_media&task=api.files&format=json&path=/sampledata/cassiopeia/test.jpg
 244       *     /api/files/sampledata/cassiopeia/test.jpg
 245       *
 246       *     JSON body:
 247       *     {
 248       *          "newPath" : "/path/to/destination",
 249       *          "move"    : "0"
 250       *     }
 251       *
 252       * @return  array  The data to send with the response
 253       *
 254       * @since   4.0.0
 255       * @throws  \Exception
 256       */
 257      public function putFiles()
 258      {
 259          if (!$this->app->getIdentity()->authorise('core.edit', 'com_media')) {
 260              throw new \Exception(Text::_('JLIB_APPLICATION_ERROR_EDIT_NOT_PERMITTED'), 403);
 261          }
 262  
 263          $adapter = $this->getAdapter();
 264          $path    = $this->getPath();
 265  
 266          $content      = $this->input->json;
 267          $name         = basename($path);
 268          $mediaContent = base64_decode($content->get('content', '', 'raw'));
 269          $newPath      = $content->getString('newPath', null);
 270          $move         = $content->get('move', true);
 271  
 272          if ($mediaContent != null) {
 273              $this->checkContent();
 274  
 275              $this->getModel()->updateFile($adapter, $name, str_replace($name, '', $path), $mediaContent);
 276          }
 277  
 278          if ($newPath != null && $newPath !== $adapter . ':' . $path) {
 279              list($destinationAdapter, $destinationPath) = explode(':', $newPath, 2);
 280  
 281              if ($move) {
 282                  $destinationPath = $this->getModel()->move($adapter, $path, $destinationPath, false);
 283              } else {
 284                  $destinationPath = $this->getModel()->copy($adapter, $path, $destinationPath, false);
 285              }
 286  
 287              $path = $destinationPath;
 288          }
 289  
 290          return $this->getModel()->getFile($adapter, $path);
 291      }
 292  
 293      /**
 294       * Send the given data as JSON response in the following format:
 295       *
 296       * {"success":true,"message":"ok","messages":null,"data":[{"type":"dir","name":"banners","path":"//"}]}
 297       *
 298       * @param   mixed    $data          The data to send
 299       * @param   integer  $responseCode  The response code
 300       *
 301       * @return  void
 302       *
 303       * @since   4.0.0
 304       */
 305      private function sendResponse($data = null, int $responseCode = 200)
 306      {
 307          // Set the correct content type
 308          $this->app->setHeader('Content-Type', 'application/json');
 309  
 310          // Set the status code for the response
 311          http_response_code($responseCode);
 312  
 313          // Send the data
 314          echo new JsonResponse($data);
 315  
 316          $this->app->close();
 317      }
 318  
 319      /**
 320       * Method to get a model object, loading it if required.
 321       *
 322       * @param   string  $name    The model name. Optional.
 323       * @param   string  $prefix  The class prefix. Optional.
 324       * @param   array   $config  Configuration array for model. Optional.
 325       *
 326       * @return  BaseModel|boolean  Model object on success; otherwise false on failure.
 327       *
 328       * @since   4.0.0
 329       */
 330      public function getModel($name = 'Api', $prefix = 'Administrator', $config = [])
 331      {
 332          return parent::getModel($name, $prefix, $config);
 333      }
 334  
 335      /**
 336       * Performs various checks if it is allowed to save the content.
 337       *
 338       * @return  void
 339       *
 340       * @since   4.0.0
 341       * @throws  \Exception
 342       */
 343      private function checkContent()
 344      {
 345          $helper              = new MediaHelper();
 346          $contentLength       = $this->input->server->getInt('CONTENT_LENGTH');
 347          $params              = ComponentHelper::getParams('com_media');
 348          $paramsUploadMaxsize = $params->get('upload_maxsize', 0) * 1024 * 1024;
 349          $uploadMaxFilesize   = $helper->toBytes(ini_get('upload_max_filesize'));
 350          $postMaxSize         = $helper->toBytes(ini_get('post_max_size'));
 351          $memoryLimit         = $helper->toBytes(ini_get('memory_limit'));
 352  
 353          if (
 354              ($paramsUploadMaxsize > 0 && $contentLength > $paramsUploadMaxsize)
 355              || ($uploadMaxFilesize > 0 && $contentLength > $uploadMaxFilesize)
 356              || ($postMaxSize > 0 && $contentLength > $postMaxSize)
 357              || ($memoryLimit > -1 && $contentLength > $memoryLimit)
 358          ) {
 359              throw new \Exception(Text::_('COM_MEDIA_ERROR_WARNFILETOOLARGE'), 403);
 360          }
 361      }
 362  
 363      /**
 364       * Get the Adapter.
 365       *
 366       * @return  string
 367       *
 368       * @since   4.0.0
 369       */
 370      private function getAdapter()
 371      {
 372          $parts = explode(':', $this->input->getString('path', ''), 2);
 373  
 374          if (count($parts) < 1) {
 375              return null;
 376          }
 377  
 378          return $parts[0];
 379      }
 380  
 381      /**
 382       * Get the Path.
 383       *
 384       * @return  string
 385       *
 386       * @since   4.0.0
 387       */
 388      private function getPath()
 389      {
 390          $parts = explode(':', $this->input->getString('path', ''), 2);
 391  
 392          if (count($parts) < 2) {
 393              return null;
 394          }
 395  
 396          return $parts[1];
 397      }
 398  }


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