/[drupal]/contributions/modules/hosting/hosting_help.inc
ViewVC logotype

Contents of /contributions/modules/hosting/hosting_help.inc

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


Revision 1.46 - (show annotations) (download) (as text)
Fri Nov 6 04:54:53 2009 UTC (2 weeks, 5 days ago) by mig5
Branch: MAIN
CVS Tags: DRUPAL-6--0-4-ALPHA3, HEAD
Changes since 1.45: +11 -12 lines
File MIME type: text/x-php
grammar police / spelling nazi
1 <?php
2
3 // $Id: hosting_help.inc,v 1.45 2009/10/14 11:42:24 mig5 Exp $
4
5 /**
6 * @file Hosting help subsystem
7 */
8
9 /**
10 * Constants used to generate the requirement help documentation.
11 */
12
13 /**
14 * Status is irrelevant. Can't be checked
15 */
16 define('HOSTING_STATUS_NONE', 0);
17
18 /**
19 * Requirement is met
20 */
21 define('HOSTING_STATUS_SUCCESS', 1);
22
23 /**
24 * Requirement not met. Less severe than an error.
25 */
26 define('HOSTING_STATUS_WARNING', 2);
27
28 /**
29 * Requirement failed. Fix before site will function
30 */
31 define('HOSTING_STATUS_ERROR', 4);
32
33 /**
34 * Returns a class name for the output of the form element.
35 */
36 function _hosting_status_class($status) {
37 static $map;
38
39 if (!sizeof($map)) {
40 $map = array(
41 HOSTING_STATUS_NONE => 'hosting-status-none',
42 HOSTING_STATUS_SUCCESS => 'hosting-status-success',
43 HOSTING_STATUS_WARNING => 'hosting-status-warning',
44 HOSTING_STATUS_ERROR => 'hosting-status-error',
45 );
46 }
47
48 return $map[$status];
49 }
50
51 /**
52 * Constants used to configure contextual hosting help
53 */
54
55 /**
56 * Display component of help
57 **/
58 define('HOSTING_HELP_ENABLED', 1);
59
60 /**
61 * Don't show help component
62 **/
63 define('HOSTING_HELP_DISABLED', ~HOSTING_HELP_ENABLED);
64
65 /**
66 * These are internally used to test against. Use the COLLAPSIBLE AND
67 * COLLAPSED instead
68 **/
69 define('_HOSTING_HELP_CAN_COLLAPSE', 2);
70 define('_HOSTING_HELP_HAS_COLLAPSED', 4);
71
72 /**
73 * Show help with the ability to collapse to save space.
74 * This automatically enables the help component
75 **/
76 define('HOSTING_HELP_COLLAPSIBLE', HOSTING_HELP_ENABLED | _HOSTING_HELP_CAN_COLLAPSE);
77
78 /**
79 * Display help component with an initial collapsed state.
80 * This automatically enables and sets the help component to be collapsible
81 */
82 define('HOSTING_HELP_COLLAPSED', HOSTING_HELP_COLLAPSIBLE | _HOSTING_HELP_HAS_COLLAPSED);
83
84
85 /**
86 * Returns a class name for the output of the form element
87 */
88 function _hosting_help_class($state) {
89 static $map;
90
91 if (!sizeof($map)) {
92 $map = array(
93 HOSTING_HELP_ENABLED => 'hosting-help',
94 HOSTING_HELP_COLLAPSIBLE => 'hosting-help-collapsible',
95 HOSTING_HELP_COLLAPSED => 'hosting-help-collapsed'
96 );
97 }
98 return $map[$state];
99 }
100
101 /**
102 * Implementation of hook_hosting_service()
103 */
104 function hosting_hosting_service() {
105 return array('hosting' => t("Basic configuration"));
106 }
107
108 /**
109 * Implementation of hook_help()
110 */
111 function hosting_help($path, $arg) {
112 switch ($path) {
113 case 'admin/help/hosting':
114 $output .= '<p>' . t('The Hostmaster system is a set of modules that provide an interface to the Provisioning framework.') . '</p>';
115 $output .= '</dl>';
116 $output .= '<a name="requirements"></a><h3>' . t('Requirements') . '</h3></a>';
117 // @TODO: make this more clear
118 $output .= _hosting_requirements('provision');
119 $output .= _hosting_requirements('hosting_setup');
120 $output .= _hosting_requirements('cron');
121 $output .= _hosting_requirements('user');
122 $output .= _hosting_requirements('group');
123 $output .= _hosting_requirements('backup_path');
124
125 $output .= '<a name="glossary"></<h3>' . t('Glossary') . '</h3></a>';
126 $output .= '<dl>';
127 $types = node_get_types();
128
129 foreach ($types as $type => $info) {
130 if ($info->description) {
131 $output .= "<dt><a name=\"glossary-$type\"></a>" . $info->name . '</dt>';
132 $output .= '<dd>' . $info->description . '</dd>';
133 }
134 }
135 return $output;
136 }
137 }
138
139 /**
140 * TODO: replace. this is OLD OLD OLD
141 */
142 function _hosting_introduction() {
143 $default_message = t('<p>Please follow these steps to set up and start using your website:</p>');
144 $default_message .= '<ol>';
145
146 $default_message .= '<li>'. t('<strong>Configure your website</strong>
147 Once logged in, visit the <a href="@admin">administration section</a>,
148 where you can <a href="@config">customize and configure</a> all aspects of your website.',
149 array('@admin' => url('admin'), '@config' => url('admin/settings'))) .'</li>';
150 $default_message .= '<li>'. t('<strong>Configure the Hosting framework.</strong>
151 You now have a configured provisioning framework, but there are some additional configuration options for the hosting framework that can be set.
152 Please visit the <a href="@hosting_admin">hosting administration</a> section for more information.', array('@hosting_admin' => url('admin/hosting'))) .'</li>';
153 $default_message .= '<li>'. t('<strong>Create your first hosted site.</strong> This system uses special site posts to store information about your sites, so you can simple <a href="@create_site">create a site post</a> to get your first hosted site running.', array('@create_site' => url('node/add/site'))) .'</li>';
154 $default_message .= '</ol>';
155 $default_message .= '<p>'. t('For more information, please refer to the <a href="@help">help section</a>, or the <a href="@handbook">online Drupal handbooks</a>. You may also post at the <a href="@forum">Drupal forum</a>, or view the wide range of <a href="@support">other support options</a> available.', array('@help' => url('admin/help'), '@handbook' => 'http://drupal.org/handbooks', '@forum' => 'http://drupal.org/forum', '@support' => 'http://drupal.org/support')) .'</p>';
156
157 $output = '<div id="first-time">'. $default_message .'</div>';
158
159 return $output;
160
161 }
162
163 /**
164 * Per node type description text. To be stored in the node_type table.
165 *
166 * @param type
167 * The node type.
168 * @return
169 * Description text for the node type.
170 */
171 function hosting_node_help($type) {
172 switch ($type) {
173 case 'site' :
174 return t("<strong>An instance of a hosted site.</strong>
175 It contains information relating to the site, most notably the domain name, database server
176 and platform it is being published on. A site may also have several aliases for additional
177 domains the site needs to be accessible on.");
178 break;
179 case 'platform' :
180 return t("<strong>The file system location on a specific web server on which to publish sites.</strong>
181 Multiple platforms can co-exist on the same web server, and need to do so for
182 upgrades to be managed, as this is accomplished by migrating the site between platforms.
183 Platforms are most commonly built for specific releases of Drupal.");
184 break;
185 case 'client' :
186 return t("<strong>The person or group that runs the site.</strong>
187 This information is usually required for billing and access purposes, to ensure
188 that only certain people are able to view the information for sites they run.
189 If you do not intend on having more than one client access the system,
190 you will not need to create any additional clients for your purposes.");
191 break;
192 case 'web_server' :
193 return t("<strong>The physical machine where files will be stored for publication.</strong>
194 Each web server hosts one or more platforms, which act as publishing points for the hosted sites.
195 If you are not intending to use Hostmaster in a distributed fashion, you will not need to create
196 additional web servers for your purposes.");
197 break;
198 case 'db_server' :
199 return t("<strong>The database server on which sites will host their data.</strong>
200 Most web servers and database servers are on the same machine, but for performance reasons
201 external database servers might be required. It is not uncommon for one database server
202 to be shared amongst all site instances.
203 If you are not intending to use an external database server, or multiple database servers, you
204 will not need to create any additional database servers for your purposes.");
205 break;
206 case 'task' :
207 return t("<strong>The mechanism whereby Hostmaster keeps track of all changes that occur to the system.</strong>
208 Each task acts as a command for the back-end, and contains a full log of all changes that have occurred.
209 If a task should fail, the administrator will be notified with an explanation of exactly what went wrong,
210 and how to fix it.");
211 break;
212 }
213 }
214
215 /**
216 * Page callback with in depth requirement documentation
217 *
218 * This will invoke hook_help() for every module implementing
219 * hook_hosting_service()
220 *
221 * @see hook_hosting_service()
222 * @see hook_hosting_help()
223 */
224 function hosting_help_requirements() {
225 $output .= _hosting_requirements("basic_drupal");
226 $output .= _hosting_requirements("basic_unix");
227 $output .= _hosting_requirements("basic_server");
228 $modules = module_implements('hosting_service');
229 foreach ($modules as $module) {
230 $service = module_invoke($module, 'hosting_service');
231 $name = current($service);
232 $help = module_invoke($module, 'help', 'admin/help/provision#requirements', null);
233 if ($name && $help) {
234 $output .= "<a href='requirements-$module'></a><h3>". t($name) .'</h3>';
235 $output .= $help;
236 }
237 }
238 return $output;
239 }
240
241 /**
242 * Helper function for displaying contextual help when not used in a form.
243 */
244 function _hosting_requirements($req, $section = 'all') {
245 $item = _element_info('requirement_help');
246 $item['#requirement'] = $req;
247 $item['#type'] = 'requirement_help';
248 /*
249 foreach (array('#heading', '#summary', '#suggestion', '#configuration') as $key) {
250 if (in_array($section, array('all', $key))) {
251 $item['#'. $key] = HOSTING_HELP_ENABLED;
252 }
253 elseif ($section != 'all') {
254 $item['#'. $key] = ($section == $key) ? HOSTING_HELP_ENABLED : HOSTING_HELP_DISABLED;
255 }
256 }
257 */
258 return theme("requirement_help", hosting_requirement_process($item));
259 }
260
261 /**
262 * Find the requirements help document for the given element
263 *
264 * This will call hook_requirements() for the given element. The
265 * function name should be _hosting_$req_requirements() for this to
266 * function properly.
267 *
268 * @see hook_requirements()
269 * @see _hosting_requirements()
270 */
271 function hosting_get_requirement($req) {
272 $func = '_hosting_'. $req .'_requirements';
273 if (function_exists($func)) {
274 $help = $func();
275 }
276 return $help;
277 }
278
279 /**
280 * Places the various help components info the $element array
281 *
282 * @see hosting_get_requirement()
283 * @return array a form item with '#help' properly filled in with hosting_get_requirement() analysis
284 */
285 function hosting_requirement_process(&$element) {
286 if (!$element['#requirement']) {
287 return $element;
288 }
289
290 $element['#help'] = hosting_get_requirement($element['#requirement']);
291 return $element;
292 }
293
294 /**
295 * Implementation of hook_elements.
296 *
297 * Defines a number of form elements that are used for formatting the contextual help
298 * in forms.
299 */
300 function hosting_elements() {
301 $type['requirement_help'] = array(
302 '#requirement' => NULL,
303 '#input' => FALSE,
304 '#status' => HOSTING_STATUS_NONE,
305 '#heading' => HOSTING_HELP_ENABLED,
306 '#summary' => HOSTING_HELP_ENABLED,
307 '#summary_prefix' => t("What is this?"),
308 '#configuration' => HOSTING_HELP_COLLAPSED,
309 '#configuration_prefix' => t("How do I configure this?"),
310 '#default_messages' => array(
311 HOSTING_STATUS_SUCCESS => t("You have met this requirement."),
312 HOSTING_STATUS_WARNING => t("This requirement has a non critical error."),
313 HOSTING_STATUS_ERROR => t("This requirement has a critical error. This system will not operate until it has been fixed")),
314 '#process' => array('hosting_requirement_process'),
315 );
316 return $type;
317 }
318
319 /**
320 * Theme function for displaying contextual help.
321 *
322 * Can control individual components of the help, for display in various places.
323 */
324 function theme_requirement_help(&$element) {
325 drupal_add_js(drupal_get_path('module', 'hosting') .'/hosting_help.js');
326 drupal_add_css(drupal_get_path('module', 'hosting') .'/hosting_help.css');
327 $req = $element['#requirement'];
328 $help = $element['#help']; // this is just to make it easier to work with.
329
330 //place anchor so user can be directed to right page.
331 $output .= "<a name='hosting-help-$req'></a>";
332
333 $output .= '<div class="hosting-requirement-help' .
334 ' '. _hosting_status_class($element['#status']) .'">';
335
336 if ($element['#status'] != HOSTING_STATUS_NONE) {
337 $output .= "<div class='message'>". (($element['#message']) ? $element['#message'] : $element['#default_messages'][$element['#status']]) ."</div>";
338 }
339
340 $components = array('summary', 'suggestion', 'configuration');
341 foreach ($components as $key) {
342 if (($element["#$key"] & HOSTING_HELP_ENABLED) && !is_null($help[$key])) {
343 $display_type = _hosting_help_class($element["#$key"]);
344 $output .= "<div class='hosting-help-$key $display_type'>";
345 if (!is_array($help[$key])) {
346 // it is simpler if there's only one way to print the component
347 $help[$key] = array($help[$key]);
348 }
349 if ($element["#$key".'_prefix'] && ($element["#$key"] & _HOSTING_HELP_CAN_COLLAPSE)) {
350 $output .= '<a href="javascript:void(0)" class="hosting-help-toggle">'. $element["#$key".'_prefix'] .'</a>';
351 }
352
353 $output .= "<div class='hosting-help'><p>". implode("</p><p>", $help[$key]) ."</p></div>";
354 $output .= '</div>';
355 }
356 }
357 $output .= '</div>';
358 if (($element['#heading'] & HOSTING_HELP_ENABLED) && $help['title'] && !$element['#title']) {
359 $element['#title'] = $help['title'];
360 }
361 $element['#value'] = $output;
362 return theme('item', $element);
363 }
364
365 /**
366 * @TODO: handle element children for requirement help
367 function _hosting_basic_requirements() {
368 $help['drupal'] = _hosting_basic_drupal_requirements();
369 $help['unix'] = _hosting_basic_unix_requirements();
370 $help['server'] = _hosting_basic_server_requirements();
371
372 return $help;
373 }
374 */
375
376 function _hosting_backup_path_requirements() {
377 $username = HOSTING_DEFAULT_SCRIPT_USER;
378 $group = HOSTING_DEFAULT_WEB_GROUP;
379 $backup_path = HOSTING_DEFAULT_BACKUP_PATH;
380 $mkdir_cmd['@backup_path'] = $backup_path;
381 $mkdir_cmd['@mkdir_cmd'] = <<<EOF
382 mkdir $backup_path
383 chown $username:$username $backup_path
384 chmod 0700 $backup_path
385 EOF;
386 $help['title'] = t('Write access to a directory to store backups');
387 $help['summary'] = t('The drush user (<a href="http://drupal.org/project/drush">http://drupal.org/project/drush</a>) needs to be able to maintain the backups repository to ensure that your site is backed up successfully.
388 It is incredibly important that this path is not accessible via the web server, so that no undesirables can get their
389 hands on your database. The recommended path is directly above your platform path, but it can be anywhere.');
390
391 $help['suggestion'] = t('Based on your server configuration we have determined that your path should be <code>@backup_path</code>', $mkdir_cmd);
392 $help['configuration'] = t('Please enter the following commands : <pre>@mkdir_cmd</pre>', $mkdir_cmd);
393 return $help;
394 }
395
396
397 function _hosting_user_requirements() {
398 $username = HOSTING_DEFAULT_SCRIPT_USER;
399 $path = HOSTING_DEFAULT_DOCROOT_PATH;
400 $add_cmd = <<<EOF
401 sudo adduser $username
402 EOF;
403 $chmod_cmd = <<<EOF
404 sudo chown -R $username $path
405 EOF;
406 $help['title'] = t('A separate system account for the scripts');
407 $help['summary'] = t('The provision framework requires that the scripts run as a non-root system account, to ensure that
408 it can correctly set the file permissions on the hosted files. All existing files need to be changed to belong to this
409 new system account.');
410 $help['suggestion'] = t('Based on your server configuration, we have determined that your user account should be <code>@script_user</code>', array('@script_user' => HOSTING_DEFAULT_SCRIPT_USER));
411 $help['configuration'][] = t('If your system supports it, run the adduser command (if this command is unavailable, please consult your operating system documentation on how to add new system accounts) : <pre>@cmd</pre>', array('@cmd' => $add_cmd));
412 $help['configuration'][] = t('Once you have created the user account, you need to modify the ownership of the files. Use the following command : <pre>@cmd</pre>', array('@cmd' => $chmod_cmd));
413 return $help;
414 }
415
416 function _hosting_group_requirements() {
417
418 $username = HOSTING_DEFAULT_SCRIPT_USER;
419 $group = HOSTING_DEFAULT_WEB_GROUP;
420
421
422 $vigr_cmd = <<<EOF
423 sudo adduser $username $group
424 EOF;
425 $vigr1 = <<<EOF
426 $group::99:
427 EOF;
428 $vigr2 = <<<EOF
429 $group::99:$username
430 EOF;
431 $vigr3 = <<<EOF
432 $group::99:anotheruser,$username
433 EOF;
434
435 $su = <<<EOF
436 su -
437 EOF;
438
439 $help['title'] = t('The system group of the web server');
440 $help['summary'] = t('For the provision framework to be able to ensure that the file permissions of the
441 hosted sites are always as safe as can be, and especially to make sure that the web server does
442 not have the ability to modify the code of the site, the configured system account needs to be a member
443 of the web server group, in order to be able to correctly set the file permissions.');
444
445 $help['suggestion'] = t('Based on your server configuration we have determined that you should add the
446 system account "<code>@username</code>" to the "<code>@group</code>" system group.', array("@username" => $username, "@group" => $group));
447
448 $help['configuration'] =t('If your system account is not a member of the web group, you can add them by using the
449 <code>adduser</code> command:
450 <pre>@vigr_cmd</pre>
451 If that command is not available, you will need to edit the /etc/group file directly with
452 your vigr or your favorite editor.
453 Find the line that says : <pre>@vigr1</pre>
454 Then add the username to the end of the line, so that it looks like : <pre>@vigr2</pre>
455 If there were already users in the group, add your user to the group using a comma as separator :
456 <pre>@vigr3</pre>
457 Once you have changed this, you will need to log out and log back into your terminal session for this
458 setting to take effect. Alternatively you
459 can get a new login shell by typing : <pre>@su</pre>',
460 array('@vigr_cmd' => $vigr_cmd, '@vigr1' => $vigr1, '@vigr2' => $vigr2, '@vigr3' => $vigr3, '@su' => $su));
461 return $help;
462
463 }
464
465 /**
466 * Implementation of hook_requirements()
467 */
468 function _hosting_basic_drupal_requirements() {
469 $help['title'] = t('A system capable of running Drupal');
470 $help['summary'] = t('If you are reading this via the inline help, this would be kind of obvious. This system is entirely Drupal based, and has the same base requirements that Drupal does.');
471 return $help;
472 }
473
474 /**
475 * Implementation of hook_requirements()
476 */
477 function _hosting_basic_server_requirements() {
478 $help['title'] = t('Your own server');
479 $help['summary'] = t('The level of access required to be able to configure this system is very far beyond what is commonly available to users with shared hosting.');
480 return $help;
481 }
482
483 /**
484 * Implementation of hook_requirements()
485 */
486 function _hosting_basic_unix_requirements() {
487 $help['title'] = t('A unix based operating system');
488 $help['summary'] = t('The majority of functionality in this system occurs in the back-end, through command line scripting. There are several features (such as symlinks), that are not available to users on Windows. There are no plans currently to add Windows support.</p>');
489 return $help;
490 }
491
492 /**
493 * Implementation of hook_requirements()
494 */
495 function _hosting_hosting_setup_requirements() {
496 $node = node_load(HOSTING_OWN_WEB_SERVER);
497 $drush_path = $node->drush_path;
498 $docroot = HOSTING_DEFAULT_DOCROOT_PATH;
499 $uri = HOSTING_DEFAULT_BASE_URL;
500 $username = HOSTING_DEFAULT_SCRIPT_USER;
501 $login_cmd = <<<EOF
502 su -s /bin/sh $username
503 EOF;
504 $setup_cmd = <<<EOF
505 cd $docroot
506 php $drush_path --uri=$uri hosting setup
507 EOF;
508 $help['title'] = t('Perform initial configuration by running the <code>Hosting Setup</code> command');
509
510 $help['summary'][] = t('The hosting setup command performs several useful installation functions, but its primary responsibility
511 is adding the crontab entry for the queue dispatcher and ensuring that has been correctly installed.');
512
513 $help['summary'][] = t('The queue dispatcher runs every minute. It keeps track of what work needs to be done on the system
514 and instructs the provisioning framework to perform the needed tasks in the task queue.');
515 $help['summary'][] = t('Otherwise said, without the dispatcher, changes on the front-end will not translate in the required back-end configuration preventing actual sites management.');
516 $help['configuration'][] = t('If you are not logged in as %script_user user, log in with command : <pre>@login_cmd</pre>',
517 array('%script_user' => $username, '@login_cmd' => $login_cmd));
518 $help['configuration'][] = t('Now execute the following commands : <pre>@setup_cmd</pre>',
519 array('%script_user' => $username, '@setup_cmd' => $setup_cmd));
520
521 return $help;
522 }
523
524 /**
525 * Implementation of hook_requirements()
526 */
527 function _hosting_cron_requirements() {
528 $cron_cmd['!queueconf'] = l(t("Queue administration"), "admin/settings/queues");
529 $cron_cmd['@cron_line'] = hosting_queues_cron_cmd();
530 $help['title'] = t('A cron entry for queue dispatcher.');
531 $help['summary'][] = t('Changes to this system are executed via a back end script which needs to be called by a user other than
532 the web server user for security reasons at regular intervals.');
533 $help['summary'][] = t('The intervals at which these commands are run can be customised by going to the !queueconf section.', $cron_cmd);
534 $help['summary'][] = t('The <code>hosting setup</code> command installs the required cron entry for you.', $cron_cmd);
535 $help['configuration'] = t('Add the following line to your crontab : <code>@cron_line</code>', $cron_cmd);
536 return $help;
537 }
538
539 /**
540 * Implementation of hook_requirements()
541 */
542 function _hosting_platform_requirements() {
543 $platform = node_load(HOSTING_OWN_PLATFORM);
544 $web_server = node_load(HOSTING_OWN_WEB_SERVER);
545 $db_server = node_load(HOSTING_OWN_DB_SERVER);
546
547 $task = hosting_get_most_recent_task($platform->nid, 'verify');
548
549 $help['title'] = t('Provisioning framework status');
550 $help['summary'][] = t('In order for the hosting system to be able to create sites, it needs a platform to publish these sites on. A platform is a Drupal site that has the provision back-end installed. Each platform also requires one correctly configured web server and one correctly configured database server. Once a new platform has been created, Hosting will automatically schedule a task that will verify the new platform is working properly.');
551 $help['summary'][] = t('As hosting is also running on a platform, it is suggested that you successfully configure your <a href="@platform">primary platform</a>
552 before creating additional platforms and servers.', array('@platform' => url('node/' . HOSTING_OWN_PLATFORM)));
553 $help['summary'][] = t('Each platform must be verified at least once, but if you find your platform is not being verified, look at the error log on the <a href="@verify_link">Verify platform task of this platform</a>', array("@verify_link" => url("node/" . $task->nid)));
554
555 return $help;
556
557 }

  ViewVC Help
Powered by ViewVC 1.1.2