/**
* 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;
}