/[drupal]/drupal/modules/update/update.authorize.inc
ViewVC logotype

Contents of /drupal/modules/update/update.authorize.inc

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.3 - (show annotations) (download) (as text)
Sun Nov 1 23:02:13 2009 UTC (3 weeks, 4 days ago) by webchick
Branch: MAIN
CVS Tags: DRUPAL-7-0-UNSTABLE-10, HEAD
Changes since 1.2: +3 -8 lines
File MIME type: text/x-php
#607008 by dww, Gerhard Killesreiter, JacobSingh, and chx: Changed Fix bugs in https support and use  https for authorize.php if available.
1 <?php
2 // $Id: update.authorize.inc,v 1.2 2009/10/22 00:52:03 dries Exp $
3
4 /**
5 * @file
6 * Callbacks and related functions invoked by authorize.php to update projects
7 * on the Drupal site. We use the Batch API to actually update each individual
8 * project on the site. All of the code in this file is run at a low bootstrap
9 * level (modules are not loaded), so these functions cannot assume access to
10 * the rest of the update module code.
11 */
12
13 /**
14 * Callback invoked by authorize.php to update existing projects.
15 *
16 * @param $filetransfer
17 * The FileTransfer object created by authorize.php for use during this
18 * operation.
19 * @param $projects
20 * A nested array of projects to install into the live webroot, keyed by
21 * project name. Each subarray contains the following keys:
22 * - 'project': The canonical project short name.
23 * - 'updater_name': The name of the Updater class to use for this project.
24 * - 'local_url': The locally installed location of new code to update with.
25 */
26 function update_authorize_run_update($filetransfer, $projects) {
27 $operations = array();
28 foreach ($projects as $project => $project_info) {
29 $operations[] = array(
30 'update_authorize_batch_copy_project',
31 array(
32 $project_info['project'],
33 $project_info['updater_name'],
34 $project_info['local_url'],
35 $filetransfer,
36 ),
37 );
38 }
39
40 $batch = array(
41 'title' => t('Installing updates'),
42 'init_message' => t('Preparing to update your site'),
43 'operations' => $operations,
44 'finished' => 'update_authorize_update_batch_finished',
45 'file' => drupal_get_path('module', 'update') . '/update.authorize.inc',
46 );
47
48 batch_set($batch);
49 // Invoke the batch via authorize.php.
50 system_authorized_batch_process();
51 }
52
53 /**
54 * Callback invoked by authorize.php to install a new project.
55 *
56 * @param FileTransfer $filetransfer
57 * The FileTransfer object created by authorize.php for use during this
58 * operation.
59 * @param string $project
60 * The canonical project short name (e.g. {system}.name).
61 * @param string $updater_name
62 * The name of the Updater class to use for installing this project.
63 * @param string $local_url
64 * The URL to the locally installed temp directory where the project has
65 * already been downloaded and extracted into.
66 */
67 function update_authorize_run_install($filetransfer, $project, $updater_name, $local_url) {
68 $operations[] = array(
69 'update_authorize_batch_copy_project',
70 array(
71 $project,
72 $updater_name,
73 $local_url,
74 $filetransfer,
75 ),
76 );
77
78 // @todo Instantiate our Updater to set the human-readable title?
79 $batch = array(
80 'title' => t('Installing %project', array('%project' => $project)),
81 'init_message' => t('Preparing to install'),
82 'operations' => $operations,
83 // @todo Use a different finished callback for different messages?
84 'finished' => 'update_authorize_install_batch_finished',
85 'file' => drupal_get_path('module', 'update') . '/update.authorize.inc',
86 );
87 batch_set($batch);
88
89 // Invoke the batch via authorize.php.
90 system_authorized_batch_process();
91 }
92
93 /**
94 * Copy a project to its proper place when authorized with elevated privileges.
95 *
96 * @param string $project
97 * The canonical short name of the project being installed.
98 * @param string $updater_name
99 * The name of the Updater class to use for installing this project.
100 * @param string $local_url
101 * The URL to the locally installed temp directory where the project has
102 * already been downloaded and extracted into.
103 * @param FileTransfer $filetransfer
104 * The FileTransfer object to use for performing this operation.
105 * @param array &$context
106 * Reference to an array used for BatchAPI storage.
107 */
108 function update_authorize_batch_copy_project($project, $updater_name, $local_url, $filetransfer, &$context) {
109
110 // Initialize some variables in the Batch API $context array.
111 if (!isset($context['results']['log'])) {
112 $context['results']['log'] = array();
113 }
114 if (!isset($context['results']['log'][$project])) {
115 $context['results']['log'][$project] = array();
116 }
117
118 if (!isset($context['results']['tasks'])) {
119 $context['results']['tasks'] = array();
120 }
121
122 /**
123 * The batch API uses a session, and since all the arguments are serialized
124 * and unserialized between requests, although the FileTransfer object
125 * itself will be reconstructed, the connection pointer itself will be lost.
126 * However, the FileTransfer object will still have the connection variable,
127 * even though the connection itself is now gone. So, although it's ugly, we
128 * have to unset the connection variable at this point so that the
129 * FileTransfer object will re-initiate the actual connection.
130 */
131 unset($filetransfer->connection);
132
133 if (!empty($context['results']['log'][$project]['#abort'])) {
134 $context['#finished'] = 1;
135 return;
136 }
137
138 $updater = new $updater_name($local_url);
139
140 try {
141 if ($updater->isInstalled()) {
142 // This is an update.
143 $tasks = $updater->update($filetransfer);
144 }
145 else {
146 $tasks = $updater->install($filetransfer);
147 }
148 }
149 catch (UpdaterException $e) {
150 _update_batch_create_message($context['results']['log'][$project], t('Error installing / updating'), FALSE);
151 _update_batch_create_message($context['results']['log'][$project], $e->getMessage(), FALSE);
152 $context['results']['log'][$project]['#abort'] = TRUE;
153 return;
154 }
155
156 _update_batch_create_message($context['results']['log'][$project], t('Installed %project_name successfully', array('%project_name' => $project)));
157 $context['results']['tasks'] += $tasks;
158
159 // This particular operation is now complete, even though the batch might
160 // have other operations to perform.
161 $context['finished'] = 1;
162 }
163
164 /**
165 * Batch callback for when the authorized update batch is finished.
166 *
167 * This processes the results and stashes them into SESSION such that
168 * authorize.php will render a report. Also responsible for putting the site
169 * back online and clearing the update status cache after a successful update.
170 */
171 function update_authorize_update_batch_finished($success, $results) {
172 foreach ($results['log'] as $project => $messages) {
173 if (!empty($messages['#abort'])) {
174 $success = FALSE;
175 }
176 }
177 $offline = variable_get('site_offline', FALSE);
178 if ($success) {
179 // Now that the update completed, we need to clear the cache of available
180 // update data and recompute our status, so prevent show bogus results.
181 _update_authorize_clear_update_status();
182
183 if ($offline) {
184 variable_set('site_offline', FALSE);
185 $page_message = array(
186 'message' => t('Update was completed successfully. Your site has been taken out of maintenance mode.'),
187 'type' => 'status',
188 );
189 }
190 else {
191 $page_message = array(
192 'message' => t('Update was completed successfully.'),
193 'type' => 'status',
194 );
195 }
196 }
197 elseif (!$offline) {
198 $page_message = array(
199 'message' => t('Update failed! See the log below for more information.'),
200 'type' => 'error',
201 );
202 }
203 else {
204 $page_message = array(
205 'message' => t('Update failed! See the log below for more information. Your site is still in maintenance mode.'),
206 'type' => 'error',
207 );
208 }
209
210 // Set all these values into the SESSION so authorize.php can display them.
211 $_SESSION['authorize_results']['success'] = $success;
212 $_SESSION['authorize_results']['page_message'] = $page_message;
213 $_SESSION['authorize_results']['messages'] = $results['log'];
214 $_SESSION['authorize_results']['tasks'] = $results['tasks'];
215 }
216
217 /**
218 * Batch callback for when the authorized install batch is finished.
219 *
220 * This processes the results and stashes them into SESSION such that
221 * authorize.php will render a report. Also responsible for putting the site
222 * back online after a successful install if necessary.
223 */
224 function update_authorize_install_batch_finished($success, $results) {
225 foreach ($results['log'] as $project => $messages) {
226 if (!empty($messages['#abort'])) {
227 $success = FALSE;
228 }
229 }
230 $offline = variable_get('site_offline', FALSE);
231 if ($success && $offline) {
232 variable_set('site_offline', FALSE);
233 $page_message = array(
234 'message' => t('Installation was completed successfully. Your site has been taken out of maintenance mode.'),
235 'type' => 'status',
236 );
237 }
238 elseif ($success && !$offline) {
239 $page_message = array(
240 'message' => t('Installation was completed successfully.'),
241 'type' => 'status',
242 );
243 }
244 elseif (!$success && !$offline) {
245 $page_message = array(
246 'message' => t('Installation failed! See the log below for more information.'),
247 'type' => 'error',
248 );
249 }
250 else {
251 $page_message = array(
252 'message' => t('Installation failed! See the log below for more information. Your site is still in maintenance mode.'),
253 'type' => 'error',
254 );
255 }
256
257 // Set all these values into the SESSION so authorize.php can display them.
258 $_SESSION['authorize_results']['success'] = $success;
259 $_SESSION['authorize_results']['page_message'] = $page_message;
260 $_SESSION['authorize_results']['messages'] = $results['log'];
261 $_SESSION['authorize_results']['tasks'] = $results['tasks'];
262 }
263
264 /**
265 * Helper function to create a structure of log messages.
266 *
267 * @param array $project_results
268 * @param string $message
269 * @param bool $success
270 */
271 function _update_batch_create_message(&$project_results, $message, $success = TRUE) {
272 $project_results[] = array('message' => $message, 'success' => $success);
273 }
274
275 /**
276 * Private helper function to clear cached available update status data.
277 *
278 * Since this function is run at such a low bootstrap level, update.module is
279 * not loaded. So, we can't just call _update_cache_clear(). However, the
280 * database is bootstrapped, so we can do a query ourselves to clear out what
281 * we want to clear.
282 *
283 * Note that we do not want to just truncate the table, since that would
284 * remove items related to currently pending fetch attempts.
285 *
286 * @see update_authorize_update_batch_finished()
287 * @see _update_cache_clear()
288 */
289 function _update_authorize_clear_update_status() {
290 $query = db_delete('cache_update');
291 $query->condition(
292 db_or()
293 ->condition('cid', 'update_project_%', 'LIKE')
294 ->condition('cid', 'available_releases::%', 'LIKE')
295 );
296 $query->execute();
297 }

  ViewVC Help
Powered by ViewVC 1.1.2