Opened 10 years ago
Closed 10 years ago
#29269 closed defect (bug) (duplicate)
save_post doesn't fire when unavailable page template saved to page
Reported by: | matthewdietsche | Owned by: | |
---|---|---|---|
Milestone: | Priority: | normal | |
Severity: | major | Version: | 2.6 |
Component: | Posts, Post Types | Keywords: | 4.1-early |
Focuses: | Cc: |
Description
When you select a page template for a page, and then switch to a theme without that page template file, the save_post action will never fire due to this logic in wp_insert_post():
if ( !empty($page_template) && 'page' == $data['post_type'] ) { $post->page_template = $page_template; $page_templates = wp_get_theme()->get_page_templates( $post ); if ( 'default' != $page_template && ! isset( $page_templates[ $page_template ] ) ) { if ( $wp_error ) return new WP_Error('invalid_page_template', __('The page template is invalid.')); else return 0; } update_post_meta($post_ID, '_wp_page_template', $page_template); }
Change History (7)
#1
@
10 years ago
- Component changed from Themes to Posts, Post Types
- Version changed from 3.9.2 to 2.6
#2
@
10 years ago
- Severity changed from normal to major
I'm sure this is a duplicate of the problem I commented on in #26809. where I added this note.
In my experience, this bug can lead to loss of data.
It prevents post meta data from being saved, with no message to the user.
In the announcement for WordPress 3.8.3 it was stated that "any loss of content is unacceptable".
I added that
While I don't believe this bug deserves its own quickfix, I'd like it to be reconsidered.
Nothing's happened on #26809. My 26809.1.patch applies directly to this bug.
A workaround is to manually delete the row from the wp_postmeta table where meta_key = 'wp_page_template'.
PS. I have just repeated the process of tracking down this bug. So I'm rather annoyed! Perhaps I should have applied the workaround 6 months ago when I first discovered the problem and developed my fix.
#3
@
10 years ago
- Keywords 4.1-early added
- Milestone changed from Awaiting Review to Future Release
Indeed, #26809 mentions this, but focuses on another issue, checking the result of wp_update_post()
in edit_post()
, which is likely a wontfix.
Let's fix the potential data loss due to an invalid template early in 4.1.
#4
@
10 years ago
I've just discovered the same problem. I have a theme with only one page template, therefore the Template UI drop down does not appear, and does not clear the no longer valid page_template.
My solution was to clear the invalid (i.e. no longer exists) page_template on the edit_form_top hook. This clears the value before the UI is rendered, as the invalid page_template is carried to the UI and posted back to wp_insert_post.
My code below for reference.
// Check the post data before saving function ac_validate_post_data_page_template($post_id) { // Page if ( get_post_type($post_id) == 'page' ) { // WordPress will prevent post data saving if a page template has been selected that does not exist // This is especially a problem when switching to our theme, and old page templates are in the post data // Unset the page template if the page doesn't exist to allow the post to save // Get the WP template name $template_file_name = get_post_meta($post_id,'_wp_page_template',TRUE); // Check the template exists if (! ac_page_template_exists($template_file_name) ) { // Template doesn't exist so remove the data to allow WP to save $post = get_post($post_id); delete_post_meta($post_id, '_wp_page_template'); } } } // Checks if a page template exists function ac_page_template_exists($template_file_name) { // Get the templates $page_templates = wp_get_theme()->get_page_templates(); // Just return if there is an index for our template return isset( $page_templates[ $template_file_name ] ); } // Validate post data when the edit for is displayed add_action('edit_form_top', 'ac_edit_form_top_hook'); function ac_edit_form_top_hook($post) { ac_validate_post_data_page_template($post->ID); }
#6
@
10 years ago
that this throws an error seems to be contradictory to WordPress' behavior: if the page has an invalid template, when the page is visited (on frontend), it simply reverts down to the next relevant theme template file. it doesn't keep the database clean, but is returning WP_Error
the right reaction to this situation? If it is, then adding save_post
and save_post_page
hooks before returning WP_Error
seems the best fix. perhaps clearing the post_template
/_wp_page_template
post metadata is cleaner, but I don't think it matches expected behavior.
Introduced in [7900].
The post is actually updated, but if
page_template
value is invalid,save_post
and related actions never run.Looks like template validation should happen earlier, before updating the post, or later, after running the actions.