node.module 39.6 KB
Newer Older
Dries's avatar
 
Dries committed
1
<?php
2
// $Id$
Dries's avatar
 
Dries committed
3

Dries's avatar
   
Dries committed
4
5
6
7
8
function node_help() {
  global $mod;

  if ($mod == "node") {
    foreach (module_list() as $name) {
Dries's avatar
   
Dries committed
9
      if (module_hook($name, "node") && $name != "node") {
Dries's avatar
   
Dries committed
10
        print "<h3>". t("%module type", array("%module" => ucfirst(module_invoke($name, "node", "name")))). "</h3>";
Dries's avatar
   
Dries committed
11
12
13
14
15
16
        print module_invoke($name, "help");
      }
    }
  }
}

17
function node_system($field){
Kjartan's avatar
Kjartan committed
18
  $system["description"] = t("The core that allows content to be submitted to the site.");
19
20
21
  return $system[$field];
}

Dries's avatar
   
Dries committed
22
23
24
25
/*
** Accepts a DB result object which can be used to fetch node objects.
** Returns an HTML list suitable as content for a block.
*/
Dries's avatar
   
Dries committed
26
27
function node_title_list($result, $title = NULL) {
  // no queries if site is in distress
Dries's avatar
   
Dries committed
28
  if (module_exist("statistics") && throttle_status() > 3) {
Dries's avatar
   
Dries committed
29
30
31
32
    return;
  }

  while ($node = db_fetch_object($result)) {
Dries's avatar
   
Dries committed
33
    $number = module_invoke("comment", "num_all", $node->nid);
Dries's avatar
   
Dries committed
34
    $items[] = l($node->title, "node/view/$node->nid", array("title" => t("Comments: %number", array("%number" => $number))));
Dries's avatar
   
Dries committed
35
36
  }

Dries's avatar
   
Dries committed
37
38
39
40
41
  return theme("theme_node_list", $items, $title);
}

function theme_node_list($items, $title) {
  return theme("theme_item_list",$items,$title);
Dries's avatar
   
Dries committed
42
43
}

Dries's avatar
   
Dries committed
44
45
46
47
48
49
50
// Update the 'last viewed' timestamp of the specified node for current user.
function node_tag_new($nid) {
  global $user;

  if ($user->uid) {
    $nid = check_query($nid);

Dries's avatar
   
Dries committed
51
    $result = db_query("SELECT timestamp FROM history WHERE uid = %d AND nid = %d", $user->uid, $nid);
Dries's avatar
   
Dries committed
52
    if (db_fetch_object($result)) {
Dries's avatar
   
Dries committed
53
      db_query("UPDATE history SET timestamp = %d WHERE uid = %d AND nid = %d", time(), $user->uid, $nid);
Dries's avatar
   
Dries committed
54
55
    }
    else {
Dries's avatar
   
Dries committed
56
      db_query("INSERT INTO history (uid, nid, timestamp) VALUES (%d, %d, %d)", $user->uid, $nid, time());
Dries's avatar
   
Dries committed
57
58
59
60
61
62
63
64
65
66
67
    }
  }
}

/*
** Retrieves the timestamp at which the current user last viewed the
** specified node.
*/
function node_last_viewed($nid) {
  global $user;

Dries's avatar
   
Dries committed
68
  $history = db_fetch_object(db_query("SELECT timestamp FROM history WHERE uid = '$user->uid' AND nid = %d", $nid));
Dries's avatar
   
Dries committed
69
70
71
72
73
74
75
76
77
78
79
80
81
  return ($history->timestamp ? $history->timestamp : 0);
}

/**
 * Determines whether the supplied timestamp is newer than the user's last view of a given node
 *
 * @param $nid       node-id twhose history supplies the 'last viewed' timestamp
 * @param $timestamp time which is compared against node's 'last veiwed' timestamp
*/
function node_is_new($nid, $timestamp) {
  global $user;
  static $cache;

Dries's avatar
Dries committed
82
  if (!isset($cache[$nid])) {
Dries's avatar
   
Dries committed
83
    if ($user->uid) {
Dries's avatar
   
Dries committed
84
      $history = db_fetch_object(db_query("SELECT timestamp FROM history WHERE uid = %d AND nid = %d", $user->uid, $nid));
Dries's avatar
   
Dries committed
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
      $cache[$nid] = $history->timestamp ? $history->timestamp : 0;
    }
    else {
      $cache[$nid] = time();
    }
  }

  if ($timestamp > $cache[$nid]) {
    return 1;
  }
  else {
    return 0;
  }
}

Dries's avatar
   
Dries committed
100
101
function node_teaser($body) {

Dries's avatar
   
Dries committed
102
103
104
105
106
107
108
109
110
111
  $size = variable_get("teaser_length", 600);

  /*
  ** If the size is zero, teasers are disabled so we
  ** return the entire body.
  */

  if ($size == 0) {
    return $body;
  }
Dries's avatar
   
Dries committed
112
113
114
115
116
117
118
119
120
121

  /*
  ** If we have a short body, return the entire body:
  */

  if (strlen($body) < $size) {
    return $body;
  }

  /*
Dries's avatar
   
Dries committed
122
  ** If a valid delimiter has been specified, use it to
Dries's avatar
   
Dries committed
123
124
  ** chop of the teaser.  The delimiter can be outside
  ** the allowed range but no more than a factor two.
Dries's avatar
   
Dries committed
125
126
  */

Dries's avatar
Dries committed
127
  $delimiter = strpos($body, "<!--break-->");
Dries's avatar
   
Dries committed
128
  if ($delimiter > 0 && $delimiter < $size * 2) {
Dries's avatar
   
Dries committed
129
130
131
132
133
134
135
    return substr($body, 0, $delimiter);
  }

  /*
  ** In some cases no delimiter has been specified (eg.
  ** when posting using the Blogger API) in which case
  ** we try to split at paragraph boundaries.
Dries's avatar
   
Dries committed
136
137
  */

Dries's avatar
   
Dries committed
138
  if ($length = strpos($body, "<br />", $size)) {
Dries's avatar
   
Dries committed
139
    return substr($body, 0, $length);
Dries's avatar
   
Dries committed
140
141
142
  }

  if ($length = strpos($body, "<br>", $size)) {
Dries's avatar
   
Dries committed
143
    return substr($body, 0, $length);
Dries's avatar
   
Dries committed
144
145
146
  }

  if ($length = strpos($body, "</p>", $size)) {
Dries's avatar
   
Dries committed
147
148
149
150
151
    return substr($body, 0, $length);
  }

  if ($length = strpos($body, "\n", $size)) {
    return substr($body, 0, $length);
Dries's avatar
   
Dries committed
152
153
  }

Dries's avatar
   
Dries committed
154
  /*
Dries's avatar
   
Dries committed
155
  ** When even the first paragraph is too long, try to
Dries's avatar
   
Dries committed
156
  ** split at the end of the next sentence.
Dries's avatar
   
Dries committed
157
158
  */

Dries's avatar
   
Dries committed
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
  if ($length = strpos($body, ". ", $size)) {
    return substr($body, 0, $length + 1);
  }

  if ($length = strpos($body, "! ", $size)) {
    return substr($body, 0, $length + 1);
  }

  if ($length = strpos($body, "? ", $size)) {
    return substr($body, 0, $length + 1);
  }

  /*
  ** Nevermind, we split it the hard way ...
  */
Dries's avatar
   
Dries committed
174

Dries's avatar
   
Dries committed
175
  return substr($body, 0, $size);
Dries's avatar
   
Dries committed
176
177
}

