| [ Index ] |
PHP Cross Reference of Joomla 1.5.26 DE |
[Summary view] [Print] [Text view]
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('&', '&', $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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Wed Mar 28 15:54:07 2012 | Cross-referenced by PHPXref 0.7.1 |