node.module 25.2 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
9
function node_help() {
  global $mod;

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

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

Dries's avatar
   
Dries committed
19
20
  if (user_access("administer nodes")) {
    return 1;
Dries's avatar
   
Dries committed
21
  }
Dries's avatar
   
Dries committed
22
  else {
Dries's avatar
   
Dries committed
23

Dries's avatar
   
Dries committed
24
25
26
    /*
    ** Convert the node to an object if necessary:
    */
Dries's avatar
   
Dries committed
27

Dries's avatar
   
Dries committed
28
29
30
    if (is_array($node)) {
      $node = node_object($node);
    }
Dries's avatar
   
Dries committed
31

Dries's avatar
   
Dries committed
32
33
34
35
36
37
38
39
40
41
42
43
    /*
    ** Construct a function:
    */

    $function = $node->type ."_access";

    if (function_exists($function)) {
      return $function($op, $node);
    }
    else {
      return 0;
    }
Dries's avatar
   
Dries committed
44
45
46
  }
}

Dries's avatar
   
Dries committed
47
function node_perm() {
Dries's avatar
   
Dries committed
48
  return array("administer nodes", "access content", "post content");
Dries's avatar
   
Dries committed
49
50
}

Dries's avatar
   
Dries committed
51
function node_search($keys) {
Dries's avatar
   
Dries committed
52
  global $PHP_SELF;
Dries's avatar
   
Dries committed
53
54
55

  $result = db_query("SELECT n.nid, n.title, n.created, u.uid, u.name FROM node n LEFT JOIN users u ON n.uid = u.uid WHERE n.status = 1 AND (n.title LIKE '%$keys%' OR n.teaser LIKE '%$keys%' OR n.body LIKE '%$keys%') ORDER BY n.created DESC LIMIT 20");
  while ($node = db_fetch_object($result)) {
Dries's avatar
   
Dries committed
56
    $find[$i++] = array("title" => check_output($node->title), "link" => (strstr($PHP_SELF, "admin.php") ? "admin.php?mod=node&type=node&op=edit&id=$node->nid" : "node.php?id=$node->nid"), "user" => $node->name, "date" => $node->created);
Dries's avatar
   
Dries committed
57
58
59
60
61
  }

  return $find;
}

Dries's avatar
   
Dries committed
62
function node_conf_options() {
Dries's avatar
   
Dries committed
63
  $output .= form_select(t("Default number of nodes to display"), "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 nodes to display on the main page."));
Dries's avatar
   
Dries committed
64
65
66
  return $output;
}