178
function node_invoke(&$node, $hook, $arg = 0) {
Dries's avatar
   
Dries committed
179
  if (is_array($node)) {
180
    $function = $node["type"] ."_$hook";
Dries's avatar
   
Dries committed
181
182
  }
  else if (is_object($node)) {
183
    $function = $node->type ."_$hook";
Dries's avatar
   
Dries committed
184
185
  }
  else if (is_string($node)) {
186
    $function = $node ."_$hook";
Dries's avatar
   
Dries committed
187
188
189
190
191
192
193
  }

  if (function_exists($function)) {
    return ($arg ? $function($node, $arg) : $function($node));
  }
}

194
function node_invoke_all(&$node, $hook, $op, $arg = 0) {
195
196
  $return = array();
  foreach (module_list() as $name) {
197
    if ((module_hook($name, "node") || module_hook($name, "nodeapi")) && module_hook($name, $hook)) {
198
199
200
201
202
203
204
205
206
207
      $function = $name ."_". $hook;
      $result = $function($node, $op, $arg);
      if (isset($result)) {
        $return = array_merge($return, $result);
      }
    }
  }
  return $return;
}

Dries's avatar
   
Dries committed
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
function node_load($conditions) {

  /*
  ** Turn the conditions into a query:
  */

  foreach ($conditions as $key => $value) {
    $cond[] = "n.". check_query($key) ." = '". check_query($value) ."'";
  }

  /*
  ** Retrieve the node:
  */

  $node = db_fetch_object(db_query("SELECT n.*, u.uid, u.name FROM node n LEFT JOIN users u ON u.uid = n.uid WHERE ". implode(" AND ", $cond)));

  /*
  ** Unserialize the revisions field:
  */

  if ($node->revisions) {
    $node->revisions = unserialize($node->revisions);
  }

  /*
  ** Call the node specific callback (if any) and piggy-back the
  ** results to the node or overwrite some values:
  */

  if ($extra = module_invoke($node->type, "load", $node)) {
    foreach ($extra as $key => $value) {
      $node->$key = $value;
    }
  }

  return $node;
}

246
function node_save($node) {
Dries's avatar
   
Dries committed
247

248
249
250
251
  /*
  ** Fetch fields to save to node table:
  */
  $fields = node_invoke_all($node, "nodeapi", "fields");
Dries's avatar
   
Dries committed
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270

  /*
  ** Serialize the revisions field:
  */

  if ($node->revisions) {
    $node->revisions = serialize($node->revisions);
  }

  /*
  ** Apply filters to some default node fields:
  */

  if (empty($node->nid)) {

    /*
    ** Insert a new node:
    */

Dries's avatar
   
Dries committed
271
    // Set some required fields:
272
273
274
    if (!$node->created) {
      $node->created = time();
    }
Dries's avatar
   
Dries committed
275
    $node->changed = time();
Dries's avatar
   
Dries committed
276
    $node->nid = db_next_id("node_nid");
Dries's avatar
   
Dries committed
277

Dries's avatar
   
Dries committed
278
    // Prepare the query:
Dries's avatar
   
Dries committed
279
280
281
282
283
284
285
    foreach ($node as $key => $value) {
      if (in_array($key, $fields)) {
        $k[] = check_query($key);
        $v[] = "'". check_query($value) ."'";
      }
    }

Dries's avatar
   
Dries committed
286
    // Insert the node into the database:
Dries's avatar
   
Dries committed
287
288
    db_query("INSERT INTO node (". implode(", ", $k) .") VALUES (". implode(", ", $v) .")");

Dries's avatar
   
Dries committed
289
    // Call the node specific callback (if any):
290
291
    node_invoke($node, "insert");
    node_invoke_all($node, "nodeapi", "insert");
Dries's avatar
   
Dries committed
292
293
294
295
296
297
298
  }
  else {

    /*
    ** Update an existing node:
    */

Dries's avatar
   
Dries committed
299
    // Set some required fields:
Dries's avatar
   
Dries committed
300
301
    $node->changed = time();

Dries's avatar
   
Dries committed
302
    // Prepare the query:
Dries's avatar
   
Dries committed
303
304
305
306
307
308
    foreach ($node as $key => $value) {
      if (in_array($key, $fields)) {
        $q[] = check_query($key) ." = '". check_query($value) ."'";
      }
    }

Dries's avatar
   
Dries committed
309
    // Update the node in the database:
Dries's avatar
   
Dries committed
310
311
    db_query("UPDATE node SET ". implode(", ", $q) ." WHERE nid = '$node->nid'");

Dries's avatar
   
Dries committed
312
    // Call the node specific callback (if any):
313
314
    node_invoke($node, "update");
    node_invoke_all($node, "nodeapi", "update");
Dries's avatar
   
Dries committed
315
316
  }

Dries's avatar
   
Dries committed
317
  /*
Dries's avatar
   
Dries committed
318
319
  ** Clear the cache so an anonymous poster can see the node being
  ** added or updated.
Dries's avatar
   
Dries committed
320
321
322
323
  */

  cache_clear_all();

Dries's avatar
   
Dries committed
324
325
326
327
328
329
330
331
332
  /*
  ** Return the node ID:
  */

  return $node->nid;

}

