renderHeader(true);
$template->renderStatusMessage(_('Performing system checks'), '', 0);
/* assert compatible version of PHP, we accept 4.3.0+ / 5.0.4+ */
if (!function_exists('version_compare') || version_compare(phpversion(), '4.3.0', '<')
|| (version_compare(phpversion(), '5.0.0', '>=')
&& version_compare(phpversion(), '5.0.4', '<'))) {
$templateData['check'][] =
array('title' => _('PHP version >= 4.3.0 or >= 5.0.4'),
'error' => true,
'notice' => sprintf(
_("Error: Gallery 2 requires PHP version 4.3.0 or newer or 5.0.4 or " .
"newer. You have PHP version %s installed. Contact your webserver " .
"administrator to request an upgrade, available at the %sPHP " .
"website%s."), phpversion(), '', ''));
$failCount++;
} else {
$templateData['check'][] =
array('title' => _('PHP Version'), 'success' => true);
}
/* assert that __FILE__ works correctly */
$fileDirectiveWorks = SystemChecksStep::CheckFileDirective();
if (!$fileDirectiveWorks) {
$templateData['check'][] =
array('title' => _('FILE directive supported'),
'error' => true,
'notice' => _('Error: your PHP __FILE__ directive is not functioning ' .
'correctly. Please file a support request with your ' .
'webserver administrator or in the Gallery forums.'));
$failCount++;
} else {
$templateData['check'][] =
array('title' => _('FILE Directive'), 'success' => true);
}
/* Make sure that safe mode is not enabled */
if (GalleryUtilities::getPhpIniBool('safe_mode')) {
$templateData['check'][] =
array('title' => _('Safe mode disabled'),
'error' => true,
'notice' => _('Error: Your version of PHP is configured with safe mode ' .
'enabled. You must disable safe mode before Gallery will run.'));
$failCount++;
} else {
$templateData['check'][] =
array('title' => _('Safe Mode'), 'success' => true);
}
/* Make sure we have PCRE support */
if (!function_exists('preg_match') || !function_exists('preg_replace')) {
$templateData['check'][] =
array('title' => _('Regular expressions'),
'error' => true,
'notice' => sprintf(
_('Error: Your PHP is configured without support for %sPerl Compatible ' .
'Regular Expressions%s. You must enable these functions before ' .
'Gallery will run.'), '', ''));
$failCount++;
} /* skip showing 'success' for this one */
/* Warning when exec() is disabled */
if (in_array('exec', preg_split('/,\s*/', ini_get('disable_functions')))) {
$templateData['check'][] =
array('title' => _('exec() allowed'),
'warning' => true,
'notice' =>
_('Warning: The exec() function is disabled in your PHP by the disabled' .
'_functions parameter in php.ini. You won\'t be able to use modules ' .
'that require external binaries (e.g. ImageMagick, NetPBM or Ffmpeg). ' .
'This can only be set server-wide, so you will need to change it in the ' .
'global php.ini.'),
);
} else {
$templateData['check'][] =
array('title' => _('exec() allowed'), 'success' => true);
}
/* Warning when set_time_limit() is disabled */
if (in_array('set_time_limit', preg_split('/,\s*/', ini_get('disable_functions')))) {
$timeLimit = ini_get('max_execution_time');
$templateData['check'][] =
array('title' => _('set_time_limit() allowed'),
'warning' => true,
'notice' => sprintf(
_('Warning: The set_time_limit() function is disabled in your PHP by ' .
'the disabled_functions parameter in php.ini. Gallery can ' .
'function with this setting, but it will not operate reliably. ' .
'Any operation that takes longer than %d seconds will fail (and in ' .
'some cases just return a blank page) possibly leading to data ' .
'corruption.'), $timeLimit),
);
} else {
$templateData['check'][] =
array('title' => _('set_time_limit() allowed'), 'success' => true);
/* Set the time limit large enough for the remaining checks (slow systems) */
set_time_limit(180);
$setTimeLimitAvailable = true;
}
$template->renderStatusMessage(_('Performing system checks'), '', 0.02);
/* Make sure filesystem operations are allowed */
$missingFilesystemFunctions = array();
foreach (array('fopen', 'fclose', 'fread', 'fwrite', 'file', 'copy', 'rename', 'readfile',
'file_get_contents', 'copy', 'move_uploaded_file', 'file_exists', 'tempnam', 'glob',
'closedir', 'stat', 'unlink', 'rmdir', 'mkdir', 'getcwd', 'chdir', 'opendir',
'readdir', 'chmod') as $function) {
if (!function_exists($function)) {
$missingFilesystemFunctions[] = $function;
}
}
if (!empty($missingFilesystemFunctions)) {
$templateData['check'][] =
array('title' => _('Filesystem Operations'),
'error' => true,
'notice' => sprintf(
_('Error: Essential filesystem operations are disabled in your PHP by ' .
'the disabled_functions parameter in php.ini. You must allow ' .
'these functions before Gallery will run. These functions are ' .
'missing: %s.'),
implode(', ', $missingFilesystemFunctions)));
$failCount++;
} /* skip showing 'success' for this one */
/* Warning if memory_limit is set and is too low */
$memoryLimit = ini_get('memory_limit');
$title = sprintf('%s (%s)', _('Memory limit'),
($memoryLimit == '' ? _('no limit') : $memoryLimit . 'b'));
$minimumMemoryLimit = 16;
if ($memoryLimit != ''
&& ($this->_getBytes($memoryLimit) / (1024 * 1024)) < $minimumMemoryLimit) {
$templateData['check'][] =
array('title' => $title,
'warning' => true,
'notice' => sprintf(
_('Warning: Your PHP is configured to limit the memory to %sb (' .
'memory_limit parameter in php.ini). You should raise this limit ' .
'to at least %sMB for proper Gallery operation.'),
$memoryLimit, $minimumMemoryLimit),
);
$suggestedHtaccess[] = sprintf('php_value memory_limit %sM', $minimumMemoryLimit);
} else {
$templateData['check'][] =
array('title' => $title, 'success' => true);
}
/* Warning if file_uploads are not allowed */
if (! GalleryUtilities::getPhpIniBool('file_uploads')) {
$templateData['check'][] =
array('title' => _('File uploads allowed'),
'warning' => true,
'notice' =>
_('Warning: Your PHP is configured not to allow file uploads (file_' .
'uploads parameter in php.ini). You will need to enable this option ' .
'if you want to upload files to your Gallery with a web browser.'),
);
$suggestedHtaccess[] = 'php_flag file_uploads on';
} else {
$templateData['check'][] =
array('title' => _('File uploads allowed'), 'success' => true);
}
/* Warning if upload_max_filesize is less than 2M */
$title = sprintf('%s (%sb)', _('Maximum upload size'), ini_get('upload_max_filesize'));
$minimumUploadsize = 2;
$uploadSize = $this->_getBytes(ini_get('upload_max_filesize')) / (1024 * 1024);
if ($uploadSize < $minimumUploadsize) {
$templateData['check'][] =
array('title' => $title,
'warning' => true,
'notice' => sprintf(
_('Warning: Your PHP is configured to limit the size of file uploads to' .
' %sb (upload_max_filesize parameter in php.ini). You should ' .
'raise this limit to allow uploading bigger files.'),
ini_get('upload_max_filesize')),
);
$suggestedHtaccess[] = sprintf('php_value upload_max_filesize %sM', $minimumUploadsize);
} else {
$templateData['check'][] =
array('title' => $title, 'success' => true);
}
/* Warning if post_max_size is less than 2M */
$title = sprintf('%s (%sb)', _('Maximum POST size'), ini_get('post_max_size'));
$minimumPostsize = 2;
$postSize = $this->_getBytes(ini_get('post_max_size')) / (1024 * 1024);
if ($postSize < $minimumPostsize) {
$templateData['check'][] =
array('title' => $title,
'warning' => true,
'notice' => sprintf(
_('Warning: Your PHP is configured to limit the post data to a maximum ' .
'of %sb (post_max_size parameter in php.ini). You should raise' .
' this limit to allow uploading bigger files.'),
ini_get('post_max_size')),
);
$suggestedHtaccess[] = sprintf('php_value post_max_size %sM', $minimumPostsize);
} else {
$templateData['check'][] =
array('title' => $title, 'success' => true);
}
/* Check for gettext support */
$title = _('Translation support');
if (!function_exists('dgettext')) {
$templateData['check'][] =
array('title' => $title,
'warning' => true,
'notice' => sprintf(
_('Your webserver does not support localization. To enable support for ' .
'additional languages please instruct your system administrator to ' .
'reconfigure PHP with the %sgettext%s option enabled.'),
'', ''));
} else if (!function_exists('bind_textdomain_codeset')) {
$templateData['check'][] =
array('title' => $title,
'warning' => true,
'notice' => sprintf(
_('Your PHP is missing the function %sbind_textdomain_codeset%s. This ' .
'means Gallery may display extended characters for some languages ' .
'incorrectly.'),
'', ''));
} else if (!function_exists('dngettext')) {
$templateData['check'][] =
array('title' => $title,
'warning' => true,
'notice' => sprintf(
_('Your PHP is missing the function %sdngettext%s. This means Gallery ' .
'will be unable to translate plural forms.'),
'', ''));
} else {
$templateData['check'][] = array('title' => $title, 'success' => true);
}
/* $x=$x[0] <--(an object) can crash PHP with zend.ze1_compatibility_mode ON */
if (GalleryUtilities::getPhpIniBool('zend.ze1_compatibility_mode')) {
$templateData['check'][] =
array('title' => _('Zend compatibility mode'),
'warning' => true,
'notice' => sprintf(
_('Warning: Your PHP is configured with Zend ze1_compatibility_mode ' .
'which can cause PHP to crash. Click %shere%s to test your PHP. ' .
'If you see "SUCCESS" then your PHP is ok. If you get an ' .
'error or no response then you must turn off ze1_compatibility_mode ' .
'before proceeding.'),
sprintf('', generateUrl('index.php?step='
. $this->_stepNumber . '&zendtest=1')),
''),
);
} /* skip showing 'success' for this one */
/* Warning if putenv is disabled */
if (in_array('putenv', preg_split('/,\s*/', ini_get('disable_functions')))) {
$templateData['check'][] =
array('title' => _('putenv() allowed'),
'warning' => true,
'notice' =>
_('Warning: The putenv() function is disabled in your PHP by the ' .
'disabled_functions parameter in php.ini. Gallery can function with ' .
'this setting, but on some rare systems Gallery will be unable to run in ' .
'other languages than the system language and English.'),
);
} /* skip showing 'success' for this one */
/* Warning if output_buffering / handlers are enabled */
$outputBuffers = array();
foreach (array('output_buffering', 'zlib.output_compression') as $outputFunction) {
if (GalleryUtilities::getPhpIniBool($outputFunction) ||
(int) ini_get($outputFunction) > 0) {
$outputBuffers[] = $outputFunction;
}
}
foreach (array('output_handler', 'zlib.output_handler') as $outputHandler) {
if (($value = ini_get($outputHandler)) && !empty($value)) {
$outputBuffers[] = $outputHandler;
}
}
if (!empty($outputBuffers)) {
$templateData['check'][] =
array('title' => _('Output buffering disabled'),
'warning' => true,
'notice' => sprintf(
_('Warning: Output buffering is enabled in your PHP by the %s ' .
'parameter(s) in php.ini. Gallery can function with this setting - ' .
'downloading files is even faster - but Gallery might be unable to ' .
'serve large files (e.g. large videos) and run into the memory limit.' .
' Also, some features like the progress bars might not work correctly' .
' if output buffering is enabled unless ini_set() is allowed.'),
implode(', ', $outputBuffers)),
);
} /* skip showing 'success' for this one */
$template->renderStatusMessage(_('Performing system checks'), '', 0.06);
/* Check if the files and dirs in the storage dir are (still) writeable */
$title = _('Storage Directory Permissions');
if (!$fileDirectiveWorks || !empty($missingFilesystemFunctions)) {
$templateData['check'][] =
array('title' => $title,
'warning' => true,
'notice' => _('Test skipped due to other errors.'));
} else {
$storageFiles = SystemChecksStep::CheckStorageDirectory();
if (!empty($storageFiles)) {
$notice = sprintf(
_('Error: Some files and or directories in your storage directory are ' .
'not writeable by the webserver user. Run chown -R webserverUser ' .
'%s OR run chmod -R 777 %s.'),
$gallery->getConfig('data.gallery.base'),
$gallery->getConfig('data.gallery.base'));
$heading = sprintf(_('Inaccessible or missing files (%d)'), count($storageFiles));
$message = $this->renderFileList($storageFiles, 'storagefiles', $heading, $notice);
$templateData['check'][] = array(
'title' => $title,
'error' => true,
'notice' => $message);
$failCount++;
} else {
$templateData['check'][] = array('title' => $title, 'success' => true);
}
}
$template->renderStatusMessage(_('Performing system checks'), '', 0.07);
/* Check all files against MANIFEST */
$title = _('Gallery file integrity');
if (!$fileDirectiveWorks || !empty($missingFilesystemFunctions)) {
$templateData['check'][] =
array('title' => $title,
'warning' => true,
'notice' => _('Test skipped due to other errors.'));
} else {
$isSvnInstall = file_exists(dirname(__FILE__) . '/.svn');
$manifest = SystemChecksStep::CheckManifest($template, $setTimeLimitAvailable);
if (!isset($manifest)) {
$templateData['check'][] =
array('title' => $title,
'warning' => true,
'notice' => _('Manifest missing or inaccessible.'));
$_SESSION['fileintegrity'] = 'Manifest missing or inaccessible';
} else if (empty($manifest['missing']) && empty($manifest['modified'])
&& empty($manifest['shouldRemove'])) {
$templateData['check'][] = array('title' => $title, 'success' => true);
$_SESSION['fileintegrity'] = 'Ok';
} else {
global $currentStep; /* needed for ManifestSystemCheck.html */
$message = $notice = '';
if (!empty($manifest['missing'])) {
if ($isSvnInstall) {
$notice = _('Note: You\'re running Gallery from SVN, so recently ' .
'removed files may appear here. It might be safe to ignore these.');
}
$heading = sprintf(_('Missing files (%d)'), count($manifest['missing']));
$message .= $this->renderFileList($manifest['missing'], 'missing', $heading,
$notice);
}
if (!empty($manifest['missing']) && !empty($manifest['modified'])) {
$message .= '
';
}
if (!empty($manifest['modified'])) {
if ($isSvnInstall) {
$notice = _('Note: You\'re running Gallery from SVN, so some modified ' .
'files are to be expected. You can probably ignore these, but to be ' .
'safe you should make sure that you do \'svn update\' before ' .
'continuing.');
}
$heading = sprintf(_('Modified files (%d)'), count($manifest['modified']));
$message .= $this->renderFileList($manifest['modified'], 'modified', $heading,
$notice);
}
if ((!empty($manifest['modified']) || !empty($manifest['missing']))
&& !empty($manifest['shouldRemove'])) {
$message .= '
';
}
if (!empty($manifest['shouldRemove'])) {
$notice = sprintf(_('These files are no longer part of Gallery. They probably' .
' won\'t cause any problems but it is a good idea to remove them to keep ' .
'your install clean. Gallery can\'t remove these files for you, but you ' .
'can download and run %sthis script%s in your gallery2 directory to ' .
'delete them for you.'), sprintf('',
generateUrl('index.php?step=' . $currentStep->getStepNumber()
. '&downloadCleanupScript=1', false)), '');
$heading = sprintf(_('Old files (%d)'), count($manifest['shouldRemove']));
$message .= $this->renderFileList($manifest['shouldRemove'], 'shouldRemove',
$heading, $notice);
}
$templateData['check'][] =
array('title' => $title,
'warning' => true,
'notice' => $message);
$_SESSION['fileintegrity'] =
(empty($manifest['missing']) && empty($manifest['modified']))
? 'There are some old files' : 'There are missing/modified files!';
}
}
/* Check if the db user has (all?) required db privileges to finish the upgrader */
$title = _('Database permissions');
if (!$fileDirectiveWorks || !empty($missingFilesystemFunctions)) {
$templateData['check'][] =
array('title' => $title,
'warning' => true,
'notice' => _('Test skipped due to other errors.'));
} else {
list ($ret, $error) = $this->_testPrivileges();
if ($ret === false) {
$message = _('Error: The configured database user does not have the required '
. 'database privileges to perform the upgrade.') . '
'
. $error;
$templateData['check'][] =
array('title' => $title,
'error' => true,
'notice' => $message);
$failCount++;
} else {
$templateData['check'][] = array('title' => $title, 'success' => true);
}
}
$template->renderStatusMessage(_('Performing system checks'), '', 1);
$template->hideStatusBlock();
$templateData['suggestedHtaccess'] = join("\n", $suggestedHtaccess);
$templateData['bodyFile'] = 'SystemChecks.html';
$this->setComplete($failCount == 0);
$this->setInError($failCount > 0);
$template->renderBodyAndFooter($templateData);
return false;
}
function CheckFileDirective() {
if (strstr(__FILE__, 'upgrade/steps/SystemChecksStep.class') ||
strstr(__FILE__, '\\upgrade\\steps\\SystemChecksStep.class')) {
return true;
} else {
return false;
}
}
/* Check if the files / dirs in the storage directory are writeable */
function CheckStorageDirectory() {
global $gallery;
$storagePath = $gallery->getConfig('data.gallery.base');
$platform =& $gallery->getPlatform();
if (empty($storagePath)) {
return array(sprintf(_('The storage folder path is not defined in config.php (%s)'),
'data.gallery.base'));
} else if ($storagePath{strlen($storagePath)-1} != $platform->getDirectorySeparator()) {
$storagePath .= $platform->getDirectorySeparator();
}
/* An exhaustive test would take too long, test a few dirs / files */
foreach (array('', 'versions.dat', 'albums') as $path) {
$path = $storagePath . $path;
if (!$platform->file_exists($path) || !$platform->is_readable($path)
|| !$platform->is_writeable($path)) {
return array($path);
}
}
/* Check up to 400 other files */
$tested = 0;
$max = 400;
$storagePath = substr($storagePath, 0, strlen($storagePath)-1);
return SystemChecksStep::_checkStorageSubDirectory($storagePath, $tested, $max);
}
/**
* Check up to $max files / dirs in a directory tree if they are still read/writeable
*
* @param string $dirname directory
* @param int $tested number of already tested files / dirs
* @param int $max max files/dirs to check
* @return array a list of files with insufficient permissions
*/
function _checkStorageSubDirectory($dirname, &$tested, $max) {
global $gallery;
$platform =& $gallery->getPlatform();
$storageFiles = array();
if (!($fd = $platform->opendir($dirname))) {
$storageFiles[] = $dirname;
return $storageFiles;
}
while (($filename = $platform->readdir($fd)) !== false && $tested < $max) {
if (!strcmp($filename, '.') || !strcmp($filename, '..')) {
continue;
}
$tested++;
$path = $dirname . $platform->getDirectorySeparator() . $filename;
if (!$platform->is_link($path) &&
(!$platform->is_writeable($path) || !$platform->is_readable($path))) {
$storageFiles[] = $path;
}
if ($platform->is_dir($path) && $tested < $max) {
/* Threshold not yet reached, check subdirectory tree */
$storageFiles = array_merge($storageFiles,
SystemChecksStep::_checkStorageSubDirectory($path, $tested, $max));
}
}
$platform->closedir($fd);
return $storageFiles;
}
function CheckManifest(&$statusMonitor, $useSetTimeLimit) {
$base = realpath(dirname(__FILE__) . '/../..') . '/';
if ($useSetTimeLimit) {
set_time_limit(180);
}
$manifest = GalleryUtilities::readManifest();
if (empty($manifest)) {
return null;
}
if (isset($statusMonitor)) {
$statusMonitor->renderStatusMessage(_('Performing system checks'), '', 0.1);
}
if ($useSetTimeLimit) {
set_time_limit(180);
}
$missing = $modified = $shouldRemove = array();
$stepSize = max((int)(count($manifest) / 22), 1);
$i = 0;
foreach ($manifest as $file => $info) {
$i++;
if ($file == 'MANIFEST') {
continue;
}
$path = $base . $file;
if ($i % $stepSize == 0) {
if (isset($statusMonitor)) {
$statusMonitor->renderStatusMessage(_('Performing system checks'), '',
0.12 + $i / $stepSize * 0.04);
}
if ($useSetTimeLimit) {
set_time_limit(180);
}
}
if (!empty($info['removed'])) {
if (file_exists($path)) {
$shouldRemove[] = $file;
}
} else if (!file_exists($path)) {
$missing[] = $file;
} else {
/*
* Use size comparison instead of checksum for speed. We have
* two sizes, one calculated with unix eols, one with windows eols.
*/
$actualSize = filesize($path);
if ($actualSize != $info['size'] && $actualSize != $info['size_crlf']) {
/* This can be useful debug info */
if (false) {
printf("%s (expected: %s/%s, actual: %s)
", $file,
$info['size'], $info['size_crlf'], $actualSize);
}
$modified[] = $file;
}
}
}
return array('missing' => $missing, 'modified' => $modified,
'shouldRemove' => $shouldRemove);
}
/**
* Render a file-list in a minimizable block with a heading and an optional notice text.
* @param array $files
* @param string $blockId The HTML id for the block toggle mechanism
* @param string $heading Heading for the block
* @param string $notice (optional) A longer notice to be shown on top of the file list
*/
function renderFileList($files, $blockId, $heading, $notice=null) {
ob_start();
include(dirname(__FILE__) . '/../templates/SystemCheckFileList.html');
$html = ob_get_contents();
ob_end_clean();
return $html;
}
/**
* Check if the user has the most basic database privileges required to finish the upgrade
* steps successfully. Check:
* - CREATE TABLE, ALTER TABLE, DROP TABLE
* - CREATE INDEX, DROP INDEX
* - CREATE SEQUENCE, DROP SEQUENCE
*
* @return array (boolean success, string errors)
*/
function _testPrivileges() {
global $gallery;
$storage =& $gallery->getStorage();
$storageExtras = $storage->_getExtras();
/* We might have lost our database connection (timeout) so check and reconnect */
$ret = $storage->validateConnection();
if ($ret) {
$gallery->debug($ret->getAsHtml());
return array(false,
_('Database permission test failed. Could not connect to database.'));
}
$gallery->startRecordingDebugSnippet();
list ($ret, $metatables) = $storageExtras->_metaTables();
$snippet = $gallery->stopRecordingDebugSnippet();
if ($ret) {
$gallery->debug($ret->getAsHtml());
return array(false,
_('Database permission test failed. Could not acquire database information.')
. "\n" . $snippet);
}
/*
* Execute T_InstallerTest_1.sql through T_InstallerTest_4.sql. These create, alter and
* drop a table, and create and drop index. Because our .xml transforms (MySQL.xsl,...)
* always updates the Schema table for all table create, alter, drops, we use here a test
* table which also has the name and the structure of the Schema table, just with another
* tablePrefix.
*
* Set an unused tablePrefix such that we can play with create/drop table in an
* unused database "namespace". Try a few prefices, don't try to drop!
*/
$ok = false;
for ($i = 0; $i < 10; $i++) {
$tablePrefix = 'gtst' . $i;
if (!in_array(GalleryUtilities::strToLower($tablePrefix . 'Schema'), $metatables)) {
$ok = true;
break;
}
}
if (!$ok) {
return array(false,
sprintf(_('Could not find an unused table prefix similar to "%s".'),
$tablePrefix));
}
$moduleSql = $storageExtras->getModuleSql('core');
if (empty($moduleSql['test'])) {
return array(false,
_('Database permission test failed due to corrupted file integrity.'));
}
for ($i = 1; $i <= 4; $i++) {
list ($success, $error) =
$this->_executeSql($moduleSql['test']['InstallerTest'][$i], $tablePrefix);
if (!$success) {
return array(false,
_('Failed to create, alter or drop a database test table. ') . $error);
}
}
/* Check CREATE and DROP SEQUENCE privileges */
$gallery->startRecordingDebugSnippet();
$storage->_traceStart();
$sequenceId = 'g2privtestseq';
$ret = $storage->_db->CreateSequence($tablePrefix . $sequenceId);
$storage->_traceStop();
$snippet = $gallery->stopRecordingDebugSnippet();
if (!$ret) {
return array(false, _('Failed to create a database test sequence. ' .
'Check the returned error message and README.html ' .
'for missing privileges and clean up the database.')
. "\n" . $snippet);
}
$gallery->startRecordingDebugSnippet();
$storage->_traceStart();
$ret = $storage->_db->DropSequence($tablePrefix . $sequenceId);
$storage->_traceStop();
$snippet = $gallery->stopRecordingDebugSnippet();
if (!$ret) {
return array(false, _('Test failed to drop a database test sequence. ' .
'Check the returned error message and README.html ' .
'for missing privileges and clean up the database.')
. "\n" . $snippet);
}
return array(true, null);
}
/**
* Execute a series of SQL statements.
* @param string $buffer the SQL statements
* @param string $tablePrefix prefix for table names
* @return array(boolean success, string error message)
*/
function _executeSql($buffer, $tablePrefix) {
global $gallery;
$storage =& $gallery->getStorage();
if (empty($buffer)) {
return array(false, _('Missing SQL statements'));
}
/*
* Split the file where semicolons are followed by a blank line..
* PL/SQL blocks will have other semicolons, so we can't split on every one.
* But first, remove that last semicolon such that all statements have no semicolon
* (required for oracle)
*/
if ($pos = strrpos($buffer, ';')) {
$buffer = substr($buffer, 0, $pos);
}
$statements = preg_split('/; *\r?\n *\r?\n/s', $buffer);
$storageConfig = $gallery->getConfig('storage.config');
$columnPrefix = $storageConfig['columnPrefix'];
foreach ($statements as $query) {
$query = trim($query);
if (!empty($query)) {
$query = str_replace('DB_TABLE_PREFIX', $tablePrefix, $query);
$query = str_replace('DB_COLUMN_PREFIX', $columnPrefix, $query);
/* For mysql, another replacement is required */
$query = str_replace('DB_TABLE_TYPE', '', $query);
$gallery->startRecordingDebugSnippet();
$ret = $storage->execute($query, array());
$snippet = $gallery->stopRecordingDebugSnippet();
if ($ret) {
return array(false, _('Check the returned error message and README.html ' .
'for missing privileges and clean up the database.')
. "\n" . $snippet);
}
}
}
return array(true, null);
}
}
?>