/[drupal]/contributions/docs/developer/examples/scaffolding_example/scaffolding_example.admin.inc
ViewVC logotype

Contents of /contributions/docs/developer/examples/scaffolding_example/scaffolding_example.admin.inc

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


Revision 1.4 - (show annotations) (download) (as text)
Sun Oct 12 08:52:36 2008 UTC (13 months, 2 weeks ago) by davereid
Branch: MAIN
CVS Tags: HEAD
Changes since 1.3: +2 -12 lines
File MIME type: text/x-php
- Fix coding standards
1 <?php
2 // $Id: scaffolding_example.admin.inc,v 1.3 2008/06/03 05:39:12 eaton Exp $
3
4 /**
5 * @file
6 * Administrative pages for the module.
7 *
8 * Contains form building functions, submit handlers, and theme functions for
9 * the module's overview form, add and edit forms, and the delete confirmation
10 * form.
11 */
12
13 /**
14 * Build an overview form with drag and drop re-ordering of records.
15 *
16 * Loads all records and builds an overview form with weight elements for each
17 * record, then adds Drupal's tabledrag.js file. Because ALL records will be
18 * displayed on this page, this style of overview is best suited to small sets
19 * of data.
20 *
21 * If your module will work with large numbers of records, or if you don't need
22 * the drag-and-drop re-ordering feature, the paged version of the overview
23 * is likly be a better solution.
24 *
25 * @ingroup forms
26 * @see _scaffolding_example_overview_record_field()
27 * @see scaffolding_example_overview_form_submit()
28 * @see theme_scaffolding_example_overview_form()
29 * @see scaffolding_example_overview_pager()
30 */
31 function scaffolding_example_overview_form(&$form_state) {
32 $records = scaffolding_example_record_load_all();
33
34 $form['records']['#tree'] = TRUE;
35 foreach ($records as $record_id => $record) {
36 $form['records'][$record_id] = _scaffolding_example_overview_record_field($record);
37 }
38
39 $form['buttons']['submit'] = array(
40 '#type' => 'submit',
41 '#value' => t('Save changes'),
42 '#disabled' => empty($records),
43 );
44
45 return $form;
46 }
47
48 /**
49 * Builds the fields for a single record on the drag-and-drop overview form.
50 *
51 * This internal function should not be called outside the module, unless you're
52 * feeling particularly cheeky.
53 *
54 * @ingroup forms
55 * @see scaffolding_example_overview_form()
56 */
57 function _scaffolding_example_overview_record_field($record) {
58 $form['record_id'] = array(
59 '#type' => 'hidden',
60 '#value' => $record['record_id'],
61 );
62
63 $form['title'] = array(
64 '#type' => 'markup',
65 '#value' => check_plain($record['title']),
66 );
67
68 $form['weight'] = array(
69 '#type' => 'weight',
70 '#default_value' => $record['weight'],
71 );
72
73 $form['operations'] = array(
74 '#type' => 'markup',
75 '#value' => _scaffolding_example_record_links($record),
76 );
77
78 return $form;
79 }
80
81 /**
82 * Build the edit and delete links for a single record.
83 *
84 * @see scaffolding_example_overview_form()
85 * @see scaffolding_example_overview_pager()
86 */
87 function _scaffolding_example_record_links($record) {
88 $path = drupal_get_path('module', 'scaffolding_example') . '/images/';
89 $links['edit'] = array(
90 'title' => theme('image', $path . 'text-editor.png', t('Edit')),
91 'href' => 'admin/build/scaffolding_example/' . $record['record_id'] . '/edit',
92 'html' => TRUE,
93 'query' => drupal_get_destination(),
94 );
95 $links['delete'] = array(
96 'title' => theme('image', $path . 'edit-delete.png', t('Delete')),
97 'href' => 'admin/build/scaffolding_example/' . $record['record_id'] . '/delete',
98 'html' => TRUE,
99 'query' => drupal_get_destination(),
100 );
101 return theme('links', $links);
102 }
103
104 /**
105 * General submit handler for the drag-and-drop overview form.
106 *
107 * Updates the weights of all records on the form.
108 *
109 * @ingroup formapi
110 * @see scaffolding_example_overview_form()
111 */
112 function scaffolding_example_overview_form_submit($form, &$form_state) {
113 $records = $form_state['values']['records'];
114 foreach ($records as $record) {
115 scaffolding_example_record_save($record);
116 }
117 }
118
119 /**
120 * Theme the drag-and-drop overview form.
121 *
122 * Arranges records in a table, and adds the css and js for draggable sorting.
123 *
124 * @ingroup themeable
125 * @ingroup forms
126 * @see scaffolding_example_overview_form()
127 */
128 function theme_scaffolding_example_overview_form($form) {
129 // Each record has a 'weight' that can be used to arrange it in relation to
130 // other records. Drupal's tabledrag.js library allows users to control these
131 // weights by dragging and dropping the records in a list -- we just need to
132 // add identifying CSS classes to key elements in the table.
133
134 $rows = array();
135 foreach (element_children($form['records']) as $key) {
136 $row = array();
137
138 // Render the hidden 'record id' field and the title of the record into the
139 // same column of the row.
140 $row[] = drupal_render($form['records'][$key]['record_id']) . drupal_render($form['records'][$key]['title']);
141
142 // Add an identifying CSS class to our weight field, as it's the one
143 // the tabledrag.js will be controlling. This can be anything we want it to
144 // be, we'll just tell the tabledrag.js library what it should look for.
145 $form['records'][$key]['weight']['#attributes']['class'] = 'scaffolding-example-weight';
146 $row[] = drupal_render($form['records'][$key]['weight']);
147
148 // Render the edit and delete links into their own column.
149 $row[] = drupal_render($form['records'][$key]['operations']);
150
151 // Add the new row to our collection of rows, and give it the 'draggable'
152 // class, indicating that it should be... well, draggable.
153 $rows[] = array(
154 'data' => $row,
155 'class' => 'draggable',
156 );
157 }
158
159 // If there were no records found, note the fact so users don't get confused
160 // by a completely empty table.
161 if (count($rows) == 0) {
162 $rows[] = array(t('No records have been added.'), '<span class="scaffolding-example-weight"></span>', '');
163 }
164
165 // Render a list of header titles, and our array of rows, into a table. Even
166 // we've already rendered all of our records, we always call drupal_render()
167 // on the form itself after we're done, so hidden security fields and other
168 // elements (like buttons) will appear properly at the bottom of the form.
169 $header = array(t('Title'), t('Weight'), t('Operations'));
170 $output = theme('table', $header, $rows, array('id' => 'scaffolding-example-overview'));
171 $output .= drupal_render($form);
172
173 // Now that we've built our output, tell Drupal to add the tabledrag.js library.
174 // We'll pass in the ID of the table, the behavior we want it to use, and the
175 // class that appears on each 'weight' form element it should be controlling.
176 drupal_add_tabledrag('scaffolding-example-overview', 'order', 'self', 'scaffolding-example-weight');
177
178 return $output;
179 }
180
181 /**
182 * Builds a sortable, paged overview of all records.
183 *
184 * This version of the overview page doesn't allow administrators to re-order
185 * records, but it breaks up long lists into groups of 20, with a convenient
186 * pager at the bottom of the list of records. This style of overview page is
187 * very useful when you know you'll be managing dozens (or hundreds) of records.
188 *
189 * Because this version of the overview page uses Drupal's helper functions to
190 * build a paged table with clickable column-headers, it can't use the module's
191 * build-in scaffolding_example_record_load_all() function. Instead, it will
192 * build its own SQL in a way that works with the Pager and Sortable Table APIs.
193 *
194 * @see scaffolding_example_overview_form()
195 */
196 function scaffolding_example_overview_pager() {
197 $sql = "SELECT * FROM {scaffolding_record}";
198 $header = array(
199 array('data' => t('Title'), 'field' => 'title', 'sort' => 'asc'),
200 array('data' => t('Weight'), 'field' => 'weight'),
201 t('Operations'),
202 );
203 $sql .= tablesort_sql($header);
204
205 $limit = 10;
206 $result = pager_query($sql, $limit);
207
208 while ($record = db_fetch_array($result)) {
209 $rows[] = check_plain($record['title']);
210 $rows[] = check_plain($record['weight']);
211 $rows[] = _scaffolding_example_record_links($record);
212 }
213 if (!isset($rows)) {
214 $rows[] = array(array('data' => t('No records have been added.'), 'colspan' => 3));
215 }
216
217 $output = theme('table', $header, $rows);
218 $output .= theme('pager', NULL, $limit);
219
220 return $output;
221 }
222
223 /**
224 * Build the record editing form.
225 *
226 * If a record is passed in, an edit form with both Save and Delete buttons will
227 * be built. Otherwise, a blank 'add new record' form, without the Delete button,
228 * will be built.
229 *
230 * @ingroup forms
231 * @see scaffolding_example_form_submit()
232 * @see scaffolding_example_form_delete()
233 */
234 function scaffolding_example_form(&$form_state, $record = array()) {
235 // Set the default values for a new item. By using += rather than =, we
236 // only overwrite array keys that have not yet been set. It's safe to use
237 // on both an empty array, and an incoming array with full or partial data.
238 $record += array(
239 'title' => '',
240 'content' => '',
241 'weight' => 0,
242 );
243
244 // If we're editing an existing record, we'll add a value field to the form
245 // containing the record's unique ID.
246 if (!empty($record['record_id'])) {
247 $form['record_id'] = array(
248 '#type' => 'value',
249 '#value' => $record['record_id'],
250 );
251 }
252
253 $form['title'] = array(
254 '#type' => 'textfield',
255 '#title' => t('Title'),
256 '#required' => TRUE,
257 '#default_value' => $record['title'],
258 );
259
260 $form['weight'] = array(
261 '#type' => 'weight',
262 '#title' => t('Weight'),
263 '#default_value' => $record['weight'],
264 );
265
266 $form['content'] = array(
267 '#type' => 'textarea',
268 '#title' => t('Content'),
269 '#required' => TRUE,
270 '#default_value' => $record['content'],
271 );
272
273 $form['buttons']['submit'] = array(
274 '#type' => 'submit',
275 '#value' => t('Submit'),
276 );
277
278 // Only show the delete button if we already have an ID. Set the delete
279 // button's submit handler to a custom function that should only fire if
280 // this button is clicked. In all other cases, the form will fall back to
281 // the default $form_id_submit() function.
282 if (!empty($record['record_id'])) {
283 $form['buttons']['delete'] = array(
284 '#type' => 'submit',
285 '#value' => t('Delete'),
286 '#submit' => array('scaffolding_example_form_delete'),
287 );
288 }
289
290 return $form;
291 }
292
293 /**
294 * General submit handler for Scaffolding's add/edit form.
295 *
296 * Simply passes incoming form values on to the module's CRUD save function,
297 * then redirects to the overview form.
298 *
299 * @ingroup formapi
300 * @see scaffolding_example_form()
301 */
302 function scaffolding_example_form_submit($form, &$form_state) {
303 $record = $form_state['values'];
304 scaffolding_example_record_save($record);
305 $form_state['redirect'] = 'admin/build/scaffolding_example';
306 }
307
308 /**
309 * Delete button submit handler for Scaffolding's add/edit form.
310 *
311 * Redirects to the 'delete record' confirmation page without performing any
312 * operations.
313 *
314 * @ingroup formapi
315 * @see scaffolding_example_form()
316 */
317 function scaffolding_example_form_delete($form, &$form_state) {
318 $form_state['redirect'] = 'admin/build/scaffolding_example/' . $form_state['values']['record_id'] . '/delete';
319 }
320
321 /**
322 * Build the delete confirmation form.
323 *
324 * A simple wrapper around Drupal's core confirm_form() function. Adds a value
325 * field to store the ID of the record being deleted.
326 *
327 * @ingroup forms
328 * @see scaffolding_example_delete_confirm_submit()
329 * @see confirm_form()
330 */
331 function scaffolding_example_delete_confirm(&$form_state, $record) {
332 $form['record_id'] = array(
333 '#type' => 'value',
334 '#value' => $record['record_id'],
335 );
336
337 return confirm_form($form,
338 t('Are you sure you want to delete %title?', array('%title' => $record['title'])),
339 isset($_GET['destination']) ? $_GET['destination'] : 'admin/build/scaffolding_example',
340 t('This action cannot be undone.'),
341 t('Delete'),
342 t('Cancel')
343 );
344 }
345
346 /**
347 * General submit handler for the delete confirmation form.
348 *
349 * Core's confirm_form() function adds the 'confirm' value element we check
350 * against to ensure the form was properly submitted. If it's there, delete
351 * the record and redirect to the overview form.
352 *
353 * @ingroup formapi
354 * @see scaffolding_example_form()
355 */
356
357 function scaffolding_example_delete_confirm_submit($form, &$form_state) {
358 if ($form_state['values']['confirm']) {
359 scaffolding_example_record_delete($form_state['values']['record_id']);
360 drupal_set_message(t('Your record was deleted.'));
361 }
362 $form_state['redirect'] = 'admin/build/scaffolding_example';
363 }

  ViewVC Help
Powered by ViewVC 1.1.2