[ Index ]

PHP Cross Reference of Joomla 2.5.4 DE

title

Body

[close]

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

   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  }


Generated: Tue Apr 3 11:40:28 2012 Cross-referenced by PHPXref 0.7.1