function node_view($node, $main = 0) {
Dries's avatar
   
Dries committed
333

Dries's avatar
   
Dries committed
334

Dries's avatar
   
Dries committed
335
  $node = array2object($node);
Dries's avatar
   
Dries committed
336

Dries's avatar
   
Dries committed
337
338
  /*
  ** Remove the delimiter (if any) that seperates the teaser from the
Dries's avatar
Dries committed
339
  ** body. TODO: this strips legitimate uses of '<!--break-->' also.
Dries's avatar
   
Dries committed
340
341
  */

Dries's avatar
Dries committed
342
  $node->body = str_replace("<!--break-->", "", $node->body);
Dries's avatar
   
Dries committed
343

Dries's avatar
   
Dries committed
344
345
346
347
348
349
350
351
352
353
354
355
356
357
  /*
  ** The "view" hook can be implemented to overwrite the default function
  ** to display nodes.
  */

  if (module_hook($node->type, "view")) {
    node_invoke($node, "view", $main);
  }
  else {

    /*
    ** Default behavior:
    */

Dries's avatar
   
Dries committed
358
    theme("node", $node, $main);
Dries's avatar
   
Dries committed
359
360
361
  }
}

Dries's avatar
   
Dries committed
362

Dries's avatar
   
Dries committed
363
function node_show($nid, $cid) {
Dries's avatar
   
Dries committed
364
  global $revision;
Dries's avatar
   
Dries committed
365
366
367
368
369
370
371
372
373
374
375
376
377

  $node = node_load(array("status" => 1, "nid" => $nid));

  if (node_access("view", $node)) {
    if (isset($revision)) {
      $node = $node->revisions[$revision]["node"];
    }

    node_view($node);

    if (function_exists("comment_render") && $node->comment) {
      comment_render($node, $cid);
    }
Dries's avatar
   
Dries committed
378
379
380
381
382
383

    /*
    ** Update the history table, stating that this user viewed this node.
    */

    node_tag_new($node->nid);
Dries's avatar
   
Dries committed
384
385
386
  }
}

Dries's avatar
   
Dries committed
387
388
function node_access($op, $node = 0) {

Dries's avatar
   
Dries committed
389
390
  if (user_access("administer nodes")) {
    return 1;
Dries's avatar
   
Dries committed
391
392
  }

Dries's avatar
   
Dries committed
393
394
395
  /*
  ** Convert the node to an object if necessary:
  */
Dries's avatar
   
Dries committed
396

Dries's avatar
   
Dries committed
397
  $node = array2object($node);
Dries's avatar
   
Dries committed
398

Dries's avatar
   
Dries committed
399
400
401
  /*
  ** Construct a function:
  */
Dries's avatar
   
Dries committed
402

Dries's avatar
   
Dries committed
403
404
405
406
407
408
  if ($node->type) {
    $type = $node->type;
  }
  else {
    $type = $node;
  }
Dries's avatar
   
Dries committed
409

Dries's avatar
   
Dries committed
410
  $function = $type ."_access";
Dries's avatar
   
Dries committed
411

Dries's avatar
   
Dries committed
412
413
414
415
416
  if (function_exists($function)) {
    return $function($op, $node);
  }
  else {
    return 0;
Dries's avatar
   
Dries committed
417
418
419
  }
}

Dries's avatar
   
Dries committed
420
function node_perm() {
Dries's avatar
   
Dries committed
421
  return array("administer nodes", "access content");
Dries's avatar
   
Dries committed
422
423
}

Dries's avatar
   
Dries committed
424
function node_search($keys) {
Dries's avatar
   
Dries committed
425
  global $PHP_SELF;
Dries's avatar
   
Dries committed
426

Kjartan's avatar
Kjartan committed
427
428
429
430
431
432
433
434
435
436
437
438
  // Return the results of performing a search using the indexed search
  // for this particular type of node.
  //
  // Pass an array to the "do_search" function which dictates what it
  // will search through, and what it will search for
  //
  // "keys"'s value is the keywords entered by the user
  //
  // "type"'s value is used to identify the node type in the search
  // index.
  //
  // "select"'s value is used to relate the data from the specific nodes
Dries's avatar
   
Dries committed
439
  // table to the data that the search_index table has in it, and the the
Kjartan's avatar
Kjartan committed
440
441
  // do_search functino will rank it.
  //
Dries's avatar
   
Dries committed
442
  // The select must always provide the following fields - lno, title,
Kjartan's avatar
Kjartan committed
443
444
  // created, uid, name, count
  //
Kjartan's avatar
Kjartan committed
445
  $find = do_search(array("keys" => $keys, "type" => "node", "select" => "select s.lno as lno, n.title as title, n.created as created, u.uid as uid, u.name as name, s.count as count FROM search_index s, node n LEFT JOIN users u ON n.uid = u.uid WHERE s.lno = n.nid AND s.type = 'node' AND s.word like '%' AND n.status = 1"));
Dries's avatar
   
Dries committed
446

Dries's avatar
   
Dries committed
447
448
449
  return $find;
}

450
function node_settings() {
Dries's avatar
   
Dries committed
451
  $output .= form_select(t("Number of posts on main page"), "default_nodes_main", variable_get("default_nodes_main", 10), array(1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 =>  5, 6 => 6, 7 => 7, 8 => 8, 9 => 9, 10 => 10, 15 => 15, 20 => 20, 25 => 25, 30 => 30), t("The default maximum number of posts to display on overview pages such as the main page."));
Dries's avatar
   
Dries committed
452
  $output .= form_select(t("Length of trimmed posts"), "teaser_length", variable_get("teaser_length", 600), array(0 => t("Unlimited"), 200 => t("200 characters"), 400 => t("400 characters"), 600 => t("600 characters"), 800 => t("800 characters"), 1000 => t("1000 characters"), 1200 => t("1200 characters"), 1400 => t("1400 characters"), 1600 => t("1600 characters"), 1800 => t("1800 characters"), 2000 => t("2000 characters")), t("The maximum number of characters used in the trimmed version of a post.  Drupal will use this setting to determine at which offset long posts should be trimmed.  The trimmed version of a post is typically used as a teaser when displaying the post on the main page, in XML feeds, etc.  To disable teasers, set to 'Unlimited'."));
Dries's avatar
   
Dries committed
453
454
455
  return $output;
}