Dries's avatar
CHANGES    
Dries committed
67
function node_conf_filters() {
Dries's avatar
   
Dries committed
68
  $output .= form_select(t("Enable HTML tags"), "filter_html", variable_get("filter_html", 0), array("Disabled", "Enabled"), t("Allow HTML and PHP tags in user-contributed content."));
Dries's avatar
   
Dries committed
69
  $output .= form_textfield(t("Allowed HTML tags"), "allowed_html", variable_get("allowed_html", "<a> <b> <dd> <dl> <dt> <i> <li> <ol> <u> <ul>"), 64, 128, 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
70
  $output .= "<hr />";
Dries's avatar
   
Dries committed
71
  $output .= form_select(t("Enable link tags"), "filter_link", variable_get("filter_link", 0), array("Disabled", "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."));
Dries's avatar
   
Dries committed
72
  $output .= "<hr />";
Dries's avatar
CHANGES    
Dries committed
73
74
75
76
77
78
79
80
81
82
83
  return $output;
}

function node_filter_html($text) {
  $text = eregi_replace("([ \f\r\t\n\'\"])style=[^>]+", "\\1", $text);
  $text = eregi_replace("([ \f\r\t\n\'\"])on[a-z]+=[^>]+", "\\1", $text);
  $text = strip_tags($text, variable_get("allowed_html", ""));
  return $text;
}

function node_filter_link($text) {
Dries's avatar
   
Dries committed
84
85
86
87
88
  $src = array("/\[\[(([^\|]*?)(\|([^\|]*?))?)\]\]/e");  // [link|description]
  $dst = array(format_tag('\\2', '\\4'));                // [link|description]
  return preg_replace($src, $dst, $text);
}

Dries's avatar
   
Dries committed
89
90
91
92
93
94
function node_filter_line($text) {
  /*
  ** If HTML mark-up is being used, strip regular mark-up:
  */

  if (strstr($text, "<br />") || strstr($text, "<p>")) {
Dries's avatar
   
Dries committed
95
    $text = ereg_replace("[\r\n]", "", $text);
Dries's avatar
   
Dries committed
96
97
98
99
100
101
102
103
104
105
106
107
  }

  /*
  ** Replace '<br>', '<br />', '<p>' and '<p />' by '\n':
  */

  $text = eregi_replace("<br>", "\n", $text);
  $text = eregi_replace("<br />", "\n", $text);
  $text = eregi_replace("<p>", "\n", $text);
  $text = eregi_replace("<br />", "\n", $text);

  /*
Dries's avatar
   
Dries committed
108
  ** Replace "\r\n" by "\n":
Dries's avatar
   
Dries committed
109
110
111
112
113
114
115
116
117
118
119
  */

  $text = ereg_replace("\r\n", "\n", $text);

  /*
  ** Replace some new line charachters:
  */

  while (strpos($text, "\n\n\n")) {
    $text = ereg_replace("\n\n\n", "\n\n", $text);
  }
Dries's avatar
   
Dries committed
120

Dries's avatar
   
Dries committed
121
122
123
  return trim($text);
}

Dries's avatar
CHANGES    
Dries committed
124
125
126
function node_filter($text) {
  if (variable_get("filter_html", 0)) $text = node_filter_html($text);
  if (variable_get("filter_link", 0)) $text = node_filter_link($text);
Dries's avatar
   
Dries committed
127
  return node_filter_line($text);
Dries's avatar
CHANGES    
Dries committed
128
129
}

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

Dries's avatar
   
Dries committed
132
  if ($type == "admin" && user_access("administer nodes")) {
Dries's avatar
   
Dries committed
133
134
135
    $links[] = "<a href=\"admin.php?mod=node\">content management</a>";
  }

Dries's avatar
   
Dries committed
136
  if ($type == "page" && user_access("post content")) {
Dries's avatar
   
Dries committed
137
    $links[] = "<a href=\"module.php?mod=node&op=add\">submit</a>";
Dries's avatar
   
Dries committed
138
139
  }

Dries's avatar
   
Dries committed
140
  if ($type == "node") {
Kjartan's avatar
Kjartan committed
141
142
143
    if ($node->links) {
      $links = $node->links;
    }
Dries's avatar
   
Dries committed
144

Dries's avatar
   
Dries committed
145
146
    if ($main && $node->teaser != $node->body) {
      $links[] = "<a href=\"node.php?id=$node->nid\">". t("read more") ."</a>";
Dries's avatar
   
Dries committed
147
    }
Dries's avatar
   
Dries committed
148

Dries's avatar
   
Dries committed
149
150
    if (module_invoke($node->type, "access", "update", $node)) {
      $links[] = "<a href=\"module.php?mod=node&op=edit&id=$node->nid\">". t("edit") ."</a>";
Dries's avatar
   
Dries committed
151
    }
Dries's avatar
   
Dries committed
152

Dries's avatar
   
Dries committed
153
    if (user_access("administer nodes")) {
Dries's avatar
   
Dries committed
154
       $links[] = "<a href=\"admin.php?mod=node&op=edit&id=$node->nid\">". t("administer") ."</a>";
Dries's avatar
   
Dries committed
155
    }
Dries's avatar
   
Dries committed
156
157
158
159
160
  }

  return $links ? $links : array();
}

Dries's avatar
   
Dries committed
161
function node_admin_settings($edit = array()) {
Dries's avatar
   
Dries committed
162
163
  global $op;

Dries's avatar
   
Dries committed
164
165
166
167
  if ($op == t("Save configuration")) {
    /*
    ** Save the configuration options:
    */
Dries's avatar
Dries committed
168

Dries's avatar
   
Dries committed
169
170
171
    foreach ($edit as $name => $value) {
      variable_set($name, $value);
    }
Dries's avatar
 
Dries committed
172
173
  }

Dries's avatar
   
Dries committed
174
175
176
177
  if ($op == t("Reset to defaults")) {
    /*
    ** Reset the configuration options to their default value:
    */
Dries's avatar
 
Dries committed
178

Dries's avatar
   
Dries committed
179
180
181
    foreach ($edit as $name=>$value) {
      variable_del($name);
    }
Dries's avatar
   
Dries committed
182
  }
Dries's avatar
Dries committed
183

Dries's avatar
   
Dries committed
184
  $output .= "<h3>". t("Global node settings") ."</h3>";
Dries's avatar
   
Dries committed
185
  $output .= node_conf_options();
Dries's avatar
   
Dries committed
186
187
188

  foreach (module_list() as $name) {
    if (module_hook($name, "conf_options") && module_hook($name, "node")) {
Dries's avatar
   
Dries committed
189
      $output .= "<h3>". ucfirst(module_invoke($name, "node", "name") ." settings") ."</h3>";
Dries's avatar
   
Dries committed
190
191
192
193
      $output .= module_invoke($name, "conf_options");
    }
  }

Dries's avatar
   
Dries committed
194
195
  $output .= form_submit(t("Save configuration"));
  $output .= form_submit(t("Reset to defaults"));
Dries's avatar
Dries committed
196

Dries's avatar
   
Dries committed
197
  return form($output);
Dries's avatar
   
Dries committed
198
199
}

Dries's avatar
   
