Source for file database.php

Documentation is available at database.php

  1. <?php
  2. /**
  3.  * @package     Joomla.Installation
  4.  * @subpackage  Model
  5.  *
  6.  * @copyright   Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
  7.  * @license     GNU General Public License version 2 or later; see LICENSE.txt
  8.  */
  9.  
  10. defined('_JEXEC'or die;
  11.  
  12. /**
  13.  * Database configuration model for the Joomla Core Installer.
  14.  *
  15.  * @package  Joomla.Installation
  16.  * @since    3.1
  17.  */
  18. {
  19.     /**
  20.      * The generated user ID
  21.      *
  22.      * @var    integer 
  23.      * @since  3.1
  24.      */
  25.     protected static $userId 0;
  26.  
  27.     /**
  28.      * Generates the user ID
  29.      *
  30.      * @return  integer  The user ID
  31.      *
  32.      * @since   3.1
  33.      */
  34.     protected static function generateRandUserId()
  35.     {
  36.         $session JFactory::getSession();
  37.         $randUserId $session->get('randUserId');
  38.  
  39.         if (empty($randUserId))
  40.         {
  41.             // Create the ID for the root user only once and store in session
  42.             $randUserId mt_rand(11000);
  43.             $session->set('randUserId'$randUserId);
  44.         }
  45.  
  46.         return $randUserId;
  47.     }
  48.  
  49.     /**
  50.      * Resets the user ID
  51.      *
  52.      * @return  void 
  53.      *
  54.      * @since   3.1
  55.      */
  56.     public static function resetRandUserId()
  57.     {
  58.         self::$userId 0;
  59.         $session JFactory::getSession();
  60.         $session->set('randUserId'self::$userId);
  61.     }
  62.  
  63.     /**
  64.      * Retrieves the default user ID and sets it if necessary
  65.      *
  66.      * @return  integer  The user ID
  67.      *
  68.      * @since   3.1
  69.      */
  70.     public static function getUserId()
  71.     {
  72.         if (!self::$userId)
  73.         {
  74.             self::$userId self::generateRandUserId();
  75.         }
  76.  
  77.         return self::$userId;
  78.     }
  79.  
  80.     /**
  81.      * Method to initialise the database
  82.      *
  83.      * @param   array  $options  The options to use for configuration
  84.      *
  85.      * @return  boolean  True on success
  86.      *
  87.      * @since   3.1
  88.      */
  89.     public function initialise($options)
  90.     {
  91.         // Get the application
  92.         /* @var InstallationApplicationWeb $app */
  93.         $app JFactory::getApplication();
  94.  
  95.         // Get the options as a object for easier handling.
  96.         $options JArrayHelper::toObject($options);
  97.  
  98.         // Load the back-end language files so that the DB error messages work
  99.         $lang JFactory::getLanguage();
  100.         $currentLang $lang->getTag();
  101.  
  102.         // Load the selected language
  103.         if (JLanguage::exists($currentLangJPATH_ADMINISTRATOR))
  104.         {
  105.             $lang->load('joomla'JPATH_ADMINISTRATOR$currentLangtrue);
  106.         }
  107.         // Pre-load en-GB in case the chosen language files do not exist
  108.         else
  109.         {
  110.             $lang->load('joomla'JPATH_ADMINISTRATOR'en-GB'true);
  111.         }
  112.  
  113.         // Ensure a database type was selected.
  114.         if (empty($options->db_type))
  115.         {
  116.             $app->enqueueMessage(JText::_('INSTL_DATABASE_INVALID_TYPE')'notice');
  117.             return false;
  118.         }
  119.  
  120.         // Ensure that a hostname and user name were input.
  121.         if (empty($options->db_host|| empty($options->db_user))
  122.         {
  123.             $app->enqueueMessage(JText::_('INSTL_DATABASE_INVALID_DB_DETAILS')'notice');
  124.             return false;
  125.         }
  126.  
  127.         // Ensure that a database name was input.
  128.         if (empty($options->db_name))
  129.         {
  130.             $app->enqueueMessage(JText::_('INSTL_DATABASE_EMPTY_NAME')'notice');
  131.             return false;
  132.         }
  133.  
  134.         // Validate database table prefix.
  135.         if (!preg_match('#^[a-zA-Z]+[a-zA-Z0-9_]*$#'$options->db_prefix))
  136.         {
  137.             $app->enqueueMessage(JText::_('INSTL_DATABASE_PREFIX_INVALID_CHARS')'notice');
  138.             return false;
  139.         }
  140.  
  141.         // Validate length of database table prefix.
  142.         if (strlen($options->db_prefix15)
  143.         {
  144.             $app->enqueueMessage(JText::_('INSTL_DATABASE_FIX_TOO_LONG')'notice');
  145.             return false;
  146.         }
  147.  
  148.         // Validate length of database name.
  149.         if (strlen($options->db_name64)
  150.         {
  151.             $app->enqueueMessage(JText::_('INSTL_DATABASE_NAME_TOO_LONG')'notice');
  152.             return false;
  153.         }
  154.  
  155.         // Get a database object.
  156.         try
  157.         {
  158.             return InstallationHelperDatabase::getDbo(
  159.                 $options->db_type$options->db_host$options->db_user$options->db_pass$options->db_name$options->db_prefix$options->db_select
  160.             );
  161.         }
  162.         catch (RuntimeException $e)
  163.         {
  164.             $app->enqueueMessage(JText::sprintf('INSTL_DATABASE_COULD_NOT_CONNECT'$e->getMessage())'notice');
  165.             return false;
  166.         }
  167.     }
  168.  
  169.     /**
  170.      * Method to create a new database.
  171.      *
  172.      * @param   array  $options  The configuration options
  173.      *
  174.      * @return    boolean    True on success.
  175.      *
  176.      * @since    3.1
  177.      */
  178.     public function createDatabase($options)
  179.     {
  180.         // Get the application
  181.         /* @var InstallationApplicationWeb $app */
  182.         $app JFactory::getApplication();
  183.  
  184.         // Disable autoselect database before it's created
  185.         $tmpSelect true;
  186.  
  187.         if (isset($options['db_select']))
  188.         {
  189.             $tmpSelect $options['db_select'];
  190.         }
  191.         $options['db_select'false;
  192.  
  193.         if (!$db $this->initialise($options))
  194.         {
  195.             return false;
  196.         }
  197.  
  198.         // Get the options as a object for easier handling.
  199.         $options JArrayHelper::toObject($options);
  200.  
  201.         // Check database version.
  202.         $type $options->db_type;
  203.  
  204.         try
  205.         {
  206.             $db_version $db->getVersion();
  207.         }
  208.         catch (RuntimeException $e)
  209.         {
  210.             $app->enqueueMessage(JText::sprintf('INSTL_DATABASE_COULD_NOT_CONNECT'$e->getMessage())'notice');
  211.             return false;
  212.         }
  213.  
  214.         if (!$db->isMinimumVersion())
  215.         {
  216.             $app->enqueueMessage(JText::sprintf('INSTL_DATABASE_INVALID_' strtoupper($type'_VERSION'$db_version)'notice');
  217.             return false;
  218.         }
  219.  
  220.         if (($type == 'mysql'|| ($type == 'mysqli'))
  221.         {
  222.             // @internal MySQL versions pre 5.1.6 forbid . / or \ or NULL
  223.             if ((preg_match('#[\\\/\.\0]#'$options->db_name)) && (!version_compare($db_version'5.1.6''>=')))
  224.             {
  225.                 $app->enqueueMessage(JText::sprintf('INSTL_DATABASE_INVALID_NAME'$db_version)'notice');
  226.                 return false;
  227.             }
  228.         }
  229.  
  230.         // @internal Check for spaces in beginning or end of name
  231.         if (strlen(trim($options->db_name)) <> strlen($options->db_name))
  232.         {
  233.             $app->enqueueMessage(JText::_('INSTL_DATABASE_NAME_INVALID_SPACES')'notice');
  234.             return false;
  235.         }
  236.  
  237.         // @internal Check for asc(00) Null in name
  238.         if (strpos($options->db_namechr(00)) !== false)
  239.         {
  240.             $app->enqueueMessage(JText::_('INSTL_DATABASE_NAME_INVALID_CHAR')'notice');
  241.             return false;
  242.         }
  243.  
  244.         // PostgreSQL database older than version 9.0.0 needs to run 'CREATE LANGUAGE' to create function.
  245.         if (($options->db_type == 'postgresql'&& (version_compare($db_version'9.0.0''<')))
  246.         {
  247.             $db->setQuery("CREATE LANGUAGE plpgsql");
  248.             $db->execute();
  249.         }
  250.  
  251.         // Get database's UTF support
  252.         $utfSupport $db->hasUTFSupport();
  253.  
  254.         // Try to select the database
  255.         try
  256.         {
  257.             $db->select($options->db_name);
  258.         }
  259.         catch (RuntimeException $e)
  260.         {
  261.             // If the database could not be selected, attempt to create it and then select it.
  262.             if ($this->createDB($db$options$utfSupport))
  263.             {
  264.                 $db->select($options->db_name);
  265.             }
  266.             else
  267.             {
  268.                 $app->enqueueMessage(JText::sprintf('INSTL_DATABASE_ERROR_CREATE'$options->db_name)'notice');
  269.                 return false;
  270.             }
  271.         }
  272.  
  273.         $options = (array) $options;
  274.  
  275.         // Remove *_errors value
  276.         foreach ($options as $i => $option)
  277.         {
  278.             if (isset($i['1']&& $i['1'== '*')
  279.             {
  280.                 unset($options[$i]);
  281.                 break;
  282.             }
  283.         }
  284.         $options array_merge(array('db_created' => 1)$options);
  285.  
  286.         // Restore autoselect value after database creation
  287.         $options['db_select'$tmpSelect;
  288.  
  289.         $session JFactory::getSession();
  290.         $session->set('setup.options'$options);
  291.  
  292.         return true;
  293.     }
  294.  
  295.     /**
  296.      * Method to process the old database
  297.      *
  298.      * @param   array  $options  The options array
  299.      *
  300.      * @return  boolean  True on success
  301.      *
  302.      * @since   3.1
  303.      */
  304.     public function handleOldDatabase($options)
  305.     {
  306.         if (!isset($options['db_created']|| !$options['db_created'])
  307.         {
  308.             return $this->createDatabase($options);
  309.         }
  310.  
  311.         if (!$db $this->initialise($options))
  312.         {
  313.             return false;
  314.         }
  315.  
  316.         // Get the options as a object for easier handling.
  317.         $options JArrayHelper::toObject($options);
  318.  
  319.         // Set the character set to UTF-8 for pre-existing databases.
  320.         $this->setDatabaseCharset($db$options->db_name);
  321.  
  322.         // Should any old database tables be removed or backed up?
  323.         if ($options->db_old == 'remove')
  324.         {
  325.             // Attempt to delete the old database tables.
  326.             if (!$this->deleteDatabase($db$options->db_prefix))
  327.             {
  328.                 // Message queued by method, simply return
  329.                 return false;
  330.             }
  331.         }
  332.         else
  333.         {
  334.             // If the database isn't being deleted, back it up.
  335.             if (!$this->backupDatabase($db$options->db_prefix))
  336.             {
  337.                 return false;
  338.             }
  339.         }
  340.  
  341.         return true;
  342.     }
  343.  
  344.     /**
  345.      * Method to create the database tables
  346.      *
  347.      * @param   array  $options  The options array
  348.      *
  349.      * @return  boolean  True on success
  350.      *
  351.      * @since   3.1
  352.      */
  353.     public function createTables($options)
  354.     {
  355.         // Get the application
  356.         /* @var InstallationApplicationWeb $app */
  357.         $app JFactory::getApplication();
  358.  
  359.         if (!isset($options['db_created']|| !$options['db_created'])
  360.         {
  361.             return $this->createDatabase($options);
  362.         }
  363.  
  364.         if (!$db $this->initialise($options))
  365.         {
  366.             return false;
  367.         }
  368.  
  369.         // Get the options as a object for easier handling.
  370.         $options JArrayHelper::toObject($options);
  371.  
  372.         // Check database type.
  373.         $type $options->db_type;
  374.  
  375.         // Set the character set to UTF-8 for pre-existing databases.
  376.         $this->setDatabaseCharset($db$options->db_name);
  377.  
  378.         // Set the appropriate schema script based on UTF-8 support.
  379.         if ($type == 'mysqli' || $type == 'mysql')
  380.         {
  381.             $schema 'sql/mysql/joomla.sql';
  382.         }
  383.         elseif ($type == 'sqlsrv' || $type == 'sqlazure')
  384.         {
  385.             $schema 'sql/sqlazure/joomla.sql';
  386.         }
  387.         else
  388.         {
  389.             $schema 'sql/' $type '/joomla.sql';
  390.         }
  391.  
  392.         // Check if the schema is a valid file
  393.         if (!is_file($schema))
  394.         {
  395.             $app->enqueueMessage(JText::sprintf('INSTL_ERROR_DB'JText::_('INSTL_DATABASE_NO_SCHEMA'))'notice');
  396.             return false;
  397.         }
  398.  
  399.         // Attempt to import the database schema.
  400.         if (!$this->populateDatabase($db$schema))
  401.         {
  402.             return false;
  403.         }
  404.  
  405.         // Attempt to update the table #__schema.
  406.         $pathPart JPATH_ADMINISTRATOR '/components/com_admin/sql/updates/';
  407.  
  408.         if ($type == 'mysqli' || $type == 'mysql')
  409.         {
  410.             $pathPart .= 'mysql/';
  411.         }
  412.         elseif ($type == 'sqlsrv' || $type == 'sqlazure')
  413.         {
  414.             $pathPart .= 'sqlazure/';
  415.         }
  416.         else
  417.         {
  418.             $pathPart .= $type '/';
  419.         }
  420.         $files JFolder::files($pathPart'\.sql$');
  421.  
  422.         if (empty($files))
  423.         {
  424.             $app->enqueueMessage(JText::_('INSTL_ERROR_INITIALISE_SCHEMA')'notice');
  425.             return false;
  426.         }
  427.         $version '';
  428.  
  429.         foreach ($files as $file)
  430.         {
  431.             if (version_compare($versionJFile::stripExt($file)) 0)
  432.             {
  433.                 $version JFile::stripExt($file);
  434.             }
  435.         }
  436.         $query $db->getQuery(true)
  437.             ->insert($db->quoteName('#__schemas'))
  438.             ->columns(
  439.                 array(
  440.                     $db->quoteName('extension_id'),
  441.                     $db->quoteName('version_id')
  442.                 )
  443.             )
  444.             ->values('700, ' $db->quote($version));
  445.         $db->setQuery($query);
  446.  
  447.         try
  448.         {
  449.             $db->execute();
  450.         }
  451.         catch (RuntimeException $e)
  452.         {
  453.             $app->enqueueMessage($e->getMessage()'notice');
  454.             return false;
  455.         }
  456.  
  457.         // Attempt to refresh manifest caches
  458.         $query->clear()
  459.             ->select('*')
  460.             ->from('#__extensions');
  461.         $db->setQuery($query);
  462.  
  463.         $return true;
  464.  
  465.         try
  466.         {
  467.             $extensions $db->loadObjectList();
  468.         }
  469.         catch (RuntimeException $e)
  470.         {
  471.             $app->enqueueMessage($e->getMessage()'notice');
  472.             $return false;
  473.         }
  474.  
  475.         JFactory::$database $db;
  476.         $installer JInstaller::getInstance();
  477.  
  478.         foreach ($extensions as $extension)
  479.         {
  480.             if (!$installer->refreshManifestCache($extension->extension_id))
  481.             {
  482.                 $app->enqueueMessage(JText::sprintf('INSTL_DATABASE_COULD_NOT_REFRESH_MANIFEST_CACHE'$extension->name)'notice');
  483.                 return false;
  484.             }
  485.         }
  486.  
  487.         // Load the localise.sql for translating the data in joomla.sql
  488.         if ($type == 'mysqli' || $type == 'mysql')
  489.         {
  490.             $dblocalise 'sql/mysql/localise.sql';
  491.         }
  492.         elseif ($type == 'sqlsrv' || $type == 'sqlazure')
  493.         {
  494.             $dblocalise 'sql/sqlazure/localise.sql';
  495.         }
  496.         else
  497.         {
  498.             $dblocalise 'sql/' $type '/localise.sql';
  499.         }
  500.  
  501.         if (is_file($dblocalise))
  502.         {
  503.             if (!$this->populateDatabase($db$dblocalise))
  504.             {
  505.                 return false;
  506.             }
  507.         }
  508.  
  509.         // Handle default backend language setting. This feature is available for localized versions of Joomla.
  510.         $app JFactory::getApplication();
  511.         $languages $app->getLocaliseAdmin($db);
  512.  
  513.         if (in_array($options->language$languages['admin']|| in_array($options->language$languages['site']))
  514.         {
  515.             // Build the language parameters for the language manager.
  516.             $params array();
  517.  
  518.             // Set default administrator/site language to sample data values:
  519.             $params['administrator''en-GB';
  520.             $params['site''en-GB';
  521.  
  522.             if (in_array($options->language$languages['admin']))
  523.             {
  524.                 $params['administrator'$options->language;
  525.             }
  526.  
  527.             if (in_array($options->language$languages['site']))
  528.             {
  529.                 $params['site'$options->language;
  530.             }
  531.             $params json_encode($params);
  532.  
  533.             // Update the language settings in the language manager.
  534.             $query->clear()
  535.                 ->update($db->quoteName('#__extensions'))
  536.                 ->set($db->quoteName('params'' = ' $db->quote($params))
  537.                 ->where($db->quoteName('element'' = ' $db->quote('com_languages'));
  538.             $db->setQuery($query);
  539.  
  540.             try
  541.             {
  542.                 $db->execute();
  543.             }
  544.             catch (RuntimeException $e)
  545.             {
  546.                 $app->enqueueMessage($e->getMessage()'notice');
  547.                 $return false;
  548.             }
  549.         }
  550.  
  551.         return $return;
  552.     }
  553.  
  554.     /**
  555.      * Method to install the sample data
  556.      *
  557.      * @param   array  $options  The options array
  558.      *
  559.      * @return  boolean  True on success
  560.      *
  561.      * @since   3.1
  562.      */
  563.     public function installSampleData($options)
  564.     {
  565.         // Get the application
  566.         /* @var InstallationApplicationWeb $app */
  567.         $app JFactory::getApplication();
  568.  
  569.         if (!isset($options['db_created']|| !$options['db_created'])
  570.         {
  571.             return $this->createDatabase($options);
  572.         }
  573.  
  574.         if (!$db $this->initialise($options))
  575.         {
  576.             return false;
  577.         }
  578.  
  579.         // Get the options as a object for easier handling.
  580.         $options JArrayHelper::toObject($options);
  581.  
  582.         // Build the path to the sample data file.
  583.         $type $options->db_type;
  584.  
  585.         if ($type == 'mysqli')
  586.         {
  587.             $type 'mysql';
  588.         }
  589.         elseif ($type == 'sqlsrv')
  590.         {
  591.             $type 'sqlazure';
  592.         }
  593.  
  594.         $data JPATH_INSTALLATION '/sql/' $type '/' $options->sample_file;
  595.  
  596.         // Attempt to import the database schema if one is chosen.
  597.         if ($options->sample_file != '')
  598.         {
  599.             if (!file_exists($data))
  600.             {
  601.                 $app->enqueueMessage(JText::sprintf('INSTL_DATABASE_FILE_DOES_NOT_EXIST'$data)'notice');
  602.                 return false;
  603.             }
  604.             elseif (!$this->populateDatabase($db$data))
  605.             {
  606.                 return false;
  607.             }
  608.  
  609.             $this->postInstallSampleData($db);
  610.         }
  611.  
  612.         return true;
  613.     }
  614.  
  615.     /**
  616.      * Method to update the user id of the sample data content to the new rand user id
  617.      *
  618.      * @param   JDatabaseDriver  $db  Database connector object $db*
  619.      *
  620.      * @return  void 
  621.      *
  622.      * @since   3.1
  623.      */
  624.     protected function postInstallSampleData($db)
  625.     {
  626.         // Create the ID for the root user
  627.         $userId self::getUserId();
  628.  
  629.         // Update all created_by field of the tables with the random user id
  630.         // categories (created_user_id), contact_details, content, newsfeeds, weblinks
  631.         $updates_array array(
  632.             'categories' => 'created_user_id',
  633.             'contact_details' => 'created_by',
  634.             'content' => 'created_by',
  635.             'newsfeeds' => 'created_by',
  636.             'weblinks' => 'created_by',
  637.         );
  638.  
  639.         foreach ($updates_array as $table => $field)
  640.         {
  641.             $db->setQuery(
  642.                 'UPDATE ' $db->quoteName('#__' $table.
  643.                     ' SET ' $db->quoteName($field' = ' $db->quote($userId)
  644.             );
  645.             $db->execute();
  646.         }
  647.     }
  648.  
  649.     /**
  650.      * Method to backup all tables in a database with a given prefix.
  651.      *
  652.      * @param   JDatabaseDriver  $db      JDatabaseDriver object.
  653.      * @param   string           $prefix  Database table prefix.
  654.      *
  655.      * @return  boolean  True on success.
  656.      *
  657.      * @since    3.1
  658.      */
  659.     public function backupDatabase($db$prefix)
  660.     {
  661.         $return true;
  662.         $backup 'bak_' $prefix;
  663.  
  664.         // Get the tables in the database.
  665.         $tables $db->getTableList();
  666.  
  667.         if ($tables)
  668.         {
  669.             foreach ($tables as $table)
  670.             {
  671.                 // If the table uses the given prefix, back it up.
  672.                 if (strpos($table$prefix=== 0)
  673.                 {
  674.                     // Backup table name.
  675.                     $backupTable str_replace($prefix$backup$table);
  676.  
  677.                     // Drop the backup table.
  678.                     try
  679.                     {
  680.                         $db->dropTable($backupTabletrue);
  681.                     }
  682.                     catch (RuntimeException $e)
  683.                     {
  684.                         JFactory::getApplication()->enqueueMessage(JText::sprintf('INSTL_DATABASE_ERROR_BACKINGUP'$e->getMessage())'notice');
  685.                         $return false;
  686.                     }
  687.  
  688.                     // Rename the current table to the backup table.
  689.                     try
  690.                     {
  691.                         $db->renameTable($table$backupTable$backup$prefix);
  692.                     }
  693.                     catch (RuntimeException $e)
  694.                     {
  695.                         JFactory::getApplication()->enqueueMessage(JText::sprintf('INSTL_DATABASE_ERROR_BACKINGUP'$e->getMessage())'notice');
  696.                         $return false;
  697.                     }
  698.                 }
  699.             }
  700.         }
  701.  
  702.         return $return;
  703.     }
  704.  
  705.     /**
  706.      * Method to create a new database.
  707.      *
  708.      * @param   JDatabaseDriver  $db       JDatabase object.
  709.      * @param   JObject          $options  JObject coming from "initialise" function to pass user
  710.      *                                      and database name to database driver.
  711.      * @param   boolean          $utf      True if the database supports the UTF-8 character set.
  712.      *
  713.      * @return  boolean  True on success.
  714.      *
  715.      * @since   3.1
  716.      */
  717.     public function createDB($db$options$utf)
  718.     {
  719.         // Build the create database query.
  720.         try
  721.         {
  722.             // Run the create database query.
  723.             $db->createDatabase($options$utf);
  724.         }
  725.         catch (RuntimeException $e)
  726.         {
  727.             // If an error occurred return false.
  728.             return false;
  729.         }
  730.  
  731.         return true;
  732.     }
  733.  
  734.     /**
  735.      * Method to delete all tables in a database with a given prefix.
  736.      *
  737.      * @param   JDatabaseDriver  $db      JDatabaseDriver object.
  738.      * @param   string           $prefix  Database table prefix.
  739.      *
  740.      * @return  boolean  True on success.
  741.      *
  742.      * @since   3.1
  743.      */
  744.     public function deleteDatabase($db$prefix)
  745.     {
  746.         $return true;
  747.  
  748.         // Get the tables in the database.
  749.         $tables $db->getTableList();
  750.  
  751.         if ($tables)
  752.         {
  753.             foreach ($tables as $table)
  754.             {
  755.                 // If the table uses the given prefix, drop it.
  756.                 if (strpos($table$prefix=== 0)
  757.                 {
  758.                     // Drop the table.
  759.                     try
  760.                     {
  761.                         $db->dropTable($table);
  762.                     }
  763.                     catch (RuntimeException $e)
  764.                     {
  765.                         JFactory::getApplication()->enqueueMessage(JText::sprintf('INSTL_DATABASE_ERROR_DELETE'$e->getMessage())'notice');
  766.                         $return false;
  767.                     }
  768.                 }
  769.             }
  770.         }
  771.  
  772.         return $return;
  773.     }
  774.  
  775.     /**
  776.      * Method to import a database schema from a file.
  777.      *
  778.      * @param   JDatabaseDriver  $db      JDatabase object.
  779.      * @param   string           $schema  Path to the schema file.
  780.      *
  781.      * @return  boolean  True on success.
  782.      *
  783.      * @since   3.1
  784.      */
  785.     public function populateDatabase($db$schema)
  786.     {
  787.         // Get the application
  788.         /* @var InstallationApplicationWeb $app */
  789.         $app JFactory::getApplication();
  790.  
  791.         $return true;
  792.  
  793.         // Get the contents of the schema file.
  794.         if (!($buffer file_get_contents($schema)))
  795.         {
  796.             $app->enqueueMessage($db->getErrorMsg()'notice');
  797.             return false;
  798.         }
  799.  
  800.         // Get an array of queries from the schema and process them.
  801.         $queries $this->_splitQueries($buffer);
  802.  
  803.         foreach ($queries as $query)
  804.         {
  805.             // Trim any whitespace.
  806.             $query trim($query);
  807.  
  808.             // If the query isn't empty and is not a MySQL or PostgreSQL comment, execute it.
  809.             if (!empty($query&& ($query{0!= '#'&& ($query{0!= '-'))
  810.             {
  811.                 // Execute the query.
  812.                 $db->setQuery($query);
  813.  
  814.                 try
  815.                 {
  816.                     $db->execute();
  817.                 }
  818.                 catch (RuntimeException $e)
  819.                 {
  820.                     $app->enqueueMessage($e->getMessage()'notice');
  821.                     $return false;
  822.                 }
  823.             }
  824.         }
  825.  
  826.         return $return;
  827.     }
  828.  
  829.     /**
  830.      * Method to set the database character set to UTF-8.
  831.      *
  832.      * @param   JDatabaseDriver  $db    JDatabaseDriver object.
  833.      * @param   string           $name  Name of the database to process.
  834.      *
  835.      * @return  boolean  True on success.
  836.      *
  837.      * @since   3.1
  838.      */
  839.     public function setDatabaseCharset($db$name)
  840.     {
  841.         // Run the create database query.
  842.         $db->setQuery($db->getAlterDbCharacterSet($name));
  843.  
  844.         try
  845.         {
  846.             $db->execute();
  847.         }
  848.         catch (RuntimeException $e)
  849.         {
  850.             return false;
  851.         }
  852.  
  853.         return true;
  854.     }
  855.  
  856.     /**
  857.      * Method to split up queries from a schema file into an array.
  858.      *
  859.      * @param   string  $query  SQL schema.
  860.      *
  861.      * @return  array  Queries to perform.
  862.      *
  863.      * @since   3.1
  864.      */
  865.     protected function _splitQueries($query)
  866.     {
  867.         $buffer array();
  868.         $queries array();
  869.         $in_string false;
  870.  
  871.         // Trim any whitespace.
  872.         $query trim($query);
  873.  
  874.         // Remove comment lines.
  875.         $query preg_replace("/\n\#[^\n]*/"''"\n" $query);
  876.  
  877.         // Remove PostgreSQL comment lines.
  878.         $query preg_replace("/\n\--[^\n]*/"''"\n" $query);
  879.  
  880.         // Find function
  881.         $funct explode('CREATE OR REPLACE FUNCTION'$query);
  882.  
  883.         // Save sql before function and parse it
  884.         $query $funct[0];
  885.  
  886.         // Parse the schema file to break up queries.
  887.         for ($i 0$i strlen($query1$i++)
  888.         {
  889.             if ($query[$i== ";" && !$in_string)
  890.             {
  891.                 $queries[substr($query0$i);
  892.                 $query substr($query$i 1);
  893.                 $i 0;
  894.             }
  895.  
  896.             if ($in_string && ($query[$i== $in_string&& $buffer[1!= "\\")
  897.             {
  898.                 $in_string false;
  899.             }
  900.             elseif (!$in_string && ($query[$i== '"' || $query[$i== "'"&& (!isset ($buffer[0]|| $buffer[0!= "\\"))
  901.             {
  902.                 $in_string $query[$i];
  903.             }
  904.             if (isset ($buffer[1]))
  905.             {
  906.                 $buffer[0$buffer[1];
  907.             }
  908.             $buffer[1$query[$i];
  909.         }
  910.  
  911.         // If the is anything left over, add it to the queries.
  912.         if (!empty($query))
  913.         {
  914.             $queries[$query;
  915.         }
  916.  
  917.         // Add function part as is
  918.         for ($f 1$f count($funct)$f++)
  919.         {
  920.             $queries['CREATE OR REPLACE FUNCTION ' $funct[$f];
  921.         }
  922.  
  923.         return $queries;
  924.     }
  925. }

Documentation generated on Tue, 19 Nov 2013 14:57:50 +0100 by phpDocumentor 1.4.3