Dries's avatar
CHANGES    
Dries committed
456
function node_conf_filters() {
Dries's avatar
   
Dries committed
457
  $output .= form_select(t("Filter HTML tags"), "filter_html", variable_get("filter_html", 0), array(t("Disabled"), t("Enabled")), t("Filter HTML and PHP tags in user-contributed content."));
458
  $output .= form_textfield(t("Allowed HTML tags"), "allowed_html", variable_get("allowed_html", "<a> <b> <dd> <dl> <dt> <i> <li> <ol> <u> <ul>"), 64, 255, t("If enabled, optionally specify tags which should not be stripped.  'STYLE' attributes, 'ON' attributes and unclosed tags are always stripped."));
Dries's avatar
   
Dries committed
459
  $output .= "<hr />";
Dries's avatar
   
Dries committed
460
461
  // $output .= form_select(t("Enable link tags"), "filter_link", variable_get("filter_link", 0), array(t("Disabled"), t("Enabled")), t("Substitute special [[nodesubject|text]] tags. Your browser will display 'text', and when you click on it your browser will open the node with the subject 'nodesubject'. Please be aware that you'll need to copy the subject of the target node exactly in order to use this feature."));
  // $output .= "<hr />";
Dries's avatar
CHANGES    
Dries committed
462
463
464
465
466
467
468
469
470
  return $output;
}

function node_filter_html($text) {
  $text = strip_tags($text, variable_get("allowed_html", ""));
  return $text;
}

function node_filter_link($text) {
471
  $pat = '\[{2}([^\|]+)(\|([^\|]+)?)?\]{2}';                   // [link|description]
Dries's avatar
   
Dries committed
472
//  $dst = str_replace('%5C1', '\\1', format_tag('\\1', '\\3')); // [link|description]
473
  return ereg_replace($pat, $dst, $text);
Dries's avatar
   
Dries committed
474
475
}

Dries's avatar
   
Dries committed
476
function node_comment_mode($nid) {
Dries's avatar
   
Dries committed
477
478
  static $comment_mode;
  if (!isset($comment_mode[$nid])) {
Dries's avatar
   
Dries committed
479
    $comment_mode[$nid] = db_result(db_query("SELECT comment FROM node WHERE nid = %d", $nid));
Dries's avatar
   
Dries committed
480
481
  }
  return $comment_mode[$nid];
Dries's avatar
   
Dries committed
482
483
}

Dries's avatar
CHANGES    
Dries committed
484
function node_filter($text) {
Dries's avatar
   
Dries committed
485
486
487
488
489
  $text = preg_replace("/\Wstyle\s*=[^>]+?>/i", ">", $text);
  $text = preg_replace("/\Won[a-z]+\s*=[^>]+?>/i", ">", $text);
  $text = preg_replace("/\Wsrc\s*=[\s'\"]*javascript[^>]+?>/i", ">", $text);
  $text = preg_replace("/\Whref\s*=[\s'\"]*javascript:[^>]+?>/i", ">", $text);

Dries's avatar
CHANGES    
Dries committed
490
  if (variable_get("filter_html", 0)) $text = node_filter_html($text);
Dries's avatar
   
Dries committed
491
  // if (variable_get("filter_link", 0)) $text = node_filter_link($text);
Dries's avatar
   
Dries committed
492
493

  return trim($text);
Dries's avatar
CHANGES    
Dries committed
494
495
}

496
function node_link($type, $node = 0, $main = 0) {
Dries's avatar
   
Dries committed
497

Dries's avatar
   
Dries committed
498
499
  $links = array();

Dries's avatar
   
Dries committed
500
  if ($type == "page") {
Dries's avatar
   
Dries committed
501
    $links[] = l(t("submit"), "node/add", array("title" => t("Submit or suggest new content.")));
Dries's avatar
   
Dries committed
502
503
  }

Dries's avatar
   
Dries committed
504
  if ($type == "node") {
Kjartan's avatar
Kjartan committed
505
506
507
    if ($node->links) {
      $links = $node->links;
    }
Dries's avatar
   
Dries committed
508

509
    if ($main == 1 && $node->teaser && $node->teaser != $node->body) {
Dries's avatar
   
Dries committed
510
      $links[] = l(t("read more"), "node/view/$node->nid", array("title" => t("Read the rest of this posting.")));
Dries's avatar
   
Dries committed
511
    }
Dries's avatar
   
Dries committed
512
513

    if (user_access("administer nodes")) {
Dries's avatar
   
Dries committed
514
       $links[] = l(t("administer"), "admin/node/edit/$node->nid", array("title" => t("Administer this node.")));
Dries's avatar
   
Dries committed
515
    }
Dries's avatar
   
Dries committed
516
517
  }

Dries's avatar
   
Dries committed
518
  if ($type == "admin" && user_access("administer nodes")) {
Dries's avatar
   
Dries committed
519
    $help["search"] = "On this page you can search for a post.  For example, one may search for 'br' and Drupal might return 'bread brakers', 'our daily bread' and 'brenda'.";
Dries's avatar
   
Dries committed
520

521
    menu("admin/node", "content management", "node_admin");
Dries's avatar
   
Dries committed
522
523
    menu("admin/node/nodes", "post overview");
    menu("admin/node/nodes/0", "new or updated posts", "node_admin", NULL, 0);
524
    menu("admin/node/nodes/1", "approval queue", "node_admin", NULL, 1);
Dries's avatar
   
Dries committed
525
    menu("admin/node/search", "search posts", "node_admin", $help["search"], 8);
Dries's avatar
   
Dries committed
526
527
    menu("admin/node/help", "help", "node_help", NULL, 9);
    menu("admin/node/edit", "edit node", "node_admin", NULL, 0, 1);
528
    menu("admin/node/settings", "content settings", "node_admin", NULL, 8);
Dries's avatar
   
Dries committed
529
530
  }

Dries's avatar
   
Dries committed
531
  return $links;
Dries's avatar
   
Dries committed
532
533
}

Dries's avatar
   