Dries committed
200
function node_admin_edit($node) {
Dries's avatar
   
Dries committed
201

Dries's avatar
   
Dries committed
202
  if (is_numeric($node)) {
Dries's avatar
   
Dries committed
203
    $node = node_load(array("nid" => $node));
Dries's avatar
   
Dries committed
204
  }
Dries's avatar
   
Dries committed
205

Dries's avatar
   
Dries committed
206
207
208
  /*
  ** Edit node:
  */
Dries's avatar
   
Dries committed
209

Dries's avatar
   
Dries committed
210
  $output .= "<h3>". t("Edit") ." ". module_invoke($node->type, "node", "name") ."</h3>";
Dries's avatar
   
Dries committed
211

Dries's avatar
   
Dries committed
212
  $output .= node_form($node);
Dries's avatar
   
Dries committed
213

Dries's avatar
   
Dries committed
214
215
216
217
218
219
220
221
222
  /*
  ** Edit revisions:
  */

  if ($node->revisions) {
    $output .= "<h3>". t("Edit revisions") ."</h3>";
    $output .= "<table border=\"1\" cellpadding=\"2\" cellspacing=\"2\">";
    $output .= " <tr><th>older revisions</th><th colspan=\"3\">operations</th></tr>";
    foreach ($node->revisions as $key => $revision) {
Dries's avatar
   
Dries committed
223
      $output .= " <tr><td>". sprintf(t("revision #%d revised by %s on %s"), $key, format_name(user_load(array("uid" => $revision["uid"]))), format_date($revision["timestamp"], "small")) . ($revision["history"] ? "<br /><small>". $revision["history"] ."</small>" : "") ."</td><td><a href=\"node.php?id=$node->nid&revision=$key\">". t("view revision") ."</a></td><td><a href=\"admin.php?mod=node&op=rollback+revision&id=$node->nid&revision=$key\">". t("rollback revision") ."</a></td><td><a href=\"admin.php?mod=node&op=delete+revision&id=$node->nid&revision=$key\">". t("delete revision") ."</a></td></tr>";
Dries's avatar
   
Dries committed
224
225
226
227
    }
    $output .= "</table>";
  }

Dries's avatar
   
Dries committed
228
  /*
Dries's avatar
   
Dries committed
229
  ** Display the node form extensions:
Dries's avatar
   
Dries committed
230
  */
Dries's avatar
   
Dries committed
231

Dries's avatar
   
Dries committed
232
233
  foreach (module_list() as $name) {
    $output .= module_invoke($name, "node_link", $node);
Dries's avatar
Dries committed
234
235
  }

Dries's avatar
   
Dries committed
236
  return $output;
Dries's avatar
   
Dries committed
237
238
239

}

Dries's avatar
   
Dries committed
240
241
function node_admin_nodes() {
  global $query;
Dries's avatar
   
Dries committed
242

Dries's avatar
   
Dries committed
243
  $queries = array(array("ORDER BY n.created DESC", "new nodes"), array("ORDER BY n.changed DESC", "updated nodes"), array("WHERE n.status = 1 AND n.moderate = 0 ORDER BY n.nid DESC", "published nodes"), array("WHERE n.status = 0 AND n.moderate = 0 ORDER BY n.nid DESC", "non-published nodes"), array("WHERE n.status = 1 AND n.moderate = 1 ORDER BY n.nid DESC", "pending nodes"), array("WHERE n.status = 1 AND n.promote = 1 ORDER BY n.nid DESC", "promoted nodes"));
Dries's avatar
   
Dries committed
244

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

Dries's avatar
   
Dries committed
247
248
  foreach ($queries as $key => $value) {
    $links[] = "<a href=\"admin.php?mod=node&op=nodes&query=$key\">$value[1]</a>";
Dries's avatar
Dries committed
249
250
  }

Dries's avatar
   
Dries committed
251
  $output .= "<small>". implode(" :: ", $links) ."</small><hr />";
Dries's avatar
   
Dries committed
252

Dries's avatar
   
Dries committed
253
254
255
  $output .= "<table border=\"1\" cellpadding=\"2\" cellspacing=\"2\">\n";
  $output .= " <tr><th>title</th><th>type</th><th>author</th><th>status</th><th colspan=\"2\">operations</th></tr>\n";
  while ($node = db_fetch_object($result)) {
Dries's avatar
   
Dries committed
256
    $output .= "<tr><td><a href=\"node.php?id=$node->nid\">". check_output($node->title) ."</a></td><td>$node->type</td><td nowrap=\"nowrap\">". format_name($node) ."</td><td>". ($node->status ? t("published") : t("not published")) ."</td><td nowrap=\"nowrap\"><a href=\"admin.php?mod=node&op=edit&id=$node->nid\">". t("edit node") ."</a></td><td nowrap=\"nowrap\"><a href=\"admin.php?mod=node&op=delete&id=$node->nid\">". t("delete node") ."</a></td></tr>";
Dries's avatar
   
Dries committed
257
  }
Dries's avatar
   
Dries committed
258
  $output .= "</table>";
Dries's avatar
   
Dries committed
259

Dries's avatar
   
Dries committed
260
  return $output;
Dries's avatar
Dries committed
261
262
}

Dries's avatar
   
