/[drupal]/contributions/docs/developer/examples/node_example.module
ViewVC logotype

Contents of /contributions/docs/developer/examples/node_example.module

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


Revision 1.28 - (show annotations) (download) (as text)
Sun Oct 12 20:03:14 2008 UTC (13 months, 2 weeks ago) by davereid
Branch: MAIN
CVS Tags: HEAD
Changes since 1.27: +2 -2 lines
File MIME type: text/x-php
- Consistency for nodeapi_op with underscores
1 <?php
2 // $Id: node_example.module,v 1.27 2008/10/12 08:52:36 davereid Exp $
3
4 /**
5 * @file
6 * This is an example outlining how a module can be used to define a new
7 * node type.
8 *
9 * Our example node type will allow users to specify a "color" and a "quantity"
10 * for their nodes; some kind of rudimentary inventory-tracking system, perhaps?
11 * To store this extra information, we need an auxiliary database table.
12 *
13 * Database definition:
14 * @code
15 * CREATE TABLE node_example (
16 * vid int(10) unsigned NOT NULL default '0',
17 * nid int(10) unsigned NOT NULL default '0',
18 * color varchar(255) NOT NULL default '',
19 * quantity int(10) unsigned NOT NULL default '0',
20 * PRIMARY KEY (vid, nid),
21 * KEY `node_example_nid` (nid)
22 * )
23 * @endcode
24 */
25
26 /**
27 * Implementation of hook_node_info(). This function replaces hook_node_name()
28 * and hook_node_types() from 4.6. Drupal 5 expands this hook significantly.
29 *
30 * This is a required node hook. This function describes the nodes provided by
31 * this module.
32 *
33 * The required attributes are:
34 * - "name" provides a human readable name for the node,
35 * - "module" tells Drupal how the module's functions map to hooks (i.e. if the
36 * module is node_example_foo then node_example_foo_insert will be called
37 * when inserting the node).
38 * - "description" provides a brief description of the node type, which is
39 * show up when a user accesses the "Create content" page for that node type.
40 *
41 * The other optional, attributes:
42 * - "has_title" boolean that indicates whether or not this node type has a
43 * title field.
44 * - "title_label": the label for the title field of this content type.
45 * - "has_body": boolean that indicates whether or not this node type has a
46 * body field.
47 * - "body_label": the label for the body field of this content type.
48 * - "min_word_count": the minimum number of words for the body field to be
49 * considered valid for this content type.
50 */
51 function node_example_node_info() {
52 return array(
53 'node_example' => array(
54 'name' => t('Example node'),
55 'module' => 'node_example',
56 'description' => t("This is an example node type with a few fields."),
57 'has_title' => TRUE,
58 'title_label' => t('Example Title'),
59 'has_body' => TRUE,
60 'body_label' => t('Example Body'),
61 )
62 );
63 }
64
65 /**
66 * Implementation of hook_access().
67 *
68 * Node modules may implement node_access() to determine the operations
69 * users may perform on nodes. This example uses a very common access pattern.
70 */
71 function node_example_access($op, $node, $account) {
72 if ($op == 'create') {
73 return user_access('create example content', $account);
74 }
75
76 if ($op == 'update') {
77 if (user_access('edit any example content', $account) || (user_access('edit own example content', $account) && ($account->uid == $node->uid))) {
78 return TRUE;
79 }
80 }
81
82 if ($op == 'delete') {
83 if (user_access('delete any example content', $account) || (user_access('delete own example content', $account) && ($account->uid == $node->uid))) {
84 return TRUE;
85 }
86 }
87 }
88
89 /**
90 * Implementation of hook_perm().
91 *
92 * Since we are limiting the ability to create new nodes to certain users,
93 * we need to define what those permissions are here. We also define a permission
94 * to allow users to edit the nodes they created.
95 */
96 function node_example_perm() {
97 return array(
98 'create example content',
99 'delete own example content',
100 'delete any example content',
101 'edit own example content',
102 'edit any example content',
103 );
104 }
105
106 /**
107 * Implementation of hook_form().
108 *
109 * Now it's time to describe the form for collecting the information
110 * specific to this node type. This hook requires us to return an array with
111 * a sub array containing information for each element in the form.
112 */
113 function node_example_form(&$node) {
114 // The site admin can decide if this node type has a title and body, and how
115 // the fields should be labeled. We need to load these settings so we can
116 // build the node form correctly.
117 $type = node_get_types('type', $node);
118
119 if ($type->has_title) {
120 $form['title'] = array(
121 '#type' => 'textfield',
122 '#title' => check_plain($type->title_label),
123 '#required' => TRUE,
124 '#default_value' => $node->title,
125 '#weight' => -5
126 );
127 }
128
129 if ($type->has_body) {
130 // In Drupal 6, we can use node_body_field() to get the body and filter
131 // elements. This replaces the old textarea + filter_form() method of
132 // setting this up. It will also ensure the teaser splitter gets set up
133 // properly.
134 $form['body_field'] = node_body_field($node, $type->body_label, $type->min_word_count);
135 }
136
137 // Now we define the form elements specific to our node type.
138 $form['color'] = array(
139 '#type' => 'textfield',
140 '#title' => t('Color'),
141 '#default_value' => isset($node->color) ? $node->color : '',
142 );
143 $form['quantity'] = array(
144 '#type' => 'textfield',
145 '#title' => t('Quantity'),
146 '#default_value' => isset($node->quantity) ? $node->quantity : 0,
147 '#size' => 10,
148 '#maxlength' => 10
149 );
150
151 return $form;
152 }
153
154 /**
155 * Implementation of hook_validate().
156 *
157 * Our "quantity" field requires a number to be entered. This hook lets
158 * us ensure that the user entered an appropriate value before we try
159 * inserting anything into the database.
160 *
161 * Errors should be signaled with form_set_error().
162 */
163 function node_example_validate(&$node) {
164 if ($node->quantity) {
165 if (!is_numeric($node->quantity)) {
166 form_set_error('quantity', t('The quantity must be a number.'));
167 }
168 }
169 else {
170 // Let an empty field mean "zero."
171 $node->quantity = 0;
172 }
173 }
174
175 /**
176 * Implementation of hook_insert().
177 *
178 * As a new node is being inserted into the database, we need to do our own
179 * database inserts.
180 */
181 function node_example_insert($node) {
182 db_query("INSERT INTO {node_example} (vid, nid, color, quantity) VALUES (%d, %d, '%s', %d)", $node->vid, $node->nid, $node->color, $node->quantity);
183 }
184
185 /**
186 * Implementation of hook_update().
187 *
188 * As an existing node is being updated in the database, we need to do our own
189 * database updates.
190 */
191 function node_example_update($node) {
192 // if this is a new node or we're adding a new revision,
193 if ($node->revision) {
194 node_example_insert($node);
195 }
196 else {
197 db_query("UPDATE {node_example} SET color = '%s', quantity = %d WHERE vid = %d", $node->color, $node->quantity, $node->vid);
198 }
199 }
200
201 /**
202 * Implementation of hook_nodeapi().
203 *
204 * When a node revision is deleted, we need to remove the corresponding record
205 * from our table. The only way to handle revision deletion is by implementing
206 * hook_nodeapi().
207 */
208 function node_example_nodeapi(&$node, $op, $teaser, $page) {
209 switch ($op) {
210 case 'delete_revision':
211 // Notice that we're matching a single revision based on the node's vid.
212 db_query('DELETE FROM {node_example} WHERE vid = %d', $node->vid);
213 break;
214 }
215 }
216
217 /**
218 * Implementation of hook_delete().
219 *
220 * When a node is deleted, we need to remove all related records from out table.
221 */
222 function node_example_delete($node) {
223 // Notice that we're matching all revision, by using the node's nid.
224 db_query('DELETE FROM {node_example} WHERE nid = %d', $node->nid);
225 }
226
227 /**
228 * Implementation of hook_load().
229 *
230 * Now that we've defined how to manage the node data in the database, we
231 * need to tell Drupal how to get the node back out. This hook is called
232 * every time a node is loaded, and allows us to do some loading of our own.
233 */
234 function node_example_load($node) {
235 $additions = db_fetch_object(db_query('SELECT color, quantity FROM {node_example} WHERE vid = %d', $node->vid));
236 return $additions;
237 }
238
239 /**
240 * Implementation of hook_view().
241 *
242 * This is a typical implementation that simply runs the node text through
243 * the output filters.
244 */
245 function node_example_view($node, $teaser = FALSE, $page = FALSE) {
246 $node = node_prepare($node, $teaser);
247 $node->content['myfield'] = array(
248 '#value' => theme('node_example_order_info', $node),
249 '#weight' => 1,
250 );
251
252 return $node;
253 }
254
255 /**
256 * Implementation of hook_theme().
257 *
258 * This lets us tell Drupal about our theme functions and their arguments.
259 */
260 function node_example_theme() {
261 return array(
262 'node_example_order_info' => array(
263 'arguments' => array('node'),
264 ),
265 );
266 }
267
268 /**
269 * A custom theme function.
270 *
271 * By using this function to format our node-specific information, themes
272 * can override this presentation if they wish. We also wrap the default
273 * presentation in a CSS class that is prefixed by the module name. This
274 * way, style sheets can modify the output without requiring theme code.
275 */
276 function theme_node_example_order_info($node) {
277 $output = '<div class="node_example_order_info">';
278 $output .= t('The order is for %quantity %color items.', array('%quantity' => check_plain($node->quantity), '%color' => check_plain($node->color)));
279 $output .= '</div>';
280 return $output;
281 }

  ViewVC Help
Powered by ViewVC 1.1.2