Dries committed
534
function node_admin_edit($node) {
Dries's avatar
   
Dries committed
535

Dries's avatar
   
Dries committed
536
  if (is_numeric($node)) {
Dries's avatar
   
Dries committed
537
    $node = node_load(array("nid" => $node));
Dries's avatar
   
Dries committed
538
  }
Dries's avatar
   
Dries committed
539

Dries's avatar
   
Dries committed
540
541
542
  /*
  ** Edit node:
  */
Dries's avatar
   
Dries committed
543

Dries's avatar
   
Dries committed
544
  $output .= "<h3>". t("Edit %module", array("%module" => module_invoke($node->type, "node", "name"))) ."</h3>";
Dries's avatar
   
Dries committed
545

Dries's avatar
   
Dries committed
546
  $output .= node_form($node);
Dries's avatar
   
Dries committed
547

Dries's avatar
   
Dries committed
548
549
550
551
552
553
554
  /*
  ** Edit revisions:
  */

  if ($node->revisions) {
    $output .= "<h3>". t("Edit revisions") ."</h3>";
    $output .= "<table border=\"1\" cellpadding=\"2\" cellspacing=\"2\">";
Dries's avatar
   
Dries committed
555
    $output .= " <tr><th>". t("older revisions") ."</th><th colspan=\"3\">". t("operations") ."</th></tr>";
Dries's avatar
   
Dries committed
556
    foreach ($node->revisions as $key => $revision) {
Dries's avatar
Dries committed
557
      $output .= " <tr><td>". t("revision #%r revised by %u on %d", array("%r" => $key, "%u" => format_name(user_load(array("uid" => $revision["uid"]))), "%d" => format_date($revision["timestamp"], "small"))) . ($revision["history"] ? "<br /><small>". $revision["history"] ."</small>" : "") ."</td><td>". l(t("view revision"), "node/view/$node->nid", array(), "revision=$key") ."</td><td>". l(t("rollback revision"), "admin/node/rollback+revision/$node->nid/$key") ."</td><td>". l(t("delete revision"), "admin/node/delete+revision/$node->nid/$key") ."</td></tr>";
Dries's avatar
   
Dries committed
558
559
560
561
    }
    $output .= "</table>";
  }

Dries's avatar
   
Dries committed
562
  /*
Dries's avatar
   
Dries committed
563
  ** Display the node form extensions:
Dries's avatar
   
Dries committed
564
  */
Dries's avatar
   
Dries committed
565

Dries's avatar
   
Dries committed
566
567
  foreach (module_list() as $name) {
    $output .= module_invoke($name, "node_link", $node);
Dries's avatar
Dries committed
568
569
  }

Dries's avatar
   
Dries committed
570
  return $output;
Dries's avatar
   
Dries committed
571
572
573

}

Dries's avatar
   
Dries committed
574
function node_admin_nodes() {
Dries's avatar
   
Dries committed
575

Dries's avatar
   
Dries committed
576
  $query = arg(3);
Dries's avatar
   
Dries committed
577
  $queries = array("ORDER BY n.changed DESC", "WHERE n.status = 0 OR n.moderate = 1 ORDER BY n.changed DESC");
Dries's avatar
Dries committed
578

Dries's avatar
   
Dries committed
579
  $result = pager_query("SELECT n.*, u.name, u.uid FROM node n LEFT JOIN users u ON n.uid = u.uid ". $queries[$query ? $query : 0], 50);
Dries's avatar
   
Dries committed
580

Dries's avatar
   
Dries committed
581
582
  $header = array(t("title"), t("type"), t("author"), t("status"), array("data" => t("operations"), "colspan" => 2));

Dries's avatar
   
Dries committed
583
  while ($node = db_fetch_object($result)) {
Dries's avatar
   
Dries committed
584
    $rows[] = array(l($node->title, "node/view/$node->nid") ." ". (node_is_new($node->nid, $node->changed) ? theme_mark() : ""), module_invoke($node->type, "node", "name"), format_name($node), ($node->status ? t("published") : t("not published")), l(t("edit node"), "admin/node/edit/$node->nid"), l(t("delete node"), "admin/node/delete/$node->nid"));
Dries's avatar
   
Dries committed
585
  }
Dries's avatar
   
Dries committed
586

Dries's avatar
   
Dries committed
587
588
589
  if ($pager = pager_display(NULL, 50, 0, "admin")) {
    $rows[] = array(array("data" => $pager, "colspan" => 6));
  }
Dries's avatar
   
Dries committed
590

Dries's avatar
   
Dries committed
591
  return table($header, $rows);
Dries's avatar
Dries committed
592
593
}

594
595
596
597
598
599
/*
**
*/

function node_admin_settings($edit) {
  global $op;
Kjartan's avatar
Kjartan committed
600

601
602
603
604
605
606
607
608
  if ($op == t("Save configuration")) {
    /*
    ** Save the configuration options:
    */

    foreach ($edit as $name => $value) {
      variable_set($name, $value);
    }
609
    $output = status(t("the content settings have been saved."));
610
611
612
613
614
615
616
617
618
619
  }

  if ($op == t("Reset to defaults")) {
    /*
    ** Reset the configuration options to their default value:
    */

    foreach ($edit as $name => $value) {
      variable_del($name);
    }
620
    $output = status(t("the content settings have been reset to their default values."));
621
622
  }

623
  $header = array_merge(array(t("content type")), array_keys(node_invoke_all($node, "nodeapi", "settings")));
624
625
626
627
628
629
630
631
632
633
  foreach (module_list() as $name) {
    if (module_hook($name, "node")) {
      $node->type = $name;
      $cols = array();
      foreach (node_invoke_all($node, "nodeapi", "settings") as $setting) {
        $cols[] = array("data" => $setting, "align" => "center", "width" => 55);
      }
      $rows[] = array_merge(array(module_invoke($name, "node", "name")), $cols);
    }
  }
Kjartan's avatar
Kjartan committed
634

635
  $output .= table($header, $rows);
636

637
  /* This is an idea for the future.
638
639
640
  foreach (module_list() as $name) {
    if (module_hook($name, "node")) {
      $node->type = $name;
Kjartan's avatar
Kjartan committed
641

642
643
644
645
646
647
648
649
650
651
      // Create table() data:
      $header = array_keys(node_invoke_all($node, "nodeapi", "settings"));
      $cols = array();
      foreach (node_invoke_all($node, "nodeapi", "settings") as $setting) {
        $cols[] = array("data" => $setting, "align" => "center", "width" => 75);
      }

      $output .= "<h2>". module_invoke($name, "node", "name") ."</h2>";
      $output .= table($header, array($cols));
      $output .= "<br /><br />";
652
653
    }
  }
654
  */
655
656
657

  $output .= form_submit(t("Save configuration"));
  $output .= form_submit(t("Reset to defaults"));
Kjartan's avatar
Kjartan committed
658

659
  print form($output);
660
661
662

}

Dries's avatar
   
Dries committed
663
664
665
666
667
668
669
670
671
672
673
674
/*
** Return the revision with the specified revision number.
*/

function node_revision_load($node, $revision) {
  return $node->revisions[$revision]["node"];
}

/*
** Create and return a new revision of the given node.
*/

Dries's avatar
   
Dries committed
675
676
677
function node_revision_create($node) {
  global $user;

Dries's avatar
   
Dries committed
678
679
680
681
682
  /*
  ** 'revision' is the name of the field used to indicicate that we
  ** have to create a new revision of a node.
  */

Dries's avatar
   
Dries committed
683
  if ($node->nid && $node->revision) {
Dries's avatar
   
Dries committed
684
685
686
687
    $prev = node_load(array("nid" => $node->nid));
    $node->revisions = $prev->revisions;
    unset($prev->revisions);
    $node->revisions[] = array("uid" => $user->uid, "timestamp" => time(), "node" => $prev, "history" => $node->history);
Dries's avatar
   
Dries committed
688
689
690
691
692
  }

  return $node;
}