Dries committed
263
264
265
266
267
268
269
270
271
272
273
274
/*
** 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
275
276
277
function node_revision_create($node) {
  global $user;

Dries's avatar
   
Dries committed
278
279
280
281
282
  /*
  ** '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
283
  if ($node->nid && $node->revision) {
Dries's avatar
   
Dries committed
284
285
286
287
    $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
288
289
290
291
292
  }

  return $node;
}

Dries's avatar
   
Dries committed
293
294
295
/*
** Roll-back to the revision with the specified revision number.
*/
Dries's avatar
   
Dries committed
296

Dries's avatar
   
Dries committed
297
298
function node_revision_rollback($node, $revision) {
  global $user;
Dries's avatar
   
Dries committed
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333

  /*
  ** 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
334
  watchdog("special", "$node->type: rollbacked to revision #$revision of '$node->title'");
Dries's avatar
   
Dries committed
335
336
}

Dries's avatar
   
Dries committed
337
338
339
340
341
/*
** Delete the revision with specified revision number.
*/

function node_revision_delete($node, $revision) {
Dries's avatar
   
Dries committed
342
343

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

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

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

Dries's avatar
   
Dries committed
350
351
352
353
354
355
356
357
358
359
360
/*
** 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
361
362
}

Dries's avatar
 
Dries committed
363
function node_admin() {
Dries's avatar
   
Dries committed
364
  global $op, $id, $revision, $edit;
Dries's avatar
   
Dries committed
365

Dries's avatar
   
Dries committed
366
  if (user_access("administer nodes")) {
Dries's avatar
   
Dries committed
367

Dries's avatar
   
Dries committed
368
369
370
    /*
    ** Compile a list of the administrative links:
    */
Dries's avatar
Dries committed
371

Dries's avatar
   
Dries committed
372
373
374
375
    $links[] = "<a href=\"admin.php?mod=node&op=nodes\">nodes</a>";
    $links[] = "<a href=\"admin.php?mod=node&op=search\">search content</a>";
    $links[] = "<a href=\"admin.php?mod=node&op=settings\">settings</a>";
    $links[] = "<a href=\"admin.php?mod=node&op=help\">help</a>";
Dries's avatar
   
Dries committed
376

Dries's avatar
   
Dries committed
377
    print "<small>". implode(" &middot; ", $links) ."</small><hr />";
Dries's avatar
   
Dries committed
378
379
380
381
382
383

    switch ($op) {
      case "help":
        print node_help();
        break;
      case "search":
Dries's avatar
   
Dries committed
384
        print search_type("node", "admin.php?mod=node&op=search");
Dries's avatar
   
Dries committed
385
        break;
Dries's avatar
   
Dries committed
386
387
388
389
      case t("Save configuration"):
      case t("Reset to defaults"):
      case "settings":
        print node_admin_settings($edit);
Dries's avatar
   
Dries committed
390
391
        break;
      case "edit":
Dries's avatar
   
Dries committed
392
        print node_admin_edit($id);
Dries's avatar
   
Dries committed
393
        break;
Dries's avatar
   
Dries committed
394
395
396
      case "delete":
        print node_delete(array("nid" => $id));
        break;
Dries's avatar
   
Dries committed
397
      case "rollback revision":
Dries's avatar
   
Dries committed
398
399
        print node_revision_rollback(node_load(array("nid" => $id)), $revision);
        print node_admin_edit($id);
Dries's avatar
   
Dries committed
400
401
        break;
      case "delete revision":
Dries's avatar
   
Dries committed
402
403
        print node_revision_delete(node_load(array("nid" => $id)), $revision);
        print node_admin_edit($id);
Dries's avatar
   
Dries committed
404
        break;
Dries's avatar
   
Dries committed
405
      case t("Preview"):
Dries's avatar
   
Dries committed
406
        print node_preview($edit);
Dries's avatar
   
Dries committed
407
        break;
Dries's avatar
   
Dries committed
408
      case t("Submit"):
Dries's avatar
   
Dries committed
409
410
411
        print node_submit($edit);
        break;
      case t("Delete"):
Dries's avatar
   
Dries committed
412
        print node_delete($edit);
Dries's avatar
   
Dries committed
413
        break;
Dries's avatar
   
Dries committed
414
      default:
Dries's avatar
   
Dries committed
415
        print node_admin_nodes();
Dries's avatar
   
Dries committed
416
417
418
419
    }
  }
  else {
    print message_access();
Dries's avatar
 
Dries committed
420
421
422
  }
}

Dries's avatar
   
Dries committed
423
424
425
426
function node_block() {
  global $theme;

  $block[0][subject] = t("Syndicate");
Dries's avatar
   
Dries committed
427
  $block[0][content] = "<div align=\"center\"><a href=\"module.php?mod=node&op=feed\"><img src=\"". $theme->image("xml.gif") ."\" width=\"36\" height=\"14\" border=\"0\" alt=\"XML\" /></a></div>\n";
Dries's avatar
   
Dries committed
428
429
430
431
432
433
  $block[0][info] = "Syndicate";

  return $block;
}

