Wordpress 2.0.4
[autoinstalls/wordpress.git] / wp-admin / admin-functions.php
1 <?php
2
3 // Creates a new post from the "Write Post" form using $_POST information.
4 function write_post() {
5         global $user_ID;
6
7         if (!current_user_can('edit_posts'))
8                 die(__('You are not allowed to create posts or drafts on this blog.'));
9
10         // Rename.
11         $_POST['post_content'] = $_POST['content'];
12         $_POST['post_excerpt'] = $_POST['excerpt'];
13         $_POST['post_parent'] = $_POST['parent_id'];
14         $_POST['to_ping'] = $_POST['trackback_url'];
15
16         if (!empty ($_POST['post_author_override'])) {
17                 $_POST['post_author'] = (int) $_POST['post_author_override'];
18         } else
19                 if (!empty ($_POST['post_author'])) {
20                         $_POST['post_author'] = (int) $_POST['post_author'];
21                 } else {
22                         $_POST['post_author'] = (int) $_POST['user_ID'];
23                 }
24
25         if (($_POST['post_author'] != $_POST['user_ID']) && !current_user_can('edit_others_posts'))
26                 die(__('You cannot post as this user.'));
27
28         // What to do based on which button they pressed
29         if ('' != $_POST['saveasdraft'])
30                 $_POST['post_status'] = 'draft';
31         if ('' != $_POST['saveasprivate'])
32                 $_POST['post_status'] = 'private';
33         if ('' != $_POST['publish'])
34                 $_POST['post_status'] = 'publish';
35         if ('' != $_POST['advanced'])
36                 $_POST['post_status'] = 'draft';
37         if ('' != $_POST['savepage'])
38                 $_POST['post_status'] = 'static';
39
40         if ('publish' == $_POST['post_status'] && !current_user_can('publish_posts'))
41                 $_POST['post_status'] = 'draft';
42
43         if ('static' == $_POST['post_status'] && !current_user_can('edit_pages'))
44                 die(__('This user cannot edit pages.'));
45
46         if (!isset ($_POST['comment_status']))
47                 $_POST['comment_status'] = 'closed';
48
49         if (!isset ($_POST['ping_status']))
50                 $_POST['ping_status'] = 'closed';
51
52         if (!empty ($_POST['edit_date'])) {
53                 $aa = $_POST['aa'];
54                 $mm = $_POST['mm'];
55                 $jj = $_POST['jj'];
56                 $hh = $_POST['hh'];
57                 $mn = $_POST['mn'];
58                 $ss = $_POST['ss'];
59                 $jj = ($jj > 31) ? 31 : $jj;
60                 $hh = ($hh > 23) ? $hh -24 : $hh;
61                 $mn = ($mn > 59) ? $mn -60 : $mn;
62                 $ss = ($ss > 59) ? $ss -60 : $ss;
63                 $_POST['post_date'] = "$aa-$mm-$jj $hh:$mn:$ss";
64                 $_POST['post_date_gmt'] = get_gmt_from_date("$aa-$mm-$jj $hh:$mn:$ss");
65         }
66
67         // Create the post.
68         $post_ID = wp_insert_post($_POST);
69         add_meta($post_ID);
70
71         // Reunite any orphaned attachments with their parent
72         if ( $_POST['temp_ID'] )
73                 relocate_children($_POST['temp_ID'], $post_ID);
74
75         // Now that we have an ID we can fix any attachment anchor hrefs
76         fix_attachment_links($post_ID);
77
78         return $post_ID;
79 }
80
81 // Move child posts to a new parent
82 function relocate_children($old_ID, $new_ID) {
83         global $wpdb;
84         $old_ID = (int) $old_ID;
85         $new_ID = (int) $new_ID;
86         return $wpdb->query("UPDATE $wpdb->posts SET post_parent = $new_ID WHERE post_parent = $old_ID");
87 }
88
89 // Replace hrefs of attachment anchors with up-to-date permalinks.
90 function fix_attachment_links($post_ID) {
91         global $wp_rewrite;
92
93         $post = & get_post($post_ID, ARRAY_A);
94
95         $search = "#<a[^>]+rel=('|\")[^'\"]*attachment[^>]*>#ie";
96
97         // See if we have any rel="attachment" links
98         if ( 0 == preg_match_all($search, $post['post_content'], $anchor_matches, PREG_PATTERN_ORDER) )
99                 return;
100
101         $i = 0;
102         $search = "# id=(\"|')p(\d+)\\1#i";
103         foreach ( $anchor_matches[0] as $anchor ) {
104                 if ( 0 == preg_match($search, $anchor, $id_matches) )
105                         continue;
106
107                 $id = $id_matches[2];
108
109                 // While we have the attachment ID, let's adopt any orphans.
110                 $attachment = & get_post($id, ARRAY_A);
111                 if ( ! empty($attachment) && ! is_object(get_post($attachment['post_parent'])) ) {
112                         $attachment['post_parent'] = $post_ID;
113                         // Escape data pulled from DB.
114                         $attachment = add_magic_quotes($attachment);
115                         wp_update_post($attachment);
116                 }
117
118                 $post_search[$i] = $anchor;
119                 $post_replace[$i] = preg_replace("#href=(\"|')[^'\"]*\\1#e", "stripslashes('href=\\1').get_attachment_link($id).stripslashes('\\1')", $anchor);
120                 ++$i;
121         }
122
123         $post['post_content'] = str_replace($post_search, $post_replace, $post['post_content']);
124
125         // Escape data pulled from DB.
126         $post = add_magic_quotes($post);
127
128         return wp_update_post($post);
129 }
130
131 // Update an existing post with values provided in $_POST.
132 function edit_post() {
133         global $user_ID;
134
135         $post_ID = (int) $_POST['post_ID'];
136
137         if (!current_user_can('edit_post', $post_ID))
138                 die(__('You are not allowed to edit this post.'));
139
140         // Rename.
141         $_POST['ID'] = (int) $_POST['post_ID'];
142         $_POST['post_content'] = $_POST['content'];
143         $_POST['post_excerpt'] = $_POST['excerpt'];
144         $_POST['post_parent'] = $_POST['parent_id'];
145         $_POST['to_ping'] = $_POST['trackback_url'];
146
147         if (!empty ($_POST['post_author_override'])) {
148                 $_POST['post_author'] = (int) $_POST['post_author_override'];
149         } else
150                 if (!empty ($_POST['post_author'])) {
151                         $_POST['post_author'] = (int) $_POST['post_author'];
152                 } else {
153                         $_POST['post_author'] = (int) $_POST['user_ID'];
154                 }
155
156         if (($_POST['post_author'] != $_POST['user_ID']) && !current_user_can('edit_others_posts'))
157                 die(__('You cannot post as this user.'));
158
159         // What to do based on which button they pressed
160         if ('' != $_POST['saveasdraft'])
161                 $_POST['post_status'] = 'draft';
162         if ('' != $_POST['saveasprivate'])
163                 $_POST['post_status'] = 'private';
164         if ('' != $_POST['publish'])
165                 $_POST['post_status'] = 'publish';
166         if ('' != $_POST['advanced'])
167                 $_POST['post_status'] = 'draft';
168         if ('' != $_POST['savepage'])
169                 $_POST['post_status'] = 'static';
170
171         if ('publish' == $_POST['post_status'] && !current_user_can('publish_posts'))
172                 $_POST['post_status'] = 'draft';
173
174         if ('static' == $_POST['post_status'] && !current_user_can('edit_pages'))
175                 die(__('This user cannot edit pages.'));
176
177         if (!isset ($_POST['comment_status']))
178                 $_POST['comment_status'] = 'closed';
179
180         if (!isset ($_POST['ping_status']))
181                 $_POST['ping_status'] = 'closed';
182
183         if (!empty ($_POST['edit_date'])) {
184                 $aa = $_POST['aa'];
185                 $mm = $_POST['mm'];
186                 $jj = $_POST['jj'];
187                 $hh = $_POST['hh'];
188                 $mn = $_POST['mn'];
189                 $ss = $_POST['ss'];
190                 $jj = ($jj > 31) ? 31 : $jj;
191                 $hh = ($hh > 23) ? $hh -24 : $hh;
192                 $mn = ($mn > 59) ? $mn -60 : $mn;
193                 $ss = ($ss > 59) ? $ss -60 : $ss;
194                 $_POST['post_date'] = "$aa-$mm-$jj $hh:$mn:$ss";
195                 $_POST['post_date_gmt'] = get_gmt_from_date("$aa-$mm-$jj $hh:$mn:$ss");
196         }
197
198         // Meta Stuff
199         if ($_POST['meta']) {
200                 foreach ($_POST['meta'] as $key => $value)
201                         update_meta($key, $value['key'], $value['value']);
202         }
203         
204         if ($_POST['deletemeta']) {
205                 foreach ($_POST['deletemeta'] as $key => $value)
206                         delete_meta($key);
207         }
208
209         add_meta($post_ID);
210
211         wp_update_post($_POST);
212
213         // Now that we have an ID we can fix any attachment anchor hrefs
214         fix_attachment_links($post_ID);
215
216         return $post_ID;
217 }
218
219 function edit_comment() {
220         global $user_ID;
221
222         $comment_ID = (int) $_POST['comment_ID'];
223         $comment_post_ID = (int) $_POST['comment_post_ID'];
224
225         if (!current_user_can('edit_post', $comment_post_ID))
226                 die(__('You are not allowed to edit comments on this post, so you cannot edit this comment.'));
227
228         $_POST['comment_author'] = $_POST['newcomment_author'];
229         $_POST['comment_author_email'] = $_POST['newcomment_author_email'];
230         $_POST['comment_author_url'] = $_POST['newcomment_author_url'];
231         $_POST['comment_approved'] = $_POST['comment_status'];
232         $_POST['comment_content'] = $_POST['content'];
233         $_POST['comment_ID'] = (int) $_POST['comment_ID'];
234
235         if (!empty ($_POST['edit_date'])) {
236                 $aa = $_POST['aa'];
237                 $mm = $_POST['mm'];
238                 $jj = $_POST['jj'];
239                 $hh = $_POST['hh'];
240                 $mn = $_POST['mn'];
241                 $ss = $_POST['ss'];
242                 $jj = ($jj > 31) ? 31 : $jj;
243                 $hh = ($hh > 23) ? $hh -24 : $hh;
244                 $mn = ($mn > 59) ? $mn -60 : $mn;
245                 $ss = ($ss > 59) ? $ss -60 : $ss;
246                 $_POST['comment_date'] = "$aa-$mm-$jj $hh:$mn:$ss";
247         }
248
249         wp_update_comment($_POST);
250 }
251
252 // Get an existing post and format it for editing.
253 function get_post_to_edit($id) {
254         global $richedit;
255         $richedit = ( 'true' == get_user_option('rich_editing') ) ? true : false;
256
257         $post = get_post($id);
258
259         $post->post_content = format_to_edit($post->post_content, $richedit);
260         $post->post_content = apply_filters('content_edit_pre', $post->post_content);
261
262         $post->post_excerpt = format_to_edit($post->post_excerpt);
263         $post->post_excerpt = apply_filters('excerpt_edit_pre', $post->post_excerpt);
264
265         $post->post_title = format_to_edit($post->post_title);
266         $post->post_title = apply_filters('title_edit_pre', $post->post_title);
267
268         if ($post->post_status == 'static')
269                 $post->page_template = get_post_meta($id, '_wp_page_template', true);
270
271         return $post;
272 }
273
274 // Default post information to use when populating the "Write Post" form.
275 function get_default_post_to_edit() {
276         if ( !empty($_REQUEST['post_title']) )
277                 $post_title = wp_specialchars(stripslashes($_REQUEST['post_title']));
278         else if ( !empty($_REQUEST['popuptitle']) ) {
279                 $post_title = wp_specialchars(stripslashes($_REQUEST['popuptitle']));
280                 $post_title = funky_javascript_fix($post_title);
281         } else {
282                 $post_title = '';
283         }
284
285         if ( !empty($_REQUEST['content']) )
286                 $post_content = wp_specialchars(stripslashes($_REQUEST['content']));
287         else if ( !empty($post_title) ) {
288                 $text       = wp_specialchars(stripslashes(urldecode($_REQUEST['text'])));
289                 $text       = funky_javascript_fix($text);
290                 $popupurl   = wp_specialchars($_REQUEST['popupurl']);
291         $post_content = '<a href="'.$popupurl.'">'.$post_title.'</a>'."\n$text";
292     }
293
294         if ( !empty($_REQUEST['excerpt']) )
295                 $post_excerpt = wp_specialchars(stripslashes($_REQUEST['excerpt']));
296         else
297                 $post_excerpt = '';
298
299         $post->post_status = 'draft';
300         $post->comment_status = get_settings('default_comment_status');
301         $post->ping_status = get_settings('default_ping_status');
302         $post->post_pingback = get_settings('default_pingback_flag');
303         $post->post_category = get_settings('default_category');
304         $post->post_content = apply_filters('default_content', $post_content);
305         $post->post_title = apply_filters('default_title', $post_title);
306         $post->post_excerpt = apply_filters('default_excerpt', $post_excerpt);
307         $post->page_template = 'default';
308         $post->post_parent = 0;
309         $post->menu_order = 0;
310
311         return $post;
312 }
313
314 function get_comment_to_edit($id) {
315         global $richedit;
316         $richedit = ( 'true' == get_user_option('rich_editing') ) ? true : false;
317
318         $comment = get_comment($id);
319
320         $comment->comment_content = format_to_edit($comment->comment_content, $richedit);
321         $comment->comment_content = apply_filters('comment_edit_pre', $comment->comment_content);
322
323         $comment->comment_author = format_to_edit($comment->comment_author);
324         $comment->comment_author_email = format_to_edit($comment->comment_author_email);
325         $comment->comment_author_url = format_to_edit($comment->comment_author_url);
326
327         return $comment;
328 }
329
330 function get_category_to_edit($id) {
331         $category = get_category($id);
332
333         return $category;
334 }
335
336 // Creates a new user from the "Users" form using $_POST information.
337
338 function add_user() {
339         return edit_user();
340 }
341
342 function edit_user($user_id = 0) {
343         global $current_user, $wp_roles, $wpdb;
344
345         if ($user_id != 0) {
346                 $update = true;
347                 $user->ID = $user_id;
348                 $userdata = get_userdata($user_id);
349                 $user->user_login = $wpdb->escape($userdata->user_login);
350         } else {
351                 $update = false;
352                 $user = '';
353         }
354
355         if (isset ($_POST['user_login']))
356                 $user->user_login = wp_specialchars(trim($_POST['user_login']));
357
358         $pass1 = $pass2 = '';
359         if (isset ($_POST['pass1']))
360                 $pass1 = $_POST['pass1'];
361         if (isset ($_POST['pass2']))
362                 $pass2 = $_POST['pass2'];
363
364         if (isset ($_POST['role']) && current_user_can('edit_users')) {
365                 if($user_id != $current_user->id || $wp_roles->role_objects[$_POST['role']]->has_cap('edit_users'))
366                         $user->role = $_POST['role'];
367         }
368
369         if (isset ($_POST['email']))
370                 $user->user_email = wp_specialchars(trim($_POST['email']));
371         if (isset ($_POST['url'])) {
372                 $user->user_url = wp_specialchars(trim($_POST['url']));
373                 $user->user_url = preg_match('/^(https?|ftps?|mailto|news|gopher):/is', $user->user_url) ? $user->user_url : 'http://'.$user->user_url;
374         }
375         if (isset ($_POST['first_name']))
376                 $user->first_name = wp_specialchars(trim($_POST['first_name']));
377         if (isset ($_POST['last_name']))
378                 $user->last_name = wp_specialchars(trim($_POST['last_name']));
379         if (isset ($_POST['nickname']))
380                 $user->nickname = wp_specialchars(trim($_POST['nickname']));
381         if (isset ($_POST['display_name']))
382                 $user->display_name = wp_specialchars(trim($_POST['display_name']));
383         if (isset ($_POST['description']))
384                 $user->description = wp_specialchars(trim($_POST['description']));
385         if (isset ($_POST['jabber']))
386                 $user->jabber = wp_specialchars(trim($_POST['jabber']));
387         if (isset ($_POST['aim']))
388                 $user->aim = wp_specialchars(trim($_POST['aim']));
389         if (isset ($_POST['yim']))
390                 $user->yim = wp_specialchars(trim($_POST['yim']));
391
392         $errors = array ();
393
394         /* checking that username has been typed */
395         if ($user->user_login == '')
396                 $errors['user_login'] = __('<strong>ERROR</strong>: Please enter a username.');
397
398         /* checking the password has been typed twice */
399         do_action('check_passwords', array ($user->user_login, & $pass1, & $pass2));
400
401         if (!$update) {
402                 if ($pass1 == '' || $pass2 == '')
403                         $errors['pass'] = __('<strong>ERROR</strong>: Please enter your password twice.');
404         } else {
405                 if ((empty ($pass1) && !empty ($pass2)) || (empty ($pass2) && !empty ($pass1)))
406                         $errors['pass'] = __("<strong>ERROR</strong>: you typed your new password only once.");
407         }
408
409         /* Check for "\" in password */
410         if( strpos( " ".$pass1, "\\" ) )
411                 $errors['pass'] = __('<strong>ERROR</strong>: Passwords may not contain the character "\\".');
412
413         /* checking the password has been typed twice the same */
414         if ($pass1 != $pass2)
415                 $errors['pass'] = __('<strong>ERROR</strong>: Please type the same password in the two password fields.');
416
417         if (!empty ($pass1))
418                 $user->user_pass = $pass1;
419
420         if ( !validate_username($user->user_login) )
421                 $errors['user_login'] = __('<strong>ERROR</strong>: This username is invalid.  Please enter a valid username.');
422
423         if (!$update && username_exists($user->user_login))
424                 $errors['user_login'] = __('<strong>ERROR</strong>: This username is already registered, please choose another one.');
425
426         /* checking e-mail address */
427         if (empty ($user->user_email)) {
428                 $errors['user_email'] = __("<strong>ERROR</strong>: please type an e-mail address");
429         } else
430                 if (!is_email($user->user_email)) {
431                         $errors['user_email'] = __("<strong>ERROR</strong>: the email address isn't correct");
432                 }
433
434         if (count($errors) != 0)
435                 return $errors;
436
437         if ($update) {
438                 $user_id = wp_update_user(get_object_vars($user));
439         } else {
440                 $user_id = wp_insert_user(get_object_vars($user));
441                 wp_new_user_notification($user_id);
442         }
443
444         return $errors;
445 }
446
447
448 function get_link_to_edit($link_id) {
449         $link = get_link($link_id);
450         
451         $link->link_url = wp_specialchars($link->link_url, 1);
452         $link->link_name = wp_specialchars($link->link_name, 1);
453         $link->link_description = wp_specialchars($link->link_description);
454         $link->link_notes = wp_specialchars($link->link_notes);
455         $link->link_rss = wp_specialchars($link->link_rss);
456         
457         return $link;
458 }
459
460 function get_default_link_to_edit() {
461         if ( isset($_GET['linkurl']) )
462                 $link->link_url = wp_specialchars($_GET['linkurl'], 1);
463         else
464                 $link->link_url = '';
465         
466         if ( isset($_GET['name']) )
467                 $link->link_name = wp_specialchars($_GET['name'], 1);
468         else
469                 $link->link_name = '';
470                 
471         return $link;
472 }
473
474 function add_link() {
475         return edit_link();     
476 }
477
478 function edit_link($link_id = '') {
479         if (!current_user_can('manage_links'))
480                 die(__("Cheatin' uh ?"));
481
482         $_POST['link_url'] = wp_specialchars($_POST['link_url']);
483         $_POST['link_url'] = preg_match('/^(https?|ftps?|mailto|news|gopher):/is', $_POST['link_url']) ? $_POST['link_url'] : 'http://' . $_POST['link_url'];
484         $_POST['link_name'] = wp_specialchars($_POST['link_name']);
485         $_POST['link_image'] = wp_specialchars($_POST['link_image']);
486         $_POST['link_rss'] = wp_specialchars($_POST['link_rss']);
487         $auto_toggle = get_autotoggle($_POST['link_category']);
488         
489         // if we are in an auto toggle category and this one is visible then we
490         // need to make the others invisible before we add this new one.
491         // FIXME Add category toggle func.
492         //if (($auto_toggle == 'Y') && ($link_visible == 'Y')) {
493         //      $wpdb->query("UPDATE $wpdb->links set link_visible = 'N' WHERE link_category = $link_category");
494         //}
495
496         if ( !empty($link_id) ) {
497                 $_POST['link_id'] = $link_id;
498                 return wp_update_link($_POST);
499         } else {
500                 return wp_insert_link($_POST);
501         }
502 }
503
504 function url_shorten($url) {
505         $short_url = str_replace('http://', '', stripslashes($url));
506         $short_url = str_replace('www.', '', $short_url);
507         if ('/' == substr($short_url, -1))
508                 $short_url = substr($short_url, 0, -1);
509         if (strlen($short_url) > 35)
510                 $short_url = substr($short_url, 0, 32).'...';
511         return $short_url;
512 }
513
514 function selected($selected, $current) {
515         if ($selected == $current)
516                 echo ' selected="selected"';
517 }
518
519 function checked($checked, $current) {
520         if ($checked == $current)
521                 echo ' checked="checked"';
522 }
523
524 function return_categories_list($parent = 0) {
525         global $wpdb;
526         return $wpdb->get_col("SELECT cat_ID FROM $wpdb->categories WHERE category_parent = $parent ORDER BY category_count DESC");
527 }
528
529 function sort_cats($cat1, $cat2) {
530         return strcasecmp($cat1['cat_name'], $cat2['cat_name']);
531 }
532
533 function get_nested_categories($default = 0, $parent = 0) {
534         global $post_ID, $mode, $wpdb;
535
536         if ($post_ID) {
537                 $checked_categories = $wpdb->get_col("
538                      SELECT category_id
539                      FROM $wpdb->categories, $wpdb->post2cat
540                      WHERE $wpdb->post2cat.category_id = cat_ID AND $wpdb->post2cat.post_id = '$post_ID'
541                      ");
542
543                 if (count($checked_categories) == 0) {
544                         // No selected categories, strange
545                         $checked_categories[] = $default;
546                 }
547
548         } else {
549                 $checked_categories[] = $default;
550         }
551
552         $cats = return_categories_list($parent);
553         $result = array ();
554
555         if (is_array($cats)) {
556                 foreach ($cats as $cat) {
557                         $result[$cat]['children'] = get_nested_categories($default, $cat);
558                         $result[$cat]['cat_ID'] = $cat;
559                         $result[$cat]['checked'] = in_array($cat, $checked_categories);
560                         $result[$cat]['cat_name'] = get_the_category_by_ID($cat);
561                 }
562         }
563         
564         usort($result, 'sort_cats');
565
566         return $result;
567 }
568
569 function write_nested_categories($categories) {
570         foreach ($categories as $category) {
571                 echo '<label for="category-', $category['cat_ID'], '" class="selectit"><input value="', $category['cat_ID'], '" type="checkbox" name="post_category[]" id="category-', $category['cat_ID'], '"', ($category['checked'] ? ' checked="checked"' : ""), '/> ', wp_specialchars($category['cat_name']), "</label>\n";
572
573                 if (isset ($category['children'])) {
574                         echo "\n<span class='cat-nest'>\n";
575                         write_nested_categories($category['children']);
576                         echo "</span>\n";
577                 }
578         }
579 }
580
581 function dropdown_categories($default = 0) {
582         write_nested_categories(get_nested_categories($default));
583 }
584
585 // Dandy new recursive multiple category stuff.
586 function cat_rows($parent = 0, $level = 0, $categories = 0) {
587         global $wpdb, $class;
588
589         if (!$categories)
590                 $categories = $wpdb->get_results("SELECT * FROM $wpdb->categories ORDER BY cat_name");
591
592         if ($categories) {
593                 foreach ($categories as $category) {
594                         if ($category->category_parent == $parent) {
595                                 $category->cat_name = wp_specialchars($category->cat_name);
596                                 $pad = str_repeat('&#8212; ', $level);
597                                 if ( current_user_can('manage_categories') ) {
598                                         $edit = "<a href='categories.php?action=edit&amp;cat_ID=$category->cat_ID' class='edit'>".__('Edit')."</a></td>";
599                                         $default_cat_id = get_option('default_category');
600
601                                         if ($category->cat_ID != $default_cat_id)
602                                                 $edit .= "<td><a href='" . wp_nonce_url("categories.php?action=delete&amp;cat_ID=$category->cat_ID", 'delete-category_' . $category->cat_ID ) . "' onclick=\"return deleteSomething( 'cat', $category->cat_ID, '" . sprintf(__("You are about to delete the category &quot;%s&quot;.  All of its posts will go to the default category.\\n&quot;OK&quot; to delete, &quot;Cancel&quot; to stop."), js_escape($category->cat_name))."' );\" class='delete'>".__('Delete')."</a>";
603                                         else
604                                                 $edit .= "<td style='text-align:center'>".__("Default");
605                                 }
606                                 else
607                                         $edit = '';
608
609                                 $class = ('alternate' == $class) ? '' : 'alternate';
610                                 echo "<tr id='cat-$category->cat_ID' class='$class'><th scope='row'>$category->cat_ID</th><td>$pad $category->cat_name</td>
611                                                                 <td>$category->category_description</td>
612                                                                 <td>$category->category_count</td>
613                                                                 <td>$edit</td>
614                                                                 </tr>";
615                                 cat_rows($category->cat_ID, $level +1, $categories);
616                         }
617                 }
618         } else {
619                 return false;
620         }
621 }
622
623 function page_rows($parent = 0, $level = 0, $pages = 0) {
624         global $wpdb, $class, $post;
625         if (!$pages)
626                 $pages = $wpdb->get_results("SELECT * FROM $wpdb->posts WHERE post_status = 'static' ORDER BY menu_order");
627
628         if ($pages) {
629                 foreach ($pages as $post) {
630                         start_wp();
631                         if ($post->post_parent == $parent) {
632                                 $post->post_title = wp_specialchars($post->post_title);
633                                 $pad = str_repeat('&#8212; ', $level);
634                                 $id = $post->ID;
635                                 $class = ('alternate' == $class) ? '' : 'alternate';
636 ?>
637   <tr id='page-<?php echo $id; ?>' class='<?php echo $class; ?>'> 
638     <th scope="row"><?php echo $post->ID; ?></th> 
639     <td>
640       <?php echo $pad; ?><?php the_title() ?> 
641     </td> 
642     <td><?php the_author() ?></td>
643     <td><?php echo mysql2date('Y-m-d g:i a', $post->post_modified); ?></td> 
644         <td><a href="<?php the_permalink(); ?>" rel="permalink" class="edit"><?php _e('View'); ?></a></td>
645     <td><?php if ( current_user_can('edit_pages') ) { echo "<a href='post.php?action=edit&amp;post=$id' class='edit'>" . __('Edit') . "</a>"; } ?></td> 
646     <td><?php if ( current_user_can('edit_pages') ) { echo "<a href='" . wp_nonce_url("post.php?action=delete&amp;post=$id", 'delete-post_' . $id) .  "' class='delete' onclick=\"return deleteSomething( 'page', " . $id . ", '" . sprintf(__("You are about to delete the &quot;%s&quot; page.\\n&quot;OK&quot; to delete, &quot;Cancel&quot; to stop."), js_escape(get_the_title()) ) . "' );\">" . __('Delete') . "</a>"; } ?></td> 
647   </tr> 
648
649 <?php
650
651                                 page_rows($id, $level +1, $pages);
652                         }
653                 }
654         } else {
655                 return false;
656         }
657 }
658
659 function wp_dropdown_cats($currentcat = 0, $currentparent = 0, $parent = 0, $level = 0, $categories = 0) {
660         global $wpdb, $bgcolor;
661         if (!$categories) {
662                 $categories = $wpdb->get_results("SELECT * FROM $wpdb->categories ORDER BY cat_name");
663         }
664         if ($categories) {
665                 foreach ($categories as $category) {
666                         if ($currentcat != $category->cat_ID && $parent == $category->category_parent) {
667                                 $count = $wpdb->get_var("SELECT COUNT(post_id) FROM $wpdb->post2cat WHERE category_id = $category->cat_ID");
668                                 $pad = str_repeat('&#8211; ', $level);
669                                 $category->cat_name = wp_specialchars($category->cat_name);
670                                 echo "\n\t<option value='$category->cat_ID'";
671                                 if ($currentparent == $category->cat_ID)
672                                         echo " selected='selected'";
673                                 echo ">$pad$category->cat_name</option>";
674                                 wp_dropdown_cats($currentcat, $currentparent, $category->cat_ID, $level +1, $categories);
675                         }
676                 }
677         } else {
678                 return false;
679         }
680 }
681
682 function link_category_dropdown($fieldname, $selected = 0) {
683         global $wpdb;
684         
685         $results = $wpdb->get_results("SELECT cat_id, cat_name, auto_toggle FROM $wpdb->linkcategories ORDER BY cat_id");
686         echo "\n<select name='$fieldname' size='1'>\n";
687         foreach ($results as $row) {
688                 echo "\n\t<option value='$row->cat_id'";
689                 if ($row->cat_id == $selected)
690                         echo " selected='selected'";
691                 echo ">$row->cat_id : " . wp_specialchars($row->cat_name);
692                 if ($row->auto_toggle == 'Y')
693                         echo ' (auto toggle)';
694                 echo "</option>";
695         }
696         echo "\n</select>\n";
697 }
698
699 function wp_create_thumbnail($file, $max_side, $effect = '') {
700
701                 // 1 = GIF, 2 = JPEG, 3 = PNG
702
703         if (file_exists($file)) {
704                 $type = getimagesize($file);
705
706                 // if the associated function doesn't exist - then it's not
707                 // handle. duh. i hope.
708
709                 if (!function_exists('imagegif') && $type[2] == 1) {
710                         $error = __('Filetype not supported. Thumbnail not created.');
711                 }
712                 elseif (!function_exists('imagejpeg') && $type[2] == 2) {
713                         $error = __('Filetype not supported. Thumbnail not created.');
714                 }
715                 elseif (!function_exists('imagepng') && $type[2] == 3) {
716                         $error = __('Filetype not supported. Thumbnail not created.');
717                 } else {
718
719                         // create the initial copy from the original file
720                         if ($type[2] == 1) {
721                                 $image = imagecreatefromgif($file);
722                         }
723                         elseif ($type[2] == 2) {
724                                 $image = imagecreatefromjpeg($file);
725                         }
726                         elseif ($type[2] == 3) {
727                                 $image = imagecreatefrompng($file);
728                         }
729
730                         if (function_exists('imageantialias'))
731                                 imageantialias($image, TRUE);
732
733                         $image_attr = getimagesize($file);
734
735                         // figure out the longest side
736
737                         if ($image_attr[0] > $image_attr[1]) {
738                                 $image_width = $image_attr[0];
739                                 $image_height = $image_attr[1];
740                                 $image_new_width = $max_side;
741
742                                 $image_ratio = $image_width / $image_new_width;
743                                 $image_new_height = $image_height / $image_ratio;
744                                 //width is > height
745                         } else {
746                                 $image_width = $image_attr[0];
747                                 $image_height = $image_attr[1];
748                                 $image_new_height = $max_side;
749
750                                 $image_ratio = $image_height / $image_new_height;
751                                 $image_new_width = $image_width / $image_ratio;
752                                 //height > width
753                         }
754
755                         $thumbnail = imagecreatetruecolor($image_new_width, $image_new_height);
756                         @ imagecopyresampled($thumbnail, $image, 0, 0, 0, 0, $image_new_width, $image_new_height, $image_attr[0], $image_attr[1]);
757
758                         // If no filters change the filename, we'll do a default transformation.
759                         if ( basename($file) == $thumb = apply_filters('thumbnail_filename', basename($file)) )
760                                 $thumb = preg_replace('!(\.[^.]+)?$!', __('.thumbnail').'$1', basename($file), 1);
761
762                         $thumbpath = str_replace(basename($file), $thumb, $file);
763
764                         // move the thumbnail to it's final destination
765                         if ($type[2] == 1) {
766                                 if (!imagegif($thumbnail, $thumbpath)) {
767                                         $error = __("Thumbnail path invalid");
768                                 }
769                         }
770                         elseif ($type[2] == 2) {
771                                 if (!imagejpeg($thumbnail, $thumbpath)) {
772                                         $error = __("Thumbnail path invalid");
773                                 }
774                         }
775                         elseif ($type[2] == 3) {
776                                 if (!imagepng($thumbnail, $thumbpath)) {
777                                         $error = __("Thumbnail path invalid");
778                                 }
779                         }
780
781                 }
782         } else {
783                 $error = __('File not found');
784         }
785
786         if (!empty ($error)) {
787                 return $error;
788         } else {
789                 return $thumbpath;
790         }
791 }
792
793 // Some postmeta stuff
794 function has_meta($postid) {
795         global $wpdb;
796
797         return $wpdb->get_results("
798                         SELECT meta_key, meta_value, meta_id, post_id
799                         FROM $wpdb->postmeta
800                         WHERE post_id = '$postid'
801                         ORDER BY meta_key,meta_id", ARRAY_A);
802
803 }
804
805 function list_meta($meta) {
806         global $post_ID;
807         // Exit if no meta
808         if (!$meta)
809                 return;
810         $count = 0;
811 ?>
812 <table id='meta-list' cellpadding="3">
813         <tr>
814                 <th><?php _e('Key') ?></th>
815                 <th><?php _e('Value') ?></th>
816                 <th colspan='2'><?php _e('Action') ?></th>
817         </tr>
818 <?php
819
820
821         foreach ($meta as $entry) {
822                 ++ $count;
823                 if ($count % 2)
824                         $style = 'alternate';
825                 else
826                         $style = '';
827                 if ('_' == $entry['meta_key'] { 0 })
828                         $style .= ' hidden';
829                 echo "
830                         <tr class='$style'>
831                                 <td valign='top'><input name='meta[{$entry['meta_id']}][key]' tabindex='6' type='text' size='20' value='{$entry['meta_key']}' /></td>
832                                 <td><textarea name='meta[{$entry['meta_id']}][value]' tabindex='6' rows='2' cols='30'>{$entry['meta_value']}</textarea></td>
833                                 <td align='center'><input name='updatemeta' type='submit' class='updatemeta' tabindex='6' value='".__('Update')."' /><br />
834                                 <input name='deletemeta[{$entry['meta_id']}]' type='submit' class='deletemeta' tabindex='6' value='".__('Delete')."' /></td>
835                         </tr>
836                 ";
837         }
838         echo "
839                 </table>
840         ";
841 }
842
843 // Get a list of previously defined keys
844 function get_meta_keys() {
845         global $wpdb;
846
847         $keys = $wpdb->get_col("
848                         SELECT meta_key
849                         FROM $wpdb->postmeta
850                         GROUP BY meta_key
851                         ORDER BY meta_key");
852
853         return $keys;
854 }
855
856 function meta_form() {
857         global $wpdb;
858         $keys = $wpdb->get_col("
859                         SELECT meta_key
860                         FROM $wpdb->postmeta
861                         GROUP BY meta_key
862                         ORDER BY meta_id DESC
863                         LIMIT 10");
864 ?>
865 <h3><?php _e('Add a new custom field:') ?></h3>
866 <table cellspacing="3" cellpadding="3">
867         <tr>
868 <th colspan="2"><?php _e('Key') ?></th>
869 <th><?php _e('Value') ?></th>
870 </tr>
871         <tr valign="top">
872                 <td align="right" width="18%">
873 <?php if ($keys) : ?>
874 <select id="metakeyselect" name="metakeyselect" tabindex="7">
875 <option value="#NONE#"><?php _e('- Select -'); ?></option>
876 <?php
877
878         foreach ($keys as $key) {
879                 echo "\n\t<option value='$key'>$key</option>";
880         }
881 ?>
882 </select> <?php _e('or'); ?>
883 <?php endif; ?>
884 </td>
885 <td><input type="text" id="metakeyinput" name="metakeyinput" tabindex="7" /></td>
886                 <td><textarea id="metavalue" name="metavalue" rows="3" cols="25" tabindex="8"></textarea></td>
887         </tr>
888
889 </table>
890 <p class="submit"><input type="submit" name="updatemeta" tabindex="9" value="<?php _e('Add Custom Field &raquo;') ?>" /></p>
891 <?php
892
893 }
894
895 function add_meta($post_ID) {
896         global $wpdb;
897
898         $metakeyselect = $wpdb->escape(stripslashes(trim($_POST['metakeyselect'])));
899         $metakeyinput = $wpdb->escape(stripslashes(trim($_POST['metakeyinput'])));
900         $metavalue = $wpdb->escape(stripslashes(trim($_POST['metavalue'])));
901
902         if ( ('0' === $metavalue || !empty ($metavalue)) && ((('#NONE#' != $metakeyselect) && !empty ($metakeyselect)) || !empty ($metakeyinput)) ) {
903                 // We have a key/value pair. If both the select and the 
904                 // input for the key have data, the input takes precedence:
905
906                 if ('#NONE#' != $metakeyselect)
907                         $metakey = $metakeyselect;
908
909                 if ($metakeyinput)
910                         $metakey = $metakeyinput; // default
911
912                 $result = $wpdb->query("
913                                                 INSERT INTO $wpdb->postmeta 
914                                                 (post_id,meta_key,meta_value) 
915                                                 VALUES ('$post_ID','$metakey','$metavalue')
916                                         ");
917         }
918 } // add_meta
919
920 function delete_meta($mid) {
921         global $wpdb;
922
923         $result = $wpdb->query("DELETE FROM $wpdb->postmeta WHERE meta_id = '$mid'");
924 }
925
926 function update_meta($mid, $mkey, $mvalue) {
927         global $wpdb;
928
929         return $wpdb->query("UPDATE $wpdb->postmeta SET meta_key = '$mkey', meta_value = '$mvalue' WHERE meta_id = '$mid'");
930 }
931
932 function touch_time($edit = 1, $for_post = 1) {
933         global $month, $post, $comment;
934
935         if ( $for_post )
936                 $edit = ( ('draft' == $post->post_status) && (!$post->post_date || '0000-00-00 00:00:00' == $post->post_date) ) ? false : true;
937  
938         echo '<fieldset><legend><input type="checkbox" class="checkbox" name="edit_date" value="1" id="timestamp" /> <label for="timestamp">'.__('Edit timestamp').'</label></legend>';
939
940         $time_adj = time() + (get_settings('gmt_offset') * 3600);
941         $post_date = ($for_post) ? $post->post_date : $comment->comment_date;
942         $jj = ($edit) ? mysql2date('d', $post_date) : gmdate('d', $time_adj);
943         $mm = ($edit) ? mysql2date('m', $post_date) : gmdate('m', $time_adj);
944         $aa = ($edit) ? mysql2date('Y', $post_date) : gmdate('Y', $time_adj);
945         $hh = ($edit) ? mysql2date('H', $post_date) : gmdate('H', $time_adj);
946         $mn = ($edit) ? mysql2date('i', $post_date) : gmdate('i', $time_adj);
947         $ss = ($edit) ? mysql2date('s', $post_date) : gmdate('s', $time_adj);
948
949         echo "<select name=\"mm\">\n";
950         for ($i = 1; $i < 13; $i = $i +1) {
951                 echo "\t\t\t<option value=\"$i\"";
952                 if ($i == $mm)
953                         echo " selected='selected'";
954                 if ($i < 10) {
955                         $ii = "0".$i;
956                 } else {
957                         $ii = "$i";
958                 }
959                 echo ">".$month["$ii"]."</option>\n";
960         }
961 ?>
962 </select>
963 <input type="text" id="jj" name="jj" value="<?php echo $jj; ?>" size="2" maxlength="2" />
964 <input type="text" id="aa" name="aa" value="<?php echo $aa ?>" size="4" maxlength="5" /> @ 
965 <input type="text" id="hh" name="hh" value="<?php echo $hh ?>" size="2" maxlength="2" /> : 
966 <input type="text" id="mn" name="mn" value="<?php echo $mn ?>" size="2" maxlength="2" /> 
967 <input type="hidden" id="ss" name="ss" value="<?php echo $ss ?>" size="2" maxlength="2" /> 
968 <?php
969         if ( $edit ) {
970                 _e('Existing timestamp');
971                 echo ": {$month[$mm]} $jj, $aa @ $hh:$mn";
972         }
973 ?>
974 </fieldset>
975         <?php
976
977 }
978
979 // insert_with_markers: Owen Winkler, fixed by Eric Anderson
980 // Inserts an array of strings into a file (.htaccess), placing it between
981 // BEGIN and END markers.  Replaces existing marked info.  Retains surrounding
982 // data.  Creates file if none exists.
983 // Returns true on write success, false on failure.
984 function insert_with_markers($filename, $marker, $insertion) {
985         if (!file_exists($filename) || is_writeable($filename)) {
986                 if (!file_exists($filename)) {
987                         $markerdata = '';
988                 } else {
989                         $markerdata = explode("\n", implode('', file($filename)));
990                 }
991
992                 $f = fopen($filename, 'w');
993                 $foundit = false;
994                 if ($markerdata) {
995                         $state = true;
996                         foreach ($markerdata as $markerline) {
997                                 if (strstr($markerline, "# BEGIN {$marker}"))
998                                         $state = false;
999                                 if ($state)
1000                                         fwrite($f, "{$markerline}\n");
1001                                 if (strstr($markerline, "# END {$marker}")) {
1002                                         fwrite($f, "# BEGIN {$marker}\n");
1003                                         if (is_array($insertion))
1004                                                 foreach ($insertion as $insertline)
1005                                                         fwrite($f, "{$insertline}\n");
1006                                         fwrite($f, "# END {$marker}\n");
1007                                         $state = true;
1008                                         $foundit = true;
1009                                 }
1010                         }
1011                 }
1012                 if (!$foundit) {
1013                         fwrite($f, "# BEGIN {$marker}\n");
1014                         foreach ($insertion as $insertline)
1015                                 fwrite($f, "{$insertline}\n");
1016                         fwrite($f, "# END {$marker}\n");
1017                 }
1018                 fclose($f);
1019                 return true;
1020         } else {
1021                 return false;
1022         }
1023 }
1024
1025 // extract_from_markers: Owen Winkler
1026 // Returns an array of strings from a file (.htaccess) from between BEGIN
1027 // and END markers.
1028 function extract_from_markers($filename, $marker) {
1029         $result = array ();
1030
1031         if (!file_exists($filename)) {
1032                 return $result;
1033         }
1034
1035         if ($markerdata = explode("\n", implode('', file($filename))));
1036         {
1037                 $state = false;
1038                 foreach ($markerdata as $markerline) {
1039                         if (strstr($markerline, "# END {$marker}"))
1040                                 $state = false;
1041                         if ($state)
1042                                 $result[] = $markerline;
1043                         if (strstr($markerline, "# BEGIN {$marker}"))
1044                                 $state = true;
1045                 }
1046         }
1047
1048         return $result;
1049 }
1050
1051 function got_mod_rewrite() {
1052         global $is_apache;
1053
1054         // take 3 educated guesses as to whether or not mod_rewrite is available
1055         if ( !$is_apache )
1056                 return false;
1057
1058         if ( function_exists('apache_get_modules') ) {
1059                 if ( !in_array('mod_rewrite', apache_get_modules()) )
1060                         return false;
1061         }
1062
1063         return true;
1064 }
1065
1066 function save_mod_rewrite_rules() {
1067         global $is_apache, $wp_rewrite;
1068         $home_path = get_home_path();
1069
1070         if (!$wp_rewrite->using_mod_rewrite_permalinks())
1071                 return;
1072
1073         if (!((!file_exists($home_path.'.htaccess') && is_writable($home_path)) || is_writable($home_path.'.htaccess')))
1074                 return;
1075
1076         if (! got_mod_rewrite())
1077                 return;
1078
1079         $rules = explode("\n", $wp_rewrite->mod_rewrite_rules());
1080         insert_with_markers($home_path.'.htaccess', 'WordPress', $rules);
1081 }
1082
1083 function the_quicktags() {
1084         // Browser detection sucks, but until Safari supports the JS needed for this to work people just assume it's a bug in WP
1085         if (!strstr($_SERVER['HTTP_USER_AGENT'], 'Safari'))
1086                 echo '
1087                 <div id="quicktags">
1088                         <script src="../wp-includes/js/quicktags.js" type="text/javascript"></script>
1089                         <script type="text/javascript">if ( typeof tinyMCE == "undefined" || tinyMCE.configs.length < 1 ) edToolbar();</script>
1090                 </div>
1091 ';
1092         else echo '
1093 <script type="text/javascript">
1094 function edInsertContent(myField, myValue) {
1095         //IE support
1096         if (document.selection) {
1097                 myField.focus();
1098                 sel = document.selection.createRange();
1099                 sel.text = myValue;
1100                 myField.focus();
1101         }
1102         //MOZILLA/NETSCAPE support
1103         else if (myField.selectionStart || myField.selectionStart == "0") {
1104                 var startPos = myField.selectionStart;
1105                 var endPos = myField.selectionEnd;
1106                 myField.value = myField.value.substring(0, startPos)
1107                               + myValue 
1108                       + myField.value.substring(endPos, myField.value.length);
1109                 myField.focus();
1110                 myField.selectionStart = startPos + myValue.length;
1111                 myField.selectionEnd = startPos + myValue.length;
1112         } else {
1113                 myField.value += myValue;
1114                 myField.focus();
1115         }
1116 }
1117 </script>
1118 ';
1119 }
1120
1121 function validate_current_theme() {
1122         $theme_loc = 'wp-content/themes';
1123         $theme_root = ABSPATH.$theme_loc;
1124
1125         $template = get_settings('template');
1126         $stylesheet = get_settings('stylesheet');
1127
1128         if (($template != 'default') && (!file_exists("$theme_root/$template/index.php"))) {
1129                 update_option('template', 'default');
1130                 update_option('stylesheet', 'default');
1131                 do_action('switch_theme', 'Default');
1132                 return false;
1133         }
1134
1135         if (($stylesheet != 'default') && (!file_exists("$theme_root/$stylesheet/style.css"))) {
1136                 update_option('template', 'default');
1137                 update_option('stylesheet', 'default');
1138                 do_action('switch_theme', 'Default');
1139                 return false;
1140         }
1141
1142         return true;
1143 }
1144
1145 function get_broken_themes() {
1146         global $wp_broken_themes;
1147
1148         get_themes();
1149         return $wp_broken_themes;
1150 }
1151
1152 function get_page_templates() {
1153         $themes = get_themes();
1154         $theme = get_current_theme();
1155         $templates = $themes[$theme]['Template Files'];
1156         $page_templates = array ();
1157
1158         if (is_array($templates)) {
1159                 foreach ($templates as $template) {
1160                         $template_data = implode('', file(ABSPATH.$template));
1161                         preg_match("|Template Name:(.*)|i", $template_data, $name);
1162                         preg_match("|Description:(.*)|i", $template_data, $description);
1163
1164                         $name = $name[1];
1165                         $description = $description[1];
1166
1167                         if (!empty ($name)) {
1168                                 $page_templates[trim($name)] = basename($template);
1169                         }
1170                 }
1171         }
1172
1173         return $page_templates;
1174 }
1175
1176 function page_template_dropdown($default = '') {
1177         $templates = get_page_templates();
1178         foreach (array_keys($templates) as $template)
1179                 : if ($default == $templates[$template])
1180                         $selected = " selected='selected'";
1181                 else
1182                         $selected = '';
1183         echo "\n\t<option value='".$templates[$template]."' $selected>$template</option>";
1184         endforeach;
1185 }
1186
1187 function parent_dropdown($default = 0, $parent = 0, $level = 0) {
1188         global $wpdb, $post_ID;
1189         $items = $wpdb->get_results("SELECT ID, post_parent, post_title FROM $wpdb->posts WHERE post_parent = $parent AND post_status = 'static' ORDER BY menu_order");
1190
1191         if ($items) {
1192                 foreach ($items as $item) {
1193                         // A page cannot be it's own parent.
1194                         if (!empty ($post_ID)) {
1195                                 if ($item->ID == $post_ID) {
1196                                         continue;
1197                                 }
1198                         }
1199                         $pad = str_repeat('&nbsp;', $level * 3);
1200                         if ($item->ID == $default)
1201                                 $current = ' selected="selected"';
1202                         else
1203                                 $current = '';
1204
1205                         echo "\n\t<option value='$item->ID'$current>$pad $item->post_title</option>";
1206                         parent_dropdown($default, $item->ID, $level +1);
1207                 }
1208         } else {
1209                 return false;
1210         }
1211 }
1212
1213 function user_can_access_admin_page() {
1214         global $pagenow;
1215         global $menu;
1216         global $submenu;
1217         global $plugin_page;
1218
1219         $parent = get_admin_page_parent();
1220
1221         foreach ($menu as $menu_array) {
1222                 //echo "parent array: " . $menu_array[2];
1223                 if ($menu_array[2] == $parent) {
1224                         if (!current_user_can($menu_array[1])) {
1225                                 return false;
1226                         } else {
1227                                 break;
1228                         }
1229                 }
1230         }
1231
1232         if (isset ($submenu[$parent])) {
1233                 if ( isset($plugin_page) ) {
1234                         foreach ($submenu[$parent] as $submenu_array) {
1235                                 if ( $submenu_array[2] == $plugin_page ) {
1236                                         if (!current_user_can($submenu_array[1]))
1237                                                 return false;
1238                                 }
1239                         }
1240                 }
1241
1242                 foreach ($submenu[$parent] as $submenu_array) {         
1243                         if ($submenu_array[2] == $pagenow) {
1244                                 if (!current_user_can($submenu_array[1]))
1245                                         return false;
1246                                 else
1247                                         return true;
1248                         }
1249                 }
1250         }
1251
1252         return true;
1253 }
1254
1255 function get_admin_page_title() {
1256         global $title;
1257         global $menu;
1258         global $submenu;
1259         global $pagenow;
1260         global $plugin_page;
1261
1262         if (isset ($title) && !empty ($title)) {
1263                 return $title;
1264         }
1265
1266         $hook = get_plugin_page_hook($plugin_page, $pagenow);
1267
1268         $parent = $parent1 = get_admin_page_parent();
1269         if (empty ($parent)) {
1270                 foreach ($menu as $menu_array) {
1271                         if (isset ($menu_array[3])) {
1272                                 if ($menu_array[2] == $pagenow) {
1273                                         $title = $menu_array[3];
1274                                         return $menu_array[3];
1275                                 } else
1276                                         if (isset ($plugin_page) && ($plugin_page == $menu_array[2]) && ($hook == $menu_array[3])) {
1277                                                 $title = $menu_array[3];
1278                                                 return $menu_array[3];
1279                                         }
1280                         }
1281                 }
1282         } else {
1283                 foreach (array_keys($submenu) as $parent) {
1284                         foreach ($submenu[$parent] as $submenu_array) {
1285                                 if (isset ($submenu_array[3])) {
1286                                         if ($submenu_array[2] == $pagenow) {
1287                                                 $title = $submenu_array[3];
1288                                                 return $submenu_array[3];
1289                                         } else
1290                                                 if (isset ($plugin_page) && ($plugin_page == $submenu_array[2]) && (($parent == $pagenow) || ($parent == $plugin_page) || ($plugin_page == $hook) || (($pagenow == 'admin.php') && ($parent1 != $submenu_array[2])))) {
1291                                                         $title = $submenu_array[3];
1292                                                         return $submenu_array[3];
1293                                                 }
1294                                 }
1295                         }
1296                 }
1297         }
1298
1299         return '';
1300 }
1301
1302 function get_admin_page_parent() {
1303         global $parent_file;
1304         global $menu;
1305         global $submenu;
1306         global $pagenow;
1307         global $plugin_page;
1308
1309         if (isset ($parent_file) && !empty ($parent_file)) {
1310                 return $parent_file;
1311         }
1312
1313         if ($pagenow == 'admin.php' && isset ($plugin_page)) {
1314                 foreach ($menu as $parent_menu) {
1315                         if ($parent_menu[2] == $plugin_page) {
1316                                 $parent_file = $plugin_page;
1317                                 return $plugin_page;
1318                         }
1319                 }
1320         }
1321
1322         foreach (array_keys($submenu) as $parent) {
1323                 foreach ($submenu[$parent] as $submenu_array) {
1324                         if ($submenu_array[2] == $pagenow) {
1325                                 $parent_file = $parent;
1326                                 return $parent;
1327                         } else
1328                                 if (isset ($plugin_page) && ($plugin_page == $submenu_array[2])) {
1329                                         $parent_file = $parent;
1330                                         return $parent;
1331                                 }
1332                 }
1333         }
1334
1335         $parent_file = '';
1336         return '';
1337 }
1338
1339 function add_menu_page($page_title, $menu_title, $access_level, $file, $function = '') {
1340         global $menu, $admin_page_hooks;
1341
1342         $file = plugin_basename($file);
1343
1344         $menu[] = array ($menu_title, $access_level, $file, $page_title);
1345
1346         $admin_page_hooks[$file] = sanitize_title($menu_title);
1347
1348         $hookname = get_plugin_page_hookname($file, '');
1349         if (!empty ($function) && !empty ($hookname))
1350                 add_action($hookname, $function);
1351
1352         return $hookname;
1353 }
1354
1355 function add_submenu_page($parent, $page_title, $menu_title, $access_level, $file, $function = '') {
1356         global $submenu;
1357         global $menu;
1358
1359         $parent = plugin_basename($parent);
1360         $file = plugin_basename($file);
1361
1362         // If the parent doesn't already have a submenu, add a link to the parent
1363         // as the first item in the submenu.  If the submenu file is the same as the
1364         // parent file someone is trying to link back to the parent manually.  In
1365         // this case, don't automatically add a link back to avoid duplication.
1366         if (!isset ($submenu[$parent]) && $file != $parent) {
1367                 foreach ($menu as $parent_menu) {
1368                         if ($parent_menu[2] == $parent) {
1369                                 $submenu[$parent][] = $parent_menu;
1370                         }
1371                 }
1372         }
1373
1374         $submenu[$parent][] = array ($menu_title, $access_level, $file, $page_title);
1375
1376         $hookname = get_plugin_page_hookname($file, $parent);
1377         if (!empty ($function) && !empty ($hookname))
1378                 add_action($hookname, $function);
1379
1380         return $hookname;
1381 }
1382
1383 function add_options_page($page_title, $menu_title, $access_level, $file, $function = '') {
1384         return add_submenu_page('options-general.php', $page_title, $menu_title, $access_level, $file, $function);
1385 }
1386
1387 function add_management_page($page_title, $menu_title, $access_level, $file, $function = '') {
1388         return add_submenu_page('edit.php', $page_title, $menu_title, $access_level, $file, $function);
1389 }
1390
1391 function add_theme_page($page_title, $menu_title, $access_level, $file, $function = '') {
1392         return add_submenu_page('themes.php', $page_title, $menu_title, $access_level, $file, $function);
1393 }
1394
1395 function validate_file($file, $allowed_files = '') {
1396         if (false !== strpos($file, './'))
1397                 return 1;
1398
1399         if (':' == substr($file, 1, 1))
1400                 return 2;
1401
1402         if (!empty ($allowed_files) && (!in_array($file, $allowed_files)))
1403                 return 3;
1404
1405         return 0;
1406 }
1407
1408 function validate_file_to_edit($file, $allowed_files = '') {
1409         $file = stripslashes($file);
1410
1411         $code = validate_file($file, $allowed_files);
1412
1413         if (!$code)
1414                 return $file;
1415
1416         switch ($code) {
1417                 case 1 :
1418                         die(__('Sorry, can&#8217;t edit files with ".." in the name. If you are trying to edit a file in your WordPress home directory, you can just type the name of the file in.'));
1419
1420                 case 2 :
1421                         die(__('Sorry, can&#8217;t call files with their real path.'));
1422
1423                 case 3 :
1424                         die(__('Sorry, that file cannot be edited.'));
1425         }
1426 }
1427
1428 function get_home_path() {
1429         $home = get_settings('home');
1430         if ($home != '' && $home != get_settings('siteurl')) {
1431                 $home_path = parse_url($home);
1432                 $home_path = $home_path['path'];
1433                 $root = str_replace($_SERVER["PHP_SELF"], '', $_SERVER["SCRIPT_FILENAME"]);
1434                 $home_path = trailingslashit($root.$home_path);
1435         } else {
1436                 $home_path = ABSPATH;
1437         }
1438
1439         return $home_path;
1440 }
1441
1442 function get_real_file_to_edit($file) {
1443         if ('index.php' == $file || '.htaccess' == $file) {
1444                 $real_file = get_home_path().$file;
1445         } else {
1446                 $real_file = ABSPATH.$file;
1447         }
1448
1449         return $real_file;
1450 }
1451
1452 $wp_file_descriptions = array ('index.php' => __('Main Index Template'), 'style.css' => __('Stylesheet'), 'comments.php' => __('Comments'), 'comments-popup.php' => __('Popup Comments'), 'footer.php' => __('Footer'), 'header.php' => __('Header'), 'sidebar.php' => __('Sidebar'), 'archive.php' => __('Archives'), 'category.php' => __('Category Template'), 'page.php' => __('Page Template'), 'search.php' => __('Search Results'), 'single.php' => __('Single Post'), '404.php' => __('404 Template'), 'my-hacks.php' => __('my-hacks.php (legacy hacks support)'), '.htaccess' => __('.htaccess (for rewrite rules)'),
1453         // Deprecated files
1454         'wp-layout.css' => __('Stylesheet'), 'wp-comments.php' => __('Comments Template'), 'wp-comments-popup.php' => __('Popup Comments Template'));
1455
1456 function get_file_description($file) {
1457         global $wp_file_descriptions;
1458
1459         if (isset ($wp_file_descriptions[basename($file)])) {
1460                 return $wp_file_descriptions[basename($file)];
1461         }
1462         elseif (file_exists(ABSPATH.$file)) {
1463                 $template_data = implode('', file(ABSPATH.$file));
1464                 if (preg_match("|Template Name:(.*)|i", $template_data, $name))
1465                         return $name[1];
1466         }
1467
1468         return basename($file);
1469 }
1470
1471 function update_recently_edited($file) {
1472         $oldfiles = (array) get_option('recently_edited');
1473         if ($oldfiles) {
1474                 $oldfiles = array_reverse($oldfiles);
1475                 $oldfiles[] = $file;
1476                 $oldfiles = array_reverse($oldfiles);
1477                 $oldfiles = array_unique($oldfiles);
1478                 if (5 < count($oldfiles))
1479                         array_pop($oldfiles);
1480         } else {
1481                 $oldfiles[] = $file;
1482         }
1483         update_option('recently_edited', $oldfiles);
1484 }
1485
1486 function get_plugin_data($plugin_file) {
1487         $plugin_data = implode('', file($plugin_file));
1488         preg_match("|Plugin Name:(.*)|i", $plugin_data, $plugin_name);
1489         preg_match("|Plugin URI:(.*)|i", $plugin_data, $plugin_uri);
1490         preg_match("|Description:(.*)|i", $plugin_data, $description);
1491         preg_match("|Author:(.*)|i", $plugin_data, $author_name);
1492         preg_match("|Author URI:(.*)|i", $plugin_data, $author_uri);
1493         if (preg_match("|Version:(.*)|i", $plugin_data, $version))
1494                 $version = trim($version[1]);
1495         else
1496                 $version = '';
1497
1498         $description = wptexturize(trim($description[1]));
1499
1500         $name = $plugin_name[1];
1501         $name = trim($name);
1502         $plugin = $name;
1503         if ('' != $plugin_uri[1] && '' != $name) {
1504                 $plugin = '<a href="' . trim($plugin_uri[1]) . '" title="'.__('Visit plugin homepage').'">'.$plugin.'</a>';
1505         }
1506
1507         if ('' == $author_uri[1]) {
1508                 $author = trim($author_name[1]);
1509         } else {
1510                 $author = '<a href="' . trim($author_uri[1]) . '" title="'.__('Visit author homepage').'">' . trim($author_name[1]) . '</a>';
1511         }
1512
1513         return array ('Name' => $name, 'Title' => $plugin, 'Description' => $description, 'Author' => $author, 'Version' => $version, 'Template' => $template[1]);
1514 }
1515
1516 function get_plugins() {
1517         global $wp_plugins;
1518
1519         if (isset ($wp_plugins)) {
1520                 return $wp_plugins;
1521         }
1522
1523         $wp_plugins = array ();
1524         $plugin_loc = 'wp-content/plugins';
1525         $plugin_root = ABSPATH.$plugin_loc;
1526
1527         // Files in wp-content/plugins directory
1528         $plugins_dir = @ dir($plugin_root);
1529         if ($plugins_dir) {
1530                 while (($file = $plugins_dir->read()) !== false) {
1531                         if (preg_match('|^\.+$|', $file))
1532                                 continue;
1533                         if (is_dir($plugin_root.'/'.$file)) {
1534                                 $plugins_subdir = @ dir($plugin_root.'/'.$file);
1535                                 if ($plugins_subdir) {
1536                                         while (($subfile = $plugins_subdir->read()) !== false) {
1537                                                 if (preg_match('|^\.+$|', $subfile))
1538                                                         continue;
1539                                                 if (preg_match('|\.php$|', $subfile))
1540                                                         $plugin_files[] = "$file/$subfile";
1541                                         }
1542                                 }
1543                         } else {
1544                                 if (preg_match('|\.php$|', $file))
1545                                         $plugin_files[] = $file;
1546                         }
1547                 }
1548         }
1549
1550         if (!$plugins_dir || !$plugin_files) {
1551                 return $wp_plugins;
1552         }
1553
1554         sort($plugin_files);
1555
1556         foreach ($plugin_files as $plugin_file) {
1557                 if ( !is_readable("$plugin_root/$plugin_file"))
1558                         continue;
1559
1560                 $plugin_data = get_plugin_data("$plugin_root/$plugin_file");
1561
1562                 if (empty ($plugin_data['Name'])) {
1563                         continue;
1564                 }
1565
1566                 $wp_plugins[plugin_basename($plugin_file)] = $plugin_data;
1567         }
1568
1569         return $wp_plugins;
1570 }
1571
1572 function get_plugin_page_hookname($plugin_page, $parent_page) {
1573         global $admin_page_hooks;
1574
1575         $parent = get_admin_page_parent();
1576
1577         if (empty ($parent_page) || 'admin.php' == $parent_page) {
1578                 if (isset ($admin_page_hooks[$plugin_page]))
1579                         $page_type = 'toplevel';
1580                 else
1581                         if (isset ($admin_page_hooks[$parent]))
1582                                 $page_type = $admin_page_hooks[$parent];
1583         } else
1584                 if (isset ($admin_page_hooks[$parent_page])) {
1585                         $page_type = $admin_page_hooks[$parent_page];
1586                 } else {
1587                         $page_type = 'admin';
1588                 }
1589
1590         $plugin_name = preg_replace('!\.php!', '', $plugin_page);
1591
1592         return $page_type.'_page_'.$plugin_name;
1593 }
1594
1595 function get_plugin_page_hook($plugin_page, $parent_page) {
1596         global $wp_filter;
1597
1598         $hook = get_plugin_page_hookname($plugin_page, $parent_page);
1599         if (isset ($wp_filter[$hook]))
1600                 return $hook;
1601         else
1602                 return '';
1603 }
1604
1605 function browse_happy() {
1606         $getit = __('WordPress recommends a better browser');
1607         echo '
1608                 <p id="bh" style="text-align: center;"><a href="http://browsehappy.com/" title="'.$getit.'"><img src="images/browse-happy.gif" alt="Browse Happy" /></a></p>
1609                 ';
1610 }
1611 if (strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE'))
1612         add_action('admin_footer', 'browse_happy');
1613
1614 function documentation_link($for) {
1615         return;
1616 }
1617
1618 function register_importer($id, $name, $description, $callback) {
1619         global $wp_importers;
1620
1621         $wp_importers[$id] = array ($name, $description, $callback);
1622 }
1623
1624 function get_importers() {
1625         global $wp_importers;
1626
1627         return $wp_importers;
1628 }
1629
1630 function current_theme_info() {
1631         $themes = get_themes();
1632         $current_theme = get_current_theme();
1633         $ct->name = $current_theme;
1634         $ct->title = $themes[$current_theme]['Title'];
1635         $ct->version = $themes[$current_theme]['Version'];
1636         $ct->parent_theme = $themes[$current_theme]['Parent Theme'];
1637         $ct->template_dir = $themes[$current_theme]['Template Dir'];
1638         $ct->stylesheet_dir = $themes[$current_theme]['Stylesheet Dir'];
1639         $ct->template = $themes[$current_theme]['Template'];
1640         $ct->stylesheet = $themes[$current_theme]['Stylesheet'];
1641         $ct->screenshot = $themes[$current_theme]['Screenshot'];
1642         $ct->description = $themes[$current_theme]['Description'];
1643         $ct->author = $themes[$current_theme]['Author'];
1644         return $ct;
1645 }
1646
1647
1648 // array wp_handle_upload ( array &file [, array overrides] )
1649 // file: reference to a single element of $_FILES. Call the function once for each uploaded file.
1650 // overrides: an associative array of names=>values to override default variables with extract($overrides, EXTR_OVERWRITE).
1651 // On success, returns an associative array of file attributes.
1652 // On failure, returns $overrides['upload_error_handler'](&$file, $message) or array('error'=>$message).
1653 function wp_handle_upload(&$file, $overrides = false) {
1654         // The default error handler.
1655         if (! function_exists('wp_handle_upload_error') ) {
1656                 function wp_handle_upload_error(&$file, $message) {
1657                         return array('error'=>$message);
1658                 }
1659         }
1660
1661         // You may define your own function and pass the name in $overrides['upload_error_handler']
1662         $upload_error_handler = 'wp_handle_upload_error';
1663
1664         // $_POST['action'] must be set and its value must equal $overrides['action'] or this:
1665         $action = 'wp_handle_upload';
1666
1667         // Courtesy of php.net, the strings that describe the error indicated in $_FILES[{form field}]['error'].
1668         $upload_error_strings = array(false,
1669                 __("The uploaded file exceeds the <code>upload_max_filesize</code> directive in <code>php.ini</code>."),
1670                 __("The uploaded file exceeds the <em>MAX_FILE_SIZE</em> directive that was specified in the HTML form."),
1671                 __("The uploaded file was only partially uploaded."),
1672                 __("No file was uploaded."),
1673                 __("Missing a temporary folder."),
1674                 __("Failed to write file to disk."));
1675
1676         // All tests are on by default. Most can be turned off by $override[{test_name}] = false;
1677         $test_form = true;
1678         $test_size = true;
1679
1680         // If you override this, you must provide $ext and $type!!!!
1681         $test_type = true;
1682
1683         // Install user overrides. Did we mention that this voids your warranty?
1684         if ( is_array($overrides) )
1685                 extract($overrides, EXTR_OVERWRITE);
1686
1687         // A correct form post will pass this test.
1688         if ( $test_form && (!isset($_POST['action']) || ($_POST['action'] != $action)) )
1689                 return $upload_error_handler($file, __('Invalid form submission.'));
1690
1691         // A successful upload will pass this test. It makes no sense to override this one.
1692         if ( $file['error'] > 0 )
1693                 return $upload_error_handler($file, $upload_error_strings[$file['error']]);
1694
1695         // A non-empty file will pass this test.
1696         if ( $test_size && !($file['size'] > 0) )
1697                 return $upload_error_handler($file, __('File is empty. Please upload something more substantial.'));
1698
1699         // A properly uploaded file will pass this test. There should be no reason to override this one.
1700         if (! @ is_uploaded_file($file['tmp_name']) )
1701                 return $upload_error_handler($file, __('Specified file failed upload test.'));
1702
1703         // A correct MIME type will pass this test. Override $mimes or use the upload_mimes filter.
1704         if ( $test_type ) {
1705                 $wp_filetype = wp_check_filetype($file['name'], $mimes);
1706
1707                 extract($wp_filetype);
1708
1709                 if ( !$type || !$ext )
1710                         return $upload_error_handler($file, __('File type does not meet security guidelines. Try another.'));
1711         }
1712
1713         // A writable uploads dir will pass this test. Again, there's no point overriding this one.
1714         if ( ! ( ( $uploads = wp_upload_dir() ) && false === $uploads['error'] ) )
1715                 return $upload_error_handler($file, $uploads['error']);
1716
1717         // Increment the file number until we have a unique file to save in $dir. Use $override['unique_filename_callback'] if supplied.
1718         if ( isset($unique_filename_callback) && function_exists($unique_filename_callback) ) {
1719                 $filename = $unique_filename_callback($uploads['path'], $file['name']);
1720         } else {
1721                 $number = '';
1722                 $filename = str_replace('#', '_', $file['name']);
1723                 $filename = str_replace(array('\\', "'"), '', $filename);
1724                 if ( empty($ext) )
1725                         $ext = '';
1726                 else
1727                         $ext = ".$ext";
1728                 while ( file_exists($uploads['path'] . "/$filename") ) {
1729                         if ( '' == "$number$ext" )
1730                                 $filename = $filename . ++$number . $ext;
1731                         else
1732                                 $filename = str_replace("$number$ext", ++$number . $ext, $filename);
1733                 }
1734                 $filename = str_replace($ext, '', $filename);
1735                 $filename = sanitize_title_with_dashes($filename) . $ext;
1736         }
1737
1738         // Move the file to the uploads dir
1739         $new_file = $uploads['path'] . "/$filename";
1740         if ( false === @ move_uploaded_file($file['tmp_name'], $new_file) )
1741                 die(printf(__('The uploaded file could not be moved to %s.'), $file['path']));
1742
1743         // Set correct file permissions
1744         $stat = stat(dirname($new_file));
1745         $perms = $stat['mode'] & 0000666;
1746         @ chmod($new_file, $perms);
1747
1748         // Compute the URL
1749         $url = $uploads['url'] . "/$filename";
1750
1751         return array('file' => $new_file, 'url' => $url, 'type' => $type);
1752 }
1753
1754 function wp_shrink_dimensions($width, $height, $wmax = 128, $hmax = 96) {
1755         if ( $height <= $hmax && $width <= $wmax )
1756                 return array($width, $height);
1757         elseif ( $width / $height > $wmax / $hmax )
1758                 return array($wmax, (int) ($height / $width * $wmax));
1759         else
1760                 return array((int) ($width / $height * $hmax), $hmax);
1761 }
1762
1763 function wp_import_cleanup($id) {
1764         wp_delete_attachment($id);
1765 }
1766
1767 function wp_import_upload_form($action) {
1768 ?>
1769 <script type="text/javascript">
1770 function cancelUpload() {
1771 o = document.getElementById('uploadForm');
1772 o.method = 'GET';
1773 o.action.value = 'view';
1774 o.submit();
1775 }
1776 </script>
1777 <form enctype="multipart/form-data" id="uploadForm" method="post" action="<?php echo $action ?>">
1778 <label for="upload"><?php _e('File:'); ?></label><input type="file" id="upload" name="import" />
1779 <input type="hidden" name="action" value="save" />
1780 <div id="buttons">
1781 <input type="submit" value="<?php _e('Import'); ?>" />
1782 <input type="button" value="<?php _e('Cancel'); ?>" onclick="cancelUpload()" />
1783 </div>
1784 </form>
1785 <?php   
1786 }
1787
1788 function wp_import_handle_upload() {
1789         $overrides = array('test_form' => false, 'test_type' => false);
1790         $file = wp_handle_upload($_FILES['import'], $overrides);
1791
1792         if ( isset($file['error']) )
1793                 return $file;
1794
1795         $url = $file['url'];
1796         $file = $file['file'];
1797         $filename = basename($file);
1798
1799         // Construct the object array
1800         $object = array(
1801                 'post_title' => $filename,
1802                 'post_content' => $url,
1803                 'post_mime_type' => 'import',
1804                 'guid' => $url
1805         );
1806
1807         // Save the data
1808         $id = wp_insert_attachment($object, $file);
1809
1810         return array('file' => $file, 'id' => $id);
1811 }
1812
1813 function user_can_richedit() {
1814         if ( 'true' != get_user_option('rich_editing') )
1815                 return false;
1816
1817         if ( preg_match('!opera[ /][2-8]|konqueror|safari!i', $_SERVER['HTTP_USER_AGENT']) )
1818                 return false;
1819
1820         return true; // Best guess
1821 }
1822
1823 function the_attachment_links($id = false) {
1824         $id = (int) $id;
1825         $post = & get_post($id);
1826
1827         if ( $post->post_status != 'attachment' )
1828                 return false;
1829
1830         $icon = get_attachment_icon($post->ID);
1831
1832 ?>
1833 <p><?php _e('Text linked to file') ?><br />
1834 <textarea rows="1" cols="40" type="text" class="attachmentlinks" readonly="readonly"><a href="<?php echo $post->guid ?>" class="attachmentlink"><?php echo basename($post->guid) ?></a></textarea></p>
1835 <p><?php _e('Text linked to subpost') ?><br />
1836 <textarea rows="1" cols="40" type="text" class="attachmentlinks" readonly="readonly"><a href="<?php echo get_attachment_link($post->ID) ?>" rel="attachment" id="<?php echo $post->ID ?>"><?php echo $post->post_title ?></a></textarea></p>
1837 <?php if ( $icon ) : ?>
1838 <p><?php _e('Thumbnail linked to file') ?><br />
1839 <textarea rows="1" cols="40" type="text" class="attachmentlinks" readonly="readonly"><a href="<?php echo $post->guid ?>" class="attachmentlink"><?php echo $icon ?></a></textarea></p>
1840 <p><?php _e('Thumbnail linked to subpost') ?><br />
1841 <textarea rows="1" cols="40" type="text" class="attachmentlinks" readonly="readonly"><a href="<?php echo get_attachment_link($post->ID) ?>" rel="attachment" id="<?php echo $post->ID ?>"><?php echo $icon ?></a></textarea></p>
1842 <?php endif; ?>
1843 <?php
1844 }
1845
1846 function get_udims($width, $height) {
1847         if ( $height <= 96 && $width <= 128 )
1848                 return array($width, $height);
1849         elseif ( $width / $height > 4 / 3 )
1850                 return array(128, (int) ($height / $width * 128));
1851         else
1852                 return array((int) ($width / $height * 96), 96);
1853 }
1854
1855 ?>