diff --git includes/plugin.inc includes/plugin.inc
index 6958285..5d64168 100644
--- includes/plugin.inc
+++ includes/plugin.inc
@@ -24,7 +24,7 @@ function plugin_filetransfer_form($form_state) {
$available_backends = module_invoke_all('filetransfer_backends');
if (!count($available_backends)) {
// @TODO: Clean up this error handling
- drupal_set_message(t('Unable to continue, not available methods of file transfer'), 'error');
+ drupal_set_message(t('Unable to continue, no available methods of file transfer'), 'error');
return array();
}
@@ -189,7 +189,7 @@ function plugin_filetransfer_form_submit($form, &$form_state) {
_plugin_manager_create_and_setup_directories($ft, 0777);
// Now run the batch.
- plugin_manager_run_batch();
+ plugin_manager_run_batch($ft);
}
break;
@@ -263,14 +263,18 @@ function get_plugin_report($messages) {
return $output;
}
-function plugin_manager_run_batch() {
+function plugin_manager_run_batch($filetransfer) {
+ global $base_url;
drupal_set_title('Installing updates');
$batch = $_SESSION['plugin_op'];
- dpr($batch);
- update_batch_copy_project('mopa', 'temporary://update-cache/mopa-7.x-1.x-dev.tar.gz');
- die();
+ foreach ($batch['operations'] as $key => $args) {
+ // Add the filetransfer class
+ $function = $args[0];
+ if ($function == 'update_batch_copy_project') {
+ $batch['operations'][$key][1][] = $filetransfer;
+ }
+ }
- //unset($_SESSION['plugin_op']);
batch_set($batch);
- batch_process(url($base_url . '/plugin.php', array('absolute' => TRUE)));
-}
\ No newline at end of file
+ batch_process(url($base_url . '/plugin.php', array('absolute' => TRUE)), url($base_url . '/plugin.php', array('absolute' => TRUE, 'query' => array('batch' => 1))));
+}
diff --git install.php install.php
index 3147ef4..c727d7c 100644
--- install.php
+++ install.php
@@ -278,7 +278,7 @@ function install_begin_request(&$install_state) {
// Since we have a database connection, we use the normal cache system.
// This is important, as the installer calls into the Drupal system for
// the clean URL checks, so we should maintain the cache properly.
- unset($conf['cache_default_class']);
+ //unset($conf['cache_default_class']);
// Initialize the database system. Note that the connection
// won't be initialized until it is actually requested.
diff --git modules/update/update.admin.inc modules/update/update.admin.inc
index 6c1a1e6..83d26ec 100644
--- modules/update/update.admin.inc
+++ modules/update/update.admin.inc
@@ -11,9 +11,9 @@ require_once 'updaters.inc';
/**
* Menu callback; main updates form.
*/
-function update_update_form($form_state = array()) {
+function update_update_form($form, $form_state = array()) {
$form = array();
-
+
if (!isset($form_state['values'])) {
// This is the first page of the update process.
$form = _update_update_form_update_table();
@@ -166,7 +166,6 @@ function _update_update_form_display_steps() {
return $form;
}
-
/**
* Submit function for the main update form.
*
@@ -192,6 +191,7 @@ function update_update_form_submit($form, &$form_state) {
$url,
),
);
+
$operations[] = array('update_batch_update_project', array($project));
}
@@ -204,12 +204,18 @@ function update_update_form_submit($form, &$form_state) {
);
$_SESSION['plugin_op'] = $batch;
+
+ if ($form_state['values']['site_offline'] == TRUE) {
+ // Put site in offline mode.
+ variable_set('site_offline', TRUE);
+ }
drupal_goto(url($base_url . '/plugin.php', array('absolute' => TRUE)));
return;
break;
default:
+ $form_state['rebuild'] = TRUE;
// This is the first page, and store the list of selected projects
$form_state['storage']['projects'] = array_keys(array_filter($form_state['values']['projects']));
break;
@@ -283,16 +289,23 @@ function update_install_form_submit($form, &$form_state) {
return;
}
- // @TODO: This should use the project.info file stuff probably
- // This is not reliable (the directory name)
- $project = drupal_substr($files[0]['filename'], 0, -1); // Remove the trailing slash.
+ $project = drupal_substr($files[0]['filename'],0,-1); // Unfortunately, we can only use the directory name for this. :(
+
+ $project_location = DRUPAL_ROOT . '/' . file_directory_path('temporary') . '/update-extraction/' . $project;
+ update_untar(drupal_realpath($local_cache));
- // I am already installed
- if (_update_get_project_location($project)) {
- form_set_error($field, t('%project is already installed', array('%project' => $project)));
+ $updater = Updater::factory($project_location);
+ $project_title = Updater::getProjectTitle($project_location);
+
+ if (!$project) {
+ form_set_error($field, t('Unable to determine %project name', array('%project' => $project_title)));
+ }
+
+ if ($updater->isInstalled()) {
+ form_set_error($field, t('%project is already installed', array('%project' => $project_title)));
return;
}
-
+
$operations = array();
$operations[] = array(
'update_batch_copy_project',
@@ -302,37 +315,8 @@ function update_install_form_submit($form, &$form_state) {
),
);
- // We expand the archive now, so we can figure out what is in it.
- $project_location = DRUPAL_ROOT . '/' . file_directory_path('temporary') . '/update-extraction/' . $project;
- update_untar(drupal_realpath($local_cache));
-
- /**
- * Determines the modules which should be enabled by default
- * If there is a project.info file, use that, else use $project.info
- * (i.e. views.info)
- */
- $project_info = NULL;
-
- $type = NULL;
-
- $info_file = _update_find_info_file($project_location);
- $project_info = drupal_parse_info_file($info_file);
-
- switch (_update_get_project_type_by_directory($project_location)) {
- case 'module':
- if (!isset($project_info['default_modules']) && basename($info_file) == "{$project}.info") {
- $project_info['default_modules'] = array($project);
- }
- $operations[] = array('update_batch_enable_modules', array($project_info['default_modules']));
- break;
-
- case 'theme':
- $operations[] = array('update_batch_enable_themes', array(array($project)));
- break;
- }
-
$batch = array(
- 'title' => t('Installing %project', array('%project' => $project_info['name'])),
+ 'title' => t('Installing %project', array('%project' => $project_title)),
'init_message' => t('Preparing update operation'),
'operations' => $operations,
'finished' => 'update_batch_finished',
@@ -358,8 +342,11 @@ function update_install_form_submit($form, &$form_state) {
* @return void;
*/
function update_batch_get_project($project, &$context) {
- if (!isset($context['results'][$project])) {
- $context['results'][$project] = array();
+ if (!isset($context['results']['log'])) {
+ $context['results']['log'] = array();
+ }
+ if (!isset($context['results']['log'][$project])) {
+ $context['results']['log'][$project] = array();
}
if (!isset($context['sandbox']['started'])) {
$context['sandbox']['started'] = TRUE;
@@ -387,16 +374,34 @@ function update_batch_get_project($project, &$context) {
* @todo Fix the $project param (refactor)
* @param string $project Either name of the project being installed or a
* @param string $url Location of a tarball to install if recommended version of $project not required
+ * @param string $filetransfer FileTransfer class
* @param array &$context BatchAPI storage
*
* @return void
*/
-function update_batch_copy_project($project, $url, &$context) {
-dd('as');
- if (!isset($context['results'][$project])) {
- $context['results'][$project] = array();
+function update_batch_copy_project($project, $url, $filetransfer, &$context) {
+
+ // Initialize some variables
+ if (!isset($context['results']['log'])) {
+ $context['results']['log'] = array();
+ }
+
+ if (!$context['results']['tasks']) {
+ $context['results']['tasks'] = array();
+ }
+
+ /**
+ * Unfortuantely, because the batch API uses a session and a connection
+ * pointer will be lost between requests, when doing an update of multiple
+ * modules, we need to unset the connection pointer to re-init a connect.
+ */
+ unset($filetransfer->connection);
+
+ if (!isset($context['results']['log'][$project])) {
+ $context['results']['log'][$project] = array();
}
- if (!empty($context['results'][$project]['#abort'])) {
+
+ if (!empty($context['results']['log'][$project]['#abort'])) {
$context['#finished'] = 1;
return;
}
@@ -406,60 +411,34 @@ dd('as');
// This extracts the file into the standard place.
try {
update_untar($local_cache);
- } catch (Exception $e) {
- _update_batch_create_message($context['results'][$project], $e->getMessage(), FALSE);
- $context['results'][$project]['#abort'] = TRUE;
+ }
+ catch (Exception $e) {
+ _update_batch_create_message($context['results']['log'][$project], $e->getMessage(), FALSE);
+ $context['results']['log'][$project]['#abort'] = TRUE;
return;
}
-
+
$project_source_dir = DRUPAL_ROOT . '/' . file_directory_path('temporary') . '/update-extraction/' . $project;
- dd("as");
$updater = Updater::factory($project_source_dir);
- dpr($updater);
- die();
- // Now check the dependencies.
- $info_file = _update_find_info_file($project_source_dir);
- $dependencies = _update_check_dependencies($info_file);
- //@TODO: Not yet implemented
-
- if ($location = _update_get_project_location($project)) {
- // This is an update
- $is_install = FALSE;
- }
- else {
- //This is a fresh install, not an update
- $type = _update_get_project_type_by_directory($project_source_dir);
- if (!$type) {
- _update_batch_create_message($context['results'][$project], t("Unable to determine project type for %name", array("%name" => $project)), FALSE);
- $context['results'][$project]['#abort'] = TRUE;
- return;
- }
-
- $default_locations = array(
- 'module' => conf_path() . '/modules',
- 'theme' => conf_path() . '/themes',
- 'theme_engine' => conf_path() . '/themes/engines'
- );
-
- $location = variable_get("update_default_{$type}_location", $default_locations[$type]) . '/' . $project;
- $is_install = TRUE;
- }
- $project_destination_dir = DRUPAL_ROOT . '/' . $location;
-
try {
-
- if (!$is_install) {
- _update_remove_directory($project_destination_dir);
+ if ($updater->isInstalled()) {
+ // This is an update.
+ $tasks = $updater->update($filetransfer);
+ }
+ else {
+ $tasks = $updater->install($filetransfer);
}
- _update_copy_directory($project_source_dir, $project_destination_dir);
}
- catch (Exception $e) {
- _update_batch_create_message($context['results'][$project], t("Error installing / updating)"), FALSE);
- $context['results'][$project]['#abort'] = TRUE;
+ catch (UpdaterError $e) {
+ _update_batch_create_message($context['results']['log'][$project], t("Error installing / updating)"), FALSE);
+ $context['results']['log'][$project]['#abort'] = TRUE;
return;
}
- _update_batch_create_message($context['results'][$project], t('Installed %project_name successfully', array('%project_name' => $project)));
+
+ _update_batch_create_message($context['results']['log'][$project], t('Installed %project_name successfully', array('%project_name' => $project)));
+ $context['results']['tasks'] += $tasks;
+
$context['finished'] = 1;
}
@@ -467,7 +446,8 @@ dd('as');
* Set the batch to run the update functions.
*/
function update_batch_update_project($project, &$context) {
- if (!empty($context['results'][$project]['#abort'])) {
+
+ if (!empty($context['results']['log'][$project]['#abort'])) {
$context['#finished'] = 1;
return;
}
@@ -488,13 +468,14 @@ function update_batch_update_project($project, &$context) {
* Batch callback for when the batch is finished.
*/
function update_batch_finished($success, $results) {
- foreach ($results as $module => $messages) {
+ foreach ($results['log'] as $module => $messages) {
if (!empty($messages['#abort'])) {
$success = FALSE;
}
}
$_SESSION['update_batch_results']['success'] = $success;
- $_SESSION['update_batch_results']['messages'] = $results;
+ $_SESSION['update_batch_results']['messages'] = $results['log'];
+ $_SESSION['update_batch_results']['tasks'] = $results['tasks'];
}
/**
@@ -562,89 +543,6 @@ function update_get_filetransfer($method, $overrides = array()) {
return $filetransfer;
}
-
-/**
- * Helper function, returns a an associative array of a project's type and
- * location returns false on failure.
- */
-function _update_get_project_type_and_location($name) {
- foreach (array('module', 'theme') as $type) {
- if ($dir = drupal_get_path($type, $name)) {
- return array('type' => $type, 'location' => $dir);
- }
- }
- return FALSE;
-}
-
-function _update_get_project_type($name) {
- $project_info = _update_get_project_type_and_location($name);
- return $project_info['type'];
-}
-
-function _update_get_project_location($name) {
- $project_info = _update_get_project_type_and_location($name);
- return $project_info['location'];
-}
-
-/**
- * Get's the latest release of a project
- *
- * @param string $project Name of the project
- * @return array An array of information about the latest recommended
- * release of the project
- */
-function _update_get_latest_version($project) {
- if ($available = update_get_available(FALSE)) {
- module_load_include('inc', 'update', 'update.compare');
- $projects_data = update_calculate_project_data($available);
- $project_data = $projects_data[$project];
- return $project_data['releases'][$project_data['latest_version']];
- }
-}
-
-/**
- * Returns the available updates for a given module in an array
- *
- * @param $project
- * The name of the module.
- */
-function _update_get_schema_updates($project) {
- require_once './includes/install.inc';
- require_once './includes/update.inc';
-
- if (_update_get_project_type($project) != 'module') {
- return array();
- }
- module_load_include('install', $project);
-
- if (!$updates = drupal_get_schema_versions($project)) {
- return array();
- }
- $updates_to_run = array();
- $modules_with_updates = update_get_update_list();
- if ($updates = $modules_with_updates[$project]) {
- if ($updates['start']) {
- return $updates['pending'];
- }
- }
- return array();
-}
-
-/**
- * Helper function, given an info file, will determine what type of project it is
- *
- * @param string $project_directory path to project
- *
- * @return string project type, could be theme or module.
- */
-function _update_get_project_type_by_directory($project_directory) {
- if (file_scan_directory($project_directory, '/.*\.module/')) {
- return 'module';
- }
- return 'theme';
-}
-
-
/**
* Get a file from the server, or if it was already downloaded, get the local
* path to the file.
@@ -694,145 +592,19 @@ function _update_get_recommended_version($name) {
return $project['releases'][$project['recommended']];
}
}
-
-/**
- * Can read an info file and check if it has any unmet dependencies.
- *
- * @param string $info_file Pathname of info file to check.
- */
-function _update_check_dependencies($info_file) {
- $files = system_get_module_data();
-
- // Remove hidden modules from display list.
- foreach ($files as $filename => $file) {
- if (!empty($file->info['hidden']) || !empty($file->info['required'])) {
- unset($files[$filename]);
- }
- }
-
- $info = drupal_parse_info_file(($info_file));
-
- $errors = array();
- if (!is_array($info['dependencies'])) {
- return array();
- }
- foreach ($info['dependencies'] as $module) {
- if (!isset($files[$module])) {
- $errors[$module] = t('@module (missing)', array('@module' => drupal_ucfirst($module)));
- }
- }
- return $errors;
-}
-
-
-/**
- * Recursively coppies a directory.
- *
- * @todo: Should use RecursiveDirectoryIterator.
- *
- * @param string $src
- * @param string $dest
- * @param array $exclude_patterns
- */
-function _update_copy_directory($src, $dest) {
- if (!file_exists($dest)) {
- mkdir($dest);
- }
- foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($src), RecursiveIteratorIterator::SELF_FIRST) as $filename => $file) {
- $relative_path = drupal_substr($filename, drupal_strlen($src));
- if ($file->isDir()) {
- mkdir($dest . '/' . $relative_path);
- }
- else {
- copy($filename, $dest . '/' . $relative_path);
- }
- }
-}
-
-/**
- * Duh. rm -Rf
- *
- * @param string $src The directory you want to zap.
- * @param string $jail An optional jail to make sure you don't wipe /.
- */
-function _update_remove_directory($src, $jail = DRUPAL_ROOT) {
- foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($src), RecursiveIteratorIterator::CHILD_FIRST) as $filename => $file) {
- if (strpos($filename, $jail) != 0) {
- throw new Exception("Tried to delete $filename, but it is outside of the jail: $jail");
- }
- if ($file->isDir()) {
- rmdir($file->getPathName());
- }
- else {
- unlink($file->getPathName());
- }
- }
- rmdir($src);
-}
-
-/**
- *
- * Enable an array of themes
- *
- * @TODO: This is not implemented yet. Just a stub
- * @param $project
- * @return
- */
-function update_batch_enable_themes($themes, &$context) {
- // @todo: Enable the theme. Would be ideal to prompt post install
- // if it should be default as well.
-}
-
-/**
- * Enable an array of modules
- * @param $modules
- */
-function update_batch_enable_modules($modules, &$context) {
- foreach ($modules as $module) {
- module_enable(array($module));
-
- _update_batch_create_message($context['results'][$project], t("%project has been enabled", array('%project' => $module)));
- }
-}
-
-/**
- * Looks through a directory, preference is for info file with same name as directory
- *
- * @param string $directory
- *
- * return string $path
- */
-function _update_find_info_file($directory) {
-
- if ($project_info_files = file_scan_directory($directory, '/\.project\.info/')) {
- return $project_info_files[0];
- }
-
- $info_files = file_scan_directory($directory, '/.*\.info/');
- if (!$info_files) {
- return FALSE;
- }
- foreach ($info_files as $info_file) {
- if (drupal_substr($info_file->filename, 0, -5) == basename($directory)) {
- // Has the same name as the directory, is prefered.
- return $info_file->uri;
- }
- }
- // Return the first one.
- $info_file = array_shift($info_files);
- return $info_file->uri;
-}
-
/**
* Returns a list of classes which implement the DrupalUpdater interface
*
* @return array
*/
function update_get_updaters() {
- $updaters = array();
- foreach(get_declared_classes() as $class) {
- if (in_array('DrupalUpdater', class_implements($class))) {
- $updaters[] = $class;
+ $updaters = drupal_static(__FUNCTION__);
+ if (!$updaters) {
+ $updaters = array();
+ foreach(get_declared_classes() as $class) {
+ if (in_array('DrupalProjectUpdater', class_implements($class))) {
+ $updaters[] = $class;
+ }
}
}
return $updaters;
diff --git modules/update/update.info modules/update/update.info
index 4f9c109..deb6094 100644
--- modules/update/update.info
+++ modules/update/update.info
@@ -6,16 +6,11 @@ package = Core
core = 7.x
files[] = update.compare.inc
files[] = update.fetch.inc
-<<<<<<< HEAD
files[] = update.admin.inc
-files[] = update.report.inc
-files[] = update.settings.inc
-files[] = update.install
+files[] = updaters.inc
files[] = update.js
-=======
files[] = update.install
files[] = update.module
files[] = update.report.inc
files[] = update.settings.inc
files[] = update.test
->>>>>>> 57fb4ed7ca80f437afaacb7ee287d8425a7e8c96
diff --git modules/update/updaters.inc modules/update/updaters.inc
index c525b67..1c7c5e7 100644
--- modules/update/updaters.inc
+++ modules/update/updaters.inc
@@ -1,84 +1,392 @@
source = $source;
+ $this->name = self::getProjectName($source);
+ $this->title = self::getProjectTitle($source);
+ }
+
+ /**
+ * Returns an Updater of the approiate type depending on the source provided.
+ *
+ * @param string $source Directory of a Drupal project
+ * @return object Child of Updater
+ */
static function factory($source) {
if (is_dir($source)) {
- $type = getProjectTypeFromDirectory($source);
- } else {
- throw new Exception('Unable to determine the type of the source directory');
+ $updater = self::getUpdaterFromDirectory($source);
+ }
+ else {
+ throw new UpdaterError('Unable to determine the type of the source directory');
}
- $classname = ucfirst($type) . 'Updater';
- if (class_exists($classname)) {
- return new $classname($source);
+ return new $updater($source);
+ }
+
+ /**
+ * Determines the project type (and assocaited updater class)
+ * from the available Updater child classes.
+ *
+ * @param string $directory Extracted Drupal project.
+ * @return string The class name which can work with this project type.
+ */
+ static function getUpdaterFromDirectory($directory) {
+ // Gets a list of possible implementing classes
+ $updaters = update_get_updaters();
+ foreach ($updaters as $updater) {
+ if (call_user_func("{$updater}::canUpdateDirectory", $directory)) {
+ return $updater;
+ }
}
+ throw new UpdaterError("Cannot determine the type of project");
}
- static function getProjectTypeFromDirectory($directory) {
+ /**
+ * Since there is no enforcement of which info file is the project's info file
+ * This will get one with the same name as the directory, or the first one it
+ * finds. Sucks, yes. But needs a larger solution.
+ *
+ * @param string $directory
+ * Directory to search in
+ * @return string
+ * Path to the info file
+ */
+ public static function findInfoFile($directory) {
+ $info_files = file_scan_directory($directory, '/.*\.info/');
+ if (!$info_files) {
+ return FALSE;
+ }
+ foreach ($info_files as $info_file) {
+ if (drupal_substr($info_file->filename, 0, -5) == basename($directory)) {
+ // Has the same name as the directory, is prefered.
+ return $info_file->uri;
+ }
+ }
+ // Return the first one.
+ $info_file = array_shift($info_files);
+ return $info_file->uri;
+ }
+ /**
+ * Gets the name of the project directory (basename).
+ *
+ * @param string $directory
+ * @return string
+ */
+ public static function getProjectName($directory) {
+ return basename($directory);
}
- static function getProjectTypeFromArchive($archive) {
+ /**
+ * From the info file of a project, gets the project name
+ *
+ * @param string $directory
+ * Directory to search for the info file.
+ * @return string
+ */
+ public static function getProjectTitle($directory) {
+ $info_file = self::findInfoFile($directory);
+ $info = drupal_parse_info_file($info_file);
+ if (!$info) {
+ //@TODO: Add the variables, t(), etc
+ throw new UpdaterError("Unable to parse info file");
+ }
+ return $info['name'];
}
-
- public function downloadProject() {
-
+
+ /**
+ * Stores default parameters for the Updater.
+ *
+ * @param array $overrides
+ * An array of overrides.
+ * @return array
+ * An array of configuration parameters for an update or install operation
+ */
+ private function getInstallArgs($overrides = array()) {
+ $args = array(
+ 'make_backup' => FALSE,
+ 'install_dir' => $this->getInstallDirectory(),
+ 'backup_dir' => $this->getBackupDir(),
+ );
+ return array_merge($args, $overrides);
}
- public function copyProject() {
+ /**
+ * Updates a Drupal project, returns a list of next actions
+ *
+ * @param FileTransfer $ft
+ * Object which is a child of FileTransfer
+ * @param array $overrides
+ * An array of settings to override defaults
+ * @see self::getInstallArgs
+ * @return array
+ * An array of links which the user may need to complete the update
+ */
+ public function update(&$ft, $overrides = array()) {
+ try {
+ // Establish arguments with possible overrides.
+ $args = $this->getInstallArgs($overrides);
+
+ // Take a Backup.
+ if ($args['make_backup']) {
+ $this->makeBackup($args['install_dir'], $args['backup_dir']);
+ }
+
+ if (!$this->name) {
+ //This is bad, don't want delte the install dir.
+ throw new UpdaterError("Fatal error in update, cowardly refusing to wipe out the install directory");
+ }
+ // Remove the existing installed file.
+ $ft->removeDirectory($args['install_dir'] . '/' . $this->name);
+ // Copy the directory in place.
+ $ft->copyDirectory($this->source, $args['install_dir']);
+ // Run the updates
+ // @TODO: decide if we want to implement this.
+ $this->postUpdate();
+ // For now, just return a list of links of things to do.
+ return $this->postUpdateTasks();
+ } catch (FileTransferException $e) {
+ throw new UpdaterError(t("File Transfer failed, reason: !reason", array ('!reason' => t($e->getMessage(), $this->arguments))));
+ }
}
-}
+ /**
+ * Installs a Drupal project, returns a list of next actions
+ *
+ * @param FileTransfer $ft
+ * Object which is a child of FileTransfer
+ * @param array $overrides
+ * An array of settings to override defaults
+ * @see self::getInstallArgs
+ * @return array
+ * An array of links which the user may need to complete the install
+ */
+ public function install(&$ft, $overrides = array()) {
+ try {
+ // Establish arguments with possible overrides.
+ $args = $this->getInstallArgs($overrides);
+ // Copy the directory in place.
+ $ft->copyDirectory($this->source, $args['install_dir']);
+ // Potentially enable something?
+ // @TODO: decide if we want to implement this.
+ $this->postInstall();
+ // For now, just return a list of links of things to do.
+ return $this->postInstallTasks();
+ }
+ catch (FileTransferException $e) {
+ throw new UpdateError(t("File Transfer failed, reason: !reason", array ('!reason' => t($e->getMessage(), $this->arguments))));
+ }
+ }
-class ModuleUpdater extends Updater implements DrupalUpdater{
+ function makeBackup(&$ft, $from, $to) {
+ //@TODO: Not implemented
+ }
- public $installDirectory;
+ function getBackupDir() {
+ return file_directory_path('temporary');
+ }
+
+ /**
+ * Needs to be overridden by children to work
+ * Actions to take after the update is complete.
+ */
+ function postUpdate() {
+
+ }
+
+ /**
+ * Needs to be overridden by children to work
+ * Actions to take after the install is complete.
+ */
+ function postInstall() {
+
+ }
+
+ /**
+ *
+ * @return array Links which provide actions to take after the install is finished.
+ */
+ function postInstallTasks() {
+ return array();
+ }
+
+ /**
+ *
+ * @return array Links which provide actions to take after the update is finished.
+ */
+ function postUpdateTasks() {
+ return array();
+ }
+}
+
+class ModuleUpdater extends Updater implements DrupalProjectUpdater{
static function getInstallDirectory() {
return DRUPAL_ROOT . '/' . conf_path() . '/modules';
}
- function isAlreadyInstalled() {
-
+ function isInstalled() {
+ return (bool) drupal_get_path('module', $this->name);
}
function installProject() {
}
+
+ static function canUpdateDirectory($directory) {
+ if (file_scan_directory($directory, '/.*\.module/')) {
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ function getSchemeUpdates() {
+ require_once './includes/install.inc';
+ require_once './includes/update.inc';
+
+ if (_update_get_project_type($project) != 'module') {
+ return array();
+ }
+ module_load_include('install', $project);
+
+ if (!$updates = drupal_get_schema_versions($project)) {
+ return array();
+ }
+ $updates_to_run = array();
+ $modules_with_updates = update_get_update_list();
+ if ($updates = $modules_with_updates[$project]) {
+ if ($updates['start']) {
+ return $updates['pending'];
+ }
+ }
+ return array();
+ }
+
+ /**
+ * @return array Links which provide actions to take after the install is finished.
+ */
+ function postInstallTasks() {
+
+ return array (
+ l(t('Enable newly added modules in !project', array('!project' => $this->title)), 'admin/config/modules'),
+ );
+ }
+
}
-class ThemeUpdater extends Updater implements DrupalUpdater{
+class ThemeUpdater extends Updater implements DrupalProjectUpdater{
public $installDirectory;
static function getInstallDirectory() {
return DRUPAL_ROOT . '/' . conf_path() . '/themes';
}
- function isAlreadyInstalled() {
-
+ function isInstalled() {
+ return (bool) drupal_get_path('theme', $this->name);
}
function installProject() {
}
+
+ static function canUpdateDirectory($directory) {
+ // This is a shitty test, but don't know how else to confirm
+ if (file_scan_directory($directory, '/.*\.module/')) {
+ return FALSE;
+ }
+ return TRUE;
+ }
+
+ function postInstall() {
+ // Update the system table.
+ system_get_theme_data();
+
+ // Active the theme
+ db_update('system')
+ ->fields(array('status' => 1))
+ ->condition('type', 'theme')
+ ->condition('name', $this->name)
+ ->execute();
+ }
+
+ function postInstallTasks() {
+ return array (
+ l(t('Set the !project theme as default', array('!project' => $this->title)), 'admin/appearance'),
+ );
+ }
+
+ function postUpdateTasks() {
+ // If there are schema updates
+ return array (
+ l(t('Run database updates for !project', array('!project' => $this->title)), 'update.php'),
+ );
+ }
}
+/**
+ * @TODO: implement this.
+ */
class ProfileUpdater extends Updater {
function installProject() {
}
}
+
+class UpdaterError extends Exception {
+
+}
?>
diff --git plugin.php plugin.php
index d294d1b..e93b427 100644
--- plugin.php
+++ plugin.php
@@ -74,7 +74,7 @@ if (realpath($_SERVER['SCRIPT_FILENAME']) == __FILE__) {
// This sets the permissions to non-writable for everyone.
_plugin_manager_create_and_setup_directories($ft, 0755);
}
-
+
//Clear the session out;
unset($_SESSION['update_batch_results']);
@@ -94,25 +94,36 @@ if (realpath($_SERVER['SCRIPT_FILENAME']) == __FILE__) {
$output .= get_plugin_report($results['messages']);
drupal_set_title('Update complete');
+ $links = array();
+ if (is_array($results['tasks'])) {
+ $links += $results['tasks'];
+ }
+
- $links = array(
+ $links = array_merge($links, array(
l('Administration pages', 'admin'),
l('Front page', ''),
- );
+ ));
+
$output .= theme('item_list', $links);
print theme('update_page', $output);
return;
}
-
- if (empty($_SESSION['plugin_op'])) {
- $output = t("It appears you have reached this page in error.");
- print theme('update_page', $output);
- return;
- }
- else {
- // We have a batch to process, show the filetransfer form.
- $output = drupal_render(drupal_get_form('plugin_filetransfer_form'));
+
+ if (isset($_GET['batch'])) {
+ $output = _batch_page();
+ } else {
+
+ if (empty($_SESSION['plugin_op'])) {
+ $output = t("It appears you have reached this page in error.");
+ print theme('update_page', $output);
+ return;
+ }
+ elseif (!$batch = batch_get()) {
+ // We have a batch to process, show the filetransfer form.
+ $output = drupal_render(drupal_get_form('plugin_filetransfer_form'));
+ }
}
if (!empty($output)) {