| [ Index ] |
PHP Cross Reference of Joomla 1.5.26 DE |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * @version $Id:module.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 * Module installer 20 * 21 * @package Joomla.Framework 22 * @subpackage Installer 23 * @since 1.5 24 */ 25 class JInstallerModule 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 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(), 'string'); 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 /** 76 * --------------------------------------------------------------------------------------------- 77 * Target Application Section 78 * --------------------------------------------------------------------------------------------- 79 */ 80 81 // Get the target application 82 if ($cname = $this->manifest->attributes('client')) { 83 // Attempt to map the client to a base path 84 jimport('joomla.application.helper'); 85 $client =& JApplicationHelper::getClientInfo($cname, true); 86 if ($client === false) { 87 $this->parent->abort(JText::_('Module').' '.JText::_('Install').': '.JText::_('Unknown client type').' ['.$client->name.']'); 88 return false; 89 } 90 $basePath = $client->path; 91 $clientId = $client->id; 92 } else { 93 // No client attribute was found so we assume the site as the client 94 $cname = 'site'; 95 $basePath = JPATH_SITE; 96 $clientId = 0; 97 } 98 99 // Set the installation path 100 $element =& $this->manifest->getElementByPath('files'); 101 if (is_a($element, 'JSimpleXMLElement') && count($element->children())) { 102 $files = $element->children(); 103 foreach ($files as $file) { 104 if ($file->attributes('module')) { 105 $mname = $file->attributes('module'); 106 break; 107 } 108 } 109 } 110 if (!empty ($mname)) { 111 $this->parent->setPath('extension_root', $basePath.DS.'modules'.DS.$mname); 112 } else { 113 $this->parent->abort(JText::_('Module').' '.JText::_('Install').': '.JText::_('No module file specified')); 114 return false; 115 } 116 117 /** 118 * --------------------------------------------------------------------------------------------- 119 * Filesystem Processing Section 120 * --------------------------------------------------------------------------------------------- 121 */ 122 123 /* 124 * If the module directory already exists, then we will assume that the 125 * module is already installed or another module is using that 126 * directory. 127 */ 128 if (file_exists($this->parent->getPath('extension_root'))&&!$this->parent->getOverwrite()) { 129 $this->parent->abort(JText::_('Module').' '.JText::_('Install').': '.JText::_('Another module is already using directory').': "'.$this->parent->getPath('extension_root').'"'); 130 return false; 131 } 132 133 // If the module directory does not exist, lets create it 134 $created = false; 135 if (!file_exists($this->parent->getPath('extension_root'))) { 136 if (!$created = JFolder::create($this->parent->getPath('extension_root'))) { 137 $this->parent->abort(JText::_('Module').' '.JText::_('Install').': '.JText::_('Failed to create directory').': "'.$this->parent->getPath('extension_root').'"'); 138 return false; 139 } 140 } 141 142 /* 143 * Since we created the module directory and will want to remove it if 144 * we have to roll back the installation, lets add it to the 145 * installation step stack 146 */ 147 if ($created) { 148 $this->parent->pushStep(array ('type' => 'folder', 'path' => $this->parent->getPath('extension_root'))); 149 } 150 151 // Copy all necessary files 152 if ($this->parent->parseFiles($element, -1) === false) { 153 // Install failed, roll back changes 154 $this->parent->abort(); 155 return false; 156 } 157 158 // Parse optional tags 159 $this->parent->parseMedia($this->manifest->getElementByPath('media'), $clientId); 160 $this->parent->parseLanguages($this->manifest->getElementByPath('languages'), $clientId); 161 162 // Parse deprecated tags 163 $this->parent->parseFiles($this->manifest->getElementByPath('images'), -1); 164 165 /** 166 * --------------------------------------------------------------------------------------------- 167 * Database Processing Section 168 * --------------------------------------------------------------------------------------------- 169 */ 170 171 // Check to see if a module by the same name is already installed 172 $query = 'SELECT `id`' . 173 ' FROM `#__modules` ' . 174 ' WHERE module = '.$db->Quote($mname) . 175 ' AND client_id = '.(int)$clientId; 176 $db->setQuery($query); 177 if (!$db->Query()) { 178 // Install failed, roll back changes 179 $this->parent->abort(JText::_('Module').' '.JText::_('Install').': '.$db->stderr(true)); 180 return false; 181 } 182 $id = $db->loadResult(); 183 184 // load module instance 185 $row =& JTable::getInstance('module'); 186 187 // Was there a module already installed with the same name? 188 // If there was then we wouldn't be here because it would have 189 // been stopped by the above. Otherwise the files weren't there 190 // (e.g. migration) or its an upgrade (files overwritten) 191 // So all we need to do is create an entry when we can't find one 192 193 if ($id) { 194 $row->load($id); 195 } else { 196 $row->title = JText::_($this->get('name')); 197 $row->ordering = $row->getNextOrder( "position='left'" ); 198 $row->position = 'left'; 199 $row->showtitle = 1; 200 $row->iscore = 0; 201 $row->access = $clientId == 1 ? 2 : 0; 202 $row->client_id = $clientId; 203 $row->module = $mname; 204 $row->params = $this->parent->getParams(); 205 206 if (!$row->store()) { 207 // Install failed, roll back changes 208 $this->parent->abort(JText::_('Module').' '.JText::_('Install').': '.$db->stderr(true)); 209 return false; 210 } 211 212 // Since we have created a module item, we add it to the installation step stack 213 // so that if we have to rollback the changes we can undo it. 214 $this->parent->pushStep(array ('type' => 'module', 'id' => $row->id)); 215 216 // Clean up possible garbage first 217 $query = 'DELETE FROM #__modules_menu WHERE moduleid = '.(int) $row->id; 218 $db->setQuery( $query ); 219 if (!$db->query()) { 220 // Install failed, roll back changes 221 $this->parent->abort(JText::_('Module').' '.JText::_('Install').': '.$db->stderr(true)); 222 return false; 223 } 224 225 // Time to create a menu entry for the module 226 $query = 'INSERT INTO `#__modules_menu` ' . 227 ' VALUES ('.(int) $row->id.', 0 )'; 228 $db->setQuery($query); 229 if (!$db->query()) { 230 // Install failed, roll back changes 231 $this->parent->abort(JText::_('Module').' '.JText::_('Install').': '.$db->stderr(true)); 232 return false; 233 } 234 235 /* 236 * Since we have created a menu item, we add it to the installation step stack 237 * so that if we have to rollback the changes we can undo it. 238 */ 239 $this->parent->pushStep(array ('type' => 'menu', 'id' => $db->insertid())); 240 } 241 242 /** 243 * --------------------------------------------------------------------------------------------- 244 * Finalization and Cleanup Section 245 * --------------------------------------------------------------------------------------------- 246 */ 247 248 // Lastly, we will copy the manifest file to its appropriate place. 249 if (!$this->parent->copyManifest(-1)) { 250 // Install failed, rollback changes 251 $this->parent->abort(JText::_('Module').' '.JText::_('Install').': '.JText::_('Could not copy setup file')); 252 return false; 253 } 254 255 // Load module language file 256 $lang =& JFactory::getLanguage(); 257 $lang->load($row->module, JPATH_BASE.DS.'..'); 258 259 return true; 260 } 261 262 /** 263 * Custom uninstall method 264 * 265 * @access public 266 * @param int $id The id of the module to uninstall 267 * @param int $clientId The id of the client (unused) 268 * @return boolean True on success 269 * @since 1.5 270 */ 271 function uninstall( $id, $clientId ) 272 { 273 // Initialize variables 274 $row = null; 275 $retval = true; 276 $db =& $this->parent->getDBO(); 277 278 // First order of business will be to load the module object table from the database. 279 // This should give us the necessary information to proceed. 280 $row = & JTable::getInstance('module'); 281 if ( !$row->load((int) $id) ) { 282 JError::raiseWarning(100, JText::_('ERRORUNKOWNEXTENSION')); 283 return false; 284 } 285 286 // Is the module we are trying to uninstall a core one? 287 // Because that is not a good idea... 288 if ($row->iscore) { 289 JError::raiseWarning(100, JText::_('Module').' '.JText::_('Uninstall').': '.JText::sprintf('WARNCOREMODULE', $row->name)."<br />".JText::_('WARNCOREMODULE2')); 290 return false; 291 } 292 293 // Get the extension root path 294 jimport('joomla.application.helper'); 295 $client =& JApplicationHelper::getClientInfo($row->client_id); 296 if ($client === false) { 297 $this->parent->abort(JText::_('Module').' '.JText::_('Uninstall').': '.JText::_('Unknown client type').' ['.$row->client_id.']'); 298 return false; 299 } 300 $this->parent->setPath('extension_root', $client->path.DS.'modules'.DS.$row->module); 301 302 // Get the package manifest objecct 303 $this->parent->setPath('source', $this->parent->getPath('extension_root')); 304 $manifest =& $this->parent->getManifest(); 305 if (!is_a($manifest, 'JSimpleXML')) { 306 // Make sure we delete the folders 307 JFolder::delete($this->parent->getPath('extension_root')); 308 JError::raiseWarning(100, 'Module Uninstall: Package manifest file invalid or not found'); 309 return false; 310 } 311 312 // Remove other files 313 $root =& $manifest->document; 314 $this->parent->removeFiles($root->getElementByPath('media')); 315 $this->parent->removeFiles($root->getElementByPath('languages'), $clientId); 316 $this->parent->removeFiles($root->getElementByPath('administration/languages'), 1); 317 318 // Lets delete all the module copies for the type we are uninstalling 319 $query = 'SELECT `id`' . 320 ' FROM `#__modules`' . 321 ' WHERE module = '.$db->Quote($row->module) . 322 ' AND client_id = '.(int)$row->client_id; 323 $db->setQuery($query); 324 $modules = $db->loadResultArray(); 325 326 // Do we have any module copies? 327 if (count($modules)) { 328 JArrayHelper::toInteger($modules); 329 $modID = implode(',', $modules); 330 $query = 'DELETE' . 331 ' FROM #__modules_menu' . 332 ' WHERE moduleid IN ('.$modID.')'; 333 $db->setQuery($query); 334 if (!$db->query()) { 335 JError::raiseWarning(100, JText::_('Module').' '.JText::_('Uninstall').': '.$db->stderr(true)); 336 $retval = false; 337 } 338 } 339 340 // Now we will no longer need the module object, so lets delete it and free up memory 341 $row->delete($row->id); 342 $query = 'DELETE FROM `#__modules` WHERE module = '.$db->Quote($row->module) . ' AND client_id = ' . $row->client_id; 343 $db->setQuery($query); 344 $db->Query(); // clean up any other ones that might exist as well 345 unset ($row); 346 347 // Remove the installation folder 348 if (!JFolder::delete($this->parent->getPath('extension_root'))) { 349 // JFolder should raise an error 350 $retval = false; 351 } 352 return $retval; 353 } 354 355 /** 356 * Custom rollback method 357 * - Roll back the menu item 358 * 359 * @access public 360 * @param array $arg Installation step to rollback 361 * @return boolean True on success 362 * @since 1.5 363 */ 364 function _rollback_menu($arg) 365 { 366 // Get database connector object 367 $db =& $this->parent->getDBO(); 368 369 // Remove the entry from the #__modules_menu table 370 $query = 'DELETE' . 371 ' FROM `#__modules_menu`' . 372 ' WHERE moduleid='.(int)$arg['id']; 373 $db->setQuery($query); 374 return ($db->query() !== false); 375 } 376 377 /** 378 * Custom rollback method 379 * - Roll back the module item 380 * 381 * @access public 382 * @param array $arg Installation step to rollback 383 * @return boolean True on success 384 * @since 1.5 385 */ 386 function _rollback_module($arg) 387 { 388 // Get database connector object 389 $db =& $this->parent->getDBO(); 390 391 // Remove the entry from the #__modules table 392 $query = 'DELETE' . 393 ' FROM `#__modules`' . 394 ' WHERE id='.(int)$arg['id']; 395 $db->setQuery($query); 396 return ($db->query() !== false); 397 } 398 }
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 |