function node_feed() {
Dries's avatar
   
Dries committed
434

Dries's avatar
   
Dries committed
435
  $result = db_query("SELECT nid, type FROM node WHERE promote = '1' AND status = '1' ORDER BY created DESC LIMIT 15");
Dries's avatar
   
Dries committed
436
437

  while ($node = db_fetch_object($result)) {
Dries's avatar
   
Dries committed
438
    $item = node_load(array("nid" => $node->nid, "type" => $node->type));
Dries's avatar
   
Dries committed
439
440
441

    $link = path_uri() ."node.php?id=$item->nid";

Dries's avatar
   
Dries committed
442
    $items .= format_rss_item($item->title, $link, $item->teaser);
Dries's avatar
   
Dries committed
443
444
445
  }

  $output .= "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n";
Dries's avatar
   
Dries committed
446
  // $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
447
  $output .= "<rss version=\"0.91\">\n";
Dries's avatar
   
Dries committed
448
  $output .= format_rss_channel(variable_get("site_name", "drupal"), path_uri(), variable_get("site_slogan", ""), $items);
Dries's avatar
   
Dries committed
449
450
  $output .= "</rss>\n";

Dries's avatar
   
Dries committed
451
452
  header("Content-Type: text/xml");

Dries's avatar
   
Dries committed
453
454
455
456
  print $output;

}

Dries's avatar
   
Dries committed
457

458
function node_validate($node, &$error) {
Dries's avatar
   
Dries committed
459
460
461
462
463
464
465

  global $user;

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

Dries's avatar
   
Dries committed
466
  $node = node_object($node);
Dries's avatar
   
Dries committed
467

Dries's avatar
   
Dries committed
468

Dries's avatar
   
Dries committed
469
470
471
472
  /*
  ** Validate the title field:
  */

Dries's avatar
   
Dries committed
473
  if (isset($node->title) && !$node->title) {
Dries's avatar
   
Dries committed
474
475
476
477
478
479
480
481
482
    $error["title"] = "<div style=\"color: red;\">". t("You have to specify a valid title.") ."</div>";
  }

  if (user_access("administer nodes")) {

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

Dries's avatar
   
Dries committed
483
484
    if (!$node->created) {
      $node->created = time();
Dries's avatar
   
Dries committed
485
486
    }

Dries's avatar
   
Dries committed
487
488
    if (!$node->date) {
      $node->date = date("M j, Y g:i a", $node->created);
Dries's avatar
   
Dries committed
489
490
491
492
493
494
    }

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

Dries's avatar
   
Dries committed
495
496
497
498
499
500
501
502
503
    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
504
      $node->uid = $account->uid;
Dries's avatar
   
Dries committed
505
506
    }
    else {
Dries's avatar
   
Dries committed
507
      $error["name"] = "<div style=\"color: red;\">". sprintf(t("The name '%s' does not exist."), $node->name) ."</div>";
Dries's avatar
   
Dries committed
508
509
510
511
512
513
    }

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

Dries's avatar
   
Dries committed
514
515
    if (strtotime($node->date) > 1000) {
      $node->created = strtotime($node->date);
Dries's avatar
   
Dries committed
516
517
518
519
    }
    else {
      $error["date"] = "<div style=\"color: red;\">". t("You have to specifiy a valid date.") ."</div>";
    }
Dries's avatar
   
Dries committed
520

Dries's avatar
   
Dries committed
521
522
  }

Dries's avatar
   
Dries committed
523
  return $node;
Dries's avatar
   
Dries committed
524
525
}

Dries's avatar
   
Dries committed
526

Dries's avatar
   
