/[drupal]/contributions/docs/developer/example.profile
ViewVC logotype

Contents of /contributions/docs/developer/example.profile

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


Revision 1.1 - (show annotations) (download) (as text)
Sat Dec 8 18:12:38 2007 UTC (23 months, 2 weeks ago) by wmostrey
Branch: MAIN
CVS Tags: HEAD
Branch point for: DRUPAL-6--1
File MIME type: text/x-php
Install profiles developer's guide by JirkaRybka: http://drupal.org/node/196928
1 <?php
2 // $Id: example.profile,v 1.1 2007/12/08 18:10:50 wmostrey Exp $
3
4 /**
5 * Return an array of the modules to be enabled when this profile is installed.
6 *
7 * @return
8 * An array of modules to enable.
9 */
10 function example_profile_modules() {
11 // This example profile enables the same optional modules as default.profile,
12 // plus the 'locale' module. But however, any available modules may be added
13 // to the list, including contributed modules, which will be then reqired by
14 // the installer. Configuration of these modules may be handled later by tasks.
15 return array('color', 'comment', 'help', 'menu', 'taxonomy', 'dblog', 'locale');
16 }
17
18 /**
19 * Return a description of the profile for the initial installation screen.
20 *
21 * @return
22 * An array with keys 'name' and 'description' describing this profile,
23 * and optional 'language' to override the language selection for
24 * language-specific profiles.
25 */
26 function example_profile_details() {
27 return array(
28 // These two strings will be displayed on the initial profile-selecion
29 // page, as a radio-button label, and description below. Because the
30 // page is shown before language selection, there's no point to attempt
31 // translation in any way; it's always shown in English. But however,
32 // if the profile is focused to install Drupal in some other language,
33 // these strings may be provided in that language, assuming that the
34 // maintainer of the installed new Drupal site understands that better.
35 // To skip the untranslatable profile-selection page entirely, ensure
36 // that there's just one profile available, by deleting the default
37 // profile.
38 'name' => 'Example installation profile',
39 'description' => 'This is an example installation profile for Drupal 6.x, demonstrating some of the principles to developers.',
40 // This example profile is supposed to be language-focused, so we
41 // inject the language selection here, hiding the language selection
42 // screen from the user, and so saving one unnecessary, untranslatable
43 // step. Any profile focused to features rather than language, or
44 // expecting more languages to choose from, should omit the line below.
45 // We're using Czech as an example here; it only works if a valid file
46 // cs.po (with installer translations) is provided in the
47 // profiles/example/translations directory, otherwise default English
48 // will be used instead.
49 'language' => 'cs',
50 );
51 }
52
53 /**
54 * Return a list of tasks that this profile supports.
55 *
56 * @return
57 * A keyed array of tasks the profile will perform during
58 * the final stage. The keys of the array will be used internally,
59 * while the values will be displayed to the user in the installer
60 * task list.
61 */
62 function example_profile_task_list() {
63 return array(
64 // Here we define names of the custom tasks we're about to perform
65 // later, so that these will be shown in the tasks list on the
66 // installer UI. The keys may be anything (internal use only),
67 // excepting the reserved tasks (as listed in install_reserved_tasks()
68 // inside install.php). The strings may be translated with the st()
69 // wrapper (translations provided in the install profile's .po file),
70 // but sometimes there's no point in doing that, if the profile is
71 // only focused to a single language. We only need to list tasks,
72 // for which a page will be displayed; internally, unlisted keys
73 // may be well used too. It's also possible to return dynamic data
74 // here, adding/removing tasks on-the-fly depending on previous
75 // steps.
76 'task1' => st('Example question'),
77 'task2' => st('Example summary'),
78 );
79 }
80
81 /**
82 * Perform any final installation tasks for this profile.
83 *
84 * The installer goes through the profile-select -> locale-select
85 * -> requirements -> database -> locale-initial-batch -> configure
86 * -> locale-remaining-batch -> finished -> done tasks in this order,
87 * if you don't implement this function in your profile.
88 *
89 * If this function is implemented, you can have any number of
90 * custom tasks to perform after 'configure', implementing a state
91 * machine here to walk the user through those tasks. First time,
92 * this function gets called with $task set to 'profile', and you
93 * can advance to further tasks by setting $task to your tasks'
94 * identifiers, used as array keys in the hook_profile_task_list()
95 * above. You must avoid the reserved tasks listed in
96 * install_reserved_tasks(). If you implement your custom tasks,
97 * this function will get called in every HTTP request (for form
98 * processing, printing your information screens and so on) until
99 * you advance to the 'profile-finished' task, with which you
100 * hand control back to the installer. Each custom page you
101 * return needs to provide a way to continue, such as a form
102 * submission or a link. You should also set custom page titles.
103 *
104 * You should define the list of custom tasks you implement by
105 * returning an array of them in hook_profile_task_list(), as these
106 * show up in the list of tasks on the installer user interface.
107 *
108 * Remember that the user will be able to reload the pages multiple
109 * times, so you might want to use variable_set() and variable_get()
110 * to remember your data and control further processing, if $task
111 * is insufficient. Should a profile want to display a form here,
112 * it can; the form should set '#redirect' to FALSE, and rely on
113 * an action in the submit handler, such as variable_set(), to
114 * detect submission and proceed to further tasks. See the configuration
115 * form handling code in install_tasks() for an example.
116 *
117 * Important: Any temporary variables should be removed using
118 * variable_del() before advancing to the 'profile-finished' phase.
119 *
120 * @param $task
121 * The current $task of the install system. When hook_profile_tasks()
122 * is first called, this is 'profile'.
123 * @param $url
124 * Complete URL to be used for a link or form action on a custom page,
125 * if providing any, to allow the user to proceed with the installation.
126 *
127 * @return
128 * An optional HTML string to display to the user. Only used if you
129 * modify the $task, otherwise discarded.
130 */
131 function example_profile_tasks(&$task, $url) {
132
133 // First time, this function will be called with the 'profile' task.
134 // In this case, we advance the pointer to our first custom task, to
135 // indicate that this profile needs more runs to complete, and we
136 // also perform some initial settings.
137 if ($task == 'profile') {
138 $task = 'task1';
139
140 // The following part is a verbatim from default.profile, doing some
141 // basic settings, that may be easily customized here. For a simple
142 // profile, with no need for custom UI screens, this will be the
143 // only code inside hook_profile_tasks(); in that case there's
144 // no need to modify $task, as demonstrated in default.profile:
145 // If $task is not changed, this function gets only called once.
146
147 // Insert default user-defined node types into the database. For a complete
148 // list of available node type attributes, refer to the node type API
149 // documentation at: http://api.drupal.org/api/HEAD/function/hook_node_info.
150 $types = array(
151 array(
152 'type' => 'page',
153 'name' => st('Page'),
154 'module' => 'node',
155 'description' => st("A <em>page</em>, similar in form to a <em>story</em>, is a simple method for creating and displaying information that rarely changes, such as an \"About us\" section of a website. By default, a <em>page</em> entry does not allow visitor comments and is not featured on the site's initial home page."),
156 'custom' => TRUE,
157 'modified' => TRUE,
158 'locked' => FALSE,
159 'help' => '',
160 'min_word_count' => '',
161 ),
162 array(
163 'type' => 'story',
164 'name' => st('Story'),
165 'module' => 'node',
166 'description' => st("A <em>story</em>, similar in form to a <em>page</em>, is ideal for creating and displaying content that informs or engages website visitors. Press releases, site announcements, and informal blog-like entries may all be created with a <em>story</em> entry. By default, a <em>story</em> entry is automatically featured on the site's initial home page, and provides the ability to post comments."),
167 'custom' => TRUE,
168 'modified' => TRUE,
169 'locked' => FALSE,
170 'help' => '',
171 'min_word_count' => '',
172 ),
173 );
174
175 foreach ($types as $type) {
176 $type = (object) _node_type_set_defaults($type);
177 node_type_save($type);
178 }
179
180 // Default page to not be promoted and have comments disabled.
181 variable_set('node_options_page', array('status'));
182 variable_set('comment_page', COMMENT_NODE_DISABLED);
183
184 // Don't display date and author information for page nodes by default.
185 $theme_settings = variable_get('theme_settings', array());
186 $theme_settings['toggle_node_info_page'] = FALSE;
187 variable_set('theme_settings', $theme_settings);
188
189 // Update the menu router information.
190 menu_rebuild();
191 }
192 // (End of verbatim from default.profile)
193
194 // Our custom tasks now follow. Just like install.php, we use a construct
195 // of if() statements here, to allow passing from one task to another in
196 // the same request, after the $task pointer got modified, and ensure
197 // that correct code gets executed on page reloads.
198
199 // Our first custom task displays a form.
200 if ($task == 'task1') {
201 // FAPI takes care of most of the operations, as page reloads go.
202 // We pass the $url to the form definition, to be used for form action.
203 $output = drupal_get_form('example_form', $url);
204
205 // The forms inside installer profiles may not use redirection, because
206 // that will break the installer workflow. So we need an other way to
207 // detect whether the form was successfully submitted, meaning that
208 // the submit handler already performed it's job. This depends on the
209 // exact use case; in this example profile, we check whether some
210 // user-submitted text was already stored into our variable.
211 if (!variable_get('example_submitted_text', FALSE)) {
212 // The variable is still empty, meaning that the drupal_get_form()
213 // call above haven't finished the form yet. We set a page-title
214 // here, and return the rendered form to the installer, to be
215 // shown to the user. Since $task is still set to 'task1', this
216 // code will be re-run on next page request, proceeding further
217 // if possible.
218 drupal_set_title(st('Example question'));
219 return $output;
220 }
221 else {
222 // The form was submitted, so now we advance to the next task.
223 $task = 'task2';
224 }
225 }
226
227 // Our second custom task shows a simple page, summarizing the previous
228 // step.
229 if ($task == 'task2') {
230
231 // To display a simple HTML page through the installer, we just set
232 // title, and return the content. But since this code is now run on
233 // every page request (until we change the $task), we need to detect
234 // whether the user already decided to finish this task by clicking
235 // to the provided link (as opposed to showing the page first time,
236 // or a reload). This is done through an extra GET string added to
237 // the link.
238 if (empty($_GET['example_finished'])) {
239 // The GET string is not present, meaning that this page request
240 // is not coming from the link being clicked, and so we need to
241 // render the page.
242 $output = '<p>'. st('This page is a demonstration of custom page shown by a custom task of installer profile.') .'</p>';
243 $output .= '<p>'. st('On the previous page, the following text was entered: %text.', array('%text' => variable_get('example_submitted_text', ''))) .'</p>';
244 // We build the link from $url provided by the installer, adding
245 // the extra GET string mentioned above.
246 $output .= '<p><a href="'. $url .'&example_finished=yes">'. st('Click here to continue') .'</a></p>';
247 drupal_set_title(st('Example summary'));
248 return $output;
249 }
250 else {
251 // The GET string is present, meaning that the user already
252 // reviewed the page and clicked the link. We can advance to
253 // further tasks now, but since we haven't any left, we just
254 // finish our business here:
255
256 // The variable 'example_submitted_text' was just a temporary
257 // storage for our testing. Variables may be used for such
258 // purposes here, but we should remove them before passing
259 // control back to installer, to avoid leaving useless temporary
260 // data in the variables table of the newly installed Drupal
261 // site.
262 variable_del('example_submitted_text');
263
264 // By advancing to the 'profile-finished' task, we hand control
265 // back to the installer, when we are done.
266 $task = 'profile-finished';
267 }
268 }
269 }
270
271 /**
272 * Form API array definition for the example form.
273 */
274 function example_form(&$form_state, $url) {
275
276 // This is just a very simple form with one textfield, and a
277 // submit button.
278 $form['example_text'] = array(
279 '#type' => 'textfield',
280 '#title' => st('Testing text'),
281 '#default_value' => '',
282 '#size' => 45,
283 '#maxlength' => 45,
284 '#required' => TRUE,
285 '#description' => st('This is an example form demonstrating forms usage in the installer profiles tasks. Enter any text to see what happens.'),
286 );
287
288 $form['continue'] = array(
289 '#type' => 'submit',
290 '#value' => st('Continue'),
291 );
292
293 // Note that #action is set to the url passed through from
294 // installer, ensuring that it points to the same page, and
295 // #redirect is FALSE to avoid broken installer workflow.
296 $form['errors'] = array();
297 $form['#action'] = $url;
298 $form['#redirect'] = FALSE;
299
300 return $form;
301 }
302
303 /**
304 * Form API submit for the example form.
305 */
306 function example_form_submit($form, &$form_state) {
307
308 // This code is executed, while the form is submitted. There's
309 // a wide range of possible operations to execute here, such as
310 // process and store settings, enable extra modules, or save
311 // contents to the new site (unless the operations are too
312 // expensive: the Batch API is a good choice for such operations,
313 // but it needs to be coded inside hook_profile_tasks(), not
314 // here).
315
316 // In this example profile, we just store the submitted text to
317 // a temporary variable, to be used in further tasks.
318 variable_set('example_submitted_text', $form_state['values']['example_text']);
319 }
320
321 /**
322 * Implementation of hook_form_alter().
323 *
324 * Allows the profile to alter the site-configuration form. This is
325 * called through custom invocation, so $form_state is not populated.
326 */
327 function example_form_alter(&$form, $form_state, $form_id) {
328 if ($form_id == 'install_configure') {
329
330 // Here we can play with the site configuration form provided
331 // by the installer, by changing the prepopulated $form array.
332 // See install_configure_form() inside install.php for its
333 // default content.
334
335 // Set default for site name field.
336 $form['site_information']['site_name']['#default_value'] = 'Drupal example';
337
338 // Set default for administrator account name.
339 $form['admin_account']['account']['name']['#default_value'] = 'admin';
340
341 // Remove the timezone setting, as this profile is supposed to be
342 // focused on Czech language as an example, where the timezone is
343 // obvious.
344 unset($form['server_settings']['date_default_timezone']);
345 // Define the timezone as fixed value instead, so that the submit
346 // handler of the site configuration form may still process it.
347 $form['date_default_timezone'] = array(
348 '#type' => 'value',
349 '#value' => '3600',
350 );
351 }
352 }

  ViewVC Help
Powered by ViewVC 1.1.2