| [ Index ] |
PHP Cross Reference of Joomla 2.5.4 DE |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * @package Joomla.Platform 4 * @subpackage Installer 5 * 6 * @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved. 7 * @license GNU General Public License version 2 or later; see LICENSE 8 */ 9 10 defined('JPATH_PLATFORM') or die; 11 12 jimport('joomla.base.adapterinstance'); 13 14 /** 15 * Language installer 16 * 17 * @package Joomla.Platform 18 * @subpackage Installer 19 * @since 11.1 20 */ 21 class JInstallerLanguage extends JAdapterInstance 22 { 23 /** 24 * Core language pack flag 25 * 26 * @var boolean 27 * @since 11.1 28 */ 29 protected $_core = false; 30 31 /** 32 * Custom install method 33 * 34 * Note: This behaves badly due to hacks made in the middle of 1.5.x to add 35 * the ability to install multiple distinct packs in one install. The 36 * preferred method is to use a package to install multiple language packs. 37 * 38 * @return boolean True on success 39 * 40 * @since 11.1 41 */ 42 public function install() 43 { 44 $source = $this->parent->getPath('source'); 45 if (!$source) 46 { 47 $this->parent 48 ->setPath( 49 'source', 50 ($this->parent->extension->client_id ? JPATH_ADMINISTRATOR : JPATH_SITE) . '/language/' . $this->parent->extension->element 51 ); 52 } 53 $this->manifest = $this->parent->getManifest(); 54 $root = $this->manifest->document; 55 56 // Get the client application target 57 if ((string) $this->manifest->attributes()->client == 'both') 58 { 59 JError::raiseWarning(42, JText::_('JLIB_INSTALLER_ERROR_DEPRECATED_FORMAT')); 60 $element = $this->manifest->site->files; 61 if (!$this->_install('site', JPATH_SITE, 0, $element)) 62 { 63 return false; 64 } 65 66 $element = $this->manifest->administration->files; 67 if (!$this->_install('administrator', JPATH_ADMINISTRATOR, 1, $element)) 68 { 69 return false; 70 } 71 // This causes an issue because we have two eid's, *sigh* nasty hacks! 72 return true; 73 } 74 elseif ($cname = (string) $this->manifest->attributes()->client) 75 { 76 // Attempt to map the client to a base path 77 $client = JApplicationHelper::getClientInfo($cname, true); 78 if ($client === null) 79 { 80 $this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT', JText::sprintf('JLIB_INSTALLER_ERROR_UNKNOWN_CLIENT_TYPE', $cname))); 81 return false; 82 } 83 $basePath = $client->path; 84 $clientId = $client->id; 85 $element = $this->manifest->files; 86 87 return $this->_install($cname, $basePath, $clientId, $element); 88 } 89 else 90 { 91 // No client attribute was found so we assume the site as the client 92 $cname = 'site'; 93 $basePath = JPATH_SITE; 94 $clientId = 0; 95 $element = $this->manifest->files; 96 97 return $this->_install($cname, $basePath, $clientId, $element); 98 } 99 } 100 101 /** 102 * Install function that is designed to handle individual clients 103 * 104 * @param string $cname Cname @todo: not used 105 * @param string $basePath The base name. 106 * @param integer $clientId The client id. 107 * @param object &$element The XML element. 108 * 109 * @return boolean 110 * 111 * @since 11.1 112 */ 113 protected function _install($cname, $basePath, $clientId, &$element) 114 { 115 $this->manifest = $this->parent->getManifest(); 116 117 // Get the language name 118 // Set the extensions name 119 $name = JFilterInput::getInstance()->clean((string) $this->manifest->name, 'cmd'); 120 $this->set('name', $name); 121 122 // Get the Language tag [ISO tag, eg. en-GB] 123 $tag = (string) $this->manifest->tag; 124 125 // Check if we found the tag - if we didn't, we may be trying to install from an older language package 126 if (!$tag) 127 { 128 $this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT', JText::_('JLIB_INSTALLER_ERROR_NO_LANGUAGE_TAG'))); 129 return false; 130 } 131 132 $this->set('tag', $tag); 133 134 // Set the language installation path 135 $this->parent->setPath('extension_site', $basePath . '/language/' . $tag); 136 137 // Do we have a meta file in the file list? In other words... is this a core language pack? 138 if ($element && count($element->children())) 139 { 140 $files = $element->children(); 141 foreach ($files as $file) 142 { 143 if ((string) $file->attributes()->file == 'meta') 144 { 145 $this->_core = true; 146 break; 147 } 148 } 149 } 150 151 // Either we are installing a core pack or a core pack must exist for the language we are installing. 152 if (!$this->_core) 153 { 154 if (!JFile::exists($this->parent->getPath('extension_site') . '/' . $this->get('tag') . '.xml')) 155 { 156 $this->parent 157 ->abort(JText::sprintf('JLIB_INSTALLER_ABORT', JText::sprintf('JLIB_INSTALLER_ERROR_NO_CORE_LANGUAGE', $this->get('tag')))); 158 return false; 159 } 160 } 161 162 // If the language directory does not exist, let's create it 163 $created = false; 164 if (!file_exists($this->parent->getPath('extension_site'))) 165 { 166 if (!$created = JFolder::create($this->parent->getPath('extension_site'))) 167 { 168 $this->parent 169 ->abort( 170 JText::sprintf( 171 'JLIB_INSTALLER_ABORT', 172 JText::sprintf('JLIB_INSTALLER_ERROR_CREATE_FOLDER_FAILED', $this->parent->getPath('extension_site')) 173 ) 174 ); 175 return false; 176 } 177 } 178 else 179 { 180 // Look for an update function or update tag 181 $updateElement = $this->manifest->update; 182 // Upgrade manually set or 183 // Update function available or 184 // Update tag detected 185 if ($this->parent->getUpgrade() || ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'update')) 186 || $updateElement) 187 { 188 return $this->update(); // transfer control to the update function 189 } 190 elseif (!$this->parent->getOverwrite()) 191 { 192 // Overwrite is set 193 // We didn't have overwrite set, find an update function or find an update tag so lets call it safe 194 if (file_exists($this->parent->getPath('extension_site'))) 195 { 196 // If the site exists say so. 197 JError::raiseWarning( 198 1, 199 JText::sprintf( 200 'JLIB_INSTALLER_ABORT', 201 JText::sprintf('JLIB_INSTALLER_ERROR_FOLDER_IN_USE', $this->parent->getPath('extension_site')) 202 ) 203 ); 204 } 205 else 206 { 207 // If the admin exists say so. 208 JError::raiseWarning( 209 1, 210 JText::sprintf( 211 'JLIB_INSTALLER_ABORT', 212 JText::sprintf('JLIB_INSTALLER_ERROR_FOLDER_IN_USE', $this->parent->getPath('extension_administrator')) 213 ) 214 ); 215 } 216 return false; 217 } 218 } 219 220 /* 221 * If we created the language directory we will want to remove it if we 222 * have to roll back the installation, so let's add it to the installation 223 * step stack 224 */ 225 if ($created) 226 { 227 $this->parent->pushStep(array('type' => 'folder', 'path' => $this->parent->getPath('extension_site'))); 228 } 229 230 // Copy all the necessary files 231 if ($this->parent->parseFiles($element) === false) 232 { 233 // Install failed, rollback changes 234 $this->parent->abort(); 235 return false; 236 } 237 238 // Parse optional tags 239 $this->parent->parseMedia($this->manifest->media); 240 241 // Copy all the necessary font files to the common pdf_fonts directory 242 $this->parent->setPath('extension_site', $basePath . '/language/pdf_fonts'); 243 $overwrite = $this->parent->setOverwrite(true); 244 if ($this->parent->parseFiles($this->manifest->fonts) === false) 245 { 246 // Install failed, rollback changes 247 $this->parent->abort(); 248 return false; 249 } 250 $this->parent->setOverwrite($overwrite); 251 252 // Get the language description 253 $description = (string) $this->manifest->description; 254 if ($description) 255 { 256 $this->parent->set('message', JText::_($description)); 257 } 258 else 259 { 260 $this->parent->set('message', ''); 261 } 262 263 // Add an entry to the extension table with a whole heap of defaults 264 $row = JTable::getInstance('extension'); 265 $row->set('name', $this->get('name')); 266 $row->set('type', 'language'); 267 $row->set('element', $this->get('tag')); 268 // There is no folder for languages 269 $row->set('folder', ''); 270 $row->set('enabled', 1); 271 $row->set('protected', 0); 272 $row->set('access', 0); 273 $row->set('client_id', $clientId); 274 $row->set('params', $this->parent->getParams()); 275 $row->set('manifest_cache', $this->parent->generateManifestCache()); 276 277 if (!$row->store()) 278 { 279 // Install failed, roll back changes 280 $this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT', $row->getError())); 281 return false; 282 } 283 284 // Clobber any possible pending updates 285 $update = JTable::getInstance('update'); 286 $uid = $update->find(array('element' => $this->get('tag'), 'type' => 'language', 'client_id' => '', 'folder' => '')); 287 if ($uid) 288 { 289 $update->delete($uid); 290 } 291 292 return $row->get('extension_id'); 293 } 294 295 /** 296 * Custom update method 297 * 298 * @return boolean True on success, false on failure 299 * 300 * @since 11.1 301 */ 302 public function update() 303 { 304 $xml = $this->parent->getManifest(); 305 306 $this->manifest = $xml; 307 308 $cname = $xml->attributes()->client; 309 310 // Attempt to map the client to a base path 311 $client = JApplicationHelper::getClientInfo($cname, true); 312 if ($client === null || (empty($cname) && $cname !== 0)) 313 { 314 $this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT', JText::sprintf('JLIB_INSTALLER_ERROR_UNKNOWN_CLIENT_TYPE', $cname))); 315 return false; 316 } 317 $basePath = $client->path; 318 $clientId = $client->id; 319 320 // Get the language name 321 // Set the extensions name 322 $name = (string) $this->manifest->name; 323 $name = JFilterInput::getInstance()->clean($name, 'cmd'); 324 $this->set('name', $name); 325 326 // Get the Language tag [ISO tag, eg. en-GB] 327 $tag = (string) $xml->tag; 328 329 // Check if we found the tag - if we didn't, we may be trying to install from an older language package 330 if (!$tag) 331 { 332 $this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT', JText::_('JLIB_INSTALLER_ERROR_NO_LANGUAGE_TAG'))); 333 return false; 334 } 335 336 $this->set('tag', $tag); 337 $folder = $tag; 338 339 // Set the language installation path 340 $this->parent->setPath('extension_site', $basePath . '/language/' . $this->get('tag')); 341 342 // Do we have a meta file in the file list? In other words... is this a core language pack? 343 if (count($xml->files->children())) 344 { 345 foreach ($xml->files->children() as $file) 346 { 347 if ((string) $file->attributes()->file == 'meta') 348 { 349 $this->_core = true; 350 break; 351 } 352 } 353 } 354 355 // Either we are installing a core pack or a core pack must exist for the language we are installing. 356 if (!$this->_core) 357 { 358 if (!JFile::exists($this->parent->getPath('extension_site') . '/' . $this->get('tag') . '.xml')) 359 { 360 $this->parent 361 ->abort(JText::sprintf('JLIB_INSTALLER_ABORT', JText::sprintf('JLIB_INSTALLER_ERROR_NO_CORE_LANGUAGE', $this->get('tag')))); 362 return false; 363 } 364 } 365 366 // Copy all the necessary files 367 if ($this->parent->parseFiles($xml->files) === false) 368 { 369 // Install failed, rollback changes 370 $this->parent->abort(); 371 return false; 372 } 373 374 // Parse optional tags 375 $this->parent->parseMedia($xml->media); 376 377 // Copy all the necessary font files to the common pdf_fonts directory 378 $this->parent->setPath('extension_site', $basePath . '/language/pdf_fonts'); 379 $overwrite = $this->parent->setOverwrite(true); 380 if ($this->parent->parseFiles($xml->fonts) === false) 381 { 382 // Install failed, rollback changes 383 $this->parent->abort(); 384 return false; 385 } 386 $this->parent->setOverwrite($overwrite); 387 388 // Get the language description and set it as message 389 $this->parent->set('message', (string) $xml->description); 390 391 // Finalization and Cleanup Section 392 393 // Clobber any possible pending updates 394 $update = JTable::getInstance('update'); 395 $uid = $update->find(array('element' => $this->get('tag'), 'type' => 'language', 'client_id' => $clientId)); 396 if ($uid) 397 { 398 $update->delete($uid); 399 } 400 401 // Update an entry to the extension table 402 $row = JTable::getInstance('extension'); 403 $eid = $row->find(array('element' => strtolower($this->get('tag')), 'type' => 'language', 'client_id' => $clientId)); 404 if ($eid) 405 { 406 $row->load($eid); 407 } 408 else 409 { 410 // set the defaults 411 $row->set('folder', ''); // There is no folder for language 412 $row->set('enabled', 1); 413 $row->set('protected', 0); 414 $row->set('access', 0); 415 $row->set('client_id', $clientId); 416 $row->set('params', $this->parent->getParams()); 417 } 418 $row->set('name', $this->get('name')); 419 $row->set('type', 'language'); 420 $row->set('element', $this->get('tag')); 421 $row->set('manifest_cache', $this->parent->generateManifestCache()); 422 423 if (!$row->store()) 424 { 425 // Install failed, roll back changes 426 $this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT', $row->getError())); 427 return false; 428 } 429 430 // And now we run the postflight 431 ob_start(); 432 ob_implicit_flush(false); 433 if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'postflight')) 434 { 435 $this->parent->manifestClass->postflight('update', $this); 436 } 437 $msg .= ob_get_contents(); // append messages 438 ob_end_clean(); 439 if ($msg != '') 440 { 441 $this->parent->set('extension_message', $msg); 442 } 443 444 return $row->get('extension_id'); 445 } 446 447 /** 448 * Custom uninstall method 449 * 450 * @param string $eid The tag of the language to uninstall 451 * 452 * @return mixed Return value for uninstall method in component uninstall file 453 * 454 * @since 11.1 455 */ 456 public function uninstall($eid) 457 { 458 // Load up the extension details 459 $extension = JTable::getInstance('extension'); 460 $extension->load($eid); 461 // Grab a copy of the client details 462 $client = JApplicationHelper::getClientInfo($extension->get('client_id')); 463 464 // Check the element isn't blank to prevent nuking the languages directory...just in case 465 $element = $extension->get('element'); 466 if (empty($element)) 467 { 468 JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_LANG_UNINSTALL_ELEMENT_EMPTY')); 469 return false; 470 } 471 472 // Check that the language is not protected, Normally en-GB. 473 $protected = $extension->get('protected'); 474 if ($protected == 1) 475 { 476 JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_LANG_UNINSTALL_PROTECTED')); 477 return false; 478 } 479 480 // Verify that it's not the default language for that client 481 $params = JComponentHelper::getParams('com_languages'); 482 if ($params->get($client->name) == $element) 483 { 484 JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_LANG_UNINSTALL_DEFAULT')); 485 return false; 486 } 487 488 // Construct the path from the client, the language and the extension element name 489 $path = $client->path . '/language/' . $element; 490 491 // Get the package manifest object and remove media 492 $this->parent->setPath('source', $path); 493 // We do findManifest to avoid problem when uninstalling a list of extension: getManifest cache its manifest file 494 $this->parent->findManifest(); 495 $this->manifest = $this->parent->getManifest(); 496 $this->parent->removeFiles($this->manifest->media); 497 498 // Check it exists 499 if (!JFolder::exists($path)) 500 { 501 // If the folder doesn't exist lets just nuke the row as well and presume the user killed it for us 502 $extension->delete(); 503 JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_LANG_UNINSTALL_PATH_EMPTY')); 504 return false; 505 } 506 507 if (!JFolder::delete($path)) 508 { 509 // If deleting failed we'll leave the extension entry in tact just in case 510 JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_LANG_UNINSTALL_DIRECTORY')); 511 return false; 512 } 513 514 // Remove the extension table entry 515 $extension->delete(); 516 517 // Setting the language of users which have this language as the default language 518 $db = JFactory::getDbo(); 519 $query = $db->getQuery(true); 520 $query->from('#__users'); 521 $query->select('*'); 522 $db->setQuery($query); 523 $users = $db->loadObjectList(); 524 if ($client->name == 'administrator') 525 { 526 $param_name = 'admin_language'; 527 } 528 else 529 { 530 $param_name = 'language'; 531 } 532 533 $count = 0; 534 foreach ($users as $user) 535 { 536 $registry = new JRegistry; 537 $registry->loadString($user->params); 538 if ($registry->get($param_name) == $element) 539 { 540 $registry->set($param_name, ''); 541 $query = $db->getQuery(true); 542 $query->update('#__users'); 543 $query->set('params=' . $db->quote($registry)); 544 $query->where('id=' . (int) $user->id); 545 $db->setQuery($query); 546 $db->query(); 547 $count = $count + 1; 548 } 549 } 550 if (!empty($count)) 551 { 552 JError::raiseNotice(500, JText::plural('JLIB_INSTALLER_NOTICE_LANG_RESET_USERS', $count)); 553 } 554 555 // All done! 556 return true; 557 } 558 559 /** 560 * Custom discover method 561 * Finds language files 562 * 563 * @return boolean True on success 564 * 565 * @since 11.1 566 */ 567 public function discover() 568 { 569 $results = array(); 570 $site_languages = JFolder::folders(JPATH_SITE . '/language'); 571 $admin_languages = JFolder::folders(JPATH_ADMINISTRATOR . '/language'); 572 foreach ($site_languages as $language) 573 { 574 if (file_exists(JPATH_SITE . '/language/' . $language . '/' . $language . '.xml')) 575 { 576 $manifest_details = JApplicationHelper::parseXMLInstallFile(JPATH_SITE . '/language/' . $language . '/' . $language . '.xml'); 577 $extension = JTable::getInstance('extension'); 578 $extension->set('type', 'language'); 579 $extension->set('client_id', 0); 580 $extension->set('element', $language); 581 $extension->set('name', $language); 582 $extension->set('state', -1); 583 $extension->set('manifest_cache', json_encode($manifest_details)); 584 $results[] = $extension; 585 } 586 } 587 foreach ($admin_languages as $language) 588 { 589 if (file_exists(JPATH_ADMINISTRATOR . '/language/' . $language . '/' . $language . '.xml')) 590 { 591 $manifest_details = JApplicationHelper::parseXMLInstallFile(JPATH_ADMINISTRATOR . '/language/' . $language . '/' . $language . '.xml'); 592 $extension = JTable::getInstance('extension'); 593 $extension->set('type', 'language'); 594 $extension->set('client_id', 1); 595 $extension->set('element', $language); 596 $extension->set('name', $language); 597 $extension->set('state', -1); 598 $extension->set('manifest_cache', json_encode($manifest_details)); 599 $results[] = $extension; 600 } 601 } 602 return $results; 603 } 604 605 /** 606 * Custom discover install method 607 * Basically updates the manifest cache and leaves everything alone 608 * 609 * @return integer The extension id 610 * 611 * @since 11.1 612 */ 613 public function discover_install() 614 { 615 // Need to find to find where the XML file is since we don't store this normally 616 $client = JApplicationHelper::getClientInfo($this->parent->extension->client_id); 617 $short_element = $this->parent->extension->element; 618 $manifestPath = $client->path . '/language/' . $short_element . '/' . $short_element . '.xml'; 619 $this->parent->manifest = $this->parent->isManifest($manifestPath); 620 $this->parent->setPath('manifest', $manifestPath); 621 $this->parent->setPath('source', $client->path . '/language/' . $short_element); 622 $this->parent->setPath('extension_root', $this->parent->getPath('source')); 623 $manifest_details = JApplicationHelper::parseXMLInstallFile($this->parent->getPath('manifest')); 624 $this->parent->extension->manifest_cache = json_encode($manifest_details); 625 $this->parent->extension->state = 0; 626 $this->parent->extension->name = $manifest_details['name']; 627 $this->parent->extension->enabled = 1; 628 //$this->parent->extension->params = $this->parent->getParams(); 629 try 630 { 631 $this->parent->extension->store(); 632 } 633 catch (JException $e) 634 { 635 JError::raiseWarning(101, JText::_('JLIB_INSTALLER_ERROR_LANG_DISCOVER_STORE_DETAILS')); 636 return false; 637 } 638 return $this->parent->extension->get('extension_id'); 639 } 640 641 /** 642 * Refreshes the extension table cache 643 * 644 * @return boolean result of operation, true if updated, false on failure 645 * 646 * @since 11.1 647 */ 648 public function refreshManifestCache() 649 { 650 $client = JApplicationHelper::getClientInfo($this->parent->extension->client_id); 651 $manifestPath = $client->path . '/language/' . $this->parent->extension->element . '/' . $this->parent->extension->element . '.xml'; 652 $this->parent->manifest = $this->parent->isManifest($manifestPath); 653 $this->parent->setPath('manifest', $manifestPath); 654 $manifest_details = JApplicationHelper::parseXMLInstallFile($this->parent->getPath('manifest')); 655 $this->parent->extension->manifest_cache = json_encode($manifest_details); 656 $this->parent->extension->name = $manifest_details['name']; 657 658 if ($this->parent->extension->store()) 659 { 660 return true; 661 } 662 else 663 { 664 JError::raiseWarning(101, JText::_('JLIB_INSTALLER_ERROR_MOD_REFRESH_MANIFEST_CACHE')); 665 666 return false; 667 } 668 } 669 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Tue Apr 3 11:40:28 2012 | Cross-referenced by PHPXref 0.7.1 |