Dries committed
527
528
function node_form($edit) {

Dries's avatar
   
Dries committed
529
530
531
532
533
534
535
  /*
  ** 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
536
537
538
539
  /*
  ** Validate the node:
  */

540
  $edit = node_validate($edit, $error);
Dries's avatar
   
Dries committed
541

Dries's avatar
   
Dries committed
542
543
544
545
546
547
  /*
  ** Get the node specific bits:
  */

  $function = $edit->type ."_form";
  if (function_exists($function)) {
548
    $form .= $function($edit, $help, $error);
Dries's avatar
   
Dries committed
549
550
551
552
553
554
555
556
557
558
  }

  /*
  ** Add the help text:
  */

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

Dries's avatar
   
Dries committed
559
560
561
562
  $output .= "<table border=\"0\" cellpadding=\"2\" cellspacing=\"2\">";
  $output .= " <tr>";
  $output .= "  <td valign=\"top\">";

Dries's avatar
   
Dries committed
563
564
565
566
567
568
569
570
571
572
573
  /*
  ** Add the default fields:
  */

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

  if ($edit->body && !$edit->teaser) {
    $edit->teaser = node_teaser($edit->body);
  }

  if ($edit->teaser) {
Dries's avatar
   
Dries committed
574
    $output .= form_textarea(t("Teaser"), "teaser", $edit->teaser, 60, 5, $error["teaser"]);
Dries's avatar
   
Dries committed
575
576
577
  }

  /*
Dries's avatar
   
Dries committed
578
  ** Add the node specific fields:
Dries's avatar
   
Dries committed
579
580
  */

Dries's avatar
   
Dries committed
581
  $output .= $form;
Dries's avatar
   
Dries committed
582
583
584
585
586
587
588
589
590

  /*
  ** Add the hidden fields:
  */

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

Dries's avatar
   
Dries committed
591
592
593
594
595
  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
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
    $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
615
  if ($edit->nid && node_access("delete", $edit)) {
Dries's avatar
   
Dries committed
616
617
618
619
620
621
622
623
    $output .= form_submit(t("Delete"));
  }

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

  if (user_access("administer nodes")) {
Dries's avatar
   
Dries committed
624
    $output .= "</td><td align=\"left\" valign=\"top\">";
Dries's avatar
   
Dries committed
625

Dries's avatar
   
Dries committed
626
627
628
    $output .= form_textfield(t("Authored by"), "name", $edit->name, 20, 25, $error["name"]);
    $output .= form_textfield(t("Authored on"), "date", $edit->date, 20, 25, $error["date"]);
    $output .= "<br />";
Dries's avatar
   
Dries committed
629
630
631
632
    $output .= form_select(t("Set public/published"), "status", $edit->status, array("Disabled", "Enabled"));
    $output .= form_select(t("Allow users comments"), "comment", $edit->comment, array("Disabled", "Enabled"));
    $output .= form_select(t("Promote to front page"), "promote", $edit->promote, array("Disabled", "Enabled"));
    $output .= form_select(t("Create new revision"), "revision", $edit->revision, array("Disabled", "Enabled"));
Dries's avatar
   
Dries committed
633
634
  }

Dries's avatar
   
Dries committed
635
636
637
638
  $output .= "  </td>";
  $output .= " </tr>";
  $output .= "</table>";

Dries's avatar
   
Dries committed
639
640
641
642
643
644
  return form($output);
}

function node_add($type) {
  global $user;

Dries's avatar
   
Dries committed
645
  /*
Dries's avatar
   
Dries committed
646
  ** If a node type has been specified, validate it existence.  If no
Dries's avatar
   
Dries committed
647
648
649
650
  ** (valid) node type has been provied, display a node type overview.
  */

  if (module_hook($type, "node")) {
Dries's avatar
   
Dries committed
651
    $output = node_form(array("uid" => $user->uid, "name" => $user->name, "type" => $type));
Dries's avatar
   
Dries committed
652
653
  }
  else {
Dries's avatar
   
Dries committed
654

Dries's avatar
   
Dries committed
655
656
657
    /*
    ** Compile a list with the different node types and their explanation:
    */
Dries's avatar
   
Dries committed
658

Dries's avatar
   
Dries committed
659
    foreach (module_list() as $name) {
Dries's avatar
   
Dries committed
660
661
662
663
664
      if (module_hook($name, "node") && node_access("create", array("type" => $name))) {
        $output .= "<li>";
        $output .= " <a href=\"module.php?mod=node&op=add&type=$name\">". module_invoke($name, "node", "name") ."</a>";
        $output .= " <div style=\"margin-left: 20px;\">". module_invoke($name, "node", "description") ."</div>";
        $output .= "</li>";
Dries's avatar
   
Dries committed
665
      }
Dries's avatar
   
Dries committed
666
667
    }

Dries's avatar
   
Dries committed
668
669
    $output = t("Choose the appropriate item from the list:") ."<ul>$output</ul>";

Dries's avatar
   
Dries committed
670
671
672
673
674
675
676
677
678
679
  }

  return $output;
}

function node_edit($id) {
  global $user;

  $node = node_load(array("nid" => $id));

Dries's avatar
   
Dries committed
680
681
682
683
684
685
686
687
  if (node_access("update", $node)) {
    $output = node_form($node);
  }
  else {
    $output = message_access();
  }

  return $output;
Dries's avatar
   
Dries committed
688
689
690
691
692
693
694
695
}

function node_preview($edit) {

  /*
  ** Load the user's name when needed:
  */

Dries's avatar
   
Dries committed
696
697
698
699
700
701
702
703
704
705
706
  if (isset($edit["name"])) {
      /*
      ** The use of isset() is mandatory in the context of user IDs as uid
      ** 0 denotes the anonymous user.
      */
    if ($user = user_load(array("name" => $edit["name"]))) {
      $edit["uid"] = $user->uid;
    }
    else {
      $edit["uid"] = 0; // anonymous user
    }
Dries's avatar
   
Dries committed
707
708
709
710
711
712
713
714
715
716
717
718
719
720
  }
  else if ($edit["uid"]) {
    $user = user_load(array("uid" => $edit["uid"]));
    $edit["name"] = $user->name;
  }

  /*
  ** Set the created time when needed:
  */

  if (empty($edit["nid"])) {
    $edit["created"] = time();
  }

Dries's avatar
   
Dries committed
721
722
723
724
725
  /*
  ** Apply the required filters:
  */

  foreach ($edit as $key => $value) {
Dries's avatar
   
Dries committed
726
727
728
729
730
    $node->$key = check_output($value); 
      /*
      ** NOTE: we can't do a check_query() or check_input() here as they
      **       add slashes which results in breakage. 
      */
Dries's avatar
   
Dries committed
731
732
  }

Dries's avatar
   
Dries committed
733
734
735
736
  /*
  ** Display a preview of the node:
  */

Dries's avatar
   
Dries committed
737
  node_view($node);
Dries's avatar
   
Dries committed
738
739
740
741

  return node_form($edit);
}

