Back to Installer class

Method parseSchemaUpdates

public bool
parseSchemaUpdates
(\SimpleXMLElement $schema, mixed $eid)
Method to process the updates for an item
Parameters
  • \SimpleXMLElement $schema The XML node to process
  • int $eid Extension Identifier
Returns
  • bool Result of the operations
Since
  • 3.1
Class: Installer
Project: Joomla

Method parseSchemaUpdates - Source code

/**
 * Method to process the updates for an item
 *
 * @param   \SimpleXMLElement  $schema  The XML node to process
 * @param   integer            $eid     Extension Identifier
 *
 * @return  boolean           Result of the operations
 *
 * @since   3.1
 */
public function parseSchemaUpdates(\SimpleXMLElement $schema, $eid)
{
    $update_count = 0;
    // Ensure we have an XML element and a valid extension id
    if ($eid && $schema) {
        $db = Factory::getDbo();
        $schemapaths = $schema->children();
        if (\count($schemapaths)) {
            $dbDriver = $db->getServerType();
            $schemapath = '';
            foreach ($schemapaths as $entry) {
                $attrs = $entry->attributes();
                // Assuming that the type is a mandatory attribute but if it is not mandatory then there should be a discussion for it.
                $uDriver = strtolower($attrs['type']);
                if ($uDriver === 'mysqli' || $uDriver === 'pdomysql') {
                    $uDriver = 'mysql';
                } elseif ($uDriver === 'pgsql') {
                    $uDriver = 'postgresql';
                }
                if ($uDriver == $dbDriver) {
                    $schemapath = $entry;
                    break;
                }
            }
            if ($schemapath !== '') {
                $files = Folder::files($this->getPath('extension_root') . '/' . $schemapath, '\\.sql$');
                if (empty($files)) {
                    return $update_count;
                }
                $files = str_replace('.sql', '', $files);
                usort($files, 'version_compare');
                $query = $db->getQuery(true)->select('version_id')->from('#__schemas')->where('extension_id = :extension_id')->bind(':extension_id', $eid, ParameterType::INTEGER);
                $db->setQuery($query);
                try {
                    $version = $db->loadResult();
                    // No version - use initial version.
                    if (!$version) {
                        $version = '0.0.0';
                    }
                } catch (ExecutionFailureException $e) {
                    $version = '0.0.0';
                }
                Log::add(Text::_('JLIB_INSTALLER_SQL_BEGIN'), Log::INFO, 'Update');
                Log::add(Text::sprintf('JLIB_INSTALLER_SQL_BEGIN_SCHEMA', $version), Log::INFO, 'Update');
                foreach ($files as $file) {
                    if (version_compare($file, $version) > 0) {
                        $buffer = file_get_contents($this->getPath('extension_root') . '/' . $schemapath . '/' . $file . '.sql');
                        // Graceful exit and rollback if read not successful
                        if ($buffer === false) {
                            Log::add(Text::sprintf('JLIB_INSTALLER_ERROR_SQL_READBUFFER'), Log::WARNING, 'jerror');
                            return false;
                        }
                        // Create an array of queries from the sql file
                        $queries = DatabaseDriver::splitSql($buffer);
                        if (\count($queries) === 0) {
                            // No queries to process
                            continue;
                        }
                        // Process each query in the $queries array (split out of sql file).
                        foreach ($queries as $query) {
                            $queryString = (string) $query;
                            $queryString = str_replace(array("\r", "\n"), array('', ' '), substr($queryString, 0, 80));
                            try {
                                $db->setQuery($query)->execute();
                            } catch (ExecutionFailureException|PrepareStatementFailureException $e) {
                                $errorMessage = Text::sprintf('JLIB_INSTALLER_ERROR_SQL_ERROR', $e->getMessage());
                                // Log the error in the update log file
                                Log::add(Text::sprintf('JLIB_INSTALLER_UPDATE_LOG_QUERY', $file, $queryString), Log::INFO, 'Update');
                                Log::add($errorMessage, Log::INFO, 'Update');
                                Log::add(Text::_('JLIB_INSTALLER_SQL_END_NOT_COMPLETE'), Log::INFO, 'Update');
                                // Show the error message to the user
                                Log::add($errorMessage, Log::WARNING, 'jerror');
                                return false;
                            }
                            Log::add(Text::sprintf('JLIB_INSTALLER_UPDATE_LOG_QUERY', $file, $queryString), Log::INFO, 'Update');
                            $update_count++;
                        }
                    }
                }
                // Update the database
                $query = $db->getQuery(true)->delete('#__schemas')->where('extension_id = :extension_id')->bind(':extension_id', $eid, ParameterType::INTEGER);
                $db->setQuery($query);
                try {
                    $db->execute();
                    $schemaVersion = end($files);
                    $query->clear()->insert($db->quoteName('#__schemas'))->columns(array($db->quoteName('extension_id'), $db->quoteName('version_id')))->values(':extension_id, :version_id')->bind(':extension_id', $eid, ParameterType::INTEGER)->bind(':version_id', $schemaVersion);
                    $db->setQuery($query);
                    $db->execute();
                } catch (ExecutionFailureException $e) {
                    Log::add(Text::sprintf('JLIB_INSTALLER_ERROR_SQL_ERROR', $e->getMessage()), Log::WARNING, 'jerror');
                    return false;
                }
                Log::add(Text::_('JLIB_INSTALLER_SQL_END'), Log::INFO, 'Update');
            }
        }
    }
    return $update_count;
}