wp/wp-includes/post.php
changeset 9 177826044cd9
parent 7 cf61fcea0001
child 16 a86126ab1dd4
equal deleted inserted replaced
8:c7c34916027a 9:177826044cd9
    16  * See {@see 'init'}.
    16  * See {@see 'init'}.
    17  *
    17  *
    18  * @since 2.9.0
    18  * @since 2.9.0
    19  */
    19  */
    20 function create_initial_post_types() {
    20 function create_initial_post_types() {
    21 	register_post_type( 'post', array(
    21 	register_post_type(
    22 		'labels' => array(
    22 		'post',
    23 			'name_admin_bar' => _x( 'Post', 'add new from admin bar' ),
    23 		array(
    24 		),
    24 			'labels'                => array(
    25 		'public'  => true,
    25 				'name_admin_bar' => _x( 'Post', 'add new from admin bar' ),
    26 		'_builtin' => true, /* internal use only. don't use this when registering your own post type. */
    26 			),
    27 		'_edit_link' => 'post.php?post=%d', /* internal use only. don't use this when registering your own post type. */
    27 			'public'                => true,
    28 		'capability_type' => 'post',
    28 			'_builtin'              => true, /* internal use only. don't use this when registering your own post type. */
    29 		'map_meta_cap' => true,
    29 			'_edit_link'            => 'post.php?post=%d', /* internal use only. don't use this when registering your own post type. */
    30 		'menu_position' => 5,
    30 			'capability_type'       => 'post',
    31 		'hierarchical' => false,
    31 			'map_meta_cap'          => true,
    32 		'rewrite' => false,
    32 			'menu_position'         => 5,
    33 		'query_var' => false,
    33 			'hierarchical'          => false,
    34 		'delete_with_user' => true,
    34 			'rewrite'               => false,
    35 		'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'trackbacks', 'custom-fields', 'comments', 'revisions', 'post-formats' ),
    35 			'query_var'             => false,
    36 		'show_in_rest' => true,
    36 			'delete_with_user'      => true,
    37 		'rest_base' => 'posts',
    37 			'supports'              => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'trackbacks', 'custom-fields', 'comments', 'revisions', 'post-formats' ),
    38 		'rest_controller_class' => 'WP_REST_Posts_Controller',
    38 			'show_in_rest'          => true,
    39 	) );
    39 			'rest_base'             => 'posts',
    40 
    40 			'rest_controller_class' => 'WP_REST_Posts_Controller',
    41 	register_post_type( 'page', array(
    41 		)
    42 		'labels' => array(
    42 	);
    43 			'name_admin_bar' => _x( 'Page', 'add new from admin bar' ),
    43 
    44 		),
    44 	register_post_type(
    45 		'public' => true,
    45 		'page',
    46 		'publicly_queryable' => false,
    46 		array(
    47 		'_builtin' => true, /* internal use only. don't use this when registering your own post type. */
    47 			'labels'                => array(
    48 		'_edit_link' => 'post.php?post=%d', /* internal use only. don't use this when registering your own post type. */
    48 				'name_admin_bar' => _x( 'Page', 'add new from admin bar' ),
    49 		'capability_type' => 'page',
    49 			),
    50 		'map_meta_cap' => true,
    50 			'public'                => true,
    51 		'menu_position' => 20,
    51 			'publicly_queryable'    => false,
    52 		'hierarchical' => true,
    52 			'_builtin'              => true, /* internal use only. don't use this when registering your own post type. */
    53 		'rewrite' => false,
    53 			'_edit_link'            => 'post.php?post=%d', /* internal use only. don't use this when registering your own post type. */
    54 		'query_var' => false,
    54 			'capability_type'       => 'page',
    55 		'delete_with_user' => true,
    55 			'map_meta_cap'          => true,
    56 		'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'page-attributes', 'custom-fields', 'comments', 'revisions' ),
    56 			'menu_position'         => 20,
    57 		'show_in_rest' => true,
    57 			'hierarchical'          => true,
    58 		'rest_base' => 'pages',
    58 			'rewrite'               => false,
    59 		'rest_controller_class' => 'WP_REST_Posts_Controller',
    59 			'query_var'             => false,
    60 	) );
    60 			'delete_with_user'      => true,
    61 
    61 			'supports'              => array( 'title', 'editor', 'author', 'thumbnail', 'page-attributes', 'custom-fields', 'comments', 'revisions' ),
    62 	register_post_type( 'attachment', array(
    62 			'show_in_rest'          => true,
    63 		'labels' => array(
    63 			'rest_base'             => 'pages',
    64 			'name' => _x('Media', 'post type general name'),
    64 			'rest_controller_class' => 'WP_REST_Posts_Controller',
    65 			'name_admin_bar' => _x( 'Media', 'add new from admin bar' ),
    65 		)
    66 			'add_new' => _x( 'Add New', 'add new media' ),
    66 	);
    67  			'edit_item' => __( 'Edit Media' ),
    67 
    68  			'view_item' => __( 'View Attachment Page' ),
    68 	register_post_type(
    69 			'attributes' => __( 'Attachment Attributes' ),
    69 		'attachment',
    70 		),
    70 		array(
    71 		'public' => true,
    71 			'labels'                => array(
    72 		'show_ui' => true,
    72 				'name'           => _x( 'Media', 'post type general name' ),
    73 		'_builtin' => true, /* internal use only. don't use this when registering your own post type. */
    73 				'name_admin_bar' => _x( 'Media', 'add new from admin bar' ),
    74 		'_edit_link' => 'post.php?post=%d', /* internal use only. don't use this when registering your own post type. */
    74 				'add_new'        => _x( 'Add New', 'add new media' ),
    75 		'capability_type' => 'post',
    75 				'edit_item'      => __( 'Edit Media' ),
    76 		'capabilities' => array(
    76 				'view_item'      => __( 'View Attachment Page' ),
    77 			'create_posts' => 'upload_files',
    77 				'attributes'     => __( 'Attachment Attributes' ),
    78 		),
    78 			),
    79 		'map_meta_cap' => true,
    79 			'public'                => true,
    80 		'hierarchical' => false,
    80 			'show_ui'               => true,
    81 		'rewrite' => false,
    81 			'_builtin'              => true, /* internal use only. don't use this when registering your own post type. */
    82 		'query_var' => false,
    82 			'_edit_link'            => 'post.php?post=%d', /* internal use only. don't use this when registering your own post type. */
    83 		'show_in_nav_menus' => false,
    83 			'capability_type'       => 'post',
    84 		'delete_with_user' => true,
    84 			'capabilities'          => array(
    85 		'supports' => array( 'title', 'author', 'comments' ),
    85 				'create_posts' => 'upload_files',
    86 		'show_in_rest' => true,
    86 			),
    87 		'rest_base' => 'media',
    87 			'map_meta_cap'          => true,
    88 		'rest_controller_class' => 'WP_REST_Attachments_Controller',
    88 			'hierarchical'          => false,
    89 	) );
    89 			'rewrite'               => false,
       
    90 			'query_var'             => false,
       
    91 			'show_in_nav_menus'     => false,
       
    92 			'delete_with_user'      => true,
       
    93 			'supports'              => array( 'title', 'author', 'comments' ),
       
    94 			'show_in_rest'          => true,
       
    95 			'rest_base'             => 'media',
       
    96 			'rest_controller_class' => 'WP_REST_Attachments_Controller',
       
    97 		)
       
    98 	);
    90 	add_post_type_support( 'attachment:audio', 'thumbnail' );
    99 	add_post_type_support( 'attachment:audio', 'thumbnail' );
    91 	add_post_type_support( 'attachment:video', 'thumbnail' );
   100 	add_post_type_support( 'attachment:video', 'thumbnail' );
    92 
   101 
    93 	register_post_type( 'revision', array(
   102 	register_post_type(
    94 		'labels' => array(
   103 		'revision',
    95 			'name' => __( 'Revisions' ),
   104 		array(
    96 			'singular_name' => __( 'Revision' ),
   105 			'labels'           => array(
    97 		),
   106 				'name'          => __( 'Revisions' ),
    98 		'public' => false,
   107 				'singular_name' => __( 'Revision' ),
    99 		'_builtin' => true, /* internal use only. don't use this when registering your own post type. */
   108 			),
   100 		'_edit_link' => 'revision.php?revision=%d', /* internal use only. don't use this when registering your own post type. */
   109 			'public'           => false,
   101 		'capability_type' => 'post',
   110 			'_builtin'         => true, /* internal use only. don't use this when registering your own post type. */
   102 		'map_meta_cap' => true,
   111 			'_edit_link'       => 'revision.php?revision=%d', /* internal use only. don't use this when registering your own post type. */
   103 		'hierarchical' => false,
   112 			'capability_type'  => 'post',
   104 		'rewrite' => false,
   113 			'map_meta_cap'     => true,
   105 		'query_var' => false,
   114 			'hierarchical'     => false,
   106 		'can_export' => false,
   115 			'rewrite'          => false,
   107 		'delete_with_user' => true,
   116 			'query_var'        => false,
   108 		'supports' => array( 'author' ),
   117 			'can_export'       => false,
   109 	) );
   118 			'delete_with_user' => true,
   110 
   119 			'supports'         => array( 'author' ),
   111 	register_post_type( 'nav_menu_item', array(
   120 		)
   112 		'labels' => array(
   121 	);
   113 			'name' => __( 'Navigation Menu Items' ),
   122 
   114 			'singular_name' => __( 'Navigation Menu Item' ),
   123 	register_post_type(
   115 		),
   124 		'nav_menu_item',
   116 		'public' => false,
   125 		array(
   117 		'_builtin' => true, /* internal use only. don't use this when registering your own post type. */
   126 			'labels'           => array(
   118 		'hierarchical' => false,
   127 				'name'          => __( 'Navigation Menu Items' ),
   119 		'rewrite' => false,
   128 				'singular_name' => __( 'Navigation Menu Item' ),
   120 		'delete_with_user' => false,
   129 			),
   121 		'query_var' => false,
   130 			'public'           => false,
   122 	) );
   131 			'_builtin'         => true, /* internal use only. don't use this when registering your own post type. */
   123 
   132 			'hierarchical'     => false,
   124 	register_post_type( 'custom_css', array(
   133 			'rewrite'          => false,
   125 		'labels' => array(
   134 			'delete_with_user' => false,
   126 			'name'          => __( 'Custom CSS' ),
   135 			'query_var'        => false,
   127 			'singular_name' => __( 'Custom CSS' ),
   136 		)
   128 		),
   137 	);
   129 		'public'           => false,
   138 
   130 		'hierarchical'     => false,
   139 	register_post_type(
   131 		'rewrite'          => false,
   140 		'custom_css',
   132 		'query_var'        => false,
   141 		array(
   133 		'delete_with_user' => false,
   142 			'labels'           => array(
   134 		'can_export'       => true,
   143 				'name'          => __( 'Custom CSS' ),
   135 		'_builtin'         => true, /* internal use only. don't use this when registering your own post type. */
   144 				'singular_name' => __( 'Custom CSS' ),
   136 		'supports'         => array( 'title', 'revisions' ),
   145 			),
   137 		'capabilities'     => array(
   146 			'public'           => false,
   138 			'delete_posts'           => 'edit_theme_options',
   147 			'hierarchical'     => false,
   139 			'delete_post'            => 'edit_theme_options',
   148 			'rewrite'          => false,
   140 			'delete_published_posts' => 'edit_theme_options',
   149 			'query_var'        => false,
   141 			'delete_private_posts'   => 'edit_theme_options',
   150 			'delete_with_user' => false,
   142 			'delete_others_posts'    => 'edit_theme_options',
   151 			'can_export'       => true,
   143 			'edit_post'              => 'edit_css',
   152 			'_builtin'         => true, /* internal use only. don't use this when registering your own post type. */
   144 			'edit_posts'             => 'edit_css',
   153 			'supports'         => array( 'title', 'revisions' ),
   145 			'edit_others_posts'      => 'edit_css',
   154 			'capabilities'     => array(
   146 			'edit_published_posts'   => 'edit_css',
   155 				'delete_posts'           => 'edit_theme_options',
   147 			'read_post'              => 'read',
   156 				'delete_post'            => 'edit_theme_options',
   148 			'read_private_posts'     => 'read',
   157 				'delete_published_posts' => 'edit_theme_options',
   149 			'publish_posts'          => 'edit_theme_options',
   158 				'delete_private_posts'   => 'edit_theme_options',
   150 		),
   159 				'delete_others_posts'    => 'edit_theme_options',
   151 	) );
   160 				'edit_post'              => 'edit_css',
   152 
   161 				'edit_posts'             => 'edit_css',
   153 	register_post_type( 'customize_changeset', array(
   162 				'edit_others_posts'      => 'edit_css',
   154 		'labels' => array(
   163 				'edit_published_posts'   => 'edit_css',
   155 			'name'               => _x( 'Changesets', 'post type general name' ),
   164 				'read_post'              => 'read',
   156 			'singular_name'      => _x( 'Changeset', 'post type singular name' ),
   165 				'read_private_posts'     => 'read',
   157 			'menu_name'          => _x( 'Changesets', 'admin menu' ),
   166 				'publish_posts'          => 'edit_theme_options',
   158 			'name_admin_bar'     => _x( 'Changeset', 'add new on admin bar' ),
   167 			),
   159 			'add_new'            => _x( 'Add New', 'Customize Changeset' ),
   168 		)
   160 			'add_new_item'       => __( 'Add New Changeset' ),
   169 	);
   161 			'new_item'           => __( 'New Changeset' ),
   170 
   162 			'edit_item'          => __( 'Edit Changeset' ),
   171 	register_post_type(
   163 			'view_item'          => __( 'View Changeset' ),
   172 		'customize_changeset',
   164 			'all_items'          => __( 'All Changesets' ),
   173 		array(
   165 			'search_items'       => __( 'Search Changesets' ),
   174 			'labels'           => array(
   166 			'not_found'          => __( 'No changesets found.' ),
   175 				'name'               => _x( 'Changesets', 'post type general name' ),
   167 			'not_found_in_trash' => __( 'No changesets found in Trash.' ),
   176 				'singular_name'      => _x( 'Changeset', 'post type singular name' ),
   168 		),
   177 				'menu_name'          => _x( 'Changesets', 'admin menu' ),
   169 		'public' => false,
   178 				'name_admin_bar'     => _x( 'Changeset', 'add new on admin bar' ),
   170 		'_builtin' => true, /* internal use only. don't use this when registering your own post type. */
   179 				'add_new'            => _x( 'Add New', 'Customize Changeset' ),
   171 		'map_meta_cap' => true,
   180 				'add_new_item'       => __( 'Add New Changeset' ),
   172 		'hierarchical' => false,
   181 				'new_item'           => __( 'New Changeset' ),
   173 		'rewrite' => false,
   182 				'edit_item'          => __( 'Edit Changeset' ),
   174 		'query_var' => false,
   183 				'view_item'          => __( 'View Changeset' ),
   175 		'can_export' => false,
   184 				'all_items'          => __( 'All Changesets' ),
   176 		'delete_with_user' => false,
   185 				'search_items'       => __( 'Search Changesets' ),
   177 		'supports' => array( 'title', 'author' ),
   186 				'not_found'          => __( 'No changesets found.' ),
   178 		'capability_type' => 'customize_changeset',
   187 				'not_found_in_trash' => __( 'No changesets found in Trash.' ),
   179 		'capabilities' => array(
   188 			),
   180 			'create_posts' => 'customize',
   189 			'public'           => false,
   181 			'delete_others_posts' => 'customize',
   190 			'_builtin'         => true, /* internal use only. don't use this when registering your own post type. */
   182 			'delete_post' => 'customize',
   191 			'map_meta_cap'     => true,
   183 			'delete_posts' => 'customize',
   192 			'hierarchical'     => false,
   184 			'delete_private_posts' => 'customize',
   193 			'rewrite'          => false,
   185 			'delete_published_posts' => 'customize',
   194 			'query_var'        => false,
   186 			'edit_others_posts' => 'customize',
   195 			'can_export'       => false,
   187 			'edit_post' => 'customize',
   196 			'delete_with_user' => false,
   188 			'edit_posts' => 'customize',
   197 			'supports'         => array( 'title', 'author' ),
   189 			'edit_private_posts' => 'customize',
   198 			'capability_type'  => 'customize_changeset',
   190 			'edit_published_posts' => 'do_not_allow',
   199 			'capabilities'     => array(
   191 			'publish_posts' => 'customize',
   200 				'create_posts'           => 'customize',
   192 			'read' => 'read',
   201 				'delete_others_posts'    => 'customize',
   193 			'read_post' => 'customize',
   202 				'delete_post'            => 'customize',
   194 			'read_private_posts' => 'customize',
   203 				'delete_posts'           => 'customize',
   195 		),
   204 				'delete_private_posts'   => 'customize',
   196 	) );
   205 				'delete_published_posts' => 'customize',
   197 
   206 				'edit_others_posts'      => 'customize',
   198 	register_post_type( 'oembed_cache', array(
   207 				'edit_post'              => 'customize',
   199 		'labels' => array(
   208 				'edit_posts'             => 'customize',
   200 			'name'          => __( 'oEmbed Responses' ),
   209 				'edit_private_posts'     => 'customize',
   201 			'singular_name' => __( 'oEmbed Response' ),
   210 				'edit_published_posts'   => 'do_not_allow',
   202 		),
   211 				'publish_posts'          => 'customize',
   203 		'public'           => false,
   212 				'read'                   => 'read',
   204 		'hierarchical'     => false,
   213 				'read_post'              => 'customize',
   205 		'rewrite'          => false,
   214 				'read_private_posts'     => 'customize',
   206 		'query_var'        => false,
   215 			),
   207 		'delete_with_user' => false,
   216 		)
   208 		'can_export'       => false,
   217 	);
   209 		'_builtin'         => true, /* internal use only. don't use this when registering your own post type. */
   218 
   210 		'supports'         => array(),
   219 	register_post_type(
   211 	) );
   220 		'oembed_cache',
   212 
   221 		array(
   213 	register_post_type( 'user_request', array(
   222 			'labels'           => array(
   214 		'labels'           => array(
   223 				'name'          => __( 'oEmbed Responses' ),
   215 			'name'          => __( 'User Requests' ),
   224 				'singular_name' => __( 'oEmbed Response' ),
   216 			'singular_name' => __( 'User Request' ),
   225 			),
   217 		),
   226 			'public'           => false,
   218 		'public'           => false,
   227 			'hierarchical'     => false,
   219 		'_builtin'         => true, /* internal use only. don't use this when registering your own post type. */
   228 			'rewrite'          => false,
   220 		'hierarchical'     => false,
   229 			'query_var'        => false,
   221 		'rewrite'          => false,
   230 			'delete_with_user' => false,
   222 		'query_var'        => false,
   231 			'can_export'       => false,
   223 		'can_export'       => false,
   232 			'_builtin'         => true, /* internal use only. don't use this when registering your own post type. */
   224 		'delete_with_user' => false,
   233 			'supports'         => array(),
   225 		'supports'         => array(),
   234 		)
   226 	) );
   235 	);
   227 
   236 
   228 	register_post_status( 'publish', array(
   237 	register_post_type(
   229 		'label'       => _x( 'Published', 'post status' ),
   238 		'user_request',
   230 		'public'      => true,
   239 		array(
   231 		'_builtin'    => true, /* internal use only. */
   240 			'labels'           => array(
   232 		'label_count' => _n_noop( 'Published <span class="count">(%s)</span>', 'Published <span class="count">(%s)</span>' ),
   241 				'name'          => __( 'User Requests' ),
   233 	) );
   242 				'singular_name' => __( 'User Request' ),
   234 
   243 			),
   235 	register_post_status( 'future', array(
   244 			'public'           => false,
   236 		'label'       => _x( 'Scheduled', 'post status' ),
   245 			'_builtin'         => true, /* internal use only. don't use this when registering your own post type. */
   237 		'protected'   => true,
   246 			'hierarchical'     => false,
   238 		'_builtin'    => true, /* internal use only. */
   247 			'rewrite'          => false,
   239 		'label_count' => _n_noop('Scheduled <span class="count">(%s)</span>', 'Scheduled <span class="count">(%s)</span>' ),
   248 			'query_var'        => false,
   240 	) );
   249 			'can_export'       => false,
   241 
   250 			'delete_with_user' => false,
   242 	register_post_status( 'draft', array(
   251 			'supports'         => array(),
   243 		'label'       => _x( 'Draft', 'post status' ),
   252 		)
   244 		'protected'   => true,
   253 	);
   245 		'_builtin'    => true, /* internal use only. */
   254 
   246 		'label_count' => _n_noop( 'Draft <span class="count">(%s)</span>', 'Drafts <span class="count">(%s)</span>' ),
   255 	register_post_type(
   247 	) );
   256 		'wp_block',
   248 
   257 		array(
   249 	register_post_status( 'pending', array(
   258 			'labels'                => array(
   250 		'label'       => _x( 'Pending', 'post status' ),
   259 				'name'                     => _x( 'Blocks', 'post type general name' ),
   251 		'protected'   => true,
   260 				'singular_name'            => _x( 'Block', 'post type singular name' ),
   252 		'_builtin'    => true, /* internal use only. */
   261 				'menu_name'                => _x( 'Blocks', 'admin menu' ),
   253 		'label_count' => _n_noop( 'Pending <span class="count">(%s)</span>', 'Pending <span class="count">(%s)</span>' ),
   262 				'name_admin_bar'           => _x( 'Block', 'add new on admin bar' ),
   254 	) );
   263 				'add_new'                  => _x( 'Add New', 'Block' ),
   255 
   264 				'add_new_item'             => __( 'Add New Block' ),
   256 	register_post_status( 'private', array(
   265 				'new_item'                 => __( 'New Block' ),
   257 		'label'       => _x( 'Private', 'post status' ),
   266 				'edit_item'                => __( 'Edit Block' ),
   258 		'private'     => true,
   267 				'view_item'                => __( 'View Block' ),
   259 		'_builtin'    => true, /* internal use only. */
   268 				'all_items'                => __( 'All Blocks' ),
   260 		'label_count' => _n_noop( 'Private <span class="count">(%s)</span>', 'Private <span class="count">(%s)</span>' ),
   269 				'search_items'             => __( 'Search Blocks' ),
   261 	) );
   270 				'not_found'                => __( 'No blocks found.' ),
   262 
   271 				'not_found_in_trash'       => __( 'No blocks found in Trash.' ),
   263 	register_post_status( 'trash', array(
   272 				'filter_items_list'        => __( 'Filter blocks list' ),
   264 		'label'       => _x( 'Trash', 'post status' ),
   273 				'items_list_navigation'    => __( 'Blocks list navigation' ),
   265 		'internal'    => true,
   274 				'items_list'               => __( 'Blocks list' ),
   266 		'_builtin'    => true, /* internal use only. */
   275 				'item_published'           => __( 'Block published.' ),
   267 		'label_count' => _n_noop( 'Trash <span class="count">(%s)</span>', 'Trash <span class="count">(%s)</span>' ),
   276 				'item_published_privately' => __( 'Block published privately.' ),
   268 		'show_in_admin_status_list' => true,
   277 				'item_reverted_to_draft'   => __( 'Block reverted to draft.' ),
   269 	) );
   278 				'item_scheduled'           => __( 'Block scheduled.' ),
   270 
   279 				'item_updated'             => __( 'Block updated.' ),
   271 	register_post_status( 'auto-draft', array(
   280 			),
   272 		'label'    => 'auto-draft',
   281 			'public'                => false,
   273 		'internal' => true,
   282 			'_builtin'              => true, /* internal use only. don't use this when registering your own post type. */
   274 		'_builtin' => true, /* internal use only. */
   283 			'show_ui'               => true,
   275 	) );
   284 			'show_in_menu'          => false,
   276 
   285 			'rewrite'               => false,
   277 	register_post_status( 'inherit', array(
   286 			'show_in_rest'          => true,
   278 		'label'    => 'inherit',
   287 			'rest_base'             => 'blocks',
   279 		'internal' => true,
   288 			'rest_controller_class' => 'WP_REST_Blocks_Controller',
   280 		'_builtin' => true, /* internal use only. */
   289 			'capability_type'       => 'block',
   281 		'exclude_from_search' => false,
   290 			'capabilities'          => array(
   282 	) );
   291 				// You need to be able to edit posts, in order to read blocks in their raw form.
   283 
   292 				'read'                   => 'edit_posts',
   284 	register_post_status( 'request-pending', array(
   293 				// You need to be able to publish posts, in order to create blocks.
   285 		'label'               => _x( 'Pending', 'request status' ),
   294 				'create_posts'           => 'publish_posts',
   286 		'internal'            => true,
   295 				'edit_posts'             => 'edit_posts',
   287 		'_builtin'            => true, /* internal use only. */
   296 				'edit_published_posts'   => 'edit_published_posts',
   288 		'exclude_from_search' => false,
   297 				'delete_published_posts' => 'delete_published_posts',
   289 	) );
   298 				'edit_others_posts'      => 'edit_others_posts',
   290 
   299 				'delete_others_posts'    => 'delete_others_posts',
   291 	register_post_status( 'request-confirmed', array(
   300 			),
   292 		'label'               => _x( 'Confirmed', 'request status' ),
   301 			'map_meta_cap'          => true,
   293 		'internal'            => true,
   302 			'supports'              => array(
   294 		'_builtin'            => true, /* internal use only. */
   303 				'title',
   295 		'exclude_from_search' => false,
   304 				'editor',
   296 	) );
   305 			),
   297 
   306 		)
   298 	register_post_status( 'request-failed', array(
   307 	);
   299 		'label'               => _x( 'Failed', 'request status' ),
   308 
   300 		'internal'            => true,
   309 	register_post_status(
   301 		'_builtin'            => true, /* internal use only. */
   310 		'publish',
   302 		'exclude_from_search' => false,
   311 		array(
   303 	) );
   312 			'label'       => _x( 'Published', 'post status' ),
   304 
   313 			'public'      => true,
   305 	register_post_status( 'request-completed', array(
   314 			'_builtin'    => true, /* internal use only. */
   306 		'label'               => _x( 'Completed', 'request status' ),
   315 			'label_count' => _n_noop( 'Published <span class="count">(%s)</span>', 'Published <span class="count">(%s)</span>' ),
   307 		'internal'            => true,
   316 		)
   308 		'_builtin'            => true, /* internal use only. */
   317 	);
   309 		'exclude_from_search' => false,
   318 
   310 	) );
   319 	register_post_status(
       
   320 		'future',
       
   321 		array(
       
   322 			'label'       => _x( 'Scheduled', 'post status' ),
       
   323 			'protected'   => true,
       
   324 			'_builtin'    => true, /* internal use only. */
       
   325 			'label_count' => _n_noop( 'Scheduled <span class="count">(%s)</span>', 'Scheduled <span class="count">(%s)</span>' ),
       
   326 		)
       
   327 	);
       
   328 
       
   329 	register_post_status(
       
   330 		'draft',
       
   331 		array(
       
   332 			'label'       => _x( 'Draft', 'post status' ),
       
   333 			'protected'   => true,
       
   334 			'_builtin'    => true, /* internal use only. */
       
   335 			'label_count' => _n_noop( 'Draft <span class="count">(%s)</span>', 'Drafts <span class="count">(%s)</span>' ),
       
   336 		)
       
   337 	);
       
   338 
       
   339 	register_post_status(
       
   340 		'pending',
       
   341 		array(
       
   342 			'label'       => _x( 'Pending', 'post status' ),
       
   343 			'protected'   => true,
       
   344 			'_builtin'    => true, /* internal use only. */
       
   345 			'label_count' => _n_noop( 'Pending <span class="count">(%s)</span>', 'Pending <span class="count">(%s)</span>' ),
       
   346 		)
       
   347 	);
       
   348 
       
   349 	register_post_status(
       
   350 		'private',
       
   351 		array(
       
   352 			'label'       => _x( 'Private', 'post status' ),
       
   353 			'private'     => true,
       
   354 			'_builtin'    => true, /* internal use only. */
       
   355 			'label_count' => _n_noop( 'Private <span class="count">(%s)</span>', 'Private <span class="count">(%s)</span>' ),
       
   356 		)
       
   357 	);
       
   358 
       
   359 	register_post_status(
       
   360 		'trash',
       
   361 		array(
       
   362 			'label'                     => _x( 'Trash', 'post status' ),
       
   363 			'internal'                  => true,
       
   364 			'_builtin'                  => true, /* internal use only. */
       
   365 			'label_count'               => _n_noop( 'Trash <span class="count">(%s)</span>', 'Trash <span class="count">(%s)</span>' ),
       
   366 			'show_in_admin_status_list' => true,
       
   367 		)
       
   368 	);
       
   369 
       
   370 	register_post_status(
       
   371 		'auto-draft',
       
   372 		array(
       
   373 			'label'    => 'auto-draft',
       
   374 			'internal' => true,
       
   375 			'_builtin' => true, /* internal use only. */
       
   376 		)
       
   377 	);
       
   378 
       
   379 	register_post_status(
       
   380 		'inherit',
       
   381 		array(
       
   382 			'label'               => 'inherit',
       
   383 			'internal'            => true,
       
   384 			'_builtin'            => true, /* internal use only. */
       
   385 			'exclude_from_search' => false,
       
   386 		)
       
   387 	);
       
   388 
       
   389 	register_post_status(
       
   390 		'request-pending',
       
   391 		array(
       
   392 			'label'               => _x( 'Pending', 'request status' ),
       
   393 			'internal'            => true,
       
   394 			'_builtin'            => true, /* internal use only. */
       
   395 			'label_count'         => _n_noop( 'Pending <span class="count">(%s)</span>', 'Pending <span class="count">(%s)</span>' ),
       
   396 			'exclude_from_search' => false,
       
   397 		)
       
   398 	);
       
   399 
       
   400 	register_post_status(
       
   401 		'request-confirmed',
       
   402 		array(
       
   403 			'label'               => _x( 'Confirmed', 'request status' ),
       
   404 			'internal'            => true,
       
   405 			'_builtin'            => true, /* internal use only. */
       
   406 			'label_count'         => _n_noop( 'Confirmed <span class="count">(%s)</span>', 'Confirmed <span class="count">(%s)</span>' ),
       
   407 			'exclude_from_search' => false,
       
   408 		)
       
   409 	);
       
   410 
       
   411 	register_post_status(
       
   412 		'request-failed',
       
   413 		array(
       
   414 			'label'               => _x( 'Failed', 'request status' ),
       
   415 			'internal'            => true,
       
   416 			'_builtin'            => true, /* internal use only. */
       
   417 			'label_count'         => _n_noop( 'Failed <span class="count">(%s)</span>', 'Failed <span class="count">(%s)</span>' ),
       
   418 			'exclude_from_search' => false,
       
   419 		)
       
   420 	);
       
   421 
       
   422 	register_post_status(
       
   423 		'request-completed',
       
   424 		array(
       
   425 			'label'               => _x( 'Completed', 'request status' ),
       
   426 			'internal'            => true,
       
   427 			'_builtin'            => true, /* internal use only. */
       
   428 			'label_count'         => _n_noop( 'Completed <span class="count">(%s)</span>', 'Completed <span class="count">(%s)</span>' ),
       
   429 			'exclude_from_search' => false,
       
   430 		)
       
   431 	);
   311 }
   432 }
   312 
   433 
   313 /**
   434 /**
   314  * Retrieve attached file path based on attachment ID.
   435  * Retrieve attached file path based on attachment ID.
   315  *
   436  *
   362  * @param int    $attachment_id Attachment ID.
   483  * @param int    $attachment_id Attachment ID.
   363  * @param string $file          File path for the attachment.
   484  * @param string $file          File path for the attachment.
   364  * @return bool True on success, false on failure.
   485  * @return bool True on success, false on failure.
   365  */
   486  */
   366 function update_attached_file( $attachment_id, $file ) {
   487 function update_attached_file( $attachment_id, $file ) {
   367 	if ( !get_post( $attachment_id ) )
   488 	if ( ! get_post( $attachment_id ) ) {
   368 		return false;
   489 		return false;
       
   490 	}
   369 
   491 
   370 	/**
   492 	/**
   371 	 * Filters the path to the attached file to update.
   493 	 * Filters the path to the attached file to update.
   372 	 *
   494 	 *
   373 	 * @since 2.1.0
   495 	 * @since 2.1.0
   375 	 * @param string $file          Path to the attached file to update.
   497 	 * @param string $file          Path to the attached file to update.
   376 	 * @param int    $attachment_id Attachment ID.
   498 	 * @param int    $attachment_id Attachment ID.
   377 	 */
   499 	 */
   378 	$file = apply_filters( 'update_attached_file', $file, $attachment_id );
   500 	$file = apply_filters( 'update_attached_file', $file, $attachment_id );
   379 
   501 
   380 	if ( $file = _wp_relative_upload_path( $file ) )
   502 	if ( $file = _wp_relative_upload_path( $file ) ) {
   381 		return update_post_meta( $attachment_id, '_wp_attached_file', $file );
   503 		return update_post_meta( $attachment_id, '_wp_attached_file', $file );
   382 	else
   504 	} else {
   383 		return delete_post_meta( $attachment_id, '_wp_attached_file' );
   505 		return delete_post_meta( $attachment_id, '_wp_attached_file' );
       
   506 	}
   384 }
   507 }
   385 
   508 
   386 /**
   509 /**
   387  * Return relative path to an uploaded file.
   510  * Return relative path to an uploaded file.
   388  *
   511  *
   389  * The path is relative to the current upload dir.
   512  * The path is relative to the current upload dir.
   390  *
   513  *
   391  * @since 2.9.0
   514  * @since 2.9.0
       
   515  * @access private
   392  *
   516  *
   393  * @param string $path Full path to the file.
   517  * @param string $path Full path to the file.
   394  * @return string Relative path on success, unchanged path on failure.
   518  * @return string Relative path on success, unchanged path on failure.
   395  */
   519  */
   396 function _wp_relative_upload_path( $path ) {
   520 function _wp_relative_upload_path( $path ) {
   466  */
   590  */
   467 function get_children( $args = '', $output = OBJECT ) {
   591 function get_children( $args = '', $output = OBJECT ) {
   468 	$kids = array();
   592 	$kids = array();
   469 	if ( empty( $args ) ) {
   593 	if ( empty( $args ) ) {
   470 		if ( isset( $GLOBALS['post'] ) ) {
   594 		if ( isset( $GLOBALS['post'] ) ) {
   471 			$args = array('post_parent' => (int) $GLOBALS['post']->post_parent );
   595 			$args = array( 'post_parent' => (int) $GLOBALS['post']->post_parent );
   472 		} else {
   596 		} else {
   473 			return $kids;
   597 			return $kids;
   474 		}
   598 		}
   475 	} elseif ( is_object( $args ) ) {
   599 	} elseif ( is_object( $args ) ) {
   476 		$args = array('post_parent' => (int) $args->post_parent );
   600 		$args = array( 'post_parent' => (int) $args->post_parent );
   477 	} elseif ( is_numeric( $args ) ) {
   601 	} elseif ( is_numeric( $args ) ) {
   478 		$args = array('post_parent' => (int) $args);
   602 		$args = array( 'post_parent' => (int) $args );
   479 	}
   603 	}
   480 
   604 
   481 	$defaults = array(
   605 	$defaults = array(
   482 		'numberposts' => -1, 'post_type' => 'any',
   606 		'numberposts' => -1,
   483 		'post_status' => 'any', 'post_parent' => 0,
   607 		'post_type'   => 'any',
       
   608 		'post_status' => 'any',
       
   609 		'post_parent' => 0,
   484 	);
   610 	);
   485 
   611 
   486 	$r = wp_parse_args( $args, $defaults );
   612 	$r = wp_parse_args( $args, $defaults );
   487 
   613 
   488 	$children = get_posts( $r );
   614 	$children = get_posts( $r );
   489 
   615 
   490 	if ( ! $children )
   616 	if ( ! $children ) {
   491 		return $kids;
   617 		return $kids;
   492 
   618 	}
   493 	if ( ! empty( $r['fields'] ) )
   619 
       
   620 	if ( ! empty( $r['fields'] ) ) {
   494 		return $children;
   621 		return $children;
   495 
   622 	}
   496 	update_post_cache($children);
   623 
   497 
   624 	update_post_cache( $children );
   498 	foreach ( $children as $key => $child )
   625 
   499 		$kids[$child->ID] = $children[$key];
   626 	foreach ( $children as $key => $child ) {
       
   627 		$kids[ $child->ID ] = $children[ $key ];
       
   628 	}
   500 
   629 
   501 	if ( $output == OBJECT ) {
   630 	if ( $output == OBJECT ) {
   502 		return $kids;
   631 		return $kids;
   503 	} elseif ( $output == ARRAY_A ) {
   632 	} elseif ( $output == ARRAY_A ) {
   504 		$weeuns = array();
   633 		$weeuns = array();
   505 		foreach ( (array) $kids as $kid ) {
   634 		foreach ( (array) $kids as $kid ) {
   506 			$weeuns[$kid->ID] = get_object_vars($kids[$kid->ID]);
   635 			$weeuns[ $kid->ID ] = get_object_vars( $kids[ $kid->ID ] );
   507 		}
   636 		}
   508 		return $weeuns;
   637 		return $weeuns;
   509 	} elseif ( $output == ARRAY_N ) {
   638 	} elseif ( $output == ARRAY_N ) {
   510 		$babes = array();
   639 		$babes = array();
   511 		foreach ( (array) $kids as $kid ) {
   640 		foreach ( (array) $kids as $kid ) {
   512 			$babes[$kid->ID] = array_values(get_object_vars($kids[$kid->ID]));
   641 			$babes[ $kid->ID ] = array_values( get_object_vars( $kids[ $kid->ID ] ) );
   513 		}
   642 		}
   514 		return $babes;
   643 		return $babes;
   515 	} else {
   644 	} else {
   516 		return $kids;
   645 		return $kids;
   517 	}
   646 	}
   533  * @param string $post Post content.
   662  * @param string $post Post content.
   534  * @return array Post before ('main'), after ('extended'), and custom read more ('more_text').
   663  * @return array Post before ('main'), after ('extended'), and custom read more ('more_text').
   535  */
   664  */
   536 function get_extended( $post ) {
   665 function get_extended( $post ) {
   537 	//Match the new style more links.
   666 	//Match the new style more links.
   538 	if ( preg_match('/<!--more(.*?)?-->/', $post, $matches) ) {
   667 	if ( preg_match( '/<!--more(.*?)?-->/', $post, $matches ) ) {
   539 		list($main, $extended) = explode($matches[0], $post, 2);
   668 		list($main, $extended) = explode( $matches[0], $post, 2 );
   540 		$more_text = $matches[1];
   669 		$more_text             = $matches[1];
   541 	} else {
   670 	} else {
   542 		$main = $post;
   671 		$main      = $post;
   543 		$extended = '';
   672 		$extended  = '';
   544 		$more_text = '';
   673 		$more_text = '';
   545 	}
   674 	}
   546 
   675 
   547 	//  leading and trailing whitespace.
   676 	//  leading and trailing whitespace.
   548 	$main = preg_replace('/^[\s]*(.*)[\s]*$/', '\\1', $main);
   677 	$main      = preg_replace( '/^[\s]*(.*)[\s]*$/', '\\1', $main );
   549 	$extended = preg_replace('/^[\s]*(.*)[\s]*$/', '\\1', $extended);
   678 	$extended  = preg_replace( '/^[\s]*(.*)[\s]*$/', '\\1', $extended );
   550 	$more_text = preg_replace('/^[\s]*(.*)[\s]*$/', '\\1', $more_text);
   679 	$more_text = preg_replace( '/^[\s]*(.*)[\s]*$/', '\\1', $more_text );
   551 
   680 
   552 	return array( 'main' => $main, 'extended' => $extended, 'more_text' => $more_text );
   681 	return array(
       
   682 		'main'      => $main,
       
   683 		'extended'  => $extended,
       
   684 		'more_text' => $more_text,
       
   685 	);
   553 }
   686 }
   554 
   687 
   555 /**
   688 /**
   556  * Retrieves post data given a post ID or post object.
   689  * Retrieves post data given a post ID or post object.
   557  *
   690  *
   569  *                                 or 'display'. Default 'raw'.
   702  *                                 or 'display'. Default 'raw'.
   570  * @return WP_Post|array|null Type corresponding to $output on success or null on failure.
   703  * @return WP_Post|array|null Type corresponding to $output on success or null on failure.
   571  *                            When $output is OBJECT, a `WP_Post` instance is returned.
   704  *                            When $output is OBJECT, a `WP_Post` instance is returned.
   572  */
   705  */
   573 function get_post( $post = null, $output = OBJECT, $filter = 'raw' ) {
   706 function get_post( $post = null, $output = OBJECT, $filter = 'raw' ) {
   574 	if ( empty( $post ) && isset( $GLOBALS['post'] ) )
   707 	if ( empty( $post ) && isset( $GLOBALS['post'] ) ) {
   575 		$post = $GLOBALS['post'];
   708 		$post = $GLOBALS['post'];
       
   709 	}
   576 
   710 
   577 	if ( $post instanceof WP_Post ) {
   711 	if ( $post instanceof WP_Post ) {
   578 		$_post = $post;
   712 		$_post = $post;
   579 	} elseif ( is_object( $post ) ) {
   713 	} elseif ( is_object( $post ) ) {
   580 		if ( empty( $post->filter ) ) {
   714 		if ( empty( $post->filter ) ) {
   587 		}
   721 		}
   588 	} else {
   722 	} else {
   589 		$_post = WP_Post::get_instance( $post );
   723 		$_post = WP_Post::get_instance( $post );
   590 	}
   724 	}
   591 
   725 
   592 	if ( ! $_post )
   726 	if ( ! $_post ) {
   593 		return null;
   727 		return null;
       
   728 	}
   594 
   729 
   595 	$_post = $_post->filter( $filter );
   730 	$_post = $_post->filter( $filter );
   596 
   731 
   597 	if ( $output == ARRAY_A )
   732 	if ( $output == ARRAY_A ) {
   598 		return $_post->to_array();
   733 		return $_post->to_array();
   599 	elseif ( $output == ARRAY_N )
   734 	} elseif ( $output == ARRAY_N ) {
   600 		return array_values( $_post->to_array() );
   735 		return array_values( $_post->to_array() );
       
   736 	}
   601 
   737 
   602 	return $_post;
   738 	return $_post;
   603 }
   739 }
   604 
   740 
   605 /**
   741 /**
   611  * @return array Ancestor IDs or empty array if none are found.
   747  * @return array Ancestor IDs or empty array if none are found.
   612  */
   748  */
   613 function get_post_ancestors( $post ) {
   749 function get_post_ancestors( $post ) {
   614 	$post = get_post( $post );
   750 	$post = get_post( $post );
   615 
   751 
   616 	if ( ! $post || empty( $post->post_parent ) || $post->post_parent == $post->ID )
   752 	if ( ! $post || empty( $post->post_parent ) || $post->post_parent == $post->ID ) {
   617 		return array();
   753 		return array();
       
   754 	}
   618 
   755 
   619 	$ancestors = array();
   756 	$ancestors = array();
   620 
   757 
   621 	$id = $ancestors[] = $post->post_parent;
   758 	$id = $ancestors[] = $post->post_parent;
   622 
   759 
   623 	while ( $ancestor = get_post( $id ) ) {
   760 	while ( $ancestor = get_post( $id ) ) {
   624 		// Loop detection: If the ancestor has been seen before, break.
   761 		// Loop detection: If the ancestor has been seen before, break.
   625 		if ( empty( $ancestor->post_parent ) || ( $ancestor->post_parent == $post->ID ) || in_array( $ancestor->post_parent, $ancestors ) )
   762 		if ( empty( $ancestor->post_parent ) || ( $ancestor->post_parent == $post->ID ) || in_array( $ancestor->post_parent, $ancestors ) ) {
   626 			break;
   763 			break;
       
   764 		}
   627 
   765 
   628 		$id = $ancestors[] = $ancestor->post_parent;
   766 		$id = $ancestors[] = $ancestor->post_parent;
   629 	}
   767 	}
   630 
   768 
   631 	return $ancestors;
   769 	return $ancestors;
   644  * @since 4.5.0 The `$post` parameter was made optional.
   782  * @since 4.5.0 The `$post` parameter was made optional.
   645  *
   783  *
   646  * @see sanitize_post_field()
   784  * @see sanitize_post_field()
   647  *
   785  *
   648  * @param string      $field   Post field name.
   786  * @param string      $field   Post field name.
   649  * @param int|WP_Post $post    Optional. Post ID or post object. Defaults to current post.
   787  * @param int|WP_Post $post    Optional. Post ID or post object. Defaults to global $post.
   650  * @param string      $context Optional. How to filter the field. Accepts 'raw', 'edit', 'db',
   788  * @param string      $context Optional. How to filter the field. Accepts 'raw', 'edit', 'db',
   651  *                             or 'display'. Default 'display'.
   789  *                             or 'display'. Default 'display'.
   652  * @return string The value of the post field on success, empty string on failure.
   790  * @return string The value of the post field on success, empty string on failure.
   653  */
   791  */
   654 function get_post_field( $field, $post = null, $context = 'display' ) {
   792 function get_post_field( $field, $post = null, $context = 'display' ) {
   655 	$post = get_post( $post );
   793 	$post = get_post( $post );
   656 
   794 
   657 	if ( !$post )
   795 	if ( ! $post ) {
   658 		return '';
   796 		return '';
   659 
   797 	}
   660 	if ( !isset($post->$field) )
   798 
       
   799 	if ( ! isset( $post->$field ) ) {
   661 		return '';
   800 		return '';
   662 
   801 	}
   663 	return sanitize_post_field($field, $post->$field, $post->ID, $context);
   802 
       
   803 	return sanitize_post_field( $field, $post->$field, $post->ID, $context );
   664 }
   804 }
   665 
   805 
   666 /**
   806 /**
   667  * Retrieve the mime type of an attachment based on the ID.
   807  * Retrieve the mime type of an attachment based on the ID.
   668  *
   808  *
   669  * This function can be used with any post type, but it makes more sense with
   809  * This function can be used with any post type, but it makes more sense with
   670  * attachments.
   810  * attachments.
   671  *
   811  *
   672  * @since 2.0.0
   812  * @since 2.0.0
   673  *
   813  *
   674  * @param int|WP_Post $ID Optional. Post ID or post object. Default empty.
   814  * @param int|WP_Post $post Optional. Post ID or post object. Defaults to global $post.
   675  * @return string|false The mime type on success, false on failure.
   815  * @return string|false The mime type on success, false on failure.
   676  */
   816  */
   677 function get_post_mime_type( $ID = '' ) {
   817 function get_post_mime_type( $post = null ) {
   678 	$post = get_post($ID);
   818 	$post = get_post( $post );
   679 
   819 
   680 	if ( is_object($post) )
   820 	if ( is_object( $post ) ) {
   681 		return $post->post_mime_type;
   821 		return $post->post_mime_type;
       
   822 	}
   682 
   823 
   683 	return false;
   824 	return false;
   684 }
   825 }
   685 
   826 
   686 /**
   827 /**
   687  * Retrieve the post status based on the Post ID.
   828  * Retrieve the post status based on the post ID.
   688  *
   829  *
   689  * If the post ID is of an attachment, then the parent post status will be given
   830  * If the post ID is of an attachment, then the parent post status will be given
   690  * instead.
   831  * instead.
   691  *
   832  *
   692  * @since 2.0.0
   833  * @since 2.0.0
   693  *
   834  *
   694  * @param int|WP_Post $ID Optional. Post ID or post object. Default empty.
   835  * @param int|WP_Post $post Optional. Post ID or post object. Defaults to global $post..
   695  * @return string|false Post status on success, false on failure.
   836  * @return string|false Post status on success, false on failure.
   696  */
   837  */
   697 function get_post_status( $ID = '' ) {
   838 function get_post_status( $post = null ) {
   698 	$post = get_post($ID);
   839 	$post = get_post( $post );
   699 
   840 
   700 	if ( !is_object($post) )
   841 	if ( ! is_object( $post ) ) {
   701 		return false;
   842 		return false;
       
   843 	}
   702 
   844 
   703 	if ( 'attachment' == $post->post_type ) {
   845 	if ( 'attachment' == $post->post_type ) {
   704 		if ( 'private' == $post->post_status )
   846 		if ( 'private' == $post->post_status ) {
   705 			return 'private';
   847 			return 'private';
       
   848 		}
   706 
   849 
   707 		// Unattached attachments are assumed to be published.
   850 		// Unattached attachments are assumed to be published.
   708 		if ( ( 'inherit' == $post->post_status ) && ( 0 == $post->post_parent) )
   851 		if ( ( 'inherit' == $post->post_status ) && ( 0 == $post->post_parent ) ) {
   709 			return 'publish';
   852 			return 'publish';
       
   853 		}
   710 
   854 
   711 		// Inherit status from the parent.
   855 		// Inherit status from the parent.
   712 		if ( $post->post_parent && ( $post->ID != $post->post_parent ) ) {
   856 		if ( $post->post_parent && ( $post->ID != $post->post_parent ) ) {
   713 			$parent_post_status = get_post_status( $post->post_parent );
   857 			$parent_post_status = get_post_status( $post->post_parent );
   714 			if ( 'trash' == $parent_post_status ) {
   858 			if ( 'trash' == $parent_post_status ) {
   715 				return get_post_meta( $post->post_parent, '_wp_trash_meta_status', true );
   859 				return get_post_meta( $post->post_parent, '_wp_trash_meta_status', true );
   716 			} else {
   860 			} else {
   717 				return $parent_post_status;
   861 				return $parent_post_status;
   718 			}
   862 			}
   719 		}
   863 		}
   720 
       
   721 	}
   864 	}
   722 
   865 
   723 	/**
   866 	/**
   724 	 * Filters the post status.
   867 	 * Filters the post status.
   725 	 *
   868 	 *
   744 function get_post_statuses() {
   887 function get_post_statuses() {
   745 	$status = array(
   888 	$status = array(
   746 		'draft'   => __( 'Draft' ),
   889 		'draft'   => __( 'Draft' ),
   747 		'pending' => __( 'Pending Review' ),
   890 		'pending' => __( 'Pending Review' ),
   748 		'private' => __( 'Private' ),
   891 		'private' => __( 'Private' ),
   749 		'publish' => __( 'Published' )
   892 		'publish' => __( 'Published' ),
   750 	);
   893 	);
   751 
   894 
   752 	return $status;
   895 	return $status;
   753 }
   896 }
   754 
   897 
   764  */
   907  */
   765 function get_page_statuses() {
   908 function get_page_statuses() {
   766 	$status = array(
   909 	$status = array(
   767 		'draft'   => __( 'Draft' ),
   910 		'draft'   => __( 'Draft' ),
   768 		'private' => __( 'Private' ),
   911 		'private' => __( 'Private' ),
   769 		'publish' => __( 'Published' )
   912 		'publish' => __( 'Published' ),
   770 	);
   913 	);
   771 
   914 
   772 	return $status;
   915 	return $status;
   773 }
   916 }
   774 
   917 
   775 /**
   918 /**
   776  * Return statuses for privacy requests.
   919  * Return statuses for privacy requests.
   777  *
   920  *
   778  * @since 5.0.0
   921  * @since 4.9.6
       
   922  * @access private
   779  *
   923  *
   780  * @return array
   924  * @return array
   781  */
   925  */
   782 function _wp_privacy_statuses() {
   926 function _wp_privacy_statuses() {
   783 	return array(
   927 	return array(
   832  * @return object
   976  * @return object
   833  */
   977  */
   834 function register_post_status( $post_status, $args = array() ) {
   978 function register_post_status( $post_status, $args = array() ) {
   835 	global $wp_post_statuses;
   979 	global $wp_post_statuses;
   836 
   980 
   837 	if (!is_array($wp_post_statuses))
   981 	if ( ! is_array( $wp_post_statuses ) ) {
   838 		$wp_post_statuses = array();
   982 		$wp_post_statuses = array();
       
   983 	}
   839 
   984 
   840 	// Args prefixed with an underscore are reserved for internal use.
   985 	// Args prefixed with an underscore are reserved for internal use.
   841 	$defaults = array(
   986 	$defaults = array(
   842 		'label' => false,
   987 		'label'                     => false,
   843 		'label_count' => false,
   988 		'label_count'               => false,
   844 		'exclude_from_search' => null,
   989 		'exclude_from_search'       => null,
   845 		'_builtin' => false,
   990 		'_builtin'                  => false,
   846 		'public' => null,
   991 		'public'                    => null,
   847 		'internal' => null,
   992 		'internal'                  => null,
   848 		'protected' => null,
   993 		'protected'                 => null,
   849 		'private' => null,
   994 		'private'                   => null,
   850 		'publicly_queryable' => null,
   995 		'publicly_queryable'        => null,
   851 		'show_in_admin_status_list' => null,
   996 		'show_in_admin_status_list' => null,
   852 		'show_in_admin_all_list' => null,
   997 		'show_in_admin_all_list'    => null,
   853 	);
   998 	);
   854 	$args = wp_parse_args($args, $defaults);
   999 	$args     = wp_parse_args( $args, $defaults );
   855 	$args = (object) $args;
  1000 	$args     = (object) $args;
   856 
  1001 
   857 	$post_status = sanitize_key($post_status);
  1002 	$post_status = sanitize_key( $post_status );
   858 	$args->name = $post_status;
  1003 	$args->name  = $post_status;
   859 
  1004 
   860 	// Set various defaults.
  1005 	// Set various defaults.
   861 	if ( null === $args->public && null === $args->internal && null === $args->protected && null === $args->private )
  1006 	if ( null === $args->public && null === $args->internal && null === $args->protected && null === $args->private ) {
   862 		$args->internal = true;
  1007 		$args->internal = true;
   863 
  1008 	}
   864 	if ( null === $args->public  )
  1009 
       
  1010 	if ( null === $args->public ) {
   865 		$args->public = false;
  1011 		$args->public = false;
   866 
  1012 	}
   867 	if ( null === $args->private  )
  1013 
       
  1014 	if ( null === $args->private ) {
   868 		$args->private = false;
  1015 		$args->private = false;
   869 
  1016 	}
   870 	if ( null === $args->protected  )
  1017 
       
  1018 	if ( null === $args->protected ) {
   871 		$args->protected = false;
  1019 		$args->protected = false;
   872 
  1020 	}
   873 	if ( null === $args->internal  )
  1021 
       
  1022 	if ( null === $args->internal ) {
   874 		$args->internal = false;
  1023 		$args->internal = false;
   875 
  1024 	}
   876 	if ( null === $args->publicly_queryable )
  1025 
       
  1026 	if ( null === $args->publicly_queryable ) {
   877 		$args->publicly_queryable = $args->public;
  1027 		$args->publicly_queryable = $args->public;
   878 
  1028 	}
   879 	if ( null === $args->exclude_from_search )
  1029 
       
  1030 	if ( null === $args->exclude_from_search ) {
   880 		$args->exclude_from_search = $args->internal;
  1031 		$args->exclude_from_search = $args->internal;
   881 
  1032 	}
   882 	if ( null === $args->show_in_admin_all_list )
  1033 
   883 		$args->show_in_admin_all_list = !$args->internal;
  1034 	if ( null === $args->show_in_admin_all_list ) {
   884 
  1035 		$args->show_in_admin_all_list = ! $args->internal;
   885 	if ( null === $args->show_in_admin_status_list )
  1036 	}
   886 		$args->show_in_admin_status_list = !$args->internal;
  1037 
   887 
  1038 	if ( null === $args->show_in_admin_status_list ) {
   888 	if ( false === $args->label )
  1039 		$args->show_in_admin_status_list = ! $args->internal;
       
  1040 	}
       
  1041 
       
  1042 	if ( false === $args->label ) {
   889 		$args->label = $post_status;
  1043 		$args->label = $post_status;
   890 
  1044 	}
   891 	if ( false === $args->label_count )
  1045 
       
  1046 	if ( false === $args->label_count ) {
       
  1047 		// phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralSingle,WordPress.WP.I18n.NonSingularStringLiteralPlural
   892 		$args->label_count = _n_noop( $args->label, $args->label );
  1048 		$args->label_count = _n_noop( $args->label, $args->label );
   893 
  1049 	}
   894 	$wp_post_statuses[$post_status] = $args;
  1050 
       
  1051 	$wp_post_statuses[ $post_status ] = $args;
   895 
  1052 
   896 	return $args;
  1053 	return $args;
   897 }
  1054 }
   898 
  1055 
   899 /**
  1056 /**
   909  * @return object|null A post status object.
  1066  * @return object|null A post status object.
   910  */
  1067  */
   911 function get_post_status_object( $post_status ) {
  1068 function get_post_status_object( $post_status ) {
   912 	global $wp_post_statuses;
  1069 	global $wp_post_statuses;
   913 
  1070 
   914 	if ( empty($wp_post_statuses[$post_status]) )
  1071 	if ( empty( $wp_post_statuses[ $post_status ] ) ) {
   915 		return null;
  1072 		return null;
   916 
  1073 	}
   917 	return $wp_post_statuses[$post_status];
  1074 
       
  1075 	return $wp_post_statuses[ $post_status ];
   918 }
  1076 }
   919 
  1077 
   920 /**
  1078 /**
   921  * Get a list of post statuses.
  1079  * Get a list of post statuses.
   922  *
  1080  *
   935  * @return array A list of post status names or objects.
  1093  * @return array A list of post status names or objects.
   936  */
  1094  */
   937 function get_post_stati( $args = array(), $output = 'names', $operator = 'and' ) {
  1095 function get_post_stati( $args = array(), $output = 'names', $operator = 'and' ) {
   938 	global $wp_post_statuses;
  1096 	global $wp_post_statuses;
   939 
  1097 
   940 	$field = ('names' == $output) ? 'name' : false;
  1098 	$field = ( 'names' == $output ) ? 'name' : false;
   941 
  1099 
   942 	return wp_filter_object_list($wp_post_statuses, $args, $operator, $field);
  1100 	return wp_filter_object_list( $wp_post_statuses, $args, $operator, $field );
   943 }
  1101 }
   944 
  1102 
   945 /**
  1103 /**
   946  * Whether the post type is hierarchical.
  1104  * Whether the post type is hierarchical.
   947  *
  1105  *
   953  *
  1111  *
   954  * @param string $post_type Post type name
  1112  * @param string $post_type Post type name
   955  * @return bool Whether post type is hierarchical.
  1113  * @return bool Whether post type is hierarchical.
   956  */
  1114  */
   957 function is_post_type_hierarchical( $post_type ) {
  1115 function is_post_type_hierarchical( $post_type ) {
   958 	if ( ! post_type_exists( $post_type ) )
  1116 	if ( ! post_type_exists( $post_type ) ) {
   959 		return false;
  1117 		return false;
       
  1118 	}
   960 
  1119 
   961 	$post_type = get_post_type_object( $post_type );
  1120 	$post_type = get_post_type_object( $post_type );
   962 	return $post_type->hierarchical;
  1121 	return $post_type->hierarchical;
   963 }
  1122 }
   964 
  1123 
   965 /**
  1124 /**
   966  * Check if a post type is registered.
  1125  * Determines whether a post type is registered.
       
  1126  *
       
  1127  * For more information on this and similar theme functions, check out
       
  1128  * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
       
  1129  * Conditional Tags} article in the Theme Developer Handbook.
   967  *
  1130  *
   968  * @since 3.0.0
  1131  * @since 3.0.0
   969  *
  1132  *
   970  * @see get_post_type_object()
  1133  * @see get_post_type_object()
   971  *
  1134  *
   983  *
  1146  *
   984  * @param int|WP_Post|null $post Optional. Post ID or post object. Default is global $post.
  1147  * @param int|WP_Post|null $post Optional. Post ID or post object. Default is global $post.
   985  * @return string|false          Post type on success, false on failure.
  1148  * @return string|false          Post type on success, false on failure.
   986  */
  1149  */
   987 function get_post_type( $post = null ) {
  1150 function get_post_type( $post = null ) {
   988 	if ( $post = get_post( $post ) )
  1151 	if ( $post = get_post( $post ) ) {
   989 		return $post->post_type;
  1152 		return $post->post_type;
       
  1153 	}
   990 
  1154 
   991 	return false;
  1155 	return false;
   992 }
  1156 }
   993 
  1157 
   994 /**
  1158 /**
   995  * Retrieves a post type object by name.
  1159  * Retrieves a post type object by name.
   996  *
  1160  *
   997  * @since 3.0.0
  1161  * @since 3.0.0
   998  * @since 4.6.0 Object returned is now an instance of WP_Post_Type.
  1162  * @since 4.6.0 Object returned is now an instance of `WP_Post_Type`.
   999  *
  1163  *
  1000  * @global array $wp_post_types List of post types.
  1164  * @global array $wp_post_types List of post types.
  1001  *
  1165  *
  1002  * @see register_post_type()
  1166  * @see register_post_type()
  1003  *
  1167  *
  1028  * @param string       $output   Optional. The type of output to return. Accepts post type 'names'
  1192  * @param string       $output   Optional. The type of output to return. Accepts post type 'names'
  1029  *                               or 'objects'. Default 'names'.
  1193  *                               or 'objects'. Default 'names'.
  1030  * @param string       $operator Optional. The logical operation to perform. 'or' means only one
  1194  * @param string       $operator Optional. The logical operation to perform. 'or' means only one
  1031  *                               element from the array needs to match; 'and' means all elements
  1195  *                               element from the array needs to match; 'and' means all elements
  1032  *                               must match; 'not' means no elements may match. Default 'and'.
  1196  *                               must match; 'not' means no elements may match. Default 'and'.
  1033  * @return array A list of post type names or objects.
  1197  * @return string[]|WP_Post_Type[] An array of post type names or objects.
  1034  */
  1198  */
  1035 function get_post_types( $args = array(), $output = 'names', $operator = 'and' ) {
  1199 function get_post_types( $args = array(), $output = 'names', $operator = 'and' ) {
  1036 	global $wp_post_types;
  1200 	global $wp_post_types;
  1037 
  1201 
  1038 	$field = ('names' == $output) ? 'name' : false;
  1202 	$field = ( 'names' == $output ) ? 'name' : false;
  1039 
  1203 
  1040 	return wp_filter_object_list($wp_post_types, $args, $operator, $field);
  1204 	return wp_filter_object_list( $wp_post_types, $args, $operator, $field );
  1041 }
  1205 }
  1042 
  1206 
  1043 /**
  1207 /**
  1044  * Registers a post type.
  1208  * Registers a post type.
  1045  *
  1209  *
  1056  *
  1220  *
  1057  * @since 2.9.0
  1221  * @since 2.9.0
  1058  * @since 3.0.0 The `show_ui` argument is now enforced on the new post screen.
  1222  * @since 3.0.0 The `show_ui` argument is now enforced on the new post screen.
  1059  * @since 4.4.0 The `show_ui` argument is now enforced on the post type listing
  1223  * @since 4.4.0 The `show_ui` argument is now enforced on the post type listing
  1060  *              screen and post editing screen.
  1224  *              screen and post editing screen.
  1061  * @since 4.6.0 Post type object returned is now an instance of WP_Post_Type.
  1225  * @since 4.6.0 Post type object returned is now an instance of `WP_Post_Type`.
  1062  * @since 4.7.0 Introduced `show_in_rest`, 'rest_base' and 'rest_controller_class'
  1226  * @since 4.7.0 Introduced `show_in_rest`, `rest_base` and `rest_controller_class`
  1063  *              arguments to register the post type in REST API.
  1227  *              arguments to register the post type in REST API.
  1064  *
  1228  *
  1065  * @global array $wp_post_types List of post types.
  1229  * @global array $wp_post_types List of post types.
  1066  *
  1230  *
  1067  * @param string $post_type Post type key. Must not exceed 20 characters and may
  1231  * @param string $post_type Post type key. Must not exceed 20 characters and may
  1203 
  1367 
  1204 	/**
  1368 	/**
  1205 	 * Fires after a post type is registered.
  1369 	 * Fires after a post type is registered.
  1206 	 *
  1370 	 *
  1207 	 * @since 3.3.0
  1371 	 * @since 3.3.0
  1208 	 * @since 4.6.0 Converted the `$post_type` parameter to accept a WP_Post_Type object.
  1372 	 * @since 4.6.0 Converted the `$post_type` parameter to accept a `WP_Post_Type` object.
  1209 	 *
  1373 	 *
  1210 	 * @param string       $post_type        Post type.
  1374 	 * @param string       $post_type        Post type.
  1211 	 * @param WP_Post_Type $post_type_object Arguments used to register the post type.
  1375 	 * @param WP_Post_Type $post_type_object Arguments used to register the post type.
  1212 	 */
  1376 	 */
  1213 	do_action( 'registered_post_type', $post_type, $post_type_object );
  1377 	do_action( 'registered_post_type', $post_type, $post_type_object );
  1315  *
  1479  *
  1316  * @param object $args Post type registration arguments.
  1480  * @param object $args Post type registration arguments.
  1317  * @return object Object with all the capabilities as member variables.
  1481  * @return object Object with all the capabilities as member variables.
  1318  */
  1482  */
  1319 function get_post_type_capabilities( $args ) {
  1483 function get_post_type_capabilities( $args ) {
  1320 	if ( ! is_array( $args->capability_type ) )
  1484 	if ( ! is_array( $args->capability_type ) ) {
  1321 		$args->capability_type = array( $args->capability_type, $args->capability_type . 's' );
  1485 		$args->capability_type = array( $args->capability_type, $args->capability_type . 's' );
       
  1486 	}
  1322 
  1487 
  1323 	// Singular base for meta capabilities, plural base for primitive capabilities.
  1488 	// Singular base for meta capabilities, plural base for primitive capabilities.
  1324 	list( $singular_base, $plural_base ) = $args->capability_type;
  1489 	list( $singular_base, $plural_base ) = $args->capability_type;
  1325 
  1490 
  1326 	$default_capabilities = array(
  1491 	$default_capabilities = array(
  1327 		// Meta capabilities
  1492 		// Meta capabilities
  1328 		'edit_post'          => 'edit_'         . $singular_base,
  1493 		'edit_post'          => 'edit_' . $singular_base,
  1329 		'read_post'          => 'read_'         . $singular_base,
  1494 		'read_post'          => 'read_' . $singular_base,
  1330 		'delete_post'        => 'delete_'       . $singular_base,
  1495 		'delete_post'        => 'delete_' . $singular_base,
  1331 		// Primitive capabilities used outside of map_meta_cap():
  1496 		// Primitive capabilities used outside of map_meta_cap():
  1332 		'edit_posts'         => 'edit_'         . $plural_base,
  1497 		'edit_posts'         => 'edit_' . $plural_base,
  1333 		'edit_others_posts'  => 'edit_others_'  . $plural_base,
  1498 		'edit_others_posts'  => 'edit_others_' . $plural_base,
  1334 		'publish_posts'      => 'publish_'      . $plural_base,
  1499 		'publish_posts'      => 'publish_' . $plural_base,
  1335 		'read_private_posts' => 'read_private_' . $plural_base,
  1500 		'read_private_posts' => 'read_private_' . $plural_base,
  1336 	);
  1501 	);
  1337 
  1502 
  1338 	// Primitive capabilities used within map_meta_cap():
  1503 	// Primitive capabilities used within map_meta_cap():
  1339 	if ( $args->map_meta_cap ) {
  1504 	if ( $args->map_meta_cap ) {
  1340 		$default_capabilities_for_mapping = array(
  1505 		$default_capabilities_for_mapping = array(
  1341 			'read'                   => 'read',
  1506 			'read'                   => 'read',
  1342 			'delete_posts'           => 'delete_'           . $plural_base,
  1507 			'delete_posts'           => 'delete_' . $plural_base,
  1343 			'delete_private_posts'   => 'delete_private_'   . $plural_base,
  1508 			'delete_private_posts'   => 'delete_private_' . $plural_base,
  1344 			'delete_published_posts' => 'delete_published_' . $plural_base,
  1509 			'delete_published_posts' => 'delete_published_' . $plural_base,
  1345 			'delete_others_posts'    => 'delete_others_'    . $plural_base,
  1510 			'delete_others_posts'    => 'delete_others_' . $plural_base,
  1346 			'edit_private_posts'     => 'edit_private_'     . $plural_base,
  1511 			'edit_private_posts'     => 'edit_private_' . $plural_base,
  1347 			'edit_published_posts'   => 'edit_published_'   . $plural_base,
  1512 			'edit_published_posts'   => 'edit_published_' . $plural_base,
  1348 		);
  1513 		);
  1349 		$default_capabilities = array_merge( $default_capabilities, $default_capabilities_for_mapping );
  1514 		$default_capabilities             = array_merge( $default_capabilities, $default_capabilities_for_mapping );
  1350 	}
  1515 	}
  1351 
  1516 
  1352 	$capabilities = array_merge( $default_capabilities, $args->capabilities );
  1517 	$capabilities = array_merge( $default_capabilities, $args->capabilities );
  1353 
  1518 
  1354 	// Post creation capability simply maps to edit_posts by default:
  1519 	// Post creation capability simply maps to edit_posts by default:
  1355 	if ( ! isset( $capabilities['create_posts'] ) )
  1520 	if ( ! isset( $capabilities['create_posts'] ) ) {
  1356 		$capabilities['create_posts'] = $capabilities['edit_posts'];
  1521 		$capabilities['create_posts'] = $capabilities['edit_posts'];
       
  1522 	}
  1357 
  1523 
  1358 	// Remember meta capabilities for future reference.
  1524 	// Remember meta capabilities for future reference.
  1359 	if ( $args->map_meta_cap )
  1525 	if ( $args->map_meta_cap ) {
  1360 		_post_type_meta_capabilities( $capabilities );
  1526 		_post_type_meta_capabilities( $capabilities );
       
  1527 	}
  1361 
  1528 
  1362 	return (object) $capabilities;
  1529 	return (object) $capabilities;
  1363 }
  1530 }
  1364 
  1531 
  1365 /**
  1532 /**
  1418  * - `filter_items_list` - Label for the table views hidden heading. Default is 'Filter posts list' /
  1585  * - `filter_items_list` - Label for the table views hidden heading. Default is 'Filter posts list' /
  1419  *                       'Filter pages list'.
  1586  *                       'Filter pages list'.
  1420  * - `items_list_navigation` - Label for the table pagination hidden heading. Default is 'Posts list navigation' /
  1587  * - `items_list_navigation` - Label for the table pagination hidden heading. Default is 'Posts list navigation' /
  1421  *                           'Pages list navigation'.
  1588  *                           'Pages list navigation'.
  1422  * - `items_list` - Label for the table hidden heading. Default is 'Posts list' / 'Pages list'.
  1589  * - `items_list` - Label for the table hidden heading. Default is 'Posts list' / 'Pages list'.
       
  1590  * - `item_published` - Label used when an item is published. Default is 'Post published.' / 'Page published.'
       
  1591  * - `item_published_privately` - Label used when an item is published with private visibility.
       
  1592  *                              Default is 'Post published privately.' / 'Page published privately.'
       
  1593  * - `item_reverted_to_draft` - Label used when an item is switched to a draft.
       
  1594  *                            Default is 'Post reverted to draft.' / 'Page reverted to draft.'
       
  1595  * - `item_scheduled` - Label used when an item is scheduled for publishing. Default is 'Post scheduled.' /
       
  1596  *                    'Page scheduled.'
       
  1597  * - `item_updated` - Label used when an item is updated. Default is 'Post updated.' / 'Page updated.'
  1423  *
  1598  *
  1424  * Above, the first default value is for non-hierarchical post types (like posts)
  1599  * Above, the first default value is for non-hierarchical post types (like posts)
  1425  * and the second one is for hierarchical post types (like pages).
  1600  * and the second one is for hierarchical post types (like pages).
  1426  *
  1601  *
  1427  * Note: To set labels used in post type admin notices, see the {@see 'post_updated_messages'} filter.
  1602  * Note: To set labels used in post type admin notices, see the {@see 'post_updated_messages'} filter.
  1429  * @since 3.0.0
  1604  * @since 3.0.0
  1430  * @since 4.3.0 Added the `featured_image`, `set_featured_image`, `remove_featured_image`,
  1605  * @since 4.3.0 Added the `featured_image`, `set_featured_image`, `remove_featured_image`,
  1431  *              and `use_featured_image` labels.
  1606  *              and `use_featured_image` labels.
  1432  * @since 4.4.0 Added the `archives`, `insert_into_item`, `uploaded_to_this_item`, `filter_items_list`,
  1607  * @since 4.4.0 Added the `archives`, `insert_into_item`, `uploaded_to_this_item`, `filter_items_list`,
  1433  *              `items_list_navigation`, and `items_list` labels.
  1608  *              `items_list_navigation`, and `items_list` labels.
  1434  * @since 4.6.0 Converted the `$post_type` parameter to accept a WP_Post_Type object.
  1609  * @since 4.6.0 Converted the `$post_type` parameter to accept a `WP_Post_Type` object.
  1435  * @since 4.7.0 Added the `view_items` and `attributes` labels.
  1610  * @since 4.7.0 Added the `view_items` and `attributes` labels.
       
  1611  * @since 5.0.0 Added the `item_published`, `item_published_privately`, `item_reverted_to_draft`,
       
  1612  *              `item_scheduled`, and `item_updated` labels.
  1436  *
  1613  *
  1437  * @access private
  1614  * @access private
  1438  *
  1615  *
  1439  * @param object|WP_Post_Type $post_type_object Post type object.
  1616  * @param object|WP_Post_Type $post_type_object Post type object.
  1440  * @return object Object with all the labels as member variables.
  1617  * @return object Object with all the labels as member variables.
  1441  */
  1618  */
  1442 function get_post_type_labels( $post_type_object ) {
  1619 function get_post_type_labels( $post_type_object ) {
  1443 	$nohier_vs_hier_defaults = array(
  1620 	$nohier_vs_hier_defaults              = array(
  1444 		'name' => array( _x('Posts', 'post type general name'), _x('Pages', 'post type general name') ),
  1621 		'name'                     => array( _x( 'Posts', 'post type general name' ), _x( 'Pages', 'post type general name' ) ),
  1445 		'singular_name' => array( _x('Post', 'post type singular name'), _x('Page', 'post type singular name') ),
  1622 		'singular_name'            => array( _x( 'Post', 'post type singular name' ), _x( 'Page', 'post type singular name' ) ),
  1446 		'add_new' => array( _x('Add New', 'post'), _x('Add New', 'page') ),
  1623 		'add_new'                  => array( _x( 'Add New', 'post' ), _x( 'Add New', 'page' ) ),
  1447 		'add_new_item' => array( __('Add New Post'), __('Add New Page') ),
  1624 		'add_new_item'             => array( __( 'Add New Post' ), __( 'Add New Page' ) ),
  1448 		'edit_item' => array( __('Edit Post'), __('Edit Page') ),
  1625 		'edit_item'                => array( __( 'Edit Post' ), __( 'Edit Page' ) ),
  1449 		'new_item' => array( __('New Post'), __('New Page') ),
  1626 		'new_item'                 => array( __( 'New Post' ), __( 'New Page' ) ),
  1450 		'view_item' => array( __('View Post'), __('View Page') ),
  1627 		'view_item'                => array( __( 'View Post' ), __( 'View Page' ) ),
  1451 		'view_items' => array( __('View Posts'), __('View Pages') ),
  1628 		'view_items'               => array( __( 'View Posts' ), __( 'View Pages' ) ),
  1452 		'search_items' => array( __('Search Posts'), __('Search Pages') ),
  1629 		'search_items'             => array( __( 'Search Posts' ), __( 'Search Pages' ) ),
  1453 		'not_found' => array( __('No posts found.'), __('No pages found.') ),
  1630 		'not_found'                => array( __( 'No posts found.' ), __( 'No pages found.' ) ),
  1454 		'not_found_in_trash' => array( __('No posts found in Trash.'), __('No pages found in Trash.') ),
  1631 		'not_found_in_trash'       => array( __( 'No posts found in Trash.' ), __( 'No pages found in Trash.' ) ),
  1455 		'parent_item_colon' => array( null, __('Parent Page:') ),
  1632 		'parent_item_colon'        => array( null, __( 'Parent Page:' ) ),
  1456 		'all_items' => array( __( 'All Posts' ), __( 'All Pages' ) ),
  1633 		'all_items'                => array( __( 'All Posts' ), __( 'All Pages' ) ),
  1457 		'archives' => array( __( 'Post Archives' ), __( 'Page Archives' ) ),
  1634 		'archives'                 => array( __( 'Post Archives' ), __( 'Page Archives' ) ),
  1458 		'attributes' => array( __( 'Post Attributes' ), __( 'Page Attributes' ) ),
  1635 		'attributes'               => array( __( 'Post Attributes' ), __( 'Page Attributes' ) ),
  1459 		'insert_into_item' => array( __( 'Insert into post' ), __( 'Insert into page' ) ),
  1636 		'insert_into_item'         => array( __( 'Insert into post' ), __( 'Insert into page' ) ),
  1460 		'uploaded_to_this_item' => array( __( 'Uploaded to this post' ), __( 'Uploaded to this page' ) ),
  1637 		'uploaded_to_this_item'    => array( __( 'Uploaded to this post' ), __( 'Uploaded to this page' ) ),
  1461 		'featured_image' => array( _x( 'Featured Image', 'post' ), _x( 'Featured Image', 'page' ) ),
  1638 		'featured_image'           => array( _x( 'Featured Image', 'post' ), _x( 'Featured Image', 'page' ) ),
  1462 		'set_featured_image' => array( _x( 'Set featured image', 'post' ), _x( 'Set featured image', 'page' ) ),
  1639 		'set_featured_image'       => array( _x( 'Set featured image', 'post' ), _x( 'Set featured image', 'page' ) ),
  1463 		'remove_featured_image' => array( _x( 'Remove featured image', 'post' ), _x( 'Remove featured image', 'page' ) ),
  1640 		'remove_featured_image'    => array( _x( 'Remove featured image', 'post' ), _x( 'Remove featured image', 'page' ) ),
  1464 		'use_featured_image' => array( _x( 'Use as featured image', 'post' ), _x( 'Use as featured image', 'page' ) ),
  1641 		'use_featured_image'       => array( _x( 'Use as featured image', 'post' ), _x( 'Use as featured image', 'page' ) ),
  1465 		'filter_items_list' => array( __( 'Filter posts list' ), __( 'Filter pages list' ) ),
  1642 		'filter_items_list'        => array( __( 'Filter posts list' ), __( 'Filter pages list' ) ),
  1466 		'items_list_navigation' => array( __( 'Posts list navigation' ), __( 'Pages list navigation' ) ),
  1643 		'items_list_navigation'    => array( __( 'Posts list navigation' ), __( 'Pages list navigation' ) ),
  1467 		'items_list' => array( __( 'Posts list' ), __( 'Pages list' ) ),
  1644 		'items_list'               => array( __( 'Posts list' ), __( 'Pages list' ) ),
       
  1645 		'item_published'           => array( __( 'Post published.' ), __( 'Page published.' ) ),
       
  1646 		'item_published_privately' => array( __( 'Post published privately.' ), __( 'Page published privately.' ) ),
       
  1647 		'item_reverted_to_draft'   => array( __( 'Post reverted to draft.' ), __( 'Page reverted to draft.' ) ),
       
  1648 		'item_scheduled'           => array( __( 'Post scheduled.' ), __( 'Page scheduled.' ) ),
       
  1649 		'item_updated'             => array( __( 'Post updated.' ), __( 'Page updated.' ) ),
  1468 	);
  1650 	);
  1469 	$nohier_vs_hier_defaults['menu_name'] = $nohier_vs_hier_defaults['name'];
  1651 	$nohier_vs_hier_defaults['menu_name'] = $nohier_vs_hier_defaults['name'];
  1470 
  1652 
  1471 	$labels = _get_custom_object_labels( $post_type_object, $nohier_vs_hier_defaults );
  1653 	$labels = _get_custom_object_labels( $post_type_object, $nohier_vs_hier_defaults );
  1472 
  1654 
  1506  * @return object Object containing labels for the given custom-something object.
  1688  * @return object Object containing labels for the given custom-something object.
  1507  */
  1689  */
  1508 function _get_custom_object_labels( $object, $nohier_vs_hier_defaults ) {
  1690 function _get_custom_object_labels( $object, $nohier_vs_hier_defaults ) {
  1509 	$object->labels = (array) $object->labels;
  1691 	$object->labels = (array) $object->labels;
  1510 
  1692 
  1511 	if ( isset( $object->label ) && empty( $object->labels['name'] ) )
  1693 	if ( isset( $object->label ) && empty( $object->labels['name'] ) ) {
  1512 		$object->labels['name'] = $object->label;
  1694 		$object->labels['name'] = $object->label;
  1513 
  1695 	}
  1514 	if ( !isset( $object->labels['singular_name'] ) && isset( $object->labels['name'] ) )
  1696 
       
  1697 	if ( ! isset( $object->labels['singular_name'] ) && isset( $object->labels['name'] ) ) {
  1515 		$object->labels['singular_name'] = $object->labels['name'];
  1698 		$object->labels['singular_name'] = $object->labels['name'];
  1516 
  1699 	}
  1517 	if ( ! isset( $object->labels['name_admin_bar'] ) )
  1700 
       
  1701 	if ( ! isset( $object->labels['name_admin_bar'] ) ) {
  1518 		$object->labels['name_admin_bar'] = isset( $object->labels['singular_name'] ) ? $object->labels['singular_name'] : $object->name;
  1702 		$object->labels['name_admin_bar'] = isset( $object->labels['singular_name'] ) ? $object->labels['singular_name'] : $object->name;
  1519 
  1703 	}
  1520 	if ( !isset( $object->labels['menu_name'] ) && isset( $object->labels['name'] ) )
  1704 
       
  1705 	if ( ! isset( $object->labels['menu_name'] ) && isset( $object->labels['name'] ) ) {
  1521 		$object->labels['menu_name'] = $object->labels['name'];
  1706 		$object->labels['menu_name'] = $object->labels['name'];
  1522 
  1707 	}
  1523 	if ( !isset( $object->labels['all_items'] ) && isset( $object->labels['menu_name'] ) )
  1708 
       
  1709 	if ( ! isset( $object->labels['all_items'] ) && isset( $object->labels['menu_name'] ) ) {
  1524 		$object->labels['all_items'] = $object->labels['menu_name'];
  1710 		$object->labels['all_items'] = $object->labels['menu_name'];
  1525 
  1711 	}
  1526 	if ( !isset( $object->labels['archives'] ) && isset( $object->labels['all_items'] ) ) {
  1712 
       
  1713 	if ( ! isset( $object->labels['archives'] ) && isset( $object->labels['all_items'] ) ) {
  1527 		$object->labels['archives'] = $object->labels['all_items'];
  1714 		$object->labels['archives'] = $object->labels['all_items'];
  1528 	}
  1715 	}
  1529 
  1716 
  1530 	$defaults = array();
  1717 	$defaults = array();
  1531 	foreach ( $nohier_vs_hier_defaults as $key => $value ) {
  1718 	foreach ( $nohier_vs_hier_defaults as $key => $value ) {
  1532 		$defaults[$key] = $object->hierarchical ? $value[1] : $value[0];
  1719 		$defaults[ $key ] = $object->hierarchical ? $value[1] : $value[0];
  1533 	}
  1720 	}
  1534 	$labels = array_merge( $defaults, $object->labels );
  1721 	$labels         = array_merge( $defaults, $object->labels );
  1535 	$object->labels = (object) $object->labels;
  1722 	$object->labels = (object) $object->labels;
  1536 
  1723 
  1537 	return (object) $labels;
  1724 	return (object) $labels;
  1538 }
  1725 }
  1539 
  1726 
  1545  */
  1732  */
  1546 function _add_post_type_submenus() {
  1733 function _add_post_type_submenus() {
  1547 	foreach ( get_post_types( array( 'show_ui' => true ) ) as $ptype ) {
  1734 	foreach ( get_post_types( array( 'show_ui' => true ) ) as $ptype ) {
  1548 		$ptype_obj = get_post_type_object( $ptype );
  1735 		$ptype_obj = get_post_type_object( $ptype );
  1549 		// Sub-menus only.
  1736 		// Sub-menus only.
  1550 		if ( ! $ptype_obj->show_in_menu || $ptype_obj->show_in_menu === true )
  1737 		if ( ! $ptype_obj->show_in_menu || $ptype_obj->show_in_menu === true ) {
  1551 			continue;
  1738 			continue;
       
  1739 		}
  1552 		add_submenu_page( $ptype_obj->show_in_menu, $ptype_obj->labels->name, $ptype_obj->labels->all_items, $ptype_obj->cap->edit_posts, "edit.php?post_type=$ptype" );
  1740 		add_submenu_page( $ptype_obj->show_in_menu, $ptype_obj->labels->name, $ptype_obj->labels->all_items, $ptype_obj->cap->edit_posts, "edit.php?post_type=$ptype" );
  1553 	}
  1741 	}
  1554 }
  1742 }
  1555 
  1743 
  1556 /**
  1744 /**
  1575  */
  1763  */
  1576 function add_post_type_support( $post_type, $feature ) {
  1764 function add_post_type_support( $post_type, $feature ) {
  1577 	global $_wp_post_type_features;
  1765 	global $_wp_post_type_features;
  1578 
  1766 
  1579 	$features = (array) $feature;
  1767 	$features = (array) $feature;
  1580 	foreach ($features as $feature) {
  1768 	foreach ( $features as $feature ) {
  1581 		if ( func_num_args() == 2 )
  1769 		if ( func_num_args() == 2 ) {
  1582 			$_wp_post_type_features[$post_type][$feature] = true;
  1770 			$_wp_post_type_features[ $post_type ][ $feature ] = true;
  1583 		else
  1771 		} else {
  1584 			$_wp_post_type_features[$post_type][$feature] = array_slice( func_get_args(), 2 );
  1772 			$_wp_post_type_features[ $post_type ][ $feature ] = array_slice( func_get_args(), 2 );
       
  1773 		}
  1585 	}
  1774 	}
  1586 }
  1775 }
  1587 
  1776 
  1588 /**
  1777 /**
  1589  * Remove support for a feature from a post type.
  1778  * Remove support for a feature from a post type.
  1612  * @return array Post type supports list.
  1801  * @return array Post type supports list.
  1613  */
  1802  */
  1614 function get_all_post_type_supports( $post_type ) {
  1803 function get_all_post_type_supports( $post_type ) {
  1615 	global $_wp_post_type_features;
  1804 	global $_wp_post_type_features;
  1616 
  1805 
  1617 	if ( isset( $_wp_post_type_features[$post_type] ) )
  1806 	if ( isset( $_wp_post_type_features[ $post_type ] ) ) {
  1618 		return $_wp_post_type_features[$post_type];
  1807 		return $_wp_post_type_features[ $post_type ];
       
  1808 	}
  1619 
  1809 
  1620 	return array();
  1810 	return array();
  1621 }
  1811 }
  1622 
  1812 
  1623 /**
  1813 /**
  1632  * @return bool Whether the post type supports the given feature.
  1822  * @return bool Whether the post type supports the given feature.
  1633  */
  1823  */
  1634 function post_type_supports( $post_type, $feature ) {
  1824 function post_type_supports( $post_type, $feature ) {
  1635 	global $_wp_post_type_features;
  1825 	global $_wp_post_type_features;
  1636 
  1826 
  1637 	return ( isset( $_wp_post_type_features[$post_type][$feature] ) );
  1827 	return ( isset( $_wp_post_type_features[ $post_type ][ $feature ] ) );
  1638 }
  1828 }
  1639 
  1829 
  1640 /**
  1830 /**
  1641  * Retrieves a list of post type names that support a specific feature.
  1831  * Retrieves a list of post type names that support a specific feature.
  1642  *
  1832  *
  1674  * @return int|false Amount of rows changed. Should be 1 for success and 0 for failure.
  1864  * @return int|false Amount of rows changed. Should be 1 for success and 0 for failure.
  1675  */
  1865  */
  1676 function set_post_type( $post_id = 0, $post_type = 'post' ) {
  1866 function set_post_type( $post_id = 0, $post_type = 'post' ) {
  1677 	global $wpdb;
  1867 	global $wpdb;
  1678 
  1868 
  1679 	$post_type = sanitize_post_field('post_type', $post_type, $post_id, 'db');
  1869 	$post_type = sanitize_post_field( 'post_type', $post_type, $post_id, 'db' );
  1680 	$return = $wpdb->update( $wpdb->posts, array('post_type' => $post_type), array('ID' => $post_id) );
  1870 	$return    = $wpdb->update( $wpdb->posts, array( 'post_type' => $post_type ), array( 'ID' => $post_id ) );
  1681 
  1871 
  1682 	clean_post_cache( $post_id );
  1872 	clean_post_cache( $post_id );
  1683 
  1873 
  1684 	return $return;
  1874 	return $return;
  1685 }
  1875 }
  1690  * For built-in post types such as posts and pages, the 'public' value will be evaluated.
  1880  * For built-in post types such as posts and pages, the 'public' value will be evaluated.
  1691  * For all others, the 'publicly_queryable' value will be used.
  1881  * For all others, the 'publicly_queryable' value will be used.
  1692  *
  1882  *
  1693  * @since 4.4.0
  1883  * @since 4.4.0
  1694  * @since 4.5.0 Added the ability to pass a post type name in addition to object.
  1884  * @since 4.5.0 Added the ability to pass a post type name in addition to object.
  1695  * @since 4.6.0 Converted the `$post_type` parameter to accept a WP_Post_Type object.
  1885  * @since 4.6.0 Converted the `$post_type` parameter to accept a `WP_Post_Type` object.
  1696  *
  1886  *
  1697  * @param string|WP_Post_Type $post_type Post type name or object.
  1887  * @param string|WP_Post_Type $post_type Post type name or object.
  1698  * @return bool Whether the post type should be considered viewable.
  1888  * @return bool Whether the post type should be considered viewable.
  1699  */
  1889  */
  1700 function is_post_type_viewable( $post_type ) {
  1890 function is_post_type_viewable( $post_type ) {
  1707 
  1897 
  1708 	return $post_type->publicly_queryable || ( $post_type->_builtin && $post_type->public );
  1898 	return $post_type->publicly_queryable || ( $post_type->_builtin && $post_type->public );
  1709 }
  1899 }
  1710 
  1900 
  1711 /**
  1901 /**
  1712  * Retrieve list of latest posts or posts matching criteria.
  1902  * Retrieves an array of the latest posts, or posts matching the given criteria.
  1713  *
  1903  *
  1714  * The defaults are as follows:
  1904  * The defaults are as follows:
  1715  *
  1905  *
  1716  * @since 1.2.0
  1906  * @since 1.2.0
  1717  *
  1907  *
  1728  *     @type array      $include          An array of post IDs to retrieve, sticky posts will be included.
  1918  *     @type array      $include          An array of post IDs to retrieve, sticky posts will be included.
  1729  *                                        Is an alias of $post__in in WP_Query. Default empty array.
  1919  *                                        Is an alias of $post__in in WP_Query. Default empty array.
  1730  *     @type array      $exclude          An array of post IDs not to retrieve. Default empty array.
  1920  *     @type array      $exclude          An array of post IDs not to retrieve. Default empty array.
  1731  *     @type bool       $suppress_filters Whether to suppress filters. Default true.
  1921  *     @type bool       $suppress_filters Whether to suppress filters. Default true.
  1732  * }
  1922  * }
  1733  * @return array List of posts.
  1923  * @return WP_Post[]|int[] Array of post objects or post IDs.
  1734  */
  1924  */
  1735 function get_posts( $args = null ) {
  1925 function get_posts( $args = null ) {
  1736 	$defaults = array(
  1926 	$defaults = array(
  1737 		'numberposts' => 5,
  1927 		'numberposts'      => 5,
  1738 		'category' => 0, 'orderby' => 'date',
  1928 		'category'         => 0,
  1739 		'order' => 'DESC', 'include' => array(),
  1929 		'orderby'          => 'date',
  1740 		'exclude' => array(), 'meta_key' => '',
  1930 		'order'            => 'DESC',
  1741 		'meta_value' =>'', 'post_type' => 'post',
  1931 		'include'          => array(),
  1742 		'suppress_filters' => true
  1932 		'exclude'          => array(),
       
  1933 		'meta_key'         => '',
       
  1934 		'meta_value'       => '',
       
  1935 		'post_type'        => 'post',
       
  1936 		'suppress_filters' => true,
  1743 	);
  1937 	);
  1744 
  1938 
  1745 	$r = wp_parse_args( $args, $defaults );
  1939 	$r = wp_parse_args( $args, $defaults );
  1746 	if ( empty( $r['post_status'] ) )
  1940 	if ( empty( $r['post_status'] ) ) {
  1747 		$r['post_status'] = ( 'attachment' == $r['post_type'] ) ? 'inherit' : 'publish';
  1941 		$r['post_status'] = ( 'attachment' == $r['post_type'] ) ? 'inherit' : 'publish';
  1748 	if ( ! empty($r['numberposts']) && empty($r['posts_per_page']) )
  1942 	}
       
  1943 	if ( ! empty( $r['numberposts'] ) && empty( $r['posts_per_page'] ) ) {
  1749 		$r['posts_per_page'] = $r['numberposts'];
  1944 		$r['posts_per_page'] = $r['numberposts'];
  1750 	if ( ! empty($r['category']) )
  1945 	}
       
  1946 	if ( ! empty( $r['category'] ) ) {
  1751 		$r['cat'] = $r['category'];
  1947 		$r['cat'] = $r['category'];
  1752 	if ( ! empty($r['include']) ) {
  1948 	}
  1753 		$incposts = wp_parse_id_list( $r['include'] );
  1949 	if ( ! empty( $r['include'] ) ) {
  1754 		$r['posts_per_page'] = count($incposts);  // only the number of posts included
  1950 		$incposts            = wp_parse_id_list( $r['include'] );
  1755 		$r['post__in'] = $incposts;
  1951 		$r['posts_per_page'] = count( $incposts );  // only the number of posts included
  1756 	} elseif ( ! empty($r['exclude']) )
  1952 		$r['post__in']       = $incposts;
       
  1953 	} elseif ( ! empty( $r['exclude'] ) ) {
  1757 		$r['post__not_in'] = wp_parse_id_list( $r['exclude'] );
  1954 		$r['post__not_in'] = wp_parse_id_list( $r['exclude'] );
       
  1955 	}
  1758 
  1956 
  1759 	$r['ignore_sticky_posts'] = true;
  1957 	$r['ignore_sticky_posts'] = true;
  1760 	$r['no_found_rows'] = true;
  1958 	$r['no_found_rows']       = true;
  1761 
  1959 
  1762 	$get_posts = new WP_Query;
  1960 	$get_posts = new WP_Query;
  1763 	return $get_posts->query($r);
  1961 	return $get_posts->query( $r );
  1764 
  1962 
  1765 }
  1963 }
  1766 
  1964 
  1767 //
  1965 //
  1768 // Post meta functions
  1966 // Post meta functions
  1769 //
  1967 //
  1770 
  1968 
  1771 /**
  1969 /**
  1772  * Add meta data field to a post.
  1970  * Adds a meta field to the given post.
  1773  *
  1971  *
  1774  * Post meta data is called "Custom Fields" on the Administration Screen.
  1972  * Post meta data is called "Custom Fields" on the Administration Screen.
  1775  *
  1973  *
  1776  * @since 1.5.0
  1974  * @since 1.5.0
  1777  *
  1975  *
  1782  *                           Default false.
  1980  *                           Default false.
  1783  * @return int|false Meta ID on success, false on failure.
  1981  * @return int|false Meta ID on success, false on failure.
  1784  */
  1982  */
  1785 function add_post_meta( $post_id, $meta_key, $meta_value, $unique = false ) {
  1983 function add_post_meta( $post_id, $meta_key, $meta_value, $unique = false ) {
  1786 	// Make sure meta is added to the post, not a revision.
  1984 	// Make sure meta is added to the post, not a revision.
  1787 	if ( $the_post = wp_is_post_revision($post_id) )
  1985 	$the_post = wp_is_post_revision( $post_id );
       
  1986 	if ( $the_post ) {
  1788 		$post_id = $the_post;
  1987 		$post_id = $the_post;
  1789 
  1988 	}
  1790 	$added = add_metadata( 'post', $post_id, $meta_key, $meta_value, $unique );
  1989 
  1791 	if ( $added ) {
  1990 	return add_metadata( 'post', $post_id, $meta_key, $meta_value, $unique );
  1792 		wp_cache_set( 'last_changed', microtime(), 'posts' );
  1991 }
  1793 	}
  1992 
  1794 	return $added;
  1993 /**
  1795 }
  1994  * Deletes a post meta field for the given post ID.
  1796 
       
  1797 /**
       
  1798  * Remove metadata matching criteria from a post.
       
  1799  *
  1995  *
  1800  * You can match based on the key, or key and value. Removing based on key and
  1996  * You can match based on the key, or key and value. Removing based on key and
  1801  * value, will keep from removing duplicate metadata with the same key. It also
  1997  * value, will keep from removing duplicate metadata with the same key. It also
  1802  * allows removing all metadata matching key, if needed.
  1998  * allows removing all metadata matching the key, if needed.
  1803  *
  1999  *
  1804  * @since 1.5.0
  2000  * @since 1.5.0
  1805  *
  2001  *
  1806  * @param int    $post_id    Post ID.
  2002  * @param int    $post_id    Post ID.
  1807  * @param string $meta_key   Metadata name.
  2003  * @param string $meta_key   Metadata name.
  1809  *                           non-scalar. Default empty.
  2005  *                           non-scalar. Default empty.
  1810  * @return bool True on success, false on failure.
  2006  * @return bool True on success, false on failure.
  1811  */
  2007  */
  1812 function delete_post_meta( $post_id, $meta_key, $meta_value = '' ) {
  2008 function delete_post_meta( $post_id, $meta_key, $meta_value = '' ) {
  1813 	// Make sure meta is added to the post, not a revision.
  2009 	// Make sure meta is added to the post, not a revision.
  1814 	if ( $the_post = wp_is_post_revision($post_id) )
  2010 	$the_post = wp_is_post_revision( $post_id );
       
  2011 	if ( $the_post ) {
  1815 		$post_id = $the_post;
  2012 		$post_id = $the_post;
  1816 
  2013 	}
  1817 	$deleted = delete_metadata( 'post', $post_id, $meta_key, $meta_value );
  2014 
  1818 	if ( $deleted ) {
  2015 	return delete_metadata( 'post', $post_id, $meta_key, $meta_value );
  1819 		wp_cache_set( 'last_changed', microtime(), 'posts' );
  2016 }
  1820 	}
  2017 
  1821 	return $deleted;
  2018 /**
  1822 }
  2019  * Retrieves a post meta field for the given post ID.
  1823 
       
  1824 /**
       
  1825  * Retrieve post meta field for a post.
       
  1826  *
  2020  *
  1827  * @since 1.5.0
  2021  * @since 1.5.0
  1828  *
  2022  *
  1829  * @param int    $post_id Post ID.
  2023  * @param int    $post_id Post ID.
  1830  * @param string $key     Optional. The meta key to retrieve. By default, returns
  2024  * @param string $key     Optional. The meta key to retrieve. By default, returns
  1831  *                        data for all keys. Default empty.
  2025  *                        data for all keys. Default empty.
  1832  * @param bool   $single  Optional. Whether to return a single value. Default false.
  2026  * @param bool   $single  Optional. If true, returns only the first value for the specified meta key.
  1833  * @return mixed Will be an array if $single is false. Will be value of meta data
  2027  *                        This parameter has no effect if $key is not specified. Default false.
       
  2028  * @return mixed Will be an array if $single is false. Will be value of the meta
  1834  *               field if $single is true.
  2029  *               field if $single is true.
  1835  */
  2030  */
  1836 function get_post_meta( $post_id, $key = '', $single = false ) {
  2031 function get_post_meta( $post_id, $key = '', $single = false ) {
  1837 	return get_metadata('post', $post_id, $key, $single);
  2032 	return get_metadata( 'post', $post_id, $key, $single );
  1838 }
  2033 }
  1839 
  2034 
  1840 /**
  2035 /**
  1841  * Update post meta field based on post ID.
  2036  * Updates a post meta field based on the given post ID.
  1842  *
  2037  *
  1843  * Use the $prev_value parameter to differentiate between meta fields with the
  2038  * Use the `$prev_value` parameter to differentiate between meta fields with the
  1844  * same key and post ID.
  2039  * same key and post ID.
  1845  *
  2040  *
  1846  * If the meta field for the post does not exist, it will be added.
  2041  * If the meta field for the post does not exist, it will be added and its ID returned.
       
  2042  *
       
  2043  * Can be used in place of add_post_meta().
  1847  *
  2044  *
  1848  * @since 1.5.0
  2045  * @since 1.5.0
  1849  *
  2046  *
  1850  * @param int    $post_id    Post ID.
  2047  * @param int    $post_id    Post ID.
  1851  * @param string $meta_key   Metadata key.
  2048  * @param string $meta_key   Metadata key.
  1852  * @param mixed  $meta_value Metadata value. Must be serializable if non-scalar.
  2049  * @param mixed  $meta_value Metadata value. Must be serializable if non-scalar.
  1853  * @param mixed  $prev_value Optional. Previous value to check before removing.
  2050  * @param mixed  $prev_value Optional. Previous value to check before updating.
  1854  *                           Default empty.
  2051  * @return int|bool The new meta field ID if a field with the given key didn't exist and was
  1855  * @return int|bool Meta ID if the key didn't exist, true on successful update,
  2052  *                  therefore added, true on successful update, false on failure.
  1856  *                  false on failure.
       
  1857  */
  2053  */
  1858 function update_post_meta( $post_id, $meta_key, $meta_value, $prev_value = '' ) {
  2054 function update_post_meta( $post_id, $meta_key, $meta_value, $prev_value = '' ) {
  1859 	// Make sure meta is added to the post, not a revision.
  2055 	// Make sure meta is added to the post, not a revision.
  1860 	if ( $the_post = wp_is_post_revision($post_id) )
  2056 	$the_post = wp_is_post_revision( $post_id );
       
  2057 	if ( $the_post ) {
  1861 		$post_id = $the_post;
  2058 		$post_id = $the_post;
  1862 
  2059 	}
  1863 	$updated = update_metadata( 'post', $post_id, $meta_key, $meta_value, $prev_value );
  2060 
  1864 	if ( $updated ) {
  2061 	return update_metadata( 'post', $post_id, $meta_key, $meta_value, $prev_value );
  1865 		wp_cache_set( 'last_changed', microtime(), 'posts' );
  2062 }
  1866 	}
  2063 
  1867 	return $updated;
  2064 /**
  1868 }
  2065  * Deletes everything from post meta matching the given meta key.
  1869 
       
  1870 /**
       
  1871  * Delete everything from post meta matching meta key.
       
  1872  *
  2066  *
  1873  * @since 2.3.0
  2067  * @since 2.3.0
  1874  *
  2068  *
  1875  * @param string $post_meta_key Key to search for when deleting.
  2069  * @param string $post_meta_key Key to search for when deleting.
  1876  * @return bool Whether the post meta key was deleted from the database.
  2070  * @return bool Whether the post meta key was deleted from the database.
  1877  */
  2071  */
  1878 function delete_post_meta_by_key( $post_meta_key ) {
  2072 function delete_post_meta_by_key( $post_meta_key ) {
  1879 	$deleted = delete_metadata( 'post', null, $post_meta_key, '', true );
  2073 	return delete_metadata( 'post', null, $post_meta_key, '', true );
  1880 	if ( $deleted ) {
       
  1881 		wp_cache_set( 'last_changed', microtime(), 'posts' );
       
  1882 	}
       
  1883 	return $deleted;
       
  1884 }
  2074 }
  1885 
  2075 
  1886 /**
  2076 /**
  1887  * Registers a meta key for posts.
  2077  * Registers a meta key for posts.
  1888  *
  2078  *
  1927  * @param int $post_id Optional. Post ID. Default is ID of the global $post.
  2117  * @param int $post_id Optional. Post ID. Default is ID of the global $post.
  1928  * @return array Post meta for the given post.
  2118  * @return array Post meta for the given post.
  1929  */
  2119  */
  1930 function get_post_custom( $post_id = 0 ) {
  2120 function get_post_custom( $post_id = 0 ) {
  1931 	$post_id = absint( $post_id );
  2121 	$post_id = absint( $post_id );
  1932 	if ( ! $post_id )
  2122 	if ( ! $post_id ) {
  1933 		$post_id = get_the_ID();
  2123 		$post_id = get_the_ID();
       
  2124 	}
  1934 
  2125 
  1935 	return get_post_meta( $post_id );
  2126 	return get_post_meta( $post_id );
  1936 }
  2127 }
  1937 
  2128 
  1938 /**
  2129 /**
  1946  * @return array|void Array of the keys, if retrieved.
  2137  * @return array|void Array of the keys, if retrieved.
  1947  */
  2138  */
  1948 function get_post_custom_keys( $post_id = 0 ) {
  2139 function get_post_custom_keys( $post_id = 0 ) {
  1949 	$custom = get_post_custom( $post_id );
  2140 	$custom = get_post_custom( $post_id );
  1950 
  2141 
  1951 	if ( !is_array($custom) )
  2142 	if ( ! is_array( $custom ) ) {
  1952 		return;
  2143 		return;
  1953 
  2144 	}
  1954 	if ( $keys = array_keys($custom) )
  2145 
       
  2146 	if ( $keys = array_keys( $custom ) ) {
  1955 		return $keys;
  2147 		return $keys;
       
  2148 	}
  1956 }
  2149 }
  1957 
  2150 
  1958 /**
  2151 /**
  1959  * Retrieve values for a custom post field.
  2152  * Retrieve values for a custom post field.
  1960  *
  2153  *
  1966  * @param string $key     Optional. Meta field key. Default empty.
  2159  * @param string $key     Optional. Meta field key. Default empty.
  1967  * @param int    $post_id Optional. Post ID. Default is ID of the global $post.
  2160  * @param int    $post_id Optional. Post ID. Default is ID of the global $post.
  1968  * @return array|null Meta field values.
  2161  * @return array|null Meta field values.
  1969  */
  2162  */
  1970 function get_post_custom_values( $key = '', $post_id = 0 ) {
  2163 function get_post_custom_values( $key = '', $post_id = 0 ) {
  1971 	if ( !$key )
  2164 	if ( ! $key ) {
  1972 		return null;
  2165 		return null;
  1973 
  2166 	}
  1974 	$custom = get_post_custom($post_id);
  2167 
  1975 
  2168 	$custom = get_post_custom( $post_id );
  1976 	return isset($custom[$key]) ? $custom[$key] : null;
  2169 
  1977 }
  2170 	return isset( $custom[ $key ] ) ? $custom[ $key ] : null;
  1978 
  2171 }
  1979 /**
  2172 
  1980  * Check if post is sticky.
  2173 /**
       
  2174  * Determines whether a post is sticky.
  1981  *
  2175  *
  1982  * Sticky posts should remain at the top of The Loop. If the post ID is not
  2176  * Sticky posts should remain at the top of The Loop. If the post ID is not
  1983  * given, then The Loop ID for the current post will be used.
  2177  * given, then The Loop ID for the current post will be used.
  1984  *
  2178  *
       
  2179  * For more information on this and similar theme functions, check out
       
  2180  * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
       
  2181  * Conditional Tags} article in the Theme Developer Handbook.
       
  2182  *
  1985  * @since 2.7.0
  2183  * @since 2.7.0
  1986  *
  2184  *
  1987  * @param int $post_id Optional. Post ID. Default is ID of the global $post.
  2185  * @param int $post_id Optional. Post ID. Default is ID of the global $post.
  1988  * @return bool Whether post is sticky.
  2186  * @return bool Whether post is sticky.
  1989  */
  2187  */
  1990 function is_sticky( $post_id = 0 ) {
  2188 function is_sticky( $post_id = 0 ) {
  1991 	$post_id = absint( $post_id );
  2189 	$post_id = absint( $post_id );
  1992 
  2190 
  1993 	if ( ! $post_id )
  2191 	if ( ! $post_id ) {
  1994 		$post_id = get_the_ID();
  2192 		$post_id = get_the_ID();
       
  2193 	}
  1995 
  2194 
  1996 	$stickies = get_option( 'sticky_posts' );
  2195 	$stickies = get_option( 'sticky_posts' );
  1997 
  2196 
  1998 	if ( ! is_array( $stickies ) )
  2197 	if ( ! is_array( $stickies ) ) {
  1999 		return false;
  2198 		return false;
  2000 
  2199 	}
  2001 	if ( in_array( $post_id, $stickies ) )
  2200 
       
  2201 	if ( in_array( $post_id, $stickies ) ) {
  2002 		return true;
  2202 		return true;
       
  2203 	}
  2003 
  2204 
  2004 	return false;
  2205 	return false;
  2005 }
  2206 }
  2006 
  2207 
  2007 /**
  2208 /**
  2020  *                                      Default 'display'.
  2221  *                                      Default 'display'.
  2021  * @return object|WP_Post|array The now sanitized Post Object or Array (will be the
  2222  * @return object|WP_Post|array The now sanitized Post Object or Array (will be the
  2022  *                              same type as $post).
  2223  *                              same type as $post).
  2023  */
  2224  */
  2024 function sanitize_post( $post, $context = 'display' ) {
  2225 function sanitize_post( $post, $context = 'display' ) {
  2025 	if ( is_object($post) ) {
  2226 	if ( is_object( $post ) ) {
  2026 		// Check if post already filtered for this context.
  2227 		// Check if post already filtered for this context.
  2027 		if ( isset($post->filter) && $context == $post->filter )
  2228 		if ( isset( $post->filter ) && $context == $post->filter ) {
  2028 			return $post;
  2229 			return $post;
  2029 		if ( !isset($post->ID) )
  2230 		}
       
  2231 		if ( ! isset( $post->ID ) ) {
  2030 			$post->ID = 0;
  2232 			$post->ID = 0;
  2031 		foreach ( array_keys(get_object_vars($post)) as $field )
  2233 		}
  2032 			$post->$field = sanitize_post_field($field, $post->$field, $post->ID, $context);
  2234 		foreach ( array_keys( get_object_vars( $post ) ) as $field ) {
       
  2235 			$post->$field = sanitize_post_field( $field, $post->$field, $post->ID, $context );
       
  2236 		}
  2033 		$post->filter = $context;
  2237 		$post->filter = $context;
  2034 	} elseif ( is_array( $post ) ) {
  2238 	} elseif ( is_array( $post ) ) {
  2035 		// Check if post already filtered for this context.
  2239 		// Check if post already filtered for this context.
  2036 		if ( isset($post['filter']) && $context == $post['filter'] )
  2240 		if ( isset( $post['filter'] ) && $context == $post['filter'] ) {
  2037 			return $post;
  2241 			return $post;
  2038 		if ( !isset($post['ID']) )
  2242 		}
       
  2243 		if ( ! isset( $post['ID'] ) ) {
  2039 			$post['ID'] = 0;
  2244 			$post['ID'] = 0;
  2040 		foreach ( array_keys($post) as $field )
  2245 		}
  2041 			$post[$field] = sanitize_post_field($field, $post[$field], $post['ID'], $context);
  2246 		foreach ( array_keys( $post ) as $field ) {
       
  2247 			$post[ $field ] = sanitize_post_field( $field, $post[ $field ], $post['ID'], $context );
       
  2248 		}
  2042 		$post['filter'] = $context;
  2249 		$post['filter'] = $context;
  2043 	}
  2250 	}
  2044 	return $post;
  2251 	return $post;
  2045 }
  2252 }
  2046 
  2253 
  2060  * @param string $context Optional. How to sanitize post fields. Looks for 'raw', 'edit',
  2267  * @param string $context Optional. How to sanitize post fields. Looks for 'raw', 'edit',
  2061  *                        'db', 'display', 'attribute' and 'js'. Default 'display'.
  2268  *                        'db', 'display', 'attribute' and 'js'. Default 'display'.
  2062  * @return mixed Sanitized value.
  2269  * @return mixed Sanitized value.
  2063  */
  2270  */
  2064 function sanitize_post_field( $field, $value, $post_id, $context = 'display' ) {
  2271 function sanitize_post_field( $field, $value, $post_id, $context = 'display' ) {
  2065 	$int_fields = array('ID', 'post_parent', 'menu_order');
  2272 	$int_fields = array( 'ID', 'post_parent', 'menu_order' );
  2066 	if ( in_array($field, $int_fields) )
  2273 	if ( in_array( $field, $int_fields ) ) {
  2067 		$value = (int) $value;
  2274 		$value = (int) $value;
       
  2275 	}
  2068 
  2276 
  2069 	// Fields which contain arrays of integers.
  2277 	// Fields which contain arrays of integers.
  2070 	$array_int_fields = array( 'ancestors' );
  2278 	$array_int_fields = array( 'ancestors' );
  2071 	if ( in_array($field, $array_int_fields) ) {
  2279 	if ( in_array( $field, $array_int_fields ) ) {
  2072 		$value = array_map( 'absint', $value);
  2280 		$value = array_map( 'absint', $value );
  2073 		return $value;
  2281 		return $value;
  2074 	}
  2282 	}
  2075 
  2283 
  2076 	if ( 'raw' == $context )
  2284 	if ( 'raw' == $context ) {
  2077 		return $value;
  2285 		return $value;
       
  2286 	}
  2078 
  2287 
  2079 	$prefixed = false;
  2288 	$prefixed = false;
  2080 	if ( false !== strpos($field, 'post_') ) {
  2289 	if ( false !== strpos( $field, 'post_' ) ) {
  2081 		$prefixed = true;
  2290 		$prefixed        = true;
  2082 		$field_no_prefix = str_replace('post_', '', $field);
  2291 		$field_no_prefix = str_replace( 'post_', '', $field );
  2083 	}
  2292 	}
  2084 
  2293 
  2085 	if ( 'edit' == $context ) {
  2294 	if ( 'edit' == $context ) {
  2086 		$format_to_edit = array('post_content', 'post_excerpt', 'post_title', 'post_password');
  2295 		$format_to_edit = array( 'post_content', 'post_excerpt', 'post_title', 'post_password' );
  2087 
  2296 
  2088 		if ( $prefixed ) {
  2297 		if ( $prefixed ) {
  2089 
  2298 
  2090 			/**
  2299 			/**
  2091 			 * Filters the value of a specific post field to edit.
  2300 			 * Filters the value of a specific post field to edit.
  2114 			$value = apply_filters( "{$field_no_prefix}_edit_pre", $value, $post_id );
  2323 			$value = apply_filters( "{$field_no_prefix}_edit_pre", $value, $post_id );
  2115 		} else {
  2324 		} else {
  2116 			$value = apply_filters( "edit_post_{$field}", $value, $post_id );
  2325 			$value = apply_filters( "edit_post_{$field}", $value, $post_id );
  2117 		}
  2326 		}
  2118 
  2327 
  2119 		if ( in_array($field, $format_to_edit) ) {
  2328 		if ( in_array( $field, $format_to_edit ) ) {
  2120 			if ( 'post_content' == $field )
  2329 			if ( 'post_content' == $field ) {
  2121 				$value = format_to_edit($value, user_can_richedit());
  2330 				$value = format_to_edit( $value, user_can_richedit() );
  2122 			else
  2331 			} else {
  2123 				$value = format_to_edit($value);
  2332 				$value = format_to_edit( $value );
       
  2333 			}
  2124 		} else {
  2334 		} else {
  2125 			$value = esc_attr($value);
  2335 			$value = esc_attr( $value );
  2126 		}
  2336 		}
  2127 	} elseif ( 'db' == $context ) {
  2337 	} elseif ( 'db' == $context ) {
  2128 		if ( $prefixed ) {
  2338 		if ( $prefixed ) {
  2129 
  2339 
  2130 			/**
  2340 			/**
  2207  * @since 2.7.0
  2417  * @since 2.7.0
  2208  *
  2418  *
  2209  * @param int $post_id Post ID.
  2419  * @param int $post_id Post ID.
  2210  */
  2420  */
  2211 function stick_post( $post_id ) {
  2421 function stick_post( $post_id ) {
  2212 	$stickies = get_option('sticky_posts');
  2422 	$stickies = get_option( 'sticky_posts' );
  2213 
  2423 
  2214 	if ( !is_array($stickies) )
  2424 	if ( ! is_array( $stickies ) ) {
  2215 		$stickies = array($post_id);
  2425 		$stickies = array( $post_id );
  2216 
  2426 	}
  2217 	if ( ! in_array($post_id, $stickies) )
  2427 
       
  2428 	if ( ! in_array( $post_id, $stickies ) ) {
  2218 		$stickies[] = $post_id;
  2429 		$stickies[] = $post_id;
       
  2430 	}
  2219 
  2431 
  2220 	$updated = update_option( 'sticky_posts', $stickies );
  2432 	$updated = update_option( 'sticky_posts', $stickies );
  2221 
  2433 
  2222 	if ( $updated ) {
  2434 	if ( $updated ) {
  2223 		/**
  2435 		/**
  2239  * @since 2.7.0
  2451  * @since 2.7.0
  2240  *
  2452  *
  2241  * @param int $post_id Post ID.
  2453  * @param int $post_id Post ID.
  2242  */
  2454  */
  2243 function unstick_post( $post_id ) {
  2455 function unstick_post( $post_id ) {
  2244 	$stickies = get_option('sticky_posts');
  2456 	$stickies = get_option( 'sticky_posts' );
  2245 
  2457 
  2246 	if ( !is_array($stickies) )
  2458 	if ( ! is_array( $stickies ) ) {
  2247 		return;
  2459 		return;
  2248 
  2460 	}
  2249 	if ( ! in_array($post_id, $stickies) )
  2461 
       
  2462 	if ( ! in_array( $post_id, $stickies ) ) {
  2250 		return;
  2463 		return;
  2251 
  2464 	}
  2252 	$offset = array_search($post_id, $stickies);
  2465 
  2253 	if ( false === $offset )
  2466 	$offset = array_search( $post_id, $stickies );
       
  2467 	if ( false === $offset ) {
  2254 		return;
  2468 		return;
  2255 
  2469 	}
  2256 	array_splice($stickies, $offset, 1);
  2470 
       
  2471 	array_splice( $stickies, $offset, 1 );
  2257 
  2472 
  2258 	$updated = update_option( 'sticky_posts', $stickies );
  2473 	$updated = update_option( 'sticky_posts', $stickies );
  2259 
  2474 
  2260 	if ( $updated ) {
  2475 	if ( $updated ) {
  2261 		/**
  2476 		/**
  2271 
  2486 
  2272 /**
  2487 /**
  2273  * Return the cache key for wp_count_posts() based on the passed arguments.
  2488  * Return the cache key for wp_count_posts() based on the passed arguments.
  2274  *
  2489  *
  2275  * @since 3.9.0
  2490  * @since 3.9.0
       
  2491  * @access private
  2276  *
  2492  *
  2277  * @param string $type Optional. Post type to retrieve count Default 'post'.
  2493  * @param string $type Optional. Post type to retrieve count Default 'post'.
  2278  * @param string $perm Optional. 'readable' or empty. Default empty.
  2494  * @param string $perm Optional. 'readable' or empty. Default empty.
  2279  * @return string The cache key.
  2495  * @return string The cache key.
  2280  */
  2496  */
  2309  * @return object Number of posts for each status.
  2525  * @return object Number of posts for each status.
  2310  */
  2526  */
  2311 function wp_count_posts( $type = 'post', $perm = '' ) {
  2527 function wp_count_posts( $type = 'post', $perm = '' ) {
  2312 	global $wpdb;
  2528 	global $wpdb;
  2313 
  2529 
  2314 	if ( ! post_type_exists( $type ) )
  2530 	if ( ! post_type_exists( $type ) ) {
  2315 		return new stdClass;
  2531 		return new stdClass;
       
  2532 	}
  2316 
  2533 
  2317 	$cache_key = _count_posts_cache_key( $type, $perm );
  2534 	$cache_key = _count_posts_cache_key( $type, $perm );
  2318 
  2535 
  2319 	$counts = wp_cache_get( $cache_key, 'counts' );
  2536 	$counts = wp_cache_get( $cache_key, 'counts' );
  2320 	if ( false !== $counts ) {
  2537 	if ( false !== $counts ) {
  2322 		return apply_filters( 'wp_count_posts', $counts, $type, $perm );
  2539 		return apply_filters( 'wp_count_posts', $counts, $type, $perm );
  2323 	}
  2540 	}
  2324 
  2541 
  2325 	$query = "SELECT post_status, COUNT( * ) AS num_posts FROM {$wpdb->posts} WHERE post_type = %s";
  2542 	$query = "SELECT post_status, COUNT( * ) AS num_posts FROM {$wpdb->posts} WHERE post_type = %s";
  2326 	if ( 'readable' == $perm && is_user_logged_in() ) {
  2543 	if ( 'readable' == $perm && is_user_logged_in() ) {
  2327 		$post_type_object = get_post_type_object($type);
  2544 		$post_type_object = get_post_type_object( $type );
  2328 		if ( ! current_user_can( $post_type_object->cap->read_private_posts ) ) {
  2545 		if ( ! current_user_can( $post_type_object->cap->read_private_posts ) ) {
  2329 			$query .= $wpdb->prepare( " AND (post_status != 'private' OR ( post_author = %d AND post_status = 'private' ))",
  2546 			$query .= $wpdb->prepare(
       
  2547 				" AND (post_status != 'private' OR ( post_author = %d AND post_status = 'private' ))",
  2330 				get_current_user_id()
  2548 				get_current_user_id()
  2331 			);
  2549 			);
  2332 		}
  2550 		}
  2333 	}
  2551 	}
  2334 	$query .= ' GROUP BY post_status';
  2552 	$query .= ' GROUP BY post_status';
  2335 
  2553 
  2336 	$results = (array) $wpdb->get_results( $wpdb->prepare( $query, $type ), ARRAY_A );
  2554 	$results = (array) $wpdb->get_results( $wpdb->prepare( $query, $type ), ARRAY_A );
  2337 	$counts = array_fill_keys( get_post_stati(), 0 );
  2555 	$counts  = array_fill_keys( get_post_stati(), 0 );
  2338 
  2556 
  2339 	foreach ( $results as $row ) {
  2557 	foreach ( $results as $row ) {
  2340 		$counts[ $row['post_status'] ] = $row['num_posts'];
  2558 		$counts[ $row['post_status'] ] = $row['num_posts'];
  2341 	}
  2559 	}
  2342 
  2560 
  2374  * @return object An object containing the attachment counts by mime type.
  2592  * @return object An object containing the attachment counts by mime type.
  2375  */
  2593  */
  2376 function wp_count_attachments( $mime_type = '' ) {
  2594 function wp_count_attachments( $mime_type = '' ) {
  2377 	global $wpdb;
  2595 	global $wpdb;
  2378 
  2596 
  2379 	$and = wp_post_mime_type_where( $mime_type );
  2597 	$and   = wp_post_mime_type_where( $mime_type );
  2380 	$count = $wpdb->get_results( "SELECT post_mime_type, COUNT( * ) AS num_posts FROM $wpdb->posts WHERE post_type = 'attachment' AND post_status != 'trash' $and GROUP BY post_mime_type", ARRAY_A );
  2598 	$count = $wpdb->get_results( "SELECT post_mime_type, COUNT( * ) AS num_posts FROM $wpdb->posts WHERE post_type = 'attachment' AND post_status != 'trash' $and GROUP BY post_mime_type", ARRAY_A );
  2381 
  2599 
  2382 	$counts = array();
  2600 	$counts = array();
  2383 	foreach ( (array) $count as $row ) {
  2601 	foreach ( (array) $count as $row ) {
  2384 		$counts[ $row['post_mime_type'] ] = $row['num_posts'];
  2602 		$counts[ $row['post_mime_type'] ] = $row['num_posts'];
  2385 	}
  2603 	}
  2386 	$counts['trash'] = $wpdb->get_var( "SELECT COUNT( * ) FROM $wpdb->posts WHERE post_type = 'attachment' AND post_status = 'trash' $and");
  2604 	$counts['trash'] = $wpdb->get_var( "SELECT COUNT( * ) FROM $wpdb->posts WHERE post_type = 'attachment' AND post_status = 'trash' $and" );
  2387 
  2605 
  2388 	/**
  2606 	/**
  2389 	 * Modify returned attachment counts by mime type.
  2607 	 * Modify returned attachment counts by mime type.
  2390 	 *
  2608 	 *
  2391 	 * @since 3.7.0
  2609 	 * @since 3.7.0
  2404  * @since 2.9.0
  2622  * @since 2.9.0
  2405  *
  2623  *
  2406  * @return array List of post mime types.
  2624  * @return array List of post mime types.
  2407  */
  2625  */
  2408 function get_post_mime_types() {
  2626 function get_post_mime_types() {
  2409 	$post_mime_types = array(	//	array( adj, noun )
  2627 	$post_mime_types = array(   //	array( adj, noun )
  2410 		'image' => array(__('Images'), __('Manage Images'), _n_noop('Image <span class="count">(%s)</span>', 'Images <span class="count">(%s)</span>')),
  2628 		'image' => array( __( 'Images' ), __( 'Manage Images' ), _n_noop( 'Image <span class="count">(%s)</span>', 'Images <span class="count">(%s)</span>' ) ),
  2411 		'audio' => array(__('Audio'), __('Manage Audio'), _n_noop('Audio <span class="count">(%s)</span>', 'Audio <span class="count">(%s)</span>')),
  2629 		'audio' => array( __( 'Audio' ), __( 'Manage Audio' ), _n_noop( 'Audio <span class="count">(%s)</span>', 'Audio <span class="count">(%s)</span>' ) ),
  2412 		'video' => array(__('Video'), __('Manage Video'), _n_noop('Video <span class="count">(%s)</span>', 'Video <span class="count">(%s)</span>')),
  2630 		'video' => array( __( 'Video' ), __( 'Manage Video' ), _n_noop( 'Video <span class="count">(%s)</span>', 'Video <span class="count">(%s)</span>' ) ),
  2413 	);
  2631 	);
  2414 
  2632 
  2415 	/**
  2633 	/**
  2416 	 * Filters the default list of post mime types.
  2634 	 * Filters the default list of post mime types.
  2417 	 *
  2635 	 *
  2444 	if ( is_string( $real_mime_types ) ) {
  2662 	if ( is_string( $real_mime_types ) ) {
  2445 		$real_mime_types = array_map( 'trim', explode( ',', $real_mime_types ) );
  2663 		$real_mime_types = array_map( 'trim', explode( ',', $real_mime_types ) );
  2446 	}
  2664 	}
  2447 
  2665 
  2448 	$patternses = array();
  2666 	$patternses = array();
  2449 	$wild = '[-._a-z0-9]*';
  2667 	$wild       = '[-._a-z0-9]*';
  2450 
  2668 
  2451 	foreach ( (array) $wildcard_mime_types as $type ) {
  2669 	foreach ( (array) $wildcard_mime_types as $type ) {
  2452 		$mimes = array_map( 'trim', explode( ',', $type ) );
  2670 		$mimes = array_map( 'trim', explode( ',', $type ) );
  2453 		foreach ( $mimes as $mime ) {
  2671 		foreach ( $mimes as $mime ) {
  2454 			$regex = str_replace( '__wildcard__', $wild, preg_quote( str_replace( '*', '__wildcard__', $mime ) ) );
  2672 			$regex                 = str_replace( '__wildcard__', $wild, preg_quote( str_replace( '*', '__wildcard__', $mime ) ) );
  2455 			$patternses[][$type] = "^$regex$";
  2673 			$patternses[][ $type ] = "^$regex$";
  2456 			if ( false === strpos( $mime, '/' ) ) {
  2674 			if ( false === strpos( $mime, '/' ) ) {
  2457 				$patternses[][$type] = "^$regex/";
  2675 				$patternses[][ $type ] = "^$regex/";
  2458 				$patternses[][$type] = $regex;
  2676 				$patternses[][ $type ] = $regex;
  2459 			}
  2677 			}
  2460 		}
  2678 		}
  2461 	}
  2679 	}
  2462 	asort( $patternses );
  2680 	asort( $patternses );
  2463 
  2681 
  2464 	foreach ( $patternses as $patterns ) {
  2682 	foreach ( $patternses as $patterns ) {
  2465 		foreach ( $patterns as $type => $pattern ) {
  2683 		foreach ( $patterns as $type => $pattern ) {
  2466 			foreach ( (array) $real_mime_types as $real ) {
  2684 			foreach ( (array) $real_mime_types as $real ) {
  2467 				if ( preg_match( "#$pattern#", $real ) && ( empty( $matches[$type] ) || false === array_search( $real, $matches[$type] ) ) ) {
  2685 				if ( preg_match( "#$pattern#", $real ) && ( empty( $matches[ $type ] ) || false === array_search( $real, $matches[ $type ] ) ) ) {
  2468 					$matches[$type][] = $real;
  2686 					$matches[ $type ][] = $real;
  2469 				}
  2687 				}
  2470 			}
  2688 			}
  2471 		}
  2689 		}
  2472 	}
  2690 	}
  2473 	return $matches;
  2691 	return $matches;
  2483  * @param string       $table_alias     Optional. Specify a table alias, if needed.
  2701  * @param string       $table_alias     Optional. Specify a table alias, if needed.
  2484  *                                      Default empty.
  2702  *                                      Default empty.
  2485  * @return string The SQL AND clause for mime searching.
  2703  * @return string The SQL AND clause for mime searching.
  2486  */
  2704  */
  2487 function wp_post_mime_type_where( $post_mime_types, $table_alias = '' ) {
  2705 function wp_post_mime_type_where( $post_mime_types, $table_alias = '' ) {
  2488 	$where = '';
  2706 	$where     = '';
  2489 	$wildcards = array('', '%', '%/%');
  2707 	$wildcards = array( '', '%', '%/%' );
  2490 	if ( is_string($post_mime_types) )
  2708 	if ( is_string( $post_mime_types ) ) {
  2491 		$post_mime_types = array_map('trim', explode(',', $post_mime_types));
  2709 		$post_mime_types = array_map( 'trim', explode( ',', $post_mime_types ) );
       
  2710 	}
  2492 
  2711 
  2493 	$wheres = array();
  2712 	$wheres = array();
  2494 
  2713 
  2495 	foreach ( (array) $post_mime_types as $mime_type ) {
  2714 	foreach ( (array) $post_mime_types as $mime_type ) {
  2496 		$mime_type = preg_replace('/\s/', '', $mime_type);
  2715 		$mime_type = preg_replace( '/\s/', '', $mime_type );
  2497 		$slashpos = strpos($mime_type, '/');
  2716 		$slashpos  = strpos( $mime_type, '/' );
  2498 		if ( false !== $slashpos ) {
  2717 		if ( false !== $slashpos ) {
  2499 			$mime_group = preg_replace('/[^-*.a-zA-Z0-9]/', '', substr($mime_type, 0, $slashpos));
  2718 			$mime_group    = preg_replace( '/[^-*.a-zA-Z0-9]/', '', substr( $mime_type, 0, $slashpos ) );
  2500 			$mime_subgroup = preg_replace('/[^-*.+a-zA-Z0-9]/', '', substr($mime_type, $slashpos + 1));
  2719 			$mime_subgroup = preg_replace( '/[^-*.+a-zA-Z0-9]/', '', substr( $mime_type, $slashpos + 1 ) );
  2501 			if ( empty($mime_subgroup) )
  2720 			if ( empty( $mime_subgroup ) ) {
  2502 				$mime_subgroup = '*';
  2721 				$mime_subgroup = '*';
  2503 			else
  2722 			} else {
  2504 				$mime_subgroup = str_replace('/', '', $mime_subgroup);
  2723 				$mime_subgroup = str_replace( '/', '', $mime_subgroup );
       
  2724 			}
  2505 			$mime_pattern = "$mime_group/$mime_subgroup";
  2725 			$mime_pattern = "$mime_group/$mime_subgroup";
  2506 		} else {
  2726 		} else {
  2507 			$mime_pattern = preg_replace('/[^-*.a-zA-Z0-9]/', '', $mime_type);
  2727 			$mime_pattern = preg_replace( '/[^-*.a-zA-Z0-9]/', '', $mime_type );
  2508 			if ( false === strpos($mime_pattern, '*') )
  2728 			if ( false === strpos( $mime_pattern, '*' ) ) {
  2509 				$mime_pattern .= '/*';
  2729 				$mime_pattern .= '/*';
  2510 		}
  2730 			}
  2511 
  2731 		}
  2512 		$mime_pattern = preg_replace('/\*+/', '%', $mime_pattern);
  2732 
  2513 
  2733 		$mime_pattern = preg_replace( '/\*+/', '%', $mime_pattern );
  2514 		if ( in_array( $mime_type, $wildcards ) )
  2734 
       
  2735 		if ( in_array( $mime_type, $wildcards ) ) {
  2515 			return '';
  2736 			return '';
  2516 
  2737 		}
  2517 		if ( false !== strpos($mime_pattern, '%') )
  2738 
  2518 			$wheres[] = empty($table_alias) ? "post_mime_type LIKE '$mime_pattern'" : "$table_alias.post_mime_type LIKE '$mime_pattern'";
  2739 		if ( false !== strpos( $mime_pattern, '%' ) ) {
  2519 		else
  2740 			$wheres[] = empty( $table_alias ) ? "post_mime_type LIKE '$mime_pattern'" : "$table_alias.post_mime_type LIKE '$mime_pattern'";
  2520 			$wheres[] = empty($table_alias) ? "post_mime_type = '$mime_pattern'" : "$table_alias.post_mime_type = '$mime_pattern'";
  2741 		} else {
  2521 	}
  2742 			$wheres[] = empty( $table_alias ) ? "post_mime_type = '$mime_pattern'" : "$table_alias.post_mime_type = '$mime_pattern'";
  2522 	if ( !empty($wheres) )
  2743 		}
  2523 		$where = ' AND (' . join(' OR ', $wheres) . ') ';
  2744 	}
       
  2745 	if ( ! empty( $wheres ) ) {
       
  2746 		$where = ' AND (' . join( ' OR ', $wheres ) . ') ';
       
  2747 	}
  2524 	return $where;
  2748 	return $where;
  2525 }
  2749 }
  2526 
  2750 
  2527 /**
  2751 /**
  2528  * Trash or delete a post or page.
  2752  * Trash or delete a post or page.
  2587 	 *
  2811 	 *
  2588 	 * @param int $postid Post ID.
  2812 	 * @param int $postid Post ID.
  2589 	 */
  2813 	 */
  2590 	do_action( 'before_delete_post', $postid );
  2814 	do_action( 'before_delete_post', $postid );
  2591 
  2815 
  2592 	delete_post_meta($postid,'_wp_trash_meta_status');
  2816 	delete_post_meta( $postid, '_wp_trash_meta_status' );
  2593 	delete_post_meta($postid,'_wp_trash_meta_time');
  2817 	delete_post_meta( $postid, '_wp_trash_meta_time' );
  2594 
  2818 
  2595 	wp_delete_object_term_relationships($postid, get_object_taxonomies($post->post_type));
  2819 	wp_delete_object_term_relationships( $postid, get_object_taxonomies( $post->post_type ) );
  2596 
  2820 
  2597 	$parent_data = array( 'post_parent' => $post->post_parent );
  2821 	$parent_data  = array( 'post_parent' => $post->post_parent );
  2598 	$parent_where = array( 'post_parent' => $postid );
  2822 	$parent_where = array( 'post_parent' => $postid );
  2599 
  2823 
  2600 	if ( is_post_type_hierarchical( $post->post_type ) ) {
  2824 	if ( is_post_type_hierarchical( $post->post_type ) ) {
  2601 		// Point children of this page to its parent, also clean the cache of affected children.
  2825 		// Point children of this page to its parent, also clean the cache of affected children.
  2602 		$children_query = $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE post_parent = %d AND post_type = %s", $postid, $post->post_type );
  2826 		$children_query = $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE post_parent = %d AND post_type = %s", $postid, $post->post_type );
  2603 		$children = $wpdb->get_results( $children_query );
  2827 		$children       = $wpdb->get_results( $children_query );
  2604 		if ( $children ) {
  2828 		if ( $children ) {
  2605 			$wpdb->update( $wpdb->posts, $parent_data, $parent_where + array( 'post_type' => $post->post_type ) );
  2829 			$wpdb->update( $wpdb->posts, $parent_data, $parent_where + array( 'post_type' => $post->post_type ) );
  2606 		}
  2830 		}
  2607 	}
  2831 	}
  2608 
  2832 
  2609 	// Do raw query. wp_get_post_revisions() is filtered.
  2833 	// Do raw query. wp_get_post_revisions() is filtered.
  2610 	$revision_ids = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_parent = %d AND post_type = 'revision'", $postid ) );
  2834 	$revision_ids = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_parent = %d AND post_type = 'revision'", $postid ) );
  2611 	// Use wp_delete_post (via wp_delete_post_revision) again. Ensures any meta/misplaced data gets cleaned up.
  2835 	// Use wp_delete_post (via wp_delete_post_revision) again. Ensures any meta/misplaced data gets cleaned up.
  2612 	foreach ( $revision_ids as $revision_id )
  2836 	foreach ( $revision_ids as $revision_id ) {
  2613 		wp_delete_post_revision( $revision_id );
  2837 		wp_delete_post_revision( $revision_id );
       
  2838 	}
  2614 
  2839 
  2615 	// Point all attachments to this post up one level.
  2840 	// Point all attachments to this post up one level.
  2616 	$wpdb->update( $wpdb->posts, $parent_data, $parent_where + array( 'post_type' => 'attachment' ) );
  2841 	$wpdb->update( $wpdb->posts, $parent_data, $parent_where + array( 'post_type' => 'attachment' ) );
  2617 
  2842 
  2618 	wp_defer_comment_counting( true );
  2843 	wp_defer_comment_counting( true );
  2619 
  2844 
  2620 	$comment_ids = $wpdb->get_col( $wpdb->prepare( "SELECT comment_ID FROM $wpdb->comments WHERE comment_post_ID = %d", $postid ));
  2845 	$comment_ids = $wpdb->get_col( $wpdb->prepare( "SELECT comment_ID FROM $wpdb->comments WHERE comment_post_ID = %d", $postid ) );
  2621 	foreach ( $comment_ids as $comment_id ) {
  2846 	foreach ( $comment_ids as $comment_id ) {
  2622 		wp_delete_comment( $comment_id, true );
  2847 		wp_delete_comment( $comment_id, true );
  2623 	}
  2848 	}
  2624 
  2849 
  2625 	wp_defer_comment_counting( false );
  2850 	wp_defer_comment_counting( false );
  2626 
  2851 
  2627 	$post_meta_ids = $wpdb->get_col( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d ", $postid ));
  2852 	$post_meta_ids = $wpdb->get_col( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d ", $postid ) );
  2628 	foreach ( $post_meta_ids as $mid )
  2853 	foreach ( $post_meta_ids as $mid ) {
  2629 		delete_metadata_by_mid( 'post', $mid );
  2854 		delete_metadata_by_mid( 'post', $mid );
       
  2855 	}
  2630 
  2856 
  2631 	/**
  2857 	/**
  2632 	 * Fires immediately before a post is deleted from the database.
  2858 	 * Fires immediately before a post is deleted from the database.
  2633 	 *
  2859 	 *
  2634 	 * @since 1.2.0
  2860 	 * @since 1.2.0
  2651 	do_action( 'deleted_post', $postid );
  2877 	do_action( 'deleted_post', $postid );
  2652 
  2878 
  2653 	clean_post_cache( $post );
  2879 	clean_post_cache( $post );
  2654 
  2880 
  2655 	if ( is_post_type_hierarchical( $post->post_type ) && $children ) {
  2881 	if ( is_post_type_hierarchical( $post->post_type ) && $children ) {
  2656 		foreach ( $children as $child )
  2882 		foreach ( $children as $child ) {
  2657 			clean_post_cache( $child );
  2883 			clean_post_cache( $child );
  2658 	}
  2884 		}
  2659 
  2885 	}
  2660 	wp_clear_scheduled_hook('publish_future_post', array( $postid ) );
  2886 
       
  2887 	wp_clear_scheduled_hook( 'publish_future_post', array( $postid ) );
  2661 
  2888 
  2662 	/**
  2889 	/**
  2663 	 * Fires after a post is deleted, at the conclusion of wp_delete_post().
  2890 	 * Fires after a post is deleted, at the conclusion of wp_delete_post().
  2664 	 *
  2891 	 *
  2665 	 * @since 3.2.0
  2892 	 * @since 3.2.0
  2685  * @param int $post_id Post ID.
  2912  * @param int $post_id Post ID.
  2686  */
  2913  */
  2687 function _reset_front_page_settings_for_post( $post_id ) {
  2914 function _reset_front_page_settings_for_post( $post_id ) {
  2688 	$post = get_post( $post_id );
  2915 	$post = get_post( $post_id );
  2689 	if ( 'page' == $post->post_type ) {
  2916 	if ( 'page' == $post->post_type ) {
  2690 	 	/*
  2917 		/*
  2691 	 	 * If the page is defined in option page_on_front or post_for_posts,
  2918 		  * If the page is defined in option page_on_front or post_for_posts,
  2692 	 	 * adjust the corresponding options.
  2919 		  * adjust the corresponding options.
  2693 	 	 */
  2920 		  */
  2694 		if ( get_option( 'page_on_front' ) == $post->ID ) {
  2921 		if ( get_option( 'page_on_front' ) == $post->ID ) {
  2695 			update_option( 'show_on_front', 'posts' );
  2922 			update_option( 'show_on_front', 'posts' );
  2696 			update_option( 'page_on_front', 0 );
  2923 			update_option( 'page_on_front', 0 );
  2697 		}
  2924 		}
  2698 		if ( get_option( 'page_for_posts' ) == $post->ID ) {
  2925 		if ( get_option( 'page_for_posts' ) == $post->ID ) {
  2753 	do_action( 'wp_trash_post', $post_id );
  2980 	do_action( 'wp_trash_post', $post_id );
  2754 
  2981 
  2755 	add_post_meta( $post_id, '_wp_trash_meta_status', $post->post_status );
  2982 	add_post_meta( $post_id, '_wp_trash_meta_status', $post->post_status );
  2756 	add_post_meta( $post_id, '_wp_trash_meta_time', time() );
  2983 	add_post_meta( $post_id, '_wp_trash_meta_time', time() );
  2757 
  2984 
  2758 	wp_update_post( array( 'ID' => $post_id, 'post_status' => 'trash' ) );
  2985 	wp_update_post(
       
  2986 		array(
       
  2987 			'ID'          => $post_id,
       
  2988 			'post_status' => 'trash',
       
  2989 		)
       
  2990 	);
  2759 
  2991 
  2760 	wp_trash_post_comments( $post_id );
  2992 	wp_trash_post_comments( $post_id );
  2761 
  2993 
  2762 	/**
  2994 	/**
  2763 	 * Fires after a post is sent to the trash.
  2995 	 * Fires after a post is sent to the trash.
  2815 	$post_status = get_post_meta( $post_id, '_wp_trash_meta_status', true );
  3047 	$post_status = get_post_meta( $post_id, '_wp_trash_meta_status', true );
  2816 
  3048 
  2817 	delete_post_meta( $post_id, '_wp_trash_meta_status' );
  3049 	delete_post_meta( $post_id, '_wp_trash_meta_status' );
  2818 	delete_post_meta( $post_id, '_wp_trash_meta_time' );
  3050 	delete_post_meta( $post_id, '_wp_trash_meta_time' );
  2819 
  3051 
  2820 	wp_update_post( array( 'ID' => $post_id, 'post_status' => $post_status ) );
  3052 	wp_update_post(
       
  3053 		array(
       
  3054 			'ID'          => $post_id,
       
  3055 			'post_status' => $post_status,
       
  3056 		)
       
  3057 	);
  2821 
  3058 
  2822 	wp_untrash_post_comments( $post_id );
  3059 	wp_untrash_post_comments( $post_id );
  2823 
  3060 
  2824 	/**
  3061 	/**
  2825 	 * Fires after a post is restored from the trash.
  3062 	 * Fires after a post is restored from the trash.
  2844  * @return mixed|void False on failure.
  3081  * @return mixed|void False on failure.
  2845  */
  3082  */
  2846 function wp_trash_post_comments( $post = null ) {
  3083 function wp_trash_post_comments( $post = null ) {
  2847 	global $wpdb;
  3084 	global $wpdb;
  2848 
  3085 
  2849 	$post = get_post($post);
  3086 	$post = get_post( $post );
  2850 	if ( empty($post) )
  3087 	if ( empty( $post ) ) {
  2851 		return;
  3088 		return;
       
  3089 	}
  2852 
  3090 
  2853 	$post_id = $post->ID;
  3091 	$post_id = $post->ID;
  2854 
  3092 
  2855 	/**
  3093 	/**
  2856 	 * Fires before comments are sent to the trash.
  3094 	 * Fires before comments are sent to the trash.
  2859 	 *
  3097 	 *
  2860 	 * @param int $post_id Post ID.
  3098 	 * @param int $post_id Post ID.
  2861 	 */
  3099 	 */
  2862 	do_action( 'trash_post_comments', $post_id );
  3100 	do_action( 'trash_post_comments', $post_id );
  2863 
  3101 
  2864 	$comments = $wpdb->get_results( $wpdb->prepare("SELECT comment_ID, comment_approved FROM $wpdb->comments WHERE comment_post_ID = %d", $post_id) );
  3102 	$comments = $wpdb->get_results( $wpdb->prepare( "SELECT comment_ID, comment_approved FROM $wpdb->comments WHERE comment_post_ID = %d", $post_id ) );
  2865 	if ( empty($comments) )
  3103 	if ( empty( $comments ) ) {
  2866 		return;
  3104 		return;
       
  3105 	}
  2867 
  3106 
  2868 	// Cache current status for each comment.
  3107 	// Cache current status for each comment.
  2869 	$statuses = array();
  3108 	$statuses = array();
  2870 	foreach ( $comments as $comment )
  3109 	foreach ( $comments as $comment ) {
  2871 		$statuses[$comment->comment_ID] = $comment->comment_approved;
  3110 		$statuses[ $comment->comment_ID ] = $comment->comment_approved;
  2872 	add_post_meta($post_id, '_wp_trash_meta_comments_status', $statuses);
  3111 	}
       
  3112 	add_post_meta( $post_id, '_wp_trash_meta_comments_status', $statuses );
  2873 
  3113 
  2874 	// Set status for all comments to post-trashed.
  3114 	// Set status for all comments to post-trashed.
  2875 	$result = $wpdb->update($wpdb->comments, array('comment_approved' => 'post-trashed'), array('comment_post_ID' => $post_id));
  3115 	$result = $wpdb->update( $wpdb->comments, array( 'comment_approved' => 'post-trashed' ), array( 'comment_post_ID' => $post_id ) );
  2876 
  3116 
  2877 	clean_comment_cache( array_keys($statuses) );
  3117 	clean_comment_cache( array_keys( $statuses ) );
  2878 
  3118 
  2879 	/**
  3119 	/**
  2880 	 * Fires after comments are sent to the trash.
  3120 	 * Fires after comments are sent to the trash.
  2881 	 *
  3121 	 *
  2882 	 * @since 2.9.0
  3122 	 * @since 2.9.0
  2900  * @return true|void
  3140  * @return true|void
  2901  */
  3141  */
  2902 function wp_untrash_post_comments( $post = null ) {
  3142 function wp_untrash_post_comments( $post = null ) {
  2903 	global $wpdb;
  3143 	global $wpdb;
  2904 
  3144 
  2905 	$post = get_post($post);
  3145 	$post = get_post( $post );
  2906 	if ( empty($post) )
  3146 	if ( empty( $post ) ) {
  2907 		return;
  3147 		return;
       
  3148 	}
  2908 
  3149 
  2909 	$post_id = $post->ID;
  3150 	$post_id = $post->ID;
  2910 
  3151 
  2911 	$statuses = get_post_meta($post_id, '_wp_trash_meta_comments_status', true);
  3152 	$statuses = get_post_meta( $post_id, '_wp_trash_meta_comments_status', true );
  2912 
  3153 
  2913 	if ( empty($statuses) )
  3154 	if ( empty( $statuses ) ) {
  2914 		return true;
  3155 		return true;
       
  3156 	}
  2915 
  3157 
  2916 	/**
  3158 	/**
  2917 	 * Fires before comments are restored for a post from the trash.
  3159 	 * Fires before comments are restored for a post from the trash.
  2918 	 *
  3160 	 *
  2919 	 * @since 2.9.0
  3161 	 * @since 2.9.0
  2922 	 */
  3164 	 */
  2923 	do_action( 'untrash_post_comments', $post_id );
  3165 	do_action( 'untrash_post_comments', $post_id );
  2924 
  3166 
  2925 	// Restore each comment to its original status.
  3167 	// Restore each comment to its original status.
  2926 	$group_by_status = array();
  3168 	$group_by_status = array();
  2927 	foreach ( $statuses as $comment_id => $comment_status )
  3169 	foreach ( $statuses as $comment_id => $comment_status ) {
  2928 		$group_by_status[$comment_status][] = $comment_id;
  3170 		$group_by_status[ $comment_status ][] = $comment_id;
       
  3171 	}
  2929 
  3172 
  2930 	foreach ( $group_by_status as $status => $comments ) {
  3173 	foreach ( $group_by_status as $status => $comments ) {
  2931 		// Sanity check. This shouldn't happen.
  3174 		// Sanity check. This shouldn't happen.
  2932 		if ( 'post-trashed' == $status ) {
  3175 		if ( 'post-trashed' == $status ) {
  2933 			$status = '0';
  3176 			$status = '0';
  2934 		}
  3177 		}
  2935 		$comments_in = implode( ', ', array_map( 'intval', $comments ) );
  3178 		$comments_in = implode( ', ', array_map( 'intval', $comments ) );
  2936 		$wpdb->query( $wpdb->prepare( "UPDATE $wpdb->comments SET comment_approved = %s WHERE comment_ID IN ($comments_in)", $status ) );
  3179 		$wpdb->query( $wpdb->prepare( "UPDATE $wpdb->comments SET comment_approved = %s WHERE comment_ID IN ($comments_in)", $status ) );
  2937 	}
  3180 	}
  2938 
  3181 
  2939 	clean_comment_cache( array_keys($statuses) );
  3182 	clean_comment_cache( array_keys( $statuses ) );
  2940 
  3183 
  2941 	delete_post_meta($post_id, '_wp_trash_meta_comments_status');
  3184 	delete_post_meta( $post_id, '_wp_trash_meta_comments_status' );
  2942 
  3185 
  2943 	/**
  3186 	/**
  2944 	 * Fires after comments are restored for a post from the trash.
  3187 	 * Fires after comments are restored for a post from the trash.
  2945 	 *
  3188 	 *
  2946 	 * @since 2.9.0
  3189 	 * @since 2.9.0
  2970  *                        WP_Error object if 'category' taxonomy doesn't exist.
  3213  *                        WP_Error object if 'category' taxonomy doesn't exist.
  2971  */
  3214  */
  2972 function wp_get_post_categories( $post_id = 0, $args = array() ) {
  3215 function wp_get_post_categories( $post_id = 0, $args = array() ) {
  2973 	$post_id = (int) $post_id;
  3216 	$post_id = (int) $post_id;
  2974 
  3217 
  2975 	$defaults = array('fields' => 'ids');
  3218 	$defaults = array( 'fields' => 'ids' );
  2976 	$args = wp_parse_args( $args, $defaults );
  3219 	$args     = wp_parse_args( $args, $defaults );
  2977 
  3220 
  2978 	$cats = wp_get_object_terms($post_id, 'category', $args);
  3221 	$cats = wp_get_object_terms( $post_id, 'category', $args );
  2979 	return $cats;
  3222 	return $cats;
  2980 }
  3223 }
  2981 
  3224 
  2982 /**
  3225 /**
  2983  * Retrieve the tags for a post.
  3226  * Retrieve the tags for a post.
  2994  *                       See WP_Term_Query::__construct() for supported arguments.
  3237  *                       See WP_Term_Query::__construct() for supported arguments.
  2995  * @return array|WP_Error Array of WP_Term objects on success or empty array if no tags were found.
  3238  * @return array|WP_Error Array of WP_Term objects on success or empty array if no tags were found.
  2996  *                        WP_Error object if 'post_tag' taxonomy doesn't exist.
  3239  *                        WP_Error object if 'post_tag' taxonomy doesn't exist.
  2997  */
  3240  */
  2998 function wp_get_post_tags( $post_id = 0, $args = array() ) {
  3241 function wp_get_post_tags( $post_id = 0, $args = array() ) {
  2999 	return wp_get_post_terms( $post_id, 'post_tag', $args);
  3242 	return wp_get_post_terms( $post_id, 'post_tag', $args );
  3000 }
  3243 }
  3001 
  3244 
  3002 /**
  3245 /**
  3003  * Retrieves the terms for a post.
  3246  * Retrieves the terms for a post.
  3004  *
  3247  *
  3017  *                        WP_Error object if `$taxonomy` doesn't exist.
  3260  *                        WP_Error object if `$taxonomy` doesn't exist.
  3018  */
  3261  */
  3019 function wp_get_post_terms( $post_id = 0, $taxonomy = 'post_tag', $args = array() ) {
  3262 function wp_get_post_terms( $post_id = 0, $taxonomy = 'post_tag', $args = array() ) {
  3020 	$post_id = (int) $post_id;
  3263 	$post_id = (int) $post_id;
  3021 
  3264 
  3022 	$defaults = array('fields' => 'all');
  3265 	$defaults = array( 'fields' => 'all' );
  3023 	$args = wp_parse_args( $args, $defaults );
  3266 	$args     = wp_parse_args( $args, $defaults );
  3024 
  3267 
  3025 	$tags = wp_get_object_terms($post_id, $taxonomy, $args);
  3268 	$tags = wp_get_object_terms( $post_id, $taxonomy, $args );
  3026 
  3269 
  3027 	return $tags;
  3270 	return $tags;
  3028 }
  3271 }
  3029 
  3272 
  3030 /**
  3273 /**
  3047 		$args = array( 'numberposts' => absint( $args ) );
  3290 		$args = array( 'numberposts' => absint( $args ) );
  3048 	}
  3291 	}
  3049 
  3292 
  3050 	// Set default arguments.
  3293 	// Set default arguments.
  3051 	$defaults = array(
  3294 	$defaults = array(
  3052 		'numberposts' => 10, 'offset' => 0,
  3295 		'numberposts'      => 10,
  3053 		'category' => 0, 'orderby' => 'post_date',
  3296 		'offset'           => 0,
  3054 		'order' => 'DESC', 'include' => '',
  3297 		'category'         => 0,
  3055 		'exclude' => '', 'meta_key' => '',
  3298 		'orderby'          => 'post_date',
  3056 		'meta_value' =>'', 'post_type' => 'post', 'post_status' => 'draft, publish, future, pending, private',
  3299 		'order'            => 'DESC',
  3057 		'suppress_filters' => true
  3300 		'include'          => '',
       
  3301 		'exclude'          => '',
       
  3302 		'meta_key'         => '',
       
  3303 		'meta_value'       => '',
       
  3304 		'post_type'        => 'post',
       
  3305 		'post_status'      => 'draft, publish, future, pending, private',
       
  3306 		'suppress_filters' => true,
  3058 	);
  3307 	);
  3059 
  3308 
  3060 	$r = wp_parse_args( $args, $defaults );
  3309 	$r = wp_parse_args( $args, $defaults );
  3061 
  3310 
  3062 	$results = get_posts( $r );
  3311 	$results = get_posts( $r );
  3063 
  3312 
  3064 	// Backward compatibility. Prior to 3.1 expected posts to be returned in array.
  3313 	// Backward compatibility. Prior to 3.1 expected posts to be returned in array.
  3065 	if ( ARRAY_A == $output ){
  3314 	if ( ARRAY_A == $output ) {
  3066 		foreach ( $results as $key => $result ) {
  3315 		foreach ( $results as $key => $result ) {
  3067 			$results[$key] = get_object_vars( $result );
  3316 			$results[ $key ] = get_object_vars( $result );
  3068 		}
  3317 		}
  3069 		return $results ? $results : array();
  3318 		return $results ? $results : array();
  3070 	}
  3319 	}
  3071 
  3320 
  3072 	return $results ? $results : false;
  3321 	return $results ? $results : false;
  3122  *                                         timezone. Default is the current time.
  3371  *                                         timezone. Default is the current time.
  3123  *     @type int    $post_parent           Set this for the post it belongs to, if any. Default 0.
  3372  *     @type int    $post_parent           Set this for the post it belongs to, if any. Default 0.
  3124  *     @type int    $menu_order            The order the post should be displayed in. Default 0.
  3373  *     @type int    $menu_order            The order the post should be displayed in. Default 0.
  3125  *     @type string $post_mime_type        The mime type of the post. Default empty.
  3374  *     @type string $post_mime_type        The mime type of the post. Default empty.
  3126  *     @type string $guid                  Global Unique ID for referencing the post. Default empty.
  3375  *     @type string $guid                  Global Unique ID for referencing the post. Default empty.
  3127  *     @type array  $post_category         Array of category names, slugs, or IDs.
  3376  *     @type array  $post_category         Array of category IDs.
  3128  *                                         Defaults to value of the 'default_category' option.
  3377  *                                         Defaults to value of the 'default_category' option.
  3129  *     @type array  $tags_input            Array of tag names, slugs, or IDs. Default empty.
  3378  *     @type array  $tags_input            Array of tag names, slugs, or IDs. Default empty.
  3130  *     @type array  $tax_input             Array of taxonomy terms keyed by their taxonomy name. Default empty.
  3379  *     @type array  $tax_input             Array of taxonomy terms keyed by their taxonomy name. Default empty.
  3131  *     @type array  $meta_input            Array of post meta values keyed by their post meta key. Default empty.
  3380  *     @type array  $meta_input            Array of post meta values keyed by their post meta key. Default empty.
  3132  * }
  3381  * }
  3137 	global $wpdb;
  3386 	global $wpdb;
  3138 
  3387 
  3139 	$user_id = get_current_user_id();
  3388 	$user_id = get_current_user_id();
  3140 
  3389 
  3141 	$defaults = array(
  3390 	$defaults = array(
  3142 		'post_author' => $user_id,
  3391 		'post_author'           => $user_id,
  3143 		'post_content' => '',
  3392 		'post_content'          => '',
  3144 		'post_content_filtered' => '',
  3393 		'post_content_filtered' => '',
  3145 		'post_title' => '',
  3394 		'post_title'            => '',
  3146 		'post_excerpt' => '',
  3395 		'post_excerpt'          => '',
  3147 		'post_status' => 'draft',
  3396 		'post_status'           => 'draft',
  3148 		'post_type' => 'post',
  3397 		'post_type'             => 'post',
  3149 		'comment_status' => '',
  3398 		'comment_status'        => '',
  3150 		'ping_status' => '',
  3399 		'ping_status'           => '',
  3151 		'post_password' => '',
  3400 		'post_password'         => '',
  3152 		'to_ping' =>  '',
  3401 		'to_ping'               => '',
  3153 		'pinged' => '',
  3402 		'pinged'                => '',
  3154 		'post_parent' => 0,
  3403 		'post_parent'           => 0,
  3155 		'menu_order' => 0,
  3404 		'menu_order'            => 0,
  3156 		'guid' => '',
  3405 		'guid'                  => '',
  3157 		'import_id' => 0,
  3406 		'import_id'             => 0,
  3158 		'context' => '',
  3407 		'context'               => '',
  3159 	);
  3408 	);
  3160 
  3409 
  3161 	$postarr = wp_parse_args($postarr, $defaults);
  3410 	$postarr = wp_parse_args( $postarr, $defaults );
  3162 
  3411 
  3163 	unset( $postarr[ 'filter' ] );
  3412 	unset( $postarr['filter'] );
  3164 
  3413 
  3165 	$postarr = sanitize_post($postarr, 'db');
  3414 	$postarr = sanitize_post( $postarr, 'db' );
  3166 
  3415 
  3167 	// Are we updating or creating?
  3416 	// Are we updating or creating?
  3168 	$post_ID = 0;
  3417 	$post_ID = 0;
  3169 	$update = false;
  3418 	$update  = false;
  3170 	$guid = $postarr['guid'];
  3419 	$guid    = $postarr['guid'];
  3171 
  3420 
  3172 	if ( ! empty( $postarr['ID'] ) ) {
  3421 	if ( ! empty( $postarr['ID'] ) ) {
  3173 		$update = true;
  3422 		$update = true;
  3174 
  3423 
  3175 		// Get the post ID and GUID.
  3424 		// Get the post ID and GUID.
  3176 		$post_ID = $postarr['ID'];
  3425 		$post_ID     = $postarr['ID'];
  3177 		$post_before = get_post( $post_ID );
  3426 		$post_before = get_post( $post_ID );
  3178 		if ( is_null( $post_before ) ) {
  3427 		if ( is_null( $post_before ) ) {
  3179 			if ( $wp_error ) {
  3428 			if ( $wp_error ) {
  3180 				return new WP_Error( 'invalid_post', __( 'Invalid post ID.' ) );
  3429 				return new WP_Error( 'invalid_post', __( 'Invalid post ID.' ) );
  3181 			}
  3430 			}
  3182 			return 0;
  3431 			return 0;
  3183 		}
  3432 		}
  3184 
  3433 
  3185 		$guid = get_post_field( 'guid', $post_ID );
  3434 		$guid            = get_post_field( 'guid', $post_ID );
  3186 		$previous_status = get_post_field('post_status', $post_ID );
  3435 		$previous_status = get_post_field( 'post_status', $post_ID );
  3187 	} else {
  3436 	} else {
  3188 		$previous_status = 'new';
  3437 		$previous_status = 'new';
  3189 	}
  3438 	}
  3190 
  3439 
  3191 	$post_type = empty( $postarr['post_type'] ) ? 'post' : $postarr['post_type'];
  3440 	$post_type = empty( $postarr['post_type'] ) ? 'post' : $postarr['post_type'];
  3192 
  3441 
  3193 	$post_title = $postarr['post_title'];
  3442 	$post_title   = $postarr['post_title'];
  3194 	$post_content = $postarr['post_content'];
  3443 	$post_content = $postarr['post_content'];
  3195 	$post_excerpt = $postarr['post_excerpt'];
  3444 	$post_excerpt = $postarr['post_excerpt'];
  3196 	if ( isset( $postarr['post_name'] ) ) {
  3445 	if ( isset( $postarr['post_name'] ) ) {
  3197 		$post_name = $postarr['post_name'];
  3446 		$post_name = $postarr['post_name'];
  3198 	} elseif ( $update ) {
  3447 	} elseif ( $update ) {
  3242 
  3491 
  3243 	// Make sure we set a valid category.
  3492 	// Make sure we set a valid category.
  3244 	if ( empty( $post_category ) || 0 == count( $post_category ) || ! is_array( $post_category ) ) {
  3493 	if ( empty( $post_category ) || 0 == count( $post_category ) || ! is_array( $post_category ) ) {
  3245 		// 'post' requires at least one category.
  3494 		// 'post' requires at least one category.
  3246 		if ( 'post' == $post_type && 'auto-draft' != $post_status ) {
  3495 		if ( 'post' == $post_type && 'auto-draft' != $post_status ) {
  3247 			$post_category = array( get_option('default_category') );
  3496 			$post_category = array( get_option( 'default_category' ) );
  3248 		} else {
  3497 		} else {
  3249 			$post_category = array();
  3498 			$post_category = array();
  3250 		}
  3499 		}
  3251 	}
  3500 	}
  3252 
  3501 
  3253 	// Don't allow contributors to set the post slug for pending review posts.
  3502 	/*
  3254 	if ( 'pending' == $post_status && !current_user_can( 'publish_posts' ) ) {
  3503 	 * Don't allow contributors to set the post slug for pending review posts.
       
  3504 	 *
       
  3505 	 * For new posts check the primitive capability, for updates check the meta capability.
       
  3506 	 */
       
  3507 	$post_type_object = get_post_type_object( $post_type );
       
  3508 
       
  3509 	if ( ! $update && 'pending' === $post_status && ! current_user_can( $post_type_object->cap->publish_posts ) ) {
       
  3510 		$post_name = '';
       
  3511 	} elseif ( $update && 'pending' === $post_status && ! current_user_can( 'publish_post', $post_ID ) ) {
  3255 		$post_name = '';
  3512 		$post_name = '';
  3256 	}
  3513 	}
  3257 
  3514 
  3258 	/*
  3515 	/*
  3259 	 * Create a valid post name. Drafts and pending posts are allowed to have
  3516 	 * Create a valid post name. Drafts and pending posts are allowed to have
  3260 	 * an empty post name.
  3517 	 * an empty post name.
  3261 	 */
  3518 	 */
  3262 	if ( empty($post_name) ) {
  3519 	if ( empty( $post_name ) ) {
  3263 		if ( !in_array( $post_status, array( 'draft', 'pending', 'auto-draft' ) ) ) {
  3520 		if ( ! in_array( $post_status, array( 'draft', 'pending', 'auto-draft' ) ) ) {
  3264 			$post_name = sanitize_title($post_title);
  3521 			$post_name = sanitize_title( $post_title );
  3265 		} else {
  3522 		} else {
  3266 			$post_name = '';
  3523 			$post_name = '';
  3267 		}
  3524 		}
  3268 	} else {
  3525 	} else {
  3269 		// On updates, we need to check to see if it's using the old, fixed sanitization context.
  3526 		// On updates, we need to check to see if it's using the old, fixed sanitization context.
  3270 		$check_name = sanitize_title( $post_name, '', 'old-save' );
  3527 		$check_name = sanitize_title( $post_name, '', 'old-save' );
  3271 		if ( $update && strtolower( urlencode( $post_name ) ) == $check_name && get_post_field( 'post_name', $post_ID ) == $check_name ) {
  3528 		if ( $update && strtolower( urlencode( $post_name ) ) == $check_name && get_post_field( 'post_name', $post_ID ) == $check_name ) {
  3272 			$post_name = $check_name;
  3529 			$post_name = $check_name;
  3273 		} else { // new post, or slug has changed.
  3530 		} else { // new post, or slug has changed.
  3274 			$post_name = sanitize_title($post_name);
  3531 			$post_name = sanitize_title( $post_name );
  3275 		}
  3532 		}
  3276 	}
  3533 	}
  3277 
  3534 
  3278 	/*
  3535 	/*
  3279 	 * If the post date is empty (due to having been new or a draft) and status
  3536 	 * If the post date is empty (due to having been new or a draft) and status
  3288 	} else {
  3545 	} else {
  3289 		$post_date = $postarr['post_date'];
  3546 		$post_date = $postarr['post_date'];
  3290 	}
  3547 	}
  3291 
  3548 
  3292 	// Validate the date.
  3549 	// Validate the date.
  3293 	$mm = substr( $post_date, 5, 2 );
  3550 	$mm         = substr( $post_date, 5, 2 );
  3294 	$jj = substr( $post_date, 8, 2 );
  3551 	$jj         = substr( $post_date, 8, 2 );
  3295 	$aa = substr( $post_date, 0, 4 );
  3552 	$aa         = substr( $post_date, 0, 4 );
  3296 	$valid_date = wp_checkdate( $mm, $jj, $aa, $post_date );
  3553 	$valid_date = wp_checkdate( $mm, $jj, $aa, $post_date );
  3297 	if ( ! $valid_date ) {
  3554 	if ( ! $valid_date ) {
  3298 		if ( $wp_error ) {
  3555 		if ( $wp_error ) {
  3299 			return new WP_Error( 'invalid_date', __( 'Invalid date.' ) );
  3556 			return new WP_Error( 'invalid_date', __( 'Invalid date.' ) );
  3300 		} else {
  3557 		} else {
  3320 		$post_modified_gmt = $post_date_gmt;
  3577 		$post_modified_gmt = $post_date_gmt;
  3321 	}
  3578 	}
  3322 
  3579 
  3323 	if ( 'attachment' !== $post_type ) {
  3580 	if ( 'attachment' !== $post_type ) {
  3324 		if ( 'publish' == $post_status ) {
  3581 		if ( 'publish' == $post_status ) {
  3325 			$now = gmdate('Y-m-d H:i:59');
  3582 			$now = gmdate( 'Y-m-d H:i:59' );
  3326 			if ( mysql2date('U', $post_date_gmt, false) > mysql2date('U', $now, false) ) {
  3583 			if ( mysql2date( 'U', $post_date_gmt, false ) > mysql2date( 'U', $now, false ) ) {
  3327 				$post_status = 'future';
  3584 				$post_status = 'future';
  3328 			}
  3585 			}
  3329 		} elseif ( 'future' == $post_status ) {
  3586 		} elseif ( 'future' == $post_status ) {
  3330 			$now = gmdate('Y-m-d H:i:59');
  3587 			$now = gmdate( 'Y-m-d H:i:59' );
  3331 			if ( mysql2date('U', $post_date_gmt, false) <= mysql2date('U', $now, false) ) {
  3588 			if ( mysql2date( 'U', $post_date_gmt, false ) <= mysql2date( 'U', $now, false ) ) {
  3332 				$post_status = 'publish';
  3589 				$post_status = 'publish';
  3333 			}
  3590 			}
  3334 		}
  3591 		}
  3335 	}
  3592 	}
  3336 
  3593 
  3345 		$comment_status = $postarr['comment_status'];
  3602 		$comment_status = $postarr['comment_status'];
  3346 	}
  3603 	}
  3347 
  3604 
  3348 	// These variables are needed by compact() later.
  3605 	// These variables are needed by compact() later.
  3349 	$post_content_filtered = $postarr['post_content_filtered'];
  3606 	$post_content_filtered = $postarr['post_content_filtered'];
  3350 	$post_author = isset( $postarr['post_author'] ) ? $postarr['post_author'] : $user_id;
  3607 	$post_author           = isset( $postarr['post_author'] ) ? $postarr['post_author'] : $user_id;
  3351 	$ping_status = empty( $postarr['ping_status'] ) ? get_default_comment_status( $post_type, 'pingback' ) : $postarr['ping_status'];
  3608 	$ping_status           = empty( $postarr['ping_status'] ) ? get_default_comment_status( $post_type, 'pingback' ) : $postarr['ping_status'];
  3352 	$to_ping = isset( $postarr['to_ping'] ) ? sanitize_trackback_urls( $postarr['to_ping'] ) : '';
  3609 	$to_ping               = isset( $postarr['to_ping'] ) ? sanitize_trackback_urls( $postarr['to_ping'] ) : '';
  3353 	$pinged = isset( $postarr['pinged'] ) ? $postarr['pinged'] : '';
  3610 	$pinged                = isset( $postarr['pinged'] ) ? $postarr['pinged'] : '';
  3354 	$import_id = isset( $postarr['import_id'] ) ? $postarr['import_id'] : 0;
  3611 	$import_id             = isset( $postarr['import_id'] ) ? $postarr['import_id'] : 0;
  3355 
  3612 
  3356 	/*
  3613 	/*
  3357 	 * The 'wp_insert_post_parent' filter expects all variables to be present.
  3614 	 * The 'wp_insert_post_parent' filter expects all variables to be present.
  3358 	 * Previously, these variables would have already been extracted
  3615 	 * Previously, these variables would have already been extracted
  3359 	 */
  3616 	 */
  3372 		$post_parent = (int) $postarr['post_parent'];
  3629 		$post_parent = (int) $postarr['post_parent'];
  3373 	} else {
  3630 	} else {
  3374 		$post_parent = 0;
  3631 		$post_parent = 0;
  3375 	}
  3632 	}
  3376 
  3633 
       
  3634 	$new_postarr = array_merge(
       
  3635 		array(
       
  3636 			'ID' => $post_ID,
       
  3637 		),
       
  3638 		compact( array_diff( array_keys( $defaults ), array( 'context', 'filter' ) ) )
       
  3639 	);
       
  3640 
  3377 	/**
  3641 	/**
  3378 	 * Filters the post parent -- used to check for and prevent hierarchy loops.
  3642 	 * Filters the post parent -- used to check for and prevent hierarchy loops.
  3379 	 *
  3643 	 *
  3380 	 * @since 3.1.0
  3644 	 * @since 3.1.0
  3381 	 *
  3645 	 *
  3382 	 * @param int   $post_parent Post parent ID.
  3646 	 * @param int   $post_parent Post parent ID.
  3383 	 * @param int   $post_ID     Post ID.
  3647 	 * @param int   $post_ID     Post ID.
  3384 	 * @param array $new_postarr Array of parsed post data.
  3648 	 * @param array $new_postarr Array of parsed post data.
  3385 	 * @param array $postarr     Array of sanitized, but otherwise unmodified post data.
  3649 	 * @param array $postarr     Array of sanitized, but otherwise unmodified post data.
  3386 	 */
  3650 	 */
  3387 	$post_parent = apply_filters( 'wp_insert_post_parent', $post_parent, $post_ID, compact( array_keys( $postarr ) ), $postarr );
  3651 	$post_parent = apply_filters( 'wp_insert_post_parent', $post_parent, $post_ID, $new_postarr, $postarr );
  3388 
  3652 
  3389 	/*
  3653 	/*
  3390 	 * If the post is being untrashed and it has a desired slug stored in post meta,
  3654 	 * If the post is being untrashed and it has a desired slug stored in post meta,
  3391 	 * reassign it.
  3655 	 * reassign it.
  3392 	 */
  3656 	 */
  3446 		 * @param array $data    An array of slashed post data.
  3710 		 * @param array $data    An array of slashed post data.
  3447 		 * @param array $postarr An array of sanitized, but otherwise unmodified post data.
  3711 		 * @param array $postarr An array of sanitized, but otherwise unmodified post data.
  3448 		 */
  3712 		 */
  3449 		$data = apply_filters( 'wp_insert_post_data', $data, $postarr );
  3713 		$data = apply_filters( 'wp_insert_post_data', $data, $postarr );
  3450 	}
  3714 	}
  3451 	$data = wp_unslash( $data );
  3715 	$data  = wp_unslash( $data );
  3452 	$where = array( 'ID' => $post_ID );
  3716 	$where = array( 'ID' => $post_ID );
  3453 
  3717 
  3454 	if ( $update ) {
  3718 	if ( $update ) {
  3455 		/**
  3719 		/**
  3456 		 * Fires immediately before an existing post is updated in the database.
  3720 		 * Fires immediately before an existing post is updated in the database.
  3461 		 * @param array $data    Array of unslashed post data.
  3725 		 * @param array $data    Array of unslashed post data.
  3462 		 */
  3726 		 */
  3463 		do_action( 'pre_post_update', $post_ID, $data );
  3727 		do_action( 'pre_post_update', $post_ID, $data );
  3464 		if ( false === $wpdb->update( $wpdb->posts, $data, $where ) ) {
  3728 		if ( false === $wpdb->update( $wpdb->posts, $data, $where ) ) {
  3465 			if ( $wp_error ) {
  3729 			if ( $wp_error ) {
  3466 				return new WP_Error('db_update_error', __('Could not update post in the database'), $wpdb->last_error);
  3730 				return new WP_Error( 'db_update_error', __( 'Could not update post in the database' ), $wpdb->last_error );
  3467 			} else {
  3731 			} else {
  3468 				return 0;
  3732 				return 0;
  3469 			}
  3733 			}
  3470 		}
  3734 		}
  3471 	} else {
  3735 	} else {
  3472 		// If there is a suggested ID, use it if not already present.
  3736 		// If there is a suggested ID, use it if not already present.
  3473 		if ( ! empty( $import_id ) ) {
  3737 		if ( ! empty( $import_id ) ) {
  3474 			$import_id = (int) $import_id;
  3738 			$import_id = (int) $import_id;
  3475 			if ( ! $wpdb->get_var( $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE ID = %d", $import_id) ) ) {
  3739 			if ( ! $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE ID = %d", $import_id ) ) ) {
  3476 				$data['ID'] = $import_id;
  3740 				$data['ID'] = $import_id;
  3477 			}
  3741 			}
  3478 		}
  3742 		}
  3479 		if ( false === $wpdb->insert( $wpdb->posts, $data ) ) {
  3743 		if ( false === $wpdb->insert( $wpdb->posts, $data ) ) {
  3480 			if ( $wp_error ) {
  3744 			if ( $wp_error ) {
  3481 				return new WP_Error('db_insert_error', __('Could not insert post into the database'), $wpdb->last_error);
  3745 				return new WP_Error( 'db_insert_error', __( 'Could not insert post into the database' ), $wpdb->last_error );
  3482 			} else {
  3746 			} else {
  3483 				return 0;
  3747 				return 0;
  3484 			}
  3748 			}
  3485 		}
  3749 		}
  3486 		$post_ID = (int) $wpdb->insert_id;
  3750 		$post_ID = (int) $wpdb->insert_id;
  3504 	}
  3768 	}
  3505 
  3769 
  3506 	// New-style support for all custom taxonomies.
  3770 	// New-style support for all custom taxonomies.
  3507 	if ( ! empty( $postarr['tax_input'] ) ) {
  3771 	if ( ! empty( $postarr['tax_input'] ) ) {
  3508 		foreach ( $postarr['tax_input'] as $taxonomy => $tags ) {
  3772 		foreach ( $postarr['tax_input'] as $taxonomy => $tags ) {
  3509 			$taxonomy_obj = get_taxonomy($taxonomy);
  3773 			$taxonomy_obj = get_taxonomy( $taxonomy );
  3510 			if ( ! $taxonomy_obj ) {
  3774 			if ( ! $taxonomy_obj ) {
  3511 				/* translators: %s: taxonomy name */
  3775 				/* translators: %s: taxonomy name */
  3512 				_doing_it_wrong( __FUNCTION__, sprintf( __( 'Invalid taxonomy: %s.' ), $taxonomy ), '4.4.0' );
  3776 				_doing_it_wrong( __FUNCTION__, sprintf( __( 'Invalid taxonomy: %s.' ), $taxonomy ), '4.4.0' );
  3513 				continue;
  3777 				continue;
  3514 			}
  3778 			}
  3515 
  3779 
  3516 			// array = hierarchical, string = non-hierarchical.
  3780 			// array = hierarchical, string = non-hierarchical.
  3517 			if ( is_array( $tags ) ) {
  3781 			if ( is_array( $tags ) ) {
  3518 				$tags = array_filter($tags);
  3782 				$tags = array_filter( $tags );
  3519 			}
  3783 			}
  3520 			if ( current_user_can( $taxonomy_obj->cap->assign_terms ) ) {
  3784 			if ( current_user_can( $taxonomy_obj->cap->assign_terms ) ) {
  3521 				wp_set_post_terms( $post_ID, $tags, $taxonomy );
  3785 				wp_set_post_terms( $post_ID, $tags, $taxonomy );
  3522 			}
  3786 			}
  3523 		}
  3787 		}
  3571 
  3835 
  3572 	$post = get_post( $post_ID );
  3836 	$post = get_post( $post_ID );
  3573 
  3837 
  3574 	if ( ! empty( $postarr['page_template'] ) ) {
  3838 	if ( ! empty( $postarr['page_template'] ) ) {
  3575 		$post->page_template = $postarr['page_template'];
  3839 		$post->page_template = $postarr['page_template'];
  3576 		$page_templates = wp_get_theme()->get_page_templates( $post );
  3840 		$page_templates      = wp_get_theme()->get_page_templates( $post );
  3577 		if ( 'default' != $postarr['page_template'] && ! isset( $page_templates[ $postarr['page_template'] ] ) ) {
  3841 		if ( 'default' != $postarr['page_template'] && ! isset( $page_templates[ $postarr['page_template'] ] ) ) {
  3578 			if ( $wp_error ) {
  3842 			if ( $wp_error ) {
  3579 				return new WP_Error( 'invalid_page_template', __( 'Invalid page template.' ) );
  3843 				return new WP_Error( 'invalid_page_template', __( 'Invalid page template.' ) );
  3580 			}
  3844 			}
  3581 			update_post_meta( $post_ID, '_wp_page_template', 'default' );
  3845 			update_post_meta( $post_ID, '_wp_page_template', 'default' );
  3625 
  3889 
  3626 	if ( $update ) {
  3890 	if ( $update ) {
  3627 		/**
  3891 		/**
  3628 		 * Fires once an existing post has been updated.
  3892 		 * Fires once an existing post has been updated.
  3629 		 *
  3893 		 *
       
  3894 		 * The dynamic portion of the hook name, `$post->post_type`, refers to
       
  3895 		 * the post type slug.
       
  3896 		 *
       
  3897 		 * @since 5.1.0
       
  3898 		 *
       
  3899 		 * @param int     $post_ID Post ID.
       
  3900 		 * @param WP_Post $post    Post object.
       
  3901 		 */
       
  3902 		do_action( "edit_post_{$post->post_type}", $post_ID, $post );
       
  3903 
       
  3904 		/**
       
  3905 		 * Fires once an existing post has been updated.
       
  3906 		 *
  3630 		 * @since 1.2.0
  3907 		 * @since 1.2.0
  3631 		 *
  3908 		 *
  3632 		 * @param int     $post_ID Post ID.
  3909 		 * @param int     $post_ID Post ID.
  3633 		 * @param WP_Post $post    Post object.
  3910 		 * @param WP_Post $post    Post object.
  3634 		 */
  3911 		 */
  3635 		do_action( 'edit_post', $post_ID, $post );
  3912 		do_action( 'edit_post', $post_ID, $post );
  3636 		$post_after = get_post($post_ID);
  3913 
       
  3914 		$post_after = get_post( $post_ID );
  3637 
  3915 
  3638 		/**
  3916 		/**
  3639 		 * Fires once an existing post has been updated.
  3917 		 * Fires once an existing post has been updated.
  3640 		 *
  3918 		 *
  3641 		 * @since 3.0.0
  3919 		 * @since 3.0.0
  3642 		 *
  3920 		 *
  3643 		 * @param int     $post_ID      Post ID.
  3921 		 * @param int     $post_ID      Post ID.
  3644 		 * @param WP_Post $post_after   Post object following the update.
  3922 		 * @param WP_Post $post_after   Post object following the update.
  3645 		 * @param WP_Post $post_before  Post object before the update.
  3923 		 * @param WP_Post $post_before  Post object before the update.
  3646 		 */
  3924 		 */
  3647 		do_action( 'post_updated', $post_ID, $post_after, $post_before);
  3925 		do_action( 'post_updated', $post_ID, $post_after, $post_before );
  3648 	}
  3926 	}
  3649 
  3927 
  3650 	/**
  3928 	/**
  3651 	 * Fires once a post has been saved.
  3929 	 * Fires once a post has been saved.
  3652 	 *
  3930 	 *
  3698  *                               objects are not. Default array.
  3976  *                               objects are not. Default array.
  3699  * @param bool         $wp_error Optional. Allow return of WP_Error on failure. Default false.
  3977  * @param bool         $wp_error Optional. Allow return of WP_Error on failure. Default false.
  3700  * @return int|WP_Error The value 0 or WP_Error on failure. The post ID on success.
  3978  * @return int|WP_Error The value 0 or WP_Error on failure. The post ID on success.
  3701  */
  3979  */
  3702 function wp_update_post( $postarr = array(), $wp_error = false ) {
  3980 function wp_update_post( $postarr = array(), $wp_error = false ) {
  3703 	if ( is_object($postarr) ) {
  3981 	if ( is_object( $postarr ) ) {
  3704 		// Non-escaped post was passed.
  3982 		// Non-escaped post was passed.
  3705 		$postarr = get_object_vars($postarr);
  3983 		$postarr = get_object_vars( $postarr );
  3706 		$postarr = wp_slash($postarr);
  3984 		$postarr = wp_slash( $postarr );
  3707 	}
  3985 	}
  3708 
  3986 
  3709 	// First, get all of the original fields.
  3987 	// First, get all of the original fields.
  3710 	$post = get_post($postarr['ID'], ARRAY_A);
  3988 	$post = get_post( $postarr['ID'], ARRAY_A );
  3711 
  3989 
  3712 	if ( is_null( $post ) ) {
  3990 	if ( is_null( $post ) ) {
  3713 		if ( $wp_error )
  3991 		if ( $wp_error ) {
  3714 			return new WP_Error( 'invalid_post', __( 'Invalid post ID.' ) );
  3992 			return new WP_Error( 'invalid_post', __( 'Invalid post ID.' ) );
       
  3993 		}
  3715 		return 0;
  3994 		return 0;
  3716 	}
  3995 	}
  3717 
  3996 
  3718 	// Escape data pulled from DB.
  3997 	// Escape data pulled from DB.
  3719 	$post = wp_slash($post);
  3998 	$post = wp_slash( $post );
  3720 
  3999 
  3721 	// Passed post category list overwrites existing category list if not empty.
  4000 	// Passed post category list overwrites existing category list if not empty.
  3722 	if ( isset($postarr['post_category']) && is_array($postarr['post_category'])
  4001 	if ( isset( $postarr['post_category'] ) && is_array( $postarr['post_category'] )
  3723 			 && 0 != count($postarr['post_category']) )
  4002 			&& 0 != count( $postarr['post_category'] ) ) {
  3724 		$post_cats = $postarr['post_category'];
  4003 		$post_cats = $postarr['post_category'];
  3725 	else
  4004 	} else {
  3726 		$post_cats = $post['post_category'];
  4005 		$post_cats = $post['post_category'];
       
  4006 	}
  3727 
  4007 
  3728 	// Drafts shouldn't be assigned a date unless explicitly done so by the user.
  4008 	// Drafts shouldn't be assigned a date unless explicitly done so by the user.
  3729 	if ( isset( $post['post_status'] ) && in_array($post['post_status'], array('draft', 'pending', 'auto-draft')) && empty($postarr['edit_date']) &&
  4009 	if ( isset( $post['post_status'] ) && in_array( $post['post_status'], array( 'draft', 'pending', 'auto-draft' ) ) && empty( $postarr['edit_date'] ) &&
  3730 			 ('0000-00-00 00:00:00' == $post['post_date_gmt']) )
  4010 			( '0000-00-00 00:00:00' == $post['post_date_gmt'] ) ) {
  3731 		$clear_date = true;
  4011 		$clear_date = true;
  3732 	else
  4012 	} else {
  3733 		$clear_date = false;
  4013 		$clear_date = false;
       
  4014 	}
  3734 
  4015 
  3735 	// Merge old and new fields with new fields overwriting old ones.
  4016 	// Merge old and new fields with new fields overwriting old ones.
  3736 	$postarr = array_merge($post, $postarr);
  4017 	$postarr                  = array_merge( $post, $postarr );
  3737 	$postarr['post_category'] = $post_cats;
  4018 	$postarr['post_category'] = $post_cats;
  3738 	if ( $clear_date ) {
  4019 	if ( $clear_date ) {
  3739 		$postarr['post_date'] = current_time('mysql');
  4020 		$postarr['post_date']     = current_time( 'mysql' );
  3740 		$postarr['post_date_gmt'] = '';
  4021 		$postarr['post_date_gmt'] = '';
  3741 	}
  4022 	}
  3742 
  4023 
  3743 	if ($postarr['post_type'] == 'attachment')
  4024 	if ( $postarr['post_type'] == 'attachment' ) {
  3744 		return wp_insert_attachment($postarr);
  4025 		return wp_insert_attachment( $postarr, false, 0, $wp_error );
       
  4026 	}
  3745 
  4027 
  3746 	return wp_insert_post( $postarr, $wp_error );
  4028 	return wp_insert_post( $postarr, $wp_error );
  3747 }
  4029 }
  3748 
  4030 
  3749 /**
  4031 /**
  3756  * @param int|WP_Post $post Post ID or post object.
  4038  * @param int|WP_Post $post Post ID or post object.
  3757  */
  4039  */
  3758 function wp_publish_post( $post ) {
  4040 function wp_publish_post( $post ) {
  3759 	global $wpdb;
  4041 	global $wpdb;
  3760 
  4042 
  3761 	if ( ! $post = get_post( $post ) )
  4043 	if ( ! $post = get_post( $post ) ) {
  3762 		return;
  4044 		return;
  3763 
  4045 	}
  3764 	if ( 'publish' == $post->post_status )
  4046 
       
  4047 	if ( 'publish' == $post->post_status ) {
  3765 		return;
  4048 		return;
       
  4049 	}
  3766 
  4050 
  3767 	$wpdb->update( $wpdb->posts, array( 'post_status' => 'publish' ), array( 'ID' => $post->ID ) );
  4051 	$wpdb->update( $wpdb->posts, array( 'post_status' => 'publish' ), array( 'ID' => $post->ID ) );
  3768 
  4052 
  3769 	clean_post_cache( $post->ID );
  4053 	clean_post_cache( $post->ID );
  3770 
  4054 
  3771 	$old_status = $post->post_status;
  4055 	$old_status        = $post->post_status;
  3772 	$post->post_status = 'publish';
  4056 	$post->post_status = 'publish';
  3773 	wp_transition_post_status( 'publish', $old_status, $post );
  4057 	wp_transition_post_status( 'publish', $old_status, $post );
  3774 
  4058 
  3775 	/** This action is documented in wp-includes/post.php */
  4059 	/** This action is documented in wp-includes/post.php */
       
  4060 	do_action( "edit_post_{$post->post_type}", $post->ID, $post );
       
  4061 
       
  4062 	/** This action is documented in wp-includes/post.php */
  3776 	do_action( 'edit_post', $post->ID, $post );
  4063 	do_action( 'edit_post', $post->ID, $post );
  3777 
  4064 
  3778 	/** This action is documented in wp-includes/post.php */
  4065 	/** This action is documented in wp-includes/post.php */
  3779 	do_action( "save_post_{$post->post_type}", $post->ID, $post, true );
  4066 	do_action( "save_post_{$post->post_type}", $post->ID, $post, true );
  3780 
  4067 
  3794  * @since 2.5.0
  4081  * @since 2.5.0
  3795  *
  4082  *
  3796  * @param int|WP_Post $post_id Post ID or post object.
  4083  * @param int|WP_Post $post_id Post ID or post object.
  3797  */
  4084  */
  3798 function check_and_publish_future_post( $post_id ) {
  4085 function check_and_publish_future_post( $post_id ) {
  3799 	$post = get_post($post_id);
  4086 	$post = get_post( $post_id );
  3800 
  4087 
  3801 	if ( empty($post) )
  4088 	if ( empty( $post ) ) {
  3802 		return;
  4089 		return;
  3803 
  4090 	}
  3804 	if ( 'future' != $post->post_status )
  4091 
       
  4092 	if ( 'future' != $post->post_status ) {
  3805 		return;
  4093 		return;
       
  4094 	}
  3806 
  4095 
  3807 	$time = strtotime( $post->post_date_gmt . ' GMT' );
  4096 	$time = strtotime( $post->post_date_gmt . ' GMT' );
  3808 
  4097 
  3809 	// Uh oh, someone jumped the gun!
  4098 	// Uh oh, someone jumped the gun!
  3810 	if ( $time > time() ) {
  4099 	if ( $time > time() ) {
  3831  * @param string $post_type   Post type.
  4120  * @param string $post_type   Post type.
  3832  * @param int    $post_parent Post parent ID.
  4121  * @param int    $post_parent Post parent ID.
  3833  * @return string Unique slug for the post, based on $post_name (with a -1, -2, etc. suffix)
  4122  * @return string Unique slug for the post, based on $post_name (with a -1, -2, etc. suffix)
  3834  */
  4123  */
  3835 function wp_unique_post_slug( $slug, $post_ID, $post_status, $post_type, $post_parent ) {
  4124 function wp_unique_post_slug( $slug, $post_ID, $post_status, $post_type, $post_parent ) {
  3836 	if ( in_array( $post_status, array( 'draft', 'pending', 'auto-draft' ) ) || ( 'inherit' == $post_status && 'revision' == $post_type ) || 'user_request' === $post_type )
  4125 	if ( in_array( $post_status, array( 'draft', 'pending', 'auto-draft' ) ) || ( 'inherit' == $post_status && 'revision' == $post_type ) || 'user_request' === $post_type ) {
  3837 		return $slug;
  4126 		return $slug;
       
  4127 	}
       
  4128 
       
  4129 	/**
       
  4130 	 * Filters the post slug before it is generated to be unique.
       
  4131 	 *
       
  4132 	 * Returning a non-null value will short-circuit the
       
  4133 	 * unique slug generation, returning the passed value instead.
       
  4134 	 *
       
  4135 	 * @since 5.1.0
       
  4136 	 *
       
  4137 	 * @param string $override_slug Short-circuit return value.
       
  4138 	 * @param string $slug          The desired slug (post_name).
       
  4139 	 * @param int    $post_ID       Post ID.
       
  4140 	 * @param string $post_status   The post status.
       
  4141 	 * @param string $post_type     Post type.
       
  4142 	 * @param int    $post_parent   Post parent ID.
       
  4143 	 */
       
  4144 	$override_slug = apply_filters( 'pre_wp_unique_post_slug', null, $slug, $post_ID, $post_status, $post_type, $post_parent );
       
  4145 	if ( null !== $override_slug ) {
       
  4146 		return $override_slug;
       
  4147 	}
  3838 
  4148 
  3839 	global $wpdb, $wp_rewrite;
  4149 	global $wpdb, $wp_rewrite;
  3840 
  4150 
  3841 	$original_slug = $slug;
  4151 	$original_slug = $slug;
  3842 
  4152 
  3843 	$feeds = $wp_rewrite->feeds;
  4153 	$feeds = $wp_rewrite->feeds;
  3844 	if ( ! is_array( $feeds ) )
  4154 	if ( ! is_array( $feeds ) ) {
  3845 		$feeds = array();
  4155 		$feeds = array();
       
  4156 	}
  3846 
  4157 
  3847 	if ( 'attachment' == $post_type ) {
  4158 	if ( 'attachment' == $post_type ) {
  3848 		// Attachment slugs must be unique across all types.
  4159 		// Attachment slugs must be unique across all types.
  3849 		$check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND ID != %d LIMIT 1";
  4160 		$check_sql       = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND ID != %d LIMIT 1";
  3850 		$post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_ID ) );
  4161 		$post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_ID ) );
  3851 
  4162 
  3852 		/**
  4163 		/**
  3853 		 * Filters whether the post slug would make a bad attachment slug.
  4164 		 * Filters whether the post slug would make a bad attachment slug.
  3854 		 *
  4165 		 *
  3858 		 * @param string $slug     The post slug.
  4169 		 * @param string $slug     The post slug.
  3859 		 */
  4170 		 */
  3860 		if ( $post_name_check || in_array( $slug, $feeds ) || 'embed' === $slug || apply_filters( 'wp_unique_post_slug_is_bad_attachment_slug', false, $slug ) ) {
  4171 		if ( $post_name_check || in_array( $slug, $feeds ) || 'embed' === $slug || apply_filters( 'wp_unique_post_slug_is_bad_attachment_slug', false, $slug ) ) {
  3861 			$suffix = 2;
  4172 			$suffix = 2;
  3862 			do {
  4173 			do {
  3863 				$alt_post_name = _truncate_post_slug( $slug, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
  4174 				$alt_post_name   = _truncate_post_slug( $slug, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
  3864 				$post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $alt_post_name, $post_ID ) );
  4175 				$post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $alt_post_name, $post_ID ) );
  3865 				$suffix++;
  4176 				$suffix++;
  3866 			} while ( $post_name_check );
  4177 			} while ( $post_name_check );
  3867 			$slug = $alt_post_name;
  4178 			$slug = $alt_post_name;
  3868 		}
  4179 		}
  3869 	} elseif ( is_post_type_hierarchical( $post_type ) ) {
  4180 	} elseif ( is_post_type_hierarchical( $post_type ) ) {
  3870 		if ( 'nav_menu_item' == $post_type )
  4181 		if ( 'nav_menu_item' == $post_type ) {
  3871 			return $slug;
  4182 			return $slug;
       
  4183 		}
  3872 
  4184 
  3873 		/*
  4185 		/*
  3874 		 * Page slugs must be unique within their own trees. Pages are in a separate
  4186 		 * Page slugs must be unique within their own trees. Pages are in a separate
  3875 		 * namespace than posts so page slugs are allowed to overlap post slugs.
  4187 		 * namespace than posts so page slugs are allowed to overlap post slugs.
  3876 		 */
  4188 		 */
  3877 		$check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type IN ( %s, 'attachment' ) AND ID != %d AND post_parent = %d LIMIT 1";
  4189 		$check_sql       = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type IN ( %s, 'attachment' ) AND ID != %d AND post_parent = %d LIMIT 1";
  3878 		$post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_type, $post_ID, $post_parent ) );
  4190 		$post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_type, $post_ID, $post_parent ) );
  3879 
  4191 
  3880 		/**
  4192 		/**
  3881 		 * Filters whether the post slug would make a bad hierarchical post slug.
  4193 		 * Filters whether the post slug would make a bad hierarchical post slug.
  3882 		 *
  4194 		 *
  3885 		 * @param bool   $bad_slug    Whether the post slug would be bad in a hierarchical post context.
  4197 		 * @param bool   $bad_slug    Whether the post slug would be bad in a hierarchical post context.
  3886 		 * @param string $slug        The post slug.
  4198 		 * @param string $slug        The post slug.
  3887 		 * @param string $post_type   Post type.
  4199 		 * @param string $post_type   Post type.
  3888 		 * @param int    $post_parent Post parent ID.
  4200 		 * @param int    $post_parent Post parent ID.
  3889 		 */
  4201 		 */
  3890 		if ( $post_name_check || in_array( $slug, $feeds ) || 'embed' === $slug || preg_match( "@^($wp_rewrite->pagination_base)?\d+$@", $slug )  || apply_filters( 'wp_unique_post_slug_is_bad_hierarchical_slug', false, $slug, $post_type, $post_parent ) ) {
  4202 		if ( $post_name_check || in_array( $slug, $feeds ) || 'embed' === $slug || preg_match( "@^($wp_rewrite->pagination_base)?\d+$@", $slug ) || apply_filters( 'wp_unique_post_slug_is_bad_hierarchical_slug', false, $slug, $post_type, $post_parent ) ) {
  3891 			$suffix = 2;
  4203 			$suffix = 2;
  3892 			do {
  4204 			do {
  3893 				$alt_post_name = _truncate_post_slug( $slug, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
  4205 				$alt_post_name   = _truncate_post_slug( $slug, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
  3894 				$post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $alt_post_name, $post_type, $post_ID, $post_parent ) );
  4206 				$post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $alt_post_name, $post_type, $post_ID, $post_parent ) );
  3895 				$suffix++;
  4207 				$suffix++;
  3896 			} while ( $post_name_check );
  4208 			} while ( $post_name_check );
  3897 			$slug = $alt_post_name;
  4209 			$slug = $alt_post_name;
  3898 		}
  4210 		}
  3899 	} else {
  4211 	} else {
  3900 		// Post slugs must be unique across all posts.
  4212 		// Post slugs must be unique across all posts.
  3901 		$check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type = %s AND ID != %d LIMIT 1";
  4213 		$check_sql       = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type = %s AND ID != %d LIMIT 1";
  3902 		$post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_type, $post_ID ) );
  4214 		$post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_type, $post_ID ) );
  3903 
  4215 
  3904 		// Prevent new post slugs that could result in URLs that conflict with date archives.
  4216 		// Prevent new post slugs that could result in URLs that conflict with date archives.
  3905 		$post = get_post( $post_ID );
  4217 		$post                        = get_post( $post_ID );
  3906 		$conflicts_with_date_archive = false;
  4218 		$conflicts_with_date_archive = false;
  3907 		if ( 'post' === $post_type && ( ! $post || $post->post_name !== $slug ) && preg_match( '/^[0-9]+$/', $slug ) && $slug_num = intval( $slug ) ) {
  4219 		if ( 'post' === $post_type && ( ! $post || $post->post_name !== $slug ) && preg_match( '/^[0-9]+$/', $slug ) && $slug_num = intval( $slug ) ) {
  3908 			$permastructs   = array_values( array_filter( explode( '/', get_option( 'permalink_structure' ) ) ) );
  4220 			$permastructs   = array_values( array_filter( explode( '/', get_option( 'permalink_structure' ) ) ) );
  3909 			$postname_index = array_search( '%postname%', $permastructs );
  4221 			$postname_index = array_search( '%postname%', $permastructs );
  3910 
  4222 
  3933 		 * @param string $post_type Post type.
  4245 		 * @param string $post_type Post type.
  3934 		 */
  4246 		 */
  3935 		if ( $post_name_check || in_array( $slug, $feeds ) || 'embed' === $slug || $conflicts_with_date_archive || apply_filters( 'wp_unique_post_slug_is_bad_flat_slug', false, $slug, $post_type ) ) {
  4247 		if ( $post_name_check || in_array( $slug, $feeds ) || 'embed' === $slug || $conflicts_with_date_archive || apply_filters( 'wp_unique_post_slug_is_bad_flat_slug', false, $slug, $post_type ) ) {
  3936 			$suffix = 2;
  4248 			$suffix = 2;
  3937 			do {
  4249 			do {
  3938 				$alt_post_name = _truncate_post_slug( $slug, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
  4250 				$alt_post_name   = _truncate_post_slug( $slug, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
  3939 				$post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $alt_post_name, $post_type, $post_ID ) );
  4251 				$post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $alt_post_name, $post_type, $post_ID ) );
  3940 				$suffix++;
  4252 				$suffix++;
  3941 			} while ( $post_name_check );
  4253 			} while ( $post_name_check );
  3942 			$slug = $alt_post_name;
  4254 			$slug = $alt_post_name;
  3943 		}
  4255 		}
  3971  * @return string The truncated slug.
  4283  * @return string The truncated slug.
  3972  */
  4284  */
  3973 function _truncate_post_slug( $slug, $length = 200 ) {
  4285 function _truncate_post_slug( $slug, $length = 200 ) {
  3974 	if ( strlen( $slug ) > $length ) {
  4286 	if ( strlen( $slug ) > $length ) {
  3975 		$decoded_slug = urldecode( $slug );
  4287 		$decoded_slug = urldecode( $slug );
  3976 		if ( $decoded_slug === $slug )
  4288 		if ( $decoded_slug === $slug ) {
  3977 			$slug = substr( $slug, 0, $length );
  4289 			$slug = substr( $slug, 0, $length );
  3978 		else
  4290 		} else {
  3979 			$slug = utf8_uri_encode( $decoded_slug, $length );
  4291 			$slug = utf8_uri_encode( $decoded_slug, $length );
       
  4292 		}
  3980 	}
  4293 	}
  3981 
  4294 
  3982 	return rtrim( $slug, '-' );
  4295 	return rtrim( $slug, '-' );
  3983 }
  4296 }
  3984 
  4297 
  3993  * @param string|array $tags    Optional. An array of tags to set for the post, or a string of tags
  4306  * @param string|array $tags    Optional. An array of tags to set for the post, or a string of tags
  3994  *                              separated by commas. Default empty.
  4307  *                              separated by commas. Default empty.
  3995  * @return array|false|WP_Error Array of affected term IDs. WP_Error or false on failure.
  4308  * @return array|false|WP_Error Array of affected term IDs. WP_Error or false on failure.
  3996  */
  4309  */
  3997 function wp_add_post_tags( $post_id = 0, $tags = '' ) {
  4310 function wp_add_post_tags( $post_id = 0, $tags = '' ) {
  3998 	return wp_set_post_tags($post_id, $tags, true);
  4311 	return wp_set_post_tags( $post_id, $tags, true );
  3999 }
  4312 }
  4000 
  4313 
  4001 /**
  4314 /**
  4002  * Set the tags for a post.
  4315  * Set the tags for a post.
  4003  *
  4316  *
  4011  * @param bool         $append  Optional. If true, don't delete existing tags, just add on. If false,
  4324  * @param bool         $append  Optional. If true, don't delete existing tags, just add on. If false,
  4012  *                              replace the tags with the new tags. Default false.
  4325  *                              replace the tags with the new tags. Default false.
  4013  * @return array|false|WP_Error Array of term taxonomy IDs of affected terms. WP_Error or false on failure.
  4326  * @return array|false|WP_Error Array of term taxonomy IDs of affected terms. WP_Error or false on failure.
  4014  */
  4327  */
  4015 function wp_set_post_tags( $post_id = 0, $tags = '', $append = false ) {
  4328 function wp_set_post_tags( $post_id = 0, $tags = '', $append = false ) {
  4016 	return wp_set_post_terms( $post_id, $tags, 'post_tag', $append);
  4329 	return wp_set_post_terms( $post_id, $tags, 'post_tag', $append );
  4017 }
  4330 }
  4018 
  4331 
  4019 /**
  4332 /**
  4020  * Set the terms for a post.
  4333  * Set the terms for a post.
  4021  *
  4334  *
  4023  *
  4336  *
  4024  * @see wp_set_object_terms()
  4337  * @see wp_set_object_terms()
  4025  *
  4338  *
  4026  * @param int          $post_id  Optional. The Post ID. Does not default to the ID of the global $post.
  4339  * @param int          $post_id  Optional. The Post ID. Does not default to the ID of the global $post.
  4027  * @param string|array $tags     Optional. An array of terms to set for the post, or a string of terms
  4340  * @param string|array $tags     Optional. An array of terms to set for the post, or a string of terms
  4028  *                               separated by commas. Default empty.
  4341  *                               separated by commas. Hierarchical taxonomies must always pass IDs rather
       
  4342  *                               than names so that children with the same names but different parents
       
  4343  *                               aren't confused. Default empty.
  4029  * @param string       $taxonomy Optional. Taxonomy name. Default 'post_tag'.
  4344  * @param string       $taxonomy Optional. Taxonomy name. Default 'post_tag'.
  4030  * @param bool         $append   Optional. If true, don't delete existing terms, just add on. If false,
  4345  * @param bool         $append   Optional. If true, don't delete existing terms, just add on. If false,
  4031  *                               replace the terms with the new terms. Default false.
  4346  *                               replace the terms with the new terms. Default false.
  4032  * @return array|false|WP_Error Array of term taxonomy IDs of affected terms. WP_Error or false on failure.
  4347  * @return array|false|WP_Error Array of term taxonomy IDs of affected terms. WP_Error or false on failure.
  4033  */
  4348  */
  4034 function wp_set_post_terms( $post_id = 0, $tags = '', $taxonomy = 'post_tag', $append = false ) {
  4349 function wp_set_post_terms( $post_id = 0, $tags = '', $taxonomy = 'post_tag', $append = false ) {
  4035 	$post_id = (int) $post_id;
  4350 	$post_id = (int) $post_id;
  4036 
  4351 
  4037 	if ( !$post_id )
  4352 	if ( ! $post_id ) {
  4038 		return false;
  4353 		return false;
  4039 
  4354 	}
  4040 	if ( empty($tags) )
  4355 
       
  4356 	if ( empty( $tags ) ) {
  4041 		$tags = array();
  4357 		$tags = array();
       
  4358 	}
  4042 
  4359 
  4043 	if ( ! is_array( $tags ) ) {
  4360 	if ( ! is_array( $tags ) ) {
  4044 		$comma = _x( ',', 'tag delimiter' );
  4361 		$comma = _x( ',', 'tag delimiter' );
  4045 		if ( ',' !== $comma )
  4362 		if ( ',' !== $comma ) {
  4046 			$tags = str_replace( $comma, ',', $tags );
  4363 			$tags = str_replace( $comma, ',', $tags );
       
  4364 		}
  4047 		$tags = explode( ',', trim( $tags, " \n\t\r\0\x0B," ) );
  4365 		$tags = explode( ',', trim( $tags, " \n\t\r\0\x0B," ) );
  4048 	}
  4366 	}
  4049 
  4367 
  4050 	/*
  4368 	/*
  4051 	 * Hierarchical taxonomies must always pass IDs rather than names so that
  4369 	 * Hierarchical taxonomies must always pass IDs rather than names so that
  4066  *
  4384  *
  4067  * @since 2.1.0
  4385  * @since 2.1.0
  4068  *
  4386  *
  4069  * @param int       $post_ID         Optional. The Post ID. Does not default to the ID
  4387  * @param int       $post_ID         Optional. The Post ID. Does not default to the ID
  4070  *                                   of the global $post. Default 0.
  4388  *                                   of the global $post. Default 0.
  4071  * @param array|int $post_categories Optional. List of categories or ID of category.
  4389  * @param array|int $post_categories Optional. List of category IDs, or the ID of a single category.
  4072  *                                   Default empty array.
  4390  *                                   Default empty array.
  4073  * @param bool      $append         If true, don't delete existing categories, just add on.
  4391  * @param bool      $append          If true, don't delete existing categories, just add on.
  4074  *                                  If false, replace the categories with the new categories.
  4392  *                                   If false, replace the categories with the new categories.
  4075  * @return array|false|WP_Error Array of term taxonomy IDs of affected categories. WP_Error or false on failure.
  4393  * @return array|false|WP_Error Array of term taxonomy IDs of affected categories. WP_Error or false on failure.
  4076  */
  4394  */
  4077 function wp_set_post_categories( $post_ID = 0, $post_categories = array(), $append = false ) {
  4395 function wp_set_post_categories( $post_ID = 0, $post_categories = array(), $append = false ) {
  4078 	$post_ID = (int) $post_ID;
  4396 	$post_ID     = (int) $post_ID;
  4079 	$post_type = get_post_type( $post_ID );
  4397 	$post_type   = get_post_type( $post_ID );
  4080 	$post_status = get_post_status( $post_ID );
  4398 	$post_status = get_post_status( $post_ID );
  4081 	// If $post_categories isn't already an array, make it one:
  4399 	// If $post_categories isn't already an array, make it one:
  4082 	$post_categories = (array) $post_categories;
  4400 	$post_categories = (array) $post_categories;
  4083 	if ( empty( $post_categories ) ) {
  4401 	if ( empty( $post_categories ) ) {
  4084 		if ( 'post' == $post_type && 'auto-draft' != $post_status ) {
  4402 		if ( 'post' == $post_type && 'auto-draft' != $post_status ) {
  4085 			$post_categories = array( get_option('default_category') );
  4403 			$post_categories = array( get_option( 'default_category' ) );
  4086 			$append = false;
  4404 			$append          = false;
  4087 		} else {
  4405 		} else {
  4088 			$post_categories = array();
  4406 			$post_categories = array();
  4089 		}
  4407 		}
  4090 	} elseif ( 1 == count( $post_categories ) && '' == reset( $post_categories ) ) {
  4408 	} elseif ( 1 == count( $post_categories ) && '' == reset( $post_categories ) ) {
  4091 		return true;
  4409 		return true;
  4167 
  4485 
  4168 /**
  4486 /**
  4169  * Add a URL to those already pinged.
  4487  * Add a URL to those already pinged.
  4170  *
  4488  *
  4171  * @since 1.5.0
  4489  * @since 1.5.0
  4172  * @since 4.7.0 $post_id can be a WP_Post object.
  4490  * @since 4.7.0 `$post_id` can be a WP_Post object.
  4173  * @since 4.7.0 $uri can be an array of URIs.
  4491  * @since 4.7.0 `$uri` can be an array of URIs.
  4174  *
  4492  *
  4175  * @global wpdb $wpdb WordPress database abstraction object.
  4493  * @global wpdb $wpdb WordPress database abstraction object.
  4176  *
  4494  *
  4177  * @param int|WP_Post  $post_id Post object or ID.
  4495  * @param int|WP_Post  $post_id Post object or ID.
  4178  * @param string|array $uri     Ping URI or array of URIs.
  4496  * @param string|array $uri     Ping URI or array of URIs.
  4189 	$pung = trim( $post->pinged );
  4507 	$pung = trim( $post->pinged );
  4190 	$pung = preg_split( '/\s/', $pung );
  4508 	$pung = preg_split( '/\s/', $pung );
  4191 
  4509 
  4192 	if ( is_array( $uri ) ) {
  4510 	if ( is_array( $uri ) ) {
  4193 		$pung = array_merge( $pung, $uri );
  4511 		$pung = array_merge( $pung, $uri );
  4194 	}
  4512 	} else {
  4195 	else {
       
  4196 		$pung[] = $uri;
  4513 		$pung[] = $uri;
  4197 	}
  4514 	}
  4198 	$new = implode("\n", $pung);
  4515 	$new = implode( "\n", $pung );
  4199 
  4516 
  4200 	/**
  4517 	/**
  4201 	 * Filters the new ping URL to add for the given post.
  4518 	 * Filters the new ping URL to add for the given post.
  4202 	 *
  4519 	 *
  4203 	 * @since 2.0.0
  4520 	 * @since 2.0.0
  4219  * @param int $post_id Post ID.
  4536  * @param int $post_id Post ID.
  4220  * @return array List of enclosures.
  4537  * @return array List of enclosures.
  4221  */
  4538  */
  4222 function get_enclosed( $post_id ) {
  4539 function get_enclosed( $post_id ) {
  4223 	$custom_fields = get_post_custom( $post_id );
  4540 	$custom_fields = get_post_custom( $post_id );
  4224 	$pung = array();
  4541 	$pung          = array();
  4225 	if ( !is_array( $custom_fields ) )
  4542 	if ( ! is_array( $custom_fields ) ) {
  4226 		return $pung;
  4543 		return $pung;
       
  4544 	}
  4227 
  4545 
  4228 	foreach ( $custom_fields as $key => $val ) {
  4546 	foreach ( $custom_fields as $key => $val ) {
  4229 		if ( 'enclosure' != $key || !is_array( $val ) )
  4547 		if ( 'enclosure' != $key || ! is_array( $val ) ) {
  4230 			continue;
  4548 			continue;
       
  4549 		}
  4231 		foreach ( $val as $enc ) {
  4550 		foreach ( $val as $enc ) {
  4232 			$enclosure = explode( "\n", $enc );
  4551 			$enclosure = explode( "\n", $enc );
  4233 			$pung[] = trim( $enclosure[ 0 ] );
  4552 			$pung[]    = trim( $enclosure[0] );
  4234 		}
  4553 		}
  4235 	}
  4554 	}
  4236 
  4555 
  4237 	/**
  4556 	/**
  4238 	 * Filters the list of enclosures already enclosed for the given post.
  4557 	 * Filters the list of enclosures already enclosed for the given post.
  4248 /**
  4567 /**
  4249  * Retrieve URLs already pinged for a post.
  4568  * Retrieve URLs already pinged for a post.
  4250  *
  4569  *
  4251  * @since 1.5.0
  4570  * @since 1.5.0
  4252  *
  4571  *
  4253  * @since 4.7.0 $post_id can be a WP_Post object.
  4572  * @since 4.7.0 `$post_id` can be a WP_Post object.
  4254  *
  4573  *
  4255  * @param int|WP_Post $post_id Post ID or object.
  4574  * @param int|WP_Post $post_id Post ID or object.
  4256  * @return array
  4575  * @return bool|string[] Array of URLs already pinged for the given post, false if the post is not found.
  4257  */
  4576  */
  4258 function get_pung( $post_id ) {
  4577 function get_pung( $post_id ) {
  4259 	$post = get_post( $post_id );
  4578 	$post = get_post( $post_id );
  4260 	if ( ! $post ) {
  4579 	if ( ! $post ) {
  4261 		return false;
  4580 		return false;
  4267 	/**
  4586 	/**
  4268 	 * Filters the list of already-pinged URLs for the given post.
  4587 	 * Filters the list of already-pinged URLs for the given post.
  4269 	 *
  4588 	 *
  4270 	 * @since 2.0.0
  4589 	 * @since 2.0.0
  4271 	 *
  4590 	 *
  4272 	 * @param array $pung Array of URLs already pinged for the given post.
  4591 	 * @param string[] $pung Array of URLs already pinged for the given post.
  4273 	 */
  4592 	 */
  4274 	return apply_filters( 'get_pung', $pung );
  4593 	return apply_filters( 'get_pung', $pung );
  4275 }
  4594 }
  4276 
  4595 
  4277 /**
  4596 /**
  4278  * Retrieve URLs that need to be pinged.
  4597  * Retrieve URLs that need to be pinged.
  4279  *
  4598  *
  4280  * @since 1.5.0
  4599  * @since 1.5.0
  4281  * @since 4.7.0 $post_id can be a WP_Post object.
  4600  * @since 4.7.0 `$post_id` can be a WP_Post object.
  4282  *
  4601  *
  4283  * @param int|WP_Post $post_id Post Object or ID
  4602  * @param int|WP_Post $post_id Post Object or ID
  4284  * @return array
  4603  * @return array
  4285  */
  4604  */
  4286 function get_to_ping( $post_id ) {
  4605 function get_to_ping( $post_id ) {
  4289 	if ( ! $post ) {
  4608 	if ( ! $post ) {
  4290 		return false;
  4609 		return false;
  4291 	}
  4610 	}
  4292 
  4611 
  4293 	$to_ping = sanitize_trackback_urls( $post->to_ping );
  4612 	$to_ping = sanitize_trackback_urls( $post->to_ping );
  4294 	$to_ping = preg_split('/\s/', $to_ping, -1, PREG_SPLIT_NO_EMPTY);
  4613 	$to_ping = preg_split( '/\s/', $to_ping, -1, PREG_SPLIT_NO_EMPTY );
  4295 
  4614 
  4296 	/**
  4615 	/**
  4297 	 * Filters the list of URLs yet to ping for the given post.
  4616 	 * Filters the list of URLs yet to ping for the given post.
  4298 	 *
  4617 	 *
  4299 	 * @since 2.0.0
  4618 	 * @since 2.0.0
  4345  * @return array List of page IDs.
  4664  * @return array List of page IDs.
  4346  */
  4665  */
  4347 function get_all_page_ids() {
  4666 function get_all_page_ids() {
  4348 	global $wpdb;
  4667 	global $wpdb;
  4349 
  4668 
  4350 	$page_ids = wp_cache_get('all_page_ids', 'posts');
  4669 	$page_ids = wp_cache_get( 'all_page_ids', 'posts' );
  4351 	if ( ! is_array( $page_ids ) ) {
  4670 	if ( ! is_array( $page_ids ) ) {
  4352 		$page_ids = $wpdb->get_col("SELECT ID FROM $wpdb->posts WHERE post_type = 'page'");
  4671 		$page_ids = $wpdb->get_col( "SELECT ID FROM $wpdb->posts WHERE post_type = 'page'" );
  4353 		wp_cache_add('all_page_ids', $page_ids, 'posts');
  4672 		wp_cache_add( 'all_page_ids', $page_ids, 'posts' );
  4354 	}
  4673 	}
  4355 
  4674 
  4356 	return $page_ids;
  4675 	return $page_ids;
  4357 }
  4676 }
  4358 
  4677 
  4369  *                       a WP_Post object, an associative array, or a numeric array, respectively. Default OBJECT.
  4688  *                       a WP_Post object, an associative array, or a numeric array, respectively. Default OBJECT.
  4370  * @param string $filter Optional. How the return value should be filtered. Accepts 'raw',
  4689  * @param string $filter Optional. How the return value should be filtered. Accepts 'raw',
  4371  *                       'edit', 'db', 'display'. Default 'raw'.
  4690  *                       'edit', 'db', 'display'. Default 'raw'.
  4372  * @return WP_Post|array|null WP_Post (or array) on success, or null on failure.
  4691  * @return WP_Post|array|null WP_Post (or array) on success, or null on failure.
  4373  */
  4692  */
  4374 function get_page( $page, $output = OBJECT, $filter = 'raw') {
  4693 function get_page( $page, $output = OBJECT, $filter = 'raw' ) {
  4375 	return get_post( $page, $output, $filter );
  4694 	return get_post( $page, $output, $filter );
  4376 }
  4695 }
  4377 
  4696 
  4378 /**
  4697 /**
  4379  * Retrieves a page given its path.
  4698  * Retrieves a page given its path.
  4391 function get_page_by_path( $page_path, $output = OBJECT, $post_type = 'page' ) {
  4710 function get_page_by_path( $page_path, $output = OBJECT, $post_type = 'page' ) {
  4392 	global $wpdb;
  4711 	global $wpdb;
  4393 
  4712 
  4394 	$last_changed = wp_cache_get_last_changed( 'posts' );
  4713 	$last_changed = wp_cache_get_last_changed( 'posts' );
  4395 
  4714 
  4396 	$hash = md5( $page_path . serialize( $post_type ) );
  4715 	$hash      = md5( $page_path . serialize( $post_type ) );
  4397 	$cache_key = "get_page_by_path:$hash:$last_changed";
  4716 	$cache_key = "get_page_by_path:$hash:$last_changed";
  4398 	$cached = wp_cache_get( $cache_key, 'posts' );
  4717 	$cached    = wp_cache_get( $cache_key, 'posts' );
  4399 	if ( false !== $cached ) {
  4718 	if ( false !== $cached ) {
  4400 		// Special case: '0' is a bad `$page_path`.
  4719 		// Special case: '0' is a bad `$page_path`.
  4401 		if ( '0' === $cached || 0 === $cached ) {
  4720 		if ( '0' === $cached || 0 === $cached ) {
  4402 			return;
  4721 			return;
  4403 		} else {
  4722 		} else {
  4404 			return get_post( $cached, $output );
  4723 			return get_post( $cached, $output );
  4405 		}
  4724 		}
  4406 	}
  4725 	}
  4407 
  4726 
  4408 	$page_path = rawurlencode(urldecode($page_path));
  4727 	$page_path     = rawurlencode( urldecode( $page_path ) );
  4409 	$page_path = str_replace('%2F', '/', $page_path);
  4728 	$page_path     = str_replace( '%2F', '/', $page_path );
  4410 	$page_path = str_replace('%20', ' ', $page_path);
  4729 	$page_path     = str_replace( '%20', ' ', $page_path );
  4411 	$parts = explode( '/', trim( $page_path, '/' ) );
  4730 	$parts         = explode( '/', trim( $page_path, '/' ) );
  4412 	$parts = array_map( 'sanitize_title_for_query', $parts );
  4731 	$parts         = array_map( 'sanitize_title_for_query', $parts );
  4413 	$escaped_parts = esc_sql( $parts );
  4732 	$escaped_parts = esc_sql( $parts );
  4414 
  4733 
  4415 	$in_string = "'" . implode( "','", $escaped_parts ) . "'";
  4734 	$in_string = "'" . implode( "','", $escaped_parts ) . "'";
  4416 
  4735 
  4417 	if ( is_array( $post_type ) ) {
  4736 	if ( is_array( $post_type ) ) {
  4418 		$post_types = $post_type;
  4737 		$post_types = $post_type;
  4419 	} else {
  4738 	} else {
  4420 		$post_types = array( $post_type, 'attachment' );
  4739 		$post_types = array( $post_type, 'attachment' );
  4421 	}
  4740 	}
  4422 
  4741 
  4423 	$post_types = esc_sql( $post_types );
  4742 	$post_types          = esc_sql( $post_types );
  4424 	$post_type_in_string = "'" . implode( "','", $post_types ) . "'";
  4743 	$post_type_in_string = "'" . implode( "','", $post_types ) . "'";
  4425 	$sql = "
  4744 	$sql                 = "
  4426 		SELECT ID, post_name, post_parent, post_type
  4745 		SELECT ID, post_name, post_parent, post_type
  4427 		FROM $wpdb->posts
  4746 		FROM $wpdb->posts
  4428 		WHERE post_name IN ($in_string)
  4747 		WHERE post_name IN ($in_string)
  4429 		AND post_type IN ($post_type_in_string)
  4748 		AND post_type IN ($post_type_in_string)
  4430 	";
  4749 	";
  4435 
  4754 
  4436 	$foundid = 0;
  4755 	$foundid = 0;
  4437 	foreach ( (array) $pages as $page ) {
  4756 	foreach ( (array) $pages as $page ) {
  4438 		if ( $page->post_name == $revparts[0] ) {
  4757 		if ( $page->post_name == $revparts[0] ) {
  4439 			$count = 0;
  4758 			$count = 0;
  4440 			$p = $page;
  4759 			$p     = $page;
  4441 
  4760 
  4442 			/*
  4761 			/*
  4443 			 * Loop through the given path parts from right to left,
  4762 			 * Loop through the given path parts from right to left,
  4444 			 * ensuring each matches the post ancestry.
  4763 			 * ensuring each matches the post ancestry.
  4445 			 */
  4764 			 */
  4446 			while ( $p->post_parent != 0 && isset( $pages[ $p->post_parent ] ) ) {
  4765 			while ( $p->post_parent != 0 && isset( $pages[ $p->post_parent ] ) ) {
  4447 				$count++;
  4766 				$count++;
  4448 				$parent = $pages[ $p->post_parent ];
  4767 				$parent = $pages[ $p->post_parent ];
  4449 				if ( ! isset( $revparts[ $count ] ) || $parent->post_name != $revparts[ $count ] )
  4768 				if ( ! isset( $revparts[ $count ] ) || $parent->post_name != $revparts[ $count ] ) {
  4450 					break;
  4769 					break;
       
  4770 				}
  4451 				$p = $parent;
  4771 				$p = $parent;
  4452 			}
  4772 			}
  4453 
  4773 
  4454 			if ( $p->post_parent == 0 && $count+1 == count( $revparts ) && $p->post_name == $revparts[ $count ] ) {
  4774 			if ( $p->post_parent == 0 && $count + 1 == count( $revparts ) && $p->post_name == $revparts[ $count ] ) {
  4455 				$foundid = $page->ID;
  4775 				$foundid = $page->ID;
  4456 				if ( $page->post_type == $post_type )
  4776 				if ( $page->post_type == $post_type ) {
  4457 					break;
  4777 					break;
       
  4778 				}
  4458 			}
  4779 			}
  4459 		}
  4780 		}
  4460 	}
  4781 	}
  4461 
  4782 
  4462 	// We cache misses as well as hits.
  4783 	// We cache misses as well as hits.
  4482  */
  4803  */
  4483 function get_page_by_title( $page_title, $output = OBJECT, $post_type = 'page' ) {
  4804 function get_page_by_title( $page_title, $output = OBJECT, $post_type = 'page' ) {
  4484 	global $wpdb;
  4805 	global $wpdb;
  4485 
  4806 
  4486 	if ( is_array( $post_type ) ) {
  4807 	if ( is_array( $post_type ) ) {
  4487 		$post_type = esc_sql( $post_type );
  4808 		$post_type           = esc_sql( $post_type );
  4488 		$post_type_in_string = "'" . implode( "','", $post_type ) . "'";
  4809 		$post_type_in_string = "'" . implode( "','", $post_type ) . "'";
  4489 		$sql = $wpdb->prepare( "
  4810 		$sql                 = $wpdb->prepare(
       
  4811 			"
  4490 			SELECT ID
  4812 			SELECT ID
  4491 			FROM $wpdb->posts
  4813 			FROM $wpdb->posts
  4492 			WHERE post_title = %s
  4814 			WHERE post_title = %s
  4493 			AND post_type IN ($post_type_in_string)
  4815 			AND post_type IN ($post_type_in_string)
  4494 		", $page_title );
  4816 		",
       
  4817 			$page_title
       
  4818 		);
  4495 	} else {
  4819 	} else {
  4496 		$sql = $wpdb->prepare( "
  4820 		$sql = $wpdb->prepare(
       
  4821 			"
  4497 			SELECT ID
  4822 			SELECT ID
  4498 			FROM $wpdb->posts
  4823 			FROM $wpdb->posts
  4499 			WHERE post_title = %s
  4824 			WHERE post_title = %s
  4500 			AND post_type = %s
  4825 			AND post_type = %s
  4501 		", $page_title, $post_type );
  4826 		",
       
  4827 			$page_title,
       
  4828 			$post_type
       
  4829 		);
  4502 	}
  4830 	}
  4503 
  4831 
  4504 	$page = $wpdb->get_var( $sql );
  4832 	$page = $wpdb->get_var( $sql );
  4505 
  4833 
  4506 	if ( $page ) {
  4834 	if ( $page ) {
  4532 	if ( isset( $children[ $page_id ] ) ) {
  4860 	if ( isset( $children[ $page_id ] ) ) {
  4533 		// Always start at the end of the stack in order to preserve original `$pages` order.
  4861 		// Always start at the end of the stack in order to preserve original `$pages` order.
  4534 		$to_look = array_reverse( $children[ $page_id ] );
  4862 		$to_look = array_reverse( $children[ $page_id ] );
  4535 
  4863 
  4536 		while ( $to_look ) {
  4864 		while ( $to_look ) {
  4537 			$p = array_pop( $to_look );
  4865 			$p           = array_pop( $to_look );
  4538 			$page_list[] = $p;
  4866 			$page_list[] = $p;
  4539 			if ( isset( $children[ $p->ID ] ) ) {
  4867 			if ( isset( $children[ $p->ID ] ) ) {
  4540 				foreach ( array_reverse( $children[ $p->ID ] ) as $child ) {
  4868 				foreach ( array_reverse( $children[ $p->ID ] ) as $child ) {
  4541 					// Append to the `$to_look` stack to descend the tree.
  4869 					// Append to the `$to_look` stack to descend the tree.
  4542 					$to_look[] = $child;
  4870 					$to_look[] = $child;
  4565 		return array();
  4893 		return array();
  4566 	}
  4894 	}
  4567 
  4895 
  4568 	$children = array();
  4896 	$children = array();
  4569 	foreach ( (array) $pages as $p ) {
  4897 	foreach ( (array) $pages as $p ) {
  4570 		$parent_id = intval( $p->post_parent );
  4898 		$parent_id                = intval( $p->post_parent );
  4571 		$children[ $parent_id ][] = $p;
  4899 		$children[ $parent_id ][] = $p;
  4572 	}
  4900 	}
  4573 
  4901 
  4574 	$result = array();
  4902 	$result = array();
  4575 	_page_traverse_name( $page_id, $children, $result );
  4903 	_page_traverse_name( $page_id, $children, $result );
  4581  * Traverse and return all the nested children post names of a root page.
  4909  * Traverse and return all the nested children post names of a root page.
  4582  *
  4910  *
  4583  * $children contains parent-children relations
  4911  * $children contains parent-children relations
  4584  *
  4912  *
  4585  * @since 2.9.0
  4913  * @since 2.9.0
       
  4914  * @access private
  4586  *
  4915  *
  4587  * @see _page_traverse_name()
  4916  * @see _page_traverse_name()
  4588  *
  4917  *
  4589  * @param int   $page_id   Page ID.
  4918  * @param int   $page_id   Page ID.
  4590  * @param array $children  Parent-children relations (passed by reference).
  4919  * @param array $children  Parent-children relations (passed by reference).
  4591  * @param array $result    Result (passed by reference).
  4920  * @param array $result    Result (passed by reference).
  4592  */
  4921  */
  4593 function _page_traverse_name( $page_id, &$children, &$result ){
  4922 function _page_traverse_name( $page_id, &$children, &$result ) {
  4594 	if ( isset( $children[ $page_id ] ) ){
  4923 	if ( isset( $children[ $page_id ] ) ) {
  4595 		foreach ( (array)$children[ $page_id ] as $child ) {
  4924 		foreach ( (array) $children[ $page_id ] as $child ) {
  4596 			$result[ $child->ID ] = $child->post_name;
  4925 			$result[ $child->ID ] = $child->post_name;
  4597 			_page_traverse_name( $child->ID, $children, $result );
  4926 			_page_traverse_name( $child->ID, $children, $result );
  4598 		}
  4927 		}
  4599 	}
  4928 	}
  4600 }
  4929 }
  4613 function get_page_uri( $page = 0 ) {
  4942 function get_page_uri( $page = 0 ) {
  4614 	if ( ! $page instanceof WP_Post ) {
  4943 	if ( ! $page instanceof WP_Post ) {
  4615 		$page = get_post( $page );
  4944 		$page = get_post( $page );
  4616 	}
  4945 	}
  4617 
  4946 
  4618 	if ( ! $page )
  4947 	if ( ! $page ) {
  4619 		return false;
  4948 		return false;
       
  4949 	}
  4620 
  4950 
  4621 	$uri = $page->post_name;
  4951 	$uri = $page->post_name;
  4622 
  4952 
  4623 	foreach ( $page->ancestors as $parent ) {
  4953 	foreach ( $page->ancestors as $parent ) {
  4624 		$parent = get_post( $parent );
  4954 		$parent = get_post( $parent );
  4701 		'post_status'  => 'publish',
  5031 		'post_status'  => 'publish',
  4702 	);
  5032 	);
  4703 
  5033 
  4704 	$r = wp_parse_args( $args, $defaults );
  5034 	$r = wp_parse_args( $args, $defaults );
  4705 
  5035 
  4706 	$number = (int) $r['number'];
  5036 	$number       = (int) $r['number'];
  4707 	$offset = (int) $r['offset'];
  5037 	$offset       = (int) $r['offset'];
  4708 	$child_of = (int) $r['child_of'];
  5038 	$child_of     = (int) $r['child_of'];
  4709 	$hierarchical = $r['hierarchical'];
  5039 	$hierarchical = $r['hierarchical'];
  4710 	$exclude = $r['exclude'];
  5040 	$exclude      = $r['exclude'];
  4711 	$meta_key = $r['meta_key'];
  5041 	$meta_key     = $r['meta_key'];
  4712 	$meta_value = $r['meta_value'];
  5042 	$meta_value   = $r['meta_value'];
  4713 	$parent = $r['parent'];
  5043 	$parent       = $r['parent'];
  4714 	$post_status = $r['post_status'];
  5044 	$post_status  = $r['post_status'];
  4715 
  5045 
  4716 	// Make sure the post type is hierarchical.
  5046 	// Make sure the post type is hierarchical.
  4717 	$hierarchical_post_types = get_post_types( array( 'hierarchical' => true ) );
  5047 	$hierarchical_post_types = get_post_types( array( 'hierarchical' => true ) );
  4718 	if ( ! in_array( $r['post_type'], $hierarchical_post_types ) ) {
  5048 	if ( ! in_array( $r['post_type'], $hierarchical_post_types ) ) {
  4719 		return false;
  5049 		return false;
  4730 	if ( array_diff( $post_status, get_post_stati() ) ) {
  5060 	if ( array_diff( $post_status, get_post_stati() ) ) {
  4731 		return false;
  5061 		return false;
  4732 	}
  5062 	}
  4733 
  5063 
  4734 	// $args can be whatever, only use the args defined in defaults to compute the key.
  5064 	// $args can be whatever, only use the args defined in defaults to compute the key.
  4735 	$key = md5( serialize( wp_array_slice_assoc( $r, array_keys( $defaults ) ) ) );
  5065 	$key          = md5( serialize( wp_array_slice_assoc( $r, array_keys( $defaults ) ) ) );
  4736 	$last_changed = wp_cache_get_last_changed( 'posts' );
  5066 	$last_changed = wp_cache_get_last_changed( 'posts' );
  4737 
  5067 
  4738 	$cache_key = "get_pages:$key:$last_changed";
  5068 	$cache_key = "get_pages:$key:$last_changed";
  4739 	if ( $cache = wp_cache_get( $cache_key, 'posts' ) ) {
  5069 	$cache     = wp_cache_get( $cache_key, 'posts' );
       
  5070 	if ( false !== $cache ) {
  4740 		// Convert to WP_Post instances.
  5071 		// Convert to WP_Post instances.
  4741 		$pages = array_map( 'get_post', $cache );
  5072 		$pages = array_map( 'get_post', $cache );
  4742 		/** This filter is documented in wp-includes/post.php */
  5073 		/** This filter is documented in wp-includes/post.php */
  4743 		$pages = apply_filters( 'get_pages', $pages, $r );
  5074 		$pages = apply_filters( 'get_pages', $pages, $r );
  4744 		return $pages;
  5075 		return $pages;
  4745 	}
  5076 	}
  4746 
  5077 
  4747 	$inclusions = '';
  5078 	$inclusions = '';
  4748 	if ( ! empty( $r['include'] ) ) {
  5079 	if ( ! empty( $r['include'] ) ) {
  4749 		$child_of = 0; //ignore child_of, parent, exclude, meta_key, and meta_value params if using include
  5080 		$child_of     = 0; //ignore child_of, parent, exclude, meta_key, and meta_value params if using include
  4750 		$parent = -1;
  5081 		$parent       = -1;
  4751 		$exclude = '';
  5082 		$exclude      = '';
  4752 		$meta_key = '';
  5083 		$meta_key     = '';
  4753 		$meta_value = '';
  5084 		$meta_value   = '';
  4754 		$hierarchical = false;
  5085 		$hierarchical = false;
  4755 		$incpages = wp_parse_id_list( $r['include'] );
  5086 		$incpages     = wp_parse_id_list( $r['include'] );
  4756 		if ( ! empty( $incpages ) ) {
  5087 		if ( ! empty( $incpages ) ) {
  4757 			$inclusions = ' AND ID IN (' . implode( ',', $incpages ) .  ')';
  5088 			$inclusions = ' AND ID IN (' . implode( ',', $incpages ) . ')';
  4758 		}
  5089 		}
  4759 	}
  5090 	}
  4760 
  5091 
  4761 	$exclusions = '';
  5092 	$exclusions = '';
  4762 	if ( ! empty( $exclude ) ) {
  5093 	if ( ! empty( $exclude ) ) {
  4763 		$expages = wp_parse_id_list( $exclude );
  5094 		$expages = wp_parse_id_list( $exclude );
  4764 		if ( ! empty( $expages ) ) {
  5095 		if ( ! empty( $expages ) ) {
  4765 			$exclusions = ' AND ID NOT IN (' . implode( ',', $expages ) .  ')';
  5096 			$exclusions = ' AND ID NOT IN (' . implode( ',', $expages ) . ')';
  4766 		}
  5097 		}
  4767 	}
  5098 	}
  4768 
  5099 
  4769 	$author_query = '';
  5100 	$author_query = '';
  4770 	if ( ! empty( $r['authors'] ) ) {
  5101 	if ( ! empty( $r['authors'] ) ) {
  4771 		$post_authors = preg_split( '/[\s,]+/', $r['authors'] );
  5102 		$post_authors = wp_parse_list( $r['authors'] );
  4772 
  5103 
  4773 		if ( ! empty( $post_authors ) ) {
  5104 		if ( ! empty( $post_authors ) ) {
  4774 			foreach ( $post_authors as $post_author ) {
  5105 			foreach ( $post_authors as $post_author ) {
  4775 				//Do we have an author id or an author login?
  5106 				//Do we have an author id or an author login?
  4776 				if ( 0 == intval($post_author) ) {
  5107 				if ( 0 == intval( $post_author ) ) {
  4777 					$post_author = get_user_by('login', $post_author);
  5108 					$post_author = get_user_by( 'login', $post_author );
  4778 					if ( empty( $post_author ) ) {
  5109 					if ( empty( $post_author ) ) {
  4779 						continue;
  5110 						continue;
  4780 					}
  5111 					}
  4781 					if ( empty( $post_author->ID ) ) {
  5112 					if ( empty( $post_author->ID ) ) {
  4782 						continue;
  5113 						continue;
  4783 					}
  5114 					}
  4784 					$post_author = $post_author->ID;
  5115 					$post_author = $post_author->ID;
  4785 				}
  5116 				}
  4786 
  5117 
  4787 				if ( '' == $author_query ) {
  5118 				if ( '' == $author_query ) {
  4788 					$author_query = $wpdb->prepare(' post_author = %d ', $post_author);
  5119 					$author_query = $wpdb->prepare( ' post_author = %d ', $post_author );
  4789 				} else {
  5120 				} else {
  4790 					$author_query .= $wpdb->prepare(' OR post_author = %d ', $post_author);
  5121 					$author_query .= $wpdb->prepare( ' OR post_author = %d ', $post_author );
  4791 				}
  5122 				}
  4792 			}
  5123 			}
  4793 			if ( '' != $author_query ) {
  5124 			if ( '' != $author_query ) {
  4794 				$author_query = " AND ($author_query)";
  5125 				$author_query = " AND ($author_query)";
  4795 			}
  5126 			}
  4796 		}
  5127 		}
  4797 	}
  5128 	}
  4798 
  5129 
  4799 	$join = '';
  5130 	$join  = '';
  4800 	$where = "$exclusions $inclusions ";
  5131 	$where = "$exclusions $inclusions ";
  4801 	if ( '' !== $meta_key || '' !== $meta_value ) {
  5132 	if ( '' !== $meta_key || '' !== $meta_value ) {
  4802 		$join = " LEFT JOIN $wpdb->postmeta ON ( $wpdb->posts.ID = $wpdb->postmeta.post_id )";
  5133 		$join = " LEFT JOIN $wpdb->postmeta ON ( $wpdb->posts.ID = $wpdb->postmeta.post_id )";
  4803 
  5134 
  4804 		// meta_key and meta_value might be slashed
  5135 		// meta_key and meta_value might be slashed
  4805 		$meta_key = wp_unslash($meta_key);
  5136 		$meta_key   = wp_unslash( $meta_key );
  4806 		$meta_value = wp_unslash($meta_value);
  5137 		$meta_value = wp_unslash( $meta_value );
  4807 		if ( '' !== $meta_key ) {
  5138 		if ( '' !== $meta_key ) {
  4808 			$where .= $wpdb->prepare(" AND $wpdb->postmeta.meta_key = %s", $meta_key);
  5139 			$where .= $wpdb->prepare( " AND $wpdb->postmeta.meta_key = %s", $meta_key );
  4809 		}
  5140 		}
  4810 		if ( '' !== $meta_value ) {
  5141 		if ( '' !== $meta_value ) {
  4811 			$where .= $wpdb->prepare(" AND $wpdb->postmeta.meta_value = %s", $meta_value);
  5142 			$where .= $wpdb->prepare( " AND $wpdb->postmeta.meta_value = %s", $meta_value );
  4812 		}
  5143 		}
  4813 
       
  4814 	}
  5144 	}
  4815 
  5145 
  4816 	if ( is_array( $parent ) ) {
  5146 	if ( is_array( $parent ) ) {
  4817 		$post_parent__in = implode( ',', array_map( 'absint', (array) $parent ) );
  5147 		$post_parent__in = implode( ',', array_map( 'absint', (array) $parent ) );
  4818 		if ( ! empty( $post_parent__in ) ) {
  5148 		if ( ! empty( $post_parent__in ) ) {
  4819 			$where .= " AND post_parent IN ($post_parent__in)";
  5149 			$where .= " AND post_parent IN ($post_parent__in)";
  4820 		}
  5150 		}
  4821 	} elseif ( $parent >= 0 ) {
  5151 	} elseif ( $parent >= 0 ) {
  4822 		$where .= $wpdb->prepare(' AND post_parent = %d ', $parent);
  5152 		$where .= $wpdb->prepare( ' AND post_parent = %d ', $parent );
  4823 	}
  5153 	}
  4824 
  5154 
  4825 	if ( 1 == count( $post_status ) ) {
  5155 	if ( 1 == count( $post_status ) ) {
  4826 		$where_post_type = $wpdb->prepare( "post_type = %s AND post_status = %s", $r['post_type'], reset( $post_status ) );
  5156 		$where_post_type = $wpdb->prepare( 'post_type = %s AND post_status = %s', $r['post_type'], reset( $post_status ) );
  4827 	} else {
  5157 	} else {
  4828 		$post_status = implode( "', '", $post_status );
  5158 		$post_status     = implode( "', '", $post_status );
  4829 		$where_post_type = $wpdb->prepare( "post_type = %s AND post_status IN ('$post_status')", $r['post_type'] );
  5159 		$where_post_type = $wpdb->prepare( "post_type = %s AND post_status IN ('$post_status')", $r['post_type'] );
  4830 	}
  5160 	}
  4831 
  5161 
  4832 	$orderby_array = array();
  5162 	$orderby_array = array();
  4833 	$allowed_keys = array( 'author', 'post_author', 'date', 'post_date', 'title', 'post_title', 'name', 'post_name', 'modified',
  5163 	$allowed_keys  = array(
  4834 		'post_modified', 'modified_gmt', 'post_modified_gmt', 'menu_order', 'parent', 'post_parent',
  5164 		'author',
  4835 		'ID', 'rand', 'comment_count' );
  5165 		'post_author',
       
  5166 		'date',
       
  5167 		'post_date',
       
  5168 		'title',
       
  5169 		'post_title',
       
  5170 		'name',
       
  5171 		'post_name',
       
  5172 		'modified',
       
  5173 		'post_modified',
       
  5174 		'modified_gmt',
       
  5175 		'post_modified_gmt',
       
  5176 		'menu_order',
       
  5177 		'parent',
       
  5178 		'post_parent',
       
  5179 		'ID',
       
  5180 		'rand',
       
  5181 		'comment_count',
       
  5182 	);
  4836 
  5183 
  4837 	foreach ( explode( ',', $r['sort_column'] ) as $orderby ) {
  5184 	foreach ( explode( ',', $r['sort_column'] ) as $orderby ) {
  4838 		$orderby = trim( $orderby );
  5185 		$orderby = trim( $orderby );
  4839 		if ( ! in_array( $orderby, $allowed_keys ) ) {
  5186 		if ( ! in_array( $orderby, $allowed_keys ) ) {
  4840 			continue;
  5187 			continue;
  4868 	$sort_order = strtoupper( $r['sort_order'] );
  5215 	$sort_order = strtoupper( $r['sort_order'] );
  4869 	if ( '' !== $sort_order && ! in_array( $sort_order, array( 'ASC', 'DESC' ) ) ) {
  5216 	if ( '' !== $sort_order && ! in_array( $sort_order, array( 'ASC', 'DESC' ) ) ) {
  4870 		$sort_order = 'ASC';
  5217 		$sort_order = 'ASC';
  4871 	}
  5218 	}
  4872 
  5219 
  4873 	$query = "SELECT * FROM $wpdb->posts $join WHERE ($where_post_type) $where ";
  5220 	$query  = "SELECT * FROM $wpdb->posts $join WHERE ($where_post_type) $where ";
  4874 	$query .= $author_query;
  5221 	$query .= $author_query;
  4875 	$query .= " ORDER BY " . $sort_column . " " . $sort_order ;
  5222 	$query .= ' ORDER BY ' . $sort_column . ' ' . $sort_order;
  4876 
  5223 
  4877 	if ( ! empty( $number ) ) {
  5224 	if ( ! empty( $number ) ) {
  4878 		$query .= ' LIMIT ' . $offset . ',' . $number;
  5225 		$query .= ' LIMIT ' . $offset . ',' . $number;
  4879 	}
  5226 	}
  4880 
  5227 
  4881 	$pages = $wpdb->get_results($query);
  5228 	$pages = $wpdb->get_results( $query );
  4882 
  5229 
  4883 	if ( empty($pages) ) {
  5230 	if ( empty( $pages ) ) {
       
  5231 		wp_cache_set( $cache_key, array(), 'posts' );
       
  5232 
  4884 		/** This filter is documented in wp-includes/post.php */
  5233 		/** This filter is documented in wp-includes/post.php */
  4885 		$pages = apply_filters( 'get_pages', array(), $r );
  5234 		$pages = apply_filters( 'get_pages', array(), $r );
  4886 		return $pages;
  5235 		return $pages;
  4887 	}
  5236 	}
  4888 
  5237 
  4889 	// Sanitize before caching so it'll only get done once.
  5238 	// Sanitize before caching so it'll only get done once.
  4890 	$num_pages = count($pages);
  5239 	$num_pages = count( $pages );
  4891 	for ($i = 0; $i < $num_pages; $i++) {
  5240 	for ( $i = 0; $i < $num_pages; $i++ ) {
  4892 		$pages[$i] = sanitize_post($pages[$i], 'raw');
  5241 		$pages[ $i ] = sanitize_post( $pages[ $i ], 'raw' );
  4893 	}
  5242 	}
  4894 
  5243 
  4895 	// Update cache.
  5244 	// Update cache.
  4896 	update_post_cache( $pages );
  5245 	update_post_cache( $pages );
  4897 
  5246 
  4898 	if ( $child_of || $hierarchical ) {
  5247 	if ( $child_of || $hierarchical ) {
  4899 		$pages = get_page_children($child_of, $pages);
  5248 		$pages = get_page_children( $child_of, $pages );
  4900 	}
  5249 	}
  4901 
  5250 
  4902 	if ( ! empty( $r['exclude_tree'] ) ) {
  5251 	if ( ! empty( $r['exclude_tree'] ) ) {
  4903 		$exclude = wp_parse_id_list( $r['exclude_tree'] );
  5252 		$exclude = wp_parse_id_list( $r['exclude_tree'] );
  4904 		foreach ( $exclude as $id ) {
  5253 		foreach ( $exclude as $id ) {
  4908 			}
  5257 			}
  4909 		}
  5258 		}
  4910 
  5259 
  4911 		$num_pages = count( $pages );
  5260 		$num_pages = count( $pages );
  4912 		for ( $i = 0; $i < $num_pages; $i++ ) {
  5261 		for ( $i = 0; $i < $num_pages; $i++ ) {
  4913 			if ( in_array( $pages[$i]->ID, $exclude ) ) {
  5262 			if ( in_array( $pages[ $i ]->ID, $exclude ) ) {
  4914 				unset( $pages[$i] );
  5263 				unset( $pages[ $i ] );
  4915 			}
  5264 			}
  4916 		}
  5265 		}
  4917 	}
  5266 	}
  4918 
  5267 
  4919 	$page_structure = array();
  5268 	$page_structure = array();
  4940 //
  5289 //
  4941 // Attachment functions
  5290 // Attachment functions
  4942 //
  5291 //
  4943 
  5292 
  4944 /**
  5293 /**
  4945  * Check if the attachment URI is local one and is really an attachment.
  5294  * Determines whether an attachment URI is local and really an attachment.
       
  5295  *
       
  5296  * For more information on this and similar theme functions, check out
       
  5297  * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
       
  5298  * Conditional Tags} article in the Theme Developer Handbook.
  4946  *
  5299  *
  4947  * @since 2.0.0
  5300  * @since 2.0.0
  4948  *
  5301  *
  4949  * @param string $url URL to check
  5302  * @param string $url URL to check
  4950  * @return bool True on success, false on failure.
  5303  * @return bool True on success, false on failure.
  4951  */
  5304  */
  4952 function is_local_attachment($url) {
  5305 function is_local_attachment( $url ) {
  4953 	if (strpos($url, home_url()) === false)
  5306 	if ( strpos( $url, home_url() ) === false ) {
  4954 		return false;
  5307 		return false;
  4955 	if (strpos($url, home_url('/?attachment_id=')) !== false)
  5308 	}
       
  5309 	if ( strpos( $url, home_url( '/?attachment_id=' ) ) !== false ) {
  4956 		return true;
  5310 		return true;
  4957 	if ( $id = url_to_postid($url) ) {
  5311 	}
  4958 		$post = get_post($id);
  5312 	if ( $id = url_to_postid( $url ) ) {
  4959 		if ( 'attachment' == $post->post_type )
  5313 		$post = get_post( $id );
       
  5314 		if ( 'attachment' == $post->post_type ) {
  4960 			return true;
  5315 			return true;
       
  5316 		}
  4961 	}
  5317 	}
  4962 	return false;
  5318 	return false;
  4963 }
  5319 }
  4964 
  5320 
  4965 /**
  5321 /**
  4988  * @return int|WP_Error The attachment ID on success. The value 0 or WP_Error on failure.
  5344  * @return int|WP_Error The attachment ID on success. The value 0 or WP_Error on failure.
  4989  */
  5345  */
  4990 function wp_insert_attachment( $args, $file = false, $parent = 0, $wp_error = false ) {
  5346 function wp_insert_attachment( $args, $file = false, $parent = 0, $wp_error = false ) {
  4991 	$defaults = array(
  5347 	$defaults = array(
  4992 		'file'        => $file,
  5348 		'file'        => $file,
  4993 		'post_parent' => 0
  5349 		'post_parent' => 0,
  4994 	);
  5350 	);
  4995 
  5351 
  4996 	$data = wp_parse_args( $args, $defaults );
  5352 	$data = wp_parse_args( $args, $defaults );
  4997 
  5353 
  4998 	if ( ! empty( $parent ) ) {
  5354 	if ( ! empty( $parent ) ) {
  5040 
  5396 
  5041 	if ( ! $force_delete && EMPTY_TRASH_DAYS && MEDIA_TRASH && 'trash' !== $post->post_status ) {
  5397 	if ( ! $force_delete && EMPTY_TRASH_DAYS && MEDIA_TRASH && 'trash' !== $post->post_status ) {
  5042 		return wp_trash_post( $post_id );
  5398 		return wp_trash_post( $post_id );
  5043 	}
  5399 	}
  5044 
  5400 
  5045 	delete_post_meta($post_id, '_wp_trash_meta_status');
  5401 	delete_post_meta( $post_id, '_wp_trash_meta_status' );
  5046 	delete_post_meta($post_id, '_wp_trash_meta_time');
  5402 	delete_post_meta( $post_id, '_wp_trash_meta_time' );
  5047 
  5403 
  5048 	$meta = wp_get_attachment_metadata( $post_id );
  5404 	$meta         = wp_get_attachment_metadata( $post_id );
  5049 	$backup_sizes = get_post_meta( $post->ID, '_wp_attachment_backup_sizes', true );
  5405 	$backup_sizes = get_post_meta( $post->ID, '_wp_attachment_backup_sizes', true );
  5050 	$file = get_attached_file( $post_id );
  5406 	$file         = get_attached_file( $post_id );
  5051 
  5407 
  5052 	if ( is_multisite() )
  5408 	if ( is_multisite() ) {
  5053 		delete_transient( 'dirsize_cache' );
  5409 		delete_transient( 'dirsize_cache' );
       
  5410 	}
  5054 
  5411 
  5055 	/**
  5412 	/**
  5056 	 * Fires before an attachment is deleted, at the start of wp_delete_attachment().
  5413 	 * Fires before an attachment is deleted, at the start of wp_delete_attachment().
  5057 	 *
  5414 	 *
  5058 	 * @since 2.0.0
  5415 	 * @since 2.0.0
  5059 	 *
  5416 	 *
  5060 	 * @param int $post_id Attachment ID.
  5417 	 * @param int $post_id Attachment ID.
  5061 	 */
  5418 	 */
  5062 	do_action( 'delete_attachment', $post_id );
  5419 	do_action( 'delete_attachment', $post_id );
  5063 
  5420 
  5064 	wp_delete_object_term_relationships($post_id, array('category', 'post_tag'));
  5421 	wp_delete_object_term_relationships( $post_id, array( 'category', 'post_tag' ) );
  5065 	wp_delete_object_term_relationships($post_id, get_object_taxonomies($post->post_type));
  5422 	wp_delete_object_term_relationships( $post_id, get_object_taxonomies( $post->post_type ) );
  5066 
  5423 
  5067 	// Delete all for any posts.
  5424 	// Delete all for any posts.
  5068 	delete_metadata( 'post', null, '_thumbnail_id', $post_id, true );
  5425 	delete_metadata( 'post', null, '_thumbnail_id', $post_id, true );
  5069 
  5426 
  5070 	wp_defer_comment_counting( true );
  5427 	wp_defer_comment_counting( true );
  5071 
  5428 
  5072 	$comment_ids = $wpdb->get_col( $wpdb->prepare( "SELECT comment_ID FROM $wpdb->comments WHERE comment_post_ID = %d", $post_id ));
  5429 	$comment_ids = $wpdb->get_col( $wpdb->prepare( "SELECT comment_ID FROM $wpdb->comments WHERE comment_post_ID = %d", $post_id ) );
  5073 	foreach ( $comment_ids as $comment_id ) {
  5430 	foreach ( $comment_ids as $comment_id ) {
  5074 		wp_delete_comment( $comment_id, true );
  5431 		wp_delete_comment( $comment_id, true );
  5075 	}
  5432 	}
  5076 
  5433 
  5077 	wp_defer_comment_counting( false );
  5434 	wp_defer_comment_counting( false );
  5078 
  5435 
  5079 	$post_meta_ids = $wpdb->get_col( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d ", $post_id ));
  5436 	$post_meta_ids = $wpdb->get_col( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d ", $post_id ) );
  5080 	foreach ( $post_meta_ids as $mid )
  5437 	foreach ( $post_meta_ids as $mid ) {
  5081 		delete_metadata_by_mid( 'post', $mid );
  5438 		delete_metadata_by_mid( 'post', $mid );
       
  5439 	}
  5082 
  5440 
  5083 	/** This action is documented in wp-includes/post.php */
  5441 	/** This action is documented in wp-includes/post.php */
  5084 	do_action( 'delete_post', $post_id );
  5442 	do_action( 'delete_post', $post_id );
  5085 	$result = $wpdb->delete( $wpdb->posts, array( 'ID' => $post_id ) );
  5443 	$result = $wpdb->delete( $wpdb->posts, array( 'ID' => $post_id ) );
  5086 	if ( ! $result ) {
  5444 	if ( ! $result ) {
  5114 	$deleted    = true;
  5472 	$deleted    = true;
  5115 
  5473 
  5116 	if ( ! empty( $meta['thumb'] ) ) {
  5474 	if ( ! empty( $meta['thumb'] ) ) {
  5117 		// Don't delete the thumb if another attachment uses it.
  5475 		// Don't delete the thumb if another attachment uses it.
  5118 		if ( ! $wpdb->get_row( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE meta_key = '_wp_attachment_metadata' AND meta_value LIKE %s AND post_id <> %d", '%' . $wpdb->esc_like( $meta['thumb'] ) . '%', $post_id ) ) ) {
  5476 		if ( ! $wpdb->get_row( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE meta_key = '_wp_attachment_metadata' AND meta_value LIKE %s AND post_id <> %d", '%' . $wpdb->esc_like( $meta['thumb'] ) . '%', $post_id ) ) ) {
  5119 			$thumbfile = str_replace( basename( $file ), $meta['thumb'], $file );
  5477 			$thumbfile = str_replace( wp_basename( $file ), $meta['thumb'], $file );
  5120 			if ( ! empty( $thumbfile ) ) {
  5478 			if ( ! empty( $thumbfile ) ) {
  5121 				$thumbfile = path_join( $uploadpath['basedir'], $thumbfile );
  5479 				$thumbfile = path_join( $uploadpath['basedir'], $thumbfile );
  5122 				$thumbdir  = path_join( $uploadpath['basedir'], dirname( $file ) );
  5480 				$thumbdir  = path_join( $uploadpath['basedir'], dirname( $file ) );
  5123 
  5481 
  5124 				if ( ! wp_delete_file_from_directory( $thumbfile, $thumbdir ) ) {
  5482 				if ( ! wp_delete_file_from_directory( $thumbfile, $thumbdir ) ) {
  5130 
  5488 
  5131 	// Remove intermediate and backup images if there are any.
  5489 	// Remove intermediate and backup images if there are any.
  5132 	if ( isset( $meta['sizes'] ) && is_array( $meta['sizes'] ) ) {
  5490 	if ( isset( $meta['sizes'] ) && is_array( $meta['sizes'] ) ) {
  5133 		$intermediate_dir = path_join( $uploadpath['basedir'], dirname( $file ) );
  5491 		$intermediate_dir = path_join( $uploadpath['basedir'], dirname( $file ) );
  5134 		foreach ( $meta['sizes'] as $size => $sizeinfo ) {
  5492 		foreach ( $meta['sizes'] as $size => $sizeinfo ) {
  5135 			$intermediate_file = str_replace( basename( $file ), $sizeinfo['file'], $file );
  5493 			$intermediate_file = str_replace( wp_basename( $file ), $sizeinfo['file'], $file );
  5136 			if ( ! empty( $intermediate_file ) ) {
  5494 			if ( ! empty( $intermediate_file ) ) {
  5137 				$intermediate_file = path_join( $uploadpath['basedir'], $intermediate_file );
  5495 				$intermediate_file = path_join( $uploadpath['basedir'], $intermediate_file );
  5138 
  5496 
  5139 				if ( ! wp_delete_file_from_directory( $intermediate_file, $intermediate_dir ) ) {
  5497 				if ( ! wp_delete_file_from_directory( $intermediate_file, $intermediate_dir ) ) {
  5140 					$deleted = false;
  5498 					$deleted = false;
  5179 		return false;
  5537 		return false;
  5180 	}
  5538 	}
  5181 
  5539 
  5182 	$data = get_post_meta( $post->ID, '_wp_attachment_metadata', true );
  5540 	$data = get_post_meta( $post->ID, '_wp_attachment_metadata', true );
  5183 
  5541 
  5184 	if ( $unfiltered )
  5542 	if ( $unfiltered ) {
  5185 		return $data;
  5543 		return $data;
       
  5544 	}
  5186 
  5545 
  5187 	/**
  5546 	/**
  5188 	 * Filters the attachment meta data.
  5547 	 * Filters the attachment meta data.
  5189 	 *
  5548 	 *
  5190 	 * @since 2.1.0
  5549 	 * @since 2.1.0
  5217 	 * @since 2.1.0
  5576 	 * @since 2.1.0
  5218 	 *
  5577 	 *
  5219 	 * @param array $data          Array of updated attachment meta data.
  5578 	 * @param array $data          Array of updated attachment meta data.
  5220 	 * @param int   $attachment_id Attachment post ID.
  5579 	 * @param int   $attachment_id Attachment post ID.
  5221 	 */
  5580 	 */
  5222 	if ( $data = apply_filters( 'wp_update_attachment_metadata', $data, $post->ID ) )
  5581 	if ( $data = apply_filters( 'wp_update_attachment_metadata', $data, $post->ID ) ) {
  5223 		return update_post_meta( $post->ID, '_wp_attachment_metadata', $data );
  5582 		return update_post_meta( $post->ID, '_wp_attachment_metadata', $data );
  5224 	else
  5583 	} else {
  5225 		return delete_post_meta( $post->ID, '_wp_attachment_metadata' );
  5584 		return delete_post_meta( $post->ID, '_wp_attachment_metadata' );
       
  5585 	}
  5226 }
  5586 }
  5227 
  5587 
  5228 /**
  5588 /**
  5229  * Retrieve the URL for an attachment.
  5589  * Retrieve the URL for an attachment.
  5230  *
  5590  *
  5239 	$attachment_id = (int) $attachment_id;
  5599 	$attachment_id = (int) $attachment_id;
  5240 	if ( ! $post = get_post( $attachment_id ) ) {
  5600 	if ( ! $post = get_post( $attachment_id ) ) {
  5241 		return false;
  5601 		return false;
  5242 	}
  5602 	}
  5243 
  5603 
  5244 	if ( 'attachment' != $post->post_type )
  5604 	if ( 'attachment' != $post->post_type ) {
  5245 		return false;
  5605 		return false;
       
  5606 	}
  5246 
  5607 
  5247 	$url = '';
  5608 	$url = '';
  5248 	// Get attached file.
  5609 	// Get attached file.
  5249 	if ( $file = get_post_meta( $post->ID, '_wp_attached_file', true ) ) {
  5610 	if ( $file = get_post_meta( $post->ID, '_wp_attached_file', true ) ) {
  5250 		// Get upload directory.
  5611 		// Get upload directory.
  5251 		if ( ( $uploads = wp_get_upload_dir() ) && false === $uploads['error'] ) {
  5612 		if ( ( $uploads = wp_get_upload_dir() ) && false === $uploads['error'] ) {
  5252 			// Check that the upload base exists in the file location.
  5613 			// Check that the upload base exists in the file location.
  5253 			if ( 0 === strpos( $file, $uploads['basedir'] ) ) {
  5614 			if ( 0 === strpos( $file, $uploads['basedir'] ) ) {
  5254 				// Replace file location with url location.
  5615 				// Replace file location with url location.
  5255 				$url = str_replace($uploads['basedir'], $uploads['baseurl'], $file);
  5616 				$url = str_replace( $uploads['basedir'], $uploads['baseurl'], $file );
  5256 			} elseif ( false !== strpos($file, 'wp-content/uploads') ) {
  5617 			} elseif ( false !== strpos( $file, 'wp-content/uploads' ) ) {
  5257 				// Get the directory name relative to the basedir (back compat for pre-2.7 uploads)
  5618 				// Get the directory name relative to the basedir (back compat for pre-2.7 uploads)
  5258 				$url = trailingslashit( $uploads['baseurl'] . '/' . _wp_get_attachment_relative_path( $file ) ) . basename( $file );
  5619 				$url = trailingslashit( $uploads['baseurl'] . '/' . _wp_get_attachment_relative_path( $file ) ) . wp_basename( $file );
  5259 			} else {
  5620 			} else {
  5260 				// It's a newly-uploaded file, therefore $file is relative to the basedir.
  5621 				// It's a newly-uploaded file, therefore $file is relative to the basedir.
  5261 				$url = $uploads['baseurl'] . "/$file";
  5622 				$url = $uploads['baseurl'] . "/$file";
  5262 			}
  5623 			}
  5263 		}
  5624 		}
  5265 
  5626 
  5266 	/*
  5627 	/*
  5267 	 * If any of the above options failed, Fallback on the GUID as used pre-2.7,
  5628 	 * If any of the above options failed, Fallback on the GUID as used pre-2.7,
  5268 	 * not recommended to rely upon this.
  5629 	 * not recommended to rely upon this.
  5269 	 */
  5630 	 */
  5270 	if ( empty($url) ) {
  5631 	if ( empty( $url ) ) {
  5271 		$url = get_the_guid( $post->ID );
  5632 		$url = get_the_guid( $post->ID );
  5272 	}
  5633 	}
  5273 
  5634 
  5274 	// On SSL front end, URLs should be HTTPS.
  5635 	// On SSL front end, URLs should be HTTPS.
  5275 	if ( is_ssl() && ! is_admin() && 'wp-login.php' !== $GLOBALS['pagenow'] ) {
  5636 	if ( is_ssl() && ! is_admin() && 'wp-login.php' !== $GLOBALS['pagenow'] ) {
  5284 	 * @param string $url           URL for the given attachment.
  5645 	 * @param string $url           URL for the given attachment.
  5285 	 * @param int    $attachment_id Attachment post ID.
  5646 	 * @param int    $attachment_id Attachment post ID.
  5286 	 */
  5647 	 */
  5287 	$url = apply_filters( 'wp_get_attachment_url', $url, $post->ID );
  5648 	$url = apply_filters( 'wp_get_attachment_url', $url, $post->ID );
  5288 
  5649 
  5289 	if ( empty( $url ) )
  5650 	if ( empty( $url ) ) {
  5290 		return false;
  5651 		return false;
       
  5652 	}
  5291 
  5653 
  5292 	return $url;
  5654 	return $url;
  5293 }
  5655 }
  5294 
  5656 
  5295 /**
  5657 /**
  5331  * @param int $post_id Optional. Attachment ID. Default 0.
  5693  * @param int $post_id Optional. Attachment ID. Default 0.
  5332  * @return string|false False on failure. Thumbnail file path on success.
  5694  * @return string|false False on failure. Thumbnail file path on success.
  5333  */
  5695  */
  5334 function wp_get_attachment_thumb_file( $post_id = 0 ) {
  5696 function wp_get_attachment_thumb_file( $post_id = 0 ) {
  5335 	$post_id = (int) $post_id;
  5697 	$post_id = (int) $post_id;
  5336 	if ( !$post = get_post( $post_id ) )
  5698 	if ( ! $post = get_post( $post_id ) ) {
  5337 		return false;
  5699 		return false;
  5338 	if ( !is_array( $imagedata = wp_get_attachment_metadata( $post->ID ) ) )
  5700 	}
       
  5701 	if ( ! is_array( $imagedata = wp_get_attachment_metadata( $post->ID ) ) ) {
  5339 		return false;
  5702 		return false;
       
  5703 	}
  5340 
  5704 
  5341 	$file = get_attached_file( $post->ID );
  5705 	$file = get_attached_file( $post->ID );
  5342 
  5706 
  5343 	if ( !empty($imagedata['thumb']) && ($thumbfile = str_replace(basename($file), $imagedata['thumb'], $file)) && file_exists($thumbfile) ) {
  5707 	if ( ! empty( $imagedata['thumb'] ) && ( $thumbfile = str_replace( wp_basename( $file ), $imagedata['thumb'], $file ) ) && file_exists( $thumbfile ) ) {
  5344 		/**
  5708 		/**
  5345 		 * Filters the attachment thumbnail file path.
  5709 		 * Filters the attachment thumbnail file path.
  5346 		 *
  5710 		 *
  5347 		 * @since 2.1.0
  5711 		 * @since 2.1.0
  5348 		 *
  5712 		 *
  5362  * @param int $post_id Optional. Attachment ID. Default 0.
  5726  * @param int $post_id Optional. Attachment ID. Default 0.
  5363  * @return string|false False on failure. Thumbnail URL on success.
  5727  * @return string|false False on failure. Thumbnail URL on success.
  5364  */
  5728  */
  5365 function wp_get_attachment_thumb_url( $post_id = 0 ) {
  5729 function wp_get_attachment_thumb_url( $post_id = 0 ) {
  5366 	$post_id = (int) $post_id;
  5730 	$post_id = (int) $post_id;
  5367 	if ( !$post = get_post( $post_id ) )
  5731 	if ( ! $post = get_post( $post_id ) ) {
  5368 		return false;
  5732 		return false;
  5369 	if ( !$url = wp_get_attachment_url( $post->ID ) )
  5733 	}
       
  5734 	if ( ! $url = wp_get_attachment_url( $post->ID ) ) {
  5370 		return false;
  5735 		return false;
       
  5736 	}
  5371 
  5737 
  5372 	$sized = image_downsize( $post_id, 'thumbnail' );
  5738 	$sized = image_downsize( $post_id, 'thumbnail' );
  5373 	if ( $sized )
  5739 	if ( $sized ) {
  5374 		return $sized[0];
  5740 		return $sized[0];
  5375 
  5741 	}
  5376 	if ( !$thumb = wp_get_attachment_thumb_file( $post->ID ) )
  5742 
       
  5743 	if ( ! $thumb = wp_get_attachment_thumb_file( $post->ID ) ) {
  5377 		return false;
  5744 		return false;
  5378 
  5745 	}
  5379 	$url = str_replace(basename($url), basename($thumb), $url);
  5746 
       
  5747 	$url = str_replace( wp_basename( $url ), wp_basename( $thumb ), $url );
  5380 
  5748 
  5381 	/**
  5749 	/**
  5382 	 * Filters the attachment thumbnail URL.
  5750 	 * Filters the attachment thumbnail URL.
  5383 	 *
  5751 	 *
  5384 	 * @since 2.1.0
  5752 	 * @since 2.1.0
  5421 	if ( 'import' !== $post->post_mime_type ) {
  5789 	if ( 'import' !== $post->post_mime_type ) {
  5422 		return $type === $ext;
  5790 		return $type === $ext;
  5423 	}
  5791 	}
  5424 
  5792 
  5425 	switch ( $type ) {
  5793 	switch ( $type ) {
  5426 	case 'image':
  5794 		case 'image':
  5427 		$image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png' );
  5795 			$image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png' );
  5428 		return in_array( $ext, $image_exts );
  5796 			return in_array( $ext, $image_exts );
  5429 
  5797 
  5430 	case 'audio':
  5798 		case 'audio':
  5431 		return in_array( $ext, wp_get_audio_extensions() );
  5799 			return in_array( $ext, wp_get_audio_extensions() );
  5432 
  5800 
  5433 	case 'video':
  5801 		case 'video':
  5434 		return in_array( $ext, wp_get_video_extensions() );
  5802 			return in_array( $ext, wp_get_video_extensions() );
  5435 
  5803 
  5436 	default:
  5804 		default:
  5437 		return $type === $ext;
  5805 			return $type === $ext;
  5438 	}
  5806 	}
  5439 }
  5807 }
  5440 
  5808 
  5441 /**
  5809 /**
  5442  * Checks if the attachment is an image.
  5810  * Determines whether an attachment is an image.
       
  5811  *
       
  5812  * For more information on this and similar theme functions, check out
       
  5813  * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
       
  5814  * Conditional Tags} article in the Theme Developer Handbook.
  5443  *
  5815  *
  5444  * @since 2.1.0
  5816  * @since 2.1.0
  5445  * @since 4.2.0 Modified into wrapper for wp_attachment_is() and
  5817  * @since 4.2.0 Modified into wrapper for wp_attachment_is() and
  5446  *              allowed WP_Post object to be passed.
  5818  *              allowed WP_Post object to be passed.
  5447  *
  5819  *
  5459  *
  5831  *
  5460  * @param string|int $mime MIME type or attachment ID.
  5832  * @param string|int $mime MIME type or attachment ID.
  5461  * @return string|false Icon, false otherwise.
  5833  * @return string|false Icon, false otherwise.
  5462  */
  5834  */
  5463 function wp_mime_type_icon( $mime = 0 ) {
  5835 function wp_mime_type_icon( $mime = 0 ) {
  5464 	if ( !is_numeric($mime) )
  5836 	if ( ! is_numeric( $mime ) ) {
  5465 		$icon = wp_cache_get("mime_type_icon_$mime");
  5837 		$icon = wp_cache_get( "mime_type_icon_$mime" );
       
  5838 	}
  5466 
  5839 
  5467 	$post_id = 0;
  5840 	$post_id = 0;
  5468 	if ( empty($icon) ) {
  5841 	if ( empty( $icon ) ) {
  5469 		$post_mimes = array();
  5842 		$post_mimes = array();
  5470 		if ( is_numeric($mime) ) {
  5843 		if ( is_numeric( $mime ) ) {
  5471 			$mime = (int) $mime;
  5844 			$mime = (int) $mime;
  5472 			if ( $post = get_post( $mime ) ) {
  5845 			if ( $post = get_post( $mime ) ) {
  5473 				$post_id = (int) $post->ID;
  5846 				$post_id = (int) $post->ID;
  5474 				$file = get_attached_file( $post_id );
  5847 				$file    = get_attached_file( $post_id );
  5475 				$ext = preg_replace('/^.+?\.([^.]+)$/', '$1', $file);
  5848 				$ext     = preg_replace( '/^.+?\.([^.]+)$/', '$1', $file );
  5476 				if ( !empty($ext) ) {
  5849 				if ( ! empty( $ext ) ) {
  5477 					$post_mimes[] = $ext;
  5850 					$post_mimes[] = $ext;
  5478 					if ( $ext_type = wp_ext2type( $ext ) )
  5851 					if ( $ext_type = wp_ext2type( $ext ) ) {
  5479 						$post_mimes[] = $ext_type;
  5852 						$post_mimes[] = $ext_type;
       
  5853 					}
  5480 				}
  5854 				}
  5481 				$mime = $post->post_mime_type;
  5855 				$mime = $post->post_mime_type;
  5482 			} else {
  5856 			} else {
  5483 				$mime = 0;
  5857 				$mime = 0;
  5484 			}
  5858 			}
  5485 		} else {
  5859 		} else {
  5486 			$post_mimes[] = $mime;
  5860 			$post_mimes[] = $mime;
  5487 		}
  5861 		}
  5488 
  5862 
  5489 		$icon_files = wp_cache_get('icon_files');
  5863 		$icon_files = wp_cache_get( 'icon_files' );
  5490 
  5864 
  5491 		if ( !is_array($icon_files) ) {
  5865 		if ( ! is_array( $icon_files ) ) {
  5492 			/**
  5866 			/**
  5493 			 * Filters the icon directory path.
  5867 			 * Filters the icon directory path.
  5494 			 *
  5868 			 *
  5495 			 * @since 2.0.0
  5869 			 * @since 2.0.0
  5496 			 *
  5870 			 *
  5512 			 *
  5886 			 *
  5513 			 * @since 2.5.0
  5887 			 * @since 2.5.0
  5514 			 *
  5888 			 *
  5515 			 * @param array $uris List of icon directory URIs.
  5889 			 * @param array $uris List of icon directory URIs.
  5516 			 */
  5890 			 */
  5517 			$dirs = apply_filters( 'icon_dirs', array( $icon_dir => $icon_dir_uri ) );
  5891 			$dirs       = apply_filters( 'icon_dirs', array( $icon_dir => $icon_dir_uri ) );
  5518 			$icon_files = array();
  5892 			$icon_files = array();
  5519 			while ( $dirs ) {
  5893 			while ( $dirs ) {
  5520 				$keys = array_keys( $dirs );
  5894 				$keys = array_keys( $dirs );
  5521 				$dir = array_shift( $keys );
  5895 				$dir  = array_shift( $keys );
  5522 				$uri = array_shift($dirs);
  5896 				$uri  = array_shift( $dirs );
  5523 				if ( $dh = opendir($dir) ) {
  5897 				if ( $dh = opendir( $dir ) ) {
  5524 					while ( false !== $file = readdir($dh) ) {
  5898 					while ( false !== $file = readdir( $dh ) ) {
  5525 						$file = basename($file);
  5899 						$file = wp_basename( $file );
  5526 						if ( substr($file, 0, 1) == '.' )
  5900 						if ( substr( $file, 0, 1 ) == '.' ) {
  5527 							continue;
       
  5528 						if ( !in_array(strtolower(substr($file, -4)), array('.png', '.gif', '.jpg') ) ) {
       
  5529 							if ( is_dir("$dir/$file") )
       
  5530 								$dirs["$dir/$file"] = "$uri/$file";
       
  5531 							continue;
  5901 							continue;
  5532 						}
  5902 						}
  5533 						$icon_files["$dir/$file"] = "$uri/$file";
  5903 						if ( ! in_array( strtolower( substr( $file, -4 ) ), array( '.png', '.gif', '.jpg' ) ) ) {
       
  5904 							if ( is_dir( "$dir/$file" ) ) {
       
  5905 								$dirs[ "$dir/$file" ] = "$uri/$file";
       
  5906 							}
       
  5907 							continue;
       
  5908 						}
       
  5909 						$icon_files[ "$dir/$file" ] = "$uri/$file";
  5534 					}
  5910 					}
  5535 					closedir($dh);
  5911 					closedir( $dh );
  5536 				}
  5912 				}
  5537 			}
  5913 			}
  5538 			wp_cache_add( 'icon_files', $icon_files, 'default', 600 );
  5914 			wp_cache_add( 'icon_files', $icon_files, 'default', 600 );
  5539 		}
  5915 		}
  5540 
  5916 
  5541 		$types = array();
  5917 		$types = array();
  5542 		// Icon basename - extension = MIME wildcard.
  5918 		// Icon wp_basename - extension = MIME wildcard.
  5543 		foreach ( $icon_files as $file => $uri )
  5919 		foreach ( $icon_files as $file => $uri ) {
  5544 			$types[ preg_replace('/^([^.]*).*$/', '$1', basename($file)) ] =& $icon_files[$file];
  5920 			$types[ preg_replace( '/^([^.]*).*$/', '$1', wp_basename( $file ) ) ] =& $icon_files[ $file ];
  5545 
  5921 		}
  5546 		if ( ! empty($mime) ) {
  5922 
  5547 			$post_mimes[] = substr($mime, 0, strpos($mime, '/'));
  5923 		if ( ! empty( $mime ) ) {
  5548 			$post_mimes[] = substr($mime, strpos($mime, '/') + 1);
  5924 			$post_mimes[] = substr( $mime, 0, strpos( $mime, '/' ) );
  5549 			$post_mimes[] = str_replace('/', '_', $mime);
  5925 			$post_mimes[] = substr( $mime, strpos( $mime, '/' ) + 1 );
  5550 		}
  5926 			$post_mimes[] = str_replace( '/', '_', $mime );
  5551 
  5927 		}
  5552 		$matches = wp_match_mime_types(array_keys($types), $post_mimes);
  5928 
  5553 		$matches['default'] = array('default');
  5929 		$matches            = wp_match_mime_types( array_keys( $types ), $post_mimes );
       
  5930 		$matches['default'] = array( 'default' );
  5554 
  5931 
  5555 		foreach ( $matches as $match => $wilds ) {
  5932 		foreach ( $matches as $match => $wilds ) {
  5556 			foreach ( $wilds as $wild ) {
  5933 			foreach ( $wilds as $wild ) {
  5557 				if ( ! isset( $types[ $wild ] ) ) {
  5934 				if ( ! isset( $types[ $wild ] ) ) {
  5558 					continue;
  5935 					continue;
  5642  * @param WP_Post $post        The Post Object
  6019  * @param WP_Post $post        The Post Object
  5643  * @param WP_Post $post_before The Previous Post Object
  6020  * @param WP_Post $post_before The Previous Post Object
  5644  */
  6021  */
  5645 function wp_check_for_changed_dates( $post_id, $post, $post_before ) {
  6022 function wp_check_for_changed_dates( $post_id, $post, $post_before ) {
  5646 	$previous_date = date( 'Y-m-d', strtotime( $post_before->post_date ) );
  6023 	$previous_date = date( 'Y-m-d', strtotime( $post_before->post_date ) );
  5647 	$new_date = date( 'Y-m-d', strtotime( $post->post_date ) );
  6024 	$new_date      = date( 'Y-m-d', strtotime( $post->post_date ) );
  5648 	// Don't bother if it hasn't changed.
  6025 	// Don't bother if it hasn't changed.
  5649 	if ( $new_date == $previous_date ) {
  6026 	if ( $new_date == $previous_date ) {
  5650 		return;
  6027 		return;
  5651 	}
  6028 	}
  5652 	// We're only concerned with published, non-hierarchical objects.
  6029 	// We're only concerned with published, non-hierarchical objects.
  5750 
  6127 
  5751 	if ( empty( $post_type_clauses ) ) {
  6128 	if ( empty( $post_type_clauses ) ) {
  5752 		return $full ? 'WHERE 1 = 0' : '1 = 0';
  6129 		return $full ? 'WHERE 1 = 0' : '1 = 0';
  5753 	}
  6130 	}
  5754 
  6131 
  5755 	$sql = '( '. implode( ' OR ', $post_type_clauses ) . ' )';
  6132 	$sql = '( ' . implode( ' OR ', $post_type_clauses ) . ' )';
  5756 
  6133 
  5757 	if ( null !== $post_author ) {
  6134 	if ( null !== $post_author ) {
  5758 		$sql .= $wpdb->prepare( ' AND post_author = %d', $post_author );
  6135 		$sql .= $wpdb->prepare( ' AND post_author = %d', $post_author );
  5759 	}
  6136 	}
  5760 
  6137 
  5829 		return $lastpostmodified;
  6206 		return $lastpostmodified;
  5830 	}
  6207 	}
  5831 
  6208 
  5832 	$lastpostmodified = _get_last_post_time( $timezone, 'modified', $post_type );
  6209 	$lastpostmodified = _get_last_post_time( $timezone, 'modified', $post_type );
  5833 
  6210 
  5834 	$lastpostdate = get_lastpostdate($timezone);
  6211 	$lastpostdate = get_lastpostdate( $timezone );
  5835 	if ( $lastpostdate > $lastpostmodified ) {
  6212 	if ( $lastpostdate > $lastpostmodified ) {
  5836 		$lastpostmodified = $lastpostdate;
  6213 		$lastpostmodified = $lastpostdate;
  5837 	}
  6214 	}
  5838 
  6215 
  5839 	/**
  6216 	/**
  5890 		$post_types = "'" . sanitize_key( $post_type ) . "'";
  6267 		$post_types = "'" . sanitize_key( $post_type ) . "'";
  5891 	}
  6268 	}
  5892 
  6269 
  5893 	switch ( $timezone ) {
  6270 	switch ( $timezone ) {
  5894 		case 'gmt':
  6271 		case 'gmt':
  5895 			$date = $wpdb->get_var("SELECT post_{$field}_gmt FROM $wpdb->posts WHERE post_status = 'publish' AND post_type IN ({$post_types}) ORDER BY post_{$field}_gmt DESC LIMIT 1");
  6272 			$date = $wpdb->get_var( "SELECT post_{$field}_gmt FROM $wpdb->posts WHERE post_status = 'publish' AND post_type IN ({$post_types}) ORDER BY post_{$field}_gmt DESC LIMIT 1" );
  5896 			break;
  6273 			break;
  5897 		case 'blog':
  6274 		case 'blog':
  5898 			$date = $wpdb->get_var("SELECT post_{$field} FROM $wpdb->posts WHERE post_status = 'publish' AND post_type IN ({$post_types}) ORDER BY post_{$field}_gmt DESC LIMIT 1");
  6275 			$date = $wpdb->get_var( "SELECT post_{$field} FROM $wpdb->posts WHERE post_status = 'publish' AND post_type IN ({$post_types}) ORDER BY post_{$field}_gmt DESC LIMIT 1" );
  5899 			break;
  6276 			break;
  5900 		case 'server':
  6277 		case 'server':
  5901 			$add_seconds_server = date( 'Z' );
  6278 			$add_seconds_server = date( 'Z' );
  5902 			$date = $wpdb->get_var("SELECT DATE_ADD(post_{$field}_gmt, INTERVAL '$add_seconds_server' SECOND) FROM $wpdb->posts WHERE post_status = 'publish' AND post_type IN ({$post_types}) ORDER BY post_{$field}_gmt DESC LIMIT 1");
  6279 			$date               = $wpdb->get_var( "SELECT DATE_ADD(post_{$field}_gmt, INTERVAL '$add_seconds_server' SECOND) FROM $wpdb->posts WHERE post_status = 'publish' AND post_type IN ({$post_types}) ORDER BY post_{$field}_gmt DESC LIMIT 1" );
  5903 			break;
  6280 			break;
  5904 	}
  6281 	}
  5905 
  6282 
  5906 	if ( $date ) {
  6283 	if ( $date ) {
  5907 		wp_cache_set( $key, $date, 'timeinfo' );
  6284 		wp_cache_set( $key, $date, 'timeinfo' );
  5918  * @since 1.5.1
  6295  * @since 1.5.1
  5919  *
  6296  *
  5920  * @param array $posts Array of post objects (passed by reference).
  6297  * @param array $posts Array of post objects (passed by reference).
  5921  */
  6298  */
  5922 function update_post_cache( &$posts ) {
  6299 function update_post_cache( &$posts ) {
  5923 	if ( ! $posts )
  6300 	if ( ! $posts ) {
  5924 		return;
  6301 		return;
  5925 
  6302 	}
  5926 	foreach ( $posts as $post )
  6303 
       
  6304 	foreach ( $posts as $post ) {
  5927 		wp_cache_add( $post->ID, $post, 'posts' );
  6305 		wp_cache_add( $post->ID, $post, 'posts' );
       
  6306 	}
  5928 }
  6307 }
  5929 
  6308 
  5930 /**
  6309 /**
  5931  * Will clean the post in the cache.
  6310  * Will clean the post in the cache.
  5932  *
  6311  *
  5943  * @param int|WP_Post $post Post ID or post object to remove from the cache.
  6322  * @param int|WP_Post $post Post ID or post object to remove from the cache.
  5944  */
  6323  */
  5945 function clean_post_cache( $post ) {
  6324 function clean_post_cache( $post ) {
  5946 	global $_wp_suspend_cache_invalidation;
  6325 	global $_wp_suspend_cache_invalidation;
  5947 
  6326 
  5948 	if ( ! empty( $_wp_suspend_cache_invalidation ) )
  6327 	if ( ! empty( $_wp_suspend_cache_invalidation ) ) {
  5949 		return;
  6328 		return;
       
  6329 	}
  5950 
  6330 
  5951 	$post = get_post( $post );
  6331 	$post = get_post( $post );
  5952 	if ( empty( $post ) )
  6332 	if ( empty( $post ) ) {
  5953 		return;
  6333 		return;
       
  6334 	}
  5954 
  6335 
  5955 	wp_cache_delete( $post->ID, 'posts' );
  6336 	wp_cache_delete( $post->ID, 'posts' );
  5956 	wp_cache_delete( $post->ID, 'post_meta' );
  6337 	wp_cache_delete( $post->ID, 'post_meta' );
  5957 
  6338 
  5958 	clean_object_term_cache( $post->ID, $post->post_type );
  6339 	clean_object_term_cache( $post->ID, $post->post_type );
  5995  * @param bool   $update_term_cache Optional. Whether to update the term cache. Default true.
  6376  * @param bool   $update_term_cache Optional. Whether to update the term cache. Default true.
  5996  * @param bool   $update_meta_cache Optional. Whether to update the meta cache. Default true.
  6377  * @param bool   $update_meta_cache Optional. Whether to update the meta cache. Default true.
  5997  */
  6378  */
  5998 function update_post_caches( &$posts, $post_type = 'post', $update_term_cache = true, $update_meta_cache = true ) {
  6379 function update_post_caches( &$posts, $post_type = 'post', $update_term_cache = true, $update_meta_cache = true ) {
  5999 	// No point in doing all this work if we didn't match any posts.
  6380 	// No point in doing all this work if we didn't match any posts.
  6000 	if ( !$posts )
  6381 	if ( ! $posts ) {
  6001 		return;
  6382 		return;
  6002 
  6383 	}
  6003 	update_post_cache($posts);
  6384 
       
  6385 	update_post_cache( $posts );
  6004 
  6386 
  6005 	$post_ids = array();
  6387 	$post_ids = array();
  6006 	foreach ( $posts as $post )
  6388 	foreach ( $posts as $post ) {
  6007 		$post_ids[] = $post->ID;
  6389 		$post_ids[] = $post->ID;
  6008 
  6390 	}
  6009 	if ( ! $post_type )
  6391 
       
  6392 	if ( ! $post_type ) {
  6010 		$post_type = 'any';
  6393 		$post_type = 'any';
       
  6394 	}
  6011 
  6395 
  6012 	if ( $update_term_cache ) {
  6396 	if ( $update_term_cache ) {
  6013 		if ( is_array($post_type) ) {
  6397 		if ( is_array( $post_type ) ) {
  6014 			$ptypes = $post_type;
  6398 			$ptypes = $post_type;
  6015 		} elseif ( 'any' == $post_type ) {
  6399 		} elseif ( 'any' == $post_type ) {
  6016 			$ptypes = array();
  6400 			$ptypes = array();
  6017 			// Just use the post_types in the supplied posts.
  6401 			// Just use the post_types in the supplied posts.
  6018 			foreach ( $posts as $post ) {
  6402 			foreach ( $posts as $post ) {
  6019 				$ptypes[] = $post->post_type;
  6403 				$ptypes[] = $post->post_type;
  6020 			}
  6404 			}
  6021 			$ptypes = array_unique($ptypes);
  6405 			$ptypes = array_unique( $ptypes );
  6022 		} else {
  6406 		} else {
  6023 			$ptypes = array($post_type);
  6407 			$ptypes = array( $post_type );
  6024 		}
  6408 		}
  6025 
  6409 
  6026 		if ( ! empty($ptypes) )
  6410 		if ( ! empty( $ptypes ) ) {
  6027 			update_object_term_cache($post_ids, $ptypes);
  6411 			update_object_term_cache( $post_ids, $ptypes );
  6028 	}
  6412 		}
  6029 
  6413 	}
  6030 	if ( $update_meta_cache )
  6414 
  6031 		update_postmeta_cache($post_ids);
  6415 	if ( $update_meta_cache ) {
       
  6416 		update_postmeta_cache( $post_ids );
       
  6417 	}
  6032 }
  6418 }
  6033 
  6419 
  6034 /**
  6420 /**
  6035  * Updates metadata cache for list of post IDs.
  6421  * Updates metadata cache for list of post IDs.
  6036  *
  6422  *
  6043  * @param array $post_ids List of post IDs.
  6429  * @param array $post_ids List of post IDs.
  6044  * @return array|false Returns false if there is nothing to update or an array
  6430  * @return array|false Returns false if there is nothing to update or an array
  6045  *                     of metadata.
  6431  *                     of metadata.
  6046  */
  6432  */
  6047 function update_postmeta_cache( $post_ids ) {
  6433 function update_postmeta_cache( $post_ids ) {
  6048 	return update_meta_cache('post', $post_ids);
  6434 	return update_meta_cache( 'post', $post_ids );
  6049 }
  6435 }
  6050 
  6436 
  6051 /**
  6437 /**
  6052  * Will clean the attachment in the cache.
  6438  * Will clean the attachment in the cache.
  6053  *
  6439  *
  6064  * @param bool $clean_terms Optional. Whether to clean terms cache. Default false.
  6450  * @param bool $clean_terms Optional. Whether to clean terms cache. Default false.
  6065  */
  6451  */
  6066 function clean_attachment_cache( $id, $clean_terms = false ) {
  6452 function clean_attachment_cache( $id, $clean_terms = false ) {
  6067 	global $_wp_suspend_cache_invalidation;
  6453 	global $_wp_suspend_cache_invalidation;
  6068 
  6454 
  6069 	if ( !empty($_wp_suspend_cache_invalidation) )
  6455 	if ( ! empty( $_wp_suspend_cache_invalidation ) ) {
  6070 		return;
  6456 		return;
       
  6457 	}
  6071 
  6458 
  6072 	$id = (int) $id;
  6459 	$id = (int) $id;
  6073 
  6460 
  6074 	wp_cache_delete($id, 'posts');
  6461 	wp_cache_delete( $id, 'posts' );
  6075 	wp_cache_delete($id, 'post_meta');
  6462 	wp_cache_delete( $id, 'post_meta' );
  6076 
  6463 
  6077 	if ( $clean_terms )
  6464 	if ( $clean_terms ) {
  6078 		clean_object_term_cache($id, 'attachment');
  6465 		clean_object_term_cache( $id, 'attachment' );
       
  6466 	}
  6079 
  6467 
  6080 	/**
  6468 	/**
  6081 	 * Fires after the given attachment's cache is cleaned.
  6469 	 * Fires after the given attachment's cache is cleaned.
  6082 	 *
  6470 	 *
  6083 	 * @since 3.0.0
  6471 	 * @since 3.0.0
  6107 function _transition_post_status( $new_status, $old_status, $post ) {
  6495 function _transition_post_status( $new_status, $old_status, $post ) {
  6108 	global $wpdb;
  6496 	global $wpdb;
  6109 
  6497 
  6110 	if ( $old_status != 'publish' && $new_status == 'publish' ) {
  6498 	if ( $old_status != 'publish' && $new_status == 'publish' ) {
  6111 		// Reset GUID if transitioning to publish and it is empty.
  6499 		// Reset GUID if transitioning to publish and it is empty.
  6112 		if ( '' == get_the_guid($post->ID) )
  6500 		if ( '' == get_the_guid( $post->ID ) ) {
  6113 			$wpdb->update( $wpdb->posts, array( 'guid' => get_permalink( $post->ID ) ), array( 'ID' => $post->ID ) );
  6501 			$wpdb->update( $wpdb->posts, array( 'guid' => get_permalink( $post->ID ) ), array( 'ID' => $post->ID ) );
       
  6502 		}
  6114 
  6503 
  6115 		/**
  6504 		/**
  6116 		 * Fires when a post's status is transitioned from private to published.
  6505 		 * Fires when a post's status is transitioned from private to published.
  6117 		 *
  6506 		 *
  6118 		 * @since 1.5.0
  6507 		 * @since 1.5.0
  6119 		 * @deprecated 2.3.0 Use 'private_to_publish' instead.
  6508 		 * @deprecated 2.3.0 Use 'private_to_publish' instead.
  6120 		 *
  6509 		 *
  6121 		 * @param int $post_id Post ID.
  6510 		 * @param int $post_id Post ID.
  6122 		 */
  6511 		 */
  6123 		do_action('private_to_published', $post->ID);
  6512 		do_action( 'private_to_published', $post->ID );
  6124 	}
  6513 	}
  6125 
  6514 
  6126 	// If published posts changed clear the lastpostmodified cache.
  6515 	// If published posts changed clear the lastpostmodified cache.
  6127 	if ( 'publish' == $new_status || 'publish' == $old_status) {
  6516 	if ( 'publish' == $new_status || 'publish' == $old_status ) {
  6128 		foreach ( array( 'server', 'gmt', 'blog' ) as $timezone ) {
  6517 		foreach ( array( 'server', 'gmt', 'blog' ) as $timezone ) {
  6129 			wp_cache_delete( "lastpostmodified:$timezone", 'timeinfo' );
  6518 			wp_cache_delete( "lastpostmodified:$timezone", 'timeinfo' );
  6130 			wp_cache_delete( "lastpostdate:$timezone", 'timeinfo' );
  6519 			wp_cache_delete( "lastpostdate:$timezone", 'timeinfo' );
  6131 			wp_cache_delete( "lastpostdate:$timezone:{$post->post_type}", 'timeinfo' );
  6520 			wp_cache_delete( "lastpostdate:$timezone:{$post->post_type}", 'timeinfo' );
  6132 		}
  6521 		}
  6136 		wp_cache_delete( _count_posts_cache_key( $post->post_type ), 'counts' );
  6525 		wp_cache_delete( _count_posts_cache_key( $post->post_type ), 'counts' );
  6137 		wp_cache_delete( _count_posts_cache_key( $post->post_type, 'readable' ), 'counts' );
  6526 		wp_cache_delete( _count_posts_cache_key( $post->post_type, 'readable' ), 'counts' );
  6138 	}
  6527 	}
  6139 
  6528 
  6140 	// Always clears the hook in case the post status bounced from future to draft.
  6529 	// Always clears the hook in case the post status bounced from future to draft.
  6141 	wp_clear_scheduled_hook('publish_future_post', array( $post->ID ) );
  6530 	wp_clear_scheduled_hook( 'publish_future_post', array( $post->ID ) );
  6142 }
  6531 }
  6143 
  6532 
  6144 /**
  6533 /**
  6145  * Hook used to schedule publication for a post marked for the future.
  6534  * Hook used to schedule publication for a post marked for the future.
  6146  *
  6535  *
  6154  *                            wp_transition_post_status() and the default filter for _future_post_hook().
  6543  *                            wp_transition_post_status() and the default filter for _future_post_hook().
  6155  * @param WP_Post $post       Post object.
  6544  * @param WP_Post $post       Post object.
  6156  */
  6545  */
  6157 function _future_post_hook( $deprecated, $post ) {
  6546 function _future_post_hook( $deprecated, $post ) {
  6158 	wp_clear_scheduled_hook( 'publish_future_post', array( $post->ID ) );
  6547 	wp_clear_scheduled_hook( 'publish_future_post', array( $post->ID ) );
  6159 	wp_schedule_single_event( strtotime( get_gmt_from_date( $post->post_date ) . ' GMT') , 'publish_future_post', array( $post->ID ) );
  6548 	wp_schedule_single_event( strtotime( get_gmt_from_date( $post->post_date ) . ' GMT' ), 'publish_future_post', array( $post->ID ) );
  6160 }
  6549 }
  6161 
  6550 
  6162 /**
  6551 /**
  6163  * Hook to schedule pings and enclosures when a post is published.
  6552  * Hook to schedule pings and enclosures when a post is published.
  6164  *
  6553  *
  6179 		 * @param int $post_id Post ID.
  6568 		 * @param int $post_id Post ID.
  6180 		 */
  6569 		 */
  6181 		do_action( 'xmlrpc_publish_post', $post_id );
  6570 		do_action( 'xmlrpc_publish_post', $post_id );
  6182 	}
  6571 	}
  6183 
  6572 
  6184 	if ( defined('WP_IMPORTING') )
  6573 	if ( defined( 'WP_IMPORTING' ) ) {
  6185 		return;
  6574 		return;
  6186 
  6575 	}
  6187 	if ( get_option('default_pingback_flag') )
  6576 
       
  6577 	if ( get_option( 'default_pingback_flag' ) ) {
  6188 		add_post_meta( $post_id, '_pingme', '1' );
  6578 		add_post_meta( $post_id, '_pingme', '1' );
       
  6579 	}
  6189 	add_post_meta( $post_id, '_encloseme', '1' );
  6580 	add_post_meta( $post_id, '_encloseme', '1' );
  6190 
  6581 
  6191 	if ( ! wp_next_scheduled( 'do_pings' ) ) {
  6582 	if ( ! wp_next_scheduled( 'do_pings' ) ) {
  6192 		wp_schedule_single_event( time(), 'do_pings' );
  6583 		wp_schedule_single_event( time(), 'do_pings' );
  6193 	}
  6584 	}
  6194 }
  6585 }
  6195 
  6586 
  6196 /**
  6587 /**
  6197  * Return the post's parent's post_ID
  6588  * Returns the ID of the post's parent.
  6198  *
  6589  *
  6199  * @since 3.1.0
  6590  * @since 3.1.0
  6200  *
  6591  *
  6201  * @param int $post_ID
  6592  * @param int|WP_Post $post Post ID or post object. Defaults to global $post.
  6202  *
  6593  * @return int|false Post parent ID (which can be 0 if there is no parent), or false if the post does not exist.
  6203  * @return int|false Post parent ID, otherwise false.
  6594  */
  6204  */
  6595 function wp_get_post_parent_id( $post ) {
  6205 function wp_get_post_parent_id( $post_ID ) {
  6596 	$post = get_post( $post );
  6206 	$post = get_post( $post_ID );
  6597 	if ( ! $post || is_wp_error( $post ) ) {
  6207 	if ( !$post || is_wp_error( $post ) )
       
  6208 		return false;
  6598 		return false;
       
  6599 	}
  6209 	return (int) $post->post_parent;
  6600 	return (int) $post->post_parent;
  6210 }
  6601 }
  6211 
  6602 
  6212 /**
  6603 /**
  6213  * Check the given subset of the post hierarchy for hierarchy loops.
  6604  * Check the given subset of the post hierarchy for hierarchy loops.
  6223  * @param int $post_ID     ID of the post we're checking.
  6614  * @param int $post_ID     ID of the post we're checking.
  6224  * @return int The new post_parent for the post, 0 otherwise.
  6615  * @return int The new post_parent for the post, 0 otherwise.
  6225  */
  6616  */
  6226 function wp_check_post_hierarchy_for_loops( $post_parent, $post_ID ) {
  6617 function wp_check_post_hierarchy_for_loops( $post_parent, $post_ID ) {
  6227 	// Nothing fancy here - bail.
  6618 	// Nothing fancy here - bail.
  6228 	if ( !$post_parent )
  6619 	if ( ! $post_parent ) {
  6229 		return 0;
  6620 		return 0;
       
  6621 	}
  6230 
  6622 
  6231 	// New post can't cause a loop.
  6623 	// New post can't cause a loop.
  6232 	if ( empty( $post_ID ) )
  6624 	if ( empty( $post_ID ) ) {
  6233 		return $post_parent;
  6625 		return $post_parent;
       
  6626 	}
  6234 
  6627 
  6235 	// Can't be its own parent.
  6628 	// Can't be its own parent.
  6236 	if ( $post_parent == $post_ID )
  6629 	if ( $post_parent == $post_ID ) {
  6237 		return 0;
  6630 		return 0;
       
  6631 	}
  6238 
  6632 
  6239 	// Now look for larger loops.
  6633 	// Now look for larger loops.
  6240 	if ( !$loop = wp_find_hierarchy_loop( 'wp_get_post_parent_id', $post_ID, $post_parent ) )
  6634 	if ( ! $loop = wp_find_hierarchy_loop( 'wp_get_post_parent_id', $post_ID, $post_parent ) ) {
  6241 		return $post_parent; // No loop
  6635 		return $post_parent; // No loop
       
  6636 	}
  6242 
  6637 
  6243 	// Setting $post_parent to the given value causes a loop.
  6638 	// Setting $post_parent to the given value causes a loop.
  6244 	if ( isset( $loop[$post_ID] ) )
  6639 	if ( isset( $loop[ $post_ID ] ) ) {
  6245 		return 0;
  6640 		return 0;
       
  6641 	}
  6246 
  6642 
  6247 	// There's a loop, but it doesn't contain $post_ID. Break the loop.
  6643 	// There's a loop, but it doesn't contain $post_ID. Break the loop.
  6248 	foreach ( array_keys( $loop ) as $loop_member )
  6644 	foreach ( array_keys( $loop ) as $loop_member ) {
  6249 		wp_update_post( array( 'ID' => $loop_member, 'post_parent' => 0 ) );
  6645 		wp_update_post(
       
  6646 			array(
       
  6647 				'ID'          => $loop_member,
       
  6648 				'post_parent' => 0,
       
  6649 			)
       
  6650 		);
       
  6651 	}
  6250 
  6652 
  6251 	return $post_parent;
  6653 	return $post_parent;
  6252 }
  6654 }
  6253 
  6655 
  6254 /**
  6656 /**
  6255  * Set a post thumbnail.
  6657  * Sets the post thumbnail (featured image) for the given post.
  6256  *
  6658  *
  6257  * @since 3.1.0
  6659  * @since 3.1.0
  6258  *
  6660  *
  6259  * @param int|WP_Post $post         Post ID or post object where thumbnail should be attached.
  6661  * @param int|WP_Post $post         Post ID or post object where thumbnail should be attached.
  6260  * @param int         $thumbnail_id Thumbnail to attach.
  6662  * @param int         $thumbnail_id Thumbnail to attach.
  6261  * @return int|bool True on success, false on failure.
  6663  * @return int|bool True on success, false on failure.
  6262  */
  6664  */
  6263 function set_post_thumbnail( $post, $thumbnail_id ) {
  6665 function set_post_thumbnail( $post, $thumbnail_id ) {
  6264 	$post = get_post( $post );
  6666 	$post         = get_post( $post );
  6265 	$thumbnail_id = absint( $thumbnail_id );
  6667 	$thumbnail_id = absint( $thumbnail_id );
  6266 	if ( $post && $thumbnail_id && get_post( $thumbnail_id ) ) {
  6668 	if ( $post && $thumbnail_id && get_post( $thumbnail_id ) ) {
  6267 		if ( wp_get_attachment_image( $thumbnail_id, 'thumbnail' ) )
  6669 		if ( wp_get_attachment_image( $thumbnail_id, 'thumbnail' ) ) {
  6268 			return update_post_meta( $post->ID, '_thumbnail_id', $thumbnail_id );
  6670 			return update_post_meta( $post->ID, '_thumbnail_id', $thumbnail_id );
  6269 		else
  6671 		} else {
  6270 			return delete_post_meta( $post->ID, '_thumbnail_id' );
  6672 			return delete_post_meta( $post->ID, '_thumbnail_id' );
       
  6673 		}
  6271 	}
  6674 	}
  6272 	return false;
  6675 	return false;
  6273 }
  6676 }
  6274 
  6677 
  6275 /**
  6678 /**
  6276  * Remove a post thumbnail.
  6679  * Removes the thumbnail (featured image) from the given post.
  6277  *
  6680  *
  6278  * @since 3.3.0
  6681  * @since 3.3.0
  6279  *
  6682  *
  6280  * @param int|WP_Post $post Post ID or post object where thumbnail should be removed from.
  6683  * @param int|WP_Post $post Post ID or post object from which the thumbnail should be removed.
  6281  * @return bool True on success, false on failure.
  6684  * @return bool True on success, false on failure.
  6282  */
  6685  */
  6283 function delete_post_thumbnail( $post ) {
  6686 function delete_post_thumbnail( $post ) {
  6284 	$post = get_post( $post );
  6687 	$post = get_post( $post );
  6285 	if ( $post )
  6688 	if ( $post ) {
  6286 		return delete_post_meta( $post->ID, '_thumbnail_id' );
  6689 		return delete_post_meta( $post->ID, '_thumbnail_id' );
       
  6690 	}
  6287 	return false;
  6691 	return false;
  6288 }
  6692 }
  6289 
  6693 
  6290 /**
  6694 /**
  6291  * Delete auto-drafts for new posts that are > 7 days old.
  6695  * Delete auto-drafts for new posts that are > 7 days old.
  6379  */
  6783  */
  6380 function _prime_post_caches( $ids, $update_term_cache = true, $update_meta_cache = true ) {
  6784 function _prime_post_caches( $ids, $update_term_cache = true, $update_meta_cache = true ) {
  6381 	global $wpdb;
  6785 	global $wpdb;
  6382 
  6786 
  6383 	$non_cached_ids = _get_non_cached_ids( $ids, 'posts' );
  6787 	$non_cached_ids = _get_non_cached_ids( $ids, 'posts' );
  6384 	if ( !empty( $non_cached_ids ) ) {
  6788 	if ( ! empty( $non_cached_ids ) ) {
  6385 		$fresh_posts = $wpdb->get_results( sprintf( "SELECT $wpdb->posts.* FROM $wpdb->posts WHERE ID IN (%s)", join( ",", $non_cached_ids ) ) );
  6789 		$fresh_posts = $wpdb->get_results( sprintf( "SELECT $wpdb->posts.* FROM $wpdb->posts WHERE ID IN (%s)", join( ',', $non_cached_ids ) ) );
  6386 
  6790 
  6387 		update_post_caches( $fresh_posts, 'any', $update_term_cache, $update_meta_cache );
  6791 		update_post_caches( $fresh_posts, 'any', $update_term_cache, $update_meta_cache );
  6388 	}
  6792 	}
  6389 }
  6793 }
  6390 
  6794 
  6401  *
  6805  *
  6402  * @param string $post_name Slug.
  6806  * @param string $post_name Slug.
  6403  * @param string $post_ID   Optional. Post ID that should be ignored. Default 0.
  6807  * @param string $post_ID   Optional. Post ID that should be ignored. Default 0.
  6404  */
  6808  */
  6405 function wp_add_trashed_suffix_to_post_name_for_trashed_posts( $post_name, $post_ID = 0 ) {
  6809 function wp_add_trashed_suffix_to_post_name_for_trashed_posts( $post_name, $post_ID = 0 ) {
  6406 	$trashed_posts_with_desired_slug = get_posts( array(
  6810 	$trashed_posts_with_desired_slug = get_posts(
  6407 		'name' => $post_name,
  6811 		array(
  6408 		'post_status' => 'trash',
  6812 			'name'         => $post_name,
  6409 		'post_type' => 'any',
  6813 			'post_status'  => 'trash',
  6410 		'nopaging' => true,
  6814 			'post_type'    => 'any',
  6411 		'post__not_in' => array( $post_ID )
  6815 			'nopaging'     => true,
  6412 	) );
  6816 			'post__not_in' => array( $post_ID ),
       
  6817 		)
       
  6818 	);
  6413 
  6819 
  6414 	if ( ! empty( $trashed_posts_with_desired_slug ) ) {
  6820 	if ( ! empty( $trashed_posts_with_desired_slug ) ) {
  6415 		foreach ( $trashed_posts_with_desired_slug as $_post ) {
  6821 		foreach ( $trashed_posts_with_desired_slug as $_post ) {
  6416 			wp_add_trashed_suffix_to_post_name_for_post( $_post );
  6822 			wp_add_trashed_suffix_to_post_name_for_post( $_post );
  6417 		}
  6823 		}
  6468 
  6874 
  6469 	$clauses['groupby'] = "{$wpdb->posts}.ID";
  6875 	$clauses['groupby'] = "{$wpdb->posts}.ID";
  6470 
  6876 
  6471 	$clauses['where'] = preg_replace(
  6877 	$clauses['where'] = preg_replace(
  6472 		"/\({$wpdb->posts}.post_content (NOT LIKE|LIKE) (\'[^']+\')\)/",
  6878 		"/\({$wpdb->posts}.post_content (NOT LIKE|LIKE) (\'[^']+\')\)/",
  6473 		"$0 OR ( sq1.meta_value $1 $2 )",
  6879 		'$0 OR ( sq1.meta_value $1 $2 )',
  6474 		$clauses['where'] );
  6880 		$clauses['where']
       
  6881 	);
  6475 
  6882 
  6476 	return $clauses;
  6883 	return $clauses;
  6477 }
  6884 }
       
  6885 
       
  6886 /**
       
  6887  * Sets the last changed time for the 'posts' cache group.
       
  6888  *
       
  6889  * @since 5.0.0
       
  6890  */
       
  6891 function wp_cache_set_posts_last_changed() {
       
  6892 	wp_cache_set( 'last_changed', microtime(), 'posts' );
       
  6893 }
       
  6894 
       
  6895 /**
       
  6896  * Get all available post MIME types for a given post type.
       
  6897  *
       
  6898  * @since 2.5.0
       
  6899  *
       
  6900  * @global wpdb $wpdb WordPress database abstraction object.
       
  6901  *
       
  6902  * @param string $type
       
  6903  * @return mixed
       
  6904  */
       
  6905 function get_available_post_mime_types( $type = 'attachment' ) {
       
  6906 	global $wpdb;
       
  6907 
       
  6908 	$types = $wpdb->get_col( $wpdb->prepare( "SELECT DISTINCT post_mime_type FROM $wpdb->posts WHERE post_type = %s", $type ) );
       
  6909 	return $types;
       
  6910 }