Dries's avatar
   
Dries committed
742
function node_submit($node) {
Dries's avatar
   
Dries committed
743
744
  global $user;

Dries's avatar
   
Dries committed
745
  if (user_access("post content")) {
Dries's avatar
   
Dries committed
746

Dries's avatar
   
Dries committed
747
748
749
750
    /*
    ** Verify a user's submission rate and avoid duplicate nodes being
    ** inserted:
    */
Dries's avatar
   
Dries committed
751

Dries's avatar
   
Dries committed
752
    throttle("node", variable_get("max_node_rate", 900));
Dries's avatar
   
Dries committed
753

Dries's avatar
   
Dries committed
754
755
756
    /*
    ** Fixup the node when required:
    */
Dries's avatar
   
Dries committed
757

758
    $node = node_validate($node, $error);
Dries's avatar
   
Dries committed
759

Dries's avatar
   
Dries committed
760
761
762
    /*
    ** Apply the filters:
    */
Dries's avatar
   
Dries committed
763

Dries's avatar
   
Dries committed
764
765
766
    $node->teaser = filter($node->teaser);
    $node->title = filter($node->title);
    $node->body = filter($node->body);
Dries's avatar
   
Dries committed
767
768

    /*
Dries's avatar
   
Dries committed
769
    ** Create a new revision when required:
Dries's avatar
   
Dries committed
770
771
    */

Dries's avatar
   
Dries committed
772
773
774
    $node = node_revision_create($node);

    if ($node->nid) {
Dries's avatar
   
Dries committed
775
776

      /*
Dries's avatar
   
Dries committed
777
778
      ** Check whether the current user has the proper access rights to
      ** perform this operation:
Dries's avatar
   
Dries committed
779
780
      */

Dries's avatar
   
Dries committed
781
782
783
784
785
786
787
788
789
790
791
      if (node_access("update", $node)) {

        /*
        ** Compile a list of the node fields and their default values that users
        ** and administrators are allowed to save when updating a node.
        */

        if (user_access("administer nodes")) {
          $fields = array("nid", "uid", "body", "comment", "created", "promote", "moderate", "revisions", "status", "teaser", "title", "type" => $node->type);
        }
        else {
Dries's avatar
   
Dries committed
792
          $fields = array("nid", "uid" => ($user->uid ? $user->uid : 0), "body", "teaser", "title", "type" => $node->type);
Dries's avatar
   
Dries committed
793
794
795
796
797
798
        }

        node_save($node, array_merge($fields, module_invoke($node->type, "save", "update", $node)));

        watchdog("special", "$node->type: updated '$node->title'");
        $output = t("The node has been updated.");
Dries's avatar
   
Dries committed
799
800
      }
      else {
Dries's avatar
   
Dries committed
801
802
        watchdog("warning", "$node->type: not authorized to update node");
        $output = t("You are not authorized to update this node.");
Dries's avatar
   
Dries committed
803
804
      }

Dries's avatar
   
Dries committed
805
806
807
    }
    else {

Dries's avatar
   
Dries committed
808
809
810
811
      /*
      ** Check whether the current user has the proper access rights to
      ** perform this operation:
      */
Dries's avatar
   
Dries committed
812

Dries's avatar
   
Dries committed
813
      if (node_access("create", $node)) {
Dries's avatar
   
Dries committed
814

Dries's avatar
   
Dries committed
815
816
817
818
        /*
        ** Compile a list of the node fields and their default values that users
        ** and administrators are allowed to save when inserting a new node.
        */
Dries's avatar
   
Dries committed
819

Dries's avatar
   
Dries committed
820
821
822
823
        if (user_access("administer nodes")) {
          $fields = array("uid", "body", "comment" => 1, "promote", "moderate", "status" => 1, "teaser", "title", "type" => $node->type);
        }
        else {
Dries's avatar
   
Dries committed
824
          $fields = array("uid" => ($user->uid ? $user->uid : 0), "body", "comment" => 1, "teaser", "title", "type" => $node->type);
Dries's avatar
   
Dries committed
825
826
827
        }

        node_save($node, array_merge($fields, module_invoke($node->type, "save", "create", $node)));
Dries's avatar
   
Dries committed
828

Dries's avatar
   
Dries committed
829
830
        watchdog("special", "$node->type: added '$node->title'");
        $output = t("Thanks for your submission.");
Dries's avatar
   
Dries committed
831
832
      }
      else {
Dries's avatar
   
Dries committed
833
834
        watchdog("warning", "$node->type: not authorized to create node");
        $output = t("You are not authorized to create this node.");
Dries's avatar
   
Dries committed
835
836
      }
    }
Dries's avatar
   
Dries committed
837
838
839
840

    if ($referer = referer_load()) {
      $output .= "<p><a href=\"$referer\">". t("return") ."</a></p>";
    }
Dries's avatar
   
Dries committed
841
  }
Dries's avatar
   
Dries committed
842
843
844
  else {
    $output = message_access();
  }
Dries's avatar
   
Dries committed
845
846
847
848

  return $output;
}

