[ Index ]

PHP Cross Reference of Joomla 1.5.26 DE

title

Body

[close]

/libraries/joomla/installer/adapters/ -> component.php (source)

   1  <?php
   2  /**
   3   * @version        $Id:component.php 6961 2007-03-15 16:06:53Z tcp $
   4   * @package        Joomla.Framework
   5   * @subpackage    Installer
   6   * @copyright    Copyright (C) 2005 - 2010 Open Source Matters. All rights reserved.
   7   * @license        GNU/GPL, see LICENSE.php
   8   * Joomla! is free software. This version may have been modified pursuant
   9   * to the GNU General Public License, and as distributed it includes or
  10   * is derivative of works licensed under the GNU General Public License or
  11   * other free or open source software licenses.
  12   * See COPYRIGHT.php for copyright notices and details.
  13   */
  14  
  15  // Check to ensure this file is within the rest of the framework
  16  defined('JPATH_BASE') or die();
  17  
  18  /**
  19   * Component installer
  20   *
  21   * @package        Joomla.Framework
  22   * @subpackage    Installer
  23   * @since        1.5
  24   */
  25  class JInstallerComponent extends JObject
  26  {
  27      /**
  28       * Constructor
  29       *
  30       * @access    protected
  31       * @param    object    $parent    Parent object [JInstaller instance]
  32       * @return    void
  33       * @since    1.5
  34       */
  35  	function __construct(&$parent)
  36      {
  37          $this->parent =& $parent;
  38      }
  39  
  40      /**
  41       * Custom install method for components
  42       *
  43       * @access    public
  44       * @return    boolean    True on success
  45       * @since    1.5
  46       */
  47  	function install()
  48      {
  49          // Get a database connector object
  50          $db =& $this->parent->getDBO();
  51  
  52          // Get the extension manifest object
  53          $manifest =& $this->parent->getManifest();
  54          $this->manifest =& $manifest->document;
  55  
  56          /**
  57           * ---------------------------------------------------------------------------------------------
  58           * Manifest Document Setup Section
  59           * ---------------------------------------------------------------------------------------------
  60           */
  61  
  62          // Set the extensions name
  63          $name =& $this->manifest->getElementByPath('name');
  64          $name = JFilterInput::clean($name->data(), 'cmd');
  65          $this->set('name', $name);
  66  
  67          // Get the component description
  68          $description = & $this->manifest->getElementByPath('description');
  69          if (is_a($description, 'JSimpleXMLElement')) {
  70              $this->parent->set('message', $description->data());
  71          } else {
  72              $this->parent->set('message', '' );
  73          }
  74  
  75          // Get some important manifest elements
  76          $this->adminElement        =& $this->manifest->getElementByPath('administration');
  77          $this->installElement    =& $this->manifest->getElementByPath('install');
  78          $this->uninstallElement    =& $this->manifest->getElementByPath('uninstall');
  79  
  80          // Set the installation target paths
  81          $this->parent->setPath('extension_site', JPath::clean(JPATH_SITE.DS."components".DS.strtolower("com_".str_replace(" ", "", $this->get('name')))));
  82          $this->parent->setPath('extension_administrator', JPath::clean(JPATH_ADMINISTRATOR.DS."components".DS.strtolower("com_".str_replace(" ", "", $this->get('name')))));
  83  
  84          /**
  85           * ---------------------------------------------------------------------------------------------
  86           * Basic Checks Section
  87           * ---------------------------------------------------------------------------------------------
  88           */
  89  
  90          // Make sure that we have an admin element
  91          if ( ! is_a($this->adminElement, 'JSimpleXMLElement') )
  92          {
  93              JError::raiseWarning(1, JText::_('Component').' '.JText::_('Install').': '.JText::_('The XML file did not contain an administration element'));
  94              return false;
  95          }
  96  
  97          /**
  98           * ---------------------------------------------------------------------------------------------
  99           * Filesystem Processing Section
 100           * ---------------------------------------------------------------------------------------------
 101           */
 102  
 103          /*
 104           * If the component site or admin directory already exists, then we will assume that the component is already
 105           * installed or another component is using that directory.
 106           */
 107          $exists    = false;
 108          if ( file_exists($this->parent->getPath('extension_site')) && !$this->parent->getOverwrite()) {
 109              $exists    = true;
 110              JError::raiseWarning(1, JText::_('Component').' '.JText::_('Install').': '.JText::_('Another component is already using directory').': "'.$this->parent->getPath('extension_site').'"');
 111          }
 112          if ( file_exists($this->parent->getPath('extension_administrator')) && !$this->parent->getOverwrite()) {
 113              $exists    = true;
 114              JError::raiseWarning(1, JText::_('Component').' '.JText::_('Install').': '.JText::_('Another component is already using directory').': "'.$this->parent->getPath('extension_administrator').'"');
 115          }
 116          if ( $exists )
 117          {
 118              return false;
 119          }
 120  
 121          // If the component directory does not exist, lets create it
 122          $created = false;
 123          if (!file_exists($this->parent->getPath('extension_site'))) {
 124              if (!$created = JFolder::create($this->parent->getPath('extension_site'))) {
 125                  JError::raiseWarning(1, JText::_('Component').' '.JText::_('Install').': '.JText::_('Failed to create directory').': "'.$this->parent->getPath('extension_site').'"');
 126                  return false;
 127              }
 128          }
 129  
 130          /*
 131           * Since we created the component directory and will want to remove it if we have to roll back
 132           * the installation, lets add it to the installation step stack
 133           */
 134          if ($created) {
 135              $this->parent->pushStep(array ('type' => 'folder', 'path' => $this->parent->getPath('extension_site')));
 136          }
 137  
 138          // If the component admin directory does not exist, lets create it
 139          $created = false;
 140          if (!file_exists($this->parent->getPath('extension_administrator'))) {
 141              if (!$created = JFolder::create($this->parent->getPath('extension_administrator'))) {
 142                  JError::raiseWarning(1, JText::_('Component').' '.JText::_('Install').': '.JText::_('Failed to create directory').': "'.$this->parent->getPath('extension_administrator').'"');
 143                  // Install failed, rollback any changes
 144                  $this->parent->abort();
 145                  return false;
 146              }
 147          }
 148  
 149          /*
 150           * Since we created the component admin directory and we will want to remove it if we have to roll
 151           * back the installation, lets add it to the installation step stack
 152           */
 153          if ($created) {
 154              $this->parent->pushStep(array ('type' => 'folder', 'path' => $this->parent->getPath('extension_administrator')));
 155          }
 156  
 157          // Find files to copy
 158          foreach ($this->manifest->children() as $child)
 159          {
 160              if (is_a($child, 'JSimpleXMLElement') && $child->name() == 'files') {
 161                  if ($this->parent->parseFiles($child) === false) {
 162                      // Install failed, rollback any changes
 163                      $this->parent->abort();
 164                      return false;
 165                  }
 166              }
 167          }
 168  
 169          foreach ($this->adminElement->children() as $child)
 170          {
 171              if (is_a($child, 'JSimpleXMLElement') && $child->name() == 'files') {
 172                  if ($this->parent->parseFiles($child, 1) === false) {
 173                      // Install failed, rollback any changes
 174                      $this->parent->abort();
 175                      return false;
 176                  }
 177              }
 178          }
 179  
 180          // Parse optional tags
 181          $this->parent->parseMedia($this->manifest->getElementByPath('media'));
 182          $this->parent->parseLanguages($this->manifest->getElementByPath('languages'));
 183          $this->parent->parseLanguages($this->manifest->getElementByPath('administration/languages'), 1);
 184  
 185          // Parse deprecated tags
 186          $this->parent->parseFiles($this->manifest->getElementByPath('images'));
 187          $this->parent->parseFiles($this->manifest->getElementByPath('administration/images'), 1);
 188  
 189          // If there is an install file, lets copy it.
 190          $installScriptElement =& $this->manifest->getElementByPath('installfile');
 191          if (is_a($installScriptElement, 'JSimpleXMLElement')) {
 192              // check if it actually has a value
 193              $installScriptFilename = $installScriptElement->data();
 194              if(empty($installScriptFilename)) {
 195                  if(JDEBUG) JError::raiseWarning(43, JText::sprintf('BLANKSCRIPTELEMENT', JText::_('install')));
 196              } else {
 197                  // Make sure it hasn't already been copied (this would be an error in the xml install file)
 198                  // Only copy over an existing file when upgrading components
 199                  if (!file_exists($this->parent->getPath('extension_administrator').DS.$installScriptFilename) || $this->parent->getOverwrite())
 200                  {
 201                      $path['src']    = $this->parent->getPath('source').DS.$installScriptFilename;
 202                      $path['dest']    = $this->parent->getPath('extension_administrator').DS.$installScriptFilename;
 203                      if(file_exists($path['src']) && file_exists(dirname($path['dest']))) {
 204                          if (!$this->parent->copyFiles(array ($path))) {
 205                              // Install failed, rollback changes
 206                              $this->parent->abort(JText::_('Component').' '.JText::_('Install').': '.JText::_('Could not copy PHP install file.'));
 207                              return false;
 208                          }
 209                      } else if(JDEBUG) {
 210                          JError::raiseWarning(42, JText::sprintf('INVALIDINSTALLFILE', JText::_('install')));
 211                      }
 212                  }
 213                  $this->set('install.script', $installScriptFilename);
 214              }
 215          }
 216  
 217          // If there is an uninstall file, lets copy it.
 218          $uninstallScriptElement =& $this->manifest->getElementByPath('uninstallfile');
 219          if (is_a($uninstallScriptElement, 'JSimpleXMLElement')) {
 220              // check it actually has a value
 221              $uninstallScriptFilename = $uninstallScriptElement->data();
 222              if(empty($uninstallScriptFilename)) {
 223                  // display a warning when we're in debug mode
 224                  if(JDEBUG) JError::raiseWarning(43, JText::sprintf('BLANKSCRIPTELEMENT', JText::_('uninstall')));
 225              } else {
 226                  // Make sure it hasn't already been copied (this would be an error in the xml install file)
 227                  // Only copy over an existing file when upgrading components
 228                  if (!file_exists($this->parent->getPath('extension_administrator').DS.$uninstallScriptFilename) || $this->parent->getOverwrite())
 229                  {
 230                      $path['src']    = $this->parent->getPath('source').DS.$uninstallScriptFilename;
 231                      $path['dest']    = $this->parent->getPath('extension_administrator').DS.$uninstallScriptFilename;
 232                      if(file_exists($path['src']) && file_exists(dirname($path['dest']))) {
 233                          if (!$this->parent->copyFiles(array ($path))) {
 234                              // Install failed, rollback changes
 235                              $this->parent->abort(JText::_('Component').' '.JText::_('Install').': '.JText::_('Could not copy PHP install file.'));
 236                              return false;
 237                          }
 238                      } else if(JDEBUG) {
 239                          JError::raiseWarning(42, JText::sprintf('INVALIDINSTALLFILE', JText::_('uninstall')));
 240                      }
 241                  }
 242              }
 243          }
 244  
 245          /**
 246           * ---------------------------------------------------------------------------------------------
 247           * Database Processing Section
 248           * ---------------------------------------------------------------------------------------------
 249           */
 250  
 251          /*
 252           * Let's run the install queries for the component
 253           *    If backward compatibility is required - run queries in xml file
 254           *    If Joomla 1.5 compatible, with discreet sql files - execute appropriate
 255           *    file for utf-8 support or non-utf-8 support
 256           */
 257          $result = $this->parent->parseQueries($this->manifest->getElementByPath('install/queries'));
 258          if ($result === false) {
 259              // Install failed, rollback changes
 260              $this->parent->abort(JText::_('Component').' '.JText::_('Install').': '.JText::_('SQL Error')." ".$db->stderr(true));
 261              return false;
 262          } elseif ($result === 0) {
 263              // no backward compatibility queries found - try for Joomla 1.5 type queries
 264              // second argument is the utf compatible version attribute
 265              $utfresult = $this->parent->parseSQLFiles($this->manifest->getElementByPath('install/sql'));
 266              if ($utfresult === false) {
 267                  // Install failed, rollback changes
 268                  $this->parent->abort(JText::_('Component').' '.JText::_('Install').': '.JText::_('SQLERRORORFILE')." ".$db->stderr(true));
 269                  return false;
 270              }
 271          }
 272  
 273          // Time to build the admin menus
 274          $this->_buildAdminMenus();
 275  
 276          /**
 277           * ---------------------------------------------------------------------------------------------
 278           * Custom Installation Script Section
 279           * ---------------------------------------------------------------------------------------------
 280           */
 281  
 282          /*
 283           * If we have an install script, lets include it, execute the custom
 284           * install method, and append the return value from the custom install
 285           * method to the installation message.
 286           */
 287          if ($this->get('install.script')) {
 288              if (is_file($this->parent->getPath('extension_administrator').DS.$this->get('install.script'))) {
 289                  ob_start();
 290                  ob_implicit_flush(false);
 291                  require_once ($this->parent->getPath('extension_administrator').DS.$this->get('install.script'));
 292                  if (function_exists('com_install')) {
 293                      if (com_install() === false) {
 294                          $this->parent->abort(JText::_('Component').' '.JText::_('Install').': '.JText::_('Custom install routine failure'));
 295                          return false;
 296                      }
 297                  }
 298                  $msg = ob_get_contents();
 299                  ob_end_clean();
 300                  if ($msg != '') {
 301                      $this->parent->set('extension.message', $msg);
 302                  }
 303              }
 304          }
 305  
 306          /**
 307           * ---------------------------------------------------------------------------------------------
 308           * Finalization and Cleanup Section
 309           * ---------------------------------------------------------------------------------------------
 310           */
 311  
 312          // Lastly, we will copy the manifest file to its appropriate place.
 313          if (!$this->parent->copyManifest()) {
 314              // Install failed, rollback changes
 315              $this->parent->abort(JText::_('Component').' '.JText::_('Install').': '.JText::_('Could not copy setup file'));
 316              return false;
 317          }
 318  
 319          // Load component lang file
 320          $lang =& JFactory::getLanguage();
 321          $lang->load(strtolower("com_".str_replace(" ", "", $this->get('name'))));
 322  
 323          return true;
 324      }
 325  
 326      /**
 327       * Custom uninstall method for components
 328       *
 329       * @access    public
 330       * @param    int        $cid    The id of the component to uninstall
 331       * @param    int        $clientId    The id of the client (unused)
 332       * @return    mixed    Return value for uninstall method in component uninstall file
 333       * @since    1.0
 334       */
 335  	function uninstall($id, $clientId)
 336      {
 337          // Initialize variables
 338          $db =& $this->parent->getDBO();
 339          $row    = null;
 340          $retval    = true;
 341  
 342          // First order of business will be to load the component object table from the database.
 343          // This should give us the necessary information to proceed.
 344          $row = & JTable::getInstance('component');
 345          if ( !$row->load((int) $id) || !trim($row->option) ) {
 346              JError::raiseWarning(100, JText::_('ERRORUNKOWNEXTENSION'));
 347              return false;
 348          }
 349  
 350          // Is the component we are trying to uninstall a core one?
 351          // Because that is not a good idea...
 352          if ($row->iscore) {
 353              JError::raiseWarning(100, JText::_('Component').' '.JText::_('Uninstall').': '.JText::sprintf('WARNCORECOMPONENT', $row->name)."<br />".JText::_('WARNCORECOMPONENT2'));
 354              return false;
 355          }
 356  
 357          // Get the admin and site paths for the component
 358          $this->parent->setPath('extension_administrator', JPath::clean(JPATH_ADMINISTRATOR.DS.'components'.DS.$row->option));
 359          $this->parent->setPath('extension_site', JPath::clean(JPATH_SITE.DS.'components'.DS.$row->option));
 360  
 361          /**
 362           * ---------------------------------------------------------------------------------------------
 363           * Manifest Document Setup Section
 364           * ---------------------------------------------------------------------------------------------
 365           */
 366  
 367          // Find and load the XML install file for the component
 368          $this->parent->setPath('source', $this->parent->getPath('extension_administrator'));
 369  
 370          // Get the package manifest objecct
 371          $manifest =& $this->parent->getManifest();
 372          if (!is_a($manifest, 'JSimpleXML')) {
 373              // Make sure we delete the folders if no manifest exists
 374              JFolder::delete($this->parent->getPath('extension_administrator'));
 375              JFolder::delete($this->parent->getPath('extension_site'));
 376  
 377              // Remove the menu
 378              $this->_removeAdminMenus($row);
 379  
 380              // Raise a warning
 381              JError::raiseWarning(100, JText::_('ERRORREMOVEMANUALLY'));
 382  
 383              // Return
 384              return false;
 385          }
 386  
 387          // Get the root node of the manifest document
 388          $this->manifest =& $manifest->document;
 389  
 390          /**
 391           * ---------------------------------------------------------------------------------------------
 392           * Custom Uninstallation Script Section
 393           * ---------------------------------------------------------------------------------------------
 394           */
 395  
 396          // Now lets load the uninstall file if there is one and execute the uninstall function if it exists.
 397          $uninstallfileElement =& $this->manifest->getElementByPath('uninstallfile');
 398          if (is_a($uninstallfileElement, 'JSimpleXMLElement')) {
 399              // Element exists, does the file exist?
 400              if (is_file($this->parent->getPath('extension_administrator').DS.$uninstallfileElement->data())) {
 401                  ob_start();
 402                  ob_implicit_flush(false);
 403                  require_once ($this->parent->getPath('extension_administrator').DS.$uninstallfileElement->data());
 404                  if (function_exists('com_uninstall')) {
 405                      if (com_uninstall() === false) {
 406                          JError::raiseWarning(100, JText::_('Component').' '.JText::_('Uninstall').': '.JText::_('Custom Uninstall script unsuccessful'));
 407                          $retval = false;
 408                      }
 409                  }
 410                  $msg = ob_get_contents();
 411                  ob_end_clean();
 412                  if ($msg != '') {
 413                      $this->parent->set('extension.message', $msg);
 414                  }
 415              }
 416          }
 417  
 418          /**
 419           * ---------------------------------------------------------------------------------------------
 420           * Database Processing Section
 421           * ---------------------------------------------------------------------------------------------
 422           */
 423  
 424          /*
 425           * Let's run the uninstall queries for the component
 426           *    If backward compatibility is required - run queries in xml file
 427           *    If Joomla 1.5 compatible, with discreet sql files - execute appropriate
 428           *    file for utf-8 support or non-utf support
 429           */
 430          $result = $this->parent->parseQueries($this->manifest->getElementByPath('uninstall/queries'));
 431          if ($result === false) {
 432              // Install failed, rollback changes
 433              JError::raiseWarning(100, JText::_('Component').' '.JText::_('Uninstall').': '.JText::_('SQL Error')." ".$db->stderr(true));
 434              $retval = false;
 435          } elseif ($result === 0) {
 436              // no backward compatibility queries found - try for Joomla 1.5 type queries
 437              // second argument is the utf compatible version attribute
 438              $utfresult = $this->parent->parseSQLFiles($this->manifest->getElementByPath('uninstall/sql'));
 439              if ($utfresult === false) {
 440                  // Install failed, rollback changes
 441                  JError::raiseWarning(100, JText::_('Component').' '.JText::_('Uninstall').': '.JText::_('SQLERRORORFILE')." ".$db->stderr(true));
 442                  $retval = false;
 443              }
 444          }
 445  
 446          $this->_removeAdminMenus($row);
 447  
 448          /**
 449           * ---------------------------------------------------------------------------------------------
 450           * Filesystem Processing Section
 451           * ---------------------------------------------------------------------------------------------
 452           */
 453  
 454          // Let's remove language files and media in the JROOT/images/ folder that are
 455          // associated with the component we are uninstalling
 456          $this->parent->removeFiles($this->manifest->getElementByPath('media'));
 457          $this->parent->removeFiles($this->manifest->getElementByPath('languages'));
 458          $this->parent->removeFiles($this->manifest->getElementByPath('administration/languages'), 1);
 459  
 460          // Now we need to delete the installation directories.  This is the final step in uninstalling the component.
 461          if (trim($row->option)) {
 462              // Delete the component site directory
 463              if (is_dir($this->parent->getPath('extension_site'))) {
 464                  if (!JFolder::delete($this->parent->getPath('extension_site'))) {
 465                      JError::raiseWarning(100, JText::_('Component').' '.JText::_('Uninstall').': '.JText::_('Unable to remove the component site directory'));
 466                      $retval = false;
 467                  }
 468              }
 469  
 470              // Delete the component admin directory
 471              if (is_dir($this->parent->getPath('extension_administrator'))) {
 472                  if (!JFolder::delete($this->parent->getPath('extension_administrator'))) {
 473                      JError::raiseWarning(100, JText::_('Component').' '.JText::_('Uninstall').': '.JText::_('Unable to remove the component admin directory'));
 474                      $retval = false;
 475                  }
 476              }
 477              return $retval;
 478          } else {
 479              // No component option defined... cannot delete what we don't know about
 480              JError::raiseWarning(100, 'Component Uninstall: Option field empty, cannot remove files');
 481              return false;
 482          }
 483      }
 484  
 485      /**
 486       * Method to build menu database entries for a component
 487       *
 488       * @access    private
 489       * @return    boolean    True if successful
 490       * @since    1.5
 491       */
 492  	function _buildAdminMenus()
 493      {
 494          // Get database connector object
 495          $db =& $this->parent->getDBO();
 496  
 497          // Initialize variables
 498          $option = strtolower("com_".str_replace(" ", "", $this->get('name')));
 499  
 500          // If a component exists with this option in the table than we don't need to add menus
 501          // Grab the params for later
 502          $query = 'SELECT id, params, enabled' .
 503                  ' FROM #__components' .
 504                  ' WHERE `option` = '.$db->Quote($option) .
 505                  ' ORDER BY `parent` ASC';
 506  
 507          $db->setQuery($query);
 508          $componentrow = $db->loadAssoc(); // will return null on error
 509          $exists = 0;
 510          $oldparams = '';
 511  
 512          // Check if menu items exist
 513          if ($componentrow) {
 514              // set the value of exists to be the value of the old id
 515              $exists = $componentrow['id'];
 516              // and set the old params
 517              $oldparams = $componentrow['params'];
 518              // and old enabled
 519              $oldenabled = $componentrow['enabled'];
 520  
 521              // Don't do anything if overwrite has not been enabled
 522              if ( ! $this->parent->getOverwrite() ) {
 523                  return true;
 524              }
 525  
 526              // Remove existing menu items if overwrite has been enabled
 527              if ( $option ) {
 528  
 529                  $sql = 'DELETE FROM #__components WHERE `option` = '.$db->Quote($option);
 530  
 531                  $db->setQuery($sql);
 532                  if (!$db->query()) {
 533                      JError::raiseWarning(100, JText::_('Component').' '.JText::_('Install').': '.$db->stderr(true));
 534                  }
 535              }
 536          }
 537  
 538          // Ok, now its time to handle the menus.  Start with the component root menu, then handle submenus.
 539          $menuElement = & $this->adminElement->getElementByPath('menu');
 540          if (is_a($menuElement, 'JSimpleXMLElement')) {
 541  
 542              $db_name = $menuElement->data();
 543              $db_link = "option=".$option;
 544              $db_menuid = 0;
 545              $db_parent = 0;
 546              $db_admin_menu_link = "option=".$option;
 547              $db_admin_menu_alt = $menuElement->data();
 548              $db_option = $option;
 549              $db_ordering = 0;
 550              $db_admin_menu_img = ($menuElement->attributes('img')) ? $menuElement->attributes('img') : 'js/ThemeOffice/component.png';
 551              $db_iscore = 0;
 552              // use the old params if a previous entry exists
 553              $db_params = $exists ? $oldparams : $this->parent->getParams();
 554              // use the old enabled field if a previous entry exists
 555              $db_enabled = $exists ? $oldenabled : 1;
 556  
 557              // This works because exists will be zero (autoincr)
 558              // or the old component id
 559              $query = 'INSERT INTO #__components' .
 560                  ' VALUES( '.$exists .', '.$db->Quote($db_name).', '.$db->Quote($db_link).', '.(int) $db_menuid.',' .
 561                  ' '.(int) $db_parent.', '.$db->Quote($db_admin_menu_link).', '.$db->Quote($db_admin_menu_alt).',' .
 562                  ' '.$db->Quote($db_option).', '.(int) $db_ordering.', '.$db->Quote($db_admin_menu_img).',' .
 563                  ' '.(int) $db_iscore.', '.$db->Quote($db_params).', '.(int) $db_enabled.' )';
 564              $db->setQuery($query);
 565              if (!$db->query()) {
 566                  // Install failed, rollback changes
 567                  $this->parent->abort(JText::_('Component').' '.JText::_('Install').': '.$db->stderr(true));
 568                  return false;
 569              }
 570              // save ourselves a call if we don't need it
 571              $menuid = $exists ? $exists : $db->insertid(); // if there was an existing value, reuse
 572  
 573              /*
 574               * Since we have created a menu item, we add it to the installation step stack
 575               * so that if we have to rollback the changes we can undo it.
 576               */
 577              $this->parent->pushStep(array ('type' => 'menu', 'id' => $menuid));
 578          } else {
 579  
 580              /*
 581               * No menu element was specified so lets first see if we have an admin menu entry for this component
 582               * if we do.. then we obviously don't want to create one -- we'll just attach sub menus to that one.
 583               */
 584              $query = 'SELECT id' .
 585                      ' FROM #__components' .
 586                      ' WHERE `option` = '.$db->Quote($option) .
 587                      ' AND parent = 0';
 588              $db->setQuery($query);
 589              $menuid = $db->loadResult();
 590  
 591              if (!$menuid) {
 592                  // No menu entry, lets just enter a component entry to the table.
 593                  $db_name = $this->get('name');
 594                  $db_link = "";
 595                  $db_menuid = 0;
 596                  $db_parent = 0;
 597                  $db_admin_menu_link = "";
 598                  $db_admin_menu_alt = $this->get('name');
 599                  $db_option = $option;
 600                  $db_ordering = 0;
 601                  $db_admin_menu_img = "";
 602                  $db_iscore = 0;
 603                  $db_params = $this->parent->getParams();
 604                  $db_enabled = 1;
 605  
 606                  $query = 'INSERT INTO #__components' .
 607                      ' VALUES( "", '.$db->Quote($db_name).', '.$db->Quote($db_link).', '.(int) $db_menuid.',' .
 608                      ' '.(int) $db_parent.', '.$db->Quote($db_admin_menu_link).', '.$db->Quote($db_admin_menu_alt).',' .
 609                      ' '.$db->Quote($db_option).', '.(int) $db_ordering.', '.$db->Quote($db_admin_menu_img).',' .
 610                      ' '.(int) $db_iscore.', '.$db->Quote($db_params).', '.(int) $db_enabled.' )';
 611                  $db->setQuery($query);
 612                  if (!$db->query()) {
 613                      // Install failed, rollback changes
 614                      $this->parent->abort(JText::_('Component').' '.JText::_('Install').': '.$db->stderr(true));
 615                      return false;
 616                  }
 617                  $menuid = $db->insertid();
 618  
 619                  /*
 620                   * Since we have created a menu item, we add it to the installation step stack
 621                   * so that if we have to rollback the changes we can undo it.
 622                   */
 623                  $this->parent->pushStep(array ('type' => 'menu', 'id' => $menuid));
 624              }
 625          }
 626  
 627          /*
 628           * Process SubMenus
 629           */
 630  
 631          // Initialize submenu ordering value
 632          $ordering = 0;
 633          $submenu = $this->adminElement->getElementByPath('submenu');
 634          if (!is_a($submenu, 'JSimpleXMLElement') || !count($submenu->children())) {
 635              return true;
 636          }
 637          foreach ($submenu->children() as $child)
 638          {
 639              if (is_a($child, 'JSimpleXMLElement') && $child->name() == 'menu') {
 640  
 641                  $com =& JTable::getInstance('component');
 642                  $com->name = $child->data();
 643                  $com->link = '';
 644                  $com->menuid = 0;
 645                  $com->parent = $menuid;
 646                  $com->iscore = 0;
 647                  $com->admin_menu_alt = $child->data();
 648                  $com->option = $option;
 649                  $com->ordering = $ordering ++;
 650  
 651                  // Set the sub menu link
 652                  if ($child->attributes("link")) {
 653                      $com->admin_menu_link = str_replace('&amp;', '&', $child->attributes("link"));
 654                  } else {
 655                      $request = array();
 656                      if ($child->attributes('act')) {
 657                          $request[] = 'act='.$child->attributes('act');
 658                      }
 659                      if ($child->attributes('task')) {
 660                          $request[] = 'task='.$child->attributes('task');
 661                      }
 662                      if ($child->attributes('controller')) {
 663                          $request[] = 'controller='.$child->attributes('controller');
 664                      }
 665                      if ($child->attributes('view')) {
 666                          $request[] = 'view='.$child->attributes('view');
 667                      }
 668                      if ($child->attributes('layout')) {
 669                          $request[] = 'layout='.$child->attributes('layout');
 670                      }
 671                      if ($child->attributes('sub')) {
 672                          $request[] = 'sub='.$child->attributes('sub');
 673                      }
 674                      $qstring = (count($request)) ? '&'.implode('&',$request) : '';
 675                      $com->admin_menu_link = "option=".$option.$qstring;
 676                  }
 677  
 678                  // Set the sub menu image
 679                  if ($child->attributes("img")) {
 680                      $com->admin_menu_img = $child->attributes("img");
 681                  } else {
 682                      $com->admin_menu_img = "js/ThemeOffice/component.png";
 683                  }
 684  
 685                  // Store the submenu
 686                  if (!$com->store()) {
 687                      // Install failed, rollback changes
 688                      $this->parent->abort(JText::_('Component').' '.JText::_('Install').': '.JText::_('SQL Error')." ".$db->stderr(true));
 689                      return false;
 690                  }
 691  
 692                  /*
 693                   * Since we have created a menu item, we add it to the installation step stack
 694                   * so that if we have to rollback the changes we can undo it.
 695                   */
 696                  $this->parent->pushStep(array ('type' => 'menu', 'id' => $com->id));
 697              }
 698          }
 699      }
 700  
 701      /**
 702       * Method to remove admin menu references to a component
 703       *
 704       * @access    private
 705       * @param    object    $component    Component table object
 706       * @return    boolean    True if successful
 707       * @since    1.5
 708       */
 709  	function _removeAdminMenus(&$row)
 710      {
 711          // Get database connector object
 712          $db =& $this->parent->getDBO();
 713          $retval = true;
 714  
 715          // Delete the submenu items
 716          $sql = 'DELETE ' .
 717                  ' FROM #__components ' .
 718                  'WHERE parent = '.(int)$row->id;
 719  
 720          $db->setQuery($sql);
 721          if (!$db->query()) {
 722              JError::raiseWarning(100, JText::_('Component').' '.JText::_('Uninstall').': '.$db->stderr(true));
 723              $retval = false;
 724          }
 725  
 726          // Next, we will delete the component object
 727          if (!$row->delete($row->id)) {
 728              JError::raiseWarning(100, JText::_('Component').' '.JText::_('Uninstall').': '.JText::_('Unable to delete the component from the database'));
 729              $retval = false;
 730          }
 731          return $retval;
 732      }
 733  
 734      /**
 735       * Custom rollback method
 736       *     - Roll back the component menu item
 737       *
 738       * @access    public
 739       * @param    array    $arg    Installation step to rollback
 740       * @return    boolean    True on success
 741       * @since    1.5
 742       */
 743  	function _rollback_menu($arg)
 744      {
 745          // Get database connector object
 746          $db =& $this->parent->getDBO();
 747  
 748          // Remove the entry from the #__components table
 749          $query = 'DELETE ' .
 750                  ' FROM `#__components` ' .
 751                  ' WHERE id='.(int)$arg['id'];
 752          $db->setQuery($query);
 753          return ($db->query() !== false);
 754      }
 755  }


Generated: Wed Mar 28 15:54:07 2012 Cross-referenced by PHPXref 0.7.1