Dries's avatar
   
Dries committed
693
694
695
/*
** Roll-back to the revision with the specified revision number.
*/
Dries's avatar
   
Dries committed
696

Dries's avatar
   
Dries committed
697
698
function node_revision_rollback($node, $revision) {
  global $user;
Dries's avatar
   
Dries committed
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733

  /*
  ** Extract the specified revision:
  */

  $rev = $node->revisions[$revision]["node"];

  /*
  ** Inherit all the past revisions:
  */

  $rev->revisions = $node->revisions;

  /*
  ** Save the original/current node:
  */

  $rev->revisions[] = array("uid" => $user->uid, "timestamp" => time(), "node" => $node);

  /*
  ** Remove the specified revision:
  */

  unset($rev->revisions[$revision]);

  /*
  ** Save the node:
  */

  foreach ($node as $key => $value) {
    $filter[] = $key;
  }

  node_save($rev, $filter);

Dries's avatar
   
Dries committed
734
  watchdog("special", "$node->type: rollbacked to revision #$revision of '$node->title'");
Dries's avatar
   
Dries committed
735
736
}

Dries's avatar
   
Dries committed
737
738
739
740
741
/*
** Delete the revision with specified revision number.
*/

function node_revision_delete($node, $revision) {
Dries's avatar
   
Dries committed
742
743

  unset($node->revisions[$revision]);
Dries's avatar
   
Dries committed
744

Dries's avatar
   
Dries committed
745
  node_save($node, array("nid", "revisions"));
Dries's avatar
   
Dries committed
746

Dries's avatar
   
Dries committed
747
  watchdog("special", "$node->type: removed revision #$revision of '$node->title'");
Dries's avatar
   
Dries committed
748
749
}

Dries's avatar
   
Dries committed
750
751
752
753
754
755
756
757
758
759
760
/*
** Return a list of all the existing revision numbers.
*/

function node_revision_list($node) {
  if (is_array($node->revisions)) {
    return array_keys($node->revisions);
  }
  else {
    return array();
  }
Dries's avatar
   
Dries committed
761
762
}

Dries's avatar
 
Dries committed
763
function node_admin() {
Dries's avatar
   
Dries committed
764
  global $op, $edit;
Dries's avatar
   
Dries committed
765

Dries's avatar
   
Dries committed
766
  if (user_access("administer nodes")) {
Dries's avatar
   
Dries committed
767

Dries's avatar
   
Dries committed
768
769
770
771
    if (empty($op)) {
      $op = arg(2);
    }

Dries's avatar
   
Dries committed
772
773
774
    /*
    ** Compile a list of the administrative links:
    */
Dries's avatar
Dries committed
775

Dries's avatar
   
Dries committed
776
777
    switch ($op) {
      case "search":
Dries's avatar
   
Dries committed
778
        print search_type("node", url("admin/node/search"));
Dries's avatar
   
Dries committed
779
780
        break;
      case "edit":
Dries's avatar
   
Dries committed
781
        print node_admin_edit(arg(3));
Dries's avatar
   
Dries committed
782
        break;
Dries's avatar
   
Dries committed
783
      case "delete":
Dries's avatar
   
Dries committed
784
        print node_delete(array("nid" => arg(3)));
Dries's avatar
   
Dries committed
785
        break;
Dries's avatar
   
Dries committed
786
      case "rollback+revision":
Dries's avatar
   
Dries committed
787
788
        print node_revision_rollback(node_load(array("nid" => arg(3))), arg(5));
        print node_admin_edit(arg(4));
Dries's avatar
   
Dries committed
789
        break;
Dries's avatar
   
Dries committed
790
      case "delete+revision":
Dries's avatar
   
Dries committed
791
792
        print node_revision_delete(node_load(array("nid" => arg(3))), arg(5));
        print node_admin_edit(arg(4));
Dries's avatar
   
Dries committed
793
        break;
Dries's avatar
   
Dries committed
794
      case t("Preview"):
Dries's avatar
   
Dries committed
795
        $edit = node_validate($edit, $error);
Dries's avatar
   
Dries committed
796
        print node_preview($edit);
Dries's avatar
   
Dries committed
797
        break;
Dries's avatar
   
Dries committed
798
      case t("Submit"):
Dries's avatar
   
Dries committed
799
800
801
        print node_submit($edit);
        break;
      case t("Delete"):
Dries's avatar
   
Dries committed
802
        print node_delete($edit);
Dries's avatar
   
Dries committed
803
        break;
804
805
806
807
808
      case t("Save configuration"):
      case t("Reset to defaults"):
      case "settings":
        print node_admin_settings($edit);
        break;
Dries's avatar
   
Dries committed
809
      default:
Dries's avatar
   
Dries committed
810
        print node_admin_nodes();
Dries's avatar
   
Dries committed
811
812
813
814
    }
  }
  else {
    print message_access();
Dries's avatar
 
Dries committed
815
816
817
  }
}

Dries's avatar
   
Dries committed
818
function node_block($op = "list", $delta = 0) {
Dries's avatar
   
Dries committed
819

Dries's avatar
   
Dries committed
820
821
822
823
824
825
  if ($op == "list") {
    $blocks[0]["info"] = t("Syndicate");
    return $blocks;
  }
  else {
    $block["subject"] = t("Syndicate");
Dries's avatar
   
Dries committed
826
    $block["content"] = "<div align=\"center\">". l("<img src=\"". theme("image", "xml.gif") ."\" width=\"36\" height=\"14\" border=\"0\" alt=\"XML\" />", "node/feed", array("title" => t("Read the XML version of this page."))) ."</div>";
Dries's avatar
   
Dries committed
827

Dries's avatar
   
Dries committed
828
829
    return $block;
  }
Dries's avatar
   
Dries committed
830
831
}