Dries's avatar
   
Dries committed
849
function node_delete($edit) {
Dries's avatar
   
Dries committed
850

Dries's avatar
   
Dries committed
851
852
853
  $node = node_load(array("nid" => $edit["nid"]));

  if (node_access("delete", $node)) {
Dries's avatar
   
Dries committed
854

Dries's avatar
   
Dries committed
855
    if ($edit["confirm"]) {
Dries's avatar
   
Dries committed
856

Dries's avatar
   
Dries committed
857
858
859
860
861
862
863
864
865
866
867
      /*
      ** Delete the specified node and its comments:
      */

      db_query("DELETE FROM node WHERE nid = '$node->nid'");
      db_query("DELETE FROM comments WHERE lid = '$node->nid'");

      /*
      ** Call the node specific callback (if any):
      */

868
      module_invoke($node->type, "delete", $node);
Dries's avatar
   
Dries committed
869

Dries's avatar
   
Dries committed
870
      watchdog("special", "$node->type: deleted '$node->title'");
Dries's avatar
   
Dries committed
871
872
873
      $output = t("The node has been deleted.");
    }
    else {
Dries's avatar
   
Dries committed
874
      $output .= form_item(t("Confirm deletion"), check_output($node->title));
Dries's avatar
   
Dries committed
875
876
877
      $output .= form_hidden("nid", $node->nid);
      $output .= form_hidden("confirm", 1);
      $output .= form_submit(t("Delete"));
Dries's avatar
   
Dries committed
878
      $output = form($output);
Dries's avatar
   
Dries committed
879
    }
Dries's avatar
   
Dries committed
880
881
  }
  else {
Dries's avatar
   
Dries committed
882
    watchdog("warning", "$node->type: not authorized to remove node");
Dries's avatar
   
Dries committed
883
    $output = t("You are not authorized to remove this node.");
Dries's avatar
   
Dries committed
884
885
886
887
888
  }

  return $output;
}

Dries's avatar
   
Dries committed
889
function node_page() {
Dries's avatar
   
Dries committed
890
  global $op, $id, $user, $edit, $type, $theme, $meta, $date;
Dries's avatar
   
Dries committed
891
892
893

  if ($op == "feed") {
    node_feed();
Dries's avatar
   
Dries committed
894
    return;
Dries's avatar
   
Dries committed
895
  }
Dries's avatar
   
Dries committed
896

Dries's avatar
   
Dries committed
897
898
899
900
901
902
903
904
905
906
907
908
909
910
  /*
  ** Try to find a good title:
  */

  if ($type) {
    $title = ucfirst(module_invoke($type, "node", "name"));
  }
  else if ($edit["type"]) {
    $title = ucfirst(module_invoke($edit["type"], "node", "name"));
  }
  else {
    $title = t("Submission form");
  }

Dries's avatar
   
Dries committed
911
912
913
914
  $theme->header();

  switch ($op) {
    case "add":
Dries's avatar
   
Dries committed
915
      $theme->box($title, node_add($type));
Dries's avatar
   
Dries committed
916
917
      break;
    case "edit":
Dries's avatar
   
Dries committed
918
      $theme->box($title, node_edit($id));
Dries's avatar
   
Dries committed
919
920
      break;
    case t("Preview"):
Dries's avatar
   
Dries committed
921
      $theme->box($title, node_preview($edit));
Dries's avatar
   
Dries committed
922
923
      break;
    case t("Submit"):
Dries's avatar
   
Dries committed
924
      $theme->box($title, node_submit($edit));
Dries's avatar
   
Dries committed
925
      break;
Dries's avatar
   
Dries committed
926
    case t("Delete"):
Dries's avatar
   
Dries committed
927
      $theme->box($title, node_delete($edit));
Dries's avatar
   
Dries committed
928
      break;
Dries's avatar
   
Dries committed
929
    default:
Dries's avatar
   
Dries committed
930
      $result = db_query("SELECT nid, type FROM node WHERE ". ($meta ? "attributes LIKE '%". check_input($meta) ."%' AND " : "") ." promote = '1' AND status = '1' AND created <= '". ($date > 0 ? check_input($date) : time()) ."' ORDER BY created DESC LIMIT ". ($user->nodes ? $user->nodes : variable_get("default_nodes_main", 10)));
931
      while ($node = db_fetch_object($result)) {
Dries's avatar
   
Dries committed
932
        node_view(node_load(array("nid" => $node->nid, "type" => $node->type)), 1);
933
934
      }
  }
Dries's avatar
   
Dries committed
935
936

  $theme->footer();
Dries's avatar
   
Dries committed
937
}
Dries's avatar
   
Dries committed
938

Dries's avatar
 
Dries committed
939
?>