Prerequisites
- [x ] I have searched for similar issues in both open and closed tickets and cannot find a duplicate.
- [x ] The issue still exists against the latest stable version of Elementor.
Description
For 3rd party Document types on appropriate document post auto-saving value for meta field '_elementor_template_type' is set to 'wp-post' instead of Document type name.
This happens only when revision is also created on post autosave. And the reasons is next:
- On AJAX builder save, for autosaves default document is replaced with an autosave document - https://github.com/elementor/elementor/blob/master/core/documents-manager.php#L497
- If autosave at this moment doesn't exists, document tries to create it - https://github.com/elementor/elementor/blob/master/core/base/document.php#L359-L367,
and then set required meta fields for this autosave - https://github.com/elementor/elementor/blob/master/core/base/document.php#L369
- On autosave creating, WordPress core runs revision creating. Revision creating calls
wp_insert_post function. Inside this function called wp_transition_post_status function. On transition_post_status hook called inside this function, in Elementor\Modules\Usage attached callback on_status_change.
- Inside this callback called method
Plugin::$instance->documents->get( $post->ID ); for this case $post->ID is created autosave ID and $post is a current autosave post object. So this method tries to get this document instance and write it into documents cache for given ID. But on this stage '_elementor_template_type' meta field still not set for current autosave. So Plugin::$instance->documents->get( $post->ID ); returns default Post document instead of correct one for appropriate Document Type.
- Later, when plugin tries to get an autosave document, it gets document instance from cache (where at this moment already stored incorrect document instance for given post ID). So, on this step - https://github.com/elementor/elementor/blob/master/core/documents-manager.php#L497
get_autosave returns not the document instance of appropriate type, but default post document instance, and later, when method $document->save( $data ); is called - is a wrong document instance. That why, when this method is called inside $document->save( $data ); - https://github.com/elementor/elementor/blob/master/core/base/document.php#L543, it rewrites '_elementor_template_type' for saved post ID and set it into 'wp-post' instead of initial Document type name.
Steps to reproduce
- Register custom document type on
elementor/documents/register hook.
- Create a new post of registered document.
- Check created post _elementor_template_type meta field value for created post, it should be set into registered document type name.
- Wait until first post autosave.
- Check created post _elementor_template_type meta field value for created post, it should be replaced into wp-post instead of initial value.
Possible solution
Not sure in such cases should be run on_status_change method in Elementor\Modules\Usage, but as I see it prevented from processing on document save - https://github.com/elementor/elementor/blob/master/modules/usage/module.php#L150-L152. So maybe you can prevent it also from processing on autosave creating. For example you can call some hooks before and after this - https://github.com/elementor/elementor/blob/master/core/base/document.php#L359, for example do_action( 'elementor/document/before-autosave-create' ); and do_action( 'elementor/document/after-autosave-create' ); and than add callbacks in Elementor\Modules\Usage class on this hook, something like this:
add_action( 'elementor/document/before-autosave-create', function() {
$this->is_autosave = true;
} );
add_action( 'elementor/document/after-autosave-create', function() {
$this->is_autosave = false;
} );
And then check $this->is_autosave inside on_status_change method.
Prerequisites
Description
For 3rd party Document types on appropriate document post auto-saving value for meta field '_elementor_template_type' is set to 'wp-post' instead of Document type name.
This happens only when revision is also created on post autosave. And the reasons is next:
and then set required meta fields for this autosave - https://github.com/elementor/elementor/blob/master/core/base/document.php#L369
wp_insert_postfunction. Inside this function calledwp_transition_post_statusfunction. Ontransition_post_statushook called inside this function, inElementor\Modules\Usageattached callbackon_status_change.Plugin::$instance->documents->get( $post->ID );for this case $post->ID is created autosave ID and $post is a current autosave post object. So this method tries to get this document instance and write it into documents cache for given ID. But on this stage '_elementor_template_type' meta field still not set for current autosave. SoPlugin::$instance->documents->get( $post->ID );returns default Post document instead of correct one for appropriate Document Type.get_autosavereturns not the document instance of appropriate type, but default post document instance, and later, when method$document->save( $data );is called - is a wrong document instance. That why, when this method is called inside$document->save( $data );- https://github.com/elementor/elementor/blob/master/core/base/document.php#L543, it rewrites '_elementor_template_type' for saved post ID and set it into 'wp-post' instead of initial Document type name.Steps to reproduce
elementor/documents/registerhook.Possible solution
Not sure in such cases should be run on_status_change method in Elementor\Modules\Usage, but as I see it prevented from processing on document save - https://github.com/elementor/elementor/blob/master/modules/usage/module.php#L150-L152. So maybe you can prevent it also from processing on autosave creating. For example you can call some hooks before and after this - https://github.com/elementor/elementor/blob/master/core/base/document.php#L359, for example do_action( 'elementor/document/before-autosave-create' ); and do_action( 'elementor/document/after-autosave-create' ); and than add callbacks in Elementor\Modules\Usage class on this hook, something like this:
And then check $this->is_autosave inside
on_status_changemethod.