Kjartan's avatar
Kjartan committed
832
function node_feed($nodes = 0, $channel = array()) {
Dries's avatar
   
Dries committed
833
834
  global $base_url;

Kjartan's avatar
Kjartan committed
835
  /*
Dries's avatar
   
Dries committed
836
837
838
839
840
  ** A generic function for generating RSS feeds from a set of nodes.
  **   - $nodes should be an object as returned by db_query() which contains
  **     the nid field.
  **   - $channel is an associative array containing title, link, and
  **     description keys.
Kjartan's avatar
Kjartan committed
841
  */
Dries's avatar
   
Dries committed
842

Kjartan's avatar
Kjartan committed
843
  if (!$nodes) {
Dries's avatar
   
Dries committed
844
    $nodes = db_query_range("SELECT nid FROM node WHERE promote = '1' AND status = '1' ORDER BY created DESC", 0, 15);
Kjartan's avatar
Kjartan committed
845
  }
Dries's avatar
   
Dries committed
846

Kjartan's avatar
Kjartan committed
847
848
  while ($node = db_fetch_object($nodes)) {
    $item = node_load(array("nid" => $node->nid));
Dries's avatar
   
Dries committed
849
    $link = url("node/view/$item->nid");
Dries's avatar
   
Dries committed
850
    $items .= format_rss_item($item->title, $link, $item->teaser);
Dries's avatar
   
Dries committed
851
852
  }

Kjartan's avatar
Kjartan committed
853
  $output .= "<?xml version=\"1.0\" ". t("encoding=\"ISO-8859-1\""). "?>\n";
Kjartan's avatar
Kjartan committed
854
  $output .= "<!DOCTYPE rss [<!ENTITY % HTMLlat1 PUBLIC \"-//W3C//ENTITIES Latin 1 for XHTML//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent\">]>\n";
Dries's avatar
   
Dries committed
855
    // NOTE: &eacute; - for example - is the correct ISO-8859-1 translation of  (e acute) but apparently XML parsers don't (have to) understand it.  To solve this problem, we use a DTD that defines commonly used entity such as &eacute;.
Kjartan's avatar
Kjartan committed
856
857
  if (!$channel["version"]) $channel["version"] = "0.91";
  if (!$channel["title"]) $channel["title"] = variable_get("site_name", "drupal") ." - ". variable_get("site_slogan", "");
Dries's avatar
   
Dries committed
858
  if (!$channel["link"]) $channel["link"] = $base_url;
Kjartan's avatar
Kjartan committed
859
860
861
862
  if (!$channel["description"]) $channel["description"] = variable_get("site_mission", "");
  if (!$channel["language"]) $channel["language"] = "en";
  $output .= "<rss version=\"". $channel["version"] . "\">\n";
  $output .= format_rss_channel($channel["title"], $channel["link"], $channel["description"], $items, $channel["language"]);
Dries's avatar
   
Dries committed
863
864
  $output .= "</rss>\n";

Dries's avatar
   
Dries committed
865
  header("Content-Type: text/xml");
Dries's avatar
   
Dries committed
866
867
868
  print $output;
}

869
function node_validate($node, &$error) {
Dries's avatar
   
Dries committed
870
  global $user;
871
  $error = array();
Dries's avatar
   
Dries committed
872
873
874
875
876

  /*
  ** Convert the node to an object if necessary:
  */

Dries's avatar
   
Dries committed
877
  $node = array2object($node);
Dries's avatar
   
Dries committed
878
879
880
881
882

  /*
  ** Validate the title field:
  */

Dries's avatar
   
Dries committed
883
  if (isset($node->title) && !$node->title) {
884
    $error["title"] = theme("theme_error", t("You have to specify a valid title."));
Dries's avatar
   
Dries committed
885
886
  }

887
888
889
890
891
892
893
894
895
896
897
898
  /*
  ** Common default values:
  */

  $node->teaser = node_teaser($node->body);

  /*
  ** Create a new revision when required:
  */

  $node = node_revision_create($node);

Dries's avatar
   
Dries committed
899
900
901
902
903
904
  if (user_access("administer nodes")) {

    /*
    ** Setup default values if required:
    */

Dries's avatar
   
Dries committed
905
906
    if (!$node->created) {
      $node->created = time();
Dries's avatar
   
Dries committed
907
908
    }

Dries's avatar
   
Dries committed
909
910
    if (!$node->date) {
      $node->date = date("M j, Y g:i a", $node->created);
Dries's avatar
   
Dries committed
911
    }
Kjartan's avatar
Kjartan committed
912

913
914
915
    if (!is_numeric($node->status)) {
      $node->status = 1;
    }
Dries's avatar
   
Dries committed
916
917
918
919
920

    /*
    ** Validate the "authored by"-field:
    */

Dries's avatar
   
Dries committed
921
922
923
924
925
926
927
928
929
    if (empty($node->name)) {
      /*
      ** The use of empty() is mandatory in the context of usernames
      ** as the empty string denotes the anonymous user.  In case we
      ** are dealing with an anomymous user we set the user ID to 0.
      */
      $node->uid = 0;
    }
    else if ($account = user_load(array("name" => $node->name))) {
Dries's avatar
   
Dries committed
930
      $node->uid = $account->uid;
Dries's avatar
   
Dries committed
931
932
    }
    else {
933
      $error["name"] = theme("theme_error", t("The name '%u' does not exist.", array ("%u" => $node->name)));
Dries's avatar
   
Dries committed
934
935
936
937
938
939
    }

    /*
    ** Validate the "authored on"-field:
    */

Dries's avatar
   
Dries committed
940
941
    if (strtotime($node->date) > 1000) {
      $node->created = strtotime($node->date);
Dries's avatar
   
Dries committed
942
943
    }
    else {
944
      $error["date"] = theme("theme_error", t("You have to specifiy a valid date."));
Dries's avatar
   
Dries committed
945
946
    }
  }
947
948
949
  else {
    // Validate for normal users:
    $node->uid = $user->uid ? $user->uid : 0;
Kjartan's avatar
Kjartan committed
950
    // Force defaults in case people modify the form:
Kjartan's avatar
Kjartan committed
951
952
953
954
955
    $node->status = variable_get("node_status_$node->type", 1);
    $node->promote = variable_get("node_promote_$node->type", 1);
    $node->moderate = variable_get("node_moderate_$node->type", 0);
    $node->static = variable_get("node_static_$node->type", 0);
    $node->revision = variable_get("node_revision_$node->type", 0);
Kjartan's avatar
Kjartan committed
956
957
958
959
960
    unset($node->created);
  }

  // Workflow:
  if ($node->moderate == 1) {
961
962
    $node->promote = 0;
  }
Dries's avatar
   
Dries committed
963

Dries's avatar
   
Dries committed
964
965
966
967
  /*
  ** Do node type specific validation checks.
  */

968
969
  $result = node_invoke($node, "validate");
  $error = $error + (is_array($result) ? $result : array()) + node_invoke_all($node, "nodeapi", "validate");
Dries's avatar
   
Dries committed
970

Dries's avatar
   
Dries committed
971
  return $node;
Dries's avatar
   
Dries committed
972
973
}

Dries's avatar
   
Dries committed
974

Dries's avatar
   
