]> scripts.mit.edu Git - autoinstalls/wordpress.git/blob - wp-admin/includes/post.php
Wordpress 2.8.5-scripts
[autoinstalls/wordpress.git] / wp-admin / includes / post.php
1 <?php
2 /**
3  * WordPress Post Administration API.
4  *
5  * @package WordPress
6  * @subpackage Administration
7  */
8
9 /**
10  * Rename $_POST data from form names to DB post columns.
11  *
12  * Manipulates $_POST directly.
13  *
14  * @package WordPress
15  * @since 2.6.0
16  *
17  * @param bool $update Are we updating a pre-existing post?
18  * @param post_data array Array of post data. Defaults to the contents of $_POST.
19  * @return object|bool WP_Error on failure, true on success.
20  */
21 function _wp_translate_postdata( $update = false, $post_data = null ) {
22
23         if ( empty($post_data) )
24                 $post_data = &$_POST;
25
26         if ( $update )
27                 $post_data['ID'] = (int) $post_data['post_ID'];
28         $post_data['post_content'] = isset($post_data['content']) ? $post_data['content'] : '';
29         $post_data['post_excerpt'] = isset($post_data['excerpt']) ? $post_data['excerpt'] : '';
30         $post_data['post_parent'] = isset($post_data['parent_id'])? $post_data['parent_id'] : '';
31         if ( isset($post_data['trackback_url']) )
32                 $post_data['to_ping'] = $post_data['trackback_url'];
33
34         if (!empty ( $post_data['post_author_override'] ) ) {
35                 $post_data['post_author'] = (int) $post_data['post_author_override'];
36         } else {
37                 if (!empty ( $post_data['post_author'] ) ) {
38                         $post_data['post_author'] = (int) $post_data['post_author'];
39                 } else {
40                         $post_data['post_author'] = (int) $post_data['user_ID'];
41                 }
42         }
43
44         if ( isset($post_data['user_ID']) && ($post_data['post_author'] != $post_data['user_ID']) ) {
45                 if ( 'page' == $post_data['post_type'] ) {
46                         if ( !current_user_can( 'edit_others_pages' ) ) {
47                                 return new WP_Error( 'edit_others_pages', $update ?
48                                         __( 'You are not allowed to edit pages as this user.' ) :
49                                         __( 'You are not allowed to create pages as this user.' )
50                                 );
51                         }
52                 } else {
53                         if ( !current_user_can( 'edit_others_posts' ) ) {
54                                 return new WP_Error( 'edit_others_posts', $update ?
55                                         __( 'You are not allowed to edit posts as this user.' ) :
56                                         __( 'You are not allowed to post as this user.' )
57                                 );
58                         }
59                 }
60         }
61
62         // What to do based on which button they pressed
63         if ( isset($post_data['saveasdraft']) && '' != $post_data['saveasdraft'] )
64                 $post_data['post_status'] = 'draft';
65         if ( isset($post_data['saveasprivate']) && '' != $post_data['saveasprivate'] )
66                 $post_data['post_status'] = 'private';
67         if ( isset($post_data['publish']) && ( '' != $post_data['publish'] ) && ( $post_data['post_status'] != 'private' ) )
68                 $post_data['post_status'] = 'publish';
69         if ( isset($post_data['advanced']) && '' != $post_data['advanced'] )
70                 $post_data['post_status'] = 'draft';
71         if ( isset($post_data['pending']) && '' != $post_data['pending'] )
72                 $post_data['post_status'] = 'pending';
73
74         $previous_status = get_post_field('post_status',  isset($post_data['ID']) ? $post_data['ID'] : $post_data['temp_ID']);
75
76         // Posts 'submitted for approval' present are submitted to $_POST the same as if they were being published.
77         // Change status from 'publish' to 'pending' if user lacks permissions to publish or to resave published posts.
78         if ( 'page' == $post_data['post_type'] ) {
79                 $publish_cap = 'publish_pages';
80                 $edit_cap = 'edit_published_pages';
81         } else {
82                 $publish_cap = 'publish_posts';
83                 $edit_cap = 'edit_published_posts';
84         }
85         if ( isset($post_data['post_status']) && ('publish' == $post_data['post_status'] && !current_user_can( $publish_cap )) )
86                 if ( $previous_status != 'publish' || !current_user_can( $edit_cap ) )
87                         $post_data['post_status'] = 'pending';
88
89         if ( ! isset($post_data['post_status']) )
90                 $post_data['post_status'] = $previous_status;
91
92         if (!isset( $post_data['comment_status'] ))
93                 $post_data['comment_status'] = 'closed';
94
95         if (!isset( $post_data['ping_status'] ))
96                 $post_data['ping_status'] = 'closed';
97
98         foreach ( array('aa', 'mm', 'jj', 'hh', 'mn') as $timeunit ) {
99                 if ( !empty( $post_data['hidden_' . $timeunit] ) && $post_data['hidden_' . $timeunit] != $post_data[$timeunit] ) {
100                         $post_data['edit_date'] = '1';
101                         break;
102                 }
103         }
104
105         if ( !empty( $post_data['edit_date'] ) ) {
106                 $aa = $post_data['aa'];
107                 $mm = $post_data['mm'];
108                 $jj = $post_data['jj'];
109                 $hh = $post_data['hh'];
110                 $mn = $post_data['mn'];
111                 $ss = $post_data['ss'];
112                 $aa = ($aa <= 0 ) ? date('Y') : $aa;
113                 $mm = ($mm <= 0 ) ? date('n') : $mm;
114                 $jj = ($jj > 31 ) ? 31 : $jj;
115                 $jj = ($jj <= 0 ) ? date('j') : $jj;
116                 $hh = ($hh > 23 ) ? $hh -24 : $hh;
117                 $mn = ($mn > 59 ) ? $mn -60 : $mn;
118                 $ss = ($ss > 59 ) ? $ss -60 : $ss;
119                 $post_data['post_date'] = sprintf( "%04d-%02d-%02d %02d:%02d:%02d", $aa, $mm, $jj, $hh, $mn, $ss );
120                 $post_data['post_date_gmt'] = get_gmt_from_date( $post_data['post_date'] );
121         }
122
123         return $post_data;
124 }
125
126 /**
127  * Update an existing post with values provided in $_POST.
128  *
129  * @since unknown
130  *
131  * @param array $post_data Optional.
132  * @return int Post ID.
133  */
134 function edit_post( $post_data = null ) {
135
136         if ( empty($post_data) )
137                 $post_data = &$_POST;
138
139         $post_ID = (int) $post_data['post_ID'];
140
141         if ( 'page' == $post_data['post_type'] ) {
142                 if ( !current_user_can( 'edit_page', $post_ID ) )
143                         wp_die( __('You are not allowed to edit this page.' ));
144         } else {
145                 if ( !current_user_can( 'edit_post', $post_ID ) )
146                         wp_die( __('You are not allowed to edit this post.' ));
147         }
148
149         // Autosave shouldn't save too soon after a real save
150         if ( 'autosave' == $post_data['action'] ) {
151                 $post =& get_post( $post_ID );
152                 $now = time();
153                 $then = strtotime($post->post_date_gmt . ' +0000');
154                 $delta = AUTOSAVE_INTERVAL / 2;
155                 if ( ($now - $then) < $delta )
156                         return $post_ID;
157         }
158
159         $post_data = _wp_translate_postdata( true, $post_data );
160         if ( is_wp_error($post_data) )
161                 wp_die( $post_data->get_error_message() );
162
163         if ( isset($post_data['visibility']) ) {
164                 switch ( $post_data['visibility'] ) {
165                         case 'public' :
166                                 $post_data['post_password'] = '';
167                                 break;
168                         case 'password' :
169                                 unset( $post_data['sticky'] );
170                                 break;
171                         case 'private' :
172                                 $post_data['post_status'] = 'private';
173                                 $post_data['post_password'] = '';
174                                 unset( $post_data['sticky'] );
175                                 break;
176                 }
177         }
178
179         // Meta Stuff
180         if ( isset($post_data['meta']) && $post_data['meta'] ) {
181                 foreach ( $post_data['meta'] as $key => $value )
182                         update_meta( $key, $value['key'], $value['value'] );
183         }
184
185         if ( isset($post_data['deletemeta']) && $post_data['deletemeta'] ) {
186                 foreach ( $post_data['deletemeta'] as $key => $value )
187                         delete_meta( $key );
188         }
189
190         add_meta( $post_ID );
191
192         wp_update_post( $post_data );
193
194         // Reunite any orphaned attachments with their parent
195         if ( !$draft_ids = get_user_option( 'autosave_draft_ids' ) )
196                 $draft_ids = array();
197         if ( $draft_temp_id = (int) array_search( $post_ID, $draft_ids ) )
198                 _relocate_children( $draft_temp_id, $post_ID );
199
200         // Now that we have an ID we can fix any attachment anchor hrefs
201         _fix_attachment_links( $post_ID );
202
203         wp_set_post_lock( $post_ID, $GLOBALS['current_user']->ID );
204
205         if ( current_user_can( 'edit_others_posts' ) ) {
206                 if ( !empty($post_data['sticky']) )
207                         stick_post($post_ID);
208                 else
209                         unstick_post($post_ID);
210         }
211
212         return $post_ID;
213 }
214
215 /**
216  * {@internal Missing Short Description}}
217  *
218  * Updates all bulk edited posts/pages, adding (but not removing) tags and
219  * categories. Skips pages when they would be their own parent or child.
220  *
221  * @since unknown
222  *
223  * @return array
224  */
225 function bulk_edit_posts( $post_data = null ) {
226         global $wpdb;
227
228         if ( empty($post_data) )
229                 $post_data = &$_POST;
230
231         if ( isset($post_data['post_type']) && 'page' == $post_data['post_type'] ) {
232                 if ( ! current_user_can( 'edit_pages' ) )
233                         wp_die( __('You are not allowed to edit pages.') );
234         } else {
235                 if ( ! current_user_can( 'edit_posts' ) )
236                         wp_die( __('You are not allowed to edit posts.') );
237         }
238
239         $post_IDs = array_map( 'intval', (array) $post_data['post'] );
240
241         $reset = array( 'post_author', 'post_status', 'post_password', 'post_parent', 'page_template', 'comment_status', 'ping_status', 'keep_private', 'tags_input', 'post_category', 'sticky' );
242         foreach ( $reset as $field ) {
243                 if ( isset($post_data[$field]) && ( '' == $post_data[$field] || -1 == $post_data[$field] ) )
244                         unset($post_data[$field]);
245         }
246
247         if ( isset($post_data['post_category']) ) {
248                 if ( is_array($post_data['post_category']) && ! empty($post_data['post_category']) )
249                         $new_cats = array_map( 'absint', $post_data['post_category'] );
250                 else
251                         unset($post_data['post_category']);
252         }
253
254         if ( isset($post_data['tags_input']) ) {
255                 $new_tags = preg_replace( '/\s*,\s*/', ',', rtrim( trim($post_data['tags_input']), ' ,' ) );
256                 $new_tags = explode(',', $new_tags);
257         }
258
259         if ( isset($post_data['post_parent']) && ($parent = (int) $post_data['post_parent']) ) {
260                 $pages = $wpdb->get_results("SELECT ID, post_parent FROM $wpdb->posts WHERE post_type = 'page'");
261                 $children = array();
262
263                 for ( $i = 0; $i < 50 && $parent > 0; $i++ ) {
264                         $children[] = $parent;
265
266                         foreach ( $pages as $page ) {
267                                 if ( $page->ID == $parent ) {
268                                         $parent = $page->post_parent;
269                                         break;
270                                 }
271                         }
272                 }
273         }
274
275         $updated = $skipped = $locked = array();
276         foreach ( $post_IDs as $post_ID ) {
277
278                 if ( isset($children) && in_array($post_ID, $children) ) {
279                         $skipped[] = $post_ID;
280                         continue;
281                 }
282
283                 if ( wp_check_post_lock( $post_ID ) ) {
284                         $locked[] = $post_ID;
285                         continue;
286                 }
287
288                 if ( isset($new_cats) ) {
289                         $cats = (array) wp_get_post_categories($post_ID);
290                         $post_data['post_category'] = array_unique( array_merge($cats, $new_cats) );
291                 }
292
293                 if ( isset($new_tags) ) {
294                         $tags = wp_get_post_tags($post_ID, array('fields' => 'names'));
295                         $post_data['tags_input'] = array_unique( array_merge($tags, $new_tags) );
296                 }
297
298                 $post_data['ID'] = $post_ID;
299                 $updated[] = wp_update_post( $post_data );
300
301                 if ( current_user_can( 'edit_others_posts' ) && isset( $post_data['sticky'] ) ) {
302                         if ( 'sticky' == $post_data['sticky'] )
303                                 stick_post( $post_ID );
304                         else
305                                 unstick_post( $post_ID );
306                 }
307
308         }
309
310         return array( 'updated' => $updated, 'skipped' => $skipped, 'locked' => $locked );
311 }
312
313 /**
314  * Default post information to use when populating the "Write Post" form.
315  *
316  * @since unknown
317  *
318  * @return unknown
319  */
320 function get_default_post_to_edit() {
321         if ( !empty( $_REQUEST['post_title'] ) )
322                 $post_title = esc_html( stripslashes( $_REQUEST['post_title'] ));
323         else if ( !empty( $_REQUEST['popuptitle'] ) ) {
324                 $post_title = esc_html( stripslashes( $_REQUEST['popuptitle'] ));
325                 $post_title = funky_javascript_fix( $post_title );
326         } else {
327                 $post_title = '';
328         }
329
330         $post_content = '';
331         if ( !empty( $_REQUEST['content'] ) )
332                 $post_content = esc_html( stripslashes( $_REQUEST['content'] ));
333         else if ( !empty( $post_title ) ) {
334                 $text       = esc_html( stripslashes( urldecode( $_REQUEST['text'] ) ) );
335                 $text       = funky_javascript_fix( $text);
336                 $popupurl   = esc_url($_REQUEST['popupurl']);
337                 $post_content = '<a href="'.$popupurl.'">'.$post_title.'</a>'."\n$text";
338         }
339
340         if ( !empty( $_REQUEST['excerpt'] ) )
341                 $post_excerpt = esc_html( stripslashes( $_REQUEST['excerpt'] ));
342         else
343                 $post_excerpt = '';
344
345         $post->ID = 0;
346         $post->post_name = '';
347         $post->post_author = '';
348         $post->post_date = '';
349         $post->post_date_gmt = '';
350         $post->post_password = '';
351         $post->post_status = 'draft';
352         $post->post_type = 'post';
353         $post->to_ping = '';
354         $post->pinged = '';
355         $post->comment_status = get_option( 'default_comment_status' );
356         $post->ping_status = get_option( 'default_ping_status' );
357         $post->post_pingback = get_option( 'default_pingback_flag' );
358         $post->post_category = get_option( 'default_category' );
359         $post->post_content = apply_filters( 'default_content', $post_content);
360         $post->post_title = apply_filters( 'default_title', $post_title );
361         $post->post_excerpt = apply_filters( 'default_excerpt', $post_excerpt);
362         $post->page_template = 'default';
363         $post->post_parent = 0;
364         $post->menu_order = 0;
365
366         return $post;
367 }
368
369 /**
370  * {@internal Missing Short Description}}
371  *
372  * @since unknown
373  *
374  * @return unknown
375  */
376 function get_default_page_to_edit() {
377         $page = get_default_post_to_edit();
378         $page->post_type = 'page';
379         return $page;
380 }
381
382 /**
383  * Get an existing post and format it for editing.
384  *
385  * @since unknown
386  *
387  * @param unknown_type $id
388  * @return unknown
389  */
390 function get_post_to_edit( $id ) {
391
392         $post = get_post( $id, OBJECT, 'edit' );
393
394         if ( $post->post_type == 'page' )
395                 $post->page_template = get_post_meta( $id, '_wp_page_template', true );
396
397         return $post;
398 }
399
400 /**
401  * Determine if a post exists based on title, content, and date
402  *
403  * @since unknown
404  *
405  * @param string $title Post title
406  * @param string $content Optional post content
407  * @param string $date Optional post date
408  * @return int Post ID if post exists, 0 otherwise.
409  */
410 function post_exists($title, $content = '', $date = '') {
411         global $wpdb;
412
413         $post_title = stripslashes( sanitize_post_field( 'post_title', $title, 0, 'db' ) );
414         $post_content = stripslashes( sanitize_post_field( 'post_content', $content, 0, 'db' ) );
415         $post_date = stripslashes( sanitize_post_field( 'post_date', $date, 0, 'db' ) );
416
417         $query = "SELECT ID FROM $wpdb->posts WHERE 1=1";
418         $args = array();
419
420         if ( !empty ( $date ) ) {
421                 $query .= ' AND post_date = %s';
422                 $args[] = $post_date;
423         }
424
425         if ( !empty ( $title ) ) {
426                 $query .= ' AND post_title = %s';
427                 $args[] = $post_title;
428         }
429
430         if ( !empty ( $content ) ) {
431                 $query .= 'AND post_content = %s';
432                 $args[] = $post_content;
433         }
434
435         if ( !empty ( $args ) )
436                 return $wpdb->get_var( $wpdb->prepare($query, $args) );
437
438         return 0;
439 }
440
441 /**
442  * Creates a new post from the "Write Post" form using $_POST information.
443  *
444  * @since unknown
445  *
446  * @return unknown
447  */
448 function wp_write_post() {
449         global $user_ID;
450
451         if ( 'page' == $_POST['post_type'] ) {
452                 if ( !current_user_can( 'edit_pages' ) )
453                         return new WP_Error( 'edit_pages', __( 'You are not allowed to create pages on this blog.' ) );
454         } else {
455                 if ( !current_user_can( 'edit_posts' ) )
456                         return new WP_Error( 'edit_posts', __( 'You are not allowed to create posts or drafts on this blog.' ) );
457         }
458
459
460         // Check for autosave collisions
461         $temp_id = false;
462         if ( isset($_POST['temp_ID']) ) {
463                 $temp_id = (int) $_POST['temp_ID'];
464                 if ( !$draft_ids = get_user_option( 'autosave_draft_ids' ) )
465                         $draft_ids = array();
466                 foreach ( $draft_ids as $temp => $real )
467                         if ( time() + $temp > 86400 ) // 1 day: $temp is equal to -1 * time( then )
468                                 unset($draft_ids[$temp]);
469
470                 if ( isset($draft_ids[$temp_id]) ) { // Edit, don't write
471                         $_POST['post_ID'] = $draft_ids[$temp_id];
472                         unset($_POST['temp_ID']);
473                         update_user_option( $user_ID, 'autosave_draft_ids', $draft_ids );
474                         return edit_post();
475                 }
476         }
477
478         $translated = _wp_translate_postdata( false );
479         if ( is_wp_error($translated) )
480                 return $translated;
481
482         if ( isset($_POST['visibility']) ) {
483                 switch ( $_POST['visibility'] ) {
484                         case 'public' :
485                                 $_POST['post_password'] = '';
486                                 break;
487                         case 'password' :
488                                 unset( $_POST['sticky'] );
489                                 break;
490                         case 'private' :
491                                 $_POST['post_status'] = 'private';
492                                 $_POST['post_password'] = '';
493                                 unset( $_POST['sticky'] );
494                                 break;
495                 }
496         }
497
498         // Create the post.
499         $post_ID = wp_insert_post( $_POST );
500         if ( is_wp_error( $post_ID ) )
501                 return $post_ID;
502
503         if ( empty($post_ID) )
504                 return 0;
505
506         add_meta( $post_ID );
507
508         // Reunite any orphaned attachments with their parent
509         if ( !$draft_ids = get_user_option( 'autosave_draft_ids' ) )
510                 $draft_ids = array();
511         if ( $draft_temp_id = (int) array_search( $post_ID, $draft_ids ) )
512                 _relocate_children( $draft_temp_id, $post_ID );
513         if ( $temp_id && $temp_id != $draft_temp_id )
514                 _relocate_children( $temp_id, $post_ID );
515
516         // Update autosave collision detection
517         if ( $temp_id ) {
518                 $draft_ids[$temp_id] = $post_ID;
519                 update_user_option( $user_ID, 'autosave_draft_ids', $draft_ids );
520         }
521
522         // Now that we have an ID we can fix any attachment anchor hrefs
523         _fix_attachment_links( $post_ID );
524
525         wp_set_post_lock( $post_ID, $GLOBALS['current_user']->ID );
526
527         return $post_ID;
528 }
529
530 /**
531  * Calls wp_write_post() and handles the errors.
532  *
533  * @since unknown
534  *
535  * @return unknown
536  */
537 function write_post() {
538         $result = wp_write_post();
539         if( is_wp_error( $result ) )
540                 wp_die( $result->get_error_message() );
541         else
542                 return $result;
543 }
544
545 //
546 // Post Meta
547 //
548
549 /**
550  * {@internal Missing Short Description}}
551  *
552  * @since unknown
553  *
554  * @param unknown_type $post_ID
555  * @return unknown
556  */
557 function add_meta( $post_ID ) {
558         global $wpdb;
559         $post_ID = (int) $post_ID;
560
561         $protected = array( '_wp_attached_file', '_wp_attachment_metadata', '_wp_old_slug', '_wp_page_template' );
562
563         $metakeyselect = isset($_POST['metakeyselect']) ? stripslashes( trim( $_POST['metakeyselect'] ) ) : '';
564         $metakeyinput = isset($_POST['metakeyinput']) ? stripslashes( trim( $_POST['metakeyinput'] ) ) : '';
565         $metavalue = isset($_POST['metavalue']) ? maybe_serialize( stripslashes( trim( $_POST['metavalue'] ) ) ) : '';
566
567         if ( ('0' === $metavalue || !empty ( $metavalue ) ) && ((('#NONE#' != $metakeyselect) && !empty ( $metakeyselect) ) || !empty ( $metakeyinput) ) ) {
568                 // We have a key/value pair. If both the select and the
569                 // input for the key have data, the input takes precedence:
570
571                 if ('#NONE#' != $metakeyselect)
572                         $metakey = $metakeyselect;
573
574                 if ( $metakeyinput)
575                         $metakey = $metakeyinput; // default
576
577                 if ( in_array($metakey, $protected) )
578                         return false;
579
580                 wp_cache_delete($post_ID, 'post_meta');
581
582                 $wpdb->query( $wpdb->prepare("INSERT INTO $wpdb->postmeta (post_id,meta_key,meta_value ) VALUES (%s, %s, %s)", $post_ID, $metakey, $metavalue) );
583                 return $wpdb->insert_id;
584         }
585         return false;
586 } // add_meta
587
588 /**
589  * {@internal Missing Short Description}}
590  *
591  * @since unknown
592  *
593  * @param unknown_type $mid
594  * @return unknown
595  */
596 function delete_meta( $mid ) {
597         global $wpdb;
598         $mid = (int) $mid;
599
600         $post_id = $wpdb->get_var( $wpdb->prepare("SELECT post_id FROM $wpdb->postmeta WHERE meta_id = %d", $mid) );
601         wp_cache_delete($post_id, 'post_meta');
602
603         return $wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->postmeta WHERE meta_id = %d", $mid) );
604 }
605
606 /**
607  * Get a list of previously defined keys.
608  *
609  * @since unknown
610  *
611  * @return unknown
612  */
613 function get_meta_keys() {
614         global $wpdb;
615
616         $keys = $wpdb->get_col( "
617                         SELECT meta_key
618                         FROM $wpdb->postmeta
619                         GROUP BY meta_key
620                         ORDER BY meta_key" );
621
622         return $keys;
623 }
624
625 /**
626  * {@internal Missing Short Description}}
627  *
628  * @since unknown
629  *
630  * @param unknown_type $mid
631  * @return unknown
632  */
633 function get_post_meta_by_id( $mid ) {
634         global $wpdb;
635         $mid = (int) $mid;
636
637         $meta = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->postmeta WHERE meta_id = %d", $mid) );
638         if ( is_serialized_string( $meta->meta_value ) )
639                 $meta->meta_value = maybe_unserialize( $meta->meta_value );
640         return $meta;
641 }
642
643 /**
644  * {@internal Missing Short Description}}
645  *
646  * Some postmeta stuff.
647  *
648  * @since unknown
649  *
650  * @param unknown_type $postid
651  * @return unknown
652  */
653 function has_meta( $postid ) {
654         global $wpdb;
655
656         return $wpdb->get_results( $wpdb->prepare("SELECT meta_key, meta_value, meta_id, post_id
657                         FROM $wpdb->postmeta WHERE post_id = %d
658                         ORDER BY meta_key,meta_id", $postid), ARRAY_A );
659
660 }
661
662 /**
663  * {@internal Missing Short Description}}
664  *
665  * @since unknown
666  *
667  * @param unknown_type $meta_id
668  * @param unknown_type $meta_key
669  * @param unknown_type $meta_value
670  * @return unknown
671  */
672 function update_meta( $meta_id, $meta_key, $meta_value ) {
673         global $wpdb;
674
675         $protected = array( '_wp_attached_file', '_wp_attachment_metadata', '_wp_old_slug', '_wp_page_template' );
676
677         if ( in_array($meta_key, $protected) )
678                 return false;
679
680         if ( '' === trim( $meta_value ) )
681                 return false;
682
683         $post_id = $wpdb->get_var( $wpdb->prepare("SELECT post_id FROM $wpdb->postmeta WHERE meta_id = %d", $meta_id) );
684         wp_cache_delete($post_id, 'post_meta');
685
686         $meta_value = maybe_serialize( stripslashes( $meta_value ) );
687         $meta_id = (int) $meta_id;
688
689         $data  = compact( 'meta_key', 'meta_value' );
690         $where = compact( 'meta_id' );
691
692         return $wpdb->update( $wpdb->postmeta, $data, $where );
693 }
694
695 //
696 // Private
697 //
698
699 /**
700  * Replace hrefs of attachment anchors with up-to-date permalinks.
701  *
702  * @since unknown
703  * @access private
704  *
705  * @param unknown_type $post_ID
706  * @return unknown
707  */
708 function _fix_attachment_links( $post_ID ) {
709
710         $post = & get_post( $post_ID, ARRAY_A );
711
712         $search = "#<a[^>]+rel=('|\")[^'\"]*attachment[^>]*>#ie";
713
714         // See if we have any rel="attachment" links
715         if ( 0 == preg_match_all( $search, $post['post_content'], $anchor_matches, PREG_PATTERN_ORDER ) )
716                 return;
717
718         $i = 0;
719         $search = "#[\s]+rel=(\"|')(.*?)wp-att-(\d+)\\1#i";
720         foreach ( $anchor_matches[0] as $anchor ) {
721                 if ( 0 == preg_match( $search, $anchor, $id_matches ) )
722                         continue;
723
724                 $id = (int) $id_matches[3];
725
726                 // While we have the attachment ID, let's adopt any orphans.
727                 $attachment = & get_post( $id, ARRAY_A );
728                 if ( ! empty( $attachment) && ! is_object( get_post( $attachment['post_parent'] ) ) ) {
729                         $attachment['post_parent'] = $post_ID;
730                         // Escape data pulled from DB.
731                         $attachment = add_magic_quotes( $attachment);
732                         wp_update_post( $attachment);
733                 }
734
735                 $post_search[$i] = $anchor;
736                 $post_replace[$i] = preg_replace( "#href=(\"|')[^'\"]*\\1#e", "stripslashes( 'href=\\1' ).get_attachment_link( $id ).stripslashes( '\\1' )", $anchor );
737                 ++$i;
738         }
739
740         $post['post_content'] = str_replace( $post_search, $post_replace, $post['post_content'] );
741
742         // Escape data pulled from DB.
743         $post = add_magic_quotes( $post);
744
745         return wp_update_post( $post);
746 }
747
748 /**
749  * Move child posts to a new parent.
750  *
751  * @since unknown
752  * @access private
753  *
754  * @param unknown_type $old_ID
755  * @param unknown_type $new_ID
756  * @return unknown
757  */
758 function _relocate_children( $old_ID, $new_ID ) {
759         global $wpdb;
760         $old_ID = (int) $old_ID;
761         $new_ID = (int) $new_ID;
762         return $wpdb->update($wpdb->posts, array('post_parent' => $new_ID), array('post_parent' => $old_ID) );
763 }
764
765 /**
766  * {@internal Missing Short Description}}
767  *
768  * @since unknown
769  *
770  * @param unknown_type $type
771  * @return unknown
772  */
773 function get_available_post_statuses($type = 'post') {
774         $stati = wp_count_posts($type);
775
776         return array_keys(get_object_vars($stati));
777 }
778
779 /**
780  * {@internal Missing Short Description}}
781  *
782  * @since unknown
783  *
784  * @param unknown_type $q
785  * @return unknown
786  */
787 function wp_edit_posts_query( $q = false ) {
788         if ( false === $q )
789                 $q = $_GET;
790         $q['m']   = isset($q['m']) ? (int) $q['m'] : 0;
791         $q['cat'] = isset($q['cat']) ? (int) $q['cat'] : 0;
792         $post_stati  = array(   //      array( adj, noun )
793                                 'publish' => array(_x('Published', 'post'), __('Published posts'), _n_noop('Published <span class="count">(%s)</span>', 'Published <span class="count">(%s)</span>')),
794                                 'future' => array(_x('Scheduled', 'post'), __('Scheduled posts'), _n_noop('Scheduled <span class="count">(%s)</span>', 'Scheduled <span class="count">(%s)</span>')),
795                                 'pending' => array(_x('Pending Review', 'post'), __('Pending posts'), _n_noop('Pending Review <span class="count">(%s)</span>', 'Pending Review <span class="count">(%s)</span>')),
796                                 'draft' => array(_x('Draft', 'post'), _x('Drafts', 'manage posts header'), _n_noop('Draft <span class="count">(%s)</span>', 'Drafts <span class="count">(%s)</span>')),
797                                 'private' => array(_x('Private', 'post'), __('Private posts'), _n_noop('Private <span class="count">(%s)</span>', 'Private <span class="count">(%s)</span>')),
798                         );
799
800         $post_stati = apply_filters('post_stati', $post_stati);
801
802         $avail_post_stati = get_available_post_statuses('post');
803
804         $post_status_q = '';
805         if ( isset($q['post_status']) && in_array( $q['post_status'], array_keys($post_stati) ) ) {
806                 $post_status_q = '&post_status=' . $q['post_status'];
807                 $post_status_q .= '&perm=readable';
808         }
809
810         if ( isset($q['post_status']) && 'pending' === $q['post_status'] ) {
811                 $order = 'ASC';
812                 $orderby = 'modified';
813         } elseif ( isset($q['post_status']) && 'draft' === $q['post_status'] ) {
814                 $order = 'DESC';
815                 $orderby = 'modified';
816         } else {
817                 $order = 'DESC';
818                 $orderby = 'date';
819         }
820
821         $posts_per_page = get_user_option('edit_per_page');
822         if ( empty($posts_per_page) )
823                 $posts_per_page = 15;
824         $posts_per_page = apply_filters('edit_posts_per_page', $posts_per_page);
825
826         wp("post_type=post&$post_status_q&posts_per_page=$posts_per_page&order=$order&orderby=$orderby");
827
828         return array($post_stati, $avail_post_stati);
829 }
830
831 /**
832  * {@internal Missing Short Description}}
833  *
834  * @since unknown
835  *
836  * @param unknown_type $type
837  * @return unknown
838  */
839 function get_available_post_mime_types($type = 'attachment') {
840         global $wpdb;
841
842         $types = $wpdb->get_col($wpdb->prepare("SELECT DISTINCT post_mime_type FROM $wpdb->posts WHERE post_type = %s", $type));
843         return $types;
844 }
845
846 /**
847  * {@internal Missing Short Description}}
848  *
849  * @since unknown
850  *
851  * @param unknown_type $q
852  * @return unknown
853  */
854 function wp_edit_attachments_query( $q = false ) {
855         if ( false === $q )
856                 $q = $_GET;
857
858         $q['m']   = isset( $q['m'] ) ? (int) $q['m'] : 0;
859         $q['cat'] = isset( $q['cat'] ) ? (int) $q['cat'] : 0;
860         $q['post_type'] = 'attachment';
861         $q['post_status'] = 'any';
862         $media_per_page = get_user_option('upload_per_page');
863         if ( empty($media_per_page) )
864                 $media_per_page = 20;
865         $q['posts_per_page'] = $media_per_page;
866         $post_mime_types = array(       //      array( adj, noun )
867                                 'image' => array(__('Images'), __('Manage Images'), _n_noop('Image <span class="count">(%s)</span>', 'Images <span class="count">(%s)</span>')),
868                                 'audio' => array(__('Audio'), __('Manage Audio'), _n_noop('Audio <span class="count">(%s)</span>', 'Audio <span class="count">(%s)</span>')),
869                                 'video' => array(__('Video'), __('Manage Video'), _n_noop('Video <span class="count">(%s)</span>', 'Video <span class="count">(%s)</span>')),
870                         );
871         $post_mime_types = apply_filters('post_mime_types', $post_mime_types);
872
873         $avail_post_mime_types = get_available_post_mime_types('attachment');
874
875         if ( isset($q['post_mime_type']) && !array_intersect( (array) $q['post_mime_type'], array_keys($post_mime_types) ) )
876                 unset($q['post_mime_type']);
877
878         wp($q);
879
880         return array($post_mime_types, $avail_post_mime_types);
881 }
882
883 /**
884  * {@internal Missing Short Description}}
885  *
886  * @since unknown
887  *
888  * @param unknown_type $id
889  * @param unknown_type $page
890  * @return unknown
891  */
892 function postbox_classes( $id, $page ) {
893         if ( isset( $_GET['edit'] ) && $_GET['edit'] == $id )
894                 return '';
895         $current_user = wp_get_current_user();
896         if ( $closed = get_user_option('closedpostboxes_'.$page, 0, false ) ) {
897                 if ( !is_array( $closed ) ) return '';
898                 return in_array( $id, $closed )? 'closed' : '';
899         } else {
900                 return '';
901         }
902 }
903
904 /**
905  * {@internal Missing Short Description}}
906  *
907  * @since unknown
908  *
909  * @param unknown_type $id
910  * @param unknown_type $title
911  * @param unknown_type $name
912  * @return unknown
913  */
914 function get_sample_permalink($id, $title=null, $name = null) {
915         $post = &get_post($id);
916         if (!$post->ID) {
917                 return array('', '');
918         }
919         $original_status = $post->post_status;
920         $original_date = $post->post_date;
921         $original_name = $post->post_name;
922
923         // Hack: get_permalink would return ugly permalink for
924         // drafts, so we will fake, that our post is published
925         if (in_array($post->post_status, array('draft', 'pending'))) {
926                 $post->post_status = 'publish';
927                 $post->post_name = sanitize_title($post->post_name? $post->post_name : $post->post_title, $post->ID);
928         }
929
930         $post->post_name = wp_unique_post_slug($post->post_name, $post->ID, $post->post_status, $post->post_type, $post->post_parent);
931
932         // If the user wants to set a new name -- override the current one
933         // Note: if empty name is supplied -- use the title instead, see #6072
934         if (!is_null($name)) {
935                 $post->post_name = sanitize_title($name? $name : $title, $post->ID);
936         }
937
938         $post->filter = 'sample';
939
940         $permalink = get_permalink($post, true);
941
942         // Handle page hierarchy
943         if ( 'page' == $post->post_type ) {
944                 $uri = get_page_uri($post->ID);
945                 $uri = untrailingslashit($uri);
946                 $uri = strrev( stristr( strrev( $uri ), '/' ) );
947                 $uri = untrailingslashit($uri);
948                 if ( !empty($uri) )
949                         $uri .='/';
950                 $permalink = str_replace('%pagename%', "${uri}%pagename%", $permalink);
951         }
952
953         $permalink = array($permalink, apply_filters('editable_slug', $post->post_name));
954         $post->post_status = $original_status;
955         $post->post_date = $original_date;
956         $post->post_name = $original_name;
957         unset($post->filter);
958
959         return $permalink;
960 }
961
962 /**
963  * {@internal Missing Short Description}}
964  *
965  * @since unknown
966  *
967  * @param unknown_type $id
968  * @param unknown_type $new_title
969  * @param unknown_type $new_slug
970  * @return unknown
971  */
972 function get_sample_permalink_html( $id, $new_title = null, $new_slug = null ) {
973         $post = &get_post($id);
974         list($permalink, $post_name) = get_sample_permalink($post->ID, $new_title, $new_slug);
975         if ( 'publish' == $post->post_status )
976                 $view_post = 'post' == $post->post_type ? __('View Post') : __('View Page');
977
978         if ( false === strpos($permalink, '%postname%') && false === strpos($permalink, '%pagename%') ) {
979                 $return = '<strong>' . __('Permalink:') . "</strong>\n" . '<span id="sample-permalink">' . $permalink . "</span>\n";
980                 if ( current_user_can( 'manage_options' ) )
981                         $return .= '<span id="change-permalinks"><a href="options-permalink.php" class="button" target="_blank">' . __('Change Permalinks') . "</a></span>\n";
982                 if ( isset($view_post) )
983                         $return .= "<span id='view-post-btn'><a href='$permalink' class='button' target='_blank'>$view_post</a></span>\n";
984
985                 return $return;
986         }
987
988         $title = __('Click to edit this part of the permalink');
989         if (function_exists('mb_strlen')) {
990                 if (mb_strlen($post_name) > 30) {
991                         $post_name_abridged = mb_substr($post_name, 0, 14). '&hellip;' . mb_substr($post_name, -14);
992                 } else {
993                         $post_name_abridged = $post_name;
994                 }
995         } else {
996                 if (strlen($post_name) > 30) {
997                         $post_name_abridged = substr($post_name, 0, 14). '&hellip;' . substr($post_name, -14);
998                 } else {
999                         $post_name_abridged = $post_name;
1000                 }
1001         }
1002
1003         $post_name_html = '<span id="editable-post-name" title="' . $title . '">' . $post_name_abridged . '</span>';
1004         $display_link = str_replace(array('%pagename%','%postname%'), $post_name_html, $permalink);
1005         $view_link = str_replace(array('%pagename%','%postname%'), $post_name, $permalink);
1006         $return = '<strong>' . __('Permalink:') . "</strong>\n" . '<span id="sample-permalink">' . $display_link . "</span>\n";
1007         $return .= '<span id="edit-slug-buttons"><a href="#post_name" class="edit-slug button hide-if-no-js" onclick="edit_permalink(' . $id . '); return false;">' . __('Edit') . "</a></span>\n";
1008         $return .= '<span id="editable-post-name-full">' . $post_name . "</span>\n";
1009         if ( isset($view_post) )
1010                 $return .= "<span id='view-post-btn'><a href='$view_link' class='button' target='_blank'>$view_post</a></span>\n";
1011
1012         return $return;
1013 }
1014
1015 /**
1016  * {@internal Missing Short Description}}
1017  *
1018  * @since unknown
1019  *
1020  * @param unknown_type $post_id
1021  * @return bool|int False: not locked or locked by current user. Int: user ID of user with lock.
1022  */
1023 function wp_check_post_lock( $post_id ) {
1024         global $current_user;
1025
1026         if ( !$post = get_post( $post_id ) )
1027                 return false;
1028
1029         $lock = get_post_meta( $post->ID, '_edit_lock', true );
1030         $last = get_post_meta( $post->ID, '_edit_last', true );
1031
1032         $time_window = apply_filters( 'wp_check_post_lock_window', AUTOSAVE_INTERVAL * 2 );
1033
1034         if ( $lock && $lock > time() - $time_window && $last != $current_user->ID )
1035                 return $last;
1036         return false;
1037 }
1038
1039 /**
1040  * {@internal Missing Short Description}}
1041  *
1042  * @since unknown
1043  *
1044  * @param unknown_type $post_id
1045  * @return unknown
1046  */
1047 function wp_set_post_lock( $post_id ) {
1048         global $current_user;
1049         if ( !$post = get_post( $post_id ) )
1050                 return false;
1051         if ( !$current_user || !$current_user->ID )
1052                 return false;
1053
1054         $now = time();
1055
1056         if ( !add_post_meta( $post->ID, '_edit_lock', $now, true ) )
1057                 update_post_meta( $post->ID, '_edit_lock', $now );
1058         if ( !add_post_meta( $post->ID, '_edit_last', $current_user->ID, true ) )
1059                 update_post_meta( $post->ID, '_edit_last', $current_user->ID );
1060 }
1061
1062 /**
1063  * Outputs the notice message to say that someone else is editing this post at the moment.
1064  * 
1065  * @since 2.8.5
1066  * @return none
1067  */
1068 function _admin_notice_post_locked() {
1069         global $post;
1070         $last_user = get_userdata( get_post_meta( $post->ID, '_edit_last', true ) );
1071         $last_user_name = $last_user ? $last_user->display_name : __('Somebody');
1072         
1073         switch ($post->post_type) {
1074                 case 'post':
1075                         $message = __( 'Warning: %s is currently editing this post' );
1076                         break;
1077                 case 'page':
1078                         $message = __( 'Warning: %s is currently editing this page' );
1079                         break;
1080                 default:
1081                         $message = __( 'Warning: %s is currently editing this.' );
1082         }
1083         
1084         $message = sprintf( $message, esc_html( $last_user_name ) );
1085         echo "<div class='error'><p>$message</p></div>";        
1086 }
1087
1088 /**
1089  * Creates autosave data for the specified post from $_POST data.
1090  *
1091  * @package WordPress
1092  * @subpackage Post_Revisions
1093  * @since 2.6.0
1094  *
1095  * @uses _wp_translate_postdata()
1096  * @uses _wp_post_revision_fields()
1097  */
1098 function wp_create_post_autosave( $post_id ) {
1099         $translated = _wp_translate_postdata( true );
1100         if ( is_wp_error( $translated ) )
1101                 return $translated;
1102
1103         // Only store one autosave.  If there is already an autosave, overwrite it.
1104         if ( $old_autosave = wp_get_post_autosave( $post_id ) ) {
1105                 $new_autosave = _wp_post_revision_fields( $_POST, true );
1106                 $new_autosave['ID'] = $old_autosave->ID;
1107                 return wp_update_post( $new_autosave );
1108         }
1109
1110         // _wp_put_post_revision() expects unescaped.
1111         $_POST = stripslashes_deep($_POST);
1112
1113         // Otherwise create the new autosave as a special post revision
1114         return _wp_put_post_revision( $_POST, true );
1115 }
1116
1117 /**
1118  * Save draft or manually autosave for showing preview.
1119  *
1120  * @package WordPress
1121  * @since 2.7
1122  *
1123  * @uses wp_write_post()
1124  * @uses edit_post()
1125  * @uses get_post()
1126  * @uses current_user_can()
1127  * @uses wp_create_post_autosave()
1128  *
1129  * @return str URL to redirect to show the preview
1130  */
1131 function post_preview() {
1132
1133         $post_ID = (int) $_POST['post_ID'];
1134         if ( $post_ID < 1 )
1135                 wp_die( __('Preview not available. Please save as a draft first.') );
1136
1137         if ( isset($_POST['catslist']) )
1138                 $_POST['post_category'] = explode(",", $_POST['catslist']);
1139
1140         if ( isset($_POST['tags_input']) )
1141                 $_POST['tags_input'] = explode(",", $_POST['tags_input']);
1142
1143         if ( $_POST['post_type'] == 'page' || empty($_POST['post_category']) )
1144                 unset($_POST['post_category']);
1145
1146         $_POST['ID'] = $post_ID;
1147         $post = get_post($post_ID);
1148
1149         if ( 'page' == $post->post_type ) {
1150                 if ( !current_user_can('edit_page', $post_ID) )
1151                         wp_die(__('You are not allowed to edit this page.'));
1152         } else {
1153                 if ( !current_user_can('edit_post', $post_ID) )
1154                         wp_die(__('You are not allowed to edit this post.'));
1155         }
1156
1157         if ( 'draft' == $post->post_status ) {
1158                 $id = edit_post();
1159         } else { // Non drafts are not overwritten.  The autosave is stored in a special post revision.
1160                 $id = wp_create_post_autosave( $post->ID );
1161                 if ( ! is_wp_error($id) )
1162                         $id = $post->ID;
1163         }
1164
1165         if ( is_wp_error($id) )
1166                 wp_die( $id->get_error_message() );
1167
1168         if ( $_POST['post_status'] == 'draft'  ) {
1169                 $url = add_query_arg( 'preview', 'true', get_permalink($id) );
1170         } else {
1171                 $nonce = wp_create_nonce('post_preview_' . $id);
1172                 $url = add_query_arg( array( 'preview' => 'true', 'preview_id' => $id, 'preview_nonce' => $nonce ), get_permalink($id) );
1173         }
1174
1175         return $url;
1176 }
1177
1178 /**
1179  * Adds the TinyMCE editor used on the Write and Edit screens.
1180  *
1181  * @package WordPress
1182  * @since 2.7
1183  *
1184  * TinyMCE is loaded separately from other Javascript by using wp-tinymce.php. It outputs concatenated
1185  * and optionaly pre-compressed version of the core and all default plugins. Additional plugins are loaded
1186  * directly by TinyMCE using non-blocking method. Custom plugins can be refreshed by adding a query string
1187  * to the URL when queueing them with the mce_external_plugins filter.
1188  *
1189  * @param bool $teeny optional Output a trimmed down version used in Press This.
1190  */
1191 function wp_tiny_mce( $teeny = false ) {
1192         global $concatenate_scripts, $compress_scripts, $tinymce_version;
1193
1194         if ( ! user_can_richedit() )
1195                 return;
1196
1197         $baseurl = includes_url('js/tinymce');
1198
1199         $mce_locale = ( '' == get_locale() ) ? 'en' : strtolower( substr(get_locale(), 0, 2) ); // only ISO 639-1
1200
1201         /*
1202         The following filter allows localization scripts to change the languages displayed in the spellchecker's drop-down menu.
1203         By default it uses Google's spellchecker API, but can be configured to use PSpell/ASpell if installed on the server.
1204         The + sign marks the default language. More information:
1205         http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/spellchecker
1206         */
1207         $mce_spellchecker_languages = apply_filters('mce_spellchecker_languages', '+English=en,Danish=da,Dutch=nl,Finnish=fi,French=fr,German=de,Italian=it,Polish=pl,Portuguese=pt,Spanish=es,Swedish=sv');
1208
1209         if ( $teeny ) {
1210                 $plugins = apply_filters( 'teeny_mce_plugins', array('safari', 'inlinepopups', 'media', 'autosave', 'fullscreen') );
1211                 $ext_plugins = '';
1212         } else {
1213                 $plugins = array( 'safari', 'inlinepopups', 'spellchecker', 'paste', 'wordpress', 'media', 'fullscreen', 'wpeditimage', 'wpgallery', 'tabfocus' );
1214
1215                 /*
1216                 The following filter takes an associative array of external plugins for TinyMCE in the form 'plugin_name' => 'url'.
1217                 It adds the plugin's name to TinyMCE's plugins init and the call to PluginManager to load the plugin.
1218                 The url should be absolute and should include the js file name to be loaded. Example:
1219                 array( 'myplugin' => 'http://my-site.com/wp-content/plugins/myfolder/mce_plugin.js' )
1220                 If the plugin uses a button, it should be added with one of the "$mce_buttons" filters.
1221                 */
1222                 $mce_external_plugins = apply_filters('mce_external_plugins', array());
1223
1224                 $ext_plugins = '';
1225                 if ( ! empty($mce_external_plugins) ) {
1226
1227                         /*
1228                         The following filter loads external language files for TinyMCE plugins.
1229                         It takes an associative array 'plugin_name' => 'path', where path is the
1230                         include path to the file. The language file should follow the same format as
1231                         /tinymce/langs/wp-langs.php and should define a variable $strings that
1232                         holds all translated strings.
1233                         When this filter is not used, the function will try to load {mce_locale}.js.
1234                         If that is not found, en.js will be tried next.
1235                         */
1236                         $mce_external_languages = apply_filters('mce_external_languages', array());
1237
1238                         $loaded_langs = array();
1239                         $strings = '';
1240
1241                         if ( ! empty($mce_external_languages) ) {
1242                                 foreach ( $mce_external_languages as $name => $path ) {
1243                                         if ( @is_file($path) && @is_readable($path) ) {
1244                                                 include_once($path);
1245                                                 $ext_plugins .= $strings . "\n";
1246                                                 $loaded_langs[] = $name;
1247                                         }
1248                                 }
1249                         }
1250
1251                         foreach ( $mce_external_plugins as $name => $url ) {
1252
1253                                 if ( is_ssl() ) $url = str_replace('http://', 'https://', $url);
1254
1255                                 $plugins[] = '-' . $name;
1256
1257                                 $plugurl = dirname($url);
1258                                 $strings = $str1 = $str2 = '';
1259                                 if ( ! in_array($name, $loaded_langs) ) {
1260                                         $path = str_replace( WP_PLUGIN_URL, '', $plugurl );
1261                                         $path = WP_PLUGIN_DIR . $path . '/langs/';
1262
1263                                         if ( function_exists('realpath') )
1264                                                 $path = trailingslashit( realpath($path) );
1265
1266                                         if ( @is_file($path . $mce_locale . '.js') )
1267                                                 $strings .= @file_get_contents($path . $mce_locale . '.js') . "\n";
1268
1269                                         if ( @is_file($path . $mce_locale . '_dlg.js') )
1270                                                 $strings .= @file_get_contents($path . $mce_locale . '_dlg.js') . "\n";
1271
1272                                         if ( 'en' != $mce_locale && empty($strings) ) {
1273                                                 if ( @is_file($path . 'en.js') ) {
1274                                                         $str1 = @file_get_contents($path . 'en.js');
1275                                                         $strings .= preg_replace( '/([\'"])en\./', '$1' . $mce_locale . '.', $str1, 1 ) . "\n";
1276                                                 }
1277
1278                                                 if ( @is_file($path . 'en_dlg.js') ) {
1279                                                         $str2 = @file_get_contents($path . 'en_dlg.js');
1280                                                         $strings .= preg_replace( '/([\'"])en\./', '$1' . $mce_locale . '.', $str2, 1 ) . "\n";
1281                                                 }
1282                                         }
1283
1284                                         if ( ! empty($strings) )
1285                                                 $ext_plugins .= "\n" . $strings . "\n";
1286                                 }
1287
1288                                 $ext_plugins .= 'tinyMCEPreInit.load_ext("' . $plugurl . '", "' . $mce_locale . '");' . "\n";
1289                                 $ext_plugins .= 'tinymce.PluginManager.load("' . $name . '", "' . $url . '");' . "\n";
1290                         }
1291                 }
1292         }
1293
1294         $plugins = implode($plugins, ',');
1295
1296         if ( $teeny ) {
1297                 $mce_buttons = apply_filters( 'teeny_mce_buttons', array('bold, italic, underline, blockquote, separator, strikethrough, bullist, numlist,justifyleft, justifycenter, justifyright, undo, redo, link, unlink, fullscreen') );
1298                 $mce_buttons = implode($mce_buttons, ',');
1299                 $mce_buttons_2 = $mce_buttons_3 = $mce_buttons_4 = '';
1300         } else {
1301                 $mce_buttons = apply_filters('mce_buttons', array('bold', 'italic', 'strikethrough', '|', 'bullist', 'numlist', 'blockquote', '|', 'justifyleft', 'justifycenter', 'justifyright', '|', 'link', 'unlink', 'wp_more', '|', 'spellchecker', 'fullscreen', 'wp_adv' ));
1302                 $mce_buttons = implode($mce_buttons, ',');
1303
1304                 $mce_buttons_2 = apply_filters('mce_buttons_2', array('formatselect', 'underline', 'justifyfull', 'forecolor', '|', 'pastetext', 'pasteword', 'removeformat', '|', 'media', 'charmap', '|', 'outdent', 'indent', '|', 'undo', 'redo', 'wp_help' ));
1305                 $mce_buttons_2 = implode($mce_buttons_2, ',');
1306
1307                 $mce_buttons_3 = apply_filters('mce_buttons_3', array());
1308                 $mce_buttons_3 = implode($mce_buttons_3, ',');
1309
1310                 $mce_buttons_4 = apply_filters('mce_buttons_4', array());
1311                 $mce_buttons_4 = implode($mce_buttons_4, ',');
1312         }
1313         $no_captions = ( apply_filters( 'disable_captions', '' ) ) ? true : false;
1314
1315         // TinyMCE init settings
1316         $initArray = array (
1317                 'mode' => 'specific_textareas',
1318                 'editor_selector' => 'theEditor',
1319                 'width' => '100%',
1320                 'theme' => 'advanced',
1321                 'skin' => 'wp_theme',
1322                 'theme_advanced_buttons1' => "$mce_buttons",
1323                 'theme_advanced_buttons2' => "$mce_buttons_2",
1324                 'theme_advanced_buttons3' => "$mce_buttons_3",
1325                 'theme_advanced_buttons4' => "$mce_buttons_4",
1326                 'language' => "$mce_locale",
1327                 'spellchecker_languages' => "$mce_spellchecker_languages",
1328                 'theme_advanced_toolbar_location' => 'top',
1329                 'theme_advanced_toolbar_align' => 'left',
1330                 'theme_advanced_statusbar_location' => 'bottom',
1331                 'theme_advanced_resizing' => true,
1332                 'theme_advanced_resize_horizontal' => false,
1333                 'dialog_type' => 'modal',
1334                 'relative_urls' => false,
1335                 'remove_script_host' => false,
1336                 'convert_urls' => false,
1337                 'apply_source_formatting' => false,
1338                 'remove_linebreaks' => true,
1339                 'gecko_spellcheck' => true,
1340                 'entities' => '38,amp,60,lt,62,gt',
1341                 'accessibility_focus' => true,
1342                 'tabfocus_elements' => 'major-publishing-actions',
1343                 'media_strict' => false,
1344                 'save_callback' => 'switchEditors.saveCallback',
1345                 'wpeditimage_disable_captions' => $no_captions,
1346                 'plugins' => "$plugins"
1347         );
1348
1349         $mce_css = trim(apply_filters('mce_css', ''), ' ,');
1350
1351         if ( ! empty($mce_css) )
1352                 $initArray['content_css'] = "$mce_css";
1353
1354         // For people who really REALLY know what they're doing with TinyMCE
1355         // You can modify initArray to add, remove, change elements of the config before tinyMCE.init
1356         // Setting "valid_elements", "invalid_elements" and "extended_valid_elements" can be done through "tiny_mce_before_init".
1357         // Best is to use the default cleanup by not specifying valid_elements, as TinyMCE contains full set of XHTML 1.0.
1358         if ( $teeny ) {
1359                 $initArray = apply_filters('teeny_mce_before_init', $initArray);
1360         } else {
1361                 $initArray = apply_filters('tiny_mce_before_init', $initArray);
1362         }
1363
1364         if ( empty($initArray['theme_advanced_buttons3']) && !empty($initArray['theme_advanced_buttons4']) ) {
1365                 $initArray['theme_advanced_buttons3'] = $initArray['theme_advanced_buttons4'];
1366                 $initArray['theme_advanced_buttons4'] = '';
1367         }
1368
1369         if ( ! isset($concatenate_scripts) )
1370                 script_concat_settings();
1371
1372         $language = $initArray['language'];
1373         $zip = $compress_scripts ? 1 : 0;
1374
1375         /**
1376          * Deprecated
1377          *
1378          * The tiny_mce_version filter is not needed since external plugins are loaded directly by TinyMCE.
1379          * These plugins can be refreshed by appending query string to the URL passed to mce_external_plugins filter.
1380          * If the plugin has a popup dialog, a query string can be added to the button action that opens it (in the plugin's code).
1381          */
1382         $version = apply_filters('tiny_mce_version', '');
1383         $version = 'ver=' . $tinymce_version . $version;
1384
1385         if ( 'en' != $language )
1386                 include_once(ABSPATH . WPINC . '/js/tinymce/langs/wp-langs.php');
1387
1388         $mce_options = '';
1389         foreach ( $initArray as $k => $v )
1390             $mce_options .= $k . ':"' . $v . '", ';
1391
1392         $mce_options = rtrim( trim($mce_options), '\n\r,' ); ?>
1393
1394 <script type="text/javascript">
1395 /* <![CDATA[ */
1396 tinyMCEPreInit = {
1397         base : "<?php echo $baseurl; ?>",
1398         suffix : "",
1399         query : "<?php echo $version; ?>",
1400         mceInit : {<?php echo $mce_options; ?>},
1401         load_ext : function(url,lang){var sl=tinymce.ScriptLoader;sl.markDone(url+'/langs/'+lang+'.js');sl.markDone(url+'/langs/'+lang+'_dlg.js');}
1402 };
1403 /* ]]> */
1404 </script>
1405
1406 <?php
1407         if ( $concatenate_scripts )
1408                 echo "<script type='text/javascript' src='$baseurl/wp-tinymce.php?c=$zip&amp;$version'></script>\n";
1409         else
1410                 echo "<script type='text/javascript' src='$baseurl/tiny_mce.js?$version'></script>\n";
1411
1412         if ( 'en' != $language && isset($lang) )
1413                 echo "<script type='text/javascript'>\n$lang\n</script>\n";
1414         else
1415                 echo "<script type='text/javascript' src='$baseurl/langs/wp-langs-en.js?$version'></script>\n";
1416 ?>
1417
1418 <script type="text/javascript">
1419 /* <![CDATA[ */
1420 <?php if ( $ext_plugins ) echo "$ext_plugins\n"; ?>
1421 <?php if ( $concatenate_scripts ) { ?>
1422 tinyMCEPreInit.go();
1423 <?php } else { ?>
1424 (function(){var t=tinyMCEPreInit,sl=tinymce.ScriptLoader,ln=t.mceInit.language,th=t.mceInit.theme,pl=t.mceInit.plugins;sl.markDone(t.base+'/langs/'+ln+'.js');sl.markDone(t.base+'/themes/'+th+'/langs/'+ln+'.js');sl.markDone(t.base+'/themes/'+th+'/langs/'+ln+'_dlg.js');tinymce.each(pl.split(','),function(n){if(n&&n.charAt(0)!='-'){sl.markDone(t.base+'/plugins/'+n+'/langs/'+ln+'.js');sl.markDone(t.base+'/plugins/'+n+'/langs/'+ln+'_dlg.js');}});})();
1425 <?php } ?>
1426 tinyMCE.init(tinyMCEPreInit.mceInit);
1427 /* ]]> */
1428 </script>
1429 <?php
1430 }