[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/src/Installer/ -> InstallerScript.php (source)

   1  <?php
   2  
   3  /**
   4   * Joomla! Content Management System
   5   *
   6   * @copyright  (C) 2016 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\CMS\Installer;
  11  
  12  use Joomla\CMS\Factory;
  13  use Joomla\CMS\Filesystem\File;
  14  use Joomla\CMS\Filesystem\Folder;
  15  use Joomla\CMS\Language\Text;
  16  use Joomla\CMS\Log\Log;
  17  use Joomla\Database\ParameterType;
  18  
  19  // phpcs:disable PSR1.Files.SideEffects
  20  \defined('_JEXEC') or die;
  21  // phpcs:enable PSR1.Files.SideEffects
  22  
  23  /**
  24   * Base install script for use by extensions providing helper methods for common behaviours.
  25   *
  26   * @since  3.6
  27   */
  28  class InstallerScript
  29  {
  30      /**
  31       * The version number of the extension.
  32       *
  33       * @var    string
  34       * @since  3.6
  35       */
  36      protected $release;
  37  
  38      /**
  39       * The table the parameters are stored in.
  40       *
  41       * @var    string
  42       * @since  3.6
  43       */
  44      protected $paramTable;
  45  
  46      /**
  47       * The extension name. This should be set in the installer script.
  48       *
  49       * @var    string
  50       * @since  3.6
  51       */
  52      protected $extension;
  53  
  54      /**
  55       * A list of files to be deleted
  56       *
  57       * @var    array
  58       * @since  3.6
  59       */
  60      protected $deleteFiles = array();
  61  
  62      /**
  63       * A list of folders to be deleted
  64       *
  65       * @var    array
  66       * @since  3.6
  67       */
  68      protected $deleteFolders = array();
  69  
  70      /**
  71       * A list of CLI script files to be copied to the cli directory
  72       *
  73       * @var    array
  74       * @since  3.6
  75       */
  76      protected $cliScriptFiles = array();
  77  
  78      /**
  79       * Minimum PHP version required to install the extension
  80       *
  81       * @var    string
  82       * @since  3.6
  83       */
  84      protected $minimumPhp;
  85  
  86      /**
  87       * Minimum Joomla! version required to install the extension
  88       *
  89       * @var    string
  90       * @since  3.6
  91       */
  92      protected $minimumJoomla;
  93  
  94      /**
  95       * Allow downgrades of your extension
  96       *
  97       * Use at your own risk as if there is a change in functionality people may wish to downgrade.
  98       *
  99       * @var    boolean
 100       * @since  3.6
 101       */
 102      protected $allowDowngrades = false;
 103  
 104      /**
 105       * Function called before extension installation/update/removal procedure commences
 106       *
 107       * @param   string            $type    The type of change (install, update or discover_install, not uninstall)
 108       * @param   InstallerAdapter  $parent  The class calling this method
 109       *
 110       * @return  boolean  True on success
 111       *
 112       * @since   3.6
 113       */
 114      public function preflight($type, $parent)
 115      {
 116          // Check for the minimum PHP version before continuing
 117          if (!empty($this->minimumPhp) && version_compare(PHP_VERSION, $this->minimumPhp, '<')) {
 118              Log::add(Text::sprintf('JLIB_INSTALLER_MINIMUM_PHP', $this->minimumPhp), Log::WARNING, 'jerror');
 119  
 120              return false;
 121          }
 122  
 123          // Check for the minimum Joomla version before continuing
 124          if (!empty($this->minimumJoomla) && version_compare(JVERSION, $this->minimumJoomla, '<')) {
 125              Log::add(Text::sprintf('JLIB_INSTALLER_MINIMUM_JOOMLA', $this->minimumJoomla), Log::WARNING, 'jerror');
 126  
 127              return false;
 128          }
 129  
 130          // Extension manifest file version
 131          $this->extension = $parent->getName();
 132          $this->release   = $parent->getManifest()->version;
 133          $extensionType   = substr($this->extension, 0, 3);
 134  
 135          // Modules parameters are located in the module table - else in the extension table
 136          if ($extensionType === 'mod') {
 137              $this->paramTable = '#__modules';
 138          } else {
 139              $this->paramTable = '#__extensions';
 140          }
 141  
 142          // Abort if the extension being installed is not newer than the currently installed version
 143          if (!$this->allowDowngrades && strtolower($type) === 'update') {
 144              $manifest = $this->getItemArray('manifest_cache', '#__extensions', 'element', $this->extension);
 145  
 146              // Check whether we have an old release installed and skip this check when this here is the initial install.
 147              if (!isset($manifest['version'])) {
 148                  return true;
 149              }
 150  
 151              $oldRelease = $manifest['version'];
 152  
 153              if (version_compare($this->release, $oldRelease, '<')) {
 154                  Factory::getApplication()->enqueueMessage(Text::sprintf('JLIB_INSTALLER_INCORRECT_SEQUENCE', $oldRelease, $this->release), 'error');
 155  
 156                  return false;
 157              }
 158          }
 159  
 160          return true;
 161      }
 162  
 163      /**
 164       * Gets each instance of a module in the #__modules table
 165       *
 166       * @param   boolean  $isModule  True if the extension is a module as this can have multiple instances
 167       *
 168       * @return  array  An array of ID's of the extension
 169       *
 170       * @since   3.6
 171       */
 172      public function getInstances($isModule)
 173      {
 174          $extension = $this->extension;
 175  
 176          $db = Factory::getDbo();
 177          $query = $db->getQuery(true);
 178  
 179          // Select the item(s) and retrieve the id
 180          $query->select($db->quoteName('id'));
 181  
 182          if ($isModule) {
 183              $query->from($db->quoteName('#__modules'))
 184                  ->where($db->quoteName('module') . ' = :extension');
 185          } else {
 186              $query->from($db->quoteName('#__extensions'))
 187                  ->where($db->quoteName('element') . ' = :extension');
 188          }
 189  
 190          $query->bind(':extension', $extension);
 191  
 192          // Set the query and obtain an array of id's
 193          return $db->setQuery($query)->loadColumn();
 194      }
 195  
 196      /**
 197       * Gets parameter value in the extensions row of the extension table
 198       *
 199       * @param   string   $name  The name of the parameter to be retrieved
 200       * @param   integer  $id    The id of the item in the Param Table
 201       *
 202       * @return  string  The parameter desired
 203       *
 204       * @since   3.6
 205       */
 206      public function getParam($name, $id = 0)
 207      {
 208          if (!\is_int($id) || $id == 0) {
 209              // Return false if there is no item given
 210              return false;
 211          }
 212  
 213          $params = $this->getItemArray('params', $this->paramTable, 'id', $id);
 214  
 215          return $params[$name];
 216      }
 217  
 218      /**
 219       * Sets parameter values in the extensions row of the extension table. Note that the
 220       * this must be called separately for deleting and editing. Note if edit is called as a
 221       * type then if the param doesn't exist it will be created
 222       *
 223       * @param   array    $paramArray  The array of parameters to be added/edited/removed
 224       * @param   string   $type        The type of change to be made to the param (edit/remove)
 225       * @param   integer  $id          The id of the item in the relevant table
 226       *
 227       * @return  boolean  True on success
 228       *
 229       * @since   3.6
 230       */
 231      public function setParams($paramArray = null, $type = 'edit', $id = 0)
 232      {
 233          if (!\is_int($id) || $id == 0) {
 234              // Return false if there is no valid item given
 235              return false;
 236          }
 237  
 238          $params = $this->getItemArray('params', $this->paramTable, 'id', $id);
 239  
 240          if ($paramArray) {
 241              foreach ($paramArray as $name => $value) {
 242                  if ($type === 'edit') {
 243                      // Add or edit the new variable(s) to the existing params
 244                      if (\is_array($value)) {
 245                          // Convert an array into a json encoded string
 246                          $params[(string) $name] = array_values($value);
 247                      } else {
 248                          $params[(string) $name] = (string) $value;
 249                      }
 250                  } elseif ($type === 'remove') {
 251                      // Unset the parameter from the array
 252                      unset($params[(string) $name]);
 253                  }
 254              }
 255          }
 256  
 257          // Store the combined new and existing values back as a JSON string
 258          $paramsString = json_encode($params);
 259  
 260          $db = Factory::getDbo();
 261          $query = $db->getQuery(true)
 262              ->update($db->quoteName($this->paramTable))
 263              ->set('params = :params')
 264              ->where('id = :id')
 265              ->bind(':params', $paramsString)
 266              ->bind(':id', $id, ParameterType::INTEGER);
 267  
 268          // Update table
 269          $db->setQuery($query)->execute();
 270  
 271          return true;
 272      }
 273  
 274      /**
 275       * Builds a standard select query to produce better DRY code in this script.
 276       * This should produce a single unique cell which is json encoded - it will then
 277       * return an associated array with this data in.
 278       *
 279       * @param   string  $element     The element to get from the query
 280       * @param   string  $table       The table to search for the data in
 281       * @param   string  $column      The column of the database to search from
 282       * @param   mixed   $identifier  The integer id or the string
 283       *
 284       * @return  array  Associated array containing data from the cell
 285       *
 286       * @since   3.6
 287       */
 288      public function getItemArray($element, $table, $column, $identifier)
 289      {
 290          // Get the DB and query objects
 291          $db = Factory::getDbo();
 292  
 293          $paramType = is_numeric($identifier) ? ParameterType::INTEGER : ParameterType::STRING;
 294  
 295          // Build the query
 296          $query = $db->getQuery(true)
 297              ->select($db->quoteName($element))
 298              ->from($db->quoteName($table))
 299              ->where($db->quoteName($column) . ' = :id')
 300              ->bind(':id', $identifier, $paramType);
 301          $db->setQuery($query);
 302  
 303          // Load the single cell and json_decode data
 304          return json_decode($db->loadResult(), true);
 305      }
 306  
 307      /**
 308       * Remove the files and folders in the given array from
 309       *
 310       * @return  void
 311       *
 312       * @since   3.6
 313       */
 314      public function removeFiles()
 315      {
 316          if (!empty($this->deleteFiles)) {
 317              foreach ($this->deleteFiles as $file) {
 318                  if (file_exists(JPATH_ROOT . $file) && !File::delete(JPATH_ROOT . $file)) {
 319                      echo Text::sprintf('JLIB_INSTALLER_ERROR_FILE_FOLDER', $file) . '<br>';
 320                  }
 321              }
 322          }
 323  
 324          if (!empty($this->deleteFolders)) {
 325              foreach ($this->deleteFolders as $folder) {
 326                  if (Folder::exists(JPATH_ROOT . $folder) && !Folder::delete(JPATH_ROOT . $folder)) {
 327                      echo Text::sprintf('JLIB_INSTALLER_ERROR_FILE_FOLDER', $folder) . '<br>';
 328                  }
 329              }
 330          }
 331      }
 332  
 333      /**
 334       * Moves the CLI scripts into the CLI folder in the CMS
 335       *
 336       * @return  void
 337       *
 338       * @since   3.6
 339       */
 340      public function moveCliFiles()
 341      {
 342          if (!empty($this->cliScriptFiles)) {
 343              foreach ($this->cliScriptFiles as $file) {
 344                  $name = basename($file);
 345  
 346                  if (file_exists(JPATH_ROOT . $file) && !File::move(JPATH_ROOT . $file, JPATH_ROOT . '/cli/' . $name)) {
 347                      echo Text::sprintf('JLIB_INSTALLER_FILE_ERROR_MOVE', $name);
 348                  }
 349              }
 350          }
 351      }
 352  
 353      /**
 354       * Creates the dashboard menu module
 355       *
 356       * @param string $dashboard The name of the dashboard
 357       * @param string $preset    The name of the menu preset
 358       *
 359       * @return  void
 360       *
 361       * @throws \Exception
 362       * @since   4.0.0
 363       */
 364      public function addDashboardMenu(string $dashboard, string $preset)
 365      {
 366          $model  = Factory::getApplication()->bootComponent('com_modules')->getMVCFactory()->createModel('Module', 'Administrator', ['ignore_request' => true]);
 367          $module = array(
 368              'id'         => 0,
 369              'asset_id'   => 0,
 370              'language'   => '*',
 371              'note'       => '',
 372              'published'  => 1,
 373              'assignment' => 0,
 374              'client_id'  => 1,
 375              'showtitle'  => 0,
 376              'content'    => '',
 377              'module'     => 'mod_submenu',
 378              'position'   => 'cpanel-' . $dashboard,
 379          );
 380  
 381          // Try to get a translated module title, otherwise fall back to a fixed string.
 382          $titleKey         = strtoupper('COM_' . $this->extension . '_DASHBOARD_' . $dashboard . '_TITLE');
 383          $title            = Text::_($titleKey);
 384          $module['title']  = ($title === $titleKey) ? ucfirst($dashboard) . ' Dashboard' : $title;
 385  
 386          $module['access'] = (int) Factory::getApplication()->get('access', 1);
 387          $module['params'] = array(
 388              'menutype' => '*',
 389              'preset'   => $preset,
 390              'style'    => 'System-none',
 391          );
 392  
 393          if (!$model->save($module)) {
 394              Factory::getApplication()->enqueueMessage(Text::sprintf('JLIB_INSTALLER_ERROR_COMP_INSTALL_FAILED_TO_CREATE_DASHBOARD', $model->getError()));
 395          }
 396      }
 397  }


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