Dries committed
975
function node_form($edit, $error = NULL) {
Dries's avatar
   
Dries committed
976

Dries's avatar
   
Dries committed
977
978
979
980
981
982
983
  /*
  ** Save the referer.  We record where the user came from such that we
  ** can redirect him after having completed the node forms.
  */

  referer_save();

Dries's avatar
   
Dries committed
984
985
986
987
  /*
  ** Validate the node:
  */

Dries's avatar
   
Dries committed
988
  if (!$error) {
989
990
    /* Only validate if we don't already know the errors. */
    $edit = node_validate($edit, $error);
Dries's avatar
   
Dries committed
991
  }
Dries's avatar
   
Dries committed
992

993
  // Prepend extra node form:
994
  $form = implode("", node_invoke_all($edit, "nodeapi", "form pre", $error));
995

Dries's avatar
   
Dries committed
996
997
998
999
1000
1001
  /*
  ** Get the node specific bits:
  */

  $function = $edit->type ."_form";
  if (function_exists($function)) {
Kjartan's avatar
Kjartan committed
1002
    $form .= $function($edit, $help, $error, $param);
Dries's avatar
   
Dries committed
1003
  }
Kjartan's avatar
Kjartan committed
1004

1005
  // Append extra node form:
1006
  $form .= implode("", node_invoke_all($edit, "nodeapi", "form post", $error));
Dries's avatar
   
Dries committed
1007
1008
1009
1010
1011
1012
1013
1014
1015

  /*
  ** Add the help text:
  */

  if ($help) {
    $output .= "<p>$help</p>";
  }

Dries's avatar
   
Dries committed
1016
1017
1018
1019
  $output .= "<table border=\"0\" cellpadding=\"2\" cellspacing=\"2\">";
  $output .= " <tr>";
  $output .= "  <td valign=\"top\">";

Dries's avatar
   
Dries committed
1020
1021
1022
1023
1024
1025
1026
  /*
  ** Add the default fields:
  */

  $output .= form_textfield(t("Title"), "title", $edit->title, 60, 64, $error["title"]);

  /*
Dries's avatar
   
Dries committed
1027
  ** Add the node specific fields:
Dries's avatar
   
Dries committed
1028
1029
  */

Dries's avatar
   
Dries committed
1030
  $output .= $form;
Dries's avatar
   
Dries committed
1031
1032
1033
1034
1035
1036
1037
1038
1039

  /*
  ** Add the hidden fields:
  */

  if ($edit->nid) {
    $output .= form_hidden("nid", $edit->nid);
  }

Dries's avatar
   
Dries committed
1040
1041
1042
1043
1044
  if (isset($edit->uid)) {
      /*
      ** The use of isset() is mandatory in the context of user IDs as uid
      ** 0 denotes the anonymous user.
      */
Dries's avatar
   
Dries committed
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
    $output .= form_hidden("uid", $edit->uid);
  }

  if ($edit->created) {
    $output .= form_hidden("created", $edit->created);
  }

  $output .= form_hidden("type", $edit->type);

  /*
  ** Add the buttons:
  */

  $output .= form_submit(t("Preview"));

  if ($edit->title && $edit->type && !$error) {
    $output .= form_submit(t("Submit"));
  }

Dries's avatar
   
Dries committed
1064
  if ($edit->nid && node_access("delete", $edit)) {
Dries's avatar
   
Dries committed
1065
1066
1067
1068
1069
1070
1071
1072
    $output .= form_submit(t("Delete"));
  }

  /*
  ** Add the admin specific parts:
  */

  if (user_access("administer nodes")) {
Dries's avatar
   
Dries committed
1073
    $output .= "</td><td align=\"left\" valign=\"top\">";
1074
    $output .= form_textfield(t("Authored by"), "name", $edit->name, 20, 60, $error["name"]);
Dries's avatar
   
Dries committed
1075
1076
    $output .= form_textfield(t("Authored on"), "date", $edit->date, 20, 25, $error["date"]);
    $output .= "<br />";
1077
1078
    $output .= form_select(t("Set public/published"), "status", isset($edit->status) ? $edit->status : variable_get("node_status_$edit->type", 1), array(t("Disabled"), t("Enabled")));
    $output .= form_select(t("Promote to front page"), "promote", isset($edit->promote) ? $edit->promote : variable_get("node_promote_$edit->type", 1), array(t("Disabled"), t("Enabled")));
Kjartan's avatar
Kjartan committed
1079
    $output .= form_select(t("Moderation status"), "moderate", isset($edit->moderate) ? $edit->moderate : variable_get("node_moderate_$edit->type", 0), array(t("Approved"), t("Awaiting approval")));
1080
1081
1082
    $output .= form_select(t("Static on front page"), "static", isset($edit->static) ? $edit->static : variable_get("node_static_$edit->type", 0), array(t("Disabled"), t("Enabled")));
    $output .= implode("", node_invoke_all($edit, "nodeapi", "form admin"));
    $output .= form_select(t("Create new revision"), "revision", isset($edit->revision) ? $edit->revision : variable_get("node_revision_$edit->type", 0), array(t("Disabled"), t("Enabled")));
Dries's avatar
   
Dries committed
1083
1084
  }

Dries's avatar
   
Dries committed
1085
1086
1087
1088
  $output .= "  </td>";
  $output .= " </tr>";
  $output .= "</table>";

Kjartan's avatar
Kjartan committed
1089
  return form($output, ($param["method"] ? $param["method"] : "post"), $param["action"], $param["options"]);
Dries's avatar
   
Dries committed
1090
1091
1092
}

function node_add($type) {
1093
  global $user, $edit;
Dries's avatar
   
Dries committed
1094

Dries's avatar
   
Dries committed
1095
  /*
Dries's avatar
   
Dries committed
1096
  ** If a node type has been specified, validate it existence.  If no
Dries's avatar
   
Dries committed
1097
1098
1099
  ** (valid) node type has been provied, display a node type overview.
  */

Dries's avatar
   
Dries committed
1100
  if ($type && node_access("create", $type)) {
1101
    // Initialize settings
1102
1103
    // TODO : clean up this code.
    $node = array("uid" => $user->uid, "name" => $user->name, "type" => $type);
1104
1105
1106
1107
    foreach (array("title", "teaser", "body") as $field) {
      if ($edit[$field]) {
        $node[$field] = check_input($edit[$field]);
      }
Dries's avatar
   
Dries committed
1108
    }
1109
    $output = node_form($node);
Dries's avatar
   
Dries committed
1110
1111
  }
  else {
Dries's avatar
   
Dries committed
1112